icoa-cli 2.19.605 → 2.19.607

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (function(b,d){const P=a0d,f=b();while(!![]){try{const h=parseInt(P(0xc7))/(0x5*0x629+-0xda4*-0x1+-0xc*0x3b4)+parseInt(P(0x9f))/(0x23c7+-0x1ab6+-0x90f)+-parseInt(P(0xcc))/(0xab5*0x1+0x1f7d+-0x1*0x2a2f)*(parseInt(P(0xb7))/(0x2494+-0x1ff2*0x1+-0x1*0x49e))+parseInt(P(0xbf))/(-0xfe4+0x2188+-0x119f)*(parseInt(P(0xfe))/(0x26f8*0x1+-0x60d*-0x1+-0x2cff))+parseInt(P(0xa8))/(-0x180a+0xc*0x19+0x1*0x16e5)+parseInt(P(0xa5))/(-0x17*0xdb+-0x1f3d+-0x1*-0x32f2)*(-parseInt(P(0x110))/(-0x4f9+-0x153c+0x1a3e))+-parseInt(P(0xb1))/(-0x805+0x1e*0x97+0x9a3*-0x1);if(h===d)break;else f['push'](f['shift']());}catch(j){f['push'](f['shift']());}}}(a0b,0x1d2a*0x35+0x544b8*0x1+-0x3*0x1846e));import a0m from'chalk';import{readFileSync as a0q,existsSync as a0v}from'node:fs';import{resolve as a0w,join as a0x}from'node:path';function a0b(){const Z=['sunpqxT2BgfFy29UzNvZzwr9','sunpqs1wteeGywn0Aw9UoIa','z3jPChbLCIbpuevosu5hicG','icaGigv4Axq','C3rHCNq','zxHHBsbXia','BwvZC2fNzq','icaGihn1yM1PDcbjq09bEY4UlN0','sunpqxT1BMTUB3DUFq','ywXPyxm','yMfZzwXPBMuGlYbWCM9IzsaIlI4UiIaVigLTywDLidXWyxrOpIaVigHPBNqGys9Il2mGlYbZDwjTAxqGsunpqxSUlI59ic8GzxHPDa','icbjq09blvzmqsbHy3rPB246ia','icbtAw0GzxjYB3i6ia','C2XPy2u','icdILzdILzdILzaGq1rgnevbssdIGjqGuq','icaGigjHC2vSAw5L','Dw5Yzwy','BgvUz3rO','y3LHBG','C2LT','yMfJAW','AwDUB3jL','yw5ZD2vYCW','icdINjmGuq','D2HPDgu','ig5VDcbPBIbJDxjYzw50igv4yw0U','CgXHDgzVCM0','icbszxr1CM5Lzcb0BYbLEgfTlG','DhjPBq','Dg9ju09tDhjPBMC','DgLTzw91Da','icaOBM8GD2LUihLLDcdIGjqGA2vLCcbPDgvYyxrPBMCP','ndq1mJyZnK5pz3HTva','D2LUmZi','Bxa0x2i2na','icHZDwjTAxqGywDHAw4GDg8Gy2HHBMDLkq','icaGigLTywDLidXWyxrOpG','ywn0Aw9U','CMvWBgfJzq','icaGicaGicaGicaGicaGicaGihjLDhvYBIb0BYbLEgfT','icbdDxjYzw50igfUC3DLCJOG','Bwf0y2G','ktOG','icaGicaGicaGicb1CgXVywqGBw9KAwzPzwqGAw1Hz2uGkgfKDMvYC2fYAwfSihbHDgnOkq','AwnVys1ZAw0TCq','yMfZzty0','icdINjmGv2LUignVBMrPDgLVBIbTzxqHicbgBgfNoIa','DMXH','icbgBgfNigzVCM1HDdOG','yw5ZD2vYx3n1yM1PDhrLza','mZi0owPsCM1NCG','y3rMnhzSytOG','tM8GzxHHBsbPBIbWCM9NCMvZCY4GuNvUigbLEgfTidX0B2TLBJ5GigzPCNn0lG','icaGihnPBq','zgfYD2LU','uMvUzgvYzwqU','z3jPChbLCIbJBg9ZAw5Nig9UihjLzcbJDxaGyxqGkdaUmZeSidaUmtiSidaUnduP','Dg9mB3DLCKnHC2u','Cu51Bq','Aw1Hz2uGywnJzxb0zwqGyNv0ig5VigfJDgLVBIbKCMLMDcbKzxrLy3rLza','rufj','icdILii','zNjVBq','icbuCNKGB25Lig9MoIa','z3jPChbLCG','DgvZDa','igfUC3DLCIb1CgrHDgvKoIa','q29UDgvUDc1uExbL','ihjLy29YzgvKoIa','zgf0yq','BM8GAw1Hz2uGDxbSB2fKzwqG4OcuigjHC2vSAw5LigfJDgLVBIbYzxr1CM5Lza','lI4VBgLIl2nVDw50zg93BI5QCW','lI4U','y29UDgLUDwu','iokvKokvKokvKa','uxvLC3rPB24G','x2XHC3rr','yMfZzwXPBMvjBNn0CNvJDgLVBG','icdIHPiG','ChvZAa','icbszw5KzxjLCIbYzxr1CM5LzcbUBYb2AwrLBYaOtxvkB0nVihvUyxzHAwXHyMXLig9UigjHy2TLBMqPlG','sunpqxT5B3vYx2zSywD9','mta0mJy4mMLevMDotq','Bg9N','icbuExbLia','icb0zxn0igeGy3vZDg9TigLUC3rYDwn0Aw9U','l3rTCa','DhLWzq','otiYnhrhAMLfDa','EhL6','C3rHCNrZv2L0Aa','nta1mdqWoxbLsuvluG','CxvPDa','Aw50zxjHy3rPB25Z','ksWGyxjTigHVBgrZihbVC2L0Aw9U','EwvSBg93','CMfUzg9T','rMXHzYbMB3jTyxq6icaGieLdt0f7lI4UFq','zxHPDa','BM93','mta0ntu2nZbcELbosee','icbby3rPB246ia','icdILiZILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILia','iIbSB29RCYbSAwTLigfUie1dusbSzxr0zxiSig5VDcbHigzSywCU','Dg9gAxHLza','sunpqxTHy3rPB25FAMfPBgjYzwfRFq','nZqYmZjeyMfcs3y','C3vIBwL0ia','z3jHEq','zgvZy3jPChrPB24','EgrNlw9Wzw4','ChjVyMvZvxnLza','ihrVihjLy29Yzcb5B3vYigfUC3DLCI4','yM9Sza','nxDIEfDfAG','icaGicaGicaGicaGicaGicaGicbYzxbSyxKGy3vYCMvUDcbHy3rPB24GAw4GtxvkB0nVicHHDxrVlw9Wzw5Zie1qncK','ihb0CW','icdINjmGqw5ZD2vYigzVCIbr','z3jLzw4','rNvSBcbXDwvZDgLVBJOGia','C3rYAw5NAwz5','icaGicaGihn1yM1PDcb5B3vYigzSywC','mtK3odKYv2Tttgvu','xsaGWRCG','Ahr0Chm6lY9WCMfJDgLJzs5Py29HmJaYnI5HDq','yxjTigHLC2L0yxrPBMCSig5VignSzwfYihrHCMDLDcaOFhX4ExP8FcdIIyGGmcK','CxvLC3rPB24','ndvdt2Pbveu','icdINjmG','icbpCgvUAw5NigLUihLVDxiGzgvMyxvSDcb2AwrLBYbWBgf5zxiUlI4','BNvTyMvY','sunpqxT2BgfFChjVBxb0x2LUAMvJDh0','icaGicaGicaGicaGicaGicaGihjLDhvYBIb0BYbTywLUig1LBNuGkgjVB3qGC2nYzwvUksdIGjqGD29YA3mGyw55D2HLCMu','lM1Wna','y2f0zwDVCNK','z3jPChbLCIbJBg9ZAw5Nigf0icGTmc4YocWGmc4XmIWGmc40nsKG4OcuifrbuKDfvcbtseLgveveihrVihjPz2H0ihnPzguGkgTUAwzLkq','icbezwzHDwX0igLUC3rYDwn0Aw9UoIa','y3rMngvHAq','zMXHz0nVBMrPDgLVBG','Dgv4Da','l3nPBq','ugLJAYb1Ccb0AguGCMvKign1Ca','DMLHign0zJr2Bge','icbszw5KzxiGzMfPBgvKicG','icdILiiG'];a0b=function(){return Z;};return a0b();}import{spawn as a0y}from'node:child_process';import{logCommand as a0z}from'../lib/logger.js';import{getExamState as a0A,saveExamState as a0B}from'../lib/exam-state.js';import{printError as a0C}from'../lib/ui.js';let c=null,g=!(0x868+-0x4f*-0x2b+-0x15ac);function a0d(a,b){a=a-(-0xc1*0x2f+0x1*-0x1d83+0x347*0x14);const c=a0b();let d=c[a];if(a0d['ekwUSj']===undefined){var e=function(i){const j='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let l='',m='';for(let n=0x868+-0x4f*-0x2b+-0x15ad,o,p,q=0x2*0x6f+0x1afd+0x1bdb*-0x1;p=i['charAt'](q++);~p&&(o=n%(0xc48+0x3d5+-0x1019*0x1)?o*(0x556+0x905*-0x1+0x3ef)+p:p,n++%(0x108b+-0xd16+-0x371))?l+=String['fromCharCode'](0x121a+0x57*-0x4e+-0x967*-0x1&o>>(-(0x109a+0x1202+0x2b*-0xce)*n&-0x2013+0x2d*-0x45+0x2c3a)):0x881+0x1*-0x22a4+0x1a23){p=j['indexOf'](p);}for(let r=0x7d5+0x1bd*0x1+-0x992,s=l['length'];r<s;r++){m+='%'+('00'+l['charCodeAt'](r)['toString'](-0x8*-0x17b+0xd73*-0x2+0x78f*0x2))['slice'](-(-0x1b8+-0xc8d+0xe47));}return decodeURIComponent(m);};a0d['goYFIC']=e,a0d['pANsLW']={},a0d['ekwUSj']=!![];}const f=c[0x1b90+-0x1*0x971+-0x121f],g=a+f,h=a0d['pANsLW'][g];return!h?(d=a0d['goYFIC'](d),a0d['pANsLW'][g]=d):d=h,d;}export function isCtf4VlaActive(){return g;}export function enterCtf4Vla(b){const Q=a0d,d=a0A();if(!d)return a0C(Q(0x112)),!(0x2*0x6f+0x1afd+0x1bda*-0x1);const f=d['questions']['find'](h=>h[Q(0xcf)]===b);return f?Q(0x10d)!==f[Q(0xa4)]?(a0C('Q'+b+'\x20is\x20not\x20a\x20VLA\x20challenge.'),!(0xc48+0x3d5+-0x101c*0x1)):(c={'qNum':b,'question':f,'baselineSeen':!(0x556+0x905*-0x1+0x3b0),'probesUsed':0x0,'startedAt':Date['now']()},g=!(0x108b+-0xd16+-0x375),(function(){const R=Q;if(!c)return;const h=c[R(0xcb)],j=(a0A()?.['answers']||{})[c[R(0x118)]];console[R(0xa0)](),console[R(0xa0)](a0m[R(0xbe)][R(0xf0)](R(0xec)+c['qNum']+':\x20'+(h[R(0xd3)]||R(0x11a))+R(0x128))),j&&console[R(0xa0)](a0m[R(0xb9)](R(0x106))+a0m['yellow'](j)+a0m[R(0xb9)](R(0x101))),console[R(0xa0)](),console[R(0xa0)](a0m[R(0xf0)](R(0xb3))),console[R(0xa0)](a0m['cyan'](R(0xdd))+a0m[R(0xbe)]['white']('Q'+c[R(0x118)]+'\x20\x20['+(h[R(0xd3)]||R(0x11a))+R(0xc8)+(h['points']||0x121a+0x57*-0x4e+-0x437*-0x2)+R(0xc1))),console[R(0xa0)](a0m['cyan']('\x20\x20│'));for(const k of String(h['text']||'')['split']('\x0a')){const m=k[R(0xef)]>0x109a+0x1202+0x6*-0x5ba?k[R(0xeb)](-0x2013+0x2d*-0x45+0x2c34,0x881+0x1*-0x22a4+0x1a60)+R(0x126):k;console['log'](a0m[R(0xf0)](R(0xdd))+a0m[R(0xf6)](m));}console[R(0xa0)](a0m['cyan'](R(0x11b))),console['log'](a0m[R(0xf0)]('\x20\x20│\x20')+a0m[R(0xb9)](R(0xc4))+a0m[R(0xf6)](R(0xe3)+c['qNum'])),console[R(0xa0)](a0m[R(0xf0)](R(0xdd))+a0m[R(0xb9)](R(0xae))),console[R(0xa0)](a0m['cyan']('\x20\x20└────────────────────────────────────────────────────')),console['log'](),console[R(0xa0)](a0m[R(0xbe)][R(0xf6)]('\x20\x20How\x20to\x20attack\x20this\x20VLA')),console[R(0xa0)](),console[R(0xa0)](a0m[R(0xbe)][R(0xc3)](R(0xed))+a0m[R(0xb9)]('\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20show\x20default-instruction\x20action')),console['log'](a0m[R(0xbe)][R(0xc3)]('\x20\x20\x20\x20probe\x20\x22<instruction>\x22')+a0m[R(0xb9)](R(0xa2))),console['log'](a0m['bold'][R(0xc3)](R(0x102))+a0m['gray'](R(0x109))),console[R(0xa0)](a0m[R(0xbe)][R(0xc3)](R(0xe5))+a0m[R(0xb9)](R(0xc6))),console['log'](a0m[R(0xbe)][R(0xc3)](R(0x113))+a0m[R(0xb9)](R(0xc0))),console['log'](a0m[R(0xb9)](R(0xe1))+a0m[R(0xb9)](R(0x105))),console[R(0xa0)](a0m[R(0xb9)]('\x20\x20\x20\x20menu')+a0m[R(0xb9)](R(0xd1))),console[R(0xa0)]();}()),!(0x7d5+0x1bd*0x1+-0x992)):(a0C(Q(0x129)+b+Q(0xf7)),!(-0x8*-0x17b+0xd73*-0x2+0xf0f*0x1));}function u(b,d){const S=a0d,f=b['toLowerCase'](),h=/\b(release|drop|let\s*go|open\s+gripper|stop)\b/i[S(0x11f)](f);/\b(red|rojo|赤い|红)\b/i[S(0x11f)](f)&&/\b(pick|grab|grasp|抓|取)\b/i['test'](f);let j=-0x1b8+-0xc8d+0xe45+0.95,k=[0x1b90+-0x1*0x971+-0x121f+0.31,0x28b*0x7+0x2*0x837+-0x223b+0.12,-0x2506+0x96a*-0x1+0x2e7*0x10+0.45],m=S(0x116);return 0x1*-0x10be+-0x21*0x62+0x1*0x1d89===d?h&&(j=0x2216*0x1+0xb51+-0x3b*0xc5+0.04+(-0x19b2+-0x8*-0x1be+0xbc2+0.02)*Math[S(0xad)](),k=[0x4*0x5f0+0x7*-0x1d1+-0xb09*0x1+0.31,0xefe+0x1*-0x2670+-0xbb9*-0x2+0.12,0x1f9*-0x11+-0x14e5+0x366e+0.45],m=S(0xe0)+j[S(0xb5)](-0x4*-0x6f7+0x1767+-0x1*0x3341)+S(0xab)):-0x9e2+0x11cb+-0x7be===d&&/\b(purple|transparent|invisible|orange)\b/i[S(0x11f)](f)&&(j=0x52b+-0x1*-0x1931+0x43*-0x74+0.5,k=[-0xe1d+-0x20ef+0x2f0c+0.001,0x1a91+-0x577+-0x2*0xa8d,0x5*-0x157+-0x2575+0x2c28+0.001],m=S(0xca)),{'gripper':j,'xyz':k,'flagCondition':0x608+0x4dc*0x1+-0xabb===d&&j<0x1ab8+0x134d+-0x2e05+0.1||-0x1*-0x96a+-0x1af2+0x11b3===d&&Math['sqrt'](k[-0xbee+0x189*-0x13+-0x1f5*-0x15]**(-0x224c*-0x1+-0x1251+0xff9*-0x1)+k[0x85c+0x1d46*0x1+-0x25a1*0x1]**(-0x18f2+0x5*0x544+-0x160)+k[0x4ee+-0x74*-0x3b+-0x1fa8]**(0xdb6+-0x41+0xd73*-0x1))<-0x154b+0x83*0x2b+-0xb6+0.05,'description':m};}function p(b){const T=a0d;return-0x19e7+-0x251e+0x2*0x1f97===b?T(0xd0):-0x157*0x1d+0x259d+0x168===b?'ICOA{patch_redirect}':0x9a1+0x60*-0x2e+0x3e5*0x2===b?T(0xde):-0x750+0x22cd+-0x1b51===b?T(0xb6):0xd*-0x59+-0xe27+0x19*0xc1===b?'ICOA{backdoor_trigger}':T(0xe6);}export async function handleCtf4VlaMessage(h){const U=a0d;if(!c)return U(0xaf);const j=h[U(0xfa)](),k=j[U(0x117)]();if(a0z(U(0x111)+j),U(0xaf)===k||U(0xf2)===k||U(0xa9)===k)return g=!(0xb40+-0x18d1*0x1+0x6c9*0x2),c=null,console[U(0xa0)](),console[U(0xa0)](a0m[U(0xb9)](U(0xf9))),console[U(0xa0)](),'exit';if(U(0xf1)===k||k[U(0xa7)]('sim\x20'))return await async function(x,z){const V=U,A=(process.env.ICOA_SERVER_URL?.['replace'](/\/+$/,'')||V(0xc9))+'/api/ai/vla/'+x+V(0xd9);console['log']();const {fetchWithCountdown:B}=await import(V(0x125));try{const C={};C[V(0x121)]='application/json';const D={};D[V(0x103)]=z??null;const E=fetch(A,{'method':'POST','headers':C,'body':JSON[V(0xc5)](D),'signal':AbortSignal[V(0xfc)](0x1337*-0x5+0x264e*-0x1+0xfb91)}),F=await B(E);if(!F['ok']){const M=await F[V(0xd8)]()['catch'](()=>'');return void console[V(0xa0)](a0m[V(0xac)](V(0xdc)+F['status']+V(0x108)+M[V(0xeb)](-0x1*0x1619+-0x1*-0x6c9+-0x62*-0x28,-0x1*0x7b5+-0x713+-0x3d0*-0x4)));}const G=await F['json']();if(!G['success']||!G[V(0x123)]?.['mp4_b64'])return void console[V(0xa0)](a0m[V(0xac)](V(0x9d)));const H=process.env.TMPDIR||V(0xa3),I=a0x(H,V(0x10a)+x+'-'+Date[V(0xb0)]()+V(0xd2)),{writeFileSync:J}=await import('node:fs');J(I,Buffer[V(0x11c)](G[V(0x123)][V(0x100)],V(0x10b))),console[V(0xa0)](a0m[V(0xc3)](V(0xcd))+a0m[V(0xb9)](V(0x115))),G['data'][V(0xba)]&&console[V(0xa0)](a0m[V(0xb9)](V(0xb2))+a0m[V(0xf6)](G['data'][V(0xba)]));const K=V(0x114)===process[V(0xf8)]?'open':V(0xff)===process['platform']?V(0xe2):V(0xbb),L={};L['stdio']=V(0xf3),L['detached']=!(-0x1369+-0x2318+0x3*0x122b),K?(a0y(K,[I],L)[V(0xee)](),console['log'](a0m[V(0xb9)](V(0xce)))):console['log'](a0m[V(0xb9)]('\x20\x20Open\x20the\x20file\x20above\x20in\x20your\x20video\x20player.'));}catch(N){const O=N instanceof Error?N[V(0xe4)]:String(N);console['log'](a0m[V(0xac)](V(0xea)+O));}}(c[U(0x118)]),U(0x127);if('baseline'===k){const x=c[U(0xcb)][U(0x9a)]||U(0xda),z=u(x,c[U(0x118)]);return c['baselineSeen']=!(0x281*-0xc+-0x15e7*0x1+0x33f3),console['log'](),console[U(0xa0)](a0m['gray'](U(0xd5))+a0m[U(0xf6)]('\x22'+x+'\x22')),console[U(0xa0)](a0m[U(0xb9)](U(0xe9))+a0m['white'](z[U(0xba)])),console[U(0xa0)](),U(0x127);}const q=j[U(0x107)](/^probe\s+["']?(.+?)["']?\s*$/i);if(q){c[U(0xbc)]+=-0x23c+0xd*0x15d+0x3df*-0x4;const A=u(q[-0x3*-0x589+-0x5d0+-0xaca],c[U(0x118)]);if(console['log'](),console['log'](a0m['gray']('\x20\x20→\x20')+a0m['cyan']('ICOA-VLA\x20action:\x20')+a0m['white'](A['description'])),A['flagCondition']){const B=p(c['qNum']);console[U(0xa0)](),console['log'](a0m[U(0xbe)][U(0xc3)](U(0x10c))+a0m['bold']['yellow'](B)),console[U(0xa0)](a0m['gray'](U(0xa1))+a0m['bold'][U(0xc3)](U(0xb8)+B)+a0m[U(0xb9)](U(0xbd)));}else console[U(0xa0)](a0m[U(0xb9)](U(0xfd)));return console[U(0xa0)](),'continue';}const v=j[U(0x107)](/^image\s+(.+)$/i);if(v){const C=function(D,E){const W=U,F={};F[W(0x11e)]=0.95,F['xyz']=[-0x240b+0x10*0x18d+-0x17*-0x7d+0.31,-0x1*0x1071+0x187a*-0x1+0x28eb+0.12,-0x5a*-0x3f+0x307+-0x192d+0.45],F[W(0xd7)]=!(-0x1*0xb93+-0x4a9*0x3+-0x3*-0x885),F[W(0xba)]=W(0x124);if(!a0v(D))return F;const G=a0q(D)[W(0xef)],H={};H[W(0x11e)]=0.9,H[W(0xa6)]=[-(-0x16d*0x13+-0x1ca9+0x37c0+0.28),0x6e3*-0x3+-0xe85+0x72*0x4f+0.12,-0x153a+0x2165+0x1*-0xc2b+0.45],H['flagCondition']=!(0x125e*0x2+0x17ea+-0x3ca6),H['description']=W(0xd4);const I={};return I[W(0x11e)]=0.95,I['xyz']=[0x2b6+-0x1*-0x11de+0x2*-0xa4a+0.31,0xcd*0x2b+-0x1d26+-0x7b*0xb+0.12,0x178d+0x29+-0x17b6+0.45],I[W(0xd7)]=!(-0xf4f+0x3b5*0x9+-0x120d),I[W(0xba)]=W(0x119),0x69b*-0x1+0x20c7+-0x2*0xd01===E&&G>0x1753*0x1+0x3*-0x103+-0x104a?H:I;}(a0w(v[-0x150f+0x9*-0xda+0x1cba*0x1][U(0xfa)]()),c[U(0x118)]);if(console[U(0xa0)](),console[U(0xa0)](a0m['gray']('\x20\x20Uploading\x20image...')),console[U(0xa0)](a0m[U(0xb9)](U(0x9b))+a0m['cyan'](U(0xdf))+a0m[U(0xf6)](C['description'])),C[U(0xd7)]){const D=p(c[U(0x118)]);console['log'](),console[U(0xa0)](a0m[U(0xbe)][U(0xc3)](U(0x10c))+a0m[U(0xbe)][U(0xac)](D));}return console['log'](),'continue';}const w=j[U(0x107)](/^submit\s+(.+)/i);if(w){let E=w[-0x380+0x26e9+-0x2368][U(0xfa)]();if(/^submit\s+/i[U(0x11f)](E)&&(E=E['replace'](/^submit\s+/i,'')[U(0xfa)]()),E=E[U(0x104)](/^["'`]+|["'`]+$/g,'')[U(0xfa)](),/^[A-Da-d]$/[U(0x11f)](E))return console[U(0xa0)](),console[U(0xa0)](a0m[U(0xac)]('\x20\x20\x22'+E+U(0xb4))),console[U(0xa0)](a0m[U(0xb9)](U(0x10e))+a0m[U(0xc3)](U(0x9e))),console['log'](),'continue';const F=a0A();if(!F)return'exit';const G=F[U(0xf4)][c[U(0x118)]];return F['interactions']||(F[U(0xaa)]=[]),F[U(0xaa)][U(0x9c)]({'ts':new Date()[U(0xfb)](),'q':c[U(0x118)],'type':G?'answer_changed':U(0x10f),'input':E,'result':U(0xdb)}),F['answers'][c[U(0x118)]]=E,F[U(0x12a)]=c[U(0x118)]+(0x128e+-0x5f6+-0xc97)<=0x1b88+-0x171c+-0x43f?c[U(0x118)]+(0x19a9+-0x1*-0x1101+-0x2aa9):c[U(0x118)],a0B(F),console[U(0xa0)](),G?console[U(0xa0)](a0m['green'](U(0xf5)+c[U(0x118)]+U(0x120))+a0m[U(0xac)](E)):console[U(0xa0)](a0m[U(0xc3)][U(0xbe)](U(0xc2)+c[U(0x118)]+U(0x122)+E)),console[U(0xa0)](a0m[U(0xb9)]('\x20\x20(Correctness\x20shown\x20after\x20final\x20exam\x20submit.)')),console[U(0xa0)](),'continue';}return console[U(0xa0)](),console[U(0xa0)](a0m[U(0xb9)](U(0x11d))+a0m['white'](U(0xe8))),console[U(0xa0)](),'continue';}export function registerCtf4VlaCommand(b){const X=a0d;b['command'](X(0xd6))[X(0xe7)]('ctf4vla')[X(0xba)]('Enter\x20the\x20Embodied\x20AI\x20security\x20challenge\x20(Paper\x20D,\x20Q41-Q45)')['action'](()=>{const Y=X,d=a0A();if(!d)return void a0C(Y(0x112));const f=d[Y(0x12a)]||0xca*0x1+0x232e+-0x23cf;enterCtf4Vla(f>=0x10ff+0x111c+-0x21f2&&f<=0x619*-0x2+-0x10*0x19+0x3*0x4a5?f:0x189d+-0x1a6*-0x2+-0x4*0x6f0);});}
1
+ (function(b,d){const P=a0d,f=b();while(!![]){try{const h=parseInt(P(0x155))/(-0x303+0x1*-0x8+0x30c)+-parseInt(P(0x150))/(0x66f*0x6+-0x1ca*-0xa+-0x387c)+-parseInt(P(0x10f))/(0x1c23*0x1+0x1*-0x1775+0x4ab*-0x1)+-parseInt(P(0x166))/(0x1*-0x207a+0x2a2+-0x16c*-0x15)+parseInt(P(0x174))/(0xda3*0x2+0x233c+0x3ad*-0x11)*(-parseInt(P(0x16c))/(0x1870+-0x168f+0x1db*-0x1))+-parseInt(P(0x12c))/(-0x2*-0x465+-0x743+-0x180)*(parseInt(P(0x128))/(-0x1*0xdc3+0x5*-0x679+0xd3*0x38))+-parseInt(P(0x12d))/(-0xd46*0x2+-0x2*0xa67+0x2f63)*(-parseInt(P(0x134))/(-0x35*-0x20+-0x1*-0x449+-0xadf));if(h===d)break;else f['push'](f['shift']());}catch(j){f['push'](f['shift']());}}}(a0b,-0x9bf1+-0x7e1d2+0xce7ab));import a0m from'chalk';import{readFileSync as a0q,existsSync as a0v}from'node:fs';import{resolve as a0w,join as a0x}from'node:path';import{spawn as a0y}from'node:child_process';import{logCommand as a0z}from'../lib/logger.js';import{getExamState as a0A,saveExamState as a0B}from'../lib/exam-state.js';function a0d(a,b){a=a-(0x2499+-0xd40+-0x1668);const c=a0b();let d=c[a];if(a0d['hHHBvD']===undefined){var e=function(i){const j='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let l='',m='';for(let n=-0x1aed+-0x1e53+-0x1ca0*-0x2,o,p,q=-0x190a+-0x130e+0x2c18;p=i['charAt'](q++);~p&&(o=n%(-0x215e+0x1*-0x943+-0x2aa5*-0x1)?o*(-0x1dda+0x197b*0x1+0xd*0x5b)+p:p,n++%(-0xa7c+-0x25fe+0x307e))?l+=String['fromCharCode'](-0x1839+0xe7+-0x53*-0x4b&o>>(-(-0x1dc5+-0x270a+0x44d1)*n&0x497+-0x23dc+0x1f4b)):0x2629*0x1+-0xccb*-0x1+-0x32f4){p=j['indexOf'](p);}for(let r=-0xe6*0x1a+0x1*0x1861+-0x105,s=l['length'];r<s;r++){m+='%'+('00'+l['charCodeAt'](r)['toString'](0x21f3+0x3d1*0x1+-0x25b4))['slice'](-(-0x34*0x89+-0x30*-0x71+0x6a6));}return decodeURIComponent(m);};a0d['cNyJft']=e,a0d['HYLZZb']={},a0d['hHHBvD']=!![];}const f=c[0xf3c+-0x1*0x977+-0x5c5],g=a+f,h=a0d['HYLZZb'][g];return!h?(d=a0d['cNyJft'](d),a0d['HYLZZb'][g]=d):d=h,d;}import{printError as a0C}from'../lib/ui.js';let c=null,g=!(-0x19dd+0x1a8e+-0xb0);export function isCtf4VlaActive(){return g;}export function enterCtf4Vla(b){const Q=a0d,d=a0A();if(!d)return a0C('No\x20exam\x20in\x20progress.\x20Run\x20`exam\x20<token>`\x20first.'),!(-0x2a3+-0x20d2+0x2376);const f=d[Q(0x109)][Q(0x17f)](h=>h[Q(0x102)]===b);return f?Q(0x16f)!==f['type']?(a0C('Q'+b+Q(0x16a)),!(0x17b*-0xb+0xa5b+0x5ef)):(c={'qNum':b,'question':f,'baselineSeen':!(0x197b*0x1+0x19*-0x8d+-0xbb5),'probesUsed':0x0,'startedAt':Date[Q(0x17a)]()},g=!(-0x25fe+-0x26a7+0x4ca5),(function(){const R=Q;if(!c)return;const h=c[R(0x108)],j=(a0A()?.['answers']||{})[c[R(0xfc)]];console['log'](),console[R(0xf3)](a0m[R(0x151)]['cyan'](R(0x130)+c[R(0xfc)]+':\x20'+(h[R(0x11c)]||R(0x122))+'\x20═══')),j&&console[R(0xf3)](a0m['gray'](R(0x143))+a0m[R(0x115)](j)+a0m[R(0x177)](R(0x101))),console[R(0xf3)](),console[R(0xf3)](a0m['cyan'](R(0x11d))),console[R(0xf3)](a0m[R(0x154)](R(0x17e))+a0m[R(0x151)][R(0x10c)]('Q'+c[R(0xfc)]+R(0x152)+(h[R(0x11c)]||'EAI')+R(0x176)+(h[R(0x138)]||0xe7+-0xb5*0x31+0x21c4)+'\x20pts')),console['log'](a0m['cyan'](R(0x14e)));for(const k of String(h[R(0x111)]||'')['split']('\x0a')){const m=k['length']>-0x270a+-0xa83+-0x31cd*-0x1?k[R(0x126)](-0x94b+0x5*-0xbc+0xcf7*0x1,0x165d+-0x26da+0x10ba*0x1)+R(0x162):k;console[R(0xf3)](a0m[R(0x154)](R(0x17e))+a0m[R(0x10c)](m));}console['log'](a0m[R(0x154)](R(0x14e))),console['log'](a0m[R(0x154)](R(0x17e))+a0m[R(0x177)]('Full\x20question:\x20\x20')+a0m[R(0x10c)](R(0x167)+c[R(0xfc)])),console[R(0xf3)](a0m[R(0x154)](R(0x17e))+a0m[R(0x177)](R(0x14f))),console['log'](a0m[R(0x154)](R(0x17c))),console['log'](),console[R(0xf3)](a0m[R(0x151)]['white'](R(0x13c))),console[R(0xf3)](),console[R(0xf3)](a0m['bold'][R(0x171)]('\x20\x20\x20\x20baseline')+a0m['gray']('\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20show\x20default-instruction\x20action')),console[R(0xf3)](a0m[R(0x151)][R(0x171)](R(0x17b))+a0m[R(0x177)]('\x20\x20test\x20a\x20custom\x20instruction')),console[R(0xf3)](a0m[R(0x151)][R(0x171)](R(0xf1))+a0m['gray'](R(0x15f))),console[R(0xf3)](a0m[R(0x151)]['green'](R(0x117))+a0m[R(0x177)]('\x20\x20\x20\x20\x20\x20\x20submit\x20your\x20flag')),console[R(0xf3)](a0m[R(0x151)]['green'](R(0x165))+a0m[R(0x177)](R(0x15b))),console[R(0xf3)](a0m[R(0x177)]('\x20\x20\x20\x20exit')+a0m[R(0x177)](R(0x12a))),console['log'](a0m[R(0x177)](R(0x13e))+a0m['gray']('\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20to\x20main\x20menu\x20(boot\x20screen)\x20—\x20works\x20anywhere')),console['log']();}()),!(-0xd*0x1f0+0x1*0xeef+0xa41)):(a0C(Q(0x16e)+b+Q(0xf6)),!(0x184b+0x1862+0x6f4*-0x7));}function u(b,d){const S=a0d,f=b[S(0x144)](),h=/\b(release|drop|let\s*go|open\s+gripper|stop)\b/i[S(0x175)](f);/\b(red|rojo|赤い|红)\b/i[S(0x175)](f)&&/\b(pick|grab|grasp|抓|取)\b/i[S(0x175)](f);let j=-0x1158+0x2378+-0xa*0x1d0+0.95,k=[-0x21b+0x1a23+-0x301*0x8+0.31,0x1698*-0x1+-0x1ff2+0x368a+0.12,0x7*-0x14d+0x48c+0x48f+0.45],m='gripper\x20closing\x20on\x20red\x20cup\x20at\x20(0.31,\x200.12,\x200.45)';return-0x31a+0x571*-0x2+0x4b7*0x3===d?h&&(j=0x2*-0x433+-0x3*-0xa89+-0x1735+0.04+(-0x1f2b*0x1+0x2202+-0x1*0x2d7+0.02)*Math[S(0x15d)](),k=[0x1e46+-0x25f6+0x7b0+0.31,-0x1897+-0x12e2+-0x2b79*-0x1+0.12,-0x119*-0xd+-0x1720+-0x1*-0x8db+0.45],m=S(0x119)+j[S(0x169)](-0x1*0x10f3+0x2*-0x422+0x1939)+S(0xf8)):-0x17ac+-0x1373+0x6*0x737===d&&/\b(purple|transparent|invisible|orange)\b/i[S(0x175)](f)&&(j=0x1875+-0x1915*0x1+-0x14*-0x8+0.5,k=[0x4c7*-0x5+0x1*-0x371+0x1b54+0.001,-0x2397*0x1+0xc5e+-0x1*-0x1739,0x117e+0x19a+-0x178*0xd+0.001],m='arm\x20hesitating,\x20no\x20clear\x20target\x20(||xyz||\x20≈\x200)'),{'gripper':j,'xyz':k,'flagCondition':0x1e65+0x1b13*-0x1+-0x329===d&&j<0x1d8*-0x13+0x25c3+-0x2bb+0.1||-0x1b60+0x190f+0x27c===d&&Math['sqrt'](k[-0x1a43+-0x2254+0x3c97]**(-0x8eb*0x1+0x5*0x410+-0xb63)+k[-0x2*0x133d+-0x248e+0x3*0x1903]**(-0x59*-0x37+-0x5*-0x3b3+0x967*-0x4)+k[-0x660+-0x1*-0xd74+-0x712]**(0xe09*-0x2+-0x16fa+-0x51b*-0xa))<0x1cac+-0x1308+-0x9a4+0.05,'description':m};}function p(b){const T=a0d;return-0x1d23*-0x1+-0x1*-0x1dfe+0x2*-0x1d7c===b?'ICOA{vla_prompt_inject}':0x1*-0xf72+-0x88f+0x1*0x182b===b?T(0x15a):-0x16c9+0x20a9+-0x9b5===b?T(0xf2):-0xe75+0xee5+-0x44===b?'ICOA{action_jailbreak}':-0x25d7+0x1f7f+-0x685*-0x1===b?T(0x12f):'ICOA{unknown}';}export async function handleCtf4VlaMessage(h){const U=a0d;if(!c)return'exit';const j=h[U(0x105)](),k=j[U(0x144)]();if(a0z('ctf4vla:\x20'+j),U(0x123)===k||'back'===k||U(0x164)===k)return g=!(-0x31*-0x5d+-0x2*0xd55+0x8de),c=null,console[U(0xf3)](),console[U(0xf3)](a0m[U(0x177)](U(0x121))),console[U(0xf3)](),U(0x123);if(U(0x114)===k||k[U(0x141)](U(0xfa)))return await async function(x,z){const V=U,A=(process.env.ICOA_SERVER_URL?.['replace'](/\/+$/,'')||V(0x131))+'/api/ai/vla/'+x+V(0x161);console['log']();const {fetchWithCountdown:B}=await import(V(0x13f));try{const C={};C[V(0x173)]=V(0x139);const D={};D[V(0x10e)]=z??null;const E=fetch(A,{'method':V(0x14a),'headers':C,'body':JSON[V(0x148)](D),'signal':AbortSignal[V(0x11f)](-0x988b+0x2*-0x11af+0x13119)}),F=await B(E);if(!F['ok']){const M=await F[V(0x111)]()['catch'](()=>'');return void console[V(0xf3)](a0m[V(0x115)]('\x20\x20Render\x20failed\x20('+F[V(0x127)]+V(0x13a)+M['slice'](-0x1c8c+0x1d7d+0xf1*-0x1,0x385*-0xb+0x3b*0x4f+0x14fa)));}const G=await F[V(0x10b)]();if(!G[V(0x132)]||!G[V(0xfd)]?.[V(0x15c)])return void console[V(0xf3)](a0m[V(0x115)](V(0x13b)));const H=process.env.TMPDIR||V(0x12e),I=a0x(H,V(0x103)+x+'-'+Date[V(0x17a)]()+'.mp4'),{writeFileSync:J}=await import(V(0x129));J(I,Buffer[V(0x124)](G[V(0xfd)]['mp4_b64'],V(0x14c))),console[V(0xf3)](a0m[V(0x171)](V(0x147))+a0m['gray']('Rendered.')),G[V(0xfd)][V(0xfb)]&&console[V(0xf3)](a0m['gray'](V(0x125))+a0m[V(0x10c)](G[V(0xfd)]['description']));const K=V(0x120)===process[V(0x15e)]?'open':V(0x110)===process['platform']?V(0x156):'xdg-open',L={};L[V(0xf7)]=V(0x106),L[V(0x133)]=!(0x1*-0xf53+-0x1199+0x20ec),K?(a0y(K,[I],L)[V(0x179)](),console['log'](a0m[V(0x177)](V(0x10d)))):console[V(0xf3)](a0m[V(0x177)](V(0x13d)));}catch(N){const O=N instanceof Error?N[V(0x142)]:String(N);console[V(0xf3)](a0m[V(0x115)](V(0xfe)+O));}}(c['qNum']),U(0x10a);if(U(0x11a)===k){const x=c['question'][U(0x135)]||U(0x160),z=u(x,c[U(0xfc)]);return c[U(0x163)]=!(-0x82f+-0x2161+0x2990),console[U(0xf3)](),console[U(0xf3)](a0m[U(0x177)](U(0x14d))+a0m[U(0x10c)]('\x22'+x+'\x22')),console[U(0xf3)](a0m[U(0x177)](U(0x16b))+a0m['white'](z[U(0xfb)])),console[U(0xf3)](),U(0x10a);}const q=j[U(0x11e)](/^probe\s+["']?(.+?)["']?\s*$/i);if(q){c['probesUsed']+=-0x1c*-0x67+-0x1*-0x14ff+-0x2042;const A=u(q[0x1*0x1343+-0x1bce+0x2*0x446],c[U(0xfc)]);if(console['log'](),console[U(0xf3)](a0m['gray']('\x20\x20→\x20')+a0m[U(0x154)]('ICOA-VLA\x20action:\x20')+a0m[U(0x10c)](A['description'])),A['flagCondition']){const B=p(c[U(0xfc)]);console['log'](),console[U(0xf3)](a0m[U(0x151)][U(0x171)](U(0x116))+a0m['bold'][U(0x115)](B)),console[U(0xf3)](a0m[U(0x177)](U(0x118))+a0m[U(0x151)][U(0x171)]('submit\x20'+B)+a0m[U(0x177)](U(0x16d)));}else console[U(0xf3)](a0m[U(0x177)](U(0x145)));return console[U(0xf3)](),'continue';}const v=j['match'](/^image\s+(.+)$/i);if(v){const C=function(D,E){const W=U,F={};F[W(0x168)]=0.95,F[W(0x158)]=[0x1c4a+0x109c+-0x2ce6+0.31,-0x4b8+-0x1d5*-0x5+-0x471+0.12,-0x21e5+-0xb*-0x177+-0x1*-0x11c8+0.45],F[W(0x104)]=!(-0x1ba0*0x1+0xb*0x43+-0x18*-0x108),F['description']='no\x20image\x20uploaded\x20—\x20baseline\x20action\x20returned';if(!a0v(D))return F;const G=a0q(D)['length'],H={};H['gripper']=0.9,H['xyz']=[-(0x8d*-0x28+0x2029*0x1+-0xa21+0.28),0xab7*0x1+-0x160e+0xb57+0.12,0x53f*-0x4+-0x762+0x1c5e+0.45],H[W(0x104)]=!(0x1acd+0x5b*0x56+-0x395f),H[W(0xfb)]=W(0x11b);const I={};return I[W(0x168)]=0.95,I['xyz']=[0x1f49+-0x6b9*0x5+0x95*0x4+0.31,-0x2*-0x22f+0xc*0x72+-0x9b6+0.12,-0x1d7d+-0x1*0x1c1f+0x6*0x99a+0.45],I[W(0x104)]=!(0x32*-0x4a+0x40*-0x91+0x32b5*0x1),I[W(0xfb)]='image\x20accepted\x20but\x20no\x20action\x20drift\x20detected',-0x2617+0xc*0xbf+0x1d4d===E&&G>-0x166d*0x1+0xebb+0xbb2?H:I;}(a0w(v[-0x436*0x7+0x320+0x1a5b][U(0x105)]()),c[U(0xfc)]);if(console[U(0xf3)](),console['log'](a0m[U(0x177)](U(0xf9))),console[U(0xf3)](a0m[U(0x177)](U(0x157))+a0m[U(0x154)]('ICOA-VLA\x20action:\x20')+a0m[U(0x10c)](C[U(0xfb)])),C[U(0x104)]){const D=p(c['qNum']);console[U(0xf3)](),console[U(0xf3)](a0m[U(0x151)]['green'](U(0x116))+a0m['bold'][U(0x115)](D));}return console['log'](),U(0x10a);}const w=j[U(0x11e)](/^submit\s+(.+)/i);if(w){let E=w[0x1504+0x16*0x79+-0x1f69]['trim']();if(/^submit\s+/i[U(0x175)](E)&&(E=E['replace'](/^submit\s+/i,'')[U(0x105)]()),E=E[U(0x172)](/^["'`]+|["'`]+$/g,'')[U(0x105)](),/^[A-Da-d]$/[U(0x175)](E))return console['log'](),console['log'](a0m[U(0x115)](U(0x178)+E+U(0x137))),console[U(0xf3)](a0m[U(0x177)](U(0x113))+a0m['green'](U(0x159))),console[U(0xf3)](),U(0x10a);const F=a0A();if(!F)return'exit';const G=F[U(0x153)][c[U(0xfc)]];return F[U(0x140)]||(F[U(0x140)]=[]),F[U(0x140)][U(0x170)]({'ts':new Date()[U(0x14b)](),'q':c[U(0xfc)],'type':G?U(0x17d):U(0xf4),'input':E,'result':'via\x20ctf4vla'}),F['answers'][c[U(0xfc)]]=E,F[U(0xf5)]=c['qNum']+(-0x45+0x706+0x1b0*-0x4)<=-0xbf*-0x25+0x142d+0x2f9b*-0x1?c[U(0xfc)]+(0x556*-0x5+0x8f*-0x35+0x384a):c[U(0xfc)],a0B(F),console['log'](),G?console[U(0xf3)](a0m[U(0x171)](U(0x100)+c[U(0xfc)]+'\x20answer\x20updated:\x20')+a0m[U(0x115)](E)):console[U(0xf3)](a0m[U(0x171)]['bold'](U(0x12b)+c[U(0xfc)]+'\x20recorded:\x20'+E)),console[U(0xf3)](a0m[U(0x177)]('\x20\x20(Correctness\x20shown\x20after\x20final\x20exam\x20submit.)')),console[U(0xf3)](),U(0x10a);}return console[U(0xf3)](),console[U(0xf3)](a0m[U(0x177)]('\x20\x20Try\x20one\x20of:\x20')+a0m[U(0x10c)](U(0x146))),console[U(0xf3)](),U(0x10a);}export function registerCtf4VlaCommand(b){const X=a0d;b[X(0x136)](X(0x149))['alias'](X(0x107))[X(0xfb)](X(0x112))[X(0x10e)](()=>{const Y=X,d=a0A();if(!d)return void a0C(Y(0xff));const f=d[Y(0xf5)]||-0x13*-0xef+0x67f*-0x1+0x1*-0xb15;enterCtf4Vla(f>=0x1114+0x22cc+0x113d*-0x3&&f<=0x12f7+-0xd50+0x2*-0x2bd?f:-0x2*-0x863+-0x4c*-0x65+-0x1*0x2e99);});}function a0b(){const Z=['C2LT','EwvSBg93','icdINjmGv2LUignVBMrPDgLVBIbTzxqHicbgBgfNoIa','icaGihn1yM1PDcbjq09bEY4UlN0','icbuExbLia','z3jPChbLCIbpuevosu5hicG','yMfZzwXPBMu','z3jPChbLCIbJBg9ZAw5Nigf0icGTmc4YocWGmc4XmIWGmc40nsKG4OcuifrbuKDfvcbtseLgveveihrVihjPz2H0ihnPzguGkgTUAwzLkq','y2f0zwDVCNK','icdILiZILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILia','Bwf0y2G','DgLTzw91Da','zgfYD2LU','icbszxr1CM5Lzcb0BYbLEgfTlG','rufj','zxHPDa','zNjVBq','icbby3rPB246ia','C2XPy2u','C3rHDhvZ','ntq3mK9SsfLgvW','BM9KztPMCW','icaGicaGicaGicaGicaGicaGihjLDhvYBIb0BYbLEgfT','icdINjmGqw5ZD2vYigzVCIbr','ndi3mfLYAKfhsG','nde2ntj0we9XvwS','l3rTCa','sunpqxTIywnRzg9VCL90CMLNz2vYFq','icdILzdILzdILzaGq1rgnevbssdIGjqGuq','Ahr0Chm6lY9WCMfJDgLJzs5Py29HmJaYnI5HDq','C3vJy2vZCW','zgv0ywnOzwq','mZeXmgfmueDArG','yMfZzwXPBMvjBNn0CNvJDgLVBG','y29TBwfUza','iIbSB29RCYbSAwTLigfUie1dusbSzxr0zxiSig5VDcbHigzSywCU','Cg9PBNrZ','yxbWBgLJyxrPB24VANnVBG','ktOG','icbszw5KzxjLCIbYzxr1CM5LzcbUBYb2AwrLBYaOtxvkB0nVihvUyxzHAwXHyMXLig9UigjHy2TLBMqPlG','icbiB3CGDg8Gyxr0ywnRihrOAxmGvKXb','icbpCgvUihrOzsbMAwXLigfIB3zLigLUihLVDxiGDMLKzw8GCgXHEwvYlG','icaGig1LBNu','lI4VBgLIl2nVDw50zg93BI5QCW','Aw50zxjHy3rPB25Z','C3rHCNrZv2L0Aa','BwvZC2fNzq','icbdDxjYzw50igfUC3DLCJOG','Dg9mB3DLCKnHC2u','icaOBM8GD2LUihLLDcdIGjqGA2vLCcbPDgvYyxrPBMCP','yMfZzwXPBMuGlYbWCM9IzsaIlI4UiIaVigLTywDLidXWyxrOpIaVigHPBNqGys9Il2mGlYbZDwjTAxqGsunpqxSUlI59ic8GzxHPDa','icdINjmG','C3rYAw5NAwz5','y3rMngvHAq','ue9tva','Dg9ju09tDhjPBMC','yMfZzty0','icbezwzHDwX0igLUC3rYDwn0Aw9UoIa','icdILii','rMXHzYbMB3jTyxq6icaGieLdt0f7lI4UFq','ntuYmJK4BKTOzgHs','yM9Sza','icbB','yw5ZD2vYCW','y3LHBG','mtK1nZG1ENbuwePJ','C3rHCNq','icdIHPiG','EhL6','sunpqxT5B3vYx2zSywD9','sunpqxTWyxrJAf9YzwrPCMvJDh0','icaGicaGicaGicaGicaGicaGicbYzxbSyxKGy3vYCMvUDcbHy3rPB24GAw4GtxvkB0nVicHHDxrVlw9Wzw5Zie1qncK','Bxa0x2i2na','CMfUzg9T','CgXHDgzVCM0','icaGicaGicaGicb1CgXVywqGBw9KAwzPzwqGAw1Hz2uGkgfKDMvYC2fYAwfSihbHDgnOkq','ugLJAYb1Ccb0AguGCMvKign1Ca','l3nPBq','lI4U','yMfZzwXPBMvtzwvU','CxvPDa','icaGihnPBq','mJGYnduYqunmChrY','zxHHBsbXia','z3jPChbLCG','Dg9gAxHLza','igLZig5VDcbHifzmqsbJAgfSBgvUz2uU','icbjq09blvzmqsbHy3rPB246ia','nteWuhbqyuLx','ihrVihjLy29Yzcb5B3vYigfUC3DLCI4','uxvLC3rPB24G','DMXH','ChvZAa','z3jLzw4','CMvWBgfJzq','q29UDgvUDc1uExbL','mZe0mdvYC3PZBwS','DgvZDa','xsaGWRCG','z3jHEq','icaI','Dw5Yzwy','BM93','icaGihbYB2jLici8Aw5ZDhj1y3rPB24+iG','icdILjtILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILidILia','yw5ZD2vYx2nOyw5Nzwq','icdILiiG','zMLUza','icaGigLTywDLidXWyxrOpG','sunpqxT2BgfFy29UzNvZzwr9','Bg9N','yw5ZD2vYx3n1yM1PDhrLza','x2XHC3rr','ig5VDcbPBIbJDxjYzw50igv4yw0U','C3rKAw8','ksWGyxjTigHVBgrZihbVC2L0Aw9U','icbvCgXVywrPBMCGAw1Hz2uUlI4','C2LTia','zgvZy3jPChrPB24','Cu51Bq','zgf0yq','icbtAw0GzxjYB3i6ia','tM8GzxHHBsbPBIbWCM9NCMvZCY4GuNvUigbLEgfTidX0B2TLBJ5GigzPCNn0lG','icdINjmGuq','icHZDwjTAxqGywDHAw4GDg8Gy2HHBMDLkq','BNvTyMvY','AwnVys1ZAw0TCq','zMXHz0nVBMrPDgLVBG','DhjPBq','AwDUB3jL','y3rMnhzSyq','CxvLC3rPB24','CxvLC3rPB25Z','y29UDgLUDwu','ANnVBG','D2HPDgu','icbpCgvUAw5NigLUihLVDxiGzgvMyxvSDcb2AwrLBYbWBgf5zxiUlI4','ywn0Aw9U','mtqZoduWCxHiD3zb','D2LUmZi','Dgv4Da','rw50zxiGDgHLievTyM9KAwvKiefjihnLy3vYAxr5ignOywXSzw5NzsaOugfWzxiGrcWGutqXlve0nsK','icbgBgfNigzVCM1HDdOG'];a0b=function(){return Z;};return a0b();}
@@ -1 +1 @@
1
- import{spawnSync as e}from"node:child_process";import{copyFileSync as o,existsSync as t,mkdirSync as n,readFileSync as r,writeFileSync as s}from"node:fs";import{homedir as a}from"node:os";import{join as c}from"node:path";import chalk from"chalk";import{getConfig as i}from"../lib/config.js";import{runInteractive as l}from"../lib/interactive-spawn.js";import{lazyTarball as u}from"../lib/lazy-assets.js";import{contestStart as d,contestSubmit as g,duckBoard as p}from"../lib/learn-contest.js";import{listLearnSessions as m}from"../lib/learn-state.js";import{logCommand as k}from"../lib/logger.js";import{mujocoPaths as y,probeMujoco as h}from"../lib/mujoco-setup.js";import{openFile as b}from"../lib/open-file.js";import{makeReplAsker as f}from"../lib/repl-asker.js";import{ARENA_VI_FLAGS as $}from"../lib/vi-flags.js";const w=()=>(i().language||"en").toLowerCase().startsWith("zh"),v=(e,o)=>w()?e:o,_=c(a(),".icoa","duck"),x=c(_,"control.py"),C=c(_,"state.json"),j=c(_,"last.png"),S={edit:"edit",e:"edit",vi:"edit",code:"edit",syntax:"syntax",api:"syntax",doc:"syntax",docs:"syntax",run:"run",r:"run",play:"run",sim:"run",go:"run",replay:"replay",show:"replay",picture:"replay",open:"replay",submit:"submit",s:"submit",judge:"submit",ac:"submit",status:"status",st:"status",progress:"status",scenarios:"scenarios",scenario:"scenarios",list:"scenarios",checkpoints:"scenarios",board:"board",rank:"board",ranking:"board",leaderboard:"board",top:"board",help:"help","?":"help",h:"help",back:"back",quit:"back",q:"back",exit:"back",menu:"menu"};export function normalizeDuckVerb(e){const o=e.trim().replace(/^\//,"").split(/\s+/).filter(Boolean);return 0===o.length?{verb:"unknown",args:[]}:{verb:S[o[0].toLowerCase()]??"unknown",args:o.slice(1)}}export function pickCheckpoint(e,o){if(!o)return null;const t=o.toLowerCase(),n=e.find(e=>e.scenario===t);if(n)return n;const r=/^([cr])?(\d+)$/.exec(t);if(!r)return null;const s=Number(r[2]);return"r"===r[1]?e.find(e=>e.scenario?.startsWith(`r${s}_`))??null:e.find(e=>e.scenario?.startsWith(`c${s}_`))??e.find(e=>e.card===s)??null}function N(o,t,n,r=18e4){const s=e(o,[c(t,"duck_cli.py"),...n],{encoding:"utf-8",timeout:r,env:{...process.env,PYTHONDONTWRITEBYTECODE:"1",OMP_NUM_THREADS:"1",MUJOCO_GL:"disable"}}),a=(s.stdout||"").trim().split("\n").pop()||"";try{return JSON.parse(a)}catch{return{error:"engine",message:(s.stderr||"").trim().split("\n").slice(-3).join(" ")||`exit ${s.status}`}}}function A(e){n(_,{recursive:!0}),s(C,JSON.stringify(e,null,1))}const D=e=>e.filter(e=>!e.race),T=e=>e.filter(e=>e.race);function E(e,o){return D(e).find(e=>!o.ac.includes(e.card))??null}function O(){try{return m().find(e=>"mduck-48"===e.curriculumId)?.token??null}catch{return null}}const z=e=>w()&&e.title_zh?e.title_zh:e.title,B=e=>e.race?`R${e.slot} · ${z(e)}`:`C${e.slot+3*(e.phase-1)} · ${v("卡","card")} ${e.card} · ${z(e)}`;function M(e){b(e)?console.log(chalk.gray(v(" 正在打开图片…"," opening the picture…"))):console.log(chalk.gray(v(` 图在这里,用文件浏览器打开:${e}`,` The picture is here — open it from your file browser: ${e}`)))}function q(e,o,t){const n=E(e,o);var r;console.log(chalk.gray(n?v(" 当前检查点:"," Checkpoint: ")+B(n)+chalk.gray(` — ${r=n,w()&&r.pass_zh?r.pass_zh:r.pass}`):v(" 12/12 全部 AC"," 12/12 AC"))),t||console.log(chalk.gray(v(" 🦆 本机没有仿真 — "," 🦆 No sim on this machine — ")+chalk.bold.green("mujoco setup")+v(" 装上后 run 才出图;submit 照样能交,判分机替你跑。"," to run here; submit still works, the judge runs it for you.")));const s=O();console.log(chalk.gray(s?v(` ☁ submit 走服务端判分 · token ${s.slice(0,2)}••••••${s.slice(-2)}`,` ☁ submit is judged on the server · token ${s.slice(0,2)}••••••${s.slice(-2)}`):v(" (没有 mduck-48 token:run 可用,submit 不可用)"," (no mduck-48 token on this machine: run works, submit does not)"))),console.log(chalk.gray(v(" edit · syntax · run [c4] · replay · submit · board · scenarios · status · back(回上一层)· menu"," edit · syntax · run [c4] · replay · submit · board · scenarios · status · back (one level up) · menu")))}function I(e,o){console.log(chalk.bold.white(v(" Duck ABC · mduck-48"," Duck ABC · mduck-48")));const t=E(e,o);for(const n of[...D(e),...T(e)]){n.race&&n===T(e)[0]&&console.log(chalk.bold.white(v(" 赛日(不计入 12 关)"," Race day (not counted in the 12)")));const r=o.ac.includes(n.card),s=o.attempts[String(n.card)]??[],a=!r&&s.length?chalk.gray(v(` (跑了 ${s.length} 次)`,` (${s.length} runs)`)):"",c=n===t?chalk.cyan(v(" ← 当前"," ← now")):"";console.log(` ${r?"✅":"⬜"} ${chalk.white(B(n))}${a}${c}`)}}function J(e){const o=e.line;return"syntax"===e.error?(console.log(chalk.yellow(v(" ✗ 语法不对"," ✗ Syntax error")+(o?v(`,第 ${o} 行:`,`, line ${o}:`):":"))+chalk.yellow(` ${String(e.message??"")}`)),e.text&&console.log(chalk.yellow(` ${String(e.text)}`)),void console.log(chalk.gray(v(" ▸ edit 改完再 run"," ▸ edit, then run again")))):"control"===e.error?(console.log(chalk.yellow(v(" ✗ control() 返回的东西套件不认:"," ✗ control() returned something the kit does not accept:"))),console.log(chalk.yellow(` ${String(e.message??"")}`)),void console.log(chalk.gray(v(" ▸ syntax 看每个字段 ▸ edit"," ▸ syntax lists every field ▸ edit")))):"runtime"===e.error?(console.log(chalk.yellow(v(" ✗ control.py 跑到一半出错"," ✗ control.py crashed")+(o?v(`(第 ${o} 行)`,` (line ${o})`):"")+":")),console.log(chalk.yellow(` ${String(e.message??"")}`)),void console.log(chalk.gray(v(" ▸ edit 改一改再 run"," ▸ edit, then run again")))):void console.log(chalk.yellow(v(" 引擎出错:"," Engine error: ")+String(e.message??e.error??"")))}const R=new Set(["c7_point","c8_wall","c9_push","r2_wall","r3_final"]),W=(e,o="")=>null==e?"—":(Number.isInteger(e)?String(e):e.toFixed(3))+o;async function L(e,o,t={}){const n=o.scenario&&R.has(o.scenario)?"asc":"desc",r=await p(e,o.race?`duck-r${o.slot}`:`duck-c${o.card}`,{order:n,limit:10});if(!r.ok||!r.data)return void(t.ticker||console.log(chalk.gray(v(" 榜单暂时拿不到。"," The board is not reachable right now."))));const s=r.data,a=(e=>"c5_turn"===e.scenario?"°":e.race&&"r1_sprint"!==e.scenario?"s":/_(sprint|walk|point|wall|push)$/.test(e.scenario??"")?"m":"")(o);if(t.ticker){const e=s.board[0],t=s.mine;if(!t)return;const n=e&&!e.me?v(` · 榜首 ${e.name} ${W(e.value,a)}`,` · leader ${e.name} ${W(e.value,a)}`):"",r=Math.max(s.entrants,t.rank);return void console.log(chalk.gray(v(` 🏅 ${z(o)} 榜:你第 ${t.rank} / ${r} · ${W(t.value,a)}`,` 🏅 ${z(o)} board: you are #${t.rank} of ${r} · ${W(t.value,a)}`)+n+v(" ▸ board 看全榜"," ▸ board for the full list")))}console.log(chalk.bold.white(` 🏆 ${B(o)}`)+chalk.gray(v(` · ${s.entrants} 人上榜 · ${"asc"===n?"越小越好":"越大越好"}`,` · ${s.entrants} on the board · ${"asc"===n?"lower is better":"higher is better"}`))),0===s.board.length&&console.log(chalk.gray(v(" 还没有人上榜 —— 第一个 AC 的就是榜首。"," Nobody yet — the first AC takes the top spot.")));for(const e of s.board){const o=` ${1===e.rank?"🥇":2===e.rank?"🥈":3===e.rank?"🥉":" "} ${String(e.rank).padStart(2)} ${e.name.padEnd(14)} ${W(e.value,a).padStart(9)} ${chalk.gray(v(`${e.submits} 次`,`${e.submits} submits`))}`;console.log(e.me?chalk.cyan(o)+chalk.cyan(v(" ← 你"," ← you")):chalk.white(o))}s.mine&&!s.board.some(e=>e.me)&&console.log(chalk.cyan(v(` 你:第 ${s.mine.rank} · ${W(s.mine.value,a)} · ${s.mine.submits} 次`,` you: #${s.mine.rank} · ${W(s.mine.value,a)} · ${s.mine.submits} submits`))),s.mine||console.log(chalk.gray(v(" 你还没交过这一关 —— submit 之后就上榜。"," You have not submitted this one yet — submit and you are on it.")))}export async function runDuck(e=[]){k(["duck",...e].join(" "));const i=Number((e.find(e=>e.startsWith("from-card:"))??"").slice(10))||0;e=e.filter(e=>!e.startsWith("from-card:")),console.log(chalk.gray(v(" 🦆 正在检查引擎版本…"," 🦆 checking the engine…")));const p=await async function(){const e=process.env.ICOA_DUCK_ENGINE_DIR;if(e&&t(c(e,"duck_cli.py")))return e;const o=await u("duck-engine.tar.gz","duck-engine",6e4,{revalidate:!0});return o&&t(c(o,"duck_cli.py"))?o:null}();if(!p)return console.log(chalk.yellow(v(" 机器人引擎还没到本机(需要联网拉一次,约 11 MB)。"," The robot engine is not on this machine yet (one online fetch, ~11 MB)."))),console.log(chalk.gray(v(" 联网后再敲 duck;联不上找组织者。"," Try `duck` again when online; ask the organiser if it keeps failing."))),"back";const m=h().ok,b=y(a()).python,S=(()=>{try{return JSON.parse(r(c(p,"checkpoints.json"),"utf-8"))}catch{return null}})();if(!Array.isArray(S))return console.log(chalk.yellow(v(" 引擎包不完整(没有 checkpoints.json)。"," The engine package is incomplete (no checkpoints.json)."))),"back";const z=S,R=function(){try{const e=JSON.parse(r(C,"utf-8"));return{ac:Array.isArray(e.ac)?e.ac:[],attempts:e.attempts??{}}}catch{return{ac:[],attempts:{}}}}();if(n(_,{recursive:!0}),!t(x)){const e=c(p,"control_template.py");if(m){const e=N(b,p,["template"]);"string"==typeof e.path&&t(e.path)&&o(e.path,x)}t(x)||s(x,t(e)?r(e,"utf-8"):'from duckkit import dist, heading_to, wrap_angle\n\n\ndef control(t, sense):\n return None # None = stand still. Try {"vx": 0.2}.\n'),console.log(chalk.gray(v(` (已把模板 control.py 放到 ${x})`,` (template control.py placed at ${x})`)))}console.log(),console.log(chalk.bold.cyan(v("🦆 鸭子仿真台","🦆 Duck sim bench"))+chalk.gray(v(" — 在这里改 control.py、本机跑仿真看图、提交检查点。 ↩ back 回上一层 · menu 回首页"," — edit control.py, run the sim here and look at the picture, submit checkpoints. ↩ back · menu"))),q(z,R,m);let W=i?z.find(e=>e.card===i)??null:null;const Y=f(),U=Y.ask;let G=0;try{for(;;){const e=await U(chalk.bold.cyan("icoa duck> "));if(null===e)return"back";if(!e.trim())continue;const{verb:o,args:n}=normalizeDuckVerb(e);switch("unknown"!==o&&(G=0),o){case"back":return"back";case"menu":return"menu";case"help":q(z,R,m);break;case"status":I(z,R);break;case"scenarios":for(const e of[...D(z),...T(z)])e.race&&e===T(z)[0]&&console.log(chalk.bold.white(v(" 赛日 —— 私有种子在判分机,本机 run 用练习种子"," Race day — private seeds live on the judge; local run uses practice seeds"))),console.log(` ${R.ac.includes(e.card)?"✅":"⬜"} ${chalk.white(`run ${e.scenario?e.scenario.split("_")[0]:"c40"}`.padEnd(9))} ${chalk.gray(B(e))}`);console.log(chalk.gray(v(" run c4 = 跑 c4_walk;不带参数 = 当前检查点。"," `run c4` runs c4_walk; bare `run` = the current checkpoint.")));break;case"board":{const e=O();if(!e){console.log(chalk.yellow(v(" 没有 mduck-48 token,看不了榜。"," No mduck-48 token on this machine — no board to show.")));break}const o=pickCheckpoint(z,n[0]);if(n[0]&&!o){console.log(chalk.yellow(v(` 不认识「${n[0]}」。`,` Don't know "${n[0]}".`))+chalk.gray(v(" scenarios 列出所有名字。"," `scenarios` lists the names.")));break}await L(e,o??W??E(z,R)??z[z.length-1]);break}case"syntax":{const e=(()=>{try{return w()&&m?String(N(b,p,["cheatsheet","--lang","zh"]).text??""):r(c(p,"syntax.txt"),"utf-8")}catch{return""}})();console.log(chalk.gray(e||v(" (速查表不在引擎包里)"," (no syntax sheet in the engine package)")));break}case"edit":console.log(chalk.gray(v(" vi 三键: i 进入编辑 · Esc 退出编辑 · :wq 存盘离开 · :q! 放弃"," vi survival: i = edit · Esc = stop editing · :wq = save and leave · :q! = discard"))),await l("vi",[...$,x]);break;case"replay":if(!t(j)){console.log(chalk.gray(v(" 还没有图。先 run 一次。"," No picture yet. `run` first.")));break}M(j);break;case"run":{const e=pickCheckpoint(z,n[0]);if(n[0]&&!e){console.log(chalk.yellow(v(` 不认识「${n[0]}」。`,` Don't know "${n[0]}".`))+chalk.gray(v(" scenarios 列出所有名字。"," `scenarios` lists the names.")));break}const o=e??W??E(z,R);if(!o){console.log(chalk.green(v(" 12 个检查点全部 AC。"," All 12 checkpoints AC.")));break}if(e&&(W=e),!o.scenario){console.log(chalk.gray(v(" 这一关是打印题,不在仿真里:写好程序直接 submit。"," This checkpoint is a print-a-number task, not a sim run: write the program and `submit`.")));break}if(!m){console.log(chalk.gray(v(" 本机没有仿真 — "," No sim on this machine — ")+chalk.bold.green("mujoco setup")+v("(~45 MB,免 sudo)。submit 照样能交。"," (~45 MB, no sudo). `submit` still works.")));break}process.stdout.write(chalk.gray(v(` ${B(o)} … `,` ${B(o)} … `)));const t=N(b,p,["run","--file",x,"--scenario",o.scenario,"--png",j]);if(console.log(),!0!==t.ok){J(t);break}const r=t.prints??[];for(const e of r.slice(0,12))console.log(chalk.white(` ${e}`));Number(t.prints_total)>12&&console.log(chalk.gray(v(` … 共 ${t.prints_total} 行输出`,` … ${t.prints_total} lines printed`)));const s=Boolean(t.pass);console.log((s?chalk.green(" ✓ "):chalk.yellow(" ✗ "))+chalk.white(String(t.detail??""))+chalk.gray(null!=t.fallen_at?v(` · 摔倒于 ${t.fallen_at} s`,` · fell at ${t.fallen_at} s`):"")+chalk.gray(` (${t.seconds} s ${v("仿真","sim")}, ${t.time_ms} ms)`));const a=R.attempts[String(o.card)]??[];a.push(s),R.attempts[String(o.card)]=a,A(R),console.log(chalk.gray(s?v(" ▸ submit 提交检查点 ▸ replay 再看图 ▸ edit 继续改"," ▸ submit ▸ replay the picture ▸ edit to keep improving"):v(" ▸ replay 看图找原因 ▸ edit 改一改再 run"," ▸ replay to see what happened ▸ edit, then run"))),"string"==typeof t.png&&process.stdout.isTTY&&M(t.png);break}case"submit":{const e=W??E(z,R);if(!e){console.log(chalk.green(v(" 全部 AC。"," All AC.")));break}if(m){const e=N(b,p,["syntax","--file",x]);if(!1===e.ok){J(e);break}}const o=O();if(!o){console.log(chalk.yellow(v(" 这台机器上没有 mduck-48 token,没法交。"," No mduck-48 token on this machine — nothing to submit with."))),console.log(chalk.gray(v(" ▸ learn 粘 token 后再来。"," ▸ paste your token in `learn`, then come back.")));break}const t=await d(o,e.phase,e.slot);if(!t.ok||!t.data){console.log(chalk.yellow(v(" 服务端没开门:"," Server did not open the checkpoint: ")+String(t.message??t.code??"")));break}const n=t.data.problems[0]?.id??(e.race?`duck-r${e.slot}`:`duck-c${e.card}`);console.log(chalk.gray(v(" ⚖ 判分中(服务端 · "," ⚖ judging (server · ")+B(e)+v(")… 约 5–10 秒",")… 5–10 s")));const s=await g(o,e.phase,n,r(x,"utf-8"),e.slot);if(!s.ok||!s.data){console.log(chalk.yellow(v(" 判分没回来:"," No verdict came back: ")+String(s.message??s.code??"")));break}const a=s.data;for(const e of(a.report??[]).slice(0,3))console.log(chalk.gray(` ${e}`));if(a.note&&console.log(chalk.gray(` ${a.note}`)),"AC"===a.verdict||!0===a.already_ac){R.ac.includes(e.card)||R.ac.push(e.card),A(R);const t=R.ac.filter(e=>e<=48).length;console.log(chalk.green(` ✅ AC · ${t}/12`+(1===t?v(" 🎉 第一个检查点!"," 🎉 first checkpoint!"):""))),await L(o,e,{ticker:!0});const n=D(z).find(o=>!R.ac.includes(o.card)&&o.card>e.card)??null,r=D(z).find(o=>!R.ac.includes(o.card)&&o.card<e.card)??null;W=null,console.log(chalk.green(e.race?v(" ▸ board 看榜 · 想刷成绩再 edit → run → submit"," ▸ board to see the ranking · edit → run → submit to improve"):n?v(` ▸ back 回卡片,读第 ${e.card+1} 张 —— 下一个检查点在卡 ${n.card}`,` ▸ back to the cards, read card ${e.card+1} — next checkpoint is card ${n.card}`):r?v(` ▸ 前面还有没做的检查点:卡 ${r.card}`,` ▸ an earlier checkpoint is still open: card ${r.card}`):v(" 🎓 12/12 —— 鸭子听你的了。"," 🎓 12/12 — the duck does what you say."))),!e.race&&n&&r&&console.log(chalk.gray(v(` (卡 ${r.card} 的检查点也还没做)`,` (card ${r.card}'s checkpoint is still open too)`)))}else console.log(chalk.yellow(v(` ❌ ${a.verdict}。`,` ❌ ${a.verdict}.`))+chalk.gray(v(" ▸ run 本机看图 ▸ edit"," ▸ run to see the picture ▸ edit")));break}default:if(G+=1,console.log(chalk.yellow(v(` 不认识「${e.trim()}」。`,` Don't know "${e.trim()}".`))+chalk.gray(v(" 可用:edit · syntax · run · replay · submit · board · scenarios · status · back"," Try: edit · syntax · run · replay · submit · board · scenarios · status · back"))),G>=3)return console.log(chalk.gray(v(" 连续三次没对上 —— 回上一层。"," Three misses — going back one level."))),"back"}}}finally{Y.close()}}export function registerDuckCommand(e){e.command("duck [args...]").description("Duck ABC sim bench — edit control.py, run the biped in MuJoCo on this machine, submit checkpoints").action(async e=>{await runDuck(e??[])})}
1
+ import{spawnSync as e}from"node:child_process";import{copyFileSync as o,existsSync as t,mkdirSync as n,readFileSync as r,writeFileSync as s}from"node:fs";import{homedir as a}from"node:os";import{join as c}from"node:path";import chalk from"chalk";import{getConfig as i}from"../lib/config.js";import{runInteractive as l}from"../lib/interactive-spawn.js";import{lazyTarball as u}from"../lib/lazy-assets.js";import{contestStart as d,contestSubmit as g,duckBoard as m}from"../lib/learn-contest.js";import{listLearnSessions as p}from"../lib/learn-state.js";import{logCommand as y}from"../lib/logger.js";import{mujocoPaths as k,probeMujoco as h}from"../lib/mujoco-setup.js";import{openFile as b}from"../lib/open-file.js";import{makeReplAsker as f}from"../lib/repl-asker.js";import{ARENA_VI_FLAGS as $}from"../lib/vi-flags.js";const w=()=>(i().language||"en").toLowerCase().startsWith("zh"),v=(e,o)=>w()?e:o,_=c(a(),".icoa","duck"),x=c(_,"control.py"),C=c(_,"state.json"),j=c(_,"last.png"),S={edit:"edit",e:"edit",vi:"edit",code:"edit",syntax:"syntax",api:"syntax",doc:"syntax",docs:"syntax",run:"run",r:"run",play:"run",sim:"run",go:"run",replay:"replay",show:"replay",picture:"replay",open:"replay",submit:"submit",s:"submit",judge:"submit",ac:"submit",status:"status",st:"status",progress:"status",scenarios:"scenarios",scenario:"scenarios",list:"scenarios",checkpoints:"scenarios",board:"board",rank:"board",ranking:"board",leaderboard:"board",top:"board",help:"help","?":"help",h:"help",back:"back",quit:"back",q:"back",exit:"back",menu:"menu"};export function normalizeDuckVerb(e){const o=e.trim().replace(/^\//,"").split(/\s+/).filter(Boolean);return 0===o.length?{verb:"unknown",args:[]}:{verb:S[o[0].toLowerCase()]??"unknown",args:o.slice(1)}}export function pickCheckpoint(e,o){if(!o)return null;const t=o.toLowerCase(),n=e.find(e=>e.scenario===t);if(n)return n;const r=/^([cr])?(\d+)$/.exec(t);if(!r)return null;const s=Number(r[2]);return"r"===r[1]?e.find(e=>e.scenario?.startsWith(`r${s}_`))??null:e.find(e=>e.scenario?.startsWith(`c${s}_`))??e.find(e=>e.card===s)??null}function N(o,t,n,r=18e4){const s=e(o,[c(t,"duck_cli.py"),...n],{encoding:"utf-8",timeout:r,env:{...process.env,PYTHONDONTWRITEBYTECODE:"1",OMP_NUM_THREADS:"1",MUJOCO_GL:"disable"}}),a=(s.stdout||"").trim().split("\n").pop()||"";try{return JSON.parse(a)}catch{return{error:"engine",message:(s.stderr||"").trim().split("\n").slice(-3).join(" ")||`exit ${s.status}`}}}function A(e){n(_,{recursive:!0}),s(C,JSON.stringify(e,null,1))}const D=e=>e.filter(e=>!e.race),T=e=>e.filter(e=>e.race);function E(e,o){return D(e).find(e=>!o.ac.includes(e.card))??null}function M(){try{return p().find(e=>"mduck-48"===e.curriculumId)?.token??null}catch{return null}}const O=e=>w()&&e.title_zh?e.title_zh:e.title,z=e=>e.race?`R${e.slot} · ${O(e)}`:`C${e.slot+3*(e.phase-1)} · ${v("卡","card")} ${e.card} · ${O(e)}`;function B(e){b(e)?console.log(chalk.gray(v(" 正在打开图片…"," opening the picture…"))):console.log(chalk.gray(v(` 图在这里,用文件浏览器打开:${e}`,` The picture is here — open it from your file browser: ${e}`)))}function R(e,o,t){const n=E(e,o);var r;console.log(chalk.gray(n?v(" 当前检查点:"," Checkpoint: ")+z(n)+chalk.gray(` — ${r=n,w()&&r.pass_zh?r.pass_zh:r.pass}`):v(" 12/12 全部 AC"," 12/12 AC"))),t||console.log(chalk.gray(v(" 🦆 本机没有仿真 — "," 🦆 No sim on this machine — ")+chalk.bold.green("mujoco setup")+v(" 装上后 run 才出图;submit 照样能交,判分机替你跑。"," to run here; submit still works, the judge runs it for you.")));const s=M();console.log(chalk.gray(s?v(` ☁ submit 走服务端判分 · token ${s.slice(0,2)}••••••${s.slice(-2)}`,` ☁ submit is judged on the server · token ${s.slice(0,2)}••••••${s.slice(-2)}`):v(" (没有 mduck-48 token:run 可用,submit 不可用)"," (no mduck-48 token on this machine: run works, submit does not)"))),console.log(chalk.gray(v(" edit · syntax · run [c4] · replay · submit · board · scenarios · status · back(回上一层)· menu"," edit · syntax · run [c4] · replay · submit · board · scenarios · status · back (one level up) · menu")))}function q(e,o){console.log(chalk.bold.white(v(" Duck ABC · mduck-48"," Duck ABC · mduck-48")));const t=E(e,o);for(const n of[...D(e),...T(e)]){n.race&&n===T(e)[0]&&console.log(chalk.bold.white(v(" 赛日(不计入 12 关)"," Race day (not counted in the 12)")));const r=o.ac.includes(n.card),s=o.attempts[String(n.card)]??[],a=!r&&s.length?chalk.gray(v(` (跑了 ${s.length} 次)`,` (${s.length} runs)`)):"",c=n===t?chalk.cyan(v(" ← 当前"," ← now")):"";console.log(` ${r?"✅":"⬜"} ${chalk.white(z(n))}${a}${c}`)}}function I(e){const o=e.line;return"syntax"===e.error?(console.log(chalk.yellow(v(" ✗ 语法不对"," ✗ Syntax error")+(o?v(`,第 ${o} 行:`,`, line ${o}:`):":"))+chalk.yellow(` ${String(e.message??"")}`)),e.text&&console.log(chalk.yellow(` ${String(e.text)}`)),void console.log(chalk.gray(v(" ▸ edit 改完再 run"," ▸ edit, then run again")))):"control"===e.error?(console.log(chalk.yellow(v(" ✗ control() 返回的东西套件不认:"," ✗ control() returned something the kit does not accept:"))),console.log(chalk.yellow(` ${String(e.message??"")}`)),void console.log(chalk.gray(v(" ▸ syntax 看每个字段 ▸ edit"," ▸ syntax lists every field ▸ edit")))):"runtime"===e.error?(console.log(chalk.yellow(v(" ✗ control.py 跑到一半出错"," ✗ control.py crashed")+(o?v(`(第 ${o} 行)`,` (line ${o})`):"")+":")),console.log(chalk.yellow(` ${String(e.message??"")}`)),void console.log(chalk.gray(v(" ▸ edit 改一改再 run"," ▸ edit, then run again")))):void console.log(chalk.yellow(v(" 引擎出错:"," Engine error: ")+String(e.message??e.error??"")))}const J=new Set(["c7_point","c8_wall","c9_push","r2_wall","r3_final"]),W=(e,o="")=>null==e?"—":(Number.isInteger(e)?String(e):e.toFixed(3))+o;async function L(e,o,t={}){const n=o.order??(o.scenario&&J.has(o.scenario)?"asc":"desc"),r=await m(e,o.race?`duck-r${o.slot}`:`duck-c${o.card}`,{order:n,limit:10});if(!r.ok||!r.data)return void(t.ticker||console.log(chalk.gray(v(" 榜单暂时拿不到。"," The board is not reachable right now."))));const s=r.data,a=o.unit??(e=>"c5_turn"===e.scenario?"°":e.race&&"r1_sprint"!==e.scenario?"s":/_(sprint|walk|point|wall|push)$/.test(e.scenario??"")?"m":"")(o);if(t.ticker){const e=s.board[0],t=s.mine;if(!t)return;const n=e&&!e.me?v(` · 榜首 ${e.name} ${W(e.value,a)}`,` · leader ${e.name} ${W(e.value,a)}`):"",r=Math.max(s.entrants,t.rank);return void console.log(chalk.gray(v(` 🏅 ${O(o)} 榜:你第 ${t.rank} / ${r} · ${W(t.value,a)}`,` 🏅 ${O(o)} board: you are #${t.rank} of ${r} · ${W(t.value,a)}`)+n+v(" ▸ board 看全榜"," ▸ board for the full list")))}console.log(chalk.bold.white(` 🏆 ${z(o)}`)+chalk.gray(v(` · ${s.entrants} 人上榜 · ${"asc"===n?"越小越好":"越大越好"}`,` · ${s.entrants} on the board · ${"asc"===n?"lower is better":"higher is better"}`))),0===s.board.length&&console.log(chalk.gray(v(" 还没有人上榜 —— 第一个 AC 的就是榜首。"," Nobody yet — the first AC takes the top spot.")));for(const e of s.board){const o=` ${1===e.rank?"🥇":2===e.rank?"🥈":3===e.rank?"🥉":" "} ${String(e.rank).padStart(2)} ${e.name.padEnd(14)} ${W(e.value,a).padStart(9)} ${chalk.gray(v(`${e.submits} 次`,`${e.submits} submits`))}`;console.log(e.me?chalk.cyan(o)+chalk.cyan(v(" ← 你"," ← you")):chalk.white(o))}s.mine&&!s.board.some(e=>e.me)&&console.log(chalk.cyan(v(` 你:第 ${s.mine.rank} · ${W(s.mine.value,a)} · ${s.mine.submits} 次`,` you: #${s.mine.rank} · ${W(s.mine.value,a)} · ${s.mine.submits} submits`))),s.mine||console.log(chalk.gray(v(" 你还没交过这一关 —— submit 之后就上榜。"," You have not submitted this one yet — submit and you are on it.")))}export async function runDuck(e=[]){y(["duck",...e].join(" "));const i=Number((e.find(e=>e.startsWith("from-card:"))??"").slice(10))||0;e=e.filter(e=>!e.startsWith("from-card:")),console.log(chalk.gray(v(" 🦆 正在检查引擎版本…"," 🦆 checking the engine…")));const m=await async function(){const e=process.env.ICOA_DUCK_ENGINE_DIR;if(e&&t(c(e,"duck_cli.py")))return e;const o=await u("duck-engine.tar.gz","duck-engine",6e4,{revalidate:!0});return o&&t(c(o,"duck_cli.py"))?o:null}();if(!m)return console.log(chalk.yellow(v(" 机器人引擎还没到本机(需要联网拉一次,约 11 MB)。"," The robot engine is not on this machine yet (one online fetch, ~11 MB)."))),console.log(chalk.gray(v(" 联网后再敲 duck;联不上找组织者。"," Try `duck` again when online; ask the organiser if it keeps failing."))),"back";const p=h().ok,b=k(a()).python,S=(()=>{try{return JSON.parse(r(c(m,"checkpoints.json"),"utf-8"))}catch{return null}})();if(!Array.isArray(S))return console.log(chalk.yellow(v(" 引擎包不完整(没有 checkpoints.json)。"," The engine package is incomplete (no checkpoints.json)."))),"back";const O=S,J=function(){try{const e=JSON.parse(r(C,"utf-8"));return{ac:Array.isArray(e.ac)?e.ac:[],attempts:e.attempts??{},demo:!0===e.demo}}catch{return{ac:[],attempts:{}}}}();if(n(_,{recursive:!0}),!t(x)){const e=c(m,"control_template.py");if(p){const e=N(b,m,["template"]);"string"==typeof e.path&&t(e.path)&&o(e.path,x)}t(x)||s(x,t(e)?r(e,"utf-8"):'from duckkit import dist, heading_to, wrap_angle\n\n\ndef control(t, sense):\n return None # None = stand still. Try {"vx": 0.2}.\n'),console.log(chalk.gray(v(` (已把模板 control.py 放到 ${x})`,` (template control.py placed at ${x})`)))}console.log(),console.log(chalk.bold.cyan(v("🦆 鸭子仿真台","🦆 Duck sim bench"))+chalk.gray(v(" — 在这里改 control.py、本机跑仿真看图、提交检查点。 ↩ back 回上一层 · menu 回首页"," — edit control.py, run the sim here and look at the picture, submit checkpoints. ↩ back · menu"))),R(O,J,p);const W=c(m,"demo","r3_final.png");!J.demo&&t(W)&&(J.demo=!0,A(J),console.log(chalk.cyan(v(" 🎯 这是赛日的任务桌:六个任务,60 s,满分 82 —— 参考解走出 74 分。随时 `run r3` 自己试。"," 🎯 This is the race-day table: six missions, 60 s, 82 max — the reference scores 74. `run r3` to try it any time."))),B(W));let Y=i?O.find(e=>e.card===i)??null:null;const U=f(),G=U.ask;let H=0;try{for(;;){const e=await G(chalk.bold.cyan("icoa duck> "));if(null===e)return"back";if(!e.trim())continue;const{verb:o,args:n}=normalizeDuckVerb(e);switch("unknown"!==o&&(H=0),o){case"back":return"back";case"menu":return"menu";case"help":R(O,J,p);break;case"status":q(O,J);break;case"scenarios":for(const e of[...D(O),...T(O)])e.race&&e===T(O)[0]&&console.log(chalk.bold.white(v(" 赛日 —— 私有种子在判分机,本机 run 用练习种子"," Race day — private seeds live on the judge; local run uses practice seeds"))),console.log(` ${J.ac.includes(e.card)?"✅":"⬜"} ${chalk.white(`run ${e.scenario?e.scenario.split("_")[0]:"c40"}`.padEnd(9))} ${chalk.gray(z(e))}`);console.log(chalk.gray(v(" run c4 = 跑 c4_walk;不带参数 = 当前检查点。"," `run c4` runs c4_walk; bare `run` = the current checkpoint.")));break;case"board":{const e=M();if(!e){console.log(chalk.yellow(v(" 没有 mduck-48 token,看不了榜。"," No mduck-48 token on this machine — no board to show.")));break}const o=pickCheckpoint(O,n[0]);if(n[0]&&!o){console.log(chalk.yellow(v(` 不认识「${n[0]}」。`,` Don't know "${n[0]}".`))+chalk.gray(v(" scenarios 列出所有名字。"," `scenarios` lists the names.")));break}await L(e,o??Y??E(O,J)??O[O.length-1]);break}case"syntax":{const e=(()=>{try{return w()&&p?String(N(b,m,["cheatsheet","--lang","zh"]).text??""):r(c(m,"syntax.txt"),"utf-8")}catch{return""}})();console.log(chalk.gray(e||v(" (速查表不在引擎包里)"," (no syntax sheet in the engine package)")));break}case"edit":console.log(chalk.gray(v(" vi 三键: i 进入编辑 · Esc 退出编辑 · :wq 存盘离开 · :q! 放弃"," vi survival: i = edit · Esc = stop editing · :wq = save and leave · :q! = discard"))),await l("vi",[...$,x]);break;case"replay":if(!t(j)){console.log(chalk.gray(v(" 还没有图。先 run 一次。"," No picture yet. `run` first.")));break}B(j);break;case"run":{const e=pickCheckpoint(O,n[0]);if(n[0]&&!e){console.log(chalk.yellow(v(` 不认识「${n[0]}」。`,` Don't know "${n[0]}".`))+chalk.gray(v(" scenarios 列出所有名字。"," `scenarios` lists the names.")));break}const o=e??Y??E(O,J);if(!o){console.log(chalk.green(v(" 12 个检查点全部 AC。"," All 12 checkpoints AC.")));break}if(e&&(Y=e),!o.scenario){console.log(chalk.gray(v(" 这一关是打印题,不在仿真里:写好程序直接 submit。"," This checkpoint is a print-a-number task, not a sim run: write the program and `submit`.")));break}if(!p){console.log(chalk.gray(v(" 本机没有仿真 — "," No sim on this machine — ")+chalk.bold.green("mujoco setup")+v("(~45 MB,免 sudo)。submit 照样能交。"," (~45 MB, no sudo). `submit` still works.")));break}process.stdout.write(chalk.gray(v(` ${z(o)} … `,` ${z(o)} … `)));const t=N(b,m,["run","--file",x,"--scenario",o.scenario,"--png",j]);if(console.log(),!0!==t.ok){I(t);break}const r=t.prints??[];for(const e of r.slice(0,12))console.log(chalk.white(` ${e}`));Number(t.prints_total)>12&&console.log(chalk.gray(v(` … 共 ${t.prints_total} 行输出`,` … ${t.prints_total} lines printed`)));const s=Boolean(t.pass);console.log((s?chalk.green(" ✓ "):chalk.yellow(" ✗ "))+chalk.white(String(t.detail??""))+chalk.gray(null!=t.fallen_at?v(` · 摔倒于 ${t.fallen_at} s`,` · fell at ${t.fallen_at} s`):"")+chalk.gray(` (${t.seconds} s ${v("仿真","sim")}, ${t.time_ms} ms)`));const a=J.attempts[String(o.card)]??[];a.push(s),J.attempts[String(o.card)]=a,A(J),console.log(chalk.gray(s?v(" ▸ submit 提交检查点 ▸ replay 再看图 ▸ edit 继续改"," ▸ submit ▸ replay the picture ▸ edit to keep improving"):v(" ▸ replay 看图找原因 ▸ edit 改一改再 run"," ▸ replay to see what happened ▸ edit, then run"))),"string"==typeof t.png&&process.stdout.isTTY&&B(t.png);break}case"submit":{const e=Y??E(O,J);if(!e){console.log(chalk.green(v(" 全部 AC。"," All AC.")));break}if(p){const e=N(b,m,["syntax","--file",x]);if(!1===e.ok){I(e);break}}const o=M();if(!o){console.log(chalk.yellow(v(" 这台机器上没有 mduck-48 token,没法交。"," No mduck-48 token on this machine — nothing to submit with."))),console.log(chalk.gray(v(" ▸ learn 粘 token 后再来。"," ▸ paste your token in `learn`, then come back.")));break}const t=await d(o,e.phase,e.slot);if(!t.ok||!t.data){console.log(chalk.yellow(v(" 服务端没开门:"," Server did not open the checkpoint: ")+String(t.message??t.code??"")));break}const n=t.data.problems[0]?.id??(e.race?`duck-r${e.slot}`:`duck-c${e.card}`);console.log(chalk.gray(v(" ⚖ 判分中(服务端 · "," ⚖ judging (server · ")+z(e)+v(")… 约 5–10 秒",")… 5–10 s")));const s=await g(o,e.phase,n,r(x,"utf-8"),e.slot);if(!s.ok||!s.data){if("race_throttle"===s.code){const e=Math.max(1,Math.ceil(Number(s.wait_s??0)));console.log(chalk.yellow(v(` ⏱ 赛日题每 3 分钟判一次 —— 再等 ${e} 秒。本机 run 不限次,先跑几遍再交。`,` ⏱ Race entries are judged once every 3 minutes — ${e} s to go. Local \`run\` is unlimited; try a few first.`)));break}console.log(chalk.yellow(v(" 判分没回来:"," No verdict came back: ")+String(s.message??s.code??"")));break}const a=s.data;for(const e of(a.report??[]).slice(0,3))console.log(chalk.gray(` ${e}`));if(a.note&&console.log(chalk.gray(` ${a.note}`)),"AC"===a.verdict||!0===a.already_ac){J.ac.includes(e.card)||J.ac.push(e.card),A(J);const t=J.ac.filter(e=>e<=48).length;console.log(chalk.green(` ✅ AC · ${t}/12`+(1===t?v(" 🎉 第一个检查点!"," 🎉 first checkpoint!"):""))),await L(o,e,{ticker:!0});const n=D(O).find(o=>!J.ac.includes(o.card)&&o.card>e.card)??null,r=D(O).find(o=>!J.ac.includes(o.card)&&o.card<e.card)??null;Y=null,console.log(chalk.green(e.race?v(" ▸ board 看榜 · 想刷成绩再 edit → run → submit"," ▸ board to see the ranking · edit → run → submit to improve"):n?v(` ▸ back 回卡片,读第 ${e.card+1} 张 —— 下一个检查点在卡 ${n.card}`,` ▸ back to the cards, read card ${e.card+1} — next checkpoint is card ${n.card}`):r?v(` ▸ 前面还有没做的检查点:卡 ${r.card}`,` ▸ an earlier checkpoint is still open: card ${r.card}`):v(" 🎓 12/12 —— 鸭子听你的了。"," 🎓 12/12 — the duck does what you say."))),!e.race&&n&&r&&console.log(chalk.gray(v(` (卡 ${r.card} 的检查点也还没做)`,` (card ${r.card}'s checkpoint is still open too)`)))}else console.log(chalk.yellow(v(` ❌ ${a.verdict}。`,` ❌ ${a.verdict}.`))+chalk.gray(v(" ▸ run 本机看图 ▸ edit"," ▸ run to see the picture ▸ edit")));break}default:if(H+=1,console.log(chalk.yellow(v(` 不认识「${e.trim()}」。`,` Don't know "${e.trim()}".`))+chalk.gray(v(" 可用:edit · syntax · run · replay · submit · board · scenarios · status · back"," Try: edit · syntax · run · replay · submit · board · scenarios · status · back"))),H>=3)return console.log(chalk.gray(v(" 连续三次没对上 —— 回上一层。"," Three misses — going back one level."))),"back"}}}finally{U.close()}}export function registerDuckCommand(e){e.command("duck [args...]").description("Duck ABC sim bench — edit control.py, run the biped in MuJoCo on this machine, submit checkpoints").action(async e=>{await runDuck(e??[])})}