#!/usr/bin/env node var Um=Object.defineProperty;var o=(t,e)=>Um(t,"name",{value:e,configurable:!0});var Or=(t,e)=>()=>(t&&(e=t(t=0)),e);var xd=(t,e)=>{for(var n in e)Um(t,n,{get:e[n],enumerable:!0})};var Md={};xd(Md,{createInlineRealm:()=>Ry});function Ry(t,e){let n=!1,s=[],r=null,i=[],l=[],d=null,a=null,c=[],h=null,p={postMessage:o(M=>{K(M)},"postMessage"),get onmessage(){return d},set onmessage(M){if(d=M,M===null||n)return;let H=i.splice(0,i.length);if(X){for(let Ge of H)F.push(Ge),y.port2.postMessage(0);return}for(let Ge of H)try{M({data:Ge})}catch(C){f(C)}},get onerror(){return a},set onerror(M){if(a=M,M===null||n)return;let H=l.splice(0,l.length);for(let Ge of H)try{M(Ge)}catch{}},setHostSyncCall:o(M=>{h=M},"setHostSyncCall"),terminate:o(()=>{if(!n){n=!0,h=null;for(let M of s)try{M()}catch{}U(),I()}},"terminate"),get stopped(){return n},get origin(){return e}},m=new MessageChannel,y=new MessageChannel,b=o(M=>{let H=M;typeof H.unref=="function"&&H.unref()},"unref");b(m.port1),b(m.port2),b(y.port1),b(y.port2);function f(M){let H=M instanceof Error?M.stack??M.message:String(M);a?a(H):n?queueMicrotask(()=>{throw new Error(`inline realm [${e}]: ${H}`)}):l.push(H)}o(f,"reportError");function I(){if(i.length>0){let M=i.map(N).join(", ");queueMicrotask(()=>{throw new Error(`inline realm [${e}]: torn down with ${i.length} message(s) the host NEVER READ \u2014 kinds: ${M}. They were posted by the realm before anything attached an onmessage handler; the host saw a machine that produced nothing.`)})}if(l.length>0){let M=l[0];queueMicrotask(()=>{throw new Error(`inline realm [${e}]: torn down with ${l.length} unread error(s); the first was: ${String(M)}`)})}if(c.length>0){let M=c.map(N).join(", ");queueMicrotask(()=>{throw new Error(`inline realm [${e}]: torn down with ${c.length} message(s) the REALM never read \u2014 kinds: ${M}.`)})}}o(I,"reportUndelivered"),m.port1.onmessage=M=>{if(!n){if(!r){c.push(M.data);return}R(M.data)}};function R(M){try{let H=r(M);H&&typeof H.catch=="function"&&H.catch(f)}catch(H){f(H)}}o(R,"deliverToRealm");let X=!!(globalThis.process?.env?.HWJS_INLINE_REALM_BROWSER_PORT||globalThis.HWJS_INLINE_REALM_BROWSER_PORT),F=[];y.port1.onmessage=M=>{if(n)return;let H=X?F.length>0?F.shift():void 0:M.data;if(!(X&&H===void 0)){if(!d){i.push(H);return}try{d({data:H})}catch(Ge){f(Ge)}}};let N=o(M=>M&&typeof M=="object"&&typeof M.kind=="string"?M.kind:"","kindOf");m.port1.onmessageerror=()=>f(`inline realm [${e}]: a message to the realm arrived but could not be DESERIALISED (messageerror). It is lost, and the realm is waiting for it.`),y.port1.onmessageerror=()=>f(`inline realm [${e}]: a message from the realm could not be DESERIALISED (messageerror). It is lost, and the host is waiting for it.`);function K(M){if(!n)try{m.port2.postMessage(M)}catch(H){f(`inline realm [${e}]: postMessage(kind=${N(M)}) to the realm threw \u2014 the value is not structured-cloneable, which a real Worker would also refuse: ${H instanceof Error?H.message:String(H)}`)}}o(K,"toRealm");function k(M){if(!n){if(X){F.push(M);try{y.port2.postMessage(0)}catch(H){f(H)}return}try{y.port2.postMessage(M)}catch(H){f(`inline realm [${e}]: postMessage(kind=${N(M)}) to the host threw \u2014 the value is not structured-cloneable, which a real Worker would also refuse: ${H instanceof Error?H.message:String(H)}`)}}}o(k,"toHost");function U(){for(let M of[m.port1,m.port2,y.port1,y.port2])try{M.close()}catch{}}return o(U,"closePorts"),t({post:k,onMessage:o(M=>{if(r=M,n)return;let H=c.splice(0,c.length);for(let Ge of H)R(Ge)},"onMessage"),onTerminate:o(M=>{s.push(M)},"onTerminate"),callHostSync:o(M=>{if(!(n||h===null))try{return h(M)}catch(H){f(H);return}},"callHostSync")}),p}var Ld=Or(()=>{"use strict";o(Ry,"createInlineRealm")});function ye(t,e){let n=0,s=0,r=0;do{if(e>=t.length)throw new Error("hwjs-dlopen: truncated LEB in dylink.0");r=t[e++],n|=(r&127)<>>0,e]}function Hy(t){if(!(t&&t.buffer instanceof SharedArrayBuffer))return t;if(Pa===void 0)try{let e=new Uint8Array(new SharedArrayBuffer(8));e.set([0,97,115,109,1,0,0,0]),new WebAssembly.Module(e),Pa=!0}catch{Pa=!1}return Pa?t:t.slice()}function Fn(t){let e=typeof SharedArrayBuffer<"u"&&t.buffer instanceof SharedArrayBuffer;return vy.decode(e?t.slice():t)}function _i(t){let e=t;if(e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-dlopen: not a wasm module (bad magic)");let n=8;for(;ni&&typeof i[t]=="function"?i[t]:void 0,"fnOf");if(e.provider!==void 0){let i=e.siblings.find(d=>d.index===e.provider),l=i?n(i.exports):void 0;return l?{f:l,sibling:i}:null}let s=n(e.exp);if(s)return{f:s,sibling:null};let r=n(e.ownExp);if(r)return{f:r,sibling:null};for(let i of e.siblings){if(i.exports===e.ownExp)continue;let l=n(i.exports);if(l)return{f:l,sibling:i}}return null}function jd(t,e){if(!(t.startsWith("__hwjs_")||t.startsWith("__wasm_")||Fh.has(t)))for(let n of e){let s=n&&n.handle;if(!s||!s.exports||typeof s.dlsym!="function"||!(s.exports[t]instanceof WebAssembly.Global))continue;let r=s.dlsym(t)>>>0;if(r!==0)return r}}function Jh(t){let e=t,n=new Map;if(!e||e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-libc: mainDataExportAddresses: not a wasm module (bad magic)");let s=8,r=0,i=new Map,l=-1,d=-1;for(;s>>0)))for(let f of b)n.set(f,y>>>0)}return n}function Uh(t,e){if(t.startsWith("__hwjs_")||t.startsWith("hwjs_")||t.startsWith("__wasm")||Fh.has(t))return;let n=e?e.get(t):void 0;return typeof n=="number"&&n>0?n:void 0}function Mh(t){let e=t;if(e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-dlopen: stripStartSection: not a wasm module (bad magic)");let n=8;for(;n=n)throw new Error("hwjs-dlopen: truncated signed LEB in global init expr");i=t[e++],s|=(i&127)<=c)return{ok:!1,why:"out-of-range",exportGlobalIndex:r,definedIndex:d,gcount:c};for(let h=0;h>>0,mutable:p}}for(;a>>0}function Ph(t,e=0){let n=t;if(!n||n.length<8||n[0]!==0||n[1]!==97||n[2]!==115||n[3]!==109)return{dataLo:0,dataHi:0,stackHi:0};let s=o(d=>{let a=za(n,d);return a.ok?a.value>>>0:0},"read"),r=s("__stack_pointer")||e>>>0,i=s("__data_end")||s("__heap_base");return{dataLo:r&&i&&r<=i?r:0,dataHi:i,stackHi:r}}function Ah(t){let e=t?t.__wasm32_get_stack_pointer:void 0;return typeof e=="function"?e()>>>0:0}function Kh(t,e=0){let n=e>>>0;if(n)return{hi:n,limit:0};let s=t?t.stackHi>>>0:0;return s?{hi:s,limit:0}:null}function zh({main:t=null,modules:e=[],stacks:n=[],arena:s=[]}){let r=[];t&&t.dataHi>t.dataLo&&r.push({kind:xh,lo:t.dataLo>>>0,hi:t.dataHi>>>0,limit:0});for(let l of e){let d=l.memoryBase>>>0,a=l.memorySize>>>0;d&&a&&r.push({kind:xh,lo:d,hi:d+a>>>0,limit:0})}let i=r.slice();for(let l of n){let d=l.hi>>>0,a=l.limit>>>0;if(!(d>a))continue;let c=l.sp>>>0,h=c>=a&&c<=d?c:a;r.push({kind:Ly,lo:h,hi:d,limit:a})}for(let[l,d]of s){let a=l>>>0,c=d>>>0;c>a&&(i.some(h=>a>=h.lo&&c<=h.hi)||r.push({kind:Py,lo:a,hi:c,limit:0}))}return r}function jh(t,e,n,s){let r=Math.max(0,Math.min(n|0,s.length)),i=e>>>0;if(r>0){if(i===0||i+r*Bh>t.byteLength)return-14;let l=new DataView(t);for(let d=0;d>>0,!0),l.setUint32(c+4,a.lo>>>0,!0),l.setUint32(c+8,a.hi>>>0,!0),l.setUint32(c+12,a.limit>>>0,!0)}}return s.length}function Oh(t){return Od(t)+Ji>>>0}function Ky(t){let e=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),n=t.length,s=Math.floor(n/536870912),r=n<<3>>>0,i=n-n%64,l=new Uint8Array((n-i+8>>6)+1<<6);l.set(t.subarray(i)),l[n-i]=128;let d=new DataView(l.buffer);d.setUint32(l.length-8,s,!1),d.setUint32(l.length-4,r,!1);let a=new DataView(t.buffer,t.byteOffset,t.byteLength),c=new Uint32Array(64);for(let p=0;p>>7|U<<25)^(U>>>18|U<<14)^U>>>3,Ge=(M>>>17|M<<15)^(M>>>19|M<<13)^M>>>10;c[k]=c[k-16]+H+c[k-7]+Ge>>>0}let b=e[0],f=e[1],I=e[2],R=e[3],X=e[4],F=e[5],N=e[6],K=e[7];for(let k=0;k<64;k++){let U=(X>>>6|X<<26)^(X>>>11|X<<21)^(X>>>25|X<<7),M=X&F^~X&N,H=K+U+M+Ay[k]+c[k]>>>0,Ge=(b>>>2|b<<30)^(b>>>13|b<<19)^(b>>>22|b<<10),C=b&f^b&I^f&I,Ie=Ge+C>>>0;K=N,N=F,F=X,X=R+H>>>0,R=I,I=f,f=b,b=H+Ie>>>0}e[0]=e[0]+b>>>0,e[1]=e[1]+f>>>0,e[2]=e[2]+I>>>0,e[3]=e[3]+R>>>0,e[4]=e[4]+X>>>0,e[5]=e[5]+F>>>0,e[6]=e[6]+N>>>0,e[7]=e[7]+K>>>0}let h="";for(let p=0;p<8;p++)h+=e[p].toString(16).padStart(8,"0");return h}function jy(){if(vo!==void 0)return vo;vo=null;try{let t=globalThis.process?.getBuiltinModule?.("node:crypto");if(t&&typeof t.createHash=="function"){let e=o(s=>t.createHash("sha256").update(s).digest("hex"),"hash"),n=new Uint8Array(typeof SharedArrayBuffer=="function"?new SharedArrayBuffer(3):3);n.set([97,98,99]),e(n)===zy&&(vo=e)}}catch{}return vo}function Ui(t){let e=jy();return e?e(t):Ky(t)}function gi(t){let e=t?t.length:0;if(e<8+Fo)return null;let n=e-Fo;if(t[n]!==0||t[n+1]!==Fo-2||t[n+2]!==Dr.length)return null;n+=3;for(let i=0;i>>0,r="";for(let i=0;i<32;i++)r+=t[n+4+i].toString(16).padStart(2,"0");return{wireLength:s,digest:r}}function Qh(t,e){if(!/^[0-9a-f]{64}$/.test(e))throw new Error(`hwjs-libc: retained copy: ${JSON.stringify(String(e).slice(0,80))} is not a SHA-256 (never-silent)`);let n=t.length;if(n<8||t[0]!==0||t[1]!==97||t[2]!==115||t[3]!==109)throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026 is not a wasm module (never-silent)`);if(gi(t))throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026 is a retained copy already (never-silent)`);let s=[[0,8]],r=8,i=0,l=8;for(;l=n)throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026: the section header at ${l} runs past the module (never-silent)`);let b=t[h++];if(p+=(b&127)*m,m*=128,!(b&128))break}let y=h+p;if(y>n)throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026: section ${c} at ${l} declares ${p}B, past the module's ${n}B (never-silent)`);c===10||c===11?i+=y-l:(s.push([l,y]),r+=y-l),l=y}let d=new Uint8Array(new SharedArrayBuffer(i>0?r+Fo:n)),a=0;for(let[c,h]of s)d.set(t.subarray(c,h),a),a+=h-c;if(i===0)return d;d[a++]=0,d[a++]=Fo-2,d[a++]=Dr.length;for(let c=0;c>>8&255,d[a++]=n>>>16&255,d[a++]=n>>>24&255;for(let c=0;c<32;c++)d[a++]=parseInt(e.slice(c*2,c*2+2),16);return d}function Oy(t){let e=gi(t);return e?e.wireLength:t.length}function Dh(t,e){let n=e.bytes instanceof Uint8Array?e.bytes:new Uint8Array(e.bytes),s=gi(n);if(s&&s.digest!==e.digest)throw new Error(`hwjs-libc: shared-lib delivery for digest ${e.digest} carries the retained copy of ${s.digest} (never-silent)`);if(s&&!e.module&&!(t&&t.module))throw new Error(`hwjs-libc: shared-lib delivery for digest ${e.digest} is a retained copy (${n.length}B of ${s.wireLength}B) with no Module \u2014 a retained copy holds no code and is only kept beside its Module (never-silent)`);if(!t)return{bytes:n,...e.module?{module:e.module}:{}};let r=Oy(t.bytes),i=s?s.wireLength:n.length;if(r!==i)throw new Error(`hwjs-libc: shared-lib re-delivery for digest ${e.digest} with DIFFERENT bytes (${r} vs ${i}) \u2014 content-addressed delivery can never disagree (never-silent)`);return!t.module&&e.module&&(t.module=e.module),s&&!gi(t.bytes)&&(t.bytes=n),t}function Mi(t,e){let n=t?t.mode:void 0;return n==="thread"||n==="migrate-resume"&&e?t.userLane|0||0:n==="fork-resume"&&e&&t.forkLane|0||0}function $h(t,e,n){let s=0;for(let r of t)try{(r.value|0)===0&&(r.value=n|0,s++)}catch{}return e&&typeof e.__hwjs_budget_get=="function"&&typeof e.__hwjs_budget_set=="function"&&(e.__hwjs_budget_get()|0)===0&&(e.__hwjs_budget_set(n|0),s++),s}function qh(t,e,n){return typeof e!="function"||!Qy.has(t)?e:(...s)=>(n(),e(...s))}function eb(t,e){if(t&&typeof t=="object"&&"bytes"in t)throw new Error("hwjs-libc: the fork payload carries libc.so BYTES \u2014 the D4 fork rule is placement-record-only (a bash fork storm would clone GBs; PLAN-DYNAMIC-LIBC \xA73.4). Corrupt payload; refusing (never-silent).");if(String(t.digest)!==e)throw new Error(`hwjs-libc: fork-replay digest ${String(t.digest).slice(0,16)}\u2026 != the boot image's needed digest ${e.slice(0,16)}\u2026 \u2014 the recorded placement is for a different libc.so generation (never-silent).`)}function Dd(t){let e=t;if(e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-dlopen: parseSideModuleNeeded: not a wasm module (bad magic)");let n=null,s=0,r=8;for(;r1)throw new Error(`hwjs-dlopen: ${s} wasm.linux.needed sections on a side module \u2014 one needed list per module (never-silent)`);let i;try{i=JSON.parse(Fn(n))}catch(d){throw new Error("hwjs-dlopen: malformed side-module wasm.linux.needed (not JSON): "+(d instanceof Error?d.message:String(d))+" (never-silent)")}if(!i||typeof i!="object"||!Array.isArray(i.needed))throw new Error('hwjs-dlopen: side-module wasm.linux.needed shape mismatch \u2014 want {"needed":[...]} (never-silent)');let l=new Set;return i.needed.forEach((d,a)=>{if(typeof d!="string"||!/^[0-9A-Za-z._+-]+\.[0-9a-f]{64}$/.test(d)||d.length>127||/^libc\.so\./.test(d)||l.has(d))throw new Error(`hwjs-dlopen: side-module wasm.linux.needed entry ${a} ${JSON.stringify(d)} is not a distinct digest-qualified library name other than libc.so (never-silent)`);l.add(d)}),[...i.needed]}function Cr(t){return t.slice(-64)}function _o(t){return t.slice(0,-65)}function $d(t){let e=t;if(e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-libc: parseWasmLinuxNeeded: not a wasm module (bad magic)");let n=null,s=0,r=8;for(;r1)throw new Error(`hwjs-libc: ${s} wasm.linux.needed sections on the image \u2014 exactly ONE needed-list carrier is legal (a concatenated/tampered artifact; never-silent refuse)`);let i;try{i=JSON.parse(Fn(n))}catch(a){throw new Error("hwjs-libc: malformed wasm.linux.needed payload (not JSON): "+(a instanceof Error?a.message:String(a))+" (never-silent refuse)")}if(!i||typeof i!="object"||!Array.isArray(i.needed)||typeof i.suspenders_sha256!="string"||!/^[0-9a-f]{64}$/.test(i.suspenders_sha256))throw new Error('hwjs-libc: wasm.linux.needed payload shape mismatch \u2014 want {"needed":[...],"suspenders_sha256":""} (never-silent refuse)');let l=127;i.needed.forEach((a,c)=>{if(typeof a!="string"||!/^[0-9A-Za-z._+-]+\.[0-9a-f]{64}$/.test(a))throw new Error(`hwjs-libc: wasm.linux.needed entry ${c} ${JSON.stringify(a)} is not a digest-qualified library name (want . over [0-9A-Za-z._+-]; never-silent refuse)`);if(a.length>l)throw new Error(`hwjs-libc: wasm.linux.needed entry ${c} is ${a.length} bytes, over the ${l} the kernel's parser accepts (WASM32_NEEDED_NAME_MAX) \u2014 the exec would fail there with no entry named (never-silent refuse)`);if(c===0&&!/^libc\.so\.[0-9a-f]{64}$/.test(a))throw new Error(`hwjs-libc: wasm.linux.needed entry 0 is ${JSON.stringify(a)}, not a digest-qualified libc.so \u2014 entry 0 is libc.so by construction (never-silent refuse)`)});let d=new Set;for(let a of i.needed){if(d.has(a))throw new Error(`hwjs-libc: wasm.linux.needed names ${JSON.stringify(a)} more than once \u2014 one entry per library (never-silent refuse)`);d.add(a)}return{needed:[...i.needed],suspendersSha256:i.suspenders_sha256}}function Jo(t){let e=t;if(e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-dlopen: parseHwjsAbi: not a wasm module (bad magic)");let n=null,s=8;for(;s{let U=0,M=0,H=0;do{if(a>=l)throw new Error(`hwjs-dlopen: malformed hwjs.abi manifest \u2014 truncated LEB reading ${k} (never-silent refuse)`);H=e[a++],U|=(H&127)<>>0},"readField"),p=o(k=>{let U=0n,M=0n,H=0;do{if(a>=l)throw new Error(`hwjs-dlopen: malformed hwjs.abi manifest \u2014 truncated LEB reading ${k} (never-silent refuse)`);H=e[a++],U|=BigInt(H&127)<=2?p("suspender_partition_digest"):null,K=m>=2?h("refused_exports"):0;if(a!==l)throw new Error(`hwjs-dlopen: malformed hwjs.abi manifest \u2014 ${l-a} trailing byte(s) after the ${m>=2?"10 v2 fields":"8 fields"} (concatenated multi-record manifest? never-silent refuse)`);n={manifestVersion:m,driveAbi:y,parkedAbi:b,dsRegionAbi:f,suspendAbiVersion:I,capregVersion:R,fpcastVersion:X,flagsRaw:F,suspenderDigestLo64:N,refusedExports:K,flags:{usesShadowStack:(F&1)!==0,usesTls:(F&2)!==0,safepoints:(F&4)!==0,dynamicModule:(F&8)!==0,checkEmitting:(F&16)!==0,laneAddressed:(F&32)!==0,preemptTotal:(F&64)!==0},preemptibility:(F&64)!==0?"whole-program":(F&4)!==0?"scoped":"none"}}}s=l}return n}function Dy(t){let e=t;if(e.length<8||e[0]!==0||e[1]!==97||e[2]!==115||e[3]!==109)throw new Error("hwjs-dlopen: scanModuleSurface: not a wasm module (bad magic)");let n={importsEnvStackPointer:!1,importedEnvFuncNames:[],importsHwjsSuspendPark:!1,exportNames:[],definedMutableGlobals:[]},s=0,r=new Map,i=8;for(;itypeof c.name=="string"&&(c.name.startsWith("GOT.data.internal.")||c.name.startsWith("GOT.func.internal."))&&c.valtype===127&&c.initIsI32Const,"isInternalGotShape"),i=o(c=>c.name==="__hwjs_budget"&&c.valtype===127&&c.initIsI32Const0&&n.flags.safepoints===!0,"isBudgetShape"),l=s.definedMutableGlobals.filter(c=>!r(c)&&!i(c)),d=o(c=>c.valtype===127&&c.initIsI32Const0,"isTlsBaseShape");if(l.length>1||l.length===1&&!d(l[0]))throw new Error(`hwjs-dlopen: private mutable global state in a .so \u2014 not an lld -shared artifact (found ${l.length} defined mutable global(s) beyond the sanctioned lld GOT.data.internal.* internal-GOT shape; at most ONE other is legal and only the lld __tls_base shape: i32, init i32.const 0; unnamed mutable globals stay refused \u2014 the name section is the sanction carrier). Refusing to instantiate (never-silent).`);if(s.importsEnvStackPointer&&!(e.stackPointer instanceof WebAssembly.Global))throw new Error("hwjs-dlopen: the .so imports env.__stack_pointer (mutable i32 \u2014 the shared shadow-stack pointer) but no opts.stackPointer WebAssembly.Global was provided. The loader REFUSES to fabricate a private sp global (a shadow-stack-using .so descending on a private sp=0 corrupts linear memory); pass the main image's exported __stack_pointer so main + .so share ONE sp (never-silent).");if(n){if(n.manifestVersion!==1&&n.manifestVersion!==2)throw new Error(`hwjs-dlopen: hwjs.abi manifest_version ${n.manifestVersion} is not a known version (want 1 or 2) \u2014 ABI-skewed / foreign .so, refusing to instantiate (never-silent).`);let c=3;if(e.mainDriveAbi!==void 0){if(e.mainDriveAbi!==3&&e.mainDriveAbi!==4)throw new Error(`hwjs-dlopen: opts.mainDriveAbi=${e.mainDriveAbi} is not a dlopen-capable drive abi (want 3 flat or 4 status-channel) \u2014 refusing to guess (never-silent).`);c=e.mainDriveAbi}let h=[["drive_abi",n.driveAbi,c],["parked_abi",n.parkedAbi,2],["ds_region_abi",n.dsRegionAbi,2],["suspend_abi_version",n.suspendAbiVersion,1],["capreg_version",n.capregVersion,1],["fpcast_version",n.fpcastVersion,1],["flags.dynamic_module",n.flags.dynamicModule?1:0,1]];for(let[y,b,f]of h)if(b!==f)throw new Error(`hwjs-dlopen: hwjs.abi manifest ${y} mismatch: got ${b}, want ${f} \u2014 ABI-skewed / foreign .so, refusing to instantiate (never-silent).`);if(n.flags.laneAddressed===!0&&n.preemptibility!=="whole-program")throw new Error(`hwjs-dlopen: hwjs.abi manifest preemptibility=${n.preemptibility} on a LANE-ADDRESSED .so (flags bit5) \u2014 want whole-program. Sibling lanes run concurrently in one process, so a lane of this module inside a syscall-free unbounded loop reaches no slice boundary: fork() would return EAGAIN on the acquire deadline and no lane's pending signals would be dispatched. ${n.preemptibility==="scoped"?"scoped means SOME checkpoints exist and is not a whole-image statement.":"This module was built with checkpoints disarmed."} Refusing to instantiate (never-silent).`);let p=e.mainLaneAddressed===!0,m=n.flags.laneAddressed===!0;if(m!==p)throw new Error(`hwjs-dlopen: LANE-ADDRESSED MISMATCH \u2014 this .so attests hwjs.abi flags bit5 lane_addressed=${m?1:0} but the process (main) attests lane_addressed=${p?1:0}. Mixing a lane-addressed module with a lane-unaware one lets the lane-unaware side read LANE 0's status word from ANY lane \u2014 silent transit under threads (I3-2; PLAN-THREADS-SINGLE-MEMORY \xA74 step 2). Rebuild the pair in lockstep (both HWJS_RT_LANES>1 or neither); refusing to instantiate (never-silent).`);if((n.flags.usesTls?1:0)==1&&e.tlsOwner!==!0){if(!(e.sideTls&&typeof e.sideTls=="object"))throw new Error("hwjs-dlopen: hwjs.abi manifest flags.uses_tls=1 on a load that binds no TLS for it \u2014 neither the libc.so thread-pointer owner (opts.tlsOwner) nor a side-module load (opts.sideTls). Its private __tls_base would be unbound on every Instance after the first. Refusing to instantiate (never-silent).");let y=qy.filter(b=>!s.exportNames.includes(b));if(y.length)throw new Error(`hwjs-dlopen: side module owns TLS (hwjs.abi uses_tls=1) but does not export ${y.join(", ")} \u2014 the loader cannot bind its per-thread block without them. Relink it with a brintld that emits the side-module TLS surface (brintos/hwjs-cc#106). Refusing to instantiate (never-silent).`)}return n}throw s.importsHwjsSuspendPark||s.importedEnvFuncNames.some(c=>c.startsWith("__hwjs_")||c.startsWith("hwjs_"))||s.exportNames.includes("__hwjs_drive_abi")?new Error("hwjs-dlopen: suspend-capable .so without hwjs.abi manifest \u2014 the module imports/exports hwjs suspend-ABI surface but carries no hwjs.abi attestation (a pre-manifest or nested-built artifact). Rebuild it with the manifest-emitting linker, brintld (never-silent refuse)."):new Error("hwjs-dlopen: .so has no hwjs.abi manifest \u2014 every dlopen-able module must attest its ABI lineage (the STEP-2 manifest-less PURE grandfather is retired). Rebuild it with the manifest-emitting linker, brintld (never-silent refuse).")}function tb(t){let e=t instanceof Error?t.message:String(t),n=o((s,r,i)=>({errno:s,errnoName:r,cls:i,message:e}),"mk");return typeof RangeError=="function"&&t instanceof RangeError||/never-silent OOM|out of memory|Cannot allocate memory|failed to grow the shared table|could not grow the shared table/i.test(e)?n(-12,"ENOMEM","alloc"):t instanceof WebAssembly.CompileError||/not a wasm module \(bad magic\)/.test(e)?n(-8,"ENOEXEC","compile"):t instanceof WebAssembly.LinkError?n(-80,"ELIBBAD","link"):e.startsWith("hwjs-dlopen:")?n(-80,"ELIBBAD","policy"):n(-22,"EINVAL","unknown")}function Ad(t){let e=t.__tls_size.value>>>0,n=Math.max(t.__tls_align.value>>>0,16);return{size:e,align:n,stride:Math.ceil(Math.max(e,1)/n)*n}}function tc(t,e){let n=ec()*t.stride+4;if(t.align>4096)throw new Error(`hwjs-dlopen: side module${e?` "${e}"`:""} asks for ${t.align}-byte TLS alignment; the slot array is page-aligned (never-silent).`);if(!(n>0)||n>Th)throw new Error(`hwjs-dlopen: side module${e?` "${e}"`:""} owns a ${t.size}B TLS image; its per-thread slot array would need ${n}B, over the ${Th}B cap (never-silent).`);return n}function nb(t,e,n,s){let r=Math.max(n>>>0,16),i=Math.ceil((e>>>0)/r)*r+r,l=Math.floor(((t>>>0)+ja)/r)*r,d=(t>>>0)+tZ,a=Math.max(0,Math.min(Math.floor((l-d)/i),Ch)),c=s>>>0>>0:0;return{addr:(c>>0,stride:i,align:r,lanes:a}}function nc(t,e,n){let s=e.tlsSlots>>>0;return t==="thread"?typeof n=="number"&&n>=0?{mode:"materialise",slotsBase:s,slot:n}:{mode:"unbound-thread"}:t==="fork-resume"?{mode:"fork",base:e.tlsBase>>>0,slotsBase:s}:{mode:"rebind",base:e.tlsBase>>>0}}function sc(t,e){return{tlsBase:t&&t.tls?t.tls.base():0,tlsSlots:e>>>0}}function nZ(t,e,n,s){let r=t.__tls_base,i=s?` "${s}"`:"",l=o((c,h)=>{if(!(c>>>0))throw new Error(`hwjs-dlopen: side module${i} owns TLS but ${h} \u2014 binding 0 would put its thread_local state at address 0 (never-silent).`)},"requireBase"),d=o(c=>{if(t.__wasm_init_tls(c|0),r.value>>>0!==c>>>0)throw new Error(`hwjs-dlopen: side module${i} __wasm_init_tls(${c>>>0}) left __tls_base at ${r.value>>>0} (never-silent).`);return c>>>0},"initInto"),a=o(()=>new DataView(e.buffer),"dv");switch(n.mode){case"fresh":{let c=r.value>>>0;return l(c,"its first Instance left __tls_base at 0 (lld's start function did not bind the loading thread's block)"),d(c)}case"rebind":return l(n.base,"the replay record carries no live __tls_base for it"),r.value=n.base|0,n.base>>>0;case"fork":{l(n.base,"the fork record carries no live __tls_base for it"),r.value=n.base|0;let c=n.slotsBase>>>0;if(c>0){let{stride:h}=Ad(t),p=(n.base>>>0)-c,m=p>=0&&p>>0}case"materialise":{let c=n.slot,h=n.slotsBase>>>0;if(typeof c!="number"||c<0||c>=qd||h===0)throw new Error(`hwjs-dlopen: side module${i} owns TLS but this thread has no TLS slot (slot=${c}, slotsBase=${n.slotsBase}) \u2014 its thread_local state has nowhere to live (never-silent).`);let{stride:p}=Ad(t),m=a().getUint32(Yh(h,p),!0),y=m!==0&&m-1===c?eZ:c;return d(h+y*p>>>0)}case"unbound-thread":return 0;default:throw new Error(`hwjs-dlopen: unknown side-module TLS bind mode ${JSON.stringify(n.mode)} (never-silent)`)}}function sZ(t,e){for(let n=0;n{(i[X]??=Object.create(null))[F]=N},"put"),d=new Map,a=new Map,c=null,h=o(()=>c??=new WebAssembly.Global({value:"i32",mutable:!0},0),"ensureBudgetGlobal"),p=new WebAssembly.Global({value:"i32",mutable:!1},n|0),m=new WebAssembly.Global({value:"i32",mutable:!1},s|0),y={exports:null},b=[],f=null,I=o(X=>(f??=new Set(WebAssembly.Module.exports(t).filter(F=>F.kind==="function").map(F=>F.name))).has(X),"ownDefines"),R=[];for(let X of WebAssembly.Module.imports(t)){let{module:F,name:N,kind:K}=X;if(K==="memory"){l(F,N,e.memory);continue}if(K==="table"){l(F,N,e.table);continue}if(K==="global"&&N==="__memory_base"){l(F,N,p);continue}if(K==="global"&&N==="__table_base"){l(F,N,m);continue}if(K==="global"&&N==="__stack_pointer"&&e.stackPointer instanceof WebAssembly.Global){l(F,N,e.stackPointer);continue}if(K==="global"&&F==="env"&&N==="__hwjs_status_channel_addr"){let U=e.statusChannelAddr;if(typeof U!="number"||!Number.isInteger(U)||U<=0)throw new Error("hwjs-dlopen: the .so imports env.__hwjs_status_channel_addr (lane-addressed module) but the caller supplied no opts.statusChannelAddr \u2014 refusing to fabricate a channel base (address 0 would silently read wrong memory as the status word; never-silent; PLAN-THREADS-SINGLE-MEMORY \xA74 step 2).");l(F,N,new WebAssembly.Global({value:"i32",mutable:!0},U|0));continue}if(K==="global"&&F==="env"&&N==="__hwjs_budget"){l(F,N,h());continue}if(K==="function"&&F==="env"&&(N==="__hwjs_budget_set"||N==="__hwjs_budget_get")){let U=h();l(F,N,N==="__hwjs_budget_set"?M=>{U.value=M|0}:()=>U.value|0);continue}if(K==="global"&&F==="GOT.func"){let U=new WebAssembly.Global({value:"i32",mutable:!0},0);d.set(N,U),l(F,N,U);continue}if(K==="global"&&F==="GOT.mem"){let U=new WebAssembly.Global({value:"i32",mutable:!0},0);a.set(N,U),l(F,N,U);continue}if(F==="hwjs_suspend"&&N==="park"){l(F,N,e.parkImport??(()=>{}));continue}let k=e.resolveImport?e.resolveImport(F,N,K):void 0;if(k==null&&e.bindOwnDefinitions&&F==="env"&&K==="function"&&I(N)){l(F,N,iZ(N,y,e.soPath)),b.push(N);continue}if(k==null&&K==="function"&&r&&r.get(N)===F){l(F,N,oZ(F,N,e.soPath)),R.push(N);continue}if(k==null){let U=e.soPath?`"${e.soPath}"`:"the shared object",M="";try{M=WebAssembly.Module.exports(t).some(H=>H.name===N&&H.kind===K)?` NOTE: ${U} ITSELF exports ${N} (${K}) \u2014 this is a PREEMPTIBLE symbol (a -shared module routes its own weak/default-visibility definitions through env so the loader may interpose one), and nothing in this process provides it.`:""}catch{}throw new Error(`hwjs-dlopen: unresolved import ${F}.${N} (${K}) in ${U} \u2014 the loader has no binding and resolveImport returned nothing (never-silent; a mis-wired dynamic module must fail loudly, not run with a hole).${M}`)}l(F,N,k)}return{imports:i,gotFunc:d,gotMem:a,budgetGlobal:c,selfBox:y,ownBound:b,weakUnbound:R}}function iZ(t,e,n){let s=null,r=o(()=>{let i=e.exports?e.exports[t]:void 0;if(typeof i!="function"){let l=n?`"${n}"`:"the shared object";throw new Error(`hwjs-dlopen: env.${t} in ${l} is bound to the module's own definition, but ${e.exports?`the instance exports no function "${t}"`:"it was called before the module was instantiated (from its start section)"} (never-silent).`)}return i},"provider");return function(i,l,d,a,c,h,p){let m=s||(s=r());switch(arguments.length){case 0:return m();case 1:return m(i);case 2:return m(i,l);case 3:return m(i,l,d);case 4:return m(i,l,d,a);case 5:return m(i,l,d,a,c);case 6:return m(i,l,d,a,c,h);case 7:return m(i,l,d,a,c,h,p);default:return m.apply(null,arguments)}}}function oZ(t,e,n){let s=n?`"${n}"`:"the shared object";return()=>{throw new Error(`hwjs-dlopen: call to ${t}.${e} in ${s}, a WEAK undefined function that no loaded module defines, so its address is null (never-silent; ELF would fault on the same call).`)}}function Li(t){let{wasmBytes:e,memory:n,table:s}=t,r=$y(e,t),i=_i(e),l=i?i.memorySize:0,d=i?i.memoryAlign:1,a=i?i.tableSize:0,c=typeof t.fixedMemoryBase=="number"?t.fixedMemoryBase>>>0:l>0?t.allocMemory(sb(l,d),d):0;if(l>0&&!(c>0))throw new Error(`hwjs-dlopen: allocMemory returned ${c} for a ${l}B .so data region (never-silent OOM / bad bump)`);let h=typeof t.fixedTableBase=="number",p=h?t.fixedTableBase>>>0:s.length;if(h){if(p+a>s.length)throw new Error(`hwjs-dlopen: fixedTableBase placement [${p}, ${p+a}) exceeds the shared table length ${s.length} \u2014 the replay payload places a module past the parent's declared table extent (corrupt placement; never-silent)`);for(let q=p;q0)try{s.grow(a)}catch(q){throw new Error(`hwjs-dlopen: failed to grow the shared table by ${a} slots for the .so (table max reached?): `+(q instanceof Error?q.message:String(q)))}let m=typeof t.compileModule=="function"?t.compileModule(e):new WebAssembly.Module(Hy(e));if(!(m instanceof WebAssembly.Module))throw new Error("hwjs-dlopen: opts.compileModule returned a non-Module \u2014 the caller must hand back a WebAssembly.Module compiled from exactly the load bytes (never-silent)");let y=i?i.weakImports:null,{imports:b,gotFunc:f,gotMem:I,budgetGlobal:R,selfBox:X,ownBound:F,weakUnbound:N}=rZ(m,t,c,p,y),K=new WebAssembly.Instance(m,b),k=K.exports;if(X.exports=k,r&&typeof k.__hwjs_drive_abi=="function"){let q=k.__hwjs_drive_abi()|0;if(q!==r.driveAbi)throw new Error(`hwjs-dlopen: lying hwjs.abi manifest \u2014 manifest drive_abi=${r.driveAbi} but exports.__hwjs_drive_abi() returned ${q} (a manifest that contradicts the live probe is a build error; never-silent refuse).`)}let U=!1,M=!1,H=new Map;if(t.seedSymbolIndices)for(let[q,_]of t.seedSymbolIndices){let D=_>>>0,ue=k[q];if(typeof ue!="function")throw new Error(`hwjs-dlopen: seedSymbolIndices["${q}"] = ${D} but the replayed module exports no such function \u2014 the parent recorded an appended slot this artifact cannot back (never-silent)`);if(!(D>0)||D>=s.length)throw new Error(`hwjs-dlopen: seedSymbolIndices["${q}"] = ${D} is outside the shared table (length ${s.length}) \u2014 corrupt placement payload (never-silent)`);let x=s.get(D);if(x!==null&&x!==ue)throw new Error(`hwjs-dlopen: seedSymbolIndices["${q}"] = ${D} collides with an occupied slot holding a DIFFERENT function \u2014 two recorded appends overlap (never-silent)`);s.set(D,ue),H.set(q,D)}let Ge=null;function C(q){if(Ge===null){Ge=new Map;for(let D=s.length-1;D>=1;D--){let ue=s.get(D);ue!==null&&Ge.set(ue,D)}}let _=Ge.get(q);return _===void 0?-1:_}o(C,"residentIndexOf");function Ie(q){let _=H.get(q);if(_!==void 0)return _;let D=k[q];if(typeof D!="function")return H.set(q,0),0;let ue=C(D);if(ue>0)return H.set(q,ue),ue;let x=s.length;try{s.grow(1)}catch(ie){throw new Error(`hwjs-dlopen: could not grow the shared table for "${q}" (max reached): `+(ie instanceof Error?ie.message:String(ie)))}return s.set(x,D),Ge!==null&&Ge.set(D,x),pe(D,x),H.set(q,x),x}if(o(Ie,"symbolIndex"),t.reservedSymbolIndices)for(let[q,_]of t.reservedSymbolIndices){let D=_>>>0,ue=k[q];if(typeof ue!="function")throw new Error(`hwjs-dlopen: a sibling reserved shared-table slot ${D} for "${q}", but ${t.soPath||"this module"} exports no such function (never-silent)`);if(!(D>0)||D>=s.length||s.get(D)!==null&&s.get(D)!==ue)throw new Error(`hwjs-dlopen: the slot ${D} reserved for "${q}" is outside the shared table (length ${s.length}) or already occupied (never-silent)`);let x=C(ue);if(x>0&&x!==D)throw new Error(`hwjs-dlopen: "${q}" in ${t.soPath||"this module"} is already table-resident at ${x}, but a sibling has baked the reserved slot ${D} into its data -- one function would have two addresses (never-silent)`);s.set(D,ue),Ge!==null&&Ge.set(ue,D),H.set(q,D)}let B=null;function ae(q){B===null&&(B=new Map);let _=B.get(q);if(_!==void 0)return _;let D=0,ue=za(e,q);return ue.ok&&!ue.mutable&&!(i&&i.tlsExports.includes(q))&&ue.value<=l&&(D=(c>>>0)+ue.value>>>0),B.set(q,D),D}o(ae,"dataSymbolAddress");let Ce=!1,Q=null,$=0;function _e(q){if(Q===null||$!==s.length){Q=new Map;for(let D=s.length-1;D>=0;D--){let ue=s.get(D);ue!==null&&Q.set(ue,D)}$=s.length}let _=Q.get(q);return _===void 0?-1:_}o(_e,"gotPassResidentIndexOf");function pe(q,_){if(Q===null)return;let D=Q.get(q);(D===void 0||_=0)return D;let ue=t.gotFuncIndex;if(!(ue instanceof Map))throw new Error(`hwjs-dlopen: GOT.func.${q} resolves to a MAIN function that is not table-resident, and no PROCESS-wide opts.gotFuncIndex Map was provided \u2014 refusing to append per-handle (two .so's address-taking the same symbol would diverge on its table index, breaking the cross-module coroutine identity; never-silent)`);let x=ue.get(q);if(x!==void 0){if(x>=s.length)try{s.grow(x+1-s.length)}catch(P){throw new Error(`hwjs-dlopen: could not grow the shared table to the seeded GOT.func.${q} index ${x} (max reached): `+(P instanceof Error?P.message:String(P)))}let ee=s.get(x);if(ee===null)return s.set(x,_),pe(_,x),x;if(ee!==_)throw new Error(`hwjs-dlopen: GOT.func.${q} identity drift \u2014 the process-wide cache holds shared-table index ${x} but the resolver now returns a DIFFERENT function object (a per-module wrapped closure?). One symbol must keep ONE table identity across modules (never-silent)`);return x}let ie=s.length;try{s.grow(1)}catch(ee){throw new Error(`hwjs-dlopen: could not grow the shared table for GOT.func.${q} (max reached): `+(ee instanceof Error?ee.message:String(ee)))}return s.set(ie,_),pe(_,ie),ue.set(q,ie),ie}o(Ut,"mainFunctionTableIndex");let rt=null,we=new Map;Ce=!0;for(let[q,_]of f){if(t.presetGotFunc&&t.presetGotFunc.has(q)){_.value=t.presetGotFunc.get(q)>>>0;continue}if(t.deferGotFunc&&t.deferGotFunc.has(q)){we.set(q,_);continue}if(typeof k[q]=="function"){let x=Ie(q);if(!(x>0))throw new Error(`hwjs-dlopen: GOT.func.${q} resolved to table index ${x} (never-silent PIC hole)`);_.value=x;continue}rt||(rt=Kd(m,e));let D=rt.get(q);if(D){let x=t.resolveImport?t.resolveImport(D.module,D.field,"function"):void 0;if(x==null&&y&&y.has(q)){_.value=0,N.push(q);continue}if(typeof x!="function")throw new Error(`hwjs-dlopen: GOT.func.${q} -> import ${D.module}.${D.field} did not resolve to a function (never-silent)`);_.value=Ut(q,x);continue}let ue=t.resolveImport?t.resolveImport("env",q,"function"):void 0;if(ue==null&&y&&y.has(q)){_.value=0,N.push(q);continue}if(typeof ue!="function")throw new Error(`hwjs-dlopen: GOT.func.${q} unresolved \u2014 not a .so export, no imported-function symbol of that name, and the MAIN resolveImport chain provides no env.${q} function (never-silent PIC hole)`);_.value=Ut(q,ue)}Ce=!1,Q=null;let Qe=0,It=[];for(let[q,_]of I){let D=t.interposeDataAddress?t.interposeDataAddress(q):void 0;if(!(typeof D=="number"&&D>>>0>0)&&t.preemptsData&&t.preemptsData(q)){let ie=t.resolveDataAddress?t.resolveDataAddress(q):void 0;if(typeof ie!="number"||!(ie>>>0>0))throw new Error(`hwjs-dlopen: GOT.mem.${q} \u2014 an earlier needed entry exports it, but its address did not resolve (resolveDataAddress -> ${ie}). Refusing rather than binding this module's own copy beside it (never-silent).`);_.value=ie|0;continue}let ue=k[q];if(ue instanceof WebAssembly.Global){let ie=t.interposeDataAddress?t.interposeDataAddress(q):void 0;if(typeof ie=="number"&&ie>>>0>0){_.value=ie|0,It.push(q);continue}let ee=(c|0)+(ue.value|0);if(q==="__hwjs_status_channel"){let P=t.resolveDataAddress?t.resolveDataAddress(q):void 0;if(typeof P=="number"&&P>>>0>0&&P>>>0!==ee>>>0)throw new Error(`hwjs-dlopen: GOT.mem.${q} LOCKSTEP VIOLATION \u2014 this .so DEFINES its own ${q} (memoryBase+offset = ${ee>>>0}) while the process already owns one at ${P>>>0} (contract \xA71: ONE channel block per process, MAIN/rt-owned). The .so was linked with the RT merged in; link it against the RT-import surface instead. Refusing the silent split-brain (two channel blocks = raises invisible to the other side's checks).`)}if(_.value=ee,q==="__hwjs_module_id"){if(!(ee>0))throw new Error(`hwjs-dlopen: GOT.mem.__hwjs_module_id resolved to addr ${ee} (memoryBase=${c}) \u2014 cannot bind the module id into the NULL page (never-silent; the .so must declare data for it)`);Qe=ee}continue}let x=t.resolveDataAddress?t.resolveDataAddress(q):void 0;if(!(typeof x=="number"&&x>>>0>0)&&y&&y.has(q)){_.value=0,N.push(q);continue}if(typeof x!="number"||!(x>>>0>0))throw new Error(`hwjs-dlopen: GOT.mem.${q} unresolved \u2014 the .so does not define it and the MAIN provides no address-bearing data export of that name (resolveDataAddress -> ${x}). Refusing the old silent memoryBase+0 resolution (never-silent PIC hole; export the symbol from the dynamic main, e.g. WASMLD_DYN_EXPORT_LIBC)`);_.value=x|0}let Ct=!1;!t.skipDataRelocs&&typeof k.__wasm_apply_data_relocs=="function"&&(k.__wasm_apply_data_relocs(),Ct=!0);let Mt=!!(r&&r.flags.usesTls&&t.tlsOwner!==!0&&k.__tls_size.value>>>0>0),At=Mt?nZ(k,n,t.sideTls,t.soPath):0;return Qe>0&&new DataView(n.buffer).setInt32(Qe,t.moduleId|0,!0),{module:m,instance:K,exports:k,memoryBase:c,tableBase:p,dylink:i,budgetGlobal:R,weakUnboundImports:N,ownBoundImports:F,tls:Mt?{...Ad(k),base:o(()=>k.__tls_base.value>>>0,"base"),unbound:At===0}:null,pendingGotFuncNames(){return[...we.keys()]},patchGotFunc(q,_){let D=we.get(q);if(!D)throw new Error(`hwjs-dlopen: patchGotFunc("${q}") \u2014 no deferred GOT.func of that name (never deferred, or already patched)`);let ue=Ut(q,_);return D.value=ue,we.delete(q),ue},dataRelocsApplied:Ct,interposedData:It,runCtors(){if(U)return!1;U=!0;let q=k.__wasm_call_ctors;return typeof q=="function"?(q(),!0):!1},dlsym(q){if(M)throw new Error(`hwjs-dlopen: dlsym("${q}") on an unloaded module`);return k[q]instanceof WebAssembly.Global?ae(q):Ie(q)},tableIndices(){let q=[];for(let _ of H.values())_>0&&q.push(_);return q},tableEntries(){let q=[];for(let[_,D]of H)D>0&&q.push([_,D]);return q},unload(){M=!0}}}function rb(t,e,n,s,r){t=t>>>0,e=e>>>0;for(let d of n)if(e>=d.tableBase&&e>>0:0,c=d.tableBase>>>0,h=d.handle&&typeof d.handle.tableIndices=="function"?d.handle.tableIndices():[],p=e>=c&&e0)||!!(d.xmodRegistrar&&d.xmodRegistrar.imported===!1);return{dead:null,live:d,inElem:p,hasRec:!!(d.xmodRecs&&d.xmodRecs.has(t+":"+e)),recOtherSig:y&&m>>>0!==t,recAny:y,regRan:b}}let i=typeof r=="function"?r(e):void 0,l=i!==void 0&&i!==0;return{dead:null,live:null,inElem:!1,hasRec:!1,recOtherSig:l&&i>>>0!==t,recAny:l,regRan:!1}}function ib(t){return WebAssembly.Module.customSections(t,aZ).length>0}function ob(t){return t.inDead?0:t.inFootprint?t.hasRec||t.fromRt||t.fromMain&&!t.inElem||!t.inElem&&!t.recAny&&t.regRan?1:t.marshal&&t.recOtherSig?2:0:t.marshal&&!t.fromRt&&t.recOtherSig?2:1}function ab(t){let e=t?t.__hwjs_ctors_defer_set:void 0,n=t?t.__hwjs_ctors_runner:void 0;if(typeof e!="function"||typeof n!="function")return{};let s=n()>>>0;return s===0?{}:{deferSet:e,runner:s}}function lb({table:t,memory:e,slotAddr:n,list:s}){let r=n>>>0,i=new DataView(e.buffer),l=i.getUint32(r,!0);if(s.length>l)throw new Error(`hwjs-libc: ${s.length} needed libraries defer their ctors to _start but the main's __wasm32_needed_ctors_in_start slot holds ${l} \u2014 refusing to drop any (never-silent).`);if(s.length===0)return[];Pd||(Pd=new WebAssembly.Module(lZ));let d=o(m=>typeof m.deferSet=="function"&&m.runner>>>0!==0,"isDriven"),a=s.length+s.filter(d).length<=l,c=t.length>>>0;t.grow(s.length);let h=0,p=s.map((m,y)=>{let b=a&&d(m),f=new WebAssembly.Instance(Pd,{e:{s:o(()=>{b&&m.deferSet(1)},"s"),c:m.ctor,z:o(()=>{b&&m.deferSet(0)},"z")}});return t.set(c+y,f.exports.r),i.setUint32(r+8+4*h++,c+y>>>0,!0),b&&i.setUint32(r+8+4*h++,m.runner>>>0,!0),c+y});return i.setUint32(r+4,h>>>0,!0),Object.defineProperty(p,"driven",{value:a}),p}var Vy,xy,By,Ty,Yy,Cy,Ny,Pa,vy,Vh,Fh,Ey,Jy,Ji,Uy,Qd,xh,Ly,Py,Bh,Eo,Ay,zy,vo,Dr,Fo,Ka,Qy,qy,qd,eZ,Th,ec,Yh,Ch,ja,tZ,aZ,lZ,Pd,Ii=Or(()=>{"use strict";o(ye,"readU32LEB");Vy=1,xy=2,By=3,Ty=4,Yy=3,Cy=1,Ny=1024;o(Hy,"wasmSource");vy=new TextDecoder;o(Fn,"decodeMaybeShared");o(_i,"parseDylink0");o(Nh,"parseImportedTableType");o(Hh,"parseImportedMemoryMinPages");o(Fy,"parseImportedFunctionNames");Vh=new WeakMap;o(Kd,"importedFunctionNamesOf");o(vh,"parseExportedFunctionIndices");o(zd,"dlopenSiblingExport");Fh=new Set(["__stack_pointer","__tls_base","__tls_size","__tls_align","__memory_base","__table_base","__heap_base","__heap_end","__data_end","__dso_handle","__global_base"]),Ey=/^_Z(T[IVSTC]|G[VR]|Z|T[hv](n?[0-9]+_)+)?N?K?St/;o(_y,"neededPreemptible");o(Eh,"neededEarlierProvider");o(_h,"neededGotPatchProvider");o(jd,"dlopenSiblingDataAddress");o(Jh,"mainDataExportAddresses");o(Uh,"interposingDataAddress");o(Mh,"stripStartSection");o(Ei,"readS32LEB");Jy=1*1024*1024,Ji=8*1024*1024,Uy=4096;o(Aa,"skipLimits");o(za,"findExportedI32Global");o(Lh,"readExportedI32Global");o(My,"readHeapBase");o(Od,"deriveHwjsRtWindowBase");Qd=64*1024,xh=1,Ly=2,Py=3,Bh=16;o(Ph,"readMainRootLayout");o(Ah,"initialStackPointer");o(Kh,"callerStackRegion");o(zh,"buildRootMap");o(jh,"writeRootMap");Eo=16*1024*1024;o(Oh,"deriveHwjsLibcWindowBase");Ay=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);o(Ky,"sha256HexJs");zy="ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";o(jy,"hostSha256Hex");o(Ui,"sha256Hex");Dr="hwjs.retained",Fo=3+Dr.length+4+32;o(gi,"retainedLibraryInfo");o(Qh,"retainedLibraryBytes");o(Oy,"sharedLibWireLength");o(Dh,"mergeSharedLib");Ka=class{static{o(this,"SoModuleCache")}constructor(e,n,s=Ui){this.max=e,this.contentKey=n,this.digestOf=s,this.entries=[]}get size(){return this.entries.length}keyOf(e,n){return n!==void 0?`sha256:${n}`:this.contentKey(e)}find(e,n){let s=e.length,r={len:s,digest:n,content:void 0},i;if(n!==void 0){if(i=this.entries.find(d=>d.digest===n),!i){let d=this.entries.filter(a=>a.digest===void 0&&a.len===s);d.length>0&&(r.content=this.contentKey(e),i=d.find(a=>a.content===r.content),i&&(i.digest=n))}}else if(r.content=this.contentKey(e),i=this.entries.find(d=>d.content===r.content),!i){let d=this.entries.filter(a=>a.content===void 0&&a.len===s);d.length>0&&(r.digest=this.digestOf(e),i=d.find(a=>a.digest===r.digest),i&&(i.content=r.content))}let l=n!==void 0?`sha256:${n}`:r.content;return i?(this.entries.splice(this.entries.indexOf(i),1),this.entries.push(i),{key:l,module:i.module,id:r}):{key:l,id:r}}add(e,n){this.entries.push({len:e.len,digest:e.digest,content:e.content,module:n}),this.entries.length>this.max&&this.entries.shift()}};o(Mi,"deriveUserLane");Qy=new Set(["__hwjs_drive","__hwjs_drive_resume"]);o($h,"refillExpiredBudgets");o(qh,"driveEntryImport");o(eb,"checkLibcReplayRecord");o(Dd,"parseSideModuleNeeded");o(Cr,"neededDigest");o(_o,"neededSoname");o($d,"parseWasmLinuxNeeded");o(Jo,"parseHwjsAbi");o(Dy,"scanModuleSurface");o($y,"checkLoadPolicy");o(tb,"classifyDlopenFailure");qy=Object.freeze(["__tls_base","__tls_size","__tls_align","__wasm_init_tls"]),qd=256,eZ=qd,Th=64*1024*1024;o(Ad,"sideTlsLayout");ec=o(()=>qd+1,"sideTlsSlotCount"),Yh=o((t,e)=>(t>>>0)+ec()*e>>>0,"sideTlsHeaderAddr");o(tc,"sideTlsSlotArrayBytes");Ch=257,ja=1*1024*1024,tZ=ja>>>1;o(nb,"mainTlsSlot");o(nc,"sideTlsReplayMode");o(sc,"sideTlsRecordFields");o(nZ,"bindSideModuleTls");o(sZ,"tableIndexOf");o(sb,"alignUp");o(rZ,"wireImports");o(iZ,"ownDefinitionTrampoline");o(oZ,"weakUndefinedCall");o(Li,"loadSharedObject");o(rb,"xmodConsultClassify");aZ="hwjs.xmod_marshal";o(ib,"xmodMarshalArmed");o(ob,"xmodConsultVerdict");lZ=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,2,19,3,1,101,1,115,0,0,1,101,1,99,0,0,1,101,1,122,0,0,3,2,1,0,7,5,1,1,114,0,3,10,10,1,8,0,16,0,16,1,16,2,11]),Pd=null;o(ab,"drivenCtorHandles");o(lb,"publishNeededCtorsInStart")});function Oa(t){let e=[],n=0;for(let s of WebAssembly.Module.imports(t))s.kind==="memory"&&(n++,s.module==="env"&&s.name==="kernel_memory"||e.push(`vmlinux imports memory ${s.module}.${s.name} \u2014 the kernel is a SINGLE-memory module now (only env.kernel_memory). A stale multi-memory vmlinux.wasm (the deleted env.user_memory splice) cannot boot on this host: rebuild the kernel (uaccess is host-serviced via linux.raw_copy_*_user; multi-memory is also what WebKit/iPadOS rejects \u2014 litb#68).`)),s.module===db&&dZ.includes(s.name)&&e.push(`vmlinux declares kernel-memory service import '${s.name}' in parking namespace '${db}' \u2014 the uaccess crossing would be a coroutine suspend boundary by construction, which is the silently-catastrophic wiring the leaf witness exists to refuse (PLAN-THREADS-SINGLE-MEMORY \xA75 R1).`);return n>1&&e.push(`vmlinux imports ${n} memories \u2014 exactly one (env.kernel_memory) is the single-memory contract.`),e}function Qa(t){let{userMemory:e,kernelMemory:n,refuse:s,context:r,redPark:i}=t;if(typeof s!="function")throw new Error("makeUaccessLeafBoundary: refuse() is required");let l=0,d=null,a=null,c=o(U=>{let M=o((...H)=>{if(l>0)throw s(`uaccess-leaf-witness REFUSAL [${r}]: park signal raised while a kernel-memory leaf crossing is live (depth=${l}). A park across the uaccess crossing is silently catastrophic (R1 spike: poison propagation with a clean DONE exit) \u2014 the crossing MUST be a leaf host memcpy. Refusing loudly instead.`),new Error("uaccess-leaf-witness: park during leaf crossing");return U(...H)},"wrapped");return a=M,M},"guardPark"),h=o(U=>{d=U},"setParkedSlotReader"),p=o(()=>l>0,"inLeafCrossing");if(!e){let U=o(M=>(...H)=>{throw s(`uaccess-leaf-witness REFUSAL [${r}]: linux.${M}(${H.map(Ge=>"0x"+(Ge>>>0).toString(16)).join(", ")}) called from kthread context \u2014 the standalone vmlinux Worker has no user pages; kernel code must never uaccess outside a process context. This is a kernel bug (the old 1-page sentinel's trap, now named).`),new Error(`kthread uaccess: linux.${M}`)},"kthreadBug");return{imports:{raw_copy_to_user:U("raw_copy_to_user"),raw_copy_from_user:U("raw_copy_from_user"),raw_clear_user:U("raw_clear_user")},guardPark:c,setParkedSlotReader:h,inLeafCrossing:p}}let m=null,y=null,b=o(()=>{let U=e.buffer;return U!==m&&(m=U,y=new Uint8Array(U)),y},"userU8"),f=null,I=null,R=o(()=>{let U=n.buffer;return U!==f&&(f=U,I=new Uint8Array(U)),I},"kernU8"),X=32,F=o((U,M,H,Ge,C)=>{if(C<=X)for(let Ie=0;Ie{throw s(`uaccess-leaf-witness REFUSAL [${r}]: linux.${U}: ${M}`),new Error(`uaccess kernel-side bug: linux.${U}`)},"kernelBug"),K=o((U,M)=>(H,Ge,C)=>{let Ie=d?d():0;l++;try{return i&&(a||s(`uaccess-leaf-witness REFUSAL [${r}]: RED park arm requested but no park binding was guarded (guardPark never called) \u2014 the witness would be vacuous. Wire guardPark.`),a()),M(H,Ge,C)}finally{if(l--,d){let B=d();B!==Ie&&s(`uaccess-leaf-witness REFUSAL [${r}]: parked slot changed across linux.${U} (0x${(Ie>>>0).toString(16)} -> 0x${(B>>>0).toString(16)}) \u2014 the kernel-memory crossing suspended. The crossing MUST be a leaf.`)}}},"leaf");return{imports:{raw_copy_to_user:K("raw_copy_to_user",(U,M,H)=>{if(U>>>=0,M>>>=0,H>>>=0,H===0)return 0;let Ge=b();if(U+H>Ge.length)return H;let C=R();return M+H>C.length&&N("raw_copy_to_user",`kernel-side source out of range (from=0x${M.toString(16)} n=${H} kernel_len=0x${C.length.toString(16)}) \u2014 kernel bug`),F(Ge,U,C,M,H),0}),raw_copy_from_user:K("raw_copy_from_user",(U,M,H)=>{if(U>>>=0,M>>>=0,H>>>=0,H===0)return 0;let Ge=b();if(M+H>Ge.length)return H;let C=R();return U+H>C.length&&N("raw_copy_from_user",`kernel-side destination out of range (to=0x${U.toString(16)} n=${H} kernel_len=0x${C.length.toString(16)}) \u2014 kernel bug`),F(C,U,Ge,M,H),0}),raw_clear_user:K("raw_clear_user",(U,M)=>{if(U>>>=0,M>>>=0,M===0)return 0;let H=b();return U+M>H.length?M:(H.fill(0,U,U+M),0)})},guardPark:c,setParkedSlotReader:h,inLeafCrossing:p}}var dZ,db,rc=Or(()=>{"use strict";dZ=Object.freeze(["raw_copy_to_user","raw_copy_from_user","raw_clear_user"]),db="hwjs_suspend";o(Oa,"auditVmlinuxSingleMemory");o(Qa,"makeUaccessLeafBoundary")});function ac(){return{kind:oc,intervalMs:ub,turns:hb,beltTurns:mb}}function hZ(){if(Da===null){let t=new MessageChannel;t.port1.onmessage=()=>{let e=$a.shift();e&&e(),$a.length===0&&ic(t.port1)},ic(t.port1),ic(t.port2),Da=t}return new Promise(t=>{$a.length===0&&mZ(Da.port1),$a.push(t),Da.port2.postMessage(0)})}function Ls(){if(hb++,oc==="setImmediate")return new Promise(n=>{setImmediate(n)});if(oc!=="MessageChannel")return new Promise(n=>{setTimeout(n,0)});let t=hZ(),e=Date.now();return e-cbnew Promise(n=>{setTimeout(n,0)})))}var cZ,uZ,oc,ub,cb,mb,hb,Da,$a,mZ,ic,qa=Or(()=>{"use strict";cZ=typeof setImmediate=="function",uZ=typeof MessageChannel=="function",oc=cZ?"setImmediate":uZ?"MessageChannel":"setTimeout",ub=100,cb=0,mb=0,hb=0;o(ac,"macrotaskCensus");Da=null,$a=[],mZ=o(t=>{typeof t.ref=="function"&&t.ref()},"macrotaskPortRef"),ic=o(t=>{typeof t.unref=="function"&&t.unref()},"macrotaskPortUnref");o(hZ,"portTurn");o(Ls,"macrotaskTurn")});function el(t,e){let n=t?.[e];return!n||typeof n.value!="number"?-1:n.value>>>0}function pZ(t,e,n){let s=e,r=Math.min(e+n,t.length);for(;s=0&&s>=0,d=r>=0&&i>=0;if(!l&&!d)return{readable:!1,why:"this image exports neither __hwjs_violation_pending_lanes/__hwjs_violation_buf_lanes nor the non-laned __hwjs_violation_pending/__hwjs_violation_buf, so its undelivered violations cannot be read. Absence of a witness line here is NOT evidence that no violation fired \u2014 it is evidence that nobody could look. The link has to name them: the user-image export list lives in brintium (brintld --export-if-defined + the DCE roots), the kernel one in scripts/link-vmlinux.sh.",found:[]};let a;try{a=new Uint8Array(e.buffer)}catch(m){return{readable:!1,why:`the image's memory could not be viewed: ${m instanceof Error?m.message:String(m)}`,found:[]}}let c=(()=>{try{return new Int32Array(e.buffer)}catch{return null}})();if(c===null)return{readable:!1,why:"no i32 view of the image memory",found:[]};let h=[],p=o((m,y,b)=>{if(y+4>a.length||b>=a.length||(Atomics.load(c,y>>2)|0)!==1)return;let f=pZ(a,b,512);bZ.some(I=>f.startsWith(I))&&h.push({lane:m,text:f.replace(/\n+$/,"")})},"consider");if(l){let m=2048;try{if(typeof t.__hwjs_lane_cap=="function"){let y=t.__hwjs_lane_cap()|0;y>0&&y` ${s.lane<0?"(unlaned)":`[lane ${s.lane}]`} ${s.text}`);return`hwjs-witness ${e}: ${t.found.length} violation sentence(s) were formatted and NEVER DELIVERED \u2014 the runtime set its pending word, tried to write(2) them to fd 2, and the write did not report every byte gone. They say what the trap does not: ${n.join(` `)}`}var bZ,bb=Or(()=>{"use strict";bZ=["hwjs-user-rt VIOLATION","hwjs-rt VIOLATION"];o(el,"globalAddr");o(pZ,"readCString");o(lc,"readViolationWitness");o(dc,"formatViolationWitness")});function _b(t,e){for(;;){let n=Atomics.load(t,0)|0;if(n===al||n===Gc)return!1;if(Atomics.compareExchange(t,0,n,Gc)===n)return Atomics.store(t,2,e|0),Atomics.notify(t,0),!0}}function xZ(t){wc=t}function TZ(t,e,n,s,r,i=!1){let l=t.byteLength,d=e>>>0,a=n>>>0,c=s>>>0;if(a===0)throw new Error(`hwjs-scatter: ${r} declares 0 segments (sglist 0x${d.toString(16)}, total ${c}B) \u2014 a staged image always has at least one segment; kernel/host ABI skew (never-silent)`);if(a>65536)throw new Error(`hwjs-scatter: ${r} declares ${a} segments, far past the kernel's WASM32_IMG_MAX_SEGS cap \u2014 REFUSED as a torn or misread request (never-silent)`);let h=a*hc;if(d===0||d>l||h>l-d)throw new Error(`hwjs-scatter: ${r} segment list [0x${d.toString(16)}, +${h}B) (${a} segments) is outside kernel memory (${l}B) \u2014 REFUSED (never-silent)`);let p=new DataView(t,d,h),m=[],y=0;for(let I=0;I>>0,X=p.getUint32(I*hc+4,!0)>>>0;if(X===0)throw new Error(`hwjs-scatter: ${r} segment ${I}/${a} has length 0 (offset 0x${R.toString(16)}) \u2014 the kernel never emits empty segments; REFUSED (never-silent)`);if(R===0||R>l||X>l-R)throw new Error(`hwjs-scatter: ${r} segment ${I}/${a} is [0x${R.toString(16)}, +${X}B) which runs past kernel memory (${l}B) \u2014 REFUSED (never-silent)`);if(y+=X,y>c)throw new Error(`hwjs-scatter: ${r} segments through ${I}/${a} already sum to ${y}B but the kernel declares ${c}B total \u2014 REFUSED (never-silent)`);m.push([R,X])}if(y!==c)throw new Error(`hwjs-scatter: ${r} segment lengths sum to ${y}B but the kernel declares ${c}B total \u2014 REFUSED (never-silent)`);let b=new Uint8Array(i?new ArrayBuffer(c):new SharedArrayBuffer(c)),f=0;for(let[I,R]of m)b.set(new Uint8Array(t,I,R),f),f+=R;return b}function Jb(t){if(!(t&&t.buffer instanceof SharedArrayBuffer))return t;if(rl===void 0)try{let e=new Uint8Array(new SharedArrayBuffer(8));e.set([0,97,115,109,1,0,0,0]),new WebAssembly.Module(e),rl=!0}catch{rl=!1}return rl?t:t.slice()}function Mo(t,e,n,s,r=!1){let i=t[`${n}_sglist_addr`],l=t[`${n}_nsegs`],d=t[`${n}_image_size`];if(typeof i!="function"||typeof l!="function"||typeof d!="function")throw new Error(`hwjs-scatter: this vmlinux does not export ${n}_sglist_addr/${n}_nsegs \u2014 it predates the segment-list staging ABI (memory-contract Part C) and this host has no flat-image path. Rebuild the kernel and the host together (never-silent).`);return TZ(e,i()>>>0,l()>>>0,d()>>>0,s,r)}function wi(t){let e=typeof SharedArrayBuffer<"u"&&t.buffer instanceof SharedArrayBuffer;return BZ.decode(e?t.slice():t)}async function YZ(t,e){let n=o(l=>e({kind:"dmesg",level:6,text:`[a4b] ${l}`}),"report"),s=39,r={ok:!1,instances:[],notes:[]},i=o((l,d)=>({kind:"init",mode:"fork",pid:0,tid:d,ppid:0,cpuId:t.cpuId|0,vmlinuxModule:t.vmlinuxModule,kernelMemory:t.kernelMemory,kernelMemoryWasm:t.kernelMemoryWasm,memory:l}),"mkInit");try{n(`instantiating vmlinux instance #1 cpu_id=${t.cpuId|0}`);let l=await Xc(i(t.userMemoryA,1001),e);if(!l){n("instance #1 FAILED to instantiate"),e({kind:"a4b-result",result:r});return}let d=l.instance.exports.wasm_syscall(s,0,0,0,0,0,0)|0;r.instances.push({idx:1,kernelPid:l.kernelPid|0,taskAddr:l.perProcessTaskAddr>>>0,getpid:d}),n(`instance #1: kernelPid=${l.kernelPid|0} task=0x${(l.perProcessTaskAddr>>>0).toString(16)} getpid=${d}`),n("resetting processVmlinuxInstanceCount (BYPASS R-K10-W1) for instance #2"),ll=0,n(`instantiating vmlinux instance #2 cpu_id=${t.cpuId|0} (same lane)`);let a=null;try{a=await Xc(i(t.userMemoryB,1002),e)}catch(b){n(`instance #2 instantiate THREW: ${b instanceof Error?b.message:String(b)}`)}if(!a){n("instance #2 FAILED \u2014 2nd same-Worker vmlinux instantiation is a HARD blocker for Approach A"),r.notes.push("second-instance-instantiate-failed"),e({kind:"a4b-result",result:r});return}let c=a.instance.exports.wasm_syscall(s,0,0,0,0,0,0)|0;r.instances.push({idx:2,kernelPid:a.kernelPid|0,taskAddr:a.perProcessTaskAddr>>>0,getpid:c}),n(`instance #2: kernelPid=${a.kernelPid|0} task=0x${(a.perProcessTaskAddr>>>0).toString(16)} getpid=${c}`);let h=l.instance.exports.wasm_syscall(s,0,0,0,0,0,0)|0;r.instances.push({idx:1,phase:"after-2",getpid:h}),n(`instance #1 re-getpid after #2: getpid=${h} (expect == ${d})`);let p=l.perProcessTaskAddr>>>0!==a.perProcessTaskAddr>>>0,m=d!==c,y=d===h;r.distinctTasks=p,r.distinctPids=m,r.inst1Intact=y,r.ok=p&&m&&y,n(`COEXIST: distinctTasks=${p} distinctPids=${m} inst1Intact=${y} => ${r.ok?"OK":"BROKEN"}`)}catch(l){r.error=l instanceof Error?`${l.message} ${l.stack}`:String(l),n(`PROBE THREW: ${r.error}`)}e({kind:"a4b-result",result:r})}function ul(t,e){if(Array.isArray(t))for(let n of t){if(!n||typeof n.digest!="string"||!n.bytes)continue;let s=rs.get(n.digest),r=Dh(s,n);if(!s){rs.set(n.digest,r);try{e&&e({kind:"dmesg",level:7,text:`hwjs-libc: shared-lib store gained digest ${n.digest.slice(0,16)}\u2026 (${n.bytes.length}B; store size ${rs.size})`})}catch{}}}}function Si(t){return t===Ub||t===Sc}function CZ(t,e){let s=t.cpuId|0;ul(t.sharedLibs,e),Kb(t.userImages);let r=new Map,i=new Map,l={blocks:0,switches:0,byTid:{},adds:0,dones:0},d=o(b=>{try{e({kind:"dmesg",level:6,text:`[cpu-worker cpu=${s}] ${b}`})}catch{}},"dbg"),a={cpuId:s,residentTasks:r,async blockYield(b,f){let I=r.get(b);I&&I.status!=="done"&&(I.status="blocked"),l.blocks++,l.byTid[b]=(l.byTid[b]|0)+1;let R=Dt?dr():0;Mn(e,`YIELD cpu=${s} tid=${b} reason=${f??"blockYield"} site=sched.blockYield slice=3ms`),await new Promise(X=>setTimeout(X,3)),Dt&&Mn(e,`RESUME cpu=${s} tid=${b} site=sched.blockYield waited=${(dr()-R).toFixed(1)}ms`),I&&I.status!=="done"&&(I.status="runnable"),l.switches++}},c=PZ({cpuId:s,residents:o(()=>r.values(),"residents"),emit:o((b,f)=>e({kind:"dmesg",level:b,text:f}),"emit"),mergedCpu0Lane:t.mergedCpu0Lane===!0}),h=o(b=>{let f=b.tid;if(b.claim){let N=new Int32Array(b.claim),K=Atomics.compareExchange(N,0,0,2);if(K!==0){d(`hwjs#3: add-task routeKey=${b.routeKey} tid=${f} DECLINED (claim=${K}: host canceled after lane-starvation timeout and re-placed the task; this stale placement is dropped)`);return}Atomics.notify(N,0)}if(b.mode==="migrate-resume"){if(!(b.mig instanceof SharedArrayBuffer)){e({kind:"error",routeKey:b.routeKey,tid:f,message:`add-task REFUSED: mode='migrate-resume' for tid=${f} carries no migration protocol word. A migration hand-off is a two-phase commit and the word IS the commit; without it this lane would start driving a task the source still believes it owns (never-silent).`});return}let N=new Int32Array(b.mig);if(Atomics.store(N,3,1),Atomics.compareExchange(N,0,Ic,Ao)!==Ic){d(`hwjs-migrate: add-task routeKey=${b.routeKey} tid=${f} DECLINED (offer already terminal: state=${Atomics.load(N,0)|0}); the source kept the task`);return}Atomics.notify(N,0);try{if(typeof process<"u"&&process.env&&process.env.HWJS_MIGRATE_RED_DROP==="1"){e({kind:"dmesg",level:4,text:`hwjs-migrate RED_DROP: cpu=${s} CLAIMED tid=${f} and is abandoning it without binding \u2014 simulating a destination that dies inside the commit window (test knob)`});return}}catch{}}if((b.mode||"fork")==="thread"){let N=["userLane","argRegionOffset","stackPointerOffset","tlsPointerOffset"].filter(K=>typeof b[K]!="number");if(N.length>0||(b.userLane|0)<=0){let K=N.length>0?`missing/non-numeric field(s): ${N.join(", ")}`:`userLane=${b.userLane|0} (a co-resident thread MUST carry a kernel-allocated user-RT lane > 0; lane 0 is the process main's single-slot shape and cannot be shared)`;e({kind:"error",routeKey:b.routeKey,tid:f,message:`add-task REFUSED: mode='thread' spec for tid=${f} routeKey=${b.routeKey} is incomplete \u2014 ${K}. A thread task init is only well-formed with userLane + argRegionOffset + stackPointerOffset + tlsPointerOffset; defaulting any of them would run the thread over a garbage arg region on the process main's lane (never-silent).`});return}}if(p){e({kind:"error",routeKey:b.routeKey,tid:f,message:`add-task REFUSED: this CPU-Worker realm (cpu=${s}) has been cooperatively STOPPED (the machine is tearing down and this lane has no Worker to terminate \u2014 PLAN-COLLAPSED-CPU0 \xA75). The task would never be driven; refusing it is what makes that visible to the placer instead of presenting as a task that was placed and never ran.`});return}l.adds++;try{typeof process<"u"&&process.env.A4C_DBG&&console.error(`[a4c-w] addTask tid=${f} routeKey=${b.routeKey} mode=${b.mode} cpu=${s}`)}catch{}try{typeof process<"u"&&process.env.A4C_FORKDBG&&e({kind:"dmesg",level:6,text:`[a4c-fork] addTask tid=${f} routeKey=${b.routeKey} mode=${b.mode} cpu=${s} (run() will instantiate+drive)`})}catch{}r.set(f,{tid:f,status:"runnable",argv:b.argv}),c.hosting(),Mn(e,`ADD cpu=${s} tid=${f} pid=${b.pid!=null?b.pid:f} mode=${b.mode||"fork"} lane=${b.userLane??0} routeKey=${b.routeKey} residents=${r.size}`);let I=b.routeKey,R=o(N=>{try{e(I!=null?{...N,routeKey:I}:{...N,tid:f})}catch{}},"taskPost"),X={kind:"init",mode:b.mode||"fork",pid:b.pid!=null?b.pid:f,tid:f,ppid:b.ppid|0,cpuId:s,wasmBytes:b.wasmBytes,memory:b.memory,ctrl:b.ctrl,vmlinuxModule:t.vmlinuxModule,hwjsRtModule:t.hwjsRtModule,hwjsRtBytes:t.hwjsRtBytes,hwjsRtProvenance:t.hwjsRtProvenance,kernelMemory:t.kernelMemory,kernelMemoryWasm:t.kernelMemoryWasm,...t.kernelLaneLocks!==void 0?{kernelLaneLocks:t.kernelLaneLocks}:{},...t.mergedCpu0Lane===!0?{mergedCpu0Lane:!0}:{},...I!=null?{routeKey:I}:{},allowMultiInstance:!0,...b.forceWasmSyscall?{forceWasmSyscall:!0}:{},...b.mode?{mode:b.mode}:{},...Array.isArray(b.argv)?{argv:b.argv}:{},...Array.isArray(b.envp)?{envp:b.envp}:{},...Array.isArray(b.lowFdRoutes)?{lowFdRoutes:b.lowFdRoutes}:{},...b.signalPendingOffset!==void 0?{signalPendingOffset:b.signalPendingOffset}:{},...b.inheritFiles!==void 0?{inheritFiles:b.inheritFiles}:{},...Array.isArray(b.fdActions)?{fdActions:b.fdActions}:{},...b.tlsBase!==void 0?{tlsBase:b.tlsBase}:{},...b.forkHandle!==void 0?{forkHandle:b.forkHandle}:{},...b.forkOwner!==void 0?{forkOwner:b.forkOwner}:{},...b.parentSp!==void 0?{parentSp:b.parentSp}:{},...b.forkLane!==void 0?{forkLane:b.forkLane}:{},...b.mig!==void 0?{mig:b.mig}:{},...b.migrateTaskAddr!==void 0?{migrateTaskAddr:b.migrateTaskAddr}:{},...b.migratePid!==void 0?{migratePid:b.migratePid}:{},...b.sp!==void 0?{sp:b.sp}:{},...b.mode==="migrate-resume"&&b.userLane!==void 0?{userLane:b.userLane|0}:{},...b.dlopenFork&&typeof b.dlopenFork=="object"?{dlopenFork:b.dlopenFork}:{},...b.hwjsRtWindowBase!==void 0?{hwjsRtWindowBase:b.hwjsRtWindowBase,hwjsRtWindowSize:b.hwjsRtWindowSize}:{},...b.hwjsLibcWindowBase!==void 0?{hwjsLibcWindowBase:b.hwjsLibcWindowBase,hwjsLibcWindowSize:b.hwjsLibcWindowSize}:{},...(b.mode||"fork")==="thread"?{userLane:b.userLane|0,argRegionOffset:b.argRegionOffset|0,stackPointerOffset:b.stackPointerOffset|0,tlsPointerOffset:b.tlsPointerOffset|0,...typeof b.mainTlsSlot=="number"?{mainTlsSlot:b.mainTlsSlot}:{}}:{},...t.pauseBuffer!==void 0?{pauseBuffer:t.pauseBuffer}:{}},F=o(N=>{if(b.mode!=="migrate-resume"||!(b.mig instanceof SharedArrayBuffer))return;let K=new Int32Array(b.mig);_b(K,N)&&e({kind:"dmesg",level:3,text:`hwjs-migrate: cpu=${s} tid=${f} FAILED to bind the migrated task and released the offer (abort code ${N}) \u2014 the source never released it and resumes driving it (loud, attributed)`})},"releaseOffer");Lb(X,R,a).then(()=>{F(Wc);let N=r.get(f);N&&(N.status="done"),r.delete(f),i.delete(f),Xi.delete(X),l.dones++,Mn(e,`DONE cpu=${s} tid=${f} residents=${r.size}`),r.size===0&&c.census()},N=>{F(Wc);let K=r.get(f);K&&(K.status="error"),r.delete(f),i.delete(f),Xi.delete(X),Mn(e,`DONE cpu=${s} tid=${f} status=error residents=${r.size}`),r.size===0&&c.census(),R({kind:"error",message:`cpu-worker task tid=${f}: ${N instanceof Error?`${N.message} ${N.stack}`:String(N)}`})})},"addTask"),p=!1;Bs={cpuId:s,residentTasks:r,sched:a,addTask:h,execResolvers:i,stats:l,dbg:d,stop:o(()=>{if(!p){p=!0;try{clearInterval(y)}catch{}d(`cooperative stop: ${r.size} resident(s) keep running to their own exit; no further placement is accepted on this lane`)}},"stopCpuWorker"),isStopped:o(()=>p,"isStopped")};let y=setInterval(()=>{let b=c.beat();if(Dt){let f=[...r.values()].map(I=>`${I.tid}:${I.status}`).join(",")||"none";Mn(e,`BEAT cpu=${s} #${c.stats().beats} gap=${b.toFixed(1)}ms period=${Sb}ms residents=[${f}] adds=${l.adds} dones=${l.dones} blocks=${l.blocks} switches=${l.switches}`)}},Sb);try{y?.unref?.()}catch{}try{typeof process<"u"&&process.env.A4C_DBG&&console.error(`[a4c-w] startCpuWorker cpu=${s} ready`)}catch{}d(`pool Worker ready (cpu_id=${s}); awaiting add-task`);for(let b of Array.isArray(t.tasks)?t.tasks:[])h(b)}function Mb({post:t,onMessage:e,onTerminate:n,callHostSync:s}){Ab=t,Ps=typeof s=="function"?s:null,n?.(()=>{Bs?.stop?.()}),e(async r=>{try{if(r?.kind==="exec-image"){if(Bs&&r.tid!=null&&Bs.execResolvers.has(r.tid)){let l=Bs.execResolvers.get(r.tid);Bs.execResolvers.delete(r.tid),l&&l(r);return}let i=wc;wc=null,i&&i(r);return}if(r?.kind==="a4b-coexist"){await YZ(r,t);return}if(r?.kind==="cpu-worker"){CZ(r,t);return}if(r?.kind==="add-task"){if(!Bs){t({kind:"error",pid:-1,message:"add-task before cpu-worker init"});return}Bs.addTask(r.spec||r);return}if(r?.kind==="shared-lib"){ul(r.sharedLibs,t);return}if(r?.kind==="user-image"){Kb(r.userImages);return}if(r?.kind==="thread-placement-request"){let i=r.pid|0,l=r.seq|0,d=r.routeKey!==void 0?{routeKey:r.routeKey}:{},a=null;for(let c of Xi.values())if((c.getPid()|0)===i){a=c;break}if(!a){t({kind:"thread-placement",seq:l,pid:i,...d,error:`no resident task with kernel pid ${i} in this Worker \u2014 thread-placement-request cannot be served (never-silent)`});return}try{t({kind:"thread-placement",seq:l,pid:i,...d,dlopenFork:a.build()})}catch(c){t({kind:"thread-placement",seq:l,pid:i,...d,error:"thread-placement snapshot failed: "+(c instanceof Error?c.message:String(c))})}return}if(r?.kind==="task-probe"){let i=r.seq|0,l=[];for(let d of Xi.values()){let a=d.getPid()|0;if(typeof d.probe!="function"){l.push({pid:a,probeReady:!1});continue}try{l.push({...d.probe(),probeReady:!0})}catch(c){l.push({pid:a,probeReady:!1,error:c instanceof Error?c.message:String(c)})}}t({kind:"task-probe-reply",seq:i,cpuId:Bs?Bs.cpuId:null,residents:Bs?[...Bs.residentTasks.values()].map(d=>({tid:d.tid|0,status:String(d.status)})):null,schedStats:Bs?{...Bs.stats}:null,isolateModuleCaches:jb(),tasks:l});return}if(r?.kind!=="init"){t({kind:"error",pid:-1,message:`unknown msg ${r?.kind}`});return}try{await Lb(r,t)}finally{Xi.delete(r)}}catch(i){t({kind:"error",pid:r?.pid??-1,message:i instanceof Error?`${i.message} ${i.stack??""}`:String(i)})}})}function Mn(t,e){if(Dt)try{t({kind:"dmesg",level:6,text:`hwjs-schedtrace t=${dr().toFixed(1)} ${e}`})}catch{}}function PZ({cpuId:t,emit:e,residents:n,now:s=dr,thresholdMs:r=MZ,censusMs:i=LZ,mergedCpu0Lane:l=!1}={}){let d=0,a=0,c=0,h=0,p=0,m=!1,y=s(),b=y,f=o((X,F)=>{try{e(X,F)}catch{}},"emitLine"),I=o(()=>{let X=typeof n=="function"?n():n;return X?[...X]:[]},"roster"),R=o(()=>{h++,p=d,b=s();let X=ac();f(7,`hwjs-worker-sched cpu=${t} beats=${d} maxGap=${a.toFixed(1)}ms turnKind=${X.kind} turns=${X.turns} belt=${X.beltTurns}`)},"census");return{beat(X=s()){let F=X-y;y=X,d++,F>a&&(a=F);let N=I();return N.length>0&&(m=!0),F>=r&&(c++,(c&c-1)===0&&f(4,`hwjs-worker-stall cpu=${t} loop unavailable ${F.toFixed(1)}ms (threshold ${r}ms) residents=[${N.map(K=>`${K.tid}:${K.status}`).join(",")||"none"}] occurrences=${c}`+(l?` thread=MERGED \u2014 this lane shares its JS thread with CPU 0 (the kernel Worker and the inline device backends), and this monitor can only see LANE ${t}'s residents. ${N.length===0?"An empty roster here does NOT mean nothing was running: with no resident of its own, the only thing that can have held this thread is CPU 0 \u2014 look at what the kernel was doing, not for a lane that froze idle.":"CPU 0 was also on this thread and is not in the roster above, so the residents named are a lower bound on what could have held it."}`:" thread=DEDICATED \u2014 this lane owns its JS thread, so the roster above is the complete list of what could have held it"))),m&&(p===0?d>0:X-b>=i)&&R(),F},census:R,hosting(){m=!0},stats:o(()=>({beats:d,maxGap:a,stalls:c,censuses:h}),"stats")}}function Ko(t,{cpu:e,pid:n,tid:s,site:r,label:i,fields:l,announce:d}){let a=dr(),c=a+kb,h=0,p=!!d,m=`cpu=${e??"?"} pid=${n??"?"} tid=${s??"?"} site=${r} label=${i}`;p&&Mn(t,`DRIVE-ENTER ${m}`);let y=o(b=>l?` ${l(b)}`:"","extra");return{holds:o(()=>h,"holds"),tick(b){let f=dr();f{let re=a[J];return re instanceof WebAssembly.Global?re.value>>>0:0},"dataAddr"),h=!1,p=o(J=>{if(!h){h=!0;try{let re=lc(a,n),Xe=dc(re,J);Xe&&s({kind:"dmesg",level:3,text:`${Xe} `})}catch{}}},"reportUndeliveredViolations"),m=c("__hwjs_parked_lanes"),y=c("__hwjs_parked_owner_lanes"),b=c("__hwjs_frame_live_lanes");if(!m||!y||typeof a.hwjs_resume!="function"||typeof a.hwjs_done!="function"||typeof a.hwjs_destroy!="function"||typeof a.__hwjs_take_parked!="function"||typeof a.__hwjs_slice_enter!="function"||typeof a.__hwjs_slice_exit!="function")return null;let f=e|0,I=null,R=null,X=o(()=>{let J=n.buffer;return J!==I&&(I=J,R=new Uint32Array(J)),R},"ku32"),F=(m>>2)+f|0,N=(y>>2)+f|0,K=b?(b>>2)+f|0:-1,k=i instanceof SharedArrayBuffer&&f>=0&&f<<20)return;if(Atomics.compareExchange(k,f,0,1)===0){H0&&Date.now()-re>=Lo)try{s({kind:"dmesg",level:4,text:`hwjs-lane[${f}] WAIT-END ${J} (pid=${r}) after ${Date.now()-re}ms `})}catch{}return}if(Ae=!0,Lo>0&&Date.now()>=Ve){Ve=Date.now()+Lo;let me=HXe){U--;let me=H0||(H=0?X()[K]>>>0:0,ae=typeof a.__hwjs_task_frames=="function"?a.__hwjs_task_frames()>>>0:0,Ce=typeof a.__hwjs_task_frames=="function",Q={lane:f,deferral:"F87c3-amended",brackets:0,drives:0,slices:0,frameResidue:0,poisoned:null},$=typeof process<"u"&&!!process.env.HWJS_LANE_DBG;function _e(J,re,Xe,Ae=Pi){let Ve=0;for(;!a.hwjs_done(re);){if($&&Ve<40)try{s({kind:"dmesg",level:6,text:`hwjs-lane[${f}] DBG drive ${J} slice=${Ve} h=0x${(re>>>0).toString(16)} owner=0x${(X()[N]>>>0).toString(16)}`})}catch{}a.hwjs_resume(re),Ve++,a.__hwjs_take_parked(Xe,re),Dt&&Ae.tick(Ve)}let me=typeof a.__hwjs_promise_i32=="function"?a.__hwjs_promise_i32(re)>>>0:0,je=me?X()[me>>2]|0:0;return a.hwjs_destroy(re),Q.drives++,Q.slices+=Ve,{value:je,slices:Ve}}o(_e,"driveToDone");function pe(J){if(K<0)return;let re=(X()[K]>>>0)-J|0;if(re!==0&&(Q.frameResidue+=re,Q.frameResidue>Rb))throw new Error(`hwjs-lane[${f}] FATAL: frame residue ${Q.frameResidue} crossed the never-silent ceiling ${Rb} (F87 conf (3): the interim reported-not-fatal deferral does not cover unexplained unbounded growth)`)}o(pe,"bracketCensus");function Ut(J,re){Q.brackets++,C(J);try{return rt(J,re)}finally{Ie()}}o(Ut,"bracket");function rt(J,re){let Xe=K>=0?X()[K]>>>0:0,Ae=Dt?Ko(s,{cpu:f,pid:r,tid:l,site:"bracket",label:J,announce:!1,fields:o(de=>`slices=${de}`,"fields")}):Pi;a.__hwjs_slice_enter();let Ve;try{Ve=re()}catch(de){!Q.poisoned&&!Si(de)&&(Q.poisoned=J);try{typeof a.__hwjs_dump_park_trace=="function"&&a.__hwjs_dump_park_trace()}catch{}throw p(`kernel lane ${f} ${J}`),a.__hwjs_slice_exit(),de}let me=X()[F]>>>0,je=0;if(me!==0){let de=X()[N]>>>0,ve=a.__hwjs_take_parked(0,0)>>>0,A;try{A=_e(J,ve,de,Ae)}catch(it){!Q.poisoned&&!Si(it)&&(Q.poisoned=J);try{typeof a.__hwjs_dump_park_trace=="function"&&a.__hwjs_dump_park_trace()}catch{}throw p(`kernel lane ${f} ${J} (mid-drive)`),a.__hwjs_slice_exit(),it}let{value:xe,slices:Oe}=A;je=Oe,s({kind:"hwjs-lane-drive",pid:r,lane:f,label:J,handle:ve,owner:de,slices:Oe}),Ve=xe}return a.__hwjs_slice_exit(),pe(Xe),Dt&&Ae.end(je),Ve}o(rt,"bracketLocked");let we=new Int32Array(new SharedArrayBuffer(4)),Qe=2,It=512;function Ct(J,re){Q.brackets++;let Xe=0,Ae=0,Ve=Dt?Ko(s,{cpu:f,pid:r,tid:l,site:"bracketYielding",label:J,announce:!0,fields:o(A=>`slices=${A} backoffs=${Xe} parked=${Ae} contended=${Ge?1:0}`,"fields")}):Pi;C(J);let me,je=0,de=0;{let A=K>=0?X()[K]>>>0:0;a.__hwjs_slice_enter();try{me=re()}catch(Oe){!Q.poisoned&&!Si(Oe)&&(Q.poisoned=J);try{typeof a.__hwjs_dump_park_trace=="function"&&a.__hwjs_dump_park_trace(),p(`kernel lane ${f}`)}catch{}throw a.__hwjs_slice_exit(),Ie(),Oe}if(X()[F]>>>0===0)return a.__hwjs_slice_exit(),pe(A),Ie(),Dt&&Ve.end(0),me;de=X()[N]>>>0,je=a.__hwjs_take_parked(0,0)>>>0,Ae=1,a.__hwjs_slice_exit(),Ie()}let ve=0;for(;;){C(J),a.__hwjs_slice_enter();let A,xe=0;try{if(A=!!a.hwjs_done(je),A||(a.hwjs_resume(je),ve++,a.__hwjs_take_parked(de,je),A=!!a.hwjs_done(je)),A){let Oe=typeof a.__hwjs_promise_i32=="function"?a.__hwjs_promise_i32(je)>>>0:0;xe=Oe?X()[Oe>>2]|0:0,a.hwjs_destroy(je)}}catch(Oe){!Q.poisoned&&!Si(Oe)&&(Q.poisoned=J);try{typeof a.__hwjs_dump_park_trace=="function"&&a.__hwjs_dump_park_trace(),p(`kernel lane ${f}`)}catch{}throw a.__hwjs_slice_exit(),Ie(),Oe}if(a.__hwjs_slice_exit(),Ie(),A)return Q.drives++,Q.slices+=ve,s({kind:"hwjs-lane-drive",pid:r,lane:f,label:J,handle:je,owner:de,slices:ve}),Dt&&Ve.end(ve),xe;Dt&&Ve.tick(ve),(Ge||ve%It===0)&&(Dt&&Xe++,Atomics.wait(we,0,0,Qe))}}o(Ct,"bracketYielding");let Mt=typeof a.__wasm32_set_park_consumer=="function",At=o(()=>Mt?a.__wasm32_set_park_consumer(KZ)>>>0:AZ,"declareParkConsumerHost"),q=o(J=>{Mt&&a.__wasm32_set_park_consumer(J>>>0)},"restoreParkConsumer"),_=typeof a.__wasm32_take_syscall_would_block=="function",D=!1;function ue(J){if(_)return(a.__wasm32_take_syscall_would_block()|0)!==0;if(!D){D=!0;try{s({kind:"dmesg",level:4,text:`hwjs-lane[${f}] this vmlinux exports no __wasm32_take_syscall_would_block, so a host drive (${J}) cannot tell a BLOCK park from a safepoint/budget park at a resume leg it owns; it drives such legs to completion exactly as before. The wasm_syscall route is unaffected (the kernel clears the flag and answers -517). Never-silent.`})}catch{}}return!1}o(ue,"takeSyscallWouldBlock");function x(J,re,Xe){Q.brackets++;let Ae=At();try{return ie(J,re,Xe)}finally{q(Ae)}}o(x,"driveWouldBlock");function ie(J,re,Xe){let Ae=0,Ve=Xe.h?1:0,me=0,je=Dt?Ko(s,{cpu:f,pid:r,tid:l,site:"driveWouldBlock",label:J,announce:!0,fields:o(de=>`slices=${de} backoffs=${Ae} parked=${Ve} contended=${Ge?1:0}`,"fields")}):Pi;if(Xe.h===0){C(J);let de=K>=0?X()[K]>>>0:0;a.__hwjs_slice_enter();let ve;try{ve=re()|0}catch(xe){!Q.poisoned&&!Si(xe)&&(Q.poisoned=J);try{typeof a.__hwjs_dump_park_trace=="function"&&a.__hwjs_dump_park_trace(),p(`kernel lane ${f}`)}catch{}throw a.__hwjs_slice_exit(),Ie(),xe}if(X()[F]>>>0===0){let xe=ue(J);return a.__hwjs_slice_exit(),pe(de),Ie(),Dt&&je.end(0),{wouldBlock:ve===Xb||xe,value:ve,slices:0}}Xe.owner=X()[N]>>>0,Xe.h=a.__hwjs_take_parked(0,0)>>>0,Ve=1,a.__hwjs_slice_exit(),Ie()}for(;;){C(J),a.__hwjs_slice_enter();let de,ve=!1,A=0,xe=Xe.h;try{if(de=!!a.hwjs_done(xe),de||(a.hwjs_resume(xe),me++,a.__hwjs_take_parked(Xe.owner,xe),de=!!a.hwjs_done(xe),ve=ue(J)),de){let Oe=typeof a.__hwjs_promise_i32=="function"?a.__hwjs_promise_i32(xe)>>>0:0;A=Oe?X()[Oe>>2]|0:0,a.hwjs_destroy(xe)}}catch(Oe){!Q.poisoned&&!Si(Oe)&&(Q.poisoned=J);try{typeof a.__hwjs_dump_park_trace=="function"&&a.__hwjs_dump_park_trace(),p(`kernel lane ${f}`)}catch{}throw a.__hwjs_slice_exit(),Ie(),Oe}if(a.__hwjs_slice_exit(),Ie(),de){let Oe=Xe.owner;return Xe.h=0,Xe.owner=0,Q.drives++,Q.slices+=me,s({kind:"hwjs-lane-drive",pid:r,lane:f,label:J,handle:xe,owner:Oe,slices:me}),Dt&&je.end(me),{wouldBlock:!1,value:A,slices:me}}if(ve)return Q.slices+=me,Dt&&je.end(me),{wouldBlock:!0,value:Xb,slices:me};Dt&&je.tick(me),(Ge||me%It===0)&&(Dt&&Ae++,Atomics.wait(we,0,0,Qe))}}o(ie,"driveWouldBlockInner");function ee(J,re){Q.brackets++,C(`wasm_syscall:${J|0}`);try{return P(J,re)}finally{Ie()}}o(ee,"dispatchSyscall");function P(J,re){let Xe=K>=0?X()[K]>>>0:0,Ae=`wasm_syscall:${J|0}`,Ve=Dt?Ko(s,{cpu:f,pid:r,tid:l,site:"dispatchSyscall",label:Ae,announce:!1,fields:o(ve=>`slices=${ve}`,"fields")}):Pi;a.__hwjs_slice_enter();let me;try{me=re()}catch(ve){throw!Q.poisoned&&!Si(ve)&&(Q.poisoned=`wasm_syscall:${J|0}`),a.__hwjs_slice_exit(),ve}let je=X()[F]>>>0,de=0;if(je!==0){let ve=X()[N]>>>0,A=a.__hwjs_take_parked(0,0)>>>0,{value:xe,slices:Oe}=_e(Ae,A,ve,Ve);de=Oe,s({kind:"hwjs-lane-drive",pid:r,lane:f,label:Ae,handle:A,owner:ve,slices:Oe}),me=xe}return a.__hwjs_slice_exit(),pe(Xe),Dt&&Ve.end(de),me}o(P,"dispatchSyscallLocked");function E(){let J=K>=0?X()[K]>>>0:0,re=Ce?a.__hwjs_task_frames()>>>0:0,Xe=Ce?re-ae|0:J-B|0||Q.frameResidue,Ae={...Q,liveAtCreate:B,liveAtExit:J,residue:Xe,framesAtCreate:ae,framesAtExit:re,perTask:Ce};if(Xe!==0&&!Q.poisoned){if(r===1)return s({kind:"dmesg",level:6,text:`hwjs-lane[${f}] pid 1 reconcile: boot-continuation residue ${Xe} frames `+(Ce?`(per-task frames ${ae} -> ${re}) `:`(lane-sum live ${B} -> ${J}) `)+"\u2014 EXPECTED (reused kernel_init's by-design parked boot frames, baselined as 0 before its final schedule() attributed them); non-fatal (HWJS-A-4.c residual-2 carve-out, pid 1 only)"}),{...Ae,explained:"pid1-boot-continuation"};throw s({kind:"error",pid:r,lane:f,message:`hwjs-lane[${f}] FATAL (quiesce reconciliation): end-of-process residue ${Xe} frames `+(Ce?`(per-task frames ${ae} -> ${re}) `:`(lane-sum live ${B} -> ${J}) `)+"with NO witnessed bracket trap \u2014 an unexplained leak the F87c3 deferral does not cover (amended form, manager 2026-06-11)"}),new Error(`hwjs-lane[${f}] unexplained end-of-process frame residue ${Xe} (reconciliation fatal)`)}return Ae}return o(E,"reconcile"),{lane:f,bracket:Ut,bracketYielding:Ct,driveWouldBlock:x,dispatchSyscall:ee,census:Q,reconcile:E}}function Nr(t,e,n){if(UZ)try{e({kind:"dmesg",level:6,text:`[thr-trace tid=${t?.tid??"?"} mode=${t?.mode??"?"} lane=${t?.userLane??"?"} cpu=${t?.cpuId??"?"}] ${n} t=${Date.now()} `})}catch{}}async function Xc(t,e){if(!t.allowMultiInstance&&ll!==0)return e({kind:"vmlinux-error",pid:t.pid,message:`K11-B2a per-Worker vmlinux invariant violated: vmlinux.wasm has already been instantiated ${ll} time(s) in this Worker. Each Worker (kernel or process) must instantiate vmlinux exactly once; re-instantiation re-runs the K10-A3 active- overlay against shared kernel memory and corrupts the running kernel's initcall arrays. See docs/ARCHITECTURE.md \xA715.3 R-K10-W1.`}),null;if(!t.kernelMemoryWasm)return e({kind:"vmlinux-error",pid:t.pid,message:"K11-B2a: cannot instantiate per-Worker vmlinux without a WebAssembly.Memory backing env.kernel_memory; spawn handler must pass kernelMemoryWasm in the init message (see KernelSpawnHandlerOptions.kernelMemoryWasm)."}),null;let n=new TextDecoder("utf-8",{fatal:!1});function s(_,D,ue){let x=new Uint8Array(t.kernelMemoryWasm.buffer,D,ue),ie=new Uint8Array(ue);ie.set(x);let ee=n.decode(ie);Zc(e,t.routeKey,t.pid,_,ee)}o(s,"dmesg");let r=255,i=1e4,l=1e6,d=65535,a=t.mergedCpu0Lane===!0,c=0,h=0,p=0;function m(){if(!a||(Ps!==null&&(++c&r)===0&&Ps(y),(++h&d)!==0))return;let _=Date.now();if(p===0){p=_;return}let D=_-p;if(D{let _=t.kernelMemoryWasm.buffer;return _!==f&&(f=_,I=new Int32Array(_)),I},"kernI32"),X=!!globalThis.process?.env?.HWJS_67_TRACE,F=!!globalThis.process?.env?.HWJS_STALL_TRACE,N=(()=>{let _=parseInt(globalThis.process?.env?.HWJS_STALL_TRACE??"",10);return Number.isFinite(_)&&_>=100?_:15e3})(),K=!!globalThis.process?.env?.HWJS_STALL_STACK;K&&(Error.stackTraceLimit=200);let k=0,U=0,M=0;function H(_,D,ue){let x=(_|0)>>>2;if(typeof ue=="bigint"&&ue>=0n){let ee=Number(ue/1000000n);if(F){k++;let E=Date.now();if(E-U>N){U=E;let J="";if(K)try{J=" at "+String(new Error().stack??"").split(` `).slice(1,40).map(re=>re.trim()).filter(re=>!/\.hwjs_resume \(/.test(re)).join(" <- ")}catch{}Zc(e,t.routeKey,t.pid,5,`STALL-TRACE pid=${t.pid??"?"} tid=${t.tid|0} lane=${t.userLane??0} kern-wait addr=0x${(_>>>0).toString(16)} expected=${D|0} cur=${Atomics.load(R(),x)|0} timeoutMs=${ee} waits=${k}${J}`)}}let P=Atomics.wait(R(),x,D|0,ee);return P==="ok"?0:P==="not-equal"?1:2}if(X)try{e({kind:"dmesg",level:6,text:`t67 tid=${t.tid|0} KERN-ATOMIC-WAIT-INF addr=0x${(_>>>0).toString(16)} expected=${D|0} cur=${Atomics.load(R(),x)|0}`})}catch{}if(t.mergedCpu0Lane===!0)return M++,(M&M-1)===0&&Zc(e,t.routeKey,t.pid,3,`hwjs-merged REFUSED an UNBOUNDED in-kernel wait on the merged CPU-0 lane: pid=${t.pid??"?"} tid=${t.tid|0} addr=0x${(_>>>0).toString(16)} expected=${D|0}. This lane shares its JS thread with CPU 0 (and, inline, with the device backends that would deliver the wake), so blocking here stops the machine, not just this task. Answering 'timed out' instead \u2014 the caller re-checks and returns. Occurrence ${M}. A merged machine runs only images whose libc absorbs the -517 park; if this fires, that assumption is false for this image. There is no other topology to move it to \u2014 every machine is merged \u2014 so what has to change is the image's libc, or the kernel path that reached an unbounded wait from a call graph the libc's nomination list does not cover.`),2;let ie=Atomics.wait(R(),x,D|0);if(X)try{e({kind:"dmesg",level:6,text:`t67 tid=${t.tid|0} KERN-ATOMIC-WAIT-INF WOKE addr=0x${(_>>>0).toString(16)} r=${ie}`})}catch{}return ie==="ok"?0:ie==="not-equal"?1:2}o(H,"atomic_wait_i32");function Ge(_,D){return Atomics.notify(R(),(_|0)>>>2,D|0)}o(Ge,"atomic_notify");let C=o(_=>(...D)=>(e({kind:"unimplemented-host-call",name:_,pid:t.pid}),0),"stubHost"),Ie=o(_=>{throw e({kind:"vmlinux-error",pid:t.pid,message:_}),new Error(_)},"uaccessRefuse"),B=Qa({userMemory:t.memory,kernelMemory:t.kernelMemoryWasm,refuse:Ie,context:`pid=${t.pid} process Worker`,redPark:!!globalThis.process?.env?.HWJS_RED_UACCESS_PARK}),ae=-1,Q={dmesg:s,cpu_relax_host:m,now_ns:b,mem_commit:o(_=>{let D=t.kernelMemoryWasm,ue=(_>>>0)*4096,x=D.buffer.byteLength;if(ue>x){try{D.grow(Math.ceil((ue-x)/65536))}catch{}let ie=D.buffer.byteLength;ie!==x&&ae>=0&&Atomics.store(new Int32Array(D.buffer),ae,ie/4096|0)}return D.buffer.byteLength/4096>>>0},"mem_commit"),atomic_wait_i32:H,atomic_notify:Ge,...B.imports,console_write:C("console_write"),console_read_nonblock:C("console_read_nonblock"),hlt:C("hlt"),mmap_user_page:C("mmap_user_page"),munmap_user_page:C("munmap_user_page"),spawn_worker:C("spawn_worker"),terminate_worker:C("terminate_worker"),signal_inject:C("signal_inject"),virtio_kick:C("virtio_kick")},_e={env:{kernel_memory:t.kernelMemoryWasm},linux:Q,hwjs_suspend:{park:B.guardPark(()=>{})}},pe=Oa(t.vmlinuxModule);if(pe.length>0)return e({kind:"vmlinux-error",pid:t.pid,message:`uaccess-leaf-witness: refusing to instantiate vmlinux in the process Worker: - `+pe.join(` - `)}),null;let Ut=WebAssembly.Module.imports(t.vmlinuxModule),rt=[];for(let _ of Ut){let D=Object.hasOwn(_e,_.module)?_e[_.module]:void 0;(!D||!Object.hasOwn(D,_.name))&&rt.push(`${_.module}.${_.name} (${_.kind})`)}if(rt.length>0)return e({kind:"vmlinux-error",pid:t.pid,message:"K11-B2a: vmlinux import-resolution failure in process Worker; missing: "+rt.join(", ")}),null;let we;try{Nr(t,e,"vmlinux-instantiate-begin"),we=await WebAssembly.instantiate(t.vmlinuxModule,_e),Nr(t,e,"vmlinux-instantiate-end"),ll+=1;{let _=we.exports.wasm32_committed_pages;_&&typeof _.value=="number"&&(ae=_.value>>>0>>2)}typeof we.exports.__wasm32_set_coop_sched=="function"&&we.exports.__wasm32_set_coop_sched(0);{let _=we.exports.__hwjs_parked_lanes??we.exports.__hwjs_parked,D=_ instanceof WebAssembly.Global?_.value>>>0:0;if(D){let ue=we.exports.__hwjs_parked_lanes?(t.cpuId|0)*4:0,x=D+ue>>2,ie=new Uint32Array(t.kernelMemoryWasm.buffer);B.setParkedSlotReader(()=>ie[x]>>>0)}}}catch(_){return e({kind:"vmlinux-error",pid:t.pid,message:"K11-B2a: vmlinux WebAssembly.instantiate trapped: "+(_ instanceof Error?_.message:String(_))}),null}if(typeof we.exports.__hwjs_budget_set=="function"&&we.exports.__hwjs_budget_set(NZ|0),typeof we.exports.__wasm_call_ctors=="function")try{we.exports.__wasm_call_ctors()}catch(_){return e({kind:"vmlinux-error",pid:t.pid,message:"K11-B2a: vmlinux __wasm_call_ctors trapped (likely a second-instance __wasm_init_memory or active-overlay invariant violation): "+(_ instanceof Error?_.message:String(_))}),null}if(typeof t.cpuId=="number"&&typeof we.exports.__wasm32_set_cpu_id=="function")try{we.exports.__wasm32_set_cpu_id(t.cpuId|0)}catch(_){return e({kind:"vmlinux-error",pid:t.pid,message:"K11-B2b: vmlinux __wasm32_set_cpu_id trapped: "+(_ instanceof Error?_.message:String(_))}),null}if(typeof t.cpuId=="number"&&(t.cpuId|0)>=1&&typeof we.exports.__wasm32_lane_stack_init=="function")try{!(we.exports.__wasm32_lane_stack_init()>>>0)&&e({kind:"dmesg",level:4,text:`hwjs #61 RED arm (wasm_shared_lane_stack): lane ${t.cpuId|0} keeps the SHARED module shadow stack \u2014 cross-Worker stack corruption is reproducible by design`})}catch(_){return e({kind:"vmlinux-error",pid:t.pid,message:"#61: vmlinux __wasm32_lane_stack_init trapped: "+(_ instanceof Error?_.message:String(_))}),null}else typeof t.cpuId=="number"&&(t.cpuId|0)>=1&&e({kind:"dmesg",level:4,text:`hwjs #61: vmlinux lacks __wasm32_lane_stack_init (older build) \u2014 lane ${t.cpuId|0} runs direct kernel calls on the SHARED module shadow stack (cross-Worker corruption window open)`});let Qe=zZ(we,typeof t.cpuId=="number"?t.cpuId|0:0,t.kernelMemoryWasm,e,t.pid,t.kernelLaneLocks,t.tid,t.mergedCpu0Lane===!0),It=0,Ct=0,Mt=t.pid|0;if(typeof we.exports.__wasm32_get_init_task_addr=="function"&&typeof we.exports.__wasm32_set_current=="function"){try{It=(we.exports.__wasm32_get_init_task_addr()|0)>>>0,we.exports.__wasm32_set_current(It|0)}catch(_){return e({kind:"vmlinux-error",pid:t.pid,message:"K11-B5: vmlinux __wasm32_set_current(&init_task) trapped: "+(_ instanceof Error?_.message:String(_))}),null}if(t.mode==="migrate-resume"){let _=(t.migrateTaskAddr|0)>>>0;if(_===0)return e({kind:"vmlinux-error",pid:t.pid,message:"migrate-resume without a migrateTaskAddr \u2014 a migration binds an EXISTING task and there is nothing to bind (never-silent; the source still holds the task and will resume it)"}),null;let D=0;try{we.exports.__wasm32_set_current(_|0),typeof we.exports.__wasm32_task_pid=="function"&&(D=we.exports.__wasm32_task_pid(_|0)|0)}catch(x){return e({kind:"vmlinux-error",pid:t.pid,message:"migrate-resume bind of task 0x"+_.toString(16)+" trapped: "+(x instanceof Error?x.message:String(x))}),null}let ue=t.migratePid|0;if(ue>0&&D!==ue)return e({kind:"vmlinux-error",pid:t.pid,message:`migrate-resume bind REFUSED: task address 0x${_.toString(16)} reports pid ${D}, the source said ${ue}. Refusing to drive a task that is not the one being migrated (never-silent).`}),null;Ct=_,D>0&&(Mt=D)}else if(typeof we.exports.__wasm32_alloc_process_task=="function")try{let _=(t.ppid|0)>>>0,D=t.inheritFiles===2?2:t.inheritFiles?1:0,ue=t.mode==="thread"?t.tid|0:0,x=o(()=>we.exports.__wasm32_alloc_process_task(t.pid|0,_|0,D|0,ue|0)|0,"rawAllocCall");Nr(t,e,"alloc-process-task-begin");let ie=((Qe?Qe.bracket("__wasm32_alloc_process_task",x):x())|0)>>>0;if(Nr(t,e,`alloc-process-task-end addr=${ie}`),ie===0)return e({kind:"vmlinux-error",pid:t.pid,message:"linux#7: vmlinux __wasm32_alloc_process_task("+(t.pid|0)+", "+(t.ppid|0)+") returned 0 (alloc_pid failure) \u2014 spawn refused (hwjs#65: parent gets -EAGAIN, the machine keeps running)"}),null;{if(we.exports.__wasm32_set_current(ie|0),Ct=ie,typeof we.exports.__wasm32_task_pid=="function"){let P=we.exports.__wasm32_task_pid(ie|0)|0;P>0&&(Mt=P)}t.mode==="thread"&&typeof we.exports.__wasm32_task_set_thread_worker=="function"&&we.exports.__wasm32_task_set_thread_worker(ie|0);let ee=Array.isArray(t.fdActions)?t.fdActions:null;if(ee&&typeof we.exports.wasm_syscall=="function")for(let J=0;Jwe.exports.wasm_syscall(33,Ae,Ve,0,0,0,0)|0,"call");me=(Qe?Qe.dispatchSyscall(33,je):je())|0}else if(Xe===1){let je=o(()=>we.exports.wasm_syscall(3,Ae,0,0,0,0,0)|0,"call");me=(Qe?Qe.dispatchSyscall(3,je):je())|0}else me=-22;if(me<0)return e({kind:"vmlinux-error",pid:t.pid,message:"K13-A: spawn fd-action "+J+" (op="+Xe+", fd1="+Ae+", fd2="+Ve+") failed rc="+me}),null}}}catch(_){try{if(typeof we.exports.__hwjs_lane_contain=="function"){let D=we.exports.__hwjs_lane_contain()|0;D!==0&&e({kind:"dmesg",level:3,text:`hwjs #85 CONTAINMENT pid=${t.pid} (alloc-task trap): kernel lane state reclaimed (dirty mask=${D}) \u2014 this spawn degrades -EAGAIN, the next spawn on this lane works`})}}catch{}return e({kind:"vmlinux-error",pid:t.pid,message:"K11-C1.a: vmlinux __wasm32_alloc_process_task("+(t.pid|0)+", "+(t.ppid|0)+") trapped: "+(_ instanceof Error?_.message:String(_))+(_ instanceof Error&&_.stack?` ALLOC-TASK-STACK: `+_.stack.split(` `).slice(0,12).join(" | "):"")}),null}}if(typeof t.signalPendingOffset=="number"&&typeof we.exports.__wasm32_kernel_set_signal_region=="function")try{we.exports.__wasm32_kernel_set_signal_region(t.signalPendingOffset>>>0)}catch{}let At=typeof we.exports.wasm_syscall=="function",q=0;if(typeof we.exports.__hwjs_task_wake_addr=="function")try{q=we.exports.__hwjs_task_wake_addr()>>>0}catch{}if(t.mergedCpu0Lane===!0&&t.mode!=="migrate-resume"&&Ps!==null&&t.routeKey!=null){let _;try{_=Ps({kind:"task-register-sync",routeKey:t.routeKey,pid:Mt})}catch{_=void 0}if(_!=="registered")try{e({kind:"dmesg",level:4,text:`hwjs-merged REGISTER-SYNC DECLINED pid=${Mt|0} tid=${t.tid|0} routeKey=${t.routeKey}: the host did not register this task through the synchronous door (answer=${_===void 0?"declined":String(_)}), so its kernel pid arrives only with the vmlinux-ready MESSAGE \u2014 which this thread cannot deliver while the guest holds it. Every host-answered syscall until then takes the deferred -517 route and depends on this libc re-issuing it.`})}catch{}}return e({kind:t.mode==="migrate-resume"?"vmlinux-rebound":"vmlinux-ready",pid:Mt,tid:t.tid,hasWasmSyscall:At,initTaskAddr:It,perProcessTaskAddr:Ct,perProcessTaskWakeAddr:q,...t.mode==="migrate-resume"?{cpuId:t.cpuId|0}:{}}),{instance:we,initTaskAddr:It,perProcessTaskAddr:Ct,kernelPid:Mt,hwjsLane:Qe}}function jZ({getExports:t,getLane:e,post:n}){let s={phase:"idle",pathPtr:0,remaining:0,chunks:0,blocks:0,chain:{h:0,owner:0}},r=0;function i(){r=s.blocks,s.phase="idle",s.pathPtr=0,s.remaining=0,s.chunks=0,s.blocks=0,s.chain.h=0,s.chain.owner=0}o(i,"execLoadPhaseReset");let l=null;function d(c,h=!1){let p=t(),m=e();if(typeof p.wasm32_user_exec_load_begin!="function"||typeof p.wasm32_user_exec_load_step!="function"){let y=o(()=>p.wasm32_user_exec_load(c>>>0)|0,"loadCall");return(m?m.bracket("wasm32_user_exec_load",y):y())|0}if(s.phase==="idle")typeof p.wasm32_user_exec_defer_commit=="function"&&p.wasm32_user_exec_defer_commit(),s.phase="begin",s.pathPtr=c>>>0,s.remaining=1/0,s.chunks=0,s.blocks=0;else if(s.pathPtr!==c>>>0)throw new Error(`execLoadKernelChunked: a load for pathPtr=0x${(c>>>0).toString(16)} entered while a load for 0x${s.pathPtr.toString(16)} is in flight (phase=${s.phase}, chunks=${s.chunks}, chain=0x${s.chain.h.toString(16)}) \u2014 refusing to abandon a live chain (never-silent)`);for(;;){let y=s.phase==="begin",b=y?uc:fb,f;try{f=a(b,c)|0}catch(I){throw i(),I}if(f===an){if(s.blocks++,h)return an;continue}if(f===Eb)return f|0;if(f<0)return i(),f|0;if(f===0)return i(),0;if(!(f>>0):p.wasm32_user_exec_load_step())|0;if(l!==!1&&typeof p.wasm_syscall=="function"){let b=m.driveWouldBlock(`wasm_syscall:${c}`,()=>p.wasm_syscall(c,h>>>0,0,0,0,0,0)|0,s.chain);if(b.wouldBlock)return l=!0,an;if(b.value!==-38)return l=!0,b.value|0;if(l===null){l=!1;try{n({kind:"dmesg",level:6,text:`hwjs-exec: this vmlinux answers no __NR_wasm_exec_load_begin/_step (${uc}/${fb}); driving the chunked load through the bare exports, which get no park preservation. Never-silent.`})}catch{}}else return-38}return m.bracketYielding(y?"wasm32_user_exec_load_begin":"wasm32_user_exec_load_step",()=>(y?p.wasm32_user_exec_load_begin(h>>>0):p.wasm32_user_exec_load_step())|0)|0}return o(a,"execLoadIssue"),{load:d,phase:s,blocks:o(()=>s.blocks,"blocks"),blocksLast:o(()=>r,"blocksLast")}}function Vb(t){return o(async function(n){let s=Ls();await t(n),await s},"parkYieldWithTurn")}async function Po({load:t,yieldTurn:e,onYield:n}){for(;;){let s=t()|0;if(s!==an)return s;n&&n(),await e()}}function OZ({len:t,from:e=0,read:n,wait:s=null,restartCap:r=1/0}){let i=e,l=0,d=0,a=o((c,h,p)=>({done:i,err:c,parked:h,lost:p,restarts:d}),"out");for(;ir)return a(-4,!1,!0);s();continue}if(c===0)break;if(c<0)return a(c,!1,!1);i+=c,l=0}return a(0,!1,!1)}function QZ({alloc:t,free:e,read:n,guestResumes:s,canWait:r,wait:i,epoch:l,restartCap:d}){let a=null,c=o(h=>({addr:0,done:0,err:0,parked:!1,lost:!1,restarts:0,...h}),"none");return{map(h){let p=0,m=-1;if(a!==null){let I=a;if(I.mfd===h.mfd&&I.len===h.len&&I.prot===h.prot&&I.flags===h.flags&&I.off===h.off&&I.epoch===l())a=null,m=I.addr,p=I.done;else{let X=n(I,I.addr,I.done)|0;if(Rc(X))return c({parked:!0,restarts:1});a=null,e(I.addr,I.len)}}if(m<0&&(m=t(h)|0,m<0))return c({addr:m,err:m});let y=s(),b=0,f=OZ({len:h.len,from:p,read:o(I=>b=n(h,m,I)|0,"read"),wait:!y&&r()?i:null,restartCap:d});if(f.parked&&y)a={...h,addr:m,done:f.done,epoch:l()};else if(f.parked)return e(m,h.len),{addr:m,...f,parked:!1,err:b};return{addr:m,...f}},reset(){a=null}}}function DZ(t,e){if(e<0)return!1;let n=Atomics.load(t,e)|0,s=Atomics.load(t,e+1)|0;return n!==0||s!==0}function qZ(t){return(t&3)!==0&&(t&-9476)===0}function Bb(t,e,n,s,r){let i=s>=0?Atomics.load(t,s)|0:0,l=Atomics.waitAsync(t,e,n,r);if(!l.async)return Promise.resolve(l.value);if(s<0||!qZ(i))return l.value;let d=Atomics.waitAsync(t,s,i,r);return d.async?Promise.race([l.value.then(a=>[s,a]),d.value.then(a=>[e,a])]).then(([a,c])=>(Atomics.notify(t,a,1),c)):(Atomics.notify(t,e,1),Promise.resolve(d.value))}function ng({getI32:t,getIdx:e,inExecWindow:n,askKernel:s,red:r}){let i=!!(r&&r.hostWritesBit);function l(){let p=e();return p<0?!1:(Atomics.load(t(),p+Tb)&Yb)!==0}o(l,"pendingNow");function d(){let p=e();return p<0?0:Atomics.load(t(),p+tg)>>>0}o(d,"deliverySeq");function a(){let p=e();if(p<0)return;let m=p+eg;Atomics.add(t(),m,1),Atomics.notify(t(),m,1/0)}o(a,"wake");function c(){let p=e();return p<0?!1:i?(Atomics.or(t(),p+Tb,Yb),a(),!0):s()>0?(a(),!0):!1}o(c,"republish");function h(p){return!p||n()||l()?!1:c()}return o(h,"maybeReassert"),{pendingNow:l,deliverySeq:d,maybeReassert:h,republish:c}}async function Lb(t,e,n){Nr(t,e,"run-entry"),Mn(e,`RUN cpu=${t.cpuId??"?"} tid=${t.tid} pid=${t.pid} mode=${t.mode??"fork"} lane=${t.userLane??0} resident=${n?1:0}`);let s=new Int32Array(t.ctrl,0,16);s[ce.PID]=t.pid,s[ce.TID]=t.tid,ul(t.sharedLibs,e),Xi.set(t,{getPid:o(()=>s[ce.PID]|0,"getPid"),build:o(()=>Nn(),"build")});let r=t.pauseBuffer?new Int32Array(t.pauseBuffer):null,i=o(()=>{if(r)for(;Atomics.load(r,0)===1;)Atomics.wait(r,0,1,200)},"maybePause"),l=!1,d=0,a=null,c=!1,h=!1,p=!1;async function m(u,Z){if(!h&&!(!Ze||He===0||typeof Ze.exports.__wasm32_notify_child_exit!="function")){if(h=!0,ed)try{e({kind:"dmesg",level:6,text:`hwjs-fd pid=${s[ce.PID]|0} NOTIFY-CHILD-EXIT ptask=0x${(He>>>0).toString(16)} code=${u|0} signaled=${Z|0}`})}catch{}try{let g=Ze.exports;if(typeof g.wasm32_exit_drain_step=="function"&&ft){let S={h:0,owner:0},Y=o(()=>g.wasm32_exit_drain_step()|0,"step"),v=0;await Po({load:o(()=>ft.driveWouldBlock("wasm32_exit_drain_step",Y,S).wouldBlock?an:0,"load"),yieldTurn:o(()=>Es("exit-drain park"),"yieldTurn"),onYield:o(()=>{if(v++,v===1)try{e({kind:"dmesg",level:6,text:`hwjs-exit pid=${t.pid} tid=${t.tid|0} wasm32_exit_drain_step would-block \u2014 handing the CPU Worker back across a real event-loop turn before resuming the preserved syscall chain (the device backends and the in-flight fetch continuations run in that turn; this is the turn the native in-wasm drain could not take)`})}catch{}Dt&&Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=EXIT-DRAIN-park site=wasm32-exit-drain-step via=wake-word`)},"onYield")})}else if(!p){p=!0;try{e({kind:"dmesg",level:4,text:`hwjs-exit pid=${t.pid} `+(typeof g.wasm32_exit_drain_step=="function"?"has no hwjs lane bracket, so ":"this vmlinux exports no wasm32_exit_drain_step, so ")+"the exit drain is NOT driven from JS: a preserved block-parked syscall is drained by entry.c's native in-wasm spin inside task_exit_cleanup, which cannot hand a would-block back. On a merged lane that spin holds the JS thread the backend it is waiting on runs on, and the wait ends only at fs/fuse/dev.c's deadline (wasm_fuse_timeout, 120 s). Never-silent."})}catch{}}if(typeof g.task_exit_cleanup=="function"){let S=o(()=>(g.task_exit_cleanup(He|0),0),"cleanup");if(ft){let Y={h:0,owner:0},v=0;await Po({load:o(()=>ft.driveWouldBlock("task_exit_cleanup",S,Y).wouldBlock?an:0,"load"),yieldTurn:o(()=>Es("task-exit-cleanup park"),"yieldTurn"),onYield:o(()=>{if(v++,v===1)try{e({kind:"dmesg",level:6,text:`hwjs-exit pid=${t.pid} tid=${t.tid|0} task_exit_cleanup would-block \u2014 handing the CPU Worker back across a real event-loop turn before resuming the preserved cleanup chain (contract 3, site 4)`})}catch{}Dt&&Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=EXIT-CLEANUP-park site=task-exit-cleanup via=wake-word`)},"onYield")})}else S()}let G=o(()=>(g.__wasm32_notify_child_exit(He|0,u|0,Z|0),0),"call");if(ft?ft.bracket("__wasm32_notify_child_exit",G):G(),typeof g.task_exit_notify_parent=="function"){let S=o(()=>(g.task_exit_notify_parent(He|0),0),"notifyParent");ft?ft.bracket("task_exit_notify_parent",S):S()}}catch(g){e({kind:"error",pid:t.pid,message:"F112 child-exit (task_exit_cleanup / __wasm32_notify_child_exit) trapped: "+(g instanceof Error?g.message:String(g))})}}}o(m,"notifyChildExitOnce");async function y(){let u=a;u&&(a=null,await m(u.codeArg,u.signaled),b(u))}o(y,"runExitTerminus");function b({codeArg:u,signaled:Z,grpExit:g}){l||(l=!0,e({kind:"exit",pid:t.pid,code:d,kind_exit:Z?"exit-by-signal":"exit",signal:Z?u&127:0,...g?{groupExit:{wstatus:g.wstatus,zapped:g.zapped}}:{},wasmSyscallStats:{...xr},...pr>0?{coopWaitViolations:pr}:{},...Br>0?{syncRestartViolations:Br}:{},...ft?{hwjsLaneCensus:Cb(ft)}:{}}))}o(b,"postExitMessage");function f(u){try{if(Ze&&typeof Ze.exports.__hwjs_lane_contain=="function"){try{typeof Ze.exports.__hwjs_dump_park_trace=="function"&&Ze.exports.__hwjs_dump_park_trace()}catch{}let Z=Ze.exports.__hwjs_lane_contain()|0;return Z!==0&&e({kind:"dmesg",level:3,text:`hwjs #85 CONTAINMENT pid=${t.pid} tid=${t.tid|0} (${u}): kernel lane state reclaimed after a terminal trap (dirty mask=${Z}: 1=orphaned parked slot, 2=in-violation latch, 4=stale slice marker) \u2014 identities in the hwjs-rt containment lines above`}),Z}}catch(Z){e({kind:"dmesg",level:3,text:`hwjs #85 CONTAINMENT pid=${t.pid}: __hwjs_lane_contain itself trapped (${Z instanceof Error?Z.message:String(Z)}) \u2014 lane state NOT reclaimed; a same-lane bystander may still trap`})}return 0}o(f,"containTrappedLane");let I=!1,R=0;function X(u,Z){if(I||!Ze||He===0)return null;I=!0;let g=Z?`a fatal terminus by signal ${u&127}`:`exit_group(${u&255})`,G=Ze.exports;if(typeof G.__wasm32_group_exit!="function")return e({kind:"dmesg",level:3,text:`hwjs-groupexit pid=${t.pid} tid=${t.tid|0}: this vmlinux has no __wasm32_group_exit export \u2014 ${g} cannot be decided by the kernel, so do_group_exit/zap_other_threads do not run and only the calling task ends. KERNEL/HOST SKEW: rebuild vmlinux`}),null;if(R===0)try{R=(G.__wasm32_group_exit.length|0)>=2?2:1}catch{R=1}if(Z&&R<2)return e({kind:"dmesg",level:3,text:`hwjs-groupexit pid=${t.pid} tid=${t.tid|0}: this vmlinux's __wasm32_group_exit takes no by_signal argument \u2014 ${g} cannot be decided by the kernel, so the group is NOT condemned by it and this process may outlive a fatal signal on one of its threads. KERNEL/HOST SKEW: rebuild vmlinux`}),null;try{let S=Z?u&127:u&255,Y=o(()=>G.__wasm32_group_exit(S,Z?1:0)|0,"call"),v=(ft?ft.bracket("__wasm32_group_exit",Y):Y())|0;return v<0?null:{wstatus:v&65535,zapped:v>>>16&32767}}catch(S){return e({kind:"dmesg",level:3,text:`hwjs-groupexit pid=${t.pid} tid=${t.tid|0}: __wasm32_group_exit trapped (${S instanceof Error?S.message:String(S)}) \u2014 the group's other threads were NOT condemned; this process may outlive ${g}`}),null}}o(X,"decideGroupExit");function F(u=9,Z="thread trap"){try{let g=Ze?Ze.exports:null;if(!g||He===0||typeof g.__wasm32_thread_trap_contain!="function"){e({kind:"dmesg",level:3,text:`hwjs #85 CONTAINMENT pid=${t.pid} tid=${t.tid|0}: ${Z} group-kill UNAVAILABLE (vmlinux export/task missing) \u2014 the host-side spawn-handler belt still delivers SIGKILL to the group`});return}let G=o(()=>(g.__wasm32_thread_trap_contain(u|0),0),"call");ft?ft.bracket("__wasm32_thread_trap_contain",G):G()}catch(g){e({kind:"dmesg",level:3,text:`hwjs #85 CONTAINMENT pid=${t.pid} tid=${t.tid|0}: __wasm32_thread_trap_contain trapped (${g instanceof Error?g.message:String(g)}) \u2014 kernel-side group kill incomplete; the host-side spawn-handler belt still delivers SIGKILL to the group`})}}o(F,"containThreadGroupAfterTrap");let N=0,K=16,k=57,U=59,M=0,H=1,Ge=2,C=null,Ie=null,B=null,ae=null,Ce=null,Q=null,$=null,_e=[],pe=[],Ut=[],rt=!1,we=!1,Qe=0,It=[],Ct=[],Mt=o(u=>{if(!u)return;let Z=[];u.budgetGlobal instanceof WebAssembly.Global&&Z.push(u.budgetGlobal);let g=u.exports?u.exports.__hwjs_budget:void 0;g instanceof WebAssembly.Global&&Z.push(g);for(let G of Z){try{G.value=dl|0}catch{continue}It.push(G)}},"armModuleBudget"),At=o(u=>{for(let Z of It)try{Z.value=u|0}catch{}},"setModuleBudgets"),q=o((u,Z)=>qh(u,Z,()=>$h(It,C,bc)),"driveImport"),_=!1,D=o(u=>{if(!Q)return;let Z=(Q.instance??Q).exports.__tls_base;if(!(Z instanceof WebAssembly.Global))throw new Error("hwjs-libc: libc.so does not export the mutable __tls_base global the S2 \xA73.3 dual-write contract requires (producer must link --export=__tls_base; never-silent).");Z.value=u|0},"setLibcTlsBase"),ue=!1,x=!1,ie=!1,ee=!1,P=!1,E=!1,J=o(u=>!!n||t.mode==="thread"&&(t.userLane|0)>0&&x&&ie||(u|0)===pb&&ee&&x&&ie,"coopParkCapableFor"),re=o(u=>J(u)&&(ee||yc.has(u|0)),"blockParkGoesToGuest"),Xe=null,Ae=!1,Ve=!1,me=null,je=0;function de(){if(!me)return;let u=me;if((Atomics.load(ct(),u.stwIdx)|0)!==0)try{e({kind:"dmesg",level:7,text:`hwjs-fork-stw pid=${s[ce.PID]|0} lane=${u.lane}: in-syscall HOLD entered (gen=${Atomics.load(ct(),u.stwIdx)|0})`})}catch{}let Z=!1,g=0;for(;;){let G=Atomics.load(ct(),u.stwIdx)|0;if(G===0)break;if(Z||(Z=!0,g=Date.now()),Atomics.store(ct(),u.ackIdx,G),Atomics.wait(ct(),u.stwIdx,G,250),Date.now()-g>1e4){g=Date.now();let S=`hwjs-fork-stw pid=${s[ce.PID]|0} lane=${u.lane}: held at an in-syscall quiesce point for >10s under generation ${Atomics.load(ct(),u.stwIdx)|0} \u2014 the forking lane's servicer has not released; still holding (loud witness, never a silent wedge)`;try{e({kind:"dmesg",level:3,text:S})}catch{}try{console.error(S)}catch{}}}Z&&Atomics.store(ct(),u.ackIdx,0)}o(de,"stwHoldSyncIfRequested");let ve=0,A=1,xe=2,Oe=3,it=4,Zt=5,Xt=1e5,kt=new Map,Ot=1,gt=[],at=null,un=null,xn=null,zn=new Map;function jn(u){try{if(kt.size>0&&Kt)try{e({kind:"dmesg",level:7,text:`hwjs-70 pid=${t.pid} RELEASE(${u}): dropping ${kt.size} dlopen handle(s) + per-process dlopen state at process end`})}catch{}kt.clear(),gt.length=0,un=null,xn=null,zn=new Map,at=null,C=null,Ie=null,B=null,ae=null,Ce=null}catch{}}o(jn,"releaseProcessRunState");let jt=!1,Qs=0,_n=0,Cs=o((u,Z)=>{let G=(Fe()[u>>>2]>>>0)-(u+8>>>0)|0;return G>_n&&(_n=G>>>0),G>(Z-8)*3>>2&&e({kind:"dmesg",level:4,text:`wasm32 D1-BASH.c: Asyncify continuation high-water ${G}B of ${Z-8}B usable (>=75%) \u2014 deepen guard / resize buffer`}),G>>>0},"noteAsyncifyHighWater"),Zs=!1,Et=null,le=0,Gt=null,Re=null,Rt=0,rn=null,On=jZ({getExports:o(()=>Ze.exports,"getExports"),getLane:o(()=>ft,"getLane"),post:e}),gs=o(()=>On.phase.phase!=="idle"||Bn.phase!=="idle","execWindowOpen"),Is=o((u,Z)=>On.load(u,Z),"execLoadKernelChunked"),Es=Vb(ey),mr=Vb(ty),mn=0,w=!1,V="",z=4096,se=1<<20;function Ue(u,Z){let g=u>>>0;if(g===0)return[];let G=t.memory.buffer,S=new Uint8Array(G),Y=new DataView(G),v=[],L=g;for(;;){if(v.length>z)throw new Error(`d1-fork-exec: ${Z} vector exceeds ${z} entries (no NULL terminator? ptr=0x${g.toString(16)}) \u2014 refusing (never-silent)`);if(L+4>S.length)throw new Error(`d1-fork-exec: ${Z} vector pointer 0x${L.toString(16)} out of bounds (mem ${S.length}B) \u2014 malformed vector, refusing`);let j=Y.getUint32(L,!0)>>>0;if(L+=4,j===0)break;if(j>=S.length)throw new Error(`d1-fork-exec: ${Z}[${v.length}] string pointer 0x${j.toString(16)} out of bounds (mem ${S.length}B) \u2014 refusing`);let T=j,fe=Math.min(S.length,j+se);for(;T=fe&&(T>=S.length||S[T]!==0))throw new Error(`d1-fork-exec: ${Z}[${v.length}] string at 0x${j.toString(16)} unterminated within ${se}B \u2014 refusing`);v.push(wi(S.subarray(j,T)))}return v}o(Ue,"decodeUserStringVector");let Ke=!1,nt=!1,Bt=0,Nt=0,St=0;function Nn(){let u=[],Z=[];for(let[G,S]of kt){if(S&&S.mainScope){Z.push(G>>>0);continue}!S||!S.bytes||u.push({cookie:G>>>0,moduleId:S.moduleId|0,memoryBase:S.memoryBase>>>0,tableBase:S.tableBase>>>0,tableSize:S.handle&&S.handle.dylink?S.handle.dylink.tableSize>>>0:0,appended:S.handle&&typeof S.handle.tableEntries=="function"?S.handle.tableEntries():[],path:S.path||"",bytes:S.bytes,...S.internal?{internal:!0,name:S.name,digest:S.digest,...S.module?{module:S.module}:{}}:{},...S.boundByDependent?{boundByDependent:!0}:{},live:S.census?S.census.live>>>0:0,poisoned:S.census?!!S.census.poisoned:!1,xmodRecs:S.xmodRecs?[...S.xmodRecs]:[],...sc(S.handle,S.tlsSlots)})}u.sort((G,S)=>G.cookie-S.cookie);let g=xn instanceof Map?[...xn]:[];return u.length||gt.length||Z.length||g.length||B||$||_e.length||zn.size?{replay:u,mainScope:Z,mainScopeNames:g,fpcastRecs:[...zn],deadRanges:gt.map(G=>({tableBase:G.tableBase>>>0,tableSize:G.tableSize>>>0,appended:Array.isArray(G.appended)?[...G.appended]:[],path:G.path||"",moduleId:G.moduleId|0})),gotFunc:un instanceof Map?[...un]:[],nextCookie:Ot>>>0,tableLen:at instanceof WebAssembly.Table?at.length>>>0:0,...B?{hwjsRt:{...B}}:{},...$?{libcSo:{...$}}:{},..._e.length?{neededLibs:_e.map(G=>({...G,...sc((pe.find(S=>S.index===G.index)||{}).handle,G.tlsSlots)}))}:{}}:null}o(Nn,"buildDlopenForkRecord");async function $t(u){Atomics.store(s,ce.NR,k|0),Atomics.store(s,ce.STATE,tl);let Z=(()=>{if(Q){let L=(Q.instance??Q).exports.__tls_base;if(L instanceof WebAssembly.Global)return L.value>>>0}return C&&typeof C.__wasm32_get_tls_base=="function"?C.__wasm32_get_tls_base()>>>0:0})(),g=u&&typeof u=="object"?u:null,G=g&&C&&typeof C.__wasm32_get_stack_pointer=="function"?C.__wasm32_get_stack_pointer()>>>0:0,S=Nn(),Y=[...ts];for(e({kind:"fork",pid:s[ce.PID]|0,tlsBase:Z,...je?{userLane:je|0}:{},...Y.length?{lowFdRoutes:Y}:{},...S?{dlopenFork:S}:{},...g?{parentSp:G,forkHandle:g.handle>>>0,forkOwner:g.owner>>>0}:{}});Atomics.load(s,ce.STATE)!==Uo;){let L=Atomics.waitAsync(s,ce.STATE,tl,5e3);if(L.async)try{await L.value}catch{}}let v=s[ce.RET_LO]|0;return Atomics.store(s,ce.STATE,Gi),v}o($t,"requestForkChild");let ns=t.mode==="migrate-resume"&&t.mig instanceof SharedArrayBuffer?new Int32Array(t.mig):null,ln=o(()=>ns?Atomics.compareExchange(ns,0,Ao,al)===Ao?(Atomics.notify(ns,0),!0):!1:!0,"migrateCommit");async function Rs(u){let Z=t.cpuId|0,g=s[ce.PID]|0,G=new SharedArrayBuffer(16),S=new Int32Array(G);Atomics.store(S,0,Ic),Atomics.store(S,1,u|0);let Y=(()=>{if(Q){let W=(Q.instance??Q).exports.__tls_base;if(W instanceof WebAssembly.Global)return W.value>>>0}return C&&typeof C.__wasm32_get_tls_base=="function"?C.__wasm32_get_tls_base()>>>0:0})(),v=C&&typeof C.__wasm32_get_stack_pointer=="function"?C.__wasm32_get_stack_pointer()>>>0:0,L=Ze&&typeof Ze.exports.__hwjs_task_frames=="function"?Ze.exports.__hwjs_task_frames()>>>0:0;e({kind:"migrate",pid:g,srcCpu:Z,destCpu:u|0,mig:G,taskAddr:He>>>0,userLane:je|0,tlsBase:Y,sp:v,frames:L,lowFdRoutes:[...ts],...(()=>{let W=Nn();return W?{dlopenFork:W}:{}})()});let j=Date.now();for(;;){let W=Atomics.load(S,0)|0;if(W===al||W===Gc)break;let Pe=j+(W===Ao?yb:Zb)-Date.now();if(Pe<=0){_b(S,W===Ao?gb:Gb);break}let bt=Atomics.waitAsync(S,0,W,Pe);if(bt.async)try{await bt.value}catch{}}if((Atomics.load(S,0)|0)===al){let W=-1;Ze&&typeof Ze.exports.__hwjs_frame_migrate_lane=="function"?(W=Ze.exports.__hwjs_frame_migrate_lane(He>>>0,Z|0,u|0)|0,W<0&&e({kind:"user-report",pid:g,message:`hwjs-migrate pid=${g}: arena retag ${Z}->${u} was refused (bad lane index) \u2014 this task's live kernel frames still carry the source lane's tag, so their teardown WILL trip the cross-lane free guard (loud, attributed)`})):e({kind:"user-report",pid:g,message:`hwjs-migrate pid=${g}: this vmlinux exports no __hwjs_frame_migrate_lane \u2014 the migration proceeds, but the task's live kernel frames keep the source lane's tag and their teardown will trip the cross-lane free guard (stale kernel; loud, attributed)`}),Mn(e,`MIGRATE-OUT cpu=${Z} tid=${t.tid} pid=${g} -> cpu=${u} lane=${je|0} taskFrames=${L} retagged=${W}`);try{e({kind:"dmesg",level:6,text:`hwjs-migrate pid=${g}: arena retag cpu=${Z}->${u} moved ${W} live chunk(s) (task frame balance ${L})`})}catch{}return!0}let T=Atomics.load(S,2)|0;if(T===Ib&&Ze&&typeof Ze.exports.__wasm32_migrate_refuse=="function")try{Ze.exports.__wasm32_migrate_refuse()}catch{}let fe=T===gb?`a lane CLAIMED the task and did not commit within ${yb} ms \u2014 it stalled or died inside the commit window`:T===Ib?"no live pool Worker holds that cpu":T===Gb?`no lane claimed the offer within ${Zb} ms \u2014 the destination lane is starved, or nothing on this machine services migration requests at all`:T===Wc?"the destination refused to bind the task":T===kZ?"the host refused the placement":`abort code ${T}`,ge=`hwjs-migrate pid=${g} cpu=${Z}: migration to cpu=${u} REFUSED \u2014 ${fe}. The task was never released and keeps running here; sched_setaffinity will answer -EAGAIN once its attempt bound is spent (loud, attributed, guest-survivable).`;try{e({kind:"dmesg",level:3,text:ge})}catch{}try{e({kind:"user-report",pid:g,message:ge})}catch{}return!1}o(Rs,"requestMigrate");function _s(u){let Z=Math.floor(t.memory.buffer.byteLength/65536);if(Z>=u)return Z;if(kc>0&&u>=kc&&fc>0)throw fc--,new Error(`hardwarejs#7 TEST INJECTION: simulated commit refusal for grow(+${u-Z}) (${fc} injected failure(s) left in this Worker realm)`);return t.memory.grow(u-Z),u}o(_s,"tryGrowUserMemoryTo");function ro(u){let g=new SharedArrayBuffer(32),G=new Int32Array(g);try{e({kind:"usermem-reclaim",pid:t.pid,needPages:u|0,sab:g})}catch{return null}let S=Date.now()+5e3;for(;Atomics.load(G,0)===0&&Date.now()0))return;let Z=new Int32Array(new SharedArrayBuffer(4));Atomics.wait(Z,0,0,u)}o(io,"settleWaitMs");function si(u,Z){let g;try{g=Hh(u)}catch(Ht){return e({kind:"user-report",pid:t.pid,message:`hardwarejs#6 ${Z}: cannot read the exec image's declared memory-import minimum (${Ht instanceof Error?Ht.message:String(Ht)}) \u2014 refusing exec with -ENOEXEC (never-silent)`}),-8}if(g===null)return 0;let G=Math.floor(t.memory.buffer.byteLength/65536);if(G>=g)return 0;let S=o(Ht=>(Ht*65536/(1024*1024)).toFixed(1),"mib"),Y=null;try{_s(g)}catch(Ht){Y=Ht}if(Y===null){try{e({kind:"dmesg",level:6,text:`hwjs exec pid=${s[ce.PID]|0} ${Z}: grew user_memory ${G} -> ${g} pages for the exec image's declared minimum (hardwarejs#6)`})}catch{}return 0}let v=null;try{if(typeof t.memory.type=="function"){let Ht=t.memory.type();Ht&&typeof Ht.maximum=="number"&&(v=Ht.maximum>>>0)}}catch{}let L=v!==null&&g>v,j=null,T=!1,fe=null,ge=0,W=0;if(!_Z&&!L){T=!0;for(let Ht=0;Ht ${g} pages (hardwarejs#7 rescue)`})}catch{}return 0}}let he=v!==null?v:j&&j.userMaxPages>0?j.userMaxPages:null,Pe=v!==null?"this Memory\u2019s declared maximum":"the machine default userMaxBytes",bt=he!==null?g>he?`the declared minimum EXCEEDS ${Pe} of ${he} pages (${S(he)} MiB) \u2014 raising userMaxBytes is the only remedy for THIS image`:`the userMaxBytes ceiling is NOT the limiting factor (${g} <= ${he} pages) \u2014 the engine refused to commit the pages`:`the Memory's maximum is not introspectable in this engine; if ${g} pages exceeds userMaxBytes that is the cause, otherwise the engine refused to commit the pages`,$e=T?j===null?`host reclaim was requested (${ge} round(s)) but never answered within the 5s/round cap (no kernelSpawnHandler route?); the blind retries also failed (${fe instanceof Error?fe.message:String(fe)})`:`host reclaim ran ${ge} round(s) with settle waits (recycled ${W} idle pool Worker(s) total; ledger: ${j.liveCount} live process SAB(s) ~${S(j.livePages)} MiB committed, ${j.zombieCount} exited-but-uncollected SAB(s) ~${S(j.zombiePages)} MiB awaiting GC, kernel SAB ${S(j.kernelPages)} MiB eagerly committed) and the last retry still failed (${fe instanceof Error?fe.message:String(fe)})`:L?"reclaim-retry skipped (pointless below an exceeded ceiling)":"reclaim-retry DISABLED (HWJS_NO_RECLAIM_RETRY)";return e({kind:"user-report",pid:t.pid,message:`hardwarejs#7 ${Z}: exec image declares a ${g}-page (${S(g)} MiB) user_memory minimum but this process's Memory holds ${G} pages (${S(G)} MiB) and grow(+${g-G}) was refused (${Y instanceof Error?Y.message:String(Y)}). ${bt}; ${$e}. Failing execve with -ENOMEM (never-silent).`}),-12}o(si,"ensureUserMemoryFitsImage");function ri(){let u=Ze&&Ze.exports;if(!u||typeof u.wasm32_user_exec_shebang_argc!="function")return null;let Z=u.wasm32_user_exec_shebang_argc()>>>0;if(Z===0)return null;let g=u.wasm32_user_exec_shebang_addr()>>>0,G=u.wasm32_user_exec_shebang_size()>>>0;if(g===0||G===0)throw new Error(`#75 shebang: kernel reports argc=${Z} but addr=0x${g.toString(16)} size=${G} \u2014 kernel/host argv-prefix contract broken (never-silent)`);let S=new Uint8Array(G);S.set(new Uint8Array(t.kernelMemoryWasm.buffer,g,G));let Y=[],v=0;for(let L=0;LJSON.stringify(g)).join(",")}]`})}catch{}}o(Ur,"applyExecShebangPrefix");function Mr(u,Z,g,G,S,Y,v=!1){let L=Ze?Ze.exports:null;if(S.v!==!1&&ft&&L&&typeof L.wasm_syscall=="function")for(;;){let j;try{j=ft.driveWouldBlock(`wasm_syscall:${Z}`,g,Y)}catch(T){throw Y.h=0,Y.owner=0,T}if(j.wouldBlock){if(S.v=!0,v)return an;continue}if(j.value!==-38)return S.v=!0,j.value|0;if(S.v===null){S.v=!1;try{e({kind:"dmesg",level:6,text:`hwjs-${u}: this vmlinux answers no ${Z}; driving ${u} through the bare export, which holds the kernel lane across the whole file and gets no park preservation. Never-silent.`})}catch{}break}return-38}return G()|0}o(Mr,"driveWholeFileRead");let Wa={v:null},Bi={v:null},oo={h:0,owner:0},Lr={h:0,owner:0},ii={name:null},Ds=null;function ao(u,Z,g=!1){let G=$d(u);if(!G||G.needed.length===0)return;let S=ii.name;if(S===null){let Ln=G.needed.filter(Ns=>!rs.has(Cr(Ns)));if(Ln.length===0)return;S=Ln[0]}let Y=G.needed.indexOf(S),v=Cr(S),L=Ze?Ze.exports:null;if(!L||typeof L.wasm32_user_libc_stage!="function"||!t.kernelMemoryWasm){try{e({kind:"user-report",pid:t.pid,message:`hwjs-libc: image needs libc.so.${v.slice(0,16)}\u2026 but this kernel exports no wasm32_user_libc_stage (a vmlinux without the libc-stage ops) \u2014 the exec preamble will refuse the image (never-silent) [${Z}]`})}catch{}return}let j=typeof L.wasm32_user_needed_stage=="function";if(!j&&Y>0){try{e({kind:"user-report",pid:t.pid,message:`hwjs-libc: the image needs ${S.slice(0,24)}\u2026 (needed entry ${Y}) but this kernel exports no wasm32_user_needed_stage \u2014 a vmlinux without the needed-graph ops can stage entry 0 only; the exec preamble will refuse the image (never-silent) [${Z}]`})}catch{}return}let T=j?wZ:WZ,fe=j?"wasm32_user_needed_stage":"wasm32_user_libc_stage",ge=o(()=>j?L.wasm32_user_needed_stage(Math.max(Y,0)>>>0,1)|0:L.wasm32_user_libc_stage(1)|0,"stageCall"),W;try{W=Mr("libc-stage",T,()=>j?L.wasm_syscall(T,Math.max(Y,0)>>>0,1,0,0,0,0)|0:L.wasm_syscall(T,1,0,0,0,0,0)|0,()=>ft?ft.bracket(fe,ge):ge(),Wa,oo,g)|0}catch(Ln){throw ii.name=null,Ln}if(ii.name=W===an||W===Eb?S:null,W===an)return an;if(W<0)throw new Error(`hwjs-libc: kernel NEEDED_STAGE for ${S.slice(0,24)}\u2026 (entry ${Y}) failed rc=${W} (${Z}) \u2014 not found on the needed search path (/lib, /usr/lib) or over the staging ceiling (never-silent).`);if(W!==2)throw new Error(`hwjs-libc: kernel NEEDED_STAGE(${Y}, force=1) returned ${W}, want 2 (staged) \u2014 kernel/host protocol skew (${Z}; never-silent).`);let he=Mo(L,t.kernelMemoryWasm.buffer,"wasm32_user_libc",`staged ${S.slice(0,24)}\u2026 (${Z})`,!0),Pe=he.length,bt=L.wasm32_user_libc_digest_addr()>>>0,$e=new Uint8Array(64);$e.set(new Uint8Array(t.kernelMemoryWasm.buffer,bt,64));let Ht=wi($e),Sn=null;if(typeof L.wasm32_user_libc_name_addr=="function"){let Ln=L.wasm32_user_libc_name_addr()>>>0;if(Ln){let Ns=new Uint8Array(t.kernelMemoryWasm.buffer),ms=Ln;for(;ms(L.wasm32_user_libc_release(),0),"releaseCall");if(ft?ft.bracket("wasm32_user_libc_release",yn):yn(),Ht!==v)throw new Error(`hwjs-libc: kernel staged digest ${Ht.slice(0,16)}\u2026 but needed entry ${Y} (${S.slice(0,24)}\u2026) wants ${v.slice(0,16)}\u2026 \u2014 needed-list parser skew between kernel and host (never-silent).`);if(Sn!==null&&Sn!==S)throw new Error(`hwjs-libc: kernel staged ${JSON.stringify(Sn.slice(0,32))} for needed index ${Y}, but the host's entry ${Y} is ${JSON.stringify(S.slice(0,32))} \u2014 the two parsers disagree about what this index names (never-silent).`);if(rs.has(v)){typeof he.buffer.transfer=="function"&&he.buffer.transfer(0);try{e({kind:"dmesg",level:6,text:`hwjs-libc: ${S.slice(0,24)}\u2026 (needed entry ${Y}) reached the store while this task's own read of it was parked; the read was finished and released, and its ${Pe}B dropped (${Z})`})}catch{}return ao(u,Z,g)}let Gs=Ui(he);if(Gs!==v)throw new Error(`hwjs-libc: CONTENT SKEW \u2014 ${S.slice(0,24)}\u2026 on the needed search path hashes to ${Gs.slice(0,16)}\u2026 (${Pe}B); the digest-qualified name lies about its content. Refusing delivery (never-silent).`);let bn=ki(he,v),zt=Qh(he,v);typeof he.buffer.transfer=="function"&&he.buffer.transfer(0),ul([{digest:v,bytes:zt,module:bn.module}],e);try{e({kind:"libc-so-staged",digest:v,bytes:zt,module:bn.module})}catch{}try{e({kind:"dmesg",level:6,text:`hwjs-libc: staged ${S.slice(0,24)}\u2026 (needed entry ${Y}, ${Pe}B, compile ${bn.cached?"HIT":"FRESH"}, ${zt.length}B kept) via kernel ${j?"NEEDED_STAGE":"LIBC_STAGE"} (${Z}; once per boot per digest)`})}catch{}return ao(u,Z,g)}o(ao,"serviceLibcStageForExecImage");async function Pr(u,Z){if(Ze&&He!==0&&typeof Ze.exports.wasm32_user_exec_load=="function"&&t.kernelMemoryWasm)try{if(Kt)try{e({kind:"dmesg",level:6,text:`EXEC-LOAD-DIAG: calling wasm32_user_exec_load path="${u}"`})}catch{}let g=await Po({load:o(()=>Is(Z,!0),"load"),yieldTurn:o(()=>Es("EXEC-LOAD park service"),"yieldTurn"),onYield:o(()=>{Yu("exec park service",u),Dt&&Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=EXEC-LOAD-park site=exec-park-service via=wake-word`)},"onYield")});if(Kt)try{e({kind:"dmesg",level:6,text:`EXEC-LOAD-DIAG: wasm32_user_exec_load RETURNED rc=${g|0}`})}catch{}if(Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} EXEC-LOAD rc=${g|0}`})}catch{}if(g<0)return{ok:!1,errno:g};let G=Mo(Ze.exports,t.kernelMemoryWasm.buffer,"wasm32_user_exec","staged exec image (park service)");if(Kt)try{e({kind:"dmesg",level:6,text:`EXEC-LOAD-DIAG: staged image ${G.length}B in ${Ze.exports.wasm32_user_exec_nsegs()>>>0} segment(s); re-instantiating`})}catch{}try{await Po({load:o(()=>ao(G,"exec-load (park service)",!0)===an?an:0,"load"),yieldTurn:o(()=>Es("LIBC-STAGE park service"),"yieldTurn"),onYield:o(()=>{Dt&&Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=LIBC-STAGE-park site=exec-park-service via=wake-word`)},"onYield")})}catch(v){try{e({kind:"user-report",pid:t.pid,message:"hwjs-libc exec-load refusal (clean POSIX exec failure): "+(v instanceof Error?v.message:String(v))})}catch{}return Promise.resolve({ok:!1,errno:-14})}let S=ri(),Y=o(()=>(Ze.exports.wasm32_user_exec_release(),0),"releaseCall");if(Kt)try{e({kind:"dmesg",level:6,text:"EXEC-LOAD-DIAG: pre-release"})}catch{}if(ft?ft.bracket("wasm32_user_exec_release",Y):Y(),Kt)try{e({kind:"dmesg",level:6,text:`EXEC-LOAD-DIAG: post-release; returning ${G.length}B to EXEC service`})}catch{}{let v=si(G,"exec-load (park service)");if(v<0)return Promise.resolve({ok:!1,errno:v})}return Ti(),Ur(S),Promise.resolve({ok:!0,wasmBytes:G})}catch(g){return f("wasm32_user_exec_load (park service)"),e({kind:"error",pid:t.pid,message:"D1-FORK exec-in-place: kernel-routed wasm32_user_exec_load trapped: "+(g instanceof Error?g.message:String(g))+(g instanceof Error&&g.stack?` EXEC-LOAD-STACK: `+g.stack.split(` `).slice(0,12).join(" | "):"")}),Promise.resolve({ok:!1,errno:-14})}return new Promise(g=>{xZ(g),e({kind:"execve",pid:s[ce.PID]|0,path:u})})}o(Pr,"requestExecImage");let Bn={phase:"idle",pathPtr:0,bytes:null};function Ti(){let u=Ze?Ze.exports:null;if(!u||typeof u.wasm32_user_exec_commit!="function")return;let Z=o(()=>(u.wasm32_user_exec_commit(),0),"commitCall");ft?ft.bracket("wasm32_user_exec_commit",Z):Z()}o(Ti,"execCommit");function $s(){Bn.phase="idle",Bn.pathPtr=0,Bn.bytes=null}o($s,"execStageReset");function Yi(u){if(Bn.phase!=="staged")return!1;if(Bn.pathPtr===u>>>0)return!0;let Z=Bn.pathPtr;throw $s(),new Error(`loadExecImageKernelSync: an exec for pathPtr=0x${(u>>>0).toString(16)} entered while the image for 0x${Z.toString(16)} is STAGED and unreleased (its libc stage is mid-flight) \u2014 refusing to abandon a live kernel staging slot (never-silent)`)}o(Yi,"execStageResuming");function lo(){if(Bn.phase!=="staged")return;let u=Bn.bytes?Bn.bytes.length:0;$s();try{let Z=Ze?Ze.exports:null;if(!Z||typeof Z.wasm32_user_exec_release!="function")return;let g=o(()=>(Z.wasm32_user_exec_release(),0),"releaseCall");ft?ft.bracket("wasm32_user_exec_release",g):g();try{e({kind:"dmesg",level:4,text:`hwjs-exec: pid=${s[ce.PID]|0} terminated with a ${u}B exec image still STAGED (its libc stage never finished) \u2014 released the kernel staging slot on the way out. Never-silent: nothing else would have, and the allocation would have outlived the machine.`})}catch{}}catch{}}o(lo,"execStageDrainOnExit");function co(u,Z=!1){if(!(Ze&&He!==0&&typeof Ze.exports.wasm32_user_exec_load=="function"&&t.kernelMemoryWasm))return{unavailable:!0};try{let g;if(Yi(u))g=Bn.bytes;else{let Y=Is(u,Z)|0;if(Y===an)return{wouldBlock:!0};if(Y<0)return{ok:!1,errno:Y};g=Mo(Ze.exports,t.kernelMemoryWasm.buffer,"wasm32_user_exec","staged exec image (inline)"),Bn.phase="staged",Bn.pathPtr=u>>>0,Bn.bytes=g}try{if(ao(g,"exec-load (inline)",Z)===an)return{wouldBlock:!0}}catch(Y){$s();try{e({kind:"user-report",pid:t.pid,message:"hwjs-libc exec-load refusal (clean POSIX exec failure): "+(Y instanceof Error?Y.message:String(Y))})}catch{}return{ok:!1,errno:-14}}let G=ri(),S=o(()=>(Ze.exports.wasm32_user_exec_release(),0),"releaseCall");ft?ft.bracket("wasm32_user_exec_release",S):S(),$s();{let Y=si(g,"exec-load (inline)");if(Y<0)return{ok:!1,errno:Y}}return Ti(),Ur(G),{ok:!0,wasmBytes:g}}catch(g){return $s(),f("wasm32_user_exec_load (inline)"),e({kind:"error",pid:t.pid,message:"HWJS-B-2 exec: kernel-routed wasm32_user_exec_load trapped: "+(g instanceof Error?g.message:String(g))+(g instanceof Error&&g.stack?` EXEC-LOAD-STACK: `+g.stack.split(` `).slice(0,12).join(" | "):"")}),{ok:!1,errno:-14}}}o(co,"loadExecImageKernelSync");function Js(u,Z=4096){let g=u>>>0;if(g===0)return"";let G=new Uint8Array(t.memory.buffer),S=g,Y=Math.min(G.length,g+Z);for(;S{let G=Js(g>>>0,256)||"",S=`hwjs-budget: DRIVER CONTRACT BREACH in "${Z}" \u2014 the M6 safepoint in ${G}() parked on an expired @__hwjs_budget and the driver RESUMED it without rebinding one. Every following back-edge crossing takes the expiry arm, so the module spends its life in park/resume round trips at loop-iteration granularity while every instrument still reports it preemptible. Refill the budget of EVERY module instance on resume (the handle's budgetGlobal / __hwjs_budget_set), not just the main's. The module traps at the \`unreachable\` immediately after this call \u2014 that trap is in the image and is identical in the static and -shared builds; this report only names the site.`;try{e({kind:"user-report",pid:t.pid,message:S})}catch{}throw new Error(S)}:()=>{let g=`hwjs-budget: UNINITIALIZED BUDGET in "${Z}" \u2014 the module's startup sanity constructor found @__hwjs_budget still at the weak-0 default, i.e. nothing bound this instance's initial safepoint budget BEFORE its constructors ran. A zero budget is correctness-safe (every safepoint parks) but perf-fatal, which is why it is refused rather than tolerated. The loader arms a freshly loaded module's budget before ctors (armModuleBudget); reaching this handler means that arming did not happen for this module. The module traps at the \`unreachable\` immediately after this call \u2014 that trap is in the image and is identical in the static and -shared builds; this report only names the module.`;try{e({kind:"user-report",pid:t.pid,message:g})}catch{}throw new Error(g)}}o(Ar,"makeBudgetLoudHandler");let uo=new Set(["__hwjs_frame_alloc","__hwjs_frame_free","__hwjs_frame_publish","__hwjs_set_parked","__hwjs_clear_parked","__hwjs_take_parked","__hwjs_noreturn_completed","__hwjs_xfer_descend","__hwjs_xfer_park","__hwjs_xfer_return","__hwjs_xfer_take","hwjs_sj_record","hwjs_lj_arm_from","hwjs_lj_match","hwjs_lj_selector","hwjs_lj_value","hwjs_lj_clear","hwjs_lj_unwound","hwjs_trap","hwjs_resume","hwjs_done","hwjs_destroy","__hwjs_lane_id","__hwjs_drive_abi","__hwjs_register_suspends","__hwjs_ds_region_abi_v2","__hwjs_region_alloc","__hwjs_region_save","__hwjs_region_restore","__hwjs_freea","__hwjs_status_park_exit","__hwjs_status_baton","__hwjs_status_clear","__hwjs_status_adopt_top","__hwjs_drive_adopt_parked","__hwjs_status_raise_unwind","__hwjs_status_raise_longjmp","__hwjs_status_sj_register","__hwjs_status_violation","__hwjs_status_longjmp_lost","__hwjs_uncaught_unwinding"]),Rr=new Set(["__hwjs_capsummary_lookup","__hwjs_e8_refuse","__hwjs_fpcast_adapter_lookup","__hwjs_fpcast_target_sig_lookup","__hwjs_register_capsummary","__hwjs_register_fpcast_adapter"]);function mo(u){let Z=Ze?Ze.exports:null;return(g,G,S)=>{if(S!=="function"||g!=="env")return;if(hr.has(G))return(globalThis.process?.env?.HWJS_RED_NO_BUDGET_HANDLER_BIND||"")==="1"?void 0:Ar(G,u||"a dlopen'd module");if(G==="fork"){let L=C&&(C._Fork||C.fork);if(typeof L=="function")return L;throw new Error("hwjs-dlopen: env.fork unresolved \u2014 the dynamic-main exports no musl _Fork/fork PARK LEAF for the loaded module to suspend through. The host cannot synthesize a wasm park leaf from JS (the fork dynamic-main must export + keep its _Fork park leaf).")}if(uo.has(G)||G.startsWith("__hwjs_promise_")){let L=C?C[G]:void 0;if(typeof L=="function")return L;throw new Error(`hwjs-dlopen: env.${G} is a MAIN-owned hwjs runtime op but the main image does not export "${G}" \u2014 refusing the kernel's namesake (cross-address-space misdispatch; the dynamic-main must carry its own hwjs_user_rt op set; never-silent).`)}if(Rr.has(G)){if(hn[G])return hn[G];let L=Z?Z[G]:void 0;if(typeof L=="function")return L;throw new Error(`hwjs-dlopen: env.${G} is a KERNEL-owned registry op but vmlinux does not export "${G}" \u2014 refusing to bind elsewhere (never-silent).`)}if(C&&typeof C[G]=="function")return q(G,C[G]);let Y=zd(G,pe);if(Y)return q(G,Y);let v=zd(G,kt.values());if(v)return q(G,v)}}o(mo,"makeDlopenResolveImport");function oi(){return u=>{let Z=C?C[u]:void 0;if(Z instanceof WebAssembly.Global)return Z.value>>>0;let g=jd(u,pe);if(g!==void 0)return g;let G=jd(u,kt.values());if(G!==void 0)return G}}o(oi,"makeDlopenResolveDataAddress");function ho(u,Z,g){return(G,S,Y)=>{let v=u(G,S,Y);return Y!=="function"||G!=="env"||typeof v!="function"?v:S==="__hwjs_frame_alloc"?L=>{let j=v(L);return(j|0)!==0&&Z.live++,j}:S==="__hwjs_frame_free"?L=>{if(v(L),(L|0)!==0){if(Z.live<=0){Z.poisoned=!0,e({kind:"user-report",pid:t.pid,message:`HWJS-5 M2 dlclose census UNDERFLOW for "${g}": __hwjs_frame_free(0x${(L>>>0).toString(16)}) with live=0 \u2014 the per-module frame census lost an alloc; module POISONED (its dlclose will refuse; never-silent, non-terminal).`});return}Z.live--}}:v}}o(ho,"makeFrameCensusResolveImport");let wa=new Set;function ai(u,Z,g,G,S){if(u=u>>>0,Z=Z>>>0,vZ){let T=[...kt.values()].map(fe=>`${fe.path}@[${fe.tableBase},${fe.tableBase+(fe.handle&&fe.handle.dylink?fe.handle.dylink.tableSize>>>0:0)})recs=${fe.xmodRecs?fe.xmodRecs.size:-1}`).join(" ");e({kind:"dmesg",level:7,text:`hwjs-xmod-consult TRACE sig=0x${u.toString(16)} fp=${Z} mods: ${T}`})}if(G&>.length===0)return 1;let Y=rb(u,Z,gt,kt.values(),T=>zn.get(T>>>0)),v=Y.dead,L=Y.live,j=ob({inDead:!!v,inFootprint:!!L,inElem:Y.inElem,hasRec:Y.hasRec,recOtherSig:Y.recOtherSig,recAny:Y.recAny,regRan:Y.regRan,fromMain:g,fromRt:G,marshal:S});if(j===2){let T=L?`"${L.path}" (moduleId=${L.moduleId})`:"the main image",fe=u+":"+Z+":"+T;if(!wa.has(fe)){wa.add(fe);let ge=zn.get(Z)>>>0;e({kind:"dmesg",level:5,text:`HWJS F173 xmod-consult MARSHAL: table index ${Z} (site_sig=0x${u.toString(16)}) targets ${T}, registered under own sig 0x${ge.toString(16)} \u2014 the site's arm calls it if that is a parameter prefix of the site signature and traps otherwise (issue linux-in-the-browser#186).`})}}return j||(e({kind:"user-report",pid:t.pid,message:v?`HWJS F152 xmod-consult E8-REFUSE (dead-module): sig-compatible open-world dispatch of table index ${Z} (site_sig=0x${u.toString(16)}) targets dlclosed module "${v.path}" (moduleId=${v.moduleId}) \u2014 refusing loudly; the caller traps (never-silent; issue linux-in-the-browser#40).`:`HWJS F152 xmod-consult E8-REFUSE (unregistered-target): sig-compatible open-world dispatch of table index ${Z} (site_sig=0x${u.toString(16)}) targets "${L.path}" (moduleId=${L.moduleId}) but that module has NO live __hwjs_register_fpcast_adapter record for (sig, target) \u2014 its F117 registration ctors under-ran (stripped start / partial registration) or the record's wasm signature is inconsistent with this site \u2014 refusing loudly; the caller traps (never-silent; issue linux-in-the-browser#40).`}),0)}o(ai,"xmodDispatchCheck");function ne(u,Z,g){return(G,S,Y)=>{if(Y==="function"&&G==="env"&&S==="__hwjs_xmod_dispatch_check")return ai;let v=u(G,S,Y);return Y!=="function"||G!=="env"||typeof v!="function"?v:S==="__hwjs_register_fpcast_adapter"?(g&&(g.imported=!0),(L,j,T,fe,ge)=>(Z.add((j>>>0)+":"+(fe>>>0)),v(L,j,T,fe,ge))):v}}o(ne,"makeXmodConsultResolveImport");function Ye(u,Z,g,G,S){if(zn.set(G>>>0,Z>>>0),!il&&u>>>0===FZ)return 1;let Y=Ze?Ze.exports:null,v=Y?Y.__hwjs_register_fpcast_adapter:void 0,L=typeof v=="function"?v(u,Z,g,G,S)|0:0;if(il){let j="n/a";try{let T=Y?Y.__hwjs_fpcast_target_sig_lookup:void 0;typeof T=="function"&&(j="0x"+(T(G)>>>0).toString(16))}catch{}try{e({kind:"dmesg",level:7,text:`FPCAST-REGISTER(scoped) sig=0x${(Z>>>0).toString(16)} fid=0x${(g>>>0).toString(16)} tgt=${G>>>0} mid=${S>>>0} census=${zn.size} kernel-rc=${L} kernel-readback=${j}`})}catch{}}return L}o(Ye,"fpcastRegisterScoped");function Wt(u,Z){let g=zn.get(Z>>>0),G=g!==void 0&&g===u>>>0?Z|0:0;if(il)try{e({kind:"dmesg",level:7,text:`FPCAST-LOOKUP(scoped) site_sig=0x${(u>>>0).toString(16)} tgt=${Z>>>0} own=${g===void 0?"MISS":"0x"+g.toString(16)} -> ${G}`})}catch{}return G}o(Wt,"fpcastAdapterLookupScoped");function qt(u){let Z=zn.get(u>>>0),g=Z===void 0?0:Z|0;if(il)try{e({kind:"dmesg",level:7,text:`FPCAST-TSIG(scoped) tgt=${u>>>0} -> ${Z===void 0?"MISS(0)":"0x"+Z.toString(16)}`})}catch{}return g}o(qt,"fpcastTargetSigLookupScoped");let hn={__hwjs_register_fpcast_adapter:Ye,__hwjs_fpcast_adapter_lookup:Wt,__hwjs_fpcast_target_sig_lookup:qt};function qs(u){if(!u||typeof u!="object")return;let Z=(globalThis.process?.env?.HWJS_FORK_REPLAY_APPEND_ONLY||"")==="1",g=Array.isArray(u.replay)?u.replay:[],G=Array.isArray(u.deadRanges)?u.deadRanges:[],S=Array.isArray(u.mainScope)?u.mainScope:[],Y=Array.isArray(u.mainScopeNames)?u.mainScopeNames:[];if(g.length===0&&G.length===0&&S.length===0&&Y.length===0)return;let v=at;if(!(v instanceof WebAssembly.Table))throw new Error("HWJS-5 fork\xD7dlopen: child has a dlopenFork payload but no shared table \u2014 the fork-resume main image is not a dynamic-main (never-silent).");let L=v.length>>>0;if(!Z){let T=u.tableLen>>>0||0;if(TL)try{v.grow(T-L)}catch(fe){throw new Error(`HWJS-5 fork\xD7dlopen: could not grow the child table ${L} -> ${T} (max reached?): `+(fe instanceof Error?fe.message:String(fe)))}for(let fe of G)gt.push({tableBase:fe.tableBase>>>0,tableSize:fe.tableSize>>>0,appended:Array.isArray(fe.appended)?[...fe.appended]:[],path:fe.path||"",moduleId:fe.moduleId|0});if(un instanceof Map)for(let[fe,ge]of Array.isArray(u.gotFunc)?u.gotFunc:[])un.set(String(fe),ge>>>0)}let j=0;for(let T of g){let fe={live:T.live>>>0||0,poisoned:!!T.poisoned},ge=new Set(Array.isArray(T.xmodRecs)?T.xmodRecs:[]),W={imported:!1},he=ne(ho(mo(T.path||""),fe,T.path||""),ge,W),Pe=T.tableBase>>>0;if(Z){if(v.length>>>0!==Pe)throw new Error(`HWJS-5 fork\xD7dlopen: child table length ${v.length} != parent tableBase ${Pe} for "${T.path}" (cookie=${T.cookie}) \u2014 the child's table layout diverged from the parent (replay order / main elem mismatch; never-silent, the cross-module identities would not match).`)}else if(Pe{let Ht=T.module?Fb(T.module,T.digest):ki($e);try{e({kind:"dmesg",level:7,text:`HWJS70-SOCACHE pid=${s[ce.PID]|0} ${Ht.cached?"HIT ":"COMPILE"} path="${T.path||""}" (fork-replay) len=${$e.length} key=${Ht.key} `+gc()})}catch{}return Ht.module},"compileModule"),fixedMemoryBase:T.memoryBase>>>0,sideTls:nc(t.mode,T,t.mainTlsSlot),...Z?{}:{fixedTableBase:Pe,seedSymbolIndices:Array.isArray(T.appended)?T.appended:[]},moduleId:T.moduleId|0,soPath:T.path||"",resolveImport:he,bindOwnDefinitions:!0,resolveDataAddress:oi(),gotFuncIndex:un,skipDataRelocs:!0,stackPointer:C?C.__stack_pointer:void 0,mainDriveAbi:C&&typeof C.__hwjs_drive_abi=="function"?C.__hwjs_drive_abi()|0:void 0,mainLaneAddressed:$?!!$.laneAddressed:we,statusChannelAddr:C&&C.__hwjs_status_channel instanceof WebAssembly.Global?C.__hwjs_status_channel.value+(je|0)*32>>>0:void 0,parkImport:o(()=>{},"parkImport")});if(Mt(bt),bt.tableBase>>>0!==Pe)throw new Error(`HWJS-5 fork\xD7dlopen: replayed "${T.path}" (cookie=${T.cookie}) landed at tableBase ${bt.tableBase}, parent recorded ${Pe} (never-silent, the cross-module identities would not match).`);if(kt.set(T.cookie>>>0,{handle:bt,moduleId:T.moduleId|0,bytes:T.bytes,path:T.path||"",memoryBase:bt.memoryBase>>>0,tableBase:bt.tableBase>>>0,census:fe,xmodRecs:ge,xmodRegistrar:W,tlsSlots:T.tlsSlots>>>0,...T.internal?{internal:!0,name:T.name,digest:T.digest,...T.module?{module:T.module}:{}}:{},...T.boundByDependent?{boundByDependent:!0}:{}}),T.cookie>>>0>j&&(j=T.cookie>>>0),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} FORK-DLOPEN-REPLAY "${T.path}" cookie=${T.cookie} moduleId=${T.moduleId} memBase=0x${(bt.memoryBase>>>0).toString(16)} tableBase=${bt.tableBase}`})}catch{}}for(let T of S)kt.set(T>>>0,br()),T>>>0>j&&(j=T>>>0);for(let[T,fe]of Y){let ge=C?C[T]:void 0;if(typeof ge!="function"||fe>>>0>=v.length)throw new Error(`HWJS-5 fork\xD7dlopen: dlsym(main, "${T}") slot ${fe} cannot be re-bound in the child (never-silent)`);let W=v.get(fe>>>0);if(W===null)v.set(fe>>>0,ge);else if(W!==ge)throw new Error(`HWJS-5 fork\xD7dlopen: dlsym(main, "${T}") slot ${fe} holds a different function in the child than in the parent (never-silent)`);xn instanceof Map&&xn.set(String(T),fe>>>0)}if(j>=Ot&&(Ot=j+1),!Z){u.nextCookie>>>0>Ot&&(Ot=u.nextCookie>>>0);let T=u.tableLen>>>0;if(v.length>>>0!==T)throw new Error(`HWJS-5 fork\xD7dlopen: child table length ${v.length} != parent fork-time length ${T} after placement replay \u2014 an append escaped the recorded placements (never-silent).`);try{e({kind:"dmesg",level:7,text:`hwjs-fork-dlopen-replay pid=${s[ce.PID]|0} placed=${g.length} deadRanges=${G.length} tableLen=${v.length} nextCookie=${Ot}`})}catch{}}}o(qs,"replayForkDlopens");function br(){return{mainScope:!0,handle:{dylink:{tableSize:0},dlsym:o(u=>bo(u),"dlsym"),tableIndices:o(()=>[],"tableIndices"),tableEntries:o(()=>[],"tableEntries"),unload:o(()=>{},"unload")},moduleId:0,bytes:null,path:"",memoryBase:0,tableBase:0,census:{live:0,poisoned:!1},xmodRecs:new Set,tlsSlots:0}}o(br,"makeMainScopeEntry");function li(){let u=Ot++;if(kt.set(u>>>0,br()),ue=!0,Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DLOPEN-MAIN-SCOPE cookie=${u}`})}catch{}return u>>>0}o(li,"openMainScope");function Sa(u){let Z=Ot++,g=br();if(g.path=u,g.handle.dlsym=G=>Q.dlsym(G),kt.set(Z>>>0,g),ue=!0,Kt)try{e({kind:dmesg,level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DLOPEN-RESIDENT-LIBC cookie=${Z} path="${u}"`})}catch{}return Z>>>0}o(Sa,"openResidentLibc");function bo(u){let Z=C?C[u]:void 0;if(typeof Z!="function")return 0;let g=at;if(!(g instanceof WebAssembly.Table)||!(xn instanceof Map)||!(un instanceof Map))return 0;let G=xn.get(u);if(G!==void 0&&G>>0||Ds.path!==Js(u))&&Vr();let S;if(Ds)S=Ds.bytes;else{let L=o(()=>g.wasm32_user_dlopen_load(u>>>0)|0,"loadCall"),j=Mr("dlopen-load",nl,()=>g.wasm_syscall(nl,u>>>0,0,0,0,0,0)|0,()=>ft?ft.bracket("wasm32_user_dlopen_load",L):L(),Bi,Lr,Z)|0;if(j===an)return an;if(j<0)return V=`kernel dlopen staging wasm32_user_dlopen_load("${Js(u)}") returned ${j} (the .so could not be resolved/read from the VFS)`,j;S=Mo(g,t.kernelMemoryWasm.buffer,"wasm32_user_dlopen",`staged .so "${Js(u)}"`);let T=o(()=>(g.wasm32_user_dlopen_release(),0),"releaseCall");ft?ft.bracket("wasm32_user_dlopen_release",T):T()}let Y=Js(u);if(Q&&$&&$.digest&&Ui(S)===$.digest)return Vr(),Sa(Y);let v;try{v=kf(u>>>0,S,Y,Z)}catch(L){throw Vr(),L}if(!Array.isArray(v))return v;for(let L of v){let j=Xu(L.bytes,L.path,{internal:!0,name:L.name,digest:Cr(L.name),...L.module?{module:L.module}:{}});if(j<0)return V=`while loading ${L.name.slice(0,-65)}, needed by "${L.by}": ${V}`,j}return Xu(S,Y,null)}o(ka,"serviceDlopen");function Vr(){let u=Ds;if(Ds=null,u&&u.scratch)try{mi(11,u.scratch,4096,0,0,0,0)}catch{}}o(Vr,"dlopenPendingDrop");function kf(u,Z,g,G){let S=o(T=>{V=`hwjs-dlopen: ${T} (never-silent)`,Vr();try{e({kind:"user-report",pid:t.pid,message:V})}catch{}return-80},"fail"),Y=Ds;if(!Y){let T;try{T=Dd(Z)}catch(fe){return S(`"${g}": ${fe instanceof Error?fe.message:fe}`)}if(T.length===0)return[];Y=Ds={pathPtr:u,path:g,bytes:Z,top:T,queue:T.map(fe=>({name:fe,by:g})),fetched:new Map,scratch:0,cand:0,fetching:null}}for(;Y.queue.length;){let{name:T,by:fe}=Y.queue[0];if(Y.fetched.has(T)){Y.queue.shift();continue}let ge=Xf(T);if(typeof ge=="string")return S(`"${fe}" needs ${T}, but ${ge}`);if(ge){Y.queue.shift();continue}let W=null,he=rs.get(Cr(T));if(Y.fetching!==T&&he&&he.bytes)W={bytes:he.bytes instanceof Uint8Array?he.bytes:new Uint8Array(he.bytes),path:`/usr/lib/${T}`,stored:!0,module:he.module};else{let $e=Rf(Y,T,G);if(Y.fetching=$e===an?T:null,$e===an)return $e;if($e===-2)return S(`"${fe}" needs ${T}, which is in neither /usr/lib nor /lib`);if(typeof $e=="number")return V=`hwjs-dlopen: "${fe}" needs ${T}; reading it returned ${$e} (never-silent)`,Vr(),$e;W=$e}let Pe=W.stored?gi(W.bytes):null;if((Pe?Pe.digest:Ui(W.bytes))!==Cr(T))return S(`"${fe}" needs ${T}, but ${W.path} does not hash to that digest -- a content-addressed library was replaced in place`);let bt;try{bt=Dd(W.bytes)}catch($e){return S(`${W.path}: ${$e instanceof Error?$e.message:$e}`)}Y.fetched.set(T,{name:T,by:fe,bytes:W.bytes,path:W.path,needs:bt,...W.module?{module:W.module}:{}}),Y.queue.shift();for(let $e of bt)Y.queue.push({name:$e,by:W.path})}let v=[],L=new Set,j=o(T=>{if(L.has(T)||!Y.fetched.has(T))return;L.add(T);let fe=Y.fetched.get(T);for(let ge of fe.needs)j(ge);v.push(fe)},"visit");for(let T of Y.top)j(T);return Vr(),v}o(kf,"dlopenNeededClosure");function Xf(u){let Z=Cr(u),g=_o(u);for(let G of _e){if(G.name===u||G.digest===Z)return!0;if(_o(G.name)===g)return`this process loaded ${g} ${G.digest.slice(0,16)}\u2026 as a needed entry of its main, not ${Z.slice(0,16)}\u2026`}for(let G of kt.values())if(!(!G||G.mainScope||!G.bytes)){if(G.name===u)return!0;if(G.name&&_o(G.name)===g)return`this process already loaded ${G.name} for another module`;if(!G.name&&(G.digest===void 0&&(G.digest=Ui(G.bytes)),G.digest===Z))return G.boundByDependent=!0,!0}return!1}o(Xf,"dlopenLibraryPresent");function Rf(u,Z,g){let G=Ze.exports,S=[`/usr/lib/${Z}`,`/lib/${Z}`];if(!u.scratch){let Y=Go(9,0,4096,3,34,-1,0)|0;if(Y<=0)return-12;u.scratch=Y>>>0,u.cand=0,u.scratchFor=""}for(;u.candG.wasm32_user_dlopen_load(v)|0,"loadCall"),j=Mr("dlopen-load",nl,()=>G.wasm_syscall(nl,v,0,0,0,0,0)|0,()=>ft?ft.bracket("wasm32_user_dlopen_load",L):L(),Bi,Lr,g)|0;if(j===an)return j;if(j===-2&&u.cand+1(G.wasm32_user_dlopen_release(),0),"releaseCall");return ft?ft.bracket("wasm32_user_dlopen_release",fe):fe(),u.cand=0,u.scratchFor="",{bytes:T,path:Y}}return u.cand=0,u.scratchFor="",-2}o(Rf,"dlopenFetchLibrary");function Xu(u,Z,g){let G=Ze.exports,S=at,Y=o((yn,Gs)=>{let zt=(globalThis.process?.env?.HWJS_RED_DLOPEN_OOM||"")==="1"?0:Go(9,0,yn|0,3,34,-1,0)|0;if(zt<=0)throw new Error(`hwjs-dlopen: SYS_mmap for the .so data region (${yn}B) returned ${zt} (never-silent OOM)`);return zt>>>0},"allocMemory"),v=typeof G.__hwjs_alloc_module_id=="function"?G.__hwjs_alloc_module_id()|0:0,L={live:0,poisoned:!1},j=new Set,T={imported:!1},fe=ne(ho(mo(Z),L,Z),j,T),ge=globalThis.process?.env?.HWJS_RED_NO_CTORS||"",W=ge==="1"||ge.startsWith("/")&&ge===Z,he=W?Mh(u):u;{let yn=_i(he),Gs=yn&&Array.isArray(yn.needed)?yn.needed.filter(zt=>/^libc\.so\./.test(String(zt))):[];for(let zt of Gs){if(!$)return V=`hwjs-libc: "${Z}" needs ${zt} but this process runs NO shared libc.so \u2014 a shared-libc .so cannot load into a static-libc process (never-silent).`,e({kind:"user-report",pid:t.pid,message:V}),-80;if(zt!==`libc.so.${$.digest}`)return V=`hwjs-libc: DIGEST SKEW \u2014 "${Z}" needs ${String(zt).slice(0,24)}\u2026 but this process loaded libc.so.${$.digest.slice(0,16)}\u2026 (a .so of a different libc generation; PLAN-DYNAMIC-LIBC \xA73.2; never-silent).`,e({kind:"user-report",pid:t.pid,message:V}),-80}let bn=Jo(he);if(bn&&bn.manifestVersion>=2&&bn.suspenderDigestLo64&&bn.suspenderDigestLo64!=="0000000000000000"){let zt=$?$.suspenderDigestLo64:null;if(bn.suspenderDigestLo64!==zt)return V=`hwjs-libc: SUSPENDER-PARTITION DIGEST SKEW \u2014 "${Z}" was linked against partition ${bn.suspenderDigestLo64}\u2026 but this process's libc.so records ${zt??""}\u2026 (PLAN-DYNAMIC-LIBC \xA73.2; never-silent).`,e({kind:"user-report",pid:t.pid,message:V}),-80}if(bn){let zt=!!(bn.flags&&bn.flags.checkEmitting),Ln=$?!!$.checkEmitting:rt;if(zt!==Ln)return V=`hwjs-dlopen: CHECK-EMITTING MISMATCH \u2014 "${Z}" attests check_emitting=${zt?1:0} (hwjs.abi flags bit4) but this process (${$?"libc.so "+$.digest.slice(0,16)+"\u2026":"main image"}) attests check_emitting=${Ln?1:0}. Mixing check-emitting and non-check-emitting modules lets a status-channel throw/longjmp transit an uninstrumented frame SILENTLY (PLAN-CXX-STATUS-CHANNEL \xA77, I3). Rebuild the .so and the process images in lockstep (never-silent).`,e({kind:"user-report",pid:t.pid,message:V}),-80;let Ns=!!(bn.flags&&bn.flags.laneAddressed),ms=$?!!$.laneAddressed:we;if(Ns!==ms)return V=`hwjs-dlopen: LANE-ADDRESSED MISMATCH \u2014 "${Z}" attests lane_addressed=${Ns?1:0} (hwjs.abi flags bit5) but this process (${$?"libc.so "+$.digest.slice(0,16)+"\u2026":"main image"}) attests lane_addressed=${ms?1:0}. Mixing a lane-addressed module with a lane-unaware one lets the lane-unaware side read LANE 0's status word from ANY lane \u2014 silent transit under threads (I3-2; PLAN-THREADS-SINGLE-MEMORY \xA74 step 2). Rebuild the .so and the process images in lockstep (never-silent).`,e({kind:"user-report",pid:t.pid,message:V}),-80}}let Pe=g?rs.get(g.digest):void 0,bt=o(yn=>{let Gs=g&&g.module&&yn===u?Fb(g.module,g.digest):ki(yn,Pe&&Pe.bytes===yn?g.digest:void 0);try{e({kind:"dmesg",level:6,text:`HWJS70-SOCACHE pid=${s[ce.PID]|0} ${Gs.cached?"HIT ":"COMPILE"} path="${Z}" len=${yn.length} key=${Gs.key} `+gc()})}catch{}return Gs.module},"compileModule"),$e,Ht=0;if($e=Li({wasmBytes:he,memory:t.memory,table:S,allocMemory:Y,moduleId:v,soPath:Z,compileModule:bt,resolveImport:fe,bindOwnDefinitions:!0,resolveDataAddress:oi(),gotFuncIndex:un,stackPointer:C?C.__stack_pointer:void 0,mainDriveAbi:C&&typeof C.__hwjs_drive_abi=="function"?C.__hwjs_drive_abi()|0:void 0,mainLaneAddressed:$?!!$.laneAddressed:we,statusChannelAddr:C&&C.__hwjs_status_channel instanceof WebAssembly.Global?C.__hwjs_status_channel.value+(je|0)*32>>>0:void 0,parkImport:o(()=>{},"parkImport"),sideTls:{mode:"fresh"}}),$e.tls&&(Ht=Y(tc($e.tls,Z),$e.tls.align)),Mt($e),W){if(Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} RED-NO-CTORS: stripped start + skipped runCtors for "${Z}" moduleId=${v} (its \xA7E8 register ctors did NOT run \u2192 its targets stay UNREGISTERED \u2192 consult UNRESOLVED \u2192 e8_refuse)`})}catch{}}else $e.runCtors();let Sn=Ot++;if(kt.set(Sn>>>0,{handle:$e,moduleId:v,bytes:u,path:Z,memoryBase:$e.memoryBase>>>0,tableBase:$e.tableBase>>>0,census:L,xmodRecs:j,xmodRegistrar:T,tlsSlots:Ht>>>0,...g||{}}),ue=!0,Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DLOPEN-OK path="${Z}" cookie=${Sn} moduleId=${v} memBase=0x${($e.memoryBase>>>0).toString(16)} tableBase=${$e.tableBase}`})}catch{}return Sn>>>0}o(Xu,"instantiateDlopenModule");let xr=Object.create(null),pr=0,Ru=!1,Vu=!1,Br=0,Xa=0,Ci=null,Vf=0,xu=0,xf=0,Bf=0,Tf=Object.freeze({kind:"syscall-sync",routeKey:t.routeKey}),Bu=2e4,Tu=!1;function Yu(u,Z){if(On.blocks()===1)try{e({kind:"dmesg",level:6,text:`hwjs-exec EXEC-LOAD-YIELD pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode} cpu=${t.cpuId??"?"} site=${u}: the exec load of "${Z??"?"}" block-parked (-517) with its chain preserved, and this Worker's JS event loop was HANDED BACK before the re-issue \u2014 a co-resident (canonically the single-threaded FUSE server this load is waiting on) gets real turns instead of being starved to the deadline`})}catch{}}o(Yu,"announceExecLoadYield");function Yf(u,Z){try{e({kind:"dmesg",level:4,text:`hwjs-exec EXEC-LOAD-INLINE pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode} cpu=${t.cpuId??"?"}: the exec load of "${u??"?"}" block-parked ${Z|0} time(s), but this image does not absorb the sentinel at raw syscalls (__hwjs_libc_syscall_park_abi ${ee?"=1":"absent"}), so execve cannot be told to retry and the host drove the load IN PLACE \u2014 this Worker's event loop, and every co-resident task with it, was frozen for the duration. Loud, attributed, and expected until this libc nominates the veneer.`})}catch{}}o(Yf,"announceExecLoadInline");let De=!!globalThis.process?.env?.HWJS_67_TRACE?{ring:[],inSysNr:-1,inSysT:0,statuses:Object.create(null),lastStatus:-1,lastStatusT:0,inWasm:!1,lastDriveEnterT:0,lastDriveRetT:0,coopWaits:0,reschedRestarts:0,futex:null,futexWaits:0,reasonAddr:0,resultAddr:0,timer:null}:null,Cf=o((u,Z)=>{De.ring.push(((u|0)<<0)+":"+(Z|0)),De.ring.length>48&&De.ring.shift(),De.inSysNr=-1},"t67RecordSys"),Nf=o(u=>{if(!De)return;let Z=Date.now(),g=Object.entries(De.statuses).map(([G,S])=>`${G}=${S}`).join(",");try{e({kind:"dmesg",level:6,text:`t67 pid=${s[ce.PID]|0} ${u} inWasm=${De.inWasm?1:0} lastStatus=0x${(De.lastStatus>>>0).toString(16)}@-${Z-De.lastStatusT}ms driveEnter@-${Z-De.lastDriveEnterT}ms driveRet@-${Z-De.lastDriveRetT}ms statuses{${g}} coopWaits=${De.coopWaits} reschedRestarts=${De.reschedRestarts} inSys=${De.inSysNr}@-${De.inSysNr>=0?Z-De.inSysT:0}ms futexWaits=${De.futexWaits} inFutex=${De.futex?JSON.stringify(De.futex):0} reason=${De.reasonAddr?Fe()[De.reasonAddr>>2]>>>0:-1} result=${De.resultAddr?Fe()[De.resultAddr>>2]|0:-1} sysRing=[${De.ring.slice(-24).join(" ")}]`})}catch{}},"t67Sample"),ts=new Set,Cu=!1,Nu=QZ({alloc:o(u=>mi(9,0,u.len,u.prot,34,-1,0),"alloc"),free:o((u,Z)=>{mi(11,u,Z,0,0,0,0)},"free"),read:o((u,Z,g)=>mi(17,u.mfd,Z+g|0,u.len-g|0,u.off+g|0,0,0),"read"),guestResumes:o(()=>E&&J(9),"guestResumes"),canWait:o(()=>!J(9),"canWait"),wait:o(()=>{sy(),de()},"wait"),epoch:o(()=>(xr[3]|0)+(xr[33]|0)+(xr[292]|0)+(xr[436]|0),"epoch"),restartCap:Xt}),ed=!!globalThis.process?.env?.D1_TRACE_FD,Kt=!!globalThis.process?.env?.D1_TRACE_SYS,Hf=o((u,Z,g)=>{if(!Kt)return"";let G=new Set([257,262,267,269,439,322,332,280]),S=new Set([4,6,21,89,79,59,80,2,87,161]),Y=-1;if(G.has(u)?Y=g>>>0:S.has(u)&&(Y=Z>>>0),Y<=0)return"";try{let v=new Uint8Array(t.memory.buffer),L=Y;for(;L=0&&G<=2&&ts.add(G)}}if(Array.isArray(t.lowFdRoutes))for(let Z of t.lowFdRoutes){let g=Z|0;g>=0&&g<=2&&ts.add(g)}}let td=202,Hu=0,vf=1,Ra=9,vu=10,Ff=128,Fu=256,Ef=~(Ff|Fu)&255,nd=1073741824,os=null,sd=0,rd=!!globalThis.process?.env?.HWJS_RED_FUTEX_TIMED_LEG,_f=-4,Eu=-11,_u=-110,di=-22,Ni=-38,Ju=null,Uu=null,Mu=null,Lu=null,id=o(()=>{let u=t.memory.buffer;u!==Ju&&(Ju=u,Uu=new Int32Array(u),Mu=new Uint32Array(u),Lu=new Uint8Array(u))},"refreshUserViews"),ct=o(()=>(id(),Uu),"uI32"),Fe=o(()=>(id(),Mu),"uU32"),od=o(()=>(id(),Lu),"uU8"),Vs=t.kernelMemoryWasm??null,Va=Vs?Vs.buffer:null,Pu=Va?new Int32Array(Va):null,xa=o(()=>{if(Vs===null)return null;let u=Vs.buffer;return u!==Va&&(Va=u,Pu=new Int32Array(u)),Pu},"kernelI32Live"),as=typeof t.signalPendingOffset=="number"&&(t.signalPendingOffset&3)===0?t.signalPendingOffset>>>2:-1;function po(){return DZ(ct(),as)}o(po,"signalPending");function fo(){if(as<0)return!1;let u=Atomics.load(ct(),as)|0,Z=Atomics.load(ct(),as+1)|0;if(u===0&&Z===0)return!1;let g=Atomics.load(ct(),as+4)|0,G=Atomics.load(ct(),as+5)|0;return(u&~g|Z&~G)!==0}o(fo,"deliverableSignalPending");let er=0,ad=0,ld=5e3;function Au(u){if(u>>>0===ad?er++:(ad=u>>>0,er=1),er===ld||er%(ld*40)===0){let Z=as>=0?Atomics.load(ct(),as)>>>0:0,g=as>=0?Atomics.load(ct(),as+1)>>>0:0,G=as>=0?Atomics.load(ct(),as+4)>>>0:0,S=as>=0?Atomics.load(ct(),as+5)>>>0:0,Y=`hwjs-futex EINTR-STORM pid=${s[ce.PID]|0} tid=${t.tid}: ${er} consecutive FUTEX_WAIT -EINTRs at uaddr=0x${(u>>>0).toString(16)} \u2014 a pending signal (pending=0x${g.toString(16)}:${Z.toString(16)} mask=0x${S.toString(16)}:${G.toString(16)}) is not being dispatched/cleared by the guest between waits: signal-delivery livelock (the caller loops on EINTR without crossing a dispatch point). Loud witness, not a behavior change.`;try{e({kind:"user-report",pid:t.pid,message:Y})}catch{}try{console.error(`[hwjs-futex pid=${s[ce.PID]|0}] ${Y}`)}catch{}}return _f}o(Au,"futexEintr");let ci=!1,Jf=!!globalThis.process?.env?.HWJS_RED_SIGCHLD_ARM_WNOHANG,Uf=!!globalThis.process?.env?.HWJS_RED_SIGCHLD_REGION_WRITE,Ku=ng({getI32:o(()=>ct(),"getI32"),getIdx:o(()=>as,"getIdx"),inExecWindow:o(()=>gs(),"inExecWindow"),askKernel:o(()=>{let u=Ze&&Ze.exports;if(!u||typeof u.__wasm32_kernel_signal_pending_republish!="function")return-1;try{return u.__wasm32_kernel_signal_pending_republish()|0}catch{return-1}},"askKernel"),red:{hostWritesBit:Uf}});function zu(){return Ku.pendingNow()}o(zu,"sigchldPendingNow");function Ba(){Ku.maybeReassert(ci)}o(Ba,"maybeReassertSigchldOnWake");function Mf(u){let Z=u>>>2,g=Fe()[Z]>>>0,G=Fe()[Z+1]|0,S=Fe()[Z+2]>>>0,Y=BigInt(G)*4294967296n+BigInt(g);return Y<0n||S>=1e9?null:Y*1000000000n+BigInt(S)}o(Mf,"readGuestTimespec64Ns");function Lf(u,Z){if(Ze&&typeof Ze.exports.wasm_syscall=="function"&&He!==0){let g=Z>>>2,G=Fe()[g],S=Fe()[g+1],Y=Fe()[g+2],v=Fe()[g+3];try{let L=o(()=>Ze.exports.wasm_syscall(228,u|0,Z|0,0,0,0,0),"call");if(((ft?ft.dispatchSyscall(228,L):L())|0)===0){let T=Fe()[g]>>>0,fe=Fe()[g+1]|0,ge=Fe()[g+2]>>>0;return(BigInt(fe)*4294967296n+BigInt(T))*1000000000n+BigInt(ge)}}catch{}finally{Fe()[g]=G,Fe()[g+1]=S,Fe()[g+2]=Y,Fe()[g+3]=v}}return u===0?typeof performance<"u"&&performance.now&&typeof performance.timeOrigin=="number"?BigInt(Math.round((performance.timeOrigin+performance.now())*1e6)):BigInt(Date.now())*1000000n:null}o(Lf,"guestClockNowNs");function Pf(u,Z,g,G,S,Y){let v=Z&Ef;if(os&&!((v===Hu||v===Ra)&&(Z&nd)!==0)&&(os=null),globalThis.process?.env?.HWJS_DBG_FUTEX)try{let j=G>>>0,T="null";if(j){let he=Fe()[j>>>2],Pe=Fe()[(j>>>2)+1],bt=Fe()[(j>>>2)+2],$e=Fe()[(j>>>2)+3];T=`[${he},${Pe},${bt},${$e}]`}let fe=as,ge=fe>=0?(Atomics.load(ct(),fe)>>>0).toString(16):"n/a",W=fe>=0?(Atomics.load(ct(),fe+4)>>>0).toString(16):"n/a";console.error(`[FUTEX-DBG pid=${s[ce.PID]|0}] raw_op=0x${(Z>>>0).toString(16)} op=${v} uaddr=0x${(u>>>0).toString(16)} val=${g|0} tp=0x${(G>>>0).toString(16)} ts32words=${T} sigRegionOff=0x${fe>=0?(fe<<2).toString(16):"-"} lo=0x${ge} mlo=0x${W} deliverable=${fo()?1:0}`)}catch{}if((u&3)!==0)return di;let L=u>>>2;if(v===Hu||v===Ra&&!rd){if(v===Ra&&(Y|0)===0)return di;if(fo()){let W=u>>>0===ad?er:0;if(n&&x&&(Z&nd)!==0&&W>=ld){if(!Ru){Ru=!0;let he=`hwjs-coopwait EINTR-STORM PARK pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0}: ${W} consecutive FUTEX_WAIT -EINTRs at uaddr=0x${(u>>>0).toString(16)} proved this caller discards EINTR. As a POOL RESIDENT that loop runs entirely inside the wasm drive and FREEZES the shared CPU Worker \u2014 every co-resident task and its onmessage. Converting to the cooperative park so the pump can yield. The underlying defect is upstream: a deliverable signal is pending and the guest never crosses a dispatch point (loud, attributed).`;try{e({kind:"dmesg",level:3,text:he})}catch{}try{e({kind:"user-report",pid:s[ce.PID]|0,message:he})}catch{}}return pr++,os=null,an}return os=null,Au(u)}let j=1/0;if(G!==0){if((G&3)!==0)return di;if(rd){let W=Fe()[G>>>2],he=Fe()[(G>>>2)+1];if(j=W*1e3+he/1e6,j<0)return di}else{let W=Mf(G>>>0);if(W===null)return di;if(v===Ra){let he=Z&Fu?0:1,Pe=Lf(he,G>>>0);if(Pe===null){try{e({kind:"dmesg",level:3,text:`wasm32: FUTEX_WAIT_BITSET pid=${s[ce.PID]|0} clockid=${he} \u2014 guest clock unreachable (no in-Worker vmlinux); refusing the absolute-deadline wait with ENOSYS rather than waiting against the wrong clock`})}catch{}return Ni}let bt=W-Pe;j=bt<=0n?0:Math.ceil(Number(bt)/1e6)+1}else j=Math.ceil(Number(W)/1e6)+1}}if((Z&nd)!==0&&x){let W=Atomics.load(ct(),L)|0,he=os&&os.uaddr===u>>>0&&os.val===(g|0)?os:null;if(W!==(g|0))return os=null,er=0,he?0:Eu;let Pe=Date.now(),bt=he?he.deadlineMs:j===1/0?1/0:Pe+j;if(Pe>=bt)return os=null,er=0,_u;if(os={uaddr:u>>>0,i32idx:L,val:g|0,deadlineMs:bt},De&&De.futexWaits++,!Vu){Vu=!0;try{e({kind:"dmesg",level:6,text:`hwjs-coopwait ACTIVE pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode}: this guest's libc sets HWJS_FUTEX_COOP_WAIT \u2014 blocking futex waits park cooperatively and never freeze a shared CPU Worker`})}catch{}}return an}if(De&&(De.futexWaits++,De.futex={uaddr:u>>>0,val:g|0,ms:j===1/0?-1:Math.round(j),t:Date.now()},j===1/0))try{e({kind:"dmesg",level:6,text:`t67 pid=${s[ce.PID]|0} USER-FUTEX-WAIT-INF uaddr=0x${(u>>>0).toString(16)} val=${g|0} cur=${Atomics.load(ct(),L)|0}`})}catch{}if(n&&j===1/0&&(pr++,(pr&pr-1)===0)){let W=`hwjs-coopwait VIOLATION pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode}: a POOL RESIDENT entered an UNBOUNDED raw FUTEX_WAIT (uaddr=0x${(u>>>0).toString(16)}) without HWJS_FUTEX_COOP_WAIT. This freezes the shared CPU Worker \u2014 every co-resident task and the Worker's own message loop (add-task claims, thread-placement requests) stall for the duration. The libc must set the cooperative bit on every indefinitely-blocking wait (PLAN-THREAD-POOL-RESIDENCY contract 3). Occurrences so far: ${pr} (loud, attributed, never-silent).`;try{e({kind:"dmesg",level:3,text:W})}catch{}try{e({kind:"user-report",pid:s[ce.PID]|0,message:W})}catch{}}let T=250,fe=j,ge;for(;;){let W=Math.min(fe,T);if(ge=Atomics.wait(ct(),L,g|0,W),ge!=="timed-out"||fe!==1/0&&(fe-=W,fe<=0)||fo())break;if(Atomics.load(ct(),L)!==(g|0)){ge="ok";break}de(),i()}if(De){if(De.futex&&De.futex.ms===-1)try{e({kind:"dmesg",level:6,text:`t67 pid=${s[ce.PID]|0} USER-FUTEX-WAIT-INF WOKE r=${ge}`})}catch{}De.futex=null}return fo()?Au(u):(er=0,ge==="ok"?0:ge==="not-equal"?Eu:ge==="timed-out"?_u:di)}if(v===vf||v===vu&&!rd){if(v===vu&&(Y|0)===0)return di;let j=g<0?2147483647:g|0;return Atomics.notify(ct(),L,j)|0}return Ni}o(Pf,"handleFutex");let tr=typeof process<"u"&&process.env?.HARDWAREJS_DEBUG_K7_U4F,Af=0,Ta=null,dd=-1;if(tr)try{Ta=await import("node:fs");let u=process.env?.HARDWAREJS_DEBUG_LOG??"/tmp/k7-u4f-trace.log";dd=Ta.openSync(u,"a")}catch{}function yo(u){if(Ta&&dd>=0)try{Ta.writeSync(dd,u)}catch{}}o(yo,"writeDebug");let Zo=typeof performance<"u"&&typeof performance.now=="function"?()=>performance.now():()=>Date.now(),cd=0,ud=!1,go=0,Io=0,Kf=2;function ju(u){if(u>0)try{Ze&&typeof Ze.exports.wasm32_account_user_ns=="function"&&Ze.exports.wasm32_account_user_ns(BigInt(Math.round(u*1e6)))}catch{}}o(ju,"acctReportUser");function md(){return go=0,Io=0,cd=Zo(),ud=!0,cd}o(md,"acctBeginSlice");function hd(u){let Z=Zo()-u-go-Io;if(ud=!1,typeof process<"u"&&process.env&&process.env.HWJS_ACCT_DBG)try{console.error(`[acct-dbg pid=${t.pid}] slice wall=${(Zo()-u).toFixed(3)}ms sys=${go.toFixed(3)}ms settled=${Io.toFixed(3)}ms user-tail=${Z.toFixed(3)}ms export=${!!(Ze&&Ze.exports.wasm32_account_user_ns)}`)}catch{}ju(Z)}o(hd,"acctEndSlice");let bd=0,Ou=0,Qu=0,Du=0,$u=0,qu=0,em=0,tm=o(()=>Ze.exports.wasm_syscall(bd,Ou,Qu,Du,$u,qu,em),"kernelCall");function nm(u,Z,g,G,S,Y,v){return bd=u|0,Ou=Z|0,Qu=g|0,Du=G|0,$u=S|0,qu=Y|0,em=v|0,ft?ft.dispatchSyscall(bd,tm):tm()}o(nm,"kernelDispatch");let pd=!1;function Go(u,Z,g,G,S,Y,v){fd&&om(`sys-entry nr=${u}`);let L=Zo();if(ud){let j=L-cd-go-Io;j>=Kf&&(ju(j),Io+=j)}try{De&&(De.inSysNr=u|0,De.inSysT=Date.now());let j=mi(u,Z,g,G,S,Y,v);return De&&Cf(u,j),u===56&&(j|0)!==an&&(pd=!1),(j|0)!==an&&(j|0)!==xb&&sd++,j}finally{go+=Zo()-L,fd&&om(`sys-exit nr=${u}`)}}o(Go,"syscall");let fd=typeof process<"u"&&process.env?.HWJS_HEAP_AUDIT?parseInt(process.env.HWJS_HEAP_AUDIT,16)>>>0:0,yd=!1,Wo="never",sm=!1,rm=!1,zf=[1,2,3,4,5,6,7,8,9,10,12,15,18,20,25,31,36,42,50,63,72,84,102,127,146,170,204,255,292,340,409,511,584,682,818,1023,1169,1364,1637,2047,2340,2730,3276,4095,4680,5460,6552,8191],im=typeof process<"u"&&process.env?.HWJS_HEAP_AUDIT_LEN?parseInt(process.env.HWJS_HEAP_AUDIT_LEN,10)>>>0:0,jf=typeof process<"u"&&!!process.env?.HWJS_HEAP_AUDIT_META,Zd=[1e9,1e9,2e3,1e3,500,25e7,1e3,10,5e4,32766,1e3],ui=0,gd=!1,Id=0;function om(u){if(yd||im&&(!Jn||Jn.length!==im))return;let Z=od(),g=new DataView(Z.buffer),G=fd;if(!sm){sm=!0;try{e({kind:"dmesg",level:5,text:`HEAP-AUDIT ARMED pid=${t.pid} lane=${t.userLane??0} ctx=0x${G.toString(16)} init_done@+12=${g.getUint32(G+12,!0)} pagesize@+8=${g.getUint32(G+8,!0)}`})}catch{}}let S=Z.length,Y=o(v=>{yd=!0;let L=`HEAP-AUDIT pid=${t.pid} lane=${t.userLane??0} FIRST VIOLATION at [${u}] (last good: [${Wo}]): ${v}`;try{e({kind:"dmesg",level:3,text:L})}catch{}try{e({kind:"user-report",pid:t.pid,message:L})}catch{}let j=typeof process<"u"?process.env?.HWJS_TRAP_DUMP:void 0;if(j)try{import("node:fs").then(T=>{let fe=new Uint8Array(Z.length);fe.set(new Uint8Array(t.memory.buffer));let ge=`auditdump-lane${t.userLane??0}-${Date.now()}`;T.writeFileSync(`${j}/${ge}.bin`,fe),T.writeFileSync(`${j}/${ge}.txt`,L+` `)}).catch(()=>{})}catch{}},"fail");try{if(g.getUint32(G+8,!0)===0){Wo=u;return}if(!rm){rm=!0;try{e({kind:"dmesg",level:5,text:`HEAP-AUDIT GATE-OPEN pid=${s?s[ce.PID]|0:"?"} lane=${t.userLane??0} ctx=0x${G.toString(16)} init_done=${g.getUint32(G+8,!0)} secret=0x${g.getUint32(G+4,!0).toString(16)}${g.getUint32(G,!0).toString(16)} area_head=0x${(g.getUint32(G+36,!0)>>>0).toString(16)} \u2014 walker LIVE`})}catch{}}let v=g.getUint32(G,!0),L=g.getUint32(G+4,!0),j=g.getUint32(G+36,!0)>>>0,T=0,fe=[];for(;j!==0&&T<64;){if(j+16>S)return Y(`meta_area 0x${j.toString(16)} out of range`);if(g.getUint32(j,!0)!==v||g.getUint32(j+4,!0)!==L)return Y(`meta_area 0x${j.toString(16)} check != secret (0x${g.getUint32(j+4,!0).toString(16)}${g.getUint32(j,!0).toString(16)})`);let ge=g.getUint32(j+12,!0);if(ge===0||ge>4096)return Y(`meta_area 0x${j.toString(16)} nslots=${ge}`);fe.push([j+16,j+16+24*ge]),j=g.getUint32(j+8,!0)>>>0,T++}for(let ge=0;ge<48;ge++){let W=g.getUint32(G+48+4*ge,!0)>>>0;if(W===0)continue;if(!fe.some(([Sn,yn])=>W>=Sn&&W+24<=yn))return Y(`active[${ge}] meta 0x${W.toString(16)} not inside any meta area`);let he=g.getUint32(W+20,!0),Pe=he>>>6&63;if(Pe!==ge)return Y(`active[${ge}] meta 0x${W.toString(16)} has sizeclass ${Pe}`);let bt=g.getUint32(W+8,!0)>>>0;if(bt===0||bt+16>S)return Y(`active[${ge}] group mem 0x${bt.toString(16)} bad`);if(g.getUint32(bt,!0)>>>0!==W)return Y(`active[${ge}] group 0x${bt.toString(16)} backptr 0x${g.getUint32(bt,!0).toString(16)} != meta 0x${W.toString(16)}`);let $e=g.getUint32(W+12,!0)>>>0,Ht=g.getUint32(W+16,!0)>>>0;if(($e&Ht)!==0)return Y(`active[${ge}] avail 0x${$e.toString(16)} \u2229 freed 0x${Ht.toString(16)} != 0 (meta 0x${W.toString(16)})`);if(ge<=10&&!jf){let Sn=zf[ge]*16,yn=he&31,Gs=bt+16;for(let bn=0;bn<=yn;bn++)if($e>>>bn&1){let zt=Gs+Sn*bn;if(zt-4>=0&&zt<=S&&Z[zt-4]!==0)return Y(`active[${ge}] AVAIL slot ${bn} p=0x${zt.toString(16)} in-band p[-4]=0x${Z[zt-4].toString(16)} != 0 (group 0x${bt.toString(16)} meta 0x${W.toString(16)} avail=0x${$e.toString(16)} freed=0x${Ht.toString(16)}; bytes ${Array.from(Z.subarray(Math.max(0,zt-16),zt+16)).map(Ln=>Ln.toString(16).padStart(2,"0")).join(" ")})`)}}}if(!gd){if(ui===0){if(Id++,Id>3072){gd=!0,Wo=u;return}if((Id&127)!==1){Wo=u;return}let ge=Math.min(S-44,67108864);for(let W=4194304;W<=ge;W+=16)if(g.getUint32(W,!0)===1e9&&g.getUint32(W+4,!0)===1e9&&g.getUint32(W+8,!0)===2e3&&g.getUint32(W+12,!0)===1e3&&g.getUint32(W+16,!0)===500&&g.getUint32(W+20,!0)===25e7){ui=W;try{e({kind:"dmesg",level:5,text:`HEAP-AUDIT ALIMIT pinned @0x${W.toString(16)} lane=${t.userLane??0} [${u}] \u2014 watching the sqlite3 connection aLimit signature for wild writes`})}catch{}break}}else for(let ge=0;ge>>0!==Zd[ge]>>>0)return gd=!0,Y(`sqlite3 connection aLimit[${ge}] @0x${(ui+4*ge).toString(16)} = 0x${g.getUint32(ui+4*ge,!0).toString(16)} (expected 0x${(Zd[ge]>>>0).toString(16)}) \u2014 WILD WRITE into the sqlite3 connection struct (the whereLoop T2 victim); bytes@aLimit-64 ${Array.from(Z.subarray(ui-64,ui+8)).map(W=>W.toString(16).padStart(2,"0")).join(" ")}`)}Wo=u}catch(v){yd=!0;try{e({kind:"dmesg",level:3,text:`HEAP-AUDIT pid=${t.pid} lane=${t.userLane??0} walker threw at [${u}]: ${v instanceof Error?v.message:String(v)}`})}catch{}}}o(om,"heapAudit");let am=typeof process<"u"&&!!process.env?.HWJS_STALL_TRACE,nr=Object.freeze(typeof process<"u"&&process.env?{...process.env}:{}),lm=-1,wo=0,dm=0,cm=0,um=o(u=>`STALL-TRACE pid=${s?s[ce.PID]|0:t.pid??"?"} lane=${t.userLane??0} ${u}; syscalls=${dm} last nr=${lm} age=${wo?((Date.now()-wo)/1e3).toFixed(1):"?"}s`,"stallLine");if(am&&typeof setInterval=="function"){let u=setInterval(()=>{try{e({kind:"dmesg",level:5,text:um("loop-alive")})}catch{}},2e4);typeof u=="object"&&u&&typeof u.unref=="function"&&u.unref()}let Gd=null,Wd=null,mm=0;function Of(u,Z){Wd!==Jn&&(Gd=Ph(Jn,mm),Wd=Jn);let g=C,G=o(T=>T&&T.dylink?T.dylink.memorySize>>>0:0,"sizeOf"),S=[];ae&&B&&S.push({memoryBase:B.memoryBase,memorySize:G(ae)}),Q&&$&&S.push({memoryBase:$.memoryBase,memorySize:G(Q)});for(let T of pe)T&&T.handle&&S.push({memoryBase:T.handle.memoryBase,memorySize:G(T.handle)});for(let T of kt.values())T&&!T.mainScope&&T.handle&&S.push({memoryBase:T.memoryBase,memorySize:G(T.handle)});let Y=[],v=Kh(Gd,t.mode==="thread"?t.stackPointerOffset>>>0:0);if(v&&g&&typeof g.__wasm32_get_stack_pointer=="function"&&Y.push({sp:g.__wasm32_get_stack_pointer()>>>0,...v}),B&&Ce){let T=B.spTop>>>0;Y.push({sp:Ce.value>>>0,hi:T,limit:T-Qd>>>0})}let L=[];if(g&&typeof g.__hwjs_arena_seg_count=="function"){let T=je>>>0,fe=Math.min(g.__hwjs_arena_seg_count(T)>>>0,1024);for(let ge=0;ge>>0,g.__hwjs_arena_seg_end(T,ge)>>>0])}let j=zh({main:Gd,modules:S,stacks:Y,arena:L});return jh(t.memory.buffer,u,Z,j)}o(Of,"serviceRootMap");function mi(u,Z,g,G,S,Y,v){if(am&&(lm=u|0,wo=Date.now(),dm++,wo-cm>15e3)){cm=wo;try{e({kind:"dmesg",level:5,text:um("in-syscall")})}catch{}}if(i(),ue=!0,os!==null&&(u|0)!==td&&(os=null),er!==0&&(u|0)!==td&&(er=0),tr){let te=++Af;yo(`[K7-U4f worker pid=${t.pid} tid=${t.tid} seq=${te}] nr=${u} args=[0x${(Z>>>0).toString(16)},0x${(g>>>0).toString(16)},0x${(G>>>0).toString(16)},0x${(S>>>0).toString(16)},0x${(Y>>>0).toString(16)},0x${(v>>>0).toString(16)}] `)}if(Kt){let te=Hf(u,Z,g);try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} ENTER nr=${u|0}`+(te?` path="${te}"`:"")+` a0=0x${(Z>>>0).toString(16)} a1=0x${(g>>>0).toString(16)} a2=0x${(G>>>0).toString(16)}`})}catch{}}if(u===56&&Z>>>0&256&&x&&!(we&&!!C&&typeof C.__hwjs_lane_attach=="function"&&typeof C.__hwjs_lane_cap=="function"&&(C.__hwjs_lane_cap()|0)>1)&&globalThis.process?.env?.HWJS_EXPERIMENTAL_THREAD_CLONE!=="1"){try{e({kind:"dmesg",level:4,text:`wasm32: REFUSING thread-mode clone (CLONE_VM, pid=${s[ce.PID]|0}, flags=0x${(Z>>>0).toString(16)}) with EAGAIN \u2014 the coro substrate's runtime protocol state is single-lane per process; a second Worker lane over the same user_memory is a structural protocol violation, not a schedulable thread. pthread_create() gets EAGAIN (catchable std::system_error). Opt-in: HWJS_EXPERIMENTAL_THREAD_CLONE=1.`})}catch{}return-11}if(u===56&&Z>>>0&256)try{pd||(pd=!0,e({kind:"thread-placement",pid:s[ce.PID]|0,seq:0,unsolicited:!0,clone:{flags:Z>>>0,ptid:G>>>0,ctid:Y>>>0},callerYieldsDuringClone:re(yZ),lowFdRoutes:[...ts],dlopenFork:Nn()}))}catch{}if(u===k){if(x)return Ae=!0,0;let te=C;if(!te||typeof te.asyncify_get_state!="function"||typeof te.asyncify_start_unwind!="function"||typeof te.__wasm32_asyncify_buf_addr!="function")return Ni;if((te.asyncify_get_state()|0)===Ge)return te.asyncify_stop_rewind(),Qs|0;let ze=te.__wasm32_asyncify_buf_addr()>>>0,pt=te.__wasm32_asyncify_buf_size()|0,Xn=ze>>>2;return Fe()[Xn]=ze+8>>>0,Fe()[Xn+1]=ze+pt>>>0,jt=!0,te.asyncify_start_unwind(ze),0}if(u===U){if(x){let Ms=On.phase.phase!=="idle"&&On.phase.pathPtr===Z>>>0||Bn.phase==="staged"&&Bn.pathPtr===Z>>>0;if(Ve=!0,!Ms){le=Z>>>0;let on=new Uint8Array(t.memory.buffer),lr=Z>>>0;for(;lr>>0,lr)),Gt=Ue(g>>>0,"execve argv"),Re=Ue(G>>>0,"execve envp"),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} EXECVE-LATCH path="${Et}" argv=[${Gt.map(zr=>JSON.stringify(zr)).join(",")}] (${Re.length} env)`})}catch{}}{let on=co(Z>>>0,ee);if(on.wouldBlock)return Yu("execve intercept",Et),Dt&&Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=EXEC-LOAD-park site=execve-intercept via=guest-restart`),an;if(on.unavailable)return 0;if(!ee&&On.blocksLast()>0&&Yf(Et,On.blocksLast()),!on.ok){if(Rt=typeof on.errno=="number"&&on.errno<0?on.errno|0:-2,Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} EXECVE-INLINE FAIL path="${Et}" errno=${Rt}`})}catch{}return Rt|0}if(rn=on.wasmBytes,Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} EXECVE-INLINE OK path="${Et}" ${on.wasmBytes.length}B \u2014 unwinding to re-instantiate`})}catch{}throw Ve=!1,Sc}}let te=C;if(!te||typeof te.asyncify_get_state!="function"||typeof te.asyncify_start_unwind!="function"||typeof te.__wasm32_asyncify_buf_addr!="function")return Ni;if((te.asyncify_get_state()|0)===Ge)return te.asyncify_stop_rewind(),Rt|0;le=Z>>>0;let ze=new Uint8Array(t.memory.buffer),pt=Z>>>0,Xn=ze.length;for(;pt>>0,pt)),Gt=Ue(g>>>0,"execve argv"),Re=Ue(G>>>0,"execve envp");let hs=te.__wasm32_asyncify_buf_addr()>>>0,yt=te.__wasm32_asyncify_buf_size()|0,Gn=hs>>>2;return Fe()[Gn]=hs+8>>>0,Fe()[Gn+1]=hs+yt>>>0,Zs=!0,te.asyncify_start_unwind(hs),0}if(u===RZ){if(x)throw new Error("HWJS-3: SYS_WASM_SETJMP from a coro-substrate image \u2014 sjlj is lowered in-module; this syscall is retired. A stale Asyncify-era setjmp override is linked into the binary.");let te=C;if(!te||typeof te.asyncify_get_state!="function"||typeof te.asyncify_start_unwind!="function"||typeof te.__wasm32_asyncify_buf_addr!="function")return Ni;if((te.asyncify_get_state()|0)===Ge)return te.asyncify_stop_rewind(),St|0;Bt=Z>>>0;let ze=te.__wasm32_asyncify_buf_addr()>>>0,pt=te.__wasm32_asyncify_buf_size()|0,Xn=ze>>>2;return Fe()[Xn]=ze+8>>>0,Fe()[Xn+1]=ze+pt>>>0,Ke=!0,te.asyncify_start_unwind(ze),0}if(u===VZ){if(x)throw new Error("HWJS-3: SYS_WASM_LONGJMP from a coro-substrate image \u2014 sjlj is lowered in-module; this syscall is retired. A stale Asyncify-era setjmp override is linked into the binary.");let te=C;if(!te||typeof te.asyncify_get_state!="function"||typeof te.asyncify_start_unwind!="function"||typeof te.__wasm32_asyncify_buf_addr!="function")return Ni;Nt=Z>>>0,St=g|0;let Te=te.__wasm32_asyncify_buf_addr()>>>0,ze=te.__wasm32_asyncify_buf_size()|0,pt=Te>>>2;return Fe()[pt]=Te+8>>>0,Fe()[pt+1]=Te+ze>>>0,nt=!0,te.asyncify_start_unwind(Te),0}if(u===td)return Pf(Z|0,g|0,G|0,S|0,Y|0,v|0);if(u===ZZ){if(w=!0,mn=Z>>>0,V="",Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DLOPEN-LATCH path="${Js(Z>>>0)}" (HWJS_PARK_DLOPEN armed)`})}catch{}return 0}if(u===GZ){let te=Z>>>0,Te=g|0;if(!V||te===0||Te<=1)return 0;let ze=new TextEncoder().encode(V),pt=Math.min(ze.length,Te-1),Xn=new Uint8Array(t.memory.buffer);return te+pt+1>Xn.length?0:(Xn.set(ze.subarray(0,pt),te),Xn[te+pt]=0,pt)}if(u===SZ)return Of(Z>>>0,g|0);if(u===gZ){let te=kt.get(Z>>>0);if(!te)return 0;let Te=Js(g>>>0),ze=0;try{ze=te.handle.dlsym(Te)|0}catch(pt){return e({kind:"error",pid:t.pid,message:"HWJS-5 dlsym trapped: "+(pt instanceof Error?pt.message:String(pt))}),0}if(Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DLSYM cookie=${Z>>>0} name="${Te}" -> ${ze>>>0}`})}catch{}return ze}if(u===IZ){let te=Z>>>0,Te=kt.get(te);if(!Te)return-22;if(Te.mainScope)return kt.delete(te),0;if(Te.internal)return-22;if(Te.boundByDependent)return Te.internal=!0,0;let ze=(globalThis.process?.env?.HWJS_DLCLOSE_NO_CENSUS||"")==="1",pt=Te.census||{live:0,poisoned:!1},Xn=C?C.__hwjs_parked:void 0,hs=Xn instanceof WebAssembly.Global?Xn.value>>>0:0,yt=hs?Fe()[hs>>2]>>>0:0,Gn=C?C.__hwjs_parked_owner:void 0,Ms=Gn instanceof WebAssembly.Global?Gn.value>>>0:0,on=Ms?Fe()[Ms>>2]>>>0:0,lr=Te.tableBase>>>0,zr=Te.handle&&Te.handle.dylink?Te.handle.dylink.tableSize>>>0:0,Xo=Te.handle&&typeof Te.handle.tableIndices=="function"?Te.handle.tableIndices():[],jr=on>=lr&&on0?ls=`${pt.live} live coroutine frame(s) allocated by the module are not yet freed`:pt.poisoned&&(ls="the module frame census is POISONED (a frame_free underflow was observed; the count is untrustworthy)"),yt!==0&&(e({kind:"user-report",pid:t.pid,message:`HWJS-5 M2 dlclose ANOMALY: __hwjs_parked=0x${yt.toString(16)} (owner=0x${on.toString(16)}) non-zero at dlclose service of cookie=${te} "${Te.path||""}" \u2014 a park is in flight while dlclose runs${jr?"; the owner word falls in the closing module's table footprint \u2014 REFUSING":""}.`}),jr&&!ls&&(ls=`a parked chain's owner word 0x${on.toString(16)} targets the closing module's table slots`)),ls)return e({kind:"user-report",pid:t.pid,message:`HWJS-5 M2 dlclose REFUSED (EBUSY): path="${Te.path||""}" cookie=${te} moduleId=${Te.moduleId} live=${pt.live} \u2014 `+ls+". The handle stays open; retry after the module's coroutines complete (never-silent, non-terminal)."}),-16}gt.push({tableBase:Te.tableBase>>>0,tableSize:zr>>>0,appended:Xo.slice(),path:Te.path||"",moduleId:Te.moduleId|0});{let ls=Te.tableBase>>>0;for(let Ro of[...zn.keys()])(Ro>=ls&&Ro>>0)||Xo.includes(Ro))&&zn.delete(Ro)}try{Te.handle.unload()}catch{}if(Ze&&typeof Ze.exports.__hwjs_deregister_module=="function")try{Ze.exports.__hwjs_deregister_module(Te.moduleId|0)}catch(ls){e({kind:"error",pid:t.pid,message:"HWJS-5 __hwjs_deregister_module trapped: "+(ls instanceof Error?ls.message:String(ls))})}if(kt.delete(te),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DLCLOSE cookie=${te} moduleId=${Te.moduleId}`})}catch{}return 0}if(u===XZ){if(Ze&&He!==0&&typeof Ze.exports.wasm32_sigconsume=="function")try{let te=o(()=>Ze.exports.wasm32_sigconsume(Z|0,g>>>0)|0,"call");return(ft?ft.bracket("wasm32_sigconsume",te):te())|0}catch(te){return e({kind:"error",pid:t.pid,message:"K12-W4: vmlinux wasm32_sigconsume trapped: "+(te instanceof Error?te.message:String(te))}),0}return 0}if(u===fZ||u===cc||u===sl){lo();let te=u===sl?1:0,Te=te?Z&127:Z&255,ze=u===cc?X(Z&255,0):u===sl?X(Z&127,1):null;if(ze&&((ze.wstatus&127)===0?(Te=ze.wstatus>>8&255,te=0):(Te=ze.wstatus&127,te=1)),d=Te,ze&&ze.zapped>0?e({kind:"dmesg",level:5,text:`hwjs-groupexit pid=${t.pid} tid=${t.tid|0} mode=${t.mode??"fork"}: `+(u===cc?`exit_group(${Z&255})`:`fatal terminus by signal ${Z&127}`)+` \u2014 the kernel condemned ${ze.zapped} other thread(s) of this process and set the group's exit code to 0x${ze.wstatus.toString(16)} (${ze.wstatus&127?`WIFSIGNALED WTERMSIG=${ze.wstatus&127}`:`WIFEXITED WEXITSTATUS=${ze.wstatus>>8&255}`}); the host now unwinds their Workers (the kernel's decision, this host's mechanism)`}):u===sl&&!ze&&e({kind:"dmesg",level:3,text:`hwjs-groupexit pid=${t.pid} tid=${t.tid|0} mode=${t.mode??"fork"}: fatal terminus by signal ${Z&127} was NOT decided by the kernel \u2014 this process's other threads are not condemned by it and the host unwinds none of them. On Linux a fatal signal on any thread ends the whole process`}),a={codeArg:Te,signaled:te,grpExit:ze},!l&&Xe&&Xe("exit-syscall"),n)throw Ub;if(a=null,Ze&&He!==0)throw new Error(`exit terminus: a legacy (non-pool) Worker reached SYS_exit_group with a live vmlinux task (ptask=0x${(He>>>0).toString(16)}) \u2014 the child-exit cleanup yields the event loop on a would-block (contract 3, site 4) and this arm has no async frame to yield into. Refusing to drop the cleanup (never-silent).`);b({codeArg:Te,signaled:te,grpExit:ze})}let L=13,j=62,T=61,fe=200,ge=234,W=3,he=32,Pe=33,bt=22,$e=292,Ht=293,Sn=109,yn=111,Gs=112,bn=121,zt=124,Ln=39,Ns=110,ms=218,rr=0,O=1,ke=8,be=19,Ee=20,Je=16,Ne=2,vt=257,Tt=85,Lt=80,Pt=81,Tn=79,Un=72,Vt=73,Pn=4,Qn=5,xs=6,Zn=217,Ws=262,An=332,tn=228,Hn=229,sn=35,ir=230,ss=219,We=96,Se=201,qe=36,ut=38,Yn=pb,Dn=204,or=309,Qt=131,ar=102,$n=104,lt=107,et=108,mt=280,ot=263,wt=21,Me=269,tt=439,gn=89,pn=267,_t=74,Kn=75,oe=162,Le=306,Be=82,ht=83,Jt=84,Yt=87,dn=90,fn=258,kn=264,Yr=268,bi=316,Hi=452,ws=165,Ss=166,Ya=155,In=272,xt=7,Us=23,Cn=270,vn=271,Kr=41,fr=55,Ca=288,So=9,ko=17,Na=18,pi=63,Im=76,Gm=77,Wm=318,wm=103,Sm=86,km=88,Xm=91,Rm=92,Vm=93,xm=94,Bm=133,Tm=259,Ym=260,Cm=265,Nm=266,iy=125,oy=126,ay=186,Hm=40,vm=137,Fm=138,Em=326,_m=!!nr.HWJS_RED_MMAP_FILE_UNPOPULATED;if(u===So&&!_m&&((S|0)&32)===0){let te=S|0,Te=G|0,ze=Y|0,pt=g>>>0,Xn=v>>>0,hs=te&15,yt=o((jr,ls)=>{try{e({kind:"dmesg",level:3,text:`hwjs-mmap pid=${s[ce.PID]|0} file-backed mmap REFUSED (${ls}): fd=${ze} len=0x${pt.toString(16)} prot=0x${(Te>>>0).toString(16)} flags=0x${(te>>>0).toString(16)} off=0x${Xn.toString(16)} -> errno ${-jr} (linux-in-the-browser#72)`})}catch{}return jr|0},"refuse");if(ze===-1)return yt(-9,"no MAP_ANONYMOUS and fd == -1");if(pt===0||(Xn&4095)!==0||hs!==1&&hs!==2&&hs!==3)return-22;if(!(Ze&&He!==0&&typeof Ze.exports.wasm_syscall=="function"))return yt(-19,"no in-Worker kernel context to populate from the file");if((te&16)!==0)return yt(-19,"MAP_FIXED file mapping unsupported (the host bump allocator owns placement)");if(hs!==2&&(Te&2)!==0)return yt(-19,"writable MAP_SHARED (write-back) unsupported \u2014 fall back to read()/write()");let{addr:Gn,done:Ms,err:on,parked:lr,lost:zr,restarts:Xo}=Nu.map({mfd:ze,len:pt,prot:Te,flags:te,off:Xn});if(lr)return xb;if(Gn<0)return Gn;if(on!==0)return!zr&&!Rc(on)&&mi(11,Gn,pt,0,0,0,0),on===-38?yt(-19,"kernel pread64 unwired \u2014 this vmlinux predates the #72 kernel half"):on===-9?(mi(72,ze,3,0,0,0,0)|0)<0?-9:yt(-13,"fd not open for reading"):on===-29||on===-21||on===-22?yt(-19,`fd does not support positioned read (pread errno ${-on})`):yt(on,"pread64 population failed");if(hs!==2&&!Cu){Cu=!0;try{e({kind:"dmesg",level:4,text:`hwjs-mmap pid=${s[ce.PID]|0} MAP_SHARED read-only file mapping is an eager snapshot on wasm32 (no faults -> no coherence with later file writes; linux-in-the-browser#72)`})}catch{}}if(Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} MMAP-FILE fd=${ze} off=0x${Xn.toString(16)} len=0x${pt.toString(16)} populated=${Ms}B restarts=${Xo} -> 0x${(Gn>>>0).toString(16)}`})}catch{}return Gn|0}let st=!1;if(Tr!==null&&He!==0&&Ze&&typeof Ze.exports.wasm_syscall=="function"&&(u|0)>=0&&(u|0)>>0&256)He!==0&&we&&C&&typeof C.__hwjs_lane_attach=="function"&&globalThis.process?.env?.HWJS_EXPERIMENTAL_THREAD_CLONE!=="1"&&(st=!0);else if(u===fe||u===ge)st=!0;else if(u===j)He!==0&&(st=!0);else if(u===T)He!==0&&(st=!0);else if(u===bt||u===Ht||u===he||u===Pe||u===$e||u===W)He!==0&&(st=!0);else if(u===Sn||u===bn||u===Gs||u===zt||u===yn)He!==0&&(st=!0);else if(u===Ln)He!==0&&(st=!0);else if(u===Tn)He!==0&&(st=!0);else if(u===ms&&t.mode==="fork-resume")He!==0&&(st=!0);else if(u===tn||u===Hn||u===We||u===Se)He!==0&&(st=!0);else if(u===sn||u===ir)He!==0&&(st=!0);else if(u===ss)He!==0&&(st=!0);else if(u===ut||u===qe)He!==0&&(st=!0);else if(u===Yn||u===Dn||u===or)He!==0&&(st=!0);else if(u===Qt)He!==0&&(st=!0);else if(u===Pn||u===Qn||u===xs||u===Ws||u===An||u===Zn)He!==0&&(st=!0);else if(u===Lt||u===Pt)He!==0&&(st=!0);else if(u===Ne||u===vt||u===Tt)He!==0&&(st=!0);else if(u===Je)He!==0&&(st=!0);else if(u===Un){let te=!!nr.HWJS_RED_FCNTL_FDGATE;He!==0&&(!te||(Z|0)>=3||ts.has(Z|0))&&(st=!0)}else if(u===Vt){let te=!!nr.HWJS_RED_FLOCK_UNROUTED;He!==0&&!te&&(st=!0)}else if(u===rr||u===be)He!==0&&((Z|0)===0||(Z|0)>=3||ts.has(Z|0))&&(st=!0);else if(u===O||u===Ee)He!==0&&((Z|0)>=3||ts.has(Z|0))&&(st=!0);else if(u===ke)He!==0&&((Z|0)>=3||ts.has(Z|0))&&(st=!0);else if(u===Ns)He!==0&&(st=!0);else if(u===ar||u===$n||u===lt||u===et)He!==0&&(st=!0);else if(u===xt||u===Us||u===Cn||u===vn)He!==0&&(st=!0);else if(u===ws||u===Ss||u===Ya||u===In)He!==0&&(st=!0);else if(u>=Kr&&u<=fr||u===Ca)He!==0&&(st=!0);else if(u===mt||u===ot)He!==0&&(st=!0);else if(u===wt||u===Me||u===tt)He!==0&&(st=!0);else if(u===gn||u===pn)He!==0&&(st=!0);else if(u===ht||u===fn||u===Jt||u===Yt||u===Be||u===kn||u===bi||u===dn||u===Yr||u===Hi)He!==0&&(st=!0);else if(u===ko||u===Na)He!==0&&!_m&&(st=!0);else if(u===oe||u===_t||u===Kn||u===Le)He!==0&&(st=!0);else if(u===pi||u===Im||u===Gm||u===Wm){let te=!!nr.HWJS_RED_788081_UNROUTED;He!==0&&!te&&(st=!0)}else if(u===wm){let te=!!nr.HWJS_RED_88_SYSLOG_UNROUTED;He!==0&&!te&&(st=!0)}else if(u===Sm||u===Cm||u===km||u===Nm||u===Bm||u===Tm||u===Xm||u===Rm||u===Vm||u===xm||u===Ym){let te=!!nr.HWJS_RED_58_VFSMUT_UNROUTED;He!==0&&!te&&(st=!0)}else if(u===iy||u===oy||u===ay)He!==0&&(st=!0);else if(u===vm||u===Fm||u===Hm||u===Em){let te=!!nr.HWJS_RED_104_FSGAP_UNROUTED;He!==0&&!te&&(st=!0)}}if(st&&Tr!==null){let te=nr,Te=Z|0,ze=Te>=3||ts.has(Te);(u===rr||u===be)&&!(Te===0||ze)&&(st=!1),(u===O||u===Ee||u===ke)&&!ze&&(st=!1),u===56&&!(Z>>>0&256&&we&&C&&typeof C.__hwjs_lane_attach=="function"&&te.HWJS_EXPERIMENTAL_THREAD_CLONE!=="1")&&(st=!1),u===ms&&t.mode!=="fork-resume"&&(st=!1),te.HWJS_RED_FCNTL_FDGATE&&u===Un&&!ze&&(st=!1),te.HWJS_RED_FLOCK_UNROUTED&&u===Vt&&(st=!1),te.HWJS_RED_MMAP_FILE_UNPOPULATED&&(u===ko||u===Na)&&(st=!1),te.HWJS_RED_788081_UNROUTED&&(u===pi||u===Im||u===Gm||u===Wm)&&(st=!1),te.HWJS_RED_88_SYSLOG_UNROUTED&&u===wm&&(st=!1),te.HWJS_RED_58_VFSMUT_UNROUTED&&(u===Sm||u===Cm||u===km||u===Nm||u===Bm||u===Tm||u===Xm||u===Rm||u===Vm||u===xm||u===Ym)&&(st=!1),te.HWJS_RED_104_FSGAP_UNROUTED&&(u===vm||u===Fm||u===Hm||u===Em)&&(st=!1)}if(ed&&(u===bt||u===Ht||u===Pe||u===$e||u===W||u===O||u===rr||u===Ee||u===be||u===Tn)&&e({kind:"dmesg",level:6,text:`hwjs-fd pid=${s[ce.PID]|0} mode=${t.mode} PRE nr=${u|0}(a0=${Z|0},a1=${g|0},a2=${G|0}) route=${st?"KERNEL":"js-direct"} ptask=0x${(He>>>0).toString(16)} lowfds={${[...ts].join(",")}}`}),Kt)try{e({kind:"dmesg",level:6,text:`SYSTRACE pid=${s[ce.PID]|0} PRE nr=${u|0} route=${st?"K":"js"} a0=0x${(Z>>>0).toString(16)} a1=0x${(g>>>0).toString(16)}`})}catch{}if(st){let te=!1;u===fe||u===ge?te=(u===ge?g|0:Z|0)===(t.tid|0):u===j&&(te=(Z|0)===(t.pid|0));try{if(!P&&Ze&&typeof Ze.exports.__wasm32_set_libc_park_abi=="function")try{Ze.exports.__wasm32_set_libc_park_abi(ee?1:0),P=!0}catch{}if(nr.A4C_FORKDBG)try{e({kind:"dmesg",level:6,text:`[a4c-sys tid=${t.tid}] PRE nr=${u|0}`})}catch{}let Te=nm(u,Z,g,G,S,Y,v);if(xr[u|0]=(xr[u|0]|0)+1,nr.A4C_FORKDBG)try{e({kind:"dmesg",level:6,text:`[a4c-sys tid=${t.tid}] nr=${u|0} -> ${Te|0}`})}catch{}let ze=J(u);if((Te|0)===an&&re(u)){if(!Tu&&ee&&!yc.has(u|0)){Tu=!0;try{e({kind:"dmesg",level:6,text:`hwjs-coopwait VENEER-PARK pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode}: syscall nr=${u|0} block-parked and this image absorbs -517 at raw veneers (__hwjs_libc_syscall_park_abi=1) \u2014 the CPU Worker was handed back instead of spun on synchronously`})}catch{}}return an}if((Te|0)===an){if(ze&&(Br++,(Br&Br-1)===0)){let Ms=`hwjs-coopwait SYNC-RESTART pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode}: syscall nr=${u|0} block-parked (-517) but this image's libc does not absorb the sentinel at raw syscalls (__hwjs_libc_syscall_park_abi ${ee?"=1":"absent"}, hwjsDrive=${x?1:0}), so the host must restart it in place on a SYNCHRONOUS wait \u2014 freezing this CPU Worker's event loop, and with it every co-resident task, for the duration. Occurrences so far: ${Br} (PLAN-THREAD-POOL-RESIDENCY contract 3; loud, attributed).`;try{e({kind:"dmesg",level:4,text:Ms})}catch{}}if(He===0||Vs===null)return e({kind:"error",pid:t.pid,message:`HWJS-A-4: syscall nr=${u|0} returned -ERESTART_RESCHED but no kernel task_struct is reachable (perProcessTaskAddr=0x${(He>>>0).toString(16)}, kernelMem=${Vs?"present":"absent"}) \u2014 cannot yield for the in-flight completion; refusing to spin.`}),-38;let yt=0,Gn=Dt?Ko(e,{cpu:t.cpuId,pid:s[ce.PID]|0,tid:t.tid,site:"sync-restart",label:`wasm_syscall:${u|0}`,announce:!1,fields:o(Ms=>`restarts=${Ms}`,"fields")}):Pi;for(;(Te|0)===an;){if(++yt>Xt)return e({kind:"error",pid:t.pid,message:`HWJS-A-4: syscall nr=${u|0} restarted ${yt} times still returning -ERESTART_RESCHED \u2014 the task never became runnable (FUSE/blocking completion never landed). Aborting the restart loop loudly rather than hanging.`}),-4;ny(`wasm_syscall nr=${u|0}`),Dt&&Gn.tick(yt),de(),Te=nm(u,Z,g,G,S,Y,v)}Dt&&Gn.end(yt)}if((u|0)===T){let yt=Te|0;Jf?yt===-10?ci=!1:yt>=0&&(ci=!0):yt===-10||yt===0?ci=!1:yt>0&&(ci=!0)}let pt=Te|0;if(pt>=0){if(u===Pe||u===$e){let yt=Z|0,Gn=g|0;Gn>=0&&Gn<=2&&(yt>=3||ts.has(yt)?ts.add(Gn):ts.delete(Gn))}else if(u===he){let yt=Z|0,Gn=pt;Gn>=0&&Gn<=2&&(yt>=3||ts.has(yt)?ts.add(Gn):ts.delete(Gn))}else if(u===W){let yt=Z|0;yt>=0&&yt<=2&&ts.delete(yt)}else if(u===Ne||u===vt||u===Tt||u===Un){let yt=u===Un&&((g|0)===0||(g|0)===1030);!nr.HWJS_RED_LOWFD_OPEN&&(u!==Un||yt)&&pt>=0&&pt<=2&&ts.add(pt)}}ed&&(u===bt||u===Ht||u===Pe||u===$e||u===W||u===O||u===Ee||u===be||u===rr)&&e({kind:"dmesg",level:6,text:`hwjs-fd pid=${s[ce.PID]|0} POST nr=${u|0} -> ret=${Te|0} lowfds={${[...ts].join(",")}}`});let Xn=pt<=-512&&pt>=-516;if((te&&pt===0||Xn)&&as>=0){let yt=as+2,Gn=Atomics.load(ct(),yt)|0;po()||Atomics.wait(ct(),yt,Gn,100)}if(tr&&yo(` -> [kern] nr=${u} ret=${Te|0} `),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} RET nr=${u|0} route=KERNEL ret=${Te|0}`})}catch{}return Te|0}catch(Te){let ze=Te instanceof Error?Te.message:String(Te),pt=Te instanceof Error&&Te.stack?` WASM-SYSCALL-STACK: `+Te.stack.split(` `).slice(0,32).join(" | "):"",Xn=f(`wasm_syscall nr=${u|0}`);if(Xn!==0&&++N<=K){let hs=Te instanceof Error&&Te.stack?Te.stack.split(` `).slice(0,16).map(yt=>yt.trim()).join(" | "):ze.split(` `)[0];return e({kind:"dmesg",level:3,text:`hwjs #85 CONTAINMENT pid=${t.pid}: wasm_syscall nr=${u|0} trapped on a POISONED LANE; lane reclaimed (mask=${Xn}), returning -EINTR to the caller (containment ${N}/${K} for this Worker) \u2014 the trapped in-flight chain's frames are leaked, attributed. The dirt is USUALLY a thread Worker that died mid-protocol on this lane (#85), but it is equally a coroutinized callee published under a NATIVE caller, and only the stack tells them apart: ${hs}`}),-4}return e({kind:"error",pid:t.pid,message:"K11-B5/B6: vmlinux.wasm_syscall trapped at nr="+(u|0)+": "+ze+pt}),-38}}if(Ci!==null){let te=Ci;if(!(te.nr===(u|0)&&te.a0===(Z|0)&&te.a1===(g|0)&&te.a2===(G|0)&&te.a3===(S|0)&&te.a4===(Y|0)&&te.a5===(v|0))){Ci=null,Atomics.store(s,ce.STATE,Gi);try{e({kind:"dmesg",level:3,text:`hwjs-merged DEFERRED-RPC MISMATCH pid=${s[ce.PID]|0} tid=${t.tid|0}: nr=${te.nr} was in flight on the merged lane and the guest came back asking nr=${u|0} instead. A -517 park is only correct if the libc RE-ISSUES THE SAME CALL; this libc did not, so the answer in the control SAB belongs to a question nobody is asking any more. Refusing with -ENOSYS rather than handing it over.`})}catch{}return-38}if(Atomics.load(s,ce.STATE)===Uo){let ze=s[ce.RET_LO]|0;if(Atomics.store(s,ce.STATE,Gi),Ci=null,Vf++,tr&&yo(` -> [sab/merged] nr=${u} ret=${ze} `),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} RET nr=${u|0} route=host-RPC/deferred ret=${ze|0} parks=${te.parks}`})}catch{}return ze}if(++te.parks>Bu)return Ci=null,Atomics.store(s,ce.STATE,Gi),e({kind:"error",pid:t.pid,message:`hwjs-merged DEFERRED-RPC UNANSWERED pid=${s[ce.PID]|0} tid=${t.tid|0}: host-RPC nr=${u|0} was issued on the merged CPU-0 lane and re-checked across ${Bu} cooperative parks without the responder ever writing an answer. The thread WAS handed back on every one of them, so this is not the merged deadlock \u2014 the responder itself never ran or never answered. Returning -EINTR rather than parking forever.`}),-4;if(xu++,(te.parks&te.parks-1)===0&&te.parks>=64)try{e({kind:"dmesg",level:4,text:`hwjs-merged DEFERRED-RPC SLOW pid=${s[ce.PID]|0} tid=${t.tid|0}: host-RPC nr=${u|0} still unanswered after ${te.parks} cooperative parks (${Date.now()-te.t0}ms). The thread was handed back on every one of them, so the responder had its turn and did not answer.`})}catch{}return an}Atomics.store(s,ce.NR,u|0),Atomics.store(s,ce.A0,Z|0),Atomics.store(s,ce.A1,g|0),Atomics.store(s,ce.A2,G|0),Atomics.store(s,ce.A3,S|0),Atomics.store(s,ce.A4,Y|0),Atomics.store(s,ce.A5,v|0),Atomics.store(s,ce.STATE,tl);let Jm=!1;if(t.mergedCpu0Lane===!0&&Ps!==null){let te;try{te=Ps(Tf)}catch{te=void 0}if(te==="sync"&&Atomics.load(s,ce.STATE)===Uo){let Te=s[ce.RET_LO]|0;if(Atomics.store(s,ce.STATE,Gi),xf++,tr&&yo(` -> [sab/merged-sync] nr=${u} ret=${Te} `),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} RET nr=${u|0} route=host-RPC/in-place ret=${Te|0}`})}catch{}return Te}te==="async"&&(Jm=!0,Bf++)}if(Jm||e({kind:"syscall",pid:t.pid}),t.mergedCpu0Lane===!0){if(!re(u)){if(Xa++,(Xa&Xa-1)===0)try{e({kind:"dmesg",level:3,text:`hwjs-merged REFUSED a host-RPC syscall on the merged CPU-0 lane: nr=${u|0} pid=${s[ce.PID]|0} tid=${t.tid|0}. The responder runs on the launching thread and this lane shares it, so the answer can only be produced by a thread this lane would be holding. The merged route out of that is the cooperative -517 park, and THIS IMAGE CANNOT TAKE ONE at this veneer (__hwjs_libc_syscall_park_abi ${ee?"=1":"absent"}, hwjsDrive=${x?1:0}, cancellable=${yc.has(u|0)?"yes":"no"}) \u2014 so it would fall into the in-place restart loop, whose wait is a thread-blocking Atomics.wait. Returning -ENOSYS instead of a livelock (occurrence ${Xa}). What fixes this is the libc absorbing -517 at raw veneers, not a change here.`})}catch{}return Atomics.store(s,ce.STATE,Gi),-38}return Ci={nr:u|0,a0:Z|0,a1:g|0,a2:G|0,a3:S|0,a4:Y|0,a5:v|0,parks:0,t0:Date.now()},xu++,an}{let ze=Date.now(),pt=ze+1e4;for(;Atomics.load(s,ce.STATE)!==Uo&&(Atomics.wait(s,ce.STATE,tl,250),Atomics.load(s,ce.STATE)!==Uo);)if(Date.now()>=pt){pt=Date.now()+1e4;let Xn=`hwjs-hostrpc STALL pid=${s[ce.PID]|0} tid=${t.tid|0} lane=${t.userLane??0} mode=${t.mode}: host-RPC syscall nr=${u|0} unanswered after ${Date.now()-ze}ms. This lane is blocked in the control SAB, which no signal, pause or fork servicer can wake \u2014 only the host's answer can. On a pool Worker that blocks every co-resident task and the message loop for the duration (loud, attributed, never a silent wedge).`;try{e({kind:"dmesg",level:4,text:Xn})}catch{}}}let Vd=s[ce.RET_LO]|0;if(Atomics.store(s,ce.STATE,Gi),tr&&yo(` -> [sab] nr=${u} ret=${Vd} `),Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} RET nr=${u|0} route=host-RPC ret=${Vd|0}`})}catch{}return Vd}o(mi,"syscallInner");let Ze=null,He=0,wd=null,Sd=null,ft=null,Tr=null;if(t.vmlinuxModule){let u=await Xc(t,e);if(!u){e({kind:"dmesg",level:3,text:`hwjs#65: spawn refused \u2014 per-Worker vmlinux/task-alloc failed (tid=${t.tid|0} ppid=${t.ppid|0} cpu=${t.cpuId|0}); the user binary will NOT run (a task with no registered kernel pid must never issue syscalls \u2014 R-K11.6-W1 closed structurally)`});return}{if(Ze=u.instance,He=u.perProcessTaskAddr|0,ft=u.hwjsLane||null,typeof Ze.exports.wasm32_syscall_implemented=="function"&&typeof Ze.exports.wasm32_syscall_table_size=="function")try{let Z=Ze.exports.wasm32_syscall_table_size()|0;if(Z>0&&Z<=4096){let g=new Uint8Array(Z),G=0;for(let S=0;S>>0;Z!==0&&(wd=Z-(He>>>0)|0)}catch{}if(typeof Ze.exports.__hwjs_task_park_deadline_addr=="function"&&He!==0&&Vs!==null)try{let Z=Ze.exports.__hwjs_task_park_deadline_addr()>>>0;Z!==0&&(Z&3)===0&&(Sd=Z-(He>>>0)|0)}catch{}typeof u.kernelPid=="number"&&u.kernelPid>0&&(s[ce.PID]=u.kernelPid|0,t.mode!=="thread"&&(s[ce.TID]=u.kernelPid|0))}}let kd=4,hm=15,Xd=1,sr=Xd,bm=-1,pm=o(u=>Math.max(Xd,u/2),"coopWaitDecay"),fm=o(()=>{sr=Xd},"coopWaitEpisodeReset"),Rd=o(()=>wd===null||He===0||Vs===null?-1:(He>>>0)+wd>>>2,"taskWakeIdx"),Qf=!!(globalThis.process?.env?.HWJS_NO_STATE_WAKE||globalThis.HWJS_NO_STATE_WAKE),Df=o(()=>Qf||He===0||Vs===null?-1:(He>>>0)+$Z>>>2,"taskStateIdx"),$f=!!(globalThis.process?.env?.HWJS_NO_PARK_DEADLINE||globalThis.HWJS_NO_PARK_DEADLINE),qf=o(u=>{if($f||Sd===null||He===0)return 0;let Z=(He>>>0)+Sd>>>2,g=Atomics.load(u,Z)>>>0;return((Atomics.load(u,Z+1)>>>0)*4294967296+g)/1e6},"taskParkDeadlineMs"),ym=o(()=>performance.timeOrigin+performance.now(),"hostNowMs");async function ey(u){De&&De.coopWaits++;let Z=Rd();if(zu()&&(ci=!0),po())return;if(Z<0){if(He===0||Vs===null)throw new Error(`${u}: -ERESTARTRESCHED but no kernel task_struct/wake word is reachable (perProcessTaskAddr=0x${(He>>>0).toString(16)}, kernelMem=${Vs?"present":"absent"}) \u2014 refusing to spin.`);await new Promise(T=>setTimeout(T,sr)),sr=Math.min(hm,sr*2),Ba();return}sd!==bm&&(sr=pm(sr));let g=xa(),G=Atomics.load(g,Z)|0,S=qf(g),Y=S>0?S-ym():1/0,v=Y=1&&(j=await Bb(g,Z,G,L,Math.floor(Y))):j=await Bb(g,Z,G,L,sr),v&&j==="timed-out"){let T=L>=0?Atomics.load(g,L)|0:0;for(;ym()=0&&(Atomics.load(g,L)|0)!==T||po()){j="ok";break}await Ls()}}}catch{j="ok"}(!v||j!=="timed-out")&&(sr=j==="timed-out"?Math.min(hm,sr*2):pm(sr)),bm=sd,Ba()}o(ey,"coopWaitRunnable");let Zm=250;async function ty(){let u=os;if(!u||fo())return;let Z=u.deadlineMs===1/0?Zm:Math.max(1,u.deadlineMs-Date.now()),g=Math.min(Z,Zm),G=ct();if(Atomics.load(G,u.i32idx)!==u.val)return;let S=Atomics.waitAsync(G,u.i32idx,u.val,g);if(S.async)try{await S.value}catch{}}o(ty,"coopFutexWait");function ny(u){if(De&&De.reschedRestarts++,He===0||Vs===null)throw new Error(`${u}: -ERESTARTRESCHED but no kernel task_struct is reachable (perProcessTaskAddr=0x${(He>>>0).toString(16)}, kernelMem=${Vs?"present":"absent"}).`);if(zu()&&(ci=!0),po())return;let Z=Rd();if(Z>=0){let Y=xa(),v=Atomics.load(Y,Z)|0;Atomics.wait(Y,Z,v,kd),Ba();return}let g=He>>>0>>>2,G=xa(),S=Atomics.load(G,g)|0;Atomics.wait(G,g,S,kd),Ba()}o(ny,"awaitReschedRunnable");function sy(){if(He===0||Vs===null)return;let u=Rd(),Z=u>=0?u:He>>>0>>>2,g=xa();Atomics.wait(g,Z,Atomics.load(g,Z)|0,kd)}o(sy,"awaitTaskWakeSlice");let wn={env:{user_memory:t.memory,__hwjs_xmod_dispatch_check:o((u,Z)=>ai(u,Z,!0,!1,!0),"__hwjs_xmod_dispatch_check"),__hwjs_register_fpcast_adapter:o((u,Z,g,G,S)=>Ye(u,Z,g,G,S),"__hwjs_register_fpcast_adapter"),__hwjs_fpcast_adapter_lookup:o((u,Z)=>Wt(u,Z),"__hwjs_fpcast_adapter_lookup"),__hwjs_fpcast_target_sig_lookup:o(u=>qt(u),"__hwjs_fpcast_target_sig_lookup")},linux:{syscall:Go},hwjs_suspend:{park:o(()=>{},"park")}};{let u=t.kernelMemoryWasm??t.kernelMemory;u&&(wn.env.kernel_memory=u)}let gm=new Set(Object.keys(wn.env)),Jn=t.wasmBytes,hi=null,ry=o(()=>({pid:s[ce.PID]|0,tid:t.tid|0,mode:t.mode==="thread"?"thread":"fork",cpuId:t.cpuId|0,userLane:t.userLane|0,poolResident:!!n,image:{byteLength:Jn?Jn.length:0,path:hi},drive:{hwjsDrive:x,hwjsFlat:ie,libcParksAnySyscall:ee},hwjsRt:B?{moduleId:B.moduleId|0,memoryBase:B.memoryBase>>>0,tableBase:B.tableBase>>>0,tableSize:B.tableSize>>>0}:null,libcSo:$?{digest:$.digest,checkEmitting:!!$.checkEmitting,laneAddressed:!!$.laneAddressed}:null,dlopen:{open:[...kt].map(([u,Z])=>({cookie:u>>>0,moduleId:Z.moduleId|0,path:Z.path||"",byteLength:Z.bytes?Z.bytes.length:0,memoryBase:Z.memoryBase>>>0,tableBase:Z.tableBase>>>0})),deadRanges:gt.length,nextCookie:Ot>>>0,tableLen:at instanceof WebAssembly.Table?at.length>>>0:0},wasmSyscallStats:{...xr},asyncifyHighWaterBytes:_n|0,coopWaitViolations:pr|0,syncRestartViolations:Br|0,lane:ft?{...ft.census}:null,isolateModuleCaches:jb()}),"buildTaskProbe");{let u=Xi.get(t);u&&(u.probe=ry)}let en=!0;e:for(;;){let u=-1;if(!en){for(let O of Object.keys(wn.env))gm.has(O)||delete wn.env[O];delete wn["GOT.mem"],delete wn["GOT.func"],at=null,un=null,xn=null,zn=new Map}let Z=null;if(!en){let O=si(Jn,"exec re-instantiate");if(O<0)Z=`user_memory cannot fit the exec image (errno ${O})`;else{if(Kt)try{e({kind:"dmesg",level:6,text:`EXEC-WIPE: pid=${t.pid} mode=${t.mode} lane=${t.userLane??"?"} wiping user_memory (${t.memory.buffer.byteLength}B) for exec re-instantiate of ${Jn.length}B image`})}catch{}if(new Uint8Array(t.memory.buffer).fill(0),Kt)try{e({kind:"dmesg",level:6,text:`EXEC-LOAD-DIAG: imageLoop re-instantiate; compiling ${Jn.length}B`})}catch{}}}let g=o(O=>{try{let ke=Array.isArray(Gt)&&Gt.length>0?String(Gt[0]):"exec",be=new TextEncoder().encode(`${ke}: ${O} `),Ee=65536,Je=new Uint8Array(t.memory.buffer);if(Je.length{let be=`hardwarejs#6: user image ${en?"spawn":"exec"} ${O} failed (${Jn.length}B image, user_memory ${Math.floor(t.memory.buffer.byteLength/65536)} pages): ${ke instanceof Error?ke.message:String(ke)}`;return en?(await m(127,0),e({kind:"error",pid:t.pid,message:be}),"return"):(g(be),e({kind:"user-report",pid:t.pid,message:`${be} \u2014 killing pid ${t.pid} with exit 127 (guest reaps; never a silent hang)`}),d=127,"break")},"imageStageFatal"),S,Y,v;try{Nr(t,e,`image-compile-begin bytes=${Jn.length}`),{module:S,key:Y,cached:v}=await ag(Jn),Nr(t,e,`image-compile-end cached=${v?1:0}`)}catch(O){if(await G("COMPILE",O)==="return"){jn("error");return}break e}try{e({kind:"dmesg",level:6,text:`HWJS-A5-IMGCACHE pid=${t.pid} ${v?"HIT ":"COMPILE"} len=${Jn.length} key=${Y} compiles=${Vc} hits=${ml} cacheSize=${Hs.size}`})}catch{}if(!en&&Kt)try{e({kind:"dmesg",level:6,text:"EXEC-LOAD-DIAG: re-instantiate compiled; instantiating"})}catch{}{let O=WebAssembly.Module.imports(S).find(ke=>ke.kind==="table");if(O){let ke=Nh(Jn)||{min:0,max:void 0};if(at=new WebAssembly.Table({initial:ke.min>>>0,...ke.max!==void 0?{maximum:ke.max>>>0}:{maximum:1<<20},element:"anyfunc"}),un=new Map,xn=new Map,Wi(t.mode)&&en&&t.dlopenFork&&Array.isArray(t.dlopenFork.gotFunc))for(let[be,Ee]of t.dlopenFork.gotFunc)un.set(String(be),Ee>>>0);(wn[O.module]??={})[O.name]=at;for(let be of WebAssembly.Module.imports(S))be.kind==="global"&&(be.name==="__memory_base"?(wn[be.module]??={})[be.name]=new WebAssembly.Global({value:"i32",mutable:!1},0):be.name==="__table_base"?(wn[be.module]??={})[be.name]=new WebAssembly.Global({value:"i32",mutable:!1},0):be.name==="__stack_pointer"&&((wn[be.module]??={})[be.name]=new WebAssembly.Global({value:"i32",mutable:!0},0)))}}Ie=null,B=null,ae=null,Ce=null,Q=null,$=null,_e=[],pe=[],Ut=[],C=null,rt=!1,Qe=0,It=[],Ct=[];let L=null,j=[];{let O;try{O=$d(Jn)}catch(ke){if(await G("NEEDED-PARSE",ke)==="return"){jn("error");return}break e}if(O&&O.needed.length>0)try{let ke=O.needed[0],be=Cr(ke);if(!rs.has(be))throw new Error(`hwjs-libc: the image needs /lib/${ke.slice(0,24)}\u2026 but no shared library of that digest was delivered to this Worker (store has ${rs.size} digest(s)) \u2014 the kernel LIBC_STAGE hand-off did not run or delivered a different generation (never-silent loud exec failure).`);L={name:ke,digest:be,suspendersSha256:O.suspendersSha256};for(let Ee=1;Eebe.module==="env"&&be.kind==="function"&&be.name==="__hwjs_frame_alloc");if(L&&!ke)throw new Error("hwjs-libc: the image carries wasm.linux.needed but does not import the hwjs runtime (env.__hwjs_frame_alloc) \u2014 a dynamic-libc main is rt-importing by construction; refusing a foreign shape (never-silent).");if(ke){if(WebAssembly.Module.exports(S).some(We=>We.name==="__hwjs_frame_alloc"))throw new Error("hwjs-rt: DOUBLE PROVISION refused \u2014 the main both LINKS its own hwjs runtime (exports __hwjs_frame_alloc) and IMPORTS the kernel-provided one. One runtime provider per process (PLAN-HWJS-RT-PSABI); relink the main.");if(L){let We=new Set(WebAssembly.Module.exports(S).filter(Se=>Se.kind==="function").map(Se=>Se.name));for(let Se of["__libc_start_main","malloc"])if(We.has(Se))throw new Error(`hwjs-libc: DOUBLE PROVISION refused \u2014 the main names ${L.name.slice(0,24)}\u2026 in wasm.linux.needed but also EXPORTS the libc anchor "${Se}" (a statically linked libc). One libc provider per process (PLAN-DYNAMIC-LIBC \xA73.4); relink the main.`)}if(!t.hwjsRtModule||!t.hwjsRtBytes)throw new Error("hwjs-rt: the main imports the hwjs runtime ops but this kernel ships no libhwjs-rt (no verified hwjs.rt.so section) \u2014 a runtime-importing dynamic main cannot run on a kernel image with no embedded rt (never-silent).");let be=t.hwjsRtBytes,Ee=t.hwjsRtModule;if(Qe===4){let We=t.vmlinuxModule?WebAssembly.Module.customSections(t.vmlinuxModule,"hwjs.rt4.so"):[];if(We.length!==1)throw new Error(`hwjs-rt: this main is drive_abi=4 (status channel) but the kernel ships ${We.length}x hwjs.rt4.so section(s) \u2014 an abi-4 dynamic main cannot run against the flat runtime (its leaf parks would silently transit; I3). Rebuild the kernel packaging (scripts/build-hwjs-rt.sh status-channel twin); never-silent.`);be=new Uint8Array(We[0]),Ee=ki(be).module;let Se=WebAssembly.Module.customSections(Ee,"hwjs.rt.provenance"),qe=Se.length===1?new TextDecoder().decode(Se[0]).trim():null,ut=typeof t.hwjsRtProvenance=="string"?t.hwjsRtProvenance.trim():null;if(!qe||!ut||qe!==ut)throw new Error("hwjs-rt: the status-channel runtime twin's embedded RT-PROVENANCE does not match the boot-verified attestation (mixed/stale kernel packaging) \u2014 refusing the runtime (never-silent).")}if(!at)throw new Error("hwjs-rt: the runtime-importing main does not import the shared table \u2014 not a dynamic main; refusing.");let Je=wn.env??={};Je.__stack_pointer instanceof WebAssembly.Global||(Je.__stack_pointer=new WebAssembly.Global({value:"i32",mutable:!0},0));let Ne=Ze?Ze.exports:null,vt=o((We,Se)=>(...qe)=>{let ut=C&&C[We];if(typeof ut!="function"){if(We==="__hwjs_lane_id"&&!C)return Mi(t,en);throw new Error(`hwjs-rt: ${Se||"rt"} import env.${We} is unresolved \u2014 `+(C?`the main image is instantiated and exports no function "${We}", which is a link defect in the main image itself`:"the main image is NOT INSTANTIATED YET, so this call came from a load-time constructor of the runtime, libc.so or a needed library, and the main's export table is not the fault")+" (never-silent).")}return ut(...qe)},"lateGeneric"),Tt=o((We,Se)=>{let qe=vt(We,Se);if(We!=="__hwjs_lane_id")return qe;pc||(pc=new WebAssembly.Module(EZ));let ut=new WebAssembly.Instance(pc,{e:{f:qe}}).exports;return Ct.push(ut),ut.lane},"late"),Lt=o((We,Se,qe)=>{if(qe==="function"&&We==="linux"&&Se==="syscall"){let ut=wn.linux&&wn.linux.syscall;if(typeof ut!="function")throw new Error("hwjs-rt: rt imports linux.syscall but the process import object carries none (never-silent).");return ut}if(!(qe!=="function"||We!=="env")){if(Se==="__hwjs_xmod_dispatch_check")return(ut,Yn)=>ai(ut,Yn,!0,!0);if(Rr.has(Se)){if(hn[Se])return hn[Se];let ut=Ne?Ne[Se]:void 0;if(typeof ut=="function")return ut;throw new Error(`hwjs-rt: rt import env.${Se} is KERNEL-owned but vmlinux does not export it (never-silent).`)}return hr.has(Se)?Ar(Se,"the hwjs runtime module (#0)"):Tt(Se,"the hwjs runtime module (#0)")}},"rtResolveImport"),Pt=Wi(t.mode)&&en&&t.dlopenFork&&t.dlopenFork.hwjsRt||null;if(Pt){let We=(Pt.tableBase>>>0)+(Pt.tableSize>>>0);at.length>>0!==Tn||t.hwjsRtWindowSize>>>0!==Ji)throw new Error(`hwjs-rt (\xA76.4): reserved-window DIVERGENCE \u2014 host computed base=0x${(t.hwjsRtWindowBase>>>0).toString(16)} size=0x${(t.hwjsRtWindowSize>>>0).toString(16)}, worker derived base=0x${Tn.toString(16)} size=0x${Ji.toString(16)} \u2014 the duplicated constants (BRK_RESERVE / HWJS_RT_WINDOW_SIZE / page size) drifted between kernelSpawnHandler.ts and dynLoader.mjs (never-silent).`)}Pn=Tn+Ji>>>0,Vt=Pn-Qd>>>0,Un=Tn,t.memory.buffer.byteLength{let qe=Math.max(Se>>>0||1,16),ut=Un+(qe-1)&~(qe-1),Yn=We>>>0;if(!(ut>=Tn)||ut+Yn>Vt)throw new Error(`hwjs-rt (\xA76.4): rt data region does NOT fit the reserved window \u2014 need ${Yn}B (align ${qe}) at 0x${ut.toString(16)}, window [0x${Tn.toString(16)}, 0x${Pn.toString(16)}) minus the top 65536B rt shadow-stack carve (usable end 0x${Vt.toString(16)}). Raise HWJS_RT_WINDOW_SIZE (src/dynLoader.mjs + src/kernelSpawnHandler.ts, in lockstep) (never-silent fit check).`);return Un=ut+Yn,ut>>>0},"rtWinAlloc"),xs=Pt?Pt.spTop>>>0:Pn>>>0;Je.__stack_pointer.value=xs|0,Ce=Je.__stack_pointer;let Zn=Pt?Pt.tableBase:at.length,Ws=Pt?Pt.moduleId|0:Ne&&typeof Ne.__hwjs_alloc_module_id=="function"?Ne.__hwjs_alloc_module_id()|0:0,An;An=Li({wasmBytes:be,memory:t.memory,table:at,moduleId:Ws,soPath:"the hwjs runtime module (#0)",compileModule:o(()=>Ee,"compileModule"),...Qe===4?{mainDriveAbi:4,mainLaneAddressed:we}:{},resolveImport:Lt,resolveDataAddress:o(()=>{},"resolveDataAddress"),gotFuncIndex:un,stackPointer:Je.__stack_pointer,parkImport:o(()=>{},"parkImport"),deferGotFunc:new Set(["hwjs_resume","hwjs_done","hwjs_destroy","__hwjs_drive_abi","__hwjs_user_park"]),...Pt?{fixedMemoryBase:Pt.memoryBase>>>0,fixedTableBase:Pt.tableBase>>>0,skipDataRelocs:!0,seedSymbolIndices:Array.isArray(Pt.appended)?Pt.appended:[]}:{allocMemory:Qn}}),Mt(An),Pt||An.runCtors(),Ie=An.instance??An,ae=An,B={memoryBase:An.memoryBase>>>0,tableBase:Zn>>>0,tableSize:at.length-Zn>>>0,moduleId:Ws|0,spTop:xs>>>0,appended:An.tableEntries()};let tn=(An.instance??An).exports;if(!(t.mode==="thread"||(t.mode==="fork-resume"||t.mode==="migrate-resume")&&en)&&typeof tn.__hwjs_lane_attach=="function"){let Se=Mi(t,en)|0;if(!(typeof tn.__hwjs_lane_occupied=="function"?tn.__hwjs_lane_occupied(Se)|0:0)){typeof tn.__wasm32_set_lane_id=="function"&&tn.__wasm32_set_lane_id(Se);let ut=tn.__hwjs_lane_attach(Se)|0;if(ut<=0)throw new Error(`hwjs-lanes: PRE-MAIN lane-${Se} attach REFUSED (rc=${ut}) on the rt instance \u2014 -11 is out of lane slots, -12 out of memory for lane state. The needed-graph constructors run next and every lane-keyed op inside them would violate on an unoccupied lane. Refusing to drive (never-silent).`);u=Se}}if(L){let We=rs.get(L.digest);We.module||(We.module=ki(We.bytes,L.digest).module);let Se;try{if(Se=Jo(We.bytes),!Se||Se.manifestVersion<2||!Se.suspenderDigestLo64)throw new Error(`hwjs-libc: staged libc.so (digest ${L.digest.slice(0,16)}\u2026) carries no v2 hwjs.abi suspender-partition digest \u2014 an older or foreign artifact cannot back a needed-main (never-silent).`);let Me=L.suspendersSha256.slice(0,16);if(Se.suspenderDigestLo64!==Me)throw new Error(`hwjs-libc: SUSPENDER-PARTITION DIGEST SKEW \u2014 the main was linked against partition ${Me}\u2026 but the staged libc.so's hwjs.abi records ${Se.suspenderDigestLo64}\u2026 (a main linked against partition N running against libc.so M; PLAN-DYNAMIC-LIBC \xA73.2). Refusing to instantiate (never-silent).`);let tt=!!(Se.flags&&Se.flags.checkEmitting);if(tt!==rt)throw new Error(`hwjs-libc: CHECK-EMITTING MISMATCH \u2014 the main attests check_emitting=${rt?1:0} but the staged libc.so (digest ${L.digest.slice(0,16)}\u2026) attests check_emitting=${tt?1:0} (hwjs.abi flags bit4). Mixing check-emitting and non-check-emitting modules lets a status-channel raise transit an uninstrumented frame SILENTLY (PLAN-CXX-STATUS-CHANNEL \xA77, I3). Relink the pair in lockstep (never-silent).`);let gn=!!(Se.flags&&Se.flags.laneAddressed);if(gn!==we)throw new Error(`hwjs-libc: LANE-ADDRESSED MISMATCH \u2014 the main attests lane_addressed=${we?1:0} but the staged libc.so (digest ${L.digest.slice(0,16)}\u2026) attests lane_addressed=${gn?1:0} (hwjs.abi flags bit5). Mixing a lane-addressed module with a lane-unaware one lets the lane-unaware side read LANE 0's status word from ANY lane \u2014 silent transit under threads (I3-2; PLAN-THREADS-SINGLE-MEMORY \xA74 step 2). Relink the pair in lockstep (never-silent).`)}catch(Me){if(await G("LIBC-STAGE",Me)==="return"){jn("error");return}break e}let qe=Wi(t.mode)&&en&&t.dlopenFork&&t.dlopenFork.libcSo||null;qe&&eb(qe,L.digest);let ut=0,Yn=0,Dn=0;if(qe){let Me=(qe.tableBase>>>0)+(qe.tableSize>>>0);at.length>>0!==ut||t.hwjsLibcWindowSize>>>0!==Eo)throw new Error(`hwjs-libc: reserved-window DIVERGENCE \u2014 host computed base=0x${(t.hwjsLibcWindowBase>>>0).toString(16)} size=0x${(t.hwjsLibcWindowSize>>>0).toString(16)}, worker derived base=0x${ut.toString(16)} size=0x${Eo.toString(16)} \u2014 the duplicated constants drifted between kernelSpawnHandler.ts and dynLoader.mjs (never-silent).`)}Dn=ut+Eo>>>0,Yn=ut,t.memory.buffer.byteLength{let gn=Math.max(tt>>>0||1,16),pn=Yn+(gn-1)&~(gn-1),_t=Me>>>0;if(!(pn>=ut)||pn+_t>Dn)throw new Error(`hwjs-libc: libc.so data region does NOT fit the reserved window \u2014 need ${_t}B (align ${gn}) at 0x${pn.toString(16)}, window [0x${ut.toString(16)}, 0x${Dn.toString(16)}). Raise HWJS_LIBC_WINDOW_SIZE (src/dynLoader.mjs + src/kernelSpawnHandler.ts, in lockstep) (never-silent fit check).`);return Yn=pn+_t,pn>>>0},"libcWinAlloc"),Qt=new Set(WebAssembly.Module.exports(We.module).filter(Me=>Me.kind==="function").map(Me=>Me.name)),ar=new Set(WebAssembly.Module.exports(S).filter(Me=>Me.kind==="function").map(Me=>Me.name)),$n=null,lt=o(Me=>{let tt=ar.has(Me)?"main":Qt.has(Me)?"self":null;if(!tt){if($n??=(_i(We.bytes)||{}).weakImports||new Map,$n.get(Me)==="env")return;throw new Error(`hwjs-libc: unresolved import env.${Me} (function) in libc.so (module #1) \u2014 the runtime (module #0) does not export it, the main image does not export it, and libc.so does not define it either, so NOTHING in this process can ever provide it. Refusing the load (never-silent): the alternative is a binding that throws at whatever guest call site reaches it first, which is where this class used to surface.`)}let gn=null,pn=o(()=>{let _t=tt==="main"?C||null:Q?(Q.instance??Q).exports:null,Kn=_t?_t[Me]:void 0;if(typeof Kn!="function")throw new Error(`hwjs-libc: libc.so's preemptible import env.${Me} was resolved at load to the ${tt==="main"?"MAIN image":"libc.so self-definition"} (ELF search order), but that provider has no function export "${Me}" now that it exists \u2014 the load-time census and the live instance disagree (never-silent).`);return Kn},"provider");return function(_t,Kn,oe,Le,Be,ht,Jt){let Yt=gn||(gn=pn());switch(arguments.length){case 0:return Yt();case 1:return Yt(_t);case 2:return Yt(_t,Kn);case 3:return Yt(_t,Kn,oe);case 4:return Yt(_t,Kn,oe,Le);case 5:return Yt(_t,Kn,oe,Le,Be);case 6:return Yt(_t,Kn,oe,Le,Be,ht);case 7:return Yt(_t,Kn,oe,Le,Be,ht,Jt);default:return Yt.apply(null,arguments)}}},"libcPreemptibleProvider"),et=o((Me,tt,gn)=>{if(gn==="function"&&Me==="linux"&&tt==="syscall"){let pn=wn.linux&&wn.linux.syscall;if(typeof pn!="function")throw new Error("hwjs-libc: libc.so imports linux.syscall but the process import object carries none (never-silent).");return pn}if(!(gn!=="function"||Me!=="env")){if(Rr.has(tt)){if(hn[tt])return hn[tt];let pn=Ne?Ne[tt]:void 0;if(typeof pn=="function")return pn;throw new Error(`hwjs-libc: libc.so import env.${tt} is KERNEL-owned but vmlinux does not export it (never-silent).`)}return tt==="__hwjs_xmod_dispatch_check"?(pn,_t)=>ai(pn,_t,!0):tt==="__hwjs_lane_id"?Tt(tt,"libc.so (module #1)"):hr.has(tt)?Ar(tt,"libc.so (module #1)"):typeof tn[tt]=="function"?q(tt,tn[tt]):lt(tt)}},"libcResolveImport"),mt=qe?qe.tableBase>>>0:at.length,ot=qe?qe.moduleId|0:Ne&&typeof Ne.__hwjs_alloc_module_id=="function"?Ne.__hwjs_alloc_module_id()|0:0,wt;wt=Li({wasmBytes:We.bytes,memory:t.memory,table:at,moduleId:ot,soPath:"libc.so (module #1)",compileModule:o(()=>We.module,"compileModule"),mainLaneAddressed:we,...Qe===3||Qe===4?{mainDriveAbi:Qe}:{},statusChannelAddr:(()=>{let Me=tn?tn.__hwjs_status_channel:void 0;if(!(Me instanceof WebAssembly.Global)||!B)return;let tt=Mi(t,en),gn=((B.memoryBase>>>0)+(Me.value|0)+tt*32|0)>>>0;if(tr)try{e({kind:"dmesg",level:6,text:`[chan-addr libc] mode=${t.mode} lane=${tt} base=0x${(B.memoryBase>>>0).toString(16)}+0x${(Me.value|0).toString(16)} addr=0x${gn.toString(16)}`})}catch{}return gn})(),resolveImport:et,resolveDataAddress:o(Me=>{let tt=tn?tn[Me]:void 0;if(tt instanceof WebAssembly.Global&&B)return((B.memoryBase>>>0)+(tt.value|0)|0)>>>0},"resolveDataAddress"),interposeDataAddress:(()=>{let Me=null;return tt=>(Me||(Me=Jh(Jn)),Uh(tt,Me))})(),gotFuncIndex:un,stackPointer:Je.__stack_pointer,parkImport:o(()=>{},"parkImport"),tlsOwner:!0,deferGotFunc:new Set(["freea","hwjs_resume","hwjs_done","hwjs_destroy","__hwjs_drive_abi","__hwjs_user_park","__wasm32_set_tls_base","__wasm_init_tls","__wasm32_get_tls_size","__wasm32_get_tls_align","__wasm32_set_stack_pointer","__hwjs_lane_id"]),...qe?{fixedMemoryBase:qe.memoryBase>>>0,fixedTableBase:qe.tableBase>>>0,skipDataRelocs:!0,seedSymbolIndices:Array.isArray(qe.appended)?qe.appended:[]}:{allocMemory:or}}),Mt(wt),qe||(Se&&Se.flags&&Se.flags.usesTls?_=!0:wt.runCtors()),Q=wt,$={digest:L.digest,suspenderDigestLo64:Se.suspenderDigestLo64,checkEmitting:!!(Se.flags&&Se.flags.checkEmitting),laneAddressed:!!(Se.flags&&Se.flags.laneAddressed),memoryBase:wt.memoryBase>>>0,tableBase:mt>>>0,tableSize:at.length-mt>>>0,moduleId:ot|0,appended:wt.tableEntries()};try{e({kind:"dmesg",level:6,text:`hwjs-libc: module #1 instantiated (libc.so.${L.digest.slice(0,16)}\u2026 moduleId=${ot} memoryBase=0x${$.memoryBase.toString(16)} tableBase=${mt}${qe?" fork-replay":""}) \u2014 libc provider is the shared module`})}catch{}if(wt.interposedData&&wt.interposedData.length)try{e({kind:"dmesg",level:6,text:`hwjs-libc: libc.so reads the main's ${wt.interposedData.join(", ")}`})}catch{}}let Hn=Q?(Q.instance??Q).exports:null,sn=[],ir=null,ss="";if(j.length){try{let We=WebAssembly.Module.exports(S).some(oe=>oe.kind==="function"&&oe.name==="__wasm32_needed_ctors_in_start"),Se=new Set(WebAssembly.Module.exports(S).filter(oe=>oe.kind==="function").map(oe=>oe.name)),qe=new Map;for(let oe of j){let Le=rs.get(oe.digest);Le.module||(Le.module=ki(Le.bytes,oe.digest).module),qe.set(oe.index,new Set(WebAssembly.Module.exports(Le.module).filter(Be=>Be.kind==="function").map(Be=>Be.name)))}let ut=new Map,Yn=new Map,Dn=new Map(j.map(oe=>[oe.index,oe])),or=new Map(j.map((oe,Le)=>[oe.index,Le])),Qt=o((oe,Le,Be)=>Eh(Be,oe.get(Be),Le.index,or),"soEarlier");for(let oe of j){let Le=rs.get(oe.digest);for(let Be of WebAssembly.Module.exports(Le.module)){let ht=Be.kind==="function"?ut:Be.kind==="global"?Yn:null;ht&&!ht.has(Be.name)&&ht.set(Be.name,oe.index)}}let ar=new Map,$n=o((oe,Le)=>{let Be=Go(9,0,Le|0,3,34,-1,0)|0;if(Be<=0)throw new Error(`hwjs-libc: SYS_mmap for ${oe}'s data region (${Le}B) returned ${Be} \u2014 the needed library cannot be placed (never-silent OOM).`);return Be>>>0},"soMmapWindow"),lt=new Map,et=o(oe=>{if(lt.has(oe))return lt.get(oe);let Le=Dn.get(oe),Be=Le?rs.get(Le.digest):null;if(!Be)return 0;let ht=_i(Be.bytes),Jt=ht?ht.memorySize|0:0,Yt=ht?ht.memoryAlign|0:1,dn=Yt>0?Yt:1,fn=Jt>0?$n(Le.soname,(Jt+dn-1&~(dn-1))>>>0):0;lt.set(oe,fn);try{e({kind:"dmesg",level:6,text:`hwjs-libc: pre-placed needed entry ${oe} (${Le.soname}) at memoryBase=0x${fn.toString(16)} \u2014 a sibling's GOT.mem names its data and a data address cannot be bound late`})}catch{}return fn},"soPreallocBase"),mt=new Map,ot=new Map,wt=new Map,Me=o((oe,Le)=>{let Be=wt.get(oe);if(!Be){let ht=Dn.get(oe),Jt=ht?rs.get(ht.digest):null;Be=Jt?vh(Jt.bytes):new Map,wt.set(oe,Be)}return Be.get(Le)},"soExportFnIndex"),tt=o((oe,Le,Be)=>{let ht=ar.get(Le);if(ht){let kn=ht.dlsym(Be)>>>0;if(!(kn>0))throw new Error(`hwjs-dlopen: ${oe.soname} (needed entry ${oe.index}) takes the address of "${Be}", which needed entry ${Le} exports, but it has no table slot for it (never-silent).`);return kn}let Jt=mt.get(Le);if(Jt||mt.set(Le,Jt=new Map),Jt.has(Be))return Jt.get(Be);let Yt=ot.get(Le);Yt||ot.set(Le,Yt=new Map);let dn=Me(Le,Be);if(dn!==void 0&&Yt.has(dn)){let kn=Yt.get(dn);return Jt.set(Be,kn),kn}let fn=at.length;at.grow(1),Jt.set(Be,fn),dn!==void 0&&Yt.set(dn,fn);try{e({kind:"dmesg",level:6,text:`hwjs-libc: reserved table slot ${fn} for "${Be}" of needed entry ${Le} \u2014 ${oe.soname} (needed entry ${oe.index}) takes its address before it is placed`})}catch{}return fn},"soSiblingFnSlot"),gn=o((oe,Le,Be)=>{let ht=null,Jt=o(()=>{let Yt=typeof Be=="number"?Be:oe.index;if(typeof Be=="number"&&!ar.has(Yt))throw new Error(`hwjs-dlopen: ${oe.soname} (needed entry ${oe.index}) called env.${Le} from a CONSTRUCTOR, but its provider (needed entry ${Yt}) is not instantiated yet -- a sibling binding is late by construction and cannot be completed before the entry that owns it is placed. Refusing rather than binding a hole (never-silent).`);let dn=Be==="main"?C||null:(()=>{let kn=ar.get(Yt);return kn?(kn.instance??kn).exports:null})(),fn=dn?dn[Le]:void 0;if(typeof fn!="function")throw new Error(`hwjs-dlopen: ${oe.soname} (needed entry ${oe.index}) imported env.${Le}, resolved at load to ${Be==="main"?"the MAIN image":typeof Be=="number"?`needed entry ${Be}`:"the library's own definition"} (ELF search order), but that provider exports no function "${Le}" now that it is called (never-silent).`);return fn},"provider");return function(Yt,dn,fn,kn,Yr,bi,Hi){let ws=ht||(ht=Jt());switch(arguments.length){case 0:return ws();case 1:return ws(Yt);case 2:return ws(Yt,dn);case 3:return ws(Yt,dn,fn);case 4:return ws(Yt,dn,fn,kn);case 5:return ws(Yt,dn,fn,kn,Yr);case 6:return ws(Yt,dn,fn,kn,Yr,bi);case 7:return ws(Yt,dn,fn,kn,Yr,bi,Hi);default:return ws.apply(null,arguments)}}},"soLateBind"),pn=o((oe,Le)=>{if(Se.has(Le))return"main";let Be=Qt(ut,oe,Le);if(Be!==void 0)return Be;let ht=qe.get(oe.index);if(ht&&ht.has(Le))return"self";let Jt=ut.get(Le);return Jt!==void 0&&Jt!==oe.index?Jt:null},"soTierFor"),_t=new Map,Kn=o((oe,Le)=>{let Be=pn(oe,Le);if(!Be){let ht=_t.get(oe.index);if(!ht){let Jt=rs.get(oe.digest);ht=Jt&&(_i(Jt.bytes)||{}).weakImports||new Map,_t.set(oe.index,ht)}if(ht.get(Le)==="env")return;throw new Error(`hwjs-dlopen: unresolved import env.${Le} (function) in "${oe.soname} (needed entry ${oe.index})" -- the runtime (module #0) does not export it, libc.so (module #1) does not export it, the main image does not export it, ${oe.soname} does not define it either, and no OTHER needed entry of this main exports it, so NOTHING in this process can ever provide it. Refusing the load (never-silent): the alternative is a binding that throws at whatever guest call site reaches it first, which is where this class used to surface.`)}return gn(oe,Le,Be)},"soPreemptibleProvider");for(let oe of j){ir=oe,ss="instantiate";let Le=rs.get(oe.digest);Le.module||(Le.module=ki(Le.bytes,oe.digest).module);let Be=Wi(t.mode)&&en&&t.dlopenFork&&Array.isArray(t.dlopenFork.neededLibs)?t.dlopenFork.neededLibs.find(In=>In.name===oe.name):null;if(!Be&&Wi(t.mode)&&en&&t.dlopenFork)throw new Error(`hwjs-libc: fork-resume child of a main needing ${oe.name.slice(0,32)}\u2026 carries no dlopenFork placement for it \u2014 refusing a fresh carve over the copied address space (the delta copy holds this library's live data; never-silent).`);if(Be&&Be.digest!==oe.digest)throw new Error(`hwjs-libc: GENERATION SKEW \u2014 the parent's placement for ${oe.soname} records digest ${String(Be.digest).slice(0,16)}\u2026 but this image needs ${oe.digest.slice(0,16)}\u2026 (never-silent).`);if(Be){let In=(Be.tableBase>>>0)+(Be.tableSize>>>0);at.length$n(oe.soname,In),"soAllocMemory"),Jt=ib(Le.module),Yt=o((In,xt,Us)=>{if(Us==="function"&&In==="linux"&&xt==="syscall"){let Cn=wn.linux&&wn.linux.syscall;if(typeof Cn!="function")throw new Error(`hwjs-libc: ${oe.soname} imports linux.syscall but the process import object carries none (never-silent).`);return Cn}if(!(Us!=="function"||In!=="env")){if(Rr.has(xt)){if(hn[xt])return hn[xt];let Cn=Ne?Ne[xt]:void 0;if(typeof Cn=="function")return Cn;throw new Error(`hwjs-libc: ${oe.soname} import env.${xt} is KERNEL-owned but vmlinux does not export it (never-silent).`)}if(xt==="__hwjs_xmod_dispatch_check")return(Cn,vn)=>ai(Cn,vn,!1,!1,Jt);if(hr.has(xt))return Ar(xt,`${oe.soname} (needed entry ${oe.index})`);if(xt==="__hwjs_lane_id"&&Se.has(xt))return()=>{let Cn=C?C[xt]:void 0;return typeof Cn=="function"?Cn():Mi(t,en)};if(typeof tn[xt]=="function")return q(xt,tn[xt]);if(Hn&&typeof Hn[xt]=="function")return Hn[xt];if(xt!=="fork")return Kn(oe,xt)}},"soResolveImport"),dn=new Set,fn=new Map,kn=new Map,Yr=null,bi=qe.get(oe.index);for(let In of WebAssembly.Module.imports(Le.module)){if(In.module!=="GOT.func")continue;let xt=In.name;if(bi&&bi.has(xt)&&Qt(ut,oe,xt)===void 0)continue;Yr||(Yr=Kd(Le.module,Le.bytes));let Us=Yr.get(xt),Cn=Us?Us.module:"env",vn=Us?Us.field:xt;if(Cn==="linux"&&vn==="syscall"||Cn==="env"&&(vn==="__hwjs_xmod_dispatch_check"||hn[vn]||hr.has(vn)))throw new Error(`hwjs-dlopen: ${oe.soname} (needed entry ${oe.index}) takes the address of "${xt}", which resolves to ${Cn}.${vn} -- a host binding, not a wasm export, so it can occupy no table slot. Refusing the load (never-silent).`);if(Cn!=="env"||Rr.has(vn)||hr.has(vn)||!(vn==="__hwjs_lane_id"&&Se.has(vn))&&(typeof tn[vn]=="function"||Hn&&typeof Hn[vn]=="function")||vn==="fork")continue;let fr=pn(oe,vn);if(fr!==null){if(vn!==xt)throw new Error(`hwjs-dlopen: ${oe.soname} (needed entry ${oe.index}) takes the address of "${xt}", which resolves through env.${vn} -- a name provided only by the main, ${oe.soname} itself, or a sibling needed entry, so the slot would need a late binding the post-main patch cannot complete under an aliased name. Refusing the load (never-silent).`);if(typeof fr=="number"&&!Be){fn.set(xt,tt(oe,fr,xt));continue}typeof fr=="number"&&kn.set(xt,fr),dn.add(xt)}}let Hi=Be?Be.tableBase>>>0:at.length,ws=Be?Be.moduleId|0:Ne&&typeof Ne.__hwjs_alloc_module_id=="function"?Ne.__hwjs_alloc_module_id()|0:0,Ss,Ya=0;if(Ss=Li({wasmBytes:Le.bytes,memory:t.memory,table:at,moduleId:ws,soPath:`${oe.soname} (needed entry ${oe.index})`,compileModule:o(()=>Le.module,"compileModule"),mainLaneAddressed:$?!!$.laneAddressed:we,resolveImport:Yt,preemptsData:o(In=>Qt(Yn,oe,In)!==void 0,"preemptsData"),resolveDataAddress:o(In=>{let xt=Hn?Hn[In]:void 0;if(xt instanceof WebAssembly.Global&&$)return(($.memoryBase>>>0)+(xt.value|0)|0)>>>0;let Us=tn?tn[In]:void 0;if(Us instanceof WebAssembly.Global&&B)return((B.memoryBase>>>0)+(Us.value|0)|0)>>>0;let Cn=Yn.get(In);if(Cn===void 0||Cn===oe.index)return;let vn=ar.get(Cn);if(vn){let pi=((vn.instance??vn).exports||{})[In];return pi instanceof WebAssembly.Global?((vn.memoryBase>>>0)+(pi.value|0)|0)>>>0:void 0}let Kr=Dn.get(Cn);if(!Kr)return;let fr=rs.get(Kr.digest);if(!fr)return;let Ca=Wi(t.mode)&&en&&t.dlopenFork&&Array.isArray(t.dlopenFork.neededLibs),So=Ca?t.dlopenFork.neededLibs.find(pi=>pi.name===Kr.name):null;if(Ca&&!So)throw new Error(`hwjs-libc: ${oe.soname} (needed entry ${oe.index}) GOT.mem.${In} is owned by sibling needed entry ${Cn} (${Kr.soname}), but this fork-resume child has no placement record for it \u2014 refusing to re-place it at a fresh base the parent's relocated data does not point at (never-silent).`);let ko=So?So.memoryBase>>>0:et(Cn);if(!(ko>0))return;let Na=Lh(fr.bytes,In,`${Kr.soname} (needed entry ${Cn})`);return((ko>>>0)+(Na|0)|0)>>>0},"resolveDataAddress"),gotFuncIndex:un,stackPointer:Je.__stack_pointer,parkImport:o(()=>{},"parkImport"),sideTls:Be?nc(t.mode,Be,t.mainTlsSlot):{mode:"fresh"},...dn.size?{deferGotFunc:dn}:{},...fn.size?{presetGotFunc:fn}:{},...!Be&&mt.has(oe.index)?{reservedSymbolIndices:[...mt.get(oe.index)]}:{},...Be?{fixedMemoryBase:Be.memoryBase>>>0,fixedTableBase:Be.tableBase>>>0,skipDataRelocs:!0,seedSymbolIndices:Array.isArray(Be.appended)?Be.appended:[]}:lt.has(oe.index)?{fixedMemoryBase:lt.get(oe.index)>>>0}:{allocMemory:ht}}),ar.set(oe.index,Ss),Ss.tls&&(Ya=Be?Be.tlsSlots>>>0:$n(`${oe.soname} TLS slots`,tc(Ss.tls,`${oe.soname} (needed entry ${oe.index})`))),ss="armModuleBudget",Mt(Ss),ss="runCtors",!Be&&We){let In=(Ss.instance??Ss).exports,xt=In.__wasm_call_ctors;typeof xt=="function"&&Ut.push({ctor:xt,moduleId:ws|0,soname:oe.soname,...ab(In)})}else Be||Ss.runCtors();sn.push({name:oe.name,soname:oe.soname,digest:oe.digest,index:oe.index,handle:Ss,exports:(Ss.instance??Ss).exports,memoryBase:Ss.memoryBase>>>0,tableBase:Hi>>>0,moduleId:ws|0,appended:Ss.tableEntries(),tlsSlots:Ya>>>0,gotProviders:kn});try{e({kind:"dmesg",level:6,text:`hwjs-libc: module #${1+oe.index} instantiated (${oe.soname}, digest ${oe.digest.slice(0,16)}\u2026 moduleId=${ws} memoryBase=0x${(Ss.memoryBase>>>0).toString(16)} tableBase=${Hi}${Be?" fork-replay":""}) \u2014 needed entry ${oe.index}`})}catch{}ir=null,ss=""}}catch(We){if(ir){let Se=ir,qe="";try{let ut=We instanceof Error?We.message:String(We),Yn=We&&We.stack?String(We.stack).split(` `).slice(1,5).map(Dn=>Dn.trim()).filter(Boolean).join(" | "):"";qe=ut+(Yn?` [${Yn}]`:"")}catch{qe="(unreportable throw value)"}We=new Error(`hwjs-libc: needed entry ${Se.index} (${Se.soname}, digest ${String(Se.digest).slice(0,16)}) failed at ${ss}: ${qe}`,{cause:We})}if(await G("NEEDED-LOAD",We)==="return"){jn("error");return}break e}pe=sn.map(We=>({handle:We.handle,soname:We.soname,index:We.index,tlsSlots:We.tlsSlots,gotProviders:We.gotProviders})),_e=sn.map(We=>({name:We.name,digest:We.digest,index:We.index,memoryBase:We.memoryBase,tableBase:We.tableBase,tableSize:at.length-We.tableBase>>>0,moduleId:We.moduleId,appended:We.handle.tableEntries(),tlsSlots:We.tlsSlots}))}for(let We of O)if(!(We.module!=="env"||We.kind!=="function")&&Je[We.name]===void 0){if(typeof tn[We.name]=="function")Je[We.name]=q(We.name,tn[We.name]);else if(Hn&&typeof Hn[We.name]=="function")Je[We.name]=Hn[We.name];else for(let Se of sn)if(typeof Se.exports[We.name]=="function"){Je[We.name]=Se.exports[We.name];break}}for(let We of sn.length?O:[]){if(We.module!=="env"||We.kind!=="function"||gm.has(We.name))continue;let Se=[];typeof tn[We.name]=="function"&&Se.push("rt (#0)"),Hn&&typeof Hn[We.name]=="function"&&Se.push("libc.so (#1)");for(let qe of sn)typeof qe.exports[We.name]=="function"&&Se.push(`${qe.soname} (#${1+qe.index})`);if(Se.length>1)try{e({kind:"dmesg",level:6,text:`hwjs-libc: ${We.name} is exported by ${Se.length} placed modules (${Se.join(", ")}) \u2014 bound from ${Se[0]} by needed-list order`})}catch{}}try{if(Q){let We=$.memoryBase>>>0;for(let Se of O)if(Se.kind==="global"){if(Se.module==="GOT.mem"){let qe=Hn[Se.name];if(qe instanceof WebAssembly.Global){(wn["GOT.mem"]??={})[Se.name]=new WebAssembly.Global({value:"i32",mutable:!0},We+(qe.value|0)|0);continue}let ut=tn?tn[Se.name]:void 0;if(ut instanceof WebAssembly.Global&&B){(wn["GOT.mem"]??={})[Se.name]=new WebAssembly.Global({value:"i32",mutable:!0},(B.memoryBase>>>0)+(ut.value|0)|0);continue}let Yn=0,Dn=0;for(let or of sn){let Qt=or.exports[Se.name];Qt instanceof WebAssembly.Global&&Yn++===0&&(Dn=(or.memoryBase>>>0)+(Qt.value|0)|0)}if(Yn>0){if((wn["GOT.mem"]??={})[Se.name]=new WebAssembly.Global({value:"i32",mutable:!0},Dn),Yn>1)try{e({kind:"dmesg",level:6,text:`hwjs-libc: GOT.mem.${Se.name} is exported as data by ${Yn} needed libraries \u2014 bound from the first in needed-list order`})}catch{}continue}throw new Error(`hwjs-libc: main GOT.mem.${Se.name} names no libc.so data export, no runtime (module #0) data export, and no data export of any needed library either \u2014 the by-name witness should have made this link-fatal; a skewed/foreign artifact pair (never-silent).`)}else if(Se.module==="GOT.func"){let qe=Q.dlsym(Se.name);if(!(qe>0)&&ae&&(qe=ae.dlsym(Se.name)),!(qe>0)){for(let ut of sn)if(qe=ut.handle.dlsym(Se.name),qe>0)break}if(!(qe>0))throw new Error(`hwjs-libc: main GOT.func.${Se.name} names no libc.so function export, no runtime op, and no export of any needed library of that name \u2014 cannot mint a table identity (never-silent).`);(wn["GOT.func"]??={})[Se.name]=new WebAssembly.Global({value:"i32",mutable:!0},qe)}}}}catch(We){if(await G("LIBC-GOT-MINT",We)==="return"){jn("error");return}break e}try{e({kind:"dmesg",level:6,text:`hwjs-rt: module #0 instantiated (moduleId=${Ws} memoryBase=0x${B.memoryBase.toString(16)} tableBase=${Zn}) \u2014 runtime provider is the kernel`})}catch{}}}let T=null;for(let O of WebAssembly.Module.imports(S))if(O.kind==="global"&&O.module==="env"&&O.name==="__hwjs_status_channel_addr"){T=new WebAssembly.Global({value:"i32",mutable:!0},0),(wn.env??={}).__hwjs_status_channel_addr=T,we=!0;break}let fe=cg(S,wn),ge;try{ge=await WebAssembly.instantiate(S,fe)}catch(O){if(await G("INSTANTIATE",O)==="return"){jn("error");return}break e}{let O=ge.exports,ke=Ie?Ie.exports:null;if(ke&&B){let Je=B.memoryBase>>>0,Ne=Object.create(null);for(let vt of Object.keys(ke)){let Tt=ke[vt];Ne[vt]=Tt instanceof WebAssembly.Global?new WebAssembly.Global({value:"i32"},Je+(Tt.value|0)|0):Tt}ke=Ne}let be=Q?(Q.instance??Q).exports:null;if(be&&$){let Je=$.memoryBase>>>0,Ne=Object.create(null);for(let vt of Object.keys(be)){let Tt=be[vt];Ne[vt]=Tt instanceof WebAssembly.Global&&vt!=="__tls_base"?new WebAssembly.Global({value:"i32"},Je+(Tt.value|0)|0):Tt}be=Ne}C=ke||be?Object.assign(Object.create(null),ke??{},be??{},O,O.__stack_pointer===void 0&&wn.env&&wn.env.__stack_pointer instanceof WebAssembly.Global?{__stack_pointer:wn.env.__stack_pointer}:{}):O;let Ee=C.__hwjs_lane_id;if(typeof Ee=="function")try{for(let Je of Ct)Je.t.set(0,Ee)}catch{}}let W=C;mm=Ah(W),Wd=null;let he=Mi(t,en);if(je=he|0,T){let O=W.__hwjs_status_channel,ke=O instanceof WebAssembly.Global?O.value>>>0:0;if(!ke)throw new Error("lane-addressed main imports env.__hwjs_status_channel_addr but exports no __hwjs_status_channel data global to derive it from \u2014 skewed artifact pair (never-silent; refusing a 0 bind, the R1-glibc phantom address-0 class).");if(T.value=ke+he*32|0,tr)try{e({kind:"dmesg",level:6,text:`[chan-addr main] mode=${t.mode} lane=${he} chBase=0x${ke.toString(16)} addr=0x${(T.value>>>0).toString(16)}`})}catch{}}if(!en&&Kt)try{e({kind:"dmesg",level:6,text:"EXEC-LOAD-DIAG: re-instantiate DONE; entering drive (bash _start)"})}catch{}if(Kt&&at)try{let O=o(ke=>{try{return typeof at.get(ke)}catch{return"oob"}},"probe");e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} DYNMAIN-TABLE len=${at.length} get(0)=${O(0)} get(1)=${O(1)} get(85)=${O(85)} exportsTable=${W.__indirect_function_table instanceof WebAssembly.Table?"yes":"no"} sameAsExport=${W.__indirect_function_table===at}`})}catch{}try{if(ae||Q||pe.length){let O=[...ae?[{handle:ae,who:"rt"}]:[],...Q?[{handle:Q,who:"libc.so"}]:[],...pe.map(be=>({handle:be.handle,who:`${be.soname} (needed entry ${be.index})`,gotProviders:be.gotProviders}))],ke=pe.map(be=>({index:be.index,soname:be.soname,exports:(be.handle.instance??be.handle).exports??be.handle.exports}));for(let be of O){let Ee=be.handle;if(!Ee)continue;let Je=be.who,Ne=(Ee.instance??Ee).exports??Ee.exports;for(let vt of Ee.pendingGotFuncNames()){let Tt=_h(vt,{exp:W,ownExp:Ne,siblings:ke,provider:be.gotProviders?be.gotProviders.get(vt):void 0}),Lt=Tt?Tt.f:void 0;if(Tt&&Tt.sibling)try{e({kind:"dmesg",level:6,text:`hwjs-rt: ${Je} took the address of "${vt}" (GOT.func); patched from sibling needed entry ${Tt.sibling.index} (${Tt.sibling.soname})`})}catch{}if(typeof Lt!="function")throw new Error(`hwjs-rt: ${Je} took the address of "${vt}" (GOT.func) but no provider (main/rt/libc.so own exports, or any needed entry of this main) supplies such a function \u2014 cannot patch the deferred slot (never-silent).`);Ee.patchGotFunc(vt,Lt)}}}}catch(O){if(await G("GOT-PATCH",O)==="return"){jn("error");return}break e}Wi(t.mode)&&en&&t.dlopenFork&&typeof t.dlopenFork=="object"&&(Array.isArray(t.dlopenFork.fpcastRecs)&&(zn=new Map(t.dlopenFork.fpcastRecs.map(([O,ke])=>[O>>>0,ke>>>0]))),qs(t.dlopenFork));let Pe=o(O=>{let ke=C[O];return ke instanceof WebAssembly.Global?ke.value>>>0:0},"hwjsData");me=null,x=typeof C.hwjs_resume=="function"&&typeof C.hwjs_done=="function"&&typeof C.hwjs_destroy=="function"&&typeof C.__hwjs_take_parked=="function"&&Pe("__hwjs_parked")!==0&&Pe("__hwjs_park_reason")!==0;{let O=x&&typeof C.__hwjs_drive_abi=="function"?C.__hwjs_drive_abi()|0:0;ie=O===3||O===4}if(ee=x&&typeof C.__hwjs_libc_syscall_park_abi=="function"&&(C.__hwjs_libc_syscall_park_abi()|0)===1,E=x&&typeof C.__hwjs_libc_mmap_park_abi=="function"&&(C.__hwjs_libc_mmap_park_abi()|0)===1,t.mergedCpu0Lane===!0&&!ee){let ke=`hwjs-merged REFUSED image ${Array.isArray(t.argv)&&t.argv.length>0?String(t.argv[0]):`pid ${t.pid??"?"}`} on the merged CPU-0 lane: it does not export __hwjs_libc_syscall_park_abi()==1 (hwjsDrive=${x?1:0}), so nothing in it can absorb a -517 cooperative park at all and every blocking read falls through to an UNBOUNDED in-kernel wait. (An image that DOES export 1 is admitted, and that is not the same as proven: glibc's port documents its export as an over-approximation over its nominated TUs. Host-answered syscalls no longer rely on it \u2014 they are answered in place through the merged lane's synchronous door \u2014 but a kernel-route block-park still does, and a libc that does not re-issue is caught there by measurement, at the DEFERRED-RPC MISMATCH arm, not here.) This lane shares its JS thread with CPU 0 \u2014 the dispatcher, every kthread, the timer tick, the virtio IRQ bottom half, and inline the PtyBridge that delivers the keystroke this image would be waiting for \u2014 so that wait stops the machine, at the first prompt, with nothing to see. PLAN-COLLAPSED-CPU0 \xA73.5 used to send this image to mergedCpuHost:'separate' (linux-6.12-glibc-bash-coreutils today); that topology is deleted, so there is nowhere to send it. Run an image whose libc parks, or widen this one's park nomination until it does.`;throw e({kind:"error",pid:t.pid,message:ke}),new Error(ke)}if(P=!1,Nu.reset(),Ae=!1,Ve=!1,typeof W.__hwjs_set_stall_bound=="function"){let O=typeof process<"u"&&process.env.HWJS_F93_STALL_BOUND||"",ke=parseInt(O,10);Number.isFinite(ke)&&ke>0&&W.__hwjs_set_stall_bound(ke|0)}typeof process<"u"&&process.env&&process.env.HWJS_RED_LANE_RECYCLE_STALE==="1"&&typeof W.__hwjs_red_lane_recycle_stale=="function"&&W.__hwjs_red_lane_recycle_stale(1);let bt=t.mode==="fork-resume"&&en||t.mode==="migrate-resume"&&en||t.mode==="thread"&&en&&(!!t.dlopenFork||(t.userLane|0)>0);if(typeof W.__hwjs_budget_set=="function"&&(W.__hwjs_budget_set(dl|0),At(dl)),!bt&&t.mode!=="thread"&&typeof W.__hwjs_lane_attach=="function")if(typeof W.__wasm32_set_lane_id=="function"&&W.__wasm32_set_lane_id(0),u===0){if(!(typeof W.__hwjs_lane_occupied=="function"?W.__hwjs_lane_occupied(0)|0:1))throw new Error("hwjs-lanes: lane-0 was attached in the PRE-MAIN window and is NOT occupied at fresh-image bring-up \u2014 something detached it while the needed graph was constructed (a stale lane binding is the one shape the occupancy table cannot see later). Refusing to drive (never-silent).")}else{let O=W.__hwjs_lane_attach(0)|0;if(O<=0)throw new Error(`hwjs-lanes: lane-0 attach REFUSED (rc=${O}) at fresh-image bring-up \u2014 the occupancy table says lane 0 is already driven (two-driver shape) or the RT/lane-id binding is skewed. Refusing to drive (never-silent).`)}let $e=Q?(Q.instance??Q).exports:null,Ht=o((O,ke,be)=>{if(O.__wasm_init_tls(be),O===ke&&typeof D=="function")try{D(be>>>0)}catch{}},"bindBootstrapTls"),Sn=$e&&typeof $e.__wasm_init_tls=="function"&&typeof $e.__wasm32_get_tls_size=="function"&&typeof $e.__wasm32_get_tls_align=="function"?$e:W;if(!bt&&t.mode!=="thread"&&typeof Sn.__wasm_init_tls=="function"&&typeof Sn.__wasm32_get_tls_size=="function"&&typeof Sn.__wasm32_get_tls_align=="function"){let O=Sn.__wasm32_get_tls_size()>>>0;if(O!==0){let ke=Math.max(Sn.__wasm32_get_tls_align()>>>0,16),be=W.__heap_base,Ee=be instanceof WebAssembly.Global?be.value>>>0:typeof be=="number"?be>>>0:0;if(Ee===0)throw new Error(`HWJS bootstrap-TLS: image exports __wasm_init_tls and a non-zero __tls_size (${O}) but no usable __heap_base global \u2014 cannot place the pre-ctor TLS block. Refusing to run glibc ctors against a zero __tls_base (the ctor malloc would smash heap metadata).`);let Je=Ee+(ke-1)&~(ke-1),Ne=1*1024*1024;if(Je-Ee+O>Ne)throw new Error(`HWJS bootstrap-TLS: TLS block (size=${O}, align=${ke}) does not fit the ${Ne}-byte brk window at __heap_base=0x${Ee.toString(16)} \u2014 raise BRK_RESERVE (kernelSpawnHandler) or shrink TLS. Refusing a colliding bootstrap block.`);Ht(Sn,$e,Je),_&&Q&&typeof Q.runCtors=="function"&&(_=!1,Q.runCtors())}}let yn=(()=>{try{if(!$e||typeof $e.__wasm32_get_tls_size!="function"||!($e.__wasm32_get_tls_size()>>>0))return!1;let O=ge.exports;return typeof O.__wasm_init_tls=="function"&&typeof O.__wasm32_get_tls_size=="function"&&typeof O.__wasm32_get_tls_align=="function"&&O.__wasm32_get_tls_size()>>>0!==0}catch{return!1}})(),Gs=o(O=>{let ke=ge.exports,be=ke.__heap_base,Ee=be instanceof WebAssembly.Global?be.value>>>0:typeof be=="number"?be>>>0:0;if(Ee===0)throw new Error("HWJS main-image TLS: the main carries thread_local state beside a TLS-owning libc.so but exports no usable __heap_base \u2014 cannot place the per-lane main-TLS slots (never-silent).");return nb(Ee,ke.__wasm32_get_tls_size()>>>0,ke.__wasm32_get_tls_align()>>>0,O)},"mainImageTlsSlot"),bn=o((O,ke)=>{let be=Gs(O);if(be.addr===0){if((O|0)!==0)return 0;throw new Error(`HWJS main-image TLS: one ${be.stride}B slot for a ${ge.exports.__wasm32_get_tls_size()>>>0}B/${be.align}-aligned main TLS image does not fit half the ${ja}B brk window \u2014 refusing a colliding carve (never-silent).`)}return ke?ge.exports.__wasm_init_tls(be.addr):ge.exports.__wasm32_set_tls_base(be.addr|0),be.addr},"bindMainImageTls"),zt=o((O,ke,be)=>yn?(D(O|0),(ke|0)<0?!1:bn(ke|0,!!be)!==0):(W.__wasm32_set_tls_base(O|0),D(O|0),!0),"bindTaskTlsBase");if(!bt&&t.mode!=="thread"&&yn)try{bn(0,!0)}catch(O){if(await G("MAIN-TLS",O)==="return"){jn("error");return}break e}!bt&&typeof ge.exports.__wasm_apply_data_relocs=="function"&&ge.exports.__wasm_apply_data_relocs();let Ln=typeof W.__wasm32_ctors_run_in_start<"u";if(!bt&&Ut.length){let O=lb({table:at,memory:t.memory,list:Ut,slotAddr:W.__wasm32_needed_ctors_in_start()});Ut.forEach((ke,be)=>{try{e({kind:"dmesg",level:6,text:`hwjs-libc: ${ke.soname} ctors deferred to _start (moduleId=${ke.moduleId}, table ${O[be]}${O.driven&&ke.runner?`, runner ${ke.runner}`:""})`})}catch{}}),Ut=[]}!bt&&!Ln&&typeof W.__wasm_call_ctors=="function"&&W.__wasm_call_ctors(),(he|0)>0&&typeof W.__wasm32_set_lane_id=="function"&&W.__wasm32_set_lane_id(he|0),typeof t.signalPendingOffset=="number"&&typeof W.__wasm32_set_signal_region=="function"&&W.__wasm32_set_signal_region(t.signalPendingOffset>>>0);let Ns=t.mode==="thread"?"thread":"fork",ms=null,rr=!1;try{if(Ns==="thread"){if([...kt.values(),...pe].some(O=>O&&O.handle&&O.handle.tls&&O.handle.tls.unbound)){await m(0,0),e({kind:"thread-refused",pid:t.pid,tid:t.tid,message:"side-module TLS slot pool exhausted (256 distinct unjoined threads carry live thread_local storage in a side module; slots recycle at pthread_join). pthread_create returns EAGAIN (loud, contained, never silent)."});return}if(typeof W.__wasm32_set_stack_pointer=="function"&&W.__wasm32_set_stack_pointer(t.stackPointerOffset|0),typeof W.__wasm32_set_tls_base=="function"){let O=typeof t.mainTlsSlot=="number"?t.mainTlsSlot:he>0?he:0;if(!zt(t.tlsPointerOffset,O<0?-1:O+1,!0)){let ke=Gs(0).lanes-1;await m(0,0),e({kind:"thread-refused",pid:t.pid,tid:t.tid,message:`main-image TLS has no slot for this thread (${ke} thread slots fit for a ${ge.exports.__wasm32_get_tls_size()>>>0}B main TLS image, at most 256; slots recycle at pthread_join). pthread_create returns EAGAIN (loud, contained, never silent).`});return}}if(typeof W.__wasm32_user_entry!="function"){e({kind:"error",pid:t.pid,message:"thread-mode Worker missing __wasm32_user_entry export \u2014 link wasm_thread.S into the binary"});return}if(he>0){let O=o(Ee=>{if(tr)try{e({kind:"dmesg",level:6,text:`[thr-lane tid=${t.tid} lane=${he}] ${Ee}`})}catch{}},"tdbg");if(O("thread arm entered"),Nr(t,e,"thread-arm-entered"),!(we&&x&&ie&&typeof W.__hwjs_lane_attach=="function"&&typeof W.__wasm32_set_lane_id=="function"&&typeof W.__hwjs_lane_detach=="function"&&T!==null)){await m(0,0),e({kind:"thread-refused",pid:t.pid,tid:t.tid,message:`thread-mode spawn carried user-RT lane ${he} but this image cannot execute it: lane_addressed=${we?1:0} laned_rt=${typeof W.__hwjs_lane_attach=="function"?1:0} flat_drive=${ie?1:0} set_lane_id=${typeof W.__wasm32_set_lane_id=="function"?1:0} chan_addr_global=${T!==null?1:0} \u2014 rebuild the image with lane-aware channel addressing (HWJS_RT_LANES>1) against the laned RT. pthread_create returns EAGAIN (loud, contained, never silent).`});return}O("laneReady; set_lane_id"),W.__wasm32_set_lane_id(he|0);let be;try{O("attach..."),be=W.__hwjs_lane_attach(he|0)|0,O(`attach rc=${be}`)}catch(Ee){await m(0,0);let Je=!1;try{typeof W.__hwjs_lane_occupied=="function"?Je=(W.__hwjs_lane_occupied(he|0)|0)!==0:typeof W.__hwjs_lane_occupancy_word=="function"&&(Je=(he|0)<32&&(W.__hwjs_lane_occupancy_word()>>>0>>>(he|0)&1)!==0)}catch{}e({kind:"thread-refused",pid:t.pid,tid:t.tid,laneOccupied:Je,message:`lane ${he} attach VIOLATED (${Ee instanceof Error?Ee.message:String(Ee)}) \u2014 occupancy/generation skew between the kernel ledger and the RT table${Je?` (lane ${he} is OCCUPIED in the RT table: the kernel promise is quarantined, not recycled)`:""}. Clone refused with EAGAIN (never silent).`});return}if(be<=0){await m(0,0);let Ee=typeof W.__hwjs_lane_cap=="function"?W.__hwjs_lane_cap()|0:-1,Je=typeof W.__hwjs_lane_block_bytes=="function"?W.__hwjs_lane_block_bytes()>>>0:0,Ne=be===-12?`out of MEMORY: this lane's ${Je||"?"}B runtime-state block could not be mmap'd (the RT wrote the syscall's own return to stderr). The lane count is NOT the constraint here`:`out of SLOTS: boot wasm32.thread_lanes promised lane ${he}, past the RT artifact's compiled cap ${Ee<0?"?":Ee} \u2014 rebuild the runtime with a higher HWJS_RT_LANES_BUILD`;e({kind:"thread-refused",pid:t.pid,tid:t.tid,message:`lane ${he} attach refused rc=${be} (RT artifact cap ${Ee<0?"?":Ee}) \u2014 ${Ne}. Clone refused with EAGAIN (loud, catchable).`});return}Nr(t,e,"thread-adopted-post"),e({kind:"thread-adopted",pid:t.pid,tid:t.tid}),rr=!0}else if(x&&(ae||Q)){let O=Pe("__hwjs_parked"),ke=Pe("__hwjs_parked_owner");if(!O||!ke)throw new Error("thread arm: coro image without the parked-slot surface (__hwjs_parked/_owner exports) \u2014 cannot adopt the thread chain (never-silent).");if(W.__wasm32_user_entry(t.argRegionOffset|0),Fe()[O>>2]===0){if(!l)throw new Error("thread arm: __wasm32_user_entry returned with an EMPTY parked slot and no exit \u2014 the thread chain neither parked for adoption nor terminated (never-silent).")}else{let be=W.__hwjs_take_parked(0,0)>>>0;try{W.hwjs_destroy(be)}catch(Ee){try{e({kind:"dmesg",level:3,text:`thread arm: hwjs_destroy of the refused thread chain trapped (${Ee instanceof Error?Ee.message:String(Ee)}) \u2014 one chain's frames leak in the arena (bounded, loud)`})}catch{}}await m(0,0),e({kind:"thread-refused",pid:t.pid,tid:t.tid,message:"thread-mode placement replay is LIVE (rt #0 + libc.so #1 replayed at the recorded bases in this thread Worker) but thread EXECUTION on the coro substrate needs the K7+ per-thread-park lift \u2014 the user-rt drive surface (parked slot / xfer verdict / drive leaf / frame arena) is single-driver-per-process shared state. pthread_create is refused with -EAGAIN (loud, contained; the thread's kernel task is reaped to a plain zombie before refusal \u2014 never a silent hang, a torn park slot, or a live-task leak)."});return}}else{e({kind:"thread-adopted",pid:t.pid,tid:t.tid});let O=W.__wasm32_user_entry(t.argRegionOffset|0);typeof O=="number"&&!l&&(d=O&255)}}if(rr||Ns!=="thread"&&typeof W._start=="function"){let O=!en&&Gt!==null,ke=O?Gt:t.mode!=="fork-resume"?t.argv:null,be=O?Re||[]:t.mode!=="fork-resume"?t.envp:[];if(Array.isArray(ke)&&ke.length>0&&typeof W.__wasm32_args_buf_addr=="function"){let Ee=ke.map(sn=>String(sn)),Je=Array.isArray(be)?be.map(sn=>String(sn)):[],Ne=W.__wasm32_args_buf_addr()>>>0,vt=typeof W.__wasm32_args_buf_size=="function"?W.__wasm32_args_buf_size()|0:0,Tt=new TextEncoder,Lt=[...Ee,...Je].map(sn=>Tt.encode(sn)),Un=typeof process<"u"&&process.env?.HWJS_RED_NO_AUXV==="1"?[]:[6,4096,0,0],Vt=Ee.length+1+Je.length+1,Pn=8,Qn=Pn+(Vt+Un.length)*4,xs=Lt.reduce((sn,ir)=>sn+ir.length+1,Qn);if(xs>vt){e({kind:"error",pid:t.pid,message:`argv block (${xs}B) exceeds __wasm32_args_buf (${vt}B)`});return}let Zn=new DataView(t.memory.buffer),Ws=new Uint8Array(t.memory.buffer),An=Pn,tn=0,Hn=o(sn=>{for(let ir of sn){let ss=Lt[tn++],We=Ne+Qn;Ws.set(ss,Ne+Qn),Ws[Ne+Qn+ss.length]=0,Qn+=ss.length+1,Zn.setUint32(Ne+An,We>>>0,!0),An+=4}Zn.setUint32(Ne+An,0,!0),An+=4},"writeVec");Hn(Ee),Hn(Je);for(let sn of Un)Zn.setUint32(Ne+An,sn>>>0,!0),An+=4;if(Zn.setUint32(Ne+0,Ee.length>>>0,!0),Zn.setUint32(Ne+4,Je.length>>>0,!0),Kt)try{e({kind:"dmesg",level:6,text:`ARGS-BLOCK pid=${t.pid} ${O?"exec":"boot"} base=0x${Ne.toString(16)} argc=${Ee.length} envc=${Je.length} auxv=[${Un.join(",")}] auxv@0x${(Ne+Pn+Vt*4).toString(16)}`})}catch{}}if(x){let Ee=o(async()=>typeof W.__hwjs_budget_set!="function"?!1:(W.__hwjs_budget_set(bc|0),At(bc),HZ||await Ls(),!0),"serviceCooperativeBreath");if(ie){let Je=Pe("__hwjs_park_reason")+he*4,Ne=Pe("__hwjs_park_result")+he*4,vt=53406,Tt=53407,Lt=0,Pt=0,Tn=typeof process<"u"&&process.env.HWJS_FLAT_CENSUS==="1",Un=typeof performance<"u"&&typeof performance.now=="function"?()=>performance.now():()=>Date.now(),Vt={NONE:0,FORK:0,EXEC:0,RESCHED:0,DONE:0,other:0,wasmCalls:0,tWasmMs:0,tHostMs:0},Pn=!1,Qn=o(lt=>{if(!Tn||Pn)return;Pn=!0;let et=Vt.NONE+Vt.FORK+Vt.EXEC+Vt.RESCHED,mt=`hwjs-flat-census pid=${s[ce.PID]|0} (${lt}): host-reentries=${et} [NONE=${Vt.NONE} FORK=${Vt.FORK} EXEC=${Vt.EXEC} RESCHED=${Vt.RESCHED}] DONE=${Vt.DONE} other=${Vt.other}; wasmCalls=${Vt.wasmCalls} tWasm=${Vt.tWasmMs.toFixed(1)}ms tHost=${Vt.tHostMs.toFixed(1)}ms (avg/crossing: wasm=${(Vt.tWasmMs/Math.max(1,Vt.wasmCalls)).toFixed(3)}ms host=${(Vt.tHostMs/Math.max(1,et)).toFixed(3)}ms)`;e({kind:"dmesg",level:6,text:mt});try{console.error(mt)}catch{}},"emitFlatCensus");Xe=Qn;let xs=0,Zn=o(lt=>{let et=md();De&&(De.inWasm=!0,De.lastDriveEnterT=Date.now());try{if(!Tn){if(!De)return lt()>>>0;let Me=lt()>>>0;De.inWasm=!1,De.lastDriveRetT=Date.now(),De.lastStatus=Me,De.lastStatusT=De.lastDriveRetT;let tt="0x"+Me.toString(16);return De.statuses[tt]=(De.statuses[tt]|0)+1,Me}let mt=++xs;try{console.error(`hwjs-flat-drivecall #${mt} ENTER pid=${s[ce.PID]|0} t=${Un().toFixed(0)}`)}catch{}let ot=Un(),wt=lt()>>>0;Vt.tWasmMs+=Un()-ot,Vt.wasmCalls++;try{console.error(`hwjs-flat-drivecall #${mt} RETURN status=0x${(wt>>>0).toString(16)} dt=${(Un()-ot).toFixed(0)}ms`)}catch{}return wt}finally{hd(et)}},"driveCall");if(typeof W.__hwjs_drive_resume!="function")throw new Error("M-FLATDRIVE: flat image (__hwjs_drive_abi()===3) without the __hwjs_drive_resume re-entry export \u2014 the F107 in-wasm driver contract is incomplete; refusing to drive blind.");let Ws=Pe("__hwjs_fork_stw"),An=Pe("__hwjs_fork_stw_seq"),tn=Pe("__hwjs_fork_stw_ack"),Hn=Pe("__hwjs_fork_stw_inslice"),sn=!!(Ws&&An&&tn&&Hn&&typeof W.__hwjs_fork_barrier_ok=="function");sn?me={stwIdx:Ws>>2,seqIdx:An>>2,ackIdx:tn+he*4>>2,mirIdx:Hn+he*4>>2,lane:he|0}:me=null;try{e({kind:"dmesg",level:7,text:`hwjs-fork-stw pid=${s[ce.PID]|0} tid=${t.tid} lane=${he} ${sn?"ARMED":"absent"} (stw=0x${Ws.toString(16)} ack=0x${tn.toString(16)} mir=0x${Hn.toString(16)})`})}catch{}let ir=o(async()=>{if(!me)return;let lt=me,et=0;for(;;){if((Atomics.load(ct(),lt.stwIdx)|0)===0){if(Atomics.store(ct(),lt.mirIdx,1),(Atomics.load(ct(),lt.stwIdx)|0)===0)return;Atomics.store(ct(),lt.mirIdx,0)}let mt=Atomics.load(ct(),lt.stwIdx)|0;if(mt!==0){if(!et){et=Date.now();try{e({kind:"dmesg",level:7,text:`hwjs-fork-stw pid=${s[ce.PID]|0} lane=${lt.lane}: slice-entry gate HELD (gen=${mt})`})}catch{}}let ot=Atomics.waitAsync(ct(),lt.stwIdx,mt,250);if(ot.async)try{await ot.value}catch{}if(et&&Date.now()-et>1e4){et=Date.now();let wt=`hwjs-fork-stw pid=${s[ce.PID]|0} lane=${lt.lane}: held at the slice-entry gate for >10s under generation ${mt} \u2014 the forking lane's servicer has not released; still holding (loud, never silent)`;try{e({kind:"dmesg",level:3,text:wt})}catch{}try{console.error(wt)}catch{}}}}},"stwGate"),ss=o(async lt=>{await ir();try{return Zn(lt)}finally{me&&Atomics.store(ct(),me.mirIdx,0)}},"driveSlice"),We=o(()=>{if(!me)return;let lt=me;for(;;){if((Atomics.load(ct(),lt.stwIdx)|0)===0){if(Atomics.store(ct(),lt.mirIdx,1),(Atomics.load(ct(),lt.stwIdx)|0)===0)return;Atomics.store(ct(),lt.mirIdx,0)}let et=Atomics.load(ct(),lt.stwIdx)|0;et!==0&&Atomics.wait(ct(),lt.stwIdx,et,250)}},"stwGateSync"),Se=o(()=>{me&&Atomics.store(ct(),me.mirIdx,0)},"stwMirrorClear"),qe=typeof process<"u"&&process.env&&process.env.HWJS_NO_DONE_TERMINUS_DISPATCH==="1",ut=o(()=>{We();try{return Yn()}finally{Se()}},"dispatchDoneLive"),Yn=o(()=>{let lt=Pe("__hwjs_status_channel"),et=lt?lt+he*32:0,mt=et?Fe()[et>>2]>>>0:0,ot=o(wt=>{let Me=`drive DONE_TOP with live status ${mt} \u2014 ${wt}`;try{e({kind:"dmesg",level:3,text:`[hwjs-\xA74-terminus pid=${s[ce.PID]|0}] ${Me}`})}catch{}throw new Error(`M-FLATDRIVE \xA74 terminus: ${Me}`)},"refuse");if(et||ot("the driver returned HWJS_DRIVE_DONE_LIVE but the image exports no __hwjs_status_channel data \u2014 drive-status/channel contract skew"),mt===2){qe&&ot("an uncaught exception completed under the driver and the \xA74 dispatch is DISABLED (HWJS_NO_DONE_TERMINUS_DISPATCH=1, RED arm) \u2014 refusing rather than reporting a clean DONE"),typeof W.__hwjs_uncaught_unwinding!="function"&&ot("no __hwjs_uncaught_unwinding export to consume it (the RT weak fallback is part of the abi-4 export surface \u2014 its absence is a link/manifest defect)");let wt=Fe()[et+8>>2]>>>0;W.__hwjs_uncaught_unwinding(wt);let Me=Fe()[et>>2]>>>0;if(Me===1&&typeof W.__hwjs_status_adopt_top=="function"&&typeof W.__hwjs_drive_adopt_parked=="function"){let tt=W.__hwjs_status_adopt_top()>>>0;return W.hwjs_done(tt)|0&&ot("the terminus chain parked but its adopted top is DONE (park protocol breach)"),W.__hwjs_drive_adopt_parked()>>>0}ot(`__hwjs_uncaught_unwinding RETURNED without terminating the process and without a parked channel \u2014 the hook must terminate or park (channel now ${Me})`)}mt===3&&(typeof W.__hwjs_status_longjmp_lost=="function"&&W.__hwjs_status_longjmp_lost(),ot("longjmp target not found (dead, stale, or foreign jmp_buf) and no __hwjs_status_longjmp_lost export to report it faithfully")),ot("not a \xA74 terminus row (NORMAL/PARKED/corrupt channel word arrived with HWJS_DRIVE_DONE_LIVE \u2014 the RT consumes PARKED on its PARK leg and violates in-loop on a parked DONE, so this is drive-protocol skew)")},"dispatchDoneLiveInner"),Dn=o(()=>{We();try{or()}finally{Se()}},"threadLaneTeardown"),or=o(()=>{if(Pt=0,Fe()[Je>>2]=ve,typeof W.__hwjs_lane_arena_reset=="function")try{W.__hwjs_lane_arena_reset(he|0)}catch(ot){e({kind:"user-report",pid:t.pid,message:`thread lane ${he} arena reset REFUSED at terminus (${ot instanceof Error?ot.message:String(ot)}) \u2014 the chain was mid-flight, not at a clean terminus (never silent)`})}let lt=Pe("__hwjs_frame_live"),et=lt?Fe()[lt+he*4>>2]>>>0:0;if(typeof process<"u"&&process.env&&process.env.HWJS_ARENA_CENSUS){let ot=Pe("__hwjs_frame_high_water"),wt=Pe("__hwjs_frame_allocs");e({kind:"user-report",pid:t.pid,message:`hwjs-arena-census lane ${he} peak bump-committed ${ot?Fe()[ot+he*4>>2]>>>0:0} B in ${wt?Fe()[wt+he*4>>2]>>>0:0} allocs (this lane's whole life; the static bootstrap slice is what has to cover it before the first mmap)`})}et!==0&&e({kind:"user-report",pid:t.pid,message:`thread lane ${he} terminus with ${et} live arena frame(s) after reclaim \u2014 a genuine per-lane leak (the detach below refuses; the lane is lost, loudly; never silent)`});let mt=!1;try{W.__hwjs_lane_detach(he|0),mt=!0}catch(ot){e({kind:"user-report",pid:t.pid,message:`thread lane ${he} detach REFUSED at terminus (${ot instanceof Error?ot.message:String(ot)}) \u2014 lane QUARANTINED: the kernel ledger release is withheld so both ledgers agree the lane stays held (never a re-promise of an occupied lane); this process's thread cap is permanently down by one (loud, attributed)`})}try{if(mt&&Ze&&typeof Ze.exports.__wasm32_thread_lane_release=="function"){let ot=Ze.exports.__wasm32_thread_lane_release(t.ppid|0,he|0)|0;ot!==0&&e({kind:"user-report",pid:t.pid,message:`kernel lane-ledger release(leader=${t.ppid|0}, lane=${he}) returned ${ot}`+(ot===-3||ot===-2?" \u2014 no promise recorded under this leader/lane (leak-free by construction: the ledger holds no budget here) but the ledgers are SKEWED \u2014 report it":" \u2014 the promise is still held; a leaked ledger lane surfaces as premature EAGAIN cap exhaustion")+" (loud, attributed)"})}}catch(ot){e({kind:"user-report",pid:t.pid,message:`kernel lane-ledger release trapped: ${ot instanceof Error?ot.message:String(ot)}`})}},"threadLaneTeardownInner");De&&(De.reasonAddr=Je,De.resultAddr=Ne,De.timer&&clearInterval(De.timer),De.timer=setInterval(()=>{if(l){clearInterval(De.timer),De.timer=null;return}Nf("SAMPLE")},1e4),typeof De.timer.unref=="function"&&De.timer.unref());let Qt,ar=typeof process<"u"&&process.env&&process.env.A4C_FORKDBG,$n=o(lt=>{if(ar)try{e({kind:"dmesg",level:6,text:`[a4c-fork tid=${t.tid} mode=${t.mode}] ${lt}`})}catch{}},"fdbg");try{if(t.mode==="migrate-resume"&&en){if($n(`FLAT migrate-resume entry: binding tls/sp on cpu=${t.cpuId|0} (userLane=${he} task=0x${(t.migrateTaskAddr>>>0).toString(16)})`),typeof W.__wasm32_set_lane_id=="function"&&W.__wasm32_set_lane_id(he|0),typeof t.tlsBase=="number"&&typeof W.__wasm32_set_tls_base=="function"&&!zt(t.tlsBase,he|0,!1))throw new Error(`migrate-resume: no main-image TLS slot for lane ${he|0} \u2014 refusing to resume with the main's __tls_base unbound (never-silent).`);typeof t.sp=="number"&&t.sp!==0&&typeof W.__wasm32_set_stack_pointer=="function"&&W.__wasm32_set_stack_pointer(t.sp>>>0);let lt=Fe()[Je>>2]>>>0;if(lt!==ve)throw new Error(`migrate-resume: arrived with a PENDING park reason ${lt} \u2014 the source offers only from a serviced park, where the slot is already clear (never-silent)`);if(!ln())throw new Error("migrate-resume: the offer was already terminal when this destination finished binding (the source or the host aborted it first) \u2014 dropping the placement without driving; the task is the source's");Mn(e,`MIGRATE-IN cpu=${t.cpuId|0} tid=${t.tid} pid=${s[ce.PID]|0} lane=${he}`),Qt=await ss(W.__hwjs_drive_resume),$n(`AFTER driveCall(__hwjs_drive_resume) [migrate] status=0x${(Qt>>>0).toString(16)}`)}else if(t.mode==="fork-resume"&&en){$n(`FLAT fork-resume entry: setting tls/sp, result=0 (forkLane=${t.forkLane|0||0} userLane=${he} stwCapable=${sn?1:0})`),typeof t.tlsBase=="number"&&typeof W.__wasm32_set_tls_base=="function"&&zt(t.tlsBase,0,!1),typeof t.parentSp=="number"&&t.parentSp!==0&&typeof W.__wasm32_set_stack_pointer=="function"&&W.__wasm32_set_stack_pointer(t.parentSp>>>0);let lt=Fe()[Je>>2]>>>0;if(lt!==ve)throw new Error(`M-FLATDRIVE: fork-resume child copied a PENDING park reason ${lt} \u2014 the parent clears the reason before the delta=0 copy by contract`);if(sn){if(typeof W.__wasm32_set_lane_id=="function"&&W.__wasm32_set_lane_id(he|0),typeof W.__hwjs_fork_child_collapse!="function")throw new Error("fork-resume child: LANED image (STW surface present) without __hwjs_fork_child_collapse \u2014 skewed RT/artifact pair; refusing to resume over ghost lane occupancy (never-silent).");if(W.__hwjs_fork_child_collapse(he|0),(he|0)>0)if(Ze&&typeof Ze.exports.__wasm32_user_lane_seed=="function"){let et=Ze.exports.__wasm32_user_lane_seed(s[ce.PID]|0,he|0)|0;et!==0&&e({kind:"user-report",pid:t.pid,message:`fork-resume child lane-ledger seed(pid=${s[ce.PID]|0}, lane=${he}) returned ${et} \u2014 the child's first pthread_create may collide on its own main lane (loud, attributed)`})}else e({kind:"user-report",pid:t.pid,message:`fork-resume child on lane ${he} but the kernel exports no __wasm32_user_lane_seed \u2014 stale vmlinux; the child's first pthread_create may collide on its own main lane (loud, attributed)`})}Fe()[Ne>>2]=0,$n("BEFORE driveCall(__hwjs_drive_resume) [fork-resume initial]"),Qt=await ss(W.__hwjs_drive_resume),$n(`AFTER driveCall(__hwjs_drive_resume) RETURNED status=0x${(Qt>>>0).toString(16)}`)}else if(rr){if($n(`THREAD lane=${he} entry: __wasm32_user_entry ramp`),tr)try{e({kind:"dmesg",level:6,text:`[thr-lane tid=${t.tid} lane=${he}] pump entry: calling __wasm32_user_entry(0x${(t.argRegionOffset>>>0).toString(16)})`})}catch{}if(await ss(()=>(W.__wasm32_user_entry(t.argRegionOffset|0),0)),tr)try{e({kind:"dmesg",level:6,text:`[thr-lane tid=${t.tid}] entry returned; exitPosted=${l}`})}catch{}if(l){Dn();return}let lt=Pe("__hwjs_status_channel")+he*32,et=Fe()[lt>>2]>>>0;if($n(`THREAD entry channel status=${et}`),et===0){Dn();break}if(et!==1)throw new Error(`thread lane entry: channel status ${et} after entry (not NORMAL/PARKED) \u2014 drive-status protocol skew.`);if(typeof W.__hwjs_status_adopt_top!="function")throw new Error("thread lane entry: parked channel but no __hwjs_status_adopt_top export (abi4 surface defect).");let mt=W.__hwjs_status_adopt_top()>>>0;if(W.hwjs_done(mt)|0)throw new Error("thread lane entry: parked channel but the adopted top is DONE (park protocol breach; never-silent).");Pt=mt,Qt=await ss(W.__hwjs_drive_adopt_parked),$n(`THREAD adopt status=0x${(Qt>>>0).toString(16)}`)}else $n("BEFORE driveCall(_start) [fresh]"),Qt=await ss(W._start),$n(`AFTER driveCall(_start) RETURNED status=0x${(Qt>>>0).toString(16)}`);for(e({kind:"hwjs-host-drive-flat",pid:t.pid});;){if(l){Qn("exit_group");return}if(Qt===Tt&&(Qt=ut()>>>0),Qt!==it&&fm(),Qt===vt){Vt.DONE++,rr&&Dn();break}if(Qt===Zt){if(!rr&&he===0)try{e({kind:"dmesg",level:4,text:`hwjs-threads pid=${s[ce.PID]|0}: pthread_exit from the MAIN thread \u2014 treating as process completion (known residual: siblings are not awaited)`})}catch{}rr&&Dn(),d=0;break}let lt=Tn?Un():0;if(Qt===A){if(Vt.FORK++,!Ae)throw new Error("M-FLATDRIVE: FORK park without a latched SYS_fork \u2014 the park leaf fired outside the musl _Fork protocol");if(Ae=!1,typeof W.__hwjs_fork_barrier_ok!="function")throw new Error("M-FLATDRIVE fork latch: coro image lacks __hwjs_fork_barrier_ok \u2014 refusing the delta=0 copy without the structural barrier predicate (ADR-0004 F87 conf (4))");Fe()[Je>>2]=ve;let et=sn&&typeof process<"u"&&process.env&&process.env.HWJS_RED_FORK_NO_ALLLANE_QUIESCE==="1",mt=!1,ot=o(()=>{mt&&(mt=!1,Atomics.store(ct(),me.stwIdx,0),Atomics.notify(ct(),me.stwIdx))},"stwRelease"),wt=o(tt=>{let gn="";try{let _t=Pe("__hwjs_park_reason"),Kn=Pe("__hwjs_parked"),oe=Pe("__hwjs_status_channel"),Le=[],Be=Math.min(typeof W.__hwjs_lane_cap=="function"?W.__hwjs_lane_cap()|0:8,64);for(let ht=0;ht>2)|0,Yt=Atomics.load(ct(),tn+ht*4>>2)|0,dn=Fe()[_t+ht*4>>2]>>>0,fn=Fe()[Kn+ht*4>>2]>>>0,kn=Fe()[oe+ht*32>>2]>>>0;(Jt||Yt||dn||fn||kn)&&Le.push(`L${ht}{mir=${Jt} ack=${Yt} rsn=${dn} pk=0x${fn.toString(16)} st=${kn}}`)}if(gn=Le.length?` [${Le.join(" ")}]`:" [all-clear]",typeof W.__hwjs_fork_barrier_why=="function"){let ht=W.__hwjs_fork_barrier_why()>>>0,Jt=["quiesced","mid-drive-unmirrored","mid-drive-no-ack","parked-slot","lj-active","park-reason","xfer-pending","status-non-normal"];gn+=` why=lane${ht>>8}:${Jt[ht&255]??ht&255}`}}catch{gn=" [dump-failed]"}let pn=`hwjs-fork-stw pid=${s[ce.PID]|0} lane=${he}: fork REFUSED with EAGAIN \u2014 ${tt}${gn} (loud, attributed, POSIX-legal; the guest's fork() observes -EAGAIN and lives \u2014 plan \xA73 I1)`;try{e({kind:"dmesg",level:3,text:pn})}catch{}try{e({kind:"user-report",pid:t.pid,message:pn})}catch{}try{console.error(pn)}catch{}Fe()[Ne>>2]=-11},"forkRefuseEagain"),Me=!0;if(et)try{e({kind:"dmesg",level:4,text:`hwjs-fork-stw pid=${s[ce.PID]|0} lane=${he}: RED_NOQUIESCE \u2014 calling-lane-only fork barrier; the delta=0 copy will race live sibling lanes (test knob)`})}catch{}else if(sn){let gn=Date.now()+1e4,pn=0;for(;;){let _t=Atomics.add(ct(),me.seqIdx,1)+1|0;if(pn=_t===0?1:_t,Atomics.compareExchange(ct(),me.stwIdx,0,pn)===0){mt=!0;break}if(Date.now()>gn)break;let Kn=Atomics.load(ct(),me.stwIdx)|0;if(Kn!==0){let oe=Atomics.waitAsync(ct(),me.stwIdx,Kn,100);if(oe.async)try{await oe.value}catch{}}}if(!mt)wt("could not acquire the fork stop-the-world word within 10000 ms (another lane's fork service is holding it)"),Me=!1;else{let _t=0,Kn="",oe=o(()=>typeof W.__hwjs_fork_barrier_why=="function"?W.__hwjs_fork_barrier_why()>>>0:65535,"whyNow"),Le=Date.now()+1e4,Be=0;for(;_t=W.__hwjs_fork_barrier_ok()|0,_t!==1;){if(Be===0||Be%500===250){let ht=oe(),Jt=ht>>8,Yt=Atomics.load(ct(),Hn+Jt*4>>2)|0,dn=Atomics.load(ct(),tn+Jt*4>>2)|0,fn=Fe()[Pe("__hwjs_park_reason")+Jt*4>>2]>>>0,kn=Fe()[Pe("__hwjs_parked")+Jt*4>>2]>>>0;Kn+=` @${Be}:0x${ht.toString(16)}{m${Yt} a${dn} r${fn} p${kn.toString(16)}}`}if(Be++,Date.now()>Le)break;await new Promise(ht=>setTimeout(ht,2))}_t!==1&&(Kn+=` @final:0x${oe().toString(16)}(b=${_t})`,ot(),wt(`the all-lanes fork barrier did not reach quiesce within 10000 ms whyTrail[lane:clause]:${Kn} (__hwjs_fork_barrier_ok=${_t}: ${_t===-1?"a lane is mid-slice and not host-held":"a lane holds in-flight protocol state"})`),Me=!1)}}else{let tt=W.__hwjs_fork_barrier_ok()|0;if(tt!==1)throw new Error(`M-FLATDRIVE fork latch ${tt===-1?"REFUSED":"not quiesced"}: __hwjs_fork_barrier_ok=${tt} \u2014 the delta=0 whole-memory copy is a whole-arena predicate, legal at barrier-quiesce only (ADR-0004 F87 conf (4))`)}if(Me)try{let tt=await $t({handle:0,owner:0});Fe()[Ne>>2]=tt|0}catch(tt){if(!sn)throw ot(),tt;wt(`fork service failed: ${tt instanceof Error?tt.message:String(tt)}`)}finally{ot()}ue=!0}else if(Qt===xe){if(Vt.EXEC++,Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} FLAT-EXEC-SERVICE status=HWJS_PARK_EXEC path="${Et}"`})}catch{}if(!Ve)throw new Error("M-FLATDRIVE: EXEC park without a latched SYS_execve \u2014 the park leaf fired outside the musl execve protocol");Ve=!1;let et=await Pr(Et,le),mt=Et;if(Et=null,le=0,et&&et.ok&&et.wasmBytes){Tn&&(Vt.tHostMs+=Un()-lt),Qn("execve"),ms=et.wasmBytes,hi=mt;break}Fe()[Je>>2]=ve,Fe()[Ne>>2]=et&&typeof et.errno=="number"?et.errno|0:-2,ue=!0}else if(Qt===Oe){if(Kt)try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${s[ce.PID]|0} FLAT-DLOPEN-SERVICE status=HWJS_PARK_DLOPEN pathPtr=0x${(mn>>>0).toString(16)}`})}catch{}if(!w)throw new Error("HWJS-5: DLOPEN park without a latched SYS_wasm_dlopen \u2014 the park leaf fired outside the musl dlopen protocol");w=!1,Fe()[Je>>2]=ve;let et=typeof W.__hwjs_drive_nest_depth=="function"?W.__hwjs_drive_nest_depth()>>>0:-1,mt;try{mt=await Po({load:o(()=>ka(mn|0,!0),"load"),yieldTurn:o(()=>Es("DLOPEN-LOAD park service"),"yieldTurn"),onYield:o(()=>{Dt&&Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=DLOPEN-LOAD-park site=dlopen-park-service via=wake-word`)},"onYield")})}catch(ot){let wt=tb(ot),Me=wt.cls==="alloc"?" | #70 per-Worker so-module accounting: "+gc():"";V=`[${wt.cls} -> ${wt.errnoName}] ${wt.message}`+Me;let tt=`HWJS-5 dlopen service failed (${wt.cls} -> ${wt.errnoName} ${wt.errno}): ${wt.message}`+Me;e({kind:"user-report",pid:t.pid,message:tt});try{console.error(`[hwjs-dlopen pid=${t.pid}] ${tt}`)}catch{}mt=wt.errno|0,et>=0&&W.__hwjs_drive_nest_unwind_to(et),Fe()[Je>>2]=ve}mn=0,Fe()[Ne>>2]=mt|0,ue=!0}else if(Qt===ve){Vt.NONE++,Lt++,await Ee()&&(ue=!0);let et=typeof W.__wasm_signal_dispatch_pending=="function"?(()=>W.__wasm_signal_dispatch_pending()):typeof W.__wasm32_signal_dispatch_restart=="function"?(()=>W.__wasm32_signal_dispatch_restart(0)):null;if(po()&&et&&typeof W.__hwjs_take_parked=="function"&&typeof W.__hwjs_drive=="function"){let mt=Pe("__hwjs_parked");await ss(()=>{if(et(),(mt?Fe()[mt>>2]>>>0:0)!==0){let wt=W.__hwjs_take_parked(0,0)>>>0,Me=W.__hwjs_drive(wt)>>>0;if(Me!==vt)throw new Error("M-FLATDRIVE breath-dispatch: the libc signal-dispatch trampoline PARKED (status 0x"+Me.toString(16)+") instead of completing \u2014 a signal handler blocked at the breath delivery point, which would corrupt the parked main chain. Refusing to continue this task.")}return 0}),ue=!0}}else if(Qt===it){if(Vt.RESCHED++,Fe()[Je>>2]=ve,Ze&&typeof Ze.exports.__wasm32_migrate_pending=="function"){let mt=0;try{mt=Ze.exports.__wasm32_migrate_pending()>>>0}catch{mt=0}if(mt>0){let ot=mt-1|0;if(ot!==(t.cpuId|0)){if(await Rs(ot)){c=!0;break}}}}let et=Dt?dr():0;Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=RESCHED-park site=flat-drive via=${os!==null?"coop-futex":"wake-word"}`),os!==null?await mr("M-FLATDRIVE"):await Es("M-FLATDRIVE"),Dt&&Mn(e,`RESUME cpu=${t.cpuId??"?"} tid=${t.tid} site=flat-drive waited=${(dr()-et).toFixed(1)}ms`),ue=!0}else{Vt.other++;try{let et=Pe("__hwjs_parked");e({kind:"dmesg",level:6,text:`[a4d-diag] unexpected status=0x${(Qt>>>0).toString(16)} reasonSlot=0x${(Fe()[Je>>2]>>>0).toString(16)} resultSlot=0x${(Fe()[Ne>>2]>>>0).toString(16)} parked=0x${(et?Fe()[et>>2]>>>0:0).toString(16)} budget=${typeof W.__hwjs_budget_get=="function"?W.__hwjs_budget_get():"n/a"}`})}catch{}throw new Error("M-FLATDRIVE: unexpected in-wasm driver status 0x"+(Qt>>>0).toString(16)+" \u2014 not a PARK reason (0 NONE / 1 FORK / 2 EXEC / 4 RESCHED) and not HWJS_DRIVE_DONE (0xD09E) / HWJS_DRIVE_DONE_LIVE (0xD09F). The _start()/__hwjs_drive_resume() return contract diverged; stop-and-report, do not loop.")}ue&&(typeof W.__hwjs_progress_note=="function"&&W.__hwjs_progress_note(),ue=!1),Tn&&(Vt.tHostMs+=Un()-lt),i(),$n("BEFORE re-drive driveCall(__hwjs_drive_resume) [loop]"),Qt=await ss(W.__hwjs_drive_resume),$n(`AFTER re-drive RETURNED status=0x${(Qt>>>0).toString(16)}`)}}finally{Qn("flat-drive-end")}if(c){try{e({kind:"dmesg",level:6,text:`hwjs-migrate pid=${s[ce.PID]|0}: released by cpu=${t.cpuId|0} after the destination committed \u2014 this Worker stops driving the task and runs NO exit path (the process is alive on another lane)`})}catch{}return}}else{let Je=Pe("__hwjs_parked"),Ne=Pe("__hwjs_parked_owner"),vt=Pe("__hwjs_park_reason"),Tt=Pe("__hwjs_park_result"),Lt=0,Pt=0,Tn=!0,Un=0,Vt=typeof W.__hwjs_slice_enter=="function"?W.__hwjs_slice_enter:null,Pn=typeof W.__hwjs_slice_exit=="function"?W.__hwjs_slice_exit:null;if(t.mode==="fork-resume"&&en){if(Lt=typeof t.forkHandle=="number"?t.forkHandle>>>0:0,Pt=typeof t.forkOwner=="number"?t.forkOwner>>>0:0,!Lt)throw new Error("HWJS-3: fork-resume child without a forkHandle rider \u2014 the parent pump must pass the adopted (handle, owner) on the fork message (the taken slot is empty by design)");typeof t.tlsBase=="number"&&typeof W.__wasm32_set_tls_base=="function"&&zt(t.tlsBase,0,!1),typeof t.parentSp=="number"&&t.parentSp!==0&&typeof W.__wasm32_set_stack_pointer=="function"&&W.__wasm32_set_stack_pointer(t.parentSp>>>0);let Qn=Fe()[vt>>2]>>>0;if(Qn!==ve)throw new Error(`HWJS-3: fork-resume child copied a PENDING park reason ${Qn} \u2014 the parent pump clears the reason before the delta=0 copy by contract`);Fe()[Tt>>2]=0,Tn=!1}else{let Qn=md();if(Vt&&Vt(),W._start(),Pn&&Pn(),hd(Qn),Fe()[Je>>2]===0)throw new Error("HWJS-3: _start returned with an EMPTY parked slot \u2014 the program chain neither parked nor exited; __libc_start_main completed (noreturn contract breach)");Pt=Fe()[Ne>>2]>>>0,Lt=W.__hwjs_take_parked(0,0)>>>0,e({kind:"hwjs-host-drive",pid:t.pid,handle:Lt,owner:Pt})}for(;;){if(Tn){let xs=Fe()[vt>>2]>>>0;if(Fe()[vt>>2]=ve,xs===A){if(!Ae)throw new Error("HWJS-3: FORK park without a latched SYS_fork \u2014 the park leaf fired outside the musl _Fork protocol");if(Ae=!1,typeof W.__hwjs_fork_barrier_ok!="function")throw new Error("HWJS-3 fork latch: coro image lacks __hwjs_fork_barrier_ok \u2014 refusing the delta=0 copy without the structural barrier predicate (ADR-0004 F87 conf (4))");let Zn=W.__hwjs_fork_barrier_ok()|0;if(Zn!==1)throw new Error(`HWJS-3 fork latch ${Zn===-1?"REFUSED":"not quiesced"}: __hwjs_fork_barrier_ok=${Zn} \u2014 the delta=0 whole-memory copy is a whole-arena predicate, legal at barrier-quiesce only (ADR-0004 F87 conf (4))`);let Ws=await $t({handle:Lt,owner:Pt});Fe()[Tt>>2]=Ws|0,ue=!0}else if(xs===xe){if(!Ve)throw new Error("HWJS-3: EXEC park without a latched SYS_execve \u2014 the park leaf fired outside the musl execve protocol");Ve=!1;let Zn=await Pr(Et,le),Ws=Et;if(Et=null,le=0,Zn&&Zn.ok&&Zn.wasmBytes){ms=Zn.wasmBytes,hi=Ws;break}Fe()[Tt>>2]=Zn&&typeof Zn.errno=="number"?Zn.errno|0:-2,ue=!0}else if(xs===ve)fm(),Un++,await Ee()&&(ue=!0);else if(xs===it){let Zn=Dt?dr():0;Mn(e,`YIELD cpu=${t.cpuId??"?"} tid=${t.tid} reason=RESCHED-park site=nested-pump via=${os!==null?"coop-futex":"wake-word"}`),os!==null?await mr("HWJS-3 nested pump"):await Es("HWJS-3 nested pump"),Dt&&Mn(e,`RESUME cpu=${t.cpuId??"?"} tid=${t.tid} site=nested-pump waited=${(dr()-Zn).toFixed(1)}ms`),ue=!0}else throw new Error(`HWJS-3: parked chain with UNKNOWN park reason=${xs} \u2014 not a service request (FORK/EXEC/RESCHED) and not a cooperative breath (0); the reason contract has a fourth value this pump does not know`)}Tn=!0,i();let Qn=md();if(Vt&&Vt(),W.hwjs_resume(Lt),W.hwjs_done(Lt))throw Pn&&Pn(),W.hwjs_destroy(Lt),new Error("HWJS-3: program chain ran to DONE \u2014 __libc_start_main completed without exit (noreturn contract breach; the in-module __hwjs_noreturn_completed witness should have fired first)");if(W.__hwjs_take_parked(Pt,Lt),Pn&&Pn(),hd(Qn),ue&&(typeof W.__hwjs_progress_note=="function"&&W.__hwjs_progress_note(),ue=!1),typeof W.__hwjs_drive_watch=="function"&&(W.__hwjs_drive_watch(Lt)|0)===1)throw new Error("HWJS-3 F93: drive-loop PROGRESS backstop tripped \u2014 the chain made stall_bound consecutive zero-progress resume slices (wedged handle 0x"+(Lt>>>0).toString(16)+"). The attributed __hwjs_progress_violation was written to fd 2. This is the F18 chained-unwind / reason-0 spin failing loud+attributed; stop-and-report with the handle, do not iterate.")}}}else for(t.mode==="fork-resume"&&en&&typeof W.asyncify_start_rewind=="function"&&(Qs=0,typeof t.tlsBase=="number"&&typeof W.__wasm32_set_tls_base=="function"&&zt(t.tlsBase,0,!1),W.asyncify_start_rewind(W.__wasm32_asyncify_buf_addr()>>>0));;){let Ee=W._start(),Je=typeof W.asyncify_get_state=="function"?W.asyncify_get_state()|0:M;if(jt&&Je===H){jt=!1,Cs(W.__wasm32_asyncify_buf_addr()>>>0,W.__wasm32_asyncify_buf_size()|0),Qs=await $t()|0,W.asyncify_start_rewind(W.__wasm32_asyncify_buf_addr()>>>0);continue}if(Zs&&Je===H){Zs=!1,Cs(W.__wasm32_asyncify_buf_addr()>>>0,W.__wasm32_asyncify_buf_size()|0);let Ne=await Pr(Et,le),vt=Et;if(Et=null,le=0,Ne&&Ne.ok&&Ne.wasmBytes){ms=Ne.wasmBytes,hi=vt;break}Rt=Ne&&typeof Ne.errno=="number"?Ne.errno|0:-2,W.asyncify_start_rewind(W.__wasm32_asyncify_buf_addr()>>>0);continue}if(Ke&&Je===H){Ke=!1;let Ne=W.__wasm32_asyncify_buf_addr()>>>0;Cs(Ne,W.__wasm32_asyncify_buf_size()|0);let vt=Ne+8>>>0,Tt=Fe()[Ne>>>2]>>>0,Lt=Tt-vt|0,Pt=Bt>>>0;if(Lt<0||Lt>Wb)throw new Error(`setjmp continuation ${Lt}B exceeds jmp_buf capacity ${Wb}B (jb=0x${Pt.toString(16)})`);Fe()[Pt>>>2]=Lt>>>0,od().copyWithin(Pt+mc,vt,Tt),St=0,W.asyncify_start_rewind(Ne);continue}if(nt&&Je===H){nt=!1;let Ne=W.__wasm32_asyncify_buf_addr()>>>0,vt=W.__wasm32_asyncify_buf_size()|0;Cs(Ne,vt);let Tt=Ne+8>>>0,Lt=Nt>>>0,Pt=Fe()[Lt>>>2]>>>0;od().copyWithin(Tt,Lt+mc,Lt+mc+Pt);let Tn=Ne>>>2;Fe()[Tn]=Tt+Pt>>>0,Fe()[Tn+1]=Ne+vt>>>0,W.asyncify_start_rewind(Ne);continue}typeof Ee=="number"&&!l&&(d=Ee&255);break}}}catch(O){if(O===Sc)ms=rn,hi=Et,rn=null;else{if(a&&await y(),l){jn("exit-unwind");return}let ke=O instanceof Error?`${O.message} ${O.stack??""}`:String(O);try{let be=lc(C,t.memory),Ee=dc(be,`pid=${t.pid??"?"} tid=${t.tid|0} terminal trap`);Ee&&e({kind:"dmesg",level:3,text:`${Ee} `})}catch{}if(typeof process<"u"&&process.env?.HWJS_TRAP_DUMP)try{let be=await import("node:fs"),Ee=process.env.HWJS_TRAP_DUMP,Je=`trapdump-pid${t.pid}-lane${t.userLane??"?"}-${Date.now()}`,Ne=new Uint8Array(t.memory.buffer),vt=new Uint8Array(Ne.length);vt.set(Ne),be.writeFileSync(`${Ee}/${Je}.bin`,vt);let Tt=null;try{let Lt=C&&C.__stack_pointer;Lt instanceof WebAssembly.Global&&(Tt=Lt.value>>>0)}catch{}be.writeFileSync(`${Ee}/${Je}.json`,JSON.stringify({pid:t.pid,mode:t.mode,lane:t.userLane??null,memLen:Ne.length,stackPointer:Tt,message:ke},null,2)),e({kind:"dmesg",level:3,text:`HWJS_TRAP_DUMP: wrote ${Je}.bin (${Ne.length}B) sp=${Tt===null?"?":"0x"+Tt.toString(16)}`})}catch(be){e({kind:"dmesg",level:3,text:`HWJS_TRAP_DUMP FAILED: ${be instanceof Error?be.message:String(be)}`})}f("run-terminal-trap"),t.mode==="thread"&&F(),await m(4,1),e({kind:"error",pid:t.pid,message:ke}),jn("error");return}}if(ms){if(Jn=ms,en=!1,kt.size>0){try{e({kind:"dmesg",level:6,text:`hwjs-sys pid=${t.pid} EXEC-DLOPEN-TEARDOWN: dropping ${kt.size} dlopen handle(s) across execve (dl handles do not survive exec; the .so instances died with the replaced address space)`})}catch{}kt.clear()}if(gt.length>0&&(gt.length=0),t.mergedCpu0Lane===!0&&Ps!==null&&t.routeKey!=null){let O;try{O=Ps({kind:"exec-install-sync",routeKey:t.routeKey,wasmBytes:Jn})}catch{O=void 0}if(O!=="installed")try{e({kind:"dmesg",level:4,text:`hwjs-merged EXEC-SYNC DECLINED pid=${t.pid} routeKey=${t.routeKey}: the host did not re-derive the mmap partition through the synchronous door (answer=${O===void 0?"declined":String(O)}), so the new image's first mmaps are served from the pre-exec floor until the exec-image-installed message is delivered.`})}catch{}}e({kind:"exec-image-installed",pid:t.pid,wasmBytes:Jn,...hi?{path:hi}:{}});continue e}break e}l||(await m(d&255,0),_n>0&&e({kind:"dmesg",level:6,text:`wasm32 asyncify continuation high-water: ${_n}B of 65528B usable (pid=${t.pid})`}),e({kind:"exit",pid:t.pid,code:d,wasmSyscallStats:{...xr},...pr>0?{coopWaitViolations:pr}:{},...Br>0?{syncRestartViolations:Br}:{},asyncifyHighWater:_n,...ft?{hwjsLaneCensus:Cb(ft)}:{}})),jn("completed")}function Cb(t){try{return t.reconcile()}catch(e){return{...t.census,reconcileFatal:e instanceof Error?e.message:String(e)}}}function ig(){let t=Date.now();if(!ol){ol=!0,Nb=t;try{setTimeout(()=>{ol=!1},0)?.unref?.()}catch{ol=!1}return 0}return t-Nb}function Zc(t,e,n,s,r){let i=ig();if(i>=rg&&Ps!==null&&e!=null){let l=o((d,a)=>{try{return Ps({kind:"dmesg-sync",routeKey:e,pid:n|0,level:d|0,text:String(a)})}catch{return}},"door");if(!Hb){if(l(4,`hwjs-merged: this realm has not reached its event loop for ${i} ms, so kernel records cannot be POSTED \u2014 the port that carries them (inlineRealm.ts) is drained by the turn this thread is not taking. Every record from here on is delivered through the SYNCHRONOUS door instead, byte-for-byte, on the stalled thread's own stack. They are OUT OF ORDER with respect to records still queued from before this line, which arrive if and when the stall ends. Never-silent: without this the log stops at the last record posted before the wedge and reads as the machine stopping there. `)!=="delivered"){try{t({kind:"dmesg",level:s|0,text:r})}catch{}return}Hb=!0}if(l(s,r)==="delivered")return}try{t({kind:"dmesg",level:s|0,text:r})}catch{}}function Kb(t){if(Array.isArray(t))for(let e of t)!e||typeof e.key!="string"||!(e.module instanceof WebAssembly.Module)||vs.has(e.key)||(vs.set(e.key,e.module),vs.size>cl&&vs.delete(vs.keys().next().value))}function zo(t,e,n,s=2166136261){let r=s>>>0;for(let i=e;i>>0}function og(t){let e=t.length,n=8192,s=zo(t,0,Math.min(n,e)),r=zo(t,Math.max(0,e-n),e),i=e>2*n?zo(t,e-n>>1,(e-n>>1)+n):0;return`${e}:${s.toString(16)}:${i.toString(16)}:${r.toString(16)}`}async function ag(t){let e=og(t),n=Hs.get(e);if(n!==void 0)return ml++,Hs.delete(e),Hs.set(e,n),{module:n,key:e,cached:!0};let s=vs.get(e);if(s!==void 0)return ml++,Pb++,vs.delete(e),vs.set(e,s),Hs.set(e,s),Hs.size>cl&&Hs.delete(Hs.keys().next().value),{module:s,key:e,cached:!0};let r=await WebAssembly.compile(Jb(t));if(Vc++,Hs.set(e,r),Hs.size>cl){let i=Hs.keys().next().value;Hs.delete(i)}vs.set(e,r),vs.size>cl&&vs.delete(vs.keys().next().value);try{Ab?.({kind:"user-image-compiled",key:e,module:r,byteLength:t.length})}catch{}return{module:r,key:e,cached:!1}}function dg(t){let e=zo(t,0,t.length),n=zo(t,0,t.length,3421674724);return`${t.length}:${e.toString(16)}:${n.toString(16)}`}function gc(){return`soCompiles=${xc} soHits=${hl} soCacheSize=${jo.size} liveSoModules=${Oo} soCompiledWireBytes=${zb}`}function jb(){return{userCompiles:Vc,userHits:ml,userCacheSize:Hs.size,userHostAdopted:Pb,userHostMirrorSize:vs.size,soCompiles:xc,soHits:hl,soCacheSize:jo.size,soModulesLive:Oo}}function Fb(t,e){return hl++,{module:t,key:`sha256:${e}`,cached:!0}}function ki(t,e){let n=gi(t);if(n)throw new Error(`hwjs-libc: the retained copy of library ${n.digest.slice(0,16)}\u2026 (${t.length}B of ${n.wireLength}B) was handed to a compile \u2014 it holds no code; the library's Module is kept beside it and must be used instead (never-silent)`);let r=(globalThis.process?.env?.HWJS_70_RED_NOCACHE||"")==="1"?null:jo.find(t,e),i=r?r.key:jo.keyOf(t,e);if(r&&r.module!==void 0)return hl++,{module:r.module,key:i,cached:!0};let l=new WebAssembly.Module(Jb(t));return xc++,zb+=t.length,vb&&(Oo++,vb.register(l,i)),r&&jo.add(r.id,l),{module:l,key:i,cached:!1}}function cg(t,e){let n=WebAssembly.Module.imports(t),s=Object.create(null);for(let r of n){let i=Object.hasOwn(e,r.module)?e[r.module]:void 0;if(!i||!Object.hasOwn(i,r.name))throw new Error(`missing import ${r.module}.${r.name} (${r.kind})`);s[r.module]=s[r.module]??Object.create(null),s[r.module][r.name]=i[r.name]}return s}var ce,tl,Uo,Gi,fZ,cc,yZ,pb,ZZ,gZ,IZ,GZ,uc,fb,WZ,nl,wZ,SZ,an,Eb,Wi,Ic,Ao,al,Gc,yb,Zb,gb,Ib,Wc,kZ,Gb,sl,XZ,RZ,VZ,Wb,mc,wc,BZ,hc,rl,Bs,rs,Xi,Ub,Sc,ll,NZ,dl,bc,HZ,vZ,il,FZ,EZ,pc,_Z,JZ,wb,kc,fc,Lo,UZ,Dt,Sb,kb,dr,MZ,LZ,Pi,Xb,AZ,KZ,Rb,xb,Rc,$Z,Tb,eg,tg,Yb,sg,yc,cl,Hs,Vc,ml,Pb,vs,Ab,Ps,rg,ol,Nb,Hb,lg,xc,hl,zb,Oo,vb,jo,Ob=Or(()=>{"use strict";Ii();Ii();Ii();Ii();rc();Ii();Ii();qa();qa();bb();ce={STATE:0,NR:1,A0:2,A1:3,A2:4,A3:5,A4:6,A5:7,RET_LO:9,RET_HI:10,PID:12,TID:13},tl=1,Uo=2,Gi=0,fZ=60,cc=231,yZ=56,pb=203,ZZ=1040,gZ=1041,IZ=1042,GZ=1043,uc=1044,fb=1045,WZ=1046,nl=1047,wZ=1048,SZ=1049,an=-517,Eb=-513,Wi=o(t=>t==="fork-resume"||t==="thread"||t==="migrate-resume","replaysModuleGraph"),Ic=0,Ao=1,al=2,Gc=3,yb=1e4,Zb=3e3,gb=1,Ib=2,Wc=3,kZ=4,Gb=5;o(_b,"migAbort");sl=1027,XZ=1028,RZ=1029,VZ=1030,Wb=4088,mc=8,wc=null;o(xZ,"setExecImageResolver");BZ=new TextDecoder("utf-8",{fatal:!1}),hc=8;o(TZ,"readKernelScatterImage");o(Jb,"wasmSource");o(Mo,"readKernelStagedImage");o(wi,"decodeMaybeShared");o(YZ,"runA4bCoexistProbe");Bs=null,rs=new Map,Xi=new Map;o(ul,"sharedLibsMerge");Ub={hwjsExitUnwind:!0},Sc={hwjsExecUnwind:!0};o(Si,"isDesignedUnwind");o(CZ,"startCpuWorker");o(Mb,"bindWorker");ll=0,NZ=(()=>{let t=typeof process<"u"&&process.env.HWJS_INITIAL_BUDGET||"",e=parseInt(t,10);return Number.isFinite(e)&&e>0?e:1<<20})(),dl=(()=>{let t=typeof process<"u"&&process.env.HWJS_INITIAL_BUDGET||"",e=parseInt(t,10);return Number.isFinite(e)&&e>0?e:16384})(),bc=(()=>{let t=typeof process<"u"&&process.env.HWJS_SP_REFILL||"",e=parseInt(t,10);return Number.isFinite(e)&&e>0?e:dl})(),HZ=typeof process<"u"&&!!process.env.HWJS_NO_SP_YIELD,vZ=globalThis.process?.env?.HWJS_XMOD_CONSULT_TRACE==="1",il=globalThis.process?.env?.HWJS_FPCAST_TRACE==="1",FZ=1,EZ=new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,127,2,7,1,1,101,1,102,0,0,3,2,1,0,4,4,1,112,0,1,7,17,3,4,108,97,110,101,0,1,1,116,1,0,2,102,98,0,0,9,7,1,0,65,0,11,1,0,10,9,1,7,0,65,0,17,0,0,11]),pc=null,_Z=typeof process<"u"&&!!process.env.HWJS_NO_RECLAIM_RETRY,JZ=(()=>{let t=typeof process<"u"&&process.env.HWJS_RECLAIM_RETRY_ROUNDS?parseInt(process.env.HWJS_RECLAIM_RETRY_ROUNDS,10):NaN;return Number.isFinite(t)&&t>=1&&t<=10?t:3})(),wb=[50,500,2e3],kc=typeof process<"u"&&process.env.HWJS_TEST_GROW_FAIL_MINPAGES?parseInt(process.env.HWJS_TEST_GROW_FAIL_MINPAGES,10)>>>0:0,fc=typeof process<"u"&&process.env.HWJS_TEST_GROW_FAIL_N?parseInt(process.env.HWJS_TEST_GROW_FAIL_N,10)|0:kc>0?1:0,Lo=(()=>{let t=typeof process<"u"&&process.env.HWJS_LANE_WAIT_REPORT_MS?parseInt(process.env.HWJS_LANE_WAIT_REPORT_MS,10):NaN;return Number.isFinite(t)?t|0:2e3})(),UZ=typeof process<"u"&&!!process.env.HWJS_THR_TRACE,Dt=typeof process<"u"&&!!process.env?.HWJS_WORKER_SCHED_TRACE,Sb=(()=>{let t=parseInt(typeof process<"u"&&process.env?.HWJS_WORKER_SCHED_TRACE||"",10);return Number.isFinite(t)&&t>=10?t|0:250})(),kb=(()=>{let t=parseInt(typeof process<"u"&&process.env?.HWJS_WORKER_SCHED_TRACE_HOLD_MS||"",10);return Number.isFinite(t)&&t>=10?t|0:1e3})(),dr=typeof performance<"u"&&typeof performance.now=="function"?()=>performance.now():()=>Date.now();o(Mn,"schedTrace");MZ=1e3,LZ=3e4;o(PZ,"makeWorkerLoopMonitor");Pi={tick(){},end(){},holds:o(()=>0,"holds")};o(Ko,"holdReport");Xb=-517,AZ=0,KZ=2,Rb=65536;o(zZ,"makeHwjsKernelLane");o(Nr,"thrTrace");o(Xc,"instantiateProcessWorkerVmlinux");o(jZ,"makeExecImageLoader");o(Vb,"makeParkYieldWithTurn");o(Po,"driveExecLoadWithYield");xb=-540,Rc=o(t=>t<=-512&&t>=-517&&t!==-515,"isRestartValue");o(OZ,"populateFileMapping");o(QZ,"makeFileMapper");o(DZ,"wasmSignalPendingIn");$Z=12;o(qZ,"taskStateSleeping");o(Bb,"waitTaskRunnable");Tb=0,eg=2,tg=6,Yb=65536;o(ng,"makeSigchldReassert");sg=new Set([9,10,11,12,24,60,231]),yc=new Set([0,1,17,18,19,20,23,7,61,35,230,257,3,270,271,42,43,44,45,46,47,74,75,34,128,130]);o(Lb,"run");o(Cb,"reconcileOrFlag");cl=8,Hs=new Map,Vc=0,ml=0,Pb=0,vs=new Map,Ab=null,Ps=null,rg=1e3,ol=!1,Nb=0,Hb=!1;o(ig,"dmesgLoopStalledMs");o(Zc,"dmesgDeliver");o(Kb,"userImagesMerge");o(zo,"fnv1a32");o(og,"userImageCacheKey");o(ag,"compileUserModule");lg=8,xc=0,hl=0,zb=0,Oo=0,vb=typeof FinalizationRegistry=="function"?new FinalizationRegistry(()=>{Oo=Math.max(0,Oo-1)}):null;o(dg,"soModuleCacheKey");jo=new Ka(lg,dg);o(gc,"soModuleCacheStats");o(jb,"isolateModuleCacheCensus");o(Fb,"storedSoModule");o(ki,"compileSoModule");o(cg,"filterImports")});var Qb={};xd(Qb,{bindInlineWorker:()=>ug});function ug(t){Mb(t)}var Db=Or(()=>{"use strict";Ob();o(ug,"bindInlineWorker")});var v0={};xd(v0,{bindKernelWorker:()=>XG});function XG({post:t,onMessage:e,onTerminate:n,callHostSync:s}){let r={requested:!1};n?.(()=>{r.requested=!0});let i=null,l=null;e(async d=>{try{if(d?.kind==="devices-ready"){if(i=d,l){let a=l;l=null,a()}return}if(d?.kind!=="boot"){t({kind:"error",message:`unknown msg ${d?.kind}`});return}await RG(d,t,r,s,{get:o(()=>i,"get"),wait:o(()=>new Promise(a=>{l=a}),"wait")})}catch(a){let c=a instanceof Error?`${a.message} ${a.stack??""}`:String(a);t({kind:"error",message:c})}})}async function RG(t,e,n={requested:!1},s=void 0,r=void 0){if(Object.prototype.hasOwnProperty.call(t,"initramfs")){e({kind:"error",message:"kernelWorker: initramfs is unsupported; no fallback root."});return}let i=new TextDecoder("utf-8",{fatal:!1}),l=t.pauseBuffer?new Int32Array(t.pauseBuffer):null,d=o(()=>{if(l)for(;Atomics.load(l,0)===1;)Atomics.wait(l,0,1,200)},"maybePause");function a(ne,Ye,Wt){let qt=new Uint8Array(t.kernelMemory.buffer,Ye,Wt),hn=new Uint8Array(Wt);hn.set(qt);let qs=i.decode(hn);e({kind:"dmesg",level:ne|0,text:qs})}o(a,"dmesg");let c=Object.freeze({kind:"virtio-drain-sync"}),h=1e4,p=1e6,m=65535,y=1e3,b=!1,f=0,I=0,R=0,X=!1,F=0;function N(){f=0,I=0,R=0,X=!1}o(N,"noteHostThreadTurn");function K(){let ne=Error.stackTraceLimit,Ye="";try{Error.stackTraceLimit=200,Ye=new Error().stack||""}catch{}finally{try{Error.stackTraceLimit=ne}catch{}}let Wt=[];for(let qt of Ye.split(` `)){let hn=/at\s+(?:([^\s(]+)\s+\()?wasm:\/\/wasm\/[^\s)]*\)?/.exec(qt);if(!hn)continue;let qs=(hn[1]||"").trim();if(Wt.push(qs||""),Wt.length>=24)break}return Wt}o(K,"mergedSpinGuestFrames");function k(ne){if(!b||(++f&m)!==0)return;let Ye=Date.now();if(I===0){I=Ye;return}let Wt=Ye-I;if(!X&&Wt>=y){X=!0;let br=++F;if((br&br-1)===0){let li=K();e({kind:"dmesg",level:4,text:`hwjs-merged SPIN #${br} \u2014 CPU 0 has held the merged JS thread for ${Wt} ms across ${f} linux.${ne} calls with no return to the drive loop (${R} unserviced doorbell(s)). Not fatal yet \u2014 the deadlock verdict needs ${h} ms \u2014 but every co-resident and every device backend on this thread was starved for that whole time. `+(li.length>0?`THE LOOP IS: ${li.join(" <- ")}`:"THE LOOP COULD NOT BE NAMED (no wasm frames in Error.stack on this runtime).")})}}if(Wtlock (arch/wasm32/Kconfig states it), and this tree forks no file outside arch/wasm32. For a driver loop the only lever is CONFIG_WASM32_CORO_SAFEPOINTS, which places a budgeted checkpoint on the back-edge \u2014 default n, and the reason is written at the line that would turn it on (distros/common/linux-6.12/config/common.fragment). `+(qs.length>0?`THE LOOP IS: ${qs.join(" <- ")}`:`THE LOOP COULD NOT BE NAMED: this runtime put no wasm frames in Error.stack, so the guest call path above linux.${ne} is not readable from here \u2014 read it from the kernel side instead.`))}o(k,"mergedSpinCheck");let U=255,M=0;function H(){b&&s!==void 0&&(++M&U)===0&&s(c),k("cpu_relax_host")}o(H,"cpu_relax_host");function Ge(){return typeof performance<"u"&&performance.now&&typeof performance.timeOrigin=="number"?BigInt(Math.round((performance.timeOrigin+performance.now())*1e6)):BigInt(Date.now())*1000000n}o(Ge,"now_ns");function C(ne,Ye,Wt){return b&&s!==void 0&&s(c),k("atomic_wait_i32"),0}o(C,"atomic_wait_i32");function Ie(ne,Ye){return 0}o(Ie,"atomic_notify");let B=o(ne=>(...Ye)=>(e({kind:"unimplemented-host-call",name:ne}),0),"stubHost"),ae=Qa({userMemory:null,kernelMemory:t.kernelMemory,refuse:o(ne=>{throw e({kind:"kernel-trap",message:ne}),new Error(ne)},"refuse"),context:"standalone vmlinux Worker (kthread context)",redPark:!1}),Ce=65536,Q=4096,$=-1,_e=o(()=>{if($<0)return;let ne=new Int32Array(t.kernelMemory.buffer);Atomics.store(ne,$,t.kernelMemory.buffer.byteLength/Q|0)},"publishCommittedPages"),pe=o(ne=>{let Ye=t.kernelMemory,Wt=Ye.buffer.byteLength;if(ne<=Wt)return Wt;let qt=Math.ceil((ne-Wt)/Ce);try{Ye.grow(qt)}catch{}let hn=Ye.buffer.byteLength;return hn!==Wt&&(_e(),e({kind:"kernel-mem-grown",bytes:hn})),hn},"growKernelMemory"),rt={dmesg:a,cpu_relax_host:H,now_ns:Ge,mem_commit:o(ne=>{let Ye=(ne>>>0)*Q;return pe(Ye)/Q>>>0},"mem_commit"),atomic_wait_i32:C,atomic_notify:Ie,...ae.imports,console_write:B("console_write"),console_read_nonblock:B("console_read_nonblock"),hlt:B("hlt"),mmap_user_page:B("mmap_user_page"),munmap_user_page:B("munmap_user_page"),spawn_worker:B("spawn_worker"),terminate_worker:B("terminate_worker"),signal_inject:B("signal_inject"),virtio_kick:o((ne,Ye)=>{R++,e({kind:"virtio-kick",devid:ne>>>0,qidx:Ye>>>0})},"virtio_kick")},we={kernel_memory:t.kernelMemory,...t.kernelImports?.env??{}},Qe=0,It=null,Ct=o(ne=>{if(!Qe||!It)return;let Ye=It[Qe>>2];if(Ye!==0){let Wt=`hwjs runtime gate (host leg): parked slot NOT EMPTY at host import '${ne}' (handle=0x${Ye.toString(16)}) \u2014 a leaked slice crossed the host boundary`;throw e({kind:"kernel-trap",message:Wt}),new Error(Wt)}},"hwjsParkedCheck"),Mt=o((ne,Ye)=>(...Wt)=>(Ct(ne),Ye(...Wt)),"hwjsGuard"),At=o((ne,Ye)=>(...Wt)=>{let qt=Ye(...Wt);return Ct(ne),qt},"hwjsGuardDmesgLast");for(let ne of Object.keys(rt))rt[ne]=(ne==="dmesg"?At:Mt)(`linux.${ne}`,rt[ne]);let q={park:ae.guardPark(Mt("hwjs_suspend.park",()=>{}))},_={env:we,linux:rt,hwjs_suspend:q},D=t.vmlinuxModule;if(!(D instanceof WebAssembly.Module)){e({kind:"instantiate-error",message:t.vmlinuxCompileError?`vmlinux did not compile on the posting thread: ${t.vmlinuxCompileError}`:"boot message carried no compiled vmlinux Module (kernelWorker expects init.vmlinuxModule \u2014 see bootKernel.ts)."});return}let ue=Oa(D);if(ue.length>0){e({kind:"instantiate-error",message:`uaccess-leaf-witness: refusing to boot this vmlinux.wasm: - `+ue.join(` - `)});return}let x=WebAssembly.Module.imports(D),ie=[];for(let ne of x){let Ye=Object.hasOwn(_,ne.module)?_[ne.module]:void 0;(!Ye||!Object.hasOwn(Ye,ne.name))&&ie.push(`${ne.module}.${ne.name} (${ne.kind})`)}if(ie.length>0){e({kind:"link-error",missing:ie});return}let ee;try{if(t.kernelMemory&&H0.has(t.kernelMemory)){e({kind:"instantiate-error",message:`K10-A4 R-K10-W1 invariant violated: vmlinux.wasm has already been instantiated against THIS env.kernel_memory (this realm has instantiated ${N0} kernel(s) in total). The K10-B active-segment overlay assumes single-instance vmlinux per env.kernel_memory; re-instantiation would re-write the .initcall_anchor.* active overlays into shared kernel memory and corrupt the running kernel's initcall arrays. See docs/ARCHITECTURE.md \xA715.3 R-K10-W1 (migration path: switch to strategy A, keeping .initcall*.init segments passive with --defsym anchors). NOTE: a power cycle is NOT this \u2014 each boot builds a fresh PhysRam and therefore a fresh memory \u2014 so if you are seeing this on a restart, the memory was reused and that is the defect to chase, not this refusal.`});return}ee=await WebAssembly.instantiate(D,_),N0+=1,t.kernelMemory&&H0.add(t.kernelMemory)}catch(ne){let Ye=ne instanceof Error?ne.message:String(ne);e({kind:"instantiate-error",message:Ye});return}let P=ee.exports;P.__hwjs_parked&&typeof P.__hwjs_parked.value=="number"&&(Qe=P.__hwjs_parked.value>>>0,It=new Uint32Array(t.kernelMemory.buffer),e({kind:"hwjs-parked-offset",offset:Qe}));let E=o(ne=>P[ne]&&typeof P[ne].value=="number"?P[ne].value>>>0:0,"hwjsDataOffset"),J={highWater:E("__hwjs_frame_high_water"),live:E("__hwjs_frame_live"),allocs:E("__hwjs_frame_allocs")},re=o(()=>!It||!J.highWater?null:{highWater:It[J.highWater>>2],live:It[J.live>>2],allocs:It[J.allocs>>2]},"hwjsArenaStats"),Xe=o(()=>{let ne=re();return ne?` [hwjs arena: high-water=${ne.highWater} live=${ne.live} allocs=${ne.allocs}]`:""},"hwjsArenaSuffix"),Ae=1<<20;if(typeof P.__hwjs_budget_set=="function"&&P.__hwjs_budget_set(Ae|0),typeof P.__wasm_call_ctors=="function")try{P.__wasm_call_ctors()}catch(ne){let Ye=ne instanceof Error?ne.message:String(ne);e({kind:"ctors-trap",message:Ye});return}if(typeof P.wasm_start_kernel!="function"){e({kind:"no-entry",message:"vmlinux.wasm has no wasm_start_kernel export"});return}let Ve=P.__heap_base;if(typeof Ve!="object"||Ve===null||typeof Ve.value!="number"){e({kind:"no-entry",message:"vmlinux.wasm has no __heap_base i32 global export"});return}let me=Ve.value>>>0,je=P.wasm32_committed_pages,de=!!(je&&typeof je.value=="number");de&&($=je.value>>>0>>2);let ve=o(ne=>ne+15&-16,"align16"),A=ve(me),xe=4096,Oe=1,it=4096,Zt=2,Xt=4096,kt=3,Ot=4096,gt=5,at=4096,un=6,xn=4096,zn=7,jn=Number(t.kernelMaxBytes)||t.kernelMemory.buffer.byteLength,jt=t.cmdline??"",Qs=1,_n=!0,Cs=P.wasm32_cpu0_park,Zs=Cs&&typeof Cs.value=="number"?Cs.value>>>0:0,Et=new Uint32Array(t.kernelMemory.buffer),le=new Int32Array(t.kernelMemory.buffer),Gt=0,Re=1,Rt=2;if(_n){if(!Zs){e({kind:"error",message:"COLLAPSED CPU 0: this vmlinux.wasm exports no wasm32_cpu0_park \u2014 it has no merged dispatcher, so its idle path is still memory.atomic.wait32 on __sched_wakeup_word and it would block the one JS thread this machine has (kernel\u2194host lockstep: hardwarejs and packages/modified/linux ship together; deploy order is host first, then machine images). Refusing to boot rather than starting a machine that wedges at its first idle. THERE IS NO OTHER TOPOLOGY TO PUT THIS IMAGE ON \u2014 mergedCpuHost:'separate' was deleted when the merged path booted the appliance end to end \u2014 so the fix is to rebuild the kernel from a tree carrying PLAN-COLLAPSED-CPU0 \xA73.1."});return}let ne=Et[(Zs>>2)+1]>>>0;if(ne!==Qs){e({kind:"error",message:`COLLAPSED CPU 0: this vmlinux.wasm publishes merged-CPU0 ABI version ${ne}; this host speaks version ${Qs}. The park block's layout is the contract between the two halves and a mismatch reads one half's fields at the other's offsets. Refusing.`});return}jt=`${jt}${jt?" ":""}wasm_merged_cpu0`,e({kind:"dmesg",level:6,text:`hwjs-merged: CPU 0 is co-resident with pool lane 1 on this JS thread; vmlinux publishes wasm32_cpu0_park @0x${Zs.toString(16)} (abi ${ne}); cmdline carries wasm_merged_cpu0. `}),e({kind:"dmesg",level:4,text:`hwjs-merged: a guest wait that BLOCKS this thread (an unbounded memory.atomic.wait32) is undetectable from here \u2014 no import runs, no timer fires, and bootKernel's watchdog is on this thread too. A merged machine that goes silent at ~0% CPU is in one; today the known one is spawn.c's host_spawn_process_worker at pid 1's execve, whose cooperative park wasm32_park_allowed() refuses on CPU 0. `}),b=!0}let rn=o(ne=>ne+4095&-4096,"alignPage"),On=rn(me),gs=On,Is=o(ne=>{let Ye=gs;return gs=rn(Ye+ne),Ye},"carveDevice"),Es=0;t.virtioBlk&&(Es=Is(4096),jt=(jt+` wasm_virtblk=0x${Es.toString(16)},0x1000,8,${t.virtioBlk.size/512},${t.virtioBlk.readOnly?1:0}`).trim());let mr=0,mn=0;t.virtioFs&&(mr=Is(xe),jt=(jt+` wasm_virtiofs=0x${mr.toString(16)},0x${xe.toString(16)},${Oe}`).trim()),t.virtioFsCache&&(mn=Is(at),jt=(jt+` wasm_virtiofs_cache=0x${mn.toString(16)},0x${at.toString(16)},${un}`).trim());let w="a8b8g8r8",V=1920,z=1080,se=3840,Ue=2160,Ke=0,nt=0,Bt=0,Nt=0,St=0,Nn=0,$t=0;if(t.framebuffer){Nn=Math.max(V,Math.min(se,t.framebuffer.maxWidth|0||V)),$t=Math.max(z,Math.min(Ue,t.framebuffer.maxHeight|0||z)),nt=t.framebuffer.width|0||640,Bt=t.framebuffer.height|0||480,nt=Math.max(16,Math.min(Nn,nt)),Bt=Math.max(16,Math.min($t,Bt)),Nt=Nn*4,St=Nt*$t+4095&-4096,Ke=Is(St);let ne=`0x${Ke.toString(16)},${nt},${Bt},${Nt},${w},${Nn},${$t}`;jt=(jt+` wasm_drmfb=${ne}`).trim(),t.framebuffer.suppressHotplug&&(jt=(jt+" wasm_drmfb_nohotplug").trim()),t.framebuffer.resizeGateTimeoutMs&&(jt=(jt+` wasm_drmfb_resize_gate=${t.framebuffer.resizeGateTimeoutMs|0}`).trim())}let ns=0;if(t.virtioInput){ns=Is(it);let Ye=t.virtioInput.absolutePointer?1:0;jt=(jt+` wasm_virtinput=0x${ns.toString(16)},0x${it.toString(16)},${Zt}${Ye?`,${Ye}`:""}`).trim()}let ln=0;if(t.virtioNet){ln=Is(Xt);let ne=1,Ye=t.virtioNet.mtu|0,Wt=t.virtioNet.mergeRxBuf?ne:0,qt=Ye>0&&Ye!==1500,hn=qt?Wt?`,${Ye},${Wt}`:`,${Ye}`:"";Wt&&!qt&&e({kind:"error",message:"virtioNet.mergeRxBuf was requested with no mtu (or mtu 1500); the flags field of wasm_virtnet= is positional and cannot be written without an mtu field before it. Set virtioNet.mtu."}),jt=(jt+` wasm_virtnet=0x${ln.toString(16)},0x${Xt.toString(16)},${kt}${hn}`).trim()}let Rs=8192,_s=4,ro=0;t.usbHcd&&(ro=Is(Rs),jt=(jt+` wasm_usb=0x${ro.toString(16)},0x${Rs.toString(16)},${_s}`).trim());let io=0;if(t.virtioConsole){io=Is(Ot);let ne=t.virtioConsole.maxNrPorts|0||2;jt=(jt+` wasm_virtcon=0x${io.toString(16)},0x${Ot.toString(16)},${gt},${ne}`).trim()}let si=0;t.hostTransport&&(si=Is(xn),jt=(jt+` wasm_hosttrans=0x${si.toString(16)},0x${xn.toString(16)},${zn}`).trim()),A=ve(gs);let ri=new TextEncoder().encode(jt),Ur=104,Mr=ve(A+Ur),Wa=ve(Mr+ri.length+1),Bi=64,oo=new Uint8Array(Bi),Lr=!1;try{globalThis.crypto&&typeof globalThis.crypto.getRandomValues=="function"&&(globalThis.crypto.getRandomValues(oo),Lr=!0)}catch{}let ii=Lr?Wa:0,Ds=Lr?Bi:0,Pr=Lr?ve(ii+Bi):Wa,Bn=jn;if(Pr>=Bn){e({kind:"error",message:`kernel memory too small for image + device regions + prologue: heap_base=0x${me.toString(16)} device_block=[0x${On.toString(16)},0x${gs.toString(16)}) usable_start=0x${Pr.toString(16)} total=0x${Bn.toString(16)}`});return}let Ti=de?Pr:Bn;if(pe(Ti)>>0,!0),Ye.setUint32(92,Ds>>>0,!0),Ye.setBigUint64(96,BigInt(t.declaredMemoryBytes??Bn),!0),$s.set(new Uint8Array(ne),A)}$s.set(ri,Mr),$s[Mr+ri.length]=0,Lr&&($s.set(oo,ii),oo.fill(0));let Yi=-1,lo=P.__sched_wakeup_word;lo&&typeof lo.value=="number"&&(Yi=lo.value>>>0,e({kind:"sched-wakeup-word-offset",offset:Yi}));let co=P.wasm32_spawn_ring;co&&typeof co.value=="number"&&e({kind:"spawn-ring-offset",offset:co.value>>>0});let Js=P.wasm32_signal_ring;Js&&typeof Js.value=="number"&&e({kind:"signal-ring-offset",offset:Js.value>>>0});let hr=P.wasm32_tick_req;hr&&typeof hr.value=="number"&&e({kind:"tick-req-offset",offset:hr.value>>>0});let Ar=P.wasm32_user_sab_pages;if(Ar&&typeof Ar.value=="number"&&e({kind:"user-sab-pages-offset",offset:Ar.value>>>0}),de&&(_e(),e({kind:"committed-pages-offset",offset:je.value>>>0})),t.virtioBlk){e({kind:"virtio-blk-window",base:Es>>>0});let ne=P.wasm32_virtio_irq_pending;if(!ne||typeof ne.value!="number")throw new Error("virtio-blk requires wasm32_virtio_irq_pending");e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0})}if(t.virtioFsCache&&e({kind:"virtio-fs-cache-window",base:mn>>>0}),t.virtioFs){e({kind:"virtio-window",base:mr>>>0,size:xe,irq:Oe});let ne=P.wasm32_virtio_irq_pending;ne&&typeof ne.value=="number"?e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0}):e({kind:"error",message:"virtioFs requested but vmlinux.wasm has no wasm32_virtio_irq_pending export"})}if(t.virtioInput){e({kind:"virtio-input-window",base:ns>>>0,size:it,irq:Zt});let ne=P.wasm32_virtio_irq_pending;ne&&typeof ne.value=="number"?e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0}):e({kind:"error",message:"virtioInput requested but vmlinux.wasm has no wasm32_virtio_irq_pending export"})}if(t.virtioNet){e({kind:"virtio-net-window",base:ln>>>0,size:Xt,irq:kt});let ne=P.wasm32_virtio_irq_pending;ne&&typeof ne.value=="number"?e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0}):e({kind:"error",message:"virtioNet requested but vmlinux.wasm has no wasm32_virtio_irq_pending export"})}if(t.usbHcd){e({kind:"usb-window",base:ro>>>0,size:Rs,irq:_s});let ne=P.wasm32_virtio_irq_pending;ne&&typeof ne.value=="number"?e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0}):e({kind:"error",message:"usbHcd requested but vmlinux.wasm has no wasm32_virtio_irq_pending export"})}if(t.virtioConsole){e({kind:"virtio-console-window",base:io>>>0,size:Ot,irq:gt});let ne=P.wasm32_virtio_irq_pending;ne&&typeof ne.value=="number"?e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0}):e({kind:"error",message:"virtioConsole requested but vmlinux.wasm has no wasm32_virtio_irq_pending export"})}if(t.hostTransport){e({kind:"hosttrans-window",base:si>>>0,size:xn,irq:zn});let ne=P.wasm32_virtio_irq_pending;ne&&typeof ne.value=="number"?e({kind:"virtio-irq-pending-offset",offset:ne.value>>>0}):e({kind:"error",message:"hostTransport requested but vmlinux.wasm has no wasm32_virtio_irq_pending export"})}if(t.framebuffer){let ne=P.wasm32_display_ctrl,Ye=ne&&typeof ne.value=="number"?ne.value>>>0:0;e({kind:"fb-window",base:Ke>>>0,width:nt,height:Bt,stride:Nt,size:St,format:w,maxWidth:Nn,maxHeight:$t,ctrlOffset:Ye})}let uo=P.wasm32_pty_bridge_ring;uo&&typeof uo.value=="number"&&e({kind:"pty-bridge-ring-offset",offset:uo.value>>>0});let Rr=P.wasm32_serial_bridge_ring;Rr&&typeof Rr.value=="number"&&e({kind:"serial-bridge-ring-offset",offset:Rr.value>>>0});let mo=2,oi=4,ho=typeof Atomics.waitAsync=="function";_n&&!ho&&e({kind:"dmesg",level:4,text:`hwjs-merged: this runtime has no Atomics.waitAsync \u2014 CPU 0's idle wait falls back to a ${oi}ms macrotask poll of __sched_wakeup_word. Correct (the word is the same, and a missed notify self-heals within one poll) but a wake costs up to ${oi}ms of latency it would not otherwise cost. `});let wa=o(()=>{let ne=Et[(Zs>>2)+2]>>>0,Ye=Et[(Zs>>2)+3]>>>0;if(ne===4294967295&&Ye===4294967295)return 1/0;let Wt=Ye*4294967296+ne;return Math.max(1,Math.ceil(Wt/1e6))},"cpu0ParkDeadlineMs");async function ai(){let ne=wa();if(Yi<0){e({kind:"dmesg",level:3,text:`hwjs-merged: CPU 0 idle-parked but __sched_wakeup_word was never published, so its wake has no address. Falling back to a ${oi}ms turn; this machine's idle costs CPU. `}),await Ls();return}let Ye=Yi>>2;if(ho){let qt=Atomics.waitAsync(le,Ye,0,ne);qt.async?await qt.value:await Ls();return}let Wt=Date.now()+(ne===1/0?1e9:ne);for(;;){if(await Ls(),(Atomics.load(le,Ye)|0)!==0||Date.now()>=Wt||n.requested)return;await new Promise(qt=>setTimeout(qt,oi))}}if(o(ai,"waitForKernelWake"),e({kind:"pre-start"}),_n){let Ye=Date.now(),Wt=r?.get?.()??null;for(;Wt===null&&!n.requested&&(await Ls(),Wt=r?.get?.()??null,!(Wt!==null||Date.now()-Ye>=1e4));)await new Promise(qt=>setTimeout(qt,1));if(Wt===null){let qt=r===void 0?"this realm was bound by a transport that cannot deliver one (no inbound path after 'boot')":`the host never posted one in ${Date.now()-Ye} ms`;e({kind:"error",message:`hwjs-merged: REFUSING to start the kernel \u2014 no 'devices-ready' from the host: ${qt}. Merged, CPU 0 and the device backends share one JS thread, and a guest that reaches an in-kernel busy-wait on a device whose backend does not yet exist holds that thread forever (the virtcons_probe deadlock). Starting anyway would trade a named refusal for a machine that boots to silence.`});return}e({kind:"dmesg",level:6,text:`hwjs-merged: host answered devices-ready after ${Date.now()-Ye} ms (${Wt.built??"unnamed"}) \u2014 every message this realm posted before pre-start has been delivered and acted on, which is what one macrotask turn does NOT prove in a runtime whose port delivers one message per task. Starting the kernel. `})}try{P.wasm_start_kernel(A);let ne=Qe&&It&&typeof P.hwjs_resume=="function"&&typeof P.hwjs_done=="function"&&typeof P.hwjs_destroy=="function"&&typeof P.__hwjs_take_parked=="function",Ye=E("__hwjs_parked_owner");if(ne&&It[Qe>>2]!==0){let Wt=Ye?It[Ye>>2]:0,qt=P.__hwjs_take_parked(0,0)>>>0;e({kind:"hwjs-host-drive",handle:qt,owner:Wt});let hn=0,qs=0,br=0,li=0,Sa=0,bo=Date.now();for(;!P.hwjs_done(qt);){if(d(),_n){let Vr=Atomics.load(le,Zs>>2)|0;if(Vr===Rt?(li++,Atomics.store(le,Zs>>2,Gt)):Vr===Re?(br++,await ai(),N(),Atomics.store(le,Zs>>2,Gt),bo=Date.now()):Date.now()-bo>=mo&&(Sa++,await Ls(),N(),bo=Date.now()),n.requested){e({kind:"dmesg",level:6,text:`hwjs-merged: cooperative stop honoured after ${hn} slice(s); the kernel chain is left PARKED (not destroyed) \u2014 nothing else may resume it, and the frame goes with the realm. `});break}}typeof P.__hwjs_budget_get=="function"&&(P.__hwjs_budget_get()|0)===0&&(qs++,P.__hwjs_budget_set(Ae|0),await Ls(),N()),P.hwjs_resume(qt),hn++,P.__hwjs_take_parked(Wt,qt)}let ka=n.requested&&!P.hwjs_done(qt);ka||P.hwjs_destroy(qt),e({kind:"returned",message:`hwjs host drive loop: top frame 0x${qt.toString(16)} (owner 0x${Wt.toString(16)}) `+(ka?`STOPPED cooperatively after ${hn} slice(s) \u2014 still parked, NOT destroyed`:`driven to done in ${hn} slice(s)`)+` (${qs} budget-expiry breath(es) refilled+yielded`+(_n?`; merged CPU 0: ${br} idle park(s) waited on __sched_wakeup_word, ${li} resume-now park(s), ${Sa} quantum yield(s) at ${mo}ms`:"")+`); wasm_start_kernel never re-enters \u2014 boot ends here by construction.${Xe()}`})}else e({kind:"returned",message:`wasm_start_kernel returned (should not happen)${Xe()}`})}catch(ne){let Ye=ne instanceof Error?`${ne.message} ${ne.stack??""}`:String(ne);e({kind:"kernel-trap",message:Ye+Xe()})}}var N0,H0,F0=Or(()=>{"use strict";rc();qa();N0=0,H0=new WeakSet;o(XG,"bindKernelWorker");o(RG,"boot")});import*as Xr from"node:fs";import*as ni from"node:path";function Mm(t,e){let n=t===0?typeof e=="number"&&e>0?e:1:t;return Math.max(1,Math.min(128,Math.floor(n)))}o(Mm,"resolveVcpu");import{pathToFileURL as FW}from"node:url";function ly(t){try{let e=t.type;if(typeof e!="function")return null;let n=e.call(t);return!n||typeof n.maximum!="number"?null:n.maximum*65536}catch{return null}}o(ly,"reflectUserMemoryMaximumBytes");function Lm(t,e){return t>4294967296?"wasm32-address-space":e!==null&&t>e?"user-max":"host-commit"}o(Lm,"classifyUserMemoryGrowBound");var dy=64*1024*1024,fi=o(t=>(t/(1024*1024)).toFixed(1),"mib");function Pm(t){let e=`user_memory grow REFUSED for pid ${t.pid} (${t.what}): needs ${fi(t.requestedBytes)} MiB (${t.requestedBytes} B), has ${fi(t.currentBytes)} MiB (${t.currentBytes} B)`,n="This is a PER-PROCESS limit on a wasm32 single WebAssembly.Memory, NOT the machine running out of RAM: the machine's RAM is an aggregate spread over the kernel SAB plus one SAB per process, and the other processes are unaffected. The guest sees ENOMEM from this one process.";switch(t.boundBy){case"wasm32-address-space":return`${e}, bounded by the WASM32 ADDRESS SPACE. One WebAssembly.Memory is at most ${fi(4294967296)} MiB (4 GiB, the entire i32 address space) and no setting raises it \u2014 a 64-bit memory would. ${n} Fix: split the work across processes, or lower this process's peak footprint.`;case"user-max":return`${e}, bounded by THIS MEMORY'S DECLARED MAXIMUM of ${t.maximumBytes===null?"(unknown)":`${fi(t.maximumBytes)} MiB`} (PhysRam userMaxBytes). That is a configured per-process cap, well under the ${fi(4294967296)} MiB wasm32 ceiling. ${n} Fix: raise userMaxBytes for this machine.`;case"host-commit":return`${e}, and it was NOT a declared cap: the request fits this Memory's maximum (${t.maximumBytes===null?"not introspectable here":`${fi(t.maximumBytes)} MiB`}) and fits the ${fi(4294967296)} MiB wasm32 ceiling, so the HOST refused to commit the pages. This one IS an out-of-memory condition, but of the browser tab / Node process, not of the guest's declared RAM. Fix: free memory on the host, or run a smaller machine.`}}o(Pm,"describeUserMemoryGrowRefusal");var vi=class{static{o(this,"PhysRam")}opts;kernelMemory;constructor(e){if(!Number.isFinite(e.kernelBytes)||e.kernelBytes<=0)throw new Error(`PhysRam: kernelBytes must be a positive byte count (got ${String(e.kernelBytes)}). This is the machine's physical RAM \u2014 there is no default, because a default is how a machine ends up booting 256 MiB while its spec says otherwise.`);if(e.kernelMaxBytes!==e.kernelBytes)throw new Error(`PhysRam: kernelMaxBytes (${e.kernelMaxBytes}) must equal kernelBytes (${e.kernelBytes}); both name the kernel SAB's SPAN. The initial commit is kernelInitBytes, which is a different, smaller number.`);let n=Math.min(e.kernelInitBytes??dy,e.kernelBytes);if(!Number.isFinite(n)||n<=0)throw new Error(`PhysRam: kernelInitBytes must be a positive byte count (got ${String(e.kernelInitBytes)}).`);let s=e.declaredMemoryBytes??e.kernelBytes;if(!Number.isFinite(s)||s>2,this.publishUserSabPages()}publishUserSabPages(){let e=this.userSabPagesWord;if(e===null)return;let n=0;for(let r of this.userMemLedger){let i=r.ref.deref();i!==void 0&&r.state==="live"&&(n+=i.buffer.byteLength)}let s=Math.floor(n/4096);Atomics.store(e,this.userSabPagesIndex,s|0)}userMemLedger=new Set;userMemEntryByMem=new WeakMap;userMemCollected=0;userMemPool=[];userMemPoolBytes=0;userMemReused=0;userMemPoolLimits(){let e=globalThis.process?.env?.HWJS_USER_MEM_POOL,n=e!==void 0?parseInt(e,10):NaN,s=Number.isFinite(n)&&n>=0?n:8;return{count:s,bytes:s*134217728}}allocUserMemory(e=this.opts.userInitBytes,n=this.opts.userMaxBytes,s=0){let r=this.takePooledUserMemory(e,n,s);if(r)return r;let i=new WebAssembly.Memory({initial:yi(e),maximum:yi(n),shared:!0}),l={ref:new WeakRef(i),state:"live",pid:0,heldFreeBytes:0,freedBytes:0,maxBytes:n};return this.userMemLedger.add(l),this.userMemEntryByMem.set(i,l),this.publishUserSabPages(),i}takePooledUserMemory(e,n,s){let r=yi(e)*65536;for(let i=this.userMemPool.length-1;i>=0;i--){let l=this.userMemPool[i],d=this.userMemEntryByMem.get(l);if(!d||d.maxBytes!==n||l.buffer.byteLength=s.count||this.userMemPoolBytes+r>s.bytes?!1:(n.state="pooled",this.userMemPool.push(e),this.userMemPoolBytes+=r,!0)}userMemoryMaximumBytes(e){let n=this.userMemEntryByMem.get(e);return n?n.maxBytes:ly(e)}noteUserMemoryOwner(e,n){let s=this.userMemEntryByMem.get(e);s&&(s.pid=n|0)}noteUserMemoryExited(e){let n=this.userMemEntryByMem.get(e);n&&n.state==="live"&&(n.state="exited"),this.publishUserSabPages()}noteUserMemoryFreed(e,n){if(!(n>0))return;let s=this.userMemEntryByMem.get(e);s&&(s.heldFreeBytes+=n,s.freedBytes+=n)}noteUserMemoryReused(e,n){if(!(n>0))return;let s=this.userMemEntryByMem.get(e);s&&(s.heldFreeBytes=Math.max(0,s.heldFreeBytes-n))}userMemoryStats(){let e=0,n=0,s=0,r=0,i=0,l=0,d=0,a=0,c=[];for(let h of this.userMemLedger){let p=h.ref.deref();if(p===void 0){this.userMemLedger.delete(h),this.userMemCollected++;continue}let m=Math.floor(p.buffer.byteLength/65536);a+=h.freedBytes,h.state==="live"?(e++,n+=m,d+=h.heldFreeBytes,h.heldFreeBytes>0&&c.push({pid:h.pid,committedBytes:p.buffer.byteLength,heldFreeBytes:h.heldFreeBytes})):h.state==="pooled"?(i++,l+=m):(s++,r+=m)}return c.sort((h,p)=>p.heldFreeBytes-h.heldFreeBytes),this.publishUserSabPages(),{liveCount:e,livePages:n,exitedUncollectedCount:s,exitedUncollectedPages:r,collectedCount:this.userMemCollected,pooledCount:i,pooledPages:l,reusedCount:this.userMemReused,kernelPages:Math.floor(this.kernelMemory.buffer.byteLength/65536),userMaxPages:yi(this.opts.userMaxBytes),userInitPages:yi(this.opts.userInitBytes),heldFreeBytes:d,cumulativeFreedBytes:a,reclaimCandidates:c}}get kernelSize(){return this.kernelMemory.buffer.byteLength}};function yi(t){return Math.ceil(t/65536)}o(yi,"pages");var Bd={read:0,write:1,open:2,close:3,stat:4,fstat:5,lstat:6,poll:7,lseek:8,mmap:9,mprotect:10,munmap:11,brk:12,rt_sigaction:13,rt_sigprocmask:14,rt_sigreturn:15,ioctl:16,pread64:17,pwrite64:18,readv:19,writev:20,access:21,pipe:22,select:23,sched_yield:24,dup:32,dup2:33,nanosleep:35,getpid:39,clone:56,fork:57,vfork:58,execve:59,exit:60,wait4:61,kill:62,uname:63,fcntl:72,getcwd:79,chdir:80,mkdir:83,rmdir:84,link:86,unlink:87,symlink:88,readlink:89,chmod:90,fchmod:91,chown:92,fchown:93,lchown:94,getuid:102,getgid:104,geteuid:107,getegid:108,arch_prctl:158,gettid:186,set_tid_address:218,clock_gettime:228,clock_nanosleep:230,exit_group:231,mknod:133,newfstatat:262,openat:257,mkdirat:258,mknodat:259,fchownat:260,unlinkat:263,linkat:265,symlinkat:266},Am=Object.fromEntries(Object.entries(Bd).map(([t,e])=>[e,t]));var Gw=3;var Km=[0,97,115,109,1,0,0,0],zm=[{id:"shared-memory (threads)",why:"env.kernel_memory is one shared Memory attached by the kernel Worker and every process Worker",supportNote:"requires the wasm threads proposal (universal since ~2021; needs crossOriginIsolated)",bytes:new Uint8Array([...Km,5,4,1,3,1,1])},{id:"bulk-memory",why:"kernel memcpy/memset lower to memory.copy/memory.fill",supportNote:"universal since ~2021",bytes:new Uint8Array([...Km,1,4,1,96,0,0,3,2,1,0,5,3,1,0,1,10,14,1,12,0,65,0,65,0,65,0,252,10,0,0,11])}];function Td(t=e=>WebAssembly.validate(e)){let e=[];for(let s of zm){let r=!1;try{r=t(s.bytes)}catch{r=!1}r||e.push({id:s.id,why:s.why,supportNote:s.supportNote})}if(e.length===0)return{ok:!0,missing:e,message:""};let n=[`REFUSING to boot: this browser's WebAssembly engine lacks ${e.length} feature(s) vmlinux.wasm requires \u2014 nothing was started (linux-in-the-browser#68).`,...e.map(s=>` - ${s.id}: ${s.why}. [${s.supportNote}]`),"Without these the engine rejects the kernel image at WebAssembly.compile, before any Worker or console exists. Use a browser whose engine supports the listed features (desktop/Android Chrome 120+, Edge 120+, Firefox 125+)."];return{ok:!1,missing:e,message:n.join(` `)}}o(Td,"preflightWasmBootSupport");var jm=0,Om=0,Fi=0,Yd=0,Cd=Object.create(null),Vo=Object.create(null),xo=new WeakMap;function Qm(t,e){!t||typeof t!="object"||xo.has(t)||(xo.set(t,e),jm++,Fi++,Fi>Yd&&(Yd=Fi),Cd[e]=(Cd[e]??0)+1,Vo[e]=(Vo[e]??0)+1)}o(Qm,"noteWorkerRealmCreated");function Bo(t){if(!(!t||typeof t!="object"))return xo.get(t)}o(Bo,"workerRealmOrigin");function Ha(t){if(!t||typeof t!="object")return;let e=xo.get(t);e!==void 0&&(xo.delete(t),Om++,Fi=Math.max(0,Fi-1),Vo[e]=Math.max(0,(Vo[e]??0)-1))}o(Ha,"noteWorkerRealmTerminated");function To(){return{live:Fi,created:jm,terminated:Om,peakLive:Yd,createdByOrigin:{...Cd},liveByOrigin:{...Vo}}}o(To,"workerRealmCensus");var va=new Set;function Dm(t){return va.add(t),()=>{va.delete(t)}}o(Dm,"registerSyncDeviceDrain");function $m(){if(va.size!==0)for(let t of va)try{t()}catch{}}o($m,"runSyncDeviceDrain");function qm(t){return t.buffer instanceof SharedArrayBuffer?t.slice():t}o(qm,"privateImageCopy");var Fa;function eh(t){if(!(t.buffer instanceof SharedArrayBuffer))return t;if(Fa===void 0)try{let e=new Uint8Array(new SharedArrayBuffer(8));e.set([0,97,115,109,1,0,0,0]),new WebAssembly.Module(e),Fa=!0}catch{Fa=!1}return Fa?t:t.slice()}o(eh,"wasmSource");var Qr="hwjs.retained",Yo=3+Qr.length+4+32;function Co(t){let e=t?t.length:0;if(e<8+Yo)return null;let n=e-Yo;if(t[n]!==0||t[n+1]!==Yo-2||t[n+2]!==Qr.length)return null;n+=3;for(let i=0;i>>0,r="";for(let i=0;i<32;i++)r+=t[n+4+i].toString(16).padStart(2,"0");return{wireLength:s,digest:r}}o(Co,"retainedLibraryInfo");function Nd(t,e){if(!/^[0-9a-f]{64}$/.test(e))throw new Error(`hwjs-libc: retained copy: ${JSON.stringify(String(e).slice(0,80))} is not a SHA-256 (never-silent)`);let n=t.length;if(n<8||t[0]!==0||t[1]!==97||t[2]!==115||t[3]!==109)throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026 is not a wasm module (never-silent)`);if(Co(t))throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026 is a retained copy already (never-silent)`);let s=[[0,8]],r=8,i=0,l=8;for(;l=n)throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026: the section header at ${l} runs past the module (never-silent)`);let b=t[h++];if(p+=(b&127)*m,m*=128,!(b&128))break}let y=h+p;if(y>n)throw new Error(`hwjs-libc: retained copy: ${e.slice(0,16)}\u2026: section ${c} at ${l} declares ${p}B, past the module's ${n}B (never-silent)`);c===10||c===11?i+=y-l:(s.push([l,y]),r+=y-l),l=y}let d=new Uint8Array(new SharedArrayBuffer(i>0?r+Yo:n)),a=0;for(let[c,h]of s)d.set(t.subarray(c,h),a),a+=h-c;if(i===0)return d;d[a++]=0,d[a++]=Yo-2,d[a++]=Qr.length;for(let c=0;c>>8&255,d[a++]=n>>>16&255,d[a++]=n>>>24&255;for(let c=0;c<32;c++)d[a++]=parseInt(e.slice(c*2,c*2+2),16);return d}o(Nd,"retainedLibraryBytes");var Iy=new TextDecoder;function Zi(t){let e=typeof SharedArrayBuffer<"u"&&t.buffer instanceof SharedArrayBuffer;return Iy.decode(e?t.slice():t)}o(Zi,"decodeMaybeShared");function Hd(t,e,n,s,r){let i=t.byteLength,l=e>>>0,d=n>>>0,a=s>>>0;if(d===0)throw new Error(`hwjs-scatter: ${r} declares 0 segments (sglist 0x${l.toString(16)}, total ${a}B) \u2014 a staged image always has at least one segment; kernel/host ABI skew (never-silent)`);if(d>65536)throw new Error(`hwjs-scatter: ${r} declares ${d} segments, far past anything the kernel's WASM32_IMG_MAX_SEGS cap can produce \u2014 REFUSED as a torn or misread request (never-silent)`);let c=d*8;if(l===0||l>i||c>i-l)throw new Error(`hwjs-scatter: ${r} segment list [0x${l.toString(16)}, +${c}B) (${d} segments) is outside kernel memory (${i}B) \u2014 REFUSED (never-silent)`);let h=new DataView(t,l,c),p=[],m=0;for(let f=0;f>>0,R=h.getUint32(f*8+4,!0)>>>0;if(R===0)throw new Error(`hwjs-scatter: ${r} segment ${f}/${d} has length 0 (offset 0x${I.toString(16)}) \u2014 the kernel never emits empty segments; REFUSED (never-silent)`);if(I===0||I>i||R>i-I)throw new Error(`hwjs-scatter: ${r} segment ${f}/${d} is [0x${I.toString(16)}, +${R}B) which runs past kernel memory (${i}B) \u2014 REFUSED (never-silent)`);if(m+=R,m>a)throw new Error(`hwjs-scatter: ${r} segments through ${f}/${d} already sum to ${m}B but the request declares ${a}B total \u2014 REFUSED (never-silent)`);p.push({off:I,len:R})}if(m!==a)throw new Error(`hwjs-scatter: ${r} segment lengths sum to ${m}B but the request declares ${a}B total \u2014 REFUSED (never-silent)`);let y=new Uint8Array(new SharedArrayBuffer(a)),b=0;for(let f of p)y.set(new Uint8Array(t,f.off,f.len),b),b+=f.len;return y}o(Hd,"readScatterImage");var Ea=16;var th=0,nh=4,sh=8,rh=12,ih=16,oh=20,ah=24,lh=28,dh=32,ch=36;var uh=40,mh=44,hh=48,bh=52,ph=56,fh=60,yh=64,Zh=0,gh=4,Ih=8,Gh=12;var Gy=32,Wy=32,vw=Wy+Ea*yh;function vd(t,e){return t+Gy+e%Ea*yh}o(vd,"ringSlotOffset");var No=class{static{o(this,"SpawnRingConsumer")}kernelMemory;ringOffset;handler;onProcessed;onError;i32;dv;running=!1;stopped=!1;loopDone=null;lastSpawnNotifyValue=0;constructor(e){if((e.ringOffset&3)!==0)throw new Error(`SpawnRingConsumer: ringOffset 0x${e.ringOffset.toString(16)} not 4-byte aligned`);this.kernelMemory=e.kernelMemory,this.ringOffset=e.ringOffset,this.handler=e.handler,this.onProcessed=e.onProcessed,this.onError=e.onError,this.i32=new Int32Array(this.kernelMemory),this.dv=new DataView(this.kernelMemory)}start(){return this.running||this.stopped?this.loopDone??Promise.resolve():(this.running=!0,this.lastSpawnNotifyValue=Atomics.load(this.i32,this.spawnNotifyIdx()),this.loopDone=this.runLoop(),this.loopDone)}async stop(){this.stopped||(this.stopped=!0,Atomics.notify(this.i32,this.spawnNotifyIdx(),1/0),await this.loopDone)}spawnNotifyIdx(){return this.ringOffset+Ih>>>2}resultNotifyIdx(){return this.ringOffset+Gh>>>2}headIdx(){return this.ringOffset+Zh>>>2}tailIdx(){return this.ringOffset+gh>>>2}readSlot(e){let n=vd(this.ringOffset,e);return{mode:this.dv.getUint32(n+th,!0),flags:this.dv.getUint32(n+nh,!0),tid:this.dv.getUint32(n+sh,!0),parentTid:this.dv.getUint32(n+rh,!0),execImageOffset:this.dv.getUint32(n+ih,!0),execImageSize:this.dv.getUint32(n+oh,!0),execImageNsegs:this.dv.getUint32(n+ph,!0),argRegionOffset:this.dv.getUint32(n+ah,!0),stackPointerOffset:this.dv.getUint32(n+lh,!0),tlsPointerOffset:this.dv.getUint32(n+dh,!0),libcImageOffset:this.dv.getUint32(n+uh,!0),libcImageSize:this.dv.getUint32(n+mh,!0),libcDigestOffset:this.dv.getUint32(n+hh,!0),libcImageNsegs:this.dv.getUint32(n+fh,!0),laneId:this.dv.getUint32(n+bh,!0)}}writeResultAndNotify(e,n){let s=vd(this.ringOffset,e);this.dv.setInt32(s+ch,n|0,!0),Atomics.store(this.i32,this.tailIdx(),e+1>>>0),Atomics.add(this.i32,this.resultNotifyIdx(),1),Atomics.notify(this.i32,this.resultNotifyIdx(),1/0)}async runLoop(){try{for(;!this.stopped;){if(Atomics.load(this.i32,this.spawnNotifyIdx())===this.lastSpawnNotifyValue){let n=Atomics.waitAsync(this.i32,this.spawnNotifyIdx(),this.lastSpawnNotifyValue,5e3);if(n.async){let s=await n.value}}if(this.stopped)break;this.lastSpawnNotifyValue=Atomics.load(this.i32,this.spawnNotifyIdx()),await this.drain()}}catch(e){throw this.onError?.(e),e}finally{this.running=!1}}async drain(){let e=Atomics.load(this.i32,this.headIdx())>>>0,n=Atomics.load(this.i32,this.tailIdx())>>>0;for(;e-n>>>0>0;){let s=n%Ea,r=this.readSlot(s),i=0;try{i=await this.handler(r)|0}catch(l){this.onError?.(l),i=-22}this.writeResultAndNotify(n,i),this.onProcessed?.(r,i),n=n+1>>>0}}};function Ed(t,e){return t+32+e%16*32}o(Ed,"signalRingSlotOffset");var _d=null;function ky(){return _d===null&&(_d=typeof process<"u"&&!!(typeof process>"u"?void 0:process)?.env?.HWJS_RED_SIGNAL_HOST_STAMP),_d}o(ky,"hostStampsPendingBitRed");var Xy=17;function Ho(){let t=new Map;return{register(e,n){t.set(e,n)},unregister(e){t.delete(e)},has(e){return t.has(e)},size(){return t.size},lookup(e){return t.get(e)}}}o(Ho,"createSignalTargetRegistry");function Jd(t,e){if(e.sig<1||e.sig>64)return{kind:"bad-signal"};let n=t.lookup(e.tid);if(!n)return{kind:"no-target"};let s=n.userMemory.buffer,r=new Int32Array(s);if(n.signalPendingOffset<0||(n.signalPendingOffset&3)!==0||n.signalPendingOffset+40>s.byteLength)return{kind:"bad-region"};let i=n.signalPendingOffset+0>>>2,l=n.signalPendingOffset+4>>>2,d=n.signalPendingOffset+8>>>2;if(e.sig===Xy){let p=n.signalPendingOffset+24>>>2;Atomics.add(r,p,1)}let a=n.signalPendingOffset+28>>>2,h=(Atomics.load(r,a)>>>0&1)!==0&&!ky();if(!h)if(e.sig<=32){let p=1<{let i=Jd(e,r);if(i.kind==="delivered"){s?.(r,i.rec);return}else{n?.(r);return}}}o(Ud,"makeSignalHandler");function Ua(t){if(t!==void 0){if(!Number.isFinite(t)||(t|0)!==t)throw new Error(`bootKernel({ num_vcpu }): expected an integer, got ${String(t)}.`);if(t<2)throw new Error(`bootKernel({ num_vcpu }): num_vcpu must be >= 2. It counts the KERNEL's CPUs, not the host's threads: CPU 0 is the kthread CPU (the only cpu_online one) and CPU 1 is the first lane a guest task can be placed on, so a machine has at least two even when CPU 0 and lane 1 share ONE JS thread. Got ${t}.`);if(t>129)throw new Error(`bootKernel({ num_vcpu }): num_vcpu must be <= 129 (CONFIG_NR_CPUS compile-time ceiling: 128 pool Workers + CPU 0). Got ${t}.`);return t|0}let e=globalThis.navigator?.hardwareConcurrency??4;return Math.max(2,Math.min(8,e|0))}o(Ua,"resolveNumVcpu");function Xh(){return Ua(void 0)-1}o(Xh,"defaultPoolMaxCpuId");function Ma(t){return Ua(t)-2}o(Ma,"expectedWorkerRealms");var La=o(()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),"nowMs");function Rh(){let t=1,e=new Set,n=[],s=0,r=o(i=>{for(e.delete(i),n.push(i);n.length>64;)n.shift(),s++},"retire");return{open(i){let l=La(),d={rec:{seq:t++,kind:i.kind,state:"placing",pid:null,tgid:i.tgid,parentPid:i.parentPid,spawnTid:i.spawnTid,residency:i.residency,cpuId:i.cpuId,routeKey:i.routeKey,placements:[{cpuId:i.cpuId,atMs:l,why:"spawn"}],image:i.image,execCount:0,sabSharedWithGroup:i.sabSharedWithGroup,signalPendingOffset:null,createdAtMs:l,pidAtMs:null,exitedAtMs:null,exit:null,degradedReason:null},mem:i.userMemory?new WeakRef(i.userMemory):null};return e.add(d),{seq:d.rec.seq,notePid(a,c){d.rec.pid===null&&(d.rec.pid=a|0,d.rec.tgid=c|0,d.rec.pidAtMs=La(),d.rec.state==="placing"&&(d.rec.state="running"))},notePlacement(a,c){d.rec.cpuId=a|0,d.rec.placements.push({cpuId:a|0,atMs:La(),why:c})},noteRouteKey(a){d.rec.routeKey=a},noteExec(a){d.rec.image=a,d.rec.execCount++},noteSignalPendingOffset(a){d.rec.signalPendingOffset=a===void 0?null:a>>>0},noteDegraded(a){d.rec.state!=="exited"&&(d.rec.state="degraded",d.rec.degradedReason=a)},noteExit(a,c){d.rec.state!=="exited"&&(d.rec.state="exited",d.rec.exit={code:a|0,note:c},d.rec.exitedAtMs=La(),r(d))}}},tasks(){let i=[],l=o(d=>{let a=d.mem===null?void 0:d.mem.deref();i.push({...d.rec,placements:d.rec.placements.slice(),image:{...d.rec.image},exit:d.rec.exit===null?null:{...d.rec.exit},sabCommittedBytes:d.mem===null||a===void 0?null:a.buffer.byteLength})},"add");for(let d of e)l(d);for(let d of n)l(d);return i.sort((d,a)=>d.seq-a.seq),i},reapedBeyondRing:o(()=>s,"reapedBeyondRing")}}o(Rh,"makeTaskLedger");function hg(){try{return typeof process<"u"&&process.env?.HWJS_THREAD_FILES_DUP==="1"}catch{return!1}}o(hg,"threadFilesShareDisabled");function Bc(){try{return typeof process<"u"&&process.env?.HWJS_THREAD_DEDICATED_WORKERS==="1"}catch{return!1}}o(Bc,"threadResidencyDisabled");function bg(){try{return typeof process<"u"&&process.env?.HWJS_THREAD_NO_PARENT_REGISTRATION==="1"}catch{return!1}}o(bg,"threadParentRegistrationDisabled");function op(){try{if(typeof process>"u")return null;let t=process.env?.HWJS_THREAD_PLACEMENT_PIN;return typeof t=="string"&&t.trim()!==""?t:null}catch{return null}}o(op,"threadPlacementPinRaw");function ap(t,e){let n=op();if(n===null)return{kind:"none"};let s=new Map;for(let i of n.split(",")){let l=i.trim();if(l==="")continue;let d=/^(-?\d+)\s*:\s*(-?\d+)$/.exec(l);if(!d)return{kind:"error",message:`HWJS_THREAD_PLACEMENT_PIN entry ${JSON.stringify(l)} is not : (whole table: ${JSON.stringify(n)}; grammar: comma-separated lane:cpu pairs, e.g. "5:1,2:3")`};let a=Number(d[1])|0,c=Number(d[2])|0;if(s.has(a)&&s.get(a)!==c)return{kind:"error",message:`HWJS_THREAD_PLACEMENT_PIN names userLane ${a} twice, with conflicting cpus ${s.get(a)} and ${c} (whole table: ${JSON.stringify(n)}) \u2014 refusing to pick one, because guessing which the experiment meant is how a pin produces a fake result`};s.set(a,c)}let r=s.get(t|0);return r===void 0?{kind:"none"}:r<1||r>e?{kind:"error",message:`HWJS_THREAD_PLACEMENT_PIN pins userLane ${t|0} to cpu ${r}, which is outside this machine's pool cpu range 1..${e} (maxCpuId=${e}; cpu 0 is the kernel Worker and is never a pool lane). NOT clamped \u2014 a clamped pin would run the experiment on a cpu nobody chose and report it as the one that was asked for. Raise num_vcpu or name a cpu in range`}:{kind:"pin",cpuId:r,raw:n}}o(ap,"resolveThreadPlacementPin");var pg=0,fg=1,yg=9,Zg=10,gg=11,Ig=12;var Gg=16,Wg=20,wg=28,Sg=56,kg=60,Xg=39,Rg=34;var Vg=218,xg=228,Bg=35,$b=230,Tg=231,Yg=273,Cg=1024,Ng=1025,Hg=0,vg=1,Fg=256,qb=16384,Eg=65536,_g=2097152,ep=112,Jg=1380471895,Ug=1145128274,Mg=1,yr=-38,Zr=-12,tp=-5,bs=-11,Lg=-10,Pg=-98,Ag=4*1024*1024,ks=4096,Kg=1*1024*1024,zg=8*1024*1024,jg=16*1024*1024,Tc=4*1024*1024,Hc=!!globalThis.process?.env?.HWJS_NO_USERMEM_GROW,Og=o(()=>!!globalThis.process?.env?.HWJS_NO_SAB_RECLAIM,"HWJS_NO_SAB_RECLAIM"),Ts=new WeakMap,Ai=new WeakMap,$o=new WeakMap;function yl(t){let e=Ai.get(t);return e||(e=[],Ai.set(t,e)),e}o(yl,"getMmapFreeList");function Qg(t,e){let n=yl(t);for(let s=0;s=e){let i=r.start;return r.start+=e,r.start===r.end&&n.splice(s,1),i}}return-1}o(Qg,"mmapFreeListTake");function Dg(t,e,n){if(n<=e)return 0;let s=yl(t),r=0;for(;r>>0,e]}o(Rn,"readUnsignedLEB");function np(t,e){let n=0,s=0,r=0;do r=t[e++],n|=(r&127)<=c)throw new Error(`hwjs port BUG: __heap_base global index ${r} (defined ${d}) out of range (${c} defined globals)`);for(let h=0;h>>0}for(;a1)throw new Error(`hwjs-libc: ${s} wasm.linux.needed sections on the image \u2014 exactly ONE carrier is legal (never-silent refuse)`);let i;try{i=JSON.parse(Zi(n))}catch(c){throw new Error(`hwjs-libc: malformed wasm.linux.needed payload (not JSON): ${c instanceof Error?c.message:String(c)} (never-silent refuse)`)}let l=Array.isArray(i?.needed)?i.needed:null;if(!l||typeof i.suspenders_sha256!="string")throw new Error("hwjs-libc: wasm.linux.needed payload shape mismatch (never-silent refuse)");if(l.length===0)return null;let d=String(l[0]),a=/^libc\.so\.([0-9a-f]{64})$/.exec(d);if(!a)throw new Error(`hwjs-libc: wasm.linux.needed entry ${JSON.stringify(d)} is not a digest-qualified libc.so name (never-silent refuse)`);return a[1]}o(gl,"imageNeededLibcDigest");function Yc(t,e,n,s=2166136261){let r=s>>>0;for(let i=e;i>>0}o(Yc,"fnv1a32");function eI(t){let e=t.length,n=8192,s=Yc(t,0,Math.min(n,e)),r=Yc(t,Math.max(0,e-n),e),i=e>2*n?Yc(t,e-n>>1,(e-n>>1)+n):0;return`${e}:${s.toString(16)}:${i.toString(16)}:${r.toString(16)}`}o(eI,"userImageKey");function Nc(t,e){let n=!1;try{n=dp(t)}catch{}let s=null;try{s=gl(t)}catch{}return{byteLength:t.length,path:e,importsHwjsRt:n,neededLibcDigest:s}}o(Nc,"imageFactsOf");function Qo(t,e,n){let s=n.pid,r=$g(e),i=Hr(r+Kg,ks),l=dp(e)?zg:0,d=gl(e);if(d!==null&&l===0)throw new Error("hwjs-libc: the image carries wasm.linux.needed but does not import the hwjs runtime (env.__hwjs_frame_alloc) \u2014 a dynamic-libc main is rt-importing by construction; refusing a foreign shape (never-silent)");let a=d!==null?jg:0,c=i+l+a,h=t.buffer.byteLength;if(!(i>=Hr(r,ks)))throw new Error(`hwjs port BUG: mmap_floor 0x${i.toString(16)} < aligned __heap_base 0x${Hr(r,ks).toString(16)} (F30 partition inverted)`);let p=qg(e),m=Math.max(c+Tc,p);if(m>h){if(Hc)throw new Error(`hwjs A-5.a RED arm (HWJS_NO_USERMEM_GROW): need 0x${m.toString(16)} (mmap_floor 0x${i.toString(16)} + headroom 0x${Tc.toString(16)}, module-min 0x${p.toString(16)}) exceeds user_memory 0x${h.toString(16)} and grow-to-fit is disabled (small-initial exec needs grow)`);let b=Math.ceil((m-h)/65536);try{t.grow(b)}catch{throw new Error(Zl(n.ram,t,s,"exec grow-to-fit",m)+` [partition detail: mmap_floor 0x${i.toString(16)} + headroom 0x${Tc.toString(16)}, module-declared minimum 0x${p.toString(16)}, grow-to-fit needed ${b} pages; lowering BRK_RESERVE also shrinks the requirement]`)}if(h=t.buffer.byteLength,m>h)throw new Error(`hwjs port BUG: grow-to-fit by ${b} pages did not satisfy need 0x${m.toString(16)} (now 0x${h.toString(16)}; F30 partition does not fit)`)}if(c0?i:0,rtWindowSize:l,libcWindowBase:a>0?i+l:0,libcWindowSize:a};return cr.set(t,y),lp.push({memBytes:h,heapBase:r,mmapFloor:i,brkHighWater:r}),y}o(Qo,"initUserMemoryPartition");function bl(t){let e=Ts.get(t);if(e===void 0)throw new Error("hwjs port BUG: user_memory mmap floor not initialized before mmap/region alloc \u2014 the F30 partition for this Memory is absent (retired WASM_MMAP_BASE default must never be hit). Either it was never set at instance-creation, or it was RECLAIMED by a process exit while a task still dispatching against this Memory was alive \u2014 a thread of that group is the case that has actually happened");return e}o(bl,"getUserBump");function cp(t){let e=$o.get(t),n;if(e&&e.length>0)n=e.pop();else{let i=bl(t);i=Hr(i,ks);let l=t.buffer.byteLength;if(i+ks>l){if(Hc)return-1;let d=Math.ceil((i+ks-l)/65536);try{t.grow(d)}catch{return-1}if(l=t.buffer.byteLength,i+ks>l)return-1}n=i,Ts.set(t,i+ks)}let s=t.buffer;return new Uint8Array(s,n,40).fill(0),n}o(cp,"allocSignalPendingRegion");function Ri(t,e){if(typeof e!="number"||e<=0)return;let n=$o.get(t);n||(n=[],$o.set(t,n)),n.push(e)}o(Ri,"freeSignalPendingRegion");function tI(t,e,n){return t.some(s=>s.cpuId!==e&&n(s))?t.filter(s=>s.cpuId!==e):[...t]}o(tI,"placementCandidates");function ta(t){let e=new Map,n=Rh(),s=new Map,r=new SharedArrayBuffer(256),i=Math.max(1,t.maxCpuId??Xh()),l=1,d=o(w=>w===l,"laneIsMerged"),a=Math.max(i,(t.laneCeiling??i)|0),c=null,h=new Map,p=new Map,m=new Map,y=o(w=>{let V=w;if(typeof V?.routeKey=="number"){if(V.kind==="syscall-sync"){let z=h.get(V.routeKey);return z?z():void 0}if(V.kind==="dmesg-sync"){if(!t.onDmesg)return;let z=V;return t.onDmesg((Number(z.level)|0)>>>0,String(z.text??""),typeof z.pid=="number"?z.pid|0:-1),"delivered"}if(V.kind==="task-register-sync"){let z=p.get(V.routeKey);if(!z)return;let se=typeof V.pid=="number"?V.pid|0:0;return se>0?z(se):void 0}if(V.kind==="exec-install-sync"){let z=m.get(V.routeKey),se=V.wasmBytes;return!z||!(se instanceof Uint8Array)||se.length===0?void 0:z(se)}}},"mergedSyscallDoor"),b=o(w=>{let V=y(w);return V!==void 0?V:c!==null?c(w):void 0},"mergedRealmDoor"),f=o(w=>{c=w;for(let V of I)V.setHostSyncCall?.(b)},"setHostSyncCall"),I=[],R=o(w=>{if(!Number.isFinite(w))return;let V=Math.max(i,w|0);V!==a&&(a=V,t.onDmesg?.(6,`hwjs-lanes: dedicated-Worker lane band = ${i+1}..${a} (pool holds 1..${i}); thread Workers are kernel-lane disjoint from pool residents by construction `,-1))},"setLaneCeiling"),X=o(w=>{for(let V of B)if(V.cpuId===w)return V.residentCount>0;return!1},"poolLaneBusy"),F=new Set,N=new Map,K=o((w,V)=>{for(let z=a;z>i;z--)if(!F.has(z))return F.add(z),N.set(w,z),z;for(let z=0;z<2;z++)for(let se=i;se>=1;se--)if(!(V!==void 0&&se===V&&i>1)&&!d(se)&&!F.has(se)&&!(z===0&&X(se)))return F.add(se),N.set(w,se),X(se)&&t.onDmesg?.(4,`hwjs-lanes: dedicated Worker tid=${w} placed on kernel lane ${se}, which a POOL Worker with live residents also uses \u2014 the lane mutex is now shared with an independently-scheduled peer (a peer parked in an unbounded in-kernel wait will stall this Worker). Raise num_vcpu so the dedicated band (${i+1}..) has room. `,w),se;return V!==void 0&&V>=1&&V<=i&&!d(V)&&!F.has(V)?(F.add(V),N.set(w,V),V):0},"allocateCpuId"),k=o(w=>{let V=N.get(w);V!==void 0&&(F.delete(V),N.delete(w))},"releaseCpuId"),U=o((w,V,z)=>{if(!(w>i)||w<1)return;let se=new Int32Array(r);if(w>=se.length||Atomics.load(se,w)===0)return;let Ue=32+w;Ue{for(let w=a;w>i;w--)if(!F.has(w))return F.add(w),w;for(let w=0;w<2;w++)for(let V=i;V>=1;V--)if(!d(V)&&!F.has(V)&&!(w===0&&X(V)))return F.add(V),V;return 0},"allocateCpuIdValue"),H=o(w=>{F.delete(w)},"releaseCpuIdValue"),Ge=t.platform??Fc(),C=i,Ie=t.vmlinuxModule!==void 0,B=[],ae=new Map,Ce=1,Q=0,$=0,_e=o(w=>{Q=Math.max(0,Q+w),Q>$&&($=Q)},"noteResidentDelta"),pe=new Map,Ut=0,rt=o(w=>({group:w===void 0?--Ut:w}),"newLaneOwner"),we=o((w,V)=>{let z=pe.get(w);z||(z=new Set,pe.set(w,z)),z.add(V)},"laneOccupy"),Qe=o((w,V)=>{let z=pe.get(w);z&&(z.delete(V),z.size===0&&pe.delete(w))},"laneRelease"),It=o(w=>{let V=new Set;for(let[z,se]of pe)for(let Ue of se)if(Ue.group!==w){V.add(z);break}return V},"lanesOwnedByOthers"),Ct=o(()=>{let w=new Set;for(let[V,z]of pe)z.size>0&&w.add(V);return w},"lanesCarryingAnyOwner"),Mt=o(w=>{let V=pe.get(w);return V&&V.size>0?[...V].map(z=>z.group).sort((z,se)=>z-se).join(","):"none"},"laneOwnerText"),At=new Map,q=t.kernelMemory,_=new Int32Array(q),D=!1,ue=o(w=>{let V=At.get(w>>>0);if(!V)return;let z=t.kernelMemoryWasm?.buffer;z!==void 0&&z!==q&&(q=z,_=new Int32Array(z));let se=V>>>0>>>2;if((V&3)!==0||se>=_.length){D||(D=!0,console.error(`kernelSpawnHandler: REFUSING the task wake for pid ${w} \u2014 published address ${V>>>0} (index ${se}) is not addressable in guest RAM: the view is ${_.length} words / ${_.length*4} bytes, live kernel_memory is ${q.byteLength} bytes. The view is LIVE, so this is not a stale snapshot \u2014 that address is not a task_struct field. The parent will fall back to its cooperative timeout, so forks still complete but pay the wait. Reported once.`));return}Atomics.add(_,se,1),Atomics.notify(_,se,1/0)},"wakeTaskByPid"),x=new Set,ie=!1,ee=new Map,P=1,E=o(w=>{let V=ee.get((w?.seq|0)>>>0);V&&V(w)},"deliverTaskProbeReply"),J=new Map,re=o(()=>[...J].map(([w,V])=>({digest:w,bytes:V.bytes,...V.module?{module:V.module}:{}})),"sharedLibsForInit"),Xe=o((w,V,z,se)=>{if(!/^[0-9a-f]{64}$/.test(w))return t.onUserError?.(-1,`hwjs-libc: shared-lib delivery (${z}) with a malformed digest ${JSON.stringify(w.slice(0,80))} \u2014 REFUSED (never-silent)`),Promise.resolve(!1);if(J.has(w))return Promise.resolve(!0);let Ue=V instanceof Uint8Array?V:new Uint8Array(V),Ke=Co(Ue);if(Ke&&(Ke.digest!==w||!(se instanceof WebAssembly.Module)))return t.onUserError?.(-1,`hwjs-libc: shared-lib delivery (${z}) for libc.so.${w.slice(0,16)}\u2026 is the retained copy of ${Ke.digest.slice(0,16)}\u2026 ${se instanceof WebAssembly.Module?"under another digest":"with no Module"} \u2014 REFUSED (never-silent)`),Promise.resolve(!1);if(!Ke&&se instanceof WebAssembly.Module){let Nt="";try{Co(Nd(Ue,w))&&(Nt=`brings a Module with the whole file (${Ue.length}B), not its retained copy`)}catch(St){Nt=`brings a Module with bytes that are no module: ${St instanceof Error?St.message:String(St)}`}if(Nt)return t.onUserError?.(-1,`hwjs-libc: shared-lib delivery (${z}) for libc.so.${w.slice(0,16)}\u2026 ${Nt} \u2014 REFUSED (never-silent)`),Promise.resolve(!1)}let nt={bytes:Ue};if(J.set(w,nt),se instanceof WebAssembly.Module){nt.module=se;for(let Nt of B)try{Ks(Nt.worker,{kind:"shared-lib",sharedLibs:[{digest:w,bytes:Ue,module:se}]})}catch{}return t.onDmesg?.(6,`hwjs-libc: host retained libc.so.${w.slice(0,16)}\u2026 (${Ue.length}B of ${Ke?Ke.wireLength:Ue.length}B, ${z}); took the Module compiled there; broadcast to ${B.length} pool worker(s) `,-1),Promise.resolve(!0)}let Bt=(async()=>{try{let Nt=qm(Ue),St=globalThis.crypto?.subtle;if(St){let ln=await St.digest("SHA-256",Nt),Rs=[...new Uint8Array(ln)].map(_s=>_s.toString(16).padStart(2,"0")).join("");if(Rs!==w)return J.delete(w),t.onUserError?.(-1,`hwjs-libc: HOST CONTENT SKEW \u2014 delivered libc.so.${w.slice(0,16)}\u2026 (${z}) hashes to ${Rs.slice(0,16)}\u2026; delivery REFUSED machine-wide (never-silent)`),!1}let Nn=await WebAssembly.compile(Nt),$t=Nd(Ue,w),ns=J.get(w);ns&&(ns.module=Nn,ns.bytes=$t);for(let ln of B)try{Ks(ln.worker,{kind:"shared-lib",sharedLibs:[{digest:w,bytes:$t,module:Nn}]})}catch{}return t.onDmesg?.(6,`hwjs-libc: host retained libc.so.${w.slice(0,16)}\u2026 (${$t.length}B of ${Ue.length}B, ${z}); compiled once; broadcast to ${B.length} pool worker(s) `,-1),!0}catch(Nt){return J.delete(w),t.onUserError?.(-1,`hwjs-libc: host retention of libc.so.${w.slice(0,16)}\u2026 (${z}) FAILED: ${Nt instanceof Error?Nt.message:String(Nt)} (never-silent)`),!1}})();return nt.pending=Bt,Bt.then(()=>{nt.pending===Bt&&delete nt.pending},()=>{nt.pending===Bt&&delete nt.pending}),Bt},"deliverSharedLib"),Ae=o(w=>J.get(w)?.pending,"sharedLibDeliveryPending"),Ve=8,me=new Map,je=o(w=>{let V=me.get(w);V&&(me.delete(w),me.set(w,V))},"userImagesBump"),de=o(()=>{for(;me.size>Ve;){let w=me.keys().next().value;if(w===void 0)break;me.delete(w)}},"userImagesEvict"),ve=o(()=>{let w=[];for(let[V,z]of me)z.module&&w.push({key:V,module:z.module});return w},"userImagesForInit"),A=o((w,V,z)=>{let se=0;for(let Ue of B)if(!(z!==void 0&&Ue.worker===z))try{Ks(Ue.worker,{kind:"user-image",userImages:[{key:w,module:V}]}),se++}catch{}return se},"broadcastUserImage"),xe=o(w=>{if(!(w instanceof Uint8Array)||w.length===0)return Promise.resolve(null);let V=eI(w),z=me.get(V);if(z){if(je(V),z.module)return Promise.resolve(z.module);if(z.pending)return z.pending}let se={byteLength:w.length};me.set(V,se),de();let Ue=(async()=>{try{let Ke=await WebAssembly.compile(eh(w)),nt=me.get(V);nt===se&&(nt.module=Ke);let Bt=A(V,Ke);return t.onDmesg?.(6,`hwjs-image: host compiled user image ${V} (${w.length}B) ONCE; broadcast to ${Bt} pool worker(s) `,-1),Ke}catch(Ke){return me.delete(V),t.onUserError?.(-1,`hwjs-image: host compile of user image ${V} (${w.length}B) FAILED: ${Ke instanceof Error?Ke.message:String(Ke)} \u2014 the placing Worker will compile it locally (slower, not wrong) (never-silent)`),null}})();return se.pending=Ue,Ue.then(()=>{se.pending===Ue&&delete se.pending},()=>{se.pending===Ue&&delete se.pending}),Ue},"userImageModule"),Oe=o((w,V)=>{let z=w;if(typeof z.key!="string"||!(z.module instanceof WebAssembly.Module))return;if(me.get(z.key)?.module){je(z.key);return}me.set(z.key,{module:z.module,byteLength:typeof z.byteLength=="number"?z.byteLength:0}),de();let Ue=A(z.key,z.module,V);t.onDmesg?.(6,`hwjs-image: adopted a pool-compiled user image ${z.key} (${typeof z.byteLength=="number"?z.byteLength:"?"}B); broadcast to ${Ue} other pool worker(s) `,-1)},"noteWorkerCompiledUserImage"),it=o(async(w,V="pool")=>{if(d(w)){let[{createInlineRealm:se},{bindInlineWorker:Ue}]=await Promise.all([Promise.resolve().then(()=>(Ld(),Md)),Promise.resolve().then(()=>(Db(),Qb))]),Ke=se(Ue,`pool-inline-cpu${w}`),nt=Bo(Ke)!==void 0;return I.push(Ke),Ke.setHostSyncCall(b),t.onDmesg?.(nt?3:6,`hwjs-merged: pool lane ${w} is INLINE \u2014 it shares this thread with CPU 0, and every other lane keeps its Worker. MEASURED: the realm census ${nt?"COUNTS this lane's realm, so it DID take a host Worker and the merge did not happen here":"does not hold it, so this lane has no host Worker realm"}. `,-1),Zt(Ke,w)}let z=await Ec(t.workerEntry,Ge,V);return Zt(z,w)},"createPoolWorker"),Zt=o(async(w,V)=>{let z={worker:w,cpuId:V,residentCount:0};return _c(w,se=>{let Ue=se?.routeKey;if(Ue!=null){let Ke=ae.get(Ue);if(Ke){Ke(se);return}return}se?.kind==="dmesg"?t.onDmesg?.((se.level|0)>>>0,String(se.text),-1):se?.kind==="task-probe-reply"?E(se):se?.kind==="error"||se?.kind==="user-report"?t.onUserError?.(-1,String(se.message??"")):se?.kind==="user-image-compiled"&&Oe(se,w)}),Jc(w,se=>{t.onUserError?.(-1,`pool CPU-Worker cpu_id=${V} crashed: ${se instanceof Error?`${se.message} ${se.stack}`:String(se)}`)}),Ks(w,{kind:"cpu-worker",cpuId:V,...d(V)?{mergedCpu0Lane:!0}:{},...t.vmlinuxModule!==void 0?{vmlinuxModule:t.vmlinuxModule}:{},...t.hwjsRtModule!==void 0?{hwjsRtModule:t.hwjsRtModule,hwjsRtBytes:t.hwjsRtBytes,hwjsRtProvenance:t.hwjsRtProvenance}:{},...J.size>0?{sharedLibs:re()}:{},...me.size>0?{userImages:ve()}:{},...t.kernelMemoryWasm===void 0?{kernelMemory:t.kernelMemory}:{},...t.kernelMemoryWasm!==void 0?{kernelMemoryWasm:t.kernelMemoryWasm}:{},kernelLaneLocks:r,...t.pauseBuffer!==void 0?{pauseBuffer:t.pauseBuffer}:{}}),ie?(vr(w),null):(B.push(z),z)},"initPoolWorker"),Xt=Promise.resolve();Ie&&(Xt=(async()=>{let w=[];for(let V=1;V<=C;V++)w.push(it(V));await Promise.all(w)})(),Xt.catch(()=>{}));let kt=new Map,Ot=3e4,gt=o(async(w,V,z,se)=>{if(await Xt,ie||B.length===0)throw new Error("kernelSpawnHandler: spawn after dispose() / empty pool");if(z!==void 0){let ln=B.find(Rs=>Rs.cpuId===z);if(ln)return ln;throw new Error(`HWJS_THREAD_PLACEMENT_PIN names pool cpu=${z}, which is in range but has NO LIVE pool Worker right now (live lanes: ${B.map(Rs=>Rs.cpuId).join(",")||"none"}) \u2014 refusing to substitute another lane, because a substituted pin reports a placement the experiment never ran`)}let Ue=Date.now(),Ke=o(ln=>(kt.get(ln)??0)>Ue,"suspect"),nt=o(ln=>ln.reduce((Rs,_s)=>_s.residentCount!V?.has(ln.cpuId)&&!Ke(ln.cpuId),"usable")).filter(ln=>!V?.has(ln.cpuId)),St=Nt.filter(ln=>!Ke(ln.cpuId)),Nn=St.filter(ln=>!se?.has(ln.cpuId)),$t=Nn.filter(ln=>ln.cpuId!==w);if($t.length>0)return nt($t);if(Nn.length>0)return nt(Nn);let ns=St.filter(ln=>ln.cpuId!==w);return ns.length>0?nt(ns):St.length>0?nt(St):Nt.length>0?nt(Nt):nt(B)},"getPoolWorker"),at=o(w=>{kt.set(w,Date.now()+Ot)},"markLaneSuspect"),un=o(w=>{kt.delete(w)},"markLaneLive"),xn=null,zn=o(async w=>{let V=0;if(Ie&&!ie){try{await Xt}catch{}let se=B.filter(Ue=>Ue.residentCount===0&&!d(Ue.cpuId));t.onDmesg?.(6,`hardwarejs#7 reclaim(${w}): lane ${l} is the merged CPU-0 lane and has no realm to destroy \u2014 it is skipped, so its exited residents' user SABs wait for engine GC. Every other idle lane recycles as usual. `,-1);for(let Ue of se){if(ie)break;if(Ue.residentCount!==0||!B.includes(Ue))continue;let Ke=null;try{Ke=await it(Ue.cpuId,"pool-recycle")}catch(nt){t.onDmesg?.(3,`hardwarejs#7 reclaim(${w}): replacement pool Worker for lane cpu=${Ue.cpuId} failed to spawn (${nt instanceof Error?nt.message:String(nt)}) \u2014 keeping the old Worker `,-1);continue}if(Ke===null)break;if(Ue.residentCount===0){let nt=B.indexOf(Ue);nt>=0&&B.splice(nt,1);try{await vr(Ue.worker)}catch{}V++}else{let nt=B.indexOf(Ke);nt>=0&&B.splice(nt,1);try{await vr(Ke.worker)}catch{}}}}let z=globalThis.gc;if(typeof z=="function")try{z()}catch{}return V>0&&t.onDmesg?.(6,`hardwarejs#7 reclaim(${w}): recycled ${V} idle pool Worker(s) (fresh realm per lane; exited processes' user SAB backing stores drop with the old realms) `,-1),{recycledWorkers:V}},"reclaimUserMemorySweep"),jn=o(w=>{if(xn)return xn;let V=zn(w).finally(()=>{xn===V&&(xn=null)});return xn=V,V},"reclaimUserMemory"),jt=250,Qs=o(()=>{let w=globalThis.process?.env?.HWJS_PROACTIVE_RECLAIM_PAGES,V=w!==void 0?parseInt(w,10):NaN;return Number.isFinite(V)&&V>=0?V:512},"proactiveReclaimThresholdPages"),_n=null,Cs=o(()=>{ie||Qs()!==0&&_n===null&&(_n=setTimeout(()=>{if(_n=null,ie)return;let w=Qs();if(w===0)return;let V=t.ram.userMemoryStats?.();!V||V.exitedUncollectedPages= ${w}-page threshold`).catch(()=>{})},jt),_n.unref?.())},"noteProcessExitForReclaim"),Zs=o(async()=>{if(ie)return;ie=!0,_n!==null&&(clearTimeout(_n),_n=null);try{await Xt}catch{}let w=[...B.map(V=>V.worker),...x];B.length=0,x.clear();for(let V of w)try{await vr(V)}catch{}ae.clear(),e.clear(),s.clear(),F.clear(),N.clear(),At.clear(),Q=0,$=0},"dispose"),Et=new Map,le=new Map,Gt=256,Re={allocate(w,V){let z=le.get(w);z||(z=new Map,le.set(w,z));let se=V>>>0,Ue=z.get(se);if(Ue!==void 0)return Ue;if(z.size>=Gt)return-1;let Ke=z.size;return z.set(se,Ke),Ke},dropParent(w){le.delete(w)}},Rt=new Map,rn=2e3,On=new Map,gs=new Set,Is=o(w=>{let V=On.get(w);if(V){On.delete(w);for(let z of V)try{z()}catch(se){t.onDmesg?.(3,`hwjs group-empty hook for pid=${w} threw: ${se instanceof Error?se.message:String(se)} (loud; whatever it was going to release stays held) `,w)}}},"runGroupEmpty"),mr=Object.assign({},t,{__threadContain:{note(w,V){gs.add(w);let z=Et.get(w);z||(z=new Set,Et.set(w,z)),z.add(V)},drop(w,V){let z=Et.get(w);z&&(z.delete(V),z.size===0&&(Et.delete(w),Is(w)))},consumeEverThreaded(w){return gs.delete(w)},whenGroupEmpty(w,V){if((Et.get(w)?.size??0)===0){V();return}let z=On.get(w);z||(z=[],On.set(w,z)),z.push(V)},registerReaper(w,V){Rt.set(w,V)},dropReaper(w){Rt.delete(w)},liveThreads(w){return Et.get(w)?.size??0},reapGroupAfter(w,V,z){let se=[...Et.get(w)??[]].filter(Ke=>Ke!==V);if(se.length===0)return;setTimeout(()=>{for(let Ke of se){let nt=Rt.get(Ke);if(nt){t.onDmesg?.(3,`hwjs group-death REAP: thread tid=${Ke} of pid=${w} survived the group's death ${rn} ms after the stamp (${z}) \u2014 a signal-blind park (e.g. a cooperative wait on a dead holder's lock). Reaping: Worker terminated, cpu lane + cleartid + signal page + registrations released (native SIGKILL is not refusable; a wedged sibling must not leak machine thread capacity) `,Ke);try{nt(z)}catch(Bt){t.onDmesg?.(3,`hwjs group-death REAP tid=${Ke} FAILED: ${Bt instanceof Error?Bt.message:String(Bt)} (loud; the lane may stay leaked \u2014 report it) `,Ke)}}}},rn).unref?.()},killGroup(w,V,z=9,se="trapped terminally"){let Ue=0,Ke=[w,...Et.get(w)??[]].filter(nt=>nt!==V);if(t.signalRegistry)for(let nt of Ke){let Bt={tid:nt,sig:z|0,senderPid:V},Nt=t.signalRegistry.lookup(nt);if(Nt){let Nn=new Int32Array(Nt.userMemory.buffer),$t=z|0;$t>=1&&$t<=32?Atomics.and(Nn,Nt.signalPendingOffset+16>>>2,~(1<<$t-1)):$t>=33&&$t<=64&&Atomics.and(Nn,Nt.signalPendingOffset+20>>>2,~(1<<$t-33))}let St=Jd(t.signalRegistry,Bt);if((typeof process>"u"?void 0:process)?.env?.HWJS_DBG_KILLGROUP){let Nn="";if(St.kind==="delivered"){let $t=new Int32Array(St.rec.userMemory.buffer),ns=St.rec.signalPendingOffset>>>2;Nn=` off=0x${St.rec.signalPendingOffset.toString(16)} lo=0x${($t[ns]>>>0).toString(16)} hi=0x${($t[ns+1]>>>0).toString(16)} mlo=0x${($t[ns+4]>>>0).toString(16)} mhi=0x${($t[ns+5]>>>0).toString(16)}`}t.onDmesg?.(3,`hwjs-killgroup DBG target=${nt} outcome=${St.kind}${Nn} `,V)}St.kind==="delivered"&&Ue++}t.onDmesg?.(3,`hwjs #85 CONTAINMENT (host belt): thread tid=${V} of process pid=${w} ${se} \u2014 sig=${z|0} stamped for the group (leader + ${Ke.length-1} sibling thread(s); ${Ue} delivered, missing targets already exited) so the process dies and the parent's wait4 resolves `,V),this.reapGroupAfter(w,V,`group death (sig=${z|0}: ${se})`)}},__mainTlsSlots:Re,__cpuIdHooks:{allocateCpuId:K,releaseCpuId:k,allocateCpuIdValue:M,releaseCpuIdValue:H,reclaimDedicatedLane:U},__kernelLaneLocks:r,__pool:Ie?{getPoolWorker:gt,poolHandlers:ae,syscallSyncDoors:h,registerSyncDoors:p,execInstallSyncDoors:m,allocRouteKey:o(()=>Ce++,"allocRouteKey"),liveWorkerCount:o(()=>B.length,"liveWorkerCount"),noteResidentDelta:_e,markLaneSuspect:at,markLaneLive:un,newLaneOwner:rt,laneOccupy:we,laneRelease:Qe,lanesOwnedByOthers:It,lanesCarryingAnyOwner:Ct,laneOwnerText:Mt,liveCpuIds:o(()=>B.map(w=>w.cpuId),"liveCpuIds"),maxCpuId:i}:void 0,__taskWakeAddrByPid:At,__sharedLibs:{list:re,deliver:Xe,deliveryPending:Ae},__userImageModule:xe,__noteWorkerCompiledUserImage:Oe,__reclaimUserMemory:jn,__noteProcessExitForReclaim:Cs,__taskLedger:n,__taskProbeReply:E,__trackWorker:o(w=>{ie||x.add(w)},"__trackWorker"),__untrackWorker:o(w=>{x.delete(w)},"__untrackWorker")});for(let w of t.sharedLibs??[])Xe(w.digest,w.bytes,"preload");mr.__poolStats=()=>({workers:B.length,residents:B.map(w=>({cpuId:w.cpuId,residentCount:w.residentCount}))});let mn=o((async w=>{if(w.mode===1)return vc(w,e,s,mr);if(w.mode!==0||w.execImageSize===0)return-22;if((w.flags&1)===0)return t.onUserError?.(w.tid,`hwjs-scatter: FORK spawn request tid=${w.tid} carries a ${w.execImageSize}-byte exec image but NOT WASM_SPAWN_FLAG_SCATTER_IMAGE (flags=0x${(w.flags>>>0).toString(16)}). This host only speaks the segment-list ABI; reading exec_image_offset as a byte offset would compile the segment list. REFUSED -EINVAL (never-silent) \u2014 the kernel and host are out of step and must be rebuilt together.`),-22;let V=t.kernelMemoryWasm?.buffer??t.kernelMemory,z;try{z=Hd(V,w.execImageOffset,w.execImageNsegs??0,w.execImageSize,`exec image for tid=${w.tid}`)}catch(Bt){return t.onUserError?.(w.tid,Bt instanceof Error?Bt.message:String(Bt)),-22}let se=(w.libcImageOffset??0)>>>0,Ue=(w.libcImageSize??0)>>>0,Ke=(w.libcDigestOffset??0)>>>0;if(Ue>0&&se>0){let Bt=new Uint8Array(V);if(Ke===0||Ke+64>V.byteLength)return t.onUserError?.(w.tid,`hwjs-scatter: libc.so digest string at 0x${Ke.toString(16)} (+64B) is outside kernel memory (${V.byteLength}B) \u2014 REFUSED (never-silent)`),-22;let Nt=new TextDecoder().decode(Bt.slice(Ke,Ke+64)),St;try{St=Hd(V,se,w.libcImageNsegs??0,Ue,`libc.so.${Nt.slice(0,16)}\u2026 hand-off for tid=${w.tid}`)}catch($t){return t.onUserError?.(w.tid,$t instanceof Error?$t.message:String($t)),-22}if(!await Xe(Nt,St,"spawn-ring"))return-8}let nt=await ea(z,w.tid,0,e,s,mr);return nt<0?nt:0}),"handler");return mn.registerParent=(w,V)=>{e.set(w,V)},mn.hasParent=w=>e.has(w),mn.parentCount=()=>e.size,mn.partitionReport=()=>lp.slice(),mn.carriesHwjsRt=t.hwjsRtModule!==void 0,mn.__setLaneCeiling=R,mn.__setHostSyncCall=f,mn.poolStats=()=>({enabled:Ie,poolSize:C,laneCeiling:a,workers:B.length,liveResidents:Q,peakResidents:$,residents:B.map(w=>({cpuId:w.cpuId,residentCount:w.residentCount}))}),mn.taskCensus=()=>({tasks:n.tasks(),reapedBeyondRing:n.reapedBeyondRing()}),mn.laneCensus=()=>{let w=new Int32Array(r),V=Date.now(),z=[];for(let se=1;se<=a;se++){let Ue=B.find(Bt=>Bt.cpuId===se),Ke=pe.get(se),nt=kt.get(se);z.push({cpuId:se,band:se<=i?"pool":"dedicated",poolWorkerLive:Ue!==void 0,residentCount:Ue?Ue.residentCount:0,ownerGroups:Ke?[...Ke].map(Bt=>Bt.group).sort((Bt,Nt)=>Bt-Nt):[],heldByDedicatedWorker:F.has(se),mutexHeld:seV?nt-V:0})}return z},mn.probeWorkers=async(w=250)=>{let V=[...B.map(se=>({realm:"pool",cpuId:se.cpuId,worker:se.worker})),...[...x].map(se=>({realm:"dedicated",cpuId:null,worker:se}))],z=Date.now();return Promise.all(V.map(se=>new Promise(Ue=>{let Ke=P++,nt=!1,Bt=o(St=>{nt||(nt=!0,ee.delete(Ke),Ue(St))},"finish"),Nt=setTimeout(()=>Bt({realm:se.realm,cpuId:se.cpuId,answered:!1,waitedMs:Date.now()-z,residents:null,schedStats:null,isolateModuleCaches:null,tasks:[]}),w);ee.set(Ke,St=>{clearTimeout(Nt),Bt({realm:se.realm,cpuId:typeof St.cpuId=="number"?St.cpuId:se.cpuId,answered:!0,waitedMs:Date.now()-z,residents:Array.isArray(St.residents)?St.residents:null,schedStats:St.schedStats??null,isolateModuleCaches:St.isolateModuleCaches??null,tasks:Array.isArray(St.tasks)?St.tasks:[]})});try{Ks(se.worker,{kind:"task-probe",seq:Ke})}catch(St){clearTimeout(Nt),Bt({realm:se.realm,cpuId:se.cpuId,answered:!1,waitedMs:Date.now()-z,postError:St instanceof Error?St.message:String(St),residents:null,schedStats:null,isolateModuleCaches:null,tasks:[]})}})))},mn.deliverSharedLib=Xe,mn.sharedLibCensus=()=>[...J].map(([w,V])=>({digest:w,byteLength:V.bytes.length,wireByteLength:Co(V.bytes)?.wireLength??V.bytes.length,compiled:V.module!==void 0,deliveryInFlight:V.pending!==void 0})),mn.__placementProbe=async(w={})=>{let V=ap(w.userLane??0,i),z=new Set(w.excludeCpuIds??[]),se=await gt(w.avoidCpuId,z),Ue=V.kind==="pin"?await gt(w.avoidCpuId,z,V.cpuId):se;return{pin:V,maxCpuId:i,naturalCpuId:se.cpuId,chosenCpuId:Ue.cpuId}},mn.wakeTaskByPid=ue,mn.reclaimUserMemory=jn,mn.userMemoryStats=()=>t.ram.userMemoryStats?.(),mn.dispose=Zs,mn}o(ta,"makeKernelSpawnHandler");function nI(t,e){let n=!1,s=!1,r=!t,i=!1,l=0,d=o(()=>{i||!n||!s||l>0||!r||(i=!0,e())},"tryOffer");return{ownExit(){n=!0,d()},reclaimed(){s=!0,d()},workerGone(){r=!0,d()},syscallBegin(){l++},syscallEnd(){l--,d()}}}o(nI,"makeUserMemPoolGate");async function ea(t,e,n,s,r,i,l,d){let a=t,c;if(d)c=d.userMem,Ts.get(c)===void 0&&Qo(c,a,{ram:i.ram,pid:-1});else{try{c=i.ram.allocUserMemory()}catch(ee){let P=i.ram.userMemoryStats();return i.onUserError?.(-1,`spawn REFUSED: could not allocate a per-process user_memory (initial ${i.ram.opts.userInitBytes} B, maximum ${i.ram.opts.userMaxBytes} B): ${ee instanceof Error?ee.message:String(ee)}. This is the HOST declining a new WebAssembly.Memory, not the guest machine running out of its declared RAM. Live user SABs: ${P.liveCount} (${P.livePages} pages); exited-but-uncollected: ${P.exitedUncollectedCount} (${P.exitedUncollectedPages} pages). The guest sees ENOMEM from fork/exec.`),Zr}Qo(c,a,{ram:i.ram,pid:-1})}let h;if(d)h=d.signalPendingOffset;else if(i.signalRegistry){let ee=cp(c);if(ee<0)return i.onUserError?.(-1,Zl(i.ram,c,-1,"signal-pending page at process spawn",c.buffer.byteLength+ks)+" The process cannot be started; the guest sees ENOMEM from fork/exec."),Zr;h=ee}let p=i.__cpuIdHooks,m=i.__pool;{let ee=i.__sharedLibs;if(ee?.deliveryPending){let P=null;try{P=gl(a)}catch{}if(P!==null){let E=ee.deliveryPending(P);E&&await E}}}{let ee=i.__userImageModule;if(ee)try{await ee(a)}catch{}}let y=null,b=0,f,I=m?m.newLaneOwner():null,R=d&&typeof d.parentCpuId=="number"?d.parentCpuId:void 0,X=o(()=>{if(!m)return;let ee=m.lanesCarryingAnyOwner();return R!==void 0&&ee.delete(R),ee},"forkForeignLanes");if(m)y=await m.getPoolWorker(R,void 0,void 0,X()),f=y.cpuId,b=m.allocRouteKey(),y.residentCount++,m.laneOccupy(f,I),m.noteResidentDelta(1),globalThis.process?.env?.A4C_DBG&&globalThis.process.stderr.write(`[a4c] place tid=${e} ppid=${n} -> pool cpu=${f} routeKey=${b} residents=${y.residentCount} forkResume=${!!d} `);else if(f=p?p.allocateCpuIdValue():1,f===0)return bs;let F=i.__taskLedger?.open({kind:"process",spawnTid:e,parentPid:n,tgid:null,cpuId:f,residency:m?"pool-resident":"dedicated-worker",routeKey:m?b:null,image:Nc(a,null),userMemory:c,sabSharedWithGroup:!1})??null;F?.noteSignalPendingOffset(h);let N=new SharedArrayBuffer(64),K=new Int32Array(N),k=e,U=!1,M=[],H=!1,Ge=new Map,C=0,Ie=null,B=[],ae=o(()=>{if(!Ie)return null;let ee=Ie.envelope;return Ie=null,ee},"peekThreadPlacement"),Ce=o((ee=5e3)=>{let P=ae();return P?Promise.resolve(P):new Promise((E,J)=>{let re=++C,Xe=!1,Ae=o(de=>{let ve=B.indexOf(de);ve>=0&&B.splice(ve,1)},"unwait"),Ve=o(de=>{Xe||(Xe=!0,clearTimeout(je),Ge.delete(re),Ae(Ve),E(de))},"settle"),me=o(de=>{Xe||(Xe=!0,clearTimeout(je),Ge.delete(re),Ae(Ve),J(de))},"fail"),je=setTimeout(()=>{me(new Error(`hwjs-libc: thread-placement fetch pid=${k} seq=${re} timed out after ${ee}ms \u2014 no clone-time pre-push arrived and the parent Worker's event loop did not serve the request (starved lane / torn Worker / pre-push-less worker build); the thread spawn must be refused (never-silent)`))},ee);B.push(Ve),Ge.set(re,{resolve:Ve,reject:me});try{we({kind:"thread-placement-request",seq:re,pid:k})}catch(de){me(de instanceof Error?de:new Error(String(de)))}})},"requestThreadPlacement"),Q=o(ee=>{U||(U=!0,k=ee,I&&(I.group=ee),F?.notePid(ee,ee),i.signalRegistry&&h!==void 0&&i.signalRegistry.register(ee,{userMemory:c,signalPendingOffset:h}),s.set(ee,{wasmBytes:a,userMemory:c,requestThreadPlacement:Ce,peekThreadPlacement:ae,getCpuId:o(()=>f,"getCpuId"),leaderPid:ee}),i.ram.noteUserMemoryOwner?.(c,ee))},"registerProcessMaps"),$=nI(!m,()=>{i.ram.recycleUserMemory?.(c)}),_e=o(ee=>($.syscallBegin(),ee.finally(()=>$.syscallEnd())),"trackSyscall"),pe=o(ee=>{if(i.ram.noteUserMemoryExited?.(c),U){let P=i.__threadContain;if(P&&ee)if((ee.zapped|0)>0){let E=ee.wstatus|0;P.killGroup(k,k,9,`process leader terminus: the kernel condemned ${ee.zapped} other thread(s) of this process and set the group's exit code to 0x${E.toString(16)} (`+(E&127?`WIFSIGNALED WTERMSIG=${E&127}`:`WIFEXITED WEXITSTATUS=${E>>8&255}`)+") \u2014 unwinding their Workers")}else P.liveThreads(k)>0&&i.onDmesg?.(4,`hwjs group-death: process leader pid=${k} reached a terminus and the kernel condemned NO other thread, while ${P.liveThreads(k)} sibling Worker(s) are still up. The host unwinds none of them \u2014 the kernel owns which tasks die `,k);else P&&P.liveThreads(k)>0&&P.killGroup(k,k,9,"process leader terminus the kernel never saw (trap / spawn failure) with live sibling threads \u2014 host containment belt, so a sibling parked on the dead leader's lock cannot leak a cpu lane");if(Do(r,k),i.__mainTlsSlots?.dropParent(k),i.signalRegistry?.unregister(k),i.stdinChannel?.dropTid(k),i.__taskWakeAddrByPid?.delete(k>>>0),!Og()){let E=P?.consumeEverThreaded!==void 0&&!P.consumeEverThreaded(k),J=o(()=>{s.delete(k),Ts.delete(c),cr.delete(c),Ai.delete(c),$o.delete(c),E&&$.reclaimed()},"reclaim");P?.whenGroupEmpty?P.whenGroupEmpty(k,J):J()}}m?(m.poolHandlers.delete(b),m.syscallSyncDoors.delete(b),m.registerSyncDoors.delete(b),m.execInstallSyncDoors.delete(b),y&&(y.residentCount=Math.max(0,y.residentCount-1),I&&m.laneRelease(y.cpuId,I)),m.noteResidentDelta(-1)):p&&p.releaseCpuIdValue(f),i.__noteProcessExitForReclaim?.()},"cleanupProcessWorker"),Ut=i.platform??Fc(),rt=m?y.worker:await Ec(i.workerEntry,Ut,"fork-dedicated");m||i.__trackWorker?.(rt);let we=o(ee=>Ks(rt,m?{...ee,routeKey:b}:ee),"postReply"),Qe=!1,It={parents:s,spawnThread:o(ee=>vc(ee,s,r,i),"spawnThread"),cloneCleartidMap:r},Ct=o(()=>{},"resolveVmlinuxAllocated"),Mt=i.vmlinuxModule!==void 0?new Promise(ee=>{Ct=ee}):Promise.resolve(e),At=0,q=o(ee=>{let P=Ts.get(c);Qo(c,ee,{ram:i.ram,pid:k});let E=Ts.get(c);P!==void 0&&E!==void 0&&P>E&&Ts.set(c,P)},"rederiveExecPartition"),_=new Promise(ee=>{let P=o(async E=>{if(E?.kind==="user-image-compiled"){i.__noteWorkerCompiledUserImage?.(E,rt);return}if(E?.kind==="syscall"){if(i.vmlinuxModule!==void 0&&!U){if(H){i.onUserError?.(e,"hwjs#65: syscall from a DEGRADED spawn (vmlinux-error, no kernel pid) answered -EAGAIN \u2014 the task should not be running user code at all (worker-side refusal bypassed?)"),Atomics.store(K,dt.RET_LO,bs|0),Atomics.store(K,dt.RET_HI,-1),Atomics.store(K,dt.STATE,As),Atomics.notify(K,dt.STATE);return}i.onDmesg?.(4,`hwjs#65: R-K11.6-W1 early-signal HOLD \u2014 syscall from tid=${e} (routeKey=${b}) arrived before the vmlinux-ready handshake registered its kernel pid; deferring dispatch until registration (held=${M.length+1}) `,e),M.push(E);return}await _e(fl(K,c,k,i,It));return}if(E?.kind==="libc-so-staged"){let J=i.__sharedLibs;J?J.deliver(String(E.digest??""),E.bytes instanceof Uint8Array?E.bytes:new Uint8Array(E.bytes??[]),`worker tid=${e}`,E.module instanceof WebAssembly.Module?E.module:void 0):i.onUserError?.(e,"hwjs-libc: 'libc-so-staged' arrived but this spawn handler has no shared-lib hooks (harness without makeKernelSpawnHandler?) \u2014 machine-wide retention SKIPPED (never-silent)");return}if(E?.kind==="thread-placement"){if(E.unsolicited){let re={dlopenFork:E.dlopenFork&&typeof E.dlopenFork=="object"?E.dlopenFork:null,...E.clone&&typeof E.clone=="object"?{clone:{flags:(E.clone.flags??0)>>>0,ptid:(E.clone.ptid??0)>>>0,ctid:(E.clone.ctid??0)>>>0}}:{},...Array.isArray(E.lowFdRoutes)?{lowFdRoutes:E.lowFdRoutes.map(Ae=>Ae|0)}:{},callerYieldsDuringClone:E.callerYieldsDuringClone===!0},Xe=B.shift();Xe?Xe(re):Ie={envelope:re};return}let J=Ge.get(E.seq|0);J&&(Ge.delete(E.seq|0),E.error?J.reject(new Error(String(E.error))):J.resolve({dlopenFork:E.dlopenFork&&typeof E.dlopenFork=="object"?E.dlopenFork:null}));return}if(E?.kind==="fork"){let J=Atomics.load(K,dt.STATE);if(J!==pl)throw new Error("D1-FORK: 'fork' message arrived with ctrl STATE="+J+" (expected REQUEST="+pl+"); refusing to snapshot a non-quiesced parent address space.");let re;try{re=i.ram.allocUserMemory(void 0,void 0,c.buffer.byteLength)}catch{Atomics.store(K,dt.RET_LO,Zr|0),Atomics.store(K,dt.RET_HI,-1),Atomics.store(K,dt.STATE,As),Atomics.notify(K,dt.STATE);return}let Xe=c.buffer.byteLength,Ae=Math.ceil((Xe-re.buffer.byteLength)/65536);Ae>0&&re.grow(Ae),new Uint8Array(re.buffer).set(new Uint8Array(c.buffer,0,Xe));let Ve=Ts.get(c),me=cr.get(c);Ve!==void 0&&me?(Ts.set(re,Ve),cr.set(re,{...me}),Ai.set(re,yl(c).map(de=>({...de})))):Qo(re,a,{ram:i.ram,pid:-1}),h!==void 0&&new Int32Array(re.buffer,h>>>0,3).fill(0);let je=await ea(a,0,k,s,r,i,void 0,{userMem:re,signalPendingOffset:h,...m?{parentCpuId:f}:{},...typeof E.tlsBase=="number"?{tlsBase:E.tlsBase>>>0}:{},...typeof E.forkHandle=="number"?{forkHandle:E.forkHandle>>>0}:{},...typeof E.forkOwner=="number"?{forkOwner:E.forkOwner>>>0}:{},...typeof E.userLane=="number"&&(E.userLane|0)>0?{forkLane:E.userLane|0}:{},...typeof E.parentSp=="number"?{parentSp:E.parentSp>>>0}:{},...typeof E.dlopenFork=="object"&&E.dlopenFork!==null?{dlopenFork:E.dlopenFork}:{},...Array.isArray(E.lowFdRoutes)?{lowFdRoutes:E.lowFdRoutes}:{}});Atomics.store(K,dt.RET_LO,je|0),Atomics.store(K,dt.RET_HI,je<0?-1:0),Atomics.store(K,dt.STATE,As),Atomics.notify(K,dt.STATE);return}if(E?.kind==="migrate"){let J=E.mig;if(!(J instanceof SharedArrayBuffer)||J.byteLength<16){i.onDmesg?.(3,`hwjs-migrate pid=${k}: 'migrate' message without a valid protocol word \u2014 ignoring (the source's own deadline releases it) `,k);return}let re=new Int32Array(J),Xe=E.destCpu|0,Ae=E.srcCpu|0,Ve=o(Zt=>{for(;;){let Xt=Atomics.load(re,0)|0;if(Xt===2||Xt===3)return!1;if(Atomics.compareExchange(re,0,Xt,3)===Xt)return Atomics.store(re,2,Zt|0),Atomics.notify(re,0),!0}},"abortMig");if(!m){Ve(4),i.onDmesg?.(3,`hwjs-migrate pid=${k}: migration requires the CPU-Worker pool (this task runs on a dedicated Worker, whose cpu id is not a pool lane) \u2014 REFUSED `,k);return}let me;try{me=await m.getPoolWorker(void 0,void 0,Xe)}catch(Zt){Ve(2),i.onDmesg?.(3,`hwjs-migrate pid=${k}: cpu=${Xe} has no live pool Worker (${Zt instanceof Error?Zt.message:String(Zt)}) \u2014 REFUSED; the task keeps running on cpu=${Ae} `,k);return}let je=rt,de=f,ve=y;rt=me.worker,f=me.cpuId,y=me,me.residentCount++,I&&m.laneOccupy(me.cpuId,I),Ks(me.worker,{kind:"add-task",routeKey:b,spec:{routeKey:b,mode:"migrate-resume",mig:J,pid:k,tid:e,ppid:n,migratePid:E.pid|0,migrateTaskAddr:E.taskAddr|0,memory:c,ctrl:N,wasmBytes:a,...h!==void 0?{signalPendingOffset:h}:{},tlsBase:E.tlsBase|0,sp:E.sp|0,userLane:E.userLane|0,...Array.isArray(E.lowFdRoutes)?{lowFdRoutes:E.lowFdRoutes}:{},...typeof E.dlopenFork=="object"&&E.dlopenFork!==null?{dlopenFork:E.dlopenFork}:{},...(()=>{let Zt=cr.get(c);return Zt?{...Zt.rtWindowSize>0?{hwjsRtWindowBase:Zt.rtWindowBase,hwjsRtWindowSize:Zt.rtWindowSize}:{},...Zt.libcWindowSize>0?{hwjsLibcWindowBase:Zt.libcWindowBase,hwjsLibcWindowSize:Zt.libcWindowSize}:{}}:{}})()}});let A=4e3,xe=Date.now()+A;for(;Date.now() cpu=${Xe} COMMITTED (routeKey=${b}; same user_memory, same ctrl, same task_struct) `,k);return}let it=Atomics.load(re,3)|0;Ve(it?1:4),rt=je,f=de,y=ve,me.residentCount=Math.max(0,me.residentCount-1),I&&m.laneRelease(me.cpuId,I),it||m.markLaneSuspect(Xe),i.onDmesg?.(3,`hwjs-migrate pid=${k}: cpu=${Ae} -> cpu=${Xe} REFUSED after ${A} ms \u2014 `+(it?"the destination lane CLAIMED the task but never committed (it stalled or died between claiming and binding); this is the half-migrated case, and it is DETECTED here rather than lost: the source never released the task and resumes driving it":"the destination lane never claimed the add-task (its event loop is starved by a resident that does not yield); lane marked suspect")+`. Host bookkeeping rolled back to cpu=${Ae} `,k);return}if(E?.kind==="vmlinux-rebound"){let J=typeof E.perProcessTaskWakeAddr=="number"?E.perProcessTaskWakeAddr>>>0:0,re=i.__taskWakeAddrByPid;J&&re&&re.set(k>>>0,J),i.onDmesg?.(6,`hwjs-migrate pid=${k}: bound on cpu=${E.cpuId??f} (task=0x${(E.perProcessTaskAddr>>>0).toString(16)}) `,k);return}if(E?.kind==="execve"){let J=String(E.path??""),re=-2,Xe,Ae=i.childImageRegistry?.lookup(J);i.childImageRegistry?Ae?Xe={kind:"exec-image",ok:!0,wasmBytes:Ae}:Xe={kind:"exec-image",ok:!1,errno:re}:Xe={kind:"exec-image",ok:!1,errno:yr},we(Xe);return}if(E?.kind==="exit"){if(!Qe){Qe=!0,$.ownExit();let J=E.code|0;pe(E.groupExit??null),E.wasmSyscallStats&&i.onWasmSyscallStats&&i.onWasmSyscallStats(k,E.wasmSyscallStats),F?.noteExit(J,"exit message from the Worker"),i.onUserExit?.(k,J),m||(await vr(rt),$.workerGone()),ee(J)}return}if(E?.kind==="error"){Qe||(Qe=!0,pe(),F?.noteExit(-1,`terminal error from the Worker: ${String(E.message??"")}`),i.onUserError?.(k,String(E.message??"")),i.onUserExit?.(k,-1),m||await vr(rt),ee(-1));return}if(E?.kind==="task-probe-reply"){i.__taskProbeReply?.(E);return}if(E?.kind==="user-report"){i.onUserError?.(k,String(E.message??""));return}if(E?.kind==="vmlinux-ready"){let J=typeof E.pid=="number"&&E.pid>0?E.pid|0:e;globalThis.process?.env?.A4C_DBG&&globalThis.process.stderr.write(`[a4c] tid=${e} routeKey=${b} VMLINUX-READY kernelPid=${J} cpu=${f} `);{let re=typeof E.perProcessTaskWakeAddr=="number"?E.perProcessTaskWakeAddr>>>0:0,Xe=i.__taskWakeAddrByPid;re&&Xe&&Xe.set(J>>>0,re)}if(Q(J),M.length>0){let re=M.splice(0,M.length);i.onDmesg?.(4,`hwjs#65: draining ${re.length} held pre-registration syscall(s) for kernel pid=${J} `,J);for(let Xe of re)P(Xe)}i.onVmlinuxReady?.(k,{hasWasmSyscall:!!E.hasWasmSyscall,cpuId:f,initTaskAddr:typeof E.initTaskAddr=="number"?E.initTaskAddr:0,perProcessTaskAddr:typeof E.perProcessTaskAddr=="number"?E.perProcessTaskAddr:0}),Ct(k);return}if(E?.kind==="vmlinux-error"){H=!0,i.onUserError?.(e,`vmlinux instantiation failed in Worker: ${String(E.message??"")} \u2014 spawn refused with -EAGAIN (hwjs#65; the machine keeps running)`),M.length>0&&(M.length=0,Atomics.store(K,dt.RET_LO,bs|0),Atomics.store(K,dt.RET_HI,-1),Atomics.store(K,dt.STATE,As),Atomics.notify(K,dt.STATE)),Qe||(Qe=!0,pe(),F?.noteDegraded(String(E.message??"")),F?.noteExit(-1,"vmlinux-error: the spawn degraded and this task never ran user code"),i.onUserExit?.(k,-1),m||await vr(rt),ee(-1)),Ct(bs);return}if(E?.kind==="usermem-reclaim"){let J=E.sab;if(!(J instanceof SharedArrayBuffer)||J.byteLength<32){i.onUserError?.(k,"hardwarejs#7: malformed 'usermem-reclaim' request (missing/short reply SAB) \u2014 the requesting Worker will time out its bounded wait");return}let re=new Int32Array(J),Xe=i.__reclaimUserMemory;(async()=>{let Ae=0;try{Xe&&(Ae=(await Xe(`execve grow-to-fit pid=${k} need=+${(E.needPages??0)|0}p`)).recycledWorkers)}catch(me){i.onUserError?.(k,`hardwarejs#7: reclaim sweep threw (${me instanceof Error?me.message:String(me)}) \u2014 answering the Worker with the ledger stats anyway`)}let Ve=i.ram.userMemoryStats?.();re[1]=Ve?Ve.liveCount:-1,re[2]=Ve?Ve.livePages:-1,re[3]=Ve?Ve.exitedUncollectedCount:-1,re[4]=Ve?Ve.exitedUncollectedPages:-1,re[5]=Ae,re[6]=Ve?Ve.userMaxPages:-1,re[7]=Ve?Ve.kernelPages:-1,Atomics.store(re,0,1),Atomics.notify(re,0)})();return}if(E?.kind==="exec-image-installed"){let J=E.wasmBytes;if(!(J instanceof Uint8Array)||J.length===0)throw new Error(`D1-FORK: 'exec-image-installed' without valid wasmBytes \u2014 refusing to track an empty/invalid post-exec image (pid=${k}).`);if(a=J,At>0?At--:q(J),U){let re=s.get(k);re&&s.set(k,{...re,wasmBytes:J})}F?.noteExec(Nc(J,typeof E.path=="string"?E.path:null));return}if(E?.kind==="dmesg"){i.onDmesg?.((E.level|0)>>>0,String(E.text),k);return}},"handleMsg");m?(m.poolHandlers.set(b,E=>{P(E)}),m.registerSyncDoors.set(b,E=>{try{Q(E|0)}catch(J){i.onUserError?.(E|0,`hwjs-merged: the SYNCHRONOUS registration door threw for pid=${E|0} routeKey=${b} \u2014 ${J instanceof Error?J.message:String(J)}. Declining, so the vmlinux-ready MESSAGE registers this task instead and its first syscalls take the deferred route (the worker says so out loud).`);return}return"registered"}),m.execInstallSyncDoors.set(b,E=>{try{q(E)}catch(J){i.onUserError?.(k,`hwjs-merged: the SYNCHRONOUS exec door threw for pid=${k} routeKey=${b} \u2014 ${J instanceof Error?J.message:String(J)}. Declining, so the exec-image-installed MESSAGE re-derives the partition instead.`);return}return At++,"installed"}),m.syscallSyncDoors.set(b,()=>{if(i.vmlinuxModule!==void 0&&!U)return;let E;try{E=_e(fl(K,c,k,i,It))}catch(J){i.onUserError?.(k,`hwjs-merged: the SYNCHRONOUS syscall door threw for nr=${K[dt.NR]|0} \u2014 ${J instanceof Error?J.message:String(J)}. Declining: nothing was written, so the caller must take the message route and get whatever answer THAT produces, including its refusal.`);return}return E?.catch?.(J=>{i.onUserError?.(k,`hwjs-merged: a syscall dispatched through the SYNCHRONOUS door rejected after awaiting (nr=${K[dt.NR]|0}) \u2014 ${J instanceof Error?J.message:String(J)}`)}),Atomics.load(K,dt.STATE)===As?"sync":"async"})):(_c(rt,P),Jc(rt,async E=>{Qe||(Qe=!0,pe(),F?.noteExit(-1,`Worker-level error event: ${E instanceof Error?E.message:String(E)}`),i.onUserError?.(k,E instanceof Error?E.message:String(E)),i.onUserExit?.(k,-1),await vr(rt),ee(-1))}))}),D=l??(d?{inheritFiles:!0,fdActions:[]}:void 0),ue=cr.get(c),x={...ue&&ue.rtWindowSize>0?{hwjsRtWindowBase:ue.rtWindowBase,hwjsRtWindowSize:ue.rtWindowSize}:{},...ue&&ue.libcWindowSize>0?{hwjsLibcWindowBase:ue.libcWindowBase,hwjsLibcWindowSize:ue.libcWindowSize}:{},mode:d?"fork-resume":"fork",pid:e,tid:e,ppid:n,wasmBytes:a,memory:c,ctrl:N,...h!==void 0?{signalPendingOffset:h}:{},...D!==void 0?{inheritFiles:D.inheritFiles,fdActions:D.fdActions}:{},...d&&d.tlsBase!==void 0?{tlsBase:d.tlsBase}:{},...d&&d.forkHandle!==void 0?{forkHandle:d.forkHandle}:{},...d&&d.forkOwner!==void 0?{forkOwner:d.forkOwner}:{},...d&&d.parentSp!==void 0?{parentSp:d.parentSp}:{},...d&&d.forkLane!==void 0?{forkLane:d.forkLane}:{},...d&&d.dlopenFork&&typeof d.dlopenFork=="object"?{dlopenFork:d.dlopenFork}:{},...d&&Array.isArray(d.lowFdRoutes)&&d.lowFdRoutes.length?{lowFdRoutes:d.lowFdRoutes}:{},...!d&&e===1&&Array.isArray(i.initArgv)&&i.initArgv.length>0?{argv:i.initArgv,envp:Array.isArray(i.initEnvp)?i.initEnvp:[]}:{},...!d&&e===1&&Array.isArray(i.initLowFdRoutes)&&i.initLowFdRoutes.length>0?{lowFdRoutes:i.initLowFdRoutes}:{}};if(m){let P=o(re=>{globalThis.process?.env?.A4C_DBG&&globalThis.process.stderr.write(`[a4c] ${re} `)},"a4cDbg"),E=new Set,J=0;for(;;){let re=new SharedArrayBuffer(4),Xe=new Int32Array(re);Ks(rt,{kind:"add-task",routeKey:b,spec:{routeKey:b,claim:re,...x}});let Ae=Date.now()+250;for(;Atomics.load(Xe,0)===0&&Date.now() cpu=${f} (lane starved)`)}}else Ks(rt,{kind:"init",...i.kernelMemoryWasm===void 0?{kernelMemory:i.kernelMemory}:{},...i.vmlinuxModule!==void 0?{vmlinuxModule:i.vmlinuxModule}:{},...i.hwjsRtModule!==void 0?{hwjsRtModule:i.hwjsRtModule,hwjsRtBytes:i.hwjsRtBytes,hwjsRtProvenance:i.hwjsRtProvenance}:{},...(()=>{let ee=i.__sharedLibs,P=ee?ee.list():[];return P.length>0?{sharedLibs:P}:{}})(),...i.kernelMemoryWasm!==void 0?{kernelMemoryWasm:i.kernelMemoryWasm}:{},...i.__kernelLaneLocks!==void 0?{kernelLaneLocks:i.__kernelLaneLocks}:{},...i.pauseBuffer!==void 0?{pauseBuffer:i.pauseBuffer}:{},cpuId:f,...x});return i.vmlinuxModule===void 0&&Q(e),await Mt}o(ea,"spawnForkWorker");var sp=0;async function vc(t,e,n,s){let r=e.get(t.parentTid);if(!r)return Lg;let i=r.leaderPid??t.parentTid;(typeof process>"u"?void 0:process)?.env?.HARDWAREJS_DEBUG_K7_U4F&&process.stderr.write(`[K7-U4f spawnThreadWorker] tid=${t.tid} parentTid=${t.parentTid} argRegion=0x${(t.argRegionOffset>>>0).toString(16)} stack=0x${(t.stackPointerOffset>>>0).toString(16)} tls=0x${(t.tlsPointerOffset>>>0).toString(16)} `);let l=s.__sharedLibs,d=globalThis.process?.env?.HWJS_TEST_THREAD_NO_PLACEMENT==="1",a=globalThis.process?.env?.HWJS_TEST_THREAD_NO_SHAREDLIBS==="1",c=null;try{c=gl(r.wasmBytes)}catch{}let h=c!==null,p=((t.laneId??0)|0)>0;{let de=s.__userImageModule;if(de)try{await de(r.wasmBytes)}catch{}}let m=null;if(c!==null&&!d){if(l?.deliveryPending){let de=l.deliveryPending(c);de&&await de}if(typeof r.requestThreadPlacement!="function")return s.onUserError?.(t.tid,`hwjs-libc: WASM_SPAWN_THREAD of a libc.so-needing main (pid ${t.parentTid}) but its parent record carries no placement channel (registerParent-installed synthetic record?) \u2014 refusing the thread spawn with -EAGAIN (never-silent)`),bs;try{m=await r.requestThreadPlacement()}catch(de){return s.onUserError?.(t.tid,`hwjs-libc: thread-placement fetch for pid ${t.parentTid} FAILED \u2014 ${de instanceof Error?de.message:String(de)} \u2014 refusing the thread spawn with -EAGAIN (never-silent)`),bs}if(!m||!m.dlopenFork||!m.dlopenFork.libcSo)return s.onUserError?.(t.tid,`hwjs-libc: thread-placement record for the libc.so-needing pid ${t.parentTid} carries no libcSo placement (module #1 was never instantiated in the parent?) \u2014 refusing the thread spawn with -EAGAIN (never-silent)`),bs}else{if(m=r.peekThreadPlacement?.()??null,p&&!m?.clone&&typeof r.requestThreadPlacement=="function")try{m=await r.requestThreadPlacement()}catch(de){return s.onUserError?.(t.tid,`hwjs-threads: clone-args fetch for laned static thread (pid ${t.parentTid} lane ${t.laneId}) FAILED \u2014 ${de instanceof Error?de.message:String(de)} \u2014 refusing the thread spawn with -EAGAIN (a missing CLEARTID registration would wedge pthread_join; never-silent)`),bs}if(p&&!m?.clone)return s.onUserError?.(t.tid,`hwjs-threads: laned static thread spawn (pid ${t.parentTid} lane ${t.laneId}) has no clone-args envelope (no pre-push, no reply) \u2014 refusing with -EAGAIN (never a settid/cleartid-less thread; pthread_join would wedge silently)`),bs}let y=h&&!d?m?.dlopenFork??null:null;if((h||p)&&m?.clone){let{flags:A,ptid:xe,ctid:Oe}=m.clone,it=r.userMemory.buffer.byteLength;A&1048576&&xe!==0&&(xe&3)===0&&xe+4<=it&&(new Uint32Array(r.userMemory.buffer)[xe>>>2]=t.tid>>>0),A&2097152&&Oe!==0&&(Oe&3)===0&&Oe+4<=it&&n.set(t.tid,{ctid:Oe,userMemory:r.userMemory})}let b=new SharedArrayBuffer(64),f=new Int32Array(b),I;if(s.signalRegistry){let de=cp(r.userMemory);if(de<0)return s.onUserError?.(t.tid,`thread spawn tid=${t.tid}: signal-pending page allocation FAILED. `+Zl(s.ram,r.userMemory,t.tid,"signal-pending page for a new thread",r.userMemory.buffer.byteLength+ks)+" pthread_create observes EAGAIN (loud, attributed)."),Zr;I=de,s.signalRegistry.register(t.tid,{userMemory:r.userMemory,signalPendingOffset:de})}let R=s.__cpuIdHooks,X=s.__pool,F=X?X.newLaneOwner(i):null,N=h||p?r.getCpuId?.():void 0,K=X?X.liveWorkerCount():0,k=m?.callerYieldsDuringClone===!0,U=o(()=>X?X.lanesOwnedByOthers(i):new Set,"foreignLanes"),H=o(()=>X?k?X.liveCpuIds():X.liveCpuIds().filter(de=>de!==N):[],"eligibleLanes")().length>0,Ge=op(),C=X?ap((t.laneId??0)|0,X.maxCpuId):{kind:"none"};if(C.kind==="error")return s.onUserError?.(t.tid,`thread spawn tid=${t.tid} (group ${i}, userLane ${t.laneId??0}): ${C.message}. Refusing the clone with -EAGAIN (loud, attributed) \u2014 every thread spawn on this machine is refused while the pin table is unusable, so a broken table can never be mistaken for an unpinned run.`),s.signalRegistry?.unregister(t.tid),bs;let Ie=C.kind==="pin"?C.cpuId:void 0;if(Ie!==void 0&&!(X&&p&&!Bc()))return s.onUserError?.(t.tid,`thread spawn tid=${t.tid} (group ${i}): HWJS_THREAD_PLACEMENT_PIN=${Ge} pins userLane ${t.laneId??0} to cpu ${Ie}, but this spawn can never be a pool resident (${X?p?"HWJS_THREAD_DEDICATED_WORKERS=1 has thread residency disabled machine-wide":`userLane ${t.laneId??0} is the process main's own lane \u2014 a lane-0 thread cannot co-reside`:"this machine has no CPU-Worker pool (no vmlinuxModule)"}). Refusing the clone with -EAGAIN rather than running an UNPINNED spawn under a pinned transcript.`),s.signalRegistry?.unregister(t.tid),bs;let B=!!X&&p&&!Bc()&&H,ae=B||Ie!==void 0;if(X&&p&&!Bc()&&!H&&Ie===void 0){let de=U(),ve=X.liveCpuIds().sort((A,xe)=>A-xe);s.onDmesg?.(4,`hwjs-threads: thread spawn tid=${t.tid} (group ${i}) cannot be a pool resident \u2014 NO lane qualifies. Lanes: ${ve.map(A=>`cpu${A}=${A===N?"CALLER":"free"}[carries ${X.laneOwnerText(A)}${de.has(A)?", incl. other groups":""}]`).join(" ")||""}. The CALLER's lane is the only excluded lane, and it is excluded because THIS caller pins that Worker for the whole clone(2): its image did not declare callerYieldsDuringClone, so the kernel's spawn-ring -517 is answered by the host's SYNCHRONOUS in-place restart loop instead of being handed to a libc that parks. Its onmessage therefore cannot claim an add-task until the clone returns, and the clone cannot return until the thread adopts. A caller whose libc absorbs the sentinel at raw veneers (musl) is NOT excluded \u2014 its lane is an ordinary lane, which is what makes cpu=1 expressible. Nor is a lane another THREAD GROUP carries: one JS thread is one scheduler, and that is what "cpu=N" means. So this is a machine with ${K} CPU Worker(s) whose only lane belongs to a caller that holds it. Falling back to a DEDICATED Worker realm for this thread: the "no host Worker after boot" invariant does NOT hold on such a machine. Raise num_vcpu, or build the caller against a libc that parks at raw syscalls. `,t.tid)}let Ce=null,Q=0,$,_e=o(()=>new Set(N!==void 0&&!k?[N]:[]),"bannedLanes");if(ae){try{if(Ie!==void 0){let de;if(!B)de="dedicated-Worker";else try{de=`cpu=${(await X.getPoolWorker(N,_e(),void 0,U())).cpuId}`}catch{de="unknown (unpinned probe failed)"}Ce=await X.getPoolWorker(N,_e(),Ie,U()),s.onDmesg?.(4,`hwjs-thread-placement-pin: APPLIED userLane=${t.laneId??0} cpu=${Ce.cpuId} would-have-been=${de} tid=${t.tid} group=${i} callerCpu=${N??"-"} poolLanes=${K} maxCpuId=${X.maxCpuId} overrode=${N===Ie?"avoidCpuId+callerLaneExclusion":"avoidCpuId"} table=HWJS_THREAD_PLACEMENT_PIN=${Ge} `,t.tid)}else Ce=await X.getPoolWorker(N,_e(),void 0,U())}catch(de){return s.onUserError?.(t.tid,`thread spawn tid=${t.tid}: pool placement failed (${de instanceof Error?de.message:String(de)}) \u2014 the machine is tearing down or the pool is empty; refusing the clone with -EAGAIN (loud, attributed).`),s.signalRegistry?.unregister(t.tid),bs}$=Ce.cpuId,Q=X.allocRouteKey(),Ce.residentCount++,X.laneOccupy($,F),X.noteResidentDelta(1)}else if($=R?R.allocateCpuId(t.tid,N):1,$===0)return s.onUserError?.(t.tid,`thread spawn tid=${t.tid}: cpu-lane pool SATURATED (machine-wide thread-Worker lane keys all in flight) \u2014 pthread_create observes EAGAIN (loud, attributed). If this machine is not actually running that many threads, a lane has leaked (a thread Worker outliving its group) \u2014 report it.`),s.signalRegistry?.unregister(t.tid),bs;let pe=s.__taskLedger?.open({kind:"thread",spawnTid:t.tid,parentPid:t.parentTid,tgid:i,cpuId:$,residency:ae?"pool-resident":"dedicated-worker",routeKey:ae?Q:null,image:Nc(r.wasmBytes,null),userMemory:r.userMemory,sabSharedWithGroup:!0})??null;pe?.noteSignalPendingOffset(I),s.onDmesg?.(6,`hwjs-thread-spawn tid=${t.tid} parentTid=${t.parentTid} group=${i} userLane=${t.laneId??0} cpu=${$} resident=${ae?`pool(routeKey=${Q})`:"dedicated-Worker"} avoidCpu=${N??"-"}${ae&&N!==void 0&&$===N?` callerLane=shared(callerYields=${k?1:0})`:""}${Ie!==void 0?` pin=${Ie}`:""} `,t.tid);let Ut=s.platform??Fc(),rt=ae?Ce.worker:await Ec(s.workerEntry,Ut,"thread-dedicated");ae||s.__trackWorker?.(rt);let we=o(de=>Ks(rt,ae?{...de,routeKey:Q}:de),"postReply"),Qe=0,It=new Map,Ct=0,Mt=null,At=[],q=o(()=>{if(!Mt)return null;let de=Mt.envelope;return Mt=null,de},"peekThreadPlacement"),_=o((de=5e3)=>{let ve=q();return ve?Promise.resolve(ve):new Promise((A,xe)=>{let Oe=++Ct,it=!1,Zt=o(gt=>{let at=At.indexOf(gt);at>=0&&At.splice(at,1)},"unwait"),Xt=o(gt=>{it||(it=!0,clearTimeout(Ot),It.delete(Oe),Zt(Xt),A(gt))},"settle"),kt=o(gt=>{it||(it=!0,clearTimeout(Ot),It.delete(Oe),Zt(Xt),xe(gt))},"fail"),Ot=setTimeout(()=>{kt(new Error(`hwjs-threads: thread-placement fetch from THREAD pid=${Qe||t.tid} seq=${Oe} timed out after ${de}ms \u2014 no clone-time pre-push arrived and the calling thread's Worker did not serve the request (starved lane / torn Worker); the nested thread spawn must be refused (never-silent)`))},de);At.push(Xt),It.set(Oe,{resolve:Xt,reject:kt});try{we({kind:"thread-placement-request",seq:Oe,pid:Qe||t.tid})}catch(gt){kt(gt instanceof Error?gt:new Error(String(gt)))}})},"requestThreadPlacement"),D=s.__threadContain;D?.note(i,t.tid);let ue=o(()=>{D?.drop(i,t.tid),D?.dropReaper?.(t.tid),Qe>0&&(s.signalRegistry?.unregister(Qe),e.delete(Qe),Qe=0)},"dropThreadRegistrations"),x=o(async()=>{if(ae){X.poolHandlers.delete(Q),X.syscallSyncDoors.delete(Q),Ce&&(Ce.residentCount=Math.max(0,Ce.residentCount-1),F&&X.laneRelease(Ce.cpuId,F),Ce=null,X.noteResidentDelta(-1));return}await vr(rt)},"releaseThreadWorker"),ie=o(()=>{ae||R?.releaseCpuId(t.tid)},"releaseThreadCpuId"),ee=o(de=>{ae||R?.reclaimDedicatedLane?.($,t.tid,de)},"reclaimThreadLane"),P=!1,E=o(()=>{},"releaseAdoptionGate"),J=new Promise(de=>{E=de}),re={parents:e,spawnThread:o(de=>vc(de,e,n,s),"spawnThread"),cloneCleartidMap:n},Xe=new Promise(de=>{D?.registerReaper?.(t.tid,A=>{E("failed"),!P&&(P=!0,Do(n,t.tid),s.signalRegistry?.unregister(t.tid),ue(),ie(),s.onUserError?.(t.tid,`thread tid=${t.tid} REAPED at group death (${A}): ${ae?`the resident survived the stamp past the grace window \u2014 reaped from pool cpu=${$} (routeKey=${Q}); the shared CPU Worker keeps serving its peers`:"the Worker survived the stamp past the grace window \u2014 terminated; cpu lane released"}; cleartid, signal page and registrations released (loud, attributed)`),pe?.noteExit(-1,`reaped at group death: ${A}`),s.onUserExit?.(t.tid,-1),x().then(()=>{ee(`group-death reap: ${A}`),Ri(r.userMemory,I),I=void 0}),de(-1))});let ve=o(async A=>{if(A?.kind==="thread-adopted"){E("adopted");return}if(A?.kind==="thread-refused"){s.onUserError?.(t.tid,String(A.message??"thread refused (no message)")),E(A.laneOccupied===!0?"failed-occupied":"failed");return}if(A?.kind==="thread-placement"){if(A.unsolicited){let Oe={dlopenFork:A.dlopenFork&&typeof A.dlopenFork=="object"?A.dlopenFork:null,...A.clone&&typeof A.clone=="object"?{clone:{flags:(A.clone.flags??0)>>>0,ptid:(A.clone.ptid??0)>>>0,ctid:(A.clone.ctid??0)>>>0}}:{},...Array.isArray(A.lowFdRoutes)?{lowFdRoutes:A.lowFdRoutes.map(Zt=>Zt|0)}:{},callerYieldsDuringClone:A.callerYieldsDuringClone===!0},it=At.shift();it?it(Oe):Mt={envelope:Oe};return}let xe=It.get(A.seq|0);xe&&(It.delete(A.seq|0),A.error?xe.reject(new Error(String(A.error))):xe.resolve({dlopenFork:A.dlopenFork&&typeof A.dlopenFork=="object"?A.dlopenFork:null}));return}if(A?.kind==="fork"){let xe=r.userMemory;s.onDmesg?.(6,`hwjs-fork(thread): fork from thread tid=${t.tid} lane-rider userLane=${A.userLane??"absent"} `,t.tid);let Oe=Atomics.load(f,dt.STATE);if(Oe!==pl)throw new Error("D1-FORK(thread): 'fork' message arrived with ctrl STATE="+Oe+" (expected REQUEST="+pl+"); refusing to snapshot a non-quiesced parent address space.");let it;try{it=s.ram.allocUserMemory(void 0,void 0,xe.buffer.byteLength)}catch{Atomics.store(f,dt.RET_LO,Zr|0),Atomics.store(f,dt.RET_HI,-1),Atomics.store(f,dt.STATE,As),Atomics.notify(f,dt.STATE);return}let Zt=xe.buffer.byteLength,Xt=Math.ceil((Zt-it.buffer.byteLength)/65536);Xt>0&&it.grow(Xt),new Uint8Array(it.buffer).set(new Uint8Array(xe.buffer,0,Zt));let kt=Ts.get(xe),Ot=cr.get(xe);kt!==void 0&&Ot?(Ts.set(it,kt),cr.set(it,{...Ot}),Ai.set(it,yl(xe).map(at=>({...at})))):Qo(it,r.wasmBytes,{ram:s.ram,pid:-1}),I!==void 0&&new Int32Array(it.buffer,I>>>0,3).fill(0);let gt=await ea(r.wasmBytes,0,i,e,n,s,void 0,{userMem:it,signalPendingOffset:I,parentCpuId:$,...typeof A.tlsBase=="number"?{tlsBase:A.tlsBase>>>0}:{},...typeof A.forkHandle=="number"?{forkHandle:A.forkHandle>>>0}:{},...typeof A.forkOwner=="number"?{forkOwner:A.forkOwner>>>0}:{},...typeof A.parentSp=="number"?{parentSp:A.parentSp>>>0}:{},...typeof A.userLane=="number"&&(A.userLane|0)>0?{forkLane:A.userLane|0}:{},...typeof A.dlopenFork=="object"&&A.dlopenFork!==null?{dlopenFork:A.dlopenFork}:{},...Array.isArray(A.lowFdRoutes)?{lowFdRoutes:A.lowFdRoutes}:{}});Atomics.store(f,dt.RET_LO,gt|0),Atomics.store(f,dt.RET_HI,gt<0?-1:0),Atomics.store(f,dt.STATE,As),Atomics.notify(f,dt.STATE);return}if(A?.kind==="syscall"){try{await fl(f,r.userMemory,t.tid,s,re)}catch(xe){s.onUserError?.(t.tid,`thread tid=${t.tid} syscall dispatch failed after group teardown (contained; -ESRCH): ${xe instanceof Error?xe.message:String(xe)}`),Atomics.store(f,dt.RET_LO,-3),Atomics.store(f,dt.RET_HI,-1),Atomics.store(f,dt.STATE,As),Atomics.notify(f,dt.STATE)}return}if(A?.kind==="exit"){if(E("adopted"),!P){P=!0;let xe=A.code|0;(typeof process>"u"?void 0:process)?.env?.HARDWAREJS_DEBUG_K7_U4F&&process.stderr.write(`[K7-U4f thread] tid=${t.tid} exit code=${xe} `);let Oe=A.groupExit;if(Oe&&(Oe.zapped|0)>0){let Xt=Oe.wstatus|0;D?.killGroup(i,t.tid,9,`a group terminus in a thread: the kernel condemned ${Oe.zapped} other thread(s) of pid=${i} and set the group's exit code to 0x${Xt.toString(16)} (`+(Xt&127?`WIFSIGNALED WTERMSIG=${Xt&127} \u2014 complete_signal's fatal block`:`WIFEXITED WEXITSTATUS=${Xt>>8&255} \u2014 do_group_exit`)+" / zap_other_threads) \u2014 unwinding their Workers")}else A.kind_exit==="exit-by-signal"&&!Oe&&s.onDmesg?.(3,`hwjs group-death: thread tid=${t.tid} of pid=${i} died by a fatal signal, but no kernel verdict came with the exit \u2014 the group is NOT condemned and its other threads keep running. KERNEL/HOST SKEW (rebuild vmlinux); on Linux this process would be dead `,t.tid);Do(n,t.tid),s.signalRegistry?.unregister(t.tid),ue(),ie(),A.wasmSyscallStats&&s.onWasmSyscallStats&&s.onWasmSyscallStats(t.tid,A.wasmSyscallStats);let it=(A.coopWaitViolations??0)|0;it>0&&s.onUserError?.(t.tid,`hwjs-coopwait: thread tid=${t.tid} (pid ${Qe||"?"}, lane ${t.laneId??0}) blocked its shared CPU Worker in an unbounded raw FUTEX_WAIT ${it} time(s) \u2014 the libc did not set HWJS_FUTEX_COOP_WAIT (PLAN-THREAD-POOL-RESIDENCY contract 3). Every co-resident task stalled for the duration.`);let Zt=(A.syncRestartViolations??0)|0;Zt>0&&s.onUserError?.(t.tid,`hwjs-coopwait: thread tid=${t.tid} (pid ${Qe||"?"}, lane ${t.laneId??0}) took the SYNCHRONOUS in-place -517 block-restart ${Zt} time(s) \u2014 its libc does not absorb the sentinel at raw syscalls (__hwjs_libc_syscall_park_abi absent), so the shared CPU Worker's event loop froze for the duration (PLAN-THREAD-POOL-RESIDENCY contract 3).`),pe?.noteExit(xe,"exit message from the thread Worker"),s.onUserExit?.(t.tid,xe),await x(),ee("thread exit"),Ri(r.userMemory,I),I=void 0,de(xe)}return}if(A?.kind==="error"){E("failed"),P||(P=!0,(typeof process>"u"?void 0:process)?.env?.HARDWAREJS_DEBUG_K7_U4F&&process.stderr.write(`[K7-U4f thread] tid=${t.tid} error: ${A.message} `),Do(n,t.tid),s.signalRegistry?.unregister(t.tid),ue(),D?.killGroup(i,t.tid),ie(),pe?.noteExit(-1,`terminal trap in the thread Worker: ${String(A.message??"")}`),s.onUserError?.(t.tid,String(A.message??"")),s.onUserExit?.(t.tid,-1),await x(),ee("terminal thread trap"),Ri(r.userMemory,I),I=void 0,de(-1));return}if(A?.kind==="task-probe-reply"){s.__taskProbeReply?.(A);return}if(A?.kind==="user-report"){s.onUserError?.(t.tid,String(A.message??""));return}if(A?.kind==="vmlinux-ready"){let xe=A.pid|0;xe>0&&pe?.notePid(xe,i),xe>0&&!P&&(Qe=xe),Qe>0&&Qe!==t.tid&&I!==void 0&&s.signalRegistry&&s.signalRegistry.register(Qe,{userMemory:r.userMemory,signalPendingOffset:I}),Qe>0&&!P&&!bg()&&e.set(Qe,{wasmBytes:r.wasmBytes,userMemory:r.userMemory,requestThreadPlacement:_,peekThreadPlacement:q,getCpuId:o(()=>$,"getCpuId"),leaderPid:i}),s.onVmlinuxReady?.(t.tid,{hasWasmSyscall:!!A.hasWasmSyscall,cpuId:$,initTaskAddr:typeof A.initTaskAddr=="number"?A.initTaskAddr:0,perProcessTaskAddr:typeof A.perProcessTaskAddr=="number"?A.perProcessTaskAddr:0});return}if(A?.kind==="vmlinux-error"){s.onUserError?.(t.tid,`vmlinux instantiation failed in Worker: ${String(A.message??"")}`);return}if(A?.kind==="dmesg"){s.onDmesg?.((A.level|0)>>>0,String(A.text),t.tid);return}},"handleThreadMsg");ae?(X.poolHandlers.set(Q,A=>{ve(A)}),X.syscallSyncDoors.set(Q,()=>{let A;try{A=fl(f,r.userMemory,t.tid,s,re)}catch(xe){s.onUserError?.(t.tid,`hwjs-merged: the SYNCHRONOUS syscall door threw for thread tid=${t.tid} nr=${f[dt.NR]|0} \u2014 ${xe instanceof Error?xe.message:String(xe)}. Declining, so the caller takes the message route: nothing was written here.`);return}return A?.catch?.(xe=>{s.onUserError?.(t.tid,`hwjs-merged: a thread syscall dispatched through the SYNCHRONOUS door rejected after awaiting (tid=${t.tid} nr=${f[dt.NR]|0}) \u2014 ${xe instanceof Error?xe.message:String(xe)}`)}),Atomics.load(f,dt.STATE)===As?"sync":"async"})):(_c(rt,ve),Jc(rt,async A=>{E("failed"),P||(P=!0,(typeof process>"u"?void 0:process)?.env?.HARDWAREJS_DEBUG_K7_U4F&&process.stderr.write(`[K7-U4f thread] tid=${t.tid} onError: ${A instanceof Error?A.message:String(A)} `),Do(n,t.tid),s.signalRegistry?.unregister(t.tid),ue(),D?.killGroup(i,t.tid),ie(),pe?.noteExit(-1,`Worker-level error event: ${A instanceof Error?A.message:String(A)}`),s.onUserError?.(t.tid,A instanceof Error?A.message:String(A)),s.onUserExit?.(t.tid,-1),await x(),Ri(r.userMemory,I),I=void 0,de(-1))}))}),Ae={mode:"thread",pid:s.vmlinuxModule!==void 0&&(h||p)?0:t.parentTid,tid:t.tid,userLane:(t.laneId??0)|0,ppid:t.parentTid,wasmBytes:r.wasmBytes,memory:r.userMemory,ctrl:b,argRegionOffset:t.argRegionOffset,stackPointerOffset:t.stackPointerOffset,tlsPointerOffset:t.tlsPointerOffset,mainTlsSlot:s.__mainTlsSlots?.allocate(i,t.tlsPointerOffset>>>0)??void 0,...y?{dlopenFork:y}:{},...Array.isArray(m?.lowFdRoutes)&&m.lowFdRoutes.length?{lowFdRoutes:m.lowFdRoutes}:{},...p?{inheritFiles:hg()?!0:2,fdActions:[]}:{},...I!==void 0?{signalPendingOffset:I}:{}};if(ae){let ve=new Set,A=0,xe=8,Oe=0;for(;;){let it=new SharedArrayBuffer(4),Zt=new Int32Array(it);Ks(rt,{kind:"add-task",routeKey:Q,spec:{routeKey:Q,claim:it,...Ae}});let Xt=Date.now()+250;for(;Atomics.load(Zt,0)===0&&Date.now()xe)return X.poolHandlers.delete(Q),X.syscallSyncDoors.delete(Q),X.noteResidentDelta(-1),Ce=null,s.onUserError?.(t.tid,`hwjs-thread-placement-pin: UNSATISFIABLE userLane=${t.laneId??0} cpu=${Ie} tid=${t.tid} group=${i} \u2014 the pinned lane did not claim the add-task in ${xe} attempts of 250ms`+(N===Ie?` (expected: cpu=${Ie} is the CALLING task's own lane, which it pins in a synchronous kernel ring wait for the whole clone(2) \u2014 this is the deadlock the caller-lane exclusion normally prevents, and the pin deliberately overrode it)`:" (that lane's resident is spinning without yielding)")+". Refusing the clone with -EAGAIN rather than re-placing on another cpu: a migrated pin would report a co-residency the run never had. Unset HWJS_THREAD_PLACEMENT_PIN or pin another cpu."),s.signalRegistry?.unregister(t.tid),n.delete(t.tid),ue(),Ri(r.userMemory,I),I=void 0,bs;let Ot;try{let gt=new Set(ve);for(let at of _e())gt.add(at);Ot=await X.getPoolWorker(N,gt,Ie)}catch(gt){return X.poolHandlers.delete(Q),X.syscallSyncDoors.delete(Q),X.noteResidentDelta(-1),Ce=null,s.onDmesg?.(4,`hwjs#3: thread add-task tid=${t.tid} routeKey=${Q} re-placement aborted (${gt.message}) \u2014 refusing the clone with -EAGAIN `,t.tid),s.signalRegistry?.unregister(t.tid),n.delete(t.tid),ue(),Ri(r.userMemory,I),I=void 0,bs}Ie===void 0&&ve.has(Ot.cpuId)&&(ve.clear(),A++,s.onDmesg?.(3,`hwjs#3: thread add-task tid=${t.tid} routeKey=${Q} found EVERY pool lane starved (cycle ${A}) \u2014 all residents are spinning without yielding; continuing to probe lanes `,t.tid)),Ce=Ot,$=Ce.cpuId,Ce.residentCount++,X.laneOccupy($,F),rt=Ce.worker,s.onDmesg?.(4,`hwjs#3: thread add-task tid=${t.tid} routeKey=${Q} claim timed out on starved pool lane cpu=${kt}; re-placing on cpu=${$} `,t.tid)}}else Ks(rt,{kind:"init",...s.kernelMemoryWasm===void 0?{kernelMemory:s.kernelMemory}:{},...(()=>{if(a||!l)return{};let de=l.list();return de.length>0?{sharedLibs:de}:{}})(),...s.vmlinuxModule!==void 0?{vmlinuxModule:s.vmlinuxModule}:{},...s.hwjsRtModule!==void 0?{hwjsRtModule:s.hwjsRtModule,hwjsRtBytes:s.hwjsRtBytes,hwjsRtProvenance:s.hwjsRtProvenance}:{},...s.kernelMemoryWasm!==void 0?{kernelMemoryWasm:s.kernelMemoryWasm}:{},...s.__kernelLaneLocks!==void 0?{kernelLaneLocks:s.__kernelLaneLocks}:{},...s.pauseBuffer!==void 0?{pauseBuffer:s.pauseBuffer}:{},cpuId:$,...Ae});if(!h&&!p)return 0;let Ve=3e4,me=await Promise.race([J,new Promise(de=>setTimeout(()=>de("timeout"),Ve))]);if(me==="adopted")return 0;let je=me==="failed-occupied"?Pg:bs;if(!P){P=!0,n.delete(t.tid);let de=Qe;if(s.signalRegistry?.unregister(t.tid),ue(),ie(),me==="timeout"){sp+=1;let ve="";try{let A=s.__kernelLaneLocks;if(A){let xe=new Int32Array(A),Oe=[];for(let it=1;it0?` (pid ${de})`:""} is stranded LIVE in the shared pid hash \u2014 it cannot be reaped from the host (the Worker holds the only current-bound instance and is unresponsive by hypothesis). Leaked live kernel tasks via this path so far: ${sp} (bounded by Worker wedges; the deterministic thread-refused path reaps).`+(ae?` RESIDENCY NOTE: this task is a POOL RESIDENT, so \u2014 unlike the dedicated-Worker path \u2014 the host CANNOT terminate its realm without killing every co-resident task on cpu ${$}. It is de-routed and its thread group is SIGKILLed instead, so a task whose pthread stack musl has already reclaimed cannot keep running over the live address space.`:"")),ae&&D?.killGroup(i,t.tid,9,"adoption gate TIMED OUT for a POOL RESIDENT \u2014 the host cannot terminate a shared CPU Worker, so the group is ended instead")}await x(),ee(`adoption gate ${me}`),Ri(r.userMemory,I),I=void 0}return je}o(vc,"spawnThreadWorker");function Do(t,e){let n=t.get(e);if(!n)return;t.delete(e);let{ctid:s,userMemory:r}=n,i=new Int32Array(r.buffer),l=s>>>2;if(globalThis.process?.env?.HWJS_CLEARTID_TRACE){let d=Atomics.load(i,l)|0;d!==0&&d!==(e|0)?globalThis.process?.stderr?.write(`[HWJS_CLEARTID_TRACE] SPURIOUS clear: tid=${e} clears ctid=0x${s.toString(16)} holding tid=${d} (a DIFFERENT live holder) \u2014 double-clear race on __thread_list_lock `):d===0&&globalThis.process?.stderr?.write(`[HWJS_CLEARTID_TRACE] redundant clear: tid=${e} ctid=0x${s.toString(16)} already 0 (kernel mm_release cleared first) \u2014 benign this instant, but proves the double-clear `)}Atomics.store(i,l,0),Atomics.notify(i,l,2147483647)}o(Do,"performCleartid");var dt={STATE:0,NR:1,A0:2,A1:3,A2:4,A3:5,A4:6,A5:7,RET_LO:9,RET_HI:10,PID:12,TID:13},pl=1,As=2,sI=2;function Cc(){return sI++}o(Cc,"allocLegacyRoutingId");function rp(t,e,n,s){if(n!==1&&n!==2)return-9;if(globalThis.process?.env?.D1_TRACE_FD&&(n===1||n===2))try{let r=Zi(s.subarray(0,48)).replace(/\n/g,"\\n");globalThis.process.stderr.write(`[D1_FD-MAIN pid=${e}] write(fd=${n}, ${s.byteLength}B "${r}") -> onUserOutput (SAB-RPC js-direct leak surface) `)}catch{}return t.onUserOutput?.(n,s,e),s.byteLength}o(rp,"writeToFd");async function fl(t,e,n,s,r){try{await rI(t,e,n,s,r)}catch(i){let l=t[dt.NR]|0;Atomics.load(t,dt.STATE)!==As&&(Atomics.store(t,dt.RET_LO,tp),Atomics.store(t,dt.RET_HI,-1),Atomics.store(t,dt.STATE,As),Atomics.notify(t,dt.STATE)),s.onUserError?.(n,`hwjs port BUG: the host syscall dispatcher THREW for nr=${l} (pid/tid ${n}) \u2014 ${i instanceof Error?i.message:String(i)}. The caller was answered -EIO (${tp}) rather than left parked on a reply that would never arrive; the errno is this belt's, not the kernel's, and the defect above is the thing to fix.`)}}o(fl,"dispatchSyscall");async function rI(t,e,n,s,r){let i=t[dt.NR]|0,l=t[dt.A0]|0,d=t[dt.A1]|0,a=t[dt.A2]|0,c=t[dt.A3]|0,h=t[dt.A4]|0,p=t[dt.A5]|0,m=0;switch(i){case fg:{let y=l,b=d>>>0,f=a>>>0,I=new Uint8Array(e.buffer,b,f),R=new Uint8Array(f);R.set(I),m=rp(s,n,y,R);break}case Wg:{let y=l,b=d>>>0,f=a>>>0,I=new Uint32Array(e.buffer),R=0;for(let X=0;X>>2)+X*2,N=I[F+0]>>>0,K=I[F+1]>>>0;if(K===0)continue;let k=new Uint8Array(e.buffer,N,K),U=new Uint8Array(K);U.set(k);let M=rp(s,n,y,U);if(M<0){m=R>0?R:M,R=-1;break}R+=M}R>=0&&(m=R);break}case Gg:{m=-25;break}case Vg:{m=1;break}case pg:{let y=l,b=d>>>0,f=a>>>0;if(y===0){if(s.stdinChannel){let I=await s.stdinChannel.read(n,f),R=I.bytes.byteLength;R>0&&new Uint8Array(e.buffer,b,R).set(I.bytes),m=R}else m=0;break}m=-9;break}case Bg:case $b:{let y=i===$b,b=y?d:0,f=(y?a:l)>>>0,I=(y?c:d)>>>0;if(!f){m=-14;break}let R=new DataView(e.buffer),X=Number(R.getBigInt64(f,!0)),F=R.getUint32(f+8,!0),N=X*1e3+F/1e6;b&1&&(N-=Date.now());let K=Date.now()+N,k=s.signalRegistry?.lookup(n),U=o(()=>{if(!k)return!1;let M=new Int32Array(k.userMemory.buffer),H=k.signalPendingOffset>>2;return(Atomics.load(M,H)|Atomics.load(M,H+1))!==0},"sigPending");for(m=0;Date.now()0&&await new Promise(H=>setTimeout(H,M))}break}case kg:case Tg:{m=0;break}case yg:{let y=Hr(d>>>0,ks);if(y===0){m=-22;break}if((h|0)!==-1&&((c|0)&32)===0&&!globalThis.process?.env?.HWJS_RED_MMAP_FILE_UNPOPULATED){s.onUnknownSyscall?.(n,i,[l,d,a,c,h,p]),m=-19;break}{let R=Qg(e,y);if(R>=0){s.ram.noteUserMemoryReused(e,y),new Uint8Array(e.buffer,R,y).fill(0),globalThis.process?.env?.D1_TRACE_MEM&&globalThis.process.stderr.write(`[D1_TRACE_MEM pid=${n}] mmap REUSED 0x${R.toString(16)}+0x${y.toString(16)} from the free list `),m=R;break}}let b=bl(e);b=Hr(b,ks);let f=e.buffer.byteLength;if(b+y>f){if(Hc){s.onUnknownSyscall?.(n,i,[l,d,a,c,h,p]),m=Zr;break}let R=Math.ceil((b+y-f)/65536);try{e.grow(R),globalThis.process?.env?.D1_TRACE_MEM&&globalThis.process.stderr.write(`[D1_TRACE_MEM pid=${n}] mmap GREW user_memory +${R} pages (0x${f.toString(16)} -> 0x${e.buffer.byteLength.toString(16)}) for len=0x${y.toString(16)} at bump=0x${b.toString(16)} `)}catch{s.onUserError?.(n,Zl(s.ram,e,n,`mmap ${y} B`,b+y)),s.onUnknownSyscall?.(n,i,[l,d,a,c,h,p]),m=Zr;break}if(f=e.buffer.byteLength,b+y>f){s.onUserError?.(n,`hwjs port BUG: mmap grow of ${R} pages for pid ${n} reported SUCCESS yet user_memory is still ${f} B, short of the ${b+y} B needed. Refusing rather than returning an out-of-bounds address. (This one really is an internal defect, not a memory ceiling.)`),s.onUnknownSyscall?.(n,i,[l,d,a,c,h,p]),m=Zr;break}}let I=b;Ts.set(e,b+y),new Uint8Array(e.buffer,I,y).fill(0),m=I;break}case gg:{let y=l>>>0,b=d>>>0;if((y&ks-1)!==0||b===0){m=-22;break}let f=Hr(b,ks),I=cr.get(e),R=I?I.mmapFloor+(I.rtWindowSize??0):0,X=bl(e),F=Math.max(y,R),N=Math.min(y+f,X),K=Dg(e,F,N);s.ram.noteUserMemoryFreed(e,K),globalThis.process?.env?.D1_TRACE_MEM&&globalThis.process.stderr.write(`[D1_TRACE_MEM pid=${n}] munmap 0x${y.toString(16)}+0x${f.toString(16)} -> freed [0x${F.toString(16)},0x${N.toString(16)}) net +${K} B unreclaimable-but-free `),m=0;break}case Zg:{let y=l>>>0,b=a|0,f=50331663;if(y&4095){m=-22;break}if(b&~f){m=-22;break}if(b&16777216&&b&33554432){m=-22;break}m=0;break}case Ig:{let y=cr.get(e),b=l>>>0;if(!y||!globalThis.process?.env?.D1_BRK_ENABLE){m=0;break}if(b===0){m=y.brk;break}if(by.mmapFloor){s.onUnknownSyscall?.(n,i,[l,d,a,c,h,p]),m=Zr;break}by.brkHighWater&&(y.brkHighWater=b),m=b;break}case wg:{m=0;break}case Yg:{m=0;break}case xg:{let y=d>>>0;if(y===0||(y&3)!==0){m=-22;break}let b=Date.now(),f=Math.floor(b/1e3),I=Math.round((b-f*1e3)*1e6),R=new Uint32Array(e.buffer),X=y>>>2;R[X]=f>>>0,R[X+1]=Math.floor(f/4294967296)>>>0,R[X+2]=I>>>0,R[X+3]=0,m=0;break}case Sg:{let y=l>>>0,b=d>>>0,f=a>>>0,I=c>>>0,R=h>>>0,X=p>>>0;if(!(y&Fg)){m=yr;break}if(!(typeof process<"u"&&!!process.env?.HWJS_RED_CLONE_LAX)&&(!(y&Eg)||y&qb)){s.onDmesg?.(4,`hwjs-spawn: SYS_clone pid=${n} flags=0x${y.toString(16)} REFUSED (-ENOSYS): CLONE_VM without CLONE_THREAD`+(y&qb?" (+CLONE_VFORK \u2014 vfork/posix_spawn shape)":"")+" \u2014 process-semantics clone cannot be serviced as a thread; use fork()+exec (musl _Fork park protocol)",n),m=yr;break}if(!r){m=yr;break}if(X===0){m=-22;break}let N=new Uint32Array(e.buffer),K=N[X>>>2]>>>0,k=N[(X>>>2)+1]>>>0,U=Cc();(typeof process>"u"?void 0:process)?.env?.HARDWAREJS_DEBUG_K7_U4F&&process.stderr.write(`[K7-U4f SYS_clone] pid=${n} newTid=${U} flags=0x${y.toString(16)} stack=0x${b.toString(16)} ptid=0x${f.toString(16)} tls=0x${I.toString(16)} ctid=0x${R.toString(16)} fn_arg_block=0x${X.toString(16)} (fn=0x${K.toString(16)} arg=0x${k.toString(16)}) `);let M=Hr(ep,ks),H=bl(e);H=Hr(H,ks);let Ge=e.buffer.byteLength;if(H+M>Ge){m=Zr;break}let C=H;Ts.set(e,H+M);let Ie=new DataView(e.buffer,C,ep);Ie.setUint32(0,Jg,!0),Ie.setUint32(4,Ug,!0),Ie.setUint32(8,Mg,!0),Ie.setUint32(12,y,!0),Ie.setUint32(16,K,!0),Ie.setUint32(20,0,!0),Ie.setUint32(24,k,!0),Ie.setUint32(28,0,!0),Ie.setUint32(32,n,!0),Ie.setUint32(36,0,!0),Ie.setUint32(40,U,!0),Ie.setUint32(44,0,!0),Ie.setUint32(48,I,!0),Ie.setUint32(52,0,!0),Ie.setUint32(56,b,!0),Ie.setUint32(60,0,!0),f!==0&&(f&3)===0&&f+4<=Ge&&(N[f>>>2]=U>>>0),y&_g&&R!==0&&(R&3)===0&&R+4<=Ge&&r.cloneCleartidMap.set(U,{ctid:R,userMemory:e});let B={mode:1,flags:0,tid:U,parentTid:n,execImageOffset:0,execImageSize:0,execImageNsegs:0,argRegionOffset:C,stackPointerOffset:b,tlsPointerOffset:I,libcImageOffset:0,libcImageSize:0,libcImageNsegs:0,libcDigestOffset:0},ae=await r.spawnThread(B);if(ae<0){m=ae;break}m=U;break}case Cg:{if(!s.childImageRegistry){m=yr;break}let y=l>>>0;if(y===0){m=-22;break}let b=new Uint8Array(e.buffer),f=4096,I=0,R=e.buffer.byteLength;for(;y+I>>0,b=d>>>0,f=a>>>0;if(y===0){m=-22;break}let I=new Uint8Array(e.buffer),R=4096,X=0,F=e.buffer.byteLength;for(;y+X0)if(b===0||(b&3)!==0||b+f*12>F)M=-14;else{let C=new Uint32Array(e.buffer);for(let Ie=0;Ie>>2)+Ie*3,ae=C[B+0]|0,Ce=C[B+1]|0,Q=C[B+2]|0;if(ae!==Hg&&ae!==vg){M=-22;break}U.push([ae,Ce,Q])}}if(M<0){m=M;break}let H=s.vmlinuxModule!==void 0?0:Cc();m=await ea(k,H,n,r.parents,r.cloneCleartidMap,s,{inheritFiles:!0,fdActions:U});break}case Xg:{m=n;break}case Rg:{m=yr;break}default:{s.onUnknownSyscall?.(n,i,[l,d,a,c,h,p]),m=yr;break}}if(globalThis.process?.env?.D1_TRACE_MEM&&(i===9||i===10||i===11||i===12)){let y=cr.get(e),b=i===9?"mmap":i===10?"mprotect":i===11?"munmap":"brk";globalThis.process.stderr.write(`[D1_TRACE_MEM pid=${n}] ${b}(a0=0x${(l>>>0).toString(16)},len=0x${(d>>>0).toString(16)}) -> 0x${(m>>>0).toString(16)} (ret=${m}) [floor=0x${(y?.mmapFloor??0).toString(16)} brk=0x${(y?.brk??0).toString(16)}] `)}Atomics.store(t,dt.RET_LO,m|0),Atomics.store(t,dt.RET_HI,m<0?-1:0),Atomics.store(t,dt.STATE,As),Atomics.notify(t,dt.STATE)}o(rI,"dispatchSyscallBody");function Fc(){let t=globalThis;return typeof t.process<"u"&&t.process?.versions?.node?"node":"browser"}o(Fc,"detectPlatform");async function Ec(t,e,n="unknown"){let s=e==="node"?new(await import("node:worker_threads")).Worker(t,{type:"module"}):new globalThis.Worker(t,{type:"module"});return Qm(s,n),s}o(Ec,"createWorker");function Ks(t,e){t.postMessage(e)}o(Ks,"postToWorker");function _c(t,e){typeof t.on=="function"?t.on("message",e):t.onmessage=n=>e(n.data)}o(_c,"onMessage");function Jc(t,e){typeof t.on=="function"?t.on("error",n=>e(ip(n))):t.onerror=n=>e(ip(n))}o(Jc,"onError");function ip(t){if(t instanceof Error)return t.stack?`${t.message} ${t.stack}`:t.message;if(t&&typeof t=="object"){let e=t,n=[];return e.message&&n.push(String(e.message)),e.filename&&n.push(`at ${String(e.filename)}:${e.lineno??"?"}:${e.colno??"?"}`),e.error instanceof Error?n.push(e.error.stack?`${e.error.message} ${e.error.stack}`:e.error.message):e.error!=null&&n.push(String(e.error)),n.length>0?n.join(" | "):`Worker emitted a content-free "error" event (no message/error/filename). In the browser this is the signature of a module Worker that failed to LOAD or PARSE. Which cause to look at depends on where the entry came from. A blob: URL has no directory, so ANY surviving relative import in the bundle (e.g. ./dynLoader.mjs) resolves to nothing \u2014 the entry must be bundled self-contained before it is turned into a Blob. A served URL fails the same way when a sibling the entry imports is not served beside it. Otherwise: a syntax error, or a cross-origin entry the embedder's COEP will not admit.`}return t===void 0?"":String(t)}o(ip,"describeWorkerError");async function vr(t){Ha(t);try{if(typeof t.terminate=="function"){let e=t.terminate();e&&typeof e.then=="function"&&await e}}catch{}}o(vr,"terminateWorker");var iI=/^RT-PROVENANCE commit=([0-9a-f]{40}) dirty=([01]) src=([0-9a-f]{64})(?: srckey=([0-9a-f]{64}))?$/;function up(t,e){let n=new TextDecoder().decode(t).trim(),s=iI.exec(n);if(!s)throw new Error(`hwjs-rt: ${e} carries an unparseable RT-PROVENANCE ("${n.slice(0,160)}") \u2014 refusing the kernel-provided runtime`);return{commit:s[1],dirty:s[2]==="1",srcSha256:s[3],srcKey:s[4],raw:n}}o(up,"parseProvenance");async function na(t){let e=WebAssembly.Module.customSections(t,"hwjs.rt.so"),n=WebAssembly.Module.customSections(t,"hwjs.rt.provenance");if(e.length===0&&n.length===0)return;if(e.length!==1||n.length!==1)throw new Error(`hwjs-rt: vmlinux carries ${e.length}x hwjs.rt.so / ${n.length}x hwjs.rt.provenance (want exactly 1 of each, or neither) \u2014 a half-embedded runtime is a build defect, refusing`);let s=up(n[0],"vmlinux");if(s.dirty)throw new Error(`hwjs-rt: the kernel-provided runtime attests a DIRTY tree (${s.raw}) \u2014 refusing (never-silent; rebuild from a clean linux tree)`);let r;try{r=await WebAssembly.compile(e[0])}catch(d){throw new Error(`hwjs-rt: embedded libhwjs-rt.so does not compile: ${d instanceof Error?d.message:String(d)}`)}for(let d of["dylink.0","hwjs.abi"])if(WebAssembly.Module.customSections(r,d).length!==1)throw new Error(`hwjs-rt: embedded libhwjs-rt.so lacks a (single) ${d} custom section \u2014 not a conformant dynamic module, refusing`);let i=WebAssembly.Module.customSections(r,"hwjs.rt.provenance");if(i.length!==1)throw new Error(`hwjs-rt: embedded libhwjs-rt.so carries ${i.length} internal hwjs.rt.provenance sections (want exactly 1), refusing`);let l=up(i[0],"libhwjs-rt.so");if(l.raw!==s.raw)throw new Error(`hwjs-rt: provenance mismatch between vmlinux ("${s.raw}") and the .so's internal section ("${l.raw}") \u2014 mix-and-match runtime, refusing`);return{module:r,provenance:s,byteLength:e[0].byteLength,bytes:new Uint8Array(e[0].slice(0))}}o(na,"extractHwjsRt");var sa=class{static{o(this,"SignalRingConsumer")}kernelMemory;ringOffset;handler;onProcessed;onError;i32;dv;running=!1;stopped=!1;loopDone=null;lastSignalNotifyValue=0;constructor(e){if((e.ringOffset&3)!==0)throw new Error(`SignalRingConsumer: ringOffset 0x${e.ringOffset.toString(16)} not 4-byte aligned`);this.kernelMemory=e.kernelMemory,this.ringOffset=e.ringOffset,this.handler=e.handler,this.onProcessed=e.onProcessed,this.onError=e.onError,this.i32=new Int32Array(this.kernelMemory),this.dv=new DataView(this.kernelMemory)}start(){return this.running||this.stopped?this.loopDone??Promise.resolve():(this.running=!0,this.lastSignalNotifyValue=Atomics.load(this.i32,this.signalNotifyIdx()),this.loopDone=this.runLoop(),this.loopDone)}async stop(){this.stopped||(this.stopped=!0,Atomics.notify(this.i32,this.signalNotifyIdx(),1/0),await this.loopDone)}signalNotifyIdx(){return this.ringOffset+8>>>2}headIdx(){return this.ringOffset+0>>>2}tailIdx(){return this.ringOffset+4>>>2}readSlot(e){let n=Ed(this.ringOffset,e);return{tid:this.dv.getUint32(n+0,!0),sig:this.dv.getUint32(n+4,!0),senderPid:this.dv.getUint32(n+8,!0)}}async runLoop(){try{for(await this.drain();!this.stopped;){if(Atomics.load(this.i32,this.signalNotifyIdx())===this.lastSignalNotifyValue){let n=Atomics.waitAsync(this.i32,this.signalNotifyIdx(),this.lastSignalNotifyValue,5e3);if(n.async){let s=await n.value}}if(this.stopped)break;this.lastSignalNotifyValue=Atomics.load(this.i32,this.signalNotifyIdx()),await this.drain()}}catch(e){throw this.onError?.(e),e}finally{this.running=!1}}async drain(){let e=Atomics.load(this.i32,this.headIdx())>>>0,n=Atomics.load(this.i32,this.tailIdx())>>>0;for(;e-n>>>0>0;){let s=n%16,r=this.readSlot(s);try{let i=this.handler(r);i&&typeof i.then=="function"&&await i}catch(i){this.onError?.(i)}n=n+1>>>0,Atomics.store(this.i32,this.tailIdx(),n),this.onProcessed?.(r)}}};var ds=class t{static{o(this,"GuestMemory")}wasm;buf;view;bytesView;words;rederives=0;constructor(e){this.wasm=e.kernelMemoryWasm,this.buf=this.wasm?.buffer??e.kernelMemory,this.view=new DataView(this.buf),this.bytesView=new Uint8Array(this.buf),this.words=new Int32Array(this.buf)}static overFixedBuffer(e){return new t({kernelMemory:e})}static overFixedBytes(e){if(e.byteOffset!==0||e.byteLength!==e.buffer.byteLength)throw new RangeError(`GuestMemory.overFixedBytes: the array must cover its whole buffer (byteOffset=${e.byteOffset}, byteLength=${e.byteLength}, buffer=${e.buffer.byteLength}) \u2014 guest addresses are absolute, so a windowed view would shift every one of them`);return new t({kernelMemory:e.buffer})}live(){let e=this.wasm?.buffer;e===void 0||e===this.buf||(this.buf=e,this.view=new DataView(e),this.bytesView=new Uint8Array(e),this.words=new Int32Array(e),this.rederives++)}get dv(){return this.live(),this.view}get u8(){return this.live(),this.bytesView}get i32(){return this.live(),this.words}get byteLength(){return this.live(),this.bytesView.length}get growsObserved(){return this.live(),this.rederives}checkRange(e,n,s){let r=this.bytesView.length;if(!Number.isInteger(e)||!Number.isInteger(n)||e<0||n<0||e+n>r)throw new RangeError(`guest memory ${s}: [${e}, ${e+n}) is outside the live guest RAM (${r}B committed, ${this.rederives} grow(s) observed). A guest-supplied address past the end is a corrupt descriptor, not a stale view \u2014 this handle re-derives from the live memory.`)}bytes(e,n){return this.live(),this.checkRange(e,n,"bytes"),this.bytesView.subarray(e,e+n)}read(e,n){return this.live(),this.checkRange(e,n,"read"),this.bytesView.slice(e,e+n)}copyOut(e,n,s,r=0){if(this.live(),this.checkRange(e,n,"copyOut"),r+n>s.length)throw new RangeError(`guest memory copyOut: destination too small (need ${r+n}B, have ${s.length}B)`);s.set(this.bytesView.subarray(e,e+n),r)}write(e,n){this.live(),this.checkRange(e,n.length,"write"),this.bytesView.set(n,e)}fill(e,n,s=0){this.live(),this.checkRange(e,n,"fill"),this.bytesView.fill(s,e,e+n)}};function gp(t,e){let n=t.dv,s=n.getUint32(e+112,!0);if(!(s&4))return{readable:!1,word0:0,why:`STATUS=0x${s.toString(16)} has no DRIVER_OK yet \u2014 negotiation is not finished`};let r=n.getUint32(e+36,!0);return r!==0?{readable:!1,word0:0,why:`DRIVER_FEATURES_SEL reads back ${r}, not 0 \u2014 the register does not hold word 0 and this readback assumption no longer holds`}:{readable:!0,word0:n.getUint32(e+32,!0)>>>0,why:""}}o(gp,"readAcceptedFeaturesWord0");var oI=768,aI=32;var lI=1,dI=2,cI=4,uI=16,zs=class{constructor(e,n){this.mem=e;this.geom=n}mem;geom;static{o(this,"VirtQueue")}lastAvailIdx=0;get ready(){return this.geom.ready}get size(){return this.geom.num}async drainAvail(e,n){if(!this.geom.ready||this.geom.num===0)return 0;let s=0,r=this.mem.dv.getUint16(this.geom.avail+2,!0);for(;this.lastAvailIdx!==r&&!(n&&!n());){let i=this.lastAvailIdx%this.geom.num,l=this.mem.dv.getUint16(this.geom.avail+4+i*2,!0),d=this.pullChain(l),a=await e(d);this.publishUsed(l,a>>>0),this.lastAvailIdx=this.lastAvailIdx+1&65535,s++}return s}takeAvail(){if(!this.geom.ready||this.geom.num===0)return null;let e=this.mem.dv,n=e.getUint16(this.geom.avail+2,!0);if(this.lastAvailIdx===n)return null;let s=this.lastAvailIdx%this.geom.num,r=e.getUint16(this.geom.avail+4+s*2,!0),i=this.pullChain(r);return this.lastAvailIdx=this.lastAvailIdx+1&65535,i}complete(e,n){this.publishUsed(e,n>>>0)}rewind(e){e<=0||(this.lastAvailIdx=this.lastAvailIdx-e&65535)}get availPending(){return!this.geom.ready||this.geom.num===0?0:this.mem.dv.getUint16(this.geom.avail+2,!0)-this.lastAvailIdx&65535}pullChain(e){let n=[],s=[],r=e,i=this.mem.dv;for(let l=0;l<=this.geom.num;l++){let d=this.geom.desc+r*uI,a=i.getUint32(d,!0),c=i.getUint32(d+4,!0),h=i.getUint32(d+8,!0),p=i.getUint16(d+12,!0),m=i.getUint16(d+14,!0),y=c*4294967296+a;if(p&cI)throw new Error("virtio_mmio: INDIRECT descriptor not supported (VERSION_1-only device)");if((p&dI?s:n).push({addr:y,len:h}),!(p&lI))return{head:e,readable:n,writable:s};r=m}throw new Error("virtio_mmio: descriptor chain exceeds queue size (corrupt)")}publishUsed(e,n){let s=this.mem.dv,r=s.getUint16(this.geom.used+2,!0),i=r%this.geom.num,l=this.geom.used+4+i*8;s.setUint32(l,e>>>0,!0),s.setUint32(l+4,n>>>0,!0),Atomics.store(this.mem.i32,this.geom.used+0>>2,mI(s.getUint16(this.geom.used,!0),r+1&65535))}};function gr(t,e,n){let s=e+oI+n*aI,r=t.dv,i=r.getUint32(s+0,!0),l=Atomics.load(t.i32,s+4>>2)===1,d=r.getUint32(s+8,!0),a=r.getUint32(s+12,!0),c=r.getUint32(s+16,!0),h=r.getUint32(s+20,!0),p=r.getUint32(s+24,!0),m=r.getUint32(s+28,!0);return{num:i,ready:l,desc:a*4294967296+d,avail:h*4294967296+c,used:m*4294967296+p}}o(gr,"readQueueGeom");function mI(t,e){return(e&65535)<<16|t&65535}o(mI,"packU16Pair");var ra=class{constructor(e){this.opts=e;this.mem=new ds(e)}opts;static{o(this,"VirtioBlkBackend")}mem;queue;onKick(e){try{if(e!==0)throw new Error(`virtio-blk: invalid queue ${e}`);if(!this.queue?.ready){let n=gr(this.mem,this.opts.windowBase,0);if(!n.ready||!n.num)return;this.queue=new zs(this.mem,n)}for(let n;n=this.queue.takeAvail();){let s=this.serve(n);this.queue.complete(n.head,s);let r=this.mem.i32;Atomics.or(r,this.opts.windowBase+96>>2,1),this.opts.suppressIrq||(Atomics.or(r,this.opts.irqPendingOffset>>2,128),Atomics.add(r,this.opts.schedWakeupOffset>>2,1),Atomics.notify(r,this.opts.schedWakeupOffset>>2))}}catch(n){this.opts.onError?.(n)}}gather(e){let n=e.reduce((i,l)=>i+l.len,0);if(n>16*1024*1024)throw new Error("virtio-blk: oversized request");let s=new Uint8Array(n),r=0;for(let i of e)s.set(this.mem.bytes(i.addr,i.len),r),r+=i.len;return s}serve(e){let n=e.writable.at(-1);if(!n||n.len!==1)throw new Error("virtio-blk: missing one-byte status descriptor");let s=0,r=1;try{let i=this.gather(e.readable);if(i.length<16)throw new Error("virtio-blk: truncated header");let l=new DataView(i.buffer),d=l.getUint32(0,!0),a=l.getBigUint64(8,!0),c=e.writable.slice(0,-1),h=d===1?i.length-16:c.reduce((p,m)=>p+m.len,0);if(d===0||d===1){if(h%512||h>16*1024*1024||a*512n+BigInt(h)>BigInt(this.opts.disk.size))throw new Error("virtio-blk: sector range exceeds selected image");if(d===0){if(i.length!==16)throw new Error("virtio-blk: unexpected read payload");let p=this.opts.disk.read(Number(a*512n),h);if(p.length!==h)throw new Error("virtio-blk: short disk read");let m=0;for(let y of c)this.mem.bytes(y.addr,y.len).set(p.subarray(m,m+y.len)),m+=y.len;r+=h}else{if(this.opts.disk.readOnly||c.length)throw new Error("virtio-blk: write refused");this.opts.disk.write(Number(a*512n),i.subarray(16))}}else if(d===4){if(i.length!==16||c.length)throw new Error("virtio-blk: malformed flush");this.opts.disk.flush()}else s=2}catch(i){s=1,this.opts.onError?.(i)}return this.mem.bytes(n.addr,1)[0]=s,r}};var Ip={EPERM:1,ENOENT:2,EIO:5,EACCES:13,EBUSY:16,EEXIST:17,EXDEV:18,ENOTDIR:20,EISDIR:21,EINVAL:22,ENOSPC:28,EROFS:30,ENAMETOOLONG:36,ENOSYS:38,ENOTEMPTY:39,ENOTSUP:95,EOPNOTSUPP:95};function hI(t){let e=t,n=e?.errno;if(typeof n=="number"&&Number.isInteger(n)&&n>0&&n<=4095)return n;let s=e?.code;return typeof s=="string"&&Object.prototype.hasOwnProperty.call(Ip,s)?Ip[s]:null}o(hI,"attributedErrno");var Gp=40,Wp=16;function Lc(t){return t!==null&&(typeof t=="object"||typeof t=="function")&&typeof t.then=="function"}o(Lc,"isThenable");function is(t,e){return Lc(t)?t.then(e):e(t)}o(is,"maybeThen");function bI(t,e){let n=e.reduce((i,l)=>i+l.len,0),s=new Uint8Array(n),r=0;for(let i of e)t.copyOut(i.addr,i.len,s,r),r+=i.len;return s}o(bI,"gather");function pI(t,e,n){let s=0;for(let r of e){if(s>=n.length)break;let i=Math.min(r.len,n.length-s);t.write(r.addr,n.subarray(s,s+i)),s+=i}return s}o(pI,"scatter");function Ir(t,e){let n=e;for(;nt.MTIME_MEMO_MAX){let n=this.regularMtime.keys().next();n.done||this.regularMtime.delete(n.value)}}mayKeepCache(e){if(!this.autoInvalData)return!1;let n=this.regularMtime.get(e);return n!==void 0&&n>=946684800}async handle(e,n,s){return this.handleMaybeSync(e,n,s)}handleMaybeSync(e,n,s){let r=bI(e,n);if(r.length{let b=hI(y);return b===null?console.error("virtio_fs: backend error -> EIO:",y.message):console.debug(`virtio_fs: backend refusal -> errno ${b}:`,y.message),this.reply(e,s,d,-(b??5),new Uint8Array(0))},"fail"),p=o(y=>{try{return y===Mc?0:typeof y=="number"?this.reply(e,s,d,-y,new Uint8Array(0)):this.reply(e,s,d,0,y)}catch(b){return h(b)}},"finish"),m;try{m=this.dispatch(l,a,i,r,c)}catch(y){return h(y)}return Lc(m)?m.then(p,h):p(m)}dispatch(e,n,s,r,i){switch(e){case 26:{let l=s.getUint32(i+0,!0),d=r.length>=i+16?s.getUint32(i+12,!0):0;return this.autoInvalData=(d&4096)!==0,!this.autoInvalData&&!this.saidNoAutoInval&&(this.saidNoAutoInval=!0,console.warn(`virtio_fs: kernel offered no FUSE_AUTO_INVAL_DATA in INIT (flags=0x${d.toString(16)}); page-cache retention stays OFF and every open(2) re-reads the whole file`)),fI(l,typeof this.fs.setlk=="function"&&this.fs.crossContextLocks===!0,this.autoInvalData)}case 38:return new Uint8Array(0);case 2:return r.length>=i+8&&(this.forgetMemos(n),this.fs.forget?.(n,Number(s.getBigUint64(i,!0)))),Mc;case 42:{let l=s.getUint32(i,!0),d=i+8,a=Math.floor((r.length-d)/16);l>a&&console.warn(`virtio_fs: BATCH_FORGET claims ${l} entries but the descriptor holds ${a}; forgetting the ${a} that are there rather than reading past the frame`);let c=Math.min(l,a);for(let h=0;hl?this.attrOut(l):2);case 1:{let l=Ir(r,i);return is(this.fs.lookup(n,l),d=>d?this.entryOut(d):2)}case 14:return this.openOut(this.mayKeepCache(n));case 27:return this.openOut(!1);case 29:case 25:return new Uint8Array(0);case 18:return this.fs.releaselk&&s.getUint32(i+12,!0)&2?is(this.fs.releaselk(n,s.getBigUint64(i+16,!0)),()=>new Uint8Array(0)):new Uint8Array(0);case 32:case 33:{if(!this.fs.setlk)return 38;let l=s.getBigUint64(i+8,!0),d=s.getUint32(i+32,!0);return(s.getUint32(i+40,!0)&1)===0?38:e===33?37:d!==0&&d!==1&&d!==2?22:is(this.fs.setlk(n,l,d),c=>typeof c=="number"&&c>0?c:new Uint8Array(0))}case 20:{if(!this.fs.fsync)return new Uint8Array(0);let l=s.getUint32(i+8,!0);return is(this.fs.fsync(n,(l&1)!==0),()=>new Uint8Array(0))}case 15:{let l=Number(s.getBigUint64(i+8,!0)),d=s.getUint32(i+16,!0);return is(this.fs.read(n,l,d),a=>new Uint8Array(a))}case 28:case 44:{let l=Number(s.getBigUint64(i+8,!0)),d=s.getUint32(i+16,!0);return this.readdirOut(n,l,d,e===44)}case 5:return this.fs.readlink?is(this.fs.readlink(n),l=>new TextEncoder().encode(l)):38;case 17:return this.statfsOut();case 22:return 95;case 16:{if(!this.fs.write)return 38;let l=Number(s.getBigUint64(i+8,!0)),d=s.getUint32(i+16,!0),a=i+40,c=r.subarray(a,a+d);return is(this.fs.write(n,l,c),h=>{let p=new Uint8Array(8);return new DataView(p.buffer).setUint32(0,h>>>0,!0),p})}case 4:return is(this.fs.getattr(n),l=>{if(!l)return 2;if(this.fs.setattr){let d=s.getUint32(i+0,!0),a=1,c=2,h=4,p=8,m=32,y=256,b={};return d&p&&(b.size=Number(s.getBigUint64(i+16,!0))),d&a&&(b.mode=s.getUint32(i+68,!0)),d&c&&(b.uid=s.getUint32(i+76,!0)),d&h&&(b.gid=s.getUint32(i+80,!0)),d&y?b.mtimeSec=Math.floor(Date.now()/1e3):d&m&&(b.mtimeSec=Number(s.getBigUint64(i+40,!0))),is(this.fs.setattr(n,b),f=>this.attrOut(f))}return this.attrOut(l)});case 10:case 11:{if(!this.fs.unlink)return 38;let l=Ir(r,i);return is(this.fs.unlink(n,l,e===11),d=>typeof d=="number"&&d>0?d:(this.invalidateDir(n),new Uint8Array(0)))}case 12:{if(!this.fs.rename)return 38;let l=Number(s.getBigUint64(i+0,!0)),d=Ir(r,i+8),a=Ir(r,i+8+d.length+1);return is(this.fs.rename(n,d,l,a),c=>typeof c=="number"&&c>0?c:(this.invalidateDir(n),this.invalidateDir(l),new Uint8Array(0)))}case 35:{if(!this.fs.create)return 38;let l=s.getUint32(i+4,!0),d=Ir(r,i+16);return is(this.fs.create(n,d,l),a=>{this.invalidateDir(n);let c=this.entryOut(a),h=this.openOut(!1),p=new Uint8Array(c.length+h.length);return p.set(c,0),p.set(h,c.length),p})}case 9:{if(!this.fs.mkdir)return 38;let l=s.getUint32(i+0,!0),d=Ir(r,i+8);return is(this.fs.mkdir(n,d,l),a=>(this.invalidateDir(n),this.entryOut(a)))}case 6:{if(!this.fs.symlink)return 1;let l=Ir(r,i),d=Ir(r,i+l.length+1);return is(this.fs.symlink(n,l,d),a=>(this.invalidateDir(n),this.entryOut(a)))}case 13:{if(!this.fs.link)return 1;let l=Number(s.getBigUint64(i+0,!0)),d=Ir(r,i+8);return is(this.fs.link(n,d,l),a=>(this.invalidateDir(n),this.entryOut(a)))}case 8:{if(!this.fs.mknod)return 1;let l=s.getUint32(i+0,!0),d=s.getUint32(i+4,!0),a=Ir(r,i+16);return is(this.fs.mknod(n,a,l,d),c=>(this.invalidateDir(n),this.entryOut(c)))}default:return 38}}reply(e,n,s,r,i){let l=new Uint8Array(Wp+i.length),d=new DataView(l.buffer);return d.setUint32(0,l.length,!0),d.setInt32(4,r,!0),d.setBigUint64(8,s,!0),l.set(i,Wp),pI(e,n,l)}attrOut(e){let n=new Uint8Array(16+Uc),s=new DataView(n.buffer);return s.setBigUint64(0,1n,!0),wp(s,16,e),this.noteAttr(e),n}entryOut(e){let n=new Uint8Array(40+Uc),s=new DataView(n.buffer);return s.setBigUint64(0,BigInt(e.ino),!0),s.setBigUint64(8,0n,!0),s.setBigUint64(16,1n,!0),s.setBigUint64(24,1n,!0),wp(s,40,e),this.noteAttr(e),n}openOut(e){let n=new Uint8Array(16);return e&&new DataView(n.buffer).setUint32(8,2,!0),n}statfsOut(){return this.fs.statfs?is(this.fs.statfs(),e=>{let n=Math.max(0,Math.floor(e.totalBytes)),s=Math.max(0,Math.min(Math.floor(e.freeBytes),n));return this.buildStatfs(BigInt(Math.ceil(n/4096)),BigInt(Math.floor(s/4096)),BigInt(e.files??1<<20),BigInt(e.ffree??1<<19))}):this.buildStatfs(1n<<20n,1n<<19n,1n<<16n,1n<<15n)}buildStatfs(e,n,s,r){let i=new Uint8Array(80),l=new DataView(i.buffer),d=4096;return l.setBigUint64(0,e,!0),l.setBigUint64(8,n,!0),l.setBigUint64(16,n,!0),l.setBigUint64(24,s,!0),l.setBigUint64(32,r,!0),l.setUint32(40,d,!0),l.setUint32(44,255,!0),l.setUint32(48,d,!0),i}readdirOut(e,n,s,r){let i=n===0?void 0:this.readdirCache.get(e);if(i)return this.readdirPage(i,n,s,r);let l=this.mutations;return is(this.fs.readdir(e),d=>(this.mutations===l&&this.readdirCache.set(e,d),this.readdirPage(d,n,s,r)))}readdirPage(e,n,s,r){let l=r?40+Uc:0,d=[],a=0,c=new TextEncoder;for(let p=n;ps)break;d.push({e:m,nameBytes:y,cookie:p+1,recLen:b}),a+=b}if(!r)return this.readdirBytes(d,a,null);let h=d.map(p=>this.fs.getattr(p.e.ino));return h.some(Lc)?Promise.all(h).then(p=>this.readdirBytes(d,a,p)):this.readdirBytes(d,a,h)}readdirBytes(e,n,s){let r=new Uint8Array(n),i=new DataView(r.buffer),l=0;for(let d=0;dthis.publish(e,n,s,i),i=>{this.inFlight--,this.opts.onError?.(i)})}publish(e,n,s,r){try{this.dbg(`q${e} req head=${s.head} -> ${r}B`),n.complete(s.head,r),this.raiseInterrupt()}catch(i){this.opts.onError?.(i)}finally{this.inFlight--}}raiseInterrupt(){let e=this.mem.i32,n=this.opts.windowBase+96;if(Atomics.or(e,n>>2,1),this.opts.suppressIrq)return;let s=1<<(this.opts.irqBit??0);Atomics.or(e,this.opts.irqPendingOffset>>2,s),Atomics.add(e,this.opts.schedWakeupOffset>>2,1);let r=Atomics.notify(e,this.opts.schedWakeupOffset>>2,1);this.dbg(`raiseInterrupt: pending|=${s} schedWakeup notify woke=${r}`)}};var Sp=0,kp=1,Xp=8,oa=class{constructor(e){this.opts=e;this.mem=new ds(e)}opts;static{o(this,"VirtioInputBackend")}mem;queues=new Map;pending=[];onKick(e){e===Sp?(this.dbg(`onKick eventq (guest refilled buffers; pending=${this.pending.length})`),this.pump()):e===kp&&this.drainStatus()}injectEvent(e,n,s){this.pending.push({type:e&65535,code:n&65535,value:s|0}),this.pump()}getQueue(e){let n=this.queues.get(e);if(n&&n.ready)return n;let s=gr(this.mem,this.opts.windowBase,e);return!s.ready||s.num===0?null:(n=new zs(this.mem,s),this.queues.set(e,n),n)}dbg(e){this.opts.onDebug?.(e)}pump(){let e=this.getQueue(Sp);if(!e){this.dbg(`inject: eventq not ready (${this.pending.length} pending)`);return}let n=0;for(;this.pending.length>0;){let s=e.takeAvail();if(!s)break;let r=s.writable[0];if(!r||r.len>>0,!0),e.complete(s.head,Xp),n++}n>0&&(this.dbg(`inject: filled ${n} eventq buffer(s)`),this.raiseInterrupt())}dispose(){}drainStatus(){let e=this.getQueue(kp);if(!e)return;let n=0;for(;;){let s=e.takeAvail();if(!s)break;e.complete(s.head,0),n++}n>0&&this.raiseInterrupt()}raiseInterrupt(){let e=this.mem.i32,n=this.opts.windowBase+96;if(Atomics.or(e,n>>2,1),this.opts.suppressIrq)return;let s=1<<(this.opts.irqBit??1),r=Atomics.or(e,this.opts.irqPendingOffset>>2,s);Atomics.add(e,this.opts.schedWakeupOffset>>2,1);let i=Atomics.notify(e,this.opts.schedWakeupOffset>>2,1);this.dbg(`raiseInterrupt: pending ${r.toString(2)}|=${s} woke=${i} sched=${Atomics.load(e,this.opts.schedWakeupOffset>>2)}`)}};var yI=[10,0,2,2],ZI=[82,85,10,0,2,2],gI=[10,0,2,3],II=[82,85,10,0,2,3],Rp="/etc/brintos/net-key",Pc=512,Ac=3128,Wl=1400,aa=64240,GI=14,Oc=0,Qc=Wl,WI=0,Dc=1,Jp=2,Up=3,Mp=4,wI=1024*1024,Gl=64*1024,Vp=8*1024*1024,SI=1024*1024,xp=256*1024,Bp=32,Tp=32*1024*1024,Yp=new Set(["connection","proxy-connection","keep-alive","te","trailer","transfer-encoding","upgrade","proxy-authorization","proxy-authenticate"]),la=class{constructor(e){this.opts=e}opts;static{o(this,"StubNaasUplink")}count=0;canRelay=!1;seen=[];open(e){this.count++,this.seen.length<64&&this.seen.push(e),this.opts.onEvent(`NaaS-FORWARD-REFUSED: ${e.proto} ${e.host}:${e.port} reached the forward boundary but no egress relay is enabled (turn on VPN in the Network tab, and check your plan); REFUSED. forward-count=${this.count}`);let n=o(()=>{},"closeCb");return queueMicrotask(()=>n(1,"network relay not enabled (enable VPN / upgrade plan)")),{send:o(()=>!1,"send"),onData:o(()=>{},"onData"),onClose:o(s=>{n=s},"onClose"),onWritable:o(()=>{},"onWritable"),ack:o(()=>{},"ack"),close:o(()=>{},"close")}}};function kI(){return{buf:[],bufLen:0,phase:"head",req:null,respActive:!1,activeHeld:!1,respHeadWritten:!1,respReader:null,respChunked:!1,respBytesExpected:-1,respBytesSent:0,reading:!1,closing:!1,guestFin:!1,pendingRec:null,requests:0}}o(kI,"newProxyState");var da=class{constructor(e){this.opts=e;if(this.tcpOpt={wscale:e.tcpOptions?.wscale??!1,mss:e.tcpOptions?.mss??!0,sackOk:e.tcpOptions?.sackOk??!1},e.packetUplink&&this.attachPacketUplink(e.packetUplink,"this machine booted with it"),this.gateway=e.gateway,this.gateway){for(let r of this.gateway.origins){let i=zc(r);if(i===null)throw new Error(`NetShim gateway: malformed allowlist origin "${r}"`);this.gatewayOrigins.add(i)}let s=this.gateway.appOrigin??this.gateway.checkout?.appOrigin;if(s!==void 0){let r=zc(s);if(r===null)throw new Error(`NetShim gateway: malformed appOrigin "${s}"`);this.gatewayAppOrigin=r}if(this.gateway.checkout){let r=zc(this.gateway.checkout.appOrigin);if(r===null)throw new Error(`NetShim gateway: malformed checkout appOrigin "${this.gateway.checkout.appOrigin}"`);if(this.gatewayAppOrigin!==r)throw new Error(`NetShim gateway: checkout appOrigin "${r}" disagrees with appOrigin "${this.gatewayAppOrigin}"`)}if(this.gateway.readOnly&&this.gatewayAppOrigin===null&&this.opts.info("GATEWAY: read-only with NO appOrigin \u2014 this gateway cannot recognise its own fs API, so brintos-fs blob reads (POST /fs/blobs/presign, presign-batch, batch-get) will be refused. This door is for a guest that reaches the fs API for itself; the ROOT does not come through it any more. Supply gateway.appOrigin."),this.gateway.appOriginDoorOpens!==void 0){if(typeof this.gateway.appOriginDoorOpens!="function")throw new Error(`NetShim gateway: appOriginDoorOpens is ${typeof this.gateway.appOriginDoorOpens}, not a function. It is DOOR 1's route table (frame/machine/fsapi-capability.ts, fsApiRouteOf) injected as a predicate; pass a (pathname) => boolean or omit it.`);if(this.gatewayAppOrigin===null)throw new Error("NetShim gateway: appOriginDoorOpens was supplied with no appOrigin (and no checkout.appOrigin), so the filesystem-API door could never be consulted \u2014 every app-origin /fs request would be refused 403 origin-not-allowlisted by the allowlist gate instead. Supply gateway.appOrigin, or omit the door.");this.appOriginDoorOpens=this.gateway.appOriginDoorOpens}}this.gwIp=Uint8Array.from(e.gatewayIp??yI),this.gwMac=Uint8Array.from(e.gatewayMac??ZI),this.dnsIp=Uint8Array.from(e.dnsIp??gI),this.dnsMac=Uint8Array.from(e.dnsMac??II),this.httpPortMapping=e.httpPortMapping===!0,this.httpPortMapping&&this.opts.info("NET: guest TCP :80 is mapped onto this host's own fetch (httpPortMapping). No origin allowlist applies to that path; the embedder asked for it.");let n=globalThis.fetch;this.fetchImpl=e.fetchImpl??(typeof n=="function"?n.bind(globalThis):(()=>{throw new Error("NetShim: no fetch implementation available (pass fetchImpl)")}))}opts;static{o(this,"NetShim")}gwIp;gwMac;dnsIp;dnsMac;fetchImpl;httpPortMapping;flows=new Map;udpFlows=new Map;nameToIp=new Map;ipToName=new Map;dnsNext=1;keyOk;tcpOpt;l3;guestMacL3=null;lastGuestMac=null;gateway;gatewayOrigins=new Set;gatewayAppOrigin=null;appOriginDoorOpens=null;doorRouteNoted=!1;gatewayActive=0;gatewayBufferedBytes=0;gatewayRequests=0;gatewayRefusals=0;gwActive=new Map;gwRing=[];gwRingHead=0;gwDropped=0;gwNextId=1;gwTotalDown=0;gwTotalUp=0;gatewayTelemetry(){let e=[];for(let n of this.gwActive.values())e.push({...n});e.sort((n,s)=>n.startedMs-s.startedMs);for(let n=0;n{this.l3===e&&this.injectIpPacket(s)}),this.guestMacL3===null&&this.lastGuestMac!==null&&(this.guestMacL3=Uint8Array.from(this.lastGuestMac)),this.opts.info(`NET: full-access packet forwarding is ON (${n}). Every IPv4 packet not addressed to the local gateway now leaves over the relay, from the next frame. eth0 needed no reconfiguration: its address, route and resolver were set at boot and are unchanged`+(this.guestMacL3===null?". The guest MAC is not known yet, so inbound packets are dropped until it transmits.":".")+" Names resolved BEFORE this point may still be held by a running process; those answers were this shim's own and do not exist on the far side of the relay."))}detachPacketUplink(e){this.l3&&(this.l3=void 0,this.guestMacL3=null,this.opts.info(`NET: full-access packet forwarding is OFF (${e}). eth0 stays up with the same address and route \u2014 what changed is that packets it cannot serve locally are refused here, loudly and by name, instead of leaving over the relay.`))}handleGuestFrame(e){if(e.length<14){this.opts.info(`FWD/drop: runt frame (${e.length}B)`);return}let n=e.subarray(6,12);if((this.lastGuestMac===null||!RI(this.lastGuestMac,n))&&(this.lastGuestMac=Uint8Array.from(n)),this.l3){this.handleL3(e);return}let s=e[12]<<8|e[13];if(s===2054){this.handleArp(e);return}if(s===2048){this.handleIpv4(e);return}this.refuseUnsupported(`l3:0x${s.toString(16)}`,"raw")}unsupportedRefuseCount=0;refuseUnsupported(e,n){this.unsupportedRefuseCount++,this.opts.info(`FWD-REFUSE: ${e} -> ${n}: the egress relay carries TCP and UDP, not raw ICMP/L3 (e.g. ping) \u2014 use a TCP or UDP connection instead. REFUSED. unsupported-refuse-count=${this.unsupportedRefuseCount}`)}handleL3(e){this.guestMacL3=this.lastGuestMac;let n=e[12]<<8|e[13];if(n===2054){this.handleArp(e);return}if(n!==2048||e.length<34)return;let s=14,r=e.subarray(s+16,s+20);if($r(r,this.gwIp)){this.handleIpv4(e);return}this.l3.send(e.subarray(14))}injectIpPacket(e){if(!this.guestMacL3||e.length<20)return;let n=new Uint8Array(14+e.length);n.set(this.guestMacL3,0),n.set(this.gwMac,6),n[12]=8,n[13]=0,n.set(e,14),this.opts.transmit(n)}handleArp(e){if(e.length<42){this.opts.info(`FWD/drop: short ARP (${e.length}B)`);return}if((e[20]<<8|e[21])!==1)return;let r=e.subarray(38,42),i=null,l=null;if($r(r,this.gwIp)?(i=this.gwMac,l=this.gwIp):$r(r,this.dnsIp)&&(i=this.dnsMac,l=this.dnsIp),!i||!l)return;let d=new Uint8Array(42);d.set(e.subarray(22,28),0),d.set(i,6),d[12]=8,d[13]=6,d.set(e.subarray(14,20),14),d[20]=0,d[21]=2,d.set(i,22),d.set(l,28),d.set(e.subarray(22,28),32),d.set(e.subarray(28,32),38),this.opts.info(`ARP: answered who-has ${ps(l)} (is-at ${VI(i)})`),this.opts.transmit(d)}handleIpv4(e){if(e.length<34||e[14]>>4!==4){this.opts.info("FWD/drop: malformed IPv4");return}let s=(e[14]&15)*4,r=e[23],i=e.subarray(30,34);if(r===6){this.handleTcp(e,14,s);return}if(r===17){let l=14+s,d=e[l+2]<<8|e[l+3];$r(i,this.dnsIp)&&d===53?this.handleDns(e,14,s):$r(i,this.gwIp)?this.udpEchoToGateway(e,14,s):this.handleUdpRelay(e,14,s);return}if(r===1){$r(i,this.gwIp)?this.icmpEchoToGateway(e,14,s):this.refuseUnsupported("icmp",ps(i));return}this.refuseUnsupported(`ip-proto:${r}`,ps(i))}icmpEchoToGateway(e,n,s){let r=n+s;if(e.length>8,i[r+3]=l&255,this.opts.info(`ICMP: echoed ping (${e.length-r-8}B payload)`),this.opts.transmit(i)}udpEchoToGateway(e,n,s){let r=n+s;if(e.lengthe.length)return;c.push(String.fromCharCode(...Array.from(e.subarray(f,f+b)))),a+=1+b}if(a+4>e.length)return;let h=e[a]<<8|e[a+1],p=c.join("."),m=a+4;if(h!==1){this.opts.info(`DNS: ${p} qtype=${h} -> empty answer`),this.sendDnsResponse(e,n,s,i,l,m,null);return}let y=this.fabricateIp(p);this.opts.info(`DNS: ${p} A -> ${ps(y)} (fabricated)`),this.sendDnsResponse(e,n,s,i,l,m,y)}fabricateIp(e){let n=this.nameToIp.get(e);if(n)return n;let s=(this.dnsNext++-1)%253+1,r=Uint8Array.from([198,51,100,s]);return this.nameToIp.set(e,r),this.ipToName.set(ps(r),e),r}sendDnsResponse(e,n,s,r,i,l,d){let a=e.subarray(r+12,l),c=d?1:0,h=d?16:0,p=12+a.length+h,m=new Uint8Array(p);if(m[0]=i>>8,m[1]=i&255,m[2]=129,m[3]=128,m[4]=0,m[5]=1,m[6]=0,m[7]=c,m.set(a,12),d){let I=12+a.length;m[I++]=192,m[I++]=12,m[I++]=0,m[I++]=1,m[I++]=0,m[I++]=1,m[I++]=0,m[I++]=0,m[I++]=0,m[I++]=60,m[I++]=0,m[I++]=4,m.set(d,I)}let y=n+s,b=e[y]<<8|e[y+1],f=this.buildUdp(e.subarray(6,12),this.dnsMac,this.dnsIp,e.subarray(n+12,n+16),53,b,m);this.opts.transmit(f)}handleUdpRelay(e,n,s){let r=n+s;if(e.length ${b}:${l} via NaaS uplink`);let f={key:m,conn:null,guestMac:Uint8Array.from(p),clientIp:Uint8Array.from(c),serverIp:Uint8Array.from(h),clientPort:i,serverPort:l,idle:null};this.udpFlows.set(m,f),y=f;let I=this.opts.naas.open({proto:"udp",host:b,port:l});f.conn=I,I.onData(R=>{if(!this.udpFlows.has(m))return;let X=this.buildUdp(f.guestMac,this.gwMac,f.serverIp,f.clientIp,f.serverPort,f.clientPort,R);this.opts.transmit(X),this.armUdpIdle(f)}),I.onClose((R,X)=>{this.opts.info(`RELAY: close udp ${m} code=${R} ${X}`),this.closeUdp(f)}),I.onWritable(()=>{})}y.conn?.send(Uint8Array.from(a)),this.armUdpIdle(y)}armUdpIdle(e){e.idle&&clearTimeout(e.idle),e.idle=setTimeout(()=>{this.opts.info(`RELAY: udp idle ${e.key}`),this.closeUdp(e)},6e4)}closeUdp(e){e.idle&&clearTimeout(e.idle),e.conn?.close("udp-close"),e.conn=null,this.udpFlows.delete(e.key)}handleTcp(e,n,s){let r=n+s;if(e.length>4)*4;if(c<20||r+c>e.length){this.opts.info(`FWD/drop: bad TCP data offset (${c}B, frame ${e.length}B)`);return}let h=e[r+13],p=e[r+14]<<8|e[r+15],m=r+c,y=e.subarray(m,e.length),b=e.subarray(n+12,n+16),f=e.subarray(n+16,n+20),I=e.subarray(6,12),R=1,X=2,F=4,N=16,K=`${ps(b)}:${i}-${ps(f)}:${l}`;if(Np()&&this.opts.info(`TCPTRACE rx ${K} flags=0x${h.toString(16)} seq=${d} ack=${a} wnd=${p} len=${y.length}`),h&F){let U=this.flows.get(K);U&&(U.closed=!0),U?.conn&&U.conn.close("guest-rst"),U?.proxy&&this.proxyAbort(U,"guest-rst"),this.flows.delete(K);return}let k=this.flows.get(K);if(h&X&&!(h&N)){let U=this.flows.get(K);U&&(U.closed=!0,U.conn&&(U.conn.close("syn-reuse"),U.conn=null),U.proxy&&this.proxyAbort(U,"syn-reuse"),this.flows.delete(K),this.opts.info(`TCP: SYN reused live 4-tuple ${K} \u2014 tore down stale flow`));let M=this.gateway?.port??Ac,H=this.gateway&&l===M&&$r(f,this.gwIp)?"proxy":this.httpPortMapping&&l===80?"http":"relay",Ge=Math.floor(Math.random()*2147483647)>>>0||4096,C=xI(e,r+20,r+c);C.malformed&&this.opts.info(`TCP: malformed option area on SYN ${K} \u2014 parsed prefix only`);let Ie=this.tcpOpt.wscale&&C.wscale!==null,B=Ie?C.wscale:0,ae=BI(this.tcpOpt,Ie?B:null);k={key:K,mode:H,guestMac:Uint8Array.from(I),clientIp:Uint8Array.from(b),serverIp:Uint8Array.from(f),clientPort:i,serverPort:l,rcvNxt:d+1>>>0,sndNxt:Ge,sndUna:Ge,established:!1,reqChunks:[],reqLen:0,requestDone:!1,fetchStarted:!1,resp:null,respStartSeq:0,finSent:!1,guestWnd:p||aa,sndWscale:B,rcvWscale:Ie?Oc:0,closed:!1,conn:null,outChunks:[],outLen:0,relayClosed:!1,advWnd:aa,proxy:null},H==="proxy"&&(k.proxy=kI()),this.flows.set(K,k),this.sendTcp(k,X|N,null,ae),k.sndNxt=Ge+1>>>0,k.sndUna=k.sndNxt,k.respStartSeq=k.sndNxt,this.opts.info(`TCP: SYN ${K} -> SYN-ACK (${H})${Ie?` ws=${B}/${Oc}`:" ws=off"}${this.tcpOpt.mss?` mss=${Qc}`:""}`),!this.gateway&&l===Ac&&$r(f,this.gwIp)&&this.opts.info(`GATEWAY-UNCONFIGURED: the guest dialled ${ps(this.gwIp)}:${Ac} (the egress gateway port) but this machine booted with no virtioNet.gateway \u2014 the flow falls to the relay path and will be refused.`),H==="relay"&&this.openRelay(k);return}k&&(k.guestWnd=p<>>0,h&N&&(TI(a,k.sndUna,k.sndNxt)&&(k.sndUna=a),k.established||(k.established=!0)),y.length>0&&(d===k.rcvNxt?(k.rcvNxt=k.rcvNxt+y.length>>>0,k.mode==="http"?(k.reqChunks.push(Uint8Array.from(y)),k.reqLen+=y.length,this.sendTcp(k,N,null),this.maybeCompleteRequest(k)):k.mode==="proxy"?(this.proxyData(k,Uint8Array.from(y)),this.sendTcp(k,N,null)):(this.relayGuestData(k,Uint8Array.from(y)),this.sendTcp(k,N,null))):this.sendTcp(k,N,null)),h&R&&(k.rcvNxt=k.rcvNxt+1>>>0,this.sendTcp(k,N,null),k.mode==="relay"&&k.conn&&(k.conn.close("guest-fin"),k.conn=null),k.mode==="proxy"&&this.proxyGuestFin(k),k.finSent&&this.flows.delete(K)),k.mode==="relay"?this.pumpRelay(k):k.mode==="proxy"?this.pumpProxy(k):k.resp&&this.pumpResponse(k))}maybeCompleteRequest(e){if(e.requestDone||e.fetchStarted)return;let n=wl(e.reqChunks,e.reqLen),s=_p(n);if(s<0)return;let r=Sl(n.subarray(0,s)),i=YI(r),l=s,d=n.length-l;i>0&&d>>0,r=e.sndNxt-e.sndUna>>>0,i=n-s;if(i<=0)break;let l=Kc(e,r);if(l<=0)break;let d=Math.min(Wl,i,l),a=e.resp.subarray(s,s+d);this.sendTcp(e,24,a),e.sndNxt=e.sndNxt+d>>>0}this.maybeFin(e)}maybeFin(e){if(!e.resp||e.finSent||e.closed)return;let n=e.resp.length,s=e.sndNxt-e.respStartSeq>>>0>=n,r=e.sndUna-e.respStartSeq>>>0;s&&r>=n&&(this.sendTcp(e,17,null),e.sndNxt=e.sndNxt+1>>>0,e.finSent=!0,this.opts.info(`TCP: response fully ACKed, FIN ${e.key}`))}rst(e){this.sendTcp(e,4,null),e.closed=!0,e.conn&&(e.conn.close("rst"),e.conn=null),e.proxy&&this.proxyAbort(e,"rst"),this.flows.delete(e.key)}openRelay(e){let n=this.ipToName.get(ps(e.serverIp))??ps(e.serverIp),s={proto:"tcp",host:n,port:e.serverPort};this.opts.info(`RELAY: open ${e.key} -> ${n}:${e.serverPort} via NaaS uplink`);let r=this.opts.naas.open(s);e.conn=r,r.onData(i=>{e.closed||i.length===0||(e.outChunks.push(i),e.outLen+=i.length,this.pumpRelay(e))}),r.onWritable(()=>{e.closed||e.advWnd!==aa&&(e.advWnd=aa,this.sendTcp(e,16,null))}),r.onClose((i,l)=>{if(e.closed)return;e.relayClosed=!0,e.conn=null,this.opts.info(`RELAY: close ${e.key} (${n}:${e.serverPort}) code=${i} ${l}`);let d=e.sndNxt-e.respStartSeq>>>0===0;if(i!==0&&d&&e.outLen===0){this.rst(e);return}e.outLen>0?this.pumpRelay(e):this.maybeFinRelay(e)})}relayGuestData(e,n){if(!e.conn)return;e.conn.send(n)||(e.advWnd=0)}pumpRelay(e){if(!e.closed){for(;!(e.outLen<=0);){let n=e.sndNxt-e.sndUna>>>0,s=Kc(e,n);if(s<=0)break;let r=Math.min(Wl,e.outLen,s),i=this.takeFromQueue(e,r);this.sendTcp(e,24,i),e.sndNxt=e.sndNxt+r>>>0,e.conn?.ack(r)}this.maybeFinRelay(e)}}takeFromQueue(e,n){let s=new Uint8Array(n),r=0;for(;r0||(this.sendTcp(e,17,null),e.sndNxt=e.sndNxt+1>>>0,e.finSent=!0,this.opts.info(`RELAY: drained, FIN ${e.key}`)))}proxyData(e,n){let s=e.proxy;s.closing||(s.buf.push(n),s.bufLen+=n.length,this.proxyDrive(e),this.proxyRecomputeWindow(e,!1))}proxyDrive(e){let n=e.proxy;for(;;){if(e.closed||n.closing)return;if(n.phase==="head"){if(n.respActive||n.bufLen===0)return;let s=wl(n.buf,n.bufLen),r=_p(s);if(r<0){n.bufLen>Gl&&this.proxySynth(e,431,"head-too-large",`request head exceeds ${Gl} bytes`);return}n.buf=r=(r.maxConcurrent??Bp)){this.noteRootFsRefusal(a,p,"too-many-requests"),this.proxySynth(e,503,"too-many-requests",`concurrent proxied fetch ceiling reached (${this.gatewayActive})`,{retryAfter:1});return}let f=new Set(Yp);f.add("host"),f.add("expect"),f.add("content-length"),f.add("x-brintos-machine-write"),f.add("x-brintos-checkout-token"),f.add("x-brintos-fetch-id");let I=null,R=!1,X=h===0,F=!1,N={},K=new Map;for(let H=1;H0?"clen":"none";if(b&&!(k==="clen"&&I<=Vp)){this.noteRootFsRefusal(a,p,"read-only-op-unprovable"),this.proxySynth(e,403,"read-only-op-unprovable",`${a} ${p.pathname} refused: this machine session holds no machine-write checkout, so this route is allowed only for op="get", and a ${R?"chunked":I===null||I<=0?"bodyless":"oversized"} request body cannot be inspected for it`);return}let U={method:a,url:p,rec:d,headers:N,bodyMode:k,bodyRemaining:I??0,chunk:{stage:"size",remaining:0,line:""},bodyChunks:null,bodyChunksLen:0,bufferedCharge:0,bodyCtrl:null,bodyDone:!1,opProof:b,abort:new AbortController};if(s.req=U,s.closing=s.closing||X,F&&this.proxyEnqueue(e,zi(`HTTP/1.1 100 Continue\r \r `)),U.bodyMode==="none"){U.bodyDone=!0,this.proxyDispatch(e,null,!1);return}if(s.phase="body",U.bodyMode==="clen"&&U.bodyRemaining<=Vp){if(this.gatewayBufferedBytes+U.bodyRemaining>Tp){this.proxySynth(e,503,"too-much-buffered",`buffered request-body budget exhausted (${this.gatewayBufferedBytes}+${U.bodyRemaining} > ${Tp} bytes)`,{retryAfter:1});return}this.gatewayBufferedBytes+=U.bodyRemaining,U.bufferedCharge=U.bodyRemaining,U.bodyChunks=[];return}let M=new ReadableStream({start:o(H=>{U.bodyCtrl=H},"start"),pull:o(()=>{this.proxyRecomputeWindow(e,!0)},"pull")},{highWaterMark:SI,size:o(H=>H.byteLength,"size")});this.proxyDispatch(e,M,!0)}proxyConsumeBody(e){let n=e.proxy,s=n.req;if(!s)return n.buf=[],n.bufLen=0,!1;if(s.bodyMode==="clen"){if(s.bodyRemaining>0){if(n.bufLen===0)return!1;let r=Math.min(n.bufLen,s.bodyRemaining);this.proxyRouteBody(e,kl(n,r)),s.bodyRemaining-=r}return s.bodyRemaining>0?!1:(this.proxyBodyEnd(e),!0)}for(;;){let r=s.chunk;if(r.stage==="size"||r.stage==="trailer"){let i=EI(n);if(i===null)return n.bufLen>Gl&&this.proxyFrameError(e,"chunk line exceeds sanity bound"),!1;if(r.stage==="size"){let l=i.indexOf(";"),d=(l>=0?i.slice(0,l):i).trim();if(!/^[0-9a-fA-F]+$/.test(d))return this.proxyFrameError(e,`malformed chunk size "${d.slice(0,32)}"`),!1;let a=parseInt(d,16);if(a===0){r.stage="trailer";continue}r.remaining=a,r.stage="data";continue}if(i==="")return this.proxyBodyEnd(e),!0;continue}if(r.stage==="data"){if(n.bufLen===0)return!1;let i=Math.min(n.bufLen,r.remaining);if(this.proxyRouteBody(e,kl(n,i)),r.remaining-=i,r.remaining>0)return!1;r.stage="data-end"}if(r.stage==="data-end"){if(n.bufLen<2)return!1;let i=kl(n,2);if(i[0]!==13||i[1]!==10)return this.proxyFrameError(e,"missing CRLF after chunk data"),!1;r.stage="size"}}}proxyRouteBody(e,n){let s=e.proxy.req;if(s.rec.up+=n.length,this.gwTotalUp+=n.length,s.bodyChunks){s.bodyChunks.push(n),s.bodyChunksLen+=n.length;return}if(s.bodyCtrl)try{s.bodyCtrl.enqueue(n)}catch{}}proxyBodyEnd(e){let n=e.proxy,s=n.req;if(s.bodyDone=!0,n.phase="head",s.bodyChunks){let r=wl(s.bodyChunks,s.bodyChunksLen);if(s.bodyChunks=null,this.proxyRefundBuffered(s),s.opProof&&!HI(r)){this.proxySynth(e,403,"read-only",`${s.method} ${s.url.pathname} refused: this machine session holds no machine-write checkout, so this route is allowed only for op="get"`);return}this.proxyDispatch(e,r.length>0?r:null,!1)}else if(s.bodyCtrl){try{s.bodyCtrl.close()}catch{}s.bodyCtrl=null}}proxyFrameError(e,n){this.opts.info(`GATEWAY: request framing error (${n}) \u2014 RST ${e.key}`),this.rst(e)}proxyDispatch(e,n,s){let r=e.proxy;r.respActive=!0,r.activeHeld=!0,this.gatewayActive++,this.proxyFetch(e,r.req,n,s)}async proxyFetch(e,n,s,r){let i=e.proxy,l=n.url.href;this.opts.info(`GATEWAY: ${n.method} ${l} (flow ${e.key})`);try{let d=await this.fetchImpl(l,{method:n.method,headers:n.headers,body:s,redirect:"manual",signal:n.abort.signal,...r?{duplex:"half"}:{}}),a=Date.now()-n.rec.startedMs;if(e.closed){this.opts.info(`GATEWAY: ${d.status} for ${n.method} ${l} arrived after ${a} ms but flow ${e.key} is already closed \u2014 the response is dropped`);return}if(this.opts.info(`GATEWAY: ${d.status} ${Xl(d.status)} head for ${n.method} ${l} in ${a} ms (flow ${e.key})`),this.proxyWriteRespHead(e,n,d),n.method==="HEAD"||d.status===204||d.status===304)d.body&&d.body.cancel().catch(()=>{}),this.proxyRespEnd(e);else if(d.body&&typeof d.body.getReader=="function")i.respReader=d.body.getReader(),this.proxyPumpUpstream(e);else{let h=new Uint8Array(await d.arrayBuffer());h.length>0&&this.proxyEnqueueBody(e,h),this.proxyRespEnd(e)}}catch(d){let a=d instanceof Error?d.message:String(d);if(e.closed){this.opts.info(`GATEWAY: ${n.method} ${l} failed after ${Date.now()-n.rec.startedMs} ms (${a}) but flow ${e.key} is already closed \u2014 nothing to report to the guest`);return}i.respHeadWritten?(this.gwEnd(n.rec,"failed","upstream-failed-mid-response"),this.opts.info(`GATEWAY: upstream failed mid-response: ${a} \u2014 RST ${e.key}`),this.rst(e)):(this.opts.info(`GATEWAY: upstream fetch failed: ${a} (${n.method} ${l})`),this.proxyReleaseActive(e),i.respActive=!1,this.proxySynth(e,502,"upstream-fetch-failed",`upstream fetch failed: ${a.slice(0,256)}`))}}proxyWriteRespHead(e,n,s){let r=e.proxy;n.rec.status=s.status,n.rec.headMs=Date.now();let i=vI(s.headers),l=null,d=!1,a=[];for(let[m,y]of i){let b=m.toLowerCase();if(!Yp.has(b)){if(b==="content-length"){/^\d+$/.test(y.trim())&&(l=parseInt(y.trim(),10));continue}if(b==="content-encoding"){d=!0;continue}a.push([m,y])}}d&&(l=null);let c=n.method==="HEAD"||s.status===204||s.status===304,h=s.statusText&&s.statusText.length>0?s.statusText:Xl(s.status),p=`HTTP/1.1 ${s.status} ${h}\r `;for(let[m,y]of a)p+=`${m}: ${y}\r `;c?(n.method==="HEAD"&&l!==null&&(p+=`Content-Length: ${l}\r `),r.respChunked=!1,r.respBytesExpected=0):l!==null?(p+=`Content-Length: ${l}\r `,r.respChunked=!1,r.respBytesExpected=l):(p+=`Transfer-Encoding: chunked\r `,r.respChunked=!0,r.respBytesExpected=-1),p+=`Connection: ${r.closing?"close":"keep-alive"}\r \r `,n.rec.contentLength=l??-1,r.respBytesSent=0,r.respHeadWritten=!0,this.proxyEnqueue(e,zi(p))}async proxyPumpUpstream(e){let n=e.proxy;if(!n.reading){n.reading=!0;try{for(;!e.closed&&n.respReader&&!(!(this.gateway?.redDisableBackpressure===!0)&&e.outLen>=xp);){let r=n.respReader,{value:i,done:l}=await r.read();if(e.closed||n.respReader!==r)break;if(l){n.respReader=null,this.proxyRespEnd(e);break}i&&i.length>0&&this.proxyEnqueueBody(e,i),this.pumpProxy(e)}}catch(s){if(!e.closed){let r=s instanceof Error?s.message:String(s);this.opts.info(`GATEWAY: upstream body read failed (${r}) \u2014 RST ${e.key}`),this.rst(e)}}finally{n.reading=!1}}}proxyEnqueue(e,n){e.outChunks.push(n),e.outLen+=n.length,this.pumpProxy(e)}proxyEnqueueBody(e,n){let s=e.proxy;s.req&&(s.req.rec.down+=n.length),this.gwTotalDown+=n.length,s.respChunked?(e.outChunks.push(zi(n.length.toString(16)+`\r `)),e.outChunks.push(n),e.outChunks.push(zi(`\r `)),e.outLen+=n.length+n.length.toString(16).length+4):(s.respBytesSent+=n.length,e.outChunks.push(n),e.outLen+=n.length),this.pumpProxy(e)}proxyRespEnd(e){let n=e.proxy;n.respChunked?this.proxyEnqueue(e,zi(`0\r \r `)):n.respBytesExpected>=0&&n.respBytesSent!==n.respBytesExpected&&(this.opts.info(`GATEWAY: upstream body ${n.respBytesSent}B != Content-Length ${n.respBytesExpected}B \u2014 closing ${e.key}`),n.closing=!0),this.proxyFinishRequest(e)}proxyFinishRequest(e){let n=e.proxy;if(n.req&&(n.req.rec.state==="pending"&&this.opts.info(`GATEWAY: ${n.req.rec.status} complete for ${n.req.method} ${n.req.url.href} \u2014 ${n.req.rec.down} body byte(s) to the guest in ${Date.now()-n.req.rec.startedMs} ms (flow ${e.key})`),this.gwEnd(n.req.rec,"done")),n.pendingRec=null,n.respActive=!1,n.respHeadWritten=!1,n.respChunked=!1,n.respBytesExpected=-1,n.respBytesSent=0,n.respReader=null,n.req=null,this.proxyReleaseActive(e),this.proxyRecomputeWindow(e,!0),n.closing||n.guestFin){this.maybeFinProxy(e);return}this.proxyDrive(e)}rootFsRefusalNoted=!1;noteRootFsRefusal(e,n,s){this.rootFsRefusalNoted||this.gatewayAppOrigin===null||this.gatewayAppOrigin!==n.origin||$c(n.pathname)&&(this.rootFsRefusalNoted=!0,this.opts.info(`GATEWAY: REFUSED A ROOT-FILESYSTEM REQUEST \u2014 ${e} ${n.pathname} (${s}). This machine's root is served by brintos-fs over THIS gateway, so the guest will report this as an I/O error or a mount timeout, not as a network failure. The cause is here, not in the filesystem. (Further refusals are logged individually above.)`))}proxySynth(e,n,s,r,i){let l=e.proxy;this.gatewayRefusals++;let d=l.req?.rec??l.pendingRec;d&&(d.status=n,this.gwEnd(d,"refused",s)),l.pendingRec=null;let a=`${r} `,c=`HTTP/1.1 ${n} ${Xl(n)}\r X-Brintos-Gateway-Error: ${s}\r `;i?.blocked&&(c+=`X-Brintos-Gateway-Blocked: ${i.blocked}\r `),i?.retryAfter!==void 0&&(c+=`Retry-After: ${i.retryAfter}\r `),c+=`Content-Type: text/plain\r Content-Length: ${a.length}\r Connection: close\r \r `,this.opts.info(`GATEWAY-REFUSE: ${n} ${s}: ${r} (flow ${e.key})`),l.closing=!0,l.req=null,l.phase="head",this.proxyEnqueue(e,zi(c+a)),this.maybeFinProxy(e)}pumpProxy(e){if(e.closed||!e.proxy)return;for(;!(e.outLen<=0);){let s=e.sndNxt-e.sndUna>>>0,r=Kc(e,s);if(r<=0)break;let i=Math.min(Wl,e.outLen,r),l=this.takeFromQueue(e,i);this.sendTcp(e,24,l),e.sndNxt=e.sndNxt+i>>>0}e.proxy.respReader&&e.outLen0||(this.sendTcp(e,17,null),e.sndNxt=e.sndNxt+1>>>0,e.finSent=!0,this.opts.info(`GATEWAY: connection closed ${e.key} (${n.requests} request(s))`),n.guestFin&&this.flows.delete(e.key)))}proxyGuestFin(e){let n=e.proxy;n.guestFin=!0;let s=n.req;if(s&&!s.bodyDone){if(this.opts.info(`GATEWAY: guest closed before its request body completed \u2014 aborting upstream (${e.key})`),s.bodyCtrl){try{s.bodyCtrl.error(new Error("guest closed the connection early"))}catch{}s.bodyCtrl=null}this.proxyRefundBuffered(s),s.abort.abort(),this.gwEnd(s.rec,"failed","guest-closed-mid-request"),n.pendingRec=null}this.maybeFinProxy(e)}proxyAbort(e,n){let s=e.proxy;if(s){if(s.req){if(s.req.bodyCtrl){try{s.req.bodyCtrl.error(new Error(`connection aborted (${n})`))}catch{}s.req.bodyCtrl=null}this.proxyRefundBuffered(s.req),s.req.abort.abort()}s.respReader&&(s.respReader.cancel().catch(()=>{}),s.respReader=null),this.gwEnd(s.req?.rec??s.pendingRec,"failed",`aborted:${n}`),s.pendingRec=null,this.proxyReleaseActive(e)}}proxyReleaseActive(e){let n=e.proxy;n.activeHeld&&(n.activeHeld=!1,this.gatewayActive--)}proxyRefundBuffered(e){e.bufferedCharge>0&&(this.gatewayBufferedBytes-=e.bufferedCharge,e.bufferedCharge=0)}proxyRecomputeWindow(e,n){let s=e.proxy;if(!s||e.closed)return;let r=s.req?.bodyCtrl??null,i=r!==null&&r.desiredSize!==null&&r.desiredSize<=0,l=s.bufLen>Gl,d=i||l?0:aa;if(d!==e.advWnd){let a=e.advWnd===0&&d>0;e.advWnd=d,a&&n&&this.sendTcp(e,16,null)}}sendTcp(e,n,s,r){let i=s??Cp,l=r&&r.length?r:Cp,d=20+l.length+i.length,a=new Uint8Array(34+d);a.set(e.guestMac,0),a.set(this.gwMac,6),a[12]=8,a[13]=0;let c=14;a[c]=69,a[c+1]=0,fs(a,c+2,20+d),fs(a,c+4,0),fs(a,c+6,16384),a[c+8]=64,a[c+9]=6,a.set(e.serverIp,c+12),a.set(e.clientIp,c+16);let h=jc(a.subarray(c,c+20));fs(a,c+10,h);let p=c+20;fs(a,p,e.serverPort),fs(a,p+2,e.clientPort),Ep(a,p+4,e.sndNxt),Ep(a,p+8,e.rcvNxt),a[p+12]=5+l.length/4<<4&240,a[p+13]=n,fs(a,p+14,n&2?Math.min(e.advWnd,65535):e.advWnd>>>e.rcvWscale&65535),fs(a,p+16,0),fs(a,p+18,0),l.length&&a.set(l,p+20),i.length&&a.set(i,p+20+l.length);let m=JI(e.serverIp,e.clientIp,a.subarray(p,p+d));fs(a,p+16,m),Np()&&this.opts.info(`TCPTRACE tx ${e.key} flags=0x${n.toString(16)} seq=${e.sndNxt} ack=${e.rcvNxt} len=${i.length}`),this.opts.transmit(a)}buildUdp(e,n,s,r,i,l,d){let a=8+d.length,c=new Uint8Array(34+a);c.set(e,0),c.set(n,6),c[12]=8,c[13]=0;let h=14;c[h]=69,fs(c,h+2,20+a),fs(c,h+6,16384),c[h+8]=64,c[h+9]=17,c.set(s,h+12),c.set(r,h+16),fs(c,h+10,jc(c.subarray(h,h+20)));let p=h+20;return fs(c,p,i),fs(c,p+2,l),fs(c,p+4,a),c.set(d,p+8),fs(c,p+6,UI(s,r,c.subarray(p,p+a))),c}ensureKey(){return this.keyOk===void 0&&(this.keyOk=this.readAndValidateKey()),this.keyOk}async readAndValidateKey(){let e=this.opts.fs,n=this.opts.keyPath??Rp;if(!e)return this.opts.info(`KEY-GATE: no FsView threaded into the net backend \u2014 cannot read ${n}; refusing`),!1;let s;try{s=await Pp(e,n)}catch(i){return this.opts.info(`KEY-GATE: error reading ${n}: ${i instanceof Error?i.message:String(i)}; refusing`),!1}if(!s||s.length===0)return this.opts.info(`KEY-GATE: ${n} absent/empty; refusing`),!1;let r=Sl(s).trim();return Lp(r)?(this.opts.info(`KEY-GATE: ${n} present + valid \u2014 fetch mapping ENABLED`),!0):(this.opts.info(`KEY-GATE: ${n} malformed (expected bnk1.); refusing`),!1)}};function Lp(t){let e=/^bnk1\.([A-Za-z0-9_-]+)$/.exec(t);if(!e)return!1;let n=e[1],s=XI(n);return s!==null&&s.length===32}o(Lp,"validateNetKey");function XI(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e.length%4===0?e:e+"=".repeat(4-e.length%4);try{if(typeof atob=="function"){let r=atob(n),i=new Uint8Array(r.length);for(let l=0;lc.length>0),s=1,r=null;for(let c of n){let h=await t.lookup(s,c);if(!h)return null;r=h,s=h.ino}if(!r)return null;let i=r.size,l=[],d=0,a=Math.min(i,1<<20);for(;de.toString(16).padStart(2,"0")).join(":")}o(VI,"fmtMac");function Hp(t){for(let e=0;e<6;e++){let n=t[e];t[e]=t[6+e],t[6+e]=n}}o(Hp,"swapEth");function vp(t,e){for(let n=0;n<4;n++){let s=t[e+12+n];t[e+12+n]=t[e+16+n],t[e+16+n]=s}}o(vp,"swapIp");function Fp(t,e){return(t[e]<<24|t[e+1]<<16|t[e+2]<<8|t[e+3])>>>0}o(Fp,"readU32");function xI(t,e,n){let s={wscale:null,mss:null,sackOk:!1,malformed:!1},r=e;for(;r=n){s.malformed=!0;break}let l=t[r+1];if(l<2||r+l>n){s.malformed=!0;break}switch(i){case Jp:l===4&&s.mss===null&&(s.mss=t[r+2]<<8|t[r+3]);break;case Up:l===3&&s.wscale===null&&(s.wscale=Math.min(t[r+2],GI));break;case Mp:l===2&&(s.sackOk=!0);break;default:break}r+=l}return s}o(xI,"parseTcpOptions");function BI(t,e){let n=[];for(t.mss&&n.push(Jp,4,Qc>>8&255,Qc&255),t.sackOk&&n.push(Mp,2),t.wscale&&e!==null&&n.push(Dc,Up,3,Oc);n.length%4!==0;)n.push(Dc);return Uint8Array.from(n)}o(BI,"buildSynAckOptions");function fs(t,e,n){t[e]=n>>8&255,t[e+1]=n&255}o(fs,"writeU16");function Ep(t,e,n){t[e]=n>>>24&255,t[e+1]=n>>>16&255,t[e+2]=n>>>8&255,t[e+3]=n&255}o(Ep,"writeU32");function wl(t,e){let n=new Uint8Array(e),s=0;for(let r of t)n.set(r,s),s+=r.length;return n}o(wl,"concat");function Sl(t){let e="";for(let n=0;n>>0,r=n-e>>>0;return s>0&&s<=r}o(TI,"seqInWindow");function _p(t){for(let e=3;ee.push([r,s]));else for(let[s,r]of t)e.push([s,r]);return e}o(vI,"headerEntries");function kl(t,e){let n=new Uint8Array(e),s=0;for(;s0;){let r=t.buf[0],i=Math.min(r.length,e-s);n.set(r.subarray(0,i),s),s+=i,i===r.length?t.buf.shift():t.buf[0]=r.subarray(i)}return t.bufLen-=s,n}o(kl,"takeProxyBytes");function FI(t){let e=0,n=!1;for(let s of t.buf){for(let r=0;ri.push([h,c]));else for(let[c,h]of t.headers)i.push([c,h]);for(let[c,h]of i){let p=c.toLowerCase();p==="content-length"||p==="transfer-encoding"||p==="connection"||(r+=`${c}: ${h}\r `)}r+=`Content-Length: ${e.length}\r `,r+=`Connection: close\r `,r+=`\r `;let d=new Uint8Array(r.length);for(let c=0;c65535;)e=(e&65535)+(e>>>16);return~e&65535}o(jc,"inetChecksum");function Ap(t,e,n,s){let r=0;r+=t[0]<<8|t[1],r+=t[2]<<8|t[3],r+=e[0]<<8|e[1],r+=e[2]<<8|e[3],r+=n,r+=s.length;let i=0;for(;i+165535;)r=(r&65535)+(r>>>16);return~r&65535}o(Ap,"l4Checksum");function JI(t,e,n){return Ap(t,e,6,n)}o(JI,"tcpChecksum");function UI(t,e,n){let s=Ap(t,e,17,n);return s===0?65535:s}o(UI,"udpChecksum");var Kp=0,zp=1,Fs=12,MI=10,cs=14,nu=2048,qp=2054,e0=20,LI=12,PI=16,jp=cs+0,Op=cs+2,AI=cs+4,KI=cs+5,zI=cs+14,jI=cs+24,t0=cs+28,OI=4,ca=1500,n0=cs+OI+ca,su=65535,ru=68,qc=4096,QI=32,Rl=Fs+n0,s0=3,r0=15;var Qp=4*1024*1024,Dp=8,Vl=class{static{o(this,"FabricMatcher")}net32;mask32;network;prefixLength;constructor(e,n){if(e.length!==4)throw new Error(`virtio-net: a fabric network is 4 bytes, got ${e.length}`);if(!Number.isInteger(n)||n<1||n>32)throw new Error(`virtio-net: fabric prefixLength ${n} is not 1..32`);this.network=e,this.prefixLength=n,this.mask32=n===32?-1:~(-1>>>n);let s=(e[0]<<24|e[1]<<16|e[2]<<8|e[3])>>>0;if(this.net32=(s&this.mask32)>>>0,s!==this.net32)throw new Error(`virtio-net: fabric network ${eu(e)}/${n} has host bits set (it means ${eu(DI(this.net32))}/${n})`)}contains(e,n){return((e[n]<<24|e[n+1]<<16|e[n+2]<<8|e[n+3])>>>0&this.mask32)>>>0===this.net32}get text(){return`${eu(this.network)}/${this.prefixLength}`}};function i0(t,e){if(t.length>>24&255,t>>>16&255,t>>>8&255,t&255])}o(DI,"u32ToIp");function eu(t){return`${t[0]}.${t[1]}.${t[2]}.${t[3]}`}o(eu,"ipText");function a0(t){let e=Math.ceil(t/qc);return Fs+(qc-QI)+e*qc}o(a0,"bigRxBufferCapacity");function l0(t,e){return e?"merged":t>ca?"big":"small"}o(l0,"rxModeFor");var ua=class{constructor(e){this.opts=e;if(this.mem=new ds(e),this.mtu=e.mtu??ca,!Number.isInteger(this.mtu)||this.mtusu)throw new Error(`virtio-net: mtu ${this.mtu} outside MIN_MTU..MAX_MTU (${ru}..${su}) \u2014 drivers/net/virtio_net.c would refuse it`);if(this.mergeRxBuf=e.mergeRxBuf===!0,this.expectedRxMode=l0(this.mtu,this.mergeRxBuf),this.link=e.link??null,this.fabric=e.fabric??null,this.link&&this.fabric)throw new Error('virtio-net: both `link` and `fabric` were given. `link` binds the WHOLE NIC to a brintos-link/1 endpoint and leaves the shim inert; `fabric` runs both planes on one NIC split by destination. Two answers to "what carries a frame off this NIC" is a device whose behaviour depends on which branch ran first. Use fabricPlaneOverLink() if you meant the second.');this.fabricNet=this.fabric?new Vl(this.fabric.network,this.fabric.prefixLength):null,this.naas=e.naas??new la({onEvent:o(n=>this.info(n),"onEvent")}),this.shim=new da({transmit:o(n=>this.injectFrom("shim",n),"transmit"),info:o(n=>this.info(n),"info"),naas:this.naas,...e.packetUplink?{packetUplink:e.packetUplink}:{},fetchImpl:e.fetchImpl,...e.httpPortMapping!==void 0?{httpPortMapping:e.httpPortMapping}:{},...e.gateway!==void 0?{gateway:e.gateway}:{},fs:e.fs,onError:o(n=>this.opts.onError?.(n),"onError")}),this.link&&(this.link.onFrames(n=>{for(let s of n)this.transmitToGuest(s)}),this.link.onCredit(()=>{this.txCreditStops>0&&this.drainTx()}),this.link.start(),this.info(`bound to a brintos-link fabric (mtu ${this.mtu}, rx mode ${this.expectedRxMode}); the MITM shim is inert on this NIC`)),this.fabric&&this.fabricNet&&(this.fabric.onFrames(n=>{for(let s of n)this.injectFrom("fabric",s)}),this.fabric.onReady?.(()=>{this.fabricTxStops>0&&this.drainTx()}),this.info(`two planes on one NIC: destinations in ${this.fabricNet.text} go to the storage fabric, everything else to the MITM shim`+(e.gateway?` (egress gateway on :${e.gateway.port??3128})`:"")+". A frame naming neither is refused, not guessed at."))}opts;static{o(this,"VirtioNetBackend")}mem;queues=new Map;pendingRx=[];pendingRxBytes=0;txFrames=0;rxFrames=0;rxOverflowDrops=0;rxStalls=0;txBatches=0;txCreditStops=0;rxMergedBuffers=0;rxStallReports=0;rxStalled=!1;loggedTx=0;observedRxMode=null;negotiationFault=null;negotiationDrops=0;featureCrossCheckDone=!1;mtu;mergeRxBuf;expectedRxMode;shim;naas;link;fabric;fabricNet;fabricTxFrames=0;shimTxFrames=0;fabricRxFrames=0;shimRxFrames=0;demuxRefusals=0;crossPlaneRefusals=0;demuxReports=0;crossPlaneReports=0;fabricTxStops=0;get naasForwardCount(){return this.naas.count??0}get rxMode(){return this.observedRxMode}get fault(){return this.negotiationFault}onKick(e){e===zp?this.drainTx():e===Kp&&(this.dbg(`onKick rxq (guest refilled buffers; pending=${this.pendingRx.length})`),this.pumpRx())}dispose(){}dbg(e){this.opts.onDebug?.(e)}info(e){this.opts.onInfo?.(e)}getQueue(e){let n=this.queues.get(e);if(n&&n.ready)return n;let s=gr(this.mem,this.opts.windowBase,e);return!s.ready||s.num===0?null:(n=new zs(this.mem,s),this.queues.set(e,n),n)}async drainTx(){let e=this.getQueue(zp);if(!e||this.negotiationFault)return;let n=this.link,s=this.fabric,r=this.fabricNet,i=0,l=0,d=[],a=!1;try{i=await e.drainAvail(c=>{let h=0;for(let b of c.readable)h+=b.len;if(h=b.len){m-=b.len;continue}let f=b.len-m;this.mem.copyOut(b.addr+m,f,p,y),y+=f,m=0}if(this.txFrames++,this.loggedTxn.credit>n.queued:s?.canAccept?()=>s.canAccept(d.length+1)?!0:(a=!0,!1):void 0)}catch(c){this.opts.onError?.(c instanceof Error?c:new Error(String(c)));return}n&&l>0&&(n.flush(),this.txBatches++),s&&d.length>0&&(s.send(d),this.txBatches++),a&&(this.fabricTxStops++,(this.fabricTxStops===1||this.fabricTxStops%256===0)&&this.info(`tx paused: the fabric plane cannot accept and ${e.availPending} chain(s) are left in the guest's avail ring. Both planes stop, because there is one ring \u2014 backpressure, not loss. fabric-tx-stops=${this.fabricTxStops}`)),n&&n.credit<=n.queued&&e.availPending>0&&(this.txCreditStops++,(this.txCreditStops===1||this.txCreditStops%256===0)&&this.info(`tx paused on link credit (${e.availPending} chain(s) left in the guest's avail ring, credit=${n.credit}) \u2014 backpressure, not loss. tx-credit-stops=${this.txCreditStops}`)),i>0&&this.raiseInterrupt()}injectFrom(e,n){let s=this.fabricNet;if(s){let r=o0(n,s);if(r!==null&&r!==e){if(this.crossPlaneRefusals++,this.crossPlaneReports<4||this.crossPlaneRefusals%256===0){this.crossPlaneReports++;let i=`virtio-net: the ${e} plane injected a ${n.length}B frame whose source belongs to the ${r} plane (fabric is ${s.text}) \u2014 REFUSED. This is a wiring fault, not traffic: a switch uplink on the wrong device, or a shim answering on an address the fabric owns. cross-plane-refusals=${this.crossPlaneRefusals}`;this.opts.onError?.(new Error(i)),this.info(i)}return}e==="fabric"?this.fabricRxFrames++:this.shimRxFrames++}this.transmitToGuest(n)}transmitToGuest(e){if(this.negotiationFault){this.negotiationDrops++,(this.negotiationDrops<=2||this.negotiationDrops%1024===0)&&this.info(`REFUSING a ${e.length}B rx frame: ${this.negotiationFault} (refused=${this.negotiationDrops}). This device does not deliver on a negotiation it cannot trust.`);return}if(e.length>this.mtu+cs+4){this.opts.onError?.(new Error(`virtio-net: refusing a ${e.length}B frame \u2014 this NIC's mtu is ${this.mtu} (ceiling ${this.mtu+cs+4}B incl. an 802.1Q tag)`));return}if(this.pendingRxBytes+e.length>Qp){if(this.rxOverflowDrops++,this.rxOverflowDrops<=4||this.rxOverflowDrops%256===0){let n=`virtio-net: rx backlog at cap (${this.pendingRxBytes}B / ${Qp}B, ${this.pendingRx.length} frames) \u2014 the guest is not posting rx buffers (stalled/dead); DROPPED a ${e.length}B frame. rx-overflow-drops=${this.rxOverflowDrops}`+(this.link?" \u2014 WITH a credit window bound, which means the window is wider than this cap and one of the two numbers is wrong.":"");this.opts.onError?.(new Error(n)),this.info(n)}return}this.pendingRx.push(e),this.pendingRxBytes+=e.length,this.pumpRx()}reportRxStall(e){this.rxStalls++,this.rxStalled=!0,(this.rxStallReports<4||this.rxStalls%256===0)&&(this.rxStallReports++,this.info(`rx STALL: ${e} \u2014 ${this.pendingRx.length} frame(s) / ${this.pendingRxBytes}B held host-side, undeliverable. The guest sees silence, not an error. rx-stalls=${this.rxStalls}`))}raiseNegotiationFault(e){if(this.negotiationFault)return;this.negotiationFault=e;let n=`virtio-net: FEATURE NEGOTIATION MISMATCH \u2014 ${e}`;this.opts.onError?.(new Error(n)),this.info(n),this.link?.raise("protocol",n)}assertRxChain(e){let n=e.writable;if(n.length===0)return!1;let s=0;for(let i of n)s+=i.len;let r;if(n.length>=3&&n[0].len===Fs)r="big";else if(n.length===1)r=n[0].len===Rl?"small":"single";else return this.opts.onError?.(new Error(`virtio-net: rx chain of ${n.length} segment(s) starting at ${n[0].len}B matches no add_recvbuf_* shape (small posts 1 segment of ${Rl}B, big posts >=3 starting with a ${Fs}B header segment, mergeable posts 1)`)),!1;if(this.observedRxMode===null){let i=this.expectedRxMode==="big"?r==="big":r!=="big";if(this.observedRxMode=i?this.expectedRxMode:r,this.info(`rx buffers: guest posts ${r} (${n.length} seg, ${s}B capacity); host configured for ${this.expectedRxMode} (mtu ${this.mtu}${this.mergeRxBuf?", MRG_RXBUF":""})`),this.crossCheckAcceptedFeatures(),this.negotiationFault)return!1;if(!i)return this.raiseNegotiationFault(`this host was configured for mtu ${this.mtu}${this.mergeRxBuf?" + VIRTIO_NET_F_MRG_RXBUF":""} (rx mode "${this.expectedRxMode}", which posts ${$p(this.expectedRxMode)}), but the guest posted ${$p(r)}. The kernel did not accept the feature this host is relying on. virtio-net's offered-features word is KERNEL-side (arch/wasm32/kernel/virtio_net_wasm.c calls wasm_virtio_add_device with it); this is the host-first half of a lockstep pair running against a kernel that has not caught up. Delivering anyway would post up to ${this.mtu+cs}B frames into ${s-Fs}B buffers, which receive_small drops at drivers/net/virtio_net.c:1838 without telling anyone.`),!1;if(this.expectedRxMode!=="merged"){let l=this.expectedRxMode==="big"?a0(this.mtu):Fs+cs+this.mtu;if(s ${r}); the queue is corrupt`)),!1;return!0}crossCheckAcceptedFeatures(){if(this.featureCrossCheckDone)return;this.featureCrossCheckDone=!0;let e=gp(this.mem,this.opts.windowBase);if(!e.readable){this.info(`accepted-features cross-check UNAVAILABLE: ${e.why}`);return}let n=(e.word0&1<ca;(r!==n||this.mergeRxBuf!==s)&&this.raiseNegotiationFault(`the driver accepted F_MTU=${n?1:0} F_MRG_RXBUF=${s?1:0}, this host expects F_MTU=${r?1:0} F_MRG_RXBUF=${this.mergeRxBuf?1:0}`)}pumpRx(){if(this.negotiationFault)return;let e=this.getQueue(Kp);if(!e){this.reportRxStall("guest rx queue not ready");return}let n=0,s=0;for(;this.pendingRx.length>0;){let r=this.pendingRx[0],i=Fs+r.length,l=[],d=0,a=!1;for(;d=0;m--)e.complete(l[m].head,0);break}if(l.length===0){this.reportRxStall("no free guest rx buffer");break}if(d0&&(this.dbg(`rx: delivered ${n} frame(s)`),this.rxStalled&&this.pendingRx.length===0&&(this.rxStalled=!1,this.info(`rx recovered: backlog drained (rx-stalls=${this.rxStalls} total)`)),this.raiseInterrupt()),s>0&&this.link?.consume(s)}writeFrameInto(e,n,s,r,i){let l=i>0||s===0;try{let d=s,a=s+r,c=l?Fs:0;for(let h of e.writable){let p=h.addr,m=h.len;if(c>0){let b=Math.min(c,m);if(this.mem.fill(p,b,0),i>0){let f=MI-(Fs-c);f>=0&&f+2<=b&&this.mem.write(p+f,Uint8Array.from([i&255,i>>8&255]))}if(p+=b,m-=b,c-=b,m===0)continue}if(d>=a)break;let y=Math.min(m,a-d);this.mem.write(p,n.subarray(d,d+y)),d+=y}return d>2,1),this.opts.suppressIrq)return;let s=1<<(this.opts.irqBit??2);Atomics.or(e,this.opts.irqPendingOffset>>2,s),Atomics.add(e,this.opts.schedWakeupOffset>>2,1),Atomics.notify(e,this.opts.schedWakeupOffset>>2,1)}};function tu(t){return t.length>=14?t[12]<<8|t[13]:0}o(tu,"ethertype");function $p(t){switch(t){case"small":return`one ${Rl}B segment, which is add_recvbuf_small with hdr_len + GOOD_PACKET_LEN buffers (drivers/net/virtio_net.c:2434)`;case"big":return"a page chain, which is add_recvbuf_big (drivers/net/virtio_net.c:2464)";case"merged":case"single":return"one variable-length segment, which is add_recvbuf_small or add_recvbuf_mergeable (drivers/net/virtio_net.c:2434 / :2530) \u2014 either way NOT the page chain add_recvbuf_big posts"}}o($p,"describeShape");var $I=96,xl=256,iu=320,qI=384,eG=40,tG=1112757591,nG=1,sG=0,ou=1,rG=2,iG=3,oG=128,aG=8,d0=0,lG=2,dG=3,c0=1,u0=512,m0=1024,h0=65536,b0=19,Yl=32,Bl=71,cG=75,ma=class{static{o(this,"UsbHcdBackend")}opts;mem;ports;validated=!1;numSlots=0;numPorts=0;completions=0;grantRefusals=0;constructor(e){this.opts=e,this.mem=new ds(e),this.ports=[]}rd32(e){return Atomics.load(this.mem.i32,this.opts.windowBase+e>>2)>>>0}wr32(e,n){Atomics.store(this.mem.i32,this.opts.windowBase+e>>2,n|0)}or32(e,n){Atomics.or(this.mem.i32,this.opts.windowBase+e>>2,n|0)}and32(e,n){Atomics.and(this.mem.i32,this.opts.windowBase+e>>2,n|0)}slotOff(e){return qI+e*eG}ensureValidated(){if(this.validated)return!0;if(this.rd32(xl+0)!==tG)return!1;let n=this.rd32(xl+4);if(this.numSlots=this.rd32(xl+8),this.numPorts=this.rd32(xl+12),n!==nG||this.numSlots===0||this.numPorts===0)return this.opts.onError?.(new Error(`usb_hcd: header mismatch (version=${n} slots=${this.numSlots} ports=${this.numPorts}) \u2014 refusing to serve`)),!1;for(let s=0;s>2,e),Atomics.add(n,this.opts.schedWakeupOffset>>2,1),Atomics.notify(n,this.opts.schedWakeupOffset>>2,1)}async attachDevice(e,n="full"){let s=Date.now()+3e4;for(;!this.ensureValidated();){if(Date.now()>s)throw new Error("usb_hcd: window header never appeared (kernel without CONFIG_USB / wasm-usb HCD?) \u2014 refusing attach");await new Promise(m=>setTimeout(m,25))}let r=this.ports.findIndex(m=>m.device===null&&!m.claimed);if(r<0)throw new Error("usb_hcd: no free root-hub port");let i=this.ports[r];i.claimed=!0;let l=o((m,y)=>this.opts.onEvent?.({kind:"descriptor-fallback",port:r,detail:`${ji(e.vendorId)}:${ji(e.productId)} ${m}: ${y} \u2014 serving one synthesized from WebUSB metadata, which has no class-specific descriptors`}),"fallback"),d,a,c,h;try{e.opened||await e.open();try{await e.reset?.()}catch(y){this.opts.onDebug?.(`usb_hcd: attach reset failed (tolerated): ${y}`)}let m=await mG(e);d=m.ok,a=m.ok?bG(m.bytes,n):f0(e),m.ok||l("device descriptor",m.why),c=new Map;for(let y=0;y=this.numSlots){this.opts.onError?.(new Error(`usb_hcd: kick with bad slot ${e}`));return}let n=this.opts.windowBase+this.slotOff(e);Atomics.load(this.mem.i32,n+0>>2)===ou&&this.handleUrb(e).catch(s=>{this.opts.onError?.(s instanceof Error?s:new Error(String(s))),this.completeSlot(e,0,-Bl)})}slotView(e){let n=this.opts.windowBase+this.slotOff(e),s=this.mem.dv;return{port:s.getUint32(n+4,!0),epinfo:s.getUint32(n+8,!0),bufAddr:s.getUint32(n+12,!0),bufLen:s.getUint32(n+16,!0),setup:this.mem.read(n+28,8)}}completeSlot(e,n,s){let r=this.opts.windowBase+this.slotOff(e),i=r+0>>2,l=this.mem.dv,d=this.mem.i32;l.setUint32(r+20,n>>>0,!0),l.setInt32(r+24,s|0,!0);let a=Atomics.compareExchange(d,i,ou,rG);if(a===iG){Atomics.store(d,i,sG),this.opts.onEvent?.({kind:"cancel-drop",port:l.getUint32(r+4,!0),detail:`slot ${e}: completion dropped (kernel canceled the URB)`});return}if(a!==ou){this.opts.onError?.(new Error(`usb_hcd: completing slot ${e} in unexpected state ${a}`));return}this.completions++,this.opts.onDebug?.(`urb slot=${e} complete actual=${n} status=${s}`),this.raiseInterrupt()}async handleUrb(e){let n=this.slotView(e),s=this.ports[n.port],r=s?.device;if(!r||s.revoked){this.grantRefusals++,this.opts.onEvent?.({kind:"grant-refuse",port:n.port,detail:`USB-GRANT-REFUSE: URB slot ${e} to ${r?"revoked":"empty"} port ${n.port} \u2014 completed -ENODEV`}),this.completeSlot(e,0,-b0);return}let i=n.epinfo&15,l=(n.epinfo&oG)!==0,d=n.epinfo>>aG&3;this.opts.onDebug?.(`urb slot=${e} port=${n.port} ep=${i}${l?"in":"out"} type=${d} len=${n.bufLen}`+(d===d0?` setup=[${Array.from(n.setup).map(a=>a.toString(16).padStart(2,"0")).join(" ")}]`:""));try{if(d===d0)await this.handleControl(e,n,s,r);else if(d===lG||d===dG)if(l){let a=await r.transferIn(i,n.bufLen),c=Math.min(a.data?.byteLength??0,n.bufLen);c>0&&a.data&&this.mem.write(n.bufAddr,new Uint8Array(a.data.buffer,a.data.byteOffset,c)),this.completeSlot(e,c,Tl(a.status,this.opts,n.port))}else{let a=this.mem.read(n.bufAddr,n.bufLen),c=await r.transferOut(i,a);this.completeSlot(e,c.bytesWritten,Tl(c.status,this.opts,n.port))}else this.opts.onEvent?.({kind:"protocol-error",port:n.port,detail:`slot ${e}: unsupported transfer type ${d} \u2014 -EPROTO`}),this.completeSlot(e,0,-Bl)}catch(a){this.transferException(e,n.port,a)}}transferException(e,n,s){let r=s instanceof Error?`${s.name}: ${s.message}`:String(s),i=/NotFoundError|disconnected|no device|LIBUSB_ERROR_NO_DEVICE/i.test(r);this.opts.onEvent?.({kind:"transfer-error",port:n,detail:`slot ${e}: ${r} -> ${i?"-ENODEV (device gone)":"-EPROTO"}`}),i?(this.completeSlot(e,0,-b0),this.detachDevice(n)):this.completeSlot(e,0,-Bl)}async handleControl(e,n,s,r){let i=n.setup[0],l=n.setup[1],d=n.setup[2]|n.setup[3]<<8,a=n.setup[4]|n.setup[5]<<8,c=n.setup[6]|n.setup[7]<<8,h=(i&128)!==0,p=i>>5&3,m=i&31;if(p===0)switch(l){case 6:{let b=d>>8,f=d&255,I;if(b===1)I=s.deviceDesc??void 0;else if(b===2){let X=r.configurations[f];I=X?s.configDescs.get(X.configurationValue):void 0}else if(b===3){if(s.deviceDescFromDevice||f!==0&&!s.strings.has(f)){let X=await Cl(r,d,a,c);X.ok&&X.bytes.length>=2&&X.bytes[1]===3&&(I=X.bytes)}I??=s.strings.get(f)}if(!I){this.completeSlot(e,0,-Yl);return}let R=Math.min(I.length,c,n.bufLen);this.mem.write(n.bufAddr,I.subarray(0,R)),this.completeSlot(e,R,0);return}case 5:s.guestAddress=d,this.completeSlot(e,0,0);return;case 9:{let b=r.configurations.find(f=>f.configurationValue===d);if(!b&&d!==0){this.completeSlot(e,0,-Yl);return}if(await r.selectConfiguration(d),b)for(let f of b.interfaces)try{await r.claimInterface(f.interfaceNumber)}catch(I){this.grantRefusals++,this.opts.onEvent?.({kind:"grant-refuse",port:n.port,detail:`USB-GRANT-REFUSE: claimInterface(${f.interfaceNumber}) refused: ${I}`}),this.completeSlot(e,0,-Yl);return}this.completeSlot(e,0,0);return}case 8:{let b=r.configurations[0]?.configurationValue??1;this.mem.fill(n.bufAddr,1,b),this.completeSlot(e,1,0);return}case 11:r.selectAlternateInterface&&await r.selectAlternateInterface(a,d),this.completeSlot(e,0,0);return;case 1:if(m===2&&r.clearHalt){let b=a&15,f=(a&128)!==0?"in":"out";await r.clearHalt(f,b)}this.completeSlot(e,0,0);return;case 0:{let b=Math.min(2,c,n.bufLen);this.mem.fill(n.bufAddr,b,0),this.completeSlot(e,b,0);return}default:this.opts.onEvent?.({kind:"protocol-error",port:n.port,detail:`slot ${e}: unmapped STANDARD request 0x${l.toString(16)} \u2014 -EPROTO`}),this.completeSlot(e,0,-Bl);return}let y={requestType:p===1?"class":"vendor",recipient:m===1?"interface":m===2?"endpoint":m===3?"other":"device",request:l,value:d,index:a};if(h){let b=await r.controlTransferIn(y,c),f=Math.min(b.data?.byteLength??0,n.bufLen);f>0&&b.data&&this.mem.write(n.bufAddr,new Uint8Array(b.data.buffer,b.data.byteOffset,f)),this.completeSlot(e,f,Tl(b.status,this.opts,n.port))}else{let b=c>0?this.mem.read(n.bufAddr,Math.min(c,n.bufLen)):void 0,f=await r.controlTransferOut(y,b);this.completeSlot(e,f.bytesWritten,Tl(f.status,this.opts,n.port))}}};function Tl(t,e,n){return t==="ok"?0:(e.onEvent?.({kind:"transfer-error",port:n,detail:`transfer status '${t}' -> ${t==="stall"?"-EPIPE":"-EOVERFLOW"}`}),t==="stall"?-Yl:-cG)}o(Tl,"statusToErrno");function ji(t){return t.toString(16).padStart(4,"0")}o(ji,"hex4");function f0(t){let e=new Uint8Array(18),n=new DataView(e.buffer);return e[0]=18,e[1]=1,n.setUint16(2,t.usbVersionMajor<<8|t.usbVersionMinor<<4,!0),e[4]=t.deviceClass,e[5]=t.deviceSubclass,e[6]=t.deviceProtocol,e[7]=64,n.setUint16(8,t.vendorId,!0),n.setUint16(10,t.productId,!0),n.setUint16(12,t.deviceVersionMajor<<8|t.deviceVersionMinor<<4|t.deviceVersionSubminor,!0),e[14]=t.manufacturerName?1:0,e[15]=t.productName?2:0,e[16]=t.serialNumber?3:0,e[17]=t.configurations.length,e}o(f0,"synthesizeDeviceDescriptor");function y0(t){let e=[],n=0;for(let i of t.interfaces){n++;for(let l of i.alternates){e.push(9,4,i.interfaceNumber,l.alternateSetting,l.endpoints.length,l.interfaceClass,l.interfaceSubclass,l.interfaceProtocol,0);for(let d of l.endpoints){let a=d.endpointNumber|(d.direction==="in"?128:0),c=d.type==="bulk"?2:d.type==="interrupt"?3:1;e.push(7,5,a,c,d.packetSize&255,d.packetSize>>8,d.type==="interrupt"?1:0)}}}let s=9+e.length,r=new Uint8Array(s);return r[0]=9,r[1]=2,r[2]=s&255,r[3]=s>>8,r[4]=n,r[5]=t.configurationValue,r[6]=0,r[7]=128,r[8]=50,r.set(e,9),r}o(y0,"synthesizeConfigDescriptor");var uG=3e3;async function Cl(t,e,n,s,r=uG){let i,l=new Promise(a=>{i=setTimeout(()=>a({ok:!1,why:`no answer in ${r} ms`}),r)}),d=(async()=>{try{let a=await t.controlTransferIn({requestType:"standard",recipient:"device",request:6,value:e,index:n},s);return a.status!=="ok"||!a.data?{ok:!1,why:`device answered ${a.status}`}:{ok:!0,bytes:new Uint8Array(a.data.buffer,a.data.byteOffset,a.data.byteLength).slice()}}catch(a){return{ok:!1,why:`transfer refused (${a instanceof Error?a.message:String(a)})`}}})();try{return await Promise.race([d,l])}finally{clearTimeout(i)}}o(Cl,"getDescriptor");async function mG(t){let e=await Cl(t,256,0,18);if(!e.ok)return e;let n=e.bytes;if(n.length!==18||n[0]!==18||n[1]!==1)return{ok:!1,why:`not a device descriptor (${n.length} B, bLength ${n[0]}, type ${n[1]})`};let s=n[8]|n[9]<<8,r=n[10]|n[11]<<8;return s!==t.vendorId||r!==t.productId||n[17]!==t.configurations.length?{ok:!1,why:`names ${ji(s)}:${ji(r)} with ${n[17]} configuration(s)`}:e}o(mG,"readDeviceDescriptor");async function hG(t,e,n){let s=await Cl(t,512|e,0,9);if(!s.ok)return s;let r=s.bytes;if(r.length<9||r[0]!==9||r[1]!==2)return{ok:!1,why:`not a configuration descriptor (${r.length} B, bLength ${r[0]}, type ${r[1]})`};if(r[5]!==n)return{ok:!1,why:`index ${e} is configuration ${r[5]}, not ${n}`};let i=r[2]|r[3]<<8;if(i<9)return{ok:!1,why:`wTotalLength ${i}`};let l=await Cl(t,512|e,0,i);if(!l.ok)return l;let d=l.bytes;return d.length!==i||d[1]!==2||d[5]!==n?{ok:!1,why:`full read gave ${d.length} of ${i} B`}:l}o(hG,"readDeviceConfigDescriptor");function bG(t,e){let n=t.slice();return(e==="low"?[8]:[8,16,32,64]).includes(n[7])||(n[7]=e==="low"?8:64),n}o(bG,"fitMaxPacket0");function p0(t,e=1,n=2,s=3){let r=new Map;r.set(0,new Uint8Array([4,3,9,4]));let i=o((l,d)=>{if(!d)return;let a=new Uint8Array(2+d.length*2);a[0]=a.length,a[1]=3;for(let c=0;c>8;r.set(l,a)},"put");return e&&i(e,t.manufacturerName),n&&i(n,t.productName),s&&i(s,t.serialNumber),r}o(p0,"synthesizeStrings");var pG=0,fG=1;var yG=3;var Z0=6,ZG=7,Nl=8,g0=2,I0=3;function w0(t){return t===0?0:t*2+2}o(w0,"portInQueue");function G0(t){return t===0?1:t*2+3}o(G0,"portOutQueue");var S0=3,W0=4*1024*1024,Hl=class{constructor(e,n,s){this.id=e;this.name=n;this.dev=s}id;name;dev;static{o(this,"VirtioConsolePort")}pending=[];pendingLen=0;sinks=new Set;guestOpen=!1;hostOpen=!1;bytesToGuest=0;bytesFromGuest=0;overflowDrops=0;get guestConnected(){return this.guestOpen}get hostConnected(){return this.hostOpen}get pendingBytes(){return this.pendingLen}write(e){if(e.length!==0){if(this.pendingLen+e.length>W0){this.overflowDrops++;let n=`virtio-console: port ${this.id} host->guest backlog at cap (${this.pendingLen}B / ${W0}B) \u2014 the guest is not posting buffers (closed, stalled, or dead); DROPPED ${e.length}B. overflow-drops=${this.overflowDrops}`;this.dev.reportError(new Error(n));return}this.pending.push(e.slice()),this.pendingLen+=e.length,this.pump()}}onData(e){return this.sinks.add(e),()=>{this.sinks.delete(e)}}setGuestConnected(e){this.guestOpen!==e&&(this.guestOpen=e,this.dev.reportInfo(`port ${this.id}${this.name?` (${this.name})`:""} ${e?"opened":"closed"} by the guest`+(e&&this.pendingLen>0?` \u2014 releasing ${this.pendingLen}B held`:"")),e&&this.pump())}setHostConnected(e){this.hostOpen=e}deliverFromGuest(e){this.bytesFromGuest+=e.length;for(let n of this.sinks)try{n(e)}catch(s){this.dev.reportError(s instanceof Error?s:new Error(String(s)))}}pump(){if(!this.guestOpen||this.pendingLen===0)return 0;let e=this.dev.queue(w0(this.id));if(!e)return 0;let n=0;for(;this.pendingLen>0;){let s=e.takeAvail();if(!s)break;let r=s.writable[0];if(!r||r.len===0){this.dev.reportError(new Error(`virtio-console: port ${this.id} in_vq buffer unusable (len=${r?r.len:0}) \u2014 completing it so the queue cannot wedge`)),e.complete(s.head,0);continue}let i=this.dev.mem.bytes(r.addr,r.len),l=0;for(;l0;){let d=this.pending[0],a=Math.min(d.length,r.len-l);i.set(d.subarray(0,a),l),l+=a,this.pendingLen-=a,a===d.length?this.pending.shift():this.pending[0]=d.subarray(a)}e.complete(s.head,l),this.bytesToGuest+=l,n++}return n>0&&(this.dev.reportDebug(`port ${this.id}: filled ${n} in_vq buffer(s)`),this.dev.raise()),n}discardPending(){this.pending.length=0,this.pendingLen=0}},ha=class{constructor(e){this.opts=e;if(this.mem=new ds(e),this.specs=e.ports??[{id:1,name:"org.brintos.fsproxyd.0"}],this.specs.length===0)throw new Error("virtio-console: a device with no ports offers the guest nothing \u2014 configure at least one port (the appliance wants id 1)");for(let n of this.specs){if(!Number.isInteger(n.id)||n.id<0)throw new Error(`virtio-console: port id ${n.id} is not a port number`);if(this.portsById.has(n.id))throw new Error(`virtio-console: port id ${n.id} configured twice`);this.portsById.set(n.id,new Hl(n.id,n.name,this))}if(this.maxNrPorts=Math.max(...this.specs.map(n=>n.id))+1,this.maxNrPorts>S0)throw new Error(`virtio-console: max_nr_ports ${this.maxNrPorts} needs ${(this.maxNrPorts+1)*2} virtqueues, past the arch's WASM_VIRTIO_SHADOW_MAXQ of 8 \u2014 the extra queues' geometry would be unreadable host-side and those ports would carry no bytes`)}opts;static{o(this,"VirtioConsoleBackend")}mem;queues=new Map;portsById=new Map;specs;pendingControl=[];maxNrPorts;deviceReady=!1;port(e){return this.portsById.get(e)}get ports(){return this.portsById}onKick(e){try{e===I0?this.drainControlOut():e===g0?this.pumpControlIn():this.onPortKick(e)}catch(n){this.reportError(n instanceof Error?n:new Error(String(n)))}}dispose(){for(let e of this.portsById.values())e.discardPending();this.pendingControl.length=0}drainControlOut(){let e=this.queue(I0);if(!e)return;let n=[];for(;;){let s=e.takeAvail();if(!s)break;let r=s.readable[0],i=null;if(!r||r.len`p${n.id}${n.name?`=${n.name}`:""}`).join(", "));for(let n of this.specs)this.sendControl(n.id,fG,1);this.pumpControlIn();return;case yG:{let n=this.portsById.get(e.id);if(!n){this.reportError(new Error(`virtio-console: PORT_READY for unconfigured port ${e.id}`));return}if(!e.value){this.reportError(new Error(`virtio-console: guest failed to add port ${e.id} (PORT_READY(0)) \u2014 /dev/vport*p${e.id} will not exist`));return}n.name!==void 0&&this.sendControlWithPayload(e.id,ZG,1,new TextEncoder().encode(`${n.name}\0`)),n.setHostConnected(!0),this.sendControl(e.id,Z0,1),this.pumpControlIn();return}case Z0:{let n=this.portsById.get(e.id);if(!n){this.reportError(new Error(`virtio-console: PORT_OPEN for unconfigured port ${e.id}`));return}n.setGuestConnected(!!e.value);return}default:this.reportDebug(`control-out event ${e.event} (id=${e.id} value=${e.value}) ignored`);return}}sendControl(e,n,s){this.sendControlWithPayload(e,n,s,null)}sendControlWithPayload(e,n,s,r){let i=new Uint8Array(Nl+(r?r.length:0)),l=new DataView(i.buffer);l.setUint32(0,e>>>0,!0),l.setUint16(4,n,!0),l.setUint16(6,s,!0),r&&i.set(r,Nl),this.pendingControl.push(i)}pumpControlIn(){if(this.pendingControl.length===0)return;let e=this.queue(g0);if(!e)return;let n=0;for(;this.pendingControl.length>0;){let s=e.takeAvail();if(!s)break;let r=s.writable[0],i=this.pendingControl[0];if(!r||r.len0&&(this.reportDebug(`control-in: delivered ${n} message(s)`),this.raise())}onPortKick(e){for(let n of this.portsById.values()){if(e===G0(n.id)){this.drainPortOut(n);return}if(e===w0(n.id)){n.pump();return}}this.reportDebug(`kick on queue ${e}, which no configured port owns`)}drainPortOut(e){let n=this.queue(G0(e.id));if(!n)return;let s=[],r=0;for(;;){let i=n.takeAvail();if(!i)break;let l=0;for(let d of i.readable)l+=d.len;if(l>0){let d=new Uint8Array(l),a=0;for(let c of i.readable)this.mem.copyOut(c.addr,c.len,d,a),a+=c.len;s.push(d)}n.complete(i.head,0),r++}if(r!==0){this.raise();for(let i of s)this.reportDebug(`port ${e.id}: ${i.length}B from the guest`),e.deliverFromGuest(i)}}queue(e){let n=this.queues.get(e);if(n&&n.ready)return n;let s=gr(this.mem,this.opts.windowBase,e);return!s.ready||s.num===0?null:(n=new zs(this.mem,s),this.queues.set(e,n),n)}reportError(e){this.opts.onError?.(e)}reportInfo(e){this.opts.onInfo?.(e)}reportDebug(e){this.opts.onDebug?.(e)}raise(){let e=this.mem.i32,n=this.opts.windowBase+96;if(Atomics.or(e,n>>2,1),this.opts.suppressIrq)return;let s=1<<(this.opts.irqBit??4);Atomics.or(e,this.opts.irqPendingOffset>>2,s),Atomics.add(e,this.opts.schedWakeupOffset>>2,1),Atomics.notify(e,this.opts.schedWakeupOffset>>2,1)}};function Oi(t){switch(t>>>0){case 0:return"NOP";case 1:return"READ";case 2:return"WRITE";case 3:return"FLUSH";case 4:return"STAT";case 5:return"ECHO";default:return`opcode ${t>>>0} (not a WASM_HOSTTRANS_OP_*)`}}o(Oi,"hosttransOpName");var ys={MAGIC:0,ABI_VERSION:4,ACTIVE:8,FEATURES:12,SCHED_WAKE_OFF:16,NOTIFY_SEQ:20,SQ_HEAD:24,SQ_TAIL:28,SQ_SLOTS:32,CQ_HEAD:36,CQ_TAIL:40,CQ_SLOTS:44,MAX_XFER:48,RESERVED:52},Gr={REQUEST_ID:0,OPCODE:4,OBJECT_ID:8,FLAGS:12,OFFSET:16,LENGTH:24,BUF_ADDR:28,BUF_LEN:32,RESERVED:36},Qi={REQUEST_ID:0,STATUS:4,LENGTH:8,RESERVED:12},au=384,k0=2560,lu=au+k0,X0=1024,gG=lu+X0;function du(t){return au+t%64*40}o(du,"hosttransSqSlotOffset");function cu(t){return lu+t%64*16}o(cu,"hosttransCqSlotOffset");var R0=5,IG=14,GG=38,WG=96,wG=1;function B0(t={},e){let n=o(r=>{if(r.buf===null)return{status:-IG,length:0};let i=Math.min(r.length||r.buf.len,r.buf.len),l=r.buf.read(i);return r.buf.write(l),{status:0,length:i}},"echo"),s={0:()=>({status:0,length:0}),5:n};return r=>{let i=t[r.opcode]??s[r.opcode];return i===void 0?(e?.(new Error(`hosttrans: no implementation for ${Oi(r.opcode)} (request_id ${r.requestId}, object_id ${r.objectId}) \u2014 answering -ENOSYS. This backend was given implementations for [${Object.keys(t).map(l=>Oi(Number(l))).join(", ")||"none"}] on top of the stateless NOP/ECHO pair.`)),{status:-GG,length:0}):i(r)}}o(B0,"makeHostTransportHandler");var pa=class{static{o(this,"HostTransportBackend")}opts;mem;handler;validated=!1;inFlight=!1;rekick=!1;requestsDrained=0;completions=0;grantRefusals=0;cqFullStalls=0;unimplemented=0;constructor(e){this.opts=e,this.mem=new ds(e),this.handler=e.handler??B0({},n=>{this.unimplemented++,this.opts.onError?.(n)})}get devid(){return 6}attach(){let e=this.mem.i32,n=this.opts.windowBase+256+ys.ACTIVE;Atomics.store(e,n>>2,1),this.opts.onInfo?.(`hosttrans: granted (devid ${6}, window 0x${this.opts.windowBase.toString(16)}, active=1)`)}detach(){let e=this.mem.i32,n=this.opts.windowBase+256+ys.ACTIVE;Atomics.store(e,n>>2,0),this.opts.onInfo?.(`hosttrans: grant REVOKED (devid ${6}, active=0) \u2014 every doorbell from here on is refused`)}get active(){let e=this.mem.i32,n=this.opts.windowBase+256+ys.ACTIVE;return Atomics.load(e,n>>2)>>>0!==0}onKick(e){if(!this.active){this.grantRefusals++,this.opts.onError?.(new Error(`hosttrans: doorbell while active=0 (devid ${6}, window 0x${this.opts.windowBase.toString(16)}) \u2014 refusing to drain an UNGRANTED transport. Nothing was consumed and sq_tail did not move; call attach() to grant it.`));return}this.ensureValidated()&&this.pump()}ensureValidated(){if(this.validated)return!0;let e=this.opts.windowBase+256,n=this.mem.i32,s=Atomics.load(n,e+ys.MAGIC>>2)>>>0;if(s!==1381255255)return this.opts.onError?.(new Error(`hosttrans: ring header not seeded (magic 0x${s.toString(16)}, want 0x${1381255255 .toString(16)} "WHTR") at window 0x${this.opts.windowBase.toString(16)}+0x${256 .toString(16)} \u2014 refusing to drain. A kernel without the wasm_hosttrans device, or one whose device_initcall has not run yet, never stores it.`)),!1;let r=Atomics.load(n,e+ys.ABI_VERSION>>2)>>>0,i=Atomics.load(n,e+ys.SQ_SLOTS>>2)>>>0,l=Atomics.load(n,e+ys.CQ_SLOTS>>2)>>>0;if(r!==1||i!==64||l!==64)return this.opts.onError?.(new Error(`hosttrans: ABI/geometry mismatch \u2014 kernel says abi_version=${r} sq_slots=${i} cq_slots=${l}; this host is built for abi_version=${1} sq_slots=${64} cq_slots=${64} (src/hosttrans-abi.ts). Refusing to serve: bump BOTH halves in one commit.`)),!1;this.validated=!0;let d=Atomics.load(n,e+ys.MAX_XFER>>2)>>>0,a=Atomics.load(n,e+ys.FEATURES>>2)>>>0;return this.opts.onInfo?.(`hosttrans: ring v${r} up \u2014 ${i} SQ / ${l} CQ slots, max_xfer ${d}B, features 0x${a.toString(16)}`),!0}pump(){if(this.inFlight){this.rekick=!0;return}this.inFlight=!0,this.drain()}drain(){for(;;){let e=this.take();if(e===null)break;let n;try{n=this.handler(e.req)}catch(s){this.publishThrow(e,s);continue}if(n instanceof Promise){this.finishAsync(e,n);return}this.publish(e,n)}this.settle()}async finishAsync(e,n){let s;try{s=await n}catch(r){this.publishThrow(e,r),this.drain();return}this.publish(e,s),this.drain()}settle(){this.inFlight=!1,this.rekick&&(this.rekick=!1,this.pump())}take(){let e=this.opts.windowBase,n=e+256,s=this.mem.i32,r=Atomics.load(s,n+ys.SQ_HEAD>>2)>>>0,i=Atomics.load(s,n+ys.SQ_TAIL>>2)>>>0;if(r===i)return null;let l=r-i>>>0;if(l>64)return this.opts.onError?.(new Error(`hosttrans: SQ indices are impossible \u2014 sq_head=${r} sq_tail=${i} means ${l} pending in a ${64}-slot ring. Refusing to read a slot the producer may still be filling; this is ring corruption, not backpressure.`)),null;let d=Atomics.load(s,n+ys.CQ_HEAD>>2)>>>0,a=Atomics.load(s,n+ys.CQ_TAIL>>2)>>>0,c=d-a>>>0;if(c>64)return this.opts.onError?.(new Error(`hosttrans: CQ indices are impossible \u2014 cq_head=${d} cq_tail=${a} means ${c} outstanding in a ${64}-slot ring. Refusing to publish.`)),null;if(c===64)return this.cqFullStalls++,this.opts.onError?.(new Error(`hosttrans: CQ full (${64} completions the guest has not consumed, cq_tail=${a}) with ${l} request(s) still in the SQ \u2014 stopping the drain here. NOTHING IS DROPPED: sq_tail stays at ${i} and the next doorbell resumes at that request.`)),this.raise(),null;let h=e+du(i),p=this.mem.dv,m=p.getUint32(h+Gr.BUF_ADDR,!0),y=p.getUint32(h+Gr.BUF_LEN,!0),b={requestId:p.getUint32(h+Gr.REQUEST_ID,!0),opcode:p.getUint32(h+Gr.OPCODE,!0),objectId:p.getUint32(h+Gr.OBJECT_ID,!0),flags:p.getUint32(h+Gr.FLAGS,!0),offset:p.getBigUint64(h+Gr.OFFSET,!0),length:p.getUint32(h+Gr.LENGTH,!0),buf:m===0?null:this.makeBuffer(m,y)};return Atomics.store(s,n+ys.SQ_TAIL>>2,i+1|0),this.requestsDrained++,{req:b,cqIndex:d}}makeBuffer(e,n){let s=this.mem;return{addr:e,len:n,read(r){let i=r===void 0?n:r;if(i<0||i>n)throw new RangeError(`hosttrans buffer read: ${i}B asked of a ${n}B descriptor at 0x${e.toString(16)} \u2014 the descriptor's capacity is the whole permission, and reading past it would read another allocation`);return s.read(e,i)},write(r,i=0){if(i<0||i+r.length>n)throw new RangeError(`hosttrans buffer write: ${r.length}B at +${i} into a ${n}B descriptor at 0x${e.toString(16)} \u2014 REFUSED rather than truncated. A silent truncation here is a short transfer the guest reports to userspace as a complete one.`);return s.write(e+i,r),r.length}}}publish(e,n){let s=this.opts.windowBase,r=s+256;(!Number.isInteger(n.status)||n.status>0)&&(this.opts.onError?.(new Error(`hosttrans: handler answered status=${n.status} for ${Oi(e.req.opcode)} request_id ${e.req.requestId}; cpl.status is 0 or -errno and nothing else. Completing -EIO.`)),n={status:-R0,length:0});let i=s+cu(e.cqIndex),l=this.mem.dv;l.setUint32(i+Qi.REQUEST_ID,e.req.requestId>>>0,!0),l.setInt32(i+Qi.STATUS,n.status|0,!0),l.setUint32(i+Qi.LENGTH,n.length>>>0,!0),l.setUint32(i+Qi.RESERVED,0,!0);let d=this.mem.i32;Atomics.store(d,r+ys.CQ_HEAD>>2,e.cqIndex+1|0),this.completions++,this.raise()}publishThrow(e,n){this.opts.onError?.(new Error(`hosttrans: handler threw on ${Oi(e.req.opcode)} request_id ${e.req.requestId} object_id ${e.req.objectId}: ${n instanceof Error?n.message:String(n)} \u2014 completing -EIO rather than leaving the guest blocked on it`)),this.publish(e,{status:-R0,length:0})}raise(){let e=this.mem.i32;if(Atomics.or(e,this.opts.windowBase+WG>>2,wG),this.opts.suppressIrq)return;let n=1<<(this.opts.irqBit??6);Atomics.or(e,this.opts.irqPendingOffset>>2,n),Atomics.add(e,this.opts.schedWakeupOffset>>2,1),Atomics.notify(e,this.opts.schedWakeupOffset>>2,1)}};var T0=Symbol.for("hardwarejs.mountProvider.registry.v1"),SG=globalThis[T0]??(globalThis[T0]={brand:Symbol("hardwarejs.mountProvider.v1")}),Y0=SG.brand;function Wr(t,e){if(t===null||typeof t!="object")throw new TypeError("defineMountProvider: a mount provider must be an object");if(typeof e?.kind!="string"||e.kind==="")throw new TypeError("defineMountProvider: record.kind is required");if(typeof e?.origin!="string"||e.origin==="")throw new TypeError("defineMountProvider: record.origin is required");return Object.defineProperty(t,Y0,{value:Object.freeze({...e}),enumerable:!1,writable:!1,configurable:!1}),t}o(Wr,"defineMountProvider");function fa(t){if(!(t===null||typeof t!="object"))return t[Y0]}o(fa,"mountProviderOf");function kG(t){return typeof t!="string"||t===""?!1:t.split(/\s+/).some(e=>e==="prestrike.rootfs=virtiofs")}o(kG,"cmdlineDeclaresVirtiofsRoot");function C0(t){if(!kG(t.cmdline))return;let e=` Get a root from a provider: Node tests/gates \u2014 hardwarejs/src/guest-root.mjs createTempGuestRoot({ "/bin/sh": bytes, ... }) builds a rootfs in a temp directory at test time and removes it afterwards; or openHostDirGuestRoot("/path/to/rootfs") mounts a directory that already exists (a distro build/cloud-rootfs, say). Browser \u2014 the guest root arrives as a capability port, not as a client in the image: frame/machine/fs-capability.ts turns the granted MessagePort into a TunnelFsView, which src/devices/ fs-tunnel.ts brands with this very provider record. NOT prestrike.rootfs=brintosfs. That spelling was here until 2026-08-30 and never named a root this kernel could mount: wasm32_rootfs_kind() (arch/wasm32/kernel/init.c) accepts exactly 'virtiofs', 'nfs' and 'ext4' and refuses everything else BY NAME, so a reader who followed this text landed on a kernel refusal one layer further down than the one they started with. It described an in-guest brintos-fs that no longer exists either: the client moved to the app origin because a filesystem client baked into an image can never be updated. Rationale and the divergences this mount does NOT reproduce: docs/hwjs/HOST-DIRECTORY-GUEST-ROOT.md`;if(t.fsView===void 0||t.fsView===null)throw new Error(`bootKernel: the cmdline declares a virtio-fs guest root (prestrike.rootfs=virtiofs) but no virtioFs was supplied, so the guest would panic mounting a device that does not exist. `+e);let n=fa(t.fsView);if(n===void 0)throw new Error(`bootKernel: refusing to boot a virtio-fs guest ROOT off an unregistered filesystem. The object passed as virtioFs.fs was not minted by a mount provider \u2014 it is a filesystem this tree has invented on the spot, and a guest booted on one proves nothing about a guest booted on a real root: it cannot hold a dynamic libc, a symlink, an executable image tree, or anything execve() has to open. `+e);return n}o(C0,"requireRegisteredGuestRoot");async function bu(t){if(Object.prototype.hasOwnProperty.call(t,"initramfs"))throw new Error("bootKernel: initramfs is unsupported; supply the selected root filesystem device.");let e=(t.cmdline??"").split(/\s+/).filter(le=>le.startsWith("prestrike.rootfs="));if(e.length!==1||!["prestrike.rootfs=virtiofs","prestrike.rootfs=ext4","prestrike.rootfs=nfs"].includes(e[0]))throw new Error("bootKernel: exactly one supported prestrike.rootfs= selection is required (virtiofs, ext4 or nfs); no fallback root.");if(e[0]==="prestrike.rootfs=ext4"&&!t.virtioBlk)throw new Error("bootKernel: ext4 root selected without a virtio block device; no fallback root.");let n=Td();if(!n.ok)throw new Error(`bootKernel: ${n.message}`);let s=C0({cmdline:t.cmdline,fsView:t.virtioFs?.fs});s!==void 0&&t.onDmesg?.(6,`hwjs-root: guest root served by mount provider "${s.kind}" <- ${s.origin}`+(s.note?` (${s.note})`:"")+` `);let r=t.platform??VG(),i=t.ram.kernelMemory,l=Ua(t.num_vcpu),d=l;{let le=t.spawnHandler?.poolStats?.(),Gt=le?.enabled&&le.poolSize>0?le.poolSize|0:l-1;t.onDmesg?.(6,`hwjs-lanes: kernel CPUs 0..${d-1} \u2014 CPU 0 is the kthread CPU, pool lanes 1..${Gt}. No dedicated-Worker lane band (the reserve was retired; threads are pool residents). A dedicated cpu id \u2014 a lane-0 thread, or the no-pool legacy path \u2014 is allocated top-down from within the pool range and shares that lane. Which OS threads the host spends on these is the hwjs-realms line, measured after the realms exist. `)}if(t.spawnHandler){let le=t.spawnHandler.poolStats?.();if(le?.enabled&&le.poolSize>l-1)throw new Error(`bootKernel: vCPU topology mismatch \u2014 the supplied spawnHandler has a pool of ${le.poolSize} CPU-Workers (cpu_ids 1..${le.poolSize}) but num_vcpu=${l} tells the kernel only CPUs 0..${l-1} exist. A pool Worker on a CPU the kernel considers impossible reads __per_cpu_offset==0 and corrupts memory through garbage per-CPU pointers (linux-in-the-browser#61). Pass consistent values: bootKernel({ num_vcpu: N }) with makeKernelSpawnHandler({ maxCpuId: N - 1 }).`);t.spawnHandler.__setLaneCeiling?.(d-1)}let a=await xG(),c=Bo(a)!==void 0;if(t.onDmesg?.(6,`hwjs-realms: CPU 0 is ${c?"a host Worker realm":"an INLINE realm in the launching thread \u2014 no Worker"} (measured: the realm census ${c?"counted it":"does not hold it"}). Whole-machine expectation for num_vcpu=${d}: ${Ma(d)} realm(s), checked against the live census on the hwjs-realms line below. `),c)throw new Error("bootKernel: CPU 0 took a host Worker realm (the census holds the realm createWorker returned). CPU 0 and pool lane 1 share the thread that called bootKernel \u2014 that is the only topology this runtime has \u2014 so this is an internal defect in createWorker, not a configuration error, and the machine it would produce has a lane 1 bound in the launching thread while CPU 0 blocks a Worker's.");let h=t.pauseBuffer??new SharedArrayBuffer(4),p=new Int32Array(h),m=[],y=[],b,f,I,R,X,F,N,K,k,U=[],M,H,Ge,C=[],Ie,B,ae=[],Ce,Q,$=[],_e,pe,Ut=[],rt,we,Qe=[],It,Ct,Mt=[],At,q,_=[],D,ue=0,x=0,ie=!1,ee,P,E,J=i.buffer.byteLength,re=!!(globalThis.process?.env?.HWJS_MERGED_NO_SYNC_DRAIN||globalThis.HWJS_MERGED_NO_SYNC_DRAIN),Xe=o(()=>{if(!re){if(Ct!==void 0){let le=2*((Ct.maxNrPorts|0)+1);for(let Gt=0;Gt{if(le?.kind==="virtio-drain-sync")return $m(),!0},"hostSyncCall");a.setHostSyncCall?.(Ae),t.spawnHandler?.__setHostSyncCall?.(Ae);let Ve=o(()=>{if(ee!==void 0||k===void 0&&Ge===void 0&&Q===void 0&&pe===void 0&&P===void 0||b===void 0)return;let le=b>>2,Gt=P!==void 0?P>>2:void 0;ee=setInterval(()=>{try{let Re=new Int32Array(i.buffer);Gt!==void 0&&Atomics.add(Re,Gt,1),Atomics.add(Re,le,1),Atomics.notify(Re,le,1),t.ram.publishUserSabPages()}catch{}},12)},"armSchedNudge"),me=o(()=>{if(!(k||!t.virtioBlk||K===void 0||H===void 0||b===void 0)){k=new ra({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:K,irqPendingOffset:H,schedWakeupOffset:b,disk:t.virtioBlk.disk,suppressIrq:t.virtioBlk.suppressIrq,onError:o(le=>t.onDmesg?.(3,`[virtio-blk-backend] ${le.message}`),"onError")});for(let le of U)k.onKick(le);U.length=0,Ve()}},"maybeStartVirtioBlkBackend"),je=o(()=>{if(!(Ge!==void 0||t.virtioFs===void 0||M===void 0||H===void 0||b===void 0)){Ge=new Ki({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:M,irqPendingOffset:H,schedWakeupOffset:b,fs:t.virtioFs.fs,suppressIrq:t.virtioFs.suppressIrq,onError:o(le=>t.onDmesg?.(3,`[virtio-fs-backend] ${le.message}`),"onError")});for(let le of C)Ge.onKick(le);C.length=0,Ve()}},"maybeStartVirtioBackend"),de=o(()=>{if(!(B!==void 0||t.virtioFsCache===void 0||Ie===void 0||H===void 0||b===void 0)){B=new Ki({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:Ie,irqPendingOffset:H,schedWakeupOffset:b,fs:t.virtioFsCache.fs,suppressIrq:t.virtioFsCache.suppressIrq,irqBit:5,onError:o(le=>t.onDmesg?.(3,`[virtio-fs-cache-backend] ${le.message}`),"onError")});for(let le of ae)B.onKick(le);ae.length=0,Ve()}},"maybeStartVirtioFsCacheBackend"),ve=o(()=>{if(Q!==void 0||t.virtioInput===void 0||Ce===void 0||H===void 0||b===void 0)return;Q=new oa({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:Ce,irqPendingOffset:H,schedWakeupOffset:b,irqBit:1,suppressIrq:t.virtioInput.suppressIrq,onError:o(Gt=>t.onDmesg?.(3,`[virtio-input-backend] ${Gt.message}`),"onError"),...globalThis.process?.env?.HWJS_INPUT_DBG||globalThis.HWJS_INPUT_DBG?{onDebug:o(Gt=>t.onDmesg?.(7,`[virtio-input] ${Gt}`),"onDebug")}:{}});for(let Gt of $)Q.onKick(Gt);$.length=0,Ve();let le=Q;t.onInputReady?.((Gt,Re,Rt)=>le.injectEvent(Gt,Re,Rt))},"maybeStartVirtioInputBackend"),A=o(()=>{if(!(pe!==void 0||t.virtioNet===void 0||_e===void 0||H===void 0||b===void 0)){pe=new ua({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:_e,irqPendingOffset:H,schedWakeupOffset:b,irqBit:2,suppressIrq:t.virtioNet.suppressIrq,...t.virtioNet.mtu!==void 0?{mtu:t.virtioNet.mtu}:{},...t.virtioNet.mergeRxBuf!==void 0?{mergeRxBuf:t.virtioNet.mergeRxBuf}:{},...t.virtioNet.link!==void 0?{link:t.virtioNet.link}:{},...t.virtioNet.fabric!==void 0?{fabric:t.virtioNet.fabric}:{},...t.virtioNet.fs!==void 0?{fs:t.virtioNet.fs}:{},...t.virtioNet.fetchImpl!==void 0?{fetchImpl:t.virtioNet.fetchImpl}:{},...t.virtioNet.httpPortMapping!==void 0?{httpPortMapping:t.virtioNet.httpPortMapping}:{},...t.virtioNet.gateway!==void 0?{gateway:t.virtioNet.gateway}:{},...t.virtioNet.naas!==void 0?{naas:t.virtioNet.naas}:{},...t.virtioNet.packetUplink!==void 0?{packetUplink:t.virtioNet.packetUplink}:{},onError:o(le=>t.onDmesg?.(3,`[virtio-net-backend] ${le.message}`),"onError"),onInfo:o(le=>t.onDmesg?.(6,`[virtio-net] ${le}`),"onInfo"),...globalThis.process?.env?.HWJS_NET_DBG||globalThis.HWJS_NET_DBG?{onDebug:o(le=>t.onDmesg?.(7,`[virtio-net] ${le}`),"onDebug")}:{}});for(let le of Ut)pe.onKick(le);Ut.length=0,Ve(),t.onNetReady?.(pe)}},"maybeStartVirtioNetBackend"),xe=o(()=>{if(!(we!==void 0||t.usbHcd===void 0||rt===void 0||H===void 0||b===void 0)){we=new ma({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:rt,irqPendingOffset:H,schedWakeupOffset:b,irqBit:3,suppressIrq:t.usbHcd.suppressIrq,onError:o(le=>t.onDmesg?.(3,`[usb-hcd-backend] ${le.message}`),"onError"),onEvent:o(le=>{t.onDmesg?.(le.kind==="attach"||le.kind==="detach"?6:4,`[usb-hcd] ${le.kind} port ${le.port}: ${le.detail}`),t.usbHcd?.onEvent?.(le)},"onEvent"),...globalThis.process?.env?.HWJS_USB_DBG||globalThis.HWJS_USB_DBG?{onDebug:o(le=>t.onDmesg?.(7,`[usb-hcd] ${le}`),"onDebug")}:{}});for(let le of Qe)we.onKick(le);Qe.length=0,Ve(),t.onUsbReady?.(we)}},"maybeStartUsbHcdBackend"),Oe=o(()=>{if(!(Ct!==void 0||t.virtioConsole===void 0||It===void 0||H===void 0||b===void 0)){Ct=new ha({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:It,irqPendingOffset:H,schedWakeupOffset:b,irqBit:4,...t.virtioConsole.ports?{ports:t.virtioConsole.ports}:{},...t.virtioConsole.suppressIrq?{suppressIrq:!0}:{},onError:o(le=>t.onDmesg?.(3,`[virtio-console] ${le.message}`),"onError"),onInfo:o(le=>t.onDmesg?.(6,`[virtio-console] ${le}`),"onInfo"),...globalThis.process?.env?.HWJS_VIRTCON_DBG||globalThis.HWJS_VIRTCON_DBG?{onDebug:o(le=>t.onDmesg?.(7,`[virtio-console] ${le}`),"onDebug")}:{}});for(let le of Mt)Ct.onKick(le);Mt.length=0,Ve(),t.onConsolePortsReady?.(Ct)}},"maybeStartVirtioConsoleBackend"),it=o(()=>{if(!(q!==void 0||t.hostTransport===void 0||At===void 0||H===void 0||b===void 0)){q=new pa({kernelMemory:i.buffer,kernelMemoryWasm:i,windowBase:At,irqPendingOffset:H,schedWakeupOffset:b,irqBit:6,...t.hostTransport.handler?{handler:t.hostTransport.handler}:{},...t.hostTransport.suppressIrq?{suppressIrq:!0}:{},onError:o(le=>t.onDmesg?.(3,`[hosttrans] ${le.message}`),"onError"),onInfo:o(le=>t.onDmesg?.(6,`[hosttrans] ${le}`),"onInfo")}),q.attach();for(let le of _)q.onKick(le);_.length=0,Ve(),t.onHostTransportReady?.(q)}},"maybeStartHostTransBackend"),Zt=o(()=>{if(ie||t.onDisplayControl===void 0||D===void 0||D===0||b===void 0)return;ie=!0;let le=D,Gt=b;t.onDisplayControl({setMode:o((Re,Rt)=>{let rn=Math.max(16,Math.min(ue||65535,Re|0)),On=Math.max(16,Math.min(x||65535,Rt|0));try{let gs=new Int32Array(i.buffer);Atomics.store(gs,le>>2,On<<16|rn|0),Atomics.add(gs,le+8>>2,1),hu(i.buffer,Gt)}catch{}},"setMode")})},"maybeFireDisplayControl"),Xt=t.signalHandler===void 0?t.signalRegistry??Ho():void 0,kt=-38,Ot,gt=t.vmlinuxModule,at;try{if(gt===void 0){if(t.wasmBytes===void 0)throw new Error("bootKernel: neither `wasmBytes` nor `vmlinuxModule` was supplied \u2014 there is no kernel image to boot (never-silent).");gt=await WebAssembly.compile(t.wasmBytes)}}catch(le){at=le instanceof Error?le.message:String(le),console.warn(`[hardwarejs] bootKernel: K11-B2a vmlinux WebAssembly.compile failed: ${at}. This Module is what the kernel Worker boots, so the boot below will refuse; the K11-A1 substrate probe should have caught this at boot-prep time.`)}let un;if(gt!==void 0&&(un=await na(gt),un===void 0&&console.log("[hardwarejs] bootKernel: vmlinux carries no hwjs.rt.so section \u2014 dynamic mains will use main-linked runtimes")),t.spawnHandler)un!==void 0&&t.spawnHandler.carriesHwjsRt!==!0&&console.warn('[hardwarejs] bootKernel: kernel provides a hwjs runtime but you supplied your own spawnHandler \u2014 bootKernel cannot inject it. Pass hwjsRtModule/hwjsRtBytes/hwjsRtProvenance (from extractHwjsRt(vmlinuxModule)) to makeKernelSpawnHandler, or dynamic mains will fail at exec with "kernel ships no libhwjs-rt".'),Ot=t.spawnHandler;else if(t.userWorkerEntry)Ot=ta({...t.spawnHandlerOptions??{},kernelMemory:i.buffer,ram:t.ram,workerEntry:t.userWorkerEntry,platform:r,...Xt!==void 0?{signalRegistry:Xt}:{},...gt!==void 0?{vmlinuxModule:gt}:{},...un!==void 0?{hwjsRtModule:un.module,hwjsRtBytes:un.bytes,hwjsRtProvenance:un.provenance.raw}:{},kernelMemoryWasm:i,pauseBuffer:h,maxCpuId:l-1,laneCeiling:d-1,onDmesg:o((le,Gt,Re)=>{m.push({level:le|0,text:String(Gt)}),t.onDmesg?.(le|0,String(Gt))},"onDmesg")});else{let le=!1;Ot=o(async Gt=>(le||(le=!0,console.warn("[hardwarejs] bootKernel: kernel issued a spawn-ring request but no spawnHandler / userWorkerEntry was supplied. Returning -ENOSYS; the kernel will fail to launch userspace and either fall through to its /init iteration or park. To fix: pass either { spawnHandler: makeKernelSpawnHandler({...}) } or { userWorkerEntry: '...path/to/worker-{node,browser}.mjs' }.")),kt),"effectiveSpawnHandler")}let xn,zn=new Promise(le=>{xn=le;let Gt=!1;BG(a,Re=>{switch(Re?.kind){case"dmesg":m.push({level:Re.level|0,text:String(Re.text)}),t.onDmesg?.(Re.level|0,String(Re.text));return;case"unimplemented-host-call":y.push(String(Re.name));return;case"sched-wakeup-word-offset":b=(Re.offset|0)>>>0,me(),je(),ve(),A(),Oe(),Zt(),Ve();return;case"user-sab-pages-offset":t.ram.attachUserSabPagesWord(i.buffer,(Re.offset|0)>>>0);return;case"committed-pages-offset":E=(Re.offset|0)>>>0;return;case"kernel-mem-grown":J=Number(Re.bytes)||J,t.onKernelMemoryGrown?.(J),t.onDmesg?.(6,`[hardwarejs] env.kernel_memory committed ${(J/(1024*1024)).toFixed(0)} MiB of ${(t.ram.opts.kernelBytes/(1024*1024)).toFixed(0)} MiB`);return;case"tick-req-offset":P=(Re.offset|0)>>>0,Ve();return;case"virtio-blk-window":K=(Re.base|0)>>>0,me();return;case"virtio-window":M=(Re.base|0)>>>0,je();return;case"virtio-fs-cache-window":Ie=(Re.base|0)>>>0,de();return;case"virtio-input-window":Ce=(Re.base|0)>>>0,ve();return;case"virtio-net-window":_e=(Re.base|0)>>>0,A();return;case"usb-window":rt=(Re.base|0)>>>0,xe();return;case"virtio-console-window":It=(Re.base|0)>>>0,Oe();return;case"hosttrans-window":At=(Re.base|0)>>>0,it();return;case"virtio-irq-pending-offset":H=(Re.offset|0)>>>0,me(),je(),de(),ve(),A(),xe(),Oe(),it();return;case"virtio-kick":(Re.devid|0)===7?k?k.onKick(Re.qidx|0):U.push(Re.qidx|0):(Re.devid|0)===6?q!==void 0?q.onKick(Re.qidx|0):_.push(Re.qidx|0):(Re.devid|0)===5?B!==void 0?B.onKick(Re.qidx|0):ae.push(Re.qidx|0):(Re.devid|0)===4?Ct!==void 0?Ct.onKick(Re.qidx|0):Mt.push(Re.qidx|0):(Re.devid|0)===3?we!==void 0?we.onKick(Re.qidx|0):Qe.push(Re.qidx|0):(Re.devid|0)===2?pe!==void 0?pe.onKick(Re.qidx|0):Ut.push(Re.qidx|0):(Re.devid|0)===1?Q!==void 0?Q.onKick(Re.qidx|0):$.push(Re.qidx|0):Ge!==void 0?Ge.onKick(Re.qidx|0):C.push(Re.qidx|0);return;case"fb-window":D=(Re.ctrlOffset|0)>>>0,ue=Re.maxWidth|0,x=Re.maxHeight|0,t.onFbWindow?.({base:(Re.base|0)>>>0,width:Re.width|0,height:Re.height|0,stride:Re.stride|0,size:Re.size|0,format:String(Re.format),maxWidth:ue,maxHeight:x,ctrlOffset:D}),Zt();return;case"signal-ring-offset":if(R===void 0){R=(Re.offset|0)>>>0;let Rt=t.signalHandler??Ud({registry:Xt});X=new sa({kernelMemory:i.buffer,ringOffset:R,handler:Rt,onProcessed:t.onSignalProcessed,onError:o(rn=>{let On=rn instanceof Error?rn.message:String(rn);t.onDmesg?.(3,`[signal-ring-consumer] handler/loop error: ${On}`)},"onError")}),X.start()}return;case"spawn-ring-offset":f===void 0&&(f=(Re.offset|0)>>>0,I=new No({kernelMemory:i.buffer,ringOffset:f,handler:Ot,onProcessed:o((Rt,rn)=>{try{Ot.wakeTaskByPid?.(Rt.parentTid>>>0)}catch{}t.onSpawnProcessed?.(Rt,rn)},"onProcessed"),onError:o(Rt=>{let rn=Rt instanceof Error?Rt.message:String(Rt);t.onDmesg?.(3,`[spawn-ring-consumer] handler/loop error: ${rn}`)},"onError")}),I.start());return;case"pty-bridge-ring-offset":F===void 0&&(F=(Re.offset|0)>>>0,t.onPtyBridgeRingOffset?.(F));return;case"serial-bridge-ring-offset":N===void 0&&(N=(Re.offset|0)>>>0,t.onSerialBridgeRingOffset?.(N));return;case"pre-start":Gt=!0;{let Rt=[],rn=[];(t.virtioConsole!==void 0?Ct!==void 0?Rt:rn:Rt).push("virtio-console"),Ge!==void 0&&Rt.push("virtio-fs"),pe!==void 0&&Rt.push("virtio-net"),Q!==void 0&&Rt.push("virtio-input"),we!==void 0&&Rt.push("usb-hcd"),rn.length>0&&t.onDmesg?.(4,`hwjs-merged: answering devices-ready with ${rn.join(", ")} DECLARED BUT NOT BUILT. A merged guest that reaches an in-kernel busy-wait on one of those holds the only thread that could build it.`),E0(a,{kind:"devices-ready",built:Rt.join(",")||"none",missing:rn.join(",")||"none"})}{let Rt=To(),rn=Ma(d),On=Object.entries(Rt.liveByOrigin).filter(([,gs])=>gs>0).map(([gs,Is])=>`${gs}=${Is}`).join(", ")||"none";t.onDmesg?.(Rt.live===rn?6:4,`hwjs-realms: host Worker realms live=${Rt.live} [${On}], expected ${rn} for num_vcpu=${d} \u2014 `+(Rt.live===rn?"AGREES.":"DISAGREES. One of the two is wrong: either a realm was constructed outside the topology (read the origin breakdown \u2014 it names the call site) or the merge did not take effect where it was reported to.")+` created=${Rt.created} terminated=${Rt.terminated} peak=${Rt.peakLive}. This line is a MEASUREMENT; anything that states a realm count without reading this census is stating a prediction. `)}return;case"returned":le({kind:"returned",message:String(Re.message)});return;case"kernel-trap":le({kind:"kernel-trap",message:String(Re.message)});return;case"link-error":le({kind:"link-error",missing:Re.missing});return;case"instantiate-error":le({kind:"instantiate-error",message:String(Re.message)});return;case"ctors-trap":le({kind:"ctors-trap",message:String(Re.message)});return;case"no-entry":le({kind:"no-entry",message:String(Re.message)});return;case"error":le({kind:"error",message:String(Re.message)});return}}),TG(a,Re=>{let Rt=Re instanceof Error?Re.message:String(Re),rn=Re instanceof Error&&Re.stack?` KERNEL-TRAP-STACK: `+Re.stack.split(` `).slice(0,24).join(" | "):"";le({kind:"error",message:Rt+rn})})});E0(a,{kind:"boot",vmlinuxModule:gt,vmlinuxCompileError:at,kernelMemory:i,kernelImports:t.kernelImports??{},cmdline:t.cmdline??"",bootInfoOverride:t.bootInfoOverride,declaredMemoryBytes:t.ram.opts.declaredMemoryBytes,kernelMaxBytes:t.ram.opts.kernelMaxBytes,virtioBlk:t.virtioBlk?{size:t.virtioBlk.disk.size,readOnly:!!t.virtioBlk.disk.readOnly}:void 0,virtioFs:t.virtioFs!==void 0,virtioFsCache:t.virtioFsCache!==void 0,framebuffer:t.framebuffer!==void 0?{width:t.framebuffer.width??0,height:t.framebuffer.height??0,maxWidth:t.framebuffer.maxWidth??0,maxHeight:t.framebuffer.maxHeight??0,suppressHotplug:t.framebuffer.suppressHotplug===!0,resizeGateTimeoutMs:t.framebuffer.resizeGateTimeoutMs??0}:void 0,virtioInput:t.virtioInput!==void 0?{absolutePointer:t.virtioInput.absolutePointer===!0}:void 0,virtioNet:t.virtioNet!==void 0?{mtu:t.virtioNet.mtu??0,mergeRxBuf:t.virtioNet.mergeRxBuf===!0}:void 0,usbHcd:t.usbHcd!==void 0,virtioConsole:t.virtioConsole!==void 0?{maxNrPorts:Math.max(...(t.virtioConsole.ports??[{id:1}]).map(le=>le.id))+1}:void 0,hostTransport:t.hostTransport!==void 0,numCpus:d,pauseBuffer:h});let jn=o(()=>{Atomics.store(p,0,1),ee!==void 0&&(clearInterval(ee),ee=void 0)},"pause"),jt=o(()=>{Atomics.store(p,0,0),Atomics.notify(p,0),Ve(),b!==void 0&&hu(i.buffer,b)},"resume"),Qs=o(()=>Atomics.load(p,0)===1,"isPaused"),_n=!1,Cs=o(async()=>{if(!_n){if(_n=!0,Atomics.store(p,0,0),Atomics.notify(p,0),ee!==void 0&&(clearInterval(ee),ee=void 0),I!==void 0)try{await I.stop()}catch{}if(X!==void 0)try{await X.stop()}catch{}await YG(a);try{await Ot.dispose?.()}catch{}}},"doTeardown"),Zs=o(async()=>{xn?.({kind:"returned",message:"host dispose()"}),await Cs()},"dispose");t.onControls?.({pause:jn,resume:jt,isPaused:Qs,dispose:Zs});let Et;if(t.watchdogMs&&t.watchdogMs>0){let le=new Promise(Gt=>{setTimeout(()=>Gt({kind:"watchdog",afterMs:t.watchdogMs}),t.watchdogMs)});Et=await Promise.race([zn,le])}else Et=await zn;if(Et.kind==="watchdog"){let le=`[hardwarejs] bootKernel WATCHDOG: machine lifetime cap watchdogMs=${Et.afterMs}ms reached \u2014 tearing down the kernel Worker + CPU pool NOW (the guest may still have been running; this is an absolute cap, not an inactivity watchdog). A driver still waiting on guest output past this point waits on a dead machine.`;m.push({level:0,text:le}),t.onDmesg?.(0,le),console.error(le)}return await Cs(),{dmesg:m,terminal:Et,unimplementedCalls:y,schedWakeupWordOffset:b,spawnRingOffset:f,signalRingOffset:R,ptyBridgeRingOffset:F,serialBridgeRingOffset:N}}o(bu,"bootKernel");function hu(t,e){if((e&3)!==0)throw new Error(`kickKernelScheduler: offset 0x${e.toString(16)} not 4-byte aligned`);let n=new Int32Array(t),s=e>>>2;Atomics.add(n,s,1),Atomics.notify(n,s,1)}o(hu,"kickKernelScheduler");function VG(){let t=globalThis;return typeof t.process<"u"&&t.process?.versions?.node?"node":"browser"}o(VG,"detectPlatform");async function xG(){let[{createInlineRealm:t},{bindKernelWorker:e}]=await Promise.all([Promise.resolve().then(()=>(Ld(),Md)),Promise.resolve().then(()=>(F0(),v0))]);return t(e,"kernel-inline")}o(xG,"createWorker");function E0(t,e){t.postMessage(e)}o(E0,"postToWorker");function BG(t,e){let n=t;typeof n.on=="function"?n.on("message",e):n.onmessage=s=>e(s.data)}o(BG,"onMessage");function TG(t,e){let n=t;typeof n.on=="function"?n.on("error",e):n.onerror=s=>e(s.error??s.message)}o(TG,"onError");async function YG(t){Ha(t);let e=t;try{if(typeof e.terminate=="function"){let n=e.terminate();n&&typeof n.then=="function"&&await n}}catch{}}o(YG,"terminateWorker");var QS=Promise.resolve();var Fl=5,CG=11,En=22;var NG=38,HG=125,El=1;var vl="posix",vG=4026531839,$i=4026531840;var sk=1<<17,FG=1<<20,EG=1<<20,_G=255,JG=4096;var UG=8,MG=4<<20,LG=64,_0=512,J0=15e3,PG=3e4;var U0={getattr:{args:["ino"],mutates:!1},lookup:{args:["ino","name"],mutates:!1},readdir:{args:["ino"],mutates:!1},read:{args:["ino","offset","readlen"],mutates:!1},readlink:{args:["ino"],mutates:!1},statfs:{args:[],mutates:!1},write:{args:["ino","offset","bytes"],mutates:!0},create:{args:["ino","name","mode"],mutates:!0},mkdir:{args:["ino","name","mode"],mutates:!0},unlink:{args:["ino","name","flag"],mutates:!0},rename:{args:["ino","name","ino","name"],mutates:!0},setattr:{args:["ino","attrs"],mutates:!0},symlink:{args:["ino","name","target"],mutates:!0},link:{args:["ino","name","ino"],mutates:!0},mknod:{args:["ino","name","mode","mode"],mutates:!0},fsync:{args:["ino","flag"],mutates:!0},setlk:{args:["ino","owner","mode"],mutates:!0},releaselk:{args:["ino","owner"],mutates:!0},forget:{args:["ino","count"],mutates:!1}};var ur=class extends Error{static{o(this,"FsTunnelFault")}code;errno;constructor(e,n,s=Fl){super(`fs-tunnel: ${n}`),this.name="FsTunnelFault",this.code=e,this.errno=s}};function cn(t,e){let n=new Error(`fs-tunnel: ${e}`);return n.errno=t,n}o(cn,"refuse");function Wn(t){if(typeof t=="string"){let e=t.length>64?`${t.slice(0,64)}...`:t;return JSON.stringify(e)}return typeof t=="bigint"?`${t}n`:t instanceof Uint8Array?`Uint8Array(${t.byteLength})`:typeof t=="object"&&t!==null?`${t.constructor?.name??"object"}{${Object.keys(t).join(",")}}`:String(t)}o(Wn,"show");function AG(t){return typeof t=="object"&&t!==null&&t.fstun===1&&typeof t.t=="string"}o(AG,"isFrame");function P0(t,e){if(!(t.buffer instanceof ArrayBuffer))throw cn(En,`${e} is backed by shared memory, which cannot cross this boundary (the two ends are cross-origin isolated, so they are in different agent clusters and the far end would fail to deserialize it \u2014 which presents as a hang, not an error). Pass unshared bytes.`)}o(P0,"requireUnsharedBytes");function KG(t,e){P0(t,e);let n=new Uint8Array(t);return{bytes:n,transfer:[n.buffer]}}o(KG,"forWire");var zG={maxReadBytes:FG,maxWriteBytes:EG,maxNameBytes:_G,maxLinkBytes:JG},M0=["size","mode","mtimeSec","uid","gid"];function jG(t,e,n,s,r){let i=`${n} argument ${s}`;switch(t){case"ino":if(!Number.isSafeInteger(e)||e<1)throw cn(En,`${i} is not an inode: ${Wn(e)}`);return;case"name":{if(typeof e!="string"||e.length===0)throw cn(En,`${i} is not a name: ${Wn(e)}`);if(e.includes("/"))throw cn(En,`${i} is a path, not a directory entry: ${Wn(e)}. A caller may name one component relative to an inode it already holds.`);if(e.includes("\0"))throw cn(En,`${i} contains a NUL: ${Wn(e)}`);if(e==="."||e==="..")throw cn(En,`${i} is ${Wn(e)}, which names a directory this caller was not given. Refused rather than resolved: normalizing here is how a traversal becomes a silent success.`);if(L0(e)>r.maxNameBytes)throw cn(En,`${i} is longer than ${r.maxNameBytes} bytes`);return}case"target":{if(typeof e!="string"||e.length===0)throw cn(En,`${i} is not a link target: ${Wn(e)}`);if(e.includes("\0"))throw cn(En,`${i} contains a NUL: ${Wn(e)}`);if(L0(e)>r.maxLinkBytes)throw cn(En,`${i} is longer than ${r.maxLinkBytes} bytes`);return}case"offset":if(!Number.isSafeInteger(e)||e<0)throw cn(En,`${i} is not an offset: ${Wn(e)}`);return;case"readlen":if(!Number.isSafeInteger(e)||e<0)throw cn(En,`${i} is not a length: ${Wn(e)}`);if(e>r.maxReadBytes)throw cn(En,`${i} asks for ${e} bytes; this capability serves at most ${r.maxReadBytes} in one call`);return;case"mode":if(!Number.isSafeInteger(e)||e<0)throw cn(En,`${i} is not a mode/flag word: ${Wn(e)}`);return;case"count":if(!Number.isSafeInteger(e)||e<0)throw cn(En,`${i} is not a count: ${Wn(e)}`);return;case"flag":if(typeof e!="boolean")throw cn(En,`${i} is not a boolean: ${Wn(e)}`);return;case"owner":if(typeof e!="bigint")throw cn(En,`${i} is not a lock owner: ${Wn(e)}`);return;case"bytes":{if(!(e instanceof Uint8Array))throw cn(En,`${i} is not bytes: ${Wn(e)}`);if(P0(e,i),e.byteLength>r.maxWriteBytes)throw cn(En,`${i} is ${e.byteLength} bytes; this capability accepts at most ${r.maxWriteBytes} in one call`);return}case"attrs":{if(typeof e!="object"||e===null||Array.isArray(e))throw cn(En,`${i} is not an attribute set: ${Wn(e)}`);for(let[l,d]of Object.entries(e)){if(!M0.includes(l))throw cn(En,`${i} carries the field ${Wn(l)}, which is not a settable attribute (${M0.join(", ")})`);if(!Number.isSafeInteger(d)||d<0)throw cn(En,`${i}.${l} is not a number: ${Wn(d)}`)}return}default:throw cn(En,`${i} has no validator for kind ${Wn(t)}`)}}o(jG,"checkArg");function OG(t){return!Number.isSafeInteger(t)||t<1?`inode ${Wn(t)} is not an inode: they are positive integers and 1 is the root`:t>4294967295?`inode ${t} does not fit in 32 bits. This architecture's st_ino is an unsigned long, which is 32 bits, and the kernel answers EOVERFLOW rather than narrowing \u2014 so this would not collide, it would make stat(2) fail on a file that is perfectly fine, with an errno nobody would connect to the number. Inodes on this wire are PER-MOUNT HANDLES and need not be the backing store's own identifiers: map them.`:t>=$i?`inode ${t} (0x${t.toString(16)}) is at or above 0x${$i.toString(16)}, which is reserved for the inodes the IMAGE synthesizes \u2014 /dev, /proc, /sys and /tmp are carved there, and the block above them is held for images that have not been built yet. Mint at or below 0x${vG.toString(16)}. Refused rather than passed on: a collision here is one directory answering to two names, and it would surface as a wrong file rather than as an error.`:null}o(OG,"inoOutOfRange");function L0(t){let e=0;for(let n of t){let s=n.codePointAt(0);e+=s<128?1:s<2048?2:s<65536?3:4}return e}o(L0,"byteLengthOf");function QG(t,e,n){if(typeof t!="string"||!Object.prototype.hasOwnProperty.call(U0,t))throw cn(NG,`no such method ${Wn(t)}. This capability serves an FsView and nothing else \u2014 there is no mount, no lookup by repository, and no control plane on this port.`);let s=U0[t];if(!Array.isArray(e)||e.length!==s.args.length)throw cn(En,`${t} takes ${s.args.length} arguments, got ${Array.isArray(e)?e.length:Wn(e)}`);for(let r=0;re(i.data),"msg"),r=o(()=>n(),"err");return t.addEventListener("message",s),t.addEventListener("messageerror",r),t.start?.(),()=>{t.removeEventListener("message",s),t.removeEventListener("messageerror",r)}}o(DG,"attach");function pu(t,e={}){let n=e.maxInFlight??UG,s=e.maxResidentBytes??MG,r=e.maxQueued??LG,i=e.callDeadlineMs??PG,l=e.setTimer??((c,h)=>setTimeout(c,h)),d=e.clearTimer??(c=>clearTimeout(c)),a=e.onNotice??(c=>{console.warn(c)});return new Promise((c,h)=>{let p=!1,m=!1,y=null,b=1,f=0,I=0,R=new Map,X=[],F={...zG},N=o(()=>{},"stop"),K=l(()=>{k(new ur("local",`the far end did not answer within ${e.handshakeDeadlineMs??J0} ms. A healthy round trip on this seam is tens of microseconds, so this is a capability that is not connected to anything.`))},e.handshakeDeadlineMs??J0);function k(B,ae=!0){if(y)return;if(y=B,d(K),ae)try{t.postMessage({fstun:1,t:"fault",code:B.code,why:B.message})}catch{}N();try{t.close?.()}catch{}let Ce=[...R.values(),...X];R.clear(),X.length=0,f=0,I=0;for(let Q of Ce)Q.reject(B);p||h(B),e.onLost?.(B)}o(k,"die");function U(){for(;X.length>0&&!y;){let B=X[0];if(f>=n||f>0&&I+B.cost>s)break;X.shift(),f++,I+=B.cost,R.set(B.id,B),M(B);try{t.postMessage({fstun:1,t:"call",id:B.id,m:B.m,a:B.a},B.transfer)}catch(ae){Ge(B.id),B.reject(cn(Fl,`could not post ${B.m}: ${ae?.message??String(ae)}`))}}}o(U,"pump");function M(B){B.timer!==void 0&&(d(B.timer),B.waited=(B.waited??0)+i),B.timer=l(()=>{if(B.timer=void 0,!R.has(B.id))return;let ae=(B.waited??0)+i;Ge(B.id),B.reject(cn(Fl,`${B.m} went unanswered for ${ae}ms and the far end gave no sign of life in that time \u2014 no reply, no progress, no fault. This is not a slow filesystem: a far end that is working says so and may take as long as it needs. Failing this call rather than waiting forever, because a hang is the one answer this seam never gives.`)),a(`fs-tunnel: ${B.m} (id ${B.id}) timed out after ${ae}ms with no progress from the far end`),U()},i)}o(M,"armDeadline");function H(B){let ae=o(Ce=>{if(Ce===null||typeof Ce!="object")return null;let Q=Ce.ino;return Q===void 0?null:OG(Q)},"one");if(Array.isArray(B)){for(let Ce of B){let Q=ae(Ce);if(Q)return Q}return null}return ae(B)}o(H,"replyInoError");function Ge(B){let ae=R.get(B);if(ae)return R.delete(B),ae.timer!==void 0&&(d(ae.timer),ae.timer=void 0),f--,I-=ae.cost,ae}o(Ge,"settle");function C(B,...ae){return new Promise((Ce,Q)=>{if(y){Q(y);return}let $;try{$=QG(B,ae,F)}catch(we){Q(we);return}let _e,pe=_0,Ut=$.args.indexOf("bytes");if(Ut>=0){let we=KG(ae[Ut],`${B} argument ${Ut}`);ae=ae.slice(),ae[Ut]=we.bytes,_e=we.transfer,pe=we.bytes.byteLength}let rt=$.args.indexOf("readlen");if(rt>=0&&(pe=Math.max(_0,ae[rt])),X.length>=r){Q(cn(CG,`${r} calls are already waiting for room on this tunnel; refusing ${B} rather than growing the queue. The far end has stopped answering or is slower than this caller.`));return}X.push({id:b++,m:B,a:ae,transfer:_e,cost:pe,resolve:Ce,reject:Q}),U()})}o(C,"call"),N=DG(t,B=>{if(!y){if(!AG(B)){k(new ur("protocol",`a frame arrived that is not of this protocol: ${Wn(B)}`));return}switch(B.t){case"hello":{if(p){k(new ur("protocol","a second opening frame arrived on a live tunnel"));return}B.p!==El&&a(`fs-tunnel: the far end announces format ${Wn(B.p)} and this end was built for ${El}. Proceeding on the frozen floor \u2014 every difference this end cannot read is one it is designed to ignore.`);let ae=B.profile===void 0?vl:B.profile;if(ae!==vl){k(new ur("protocol",`the far end serves the filesystem profile ${Wn(ae)} and this image only knows how to be a guest on ${Wn(vl)}. Refusing the mount rather than guessing at semantics: a profile names how names resolve, whether hard links exist and what a readdir cookie means, and every one of those is a question where a wrong guess writes to the wrong file. An image cannot be taught a new profile \u2014 serve this machine the ${Wn(vl)} profile, or give it a newer image.`));return}d(K),p=!0;try{t.postMessage({fstun:1,t:"open",p:El,callDeadlineMs:i})}catch{}F={...F,maxReadBytes:Math.min(F.maxReadBytes,B.limits?.maxReadBytes??F.maxReadBytes),maxWriteBytes:Math.min(F.maxWriteBytes,B.limits?.maxWriteBytes??F.maxWriteBytes)},c(Ie(B.crossContextLocks===!0,B.readOnly===!0,typeof B.label=="string"?B.label:""));return}case"reply":{let ae=Ge(B.id);if(!ae)return;if(B.ok){let Ce=H(B.v);if(Ce){a(`fs-tunnel: refusing an inode from the far end \u2014 ${Ce}`),ae.reject(cn(Fl,Ce)),U();return}ae.resolve(B.v)}else{let Ce=new Error(B.e?.message??"fs-tunnel: the far end refused");typeof B.e?.errno=="number"&&(Ce.errno=B.e.errno),ae.reject(Ce)}U();return}case"progress":{let ae=R.get(B.id);ae&&M(ae);return}case"fault":k(new ur(B.code,B.why),!1);return;case"release":k(new ur("released",B.why),!1);return;default:m||(m=!0,a(`fs-tunnel: the far end sent the frame type ${Wn(B.t)}, which this image predates. Ignoring it, and every later one, rather than dropping a working mount over a frame that asks nothing of this end.`));return}}},()=>{k(new ur("messageerror","a message from the far end could not be deserialized. Nothing in it identifies the call it answers, so the tunnel cannot be resynchronized and every outstanding call is refused. The usual cause is shared memory, which cannot cross two cross-origin isolated documents."))});function Ie(B,ae,Ce){return Wr({getattr:o($=>C("getattr",$),"getattr"),lookup:o(($,_e)=>C("lookup",$,_e),"lookup"),readdir:o($=>C("readdir",$),"readdir"),read:o(($,_e,pe)=>C("read",$,_e,pe),"read"),readlink:o($=>C("readlink",$),"readlink"),statfs:o(()=>C("statfs"),"statfs"),write:o(($,_e,pe)=>C("write",$,_e,pe),"write"),create:o(($,_e,pe)=>C("create",$,_e,pe),"create"),mkdir:o(($,_e,pe)=>C("mkdir",$,_e,pe),"mkdir"),unlink:o(($,_e,pe)=>C("unlink",$,_e,pe),"unlink"),rename:o(($,_e,pe,Ut)=>C("rename",$,_e,pe,Ut),"rename"),setattr:o(($,_e)=>C("setattr",$,_e),"setattr"),symlink:o(($,_e,pe)=>C("symlink",$,_e,pe),"symlink"),link:o(($,_e,pe)=>C("link",$,_e,pe),"link"),mknod:o(($,_e,pe,Ut)=>C("mknod",$,_e,pe,Ut),"mknod"),fsync:o(($,_e)=>C("fsync",$,_e),"fsync"),setlk:o(($,_e,pe)=>C("setlk",$,_e,pe),"setlk"),releaselk:o(($,_e)=>C("releaselk",$,_e),"releaselk"),forget:o(($,_e)=>{C("forget",$,_e).catch(pe=>{a(`fs-tunnel[${Ce}]: forget(${$}) was refused \u2014 ${pe?.message??String(pe)}`)})},"forget"),crossContextLocks:B,readOnly:ae,label:Ce,get lost(){return y!==null},get residentBytes(){return I},get inFlight(){return f},dispose($="the holder released this capability"){if(!y){for(let _e of R.keys())try{t.postMessage({fstun:1,t:"cancel",id:_e})}catch{}try{t.postMessage({fstun:1,t:"release",why:$})}catch{}k(new ur("local",$,HG),!1)}}},{kind:"fs-tunnel",origin:Ce?`capability port (${Ce})`:"capability port (unnamed by the far end)",note:ae?"read-only at the far end":void 0})}o(Ie,"buildView")})}o(pu,"openTunnelFsView");var Er=14;var hk=Er+0,bk=Er+2,pk=Er+4,fk=Er+5,yk=Er+8,Zk=Er+14,gk=Er+18,Ik=Er+24,Gk=Er+28;var eW=Object.freeze([10,99]);var qi={HELLO:1,HELLO_OK:2,PACKET:5,ERROR:8,REFRESH:11},tW=1,nW=8*1024*1024,sW=500,rW=3e4,ya=class{constructor(e){this.opts=e;let n=e.WebSocketCtor??globalThis.WebSocket;if(!n)throw new Error("WebSocketPacketNaasUplink: no WebSocket available");if(this.WsCtor=n,this.connect(),e.refreshIntervalMs&&e.refreshIntervalMs>0){this.refreshTimer=setInterval(()=>{this.refresh()},e.refreshIntervalMs);let s=this.refreshTimer;s.unref&&s.unref()}}opts;static{o(this,"WebSocketPacketNaasUplink")}ws=null;helloSent=!1;authorized=!1;closedByUs=!1;packetCb=o(()=>{},"packetCb");readyCb=o(()=>{},"readyCb");closeCb=o(()=>{},"closeCb");refreshTimer=null;WsCtor;wsGen=0;reconnectAttempt=0;reconnectTimer=null;inOutage=!1;txDropLogged=!1;sPktUp=0;sPktDown=0;sBytesUp=0;sBytesDown=0;sDrops=0;get ready(){return this.authorized}stats(){return{authorized:this.authorized,packetsUp:this.sPktUp,packetsDown:this.sPktDown,bytesUp:this.sBytesUp,bytesDown:this.sBytesDown,drops:this.sDrops}}onPacket(e){this.packetCb=e}onReady(e){this.readyCb=e,this.authorized&&e()}onClose(e){this.closeCb=e}send(e){let n=this.ws;if(!this.authorized||!n||n.readyState!==tW){this.txDropLogged||(this.txDropLogged=!0,this.info("L3 uplink: not connected \u2014 dropping guest egress until reconnect")),this.sDrops++;return}let s=n.bufferedAmount;if(s!==void 0&&s>nW){this.sDrops++;return}let r=new Uint8Array(1+e.length);r[0]=qi.PACKET,r.set(e,1);try{n.send(r),this.sPktUp++,this.sBytesUp+=e.length}catch{this.sDrops++}}close(){this.closedByUs=!0,this.refreshTimer&&clearInterval(this.refreshTimer),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.authorized=!1;try{this.ws?.close()}catch{}this.ws=null}connect(){let e=++this.wsGen;this.helloSent=!1;let n;try{n=new this.WsCtor(this.opts.url)}catch(d){this.info(`L3 uplink: connect failed: ${d instanceof Error?d.message:String(d)}`),this.ws=null,this.scheduleReconnect();return}n.binaryType="arraybuffer",this.ws=n;let s=o(()=>{this.onOpen(e)},"onOpen"),r=o(d=>{e===this.wsGen&&this.onMessage(d.data)},"onMessage"),i=o(()=>this.onSocketClose(e),"onClose"),l=o(()=>this.info("L3 uplink: WebSocket error"),"onError");n.addEventListener?(n.addEventListener("open",s),n.addEventListener("message",r),n.addEventListener("close",i),n.addEventListener("error",l)):(n.onopen=s,n.onmessage=r,n.onclose=i,n.onerror=l)}scheduleReconnect(){if(this.closedByUs||this.reconnectTimer)return;this.reconnectAttempt++;let e=Math.min(sW*2**(this.reconnectAttempt-1),rW),n=e/2+Math.random()*(e/2);this.info(`L3 uplink: reconnecting in ${(n/1e3).toFixed(1)}s (attempt ${this.reconnectAttempt})`),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,!this.closedByUs&&this.connect()},n);let s=this.reconnectTimer;s.unref&&s.unref()}async onOpen(e){if(e!==this.wsGen||this.closedByUs)return;let n;try{n=typeof this.opts.token=="function"?await this.opts.token():this.opts.token}catch(i){this.info(`L3 uplink: no token: ${i instanceof Error?i.message:String(i)}`),this.teardown("no token");try{this.ws?.close()}catch{}return}if(e!==this.wsGen||this.closedByUs)return;let s=new TextEncoder().encode(n),r=new Uint8Array(1+s.length);r[0]=qi.HELLO,r.set(s,1),this.rawSend(r),this.helloSent=!0}async refresh(){if(!(!this.authorized||typeof this.opts.token!="function"))try{let e=await this.opts.token(),n=new TextEncoder().encode(e),s=new Uint8Array(1+n.length);s[0]=qi.REFRESH,s.set(n,1),this.rawSend(s)}catch{}}onMessage(e){let n=null;if(e instanceof Uint8Array?n=e:e instanceof ArrayBuffer?n=new Uint8Array(e):ArrayBuffer.isView(e)&&(n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength)),!(!n||n.length<1))switch(n[0]){case qi.HELLO_OK:this.authorized=!0,this.reconnectAttempt=0,this.txDropLogged=!1,this.inOutage&&(this.inOutage=!1,this.info("L3 uplink: reconnected")),this.info("L3 uplink: authorized"),this.readyCb();break;case qi.PACKET:{let s=n.subarray(1);this.sPktDown++,this.sBytesDown+=s.length,this.packetCb(s);break}case qi.ERROR:this.info("L3 uplink: relay rejected the session"),this.teardown("relay error"),this.inOutage=!0;try{this.ws?.close()}catch{}break}}onSocketClose(e){e===this.wsGen&&(this.ws=null,!this.closedByUs&&(this.inOutage||this.info("L3 uplink: relay connection closed"),this.teardown("relay connection closed"),this.inOutage=!0,this.scheduleReconnect()))}teardown(e){!this.inOutage&&(this.authorized||this.helloSent)&&this.closeCb(e),this.authorized=!1}rawSend(e){try{this.ws?.send(e)}catch(n){this.info(`L3 uplink: send failed: ${n instanceof Error?n.message:String(n)}`)}}info(e){this.opts.onEvent?.(e)}};var iW=[{what:"process state (R/S/D/Z), ppid chains, comm, cwd, fds",why:"the kernel owns the process table in env.kernel_memory and the host does not walk it; tasks[] reports what a SPAWN saw, not what the process is doing now. Read /proc in the guest."},{what:"the boot image's pathname",why:"the spawn ring carries a scatter list and sizes and no pathname (spawn-ring-abi.ts struct wasm_spawn_request). Images installed by a later execve DO carry the path the guest passed."},{what:"whether any libhwjs-rt function was called",why:"rt is a wasm side module called wasm-to-wasm with no host frame in between \u2014 see hwjsRt.calledNote for what is observable instead."},{what:"guest MemTotal / MemFree",why:"the host allocates the SABs; only the guest knows what it did inside them. Run `free` or read /proc/meminfo in the machine's console."},{what:"per-process dlopen'd libraries, in this cheap poll",why:"the dlopen table lives in the owning Worker's run() closure, not on the host. probeWorkers() fetches it \u2014 as a request, with a timeout."}];function fu(t={}){let{handler:e,ram:n,boot:s,dmesg:r}=t,i=e?.poolStats,l=typeof i=="function"?i():null,d=typeof e?.laneCensus=="function"?e.laneCensus():null,a=typeof e?.taskCensus=="function"?e.taskCensus():null,c=typeof e?.sharedLibCensus=="function"?e.sharedLibCensus():null,h=null;if(n){let m=n.userMemoryStats();h={...m,kernelSabBytes:m.kernelPages*65536,liveUserSabBytes:m.livePages*65536,exitedUncollectedBytes:m.exitedUncollectedPages*65536}}let p=null;if(r){let m={};for(let y of r)m[y.level|0]=(m[y.level|0]??0)+1;p={total:r.length,byLevel:m,note:"printk suppresses below the kernel's compiled-in console_loglevel BEFORE the linux.dmesg host import runs, so a level absent here was never emitted to the host \u2014 not necessarily never recorded."}}return{takenAtIso:new Date().toISOString(),realms:To(),pool:l??null,lanes:d,tasks:a?a.tasks:null,tasksReapedBeyondRing:a?a.reapedBeyondRing:null,sharedLibs:c,memory:h,hwjsRt:{carriedBySpawnHandler:e?.carriesHwjsRt===!0,...s?.hwjsRtProvenance!==void 0?{provenance:s.hwjsRtProvenance}:{},...s?.hwjsRtByteLength!==void 0?{byteLength:s.hwjsRtByteLength}:{},calledNote:"NOT OBSERVABLE FROM THE HOST: libhwjs-rt is a wasm side module (process module #0) whose functions are called wasm-to-wasm and through the process's shared indirect function table, with no host frame in between. Counting calls would need the .so itself instrumented at kernel build time. Observable instead: whether the runtime was INSTANTIATED for a process (probeWorkers -> tasks[].hwjsRt) and whether an image IMPORTS it (tasks[].image.importsHwjsRt). Both are weaker than 'called'."},boot:s??null,dmesg:p,unobservable:iW.map(m=>({...m}))}}o(fu,"machineSnapshot");var qn={ACTIVE:0,PTN:4,READER_WAKE_OFF:8,ABI_VERSION:12,INJECT_HEAD:16,INJECT_TAIL:20,INJECT_CAP:24,DRAIN_HEAD:32,DRAIN_TAIL:36,DRAIN_NOTIFY:40,DRAIN_CAP:44,SCHED_WAKE_OFF:48,WINSIZE_REQ:52,WINSIZE_SEQ:56,WINSIZE_ACK:60,INJECT_BUF:64,DRAIN_BUF:8256};var oW=new TextEncoder,K0=new Uint8Array(0),aW=new TextDecoder("utf-8",{fatal:!1}),Za=class{static{o(this,"PtyBridge")}i32;u8;buf;wasm;base;ptn;rederives=0;constructor(e){if(this.base=e.ringOffset>>>0,(this.base&3)!==0)throw new Error(`PtyBridge: ring offset ${this.base} not 4-byte aligned`);this.wasm=e.kernelMemoryWasm,this.buf=e.kernelMemory,this.i32=new Int32Array(e.kernelMemory),this.u8=new Uint8Array(e.kernelMemory),this.ptn=(e.ptn??0)>>>0}live(){let e=this.wasm?.buffer;e===void 0||e===this.buf||(this.buf=e,this.i32=new Int32Array(e),this.u8=new Uint8Array(e),this.rederives++)}idx(e){return this.base+e>>>2}doorbellRefused={reader:!1,sched:!1};ringDoorbell(e,n,s){if(n===0)return!1;let r=n>>>2;return(n&3)!==0||r>=this.i32.length?(this.doorbellRefused[e]||(this.doorbellRefused[e]=!0,console.error(`PtyBridge: REFUSING the ${e} doorbell \u2014 published offset ${n} (index ${r}) is not addressable in guest RAM: the view is ${this.i32.length} words / ${this.i32.length*4} bytes, live kernel_memory is ${this.buf.byteLength} bytes (${this.rederives} grow(s) picked up), ringOffset=${this.base}. The view is LIVE, so this is not a stale snapshot \u2014 the ring header published something that is not a guest address. Input is still being delivered and the other doorbell still rings, so the terminal keeps working on the periodic sched nudge and will feel laggy. Reported once per doorbell.`)),!1):(Atomics.add(this.i32,r,1),Atomics.notify(this.i32,r,s),!0)}faulted=!1;abiVersion(){return this.live(),Atomics.load(this.i32,this.idx(qn.ABI_VERSION))>>>0}activate(){this.live();let e=this.abiVersion();if(e!==2){let n=e<2?`the KERNEL is stale (vmlinux.wasm predates ring ABI v${2}) \u2014 rebuild it`:`this HOST is stale (hardwarejs predates ring ABI v${e}) \u2014 rebuild hardwarejs and re-run hwjs:sync`;throw new Error(`PtyBridge: pty ring ABI mismatch \u2014 kernel published v${e}, host expects v${2}: ${n}. Refusing to attach: the halves disagree about the ring header, so terminal size (and anything else added past v1) would be silently wrong rather than visibly broken.`)}Atomics.store(this.i32,this.idx(qn.PTN),this.ptn|0),Atomics.store(this.i32,this.idx(qn.ACTIVE),1)}deactivate(){this.live(),Atomics.store(this.i32,this.idx(qn.ACTIVE),0)}setWinsize(e,n){this.live();let s=Math.trunc(e),r=Math.trunc(n);if(!Number.isFinite(s)||!Number.isFinite(r)||s<=0||r<=0)throw new Error(`PtyBridge.setWinsize: rows/cols must be positive integers, got ${e}x${n}`);if(s>65535||r>65535)throw new Error(`PtyBridge.setWinsize: ${s}x${r} exceeds the u16 winsize limit`);let i=((s&65535)<<16|r&65535)>>>0,l=this.idx(qn.WINSIZE_REQ);return Atomics.load(this.i32,l)>>>0===i?!1:(Atomics.store(this.i32,l,i|0),Atomics.add(this.i32,this.idx(qn.WINSIZE_SEQ),1),this.ringDoorbell("sched",Atomics.load(this.i32,this.idx(qn.SCHED_WAKE_OFF))>>>0,1/0),!0)}winsize(){this.live();let e=Atomics.load(this.i32,this.idx(qn.WINSIZE_REQ))>>>0;return e===0?null:{rows:e>>>16,cols:e&65535}}inject(e){this.live();let n=this.idx(qn.INJECT_HEAD),s=this.idx(qn.INJECT_TAIL),r=Atomics.load(this.i32,n)>>>0,i=Atomics.load(this.i32,s)>>>0,l=r-i>>>0,d=8192-l,a=Math.min(e.length,d),c=this.base+qn.INJECT_BUF;for(let h=0;h>>0|0),this.ringDoorbell("reader",Atomics.load(this.i32,this.idx(qn.READER_WAKE_OFF))>>>0,1),this.ringDoorbell("sched",Atomics.load(this.i32,this.idx(qn.SCHED_WAKE_OFF))>>>0,1/0),a}injectStr(e){return this.inject(oW.encode(e))}drainAvailable(){if(this.live(),this.faulted)return 0;let e=Atomics.load(this.i32,this.idx(qn.DRAIN_HEAD))>>>0,n=Atomics.load(this.i32,this.idx(qn.DRAIN_TAIL))>>>0,s=e-n>>>0;return s>8192?0:s}drain(){if(this.live(),this.faulted)return K0;let e=this.idx(qn.DRAIN_HEAD),n=this.idx(qn.DRAIN_TAIL),s=Atomics.load(this.i32,e)>>>0,r=Atomics.load(this.i32,n)>>>0,i=s-r>>>0;if(i>8192)return this.faulted=!0,console.error(`PtyBridge: REFUSING to drain \u2014 drain ring reports ${i} bytes available in a ${8192}-byte ring (head=${s} tail=${r}, ringOffset=${this.base}). That is not a ring header. The usual cause is a drain loop still running against a machine that has been halted or re-launched \u2014 clear its interval on teardown. This bridge is now inert; no bytes were rendered.`),K0;let l=new Uint8Array(i),d=this.base+qn.DRAIN_BUF;for(let a=0;a>>0|0),i>0&&this.ringDoorbell("sched",Atomics.load(this.i32,this.idx(qn.SCHED_WAKE_OFF))>>>0,1/0),l}drainStr(){return aW.decode(this.drain())}waitForOutput(e){this.live();let n=this.idx(qn.DRAIN_NOTIFY),s=Atomics.load(this.i32,n);return Atomics.wait(this.i32,n,s,e)!=="timed-out"}collectUntil(e,n){let s=Date.now()+n,r="";for(;;){if(r+=this.drainStr(),e(r))return r;let i=s-Date.now();if(i<=0)return r;this.waitForOutput(Math.min(i,50))}}};function lW(){return typeof process<"u"&&process!==null&&typeof process.versions=="object"&&process.versions!==null&&typeof process.versions.node=="string"}o(lW,"isNodeRealm");function dW(){return typeof window<"u"&&typeof document<"u"?"a browser window":typeof self<"u"&&typeof globalThis.WorkerGlobalScope<"u"||typeof importScripts=="function"?"a browser Worker":typeof globalThis.Deno<"u"?"Deno":"an unrecognised JavaScript realm"}o(dW,"describeRealm");function Ul(t){if(!lW())throw cW(t)}o(Ul,"assertNodeRealm");function cW(t){return new Error(`hardwarejs: ${t} is NODE-ONLY and was imported from ${dW()}. It mounts a host DIRECTORY as the guest root through node:fs. There is no browser equivalent \u2014 a page cannot open a POSIX directory, and this port does not fake one. In a browser the guest root arrives as a TRANSFERRED PORT, not as a client in the image: the embedding page holds brintos-fs and serves an FsView over it (src/devices/fs-tunnel.ts), and frame/machine/fs-capability.ts turns the port into the root view. The appliance's /cache device is a separate virtio-fs served from OPFS via createOpfsFsViewInThread(). Nothing here degrades to a browser-safe subset on purpose: a half-working host mount would answer some paths and silently miss others, which is worse than not being there.`)}o(cW,"refusal");Ul("a hardwarejs Node-only module (host-realm.mjs)");import{execFileSync as uW}from"node:child_process";import*as Vn from"node:fs";import*as Ft from"node:fs/promises";import*as j0 from"node:os";import*as nn from"node:path";Ul("cli/dir-fs-view.mjs");function O0(t){let e=nn.resolve(t),n=nn.join(nn.dirname(e),`.manifest.${nn.basename(e)}`);return Vn.existsSync(n)?n:null}o(O0,"stagingCertificate");var Ml=new Map,z0=!1;function mW(){if(z0)return;z0=!0;let t=o(()=>{for(let e of Ml.values())hW(e);Ml.clear()},"sweep");process.on("exit",t);for(let e of["SIGINT","SIGTERM","SIGHUP"])process.on(e,()=>{t(),process.exit(128+(e==="SIGINT"?2:e==="SIGTERM"?15:1))})}o(mW,"installCopyExitHook");function hW(t){if(process.env.HWJS_STAGING_COPY_KEEP==="1"){process.stderr.write(`[staging] HWJS_STAGING_COPY_KEEP=1 \u2014 leaving ${t} in place `);return}try{Vn.rmSync(nn.dirname(t),{recursive:!0,force:!0})}catch(e){process.stderr.write(`[staging] WARNING: could not remove private staging copy ${t}: ${e&&e.message||e} `)}}o(hW,"removePrivateCopySync");function Q0(t){Ul("cli/dir-fs-view.mjs");let e=nn.resolve(t),n=O0(e);if(!n)return e;let s=Ml.get(e);if(s)return s;if(!Vn.existsSync(e))return e;mW();let r=Vn.mkdtempSync(nn.join(j0.tmpdir(),"hwjs-staging-")),i=nn.join(r,nn.basename(e)),l=Date.now();try{uW("cp",["-a","--reflink=auto",e,i],{stdio:"pipe"})}catch(d){throw Vn.rmSync(r,{recursive:!0,force:!0}),new Error(`staging: could not make a private copy of ${e}: ${d&&d.message||d}`)}return Ml.set(e,i),process.stderr.write(`[staging] ${e} [staging] is certified by ${nn.basename(n)}; booting a private copy so this run cannot alter it [staging] copy: ${i} (${Date.now()-l} ms, removed on exit) `),i}o(Q0,"privateStagingCopy");var ga=61440,yu=32768,D0=1,_r=2;function to(t){let e=t&&t.code;return e&&{ENOENT:_r,EPERM:D0,EACCES:13,EEXIST:17,ENOTDIR:20,EISDIR:21,EINVAL:22,EROFS:30,ENOTEMPTY:39}[e]||5}o(to,"toErrno");function Xs(t,e){return Object.assign(new Error(e),{errno:t})}o(Xs,"fsErr");function eo(t,e,n){return Object.assign(new Error(`${t} ${e}: ${n&&n.code||n}`),{errno:to(n),code:n&&n.code})}o(eo,"opErr");var Ll=class t{static{o(this,"DirFsView")}constructor(e,n={}){if(this.root=Vn.realpathSync(e),!Vn.lstatSync(this.root).isDirectory())throw Xs(20,"root is not a directory");if(this.refuseWrites=n.refuseWrites,!n.refuseWrites){let r=O0(this.root);if(r)throw new Error(`DirFsView: refusing to serve ${this.root} read-write. It is a staged rootfs its rig CERTIFIED (${nn.basename(r)}), i.e. a build product. Booting it read-write lets the guest \u2014 and this process's own probe installs \u2014 write into that build product. \`pack\`/\`rootfs\` are stamp-guarded and will never rebuild for a file that is not a declared input, and the deploy is additive, so every such stray becomes permanent in a machine image. That is the 2026-07-25 staging contamination, and it is what deploy-manifest.sh and \`make artifact-check\` refuse on. Boot a disposable private copy instead \u2014 the same class, the same bytes, ~20 ms: import { DirFsView, privateStagingCopy } from ".../cli/dir-fs-view.mjs"; const ROOTFS = privateStagingCopy(); Resolve the path through privateStagingCopy() ONCE, at the top, and use that value for everything \u2014 the view AND any probe this run installs \u2014 so nothing is left behind. (A mount opened with { refuseWrites } is exempt: it cannot write either way.)`)}this.onOp=n.onOp;let s=Promise.resolve();for(let r of["getattr","lookup","readdir","read","readlink","write","create","mkdir","unlink","rename","setattr","symlink","link","mknod"]){let i=this[r].bind(this);this[r]=(...l)=>{let d=s.then(()=>i(...l));return s=d.catch(()=>{}),d}}this.inoToPath=["",this.root],this.pathToIno=new Map([[this.root,1]]),this.hostInoAlias=new Map,Wr(this,{kind:"host-dir",origin:this.root,note:"host directory, served read-write"})}_note(e,n){this.onOp?.(e,n)}async _refuseIfReadOnly(e){let n=this.refuseWrites;if(n)throw n.delayMs&&await new Promise(s=>setTimeout(s,n.delayMs)),Object.assign(new Error(n.message??`fs write refused (read-only mount): [op=${e}]`),{errno:n.errno??13})}_ino(e){let n=nn.resolve(e),s=this.pathToIno.get(n);return s===void 0&&(s=this.inoToPath.length,this.inoToPath.push(n),this.pathToIno.set(n,s)),s}_path(e){let n=this.inoToPath[e];if(!n)return n;let s=nn.relative(this.root,n);if(s===".."||s.startsWith(".."+nn.sep)||nn.isAbsolute(s))throw Xs(13,"path escapes the selected directory");let r=this.root,i=s.split(nn.sep);for(let l of i.slice(0,-1)){r=nn.join(r,l);let d=Vn.lstatSync(r);if(d.isSymbolicLink()||!d.isDirectory())throw Xs(20,"parent is not a directory")}if(!Vn.lstatSync(this.root).isDirectory()||Vn.lstatSync(this.root).isSymbolicLink())throw Xs(13,"selected root changed");return n}_child(e,n){if(typeof n!="string"||!n||n==="."||n===".."||/[\/\\:\x00]/.test(n)||Buffer.byteLength(n)>255||process.platform==="win32"&&(/[ .]$/.test(n)||/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(n)))throw Xs(22,"filename must be a single component");let s=Vn.lstatSync(e);if(s.isSymbolicLink()||!s.isDirectory())throw Xs(20,"parent is not a directory");return nn.join(e,n)}_dataPath(e,n=!1,s=!1){let r;try{r=Vn.lstatSync(e)}catch(i){if(s&&i.code==="ENOENT")return;throw i}if(!r.isFile()&&!(n&&r.isDirectory()))throw Xs(13,"host data operations require a regular file or directory")}_range(e,n){if(!Number.isSafeInteger(e)||e<0||!Number.isSafeInteger(n)||n<0||n>4*1024*1024||!Number.isSafeInteger(e+n))throw Xs(22,"invalid or oversized filesystem I/O")}_repoint(e,n){let s=e+nn.sep,r=[];for(let i of this.pathToIno.keys())(i===e||i.startsWith(s))&&r.push(i);for(let i of r){let l=this.pathToIno.get(i),d=n+i.slice(e.length);this.pathToIno.delete(i),this.pathToIno.set(d,l),this.inoToPath[l]===i&&(this.inoToPath[l]=d)}}_forgetName(e,n){let s=this.pathToIno.get(e);if(s!==void 0&&(this.pathToIno.delete(e),this.inoToPath[s]===e)){for(let[r,i]of this.pathToIno)if(i===s){this.inoToPath[s]=r;return}n!==void 0&&this.hostInoAlias.delete(n)}}_supersedeName(e){let n=this.pathToIno.get(e);this._forgetName(e),n!==void 0&&this.inoToPath[n]===e&&(this.inoToPath[n]=void 0)}_inoForStat(e,n){let s=nn.resolve(e);if(n&&n.nlink>1&&(n.mode&ga)===yu){let r=`${n.dev}:${n.ino}`,i=this.hostInoAlias.get(r);if(i!==void 0)return this.pathToIno.set(s,i),i;let l=this._ino(s);return this.hostInoAlias.set(r,l),l}return this._ino(s)}_attr(e,n){return{ino:e,size:Number(n.size),mode:n.mode,nlink:n.nlink,uid:n.uid,gid:n.gid,mtimeSec:Math.floor(n.mtimeMs/1e3),rdev:n.rdev}}async getattr(e){let n=this._path(e);if(!n)return null;try{return this._attr(e,await Ft.lstat(n))}catch{return null}}async lookup(e,n){let s=this._path(e);if(!s)return null;let r=this._child(s,n);try{let i=await Ft.lstat(r);return this._note("lookup",{parent:e,name:n,hit:!0}),this._attr(this._inoForStat(r,i),i)}catch{return this._note("lookup",{parent:e,name:n,hit:!1}),null}}async readdir(e){let n=this._path(e);if(!n)return[];this._dataPath(n,!0);let s=[];for await(let i of await Ft.opendir(n)){if(s.length>=65536)throw Xs(28,"directory exceeds the host listing limit");s.push(i.name)}let r=[];for(let i of s){let l=nn.join(n,i);try{let d=await Ft.lstat(l);r.push({name:i,ino:this._inoForStat(l,d),type:(d.mode&ga)>>12})}catch{}}return r}async read(e,n,s){let r=this._path(e);if(!r)throw Xs(_r,`read: inode ${e} has no path`);try{this._range(n,s),this._dataPath(r);let i=await Ft.open(r,Vn.constants.O_RDONLY|(Vn.constants.O_NOFOLLOW||0));try{let l=Buffer.alloc(s),{bytesRead:d}=await i.read(l,0,s,n);return l.subarray(0,d)}finally{await i.close()}}catch(i){throw eo("read",r,i)}}async readlink(e){let n=this._path(e);if(!n)throw Xs(_r,`readlink: inode ${e} has no path`);try{return await Ft.readlink(n)}catch(s){throw eo("readlink",n,s)}}async write(e,n,s){await this._refuseIfReadOnly("write");let r=this._path(e);if(!r)throw Xs(_r,`write: inode ${e} has no path`);try{this._range(n,s?.length),this._dataPath(r);let i=await Ft.open(r,Vn.constants.O_RDWR|(Vn.constants.O_NOFOLLOW||0));try{let{bytesWritten:l}=await i.write(s,0,s.length,n);return l}finally{await i.close()}}catch(i){throw eo("write",r,i)}}async create(e,n,s){await this._refuseIfReadOnly("create"),this._note("create",{parent:e,name:n,mode:s});let r=this._path(e);if(!r)throw Xs(_r,`create ${n}: inode ${e} has no path`);let i=this._child(r,n);try{return this._dataPath(i,!1,!0),await(await Ft.open(i,Vn.constants.O_WRONLY|Vn.constants.O_CREAT|Vn.constants.O_TRUNC|(Vn.constants.O_NOFOLLOW||0),s&4095)).close(),this._attr(this._ino(i),await Ft.lstat(i))}catch(l){throw eo("create",i,l)}}async mkdir(e,n,s){await this._refuseIfReadOnly("mkdir");let r=this._path(e);if(!r)throw Xs(_r,`mkdir ${n}: inode ${e} has no path`);let i=this._child(r,n);try{return await Ft.mkdir(i,{mode:s&4095}),this._attr(this._ino(i),await Ft.lstat(i))}catch(l){throw eo("mkdir",i,l)}}async unlink(e,n,s){await this._refuseIfReadOnly("unlink"),this._note("unlink",{parent:e,name:n,isDir:s});let r=this._path(e);if(!r)return _r;let i=this._child(r,n),l=nn.resolve(i),d;if(!s)try{let a=await Ft.lstat(i);(a.mode&ga)===yu&&a.nlink>1&&(d=`${a.dev}:${a.ino}`)}catch{}try{s?await Ft.rmdir(i):await Ft.unlink(i)}catch(a){return to(a)}this._forgetName(l,d)}async rename(e,n,s,r){await this._refuseIfReadOnly("rename");let i=this._path(e),l=this._path(s);if(!i||!l)return _r;let d=nn.resolve(this._child(i,n)),a=nn.resolve(this._child(l,r));if(process.env.HWJS_DIRFSVIEW_NO_DIR_RENAME==="1"){let h;try{h=await Ft.lstat(d)}catch(p){return to(p)}if(h.isDirectory())return D0}let c=this.pathToIno.has(a);try{await Ft.rename(d,a)}catch(h){return to(h)}if(c){let h=!1;try{await Ft.lstat(d),h=!0}catch{}if(h)return;this._supersedeName(a)}this._repoint(d,a)}async setattr(e,n){await this._refuseIfReadOnly("setattr"),this._note("setattr",{ino:e,changes:n});let s=this._path(e);if(!s)throw Xs(_r,`setattr: inode ${e} has no path`);try{if(this._dataPath(s,!0),n.size!==void 0){if(!Number.isSafeInteger(n.size)||n.size<0)throw Xs(22,"invalid file size");await Ft.truncate(s,n.size)}n.mode!==void 0&&await Ft.chmod(s,n.mode&4095),n.mtimeSec!==void 0&&await Ft.utimes(s,n.mtimeSec,n.mtimeSec)}catch(r){throw eo("setattr",s,r)}return this._attr(e,await Ft.lstat(s))}async symlink(e,n,s){await this._refuseIfReadOnly("symlink");let r=this._path(e);if(!r)throw Object.assign(new Error("symlink: no such parent"),{errno:2});let i=this._child(r,n);try{await Ft.symlink(s,i)}catch(l){throw Object.assign(new Error(`symlink: ${l.code}`),{errno:to(l)})}return this._attr(this._ino(i),await Ft.lstat(i))}async link(e,n,s){await this._refuseIfReadOnly("link");let r=this._path(e),i=this._path(s);if(!r||!i)throw Object.assign(new Error("link: no such node"),{errno:2});let l=this._child(r,n),d=nn.resolve(l);try{this._dataPath(i),await Ft.link(i,l)}catch(c){throw Object.assign(new Error(`link: ${c.code}`),{errno:to(c)})}this.pathToIno.set(d,s);let a=await Ft.lstat(l);return this.hostInoAlias.set(`${a.dev}:${a.ino}`,s),this._attr(s,a)}async mknod(e,n,s,r){if(await this._refuseIfReadOnly("mknod"),(s&ga)!==yu&&(s&ga)!==0)throw Object.assign(new Error("mknod: only regular files are representable on the host-directory store"),{errno:1});return t.prototype.create.call(this,e,n,s)}};import{openSync as bW,closeSync as $0,fstatSync as pW,readSync as q0,writeSync as fW,fsyncSync as ef}from"node:fs";import{resolve as yW}from"node:path";function tf(t,e=!1){let n=yW(t),s=bW(n,e?"r":"r+");try{let r=pW(s);if(!r.isFile()||!Number.isSafeInteger(r.size)||r.size<2048||r.size%512)throw new Error("--image must be a regular ext4 image with a whole number of 512-byte sectors");let i=Buffer.alloc(1024);if(q0(s,i,0,1024,1024)!==1024||i.readUInt16LE(56)!==61267)throw new Error("--image must contain an ext4 filesystem starting at byte zero (no partition table)");let l=o((d,a)=>{if(!Number.isSafeInteger(d)||!Number.isSafeInteger(a)||d<0||a<0||a>4*1024*1024||!Number.isSafeInteger(d+a)||d+a>r.size)throw new Error("disk I/O is outside the selected image")},"range");return{path:n,size:r.size,readOnly:e,read(d,a){l(d,a);let c=new Uint8Array(a);if(q0(s,c,0,a,d)!==a)throw new Error("short image read");return c},write(d,a){if(e)throw new Error("image is read-only");if(l(d,a.length),fW(s,a,0,a.length,d)!==a.length)throw new Error("short image write")},flush(){e||ef(s)},close(){s!==void 0&&(e||ef(s),$0(s),s=void 0)}}}catch(r){throw $0(s),r}}o(tf,"openImageDisk");import{execFile as ZW}from"node:child_process";function Pl(t){let e="(?:0|[1-9][0-9]{0,5})\\.(?:0|[1-9][0-9]{0,5})\\.(?:0|[1-9][0-9]{0,5})(?:-dev\\.(?:0|[1-9][0-9]{0,7}))?",n=new RegExp(`^vmlinux-[0-9]+\\.[0-9]+(?:\\.[0-9]+)?-wasm32-${e}-hwjs-${e}\\.wasm$`),s=t.filter(r=>n.test(r));if(s.length!==1)throw new Error(`Expected one versioned kernel in /boot, found ${s.length}; supply --kernel to select a local kernel explicitly`);return s[0]}o(Pl,"selectKernelName");var gW=256*1024*1024;async function Zu(t,e,n,s){for(let r of["7z","7zz"])try{return await new Promise((i,l)=>{ZW(r,[...e,"-spd","--",t,...n],{encoding:"buffer",maxBuffer:s,timeout:6e4,windowsHide:!0},(a,c,h)=>{a?a.code==="ENOENT"?l(a):l(new Error(`${r} could not read the image's boot files: ${String(h).trim()||a.message}`)):i(c)}).stdin?.end()})}catch(i){if(i.code!=="ENOENT")throw i}throw new Error("Reading boot files from --image requires 7-Zip (7z or 7zz on PATH). Install it locally, or supply both --kernel and --init . No network download is attempted.")}o(Zu,"imageEntry");async function nf(t){let n=[...(await Zu(t,["l","-slt","-ba","-sccUTF-8"],["boot"],1048576)).toString("utf8").matchAll(/^Path = boot\/([^/\r\n]+)\r?$/gm)].map(i=>i[1]),s="boot/"+Pl(n),r=await Zu(t,["e","-so"],[s],gW);if(r.length<8||!r.subarray(0,8).equals(Buffer.from([0,97,115,109,1,0,0,0])))throw new Error(`The image must contain a WASM kernel at /${s}; use --kernel to override it`);return r}o(nf,"readImageKernel");async function sf(t){let e=(await Zu(t,["l","-slt","-ba","-sccUTF-8"],["bin/sh","bin/bash"],1048576)).toString("utf8"),n=new Set([...e.matchAll(/^Path = (bin\/(?:sh|bash))\r?$/gm)].map(s=>s[1]));for(let s of["bin/sh","bin/bash"])if(n.has(s))return"/"+s;throw new Error("The image contains neither /bin/sh nor /bin/bash; pass --init to choose PID 1.")}o(sf,"imageShell");var rf=1,IW=2,GW=5,of=17,WW=21,wW=22,js=1,gu=16384,Ys=["dev","proc","sys","tmp"],Os=$i;if(Os+Ys.length-1>4294967294)throw new Error(`fs-mountpoints: ${Ys.length} mountpoints from 0x${Os.toString(16)} run past the 32-bit inode space. st_ino is 32 bits on this architecture and the kernel answers EOVERFLOW rather than narrowing.`);var Gu=Os+Ys.length-1;function es(t){return t>=Os&&t<=Gu}o(es,"isSynthetic");function Iu(t){return es(t)?Ys[t-Os]:null}o(Iu,"synthesizedName");function wr(t){return Ys.indexOf(t)}o(wr,"reservedIndex");function so(t,e){let n=new Error(e);return n.errno=t,n}o(so,"refuse");function af(t){return{ino:Os+t,size:0,mode:Il("dir",493),nlink:2,uid:0,gid:0,mtimeSec:0}}o(af,"mountpointAttr");function Wu(t,e){let n=Iu(t);if(n!==null)throw so(GW,`the filesystem serving this machine's root answered ${e} with inode ${t}, which is the inode this view presents /${n} on. Two different directories answering to one inode is a mount where a path resolves to the wrong file, so it is refused here rather than discovered later as unexplained file confusion. The synthetic range is ${Os}..${Gu}.`)}o(Wu,"checkForeignIno");function lf(t,e){return t!==null&&Wu(t.ino,e),t}o(lf,"checkForeignAttr");function no(t,e){return Wu(t.ino,e),t}o(no,"checkMintedAttr");function SW(t,e){let{notice:n}=e,s=new Set;function r(a,c){return so(rf,`${a} /${c}: this machine's root presents /${c} as a mountpoint for the kernel's own boot mounts. It is not in the repository \u2014 nothing here can be created, removed or renamed, and nothing that happens to it would be visible to a diff.`)}o(r,"refuseReservedName");function i(a,c){let h=Iu(c);return so(a==="read"||a==="write"?WW:rf,`${a} on inode ${c} (/${h}): a synthesized mountpoint is an empty directory this view presents so the boot mounts have somewhere to land. It has no contents, no backing store and nothing to change.`)}o(i,"refuseSyntheticIno");let l={async getattr(a){return es(a)?af(a-Os):lf(await t.getattr(a),`getattr(${a})`)},async lookup(a,c){if(a===js){let h=wr(c);if(h>=0)return af(h)}return es(a)?null:lf(await t.lookup(a,c),`lookup(${a}, ${JSON.stringify(c)})`)},async readdir(a){if(es(a))return[];let c=await t.readdir(a);for(let m of c)Wu(m.ino,`readdir(${a}) entry ${m.name}`);if(a!==js)return c;let h=c.filter(m=>wr(m.name)>=0).map(m=>m.name);if(h.length>0){let m=`this machine's root now carries ${h.map(y=>`/${y}`).join(", ")}, which this view presents as ${h.length===1?"a mountpoint":"mountpoints"} for the kernel's boot mounts. Refusing to list a root where one name means two directories.`;if(h.some(y=>!s.has(y))){for(let y of h)s.add(y);n(`hardwarejs: ${m}`)}throw so(of,m)}let p=Ys.map((m,y)=>({name:m,ino:Os+y,type:gu>>12}));return[...c,...p]},async read(a,c,h){if(es(a))throw i("read",a);return t.read(a,c,h)}};t.readlink&&(l.readlink=async a=>{if(es(a))throw so(wW,`readlink on inode ${a} (/${Iu(a)}): it is a directory`);return t.readlink(a)}),t.write&&(l.write=async(a,c,h)=>{if(es(a))throw i("write",a);return t.write(a,c,h)}),t.create&&(l.create=async(a,c,h)=>{if(a===js&&wr(c)>=0)throw r("create",c);if(es(a))throw i("create",a);return no(await t.create(a,c,h),"create")}),t.mkdir&&(l.mkdir=async(a,c,h)=>{if(a===js&&wr(c)>=0)throw so(of,`mkdir /${c}: this machine's root already presents /${c} as a mountpoint for the kernel's boot mounts.`);if(es(a))throw i("mkdir",a);return no(await t.mkdir(a,c,h),"mkdir")}),t.unlink&&(l.unlink=async(a,c,h)=>{if(a===js&&wr(c)>=0)throw r(h?"rmdir":"unlink",c);if(es(a))throw i("unlink",a);return t.unlink(a,c,h)}),t.rename&&(l.rename=async(a,c,h,p)=>{if(a===js&&wr(c)>=0)throw r("rename",c);if(h===js&&wr(p)>=0)throw r("rename onto",p);if(es(a)||es(h))throw i("rename",es(a)?a:h);return t.rename(a,c,h,p)}),t.setattr&&(l.setattr=async(a,c)=>{if(es(a))throw i("setattr",a);return no(await t.setattr(a,c),"setattr")}),t.symlink&&(l.symlink=async(a,c,h)=>{if(a===js&&wr(c)>=0)throw r("symlink",c);if(es(a))throw i("symlink",a);return no(await t.symlink(a,c,h),"symlink")}),t.link&&(l.link=async(a,c,h)=>{if(a===js&&wr(c)>=0)throw r("link",c);if(es(a))throw i("link",a);if(es(h))throw i("link",h);return no(await t.link(a,c,h),"link")}),t.mknod&&(l.mknod=async(a,c,h,p)=>{if(a===js&&wr(c)>=0)throw r("mknod",c);if(es(a))throw i("mknod",a);return no(await t.mknod(a,c,h,p),"mknod")}),t.statfs&&(l.statfs=()=>t.statfs()),t.fsync&&(l.fsync=async(a,c)=>{if(!es(a))return t.fsync(a,c)}),t.setlk&&(l.setlk=async(a,c,h)=>{if(es(a))throw i("setlk",a);return t.setlk(a,c,h)}),t.releaselk&&(l.releaselk=async(a,c)=>{if(!es(a))return t.releaselk(a,c)}),t.crossContextLocks!==void 0&&(l.crossContextLocks=t.crossContextLocks);let d=fa(t);return d!==void 0&&Wr(l,{kind:`boot-mountpoints+${d.kind}`,origin:d.origin,note:[d.note,`presents /${Ys.join(" /")}`].filter(a=>typeof a=="string"&&a!=="").join("; ")}),l}o(SW,"synthesizeBootMountpoints");async function df(t,e){let n=[];for(let i of Ys){let l;try{l=await t.lookup(js,i)}catch(d){if(d.errno===IW)continue;throw new Error(`the filesystem serving this machine's root could not be asked whether it already carries /${i}: ${d instanceof Error?d.message:String(d)}. The four boot mountpoints are presented over a tree that has to be readable first \u2014 a view that cannot answer is one this could be silently shadowing.`)}l!==null&&n.push(`/${i} (inode ${l.ino}, mode 0${l.mode.toString(8)})`)}if(n.length>0)throw new Error(`the root served to this machine already carries ${n.join(", ")}. The four boot mountpoints (${Ys.map(i=>`/${i}`).join(" ")}) are presented here, over whatever tree the root arrives as \u2014 presenting them a second time would hide whatever is really at those names, and standing down would hand devtmpfs, proc, sysfs or tmpfs a directory with contents underneath. Neither is decided quietly, so the boot stops here. Either the filesystem serving this root presents these itself, in which case it should stop \u2014 this runtime owns them, because it is the half that knows which names its kernel probes and has to check them regardless \u2014 or the repository behind it genuinely commits ${n.length===1?"that name":"those names"}, in which case rename the entry.`);let s=SW(t,e),r=new Set;for(let i of Ys){let l=await s.lookup(js,i);if(l===null||(l.mode&61440)!==gu)throw new Error(`the view serving this machine's root does not present /${i} as a directory (${l===null?"it resolves to nothing":`mode 0${l.mode.toString(8)}`}). The kernel probes all four before it chroots and refuses the root when one is missing \u2014 it then umounts the root and panics, because there is nothing to fall back to. This boot would end there, with the machine's own userland never reached.`);let d=await s.getattr(l.ino);if(d===null||d.ino!==l.ino||(d.mode&61440)!==gu)throw new Error(`/${i} resolves to inode ${l.ino} but that inode does not answer as the same directory. A mountpoint whose lookup and getattr disagree is one the kernel walks into and then cannot mount over.`);if(r.has(l.ino))throw new Error(`/${i} resolves to inode ${l.ino}, which another boot mountpoint already uses. Four distinct directories are required; these would be one directory with four names.`);r.add(l.ino)}return e.notice(`hardwarejs: root view presents the ${Ys.length} boot mountpoints (${Ys.map(i=>`/${i}`).join(" ")}) at inodes ${Os}..${Gu} \u2014 presented by this view, not stored in the repository, so no diff or commit can see them. /dev/pts is not among them: it is made inside devtmpfs after /dev is mounted over.`),s}o(df,"presentBootMountpoints");var us=["boot","hardwarejs-hotset.bin"],uf="hwjs.hotset=off",mf="hwjs.hotset=trace",hf="HWJSHOT1",Al=1,Ga=24,bf=$i+65536,kW=4294967294;if(Os+Ys.length>bf)throw new Error("fs-hotset: the hot-set inode block overlaps the mountpoints'");var zl=1,XW=61440,Jr=2,pf=5,RW=11,VW=20,jl=1<<20,xW=2,BW=4,ff=6,yf=5,TW=1e3;function Ol(t){return t?.errno}o(Ol,"errnoOf");function Ql(t){return t===Jr||t===VW}o(Ql,"gone");function ei(t){let e=Ol(t);return typeof e=="number"&&e>0?e:pf}o(ei,"thrownErrno");function kr(t){return typeof t=="number"&&t>0}o(kr,"failed");function Kl(t,e){let n=new Error(e);return n.errno=t,n}o(Kl,"refuse");function Sr(t,e){return t==="/"?`/${e}`:`${t}/${e}`}o(Sr,"joinPath");function Ia(t){let e=t.lastIndexOf("/");return[e===0?"/":t.slice(0,e),t.slice(e+1)]}o(Ia,"splitParent");async function Zf(t){let e=new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}o(Zf,"gunzip");async function YW(t){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",t));return Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}o(YW,"sha256Hex");async function CW(t){if(t.lengthperformance.now()),s=o(l=>(l!==null&&e.notice(l),e.trace?(e.notice("hot set: tracing every request with no cache in front"),new Dl(t,null,null,new Uint8Array(0),vW,e).asFsView()):t),"without"),r=zl,i=null;try{for(let l=0;lt.lookup(r,us[l]));if(!d)return s(null);lt.read(i.ino,0,Math.min(jl,i.size)));if(d.length>=Ga&&new TextDecoder().decode(d.subarray(0,8))===hf){let h=Ga+new DataView(d.buffer,d.byteOffset,d.byteLength).getUint32(12,!0);if(h>i.size)throw new Error(`manifest needs ${h} bytes, the object has ${i.size}`);for(;d.lengtht.read(i.ino,d.length,Math.min(jl,h-d.length)));if(p.length===0)break;let m=new Uint8Array(d.length+p.length);m.set(d),m.set(p,d.length),d=m}}let a=await CW(d);if(a.payloadOffset+a.payloadGzBytes>i.size)throw new Error(`content needs ${a.payloadOffset+a.payloadGzBytes} bytes, the object has ${i.size}`);let c=new Dl(t,i,r,d,a,e);return e.off?(e.notice(`hot set: off from the cmdline; watching its ${a.manifest.entries.length} paths, so a change to one unlinks /${us.join("/")}`),c.asFsView()):(e.notice(`hot set: ${a.manifest.entries.length} entries, ${(a.manifest.absent??[]).length} absent names, content ${(a.manifest.payloadBytes/1048576).toFixed(1)} MiB (${(a.payloadGzBytes/1048576).toFixed(1)} MiB to fetch, on first use); manifest read in ${(n()-l).toFixed(0)} ms`+(a.manifest.source?`; ${a.manifest.source}`:"")),c.asFsView())}catch(l){return cf(t,e,`it is unusable (${l.message})`)}}o(gf,"presentHotSet");async function ti(t){for(let e=0,n=yf;;e++,n*=2)try{return await t()}catch(s){if(Ol(s)!==RW||e+1>=ff)throw s;await new Promise(r=>setTimeout(r,n))}}o(ti,"readRetrying");var NW=["lookup","getattr","readdir","read","readlink","statfs","forget","fsync","setlk","releaselk"],HW=["write","create","mkdir","rename","setattr","unlink","symlink","link","mknod"];function cf(t,e,n){let s=`/${us.join("/")}`;e.notice(`hot set: ${s}: ${n}; serving without it, and unlinking it before the first change`);let r=!t.unlink,i=!1,l=null,d=us[us.length-1],a=o(async()=>{let f=zl;for(let I of us.slice(0,-1)){let R;try{R=await ti(()=>t.lookup(f,I))}catch(X){if(Ql(ei(X)))return null;throw X}if(!R)return null;f=R.ino}return f},"objectDir"),c=o(async()=>{let f=await a();if(f===null)return;let I;try{I=await ti(()=>t.unlink(f,us[us.length-1],!1))}catch(R){I=ei(R)}if(kr(I)&&!Ql(I))throw Kl(I,`hot set: could not unlink ${s} (errno ${I})`);kr(I)||(i=!0),e.notice(`hot set: unlinked ${s}, which this runtime could not read`)},"unlinkObject"),h=o(()=>r?Promise.resolve():(l??=c().then(()=>{r=!0},f=>{throw l=null,e.notice(`hot set: ${f.message}; refusing the change, the next one tries again`),f}),l),"before"),p={},m=t;for(let f of NW)typeof m[f]=="function"&&(p[f]=m[f].bind(t));for(let f of HW)typeof m[f]=="function"&&(p[f]=async(...I)=>(await h(),m[f].apply(t,I)));let y=o(async(f,I)=>!r&&I===d&&f===await a().catch(()=>null),"own"),b=o(async(f,I)=>{let R;try{R=await I()}catch(X){if(R=ei(X),!(f&&R===Jr&&i))throw await h().catch(()=>{}),X}return kr(R)?f&&R===Jr&&i?0:(await h().catch(()=>{}),R):(r=!0,R)},"ownChange");return t.unlink&&(p.unlink=async(f,I,R)=>await y(f,I)?b(!0,()=>t.unlink(f,I,R)):(await h(),t.unlink(f,I,R))),t.rename&&(p.rename=async(f,I,R,X)=>await y(f,I)?b(!1,()=>t.rename(f,I,R,X)):(await h(),t.rename(f,I,R,X))),t.crossContextLocks!==void 0&&(p.crossContextLocks=t.crossContextLocks),If(t,p,"hotset-guard",`${s} unread`),p}o(cf,"guardObject");function If(t,e,n,s){let r=fa(t);r!==void 0&&Wr(e,{kind:`${n}+${r.kind}`,origin:r.origin,note:[r.note,s].filter(i=>typeof i=="string"&&i!=="").join("; ")})}o(If,"carryProvider");var vW={manifest:{version:Al,payloadBytes:0,payloadSha256:"",entries:[],absent:[]},payloadOffset:0,payloadGzBytes:0},Dl=class{constructor(e,n,s,r,i,l){this.base=e;this.object=n;this.objectDir=s;this.head=r;this.parsed=i;this.opts=l;this.now=l.now??(()=>performance.now()),this.enabled=!l.off,this.seenAt=this.now(),this.watching=n!==null;let d=bf;for(let a of i.manifest.entries){if(this.byPath.set(a.p,a),d>kW)throw new Error("hot set: more entries than the inode block holds");let c=d++;if(this.inoOf.set(a,c),this.entryOf.set(c,a),a.p!=="/"){let[h]=Ia(a.p),p=this.children.get(h);p||this.children.set(h,p=[]),p.push(a)}}this.absent=new Set(i.manifest.absent??[]);for(let a of this.absent)for(let c=Ia(a)[0];c!=="/";c=Ia(c)[0])this.absentPrefixes.add(c);this.realIno.set("/",Promise.resolve(zl)),this.realPath.set(zl,"/"),n&&this.viewHeld.add(n.ino),s!==null&&this.viewHeld.add(s)}base;object;objectDir;head;parsed;opts;static{o(this,"HotSetView")}byPath=new Map;inoOf=new Map;entryOf=new Map;children=new Map;absent;realPath=new Map;realIno=new Map;handed=new Set;viewHeld=new Set;absentPrefixes=new Set;mintedOf=new Map;payload=null;enabled;watching;turningOff=null;seenAt;looking=null;replaced=!1;objectUnlinked=!1;announced=!1;now;isOurs(e){return this.entryOf.has(e)}pathOf(e){let n=this.entryOf.get(e);return n?n.p:this.realPath.get(e)}attrOf(e){return{ino:this.inoOf.get(e),size:e.s,mode:e.m,nlink:e.n,uid:e.u,gid:e.g,mtimeSec:e.t}}trace(e){this.opts.trace&&this.opts.notice(`hot set miss: ${e}`)}resolve(e){let n=this.realIno.get(e);if(n)return n;let[s,r]=Ia(e);return n=this.resolve(s).then(async i=>{let l=await this.base.lookup(i,r);if(!l)throw Kl(Jr,`hot set: ${e} is in the image's manifest and not on the far end`);return this.viewHeld.add(l.ino),this.realPath.set(l.ino,e),l.ino}),n.catch(i=>{this.realIno.get(e)===n&&(this.enabled||this.watching&&Ol(i)!==Jr)&&this.realIno.delete(e)}),this.realIno.set(e,n),n}real(e){let n=this.entryOf.get(e);return n?this.resolve(n.p).then(s=>(this.mintedOf.set(s,e),s)):Promise.resolve(e)}get placing(){return this.watching||this.opts.trace===!0}present(e){let n=this.mintedOf.get(e.ino);return n===void 0?e:(this.handed.add(n),{...e,ino:n})}disable(e,n=!1){return this.watching?this.turningOff?this.turningOff:(this.enabled=!1,this.announced||(this.announced=!0,this.opts.notice(`hot set: turned off for this session \u2014 ${e}`)),this.turningOff=(async()=>{let s=`/${us.join("/")}`,r=o((l,d)=>{throw this.turningOff=null,this.opts.notice(`hot set: ${d}; refusing the change that would outdate ${s}, the next one tries again`),Kl(l,`hot set: ${d}`)},"retry"),i=await this.bindHanded();if(i!==void 0&&r(ei(i),`binding the inodes handed out failed (${i.message})`),this.object&&this.objectDir!==null&&this.base.unlink&&!this.replaced&&!n){let l=await this.unlinkObject();kr(l)&&!Ql(l)&&r(l,`could not unlink ${s} (errno ${l})`),this.opts.notice(kr(l)?`hot set: ${s} is already gone from this tree`:`hot set: unlinked ${s}, which no longer matches this tree`)}this.watching=!1})(),this.turningOff):Promise.resolve()}async live(){return this.enabled?!this.object||this.objectDir===null||this.now()-this.seenAt{this.looking=null}),await this.looking&&this.enabled):!1}async lookAgain(){let e=us[us.length-1],n;try{n=await ti(()=>this.base.lookup(this.objectDir,e))}catch(r){if(!Ql(ei(r)))return!1;n=null}let s=this.object;return n&&n.ino===s.ino?(this.seenAt=this.now(),!0):(this.replaced=n!==null,await this.disable(`/${us.join("/")} ${n?"was replaced":"went"}, so another machine changed this tree`).catch(()=>{}),!1)}async unlinkObject(){let e;try{e=await ti(()=>this.base.unlink(this.objectDir,us[us.length-1],!1))}catch(n){e=ei(n)}return kr(e)||(this.objectUnlinked=!0),e}isObject(e,n){return this.object!==null&&e===this.objectDir&&n===us[us.length-1]}async ownObjectChanged(e,n){return kr(e)?n&&e===Jr&&this.objectUnlinked?0:(!this.objectUnlinked&&this.base.unlink&&!this.replaced&&await this.unlinkObject(),e):e}async bindHanded(){let e=[...this.handed],n,s=o(async i=>{for(let l=0,d=yf;n===void 0;l++,d*=2)try{await this.real(i);return}catch(a){if(Ol(a)===Jr)return;if(l+1>=ff){n=a;return}await new Promise(c=>setTimeout(c,d))}},"one"),r=o(async()=>{for(;e.length;)await s(e.shift())},"worker");return await Promise.all(Array.from({length:Math.min(BW,e.length)},r)),n}touches(e,n){if(!this.watching)return!1;if(this.isOurs(e))return!0;let s=this.pathOf(e);if(n===void 0)return s!==void 0&&this.byPath.has(s);if(s===void 0)return!0;let r=Sr(s,n);return this.byPath.has(s)||this.byPath.has(r)||this.absent.has(r)||this.absentPrefixes.has(r)}learn(e,n,s){if(!this.placing)return;let r=this.pathOf(e);s&&r!==void 0&&!this.isOurs(s.ino)&&this.realPath.set(s.ino,Sr(r,n))}relearn(e,n,s){if(!this.placing)return;let r=this.pathOf(e);if(r===void 0)return;let i=Sr(r,n);for(let[l,d]of this.realPath)d!==i&&!d.startsWith(`${i}/`)||(s===void 0?this.realPath.delete(l):this.realPath.set(l,s+d.slice(i.length)))}fetchPayload(){if(this.payload)return this.payload;let e=this.now();return this.payload=(async()=>{let{payloadOffset:n,payloadGzBytes:s,manifest:r}=this.parsed,i=new Uint8Array(s),l=Math.max(0,Math.min(this.head.length-n,s));l>0&&i.set(this.head.subarray(n,n+l),0);let d=[];for(let b=l;b{for(;athis.base.read(this.object.ino,n+b+I,f-I));if(R.length===0)throw new Error(`short read at ${n+b+I}`);i.set(R,b+I),I+=R.length}}},"worker");await Promise.all(Array.from({length:Math.min(xW,d.length)},c));let h=this.now(),p=await Zf(i);if(p.length!==r.payloadBytes)throw new Error(`content is ${p.length} bytes, the manifest says ${r.payloadBytes}`);let m=await YW(p);if(m!==r.payloadSha256)throw new Error(`content sha256 ${m}, the manifest says ${r.payloadSha256}`);let y=this.now()-e;return this.opts.notice(`hot set: content fetched, ${(s/1048576).toFixed(1)} MiB in ${(h-e).toFixed(0)} ms over ${d.length+(l>0?1:0)} reads, unpacked and checked in ${(y-(h-e)).toFixed(0)} ms`),p})().catch(n=>(this.opts.notice(`hot set: fetching the content failed (${n.message}); file content goes to the network`),null)),this.payload}hit(e){e.o!==void 0&&this.fetchPayload();let n=this.attrOf(e);return this.handed.add(n.ino),n}async lookup(e,n){let s=this.pathOf(e);if(s!==void 0&&await this.live()&&this.enabled){let i=Sr(s,n),l=this.byPath.get(i);if(l)return this.hit(l);if(this.absent.has(i)||this.byPath.get(s)?.c)return null}this.trace(`lookup ${s!==void 0?Sr(s,n):`${e}/${n}`}`);let r;try{r=await this.base.lookup(await this.real(e),n)}catch(i){throw this.opts.trace&&s!==void 0&&i.errno===Jr&&this.opts.notice(`hot set miss: absent ${Sr(s,n)}`),i}if(s!==void 0){let i=Sr(s,n);if(r&&this.placing){this.realPath.set(r.ino,i);let l=this.watching?this.byPath.get(i):void 0;l&&this.handed.has(this.inoOf.get(l))&&(this.mintedOf.set(r.ino,this.inoOf.get(l)),this.realIno.set(i,Promise.resolve(r.ino)),this.viewHeld.add(r.ino))}else this.opts.trace&&this.opts.notice(`hot set miss: absent ${i}`)}return r&&this.present(r)}async getattr(e){let n=this.entryOf.get(e);if(n&&await this.live()&&this.enabled)return this.attrOf(n);this.trace(`getattr ${this.pathOf(e)??e}`);let s=await this.base.getattr(await this.real(e));return s&&n?{...s,ino:e}:s}async readlink(e){let n=this.entryOf.get(e);if(n&&n.l!==void 0&&await this.live()&&this.enabled)return n.l;if(this.trace(`readlink ${this.pathOf(e)??e}`),!this.base.readlink)throw Kl(pf,"hot set: the view underneath has no readlink");return this.base.readlink(await this.real(e))}async readdir(e){let n=this.entryOf.get(e),s=this.pathOf(e);if(n?.c&&await this.live()&&this.enabled)return(this.children.get(n.p)??[]).map(i=>{let l=this.inoOf.get(i);return this.handed.add(l),{name:Ia(i.p)[1],ino:l,type:(i.m&XW)>>12}});this.trace(`readdir ${s??e}`);let r=await this.base.readdir(await this.real(e));return s===void 0?r:r.map(i=>{let l=this.byPath.get(Sr(s,i.name));l&&!this.enabled&&this.watching&&this.handed.has(this.inoOf.get(l))&&(this.mintedOf.set(i.ino,this.inoOf.get(l)),this.realIno.set(l.p,Promise.resolve(i.ino)),this.viewHeld.add(i.ino));let d=this.enabled?l:void 0;if(!d){this.placing&&this.realPath.set(i.ino,Sr(s,i.name));let c=this.mintedOf.get(i.ino);return c===void 0?i:{...i,ino:c}}let a=this.inoOf.get(d);return this.handed.add(a),{...i,ino:a}})}async read(e,n,s){let r=this.entryOf.get(e);if(r&&r.o!==void 0&&await this.live()){let i=await this.fetchPayload();if(i&&this.enabled){let l=r.o+Math.min(n,r.s),d=r.o+Math.min(n+s,r.s);return i.slice(l,d)}}return this.trace(`read ${this.pathOf(e)??e} @${n}+${s}`),this.base.read(await this.real(e),n,s)}asFsView(){let e=this.base,n={lookup:o((r,i)=>this.lookup(r,i),"lookup"),getattr:o(r=>this.getattr(r),"getattr"),readdir:o(r=>this.readdir(r),"readdir"),read:o((r,i,l)=>this.read(r,i,l),"read")};e.readlink&&(n.readlink=r=>this.readlink(r)),e.statfs&&(n.statfs=()=>e.statfs()),e.forget&&(n.forget=(r,i)=>{if(this.isOurs(r)){this.handed.delete(r);return}this.viewHeld.has(r)||(this.realPath.delete(r),e.forget(r,i))});let s=o(async(r,i,l,d=!1)=>(i&&await this.disable(`${r} on a cached path, or under a directory it cannot place`,d),l()),"mutate");return e.write&&(n.write=async(r,i,l)=>s(`write ${this.pathOf(r)??r}`,this.touches(r),async()=>e.write(await this.real(r),i,l))),e.create&&(n.create=async(r,i,l)=>s(`create ${i}`,this.touches(r,i),async()=>{let d=await e.create(await this.real(r),i,l);return this.learn(r,i,d),this.present(d)})),e.mkdir&&(n.mkdir=async(r,i,l)=>s(`mkdir ${i}`,this.touches(r,i),async()=>{let d=await e.mkdir(await this.real(r),i,l);return this.learn(r,i,d),d})),e.rename&&(n.rename=async(r,i,l,d)=>{let a=this.isObject(r,i);return s(`rename ${i}`,a||this.touches(r,i)||this.touches(l,d),async()=>{let c;try{c=await e.rename(await this.real(r),i,await this.real(l),d)}catch(p){throw a&&await this.ownObjectChanged(ei(p),!1),p}if(a&&(c=await this.ownObjectChanged(c,!1)),kr(c))return c;let h=this.pathOf(l);return this.relearn(l,d),this.relearn(r,i,h===void 0?void 0:Sr(h,d)),c},a)}),e.setattr&&(n.setattr=async(r,i)=>s(`setattr ${this.pathOf(r)??r}`,this.touches(r),async()=>{let l=await e.setattr(await this.real(r),i);return this.isOurs(r)?{...l,ino:r}:l})),e.unlink&&(n.unlink=async(r,i,l)=>{let d=this.isObject(r,i);return s(`unlink ${i}`,d||this.touches(r,i),async()=>{let a;try{a=await e.unlink(await this.real(r),i,l)}catch(c){if(!d||(a=await this.ownObjectChanged(ei(c),!0),kr(a)))throw c}return d&&(a=await this.ownObjectChanged(a,!0)),kr(a)||this.relearn(r,i),a},d)}),e.symlink&&(n.symlink=async(r,i,l)=>s(`symlink ${i}`,this.touches(r,i),async()=>{let d=await e.symlink(await this.real(r),i,l);return this.learn(r,i,d),d})),e.link&&(n.link=async(r,i,l)=>s(`link ${i}`,this.touches(r,i)||this.touches(l),async()=>{let d=await e.link(await this.real(r),i,await this.real(l));return this.isOurs(l)?{...d,ino:l}:this.present(d)})),e.mknod&&(n.mknod=async(r,i,l,d)=>s(`mknod ${i}`,this.touches(r,i),async()=>{let a=await e.mknod(await this.real(r),i,l,d);return this.learn(r,i,a),a})),e.fsync&&(n.fsync=async(r,i)=>{if(!(this.isOurs(r)&&this.enabled))return e.fsync(await this.real(r),i)}),e.setlk&&(n.setlk=async(r,i,l)=>e.setlk(await this.real(r),i,l)),e.releaselk&&(n.releaselk=async(r,i)=>e.releaselk(await this.real(r),i)),e.crossContextLocks!==void 0&&(n.crossContextLocks=e.crossContextLocks),If(e,n,"hotset",`hot set of ${this.byPath.size} paths`),n}};var Gf=new URL("data:text/javascript;base64,dmFyIHRyPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgcz0odCxyKT0+dHIodCwibmFtZSIse3ZhbHVlOnIsY29uZmlndXJhYmxlOiEwfSk7aW1wb3J0e3BhcmVudFBvcnQgYXMgRHR9ZnJvbSJub2RlOndvcmtlcl90aHJlYWRzIjt2YXIgcnI9T2JqZWN0LmZyZWV6ZShbInJhd19jb3B5X3RvX3VzZXIiLCJyYXdfY29weV9mcm9tX3VzZXIiLCJyYXdfY2xlYXJfdXNlciJdKTt2YXIgUHQ9Imh3anNfc3VzcGVuZCI7ZnVuY3Rpb24gUnQodCl7bGV0IHI9W10sZj0wO2ZvcihsZXQgbSBvZiBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyh0KSltLmtpbmQ9PT0ibWVtb3J5IiYmKGYrKyxtLm1vZHVsZT09PSJlbnYiJiZtLm5hbWU9PT0ia2VybmVsX21lbW9yeSJ8fHIucHVzaChgdm1saW51eCBpbXBvcnRzIG1lbW9yeSAke20ubW9kdWxlfS4ke20ubmFtZX0gXHUyMDE0IHRoZSBrZXJuZWwgaXMgYSBTSU5HTEUtbWVtb3J5IG1vZHVsZSBub3cgKG9ubHkgZW52Lmtlcm5lbF9tZW1vcnkpLiBBIHN0YWxlIG11bHRpLW1lbW9yeSB2bWxpbnV4Lndhc20gKHRoZSBkZWxldGVkIGVudi51c2VyX21lbW9yeSBzcGxpY2UpIGNhbm5vdCBib290IG9uIHRoaXMgaG9zdDogcmVidWlsZCB0aGUga2VybmVsICh1YWNjZXNzIGlzIGhvc3Qtc2VydmljZWQgdmlhIGxpbnV4LnJhd19jb3B5XypfdXNlcjsgbXVsdGktbWVtb3J5IGlzIGFsc28gd2hhdCBXZWJLaXQvaVBhZE9TIHJlamVjdHMgXHUyMDE0IGxpdGIjNjgpLmApKSxtLm1vZHVsZT09PVB0JiZyci5pbmNsdWRlcyhtLm5hbWUpJiZyLnB1c2goYHZtbGludXggZGVjbGFyZXMga2VybmVsLW1lbW9yeSBzZXJ2aWNlIGltcG9ydCAnJHttLm5hbWV9JyBpbiBwYXJraW5nIG5hbWVzcGFjZSAnJHtQdH0nIFx1MjAxNCB0aGUgdWFjY2VzcyBjcm9zc2luZyB3b3VsZCBiZSBhIGNvcm91dGluZSBzdXNwZW5kIGJvdW5kYXJ5IGJ5IGNvbnN0cnVjdGlvbiwgd2hpY2ggaXMgdGhlIHNpbGVudGx5LWNhdGFzdHJvcGhpYyB3aXJpbmcgdGhlIGxlYWYgd2l0bmVzcyBleGlzdHMgdG8gcmVmdXNlIChQTEFOLVRIUkVBRFMtU0lOR0xFLU1FTU9SWSBceEE3NSBSMSkuYCk7cmV0dXJuIGY+MSYmci5wdXNoKGB2bWxpbnV4IGltcG9ydHMgJHtmfSBtZW1vcmllcyBcdTIwMTQgZXhhY3RseSBvbmUgKGVudi5rZXJuZWxfbWVtb3J5KSBpcyB0aGUgc2luZ2xlLW1lbW9yeSBjb250cmFjdC5gKSxyfXMoUnQsImF1ZGl0Vm1saW51eFNpbmdsZU1lbW9yeSIpO2Z1bmN0aW9uIFV0KHQpe2xldHt1c2VyTWVtb3J5OnIsa2VybmVsTWVtb3J5OmYscmVmdXNlOm0sY29udGV4dDp2LHJlZFBhcms6Tn09dDtpZih0eXBlb2YgbSE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoIm1ha2VVYWNjZXNzTGVhZkJvdW5kYXJ5OiByZWZ1c2UoKSBpcyByZXF1aXJlZCIpO2xldCBnPTAsaz1udWxsLHA9bnVsbCxUPXMoYT0+e2xldCBsPXMoKC4uLnUpPT57aWYoZz4wKXRocm93IG0oYHVhY2Nlc3MtbGVhZi13aXRuZXNzIFJFRlVTQUwgWyR7dn1dOiBwYXJrIHNpZ25hbCByYWlzZWQgd2hpbGUgYSBrZXJuZWwtbWVtb3J5IGxlYWYgY3Jvc3NpbmcgaXMgbGl2ZSAoZGVwdGg9JHtnfSkuIEEgcGFyayBhY3Jvc3MgdGhlIHVhY2Nlc3MgY3Jvc3NpbmcgaXMgc2lsZW50bHkgY2F0YXN0cm9waGljIChSMSBzcGlrZTogcG9pc29uIHByb3BhZ2F0aW9uIHdpdGggYSBjbGVhbiBET05FIGV4aXQpIFx1MjAxNCB0aGUgY3Jvc3NpbmcgTVVTVCBiZSBhIGxlYWYgaG9zdCBtZW1jcHkuIFJlZnVzaW5nIGxvdWRseSBpbnN0ZWFkLmApLG5ldyBFcnJvcigidWFjY2Vzcy1sZWFmLXdpdG5lc3M6IHBhcmsgZHVyaW5nIGxlYWYgY3Jvc3NpbmciKTtyZXR1cm4gYSguLi51KX0sIndyYXBwZWQiKTtyZXR1cm4gcD1sLGx9LCJndWFyZFBhcmsiKSxEPXMoYT0+e2s9YX0sInNldFBhcmtlZFNsb3RSZWFkZXIiKSxlZT1zKCgpPT5nPjAsImluTGVhZkNyb3NzaW5nIik7aWYoIXIpe2xldCBhPXMobD0+KC4uLnUpPT57dGhyb3cgbShgdWFjY2Vzcy1sZWFmLXdpdG5lc3MgUkVGVVNBTCBbJHt2fV06IGxpbnV4LiR7bH0oJHt1Lm1hcChfPT4iMHgiKyhfPj4+MCkudG9TdHJpbmcoMTYpKS5qb2luKCIsICIpfSkgY2FsbGVkIGZyb20ga3RocmVhZCBjb250ZXh0IFx1MjAxNCB0aGUgc3RhbmRhbG9uZSB2bWxpbnV4IFdvcmtlciBoYXMgbm8gdXNlciBwYWdlczsga2VybmVsIGNvZGUgbXVzdCBuZXZlciB1YWNjZXNzIG91dHNpZGUgYSBwcm9jZXNzIGNvbnRleHQuIFRoaXMgaXMgYSBrZXJuZWwgYnVnICh0aGUgb2xkIDEtcGFnZSBzZW50aW5lbCdzIHRyYXAsIG5vdyBuYW1lZCkuYCksbmV3IEVycm9yKGBrdGhyZWFkIHVhY2Nlc3M6IGxpbnV4LiR7bH1gKX0sImt0aHJlYWRCdWciKTtyZXR1cm57aW1wb3J0czp7cmF3X2NvcHlfdG9fdXNlcjphKCJyYXdfY29weV90b191c2VyIikscmF3X2NvcHlfZnJvbV91c2VyOmEoInJhd19jb3B5X2Zyb21fdXNlciIpLHJhd19jbGVhcl91c2VyOmEoInJhd19jbGVhcl91c2VyIil9LGd1YXJkUGFyazpULHNldFBhcmtlZFNsb3RSZWFkZXI6RCxpbkxlYWZDcm9zc2luZzplZX19bGV0IHRlPW51bGwscmU9bnVsbCwkPXMoKCk9PntsZXQgYT1yLmJ1ZmZlcjtyZXR1cm4gYSE9PXRlJiYodGU9YSxyZT1uZXcgVWludDhBcnJheShhKSkscmV9LCJ1c2VyVTgiKSxBPW51bGwsUD1udWxsLFI9cygoKT0+e2xldCBhPWYuYnVmZmVyO3JldHVybiBhIT09QSYmKEE9YSxQPW5ldyBVaW50OEFycmF5KGEpKSxQfSwia2VyblU4IiksTD0zMixuZT1zKChhLGwsdSxfLHcpPT57aWYodzw9TClmb3IobGV0IHg9MDt4PHc7eCsrKWFbbCt4XT11W18reF07ZWxzZSBhLnNldCh1LnN1YmFycmF5KF8sXyt3KSxsKX0sImNvcHlCeXRlcyIpLFU9cygoYSxsKT0+e3Rocm93IG0oYHVhY2Nlc3MtbGVhZi13aXRuZXNzIFJFRlVTQUwgWyR7dn1dOiBsaW51eC4ke2F9OiAke2x9YCksbmV3IEVycm9yKGB1YWNjZXNzIGtlcm5lbC1zaWRlIGJ1ZzogbGludXguJHthfWApfSwia2VybmVsQnVnIiksTz1zKChhLGwpPT4odSxfLHcpPT57bGV0IHg9az9rKCk6MDtnKys7dHJ5e3JldHVybiBOJiYocHx8bShgdWFjY2Vzcy1sZWFmLXdpdG5lc3MgUkVGVVNBTCBbJHt2fV06IFJFRCBwYXJrIGFybSByZXF1ZXN0ZWQgYnV0IG5vIHBhcmsgYmluZGluZyB3YXMgZ3VhcmRlZCAoZ3VhcmRQYXJrIG5ldmVyIGNhbGxlZCkgXHUyMDE0IHRoZSB3aXRuZXNzIHdvdWxkIGJlIHZhY3VvdXMuIFdpcmUgZ3VhcmRQYXJrLmApLHAoKSksbCh1LF8sdyl9ZmluYWxseXtpZihnLS0sayl7bGV0IGI9aygpO2IhPT14JiZtKGB1YWNjZXNzLWxlYWYtd2l0bmVzcyBSRUZVU0FMIFske3Z9XTogcGFya2VkIHNsb3QgY2hhbmdlZCBhY3Jvc3MgbGludXguJHthfSAoMHgkeyh4Pj4+MCkudG9TdHJpbmcoMTYpfSAtPiAweCR7KGI+Pj4wKS50b1N0cmluZygxNil9KSBcdTIwMTQgdGhlIGtlcm5lbC1tZW1vcnkgY3Jvc3Npbmcgc3VzcGVuZGVkLiBUaGUgY3Jvc3NpbmcgTVVTVCBiZSBhIGxlYWYuYCl9fX0sImxlYWYiKTtyZXR1cm57aW1wb3J0czp7cmF3X2NvcHlfdG9fdXNlcjpPKCJyYXdfY29weV90b191c2VyIiwoYSxsLHUpPT57aWYoYT4+Pj0wLGw+Pj49MCx1Pj4+PTAsdT09PTApcmV0dXJuIDA7bGV0IF89JCgpO2lmKGErdT5fLmxlbmd0aClyZXR1cm4gdTtsZXQgdz1SKCk7cmV0dXJuIGwrdT53Lmxlbmd0aCYmVSgicmF3X2NvcHlfdG9fdXNlciIsYGtlcm5lbC1zaWRlIHNvdXJjZSBvdXQgb2YgcmFuZ2UgKGZyb209MHgke2wudG9TdHJpbmcoMTYpfSBuPSR7dX0ga2VybmVsX2xlbj0weCR7dy5sZW5ndGgudG9TdHJpbmcoMTYpfSkgXHUyMDE0IGtlcm5lbCBidWdgKSxuZShfLGEsdyxsLHUpLDB9KSxyYXdfY29weV9mcm9tX3VzZXI6TygicmF3X2NvcHlfZnJvbV91c2VyIiwoYSxsLHUpPT57aWYoYT4+Pj0wLGw+Pj49MCx1Pj4+PTAsdT09PTApcmV0dXJuIDA7bGV0IF89JCgpO2lmKGwrdT5fLmxlbmd0aClyZXR1cm4gdTtsZXQgdz1SKCk7cmV0dXJuIGErdT53Lmxlbmd0aCYmVSgicmF3X2NvcHlfZnJvbV91c2VyIixga2VybmVsLXNpZGUgZGVzdGluYXRpb24gb3V0IG9mIHJhbmdlICh0bz0weCR7YS50b1N0cmluZygxNil9IG49JHt1fSBrZXJuZWxfbGVuPTB4JHt3Lmxlbmd0aC50b1N0cmluZygxNil9KSBcdTIwMTQga2VybmVsIGJ1Z2ApLG5lKHcsYSxfLGwsdSksMH0pLHJhd19jbGVhcl91c2VyOk8oInJhd19jbGVhcl91c2VyIiwoYSxsKT0+e2lmKGE+Pj49MCxsPj4+PTAsbD09PTApcmV0dXJuIDA7bGV0IHU9JCgpO3JldHVybiBhK2w+dS5sZW5ndGg/bDoodS5maWxsKDAsYSxhK2wpLDApfSl9LGd1YXJkUGFyazpULHNldFBhcmtlZFNsb3RSZWFkZXI6RCxpbkxlYWZDcm9zc2luZzplZX19cyhVdCwibWFrZVVhY2Nlc3NMZWFmQm91bmRhcnkiKTt2YXIgbnI9dHlwZW9mIHNldEltbWVkaWF0ZT09ImZ1bmN0aW9uIixzcj10eXBlb2YgTWVzc2FnZUNoYW5uZWw9PSJmdW5jdGlvbiIsQ3Q9bnI/InNldEltbWVkaWF0ZSI6c3I/Ik1lc3NhZ2VDaGFubmVsIjoic2V0VGltZW91dCI7dmFyIG9yPTEwMCxOdD0wLGlyPTAsYXI9MDt2YXIgcGU9bnVsbCxrZT1bXSxscj1zKHQ9Pnt0eXBlb2YgdC5yZWY9PSJmdW5jdGlvbiImJnQucmVmKCl9LCJtYWNyb3Rhc2tQb3J0UmVmIikscnQ9cyh0PT57dHlwZW9mIHQudW5yZWY9PSJmdW5jdGlvbiImJnQudW5yZWYoKX0sIm1hY3JvdGFza1BvcnRVbnJlZiIpO2Z1bmN0aW9uIHVyKCl7aWYocGU9PT1udWxsKXtsZXQgdD1uZXcgTWVzc2FnZUNoYW5uZWw7dC5wb3J0MS5vbm1lc3NhZ2U9KCk9PntsZXQgcj1rZS5zaGlmdCgpO3ImJnIoKSxrZS5sZW5ndGg9PT0wJiZydCh0LnBvcnQxKX0scnQodC5wb3J0MSkscnQodC5wb3J0MikscGU9dH1yZXR1cm4gbmV3IFByb21pc2UodD0+e2tlLmxlbmd0aD09PTAmJmxyKHBlLnBvcnQxKSxrZS5wdXNoKHQpLHBlLnBvcnQyLnBvc3RNZXNzYWdlKDApfSl9cyh1ciwicG9ydFR1cm4iKTtmdW5jdGlvbiBDKCl7aWYoYXIrKyxDdD09PSJzZXRJbW1lZGlhdGUiKXJldHVybiBuZXcgUHJvbWlzZShmPT57c2V0SW1tZWRpYXRlKGYpfSk7aWYoQ3QhPT0iTWVzc2FnZUNoYW5uZWwiKXJldHVybiBuZXcgUHJvbWlzZShmPT57c2V0VGltZW91dChmLDApfSk7bGV0IHQ9dXIoKSxyPURhdGUubm93KCk7cmV0dXJuIHItTnQ8b3I/dDooTnQ9cixpcisrLHQudGhlbigoKT0+bmV3IFByb21pc2UoZj0+e3NldFRpbWVvdXQoZiwwKX0pKSl9cyhDLCJtYWNyb3Rhc2tUdXJuIik7dmFyIE90PTAsQnQ9bmV3IFdlYWtTZXQ7ZnVuY3Rpb24ganQoe3Bvc3Q6dCxvbk1lc3NhZ2U6cixvblRlcm1pbmF0ZTpmLGNhbGxIb3N0U3luYzptfSl7bGV0IHY9e3JlcXVlc3RlZDohMX07Zj8uKCgpPT57di5yZXF1ZXN0ZWQ9ITB9KTtsZXQgTj1udWxsLGc9bnVsbDtyKGFzeW5jIGs9Pnt0cnl7aWYoaz8ua2luZD09PSJkZXZpY2VzLXJlYWR5Iil7aWYoTj1rLGcpe2xldCBwPWc7Zz1udWxsLHAoKX1yZXR1cm59aWYoaz8ua2luZCE9PSJib290Iil7dCh7a2luZDoiZXJyb3IiLG1lc3NhZ2U6YHVua25vd24gbXNnICR7az8ua2luZH1gfSk7cmV0dXJufWF3YWl0IGNyKGssdCx2LG0se2dldDpzKCgpPT5OLCJnZXQiKSx3YWl0OnMoKCk9Pm5ldyBQcm9taXNlKHA9PntnPXB9KSwid2FpdCIpfSl9Y2F0Y2gocCl7bGV0IFQ9cCBpbnN0YW5jZW9mIEVycm9yP2Ake3AubWVzc2FnZX0KJHtwLnN0YWNrPz8iIn1gOlN0cmluZyhwKTt0KHtraW5kOiJlcnJvciIsbWVzc2FnZTpUfSl9fSl9cyhqdCwiYmluZEtlcm5lbFdvcmtlciIpO2FzeW5jIGZ1bmN0aW9uIGNyKHQscixmPXtyZXF1ZXN0ZWQ6ITF9LG09dm9pZCAwLHY9dm9pZCAwKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCwiaW5pdHJhbWZzIikpe3Ioe2tpbmQ6ImVycm9yIixtZXNzYWdlOiJrZXJuZWxXb3JrZXI6IGluaXRyYW1mcyBpcyB1bnN1cHBvcnRlZDsgbm8gZmFsbGJhY2sgcm9vdC4ifSk7cmV0dXJufWxldCBOPW5ldyBUZXh0RGVjb2RlcigidXRmLTgiLHtmYXRhbDohMX0pLGc9dC5wYXVzZUJ1ZmZlcj9uZXcgSW50MzJBcnJheSh0LnBhdXNlQnVmZmVyKTpudWxsLGs9cygoKT0+e2lmKGcpZm9yKDtBdG9taWNzLmxvYWQoZywwKT09PTE7KUF0b21pY3Mud2FpdChnLDAsMSwyMDApfSwibWF5YmVQYXVzZSIpO2Z1bmN0aW9uIHAoZSxuLGkpe2xldCBjPW5ldyBVaW50OEFycmF5KHQua2VybmVsTWVtb3J5LmJ1ZmZlcixuLGkpLGg9bmV3IFVpbnQ4QXJyYXkoaSk7aC5zZXQoYyk7bGV0IEU9Ti5kZWNvZGUoaCk7cih7a2luZDoiZG1lc2ciLGxldmVsOmV8MCx0ZXh0OkV9KX1zKHAsImRtZXNnIik7bGV0IFQ9T2JqZWN0LmZyZWV6ZSh7a2luZDoidmlydGlvLWRyYWluLXN5bmMifSksRD0xZTQsZWU9MWU2LHRlPTY1NTM1LHJlPTFlMywkPSExLEE9MCxQPTAsUj0wLEw9ITEsbmU9MDtmdW5jdGlvbiBVKCl7QT0wLFA9MCxSPTAsTD0hMX1zKFUsIm5vdGVIb3N0VGhyZWFkVHVybiIpO2Z1bmN0aW9uIE8oKXtsZXQgZT1FcnJvci5zdGFja1RyYWNlTGltaXQsbj0iIjt0cnl7RXJyb3Iuc3RhY2tUcmFjZUxpbWl0PTIwMCxuPW5ldyBFcnJvcigpLnN0YWNrfHwiIn1jYXRjaHt9ZmluYWxseXt0cnl7RXJyb3Iuc3RhY2tUcmFjZUxpbWl0PWV9Y2F0Y2h7fX1sZXQgaT1bXTtmb3IobGV0IGMgb2Ygbi5zcGxpdChgCmApKXtsZXQgaD0vYXRccysoPzooW15ccyhdKylccytcKCk/d2FzbTpcL1wvd2FzbVwvW15ccyldKlwpPy8uZXhlYyhjKTtpZighaCljb250aW51ZTtsZXQgRT0oaFsxXXx8IiIpLnRyaW0oKTtpZihpLnB1c2goRXx8Ijx1bm5hbWVkIHdhc20gZnJhbWU+IiksaS5sZW5ndGg+PTI0KWJyZWFrfXJldHVybiBpfXMoTywibWVyZ2VkU3Bpbkd1ZXN0RnJhbWVzIik7ZnVuY3Rpb24gdmUoZSl7aWYoISR8fCgrK0EmdGUpIT09MClyZXR1cm47bGV0IG49RGF0ZS5ub3coKTtpZihQPT09MCl7UD1uO3JldHVybn1sZXQgaT1uLVA7aWYoIUwmJmk+PXJlKXtMPSEwO2xldCBqPSsrbmU7aWYoKGomai0xKT09PTApe2xldCBYPU8oKTtyKHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLW1lcmdlZCBTUElOICMke2p9IFx1MjAxNCBDUFUgMCBoYXMgaGVsZCB0aGUgbWVyZ2VkIEpTIHRocmVhZCBmb3IgJHtpfSBtcyBhY3Jvc3MgJHtBfSBsaW51eC4ke2V9IGNhbGxzIHdpdGggbm8gcmV0dXJuIHRvIHRoZSBkcml2ZSBsb29wICgke1J9IHVuc2VydmljZWQgZG9vcmJlbGwocykpLiBOb3QgZmF0YWwgeWV0IFx1MjAxNCB0aGUgZGVhZGxvY2sgdmVyZGljdCBuZWVkcyAke0R9IG1zIFx1MjAxNCBidXQgZXZlcnkgY28tcmVzaWRlbnQgYW5kIGV2ZXJ5IGRldmljZSBiYWNrZW5kIG9uIHRoaXMgdGhyZWFkIHdhcyBzdGFydmVkIGZvciB0aGF0IHdob2xlIHRpbWUuIGArKFgubGVuZ3RoPjA/YFRIRSBMT09QIElTOiAke1guam9pbigiIDwtICIpfWA6IlRIRSBMT09QIENPVUxEIE5PVCBCRSBOQU1FRCAobm8gd2FzbSBmcmFtZXMgaW4gRXJyb3Iuc3RhY2sgb24gdGhpcyBydW50aW1lKS4iKX0pfX1pZihpPER8fEE8ZWUpcmV0dXJuO2xldCBjPUEsaD1SLEU9TygpO3Rocm93IFUoKSxuZXcgRXJyb3IoYGh3anMtbWVyZ2VkIERFQURMT0NLOiBDUFUgMCBoYXMgaGVsZCB0aGUgbWVyZ2VkIEpTIHRocmVhZCBmb3IgJHtpfSBtcyBhY3Jvc3MgJHtjfSBsaW51eC4ke2V9IGNhbGxzIHdpdGhvdXQgb25lIHJldHVybiB0byB0aGUgaG9zdCBkcml2ZSBsb29wLiBUaGUgZ3Vlc3QgaXMgaW4gYW4gaW4ta2VybmVsIEJVU1ktV0FJVCAob24gdGhpcyBhcmNoIGNwdV9yZWxheCgpIElTIGxpbnV4LmNwdV9yZWxheF9ob3N0IFx1MjAxNCBhc20vYmFycmllci5oIFx1MjAxNCBhbmQgaXQgaXMgbm90IGEgc3VzcGVuZCBwb2ludCksIGFuZCAke2h9IHZpcnRpbyBkb29yYmVsbChzKSB3ZXJlIHJ1bmcgZHVyaW5nIHRoYXQgcnVuIGFuZCBOT1QgT05FIHdhcyBzZXJ2aWNlZCwgYmVjYXVzZSB0aGUgYmFja2VuZCB0aGF0IHdvdWxkIHNlcnZpY2UgdGhlbSBpcyBvbiB0aGlzIHNhbWUgdGhyZWFkLiBDUFUgMCdzIG9ubHkgaGFuZGJhY2sgaXMgdGhlIElETEUgcGFyaywgd2hpY2ggYSBydW5uYWJsZSBidXN5LXdhaXRpbmcgdGFzayBuZXZlciByZWFjaGVzLCBhbmQgdGhlIGRyaXZlIGxvb3AncyBxdWFudHVtIGlzIG1lYXN1cmVkIGJldHdlZW4gaHdqc19yZXN1bWUgcmV0dXJucywgd2hpY2ggbmV2ZXIgaGFwcGVuLiBUaGUgaG9zdCBjYW5ub3QgY2xvc2UgdGhpcyBmcm9tIGluc2lkZSBhIHN5bmNocm9ub3VzIGltcG9ydDogaXQgY2FuIG5laXRoZXIgdHVybiB0aGUgZXZlbnQgbG9vcCBub3IgcmVzb2x2ZSBhIHByb21pc2UsIGFuZCBldmVyeSBGVVNFIHJlcGx5IGFuZCBldmVyeSB2aXJ0aW8tbmV0IHJlcGx5IGlzIGEgcHJvbWlzZS4gV0hBVCBFTkRTIElUIGlzIGEga2VybmVsLXNpZGUgeWllbGQgb24gd2FzbV9tZXJnZWRfY3B1MCB0aGF0IGlzIG5vdCB0aGUgaWRsZSBwYXJrLiBXSElDSCBMRVZFUiBkZXBlbmRzIG9uIFdIRVJFIHRoZSBsb29wIGJlbG93IGlzLCBhbmQgdGhpcyBzZW50ZW5jZSB1c2VkIHRvIG5hbWUgYSBkb29yIHRoYXQgaXMgYWxyZWFkeSBvcGVuOiB3YXNtMzJfcGFya19hbGxvd2VkKCkgZG9lcyBOT1QgcmVmdXNlIGEgbWVyZ2VkIENQVSAwIFx1MjAxNCBwYXJrLmMncyBrZXJuZWwtV29ya2VyIGNsYXVzZSByZWFkcyBcYGNvb3Bfc2NoZWQgJiYgIW1lcmdlZF9jcHUwXGAgYW5kIHBhcmsuYydzIGNvbnN1bWVyIHN3aXRjaCBzdWJzdGl0dXRlcyBDT05TVU1FUl9IT1NUIGZvciBpdCwgc28gYSBDUFUtMCBjaGFpbiBtYXkgcGFyayBhbmQgcGFya19zdXNwZW5kKCkgYnJhY2tldHMgaXQgd2l0aCB3YXNtMzJfY3B1MF9oYW5kYmFja19wYXJrXyouIFdoYXQgaXMgbWlzc2luZyBpcyBhIENBTExFUjogbm8gaW4ta2VybmVsIGJ1c3ktd2FpdCBhc2tzLiBJZiB0aGUgbG9vcCBpcyBpbiBhcmNoL3dhc20zMiwgZ2l2ZSB0aGF0IGxlYWYgYSB3YXNtMzJfY29vcGVyYXRpdmVfcGFyaygpIGFuZCBpdCB3aWxsIGJlIHRha2VuLiBJZiBpdCBpcyBpbiBhIERSSVZFUiBcdTIwMTQgYXMgdGhpcyBvbmUgaXMgXHUyMDE0IHRoYXQgaXMgbm90IGF2YWlsYWJsZTogY3B1X3JlbGF4KCkgbWF5IG5vdCBiZWNvbWUgYSBzdXNwZW5kIHBvaW50LCBiZWNhdXNlIGl0IGlzIGlubGluZWQgaW50byBuYXRpdmUgc2NoZWR1bGVyIGludGVybmFscyB1bmRlciBycS0+bG9jayAoYXJjaC93YXNtMzIvS2NvbmZpZyBzdGF0ZXMgaXQpLCBhbmQgdGhpcyB0cmVlIGZvcmtzIG5vIGZpbGUgb3V0c2lkZSBhcmNoL3dhc20zMi4gRm9yIGEgZHJpdmVyIGxvb3AgdGhlIG9ubHkgbGV2ZXIgaXMgQ09ORklHX1dBU00zMl9DT1JPX1NBRkVQT0lOVFMsIHdoaWNoIHBsYWNlcyBhIGJ1ZGdldGVkIGNoZWNrcG9pbnQgb24gdGhlIGJhY2stZWRnZSBcdTIwMTQgZGVmYXVsdCBuLCBhbmQgdGhlIHJlYXNvbiBpcyB3cml0dGVuIGF0IHRoZSBsaW5lIHRoYXQgd291bGQgdHVybiBpdCBvbiAoZGlzdHJvcy9jb21tb24vbGludXgtNi4xMi9jb25maWcvY29tbW9uLmZyYWdtZW50KS4gYCsoRS5sZW5ndGg+MD9gVEhFIExPT1AgSVM6ICR7RS5qb2luKCIgPC0gIil9YDpgVEhFIExPT1AgQ09VTEQgTk9UIEJFIE5BTUVEOiB0aGlzIHJ1bnRpbWUgcHV0IG5vIHdhc20gZnJhbWVzIGluIEVycm9yLnN0YWNrLCBzbyB0aGUgZ3Vlc3QgY2FsbCBwYXRoIGFib3ZlIGxpbnV4LiR7ZX0gaXMgbm90IHJlYWRhYmxlIGZyb20gaGVyZSBcdTIwMTQgcmVhZCBpdCBmcm9tIHRoZSBrZXJuZWwgc2lkZSBpbnN0ZWFkLmApKX1zKHZlLCJtZXJnZWRTcGluQ2hlY2siKTtsZXQgYT0yNTUsbD0wO2Z1bmN0aW9uIHUoKXskJiZtIT09dm9pZCAwJiYoKytsJmEpPT09MCYmbShUKSx2ZSgiY3B1X3JlbGF4X2hvc3QiKX1zKHUsImNwdV9yZWxheF9ob3N0Iik7ZnVuY3Rpb24gXygpe3JldHVybiB0eXBlb2YgcGVyZm9ybWFuY2U8InUiJiZwZXJmb3JtYW5jZS5ub3cmJnR5cGVvZiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luPT0ibnVtYmVyIj9CaWdJbnQoTWF0aC5yb3VuZCgocGVyZm9ybWFuY2UudGltZU9yaWdpbitwZXJmb3JtYW5jZS5ub3coKSkqMWU2KSk6QmlnSW50KERhdGUubm93KCkpKjEwMDAwMDBufXMoXywibm93X25zIik7ZnVuY3Rpb24gdyhlLG4saSl7cmV0dXJuICQmJm0hPT12b2lkIDAmJm0oVCksdmUoImF0b21pY193YWl0X2kzMiIpLDB9cyh3LCJhdG9taWNfd2FpdF9pMzIiKTtmdW5jdGlvbiB4KGUsbil7cmV0dXJuIDB9cyh4LCJhdG9taWNfbm90aWZ5Iik7bGV0IGI9cyhlPT4oLi4ubik9PihyKHtraW5kOiJ1bmltcGxlbWVudGVkLWhvc3QtY2FsbCIsbmFtZTplfSksMCksInN0dWJIb3N0IiksbnQ9VXQoe3VzZXJNZW1vcnk6bnVsbCxrZXJuZWxNZW1vcnk6dC5rZXJuZWxNZW1vcnkscmVmdXNlOnMoZT0+e3Rocm93IHIoe2tpbmQ6Imtlcm5lbC10cmFwIixtZXNzYWdlOmV9KSxuZXcgRXJyb3IoZSl9LCJyZWZ1c2UiKSxjb250ZXh0OiJzdGFuZGFsb25lIHZtbGludXggV29ya2VyIChrdGhyZWFkIGNvbnRleHQpIixyZWRQYXJrOiExfSksTHQ9NjU1MzYsYmU9NDA5Nix5ZT0tMSxzdD1zKCgpPT57aWYoeWU8MClyZXR1cm47bGV0IGU9bmV3IEludDMyQXJyYXkodC5rZXJuZWxNZW1vcnkuYnVmZmVyKTtBdG9taWNzLnN0b3JlKGUseWUsdC5rZXJuZWxNZW1vcnkuYnVmZmVyLmJ5dGVMZW5ndGgvYmV8MCl9LCJwdWJsaXNoQ29tbWl0dGVkUGFnZXMiKSxvdD1zKGU9PntsZXQgbj10Lmtlcm5lbE1lbW9yeSxpPW4uYnVmZmVyLmJ5dGVMZW5ndGg7aWYoZTw9aSlyZXR1cm4gaTtsZXQgYz1NYXRoLmNlaWwoKGUtaSkvTHQpO3RyeXtuLmdyb3coYyl9Y2F0Y2h7fWxldCBoPW4uYnVmZmVyLmJ5dGVMZW5ndGg7cmV0dXJuIGghPT1pJiYoc3QoKSxyKHtraW5kOiJrZXJuZWwtbWVtLWdyb3duIixieXRlczpofSkpLGh9LCJncm93S2VybmVsTWVtb3J5Iiksc2U9e2RtZXNnOnAsY3B1X3JlbGF4X2hvc3Q6dSxub3dfbnM6XyxtZW1fY29tbWl0OnMoZT0+e2xldCBuPShlPj4+MCkqYmU7cmV0dXJuIG90KG4pL2JlPj4+MH0sIm1lbV9jb21taXQiKSxhdG9taWNfd2FpdF9pMzI6dyxhdG9taWNfbm90aWZ5OngsLi4ubnQuaW1wb3J0cyxjb25zb2xlX3dyaXRlOmIoImNvbnNvbGVfd3JpdGUiKSxjb25zb2xlX3JlYWRfbm9uYmxvY2s6YigiY29uc29sZV9yZWFkX25vbmJsb2NrIiksaGx0OmIoImhsdCIpLG1tYXBfdXNlcl9wYWdlOmIoIm1tYXBfdXNlcl9wYWdlIiksbXVubWFwX3VzZXJfcGFnZTpiKCJtdW5tYXBfdXNlcl9wYWdlIiksc3Bhd25fd29ya2VyOmIoInNwYXduX3dvcmtlciIpLHRlcm1pbmF0ZV93b3JrZXI6YigidGVybWluYXRlX3dvcmtlciIpLHNpZ25hbF9pbmplY3Q6Yigic2lnbmFsX2luamVjdCIpLHZpcnRpb19raWNrOnMoKGUsbik9PntSKysscih7a2luZDoidmlydGlvLWtpY2siLGRldmlkOmU+Pj4wLHFpZHg6bj4+PjB9KX0sInZpcnRpb19raWNrIil9LHF0PXtrZXJuZWxfbWVtb3J5OnQua2VybmVsTWVtb3J5LC4uLnQua2VybmVsSW1wb3J0cz8uZW52Pz97fX0sQj0wLHk9bnVsbCxpdD1zKGU9PntpZighQnx8IXkpcmV0dXJuO2xldCBuPXlbQj4+Ml07aWYobiE9PTApe2xldCBpPWBod2pzIHJ1bnRpbWUgZ2F0ZSAoaG9zdCBsZWcpOiBwYXJrZWQgc2xvdCBOT1QgRU1QVFkgYXQgaG9zdCBpbXBvcnQgJyR7ZX0nIChoYW5kbGU9MHgke24udG9TdHJpbmcoMTYpfSkgXHUyMDE0IGEgbGVha2VkIHNsaWNlIGNyb3NzZWQgdGhlIGhvc3QgYm91bmRhcnlgO3Rocm93IHIoe2tpbmQ6Imtlcm5lbC10cmFwIixtZXNzYWdlOml9KSxuZXcgRXJyb3IoaSl9fSwiaHdqc1BhcmtlZENoZWNrIiksYXQ9cygoZSxuKT0+KC4uLmkpPT4oaXQoZSksbiguLi5pKSksImh3anNHdWFyZCIpLFd0PXMoKGUsbik9PiguLi5pKT0+e2xldCBjPW4oLi4uaSk7cmV0dXJuIGl0KGUpLGN9LCJod2pzR3VhcmREbWVzZ0xhc3QiKTtmb3IobGV0IGUgb2YgT2JqZWN0LmtleXMoc2UpKXNlW2VdPShlPT09ImRtZXNnIj9XdDphdCkoYGxpbnV4LiR7ZX1gLHNlW2VdKTtsZXQgRnQ9e3Bhcms6bnQuZ3VhcmRQYXJrKGF0KCJod2pzX3N1c3BlbmQucGFyayIsKCk9Pnt9KSl9LHhlPXtlbnY6cXQsbGludXg6c2UsaHdqc19zdXNwZW5kOkZ0fSxvZT10LnZtbGludXhNb2R1bGU7aWYoIShvZSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lk1vZHVsZSkpe3Ioe2tpbmQ6Imluc3RhbnRpYXRlLWVycm9yIixtZXNzYWdlOnQudm1saW51eENvbXBpbGVFcnJvcj9gdm1saW51eCBkaWQgbm90IGNvbXBpbGUgb24gdGhlIHBvc3RpbmcgdGhyZWFkOiAke3Qudm1saW51eENvbXBpbGVFcnJvcn1gOiJib290IG1lc3NhZ2UgY2FycmllZCBubyBjb21waWxlZCB2bWxpbnV4IE1vZHVsZSAoa2VybmVsV29ya2VyIGV4cGVjdHMgaW5pdC52bWxpbnV4TW9kdWxlIFx1MjAxNCBzZWUgYm9vdEtlcm5lbC50cykuIn0pO3JldHVybn1sZXQgbHQ9UnQob2UpO2lmKGx0Lmxlbmd0aD4wKXtyKHtraW5kOiJpbnN0YW50aWF0ZS1lcnJvciIsbWVzc2FnZTpgdWFjY2Vzcy1sZWFmLXdpdG5lc3M6IHJlZnVzaW5nIHRvIGJvb3QgdGhpcyB2bWxpbnV4Lndhc206CiAgLSBgK2x0LmpvaW4oYAogIC0gYCl9KTtyZXR1cm59bGV0IEh0PVdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG9lKSxTZT1bXTtmb3IobGV0IGUgb2YgSHQpe2xldCBuPU9iamVjdC5oYXNPd24oeGUsZS5tb2R1bGUpP3hlW2UubW9kdWxlXTp2b2lkIDA7KCFufHwhT2JqZWN0Lmhhc093bihuLGUubmFtZSkpJiZTZS5wdXNoKGAke2UubW9kdWxlfS4ke2UubmFtZX0gKCR7ZS5raW5kfSlgKX1pZihTZS5sZW5ndGg+MCl7cih7a2luZDoibGluay1lcnJvciIsbWlzc2luZzpTZX0pO3JldHVybn1sZXQgdXQ7dHJ5e2lmKHQua2VybmVsTWVtb3J5JiZCdC5oYXModC5rZXJuZWxNZW1vcnkpKXtyKHtraW5kOiJpbnN0YW50aWF0ZS1lcnJvciIsbWVzc2FnZTpgSzEwLUE0IFItSzEwLVcxIGludmFyaWFudCB2aW9sYXRlZDogdm1saW51eC53YXNtIGhhcyBhbHJlYWR5IGJlZW4gaW5zdGFudGlhdGVkIGFnYWluc3QgVEhJUyBlbnYua2VybmVsX21lbW9yeSAodGhpcyByZWFsbSBoYXMgaW5zdGFudGlhdGVkICR7T3R9IGtlcm5lbChzKSBpbiB0b3RhbCkuIFRoZSBLMTAtQiBhY3RpdmUtc2VnbWVudCBvdmVybGF5IGFzc3VtZXMgc2luZ2xlLWluc3RhbmNlIHZtbGludXggcGVyIGVudi5rZXJuZWxfbWVtb3J5OyByZS1pbnN0YW50aWF0aW9uIHdvdWxkIHJlLXdyaXRlIHRoZSAuaW5pdGNhbGxfYW5jaG9yLiogYWN0aXZlIG92ZXJsYXlzIGludG8gc2hhcmVkIGtlcm5lbCBtZW1vcnkgYW5kIGNvcnJ1cHQgdGhlIHJ1bm5pbmcga2VybmVsJ3MgaW5pdGNhbGwgYXJyYXlzLiBTZWUgZG9jcy9BUkNISVRFQ1RVUkUubWQgXHhBNzE1LjMgUi1LMTAtVzEgKG1pZ3JhdGlvbiBwYXRoOiBzd2l0Y2ggdG8gc3RyYXRlZ3kgQSwga2VlcGluZyAuaW5pdGNhbGwqLmluaXQgc2VnbWVudHMgcGFzc2l2ZSB3aXRoIC0tZGVmc3ltIGFuY2hvcnMpLiBOT1RFOiBhIHBvd2VyIGN5Y2xlIGlzIE5PVCB0aGlzIFx1MjAxNCBlYWNoIGJvb3QgYnVpbGRzIGEgZnJlc2ggUGh5c1JhbSBhbmQgdGhlcmVmb3JlIGEgZnJlc2ggbWVtb3J5IFx1MjAxNCBzbyBpZiB5b3UgYXJlIHNlZWluZyB0aGlzIG9uIGEgcmVzdGFydCwgdGhlIG1lbW9yeSB3YXMgcmV1c2VkIGFuZCB0aGF0IGlzIHRoZSBkZWZlY3QgdG8gY2hhc2UsIG5vdCB0aGlzIHJlZnVzYWwuYH0pO3JldHVybn11dD1hd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShvZSx4ZSksT3QrPTEsdC5rZXJuZWxNZW1vcnkmJkJ0LmFkZCh0Lmtlcm5lbE1lbW9yeSl9Y2F0Y2goZSl7bGV0IG49ZSBpbnN0YW5jZW9mIEVycm9yP2UubWVzc2FnZTpTdHJpbmcoZSk7cih7a2luZDoiaW5zdGFudGlhdGUtZXJyb3IiLG1lc3NhZ2U6bn0pO3JldHVybn1sZXQgbz11dC5leHBvcnRzO28uX19od2pzX3BhcmtlZCYmdHlwZW9mIG8uX19od2pzX3BhcmtlZC52YWx1ZT09Im51bWJlciImJihCPW8uX19od2pzX3BhcmtlZC52YWx1ZT4+PjAseT1uZXcgVWludDMyQXJyYXkodC5rZXJuZWxNZW1vcnkuYnVmZmVyKSxyKHtraW5kOiJod2pzLXBhcmtlZC1vZmZzZXQiLG9mZnNldDpCfSkpO2xldCBpZT1zKGU9Pm9bZV0mJnR5cGVvZiBvW2VdLnZhbHVlPT0ibnVtYmVyIj9vW2VdLnZhbHVlPj4+MDowLCJod2pzRGF0YU9mZnNldCIpLGFlPXtoaWdoV2F0ZXI6aWUoIl9faHdqc19mcmFtZV9oaWdoX3dhdGVyIiksbGl2ZTppZSgiX19od2pzX2ZyYW1lX2xpdmUiKSxhbGxvY3M6aWUoIl9faHdqc19mcmFtZV9hbGxvY3MiKX0sR3Q9cygoKT0+IXl8fCFhZS5oaWdoV2F0ZXI/bnVsbDp7aGlnaFdhdGVyOnlbYWUuaGlnaFdhdGVyPj4yXSxsaXZlOnlbYWUubGl2ZT4+Ml0sYWxsb2NzOnlbYWUuYWxsb2NzPj4yXX0sImh3anNBcmVuYVN0YXRzIiksRWU9cygoKT0+e2xldCBlPUd0KCk7cmV0dXJuIGU/YCBbaHdqcyBhcmVuYTogaGlnaC13YXRlcj0ke2UuaGlnaFdhdGVyfSBsaXZlPSR7ZS5saXZlfSBhbGxvY3M9JHtlLmFsbG9jc31dYDoiIn0sImh3anNBcmVuYVN1ZmZpeCIpLGN0PTE8PDIwO2lmKHR5cGVvZiBvLl9faHdqc19idWRnZXRfc2V0PT0iZnVuY3Rpb24iJiZvLl9faHdqc19idWRnZXRfc2V0KGN0fDApLHR5cGVvZiBvLl9fd2FzbV9jYWxsX2N0b3JzPT0iZnVuY3Rpb24iKXRyeXtvLl9fd2FzbV9jYWxsX2N0b3JzKCl9Y2F0Y2goZSl7bGV0IG49ZSBpbnN0YW5jZW9mIEVycm9yP2UubWVzc2FnZTpTdHJpbmcoZSk7cih7a2luZDoiY3RvcnMtdHJhcCIsbWVzc2FnZTpufSk7cmV0dXJufWlmKHR5cGVvZiBvLndhc21fc3RhcnRfa2VybmVsIT0iZnVuY3Rpb24iKXtyKHtraW5kOiJuby1lbnRyeSIsbWVzc2FnZToidm1saW51eC53YXNtIGhhcyBubyB3YXNtX3N0YXJ0X2tlcm5lbCBleHBvcnQifSk7cmV0dXJufWxldCBsZT1vLl9faGVhcF9iYXNlO2lmKHR5cGVvZiBsZSE9Im9iamVjdCJ8fGxlPT09bnVsbHx8dHlwZW9mIGxlLnZhbHVlIT0ibnVtYmVyIil7cih7a2luZDoibm8tZW50cnkiLG1lc3NhZ2U6InZtbGludXgud2FzbSBoYXMgbm8gX19oZWFwX2Jhc2UgaTMyIGdsb2JhbCBleHBvcnQifSk7cmV0dXJufWxldCB1ZT1sZS52YWx1ZT4+PjAsY2U9by53YXNtMzJfY29tbWl0dGVkX3BhZ2VzLHE9ISEoY2UmJnR5cGVvZiBjZS52YWx1ZT09Im51bWJlciIpO3EmJih5ZT1jZS52YWx1ZT4+PjA+PjIpO2xldCBXPXMoZT0+ZSsxNSYtMTYsImFsaWduMTYiKSxGPVcodWUpLCRlPTQwOTYsZHQ9MSxBZT00MDk2LG10PTIsSWU9NDA5NixmdD0zLE1lPTQwOTYsaHQ9NSxfdD00MDk2LFZ0PTYsVGU9NDA5Nix3dD03LEt0PU51bWJlcih0Lmtlcm5lbE1heEJ5dGVzKXx8dC5rZXJuZWxNZW1vcnkuYnVmZmVyLmJ5dGVMZW5ndGgsZD10LmNtZGxpbmU/PyIiLGd0PTEsSD0hMCxQZT1vLndhc20zMl9jcHUwX3BhcmssST1QZSYmdHlwZW9mIFBlLnZhbHVlPT0ibnVtYmVyIj9QZS52YWx1ZT4+PjA6MCxSZT1uZXcgVWludDMyQXJyYXkodC5rZXJuZWxNZW1vcnkuYnVmZmVyKSxHPW5ldyBJbnQzMkFycmF5KHQua2VybmVsTWVtb3J5LmJ1ZmZlcikscHQ9MCx6dD0xLFl0PTI7aWYoSCl7aWYoIUkpe3Ioe2tpbmQ6ImVycm9yIixtZXNzYWdlOiJDT0xMQVBTRUQgQ1BVIDA6IHRoaXMgdm1saW51eC53YXNtIGV4cG9ydHMgbm8gd2FzbTMyX2NwdTBfcGFyayBcdTIwMTQgaXQgaGFzIG5vIG1lcmdlZCBkaXNwYXRjaGVyLCBzbyBpdHMgaWRsZSBwYXRoIGlzIHN0aWxsIG1lbW9yeS5hdG9taWMud2FpdDMyIG9uIF9fc2NoZWRfd2FrZXVwX3dvcmQgYW5kIGl0IHdvdWxkIGJsb2NrIHRoZSBvbmUgSlMgdGhyZWFkIHRoaXMgbWFjaGluZSBoYXMgKGtlcm5lbFx1MjE5NGhvc3QgbG9ja3N0ZXA6IGhhcmR3YXJlanMgYW5kIHBhY2thZ2VzL21vZGlmaWVkL2xpbnV4IHNoaXAgdG9nZXRoZXI7IGRlcGxveSBvcmRlciBpcyBob3N0IGZpcnN0LCB0aGVuIG1hY2hpbmUgaW1hZ2VzKS4gUmVmdXNpbmcgdG8gYm9vdCByYXRoZXIgdGhhbiBzdGFydGluZyBhIG1hY2hpbmUgdGhhdCB3ZWRnZXMgYXQgaXRzIGZpcnN0IGlkbGUuIFRIRVJFIElTIE5PIE9USEVSIFRPUE9MT0dZIFRPIFBVVCBUSElTIElNQUdFIE9OIFx1MjAxNCBtZXJnZWRDcHVIb3N0OidzZXBhcmF0ZScgd2FzIGRlbGV0ZWQgd2hlbiB0aGUgbWVyZ2VkIHBhdGggYm9vdGVkIHRoZSBhcHBsaWFuY2UgZW5kIHRvIGVuZCBcdTIwMTQgc28gdGhlIGZpeCBpcyB0byByZWJ1aWxkIHRoZSBrZXJuZWwgZnJvbSBhIHRyZWUgY2FycnlpbmcgUExBTi1DT0xMQVBTRUQtQ1BVMCBceEE3My4xLiJ9KTtyZXR1cm59bGV0IGU9UmVbKEk+PjIpKzFdPj4+MDtpZihlIT09Z3Qpe3Ioe2tpbmQ6ImVycm9yIixtZXNzYWdlOmBDT0xMQVBTRUQgQ1BVIDA6IHRoaXMgdm1saW51eC53YXNtIHB1Ymxpc2hlcyBtZXJnZWQtQ1BVMCBBQkkgdmVyc2lvbiAke2V9OyB0aGlzIGhvc3Qgc3BlYWtzIHZlcnNpb24gJHtndH0uIFRoZSBwYXJrIGJsb2NrJ3MgbGF5b3V0IGlzIHRoZSBjb250cmFjdCBiZXR3ZWVuIHRoZSB0d28gaGFsdmVzIGFuZCBhIG1pc21hdGNoIHJlYWRzIG9uZSBoYWxmJ3MgZmllbGRzIGF0IHRoZSBvdGhlcidzIG9mZnNldHMuIFJlZnVzaW5nLmB9KTtyZXR1cm59ZD1gJHtkfSR7ZD8iICI6IiJ9d2FzbV9tZXJnZWRfY3B1MGAscih7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1tZXJnZWQ6IENQVSAwIGlzIGNvLXJlc2lkZW50IHdpdGggcG9vbCBsYW5lIDEgb24gdGhpcyBKUyB0aHJlYWQ7IHZtbGludXggcHVibGlzaGVzIHdhc20zMl9jcHUwX3BhcmsgQDB4JHtJLnRvU3RyaW5nKDE2KX0gKGFiaSAke2V9KTsgY21kbGluZSBjYXJyaWVzIHdhc21fbWVyZ2VkX2NwdTAuCmB9KSxyKHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLW1lcmdlZDogYSBndWVzdCB3YWl0IHRoYXQgQkxPQ0tTIHRoaXMgdGhyZWFkIChhbiB1bmJvdW5kZWQgbWVtb3J5LmF0b21pYy53YWl0MzIpIGlzIHVuZGV0ZWN0YWJsZSBmcm9tIGhlcmUgXHUyMDE0IG5vIGltcG9ydCBydW5zLCBubyB0aW1lciBmaXJlcywgYW5kIGJvb3RLZXJuZWwncyB3YXRjaGRvZyBpcyBvbiB0aGlzIHRocmVhZCB0b28uIEEgbWVyZ2VkIG1hY2hpbmUgdGhhdCBnb2VzIHNpbGVudCBhdCB+MCUgQ1BVIGlzIGluIG9uZTsgdG9kYXkgdGhlIGtub3duIG9uZSBpcyBzcGF3bi5jJ3MgaG9zdF9zcGF3bl9wcm9jZXNzX3dvcmtlciBhdCBwaWQgMSdzIGV4ZWN2ZSwgd2hvc2UgY29vcGVyYXRpdmUgcGFyayB3YXNtMzJfcGFya19hbGxvd2VkKCkgcmVmdXNlcyBvbiBDUFUgMC4KYH0pLCQ9ITB9bGV0IGt0PXMoZT0+ZSs0MDk1Ji00MDk2LCJhbGlnblBhZ2UiKSx2dD1rdCh1ZSksZGU9dnQsUz1zKGU9PntsZXQgbj1kZTtyZXR1cm4gZGU9a3QobitlKSxufSwiY2FydmVEZXZpY2UiKSxVZT0wO3QudmlydGlvQmxrJiYoVWU9Uyg0MDk2KSxkPShkK2Agd2FzbV92aXJ0YmxrPTB4JHtVZS50b1N0cmluZygxNil9LDB4MTAwMCw4LCR7dC52aXJ0aW9CbGsuc2l6ZS81MTJ9LCR7dC52aXJ0aW9CbGsucmVhZE9ubHk/MTowfWApLnRyaW0oKSk7bGV0IENlPTAsTmU9MDt0LnZpcnRpb0ZzJiYoQ2U9UygkZSksZD0oZCtgIHdhc21fdmlydGlvZnM9MHgke0NlLnRvU3RyaW5nKDE2KX0sMHgkeyRlLnRvU3RyaW5nKDE2KX0sJHtkdH1gKS50cmltKCkpLHQudmlydGlvRnNDYWNoZSYmKE5lPVMoX3QpLGQ9KGQrYCB3YXNtX3ZpcnRpb2ZzX2NhY2hlPTB4JHtOZS50b1N0cmluZygxNil9LDB4JHtfdC50b1N0cmluZygxNil9LCR7VnR9YCkudHJpbSgpKTtsZXQgYnQ9ImE4YjhnOHI4Iix5dD0xOTIwLHh0PTEwODAsUXQ9Mzg0MCxadD0yMTYwLE9lPTAsVj0wLEs9MCxtZT0wLEJlPTAsej0wLFk9MDtpZih0LmZyYW1lYnVmZmVyKXt6PU1hdGgubWF4KHl0LE1hdGgubWluKFF0LHQuZnJhbWVidWZmZXIubWF4V2lkdGh8MHx8eXQpKSxZPU1hdGgubWF4KHh0LE1hdGgubWluKFp0LHQuZnJhbWVidWZmZXIubWF4SGVpZ2h0fDB8fHh0KSksVj10LmZyYW1lYnVmZmVyLndpZHRofDB8fDY0MCxLPXQuZnJhbWVidWZmZXIuaGVpZ2h0fDB8fDQ4MCxWPU1hdGgubWF4KDE2LE1hdGgubWluKHosVikpLEs9TWF0aC5tYXgoMTYsTWF0aC5taW4oWSxLKSksbWU9eio0LEJlPW1lKlkrNDA5NSYtNDA5NixPZT1TKEJlKTtsZXQgZT1gMHgke09lLnRvU3RyaW5nKDE2KX0sJHtWfSwke0t9LCR7bWV9LCR7YnR9LCR7en0sJHtZfWA7ZD0oZCtgIHdhc21fZHJtZmI9JHtlfWApLnRyaW0oKSx0LmZyYW1lYnVmZmVyLnN1cHByZXNzSG90cGx1ZyYmKGQ9KGQrIiB3YXNtX2RybWZiX25vaG90cGx1ZyIpLnRyaW0oKSksdC5mcmFtZWJ1ZmZlci5yZXNpemVHYXRlVGltZW91dE1zJiYoZD0oZCtgIHdhc21fZHJtZmJfcmVzaXplX2dhdGU9JHt0LmZyYW1lYnVmZmVyLnJlc2l6ZUdhdGVUaW1lb3V0TXN8MH1gKS50cmltKCkpfWxldCBqZT0wO2lmKHQudmlydGlvSW5wdXQpe2plPVMoQWUpO2xldCBuPXQudmlydGlvSW5wdXQuYWJzb2x1dGVQb2ludGVyPzE6MDtkPShkK2Agd2FzbV92aXJ0aW5wdXQ9MHgke2plLnRvU3RyaW5nKDE2KX0sMHgke0FlLnRvU3RyaW5nKDE2KX0sJHttdH0ke24/YCwke259YDoiIn1gKS50cmltKCl9bGV0IERlPTA7aWYodC52aXJ0aW9OZXQpe0RlPVMoSWUpO2xldCBlPTEsbj10LnZpcnRpb05ldC5tdHV8MCxpPXQudmlydGlvTmV0Lm1lcmdlUnhCdWY/ZTowLGM9bj4wJiZuIT09MTUwMCxoPWM/aT9gLCR7bn0sJHtpfWA6YCwke259YDoiIjtpJiYhYyYmcih7a2luZDoiZXJyb3IiLG1lc3NhZ2U6InZpcnRpb05ldC5tZXJnZVJ4QnVmIHdhcyByZXF1ZXN0ZWQgd2l0aCBubyBtdHUgKG9yIG10dSAxNTAwKTsgdGhlIGZsYWdzIGZpZWxkIG9mIHdhc21fdmlydG5ldD0gaXMgcG9zaXRpb25hbCBhbmQgY2Fubm90IGJlIHdyaXR0ZW4gd2l0aG91dCBhbiBtdHUgZmllbGQgYmVmb3JlIGl0LiBTZXQgdmlydGlvTmV0Lm10dS4ifSksZD0oZCtgIHdhc21fdmlydG5ldD0weCR7RGUudG9TdHJpbmcoMTYpfSwweCR7SWUudG9TdHJpbmcoMTYpfSwke2Z0fSR7aH1gKS50cmltKCl9bGV0IExlPTgxOTIsU3Q9NCxxZT0wO3QudXNiSGNkJiYocWU9UyhMZSksZD0oZCtgIHdhc21fdXNiPTB4JHtxZS50b1N0cmluZygxNil9LDB4JHtMZS50b1N0cmluZygxNil9LCR7U3R9YCkudHJpbSgpKTtsZXQgV2U9MDtpZih0LnZpcnRpb0NvbnNvbGUpe1dlPVMoTWUpO2xldCBlPXQudmlydGlvQ29uc29sZS5tYXhOclBvcnRzfDB8fDI7ZD0oZCtgIHdhc21fdmlydGNvbj0weCR7V2UudG9TdHJpbmcoMTYpfSwweCR7TWUudG9TdHJpbmcoMTYpfSwke2h0fSwke2V9YCkudHJpbSgpfWxldCBGZT0wO3QuaG9zdFRyYW5zcG9ydCYmKEZlPVMoVGUpLGQ9KGQrYCB3YXNtX2hvc3R0cmFucz0weCR7RmUudG9TdHJpbmcoMTYpfSwweCR7VGUudG9TdHJpbmcoMTYpfSwke3d0fWApLnRyaW0oKSksRj1XKGRlKTtsZXQgZmU9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGQpLFE9MTA0LGhlPVcoRitRKSxFdD1XKGhlK2ZlLmxlbmd0aCsxKSxIZT02NCxHZT1uZXcgVWludDhBcnJheShIZSksWj0hMTt0cnl7Z2xvYmFsVGhpcy5jcnlwdG8mJnR5cGVvZiBnbG9iYWxUaGlzLmNyeXB0by5nZXRSYW5kb21WYWx1ZXM9PSJmdW5jdGlvbiImJihnbG9iYWxUaGlzLmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoR2UpLFo9ITApfWNhdGNoe31sZXQgVmU9Wj9FdDowLEp0PVo/SGU6MCxfZT1aP1coVmUrSGUpOkV0LE09S3Q7aWYoX2U+PU0pe3Ioe2tpbmQ6ImVycm9yIixtZXNzYWdlOmBrZXJuZWwgbWVtb3J5IHRvbyBzbWFsbCBmb3IgaW1hZ2UgKyBkZXZpY2UgcmVnaW9ucyArIHByb2xvZ3VlOiBoZWFwX2Jhc2U9MHgke3VlLnRvU3RyaW5nKDE2KX0gZGV2aWNlX2Jsb2NrPVsweCR7dnQudG9TdHJpbmcoMTYpfSwweCR7ZGUudG9TdHJpbmcoMTYpfSkgdXNhYmxlX3N0YXJ0PTB4JHtfZS50b1N0cmluZygxNil9IHRvdGFsPTB4JHtNLnRvU3RyaW5nKDE2KX1gfSk7cmV0dXJufWxldCBLZT1xP19lOk07aWYob3QoS2UpPEtlKXtyKHtraW5kOiJlcnJvciIsbWVzc2FnZTpga2VybmVsIG1lbW9yeSBjb3VsZCBub3QgYmUgZ3Jvd24gdG8gJHtxPyJob2xkIHRoZSBib290IHByb2xvZ3VlIjoidGhlIGZ1bGwgc3BhbiB0aGlzIHByZS1kZW1hbmQtY29tbWl0IGtlcm5lbCByZXF1aXJlcyJ9OiBuZWVkIDB4JHtLZS50b1N0cmluZygxNil9IGJ5dGVzLCBlbnYua2VybmVsX21lbW9yeSBzdG9wcGVkIGF0IDB4JHt0Lmtlcm5lbE1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aC50b1N0cmluZygxNil9IChtYXhpbXVtIDB4JHtNLnRvU3RyaW5nKDE2KX0pYH0pO3JldHVybn1xfHxyKHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBoYXJkd2FyZWpzOiB0aGlzIHZtbGludXgud2FzbSBleHBvcnRzIG5vIHdhc20zMl9jb21taXR0ZWRfcGFnZXMgXHUyMDE0IGl0IGNhbm5vdCBhc2sgdGhlIGhvc3QgdG8gZ3JvdyBlbnYua2VybmVsX21lbW9yeSwgc28gdGhlIGZ1bGwgJHsoTS8oMTAyNCoxMDI0KSkudG9GaXhlZCgwKX0gTWlCIHNwYW4gd2FzIGNvbW1pdHRlZCBhdCBib290LiBBIGRlbWFuZC1jb21taXQga2VybmVsIHdvdWxkIGhhdmUgc3RhcnRlZCBhdCAkeyh0Lmtlcm5lbE1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aC8oMTAyNCoxMDI0KSkudG9GaXhlZCgwKX0gTWlCLmB9KTtsZXQgSj1uZXcgVWludDhBcnJheSh0Lmtlcm5lbE1lbW9yeS5idWZmZXIpO2lmKHQuYm9vdEluZm9PdmVycmlkZSl7aWYodC5ib290SW5mb092ZXJyaWRlLmxlbmd0aCE9PVEpe3Ioe2tpbmQ6ImVycm9yIixtZXNzYWdlOmBib290SW5mb092ZXJyaWRlIG11c3QgYmUgZXhhY3RseSAke1F9IGJ5dGVzLCBnb3QgJHt0LmJvb3RJbmZvT3ZlcnJpZGUubGVuZ3RofWB9KTtyZXR1cm59Si5zZXQodC5ib290SW5mb092ZXJyaWRlLEYpfWVsc2V7bGV0IGU9bmV3IEFycmF5QnVmZmVyKFEpLG49bmV3IERhdGFWaWV3KGUpO24uc2V0VWludDMyKDAsODI2ODg0Njk1LCEwKSxuLnNldFVpbnQzMig0LDQsITApLG4uc2V0VWludDMyKDgsUSwhMCksbi5zZXRVaW50MzIoMTIsMCwhMCksbi5zZXRCaWdVaW50NjQoMTYsQmlnSW50KE0pLCEwKSxuLnNldEJpZ1VpbnQ2NCgyNCxCaWdJbnQoX2UpLCEwKSxuLnNldEJpZ1VpbnQ2NCgzMixCaWdJbnQoTSksITApLG4uc2V0QmlnVWludDY0KDQwLDBuLCEwKSxuLnNldEJpZ1VpbnQ2NCg0OCxCaWdJbnQodWUpLCEwKSxuLnNldFVpbnQzMig1NixoZSwhMCksbi5zZXRVaW50MzIoNjAsZmUubGVuZ3RoLCEwKSxuLnNldFVpbnQzMig2NCx0Lm51bUNwdXN8MHx8MSwhMCksbi5zZXRVaW50MzIoNjgsMCwhMCksbi5zZXRCaWdVaW50NjQoNzIsMTAwMDAwMDAwMG4sITApLG4uc2V0VWludDMyKDgwLDAsITApLG4uc2V0VWludDMyKDg0LDAsITApLG4uc2V0VWludDMyKDg4LFZlPj4+MCwhMCksbi5zZXRVaW50MzIoOTIsSnQ+Pj4wLCEwKSxuLnNldEJpZ1VpbnQ2NCg5NixCaWdJbnQodC5kZWNsYXJlZE1lbW9yeUJ5dGVzPz9NKSwhMCksSi5zZXQobmV3IFVpbnQ4QXJyYXkoZSksRil9Si5zZXQoZmUsaGUpLEpbaGUrZmUubGVuZ3RoXT0wLFomJihKLnNldChHZSxWZSksR2UuZmlsbCgwKSk7bGV0IHdlPS0xLHplPW8uX19zY2hlZF93YWtldXBfd29yZDt6ZSYmdHlwZW9mIHplLnZhbHVlPT0ibnVtYmVyIiYmKHdlPXplLnZhbHVlPj4+MCxyKHtraW5kOiJzY2hlZC13YWtldXAtd29yZC1vZmZzZXQiLG9mZnNldDp3ZX0pKTtsZXQgWWU9by53YXNtMzJfc3Bhd25fcmluZztZZSYmdHlwZW9mIFllLnZhbHVlPT0ibnVtYmVyIiYmcih7a2luZDoic3Bhd24tcmluZy1vZmZzZXQiLG9mZnNldDpZZS52YWx1ZT4+PjB9KTtsZXQgUWU9by53YXNtMzJfc2lnbmFsX3Jpbmc7UWUmJnR5cGVvZiBRZS52YWx1ZT09Im51bWJlciImJnIoe2tpbmQ6InNpZ25hbC1yaW5nLW9mZnNldCIsb2Zmc2V0OlFlLnZhbHVlPj4+MH0pO2xldCBaZT1vLndhc20zMl90aWNrX3JlcTtaZSYmdHlwZW9mIFplLnZhbHVlPT0ibnVtYmVyIiYmcih7a2luZDoidGljay1yZXEtb2Zmc2V0IixvZmZzZXQ6WmUudmFsdWU+Pj4wfSk7bGV0IEplPW8ud2FzbTMyX3VzZXJfc2FiX3BhZ2VzO2lmKEplJiZ0eXBlb2YgSmUudmFsdWU9PSJudW1iZXIiJiZyKHtraW5kOiJ1c2VyLXNhYi1wYWdlcy1vZmZzZXQiLG9mZnNldDpKZS52YWx1ZT4+PjB9KSxxJiYoc3QoKSxyKHtraW5kOiJjb21taXR0ZWQtcGFnZXMtb2Zmc2V0IixvZmZzZXQ6Y2UudmFsdWU+Pj4wfSkpLHQudmlydGlvQmxrKXtyKHtraW5kOiJ2aXJ0aW8tYmxrLXdpbmRvdyIsYmFzZTpVZT4+PjB9KTtsZXQgZT1vLndhc20zMl92aXJ0aW9faXJxX3BlbmRpbmc7aWYoIWV8fHR5cGVvZiBlLnZhbHVlIT0ibnVtYmVyIil0aHJvdyBuZXcgRXJyb3IoInZpcnRpby1ibGsgcmVxdWlyZXMgd2FzbTMyX3ZpcnRpb19pcnFfcGVuZGluZyIpO3Ioe2tpbmQ6InZpcnRpby1pcnEtcGVuZGluZy1vZmZzZXQiLG9mZnNldDplLnZhbHVlPj4+MH0pfWlmKHQudmlydGlvRnNDYWNoZSYmcih7a2luZDoidmlydGlvLWZzLWNhY2hlLXdpbmRvdyIsYmFzZTpOZT4+PjB9KSx0LnZpcnRpb0ZzKXtyKHtraW5kOiJ2aXJ0aW8td2luZG93IixiYXNlOkNlPj4+MCxzaXplOiRlLGlycTpkdH0pO2xldCBlPW8ud2FzbTMyX3ZpcnRpb19pcnFfcGVuZGluZztlJiZ0eXBlb2YgZS52YWx1ZT09Im51bWJlciI/cih7a2luZDoidmlydGlvLWlycS1wZW5kaW5nLW9mZnNldCIsb2Zmc2V0OmUudmFsdWU+Pj4wfSk6cih7a2luZDoiZXJyb3IiLG1lc3NhZ2U6InZpcnRpb0ZzIHJlcXVlc3RlZCBidXQgdm1saW51eC53YXNtIGhhcyBubyB3YXNtMzJfdmlydGlvX2lycV9wZW5kaW5nIGV4cG9ydCJ9KX1pZih0LnZpcnRpb0lucHV0KXtyKHtraW5kOiJ2aXJ0aW8taW5wdXQtd2luZG93IixiYXNlOmplPj4+MCxzaXplOkFlLGlycTptdH0pO2xldCBlPW8ud2FzbTMyX3ZpcnRpb19pcnFfcGVuZGluZztlJiZ0eXBlb2YgZS52YWx1ZT09Im51bWJlciI/cih7a2luZDoidmlydGlvLWlycS1wZW5kaW5nLW9mZnNldCIsb2Zmc2V0OmUudmFsdWU+Pj4wfSk6cih7a2luZDoiZXJyb3IiLG1lc3NhZ2U6InZpcnRpb0lucHV0IHJlcXVlc3RlZCBidXQgdm1saW51eC53YXNtIGhhcyBubyB3YXNtMzJfdmlydGlvX2lycV9wZW5kaW5nIGV4cG9ydCJ9KX1pZih0LnZpcnRpb05ldCl7cih7a2luZDoidmlydGlvLW5ldC13aW5kb3ciLGJhc2U6RGU+Pj4wLHNpemU6SWUsaXJxOmZ0fSk7bGV0IGU9by53YXNtMzJfdmlydGlvX2lycV9wZW5kaW5nO2UmJnR5cGVvZiBlLnZhbHVlPT0ibnVtYmVyIj9yKHtraW5kOiJ2aXJ0aW8taXJxLXBlbmRpbmctb2Zmc2V0IixvZmZzZXQ6ZS52YWx1ZT4+PjB9KTpyKHtraW5kOiJlcnJvciIsbWVzc2FnZToidmlydGlvTmV0IHJlcXVlc3RlZCBidXQgdm1saW51eC53YXNtIGhhcyBubyB3YXNtMzJfdmlydGlvX2lycV9wZW5kaW5nIGV4cG9ydCJ9KX1pZih0LnVzYkhjZCl7cih7a2luZDoidXNiLXdpbmRvdyIsYmFzZTpxZT4+PjAsc2l6ZTpMZSxpcnE6U3R9KTtsZXQgZT1vLndhc20zMl92aXJ0aW9faXJxX3BlbmRpbmc7ZSYmdHlwZW9mIGUudmFsdWU9PSJudW1iZXIiP3Ioe2tpbmQ6InZpcnRpby1pcnEtcGVuZGluZy1vZmZzZXQiLG9mZnNldDplLnZhbHVlPj4+MH0pOnIoe2tpbmQ6ImVycm9yIixtZXNzYWdlOiJ1c2JIY2QgcmVxdWVzdGVkIGJ1dCB2bWxpbnV4Lndhc20gaGFzIG5vIHdhc20zMl92aXJ0aW9faXJxX3BlbmRpbmcgZXhwb3J0In0pfWlmKHQudmlydGlvQ29uc29sZSl7cih7a2luZDoidmlydGlvLWNvbnNvbGUtd2luZG93IixiYXNlOldlPj4+MCxzaXplOk1lLGlycTpodH0pO2xldCBlPW8ud2FzbTMyX3ZpcnRpb19pcnFfcGVuZGluZztlJiZ0eXBlb2YgZS52YWx1ZT09Im51bWJlciI/cih7a2luZDoidmlydGlvLWlycS1wZW5kaW5nLW9mZnNldCIsb2Zmc2V0OmUudmFsdWU+Pj4wfSk6cih7a2luZDoiZXJyb3IiLG1lc3NhZ2U6InZpcnRpb0NvbnNvbGUgcmVxdWVzdGVkIGJ1dCB2bWxpbnV4Lndhc20gaGFzIG5vIHdhc20zMl92aXJ0aW9faXJxX3BlbmRpbmcgZXhwb3J0In0pfWlmKHQuaG9zdFRyYW5zcG9ydCl7cih7a2luZDoiaG9zdHRyYW5zLXdpbmRvdyIsYmFzZTpGZT4+PjAsc2l6ZTpUZSxpcnE6d3R9KTtsZXQgZT1vLndhc20zMl92aXJ0aW9faXJxX3BlbmRpbmc7ZSYmdHlwZW9mIGUudmFsdWU9PSJudW1iZXIiP3Ioe2tpbmQ6InZpcnRpby1pcnEtcGVuZGluZy1vZmZzZXQiLG9mZnNldDplLnZhbHVlPj4+MH0pOnIoe2tpbmQ6ImVycm9yIixtZXNzYWdlOiJob3N0VHJhbnNwb3J0IHJlcXVlc3RlZCBidXQgdm1saW51eC53YXNtIGhhcyBubyB3YXNtMzJfdmlydGlvX2lycV9wZW5kaW5nIGV4cG9ydCJ9KX1pZih0LmZyYW1lYnVmZmVyKXtsZXQgZT1vLndhc20zMl9kaXNwbGF5X2N0cmwsbj1lJiZ0eXBlb2YgZS52YWx1ZT09Im51bWJlciI/ZS52YWx1ZT4+PjA6MDtyKHtraW5kOiJmYi13aW5kb3ciLGJhc2U6T2U+Pj4wLHdpZHRoOlYsaGVpZ2h0Okssc3RyaWRlOm1lLHNpemU6QmUsZm9ybWF0OmJ0LG1heFdpZHRoOnosbWF4SGVpZ2h0OlksY3RybE9mZnNldDpufSl9bGV0IFhlPW8ud2FzbTMyX3B0eV9icmlkZ2VfcmluZztYZSYmdHlwZW9mIFhlLnZhbHVlPT0ibnVtYmVyIiYmcih7a2luZDoicHR5LWJyaWRnZS1yaW5nLW9mZnNldCIsb2Zmc2V0OlhlLnZhbHVlPj4+MH0pO2xldCBldD1vLndhc20zMl9zZXJpYWxfYnJpZGdlX3Jpbmc7ZXQmJnR5cGVvZiBldC52YWx1ZT09Im51bWJlciImJnIoe2tpbmQ6InNlcmlhbC1icmlkZ2UtcmluZy1vZmZzZXQiLG9mZnNldDpldC52YWx1ZT4+PjB9KTtsZXQgJHQ9MixnZT00LEF0PXR5cGVvZiBBdG9taWNzLndhaXRBc3luYz09ImZ1bmN0aW9uIjtIJiYhQXQmJnIoe2tpbmQ6ImRtZXNnIixsZXZlbDo0LHRleHQ6YGh3anMtbWVyZ2VkOiB0aGlzIHJ1bnRpbWUgaGFzIG5vIEF0b21pY3Mud2FpdEFzeW5jIFx1MjAxNCBDUFUgMCdzIGlkbGUgd2FpdCBmYWxscyBiYWNrIHRvIGEgJHtnZX1tcyBtYWNyb3Rhc2sgcG9sbCBvZiBfX3NjaGVkX3dha2V1cF93b3JkLiBDb3JyZWN0ICh0aGUgd29yZCBpcyB0aGUgc2FtZSwgYW5kIGEgbWlzc2VkIG5vdGlmeSBzZWxmLWhlYWxzIHdpdGhpbiBvbmUgcG9sbCkgYnV0IGEgd2FrZSBjb3N0cyB1cCB0byAke2dlfW1zIG9mIGxhdGVuY3kgaXQgd291bGQgbm90IG90aGVyd2lzZSBjb3N0LgpgfSk7bGV0IFh0PXMoKCk9PntsZXQgZT1SZVsoST4+MikrMl0+Pj4wLG49UmVbKEk+PjIpKzNdPj4+MDtpZihlPT09NDI5NDk2NzI5NSYmbj09PTQyOTQ5NjcyOTUpcmV0dXJuIDEvMDtsZXQgaT1uKjQyOTQ5NjcyOTYrZTtyZXR1cm4gTWF0aC5tYXgoMSxNYXRoLmNlaWwoaS8xZTYpKX0sImNwdTBQYXJrRGVhZGxpbmVNcyIpO2FzeW5jIGZ1bmN0aW9uIGVyKCl7bGV0IGU9WHQoKTtpZih3ZTwwKXtyKHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBod2pzLW1lcmdlZDogQ1BVIDAgaWRsZS1wYXJrZWQgYnV0IF9fc2NoZWRfd2FrZXVwX3dvcmQgd2FzIG5ldmVyIHB1Ymxpc2hlZCwgc28gaXRzIHdha2UgaGFzIG5vIGFkZHJlc3MuIEZhbGxpbmcgYmFjayB0byBhICR7Z2V9bXMgdHVybjsgdGhpcyBtYWNoaW5lJ3MgaWRsZSBjb3N0cyBDUFUuCmB9KSxhd2FpdCBDKCk7cmV0dXJufWxldCBuPXdlPj4yO2lmKEF0KXtsZXQgYz1BdG9taWNzLndhaXRBc3luYyhHLG4sMCxlKTtjLmFzeW5jP2F3YWl0IGMudmFsdWU6YXdhaXQgQygpO3JldHVybn1sZXQgaT1EYXRlLm5vdygpKyhlPT09MS8wPzFlOTplKTtmb3IoOzspe2lmKGF3YWl0IEMoKSwoQXRvbWljcy5sb2FkKEcsbil8MCkhPT0wfHxEYXRlLm5vdygpPj1pfHxmLnJlcXVlc3RlZClyZXR1cm47YXdhaXQgbmV3IFByb21pc2UoYz0+c2V0VGltZW91dChjLGdlKSl9fWlmKHMoZXIsIndhaXRGb3JLZXJuZWxXYWtlIikscih7a2luZDoicHJlLXN0YXJ0In0pLEgpe2xldCBuPURhdGUubm93KCksaT12Py5nZXQ/LigpPz9udWxsO2Zvcig7aT09PW51bGwmJiFmLnJlcXVlc3RlZCYmKGF3YWl0IEMoKSxpPXY/LmdldD8uKCk/P251bGwsIShpIT09bnVsbHx8RGF0ZS5ub3coKS1uPj0xZTQpKTspYXdhaXQgbmV3IFByb21pc2UoYz0+c2V0VGltZW91dChjLDEpKTtpZihpPT09bnVsbCl7bGV0IGM9dj09PXZvaWQgMD8idGhpcyByZWFsbSB3YXMgYm91bmQgYnkgYSB0cmFuc3BvcnQgdGhhdCBjYW5ub3QgZGVsaXZlciBvbmUgKG5vIGluYm91bmQgcGF0aCBhZnRlciAnYm9vdCcpIjpgdGhlIGhvc3QgbmV2ZXIgcG9zdGVkIG9uZSBpbiAke0RhdGUubm93KCktbn0gbXNgO3Ioe2tpbmQ6ImVycm9yIixtZXNzYWdlOmBod2pzLW1lcmdlZDogUkVGVVNJTkcgdG8gc3RhcnQgdGhlIGtlcm5lbCBcdTIwMTQgbm8gJ2RldmljZXMtcmVhZHknIGZyb20gdGhlIGhvc3Q6ICR7Y30uIE1lcmdlZCwgQ1BVIDAgYW5kIHRoZSBkZXZpY2UgYmFja2VuZHMgc2hhcmUgb25lIEpTIHRocmVhZCwgYW5kIGEgZ3Vlc3QgdGhhdCByZWFjaGVzIGFuIGluLWtlcm5lbCBidXN5LXdhaXQgb24gYSBkZXZpY2Ugd2hvc2UgYmFja2VuZCBkb2VzIG5vdCB5ZXQgZXhpc3QgaG9sZHMgdGhhdCB0aHJlYWQgZm9yZXZlciAodGhlIHZpcnRjb25zX3Byb2JlIGRlYWRsb2NrKS4gU3RhcnRpbmcgYW55d2F5IHdvdWxkIHRyYWRlIGEgbmFtZWQgcmVmdXNhbCBmb3IgYSBtYWNoaW5lIHRoYXQgYm9vdHMgdG8gc2lsZW5jZS5gfSk7cmV0dXJufXIoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtbWVyZ2VkOiBob3N0IGFuc3dlcmVkIGRldmljZXMtcmVhZHkgYWZ0ZXIgJHtEYXRlLm5vdygpLW59IG1zICgke2kuYnVpbHQ/PyJ1bm5hbWVkIn0pIFx1MjAxNCBldmVyeSBtZXNzYWdlIHRoaXMgcmVhbG0gcG9zdGVkIGJlZm9yZSBwcmUtc3RhcnQgaGFzIGJlZW4gZGVsaXZlcmVkIGFuZCBhY3RlZCBvbiwgd2hpY2ggaXMgd2hhdCBvbmUgbWFjcm90YXNrIHR1cm4gZG9lcyBOT1QgcHJvdmUgaW4gYSBydW50aW1lIHdob3NlIHBvcnQgZGVsaXZlcnMgb25lIG1lc3NhZ2UgcGVyIHRhc2suIFN0YXJ0aW5nIHRoZSBrZXJuZWwuCmB9KX10cnl7by53YXNtX3N0YXJ0X2tlcm5lbChGKTtsZXQgZT1CJiZ5JiZ0eXBlb2Ygby5od2pzX3Jlc3VtZT09ImZ1bmN0aW9uIiYmdHlwZW9mIG8uaHdqc19kb25lPT0iZnVuY3Rpb24iJiZ0eXBlb2Ygby5od2pzX2Rlc3Ryb3k9PSJmdW5jdGlvbiImJnR5cGVvZiBvLl9faHdqc190YWtlX3BhcmtlZD09ImZ1bmN0aW9uIixuPWllKCJfX2h3anNfcGFya2VkX293bmVyIik7aWYoZSYmeVtCPj4yXSE9PTApe2xldCBpPW4/eVtuPj4yXTowLGM9by5fX2h3anNfdGFrZV9wYXJrZWQoMCwwKT4+PjA7cih7a2luZDoiaHdqcy1ob3N0LWRyaXZlIixoYW5kbGU6Yyxvd25lcjppfSk7bGV0IGg9MCxFPTAsaj0wLFg9MCxJdD0wLHR0PURhdGUubm93KCk7Zm9yKDshby5od2pzX2RvbmUoYyk7KXtpZihrKCksSCl7bGV0IFR0PUF0b21pY3MubG9hZChHLEk+PjIpfDA7aWYoVHQ9PT1ZdD8oWCsrLEF0b21pY3Muc3RvcmUoRyxJPj4yLHB0KSk6VHQ9PT16dD8oaisrLGF3YWl0IGVyKCksVSgpLEF0b21pY3Muc3RvcmUoRyxJPj4yLHB0KSx0dD1EYXRlLm5vdygpKTpEYXRlLm5vdygpLXR0Pj0kdCYmKEl0KyssYXdhaXQgQygpLFUoKSx0dD1EYXRlLm5vdygpKSxmLnJlcXVlc3RlZCl7cih7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1tZXJnZWQ6IGNvb3BlcmF0aXZlIHN0b3AgaG9ub3VyZWQgYWZ0ZXIgJHtofSBzbGljZShzKTsgdGhlIGtlcm5lbCBjaGFpbiBpcyBsZWZ0IFBBUktFRCAobm90IGRlc3Ryb3llZCkgXHUyMDE0IG5vdGhpbmcgZWxzZSBtYXkgcmVzdW1lIGl0LCBhbmQgdGhlIGZyYW1lIGdvZXMgd2l0aCB0aGUgcmVhbG0uCmB9KTticmVha319dHlwZW9mIG8uX19od2pzX2J1ZGdldF9nZXQ9PSJmdW5jdGlvbiImJihvLl9faHdqc19idWRnZXRfZ2V0KCl8MCk9PT0wJiYoRSsrLG8uX19od2pzX2J1ZGdldF9zZXQoY3R8MCksYXdhaXQgQygpLFUoKSksby5od2pzX3Jlc3VtZShjKSxoKyssby5fX2h3anNfdGFrZV9wYXJrZWQoaSxjKX1sZXQgTXQ9Zi5yZXF1ZXN0ZWQmJiFvLmh3anNfZG9uZShjKTtNdHx8by5od2pzX2Rlc3Ryb3koYykscih7a2luZDoicmV0dXJuZWQiLG1lc3NhZ2U6YGh3anMgaG9zdCBkcml2ZSBsb29wOiB0b3AgZnJhbWUgMHgke2MudG9TdHJpbmcoMTYpfSAob3duZXIgMHgke2kudG9TdHJpbmcoMTYpfSkgYCsoTXQ/YFNUT1BQRUQgY29vcGVyYXRpdmVseSBhZnRlciAke2h9IHNsaWNlKHMpIFx1MjAxNCBzdGlsbCBwYXJrZWQsIE5PVCBkZXN0cm95ZWRgOmBkcml2ZW4gdG8gZG9uZSBpbiAke2h9IHNsaWNlKHMpYCkrYCAoJHtFfSBidWRnZXQtZXhwaXJ5IGJyZWF0aChlcykgcmVmaWxsZWQreWllbGRlZGArKEg/YDsgbWVyZ2VkIENQVSAwOiAke2p9IGlkbGUgcGFyayhzKSB3YWl0ZWQgb24gX19zY2hlZF93YWtldXBfd29yZCwgJHtYfSByZXN1bWUtbm93IHBhcmsocyksICR7SXR9IHF1YW50dW0geWllbGQocykgYXQgJHskdH1tc2A6IiIpK2ApOyB3YXNtX3N0YXJ0X2tlcm5lbCBuZXZlciByZS1lbnRlcnMgXHUyMDE0IGJvb3QgZW5kcyBoZXJlIGJ5IGNvbnN0cnVjdGlvbi4ke0VlKCl9YH0pfWVsc2Ugcih7a2luZDoicmV0dXJuZWQiLG1lc3NhZ2U6YHdhc21fc3RhcnRfa2VybmVsIHJldHVybmVkIChzaG91bGQgbm90IGhhcHBlbikke0VlKCl9YH0pfWNhdGNoKGUpe2xldCBuPWUgaW5zdGFuY2VvZiBFcnJvcj9gJHtlLm1lc3NhZ2V9CiR7ZS5zdGFjaz8/IiJ9YDpTdHJpbmcoZSk7cih7a2luZDoia2VybmVsLXRyYXAiLG1lc3NhZ2U6bitFZSgpfSl9fXMoY3IsImJvb3QiKTtqdCh7cG9zdDpzKHQ9PkR0LnBvc3RNZXNzYWdlKHQpLCJwb3N0Iiksb25NZXNzYWdlOnModD0+RHQub24oIm1lc3NhZ2UiLHQpLCJvbk1lc3NhZ2UiKX0pOwo="),Wf=new URL("data:text/javascript;base64,dmFyIE9jPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgcj0oZSx0KT0+T2MoZSwibmFtZSIse3ZhbHVlOnQsY29uZmlndXJhYmxlOiEwfSk7aW1wb3J0e3BhcmVudFBvcnQgYXMgT2R9ZnJvbSJub2RlOndvcmtlcl90aHJlYWRzIjtmdW5jdGlvbiBCKGUsdCl7bGV0IG89MCxzPTAsbD0wO2Rve2lmKHQ+PWUubGVuZ3RoKXRocm93IG5ldyBFcnJvcigiaHdqcy1kbG9wZW46IHRydW5jYXRlZCBMRUIgaW4gZHlsaW5rLjAiKTtsPWVbdCsrXSxvfD0obCYxMjcpPDxzLHMrPTd9d2hpbGUobCYxMjgpO3JldHVybltvPj4+MCx0XX1yKEIsInJlYWRVMzJMRUIiKTt2YXIgV2M9MSxDYz0yLFBjPTMsQmM9NCxGYz0zLEhjPTEsVWM9MTAyNCxNcjtmdW5jdGlvbiBHYyhlKXtpZighKGUmJmUuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXIpKXJldHVybiBlO2lmKE1yPT09dm9pZCAwKXRyeXtsZXQgdD1uZXcgVWludDhBcnJheShuZXcgU2hhcmVkQXJyYXlCdWZmZXIoOCkpO3Quc2V0KFswLDk3LDExNSwxMDksMSwwLDAsMF0pLG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUodCksTXI9ITB9Y2F0Y2h7TXI9ITF9cmV0dXJuIE1yP2U6ZS5zbGljZSgpfXIoR2MsIndhc21Tb3VyY2UiKTt2YXIgS2M9bmV3IFRleHREZWNvZGVyO2Z1bmN0aW9uIEx0KGUpe2xldCB0PXR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlcjwidSImJmUuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXI7cmV0dXJuIEtjLmRlY29kZSh0P2Uuc2xpY2UoKTplKX1yKEx0LCJkZWNvZGVNYXliZVNoYXJlZCIpO2Z1bmN0aW9uIExzKGUpe2xldCB0PWU7aWYodC5sZW5ndGg8OHx8dFswXSE9PTB8fHRbMV0hPT05N3x8dFsyXSE9PTExNXx8dFszXSE9PTEwOSl0aHJvdyBuZXcgRXJyb3IoImh3anMtZGxvcGVuOiBub3QgYSB3YXNtIG1vZHVsZSAoYmFkIG1hZ2ljKSIpO2xldCBvPTg7Zm9yKDtvPHQubGVuZ3RoOyl7bGV0IHM9dFtvKytdLGw7W2wsb109Qih0LG8pO2xldCBkPW8rbDtpZihzPT09MCl7bGV0IF8sbT1vO1tfLG1dPUIodCxtKTtsZXQgYz1MdCh0LnN1YmFycmF5KG0sbStfKSk7aWYobSs9XyxjPT09ImR5bGluay4wIil7bGV0IGg9e21lbW9yeVNpemU6MCxtZW1vcnlBbGlnbjoxLHRhYmxlU2l6ZTowLHRhYmxlQWxpZ246MSxuZWVkZWQ6W10sdGxzRXhwb3J0czpbXSx3ZWFrSW1wb3J0czpuZXcgTWFwfSxnPW07Zm9yKDtnPGQ7KXtsZXQgeD10W2crK10sUztbUyxnXT1CKHQsZyk7bGV0IFI9ZytTO2lmKHg9PT1XYyl7bGV0IHcseSxELGRlO1t3LGddPUIodCxnKSxbeSxnXT1CKHQsZyksW0QsZ109Qih0LGcpLFtkZSxnXT1CKHQsZyksaC5tZW1vcnlTaXplPXcsaC5tZW1vcnlBbGlnbj0xPDx5LGgudGFibGVTaXplPUQsaC50YWJsZUFsaWduPTE8PGRlfWVsc2UgaWYoeD09PUNjKXtsZXQgdztbdyxnXT1CKHQsZyk7Zm9yKGxldCB5PTA7eTx3O3krKyl7bGV0IEQ7W0QsZ109Qih0LGcpLGgubmVlZGVkLnB1c2goTHQodC5zdWJhcnJheShnLGcrRCkpKSxnKz1EfX1lbHNlIGlmKHg9PT1QYyl7bGV0IHc7W3csZ109Qih0LGcpO2ZvcihsZXQgeT0wO3k8dzt5Kyspe2xldCBELGRlO1tELGddPUIodCxnKTtsZXQgej1MdCh0LnN1YmFycmF5KGcsZytEKSk7Zys9RCxbZGUsZ109Qih0LGcpLGRlJlVjJiZoLnRsc0V4cG9ydHMucHVzaCh6KX19ZWxzZSBpZih4PT09QmMpe2xldCB3O1t3LGddPUIodCxnKTtmb3IobGV0IHk9MDt5PHc7eSsrKXtsZXQgRCxkZTtbRCxnXT1CKHQsZyk7bGV0IHo9THQodC5zdWJhcnJheShnLGcrRCkpO2crPUQsW0QsZ109Qih0LGcpO2xldCBRPUx0KHQuc3ViYXJyYXkoZyxnK0QpKTtnKz1ELFtkZSxnXT1CKHQsZyksKGRlJkZjKT09PUhjJiZoLndlYWtJbXBvcnRzLnNldChRLHopfX1nPVJ9cmV0dXJuIGh9fW89ZH1yZXR1cm4gbnVsbH1yKExzLCJwYXJzZUR5bGluazAiKTtmdW5jdGlvbiBibChlKXtsZXQgdD1lO2lmKHQubGVuZ3RoPDh8fHRbMF0hPT0wfHx0WzFdIT09OTd8fHRbMl0hPT0xMTV8fHRbM10hPT0xMDkpdGhyb3cgbmV3IEVycm9yKCJod2pzLWRsb3Blbjogbm90IGEgd2FzbSBtb2R1bGUgKGJhZCBtYWdpYykiKTtsZXQgbz04O2Zvcig7bzx0Lmxlbmd0aDspe2xldCBzPXRbbysrXSxsO1tsLG9dPUIodCxvKTtsZXQgZD1vK2w7aWYocz09PTIpe2xldCBfO1tfLG9dPUIodCxvKTtmb3IobGV0IG09MDttPF87bSsrKXtsZXQgYztbYyxvXT1CKHQsbyksbys9YyxbYyxvXT1CKHQsbyksbys9YztsZXQgaD10W28rK107aWYoaD09PTApWyxvXT1CKHQsbyk7ZWxzZSBpZihoPT09MSl7bys9MTtsZXQgZz10W28rK10seCxTO3JldHVyblt4LG9dPUIodCxvKSxnJjEmJihbUyxvXT1CKHQsbykpLHttaW46eCxtYXg6U319ZWxzZSBpZihoPT09Mil7bGV0IGc9dFtvKytdO1ssb109Qih0LG8pLGcmMSYmKFssb109Qih0LG8pKX1lbHNlIGg9PT0zJiYobys9Mil9fW89ZH1yZXR1cm4gbnVsbH1yKGJsLCJwYXJzZUltcG9ydGVkVGFibGVUeXBlIik7ZnVuY3Rpb24ga2woZSl7bGV0IHQ9ZTtpZih0Lmxlbmd0aDw4fHx0WzBdIT09MHx8dFsxXSE9PTk3fHx0WzJdIT09MTE1fHx0WzNdIT09MTA5KXRocm93IG5ldyBFcnJvcigiaHdqcy1leGVjOiBub3QgYSB3YXNtIG1vZHVsZSAoYmFkIG1hZ2ljOyBjYW5ub3QgcmVhZCBtZW1vcnktaW1wb3J0IG1pbikiKTtsZXQgbz1udWxsLHM9ODtmb3IoO3M8dC5sZW5ndGg7KXtsZXQgbD10W3MrK10sZDtbZCxzXT1CKHQscyk7bGV0IF89cytkO2lmKGw9PT0yKXtsZXQgbTtbbSxzXT1CKHQscyk7Zm9yKGxldCBjPTA7YzxtO2MrKyl7bGV0IGg7W2gsc109Qih0LHMpO2xldCBnPUx0KHQuc3ViYXJyYXkocyxzK2gpKTtzKz1oLFtoLHNdPUIodCxzKTtsZXQgeD1MdCh0LnN1YmFycmF5KHMscytoKSk7cys9aDtsZXQgUz10W3MrK107aWYoUz09PTApWyxzXT1CKHQscyk7ZWxzZSBpZihTPT09MSl7cys9MTtsZXQgUj10W3MrK107WyxzXT1CKHQscyksUiYxJiYoWyxzXT1CKHQscykpfWVsc2UgaWYoUz09PTIpe2xldCBSPXRbcysrXSx3O2lmKFt3LHNdPUIodCxzKSxSJjEmJihbLHNdPUIodCxzKSksZz09PSJlbnYiJiZ4PT09InVzZXJfbWVtb3J5IilyZXR1cm4gdztvPT09bnVsbCYmKG89dyl9ZWxzZSBTPT09MyYmKHMrPTIpfXJldHVybiBvfXM9X31yZXR1cm4gb31yKGtsLCJwYXJzZUltcG9ydGVkTWVtb3J5TWluUGFnZXMiKTtmdW5jdGlvbiBKYyhlKXtsZXQgdD1lLG89W10scz1bXSxsPTg7Zm9yKDtsPHQubGVuZ3RoOyl7bGV0IG09dFtsKytdLGM7W2MsbF09Qih0LGwpO2xldCBoPWwrYztpZihtPT09Mil7bGV0IGc7W2csbF09Qih0LGwpO2ZvcihsZXQgeD0wO3g8Zzt4Kyspe2xldCBTLFIsdztbUyxsXT1CKHQsbCksUj1MdCh0LnN1YmFycmF5KGwsbCtTKSksbCs9UyxbUyxsXT1CKHQsbCksdz1MdCh0LnN1YmFycmF5KGwsbCtTKSksbCs9UztsZXQgeT10W2wrK107aWYoeT09PTApWyxsXT1CKHQsbCksby5wdXNoKHttb2R1bGU6UixmaWVsZDp3fSk7ZWxzZSBpZih5PT09MSl7bCs9MTtsZXQgRD10W2wrK107WyxsXT1CKHQsbCksRCYxJiYoWyxsXT1CKHQsbCkpfWVsc2UgaWYoeT09PTIpe2xldCBEPXRbbCsrXTtbLGxdPUIodCxsKSxEJjEmJihbLGxdPUIodCxsKSl9ZWxzZSB5PT09MyYmKGwrPTIpfX1lbHNlIGlmKG09PT0wKXtsZXQgZyx4PWw7W2cseF09Qih0LHgpO2xldCBTPUx0KHQuc3ViYXJyYXkoeCx4K2cpKTtpZih4Kz1nLFM9PT0ibmFtZSIpe2xldCBSPXg7Zm9yKDtSPGg7KXtsZXQgdz10W1IrK10seTtbeSxSXT1CKHQsUik7bGV0IEQ9Uit5O3c9PT0xJiZzLnB1c2goUiksUj1EfX19bD1ofWxldCBkPW5ldyBNYXA7Zm9yKGxldCBtIG9mIHMpe2xldCBjO1tjLG1dPUIodCxtKTtmb3IobGV0IGg9MDtoPGM7aCsrKXtsZXQgZyx4O1tnLG1dPUIodCxtKSxbeCxtXT1CKHQsbSksZzxvLmxlbmd0aCYmZC5zZXQoZyxMdCh0LnN1YmFycmF5KG0sbSt4KSkpLG0rPXh9fWxldCBfPW5ldyBNYXA7Zm9yKGxldCBtPTA7bTxvLmxlbmd0aDttKyspe2xldCBjPWQuZ2V0KG0pO2MmJl8uc2V0KGMsb1ttXSl9cmV0dXJuIF99cihKYywicGFyc2VJbXBvcnRlZEZ1bmN0aW9uTmFtZXMiKTt2YXIgaGw9bmV3IFdlYWtNYXA7ZnVuY3Rpb24gVm8oZSx0KXtsZXQgbz1obC5nZXQoZSk7cmV0dXJuIG89PT12b2lkIDAmJihvPUpjKHQpLGhsLnNldChlLG8pKSxvfXIoVm8sImltcG9ydGVkRnVuY3Rpb25OYW1lc09mIik7ZnVuY3Rpb24geGwoZSl7bGV0IHQ9ZSxvPW5ldyBNYXAscz04O2Zvcig7czx0Lmxlbmd0aDspe2xldCBsPXRbcysrXSxkO1tkLHNdPUIodCxzKTtsZXQgXz1zK2Q7aWYobD09PTcpe2xldCBtO1ttLHNdPUIodCxzKTtmb3IobGV0IGM9MDtjPG07YysrKXtsZXQgaCxnO1toLHNdPUIodCxzKTtsZXQgeD1MdCh0LnN1YmFycmF5KHMscytoKSk7cys9aDtsZXQgUz10W3MrK107W2csc109Qih0LHMpLFM9PT0wJiZvLnNldCh4LGcpfWJyZWFrfXM9X31yZXR1cm4gb31yKHhsLCJwYXJzZUV4cG9ydGVkRnVuY3Rpb25JbmRpY2VzIik7ZnVuY3Rpb24gWG8oZSx0KXtpZighKGUuc3RhcnRzV2l0aCgiX19od2pzXyIpfHxlLnN0YXJ0c1dpdGgoIl9fd2FzbV8iKSkpZm9yKGxldCBvIG9mIHQpe2xldCBzPW8mJm8uaGFuZGxlJiZvLmhhbmRsZS5leHBvcnRzP28uaGFuZGxlLmV4cG9ydHNbZV06dm9pZCAwO2lmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXJldHVybiBzfX1yKFhvLCJkbG9wZW5TaWJsaW5nRXhwb3J0Iik7dmFyIEVsPW5ldyBTZXQoWyJfX3N0YWNrX3BvaW50ZXIiLCJfX3Rsc19iYXNlIiwiX190bHNfc2l6ZSIsIl9fdGxzX2FsaWduIiwiX19tZW1vcnlfYmFzZSIsIl9fdGFibGVfYmFzZSIsIl9faGVhcF9iYXNlIiwiX19oZWFwX2VuZCIsIl9fZGF0YV9lbmQiLCJfX2Rzb19oYW5kbGUiLCJfX2dsb2JhbF9iYXNlIl0pLHpjPS9eX1ooVFtJVlNUQ118R1tWUl18WnxUW2h2XShuP1swLTldK18pKyk/Tj9LP1N0LztmdW5jdGlvbiBZYyhlKXtyZXR1cm4gZS5zdGFydHNXaXRoKCJfXyIpPyExOiF6Yy50ZXN0KGUpfXIoWWMsIm5lZWRlZFByZWVtcHRpYmxlIik7ZnVuY3Rpb24gU2woZSx0LG8scyl7aWYodD09PXZvaWQgMHx8dD09PW98fCFZYyhlKSlyZXR1cm47bGV0IGw9cy5nZXQodCksZD1zLmdldChvKTtyZXR1cm4gbCE9PXZvaWQgMCYmZCE9PXZvaWQgMCYmbDxkP3Q6dm9pZCAwfXIoU2wsIm5lZWRlZEVhcmxpZXJQcm92aWRlciIpO2Z1bmN0aW9uICRsKGUsdCl7bGV0IG89cihkPT5kJiZ0eXBlb2YgZFtlXT09ImZ1bmN0aW9uIj9kW2VdOnZvaWQgMCwiZm5PZiIpO2lmKHQucHJvdmlkZXIhPT12b2lkIDApe2xldCBkPXQuc2libGluZ3MuZmluZChtPT5tLmluZGV4PT09dC5wcm92aWRlciksXz1kP28oZC5leHBvcnRzKTp2b2lkIDA7cmV0dXJuIF8/e2Y6XyxzaWJsaW5nOmR9Om51bGx9bGV0IHM9byh0LmV4cCk7aWYocylyZXR1cm57ZjpzLHNpYmxpbmc6bnVsbH07bGV0IGw9byh0Lm93bkV4cCk7aWYobClyZXR1cm57ZjpsLHNpYmxpbmc6bnVsbH07Zm9yKGxldCBkIG9mIHQuc2libGluZ3Mpe2lmKGQuZXhwb3J0cz09PXQub3duRXhwKWNvbnRpbnVlO2xldCBfPW8oZC5leHBvcnRzKTtpZihfKXJldHVybntmOl8sc2libGluZzpkfX1yZXR1cm4gbnVsbH1yKCRsLCJuZWVkZWRHb3RQYXRjaFByb3ZpZGVyIik7ZnVuY3Rpb24gcW8oZSx0KXtpZighKGUuc3RhcnRzV2l0aCgiX19od2pzXyIpfHxlLnN0YXJ0c1dpdGgoIl9fd2FzbV8iKXx8RWwuaGFzKGUpKSlmb3IobGV0IG8gb2YgdCl7bGV0IHM9byYmby5oYW5kbGU7aWYoIXN8fCFzLmV4cG9ydHN8fHR5cGVvZiBzLmRsc3ltIT0iZnVuY3Rpb24ifHwhKHMuZXhwb3J0c1tlXWluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsKSljb250aW51ZTtsZXQgbD1zLmRsc3ltKGUpPj4+MDtpZihsIT09MClyZXR1cm4gbH19cihxbywiZGxvcGVuU2libGluZ0RhdGFBZGRyZXNzIik7ZnVuY3Rpb24gdmwoZSl7bGV0IHQ9ZSxvPW5ldyBNYXA7aWYoIXR8fHQubGVuZ3RoPDh8fHRbMF0hPT0wfHx0WzFdIT09OTd8fHRbMl0hPT0xMTV8fHRbM10hPT0xMDkpdGhyb3cgbmV3IEVycm9yKCJod2pzLWxpYmM6IG1haW5EYXRhRXhwb3J0QWRkcmVzc2VzOiBub3QgYSB3YXNtIG1vZHVsZSAoYmFkIG1hZ2ljKSIpO2xldCBzPTgsbD0wLGQ9bmV3IE1hcCxfPS0xLG09LTE7Zm9yKDtzPHQubGVuZ3RoOyl7bGV0IGc9dFtzKytdLHg7W3gsc109Qih0LHMpO2xldCBTPXMreDtpZihnPT09Mil7bGV0IFI7W1Isc109Qih0LHMpO2ZvcihsZXQgdz0wO3c8Ujt3Kyspe2xldCB5O1t5LHNdPUIodCxzKSxzKz15LFt5LHNdPUIodCxzKSxzKz15O2xldCBEPXRbcysrXTtEPT09MD9bLHNdPUIodCxzKTpEPT09MT8ocys9MSxzPU9yKHQscykpOkQ9PT0yP3M9T3IodCxzKTpEPT09Mz8ocys9MixsKyspOkQ9PT00JiYocys9MSxbLHNdPUIodCxzKSl9fWVsc2UgaWYoZz09PTcpe2xldCBSO1tSLHNdPUIodCxzKTtmb3IobGV0IHc9MDt3PFI7dysrKXtsZXQgeTtbeSxzXT1CKHQscyk7bGV0IEQ9THQodC5zdWJhcnJheShzLHMreSkpO3MrPXk7bGV0IGRlPXRbcysrXSx6O2lmKFt6LHNdPUIodCxzKSxkZT09PTMpe2xldCBRPWQuZ2V0KHopO1E/US5wdXNoKEQpOmQuc2V0KHosW0RdKX19fWVsc2UgZz09PTYmJihfPXMsbT1TKTtzPVN9aWYoXzwwfHxkLnNpemU9PT0wKXJldHVybiBvO2xldCBjPV8saDtbaCxjXT1CKHQsYyk7Zm9yKGxldCBnPTA7ZzxoJiZjPG07ZysrKXtsZXQgeD10W2NdLFM9dFtjKzFdIT09MDtjKz0yO2xldCBSO2Zvcih0W2NdPT09NjUmJng9PT0xMjcmJihbUixjXT1Ocyh0LGMrMSxtKSx0W2NdIT09MTEmJihSPXZvaWQgMCkpO2M8bSYmdFtjXSE9PTExOyl7bGV0IHk9dFtjKytdO3k9PT02NXx8eT09PTY2P1ssY109TnModCxjLG0pOnk9PT02Nz9jKz00Onk9PT02OD9jKz04Onk9PT0zNSYmKFssY109Qih0LGMpKX1jKys7bGV0IHc9ZC5nZXQobCtnKTtpZighKCF3fHxTfHxSPT09dm9pZCAwfHwhKFI+Pj4wKSkpZm9yKGxldCB5IG9mIHcpby5zZXQoeSxSPj4+MCl9cmV0dXJuIG99cih2bCwibWFpbkRhdGFFeHBvcnRBZGRyZXNzZXMiKTtmdW5jdGlvbiBBbChlLHQpe2lmKGUuc3RhcnRzV2l0aCgiX19od2pzXyIpfHxlLnN0YXJ0c1dpdGgoImh3anNfIil8fGUuc3RhcnRzV2l0aCgiX193YXNtIil8fEVsLmhhcyhlKSlyZXR1cm47bGV0IG89dD90LmdldChlKTp2b2lkIDA7cmV0dXJuIHR5cGVvZiBvPT0ibnVtYmVyIiYmbz4wP286dm9pZCAwfXIoQWwsImludGVycG9zaW5nRGF0YUFkZHJlc3MiKTtmdW5jdGlvbiBJbChlKXtsZXQgdD1lO2lmKHQubGVuZ3RoPDh8fHRbMF0hPT0wfHx0WzFdIT09OTd8fHRbMl0hPT0xMTV8fHRbM10hPT0xMDkpdGhyb3cgbmV3IEVycm9yKCJod2pzLWRsb3Blbjogc3RyaXBTdGFydFNlY3Rpb246IG5vdCBhIHdhc20gbW9kdWxlIChiYWQgbWFnaWMpIik7bGV0IG89ODtmb3IoO288dC5sZW5ndGg7KXtsZXQgcz1vLGw9dFtvKytdLGQ7W2Qsb109Qih0LG8pO2xldCBfPW8rZDtpZihsPT09OCl7bGV0IG09bmV3IFVpbnQ4QXJyYXkodC5sZW5ndGgtKF8tcykpO3JldHVybiBtLnNldCh0LnN1YmFycmF5KDAscyksMCksbS5zZXQodC5zdWJhcnJheShfKSxzKSxtfW89X31yZXR1cm4gdH1yKElsLCJzdHJpcFN0YXJ0U2VjdGlvbiIpO2Z1bmN0aW9uIE5zKGUsdCxvKXtsZXQgcz0wLGw9MCxkPTA7ZG97aWYodD49byl0aHJvdyBuZXcgRXJyb3IoImh3anMtZGxvcGVuOiB0cnVuY2F0ZWQgc2lnbmVkIExFQiBpbiBnbG9iYWwgaW5pdCBleHByIik7ZD1lW3QrK10sc3w9KGQmMTI3KTw8bCxsKz03fXdoaWxlKGQmMTI4KTtyZXR1cm4gbDwzMiYmZCY2NCYmKHN8PS0xPDxsKSxbc3wwLHRdfXIoTnMsInJlYWRTMzJMRUIiKTt2YXIgVmM9MSoxMDI0KjEwMjQsTXM9OCoxMDI0KjEwMjQsWGM9NDA5NjtmdW5jdGlvbiBPcihlLHQpe2xldCBvPWVbdCsrXTtyZXR1cm5bLHRdPUIoZSx0KSxvJjEmJihbLHRdPUIoZSx0KSksdH1yKE9yLCJza2lwTGltaXRzIik7ZnVuY3Rpb24gQ3IoZSx0KXtsZXQgbz04LHM9MCxsPS0xLGQ9LTEsXz0tMTtmb3IoO288ZS5sZW5ndGg7KXtsZXQgZz1lW28rK10seDtbeCxvXT1CKGUsbyk7bGV0IFM9byxSPW8reDtpZihnPT09Mil7bGV0IHc7W3csb109QihlLG8pO2ZvcihsZXQgeT0wO3k8dzt5Kyspe2xldCBEO1tELG9dPUIoZSxvKSxvKz1ELFtELG9dPUIoZSxvKSxvKz1EO2xldCBkZT1lW28rK107ZGU9PT0wP1ssb109QihlLG8pOmRlPT09MT8obys9MSxvPU9yKGUsbykpOmRlPT09Mj9vPU9yKGUsbyk6ZGU9PT0zJiYobys9MixzKyspfX1lbHNlIGlmKGc9PT03KXtsZXQgdztbdyxvXT1CKGUsbyk7Zm9yKGxldCB5PTA7eTx3O3krKyl7bGV0IEQ7W0Qsb109QihlLG8pO2xldCBkZT1MdChlLnN1YmFycmF5KG8sbytEKSk7bys9RDtsZXQgej1lW28rK10sUTtbUSxvXT1CKGUsbyksej09PTMmJmRlPT09dCYmKGw9USl9fWVsc2UgZz09PTYmJihkPVMsXz1SKTtvPVJ9aWYobDwwKXJldHVybntvazohMSx3aHk6Im5vLWV4cG9ydCJ9O2lmKGQ8MClyZXR1cm57b2s6ITEsd2h5OiJuby1nbG9iYWwtc2VjdGlvbiJ9O2xldCBtPWwtcyxjPWQsaDtpZihbaCxjXT1CKGUsYyksbTwwfHxtPj1oKXJldHVybntvazohMSx3aHk6Im91dC1vZi1yYW5nZSIsZXhwb3J0R2xvYmFsSW5kZXg6bCxkZWZpbmVkSW5kZXg6bSxnY291bnQ6aH07Zm9yKGxldCBnPTA7ZzxoO2crKyl7bGV0IHg9ZVtjKzFdIT09MDtpZihjKz0yLGc9PT1tKXtsZXQgUz1lW2MrK107aWYoUyE9PTY1KXJldHVybntvazohMSx3aHk6Im5vdC1pMzItY29uc3QiLG9wOlN9O2xldCBSO3JldHVybltSLGNdPU5zKGUsYyxfKSx7b2s6ITAsdmFsdWU6Uj4+PjAsbXV0YWJsZTp4fX1mb3IoO2M8XyYmZVtjXSE9PTExOyl7bGV0IFM9ZVtjKytdO1M9PT02NXx8Uz09PTY2P1ssY109TnMoZSxjLF8pOlM9PT02Nz9jKz00OlM9PT02OD9jKz04OlM9PT0zNSYmKFssY109QihlLGMpKX1jKyt9cmV0dXJue29rOiExLHdoeToidW5yZWFjaGVkIn19cihDciwiZmluZEV4cG9ydGVkSTMyR2xvYmFsIik7ZnVuY3Rpb24gUmwoZSx0LG8pe2xldCBzPWU7aWYocy5sZW5ndGg8OHx8c1swXSE9PTB8fHNbMV0hPT05N3x8c1syXSE9PTExNXx8c1szXSE9PTEwOSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiByZWFkRXhwb3J0ZWRJMzJHbG9iYWwoJHt0fSkgZm9yICR7b306IG5vdCBhIHdhc20gbW9kdWxlIChiYWQgbWFnaWMpYCk7bGV0IGw9Q3Iocyx0KTtpZihsLm9rKXJldHVybiBsLnZhbHVlO3Rocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46ICR7b30gZG9lcyBub3QgcHVibGlzaCBhIHJlYWRhYmxlIGkzMiBkYXRhIG9mZnNldCBmb3IgIiR7dH0iICgke2wud2h5fSkgLS0gYSBzaWJsaW5nIEdPVC5tZW0gYmluZGluZyBuZWVkcyB0aGUgUFJPVklERVIncyBsaW5rLXRpbWUgb2Zmc2V0LCBhbmQgYSBkZWZpbmVkIC1zaGFyZWQgZGF0YSBleHBvcnQgaXMgYW4gaW1tdXRhYmxlIGkzMiBnbG9iYWwgd2l0aCBhbiBpMzIuY29uc3QgaW5pdCBieSBjb25zdHJ1Y3Rpb24gKG5ldmVyLXNpbGVudCkuYCl9cihSbCwicmVhZEV4cG9ydGVkSTMyR2xvYmFsIik7ZnVuY3Rpb24gcWMoZSl7bGV0IHQ9ZTtpZih0Lmxlbmd0aDw4fHx0WzBdIT09MHx8dFsxXSE9PTk3fHx0WzJdIT09MTE1fHx0WzNdIT09MTA5KXRocm93IG5ldyBFcnJvcigiaHdqcy1ydDogcmVhZEhlYXBCYXNlOiBub3QgYSB3YXNtIG1vZHVsZSAoYmFkIG1hZ2ljKSIpO2xldCBvPUNyKHQsIl9faGVhcF9iYXNlIik7aWYoby5vaylyZXR1cm4gby52YWx1ZTt0aHJvdyBvLndoeT09PSJuby1leHBvcnQiP25ldyBFcnJvcigiaHdqcy1ydDogaW1hZ2UgZG9lcyBub3QgZXhwb3J0IF9faGVhcF9iYXNlIChjYW5ub3QgZGVyaXZlIHRoZSByZXNlcnZlZCBydCB3aW5kb3cpIik6by53aHk9PT0ibm8tZ2xvYmFsLXNlY3Rpb24iP25ldyBFcnJvcigiaHdqcy1ydDogaW1hZ2UgaGFzIG5vIGdsb2JhbCBzZWN0aW9uIChjYW5ub3QgcmVhZCBfX2hlYXBfYmFzZSkiKTpvLndoeT09PSJvdXQtb2YtcmFuZ2UiP25ldyBFcnJvcihgaHdqcy1ydDogX19oZWFwX2Jhc2UgZ2xvYmFsIGluZGV4ICR7by5leHBvcnRHbG9iYWxJbmRleH0gKGRlZmluZWQgJHtvLmRlZmluZWRJbmRleH0pIG91dCBvZiByYW5nZSAoJHtvLmdjb3VudH0gZGVmaW5lZCBnbG9iYWxzKWApOm8ud2h5PT09Im5vdC1pMzItY29uc3QiP25ldyBFcnJvcihgaHdqcy1ydDogX19oZWFwX2Jhc2UgaW5pdCBpcyBvcGNvZGUgMHgke28ub3AudG9TdHJpbmcoMTYpfSwgZXhwZWN0ZWQgaTMyLmNvbnN0ICgweDQxKWApOm5ldyBFcnJvcigiaHdqcy1ydDogX19oZWFwX2Jhc2UgZ2xvYmFsIG5vdCByZWFjaGVkIHdoaWxlIHdhbGtpbmcgdGhlIGdsb2JhbCBzZWN0aW9uIil9cihxYywicmVhZEhlYXBCYXNlIik7ZnVuY3Rpb24gWm8oZSl7cmV0dXJuIFVsKHFjKGUpK1ZjLFhjKT4+PjB9cihabywiZGVyaXZlSHdqc1J0V2luZG93QmFzZSIpO3ZhciBRbz02NCoxMDI0LG1sPTEsWmM9MixRYz0zLHBsPTE2O2Z1bmN0aW9uIFRsKGUsdD0wKXtsZXQgbz1lO2lmKCFvfHxvLmxlbmd0aDw4fHxvWzBdIT09MHx8b1sxXSE9PTk3fHxvWzJdIT09MTE1fHxvWzNdIT09MTA5KXJldHVybntkYXRhTG86MCxkYXRhSGk6MCxzdGFja0hpOjB9O2xldCBzPXIobT0+e2xldCBjPUNyKG8sbSk7cmV0dXJuIGMub2s/Yy52YWx1ZT4+PjA6MH0sInJlYWQiKSxsPXMoIl9fc3RhY2tfcG9pbnRlciIpfHx0Pj4+MCxkPXMoIl9fZGF0YV9lbmQiKXx8cygiX19oZWFwX2Jhc2UiKTtyZXR1cm57ZGF0YUxvOmwmJmQmJmw8PWQ/bDowLGRhdGFIaTpkLHN0YWNrSGk6bH19cihUbCwicmVhZE1haW5Sb290TGF5b3V0Iik7ZnVuY3Rpb24gamwoZSl7bGV0IHQ9ZT9lLl9fd2FzbTMyX2dldF9zdGFja19wb2ludGVyOnZvaWQgMDtyZXR1cm4gdHlwZW9mIHQ9PSJmdW5jdGlvbiI/dCgpPj4+MDowfXIoamwsImluaXRpYWxTdGFja1BvaW50ZXIiKTtmdW5jdGlvbiBEbChlLHQ9MCl7bGV0IG89dD4+PjA7aWYobylyZXR1cm57aGk6byxsaW1pdDowfTtsZXQgcz1lP2Uuc3RhY2tIaT4+PjA6MDtyZXR1cm4gcz97aGk6cyxsaW1pdDowfTpudWxsfXIoRGwsImNhbGxlclN0YWNrUmVnaW9uIik7ZnVuY3Rpb24gTmwoe21haW46ZT1udWxsLG1vZHVsZXM6dD1bXSxzdGFja3M6bz1bXSxhcmVuYTpzPVtdfSl7bGV0IGw9W107ZSYmZS5kYXRhSGk+ZS5kYXRhTG8mJmwucHVzaCh7a2luZDptbCxsbzplLmRhdGFMbz4+PjAsaGk6ZS5kYXRhSGk+Pj4wLGxpbWl0OjB9KTtmb3IobGV0IF8gb2YgdCl7bGV0IG09Xy5tZW1vcnlCYXNlPj4+MCxjPV8ubWVtb3J5U2l6ZT4+PjA7bSYmYyYmbC5wdXNoKHtraW5kOm1sLGxvOm0saGk6bStjPj4+MCxsaW1pdDowfSl9bGV0IGQ9bC5zbGljZSgpO2ZvcihsZXQgXyBvZiBvKXtsZXQgbT1fLmhpPj4+MCxjPV8ubGltaXQ+Pj4wO2lmKCEobT5jKSljb250aW51ZTtsZXQgaD1fLnNwPj4+MCxnPWg+PWMmJmg8PW0/aDpjO2wucHVzaCh7a2luZDpaYyxsbzpnLGhpOm0sbGltaXQ6Y30pfWZvcihsZXRbXyxtXW9mIHMpe2xldCBjPV8+Pj4wLGg9bT4+PjA7aD5jJiYoZC5zb21lKGc9PmM+PWcubG8mJmg8PWcuaGkpfHxsLnB1c2goe2tpbmQ6UWMsbG86YyxoaTpoLGxpbWl0OjB9KSl9cmV0dXJuIGx9cihObCwiYnVpbGRSb290TWFwIik7ZnVuY3Rpb24gTGwoZSx0LG8scyl7bGV0IGw9TWF0aC5tYXgoMCxNYXRoLm1pbihvfDAscy5sZW5ndGgpKSxkPXQ+Pj4wO2lmKGw+MCl7aWYoZD09PTB8fGQrbCpwbD5lLmJ5dGVMZW5ndGgpcmV0dXJuLTE0O2xldCBfPW5ldyBEYXRhVmlldyhlKTtmb3IobGV0IG09MDttPGw7bSsrKXtsZXQgYz1zW21dLGg9ZCttKnBsO18uc2V0VWludDMyKGgsYy5raW5kPj4+MCwhMCksXy5zZXRVaW50MzIoaCs0LGMubG8+Pj4wLCEwKSxfLnNldFVpbnQzMihoKzgsYy5oaT4+PjAsITApLF8uc2V0VWludDMyKGgrMTIsYy5saW1pdD4+PjAsITApfX1yZXR1cm4gcy5sZW5ndGh9cihMbCwid3JpdGVSb290TWFwIik7dmFyIG9yPTE2KjEwMjQqMTAyNDtmdW5jdGlvbiBNbChlKXtyZXR1cm4gWm8oZSkrTXM+Pj4wfXIoTWwsImRlcml2ZUh3anNMaWJjV2luZG93QmFzZSIpO3ZhciBldT1uZXcgVWludDMyQXJyYXkoWzExMTYzNTI0MDgsMTg5OTQ0NzQ0MSwzMDQ5MzIzNDcxLDM5MjEwMDk1NzMsOTYxOTg3MTYzLDE1MDg5NzA5OTMsMjQ1MzYzNTc0OCwyODcwNzYzMjIxLDM2MjQzODEwODAsMzEwNTk4NDAxLDYwNzIyNTI3OCwxNDI2ODgxOTg3LDE5MjUwNzgzODgsMjE2MjA3ODIwNiwyNjE0ODg4MTAzLDMyNDgyMjI1ODAsMzgzNTM5MDQwMSw0MDIyMjI0Nzc0LDI2NDM0NzA3OCw2MDQ4MDc2MjgsNzcwMjU1OTgzLDEyNDkxNTAxMjIsMTU1NTA4MTY5MiwxOTk2MDY0OTg2LDI1NTQyMjA4ODIsMjgyMTgzNDM0OSwyOTUyOTk2ODA4LDMyMTAzMTM2NzEsMzMzNjU3MTg5MSwzNTg0NTI4NzExLDExMzkyNjk5MywzMzgyNDE4OTUsNjY2MzA3MjA1LDc3MzUyOTkxMiwxMjk0NzU3MzcyLDEzOTYxODIyOTEsMTY5NTE4MzcwMCwxOTg2NjYxMDUxLDIxNzcwMjYzNTAsMjQ1Njk1NjAzNywyNzMwNDg1OTIxLDI4MjAzMDI0MTEsMzI1OTczMDgwMCwzMzQ1NzY0NzcxLDM1MTYwNjU4MTcsMzYwMDM1MjgwNCw0MDk0NTcxOTA5LDI3NTQyMzM0NCw0MzAyMjc3MzQsNTA2OTQ4NjE2LDY1OTA2MDU1Niw4ODM5OTc4NzcsOTU4MTM5NTcxLDEzMjI4MjIyMTgsMTUzNzAwMjA2MywxNzQ3ODczNzc5LDE5NTU1NjIyMjIsMjAyNDEwNDgxNSwyMjI3NzMwNDUyLDIzNjE4NTI0MjQsMjQyODQzNjQ3NCwyNzU2NzM0MTg3LDMyMDQwMzE0NzksMzMyOTMyNTI5OF0pO2Z1bmN0aW9uIHR1KGUpe2xldCB0PW5ldyBVaW50MzJBcnJheShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKSxvPWUubGVuZ3RoLHM9TWF0aC5mbG9vcihvLzUzNjg3MDkxMiksbD1vPDwzPj4+MCxkPW8tbyU2NCxfPW5ldyBVaW50OEFycmF5KChvLWQrOD4+NikrMTw8Nik7Xy5zZXQoZS5zdWJhcnJheShkKSksX1tvLWRdPTEyODtsZXQgbT1uZXcgRGF0YVZpZXcoXy5idWZmZXIpO20uc2V0VWludDMyKF8ubGVuZ3RoLTgscywhMSksbS5zZXRVaW50MzIoXy5sZW5ndGgtNCxsLCExKTtsZXQgYz1uZXcgRGF0YVZpZXcoZS5idWZmZXIsZS5ieXRlT2Zmc2V0LGUuYnl0ZUxlbmd0aCksaD1uZXcgVWludDMyQXJyYXkoNjQpO2ZvcihsZXQgeD0wO3g8ZCtfLmxlbmd0aDt4Kz02NCl7bGV0IFM9eDxkP2M6bSxSPXg8ZD94OngtZDtmb3IobGV0IHJlPTA7cmU8MTY7cmUrKyloW3JlXT1TLmdldFVpbnQzMihSK3JlKjQsITEpO2ZvcihsZXQgcmU9MTY7cmU8NjQ7cmUrKyl7bGV0IFg9aFtyZS0xNV0sa2U9aFtyZS0yXSxvZT0oWD4+Pjd8WDw8MjUpXihYPj4+MTh8WDw8MTQpXlg+Pj4zLEZlPShrZT4+PjE3fGtlPDwxNSleKGtlPj4+MTl8a2U8PDEzKV5rZT4+PjEwO2hbcmVdPWhbcmUtMTZdK29lK2hbcmUtN10rRmU+Pj4wfWxldCB3PXRbMF0seT10WzFdLEQ9dFsyXSxkZT10WzNdLHo9dFs0XSxRPXRbNV0sVT10WzZdLGZlPXRbN107Zm9yKGxldCByZT0wO3JlPDY0O3JlKyspe2xldCBYPSh6Pj4+Nnx6PDwyNileKHo+Pj4xMXx6PDwyMSleKHo+Pj4yNXx6PDw3KSxrZT16JlFefnomVSxvZT1mZStYK2tlK2V1W3JlXStoW3JlXT4+PjAsRmU9KHc+Pj4yfHc8PDMwKV4odz4+PjEzfHc8PDE5KV4odz4+PjIyfHc8PDEwKSxqPXcmeV53JkReeSZELHJ0PUZlK2o+Pj4wO2ZlPVUsVT1RLFE9eix6PWRlK29lPj4+MCxkZT1ELEQ9eSx5PXcsdz1vZStydD4+PjB9dFswXT10WzBdK3c+Pj4wLHRbMV09dFsxXSt5Pj4+MCx0WzJdPXRbMl0rRD4+PjAsdFszXT10WzNdK2RlPj4+MCx0WzRdPXRbNF0rej4+PjAsdFs1XT10WzVdK1E+Pj4wLHRbNl09dFs2XStVPj4+MCx0WzddPXRbN10rZmU+Pj4wfWxldCBnPSIiO2ZvcihsZXQgeD0wO3g8ODt4KyspZys9dFt4XS50b1N0cmluZygxNikucGFkU3RhcnQoOCwiMCIpO3JldHVybiBnfXIodHUsInNoYTI1NkhleEpzIik7dmFyIG51PSJiYTc4MTZiZjhmMDFjZmVhNDE0MTQwZGU1ZGFlMjIyM2IwMDM2MWEzOTYxNzdhOWNiNDEwZmY2MWYyMDAxNWFkIixzcjtmdW5jdGlvbiBzdSgpe2lmKHNyIT09dm9pZCAwKXJldHVybiBzcjtzcj1udWxsO3RyeXtsZXQgZT1nbG9iYWxUaGlzLnByb2Nlc3M/LmdldEJ1aWx0aW5Nb2R1bGU/Ligibm9kZTpjcnlwdG8iKTtpZihlJiZ0eXBlb2YgZS5jcmVhdGVIYXNoPT0iZnVuY3Rpb24iKXtsZXQgdD1yKHM9PmUuY3JlYXRlSGFzaCgic2hhMjU2IikudXBkYXRlKHMpLmRpZ2VzdCgiaGV4IiksImhhc2giKSxvPW5ldyBVaW50OEFycmF5KHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlcj09ImZ1bmN0aW9uIj9uZXcgU2hhcmVkQXJyYXlCdWZmZXIoMyk6Myk7by5zZXQoWzk3LDk4LDk5XSksdChvKT09PW51JiYoc3I9dCl9fWNhdGNoe31yZXR1cm4gc3J9cihzdSwiaG9zdFNoYTI1NkhleCIpO2Z1bmN0aW9uIE9zKGUpe2xldCB0PXN1KCk7cmV0dXJuIHQ/dChlKTp0dShlKX1yKE9zLCJzaGEyNTZIZXgiKTt2YXIgY3M9Imh3anMucmV0YWluZWQiLHJyPTMrY3MubGVuZ3RoKzQrMzI7ZnVuY3Rpb24gYnMoZSl7bGV0IHQ9ZT9lLmxlbmd0aDowO2lmKHQ8OCtycilyZXR1cm4gbnVsbDtsZXQgbz10LXJyO2lmKGVbb10hPT0wfHxlW28rMV0hPT1yci0yfHxlW28rMl0hPT1jcy5sZW5ndGgpcmV0dXJuIG51bGw7bys9Mztmb3IobGV0IGQ9MDtkPGNzLmxlbmd0aDtkKyspaWYoZVtvK2RdIT09Y3MuY2hhckNvZGVBdChkKSlyZXR1cm4gbnVsbDtvKz1jcy5sZW5ndGg7bGV0IHM9KGVbb118ZVtvKzFdPDw4fGVbbysyXTw8MTZ8ZVtvKzNdPDwyNCk+Pj4wLGw9IiI7Zm9yKGxldCBkPTA7ZDwzMjtkKyspbCs9ZVtvKzQrZF0udG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKTtyZXR1cm57d2lyZUxlbmd0aDpzLGRpZ2VzdDpsfX1yKGJzLCJyZXRhaW5lZExpYnJhcnlJbmZvIik7ZnVuY3Rpb24gT2woZSx0KXtpZighL15bMC05YS1mXXs2NH0kLy50ZXN0KHQpKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiByZXRhaW5lZCBjb3B5OiAke0pTT04uc3RyaW5naWZ5KFN0cmluZyh0KS5zbGljZSgwLDgwKSl9IGlzIG5vdCBhIFNIQS0yNTYgKG5ldmVyLXNpbGVudClgKTtsZXQgbz1lLmxlbmd0aDtpZihvPDh8fGVbMF0hPT0wfHxlWzFdIT09OTd8fGVbMl0hPT0xMTV8fGVbM10hPT0xMDkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHJldGFpbmVkIGNvcHk6ICR7dC5zbGljZSgwLDE2KX1cdTIwMjYgaXMgbm90IGEgd2FzbSBtb2R1bGUgKG5ldmVyLXNpbGVudClgKTtpZihicyhlKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogcmV0YWluZWQgY29weTogJHt0LnNsaWNlKDAsMTYpfVx1MjAyNiBpcyBhIHJldGFpbmVkIGNvcHkgYWxyZWFkeSAobmV2ZXItc2lsZW50KWApO2xldCBzPVtbMCw4XV0sbD04LGQ9MCxfPTg7Zm9yKDtfPG87KXtsZXQgaD1lW19dLGc9XysxLHg9MCxTPTE7Zm9yKDs7KXtpZihnPj1vKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiByZXRhaW5lZCBjb3B5OiAke3Quc2xpY2UoMCwxNil9XHUyMDI2OiB0aGUgc2VjdGlvbiBoZWFkZXIgYXQgJHtffSBydW5zIHBhc3QgdGhlIG1vZHVsZSAobmV2ZXItc2lsZW50KWApO2xldCB3PWVbZysrXTtpZih4Kz0odyYxMjcpKlMsUyo9MTI4LCEodyYxMjgpKWJyZWFrfWxldCBSPWcreDtpZihSPm8pdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHJldGFpbmVkIGNvcHk6ICR7dC5zbGljZSgwLDE2KX1cdTIwMjY6IHNlY3Rpb24gJHtofSBhdCAke199IGRlY2xhcmVzICR7eH1CLCBwYXN0IHRoZSBtb2R1bGUncyAke299QiAobmV2ZXItc2lsZW50KWApO2g9PT0xMHx8aD09PTExP2QrPVItXzoocy5wdXNoKFtfLFJdKSxsKz1SLV8pLF89Un1sZXQgbT1uZXcgVWludDhBcnJheShuZXcgU2hhcmVkQXJyYXlCdWZmZXIoZD4wP2wrcnI6bykpLGM9MDtmb3IobGV0W2gsZ11vZiBzKW0uc2V0KGUuc3ViYXJyYXkoaCxnKSxjKSxjKz1nLWg7aWYoZD09PTApcmV0dXJuIG07bVtjKytdPTAsbVtjKytdPXJyLTIsbVtjKytdPWNzLmxlbmd0aDtmb3IobGV0IGg9MDtoPGNzLmxlbmd0aDtoKyspbVtjKytdPWNzLmNoYXJDb2RlQXQoaCk7bVtjKytdPW8mMjU1LG1bYysrXT1vPj4+OCYyNTUsbVtjKytdPW8+Pj4xNiYyNTUsbVtjKytdPW8+Pj4yNCYyNTU7Zm9yKGxldCBoPTA7aDwzMjtoKyspbVtjKytdPXBhcnNlSW50KHQuc2xpY2UoaCoyLGgqMisyKSwxNik7cmV0dXJuIG19cihPbCwicmV0YWluZWRMaWJyYXJ5Qnl0ZXMiKTtmdW5jdGlvbiBydShlKXtsZXQgdD1icyhlKTtyZXR1cm4gdD90LndpcmVMZW5ndGg6ZS5sZW5ndGh9cihydSwic2hhcmVkTGliV2lyZUxlbmd0aCIpO2Z1bmN0aW9uIFdsKGUsdCl7bGV0IG89dC5ieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk/dC5ieXRlczpuZXcgVWludDhBcnJheSh0LmJ5dGVzKSxzPWJzKG8pO2lmKHMmJnMuZGlnZXN0IT09dC5kaWdlc3QpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHNoYXJlZC1saWIgZGVsaXZlcnkgZm9yIGRpZ2VzdCAke3QuZGlnZXN0fSBjYXJyaWVzIHRoZSByZXRhaW5lZCBjb3B5IG9mICR7cy5kaWdlc3R9IChuZXZlci1zaWxlbnQpYCk7aWYocyYmIXQubW9kdWxlJiYhKGUmJmUubW9kdWxlKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogc2hhcmVkLWxpYiBkZWxpdmVyeSBmb3IgZGlnZXN0ICR7dC5kaWdlc3R9IGlzIGEgcmV0YWluZWQgY29weSAoJHtvLmxlbmd0aH1CIG9mICR7cy53aXJlTGVuZ3RofUIpIHdpdGggbm8gTW9kdWxlIFx1MjAxNCBhIHJldGFpbmVkIGNvcHkgaG9sZHMgbm8gY29kZSBhbmQgaXMgb25seSBrZXB0IGJlc2lkZSBpdHMgTW9kdWxlIChuZXZlci1zaWxlbnQpYCk7aWYoIWUpcmV0dXJue2J5dGVzOm8sLi4udC5tb2R1bGU/e21vZHVsZTp0Lm1vZHVsZX06e319O2xldCBsPXJ1KGUuYnl0ZXMpLGQ9cz9zLndpcmVMZW5ndGg6by5sZW5ndGg7aWYobCE9PWQpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHNoYXJlZC1saWIgcmUtZGVsaXZlcnkgZm9yIGRpZ2VzdCAke3QuZGlnZXN0fSB3aXRoIERJRkZFUkVOVCBieXRlcyAoJHtsfSB2cyAke2R9KSBcdTIwMTQgY29udGVudC1hZGRyZXNzZWQgZGVsaXZlcnkgY2FuIG5ldmVyIGRpc2FncmVlIChuZXZlci1zaWxlbnQpYCk7cmV0dXJuIWUubW9kdWxlJiZ0Lm1vZHVsZSYmKGUubW9kdWxlPXQubW9kdWxlKSxzJiYhYnMoZS5ieXRlcykmJihlLmJ5dGVzPW8pLGV9cihXbCwibWVyZ2VTaGFyZWRMaWIiKTt2YXIgV3I9Y2xhc3N7c3RhdGlje3IodGhpcywiU29Nb2R1bGVDYWNoZSIpfWNvbnN0cnVjdG9yKHQsbyxzPU9zKXt0aGlzLm1heD10LHRoaXMuY29udGVudEtleT1vLHRoaXMuZGlnZXN0T2Y9cyx0aGlzLmVudHJpZXM9W119Z2V0IHNpemUoKXtyZXR1cm4gdGhpcy5lbnRyaWVzLmxlbmd0aH1rZXlPZih0LG8pe3JldHVybiBvIT09dm9pZCAwP2BzaGEyNTY6JHtvfWA6dGhpcy5jb250ZW50S2V5KHQpfWZpbmQodCxvKXtsZXQgcz10Lmxlbmd0aCxsPXtsZW46cyxkaWdlc3Q6byxjb250ZW50OnZvaWQgMH0sZDtpZihvIT09dm9pZCAwKXtpZihkPXRoaXMuZW50cmllcy5maW5kKG09Pm0uZGlnZXN0PT09byksIWQpe2xldCBtPXRoaXMuZW50cmllcy5maWx0ZXIoYz0+Yy5kaWdlc3Q9PT12b2lkIDAmJmMubGVuPT09cyk7bS5sZW5ndGg+MCYmKGwuY29udGVudD10aGlzLmNvbnRlbnRLZXkodCksZD1tLmZpbmQoYz0+Yy5jb250ZW50PT09bC5jb250ZW50KSxkJiYoZC5kaWdlc3Q9bykpfX1lbHNlIGlmKGwuY29udGVudD10aGlzLmNvbnRlbnRLZXkodCksZD10aGlzLmVudHJpZXMuZmluZChtPT5tLmNvbnRlbnQ9PT1sLmNvbnRlbnQpLCFkKXtsZXQgbT10aGlzLmVudHJpZXMuZmlsdGVyKGM9PmMuY29udGVudD09PXZvaWQgMCYmYy5sZW49PT1zKTttLmxlbmd0aD4wJiYobC5kaWdlc3Q9dGhpcy5kaWdlc3RPZih0KSxkPW0uZmluZChjPT5jLmRpZ2VzdD09PWwuZGlnZXN0KSxkJiYoZC5jb250ZW50PWwuY29udGVudCkpfWxldCBfPW8hPT12b2lkIDA/YHNoYTI1Njoke299YDpsLmNvbnRlbnQ7cmV0dXJuIGQ/KHRoaXMuZW50cmllcy5zcGxpY2UodGhpcy5lbnRyaWVzLmluZGV4T2YoZCksMSksdGhpcy5lbnRyaWVzLnB1c2goZCkse2tleTpfLG1vZHVsZTpkLm1vZHVsZSxpZDpsfSk6e2tleTpfLGlkOmx9fWFkZCh0LG8pe3RoaXMuZW50cmllcy5wdXNoKHtsZW46dC5sZW4sZGlnZXN0OnQuZGlnZXN0LGNvbnRlbnQ6dC5jb250ZW50LG1vZHVsZTpvfSksdGhpcy5lbnRyaWVzLmxlbmd0aD50aGlzLm1heCYmdGhpcy5lbnRyaWVzLnNoaWZ0KCl9fTtmdW5jdGlvbiBXcyhlLHQpe2xldCBvPWU/ZS5tb2RlOnZvaWQgMDtyZXR1cm4gbz09PSJ0aHJlYWQifHxvPT09Im1pZ3JhdGUtcmVzdW1lIiYmdD9lLnVzZXJMYW5lfDB8fDA6bz09PSJmb3JrLXJlc3VtZSImJnQmJmUuZm9ya0xhbmV8MHx8MH1yKFdzLCJkZXJpdmVVc2VyTGFuZSIpO3ZhciBvdT1uZXcgU2V0KFsiX19od2pzX2RyaXZlIiwiX19od2pzX2RyaXZlX3Jlc3VtZSJdKTtmdW5jdGlvbiBDbChlLHQsbyl7bGV0IHM9MDtmb3IobGV0IGwgb2YgZSl0cnl7KGwudmFsdWV8MCk9PT0wJiYobC52YWx1ZT1vfDAscysrKX1jYXRjaHt9cmV0dXJuIHQmJnR5cGVvZiB0Ll9faHdqc19idWRnZXRfZ2V0PT0iZnVuY3Rpb24iJiZ0eXBlb2YgdC5fX2h3anNfYnVkZ2V0X3NldD09ImZ1bmN0aW9uIiYmKHQuX19od2pzX2J1ZGdldF9nZXQoKXwwKT09PTAmJih0Ll9faHdqc19idWRnZXRfc2V0KG98MCkscysrKSxzfXIoQ2wsInJlZmlsbEV4cGlyZWRCdWRnZXRzIik7ZnVuY3Rpb24gUGwoZSx0LG8pe3JldHVybiB0eXBlb2YgdCE9ImZ1bmN0aW9uInx8IW91LmhhcyhlKT90OiguLi5zKT0+KG8oKSx0KC4uLnMpKX1yKFBsLCJkcml2ZUVudHJ5SW1wb3J0Iik7ZnVuY3Rpb24gQmwoZSx0KXtpZihlJiZ0eXBlb2YgZT09Im9iamVjdCImJiJieXRlcyJpbiBlKXRocm93IG5ldyBFcnJvcigiaHdqcy1saWJjOiB0aGUgZm9yayBwYXlsb2FkIGNhcnJpZXMgbGliYy5zbyBCWVRFUyBcdTIwMTQgdGhlIEQ0IGZvcmsgcnVsZSBpcyBwbGFjZW1lbnQtcmVjb3JkLW9ubHkgKGEgYmFzaCBmb3JrIHN0b3JtIHdvdWxkIGNsb25lIEdCczsgUExBTi1EWU5BTUlDLUxJQkMgXHhBNzMuNCkuIENvcnJ1cHQgcGF5bG9hZDsgcmVmdXNpbmcgKG5ldmVyLXNpbGVudCkuIik7aWYoU3RyaW5nKGUuZGlnZXN0KSE9PXQpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IGZvcmstcmVwbGF5IGRpZ2VzdCAke1N0cmluZyhlLmRpZ2VzdCkuc2xpY2UoMCwxNil9XHUyMDI2ICE9IHRoZSBib290IGltYWdlJ3MgbmVlZGVkIGRpZ2VzdCAke3Quc2xpY2UoMCwxNil9XHUyMDI2IFx1MjAxNCB0aGUgcmVjb3JkZWQgcGxhY2VtZW50IGlzIGZvciBhIGRpZmZlcmVudCBsaWJjLnNvIGdlbmVyYXRpb24gKG5ldmVyLXNpbGVudCkuYCl9cihCbCwiY2hlY2tMaWJjUmVwbGF5UmVjb3JkIik7ZnVuY3Rpb24gZWEoZSl7bGV0IHQ9ZTtpZih0Lmxlbmd0aDw4fHx0WzBdIT09MHx8dFsxXSE9PTk3fHx0WzJdIT09MTE1fHx0WzNdIT09MTA5KXRocm93IG5ldyBFcnJvcigiaHdqcy1kbG9wZW46IHBhcnNlU2lkZU1vZHVsZU5lZWRlZDogbm90IGEgd2FzbSBtb2R1bGUgKGJhZCBtYWdpYykiKTtsZXQgbz1udWxsLHM9MCxsPTg7Zm9yKDtsPHQubGVuZ3RoOyl7bGV0IG09dFtsKytdLGM7W2MsbF09Qih0LGwpO2xldCBoPWwrYztpZihtPT09MCl7bGV0IGcseD1sO1tnLHhdPUIodCx4KSxMdCh0LnN1YmFycmF5KHgseCtnKSk9PT0id2FzbS5saW51eC5uZWVkZWQiJiYocysrLG89dC5zdWJhcnJheSh4K2csaCkpfWw9aH1pZihzPT09MClyZXR1cm5bXTtpZihzPjEpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogJHtzfSB3YXNtLmxpbnV4Lm5lZWRlZCBzZWN0aW9ucyBvbiBhIHNpZGUgbW9kdWxlIFx1MjAxNCBvbmUgbmVlZGVkIGxpc3QgcGVyIG1vZHVsZSAobmV2ZXItc2lsZW50KWApO2xldCBkO3RyeXtkPUpTT04ucGFyc2UoTHQobykpfWNhdGNoKG0pe3Rocm93IG5ldyBFcnJvcigiaHdqcy1kbG9wZW46IG1hbGZvcm1lZCBzaWRlLW1vZHVsZSB3YXNtLmxpbnV4Lm5lZWRlZCAobm90IEpTT04pOiAiKyhtIGluc3RhbmNlb2YgRXJyb3I/bS5tZXNzYWdlOlN0cmluZyhtKSkrIiAobmV2ZXItc2lsZW50KSIpfWlmKCFkfHx0eXBlb2YgZCE9Im9iamVjdCJ8fCFBcnJheS5pc0FycmF5KGQubmVlZGVkKSl0aHJvdyBuZXcgRXJyb3IoJ2h3anMtZGxvcGVuOiBzaWRlLW1vZHVsZSB3YXNtLmxpbnV4Lm5lZWRlZCBzaGFwZSBtaXNtYXRjaCBcdTIwMTQgd2FudCB7Im5lZWRlZCI6Wy4uLl19IChuZXZlci1zaWxlbnQpJyk7bGV0IF89bmV3IFNldDtyZXR1cm4gZC5uZWVkZWQuZm9yRWFjaCgobSxjKT0+e2lmKHR5cGVvZiBtIT0ic3RyaW5nInx8IS9eWzAtOUEtWmEtei5fKy1dK1wuWzAtOWEtZl17NjR9JC8udGVzdChtKXx8bS5sZW5ndGg+MTI3fHwvXmxpYmNcLnNvXC4vLnRlc3QobSl8fF8uaGFzKG0pKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IHNpZGUtbW9kdWxlIHdhc20ubGludXgubmVlZGVkIGVudHJ5ICR7Y30gJHtKU09OLnN0cmluZ2lmeShtKX0gaXMgbm90IGEgZGlzdGluY3QgZGlnZXN0LXF1YWxpZmllZCBsaWJyYXJ5IG5hbWUgb3RoZXIgdGhhbiBsaWJjLnNvIChuZXZlci1zaWxlbnQpYCk7Xy5hZGQobSl9KSxbLi4uZC5uZWVkZWRdfXIoZWEsInBhcnNlU2lkZU1vZHVsZU5lZWRlZCIpO2Z1bmN0aW9uIHRzKGUpe3JldHVybiBlLnNsaWNlKC02NCl9cih0cywibmVlZGVkRGlnZXN0Iik7ZnVuY3Rpb24gYXIoZSl7cmV0dXJuIGUuc2xpY2UoMCwtNjUpfXIoYXIsIm5lZWRlZFNvbmFtZSIpO2Z1bmN0aW9uIHRhKGUpe2xldCB0PWU7aWYodC5sZW5ndGg8OHx8dFswXSE9PTB8fHRbMV0hPT05N3x8dFsyXSE9PTExNXx8dFszXSE9PTEwOSl0aHJvdyBuZXcgRXJyb3IoImh3anMtbGliYzogcGFyc2VXYXNtTGludXhOZWVkZWQ6IG5vdCBhIHdhc20gbW9kdWxlIChiYWQgbWFnaWMpIik7bGV0IG89bnVsbCxzPTAsbD04O2Zvcig7bDx0Lmxlbmd0aDspe2xldCBjPXRbbCsrXSxoO1toLGxdPUIodCxsKTtsZXQgZz1sK2g7aWYoYz09PTApe2xldCB4LFM9bDtbeCxTXT1CKHQsUyk7bGV0IFI9THQodC5zdWJhcnJheShTLFMreCkpO1MrPXgsUj09PSJ3YXNtLmxpbnV4Lm5lZWRlZCImJihzKyssbz10LnN1YmFycmF5KFMsZykpfWw9Z31pZihzPT09MClyZXR1cm4gbnVsbDtpZihzPjEpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6ICR7c30gd2FzbS5saW51eC5uZWVkZWQgc2VjdGlvbnMgb24gdGhlIGltYWdlIFx1MjAxNCBleGFjdGx5IE9ORSBuZWVkZWQtbGlzdCBjYXJyaWVyIGlzIGxlZ2FsIChhIGNvbmNhdGVuYXRlZC90YW1wZXJlZCBhcnRpZmFjdDsgbmV2ZXItc2lsZW50IHJlZnVzZSlgKTtsZXQgZDt0cnl7ZD1KU09OLnBhcnNlKEx0KG8pKX1jYXRjaChjKXt0aHJvdyBuZXcgRXJyb3IoImh3anMtbGliYzogbWFsZm9ybWVkIHdhc20ubGludXgubmVlZGVkIHBheWxvYWQgKG5vdCBKU09OKTogIisoYyBpbnN0YW5jZW9mIEVycm9yP2MubWVzc2FnZTpTdHJpbmcoYykpKyIgKG5ldmVyLXNpbGVudCByZWZ1c2UpIil9aWYoIWR8fHR5cGVvZiBkIT0ib2JqZWN0Inx8IUFycmF5LmlzQXJyYXkoZC5uZWVkZWQpfHx0eXBlb2YgZC5zdXNwZW5kZXJzX3NoYTI1NiE9InN0cmluZyJ8fCEvXlswLTlhLWZdezY0fSQvLnRlc3QoZC5zdXNwZW5kZXJzX3NoYTI1NikpdGhyb3cgbmV3IEVycm9yKCdod2pzLWxpYmM6IHdhc20ubGludXgubmVlZGVkIHBheWxvYWQgc2hhcGUgbWlzbWF0Y2ggXHUyMDE0IHdhbnQgeyJuZWVkZWQiOlsuLi5dLCJzdXNwZW5kZXJzX3NoYTI1NiI6IjxoZXg2ND4ifSAobmV2ZXItc2lsZW50IHJlZnVzZSknKTtsZXQgXz0xMjc7ZC5uZWVkZWQuZm9yRWFjaCgoYyxoKT0+e2lmKHR5cGVvZiBjIT0ic3RyaW5nInx8IS9eWzAtOUEtWmEtei5fKy1dK1wuWzAtOWEtZl17NjR9JC8udGVzdChjKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogd2FzbS5saW51eC5uZWVkZWQgZW50cnkgJHtofSAke0pTT04uc3RyaW5naWZ5KGMpfSBpcyBub3QgYSBkaWdlc3QtcXVhbGlmaWVkIGxpYnJhcnkgbmFtZSAod2FudCA8c29uYW1lPi48c2hhMjU2LWhleDY0PiBvdmVyIFswLTlBLVphLXouXystXTsgbmV2ZXItc2lsZW50IHJlZnVzZSlgKTtpZihjLmxlbmd0aD5fKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiB3YXNtLmxpbnV4Lm5lZWRlZCBlbnRyeSAke2h9IGlzICR7Yy5sZW5ndGh9IGJ5dGVzLCBvdmVyIHRoZSAke199IHRoZSBrZXJuZWwncyBwYXJzZXIgYWNjZXB0cyAoV0FTTTMyX05FRURFRF9OQU1FX01BWCkgXHUyMDE0IHRoZSBleGVjIHdvdWxkIGZhaWwgdGhlcmUgd2l0aCBubyBlbnRyeSBuYW1lZCAobmV2ZXItc2lsZW50IHJlZnVzZSlgKTtpZihoPT09MCYmIS9ebGliY1wuc29cLlswLTlhLWZdezY0fSQvLnRlc3QoYykpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHdhc20ubGludXgubmVlZGVkIGVudHJ5IDAgaXMgJHtKU09OLnN0cmluZ2lmeShjKX0sIG5vdCBhIGRpZ2VzdC1xdWFsaWZpZWQgbGliYy5zbyBcdTIwMTQgZW50cnkgMCBpcyBsaWJjLnNvIGJ5IGNvbnN0cnVjdGlvbiAobmV2ZXItc2lsZW50IHJlZnVzZSlgKX0pO2xldCBtPW5ldyBTZXQ7Zm9yKGxldCBjIG9mIGQubmVlZGVkKXtpZihtLmhhcyhjKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogd2FzbS5saW51eC5uZWVkZWQgbmFtZXMgJHtKU09OLnN0cmluZ2lmeShjKX0gbW9yZSB0aGFuIG9uY2UgXHUyMDE0IG9uZSBlbnRyeSBwZXIgbGlicmFyeSAobmV2ZXItc2lsZW50IHJlZnVzZSlgKTttLmFkZChjKX1yZXR1cm57bmVlZGVkOlsuLi5kLm5lZWRlZF0sc3VzcGVuZGVyc1NoYTI1NjpkLnN1c3BlbmRlcnNfc2hhMjU2fX1yKHRhLCJwYXJzZVdhc21MaW51eE5lZWRlZCIpO2Z1bmN0aW9uIGlyKGUpe2xldCB0PWU7aWYodC5sZW5ndGg8OHx8dFswXSE9PTB8fHRbMV0hPT05N3x8dFsyXSE9PTExNXx8dFszXSE9PTEwOSl0aHJvdyBuZXcgRXJyb3IoImh3anMtZGxvcGVuOiBwYXJzZUh3anNBYmk6IG5vdCBhIHdhc20gbW9kdWxlIChiYWQgbWFnaWMpIik7bGV0IG89bnVsbCxzPTg7Zm9yKDtzPHQubGVuZ3RoOyl7bGV0IGw9dFtzKytdLGQ7W2Qsc109Qih0LHMpO2xldCBfPXMrZDtpZihsPT09MCl7bGV0IG0sYz1zO1ttLGNdPUIodCxjKTtsZXQgaD1MdCh0LnN1YmFycmF5KGMsYyttKSk7aWYoYys9bSxoPT09Imh3anMuYWJpIil7aWYobyl0aHJvdyBuZXcgRXJyb3IoImh3anMtZGxvcGVuOiBtdWx0aXBsZSBod2pzLmFiaSBzZWN0aW9ucyBpbiB0aGUgLnNvIFx1MjAxNCBleGFjdGx5IE9ORSBtYW5pZmVzdCBpcyBsZWdhbCAoY29uY2F0ZW5hdGVkIC8gbXVsdGktcmVjb3JkIGFydGlmYWN0OyBuZXZlci1zaWxlbnQgcmVmdXNlKSIpO2xldCBnPXIocmU9PntsZXQgWD0wLGtlPTAsb2U9MDtkb3tpZihjPj1fKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IG1hbGZvcm1lZCBod2pzLmFiaSBtYW5pZmVzdCBcdTIwMTQgdHJ1bmNhdGVkIExFQiByZWFkaW5nICR7cmV9IChuZXZlci1zaWxlbnQgcmVmdXNlKWApO29lPXRbYysrXSxYfD0ob2UmMTI3KTw8a2Usa2UrPTd9d2hpbGUob2UmMTI4KTtyZXR1cm4gWD4+PjB9LCJyZWFkRmllbGQiKSx4PXIocmU9PntsZXQgWD0wbixrZT0wbixvZT0wO2Rve2lmKGM+PV8pdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogbWFsZm9ybWVkIGh3anMuYWJpIG1hbmlmZXN0IFx1MjAxNCB0cnVuY2F0ZWQgTEVCIHJlYWRpbmcgJHtyZX0gKG5ldmVyLXNpbGVudCByZWZ1c2UpYCk7b2U9dFtjKytdLFh8PUJpZ0ludChvZSYxMjcpPDxrZSxrZSs9N259d2hpbGUob2UmMTI4KTtyZXR1cm4gWC50b1N0cmluZygxNikucGFkU3RhcnQoMTYsIjAiKX0sInJlYWRGaWVsZDY0SGV4IiksUz1nKCJtYW5pZmVzdF92ZXJzaW9uIiksUj1nKCJkcml2ZV9hYmkiKSx3PWcoInBhcmtlZF9hYmkiKSx5PWcoImRzX3JlZ2lvbl9hYmkiKSxEPWcoInN1c3BlbmRfYWJpX3ZlcnNpb24iKSxkZT1nKCJjYXByZWdfdmVyc2lvbiIpLHo9ZygiZnBjYXN0X3ZlcnNpb24iKSxRPWcoImZsYWdzIiksVT1TPj0yP3goInN1c3BlbmRlcl9wYXJ0aXRpb25fZGlnZXN0Iik6bnVsbCxmZT1TPj0yP2coInJlZnVzZWRfZXhwb3J0cyIpOjA7aWYoYyE9PV8pdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogbWFsZm9ybWVkIGh3anMuYWJpIG1hbmlmZXN0IFx1MjAxNCAke18tY30gdHJhaWxpbmcgYnl0ZShzKSBhZnRlciB0aGUgJHtTPj0yPyIxMCB2MiBmaWVsZHMiOiI4IGZpZWxkcyJ9IChjb25jYXRlbmF0ZWQgbXVsdGktcmVjb3JkIG1hbmlmZXN0PyBuZXZlci1zaWxlbnQgcmVmdXNlKWApO289e21hbmlmZXN0VmVyc2lvbjpTLGRyaXZlQWJpOlIscGFya2VkQWJpOncsZHNSZWdpb25BYmk6eSxzdXNwZW5kQWJpVmVyc2lvbjpELGNhcHJlZ1ZlcnNpb246ZGUsZnBjYXN0VmVyc2lvbjp6LGZsYWdzUmF3OlEsc3VzcGVuZGVyRGlnZXN0TG82NDpVLHJlZnVzZWRFeHBvcnRzOmZlLGZsYWdzOnt1c2VzU2hhZG93U3RhY2s6KFEmMSkhPT0wLHVzZXNUbHM6KFEmMikhPT0wLHNhZmVwb2ludHM6KFEmNCkhPT0wLGR5bmFtaWNNb2R1bGU6KFEmOCkhPT0wLGNoZWNrRW1pdHRpbmc6KFEmMTYpIT09MCxsYW5lQWRkcmVzc2VkOihRJjMyKSE9PTAscHJlZW1wdFRvdGFsOihRJjY0KSE9PTB9LHByZWVtcHRpYmlsaXR5OihRJjY0KSE9PTA/Indob2xlLXByb2dyYW0iOihRJjQpIT09MD8ic2NvcGVkIjoibm9uZSJ9fX1zPV99cmV0dXJuIG99cihpciwicGFyc2VId2pzQWJpIik7ZnVuY3Rpb24gYXUoZSl7bGV0IHQ9ZTtpZih0Lmxlbmd0aDw4fHx0WzBdIT09MHx8dFsxXSE9PTk3fHx0WzJdIT09MTE1fHx0WzNdIT09MTA5KXRocm93IG5ldyBFcnJvcigiaHdqcy1kbG9wZW46IHNjYW5Nb2R1bGVTdXJmYWNlOiBub3QgYSB3YXNtIG1vZHVsZSAoYmFkIG1hZ2ljKSIpO2xldCBvPXtpbXBvcnRzRW52U3RhY2tQb2ludGVyOiExLGltcG9ydGVkRW52RnVuY05hbWVzOltdLGltcG9ydHNId2pzU3VzcGVuZFBhcms6ITEsZXhwb3J0TmFtZXM6W10sZGVmaW5lZE11dGFibGVHbG9iYWxzOltdfSxzPTAsbD1uZXcgTWFwLGQ9ODtmb3IoO2Q8dC5sZW5ndGg7KXtsZXQgXz10W2QrK10sbTtbbSxkXT1CKHQsZCk7bGV0IGM9ZCttO2lmKF89PT0yKXtsZXQgaDtbaCxkXT1CKHQsZCk7Zm9yKGxldCBnPTA7ZzxoO2crKyl7bGV0IHgsUyxSO1t4LGRdPUIodCxkKSxTPUx0KHQuc3ViYXJyYXkoZCxkK3gpKSxkKz14LFt4LGRdPUIodCxkKSxSPUx0KHQuc3ViYXJyYXkoZCxkK3gpKSxkKz14O2xldCB3PXRbZCsrXTtpZih3PT09MClbLGRdPUIodCxkKSxTPT09ImVudiImJm8uaW1wb3J0ZWRFbnZGdW5jTmFtZXMucHVzaChSKSxTPT09Imh3anNfc3VzcGVuZCImJlI9PT0icGFyayImJihvLmltcG9ydHNId2pzU3VzcGVuZFBhcms9ITApO2Vsc2UgaWYodz09PTEpe2QrPTE7bGV0IHk9dFtkKytdO1ssZF09Qih0LGQpLHkmMSYmKFssZF09Qih0LGQpKX1lbHNlIGlmKHc9PT0yKXtsZXQgeT10W2QrK107WyxkXT1CKHQsZCkseSYxJiYoWyxkXT1CKHQsZCkpfWVsc2UgaWYodz09PTMpe2xldCB5PXRbZCsrXSxEPXRbZCsrXTtzKyssUz09PSJlbnYiJiZSPT09Il9fc3RhY2tfcG9pbnRlciImJnk9PT0xMjcmJkQ9PT0xJiYoby5pbXBvcnRzRW52U3RhY2tQb2ludGVyPSEwKX1lbHNlIHRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IHNjYW5Nb2R1bGVTdXJmYWNlOiB1bmtub3duIGltcG9ydCBraW5kIDB4JHt3LnRvU3RyaW5nKDE2KX0gKG1hbGZvcm1lZCAuc287IG5ldmVyLXNpbGVudClgKX19ZWxzZSBpZihfPT09Nil7bGV0IGg7W2gsZF09Qih0LGQpO2ZvcihsZXQgZz0wO2c8aDtnKyspe2xldCB4PXRbZCsrXSxTPXRbZCsrXSxSPSExLHc9ITEseT10W2QrK107aWYoeT09PTY1KXtsZXQgRDtbRCxkXT1Ocyh0LGQsYyksUj1EPT09MCx3PSEwfWVsc2UgaWYoeT09PTY2KVssZF09TnModCxkLGMpO2Vsc2UgaWYoeT09PTY3KWQrPTQ7ZWxzZSBpZih5PT09NjgpZCs9ODtlbHNlIGlmKHk9PT0zNSlbLGRdPUIodCxkKTtlbHNlIGlmKHk9PT0yMDgpZCs9MTtlbHNlIGlmKHk9PT0yMTApWyxkXT1CKHQsZCk7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBzY2FuTW9kdWxlU3VyZmFjZTogdW5zdXBwb3J0ZWQgZ2xvYmFsIGluaXQgb3Bjb2RlIDB4JHt5LnRvU3RyaW5nKDE2KX0gKG5vdCBhbiBsbGQgLXNoYXJlZCBhcnRpZmFjdDsgbmV2ZXItc2lsZW50KWApO2lmKHRbZCsrXSE9PTExKXRocm93IG5ldyBFcnJvcigiaHdqcy1kbG9wZW46IHNjYW5Nb2R1bGVTdXJmYWNlOiBnbG9iYWwgaW5pdCBleHByIG5vdCB0ZXJtaW5hdGVkIGJ5IGVuZCAobWFsZm9ybWVkIC5zbzsgbmV2ZXItc2lsZW50KSIpO1M9PT0xJiZvLmRlZmluZWRNdXRhYmxlR2xvYmFscy5wdXNoKHt2YWx0eXBlOngsaW5pdElzSTMyQ29uc3QwOlIsaW5pdElzSTMyQ29uc3Q6dyxkZWZpbmVkSW5kZXg6Z30pfX1lbHNlIGlmKF89PT03KXtsZXQgaDtbaCxkXT1CKHQsZCk7Zm9yKGxldCBnPTA7ZzxoO2crKyl7bGV0IHg7W3gsZF09Qih0LGQpLG8uZXhwb3J0TmFtZXMucHVzaChMdCh0LnN1YmFycmF5KGQsZCt4KSkpLGQrPXgsZCs9MSxbLGRdPUIodCxkKX19ZWxzZSBpZihfPT09MCl7bGV0IGg7W2gsZF09Qih0LGQpO2xldCBnPUx0KHQuc3ViYXJyYXkoZCxkK2gpKTtpZihkKz1oLGc9PT0ibmFtZSIpZm9yKDtkPGM7KXtsZXQgeD10W2QrK10sUztbUyxkXT1CKHQsZCk7bGV0IFI9ZCtTO2lmKHg9PT03KXtsZXQgdztbdyxkXT1CKHQsZCk7Zm9yKGxldCB5PTA7eTx3O3krKyl7bGV0IEQsZGU7W0QsZF09Qih0LGQpLFtkZSxkXT1CKHQsZCksbC5zZXQoRCxMdCh0LnN1YmFycmF5KGQsZCtkZSkpKSxkKz1kZX19ZD1SfX1kPWN9Zm9yKGxldCBfIG9mIG8uZGVmaW5lZE11dGFibGVHbG9iYWxzKV8ubmFtZT1sLmdldChzK18uZGVmaW5lZEluZGV4KTtyZXR1cm4gb31yKGF1LCJzY2FuTW9kdWxlU3VyZmFjZSIpO2Z1bmN0aW9uIGl1KGUsdCl7bGV0IG89aXIoZSkscz1hdShlKSxsPXIoaD0+dHlwZW9mIGgubmFtZT09InN0cmluZyImJihoLm5hbWUuc3RhcnRzV2l0aCgiR09ULmRhdGEuaW50ZXJuYWwuIil8fGgubmFtZS5zdGFydHNXaXRoKCJHT1QuZnVuYy5pbnRlcm5hbC4iKSkmJmgudmFsdHlwZT09PTEyNyYmaC5pbml0SXNJMzJDb25zdCwiaXNJbnRlcm5hbEdvdFNoYXBlIiksZD1yKGg9PmgubmFtZT09PSJfX2h3anNfYnVkZ2V0IiYmaC52YWx0eXBlPT09MTI3JiZoLmluaXRJc0kzMkNvbnN0MCYmby5mbGFncy5zYWZlcG9pbnRzPT09ITAsImlzQnVkZ2V0U2hhcGUiKSxfPXMuZGVmaW5lZE11dGFibGVHbG9iYWxzLmZpbHRlcihoPT4hbChoKSYmIWQoaCkpLG09cihoPT5oLnZhbHR5cGU9PT0xMjcmJmguaW5pdElzSTMyQ29uc3QwLCJpc1Rsc0Jhc2VTaGFwZSIpO2lmKF8ubGVuZ3RoPjF8fF8ubGVuZ3RoPT09MSYmIW0oX1swXSkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogcHJpdmF0ZSBtdXRhYmxlIGdsb2JhbCBzdGF0ZSBpbiBhIC5zbyBcdTIwMTQgbm90IGFuIGxsZCAtc2hhcmVkIGFydGlmYWN0IChmb3VuZCAke18ubGVuZ3RofSBkZWZpbmVkIG11dGFibGUgZ2xvYmFsKHMpIGJleW9uZCB0aGUgc2FuY3Rpb25lZCBsbGQgR09ULmRhdGEuaW50ZXJuYWwuKiBpbnRlcm5hbC1HT1Qgc2hhcGU7IGF0IG1vc3QgT05FIG90aGVyIGlzIGxlZ2FsIGFuZCBvbmx5IHRoZSBsbGQgX190bHNfYmFzZSBzaGFwZTogaTMyLCBpbml0IGkzMi5jb25zdCAwOyB1bm5hbWVkIG11dGFibGUgZ2xvYmFscyBzdGF5IHJlZnVzZWQgXHUyMDE0IHRoZSBuYW1lIHNlY3Rpb24gaXMgdGhlIHNhbmN0aW9uIGNhcnJpZXIpLiBSZWZ1c2luZyB0byBpbnN0YW50aWF0ZSAobmV2ZXItc2lsZW50KS5gKTtpZihzLmltcG9ydHNFbnZTdGFja1BvaW50ZXImJiEodC5zdGFja1BvaW50ZXIgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWwpKXRocm93IG5ldyBFcnJvcigiaHdqcy1kbG9wZW46IHRoZSAuc28gaW1wb3J0cyBlbnYuX19zdGFja19wb2ludGVyIChtdXRhYmxlIGkzMiBcdTIwMTQgdGhlIHNoYXJlZCBzaGFkb3ctc3RhY2sgcG9pbnRlcikgYnV0IG5vIG9wdHMuc3RhY2tQb2ludGVyIFdlYkFzc2VtYmx5Lkdsb2JhbCB3YXMgcHJvdmlkZWQuIFRoZSBsb2FkZXIgUkVGVVNFUyB0byBmYWJyaWNhdGUgYSBwcml2YXRlIHNwIGdsb2JhbCAoYSBzaGFkb3ctc3RhY2stdXNpbmcgLnNvIGRlc2NlbmRpbmcgb24gYSBwcml2YXRlIHNwPTAgY29ycnVwdHMgbGluZWFyIG1lbW9yeSk7IHBhc3MgdGhlIG1haW4gaW1hZ2UncyBleHBvcnRlZCBfX3N0YWNrX3BvaW50ZXIgc28gbWFpbiArIC5zbyBzaGFyZSBPTkUgc3AgKG5ldmVyLXNpbGVudCkuIik7aWYobyl7aWYoby5tYW5pZmVzdFZlcnNpb24hPT0xJiZvLm1hbmlmZXN0VmVyc2lvbiE9PTIpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogaHdqcy5hYmkgbWFuaWZlc3RfdmVyc2lvbiAke28ubWFuaWZlc3RWZXJzaW9ufSBpcyBub3QgYSBrbm93biB2ZXJzaW9uICh3YW50IDEgb3IgMikgXHUyMDE0IEFCSS1za2V3ZWQgLyBmb3JlaWduIC5zbywgcmVmdXNpbmcgdG8gaW5zdGFudGlhdGUgKG5ldmVyLXNpbGVudCkuYCk7bGV0IGg9MztpZih0Lm1haW5Ecml2ZUFiaSE9PXZvaWQgMCl7aWYodC5tYWluRHJpdmVBYmkhPT0zJiZ0Lm1haW5Ecml2ZUFiaSE9PTQpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3Blbjogb3B0cy5tYWluRHJpdmVBYmk9JHt0Lm1haW5Ecml2ZUFiaX0gaXMgbm90IGEgZGxvcGVuLWNhcGFibGUgZHJpdmUgYWJpICh3YW50IDMgZmxhdCBvciA0IHN0YXR1cy1jaGFubmVsKSBcdTIwMTQgcmVmdXNpbmcgdG8gZ3Vlc3MgKG5ldmVyLXNpbGVudCkuYCk7aD10Lm1haW5Ecml2ZUFiaX1sZXQgZz1bWyJkcml2ZV9hYmkiLG8uZHJpdmVBYmksaF0sWyJwYXJrZWRfYWJpIixvLnBhcmtlZEFiaSwyXSxbImRzX3JlZ2lvbl9hYmkiLG8uZHNSZWdpb25BYmksMl0sWyJzdXNwZW5kX2FiaV92ZXJzaW9uIixvLnN1c3BlbmRBYmlWZXJzaW9uLDFdLFsiY2FwcmVnX3ZlcnNpb24iLG8uY2FwcmVnVmVyc2lvbiwxXSxbImZwY2FzdF92ZXJzaW9uIixvLmZwY2FzdFZlcnNpb24sMV0sWyJmbGFncy5keW5hbWljX21vZHVsZSIsby5mbGFncy5keW5hbWljTW9kdWxlPzE6MCwxXV07Zm9yKGxldFtSLHcseV1vZiBnKWlmKHchPT15KXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IGh3anMuYWJpIG1hbmlmZXN0ICR7Un0gbWlzbWF0Y2g6IGdvdCAke3d9LCB3YW50ICR7eX0gXHUyMDE0IEFCSS1za2V3ZWQgLyBmb3JlaWduIC5zbywgcmVmdXNpbmcgdG8gaW5zdGFudGlhdGUgKG5ldmVyLXNpbGVudCkuYCk7aWYoby5mbGFncy5sYW5lQWRkcmVzc2VkPT09ITAmJm8ucHJlZW1wdGliaWxpdHkhPT0id2hvbGUtcHJvZ3JhbSIpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogaHdqcy5hYmkgbWFuaWZlc3QgcHJlZW1wdGliaWxpdHk9JHtvLnByZWVtcHRpYmlsaXR5fSBvbiBhIExBTkUtQUREUkVTU0VEIC5zbyAoZmxhZ3MgYml0NSkgXHUyMDE0IHdhbnQgd2hvbGUtcHJvZ3JhbS4gU2libGluZyBsYW5lcyBydW4gY29uY3VycmVudGx5IGluIG9uZSBwcm9jZXNzLCBzbyBhIGxhbmUgb2YgdGhpcyBtb2R1bGUgaW5zaWRlIGEgc3lzY2FsbC1mcmVlIHVuYm91bmRlZCBsb29wIHJlYWNoZXMgbm8gc2xpY2UgYm91bmRhcnk6IGZvcmsoKSB3b3VsZCByZXR1cm4gRUFHQUlOIG9uIHRoZSBhY3F1aXJlIGRlYWRsaW5lIGFuZCBubyBsYW5lJ3MgcGVuZGluZyBzaWduYWxzIHdvdWxkIGJlIGRpc3BhdGNoZWQuICR7by5wcmVlbXB0aWJpbGl0eT09PSJzY29wZWQiPyJzY29wZWQgbWVhbnMgU09NRSBjaGVja3BvaW50cyBleGlzdCBhbmQgaXMgbm90IGEgd2hvbGUtaW1hZ2Ugc3RhdGVtZW50LiI6IlRoaXMgbW9kdWxlIHdhcyBidWlsdCB3aXRoIGNoZWNrcG9pbnRzIGRpc2FybWVkLiJ9IFJlZnVzaW5nIHRvIGluc3RhbnRpYXRlIChuZXZlci1zaWxlbnQpLmApO2xldCB4PXQubWFpbkxhbmVBZGRyZXNzZWQ9PT0hMCxTPW8uZmxhZ3MubGFuZUFkZHJlc3NlZD09PSEwO2lmKFMhPT14KXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IExBTkUtQUREUkVTU0VEIE1JU01BVENIIFx1MjAxNCB0aGlzIC5zbyBhdHRlc3RzIGh3anMuYWJpIGZsYWdzIGJpdDUgbGFuZV9hZGRyZXNzZWQ9JHtTPzE6MH0gYnV0IHRoZSBwcm9jZXNzIChtYWluKSBhdHRlc3RzIGxhbmVfYWRkcmVzc2VkPSR7eD8xOjB9LiBNaXhpbmcgYSBsYW5lLWFkZHJlc3NlZCBtb2R1bGUgd2l0aCBhIGxhbmUtdW5hd2FyZSBvbmUgbGV0cyB0aGUgbGFuZS11bmF3YXJlIHNpZGUgcmVhZCBMQU5FIDAncyBzdGF0dXMgd29yZCBmcm9tIEFOWSBsYW5lIFx1MjAxNCBzaWxlbnQgdHJhbnNpdCB1bmRlciB0aHJlYWRzIChJMy0yOyBQTEFOLVRIUkVBRFMtU0lOR0xFLU1FTU9SWSBceEE3NCBzdGVwIDIpLiBSZWJ1aWxkIHRoZSBwYWlyIGluIGxvY2tzdGVwIChib3RoIEhXSlNfUlRfTEFORVM+MSBvciBuZWl0aGVyKTsgcmVmdXNpbmcgdG8gaW5zdGFudGlhdGUgKG5ldmVyLXNpbGVudCkuYCk7aWYoKG8uZmxhZ3MudXNlc1Rscz8xOjApPT0xJiZ0LnRsc093bmVyIT09ITApe2lmKCEodC5zaWRlVGxzJiZ0eXBlb2YgdC5zaWRlVGxzPT0ib2JqZWN0IikpdGhyb3cgbmV3IEVycm9yKCJod2pzLWRsb3BlbjogaHdqcy5hYmkgbWFuaWZlc3QgZmxhZ3MudXNlc190bHM9MSBvbiBhIGxvYWQgdGhhdCBiaW5kcyBubyBUTFMgZm9yIGl0IFx1MjAxNCBuZWl0aGVyIHRoZSBsaWJjLnNvIHRocmVhZC1wb2ludGVyIG93bmVyIChvcHRzLnRsc093bmVyKSBub3IgYSBzaWRlLW1vZHVsZSBsb2FkIChvcHRzLnNpZGVUbHMpLiBJdHMgcHJpdmF0ZSBfX3Rsc19iYXNlIHdvdWxkIGJlIHVuYm91bmQgb24gZXZlcnkgSW5zdGFuY2UgYWZ0ZXIgdGhlIGZpcnN0LiBSZWZ1c2luZyB0byBpbnN0YW50aWF0ZSAobmV2ZXItc2lsZW50KS4iKTtsZXQgUj1sdS5maWx0ZXIodz0+IXMuZXhwb3J0TmFtZXMuaW5jbHVkZXModykpO2lmKFIubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IHNpZGUgbW9kdWxlIG93bnMgVExTIChod2pzLmFiaSB1c2VzX3Rscz0xKSBidXQgZG9lcyBub3QgZXhwb3J0ICR7Ui5qb2luKCIsICIpfSBcdTIwMTQgdGhlIGxvYWRlciBjYW5ub3QgYmluZCBpdHMgcGVyLXRocmVhZCBibG9jayB3aXRob3V0IHRoZW0uIFJlbGluayBpdCB3aXRoIGEgYnJpbnRsZCB0aGF0IGVtaXRzIHRoZSBzaWRlLW1vZHVsZSBUTFMgc3VyZmFjZSAoYnJpbnRvcy9od2pzLWNjIzEwNikuIFJlZnVzaW5nIHRvIGluc3RhbnRpYXRlIChuZXZlci1zaWxlbnQpLmApfXJldHVybiBvfXRocm93IHMuaW1wb3J0c0h3anNTdXNwZW5kUGFya3x8cy5pbXBvcnRlZEVudkZ1bmNOYW1lcy5zb21lKGg9Pmguc3RhcnRzV2l0aCgiX19od2pzXyIpfHxoLnN0YXJ0c1dpdGgoImh3anNfIikpfHxzLmV4cG9ydE5hbWVzLmluY2x1ZGVzKCJfX2h3anNfZHJpdmVfYWJpIik/bmV3IEVycm9yKCJod2pzLWRsb3Blbjogc3VzcGVuZC1jYXBhYmxlIC5zbyB3aXRob3V0IGh3anMuYWJpIG1hbmlmZXN0IFx1MjAxNCB0aGUgbW9kdWxlIGltcG9ydHMvZXhwb3J0cyBod2pzIHN1c3BlbmQtQUJJIHN1cmZhY2UgYnV0IGNhcnJpZXMgbm8gaHdqcy5hYmkgYXR0ZXN0YXRpb24gKGEgcHJlLW1hbmlmZXN0IG9yIG5lc3RlZC1idWlsdCBhcnRpZmFjdCkuIFJlYnVpbGQgaXQgd2l0aCB0aGUgbWFuaWZlc3QtZW1pdHRpbmcgbGlua2VyLCBicmludGxkIChuZXZlci1zaWxlbnQgcmVmdXNlKS4iKTpuZXcgRXJyb3IoImh3anMtZGxvcGVuOiAuc28gaGFzIG5vIGh3anMuYWJpIG1hbmlmZXN0IFx1MjAxNCBldmVyeSBkbG9wZW4tYWJsZSBtb2R1bGUgbXVzdCBhdHRlc3QgaXRzIEFCSSBsaW5lYWdlICh0aGUgU1RFUC0yIG1hbmlmZXN0LWxlc3MgUFVSRSBncmFuZGZhdGhlciBpcyByZXRpcmVkKS4gUmVidWlsZCBpdCB3aXRoIHRoZSBtYW5pZmVzdC1lbWl0dGluZyBsaW5rZXIsIGJyaW50bGQgKG5ldmVyLXNpbGVudCByZWZ1c2UpLiIpfXIoaXUsImNoZWNrTG9hZFBvbGljeSIpO2Z1bmN0aW9uIEZsKGUpe2xldCB0PWUgaW5zdGFuY2VvZiBFcnJvcj9lLm1lc3NhZ2U6U3RyaW5nKGUpLG89cigocyxsLGQpPT4oe2Vycm5vOnMsZXJybm9OYW1lOmwsY2xzOmQsbWVzc2FnZTp0fSksIm1rIik7cmV0dXJuIHR5cGVvZiBSYW5nZUVycm9yPT0iZnVuY3Rpb24iJiZlIGluc3RhbmNlb2YgUmFuZ2VFcnJvcnx8L25ldmVyLXNpbGVudCBPT018b3V0IG9mIG1lbW9yeXxDYW5ub3QgYWxsb2NhdGUgbWVtb3J5fGZhaWxlZCB0byBncm93IHRoZSBzaGFyZWQgdGFibGV8Y291bGQgbm90IGdyb3cgdGhlIHNoYXJlZCB0YWJsZS9pLnRlc3QodCk/bygtMTIsIkVOT01FTSIsImFsbG9jIik6ZSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5LkNvbXBpbGVFcnJvcnx8L25vdCBhIHdhc20gbW9kdWxlIFwoYmFkIG1hZ2ljXCkvLnRlc3QodCk/bygtOCwiRU5PRVhFQyIsImNvbXBpbGUiKTplIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuTGlua0Vycm9yP28oLTgwLCJFTElCQkFEIiwibGluayIpOnQuc3RhcnRzV2l0aCgiaHdqcy1kbG9wZW46Iik/bygtODAsIkVMSUJCQUQiLCJwb2xpY3kiKTpvKC0yMiwiRUlOVkFMIiwidW5rbm93biIpfXIoRmwsImNsYXNzaWZ5RGxvcGVuRmFpbHVyZSIpO3ZhciBsdT1PYmplY3QuZnJlZXplKFsiX190bHNfYmFzZSIsIl9fdGxzX3NpemUiLCJfX3Rsc19hbGlnbiIsIl9fd2FzbV9pbml0X3RscyJdKSxuYT0yNTYsZHU9bmEsd2w9NjQqMTAyNCoxMDI0O2Z1bmN0aW9uIFlvKGUpe2xldCB0PWUuX190bHNfc2l6ZS52YWx1ZT4+PjAsbz1NYXRoLm1heChlLl9fdGxzX2FsaWduLnZhbHVlPj4+MCwxNik7cmV0dXJue3NpemU6dCxhbGlnbjpvLHN0cmlkZTpNYXRoLmNlaWwoTWF0aC5tYXgodCwxKS9vKSpvfX1yKFlvLCJzaWRlVGxzTGF5b3V0Iik7dmFyIHNhPXIoKCk9Pm5hKzEsInNpZGVUbHNTbG90Q291bnQiKSxnbD1yKChlLHQpPT4oZT4+PjApK3NhKCkqdD4+PjAsInNpZGVUbHNIZWFkZXJBZGRyIik7ZnVuY3Rpb24gcmEoZSx0KXtsZXQgbz1zYSgpKmUuc3RyaWRlKzQ7aWYoZS5hbGlnbj40MDk2KXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IHNpZGUgbW9kdWxlJHt0P2AgIiR7dH0iYDoiIn0gYXNrcyBmb3IgJHtlLmFsaWdufS1ieXRlIFRMUyBhbGlnbm1lbnQ7IHRoZSBzbG90IGFycmF5IGlzIHBhZ2UtYWxpZ25lZCAobmV2ZXItc2lsZW50KS5gKTtpZighKG8+MCl8fG8+d2wpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3Blbjogc2lkZSBtb2R1bGUke3Q/YCAiJHt0fSJgOiIifSBvd25zIGEgJHtlLnNpemV9QiBUTFMgaW1hZ2U7IGl0cyBwZXItdGhyZWFkIHNsb3QgYXJyYXkgd291bGQgbmVlZCAke299Qiwgb3ZlciB0aGUgJHt3bH1CIGNhcCAobmV2ZXItc2lsZW50KS5gKTtyZXR1cm4gb31yKHJhLCJzaWRlVGxzU2xvdEFycmF5Qnl0ZXMiKTt2YXIgeWw9MjU3LFByPTEqMTAyNCoxMDI0LGN1PVByPj4+MTtmdW5jdGlvbiBIbChlLHQsbyxzKXtsZXQgbD1NYXRoLm1heChvPj4+MCwxNiksZD1NYXRoLmNlaWwoKHQ+Pj4wKS9sKSpsK2wsXz1NYXRoLmZsb29yKCgoZT4+PjApK1ByKS9sKSpsLG09KGU+Pj4wKStjdSxjPU1hdGgubWF4KDAsTWF0aC5taW4oTWF0aC5mbG9vcigoXy1tKS9kKSx5bCkpLGg9cz4+PjA8eWw/cz4+PjA6MDtyZXR1cm57YWRkcjooaDxjP18tKGgrMSkqZDowKT4+PjAsc3RyaWRlOmQsYWxpZ246bCxsYW5lczpjfX1yKEhsLCJtYWluVGxzU2xvdCIpO2Z1bmN0aW9uIG9hKGUsdCxvKXtsZXQgcz10LnRsc1Nsb3RzPj4+MDtyZXR1cm4gZT09PSJ0aHJlYWQiP3R5cGVvZiBvPT0ibnVtYmVyIiYmbz49MD97bW9kZToibWF0ZXJpYWxpc2UiLHNsb3RzQmFzZTpzLHNsb3Q6b306e21vZGU6InVuYm91bmQtdGhyZWFkIn06ZT09PSJmb3JrLXJlc3VtZSI/e21vZGU6ImZvcmsiLGJhc2U6dC50bHNCYXNlPj4+MCxzbG90c0Jhc2U6c306e21vZGU6InJlYmluZCIsYmFzZTp0LnRsc0Jhc2U+Pj4wfX1yKG9hLCJzaWRlVGxzUmVwbGF5TW9kZSIpO2Z1bmN0aW9uIGFhKGUsdCl7cmV0dXJue3Rsc0Jhc2U6ZSYmZS50bHM/ZS50bHMuYmFzZSgpOjAsdGxzU2xvdHM6dD4+PjB9fXIoYWEsInNpZGVUbHNSZWNvcmRGaWVsZHMiKTtmdW5jdGlvbiB1dShlLHQsbyxzKXtsZXQgbD1lLl9fdGxzX2Jhc2UsZD1zP2AgIiR7c30iYDoiIixfPXIoKGgsZyk9PntpZighKGg+Pj4wKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBzaWRlIG1vZHVsZSR7ZH0gb3ducyBUTFMgYnV0ICR7Z30gXHUyMDE0IGJpbmRpbmcgMCB3b3VsZCBwdXQgaXRzIHRocmVhZF9sb2NhbCBzdGF0ZSBhdCBhZGRyZXNzIDAgKG5ldmVyLXNpbGVudCkuYCl9LCJyZXF1aXJlQmFzZSIpLG09cihoPT57aWYoZS5fX3dhc21faW5pdF90bHMoaHwwKSxsLnZhbHVlPj4+MCE9PWg+Pj4wKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IHNpZGUgbW9kdWxlJHtkfSBfX3dhc21faW5pdF90bHMoJHtoPj4+MH0pIGxlZnQgX190bHNfYmFzZSBhdCAke2wudmFsdWU+Pj4wfSAobmV2ZXItc2lsZW50KS5gKTtyZXR1cm4gaD4+PjB9LCJpbml0SW50byIpLGM9cigoKT0+bmV3IERhdGFWaWV3KHQuYnVmZmVyKSwiZHYiKTtzd2l0Y2goby5tb2RlKXtjYXNlImZyZXNoIjp7bGV0IGg9bC52YWx1ZT4+PjA7cmV0dXJuIF8oaCwiaXRzIGZpcnN0IEluc3RhbmNlIGxlZnQgX190bHNfYmFzZSBhdCAwIChsbGQncyBzdGFydCBmdW5jdGlvbiBkaWQgbm90IGJpbmQgdGhlIGxvYWRpbmcgdGhyZWFkJ3MgYmxvY2spIiksbShoKX1jYXNlInJlYmluZCI6cmV0dXJuIF8oby5iYXNlLCJ0aGUgcmVwbGF5IHJlY29yZCBjYXJyaWVzIG5vIGxpdmUgX190bHNfYmFzZSBmb3IgaXQiKSxsLnZhbHVlPW8uYmFzZXwwLG8uYmFzZT4+PjA7Y2FzZSJmb3JrIjp7XyhvLmJhc2UsInRoZSBmb3JrIHJlY29yZCBjYXJyaWVzIG5vIGxpdmUgX190bHNfYmFzZSBmb3IgaXQiKSxsLnZhbHVlPW8uYmFzZXwwO2xldCBoPW8uc2xvdHNCYXNlPj4+MDtpZihoPjApe2xldHtzdHJpZGU6Z309WW8oZSkseD0oby5iYXNlPj4+MCktaCxTPXg+PTAmJng8c2EoKSpnO2MoKS5zZXRVaW50MzIoZ2woaCxnKSxTP01hdGguZmxvb3IoeC9nKSsxOjAsITApfXJldHVybiBvLmJhc2U+Pj4wfWNhc2UibWF0ZXJpYWxpc2UiOntsZXQgaD1vLnNsb3QsZz1vLnNsb3RzQmFzZT4+PjA7aWYodHlwZW9mIGghPSJudW1iZXIifHxoPDB8fGg+PW5hfHxnPT09MCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBzaWRlIG1vZHVsZSR7ZH0gb3ducyBUTFMgYnV0IHRoaXMgdGhyZWFkIGhhcyBubyBUTFMgc2xvdCAoc2xvdD0ke2h9LCBzbG90c0Jhc2U9JHtvLnNsb3RzQmFzZX0pIFx1MjAxNCBpdHMgdGhyZWFkX2xvY2FsIHN0YXRlIGhhcyBub3doZXJlIHRvIGxpdmUgKG5ldmVyLXNpbGVudCkuYCk7bGV0e3N0cmlkZTp4fT1ZbyhlKSxTPWMoKS5nZXRVaW50MzIoZ2woZyx4KSwhMCksUj1TIT09MCYmUy0xPT09aD9kdTpoO3JldHVybiBtKGcrUip4Pj4+MCl9Y2FzZSJ1bmJvdW5kLXRocmVhZCI6cmV0dXJuIDA7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiB1bmtub3duIHNpZGUtbW9kdWxlIFRMUyBiaW5kIG1vZGUgJHtKU09OLnN0cmluZ2lmeShvLm1vZGUpfSAobmV2ZXItc2lsZW50KWApfX1yKHV1LCJiaW5kU2lkZU1vZHVsZVRscyIpO2Z1bmN0aW9uIGZ1KGUsdCl7Zm9yKGxldCBvPTA7bzxlLmxlbmd0aDtvKyspaWYoZS5nZXQobyk9PT10KXJldHVybiBvO3JldHVybi0xfXIoZnUsInRhYmxlSW5kZXhPZiIpO2Z1bmN0aW9uIFVsKGUsdCl7cmV0dXJuIHQ8PTE/ZTplKyh0LTEpJn4odC0xKX1yKFVsLCJhbGlnblVwIik7ZnVuY3Rpb24gX3UoZSx0LG8scyxsKXtsZXQgZD1PYmplY3QuY3JlYXRlKG51bGwpLF89cigoeixRLFUpPT57KGRbel0/Pz1PYmplY3QuY3JlYXRlKG51bGwpKVtRXT1VfSwicHV0IiksbT1uZXcgTWFwLGM9bmV3IE1hcCxoPW51bGwsZz1yKCgpPT5oPz89bmV3IFdlYkFzc2VtYmx5Lkdsb2JhbCh7dmFsdWU6ImkzMiIsbXV0YWJsZTohMH0sMCksImVuc3VyZUJ1ZGdldEdsb2JhbCIpLHg9bmV3IFdlYkFzc2VtYmx5Lkdsb2JhbCh7dmFsdWU6ImkzMiIsbXV0YWJsZTohMX0sb3wwKSxTPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITF9LHN8MCksUj17ZXhwb3J0czpudWxsfSx3PVtdLHk9bnVsbCxEPXIoej0+KHk/Pz1uZXcgU2V0KFdlYkFzc2VtYmx5Lk1vZHVsZS5leHBvcnRzKGUpLmZpbHRlcihRPT5RLmtpbmQ9PT0iZnVuY3Rpb24iKS5tYXAoUT0+US5uYW1lKSkpLmhhcyh6KSwib3duRGVmaW5lcyIpLGRlPVtdO2ZvcihsZXQgeiBvZiBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhlKSl7bGV0e21vZHVsZTpRLG5hbWU6VSxraW5kOmZlfT16O2lmKGZlPT09Im1lbW9yeSIpe18oUSxVLHQubWVtb3J5KTtjb250aW51ZX1pZihmZT09PSJ0YWJsZSIpe18oUSxVLHQudGFibGUpO2NvbnRpbnVlfWlmKGZlPT09Imdsb2JhbCImJlU9PT0iX19tZW1vcnlfYmFzZSIpe18oUSxVLHgpO2NvbnRpbnVlfWlmKGZlPT09Imdsb2JhbCImJlU9PT0iX190YWJsZV9iYXNlIil7XyhRLFUsUyk7Y29udGludWV9aWYoZmU9PT0iZ2xvYmFsIiYmVT09PSJfX3N0YWNrX3BvaW50ZXIiJiZ0LnN0YWNrUG9pbnRlciBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbCl7XyhRLFUsdC5zdGFja1BvaW50ZXIpO2NvbnRpbnVlfWlmKGZlPT09Imdsb2JhbCImJlE9PT0iZW52IiYmVT09PSJfX2h3anNfc3RhdHVzX2NoYW5uZWxfYWRkciIpe2xldCBYPXQuc3RhdHVzQ2hhbm5lbEFkZHI7aWYodHlwZW9mIFghPSJudW1iZXIifHwhTnVtYmVyLmlzSW50ZWdlcihYKXx8WDw9MCl0aHJvdyBuZXcgRXJyb3IoImh3anMtZGxvcGVuOiB0aGUgLnNvIGltcG9ydHMgZW52Ll9faHdqc19zdGF0dXNfY2hhbm5lbF9hZGRyIChsYW5lLWFkZHJlc3NlZCBtb2R1bGUpIGJ1dCB0aGUgY2FsbGVyIHN1cHBsaWVkIG5vIG9wdHMuc3RhdHVzQ2hhbm5lbEFkZHIgXHUyMDE0IHJlZnVzaW5nIHRvIGZhYnJpY2F0ZSBhIGNoYW5uZWwgYmFzZSAoYWRkcmVzcyAwIHdvdWxkIHNpbGVudGx5IHJlYWQgd3JvbmcgbWVtb3J5IGFzIHRoZSBzdGF0dXMgd29yZDsgbmV2ZXItc2lsZW50OyBQTEFOLVRIUkVBRFMtU0lOR0xFLU1FTU9SWSBceEE3NCBzdGVwIDIpLiIpO18oUSxVLG5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITB9LFh8MCkpO2NvbnRpbnVlfWlmKGZlPT09Imdsb2JhbCImJlE9PT0iZW52IiYmVT09PSJfX2h3anNfYnVkZ2V0Iil7XyhRLFUsZygpKTtjb250aW51ZX1pZihmZT09PSJmdW5jdGlvbiImJlE9PT0iZW52IiYmKFU9PT0iX19od2pzX2J1ZGdldF9zZXQifHxVPT09Il9faHdqc19idWRnZXRfZ2V0Iikpe2xldCBYPWcoKTtfKFEsVSxVPT09Il9faHdqc19idWRnZXRfc2V0Ij9rZT0+e1gudmFsdWU9a2V8MH06KCk9PlgudmFsdWV8MCk7Y29udGludWV9aWYoZmU9PT0iZ2xvYmFsIiYmUT09PSJHT1QuZnVuYyIpe2xldCBYPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITB9LDApO20uc2V0KFUsWCksXyhRLFUsWCk7Y29udGludWV9aWYoZmU9PT0iZ2xvYmFsIiYmUT09PSJHT1QubWVtIil7bGV0IFg9bmV3IFdlYkFzc2VtYmx5Lkdsb2JhbCh7dmFsdWU6ImkzMiIsbXV0YWJsZTohMH0sMCk7Yy5zZXQoVSxYKSxfKFEsVSxYKTtjb250aW51ZX1pZihRPT09Imh3anNfc3VzcGVuZCImJlU9PT0icGFyayIpe18oUSxVLHQucGFya0ltcG9ydD8/KCgpPT57fSkpO2NvbnRpbnVlfWxldCByZT10LnJlc29sdmVJbXBvcnQ/dC5yZXNvbHZlSW1wb3J0KFEsVSxmZSk6dm9pZCAwO2lmKHJlPT1udWxsJiZ0LmJpbmRPd25EZWZpbml0aW9ucyYmUT09PSJlbnYiJiZmZT09PSJmdW5jdGlvbiImJkQoVSkpe18oUSxVLGh1KFUsUix0LnNvUGF0aCkpLHcucHVzaChVKTtjb250aW51ZX1pZihyZT09bnVsbCYmZmU9PT0iZnVuY3Rpb24iJiZsJiZsLmdldChVKT09PVEpe18oUSxVLG11KFEsVSx0LnNvUGF0aCkpLGRlLnB1c2goVSk7Y29udGludWV9aWYocmU9PW51bGwpe2xldCBYPXQuc29QYXRoP2AiJHt0LnNvUGF0aH0iYDoidGhlIHNoYXJlZCBvYmplY3QiLGtlPSIiO3RyeXtrZT1XZWJBc3NlbWJseS5Nb2R1bGUuZXhwb3J0cyhlKS5zb21lKG9lPT5vZS5uYW1lPT09VSYmb2Uua2luZD09PWZlKT9gIE5PVEU6ICR7WH0gSVRTRUxGIGV4cG9ydHMgJHtVfSAoJHtmZX0pIFx1MjAxNCB0aGlzIGlzIGEgUFJFRU1QVElCTEUgc3ltYm9sIChhIC1zaGFyZWQgbW9kdWxlIHJvdXRlcyBpdHMgb3duIHdlYWsvZGVmYXVsdC12aXNpYmlsaXR5IGRlZmluaXRpb25zIHRocm91Z2ggZW52IHNvIHRoZSBsb2FkZXIgbWF5IGludGVycG9zZSBvbmUpLCBhbmQgbm90aGluZyBpbiB0aGlzIHByb2Nlc3MgcHJvdmlkZXMgaXQuYDoiIn1jYXRjaHt9dGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogdW5yZXNvbHZlZCBpbXBvcnQgJHtRfS4ke1V9ICgke2ZlfSkgaW4gJHtYfSBcdTIwMTQgdGhlIGxvYWRlciBoYXMgbm8gYmluZGluZyBhbmQgcmVzb2x2ZUltcG9ydCByZXR1cm5lZCBub3RoaW5nIChuZXZlci1zaWxlbnQ7IGEgbWlzLXdpcmVkIGR5bmFtaWMgbW9kdWxlIG11c3QgZmFpbCBsb3VkbHksIG5vdCBydW4gd2l0aCBhIGhvbGUpLiR7a2V9YCl9XyhRLFUscmUpfXJldHVybntpbXBvcnRzOmQsZ290RnVuYzptLGdvdE1lbTpjLGJ1ZGdldEdsb2JhbDpoLHNlbGZCb3g6Uixvd25Cb3VuZDp3LHdlYWtVbmJvdW5kOmRlfX1yKF91LCJ3aXJlSW1wb3J0cyIpO2Z1bmN0aW9uIGh1KGUsdCxvKXtsZXQgcz1udWxsLGw9cigoKT0+e2xldCBkPXQuZXhwb3J0cz90LmV4cG9ydHNbZV06dm9pZCAwO2lmKHR5cGVvZiBkIT0iZnVuY3Rpb24iKXtsZXQgXz1vP2AiJHtvfSJgOiJ0aGUgc2hhcmVkIG9iamVjdCI7dGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogZW52LiR7ZX0gaW4gJHtffSBpcyBib3VuZCB0byB0aGUgbW9kdWxlJ3Mgb3duIGRlZmluaXRpb24sIGJ1dCAke3QuZXhwb3J0cz9gdGhlIGluc3RhbmNlIGV4cG9ydHMgbm8gZnVuY3Rpb24gIiR7ZX0iYDoiaXQgd2FzIGNhbGxlZCBiZWZvcmUgdGhlIG1vZHVsZSB3YXMgaW5zdGFudGlhdGVkIChmcm9tIGl0cyBzdGFydCBzZWN0aW9uKSJ9IChuZXZlci1zaWxlbnQpLmApfXJldHVybiBkfSwicHJvdmlkZXIiKTtyZXR1cm4gZnVuY3Rpb24oZCxfLG0sYyxoLGcseCl7bGV0IFM9c3x8KHM9bCgpKTtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAwOnJldHVybiBTKCk7Y2FzZSAxOnJldHVybiBTKGQpO2Nhc2UgMjpyZXR1cm4gUyhkLF8pO2Nhc2UgMzpyZXR1cm4gUyhkLF8sbSk7Y2FzZSA0OnJldHVybiBTKGQsXyxtLGMpO2Nhc2UgNTpyZXR1cm4gUyhkLF8sbSxjLGgpO2Nhc2UgNjpyZXR1cm4gUyhkLF8sbSxjLGgsZyk7Y2FzZSA3OnJldHVybiBTKGQsXyxtLGMsaCxnLHgpO2RlZmF1bHQ6cmV0dXJuIFMuYXBwbHkobnVsbCxhcmd1bWVudHMpfX19cihodSwib3duRGVmaW5pdGlvblRyYW1wb2xpbmUiKTtmdW5jdGlvbiBtdShlLHQsbyl7bGV0IHM9bz9gIiR7b30iYDoidGhlIHNoYXJlZCBvYmplY3QiO3JldHVybigpPT57dGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogY2FsbCB0byAke2V9LiR7dH0gaW4gJHtzfSwgYSBXRUFLIHVuZGVmaW5lZCBmdW5jdGlvbiB0aGF0IG5vIGxvYWRlZCBtb2R1bGUgZGVmaW5lcywgc28gaXRzIGFkZHJlc3MgaXMgbnVsbCAobmV2ZXItc2lsZW50OyBFTEYgd291bGQgZmF1bHQgb24gdGhlIHNhbWUgY2FsbCkuYCl9fXIobXUsIndlYWtVbmRlZmluZWRDYWxsIik7ZnVuY3Rpb24gQ3MoZSl7bGV0e3dhc21CeXRlczp0LG1lbW9yeTpvLHRhYmxlOnN9PWUsbD1pdSh0LGUpLGQ9THModCksXz1kP2QubWVtb3J5U2l6ZTowLG09ZD9kLm1lbW9yeUFsaWduOjEsYz1kP2QudGFibGVTaXplOjAsaD10eXBlb2YgZS5maXhlZE1lbW9yeUJhc2U9PSJudW1iZXIiP2UuZml4ZWRNZW1vcnlCYXNlPj4+MDpfPjA/ZS5hbGxvY01lbW9yeShVbChfLG0pLG0pOjA7aWYoXz4wJiYhKGg+MCkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogYWxsb2NNZW1vcnkgcmV0dXJuZWQgJHtofSBmb3IgYSAke199QiAuc28gZGF0YSByZWdpb24gKG5ldmVyLXNpbGVudCBPT00gLyBiYWQgYnVtcClgKTtsZXQgZz10eXBlb2YgZS5maXhlZFRhYmxlQmFzZT09Im51bWJlciIseD1nP2UuZml4ZWRUYWJsZUJhc2U+Pj4wOnMubGVuZ3RoO2lmKGcpe2lmKHgrYz5zLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBmaXhlZFRhYmxlQmFzZSBwbGFjZW1lbnQgWyR7eH0sICR7eCtjfSkgZXhjZWVkcyB0aGUgc2hhcmVkIHRhYmxlIGxlbmd0aCAke3MubGVuZ3RofSBcdTIwMTQgdGhlIHJlcGxheSBwYXlsb2FkIHBsYWNlcyBhIG1vZHVsZSBwYXN0IHRoZSBwYXJlbnQncyBkZWNsYXJlZCB0YWJsZSBleHRlbnQgKGNvcnJ1cHQgcGxhY2VtZW50OyBuZXZlci1zaWxlbnQpYCk7Zm9yKGxldCBMPXg7TDx4K2M7TCsrKWlmKHMuZ2V0KEwpIT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBmaXhlZFRhYmxlQmFzZSBwbGFjZW1lbnQgWyR7eH0sICR7eCtjfSkgY29sbGlkZXMgd2l0aCBhbiBvY2N1cGllZCBzbG90ICR7TH0gXHUyMDE0IHR3byBtb2R1bGVzJyByZWNvcmRlZCB3aW5kb3dzIG92ZXJsYXAgKGNvcnJ1cHQgcGxhY2VtZW50OyBuZXZlci1zaWxlbnQsIHRoZSBlbGVtIHdyaXRlIHdvdWxkIGNsb2JiZXIgYW5vdGhlciBtb2R1bGUncyBpZGVudGl0aWVzKWApfWVsc2UgaWYoYz4wKXRyeXtzLmdyb3coYyl9Y2F0Y2goTCl7dGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogZmFpbGVkIHRvIGdyb3cgdGhlIHNoYXJlZCB0YWJsZSBieSAke2N9IHNsb3RzIGZvciB0aGUgLnNvICh0YWJsZSBtYXggcmVhY2hlZD8pOiBgKyhMIGluc3RhbmNlb2YgRXJyb3I/TC5tZXNzYWdlOlN0cmluZyhMKSkpfWxldCBTPXR5cGVvZiBlLmNvbXBpbGVNb2R1bGU9PSJmdW5jdGlvbiI/ZS5jb21waWxlTW9kdWxlKHQpOm5ldyBXZWJBc3NlbWJseS5Nb2R1bGUoR2ModCkpO2lmKCEoUyBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lk1vZHVsZSkpdGhyb3cgbmV3IEVycm9yKCJod2pzLWRsb3Blbjogb3B0cy5jb21waWxlTW9kdWxlIHJldHVybmVkIGEgbm9uLU1vZHVsZSBcdTIwMTQgdGhlIGNhbGxlciBtdXN0IGhhbmQgYmFjayBhIFdlYkFzc2VtYmx5Lk1vZHVsZSBjb21waWxlZCBmcm9tIGV4YWN0bHkgdGhlIGxvYWQgYnl0ZXMgKG5ldmVyLXNpbGVudCkiKTtsZXQgUj1kP2Qud2Vha0ltcG9ydHM6bnVsbCx7aW1wb3J0czp3LGdvdEZ1bmM6eSxnb3RNZW06RCxidWRnZXRHbG9iYWw6ZGUsc2VsZkJveDp6LG93bkJvdW5kOlEsd2Vha1VuYm91bmQ6VX09X3UoUyxlLGgseCxSKSxmZT1uZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UoUyx3KSxyZT1mZS5leHBvcnRzO2lmKHouZXhwb3J0cz1yZSxsJiZ0eXBlb2YgcmUuX19od2pzX2RyaXZlX2FiaT09ImZ1bmN0aW9uIil7bGV0IEw9cmUuX19od2pzX2RyaXZlX2FiaSgpfDA7aWYoTCE9PWwuZHJpdmVBYmkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogbHlpbmcgaHdqcy5hYmkgbWFuaWZlc3QgXHUyMDE0IG1hbmlmZXN0IGRyaXZlX2FiaT0ke2wuZHJpdmVBYml9IGJ1dCBleHBvcnRzLl9faHdqc19kcml2ZV9hYmkoKSByZXR1cm5lZCAke0x9IChhIG1hbmlmZXN0IHRoYXQgY29udHJhZGljdHMgdGhlIGxpdmUgcHJvYmUgaXMgYSBidWlsZCBlcnJvcjsgbmV2ZXItc2lsZW50IHJlZnVzZSkuYCl9bGV0IFg9ITEsa2U9ITEsb2U9bmV3IE1hcDtpZihlLnNlZWRTeW1ib2xJbmRpY2VzKWZvcihsZXRbTCxJXW9mIGUuc2VlZFN5bWJvbEluZGljZXMpe2xldCBPPUk+Pj4wLHRlPXJlW0xdO2lmKHR5cGVvZiB0ZSE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBzZWVkU3ltYm9sSW5kaWNlc1siJHtMfSJdID0gJHtPfSBidXQgdGhlIHJlcGxheWVkIG1vZHVsZSBleHBvcnRzIG5vIHN1Y2ggZnVuY3Rpb24gXHUyMDE0IHRoZSBwYXJlbnQgcmVjb3JkZWQgYW4gYXBwZW5kZWQgc2xvdCB0aGlzIGFydGlmYWN0IGNhbm5vdCBiYWNrIChuZXZlci1zaWxlbnQpYCk7aWYoIShPPjApfHxPPj1zLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBzZWVkU3ltYm9sSW5kaWNlc1siJHtMfSJdID0gJHtPfSBpcyBvdXRzaWRlIHRoZSBzaGFyZWQgdGFibGUgKGxlbmd0aCAke3MubGVuZ3RofSkgXHUyMDE0IGNvcnJ1cHQgcGxhY2VtZW50IHBheWxvYWQgKG5ldmVyLXNpbGVudClgKTtsZXQgcT1zLmdldChPKTtpZihxIT09bnVsbCYmcSE9PXRlKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IHNlZWRTeW1ib2xJbmRpY2VzWyIke0x9Il0gPSAke099IGNvbGxpZGVzIHdpdGggYW4gb2NjdXBpZWQgc2xvdCBob2xkaW5nIGEgRElGRkVSRU5UIGZ1bmN0aW9uIFx1MjAxNCB0d28gcmVjb3JkZWQgYXBwZW5kcyBvdmVybGFwIChuZXZlci1zaWxlbnQpYCk7cy5zZXQoTyx0ZSksb2Uuc2V0KEwsTyl9bGV0IEZlPW51bGw7ZnVuY3Rpb24gaihMKXtpZihGZT09PW51bGwpe0ZlPW5ldyBNYXA7Zm9yKGxldCBPPXMubGVuZ3RoLTE7Tz49MTtPLS0pe2xldCB0ZT1zLmdldChPKTt0ZSE9PW51bGwmJkZlLnNldCh0ZSxPKX19bGV0IEk9RmUuZ2V0KEwpO3JldHVybiBJPT09dm9pZCAwPy0xOkl9cihqLCJyZXNpZGVudEluZGV4T2YiKTtmdW5jdGlvbiBydChMKXtsZXQgST1vZS5nZXQoTCk7aWYoSSE9PXZvaWQgMClyZXR1cm4gSTtsZXQgTz1yZVtMXTtpZih0eXBlb2YgTyE9ImZ1bmN0aW9uIilyZXR1cm4gb2Uuc2V0KEwsMCksMDtsZXQgdGU9aihPKTtpZih0ZT4wKXJldHVybiBvZS5zZXQoTCx0ZSksdGU7bGV0IHE9cy5sZW5ndGg7dHJ5e3MuZ3JvdygxKX1jYXRjaChPZSl7dGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogY291bGQgbm90IGdyb3cgdGhlIHNoYXJlZCB0YWJsZSBmb3IgIiR7TH0iIChtYXggcmVhY2hlZCk6IGArKE9lIGluc3RhbmNlb2YgRXJyb3I/T2UubWVzc2FnZTpTdHJpbmcoT2UpKSl9cmV0dXJuIHMuc2V0KHEsTyksRmUhPT1udWxsJiZGZS5zZXQoTyxxKSxCdChPLHEpLG9lLnNldChMLHEpLHF9aWYocihydCwic3ltYm9sSW5kZXgiKSxlLnJlc2VydmVkU3ltYm9sSW5kaWNlcylmb3IobGV0W0wsSV1vZiBlLnJlc2VydmVkU3ltYm9sSW5kaWNlcyl7bGV0IE89ST4+PjAsdGU9cmVbTF07aWYodHlwZW9mIHRlIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IGEgc2libGluZyByZXNlcnZlZCBzaGFyZWQtdGFibGUgc2xvdCAke099IGZvciAiJHtMfSIsIGJ1dCAke2Uuc29QYXRofHwidGhpcyBtb2R1bGUifSBleHBvcnRzIG5vIHN1Y2ggZnVuY3Rpb24gKG5ldmVyLXNpbGVudClgKTtpZighKE8+MCl8fE8+PXMubGVuZ3RofHxzLmdldChPKSE9PW51bGwmJnMuZ2V0KE8pIT09dGUpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogdGhlIHNsb3QgJHtPfSByZXNlcnZlZCBmb3IgIiR7TH0iIGlzIG91dHNpZGUgdGhlIHNoYXJlZCB0YWJsZSAobGVuZ3RoICR7cy5sZW5ndGh9KSBvciBhbHJlYWR5IG9jY3VwaWVkIChuZXZlci1zaWxlbnQpYCk7bGV0IHE9aih0ZSk7aWYocT4wJiZxIT09Tyl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiAiJHtMfSIgaW4gJHtlLnNvUGF0aHx8InRoaXMgbW9kdWxlIn0gaXMgYWxyZWFkeSB0YWJsZS1yZXNpZGVudCBhdCAke3F9LCBidXQgYSBzaWJsaW5nIGhhcyBiYWtlZCB0aGUgcmVzZXJ2ZWQgc2xvdCAke099IGludG8gaXRzIGRhdGEgLS0gb25lIGZ1bmN0aW9uIHdvdWxkIGhhdmUgdHdvIGFkZHJlc3NlcyAobmV2ZXItc2lsZW50KWApO3Muc2V0KE8sdGUpLEZlIT09bnVsbCYmRmUuc2V0KHRlLE8pLG9lLnNldChMLE8pfWxldCBDZT1udWxsO2Z1bmN0aW9uIFB0KEwpe0NlPT09bnVsbCYmKENlPW5ldyBNYXApO2xldCBJPUNlLmdldChMKTtpZihJIT09dm9pZCAwKXJldHVybiBJO2xldCBPPTAsdGU9Q3IodCxMKTtyZXR1cm4gdGUub2smJiF0ZS5tdXRhYmxlJiYhKGQmJmQudGxzRXhwb3J0cy5pbmNsdWRlcyhMKSkmJnRlLnZhbHVlPD1fJiYoTz0oaD4+PjApK3RlLnZhbHVlPj4+MCksQ2Uuc2V0KEwsTyksT31yKFB0LCJkYXRhU3ltYm9sQWRkcmVzcyIpO2xldCBkbj0hMSxlZT1udWxsLE1lPTA7ZnVuY3Rpb24gcG4oTCl7aWYoZWU9PT1udWxsfHxNZSE9PXMubGVuZ3RoKXtlZT1uZXcgTWFwO2ZvcihsZXQgTz1zLmxlbmd0aC0xO08+PTA7Ty0tKXtsZXQgdGU9cy5nZXQoTyk7dGUhPT1udWxsJiZlZS5zZXQodGUsTyl9TWU9cy5sZW5ndGh9bGV0IEk9ZWUuZ2V0KEwpO3JldHVybiBJPT09dm9pZCAwPy0xOkl9cihwbiwiZ290UGFzc1Jlc2lkZW50SW5kZXhPZiIpO2Z1bmN0aW9uIEJ0KEwsSSl7aWYoZWU9PT1udWxsKXJldHVybjtsZXQgTz1lZS5nZXQoTCk7KE89PT12b2lkIDB8fEk8TykmJmVlLnNldChMLEkpLE1lPXMubGVuZ3RofXIoQnQsImdvdFBhc3NSZWNvcmQiKTtmdW5jdGlvbiBrbihMLEkpe2xldCBPPWRuP3BuKEkpOmZ1KHMsSSk7aWYoTz49MClyZXR1cm4gTztsZXQgdGU9ZS5nb3RGdW5jSW5kZXg7aWYoISh0ZSBpbnN0YW5jZW9mIE1hcCkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogR09ULmZ1bmMuJHtMfSByZXNvbHZlcyB0byBhIE1BSU4gZnVuY3Rpb24gdGhhdCBpcyBub3QgdGFibGUtcmVzaWRlbnQsIGFuZCBubyBQUk9DRVNTLXdpZGUgb3B0cy5nb3RGdW5jSW5kZXggTWFwIHdhcyBwcm92aWRlZCBcdTIwMTQgcmVmdXNpbmcgdG8gYXBwZW5kIHBlci1oYW5kbGUgKHR3byAuc28ncyBhZGRyZXNzLXRha2luZyB0aGUgc2FtZSBzeW1ib2wgd291bGQgZGl2ZXJnZSBvbiBpdHMgdGFibGUgaW5kZXgsIGJyZWFraW5nIHRoZSBjcm9zcy1tb2R1bGUgY29yb3V0aW5lIGlkZW50aXR5OyBuZXZlci1zaWxlbnQpYCk7bGV0IHE9dGUuZ2V0KEwpO2lmKHEhPT12b2lkIDApe2lmKHE+PXMubGVuZ3RoKXRyeXtzLmdyb3cocSsxLXMubGVuZ3RoKX1jYXRjaChZdCl7dGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogY291bGQgbm90IGdyb3cgdGhlIHNoYXJlZCB0YWJsZSB0byB0aGUgc2VlZGVkIEdPVC5mdW5jLiR7TH0gaW5kZXggJHtxfSAobWF4IHJlYWNoZWQpOiBgKyhZdCBpbnN0YW5jZW9mIEVycm9yP1l0Lm1lc3NhZ2U6U3RyaW5nKFl0KSkpfWxldCBIZT1zLmdldChxKTtpZihIZT09PW51bGwpcmV0dXJuIHMuc2V0KHEsSSksQnQoSSxxKSxxO2lmKEhlIT09SSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBHT1QuZnVuYy4ke0x9IGlkZW50aXR5IGRyaWZ0IFx1MjAxNCB0aGUgcHJvY2Vzcy13aWRlIGNhY2hlIGhvbGRzIHNoYXJlZC10YWJsZSBpbmRleCAke3F9IGJ1dCB0aGUgcmVzb2x2ZXIgbm93IHJldHVybnMgYSBESUZGRVJFTlQgZnVuY3Rpb24gb2JqZWN0IChhIHBlci1tb2R1bGUgd3JhcHBlZCBjbG9zdXJlPykuIE9uZSBzeW1ib2wgbXVzdCBrZWVwIE9ORSB0YWJsZSBpZGVudGl0eSBhY3Jvc3MgbW9kdWxlcyAobmV2ZXItc2lsZW50KWApO3JldHVybiBxfWxldCBPZT1zLmxlbmd0aDt0cnl7cy5ncm93KDEpfWNhdGNoKEhlKXt0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBjb3VsZCBub3QgZ3JvdyB0aGUgc2hhcmVkIHRhYmxlIGZvciBHT1QuZnVuYy4ke0x9IChtYXggcmVhY2hlZCk6IGArKEhlIGluc3RhbmNlb2YgRXJyb3I/SGUubWVzc2FnZTpTdHJpbmcoSGUpKSl9cmV0dXJuIHMuc2V0KE9lLEkpLEJ0KEksT2UpLHRlLnNldChMLE9lKSxPZX1yKGtuLCJtYWluRnVuY3Rpb25UYWJsZUluZGV4Iik7bGV0IHduPW51bGwsaGU9bmV3IE1hcDtkbj0hMDtmb3IobGV0W0wsSV1vZiB5KXtpZihlLnByZXNldEdvdEZ1bmMmJmUucHJlc2V0R290RnVuYy5oYXMoTCkpe0kudmFsdWU9ZS5wcmVzZXRHb3RGdW5jLmdldChMKT4+PjA7Y29udGludWV9aWYoZS5kZWZlckdvdEZ1bmMmJmUuZGVmZXJHb3RGdW5jLmhhcyhMKSl7aGUuc2V0KEwsSSk7Y29udGludWV9aWYodHlwZW9mIHJlW0xdPT0iZnVuY3Rpb24iKXtsZXQgcT1ydChMKTtpZighKHE+MCkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogR09ULmZ1bmMuJHtMfSByZXNvbHZlZCB0byB0YWJsZSBpbmRleCAke3F9IChuZXZlci1zaWxlbnQgUElDIGhvbGUpYCk7SS52YWx1ZT1xO2NvbnRpbnVlfXdufHwod249Vm8oUyx0KSk7bGV0IE89d24uZ2V0KEwpO2lmKE8pe2xldCBxPWUucmVzb2x2ZUltcG9ydD9lLnJlc29sdmVJbXBvcnQoTy5tb2R1bGUsTy5maWVsZCwiZnVuY3Rpb24iKTp2b2lkIDA7aWYocT09bnVsbCYmUiYmUi5oYXMoTCkpe0kudmFsdWU9MCxVLnB1c2goTCk7Y29udGludWV9aWYodHlwZW9mIHEhPSJmdW5jdGlvbiIpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogR09ULmZ1bmMuJHtMfSAtPiBpbXBvcnQgJHtPLm1vZHVsZX0uJHtPLmZpZWxkfSBkaWQgbm90IHJlc29sdmUgdG8gYSBmdW5jdGlvbiAobmV2ZXItc2lsZW50KWApO0kudmFsdWU9a24oTCxxKTtjb250aW51ZX1sZXQgdGU9ZS5yZXNvbHZlSW1wb3J0P2UucmVzb2x2ZUltcG9ydCgiZW52IixMLCJmdW5jdGlvbiIpOnZvaWQgMDtpZih0ZT09bnVsbCYmUiYmUi5oYXMoTCkpe0kudmFsdWU9MCxVLnB1c2goTCk7Y29udGludWV9aWYodHlwZW9mIHRlIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IEdPVC5mdW5jLiR7TH0gdW5yZXNvbHZlZCBcdTIwMTQgbm90IGEgLnNvIGV4cG9ydCwgbm8gaW1wb3J0ZWQtZnVuY3Rpb24gc3ltYm9sIG9mIHRoYXQgbmFtZSwgYW5kIHRoZSBNQUlOIHJlc29sdmVJbXBvcnQgY2hhaW4gcHJvdmlkZXMgbm8gZW52LiR7TH0gZnVuY3Rpb24gKG5ldmVyLXNpbGVudCBQSUMgaG9sZSlgKTtJLnZhbHVlPWtuKEwsdGUpfWRuPSExLGVlPW51bGw7bGV0IEZ0PTAsZ249W107Zm9yKGxldFtMLEldb2YgRCl7bGV0IE89ZS5pbnRlcnBvc2VEYXRhQWRkcmVzcz9lLmludGVycG9zZURhdGFBZGRyZXNzKEwpOnZvaWQgMDtpZighKHR5cGVvZiBPPT0ibnVtYmVyIiYmTz4+PjA+MCkmJmUucHJlZW1wdHNEYXRhJiZlLnByZWVtcHRzRGF0YShMKSl7bGV0IE9lPWUucmVzb2x2ZURhdGFBZGRyZXNzP2UucmVzb2x2ZURhdGFBZGRyZXNzKEwpOnZvaWQgMDtpZih0eXBlb2YgT2UhPSJudW1iZXIifHwhKE9lPj4+MD4wKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBHT1QubWVtLiR7TH0gXHUyMDE0IGFuIGVhcmxpZXIgbmVlZGVkIGVudHJ5IGV4cG9ydHMgaXQsIGJ1dCBpdHMgYWRkcmVzcyBkaWQgbm90IHJlc29sdmUgKHJlc29sdmVEYXRhQWRkcmVzcyAtPiAke09lfSkuIFJlZnVzaW5nIHJhdGhlciB0aGFuIGJpbmRpbmcgdGhpcyBtb2R1bGUncyBvd24gY29weSBiZXNpZGUgaXQgKG5ldmVyLXNpbGVudCkuYCk7SS52YWx1ZT1PZXwwO2NvbnRpbnVlfWxldCB0ZT1yZVtMXTtpZih0ZSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbCl7bGV0IE9lPWUuaW50ZXJwb3NlRGF0YUFkZHJlc3M/ZS5pbnRlcnBvc2VEYXRhQWRkcmVzcyhMKTp2b2lkIDA7aWYodHlwZW9mIE9lPT0ibnVtYmVyIiYmT2U+Pj4wPjApe0kudmFsdWU9T2V8MCxnbi5wdXNoKEwpO2NvbnRpbnVlfWxldCBIZT0oaHwwKSsodGUudmFsdWV8MCk7aWYoTD09PSJfX2h3anNfc3RhdHVzX2NoYW5uZWwiKXtsZXQgWXQ9ZS5yZXNvbHZlRGF0YUFkZHJlc3M/ZS5yZXNvbHZlRGF0YUFkZHJlc3MoTCk6dm9pZCAwO2lmKHR5cGVvZiBZdD09Im51bWJlciImJll0Pj4+MD4wJiZZdD4+PjAhPT1IZT4+PjApdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogR09ULm1lbS4ke0x9IExPQ0tTVEVQIFZJT0xBVElPTiBcdTIwMTQgdGhpcyAuc28gREVGSU5FUyBpdHMgb3duICR7TH0gKG1lbW9yeUJhc2Urb2Zmc2V0ID0gJHtIZT4+PjB9KSB3aGlsZSB0aGUgcHJvY2VzcyBhbHJlYWR5IG93bnMgb25lIGF0ICR7WXQ+Pj4wfSAoY29udHJhY3QgXHhBNzE6IE9ORSBjaGFubmVsIGJsb2NrIHBlciBwcm9jZXNzLCBNQUlOL3J0LW93bmVkKS4gVGhlIC5zbyB3YXMgbGlua2VkIHdpdGggdGhlIFJUIG1lcmdlZCBpbjsgbGluayBpdCBhZ2FpbnN0IHRoZSBSVC1pbXBvcnQgc3VyZmFjZSBpbnN0ZWFkLiBSZWZ1c2luZyB0aGUgc2lsZW50IHNwbGl0LWJyYWluICh0d28gY2hhbm5lbCBibG9ja3MgPSByYWlzZXMgaW52aXNpYmxlIHRvIHRoZSBvdGhlciBzaWRlJ3MgY2hlY2tzKS5gKX1pZihJLnZhbHVlPUhlLEw9PT0iX19od2pzX21vZHVsZV9pZCIpe2lmKCEoSGU+MCkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogR09ULm1lbS5fX2h3anNfbW9kdWxlX2lkIHJlc29sdmVkIHRvIGFkZHIgJHtIZX0gKG1lbW9yeUJhc2U9JHtofSkgXHUyMDE0IGNhbm5vdCBiaW5kIHRoZSBtb2R1bGUgaWQgaW50byB0aGUgTlVMTCBwYWdlIChuZXZlci1zaWxlbnQ7IHRoZSAuc28gbXVzdCBkZWNsYXJlIGRhdGEgZm9yIGl0KWApO0Z0PUhlfWNvbnRpbnVlfWxldCBxPWUucmVzb2x2ZURhdGFBZGRyZXNzP2UucmVzb2x2ZURhdGFBZGRyZXNzKEwpOnZvaWQgMDtpZighKHR5cGVvZiBxPT0ibnVtYmVyIiYmcT4+PjA+MCkmJlImJlIuaGFzKEwpKXtJLnZhbHVlPTAsVS5wdXNoKEwpO2NvbnRpbnVlfWlmKHR5cGVvZiBxIT0ibnVtYmVyInx8IShxPj4+MD4wKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBHT1QubWVtLiR7TH0gdW5yZXNvbHZlZCBcdTIwMTQgdGhlIC5zbyBkb2VzIG5vdCBkZWZpbmUgaXQgYW5kIHRoZSBNQUlOIHByb3ZpZGVzIG5vIGFkZHJlc3MtYmVhcmluZyBkYXRhIGV4cG9ydCBvZiB0aGF0IG5hbWUgKHJlc29sdmVEYXRhQWRkcmVzcyAtPiAke3F9KS4gUmVmdXNpbmcgdGhlIG9sZCBzaWxlbnQgbWVtb3J5QmFzZSswIHJlc29sdXRpb24gKG5ldmVyLXNpbGVudCBQSUMgaG9sZTsgZXhwb3J0IHRoZSBzeW1ib2wgZnJvbSB0aGUgZHluYW1pYyBtYWluLCBlLmcuIFdBU01MRF9EWU5fRVhQT1JUX0xJQkMpYCk7SS52YWx1ZT1xfDB9bGV0IEVuPSExOyFlLnNraXBEYXRhUmVsb2NzJiZ0eXBlb2YgcmUuX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzPT0iZnVuY3Rpb24iJiYocmUuX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzKCksRW49ITApO2xldCB0bj0hIShsJiZsLmZsYWdzLnVzZXNUbHMmJmUudGxzT3duZXIhPT0hMCYmcmUuX190bHNfc2l6ZS52YWx1ZT4+PjA+MCksc3M9dG4/dXUocmUsbyxlLnNpZGVUbHMsZS5zb1BhdGgpOjA7cmV0dXJuIEZ0PjAmJm5ldyBEYXRhVmlldyhvLmJ1ZmZlcikuc2V0SW50MzIoRnQsZS5tb2R1bGVJZHwwLCEwKSx7bW9kdWxlOlMsaW5zdGFuY2U6ZmUsZXhwb3J0czpyZSxtZW1vcnlCYXNlOmgsdGFibGVCYXNlOngsZHlsaW5rOmQsYnVkZ2V0R2xvYmFsOmRlLHdlYWtVbmJvdW5kSW1wb3J0czpVLG93bkJvdW5kSW1wb3J0czpRLHRsczp0bj97Li4uWW8ocmUpLGJhc2U6cigoKT0+cmUuX190bHNfYmFzZS52YWx1ZT4+PjAsImJhc2UiKSx1bmJvdW5kOnNzPT09MH06bnVsbCxwZW5kaW5nR290RnVuY05hbWVzKCl7cmV0dXJuWy4uLmhlLmtleXMoKV19LHBhdGNoR290RnVuYyhMLEkpe2xldCBPPWhlLmdldChMKTtpZighTyl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBwYXRjaEdvdEZ1bmMoIiR7TH0iKSBcdTIwMTQgbm8gZGVmZXJyZWQgR09ULmZ1bmMgb2YgdGhhdCBuYW1lIChuZXZlciBkZWZlcnJlZCwgb3IgYWxyZWFkeSBwYXRjaGVkKWApO2xldCB0ZT1rbihMLEkpO3JldHVybiBPLnZhbHVlPXRlLGhlLmRlbGV0ZShMKSx0ZX0sZGF0YVJlbG9jc0FwcGxpZWQ6RW4saW50ZXJwb3NlZERhdGE6Z24scnVuQ3RvcnMoKXtpZihYKXJldHVybiExO1g9ITA7bGV0IEw9cmUuX193YXNtX2NhbGxfY3RvcnM7cmV0dXJuIHR5cGVvZiBMPT0iZnVuY3Rpb24iPyhMKCksITApOiExfSxkbHN5bShMKXtpZihrZSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBkbHN5bSgiJHtMfSIpIG9uIGFuIHVubG9hZGVkIG1vZHVsZWApO3JldHVybiByZVtMXWluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsP1B0KEwpOnJ0KEwpfSx0YWJsZUluZGljZXMoKXtsZXQgTD1bXTtmb3IobGV0IEkgb2Ygb2UudmFsdWVzKCkpST4wJiZMLnB1c2goSSk7cmV0dXJuIEx9LHRhYmxlRW50cmllcygpe2xldCBMPVtdO2ZvcihsZXRbSSxPXW9mIG9lKU8+MCYmTC5wdXNoKFtJLE9dKTtyZXR1cm4gTH0sdW5sb2FkKCl7a2U9ITB9fX1yKENzLCJsb2FkU2hhcmVkT2JqZWN0Iik7ZnVuY3Rpb24gR2woZSx0LG8scyxsKXtlPWU+Pj4wLHQ9dD4+PjA7Zm9yKGxldCBtIG9mIG8paWYodD49bS50YWJsZUJhc2UmJnQ8bS50YWJsZUJhc2UrbS50YWJsZVNpemV8fEFycmF5LmlzQXJyYXkobS5hcHBlbmRlZCkmJm0uYXBwZW5kZWQuaW5jbHVkZXModCkpcmV0dXJue2RlYWQ6bSxsaXZlOm51bGwsaW5FbGVtOiExLGhhc1JlYzohMSxyZWNPdGhlclNpZzohMSxyZWNBbnk6ITEscmVnUmFuOiExfTtmb3IobGV0IG0gb2Ygcyl7bGV0IGM9bS5oYW5kbGUmJm0uaGFuZGxlLmR5bGluaz9tLmhhbmRsZS5keWxpbmsudGFibGVTaXplPj4+MDowLGg9bS50YWJsZUJhc2U+Pj4wLGc9bS5oYW5kbGUmJnR5cGVvZiBtLmhhbmRsZS50YWJsZUluZGljZXM9PSJmdW5jdGlvbiI/bS5oYW5kbGUudGFibGVJbmRpY2VzKCk6W10seD10Pj1oJiZ0PGgrYztpZighKHh8fGcuaW5jbHVkZXModCkpKWNvbnRpbnVlO2xldCBTPXR5cGVvZiBsPT0iZnVuY3Rpb24iP2wodCk6dm9pZCAwLFI9UyE9PXZvaWQgMCYmUyE9PTAsdz0hIShtLnhtb2RSZWNzJiZtLnhtb2RSZWNzLnNpemU+MCl8fCEhKG0ueG1vZFJlZ2lzdHJhciYmbS54bW9kUmVnaXN0cmFyLmltcG9ydGVkPT09ITEpO3JldHVybntkZWFkOm51bGwsbGl2ZTptLGluRWxlbTp4LGhhc1JlYzohIShtLnhtb2RSZWNzJiZtLnhtb2RSZWNzLmhhcyhlKyI6Iit0KSkscmVjT3RoZXJTaWc6UiYmUz4+PjAhPT1lLHJlY0FueTpSLHJlZ1Jhbjp3fX1sZXQgZD10eXBlb2YgbD09ImZ1bmN0aW9uIj9sKHQpOnZvaWQgMCxfPWQhPT12b2lkIDAmJmQhPT0wO3JldHVybntkZWFkOm51bGwsbGl2ZTpudWxsLGluRWxlbTohMSxoYXNSZWM6ITEscmVjT3RoZXJTaWc6XyYmZD4+PjAhPT1lLHJlY0FueTpfLHJlZ1JhbjohMX19cihHbCwieG1vZENvbnN1bHRDbGFzc2lmeSIpO3ZhciBwdT0iaHdqcy54bW9kX21hcnNoYWwiO2Z1bmN0aW9uIEtsKGUpe3JldHVybiBXZWJBc3NlbWJseS5Nb2R1bGUuY3VzdG9tU2VjdGlvbnMoZSxwdSkubGVuZ3RoPjB9cihLbCwieG1vZE1hcnNoYWxBcm1lZCIpO2Z1bmN0aW9uIEpsKGUpe3JldHVybiBlLmluRGVhZD8wOmUuaW5Gb290cHJpbnQ/ZS5oYXNSZWN8fGUuZnJvbVJ0fHxlLmZyb21NYWluJiYhZS5pbkVsZW18fCFlLmluRWxlbSYmIWUucmVjQW55JiZlLnJlZ1Jhbj8xOmUubWFyc2hhbCYmZS5yZWNPdGhlclNpZz8yOjA6ZS5tYXJzaGFsJiYhZS5mcm9tUnQmJmUucmVjT3RoZXJTaWc/MjoxfXIoSmwsInhtb2RDb25zdWx0VmVyZGljdCIpO3ZhciB3dT1uZXcgVWludDhBcnJheShbMCw5NywxMTUsMTA5LDEsMCwwLDAsMSw0LDEsOTYsMCwwLDIsMTksMywxLDEwMSwxLDExNSwwLDAsMSwxMDEsMSw5OSwwLDAsMSwxMDEsMSwxMjIsMCwwLDMsMiwxLDAsNyw1LDEsMSwxMTQsMCwzLDEwLDEwLDEsOCwwLDE2LDAsMTYsMSwxNiwyLDExXSksem89bnVsbDtmdW5jdGlvbiB6bChlKXtsZXQgdD1lP2UuX19od2pzX2N0b3JzX2RlZmVyX3NldDp2b2lkIDAsbz1lP2UuX19od2pzX2N0b3JzX3J1bm5lcjp2b2lkIDA7aWYodHlwZW9mIHQhPSJmdW5jdGlvbiJ8fHR5cGVvZiBvIT0iZnVuY3Rpb24iKXJldHVybnt9O2xldCBzPW8oKT4+PjA7cmV0dXJuIHM9PT0wP3t9OntkZWZlclNldDp0LHJ1bm5lcjpzfX1yKHpsLCJkcml2ZW5DdG9ySGFuZGxlcyIpO2Z1bmN0aW9uIFlsKHt0YWJsZTplLG1lbW9yeTp0LHNsb3RBZGRyOm8sbGlzdDpzfSl7bGV0IGw9bz4+PjAsZD1uZXcgRGF0YVZpZXcodC5idWZmZXIpLF89ZC5nZXRVaW50MzIobCwhMCk7aWYocy5sZW5ndGg+Xyl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogJHtzLmxlbmd0aH0gbmVlZGVkIGxpYnJhcmllcyBkZWZlciB0aGVpciBjdG9ycyB0byBfc3RhcnQgYnV0IHRoZSBtYWluJ3MgX193YXNtMzJfbmVlZGVkX2N0b3JzX2luX3N0YXJ0IHNsb3QgaG9sZHMgJHtffSBcdTIwMTQgcmVmdXNpbmcgdG8gZHJvcCBhbnkgKG5ldmVyLXNpbGVudCkuYCk7aWYocy5sZW5ndGg9PT0wKXJldHVybltdO3pvfHwoem89bmV3IFdlYkFzc2VtYmx5Lk1vZHVsZSh3dSkpO2xldCBtPXIoUz0+dHlwZW9mIFMuZGVmZXJTZXQ9PSJmdW5jdGlvbiImJlMucnVubmVyPj4+MCE9PTAsImlzRHJpdmVuIiksYz1zLmxlbmd0aCtzLmZpbHRlcihtKS5sZW5ndGg8PV8saD1lLmxlbmd0aD4+PjA7ZS5ncm93KHMubGVuZ3RoKTtsZXQgZz0wLHg9cy5tYXAoKFMsUik9PntsZXQgdz1jJiZtKFMpLHk9bmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHpvLHtlOntzOnIoKCk9Pnt3JiZTLmRlZmVyU2V0KDEpfSwicyIpLGM6Uy5jdG9yLHo6cigoKT0+e3cmJlMuZGVmZXJTZXQoMCl9LCJ6Iil9fSk7cmV0dXJuIGUuc2V0KGgrUix5LmV4cG9ydHMuciksZC5zZXRVaW50MzIobCs4KzQqZysrLGgrUj4+PjAsITApLHcmJmQuc2V0VWludDMyKGwrOCs0KmcrKyxTLnJ1bm5lcj4+PjAsITApLGgrUn0pO3JldHVybiBkLnNldFVpbnQzMihsKzQsZz4+PjAsITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh4LCJkcml2ZW4iLHt2YWx1ZTpjfSkseH1yKFlsLCJwdWJsaXNoTmVlZGVkQ3RvcnNJblN0YXJ0Iik7dmFyIGd1PU9iamVjdC5mcmVlemUoWyJyYXdfY29weV90b191c2VyIiwicmF3X2NvcHlfZnJvbV91c2VyIiwicmF3X2NsZWFyX3VzZXIiXSk7dmFyIFZsPSJod2pzX3N1c3BlbmQiO2Z1bmN0aW9uIFhsKGUpe2xldCB0PVtdLG89MDtmb3IobGV0IHMgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMoZSkpcy5raW5kPT09Im1lbW9yeSImJihvKysscy5tb2R1bGU9PT0iZW52IiYmcy5uYW1lPT09Imtlcm5lbF9tZW1vcnkifHx0LnB1c2goYHZtbGludXggaW1wb3J0cyBtZW1vcnkgJHtzLm1vZHVsZX0uJHtzLm5hbWV9IFx1MjAxNCB0aGUga2VybmVsIGlzIGEgU0lOR0xFLW1lbW9yeSBtb2R1bGUgbm93IChvbmx5IGVudi5rZXJuZWxfbWVtb3J5KS4gQSBzdGFsZSBtdWx0aS1tZW1vcnkgdm1saW51eC53YXNtICh0aGUgZGVsZXRlZCBlbnYudXNlcl9tZW1vcnkgc3BsaWNlKSBjYW5ub3QgYm9vdCBvbiB0aGlzIGhvc3Q6IHJlYnVpbGQgdGhlIGtlcm5lbCAodWFjY2VzcyBpcyBob3N0LXNlcnZpY2VkIHZpYSBsaW51eC5yYXdfY29weV8qX3VzZXI7IG11bHRpLW1lbW9yeSBpcyBhbHNvIHdoYXQgV2ViS2l0L2lQYWRPUyByZWplY3RzIFx1MjAxNCBsaXRiIzY4KS5gKSkscy5tb2R1bGU9PT1WbCYmZ3UuaW5jbHVkZXMocy5uYW1lKSYmdC5wdXNoKGB2bWxpbnV4IGRlY2xhcmVzIGtlcm5lbC1tZW1vcnkgc2VydmljZSBpbXBvcnQgJyR7cy5uYW1lfScgaW4gcGFya2luZyBuYW1lc3BhY2UgJyR7Vmx9JyBcdTIwMTQgdGhlIHVhY2Nlc3MgY3Jvc3Npbmcgd291bGQgYmUgYSBjb3JvdXRpbmUgc3VzcGVuZCBib3VuZGFyeSBieSBjb25zdHJ1Y3Rpb24sIHdoaWNoIGlzIHRoZSBzaWxlbnRseS1jYXRhc3Ryb3BoaWMgd2lyaW5nIHRoZSBsZWFmIHdpdG5lc3MgZXhpc3RzIHRvIHJlZnVzZSAoUExBTi1USFJFQURTLVNJTkdMRS1NRU1PUlkgXHhBNzUgUjEpLmApO3JldHVybiBvPjEmJnQucHVzaChgdm1saW51eCBpbXBvcnRzICR7b30gbWVtb3JpZXMgXHUyMDE0IGV4YWN0bHkgb25lIChlbnYua2VybmVsX21lbW9yeSkgaXMgdGhlIHNpbmdsZS1tZW1vcnkgY29udHJhY3QuYCksdH1yKFhsLCJhdWRpdFZtbGludXhTaW5nbGVNZW1vcnkiKTtmdW5jdGlvbiBxbChlKXtsZXR7dXNlck1lbW9yeTp0LGtlcm5lbE1lbW9yeTpvLHJlZnVzZTpzLGNvbnRleHQ6bCxyZWRQYXJrOmR9PWU7aWYodHlwZW9mIHMhPSJmdW5jdGlvbiIpdGhyb3cgbmV3IEVycm9yKCJtYWtlVWFjY2Vzc0xlYWZCb3VuZGFyeTogcmVmdXNlKCkgaXMgcmVxdWlyZWQiKTtsZXQgXz0wLG09bnVsbCxjPW51bGwsaD1yKFg9PntsZXQga2U9cigoLi4ub2UpPT57aWYoXz4wKXRocm93IHMoYHVhY2Nlc3MtbGVhZi13aXRuZXNzIFJFRlVTQUwgWyR7bH1dOiBwYXJrIHNpZ25hbCByYWlzZWQgd2hpbGUgYSBrZXJuZWwtbWVtb3J5IGxlYWYgY3Jvc3NpbmcgaXMgbGl2ZSAoZGVwdGg9JHtffSkuIEEgcGFyayBhY3Jvc3MgdGhlIHVhY2Nlc3MgY3Jvc3NpbmcgaXMgc2lsZW50bHkgY2F0YXN0cm9waGljIChSMSBzcGlrZTogcG9pc29uIHByb3BhZ2F0aW9uIHdpdGggYSBjbGVhbiBET05FIGV4aXQpIFx1MjAxNCB0aGUgY3Jvc3NpbmcgTVVTVCBiZSBhIGxlYWYgaG9zdCBtZW1jcHkuIFJlZnVzaW5nIGxvdWRseSBpbnN0ZWFkLmApLG5ldyBFcnJvcigidWFjY2Vzcy1sZWFmLXdpdG5lc3M6IHBhcmsgZHVyaW5nIGxlYWYgY3Jvc3NpbmciKTtyZXR1cm4gWCguLi5vZSl9LCJ3cmFwcGVkIik7cmV0dXJuIGM9a2Usa2V9LCJndWFyZFBhcmsiKSxnPXIoWD0+e209WH0sInNldFBhcmtlZFNsb3RSZWFkZXIiKSx4PXIoKCk9Pl8+MCwiaW5MZWFmQ3Jvc3NpbmciKTtpZighdCl7bGV0IFg9cihrZT0+KC4uLm9lKT0+e3Rocm93IHMoYHVhY2Nlc3MtbGVhZi13aXRuZXNzIFJFRlVTQUwgWyR7bH1dOiBsaW51eC4ke2tlfSgke29lLm1hcChGZT0+IjB4IisoRmU+Pj4wKS50b1N0cmluZygxNikpLmpvaW4oIiwgIil9KSBjYWxsZWQgZnJvbSBrdGhyZWFkIGNvbnRleHQgXHUyMDE0IHRoZSBzdGFuZGFsb25lIHZtbGludXggV29ya2VyIGhhcyBubyB1c2VyIHBhZ2VzOyBrZXJuZWwgY29kZSBtdXN0IG5ldmVyIHVhY2Nlc3Mgb3V0c2lkZSBhIHByb2Nlc3MgY29udGV4dC4gVGhpcyBpcyBhIGtlcm5lbCBidWcgKHRoZSBvbGQgMS1wYWdlIHNlbnRpbmVsJ3MgdHJhcCwgbm93IG5hbWVkKS5gKSxuZXcgRXJyb3IoYGt0aHJlYWQgdWFjY2VzczogbGludXguJHtrZX1gKX0sImt0aHJlYWRCdWciKTtyZXR1cm57aW1wb3J0czp7cmF3X2NvcHlfdG9fdXNlcjpYKCJyYXdfY29weV90b191c2VyIikscmF3X2NvcHlfZnJvbV91c2VyOlgoInJhd19jb3B5X2Zyb21fdXNlciIpLHJhd19jbGVhcl91c2VyOlgoInJhd19jbGVhcl91c2VyIil9LGd1YXJkUGFyazpoLHNldFBhcmtlZFNsb3RSZWFkZXI6ZyxpbkxlYWZDcm9zc2luZzp4fX1sZXQgUz1udWxsLFI9bnVsbCx3PXIoKCk9PntsZXQgWD10LmJ1ZmZlcjtyZXR1cm4gWCE9PVMmJihTPVgsUj1uZXcgVWludDhBcnJheShYKSksUn0sInVzZXJVOCIpLHk9bnVsbCxEPW51bGwsZGU9cigoKT0+e2xldCBYPW8uYnVmZmVyO3JldHVybiBYIT09eSYmKHk9WCxEPW5ldyBVaW50OEFycmF5KFgpKSxEfSwia2VyblU4Iiksej0zMixRPXIoKFgsa2Usb2UsRmUsaik9PntpZihqPD16KWZvcihsZXQgcnQ9MDtydDxqO3J0KyspWFtrZStydF09b2VbRmUrcnRdO2Vsc2UgWC5zZXQob2Uuc3ViYXJyYXkoRmUsRmUraiksa2UpfSwiY29weUJ5dGVzIiksVT1yKChYLGtlKT0+e3Rocm93IHMoYHVhY2Nlc3MtbGVhZi13aXRuZXNzIFJFRlVTQUwgWyR7bH1dOiBsaW51eC4ke1h9OiAke2tlfWApLG5ldyBFcnJvcihgdWFjY2VzcyBrZXJuZWwtc2lkZSBidWc6IGxpbnV4LiR7WH1gKX0sImtlcm5lbEJ1ZyIpLGZlPXIoKFgsa2UpPT4ob2UsRmUsaik9PntsZXQgcnQ9bT9tKCk6MDtfKys7dHJ5e3JldHVybiBkJiYoY3x8cyhgdWFjY2Vzcy1sZWFmLXdpdG5lc3MgUkVGVVNBTCBbJHtsfV06IFJFRCBwYXJrIGFybSByZXF1ZXN0ZWQgYnV0IG5vIHBhcmsgYmluZGluZyB3YXMgZ3VhcmRlZCAoZ3VhcmRQYXJrIG5ldmVyIGNhbGxlZCkgXHUyMDE0IHRoZSB3aXRuZXNzIHdvdWxkIGJlIHZhY3VvdXMuIFdpcmUgZ3VhcmRQYXJrLmApLGMoKSksa2Uob2UsRmUsail9ZmluYWxseXtpZihfLS0sbSl7bGV0IENlPW0oKTtDZSE9PXJ0JiZzKGB1YWNjZXNzLWxlYWYtd2l0bmVzcyBSRUZVU0FMIFske2x9XTogcGFya2VkIHNsb3QgY2hhbmdlZCBhY3Jvc3MgbGludXguJHtYfSAoMHgkeyhydD4+PjApLnRvU3RyaW5nKDE2KX0gLT4gMHgkeyhDZT4+PjApLnRvU3RyaW5nKDE2KX0pIFx1MjAxNCB0aGUga2VybmVsLW1lbW9yeSBjcm9zc2luZyBzdXNwZW5kZWQuIFRoZSBjcm9zc2luZyBNVVNUIGJlIGEgbGVhZi5gKX19fSwibGVhZiIpO3JldHVybntpbXBvcnRzOntyYXdfY29weV90b191c2VyOmZlKCJyYXdfY29weV90b191c2VyIiwoWCxrZSxvZSk9PntpZihYPj4+PTAsa2U+Pj49MCxvZT4+Pj0wLG9lPT09MClyZXR1cm4gMDtsZXQgRmU9dygpO2lmKFgrb2U+RmUubGVuZ3RoKXJldHVybiBvZTtsZXQgaj1kZSgpO3JldHVybiBrZStvZT5qLmxlbmd0aCYmVSgicmF3X2NvcHlfdG9fdXNlciIsYGtlcm5lbC1zaWRlIHNvdXJjZSBvdXQgb2YgcmFuZ2UgKGZyb209MHgke2tlLnRvU3RyaW5nKDE2KX0gbj0ke29lfSBrZXJuZWxfbGVuPTB4JHtqLmxlbmd0aC50b1N0cmluZygxNil9KSBcdTIwMTQga2VybmVsIGJ1Z2ApLFEoRmUsWCxqLGtlLG9lKSwwfSkscmF3X2NvcHlfZnJvbV91c2VyOmZlKCJyYXdfY29weV9mcm9tX3VzZXIiLChYLGtlLG9lKT0+e2lmKFg+Pj49MCxrZT4+Pj0wLG9lPj4+PTAsb2U9PT0wKXJldHVybiAwO2xldCBGZT13KCk7aWYoa2Urb2U+RmUubGVuZ3RoKXJldHVybiBvZTtsZXQgaj1kZSgpO3JldHVybiBYK29lPmoubGVuZ3RoJiZVKCJyYXdfY29weV9mcm9tX3VzZXIiLGBrZXJuZWwtc2lkZSBkZXN0aW5hdGlvbiBvdXQgb2YgcmFuZ2UgKHRvPTB4JHtYLnRvU3RyaW5nKDE2KX0gbj0ke29lfSBrZXJuZWxfbGVuPTB4JHtqLmxlbmd0aC50b1N0cmluZygxNil9KSBcdTIwMTQga2VybmVsIGJ1Z2ApLFEoaixYLEZlLGtlLG9lKSwwfSkscmF3X2NsZWFyX3VzZXI6ZmUoInJhd19jbGVhcl91c2VyIiwoWCxrZSk9PntpZihYPj4+PTAsa2U+Pj49MCxrZT09PTApcmV0dXJuIDA7bGV0IG9lPXcoKTtyZXR1cm4gWCtrZT5vZS5sZW5ndGg/a2U6KG9lLmZpbGwoMCxYLFgra2UpLDApfSl9LGd1YXJkUGFyazpoLHNldFBhcmtlZFNsb3RSZWFkZXI6ZyxpbkxlYWZDcm9zc2luZzp4fX1yKHFsLCJtYWtlVWFjY2Vzc0xlYWZCb3VuZGFyeSIpO3ZhciB5dT10eXBlb2Ygc2V0SW1tZWRpYXRlPT0iZnVuY3Rpb24iLGJ1PXR5cGVvZiBNZXNzYWdlQ2hhbm5lbD09ImZ1bmN0aW9uIixsYT15dT8ic2V0SW1tZWRpYXRlIjpidT8iTWVzc2FnZUNoYW5uZWwiOiJzZXRUaW1lb3V0Ijt2YXIgUWw9MTAwLFpsPTAsZWQ9MCx0ZD0wO2Z1bmN0aW9uIGRhKCl7cmV0dXJue2tpbmQ6bGEsaW50ZXJ2YWxNczpRbCx0dXJuczp0ZCxiZWx0VHVybnM6ZWR9fXIoZGEsIm1hY3JvdGFza0NlbnN1cyIpO3ZhciBCcj1udWxsLEZyPVtdLGt1PXIoZT0+e3R5cGVvZiBlLnJlZj09ImZ1bmN0aW9uIiYmZS5yZWYoKX0sIm1hY3JvdGFza1BvcnRSZWYiKSxpYT1yKGU9Pnt0eXBlb2YgZS51bnJlZj09ImZ1bmN0aW9uIiYmZS51bnJlZigpfSwibWFjcm90YXNrUG9ydFVucmVmIik7ZnVuY3Rpb24geHUoKXtpZihCcj09PW51bGwpe2xldCBlPW5ldyBNZXNzYWdlQ2hhbm5lbDtlLnBvcnQxLm9ubWVzc2FnZT0oKT0+e2xldCB0PUZyLnNoaWZ0KCk7dCYmdCgpLEZyLmxlbmd0aD09PTAmJmlhKGUucG9ydDEpfSxpYShlLnBvcnQxKSxpYShlLnBvcnQyKSxCcj1lfXJldHVybiBuZXcgUHJvbWlzZShlPT57RnIubGVuZ3RoPT09MCYma3UoQnIucG9ydDEpLEZyLnB1c2goZSksQnIucG9ydDIucG9zdE1lc3NhZ2UoMCl9KX1yKHh1LCJwb3J0VHVybiIpO2Z1bmN0aW9uIGxyKCl7aWYodGQrKyxsYT09PSJzZXRJbW1lZGlhdGUiKXJldHVybiBuZXcgUHJvbWlzZShvPT57c2V0SW1tZWRpYXRlKG8pfSk7aWYobGEhPT0iTWVzc2FnZUNoYW5uZWwiKXJldHVybiBuZXcgUHJvbWlzZShvPT57c2V0VGltZW91dChvLDApfSk7bGV0IGU9eHUoKSx0PURhdGUubm93KCk7cmV0dXJuIHQtWmw8UWw/ZTooWmw9dCxlZCsrLGUudGhlbigoKT0+bmV3IFByb21pc2Uobz0+e3NldFRpbWVvdXQobywwKX0pKSl9cihsciwibWFjcm90YXNrVHVybiIpO3ZhciBFdT1bImh3anMtdXNlci1ydCBWSU9MQVRJT04iLCJod2pzLXJ0IFZJT0xBVElPTiJdO2Z1bmN0aW9uIEhyKGUsdCl7bGV0IG89ZT8uW3RdO3JldHVybiFvfHx0eXBlb2Ygby52YWx1ZSE9Im51bWJlciI/LTE6by52YWx1ZT4+PjB9cihIciwiZ2xvYmFsQWRkciIpO2Z1bmN0aW9uIFN1KGUsdCxvKXtsZXQgcz10LGw9TWF0aC5taW4odCtvLGUubGVuZ3RoKTtmb3IoO3M8bCYmZVtzXSE9PTA7KXMrKztyZXR1cm4gczw9dD8iIjpuZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6ITF9KS5kZWNvZGUoZS5zbGljZSh0LHMpKX1yKFN1LCJyZWFkQ1N0cmluZyIpO2Z1bmN0aW9uIGNhKGUsdCl7bGV0IG89SHIoZSwiX19od2pzX3Zpb2xhdGlvbl9wZW5kaW5nX2xhbmVzIikscz1IcihlLCJfX2h3anNfdmlvbGF0aW9uX2J1Zl9sYW5lcyIpLGw9SHIoZSwiX19od2pzX3Zpb2xhdGlvbl9wZW5kaW5nIiksZD1IcihlLCJfX2h3anNfdmlvbGF0aW9uX2J1ZiIpLF89bz49MCYmcz49MCxtPWw+PTAmJmQ+PTA7aWYoIV8mJiFtKXJldHVybntyZWFkYWJsZTohMSx3aHk6InRoaXMgaW1hZ2UgZXhwb3J0cyBuZWl0aGVyIF9faHdqc192aW9sYXRpb25fcGVuZGluZ19sYW5lcy9fX2h3anNfdmlvbGF0aW9uX2J1Zl9sYW5lcyBub3IgdGhlIG5vbi1sYW5lZCBfX2h3anNfdmlvbGF0aW9uX3BlbmRpbmcvX19od2pzX3Zpb2xhdGlvbl9idWYsIHNvIGl0cyB1bmRlbGl2ZXJlZCB2aW9sYXRpb25zIGNhbm5vdCBiZSByZWFkLiBBYnNlbmNlIG9mIGEgd2l0bmVzcyBsaW5lIGhlcmUgaXMgTk9UIGV2aWRlbmNlIHRoYXQgbm8gdmlvbGF0aW9uIGZpcmVkIFx1MjAxNCBpdCBpcyBldmlkZW5jZSB0aGF0IG5vYm9keSBjb3VsZCBsb29rLiBUaGUgbGluayBoYXMgdG8gbmFtZSB0aGVtOiB0aGUgdXNlci1pbWFnZSBleHBvcnQgbGlzdCBsaXZlcyBpbiBicmludGl1bSAoYnJpbnRsZCAtLWV4cG9ydC1pZi1kZWZpbmVkICsgdGhlIERDRSByb290cyksIHRoZSBrZXJuZWwgb25lIGluIHNjcmlwdHMvbGluay12bWxpbnV4LnNoLiIsZm91bmQ6W119O2xldCBjO3RyeXtjPW5ldyBVaW50OEFycmF5KHQuYnVmZmVyKX1jYXRjaChTKXtyZXR1cm57cmVhZGFibGU6ITEsd2h5OmB0aGUgaW1hZ2UncyBtZW1vcnkgY291bGQgbm90IGJlIHZpZXdlZDogJHtTIGluc3RhbmNlb2YgRXJyb3I/Uy5tZXNzYWdlOlN0cmluZyhTKX1gLGZvdW5kOltdfX1sZXQgaD0oKCk9Pnt0cnl7cmV0dXJuIG5ldyBJbnQzMkFycmF5KHQuYnVmZmVyKX1jYXRjaHtyZXR1cm4gbnVsbH19KSgpO2lmKGg9PT1udWxsKXJldHVybntyZWFkYWJsZTohMSx3aHk6Im5vIGkzMiB2aWV3IG9mIHRoZSBpbWFnZSBtZW1vcnkiLGZvdW5kOltdfTtsZXQgZz1bXSx4PXIoKFMsUix3KT0+e2lmKFIrND5jLmxlbmd0aHx8dz49Yy5sZW5ndGh8fChBdG9taWNzLmxvYWQoaCxSPj4yKXwwKSE9PTEpcmV0dXJuO2xldCB5PVN1KGMsdyw1MTIpO0V1LnNvbWUoRD0+eS5zdGFydHNXaXRoKEQpKSYmZy5wdXNoKHtsYW5lOlMsdGV4dDp5LnJlcGxhY2UoL1xuKyQvLCIiKX0pfSwiY29uc2lkZXIiKTtpZihfKXtsZXQgUz0yMDQ4O3RyeXtpZih0eXBlb2YgZS5fX2h3anNfbGFuZV9jYXA9PSJmdW5jdGlvbiIpe2xldCBSPWUuX19od2pzX2xhbmVfY2FwKCl8MDtSPjAmJlI8UyYmKFM9Uil9fWNhdGNoe31mb3IobGV0IFI9MDtSPFM7UisrKXgoUixvKzQqUixzKzUxMipSKX1yZXR1cm4gbSYmeCgtMSxsLGQpLHtyZWFkYWJsZTohMCx3aHk6IiIsZm91bmQ6Z319cihjYSwicmVhZFZpb2xhdGlvbldpdG5lc3MiKTtmdW5jdGlvbiB1YShlLHQpe2lmKCFlLnJlYWRhYmxlKXJldHVybmBod2pzLXdpdG5lc3MgJHt0fTogdGhlIHVuZGVsaXZlcmVkLXZpb2xhdGlvbiB3aXRuZXNzIGNvdWxkIG5vdCBiZSByZWFkIFx1MjAxNCAke2Uud2h5fWA7aWYoZS5mb3VuZC5sZW5ndGg9PT0wKXJldHVybiBudWxsO2xldCBvPWUuZm91bmQubWFwKHM9PmAgICR7cy5sYW5lPDA/Iih1bmxhbmVkKSI6YFtsYW5lICR7cy5sYW5lfV1gfSAke3MudGV4dH1gKTtyZXR1cm5gaHdqcy13aXRuZXNzICR7dH06ICR7ZS5mb3VuZC5sZW5ndGh9IHZpb2xhdGlvbiBzZW50ZW5jZShzKSB3ZXJlIGZvcm1hdHRlZCBhbmQgTkVWRVIgREVMSVZFUkVEIFx1MjAxNCB0aGUgcnVudGltZSBzZXQgaXRzIHBlbmRpbmcgd29yZCwgdHJpZWQgdG8gd3JpdGUoMikgdGhlbSB0byBmZCAyLCBhbmQgdGhlIHdyaXRlIGRpZCBub3QgcmVwb3J0IGV2ZXJ5IGJ5dGUgZ29uZS4gVGhleSBzYXkgd2hhdCB0aGUgdHJhcCBkb2VzIG5vdDoKJHtvLmpvaW4oYApgKX1gfXIodWEsImZvcm1hdFZpb2xhdGlvbldpdG5lc3MiKTt2YXIgTT17U1RBVEU6MCxOUjoxLEEwOjIsQTE6MyxBMjo0LEEzOjUsQTQ6NixBNTo3LFJFVF9MTzo5LFJFVF9ISToxMCxQSUQ6MTIsVElEOjEzfSxVcj0xLGRyPTIsa3M9MCwkdT02MCxmYT0yMzEsdnU9NTYsbmQ9MjAzLEF1PTEwNDAsSXU9MTA0MSxSdT0xMDQyLFR1PTEwNDMsX2E9MTA0NCxzZD0xMDQ1LGp1PTEwNDYsR3I9MTA0NyxEdT0xMDQ4LE51PTEwNDksZnQ9LTUxNywkZD0tNTEzLHhzPXIoZT0+ZT09PSJmb3JrLXJlc3VtZSJ8fGU9PT0idGhyZWFkInx8ZT09PSJtaWdyYXRlLXJlc3VtZSIsInJlcGxheXNNb2R1bGVHcmFwaCIpLHhhPTAsX3I9MSxWcj0yLEVhPTMscmQ9MWU0LG9kPTNlMyxhZD0xLGlkPTIsU2E9MyxMdT00LGxkPTU7ZnVuY3Rpb24gdmQoZSx0KXtmb3IoOzspe2xldCBvPUF0b21pY3MubG9hZChlLDApfDA7aWYobz09PVZyfHxvPT09RWEpcmV0dXJuITE7aWYoQXRvbWljcy5jb21wYXJlRXhjaGFuZ2UoZSwwLG8sRWEpPT09bylyZXR1cm4gQXRvbWljcy5zdG9yZShlLDIsdHwwKSxBdG9taWNzLm5vdGlmeShlLDApLCEwfX1yKHZkLCJtaWdBYm9ydCIpO3ZhciBLcj0xMDI3LE11PTEwMjgsT3U9MTAyOSxXdT0xMDMwLGRkPTQwODgsaGE9OCwkYT1udWxsO2Z1bmN0aW9uIEN1KGUpeyRhPWV9cihDdSwic2V0RXhlY0ltYWdlUmVzb2x2ZXIiKTt2YXIgUHU9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFsOiExfSksbWE9ODtmdW5jdGlvbiBCdShlLHQsbyxzLGwsZD0hMSl7bGV0IF89ZS5ieXRlTGVuZ3RoLG09dD4+PjAsYz1vPj4+MCxoPXM+Pj4wO2lmKGM9PT0wKXRocm93IG5ldyBFcnJvcihgaHdqcy1zY2F0dGVyOiAke2x9IGRlY2xhcmVzIDAgc2VnbWVudHMgKHNnbGlzdCAweCR7bS50b1N0cmluZygxNil9LCB0b3RhbCAke2h9QikgXHUyMDE0IGEgc3RhZ2VkIGltYWdlIGFsd2F5cyBoYXMgYXQgbGVhc3Qgb25lIHNlZ21lbnQ7IGtlcm5lbC9ob3N0IEFCSSBza2V3IChuZXZlci1zaWxlbnQpYCk7aWYoYz42NTUzNil0aHJvdyBuZXcgRXJyb3IoYGh3anMtc2NhdHRlcjogJHtsfSBkZWNsYXJlcyAke2N9IHNlZ21lbnRzLCBmYXIgcGFzdCB0aGUga2VybmVsJ3MgV0FTTTMyX0lNR19NQVhfU0VHUyBjYXAgXHUyMDE0IFJFRlVTRUQgYXMgYSB0b3JuIG9yIG1pc3JlYWQgcmVxdWVzdCAobmV2ZXItc2lsZW50KWApO2xldCBnPWMqbWE7aWYobT09PTB8fG0+X3x8Zz5fLW0pdGhyb3cgbmV3IEVycm9yKGBod2pzLXNjYXR0ZXI6ICR7bH0gc2VnbWVudCBsaXN0IFsweCR7bS50b1N0cmluZygxNil9LCArJHtnfUIpICgke2N9IHNlZ21lbnRzKSBpcyBvdXRzaWRlIGtlcm5lbCBtZW1vcnkgKCR7X31CKSBcdTIwMTQgUkVGVVNFRCAobmV2ZXItc2lsZW50KWApO2xldCB4PW5ldyBEYXRhVmlldyhlLG0sZyksUz1bXSxSPTA7Zm9yKGxldCBEPTA7RDxjO0QrKyl7bGV0IGRlPXguZ2V0VWludDMyKEQqbWEsITApPj4+MCx6PXguZ2V0VWludDMyKEQqbWErNCwhMCk+Pj4wO2lmKHo9PT0wKXRocm93IG5ldyBFcnJvcihgaHdqcy1zY2F0dGVyOiAke2x9IHNlZ21lbnQgJHtEfS8ke2N9IGhhcyBsZW5ndGggMCAob2Zmc2V0IDB4JHtkZS50b1N0cmluZygxNil9KSBcdTIwMTQgdGhlIGtlcm5lbCBuZXZlciBlbWl0cyBlbXB0eSBzZWdtZW50czsgUkVGVVNFRCAobmV2ZXItc2lsZW50KWApO2lmKGRlPT09MHx8ZGU+X3x8ej5fLWRlKXRocm93IG5ldyBFcnJvcihgaHdqcy1zY2F0dGVyOiAke2x9IHNlZ21lbnQgJHtEfS8ke2N9IGlzIFsweCR7ZGUudG9TdHJpbmcoMTYpfSwgKyR7en1CKSB3aGljaCBydW5zIHBhc3Qga2VybmVsIG1lbW9yeSAoJHtffUIpIFx1MjAxNCBSRUZVU0VEIChuZXZlci1zaWxlbnQpYCk7aWYoUis9eixSPmgpdGhyb3cgbmV3IEVycm9yKGBod2pzLXNjYXR0ZXI6ICR7bH0gc2VnbWVudHMgdGhyb3VnaCAke0R9LyR7Y30gYWxyZWFkeSBzdW0gdG8gJHtSfUIgYnV0IHRoZSBrZXJuZWwgZGVjbGFyZXMgJHtofUIgdG90YWwgXHUyMDE0IFJFRlVTRUQgKG5ldmVyLXNpbGVudClgKTtTLnB1c2goW2RlLHpdKX1pZihSIT09aCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtc2NhdHRlcjogJHtsfSBzZWdtZW50IGxlbmd0aHMgc3VtIHRvICR7Un1CIGJ1dCB0aGUga2VybmVsIGRlY2xhcmVzICR7aH1CIHRvdGFsIFx1MjAxNCBSRUZVU0VEIChuZXZlci1zaWxlbnQpYCk7bGV0IHc9bmV3IFVpbnQ4QXJyYXkoZD9uZXcgQXJyYXlCdWZmZXIoaCk6bmV3IFNoYXJlZEFycmF5QnVmZmVyKGgpKSx5PTA7Zm9yKGxldFtELGRlXW9mIFMpdy5zZXQobmV3IFVpbnQ4QXJyYXkoZSxELGRlKSx5KSx5Kz1kZTtyZXR1cm4gd31yKEJ1LCJyZWFkS2VybmVsU2NhdHRlckltYWdlIik7dmFyIEpyO2Z1bmN0aW9uIEFkKGUpe2lmKCEoZSYmZS5idWZmZXIgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcikpcmV0dXJuIGU7aWYoSnI9PT12b2lkIDApdHJ5e2xldCB0PW5ldyBVaW50OEFycmF5KG5ldyBTaGFyZWRBcnJheUJ1ZmZlcig4KSk7dC5zZXQoWzAsOTcsMTE1LDEwOSwxLDAsMCwwXSksbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZSh0KSxKcj0hMH1jYXRjaHtKcj0hMX1yZXR1cm4gSnI/ZTplLnNsaWNlKCl9cihBZCwid2FzbVNvdXJjZSIpO2Z1bmN0aW9uIGNyKGUsdCxvLHMsbD0hMSl7bGV0IGQ9ZVtgJHtvfV9zZ2xpc3RfYWRkcmBdLF89ZVtgJHtvfV9uc2Vnc2BdLG09ZVtgJHtvfV9pbWFnZV9zaXplYF07aWYodHlwZW9mIGQhPSJmdW5jdGlvbiJ8fHR5cGVvZiBfIT0iZnVuY3Rpb24ifHx0eXBlb2YgbSE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoYGh3anMtc2NhdHRlcjogdGhpcyB2bWxpbnV4IGRvZXMgbm90IGV4cG9ydCAke299X3NnbGlzdF9hZGRyLyR7b31fbnNlZ3MgXHUyMDE0IGl0IHByZWRhdGVzIHRoZSBzZWdtZW50LWxpc3Qgc3RhZ2luZyBBQkkgKG1lbW9yeS1jb250cmFjdCBQYXJ0IEMpIGFuZCB0aGlzIGhvc3QgaGFzIG5vIGZsYXQtaW1hZ2UgcGF0aC4gUmVidWlsZCB0aGUga2VybmVsIGFuZCB0aGUgaG9zdCB0b2dldGhlciAobmV2ZXItc2lsZW50KS5gKTtyZXR1cm4gQnUodCxkKCk+Pj4wLF8oKT4+PjAsbSgpPj4+MCxzLGwpfXIoY3IsInJlYWRLZXJuZWxTdGFnZWRJbWFnZSIpO2Z1bmN0aW9uIEVzKGUpe2xldCB0PXR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlcjwidSImJmUuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXI7cmV0dXJuIFB1LmRlY29kZSh0P2Uuc2xpY2UoKTplKX1yKEVzLCJkZWNvZGVNYXliZVNoYXJlZCIpO2FzeW5jIGZ1bmN0aW9uIEZ1KGUsdCl7bGV0IG89cihfPT50KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbYTRiXSAke199YH0pLCJyZXBvcnQiKSxzPTM5LGw9e29rOiExLGluc3RhbmNlczpbXSxub3RlczpbXX0sZD1yKChfLG0pPT4oe2tpbmQ6ImluaXQiLG1vZGU6ImZvcmsiLHBpZDowLHRpZDptLHBwaWQ6MCxjcHVJZDplLmNwdUlkfDAsdm1saW51eE1vZHVsZTplLnZtbGludXhNb2R1bGUsa2VybmVsTWVtb3J5OmUua2VybmVsTWVtb3J5LGtlcm5lbE1lbW9yeVdhc206ZS5rZXJuZWxNZW1vcnlXYXNtLG1lbW9yeTpffSksIm1rSW5pdCIpO3RyeXtvKGBpbnN0YW50aWF0aW5nIHZtbGludXggaW5zdGFuY2UgIzEgY3B1X2lkPSR7ZS5jcHVJZHwwfWApO2xldCBfPWF3YWl0IElhKGQoZS51c2VyTWVtb3J5QSwxMDAxKSx0KTtpZighXyl7bygiaW5zdGFuY2UgIzEgRkFJTEVEIHRvIGluc3RhbnRpYXRlIiksdCh7a2luZDoiYTRiLXJlc3VsdCIscmVzdWx0Omx9KTtyZXR1cm59bGV0IG09Xy5pbnN0YW5jZS5leHBvcnRzLndhc21fc3lzY2FsbChzLDAsMCwwLDAsMCwwKXwwO2wuaW5zdGFuY2VzLnB1c2goe2lkeDoxLGtlcm5lbFBpZDpfLmtlcm5lbFBpZHwwLHRhc2tBZGRyOl8ucGVyUHJvY2Vzc1Rhc2tBZGRyPj4+MCxnZXRwaWQ6bX0pLG8oYGluc3RhbmNlICMxOiBrZXJuZWxQaWQ9JHtfLmtlcm5lbFBpZHwwfSB0YXNrPTB4JHsoXy5wZXJQcm9jZXNzVGFza0FkZHI+Pj4wKS50b1N0cmluZygxNil9IGdldHBpZD0ke219YCksbygicmVzZXR0aW5nIHByb2Nlc3NWbWxpbnV4SW5zdGFuY2VDb3VudCAoQllQQVNTIFItSzEwLVcxKSBmb3IgaW5zdGFuY2UgIzIiKSxYcj0wLG8oYGluc3RhbnRpYXRpbmcgdm1saW51eCBpbnN0YW5jZSAjMiBjcHVfaWQ9JHtlLmNwdUlkfDB9IChzYW1lIGxhbmUpYCk7bGV0IGM9bnVsbDt0cnl7Yz1hd2FpdCBJYShkKGUudXNlck1lbW9yeUIsMTAwMiksdCl9Y2F0Y2godyl7byhgaW5zdGFuY2UgIzIgaW5zdGFudGlhdGUgVEhSRVc6ICR7dyBpbnN0YW5jZW9mIEVycm9yP3cubWVzc2FnZTpTdHJpbmcodyl9YCl9aWYoIWMpe28oImluc3RhbmNlICMyIEZBSUxFRCBcdTIwMTQgMm5kIHNhbWUtV29ya2VyIHZtbGludXggaW5zdGFudGlhdGlvbiBpcyBhIEhBUkQgYmxvY2tlciBmb3IgQXBwcm9hY2ggQSIpLGwubm90ZXMucHVzaCgic2Vjb25kLWluc3RhbmNlLWluc3RhbnRpYXRlLWZhaWxlZCIpLHQoe2tpbmQ6ImE0Yi1yZXN1bHQiLHJlc3VsdDpsfSk7cmV0dXJufWxldCBoPWMuaW5zdGFuY2UuZXhwb3J0cy53YXNtX3N5c2NhbGwocywwLDAsMCwwLDAsMCl8MDtsLmluc3RhbmNlcy5wdXNoKHtpZHg6MixrZXJuZWxQaWQ6Yy5rZXJuZWxQaWR8MCx0YXNrQWRkcjpjLnBlclByb2Nlc3NUYXNrQWRkcj4+PjAsZ2V0cGlkOmh9KSxvKGBpbnN0YW5jZSAjMjoga2VybmVsUGlkPSR7Yy5rZXJuZWxQaWR8MH0gdGFzaz0weCR7KGMucGVyUHJvY2Vzc1Rhc2tBZGRyPj4+MCkudG9TdHJpbmcoMTYpfSBnZXRwaWQ9JHtofWApO2xldCBnPV8uaW5zdGFuY2UuZXhwb3J0cy53YXNtX3N5c2NhbGwocywwLDAsMCwwLDAsMCl8MDtsLmluc3RhbmNlcy5wdXNoKHtpZHg6MSxwaGFzZToiYWZ0ZXItMiIsZ2V0cGlkOmd9KSxvKGBpbnN0YW5jZSAjMSByZS1nZXRwaWQgYWZ0ZXIgIzI6IGdldHBpZD0ke2d9IChleHBlY3QgPT0gJHttfSlgKTtsZXQgeD1fLnBlclByb2Nlc3NUYXNrQWRkcj4+PjAhPT1jLnBlclByb2Nlc3NUYXNrQWRkcj4+PjAsUz1tIT09aCxSPW09PT1nO2wuZGlzdGluY3RUYXNrcz14LGwuZGlzdGluY3RQaWRzPVMsbC5pbnN0MUludGFjdD1SLGwub2s9eCYmUyYmUixvKGBDT0VYSVNUOiBkaXN0aW5jdFRhc2tzPSR7eH0gZGlzdGluY3RQaWRzPSR7U30gaW5zdDFJbnRhY3Q9JHtSfSA9PiAke2wub2s/Ik9LIjoiQlJPS0VOIn1gKX1jYXRjaChfKXtsLmVycm9yPV8gaW5zdGFuY2VvZiBFcnJvcj9gJHtfLm1lc3NhZ2V9CiR7Xy5zdGFja31gOlN0cmluZyhfKSxvKGBQUk9CRSBUSFJFVzogJHtsLmVycm9yfWApfXQoe2tpbmQ6ImE0Yi1yZXN1bHQiLHJlc3VsdDpsfSl9cihGdSwicnVuQTRiQ29leGlzdFByb2JlIik7dmFyIHhuPW51bGwsZW49bmV3IE1hcCx2cz1uZXcgTWFwO2Z1bmN0aW9uIFFyKGUsdCl7aWYoQXJyYXkuaXNBcnJheShlKSlmb3IobGV0IG8gb2YgZSl7aWYoIW98fHR5cGVvZiBvLmRpZ2VzdCE9InN0cmluZyJ8fCFvLmJ5dGVzKWNvbnRpbnVlO2xldCBzPWVuLmdldChvLmRpZ2VzdCksbD1XbChzLG8pO2lmKCFzKXtlbi5zZXQoby5kaWdlc3QsbCk7dHJ5e3QmJnQoe2tpbmQ6ImRtZXNnIixsZXZlbDo3LHRleHQ6YGh3anMtbGliYzogc2hhcmVkLWxpYiBzdG9yZSBnYWluZWQgZGlnZXN0ICR7by5kaWdlc3Quc2xpY2UoMCwxNil9XHUyMDI2ICgke28uYnl0ZXMubGVuZ3RofUI7IHN0b3JlIHNpemUgJHtlbi5zaXplfSlgfSl9Y2F0Y2h7fX19fXIoUXIsInNoYXJlZExpYnNNZXJnZSIpO3ZhciBJZD17aHdqc0V4aXRVbndpbmQ6ITB9LHZhPXtod2pzRXhlY1Vud2luZDohMH07ZnVuY3Rpb24gU3MoZSl7cmV0dXJuIGU9PT1JZHx8ZT09PXZhfXIoU3MsImlzRGVzaWduZWRVbndpbmQiKTtmdW5jdGlvbiBIdShlLHQpe2xldCBzPWUuY3B1SWR8MDtRcihlLnNoYXJlZExpYnMsdCksTmQoZS51c2VySW1hZ2VzKTtsZXQgbD1uZXcgTWFwLGQ9bmV3IE1hcCxfPXtibG9ja3M6MCxzd2l0Y2hlczowLGJ5VGlkOnt9LGFkZHM6MCxkb25lczowfSxtPXIodz0+e3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbY3B1LXdvcmtlciBjcHU9JHtzfV0gJHt3fWB9KX1jYXRjaHt9fSwiZGJnIiksYz17Y3B1SWQ6cyxyZXNpZGVudFRhc2tzOmwsYXN5bmMgYmxvY2tZaWVsZCh3LHkpe2xldCBEPWwuZ2V0KHcpO0QmJkQuc3RhdHVzIT09ImRvbmUiJiYoRC5zdGF0dXM9ImJsb2NrZWQiKSxfLmJsb2NrcysrLF8uYnlUaWRbd109KF8uYnlUaWRbd118MCkrMTtsZXQgZGU9aXQ/VW4oKTowO0N0KHQsYFlJRUxEIGNwdT0ke3N9IHRpZD0ke3d9IHJlYXNvbj0ke3k/PyJibG9ja1lpZWxkIn0gc2l0ZT1zY2hlZC5ibG9ja1lpZWxkIHNsaWNlPTNtc2ApLGF3YWl0IG5ldyBQcm9taXNlKHo9PnNldFRpbWVvdXQoeiwzKSksaXQmJkN0KHQsYFJFU1VNRSBjcHU9JHtzfSB0aWQ9JHt3fSBzaXRlPXNjaGVkLmJsb2NrWWllbGQgd2FpdGVkPSR7KFVuKCktZGUpLnRvRml4ZWQoMSl9bXNgKSxEJiZELnN0YXR1cyE9PSJkb25lIiYmKEQuc3RhdHVzPSJydW5uYWJsZSIpLF8uc3dpdGNoZXMrK319LGg9UXUoe2NwdUlkOnMscmVzaWRlbnRzOnIoKCk9PmwudmFsdWVzKCksInJlc2lkZW50cyIpLGVtaXQ6cigodyx5KT0+dCh7a2luZDoiZG1lc2ciLGxldmVsOncsdGV4dDp5fSksImVtaXQiKSxtZXJnZWRDcHUwTGFuZTplLm1lcmdlZENwdTBMYW5lPT09ITB9KSxnPXIodz0+e2xldCB5PXcudGlkO2lmKHcuY2xhaW0pe2xldCBVPW5ldyBJbnQzMkFycmF5KHcuY2xhaW0pLGZlPUF0b21pY3MuY29tcGFyZUV4Y2hhbmdlKFUsMCwwLDIpO2lmKGZlIT09MCl7bShgaHdqcyMzOiBhZGQtdGFzayByb3V0ZUtleT0ke3cucm91dGVLZXl9IHRpZD0ke3l9IERFQ0xJTkVEIChjbGFpbT0ke2ZlfTogaG9zdCBjYW5jZWxlZCBhZnRlciBsYW5lLXN0YXJ2YXRpb24gdGltZW91dCBhbmQgcmUtcGxhY2VkIHRoZSB0YXNrOyB0aGlzIHN0YWxlIHBsYWNlbWVudCBpcyBkcm9wcGVkKWApO3JldHVybn1BdG9taWNzLm5vdGlmeShVLDApfWlmKHcubW9kZT09PSJtaWdyYXRlLXJlc3VtZSIpe2lmKCEody5taWcgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcikpe3Qoe2tpbmQ6ImVycm9yIixyb3V0ZUtleTp3LnJvdXRlS2V5LHRpZDp5LG1lc3NhZ2U6YGFkZC10YXNrIFJFRlVTRUQ6IG1vZGU9J21pZ3JhdGUtcmVzdW1lJyBmb3IgdGlkPSR7eX0gY2FycmllcyBubyBtaWdyYXRpb24gcHJvdG9jb2wgd29yZC4gQSBtaWdyYXRpb24gaGFuZC1vZmYgaXMgYSB0d28tcGhhc2UgY29tbWl0IGFuZCB0aGUgd29yZCBJUyB0aGUgY29tbWl0OyB3aXRob3V0IGl0IHRoaXMgbGFuZSB3b3VsZCBzdGFydCBkcml2aW5nIGEgdGFzayB0aGUgc291cmNlIHN0aWxsIGJlbGlldmVzIGl0IG93bnMgKG5ldmVyLXNpbGVudCkuYH0pO3JldHVybn1sZXQgVT1uZXcgSW50MzJBcnJheSh3Lm1pZyk7aWYoQXRvbWljcy5zdG9yZShVLDMsMSksQXRvbWljcy5jb21wYXJlRXhjaGFuZ2UoVSwwLHhhLF9yKSE9PXhhKXttKGBod2pzLW1pZ3JhdGU6IGFkZC10YXNrIHJvdXRlS2V5PSR7dy5yb3V0ZUtleX0gdGlkPSR7eX0gREVDTElORUQgKG9mZmVyIGFscmVhZHkgdGVybWluYWw6IHN0YXRlPSR7QXRvbWljcy5sb2FkKFUsMCl8MH0pOyB0aGUgc291cmNlIGtlcHQgdGhlIHRhc2tgKTtyZXR1cm59QXRvbWljcy5ub3RpZnkoVSwwKTt0cnl7aWYodHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudiYmcHJvY2Vzcy5lbnYuSFdKU19NSUdSQVRFX1JFRF9EUk9QPT09IjEiKXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLW1pZ3JhdGUgUkVEX0RST1A6IGNwdT0ke3N9IENMQUlNRUQgdGlkPSR7eX0gYW5kIGlzIGFiYW5kb25pbmcgaXQgd2l0aG91dCBiaW5kaW5nIFx1MjAxNCBzaW11bGF0aW5nIGEgZGVzdGluYXRpb24gdGhhdCBkaWVzIGluc2lkZSB0aGUgY29tbWl0IHdpbmRvdyAodGVzdCBrbm9iKWB9KTtyZXR1cm59fWNhdGNoe319aWYoKHcubW9kZXx8ImZvcmsiKT09PSJ0aHJlYWQiKXtsZXQgVT1bInVzZXJMYW5lIiwiYXJnUmVnaW9uT2Zmc2V0Iiwic3RhY2tQb2ludGVyT2Zmc2V0IiwidGxzUG9pbnRlck9mZnNldCJdLmZpbHRlcihmZT0+dHlwZW9mIHdbZmVdIT0ibnVtYmVyIik7aWYoVS5sZW5ndGg+MHx8KHcudXNlckxhbmV8MCk8PTApe2xldCBmZT1VLmxlbmd0aD4wP2BtaXNzaW5nL25vbi1udW1lcmljIGZpZWxkKHMpOiAke1Uuam9pbigiLCAiKX1gOmB1c2VyTGFuZT0ke3cudXNlckxhbmV8MH0gKGEgY28tcmVzaWRlbnQgdGhyZWFkIE1VU1QgY2FycnkgYSBrZXJuZWwtYWxsb2NhdGVkIHVzZXItUlQgbGFuZSA+IDA7IGxhbmUgMCBpcyB0aGUgcHJvY2VzcyBtYWluJ3Mgc2luZ2xlLXNsb3Qgc2hhcGUgYW5kIGNhbm5vdCBiZSBzaGFyZWQpYDt0KHtraW5kOiJlcnJvciIscm91dGVLZXk6dy5yb3V0ZUtleSx0aWQ6eSxtZXNzYWdlOmBhZGQtdGFzayBSRUZVU0VEOiBtb2RlPSd0aHJlYWQnIHNwZWMgZm9yIHRpZD0ke3l9IHJvdXRlS2V5PSR7dy5yb3V0ZUtleX0gaXMgaW5jb21wbGV0ZSBcdTIwMTQgJHtmZX0uIEEgdGhyZWFkIHRhc2sgaW5pdCBpcyBvbmx5IHdlbGwtZm9ybWVkIHdpdGggdXNlckxhbmUgKyBhcmdSZWdpb25PZmZzZXQgKyBzdGFja1BvaW50ZXJPZmZzZXQgKyB0bHNQb2ludGVyT2Zmc2V0OyBkZWZhdWx0aW5nIGFueSBvZiB0aGVtIHdvdWxkIHJ1biB0aGUgdGhyZWFkIG92ZXIgYSBnYXJiYWdlIGFyZyByZWdpb24gb24gdGhlIHByb2Nlc3MgbWFpbidzIGxhbmUgKG5ldmVyLXNpbGVudCkuYH0pO3JldHVybn19aWYoeCl7dCh7a2luZDoiZXJyb3IiLHJvdXRlS2V5Oncucm91dGVLZXksdGlkOnksbWVzc2FnZTpgYWRkLXRhc2sgUkVGVVNFRDogdGhpcyBDUFUtV29ya2VyIHJlYWxtIChjcHU9JHtzfSkgaGFzIGJlZW4gY29vcGVyYXRpdmVseSBTVE9QUEVEICh0aGUgbWFjaGluZSBpcyB0ZWFyaW5nIGRvd24gYW5kIHRoaXMgbGFuZSBoYXMgbm8gV29ya2VyIHRvIHRlcm1pbmF0ZSBcdTIwMTQgUExBTi1DT0xMQVBTRUQtQ1BVMCBceEE3NSkuIFRoZSB0YXNrIHdvdWxkIG5ldmVyIGJlIGRyaXZlbjsgcmVmdXNpbmcgaXQgaXMgd2hhdCBtYWtlcyB0aGF0IHZpc2libGUgdG8gdGhlIHBsYWNlciBpbnN0ZWFkIG9mIHByZXNlbnRpbmcgYXMgYSB0YXNrIHRoYXQgd2FzIHBsYWNlZCBhbmQgbmV2ZXIgcmFuLmB9KTtyZXR1cm59Xy5hZGRzKys7dHJ5e3R5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYuQTRDX0RCRyYmY29uc29sZS5lcnJvcihgW2E0Yy13XSBhZGRUYXNrIHRpZD0ke3l9IHJvdXRlS2V5PSR7dy5yb3V0ZUtleX0gbW9kZT0ke3cubW9kZX0gY3B1PSR7c31gKX1jYXRjaHt9dHJ5e3R5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYuQTRDX0ZPUktEQkcmJnQoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YFthNGMtZm9ya10gYWRkVGFzayB0aWQ9JHt5fSByb3V0ZUtleT0ke3cucm91dGVLZXl9IG1vZGU9JHt3Lm1vZGV9IGNwdT0ke3N9IChydW4oKSB3aWxsIGluc3RhbnRpYXRlK2RyaXZlKWB9KX1jYXRjaHt9bC5zZXQoeSx7dGlkOnksc3RhdHVzOiJydW5uYWJsZSIsYXJndjp3LmFyZ3Z9KSxoLmhvc3RpbmcoKSxDdCh0LGBBREQgY3B1PSR7c30gdGlkPSR7eX0gcGlkPSR7dy5waWQhPW51bGw/dy5waWQ6eX0gbW9kZT0ke3cubW9kZXx8ImZvcmsifSBsYW5lPSR7dy51c2VyTGFuZT8/MH0gcm91dGVLZXk9JHt3LnJvdXRlS2V5fSByZXNpZGVudHM9JHtsLnNpemV9YCk7bGV0IEQ9dy5yb3V0ZUtleSxkZT1yKFU9Pnt0cnl7dChEIT1udWxsP3suLi5VLHJvdXRlS2V5OkR9OnsuLi5VLHRpZDp5fSl9Y2F0Y2h7fX0sInRhc2tQb3N0Iiksej17a2luZDoiaW5pdCIsbW9kZTp3Lm1vZGV8fCJmb3JrIixwaWQ6dy5waWQhPW51bGw/dy5waWQ6eSx0aWQ6eSxwcGlkOncucHBpZHwwLGNwdUlkOnMsd2FzbUJ5dGVzOncud2FzbUJ5dGVzLG1lbW9yeTp3Lm1lbW9yeSxjdHJsOncuY3RybCx2bWxpbnV4TW9kdWxlOmUudm1saW51eE1vZHVsZSxod2pzUnRNb2R1bGU6ZS5od2pzUnRNb2R1bGUsaHdqc1J0Qnl0ZXM6ZS5od2pzUnRCeXRlcyxod2pzUnRQcm92ZW5hbmNlOmUuaHdqc1J0UHJvdmVuYW5jZSxrZXJuZWxNZW1vcnk6ZS5rZXJuZWxNZW1vcnksa2VybmVsTWVtb3J5V2FzbTplLmtlcm5lbE1lbW9yeVdhc20sLi4uZS5rZXJuZWxMYW5lTG9ja3MhPT12b2lkIDA/e2tlcm5lbExhbmVMb2NrczplLmtlcm5lbExhbmVMb2Nrc306e30sLi4uZS5tZXJnZWRDcHUwTGFuZT09PSEwP3ttZXJnZWRDcHUwTGFuZTohMH06e30sLi4uRCE9bnVsbD97cm91dGVLZXk6RH06e30sYWxsb3dNdWx0aUluc3RhbmNlOiEwLC4uLncuZm9yY2VXYXNtU3lzY2FsbD97Zm9yY2VXYXNtU3lzY2FsbDohMH06e30sLi4udy5tb2RlP3ttb2RlOncubW9kZX06e30sLi4uQXJyYXkuaXNBcnJheSh3LmFyZ3YpP3thcmd2OncuYXJndn06e30sLi4uQXJyYXkuaXNBcnJheSh3LmVudnApP3tlbnZwOncuZW52cH06e30sLi4uQXJyYXkuaXNBcnJheSh3Lmxvd0ZkUm91dGVzKT97bG93RmRSb3V0ZXM6dy5sb3dGZFJvdXRlc306e30sLi4udy5zaWduYWxQZW5kaW5nT2Zmc2V0IT09dm9pZCAwP3tzaWduYWxQZW5kaW5nT2Zmc2V0Oncuc2lnbmFsUGVuZGluZ09mZnNldH06e30sLi4udy5pbmhlcml0RmlsZXMhPT12b2lkIDA/e2luaGVyaXRGaWxlczp3LmluaGVyaXRGaWxlc306e30sLi4uQXJyYXkuaXNBcnJheSh3LmZkQWN0aW9ucyk/e2ZkQWN0aW9uczp3LmZkQWN0aW9uc306e30sLi4udy50bHNCYXNlIT09dm9pZCAwP3t0bHNCYXNlOncudGxzQmFzZX06e30sLi4udy5mb3JrSGFuZGxlIT09dm9pZCAwP3tmb3JrSGFuZGxlOncuZm9ya0hhbmRsZX06e30sLi4udy5mb3JrT3duZXIhPT12b2lkIDA/e2ZvcmtPd25lcjp3LmZvcmtPd25lcn06e30sLi4udy5wYXJlbnRTcCE9PXZvaWQgMD97cGFyZW50U3A6dy5wYXJlbnRTcH06e30sLi4udy5mb3JrTGFuZSE9PXZvaWQgMD97Zm9ya0xhbmU6dy5mb3JrTGFuZX06e30sLi4udy5taWchPT12b2lkIDA/e21pZzp3Lm1pZ306e30sLi4udy5taWdyYXRlVGFza0FkZHIhPT12b2lkIDA/e21pZ3JhdGVUYXNrQWRkcjp3Lm1pZ3JhdGVUYXNrQWRkcn06e30sLi4udy5taWdyYXRlUGlkIT09dm9pZCAwP3ttaWdyYXRlUGlkOncubWlncmF0ZVBpZH06e30sLi4udy5zcCE9PXZvaWQgMD97c3A6dy5zcH06e30sLi4udy5tb2RlPT09Im1pZ3JhdGUtcmVzdW1lIiYmdy51c2VyTGFuZSE9PXZvaWQgMD97dXNlckxhbmU6dy51c2VyTGFuZXwwfTp7fSwuLi53LmRsb3BlbkZvcmsmJnR5cGVvZiB3LmRsb3BlbkZvcms9PSJvYmplY3QiP3tkbG9wZW5Gb3JrOncuZGxvcGVuRm9ya306e30sLi4udy5od2pzUnRXaW5kb3dCYXNlIT09dm9pZCAwP3tod2pzUnRXaW5kb3dCYXNlOncuaHdqc1J0V2luZG93QmFzZSxod2pzUnRXaW5kb3dTaXplOncuaHdqc1J0V2luZG93U2l6ZX06e30sLi4udy5od2pzTGliY1dpbmRvd0Jhc2UhPT12b2lkIDA/e2h3anNMaWJjV2luZG93QmFzZTp3Lmh3anNMaWJjV2luZG93QmFzZSxod2pzTGliY1dpbmRvd1NpemU6dy5od2pzTGliY1dpbmRvd1NpemV9Ont9LC4uLih3Lm1vZGV8fCJmb3JrIik9PT0idGhyZWFkIj97dXNlckxhbmU6dy51c2VyTGFuZXwwLGFyZ1JlZ2lvbk9mZnNldDp3LmFyZ1JlZ2lvbk9mZnNldHwwLHN0YWNrUG9pbnRlck9mZnNldDp3LnN0YWNrUG9pbnRlck9mZnNldHwwLHRsc1BvaW50ZXJPZmZzZXQ6dy50bHNQb2ludGVyT2Zmc2V0fDAsLi4udHlwZW9mIHcubWFpblRsc1Nsb3Q9PSJudW1iZXIiP3ttYWluVGxzU2xvdDp3Lm1haW5UbHNTbG90fTp7fX06e30sLi4uZS5wYXVzZUJ1ZmZlciE9PXZvaWQgMD97cGF1c2VCdWZmZXI6ZS5wYXVzZUJ1ZmZlcn06e319LFE9cihVPT57aWYody5tb2RlIT09Im1pZ3JhdGUtcmVzdW1lInx8ISh3Lm1pZyBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKSlyZXR1cm47bGV0IGZlPW5ldyBJbnQzMkFycmF5KHcubWlnKTt2ZChmZSxVKSYmdCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgaHdqcy1taWdyYXRlOiBjcHU9JHtzfSB0aWQ9JHt5fSBGQUlMRUQgdG8gYmluZCB0aGUgbWlncmF0ZWQgdGFzayBhbmQgcmVsZWFzZWQgdGhlIG9mZmVyIChhYm9ydCBjb2RlICR7VX0pIFx1MjAxNCB0aGUgc291cmNlIG5ldmVyIHJlbGVhc2VkIGl0IGFuZCByZXN1bWVzIGRyaXZpbmcgaXQgKGxvdWQsIGF0dHJpYnV0ZWQpYH0pfSwicmVsZWFzZU9mZmVyIik7VGQoeixkZSxjKS50aGVuKCgpPT57UShTYSk7bGV0IFU9bC5nZXQoeSk7VSYmKFUuc3RhdHVzPSJkb25lIiksbC5kZWxldGUoeSksZC5kZWxldGUoeSksdnMuZGVsZXRlKHopLF8uZG9uZXMrKyxDdCh0LGBET05FIGNwdT0ke3N9IHRpZD0ke3l9IHJlc2lkZW50cz0ke2wuc2l6ZX1gKSxsLnNpemU9PT0wJiZoLmNlbnN1cygpfSxVPT57UShTYSk7bGV0IGZlPWwuZ2V0KHkpO2ZlJiYoZmUuc3RhdHVzPSJlcnJvciIpLGwuZGVsZXRlKHkpLGQuZGVsZXRlKHkpLHZzLmRlbGV0ZSh6KSxDdCh0LGBET05FIGNwdT0ke3N9IHRpZD0ke3l9IHN0YXR1cz1lcnJvciByZXNpZGVudHM9JHtsLnNpemV9YCksbC5zaXplPT09MCYmaC5jZW5zdXMoKSxkZSh7a2luZDoiZXJyb3IiLG1lc3NhZ2U6YGNwdS13b3JrZXIgdGFzayB0aWQ9JHt5fTogJHtVIGluc3RhbmNlb2YgRXJyb3I/YCR7VS5tZXNzYWdlfQoke1Uuc3RhY2t9YDpTdHJpbmcoVSl9YH0pfSl9LCJhZGRUYXNrIikseD0hMTt4bj17Y3B1SWQ6cyxyZXNpZGVudFRhc2tzOmwsc2NoZWQ6YyxhZGRUYXNrOmcsZXhlY1Jlc29sdmVyczpkLHN0YXRzOl8sZGJnOm0sc3RvcDpyKCgpPT57aWYoIXgpe3g9ITA7dHJ5e2NsZWFySW50ZXJ2YWwoUil9Y2F0Y2h7fW0oYGNvb3BlcmF0aXZlIHN0b3A6ICR7bC5zaXplfSByZXNpZGVudChzKSBrZWVwIHJ1bm5pbmcgdG8gdGhlaXIgb3duIGV4aXQ7IG5vIGZ1cnRoZXIgcGxhY2VtZW50IGlzIGFjY2VwdGVkIG9uIHRoaXMgbGFuZWApfX0sInN0b3BDcHVXb3JrZXIiKSxpc1N0b3BwZWQ6cigoKT0+eCwiaXNTdG9wcGVkIil9O2xldCBSPXNldEludGVydmFsKCgpPT57bGV0IHc9aC5iZWF0KCk7aWYoaXQpe2xldCB5PVsuLi5sLnZhbHVlcygpXS5tYXAoRD0+YCR7RC50aWR9OiR7RC5zdGF0dXN9YCkuam9pbigiLCIpfHwibm9uZSI7Q3QodCxgQkVBVCBjcHU9JHtzfSAjJHtoLnN0YXRzKCkuYmVhdHN9IGdhcD0ke3cudG9GaXhlZCgxKX1tcyBwZXJpb2Q9JHt1ZH1tcyByZXNpZGVudHM9WyR7eX1dIGFkZHM9JHtfLmFkZHN9IGRvbmVzPSR7Xy5kb25lc30gYmxvY2tzPSR7Xy5ibG9ja3N9IHN3aXRjaGVzPSR7Xy5zd2l0Y2hlc31gKX19LHVkKTt0cnl7Uj8udW5yZWY/LigpfWNhdGNoe310cnl7dHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudi5BNENfREJHJiZjb25zb2xlLmVycm9yKGBbYTRjLXddIHN0YXJ0Q3B1V29ya2VyIGNwdT0ke3N9IHJlYWR5YCl9Y2F0Y2h7fW0oYHBvb2wgV29ya2VyIHJlYWR5IChjcHVfaWQ9JHtzfSk7IGF3YWl0aW5nIGFkZC10YXNrYCk7Zm9yKGxldCB3IG9mIEFycmF5LmlzQXJyYXkoZS50YXNrcyk/ZS50YXNrczpbXSlnKHcpfXIoSHUsInN0YXJ0Q3B1V29ya2VyIik7ZnVuY3Rpb24gUmQoe3Bvc3Q6ZSxvbk1lc3NhZ2U6dCxvblRlcm1pbmF0ZTpvLGNhbGxIb3N0U3luYzpzfSl7RGQ9ZSxObj10eXBlb2Ygcz09ImZ1bmN0aW9uIj9zOm51bGwsbz8uKCgpPT57eG4/LnN0b3A/LigpfSksdChhc3luYyBsPT57dHJ5e2lmKGw/LmtpbmQ9PT0iZXhlYy1pbWFnZSIpe2lmKHhuJiZsLnRpZCE9bnVsbCYmeG4uZXhlY1Jlc29sdmVycy5oYXMobC50aWQpKXtsZXQgXz14bi5leGVjUmVzb2x2ZXJzLmdldChsLnRpZCk7eG4uZXhlY1Jlc29sdmVycy5kZWxldGUobC50aWQpLF8mJl8obCk7cmV0dXJufWxldCBkPSRhOyRhPW51bGwsZCYmZChsKTtyZXR1cm59aWYobD8ua2luZD09PSJhNGItY29leGlzdCIpe2F3YWl0IEZ1KGwsZSk7cmV0dXJufWlmKGw/LmtpbmQ9PT0iY3B1LXdvcmtlciIpe0h1KGwsZSk7cmV0dXJufWlmKGw/LmtpbmQ9PT0iYWRkLXRhc2siKXtpZigheG4pe2Uoe2tpbmQ6ImVycm9yIixwaWQ6LTEsbWVzc2FnZToiYWRkLXRhc2sgYmVmb3JlIGNwdS13b3JrZXIgaW5pdCJ9KTtyZXR1cm59eG4uYWRkVGFzayhsLnNwZWN8fGwpO3JldHVybn1pZihsPy5raW5kPT09InNoYXJlZC1saWIiKXtRcihsLnNoYXJlZExpYnMsZSk7cmV0dXJufWlmKGw/LmtpbmQ9PT0idXNlci1pbWFnZSIpe05kKGwudXNlckltYWdlcyk7cmV0dXJufWlmKGw/LmtpbmQ9PT0idGhyZWFkLXBsYWNlbWVudC1yZXF1ZXN0Iil7bGV0IGQ9bC5waWR8MCxfPWwuc2VxfDAsbT1sLnJvdXRlS2V5IT09dm9pZCAwP3tyb3V0ZUtleTpsLnJvdXRlS2V5fTp7fSxjPW51bGw7Zm9yKGxldCBoIG9mIHZzLnZhbHVlcygpKWlmKChoLmdldFBpZCgpfDApPT09ZCl7Yz1oO2JyZWFrfWlmKCFjKXtlKHtraW5kOiJ0aHJlYWQtcGxhY2VtZW50IixzZXE6XyxwaWQ6ZCwuLi5tLGVycm9yOmBubyByZXNpZGVudCB0YXNrIHdpdGgga2VybmVsIHBpZCAke2R9IGluIHRoaXMgV29ya2VyIFx1MjAxNCB0aHJlYWQtcGxhY2VtZW50LXJlcXVlc3QgY2Fubm90IGJlIHNlcnZlZCAobmV2ZXItc2lsZW50KWB9KTtyZXR1cm59dHJ5e2Uoe2tpbmQ6InRocmVhZC1wbGFjZW1lbnQiLHNlcTpfLHBpZDpkLC4uLm0sZGxvcGVuRm9yazpjLmJ1aWxkKCl9KX1jYXRjaChoKXtlKHtraW5kOiJ0aHJlYWQtcGxhY2VtZW50IixzZXE6XyxwaWQ6ZCwuLi5tLGVycm9yOiJ0aHJlYWQtcGxhY2VtZW50IHNuYXBzaG90IGZhaWxlZDogIisoaCBpbnN0YW5jZW9mIEVycm9yP2gubWVzc2FnZTpTdHJpbmcoaCkpfSl9cmV0dXJufWlmKGw/LmtpbmQ9PT0idGFzay1wcm9iZSIpe2xldCBkPWwuc2VxfDAsXz1bXTtmb3IobGV0IG0gb2YgdnMudmFsdWVzKCkpe2xldCBjPW0uZ2V0UGlkKCl8MDtpZih0eXBlb2YgbS5wcm9iZSE9ImZ1bmN0aW9uIil7Xy5wdXNoKHtwaWQ6Yyxwcm9iZVJlYWR5OiExfSk7Y29udGludWV9dHJ5e18ucHVzaCh7Li4ubS5wcm9iZSgpLHByb2JlUmVhZHk6ITB9KX1jYXRjaChoKXtfLnB1c2goe3BpZDpjLHByb2JlUmVhZHk6ITEsZXJyb3I6aCBpbnN0YW5jZW9mIEVycm9yP2gubWVzc2FnZTpTdHJpbmcoaCl9KX19ZSh7a2luZDoidGFzay1wcm9iZS1yZXBseSIsc2VxOmQsY3B1SWQ6eG4/eG4uY3B1SWQ6bnVsbCxyZXNpZGVudHM6eG4/Wy4uLnhuLnJlc2lkZW50VGFza3MudmFsdWVzKCldLm1hcChtPT4oe3RpZDptLnRpZHwwLHN0YXR1czpTdHJpbmcobS5zdGF0dXMpfSkpOm51bGwsc2NoZWRTdGF0czp4bj97Li4ueG4uc3RhdHN9Om51bGwsaXNvbGF0ZU1vZHVsZUNhY2hlczpNZCgpLHRhc2tzOl99KTtyZXR1cm59aWYobD8ua2luZCE9PSJpbml0Iil7ZSh7a2luZDoiZXJyb3IiLHBpZDotMSxtZXNzYWdlOmB1bmtub3duIG1zZyAke2w/LmtpbmR9YH0pO3JldHVybn10cnl7YXdhaXQgVGQobCxlKX1maW5hbGx5e3ZzLmRlbGV0ZShsKX19Y2F0Y2goZCl7ZSh7a2luZDoiZXJyb3IiLHBpZDpsPy5waWQ/Py0xLG1lc3NhZ2U6ZCBpbnN0YW5jZW9mIEVycm9yP2Ake2QubWVzc2FnZX0KJHtkLnN0YWNrPz8iIn1gOlN0cmluZyhkKX0pfX0pfXIoUmQsImJpbmRXb3JrZXIiKTt2YXIgWHI9MCxVdT0oKCk9PntsZXQgZT10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52LkhXSlNfSU5JVElBTF9CVURHRVR8fCIiLHQ9cGFyc2VJbnQoZSwxMCk7cmV0dXJuIE51bWJlci5pc0Zpbml0ZSh0KSYmdD4wP3Q6MTw8MjB9KSgpLHFyPSgoKT0+e2xldCBlPXR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYuSFdKU19JTklUSUFMX0JVREdFVHx8IiIsdD1wYXJzZUludChlLDEwKTtyZXR1cm4gTnVtYmVyLmlzRmluaXRlKHQpJiZ0PjA/dDoxNjM4NH0pKCkscGE9KCgpPT57bGV0IGU9dHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudi5IV0pTX1NQX1JFRklMTHx8IiIsdD1wYXJzZUludChlLDEwKTtyZXR1cm4gTnVtYmVyLmlzRmluaXRlKHQpJiZ0PjA/dDpxcn0pKCksR3U9dHlwZW9mIHByb2Nlc3M8InUiJiYhIXByb2Nlc3MuZW52LkhXSlNfTk9fU1BfWUlFTEQsS3U9Z2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfWE1PRF9DT05TVUxUX1RSQUNFPT09IjEiLHpyPWdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX0ZQQ0FTVF9UUkFDRT09PSIxIixKdT0xLHp1PW5ldyBVaW50OEFycmF5KFswLDk3LDExNSwxMDksMSwwLDAsMCwxLDUsMSw5NiwwLDEsMTI3LDIsNywxLDEsMTAxLDEsMTAyLDAsMCwzLDIsMSwwLDQsNCwxLDExMiwwLDEsNywxNywzLDQsMTA4LDk3LDExMCwxMDEsMCwxLDEsMTE2LDEsMCwyLDEwMiw5OCwwLDAsOSw3LDEsMCw2NSwwLDExLDEsMCwxMCw5LDEsNywwLDY1LDAsMTcsMCwwLDExXSksd2E9bnVsbCxZdT10eXBlb2YgcHJvY2VzczwidSImJiEhcHJvY2Vzcy5lbnYuSFdKU19OT19SRUNMQUlNX1JFVFJZLFZ1PSgoKT0+e2xldCBlPXR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYuSFdKU19SRUNMQUlNX1JFVFJZX1JPVU5EUz9wYXJzZUludChwcm9jZXNzLmVudi5IV0pTX1JFQ0xBSU1fUkVUUllfUk9VTkRTLDEwKTpOYU47cmV0dXJuIE51bWJlci5pc0Zpbml0ZShlKSYmZT49MSYmZTw9MTA/ZTozfSkoKSxjZD1bNTAsNTAwLDJlM10sQWE9dHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudi5IV0pTX1RFU1RfR1JPV19GQUlMX01JTlBBR0VTP3BhcnNlSW50KHByb2Nlc3MuZW52LkhXSlNfVEVTVF9HUk9XX0ZBSUxfTUlOUEFHRVMsMTApPj4+MDowLGdhPXR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYuSFdKU19URVNUX0dST1dfRkFJTF9OP3BhcnNlSW50KHByb2Nlc3MuZW52LkhXSlNfVEVTVF9HUk9XX0ZBSUxfTiwxMCl8MDpBYT4wPzE6MCx1cj0oKCk9PntsZXQgZT10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52LkhXSlNfTEFORV9XQUlUX1JFUE9SVF9NUz9wYXJzZUludChwcm9jZXNzLmVudi5IV0pTX0xBTkVfV0FJVF9SRVBPUlRfTVMsMTApOk5hTjtyZXR1cm4gTnVtYmVyLmlzRmluaXRlKGUpP2V8MDoyZTN9KSgpLFh1PXR5cGVvZiBwcm9jZXNzPCJ1IiYmISFwcm9jZXNzLmVudi5IV0pTX1RIUl9UUkFDRSxpdD10eXBlb2YgcHJvY2VzczwidSImJiEhcHJvY2Vzcy5lbnY/LkhXSlNfV09SS0VSX1NDSEVEX1RSQUNFLHVkPSgoKT0+e2xldCBlPXBhcnNlSW50KHR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnY/LkhXSlNfV09SS0VSX1NDSEVEX1RSQUNFfHwiIiwxMCk7cmV0dXJuIE51bWJlci5pc0Zpbml0ZShlKSYmZT49MTA/ZXwwOjI1MH0pKCksZmQ9KCgpPT57bGV0IGU9cGFyc2VJbnQodHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudj8uSFdKU19XT1JLRVJfU0NIRURfVFJBQ0VfSE9MRF9NU3x8IiIsMTApO3JldHVybiBOdW1iZXIuaXNGaW5pdGUoZSkmJmU+PTEwP2V8MDoxZTN9KSgpLFVuPXR5cGVvZiBwZXJmb3JtYW5jZTwidSImJnR5cGVvZiBwZXJmb3JtYW5jZS5ub3c9PSJmdW5jdGlvbiI/KCk9PnBlcmZvcm1hbmNlLm5vdygpOigpPT5EYXRlLm5vdygpO2Z1bmN0aW9uIEN0KGUsdCl7aWYoaXQpdHJ5e2Uoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc2NoZWR0cmFjZSB0PSR7VW4oKS50b0ZpeGVkKDEpfSAke3R9YH0pfWNhdGNoe319cihDdCwic2NoZWRUcmFjZSIpO3ZhciBxdT0xZTMsWnU9M2U0O2Z1bmN0aW9uIFF1KHtjcHVJZDplLGVtaXQ6dCxyZXNpZGVudHM6byxub3c6cz1Vbix0aHJlc2hvbGRNczpsPXF1LGNlbnN1c01zOmQ9WnUsbWVyZ2VkQ3B1MExhbmU6Xz0hMX09e30pe2xldCBtPTAsYz0wLGg9MCxnPTAseD0wLFM9ITEsUj1zKCksdz1SLHk9cigoeixRKT0+e3RyeXt0KHosUSl9Y2F0Y2h7fX0sImVtaXRMaW5lIiksRD1yKCgpPT57bGV0IHo9dHlwZW9mIG89PSJmdW5jdGlvbiI/bygpOm87cmV0dXJuIHo/Wy4uLnpdOltdfSwicm9zdGVyIiksZGU9cigoKT0+e2crKyx4PW0sdz1zKCk7bGV0IHo9ZGEoKTt5KDcsYGh3anMtd29ya2VyLXNjaGVkIGNwdT0ke2V9IGJlYXRzPSR7bX0gbWF4R2FwPSR7Yy50b0ZpeGVkKDEpfW1zIHR1cm5LaW5kPSR7ei5raW5kfSB0dXJucz0ke3oudHVybnN9IGJlbHQ9JHt6LmJlbHRUdXJuc31gKX0sImNlbnN1cyIpO3JldHVybntiZWF0KHo9cygpKXtsZXQgUT16LVI7Uj16LG0rKyxRPmMmJihjPVEpO2xldCBVPUQoKTtyZXR1cm4gVS5sZW5ndGg+MCYmKFM9ITApLFE+PWwmJihoKyssKGgmaC0xKT09PTAmJnkoNCxgaHdqcy13b3JrZXItc3RhbGwgY3B1PSR7ZX0gbG9vcCB1bmF2YWlsYWJsZSAke1EudG9GaXhlZCgxKX1tcyAodGhyZXNob2xkICR7bH1tcykgcmVzaWRlbnRzPVske1UubWFwKGZlPT5gJHtmZS50aWR9OiR7ZmUuc3RhdHVzfWApLmpvaW4oIiwiKXx8Im5vbmUifV0gb2NjdXJyZW5jZXM9JHtofWArKF8/YCB0aHJlYWQ9TUVSR0VEIFx1MjAxNCB0aGlzIGxhbmUgc2hhcmVzIGl0cyBKUyB0aHJlYWQgd2l0aCBDUFUgMCAodGhlIGtlcm5lbCBXb3JrZXIgYW5kIHRoZSBpbmxpbmUgZGV2aWNlIGJhY2tlbmRzKSwgYW5kIHRoaXMgbW9uaXRvciBjYW4gb25seSBzZWUgTEFORSAke2V9J3MgcmVzaWRlbnRzLiAke1UubGVuZ3RoPT09MD8iQW4gZW1wdHkgcm9zdGVyIGhlcmUgZG9lcyBOT1QgbWVhbiBub3RoaW5nIHdhcyBydW5uaW5nOiB3aXRoIG5vIHJlc2lkZW50IG9mIGl0cyBvd24sIHRoZSBvbmx5IHRoaW5nIHRoYXQgY2FuIGhhdmUgaGVsZCB0aGlzIHRocmVhZCBpcyBDUFUgMCBcdTIwMTQgbG9vayBhdCB3aGF0IHRoZSBrZXJuZWwgd2FzIGRvaW5nLCBub3QgZm9yIGEgbGFuZSB0aGF0IGZyb3plIGlkbGUuIjoiQ1BVIDAgd2FzIGFsc28gb24gdGhpcyB0aHJlYWQgYW5kIGlzIG5vdCBpbiB0aGUgcm9zdGVyIGFib3ZlLCBzbyB0aGUgcmVzaWRlbnRzIG5hbWVkIGFyZSBhIGxvd2VyIGJvdW5kIG9uIHdoYXQgY291bGQgaGF2ZSBoZWxkIGl0LiJ9YDoiIHRocmVhZD1ERURJQ0FURUQgXHUyMDE0IHRoaXMgbGFuZSBvd25zIGl0cyBKUyB0aHJlYWQsIHNvIHRoZSByb3N0ZXIgYWJvdmUgaXMgdGhlIGNvbXBsZXRlIGxpc3Qgb2Ygd2hhdCBjb3VsZCBoYXZlIGhlbGQgaXQiKSkpLFMmJih4PT09MD9tPjA6ei13Pj1kKSYmZGUoKSxRfSxjZW5zdXM6ZGUsaG9zdGluZygpe1M9ITB9LHN0YXRzOnIoKCk9Pih7YmVhdHM6bSxtYXhHYXA6YyxzdGFsbHM6aCxjZW5zdXNlczpnfSksInN0YXRzIil9fXIoUXUsIm1ha2VXb3JrZXJMb29wTW9uaXRvciIpO3ZhciBQcz17dGljaygpe30sZW5kKCl7fSxob2xkczpyKCgpPT4wLCJob2xkcyIpfTtmdW5jdGlvbiBocihlLHtjcHU6dCxwaWQ6byx0aWQ6cyxzaXRlOmwsbGFiZWw6ZCxmaWVsZHM6Xyxhbm5vdW5jZTptfSl7bGV0IGM9VW4oKSxoPWMrZmQsZz0wLHg9ISFtLFM9YGNwdT0ke3Q/PyI/In0gcGlkPSR7bz8/Ij8ifSB0aWQ9JHtzPz8iPyJ9IHNpdGU9JHtsfSBsYWJlbD0ke2R9YDt4JiZDdChlLGBEUklWRS1FTlRFUiAke1N9YCk7bGV0IFI9cih3PT5fP2AgJHtfKHcpfWA6IiIsImV4dHJhIik7cmV0dXJue2hvbGRzOnIoKCk9PmcsImhvbGRzIiksdGljayh3KXtsZXQgeT1VbigpO3k8aHx8KGg9eStmZCxnKysseHx8KHg9ITAsQ3QoZSxgRFJJVkUtRU5URVIgJHtTfWApKSxDdChlLGBIT0xEICR7U30gIyR7Z30gaGVsZD0keyh5LWMpLnRvRml4ZWQoMSl9bXMke1Iodyl9YCkpfSxlbmQodyl7eCYmQ3QoZSxgSE9MRC1FTkQgJHtTfSBoZWxkPSR7KFVuKCktYykudG9GaXhlZCgxKX1tcyR7Uih3KX0gaG9sZHM9JHtnfWApfX19cihociwiaG9sZFJlcG9ydCIpO3ZhciBfZD0tNTE3LGVmPTAsdGY9MixoZD02NTUzNjtmdW5jdGlvbiBuZihlLHQsbyxzLGwsZCxfLG09ITEpe2xldCBjPWUuZXhwb3J0cyxoPXIoYWU9PntsZXQgJGU9Y1thZV07cmV0dXJuICRlIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsPyRlLnZhbHVlPj4+MDowfSwiZGF0YUFkZHIiKSxnPSExLHg9cihhZT0+e2lmKCFnKXtnPSEwO3RyeXtsZXQgJGU9Y2EoYyxvKSxVZT11YSgkZSxhZSk7VWUmJnMoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YCR7VWV9CmB9KX1jYXRjaHt9fX0sInJlcG9ydFVuZGVsaXZlcmVkVmlvbGF0aW9ucyIpLFM9aCgiX19od2pzX3BhcmtlZF9sYW5lcyIpLFI9aCgiX19od2pzX3BhcmtlZF9vd25lcl9sYW5lcyIpLHc9aCgiX19od2pzX2ZyYW1lX2xpdmVfbGFuZXMiKTtpZighU3x8IVJ8fHR5cGVvZiBjLmh3anNfcmVzdW1lIT0iZnVuY3Rpb24ifHx0eXBlb2YgYy5od2pzX2RvbmUhPSJmdW5jdGlvbiJ8fHR5cGVvZiBjLmh3anNfZGVzdHJveSE9ImZ1bmN0aW9uInx8dHlwZW9mIGMuX19od2pzX3Rha2VfcGFya2VkIT0iZnVuY3Rpb24ifHx0eXBlb2YgYy5fX2h3anNfc2xpY2VfZW50ZXIhPSJmdW5jdGlvbiJ8fHR5cGVvZiBjLl9faHdqc19zbGljZV9leGl0IT0iZnVuY3Rpb24iKXJldHVybiBudWxsO2xldCB5PXR8MCxEPW51bGwsZGU9bnVsbCx6PXIoKCk9PntsZXQgYWU9by5idWZmZXI7cmV0dXJuIGFlIT09RCYmKEQ9YWUsZGU9bmV3IFVpbnQzMkFycmF5KGFlKSksZGV9LCJrdTMyIiksUT0oUz4+MikreXwwLFU9KFI+PjIpK3l8MCxmZT13Pyh3Pj4yKSt5fDA6LTEscmU9ZCBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyJiZ5Pj0wJiZ5PDwyPGQuYnl0ZUxlbmd0aD9uZXcgSW50MzJBcnJheShkKTpudWxsLFg9MCxrZT0xOGU0LG9lPTMyK3ksRmU9ITE7ZnVuY3Rpb24gaihhZSl7aWYoIXJlfHxYKys+MClyZXR1cm47aWYoQXRvbWljcy5jb21wYXJlRXhjaGFuZ2UocmUseSwwLDEpPT09MCl7b2U8cmUubGVuZ3RoJiZBdG9taWNzLnN0b3JlKHJlLG9lLChsPz8wKXwwKSxGZT0hMTtyZXR1cm59bGV0ICRlPURhdGUubm93KCksVWU9JGUra2Usb3Q9ITAsc3Q9JGUrdXI7Zm9yKDs7KXtpZihBdG9taWNzLmNvbXBhcmVFeGNoYW5nZShyZSx5LDAsMSk9PT0wKXtpZihvZTxyZS5sZW5ndGgmJkF0b21pY3Muc3RvcmUocmUsb2UsKGw/PzApfDApLEZlPW90LHVyPjAmJkRhdGUubm93KCktJGU+PXVyKXRyeXtzKHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLWxhbmVbJHt5fV0gV0FJVC1FTkQgJHthZX0gKHBpZD0ke2x9KSBhZnRlciAke0RhdGUubm93KCktJGV9bXMKYH0pfWNhdGNoe31yZXR1cm59aWYob3Q9ITAsdXI+MCYmRGF0ZS5ub3coKT49c3Qpe3N0PURhdGUubm93KCkrdXI7bGV0IFNlPW9lPHJlLmxlbmd0aD9BdG9taWNzLmxvYWQocmUsb2UpfDA6MDt0cnl7cyh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy1sYW5lWyR7eX1dIFdBSVQgJHthZX0gKHBpZD0ke2x9KSBibG9ja2VkICR7RGF0ZS5ub3coKS0kZX1tcyBvbiBob2xkZXIgdGlkPSR7U2V9CmB9KX1jYXRjaHt9fWlmKG0pe1gtLTtsZXQgU2U9b2U8cmUubGVuZ3RoP0F0b21pY3MubG9hZChyZSxvZSl8MDowO3Rocm93IG5ldyBFcnJvcihgaHdqcy1sYW5lWyR7eX1dIEZBVEFMIChtZXJnZWQgQ1BVIDApOiB0aGUgbGFuZSBtdXRleCBpcyBIRUxEIGJ5IHRpZD0ke1NlfSB3aGlsZSB0aGlzIHJlYWxtIFx1MjAxNCB0aGUgb25lIHRoYXQgc2hhcmVzIGl0cyBKUyB0aHJlYWQgd2l0aCBDUFUgMCBcdTIwMTQgdHJpZWQgdG8gdGFrZSBpdCBmb3IgJHthZX0gKHBpZD0ke2x9KS4gRXhhY3RseSBvbmUgcmVhbG0gbWF5IG93biB0aGUgbWVyZ2VkIGxhbmU6IHRoZSBob3N0J3MgY3B1LWlkIGFsbG9jYXRvciBleGNsdWRlcyBsYW5lICR7eX0gZnJvbSBldmVyeSBkZWRpY2F0ZWQtV29ya2VyIHBsYWNlbWVudCwgc28gYSBzZWNvbmQgb3duZXIgbWVhbnMgdGhhdCBleGNsdXNpb24gd2FzIGJyb2tlbi4gUmVmdXNpbmcgcmF0aGVyIHRoYW4gd2FpdGluZzogYW4gQXRvbWljcy53YWl0IGhlcmUgd291bGQgYmxvY2sgdGhlIGtlcm5lbCBkaXNwYXRjaGVyLCBldmVyeSBrdGhyZWFkIGFuZCAoaW5saW5lKSB0aGUgZGV2aWNlIGJhY2tlbmRzIG9uIGEgcGVlciB0aGlzIHRocmVhZCBjYW5ub3Qgc2NoZWR1bGUuYCl9aWYoRGF0ZS5ub3coKT5VZSl7WC0tO2xldCBTZT1vZTxyZS5sZW5ndGg/QXRvbWljcy5sb2FkKHJlLG9lKXwwOjA7dGhyb3cgbmV3IEVycm9yKGBod2pzLWxhbmVbJHt5fV0gRkFUQUw6IGNyb3NzLVdvcmtlciBsYW5lIG11dGV4IG5vdCBhY3F1aXJlZCB3aXRoaW4gJHtrZX1tcyBmb3IgJHthZX0gKHBpZD0ke2x9KSBcdTIwMTQgYSBwZWVyIFdvcmtlciAoaG9sZGVyIHRpZD0ke1NlfSkgaXMgd2VkZ2VkIElOU0lERSBhIGxhbmUgYnJhY2tldCAoZXZlcnkgaG9sZCBpcyBvbmUgYm91bmRlZCBkcml2ZSBzbGljZSBieSBjb25zdHJ1Y3Rpb24pLiBSZWZ1c2luZyB0byBkcml2ZSBhIHRvcm4gbGFuZTsgbmV2ZXItc2lsZW50LmApfUF0b21pY3Mud2FpdChyZSx5LDEsNTApfX1yKGosImxhbmVMb2NrQWNxdWlyZSIpO2Z1bmN0aW9uIHJ0KCl7cmUmJigtLVg+MHx8KG9lPHJlLmxlbmd0aCYmQXRvbWljcy5zdG9yZShyZSxvZSwwKSxBdG9taWNzLnN0b3JlKHJlLHksMCksQXRvbWljcy5ub3RpZnkocmUseSwxKSkpfXIocnQsImxhbmVMb2NrUmVsZWFzZSIpO2xldCBDZT1mZT49MD96KClbZmVdPj4+MDowLFB0PXR5cGVvZiBjLl9faHdqc190YXNrX2ZyYW1lcz09ImZ1bmN0aW9uIj9jLl9faHdqc190YXNrX2ZyYW1lcygpPj4+MDowLGRuPXR5cGVvZiBjLl9faHdqc190YXNrX2ZyYW1lcz09ImZ1bmN0aW9uIixlZT17bGFuZTp5LGRlZmVycmFsOiJGODdjMy1hbWVuZGVkIixicmFja2V0czowLGRyaXZlczowLHNsaWNlczowLGZyYW1lUmVzaWR1ZTowLHBvaXNvbmVkOm51bGx9LE1lPXR5cGVvZiBwcm9jZXNzPCJ1IiYmISFwcm9jZXNzLmVudi5IV0pTX0xBTkVfREJHO2Z1bmN0aW9uIHBuKGFlLCRlLFVlLG90PVBzKXtsZXQgc3Q9MDtmb3IoOyFjLmh3anNfZG9uZSgkZSk7KXtpZihNZSYmc3Q8NDApdHJ5e3Moe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtbGFuZVske3l9XSBEQkcgZHJpdmUgJHthZX0gc2xpY2U9JHtzdH0gaD0weCR7KCRlPj4+MCkudG9TdHJpbmcoMTYpfSBvd25lcj0weCR7KHooKVtVXT4+PjApLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fWMuaHdqc19yZXN1bWUoJGUpLHN0KyssYy5fX2h3anNfdGFrZV9wYXJrZWQoVWUsJGUpLGl0JiZvdC50aWNrKHN0KX1sZXQgU2U9dHlwZW9mIGMuX19od2pzX3Byb21pc2VfaTMyPT0iZnVuY3Rpb24iP2MuX19od2pzX3Byb21pc2VfaTMyKCRlKT4+PjA6MCxaZT1TZT96KClbU2U+PjJdfDA6MDtyZXR1cm4gYy5od2pzX2Rlc3Ryb3koJGUpLGVlLmRyaXZlcysrLGVlLnNsaWNlcys9c3Qse3ZhbHVlOlplLHNsaWNlczpzdH19cihwbiwiZHJpdmVUb0RvbmUiKTtmdW5jdGlvbiBCdChhZSl7aWYoZmU8MClyZXR1cm47bGV0ICRlPSh6KClbZmVdPj4+MCktYWV8MDtpZigkZSE9PTAmJihlZS5mcmFtZVJlc2lkdWUrPSRlLGVlLmZyYW1lUmVzaWR1ZT5oZCkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxhbmVbJHt5fV0gRkFUQUw6IGZyYW1lIHJlc2lkdWUgJHtlZS5mcmFtZVJlc2lkdWV9IGNyb3NzZWQgdGhlIG5ldmVyLXNpbGVudCBjZWlsaW5nICR7aGR9IChGODcgY29uZiAoMyk6IHRoZSBpbnRlcmltIHJlcG9ydGVkLW5vdC1mYXRhbCBkZWZlcnJhbCBkb2VzIG5vdCBjb3ZlciB1bmV4cGxhaW5lZCB1bmJvdW5kZWQgZ3Jvd3RoKWApfXIoQnQsImJyYWNrZXRDZW5zdXMiKTtmdW5jdGlvbiBrbihhZSwkZSl7ZWUuYnJhY2tldHMrKyxqKGFlKTt0cnl7cmV0dXJuIHduKGFlLCRlKX1maW5hbGx5e3J0KCl9fXIoa24sImJyYWNrZXQiKTtmdW5jdGlvbiB3bihhZSwkZSl7bGV0IFVlPWZlPj0wP3ooKVtmZV0+Pj4wOjAsb3Q9aXQ/aHIocyx7Y3B1OnkscGlkOmwsdGlkOl8sc2l0ZToiYnJhY2tldCIsbGFiZWw6YWUsYW5ub3VuY2U6ITEsZmllbGRzOnIoX3Q9PmBzbGljZXM9JHtfdH1gLCJmaWVsZHMiKX0pOlBzO2MuX19od2pzX3NsaWNlX2VudGVyKCk7bGV0IHN0O3RyeXtzdD0kZSgpfWNhdGNoKF90KXshZWUucG9pc29uZWQmJiFTcyhfdCkmJihlZS5wb2lzb25lZD1hZSk7dHJ5e3R5cGVvZiBjLl9faHdqc19kdW1wX3BhcmtfdHJhY2U9PSJmdW5jdGlvbiImJmMuX19od2pzX2R1bXBfcGFya190cmFjZSgpfWNhdGNoe310aHJvdyB4KGBrZXJuZWwgbGFuZSAke3l9ICR7YWV9YCksYy5fX2h3anNfc2xpY2VfZXhpdCgpLF90fWxldCBTZT16KClbUV0+Pj4wLFplPTA7aWYoU2UhPT0wKXtsZXQgX3Q9eigpW1VdPj4+MCxKZT1jLl9faHdqc190YWtlX3BhcmtlZCgwLDApPj4+MCxIdDt0cnl7SHQ9cG4oYWUsSmUsX3Qsb3QpfWNhdGNoKFluKXshZWUucG9pc29uZWQmJiFTcyhZbikmJihlZS5wb2lzb25lZD1hZSk7dHJ5e3R5cGVvZiBjLl9faHdqc19kdW1wX3BhcmtfdHJhY2U9PSJmdW5jdGlvbiImJmMuX19od2pzX2R1bXBfcGFya190cmFjZSgpfWNhdGNoe310aHJvdyB4KGBrZXJuZWwgbGFuZSAke3l9ICR7YWV9IChtaWQtZHJpdmUpYCksYy5fX2h3anNfc2xpY2VfZXhpdCgpLFlufWxldHt2YWx1ZTpNdCxzbGljZXM6QXR9PUh0O1plPUF0LHMoe2tpbmQ6Imh3anMtbGFuZS1kcml2ZSIscGlkOmwsbGFuZTp5LGxhYmVsOmFlLGhhbmRsZTpKZSxvd25lcjpfdCxzbGljZXM6QXR9KSxzdD1NdH1yZXR1cm4gYy5fX2h3anNfc2xpY2VfZXhpdCgpLEJ0KFVlKSxpdCYmb3QuZW5kKFplKSxzdH1yKHduLCJicmFja2V0TG9ja2VkIik7bGV0IGhlPW5ldyBJbnQzMkFycmF5KG5ldyBTaGFyZWRBcnJheUJ1ZmZlcig0KSksRnQ9Mixnbj01MTI7ZnVuY3Rpb24gRW4oYWUsJGUpe2VlLmJyYWNrZXRzKys7bGV0IFVlPTAsb3Q9MCxzdD1pdD9ocihzLHtjcHU6eSxwaWQ6bCx0aWQ6XyxzaXRlOiJicmFja2V0WWllbGRpbmciLGxhYmVsOmFlLGFubm91bmNlOiEwLGZpZWxkczpyKEh0PT5gc2xpY2VzPSR7SHR9IGJhY2tvZmZzPSR7VWV9IHBhcmtlZD0ke290fSBjb250ZW5kZWQ9JHtGZT8xOjB9YCwiZmllbGRzIil9KTpQcztqKGFlKTtsZXQgU2UsWmU9MCxfdD0wO3tsZXQgSHQ9ZmU+PTA/eigpW2ZlXT4+PjA6MDtjLl9faHdqc19zbGljZV9lbnRlcigpO3RyeXtTZT0kZSgpfWNhdGNoKEF0KXshZWUucG9pc29uZWQmJiFTcyhBdCkmJihlZS5wb2lzb25lZD1hZSk7dHJ5e3R5cGVvZiBjLl9faHdqc19kdW1wX3BhcmtfdHJhY2U9PSJmdW5jdGlvbiImJmMuX19od2pzX2R1bXBfcGFya190cmFjZSgpLHgoYGtlcm5lbCBsYW5lICR7eX1gKX1jYXRjaHt9dGhyb3cgYy5fX2h3anNfc2xpY2VfZXhpdCgpLHJ0KCksQXR9aWYoeigpW1FdPj4+MD09PTApcmV0dXJuIGMuX19od2pzX3NsaWNlX2V4aXQoKSxCdChIdCkscnQoKSxpdCYmc3QuZW5kKDApLFNlO190PXooKVtVXT4+PjAsWmU9Yy5fX2h3anNfdGFrZV9wYXJrZWQoMCwwKT4+PjAsb3Q9MSxjLl9faHdqc19zbGljZV9leGl0KCkscnQoKX1sZXQgSmU9MDtmb3IoOzspe2ooYWUpLGMuX19od2pzX3NsaWNlX2VudGVyKCk7bGV0IEh0LE10PTA7dHJ5e2lmKEh0PSEhYy5od2pzX2RvbmUoWmUpLEh0fHwoYy5od2pzX3Jlc3VtZShaZSksSmUrKyxjLl9faHdqc190YWtlX3BhcmtlZChfdCxaZSksSHQ9ISFjLmh3anNfZG9uZShaZSkpLEh0KXtsZXQgQXQ9dHlwZW9mIGMuX19od2pzX3Byb21pc2VfaTMyPT0iZnVuY3Rpb24iP2MuX19od2pzX3Byb21pc2VfaTMyKFplKT4+PjA6MDtNdD1BdD96KClbQXQ+PjJdfDA6MCxjLmh3anNfZGVzdHJveShaZSl9fWNhdGNoKEF0KXshZWUucG9pc29uZWQmJiFTcyhBdCkmJihlZS5wb2lzb25lZD1hZSk7dHJ5e3R5cGVvZiBjLl9faHdqc19kdW1wX3BhcmtfdHJhY2U9PSJmdW5jdGlvbiImJmMuX19od2pzX2R1bXBfcGFya190cmFjZSgpLHgoYGtlcm5lbCBsYW5lICR7eX1gKX1jYXRjaHt9dGhyb3cgYy5fX2h3anNfc2xpY2VfZXhpdCgpLHJ0KCksQXR9aWYoYy5fX2h3anNfc2xpY2VfZXhpdCgpLHJ0KCksSHQpcmV0dXJuIGVlLmRyaXZlcysrLGVlLnNsaWNlcys9SmUscyh7a2luZDoiaHdqcy1sYW5lLWRyaXZlIixwaWQ6bCxsYW5lOnksbGFiZWw6YWUsaGFuZGxlOlplLG93bmVyOl90LHNsaWNlczpKZX0pLGl0JiZzdC5lbmQoSmUpLE10O2l0JiZzdC50aWNrKEplKSwoRmV8fEplJWduPT09MCkmJihpdCYmVWUrKyxBdG9taWNzLndhaXQoaGUsMCwwLEZ0KSl9fXIoRW4sImJyYWNrZXRZaWVsZGluZyIpO2xldCB0bj10eXBlb2YgYy5fX3dhc20zMl9zZXRfcGFya19jb25zdW1lcj09ImZ1bmN0aW9uIixzcz1yKCgpPT50bj9jLl9fd2FzbTMyX3NldF9wYXJrX2NvbnN1bWVyKHRmKT4+PjA6ZWYsImRlY2xhcmVQYXJrQ29uc3VtZXJIb3N0IiksTD1yKGFlPT57dG4mJmMuX193YXNtMzJfc2V0X3BhcmtfY29uc3VtZXIoYWU+Pj4wKX0sInJlc3RvcmVQYXJrQ29uc3VtZXIiKSxJPXR5cGVvZiBjLl9fd2FzbTMyX3Rha2Vfc3lzY2FsbF93b3VsZF9ibG9jaz09ImZ1bmN0aW9uIixPPSExO2Z1bmN0aW9uIHRlKGFlKXtpZihJKXJldHVybihjLl9fd2FzbTMyX3Rha2Vfc3lzY2FsbF93b3VsZF9ibG9jaygpfDApIT09MDtpZighTyl7Tz0hMDt0cnl7cyh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy1sYW5lWyR7eX1dIHRoaXMgdm1saW51eCBleHBvcnRzIG5vIF9fd2FzbTMyX3Rha2Vfc3lzY2FsbF93b3VsZF9ibG9jaywgc28gYSBob3N0IGRyaXZlICgke2FlfSkgY2Fubm90IHRlbGwgYSBCTE9DSyBwYXJrIGZyb20gYSBzYWZlcG9pbnQvYnVkZ2V0IHBhcmsgYXQgYSByZXN1bWUgbGVnIGl0IG93bnM7IGl0IGRyaXZlcyBzdWNoIGxlZ3MgdG8gY29tcGxldGlvbiBleGFjdGx5IGFzIGJlZm9yZS4gVGhlIHdhc21fc3lzY2FsbCByb3V0ZSBpcyB1bmFmZmVjdGVkICh0aGUga2VybmVsIGNsZWFycyB0aGUgZmxhZyBhbmQgYW5zd2VycyAtNTE3KS4gTmV2ZXItc2lsZW50LmB9KX1jYXRjaHt9fXJldHVybiExfXIodGUsInRha2VTeXNjYWxsV291bGRCbG9jayIpO2Z1bmN0aW9uIHEoYWUsJGUsVWUpe2VlLmJyYWNrZXRzKys7bGV0IG90PXNzKCk7dHJ5e3JldHVybiBPZShhZSwkZSxVZSl9ZmluYWxseXtMKG90KX19cihxLCJkcml2ZVdvdWxkQmxvY2siKTtmdW5jdGlvbiBPZShhZSwkZSxVZSl7bGV0IG90PTAsc3Q9VWUuaD8xOjAsU2U9MCxaZT1pdD9ocihzLHtjcHU6eSxwaWQ6bCx0aWQ6XyxzaXRlOiJkcml2ZVdvdWxkQmxvY2siLGxhYmVsOmFlLGFubm91bmNlOiEwLGZpZWxkczpyKF90PT5gc2xpY2VzPSR7X3R9IGJhY2tvZmZzPSR7b3R9IHBhcmtlZD0ke3N0fSBjb250ZW5kZWQ9JHtGZT8xOjB9YCwiZmllbGRzIil9KTpQcztpZihVZS5oPT09MCl7aihhZSk7bGV0IF90PWZlPj0wP3ooKVtmZV0+Pj4wOjA7Yy5fX2h3anNfc2xpY2VfZW50ZXIoKTtsZXQgSmU7dHJ5e0plPSRlKCl8MH1jYXRjaChNdCl7IWVlLnBvaXNvbmVkJiYhU3MoTXQpJiYoZWUucG9pc29uZWQ9YWUpO3RyeXt0eXBlb2YgYy5fX2h3anNfZHVtcF9wYXJrX3RyYWNlPT0iZnVuY3Rpb24iJiZjLl9faHdqc19kdW1wX3BhcmtfdHJhY2UoKSx4KGBrZXJuZWwgbGFuZSAke3l9YCl9Y2F0Y2h7fXRocm93IGMuX19od2pzX3NsaWNlX2V4aXQoKSxydCgpLE10fWlmKHooKVtRXT4+PjA9PT0wKXtsZXQgTXQ9dGUoYWUpO3JldHVybiBjLl9faHdqc19zbGljZV9leGl0KCksQnQoX3QpLHJ0KCksaXQmJlplLmVuZCgwKSx7d291bGRCbG9jazpKZT09PV9kfHxNdCx2YWx1ZTpKZSxzbGljZXM6MH19VWUub3duZXI9eigpW1VdPj4+MCxVZS5oPWMuX19od2pzX3Rha2VfcGFya2VkKDAsMCk+Pj4wLHN0PTEsYy5fX2h3anNfc2xpY2VfZXhpdCgpLHJ0KCl9Zm9yKDs7KXtqKGFlKSxjLl9faHdqc19zbGljZV9lbnRlcigpO2xldCBfdCxKZT0hMSxIdD0wLE10PVVlLmg7dHJ5e2lmKF90PSEhYy5od2pzX2RvbmUoTXQpLF90fHwoYy5od2pzX3Jlc3VtZShNdCksU2UrKyxjLl9faHdqc190YWtlX3BhcmtlZChVZS5vd25lcixNdCksX3Q9ISFjLmh3anNfZG9uZShNdCksSmU9dGUoYWUpKSxfdCl7bGV0IEF0PXR5cGVvZiBjLl9faHdqc19wcm9taXNlX2kzMj09ImZ1bmN0aW9uIj9jLl9faHdqc19wcm9taXNlX2kzMihNdCk+Pj4wOjA7SHQ9QXQ/eigpW0F0Pj4yXXwwOjAsYy5od2pzX2Rlc3Ryb3koTXQpfX1jYXRjaChBdCl7IWVlLnBvaXNvbmVkJiYhU3MoQXQpJiYoZWUucG9pc29uZWQ9YWUpO3RyeXt0eXBlb2YgYy5fX2h3anNfZHVtcF9wYXJrX3RyYWNlPT0iZnVuY3Rpb24iJiZjLl9faHdqc19kdW1wX3BhcmtfdHJhY2UoKSx4KGBrZXJuZWwgbGFuZSAke3l9YCl9Y2F0Y2h7fXRocm93IGMuX19od2pzX3NsaWNlX2V4aXQoKSxydCgpLEF0fWlmKGMuX19od2pzX3NsaWNlX2V4aXQoKSxydCgpLF90KXtsZXQgQXQ9VWUub3duZXI7cmV0dXJuIFVlLmg9MCxVZS5vd25lcj0wLGVlLmRyaXZlcysrLGVlLnNsaWNlcys9U2Uscyh7a2luZDoiaHdqcy1sYW5lLWRyaXZlIixwaWQ6bCxsYW5lOnksbGFiZWw6YWUsaGFuZGxlOk10LG93bmVyOkF0LHNsaWNlczpTZX0pLGl0JiZaZS5lbmQoU2UpLHt3b3VsZEJsb2NrOiExLHZhbHVlOkh0LHNsaWNlczpTZX19aWYoSmUpcmV0dXJuIGVlLnNsaWNlcys9U2UsaXQmJlplLmVuZChTZSkse3dvdWxkQmxvY2s6ITAsdmFsdWU6X2Qsc2xpY2VzOlNlfTtpdCYmWmUudGljayhTZSksKEZlfHxTZSVnbj09PTApJiYoaXQmJm90KyssQXRvbWljcy53YWl0KGhlLDAsMCxGdCkpfX1yKE9lLCJkcml2ZVdvdWxkQmxvY2tJbm5lciIpO2Z1bmN0aW9uIEhlKGFlLCRlKXtlZS5icmFja2V0cysrLGooYHdhc21fc3lzY2FsbDoke2FlfDB9YCk7dHJ5e3JldHVybiBZdChhZSwkZSl9ZmluYWxseXtydCgpfX1yKEhlLCJkaXNwYXRjaFN5c2NhbGwiKTtmdW5jdGlvbiBZdChhZSwkZSl7bGV0IFVlPWZlPj0wP3ooKVtmZV0+Pj4wOjAsb3Q9YHdhc21fc3lzY2FsbDoke2FlfDB9YCxzdD1pdD9ocihzLHtjcHU6eSxwaWQ6bCx0aWQ6XyxzaXRlOiJkaXNwYXRjaFN5c2NhbGwiLGxhYmVsOm90LGFubm91bmNlOiExLGZpZWxkczpyKEplPT5gc2xpY2VzPSR7SmV9YCwiZmllbGRzIil9KTpQcztjLl9faHdqc19zbGljZV9lbnRlcigpO2xldCBTZTt0cnl7U2U9JGUoKX1jYXRjaChKZSl7dGhyb3chZWUucG9pc29uZWQmJiFTcyhKZSkmJihlZS5wb2lzb25lZD1gd2FzbV9zeXNjYWxsOiR7YWV8MH1gKSxjLl9faHdqc19zbGljZV9leGl0KCksSmV9bGV0IFplPXooKVtRXT4+PjAsX3Q9MDtpZihaZSE9PTApe2xldCBKZT16KClbVV0+Pj4wLEh0PWMuX19od2pzX3Rha2VfcGFya2VkKDAsMCk+Pj4wLHt2YWx1ZTpNdCxzbGljZXM6QXR9PXBuKG90LEh0LEplLHN0KTtfdD1BdCxzKHtraW5kOiJod2pzLWxhbmUtZHJpdmUiLHBpZDpsLGxhbmU6eSxsYWJlbDpvdCxoYW5kbGU6SHQsb3duZXI6SmUsc2xpY2VzOkF0fSksU2U9TXR9cmV0dXJuIGMuX19od2pzX3NsaWNlX2V4aXQoKSxCdChVZSksaXQmJnN0LmVuZChfdCksU2V9cihZdCwiZGlzcGF0Y2hTeXNjYWxsTG9ja2VkIik7ZnVuY3Rpb24gcnMoKXtsZXQgYWU9ZmU+PTA/eigpW2ZlXT4+PjA6MCwkZT1kbj9jLl9faHdqc190YXNrX2ZyYW1lcygpPj4+MDowLFVlPWRuPyRlLVB0fDA6YWUtQ2V8MHx8ZWUuZnJhbWVSZXNpZHVlLG90PXsuLi5lZSxsaXZlQXRDcmVhdGU6Q2UsbGl2ZUF0RXhpdDphZSxyZXNpZHVlOlVlLGZyYW1lc0F0Q3JlYXRlOlB0LGZyYW1lc0F0RXhpdDokZSxwZXJUYXNrOmRufTtpZihVZSE9PTAmJiFlZS5wb2lzb25lZCl7aWYobD09PTEpcmV0dXJuIHMoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtbGFuZVske3l9XSBwaWQgMSByZWNvbmNpbGU6IGJvb3QtY29udGludWF0aW9uIHJlc2lkdWUgJHtVZX0gZnJhbWVzIGArKGRuP2AocGVyLXRhc2sgZnJhbWVzICR7UHR9IC0+ICR7JGV9KSBgOmAobGFuZS1zdW0gbGl2ZSAke0NlfSAtPiAke2FlfSkgYCkrIlx1MjAxNCBFWFBFQ1RFRCAocmV1c2VkIGtlcm5lbF9pbml0J3MgYnktZGVzaWduIHBhcmtlZCBib290IGZyYW1lcywgYmFzZWxpbmVkIGFzIDAgYmVmb3JlIGl0cyBmaW5hbCBzY2hlZHVsZSgpIGF0dHJpYnV0ZWQgdGhlbSk7IG5vbi1mYXRhbCAoSFdKUy1BLTQuYyByZXNpZHVhbC0yIGNhcnZlLW91dCwgcGlkIDEgb25seSkifSksey4uLm90LGV4cGxhaW5lZDoicGlkMS1ib290LWNvbnRpbnVhdGlvbiJ9O3Rocm93IHMoe2tpbmQ6ImVycm9yIixwaWQ6bCxsYW5lOnksbWVzc2FnZTpgaHdqcy1sYW5lWyR7eX1dIEZBVEFMIChxdWllc2NlIHJlY29uY2lsaWF0aW9uKTogZW5kLW9mLXByb2Nlc3MgcmVzaWR1ZSAke1VlfSBmcmFtZXMgYCsoZG4/YChwZXItdGFzayBmcmFtZXMgJHtQdH0gLT4gJHskZX0pIGA6YChsYW5lLXN1bSBsaXZlICR7Q2V9IC0+ICR7YWV9KSBgKSsid2l0aCBOTyB3aXRuZXNzZWQgYnJhY2tldCB0cmFwIFx1MjAxNCBhbiB1bmV4cGxhaW5lZCBsZWFrIHRoZSBGODdjMyBkZWZlcnJhbCBkb2VzIG5vdCBjb3ZlciAoYW1lbmRlZCBmb3JtLCBtYW5hZ2VyIDIwMjYtMDYtMTEpIn0pLG5ldyBFcnJvcihgaHdqcy1sYW5lWyR7eX1dIHVuZXhwbGFpbmVkIGVuZC1vZi1wcm9jZXNzIGZyYW1lIHJlc2lkdWUgJHtVZX0gKHJlY29uY2lsaWF0aW9uIGZhdGFsKWApfXJldHVybiBvdH1yZXR1cm4gcihycywicmVjb25jaWxlIikse2xhbmU6eSxicmFja2V0OmtuLGJyYWNrZXRZaWVsZGluZzpFbixkcml2ZVdvdWxkQmxvY2s6cSxkaXNwYXRjaFN5c2NhbGw6SGUsY2Vuc3VzOmVlLHJlY29uY2lsZTpyc319cihuZiwibWFrZUh3anNLZXJuZWxMYW5lIik7ZnVuY3Rpb24gbnMoZSx0LG8pe2lmKFh1KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbdGhyLXRyYWNlIHRpZD0ke2U/LnRpZD8/Ij8ifSBtb2RlPSR7ZT8ubW9kZT8/Ij8ifSBsYW5lPSR7ZT8udXNlckxhbmU/PyI/In0gY3B1PSR7ZT8uY3B1SWQ/PyI/In1dICR7b30gdD0ke0RhdGUubm93KCl9CmB9KX1jYXRjaHt9fXIobnMsInRoclRyYWNlIik7YXN5bmMgZnVuY3Rpb24gSWEoZSx0KXtpZighZS5hbGxvd011bHRpSW5zdGFuY2UmJlhyIT09MClyZXR1cm4gdCh7a2luZDoidm1saW51eC1lcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6YEsxMS1CMmEgcGVyLVdvcmtlciB2bWxpbnV4IGludmFyaWFudCB2aW9sYXRlZDogdm1saW51eC53YXNtIGhhcyBhbHJlYWR5IGJlZW4gaW5zdGFudGlhdGVkICR7WHJ9IHRpbWUocykgaW4gdGhpcyBXb3JrZXIuIEVhY2ggV29ya2VyIChrZXJuZWwgb3IgcHJvY2VzcykgbXVzdCBpbnN0YW50aWF0ZSB2bWxpbnV4IGV4YWN0bHkgb25jZTsgcmUtaW5zdGFudGlhdGlvbiByZS1ydW5zIHRoZSBLMTAtQTMgYWN0aXZlLSBvdmVybGF5IGFnYWluc3Qgc2hhcmVkIGtlcm5lbCBtZW1vcnkgYW5kIGNvcnJ1cHRzIHRoZSBydW5uaW5nIGtlcm5lbCdzIGluaXRjYWxsIGFycmF5cy4gU2VlIGRvY3MvQVJDSElURUNUVVJFLm1kIFx4QTcxNS4zIFItSzEwLVcxLmB9KSxudWxsO2lmKCFlLmtlcm5lbE1lbW9yeVdhc20pcmV0dXJuIHQoe2tpbmQ6InZtbGludXgtZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiJLMTEtQjJhOiBjYW5ub3QgaW5zdGFudGlhdGUgcGVyLVdvcmtlciB2bWxpbnV4IHdpdGhvdXQgYSBXZWJBc3NlbWJseS5NZW1vcnkgYmFja2luZyBlbnYua2VybmVsX21lbW9yeTsgc3Bhd24gaGFuZGxlciBtdXN0IHBhc3Mga2VybmVsTWVtb3J5V2FzbSBpbiB0aGUgaW5pdCBtZXNzYWdlIChzZWUgS2VybmVsU3Bhd25IYW5kbGVyT3B0aW9ucy5rZXJuZWxNZW1vcnlXYXNtKS4ifSksbnVsbDtsZXQgbz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6ITF9KTtmdW5jdGlvbiBzKEksTyx0ZSl7bGV0IHE9bmV3IFVpbnQ4QXJyYXkoZS5rZXJuZWxNZW1vcnlXYXNtLmJ1ZmZlcixPLHRlKSxPZT1uZXcgVWludDhBcnJheSh0ZSk7T2Uuc2V0KHEpO2xldCBIZT1vLmRlY29kZShPZSk7YmEodCxlLnJvdXRlS2V5LGUucGlkLEksSGUpfXIocywiZG1lc2ciKTtsZXQgbD0yNTUsZD0xZTQsXz0xZTYsbT02NTUzNSxjPWUubWVyZ2VkQ3B1MExhbmU9PT0hMCxoPTAsZz0wLHg9MDtmdW5jdGlvbiBTKCl7aWYoIWN8fChObiE9PW51bGwmJigrK2gmbCk9PT0wJiZObihSKSwoKytnJm0pIT09MCkpcmV0dXJuO2xldCBJPURhdGUubm93KCk7aWYoeD09PTApe3g9STtyZXR1cm59bGV0IE89SS14O2lmKE88ZHx8ZzxfKXJldHVybjtsZXQgdGU9Zzt0aHJvdyBnPTAseD0wLG5ldyBFcnJvcihgaHdqcy1tZXJnZWQgTEFORSBERUFETE9DSzogcG9vbCBsYW5lICR7ZS5jcHVJZHwwfSAodGlkPSR7ZS50aWR8MH0pIGhhcyBoZWxkIHRoZSBtZXJnZWQgSlMgdGhyZWFkIGZvciAke099IG1zIGFjcm9zcyAke3RlfSBsaW51eC5jcHVfcmVsYXhfaG9zdCBjYWxscyB3aXRob3V0IHByb2dyZXNzLiBUaGUgZ3Vlc3QgaXMgaW4gYW4gaW4ta2VybmVsIEJVU1ktV0FJVCBcdTIwMTQgb24gdGhpcyBhcmNoIGNwdV9yZWxheCgpIElTIHRoaXMgaG9zdCBjYWxsIChhc20vYmFycmllci5oKSBhbmQgaXQgaXMgbm90IGEgc3VzcGVuZCBwb2ludCBcdTIwMTQgYW5kIHRoZSBob3N0IGJhY2tlbmQgaXQgaXMgd2FpdGluZyBvbiBpcyBvbiBUSElTIHRocmVhZC4gJHtObj09PW51bGw/Ik5vIHN5bmNocm9ub3VzIGRvb3JiZWxsIGlzIGluc3RhbGxlZCBvbiB0aGlzIHJlYWxtLCBzbyBub3RoaW5nIHdhcyBkcmFpbmVkIGF0IGFsbC4iOiJUaGUgc3luY2hyb25vdXMgZG9vcmJlbGwgd2FzIGRyYWluZWQgZXZlcnkgIisobCsxKSsiIGNhbGxzIGFuZCBkaWQgbm90IHNhdGlzZnkgaXQsIHNvIHRoZSBiYWNrZW5kIGl0IG5lZWRzIGlzIG9uZSB0aGF0IEFXQUlUUyAodmlydGlvLWZzLCB2aXJ0aW8tbmV0KSBvciBpcyBub3QgcmVnaXN0ZXJlZCBpbiB0aGlzIHJlYWxtLiJ9IEEgc3luY2hyb25vdXMgaW1wb3J0IGNhbiBuZWl0aGVyIHR1cm4gdGhlIGV2ZW50IGxvb3Agbm9yIHJlc29sdmUgYSBwcm9taXNlLCBzbyB0aGlzIGNhbm5vdCBiZSBjbG9zZWQgZnJvbSBoZXJlOiB0aGUgZ3Vlc3Qgd2FpdCBoYXMgdG8gYmVjb21lIGEgY29vcGVyYXRpdmUgcGFyay5gKX1yKFMsImNwdV9yZWxheF9ob3N0Iik7bGV0IFI9T2JqZWN0LmZyZWV6ZSh7a2luZDoidmlydGlvLWRyYWluLXN5bmMifSk7ZnVuY3Rpb24gdygpe3JldHVybiB0eXBlb2YgcGVyZm9ybWFuY2U8InUiJiZwZXJmb3JtYW5jZS5ub3cmJnR5cGVvZiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luPT0ibnVtYmVyIj9CaWdJbnQoTWF0aC5yb3VuZCgocGVyZm9ybWFuY2UudGltZU9yaWdpbitwZXJmb3JtYW5jZS5ub3coKSkqMWU2KSk6QmlnSW50KERhdGUubm93KCkpKjEwMDAwMDBufXIodywibm93X25zIik7bGV0IHk9ZS5rZXJuZWxNZW1vcnlXYXNtLmJ1ZmZlcixEPW5ldyBJbnQzMkFycmF5KHkpLGRlPXIoKCk9PntsZXQgST1lLmtlcm5lbE1lbW9yeVdhc20uYnVmZmVyO3JldHVybiBJIT09eSYmKHk9SSxEPW5ldyBJbnQzMkFycmF5KEkpKSxEfSwia2VybkkzMiIpLHo9ISFnbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU182N19UUkFDRSxRPSEhZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfU1RBTExfVFJBQ0UsVT0oKCk9PntsZXQgST1wYXJzZUludChnbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU19TVEFMTF9UUkFDRT8/IiIsMTApO3JldHVybiBOdW1iZXIuaXNGaW5pdGUoSSkmJkk+PTEwMD9JOjE1ZTN9KSgpLGZlPSEhZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfU1RBTExfU1RBQ0s7ZmUmJihFcnJvci5zdGFja1RyYWNlTGltaXQ9MjAwKTtsZXQgcmU9MCxYPTAsa2U9MDtmdW5jdGlvbiBvZShJLE8sdGUpe2xldCBxPShJfDApPj4+MjtpZih0eXBlb2YgdGU9PSJiaWdpbnQiJiZ0ZT49MG4pe2xldCBIZT1OdW1iZXIodGUvMTAwMDAwMG4pO2lmKFEpe3JlKys7bGV0IHJzPURhdGUubm93KCk7aWYocnMtWD5VKXtYPXJzO2xldCBhZT0iIjtpZihmZSl0cnl7YWU9IiBhdCAiK1N0cmluZyhuZXcgRXJyb3IoKS5zdGFjaz8/IiIpLnNwbGl0KGAKYCkuc2xpY2UoMSw0MCkubWFwKCRlPT4kZS50cmltKCkpLmZpbHRlcigkZT0+IS9cLmh3anNfcmVzdW1lIFwoLy50ZXN0KCRlKSkuam9pbigiIDwtICIpfWNhdGNoe31iYSh0LGUucm91dGVLZXksZS5waWQsNSxgU1RBTEwtVFJBQ0UgcGlkPSR7ZS5waWQ/PyI/In0gdGlkPSR7ZS50aWR8MH0gbGFuZT0ke2UudXNlckxhbmU/PzB9IGtlcm4td2FpdCBhZGRyPTB4JHsoST4+PjApLnRvU3RyaW5nKDE2KX0gZXhwZWN0ZWQ9JHtPfDB9IGN1cj0ke0F0b21pY3MubG9hZChkZSgpLHEpfDB9IHRpbWVvdXRNcz0ke0hlfSB3YWl0cz0ke3JlfSR7YWV9YCl9fWxldCBZdD1BdG9taWNzLndhaXQoZGUoKSxxLE98MCxIZSk7cmV0dXJuIFl0PT09Im9rIj8wOll0PT09Im5vdC1lcXVhbCI/MToyfWlmKHopdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YHQ2NyB0aWQ9JHtlLnRpZHwwfSBLRVJOLUFUT01JQy1XQUlULUlORiBhZGRyPTB4JHsoST4+PjApLnRvU3RyaW5nKDE2KX0gZXhwZWN0ZWQ9JHtPfDB9IGN1cj0ke0F0b21pY3MubG9hZChkZSgpLHEpfDB9YH0pfWNhdGNoe31pZihlLm1lcmdlZENwdTBMYW5lPT09ITApcmV0dXJuIGtlKyssKGtlJmtlLTEpPT09MCYmYmEodCxlLnJvdXRlS2V5LGUucGlkLDMsYGh3anMtbWVyZ2VkIFJFRlVTRUQgYW4gVU5CT1VOREVEIGluLWtlcm5lbCB3YWl0IG9uIHRoZSBtZXJnZWQgQ1BVLTAgbGFuZTogcGlkPSR7ZS5waWQ/PyI/In0gdGlkPSR7ZS50aWR8MH0gYWRkcj0weCR7KEk+Pj4wKS50b1N0cmluZygxNil9IGV4cGVjdGVkPSR7T3wwfS4gVGhpcyBsYW5lIHNoYXJlcyBpdHMgSlMgdGhyZWFkIHdpdGggQ1BVIDAgKGFuZCwgaW5saW5lLCB3aXRoIHRoZSBkZXZpY2UgYmFja2VuZHMgdGhhdCB3b3VsZCBkZWxpdmVyIHRoZSB3YWtlKSwgc28gYmxvY2tpbmcgaGVyZSBzdG9wcyB0aGUgbWFjaGluZSwgbm90IGp1c3QgdGhpcyB0YXNrLiBBbnN3ZXJpbmcgJ3RpbWVkIG91dCcgaW5zdGVhZCBcdTIwMTQgdGhlIGNhbGxlciByZS1jaGVja3MgYW5kIHJldHVybnMuIE9jY3VycmVuY2UgJHtrZX0uIEEgbWVyZ2VkIG1hY2hpbmUgcnVucyBvbmx5IGltYWdlcyB3aG9zZSBsaWJjIGFic29yYnMgdGhlIC01MTcgcGFyazsgaWYgdGhpcyBmaXJlcywgdGhhdCBhc3N1bXB0aW9uIGlzIGZhbHNlIGZvciB0aGlzIGltYWdlLiBUaGVyZSBpcyBubyBvdGhlciB0b3BvbG9neSB0byBtb3ZlIGl0IHRvIFx1MjAxNCBldmVyeSBtYWNoaW5lIGlzIG1lcmdlZCBcdTIwMTQgc28gd2hhdCBoYXMgdG8gY2hhbmdlIGlzIHRoZSBpbWFnZSdzIGxpYmMsIG9yIHRoZSBrZXJuZWwgcGF0aCB0aGF0IHJlYWNoZWQgYW4gdW5ib3VuZGVkIHdhaXQgZnJvbSBhIGNhbGwgZ3JhcGggdGhlIGxpYmMncyBub21pbmF0aW9uIGxpc3QgZG9lcyBub3QgY292ZXIuYCksMjtsZXQgT2U9QXRvbWljcy53YWl0KGRlKCkscSxPfDApO2lmKHopdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YHQ2NyB0aWQ9JHtlLnRpZHwwfSBLRVJOLUFUT01JQy1XQUlULUlORiBXT0tFIGFkZHI9MHgkeyhJPj4+MCkudG9TdHJpbmcoMTYpfSByPSR7T2V9YH0pfWNhdGNoe31yZXR1cm4gT2U9PT0ib2siPzA6T2U9PT0ibm90LWVxdWFsIj8xOjJ9cihvZSwiYXRvbWljX3dhaXRfaTMyIik7ZnVuY3Rpb24gRmUoSSxPKXtyZXR1cm4gQXRvbWljcy5ub3RpZnkoZGUoKSwoSXwwKT4+PjIsT3wwKX1yKEZlLCJhdG9taWNfbm90aWZ5Iik7bGV0IGo9cihJPT4oLi4uTyk9Pih0KHtraW5kOiJ1bmltcGxlbWVudGVkLWhvc3QtY2FsbCIsbmFtZTpJLHBpZDplLnBpZH0pLDApLCJzdHViSG9zdCIpLHJ0PXIoST0+e3Rocm93IHQoe2tpbmQ6InZtbGludXgtZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOkl9KSxuZXcgRXJyb3IoSSl9LCJ1YWNjZXNzUmVmdXNlIiksQ2U9cWwoe3VzZXJNZW1vcnk6ZS5tZW1vcnksa2VybmVsTWVtb3J5OmUua2VybmVsTWVtb3J5V2FzbSxyZWZ1c2U6cnQsY29udGV4dDpgcGlkPSR7ZS5waWR9IHByb2Nlc3MgV29ya2VyYCxyZWRQYXJrOiEhZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfUkVEX1VBQ0NFU1NfUEFSS30pLFB0PS0xLGVlPXtkbWVzZzpzLGNwdV9yZWxheF9ob3N0OlMsbm93X25zOncsbWVtX2NvbW1pdDpyKEk9PntsZXQgTz1lLmtlcm5lbE1lbW9yeVdhc20sdGU9KEk+Pj4wKSo0MDk2LHE9Ty5idWZmZXIuYnl0ZUxlbmd0aDtpZih0ZT5xKXt0cnl7Ty5ncm93KE1hdGguY2VpbCgodGUtcSkvNjU1MzYpKX1jYXRjaHt9bGV0IE9lPU8uYnVmZmVyLmJ5dGVMZW5ndGg7T2UhPT1xJiZQdD49MCYmQXRvbWljcy5zdG9yZShuZXcgSW50MzJBcnJheShPLmJ1ZmZlciksUHQsT2UvNDA5NnwwKX1yZXR1cm4gTy5idWZmZXIuYnl0ZUxlbmd0aC80MDk2Pj4+MH0sIm1lbV9jb21taXQiKSxhdG9taWNfd2FpdF9pMzI6b2UsYXRvbWljX25vdGlmeTpGZSwuLi5DZS5pbXBvcnRzLGNvbnNvbGVfd3JpdGU6aigiY29uc29sZV93cml0ZSIpLGNvbnNvbGVfcmVhZF9ub25ibG9jazpqKCJjb25zb2xlX3JlYWRfbm9uYmxvY2siKSxobHQ6aigiaGx0IiksbW1hcF91c2VyX3BhZ2U6aigibW1hcF91c2VyX3BhZ2UiKSxtdW5tYXBfdXNlcl9wYWdlOmooIm11bm1hcF91c2VyX3BhZ2UiKSxzcGF3bl93b3JrZXI6aigic3Bhd25fd29ya2VyIiksdGVybWluYXRlX3dvcmtlcjpqKCJ0ZXJtaW5hdGVfd29ya2VyIiksc2lnbmFsX2luamVjdDpqKCJzaWduYWxfaW5qZWN0IiksdmlydGlvX2tpY2s6aigidmlydGlvX2tpY2siKX0scG49e2Vudjp7a2VybmVsX21lbW9yeTplLmtlcm5lbE1lbW9yeVdhc219LGxpbnV4OmVlLGh3anNfc3VzcGVuZDp7cGFyazpDZS5ndWFyZFBhcmsoKCk9Pnt9KX19LEJ0PVhsKGUudm1saW51eE1vZHVsZSk7aWYoQnQubGVuZ3RoPjApcmV0dXJuIHQoe2tpbmQ6InZtbGludXgtZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOmB1YWNjZXNzLWxlYWYtd2l0bmVzczogcmVmdXNpbmcgdG8gaW5zdGFudGlhdGUgdm1saW51eCBpbiB0aGUgcHJvY2VzcyBXb3JrZXI6CiAgLSBgK0J0LmpvaW4oYAogIC0gYCl9KSxudWxsO2xldCBrbj1XZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhlLnZtbGludXhNb2R1bGUpLHduPVtdO2ZvcihsZXQgSSBvZiBrbil7bGV0IE89T2JqZWN0Lmhhc093bihwbixJLm1vZHVsZSk/cG5bSS5tb2R1bGVdOnZvaWQgMDsoIU98fCFPYmplY3QuaGFzT3duKE8sSS5uYW1lKSkmJnduLnB1c2goYCR7SS5tb2R1bGV9LiR7SS5uYW1lfSAoJHtJLmtpbmR9KWApfWlmKHduLmxlbmd0aD4wKXJldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToiSzExLUIyYTogdm1saW51eCBpbXBvcnQtcmVzb2x1dGlvbiBmYWlsdXJlIGluIHByb2Nlc3MgV29ya2VyOyBtaXNzaW5nOiAiK3duLmpvaW4oIiwgIil9KSxudWxsO2xldCBoZTt0cnl7bnMoZSx0LCJ2bWxpbnV4LWluc3RhbnRpYXRlLWJlZ2luIiksaGU9YXdhaXQgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGUoZS52bWxpbnV4TW9kdWxlLHBuKSxucyhlLHQsInZtbGludXgtaW5zdGFudGlhdGUtZW5kIiksWHIrPTE7e2xldCBJPWhlLmV4cG9ydHMud2FzbTMyX2NvbW1pdHRlZF9wYWdlcztJJiZ0eXBlb2YgSS52YWx1ZT09Im51bWJlciImJihQdD1JLnZhbHVlPj4+MD4+Mil9dHlwZW9mIGhlLmV4cG9ydHMuX193YXNtMzJfc2V0X2Nvb3Bfc2NoZWQ9PSJmdW5jdGlvbiImJmhlLmV4cG9ydHMuX193YXNtMzJfc2V0X2Nvb3Bfc2NoZWQoMCk7e2xldCBJPWhlLmV4cG9ydHMuX19od2pzX3BhcmtlZF9sYW5lcz8/aGUuZXhwb3J0cy5fX2h3anNfcGFya2VkLE89SSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbD9JLnZhbHVlPj4+MDowO2lmKE8pe2xldCB0ZT1oZS5leHBvcnRzLl9faHdqc19wYXJrZWRfbGFuZXM/KGUuY3B1SWR8MCkqNDowLHE9Tyt0ZT4+MixPZT1uZXcgVWludDMyQXJyYXkoZS5rZXJuZWxNZW1vcnlXYXNtLmJ1ZmZlcik7Q2Uuc2V0UGFya2VkU2xvdFJlYWRlcigoKT0+T2VbcV0+Pj4wKX19fWNhdGNoKEkpe3JldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToiSzExLUIyYTogdm1saW51eCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZSB0cmFwcGVkOiAiKyhJIGluc3RhbmNlb2YgRXJyb3I/SS5tZXNzYWdlOlN0cmluZyhJKSl9KSxudWxsfWlmKHR5cGVvZiBoZS5leHBvcnRzLl9faHdqc19idWRnZXRfc2V0PT0iZnVuY3Rpb24iJiZoZS5leHBvcnRzLl9faHdqc19idWRnZXRfc2V0KFV1fDApLHR5cGVvZiBoZS5leHBvcnRzLl9fd2FzbV9jYWxsX2N0b3JzPT0iZnVuY3Rpb24iKXRyeXtoZS5leHBvcnRzLl9fd2FzbV9jYWxsX2N0b3JzKCl9Y2F0Y2goSSl7cmV0dXJuIHQoe2tpbmQ6InZtbGludXgtZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiJLMTEtQjJhOiB2bWxpbnV4IF9fd2FzbV9jYWxsX2N0b3JzIHRyYXBwZWQgKGxpa2VseSBhIHNlY29uZC1pbnN0YW5jZSBfX3dhc21faW5pdF9tZW1vcnkgb3IgYWN0aXZlLW92ZXJsYXkgaW52YXJpYW50IHZpb2xhdGlvbik6ICIrKEkgaW5zdGFuY2VvZiBFcnJvcj9JLm1lc3NhZ2U6U3RyaW5nKEkpKX0pLG51bGx9aWYodHlwZW9mIGUuY3B1SWQ9PSJudW1iZXIiJiZ0eXBlb2YgaGUuZXhwb3J0cy5fX3dhc20zMl9zZXRfY3B1X2lkPT0iZnVuY3Rpb24iKXRyeXtoZS5leHBvcnRzLl9fd2FzbTMyX3NldF9jcHVfaWQoZS5jcHVJZHwwKX1jYXRjaChJKXtyZXR1cm4gdCh7a2luZDoidm1saW51eC1lcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6IksxMS1CMmI6IHZtbGludXggX193YXNtMzJfc2V0X2NwdV9pZCB0cmFwcGVkOiAiKyhJIGluc3RhbmNlb2YgRXJyb3I/SS5tZXNzYWdlOlN0cmluZyhJKSl9KSxudWxsfWlmKHR5cGVvZiBlLmNwdUlkPT0ibnVtYmVyIiYmKGUuY3B1SWR8MCk+PTEmJnR5cGVvZiBoZS5leHBvcnRzLl9fd2FzbTMyX2xhbmVfc3RhY2tfaW5pdD09ImZ1bmN0aW9uIil0cnl7IShoZS5leHBvcnRzLl9fd2FzbTMyX2xhbmVfc3RhY2tfaW5pdCgpPj4+MCkmJnQoe2tpbmQ6ImRtZXNnIixsZXZlbDo0LHRleHQ6YGh3anMgIzYxIFJFRCBhcm0gKHdhc21fc2hhcmVkX2xhbmVfc3RhY2spOiBsYW5lICR7ZS5jcHVJZHwwfSBrZWVwcyB0aGUgU0hBUkVEIG1vZHVsZSBzaGFkb3cgc3RhY2sgXHUyMDE0IGNyb3NzLVdvcmtlciBzdGFjayBjb3JydXB0aW9uIGlzIHJlcHJvZHVjaWJsZSBieSBkZXNpZ25gfSl9Y2F0Y2goSSl7cmV0dXJuIHQoe2tpbmQ6InZtbGludXgtZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiIjNjE6IHZtbGludXggX193YXNtMzJfbGFuZV9zdGFja19pbml0IHRyYXBwZWQ6ICIrKEkgaW5zdGFuY2VvZiBFcnJvcj9JLm1lc3NhZ2U6U3RyaW5nKEkpKX0pLG51bGx9ZWxzZSB0eXBlb2YgZS5jcHVJZD09Im51bWJlciImJihlLmNwdUlkfDApPj0xJiZ0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzICM2MTogdm1saW51eCBsYWNrcyBfX3dhc20zMl9sYW5lX3N0YWNrX2luaXQgKG9sZGVyIGJ1aWxkKSBcdTIwMTQgbGFuZSAke2UuY3B1SWR8MH0gcnVucyBkaXJlY3Qga2VybmVsIGNhbGxzIG9uIHRoZSBTSEFSRUQgbW9kdWxlIHNoYWRvdyBzdGFjayAoY3Jvc3MtV29ya2VyIGNvcnJ1cHRpb24gd2luZG93IG9wZW4pYH0pO2xldCBGdD1uZihoZSx0eXBlb2YgZS5jcHVJZD09Im51bWJlciI/ZS5jcHVJZHwwOjAsZS5rZXJuZWxNZW1vcnlXYXNtLHQsZS5waWQsZS5rZXJuZWxMYW5lTG9ja3MsZS50aWQsZS5tZXJnZWRDcHUwTGFuZT09PSEwKSxnbj0wLEVuPTAsdG49ZS5waWR8MDtpZih0eXBlb2YgaGUuZXhwb3J0cy5fX3dhc20zMl9nZXRfaW5pdF90YXNrX2FkZHI9PSJmdW5jdGlvbiImJnR5cGVvZiBoZS5leHBvcnRzLl9fd2FzbTMyX3NldF9jdXJyZW50PT0iZnVuY3Rpb24iKXt0cnl7Z249KGhlLmV4cG9ydHMuX193YXNtMzJfZ2V0X2luaXRfdGFza19hZGRyKCl8MCk+Pj4wLGhlLmV4cG9ydHMuX193YXNtMzJfc2V0X2N1cnJlbnQoZ258MCl9Y2F0Y2goSSl7cmV0dXJuIHQoe2tpbmQ6InZtbGludXgtZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiJLMTEtQjU6IHZtbGludXggX193YXNtMzJfc2V0X2N1cnJlbnQoJmluaXRfdGFzaykgdHJhcHBlZDogIisoSSBpbnN0YW5jZW9mIEVycm9yP0kubWVzc2FnZTpTdHJpbmcoSSkpfSksbnVsbH1pZihlLm1vZGU9PT0ibWlncmF0ZS1yZXN1bWUiKXtsZXQgST0oZS5taWdyYXRlVGFza0FkZHJ8MCk+Pj4wO2lmKEk9PT0wKXJldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToibWlncmF0ZS1yZXN1bWUgd2l0aG91dCBhIG1pZ3JhdGVUYXNrQWRkciBcdTIwMTQgYSBtaWdyYXRpb24gYmluZHMgYW4gRVhJU1RJTkcgdGFzayBhbmQgdGhlcmUgaXMgbm90aGluZyB0byBiaW5kIChuZXZlci1zaWxlbnQ7IHRoZSBzb3VyY2Ugc3RpbGwgaG9sZHMgdGhlIHRhc2sgYW5kIHdpbGwgcmVzdW1lIGl0KSJ9KSxudWxsO2xldCBPPTA7dHJ5e2hlLmV4cG9ydHMuX193YXNtMzJfc2V0X2N1cnJlbnQoSXwwKSx0eXBlb2YgaGUuZXhwb3J0cy5fX3dhc20zMl90YXNrX3BpZD09ImZ1bmN0aW9uIiYmKE89aGUuZXhwb3J0cy5fX3dhc20zMl90YXNrX3BpZChJfDApfDApfWNhdGNoKHEpe3JldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToibWlncmF0ZS1yZXN1bWUgYmluZCBvZiB0YXNrIDB4IitJLnRvU3RyaW5nKDE2KSsiIHRyYXBwZWQ6ICIrKHEgaW5zdGFuY2VvZiBFcnJvcj9xLm1lc3NhZ2U6U3RyaW5nKHEpKX0pLG51bGx9bGV0IHRlPWUubWlncmF0ZVBpZHwwO2lmKHRlPjAmJk8hPT10ZSlyZXR1cm4gdCh7a2luZDoidm1saW51eC1lcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6YG1pZ3JhdGUtcmVzdW1lIGJpbmQgUkVGVVNFRDogdGFzayBhZGRyZXNzIDB4JHtJLnRvU3RyaW5nKDE2KX0gcmVwb3J0cyBwaWQgJHtPfSwgdGhlIHNvdXJjZSBzYWlkICR7dGV9LiBSZWZ1c2luZyB0byBkcml2ZSBhIHRhc2sgdGhhdCBpcyBub3QgdGhlIG9uZSBiZWluZyBtaWdyYXRlZCAobmV2ZXItc2lsZW50KS5gfSksbnVsbDtFbj1JLE8+MCYmKHRuPU8pfWVsc2UgaWYodHlwZW9mIGhlLmV4cG9ydHMuX193YXNtMzJfYWxsb2NfcHJvY2Vzc190YXNrPT0iZnVuY3Rpb24iKXRyeXtsZXQgST0oZS5wcGlkfDApPj4+MCxPPWUuaW5oZXJpdEZpbGVzPT09Mj8yOmUuaW5oZXJpdEZpbGVzPzE6MCx0ZT1lLm1vZGU9PT0idGhyZWFkIj9lLnRpZHwwOjAscT1yKCgpPT5oZS5leHBvcnRzLl9fd2FzbTMyX2FsbG9jX3Byb2Nlc3NfdGFzayhlLnBpZHwwLEl8MCxPfDAsdGV8MCl8MCwicmF3QWxsb2NDYWxsIik7bnMoZSx0LCJhbGxvYy1wcm9jZXNzLXRhc2stYmVnaW4iKTtsZXQgT2U9KChGdD9GdC5icmFja2V0KCJfX3dhc20zMl9hbGxvY19wcm9jZXNzX3Rhc2siLHEpOnEoKSl8MCk+Pj4wO2lmKG5zKGUsdCxgYWxsb2MtcHJvY2Vzcy10YXNrLWVuZCBhZGRyPSR7T2V9YCksT2U9PT0wKXJldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToibGludXgjNzogdm1saW51eCBfX3dhc20zMl9hbGxvY19wcm9jZXNzX3Rhc2soIisoZS5waWR8MCkrIiwgIisoZS5wcGlkfDApKyIpIHJldHVybmVkIDAgKGFsbG9jX3BpZCBmYWlsdXJlKSBcdTIwMTQgc3Bhd24gcmVmdXNlZCAoaHdqcyM2NTogcGFyZW50IGdldHMgLUVBR0FJTiwgdGhlIG1hY2hpbmUga2VlcHMgcnVubmluZykifSksbnVsbDt7aWYoaGUuZXhwb3J0cy5fX3dhc20zMl9zZXRfY3VycmVudChPZXwwKSxFbj1PZSx0eXBlb2YgaGUuZXhwb3J0cy5fX3dhc20zMl90YXNrX3BpZD09ImZ1bmN0aW9uIil7bGV0IFl0PWhlLmV4cG9ydHMuX193YXNtMzJfdGFza19waWQoT2V8MCl8MDtZdD4wJiYodG49WXQpfWUubW9kZT09PSJ0aHJlYWQiJiZ0eXBlb2YgaGUuZXhwb3J0cy5fX3dhc20zMl90YXNrX3NldF90aHJlYWRfd29ya2VyPT0iZnVuY3Rpb24iJiZoZS5leHBvcnRzLl9fd2FzbTMyX3Rhc2tfc2V0X3RocmVhZF93b3JrZXIoT2V8MCk7bGV0IEhlPUFycmF5LmlzQXJyYXkoZS5mZEFjdGlvbnMpP2UuZmRBY3Rpb25zOm51bGw7aWYoSGUmJnR5cGVvZiBoZS5leHBvcnRzLndhc21fc3lzY2FsbD09ImZ1bmN0aW9uIilmb3IobGV0IGFlPTA7YWU8SGUubGVuZ3RoO2FlKyspe2xldCAkZT1IZVthZV0sVWU9JGVbMF18MCxvdD0kZVsxXXwwLHN0PSRlWzJdfDAsU2U7aWYoVWU9PT0wKXtsZXQgWmU9cigoKT0+aGUuZXhwb3J0cy53YXNtX3N5c2NhbGwoMzMsb3Qsc3QsMCwwLDAsMCl8MCwiY2FsbCIpO1NlPShGdD9GdC5kaXNwYXRjaFN5c2NhbGwoMzMsWmUpOlplKCkpfDB9ZWxzZSBpZihVZT09PTEpe2xldCBaZT1yKCgpPT5oZS5leHBvcnRzLndhc21fc3lzY2FsbCgzLG90LDAsMCwwLDAsMCl8MCwiY2FsbCIpO1NlPShGdD9GdC5kaXNwYXRjaFN5c2NhbGwoMyxaZSk6WmUoKSl8MH1lbHNlIFNlPS0yMjtpZihTZTwwKXJldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToiSzEzLUE6IHNwYXduIGZkLWFjdGlvbiAiK2FlKyIgKG9wPSIrVWUrIiwgZmQxPSIrb3QrIiwgZmQyPSIrc3QrIikgZmFpbGVkIHJjPSIrU2V9KSxudWxsfX19Y2F0Y2goSSl7dHJ5e2lmKHR5cGVvZiBoZS5leHBvcnRzLl9faHdqc19sYW5lX2NvbnRhaW49PSJmdW5jdGlvbiIpe2xldCBPPWhlLmV4cG9ydHMuX19od2pzX2xhbmVfY29udGFpbigpfDA7TyE9PTAmJnQoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YGh3anMgIzg1IENPTlRBSU5NRU5UIHBpZD0ke2UucGlkfSAoYWxsb2MtdGFzayB0cmFwKToga2VybmVsIGxhbmUgc3RhdGUgcmVjbGFpbWVkIChkaXJ0eSBtYXNrPSR7T30pIFx1MjAxNCB0aGlzIHNwYXduIGRlZ3JhZGVzIC1FQUdBSU4sIHRoZSBuZXh0IHNwYXduIG9uIHRoaXMgbGFuZSB3b3Jrc2B9KX19Y2F0Y2h7fXJldHVybiB0KHtraW5kOiJ2bWxpbnV4LWVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToiSzExLUMxLmE6IHZtbGludXggX193YXNtMzJfYWxsb2NfcHJvY2Vzc190YXNrKCIrKGUucGlkfDApKyIsICIrKGUucHBpZHwwKSsiKSB0cmFwcGVkOiAiKyhJIGluc3RhbmNlb2YgRXJyb3I/SS5tZXNzYWdlOlN0cmluZyhJKSkrKEkgaW5zdGFuY2VvZiBFcnJvciYmSS5zdGFjaz9gCkFMTE9DLVRBU0stU1RBQ0s6IGArSS5zdGFjay5zcGxpdChgCmApLnNsaWNlKDAsMTIpLmpvaW4oIiB8ICIpOiIiKX0pLG51bGx9fWlmKHR5cGVvZiBlLnNpZ25hbFBlbmRpbmdPZmZzZXQ9PSJudW1iZXIiJiZ0eXBlb2YgaGUuZXhwb3J0cy5fX3dhc20zMl9rZXJuZWxfc2V0X3NpZ25hbF9yZWdpb249PSJmdW5jdGlvbiIpdHJ5e2hlLmV4cG9ydHMuX193YXNtMzJfa2VybmVsX3NldF9zaWduYWxfcmVnaW9uKGUuc2lnbmFsUGVuZGluZ09mZnNldD4+PjApfWNhdGNoe31sZXQgc3M9dHlwZW9mIGhlLmV4cG9ydHMud2FzbV9zeXNjYWxsPT0iZnVuY3Rpb24iLEw9MDtpZih0eXBlb2YgaGUuZXhwb3J0cy5fX2h3anNfdGFza193YWtlX2FkZHI9PSJmdW5jdGlvbiIpdHJ5e0w9aGUuZXhwb3J0cy5fX2h3anNfdGFza193YWtlX2FkZHIoKT4+PjB9Y2F0Y2h7fWlmKGUubWVyZ2VkQ3B1MExhbmU9PT0hMCYmZS5tb2RlIT09Im1pZ3JhdGUtcmVzdW1lIiYmTm4hPT1udWxsJiZlLnJvdXRlS2V5IT1udWxsKXtsZXQgSTt0cnl7ST1Obih7a2luZDoidGFzay1yZWdpc3Rlci1zeW5jIixyb3V0ZUtleTplLnJvdXRlS2V5LHBpZDp0bn0pfWNhdGNoe0k9dm9pZCAwfWlmKEkhPT0icmVnaXN0ZXJlZCIpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo0LHRleHQ6YGh3anMtbWVyZ2VkIFJFR0lTVEVSLVNZTkMgREVDTElORUQgcGlkPSR7dG58MH0gdGlkPSR7ZS50aWR8MH0gcm91dGVLZXk9JHtlLnJvdXRlS2V5fTogdGhlIGhvc3QgZGlkIG5vdCByZWdpc3RlciB0aGlzIHRhc2sgdGhyb3VnaCB0aGUgc3luY2hyb25vdXMgZG9vciAoYW5zd2VyPSR7ST09PXZvaWQgMD8iZGVjbGluZWQiOlN0cmluZyhJKX0pLCBzbyBpdHMga2VybmVsIHBpZCBhcnJpdmVzIG9ubHkgd2l0aCB0aGUgdm1saW51eC1yZWFkeSBNRVNTQUdFIFx1MjAxNCB3aGljaCB0aGlzIHRocmVhZCBjYW5ub3QgZGVsaXZlciB3aGlsZSB0aGUgZ3Vlc3QgaG9sZHMgaXQuIEV2ZXJ5IGhvc3QtYW5zd2VyZWQgc3lzY2FsbCB1bnRpbCB0aGVuIHRha2VzIHRoZSBkZWZlcnJlZCAtNTE3IHJvdXRlIGFuZCBkZXBlbmRzIG9uIHRoaXMgbGliYyByZS1pc3N1aW5nIGl0LmB9KX1jYXRjaHt9fXJldHVybiB0KHtraW5kOmUubW9kZT09PSJtaWdyYXRlLXJlc3VtZSI/InZtbGludXgtcmVib3VuZCI6InZtbGludXgtcmVhZHkiLHBpZDp0bix0aWQ6ZS50aWQsaGFzV2FzbVN5c2NhbGw6c3MsaW5pdFRhc2tBZGRyOmduLHBlclByb2Nlc3NUYXNrQWRkcjpFbixwZXJQcm9jZXNzVGFza1dha2VBZGRyOkwsLi4uZS5tb2RlPT09Im1pZ3JhdGUtcmVzdW1lIj97Y3B1SWQ6ZS5jcHVJZHwwfTp7fX0pLHtpbnN0YW5jZTpoZSxpbml0VGFza0FkZHI6Z24scGVyUHJvY2Vzc1Rhc2tBZGRyOkVuLGtlcm5lbFBpZDp0bixod2pzTGFuZTpGdH19cihJYSwiaW5zdGFudGlhdGVQcm9jZXNzV29ya2VyVm1saW51eCIpO2Z1bmN0aW9uIHNmKHtnZXRFeHBvcnRzOmUsZ2V0TGFuZTp0LHBvc3Q6b30pe2xldCBzPXtwaGFzZToiaWRsZSIscGF0aFB0cjowLHJlbWFpbmluZzowLGNodW5rczowLGJsb2NrczowLGNoYWluOntoOjAsb3duZXI6MH19LGw9MDtmdW5jdGlvbiBkKCl7bD1zLmJsb2NrcyxzLnBoYXNlPSJpZGxlIixzLnBhdGhQdHI9MCxzLnJlbWFpbmluZz0wLHMuY2h1bmtzPTAscy5ibG9ja3M9MCxzLmNoYWluLmg9MCxzLmNoYWluLm93bmVyPTB9cihkLCJleGVjTG9hZFBoYXNlUmVzZXQiKTtsZXQgXz1udWxsO2Z1bmN0aW9uIG0oaCxnPSExKXtsZXQgeD1lKCksUz10KCk7aWYodHlwZW9mIHgud2FzbTMyX3VzZXJfZXhlY19sb2FkX2JlZ2luIT0iZnVuY3Rpb24ifHx0eXBlb2YgeC53YXNtMzJfdXNlcl9leGVjX2xvYWRfc3RlcCE9ImZ1bmN0aW9uIil7bGV0IFI9cigoKT0+eC53YXNtMzJfdXNlcl9leGVjX2xvYWQoaD4+PjApfDAsImxvYWRDYWxsIik7cmV0dXJuKFM/Uy5icmFja2V0KCJ3YXNtMzJfdXNlcl9leGVjX2xvYWQiLFIpOlIoKSl8MH1pZihzLnBoYXNlPT09ImlkbGUiKXR5cGVvZiB4Lndhc20zMl91c2VyX2V4ZWNfZGVmZXJfY29tbWl0PT0iZnVuY3Rpb24iJiZ4Lndhc20zMl91c2VyX2V4ZWNfZGVmZXJfY29tbWl0KCkscy5waGFzZT0iYmVnaW4iLHMucGF0aFB0cj1oPj4+MCxzLnJlbWFpbmluZz0xLzAscy5jaHVua3M9MCxzLmJsb2Nrcz0wO2Vsc2UgaWYocy5wYXRoUHRyIT09aD4+PjApdGhyb3cgbmV3IEVycm9yKGBleGVjTG9hZEtlcm5lbENodW5rZWQ6IGEgbG9hZCBmb3IgcGF0aFB0cj0weCR7KGg+Pj4wKS50b1N0cmluZygxNil9IGVudGVyZWQgd2hpbGUgYSBsb2FkIGZvciAweCR7cy5wYXRoUHRyLnRvU3RyaW5nKDE2KX0gaXMgaW4gZmxpZ2h0IChwaGFzZT0ke3MucGhhc2V9LCBjaHVua3M9JHtzLmNodW5rc30sIGNoYWluPTB4JHtzLmNoYWluLmgudG9TdHJpbmcoMTYpfSkgXHUyMDE0IHJlZnVzaW5nIHRvIGFiYW5kb24gYSBsaXZlIGNoYWluIChuZXZlci1zaWxlbnQpYCk7Zm9yKDs7KXtsZXQgUj1zLnBoYXNlPT09ImJlZ2luIix3PVI/X2E6c2QseTt0cnl7eT1jKHcsaCl8MH1jYXRjaChEKXt0aHJvdyBkKCksRH1pZih5PT09ZnQpe2lmKHMuYmxvY2tzKyssZylyZXR1cm4gZnQ7Y29udGludWV9aWYoeT09PSRkKXJldHVybiB5fDA7aWYoeTwwKXJldHVybiBkKCkseXwwO2lmKHk9PT0wKXJldHVybiBkKCksMDtpZighKHk8cy5yZW1haW5pbmcpKXtsZXQgRD1zLnJlbWFpbmluZz09PTEvMD8iXHUyMjFFIjpzLnJlbWFpbmluZyxkZT1zLmNodW5rczt0aHJvdyBkKCksbmV3IEVycm9yKGBleGVjTG9hZEtlcm5lbENodW5rZWQ6ICR7Uj8iYmVnaW4iOiJzdGVwIn0gbGVmdCAke3l9IGJ5dGVzIHJlbWFpbmluZywgbm8gZmV3ZXIgdGhhbiB0aGUgJHtEfSBiZWZvcmUgaXQgKCR7ZGV9IHJlYWwgY2h1bmtzIHNvIGZhcikgXHUyMDE0IHRoZSBjaHVua2VkIGxvYWRlciBpcyBub3QgcHJvZ3Jlc3Npbmc7IHJlZnVzaW5nIHRvIHNwaW4gKG5ldmVyLXNpbGVudClgKX1zLnJlbWFpbmluZz15LHMuY2h1bmtzKysscy5waGFzZT0ic3RlcCJ9fXIobSwibG9hZCIpO2Z1bmN0aW9uIGMoaCxnKXtsZXQgeD1lKCksUz10KCksUj1oPT09X2E7aWYoIVMpcmV0dXJuKFI/eC53YXNtMzJfdXNlcl9leGVjX2xvYWRfYmVnaW4oZz4+PjApOngud2FzbTMyX3VzZXJfZXhlY19sb2FkX3N0ZXAoKSl8MDtpZihfIT09ITEmJnR5cGVvZiB4Lndhc21fc3lzY2FsbD09ImZ1bmN0aW9uIil7bGV0IHc9Uy5kcml2ZVdvdWxkQmxvY2soYHdhc21fc3lzY2FsbDoke2h9YCwoKT0+eC53YXNtX3N5c2NhbGwoaCxnPj4+MCwwLDAsMCwwLDApfDAscy5jaGFpbik7aWYody53b3VsZEJsb2NrKXJldHVybiBfPSEwLGZ0O2lmKHcudmFsdWUhPT0tMzgpcmV0dXJuIF89ITAsdy52YWx1ZXwwO2lmKF89PT1udWxsKXtfPSExO3RyeXtvKHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLWV4ZWM6IHRoaXMgdm1saW51eCBhbnN3ZXJzIG5vIF9fTlJfd2FzbV9leGVjX2xvYWRfYmVnaW4vX3N0ZXAgKCR7X2F9LyR7c2R9KTsgZHJpdmluZyB0aGUgY2h1bmtlZCBsb2FkIHRocm91Z2ggdGhlIGJhcmUgZXhwb3J0cywgd2hpY2ggZ2V0IG5vIHBhcmsgcHJlc2VydmF0aW9uLiBOZXZlci1zaWxlbnQuYH0pfWNhdGNoe319ZWxzZSByZXR1cm4tMzh9cmV0dXJuIFMuYnJhY2tldFlpZWxkaW5nKFI/Indhc20zMl91c2VyX2V4ZWNfbG9hZF9iZWdpbiI6Indhc20zMl91c2VyX2V4ZWNfbG9hZF9zdGVwIiwoKT0+KFI/eC53YXNtMzJfdXNlcl9leGVjX2xvYWRfYmVnaW4oZz4+PjApOngud2FzbTMyX3VzZXJfZXhlY19sb2FkX3N0ZXAoKSl8MCl8MH1yZXR1cm4gcihjLCJleGVjTG9hZElzc3VlIikse2xvYWQ6bSxwaGFzZTpzLGJsb2NrczpyKCgpPT5zLmJsb2NrcywiYmxvY2tzIiksYmxvY2tzTGFzdDpyKCgpPT5sLCJibG9ja3NMYXN0Iil9fXIoc2YsIm1ha2VFeGVjSW1hZ2VMb2FkZXIiKTtmdW5jdGlvbiBtZChlKXtyZXR1cm4gcihhc3luYyBmdW5jdGlvbihvKXtsZXQgcz1scigpO2F3YWl0IGUobyksYXdhaXQgc30sInBhcmtZaWVsZFdpdGhUdXJuIil9cihtZCwibWFrZVBhcmtZaWVsZFdpdGhUdXJuIik7YXN5bmMgZnVuY3Rpb24gZnIoe2xvYWQ6ZSx5aWVsZFR1cm46dCxvbllpZWxkOm99KXtmb3IoOzspe2xldCBzPWUoKXwwO2lmKHMhPT1mdClyZXR1cm4gcztvJiZvKCksYXdhaXQgdCgpfX1yKGZyLCJkcml2ZUV4ZWNMb2FkV2l0aFlpZWxkIik7dmFyIHBkPS01NDAsUmE9cihlPT5lPD0tNTEyJiZlPj0tNTE3JiZlIT09LTUxNSwiaXNSZXN0YXJ0VmFsdWUiKTtmdW5jdGlvbiByZih7bGVuOmUsZnJvbTp0PTAscmVhZDpvLHdhaXQ6cz1udWxsLHJlc3RhcnRDYXA6bD0xLzB9KXtsZXQgZD10LF89MCxtPTAsYz1yKChoLGcseCk9Pih7ZG9uZTpkLGVycjpoLHBhcmtlZDpnLGxvc3Q6eCxyZXN0YXJ0czptfSksIm91dCIpO2Zvcig7ZDxlOyl7bGV0IGg9byhkKXwwO2lmKFJhKGgpKXtpZihtKyssIXMpcmV0dXJuIGMoMCwhMCwhMSk7aWYoKytfPmwpcmV0dXJuIGMoLTQsITEsITApO3MoKTtjb250aW51ZX1pZihoPT09MClicmVhaztpZihoPDApcmV0dXJuIGMoaCwhMSwhMSk7ZCs9aCxfPTB9cmV0dXJuIGMoMCwhMSwhMSl9cihyZiwicG9wdWxhdGVGaWxlTWFwcGluZyIpO2Z1bmN0aW9uIG9mKHthbGxvYzplLGZyZWU6dCxyZWFkOm8sZ3Vlc3RSZXN1bWVzOnMsY2FuV2FpdDpsLHdhaXQ6ZCxlcG9jaDpfLHJlc3RhcnRDYXA6bX0pe2xldCBjPW51bGwsaD1yKGc9Pih7YWRkcjowLGRvbmU6MCxlcnI6MCxwYXJrZWQ6ITEsbG9zdDohMSxyZXN0YXJ0czowLC4uLmd9KSwibm9uZSIpO3JldHVybnttYXAoZyl7bGV0IHg9MCxTPS0xO2lmKGMhPT1udWxsKXtsZXQgRD1jO2lmKEQubWZkPT09Zy5tZmQmJkQubGVuPT09Zy5sZW4mJkQucHJvdD09PWcucHJvdCYmRC5mbGFncz09PWcuZmxhZ3MmJkQub2ZmPT09Zy5vZmYmJkQuZXBvY2g9PT1fKCkpYz1udWxsLFM9RC5hZGRyLHg9RC5kb25lO2Vsc2V7bGV0IHo9byhELEQuYWRkcixELmRvbmUpfDA7aWYoUmEoeikpcmV0dXJuIGgoe3BhcmtlZDohMCxyZXN0YXJ0czoxfSk7Yz1udWxsLHQoRC5hZGRyLEQubGVuKX19aWYoUzwwJiYoUz1lKGcpfDAsUzwwKSlyZXR1cm4gaCh7YWRkcjpTLGVycjpTfSk7bGV0IFI9cygpLHc9MCx5PXJmKHtsZW46Zy5sZW4sZnJvbTp4LHJlYWQ6cihEPT53PW8oZyxTLEQpfDAsInJlYWQiKSx3YWl0OiFSJiZsKCk/ZDpudWxsLHJlc3RhcnRDYXA6bX0pO2lmKHkucGFya2VkJiZSKWM9ey4uLmcsYWRkcjpTLGRvbmU6eS5kb25lLGVwb2NoOl8oKX07ZWxzZSBpZih5LnBhcmtlZClyZXR1cm4gdChTLGcubGVuKSx7YWRkcjpTLC4uLnkscGFya2VkOiExLGVycjp3fTtyZXR1cm57YWRkcjpTLC4uLnl9fSxyZXNldCgpe2M9bnVsbH19fXIob2YsIm1ha2VGaWxlTWFwcGVyIik7ZnVuY3Rpb24gYWYoZSx0KXtpZih0PDApcmV0dXJuITE7bGV0IG89QXRvbWljcy5sb2FkKGUsdCl8MCxzPUF0b21pY3MubG9hZChlLHQrMSl8MDtyZXR1cm4gbyE9PTB8fHMhPT0wfXIoYWYsIndhc21TaWduYWxQZW5kaW5nSW4iKTt2YXIgbGY9MTI7ZnVuY3Rpb24gZGYoZSl7cmV0dXJuKGUmMykhPT0wJiYoZSYtOTQ3Nik9PT0wfXIoZGYsInRhc2tTdGF0ZVNsZWVwaW5nIik7ZnVuY3Rpb24gd2QoZSx0LG8scyxsKXtsZXQgZD1zPj0wP0F0b21pY3MubG9hZChlLHMpfDA6MCxfPUF0b21pY3Mud2FpdEFzeW5jKGUsdCxvLGwpO2lmKCFfLmFzeW5jKXJldHVybiBQcm9taXNlLnJlc29sdmUoXy52YWx1ZSk7aWYoczwwfHwhZGYoZCkpcmV0dXJuIF8udmFsdWU7bGV0IG09QXRvbWljcy53YWl0QXN5bmMoZSxzLGQsbCk7cmV0dXJuIG0uYXN5bmM/UHJvbWlzZS5yYWNlKFtfLnZhbHVlLnRoZW4oYz0+W3MsY10pLG0udmFsdWUudGhlbihjPT5bdCxjXSldKS50aGVuKChbYyxoXSk9PihBdG9taWNzLm5vdGlmeShlLGMsMSksaCkpOihBdG9taWNzLm5vdGlmeShlLHQsMSksUHJvbWlzZS5yZXNvbHZlKG0udmFsdWUpKX1yKHdkLCJ3YWl0VGFza1J1bm5hYmxlIik7dmFyIGdkPTAsY2Y9Mix1Zj02LHlkPTY1NTM2O2Z1bmN0aW9uIGZmKHtnZXRJMzI6ZSxnZXRJZHg6dCxpbkV4ZWNXaW5kb3c6byxhc2tLZXJuZWw6cyxyZWQ6bH0pe2xldCBkPSEhKGwmJmwuaG9zdFdyaXRlc0JpdCk7ZnVuY3Rpb24gXygpe2xldCB4PXQoKTtyZXR1cm4geDwwPyExOihBdG9taWNzLmxvYWQoZSgpLHgrZ2QpJnlkKSE9PTB9cihfLCJwZW5kaW5nTm93Iik7ZnVuY3Rpb24gbSgpe2xldCB4PXQoKTtyZXR1cm4geDwwPzA6QXRvbWljcy5sb2FkKGUoKSx4K3VmKT4+PjB9cihtLCJkZWxpdmVyeVNlcSIpO2Z1bmN0aW9uIGMoKXtsZXQgeD10KCk7aWYoeDwwKXJldHVybjtsZXQgUz14K2NmO0F0b21pY3MuYWRkKGUoKSxTLDEpLEF0b21pY3Mubm90aWZ5KGUoKSxTLDEvMCl9cihjLCJ3YWtlIik7ZnVuY3Rpb24gaCgpe2xldCB4PXQoKTtyZXR1cm4geDwwPyExOmQ/KEF0b21pY3Mub3IoZSgpLHgrZ2QseWQpLGMoKSwhMCk6cygpPjA/KGMoKSwhMCk6ITF9cihoLCJyZXB1Ymxpc2giKTtmdW5jdGlvbiBnKHgpe3JldHVybiF4fHxvKCl8fF8oKT8hMTpoKCl9cmV0dXJuIHIoZywibWF5YmVSZWFzc2VydCIpLHtwZW5kaW5nTm93Ol8sZGVsaXZlcnlTZXE6bSxtYXliZVJlYXNzZXJ0OmcscmVwdWJsaXNoOmh9fXIoZmYsIm1ha2VTaWdjaGxkUmVhc3NlcnQiKTt2YXIgX2Y9bmV3IFNldChbOSwxMCwxMSwxMiwyNCw2MCwyMzFdKSx5YT1uZXcgU2V0KFswLDEsMTcsMTgsMTksMjAsMjMsNyw2MSwzNSwyMzAsMjU3LDMsMjcwLDI3MSw0Miw0Myw0NCw0NSw0Niw0Nyw3NCw3NSwzNCwxMjgsMTMwXSk7YXN5bmMgZnVuY3Rpb24gVGQoZSx0LG8pe25zKGUsdCwicnVuLWVudHJ5IiksQ3QodCxgUlVOIGNwdT0ke2UuY3B1SWQ/PyI/In0gdGlkPSR7ZS50aWR9IHBpZD0ke2UucGlkfSBtb2RlPSR7ZS5tb2RlPz8iZm9yayJ9IGxhbmU9JHtlLnVzZXJMYW5lPz8wfSByZXNpZGVudD0ke28/MTowfWApO2xldCBzPW5ldyBJbnQzMkFycmF5KGUuY3RybCwwLDE2KTtzW00uUElEXT1lLnBpZCxzW00uVElEXT1lLnRpZCxRcihlLnNoYXJlZExpYnMsdCksdnMuc2V0KGUse2dldFBpZDpyKCgpPT5zW00uUElEXXwwLCJnZXRQaWQiKSxidWlsZDpyKCgpPT54cigpLCJidWlsZCIpfSk7bGV0IGw9ZS5wYXVzZUJ1ZmZlcj9uZXcgSW50MzJBcnJheShlLnBhdXNlQnVmZmVyKTpudWxsLGQ9cigoKT0+e2lmKGwpZm9yKDtBdG9taWNzLmxvYWQobCwwKT09PTE7KUF0b21pY3Mud2FpdChsLDAsMSwyMDApfSwibWF5YmVQYXVzZSIpLF89ITEsbT0wLGM9bnVsbCxoPSExLGc9ITEseD0hMTthc3luYyBmdW5jdGlvbiBTKG4sYSl7aWYoIWcmJiEoIUZ8fG5lPT09MHx8dHlwZW9mIEYuZXhwb3J0cy5fX3dhc20zMl9ub3RpZnlfY2hpbGRfZXhpdCE9ImZ1bmN0aW9uIikpe2lmKGc9ITAsZ28pdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtZmQgcGlkPSR7c1tNLlBJRF18MH0gTk9USUZZLUNISUxELUVYSVQgcHRhc2s9MHgkeyhuZT4+PjApLnRvU3RyaW5nKDE2KX0gY29kZT0ke258MH0gc2lnbmFsZWQ9JHthfDB9YH0pfWNhdGNoe310cnl7bGV0IGk9Ri5leHBvcnRzO2lmKHR5cGVvZiBpLndhc20zMl9leGl0X2RyYWluX3N0ZXA9PSJmdW5jdGlvbiImJk5lKXtsZXQgcD17aDowLG93bmVyOjB9LGs9cigoKT0+aS53YXNtMzJfZXhpdF9kcmFpbl9zdGVwKCl8MCwic3RlcCIpLEU9MDthd2FpdCBmcih7bG9hZDpyKCgpPT5OZS5kcml2ZVdvdWxkQmxvY2soIndhc20zMl9leGl0X2RyYWluX3N0ZXAiLGsscCkud291bGRCbG9jaz9mdDowLCJsb2FkIikseWllbGRUdXJuOnIoKCk9PmZzKCJleGl0LWRyYWluIHBhcmsiKSwieWllbGRUdXJuIiksb25ZaWVsZDpyKCgpPT57aWYoRSsrLEU9PT0xKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLWV4aXQgcGlkPSR7ZS5waWR9IHRpZD0ke2UudGlkfDB9IHdhc20zMl9leGl0X2RyYWluX3N0ZXAgd291bGQtYmxvY2sgXHUyMDE0IGhhbmRpbmcgdGhlIENQVSBXb3JrZXIgYmFjayBhY3Jvc3MgYSByZWFsIGV2ZW50LWxvb3AgdHVybiBiZWZvcmUgcmVzdW1pbmcgdGhlIHByZXNlcnZlZCBzeXNjYWxsIGNoYWluICh0aGUgZGV2aWNlIGJhY2tlbmRzIGFuZCB0aGUgaW4tZmxpZ2h0IGZldGNoIGNvbnRpbnVhdGlvbnMgcnVuIGluIHRoYXQgdHVybjsgdGhpcyBpcyB0aGUgdHVybiB0aGUgbmF0aXZlIGluLXdhc20gZHJhaW4gY291bGQgbm90IHRha2UpYH0pfWNhdGNoe31pdCYmQ3QodCxgWUlFTEQgY3B1PSR7ZS5jcHVJZD8/Ij8ifSB0aWQ9JHtlLnRpZH0gcmVhc29uPUVYSVQtRFJBSU4tcGFyayBzaXRlPXdhc20zMi1leGl0LWRyYWluLXN0ZXAgdmlhPXdha2Utd29yZGApfSwib25ZaWVsZCIpfSl9ZWxzZSBpZigheCl7eD0hMDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy1leGl0IHBpZD0ke2UucGlkfSBgKyh0eXBlb2YgaS53YXNtMzJfZXhpdF9kcmFpbl9zdGVwPT0iZnVuY3Rpb24iPyJoYXMgbm8gaHdqcyBsYW5lIGJyYWNrZXQsIHNvICI6InRoaXMgdm1saW51eCBleHBvcnRzIG5vIHdhc20zMl9leGl0X2RyYWluX3N0ZXAsIHNvICIpKyJ0aGUgZXhpdCBkcmFpbiBpcyBOT1QgZHJpdmVuIGZyb20gSlM6IGEgcHJlc2VydmVkIGJsb2NrLXBhcmtlZCBzeXNjYWxsIGlzIGRyYWluZWQgYnkgZW50cnkuYydzIG5hdGl2ZSBpbi13YXNtIHNwaW4gaW5zaWRlIHRhc2tfZXhpdF9jbGVhbnVwLCB3aGljaCBjYW5ub3QgaGFuZCBhIHdvdWxkLWJsb2NrIGJhY2suIE9uIGEgbWVyZ2VkIGxhbmUgdGhhdCBzcGluIGhvbGRzIHRoZSBKUyB0aHJlYWQgdGhlIGJhY2tlbmQgaXQgaXMgd2FpdGluZyBvbiBydW5zIG9uLCBhbmQgdGhlIHdhaXQgZW5kcyBvbmx5IGF0IGZzL2Z1c2UvZGV2LmMncyBkZWFkbGluZSAod2FzbV9mdXNlX3RpbWVvdXQsIDEyMCBzKS4gTmV2ZXItc2lsZW50LiJ9KX1jYXRjaHt9fWlmKHR5cGVvZiBpLnRhc2tfZXhpdF9jbGVhbnVwPT0iZnVuY3Rpb24iKXtsZXQgcD1yKCgpPT4oaS50YXNrX2V4aXRfY2xlYW51cChuZXwwKSwwKSwiY2xlYW51cCIpO2lmKE5lKXtsZXQgaz17aDowLG93bmVyOjB9LEU9MDthd2FpdCBmcih7bG9hZDpyKCgpPT5OZS5kcml2ZVdvdWxkQmxvY2soInRhc2tfZXhpdF9jbGVhbnVwIixwLGspLndvdWxkQmxvY2s/ZnQ6MCwibG9hZCIpLHlpZWxkVHVybjpyKCgpPT5mcygidGFzay1leGl0LWNsZWFudXAgcGFyayIpLCJ5aWVsZFR1cm4iKSxvbllpZWxkOnIoKCk9PntpZihFKyssRT09PTEpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtZXhpdCBwaWQ9JHtlLnBpZH0gdGlkPSR7ZS50aWR8MH0gdGFza19leGl0X2NsZWFudXAgd291bGQtYmxvY2sgXHUyMDE0IGhhbmRpbmcgdGhlIENQVSBXb3JrZXIgYmFjayBhY3Jvc3MgYSByZWFsIGV2ZW50LWxvb3AgdHVybiBiZWZvcmUgcmVzdW1pbmcgdGhlIHByZXNlcnZlZCBjbGVhbnVwIGNoYWluIChjb250cmFjdCAzLCBzaXRlIDQpYH0pfWNhdGNoe31pdCYmQ3QodCxgWUlFTEQgY3B1PSR7ZS5jcHVJZD8/Ij8ifSB0aWQ9JHtlLnRpZH0gcmVhc29uPUVYSVQtQ0xFQU5VUC1wYXJrIHNpdGU9dGFzay1leGl0LWNsZWFudXAgdmlhPXdha2Utd29yZGApfSwib25ZaWVsZCIpfSl9ZWxzZSBwKCl9bGV0IHU9cigoKT0+KGkuX193YXNtMzJfbm90aWZ5X2NoaWxkX2V4aXQobmV8MCxufDAsYXwwKSwwKSwiY2FsbCIpO2lmKE5lP05lLmJyYWNrZXQoIl9fd2FzbTMyX25vdGlmeV9jaGlsZF9leGl0Iix1KTp1KCksdHlwZW9mIGkudGFza19leGl0X25vdGlmeV9wYXJlbnQ9PSJmdW5jdGlvbiIpe2xldCBwPXIoKCk9PihpLnRhc2tfZXhpdF9ub3RpZnlfcGFyZW50KG5lfDApLDApLCJub3RpZnlQYXJlbnQiKTtOZT9OZS5icmFja2V0KCJ0YXNrX2V4aXRfbm90aWZ5X3BhcmVudCIscCk6cCgpfX1jYXRjaChpKXt0KHtraW5kOiJlcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6IkYxMTIgY2hpbGQtZXhpdCAodGFza19leGl0X2NsZWFudXAgLyBfX3dhc20zMl9ub3RpZnlfY2hpbGRfZXhpdCkgdHJhcHBlZDogIisoaSBpbnN0YW5jZW9mIEVycm9yP2kubWVzc2FnZTpTdHJpbmcoaSkpfSl9fX1yKFMsIm5vdGlmeUNoaWxkRXhpdE9uY2UiKTthc3luYyBmdW5jdGlvbiBSKCl7bGV0IG49YztuJiYoYz1udWxsLGF3YWl0IFMobi5jb2RlQXJnLG4uc2lnbmFsZWQpLHcobikpfXIoUiwicnVuRXhpdFRlcm1pbnVzIik7ZnVuY3Rpb24gdyh7Y29kZUFyZzpuLHNpZ25hbGVkOmEsZ3JwRXhpdDppfSl7X3x8KF89ITAsdCh7a2luZDoiZXhpdCIscGlkOmUucGlkLGNvZGU6bSxraW5kX2V4aXQ6YT8iZXhpdC1ieS1zaWduYWwiOiJleGl0IixzaWduYWw6YT9uJjEyNzowLC4uLmk/e2dyb3VwRXhpdDp7d3N0YXR1czppLndzdGF0dXMsemFwcGVkOmkuemFwcGVkfX06e30sd2FzbVN5c2NhbGxTdGF0czp7Li4ucW59LC4uLkpuPjA/e2Nvb3BXYWl0VmlvbGF0aW9uczpKbn06e30sLi4uWm4+MD97c3luY1Jlc3RhcnRWaW9sYXRpb25zOlpufTp7fSwuLi5OZT97aHdqc0xhbmVDZW5zdXM6YmQoTmUpfTp7fX0pKX1yKHcsInBvc3RFeGl0TWVzc2FnZSIpO2Z1bmN0aW9uIHkobil7dHJ5e2lmKEYmJnR5cGVvZiBGLmV4cG9ydHMuX19od2pzX2xhbmVfY29udGFpbj09ImZ1bmN0aW9uIil7dHJ5e3R5cGVvZiBGLmV4cG9ydHMuX19od2pzX2R1bXBfcGFya190cmFjZT09ImZ1bmN0aW9uIiYmRi5leHBvcnRzLl9faHdqc19kdW1wX3BhcmtfdHJhY2UoKX1jYXRjaHt9bGV0IGE9Ri5leHBvcnRzLl9faHdqc19sYW5lX2NvbnRhaW4oKXwwO3JldHVybiBhIT09MCYmdCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgaHdqcyAjODUgQ09OVEFJTk1FTlQgcGlkPSR7ZS5waWR9IHRpZD0ke2UudGlkfDB9ICgke259KToga2VybmVsIGxhbmUgc3RhdGUgcmVjbGFpbWVkIGFmdGVyIGEgdGVybWluYWwgdHJhcCAoZGlydHkgbWFzaz0ke2F9OiAxPW9ycGhhbmVkIHBhcmtlZCBzbG90LCAyPWluLXZpb2xhdGlvbiBsYXRjaCwgND1zdGFsZSBzbGljZSBtYXJrZXIpIFx1MjAxNCBpZGVudGl0aWVzIGluIHRoZSBod2pzLXJ0IGNvbnRhaW5tZW50IGxpbmVzIGFib3ZlYH0pLGF9fWNhdGNoKGEpe3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YGh3anMgIzg1IENPTlRBSU5NRU5UIHBpZD0ke2UucGlkfTogX19od2pzX2xhbmVfY29udGFpbiBpdHNlbGYgdHJhcHBlZCAoJHthIGluc3RhbmNlb2YgRXJyb3I/YS5tZXNzYWdlOlN0cmluZyhhKX0pIFx1MjAxNCBsYW5lIHN0YXRlIE5PVCByZWNsYWltZWQ7IGEgc2FtZS1sYW5lIGJ5c3RhbmRlciBtYXkgc3RpbGwgdHJhcGB9KX1yZXR1cm4gMH1yKHksImNvbnRhaW5UcmFwcGVkTGFuZSIpO2xldCBEPSExLGRlPTA7ZnVuY3Rpb24geihuLGEpe2lmKER8fCFGfHxuZT09PTApcmV0dXJuIG51bGw7RD0hMDtsZXQgaT1hP2BhIGZhdGFsIHRlcm1pbnVzIGJ5IHNpZ25hbCAke24mMTI3fWA6YGV4aXRfZ3JvdXAoJHtuJjI1NX0pYCx1PUYuZXhwb3J0cztpZih0eXBlb2YgdS5fX3dhc20zMl9ncm91cF9leGl0IT0iZnVuY3Rpb24iKXJldHVybiB0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBod2pzLWdyb3VwZXhpdCBwaWQ9JHtlLnBpZH0gdGlkPSR7ZS50aWR8MH06IHRoaXMgdm1saW51eCBoYXMgbm8gX193YXNtMzJfZ3JvdXBfZXhpdCBleHBvcnQgXHUyMDE0ICR7aX0gY2Fubm90IGJlIGRlY2lkZWQgYnkgdGhlIGtlcm5lbCwgc28gZG9fZ3JvdXBfZXhpdC96YXBfb3RoZXJfdGhyZWFkcyBkbyBub3QgcnVuIGFuZCBvbmx5IHRoZSBjYWxsaW5nIHRhc2sgZW5kcy4gS0VSTkVML0hPU1QgU0tFVzogcmVidWlsZCB2bWxpbnV4YH0pLG51bGw7aWYoZGU9PT0wKXRyeXtkZT0odS5fX3dhc20zMl9ncm91cF9leGl0Lmxlbmd0aHwwKT49Mj8yOjF9Y2F0Y2h7ZGU9MX1pZihhJiZkZTwyKXJldHVybiB0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBod2pzLWdyb3VwZXhpdCBwaWQ9JHtlLnBpZH0gdGlkPSR7ZS50aWR8MH06IHRoaXMgdm1saW51eCdzIF9fd2FzbTMyX2dyb3VwX2V4aXQgdGFrZXMgbm8gYnlfc2lnbmFsIGFyZ3VtZW50IFx1MjAxNCAke2l9IGNhbm5vdCBiZSBkZWNpZGVkIGJ5IHRoZSBrZXJuZWwsIHNvIHRoZSBncm91cCBpcyBOT1QgY29uZGVtbmVkIGJ5IGl0IGFuZCB0aGlzIHByb2Nlc3MgbWF5IG91dGxpdmUgYSBmYXRhbCBzaWduYWwgb24gb25lIG9mIGl0cyB0aHJlYWRzLiBLRVJORUwvSE9TVCBTS0VXOiByZWJ1aWxkIHZtbGludXhgfSksbnVsbDt0cnl7bGV0IHA9YT9uJjEyNzpuJjI1NSxrPXIoKCk9PnUuX193YXNtMzJfZ3JvdXBfZXhpdChwLGE/MTowKXwwLCJjYWxsIiksRT0oTmU/TmUuYnJhY2tldCgiX193YXNtMzJfZ3JvdXBfZXhpdCIsayk6aygpKXwwO3JldHVybiBFPDA/bnVsbDp7d3N0YXR1czpFJjY1NTM1LHphcHBlZDpFPj4+MTYmMzI3Njd9fWNhdGNoKHApe3JldHVybiB0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBod2pzLWdyb3VwZXhpdCBwaWQ9JHtlLnBpZH0gdGlkPSR7ZS50aWR8MH06IF9fd2FzbTMyX2dyb3VwX2V4aXQgdHJhcHBlZCAoJHtwIGluc3RhbmNlb2YgRXJyb3I/cC5tZXNzYWdlOlN0cmluZyhwKX0pIFx1MjAxNCB0aGUgZ3JvdXAncyBvdGhlciB0aHJlYWRzIHdlcmUgTk9UIGNvbmRlbW5lZDsgdGhpcyBwcm9jZXNzIG1heSBvdXRsaXZlICR7aX1gfSksbnVsbH19cih6LCJkZWNpZGVHcm91cEV4aXQiKTtmdW5jdGlvbiBRKG49OSxhPSJ0aHJlYWQgdHJhcCIpe3RyeXtsZXQgaT1GP0YuZXhwb3J0czpudWxsO2lmKCFpfHxuZT09PTB8fHR5cGVvZiBpLl9fd2FzbTMyX3RocmVhZF90cmFwX2NvbnRhaW4hPSJmdW5jdGlvbiIpe3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YGh3anMgIzg1IENPTlRBSU5NRU5UIHBpZD0ke2UucGlkfSB0aWQ9JHtlLnRpZHwwfTogJHthfSBncm91cC1raWxsIFVOQVZBSUxBQkxFICh2bWxpbnV4IGV4cG9ydC90YXNrIG1pc3NpbmcpIFx1MjAxNCB0aGUgaG9zdC1zaWRlIHNwYXduLWhhbmRsZXIgYmVsdCBzdGlsbCBkZWxpdmVycyBTSUdLSUxMIHRvIHRoZSBncm91cGB9KTtyZXR1cm59bGV0IHU9cigoKT0+KGkuX193YXNtMzJfdGhyZWFkX3RyYXBfY29udGFpbihufDApLDApLCJjYWxsIik7TmU/TmUuYnJhY2tldCgiX193YXNtMzJfdGhyZWFkX3RyYXBfY29udGFpbiIsdSk6dSgpfWNhdGNoKGkpe3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YGh3anMgIzg1IENPTlRBSU5NRU5UIHBpZD0ke2UucGlkfSB0aWQ9JHtlLnRpZHwwfTogX193YXNtMzJfdGhyZWFkX3RyYXBfY29udGFpbiB0cmFwcGVkICgke2kgaW5zdGFuY2VvZiBFcnJvcj9pLm1lc3NhZ2U6U3RyaW5nKGkpfSkgXHUyMDE0IGtlcm5lbC1zaWRlIGdyb3VwIGtpbGwgaW5jb21wbGV0ZTsgdGhlIGhvc3Qtc2lkZSBzcGF3bi1oYW5kbGVyIGJlbHQgc3RpbGwgZGVsaXZlcnMgU0lHS0lMTCB0byB0aGUgZ3JvdXBgfSl9fXIoUSwiY29udGFpblRocmVhZEdyb3VwQWZ0ZXJUcmFwIik7bGV0IFU9MCxmZT0xNixyZT01NyxYPTU5LGtlPTAsb2U9MSxGZT0yLGo9bnVsbCxydD1udWxsLENlPW51bGwsUHQ9bnVsbCxkbj1udWxsLGVlPW51bGwsTWU9bnVsbCxwbj1bXSxCdD1bXSxrbj1bXSx3bj0hMSxoZT0hMSxGdD0wLGduPVtdLEVuPVtdLHRuPXIobj0+e2lmKCFuKXJldHVybjtsZXQgYT1bXTtuLmJ1ZGdldEdsb2JhbCBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbCYmYS5wdXNoKG4uYnVkZ2V0R2xvYmFsKTtsZXQgaT1uLmV4cG9ydHM/bi5leHBvcnRzLl9faHdqc19idWRnZXQ6dm9pZCAwO2kgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWwmJmEucHVzaChpKTtmb3IobGV0IHUgb2YgYSl7dHJ5e3UudmFsdWU9cXJ8MH1jYXRjaHtjb250aW51ZX1nbi5wdXNoKHUpfX0sImFybU1vZHVsZUJ1ZGdldCIpLHNzPXIobj0+e2ZvcihsZXQgYSBvZiBnbil0cnl7YS52YWx1ZT1ufDB9Y2F0Y2h7fX0sInNldE1vZHVsZUJ1ZGdldHMiKSxMPXIoKG4sYSk9PlBsKG4sYSwoKT0+Q2woZ24saixwYSkpLCJkcml2ZUltcG9ydCIpLEk9ITEsTz1yKG49PntpZighZWUpcmV0dXJuO2xldCBhPShlZS5pbnN0YW5jZT8/ZWUpLmV4cG9ydHMuX190bHNfYmFzZTtpZighKGEgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWwpKXRocm93IG5ldyBFcnJvcigiaHdqcy1saWJjOiBsaWJjLnNvIGRvZXMgbm90IGV4cG9ydCB0aGUgbXV0YWJsZSBfX3Rsc19iYXNlIGdsb2JhbCB0aGUgUzIgXHhBNzMuMyBkdWFsLXdyaXRlIGNvbnRyYWN0IHJlcXVpcmVzIChwcm9kdWNlciBtdXN0IGxpbmsgLS1leHBvcnQ9X190bHNfYmFzZTsgbmV2ZXItc2lsZW50KS4iKTthLnZhbHVlPW58MH0sInNldExpYmNUbHNCYXNlIiksdGU9ITEscT0hMSxPZT0hMSxIZT0hMSxZdD0hMSxycz0hMSxhZT1yKG49PiEhb3x8ZS5tb2RlPT09InRocmVhZCImJihlLnVzZXJMYW5lfDApPjAmJnEmJk9lfHwobnwwKT09PW5kJiZIZSYmcSYmT2UsImNvb3BQYXJrQ2FwYWJsZUZvciIpLCRlPXIobj0+YWUobikmJihIZXx8eWEuaGFzKG58MCkpLCJibG9ja1BhcmtHb2VzVG9HdWVzdCIpLFVlPW51bGwsb3Q9ITEsc3Q9ITEsU2U9bnVsbCxaZT0wO2Z1bmN0aW9uIF90KCl7aWYoIVNlKXJldHVybjtsZXQgbj1TZTtpZigoQXRvbWljcy5sb2FkKEFlKCksbi5zdHdJZHgpfDApIT09MCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjcsdGV4dDpgaHdqcy1mb3JrLXN0dyBwaWQ9JHtzW00uUElEXXwwfSBsYW5lPSR7bi5sYW5lfTogaW4tc3lzY2FsbCBIT0xEIGVudGVyZWQgKGdlbj0ke0F0b21pY3MubG9hZChBZSgpLG4uc3R3SWR4KXwwfSlgfSl9Y2F0Y2h7fWxldCBhPSExLGk9MDtmb3IoOzspe2xldCB1PUF0b21pY3MubG9hZChBZSgpLG4uc3R3SWR4KXwwO2lmKHU9PT0wKWJyZWFrO2lmKGF8fChhPSEwLGk9RGF0ZS5ub3coKSksQXRvbWljcy5zdG9yZShBZSgpLG4uYWNrSWR4LHUpLEF0b21pY3Mud2FpdChBZSgpLG4uc3R3SWR4LHUsMjUwKSxEYXRlLm5vdygpLWk+MWU0KXtpPURhdGUubm93KCk7bGV0IHA9YGh3anMtZm9yay1zdHcgcGlkPSR7c1tNLlBJRF18MH0gbGFuZT0ke24ubGFuZX06IGhlbGQgYXQgYW4gaW4tc3lzY2FsbCBxdWllc2NlIHBvaW50IGZvciA+MTBzIHVuZGVyIGdlbmVyYXRpb24gJHtBdG9taWNzLmxvYWQoQWUoKSxuLnN0d0lkeCl8MH0gXHUyMDE0IHRoZSBmb3JraW5nIGxhbmUncyBzZXJ2aWNlciBoYXMgbm90IHJlbGVhc2VkOyBzdGlsbCBob2xkaW5nIChsb3VkIHdpdG5lc3MsIG5ldmVyIGEgc2lsZW50IHdlZGdlKWA7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6cH0pfWNhdGNoe310cnl7Y29uc29sZS5lcnJvcihwKX1jYXRjaHt9fX1hJiZBdG9taWNzLnN0b3JlKEFlKCksbi5hY2tJZHgsMCl9cihfdCwic3R3SG9sZFN5bmNJZlJlcXVlc3RlZCIpO2xldCBKZT0wLEh0PTEsTXQ9MixBdD0zLFluPTQsRGE9NSxOYT0xZTUsanQ9bmV3IE1hcCxHbj0xLEtuPVtdLHplPW51bGwsY249bnVsbCxSbj1udWxsLFNuPW5ldyBNYXA7ZnVuY3Rpb24gJG4obil7dHJ5e2lmKGp0LnNpemU+MCYmdHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo3LHRleHQ6YGh3anMtNzAgcGlkPSR7ZS5waWR9IFJFTEVBU0UoJHtufSk6IGRyb3BwaW5nICR7anQuc2l6ZX0gZGxvcGVuIGhhbmRsZShzKSArIHBlci1wcm9jZXNzIGRsb3BlbiBzdGF0ZSBhdCBwcm9jZXNzIGVuZGB9KX1jYXRjaHt9anQuY2xlYXIoKSxLbi5sZW5ndGg9MCxjbj1udWxsLFJuPW51bGwsU249bmV3IE1hcCx6ZT1udWxsLGo9bnVsbCxydD1udWxsLENlPW51bGwsUHQ9bnVsbCxkbj1udWxsfWNhdGNoe319cigkbiwicmVsZWFzZVByb2Nlc3NSdW5TdGF0ZSIpO2xldCBubz0hMSxzbz0wLEFzPTAsZ3I9cigobixhKT0+e2xldCB1PShzZSgpW24+Pj4yXT4+PjApLShuKzg+Pj4wKXwwO3JldHVybiB1PkFzJiYoQXM9dT4+PjApLHU+KGEtOCkqMz4+MiYmdCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgd2FzbTMyIEQxLUJBU0guYzogQXN5bmNpZnkgY29udGludWF0aW9uIGhpZ2gtd2F0ZXIgJHt1fUIgb2YgJHthLTh9QiB1c2FibGUgKD49NzUlKSBcdTIwMTQgZGVlcGVuIGd1YXJkIC8gcmVzaXplIGJ1ZmZlcmB9KSx1Pj4+MH0sIm5vdGVBc3luY2lmeUhpZ2hXYXRlciIpLHJvPSExLG5uPW51bGwsb3M9MCxUbj1udWxsLHlyPW51bGwsQnM9MCxvbz1udWxsLHVzPXNmKHtnZXRFeHBvcnRzOnIoKCk9PkYuZXhwb3J0cywiZ2V0RXhwb3J0cyIpLGdldExhbmU6cigoKT0+TmUsImdldExhbmUiKSxwb3N0OnR9KSxXZD1yKCgpPT51cy5waGFzZS5waGFzZSE9PSJpZGxlInx8dW4ucGhhc2UhPT0iaWRsZSIsImV4ZWNXaW5kb3dPcGVuIiksTGE9cigobixhKT0+dXMubG9hZChuLGEpLCJleGVjTG9hZEtlcm5lbENodW5rZWQiKSxmcz1tZChJYyksTWE9bWQoUmMpLGJyPTAsYW89ITEsVXQ9IiIsT2E9NDA5NixXYT0xPDwyMDtmdW5jdGlvbiBrcihuLGEpe2xldCBpPW4+Pj4wO2lmKGk9PT0wKXJldHVybltdO2xldCB1PWUubWVtb3J5LmJ1ZmZlcixwPW5ldyBVaW50OEFycmF5KHUpLGs9bmV3IERhdGFWaWV3KHUpLEU9W10sJD1pO2Zvcig7Oyl7aWYoRS5sZW5ndGg+T2EpdGhyb3cgbmV3IEVycm9yKGBkMS1mb3JrLWV4ZWM6ICR7YX0gdmVjdG9yIGV4Y2VlZHMgJHtPYX0gZW50cmllcyAobm8gTlVMTCB0ZXJtaW5hdG9yPyBwdHI9MHgke2kudG9TdHJpbmcoMTYpfSkgXHUyMDE0IHJlZnVzaW5nIChuZXZlci1zaWxlbnQpYCk7aWYoJCs0PnAubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgZDEtZm9yay1leGVjOiAke2F9IHZlY3RvciBwb2ludGVyIDB4JHskLnRvU3RyaW5nKDE2KX0gb3V0IG9mIGJvdW5kcyAobWVtICR7cC5sZW5ndGh9QikgXHUyMDE0IG1hbGZvcm1lZCB2ZWN0b3IsIHJlZnVzaW5nYCk7bGV0IHY9ay5nZXRVaW50MzIoJCwhMCk+Pj4wO2lmKCQrPTQsdj09PTApYnJlYWs7aWYodj49cC5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKGBkMS1mb3JrLWV4ZWM6ICR7YX1bJHtFLmxlbmd0aH1dIHN0cmluZyBwb2ludGVyIDB4JHt2LnRvU3RyaW5nKDE2KX0gb3V0IG9mIGJvdW5kcyAobWVtICR7cC5sZW5ndGh9QikgXHUyMDE0IHJlZnVzaW5nYCk7bGV0IGI9dixQPU1hdGgubWluKHAubGVuZ3RoLHYrV2EpO2Zvcig7YjxQJiZwW2JdIT09MDspYisrO2lmKGI+PVAmJihiPj1wLmxlbmd0aHx8cFtiXSE9PTApKXRocm93IG5ldyBFcnJvcihgZDEtZm9yay1leGVjOiAke2F9WyR7RS5sZW5ndGh9XSBzdHJpbmcgYXQgMHgke3YudG9TdHJpbmcoMTYpfSB1bnRlcm1pbmF0ZWQgd2l0aGluICR7V2F9QiBcdTIwMTQgcmVmdXNpbmdgKTtFLnB1c2goRXMocC5zdWJhcnJheSh2LGIpKSl9cmV0dXJuIEV9cihrciwiZGVjb2RlVXNlclN0cmluZ1ZlY3RvciIpO2xldCBpbz0hMSxsbz0hMSxDYT0wLFBhPTAsY289MDtmdW5jdGlvbiB4cigpe2xldCBuPVtdLGE9W107Zm9yKGxldFt1LHBdb2YganQpe2lmKHAmJnAubWFpblNjb3BlKXthLnB1c2godT4+PjApO2NvbnRpbnVlfSFwfHwhcC5ieXRlc3x8bi5wdXNoKHtjb29raWU6dT4+PjAsbW9kdWxlSWQ6cC5tb2R1bGVJZHwwLG1lbW9yeUJhc2U6cC5tZW1vcnlCYXNlPj4+MCx0YWJsZUJhc2U6cC50YWJsZUJhc2U+Pj4wLHRhYmxlU2l6ZTpwLmhhbmRsZSYmcC5oYW5kbGUuZHlsaW5rP3AuaGFuZGxlLmR5bGluay50YWJsZVNpemU+Pj4wOjAsYXBwZW5kZWQ6cC5oYW5kbGUmJnR5cGVvZiBwLmhhbmRsZS50YWJsZUVudHJpZXM9PSJmdW5jdGlvbiI/cC5oYW5kbGUudGFibGVFbnRyaWVzKCk6W10scGF0aDpwLnBhdGh8fCIiLGJ5dGVzOnAuYnl0ZXMsLi4ucC5pbnRlcm5hbD97aW50ZXJuYWw6ITAsbmFtZTpwLm5hbWUsZGlnZXN0OnAuZGlnZXN0LC4uLnAubW9kdWxlP3ttb2R1bGU6cC5tb2R1bGV9Ont9fTp7fSwuLi5wLmJvdW5kQnlEZXBlbmRlbnQ/e2JvdW5kQnlEZXBlbmRlbnQ6ITB9Ont9LGxpdmU6cC5jZW5zdXM/cC5jZW5zdXMubGl2ZT4+PjA6MCxwb2lzb25lZDpwLmNlbnN1cz8hIXAuY2Vuc3VzLnBvaXNvbmVkOiExLHhtb2RSZWNzOnAueG1vZFJlY3M/Wy4uLnAueG1vZFJlY3NdOltdLC4uLmFhKHAuaGFuZGxlLHAudGxzU2xvdHMpfSl9bi5zb3J0KCh1LHApPT51LmNvb2tpZS1wLmNvb2tpZSk7bGV0IGk9Um4gaW5zdGFuY2VvZiBNYXA/Wy4uLlJuXTpbXTtyZXR1cm4gbi5sZW5ndGh8fEtuLmxlbmd0aHx8YS5sZW5ndGh8fGkubGVuZ3RofHxDZXx8TWV8fHBuLmxlbmd0aHx8U24uc2l6ZT97cmVwbGF5Om4sbWFpblNjb3BlOmEsbWFpblNjb3BlTmFtZXM6aSxmcGNhc3RSZWNzOlsuLi5Tbl0sZGVhZFJhbmdlczpLbi5tYXAodT0+KHt0YWJsZUJhc2U6dS50YWJsZUJhc2U+Pj4wLHRhYmxlU2l6ZTp1LnRhYmxlU2l6ZT4+PjAsYXBwZW5kZWQ6QXJyYXkuaXNBcnJheSh1LmFwcGVuZGVkKT9bLi4udS5hcHBlbmRlZF06W10scGF0aDp1LnBhdGh8fCIiLG1vZHVsZUlkOnUubW9kdWxlSWR8MH0pKSxnb3RGdW5jOmNuIGluc3RhbmNlb2YgTWFwP1suLi5jbl06W10sbmV4dENvb2tpZTpHbj4+PjAsdGFibGVMZW46emUgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5UYWJsZT96ZS5sZW5ndGg+Pj4wOjAsLi4uQ2U/e2h3anNSdDp7Li4uQ2V9fTp7fSwuLi5NZT97bGliY1NvOnsuLi5NZX19Ont9LC4uLnBuLmxlbmd0aD97bmVlZGVkTGliczpwbi5tYXAodT0+KHsuLi51LC4uLmFhKChCdC5maW5kKHA9PnAuaW5kZXg9PT11LmluZGV4KXx8e30pLmhhbmRsZSx1LnRsc1Nsb3RzKX0pKX06e319Om51bGx9cih4ciwiYnVpbGREbG9wZW5Gb3JrUmVjb3JkIik7YXN5bmMgZnVuY3Rpb24gdW8obil7QXRvbWljcy5zdG9yZShzLE0uTlIscmV8MCksQXRvbWljcy5zdG9yZShzLE0uU1RBVEUsVXIpO2xldCBhPSgoKT0+e2lmKGVlKXtsZXQgJD0oZWUuaW5zdGFuY2U/P2VlKS5leHBvcnRzLl9fdGxzX2Jhc2U7aWYoJCBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbClyZXR1cm4gJC52YWx1ZT4+PjB9cmV0dXJuIGomJnR5cGVvZiBqLl9fd2FzbTMyX2dldF90bHNfYmFzZT09ImZ1bmN0aW9uIj9qLl9fd2FzbTMyX2dldF90bHNfYmFzZSgpPj4+MDowfSkoKSxpPW4mJnR5cGVvZiBuPT0ib2JqZWN0Ij9uOm51bGwsdT1pJiZqJiZ0eXBlb2Ygai5fX3dhc20zMl9nZXRfc3RhY2tfcG9pbnRlcj09ImZ1bmN0aW9uIj9qLl9fd2FzbTMyX2dldF9zdGFja19wb2ludGVyKCk+Pj4wOjAscD14cigpLGs9Wy4uLlp0XTtmb3IodCh7a2luZDoiZm9yayIscGlkOnNbTS5QSURdfDAsdGxzQmFzZTphLC4uLlplP3t1c2VyTGFuZTpaZXwwfTp7fSwuLi5rLmxlbmd0aD97bG93RmRSb3V0ZXM6a306e30sLi4ucD97ZGxvcGVuRm9yazpwfTp7fSwuLi5pP3twYXJlbnRTcDp1LGZvcmtIYW5kbGU6aS5oYW5kbGU+Pj4wLGZvcmtPd25lcjppLm93bmVyPj4+MH06e319KTtBdG9taWNzLmxvYWQocyxNLlNUQVRFKSE9PWRyOyl7bGV0ICQ9QXRvbWljcy53YWl0QXN5bmMocyxNLlNUQVRFLFVyLDVlMyk7aWYoJC5hc3luYyl0cnl7YXdhaXQgJC52YWx1ZX1jYXRjaHt9fWxldCBFPXNbTS5SRVRfTE9dfDA7cmV0dXJuIEF0b21pY3Muc3RvcmUocyxNLlNUQVRFLGtzKSxFfXIodW8sInJlcXVlc3RGb3JrQ2hpbGQiKTtsZXQgZm89ZS5tb2RlPT09Im1pZ3JhdGUtcmVzdW1lIiYmZS5taWcgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcj9uZXcgSW50MzJBcnJheShlLm1pZyk6bnVsbCxDZD1yKCgpPT5mbz9BdG9taWNzLmNvbXBhcmVFeGNoYW5nZShmbywwLF9yLFZyKT09PV9yPyhBdG9taWNzLm5vdGlmeShmbywwKSwhMCk6ITE6ITAsIm1pZ3JhdGVDb21taXQiKTthc3luYyBmdW5jdGlvbiBQZChuKXtsZXQgYT1lLmNwdUlkfDAsaT1zW00uUElEXXwwLHU9bmV3IFNoYXJlZEFycmF5QnVmZmVyKDE2KSxwPW5ldyBJbnQzMkFycmF5KHUpO0F0b21pY3Muc3RvcmUocCwwLHhhKSxBdG9taWNzLnN0b3JlKHAsMSxufDApO2xldCBrPSgoKT0+e2lmKGVlKXtsZXQgZj0oZWUuaW5zdGFuY2U/P2VlKS5leHBvcnRzLl9fdGxzX2Jhc2U7aWYoZiBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbClyZXR1cm4gZi52YWx1ZT4+PjB9cmV0dXJuIGomJnR5cGVvZiBqLl9fd2FzbTMyX2dldF90bHNfYmFzZT09ImZ1bmN0aW9uIj9qLl9fd2FzbTMyX2dldF90bHNfYmFzZSgpPj4+MDowfSkoKSxFPWomJnR5cGVvZiBqLl9fd2FzbTMyX2dldF9zdGFja19wb2ludGVyPT0iZnVuY3Rpb24iP2ouX193YXNtMzJfZ2V0X3N0YWNrX3BvaW50ZXIoKT4+PjA6MCwkPUYmJnR5cGVvZiBGLmV4cG9ydHMuX19od2pzX3Rhc2tfZnJhbWVzPT0iZnVuY3Rpb24iP0YuZXhwb3J0cy5fX2h3anNfdGFza19mcmFtZXMoKT4+PjA6MDt0KHtraW5kOiJtaWdyYXRlIixwaWQ6aSxzcmNDcHU6YSxkZXN0Q3B1Om58MCxtaWc6dSx0YXNrQWRkcjpuZT4+PjAsdXNlckxhbmU6WmV8MCx0bHNCYXNlOmssc3A6RSxmcmFtZXM6JCxsb3dGZFJvdXRlczpbLi4uWnRdLC4uLigoKT0+e2xldCBmPXhyKCk7cmV0dXJuIGY/e2Rsb3BlbkZvcms6Zn06e319KSgpfSk7bGV0IHY9RGF0ZS5ub3coKTtmb3IoOzspe2xldCBmPUF0b21pY3MubG9hZChwLDApfDA7aWYoZj09PVZyfHxmPT09RWEpYnJlYWs7bGV0IF9lPXYrKGY9PT1fcj9yZDpvZCktRGF0ZS5ub3coKTtpZihfZTw9MCl7dmQocCxmPT09X3I/YWQ6bGQpO2JyZWFrfWxldCBqZT1BdG9taWNzLndhaXRBc3luYyhwLDAsZixfZSk7aWYoamUuYXN5bmMpdHJ5e2F3YWl0IGplLnZhbHVlfWNhdGNoe319aWYoKEF0b21pY3MubG9hZChwLDApfDApPT09VnIpe2xldCBmPS0xO0YmJnR5cGVvZiBGLmV4cG9ydHMuX19od2pzX2ZyYW1lX21pZ3JhdGVfbGFuZT09ImZ1bmN0aW9uIj8oZj1GLmV4cG9ydHMuX19od2pzX2ZyYW1lX21pZ3JhdGVfbGFuZShuZT4+PjAsYXwwLG58MCl8MCxmPDAmJnQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6aSxtZXNzYWdlOmBod2pzLW1pZ3JhdGUgcGlkPSR7aX06IGFyZW5hIHJldGFnICR7YX0tPiR7bn0gd2FzIHJlZnVzZWQgKGJhZCBsYW5lIGluZGV4KSBcdTIwMTQgdGhpcyB0YXNrJ3MgbGl2ZSBrZXJuZWwgZnJhbWVzIHN0aWxsIGNhcnJ5IHRoZSBzb3VyY2UgbGFuZSdzIHRhZywgc28gdGhlaXIgdGVhcmRvd24gV0lMTCB0cmlwIHRoZSBjcm9zcy1sYW5lIGZyZWUgZ3VhcmQgKGxvdWQsIGF0dHJpYnV0ZWQpYH0pKTp0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmksbWVzc2FnZTpgaHdqcy1taWdyYXRlIHBpZD0ke2l9OiB0aGlzIHZtbGludXggZXhwb3J0cyBubyBfX2h3anNfZnJhbWVfbWlncmF0ZV9sYW5lIFx1MjAxNCB0aGUgbWlncmF0aW9uIHByb2NlZWRzLCBidXQgdGhlIHRhc2sncyBsaXZlIGtlcm5lbCBmcmFtZXMga2VlcCB0aGUgc291cmNlIGxhbmUncyB0YWcgYW5kIHRoZWlyIHRlYXJkb3duIHdpbGwgdHJpcCB0aGUgY3Jvc3MtbGFuZSBmcmVlIGd1YXJkIChzdGFsZSBrZXJuZWw7IGxvdWQsIGF0dHJpYnV0ZWQpYH0pLEN0KHQsYE1JR1JBVEUtT1VUIGNwdT0ke2F9IHRpZD0ke2UudGlkfSBwaWQ9JHtpfSAtPiBjcHU9JHtufSBsYW5lPSR7WmV8MH0gdGFza0ZyYW1lcz0keyR9IHJldGFnZ2VkPSR7Zn1gKTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1taWdyYXRlIHBpZD0ke2l9OiBhcmVuYSByZXRhZyBjcHU9JHthfS0+JHtufSBtb3ZlZCAke2Z9IGxpdmUgY2h1bmsocykgKHRhc2sgZnJhbWUgYmFsYW5jZSAkeyR9KWB9KX1jYXRjaHt9cmV0dXJuITB9bGV0IGI9QXRvbWljcy5sb2FkKHAsMil8MDtpZihiPT09aWQmJkYmJnR5cGVvZiBGLmV4cG9ydHMuX193YXNtMzJfbWlncmF0ZV9yZWZ1c2U9PSJmdW5jdGlvbiIpdHJ5e0YuZXhwb3J0cy5fX3dhc20zMl9taWdyYXRlX3JlZnVzZSgpfWNhdGNoe31sZXQgUD1iPT09YWQ/YGEgbGFuZSBDTEFJTUVEIHRoZSB0YXNrIGFuZCBkaWQgbm90IGNvbW1pdCB3aXRoaW4gJHtyZH0gbXMgXHUyMDE0IGl0IHN0YWxsZWQgb3IgZGllZCBpbnNpZGUgdGhlIGNvbW1pdCB3aW5kb3dgOmI9PT1pZD8ibm8gbGl2ZSBwb29sIFdvcmtlciBob2xkcyB0aGF0IGNwdSI6Yj09PWxkP2BubyBsYW5lIGNsYWltZWQgdGhlIG9mZmVyIHdpdGhpbiAke29kfSBtcyBcdTIwMTQgdGhlIGRlc3RpbmF0aW9uIGxhbmUgaXMgc3RhcnZlZCwgb3Igbm90aGluZyBvbiB0aGlzIG1hY2hpbmUgc2VydmljZXMgbWlncmF0aW9uIHJlcXVlc3RzIGF0IGFsbGA6Yj09PVNhPyJ0aGUgZGVzdGluYXRpb24gcmVmdXNlZCB0byBiaW5kIHRoZSB0YXNrIjpiPT09THU/InRoZSBob3N0IHJlZnVzZWQgdGhlIHBsYWNlbWVudCI6YGFib3J0IGNvZGUgJHtifWAsSD1gaHdqcy1taWdyYXRlIHBpZD0ke2l9IGNwdT0ke2F9OiBtaWdyYXRpb24gdG8gY3B1PSR7bn0gUkVGVVNFRCBcdTIwMTQgJHtQfS4gVGhlIHRhc2sgd2FzIG5ldmVyIHJlbGVhc2VkIGFuZCBrZWVwcyBydW5uaW5nIGhlcmU7IHNjaGVkX3NldGFmZmluaXR5IHdpbGwgYW5zd2VyIC1FQUdBSU4gb25jZSBpdHMgYXR0ZW1wdCBib3VuZCBpcyBzcGVudCAobG91ZCwgYXR0cmlidXRlZCwgZ3Vlc3Qtc3Vydml2YWJsZSkuYDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpIfSl9Y2F0Y2h7fXRyeXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmksbWVzc2FnZTpIfSl9Y2F0Y2h7fXJldHVybiExfXIoUGQsInJlcXVlc3RNaWdyYXRlIik7ZnVuY3Rpb24gRXIobil7bGV0IGE9TWF0aC5mbG9vcihlLm1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aC82NTUzNik7aWYoYT49bilyZXR1cm4gYTtpZihBYT4wJiZuPj1BYSYmZ2E+MCl0aHJvdyBnYS0tLG5ldyBFcnJvcihgaGFyZHdhcmVqcyM3IFRFU1QgSU5KRUNUSU9OOiBzaW11bGF0ZWQgY29tbWl0IHJlZnVzYWwgZm9yIGdyb3coKyR7bi1hfSkgKCR7Z2F9IGluamVjdGVkIGZhaWx1cmUocykgbGVmdCBpbiB0aGlzIFdvcmtlciByZWFsbSlgKTtyZXR1cm4gZS5tZW1vcnkuZ3JvdyhuLWEpLG59cihFciwidHJ5R3Jvd1VzZXJNZW1vcnlUbyIpO2Z1bmN0aW9uIEJkKG4pe2xldCBpPW5ldyBTaGFyZWRBcnJheUJ1ZmZlcigzMiksdT1uZXcgSW50MzJBcnJheShpKTt0cnl7dCh7a2luZDoidXNlcm1lbS1yZWNsYWltIixwaWQ6ZS5waWQsbmVlZFBhZ2VzOm58MCxzYWI6aX0pfWNhdGNoe3JldHVybiBudWxsfWxldCBwPURhdGUubm93KCkrNWUzO2Zvcig7QXRvbWljcy5sb2FkKHUsMCk9PT0wJiZEYXRlLm5vdygpPHA7KUF0b21pY3Mud2FpdCh1LDAsMCxNYXRoLm1heCgxLHAtRGF0ZS5ub3coKSkpO3JldHVybiBBdG9taWNzLmxvYWQodSwwKSE9PTE/bnVsbDp7bGl2ZUNvdW50OnVbMV0sbGl2ZVBhZ2VzOnVbMl0sem9tYmllQ291bnQ6dVszXSx6b21iaWVQYWdlczp1WzRdLHJlY3ljbGVkV29ya2Vyczp1WzVdLHVzZXJNYXhQYWdlczp1WzZdLGtlcm5lbFBhZ2VzOnVbN119fXIoQmQsInJlcXVlc3RIb3N0VXNlck1lbVJlY2xhaW0iKTtmdW5jdGlvbiBGZChuKXtpZighKG4+MCkpcmV0dXJuO2xldCBhPW5ldyBJbnQzMkFycmF5KG5ldyBTaGFyZWRBcnJheUJ1ZmZlcig0KSk7QXRvbWljcy53YWl0KGEsMCwwLG4pfXIoRmQsInNldHRsZVdhaXRNcyIpO2Z1bmN0aW9uIF9vKG4sYSl7bGV0IGk7dHJ5e2k9a2wobil9Y2F0Y2goWWUpe3JldHVybiB0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6YGhhcmR3YXJlanMjNiAke2F9OiBjYW5ub3QgcmVhZCB0aGUgZXhlYyBpbWFnZSdzIGRlY2xhcmVkIG1lbW9yeS1pbXBvcnQgbWluaW11bSAoJHtZZSBpbnN0YW5jZW9mIEVycm9yP1llLm1lc3NhZ2U6U3RyaW5nKFllKX0pIFx1MjAxNCByZWZ1c2luZyBleGVjIHdpdGggLUVOT0VYRUMgKG5ldmVyLXNpbGVudClgfSksLTh9aWYoaT09PW51bGwpcmV0dXJuIDA7bGV0IHU9TWF0aC5mbG9vcihlLm1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aC82NTUzNik7aWYodT49aSlyZXR1cm4gMDtsZXQgcD1yKFllPT4oWWUqNjU1MzYvKDEwMjQqMTAyNCkpLnRvRml4ZWQoMSksIm1pYiIpLGs9bnVsbDt0cnl7RXIoaSl9Y2F0Y2goWWUpe2s9WWV9aWYoaz09PW51bGwpe3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzIGV4ZWMgcGlkPSR7c1tNLlBJRF18MH0gJHthfTogZ3JldyB1c2VyX21lbW9yeSAke3V9IC0+ICR7aX0gcGFnZXMgZm9yIHRoZSBleGVjIGltYWdlJ3MgZGVjbGFyZWQgbWluaW11bSAoaGFyZHdhcmVqcyM2KWB9KX1jYXRjaHt9cmV0dXJuIDB9bGV0IEU9bnVsbDt0cnl7aWYodHlwZW9mIGUubWVtb3J5LnR5cGU9PSJmdW5jdGlvbiIpe2xldCBZZT1lLm1lbW9yeS50eXBlKCk7WWUmJnR5cGVvZiBZZS5tYXhpbXVtPT0ibnVtYmVyIiYmKEU9WWUubWF4aW11bT4+PjApfX1jYXRjaHt9bGV0ICQ9RSE9PW51bGwmJmk+RSx2PW51bGwsYj0hMSxQPW51bGwsSD0wLGY9MDtpZighWXUmJiEkKXtiPSEwO2ZvcihsZXQgWWU9MDtZZTxWdTtZZSsrKXtIKys7bGV0IFN0PUJkKGktdSk7U3QhPT1udWxsJiYodj1TdCxmKz1TdC5yZWN5Y2xlZFdvcmtlcnN8MCksRmQoY2RbTWF0aC5taW4oWWUsY2QubGVuZ3RoLTEpXSk7dHJ5e0VyKGkpLFA9bnVsbDticmVha31jYXRjaChndCl7UD1ndH19aWYoUD09PW51bGwpe3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzIGV4ZWMgcGlkPSR7c1tNLlBJRF18MH0gJHthfTogZ3JvdygrJHtpLXV9KSB3YXMgcmVmdXNlZCAoJHtrIGluc3RhbmNlb2YgRXJyb3I/ay5tZXNzYWdlOlN0cmluZyhrKX0pIGJ1dCBzdWNjZWVkZWQgYWZ0ZXIgaG9zdCByZWNsYWltICgke0h9IHJvdW5kKHMpLCByZWN5Y2xlZCAke2Z9IGlkbGUgcG9vbCBXb3JrZXIocykgdG90YWwpOyB1c2VyX21lbW9yeSAke3V9IC0+ICR7aX0gcGFnZXMgKGhhcmR3YXJlanMjNyByZXNjdWUpYH0pfWNhdGNoe31yZXR1cm4gMH19bGV0IFc9RSE9PW51bGw/RTp2JiZ2LnVzZXJNYXhQYWdlcz4wP3YudXNlck1heFBhZ2VzOm51bGwsX2U9RSE9PW51bGw/InRoaXMgTWVtb3J5XHUyMDE5cyBkZWNsYXJlZCBtYXhpbXVtIjoidGhlIG1hY2hpbmUgZGVmYXVsdCB1c2VyTWF4Qnl0ZXMiLGplPVchPT1udWxsP2k+Vz9gdGhlIGRlY2xhcmVkIG1pbmltdW0gRVhDRUVEUyAke19lfSBvZiAke1d9IHBhZ2VzICgke3AoVyl9IE1pQikgXHUyMDE0IHJhaXNpbmcgdXNlck1heEJ5dGVzIGlzIHRoZSBvbmx5IHJlbWVkeSBmb3IgVEhJUyBpbWFnZWA6YHRoZSB1c2VyTWF4Qnl0ZXMgY2VpbGluZyBpcyBOT1QgdGhlIGxpbWl0aW5nIGZhY3RvciAoJHtpfSA8PSAke1d9IHBhZ2VzKSBcdTIwMTQgdGhlIGVuZ2luZSByZWZ1c2VkIHRvIGNvbW1pdCB0aGUgcGFnZXNgOmB0aGUgTWVtb3J5J3MgbWF4aW11bSBpcyBub3QgaW50cm9zcGVjdGFibGUgaW4gdGhpcyBlbmdpbmU7IGlmICR7aX0gcGFnZXMgZXhjZWVkcyB1c2VyTWF4Qnl0ZXMgdGhhdCBpcyB0aGUgY2F1c2UsIG90aGVyd2lzZSB0aGUgZW5naW5lIHJlZnVzZWQgdG8gY29tbWl0IHRoZSBwYWdlc2Asd2U9Yj92PT09bnVsbD9gaG9zdCByZWNsYWltIHdhcyByZXF1ZXN0ZWQgKCR7SH0gcm91bmQocykpIGJ1dCBuZXZlciBhbnN3ZXJlZCB3aXRoaW4gdGhlIDVzL3JvdW5kIGNhcCAobm8ga2VybmVsU3Bhd25IYW5kbGVyIHJvdXRlPyk7IHRoZSBibGluZCByZXRyaWVzIGFsc28gZmFpbGVkICgke1AgaW5zdGFuY2VvZiBFcnJvcj9QLm1lc3NhZ2U6U3RyaW5nKFApfSlgOmBob3N0IHJlY2xhaW0gcmFuICR7SH0gcm91bmQocykgd2l0aCBzZXR0bGUgd2FpdHMgKHJlY3ljbGVkICR7Zn0gaWRsZSBwb29sIFdvcmtlcihzKSB0b3RhbDsgbGVkZ2VyOiAke3YubGl2ZUNvdW50fSBsaXZlIHByb2Nlc3MgU0FCKHMpIH4ke3Aodi5saXZlUGFnZXMpfSBNaUIgY29tbWl0dGVkLCAke3Yuem9tYmllQ291bnR9IGV4aXRlZC1idXQtdW5jb2xsZWN0ZWQgU0FCKHMpIH4ke3Aodi56b21iaWVQYWdlcyl9IE1pQiBhd2FpdGluZyBHQywga2VybmVsIFNBQiAke3Aodi5rZXJuZWxQYWdlcyl9IE1pQiBlYWdlcmx5IGNvbW1pdHRlZCkgYW5kIHRoZSBsYXN0IHJldHJ5IHN0aWxsIGZhaWxlZCAoJHtQIGluc3RhbmNlb2YgRXJyb3I/UC5tZXNzYWdlOlN0cmluZyhQKX0pYDokPyJyZWNsYWltLXJldHJ5IHNraXBwZWQgKHBvaW50bGVzcyBiZWxvdyBhbiBleGNlZWRlZCBjZWlsaW5nKSI6InJlY2xhaW0tcmV0cnkgRElTQUJMRUQgKEhXSlNfTk9fUkVDTEFJTV9SRVRSWSkiO3JldHVybiB0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6YGhhcmR3YXJlanMjNyAke2F9OiBleGVjIGltYWdlIGRlY2xhcmVzIGEgJHtpfS1wYWdlICgke3AoaSl9IE1pQikgdXNlcl9tZW1vcnkgbWluaW11bSBidXQgdGhpcyBwcm9jZXNzJ3MgTWVtb3J5IGhvbGRzICR7dX0gcGFnZXMgKCR7cCh1KX0gTWlCKSBhbmQgZ3JvdygrJHtpLXV9KSB3YXMgcmVmdXNlZCAoJHtrIGluc3RhbmNlb2YgRXJyb3I/ay5tZXNzYWdlOlN0cmluZyhrKX0pLiAke2plfTsgJHt3ZX0uIEZhaWxpbmcgZXhlY3ZlIHdpdGggLUVOT01FTSAobmV2ZXItc2lsZW50KS5gfSksLTEyfXIoX28sImVuc3VyZVVzZXJNZW1vcnlGaXRzSW1hZ2UiKTtmdW5jdGlvbiBCYSgpe2xldCBuPUYmJkYuZXhwb3J0cztpZighbnx8dHlwZW9mIG4ud2FzbTMyX3VzZXJfZXhlY19zaGViYW5nX2FyZ2MhPSJmdW5jdGlvbiIpcmV0dXJuIG51bGw7bGV0IGE9bi53YXNtMzJfdXNlcl9leGVjX3NoZWJhbmdfYXJnYygpPj4+MDtpZihhPT09MClyZXR1cm4gbnVsbDtsZXQgaT1uLndhc20zMl91c2VyX2V4ZWNfc2hlYmFuZ19hZGRyKCk+Pj4wLHU9bi53YXNtMzJfdXNlcl9leGVjX3NoZWJhbmdfc2l6ZSgpPj4+MDtpZihpPT09MHx8dT09PTApdGhyb3cgbmV3IEVycm9yKGAjNzUgc2hlYmFuZzoga2VybmVsIHJlcG9ydHMgYXJnYz0ke2F9IGJ1dCBhZGRyPTB4JHtpLnRvU3RyaW5nKDE2KX0gc2l6ZT0ke3V9IFx1MjAxNCBrZXJuZWwvaG9zdCBhcmd2LXByZWZpeCBjb250cmFjdCBicm9rZW4gKG5ldmVyLXNpbGVudClgKTtsZXQgcD1uZXcgVWludDhBcnJheSh1KTtwLnNldChuZXcgVWludDhBcnJheShlLmtlcm5lbE1lbW9yeVdhc20uYnVmZmVyLGksdSkpO2xldCBrPVtdLEU9MDtmb3IobGV0ICQ9MDskPHAubGVuZ3RoOyQrKylwWyRdPT09MCYmKGsucHVzaChuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocC5zdWJhcnJheShFLCQpKSksRT0kKzEpO2lmKGsubGVuZ3RoIT09YXx8RSE9PXAubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgIzc1IHNoZWJhbmc6IGFyZ3YtcHJlZml4IGJsb2IgZGVjb2RlcyB0byAke2subGVuZ3RofSBzdHJpbmdzICh0YWlsPSR7cC5sZW5ndGgtRX1CKSBidXQgdGhlIGtlcm5lbCByZXBvcnRzIGFyZ2M9JHthfSBcdTIwMTQgcmVmdXNpbmcgdG8gZXhlYyB3aXRoIHRvcm4gYXJndiAobmV2ZXItc2lsZW50KWApO3JldHVybiBrfXIoQmEsInJlYWRFeGVjU2hlYmFuZ1ByZWZpeCIpO2Z1bmN0aW9uIEZhKG4pe2lmKCFuKXJldHVybjtsZXQgYT1BcnJheS5pc0FycmF5KFRuKT9Ubi5zbGljZSgxKTpbXTtpZihUbj1bLi4ubiwuLi5hXSx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRVhFQy1TSEVCQU5HIGFyZ3YgcmVzcGxpY2VkOiBbJHtUbi5tYXAoaT0+SlNPTi5zdHJpbmdpZnkoaSkpLmpvaW4oIiwiKX1dYH0pfWNhdGNoe319cihGYSwiYXBwbHlFeGVjU2hlYmFuZ1ByZWZpeCIpO2Z1bmN0aW9uIGhvKG4sYSxpLHUscCxrLEU9ITEpe2xldCAkPUY/Ri5leHBvcnRzOm51bGw7aWYocC52IT09ITEmJk5lJiYkJiZ0eXBlb2YgJC53YXNtX3N5c2NhbGw9PSJmdW5jdGlvbiIpZm9yKDs7KXtsZXQgdjt0cnl7dj1OZS5kcml2ZVdvdWxkQmxvY2soYHdhc21fc3lzY2FsbDoke2F9YCxpLGspfWNhdGNoKGIpe3Rocm93IGsuaD0wLGsub3duZXI9MCxifWlmKHYud291bGRCbG9jayl7aWYocC52PSEwLEUpcmV0dXJuIGZ0O2NvbnRpbnVlfWlmKHYudmFsdWUhPT0tMzgpcmV0dXJuIHAudj0hMCx2LnZhbHVlfDA7aWYocC52PT09bnVsbCl7cC52PSExO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLSR7bn06IHRoaXMgdm1saW51eCBhbnN3ZXJzIG5vICR7YX07IGRyaXZpbmcgJHtufSB0aHJvdWdoIHRoZSBiYXJlIGV4cG9ydCwgd2hpY2ggaG9sZHMgdGhlIGtlcm5lbCBsYW5lIGFjcm9zcyB0aGUgd2hvbGUgZmlsZSBhbmQgZ2V0cyBubyBwYXJrIHByZXNlcnZhdGlvbi4gTmV2ZXItc2lsZW50LmB9KX1jYXRjaHt9YnJlYWt9cmV0dXJuLTM4fXJldHVybiB1KCl8MH1yKGhvLCJkcml2ZVdob2xlRmlsZVJlYWQiKTtsZXQgSGQ9e3Y6bnVsbH0sSGE9e3Y6bnVsbH0sVWQ9e2g6MCxvd25lcjowfSxVYT17aDowLG93bmVyOjB9LG1vPXtuYW1lOm51bGx9LFZuPW51bGw7ZnVuY3Rpb24gU3IobixhLGk9ITEpe2xldCB1PXRhKG4pO2lmKCF1fHx1Lm5lZWRlZC5sZW5ndGg9PT0wKXJldHVybjtsZXQgcD1tby5uYW1lO2lmKHA9PT1udWxsKXtsZXQgR3Q9dS5uZWVkZWQuZmlsdGVyKHZuPT4hZW4uaGFzKHRzKHZuKSkpO2lmKEd0Lmxlbmd0aD09PTApcmV0dXJuO3A9R3RbMF19bGV0IGs9dS5uZWVkZWQuaW5kZXhPZihwKSxFPXRzKHApLCQ9Rj9GLmV4cG9ydHM6bnVsbDtpZighJHx8dHlwZW9mICQud2FzbTMyX3VzZXJfbGliY19zdGFnZSE9ImZ1bmN0aW9uInx8IWUua2VybmVsTWVtb3J5V2FzbSl7dHJ5e3Qoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpgaHdqcy1saWJjOiBpbWFnZSBuZWVkcyBsaWJjLnNvLiR7RS5zbGljZSgwLDE2KX1cdTIwMjYgYnV0IHRoaXMga2VybmVsIGV4cG9ydHMgbm8gd2FzbTMyX3VzZXJfbGliY19zdGFnZSAoYSB2bWxpbnV4IHdpdGhvdXQgdGhlIGxpYmMtc3RhZ2Ugb3BzKSBcdTIwMTQgdGhlIGV4ZWMgcHJlYW1ibGUgd2lsbCByZWZ1c2UgdGhlIGltYWdlIChuZXZlci1zaWxlbnQpIFske2F9XWB9KX1jYXRjaHt9cmV0dXJufWxldCB2PXR5cGVvZiAkLndhc20zMl91c2VyX25lZWRlZF9zdGFnZT09ImZ1bmN0aW9uIjtpZighdiYmaz4wKXt0cnl7dCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOmBod2pzLWxpYmM6IHRoZSBpbWFnZSBuZWVkcyAke3Auc2xpY2UoMCwyNCl9XHUyMDI2IChuZWVkZWQgZW50cnkgJHtrfSkgYnV0IHRoaXMga2VybmVsIGV4cG9ydHMgbm8gd2FzbTMyX3VzZXJfbmVlZGVkX3N0YWdlIFx1MjAxNCBhIHZtbGludXggd2l0aG91dCB0aGUgbmVlZGVkLWdyYXBoIG9wcyBjYW4gc3RhZ2UgZW50cnkgMCBvbmx5OyB0aGUgZXhlYyBwcmVhbWJsZSB3aWxsIHJlZnVzZSB0aGUgaW1hZ2UgKG5ldmVyLXNpbGVudCkgWyR7YX1dYH0pfWNhdGNoe31yZXR1cm59bGV0IGI9dj9EdTpqdSxQPXY/Indhc20zMl91c2VyX25lZWRlZF9zdGFnZSI6Indhc20zMl91c2VyX2xpYmNfc3RhZ2UiLEg9cigoKT0+dj8kLndhc20zMl91c2VyX25lZWRlZF9zdGFnZShNYXRoLm1heChrLDApPj4+MCwxKXwwOiQud2FzbTMyX3VzZXJfbGliY19zdGFnZSgxKXwwLCJzdGFnZUNhbGwiKSxmO3RyeXtmPWhvKCJsaWJjLXN0YWdlIixiLCgpPT52PyQud2FzbV9zeXNjYWxsKGIsTWF0aC5tYXgoaywwKT4+PjAsMSwwLDAsMCwwKXwwOiQud2FzbV9zeXNjYWxsKGIsMSwwLDAsMCwwLDApfDAsKCk9Pk5lP05lLmJyYWNrZXQoUCxIKTpIKCksSGQsVWQsaSl8MH1jYXRjaChHdCl7dGhyb3cgbW8ubmFtZT1udWxsLEd0fWlmKG1vLm5hbWU9Zj09PWZ0fHxmPT09JGQ/cDpudWxsLGY9PT1mdClyZXR1cm4gZnQ7aWYoZjwwKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBrZXJuZWwgTkVFREVEX1NUQUdFIGZvciAke3Auc2xpY2UoMCwyNCl9XHUyMDI2IChlbnRyeSAke2t9KSBmYWlsZWQgcmM9JHtmfSAoJHthfSkgXHUyMDE0IG5vdCBmb3VuZCBvbiB0aGUgbmVlZGVkIHNlYXJjaCBwYXRoICgvbGliLCAvdXNyL2xpYikgb3Igb3ZlciB0aGUgc3RhZ2luZyBjZWlsaW5nIChuZXZlci1zaWxlbnQpLmApO2lmKGYhPT0yKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBrZXJuZWwgTkVFREVEX1NUQUdFKCR7a30sIGZvcmNlPTEpIHJldHVybmVkICR7Zn0sIHdhbnQgMiAoc3RhZ2VkKSBcdTIwMTQga2VybmVsL2hvc3QgcHJvdG9jb2wgc2tldyAoJHthfTsgbmV2ZXItc2lsZW50KS5gKTtsZXQgVz1jcigkLGUua2VybmVsTWVtb3J5V2FzbS5idWZmZXIsIndhc20zMl91c2VyX2xpYmMiLGBzdGFnZWQgJHtwLnNsaWNlKDAsMjQpfVx1MjAyNiAoJHthfSlgLCEwKSxfZT1XLmxlbmd0aCxqZT0kLndhc20zMl91c2VyX2xpYmNfZGlnZXN0X2FkZHIoKT4+PjAsd2U9bmV3IFVpbnQ4QXJyYXkoNjQpO3dlLnNldChuZXcgVWludDhBcnJheShlLmtlcm5lbE1lbW9yeVdhc20uYnVmZmVyLGplLDY0KSk7bGV0IFllPUVzKHdlKSxTdD1udWxsO2lmKHR5cGVvZiAkLndhc20zMl91c2VyX2xpYmNfbmFtZV9hZGRyPT0iZnVuY3Rpb24iKXtsZXQgR3Q9JC53YXNtMzJfdXNlcl9saWJjX25hbWVfYWRkcigpPj4+MDtpZihHdCl7bGV0IHZuPW5ldyBVaW50OEFycmF5KGUua2VybmVsTWVtb3J5V2FzbS5idWZmZXIpLGFuPUd0O2Zvcig7YW48dm4ubGVuZ3RoJiZ2blthbl0hPT0wOylhbisrO1N0PUVzKHZuLnNsaWNlKEd0LGFuKSl9fWxldCBndD1yKCgpPT4oJC53YXNtMzJfdXNlcl9saWJjX3JlbGVhc2UoKSwwKSwicmVsZWFzZUNhbGwiKTtpZihOZT9OZS5icmFja2V0KCJ3YXNtMzJfdXNlcl9saWJjX3JlbGVhc2UiLGd0KTpndCgpLFllIT09RSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzoga2VybmVsIHN0YWdlZCBkaWdlc3QgJHtZZS5zbGljZSgwLDE2KX1cdTIwMjYgYnV0IG5lZWRlZCBlbnRyeSAke2t9ICgke3Auc2xpY2UoMCwyNCl9XHUyMDI2KSB3YW50cyAke0Uuc2xpY2UoMCwxNil9XHUyMDI2IFx1MjAxNCBuZWVkZWQtbGlzdCBwYXJzZXIgc2tldyBiZXR3ZWVuIGtlcm5lbCBhbmQgaG9zdCAobmV2ZXItc2lsZW50KS5gKTtpZihTdCE9PW51bGwmJlN0IT09cCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzoga2VybmVsIHN0YWdlZCAke0pTT04uc3RyaW5naWZ5KFN0LnNsaWNlKDAsMzIpKX0gZm9yIG5lZWRlZCBpbmRleCAke2t9LCBidXQgdGhlIGhvc3QncyBlbnRyeSAke2t9IGlzICR7SlNPTi5zdHJpbmdpZnkocC5zbGljZSgwLDMyKSl9IFx1MjAxNCB0aGUgdHdvIHBhcnNlcnMgZGlzYWdyZWUgYWJvdXQgd2hhdCB0aGlzIGluZGV4IG5hbWVzIChuZXZlci1zaWxlbnQpLmApO2lmKGVuLmhhcyhFKSl7dHlwZW9mIFcuYnVmZmVyLnRyYW5zZmVyPT0iZnVuY3Rpb24iJiZXLmJ1ZmZlci50cmFuc2ZlcigwKTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1saWJjOiAke3Auc2xpY2UoMCwyNCl9XHUyMDI2IChuZWVkZWQgZW50cnkgJHtrfSkgcmVhY2hlZCB0aGUgc3RvcmUgd2hpbGUgdGhpcyB0YXNrJ3Mgb3duIHJlYWQgb2YgaXQgd2FzIHBhcmtlZDsgdGhlIHJlYWQgd2FzIGZpbmlzaGVkIGFuZCByZWxlYXNlZCwgYW5kIGl0cyAke19lfUIgZHJvcHBlZCAoJHthfSlgfSl9Y2F0Y2h7fXJldHVybiBTcihuLGEsaSl9bGV0IGZuPU9zKFcpO2lmKGZuIT09RSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogQ09OVEVOVCBTS0VXIFx1MjAxNCAke3Auc2xpY2UoMCwyNCl9XHUyMDI2IG9uIHRoZSBuZWVkZWQgc2VhcmNoIHBhdGggaGFzaGVzIHRvICR7Zm4uc2xpY2UoMCwxNil9XHUyMDI2ICgke19lfUIpOyB0aGUgZGlnZXN0LXF1YWxpZmllZCBuYW1lIGxpZXMgYWJvdXQgaXRzIGNvbnRlbnQuIFJlZnVzaW5nIGRlbGl2ZXJ5IChuZXZlci1zaWxlbnQpLmApO2xldCBtdD0kcyhXLEUpLG50PU9sKFcsRSk7dHlwZW9mIFcuYnVmZmVyLnRyYW5zZmVyPT0iZnVuY3Rpb24iJiZXLmJ1ZmZlci50cmFuc2ZlcigwKSxRcihbe2RpZ2VzdDpFLGJ5dGVzOm50LG1vZHVsZTptdC5tb2R1bGV9XSx0KTt0cnl7dCh7a2luZDoibGliYy1zby1zdGFnZWQiLGRpZ2VzdDpFLGJ5dGVzOm50LG1vZHVsZTptdC5tb2R1bGV9KX1jYXRjaHt9dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtbGliYzogc3RhZ2VkICR7cC5zbGljZSgwLDI0KX1cdTIwMjYgKG5lZWRlZCBlbnRyeSAke2t9LCAke19lfUIsIGNvbXBpbGUgJHttdC5jYWNoZWQ/IkhJVCI6IkZSRVNIIn0sICR7bnQubGVuZ3RofUIga2VwdCkgdmlhIGtlcm5lbCAke3Y/Ik5FRURFRF9TVEFHRSI6IkxJQkNfU1RBR0UifSAoJHthfTsgb25jZSBwZXIgYm9vdCBwZXIgZGlnZXN0KWB9KX1jYXRjaHt9cmV0dXJuIFNyKG4sYSxpKX1yKFNyLCJzZXJ2aWNlTGliY1N0YWdlRm9yRXhlY0ltYWdlIik7YXN5bmMgZnVuY3Rpb24gcG8obixhKXtpZihGJiZuZSE9PTAmJnR5cGVvZiBGLmV4cG9ydHMud2FzbTMyX3VzZXJfZXhlY19sb2FkPT0iZnVuY3Rpb24iJiZlLmtlcm5lbE1lbW9yeVdhc20pdHJ5e2lmKHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBFWEVDLUxPQUQtRElBRzogY2FsbGluZyB3YXNtMzJfdXNlcl9leGVjX2xvYWQgcGF0aD0iJHtufSJgfSl9Y2F0Y2h7fWxldCBpPWF3YWl0IGZyKHtsb2FkOnIoKCk9PkxhKGEsITApLCJsb2FkIikseWllbGRUdXJuOnIoKCk9PmZzKCJFWEVDLUxPQUQgcGFyayBzZXJ2aWNlIiksInlpZWxkVHVybiIpLG9uWWllbGQ6cigoKT0+e29pKCJleGVjIHBhcmsgc2VydmljZSIsbiksaXQmJkN0KHQsYFlJRUxEIGNwdT0ke2UuY3B1SWQ/PyI/In0gdGlkPSR7ZS50aWR9IHJlYXNvbj1FWEVDLUxPQUQtcGFyayBzaXRlPWV4ZWMtcGFyay1zZXJ2aWNlIHZpYT13YWtlLXdvcmRgKX0sIm9uWWllbGQiKX0pO2lmKHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBFWEVDLUxPQUQtRElBRzogd2FzbTMyX3VzZXJfZXhlY19sb2FkIFJFVFVSTkVEIHJjPSR7aXwwfWB9KX1jYXRjaHt9aWYodHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke3NbTS5QSURdfDB9IEVYRUMtTE9BRCByYz0ke2l8MH1gfSl9Y2F0Y2h7fWlmKGk8MClyZXR1cm57b2s6ITEsZXJybm86aX07bGV0IHU9Y3IoRi5leHBvcnRzLGUua2VybmVsTWVtb3J5V2FzbS5idWZmZXIsIndhc20zMl91c2VyX2V4ZWMiLCJzdGFnZWQgZXhlYyBpbWFnZSAocGFyayBzZXJ2aWNlKSIpO2lmKHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBFWEVDLUxPQUQtRElBRzogc3RhZ2VkIGltYWdlICR7dS5sZW5ndGh9QiBpbiAke0YuZXhwb3J0cy53YXNtMzJfdXNlcl9leGVjX25zZWdzKCk+Pj4wfSBzZWdtZW50KHMpOyByZS1pbnN0YW50aWF0aW5nYH0pfWNhdGNoe310cnl7YXdhaXQgZnIoe2xvYWQ6cigoKT0+U3IodSwiZXhlYy1sb2FkIChwYXJrIHNlcnZpY2UpIiwhMCk9PT1mdD9mdDowLCJsb2FkIikseWllbGRUdXJuOnIoKCk9PmZzKCJMSUJDLVNUQUdFIHBhcmsgc2VydmljZSIpLCJ5aWVsZFR1cm4iKSxvbllpZWxkOnIoKCk9PntpdCYmQ3QodCxgWUlFTEQgY3B1PSR7ZS5jcHVJZD8/Ij8ifSB0aWQ9JHtlLnRpZH0gcmVhc29uPUxJQkMtU1RBR0UtcGFyayBzaXRlPWV4ZWMtcGFyay1zZXJ2aWNlIHZpYT13YWtlLXdvcmRgKX0sIm9uWWllbGQiKX0pfWNhdGNoKEUpe3RyeXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6Imh3anMtbGliYyBleGVjLWxvYWQgcmVmdXNhbCAoY2xlYW4gUE9TSVggZXhlYyBmYWlsdXJlKTogIisoRSBpbnN0YW5jZW9mIEVycm9yP0UubWVzc2FnZTpTdHJpbmcoRSkpfSl9Y2F0Y2h7fXJldHVybiBQcm9taXNlLnJlc29sdmUoe29rOiExLGVycm5vOi0xNH0pfWxldCBwPUJhKCksaz1yKCgpPT4oRi5leHBvcnRzLndhc20zMl91c2VyX2V4ZWNfcmVsZWFzZSgpLDApLCJyZWxlYXNlQ2FsbCIpO2lmKHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OiJFWEVDLUxPQUQtRElBRzogcHJlLXJlbGVhc2UifSl9Y2F0Y2h7fWlmKE5lP05lLmJyYWNrZXQoIndhc20zMl91c2VyX2V4ZWNfcmVsZWFzZSIsayk6aygpLHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBFWEVDLUxPQUQtRElBRzogcG9zdC1yZWxlYXNlOyByZXR1cm5pbmcgJHt1Lmxlbmd0aH1CIHRvIEVYRUMgc2VydmljZWB9KX1jYXRjaHt9e2xldCBFPV9vKHUsImV4ZWMtbG9hZCAocGFyayBzZXJ2aWNlKSIpO2lmKEU8MClyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtvazohMSxlcnJubzpFfSl9cmV0dXJuIEdhKCksRmEocCksUHJvbWlzZS5yZXNvbHZlKHtvazohMCx3YXNtQnl0ZXM6dX0pfWNhdGNoKGkpe3JldHVybiB5KCJ3YXNtMzJfdXNlcl9leGVjX2xvYWQgKHBhcmsgc2VydmljZSkiKSx0KHtraW5kOiJlcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6IkQxLUZPUksgZXhlYy1pbi1wbGFjZToga2VybmVsLXJvdXRlZCB3YXNtMzJfdXNlcl9leGVjX2xvYWQgdHJhcHBlZDogIisoaSBpbnN0YW5jZW9mIEVycm9yP2kubWVzc2FnZTpTdHJpbmcoaSkpKyhpIGluc3RhbmNlb2YgRXJyb3ImJmkuc3RhY2s/YApFWEVDLUxPQUQtU1RBQ0s6IGAraS5zdGFjay5zcGxpdChgCmApLnNsaWNlKDAsMTIpLmpvaW4oIiB8ICIpOiIiKX0pLFByb21pc2UucmVzb2x2ZSh7b2s6ITEsZXJybm86LTE0fSl9cmV0dXJuIG5ldyBQcm9taXNlKGk9PntDdShpKSx0KHtraW5kOiJleGVjdmUiLHBpZDpzW00uUElEXXwwLHBhdGg6bn0pfSl9cihwbywicmVxdWVzdEV4ZWNJbWFnZSIpO2xldCB1bj17cGhhc2U6ImlkbGUiLHBhdGhQdHI6MCxieXRlczpudWxsfTtmdW5jdGlvbiBHYSgpe2xldCBuPUY/Ri5leHBvcnRzOm51bGw7aWYoIW58fHR5cGVvZiBuLndhc20zMl91c2VyX2V4ZWNfY29tbWl0IT0iZnVuY3Rpb24iKXJldHVybjtsZXQgYT1yKCgpPT4obi53YXNtMzJfdXNlcl9leGVjX2NvbW1pdCgpLDApLCJjb21taXRDYWxsIik7TmU/TmUuYnJhY2tldCgid2FzbTMyX3VzZXJfZXhlY19jb21taXQiLGEpOmEoKX1yKEdhLCJleGVjQ29tbWl0Iik7ZnVuY3Rpb24gRnMoKXt1bi5waGFzZT0iaWRsZSIsdW4ucGF0aFB0cj0wLHVuLmJ5dGVzPW51bGx9cihGcywiZXhlY1N0YWdlUmVzZXQiKTtmdW5jdGlvbiBHZChuKXtpZih1bi5waGFzZSE9PSJzdGFnZWQiKXJldHVybiExO2lmKHVuLnBhdGhQdHI9PT1uPj4+MClyZXR1cm4hMDtsZXQgYT11bi5wYXRoUHRyO3Rocm93IEZzKCksbmV3IEVycm9yKGBsb2FkRXhlY0ltYWdlS2VybmVsU3luYzogYW4gZXhlYyBmb3IgcGF0aFB0cj0weCR7KG4+Pj4wKS50b1N0cmluZygxNil9IGVudGVyZWQgd2hpbGUgdGhlIGltYWdlIGZvciAweCR7YS50b1N0cmluZygxNil9IGlzIFNUQUdFRCBhbmQgdW5yZWxlYXNlZCAoaXRzIGxpYmMgc3RhZ2UgaXMgbWlkLWZsaWdodCkgXHUyMDE0IHJlZnVzaW5nIHRvIGFiYW5kb24gYSBsaXZlIGtlcm5lbCBzdGFnaW5nIHNsb3QgKG5ldmVyLXNpbGVudClgKX1yKEdkLCJleGVjU3RhZ2VSZXN1bWluZyIpO2Z1bmN0aW9uIEtkKCl7aWYodW4ucGhhc2UhPT0ic3RhZ2VkIilyZXR1cm47bGV0IG49dW4uYnl0ZXM/dW4uYnl0ZXMubGVuZ3RoOjA7RnMoKTt0cnl7bGV0IGE9Rj9GLmV4cG9ydHM6bnVsbDtpZighYXx8dHlwZW9mIGEud2FzbTMyX3VzZXJfZXhlY19yZWxlYXNlIT0iZnVuY3Rpb24iKXJldHVybjtsZXQgaT1yKCgpPT4oYS53YXNtMzJfdXNlcl9leGVjX3JlbGVhc2UoKSwwKSwicmVsZWFzZUNhbGwiKTtOZT9OZS5icmFja2V0KCJ3YXNtMzJfdXNlcl9leGVjX3JlbGVhc2UiLGkpOmkoKTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy1leGVjOiBwaWQ9JHtzW00uUElEXXwwfSB0ZXJtaW5hdGVkIHdpdGggYSAke259QiBleGVjIGltYWdlIHN0aWxsIFNUQUdFRCAoaXRzIGxpYmMgc3RhZ2UgbmV2ZXIgZmluaXNoZWQpIFx1MjAxNCByZWxlYXNlZCB0aGUga2VybmVsIHN0YWdpbmcgc2xvdCBvbiB0aGUgd2F5IG91dC4gTmV2ZXItc2lsZW50OiBub3RoaW5nIGVsc2Ugd291bGQgaGF2ZSwgYW5kIHRoZSBhbGxvY2F0aW9uIHdvdWxkIGhhdmUgb3V0bGl2ZWQgdGhlIG1hY2hpbmUuYH0pfWNhdGNoe319Y2F0Y2h7fX1yKEtkLCJleGVjU3RhZ2VEcmFpbk9uRXhpdCIpO2Z1bmN0aW9uIEpkKG4sYT0hMSl7aWYoIShGJiZuZSE9PTAmJnR5cGVvZiBGLmV4cG9ydHMud2FzbTMyX3VzZXJfZXhlY19sb2FkPT0iZnVuY3Rpb24iJiZlLmtlcm5lbE1lbW9yeVdhc20pKXJldHVybnt1bmF2YWlsYWJsZTohMH07dHJ5e2xldCBpO2lmKEdkKG4pKWk9dW4uYnl0ZXM7ZWxzZXtsZXQgaz1MYShuLGEpfDA7aWYoaz09PWZ0KXJldHVybnt3b3VsZEJsb2NrOiEwfTtpZihrPDApcmV0dXJue29rOiExLGVycm5vOmt9O2k9Y3IoRi5leHBvcnRzLGUua2VybmVsTWVtb3J5V2FzbS5idWZmZXIsIndhc20zMl91c2VyX2V4ZWMiLCJzdGFnZWQgZXhlYyBpbWFnZSAoaW5saW5lKSIpLHVuLnBoYXNlPSJzdGFnZWQiLHVuLnBhdGhQdHI9bj4+PjAsdW4uYnl0ZXM9aX10cnl7aWYoU3IoaSwiZXhlYy1sb2FkIChpbmxpbmUpIixhKT09PWZ0KXJldHVybnt3b3VsZEJsb2NrOiEwfX1jYXRjaChrKXtGcygpO3RyeXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6Imh3anMtbGliYyBleGVjLWxvYWQgcmVmdXNhbCAoY2xlYW4gUE9TSVggZXhlYyBmYWlsdXJlKTogIisoayBpbnN0YW5jZW9mIEVycm9yP2subWVzc2FnZTpTdHJpbmcoaykpfSl9Y2F0Y2h7fXJldHVybntvazohMSxlcnJubzotMTR9fWxldCB1PUJhKCkscD1yKCgpPT4oRi5leHBvcnRzLndhc20zMl91c2VyX2V4ZWNfcmVsZWFzZSgpLDApLCJyZWxlYXNlQ2FsbCIpO05lP05lLmJyYWNrZXQoIndhc20zMl91c2VyX2V4ZWNfcmVsZWFzZSIscCk6cCgpLEZzKCk7e2xldCBrPV9vKGksImV4ZWMtbG9hZCAoaW5saW5lKSIpO2lmKGs8MClyZXR1cm57b2s6ITEsZXJybm86a319cmV0dXJuIEdhKCksRmEodSkse29rOiEwLHdhc21CeXRlczppfX1jYXRjaChpKXtyZXR1cm4gRnMoKSx5KCJ3YXNtMzJfdXNlcl9leGVjX2xvYWQgKGlubGluZSkiKSx0KHtraW5kOiJlcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6IkhXSlMtQi0yIGV4ZWM6IGtlcm5lbC1yb3V0ZWQgd2FzbTMyX3VzZXJfZXhlY19sb2FkIHRyYXBwZWQ6ICIrKGkgaW5zdGFuY2VvZiBFcnJvcj9pLm1lc3NhZ2U6U3RyaW5nKGkpKSsoaSBpbnN0YW5jZW9mIEVycm9yJiZpLnN0YWNrP2AKRVhFQy1MT0FELVNUQUNLOiBgK2kuc3RhY2suc3BsaXQoYApgKS5zbGljZSgwLDEyKS5qb2luKCIgfCAiKToiIil9KSx7b2s6ITEsZXJybm86LTE0fX19cihKZCwibG9hZEV4ZWNJbWFnZUtlcm5lbFN5bmMiKTtmdW5jdGlvbiBhcyhuLGE9NDA5Nil7bGV0IGk9bj4+PjA7aWYoaT09PTApcmV0dXJuIiI7bGV0IHU9bmV3IFVpbnQ4QXJyYXkoZS5tZW1vcnkuYnVmZmVyKSxwPWksaz1NYXRoLm1pbih1Lmxlbmd0aCxpK2EpO2Zvcig7cDxrJiZ1W3BdIT09MDspcCsrO3JldHVybiBFcyh1LnN1YmFycmF5KGkscCkpfXIoYXMsInJlYWRVc2VyQ1N0cmluZyIpO2xldCBJcz1uZXcgU2V0KFsiX19od2pzX2J1ZGdldF91bmluaXRpYWxpemVkIiwiX19od2pzX2J1ZGdldF9ub3RfcmVmaWxsZWQiXSk7ZnVuY3Rpb24gJHIobixhKXtyZXR1cm4gbj09PSJfX2h3anNfYnVkZ2V0X25vdF9yZWZpbGxlZCI/aT0+e2xldCB1PWFzKGk+Pj4wLDI1Nil8fCI8dW5uYW1lZD4iLHA9YGh3anMtYnVkZ2V0OiBEUklWRVIgQ09OVFJBQ1QgQlJFQUNIIGluICIke2F9IiBcdTIwMTQgdGhlIE02IHNhZmVwb2ludCBpbiAke3V9KCkgcGFya2VkIG9uIGFuIGV4cGlyZWQgQF9faHdqc19idWRnZXQgYW5kIHRoZSBkcml2ZXIgUkVTVU1FRCBpdCB3aXRob3V0IHJlYmluZGluZyBvbmUuIEV2ZXJ5IGZvbGxvd2luZyBiYWNrLWVkZ2UgY3Jvc3NpbmcgdGFrZXMgdGhlIGV4cGlyeSBhcm0sIHNvIHRoZSBtb2R1bGUgc3BlbmRzIGl0cyBsaWZlIGluIHBhcmsvcmVzdW1lIHJvdW5kIHRyaXBzIGF0IGxvb3AtaXRlcmF0aW9uIGdyYW51bGFyaXR5IHdoaWxlIGV2ZXJ5IGluc3RydW1lbnQgc3RpbGwgcmVwb3J0cyBpdCBwcmVlbXB0aWJsZS4gUmVmaWxsIHRoZSBidWRnZXQgb2YgRVZFUlkgbW9kdWxlIGluc3RhbmNlIG9uIHJlc3VtZSAodGhlIGhhbmRsZSdzIGJ1ZGdldEdsb2JhbCAvIF9faHdqc19idWRnZXRfc2V0KSwgbm90IGp1c3QgdGhlIG1haW4ncy4gVGhlIG1vZHVsZSB0cmFwcyBhdCB0aGUgXGB1bnJlYWNoYWJsZVxgIGltbWVkaWF0ZWx5IGFmdGVyIHRoaXMgY2FsbCBcdTIwMTQgdGhhdCB0cmFwIGlzIGluIHRoZSBpbWFnZSBhbmQgaXMgaWRlbnRpY2FsIGluIHRoZSBzdGF0aWMgYW5kIC1zaGFyZWQgYnVpbGRzOyB0aGlzIHJlcG9ydCBvbmx5IG5hbWVzIHRoZSBzaXRlLmA7dHJ5e3Qoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpwfSl9Y2F0Y2h7fXRocm93IG5ldyBFcnJvcihwKX06KCk9PntsZXQgaT1gaHdqcy1idWRnZXQ6IFVOSU5JVElBTElaRUQgQlVER0VUIGluICIke2F9IiBcdTIwMTQgdGhlIG1vZHVsZSdzIHN0YXJ0dXAgc2FuaXR5IGNvbnN0cnVjdG9yIGZvdW5kIEBfX2h3anNfYnVkZ2V0IHN0aWxsIGF0IHRoZSB3ZWFrLTAgZGVmYXVsdCwgaS5lLiBub3RoaW5nIGJvdW5kIHRoaXMgaW5zdGFuY2UncyBpbml0aWFsIHNhZmVwb2ludCBidWRnZXQgQkVGT1JFIGl0cyBjb25zdHJ1Y3RvcnMgcmFuLiBBIHplcm8gYnVkZ2V0IGlzIGNvcnJlY3RuZXNzLXNhZmUgKGV2ZXJ5IHNhZmVwb2ludCBwYXJrcykgYnV0IHBlcmYtZmF0YWwsIHdoaWNoIGlzIHdoeSBpdCBpcyByZWZ1c2VkIHJhdGhlciB0aGFuIHRvbGVyYXRlZC4gVGhlIGxvYWRlciBhcm1zIGEgZnJlc2hseSBsb2FkZWQgbW9kdWxlJ3MgYnVkZ2V0IGJlZm9yZSBjdG9ycyAoYXJtTW9kdWxlQnVkZ2V0KTsgcmVhY2hpbmcgdGhpcyBoYW5kbGVyIG1lYW5zIHRoYXQgYXJtaW5nIGRpZCBub3QgaGFwcGVuIGZvciB0aGlzIG1vZHVsZS4gVGhlIG1vZHVsZSB0cmFwcyBhdCB0aGUgXGB1bnJlYWNoYWJsZVxgIGltbWVkaWF0ZWx5IGFmdGVyIHRoaXMgY2FsbCBcdTIwMTQgdGhhdCB0cmFwIGlzIGluIHRoZSBpbWFnZSBhbmQgaXMgaWRlbnRpY2FsIGluIHRoZSBzdGF0aWMgYW5kIC1zaGFyZWQgYnVpbGRzOyB0aGlzIHJlcG9ydCBvbmx5IG5hbWVzIHRoZSBtb2R1bGUuYDt0cnl7dCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOml9KX1jYXRjaHt9dGhyb3cgbmV3IEVycm9yKGkpfX1yKCRyLCJtYWtlQnVkZ2V0TG91ZEhhbmRsZXIiKTtsZXQgemQ9bmV3IFNldChbIl9faHdqc19mcmFtZV9hbGxvYyIsIl9faHdqc19mcmFtZV9mcmVlIiwiX19od2pzX2ZyYW1lX3B1Ymxpc2giLCJfX2h3anNfc2V0X3BhcmtlZCIsIl9faHdqc19jbGVhcl9wYXJrZWQiLCJfX2h3anNfdGFrZV9wYXJrZWQiLCJfX2h3anNfbm9yZXR1cm5fY29tcGxldGVkIiwiX19od2pzX3hmZXJfZGVzY2VuZCIsIl9faHdqc194ZmVyX3BhcmsiLCJfX2h3anNfeGZlcl9yZXR1cm4iLCJfX2h3anNfeGZlcl90YWtlIiwiaHdqc19zal9yZWNvcmQiLCJod2pzX2xqX2FybV9mcm9tIiwiaHdqc19sal9tYXRjaCIsImh3anNfbGpfc2VsZWN0b3IiLCJod2pzX2xqX3ZhbHVlIiwiaHdqc19sal9jbGVhciIsImh3anNfbGpfdW53b3VuZCIsImh3anNfdHJhcCIsImh3anNfcmVzdW1lIiwiaHdqc19kb25lIiwiaHdqc19kZXN0cm95IiwiX19od2pzX2xhbmVfaWQiLCJfX2h3anNfZHJpdmVfYWJpIiwiX19od2pzX3JlZ2lzdGVyX3N1c3BlbmRzIiwiX19od2pzX2RzX3JlZ2lvbl9hYmlfdjIiLCJfX2h3anNfcmVnaW9uX2FsbG9jIiwiX19od2pzX3JlZ2lvbl9zYXZlIiwiX19od2pzX3JlZ2lvbl9yZXN0b3JlIiwiX19od2pzX2ZyZWVhIiwiX19od2pzX3N0YXR1c19wYXJrX2V4aXQiLCJfX2h3anNfc3RhdHVzX2JhdG9uIiwiX19od2pzX3N0YXR1c19jbGVhciIsIl9faHdqc19zdGF0dXNfYWRvcHRfdG9wIiwiX19od2pzX2RyaXZlX2Fkb3B0X3BhcmtlZCIsIl9faHdqc19zdGF0dXNfcmFpc2VfdW53aW5kIiwiX19od2pzX3N0YXR1c19yYWlzZV9sb25nam1wIiwiX19od2pzX3N0YXR1c19zal9yZWdpc3RlciIsIl9faHdqc19zdGF0dXNfdmlvbGF0aW9uIiwiX19od2pzX3N0YXR1c19sb25nam1wX2xvc3QiLCJfX2h3anNfdW5jYXVnaHRfdW53aW5kaW5nIl0pLEhzPW5ldyBTZXQoWyJfX2h3anNfY2Fwc3VtbWFyeV9sb29rdXAiLCJfX2h3anNfZThfcmVmdXNlIiwiX19od2pzX2ZwY2FzdF9hZGFwdGVyX2xvb2t1cCIsIl9faHdqc19mcGNhc3RfdGFyZ2V0X3NpZ19sb29rdXAiLCJfX2h3anNfcmVnaXN0ZXJfY2Fwc3VtbWFyeSIsIl9faHdqc19yZWdpc3Rlcl9mcGNhc3RfYWRhcHRlciJdKTtmdW5jdGlvbiBLYShuKXtsZXQgYT1GP0YuZXhwb3J0czpudWxsO3JldHVybihpLHUscCk9PntpZihwIT09ImZ1bmN0aW9uInx8aSE9PSJlbnYiKXJldHVybjtpZihJcy5oYXModSkpcmV0dXJuKGdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX1JFRF9OT19CVURHRVRfSEFORExFUl9CSU5EfHwiIik9PT0iMSI/dm9pZCAwOiRyKHUsbnx8ImEgZGxvcGVuJ2QgbW9kdWxlIik7aWYodT09PSJmb3JrIil7bGV0ICQ9aiYmKGouX0Zvcmt8fGouZm9yayk7aWYodHlwZW9mICQ9PSJmdW5jdGlvbiIpcmV0dXJuICQ7dGhyb3cgbmV3IEVycm9yKCJod2pzLWRsb3BlbjogZW52LmZvcmsgdW5yZXNvbHZlZCBcdTIwMTQgdGhlIGR5bmFtaWMtbWFpbiBleHBvcnRzIG5vIG11c2wgX0ZvcmsvZm9yayBQQVJLIExFQUYgZm9yIHRoZSBsb2FkZWQgbW9kdWxlIHRvIHN1c3BlbmQgdGhyb3VnaC4gVGhlIGhvc3QgY2Fubm90IHN5bnRoZXNpemUgYSB3YXNtIHBhcmsgbGVhZiBmcm9tIEpTICh0aGUgZm9yayBkeW5hbWljLW1haW4gbXVzdCBleHBvcnQgKyBrZWVwIGl0cyBfRm9yayBwYXJrIGxlYWYpLiIpfWlmKHpkLmhhcyh1KXx8dS5zdGFydHNXaXRoKCJfX2h3anNfcHJvbWlzZV8iKSl7bGV0ICQ9aj9qW3VdOnZvaWQgMDtpZih0eXBlb2YgJD09ImZ1bmN0aW9uIilyZXR1cm4gJDt0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBlbnYuJHt1fSBpcyBhIE1BSU4tb3duZWQgaHdqcyBydW50aW1lIG9wIGJ1dCB0aGUgbWFpbiBpbWFnZSBkb2VzIG5vdCBleHBvcnQgIiR7dX0iIFx1MjAxNCByZWZ1c2luZyB0aGUga2VybmVsJ3MgbmFtZXNha2UgKGNyb3NzLWFkZHJlc3Mtc3BhY2UgbWlzZGlzcGF0Y2g7IHRoZSBkeW5hbWljLW1haW4gbXVzdCBjYXJyeSBpdHMgb3duIGh3anNfdXNlcl9ydCBvcCBzZXQ7IG5ldmVyLXNpbGVudCkuYCl9aWYoSHMuaGFzKHUpKXtpZihYblt1XSlyZXR1cm4gWG5bdV07bGV0ICQ9YT9hW3VdOnZvaWQgMDtpZih0eXBlb2YgJD09ImZ1bmN0aW9uIilyZXR1cm4gJDt0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiBlbnYuJHt1fSBpcyBhIEtFUk5FTC1vd25lZCByZWdpc3RyeSBvcCBidXQgdm1saW51eCBkb2VzIG5vdCBleHBvcnQgIiR7dX0iIFx1MjAxNCByZWZ1c2luZyB0byBiaW5kIGVsc2V3aGVyZSAobmV2ZXItc2lsZW50KS5gKX1pZihqJiZ0eXBlb2Ygalt1XT09ImZ1bmN0aW9uIilyZXR1cm4gTCh1LGpbdV0pO2xldCBrPVhvKHUsQnQpO2lmKGspcmV0dXJuIEwodSxrKTtsZXQgRT1Ybyh1LGp0LnZhbHVlcygpKTtpZihFKXJldHVybiBMKHUsRSl9fXIoS2EsIm1ha2VEbG9wZW5SZXNvbHZlSW1wb3J0Iik7ZnVuY3Rpb24gSmEoKXtyZXR1cm4gbj0+e2xldCBhPWo/altuXTp2b2lkIDA7aWYoYSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbClyZXR1cm4gYS52YWx1ZT4+PjA7bGV0IGk9cW8obixCdCk7aWYoaSE9PXZvaWQgMClyZXR1cm4gaTtsZXQgdT1xbyhuLGp0LnZhbHVlcygpKTtpZih1IT09dm9pZCAwKXJldHVybiB1fX1yKEphLCJtYWtlRGxvcGVuUmVzb2x2ZURhdGFBZGRyZXNzIik7ZnVuY3Rpb24gemEobixhLGkpe3JldHVybih1LHAsayk9PntsZXQgRT1uKHUscCxrKTtyZXR1cm4gayE9PSJmdW5jdGlvbiJ8fHUhPT0iZW52Inx8dHlwZW9mIEUhPSJmdW5jdGlvbiI/RTpwPT09Il9faHdqc19mcmFtZV9hbGxvYyI/JD0+e2xldCB2PUUoJCk7cmV0dXJuKHZ8MCkhPT0wJiZhLmxpdmUrKyx2fTpwPT09Il9faHdqc19mcmFtZV9mcmVlIj8kPT57aWYoRSgkKSwoJHwwKSE9PTApe2lmKGEubGl2ZTw9MCl7YS5wb2lzb25lZD0hMCx0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6YEhXSlMtNSBNMiBkbGNsb3NlIGNlbnN1cyBVTkRFUkZMT1cgZm9yICIke2l9IjogX19od2pzX2ZyYW1lX2ZyZWUoMHgkeygkPj4+MCkudG9TdHJpbmcoMTYpfSkgd2l0aCBsaXZlPTAgXHUyMDE0IHRoZSBwZXItbW9kdWxlIGZyYW1lIGNlbnN1cyBsb3N0IGFuIGFsbG9jOyBtb2R1bGUgUE9JU09ORUQgKGl0cyBkbGNsb3NlIHdpbGwgcmVmdXNlOyBuZXZlci1zaWxlbnQsIG5vbi10ZXJtaW5hbCkuYH0pO3JldHVybn1hLmxpdmUtLX19OkV9fXIoemEsIm1ha2VGcmFtZUNlbnN1c1Jlc29sdmVJbXBvcnQiKTtsZXQgWWE9bmV3IFNldDtmdW5jdGlvbiBVcyhuLGEsaSx1LHApe2lmKG49bj4+PjAsYT1hPj4+MCxLdSl7bGV0IGI9Wy4uLmp0LnZhbHVlcygpXS5tYXAoUD0+YCR7UC5wYXRofUBbJHtQLnRhYmxlQmFzZX0sJHtQLnRhYmxlQmFzZSsoUC5oYW5kbGUmJlAuaGFuZGxlLmR5bGluaz9QLmhhbmRsZS5keWxpbmsudGFibGVTaXplPj4+MDowKX0pcmVjcz0ke1AueG1vZFJlY3M/UC54bW9kUmVjcy5zaXplOi0xfWApLmpvaW4oIiAiKTt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nyx0ZXh0OmBod2pzLXhtb2QtY29uc3VsdCBUUkFDRSBzaWc9MHgke24udG9TdHJpbmcoMTYpfSBmcD0ke2F9IG1vZHM6ICR7Yn1gfSl9aWYodSYmS24ubGVuZ3RoPT09MClyZXR1cm4gMTtsZXQgaz1HbChuLGEsS24sanQudmFsdWVzKCksYj0+U24uZ2V0KGI+Pj4wKSksRT1rLmRlYWQsJD1rLmxpdmUsdj1KbCh7aW5EZWFkOiEhRSxpbkZvb3RwcmludDohISQsaW5FbGVtOmsuaW5FbGVtLGhhc1JlYzprLmhhc1JlYyxyZWNPdGhlclNpZzprLnJlY090aGVyU2lnLHJlY0FueTprLnJlY0FueSxyZWdSYW46ay5yZWdSYW4sZnJvbU1haW46aSxmcm9tUnQ6dSxtYXJzaGFsOnB9KTtpZih2PT09Mil7bGV0IGI9JD9gIiR7JC5wYXRofSIgKG1vZHVsZUlkPSR7JC5tb2R1bGVJZH0pYDoidGhlIG1haW4gaW1hZ2UiLFA9bisiOiIrYSsiOiIrYjtpZighWWEuaGFzKFApKXtZYS5hZGQoUCk7bGV0IEg9U24uZ2V0KGEpPj4+MDt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NSx0ZXh0OmBIV0pTIEYxNzMgeG1vZC1jb25zdWx0IE1BUlNIQUw6IHRhYmxlIGluZGV4ICR7YX0gKHNpdGVfc2lnPTB4JHtuLnRvU3RyaW5nKDE2KX0pIHRhcmdldHMgJHtifSwgcmVnaXN0ZXJlZCB1bmRlciBvd24gc2lnIDB4JHtILnRvU3RyaW5nKDE2KX0gXHUyMDE0IHRoZSBzaXRlJ3MgYXJtIGNhbGxzIGl0IGlmIHRoYXQgaXMgYSBwYXJhbWV0ZXIgcHJlZml4IG9mIHRoZSBzaXRlIHNpZ25hdHVyZSBhbmQgdHJhcHMgb3RoZXJ3aXNlIChpc3N1ZSBsaW51eC1pbi10aGUtYnJvd3NlciMxODYpLmB9KX19cmV0dXJuIHZ8fCh0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6RT9gSFdKUyBGMTUyIHhtb2QtY29uc3VsdCBFOC1SRUZVU0UgKGRlYWQtbW9kdWxlKTogc2lnLWNvbXBhdGlibGUgb3Blbi13b3JsZCBkaXNwYXRjaCBvZiB0YWJsZSBpbmRleCAke2F9IChzaXRlX3NpZz0weCR7bi50b1N0cmluZygxNil9KSB0YXJnZXRzIGRsY2xvc2VkIG1vZHVsZSAiJHtFLnBhdGh9IiAobW9kdWxlSWQ9JHtFLm1vZHVsZUlkfSkgXHUyMDE0IHJlZnVzaW5nIGxvdWRseTsgdGhlIGNhbGxlciB0cmFwcyAobmV2ZXItc2lsZW50OyBpc3N1ZSBsaW51eC1pbi10aGUtYnJvd3NlciM0MCkuYDpgSFdKUyBGMTUyIHhtb2QtY29uc3VsdCBFOC1SRUZVU0UgKHVucmVnaXN0ZXJlZC10YXJnZXQpOiBzaWctY29tcGF0aWJsZSBvcGVuLXdvcmxkIGRpc3BhdGNoIG9mIHRhYmxlIGluZGV4ICR7YX0gKHNpdGVfc2lnPTB4JHtuLnRvU3RyaW5nKDE2KX0pIHRhcmdldHMgIiR7JC5wYXRofSIgKG1vZHVsZUlkPSR7JC5tb2R1bGVJZH0pIGJ1dCB0aGF0IG1vZHVsZSBoYXMgTk8gbGl2ZSBfX2h3anNfcmVnaXN0ZXJfZnBjYXN0X2FkYXB0ZXIgcmVjb3JkIGZvciAoc2lnLCB0YXJnZXQpIFx1MjAxNCBpdHMgRjExNyByZWdpc3RyYXRpb24gY3RvcnMgdW5kZXItcmFuIChzdHJpcHBlZCBzdGFydCAvIHBhcnRpYWwgcmVnaXN0cmF0aW9uKSBvciB0aGUgcmVjb3JkJ3Mgd2FzbSBzaWduYXR1cmUgaXMgaW5jb25zaXN0ZW50IHdpdGggdGhpcyBzaXRlIFx1MjAxNCByZWZ1c2luZyBsb3VkbHk7IHRoZSBjYWxsZXIgdHJhcHMgKG5ldmVyLXNpbGVudDsgaXNzdWUgbGludXgtaW4tdGhlLWJyb3dzZXIjNDApLmB9KSwwKX1yKFVzLCJ4bW9kRGlzcGF0Y2hDaGVjayIpO2Z1bmN0aW9uIFZhKG4sYSxpKXtyZXR1cm4odSxwLGspPT57aWYoaz09PSJmdW5jdGlvbiImJnU9PT0iZW52IiYmcD09PSJfX2h3anNfeG1vZF9kaXNwYXRjaF9jaGVjayIpcmV0dXJuIFVzO2xldCBFPW4odSxwLGspO3JldHVybiBrIT09ImZ1bmN0aW9uInx8dSE9PSJlbnYifHx0eXBlb2YgRSE9ImZ1bmN0aW9uIj9FOnA9PT0iX19od2pzX3JlZ2lzdGVyX2ZwY2FzdF9hZGFwdGVyIj8oaSYmKGkuaW1wb3J0ZWQ9ITApLCgkLHYsYixQLEgpPT4oYS5hZGQoKHY+Pj4wKSsiOiIrKFA+Pj4wKSksRSgkLHYsYixQLEgpKSk6RX19cihWYSwibWFrZVhtb2RDb25zdWx0UmVzb2x2ZUltcG9ydCIpO2Z1bmN0aW9uIFhhKG4sYSxpLHUscCl7aWYoU24uc2V0KHU+Pj4wLGE+Pj4wKSwhenImJm4+Pj4wPT09SnUpcmV0dXJuIDE7bGV0IGs9Rj9GLmV4cG9ydHM6bnVsbCxFPWs/ay5fX2h3anNfcmVnaXN0ZXJfZnBjYXN0X2FkYXB0ZXI6dm9pZCAwLCQ9dHlwZW9mIEU9PSJmdW5jdGlvbiI/RShuLGEsaSx1LHApfDA6MDtpZih6cil7bGV0IHY9Im4vYSI7dHJ5e2xldCBiPWs/ay5fX2h3anNfZnBjYXN0X3RhcmdldF9zaWdfbG9va3VwOnZvaWQgMDt0eXBlb2YgYj09ImZ1bmN0aW9uIiYmKHY9IjB4IisoYih1KT4+PjApLnRvU3RyaW5nKDE2KSl9Y2F0Y2h7fXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nyx0ZXh0OmBGUENBU1QtUkVHSVNURVIoc2NvcGVkKSBzaWc9MHgkeyhhPj4+MCkudG9TdHJpbmcoMTYpfSBmaWQ9MHgkeyhpPj4+MCkudG9TdHJpbmcoMTYpfSB0Z3Q9JHt1Pj4+MH0gbWlkPSR7cD4+PjB9IGNlbnN1cz0ke1NuLnNpemV9IGtlcm5lbC1yYz0keyR9IGtlcm5lbC1yZWFkYmFjaz0ke3Z9YH0pfWNhdGNoe319cmV0dXJuICR9cihYYSwiZnBjYXN0UmVnaXN0ZXJTY29wZWQiKTtmdW5jdGlvbiBxYShuLGEpe2xldCBpPVNuLmdldChhPj4+MCksdT1pIT09dm9pZCAwJiZpPT09bj4+PjA/YXwwOjA7aWYoenIpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo3LHRleHQ6YEZQQ0FTVC1MT09LVVAoc2NvcGVkKSBzaXRlX3NpZz0weCR7KG4+Pj4wKS50b1N0cmluZygxNil9IHRndD0ke2E+Pj4wfSBvd249JHtpPT09dm9pZCAwPyJNSVNTIjoiMHgiK2kudG9TdHJpbmcoMTYpfSAtPiAke3V9YH0pfWNhdGNoe31yZXR1cm4gdX1yKHFhLCJmcGNhc3RBZGFwdGVyTG9va3VwU2NvcGVkIik7ZnVuY3Rpb24gWmEobil7bGV0IGE9U24uZ2V0KG4+Pj4wKSxpPWE9PT12b2lkIDA/MDphfDA7aWYoenIpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo3LHRleHQ6YEZQQ0FTVC1UU0lHKHNjb3BlZCkgdGd0PSR7bj4+PjB9IC0+ICR7YT09PXZvaWQgMD8iTUlTUygwKSI6IjB4IithLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fXJldHVybiBpfXIoWmEsImZwY2FzdFRhcmdldFNpZ0xvb2t1cFNjb3BlZCIpO2xldCBYbj17X19od2pzX3JlZ2lzdGVyX2ZwY2FzdF9hZGFwdGVyOlhhLF9faHdqc19mcGNhc3RfYWRhcHRlcl9sb29rdXA6cWEsX19od2pzX2ZwY2FzdF90YXJnZXRfc2lnX2xvb2t1cDpaYX07ZnVuY3Rpb24gWWQobil7aWYoIW58fHR5cGVvZiBuIT0ib2JqZWN0IilyZXR1cm47bGV0IGE9KGdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX0ZPUktfUkVQTEFZX0FQUEVORF9PTkxZfHwiIik9PT0iMSIsaT1BcnJheS5pc0FycmF5KG4ucmVwbGF5KT9uLnJlcGxheTpbXSx1PUFycmF5LmlzQXJyYXkobi5kZWFkUmFuZ2VzKT9uLmRlYWRSYW5nZXM6W10scD1BcnJheS5pc0FycmF5KG4ubWFpblNjb3BlKT9uLm1haW5TY29wZTpbXSxrPUFycmF5LmlzQXJyYXkobi5tYWluU2NvcGVOYW1lcyk/bi5tYWluU2NvcGVOYW1lczpbXTtpZihpLmxlbmd0aD09PTAmJnUubGVuZ3RoPT09MCYmcC5sZW5ndGg9PT0wJiZrLmxlbmd0aD09PTApcmV0dXJuO2xldCBFPXplO2lmKCEoRSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5LlRhYmxlKSl0aHJvdyBuZXcgRXJyb3IoIkhXSlMtNSBmb3JrXHhEN2Rsb3BlbjogY2hpbGQgaGFzIGEgZGxvcGVuRm9yayBwYXlsb2FkIGJ1dCBubyBzaGFyZWQgdGFibGUgXHUyMDE0IHRoZSBmb3JrLXJlc3VtZSBtYWluIGltYWdlIGlzIG5vdCBhIGR5bmFtaWMtbWFpbiAobmV2ZXItc2lsZW50KS4iKTtsZXQgJD1FLmxlbmd0aD4+PjA7aWYoIWEpe2xldCBiPW4udGFibGVMZW4+Pj4wfHwwO2lmKGI8JCl0aHJvdyBuZXcgRXJyb3IoYEhXSlMtNSBmb3JrXHhEN2Rsb3BlbjogcGFyZW50IGZvcmstdGltZSB0YWJsZSBsZW5ndGggJHtifSA8IGNoaWxkIG1haW4tZWxlbSB0YWJsZSBsZW5ndGggJHskfSBcdTIwMTQgdGhlIGNoaWxkJ3MgbWFpbiBpbWFnZSBkaXZlcmdlZCBmcm9tIHRoZSBwYXJlbnQncyAobmV2ZXItc2lsZW50LCB0aGUgcmVjb3JkZWQgcGxhY2VtZW50cyB3b3VsZCBvdmVybGFwIG1haW4ncyBlbGVtKS5gKTtpZihiPiQpdHJ5e0UuZ3JvdyhiLSQpfWNhdGNoKFApe3Rocm93IG5ldyBFcnJvcihgSFdKUy01IGZvcmtceEQ3ZGxvcGVuOiBjb3VsZCBub3QgZ3JvdyB0aGUgY2hpbGQgdGFibGUgJHskfSAtPiAke2J9IChtYXggcmVhY2hlZD8pOiBgKyhQIGluc3RhbmNlb2YgRXJyb3I/UC5tZXNzYWdlOlN0cmluZyhQKSkpfWZvcihsZXQgUCBvZiB1KUtuLnB1c2goe3RhYmxlQmFzZTpQLnRhYmxlQmFzZT4+PjAsdGFibGVTaXplOlAudGFibGVTaXplPj4+MCxhcHBlbmRlZDpBcnJheS5pc0FycmF5KFAuYXBwZW5kZWQpP1suLi5QLmFwcGVuZGVkXTpbXSxwYXRoOlAucGF0aHx8IiIsbW9kdWxlSWQ6UC5tb2R1bGVJZHwwfSk7aWYoY24gaW5zdGFuY2VvZiBNYXApZm9yKGxldFtQLEhdb2YgQXJyYXkuaXNBcnJheShuLmdvdEZ1bmMpP24uZ290RnVuYzpbXSljbi5zZXQoU3RyaW5nKFApLEg+Pj4wKX1sZXQgdj0wO2ZvcihsZXQgYiBvZiBpKXtsZXQgUD17bGl2ZTpiLmxpdmU+Pj4wfHwwLHBvaXNvbmVkOiEhYi5wb2lzb25lZH0sSD1uZXcgU2V0KEFycmF5LmlzQXJyYXkoYi54bW9kUmVjcyk/Yi54bW9kUmVjczpbXSksZj17aW1wb3J0ZWQ6ITF9LFc9VmEoemEoS2EoYi5wYXRofHwiIiksUCxiLnBhdGh8fCIiKSxILGYpLF9lPWIudGFibGVCYXNlPj4+MDtpZihhKXtpZihFLmxlbmd0aD4+PjAhPT1fZSl0aHJvdyBuZXcgRXJyb3IoYEhXSlMtNSBmb3JrXHhEN2Rsb3BlbjogY2hpbGQgdGFibGUgbGVuZ3RoICR7RS5sZW5ndGh9ICE9IHBhcmVudCB0YWJsZUJhc2UgJHtfZX0gZm9yICIke2IucGF0aH0iIChjb29raWU9JHtiLmNvb2tpZX0pIFx1MjAxNCB0aGUgY2hpbGQncyB0YWJsZSBsYXlvdXQgZGl2ZXJnZWQgZnJvbSB0aGUgcGFyZW50IChyZXBsYXkgb3JkZXIgLyBtYWluIGVsZW0gbWlzbWF0Y2g7IG5ldmVyLXNpbGVudCwgdGhlIGNyb3NzLW1vZHVsZSBpZGVudGl0aWVzIHdvdWxkIG5vdCBtYXRjaCkuYCl9ZWxzZSBpZihfZTwkKXRocm93IG5ldyBFcnJvcihgSFdKUy01IGZvcmtceEQ3ZGxvcGVuOiByZWNvcmRlZCB0YWJsZUJhc2UgJHtfZX0gZm9yICIke2IucGF0aH0iIChjb29raWU9JHtiLmNvb2tpZX0pIGZhbGxzIGluc2lkZSB0aGUgY2hpbGQgbWFpbiBpbWFnZSdzIGVsZW0gcmVnaW9uIFswLCAkeyR9KSBcdTIwMTQgY29ycnVwdCBwbGFjZW1lbnQgcGF5bG9hZCAobmV2ZXItc2lsZW50LCB0aGUgZWxlbSB3cml0ZSB3b3VsZCBjbG9iYmVyIG1haW4ncyBpZGVudGl0aWVzKS5gKTtsZXQgamU9Q3Moe3dhc21CeXRlczpiLmJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheT9iLmJ5dGVzOm5ldyBVaW50OEFycmF5KGIuYnl0ZXMpLG1lbW9yeTplLm1lbW9yeSx0YWJsZTpFLGNvbXBpbGVNb2R1bGU6cih3ZT0+e2xldCBZZT1iLm1vZHVsZT9TZChiLm1vZHVsZSxiLmRpZ2VzdCk6JHMod2UpO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nyx0ZXh0OmBIV0pTNzAtU09DQUNIRSBwaWQ9JHtzW00uUElEXXwwfSAke1llLmNhY2hlZD8iSElUICI6IkNPTVBJTEUifSBwYXRoPSIke2IucGF0aHx8IiJ9IiAoZm9yay1yZXBsYXkpIGxlbj0ke3dlLmxlbmd0aH0ga2V5PSR7WWUua2V5fSBgK2thKCl9KX1jYXRjaHt9cmV0dXJuIFllLm1vZHVsZX0sImNvbXBpbGVNb2R1bGUiKSxmaXhlZE1lbW9yeUJhc2U6Yi5tZW1vcnlCYXNlPj4+MCxzaWRlVGxzOm9hKGUubW9kZSxiLGUubWFpblRsc1Nsb3QpLC4uLmE/e306e2ZpeGVkVGFibGVCYXNlOl9lLHNlZWRTeW1ib2xJbmRpY2VzOkFycmF5LmlzQXJyYXkoYi5hcHBlbmRlZCk/Yi5hcHBlbmRlZDpbXX0sbW9kdWxlSWQ6Yi5tb2R1bGVJZHwwLHNvUGF0aDpiLnBhdGh8fCIiLHJlc29sdmVJbXBvcnQ6VyxiaW5kT3duRGVmaW5pdGlvbnM6ITAscmVzb2x2ZURhdGFBZGRyZXNzOkphKCksZ290RnVuY0luZGV4OmNuLHNraXBEYXRhUmVsb2NzOiEwLHN0YWNrUG9pbnRlcjpqP2ouX19zdGFja19wb2ludGVyOnZvaWQgMCxtYWluRHJpdmVBYmk6aiYmdHlwZW9mIGouX19od2pzX2RyaXZlX2FiaT09ImZ1bmN0aW9uIj9qLl9faHdqc19kcml2ZV9hYmkoKXwwOnZvaWQgMCxtYWluTGFuZUFkZHJlc3NlZDpNZT8hIU1lLmxhbmVBZGRyZXNzZWQ6aGUsc3RhdHVzQ2hhbm5lbEFkZHI6aiYmai5fX2h3anNfc3RhdHVzX2NoYW5uZWwgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWw/ai5fX2h3anNfc3RhdHVzX2NoYW5uZWwudmFsdWUrKFplfDApKjMyPj4+MDp2b2lkIDAscGFya0ltcG9ydDpyKCgpPT57fSwicGFya0ltcG9ydCIpfSk7aWYodG4oamUpLGplLnRhYmxlQmFzZT4+PjAhPT1fZSl0aHJvdyBuZXcgRXJyb3IoYEhXSlMtNSBmb3JrXHhEN2Rsb3BlbjogcmVwbGF5ZWQgIiR7Yi5wYXRofSIgKGNvb2tpZT0ke2IuY29va2llfSkgbGFuZGVkIGF0IHRhYmxlQmFzZSAke2plLnRhYmxlQmFzZX0sIHBhcmVudCByZWNvcmRlZCAke19lfSAobmV2ZXItc2lsZW50LCB0aGUgY3Jvc3MtbW9kdWxlIGlkZW50aXRpZXMgd291bGQgbm90IG1hdGNoKS5gKTtpZihqdC5zZXQoYi5jb29raWU+Pj4wLHtoYW5kbGU6amUsbW9kdWxlSWQ6Yi5tb2R1bGVJZHwwLGJ5dGVzOmIuYnl0ZXMscGF0aDpiLnBhdGh8fCIiLG1lbW9yeUJhc2U6amUubWVtb3J5QmFzZT4+PjAsdGFibGVCYXNlOmplLnRhYmxlQmFzZT4+PjAsY2Vuc3VzOlAseG1vZFJlY3M6SCx4bW9kUmVnaXN0cmFyOmYsdGxzU2xvdHM6Yi50bHNTbG90cz4+PjAsLi4uYi5pbnRlcm5hbD97aW50ZXJuYWw6ITAsbmFtZTpiLm5hbWUsZGlnZXN0OmIuZGlnZXN0LC4uLmIubW9kdWxlP3ttb2R1bGU6Yi5tb2R1bGV9Ont9fTp7fSwuLi5iLmJvdW5kQnlEZXBlbmRlbnQ/e2JvdW5kQnlEZXBlbmRlbnQ6ITB9Ont9fSksYi5jb29raWU+Pj4wPnYmJih2PWIuY29va2llPj4+MCksdHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke3NbTS5QSURdfDB9IEZPUkstRExPUEVOLVJFUExBWSAiJHtiLnBhdGh9IiBjb29raWU9JHtiLmNvb2tpZX0gbW9kdWxlSWQ9JHtiLm1vZHVsZUlkfSBtZW1CYXNlPTB4JHsoamUubWVtb3J5QmFzZT4+PjApLnRvU3RyaW5nKDE2KX0gdGFibGVCYXNlPSR7amUudGFibGVCYXNlfWB9KX1jYXRjaHt9fWZvcihsZXQgYiBvZiBwKWp0LnNldChiPj4+MCx3bygpKSxiPj4+MD52JiYodj1iPj4+MCk7Zm9yKGxldFtiLFBdb2Ygayl7bGV0IEg9aj9qW2JdOnZvaWQgMDtpZih0eXBlb2YgSCE9ImZ1bmN0aW9uInx8UD4+PjA+PUUubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgSFdKUy01IGZvcmtceEQ3ZGxvcGVuOiBkbHN5bShtYWluLCAiJHtifSIpIHNsb3QgJHtQfSBjYW5ub3QgYmUgcmUtYm91bmQgaW4gdGhlIGNoaWxkIChuZXZlci1zaWxlbnQpYCk7bGV0IGY9RS5nZXQoUD4+PjApO2lmKGY9PT1udWxsKUUuc2V0KFA+Pj4wLEgpO2Vsc2UgaWYoZiE9PUgpdGhyb3cgbmV3IEVycm9yKGBIV0pTLTUgZm9ya1x4RDdkbG9wZW46IGRsc3ltKG1haW4sICIke2J9Iikgc2xvdCAke1B9IGhvbGRzIGEgZGlmZmVyZW50IGZ1bmN0aW9uIGluIHRoZSBjaGlsZCB0aGFuIGluIHRoZSBwYXJlbnQgKG5ldmVyLXNpbGVudClgKTtSbiBpbnN0YW5jZW9mIE1hcCYmUm4uc2V0KFN0cmluZyhiKSxQPj4+MCl9aWYodj49R24mJihHbj12KzEpLCFhKXtuLm5leHRDb29raWU+Pj4wPkduJiYoR249bi5uZXh0Q29va2llPj4+MCk7bGV0IGI9bi50YWJsZUxlbj4+PjA7aWYoRS5sZW5ndGg+Pj4wIT09Yil0aHJvdyBuZXcgRXJyb3IoYEhXSlMtNSBmb3JrXHhEN2Rsb3BlbjogY2hpbGQgdGFibGUgbGVuZ3RoICR7RS5sZW5ndGh9ICE9IHBhcmVudCBmb3JrLXRpbWUgbGVuZ3RoICR7Yn0gYWZ0ZXIgcGxhY2VtZW50IHJlcGxheSBcdTIwMTQgYW4gYXBwZW5kIGVzY2FwZWQgdGhlIHJlY29yZGVkIHBsYWNlbWVudHMgKG5ldmVyLXNpbGVudCkuYCk7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo3LHRleHQ6YGh3anMtZm9yay1kbG9wZW4tcmVwbGF5IHBpZD0ke3NbTS5QSURdfDB9IHBsYWNlZD0ke2kubGVuZ3RofSBkZWFkUmFuZ2VzPSR7dS5sZW5ndGh9IHRhYmxlTGVuPSR7RS5sZW5ndGh9IG5leHRDb29raWU9JHtHbn1gfSl9Y2F0Y2h7fX19cihZZCwicmVwbGF5Rm9ya0Rsb3BlbnMiKTtmdW5jdGlvbiB3bygpe3JldHVybnttYWluU2NvcGU6ITAsaGFuZGxlOntkeWxpbms6e3RhYmxlU2l6ZTowfSxkbHN5bTpyKG49PnFkKG4pLCJkbHN5bSIpLHRhYmxlSW5kaWNlczpyKCgpPT5bXSwidGFibGVJbmRpY2VzIiksdGFibGVFbnRyaWVzOnIoKCk9PltdLCJ0YWJsZUVudHJpZXMiKSx1bmxvYWQ6cigoKT0+e30sInVubG9hZCIpfSxtb2R1bGVJZDowLGJ5dGVzOm51bGwscGF0aDoiIixtZW1vcnlCYXNlOjAsdGFibGVCYXNlOjAsY2Vuc3VzOntsaXZlOjAscG9pc29uZWQ6ITF9LHhtb2RSZWNzOm5ldyBTZXQsdGxzU2xvdHM6MH19cih3bywibWFrZU1haW5TY29wZUVudHJ5Iik7ZnVuY3Rpb24gVmQoKXtsZXQgbj1HbisrO2lmKGp0LnNldChuPj4+MCx3bygpKSx0ZT0hMCx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRExPUEVOLU1BSU4tU0NPUEUgY29va2llPSR7bn1gfSl9Y2F0Y2h7fXJldHVybiBuPj4+MH1yKFZkLCJvcGVuTWFpblNjb3BlIik7ZnVuY3Rpb24gWGQobil7bGV0IGE9R24rKyxpPXdvKCk7aWYoaS5wYXRoPW4saS5oYW5kbGUuZGxzeW09dT0+ZWUuZGxzeW0odSksanQuc2V0KGE+Pj4wLGkpLHRlPSEwLHR0KXRyeXt0KHtraW5kOmRtZXNnLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRExPUEVOLVJFU0lERU5ULUxJQkMgY29va2llPSR7YX0gcGF0aD0iJHtufSJgfSl9Y2F0Y2h7fXJldHVybiBhPj4+MH1yKFhkLCJvcGVuUmVzaWRlbnRMaWJjIik7ZnVuY3Rpb24gcWQobil7bGV0IGE9aj9qW25dOnZvaWQgMDtpZih0eXBlb2YgYSE9ImZ1bmN0aW9uIilyZXR1cm4gMDtsZXQgaT16ZTtpZighKGkgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5UYWJsZSl8fCEoUm4gaW5zdGFuY2VvZiBNYXApfHwhKGNuIGluc3RhbmNlb2YgTWFwKSlyZXR1cm4gMDtsZXQgdT1Sbi5nZXQobik7aWYodSE9PXZvaWQgMCYmdTxpLmxlbmd0aCl7bGV0IEU9aS5nZXQodSk7aWYoRT09PWEpcmV0dXJuIHU7aWYoRSE9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogZGxzeW0obWFpbiwgIiR7bn0iKSBpZGVudGl0eSBkcmlmdCAtLSBzbG90ICR7dX0gaXQgd2FzIGhhbmRlZCBvdXQgYXQgaG9sZHMgYSBkaWZmZXJlbnQgZnVuY3Rpb24gKG5ldmVyLXNpbGVudClgKTtyZXR1cm4gaS5zZXQodSxhKSx1fWZvcihsZXQgRT0wO0U8aS5sZW5ndGg7RSsrKWlmKGkuZ2V0KEUpPT09YSlyZXR1cm4gUm4uc2V0KG4sRSksRTtsZXQgcD1jbi5nZXQobik7aWYocCE9PXZvaWQgMCYmcDxpLmxlbmd0aCl7bGV0IEU9aS5nZXQocCk7aWYoRSE9PW51bGwmJkUhPT1hKXRocm93IG5ldyBFcnJvcihgaHdqcy1kbG9wZW46IGRsc3ltKG1haW4sICIke259IikgaWRlbnRpdHkgZHJpZnQgLS0gc2xvdCAke3B9IGhvbGRzIGEgZGlmZmVyZW50IGZ1bmN0aW9uIChuZXZlci1zaWxlbnQpYCk7cmV0dXJuIEU9PT1udWxsJiZpLnNldChwLGEpLFJuLnNldChuLHApLHB9bGV0IGs9aS5sZW5ndGg7cmV0dXJuIGkuZ3JvdygxKSxpLnNldChrLGEpLGNuLnNldChuLGspLFJuLnNldChuLGspLGt9cihxZCwibWFpblNjb3BlRGxzeW0iKTtmdW5jdGlvbiBaZChuLGE9ITEpe2xldCBpPUY/Ri5leHBvcnRzOm51bGw7aWYoIWl8fHR5cGVvZiBpLndhc20zMl91c2VyX2Rsb3Blbl9sb2FkIT0iZnVuY3Rpb24ifHwhZS5rZXJuZWxNZW1vcnlXYXNtKXJldHVybiBVdD0iZGxvcGVuIHJlZnVzZWQgKEVOT1NZUyk6IG5vIGtlcm5lbCBkbG9wZW4gc3RhZ2luZyBvbiB0aGlzIFdvcmtlciAobm8gdm1saW51eCBpbnN0YW5jZSAvIHdhc20zMl91c2VyX2Rsb3Blbl9sb2FkKSIsLTM4O2lmKCEoemUgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5UYWJsZSkpcmV0dXJuIFV0PSJkbG9wZW4gcmVmdXNlZCAoRU5PU1lTKTogdGhpcyBwcm9jZXNzIGlzIG5vdCBhIGR5bmFtaWMgbWFpbiAobm8gc2hhcmVkIF9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUgdG8gbG9hZCBhIC5zbyBpbnRvIFx1MjAxNCBhIHN0YXRpYyBpbWFnZSBjYW5ub3QgZGxvcGVuKSIsLTM4O2lmKGFzKG4pPT09IiIpcmV0dXJuIFZkKCk7Vm4mJihWbi5wYXRoUHRyIT09bj4+PjB8fFZuLnBhdGghPT1hcyhuKSkmJlJzKCk7bGV0IHA7aWYoVm4pcD1Wbi5ieXRlcztlbHNle2xldCAkPXIoKCk9Pmkud2FzbTMyX3VzZXJfZGxvcGVuX2xvYWQobj4+PjApfDAsImxvYWRDYWxsIiksdj1obygiZGxvcGVuLWxvYWQiLEdyLCgpPT5pLndhc21fc3lzY2FsbChHcixuPj4+MCwwLDAsMCwwLDApfDAsKCk9Pk5lP05lLmJyYWNrZXQoIndhc20zMl91c2VyX2Rsb3Blbl9sb2FkIiwkKTokKCksSGEsVWEsYSl8MDtpZih2PT09ZnQpcmV0dXJuIGZ0O2lmKHY8MClyZXR1cm4gVXQ9YGtlcm5lbCBkbG9wZW4gc3RhZ2luZyB3YXNtMzJfdXNlcl9kbG9wZW5fbG9hZCgiJHthcyhuKX0iKSByZXR1cm5lZCAke3Z9ICh0aGUgLnNvIGNvdWxkIG5vdCBiZSByZXNvbHZlZC9yZWFkIGZyb20gdGhlIFZGUylgLHY7cD1jcihpLGUua2VybmVsTWVtb3J5V2FzbS5idWZmZXIsIndhc20zMl91c2VyX2Rsb3BlbiIsYHN0YWdlZCAuc28gIiR7YXMobil9ImApO2xldCBiPXIoKCk9PihpLndhc20zMl91c2VyX2Rsb3Blbl9yZWxlYXNlKCksMCksInJlbGVhc2VDYWxsIik7TmU/TmUuYnJhY2tldCgid2FzbTMyX3VzZXJfZGxvcGVuX3JlbGVhc2UiLGIpOmIoKX1sZXQgaz1hcyhuKTtpZihlZSYmTWUmJk1lLmRpZ2VzdCYmT3MocCk9PT1NZS5kaWdlc3QpcmV0dXJuIFJzKCksWGQoayk7bGV0IEU7dHJ5e0U9UWQobj4+PjAscCxrLGEpfWNhdGNoKCQpe3Rocm93IFJzKCksJH1pZighQXJyYXkuaXNBcnJheShFKSlyZXR1cm4gRTtmb3IobGV0ICQgb2YgRSl7bGV0IHY9UWEoJC5ieXRlcywkLnBhdGgse2ludGVybmFsOiEwLG5hbWU6JC5uYW1lLGRpZ2VzdDp0cygkLm5hbWUpLC4uLiQubW9kdWxlP3ttb2R1bGU6JC5tb2R1bGV9Ont9fSk7aWYodjwwKXJldHVybiBVdD1gd2hpbGUgbG9hZGluZyAkeyQubmFtZS5zbGljZSgwLC02NSl9LCBuZWVkZWQgYnkgIiR7JC5ieX0iOiAke1V0fWAsdn1yZXR1cm4gUWEocCxrLG51bGwpfXIoWmQsInNlcnZpY2VEbG9wZW4iKTtmdW5jdGlvbiBScygpe2xldCBuPVZuO2lmKFZuPW51bGwsbiYmbi5zY3JhdGNoKXRyeXtwcygxMSxuLnNjcmF0Y2gsNDA5NiwwLDAsMCwwKX1jYXRjaHt9fXIoUnMsImRsb3BlblBlbmRpbmdEcm9wIik7ZnVuY3Rpb24gUWQobixhLGksdSl7bGV0IHA9cihiPT57VXQ9YGh3anMtZGxvcGVuOiAke2J9IChuZXZlci1zaWxlbnQpYCxScygpO3RyeXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6VXR9KX1jYXRjaHt9cmV0dXJuLTgwfSwiZmFpbCIpLGs9Vm47aWYoIWspe2xldCBiO3RyeXtiPWVhKGEpfWNhdGNoKFApe3JldHVybiBwKGAiJHtpfSI6ICR7UCBpbnN0YW5jZW9mIEVycm9yP1AubWVzc2FnZTpQfWApfWlmKGIubGVuZ3RoPT09MClyZXR1cm5bXTtrPVZuPXtwYXRoUHRyOm4scGF0aDppLGJ5dGVzOmEsdG9wOmIscXVldWU6Yi5tYXAoUD0+KHtuYW1lOlAsYnk6aX0pKSxmZXRjaGVkOm5ldyBNYXAsc2NyYXRjaDowLGNhbmQ6MCxmZXRjaGluZzpudWxsfX1mb3IoO2sucXVldWUubGVuZ3RoOyl7bGV0e25hbWU6YixieTpQfT1rLnF1ZXVlWzBdO2lmKGsuZmV0Y2hlZC5oYXMoYikpe2sucXVldWUuc2hpZnQoKTtjb250aW51ZX1sZXQgSD1lYyhiKTtpZih0eXBlb2YgSD09InN0cmluZyIpcmV0dXJuIHAoYCIke1B9IiBuZWVkcyAke2J9LCBidXQgJHtIfWApO2lmKEgpe2sucXVldWUuc2hpZnQoKTtjb250aW51ZX1sZXQgZj1udWxsLFc9ZW4uZ2V0KHRzKGIpKTtpZihrLmZldGNoaW5nIT09YiYmVyYmVy5ieXRlcylmPXtieXRlczpXLmJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheT9XLmJ5dGVzOm5ldyBVaW50OEFycmF5KFcuYnl0ZXMpLHBhdGg6YC91c3IvbGliLyR7Yn1gLHN0b3JlZDohMCxtb2R1bGU6Vy5tb2R1bGV9O2Vsc2V7bGV0IHdlPXRjKGssYix1KTtpZihrLmZldGNoaW5nPXdlPT09ZnQ/YjpudWxsLHdlPT09ZnQpcmV0dXJuIHdlO2lmKHdlPT09LTIpcmV0dXJuIHAoYCIke1B9IiBuZWVkcyAke2J9LCB3aGljaCBpcyBpbiBuZWl0aGVyIC91c3IvbGliIG5vciAvbGliYCk7aWYodHlwZW9mIHdlPT0ibnVtYmVyIilyZXR1cm4gVXQ9YGh3anMtZGxvcGVuOiAiJHtQfSIgbmVlZHMgJHtifTsgcmVhZGluZyBpdCByZXR1cm5lZCAke3dlfSAobmV2ZXItc2lsZW50KWAsUnMoKSx3ZTtmPXdlfWxldCBfZT1mLnN0b3JlZD9icyhmLmJ5dGVzKTpudWxsO2lmKChfZT9fZS5kaWdlc3Q6T3MoZi5ieXRlcykpIT09dHMoYikpcmV0dXJuIHAoYCIke1B9IiBuZWVkcyAke2J9LCBidXQgJHtmLnBhdGh9IGRvZXMgbm90IGhhc2ggdG8gdGhhdCBkaWdlc3QgLS0gYSBjb250ZW50LWFkZHJlc3NlZCBsaWJyYXJ5IHdhcyByZXBsYWNlZCBpbiBwbGFjZWApO2xldCBqZTt0cnl7amU9ZWEoZi5ieXRlcyl9Y2F0Y2god2Upe3JldHVybiBwKGAke2YucGF0aH06ICR7d2UgaW5zdGFuY2VvZiBFcnJvcj93ZS5tZXNzYWdlOndlfWApfWsuZmV0Y2hlZC5zZXQoYix7bmFtZTpiLGJ5OlAsYnl0ZXM6Zi5ieXRlcyxwYXRoOmYucGF0aCxuZWVkczpqZSwuLi5mLm1vZHVsZT97bW9kdWxlOmYubW9kdWxlfTp7fX0pLGsucXVldWUuc2hpZnQoKTtmb3IobGV0IHdlIG9mIGplKWsucXVldWUucHVzaCh7bmFtZTp3ZSxieTpmLnBhdGh9KX1sZXQgRT1bXSwkPW5ldyBTZXQsdj1yKGI9PntpZigkLmhhcyhiKXx8IWsuZmV0Y2hlZC5oYXMoYikpcmV0dXJuOyQuYWRkKGIpO2xldCBQPWsuZmV0Y2hlZC5nZXQoYik7Zm9yKGxldCBIIG9mIFAubmVlZHMpdihIKTtFLnB1c2goUCl9LCJ2aXNpdCIpO2ZvcihsZXQgYiBvZiBrLnRvcCl2KGIpO3JldHVybiBScygpLEV9cihRZCwiZGxvcGVuTmVlZGVkQ2xvc3VyZSIpO2Z1bmN0aW9uIGVjKG4pe2xldCBhPXRzKG4pLGk9YXIobik7Zm9yKGxldCB1IG9mIHBuKXtpZih1Lm5hbWU9PT1ufHx1LmRpZ2VzdD09PWEpcmV0dXJuITA7aWYoYXIodS5uYW1lKT09PWkpcmV0dXJuYHRoaXMgcHJvY2VzcyBsb2FkZWQgJHtpfSAke3UuZGlnZXN0LnNsaWNlKDAsMTYpfVx1MjAyNiBhcyBhIG5lZWRlZCBlbnRyeSBvZiBpdHMgbWFpbiwgbm90ICR7YS5zbGljZSgwLDE2KX1cdTIwMjZgfWZvcihsZXQgdSBvZiBqdC52YWx1ZXMoKSlpZighKCF1fHx1Lm1haW5TY29wZXx8IXUuYnl0ZXMpKXtpZih1Lm5hbWU9PT1uKXJldHVybiEwO2lmKHUubmFtZSYmYXIodS5uYW1lKT09PWkpcmV0dXJuYHRoaXMgcHJvY2VzcyBhbHJlYWR5IGxvYWRlZCAke3UubmFtZX0gZm9yIGFub3RoZXIgbW9kdWxlYDtpZighdS5uYW1lJiYodS5kaWdlc3Q9PT12b2lkIDAmJih1LmRpZ2VzdD1Pcyh1LmJ5dGVzKSksdS5kaWdlc3Q9PT1hKSlyZXR1cm4gdS5ib3VuZEJ5RGVwZW5kZW50PSEwLCEwfXJldHVybiExfXIoZWMsImRsb3BlbkxpYnJhcnlQcmVzZW50Iik7ZnVuY3Rpb24gdGMobixhLGkpe2xldCB1PUYuZXhwb3J0cyxwPVtgL3Vzci9saWIvJHthfWAsYC9saWIvJHthfWBdO2lmKCFuLnNjcmF0Y2gpe2xldCBrPVhzKDksMCw0MDk2LDMsMzQsLTEsMCl8MDtpZihrPD0wKXJldHVybi0xMjtuLnNjcmF0Y2g9az4+PjAsbi5jYW5kPTAsbi5zY3JhdGNoRm9yPSIifWZvcig7bi5jYW5kPHAubGVuZ3RoO24uY2FuZCsrKXtsZXQgaz1wW24uY2FuZF07aWYobi5zY3JhdGNoRm9yIT09ayl7bGV0IEg9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGspLGY9bmV3IFVpbnQ4QXJyYXkoZS5tZW1vcnkuYnVmZmVyKTtmLnNldChILG4uc2NyYXRjaCksZltuLnNjcmF0Y2grSC5sZW5ndGhdPTAsbi5zY3JhdGNoRm9yPWt9bGV0IEU9bi5zY3JhdGNoLCQ9cigoKT0+dS53YXNtMzJfdXNlcl9kbG9wZW5fbG9hZChFKXwwLCJsb2FkQ2FsbCIpLHY9aG8oImRsb3Blbi1sb2FkIixHciwoKT0+dS53YXNtX3N5c2NhbGwoR3IsRSwwLDAsMCwwLDApfDAsKCk9Pk5lP05lLmJyYWNrZXQoIndhc20zMl91c2VyX2Rsb3Blbl9sb2FkIiwkKTokKCksSGEsVWEsaSl8MDtpZih2PT09ZnQpcmV0dXJuIHY7aWYodj09PS0yJiZuLmNhbmQrMTxwLmxlbmd0aCljb250aW51ZTtpZih2PDApcmV0dXJuIG4uY2FuZD0wLG4uc2NyYXRjaEZvcj0iIix2O2xldCBiPWNyKHUsZS5rZXJuZWxNZW1vcnlXYXNtLmJ1ZmZlciwid2FzbTMyX3VzZXJfZGxvcGVuIixgc3RhZ2VkIC5zbyAiJHtrfSJgKSxQPXIoKCk9Pih1Lndhc20zMl91c2VyX2Rsb3Blbl9yZWxlYXNlKCksMCksInJlbGVhc2VDYWxsIik7cmV0dXJuIE5lP05lLmJyYWNrZXQoIndhc20zMl91c2VyX2Rsb3Blbl9yZWxlYXNlIixQKTpQKCksbi5jYW5kPTAsbi5zY3JhdGNoRm9yPSIiLHtieXRlczpiLHBhdGg6a319cmV0dXJuIG4uY2FuZD0wLG4uc2NyYXRjaEZvcj0iIiwtMn1yKHRjLCJkbG9wZW5GZXRjaExpYnJhcnkiKTtmdW5jdGlvbiBRYShuLGEsaSl7bGV0IHU9Ri5leHBvcnRzLHA9emUsaz1yKChndCxmbik9PntsZXQgbnQ9KGdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX1JFRF9ETE9QRU5fT09NfHwiIik9PT0iMSI/MDpYcyg5LDAsZ3R8MCwzLDM0LC0xLDApfDA7aWYobnQ8PTApdGhyb3cgbmV3IEVycm9yKGBod2pzLWRsb3BlbjogU1lTX21tYXAgZm9yIHRoZSAuc28gZGF0YSByZWdpb24gKCR7Z3R9QikgcmV0dXJuZWQgJHtudH0gKG5ldmVyLXNpbGVudCBPT00pYCk7cmV0dXJuIG50Pj4+MH0sImFsbG9jTWVtb3J5IiksRT10eXBlb2YgdS5fX2h3anNfYWxsb2NfbW9kdWxlX2lkPT0iZnVuY3Rpb24iP3UuX19od2pzX2FsbG9jX21vZHVsZV9pZCgpfDA6MCwkPXtsaXZlOjAscG9pc29uZWQ6ITF9LHY9bmV3IFNldCxiPXtpbXBvcnRlZDohMX0sUD1WYSh6YShLYShhKSwkLGEpLHYsYiksSD1nbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU19SRURfTk9fQ1RPUlN8fCIiLGY9SD09PSIxInx8SC5zdGFydHNXaXRoKCIvIikmJkg9PT1hLFc9Zj9JbChuKTpuO3tsZXQgZ3Q9THMoVyksZm49Z3QmJkFycmF5LmlzQXJyYXkoZ3QubmVlZGVkKT9ndC5uZWVkZWQuZmlsdGVyKG50PT4vXmxpYmNcLnNvXC4vLnRlc3QoU3RyaW5nKG50KSkpOltdO2ZvcihsZXQgbnQgb2YgZm4pe2lmKCFNZSlyZXR1cm4gVXQ9YGh3anMtbGliYzogIiR7YX0iIG5lZWRzICR7bnR9IGJ1dCB0aGlzIHByb2Nlc3MgcnVucyBOTyBzaGFyZWQgbGliYy5zbyBcdTIwMTQgYSBzaGFyZWQtbGliYyAuc28gY2Fubm90IGxvYWQgaW50byBhIHN0YXRpYy1saWJjIHByb2Nlc3MgKG5ldmVyLXNpbGVudCkuYCx0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6VXR9KSwtODA7aWYobnQhPT1gbGliYy5zby4ke01lLmRpZ2VzdH1gKXJldHVybiBVdD1gaHdqcy1saWJjOiBESUdFU1QgU0tFVyBcdTIwMTQgIiR7YX0iIG5lZWRzICR7U3RyaW5nKG50KS5zbGljZSgwLDI0KX1cdTIwMjYgYnV0IHRoaXMgcHJvY2VzcyBsb2FkZWQgbGliYy5zby4ke01lLmRpZ2VzdC5zbGljZSgwLDE2KX1cdTIwMjYgKGEgLnNvIG9mIGEgZGlmZmVyZW50IGxpYmMgZ2VuZXJhdGlvbjsgUExBTi1EWU5BTUlDLUxJQkMgXHhBNzMuMjsgbmV2ZXItc2lsZW50KS5gLHQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpVdH0pLC04MH1sZXQgbXQ9aXIoVyk7aWYobXQmJm10Lm1hbmlmZXN0VmVyc2lvbj49MiYmbXQuc3VzcGVuZGVyRGlnZXN0TG82NCYmbXQuc3VzcGVuZGVyRGlnZXN0TG82NCE9PSIwMDAwMDAwMDAwMDAwMDAwIil7bGV0IG50PU1lP01lLnN1c3BlbmRlckRpZ2VzdExvNjQ6bnVsbDtpZihtdC5zdXNwZW5kZXJEaWdlc3RMbzY0IT09bnQpcmV0dXJuIFV0PWBod2pzLWxpYmM6IFNVU1BFTkRFUi1QQVJUSVRJT04gRElHRVNUIFNLRVcgXHUyMDE0ICIke2F9IiB3YXMgbGlua2VkIGFnYWluc3QgcGFydGl0aW9uICR7bXQuc3VzcGVuZGVyRGlnZXN0TG82NH1cdTIwMjYgYnV0IHRoaXMgcHJvY2VzcydzIGxpYmMuc28gcmVjb3JkcyAke250Pz8iPG5vbmUgXHUyMDE0IG5vIGxpYmMuc28gbG9hZGVkPiJ9XHUyMDI2IChQTEFOLURZTkFNSUMtTElCQyBceEE3My4yOyBuZXZlci1zaWxlbnQpLmAsdCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOlV0fSksLTgwfWlmKG10KXtsZXQgbnQ9ISEobXQuZmxhZ3MmJm10LmZsYWdzLmNoZWNrRW1pdHRpbmcpLEd0PU1lPyEhTWUuY2hlY2tFbWl0dGluZzp3bjtpZihudCE9PUd0KXJldHVybiBVdD1gaHdqcy1kbG9wZW46IENIRUNLLUVNSVRUSU5HIE1JU01BVENIIFx1MjAxNCAiJHthfSIgYXR0ZXN0cyBjaGVja19lbWl0dGluZz0ke250PzE6MH0gKGh3anMuYWJpIGZsYWdzIGJpdDQpIGJ1dCB0aGlzIHByb2Nlc3MgKCR7TWU/ImxpYmMuc28gIitNZS5kaWdlc3Quc2xpY2UoMCwxNikrIlx1MjAyNiI6Im1haW4gaW1hZ2UifSkgYXR0ZXN0cyBjaGVja19lbWl0dGluZz0ke0d0PzE6MH0uIE1peGluZyBjaGVjay1lbWl0dGluZyBhbmQgbm9uLWNoZWNrLWVtaXR0aW5nIG1vZHVsZXMgbGV0cyBhIHN0YXR1cy1jaGFubmVsIHRocm93L2xvbmdqbXAgdHJhbnNpdCBhbiB1bmluc3RydW1lbnRlZCBmcmFtZSBTSUxFTlRMWSAoUExBTi1DWFgtU1RBVFVTLUNIQU5ORUwgXHhBNzcsIEkzKS4gUmVidWlsZCB0aGUgLnNvIGFuZCB0aGUgcHJvY2VzcyBpbWFnZXMgaW4gbG9ja3N0ZXAgKG5ldmVyLXNpbGVudCkuYCx0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6VXR9KSwtODA7bGV0IHZuPSEhKG10LmZsYWdzJiZtdC5mbGFncy5sYW5lQWRkcmVzc2VkKSxhbj1NZT8hIU1lLmxhbmVBZGRyZXNzZWQ6aGU7aWYodm4hPT1hbilyZXR1cm4gVXQ9YGh3anMtZGxvcGVuOiBMQU5FLUFERFJFU1NFRCBNSVNNQVRDSCBcdTIwMTQgIiR7YX0iIGF0dGVzdHMgbGFuZV9hZGRyZXNzZWQ9JHt2bj8xOjB9IChod2pzLmFiaSBmbGFncyBiaXQ1KSBidXQgdGhpcyBwcm9jZXNzICgke01lPyJsaWJjLnNvICIrTWUuZGlnZXN0LnNsaWNlKDAsMTYpKyJcdTIwMjYiOiJtYWluIGltYWdlIn0pIGF0dGVzdHMgbGFuZV9hZGRyZXNzZWQ9JHthbj8xOjB9LiBNaXhpbmcgYSBsYW5lLWFkZHJlc3NlZCBtb2R1bGUgd2l0aCBhIGxhbmUtdW5hd2FyZSBvbmUgbGV0cyB0aGUgbGFuZS11bmF3YXJlIHNpZGUgcmVhZCBMQU5FIDAncyBzdGF0dXMgd29yZCBmcm9tIEFOWSBsYW5lIFx1MjAxNCBzaWxlbnQgdHJhbnNpdCB1bmRlciB0aHJlYWRzIChJMy0yOyBQTEFOLVRIUkVBRFMtU0lOR0xFLU1FTU9SWSBceEE3NCBzdGVwIDIpLiBSZWJ1aWxkIHRoZSAuc28gYW5kIHRoZSBwcm9jZXNzIGltYWdlcyBpbiBsb2Nrc3RlcCAobmV2ZXItc2lsZW50KS5gLHQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpVdH0pLC04MH19bGV0IF9lPWk/ZW4uZ2V0KGkuZGlnZXN0KTp2b2lkIDAsamU9cihndD0+e2xldCBmbj1pJiZpLm1vZHVsZSYmZ3Q9PT1uP1NkKGkubW9kdWxlLGkuZGlnZXN0KTokcyhndCxfZSYmX2UuYnl0ZXM9PT1ndD9pLmRpZ2VzdDp2b2lkIDApO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBIV0pTNzAtU09DQUNIRSBwaWQ9JHtzW00uUElEXXwwfSAke2ZuLmNhY2hlZD8iSElUICI6IkNPTVBJTEUifSBwYXRoPSIke2F9IiBsZW49JHtndC5sZW5ndGh9IGtleT0ke2ZuLmtleX0gYCtrYSgpfSl9Y2F0Y2h7fXJldHVybiBmbi5tb2R1bGV9LCJjb21waWxlTW9kdWxlIiksd2UsWWU9MDtpZih3ZT1Dcyh7d2FzbUJ5dGVzOlcsbWVtb3J5OmUubWVtb3J5LHRhYmxlOnAsYWxsb2NNZW1vcnk6ayxtb2R1bGVJZDpFLHNvUGF0aDphLGNvbXBpbGVNb2R1bGU6amUscmVzb2x2ZUltcG9ydDpQLGJpbmRPd25EZWZpbml0aW9uczohMCxyZXNvbHZlRGF0YUFkZHJlc3M6SmEoKSxnb3RGdW5jSW5kZXg6Y24sc3RhY2tQb2ludGVyOmo/ai5fX3N0YWNrX3BvaW50ZXI6dm9pZCAwLG1haW5Ecml2ZUFiaTpqJiZ0eXBlb2Ygai5fX2h3anNfZHJpdmVfYWJpPT0iZnVuY3Rpb24iP2ouX19od2pzX2RyaXZlX2FiaSgpfDA6dm9pZCAwLG1haW5MYW5lQWRkcmVzc2VkOk1lPyEhTWUubGFuZUFkZHJlc3NlZDpoZSxzdGF0dXNDaGFubmVsQWRkcjpqJiZqLl9faHdqc19zdGF0dXNfY2hhbm5lbCBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbD9qLl9faHdqc19zdGF0dXNfY2hhbm5lbC52YWx1ZSsoWmV8MCkqMzI+Pj4wOnZvaWQgMCxwYXJrSW1wb3J0OnIoKCk9Pnt9LCJwYXJrSW1wb3J0Iiksc2lkZVRsczp7bW9kZToiZnJlc2gifX0pLHdlLnRscyYmKFllPWsocmEod2UudGxzLGEpLHdlLnRscy5hbGlnbikpLHRuKHdlKSxmKXtpZih0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gUkVELU5PLUNUT1JTOiBzdHJpcHBlZCBzdGFydCArIHNraXBwZWQgcnVuQ3RvcnMgZm9yICIke2F9IiBtb2R1bGVJZD0ke0V9IChpdHMgXHhBN0U4IHJlZ2lzdGVyIGN0b3JzIGRpZCBOT1QgcnVuIFx1MjE5MiBpdHMgdGFyZ2V0cyBzdGF5IFVOUkVHSVNURVJFRCBcdTIxOTIgY29uc3VsdCBVTlJFU09MVkVEIFx1MjE5MiBlOF9yZWZ1c2UpYH0pfWNhdGNoe319ZWxzZSB3ZS5ydW5DdG9ycygpO2xldCBTdD1HbisrO2lmKGp0LnNldChTdD4+PjAse2hhbmRsZTp3ZSxtb2R1bGVJZDpFLGJ5dGVzOm4scGF0aDphLG1lbW9yeUJhc2U6d2UubWVtb3J5QmFzZT4+PjAsdGFibGVCYXNlOndlLnRhYmxlQmFzZT4+PjAsY2Vuc3VzOiQseG1vZFJlY3M6dix4bW9kUmVnaXN0cmFyOmIsdGxzU2xvdHM6WWU+Pj4wLC4uLml8fHt9fSksdGU9ITAsdHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke3NbTS5QSURdfDB9IERMT1BFTi1PSyBwYXRoPSIke2F9IiBjb29raWU9JHtTdH0gbW9kdWxlSWQ9JHtFfSBtZW1CYXNlPTB4JHsod2UubWVtb3J5QmFzZT4+PjApLnRvU3RyaW5nKDE2KX0gdGFibGVCYXNlPSR7d2UudGFibGVCYXNlfWB9KX1jYXRjaHt9cmV0dXJuIFN0Pj4+MH1yKFFhLCJpbnN0YW50aWF0ZURsb3Blbk1vZHVsZSIpO2xldCBxbj1PYmplY3QuY3JlYXRlKG51bGwpLEpuPTAsZWk9ITEsdGk9ITEsWm49MCx2cj0wLFRzPW51bGwsbmM9MCxuaT0wLHNjPTAscmM9MCxvYz1PYmplY3QuZnJlZXplKHtraW5kOiJzeXNjYWxsLXN5bmMiLHJvdXRlS2V5OmUucm91dGVLZXl9KSxzaT0yZTQscmk9ITE7ZnVuY3Rpb24gb2kobixhKXtpZih1cy5ibG9ja3MoKT09PTEpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtZXhlYyBFWEVDLUxPQUQtWUlFTEQgcGlkPSR7c1tNLlBJRF18MH0gdGlkPSR7ZS50aWR8MH0gbGFuZT0ke2UudXNlckxhbmU/PzB9IG1vZGU9JHtlLm1vZGV9IGNwdT0ke2UuY3B1SWQ/PyI/In0gc2l0ZT0ke259OiB0aGUgZXhlYyBsb2FkIG9mICIke2E/PyI/In0iIGJsb2NrLXBhcmtlZCAoLTUxNykgd2l0aCBpdHMgY2hhaW4gcHJlc2VydmVkLCBhbmQgdGhpcyBXb3JrZXIncyBKUyBldmVudCBsb29wIHdhcyBIQU5ERUQgQkFDSyBiZWZvcmUgdGhlIHJlLWlzc3VlIFx1MjAxNCBhIGNvLXJlc2lkZW50IChjYW5vbmljYWxseSB0aGUgc2luZ2xlLXRocmVhZGVkIEZVU0Ugc2VydmVyIHRoaXMgbG9hZCBpcyB3YWl0aW5nIG9uKSBnZXRzIHJlYWwgdHVybnMgaW5zdGVhZCBvZiBiZWluZyBzdGFydmVkIHRvIHRoZSBkZWFkbGluZWB9KX1jYXRjaHt9fXIob2ksImFubm91bmNlRXhlY0xvYWRZaWVsZCIpO2Z1bmN0aW9uIGFjKG4sYSl7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo0LHRleHQ6YGh3anMtZXhlYyBFWEVDLUxPQUQtSU5MSU5FIHBpZD0ke3NbTS5QSURdfDB9IHRpZD0ke2UudGlkfDB9IGxhbmU9JHtlLnVzZXJMYW5lPz8wfSBtb2RlPSR7ZS5tb2RlfSBjcHU9JHtlLmNwdUlkPz8iPyJ9OiB0aGUgZXhlYyBsb2FkIG9mICIke24/PyI/In0iIGJsb2NrLXBhcmtlZCAke2F8MH0gdGltZShzKSwgYnV0IHRoaXMgaW1hZ2UgZG9lcyBub3QgYWJzb3JiIHRoZSBzZW50aW5lbCBhdCByYXcgc3lzY2FsbHMgKF9faHdqc19saWJjX3N5c2NhbGxfcGFya19hYmkgJHtIZT8iPTEiOiJhYnNlbnQifSksIHNvIGV4ZWN2ZSBjYW5ub3QgYmUgdG9sZCB0byByZXRyeSBhbmQgdGhlIGhvc3QgZHJvdmUgdGhlIGxvYWQgSU4gUExBQ0UgXHUyMDE0IHRoaXMgV29ya2VyJ3MgZXZlbnQgbG9vcCwgYW5kIGV2ZXJ5IGNvLXJlc2lkZW50IHRhc2sgd2l0aCBpdCwgd2FzIGZyb3plbiBmb3IgdGhlIGR1cmF0aW9uLiBMb3VkLCBhdHRyaWJ1dGVkLCBhbmQgZXhwZWN0ZWQgdW50aWwgdGhpcyBsaWJjIG5vbWluYXRlcyB0aGUgdmVuZWVyLmB9KX1jYXRjaHt9fXIoYWMsImFubm91bmNlRXhlY0xvYWRJbmxpbmUiKTtsZXQgcGU9ISFnbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU182N19UUkFDRT97cmluZzpbXSxpblN5c05yOi0xLGluU3lzVDowLHN0YXR1c2VzOk9iamVjdC5jcmVhdGUobnVsbCksbGFzdFN0YXR1czotMSxsYXN0U3RhdHVzVDowLGluV2FzbTohMSxsYXN0RHJpdmVFbnRlclQ6MCxsYXN0RHJpdmVSZXRUOjAsY29vcFdhaXRzOjAscmVzY2hlZFJlc3RhcnRzOjAsZnV0ZXg6bnVsbCxmdXRleFdhaXRzOjAscmVhc29uQWRkcjowLHJlc3VsdEFkZHI6MCx0aW1lcjpudWxsfTpudWxsLGljPXIoKG4sYSk9PntwZS5yaW5nLnB1c2goKChufDApPDwwKSsiOiIrKGF8MCkpLHBlLnJpbmcubGVuZ3RoPjQ4JiZwZS5yaW5nLnNoaWZ0KCkscGUuaW5TeXNOcj0tMX0sInQ2N1JlY29yZFN5cyIpLGxjPXIobj0+e2lmKCFwZSlyZXR1cm47bGV0IGE9RGF0ZS5ub3coKSxpPU9iamVjdC5lbnRyaWVzKHBlLnN0YXR1c2VzKS5tYXAoKFt1LHBdKT0+YCR7dX09JHtwfWApLmpvaW4oIiwiKTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgdDY3IHBpZD0ke3NbTS5QSURdfDB9ICR7bn0gaW5XYXNtPSR7cGUuaW5XYXNtPzE6MH0gbGFzdFN0YXR1cz0weCR7KHBlLmxhc3RTdGF0dXM+Pj4wKS50b1N0cmluZygxNil9QC0ke2EtcGUubGFzdFN0YXR1c1R9bXMgZHJpdmVFbnRlckAtJHthLXBlLmxhc3REcml2ZUVudGVyVH1tcyBkcml2ZVJldEAtJHthLXBlLmxhc3REcml2ZVJldFR9bXMgc3RhdHVzZXN7JHtpfX0gY29vcFdhaXRzPSR7cGUuY29vcFdhaXRzfSByZXNjaGVkUmVzdGFydHM9JHtwZS5yZXNjaGVkUmVzdGFydHN9IGluU3lzPSR7cGUuaW5TeXNOcn1ALSR7cGUuaW5TeXNOcj49MD9hLXBlLmluU3lzVDowfW1zIGZ1dGV4V2FpdHM9JHtwZS5mdXRleFdhaXRzfSBpbkZ1dGV4PSR7cGUuZnV0ZXg/SlNPTi5zdHJpbmdpZnkocGUuZnV0ZXgpOjB9IHJlYXNvbj0ke3BlLnJlYXNvbkFkZHI/c2UoKVtwZS5yZWFzb25BZGRyPj4yXT4+PjA6LTF9IHJlc3VsdD0ke3BlLnJlc3VsdEFkZHI/c2UoKVtwZS5yZXN1bHRBZGRyPj4yXXwwOi0xfSBzeXNSaW5nPVske3BlLnJpbmcuc2xpY2UoLTI0KS5qb2luKCIgIil9XWB9KX1jYXRjaHt9fSwidDY3U2FtcGxlIiksWnQ9bmV3IFNldCxhaT0hMSxpaT1vZih7YWxsb2M6cihuPT5wcyg5LDAsbi5sZW4sbi5wcm90LDM0LC0xLDApLCJhbGxvYyIpLGZyZWU6cigobixhKT0+e3BzKDExLG4sYSwwLDAsMCwwKX0sImZyZWUiKSxyZWFkOnIoKG4sYSxpKT0+cHMoMTcsbi5tZmQsYStpfDAsbi5sZW4taXwwLG4ub2ZmK2l8MCwwLDApLCJyZWFkIiksZ3Vlc3RSZXN1bWVzOnIoKCk9PnJzJiZhZSg5KSwiZ3Vlc3RSZXN1bWVzIiksY2FuV2FpdDpyKCgpPT4hYWUoOSksImNhbldhaXQiKSx3YWl0OnIoKCk9PntqYygpLF90KCl9LCJ3YWl0IiksZXBvY2g6cigoKT0+KHFuWzNdfDApKyhxblszM118MCkrKHFuWzI5Ml18MCkrKHFuWzQzNl18MCksImVwb2NoIikscmVzdGFydENhcDpOYX0pLGdvPSEhZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkQxX1RSQUNFX0ZELHR0PSEhZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkQxX1RSQUNFX1NZUyxkYz1yKChuLGEsaSk9PntpZighdHQpcmV0dXJuIiI7bGV0IHU9bmV3IFNldChbMjU3LDI2MiwyNjcsMjY5LDQzOSwzMjIsMzMyLDI4MF0pLHA9bmV3IFNldChbNCw2LDIxLDg5LDc5LDU5LDgwLDIsODcsMTYxXSksaz0tMTtpZih1LmhhcyhuKT9rPWk+Pj4wOnAuaGFzKG4pJiYoaz1hPj4+MCksazw9MClyZXR1cm4iIjt0cnl7bGV0IEU9bmV3IFVpbnQ4QXJyYXkoZS5tZW1vcnkuYnVmZmVyKSwkPWs7Zm9yKDskPEUubGVuZ3RoJiYkPGsrMjU2JiZFWyRdIT09MDspJCsrO3JldHVybiBFcyhFLnN1YmFycmF5KGssJCkpfWNhdGNoe3JldHVybiIifX0sImQxU3lzUGF0aCIpO3tsZXQgbj1BcnJheS5pc0FycmF5KGUuZmRBY3Rpb25zKT9lLmZkQWN0aW9uczpudWxsO2lmKG4pZm9yKGxldCBhPTA7YTxuLmxlbmd0aDthKyspe2xldCBpPW5bYV07aWYoKGlbMF18MCk9PT0wKXtsZXQgdT1pWzJdfDA7dT49MCYmdTw9MiYmWnQuYWRkKHUpfX1pZihBcnJheS5pc0FycmF5KGUubG93RmRSb3V0ZXMpKWZvcihsZXQgYSBvZiBlLmxvd0ZkUm91dGVzKXtsZXQgaT1hfDA7aT49MCYmaTw9MiYmWnQuYWRkKGkpfX1sZXQgeW89MjAyLGxpPTAsY2M9MSxBcj05LGRpPTEwLHVjPTEyOCxjaT0yNTYsZmM9fih1Y3xjaSkmMjU1LGJvPTEwNzM3NDE4MjQsc249bnVsbCxrbz0wLHhvPSEhZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfUkVEX0ZVVEVYX1RJTUVEX0xFRyxfYz0tNCx1aT0tMTEsZmk9LTExMCxfcz0tMjIsanM9LTM4LF9pPW51bGwsaGk9bnVsbCxtaT1udWxsLHBpPW51bGwsRW89cigoKT0+e2xldCBuPWUubWVtb3J5LmJ1ZmZlcjtuIT09X2kmJihfaT1uLGhpPW5ldyBJbnQzMkFycmF5KG4pLG1pPW5ldyBVaW50MzJBcnJheShuKSxwaT1uZXcgVWludDhBcnJheShuKSl9LCJyZWZyZXNoVXNlclZpZXdzIiksQWU9cigoKT0+KEVvKCksaGkpLCJ1STMyIiksc2U9cigoKT0+KEVvKCksbWkpLCJ1VTMyIiksU289cigoKT0+KEVvKCkscGkpLCJ1VTgiKSx5bj1lLmtlcm5lbE1lbW9yeVdhc20/P251bGwsSXI9eW4/eW4uYnVmZmVyOm51bGwsd2k9SXI/bmV3IEludDMyQXJyYXkoSXIpOm51bGwsUnI9cigoKT0+e2lmKHluPT09bnVsbClyZXR1cm4gbnVsbDtsZXQgbj15bi5idWZmZXI7cmV0dXJuIG4hPT1JciYmKElyPW4sd2k9bmV3IEludDMyQXJyYXkobikpLHdpfSwia2VybmVsSTMyTGl2ZSIpLHJuPXR5cGVvZiBlLnNpZ25hbFBlbmRpbmdPZmZzZXQ9PSJudW1iZXIiJiYoZS5zaWduYWxQZW5kaW5nT2Zmc2V0JjMpPT09MD9lLnNpZ25hbFBlbmRpbmdPZmZzZXQ+Pj4yOi0xO2Z1bmN0aW9uIEdzKCl7cmV0dXJuIGFmKEFlKCkscm4pfXIoR3MsInNpZ25hbFBlbmRpbmciKTtmdW5jdGlvbiBLcygpe2lmKHJuPDApcmV0dXJuITE7bGV0IG49QXRvbWljcy5sb2FkKEFlKCkscm4pfDAsYT1BdG9taWNzLmxvYWQoQWUoKSxybisxKXwwO2lmKG49PT0wJiZhPT09MClyZXR1cm4hMTtsZXQgaT1BdG9taWNzLmxvYWQoQWUoKSxybis0KXwwLHU9QXRvbWljcy5sb2FkKEFlKCkscm4rNSl8MDtyZXR1cm4obiZ+aXxhJn51KSE9PTB9cihLcywiZGVsaXZlcmFibGVTaWduYWxQZW5kaW5nIik7bGV0IExuPTAsJG89MCx2bz01ZTM7ZnVuY3Rpb24gZ2kobil7aWYobj4+PjA9PT0kbz9MbisrOigkbz1uPj4+MCxMbj0xKSxMbj09PXZvfHxMbiUodm8qNDApPT09MCl7bGV0IGE9cm4+PTA/QXRvbWljcy5sb2FkKEFlKCkscm4pPj4+MDowLGk9cm4+PTA/QXRvbWljcy5sb2FkKEFlKCkscm4rMSk+Pj4wOjAsdT1ybj49MD9BdG9taWNzLmxvYWQoQWUoKSxybis0KT4+PjA6MCxwPXJuPj0wP0F0b21pY3MubG9hZChBZSgpLHJuKzUpPj4+MDowLGs9YGh3anMtZnV0ZXggRUlOVFItU1RPUk0gcGlkPSR7c1tNLlBJRF18MH0gdGlkPSR7ZS50aWR9OiAke0xufSBjb25zZWN1dGl2ZSBGVVRFWF9XQUlUIC1FSU5UUnMgYXQgdWFkZHI9MHgkeyhuPj4+MCkudG9TdHJpbmcoMTYpfSBcdTIwMTQgYSBwZW5kaW5nIHNpZ25hbCAocGVuZGluZz0weCR7aS50b1N0cmluZygxNil9OiR7YS50b1N0cmluZygxNil9IG1hc2s9MHgke3AudG9TdHJpbmcoMTYpfToke3UudG9TdHJpbmcoMTYpfSkgaXMgbm90IGJlaW5nIGRpc3BhdGNoZWQvY2xlYXJlZCBieSB0aGUgZ3Vlc3QgYmV0d2VlbiB3YWl0czogc2lnbmFsLWRlbGl2ZXJ5IGxpdmVsb2NrICh0aGUgY2FsbGVyIGxvb3BzIG9uIEVJTlRSIHdpdGhvdXQgY3Jvc3NpbmcgYSBkaXNwYXRjaCBwb2ludCkuIExvdWQgd2l0bmVzcywgbm90IGEgYmVoYXZpb3IgY2hhbmdlLmA7dHJ5e3Qoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTprfSl9Y2F0Y2h7fXRyeXtjb25zb2xlLmVycm9yKGBbaHdqcy1mdXRleCBwaWQ9JHtzW00uUElEXXwwfV0gJHtrfWApfWNhdGNoe319cmV0dXJuIF9jfXIoZ2ksImZ1dGV4RWludHIiKTtsZXQgaHM9ITEsaGM9ISFnbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU19SRURfU0lHQ0hMRF9BUk1fV05PSEFORyxtYz0hIWdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX1JFRF9TSUdDSExEX1JFR0lPTl9XUklURSx5aT1mZih7Z2V0STMyOnIoKCk9PkFlKCksImdldEkzMiIpLGdldElkeDpyKCgpPT5ybiwiZ2V0SWR4IiksaW5FeGVjV2luZG93OnIoKCk9PldkKCksImluRXhlY1dpbmRvdyIpLGFza0tlcm5lbDpyKCgpPT57bGV0IG49RiYmRi5leHBvcnRzO2lmKCFufHx0eXBlb2Ygbi5fX3dhc20zMl9rZXJuZWxfc2lnbmFsX3BlbmRpbmdfcmVwdWJsaXNoIT0iZnVuY3Rpb24iKXJldHVybi0xO3RyeXtyZXR1cm4gbi5fX3dhc20zMl9rZXJuZWxfc2lnbmFsX3BlbmRpbmdfcmVwdWJsaXNoKCl8MH1jYXRjaHtyZXR1cm4tMX19LCJhc2tLZXJuZWwiKSxyZWQ6e2hvc3RXcml0ZXNCaXQ6bWN9fSk7ZnVuY3Rpb24gYmkoKXtyZXR1cm4geWkucGVuZGluZ05vdygpfXIoYmksInNpZ2NobGRQZW5kaW5nTm93Iik7ZnVuY3Rpb24gVHIoKXt5aS5tYXliZVJlYXNzZXJ0KGhzKX1yKFRyLCJtYXliZVJlYXNzZXJ0U2lnY2hsZE9uV2FrZSIpO2Z1bmN0aW9uIHBjKG4pe2xldCBhPW4+Pj4yLGk9c2UoKVthXT4+PjAsdT1zZSgpW2ErMV18MCxwPXNlKClbYSsyXT4+PjAsaz1CaWdJbnQodSkqNDI5NDk2NzI5Nm4rQmlnSW50KGkpO3JldHVybiBrPDBufHxwPj0xZTk/bnVsbDprKjEwMDAwMDAwMDBuK0JpZ0ludChwKX1yKHBjLCJyZWFkR3Vlc3RUaW1lc3BlYzY0TnMiKTtmdW5jdGlvbiB3YyhuLGEpe2lmKEYmJnR5cGVvZiBGLmV4cG9ydHMud2FzbV9zeXNjYWxsPT0iZnVuY3Rpb24iJiZuZSE9PTApe2xldCBpPWE+Pj4yLHU9c2UoKVtpXSxwPXNlKClbaSsxXSxrPXNlKClbaSsyXSxFPXNlKClbaSszXTt0cnl7bGV0ICQ9cigoKT0+Ri5leHBvcnRzLndhc21fc3lzY2FsbCgyMjgsbnwwLGF8MCwwLDAsMCwwKSwiY2FsbCIpO2lmKCgoTmU/TmUuZGlzcGF0Y2hTeXNjYWxsKDIyOCwkKTokKCkpfDApPT09MCl7bGV0IGI9c2UoKVtpXT4+PjAsUD1zZSgpW2krMV18MCxIPXNlKClbaSsyXT4+PjA7cmV0dXJuKEJpZ0ludChQKSo0Mjk0OTY3Mjk2bitCaWdJbnQoYikpKjEwMDAwMDAwMDBuK0JpZ0ludChIKX19Y2F0Y2h7fWZpbmFsbHl7c2UoKVtpXT11LHNlKClbaSsxXT1wLHNlKClbaSsyXT1rLHNlKClbaSszXT1FfX1yZXR1cm4gbj09PTA/dHlwZW9mIHBlcmZvcm1hbmNlPCJ1IiYmcGVyZm9ybWFuY2Uubm93JiZ0eXBlb2YgcGVyZm9ybWFuY2UudGltZU9yaWdpbj09Im51bWJlciI/QmlnSW50KE1hdGgucm91bmQoKHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4rcGVyZm9ybWFuY2Uubm93KCkpKjFlNikpOkJpZ0ludChEYXRlLm5vdygpKSoxMDAwMDAwbjpudWxsfXIod2MsImd1ZXN0Q2xvY2tOb3dOcyIpO2Z1bmN0aW9uIGdjKG4sYSxpLHUscCxrKXtsZXQgRT1hJmZjO2lmKHNuJiYhKChFPT09bGl8fEU9PT1BcikmJihhJmJvKSE9PTApJiYoc249bnVsbCksZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfREJHX0ZVVEVYKXRyeXtsZXQgdj11Pj4+MCxiPSJudWxsIjtpZih2KXtsZXQgVz1zZSgpW3Y+Pj4yXSxfZT1zZSgpWyh2Pj4+MikrMV0samU9c2UoKVsodj4+PjIpKzJdLHdlPXNlKClbKHY+Pj4yKSszXTtiPWBbJHtXfSwke19lfSwke2plfSwke3dlfV1gfWxldCBQPXJuLEg9UD49MD8oQXRvbWljcy5sb2FkKEFlKCksUCk+Pj4wKS50b1N0cmluZygxNik6Im4vYSIsZj1QPj0wPyhBdG9taWNzLmxvYWQoQWUoKSxQKzQpPj4+MCkudG9TdHJpbmcoMTYpOiJuL2EiO2NvbnNvbGUuZXJyb3IoYFtGVVRFWC1EQkcgcGlkPSR7c1tNLlBJRF18MH1dIHJhd19vcD0weCR7KGE+Pj4wKS50b1N0cmluZygxNil9IG9wPSR7RX0gdWFkZHI9MHgkeyhuPj4+MCkudG9TdHJpbmcoMTYpfSB2YWw9JHtpfDB9IHRwPTB4JHsodT4+PjApLnRvU3RyaW5nKDE2KX0gdHMzMndvcmRzPSR7Yn0gc2lnUmVnaW9uT2ZmPTB4JHtQPj0wPyhQPDwyKS50b1N0cmluZygxNik6Ii0ifSBsbz0weCR7SH0gbWxvPTB4JHtmfSBkZWxpdmVyYWJsZT0ke0tzKCk/MTowfWApfWNhdGNoe31pZigobiYzKSE9PTApcmV0dXJuIF9zO2xldCAkPW4+Pj4yO2lmKEU9PT1saXx8RT09PUFyJiYheG8pe2lmKEU9PT1BciYmKGt8MCk9PT0wKXJldHVybiBfcztpZihLcygpKXtsZXQgZj1uPj4+MD09PSRvP0xuOjA7aWYobyYmcSYmKGEmYm8pIT09MCYmZj49dm8pe2lmKCFlaSl7ZWk9ITA7bGV0IFc9YGh3anMtY29vcHdhaXQgRUlOVFItU1RPUk0gUEFSSyBwaWQ9JHtzW00uUElEXXwwfSB0aWQ9JHtlLnRpZHwwfSBsYW5lPSR7ZS51c2VyTGFuZT8/MH06ICR7Zn0gY29uc2VjdXRpdmUgRlVURVhfV0FJVCAtRUlOVFJzIGF0IHVhZGRyPTB4JHsobj4+PjApLnRvU3RyaW5nKDE2KX0gcHJvdmVkIHRoaXMgY2FsbGVyIGRpc2NhcmRzIEVJTlRSLiBBcyBhIFBPT0wgUkVTSURFTlQgdGhhdCBsb29wIHJ1bnMgZW50aXJlbHkgaW5zaWRlIHRoZSB3YXNtIGRyaXZlIGFuZCBGUkVFWkVTIHRoZSBzaGFyZWQgQ1BVIFdvcmtlciBcdTIwMTQgZXZlcnkgY28tcmVzaWRlbnQgdGFzayBhbmQgaXRzIG9ubWVzc2FnZS4gQ29udmVydGluZyB0byB0aGUgY29vcGVyYXRpdmUgcGFyayBzbyB0aGUgcHVtcCBjYW4geWllbGQuIFRoZSB1bmRlcmx5aW5nIGRlZmVjdCBpcyB1cHN0cmVhbTogYSBkZWxpdmVyYWJsZSBzaWduYWwgaXMgcGVuZGluZyBhbmQgdGhlIGd1ZXN0IG5ldmVyIGNyb3NzZXMgYSBkaXNwYXRjaCBwb2ludCAobG91ZCwgYXR0cmlidXRlZCkuYDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpXfSl9Y2F0Y2h7fXRyeXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOnNbTS5QSURdfDAsbWVzc2FnZTpXfSl9Y2F0Y2h7fX1yZXR1cm4gSm4rKyxzbj1udWxsLGZ0fXJldHVybiBzbj1udWxsLGdpKG4pfWxldCB2PTEvMDtpZih1IT09MCl7aWYoKHUmMykhPT0wKXJldHVybiBfcztpZih4byl7bGV0IGY9c2UoKVt1Pj4+Ml0sVz1zZSgpWyh1Pj4+MikrMV07aWYodj1mKjFlMytXLzFlNix2PDApcmV0dXJuIF9zfWVsc2V7bGV0IGY9cGModT4+PjApO2lmKGY9PT1udWxsKXJldHVybiBfcztpZihFPT09QXIpe2xldCBXPWEmY2k/MDoxLF9lPXdjKFcsdT4+PjApO2lmKF9lPT09bnVsbCl7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YHdhc20zMjogRlVURVhfV0FJVF9CSVRTRVQgcGlkPSR7c1tNLlBJRF18MH0gY2xvY2tpZD0ke1d9IFx1MjAxNCBndWVzdCBjbG9jayB1bnJlYWNoYWJsZSAobm8gaW4tV29ya2VyIHZtbGludXgpOyByZWZ1c2luZyB0aGUgYWJzb2x1dGUtZGVhZGxpbmUgd2FpdCB3aXRoIEVOT1NZUyByYXRoZXIgdGhhbiB3YWl0aW5nIGFnYWluc3QgdGhlIHdyb25nIGNsb2NrYH0pfWNhdGNoe31yZXR1cm4ganN9bGV0IGplPWYtX2U7dj1qZTw9MG4/MDpNYXRoLmNlaWwoTnVtYmVyKGplKS8xZTYpKzF9ZWxzZSB2PU1hdGguY2VpbChOdW1iZXIoZikvMWU2KSsxfX1pZigoYSZibykhPT0wJiZxKXtsZXQgZj1BdG9taWNzLmxvYWQoQWUoKSwkKXwwLFc9c24mJnNuLnVhZGRyPT09bj4+PjAmJnNuLnZhbD09PShpfDApP3NuOm51bGw7aWYoZiE9PShpfDApKXJldHVybiBzbj1udWxsLExuPTAsVz8wOnVpO2xldCBfZT1EYXRlLm5vdygpLGplPVc/Vy5kZWFkbGluZU1zOnY9PT0xLzA/MS8wOl9lK3Y7aWYoX2U+PWplKXJldHVybiBzbj1udWxsLExuPTAsZmk7aWYoc249e3VhZGRyOm4+Pj4wLGkzMmlkeDokLHZhbDppfDAsZGVhZGxpbmVNczpqZX0scGUmJnBlLmZ1dGV4V2FpdHMrKywhdGkpe3RpPSEwO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLWNvb3B3YWl0IEFDVElWRSBwaWQ9JHtzW00uUElEXXwwfSB0aWQ9JHtlLnRpZHwwfSBsYW5lPSR7ZS51c2VyTGFuZT8/MH0gbW9kZT0ke2UubW9kZX06IHRoaXMgZ3Vlc3QncyBsaWJjIHNldHMgSFdKU19GVVRFWF9DT09QX1dBSVQgXHUyMDE0IGJsb2NraW5nIGZ1dGV4IHdhaXRzIHBhcmsgY29vcGVyYXRpdmVseSBhbmQgbmV2ZXIgZnJlZXplIGEgc2hhcmVkIENQVSBXb3JrZXJgfSl9Y2F0Y2h7fX1yZXR1cm4gZnR9aWYocGUmJihwZS5mdXRleFdhaXRzKysscGUuZnV0ZXg9e3VhZGRyOm4+Pj4wLHZhbDppfDAsbXM6dj09PTEvMD8tMTpNYXRoLnJvdW5kKHYpLHQ6RGF0ZS5ub3coKX0sdj09PTEvMCkpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YHQ2NyBwaWQ9JHtzW00uUElEXXwwfSBVU0VSLUZVVEVYLVdBSVQtSU5GIHVhZGRyPTB4JHsobj4+PjApLnRvU3RyaW5nKDE2KX0gdmFsPSR7aXwwfSBjdXI9JHtBdG9taWNzLmxvYWQoQWUoKSwkKXwwfWB9KX1jYXRjaHt9aWYobyYmdj09PTEvMCYmKEpuKyssKEpuJkpuLTEpPT09MCkpe2xldCBmPWBod2pzLWNvb3B3YWl0IFZJT0xBVElPTiBwaWQ9JHtzW00uUElEXXwwfSB0aWQ9JHtlLnRpZHwwfSBsYW5lPSR7ZS51c2VyTGFuZT8/MH0gbW9kZT0ke2UubW9kZX06IGEgUE9PTCBSRVNJREVOVCBlbnRlcmVkIGFuIFVOQk9VTkRFRCByYXcgRlVURVhfV0FJVCAodWFkZHI9MHgkeyhuPj4+MCkudG9TdHJpbmcoMTYpfSkgd2l0aG91dCBIV0pTX0ZVVEVYX0NPT1BfV0FJVC4gVGhpcyBmcmVlemVzIHRoZSBzaGFyZWQgQ1BVIFdvcmtlciBcdTIwMTQgZXZlcnkgY28tcmVzaWRlbnQgdGFzayBhbmQgdGhlIFdvcmtlcidzIG93biBtZXNzYWdlIGxvb3AgKGFkZC10YXNrIGNsYWltcywgdGhyZWFkLXBsYWNlbWVudCByZXF1ZXN0cykgc3RhbGwgZm9yIHRoZSBkdXJhdGlvbi4gVGhlIGxpYmMgbXVzdCBzZXQgdGhlIGNvb3BlcmF0aXZlIGJpdCBvbiBldmVyeSBpbmRlZmluaXRlbHktYmxvY2tpbmcgd2FpdCAoUExBTi1USFJFQUQtUE9PTC1SRVNJREVOQ1kgY29udHJhY3QgMykuIE9jY3VycmVuY2VzIHNvIGZhcjogJHtKbn0gKGxvdWQsIGF0dHJpYnV0ZWQsIG5ldmVyLXNpbGVudCkuYDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpmfSl9Y2F0Y2h7fXRyeXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOnNbTS5QSURdfDAsbWVzc2FnZTpmfSl9Y2F0Y2h7fX1sZXQgYj0yNTAsUD12LEg7Zm9yKDs7KXtsZXQgZj1NYXRoLm1pbihQLGIpO2lmKEg9QXRvbWljcy53YWl0KEFlKCksJCxpfDAsZiksSCE9PSJ0aW1lZC1vdXQifHxQIT09MS8wJiYoUC09ZixQPD0wKXx8S3MoKSlicmVhaztpZihBdG9taWNzLmxvYWQoQWUoKSwkKSE9PShpfDApKXtIPSJvayI7YnJlYWt9X3QoKSxkKCl9aWYocGUpe2lmKHBlLmZ1dGV4JiZwZS5mdXRleC5tcz09PS0xKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmB0NjcgcGlkPSR7c1tNLlBJRF18MH0gVVNFUi1GVVRFWC1XQUlULUlORiBXT0tFIHI9JHtIfWB9KX1jYXRjaHt9cGUuZnV0ZXg9bnVsbH1yZXR1cm4gS3MoKT9naShuKTooTG49MCxIPT09Im9rIj8wOkg9PT0ibm90LWVxdWFsIj91aTpIPT09InRpbWVkLW91dCI/Zmk6X3MpfWlmKEU9PT1jY3x8RT09PWRpJiYheG8pe2lmKEU9PT1kaSYmKGt8MCk9PT0wKXJldHVybiBfcztsZXQgdj1pPDA/MjE0NzQ4MzY0NzppfDA7cmV0dXJuIEF0b21pY3Mubm90aWZ5KEFlKCksJCx2KXwwfXJldHVybiBqc31yKGdjLCJoYW5kbGVGdXRleCIpO2xldCBNbj10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52Py5IQVJEV0FSRUpTX0RFQlVHX0s3X1U0Rix5Yz0wLGpyPW51bGwsQW89LTE7aWYoTW4pdHJ5e2pyPWF3YWl0IGltcG9ydCgibm9kZTpmcyIpO2xldCBuPXByb2Nlc3MuZW52Py5IQVJEV0FSRUpTX0RFQlVHX0xPRz8/Ii90bXAvazctdTRmLXRyYWNlLmxvZyI7QW89anIub3BlblN5bmMobiwiYSIpfWNhdGNoe31mdW5jdGlvbiBKcyhuKXtpZihqciYmQW8+PTApdHJ5e2pyLndyaXRlU3luYyhBbyxuKX1jYXRjaHt9fXIoSnMsIndyaXRlRGVidWciKTtsZXQgenM9dHlwZW9mIHBlcmZvcm1hbmNlPCJ1IiYmdHlwZW9mIHBlcmZvcm1hbmNlLm5vdz09ImZ1bmN0aW9uIj8oKT0+cGVyZm9ybWFuY2Uubm93KCk6KCk9PkRhdGUubm93KCksSW89MCxSbz0hMSxZcz0wLFZzPTAsYmM9MjtmdW5jdGlvbiBraShuKXtpZihuPjApdHJ5e0YmJnR5cGVvZiBGLmV4cG9ydHMud2FzbTMyX2FjY291bnRfdXNlcl9ucz09ImZ1bmN0aW9uIiYmRi5leHBvcnRzLndhc20zMl9hY2NvdW50X3VzZXJfbnMoQmlnSW50KE1hdGgucm91bmQobioxZTYpKSl9Y2F0Y2h7fX1yKGtpLCJhY2N0UmVwb3J0VXNlciIpO2Z1bmN0aW9uIFRvKCl7cmV0dXJuIFlzPTAsVnM9MCxJbz16cygpLFJvPSEwLElvfXIoVG8sImFjY3RCZWdpblNsaWNlIik7ZnVuY3Rpb24gam8obil7bGV0IGE9enMoKS1uLVlzLVZzO2lmKFJvPSExLHR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYmJnByb2Nlc3MuZW52LkhXSlNfQUNDVF9EQkcpdHJ5e2NvbnNvbGUuZXJyb3IoYFthY2N0LWRiZyBwaWQ9JHtlLnBpZH1dIHNsaWNlIHdhbGw9JHsoenMoKS1uKS50b0ZpeGVkKDMpfW1zIHN5cz0ke1lzLnRvRml4ZWQoMyl9bXMgc2V0dGxlZD0ke1ZzLnRvRml4ZWQoMyl9bXMgdXNlci10YWlsPSR7YS50b0ZpeGVkKDMpfW1zIGV4cG9ydD0keyEhKEYmJkYuZXhwb3J0cy53YXNtMzJfYWNjb3VudF91c2VyX25zKX1gKX1jYXRjaHt9a2koYSl9cihqbywiYWNjdEVuZFNsaWNlIik7bGV0IERvPTAseGk9MCxFaT0wLFNpPTAsJGk9MCx2aT0wLEFpPTAsSWk9cigoKT0+Ri5leHBvcnRzLndhc21fc3lzY2FsbChEbyx4aSxFaSxTaSwkaSx2aSxBaSksImtlcm5lbENhbGwiKTtmdW5jdGlvbiBSaShuLGEsaSx1LHAsayxFKXtyZXR1cm4gRG89bnwwLHhpPWF8MCxFaT1pfDAsU2k9dXwwLCRpPXB8MCx2aT1rfDAsQWk9RXwwLE5lP05lLmRpc3BhdGNoU3lzY2FsbChEbyxJaSk6SWkoKX1yKFJpLCJrZXJuZWxEaXNwYXRjaCIpO2xldCBObz0hMTtmdW5jdGlvbiBYcyhuLGEsaSx1LHAsayxFKXtMbyYmTmkoYHN5cy1lbnRyeSBucj0ke259YCk7bGV0ICQ9enMoKTtpZihSbyl7bGV0IHY9JC1Jby1Zcy1Wczt2Pj1iYyYmKGtpKHYpLFZzKz12KX10cnl7cGUmJihwZS5pblN5c05yPW58MCxwZS5pblN5c1Q9RGF0ZS5ub3coKSk7bGV0IHY9cHMobixhLGksdSxwLGssRSk7cmV0dXJuIHBlJiZpYyhuLHYpLG49PT01NiYmKHZ8MCkhPT1mdCYmKE5vPSExKSwodnwwKSE9PWZ0JiYodnwwKSE9PXBkJiZrbysrLHZ9ZmluYWxseXtZcys9enMoKS0kLExvJiZOaShgc3lzLWV4aXQgbnI9JHtufWApfX1yKFhzLCJzeXNjYWxsIik7bGV0IExvPXR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnY/LkhXSlNfSEVBUF9BVURJVD9wYXJzZUludChwcm9jZXNzLmVudi5IV0pTX0hFQVBfQVVESVQsMTYpPj4+MDowLE1vPSExLHFzPSJuZXZlciIsVGk9ITEsamk9ITEsa2M9WzEsMiwzLDQsNSw2LDcsOCw5LDEwLDEyLDE1LDE4LDIwLDI1LDMxLDM2LDQyLDUwLDYzLDcyLDg0LDEwMiwxMjcsMTQ2LDE3MCwyMDQsMjU1LDI5MiwzNDAsNDA5LDUxMSw1ODQsNjgyLDgxOCwxMDIzLDExNjksMTM2NCwxNjM3LDIwNDcsMjM0MCwyNzMwLDMyNzYsNDA5NSw0NjgwLDU0NjAsNjU1Miw4MTkxXSxEaT10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52Py5IV0pTX0hFQVBfQVVESVRfTEVOP3BhcnNlSW50KHByb2Nlc3MuZW52LkhXSlNfSEVBUF9BVURJVF9MRU4sMTApPj4+MDowLHhjPXR5cGVvZiBwcm9jZXNzPCJ1IiYmISFwcm9jZXNzLmVudj8uSFdKU19IRUFQX0FVRElUX01FVEEsT289WzFlOSwxZTksMmUzLDFlMyw1MDAsMjVlNywxZTMsMTAsNWU0LDMyNzY2LDFlM10sbXM9MCxXbz0hMSxDbz0wO2Z1bmN0aW9uIE5pKG4pe2lmKE1vfHxEaSYmKCFPdHx8T3QubGVuZ3RoIT09RGkpKXJldHVybjtsZXQgYT1TbygpLGk9bmV3IERhdGFWaWV3KGEuYnVmZmVyKSx1PUxvO2lmKCFUaSl7VGk9ITA7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo1LHRleHQ6YEhFQVAtQVVESVQgQVJNRUQgcGlkPSR7ZS5waWR9IGxhbmU9JHtlLnVzZXJMYW5lPz8wfSBjdHg9MHgke3UudG9TdHJpbmcoMTYpfSBpbml0X2RvbmVAKzEyPSR7aS5nZXRVaW50MzIodSsxMiwhMCl9IHBhZ2VzaXplQCs4PSR7aS5nZXRVaW50MzIodSs4LCEwKX1gfSl9Y2F0Y2h7fX1sZXQgcD1hLmxlbmd0aCxrPXIoRT0+e01vPSEwO2xldCAkPWBIRUFQLUFVRElUIHBpZD0ke2UucGlkfSBsYW5lPSR7ZS51c2VyTGFuZT8/MH0gRklSU1QgVklPTEFUSU9OIGF0IFske259XSAobGFzdCBnb29kOiBbJHtxc31dKTogJHtFfWA7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6JH0pfWNhdGNoe310cnl7dCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOiR9KX1jYXRjaHt9bGV0IHY9dHlwZW9mIHByb2Nlc3M8InUiP3Byb2Nlc3MuZW52Py5IV0pTX1RSQVBfRFVNUDp2b2lkIDA7aWYodil0cnl7aW1wb3J0KCJub2RlOmZzIikudGhlbihiPT57bGV0IFA9bmV3IFVpbnQ4QXJyYXkoYS5sZW5ndGgpO1Auc2V0KG5ldyBVaW50OEFycmF5KGUubWVtb3J5LmJ1ZmZlcikpO2xldCBIPWBhdWRpdGR1bXAtbGFuZSR7ZS51c2VyTGFuZT8/MH0tJHtEYXRlLm5vdygpfWA7Yi53cml0ZUZpbGVTeW5jKGAke3Z9LyR7SH0uYmluYCxQKSxiLndyaXRlRmlsZVN5bmMoYCR7dn0vJHtIfS50eHRgLCQrYApgKX0pLmNhdGNoKCgpPT57fSl9Y2F0Y2h7fX0sImZhaWwiKTt0cnl7aWYoaS5nZXRVaW50MzIodSs4LCEwKT09PTApe3FzPW47cmV0dXJufWlmKCFqaSl7amk9ITA7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo1LHRleHQ6YEhFQVAtQVVESVQgR0FURS1PUEVOIHBpZD0ke3M/c1tNLlBJRF18MDoiPyJ9IGxhbmU9JHtlLnVzZXJMYW5lPz8wfSBjdHg9MHgke3UudG9TdHJpbmcoMTYpfSBpbml0X2RvbmU9JHtpLmdldFVpbnQzMih1KzgsITApfSBzZWNyZXQ9MHgke2kuZ2V0VWludDMyKHUrNCwhMCkudG9TdHJpbmcoMTYpfSR7aS5nZXRVaW50MzIodSwhMCkudG9TdHJpbmcoMTYpfSBhcmVhX2hlYWQ9MHgkeyhpLmdldFVpbnQzMih1KzM2LCEwKT4+PjApLnRvU3RyaW5nKDE2KX0gXHUyMDE0IHdhbGtlciBMSVZFYH0pfWNhdGNoe319bGV0IEU9aS5nZXRVaW50MzIodSwhMCksJD1pLmdldFVpbnQzMih1KzQsITApLHY9aS5nZXRVaW50MzIodSszNiwhMCk+Pj4wLGI9MCxQPVtdO2Zvcig7diE9PTAmJmI8NjQ7KXtpZih2KzE2PnApcmV0dXJuIGsoYG1ldGFfYXJlYSAweCR7di50b1N0cmluZygxNil9IG91dCBvZiByYW5nZWApO2lmKGkuZ2V0VWludDMyKHYsITApIT09RXx8aS5nZXRVaW50MzIodis0LCEwKSE9PSQpcmV0dXJuIGsoYG1ldGFfYXJlYSAweCR7di50b1N0cmluZygxNil9IGNoZWNrICE9IHNlY3JldCAoMHgke2kuZ2V0VWludDMyKHYrNCwhMCkudG9TdHJpbmcoMTYpfSR7aS5nZXRVaW50MzIodiwhMCkudG9TdHJpbmcoMTYpfSlgKTtsZXQgSD1pLmdldFVpbnQzMih2KzEyLCEwKTtpZihIPT09MHx8SD40MDk2KXJldHVybiBrKGBtZXRhX2FyZWEgMHgke3YudG9TdHJpbmcoMTYpfSBuc2xvdHM9JHtIfWApO1AucHVzaChbdisxNix2KzE2KzI0KkhdKSx2PWkuZ2V0VWludDMyKHYrOCwhMCk+Pj4wLGIrK31mb3IobGV0IEg9MDtIPDQ4O0grKyl7bGV0IGY9aS5nZXRVaW50MzIodSs0OCs0KkgsITApPj4+MDtpZihmPT09MCljb250aW51ZTtpZighUC5zb21lKChbU3QsZ3RdKT0+Zj49U3QmJmYrMjQ8PWd0KSlyZXR1cm4gayhgYWN0aXZlWyR7SH1dIG1ldGEgMHgke2YudG9TdHJpbmcoMTYpfSBub3QgaW5zaWRlIGFueSBtZXRhIGFyZWFgKTtsZXQgVz1pLmdldFVpbnQzMihmKzIwLCEwKSxfZT1XPj4+NiY2MztpZihfZSE9PUgpcmV0dXJuIGsoYGFjdGl2ZVske0h9XSBtZXRhIDB4JHtmLnRvU3RyaW5nKDE2KX0gaGFzIHNpemVjbGFzcyAke19lfWApO2xldCBqZT1pLmdldFVpbnQzMihmKzgsITApPj4+MDtpZihqZT09PTB8fGplKzE2PnApcmV0dXJuIGsoYGFjdGl2ZVske0h9XSBncm91cCBtZW0gMHgke2plLnRvU3RyaW5nKDE2KX0gYmFkYCk7aWYoaS5nZXRVaW50MzIoamUsITApPj4+MCE9PWYpcmV0dXJuIGsoYGFjdGl2ZVske0h9XSBncm91cCAweCR7amUudG9TdHJpbmcoMTYpfSBiYWNrcHRyIDB4JHtpLmdldFVpbnQzMihqZSwhMCkudG9TdHJpbmcoMTYpfSAhPSBtZXRhIDB4JHtmLnRvU3RyaW5nKDE2KX1gKTtsZXQgd2U9aS5nZXRVaW50MzIoZisxMiwhMCk+Pj4wLFllPWkuZ2V0VWludDMyKGYrMTYsITApPj4+MDtpZigod2UmWWUpIT09MClyZXR1cm4gayhgYWN0aXZlWyR7SH1dIGF2YWlsIDB4JHt3ZS50b1N0cmluZygxNil9IFx1MjIyOSBmcmVlZCAweCR7WWUudG9TdHJpbmcoMTYpfSAhPSAwIChtZXRhIDB4JHtmLnRvU3RyaW5nKDE2KX0pYCk7aWYoSDw9MTAmJiF4Yyl7bGV0IFN0PWtjW0hdKjE2LGd0PVcmMzEsZm49amUrMTY7Zm9yKGxldCBtdD0wO210PD1ndDttdCsrKWlmKHdlPj4+bXQmMSl7bGV0IG50PWZuK1N0Km10O2lmKG50LTQ+PTAmJm50PD1wJiZhW250LTRdIT09MClyZXR1cm4gayhgYWN0aXZlWyR7SH1dIEFWQUlMIHNsb3QgJHttdH0gcD0weCR7bnQudG9TdHJpbmcoMTYpfSBpbi1iYW5kIHBbLTRdPTB4JHthW250LTRdLnRvU3RyaW5nKDE2KX0gIT0gMCAoZ3JvdXAgMHgke2plLnRvU3RyaW5nKDE2KX0gbWV0YSAweCR7Zi50b1N0cmluZygxNil9IGF2YWlsPTB4JHt3ZS50b1N0cmluZygxNil9IGZyZWVkPTB4JHtZZS50b1N0cmluZygxNil9OyBieXRlcyAke0FycmF5LmZyb20oYS5zdWJhcnJheShNYXRoLm1heCgwLG50LTE2KSxudCsxNikpLm1hcChHdD0+R3QudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKSkuam9pbigiICIpfSlgKX19fWlmKCFXbyl7aWYobXM9PT0wKXtpZihDbysrLENvPjMwNzIpe1dvPSEwLHFzPW47cmV0dXJufWlmKChDbyYxMjcpIT09MSl7cXM9bjtyZXR1cm59bGV0IEg9TWF0aC5taW4ocC00NCw2NzEwODg2NCk7Zm9yKGxldCBmPTQxOTQzMDQ7Zjw9SDtmKz0xNilpZihpLmdldFVpbnQzMihmLCEwKT09PTFlOSYmaS5nZXRVaW50MzIoZis0LCEwKT09PTFlOSYmaS5nZXRVaW50MzIoZis4LCEwKT09PTJlMyYmaS5nZXRVaW50MzIoZisxMiwhMCk9PT0xZTMmJmkuZ2V0VWludDMyKGYrMTYsITApPT09NTAwJiZpLmdldFVpbnQzMihmKzIwLCEwKT09PTI1ZTcpe21zPWY7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo1LHRleHQ6YEhFQVAtQVVESVQgQUxJTUlUIHBpbm5lZCBAMHgke2YudG9TdHJpbmcoMTYpfSBsYW5lPSR7ZS51c2VyTGFuZT8/MH0gWyR7bn1dIFx1MjAxNCB3YXRjaGluZyB0aGUgc3FsaXRlMyBjb25uZWN0aW9uIGFMaW1pdCBzaWduYXR1cmUgZm9yIHdpbGQgd3JpdGVzYH0pfWNhdGNoe31icmVha319ZWxzZSBmb3IobGV0IEg9MDtIPE9vLmxlbmd0aDtIKyspaWYoaS5nZXRVaW50MzIobXMrNCpILCEwKT4+PjAhPT1Pb1tIXT4+PjApcmV0dXJuIFdvPSEwLGsoYHNxbGl0ZTMgY29ubmVjdGlvbiBhTGltaXRbJHtIfV0gQDB4JHsobXMrNCpIKS50b1N0cmluZygxNil9ID0gMHgke2kuZ2V0VWludDMyKG1zKzQqSCwhMCkudG9TdHJpbmcoMTYpfSAoZXhwZWN0ZWQgMHgkeyhPb1tIXT4+PjApLnRvU3RyaW5nKDE2KX0pIFx1MjAxNCBXSUxEIFdSSVRFIGludG8gdGhlIHNxbGl0ZTMgY29ubmVjdGlvbiBzdHJ1Y3QgKHRoZSB3aGVyZUxvb3AgVDIgdmljdGltKTsgYnl0ZXNAYUxpbWl0LTY0ICR7QXJyYXkuZnJvbShhLnN1YmFycmF5KG1zLTY0LG1zKzgpKS5tYXAoZj0+Zi50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIgIil9YCl9cXM9bn1jYXRjaChFKXtNbz0hMDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgSEVBUC1BVURJVCBwaWQ9JHtlLnBpZH0gbGFuZT0ke2UudXNlckxhbmU/PzB9IHdhbGtlciB0aHJldyBhdCBbJHtufV06ICR7RSBpbnN0YW5jZW9mIEVycm9yP0UubWVzc2FnZTpTdHJpbmcoRSl9YH0pfWNhdGNoe319fXIoTmksImhlYXBBdWRpdCIpO2xldCBMaT10eXBlb2YgcHJvY2VzczwidSImJiEhcHJvY2Vzcy5lbnY/LkhXSlNfU1RBTExfVFJBQ0UsT249T2JqZWN0LmZyZWV6ZSh0eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52P3suLi5wcm9jZXNzLmVudn06e30pLE1pPS0xLFpzPTAsT2k9MCxXaT0wLENpPXIobj0+YFNUQUxMLVRSQUNFIHBpZD0ke3M/c1tNLlBJRF18MDplLnBpZD8/Ij8ifSBsYW5lPSR7ZS51c2VyTGFuZT8/MH0gJHtufTsgc3lzY2FsbHM9JHtPaX0gbGFzdCBucj0ke01pfSBhZ2U9JHtacz8oKERhdGUubm93KCktWnMpLzFlMykudG9GaXhlZCgxKToiPyJ9c2AsInN0YWxsTGluZSIpO2lmKExpJiZ0eXBlb2Ygc2V0SW50ZXJ2YWw9PSJmdW5jdGlvbiIpe2xldCBuPXNldEludGVydmFsKCgpPT57dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo1LHRleHQ6Q2koImxvb3AtYWxpdmUiKX0pfWNhdGNoe319LDJlNCk7dHlwZW9mIG49PSJvYmplY3QiJiZuJiZ0eXBlb2Ygbi51bnJlZj09ImZ1bmN0aW9uIiYmbi51bnJlZigpfWxldCBQbz1udWxsLEJvPW51bGwsUGk9MDtmdW5jdGlvbiBFYyhuLGEpe0JvIT09T3QmJihQbz1UbChPdCxQaSksQm89T3QpO2xldCBpPWosdT1yKGI9PmImJmIuZHlsaW5rP2IuZHlsaW5rLm1lbW9yeVNpemU+Pj4wOjAsInNpemVPZiIpLHA9W107UHQmJkNlJiZwLnB1c2goe21lbW9yeUJhc2U6Q2UubWVtb3J5QmFzZSxtZW1vcnlTaXplOnUoUHQpfSksZWUmJk1lJiZwLnB1c2goe21lbW9yeUJhc2U6TWUubWVtb3J5QmFzZSxtZW1vcnlTaXplOnUoZWUpfSk7Zm9yKGxldCBiIG9mIEJ0KWImJmIuaGFuZGxlJiZwLnB1c2goe21lbW9yeUJhc2U6Yi5oYW5kbGUubWVtb3J5QmFzZSxtZW1vcnlTaXplOnUoYi5oYW5kbGUpfSk7Zm9yKGxldCBiIG9mIGp0LnZhbHVlcygpKWImJiFiLm1haW5TY29wZSYmYi5oYW5kbGUmJnAucHVzaCh7bWVtb3J5QmFzZTpiLm1lbW9yeUJhc2UsbWVtb3J5U2l6ZTp1KGIuaGFuZGxlKX0pO2xldCBrPVtdLEU9RGwoUG8sZS5tb2RlPT09InRocmVhZCI/ZS5zdGFja1BvaW50ZXJPZmZzZXQ+Pj4wOjApO2lmKEUmJmkmJnR5cGVvZiBpLl9fd2FzbTMyX2dldF9zdGFja19wb2ludGVyPT0iZnVuY3Rpb24iJiZrLnB1c2goe3NwOmkuX193YXNtMzJfZ2V0X3N0YWNrX3BvaW50ZXIoKT4+PjAsLi4uRX0pLENlJiZkbil7bGV0IGI9Q2Uuc3BUb3A+Pj4wO2sucHVzaCh7c3A6ZG4udmFsdWU+Pj4wLGhpOmIsbGltaXQ6Yi1Rbz4+PjB9KX1sZXQgJD1bXTtpZihpJiZ0eXBlb2YgaS5fX2h3anNfYXJlbmFfc2VnX2NvdW50PT0iZnVuY3Rpb24iKXtsZXQgYj1aZT4+PjAsUD1NYXRoLm1pbihpLl9faHdqc19hcmVuYV9zZWdfY291bnQoYik+Pj4wLDEwMjQpO2ZvcihsZXQgSD0wO0g8UDtIKyspJC5wdXNoKFtpLl9faHdqc19hcmVuYV9zZWdfYmFzZShiLEgpPj4+MCxpLl9faHdqc19hcmVuYV9zZWdfZW5kKGIsSCk+Pj4wXSl9bGV0IHY9Tmwoe21haW46UG8sbW9kdWxlczpwLHN0YWNrczprLGFyZW5hOiR9KTtyZXR1cm4gTGwoZS5tZW1vcnkuYnVmZmVyLG4sYSx2KX1yKEVjLCJzZXJ2aWNlUm9vdE1hcCIpO2Z1bmN0aW9uIHBzKG4sYSxpLHUscCxrLEUpe2lmKExpJiYoTWk9bnwwLFpzPURhdGUubm93KCksT2krKyxacy1XaT4xNWUzKSl7V2k9WnM7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo1LHRleHQ6Q2koImluLXN5c2NhbGwiKX0pfWNhdGNoe319aWYoZCgpLHRlPSEwLHNuIT09bnVsbCYmKG58MCkhPT15byYmKHNuPW51bGwpLExuIT09MCYmKG58MCkhPT15byYmKExuPTApLE1uKXtsZXQgVD0rK3ljO0pzKGBbSzctVTRmIHdvcmtlciBwaWQ9JHtlLnBpZH0gdGlkPSR7ZS50aWR9IHNlcT0ke1R9XSBucj0ke259IGFyZ3M9WzB4JHsoYT4+PjApLnRvU3RyaW5nKDE2KX0sMHgkeyhpPj4+MCkudG9TdHJpbmcoMTYpfSwweCR7KHU+Pj4wKS50b1N0cmluZygxNil9LDB4JHsocD4+PjApLnRvU3RyaW5nKDE2KX0sMHgkeyhrPj4+MCkudG9TdHJpbmcoMTYpfSwweCR7KEU+Pj4wKS50b1N0cmluZygxNil9XQpgKX1pZih0dCl7bGV0IFQ9ZGMobixhLGkpO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBFTlRFUiBucj0ke258MH1gKyhUP2AgcGF0aD0iJHtUfSJgOiIiKStgIGEwPTB4JHsoYT4+PjApLnRvU3RyaW5nKDE2KX0gYTE9MHgkeyhpPj4+MCkudG9TdHJpbmcoMTYpfSBhMj0weCR7KHU+Pj4wKS50b1N0cmluZygxNil9YH0pfWNhdGNoe319aWYobj09PTU2JiZhPj4+MCYyNTYmJnEmJiEoaGUmJiEhaiYmdHlwZW9mIGouX19od2pzX2xhbmVfYXR0YWNoPT0iZnVuY3Rpb24iJiZ0eXBlb2Ygai5fX2h3anNfbGFuZV9jYXA9PSJmdW5jdGlvbiImJihqLl9faHdqc19sYW5lX2NhcCgpfDApPjEpJiZnbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU19FWFBFUklNRU5UQUxfVEhSRUFEX0NMT05FIT09IjEiKXt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgd2FzbTMyOiBSRUZVU0lORyB0aHJlYWQtbW9kZSBjbG9uZSAoQ0xPTkVfVk0sIHBpZD0ke3NbTS5QSURdfDB9LCBmbGFncz0weCR7KGE+Pj4wKS50b1N0cmluZygxNil9KSB3aXRoIEVBR0FJTiBcdTIwMTQgdGhlIGNvcm8gc3Vic3RyYXRlJ3MgcnVudGltZSBwcm90b2NvbCBzdGF0ZSBpcyBzaW5nbGUtbGFuZSBwZXIgcHJvY2VzczsgYSBzZWNvbmQgV29ya2VyIGxhbmUgb3ZlciB0aGUgc2FtZSB1c2VyX21lbW9yeSBpcyBhIHN0cnVjdHVyYWwgcHJvdG9jb2wgdmlvbGF0aW9uLCBub3QgYSBzY2hlZHVsYWJsZSB0aHJlYWQuIHB0aHJlYWRfY3JlYXRlKCkgZ2V0cyBFQUdBSU4gKGNhdGNoYWJsZSBzdGQ6OnN5c3RlbV9lcnJvcikuIE9wdC1pbjogSFdKU19FWFBFUklNRU5UQUxfVEhSRUFEX0NMT05FPTEuYH0pfWNhdGNoe31yZXR1cm4tMTF9aWYobj09PTU2JiZhPj4+MCYyNTYpdHJ5e05vfHwoTm89ITAsdCh7a2luZDoidGhyZWFkLXBsYWNlbWVudCIscGlkOnNbTS5QSURdfDAsc2VxOjAsdW5zb2xpY2l0ZWQ6ITAsY2xvbmU6e2ZsYWdzOmE+Pj4wLHB0aWQ6dT4+PjAsY3RpZDprPj4+MH0sY2FsbGVyWWllbGRzRHVyaW5nQ2xvbmU6JGUodnUpLGxvd0ZkUm91dGVzOlsuLi5adF0sZGxvcGVuRm9yazp4cigpfSkpfWNhdGNoe31pZihuPT09cmUpe2lmKHEpcmV0dXJuIG90PSEwLDA7bGV0IFQ9ajtpZighVHx8dHlwZW9mIFQuYXN5bmNpZnlfZ2V0X3N0YXRlIT0iZnVuY3Rpb24ifHx0eXBlb2YgVC5hc3luY2lmeV9zdGFydF91bndpbmQhPSJmdW5jdGlvbiJ8fHR5cGVvZiBULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyIT0iZnVuY3Rpb24iKXJldHVybiBqcztpZigoVC5hc3luY2lmeV9nZXRfc3RhdGUoKXwwKT09PUZlKXJldHVybiBULmFzeW5jaWZ5X3N0b3BfcmV3aW5kKCksc298MDtsZXQgbWU9VC5fX3dhc20zMl9hc3luY2lmeV9idWZfYWRkcigpPj4+MCxEZT1ULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9zaXplKCl8MCx2dD1tZT4+PjI7cmV0dXJuIHNlKClbdnRdPW1lKzg+Pj4wLHNlKClbdnQrMV09bWUrRGU+Pj4wLG5vPSEwLFQuYXN5bmNpZnlfc3RhcnRfdW53aW5kKG1lKSwwfWlmKG49PT1YKXtpZihxKXtsZXQgRG49dXMucGhhc2UucGhhc2UhPT0iaWRsZSImJnVzLnBoYXNlLnBhdGhQdHI9PT1hPj4+MHx8dW4ucGhhc2U9PT0ic3RhZ2VkIiYmdW4ucGF0aFB0cj09PWE+Pj4wO2lmKHN0PSEwLCFEbil7b3M9YT4+PjA7bGV0IHV0PW5ldyBVaW50OEFycmF5KGUubWVtb3J5LmJ1ZmZlciksSG49YT4+PjA7Zm9yKDtIbjx1dC5sZW5ndGgmJnV0W0huXSE9PTA7KUhuKys7aWYobm49RXModXQuc3ViYXJyYXkoYT4+PjAsSG4pKSxUbj1rcihpPj4+MCwiZXhlY3ZlIGFyZ3YiKSx5cj1rcih1Pj4+MCwiZXhlY3ZlIGVudnAiKSx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRVhFQ1ZFLUxBVENIIHBhdGg9IiR7bm59IiBhcmd2PVske1RuLm1hcChscz0+SlNPTi5zdHJpbmdpZnkobHMpKS5qb2luKCIsIil9XSAoJHt5ci5sZW5ndGh9IGVudilgfSl9Y2F0Y2h7fX17bGV0IHV0PUpkKGE+Pj4wLEhlKTtpZih1dC53b3VsZEJsb2NrKXJldHVybiBvaSgiZXhlY3ZlIGludGVyY2VwdCIsbm4pLGl0JiZDdCh0LGBZSUVMRCBjcHU9JHtlLmNwdUlkPz8iPyJ9IHRpZD0ke2UudGlkfSByZWFzb249RVhFQy1MT0FELXBhcmsgc2l0ZT1leGVjdmUtaW50ZXJjZXB0IHZpYT1ndWVzdC1yZXN0YXJ0YCksZnQ7aWYodXQudW5hdmFpbGFibGUpcmV0dXJuIDA7aWYoIUhlJiZ1cy5ibG9ja3NMYXN0KCk+MCYmYWMobm4sdXMuYmxvY2tzTGFzdCgpKSwhdXQub2spe2lmKEJzPXR5cGVvZiB1dC5lcnJubz09Im51bWJlciImJnV0LmVycm5vPDA/dXQuZXJybm98MDotMix0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRVhFQ1ZFLUlOTElORSBGQUlMIHBhdGg9IiR7bm59IiBlcnJubz0ke0JzfWB9KX1jYXRjaHt9cmV0dXJuIEJzfDB9aWYob289dXQud2FzbUJ5dGVzLHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBFWEVDVkUtSU5MSU5FIE9LIHBhdGg9IiR7bm59IiAke3V0Lndhc21CeXRlcy5sZW5ndGh9QiBcdTIwMTQgdW53aW5kaW5nIHRvIHJlLWluc3RhbnRpYXRlYH0pfWNhdGNoe310aHJvdyBzdD0hMSx2YX19bGV0IFQ9ajtpZighVHx8dHlwZW9mIFQuYXN5bmNpZnlfZ2V0X3N0YXRlIT0iZnVuY3Rpb24ifHx0eXBlb2YgVC5hc3luY2lmeV9zdGFydF91bndpbmQhPSJmdW5jdGlvbiJ8fHR5cGVvZiBULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyIT0iZnVuY3Rpb24iKXJldHVybiBqcztpZigoVC5hc3luY2lmeV9nZXRfc3RhdGUoKXwwKT09PUZlKXJldHVybiBULmFzeW5jaWZ5X3N0b3BfcmV3aW5kKCksQnN8MDtvcz1hPj4+MDtsZXQgbWU9bmV3IFVpbnQ4QXJyYXkoZS5tZW1vcnkuYnVmZmVyKSxEZT1hPj4+MCx2dD1tZS5sZW5ndGg7Zm9yKDtEZTx2dCYmbWVbRGVdIT09MDspRGUrKztubj1FcyhtZS5zdWJhcnJheShhPj4+MCxEZSkpLFRuPWtyKGk+Pj4wLCJleGVjdmUgYXJndiIpLHlyPWtyKHU+Pj4wLCJleGVjdmUgZW52cCIpO2xldCBsbj1ULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyKCk+Pj4wLExlPVQuX193YXNtMzJfYXN5bmNpZnlfYnVmX3NpemUoKXwwLHh0PWxuPj4+MjtyZXR1cm4gc2UoKVt4dF09bG4rOD4+PjAsc2UoKVt4dCsxXT1sbitMZT4+PjAscm89ITAsVC5hc3luY2lmeV9zdGFydF91bndpbmQobG4pLDB9aWYobj09PU91KXtpZihxKXRocm93IG5ldyBFcnJvcigiSFdKUy0zOiBTWVNfV0FTTV9TRVRKTVAgZnJvbSBhIGNvcm8tc3Vic3RyYXRlIGltYWdlIFx1MjAxNCBzamxqIGlzIGxvd2VyZWQgaW4tbW9kdWxlOyB0aGlzIHN5c2NhbGwgaXMgcmV0aXJlZC4gQSBzdGFsZSBBc3luY2lmeS1lcmEgc2V0am1wIG92ZXJyaWRlIGlzIGxpbmtlZCBpbnRvIHRoZSBiaW5hcnkuIik7bGV0IFQ9ajtpZighVHx8dHlwZW9mIFQuYXN5bmNpZnlfZ2V0X3N0YXRlIT0iZnVuY3Rpb24ifHx0eXBlb2YgVC5hc3luY2lmeV9zdGFydF91bndpbmQhPSJmdW5jdGlvbiJ8fHR5cGVvZiBULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyIT0iZnVuY3Rpb24iKXJldHVybiBqcztpZigoVC5hc3luY2lmeV9nZXRfc3RhdGUoKXwwKT09PUZlKXJldHVybiBULmFzeW5jaWZ5X3N0b3BfcmV3aW5kKCksY298MDtDYT1hPj4+MDtsZXQgbWU9VC5fX3dhc20zMl9hc3luY2lmeV9idWZfYWRkcigpPj4+MCxEZT1ULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9zaXplKCl8MCx2dD1tZT4+PjI7cmV0dXJuIHNlKClbdnRdPW1lKzg+Pj4wLHNlKClbdnQrMV09bWUrRGU+Pj4wLGlvPSEwLFQuYXN5bmNpZnlfc3RhcnRfdW53aW5kKG1lKSwwfWlmKG49PT1XdSl7aWYocSl0aHJvdyBuZXcgRXJyb3IoIkhXSlMtMzogU1lTX1dBU01fTE9OR0pNUCBmcm9tIGEgY29yby1zdWJzdHJhdGUgaW1hZ2UgXHUyMDE0IHNqbGogaXMgbG93ZXJlZCBpbi1tb2R1bGU7IHRoaXMgc3lzY2FsbCBpcyByZXRpcmVkLiBBIHN0YWxlIEFzeW5jaWZ5LWVyYSBzZXRqbXAgb3ZlcnJpZGUgaXMgbGlua2VkIGludG8gdGhlIGJpbmFyeS4iKTtsZXQgVD1qO2lmKCFUfHx0eXBlb2YgVC5hc3luY2lmeV9nZXRfc3RhdGUhPSJmdW5jdGlvbiJ8fHR5cGVvZiBULmFzeW5jaWZ5X3N0YXJ0X3Vud2luZCE9ImZ1bmN0aW9uInx8dHlwZW9mIFQuX193YXNtMzJfYXN5bmNpZnlfYnVmX2FkZHIhPSJmdW5jdGlvbiIpcmV0dXJuIGpzO1BhPWE+Pj4wLGNvPWl8MDtsZXQgVj1ULl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyKCk+Pj4wLG1lPVQuX193YXNtMzJfYXN5bmNpZnlfYnVmX3NpemUoKXwwLERlPVY+Pj4yO3JldHVybiBzZSgpW0RlXT1WKzg+Pj4wLHNlKClbRGUrMV09VittZT4+PjAsbG89ITAsVC5hc3luY2lmeV9zdGFydF91bndpbmQoViksMH1pZihuPT09eW8pcmV0dXJuIGdjKGF8MCxpfDAsdXwwLHB8MCxrfDAsRXwwKTtpZihuPT09QXUpe2lmKGFvPSEwLGJyPWE+Pj4wLFV0PSIiLHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBETE9QRU4tTEFUQ0ggcGF0aD0iJHthcyhhPj4+MCl9IiAoSFdKU19QQVJLX0RMT1BFTiBhcm1lZClgfSl9Y2F0Y2h7fXJldHVybiAwfWlmKG49PT1UdSl7bGV0IFQ9YT4+PjAsVj1pfDA7aWYoIVV0fHxUPT09MHx8Vjw9MSlyZXR1cm4gMDtsZXQgbWU9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFV0KSxEZT1NYXRoLm1pbihtZS5sZW5ndGgsVi0xKSx2dD1uZXcgVWludDhBcnJheShlLm1lbW9yeS5idWZmZXIpO3JldHVybiBUK0RlKzE+dnQubGVuZ3RoPzA6KHZ0LnNldChtZS5zdWJhcnJheSgwLERlKSxUKSx2dFtUK0RlXT0wLERlKX1pZihuPT09TnUpcmV0dXJuIEVjKGE+Pj4wLGl8MCk7aWYobj09PUl1KXtsZXQgVD1qdC5nZXQoYT4+PjApO2lmKCFUKXJldHVybiAwO2xldCBWPWFzKGk+Pj4wKSxtZT0wO3RyeXttZT1ULmhhbmRsZS5kbHN5bShWKXwwfWNhdGNoKERlKXtyZXR1cm4gdCh7a2luZDoiZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiJIV0pTLTUgZGxzeW0gdHJhcHBlZDogIisoRGUgaW5zdGFuY2VvZiBFcnJvcj9EZS5tZXNzYWdlOlN0cmluZyhEZSkpfSksMH1pZih0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRExTWU0gY29va2llPSR7YT4+PjB9IG5hbWU9IiR7Vn0iIC0+ICR7bWU+Pj4wfWB9KX1jYXRjaHt9cmV0dXJuIG1lfWlmKG49PT1SdSl7bGV0IFQ9YT4+PjAsVj1qdC5nZXQoVCk7aWYoIVYpcmV0dXJuLTIyO2lmKFYubWFpblNjb3BlKXJldHVybiBqdC5kZWxldGUoVCksMDtpZihWLmludGVybmFsKXJldHVybi0yMjtpZihWLmJvdW5kQnlEZXBlbmRlbnQpcmV0dXJuIFYuaW50ZXJuYWw9ITAsMDtsZXQgbWU9KGdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX0RMQ0xPU0VfTk9fQ0VOU1VTfHwiIik9PT0iMSIsRGU9Vi5jZW5zdXN8fHtsaXZlOjAscG9pc29uZWQ6ITF9LHZ0PWo/ai5fX2h3anNfcGFya2VkOnZvaWQgMCxsbj12dCBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbD92dC52YWx1ZT4+PjA6MCxMZT1sbj9zZSgpW2xuPj4yXT4+PjA6MCx4dD1qP2ouX19od2pzX3BhcmtlZF9vd25lcjp2b2lkIDAsRG49eHQgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWw/eHQudmFsdWU+Pj4wOjAsdXQ9RG4/c2UoKVtEbj4+Ml0+Pj4wOjAsSG49Vi50YWJsZUJhc2U+Pj4wLGxzPVYuaGFuZGxlJiZWLmhhbmRsZS5keWxpbms/Vi5oYW5kbGUuZHlsaW5rLnRhYmxlU2l6ZT4+PjA6MCx0cj1WLmhhbmRsZSYmdHlwZW9mIFYuaGFuZGxlLnRhYmxlSW5kaWNlcz09ImZ1bmN0aW9uIj9WLmhhbmRsZS50YWJsZUluZGljZXMoKTpbXSxkcz11dD49SG4mJnV0PEhuK2xzfHx0ci5pbmNsdWRlcyh1dCk7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo3LHRleHQ6YGh3anMtZGxjbG9zZS1jZW5zdXMgcGlkPSR7c1tNLlBJRF18MH0gY29va2llPSR7VH0gbW9kdWxlSWQ9JHtWLm1vZHVsZUlkfSBwYXRoPSIke1YucGF0aHx8IiJ9IiBsaXZlPSR7RGUubGl2ZX0gcG9pc29uZWQ9JHtEZS5wb2lzb25lZD8xOjB9IHBhcmtlZD0weCR7TGUudG9TdHJpbmcoMTYpfSBvd25lcj0weCR7dXQudG9TdHJpbmcoMTYpfSBub0NlbnN1cz0ke21lPzE6MH1gfSl9Y2F0Y2h7fWlmKCFtZSl7bGV0IG9uPW51bGw7aWYoRGUubGl2ZT4wP29uPWAke0RlLmxpdmV9IGxpdmUgY29yb3V0aW5lIGZyYW1lKHMpIGFsbG9jYXRlZCBieSB0aGUgbW9kdWxlIGFyZSBub3QgeWV0IGZyZWVkYDpEZS5wb2lzb25lZCYmKG9uPSJ0aGUgbW9kdWxlIGZyYW1lIGNlbnN1cyBpcyBQT0lTT05FRCAoYSBmcmFtZV9mcmVlIHVuZGVyZmxvdyB3YXMgb2JzZXJ2ZWQ7IHRoZSBjb3VudCBpcyB1bnRydXN0d29ydGh5KSIpLExlIT09MCYmKHQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpgSFdKUy01IE0yIGRsY2xvc2UgQU5PTUFMWTogX19od2pzX3BhcmtlZD0weCR7TGUudG9TdHJpbmcoMTYpfSAob3duZXI9MHgke3V0LnRvU3RyaW5nKDE2KX0pIG5vbi16ZXJvIGF0IGRsY2xvc2Ugc2VydmljZSBvZiBjb29raWU9JHtUfSAiJHtWLnBhdGh8fCIifSIgXHUyMDE0IGEgcGFyayBpcyBpbiBmbGlnaHQgd2hpbGUgZGxjbG9zZSBydW5zJHtkcz8iOyB0aGUgb3duZXIgd29yZCBmYWxscyBpbiB0aGUgY2xvc2luZyBtb2R1bGUncyB0YWJsZSBmb290cHJpbnQgXHUyMDE0IFJFRlVTSU5HIjoiIn0uYH0pLGRzJiYhb24mJihvbj1gYSBwYXJrZWQgY2hhaW4ncyBvd25lciB3b3JkIDB4JHt1dC50b1N0cmluZygxNil9IHRhcmdldHMgdGhlIGNsb3NpbmcgbW9kdWxlJ3MgdGFibGUgc2xvdHNgKSksb24pcmV0dXJuIHQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpgSFdKUy01IE0yIGRsY2xvc2UgUkVGVVNFRCAoRUJVU1kpOiBwYXRoPSIke1YucGF0aHx8IiJ9IiBjb29raWU9JHtUfSBtb2R1bGVJZD0ke1YubW9kdWxlSWR9IGxpdmU9JHtEZS5saXZlfSBcdTIwMTQgYCtvbisiLiBUaGUgaGFuZGxlIHN0YXlzIG9wZW47IHJldHJ5IGFmdGVyIHRoZSBtb2R1bGUncyBjb3JvdXRpbmVzIGNvbXBsZXRlIChuZXZlci1zaWxlbnQsIG5vbi10ZXJtaW5hbCkuIn0pLC0xNn1Lbi5wdXNoKHt0YWJsZUJhc2U6Vi50YWJsZUJhc2U+Pj4wLHRhYmxlU2l6ZTpscz4+PjAsYXBwZW5kZWQ6dHIuc2xpY2UoKSxwYXRoOlYucGF0aHx8IiIsbW9kdWxlSWQ6Vi5tb2R1bGVJZHwwfSk7e2xldCBvbj1WLnRhYmxlQmFzZT4+PjA7Zm9yKGxldCBuciBvZlsuLi5Tbi5rZXlzKCldKShucj49b24mJm5yPG9uKyhscz4+PjApfHx0ci5pbmNsdWRlcyhucikpJiZTbi5kZWxldGUobnIpfXRyeXtWLmhhbmRsZS51bmxvYWQoKX1jYXRjaHt9aWYoRiYmdHlwZW9mIEYuZXhwb3J0cy5fX2h3anNfZGVyZWdpc3Rlcl9tb2R1bGU9PSJmdW5jdGlvbiIpdHJ5e0YuZXhwb3J0cy5fX2h3anNfZGVyZWdpc3Rlcl9tb2R1bGUoVi5tb2R1bGVJZHwwKX1jYXRjaChvbil7dCh7a2luZDoiZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiJIV0pTLTUgX19od2pzX2RlcmVnaXN0ZXJfbW9kdWxlIHRyYXBwZWQ6ICIrKG9uIGluc3RhbmNlb2YgRXJyb3I/b24ubWVzc2FnZTpTdHJpbmcob24pKX0pfWlmKGp0LmRlbGV0ZShUKSx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gRExDTE9TRSBjb29raWU9JHtUfSBtb2R1bGVJZD0ke1YubW9kdWxlSWR9YH0pfWNhdGNoe31yZXR1cm4gMH1pZihuPT09TXUpe2lmKEYmJm5lIT09MCYmdHlwZW9mIEYuZXhwb3J0cy53YXNtMzJfc2lnY29uc3VtZT09ImZ1bmN0aW9uIil0cnl7bGV0IFQ9cigoKT0+Ri5leHBvcnRzLndhc20zMl9zaWdjb25zdW1lKGF8MCxpPj4+MCl8MCwiY2FsbCIpO3JldHVybihOZT9OZS5icmFja2V0KCJ3YXNtMzJfc2lnY29uc3VtZSIsVCk6VCgpKXwwfWNhdGNoKFQpe3JldHVybiB0KHtraW5kOiJlcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6IksxMi1XNDogdm1saW51eCB3YXNtMzJfc2lnY29uc3VtZSB0cmFwcGVkOiAiKyhUIGluc3RhbmNlb2YgRXJyb3I/VC5tZXNzYWdlOlN0cmluZyhUKSl9KSwwfXJldHVybiAwfWlmKG49PT0kdXx8bj09PWZhfHxuPT09S3Ipe0tkKCk7bGV0IFQ9bj09PUtyPzE6MCxWPVQ/YSYxMjc6YSYyNTUsbWU9bj09PWZhP3ooYSYyNTUsMCk6bj09PUtyP3ooYSYxMjcsMSk6bnVsbDtpZihtZSYmKChtZS53c3RhdHVzJjEyNyk9PT0wPyhWPW1lLndzdGF0dXM+PjgmMjU1LFQ9MCk6KFY9bWUud3N0YXR1cyYxMjcsVD0xKSksbT1WLG1lJiZtZS56YXBwZWQ+MD90KHtraW5kOiJkbWVzZyIsbGV2ZWw6NSx0ZXh0OmBod2pzLWdyb3VwZXhpdCBwaWQ9JHtlLnBpZH0gdGlkPSR7ZS50aWR8MH0gbW9kZT0ke2UubW9kZT8/ImZvcmsifTogYCsobj09PWZhP2BleGl0X2dyb3VwKCR7YSYyNTV9KWA6YGZhdGFsIHRlcm1pbnVzIGJ5IHNpZ25hbCAke2EmMTI3fWApK2AgXHUyMDE0IHRoZSBrZXJuZWwgY29uZGVtbmVkICR7bWUuemFwcGVkfSBvdGhlciB0aHJlYWQocykgb2YgdGhpcyBwcm9jZXNzIGFuZCBzZXQgdGhlIGdyb3VwJ3MgZXhpdCBjb2RlIHRvIDB4JHttZS53c3RhdHVzLnRvU3RyaW5nKDE2KX0gKCR7bWUud3N0YXR1cyYxMjc/YFdJRlNJR05BTEVEIFdURVJNU0lHPSR7bWUud3N0YXR1cyYxMjd9YDpgV0lGRVhJVEVEIFdFWElUU1RBVFVTPSR7bWUud3N0YXR1cz4+OCYyNTV9YH0pOyB0aGUgaG9zdCBub3cgdW53aW5kcyB0aGVpciBXb3JrZXJzICh0aGUga2VybmVsJ3MgZGVjaXNpb24sIHRoaXMgaG9zdCdzIG1lY2hhbmlzbSlgfSk6bj09PUtyJiYhbWUmJnQoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YGh3anMtZ3JvdXBleGl0IHBpZD0ke2UucGlkfSB0aWQ9JHtlLnRpZHwwfSBtb2RlPSR7ZS5tb2RlPz8iZm9yayJ9OiBmYXRhbCB0ZXJtaW51cyBieSBzaWduYWwgJHthJjEyN30gd2FzIE5PVCBkZWNpZGVkIGJ5IHRoZSBrZXJuZWwgXHUyMDE0IHRoaXMgcHJvY2VzcydzIG90aGVyIHRocmVhZHMgYXJlIG5vdCBjb25kZW1uZWQgYnkgaXQgYW5kIHRoZSBob3N0IHVud2luZHMgbm9uZSBvZiB0aGVtLiBPbiBMaW51eCBhIGZhdGFsIHNpZ25hbCBvbiBhbnkgdGhyZWFkIGVuZHMgdGhlIHdob2xlIHByb2Nlc3NgfSksYz17Y29kZUFyZzpWLHNpZ25hbGVkOlQsZ3JwRXhpdDptZX0sIV8mJlVlJiZVZSgiZXhpdC1zeXNjYWxsIiksbyl0aHJvdyBJZDtpZihjPW51bGwsRiYmbmUhPT0wKXRocm93IG5ldyBFcnJvcihgZXhpdCB0ZXJtaW51czogYSBsZWdhY3kgKG5vbi1wb29sKSBXb3JrZXIgcmVhY2hlZCBTWVNfZXhpdF9ncm91cCB3aXRoIGEgbGl2ZSB2bWxpbnV4IHRhc2sgKHB0YXNrPTB4JHsobmU+Pj4wKS50b1N0cmluZygxNil9KSBcdTIwMTQgdGhlIGNoaWxkLWV4aXQgY2xlYW51cCB5aWVsZHMgdGhlIGV2ZW50IGxvb3Agb24gYSB3b3VsZC1ibG9jayAoY29udHJhY3QgMywgc2l0ZSA0KSBhbmQgdGhpcyBhcm0gaGFzIG5vIGFzeW5jIGZyYW1lIHRvIHlpZWxkIGludG8uIFJlZnVzaW5nIHRvIGRyb3AgdGhlIGNsZWFudXAgKG5ldmVyLXNpbGVudCkuYCk7dyh7Y29kZUFyZzpWLHNpZ25hbGVkOlQsZ3JwRXhpdDptZX0pfWxldCAkPTEzLHY9NjIsYj02MSxQPTIwMCxIPTIzNCxmPTMsVz0zMixfZT0zMyxqZT0yMix3ZT0yOTIsWWU9MjkzLFN0PTEwOSxndD0xMTEsZm49MTEyLG10PTEyMSxudD0xMjQsR3Q9Mzksdm49MTEwLGFuPTIxOCxDbj0wLEE9MSxKPTgsQz0xOSxpZT0yMCxsZT0xNixaPTIsVmU9MjU3LEdlPTg1LFFlPTgwLGV0PTgxLEl0PTc5LFd0PTcyLFBlPTczLEt0PTQsVnQ9NSxibj02LHl0PTIxNyxfbj0yNjIsSnQ9MzMyLGR0PTIyOCxEdD0yMjksY3Q9MzUsUG49MjMwLFF0PTIxOSxHPTk2LEs9MjAxLGdlPTM2LEllPTM4LFJ0PW5kLFh0PTIwNCxCbj0zMDksYXQ9MTMxLEZuPTEwMixxdD0xMDQsdmU9MTA3LHllPTEwOCxSZT0yODAsRWU9MjYzLFdlPTIxLGNlPTI2OSxiZT00MzksYnQ9ODkscHQ9MjY3LFhlPTc0LHp0PTc1LE49MTYyLHVlPTMwNixZPTgyLFRlPTgzLHFlPTg0LEtlPTg3LGh0PTkwLHd0PTI1OCwkdD0yNjQsZXM9MjY4LGdzPTMxNixEcz00NTIsaG49MTY1LG1uPTE2NixEcj0xNTUsa3Q9MjcyLEJlPTcsam49MjMsVHQ9MjcwLE50PTI3MSxpcz00MSx6bj01NSxOcj0yODgsUXM9OSxlcj0xNyxMcj0xOCx5cz02Myx6aT03NixZaT03NyxWaT0zMTgsWGk9MTAzLHFpPTg2LFppPTg4LFFpPTkxLGVsPTkyLHRsPTkzLG5sPTk0LHNsPTEzMyxybD0yNTksb2w9MjYwLGFsPTI2NSxpbD0yNjYsTmM9MTI1LExjPTEyNixNYz0xODYsbGw9NDAsZGw9MTM3LGNsPTEzOCx1bD0zMjYsZmw9ISFPbi5IV0pTX1JFRF9NTUFQX0ZJTEVfVU5QT1BVTEFURUQ7aWYobj09PVFzJiYhZmwmJigocHwwKSYzMik9PT0wKXtsZXQgVD1wfDAsVj11fDAsbWU9a3wwLERlPWk+Pj4wLHZ0PUU+Pj4wLGxuPVQmMTUsTGU9cigoZHMsb24pPT57dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YGh3anMtbW1hcCBwaWQ9JHtzW00uUElEXXwwfSBmaWxlLWJhY2tlZCBtbWFwIFJFRlVTRUQgKCR7b259KTogZmQ9JHttZX0gbGVuPTB4JHtEZS50b1N0cmluZygxNil9IHByb3Q9MHgkeyhWPj4+MCkudG9TdHJpbmcoMTYpfSBmbGFncz0weCR7KFQ+Pj4wKS50b1N0cmluZygxNil9IG9mZj0weCR7dnQudG9TdHJpbmcoMTYpfSAtPiBlcnJubyAkey1kc30gKGxpbnV4LWluLXRoZS1icm93c2VyIzcyKWB9KX1jYXRjaHt9cmV0dXJuIGRzfDB9LCJyZWZ1c2UiKTtpZihtZT09PS0xKXJldHVybiBMZSgtOSwibm8gTUFQX0FOT05ZTU9VUyBhbmQgZmQgPT0gLTEiKTtpZihEZT09PTB8fCh2dCY0MDk1KSE9PTB8fGxuIT09MSYmbG4hPT0yJiZsbiE9PTMpcmV0dXJuLTIyO2lmKCEoRiYmbmUhPT0wJiZ0eXBlb2YgRi5leHBvcnRzLndhc21fc3lzY2FsbD09ImZ1bmN0aW9uIikpcmV0dXJuIExlKC0xOSwibm8gaW4tV29ya2VyIGtlcm5lbCBjb250ZXh0IHRvIHBvcHVsYXRlIGZyb20gdGhlIGZpbGUiKTtpZigoVCYxNikhPT0wKXJldHVybiBMZSgtMTksIk1BUF9GSVhFRCBmaWxlIG1hcHBpbmcgdW5zdXBwb3J0ZWQgKHRoZSBob3N0IGJ1bXAgYWxsb2NhdG9yIG93bnMgcGxhY2VtZW50KSIpO2lmKGxuIT09MiYmKFYmMikhPT0wKXJldHVybiBMZSgtMTksIndyaXRhYmxlIE1BUF9TSEFSRUQgKHdyaXRlLWJhY2spIHVuc3VwcG9ydGVkIFx1MjAxNCBmYWxsIGJhY2sgdG8gcmVhZCgpL3dyaXRlKCkiKTtsZXR7YWRkcjp4dCxkb25lOkRuLGVycjp1dCxwYXJrZWQ6SG4sbG9zdDpscyxyZXN0YXJ0czp0cn09aWkubWFwKHttZmQ6bWUsbGVuOkRlLHByb3Q6VixmbGFnczpULG9mZjp2dH0pO2lmKEhuKXJldHVybiBwZDtpZih4dDwwKXJldHVybiB4dDtpZih1dCE9PTApcmV0dXJuIWxzJiYhUmEodXQpJiZwcygxMSx4dCxEZSwwLDAsMCwwKSx1dD09PS0zOD9MZSgtMTksImtlcm5lbCBwcmVhZDY0IHVud2lyZWQgXHUyMDE0IHRoaXMgdm1saW51eCBwcmVkYXRlcyB0aGUgIzcyIGtlcm5lbCBoYWxmIik6dXQ9PT0tOT8ocHMoNzIsbWUsMywwLDAsMCwwKXwwKTwwPy05OkxlKC0xMywiZmQgbm90IG9wZW4gZm9yIHJlYWRpbmciKTp1dD09PS0yOXx8dXQ9PT0tMjF8fHV0PT09LTIyP0xlKC0xOSxgZmQgZG9lcyBub3Qgc3VwcG9ydCBwb3NpdGlvbmVkIHJlYWQgKHByZWFkIGVycm5vICR7LXV0fSlgKTpMZSh1dCwicHJlYWQ2NCBwb3B1bGF0aW9uIGZhaWxlZCIpO2lmKGxuIT09MiYmIWFpKXthaT0hMDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy1tbWFwIHBpZD0ke3NbTS5QSURdfDB9IE1BUF9TSEFSRUQgcmVhZC1vbmx5IGZpbGUgbWFwcGluZyBpcyBhbiBlYWdlciBzbmFwc2hvdCBvbiB3YXNtMzIgKG5vIGZhdWx0cyAtPiBubyBjb2hlcmVuY2Ugd2l0aCBsYXRlciBmaWxlIHdyaXRlczsgbGludXgtaW4tdGhlLWJyb3dzZXIjNzIpYH0pfWNhdGNoe319aWYodHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke3NbTS5QSURdfDB9IE1NQVAtRklMRSBmZD0ke21lfSBvZmY9MHgke3Z0LnRvU3RyaW5nKDE2KX0gbGVuPTB4JHtEZS50b1N0cmluZygxNil9IHBvcHVsYXRlZD0ke0RufUIgcmVzdGFydHM9JHt0cn0gLT4gMHgkeyh4dD4+PjApLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fXJldHVybiB4dHwwfWxldCB4ZT0hMTtpZihRbiE9PW51bGwmJm5lIT09MCYmRiYmdHlwZW9mIEYuZXhwb3J0cy53YXNtX3N5c2NhbGw9PSJmdW5jdGlvbiImJihufDApPj0wJiYobnwwKTxRbi5sZW5ndGgmJlFuW258MF09PT0xJiYhX2YuaGFzKG58MCkmJih4ZT0hMCksZS5mb3JjZVdhc21TeXNjYWxsJiZGJiZuZSE9PTAmJnR5cGVvZiBGLmV4cG9ydHMud2FzbV9zeXNjYWxsPT0iZnVuY3Rpb24iJiYoeGU9ITApLFFuIT09bnVsbCYmbj09PSQmJkYmJnR5cGVvZiBGLmV4cG9ydHMud2FzbV9zeXNjYWxsPT0iZnVuY3Rpb24iJiYoeGU9ITApLFFuPT09bnVsbCYmRiYmdHlwZW9mIEYuZXhwb3J0cy53YXNtX3N5c2NhbGw9PSJmdW5jdGlvbiIpe2lmKG49PT0kKXhlPSEwO2Vsc2UgaWYobj09PTU2JiZhPj4+MCYyNTYpbmUhPT0wJiZoZSYmaiYmdHlwZW9mIGouX19od2pzX2xhbmVfYXR0YWNoPT0iZnVuY3Rpb24iJiZnbG9iYWxUaGlzLnByb2Nlc3M/LmVudj8uSFdKU19FWFBFUklNRU5UQUxfVEhSRUFEX0NMT05FIT09IjEiJiYoeGU9ITApO2Vsc2UgaWYobj09PVB8fG49PT1IKXhlPSEwO2Vsc2UgaWYobj09PXYpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PWIpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PWplfHxuPT09WWV8fG49PT1XfHxuPT09X2V8fG49PT13ZXx8bj09PWYpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PVN0fHxuPT09bXR8fG49PT1mbnx8bj09PW50fHxuPT09Z3QpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PUd0KW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1JdCluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09YW4mJmUubW9kZT09PSJmb3JrLXJlc3VtZSIpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PWR0fHxuPT09RHR8fG49PT1HfHxuPT09SyluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09Y3R8fG49PT1QbiluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09UXQpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PUllfHxuPT09Z2UpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PVJ0fHxuPT09WHR8fG49PT1CbiluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09YXQpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PUt0fHxuPT09VnR8fG49PT1ibnx8bj09PV9ufHxuPT09SnR8fG49PT15dCluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09UWV8fG49PT1ldCluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09Wnx8bj09PVZlfHxuPT09R2UpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PWxlKW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1XdCl7bGV0IFQ9ISFPbi5IV0pTX1JFRF9GQ05UTF9GREdBVEU7bmUhPT0wJiYoIVR8fChhfDApPj0zfHxadC5oYXMoYXwwKSkmJih4ZT0hMCl9ZWxzZSBpZihuPT09UGUpe2xldCBUPSEhT24uSFdKU19SRURfRkxPQ0tfVU5ST1VURUQ7bmUhPT0wJiYhVCYmKHhlPSEwKX1lbHNlIGlmKG49PT1Dbnx8bj09PUMpbmUhPT0wJiYoKGF8MCk9PT0wfHwoYXwwKT49M3x8WnQuaGFzKGF8MCkpJiYoeGU9ITApO2Vsc2UgaWYobj09PUF8fG49PT1pZSluZSE9PTAmJigoYXwwKT49M3x8WnQuaGFzKGF8MCkpJiYoeGU9ITApO2Vsc2UgaWYobj09PUopbmUhPT0wJiYoKGF8MCk+PTN8fFp0LmhhcyhhfDApKSYmKHhlPSEwKTtlbHNlIGlmKG49PT12biluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09Rm58fG49PT1xdHx8bj09PXZlfHxuPT09eWUpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PUJlfHxuPT09am58fG49PT1UdHx8bj09PU50KW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1obnx8bj09PW1ufHxuPT09RHJ8fG49PT1rdCluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPj1pcyYmbjw9em58fG49PT1OciluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09UmV8fG49PT1FZSluZSE9PTAmJih4ZT0hMCk7ZWxzZSBpZihuPT09V2V8fG49PT1jZXx8bj09PWJlKW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1idHx8bj09PXB0KW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1UZXx8bj09PXd0fHxuPT09cWV8fG49PT1LZXx8bj09PVl8fG49PT0kdHx8bj09PWdzfHxuPT09aHR8fG49PT1lc3x8bj09PURzKW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1lcnx8bj09PUxyKW5lIT09MCYmIWZsJiYoeGU9ITApO2Vsc2UgaWYobj09PU58fG49PT1YZXx8bj09PXp0fHxuPT09dWUpbmUhPT0wJiYoeGU9ITApO2Vsc2UgaWYobj09PXlzfHxuPT09eml8fG49PT1ZaXx8bj09PVZpKXtsZXQgVD0hIU9uLkhXSlNfUkVEXzc4ODA4MV9VTlJPVVRFRDtuZSE9PTAmJiFUJiYoeGU9ITApfWVsc2UgaWYobj09PVhpKXtsZXQgVD0hIU9uLkhXSlNfUkVEXzg4X1NZU0xPR19VTlJPVVRFRDtuZSE9PTAmJiFUJiYoeGU9ITApfWVsc2UgaWYobj09PXFpfHxuPT09YWx8fG49PT1aaXx8bj09PWlsfHxuPT09c2x8fG49PT1ybHx8bj09PVFpfHxuPT09ZWx8fG49PT10bHx8bj09PW5sfHxuPT09b2wpe2xldCBUPSEhT24uSFdKU19SRURfNThfVkZTTVVUX1VOUk9VVEVEO25lIT09MCYmIVQmJih4ZT0hMCl9ZWxzZSBpZihuPT09TmN8fG49PT1MY3x8bj09PU1jKW5lIT09MCYmKHhlPSEwKTtlbHNlIGlmKG49PT1kbHx8bj09PWNsfHxuPT09bGx8fG49PT11bCl7bGV0IFQ9ISFPbi5IV0pTX1JFRF8xMDRfRlNHQVBfVU5ST1VURUQ7bmUhPT0wJiYhVCYmKHhlPSEwKX19aWYoeGUmJlFuIT09bnVsbCl7bGV0IFQ9T24sVj1hfDAsbWU9Vj49M3x8WnQuaGFzKFYpOyhuPT09Q258fG49PT1DKSYmIShWPT09MHx8bWUpJiYoeGU9ITEpLChuPT09QXx8bj09PWllfHxuPT09SikmJiFtZSYmKHhlPSExKSxuPT09NTYmJiEoYT4+PjAmMjU2JiZoZSYmaiYmdHlwZW9mIGouX19od2pzX2xhbmVfYXR0YWNoPT0iZnVuY3Rpb24iJiZULkhXSlNfRVhQRVJJTUVOVEFMX1RIUkVBRF9DTE9ORSE9PSIxIikmJih4ZT0hMSksbj09PWFuJiZlLm1vZGUhPT0iZm9yay1yZXN1bWUiJiYoeGU9ITEpLFQuSFdKU19SRURfRkNOVExfRkRHQVRFJiZuPT09V3QmJiFtZSYmKHhlPSExKSxULkhXSlNfUkVEX0ZMT0NLX1VOUk9VVEVEJiZuPT09UGUmJih4ZT0hMSksVC5IV0pTX1JFRF9NTUFQX0ZJTEVfVU5QT1BVTEFURUQmJihuPT09ZXJ8fG49PT1McikmJih4ZT0hMSksVC5IV0pTX1JFRF83ODgwODFfVU5ST1VURUQmJihuPT09eXN8fG49PT16aXx8bj09PVlpfHxuPT09VmkpJiYoeGU9ITEpLFQuSFdKU19SRURfODhfU1lTTE9HX1VOUk9VVEVEJiZuPT09WGkmJih4ZT0hMSksVC5IV0pTX1JFRF81OF9WRlNNVVRfVU5ST1VURUQmJihuPT09cWl8fG49PT1hbHx8bj09PVppfHxuPT09aWx8fG49PT1zbHx8bj09PXJsfHxuPT09UWl8fG49PT1lbHx8bj09PXRsfHxuPT09bmx8fG49PT1vbCkmJih4ZT0hMSksVC5IV0pTX1JFRF8xMDRfRlNHQVBfVU5ST1VURUQmJihuPT09ZGx8fG49PT1jbHx8bj09PWxsfHxuPT09dWwpJiYoeGU9ITEpfWlmKGdvJiYobj09PWplfHxuPT09WWV8fG49PT1fZXx8bj09PXdlfHxuPT09Znx8bj09PUF8fG49PT1Dbnx8bj09PWllfHxuPT09Q3x8bj09PUl0KSYmdCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1mZCBwaWQ9JHtzW00uUElEXXwwfSBtb2RlPSR7ZS5tb2RlfSBQUkUgbnI9JHtufDB9KGEwPSR7YXwwfSxhMT0ke2l8MH0sYTI9JHt1fDB9KSByb3V0ZT0ke3hlPyJLRVJORUwiOiJqcy1kaXJlY3QifSBwdGFzaz0weCR7KG5lPj4+MCkudG9TdHJpbmcoMTYpfSBsb3dmZHM9eyR7Wy4uLlp0XS5qb2luKCIsIil9fWB9KSx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgU1lTVFJBQ0UgcGlkPSR7c1tNLlBJRF18MH0gUFJFIG5yPSR7bnwwfSByb3V0ZT0ke3hlPyJLIjoianMifSBhMD0weCR7KGE+Pj4wKS50b1N0cmluZygxNil9IGExPTB4JHsoaT4+PjApLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fWlmKHhlKXtsZXQgVD0hMTtuPT09UHx8bj09PUg/VD0obj09PUg/aXwwOmF8MCk9PT0oZS50aWR8MCk6bj09PXYmJihUPShhfDApPT09KGUucGlkfDApKTt0cnl7aWYoIVl0JiZGJiZ0eXBlb2YgRi5leHBvcnRzLl9fd2FzbTMyX3NldF9saWJjX3BhcmtfYWJpPT0iZnVuY3Rpb24iKXRyeXtGLmV4cG9ydHMuX193YXNtMzJfc2V0X2xpYmNfcGFya19hYmkoSGU/MTowKSxZdD0hMH1jYXRjaHt9aWYoT24uQTRDX0ZPUktEQkcpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YFthNGMtc3lzIHRpZD0ke2UudGlkfV0gUFJFIG5yPSR7bnwwfWB9KX1jYXRjaHt9bGV0IFY9UmkobixhLGksdSxwLGssRSk7aWYocW5bbnwwXT0ocW5bbnwwXXwwKSsxLE9uLkE0Q19GT1JLREJHKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbYTRjLXN5cyB0aWQ9JHtlLnRpZH1dIG5yPSR7bnwwfSAtPiAke1Z8MH1gfSl9Y2F0Y2h7fWxldCBtZT1hZShuKTtpZigoVnwwKT09PWZ0JiYkZShuKSl7aWYoIXJpJiZIZSYmIXlhLmhhcyhufDApKXtyaT0hMDt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1jb29wd2FpdCBWRU5FRVItUEFSSyBwaWQ9JHtzW00uUElEXXwwfSB0aWQ9JHtlLnRpZHwwfSBsYW5lPSR7ZS51c2VyTGFuZT8/MH0gbW9kZT0ke2UubW9kZX06IHN5c2NhbGwgbnI9JHtufDB9IGJsb2NrLXBhcmtlZCBhbmQgdGhpcyBpbWFnZSBhYnNvcmJzIC01MTcgYXQgcmF3IHZlbmVlcnMgKF9faHdqc19saWJjX3N5c2NhbGxfcGFya19hYmk9MSkgXHUyMDE0IHRoZSBDUFUgV29ya2VyIHdhcyBoYW5kZWQgYmFjayBpbnN0ZWFkIG9mIHNwdW4gb24gc3luY2hyb25vdXNseWB9KX1jYXRjaHt9fXJldHVybiBmdH1pZigoVnwwKT09PWZ0KXtpZihtZSYmKFpuKyssKFpuJlpuLTEpPT09MCkpe2xldCBEbj1gaHdqcy1jb29wd2FpdCBTWU5DLVJFU1RBUlQgcGlkPSR7c1tNLlBJRF18MH0gdGlkPSR7ZS50aWR8MH0gbGFuZT0ke2UudXNlckxhbmU/PzB9IG1vZGU9JHtlLm1vZGV9OiBzeXNjYWxsIG5yPSR7bnwwfSBibG9jay1wYXJrZWQgKC01MTcpIGJ1dCB0aGlzIGltYWdlJ3MgbGliYyBkb2VzIG5vdCBhYnNvcmIgdGhlIHNlbnRpbmVsIGF0IHJhdyBzeXNjYWxscyAoX19od2pzX2xpYmNfc3lzY2FsbF9wYXJrX2FiaSAke0hlPyI9MSI6ImFic2VudCJ9LCBod2pzRHJpdmU9JHtxPzE6MH0pLCBzbyB0aGUgaG9zdCBtdXN0IHJlc3RhcnQgaXQgaW4gcGxhY2Ugb24gYSBTWU5DSFJPTk9VUyB3YWl0IFx1MjAxNCBmcmVlemluZyB0aGlzIENQVSBXb3JrZXIncyBldmVudCBsb29wLCBhbmQgd2l0aCBpdCBldmVyeSBjby1yZXNpZGVudCB0YXNrLCBmb3IgdGhlIGR1cmF0aW9uLiBPY2N1cnJlbmNlcyBzbyBmYXI6ICR7Wm59IChQTEFOLVRIUkVBRC1QT09MLVJFU0lERU5DWSBjb250cmFjdCAzOyBsb3VkLCBhdHRyaWJ1dGVkKS5gO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OkRufSl9Y2F0Y2h7fX1pZihuZT09PTB8fHluPT09bnVsbClyZXR1cm4gdCh7a2luZDoiZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOmBIV0pTLUEtNDogc3lzY2FsbCBucj0ke258MH0gcmV0dXJuZWQgLUVSRVNUQVJUX1JFU0NIRUQgYnV0IG5vIGtlcm5lbCB0YXNrX3N0cnVjdCBpcyByZWFjaGFibGUgKHBlclByb2Nlc3NUYXNrQWRkcj0weCR7KG5lPj4+MCkudG9TdHJpbmcoMTYpfSwga2VybmVsTWVtPSR7eW4/InByZXNlbnQiOiJhYnNlbnQifSkgXHUyMDE0IGNhbm5vdCB5aWVsZCBmb3IgdGhlIGluLWZsaWdodCBjb21wbGV0aW9uOyByZWZ1c2luZyB0byBzcGluLmB9KSwtMzg7bGV0IExlPTAseHQ9aXQ/aHIodCx7Y3B1OmUuY3B1SWQscGlkOnNbTS5QSURdfDAsdGlkOmUudGlkLHNpdGU6InN5bmMtcmVzdGFydCIsbGFiZWw6YHdhc21fc3lzY2FsbDoke258MH1gLGFubm91bmNlOiExLGZpZWxkczpyKERuPT5gcmVzdGFydHM9JHtEbn1gLCJmaWVsZHMiKX0pOlBzO2Zvcig7KFZ8MCk9PT1mdDspe2lmKCsrTGU+TmEpcmV0dXJuIHQoe2tpbmQ6ImVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZTpgSFdKUy1BLTQ6IHN5c2NhbGwgbnI9JHtufDB9IHJlc3RhcnRlZCAke0xlfSB0aW1lcyBzdGlsbCByZXR1cm5pbmcgLUVSRVNUQVJUX1JFU0NIRUQgXHUyMDE0IHRoZSB0YXNrIG5ldmVyIGJlY2FtZSBydW5uYWJsZSAoRlVTRS9ibG9ja2luZyBjb21wbGV0aW9uIG5ldmVyIGxhbmRlZCkuIEFib3J0aW5nIHRoZSByZXN0YXJ0IGxvb3AgbG91ZGx5IHJhdGhlciB0aGFuIGhhbmdpbmcuYH0pLC00O1RjKGB3YXNtX3N5c2NhbGwgbnI9JHtufDB9YCksaXQmJnh0LnRpY2soTGUpLF90KCksVj1SaShuLGEsaSx1LHAsayxFKX1pdCYmeHQuZW5kKExlKX1pZigobnwwKT09PWIpe2xldCBMZT1WfDA7aGM/TGU9PT0tMTA/aHM9ITE6TGU+PTAmJihocz0hMCk6TGU9PT0tMTB8fExlPT09MD9ocz0hMTpMZT4wJiYoaHM9ITApfWxldCBEZT1WfDA7aWYoRGU+PTApe2lmKG49PT1fZXx8bj09PXdlKXtsZXQgTGU9YXwwLHh0PWl8MDt4dD49MCYmeHQ8PTImJihMZT49M3x8WnQuaGFzKExlKT9adC5hZGQoeHQpOlp0LmRlbGV0ZSh4dCkpfWVsc2UgaWYobj09PVcpe2xldCBMZT1hfDAseHQ9RGU7eHQ+PTAmJnh0PD0yJiYoTGU+PTN8fFp0LmhhcyhMZSk/WnQuYWRkKHh0KTpadC5kZWxldGUoeHQpKX1lbHNlIGlmKG49PT1mKXtsZXQgTGU9YXwwO0xlPj0wJiZMZTw9MiYmWnQuZGVsZXRlKExlKX1lbHNlIGlmKG49PT1afHxuPT09VmV8fG49PT1HZXx8bj09PVd0KXtsZXQgTGU9bj09PVd0JiYoKGl8MCk9PT0wfHwoaXwwKT09PTEwMzApOyFPbi5IV0pTX1JFRF9MT1dGRF9PUEVOJiYobiE9PVd0fHxMZSkmJkRlPj0wJiZEZTw9MiYmWnQuYWRkKERlKX19Z28mJihuPT09amV8fG49PT1ZZXx8bj09PV9lfHxuPT09d2V8fG49PT1mfHxuPT09QXx8bj09PWllfHxuPT09Q3x8bj09PUNuKSYmdCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1mZCBwaWQ9JHtzW00uUElEXXwwfSBQT1NUIG5yPSR7bnwwfSAtPiByZXQ9JHtWfDB9IGxvd2Zkcz17JHtbLi4uWnRdLmpvaW4oIiwiKX19YH0pO2xldCB2dD1EZTw9LTUxMiYmRGU+PS01MTY7aWYoKFQmJkRlPT09MHx8dnQpJiZybj49MCl7bGV0IExlPXJuKzIseHQ9QXRvbWljcy5sb2FkKEFlKCksTGUpfDA7R3MoKXx8QXRvbWljcy53YWl0KEFlKCksTGUseHQsMTAwKX1pZihNbiYmSnMoYCAgLT4gW2tlcm5dIG5yPSR7bn0gcmV0PSR7VnwwfQpgKSx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1zeXMgcGlkPSR7c1tNLlBJRF18MH0gUkVUIG5yPSR7bnwwfSByb3V0ZT1LRVJORUwgcmV0PSR7VnwwfWB9KX1jYXRjaHt9cmV0dXJuIFZ8MH1jYXRjaChWKXtsZXQgbWU9ViBpbnN0YW5jZW9mIEVycm9yP1YubWVzc2FnZTpTdHJpbmcoViksRGU9ViBpbnN0YW5jZW9mIEVycm9yJiZWLnN0YWNrP2AKV0FTTS1TWVNDQUxMLVNUQUNLOiBgK1Yuc3RhY2suc3BsaXQoYApgKS5zbGljZSgwLDMyKS5qb2luKCIgfCAiKToiIix2dD15KGB3YXNtX3N5c2NhbGwgbnI9JHtufDB9YCk7aWYodnQhPT0wJiYrK1U8PWZlKXtsZXQgbG49ViBpbnN0YW5jZW9mIEVycm9yJiZWLnN0YWNrP1Yuc3RhY2suc3BsaXQoYApgKS5zbGljZSgwLDE2KS5tYXAoTGU9PkxlLnRyaW0oKSkuam9pbigiIHwgIik6bWUuc3BsaXQoYApgKVswXTtyZXR1cm4gdCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgaHdqcyAjODUgQ09OVEFJTk1FTlQgcGlkPSR7ZS5waWR9OiB3YXNtX3N5c2NhbGwgbnI9JHtufDB9IHRyYXBwZWQgb24gYSBQT0lTT05FRCBMQU5FOyBsYW5lIHJlY2xhaW1lZCAobWFzaz0ke3Z0fSksIHJldHVybmluZyAtRUlOVFIgdG8gdGhlIGNhbGxlciAoY29udGFpbm1lbnQgJHtVfS8ke2ZlfSBmb3IgdGhpcyBXb3JrZXIpIFx1MjAxNCB0aGUgdHJhcHBlZCBpbi1mbGlnaHQgY2hhaW4ncyBmcmFtZXMgYXJlIGxlYWtlZCwgYXR0cmlidXRlZC4gVGhlIGRpcnQgaXMgVVNVQUxMWSBhIHRocmVhZCBXb3JrZXIgdGhhdCBkaWVkIG1pZC1wcm90b2NvbCBvbiB0aGlzIGxhbmUgKCM4NSksIGJ1dCBpdCBpcyBlcXVhbGx5IGEgY29yb3V0aW5pemVkIGNhbGxlZSBwdWJsaXNoZWQgdW5kZXIgYSBOQVRJVkUgY2FsbGVyLCBhbmQgb25seSB0aGUgc3RhY2sgdGVsbHMgdGhlbSBhcGFydDogJHtsbn1gfSksLTR9cmV0dXJuIHQoe2tpbmQ6ImVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZToiSzExLUI1L0I2OiB2bWxpbnV4Lndhc21fc3lzY2FsbCB0cmFwcGVkIGF0IG5yPSIrKG58MCkrIjogIittZStEZX0pLC0zOH19aWYoVHMhPT1udWxsKXtsZXQgVD1UcztpZighKFQubnI9PT0obnwwKSYmVC5hMD09PShhfDApJiZULmExPT09KGl8MCkmJlQuYTI9PT0odXwwKSYmVC5hMz09PShwfDApJiZULmE0PT09KGt8MCkmJlQuYTU9PT0oRXwwKSkpe1RzPW51bGwsQXRvbWljcy5zdG9yZShzLE0uU1RBVEUsa3MpO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBod2pzLW1lcmdlZCBERUZFUlJFRC1SUEMgTUlTTUFUQ0ggcGlkPSR7c1tNLlBJRF18MH0gdGlkPSR7ZS50aWR8MH06IG5yPSR7VC5ucn0gd2FzIGluIGZsaWdodCBvbiB0aGUgbWVyZ2VkIGxhbmUgYW5kIHRoZSBndWVzdCBjYW1lIGJhY2sgYXNraW5nIG5yPSR7bnwwfSBpbnN0ZWFkLiBBIC01MTcgcGFyayBpcyBvbmx5IGNvcnJlY3QgaWYgdGhlIGxpYmMgUkUtSVNTVUVTIFRIRSBTQU1FIENBTEw7IHRoaXMgbGliYyBkaWQgbm90LCBzbyB0aGUgYW5zd2VyIGluIHRoZSBjb250cm9sIFNBQiBiZWxvbmdzIHRvIGEgcXVlc3Rpb24gbm9ib2R5IGlzIGFza2luZyBhbnkgbW9yZS4gUmVmdXNpbmcgd2l0aCAtRU5PU1lTIHJhdGhlciB0aGFuIGhhbmRpbmcgaXQgb3Zlci5gfSl9Y2F0Y2h7fXJldHVybi0zOH1pZihBdG9taWNzLmxvYWQocyxNLlNUQVRFKT09PWRyKXtsZXQgbWU9c1tNLlJFVF9MT118MDtpZihBdG9taWNzLnN0b3JlKHMsTS5TVEFURSxrcyksVHM9bnVsbCxuYysrLE1uJiZKcyhgICAtPiBbc2FiL21lcmdlZF0gbnI9JHtufSByZXQ9JHttZX0KYCksdHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke3NbTS5QSURdfDB9IFJFVCBucj0ke258MH0gcm91dGU9aG9zdC1SUEMvZGVmZXJyZWQgcmV0PSR7bWV8MH0gcGFya3M9JHtULnBhcmtzfWB9KX1jYXRjaHt9cmV0dXJuIG1lfWlmKCsrVC5wYXJrcz5zaSlyZXR1cm4gVHM9bnVsbCxBdG9taWNzLnN0b3JlKHMsTS5TVEFURSxrcyksdCh7a2luZDoiZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOmBod2pzLW1lcmdlZCBERUZFUlJFRC1SUEMgVU5BTlNXRVJFRCBwaWQ9JHtzW00uUElEXXwwfSB0aWQ9JHtlLnRpZHwwfTogaG9zdC1SUEMgbnI9JHtufDB9IHdhcyBpc3N1ZWQgb24gdGhlIG1lcmdlZCBDUFUtMCBsYW5lIGFuZCByZS1jaGVja2VkIGFjcm9zcyAke3NpfSBjb29wZXJhdGl2ZSBwYXJrcyB3aXRob3V0IHRoZSByZXNwb25kZXIgZXZlciB3cml0aW5nIGFuIGFuc3dlci4gVGhlIHRocmVhZCBXQVMgaGFuZGVkIGJhY2sgb24gZXZlcnkgb25lIG9mIHRoZW0sIHNvIHRoaXMgaXMgbm90IHRoZSBtZXJnZWQgZGVhZGxvY2sgXHUyMDE0IHRoZSByZXNwb25kZXIgaXRzZWxmIG5ldmVyIHJhbiBvciBuZXZlciBhbnN3ZXJlZC4gUmV0dXJuaW5nIC1FSU5UUiByYXRoZXIgdGhhbiBwYXJraW5nIGZvcmV2ZXIuYH0pLC00O2lmKG5pKyssKFQucGFya3MmVC5wYXJrcy0xKT09PTAmJlQucGFya3M+PTY0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLW1lcmdlZCBERUZFUlJFRC1SUEMgU0xPVyBwaWQ9JHtzW00uUElEXXwwfSB0aWQ9JHtlLnRpZHwwfTogaG9zdC1SUEMgbnI9JHtufDB9IHN0aWxsIHVuYW5zd2VyZWQgYWZ0ZXIgJHtULnBhcmtzfSBjb29wZXJhdGl2ZSBwYXJrcyAoJHtEYXRlLm5vdygpLVQudDB9bXMpLiBUaGUgdGhyZWFkIHdhcyBoYW5kZWQgYmFjayBvbiBldmVyeSBvbmUgb2YgdGhlbSwgc28gdGhlIHJlc3BvbmRlciBoYWQgaXRzIHR1cm4gYW5kIGRpZCBub3QgYW5zd2VyLmB9KX1jYXRjaHt9cmV0dXJuIGZ0fUF0b21pY3Muc3RvcmUocyxNLk5SLG58MCksQXRvbWljcy5zdG9yZShzLE0uQTAsYXwwKSxBdG9taWNzLnN0b3JlKHMsTS5BMSxpfDApLEF0b21pY3Muc3RvcmUocyxNLkEyLHV8MCksQXRvbWljcy5zdG9yZShzLE0uQTMscHwwKSxBdG9taWNzLnN0b3JlKHMsTS5BNCxrfDApLEF0b21pY3Muc3RvcmUocyxNLkE1LEV8MCksQXRvbWljcy5zdG9yZShzLE0uU1RBVEUsVXIpO2xldCBfbD0hMTtpZihlLm1lcmdlZENwdTBMYW5lPT09ITAmJk5uIT09bnVsbCl7bGV0IFQ7dHJ5e1Q9Tm4ob2MpfWNhdGNoe1Q9dm9pZCAwfWlmKFQ9PT0ic3luYyImJkF0b21pY3MubG9hZChzLE0uU1RBVEUpPT09ZHIpe2xldCBWPXNbTS5SRVRfTE9dfDA7aWYoQXRvbWljcy5zdG9yZShzLE0uU1RBVEUsa3MpLHNjKyssTW4mJkpzKGAgIC0+IFtzYWIvbWVyZ2VkLXN5bmNdIG5yPSR7bn0gcmV0PSR7Vn0KYCksdHQpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke3NbTS5QSURdfDB9IFJFVCBucj0ke258MH0gcm91dGU9aG9zdC1SUEMvaW4tcGxhY2UgcmV0PSR7VnwwfWB9KX1jYXRjaHt9cmV0dXJuIFZ9VD09PSJhc3luYyImJihfbD0hMCxyYysrKX1pZihfbHx8dCh7a2luZDoic3lzY2FsbCIscGlkOmUucGlkfSksZS5tZXJnZWRDcHUwTGFuZT09PSEwKXtpZighJGUobikpe2lmKHZyKyssKHZyJnZyLTEpPT09MCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgaHdqcy1tZXJnZWQgUkVGVVNFRCBhIGhvc3QtUlBDIHN5c2NhbGwgb24gdGhlIG1lcmdlZCBDUFUtMCBsYW5lOiBucj0ke258MH0gcGlkPSR7c1tNLlBJRF18MH0gdGlkPSR7ZS50aWR8MH0uIFRoZSByZXNwb25kZXIgcnVucyBvbiB0aGUgbGF1bmNoaW5nIHRocmVhZCBhbmQgdGhpcyBsYW5lIHNoYXJlcyBpdCwgc28gdGhlIGFuc3dlciBjYW4gb25seSBiZSBwcm9kdWNlZCBieSBhIHRocmVhZCB0aGlzIGxhbmUgd291bGQgYmUgaG9sZGluZy4gVGhlIG1lcmdlZCByb3V0ZSBvdXQgb2YgdGhhdCBpcyB0aGUgY29vcGVyYXRpdmUgLTUxNyBwYXJrLCBhbmQgVEhJUyBJTUFHRSBDQU5OT1QgVEFLRSBPTkUgYXQgdGhpcyB2ZW5lZXIgKF9faHdqc19saWJjX3N5c2NhbGxfcGFya19hYmkgJHtIZT8iPTEiOiJhYnNlbnQifSwgaHdqc0RyaXZlPSR7cT8xOjB9LCBjYW5jZWxsYWJsZT0ke3lhLmhhcyhufDApPyJ5ZXMiOiJubyJ9KSBcdTIwMTQgc28gaXQgd291bGQgZmFsbCBpbnRvIHRoZSBpbi1wbGFjZSByZXN0YXJ0IGxvb3AsIHdob3NlIHdhaXQgaXMgYSB0aHJlYWQtYmxvY2tpbmcgQXRvbWljcy53YWl0LiBSZXR1cm5pbmcgLUVOT1NZUyBpbnN0ZWFkIG9mIGEgbGl2ZWxvY2sgKG9jY3VycmVuY2UgJHt2cn0pLiBXaGF0IGZpeGVzIHRoaXMgaXMgdGhlIGxpYmMgYWJzb3JiaW5nIC01MTcgYXQgcmF3IHZlbmVlcnMsIG5vdCBhIGNoYW5nZSBoZXJlLmB9KX1jYXRjaHt9cmV0dXJuIEF0b21pY3Muc3RvcmUocyxNLlNUQVRFLGtzKSwtMzh9cmV0dXJuIFRzPXtucjpufDAsYTA6YXwwLGExOml8MCxhMjp1fDAsYTM6cHwwLGE0Omt8MCxhNTpFfDAscGFya3M6MCx0MDpEYXRlLm5vdygpfSxuaSsrLGZ0fXtsZXQgbWU9RGF0ZS5ub3coKSxEZT1tZSsxZTQ7Zm9yKDtBdG9taWNzLmxvYWQocyxNLlNUQVRFKSE9PWRyJiYoQXRvbWljcy53YWl0KHMsTS5TVEFURSxVciwyNTApLEF0b21pY3MubG9hZChzLE0uU1RBVEUpIT09ZHIpOylpZihEYXRlLm5vdygpPj1EZSl7RGU9RGF0ZS5ub3coKSsxZTQ7bGV0IHZ0PWBod2pzLWhvc3RycGMgU1RBTEwgcGlkPSR7c1tNLlBJRF18MH0gdGlkPSR7ZS50aWR8MH0gbGFuZT0ke2UudXNlckxhbmU/PzB9IG1vZGU9JHtlLm1vZGV9OiBob3N0LVJQQyBzeXNjYWxsIG5yPSR7bnwwfSB1bmFuc3dlcmVkIGFmdGVyICR7RGF0ZS5ub3coKS1tZX1tcy4gVGhpcyBsYW5lIGlzIGJsb2NrZWQgaW4gdGhlIGNvbnRyb2wgU0FCLCB3aGljaCBubyBzaWduYWwsIHBhdXNlIG9yIGZvcmsgc2VydmljZXIgY2FuIHdha2UgXHUyMDE0IG9ubHkgdGhlIGhvc3QncyBhbnN3ZXIgY2FuLiBPbiBhIHBvb2wgV29ya2VyIHRoYXQgYmxvY2tzIGV2ZXJ5IGNvLXJlc2lkZW50IHRhc2sgYW5kIHRoZSBtZXNzYWdlIGxvb3AgZm9yIHRoZSBkdXJhdGlvbiAobG91ZCwgYXR0cmlidXRlZCwgbmV2ZXIgYSBzaWxlbnQgd2VkZ2UpLmA7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo0LHRleHQ6dnR9KX1jYXRjaHt9fX1sZXQgSm89c1tNLlJFVF9MT118MDtpZihBdG9taWNzLnN0b3JlKHMsTS5TVEFURSxrcyksTW4mJkpzKGAgIC0+IFtzYWJdIG5yPSR7bn0gcmV0PSR7Sm99CmApLHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBSRVQgbnI9JHtufDB9IHJvdXRlPWhvc3QtUlBDIHJldD0ke0pvfDB9YH0pfWNhdGNoe31yZXR1cm4gSm99cihwcywic3lzY2FsbElubmVyIik7bGV0IEY9bnVsbCxuZT0wLEZvPW51bGwsSG89bnVsbCxOZT1udWxsLFFuPW51bGw7aWYoZS52bWxpbnV4TW9kdWxlKXtsZXQgbj1hd2FpdCBJYShlLHQpO2lmKCFuKXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBod2pzIzY1OiBzcGF3biByZWZ1c2VkIFx1MjAxNCBwZXItV29ya2VyIHZtbGludXgvdGFzay1hbGxvYyBmYWlsZWQgKHRpZD0ke2UudGlkfDB9IHBwaWQ9JHtlLnBwaWR8MH0gY3B1PSR7ZS5jcHVJZHwwfSk7IHRoZSB1c2VyIGJpbmFyeSB3aWxsIE5PVCBydW4gKGEgdGFzayB3aXRoIG5vIHJlZ2lzdGVyZWQga2VybmVsIHBpZCBtdXN0IG5ldmVyIGlzc3VlIHN5c2NhbGxzIFx1MjAxNCBSLUsxMS42LVcxIGNsb3NlZCBzdHJ1Y3R1cmFsbHkpYH0pO3JldHVybn17aWYoRj1uLmluc3RhbmNlLG5lPW4ucGVyUHJvY2Vzc1Rhc2tBZGRyfDAsTmU9bi5od2pzTGFuZXx8bnVsbCx0eXBlb2YgRi5leHBvcnRzLndhc20zMl9zeXNjYWxsX2ltcGxlbWVudGVkPT0iZnVuY3Rpb24iJiZ0eXBlb2YgRi5leHBvcnRzLndhc20zMl9zeXNjYWxsX3RhYmxlX3NpemU9PSJmdW5jdGlvbiIpdHJ5e2xldCBhPUYuZXhwb3J0cy53YXNtMzJfc3lzY2FsbF90YWJsZV9zaXplKCl8MDtpZihhPjAmJmE8PTQwOTYpe2xldCBpPW5ldyBVaW50OEFycmF5KGEpLHU9MDtmb3IobGV0IHA9MDtwPGE7cCsrKXtsZXQgaz1GLmV4cG9ydHMud2FzbTMyX3N5c2NhbGxfaW1wbGVtZW50ZWQocCl8MDtpW3BdPWs/MTowLHUrPWlbcF19UW49aSx0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXJvdXRlIHBpZD0ke3NbTS5QSURdfDB9IGtlcm5lbCBzeXNjYWxsIHRhYmxlOiAke3V9LyR7YX0gaW1wbGVtZW50ZWQgXHUyMDE0IHRoZSBrZXJuZWwncyB0YWJsZSBpcyB0aGUgcm91dGluZyBydWxlOyBob3N0IGV4Y2VwdGlvbnMgYXJlIG5hbWVkIGluIEhPU1RfQU5TV0VSRURgfSl9fWNhdGNoe1FuPW51bGx9aWYoUW49PT1udWxsJiZ0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLXJvdXRlIHBpZD0ke3NbTS5QSURdfDB9IHRoaXMgdm1saW51eCBleHBvcnRzIG5vIHdhc20zMl9zeXNjYWxsX2ltcGxlbWVudGVkIFx1MjAxNCBmYWxsaW5nIGJhY2sgdG8gdGhlIGhvc3Qtc2lkZSBwZXItbnIgYWxsb3dsaXN0LiBTeXNjYWxscyB0aGUga2VybmVsIGltcGxlbWVudHMgYnV0IHRoZSBsaXN0IG9taXRzIHdpbGwgYmUgYW5zd2VyZWQgYnkgdGhlIGhvc3QgcmVzcG9uZGVyIHdpdGhvdXQgY29uc3VsdGluZyB0aGUga2VybmVsLmB9KSx0eXBlb2YgRi5leHBvcnRzLl9faHdqc190YXNrX3dha2VfYWRkcj09ImZ1bmN0aW9uIiYmbmUhPT0wJiZ5biE9PW51bGwpdHJ5e2xldCBhPUYuZXhwb3J0cy5fX2h3anNfdGFza193YWtlX2FkZHIoKT4+PjA7YSE9PTAmJihGbz1hLShuZT4+PjApfDApfWNhdGNoe31pZih0eXBlb2YgRi5leHBvcnRzLl9faHdqc190YXNrX3BhcmtfZGVhZGxpbmVfYWRkcj09ImZ1bmN0aW9uIiYmbmUhPT0wJiZ5biE9PW51bGwpdHJ5e2xldCBhPUYuZXhwb3J0cy5fX2h3anNfdGFza19wYXJrX2RlYWRsaW5lX2FkZHIoKT4+PjA7YSE9PTAmJihhJjMpPT09MCYmKEhvPWEtKG5lPj4+MCl8MCl9Y2F0Y2h7fXR5cGVvZiBuLmtlcm5lbFBpZD09Im51bWJlciImJm4ua2VybmVsUGlkPjAmJihzW00uUElEXT1uLmtlcm5lbFBpZHwwLGUubW9kZSE9PSJ0aHJlYWQiJiYoc1tNLlRJRF09bi5rZXJuZWxQaWR8MCkpfX1sZXQgVW89NCxCaT0xNSxHbz0xLFduPUdvLEZpPS0xLEhpPXIobj0+TWF0aC5tYXgoR28sbi8yKSwiY29vcFdhaXREZWNheSIpLFVpPXIoKCk9PntXbj1Hb30sImNvb3BXYWl0RXBpc29kZVJlc2V0IiksS289cigoKT0+Rm89PT1udWxsfHxuZT09PTB8fHluPT09bnVsbD8tMToobmU+Pj4wKStGbz4+PjIsInRhc2tXYWtlSWR4IiksU2M9ISEoZ2xvYmFsVGhpcy5wcm9jZXNzPy5lbnY/LkhXSlNfTk9fU1RBVEVfV0FLRXx8Z2xvYmFsVGhpcy5IV0pTX05PX1NUQVRFX1dBS0UpLCRjPXIoKCk9PlNjfHxuZT09PTB8fHluPT09bnVsbD8tMToobmU+Pj4wKStsZj4+PjIsInRhc2tTdGF0ZUlkeCIpLHZjPSEhKGdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTX05PX1BBUktfREVBRExJTkV8fGdsb2JhbFRoaXMuSFdKU19OT19QQVJLX0RFQURMSU5FKSxBYz1yKG49PntpZih2Y3x8SG89PT1udWxsfHxuZT09PTApcmV0dXJuIDA7bGV0IGE9KG5lPj4+MCkrSG8+Pj4yLGk9QXRvbWljcy5sb2FkKG4sYSk+Pj4wO3JldHVybigoQXRvbWljcy5sb2FkKG4sYSsxKT4+PjApKjQyOTQ5NjcyOTYraSkvMWU2fSwidGFza1BhcmtEZWFkbGluZU1zIiksR2k9cigoKT0+cGVyZm9ybWFuY2UudGltZU9yaWdpbitwZXJmb3JtYW5jZS5ub3coKSwiaG9zdE5vd01zIik7YXN5bmMgZnVuY3Rpb24gSWMobil7cGUmJnBlLmNvb3BXYWl0cysrO2xldCBhPUtvKCk7aWYoYmkoKSYmKGhzPSEwKSxHcygpKXJldHVybjtpZihhPDApe2lmKG5lPT09MHx8eW49PT1udWxsKXRocm93IG5ldyBFcnJvcihgJHtufTogLUVSRVNUQVJUUkVTQ0hFRCBidXQgbm8ga2VybmVsIHRhc2tfc3RydWN0L3dha2Ugd29yZCBpcyByZWFjaGFibGUgKHBlclByb2Nlc3NUYXNrQWRkcj0weCR7KG5lPj4+MCkudG9TdHJpbmcoMTYpfSwga2VybmVsTWVtPSR7eW4/InByZXNlbnQiOiJhYnNlbnQifSkgXHUyMDE0IHJlZnVzaW5nIHRvIHNwaW4uYCk7YXdhaXQgbmV3IFByb21pc2UoYj0+c2V0VGltZW91dChiLFduKSksV249TWF0aC5taW4oQmksV24qMiksVHIoKTtyZXR1cm59a28hPT1GaSYmKFduPUhpKFduKSk7bGV0IGk9UnIoKSx1PUF0b21pY3MubG9hZChpLGEpfDAscD1BYyhpKSxrPXA+MD9wLUdpKCk6MS8wLEU9azxXbiwkPSRjKCksdj0idGltZWQtb3V0Ijt0cnl7aWYoRT9rPj0xJiYodj1hd2FpdCB3ZChpLGEsdSwkLE1hdGguZmxvb3IoaykpKTp2PWF3YWl0IHdkKGksYSx1LCQsV24pLEUmJnY9PT0idGltZWQtb3V0Iil7bGV0IGI9JD49MD9BdG9taWNzLmxvYWQoaSwkKXwwOjA7Zm9yKDtHaSgpPHA7KXtpZigoQXRvbWljcy5sb2FkKGksYSl8MCkhPT11fHwkPj0wJiYoQXRvbWljcy5sb2FkKGksJCl8MCkhPT1ifHxHcygpKXt2PSJvayI7YnJlYWt9YXdhaXQgbHIoKX19fWNhdGNoe3Y9Im9rIn0oIUV8fHYhPT0idGltZWQtb3V0IikmJihXbj12PT09InRpbWVkLW91dCI/TWF0aC5taW4oQmksV24qMik6SGkoV24pKSxGaT1rbyxUcigpfXIoSWMsImNvb3BXYWl0UnVubmFibGUiKTtsZXQgS2k9MjUwO2FzeW5jIGZ1bmN0aW9uIFJjKCl7bGV0IG49c247aWYoIW58fEtzKCkpcmV0dXJuO2xldCBhPW4uZGVhZGxpbmVNcz09PTEvMD9LaTpNYXRoLm1heCgxLG4uZGVhZGxpbmVNcy1EYXRlLm5vdygpKSxpPU1hdGgubWluKGEsS2kpLHU9QWUoKTtpZihBdG9taWNzLmxvYWQodSxuLmkzMmlkeCkhPT1uLnZhbClyZXR1cm47bGV0IHA9QXRvbWljcy53YWl0QXN5bmModSxuLmkzMmlkeCxuLnZhbCxpKTtpZihwLmFzeW5jKXRyeXthd2FpdCBwLnZhbHVlfWNhdGNoe319cihSYywiY29vcEZ1dGV4V2FpdCIpO2Z1bmN0aW9uIFRjKG4pe2lmKHBlJiZwZS5yZXNjaGVkUmVzdGFydHMrKyxuZT09PTB8fHluPT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYCR7bn06IC1FUkVTVEFSVFJFU0NIRUQgYnV0IG5vIGtlcm5lbCB0YXNrX3N0cnVjdCBpcyByZWFjaGFibGUgKHBlclByb2Nlc3NUYXNrQWRkcj0weCR7KG5lPj4+MCkudG9TdHJpbmcoMTYpfSwga2VybmVsTWVtPSR7eW4/InByZXNlbnQiOiJhYnNlbnQifSkuYCk7aWYoYmkoKSYmKGhzPSEwKSxHcygpKXJldHVybjtsZXQgYT1LbygpO2lmKGE+PTApe2xldCBrPVJyKCksRT1BdG9taWNzLmxvYWQoayxhKXwwO0F0b21pY3Mud2FpdChrLGEsRSxVbyksVHIoKTtyZXR1cm59bGV0IGk9bmU+Pj4wPj4+Mix1PVJyKCkscD1BdG9taWNzLmxvYWQodSxpKXwwO0F0b21pY3Mud2FpdCh1LGkscCxVbyksVHIoKX1yKFRjLCJhd2FpdFJlc2NoZWRSdW5uYWJsZSIpO2Z1bmN0aW9uIGpjKCl7aWYobmU9PT0wfHx5bj09PW51bGwpcmV0dXJuO2xldCBuPUtvKCksYT1uPj0wP246bmU+Pj4wPj4+MixpPVJyKCk7QXRvbWljcy53YWl0KGksYSxBdG9taWNzLmxvYWQoaSxhKXwwLFVvKX1yKGpjLCJhd2FpdFRhc2tXYWtlU2xpY2UiKTtsZXQgRXQ9e2Vudjp7dXNlcl9tZW1vcnk6ZS5tZW1vcnksX19od2pzX3htb2RfZGlzcGF0Y2hfY2hlY2s6cigobixhKT0+VXMobixhLCEwLCExLCEwKSwiX19od2pzX3htb2RfZGlzcGF0Y2hfY2hlY2siKSxfX2h3anNfcmVnaXN0ZXJfZnBjYXN0X2FkYXB0ZXI6cigobixhLGksdSxwKT0+WGEobixhLGksdSxwKSwiX19od2pzX3JlZ2lzdGVyX2ZwY2FzdF9hZGFwdGVyIiksX19od2pzX2ZwY2FzdF9hZGFwdGVyX2xvb2t1cDpyKChuLGEpPT5xYShuLGEpLCJfX2h3anNfZnBjYXN0X2FkYXB0ZXJfbG9va3VwIiksX19od2pzX2ZwY2FzdF90YXJnZXRfc2lnX2xvb2t1cDpyKG49PlphKG4pLCJfX2h3anNfZnBjYXN0X3RhcmdldF9zaWdfbG9va3VwIil9LGxpbnV4OntzeXNjYWxsOlhzfSxod2pzX3N1c3BlbmQ6e3Bhcms6cigoKT0+e30sInBhcmsiKX19O3tsZXQgbj1lLmtlcm5lbE1lbW9yeVdhc20/P2Uua2VybmVsTWVtb3J5O24mJihFdC5lbnYua2VybmVsX21lbW9yeT1uKX1sZXQgSmk9bmV3IFNldChPYmplY3Qua2V5cyhFdC5lbnYpKSxPdD1lLndhc21CeXRlcyx3cz1udWxsLERjPXIoKCk9Pih7cGlkOnNbTS5QSURdfDAsdGlkOmUudGlkfDAsbW9kZTplLm1vZGU9PT0idGhyZWFkIj8idGhyZWFkIjoiZm9yayIsY3B1SWQ6ZS5jcHVJZHwwLHVzZXJMYW5lOmUudXNlckxhbmV8MCxwb29sUmVzaWRlbnQ6ISFvLGltYWdlOntieXRlTGVuZ3RoOk90P090Lmxlbmd0aDowLHBhdGg6d3N9LGRyaXZlOntod2pzRHJpdmU6cSxod2pzRmxhdDpPZSxsaWJjUGFya3NBbnlTeXNjYWxsOkhlfSxod2pzUnQ6Q2U/e21vZHVsZUlkOkNlLm1vZHVsZUlkfDAsbWVtb3J5QmFzZTpDZS5tZW1vcnlCYXNlPj4+MCx0YWJsZUJhc2U6Q2UudGFibGVCYXNlPj4+MCx0YWJsZVNpemU6Q2UudGFibGVTaXplPj4+MH06bnVsbCxsaWJjU286TWU/e2RpZ2VzdDpNZS5kaWdlc3QsY2hlY2tFbWl0dGluZzohIU1lLmNoZWNrRW1pdHRpbmcsbGFuZUFkZHJlc3NlZDohIU1lLmxhbmVBZGRyZXNzZWR9Om51bGwsZGxvcGVuOntvcGVuOlsuLi5qdF0ubWFwKChbbixhXSk9Pih7Y29va2llOm4+Pj4wLG1vZHVsZUlkOmEubW9kdWxlSWR8MCxwYXRoOmEucGF0aHx8IiIsYnl0ZUxlbmd0aDphLmJ5dGVzP2EuYnl0ZXMubGVuZ3RoOjAsbWVtb3J5QmFzZTphLm1lbW9yeUJhc2U+Pj4wLHRhYmxlQmFzZTphLnRhYmxlQmFzZT4+PjB9KSksZGVhZFJhbmdlczpLbi5sZW5ndGgsbmV4dENvb2tpZTpHbj4+PjAsdGFibGVMZW46emUgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5UYWJsZT96ZS5sZW5ndGg+Pj4wOjB9LHdhc21TeXNjYWxsU3RhdHM6ey4uLnFufSxhc3luY2lmeUhpZ2hXYXRlckJ5dGVzOkFzfDAsY29vcFdhaXRWaW9sYXRpb25zOkpufDAsc3luY1Jlc3RhcnRWaW9sYXRpb25zOlpufDAsbGFuZTpOZT97Li4uTmUuY2Vuc3VzfTpudWxsLGlzb2xhdGVNb2R1bGVDYWNoZXM6TWQoKX0pLCJidWlsZFRhc2tQcm9iZSIpO3tsZXQgbj12cy5nZXQoZSk7biYmKG4ucHJvYmU9RGMpfWxldCBsdD0hMDtlOmZvcig7Oyl7bGV0IG49LTE7aWYoIWx0KXtmb3IobGV0IEEgb2YgT2JqZWN0LmtleXMoRXQuZW52KSlKaS5oYXMoQSl8fGRlbGV0ZSBFdC5lbnZbQV07ZGVsZXRlIEV0WyJHT1QubWVtIl0sZGVsZXRlIEV0WyJHT1QuZnVuYyJdLHplPW51bGwsY249bnVsbCxSbj1udWxsLFNuPW5ldyBNYXB9bGV0IGE9bnVsbDtpZighbHQpe2xldCBBPV9vKE90LCJleGVjIHJlLWluc3RhbnRpYXRlIik7aWYoQTwwKWE9YHVzZXJfbWVtb3J5IGNhbm5vdCBmaXQgdGhlIGV4ZWMgaW1hZ2UgKGVycm5vICR7QX0pYDtlbHNle2lmKHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBFWEVDLVdJUEU6IHBpZD0ke2UucGlkfSBtb2RlPSR7ZS5tb2RlfSBsYW5lPSR7ZS51c2VyTGFuZT8/Ij8ifSB3aXBpbmcgdXNlcl9tZW1vcnkgKCR7ZS5tZW1vcnkuYnVmZmVyLmJ5dGVMZW5ndGh9QikgZm9yIGV4ZWMgcmUtaW5zdGFudGlhdGUgb2YgJHtPdC5sZW5ndGh9QiBpbWFnZWB9KX1jYXRjaHt9aWYobmV3IFVpbnQ4QXJyYXkoZS5tZW1vcnkuYnVmZmVyKS5maWxsKDApLHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBFWEVDLUxPQUQtRElBRzogaW1hZ2VMb29wIHJlLWluc3RhbnRpYXRlOyBjb21waWxpbmcgJHtPdC5sZW5ndGh9QmB9KX1jYXRjaHt9fX1sZXQgaT1yKEE9Pnt0cnl7bGV0IEo9QXJyYXkuaXNBcnJheShUbikmJlRuLmxlbmd0aD4wP1N0cmluZyhUblswXSk6ImV4ZWMiLEM9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGAke0p9OiAke0F9CmApLGllPTY1NTM2LGxlPW5ldyBVaW50OEFycmF5KGUubWVtb3J5LmJ1ZmZlcik7aWYobGUubGVuZ3RoPGllK0MubGVuZ3RoKXJldHVybjtsZS5zZXQoQyxpZSksWHMoMSwyLGllLEMubGVuZ3RoLDAsMCwwKX1jYXRjaHt9fSwiZXhlY1JlZnVzYWxUb1N0ZGVyciIpO2lmKGEpe2koYSksdCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOmBoYXJkd2FyZWpzIzY6IGV4ZWMtaW4tcGxhY2UgRkFJTEVEIHBhc3QgdGhlIHBvaW50IG9mIG5vIHJldHVybiBcdTIwMTQgJHthfTsga2lsbGluZyBwaWQgJHtlLnBpZH0gd2l0aCBleGl0IDEyNyAoZ3Vlc3QgcmVhcHM7IG5ldmVyIGEgc2lsZW50IGhhbmcpYH0pLG09MTI3O2JyZWFrIGV9bGV0IHU9cihhc3luYyhBLEopPT57bGV0IEM9YGhhcmR3YXJlanMjNjogdXNlciBpbWFnZSAke2x0PyJzcGF3biI6ImV4ZWMifSAke0F9IGZhaWxlZCAoJHtPdC5sZW5ndGh9QiBpbWFnZSwgdXNlcl9tZW1vcnkgJHtNYXRoLmZsb29yKGUubWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoLzY1NTM2KX0gcGFnZXMpOiAke0ogaW5zdGFuY2VvZiBFcnJvcj9KLm1lc3NhZ2U6U3RyaW5nKEopfWA7cmV0dXJuIGx0Pyhhd2FpdCBTKDEyNywwKSx0KHtraW5kOiJlcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6Q30pLCJyZXR1cm4iKTooaShDKSx0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6YCR7Q30gXHUyMDE0IGtpbGxpbmcgcGlkICR7ZS5waWR9IHdpdGggZXhpdCAxMjcgKGd1ZXN0IHJlYXBzOyBuZXZlciBhIHNpbGVudCBoYW5nKWB9KSxtPTEyNywiYnJlYWsiKX0sImltYWdlU3RhZ2VGYXRhbCIpLHAsayxFO3RyeXtucyhlLHQsYGltYWdlLWNvbXBpbGUtYmVnaW4gYnl0ZXM9JHtPdC5sZW5ndGh9YCkse21vZHVsZTpwLGtleTprLGNhY2hlZDpFfT1hd2FpdCB3ZihPdCksbnMoZSx0LGBpbWFnZS1jb21waWxlLWVuZCBjYWNoZWQ9JHtFPzE6MH1gKX1jYXRjaChBKXtpZihhd2FpdCB1KCJDT01QSUxFIixBKT09PSJyZXR1cm4iKXskbigiZXJyb3IiKTtyZXR1cm59YnJlYWsgZX10cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgSFdKUy1BNS1JTUdDQUNIRSBwaWQ9JHtlLnBpZH0gJHtFPyJISVQgIjoiQ09NUElMRSJ9IGxlbj0ke090Lmxlbmd0aH0ga2V5PSR7a30gY29tcGlsZXM9JHtUYX0gaGl0cz0ke2VvfSBjYWNoZVNpemU9JHtBbi5zaXplfWB9KX1jYXRjaHt9aWYoIWx0JiZ0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDoiRVhFQy1MT0FELURJQUc6IHJlLWluc3RhbnRpYXRlIGNvbXBpbGVkOyBpbnN0YW50aWF0aW5nIn0pfWNhdGNoe317bGV0IEE9V2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMocCkuZmluZChKPT5KLmtpbmQ9PT0idGFibGUiKTtpZihBKXtsZXQgSj1ibChPdCl8fHttaW46MCxtYXg6dm9pZCAwfTtpZih6ZT1uZXcgV2ViQXNzZW1ibHkuVGFibGUoe2luaXRpYWw6Si5taW4+Pj4wLC4uLkoubWF4IT09dm9pZCAwP3ttYXhpbXVtOkoubWF4Pj4+MH06e21heGltdW06MTw8MjB9LGVsZW1lbnQ6ImFueWZ1bmMifSksY249bmV3IE1hcCxSbj1uZXcgTWFwLHhzKGUubW9kZSkmJmx0JiZlLmRsb3BlbkZvcmsmJkFycmF5LmlzQXJyYXkoZS5kbG9wZW5Gb3JrLmdvdEZ1bmMpKWZvcihsZXRbQyxpZV1vZiBlLmRsb3BlbkZvcmsuZ290RnVuYyljbi5zZXQoU3RyaW5nKEMpLGllPj4+MCk7KEV0W0EubW9kdWxlXT8/PXt9KVtBLm5hbWVdPXplO2ZvcihsZXQgQyBvZiBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhwKSlDLmtpbmQ9PT0iZ2xvYmFsIiYmKEMubmFtZT09PSJfX21lbW9yeV9iYXNlIj8oRXRbQy5tb2R1bGVdPz89e30pW0MubmFtZV09bmV3IFdlYkFzc2VtYmx5Lkdsb2JhbCh7dmFsdWU6ImkzMiIsbXV0YWJsZTohMX0sMCk6Qy5uYW1lPT09Il9fdGFibGVfYmFzZSI/KEV0W0MubW9kdWxlXT8/PXt9KVtDLm5hbWVdPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITF9LDApOkMubmFtZT09PSJfX3N0YWNrX3BvaW50ZXIiJiYoKEV0W0MubW9kdWxlXT8/PXt9KVtDLm5hbWVdPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITB9LDApKSl9fXJ0PW51bGwsQ2U9bnVsbCxQdD1udWxsLGRuPW51bGwsZWU9bnVsbCxNZT1udWxsLHBuPVtdLEJ0PVtdLGtuPVtdLGo9bnVsbCx3bj0hMSxGdD0wLGduPVtdLEVuPVtdO2xldCAkPW51bGwsdj1bXTt7bGV0IEE7dHJ5e0E9dGEoT3QpfWNhdGNoKEope2lmKGF3YWl0IHUoIk5FRURFRC1QQVJTRSIsSik9PT0icmV0dXJuIil7JG4oImVycm9yIik7cmV0dXJufWJyZWFrIGV9aWYoQSYmQS5uZWVkZWQubGVuZ3RoPjApdHJ5e2xldCBKPUEubmVlZGVkWzBdLEM9dHMoSik7aWYoIWVuLmhhcyhDKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogdGhlIGltYWdlIG5lZWRzIC9saWIvJHtKLnNsaWNlKDAsMjQpfVx1MjAyNiBidXQgbm8gc2hhcmVkIGxpYnJhcnkgb2YgdGhhdCBkaWdlc3Qgd2FzIGRlbGl2ZXJlZCB0byB0aGlzIFdvcmtlciAoc3RvcmUgaGFzICR7ZW4uc2l6ZX0gZGlnZXN0KHMpKSBcdTIwMTQgdGhlIGtlcm5lbCBMSUJDX1NUQUdFIGhhbmQtb2ZmIGRpZCBub3QgcnVuIG9yIGRlbGl2ZXJlZCBhIGRpZmZlcmVudCBnZW5lcmF0aW9uIChuZXZlci1zaWxlbnQgbG91ZCBleGVjIGZhaWx1cmUpLmApOyQ9e25hbWU6SixkaWdlc3Q6QyxzdXNwZW5kZXJzU2hhMjU2OkEuc3VzcGVuZGVyc1NoYTI1Nn07Zm9yKGxldCBpZT0xO2llPEEubmVlZGVkLmxlbmd0aDtpZSsrKXtsZXQgbGU9QS5uZWVkZWRbaWVdLFo9dHMobGUpO2lmKCFlbi5oYXMoWikpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHRoZSBpbWFnZSBuZWVkcyAke2xlLnNsaWNlKDAsMzIpfVx1MjAyNiAobmVlZGVkIGVudHJ5ICR7aWV9KSBidXQgbm8gc2hhcmVkIGxpYnJhcnkgb2YgdGhhdCBkaWdlc3Qgd2FzIGRlbGl2ZXJlZCB0byB0aGlzIFdvcmtlciAoc3RvcmUgaGFzICR7ZW4uc2l6ZX0gZGlnZXN0KHMpKSBcdTIwMTQgdGhlIGtlcm5lbCBORUVERURfU1RBR0UgaGFuZC1vZmYgZGlkIG5vdCBydW4gZm9yIHRoaXMgZW50cnkgb3IgZGVsaXZlcmVkIGEgZGlmZmVyZW50IGdlbmVyYXRpb24gKG5ldmVyLXNpbGVudCBsb3VkIGV4ZWMgZmFpbHVyZSkuYCk7di5wdXNoKHtuYW1lOmxlLHNvbmFtZTphcihsZSksZGlnZXN0OlosaW5kZXg6aWV9KX19Y2F0Y2goSil7aWYoYXdhaXQgdSgiTElCQy1ORUVERUQiLEopPT09InJldHVybiIpeyRuKCJlcnJvciIpO3JldHVybn1icmVhayBlfX10cnl7bGV0IEE9aXIoT3QpO3duPSEhKEEmJkEuZmxhZ3MuY2hlY2tFbWl0dGluZyksaGU9ISEoQSYmQS5mbGFncy5sYW5lQWRkcmVzc2VkKSxGdD1BP0EuZHJpdmVBYml8MDowfWNhdGNoKEEpe2lmKGF3YWl0IHUoIk1BSU4tTUFOSUZFU1QiLEEpPT09InJldHVybiIpeyRuKCJlcnJvciIpO3JldHVybn1icmVhayBlfXtsZXQgQT1XZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhwKSxKPUEuc29tZShDPT5DLm1vZHVsZT09PSJlbnYiJiZDLmtpbmQ9PT0iZnVuY3Rpb24iJiZDLm5hbWU9PT0iX19od2pzX2ZyYW1lX2FsbG9jIik7aWYoJCYmIUopdGhyb3cgbmV3IEVycm9yKCJod2pzLWxpYmM6IHRoZSBpbWFnZSBjYXJyaWVzIHdhc20ubGludXgubmVlZGVkIGJ1dCBkb2VzIG5vdCBpbXBvcnQgdGhlIGh3anMgcnVudGltZSAoZW52Ll9faHdqc19mcmFtZV9hbGxvYykgXHUyMDE0IGEgZHluYW1pYy1saWJjIG1haW4gaXMgcnQtaW1wb3J0aW5nIGJ5IGNvbnN0cnVjdGlvbjsgcmVmdXNpbmcgYSBmb3JlaWduIHNoYXBlIChuZXZlci1zaWxlbnQpLiIpO2lmKEope2lmKFdlYkFzc2VtYmx5Lk1vZHVsZS5leHBvcnRzKHApLnNvbWUoRz0+Ry5uYW1lPT09Il9faHdqc19mcmFtZV9hbGxvYyIpKXRocm93IG5ldyBFcnJvcigiaHdqcy1ydDogRE9VQkxFIFBST1ZJU0lPTiByZWZ1c2VkIFx1MjAxNCB0aGUgbWFpbiBib3RoIExJTktTIGl0cyBvd24gaHdqcyBydW50aW1lIChleHBvcnRzIF9faHdqc19mcmFtZV9hbGxvYykgYW5kIElNUE9SVFMgdGhlIGtlcm5lbC1wcm92aWRlZCBvbmUuIE9uZSBydW50aW1lIHByb3ZpZGVyIHBlciBwcm9jZXNzIChQTEFOLUhXSlMtUlQtUFNBQkkpOyByZWxpbmsgdGhlIG1haW4uIik7aWYoJCl7bGV0IEc9bmV3IFNldChXZWJBc3NlbWJseS5Nb2R1bGUuZXhwb3J0cyhwKS5maWx0ZXIoSz0+Sy5raW5kPT09ImZ1bmN0aW9uIikubWFwKEs9PksubmFtZSkpO2ZvcihsZXQgSyBvZlsiX19saWJjX3N0YXJ0X21haW4iLCJtYWxsb2MiXSlpZihHLmhhcyhLKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogRE9VQkxFIFBST1ZJU0lPTiByZWZ1c2VkIFx1MjAxNCB0aGUgbWFpbiBuYW1lcyAkeyQubmFtZS5zbGljZSgwLDI0KX1cdTIwMjYgaW4gd2FzbS5saW51eC5uZWVkZWQgYnV0IGFsc28gRVhQT1JUUyB0aGUgbGliYyBhbmNob3IgIiR7S30iIChhIHN0YXRpY2FsbHkgbGlua2VkIGxpYmMpLiBPbmUgbGliYyBwcm92aWRlciBwZXIgcHJvY2VzcyAoUExBTi1EWU5BTUlDLUxJQkMgXHhBNzMuNCk7IHJlbGluayB0aGUgbWFpbi5gKX1pZighZS5od2pzUnRNb2R1bGV8fCFlLmh3anNSdEJ5dGVzKXRocm93IG5ldyBFcnJvcigiaHdqcy1ydDogdGhlIG1haW4gaW1wb3J0cyB0aGUgaHdqcyBydW50aW1lIG9wcyBidXQgdGhpcyBrZXJuZWwgc2hpcHMgbm8gbGliaHdqcy1ydCAobm8gdmVyaWZpZWQgaHdqcy5ydC5zbyBzZWN0aW9uKSBcdTIwMTQgYSBydW50aW1lLWltcG9ydGluZyBkeW5hbWljIG1haW4gY2Fubm90IHJ1biBvbiBhIGtlcm5lbCBpbWFnZSB3aXRoIG5vIGVtYmVkZGVkIHJ0IChuZXZlci1zaWxlbnQpLiIpO2xldCBDPWUuaHdqc1J0Qnl0ZXMsaWU9ZS5od2pzUnRNb2R1bGU7aWYoRnQ9PT00KXtsZXQgRz1lLnZtbGludXhNb2R1bGU/V2ViQXNzZW1ibHkuTW9kdWxlLmN1c3RvbVNlY3Rpb25zKGUudm1saW51eE1vZHVsZSwiaHdqcy5ydDQuc28iKTpbXTtpZihHLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBod2pzLXJ0OiB0aGlzIG1haW4gaXMgZHJpdmVfYWJpPTQgKHN0YXR1cyBjaGFubmVsKSBidXQgdGhlIGtlcm5lbCBzaGlwcyAke0cubGVuZ3RofXggaHdqcy5ydDQuc28gc2VjdGlvbihzKSBcdTIwMTQgYW4gYWJpLTQgZHluYW1pYyBtYWluIGNhbm5vdCBydW4gYWdhaW5zdCB0aGUgZmxhdCBydW50aW1lIChpdHMgbGVhZiBwYXJrcyB3b3VsZCBzaWxlbnRseSB0cmFuc2l0OyBJMykuIFJlYnVpbGQgdGhlIGtlcm5lbCBwYWNrYWdpbmcgKHNjcmlwdHMvYnVpbGQtaHdqcy1ydC5zaCBzdGF0dXMtY2hhbm5lbCB0d2luKTsgbmV2ZXItc2lsZW50LmApO0M9bmV3IFVpbnQ4QXJyYXkoR1swXSksaWU9JHMoQykubW9kdWxlO2xldCBLPVdlYkFzc2VtYmx5Lk1vZHVsZS5jdXN0b21TZWN0aW9ucyhpZSwiaHdqcy5ydC5wcm92ZW5hbmNlIiksZ2U9Sy5sZW5ndGg9PT0xP25ldyBUZXh0RGVjb2RlcigpLmRlY29kZShLWzBdKS50cmltKCk6bnVsbCxJZT10eXBlb2YgZS5od2pzUnRQcm92ZW5hbmNlPT0ic3RyaW5nIj9lLmh3anNSdFByb3ZlbmFuY2UudHJpbSgpOm51bGw7aWYoIWdlfHwhSWV8fGdlIT09SWUpdGhyb3cgbmV3IEVycm9yKCJod2pzLXJ0OiB0aGUgc3RhdHVzLWNoYW5uZWwgcnVudGltZSB0d2luJ3MgZW1iZWRkZWQgUlQtUFJPVkVOQU5DRSBkb2VzIG5vdCBtYXRjaCB0aGUgYm9vdC12ZXJpZmllZCBhdHRlc3RhdGlvbiAobWl4ZWQvc3RhbGUga2VybmVsIHBhY2thZ2luZykgXHUyMDE0IHJlZnVzaW5nIHRoZSBydW50aW1lIChuZXZlci1zaWxlbnQpLiIpfWlmKCF6ZSl0aHJvdyBuZXcgRXJyb3IoImh3anMtcnQ6IHRoZSBydW50aW1lLWltcG9ydGluZyBtYWluIGRvZXMgbm90IGltcG9ydCB0aGUgc2hhcmVkIHRhYmxlIFx1MjAxNCBub3QgYSBkeW5hbWljIG1haW47IHJlZnVzaW5nLiIpO2xldCBsZT1FdC5lbnY/Pz17fTtsZS5fX3N0YWNrX3BvaW50ZXIgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWx8fChsZS5fX3N0YWNrX3BvaW50ZXI9bmV3IFdlYkFzc2VtYmx5Lkdsb2JhbCh7dmFsdWU6ImkzMiIsbXV0YWJsZTohMH0sMCkpO2xldCBaPUY/Ri5leHBvcnRzOm51bGwsVmU9cigoRyxLKT0+KC4uLmdlKT0+e2xldCBJZT1qJiZqW0ddO2lmKHR5cGVvZiBJZSE9ImZ1bmN0aW9uIil7aWYoRz09PSJfX2h3anNfbGFuZV9pZCImJiFqKXJldHVybiBXcyhlLGx0KTt0aHJvdyBuZXcgRXJyb3IoYGh3anMtcnQ6ICR7S3x8InJ0In0gaW1wb3J0IGVudi4ke0d9IGlzIHVucmVzb2x2ZWQgXHUyMDE0IGArKGo/YHRoZSBtYWluIGltYWdlIGlzIGluc3RhbnRpYXRlZCBhbmQgZXhwb3J0cyBubyBmdW5jdGlvbiAiJHtHfSIsIHdoaWNoIGlzIGEgbGluayBkZWZlY3QgaW4gdGhlIG1haW4gaW1hZ2UgaXRzZWxmYDoidGhlIG1haW4gaW1hZ2UgaXMgTk9UIElOU1RBTlRJQVRFRCBZRVQsIHNvIHRoaXMgY2FsbCBjYW1lIGZyb20gYSBsb2FkLXRpbWUgY29uc3RydWN0b3Igb2YgdGhlIHJ1bnRpbWUsIGxpYmMuc28gb3IgYSBuZWVkZWQgbGlicmFyeSwgYW5kIHRoZSBtYWluJ3MgZXhwb3J0IHRhYmxlIGlzIG5vdCB0aGUgZmF1bHQiKSsiIChuZXZlci1zaWxlbnQpLiIpfXJldHVybiBJZSguLi5nZSl9LCJsYXRlR2VuZXJpYyIpLEdlPXIoKEcsSyk9PntsZXQgZ2U9VmUoRyxLKTtpZihHIT09Il9faHdqc19sYW5lX2lkIilyZXR1cm4gZ2U7d2F8fCh3YT1uZXcgV2ViQXNzZW1ibHkuTW9kdWxlKHp1KSk7bGV0IEllPW5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZSh3YSx7ZTp7ZjpnZX19KS5leHBvcnRzO3JldHVybiBFbi5wdXNoKEllKSxJZS5sYW5lfSwibGF0ZSIpLFFlPXIoKEcsSyxnZSk9PntpZihnZT09PSJmdW5jdGlvbiImJkc9PT0ibGludXgiJiZLPT09InN5c2NhbGwiKXtsZXQgSWU9RXQubGludXgmJkV0LmxpbnV4LnN5c2NhbGw7aWYodHlwZW9mIEllIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiaHdqcy1ydDogcnQgaW1wb3J0cyBsaW51eC5zeXNjYWxsIGJ1dCB0aGUgcHJvY2VzcyBpbXBvcnQgb2JqZWN0IGNhcnJpZXMgbm9uZSAobmV2ZXItc2lsZW50KS4iKTtyZXR1cm4gSWV9aWYoIShnZSE9PSJmdW5jdGlvbiJ8fEchPT0iZW52Iikpe2lmKEs9PT0iX19od2pzX3htb2RfZGlzcGF0Y2hfY2hlY2siKXJldHVybihJZSxSdCk9PlVzKEllLFJ0LCEwLCEwKTtpZihIcy5oYXMoSykpe2lmKFhuW0tdKXJldHVybiBYbltLXTtsZXQgSWU9Wj9aW0tdOnZvaWQgMDtpZih0eXBlb2YgSWU9PSJmdW5jdGlvbiIpcmV0dXJuIEllO3Rocm93IG5ldyBFcnJvcihgaHdqcy1ydDogcnQgaW1wb3J0IGVudi4ke0t9IGlzIEtFUk5FTC1vd25lZCBidXQgdm1saW51eCBkb2VzIG5vdCBleHBvcnQgaXQgKG5ldmVyLXNpbGVudCkuYCl9cmV0dXJuIElzLmhhcyhLKT8kcihLLCJ0aGUgaHdqcyBydW50aW1lIG1vZHVsZSAoIzApIik6R2UoSywidGhlIGh3anMgcnVudGltZSBtb2R1bGUgKCMwKSIpfX0sInJ0UmVzb2x2ZUltcG9ydCIpLGV0PXhzKGUubW9kZSkmJmx0JiZlLmRsb3BlbkZvcmsmJmUuZGxvcGVuRm9yay5od2pzUnR8fG51bGw7aWYoZXQpe2xldCBHPShldC50YWJsZUJhc2U+Pj4wKSsoZXQudGFibGVTaXplPj4+MCk7emUubGVuZ3RoPEcmJnplLmdyb3coRy16ZS5sZW5ndGgpfWxldCBJdD0wLFd0PTAsUGU9MCxLdD0wO2lmKCFldCl7aWYoZS5tb2RlPT09ImZvcmstcmVzdW1lIiYmbHQpdGhyb3cgbmV3IEVycm9yKCJod2pzLXJ0IChceEE3Ni40KTogZm9yay1yZXN1bWUgY2hpbGQgb2YgYSBydW50aW1lLWltcG9ydGluZyBtYWluIGNhcnJpZXMgbm8gZGxvcGVuRm9yay5od2pzUnQgcGxhY2VtZW50IFx1MjAxNCByZWZ1c2luZyBhIGZyZXNoIGNhcnZlIG92ZXIgdGhlIGNvcGllZCBhZGRyZXNzIHNwYWNlIChuZXZlci1zaWxlbnQpLiIpO2lmKGUubW9kZT09PSJtaWdyYXRlLXJlc3VtZSIpdGhyb3cgbmV3IEVycm9yKCJod2pzLXJ0IChceEE3Ni40KTogbWlncmF0ZS1yZXN1bWUgb2YgYSBydW50aW1lLWltcG9ydGluZyBtYWluIGNhcnJpZXMgbm8gZGxvcGVuRm9yay5od2pzUnQgcGxhY2VtZW50IHJlY29yZCBcdTIwMTQgcmVmdXNpbmcgYSBmcmVzaCBjYXJ2ZSBvdmVyIHRoZSBMSVZFIGFkZHJlc3Mgc3BhY2Ugb2YgYSB0YXNrIHRoYXQgaGFzIG5vdCBiZWVuIHJlbGVhc2VkIHlldCAobmV2ZXItc2lsZW50OyB0aGUgc291cmNlIGtlZXBzIGl0KS4iKTtpZihlLm1vZGU9PT0idGhyZWFkIil0aHJvdyBuZXcgRXJyb3IoImh3anMtcnQgKFx4QTc2LjQpOiB0aHJlYWQtbW9kZSBXb3JrZXIgb2YgYSBydW50aW1lLWltcG9ydGluZyBtYWluIGNhcnJpZXMgbm8gZGxvcGVuRm9yay5od2pzUnQgcGxhY2VtZW50IHJlY29yZCBcdTIwMTQgcmVmdXNpbmcgYSBmcmVzaCBjYXJ2ZSBvdmVyIHRoZSBwcm9jZXNzJ3MgTElWRSBzaGFyZWQgYWRkcmVzcyBzcGFjZSAodGhlIHRocmVhZC1zcGF3biBwbGFjZW1lbnQgcm91bmQtdHJpcCBkaWQgbm90IGRlbGl2ZXI7IG5ldmVyLXNpbGVudCkuIik7aWYoSXQ9Wm8oT3QpLGx0KXtpZih0eXBlb2YgZS5od2pzUnRXaW5kb3dCYXNlIT0ibnVtYmVyIil0aHJvdyBuZXcgRXJyb3IoImh3anMtcnQgKFx4QTc2LjQpOiB0aGUgbWFpbiBpbXBvcnRzIHRoZSBod2pzIHJ1bnRpbWUgYnV0IHRoaXMgaW5pdCBjYXJyaWVzIG5vIGh3anNSdFdpbmRvd0Jhc2UgXHUyMDE0IHRoZSBob3N0IHNwYXduIGhhbmRsZXIgZGlkIG5vdCByZXNlcnZlIHRoZSBydCB3aW5kb3cgKGhvc3Qvd29ya2VyIHZlcnNpb24gc2tldz8pOyByZWZ1c2luZyAobmV2ZXItc2lsZW50KS4iKTtpZihlLmh3anNSdFdpbmRvd0Jhc2U+Pj4wIT09SXR8fGUuaHdqc1J0V2luZG93U2l6ZT4+PjAhPT1Ncyl0aHJvdyBuZXcgRXJyb3IoYGh3anMtcnQgKFx4QTc2LjQpOiByZXNlcnZlZC13aW5kb3cgRElWRVJHRU5DRSBcdTIwMTQgaG9zdCBjb21wdXRlZCBiYXNlPTB4JHsoZS5od2pzUnRXaW5kb3dCYXNlPj4+MCkudG9TdHJpbmcoMTYpfSBzaXplPTB4JHsoZS5od2pzUnRXaW5kb3dTaXplPj4+MCkudG9TdHJpbmcoMTYpfSwgd29ya2VyIGRlcml2ZWQgYmFzZT0weCR7SXQudG9TdHJpbmcoMTYpfSBzaXplPTB4JHtNcy50b1N0cmluZygxNil9IFx1MjAxNCB0aGUgZHVwbGljYXRlZCBjb25zdGFudHMgKEJSS19SRVNFUlZFIC8gSFdKU19SVF9XSU5ET1dfU0laRSAvIHBhZ2Ugc2l6ZSkgZHJpZnRlZCBiZXR3ZWVuIGtlcm5lbFNwYXduSGFuZGxlci50cyBhbmQgZHluTG9hZGVyLm1qcyAobmV2ZXItc2lsZW50KS5gKX1LdD1JdCtNcz4+PjAsUGU9S3QtUW8+Pj4wLFd0PUl0LGUubWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoPEt0JiZFcihNYXRoLmNlaWwoS3QvNjU1MzYpKSxuZXcgVWludDhBcnJheShlLm1lbW9yeS5idWZmZXIsSXQsTXMpLmZpbGwoMCl9bGV0IFZ0PXIoKEcsSyk9PntsZXQgZ2U9TWF0aC5tYXgoSz4+PjB8fDEsMTYpLEllPVd0KyhnZS0xKSZ+KGdlLTEpLFJ0PUc+Pj4wO2lmKCEoSWU+PUl0KXx8SWUrUnQ+UGUpdGhyb3cgbmV3IEVycm9yKGBod2pzLXJ0IChceEE3Ni40KTogcnQgZGF0YSByZWdpb24gZG9lcyBOT1QgZml0IHRoZSByZXNlcnZlZCB3aW5kb3cgXHUyMDE0IG5lZWQgJHtSdH1CIChhbGlnbiAke2dlfSkgYXQgMHgke0llLnRvU3RyaW5nKDE2KX0sIHdpbmRvdyBbMHgke0l0LnRvU3RyaW5nKDE2KX0sIDB4JHtLdC50b1N0cmluZygxNil9KSBtaW51cyB0aGUgdG9wIDY1NTM2QiBydCBzaGFkb3ctc3RhY2sgY2FydmUgKHVzYWJsZSBlbmQgMHgke1BlLnRvU3RyaW5nKDE2KX0pLiBSYWlzZSBIV0pTX1JUX1dJTkRPV19TSVpFIChzcmMvZHluTG9hZGVyLm1qcyArIHNyYy9rZXJuZWxTcGF3bkhhbmRsZXIudHMsIGluIGxvY2tzdGVwKSAobmV2ZXItc2lsZW50IGZpdCBjaGVjaykuYCk7cmV0dXJuIFd0PUllK1J0LEllPj4+MH0sInJ0V2luQWxsb2MiKSxibj1ldD9ldC5zcFRvcD4+PjA6S3Q+Pj4wO2xlLl9fc3RhY2tfcG9pbnRlci52YWx1ZT1ibnwwLGRuPWxlLl9fc3RhY2tfcG9pbnRlcjtsZXQgeXQ9ZXQ/ZXQudGFibGVCYXNlOnplLmxlbmd0aCxfbj1ldD9ldC5tb2R1bGVJZHwwOlomJnR5cGVvZiBaLl9faHdqc19hbGxvY19tb2R1bGVfaWQ9PSJmdW5jdGlvbiI/Wi5fX2h3anNfYWxsb2NfbW9kdWxlX2lkKCl8MDowLEp0O0p0PUNzKHt3YXNtQnl0ZXM6QyxtZW1vcnk6ZS5tZW1vcnksdGFibGU6emUsbW9kdWxlSWQ6X24sc29QYXRoOiJ0aGUgaHdqcyBydW50aW1lIG1vZHVsZSAoIzApIixjb21waWxlTW9kdWxlOnIoKCk9PmllLCJjb21waWxlTW9kdWxlIiksLi4uRnQ9PT00P3ttYWluRHJpdmVBYmk6NCxtYWluTGFuZUFkZHJlc3NlZDpoZX06e30scmVzb2x2ZUltcG9ydDpRZSxyZXNvbHZlRGF0YUFkZHJlc3M6cigoKT0+e30sInJlc29sdmVEYXRhQWRkcmVzcyIpLGdvdEZ1bmNJbmRleDpjbixzdGFja1BvaW50ZXI6bGUuX19zdGFja19wb2ludGVyLHBhcmtJbXBvcnQ6cigoKT0+e30sInBhcmtJbXBvcnQiKSxkZWZlckdvdEZ1bmM6bmV3IFNldChbImh3anNfcmVzdW1lIiwiaHdqc19kb25lIiwiaHdqc19kZXN0cm95IiwiX19od2pzX2RyaXZlX2FiaSIsIl9faHdqc191c2VyX3BhcmsiXSksLi4uZXQ/e2ZpeGVkTWVtb3J5QmFzZTpldC5tZW1vcnlCYXNlPj4+MCxmaXhlZFRhYmxlQmFzZTpldC50YWJsZUJhc2U+Pj4wLHNraXBEYXRhUmVsb2NzOiEwLHNlZWRTeW1ib2xJbmRpY2VzOkFycmF5LmlzQXJyYXkoZXQuYXBwZW5kZWQpP2V0LmFwcGVuZGVkOltdfTp7YWxsb2NNZW1vcnk6VnR9fSksdG4oSnQpLGV0fHxKdC5ydW5DdG9ycygpLHJ0PUp0Lmluc3RhbmNlPz9KdCxQdD1KdCxDZT17bWVtb3J5QmFzZTpKdC5tZW1vcnlCYXNlPj4+MCx0YWJsZUJhc2U6eXQ+Pj4wLHRhYmxlU2l6ZTp6ZS5sZW5ndGgteXQ+Pj4wLG1vZHVsZUlkOl9ufDAsc3BUb3A6Ym4+Pj4wLGFwcGVuZGVkOkp0LnRhYmxlRW50cmllcygpfTtsZXQgZHQ9KEp0Lmluc3RhbmNlPz9KdCkuZXhwb3J0cztpZighKGUubW9kZT09PSJ0aHJlYWQifHwoZS5tb2RlPT09ImZvcmstcmVzdW1lInx8ZS5tb2RlPT09Im1pZ3JhdGUtcmVzdW1lIikmJmx0KSYmdHlwZW9mIGR0Ll9faHdqc19sYW5lX2F0dGFjaD09ImZ1bmN0aW9uIil7bGV0IEs9V3MoZSxsdCl8MDtpZighKHR5cGVvZiBkdC5fX2h3anNfbGFuZV9vY2N1cGllZD09ImZ1bmN0aW9uIj9kdC5fX2h3anNfbGFuZV9vY2N1cGllZChLKXwwOjApKXt0eXBlb2YgZHQuX193YXNtMzJfc2V0X2xhbmVfaWQ9PSJmdW5jdGlvbiImJmR0Ll9fd2FzbTMyX3NldF9sYW5lX2lkKEspO2xldCBJZT1kdC5fX2h3anNfbGFuZV9hdHRhY2goSyl8MDtpZihJZTw9MCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGFuZXM6IFBSRS1NQUlOIGxhbmUtJHtLfSBhdHRhY2ggUkVGVVNFRCAocmM9JHtJZX0pIG9uIHRoZSBydCBpbnN0YW5jZSBcdTIwMTQgLTExIGlzIG91dCBvZiBsYW5lIHNsb3RzLCAtMTIgb3V0IG9mIG1lbW9yeSBmb3IgbGFuZSBzdGF0ZS4gVGhlIG5lZWRlZC1ncmFwaCBjb25zdHJ1Y3RvcnMgcnVuIG5leHQgYW5kIGV2ZXJ5IGxhbmUta2V5ZWQgb3AgaW5zaWRlIHRoZW0gd291bGQgdmlvbGF0ZSBvbiBhbiB1bm9jY3VwaWVkIGxhbmUuIFJlZnVzaW5nIHRvIGRyaXZlIChuZXZlci1zaWxlbnQpLmApO249S319aWYoJCl7bGV0IEc9ZW4uZ2V0KCQuZGlnZXN0KTtHLm1vZHVsZXx8KEcubW9kdWxlPSRzKEcuYnl0ZXMsJC5kaWdlc3QpLm1vZHVsZSk7bGV0IEs7dHJ5e2lmKEs9aXIoRy5ieXRlcyksIUt8fEsubWFuaWZlc3RWZXJzaW9uPDJ8fCFLLnN1c3BlbmRlckRpZ2VzdExvNjQpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHN0YWdlZCBsaWJjLnNvIChkaWdlc3QgJHskLmRpZ2VzdC5zbGljZSgwLDE2KX1cdTIwMjYpIGNhcnJpZXMgbm8gdjIgaHdqcy5hYmkgc3VzcGVuZGVyLXBhcnRpdGlvbiBkaWdlc3QgXHUyMDE0IGFuIG9sZGVyIG9yIGZvcmVpZ24gYXJ0aWZhY3QgY2Fubm90IGJhY2sgYSBuZWVkZWQtbWFpbiAobmV2ZXItc2lsZW50KS5gKTtsZXQgY2U9JC5zdXNwZW5kZXJzU2hhMjU2LnNsaWNlKDAsMTYpO2lmKEsuc3VzcGVuZGVyRGlnZXN0TG82NCE9PWNlKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBTVVNQRU5ERVItUEFSVElUSU9OIERJR0VTVCBTS0VXIFx1MjAxNCB0aGUgbWFpbiB3YXMgbGlua2VkIGFnYWluc3QgcGFydGl0aW9uICR7Y2V9XHUyMDI2IGJ1dCB0aGUgc3RhZ2VkIGxpYmMuc28ncyBod2pzLmFiaSByZWNvcmRzICR7Sy5zdXNwZW5kZXJEaWdlc3RMbzY0fVx1MjAyNiAoYSBtYWluIGxpbmtlZCBhZ2FpbnN0IHBhcnRpdGlvbiBOIHJ1bm5pbmcgYWdhaW5zdCBsaWJjLnNvIE07IFBMQU4tRFlOQU1JQy1MSUJDIFx4QTczLjIpLiBSZWZ1c2luZyB0byBpbnN0YW50aWF0ZSAobmV2ZXItc2lsZW50KS5gKTtsZXQgYmU9ISEoSy5mbGFncyYmSy5mbGFncy5jaGVja0VtaXR0aW5nKTtpZihiZSE9PXduKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBDSEVDSy1FTUlUVElORyBNSVNNQVRDSCBcdTIwMTQgdGhlIG1haW4gYXR0ZXN0cyBjaGVja19lbWl0dGluZz0ke3duPzE6MH0gYnV0IHRoZSBzdGFnZWQgbGliYy5zbyAoZGlnZXN0ICR7JC5kaWdlc3Quc2xpY2UoMCwxNil9XHUyMDI2KSBhdHRlc3RzIGNoZWNrX2VtaXR0aW5nPSR7YmU/MTowfSAoaHdqcy5hYmkgZmxhZ3MgYml0NCkuIE1peGluZyBjaGVjay1lbWl0dGluZyBhbmQgbm9uLWNoZWNrLWVtaXR0aW5nIG1vZHVsZXMgbGV0cyBhIHN0YXR1cy1jaGFubmVsIHJhaXNlIHRyYW5zaXQgYW4gdW5pbnN0cnVtZW50ZWQgZnJhbWUgU0lMRU5UTFkgKFBMQU4tQ1hYLVNUQVRVUy1DSEFOTkVMIFx4QTc3LCBJMykuIFJlbGluayB0aGUgcGFpciBpbiBsb2Nrc3RlcCAobmV2ZXItc2lsZW50KS5gKTtsZXQgYnQ9ISEoSy5mbGFncyYmSy5mbGFncy5sYW5lQWRkcmVzc2VkKTtpZihidCE9PWhlKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBMQU5FLUFERFJFU1NFRCBNSVNNQVRDSCBcdTIwMTQgdGhlIG1haW4gYXR0ZXN0cyBsYW5lX2FkZHJlc3NlZD0ke2hlPzE6MH0gYnV0IHRoZSBzdGFnZWQgbGliYy5zbyAoZGlnZXN0ICR7JC5kaWdlc3Quc2xpY2UoMCwxNil9XHUyMDI2KSBhdHRlc3RzIGxhbmVfYWRkcmVzc2VkPSR7YnQ/MTowfSAoaHdqcy5hYmkgZmxhZ3MgYml0NSkuIE1peGluZyBhIGxhbmUtYWRkcmVzc2VkIG1vZHVsZSB3aXRoIGEgbGFuZS11bmF3YXJlIG9uZSBsZXRzIHRoZSBsYW5lLXVuYXdhcmUgc2lkZSByZWFkIExBTkUgMCdzIHN0YXR1cyB3b3JkIGZyb20gQU5ZIGxhbmUgXHUyMDE0IHNpbGVudCB0cmFuc2l0IHVuZGVyIHRocmVhZHMgKEkzLTI7IFBMQU4tVEhSRUFEUy1TSU5HTEUtTUVNT1JZIFx4QTc0IHN0ZXAgMikuIFJlbGluayB0aGUgcGFpciBpbiBsb2Nrc3RlcCAobmV2ZXItc2lsZW50KS5gKX1jYXRjaChjZSl7aWYoYXdhaXQgdSgiTElCQy1TVEFHRSIsY2UpPT09InJldHVybiIpeyRuKCJlcnJvciIpO3JldHVybn1icmVhayBlfWxldCBnZT14cyhlLm1vZGUpJiZsdCYmZS5kbG9wZW5Gb3JrJiZlLmRsb3BlbkZvcmsubGliY1NvfHxudWxsO2dlJiZCbChnZSwkLmRpZ2VzdCk7bGV0IEllPTAsUnQ9MCxYdD0wO2lmKGdlKXtsZXQgY2U9KGdlLnRhYmxlQmFzZT4+PjApKyhnZS50YWJsZVNpemU+Pj4wKTt6ZS5sZW5ndGg8Y2UmJnplLmdyb3coY2UtemUubGVuZ3RoKX1lbHNle2lmKGUubW9kZT09PSJmb3JrLXJlc3VtZSImJmx0KXRocm93IG5ldyBFcnJvcigiaHdqcy1saWJjOiBmb3JrLXJlc3VtZSBjaGlsZCBvZiBhIGxpYmMuc28tbmVlZGluZyBtYWluIGNhcnJpZXMgbm8gZGxvcGVuRm9yay5saWJjU28gcGxhY2VtZW50IFx1MjAxNCByZWZ1c2luZyBhIGZyZXNoIGNhcnZlIG92ZXIgdGhlIGNvcGllZCBhZGRyZXNzIHNwYWNlICh0aGUgZGVsdGEgY29weSBob2xkcyBsaXZlIGxpYmMuc28gZGF0YTsgbmV2ZXItc2lsZW50KS4iKTtpZihlLm1vZGU9PT0ibWlncmF0ZS1yZXN1bWUiKXRocm93IG5ldyBFcnJvcigiaHdqcy1saWJjOiBtaWdyYXRlLXJlc3VtZSBvZiBhIGxpYmMuc28tbmVlZGluZyBtYWluIGNhcnJpZXMgbm8gZGxvcGVuRm9yay5saWJjU28gcGxhY2VtZW50IHJlY29yZCBcdTIwMTQgcmVmdXNpbmcgYSBmcmVzaCBjYXJ2ZSBvdmVyIHRoZSBMSVZFIGFkZHJlc3Mgc3BhY2Ugb2YgYSB0YXNrIHRoYXQgaGFzIG5vdCBiZWVuIHJlbGVhc2VkIHlldCAobmV2ZXItc2lsZW50KS4iKTtpZihlLm1vZGU9PT0idGhyZWFkIil0aHJvdyBuZXcgRXJyb3IoImh3anMtbGliYzogdGhyZWFkLW1vZGUgV29ya2VyIG9mIGEgbGliYy5zby1uZWVkaW5nIG1haW4gY2FycmllcyBubyBkbG9wZW5Gb3JrLmxpYmNTbyBwbGFjZW1lbnQgcmVjb3JkIFx1MjAxNCByZWZ1c2luZyBhIGZyZXNoIGNhcnZlIG92ZXIgdGhlIHByb2Nlc3MncyBMSVZFIHNoYXJlZCBhZGRyZXNzIHNwYWNlIChuZXZlci1zaWxlbnQpLiIpO2lmKEllPU1sKE90KSxsdCl7aWYodHlwZW9mIGUuaHdqc0xpYmNXaW5kb3dCYXNlIT0ibnVtYmVyIil0aHJvdyBuZXcgRXJyb3IoImh3anMtbGliYzogdGhlIG1haW4gbmVlZHMgbGliYy5zbyBidXQgdGhpcyBpbml0IGNhcnJpZXMgbm8gaHdqc0xpYmNXaW5kb3dCYXNlIFx1MjAxNCB0aGUgaG9zdCBzcGF3biBoYW5kbGVyIGRpZCBub3QgcmVzZXJ2ZSB0aGUgbGliYyB3aW5kb3cgKGhvc3Qvd29ya2VyIHZlcnNpb24gc2tldz8pOyByZWZ1c2luZyAobmV2ZXItc2lsZW50KS4iKTtpZihlLmh3anNMaWJjV2luZG93QmFzZT4+PjAhPT1JZXx8ZS5od2pzTGliY1dpbmRvd1NpemU+Pj4wIT09b3IpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHJlc2VydmVkLXdpbmRvdyBESVZFUkdFTkNFIFx1MjAxNCBob3N0IGNvbXB1dGVkIGJhc2U9MHgkeyhlLmh3anNMaWJjV2luZG93QmFzZT4+PjApLnRvU3RyaW5nKDE2KX0gc2l6ZT0weCR7KGUuaHdqc0xpYmNXaW5kb3dTaXplPj4+MCkudG9TdHJpbmcoMTYpfSwgd29ya2VyIGRlcml2ZWQgYmFzZT0weCR7SWUudG9TdHJpbmcoMTYpfSBzaXplPTB4JHtvci50b1N0cmluZygxNil9IFx1MjAxNCB0aGUgZHVwbGljYXRlZCBjb25zdGFudHMgZHJpZnRlZCBiZXR3ZWVuIGtlcm5lbFNwYXduSGFuZGxlci50cyBhbmQgZHluTG9hZGVyLm1qcyAobmV2ZXItc2lsZW50KS5gKX1YdD1JZStvcj4+PjAsUnQ9SWUsZS5tZW1vcnkuYnVmZmVyLmJ5dGVMZW5ndGg8WHQmJkVyKE1hdGguY2VpbChYdC82NTUzNikpLG5ldyBVaW50OEFycmF5KGUubWVtb3J5LmJ1ZmZlcixJZSxvcikuZmlsbCgwKX1sZXQgQm49cigoY2UsYmUpPT57bGV0IGJ0PU1hdGgubWF4KGJlPj4+MHx8MSwxNikscHQ9UnQrKGJ0LTEpJn4oYnQtMSksWGU9Y2U+Pj4wO2lmKCEocHQ+PUllKXx8cHQrWGU+WHQpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IGxpYmMuc28gZGF0YSByZWdpb24gZG9lcyBOT1QgZml0IHRoZSByZXNlcnZlZCB3aW5kb3cgXHUyMDE0IG5lZWQgJHtYZX1CIChhbGlnbiAke2J0fSkgYXQgMHgke3B0LnRvU3RyaW5nKDE2KX0sIHdpbmRvdyBbMHgke0llLnRvU3RyaW5nKDE2KX0sIDB4JHtYdC50b1N0cmluZygxNil9KS4gUmFpc2UgSFdKU19MSUJDX1dJTkRPV19TSVpFIChzcmMvZHluTG9hZGVyLm1qcyArIHNyYy9rZXJuZWxTcGF3bkhhbmRsZXIudHMsIGluIGxvY2tzdGVwKSAobmV2ZXItc2lsZW50IGZpdCBjaGVjaykuYCk7cmV0dXJuIFJ0PXB0K1hlLHB0Pj4+MH0sImxpYmNXaW5BbGxvYyIpLGF0PW5ldyBTZXQoV2ViQXNzZW1ibHkuTW9kdWxlLmV4cG9ydHMoRy5tb2R1bGUpLmZpbHRlcihjZT0+Y2Uua2luZD09PSJmdW5jdGlvbiIpLm1hcChjZT0+Y2UubmFtZSkpLEZuPW5ldyBTZXQoV2ViQXNzZW1ibHkuTW9kdWxlLmV4cG9ydHMocCkuZmlsdGVyKGNlPT5jZS5raW5kPT09ImZ1bmN0aW9uIikubWFwKGNlPT5jZS5uYW1lKSkscXQ9bnVsbCx2ZT1yKGNlPT57bGV0IGJlPUZuLmhhcyhjZSk/Im1haW4iOmF0LmhhcyhjZSk/InNlbGYiOm51bGw7aWYoIWJlKXtpZihxdD8/PShMcyhHLmJ5dGVzKXx8e30pLndlYWtJbXBvcnRzfHxuZXcgTWFwLHF0LmdldChjZSk9PT0iZW52IilyZXR1cm47dGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHVucmVzb2x2ZWQgaW1wb3J0IGVudi4ke2NlfSAoZnVuY3Rpb24pIGluIGxpYmMuc28gKG1vZHVsZSAjMSkgXHUyMDE0IHRoZSBydW50aW1lIChtb2R1bGUgIzApIGRvZXMgbm90IGV4cG9ydCBpdCwgdGhlIG1haW4gaW1hZ2UgZG9lcyBub3QgZXhwb3J0IGl0LCBhbmQgbGliYy5zbyBkb2VzIG5vdCBkZWZpbmUgaXQgZWl0aGVyLCBzbyBOT1RISU5HIGluIHRoaXMgcHJvY2VzcyBjYW4gZXZlciBwcm92aWRlIGl0LiBSZWZ1c2luZyB0aGUgbG9hZCAobmV2ZXItc2lsZW50KTogdGhlIGFsdGVybmF0aXZlIGlzIGEgYmluZGluZyB0aGF0IHRocm93cyBhdCB3aGF0ZXZlciBndWVzdCBjYWxsIHNpdGUgcmVhY2hlcyBpdCBmaXJzdCwgd2hpY2ggaXMgd2hlcmUgdGhpcyBjbGFzcyB1c2VkIHRvIHN1cmZhY2UuYCl9bGV0IGJ0PW51bGwscHQ9cigoKT0+e2xldCBYZT1iZT09PSJtYWluIj9qfHxudWxsOmVlPyhlZS5pbnN0YW5jZT8/ZWUpLmV4cG9ydHM6bnVsbCx6dD1YZT9YZVtjZV06dm9pZCAwO2lmKHR5cGVvZiB6dCE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogbGliYy5zbydzIHByZWVtcHRpYmxlIGltcG9ydCBlbnYuJHtjZX0gd2FzIHJlc29sdmVkIGF0IGxvYWQgdG8gdGhlICR7YmU9PT0ibWFpbiI/Ik1BSU4gaW1hZ2UiOiJsaWJjLnNvIHNlbGYtZGVmaW5pdGlvbiJ9IChFTEYgc2VhcmNoIG9yZGVyKSwgYnV0IHRoYXQgcHJvdmlkZXIgaGFzIG5vIGZ1bmN0aW9uIGV4cG9ydCAiJHtjZX0iIG5vdyB0aGF0IGl0IGV4aXN0cyBcdTIwMTQgdGhlIGxvYWQtdGltZSBjZW5zdXMgYW5kIHRoZSBsaXZlIGluc3RhbmNlIGRpc2FncmVlIChuZXZlci1zaWxlbnQpLmApO3JldHVybiB6dH0sInByb3ZpZGVyIik7cmV0dXJuIGZ1bmN0aW9uKFhlLHp0LE4sdWUsWSxUZSxxZSl7bGV0IEtlPWJ0fHwoYnQ9cHQoKSk7c3dpdGNoKGFyZ3VtZW50cy5sZW5ndGgpe2Nhc2UgMDpyZXR1cm4gS2UoKTtjYXNlIDE6cmV0dXJuIEtlKFhlKTtjYXNlIDI6cmV0dXJuIEtlKFhlLHp0KTtjYXNlIDM6cmV0dXJuIEtlKFhlLHp0LE4pO2Nhc2UgNDpyZXR1cm4gS2UoWGUsenQsTix1ZSk7Y2FzZSA1OnJldHVybiBLZShYZSx6dCxOLHVlLFkpO2Nhc2UgNjpyZXR1cm4gS2UoWGUsenQsTix1ZSxZLFRlKTtjYXNlIDc6cmV0dXJuIEtlKFhlLHp0LE4sdWUsWSxUZSxxZSk7ZGVmYXVsdDpyZXR1cm4gS2UuYXBwbHkobnVsbCxhcmd1bWVudHMpfX19LCJsaWJjUHJlZW1wdGlibGVQcm92aWRlciIpLHllPXIoKGNlLGJlLGJ0KT0+e2lmKGJ0PT09ImZ1bmN0aW9uIiYmY2U9PT0ibGludXgiJiZiZT09PSJzeXNjYWxsIil7bGV0IHB0PUV0LmxpbnV4JiZFdC5saW51eC5zeXNjYWxsO2lmKHR5cGVvZiBwdCE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoImh3anMtbGliYzogbGliYy5zbyBpbXBvcnRzIGxpbnV4LnN5c2NhbGwgYnV0IHRoZSBwcm9jZXNzIGltcG9ydCBvYmplY3QgY2FycmllcyBub25lIChuZXZlci1zaWxlbnQpLiIpO3JldHVybiBwdH1pZighKGJ0IT09ImZ1bmN0aW9uInx8Y2UhPT0iZW52Iikpe2lmKEhzLmhhcyhiZSkpe2lmKFhuW2JlXSlyZXR1cm4gWG5bYmVdO2xldCBwdD1aP1pbYmVdOnZvaWQgMDtpZih0eXBlb2YgcHQ9PSJmdW5jdGlvbiIpcmV0dXJuIHB0O3Rocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBsaWJjLnNvIGltcG9ydCBlbnYuJHtiZX0gaXMgS0VSTkVMLW93bmVkIGJ1dCB2bWxpbnV4IGRvZXMgbm90IGV4cG9ydCBpdCAobmV2ZXItc2lsZW50KS5gKX1yZXR1cm4gYmU9PT0iX19od2pzX3htb2RfZGlzcGF0Y2hfY2hlY2siPyhwdCxYZSk9PlVzKHB0LFhlLCEwKTpiZT09PSJfX2h3anNfbGFuZV9pZCI/R2UoYmUsImxpYmMuc28gKG1vZHVsZSAjMSkiKTpJcy5oYXMoYmUpPyRyKGJlLCJsaWJjLnNvIChtb2R1bGUgIzEpIik6dHlwZW9mIGR0W2JlXT09ImZ1bmN0aW9uIj9MKGJlLGR0W2JlXSk6dmUoYmUpfX0sImxpYmNSZXNvbHZlSW1wb3J0IiksUmU9Z2U/Z2UudGFibGVCYXNlPj4+MDp6ZS5sZW5ndGgsRWU9Z2U/Z2UubW9kdWxlSWR8MDpaJiZ0eXBlb2YgWi5fX2h3anNfYWxsb2NfbW9kdWxlX2lkPT0iZnVuY3Rpb24iP1ouX19od2pzX2FsbG9jX21vZHVsZV9pZCgpfDA6MCxXZTtXZT1Dcyh7d2FzbUJ5dGVzOkcuYnl0ZXMsbWVtb3J5OmUubWVtb3J5LHRhYmxlOnplLG1vZHVsZUlkOkVlLHNvUGF0aDoibGliYy5zbyAobW9kdWxlICMxKSIsY29tcGlsZU1vZHVsZTpyKCgpPT5HLm1vZHVsZSwiY29tcGlsZU1vZHVsZSIpLG1haW5MYW5lQWRkcmVzc2VkOmhlLC4uLkZ0PT09M3x8RnQ9PT00P3ttYWluRHJpdmVBYmk6RnR9Ont9LHN0YXR1c0NoYW5uZWxBZGRyOigoKT0+e2xldCBjZT1kdD9kdC5fX2h3anNfc3RhdHVzX2NoYW5uZWw6dm9pZCAwO2lmKCEoY2UgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWwpfHwhQ2UpcmV0dXJuO2xldCBiZT1XcyhlLGx0KSxidD0oKENlLm1lbW9yeUJhc2U+Pj4wKSsoY2UudmFsdWV8MCkrYmUqMzJ8MCk+Pj4wO2lmKE1uKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbY2hhbi1hZGRyIGxpYmNdIG1vZGU9JHtlLm1vZGV9IGxhbmU9JHtiZX0gYmFzZT0weCR7KENlLm1lbW9yeUJhc2U+Pj4wKS50b1N0cmluZygxNil9KzB4JHsoY2UudmFsdWV8MCkudG9TdHJpbmcoMTYpfSBhZGRyPTB4JHtidC50b1N0cmluZygxNil9YH0pfWNhdGNoe31yZXR1cm4gYnR9KSgpLHJlc29sdmVJbXBvcnQ6eWUscmVzb2x2ZURhdGFBZGRyZXNzOnIoY2U9PntsZXQgYmU9ZHQ/ZHRbY2VdOnZvaWQgMDtpZihiZSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbCYmQ2UpcmV0dXJuKChDZS5tZW1vcnlCYXNlPj4+MCkrKGJlLnZhbHVlfDApfDApPj4+MH0sInJlc29sdmVEYXRhQWRkcmVzcyIpLGludGVycG9zZURhdGFBZGRyZXNzOigoKT0+e2xldCBjZT1udWxsO3JldHVybiBiZT0+KGNlfHwoY2U9dmwoT3QpKSxBbChiZSxjZSkpfSkoKSxnb3RGdW5jSW5kZXg6Y24sc3RhY2tQb2ludGVyOmxlLl9fc3RhY2tfcG9pbnRlcixwYXJrSW1wb3J0OnIoKCk9Pnt9LCJwYXJrSW1wb3J0IiksdGxzT3duZXI6ITAsZGVmZXJHb3RGdW5jOm5ldyBTZXQoWyJmcmVlYSIsImh3anNfcmVzdW1lIiwiaHdqc19kb25lIiwiaHdqc19kZXN0cm95IiwiX19od2pzX2RyaXZlX2FiaSIsIl9faHdqc191c2VyX3BhcmsiLCJfX3dhc20zMl9zZXRfdGxzX2Jhc2UiLCJfX3dhc21faW5pdF90bHMiLCJfX3dhc20zMl9nZXRfdGxzX3NpemUiLCJfX3dhc20zMl9nZXRfdGxzX2FsaWduIiwiX193YXNtMzJfc2V0X3N0YWNrX3BvaW50ZXIiLCJfX2h3anNfbGFuZV9pZCJdKSwuLi5nZT97Zml4ZWRNZW1vcnlCYXNlOmdlLm1lbW9yeUJhc2U+Pj4wLGZpeGVkVGFibGVCYXNlOmdlLnRhYmxlQmFzZT4+PjAsc2tpcERhdGFSZWxvY3M6ITAsc2VlZFN5bWJvbEluZGljZXM6QXJyYXkuaXNBcnJheShnZS5hcHBlbmRlZCk/Z2UuYXBwZW5kZWQ6W119OnthbGxvY01lbW9yeTpCbn19KSx0bihXZSksZ2V8fChLJiZLLmZsYWdzJiZLLmZsYWdzLnVzZXNUbHM/ST0hMDpXZS5ydW5DdG9ycygpKSxlZT1XZSxNZT17ZGlnZXN0OiQuZGlnZXN0LHN1c3BlbmRlckRpZ2VzdExvNjQ6Sy5zdXNwZW5kZXJEaWdlc3RMbzY0LGNoZWNrRW1pdHRpbmc6ISEoSy5mbGFncyYmSy5mbGFncy5jaGVja0VtaXR0aW5nKSxsYW5lQWRkcmVzc2VkOiEhKEsuZmxhZ3MmJksuZmxhZ3MubGFuZUFkZHJlc3NlZCksbWVtb3J5QmFzZTpXZS5tZW1vcnlCYXNlPj4+MCx0YWJsZUJhc2U6UmU+Pj4wLHRhYmxlU2l6ZTp6ZS5sZW5ndGgtUmU+Pj4wLG1vZHVsZUlkOkVlfDAsYXBwZW5kZWQ6V2UudGFibGVFbnRyaWVzKCl9O3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLWxpYmM6IG1vZHVsZSAjMSBpbnN0YW50aWF0ZWQgKGxpYmMuc28uJHskLmRpZ2VzdC5zbGljZSgwLDE2KX1cdTIwMjYgbW9kdWxlSWQ9JHtFZX0gbWVtb3J5QmFzZT0weCR7TWUubWVtb3J5QmFzZS50b1N0cmluZygxNil9IHRhYmxlQmFzZT0ke1JlfSR7Z2U/IiBmb3JrLXJlcGxheSI6IiJ9KSBcdTIwMTQgbGliYyBwcm92aWRlciBpcyB0aGUgc2hhcmVkIG1vZHVsZWB9KX1jYXRjaHt9aWYoV2UuaW50ZXJwb3NlZERhdGEmJldlLmludGVycG9zZWREYXRhLmxlbmd0aCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1saWJjOiBsaWJjLnNvIHJlYWRzIHRoZSBtYWluJ3MgJHtXZS5pbnRlcnBvc2VkRGF0YS5qb2luKCIsICIpfWB9KX1jYXRjaHt9fWxldCBEdD1lZT8oZWUuaW5zdGFuY2U/P2VlKS5leHBvcnRzOm51bGwsY3Q9W10sUG49bnVsbCxRdD0iIjtpZih2Lmxlbmd0aCl7dHJ5e2xldCBHPVdlYkFzc2VtYmx5Lk1vZHVsZS5leHBvcnRzKHApLnNvbWUoTj0+Ti5raW5kPT09ImZ1bmN0aW9uIiYmTi5uYW1lPT09Il9fd2FzbTMyX25lZWRlZF9jdG9yc19pbl9zdGFydCIpLEs9bmV3IFNldChXZWJBc3NlbWJseS5Nb2R1bGUuZXhwb3J0cyhwKS5maWx0ZXIoTj0+Ti5raW5kPT09ImZ1bmN0aW9uIikubWFwKE49Pk4ubmFtZSkpLGdlPW5ldyBNYXA7Zm9yKGxldCBOIG9mIHYpe2xldCB1ZT1lbi5nZXQoTi5kaWdlc3QpO3VlLm1vZHVsZXx8KHVlLm1vZHVsZT0kcyh1ZS5ieXRlcyxOLmRpZ2VzdCkubW9kdWxlKSxnZS5zZXQoTi5pbmRleCxuZXcgU2V0KFdlYkFzc2VtYmx5Lk1vZHVsZS5leHBvcnRzKHVlLm1vZHVsZSkuZmlsdGVyKFk9Plkua2luZD09PSJmdW5jdGlvbiIpLm1hcChZPT5ZLm5hbWUpKSl9bGV0IEllPW5ldyBNYXAsUnQ9bmV3IE1hcCxYdD1uZXcgTWFwKHYubWFwKE49PltOLmluZGV4LE5dKSksQm49bmV3IE1hcCh2Lm1hcCgoTix1ZSk9PltOLmluZGV4LHVlXSkpLGF0PXIoKE4sdWUsWSk9PlNsKFksTi5nZXQoWSksdWUuaW5kZXgsQm4pLCJzb0VhcmxpZXIiKTtmb3IobGV0IE4gb2Ygdil7bGV0IHVlPWVuLmdldChOLmRpZ2VzdCk7Zm9yKGxldCBZIG9mIFdlYkFzc2VtYmx5Lk1vZHVsZS5leHBvcnRzKHVlLm1vZHVsZSkpe2xldCBUZT1ZLmtpbmQ9PT0iZnVuY3Rpb24iP0llOlkua2luZD09PSJnbG9iYWwiP1J0Om51bGw7VGUmJiFUZS5oYXMoWS5uYW1lKSYmVGUuc2V0KFkubmFtZSxOLmluZGV4KX19bGV0IEZuPW5ldyBNYXAscXQ9cigoTix1ZSk9PntsZXQgWT1Ycyg5LDAsdWV8MCwzLDM0LC0xLDApfDA7aWYoWTw9MCl0aHJvdyBuZXcgRXJyb3IoYGh3anMtbGliYzogU1lTX21tYXAgZm9yICR7Tn0ncyBkYXRhIHJlZ2lvbiAoJHt1ZX1CKSByZXR1cm5lZCAke1l9IFx1MjAxNCB0aGUgbmVlZGVkIGxpYnJhcnkgY2Fubm90IGJlIHBsYWNlZCAobmV2ZXItc2lsZW50IE9PTSkuYCk7cmV0dXJuIFk+Pj4wfSwic29NbWFwV2luZG93IiksdmU9bmV3IE1hcCx5ZT1yKE49PntpZih2ZS5oYXMoTikpcmV0dXJuIHZlLmdldChOKTtsZXQgdWU9WHQuZ2V0KE4pLFk9dWU/ZW4uZ2V0KHVlLmRpZ2VzdCk6bnVsbDtpZighWSlyZXR1cm4gMDtsZXQgVGU9THMoWS5ieXRlcykscWU9VGU/VGUubWVtb3J5U2l6ZXwwOjAsS2U9VGU/VGUubWVtb3J5QWxpZ258MDoxLGh0PUtlPjA/S2U6MSx3dD1xZT4wP3F0KHVlLnNvbmFtZSwocWUraHQtMSZ+KGh0LTEpKT4+PjApOjA7dmUuc2V0KE4sd3QpO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLWxpYmM6IHByZS1wbGFjZWQgbmVlZGVkIGVudHJ5ICR7Tn0gKCR7dWUuc29uYW1lfSkgYXQgbWVtb3J5QmFzZT0weCR7d3QudG9TdHJpbmcoMTYpfSBcdTIwMTQgYSBzaWJsaW5nJ3MgR09ULm1lbSBuYW1lcyBpdHMgZGF0YSBhbmQgYSBkYXRhIGFkZHJlc3MgY2Fubm90IGJlIGJvdW5kIGxhdGVgfSl9Y2F0Y2h7fXJldHVybiB3dH0sInNvUHJlYWxsb2NCYXNlIiksUmU9bmV3IE1hcCxFZT1uZXcgTWFwLFdlPW5ldyBNYXAsY2U9cigoTix1ZSk9PntsZXQgWT1XZS5nZXQoTik7aWYoIVkpe2xldCBUZT1YdC5nZXQoTikscWU9VGU/ZW4uZ2V0KFRlLmRpZ2VzdCk6bnVsbDtZPXFlP3hsKHFlLmJ5dGVzKTpuZXcgTWFwLFdlLnNldChOLFkpfXJldHVybiBZLmdldCh1ZSl9LCJzb0V4cG9ydEZuSW5kZXgiKSxiZT1yKChOLHVlLFkpPT57bGV0IFRlPUZuLmdldCh1ZSk7aWYoVGUpe2xldCAkdD1UZS5kbHN5bShZKT4+PjA7aWYoISgkdD4wKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiAke04uc29uYW1lfSAobmVlZGVkIGVudHJ5ICR7Ti5pbmRleH0pIHRha2VzIHRoZSBhZGRyZXNzIG9mICIke1l9Iiwgd2hpY2ggbmVlZGVkIGVudHJ5ICR7dWV9IGV4cG9ydHMsIGJ1dCBpdCBoYXMgbm8gdGFibGUgc2xvdCBmb3IgaXQgKG5ldmVyLXNpbGVudCkuYCk7cmV0dXJuICR0fWxldCBxZT1SZS5nZXQodWUpO2lmKHFlfHxSZS5zZXQodWUscWU9bmV3IE1hcCkscWUuaGFzKFkpKXJldHVybiBxZS5nZXQoWSk7bGV0IEtlPUVlLmdldCh1ZSk7S2V8fEVlLnNldCh1ZSxLZT1uZXcgTWFwKTtsZXQgaHQ9Y2UodWUsWSk7aWYoaHQhPT12b2lkIDAmJktlLmhhcyhodCkpe2xldCAkdD1LZS5nZXQoaHQpO3JldHVybiBxZS5zZXQoWSwkdCksJHR9bGV0IHd0PXplLmxlbmd0aDt6ZS5ncm93KDEpLHFlLnNldChZLHd0KSxodCE9PXZvaWQgMCYmS2Uuc2V0KGh0LHd0KTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1saWJjOiByZXNlcnZlZCB0YWJsZSBzbG90ICR7d3R9IGZvciAiJHtZfSIgb2YgbmVlZGVkIGVudHJ5ICR7dWV9IFx1MjAxNCAke04uc29uYW1lfSAobmVlZGVkIGVudHJ5ICR7Ti5pbmRleH0pIHRha2VzIGl0cyBhZGRyZXNzIGJlZm9yZSBpdCBpcyBwbGFjZWRgfSl9Y2F0Y2h7fXJldHVybiB3dH0sInNvU2libGluZ0ZuU2xvdCIpLGJ0PXIoKE4sdWUsWSk9PntsZXQgVGU9bnVsbCxxZT1yKCgpPT57bGV0IEtlPXR5cGVvZiBZPT0ibnVtYmVyIj9ZOk4uaW5kZXg7aWYodHlwZW9mIFk9PSJudW1iZXIiJiYhRm4uaGFzKEtlKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiAke04uc29uYW1lfSAobmVlZGVkIGVudHJ5ICR7Ti5pbmRleH0pIGNhbGxlZCBlbnYuJHt1ZX0gZnJvbSBhIENPTlNUUlVDVE9SLCBidXQgaXRzIHByb3ZpZGVyIChuZWVkZWQgZW50cnkgJHtLZX0pIGlzIG5vdCBpbnN0YW50aWF0ZWQgeWV0IC0tIGEgc2libGluZyBiaW5kaW5nIGlzIGxhdGUgYnkgY29uc3RydWN0aW9uIGFuZCBjYW5ub3QgYmUgY29tcGxldGVkIGJlZm9yZSB0aGUgZW50cnkgdGhhdCBvd25zIGl0IGlzIHBsYWNlZC4gUmVmdXNpbmcgcmF0aGVyIHRoYW4gYmluZGluZyBhIGhvbGUgKG5ldmVyLXNpbGVudCkuYCk7bGV0IGh0PVk9PT0ibWFpbiI/anx8bnVsbDooKCk9PntsZXQgJHQ9Rm4uZ2V0KEtlKTtyZXR1cm4gJHQ/KCR0Lmluc3RhbmNlPz8kdCkuZXhwb3J0czpudWxsfSkoKSx3dD1odD9odFt1ZV06dm9pZCAwO2lmKHR5cGVvZiB3dCE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiAke04uc29uYW1lfSAobmVlZGVkIGVudHJ5ICR7Ti5pbmRleH0pIGltcG9ydGVkIGVudi4ke3VlfSwgcmVzb2x2ZWQgYXQgbG9hZCB0byAke1k9PT0ibWFpbiI/InRoZSBNQUlOIGltYWdlIjp0eXBlb2YgWT09Im51bWJlciI/YG5lZWRlZCBlbnRyeSAke1l9YDoidGhlIGxpYnJhcnkncyBvd24gZGVmaW5pdGlvbiJ9IChFTEYgc2VhcmNoIG9yZGVyKSwgYnV0IHRoYXQgcHJvdmlkZXIgZXhwb3J0cyBubyBmdW5jdGlvbiAiJHt1ZX0iIG5vdyB0aGF0IGl0IGlzIGNhbGxlZCAobmV2ZXItc2lsZW50KS5gKTtyZXR1cm4gd3R9LCJwcm92aWRlciIpO3JldHVybiBmdW5jdGlvbihLZSxodCx3dCwkdCxlcyxncyxEcyl7bGV0IGhuPVRlfHwoVGU9cWUoKSk7c3dpdGNoKGFyZ3VtZW50cy5sZW5ndGgpe2Nhc2UgMDpyZXR1cm4gaG4oKTtjYXNlIDE6cmV0dXJuIGhuKEtlKTtjYXNlIDI6cmV0dXJuIGhuKEtlLGh0KTtjYXNlIDM6cmV0dXJuIGhuKEtlLGh0LHd0KTtjYXNlIDQ6cmV0dXJuIGhuKEtlLGh0LHd0LCR0KTtjYXNlIDU6cmV0dXJuIGhuKEtlLGh0LHd0LCR0LGVzKTtjYXNlIDY6cmV0dXJuIGhuKEtlLGh0LHd0LCR0LGVzLGdzKTtjYXNlIDc6cmV0dXJuIGhuKEtlLGh0LHd0LCR0LGVzLGdzLERzKTtkZWZhdWx0OnJldHVybiBobi5hcHBseShudWxsLGFyZ3VtZW50cyl9fX0sInNvTGF0ZUJpbmQiKSxwdD1yKChOLHVlKT0+e2lmKEsuaGFzKHVlKSlyZXR1cm4ibWFpbiI7bGV0IFk9YXQoSWUsTix1ZSk7aWYoWSE9PXZvaWQgMClyZXR1cm4gWTtsZXQgVGU9Z2UuZ2V0KE4uaW5kZXgpO2lmKFRlJiZUZS5oYXModWUpKXJldHVybiJzZWxmIjtsZXQgcWU9SWUuZ2V0KHVlKTtyZXR1cm4gcWUhPT12b2lkIDAmJnFlIT09Ti5pbmRleD9xZTpudWxsfSwic29UaWVyRm9yIiksWGU9bmV3IE1hcCx6dD1yKChOLHVlKT0+e2xldCBZPXB0KE4sdWUpO2lmKCFZKXtsZXQgVGU9WGUuZ2V0KE4uaW5kZXgpO2lmKCFUZSl7bGV0IHFlPWVuLmdldChOLmRpZ2VzdCk7VGU9cWUmJihMcyhxZS5ieXRlcyl8fHt9KS53ZWFrSW1wb3J0c3x8bmV3IE1hcCxYZS5zZXQoTi5pbmRleCxUZSl9aWYoVGUuZ2V0KHVlKT09PSJlbnYiKXJldHVybjt0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiB1bnJlc29sdmVkIGltcG9ydCBlbnYuJHt1ZX0gKGZ1bmN0aW9uKSBpbiAiJHtOLnNvbmFtZX0gKG5lZWRlZCBlbnRyeSAke04uaW5kZXh9KSIgLS0gdGhlIHJ1bnRpbWUgKG1vZHVsZSAjMCkgZG9lcyBub3QgZXhwb3J0IGl0LCBsaWJjLnNvIChtb2R1bGUgIzEpIGRvZXMgbm90IGV4cG9ydCBpdCwgdGhlIG1haW4gaW1hZ2UgZG9lcyBub3QgZXhwb3J0IGl0LCAke04uc29uYW1lfSBkb2VzIG5vdCBkZWZpbmUgaXQgZWl0aGVyLCBhbmQgbm8gT1RIRVIgbmVlZGVkIGVudHJ5IG9mIHRoaXMgbWFpbiBleHBvcnRzIGl0LCBzbyBOT1RISU5HIGluIHRoaXMgcHJvY2VzcyBjYW4gZXZlciBwcm92aWRlIGl0LiBSZWZ1c2luZyB0aGUgbG9hZCAobmV2ZXItc2lsZW50KTogdGhlIGFsdGVybmF0aXZlIGlzIGEgYmluZGluZyB0aGF0IHRocm93cyBhdCB3aGF0ZXZlciBndWVzdCBjYWxsIHNpdGUgcmVhY2hlcyBpdCBmaXJzdCwgd2hpY2ggaXMgd2hlcmUgdGhpcyBjbGFzcyB1c2VkIHRvIHN1cmZhY2UuYCl9cmV0dXJuIGJ0KE4sdWUsWSl9LCJzb1ByZWVtcHRpYmxlUHJvdmlkZXIiKTtmb3IobGV0IE4gb2Ygdil7UG49TixRdD0iaW5zdGFudGlhdGUiO2xldCB1ZT1lbi5nZXQoTi5kaWdlc3QpO3VlLm1vZHVsZXx8KHVlLm1vZHVsZT0kcyh1ZS5ieXRlcyxOLmRpZ2VzdCkubW9kdWxlKTtsZXQgWT14cyhlLm1vZGUpJiZsdCYmZS5kbG9wZW5Gb3JrJiZBcnJheS5pc0FycmF5KGUuZGxvcGVuRm9yay5uZWVkZWRMaWJzKT9lLmRsb3BlbkZvcmsubmVlZGVkTGlicy5maW5kKGt0PT5rdC5uYW1lPT09Ti5uYW1lKTpudWxsO2lmKCFZJiZ4cyhlLm1vZGUpJiZsdCYmZS5kbG9wZW5Gb3JrKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBmb3JrLXJlc3VtZSBjaGlsZCBvZiBhIG1haW4gbmVlZGluZyAke04ubmFtZS5zbGljZSgwLDMyKX1cdTIwMjYgY2FycmllcyBubyBkbG9wZW5Gb3JrIHBsYWNlbWVudCBmb3IgaXQgXHUyMDE0IHJlZnVzaW5nIGEgZnJlc2ggY2FydmUgb3ZlciB0aGUgY29waWVkIGFkZHJlc3Mgc3BhY2UgKHRoZSBkZWx0YSBjb3B5IGhvbGRzIHRoaXMgbGlicmFyeSdzIGxpdmUgZGF0YTsgbmV2ZXItc2lsZW50KS5gKTtpZihZJiZZLmRpZ2VzdCE9PU4uZGlnZXN0KXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBHRU5FUkFUSU9OIFNLRVcgXHUyMDE0IHRoZSBwYXJlbnQncyBwbGFjZW1lbnQgZm9yICR7Ti5zb25hbWV9IHJlY29yZHMgZGlnZXN0ICR7U3RyaW5nKFkuZGlnZXN0KS5zbGljZSgwLDE2KX1cdTIwMjYgYnV0IHRoaXMgaW1hZ2UgbmVlZHMgJHtOLmRpZ2VzdC5zbGljZSgwLDE2KX1cdTIwMjYgKG5ldmVyLXNpbGVudCkuYCk7aWYoWSl7bGV0IGt0PShZLnRhYmxlQmFzZT4+PjApKyhZLnRhYmxlU2l6ZT4+PjApO3plLmxlbmd0aDxrdCYmemUuZ3JvdyhrdC16ZS5sZW5ndGgpfWxldCBUZT1yKChrdCxCZSk9PnF0KE4uc29uYW1lLGt0KSwic29BbGxvY01lbW9yeSIpLHFlPUtsKHVlLm1vZHVsZSksS2U9cigoa3QsQmUsam4pPT57aWYoam49PT0iZnVuY3Rpb24iJiZrdD09PSJsaW51eCImJkJlPT09InN5c2NhbGwiKXtsZXQgVHQ9RXQubGludXgmJkV0LmxpbnV4LnN5c2NhbGw7aWYodHlwZW9mIFR0IT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiAke04uc29uYW1lfSBpbXBvcnRzIGxpbnV4LnN5c2NhbGwgYnV0IHRoZSBwcm9jZXNzIGltcG9ydCBvYmplY3QgY2FycmllcyBub25lIChuZXZlci1zaWxlbnQpLmApO3JldHVybiBUdH1pZighKGpuIT09ImZ1bmN0aW9uInx8a3QhPT0iZW52Iikpe2lmKEhzLmhhcyhCZSkpe2lmKFhuW0JlXSlyZXR1cm4gWG5bQmVdO2xldCBUdD1aP1pbQmVdOnZvaWQgMDtpZih0eXBlb2YgVHQ9PSJmdW5jdGlvbiIpcmV0dXJuIFR0O3Rocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiAke04uc29uYW1lfSBpbXBvcnQgZW52LiR7QmV9IGlzIEtFUk5FTC1vd25lZCBidXQgdm1saW51eCBkb2VzIG5vdCBleHBvcnQgaXQgKG5ldmVyLXNpbGVudCkuYCl9aWYoQmU9PT0iX19od2pzX3htb2RfZGlzcGF0Y2hfY2hlY2siKXJldHVybihUdCxOdCk9PlVzKFR0LE50LCExLCExLHFlKTtpZihJcy5oYXMoQmUpKXJldHVybiAkcihCZSxgJHtOLnNvbmFtZX0gKG5lZWRlZCBlbnRyeSAke04uaW5kZXh9KWApO2lmKEJlPT09Il9faHdqc19sYW5lX2lkIiYmSy5oYXMoQmUpKXJldHVybigpPT57bGV0IFR0PWo/altCZV06dm9pZCAwO3JldHVybiB0eXBlb2YgVHQ9PSJmdW5jdGlvbiI/VHQoKTpXcyhlLGx0KX07aWYodHlwZW9mIGR0W0JlXT09ImZ1bmN0aW9uIilyZXR1cm4gTChCZSxkdFtCZV0pO2lmKER0JiZ0eXBlb2YgRHRbQmVdPT0iZnVuY3Rpb24iKXJldHVybiBEdFtCZV07aWYoQmUhPT0iZm9yayIpcmV0dXJuIHp0KE4sQmUpfX0sInNvUmVzb2x2ZUltcG9ydCIpLGh0PW5ldyBTZXQsd3Q9bmV3IE1hcCwkdD1uZXcgTWFwLGVzPW51bGwsZ3M9Z2UuZ2V0KE4uaW5kZXgpO2ZvcihsZXQga3Qgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHModWUubW9kdWxlKSl7aWYoa3QubW9kdWxlIT09IkdPVC5mdW5jIiljb250aW51ZTtsZXQgQmU9a3QubmFtZTtpZihncyYmZ3MuaGFzKEJlKSYmYXQoSWUsTixCZSk9PT12b2lkIDApY29udGludWU7ZXN8fChlcz1Wbyh1ZS5tb2R1bGUsdWUuYnl0ZXMpKTtsZXQgam49ZXMuZ2V0KEJlKSxUdD1qbj9qbi5tb2R1bGU6ImVudiIsTnQ9am4/am4uZmllbGQ6QmU7aWYoVHQ9PT0ibGludXgiJiZOdD09PSJzeXNjYWxsInx8VHQ9PT0iZW52IiYmKE50PT09Il9faHdqc194bW9kX2Rpc3BhdGNoX2NoZWNrInx8WG5bTnRdfHxJcy5oYXMoTnQpKSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiAke04uc29uYW1lfSAobmVlZGVkIGVudHJ5ICR7Ti5pbmRleH0pIHRha2VzIHRoZSBhZGRyZXNzIG9mICIke0JlfSIsIHdoaWNoIHJlc29sdmVzIHRvICR7VHR9LiR7TnR9IC0tIGEgaG9zdCBiaW5kaW5nLCBub3QgYSB3YXNtIGV4cG9ydCwgc28gaXQgY2FuIG9jY3VweSBubyB0YWJsZSBzbG90LiBSZWZ1c2luZyB0aGUgbG9hZCAobmV2ZXItc2lsZW50KS5gKTtpZihUdCE9PSJlbnYifHxIcy5oYXMoTnQpfHxJcy5oYXMoTnQpfHwhKE50PT09Il9faHdqc19sYW5lX2lkIiYmSy5oYXMoTnQpKSYmKHR5cGVvZiBkdFtOdF09PSJmdW5jdGlvbiJ8fER0JiZ0eXBlb2YgRHRbTnRdPT0iZnVuY3Rpb24iKXx8TnQ9PT0iZm9yayIpY29udGludWU7bGV0IHpuPXB0KE4sTnQpO2lmKHpuIT09bnVsbCl7aWYoTnQhPT1CZSl0aHJvdyBuZXcgRXJyb3IoYGh3anMtZGxvcGVuOiAke04uc29uYW1lfSAobmVlZGVkIGVudHJ5ICR7Ti5pbmRleH0pIHRha2VzIHRoZSBhZGRyZXNzIG9mICIke0JlfSIsIHdoaWNoIHJlc29sdmVzIHRocm91Z2ggZW52LiR7TnR9IC0tIGEgbmFtZSBwcm92aWRlZCBvbmx5IGJ5IHRoZSBtYWluLCAke04uc29uYW1lfSBpdHNlbGYsIG9yIGEgc2libGluZyBuZWVkZWQgZW50cnksIHNvIHRoZSBzbG90IHdvdWxkIG5lZWQgYSBsYXRlIGJpbmRpbmcgdGhlIHBvc3QtbWFpbiBwYXRjaCBjYW5ub3QgY29tcGxldGUgdW5kZXIgYW4gYWxpYXNlZCBuYW1lLiBSZWZ1c2luZyB0aGUgbG9hZCAobmV2ZXItc2lsZW50KS5gKTtpZih0eXBlb2Ygem49PSJudW1iZXIiJiYhWSl7d3Quc2V0KEJlLGJlKE4sem4sQmUpKTtjb250aW51ZX10eXBlb2Ygem49PSJudW1iZXIiJiYkdC5zZXQoQmUsem4pLGh0LmFkZChCZSl9fWxldCBEcz1ZP1kudGFibGVCYXNlPj4+MDp6ZS5sZW5ndGgsaG49WT9ZLm1vZHVsZUlkfDA6WiYmdHlwZW9mIFouX19od2pzX2FsbG9jX21vZHVsZV9pZD09ImZ1bmN0aW9uIj9aLl9faHdqc19hbGxvY19tb2R1bGVfaWQoKXwwOjAsbW4sRHI9MDtpZihtbj1Dcyh7d2FzbUJ5dGVzOnVlLmJ5dGVzLG1lbW9yeTplLm1lbW9yeSx0YWJsZTp6ZSxtb2R1bGVJZDpobixzb1BhdGg6YCR7Ti5zb25hbWV9IChuZWVkZWQgZW50cnkgJHtOLmluZGV4fSlgLGNvbXBpbGVNb2R1bGU6cigoKT0+dWUubW9kdWxlLCJjb21waWxlTW9kdWxlIiksbWFpbkxhbmVBZGRyZXNzZWQ6TWU/ISFNZS5sYW5lQWRkcmVzc2VkOmhlLHJlc29sdmVJbXBvcnQ6S2UscHJlZW1wdHNEYXRhOnIoa3Q9PmF0KFJ0LE4sa3QpIT09dm9pZCAwLCJwcmVlbXB0c0RhdGEiKSxyZXNvbHZlRGF0YUFkZHJlc3M6cihrdD0+e2xldCBCZT1EdD9EdFtrdF06dm9pZCAwO2lmKEJlIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsJiZNZSlyZXR1cm4oKE1lLm1lbW9yeUJhc2U+Pj4wKSsoQmUudmFsdWV8MCl8MCk+Pj4wO2xldCBqbj1kdD9kdFtrdF06dm9pZCAwO2lmKGpuIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsJiZDZSlyZXR1cm4oKENlLm1lbW9yeUJhc2U+Pj4wKSsoam4udmFsdWV8MCl8MCk+Pj4wO2xldCBUdD1SdC5nZXQoa3QpO2lmKFR0PT09dm9pZCAwfHxUdD09PU4uaW5kZXgpcmV0dXJuO2xldCBOdD1Gbi5nZXQoVHQpO2lmKE50KXtsZXQgeXM9KChOdC5pbnN0YW5jZT8/TnQpLmV4cG9ydHN8fHt9KVtrdF07cmV0dXJuIHlzIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsPygoTnQubWVtb3J5QmFzZT4+PjApKyh5cy52YWx1ZXwwKXwwKT4+PjA6dm9pZCAwfWxldCBpcz1YdC5nZXQoVHQpO2lmKCFpcylyZXR1cm47bGV0IHpuPWVuLmdldChpcy5kaWdlc3QpO2lmKCF6bilyZXR1cm47bGV0IE5yPXhzKGUubW9kZSkmJmx0JiZlLmRsb3BlbkZvcmsmJkFycmF5LmlzQXJyYXkoZS5kbG9wZW5Gb3JrLm5lZWRlZExpYnMpLFFzPU5yP2UuZGxvcGVuRm9yay5uZWVkZWRMaWJzLmZpbmQoeXM9PnlzLm5hbWU9PT1pcy5uYW1lKTpudWxsO2lmKE5yJiYhUXMpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6ICR7Ti5zb25hbWV9IChuZWVkZWQgZW50cnkgJHtOLmluZGV4fSkgR09ULm1lbS4ke2t0fSBpcyBvd25lZCBieSBzaWJsaW5nIG5lZWRlZCBlbnRyeSAke1R0fSAoJHtpcy5zb25hbWV9KSwgYnV0IHRoaXMgZm9yay1yZXN1bWUgY2hpbGQgaGFzIG5vIHBsYWNlbWVudCByZWNvcmQgZm9yIGl0IFx1MjAxNCByZWZ1c2luZyB0byByZS1wbGFjZSBpdCBhdCBhIGZyZXNoIGJhc2UgdGhlIHBhcmVudCdzIHJlbG9jYXRlZCBkYXRhIGRvZXMgbm90IHBvaW50IGF0IChuZXZlci1zaWxlbnQpLmApO2xldCBlcj1Rcz9Rcy5tZW1vcnlCYXNlPj4+MDp5ZShUdCk7aWYoIShlcj4wKSlyZXR1cm47bGV0IExyPVJsKHpuLmJ5dGVzLGt0LGAke2lzLnNvbmFtZX0gKG5lZWRlZCBlbnRyeSAke1R0fSlgKTtyZXR1cm4oKGVyPj4+MCkrKExyfDApfDApPj4+MH0sInJlc29sdmVEYXRhQWRkcmVzcyIpLGdvdEZ1bmNJbmRleDpjbixzdGFja1BvaW50ZXI6bGUuX19zdGFja19wb2ludGVyLHBhcmtJbXBvcnQ6cigoKT0+e30sInBhcmtJbXBvcnQiKSxzaWRlVGxzOlk/b2EoZS5tb2RlLFksZS5tYWluVGxzU2xvdCk6e21vZGU6ImZyZXNoIn0sLi4uaHQuc2l6ZT97ZGVmZXJHb3RGdW5jOmh0fTp7fSwuLi53dC5zaXplP3twcmVzZXRHb3RGdW5jOnd0fTp7fSwuLi4hWSYmUmUuaGFzKE4uaW5kZXgpP3tyZXNlcnZlZFN5bWJvbEluZGljZXM6Wy4uLlJlLmdldChOLmluZGV4KV19Ont9LC4uLlk/e2ZpeGVkTWVtb3J5QmFzZTpZLm1lbW9yeUJhc2U+Pj4wLGZpeGVkVGFibGVCYXNlOlkudGFibGVCYXNlPj4+MCxza2lwRGF0YVJlbG9jczohMCxzZWVkU3ltYm9sSW5kaWNlczpBcnJheS5pc0FycmF5KFkuYXBwZW5kZWQpP1kuYXBwZW5kZWQ6W119OnZlLmhhcyhOLmluZGV4KT97Zml4ZWRNZW1vcnlCYXNlOnZlLmdldChOLmluZGV4KT4+PjB9OnthbGxvY01lbW9yeTpUZX19KSxGbi5zZXQoTi5pbmRleCxtbiksbW4udGxzJiYoRHI9WT9ZLnRsc1Nsb3RzPj4+MDpxdChgJHtOLnNvbmFtZX0gVExTIHNsb3RzYCxyYShtbi50bHMsYCR7Ti5zb25hbWV9IChuZWVkZWQgZW50cnkgJHtOLmluZGV4fSlgKSkpLFF0PSJhcm1Nb2R1bGVCdWRnZXQiLHRuKG1uKSxRdD0icnVuQ3RvcnMiLCFZJiZHKXtsZXQga3Q9KG1uLmluc3RhbmNlPz9tbikuZXhwb3J0cyxCZT1rdC5fX3dhc21fY2FsbF9jdG9yczt0eXBlb2YgQmU9PSJmdW5jdGlvbiImJmtuLnB1c2goe2N0b3I6QmUsbW9kdWxlSWQ6aG58MCxzb25hbWU6Ti5zb25hbWUsLi4uemwoa3QpfSl9ZWxzZSBZfHxtbi5ydW5DdG9ycygpO2N0LnB1c2goe25hbWU6Ti5uYW1lLHNvbmFtZTpOLnNvbmFtZSxkaWdlc3Q6Ti5kaWdlc3QsaW5kZXg6Ti5pbmRleCxoYW5kbGU6bW4sZXhwb3J0czoobW4uaW5zdGFuY2U/P21uKS5leHBvcnRzLG1lbW9yeUJhc2U6bW4ubWVtb3J5QmFzZT4+PjAsdGFibGVCYXNlOkRzPj4+MCxtb2R1bGVJZDpobnwwLGFwcGVuZGVkOm1uLnRhYmxlRW50cmllcygpLHRsc1Nsb3RzOkRyPj4+MCxnb3RQcm92aWRlcnM6JHR9KTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1saWJjOiBtb2R1bGUgIyR7MStOLmluZGV4fSBpbnN0YW50aWF0ZWQgKCR7Ti5zb25hbWV9LCBkaWdlc3QgJHtOLmRpZ2VzdC5zbGljZSgwLDE2KX1cdTIwMjYgbW9kdWxlSWQ9JHtobn0gbWVtb3J5QmFzZT0weCR7KG1uLm1lbW9yeUJhc2U+Pj4wKS50b1N0cmluZygxNil9IHRhYmxlQmFzZT0ke0RzfSR7WT8iIGZvcmstcmVwbGF5IjoiIn0pIFx1MjAxNCBuZWVkZWQgZW50cnkgJHtOLmluZGV4fWB9KX1jYXRjaHt9UG49bnVsbCxRdD0iIn19Y2F0Y2goRyl7aWYoUG4pe2xldCBLPVBuLGdlPSIiO3RyeXtsZXQgSWU9RyBpbnN0YW5jZW9mIEVycm9yP0cubWVzc2FnZTpTdHJpbmcoRyksUnQ9RyYmRy5zdGFjaz9TdHJpbmcoRy5zdGFjaykuc3BsaXQoYApgKS5zbGljZSgxLDUpLm1hcChYdD0+WHQudHJpbSgpKS5maWx0ZXIoQm9vbGVhbikuam9pbigiIHwgIik6IiI7Z2U9SWUrKFJ0P2AgWyR7UnR9XWA6IiIpfWNhdGNoe2dlPSIodW5yZXBvcnRhYmxlIHRocm93IHZhbHVlKSJ9Rz1uZXcgRXJyb3IoYGh3anMtbGliYzogbmVlZGVkIGVudHJ5ICR7Sy5pbmRleH0gKCR7Sy5zb25hbWV9LCBkaWdlc3QgJHtTdHJpbmcoSy5kaWdlc3QpLnNsaWNlKDAsMTYpfSkgZmFpbGVkIGF0ICR7UXR9OiAke2dlfWAse2NhdXNlOkd9KX1pZihhd2FpdCB1KCJORUVERUQtTE9BRCIsRyk9PT0icmV0dXJuIil7JG4oImVycm9yIik7cmV0dXJufWJyZWFrIGV9QnQ9Y3QubWFwKEc9Pih7aGFuZGxlOkcuaGFuZGxlLHNvbmFtZTpHLnNvbmFtZSxpbmRleDpHLmluZGV4LHRsc1Nsb3RzOkcudGxzU2xvdHMsZ290UHJvdmlkZXJzOkcuZ290UHJvdmlkZXJzfSkpLHBuPWN0Lm1hcChHPT4oe25hbWU6Ry5uYW1lLGRpZ2VzdDpHLmRpZ2VzdCxpbmRleDpHLmluZGV4LG1lbW9yeUJhc2U6Ry5tZW1vcnlCYXNlLHRhYmxlQmFzZTpHLnRhYmxlQmFzZSx0YWJsZVNpemU6emUubGVuZ3RoLUcudGFibGVCYXNlPj4+MCxtb2R1bGVJZDpHLm1vZHVsZUlkLGFwcGVuZGVkOkcuaGFuZGxlLnRhYmxlRW50cmllcygpLHRsc1Nsb3RzOkcudGxzU2xvdHN9KSl9Zm9yKGxldCBHIG9mIEEpaWYoIShHLm1vZHVsZSE9PSJlbnYifHxHLmtpbmQhPT0iZnVuY3Rpb24iKSYmbGVbRy5uYW1lXT09PXZvaWQgMCl7aWYodHlwZW9mIGR0W0cubmFtZV09PSJmdW5jdGlvbiIpbGVbRy5uYW1lXT1MKEcubmFtZSxkdFtHLm5hbWVdKTtlbHNlIGlmKER0JiZ0eXBlb2YgRHRbRy5uYW1lXT09ImZ1bmN0aW9uIilsZVtHLm5hbWVdPUR0W0cubmFtZV07ZWxzZSBmb3IobGV0IEsgb2YgY3QpaWYodHlwZW9mIEsuZXhwb3J0c1tHLm5hbWVdPT0iZnVuY3Rpb24iKXtsZVtHLm5hbWVdPUsuZXhwb3J0c1tHLm5hbWVdO2JyZWFrfX1mb3IobGV0IEcgb2YgY3QubGVuZ3RoP0E6W10pe2lmKEcubW9kdWxlIT09ImVudiJ8fEcua2luZCE9PSJmdW5jdGlvbiJ8fEppLmhhcyhHLm5hbWUpKWNvbnRpbnVlO2xldCBLPVtdO3R5cGVvZiBkdFtHLm5hbWVdPT0iZnVuY3Rpb24iJiZLLnB1c2goInJ0ICgjMCkiKSxEdCYmdHlwZW9mIER0W0cubmFtZV09PSJmdW5jdGlvbiImJksucHVzaCgibGliYy5zbyAoIzEpIik7Zm9yKGxldCBnZSBvZiBjdCl0eXBlb2YgZ2UuZXhwb3J0c1tHLm5hbWVdPT0iZnVuY3Rpb24iJiZLLnB1c2goYCR7Z2Uuc29uYW1lfSAoIyR7MStnZS5pbmRleH0pYCk7aWYoSy5sZW5ndGg+MSl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgaHdqcy1saWJjOiAke0cubmFtZX0gaXMgZXhwb3J0ZWQgYnkgJHtLLmxlbmd0aH0gcGxhY2VkIG1vZHVsZXMgKCR7Sy5qb2luKCIsICIpfSkgXHUyMDE0IGJvdW5kIGZyb20gJHtLWzBdfSBieSBuZWVkZWQtbGlzdCBvcmRlcmB9KX1jYXRjaHt9fXRyeXtpZihlZSl7bGV0IEc9TWUubWVtb3J5QmFzZT4+PjA7Zm9yKGxldCBLIG9mIEEpaWYoSy5raW5kPT09Imdsb2JhbCIpe2lmKEsubW9kdWxlPT09IkdPVC5tZW0iKXtsZXQgZ2U9RHRbSy5uYW1lXTtpZihnZSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbCl7KEV0WyJHT1QubWVtIl0/Pz17fSlbSy5uYW1lXT1uZXcgV2ViQXNzZW1ibHkuR2xvYmFsKHt2YWx1ZToiaTMyIixtdXRhYmxlOiEwfSxHKyhnZS52YWx1ZXwwKXwwKTtjb250aW51ZX1sZXQgSWU9ZHQ/ZHRbSy5uYW1lXTp2b2lkIDA7aWYoSWUgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWwmJkNlKXsoRXRbIkdPVC5tZW0iXT8/PXt9KVtLLm5hbWVdPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITB9LChDZS5tZW1vcnlCYXNlPj4+MCkrKEllLnZhbHVlfDApfDApO2NvbnRpbnVlfWxldCBSdD0wLFh0PTA7Zm9yKGxldCBCbiBvZiBjdCl7bGV0IGF0PUJuLmV4cG9ydHNbSy5uYW1lXTthdCBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbCYmUnQrKz09PTAmJihYdD0oQm4ubWVtb3J5QmFzZT4+PjApKyhhdC52YWx1ZXwwKXwwKX1pZihSdD4wKXtpZigoRXRbIkdPVC5tZW0iXT8/PXt9KVtLLm5hbWVdPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITB9LFh0KSxSdD4xKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLWxpYmM6IEdPVC5tZW0uJHtLLm5hbWV9IGlzIGV4cG9ydGVkIGFzIGRhdGEgYnkgJHtSdH0gbmVlZGVkIGxpYnJhcmllcyBcdTIwMTQgYm91bmQgZnJvbSB0aGUgZmlyc3QgaW4gbmVlZGVkLWxpc3Qgb3JkZXJgfSl9Y2F0Y2h7fWNvbnRpbnVlfXRocm93IG5ldyBFcnJvcihgaHdqcy1saWJjOiBtYWluIEdPVC5tZW0uJHtLLm5hbWV9IG5hbWVzIG5vIGxpYmMuc28gZGF0YSBleHBvcnQsIG5vIHJ1bnRpbWUgKG1vZHVsZSAjMCkgZGF0YSBleHBvcnQsIGFuZCBubyBkYXRhIGV4cG9ydCBvZiBhbnkgbmVlZGVkIGxpYnJhcnkgZWl0aGVyIFx1MjAxNCB0aGUgYnktbmFtZSB3aXRuZXNzIHNob3VsZCBoYXZlIG1hZGUgdGhpcyBsaW5rLWZhdGFsOyBhIHNrZXdlZC9mb3JlaWduIGFydGlmYWN0IHBhaXIgKG5ldmVyLXNpbGVudCkuYCl9ZWxzZSBpZihLLm1vZHVsZT09PSJHT1QuZnVuYyIpe2xldCBnZT1lZS5kbHN5bShLLm5hbWUpO2lmKCEoZ2U+MCkmJlB0JiYoZ2U9UHQuZGxzeW0oSy5uYW1lKSksIShnZT4wKSl7Zm9yKGxldCBJZSBvZiBjdClpZihnZT1JZS5oYW5kbGUuZGxzeW0oSy5uYW1lKSxnZT4wKWJyZWFrfWlmKCEoZ2U+MCkpdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IG1haW4gR09ULmZ1bmMuJHtLLm5hbWV9IG5hbWVzIG5vIGxpYmMuc28gZnVuY3Rpb24gZXhwb3J0LCBubyBydW50aW1lIG9wLCBhbmQgbm8gZXhwb3J0IG9mIGFueSBuZWVkZWQgbGlicmFyeSBvZiB0aGF0IG5hbWUgXHUyMDE0IGNhbm5vdCBtaW50IGEgdGFibGUgaWRlbnRpdHkgKG5ldmVyLXNpbGVudCkuYCk7KEV0WyJHT1QuZnVuYyJdPz89e30pW0submFtZV09bmV3IFdlYkFzc2VtYmx5Lkdsb2JhbCh7dmFsdWU6ImkzMiIsbXV0YWJsZTohMH0sZ2UpfX19fWNhdGNoKEcpe2lmKGF3YWl0IHUoIkxJQkMtR09ULU1JTlQiLEcpPT09InJldHVybiIpeyRuKCJlcnJvciIpO3JldHVybn1icmVhayBlfXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXJ0OiBtb2R1bGUgIzAgaW5zdGFudGlhdGVkIChtb2R1bGVJZD0ke19ufSBtZW1vcnlCYXNlPTB4JHtDZS5tZW1vcnlCYXNlLnRvU3RyaW5nKDE2KX0gdGFibGVCYXNlPSR7eXR9KSBcdTIwMTQgcnVudGltZSBwcm92aWRlciBpcyB0aGUga2VybmVsYH0pfWNhdGNoe319fWxldCBiPW51bGw7Zm9yKGxldCBBIG9mIFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKHApKWlmKEEua2luZD09PSJnbG9iYWwiJiZBLm1vZHVsZT09PSJlbnYiJiZBLm5hbWU9PT0iX19od2pzX3N0YXR1c19jaGFubmVsX2FkZHIiKXtiPW5ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIiLG11dGFibGU6ITB9LDApLChFdC5lbnY/Pz17fSkuX19od2pzX3N0YXR1c19jaGFubmVsX2FkZHI9YixoZT0hMDticmVha31sZXQgUD1iZihwLEV0KSxIO3RyeXtIPWF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKHAsUCl9Y2F0Y2goQSl7aWYoYXdhaXQgdSgiSU5TVEFOVElBVEUiLEEpPT09InJldHVybiIpeyRuKCJlcnJvciIpO3JldHVybn1icmVhayBlfXtsZXQgQT1ILmV4cG9ydHMsSj1ydD9ydC5leHBvcnRzOm51bGw7aWYoSiYmQ2Upe2xldCBsZT1DZS5tZW1vcnlCYXNlPj4+MCxaPU9iamVjdC5jcmVhdGUobnVsbCk7Zm9yKGxldCBWZSBvZiBPYmplY3Qua2V5cyhKKSl7bGV0IEdlPUpbVmVdO1pbVmVdPUdlIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsP25ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIifSxsZSsoR2UudmFsdWV8MCl8MCk6R2V9Sj1afWxldCBDPWVlPyhlZS5pbnN0YW5jZT8/ZWUpLmV4cG9ydHM6bnVsbDtpZihDJiZNZSl7bGV0IGxlPU1lLm1lbW9yeUJhc2U+Pj4wLFo9T2JqZWN0LmNyZWF0ZShudWxsKTtmb3IobGV0IFZlIG9mIE9iamVjdC5rZXlzKEMpKXtsZXQgR2U9Q1tWZV07WltWZV09R2UgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWwmJlZlIT09Il9fdGxzX2Jhc2UiP25ldyBXZWJBc3NlbWJseS5HbG9iYWwoe3ZhbHVlOiJpMzIifSxsZSsoR2UudmFsdWV8MCl8MCk6R2V9Qz1afWo9Snx8Qz9PYmplY3QuYXNzaWduKE9iamVjdC5jcmVhdGUobnVsbCksSj8/e30sQz8/e30sQSxBLl9fc3RhY2tfcG9pbnRlcj09PXZvaWQgMCYmRXQuZW52JiZFdC5lbnYuX19zdGFja19wb2ludGVyIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsP3tfX3N0YWNrX3BvaW50ZXI6RXQuZW52Ll9fc3RhY2tfcG9pbnRlcn06e30pOkE7bGV0IGllPWouX19od2pzX2xhbmVfaWQ7aWYodHlwZW9mIGllPT0iZnVuY3Rpb24iKXRyeXtmb3IobGV0IGxlIG9mIEVuKWxlLnQuc2V0KDAsaWUpfWNhdGNoe319bGV0IGY9ajtQaT1qbChmKSxCbz1udWxsO2xldCBXPVdzKGUsbHQpO2lmKFplPVd8MCxiKXtsZXQgQT1mLl9faHdqc19zdGF0dXNfY2hhbm5lbCxKPUEgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWw/QS52YWx1ZT4+PjA6MDtpZighSil0aHJvdyBuZXcgRXJyb3IoImxhbmUtYWRkcmVzc2VkIG1haW4gaW1wb3J0cyBlbnYuX19od2pzX3N0YXR1c19jaGFubmVsX2FkZHIgYnV0IGV4cG9ydHMgbm8gX19od2pzX3N0YXR1c19jaGFubmVsIGRhdGEgZ2xvYmFsIHRvIGRlcml2ZSBpdCBmcm9tIFx1MjAxNCBza2V3ZWQgYXJ0aWZhY3QgcGFpciAobmV2ZXItc2lsZW50OyByZWZ1c2luZyBhIDAgYmluZCwgdGhlIFIxLWdsaWJjIHBoYW50b20gYWRkcmVzcy0wIGNsYXNzKS4iKTtpZihiLnZhbHVlPUorVyozMnwwLE1uKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbY2hhbi1hZGRyIG1haW5dIG1vZGU9JHtlLm1vZGV9IGxhbmU9JHtXfSBjaEJhc2U9MHgke0oudG9TdHJpbmcoMTYpfSBhZGRyPTB4JHsoYi52YWx1ZT4+PjApLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fX1pZighbHQmJnR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OiJFWEVDLUxPQUQtRElBRzogcmUtaW5zdGFudGlhdGUgRE9ORTsgZW50ZXJpbmcgZHJpdmUgKGJhc2ggX3N0YXJ0KSJ9KX1jYXRjaHt9aWYodHQmJnplKXRyeXtsZXQgQT1yKEo9Pnt0cnl7cmV0dXJuIHR5cGVvZiB6ZS5nZXQoSil9Y2F0Y2h7cmV0dXJuIm9vYiJ9fSwicHJvYmUiKTt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBEWU5NQUlOLVRBQkxFIGxlbj0ke3plLmxlbmd0aH0gZ2V0KDApPSR7QSgwKX0gZ2V0KDEpPSR7QSgxKX0gZ2V0KDg1KT0ke0EoODUpfSBleHBvcnRzVGFibGU9JHtmLl9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5UYWJsZT8ieWVzIjoibm8ifSBzYW1lQXNFeHBvcnQ9JHtmLl9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGU9PT16ZX1gfSl9Y2F0Y2h7fXRyeXtpZihQdHx8ZWV8fEJ0Lmxlbmd0aCl7bGV0IEE9Wy4uLlB0P1t7aGFuZGxlOlB0LHdobzoicnQifV06W10sLi4uZWU/W3toYW5kbGU6ZWUsd2hvOiJsaWJjLnNvIn1dOltdLC4uLkJ0Lm1hcChDPT4oe2hhbmRsZTpDLmhhbmRsZSx3aG86YCR7Qy5zb25hbWV9IChuZWVkZWQgZW50cnkgJHtDLmluZGV4fSlgLGdvdFByb3ZpZGVyczpDLmdvdFByb3ZpZGVyc30pKV0sSj1CdC5tYXAoQz0+KHtpbmRleDpDLmluZGV4LHNvbmFtZTpDLnNvbmFtZSxleHBvcnRzOihDLmhhbmRsZS5pbnN0YW5jZT8/Qy5oYW5kbGUpLmV4cG9ydHM/P0MuaGFuZGxlLmV4cG9ydHN9KSk7Zm9yKGxldCBDIG9mIEEpe2xldCBpZT1DLmhhbmRsZTtpZighaWUpY29udGludWU7bGV0IGxlPUMud2hvLFo9KGllLmluc3RhbmNlPz9pZSkuZXhwb3J0cz8/aWUuZXhwb3J0cztmb3IobGV0IFZlIG9mIGllLnBlbmRpbmdHb3RGdW5jTmFtZXMoKSl7bGV0IEdlPSRsKFZlLHtleHA6Zixvd25FeHA6WixzaWJsaW5nczpKLHByb3ZpZGVyOkMuZ290UHJvdmlkZXJzP0MuZ290UHJvdmlkZXJzLmdldChWZSk6dm9pZCAwfSksUWU9R2U/R2UuZjp2b2lkIDA7aWYoR2UmJkdlLnNpYmxpbmcpdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtcnQ6ICR7bGV9IHRvb2sgdGhlIGFkZHJlc3Mgb2YgIiR7VmV9IiAoR09ULmZ1bmMpOyBwYXRjaGVkIGZyb20gc2libGluZyBuZWVkZWQgZW50cnkgJHtHZS5zaWJsaW5nLmluZGV4fSAoJHtHZS5zaWJsaW5nLnNvbmFtZX0pYH0pfWNhdGNoe31pZih0eXBlb2YgUWUhPSJmdW5jdGlvbiIpdGhyb3cgbmV3IEVycm9yKGBod2pzLXJ0OiAke2xlfSB0b29rIHRoZSBhZGRyZXNzIG9mICIke1ZlfSIgKEdPVC5mdW5jKSBidXQgbm8gcHJvdmlkZXIgKG1haW4vcnQvbGliYy5zbyBvd24gZXhwb3J0cywgb3IgYW55IG5lZWRlZCBlbnRyeSBvZiB0aGlzIG1haW4pIHN1cHBsaWVzIHN1Y2ggYSBmdW5jdGlvbiBcdTIwMTQgY2Fubm90IHBhdGNoIHRoZSBkZWZlcnJlZCBzbG90IChuZXZlci1zaWxlbnQpLmApO2llLnBhdGNoR290RnVuYyhWZSxRZSl9fX19Y2F0Y2goQSl7aWYoYXdhaXQgdSgiR09ULVBBVENIIixBKT09PSJyZXR1cm4iKXskbigiZXJyb3IiKTtyZXR1cm59YnJlYWsgZX14cyhlLm1vZGUpJiZsdCYmZS5kbG9wZW5Gb3JrJiZ0eXBlb2YgZS5kbG9wZW5Gb3JrPT0ib2JqZWN0IiYmKEFycmF5LmlzQXJyYXkoZS5kbG9wZW5Gb3JrLmZwY2FzdFJlY3MpJiYoU249bmV3IE1hcChlLmRsb3BlbkZvcmsuZnBjYXN0UmVjcy5tYXAoKFtBLEpdKT0+W0E+Pj4wLEo+Pj4wXSkpKSxZZChlLmRsb3BlbkZvcmspKTtsZXQgX2U9cihBPT57bGV0IEo9altBXTtyZXR1cm4gSiBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lkdsb2JhbD9KLnZhbHVlPj4+MDowfSwiaHdqc0RhdGEiKTtTZT1udWxsLHE9dHlwZW9mIGouaHdqc19yZXN1bWU9PSJmdW5jdGlvbiImJnR5cGVvZiBqLmh3anNfZG9uZT09ImZ1bmN0aW9uIiYmdHlwZW9mIGouaHdqc19kZXN0cm95PT0iZnVuY3Rpb24iJiZ0eXBlb2Ygai5fX2h3anNfdGFrZV9wYXJrZWQ9PSJmdW5jdGlvbiImJl9lKCJfX2h3anNfcGFya2VkIikhPT0wJiZfZSgiX19od2pzX3BhcmtfcmVhc29uIikhPT0wO3tsZXQgQT1xJiZ0eXBlb2Ygai5fX2h3anNfZHJpdmVfYWJpPT0iZnVuY3Rpb24iP2ouX19od2pzX2RyaXZlX2FiaSgpfDA6MDtPZT1BPT09M3x8QT09PTR9aWYoSGU9cSYmdHlwZW9mIGouX19od2pzX2xpYmNfc3lzY2FsbF9wYXJrX2FiaT09ImZ1bmN0aW9uIiYmKGouX19od2pzX2xpYmNfc3lzY2FsbF9wYXJrX2FiaSgpfDApPT09MSxycz1xJiZ0eXBlb2Ygai5fX2h3anNfbGliY19tbWFwX3BhcmtfYWJpPT0iZnVuY3Rpb24iJiYoai5fX2h3anNfbGliY19tbWFwX3BhcmtfYWJpKCl8MCk9PT0xLGUubWVyZ2VkQ3B1MExhbmU9PT0hMCYmIUhlKXtsZXQgSj1gaHdqcy1tZXJnZWQgUkVGVVNFRCBpbWFnZSAke0FycmF5LmlzQXJyYXkoZS5hcmd2KSYmZS5hcmd2Lmxlbmd0aD4wP1N0cmluZyhlLmFyZ3ZbMF0pOmBwaWQgJHtlLnBpZD8/Ij8ifWB9IG9uIHRoZSBtZXJnZWQgQ1BVLTAgbGFuZTogaXQgZG9lcyBub3QgZXhwb3J0IF9faHdqc19saWJjX3N5c2NhbGxfcGFya19hYmkoKT09MSAoaHdqc0RyaXZlPSR7cT8xOjB9KSwgc28gbm90aGluZyBpbiBpdCBjYW4gYWJzb3JiIGEgLTUxNyBjb29wZXJhdGl2ZSBwYXJrIGF0IGFsbCBhbmQgZXZlcnkgYmxvY2tpbmcgcmVhZCBmYWxscyB0aHJvdWdoIHRvIGFuIFVOQk9VTkRFRCBpbi1rZXJuZWwgd2FpdC4gKEFuIGltYWdlIHRoYXQgRE9FUyBleHBvcnQgMSBpcyBhZG1pdHRlZCwgYW5kIHRoYXQgaXMgbm90IHRoZSBzYW1lIGFzIHByb3ZlbjogZ2xpYmMncyBwb3J0IGRvY3VtZW50cyBpdHMgZXhwb3J0IGFzIGFuIG92ZXItYXBwcm94aW1hdGlvbiBvdmVyIGl0cyBub21pbmF0ZWQgVFVzLiBIb3N0LWFuc3dlcmVkIHN5c2NhbGxzIG5vIGxvbmdlciByZWx5IG9uIGl0IFx1MjAxNCB0aGV5IGFyZSBhbnN3ZXJlZCBpbiBwbGFjZSB0aHJvdWdoIHRoZSBtZXJnZWQgbGFuZSdzIHN5bmNocm9ub3VzIGRvb3IgXHUyMDE0IGJ1dCBhIGtlcm5lbC1yb3V0ZSBibG9jay1wYXJrIHN0aWxsIGRvZXMsIGFuZCBhIGxpYmMgdGhhdCBkb2VzIG5vdCByZS1pc3N1ZSBpcyBjYXVnaHQgdGhlcmUgYnkgbWVhc3VyZW1lbnQsIGF0IHRoZSBERUZFUlJFRC1SUEMgTUlTTUFUQ0ggYXJtLCBub3QgaGVyZS4pIFRoaXMgbGFuZSBzaGFyZXMgaXRzIEpTIHRocmVhZCB3aXRoIENQVSAwIFx1MjAxNCB0aGUgZGlzcGF0Y2hlciwgZXZlcnkga3RocmVhZCwgdGhlIHRpbWVyIHRpY2ssIHRoZSB2aXJ0aW8gSVJRIGJvdHRvbSBoYWxmLCBhbmQgaW5saW5lIHRoZSBQdHlCcmlkZ2UgdGhhdCBkZWxpdmVycyB0aGUga2V5c3Ryb2tlIHRoaXMgaW1hZ2Ugd291bGQgYmUgd2FpdGluZyBmb3IgXHUyMDE0IHNvIHRoYXQgd2FpdCBzdG9wcyB0aGUgbWFjaGluZSwgYXQgdGhlIGZpcnN0IHByb21wdCwgd2l0aCBub3RoaW5nIHRvIHNlZS4gUExBTi1DT0xMQVBTRUQtQ1BVMCBceEE3My41IHVzZWQgdG8gc2VuZCB0aGlzIGltYWdlIHRvIG1lcmdlZENwdUhvc3Q6J3NlcGFyYXRlJyAobGludXgtNi4xMi1nbGliYy1iYXNoLWNvcmV1dGlscyB0b2RheSk7IHRoYXQgdG9wb2xvZ3kgaXMgZGVsZXRlZCwgc28gdGhlcmUgaXMgbm93aGVyZSB0byBzZW5kIGl0LiBSdW4gYW4gaW1hZ2Ugd2hvc2UgbGliYyBwYXJrcywgb3Igd2lkZW4gdGhpcyBvbmUncyBwYXJrIG5vbWluYXRpb24gdW50aWwgaXQgZG9lcy5gO3Rocm93IHQoe2tpbmQ6ImVycm9yIixwaWQ6ZS5waWQsbWVzc2FnZTpKfSksbmV3IEVycm9yKEopfWlmKFl0PSExLGlpLnJlc2V0KCksb3Q9ITEsc3Q9ITEsdHlwZW9mIGYuX19od2pzX3NldF9zdGFsbF9ib3VuZD09ImZ1bmN0aW9uIil7bGV0IEE9dHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudi5IV0pTX0Y5M19TVEFMTF9CT1VORHx8IiIsSj1wYXJzZUludChBLDEwKTtOdW1iZXIuaXNGaW5pdGUoSikmJko+MCYmZi5fX2h3anNfc2V0X3N0YWxsX2JvdW5kKEp8MCl9dHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudiYmcHJvY2Vzcy5lbnYuSFdKU19SRURfTEFORV9SRUNZQ0xFX1NUQUxFPT09IjEiJiZ0eXBlb2YgZi5fX2h3anNfcmVkX2xhbmVfcmVjeWNsZV9zdGFsZT09ImZ1bmN0aW9uIiYmZi5fX2h3anNfcmVkX2xhbmVfcmVjeWNsZV9zdGFsZSgxKTtsZXQgamU9ZS5tb2RlPT09ImZvcmstcmVzdW1lIiYmbHR8fGUubW9kZT09PSJtaWdyYXRlLXJlc3VtZSImJmx0fHxlLm1vZGU9PT0idGhyZWFkIiYmbHQmJighIWUuZGxvcGVuRm9ya3x8KGUudXNlckxhbmV8MCk+MCk7aWYodHlwZW9mIGYuX19od2pzX2J1ZGdldF9zZXQ9PSJmdW5jdGlvbiImJihmLl9faHdqc19idWRnZXRfc2V0KHFyfDApLHNzKHFyKSksIWplJiZlLm1vZGUhPT0idGhyZWFkIiYmdHlwZW9mIGYuX19od2pzX2xhbmVfYXR0YWNoPT0iZnVuY3Rpb24iKWlmKHR5cGVvZiBmLl9fd2FzbTMyX3NldF9sYW5lX2lkPT0iZnVuY3Rpb24iJiZmLl9fd2FzbTMyX3NldF9sYW5lX2lkKDApLG49PT0wKXtpZighKHR5cGVvZiBmLl9faHdqc19sYW5lX29jY3VwaWVkPT0iZnVuY3Rpb24iP2YuX19od2pzX2xhbmVfb2NjdXBpZWQoMCl8MDoxKSl0aHJvdyBuZXcgRXJyb3IoImh3anMtbGFuZXM6IGxhbmUtMCB3YXMgYXR0YWNoZWQgaW4gdGhlIFBSRS1NQUlOIHdpbmRvdyBhbmQgaXMgTk9UIG9jY3VwaWVkIGF0IGZyZXNoLWltYWdlIGJyaW5nLXVwIFx1MjAxNCBzb21ldGhpbmcgZGV0YWNoZWQgaXQgd2hpbGUgdGhlIG5lZWRlZCBncmFwaCB3YXMgY29uc3RydWN0ZWQgKGEgc3RhbGUgbGFuZSBiaW5kaW5nIGlzIHRoZSBvbmUgc2hhcGUgdGhlIG9jY3VwYW5jeSB0YWJsZSBjYW5ub3Qgc2VlIGxhdGVyKS4gUmVmdXNpbmcgdG8gZHJpdmUgKG5ldmVyLXNpbGVudCkuIil9ZWxzZXtsZXQgQT1mLl9faHdqc19sYW5lX2F0dGFjaCgwKXwwO2lmKEE8PTApdGhyb3cgbmV3IEVycm9yKGBod2pzLWxhbmVzOiBsYW5lLTAgYXR0YWNoIFJFRlVTRUQgKHJjPSR7QX0pIGF0IGZyZXNoLWltYWdlIGJyaW5nLXVwIFx1MjAxNCB0aGUgb2NjdXBhbmN5IHRhYmxlIHNheXMgbGFuZSAwIGlzIGFscmVhZHkgZHJpdmVuICh0d28tZHJpdmVyIHNoYXBlKSBvciB0aGUgUlQvbGFuZS1pZCBiaW5kaW5nIGlzIHNrZXdlZC4gUmVmdXNpbmcgdG8gZHJpdmUgKG5ldmVyLXNpbGVudCkuYCl9bGV0IHdlPWVlPyhlZS5pbnN0YW5jZT8/ZWUpLmV4cG9ydHM6bnVsbCxZZT1yKChBLEosQyk9PntpZihBLl9fd2FzbV9pbml0X3RscyhDKSxBPT09SiYmdHlwZW9mIE89PSJmdW5jdGlvbiIpdHJ5e08oQz4+PjApfWNhdGNoe319LCJiaW5kQm9vdHN0cmFwVGxzIiksU3Q9d2UmJnR5cGVvZiB3ZS5fX3dhc21faW5pdF90bHM9PSJmdW5jdGlvbiImJnR5cGVvZiB3ZS5fX3dhc20zMl9nZXRfdGxzX3NpemU9PSJmdW5jdGlvbiImJnR5cGVvZiB3ZS5fX3dhc20zMl9nZXRfdGxzX2FsaWduPT0iZnVuY3Rpb24iP3dlOmY7aWYoIWplJiZlLm1vZGUhPT0idGhyZWFkIiYmdHlwZW9mIFN0Ll9fd2FzbV9pbml0X3Rscz09ImZ1bmN0aW9uIiYmdHlwZW9mIFN0Ll9fd2FzbTMyX2dldF90bHNfc2l6ZT09ImZ1bmN0aW9uIiYmdHlwZW9mIFN0Ll9fd2FzbTMyX2dldF90bHNfYWxpZ249PSJmdW5jdGlvbiIpe2xldCBBPVN0Ll9fd2FzbTMyX2dldF90bHNfc2l6ZSgpPj4+MDtpZihBIT09MCl7bGV0IEo9TWF0aC5tYXgoU3QuX193YXNtMzJfZ2V0X3Rsc19hbGlnbigpPj4+MCwxNiksQz1mLl9faGVhcF9iYXNlLGllPUMgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5HbG9iYWw/Qy52YWx1ZT4+PjA6dHlwZW9mIEM9PSJudW1iZXIiP0M+Pj4wOjA7aWYoaWU9PT0wKXRocm93IG5ldyBFcnJvcihgSFdKUyBib290c3RyYXAtVExTOiBpbWFnZSBleHBvcnRzIF9fd2FzbV9pbml0X3RscyBhbmQgYSBub24temVybyBfX3Rsc19zaXplICgke0F9KSBidXQgbm8gdXNhYmxlIF9faGVhcF9iYXNlIGdsb2JhbCBcdTIwMTQgY2Fubm90IHBsYWNlIHRoZSBwcmUtY3RvciBUTFMgYmxvY2suIFJlZnVzaW5nIHRvIHJ1biBnbGliYyBjdG9ycyBhZ2FpbnN0IGEgemVybyBfX3Rsc19iYXNlICh0aGUgY3RvciBtYWxsb2Mgd291bGQgc21hc2ggaGVhcCBtZXRhZGF0YSkuYCk7bGV0IGxlPWllKyhKLTEpJn4oSi0xKSxaPTEqMTAyNCoxMDI0O2lmKGxlLWllK0E+Wil0aHJvdyBuZXcgRXJyb3IoYEhXSlMgYm9vdHN0cmFwLVRMUzogVExTIGJsb2NrIChzaXplPSR7QX0sIGFsaWduPSR7Sn0pIGRvZXMgbm90IGZpdCB0aGUgJHtafS1ieXRlIGJyayB3aW5kb3cgYXQgX19oZWFwX2Jhc2U9MHgke2llLnRvU3RyaW5nKDE2KX0gXHUyMDE0IHJhaXNlIEJSS19SRVNFUlZFIChrZXJuZWxTcGF3bkhhbmRsZXIpIG9yIHNocmluayBUTFMuIFJlZnVzaW5nIGEgY29sbGlkaW5nIGJvb3RzdHJhcCBibG9jay5gKTtZZShTdCx3ZSxsZSksSSYmZWUmJnR5cGVvZiBlZS5ydW5DdG9ycz09ImZ1bmN0aW9uIiYmKEk9ITEsZWUucnVuQ3RvcnMoKSl9fWxldCBndD0oKCk9Pnt0cnl7aWYoIXdlfHx0eXBlb2Ygd2UuX193YXNtMzJfZ2V0X3Rsc19zaXplIT0iZnVuY3Rpb24ifHwhKHdlLl9fd2FzbTMyX2dldF90bHNfc2l6ZSgpPj4+MCkpcmV0dXJuITE7bGV0IEE9SC5leHBvcnRzO3JldHVybiB0eXBlb2YgQS5fX3dhc21faW5pdF90bHM9PSJmdW5jdGlvbiImJnR5cGVvZiBBLl9fd2FzbTMyX2dldF90bHNfc2l6ZT09ImZ1bmN0aW9uIiYmdHlwZW9mIEEuX193YXNtMzJfZ2V0X3Rsc19hbGlnbj09ImZ1bmN0aW9uIiYmQS5fX3dhc20zMl9nZXRfdGxzX3NpemUoKT4+PjAhPT0wfWNhdGNoe3JldHVybiExfX0pKCksZm49cihBPT57bGV0IEo9SC5leHBvcnRzLEM9Si5fX2hlYXBfYmFzZSxpZT1DIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsP0MudmFsdWU+Pj4wOnR5cGVvZiBDPT0ibnVtYmVyIj9DPj4+MDowO2lmKGllPT09MCl0aHJvdyBuZXcgRXJyb3IoIkhXSlMgbWFpbi1pbWFnZSBUTFM6IHRoZSBtYWluIGNhcnJpZXMgdGhyZWFkX2xvY2FsIHN0YXRlIGJlc2lkZSBhIFRMUy1vd25pbmcgbGliYy5zbyBidXQgZXhwb3J0cyBubyB1c2FibGUgX19oZWFwX2Jhc2UgXHUyMDE0IGNhbm5vdCBwbGFjZSB0aGUgcGVyLWxhbmUgbWFpbi1UTFMgc2xvdHMgKG5ldmVyLXNpbGVudCkuIik7cmV0dXJuIEhsKGllLEouX193YXNtMzJfZ2V0X3Rsc19zaXplKCk+Pj4wLEouX193YXNtMzJfZ2V0X3Rsc19hbGlnbigpPj4+MCxBKX0sIm1haW5JbWFnZVRsc1Nsb3QiKSxtdD1yKChBLEopPT57bGV0IEM9Zm4oQSk7aWYoQy5hZGRyPT09MCl7aWYoKEF8MCkhPT0wKXJldHVybiAwO3Rocm93IG5ldyBFcnJvcihgSFdKUyBtYWluLWltYWdlIFRMUzogb25lICR7Qy5zdHJpZGV9QiBzbG90IGZvciBhICR7SC5leHBvcnRzLl9fd2FzbTMyX2dldF90bHNfc2l6ZSgpPj4+MH1CLyR7Qy5hbGlnbn0tYWxpZ25lZCBtYWluIFRMUyBpbWFnZSBkb2VzIG5vdCBmaXQgaGFsZiB0aGUgJHtQcn1CIGJyayB3aW5kb3cgXHUyMDE0IHJlZnVzaW5nIGEgY29sbGlkaW5nIGNhcnZlIChuZXZlci1zaWxlbnQpLmApfXJldHVybiBKP0guZXhwb3J0cy5fX3dhc21faW5pdF90bHMoQy5hZGRyKTpILmV4cG9ydHMuX193YXNtMzJfc2V0X3Rsc19iYXNlKEMuYWRkcnwwKSxDLmFkZHJ9LCJiaW5kTWFpbkltYWdlVGxzIiksbnQ9cigoQSxKLEMpPT5ndD8oTyhBfDApLChKfDApPDA/ITE6bXQoSnwwLCEhQykhPT0wKTooZi5fX3dhc20zMl9zZXRfdGxzX2Jhc2UoQXwwKSxPKEF8MCksITApLCJiaW5kVGFza1Rsc0Jhc2UiKTtpZighamUmJmUubW9kZSE9PSJ0aHJlYWQiJiZndCl0cnl7bXQoMCwhMCl9Y2F0Y2goQSl7aWYoYXdhaXQgdSgiTUFJTi1UTFMiLEEpPT09InJldHVybiIpeyRuKCJlcnJvciIpO3JldHVybn1icmVhayBlfSFqZSYmdHlwZW9mIEguZXhwb3J0cy5fX3dhc21fYXBwbHlfZGF0YV9yZWxvY3M9PSJmdW5jdGlvbiImJkguZXhwb3J0cy5fX3dhc21fYXBwbHlfZGF0YV9yZWxvY3MoKTtsZXQgR3Q9dHlwZW9mIGYuX193YXNtMzJfY3RvcnNfcnVuX2luX3N0YXJ0PCJ1IjtpZighamUmJmtuLmxlbmd0aCl7bGV0IEE9WWwoe3RhYmxlOnplLG1lbW9yeTplLm1lbW9yeSxsaXN0OmtuLHNsb3RBZGRyOmYuX193YXNtMzJfbmVlZGVkX2N0b3JzX2luX3N0YXJ0KCl9KTtrbi5mb3JFYWNoKChKLEMpPT57dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtbGliYzogJHtKLnNvbmFtZX0gY3RvcnMgZGVmZXJyZWQgdG8gX3N0YXJ0IChtb2R1bGVJZD0ke0oubW9kdWxlSWR9LCB0YWJsZSAke0FbQ119JHtBLmRyaXZlbiYmSi5ydW5uZXI/YCwgcnVubmVyICR7Si5ydW5uZXJ9YDoiIn0pYH0pfWNhdGNoe319KSxrbj1bXX0hamUmJiFHdCYmdHlwZW9mIGYuX193YXNtX2NhbGxfY3RvcnM9PSJmdW5jdGlvbiImJmYuX193YXNtX2NhbGxfY3RvcnMoKSwoV3wwKT4wJiZ0eXBlb2YgZi5fX3dhc20zMl9zZXRfbGFuZV9pZD09ImZ1bmN0aW9uIiYmZi5fX3dhc20zMl9zZXRfbGFuZV9pZChXfDApLHR5cGVvZiBlLnNpZ25hbFBlbmRpbmdPZmZzZXQ9PSJudW1iZXIiJiZ0eXBlb2YgZi5fX3dhc20zMl9zZXRfc2lnbmFsX3JlZ2lvbj09ImZ1bmN0aW9uIiYmZi5fX3dhc20zMl9zZXRfc2lnbmFsX3JlZ2lvbihlLnNpZ25hbFBlbmRpbmdPZmZzZXQ+Pj4wKTtsZXQgdm49ZS5tb2RlPT09InRocmVhZCI/InRocmVhZCI6ImZvcmsiLGFuPW51bGwsQ249ITE7dHJ5e2lmKHZuPT09InRocmVhZCIpe2lmKFsuLi5qdC52YWx1ZXMoKSwuLi5CdF0uc29tZShBPT5BJiZBLmhhbmRsZSYmQS5oYW5kbGUudGxzJiZBLmhhbmRsZS50bHMudW5ib3VuZCkpe2F3YWl0IFMoMCwwKSx0KHtraW5kOiJ0aHJlYWQtcmVmdXNlZCIscGlkOmUucGlkLHRpZDplLnRpZCxtZXNzYWdlOiJzaWRlLW1vZHVsZSBUTFMgc2xvdCBwb29sIGV4aGF1c3RlZCAoMjU2IGRpc3RpbmN0IHVuam9pbmVkIHRocmVhZHMgY2FycnkgbGl2ZSB0aHJlYWRfbG9jYWwgc3RvcmFnZSBpbiBhIHNpZGUgbW9kdWxlOyBzbG90cyByZWN5Y2xlIGF0IHB0aHJlYWRfam9pbikuIHB0aHJlYWRfY3JlYXRlIHJldHVybnMgRUFHQUlOIChsb3VkLCBjb250YWluZWQsIG5ldmVyIHNpbGVudCkuIn0pO3JldHVybn1pZih0eXBlb2YgZi5fX3dhc20zMl9zZXRfc3RhY2tfcG9pbnRlcj09ImZ1bmN0aW9uIiYmZi5fX3dhc20zMl9zZXRfc3RhY2tfcG9pbnRlcihlLnN0YWNrUG9pbnRlck9mZnNldHwwKSx0eXBlb2YgZi5fX3dhc20zMl9zZXRfdGxzX2Jhc2U9PSJmdW5jdGlvbiIpe2xldCBBPXR5cGVvZiBlLm1haW5UbHNTbG90PT0ibnVtYmVyIj9lLm1haW5UbHNTbG90Olc+MD9XOjA7aWYoIW50KGUudGxzUG9pbnRlck9mZnNldCxBPDA/LTE6QSsxLCEwKSl7bGV0IEo9Zm4oMCkubGFuZXMtMTthd2FpdCBTKDAsMCksdCh7a2luZDoidGhyZWFkLXJlZnVzZWQiLHBpZDplLnBpZCx0aWQ6ZS50aWQsbWVzc2FnZTpgbWFpbi1pbWFnZSBUTFMgaGFzIG5vIHNsb3QgZm9yIHRoaXMgdGhyZWFkICgke0p9IHRocmVhZCBzbG90cyBmaXQgZm9yIGEgJHtILmV4cG9ydHMuX193YXNtMzJfZ2V0X3Rsc19zaXplKCk+Pj4wfUIgbWFpbiBUTFMgaW1hZ2UsIGF0IG1vc3QgMjU2OyBzbG90cyByZWN5Y2xlIGF0IHB0aHJlYWRfam9pbikuIHB0aHJlYWRfY3JlYXRlIHJldHVybnMgRUFHQUlOIChsb3VkLCBjb250YWluZWQsIG5ldmVyIHNpbGVudCkuYH0pO3JldHVybn19aWYodHlwZW9mIGYuX193YXNtMzJfdXNlcl9lbnRyeSE9ImZ1bmN0aW9uIil7dCh7a2luZDoiZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOiJ0aHJlYWQtbW9kZSBXb3JrZXIgbWlzc2luZyBfX3dhc20zMl91c2VyX2VudHJ5IGV4cG9ydCBcdTIwMTQgbGluayB3YXNtX3RocmVhZC5TIGludG8gdGhlIGJpbmFyeSJ9KTtyZXR1cm59aWYoVz4wKXtsZXQgQT1yKGllPT57aWYoTW4pdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YFt0aHItbGFuZSB0aWQ9JHtlLnRpZH0gbGFuZT0ke1d9XSAke2llfWB9KX1jYXRjaHt9fSwidGRiZyIpO2lmKEEoInRocmVhZCBhcm0gZW50ZXJlZCIpLG5zKGUsdCwidGhyZWFkLWFybS1lbnRlcmVkIiksIShoZSYmcSYmT2UmJnR5cGVvZiBmLl9faHdqc19sYW5lX2F0dGFjaD09ImZ1bmN0aW9uIiYmdHlwZW9mIGYuX193YXNtMzJfc2V0X2xhbmVfaWQ9PSJmdW5jdGlvbiImJnR5cGVvZiBmLl9faHdqc19sYW5lX2RldGFjaD09ImZ1bmN0aW9uIiYmYiE9PW51bGwpKXthd2FpdCBTKDAsMCksdCh7a2luZDoidGhyZWFkLXJlZnVzZWQiLHBpZDplLnBpZCx0aWQ6ZS50aWQsbWVzc2FnZTpgdGhyZWFkLW1vZGUgc3Bhd24gY2FycmllZCB1c2VyLVJUIGxhbmUgJHtXfSBidXQgdGhpcyBpbWFnZSBjYW5ub3QgZXhlY3V0ZSBpdDogbGFuZV9hZGRyZXNzZWQ9JHtoZT8xOjB9IGxhbmVkX3J0PSR7dHlwZW9mIGYuX19od2pzX2xhbmVfYXR0YWNoPT0iZnVuY3Rpb24iPzE6MH0gZmxhdF9kcml2ZT0ke09lPzE6MH0gc2V0X2xhbmVfaWQ9JHt0eXBlb2YgZi5fX3dhc20zMl9zZXRfbGFuZV9pZD09ImZ1bmN0aW9uIj8xOjB9IGNoYW5fYWRkcl9nbG9iYWw9JHtiIT09bnVsbD8xOjB9IFx1MjAxNCByZWJ1aWxkIHRoZSBpbWFnZSB3aXRoIGxhbmUtYXdhcmUgY2hhbm5lbCBhZGRyZXNzaW5nIChIV0pTX1JUX0xBTkVTPjEpIGFnYWluc3QgdGhlIGxhbmVkIFJULiBwdGhyZWFkX2NyZWF0ZSByZXR1cm5zIEVBR0FJTiAobG91ZCwgY29udGFpbmVkLCBuZXZlciBzaWxlbnQpLmB9KTtyZXR1cm59QSgibGFuZVJlYWR5OyBzZXRfbGFuZV9pZCIpLGYuX193YXNtMzJfc2V0X2xhbmVfaWQoV3wwKTtsZXQgQzt0cnl7QSgiYXR0YWNoLi4uIiksQz1mLl9faHdqc19sYW5lX2F0dGFjaChXfDApfDAsQShgYXR0YWNoIHJjPSR7Q31gKX1jYXRjaChpZSl7YXdhaXQgUygwLDApO2xldCBsZT0hMTt0cnl7dHlwZW9mIGYuX19od2pzX2xhbmVfb2NjdXBpZWQ9PSJmdW5jdGlvbiI/bGU9KGYuX19od2pzX2xhbmVfb2NjdXBpZWQoV3wwKXwwKSE9PTA6dHlwZW9mIGYuX19od2pzX2xhbmVfb2NjdXBhbmN5X3dvcmQ9PSJmdW5jdGlvbiImJihsZT0oV3wwKTwzMiYmKGYuX19od2pzX2xhbmVfb2NjdXBhbmN5X3dvcmQoKT4+PjA+Pj4oV3wwKSYxKSE9PTApfWNhdGNoe310KHtraW5kOiJ0aHJlYWQtcmVmdXNlZCIscGlkOmUucGlkLHRpZDplLnRpZCxsYW5lT2NjdXBpZWQ6bGUsbWVzc2FnZTpgbGFuZSAke1d9IGF0dGFjaCBWSU9MQVRFRCAoJHtpZSBpbnN0YW5jZW9mIEVycm9yP2llLm1lc3NhZ2U6U3RyaW5nKGllKX0pIFx1MjAxNCBvY2N1cGFuY3kvZ2VuZXJhdGlvbiBza2V3IGJldHdlZW4gdGhlIGtlcm5lbCBsZWRnZXIgYW5kIHRoZSBSVCB0YWJsZSR7bGU/YCAobGFuZSAke1d9IGlzIE9DQ1VQSUVEIGluIHRoZSBSVCB0YWJsZTogdGhlIGtlcm5lbCBwcm9taXNlIGlzIHF1YXJhbnRpbmVkLCBub3QgcmVjeWNsZWQpYDoiIn0uIENsb25lIHJlZnVzZWQgd2l0aCBFQUdBSU4gKG5ldmVyIHNpbGVudCkuYH0pO3JldHVybn1pZihDPD0wKXthd2FpdCBTKDAsMCk7bGV0IGllPXR5cGVvZiBmLl9faHdqc19sYW5lX2NhcD09ImZ1bmN0aW9uIj9mLl9faHdqc19sYW5lX2NhcCgpfDA6LTEsbGU9dHlwZW9mIGYuX19od2pzX2xhbmVfYmxvY2tfYnl0ZXM9PSJmdW5jdGlvbiI/Zi5fX2h3anNfbGFuZV9ibG9ja19ieXRlcygpPj4+MDowLFo9Qz09PS0xMj9gb3V0IG9mIE1FTU9SWTogdGhpcyBsYW5lJ3MgJHtsZXx8Ij8ifUIgcnVudGltZS1zdGF0ZSBibG9jayBjb3VsZCBub3QgYmUgbW1hcCdkICh0aGUgUlQgd3JvdGUgdGhlIHN5c2NhbGwncyBvd24gcmV0dXJuIHRvIHN0ZGVycikuIFRoZSBsYW5lIGNvdW50IGlzIE5PVCB0aGUgY29uc3RyYWludCBoZXJlYDpgb3V0IG9mIFNMT1RTOiBib290IHdhc20zMi50aHJlYWRfbGFuZXMgcHJvbWlzZWQgbGFuZSAke1d9LCBwYXN0IHRoZSBSVCBhcnRpZmFjdCdzIGNvbXBpbGVkIGNhcCAke2llPDA/Ij8iOmllfSBcdTIwMTQgcmVidWlsZCB0aGUgcnVudGltZSB3aXRoIGEgaGlnaGVyIEhXSlNfUlRfTEFORVNfQlVJTERgO3Qoe2tpbmQ6InRocmVhZC1yZWZ1c2VkIixwaWQ6ZS5waWQsdGlkOmUudGlkLG1lc3NhZ2U6YGxhbmUgJHtXfSBhdHRhY2ggcmVmdXNlZCByYz0ke0N9IChSVCBhcnRpZmFjdCBjYXAgJHtpZTwwPyI/IjppZX0pIFx1MjAxNCAke1p9LiBDbG9uZSByZWZ1c2VkIHdpdGggRUFHQUlOIChsb3VkLCBjYXRjaGFibGUpLmB9KTtyZXR1cm59bnMoZSx0LCJ0aHJlYWQtYWRvcHRlZC1wb3N0IiksdCh7a2luZDoidGhyZWFkLWFkb3B0ZWQiLHBpZDplLnBpZCx0aWQ6ZS50aWR9KSxDbj0hMH1lbHNlIGlmKHEmJihQdHx8ZWUpKXtsZXQgQT1fZSgiX19od2pzX3BhcmtlZCIpLEo9X2UoIl9faHdqc19wYXJrZWRfb3duZXIiKTtpZighQXx8IUopdGhyb3cgbmV3IEVycm9yKCJ0aHJlYWQgYXJtOiBjb3JvIGltYWdlIHdpdGhvdXQgdGhlIHBhcmtlZC1zbG90IHN1cmZhY2UgKF9faHdqc19wYXJrZWQvX293bmVyIGV4cG9ydHMpIFx1MjAxNCBjYW5ub3QgYWRvcHQgdGhlIHRocmVhZCBjaGFpbiAobmV2ZXItc2lsZW50KS4iKTtpZihmLl9fd2FzbTMyX3VzZXJfZW50cnkoZS5hcmdSZWdpb25PZmZzZXR8MCksc2UoKVtBPj4yXT09PTApe2lmKCFfKXRocm93IG5ldyBFcnJvcigidGhyZWFkIGFybTogX193YXNtMzJfdXNlcl9lbnRyeSByZXR1cm5lZCB3aXRoIGFuIEVNUFRZIHBhcmtlZCBzbG90IGFuZCBubyBleGl0IFx1MjAxNCB0aGUgdGhyZWFkIGNoYWluIG5laXRoZXIgcGFya2VkIGZvciBhZG9wdGlvbiBub3IgdGVybWluYXRlZCAobmV2ZXItc2lsZW50KS4iKX1lbHNle2xldCBDPWYuX19od2pzX3Rha2VfcGFya2VkKDAsMCk+Pj4wO3RyeXtmLmh3anNfZGVzdHJveShDKX1jYXRjaChpZSl7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YHRocmVhZCBhcm06IGh3anNfZGVzdHJveSBvZiB0aGUgcmVmdXNlZCB0aHJlYWQgY2hhaW4gdHJhcHBlZCAoJHtpZSBpbnN0YW5jZW9mIEVycm9yP2llLm1lc3NhZ2U6U3RyaW5nKGllKX0pIFx1MjAxNCBvbmUgY2hhaW4ncyBmcmFtZXMgbGVhayBpbiB0aGUgYXJlbmEgKGJvdW5kZWQsIGxvdWQpYH0pfWNhdGNoe319YXdhaXQgUygwLDApLHQoe2tpbmQ6InRocmVhZC1yZWZ1c2VkIixwaWQ6ZS5waWQsdGlkOmUudGlkLG1lc3NhZ2U6InRocmVhZC1tb2RlIHBsYWNlbWVudCByZXBsYXkgaXMgTElWRSAocnQgIzAgKyBsaWJjLnNvICMxIHJlcGxheWVkIGF0IHRoZSByZWNvcmRlZCBiYXNlcyBpbiB0aGlzIHRocmVhZCBXb3JrZXIpIGJ1dCB0aHJlYWQgRVhFQ1VUSU9OIG9uIHRoZSBjb3JvIHN1YnN0cmF0ZSBuZWVkcyB0aGUgSzcrIHBlci10aHJlYWQtcGFyayBsaWZ0IFx1MjAxNCB0aGUgdXNlci1ydCBkcml2ZSBzdXJmYWNlIChwYXJrZWQgc2xvdCAvIHhmZXIgdmVyZGljdCAvIGRyaXZlIGxlYWYgLyBmcmFtZSBhcmVuYSkgaXMgc2luZ2xlLWRyaXZlci1wZXItcHJvY2VzcyBzaGFyZWQgc3RhdGUuIHB0aHJlYWRfY3JlYXRlIGlzIHJlZnVzZWQgd2l0aCAtRUFHQUlOIChsb3VkLCBjb250YWluZWQ7IHRoZSB0aHJlYWQncyBrZXJuZWwgdGFzayBpcyByZWFwZWQgdG8gYSBwbGFpbiB6b21iaWUgYmVmb3JlIHJlZnVzYWwgXHUyMDE0IG5ldmVyIGEgc2lsZW50IGhhbmcsIGEgdG9ybiBwYXJrIHNsb3QsIG9yIGEgbGl2ZS10YXNrIGxlYWspLiJ9KTtyZXR1cm59fWVsc2V7dCh7a2luZDoidGhyZWFkLWFkb3B0ZWQiLHBpZDplLnBpZCx0aWQ6ZS50aWR9KTtsZXQgQT1mLl9fd2FzbTMyX3VzZXJfZW50cnkoZS5hcmdSZWdpb25PZmZzZXR8MCk7dHlwZW9mIEE9PSJudW1iZXIiJiYhXyYmKG09QSYyNTUpfX1pZihDbnx8dm4hPT0idGhyZWFkIiYmdHlwZW9mIGYuX3N0YXJ0PT0iZnVuY3Rpb24iKXtsZXQgQT0hbHQmJlRuIT09bnVsbCxKPUE/VG46ZS5tb2RlIT09ImZvcmstcmVzdW1lIj9lLmFyZ3Y6bnVsbCxDPUE/eXJ8fFtdOmUubW9kZSE9PSJmb3JrLXJlc3VtZSI/ZS5lbnZwOltdO2lmKEFycmF5LmlzQXJyYXkoSikmJkoubGVuZ3RoPjAmJnR5cGVvZiBmLl9fd2FzbTMyX2FyZ3NfYnVmX2FkZHI9PSJmdW5jdGlvbiIpe2xldCBpZT1KLm1hcChjdD0+U3RyaW5nKGN0KSksbGU9QXJyYXkuaXNBcnJheShDKT9DLm1hcChjdD0+U3RyaW5nKGN0KSk6W10sWj1mLl9fd2FzbTMyX2FyZ3NfYnVmX2FkZHIoKT4+PjAsVmU9dHlwZW9mIGYuX193YXNtMzJfYXJnc19idWZfc2l6ZT09ImZ1bmN0aW9uIj9mLl9fd2FzbTMyX2FyZ3NfYnVmX3NpemUoKXwwOjAsR2U9bmV3IFRleHRFbmNvZGVyLFFlPVsuLi5pZSwuLi5sZV0ubWFwKGN0PT5HZS5lbmNvZGUoY3QpKSxXdD10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52Py5IV0pTX1JFRF9OT19BVVhWPT09IjEiP1tdOls2LDQwOTYsMCwwXSxQZT1pZS5sZW5ndGgrMStsZS5sZW5ndGgrMSxLdD04LFZ0PUt0KyhQZStXdC5sZW5ndGgpKjQsYm49UWUucmVkdWNlKChjdCxQbik9PmN0K1BuLmxlbmd0aCsxLFZ0KTtpZihibj5WZSl7dCh7a2luZDoiZXJyb3IiLHBpZDplLnBpZCxtZXNzYWdlOmBhcmd2IGJsb2NrICgke2JufUIpIGV4Y2VlZHMgX193YXNtMzJfYXJnc19idWYgKCR7VmV9QilgfSk7cmV0dXJufWxldCB5dD1uZXcgRGF0YVZpZXcoZS5tZW1vcnkuYnVmZmVyKSxfbj1uZXcgVWludDhBcnJheShlLm1lbW9yeS5idWZmZXIpLEp0PUt0LGR0PTAsRHQ9cihjdD0+e2ZvcihsZXQgUG4gb2YgY3Qpe2xldCBRdD1RZVtkdCsrXSxHPVorVnQ7X24uc2V0KFF0LForVnQpLF9uW1orVnQrUXQubGVuZ3RoXT0wLFZ0Kz1RdC5sZW5ndGgrMSx5dC5zZXRVaW50MzIoWitKdCxHPj4+MCwhMCksSnQrPTR9eXQuc2V0VWludDMyKForSnQsMCwhMCksSnQrPTR9LCJ3cml0ZVZlYyIpO0R0KGllKSxEdChsZSk7Zm9yKGxldCBjdCBvZiBXdCl5dC5zZXRVaW50MzIoWitKdCxjdD4+PjAsITApLEp0Kz00O2lmKHl0LnNldFVpbnQzMihaKzAsaWUubGVuZ3RoPj4+MCwhMCkseXQuc2V0VWludDMyKForNCxsZS5sZW5ndGg+Pj4wLCEwKSx0dCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpgQVJHUy1CTE9DSyBwaWQ9JHtlLnBpZH0gJHtBPyJleGVjIjoiYm9vdCJ9IGJhc2U9MHgke1oudG9TdHJpbmcoMTYpfSBhcmdjPSR7aWUubGVuZ3RofSBlbnZjPSR7bGUubGVuZ3RofSBhdXh2PVske1d0LmpvaW4oIiwiKX1dIGF1eHZAMHgkeyhaK0t0K1BlKjQpLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fX1pZihxKXtsZXQgaWU9cihhc3luYygpPT50eXBlb2YgZi5fX2h3anNfYnVkZ2V0X3NldCE9ImZ1bmN0aW9uIj8hMTooZi5fX2h3anNfYnVkZ2V0X3NldChwYXwwKSxzcyhwYSksR3V8fGF3YWl0IGxyKCksITApLCJzZXJ2aWNlQ29vcGVyYXRpdmVCcmVhdGgiKTtpZihPZSl7bGV0IGxlPV9lKCJfX2h3anNfcGFya19yZWFzb24iKStXKjQsWj1fZSgiX19od2pzX3BhcmtfcmVzdWx0IikrVyo0LFZlPTUzNDA2LEdlPTUzNDA3LFFlPTAsZXQ9MCxJdD10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52LkhXSlNfRkxBVF9DRU5TVVM9PT0iMSIsV3Q9dHlwZW9mIHBlcmZvcm1hbmNlPCJ1IiYmdHlwZW9mIHBlcmZvcm1hbmNlLm5vdz09ImZ1bmN0aW9uIj8oKT0+cGVyZm9ybWFuY2Uubm93KCk6KCk9PkRhdGUubm93KCksUGU9e05PTkU6MCxGT1JLOjAsRVhFQzowLFJFU0NIRUQ6MCxET05FOjAsb3RoZXI6MCx3YXNtQ2FsbHM6MCx0V2FzbU1zOjAsdEhvc3RNczowfSxLdD0hMSxWdD1yKHZlPT57aWYoIUl0fHxLdClyZXR1cm47S3Q9ITA7bGV0IHllPVBlLk5PTkUrUGUuRk9SSytQZS5FWEVDK1BlLlJFU0NIRUQsUmU9YGh3anMtZmxhdC1jZW5zdXMgcGlkPSR7c1tNLlBJRF18MH0gKCR7dmV9KTogaG9zdC1yZWVudHJpZXM9JHt5ZX0gW05PTkU9JHtQZS5OT05FfSBGT1JLPSR7UGUuRk9SS30gRVhFQz0ke1BlLkVYRUN9IFJFU0NIRUQ9JHtQZS5SRVNDSEVEfV0gRE9ORT0ke1BlLkRPTkV9IG90aGVyPSR7UGUub3RoZXJ9OyB3YXNtQ2FsbHM9JHtQZS53YXNtQ2FsbHN9IHRXYXNtPSR7UGUudFdhc21Ncy50b0ZpeGVkKDEpfW1zIHRIb3N0PSR7UGUudEhvc3RNcy50b0ZpeGVkKDEpfW1zIChhdmcvY3Jvc3Npbmc6IHdhc209JHsoUGUudFdhc21Ncy9NYXRoLm1heCgxLFBlLndhc21DYWxscykpLnRvRml4ZWQoMyl9bXMgaG9zdD0keyhQZS50SG9zdE1zL01hdGgubWF4KDEseWUpKS50b0ZpeGVkKDMpfW1zKWA7dCh7a2luZDoiZG1lc2ciLGxldmVsOjYsdGV4dDpSZX0pO3RyeXtjb25zb2xlLmVycm9yKFJlKX1jYXRjaHt9fSwiZW1pdEZsYXRDZW5zdXMiKTtVZT1WdDtsZXQgYm49MCx5dD1yKHZlPT57bGV0IHllPVRvKCk7cGUmJihwZS5pbldhc209ITAscGUubGFzdERyaXZlRW50ZXJUPURhdGUubm93KCkpO3RyeXtpZighSXQpe2lmKCFwZSlyZXR1cm4gdmUoKT4+PjA7bGV0IGNlPXZlKCk+Pj4wO3BlLmluV2FzbT0hMSxwZS5sYXN0RHJpdmVSZXRUPURhdGUubm93KCkscGUubGFzdFN0YXR1cz1jZSxwZS5sYXN0U3RhdHVzVD1wZS5sYXN0RHJpdmVSZXRUO2xldCBiZT0iMHgiK2NlLnRvU3RyaW5nKDE2KTtyZXR1cm4gcGUuc3RhdHVzZXNbYmVdPShwZS5zdGF0dXNlc1tiZV18MCkrMSxjZX1sZXQgUmU9Kytibjt0cnl7Y29uc29sZS5lcnJvcihgaHdqcy1mbGF0LWRyaXZlY2FsbCAjJHtSZX0gRU5URVIgcGlkPSR7c1tNLlBJRF18MH0gdD0ke1d0KCkudG9GaXhlZCgwKX1gKX1jYXRjaHt9bGV0IEVlPVd0KCksV2U9dmUoKT4+PjA7UGUudFdhc21Ncys9V3QoKS1FZSxQZS53YXNtQ2FsbHMrKzt0cnl7Y29uc29sZS5lcnJvcihgaHdqcy1mbGF0LWRyaXZlY2FsbCAjJHtSZX0gUkVUVVJOIHN0YXR1cz0weCR7KFdlPj4+MCkudG9TdHJpbmcoMTYpfSBkdD0keyhXdCgpLUVlKS50b0ZpeGVkKDApfW1zYCl9Y2F0Y2h7fXJldHVybiBXZX1maW5hbGx5e2pvKHllKX19LCJkcml2ZUNhbGwiKTtpZih0eXBlb2YgZi5fX2h3anNfZHJpdmVfcmVzdW1lIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiTS1GTEFURFJJVkU6IGZsYXQgaW1hZ2UgKF9faHdqc19kcml2ZV9hYmkoKT09PTMpIHdpdGhvdXQgdGhlIF9faHdqc19kcml2ZV9yZXN1bWUgcmUtZW50cnkgZXhwb3J0IFx1MjAxNCB0aGUgRjEwNyBpbi13YXNtIGRyaXZlciBjb250cmFjdCBpcyBpbmNvbXBsZXRlOyByZWZ1c2luZyB0byBkcml2ZSBibGluZC4iKTtsZXQgX249X2UoIl9faHdqc19mb3JrX3N0dyIpLEp0PV9lKCJfX2h3anNfZm9ya19zdHdfc2VxIiksZHQ9X2UoIl9faHdqc19mb3JrX3N0d19hY2siKSxEdD1fZSgiX19od2pzX2Zvcmtfc3R3X2luc2xpY2UiKSxjdD0hIShfbiYmSnQmJmR0JiZEdCYmdHlwZW9mIGYuX19od2pzX2ZvcmtfYmFycmllcl9vaz09ImZ1bmN0aW9uIik7Y3Q/U2U9e3N0d0lkeDpfbj4+MixzZXFJZHg6SnQ+PjIsYWNrSWR4OmR0K1cqND4+MixtaXJJZHg6RHQrVyo0Pj4yLGxhbmU6V3wwfTpTZT1udWxsO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nyx0ZXh0OmBod2pzLWZvcmstc3R3IHBpZD0ke3NbTS5QSURdfDB9IHRpZD0ke2UudGlkfSBsYW5lPSR7V30gJHtjdD8iQVJNRUQiOiJhYnNlbnQifSAoc3R3PTB4JHtfbi50b1N0cmluZygxNil9IGFjaz0weCR7ZHQudG9TdHJpbmcoMTYpfSBtaXI9MHgke0R0LnRvU3RyaW5nKDE2KX0pYH0pfWNhdGNoe31sZXQgUG49cihhc3luYygpPT57aWYoIVNlKXJldHVybjtsZXQgdmU9U2UseWU9MDtmb3IoOzspe2lmKChBdG9taWNzLmxvYWQoQWUoKSx2ZS5zdHdJZHgpfDApPT09MCl7aWYoQXRvbWljcy5zdG9yZShBZSgpLHZlLm1pcklkeCwxKSwoQXRvbWljcy5sb2FkKEFlKCksdmUuc3R3SWR4KXwwKT09PTApcmV0dXJuO0F0b21pY3Muc3RvcmUoQWUoKSx2ZS5taXJJZHgsMCl9bGV0IFJlPUF0b21pY3MubG9hZChBZSgpLHZlLnN0d0lkeCl8MDtpZihSZSE9PTApe2lmKCF5ZSl7eWU9RGF0ZS5ub3coKTt0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjcsdGV4dDpgaHdqcy1mb3JrLXN0dyBwaWQ9JHtzW00uUElEXXwwfSBsYW5lPSR7dmUubGFuZX06IHNsaWNlLWVudHJ5IGdhdGUgSEVMRCAoZ2VuPSR7UmV9KWB9KX1jYXRjaHt9fWxldCBFZT1BdG9taWNzLndhaXRBc3luYyhBZSgpLHZlLnN0d0lkeCxSZSwyNTApO2lmKEVlLmFzeW5jKXRyeXthd2FpdCBFZS52YWx1ZX1jYXRjaHt9aWYoeWUmJkRhdGUubm93KCkteWU+MWU0KXt5ZT1EYXRlLm5vdygpO2xldCBXZT1gaHdqcy1mb3JrLXN0dyBwaWQ9JHtzW00uUElEXXwwfSBsYW5lPSR7dmUubGFuZX06IGhlbGQgYXQgdGhlIHNsaWNlLWVudHJ5IGdhdGUgZm9yID4xMHMgdW5kZXIgZ2VuZXJhdGlvbiAke1JlfSBcdTIwMTQgdGhlIGZvcmtpbmcgbGFuZSdzIHNlcnZpY2VyIGhhcyBub3QgcmVsZWFzZWQ7IHN0aWxsIGhvbGRpbmcgKGxvdWQsIG5ldmVyIHNpbGVudClgO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OldlfSl9Y2F0Y2h7fXRyeXtjb25zb2xlLmVycm9yKFdlKX1jYXRjaHt9fX19fSwic3R3R2F0ZSIpLFF0PXIoYXN5bmMgdmU9Pnthd2FpdCBQbigpO3RyeXtyZXR1cm4geXQodmUpfWZpbmFsbHl7U2UmJkF0b21pY3Muc3RvcmUoQWUoKSxTZS5taXJJZHgsMCl9fSwiZHJpdmVTbGljZSIpLEc9cigoKT0+e2lmKCFTZSlyZXR1cm47bGV0IHZlPVNlO2Zvcig7Oyl7aWYoKEF0b21pY3MubG9hZChBZSgpLHZlLnN0d0lkeCl8MCk9PT0wKXtpZihBdG9taWNzLnN0b3JlKEFlKCksdmUubWlySWR4LDEpLChBdG9taWNzLmxvYWQoQWUoKSx2ZS5zdHdJZHgpfDApPT09MClyZXR1cm47QXRvbWljcy5zdG9yZShBZSgpLHZlLm1pcklkeCwwKX1sZXQgeWU9QXRvbWljcy5sb2FkKEFlKCksdmUuc3R3SWR4KXwwO3llIT09MCYmQXRvbWljcy53YWl0KEFlKCksdmUuc3R3SWR4LHllLDI1MCl9fSwic3R3R2F0ZVN5bmMiKSxLPXIoKCk9PntTZSYmQXRvbWljcy5zdG9yZShBZSgpLFNlLm1pcklkeCwwKX0sInN0d01pcnJvckNsZWFyIiksZ2U9dHlwZW9mIHByb2Nlc3M8InUiJiZwcm9jZXNzLmVudiYmcHJvY2Vzcy5lbnYuSFdKU19OT19ET05FX1RFUk1JTlVTX0RJU1BBVENIPT09IjEiLEllPXIoKCk9PntHKCk7dHJ5e3JldHVybiBSdCgpfWZpbmFsbHl7SygpfX0sImRpc3BhdGNoRG9uZUxpdmUiKSxSdD1yKCgpPT57bGV0IHZlPV9lKCJfX2h3anNfc3RhdHVzX2NoYW5uZWwiKSx5ZT12ZT92ZStXKjMyOjAsUmU9eWU/c2UoKVt5ZT4+Ml0+Pj4wOjAsRWU9cihXZT0+e2xldCBjZT1gZHJpdmUgRE9ORV9UT1Agd2l0aCBsaXZlIHN0YXR1cyAke1JlfSBcdTIwMTQgJHtXZX1gO3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Myx0ZXh0OmBbaHdqcy1ceEE3NC10ZXJtaW51cyBwaWQ9JHtzW00uUElEXXwwfV0gJHtjZX1gfSl9Y2F0Y2h7fXRocm93IG5ldyBFcnJvcihgTS1GTEFURFJJVkUgXHhBNzQgdGVybWludXM6ICR7Y2V9YCl9LCJyZWZ1c2UiKTtpZih5ZXx8RWUoInRoZSBkcml2ZXIgcmV0dXJuZWQgSFdKU19EUklWRV9ET05FX0xJVkUgYnV0IHRoZSBpbWFnZSBleHBvcnRzIG5vIF9faHdqc19zdGF0dXNfY2hhbm5lbCBkYXRhIFx1MjAxNCBkcml2ZS1zdGF0dXMvY2hhbm5lbCBjb250cmFjdCBza2V3IiksUmU9PT0yKXtnZSYmRWUoImFuIHVuY2F1Z2h0IGV4Y2VwdGlvbiBjb21wbGV0ZWQgdW5kZXIgdGhlIGRyaXZlciBhbmQgdGhlIFx4QTc0IGRpc3BhdGNoIGlzIERJU0FCTEVEIChIV0pTX05PX0RPTkVfVEVSTUlOVVNfRElTUEFUQ0g9MSwgUkVEIGFybSkgXHUyMDE0IHJlZnVzaW5nIHJhdGhlciB0aGFuIHJlcG9ydGluZyBhIGNsZWFuIERPTkUiKSx0eXBlb2YgZi5fX2h3anNfdW5jYXVnaHRfdW53aW5kaW5nIT0iZnVuY3Rpb24iJiZFZSgibm8gX19od2pzX3VuY2F1Z2h0X3Vud2luZGluZyBleHBvcnQgdG8gY29uc3VtZSBpdCAodGhlIFJUIHdlYWsgZmFsbGJhY2sgaXMgcGFydCBvZiB0aGUgYWJpLTQgZXhwb3J0IHN1cmZhY2UgXHUyMDE0IGl0cyBhYnNlbmNlIGlzIGEgbGluay9tYW5pZmVzdCBkZWZlY3QpIik7bGV0IFdlPXNlKClbeWUrOD4+Ml0+Pj4wO2YuX19od2pzX3VuY2F1Z2h0X3Vud2luZGluZyhXZSk7bGV0IGNlPXNlKClbeWU+PjJdPj4+MDtpZihjZT09PTEmJnR5cGVvZiBmLl9faHdqc19zdGF0dXNfYWRvcHRfdG9wPT0iZnVuY3Rpb24iJiZ0eXBlb2YgZi5fX2h3anNfZHJpdmVfYWRvcHRfcGFya2VkPT0iZnVuY3Rpb24iKXtsZXQgYmU9Zi5fX2h3anNfc3RhdHVzX2Fkb3B0X3RvcCgpPj4+MDtyZXR1cm4gZi5od2pzX2RvbmUoYmUpfDAmJkVlKCJ0aGUgdGVybWludXMgY2hhaW4gcGFya2VkIGJ1dCBpdHMgYWRvcHRlZCB0b3AgaXMgRE9ORSAocGFyayBwcm90b2NvbCBicmVhY2gpIiksZi5fX2h3anNfZHJpdmVfYWRvcHRfcGFya2VkKCk+Pj4wfUVlKGBfX2h3anNfdW5jYXVnaHRfdW53aW5kaW5nIFJFVFVSTkVEIHdpdGhvdXQgdGVybWluYXRpbmcgdGhlIHByb2Nlc3MgYW5kIHdpdGhvdXQgYSBwYXJrZWQgY2hhbm5lbCBcdTIwMTQgdGhlIGhvb2sgbXVzdCB0ZXJtaW5hdGUgb3IgcGFyayAoY2hhbm5lbCBub3cgJHtjZX0pYCl9UmU9PT0zJiYodHlwZW9mIGYuX19od2pzX3N0YXR1c19sb25nam1wX2xvc3Q9PSJmdW5jdGlvbiImJmYuX19od2pzX3N0YXR1c19sb25nam1wX2xvc3QoKSxFZSgibG9uZ2ptcCB0YXJnZXQgbm90IGZvdW5kIChkZWFkLCBzdGFsZSwgb3IgZm9yZWlnbiBqbXBfYnVmKSBhbmQgbm8gX19od2pzX3N0YXR1c19sb25nam1wX2xvc3QgZXhwb3J0IHRvIHJlcG9ydCBpdCBmYWl0aGZ1bGx5IikpLEVlKCJub3QgYSBceEE3NCB0ZXJtaW51cyByb3cgKE5PUk1BTC9QQVJLRUQvY29ycnVwdCBjaGFubmVsIHdvcmQgYXJyaXZlZCB3aXRoIEhXSlNfRFJJVkVfRE9ORV9MSVZFIFx1MjAxNCB0aGUgUlQgY29uc3VtZXMgUEFSS0VEIG9uIGl0cyBQQVJLIGxlZyBhbmQgdmlvbGF0ZXMgaW4tbG9vcCBvbiBhIHBhcmtlZCBET05FLCBzbyB0aGlzIGlzIGRyaXZlLXByb3RvY29sIHNrZXcpIil9LCJkaXNwYXRjaERvbmVMaXZlSW5uZXIiKSxYdD1yKCgpPT57RygpO3RyeXtCbigpfWZpbmFsbHl7SygpfX0sInRocmVhZExhbmVUZWFyZG93biIpLEJuPXIoKCk9PntpZihldD0wLHNlKClbbGU+PjJdPUplLHR5cGVvZiBmLl9faHdqc19sYW5lX2FyZW5hX3Jlc2V0PT0iZnVuY3Rpb24iKXRyeXtmLl9faHdqc19sYW5lX2FyZW5hX3Jlc2V0KFd8MCl9Y2F0Y2goRWUpe3Qoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpgdGhyZWFkIGxhbmUgJHtXfSBhcmVuYSByZXNldCBSRUZVU0VEIGF0IHRlcm1pbnVzICgke0VlIGluc3RhbmNlb2YgRXJyb3I/RWUubWVzc2FnZTpTdHJpbmcoRWUpfSkgXHUyMDE0IHRoZSBjaGFpbiB3YXMgbWlkLWZsaWdodCwgbm90IGF0IGEgY2xlYW4gdGVybWludXMgKG5ldmVyIHNpbGVudClgfSl9bGV0IHZlPV9lKCJfX2h3anNfZnJhbWVfbGl2ZSIpLHllPXZlP3NlKClbdmUrVyo0Pj4yXT4+PjA6MDtpZih0eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52JiZwcm9jZXNzLmVudi5IV0pTX0FSRU5BX0NFTlNVUyl7bGV0IEVlPV9lKCJfX2h3anNfZnJhbWVfaGlnaF93YXRlciIpLFdlPV9lKCJfX2h3anNfZnJhbWVfYWxsb2NzIik7dCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOmBod2pzLWFyZW5hLWNlbnN1cyBsYW5lICR7V30gcGVhayBidW1wLWNvbW1pdHRlZCAke0VlP3NlKClbRWUrVyo0Pj4yXT4+PjA6MH0gQiBpbiAke1dlP3NlKClbV2UrVyo0Pj4yXT4+PjA6MH0gYWxsb2NzICh0aGlzIGxhbmUncyB3aG9sZSBsaWZlOyB0aGUgc3RhdGljIGJvb3RzdHJhcCBzbGljZSBpcyB3aGF0IGhhcyB0byBjb3ZlciBpdCBiZWZvcmUgdGhlIGZpcnN0IG1tYXApYH0pfXllIT09MCYmdCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOmB0aHJlYWQgbGFuZSAke1d9IHRlcm1pbnVzIHdpdGggJHt5ZX0gbGl2ZSBhcmVuYSBmcmFtZShzKSBhZnRlciByZWNsYWltIFx1MjAxNCBhIGdlbnVpbmUgcGVyLWxhbmUgbGVhayAodGhlIGRldGFjaCBiZWxvdyByZWZ1c2VzOyB0aGUgbGFuZSBpcyBsb3N0LCBsb3VkbHk7IG5ldmVyIHNpbGVudClgfSk7bGV0IFJlPSExO3RyeXtmLl9faHdqc19sYW5lX2RldGFjaChXfDApLFJlPSEwfWNhdGNoKEVlKXt0KHtraW5kOiJ1c2VyLXJlcG9ydCIscGlkOmUucGlkLG1lc3NhZ2U6YHRocmVhZCBsYW5lICR7V30gZGV0YWNoIFJFRlVTRUQgYXQgdGVybWludXMgKCR7RWUgaW5zdGFuY2VvZiBFcnJvcj9FZS5tZXNzYWdlOlN0cmluZyhFZSl9KSBcdTIwMTQgbGFuZSBRVUFSQU5USU5FRDogdGhlIGtlcm5lbCBsZWRnZXIgcmVsZWFzZSBpcyB3aXRoaGVsZCBzbyBib3RoIGxlZGdlcnMgYWdyZWUgdGhlIGxhbmUgc3RheXMgaGVsZCAobmV2ZXIgYSByZS1wcm9taXNlIG9mIGFuIG9jY3VwaWVkIGxhbmUpOyB0aGlzIHByb2Nlc3MncyB0aHJlYWQgY2FwIGlzIHBlcm1hbmVudGx5IGRvd24gYnkgb25lIChsb3VkLCBhdHRyaWJ1dGVkKWB9KX10cnl7aWYoUmUmJkYmJnR5cGVvZiBGLmV4cG9ydHMuX193YXNtMzJfdGhyZWFkX2xhbmVfcmVsZWFzZT09ImZ1bmN0aW9uIil7bGV0IEVlPUYuZXhwb3J0cy5fX3dhc20zMl90aHJlYWRfbGFuZV9yZWxlYXNlKGUucHBpZHwwLFd8MCl8MDtFZSE9PTAmJnQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpga2VybmVsIGxhbmUtbGVkZ2VyIHJlbGVhc2UobGVhZGVyPSR7ZS5wcGlkfDB9LCBsYW5lPSR7V30pIHJldHVybmVkICR7RWV9YCsoRWU9PT0tM3x8RWU9PT0tMj8iIFx1MjAxNCBubyBwcm9taXNlIHJlY29yZGVkIHVuZGVyIHRoaXMgbGVhZGVyL2xhbmUgKGxlYWstZnJlZSBieSBjb25zdHJ1Y3Rpb246IHRoZSBsZWRnZXIgaG9sZHMgbm8gYnVkZ2V0IGhlcmUpIGJ1dCB0aGUgbGVkZ2VycyBhcmUgU0tFV0VEIFx1MjAxNCByZXBvcnQgaXQiOiIgXHUyMDE0IHRoZSBwcm9taXNlIGlzIHN0aWxsIGhlbGQ7IGEgbGVha2VkIGxlZGdlciBsYW5lIHN1cmZhY2VzIGFzIHByZW1hdHVyZSBFQUdBSU4gY2FwIGV4aGF1c3Rpb24iKSsiIChsb3VkLCBhdHRyaWJ1dGVkKSJ9KX19Y2F0Y2goRWUpe3Qoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpga2VybmVsIGxhbmUtbGVkZ2VyIHJlbGVhc2UgdHJhcHBlZDogJHtFZSBpbnN0YW5jZW9mIEVycm9yP0VlLm1lc3NhZ2U6U3RyaW5nKEVlKX1gfSl9fSwidGhyZWFkTGFuZVRlYXJkb3duSW5uZXIiKTtwZSYmKHBlLnJlYXNvbkFkZHI9bGUscGUucmVzdWx0QWRkcj1aLHBlLnRpbWVyJiZjbGVhckludGVydmFsKHBlLnRpbWVyKSxwZS50aW1lcj1zZXRJbnRlcnZhbCgoKT0+e2lmKF8pe2NsZWFySW50ZXJ2YWwocGUudGltZXIpLHBlLnRpbWVyPW51bGw7cmV0dXJufWxjKCJTQU1QTEUiKX0sMWU0KSx0eXBlb2YgcGUudGltZXIudW5yZWY9PSJmdW5jdGlvbiImJnBlLnRpbWVyLnVucmVmKCkpO2xldCBhdCxGbj10eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52JiZwcm9jZXNzLmVudi5BNENfRk9SS0RCRyxxdD1yKHZlPT57aWYoRm4pdHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YFthNGMtZm9yayB0aWQ9JHtlLnRpZH0gbW9kZT0ke2UubW9kZX1dICR7dmV9YH0pfWNhdGNoe319LCJmZGJnIik7dHJ5e2lmKGUubW9kZT09PSJtaWdyYXRlLXJlc3VtZSImJmx0KXtpZihxdChgRkxBVCBtaWdyYXRlLXJlc3VtZSBlbnRyeTogYmluZGluZyB0bHMvc3Agb24gY3B1PSR7ZS5jcHVJZHwwfSAodXNlckxhbmU9JHtXfSB0YXNrPTB4JHsoZS5taWdyYXRlVGFza0FkZHI+Pj4wKS50b1N0cmluZygxNil9KWApLHR5cGVvZiBmLl9fd2FzbTMyX3NldF9sYW5lX2lkPT0iZnVuY3Rpb24iJiZmLl9fd2FzbTMyX3NldF9sYW5lX2lkKFd8MCksdHlwZW9mIGUudGxzQmFzZT09Im51bWJlciImJnR5cGVvZiBmLl9fd2FzbTMyX3NldF90bHNfYmFzZT09ImZ1bmN0aW9uIiYmIW50KGUudGxzQmFzZSxXfDAsITEpKXRocm93IG5ldyBFcnJvcihgbWlncmF0ZS1yZXN1bWU6IG5vIG1haW4taW1hZ2UgVExTIHNsb3QgZm9yIGxhbmUgJHtXfDB9IFx1MjAxNCByZWZ1c2luZyB0byByZXN1bWUgd2l0aCB0aGUgbWFpbidzIF9fdGxzX2Jhc2UgdW5ib3VuZCAobmV2ZXItc2lsZW50KS5gKTt0eXBlb2YgZS5zcD09Im51bWJlciImJmUuc3AhPT0wJiZ0eXBlb2YgZi5fX3dhc20zMl9zZXRfc3RhY2tfcG9pbnRlcj09ImZ1bmN0aW9uIiYmZi5fX3dhc20zMl9zZXRfc3RhY2tfcG9pbnRlcihlLnNwPj4+MCk7bGV0IHZlPXNlKClbbGU+PjJdPj4+MDtpZih2ZSE9PUplKXRocm93IG5ldyBFcnJvcihgbWlncmF0ZS1yZXN1bWU6IGFycml2ZWQgd2l0aCBhIFBFTkRJTkcgcGFyayByZWFzb24gJHt2ZX0gXHUyMDE0IHRoZSBzb3VyY2Ugb2ZmZXJzIG9ubHkgZnJvbSBhIHNlcnZpY2VkIHBhcmssIHdoZXJlIHRoZSBzbG90IGlzIGFscmVhZHkgY2xlYXIgKG5ldmVyLXNpbGVudClgKTtpZighQ2QoKSl0aHJvdyBuZXcgRXJyb3IoIm1pZ3JhdGUtcmVzdW1lOiB0aGUgb2ZmZXIgd2FzIGFscmVhZHkgdGVybWluYWwgd2hlbiB0aGlzIGRlc3RpbmF0aW9uIGZpbmlzaGVkIGJpbmRpbmcgKHRoZSBzb3VyY2Ugb3IgdGhlIGhvc3QgYWJvcnRlZCBpdCBmaXJzdCkgXHUyMDE0IGRyb3BwaW5nIHRoZSBwbGFjZW1lbnQgd2l0aG91dCBkcml2aW5nOyB0aGUgdGFzayBpcyB0aGUgc291cmNlJ3MiKTtDdCh0LGBNSUdSQVRFLUlOIGNwdT0ke2UuY3B1SWR8MH0gdGlkPSR7ZS50aWR9IHBpZD0ke3NbTS5QSURdfDB9IGxhbmU9JHtXfWApLGF0PWF3YWl0IFF0KGYuX19od2pzX2RyaXZlX3Jlc3VtZSkscXQoYEFGVEVSIGRyaXZlQ2FsbChfX2h3anNfZHJpdmVfcmVzdW1lKSBbbWlncmF0ZV0gc3RhdHVzPTB4JHsoYXQ+Pj4wKS50b1N0cmluZygxNil9YCl9ZWxzZSBpZihlLm1vZGU9PT0iZm9yay1yZXN1bWUiJiZsdCl7cXQoYEZMQVQgZm9yay1yZXN1bWUgZW50cnk6IHNldHRpbmcgdGxzL3NwLCByZXN1bHQ9MCAoZm9ya0xhbmU9JHtlLmZvcmtMYW5lfDB8fDB9IHVzZXJMYW5lPSR7V30gc3R3Q2FwYWJsZT0ke2N0PzE6MH0pYCksdHlwZW9mIGUudGxzQmFzZT09Im51bWJlciImJnR5cGVvZiBmLl9fd2FzbTMyX3NldF90bHNfYmFzZT09ImZ1bmN0aW9uIiYmbnQoZS50bHNCYXNlLDAsITEpLHR5cGVvZiBlLnBhcmVudFNwPT0ibnVtYmVyIiYmZS5wYXJlbnRTcCE9PTAmJnR5cGVvZiBmLl9fd2FzbTMyX3NldF9zdGFja19wb2ludGVyPT0iZnVuY3Rpb24iJiZmLl9fd2FzbTMyX3NldF9zdGFja19wb2ludGVyKGUucGFyZW50U3A+Pj4wKTtsZXQgdmU9c2UoKVtsZT4+Ml0+Pj4wO2lmKHZlIT09SmUpdGhyb3cgbmV3IEVycm9yKGBNLUZMQVREUklWRTogZm9yay1yZXN1bWUgY2hpbGQgY29waWVkIGEgUEVORElORyBwYXJrIHJlYXNvbiAke3ZlfSBcdTIwMTQgdGhlIHBhcmVudCBjbGVhcnMgdGhlIHJlYXNvbiBiZWZvcmUgdGhlIGRlbHRhPTAgY29weSBieSBjb250cmFjdGApO2lmKGN0KXtpZih0eXBlb2YgZi5fX3dhc20zMl9zZXRfbGFuZV9pZD09ImZ1bmN0aW9uIiYmZi5fX3dhc20zMl9zZXRfbGFuZV9pZChXfDApLHR5cGVvZiBmLl9faHdqc19mb3JrX2NoaWxkX2NvbGxhcHNlIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiZm9yay1yZXN1bWUgY2hpbGQ6IExBTkVEIGltYWdlIChTVFcgc3VyZmFjZSBwcmVzZW50KSB3aXRob3V0IF9faHdqc19mb3JrX2NoaWxkX2NvbGxhcHNlIFx1MjAxNCBza2V3ZWQgUlQvYXJ0aWZhY3QgcGFpcjsgcmVmdXNpbmcgdG8gcmVzdW1lIG92ZXIgZ2hvc3QgbGFuZSBvY2N1cGFuY3kgKG5ldmVyLXNpbGVudCkuIik7aWYoZi5fX2h3anNfZm9ya19jaGlsZF9jb2xsYXBzZShXfDApLChXfDApPjApaWYoRiYmdHlwZW9mIEYuZXhwb3J0cy5fX3dhc20zMl91c2VyX2xhbmVfc2VlZD09ImZ1bmN0aW9uIil7bGV0IHllPUYuZXhwb3J0cy5fX3dhc20zMl91c2VyX2xhbmVfc2VlZChzW00uUElEXXwwLFd8MCl8MDt5ZSE9PTAmJnQoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpgZm9yay1yZXN1bWUgY2hpbGQgbGFuZS1sZWRnZXIgc2VlZChwaWQ9JHtzW00uUElEXXwwfSwgbGFuZT0ke1d9KSByZXR1cm5lZCAke3llfSBcdTIwMTQgdGhlIGNoaWxkJ3MgZmlyc3QgcHRocmVhZF9jcmVhdGUgbWF5IGNvbGxpZGUgb24gaXRzIG93biBtYWluIGxhbmUgKGxvdWQsIGF0dHJpYnV0ZWQpYH0pfWVsc2UgdCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOmBmb3JrLXJlc3VtZSBjaGlsZCBvbiBsYW5lICR7V30gYnV0IHRoZSBrZXJuZWwgZXhwb3J0cyBubyBfX3dhc20zMl91c2VyX2xhbmVfc2VlZCBcdTIwMTQgc3RhbGUgdm1saW51eDsgdGhlIGNoaWxkJ3MgZmlyc3QgcHRocmVhZF9jcmVhdGUgbWF5IGNvbGxpZGUgb24gaXRzIG93biBtYWluIGxhbmUgKGxvdWQsIGF0dHJpYnV0ZWQpYH0pfXNlKClbWj4+Ml09MCxxdCgiQkVGT1JFIGRyaXZlQ2FsbChfX2h3anNfZHJpdmVfcmVzdW1lKSBbZm9yay1yZXN1bWUgaW5pdGlhbF0iKSxhdD1hd2FpdCBRdChmLl9faHdqc19kcml2ZV9yZXN1bWUpLHF0KGBBRlRFUiBkcml2ZUNhbGwoX19od2pzX2RyaXZlX3Jlc3VtZSkgUkVUVVJORUQgc3RhdHVzPTB4JHsoYXQ+Pj4wKS50b1N0cmluZygxNil9YCl9ZWxzZSBpZihDbil7aWYocXQoYFRIUkVBRCBsYW5lPSR7V30gZW50cnk6IF9fd2FzbTMyX3VzZXJfZW50cnkgcmFtcGApLE1uKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbdGhyLWxhbmUgdGlkPSR7ZS50aWR9IGxhbmU9JHtXfV0gcHVtcCBlbnRyeTogY2FsbGluZyBfX3dhc20zMl91c2VyX2VudHJ5KDB4JHsoZS5hcmdSZWdpb25PZmZzZXQ+Pj4wKS50b1N0cmluZygxNil9KWB9KX1jYXRjaHt9aWYoYXdhaXQgUXQoKCk9PihmLl9fd2FzbTMyX3VzZXJfZW50cnkoZS5hcmdSZWdpb25PZmZzZXR8MCksMCkpLE1uKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBbdGhyLWxhbmUgdGlkPSR7ZS50aWR9XSBlbnRyeSByZXR1cm5lZDsgZXhpdFBvc3RlZD0ke199YH0pfWNhdGNoe31pZihfKXtYdCgpO3JldHVybn1sZXQgdmU9X2UoIl9faHdqc19zdGF0dXNfY2hhbm5lbCIpK1cqMzIseWU9c2UoKVt2ZT4+Ml0+Pj4wO2lmKHF0KGBUSFJFQUQgZW50cnkgY2hhbm5lbCBzdGF0dXM9JHt5ZX1gKSx5ZT09PTApe1h0KCk7YnJlYWt9aWYoeWUhPT0xKXRocm93IG5ldyBFcnJvcihgdGhyZWFkIGxhbmUgZW50cnk6IGNoYW5uZWwgc3RhdHVzICR7eWV9IGFmdGVyIGVudHJ5IChub3QgTk9STUFML1BBUktFRCkgXHUyMDE0IGRyaXZlLXN0YXR1cyBwcm90b2NvbCBza2V3LmApO2lmKHR5cGVvZiBmLl9faHdqc19zdGF0dXNfYWRvcHRfdG9wIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigidGhyZWFkIGxhbmUgZW50cnk6IHBhcmtlZCBjaGFubmVsIGJ1dCBubyBfX2h3anNfc3RhdHVzX2Fkb3B0X3RvcCBleHBvcnQgKGFiaTQgc3VyZmFjZSBkZWZlY3QpLiIpO2xldCBSZT1mLl9faHdqc19zdGF0dXNfYWRvcHRfdG9wKCk+Pj4wO2lmKGYuaHdqc19kb25lKFJlKXwwKXRocm93IG5ldyBFcnJvcigidGhyZWFkIGxhbmUgZW50cnk6IHBhcmtlZCBjaGFubmVsIGJ1dCB0aGUgYWRvcHRlZCB0b3AgaXMgRE9ORSAocGFyayBwcm90b2NvbCBicmVhY2g7IG5ldmVyLXNpbGVudCkuIik7ZXQ9UmUsYXQ9YXdhaXQgUXQoZi5fX2h3anNfZHJpdmVfYWRvcHRfcGFya2VkKSxxdChgVEhSRUFEIGFkb3B0IHN0YXR1cz0weCR7KGF0Pj4+MCkudG9TdHJpbmcoMTYpfWApfWVsc2UgcXQoIkJFRk9SRSBkcml2ZUNhbGwoX3N0YXJ0KSBbZnJlc2hdIiksYXQ9YXdhaXQgUXQoZi5fc3RhcnQpLHF0KGBBRlRFUiBkcml2ZUNhbGwoX3N0YXJ0KSBSRVRVUk5FRCBzdGF0dXM9MHgkeyhhdD4+PjApLnRvU3RyaW5nKDE2KX1gKTtmb3IodCh7a2luZDoiaHdqcy1ob3N0LWRyaXZlLWZsYXQiLHBpZDplLnBpZH0pOzspe2lmKF8pe1Z0KCJleGl0X2dyb3VwIik7cmV0dXJufWlmKGF0PT09R2UmJihhdD1JZSgpPj4+MCksYXQhPT1ZbiYmVWkoKSxhdD09PVZlKXtQZS5ET05FKyssQ24mJlh0KCk7YnJlYWt9aWYoYXQ9PT1EYSl7aWYoIUNuJiZXPT09MCl0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy10aHJlYWRzIHBpZD0ke3NbTS5QSURdfDB9OiBwdGhyZWFkX2V4aXQgZnJvbSB0aGUgTUFJTiB0aHJlYWQgXHUyMDE0IHRyZWF0aW5nIGFzIHByb2Nlc3MgY29tcGxldGlvbiAoa25vd24gcmVzaWR1YWw6IHNpYmxpbmdzIGFyZSBub3QgYXdhaXRlZClgfSl9Y2F0Y2h7fUNuJiZYdCgpLG09MDticmVha31sZXQgdmU9SXQ/V3QoKTowO2lmKGF0PT09SHQpe2lmKFBlLkZPUksrKywhb3QpdGhyb3cgbmV3IEVycm9yKCJNLUZMQVREUklWRTogRk9SSyBwYXJrIHdpdGhvdXQgYSBsYXRjaGVkIFNZU19mb3JrIFx1MjAxNCB0aGUgcGFyayBsZWFmIGZpcmVkIG91dHNpZGUgdGhlIG11c2wgX0ZvcmsgcHJvdG9jb2wiKTtpZihvdD0hMSx0eXBlb2YgZi5fX2h3anNfZm9ya19iYXJyaWVyX29rIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiTS1GTEFURFJJVkUgZm9yayBsYXRjaDogY29ybyBpbWFnZSBsYWNrcyBfX2h3anNfZm9ya19iYXJyaWVyX29rIFx1MjAxNCByZWZ1c2luZyB0aGUgZGVsdGE9MCBjb3B5IHdpdGhvdXQgdGhlIHN0cnVjdHVyYWwgYmFycmllciBwcmVkaWNhdGUgKEFEUi0wMDA0IEY4NyBjb25mICg0KSkiKTtzZSgpW2xlPj4yXT1KZTtsZXQgeWU9Y3QmJnR5cGVvZiBwcm9jZXNzPCJ1IiYmcHJvY2Vzcy5lbnYmJnByb2Nlc3MuZW52LkhXSlNfUkVEX0ZPUktfTk9fQUxMTEFORV9RVUlFU0NFPT09IjEiLFJlPSExLEVlPXIoKCk9PntSZSYmKFJlPSExLEF0b21pY3Muc3RvcmUoQWUoKSxTZS5zdHdJZHgsMCksQXRvbWljcy5ub3RpZnkoQWUoKSxTZS5zdHdJZHgpKX0sInN0d1JlbGVhc2UiKSxXZT1yKGJlPT57bGV0IGJ0PSIiO3RyeXtsZXQgWGU9X2UoIl9faHdqc19wYXJrX3JlYXNvbiIpLHp0PV9lKCJfX2h3anNfcGFya2VkIiksTj1fZSgiX19od2pzX3N0YXR1c19jaGFubmVsIiksdWU9W10sWT1NYXRoLm1pbih0eXBlb2YgZi5fX2h3anNfbGFuZV9jYXA9PSJmdW5jdGlvbiI/Zi5fX2h3anNfbGFuZV9jYXAoKXwwOjgsNjQpO2ZvcihsZXQgVGU9MDtUZTxZO1RlKyspe2xldCBxZT1BdG9taWNzLmxvYWQoQWUoKSxEdCtUZSo0Pj4yKXwwLEtlPUF0b21pY3MubG9hZChBZSgpLGR0K1RlKjQ+PjIpfDAsaHQ9c2UoKVtYZStUZSo0Pj4yXT4+PjAsd3Q9c2UoKVt6dCtUZSo0Pj4yXT4+PjAsJHQ9c2UoKVtOK1RlKjMyPj4yXT4+PjA7KHFlfHxLZXx8aHR8fHd0fHwkdCkmJnVlLnB1c2goYEwke1RlfXttaXI9JHtxZX0gYWNrPSR7S2V9IHJzbj0ke2h0fSBwaz0weCR7d3QudG9TdHJpbmcoMTYpfSBzdD0keyR0fX1gKX1pZihidD11ZS5sZW5ndGg/YCBbJHt1ZS5qb2luKCIgIil9XWA6IiBbYWxsLWNsZWFyXSIsdHlwZW9mIGYuX19od2pzX2ZvcmtfYmFycmllcl93aHk9PSJmdW5jdGlvbiIpe2xldCBUZT1mLl9faHdqc19mb3JrX2JhcnJpZXJfd2h5KCk+Pj4wLHFlPVsicXVpZXNjZWQiLCJtaWQtZHJpdmUtdW5taXJyb3JlZCIsIm1pZC1kcml2ZS1uby1hY2siLCJwYXJrZWQtc2xvdCIsImxqLWFjdGl2ZSIsInBhcmstcmVhc29uIiwieGZlci1wZW5kaW5nIiwic3RhdHVzLW5vbi1ub3JtYWwiXTtidCs9YCB3aHk9bGFuZSR7VGU+Pjh9OiR7cWVbVGUmMjU1XT8/VGUmMjU1fWB9fWNhdGNoe2J0PSIgW2R1bXAtZmFpbGVkXSJ9bGV0IHB0PWBod2pzLWZvcmstc3R3IHBpZD0ke3NbTS5QSURdfDB9IGxhbmU9JHtXfTogZm9yayBSRUZVU0VEIHdpdGggRUFHQUlOIFx1MjAxNCAke2JlfSR7YnR9IChsb3VkLCBhdHRyaWJ1dGVkLCBQT1NJWC1sZWdhbDsgdGhlIGd1ZXN0J3MgZm9yaygpIG9ic2VydmVzIC1FQUdBSU4gYW5kIGxpdmVzIFx1MjAxNCBwbGFuIFx4QTczIEkxKWA7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6cHR9KX1jYXRjaHt9dHJ5e3Qoe2tpbmQ6InVzZXItcmVwb3J0IixwaWQ6ZS5waWQsbWVzc2FnZTpwdH0pfWNhdGNoe310cnl7Y29uc29sZS5lcnJvcihwdCl9Y2F0Y2h7fXNlKClbWj4+Ml09LTExfSwiZm9ya1JlZnVzZUVhZ2FpbiIpLGNlPSEwO2lmKHllKXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6NCx0ZXh0OmBod2pzLWZvcmstc3R3IHBpZD0ke3NbTS5QSURdfDB9IGxhbmU9JHtXfTogUkVEX05PUVVJRVNDRSBcdTIwMTQgY2FsbGluZy1sYW5lLW9ubHkgZm9yayBiYXJyaWVyOyB0aGUgZGVsdGE9MCBjb3B5IHdpbGwgcmFjZSBsaXZlIHNpYmxpbmcgbGFuZXMgKHRlc3Qga25vYilgfSl9Y2F0Y2h7fWVsc2UgaWYoY3Qpe2xldCBidD1EYXRlLm5vdygpKzFlNCxwdD0wO2Zvcig7Oyl7bGV0IFhlPUF0b21pY3MuYWRkKEFlKCksU2Uuc2VxSWR4LDEpKzF8MDtpZihwdD1YZT09PTA/MTpYZSxBdG9taWNzLmNvbXBhcmVFeGNoYW5nZShBZSgpLFNlLnN0d0lkeCwwLHB0KT09PTApe1JlPSEwO2JyZWFrfWlmKERhdGUubm93KCk+YnQpYnJlYWs7bGV0IHp0PUF0b21pY3MubG9hZChBZSgpLFNlLnN0d0lkeCl8MDtpZih6dCE9PTApe2xldCBOPUF0b21pY3Mud2FpdEFzeW5jKEFlKCksU2Uuc3R3SWR4LHp0LDEwMCk7aWYoTi5hc3luYyl0cnl7YXdhaXQgTi52YWx1ZX1jYXRjaHt9fX1pZighUmUpV2UoImNvdWxkIG5vdCBhY3F1aXJlIHRoZSBmb3JrIHN0b3AtdGhlLXdvcmxkIHdvcmQgd2l0aGluIDEwMDAwIG1zIChhbm90aGVyIGxhbmUncyBmb3JrIHNlcnZpY2UgaXMgaG9sZGluZyBpdCkiKSxjZT0hMTtlbHNle2xldCBYZT0wLHp0PSIiLE49cigoKT0+dHlwZW9mIGYuX19od2pzX2ZvcmtfYmFycmllcl93aHk9PSJmdW5jdGlvbiI/Zi5fX2h3anNfZm9ya19iYXJyaWVyX3doeSgpPj4+MDo2NTUzNSwid2h5Tm93IiksdWU9RGF0ZS5ub3coKSsxZTQsWT0wO2Zvcig7WGU9Zi5fX2h3anNfZm9ya19iYXJyaWVyX29rKCl8MCxYZSE9PTE7KXtpZihZPT09MHx8WSU1MDA9PT0yNTApe2xldCBUZT1OKCkscWU9VGU+PjgsS2U9QXRvbWljcy5sb2FkKEFlKCksRHQrcWUqND4+Mil8MCxodD1BdG9taWNzLmxvYWQoQWUoKSxkdCtxZSo0Pj4yKXwwLHd0PXNlKClbX2UoIl9faHdqc19wYXJrX3JlYXNvbiIpK3FlKjQ+PjJdPj4+MCwkdD1zZSgpW19lKCJfX2h3anNfcGFya2VkIikrcWUqND4+Ml0+Pj4wO3p0Kz1gIEAke1l9OjB4JHtUZS50b1N0cmluZygxNil9e20ke0tlfSBhJHtodH0gciR7d3R9IHAkeyR0LnRvU3RyaW5nKDE2KX19YH1pZihZKyssRGF0ZS5ub3coKT51ZSlicmVhazthd2FpdCBuZXcgUHJvbWlzZShUZT0+c2V0VGltZW91dChUZSwyKSl9WGUhPT0xJiYoenQrPWAgQGZpbmFsOjB4JHtOKCkudG9TdHJpbmcoMTYpfShiPSR7WGV9KWAsRWUoKSxXZShgdGhlIGFsbC1sYW5lcyBmb3JrIGJhcnJpZXIgZGlkIG5vdCByZWFjaCBxdWllc2NlIHdpdGhpbiAxMDAwMCBtcyB3aHlUcmFpbFtsYW5lOmNsYXVzZV06JHt6dH0gKF9faHdqc19mb3JrX2JhcnJpZXJfb2s9JHtYZX06ICR7WGU9PT0tMT8iYSBsYW5lIGlzIG1pZC1zbGljZSBhbmQgbm90IGhvc3QtaGVsZCI6ImEgbGFuZSBob2xkcyBpbi1mbGlnaHQgcHJvdG9jb2wgc3RhdGUifSlgKSxjZT0hMSl9fWVsc2V7bGV0IGJlPWYuX19od2pzX2ZvcmtfYmFycmllcl9vaygpfDA7aWYoYmUhPT0xKXRocm93IG5ldyBFcnJvcihgTS1GTEFURFJJVkUgZm9yayBsYXRjaCAke2JlPT09LTE/IlJFRlVTRUQiOiJub3QgcXVpZXNjZWQifTogX19od2pzX2ZvcmtfYmFycmllcl9vaz0ke2JlfSBcdTIwMTQgdGhlIGRlbHRhPTAgd2hvbGUtbWVtb3J5IGNvcHkgaXMgYSB3aG9sZS1hcmVuYSBwcmVkaWNhdGUsIGxlZ2FsIGF0IGJhcnJpZXItcXVpZXNjZSBvbmx5IChBRFItMDAwNCBGODcgY29uZiAoNCkpYCl9aWYoY2UpdHJ5e2xldCBiZT1hd2FpdCB1byh7aGFuZGxlOjAsb3duZXI6MH0pO3NlKClbWj4+Ml09YmV8MH1jYXRjaChiZSl7aWYoIWN0KXRocm93IEVlKCksYmU7V2UoYGZvcmsgc2VydmljZSBmYWlsZWQ6ICR7YmUgaW5zdGFuY2VvZiBFcnJvcj9iZS5tZXNzYWdlOlN0cmluZyhiZSl9YCl9ZmluYWxseXtFZSgpfXRlPSEwfWVsc2UgaWYoYXQ9PT1NdCl7aWYoUGUuRVhFQysrLHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBGTEFULUVYRUMtU0VSVklDRSBzdGF0dXM9SFdKU19QQVJLX0VYRUMgcGF0aD0iJHtubn0iYH0pfWNhdGNoe31pZighc3QpdGhyb3cgbmV3IEVycm9yKCJNLUZMQVREUklWRTogRVhFQyBwYXJrIHdpdGhvdXQgYSBsYXRjaGVkIFNZU19leGVjdmUgXHUyMDE0IHRoZSBwYXJrIGxlYWYgZmlyZWQgb3V0c2lkZSB0aGUgbXVzbCBleGVjdmUgcHJvdG9jb2wiKTtzdD0hMTtsZXQgeWU9YXdhaXQgcG8obm4sb3MpLFJlPW5uO2lmKG5uPW51bGwsb3M9MCx5ZSYmeWUub2smJnllLndhc21CeXRlcyl7SXQmJihQZS50SG9zdE1zKz1XdCgpLXZlKSxWdCgiZXhlY3ZlIiksYW49eWUud2FzbUJ5dGVzLHdzPVJlO2JyZWFrfXNlKClbbGU+PjJdPUplLHNlKClbWj4+Ml09eWUmJnR5cGVvZiB5ZS5lcnJubz09Im51bWJlciI/eWUuZXJybm98MDotMix0ZT0hMH1lbHNlIGlmKGF0PT09QXQpe2lmKHR0KXRyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLXN5cyBwaWQ9JHtzW00uUElEXXwwfSBGTEFULURMT1BFTi1TRVJWSUNFIHN0YXR1cz1IV0pTX1BBUktfRExPUEVOIHBhdGhQdHI9MHgkeyhicj4+PjApLnRvU3RyaW5nKDE2KX1gfSl9Y2F0Y2h7fWlmKCFhbyl0aHJvdyBuZXcgRXJyb3IoIkhXSlMtNTogRExPUEVOIHBhcmsgd2l0aG91dCBhIGxhdGNoZWQgU1lTX3dhc21fZGxvcGVuIFx1MjAxNCB0aGUgcGFyayBsZWFmIGZpcmVkIG91dHNpZGUgdGhlIG11c2wgZGxvcGVuIHByb3RvY29sIik7YW89ITEsc2UoKVtsZT4+Ml09SmU7bGV0IHllPXR5cGVvZiBmLl9faHdqc19kcml2ZV9uZXN0X2RlcHRoPT0iZnVuY3Rpb24iP2YuX19od2pzX2RyaXZlX25lc3RfZGVwdGgoKT4+PjA6LTEsUmU7dHJ5e1JlPWF3YWl0IGZyKHtsb2FkOnIoKCk9PlpkKGJyfDAsITApLCJsb2FkIikseWllbGRUdXJuOnIoKCk9PmZzKCJETE9QRU4tTE9BRCBwYXJrIHNlcnZpY2UiKSwieWllbGRUdXJuIiksb25ZaWVsZDpyKCgpPT57aXQmJkN0KHQsYFlJRUxEIGNwdT0ke2UuY3B1SWQ/PyI/In0gdGlkPSR7ZS50aWR9IHJlYXNvbj1ETE9QRU4tTE9BRC1wYXJrIHNpdGU9ZGxvcGVuLXBhcmstc2VydmljZSB2aWE9d2FrZS13b3JkYCl9LCJvbllpZWxkIil9KX1jYXRjaChFZSl7bGV0IFdlPUZsKEVlKSxjZT1XZS5jbHM9PT0iYWxsb2MiPyIgfCAjNzAgcGVyLVdvcmtlciBzby1tb2R1bGUgYWNjb3VudGluZzogIitrYSgpOiIiO1V0PWBbJHtXZS5jbHN9IC0+ICR7V2UuZXJybm9OYW1lfV0gJHtXZS5tZXNzYWdlfWArY2U7bGV0IGJlPWBIV0pTLTUgZGxvcGVuIHNlcnZpY2UgZmFpbGVkICgke1dlLmNsc30gLT4gJHtXZS5lcnJub05hbWV9ICR7V2UuZXJybm99KTogJHtXZS5tZXNzYWdlfWArY2U7dCh7a2luZDoidXNlci1yZXBvcnQiLHBpZDplLnBpZCxtZXNzYWdlOmJlfSk7dHJ5e2NvbnNvbGUuZXJyb3IoYFtod2pzLWRsb3BlbiBwaWQ9JHtlLnBpZH1dICR7YmV9YCl9Y2F0Y2h7fVJlPVdlLmVycm5vfDAseWU+PTAmJmYuX19od2pzX2RyaXZlX25lc3RfdW53aW5kX3RvKHllKSxzZSgpW2xlPj4yXT1KZX1icj0wLHNlKClbWj4+Ml09UmV8MCx0ZT0hMH1lbHNlIGlmKGF0PT09SmUpe1BlLk5PTkUrKyxRZSsrLGF3YWl0IGllKCkmJih0ZT0hMCk7bGV0IHllPXR5cGVvZiBmLl9fd2FzbV9zaWduYWxfZGlzcGF0Y2hfcGVuZGluZz09ImZ1bmN0aW9uIj8oKCk9PmYuX193YXNtX3NpZ25hbF9kaXNwYXRjaF9wZW5kaW5nKCkpOnR5cGVvZiBmLl9fd2FzbTMyX3NpZ25hbF9kaXNwYXRjaF9yZXN0YXJ0PT0iZnVuY3Rpb24iPygoKT0+Zi5fX3dhc20zMl9zaWduYWxfZGlzcGF0Y2hfcmVzdGFydCgwKSk6bnVsbDtpZihHcygpJiZ5ZSYmdHlwZW9mIGYuX19od2pzX3Rha2VfcGFya2VkPT0iZnVuY3Rpb24iJiZ0eXBlb2YgZi5fX2h3anNfZHJpdmU9PSJmdW5jdGlvbiIpe2xldCBSZT1fZSgiX19od2pzX3BhcmtlZCIpO2F3YWl0IFF0KCgpPT57aWYoeWUoKSwoUmU/c2UoKVtSZT4+Ml0+Pj4wOjApIT09MCl7bGV0IFdlPWYuX19od2pzX3Rha2VfcGFya2VkKDAsMCk+Pj4wLGNlPWYuX19od2pzX2RyaXZlKFdlKT4+PjA7aWYoY2UhPT1WZSl0aHJvdyBuZXcgRXJyb3IoIk0tRkxBVERSSVZFIGJyZWF0aC1kaXNwYXRjaDogdGhlIGxpYmMgc2lnbmFsLWRpc3BhdGNoIHRyYW1wb2xpbmUgUEFSS0VEIChzdGF0dXMgMHgiK2NlLnRvU3RyaW5nKDE2KSsiKSBpbnN0ZWFkIG9mIGNvbXBsZXRpbmcgXHUyMDE0IGEgc2lnbmFsIGhhbmRsZXIgYmxvY2tlZCBhdCB0aGUgYnJlYXRoIGRlbGl2ZXJ5IHBvaW50LCB3aGljaCB3b3VsZCBjb3JydXB0IHRoZSBwYXJrZWQgbWFpbiBjaGFpbi4gUmVmdXNpbmcgdG8gY29udGludWUgdGhpcyB0YXNrLiIpfXJldHVybiAwfSksdGU9ITB9fWVsc2UgaWYoYXQ9PT1Zbil7aWYoUGUuUkVTQ0hFRCsrLHNlKClbbGU+PjJdPUplLEYmJnR5cGVvZiBGLmV4cG9ydHMuX193YXNtMzJfbWlncmF0ZV9wZW5kaW5nPT0iZnVuY3Rpb24iKXtsZXQgUmU9MDt0cnl7UmU9Ri5leHBvcnRzLl9fd2FzbTMyX21pZ3JhdGVfcGVuZGluZygpPj4+MH1jYXRjaHtSZT0wfWlmKFJlPjApe2xldCBFZT1SZS0xfDA7aWYoRWUhPT0oZS5jcHVJZHwwKSl7aWYoYXdhaXQgUGQoRWUpKXtoPSEwO2JyZWFrfX19fWxldCB5ZT1pdD9VbigpOjA7Q3QodCxgWUlFTEQgY3B1PSR7ZS5jcHVJZD8/Ij8ifSB0aWQ9JHtlLnRpZH0gcmVhc29uPVJFU0NIRUQtcGFyayBzaXRlPWZsYXQtZHJpdmUgdmlhPSR7c24hPT1udWxsPyJjb29wLWZ1dGV4Ijoid2FrZS13b3JkIn1gKSxzbiE9PW51bGw/YXdhaXQgTWEoIk0tRkxBVERSSVZFIik6YXdhaXQgZnMoIk0tRkxBVERSSVZFIiksaXQmJkN0KHQsYFJFU1VNRSBjcHU9JHtlLmNwdUlkPz8iPyJ9IHRpZD0ke2UudGlkfSBzaXRlPWZsYXQtZHJpdmUgd2FpdGVkPSR7KFVuKCkteWUpLnRvRml4ZWQoMSl9bXNgKSx0ZT0hMH1lbHNle1BlLm90aGVyKys7dHJ5e2xldCB5ZT1fZSgiX19od2pzX3BhcmtlZCIpO3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YFthNGQtZGlhZ10gdW5leHBlY3RlZCBzdGF0dXM9MHgkeyhhdD4+PjApLnRvU3RyaW5nKDE2KX0gcmVhc29uU2xvdD0weCR7KHNlKClbbGU+PjJdPj4+MCkudG9TdHJpbmcoMTYpfSByZXN1bHRTbG90PTB4JHsoc2UoKVtaPj4yXT4+PjApLnRvU3RyaW5nKDE2KX0gcGFya2VkPTB4JHsoeWU/c2UoKVt5ZT4+Ml0+Pj4wOjApLnRvU3RyaW5nKDE2KX0gYnVkZ2V0PSR7dHlwZW9mIGYuX19od2pzX2J1ZGdldF9nZXQ9PSJmdW5jdGlvbiI/Zi5fX2h3anNfYnVkZ2V0X2dldCgpOiJuL2EifWB9KX1jYXRjaHt9dGhyb3cgbmV3IEVycm9yKCJNLUZMQVREUklWRTogdW5leHBlY3RlZCBpbi13YXNtIGRyaXZlciBzdGF0dXMgMHgiKyhhdD4+PjApLnRvU3RyaW5nKDE2KSsiIFx1MjAxNCBub3QgYSBQQVJLIHJlYXNvbiAoMCBOT05FIC8gMSBGT1JLIC8gMiBFWEVDIC8gNCBSRVNDSEVEKSBhbmQgbm90IEhXSlNfRFJJVkVfRE9ORSAoMHhEMDlFKSAvIEhXSlNfRFJJVkVfRE9ORV9MSVZFICgweEQwOUYpLiBUaGUgX3N0YXJ0KCkvX19od2pzX2RyaXZlX3Jlc3VtZSgpIHJldHVybiBjb250cmFjdCBkaXZlcmdlZDsgc3RvcC1hbmQtcmVwb3J0LCBkbyBub3QgbG9vcC4iKX10ZSYmKHR5cGVvZiBmLl9faHdqc19wcm9ncmVzc19ub3RlPT0iZnVuY3Rpb24iJiZmLl9faHdqc19wcm9ncmVzc19ub3RlKCksdGU9ITEpLEl0JiYoUGUudEhvc3RNcys9V3QoKS12ZSksZCgpLHF0KCJCRUZPUkUgcmUtZHJpdmUgZHJpdmVDYWxsKF9faHdqc19kcml2ZV9yZXN1bWUpIFtsb29wXSIpLGF0PWF3YWl0IFF0KGYuX19od2pzX2RyaXZlX3Jlc3VtZSkscXQoYEFGVEVSIHJlLWRyaXZlIFJFVFVSTkVEIHN0YXR1cz0weCR7KGF0Pj4+MCkudG9TdHJpbmcoMTYpfWApfX1maW5hbGx5e1Z0KCJmbGF0LWRyaXZlLWVuZCIpfWlmKGgpe3RyeXt0KHtraW5kOiJkbWVzZyIsbGV2ZWw6Nix0ZXh0OmBod2pzLW1pZ3JhdGUgcGlkPSR7c1tNLlBJRF18MH06IHJlbGVhc2VkIGJ5IGNwdT0ke2UuY3B1SWR8MH0gYWZ0ZXIgdGhlIGRlc3RpbmF0aW9uIGNvbW1pdHRlZCBcdTIwMTQgdGhpcyBXb3JrZXIgc3RvcHMgZHJpdmluZyB0aGUgdGFzayBhbmQgcnVucyBOTyBleGl0IHBhdGggKHRoZSBwcm9jZXNzIGlzIGFsaXZlIG9uIGFub3RoZXIgbGFuZSlgfSl9Y2F0Y2h7fXJldHVybn19ZWxzZXtsZXQgbGU9X2UoIl9faHdqc19wYXJrZWQiKSxaPV9lKCJfX2h3anNfcGFya2VkX293bmVyIiksVmU9X2UoIl9faHdqc19wYXJrX3JlYXNvbiIpLEdlPV9lKCJfX2h3anNfcGFya19yZXN1bHQiKSxRZT0wLGV0PTAsSXQ9ITAsV3Q9MCxQZT10eXBlb2YgZi5fX2h3anNfc2xpY2VfZW50ZXI9PSJmdW5jdGlvbiI/Zi5fX2h3anNfc2xpY2VfZW50ZXI6bnVsbCxLdD10eXBlb2YgZi5fX2h3anNfc2xpY2VfZXhpdD09ImZ1bmN0aW9uIj9mLl9faHdqc19zbGljZV9leGl0Om51bGw7aWYoZS5tb2RlPT09ImZvcmstcmVzdW1lIiYmbHQpe2lmKFFlPXR5cGVvZiBlLmZvcmtIYW5kbGU9PSJudW1iZXIiP2UuZm9ya0hhbmRsZT4+PjA6MCxldD10eXBlb2YgZS5mb3JrT3duZXI9PSJudW1iZXIiP2UuZm9ya093bmVyPj4+MDowLCFRZSl0aHJvdyBuZXcgRXJyb3IoIkhXSlMtMzogZm9yay1yZXN1bWUgY2hpbGQgd2l0aG91dCBhIGZvcmtIYW5kbGUgcmlkZXIgXHUyMDE0IHRoZSBwYXJlbnQgcHVtcCBtdXN0IHBhc3MgdGhlIGFkb3B0ZWQgKGhhbmRsZSwgb3duZXIpIG9uIHRoZSBmb3JrIG1lc3NhZ2UgKHRoZSB0YWtlbiBzbG90IGlzIGVtcHR5IGJ5IGRlc2lnbikiKTt0eXBlb2YgZS50bHNCYXNlPT0ibnVtYmVyIiYmdHlwZW9mIGYuX193YXNtMzJfc2V0X3Rsc19iYXNlPT0iZnVuY3Rpb24iJiZudChlLnRsc0Jhc2UsMCwhMSksdHlwZW9mIGUucGFyZW50U3A9PSJudW1iZXIiJiZlLnBhcmVudFNwIT09MCYmdHlwZW9mIGYuX193YXNtMzJfc2V0X3N0YWNrX3BvaW50ZXI9PSJmdW5jdGlvbiImJmYuX193YXNtMzJfc2V0X3N0YWNrX3BvaW50ZXIoZS5wYXJlbnRTcD4+PjApO2xldCBWdD1zZSgpW1ZlPj4yXT4+PjA7aWYoVnQhPT1KZSl0aHJvdyBuZXcgRXJyb3IoYEhXSlMtMzogZm9yay1yZXN1bWUgY2hpbGQgY29waWVkIGEgUEVORElORyBwYXJrIHJlYXNvbiAke1Z0fSBcdTIwMTQgdGhlIHBhcmVudCBwdW1wIGNsZWFycyB0aGUgcmVhc29uIGJlZm9yZSB0aGUgZGVsdGE9MCBjb3B5IGJ5IGNvbnRyYWN0YCk7c2UoKVtHZT4+Ml09MCxJdD0hMX1lbHNle2xldCBWdD1UbygpO2lmKFBlJiZQZSgpLGYuX3N0YXJ0KCksS3QmJkt0KCksam8oVnQpLHNlKClbbGU+PjJdPT09MCl0aHJvdyBuZXcgRXJyb3IoIkhXSlMtMzogX3N0YXJ0IHJldHVybmVkIHdpdGggYW4gRU1QVFkgcGFya2VkIHNsb3QgXHUyMDE0IHRoZSBwcm9ncmFtIGNoYWluIG5laXRoZXIgcGFya2VkIG5vciBleGl0ZWQ7IF9fbGliY19zdGFydF9tYWluIGNvbXBsZXRlZCAobm9yZXR1cm4gY29udHJhY3QgYnJlYWNoKSIpO2V0PXNlKClbWj4+Ml0+Pj4wLFFlPWYuX19od2pzX3Rha2VfcGFya2VkKDAsMCk+Pj4wLHQoe2tpbmQ6Imh3anMtaG9zdC1kcml2ZSIscGlkOmUucGlkLGhhbmRsZTpRZSxvd25lcjpldH0pfWZvcig7Oyl7aWYoSXQpe2xldCBibj1zZSgpW1ZlPj4yXT4+PjA7aWYoc2UoKVtWZT4+Ml09SmUsYm49PT1IdCl7aWYoIW90KXRocm93IG5ldyBFcnJvcigiSFdKUy0zOiBGT1JLIHBhcmsgd2l0aG91dCBhIGxhdGNoZWQgU1lTX2ZvcmsgXHUyMDE0IHRoZSBwYXJrIGxlYWYgZmlyZWQgb3V0c2lkZSB0aGUgbXVzbCBfRm9yayBwcm90b2NvbCIpO2lmKG90PSExLHR5cGVvZiBmLl9faHdqc19mb3JrX2JhcnJpZXJfb2shPSJmdW5jdGlvbiIpdGhyb3cgbmV3IEVycm9yKCJIV0pTLTMgZm9yayBsYXRjaDogY29ybyBpbWFnZSBsYWNrcyBfX2h3anNfZm9ya19iYXJyaWVyX29rIFx1MjAxNCByZWZ1c2luZyB0aGUgZGVsdGE9MCBjb3B5IHdpdGhvdXQgdGhlIHN0cnVjdHVyYWwgYmFycmllciBwcmVkaWNhdGUgKEFEUi0wMDA0IEY4NyBjb25mICg0KSkiKTtsZXQgeXQ9Zi5fX2h3anNfZm9ya19iYXJyaWVyX29rKCl8MDtpZih5dCE9PTEpdGhyb3cgbmV3IEVycm9yKGBIV0pTLTMgZm9yayBsYXRjaCAke3l0PT09LTE/IlJFRlVTRUQiOiJub3QgcXVpZXNjZWQifTogX19od2pzX2ZvcmtfYmFycmllcl9vaz0ke3l0fSBcdTIwMTQgdGhlIGRlbHRhPTAgd2hvbGUtbWVtb3J5IGNvcHkgaXMgYSB3aG9sZS1hcmVuYSBwcmVkaWNhdGUsIGxlZ2FsIGF0IGJhcnJpZXItcXVpZXNjZSBvbmx5IChBRFItMDAwNCBGODcgY29uZiAoNCkpYCk7bGV0IF9uPWF3YWl0IHVvKHtoYW5kbGU6UWUsb3duZXI6ZXR9KTtzZSgpW0dlPj4yXT1fbnwwLHRlPSEwfWVsc2UgaWYoYm49PT1NdCl7aWYoIXN0KXRocm93IG5ldyBFcnJvcigiSFdKUy0zOiBFWEVDIHBhcmsgd2l0aG91dCBhIGxhdGNoZWQgU1lTX2V4ZWN2ZSBcdTIwMTQgdGhlIHBhcmsgbGVhZiBmaXJlZCBvdXRzaWRlIHRoZSBtdXNsIGV4ZWN2ZSBwcm90b2NvbCIpO3N0PSExO2xldCB5dD1hd2FpdCBwbyhubixvcyksX249bm47aWYobm49bnVsbCxvcz0wLHl0JiZ5dC5vayYmeXQud2FzbUJ5dGVzKXthbj15dC53YXNtQnl0ZXMsd3M9X247YnJlYWt9c2UoKVtHZT4+Ml09eXQmJnR5cGVvZiB5dC5lcnJubz09Im51bWJlciI/eXQuZXJybm98MDotMix0ZT0hMH1lbHNlIGlmKGJuPT09SmUpVWkoKSxXdCsrLGF3YWl0IGllKCkmJih0ZT0hMCk7ZWxzZSBpZihibj09PVluKXtsZXQgeXQ9aXQ/VW4oKTowO0N0KHQsYFlJRUxEIGNwdT0ke2UuY3B1SWQ/PyI/In0gdGlkPSR7ZS50aWR9IHJlYXNvbj1SRVNDSEVELXBhcmsgc2l0ZT1uZXN0ZWQtcHVtcCB2aWE9JHtzbiE9PW51bGw/ImNvb3AtZnV0ZXgiOiJ3YWtlLXdvcmQifWApLHNuIT09bnVsbD9hd2FpdCBNYSgiSFdKUy0zIG5lc3RlZCBwdW1wIik6YXdhaXQgZnMoIkhXSlMtMyBuZXN0ZWQgcHVtcCIpLGl0JiZDdCh0LGBSRVNVTUUgY3B1PSR7ZS5jcHVJZD8/Ij8ifSB0aWQ9JHtlLnRpZH0gc2l0ZT1uZXN0ZWQtcHVtcCB3YWl0ZWQ9JHsoVW4oKS15dCkudG9GaXhlZCgxKX1tc2ApLHRlPSEwfWVsc2UgdGhyb3cgbmV3IEVycm9yKGBIV0pTLTM6IHBhcmtlZCBjaGFpbiB3aXRoIFVOS05PV04gcGFyayByZWFzb249JHtibn0gXHUyMDE0IG5vdCBhIHNlcnZpY2UgcmVxdWVzdCAoRk9SSy9FWEVDL1JFU0NIRUQpIGFuZCBub3QgYSBjb29wZXJhdGl2ZSBicmVhdGggKDApOyB0aGUgcmVhc29uIGNvbnRyYWN0IGhhcyBhIGZvdXJ0aCB2YWx1ZSB0aGlzIHB1bXAgZG9lcyBub3Qga25vd2ApfUl0PSEwLGQoKTtsZXQgVnQ9VG8oKTtpZihQZSYmUGUoKSxmLmh3anNfcmVzdW1lKFFlKSxmLmh3anNfZG9uZShRZSkpdGhyb3cgS3QmJkt0KCksZi5od2pzX2Rlc3Ryb3koUWUpLG5ldyBFcnJvcigiSFdKUy0zOiBwcm9ncmFtIGNoYWluIHJhbiB0byBET05FIFx1MjAxNCBfX2xpYmNfc3RhcnRfbWFpbiBjb21wbGV0ZWQgd2l0aG91dCBleGl0IChub3JldHVybiBjb250cmFjdCBicmVhY2g7IHRoZSBpbi1tb2R1bGUgX19od2pzX25vcmV0dXJuX2NvbXBsZXRlZCB3aXRuZXNzIHNob3VsZCBoYXZlIGZpcmVkIGZpcnN0KSIpO2lmKGYuX19od2pzX3Rha2VfcGFya2VkKGV0LFFlKSxLdCYmS3QoKSxqbyhWdCksdGUmJih0eXBlb2YgZi5fX2h3anNfcHJvZ3Jlc3Nfbm90ZT09ImZ1bmN0aW9uIiYmZi5fX2h3anNfcHJvZ3Jlc3Nfbm90ZSgpLHRlPSExKSx0eXBlb2YgZi5fX2h3anNfZHJpdmVfd2F0Y2g9PSJmdW5jdGlvbiImJihmLl9faHdqc19kcml2ZV93YXRjaChRZSl8MCk9PT0xKXRocm93IG5ldyBFcnJvcigiSFdKUy0zIEY5MzogZHJpdmUtbG9vcCBQUk9HUkVTUyBiYWNrc3RvcCB0cmlwcGVkIFx1MjAxNCB0aGUgY2hhaW4gbWFkZSBzdGFsbF9ib3VuZCBjb25zZWN1dGl2ZSB6ZXJvLXByb2dyZXNzIHJlc3VtZSBzbGljZXMgKHdlZGdlZCBoYW5kbGUgMHgiKyhRZT4+PjApLnRvU3RyaW5nKDE2KSsiKS4gVGhlIGF0dHJpYnV0ZWQgX19od2pzX3Byb2dyZXNzX3Zpb2xhdGlvbiB3YXMgd3JpdHRlbiB0byBmZCAyLiBUaGlzIGlzIHRoZSBGMTggY2hhaW5lZC11bndpbmQgLyByZWFzb24tMCBzcGluIGZhaWxpbmcgbG91ZCthdHRyaWJ1dGVkOyBzdG9wLWFuZC1yZXBvcnQgd2l0aCB0aGUgaGFuZGxlLCBkbyBub3QgaXRlcmF0ZS4iKX19fWVsc2UgZm9yKGUubW9kZT09PSJmb3JrLXJlc3VtZSImJmx0JiZ0eXBlb2YgZi5hc3luY2lmeV9zdGFydF9yZXdpbmQ9PSJmdW5jdGlvbiImJihzbz0wLHR5cGVvZiBlLnRsc0Jhc2U9PSJudW1iZXIiJiZ0eXBlb2YgZi5fX3dhc20zMl9zZXRfdGxzX2Jhc2U9PSJmdW5jdGlvbiImJm50KGUudGxzQmFzZSwwLCExKSxmLmFzeW5jaWZ5X3N0YXJ0X3Jld2luZChmLl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyKCk+Pj4wKSk7Oyl7bGV0IGllPWYuX3N0YXJ0KCksbGU9dHlwZW9mIGYuYXN5bmNpZnlfZ2V0X3N0YXRlPT0iZnVuY3Rpb24iP2YuYXN5bmNpZnlfZ2V0X3N0YXRlKCl8MDprZTtpZihubyYmbGU9PT1vZSl7bm89ITEsZ3IoZi5fX3dhc20zMl9hc3luY2lmeV9idWZfYWRkcigpPj4+MCxmLl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9zaXplKCl8MCksc289YXdhaXQgdW8oKXwwLGYuYXN5bmNpZnlfc3RhcnRfcmV3aW5kKGYuX193YXNtMzJfYXN5bmNpZnlfYnVmX2FkZHIoKT4+PjApO2NvbnRpbnVlfWlmKHJvJiZsZT09PW9lKXtybz0hMSxncihmLl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyKCk+Pj4wLGYuX193YXNtMzJfYXN5bmNpZnlfYnVmX3NpemUoKXwwKTtsZXQgWj1hd2FpdCBwbyhubixvcyksVmU9bm47aWYobm49bnVsbCxvcz0wLFomJloub2smJloud2FzbUJ5dGVzKXthbj1aLndhc21CeXRlcyx3cz1WZTticmVha31Ccz1aJiZ0eXBlb2YgWi5lcnJubz09Im51bWJlciI/Wi5lcnJub3wwOi0yLGYuYXN5bmNpZnlfc3RhcnRfcmV3aW5kKGYuX193YXNtMzJfYXN5bmNpZnlfYnVmX2FkZHIoKT4+PjApO2NvbnRpbnVlfWlmKGlvJiZsZT09PW9lKXtpbz0hMTtsZXQgWj1mLl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyKCk+Pj4wO2dyKFosZi5fX3dhc20zMl9hc3luY2lmeV9idWZfc2l6ZSgpfDApO2xldCBWZT1aKzg+Pj4wLEdlPXNlKClbWj4+PjJdPj4+MCxRZT1HZS1WZXwwLGV0PUNhPj4+MDtpZihRZTwwfHxRZT5kZCl0aHJvdyBuZXcgRXJyb3IoYHNldGptcCBjb250aW51YXRpb24gJHtRZX1CIGV4Y2VlZHMgam1wX2J1ZiBjYXBhY2l0eSAke2RkfUIgKGpiPTB4JHtldC50b1N0cmluZygxNil9KWApO3NlKClbZXQ+Pj4yXT1RZT4+PjAsU28oKS5jb3B5V2l0aGluKGV0K2hhLFZlLEdlKSxjbz0wLGYuYXN5bmNpZnlfc3RhcnRfcmV3aW5kKFopO2NvbnRpbnVlfWlmKGxvJiZsZT09PW9lKXtsbz0hMTtsZXQgWj1mLl9fd2FzbTMyX2FzeW5jaWZ5X2J1Zl9hZGRyKCk+Pj4wLFZlPWYuX193YXNtMzJfYXN5bmNpZnlfYnVmX3NpemUoKXwwO2dyKFosVmUpO2xldCBHZT1aKzg+Pj4wLFFlPVBhPj4+MCxldD1zZSgpW1FlPj4+Ml0+Pj4wO1NvKCkuY29weVdpdGhpbihHZSxRZStoYSxRZStoYStldCk7bGV0IEl0PVo+Pj4yO3NlKClbSXRdPUdlK2V0Pj4+MCxzZSgpW0l0KzFdPVorVmU+Pj4wLGYuYXN5bmNpZnlfc3RhcnRfcmV3aW5kKFopO2NvbnRpbnVlfXR5cGVvZiBpZT09Im51bWJlciImJiFfJiYobT1pZSYyNTUpO2JyZWFrfX19Y2F0Y2goQSl7aWYoQT09PXZhKWFuPW9vLHdzPW5uLG9vPW51bGw7ZWxzZXtpZihjJiZhd2FpdCBSKCksXyl7JG4oImV4aXQtdW53aW5kIik7cmV0dXJufWxldCBKPUEgaW5zdGFuY2VvZiBFcnJvcj9gJHtBLm1lc3NhZ2V9CiR7QS5zdGFjaz8/IiJ9YDpTdHJpbmcoQSk7dHJ5e2xldCBDPWNhKGosZS5tZW1vcnkpLGllPXVhKEMsYHBpZD0ke2UucGlkPz8iPyJ9IHRpZD0ke2UudGlkfDB9IHRlcm1pbmFsIHRyYXBgKTtpZSYmdCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgJHtpZX0KYH0pfWNhdGNoe31pZih0eXBlb2YgcHJvY2VzczwidSImJnByb2Nlc3MuZW52Py5IV0pTX1RSQVBfRFVNUCl0cnl7bGV0IEM9YXdhaXQgaW1wb3J0KCJub2RlOmZzIiksaWU9cHJvY2Vzcy5lbnYuSFdKU19UUkFQX0RVTVAsbGU9YHRyYXBkdW1wLXBpZCR7ZS5waWR9LWxhbmUke2UudXNlckxhbmU/PyI/In0tJHtEYXRlLm5vdygpfWAsWj1uZXcgVWludDhBcnJheShlLm1lbW9yeS5idWZmZXIpLFZlPW5ldyBVaW50OEFycmF5KFoubGVuZ3RoKTtWZS5zZXQoWiksQy53cml0ZUZpbGVTeW5jKGAke2llfS8ke2xlfS5iaW5gLFZlKTtsZXQgR2U9bnVsbDt0cnl7bGV0IFFlPWomJmouX19zdGFja19wb2ludGVyO1FlIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuR2xvYmFsJiYoR2U9UWUudmFsdWU+Pj4wKX1jYXRjaHt9Qy53cml0ZUZpbGVTeW5jKGAke2llfS8ke2xlfS5qc29uYCxKU09OLnN0cmluZ2lmeSh7cGlkOmUucGlkLG1vZGU6ZS5tb2RlLGxhbmU6ZS51c2VyTGFuZT8/bnVsbCxtZW1MZW46Wi5sZW5ndGgsc3RhY2tQb2ludGVyOkdlLG1lc3NhZ2U6Sn0sbnVsbCwyKSksdCh7a2luZDoiZG1lc2ciLGxldmVsOjMsdGV4dDpgSFdKU19UUkFQX0RVTVA6IHdyb3RlICR7bGV9LmJpbiAoJHtaLmxlbmd0aH1CKSBzcD0ke0dlPT09bnVsbD8iPyI6IjB4IitHZS50b1N0cmluZygxNil9YH0pfWNhdGNoKEMpe3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDozLHRleHQ6YEhXSlNfVFJBUF9EVU1QIEZBSUxFRDogJHtDIGluc3RhbmNlb2YgRXJyb3I/Qy5tZXNzYWdlOlN0cmluZyhDKX1gfSl9eSgicnVuLXRlcm1pbmFsLXRyYXAiKSxlLm1vZGU9PT0idGhyZWFkIiYmUSgpLGF3YWl0IFMoNCwxKSx0KHtraW5kOiJlcnJvciIscGlkOmUucGlkLG1lc3NhZ2U6Sn0pLCRuKCJlcnJvciIpO3JldHVybn19aWYoYW4pe2lmKE90PWFuLGx0PSExLGp0LnNpemU+MCl7dHJ5e3Qoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YGh3anMtc3lzIHBpZD0ke2UucGlkfSBFWEVDLURMT1BFTi1URUFSRE9XTjogZHJvcHBpbmcgJHtqdC5zaXplfSBkbG9wZW4gaGFuZGxlKHMpIGFjcm9zcyBleGVjdmUgKGRsIGhhbmRsZXMgZG8gbm90IHN1cnZpdmUgZXhlYzsgdGhlIC5zbyBpbnN0YW5jZXMgZGllZCB3aXRoIHRoZSByZXBsYWNlZCBhZGRyZXNzIHNwYWNlKWB9KX1jYXRjaHt9anQuY2xlYXIoKX1pZihLbi5sZW5ndGg+MCYmKEtuLmxlbmd0aD0wKSxlLm1lcmdlZENwdTBMYW5lPT09ITAmJk5uIT09bnVsbCYmZS5yb3V0ZUtleSE9bnVsbCl7bGV0IEE7dHJ5e0E9Tm4oe2tpbmQ6ImV4ZWMtaW5zdGFsbC1zeW5jIixyb3V0ZUtleTplLnJvdXRlS2V5LHdhc21CeXRlczpPdH0pfWNhdGNoe0E9dm9pZCAwfWlmKEEhPT0iaW5zdGFsbGVkIil0cnl7dCh7a2luZDoiZG1lc2ciLGxldmVsOjQsdGV4dDpgaHdqcy1tZXJnZWQgRVhFQy1TWU5DIERFQ0xJTkVEIHBpZD0ke2UucGlkfSByb3V0ZUtleT0ke2Uucm91dGVLZXl9OiB0aGUgaG9zdCBkaWQgbm90IHJlLWRlcml2ZSB0aGUgbW1hcCBwYXJ0aXRpb24gdGhyb3VnaCB0aGUgc3luY2hyb25vdXMgZG9vciAoYW5zd2VyPSR7QT09PXZvaWQgMD8iZGVjbGluZWQiOlN0cmluZyhBKX0pLCBzbyB0aGUgbmV3IGltYWdlJ3MgZmlyc3QgbW1hcHMgYXJlIHNlcnZlZCBmcm9tIHRoZSBwcmUtZXhlYyBmbG9vciB1bnRpbCB0aGUgZXhlYy1pbWFnZS1pbnN0YWxsZWQgbWVzc2FnZSBpcyBkZWxpdmVyZWQuYH0pfWNhdGNoe319dCh7a2luZDoiZXhlYy1pbWFnZS1pbnN0YWxsZWQiLHBpZDplLnBpZCx3YXNtQnl0ZXM6T3QsLi4ud3M/e3BhdGg6d3N9Ont9fSk7Y29udGludWUgZX1icmVhayBlfV98fChhd2FpdCBTKG0mMjU1LDApLEFzPjAmJnQoe2tpbmQ6ImRtZXNnIixsZXZlbDo2LHRleHQ6YHdhc20zMiBhc3luY2lmeSBjb250aW51YXRpb24gaGlnaC13YXRlcjogJHtBc31CIG9mIDY1NTI4QiB1c2FibGUgKHBpZD0ke2UucGlkfSlgfSksdCh7a2luZDoiZXhpdCIscGlkOmUucGlkLGNvZGU6bSx3YXNtU3lzY2FsbFN0YXRzOnsuLi5xbn0sLi4uSm4+MD97Y29vcFdhaXRWaW9sYXRpb25zOkpufTp7fSwuLi5abj4wP3tzeW5jUmVzdGFydFZpb2xhdGlvbnM6Wm59Ont9LGFzeW5jaWZ5SGlnaFdhdGVyOkFzLC4uLk5lP3tod2pzTGFuZUNlbnN1czpiZChOZSl9Ont9fSkpLCRuKCJjb21wbGV0ZWQiKX1yKFRkLCJydW4iKTtmdW5jdGlvbiBiZChlKXt0cnl7cmV0dXJuIGUucmVjb25jaWxlKCl9Y2F0Y2godCl7cmV0dXJuey4uLmUuY2Vuc3VzLHJlY29uY2lsZUZhdGFsOnQgaW5zdGFuY2VvZiBFcnJvcj90Lm1lc3NhZ2U6U3RyaW5nKHQpfX19cihiZCwicmVjb25jaWxlT3JGbGFnIik7dmFyIFpyPTgsQW49bmV3IE1hcCxUYT0wLGVvPTAsamQ9MCxJbj1uZXcgTWFwLERkPW51bGwsTm49bnVsbCxoZj0xZTMsWXI9ITEsa2Q9MCx4ZD0hMTtmdW5jdGlvbiBtZigpe2xldCBlPURhdGUubm93KCk7aWYoIVlyKXtZcj0hMCxrZD1lO3RyeXtzZXRUaW1lb3V0KCgpPT57WXI9ITF9LDApPy51bnJlZj8uKCl9Y2F0Y2h7WXI9ITF9cmV0dXJuIDB9cmV0dXJuIGUta2R9cihtZiwiZG1lc2dMb29wU3RhbGxlZE1zIik7ZnVuY3Rpb24gYmEoZSx0LG8scyxsKXtsZXQgZD1tZigpO2lmKGQ+PWhmJiZObiE9PW51bGwmJnQhPW51bGwpe2xldCBfPXIoKG0sYyk9Pnt0cnl7cmV0dXJuIE5uKHtraW5kOiJkbWVzZy1zeW5jIixyb3V0ZUtleTp0LHBpZDpvfDAsbGV2ZWw6bXwwLHRleHQ6U3RyaW5nKGMpfSl9Y2F0Y2h7cmV0dXJufX0sImRvb3IiKTtpZigheGQpe2lmKF8oNCxgaHdqcy1tZXJnZWQ6IHRoaXMgcmVhbG0gaGFzIG5vdCByZWFjaGVkIGl0cyBldmVudCBsb29wIGZvciAke2R9IG1zLCBzbyBrZXJuZWwgcmVjb3JkcyBjYW5ub3QgYmUgUE9TVEVEIFx1MjAxNCB0aGUgcG9ydCB0aGF0IGNhcnJpZXMgdGhlbSAoaW5saW5lUmVhbG0udHMpIGlzIGRyYWluZWQgYnkgdGhlIHR1cm4gdGhpcyB0aHJlYWQgaXMgbm90IHRha2luZy4gRXZlcnkgcmVjb3JkIGZyb20gaGVyZSBvbiBpcyBkZWxpdmVyZWQgdGhyb3VnaCB0aGUgU1lOQ0hST05PVVMgZG9vciBpbnN0ZWFkLCBieXRlLWZvci1ieXRlLCBvbiB0aGUgc3RhbGxlZCB0aHJlYWQncyBvd24gc3RhY2suIFRoZXkgYXJlIE9VVCBPRiBPUkRFUiB3aXRoIHJlc3BlY3QgdG8gcmVjb3JkcyBzdGlsbCBxdWV1ZWQgZnJvbSBiZWZvcmUgdGhpcyBsaW5lLCB3aGljaCBhcnJpdmUgaWYgYW5kIHdoZW4gdGhlIHN0YWxsIGVuZHMuIE5ldmVyLXNpbGVudDogd2l0aG91dCB0aGlzIHRoZSBsb2cgc3RvcHMgYXQgdGhlIGxhc3QgcmVjb3JkIHBvc3RlZCBiZWZvcmUgdGhlIHdlZGdlIGFuZCByZWFkcyBhcyB0aGUgbWFjaGluZSBzdG9wcGluZyB0aGVyZS4KYCkhPT0iZGVsaXZlcmVkIil7dHJ5e2Uoe2tpbmQ6ImRtZXNnIixsZXZlbDpzfDAsdGV4dDpsfSl9Y2F0Y2h7fXJldHVybn14ZD0hMH1pZihfKHMsbCk9PT0iZGVsaXZlcmVkIilyZXR1cm59dHJ5e2Uoe2tpbmQ6ImRtZXNnIixsZXZlbDpzfDAsdGV4dDpsfSl9Y2F0Y2h7fX1yKGJhLCJkbWVzZ0RlbGl2ZXIiKTtmdW5jdGlvbiBOZChlKXtpZihBcnJheS5pc0FycmF5KGUpKWZvcihsZXQgdCBvZiBlKSF0fHx0eXBlb2YgdC5rZXkhPSJzdHJpbmcifHwhKHQubW9kdWxlIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuTW9kdWxlKXx8SW4uaGFzKHQua2V5KXx8KEluLnNldCh0LmtleSx0Lm1vZHVsZSksSW4uc2l6ZT5aciYmSW4uZGVsZXRlKEluLmtleXMoKS5uZXh0KCkudmFsdWUpKX1yKE5kLCJ1c2VySW1hZ2VzTWVyZ2UiKTtmdW5jdGlvbiBtcihlLHQsbyxzPTIxNjYxMzYyNjEpe2xldCBsPXM+Pj4wO2ZvcihsZXQgZD10O2Q8bztkKyspbF49ZVtkXSxsPU1hdGguaW11bChsLDE2Nzc3NjE5KTtyZXR1cm4gbD4+PjB9cihtciwiZm52MWEzMiIpO2Z1bmN0aW9uIHBmKGUpe2xldCB0PWUubGVuZ3RoLG89ODE5MixzPW1yKGUsMCxNYXRoLm1pbihvLHQpKSxsPW1yKGUsTWF0aC5tYXgoMCx0LW8pLHQpLGQ9dD4yKm8/bXIoZSx0LW8+PjEsKHQtbz4+MSkrbyk6MDtyZXR1cm5gJHt0fToke3MudG9TdHJpbmcoMTYpfToke2QudG9TdHJpbmcoMTYpfToke2wudG9TdHJpbmcoMTYpfWB9cihwZiwidXNlckltYWdlQ2FjaGVLZXkiKTthc3luYyBmdW5jdGlvbiB3ZihlKXtsZXQgdD1wZihlKSxvPUFuLmdldCh0KTtpZihvIT09dm9pZCAwKXJldHVybiBlbysrLEFuLmRlbGV0ZSh0KSxBbi5zZXQodCxvKSx7bW9kdWxlOm8sa2V5OnQsY2FjaGVkOiEwfTtsZXQgcz1Jbi5nZXQodCk7aWYocyE9PXZvaWQgMClyZXR1cm4gZW8rKyxqZCsrLEluLmRlbGV0ZSh0KSxJbi5zZXQodCxzKSxBbi5zZXQodCxzKSxBbi5zaXplPlpyJiZBbi5kZWxldGUoQW4ua2V5cygpLm5leHQoKS52YWx1ZSkse21vZHVsZTpzLGtleTp0LGNhY2hlZDohMH07bGV0IGw9YXdhaXQgV2ViQXNzZW1ibHkuY29tcGlsZShBZChlKSk7aWYoVGErKyxBbi5zZXQodCxsKSxBbi5zaXplPlpyKXtsZXQgZD1Bbi5rZXlzKCkubmV4dCgpLnZhbHVlO0FuLmRlbGV0ZShkKX1Jbi5zZXQodCxsKSxJbi5zaXplPlpyJiZJbi5kZWxldGUoSW4ua2V5cygpLm5leHQoKS52YWx1ZSk7dHJ5e0RkPy4oe2tpbmQ6InVzZXItaW1hZ2UtY29tcGlsZWQiLGtleTp0LG1vZHVsZTpsLGJ5dGVMZW5ndGg6ZS5sZW5ndGh9KX1jYXRjaHt9cmV0dXJue21vZHVsZTpsLGtleTp0LGNhY2hlZDohMX19cih3ZiwiY29tcGlsZVVzZXJNb2R1bGUiKTt2YXIgZ2Y9OCxqYT0wLHRvPTAsTGQ9MCx3cj0wLEVkPXR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeT09ImZ1bmN0aW9uIj9uZXcgRmluYWxpemF0aW9uUmVnaXN0cnkoKCk9Pnt3cj1NYXRoLm1heCgwLHdyLTEpfSk6bnVsbDtmdW5jdGlvbiB5ZihlKXtsZXQgdD1tcihlLDAsZS5sZW5ndGgpLG89bXIoZSwwLGUubGVuZ3RoLDM0MjE2NzQ3MjQpO3JldHVybmAke2UubGVuZ3RofToke3QudG9TdHJpbmcoMTYpfToke28udG9TdHJpbmcoMTYpfWB9cih5Ziwic29Nb2R1bGVDYWNoZUtleSIpO3ZhciBwcj1uZXcgV3IoZ2YseWYpO2Z1bmN0aW9uIGthKCl7cmV0dXJuYHNvQ29tcGlsZXM9JHtqYX0gc29IaXRzPSR7dG99IHNvQ2FjaGVTaXplPSR7cHIuc2l6ZX0gbGl2ZVNvTW9kdWxlcz0ke3dyfSBzb0NvbXBpbGVkV2lyZUJ5dGVzPSR7TGR9YH1yKGthLCJzb01vZHVsZUNhY2hlU3RhdHMiKTtmdW5jdGlvbiBNZCgpe3JldHVybnt1c2VyQ29tcGlsZXM6VGEsdXNlckhpdHM6ZW8sdXNlckNhY2hlU2l6ZTpBbi5zaXplLHVzZXJIb3N0QWRvcHRlZDpqZCx1c2VySG9zdE1pcnJvclNpemU6SW4uc2l6ZSxzb0NvbXBpbGVzOmphLHNvSGl0czp0byxzb0NhY2hlU2l6ZTpwci5zaXplLHNvTW9kdWxlc0xpdmU6d3J9fXIoTWQsImlzb2xhdGVNb2R1bGVDYWNoZUNlbnN1cyIpO2Z1bmN0aW9uIFNkKGUsdCl7cmV0dXJuIHRvKysse21vZHVsZTplLGtleTpgc2hhMjU2OiR7dH1gLGNhY2hlZDohMH19cihTZCwic3RvcmVkU29Nb2R1bGUiKTtmdW5jdGlvbiAkcyhlLHQpe2xldCBvPWJzKGUpO2lmKG8pdGhyb3cgbmV3IEVycm9yKGBod2pzLWxpYmM6IHRoZSByZXRhaW5lZCBjb3B5IG9mIGxpYnJhcnkgJHtvLmRpZ2VzdC5zbGljZSgwLDE2KX1cdTIwMjYgKCR7ZS5sZW5ndGh9QiBvZiAke28ud2lyZUxlbmd0aH1CKSB3YXMgaGFuZGVkIHRvIGEgY29tcGlsZSBcdTIwMTQgaXQgaG9sZHMgbm8gY29kZTsgdGhlIGxpYnJhcnkncyBNb2R1bGUgaXMga2VwdCBiZXNpZGUgaXQgYW5kIG11c3QgYmUgdXNlZCBpbnN0ZWFkIChuZXZlci1zaWxlbnQpYCk7bGV0IGw9KGdsb2JhbFRoaXMucHJvY2Vzcz8uZW52Py5IV0pTXzcwX1JFRF9OT0NBQ0hFfHwiIik9PT0iMSI/bnVsbDpwci5maW5kKGUsdCksZD1sP2wua2V5OnByLmtleU9mKGUsdCk7aWYobCYmbC5tb2R1bGUhPT12b2lkIDApcmV0dXJuIHRvKysse21vZHVsZTpsLm1vZHVsZSxrZXk6ZCxjYWNoZWQ6ITB9O2xldCBfPW5ldyBXZWJBc3NlbWJseS5Nb2R1bGUoQWQoZSkpO3JldHVybiBqYSsrLExkKz1lLmxlbmd0aCxFZCYmKHdyKyssRWQucmVnaXN0ZXIoXyxkKSksbCYmcHIuYWRkKGwuaWQsXykse21vZHVsZTpfLGtleTpkLGNhY2hlZDohMX19cigkcywiY29tcGlsZVNvTW9kdWxlIik7ZnVuY3Rpb24gYmYoZSx0KXtsZXQgbz1XZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhlKSxzPU9iamVjdC5jcmVhdGUobnVsbCk7Zm9yKGxldCBsIG9mIG8pe2xldCBkPU9iamVjdC5oYXNPd24odCxsLm1vZHVsZSk/dFtsLm1vZHVsZV06dm9pZCAwO2lmKCFkfHwhT2JqZWN0Lmhhc093bihkLGwubmFtZSkpdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGltcG9ydCAke2wubW9kdWxlfS4ke2wubmFtZX0gKCR7bC5raW5kfSlgKTtzW2wubW9kdWxlXT1zW2wubW9kdWxlXT8/T2JqZWN0LmNyZWF0ZShudWxsKSxzW2wubW9kdWxlXVtsLm5hbWVdPWRbbC5uYW1lXX1yZXR1cm4gc31yKGJmLCJmaWx0ZXJJbXBvcnRzIik7UmQoe3Bvc3Q6cihlPT5PZC5wb3N0TWVzc2FnZShlKSwicG9zdCIpLG9uTWVzc2FnZTpyKGU9Pk9kLm9uKCJtZXNzYWdlIixlKSwib25NZXNzYWdlIil9KTsK"),wf="inlined in this file (single-file /boot/hardwarejs.js)";var EW=29,_W=28,$l;async function wu(t){await Promise.all([process.stdout,process.stderr].map(e=>new Promise(n=>e.write("",n)))),process.exit(t)}o(wu,"exitAfterOutput");function Su(){Xr.writeSync(2,`Usage: hardwarejs --url | --fs | --image [options] --url Cloud boot is hosted by the website's brintos.js node brintos.js --url [--api-url ] --image Offline writable ext4 image; 7z/7zz reads its one versioned /boot kernel unless --kernel is supplied --read-only Open --image and mount ext4 read-only -f, --fs Development root filesystem directory -k, --kernel Local kernel override (default: versioned /boot kernel inside --image or --fs) -i, --init init to exec as PID 1 (image default: /bin/sh or /bin/bash, selected with 7-Zip; --fs: /bin/sh) --vcpus Process CPU count (1..128); default: host policy --ram Kernel SAB \u2014 the kernel's OWN memory, and the only memory it can touch (default: 256) --machine-ram The machine's declared AGGREGATE RAM: the kernel SAB plus the budget for the per-process user SABs the kernel never maps. This is what the guest reports as MemTotal. Must be >= --ram; defaults to --ram, which means "this machine is exactly its kernel SAB". --user-ram Per-process user memory, initial (default: 64) --user-max Per-process user memory CEILING \u2014 the maximum one process's SAB may grow to (default: 256). This is a PER-PROCESS cap, not the machine's RAM; a process that hits it fails while the machine has RAM free. --cmdline Extra kernel command line appended verbatim --gateway-origin Allow this origin through the Track N HTTP egress gateway (10.0.2.2:3128); repeatable. Any use enables the gateway (Node fetch upstream). --gateway-app-origin Which allowlisted origin is the brintOS app. A read-only gateway needs it to tell this machine's own fs API from a stranger's, so brintos-fs blob reads (POST /fs/blobs/presign op=get, presign-batch, batch-get) are permitted. --gateway-read-only Gateway refuses repo-MUTATING requests (403). --usb :[@] Attach this host USB device to the guest's root hub; repeatable. Ids are 4 hex digits; a serial may spell a character as \\uXXXX. Needs a host that hands launchMachine a WebUSB: this file carries no USB stack of its own --virtio-input Register the virtio-input device the browser frame has (/dev/input/event0). Nothing feeds it events --framebuffer [WxH] Give the guest a DRM display (default 1024x768). Nothing shows it; its memory is carved either way -h, --help Show this help Press Ctrl-] while running to power the machine off. `)}o(Su,"usage");function JW(t){let e={fs:void 0,kernel:void 0,init:void 0,readOnly:!1,ram:256,machineRam:void 0,userRam:64,userMax:void 0,cmdline:"",gatewayOrigins:[],gatewayAppOrigin:void 0,gatewayReadOnly:!1,usb:[],virtioInput:!1,framebuffer:void 0};for(let n=0;n{let i=t[++n];if(!i||i.startsWith("--"))throw new Error(`missing value for ${s}`);return i},"val");switch(s){case"-f":case"--fs":e.fs=r();break;case"--image":e.image=r();break;case"--read-only":e.readOnly=!0;break;case"--url":e.url=r();break;case"-k":case"--kernel":e.kernel=r();break;case"-i":case"--init":e.init=r();break;case"--vcpus":e.vcpus=Number(r());break;case"--ram":e.ram=Number(r());break;case"--machine-ram":e.machineRam=Number(r());break;case"--user-ram":e.userRam=Number(r());break;case"--user-max":e.userMax=Number(r());break;case"--cmdline":e.cmdline=r()??"";break;case"--gateway-origin":e.gatewayOrigins.push(r());break;case"--gateway-app-origin":e.gatewayAppOrigin=r();break;case"--gateway-read-only":e.gatewayReadOnly=!0;break;case"--usb":e.usb.push(MW(r()));break;case"--virtio-input":e.virtioInput=!0;break;case"--framebuffer":{let i=/^([1-9]\d*)x([1-9]\d*)$/.exec(t[n+1]??"");i&&n++,e.framebuffer=i?{width:Number(i[1]),height:Number(i[2])}:{width:1024,height:768};break}case"-h":case"--help":Su(),process.exit(0);break;default:e.fs===void 0&&!s.startsWith("-")?e.fs=s:(process.stderr.write(`run-machine: unknown argument '${s}' `),Su(),process.exit(2))}}if(e.vcpus!==void 0&&(!Number.isInteger(e.vcpus)||e.vcpus<1||e.vcpus>128))throw new Error("--vcpus must be an integer from 1 through 128");return e}o(JW,"parseArgs");var ku=o(t=>t.toString(16).padStart(4,"0"),"hex4"),UW=o(t=>t.replace(/[^\x21-\x7e]|\\/g,e=>`\\u${ku(e.charCodeAt(0))}`),"escSerial"),Sf=o(t=>`${ku(t.vendorId)}:${ku(t.productId)}${t.serialNumber?`@${UW(t.serialNumber)}`:""}`,"usbName");function MW(t){let e=/^([0-9a-f]{4}):([0-9a-f]{4})(?:@(.+))?$/i.exec(t);if(!e)throw new Error(`--usb ${t}: expected :[@], each id four hex digits`);let n=e[3]?.replace(/\\u([0-9a-f]{4})/gi,(s,r)=>String.fromCharCode(parseInt(r,16)));return{spec:t,vendorId:parseInt(e[1],16),productId:parseInt(e[2],16),serialNumber:n}}o(MW,"parseUsbSpec");function LW(t){return{...t.virtioInput?{virtioInput:{absolutePointer:!0}}:{},...t.framebuffer?{framebuffer:{...t.framebuffer,maxWidth:t.framebuffer.width,maxHeight:t.framebuffer.height}}:{}}}o(LW,"bootDevices");function PW(t,e){let n=[];for(let s of t){let r=e.filter(i=>i.vendorId===s.vendorId&&i.productId===s.productId&&(s.serialNumber===void 0||i.serialNumber===s.serialNumber));if(r.length===0)throw new Error(`--usb ${s.spec}: no such device on this host (it has: ${e.map(Sf).join(", ")||"none"})`);if(r.length>1)throw new Error(`--usb ${s.spec}: ${r.length} devices match; name one with @ (${r.map(Sf).join(", ")})`);if(n.includes(r[0]))throw new Error(`--usb ${s.spec}: an earlier --usb already names that device`);n.push(r[0])}return n}o(PW,"pickUsbDevices");async function AW(t,e){return t.length===0?[]:(typeof e?.usb?.getDevices!="function"&&ql("--usb needs a host that supplies WebUSB: launchMachine(argv, root, { usb }) with a navigator.usb-shaped usb, such as node usb@2's new WebUSB({ allowAllDevices: true }). This launcher carries no USB stack of its own."),PW(t,await e.usb.getDevices()))}o(AW,"hostUsbDevices");function ql(t){throw new Error(t)}o(ql,"die");function KW(t,e,n=globalThis.navigator?.hardwareConcurrency){let s=JW(t);return e&&(t.includes("--machine-ram")||(s.machineRam=e.ramMiB),t.includes("--vcpus")||(s.vcpus=Mm(e.cpu,n)),t.includes("--user-ram")||(s.userRam=2),!t.includes("--init")&&!t.includes("-i")&&(s.init=e.init),t.includes("--cmdline")||(s.cmdline=e.cmdline??"")),s}o(KW,"cloudBootArgs");async function zW(t,e,n){$l=e;let s=KW(t,e?.bootSpec);if([s.fs,s.url,s.image].filter(Boolean).length!==1)throw Su(),new Error("select exactly one of --url, --fs, and --image");if(s.readOnly&&!s.image)throw new Error("--read-only requires --image in the standalone hardwarejs launcher");if(s.url&&!e)throw new Error("Cloud boot requires the website filesystem host: download https://brintos.io/brintos.js and run node brintos.js --url (use --api-url for another installation)");if(e&&!s.url)throw new Error("A cloud filesystem capability requires --url");let r=await AW(s.usb,n);if(e){let x=o(P=>process.stderr.write(`[cloud] ${P} `),"notice"),ie=await pu(e.port,{onNotice:x}),ee=e.close;e={...e,fsView:await df(ie,{notice:x}),close:o(async P=>{ie.dispose(),await ee(P)},"close")},$l=e}let i=s.image?tf(s.image,s.readOnly):void 0,l=e??i;$l=l;let d=s.fs?ni.resolve(s.fs):void 0;d&&(!Xr.existsSync(d)||!Xr.statSync(d).isDirectory())&&ql(`--fs path is not a directory: ${d}`);let a=d?Q0(d):e?.label??i.path,c=d?new Ll(a):void 0,h,p;if(c&&!s.kernel){if(h=await c.lookup(1,"boot"),!h||(h.mode&61440)!==16384)throw new Error("/boot must be a real directory");p=Pl((await c.readdir(h.ino)).filter(x=>x.type===8).map(x=>x.name))}let m=s.kernel?ni.resolve(s.kernel):e?.kernelLabel??(i?`${i.path}:/boot/`:ni.join(a,"boot",p)),y;if(c&&!s.kernel){let x=await c.lookup(h.ino,p);if(!x||x.size<8||x.size>256*1024*1024)throw new Error("Image kernel exceeds the 256 MiB bootstrap limit");y=new Uint8Array(x.size);for(let ie=0;ieI&&(process.stderr.write(`run-machine: --user-ram ${R} MiB exceeds --user-max ${I} MiB; clamping the per-process initial to ${I} MiB. `),R=I);let X=s.machineRam===void 0?s.ram:s.machineRam;(!Number.isFinite(X)||Xprocess.stderr.write(`[hardwarejs] ${ee} `),"notice"),trace:x.includes(mf),off:x.includes(uf)})}let M=!!process.stdin.isTTY,H=4096,Ge=[],C=o((x,ie)=>{Ge.push({level:x|0,text:String(ie)}),Ge.length>H&&Ge.shift()},"tapDmesg"),Ie,B=o(()=>({cmdline:_,declaredMemoryBytes:F.opts.declaredMemoryBytes,...At!==void 0?{hwjsRtProvenance:At.provenance.raw,hwjsRtByteLength:At.byteLength}:{},ringOffsets:{ptyBridge:Ie}}),"bootFacts"),ae,Ce,Q,$=!1,_e=o(x=>M?x.replace(/(?process.stderr.write(_e(x)),"note");function Ut(){let x=process.env.HWJS_WINSIZE;if(x){let P=/^(\d+)x(\d+)$/.exec(x.trim());if(P)return{rows:+P[1],cols:+P[2]};pe(`[hardwarejs] ignoring malformed HWJS_WINSIZE=${x} (want ROWSxCOLS) `)}let ie=process.stdout.rows,ee=process.stdout.columns;return ie>0&&ee>0?{rows:ie,cols:ee}:null}o(Ut,"hostWinsize");function rt(){let x=Ut();if(x&&ae)try{ae.setWinsize(x.rows,x.cols)}catch{}}o(rt,"pushWinsize");function we(){Ce&&(clearInterval(Ce),Ce=void 0),process.stdout.removeListener("resize",rt),M&&process.stdin.isRaw&&process.stdin.setRawMode(!1),process.stdin.removeListener("data",Ct),process.stdin.pause()}o(we,"restoreTerminal");function Qe(){let x=q?.userMemoryStats?.();if(!x)return;let ie=o(P=>(P*65536/(1024*1024)).toFixed(1),"pmib"),ee=o(P=>(P/1024).toFixed(1),"bkib");pe(`[hardwarejs] kernel SAB: ${ie(x.kernelPages)} MiB committed of ${(F.opts.kernelBytes/(1024*1024)).toFixed(1)} MiB span `),pe(`[hardwarejs] user SABs: ${x.liveCount} live (${ie(x.livePages)} MiB), ${x.exitedUncollectedCount} exited-uncollected (${ie(x.exitedUncollectedPages)} MiB), ${x.collectedCount} collected, ${x.pooledCount??0} pooled (${ie(x.pooledPages??0)} MiB), ${x.reusedCount??0} reused [hardwarejs] freed-but-unreclaimable: ${ee(x.heldFreeBytes)} KiB held free now, ${ee(x.cumulativeFreedBytes)} KiB freed through the kernel over this machine's life (SABs do not shrink; tracked for a future shrink-by-reclone) `);for(let P of x.reclaimCandidates.slice(0,5))pe(`[hardwarejs] reclone candidate pid=${P.pid}: ${ee(P.committedBytes)} KiB committed, ${ee(P.heldFreeBytes)} KiB of it free `)}o(Qe,"noteUserMemoryLedger");async function It(x){if(!$){$=!0,we(),pe(` [hardwarejs] powering off\u2026 `);try{Qe()}catch(ie){pe(`[hardwarejs] user-memory ledger unavailable: ${ie} `)}try{Q?.dispose()}catch{}try{await l?.close({cleanShutdown:!0})}catch(ie){pe(`[hardwarejs] filesystem shutdown failed: ${ie.message}; local cache preserved `),x=1}await wu(x??0)}}o(It,"powerOff");function Ct(x){if(x.includes(_W)){Mt();return}if(x.includes(EW)){It(0);return}ae?.inject(new Uint8Array(x.buffer,x.byteOffset,x.length))}o(Ct,"onStdin"),process.once("SIGINT",()=>{It(130)}),process.once("SIGTERM",()=>{It(143)});async function Mt(){try{let x=fu({handler:q,ram:F,dmesg:Ge,boot:B()});pe(` [hardwarejs] machineSnapshot(): ${JSON.stringify(x,null,2)} `)}catch(x){pe(` [hardwarejs] machineSnapshot() failed: ${x&&x.stack||x} `)}try{let x=await q.probeWorkers?.(500);pe(`[hardwarejs] probeWorkers() (a REQUEST, not a sample): ${JSON.stringify(x,null,2)} `)}catch(x){pe(`[hardwarejs] probeWorkers() failed: ${x&&x.stack||x} `)}}o(Mt,"dumpSnapshot");let At=await na(K),q=ta({kernelMemory:N,ram:F,workerEntry:Wf,platform:"node",signalRegistry:k,vmlinuxModule:K,maxCpuId:s.vcpus,...At!==void 0?{hwjsRtModule:At.module,hwjsRtBytes:At.bytes,hwjsRtProvenance:At.provenance.raw}:{},kernelMemoryWasm:F.kernelMemory,...b?{initArgv:[b,"-i"]}:{},initEnvp:["PATH=/bin:/sbin:/usr/bin:/usr/sbin","HOME=/","PS1=brintos$ ","TERM=xterm-256color","PWD=/"],initLowFdRoutes:[0,1,2],onUserOutput:o((x,ie)=>{(x===1||x===2)&&process.stdout.write(_e(new TextDecoder().decode(ie)))},"onUserOutput"),onUserError:o((x,ie)=>pe(`[hardwarejs] user[${x}] error: ${ie} `),"onUserError"),onDmesg:o((x,ie)=>{C(x,ie),(process.env.DBG||(x|0)<=4||/VIOLATION/.test(ie))&&pe(`[k] ${ie} `)},"onDmesg")}),_=`console=hvc0 loglevel=8 prestrike.repo=${e?.label??`local/${ni.basename(a)}`} prestrike.rootfs=${i?"ext4":"virtiofs"}`+(i?.readOnly?" prestrike.rootfs_ro":"")+(b?` init=${b}`:"")+(s.cmdline?` ${s.cmdline}`:"");pe(`[hardwarejs] kernel : ${m} [hardwarejs] rootfs : ${a} [hardwarejs] init : ${b||"(kernel default)"} [hardwarejs] input : ${s.virtioInput?"virtio-input":"none"} [hardwarejs] display: ${s.framebuffer?`${s.framebuffer.width}x${s.framebuffer.height}`:"none"} [hardwarejs] workers: ${wf} [hardwarejs] press Ctrl-] to power off, Ctrl-\\ to dump machineSnapshot() `),M&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("data",Ct);let D;if(e?.network)try{let x=await e.network.session(),ie=x.token;D=new ya({url:x.relayUrl,WebSocketCtor:e.network.WebSocketCtor,token:o(async()=>{if(ie){let P=ie;return ie=null,P}return(await e.network.session()).token},"token"),refreshIntervalMs:480*1e3,onEvent:o(P=>pe(`[naas] ${P} `),"onEvent")}),D.onReady(()=>pe(`[naas] VPN active (${x.tier}): ${x.tierDetail} `));let ee=l.close;l.close=async P=>{D.close(),await ee(P)}}catch(x){pe(`[naas] VPN unavailable: ${x.message} `)}let ue;try{ue=await bu({ram:F,vmlinuxModule:K,workerEntry:Gf,platform:"node",num_vcpu:s.vcpus===void 0?void 0:s.vcpus+1,cmdline:_,spawnHandler:q,signalRegistry:k,virtioFs:U?{fs:U}:void 0,virtioBlk:i?{disk:i}:void 0,...LW(s),...D||s.gatewayOrigins.length>0?{virtioNet:{...D?{packetUplink:D}:{},...U?{fs:U}:{},...s.gatewayOrigins.length>0?{fetchImpl:o((x,ie)=>fetch(x,ie),"fetchImpl"),httpPortMapping:!0,gateway:{origins:s.gatewayOrigins,...s.gatewayAppOrigin?{appOrigin:s.gatewayAppOrigin}:{},...s.gatewayReadOnly?{readOnly:!0}:{}}}:{}}}:{},...r.length>0?{usbHcd:{},onUsbReady:o(x=>{for(let[ie,ee]of r.entries())x.attachDevice(ee).then(P=>pe(`[hardwarejs] usb: ${s.usb[ie].spec} -> guest root-hub port ${P+1} `),P=>pe(`[hardwarejs] usb: attach ${s.usb[ie].spec} failed: ${P?.message??P} `))},"onUsbReady")}:{},watchdogMs:0,onControls:o(x=>{Q=x},"onControls"),onPtyBridgeRingOffset:o(x=>{Ie=x,ae=new Za({kernelMemory:N,kernelMemoryWasm:F.kernelMemory,ringOffset:x,ptn:0}),ae.activate(),rt(),process.stdout.on("resize",rt);let ie=!1;Ce=setInterval(()=>{let ee=ae.drain();ee.length&&(ie||(ie=!0,pe(` [hardwarejs] Console ready. Ctrl-C interrupts the guest; Ctrl-] (Control + right bracket) exits Node${e?" and flushes cloud writes":""}. `)),process.stdout.write(Buffer.from(ee)))},8)},"onPtyBridgeRingOffset"),onDmesg:o((x,ie)=>{C(x,ie),process.stdout.write(_e(ie.endsWith(` `)?ie:ie+` `))},"onDmesg")})}catch(x){we(),await l?.close(),ql(`bootKernel threw: ${x&&x.stack||x}`)}we(),$||(pe(` [hardwarejs] kernel terminated (${ue.terminal.kind}). `),ue.terminal.message&&pe(`[hardwarejs] ${ue.terminal.message} `),await l?.close({cleanShutdown:ue.terminal.kind==="returned"}),await wu(ue.terminal.kind==="returned"?0:1))}o(zW,"main");var ux="hardwarejs-node-host-v1",mx=["vcpus","boot-spec","vpn","clean-shutdown","usb","virtio-input","framebuffer"];async function jW(t,e,n){try{await zW(t,e,n)}catch(s){process.stdin.isTTY&&process.stdin.isRaw&&process.stdin.setRawMode(!1),Xr.writeSync(2,` run-machine: fatal: ${s&&s.stack||s} `);try{await $l?.close()}catch(r){Xr.writeSync(2,`Filesystem cleanup failed: ${r.message} `)}await wu(1)}}o(jW,"launchMachine");process.argv[1]&&import.meta.url===FW(ni.resolve(process.argv[1])).href&&jW(process.argv.slice(2));export{LW as bootDevices,KW as cloudBootArgs,jW as launchMachine,mx as nodeHostFeatures,ux as nodeHostProtocol,JW as parseArgs,MW as parseUsbSpec,PW as pickUsbDevices};