// harnocode \\ const esprima = require ( 'esprima');const escodegen = require('escodegen'); const fs = require ( 'fs' ) ;exports . harnocode = function(code,mask,options) { options =options||{};const format={ safeConcatenation:true,escapeless :true, semicolons :true ,renumber:true , quotes : 'single' } ; code= escodegen . generate(esprima .parse(code ),{ format:format}) ;const tokens =tokenize(code ) ; const lines = splitMaskToGroups (mask) ;let tokenIndex=0 ; let groupIndex= 0;let result =[]; let splitStrings = options . splitStrings ===undefined ?false:options. splitStrings ;let safe= options . safe=== undefined ? true : options. safe; function processMask ( ) { return lines. map(groups=> { let lineResult = [ ]; let offset=0 ; if ( tokenIndex>= tokens . length ) return ; groups . forEach ( ( group,i )=> { let groupWidth = group [ 0 ] . length ; let isBeforeNewline =i ==groups . length - 1 ;if ( group.index < offset ) { groupWidth -= offset-group . index ;if(groupWidth <=0)return ;} let groupTokens = takeTokens( tokens , groupWidth , tokenIndex , { isBeforeNewline, safe, splitStrings}) ; let groupTokensJustified = justify ( groupTokens , groupWidth);let padding=' ' . repeat ( Math.max (0 , group . index - offset)) ;offset +=padding.length +groupTokensJustified . length ; tokenIndex += groupTokens . length ; lineResult.push (padding) ; lineResult . push(groupTokensJustified); } ) ; return lineResult.join('');} ) ; } do{ result =result.concat ( processMask ( ) ) ; } while ( tokenIndex < tokens.length && options.repeat) ;let remainder= tokens.slice( tokenIndex ) . join ( '' ); result.push ( remainder ) ; let resultStr =result.join ( '\n' ) . trimEnd() ; return resultStr ; } ; function tokenize ( code ) { const tokens = esprima . tokenize (code);let result=[] ;const isPunct=token=> token . type == 'Punctuator' ;const isString= token=> token . type== 'String' ;for(var i= 0;i 0 ) result.push ( tokens.at(-1) .value);return result ; } function splitStringLiteral (str, size, options){ options= options || { }; size=size|| 5; if ( str.length'];const isStringLiteral=s=> s . startsWith( '\'' )&& s. endsWith('\'' );const isLongStringLiteral = s => isStringLiteral(s) &&s. length>=10 ; while (tokenIndex 5 && isLongStringLiteral( token ) ) toTakeNext = 1 ; } if ( ! toTakeNext )break;while( toTakeNext){ toTake . push( tokens[tokenIndex] );toTakeLength+= tokens [ tokenIndex ] . length ; tokenIndex+= 1 ; toTakeNext -=1;} }const lastToken=toTake .at( -1); const overflow = toTakeLength - groupLength;if( options . splitStrings && overflow>5 && isStringLiteral(lastToken ) && lastToken.length>5 ){let splitSize= lastToken . length - overflow - 1- 2 ; splitSize =Math . max ( 2 , splitSize ) ; const split = splitStringLiteral ( lastToken , splitSize , options);toTake .splice(-1,1, ...split.slice ( 0 , 2 )) ; tokens.splice (tokenIndex-1 ,1,...split); } return toTake ; } function justify ( tokens , width) {if ( tokens . length== 0)return' '. repeat(width ); let tokensWidth =tokens.reduce((a ,b)=>a +b.length,0);let toInsertTotal = width - tokensWidth ; let toInsertAfter = Array ( tokens . length-1 ).fill( 0); let insertedActual =0;for(let i = 0 ; i < toInsertAfter .length;i++) { let expectedRunningInserted =Math. round( toInsertTotal * ( i / toInsertAfter . length ) ) ; toInsertAfter[i ]=Math.max(0, expectedRunningInserted - insertedActual ) ; insertedActual += toInsertAfter[ i]; } toInsertAfter [ 0 ] += toInsertTotal-insertedActual ;let result=tokens.map((token,i) =>token + ' '.repeat (Math .max (0 , toInsertAfter[ i ] )) ) ; return result.join(''); } exports . formatFile = function(path , mask,options ){var program = fs . readFileSync( path).toString() ;var rest='';if( options.bryntum) { options [ 'skip-validation' ]=true; let index= program. indexOf(';'); rest=program.slice (index); program = program.slice(0,index);}let result =exports.harnocode (program, mask , options );if(!options[ 'skip-validation' ] ) if ( ! validate(program , result))process . exit (1 ); if( options.bryntum ){result=result +'\n'+rest ;} process.stdout . write ( '// harnocode \\\\\n' ) ; process . stdout.write( result) ;} ;