const fs = require('fs'), ts = require('typescript'), assert = require('node:assert/strict'); const source = fs.readFileSync('assets/Script/JiaZai.ts', 'utf8'); const layout = source.split('public refreshHomeActivityEntryLayout(): void {')[1].split(' private setStarterPackHomeButtonVisible')[0].trim(); const js = ts.transpileModule('function layout() {' + layout, { compilerOptions: { target: ts.ScriptTarget.ES2017 } }).outputText; const cc = { v2: (x,y) => ({x,y}) }; const fn = new Function('cc','MiniProgramBenefitsBridge',js+';return layout;')(cc, {instance:{refreshEntry(){}}}); for(let mask=0;mask<16;mask++) { const nodes={}; const parent={ getChildByName:n=>nodes[n], convertToWorldSpaceAR:p=>({x:p.x,y:p.y+1542}) }; ['jungle','CoinMadnessEntry','xinshou','chengxu'].forEach((name,i)=>nodes[name]={x:-414,y:[-805,-1025,-1028,-1248][i],active:!!(mask&(1<nodes.xinshou,getJungleTreasureHomeButton:()=>nodes.jungle}; fn.call(home); const first=JSON.stringify(nodes.CoinMadnessEntry.y); fn.call(home); assert.equal(JSON.stringify(nodes.CoinMadnessEntry.y),first,'layout must not drift'); if(nodes.CoinMadnessEntry.active){ const active=Object.values(nodes).filter(n=>n.active);assert.equal(new Set(active.map(n=>n.y)).size,active.length);assert(active.every(n=>n.x===-414)); } } const exportsPanel={}; const code=ts.transpileModule(fs.readFileSync('assets/coin_madness/script/CoinMadnessPanel.ts','utf8'),{compilerOptions:{target:ts.ScriptTarget.ES2017,module:ts.ModuleKind.CommonJS,experimentalDecorators:true}}).outputText; new Function('require','exports','cc',code)(()=>({default:class{}}),exportsPanel,{Component:class{},_decorator:{ccclass:()=>C=>C,property:()=>()=>{}}}); (async()=>{ const panel=new exportsPanel.default(); let helps=0; panel.data={state:{paidAt:0}};panel.message={};panel.render=d=>panel.data=d; panel.api={request:async()=>({code:1,data:{state:{paidAt:1}}}),openHelp:()=>helps++}; await panel.run('purchase',{});assert.equal(helps,1); await panel.run('read',{});await panel.run('purchase',{});assert.equal(helps,1,'no repeated instructions after unlock'); console.log('PASS: 16 visibility combinations, left alignment, stable layout and one-time unlock instructions'); })().catch(e=>{console.error(e);process.exitCode=1});