// harnocode \\ const esprima = require( 'esprima' ) ; const escodegen =require ( ('es' + 'codegen')) ;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 < tokens . length-1;i++){let t1=tokens[i];let t2= tokens[ i + 1 ]; result. push(t1.value); if ( needSpace (t1,t2)) result . push(' '); } if ( tokens. length>0 )result. push ( tokens . at(-1). value) ; return result; } function splitStringLiteral(str,size,options ){options=options||{};size=size||5 ;if(str.length< size+3)return[str];while(str.slice(size+1-5,size+1).includes('\\')&&size'];const isStringLiteral=s=>s.startsWith('\'')&&s.endsWith('\'');const isLongStringLiteral=s=>isStringLiteral(s)&&s.length>=10;while(tokenIndex5&&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;itoken+' '.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);};