@interncom/diplomatic 0.14.1 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.mjs +3 -3
- package/dist/cli/shared/codecs/identityBundle.d.ts +3 -16
- package/dist/cli/shared/crypto/enclave.d.ts +8 -0
- package/dist/cli/shared/webauthn/common.d.ts +10 -0
- package/dist/cli/shared/webauthn/largeBlob.d.ts +0 -3
- package/dist/cli/shared/webauthn/prf.d.ts +0 -19
- package/dist/web/index.d.ts +4 -4
- package/dist/web/index.mjs +1 -1
- package/dist/web/passkey/seed.d.ts +1 -3
- package/dist/web/shared/codecs/identityBundle.d.ts +3 -16
- package/dist/web/shared/crypto/enclave.d.ts +8 -0
- package/dist/web/shared/webauthn/common.d.ts +10 -0
- package/dist/web/shared/webauthn/largeBlob.d.ts +0 -3
- package/dist/web/shared/webauthn/prf.d.ts +0 -19
- package/dist/web/worker.mjs +1 -1
- package/package.json +2 -1
- package/dist/cli/shared/codecs/pairPackage.d.ts +0 -14
- package/dist/web/passkey/largeBlob.d.ts +0 -17
- package/dist/web/passkey/webauthn.d.ts +0 -1
- package/dist/web/shared/codecs/pairPackage.d.ts +0 -14
package/dist/web/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function Gl(Z){let X=Z.length,W=0,V=0;while(V<X){let l=Z.charCodeAt(V++);if((l&4294967168)===0){W++;continue}else if((l&4294965248)===0)W+=2;else{if(l>=55296&&l<=56319){if(V<X){let K=Z.charCodeAt(V);if((K&64512)===56320)++V,l=((l&1023)<<10)+(K&1023)+65536}}if((l&4294901760)===0)W+=3;else W+=4}}return W}function r0(Z,X,W){let V=Z.length,l=W,K=0;while(K<V){let G=Z.charCodeAt(K++);if((G&4294967168)===0){X[l++]=G;continue}else if((G&4294965248)===0)X[l++]=G>>6&31|192;else{if(G>=55296&&G<=56319){if(K<V){let m=Z.charCodeAt(K);if((m&64512)===56320)++K,G=((G&1023)<<10)+(m&1023)+65536}}if((G&4294901760)===0)X[l++]=G>>12&15|224,X[l++]=G>>6&63|128;else X[l++]=G>>18&7|240,X[l++]=G>>12&63|128,X[l++]=G>>6&63|128}X[l++]=G&63|128}}var t0=new TextEncoder,e0=50;function ZK(Z,X,W){t0.encodeInto(Z,X.subarray(W))}function ml(Z,X,W){if(Z.length>e0)ZK(Z,X,W);else r0(Z,X,W)}var XK=4096;function BW(Z,X,W){let V=X,l=V+W,K=[],G="";while(V<l){let m=Z[V++];if((m&128)===0)K.push(m);else if((m&224)===192){let J=Z[V++]&63;K.push((m&31)<<6|J)}else if((m&240)===224){let J=Z[V++]&63,R=Z[V++]&63;K.push((m&31)<<12|J<<6|R)}else if((m&248)===240){let J=Z[V++]&63,R=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|J<<12|R<<6|C;if(F>65535)F-=65536,K.push(F>>>10&1023|55296),F=56320|F&1023;K.push(F)}else K.push(m);if(K.length>=XK)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var WK=new TextDecoder,VK=200;function lK(Z,X,W){let V=Z.subarray(X,X+W);return WK.decode(V)}function Yl(Z,X,W){if(W>VK)return lK(Z,X,W);else return BW(Z,X,W)}class VX{type;data;constructor(Z,X){this.type=Z,this.data=X}}class WZ extends Error{constructor(Z){super(Z);let X=Object.create(WZ.prototype);Object.setPrototypeOf(this,X),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:WZ.name})}}var lX=4294967295;function Jl(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function qX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function fX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function Rl(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var KK=-1,GK=4294967295,mK=17179869183;function YK({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=mK)if(X===0&&Z<=GK){let W=new Uint8Array(4);return new DataView(W.buffer).setUint32(0,Z),W}else{let W=Z/4294967296,V=Z&4294967295,l=new Uint8Array(8),K=new DataView(l.buffer);return K.setUint32(0,X<<2|W&3),K.setUint32(4,V),l}else{let W=new Uint8Array(12),V=new DataView(W.buffer);return V.setUint32(0,X),qX(V,4,Z),W}}function JK(Z){let X=Z.getTime(),W=Math.floor(X/1000),V=(X-W*1000)*1e6,l=Math.floor(V/1e9);return{sec:W+l,nsec:V-l*1e9}}function RK(Z){if(Z instanceof Date){let X=JK(Z);return YK(X)}else return null}function CK(Z){let X=new DataView(Z.buffer,Z.byteOffset,Z.byteLength);switch(Z.byteLength){case 4:{let W=X.getUint32(0),V=0;return{sec:W,nsec:0}}case 8:{let W=X.getUint32(0),V=X.getUint32(4),l=(W&3)*4294967296+V,K=W>>>2;return{sec:l,nsec:K}}case 12:{let W=fX(X,4),V=X.getUint32(0);return{sec:W,nsec:V}}default:throw new WZ(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${Z.length}`)}}function FK(Z){let X=CK(Z);return new Date(X.sec*1000+X.nsec/1e6)}var Cl={type:KK,encode:RK,decode:FK};class KX{static defaultCodec=new KX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(Cl)}register({type:Z,encode:X,decode:W}){if(Z>=0)this.encoders[Z]=X,this.decoders[Z]=W;else{let V=-1-Z;this.builtInEncoders[V]=X,this.builtInDecoders[V]=W}}tryToEncode(Z,X){for(let W=0;W<this.builtInEncoders.length;W++){let V=this.builtInEncoders[W];if(V!=null){let l=V(Z,X);if(l!=null){let K=-1-W;return new VX(K,l)}}}for(let W=0;W<this.encoders.length;W++){let V=this.encoders[W];if(V!=null){let l=V(Z,X);if(l!=null)return new VX(W,l)}}if(Z instanceof VX)return Z;return null}decode(Z,X,W){let V=X<0?this.builtInDecoders[-1-X]:this.decoders[X];if(V)return V(Z,X,W);else return new VX(X,Z)}}function bK(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function yX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(bK(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var dK=100,kK=2048;class nX{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??KX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??dK,this.initialBufferSize=Z?.initialBufferSize??kK,this.sortKeys=Z?.sortKeys??!1,this.forceFloat32=Z?.forceFloat32??!1,this.ignoreUndefined=Z?.ignoreUndefined??!1,this.forceIntegerToFloat=Z?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new nX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(Z){if(this.entered)return this.clone().encodeSharedRef(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(Z){if(this.entered)return this.clone().encode(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(Z,X){if(X>this.maxDepth)throw Error(`Too deep objects in depth ${X}`);if(Z==null)this.encodeNil();else if(typeof Z==="boolean")this.encodeBoolean(Z);else if(typeof Z==="number")if(!this.forceIntegerToFloat)this.encodeNumber(Z);else this.encodeNumberAsFloat(Z);else if(typeof Z==="string")this.encodeString(Z);else if(this.useBigInt64&&typeof Z==="bigint")this.encodeBigInt64(Z);else this.encodeObject(Z,X)}ensureBufferSizeToWrite(Z){let X=this.pos+Z;if(this.view.byteLength<X)this.resizeBuffer(X*2)}resizeBuffer(Z){let X=new ArrayBuffer(Z),W=new Uint8Array(X),V=new DataView(X);W.set(this.bytes),this.view=V,this.bytes=W}encodeNil(){this.writeU8(192)}encodeBoolean(Z){if(Z===!1)this.writeU8(194);else this.writeU8(195)}encodeNumber(Z){if(!this.forceIntegerToFloat&&Number.isSafeInteger(Z))if(Z>=0)if(Z<128)this.writeU8(Z);else if(Z<256)this.writeU8(204),this.writeU8(Z);else if(Z<65536)this.writeU8(205),this.writeU16(Z);else if(Z<4294967296)this.writeU8(206),this.writeU32(Z);else if(!this.useBigInt64)this.writeU8(207),this.writeU64(Z);else this.encodeNumberAsFloat(Z);else if(Z>=-32)this.writeU8(224|Z+32);else if(Z>=-128)this.writeU8(208),this.writeI8(Z);else if(Z>=-32768)this.writeU8(209),this.writeI16(Z);else if(Z>=-2147483648)this.writeU8(210),this.writeI32(Z);else if(!this.useBigInt64)this.writeU8(211),this.writeI64(Z);else this.encodeNumberAsFloat(Z);else this.encodeNumberAsFloat(Z)}encodeNumberAsFloat(Z){if(this.forceFloat32)this.writeU8(202),this.writeF32(Z);else this.writeU8(203),this.writeF64(Z)}encodeBigInt64(Z){if(Z>=BigInt(0))this.writeU8(207),this.writeBigUint64(Z);else this.writeU8(211),this.writeBigInt64(Z)}writeStringHeader(Z){if(Z<32)this.writeU8(160+Z);else if(Z<256)this.writeU8(217),this.writeU8(Z);else if(Z<65536)this.writeU8(218),this.writeU16(Z);else if(Z<4294967296)this.writeU8(219),this.writeU32(Z);else throw Error(`Too long string: ${Z} bytes in UTF-8`)}encodeString(Z){let W=Gl(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),ml(Z,this.bytes,this.pos),this.pos+=W}encodeObject(Z,X){let W=this.extensionCodec.tryToEncode(Z,this.context);if(W!=null)this.encodeExtension(W);else if(Array.isArray(Z))this.encodeArray(Z,X);else if(ArrayBuffer.isView(Z))this.encodeBinary(Z);else if(typeof Z==="object")this.encodeMap(Z,X);else throw Error(`Unrecognized object: ${Object.prototype.toString.apply(Z)}`)}encodeBinary(Z){let X=Z.byteLength;if(X<256)this.writeU8(196),this.writeU8(X);else if(X<65536)this.writeU8(197),this.writeU16(X);else if(X<4294967296)this.writeU8(198),this.writeU32(X);else throw Error(`Too large binary: ${X}`);let W=yX(Z);this.writeU8a(W)}encodeArray(Z,X){let W=Z.length;if(W<16)this.writeU8(144+W);else if(W<65536)this.writeU8(220),this.writeU16(W);else if(W<4294967296)this.writeU8(221),this.writeU32(W);else throw Error(`Too large array: ${W}`);for(let V of Z)this.doEncode(V,X+1)}countWithoutUndefined(Z,X){let W=0;for(let V of X)if(Z[V]!==void 0)W++;return W}encodeMap(Z,X){let W=Object.keys(Z);if(this.sortKeys)W.sort();let V=this.ignoreUndefined?this.countWithoutUndefined(Z,W):W.length;if(V<16)this.writeU8(128+V);else if(V<65536)this.writeU8(222),this.writeU16(V);else if(V<4294967296)this.writeU8(223),this.writeU32(V);else throw Error(`Too large map object: ${V}`);for(let l of W){let K=Z[l];if(!(this.ignoreUndefined&&K===void 0))this.encodeString(l),this.doEncode(K,X+1)}}encodeExtension(Z){if(typeof Z.data==="function"){let W=Z.data(this.pos+6),V=W.length;if(V>=4294967296)throw Error(`Too large extension object: ${V}`);this.writeU8(201),this.writeU32(V),this.writeI8(Z.type),this.writeU8a(W);return}let X=Z.data.length;if(X===1)this.writeU8(212);else if(X===2)this.writeU8(213);else if(X===4)this.writeU8(214);else if(X===8)this.writeU8(215);else if(X===16)this.writeU8(216);else if(X<256)this.writeU8(199),this.writeU8(X);else if(X<65536)this.writeU8(200),this.writeU16(X);else if(X<4294967296)this.writeU8(201),this.writeU32(X);else throw Error(`Too large extension object: ${X}`);this.writeI8(Z.type),this.writeU8a(Z.data)}writeU8(Z){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,Z),this.pos++}writeU8a(Z){let X=Z.length;this.ensureBufferSizeToWrite(X),this.bytes.set(Z,this.pos),this.pos+=X}writeI8(Z){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,Z),this.pos++}writeU16(Z){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,Z),this.pos+=2}writeI16(Z){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,Z),this.pos+=2}writeU32(Z){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,Z),this.pos+=4}writeI32(Z){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,Z),this.pos+=4}writeF32(Z){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,Z),this.pos+=4}writeF64(Z){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,Z),this.pos+=8}writeU64(Z){this.ensureBufferSizeToWrite(8),Jl(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),qX(this.view,this.pos,Z),this.pos+=8}writeBigUint64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,Z),this.pos+=8}writeBigInt64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,Z),this.pos+=8}}function qZ(Z,X){return new nX(X).encodeSharedRef(Z)}function _X(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var cK=16,IK=16;class wW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=cK,X=IK){this.maxKeyLength=Z,this.maxLengthPerKey=X,this.caches=[];for(let W=0;W<this.maxKeyLength;W++)this.caches.push([])}canBeCached(Z){return Z>0&&Z<=this.maxKeyLength}find(Z,X,W){let V=this.caches[W-1];Z:for(let l of V){let K=l.bytes;for(let G=0;G<W;G++)if(K[G]!==Z[X+G])continue Z;return l.str}return null}store(Z,X){let W=this.caches[Z.length-1],V={bytes:Z,str:X};if(W.length>=this.maxLengthPerKey)W[Math.random()*W.length|0]=V;else W.push(V)}decode(Z,X,W){let V=this.find(Z,X,W);if(V!=null)return this.hit++,V;this.miss++;let l=BW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var DW="array",zX="map_key",bl="map_value",TK=(Z)=>{if(typeof Z==="string"||typeof Z==="number")return Z;throw new WZ("The type of key must be string or number but "+typeof Z)};class dl{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=DW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=zX,X.readCount=0,X.size=Z,X.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let Z={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(Z)}return this.stack[this.stackHeadPosition]}release(Z){if(this.stack[this.stackHeadPosition]!==Z)throw Error("Invalid stack state. Released state is not on top of the stack.");if(Z.type===DW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===zX||Z.type===bl){let W=Z;W.size=0,W.map=void 0,W.readCount=0,W.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}var SX=-1,AW=new DataView(new ArrayBuffer(0)),QK=new Uint8Array(AW.buffer);try{AW.getInt8(0)}catch(Z){if(!(Z instanceof RangeError))throw Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var Fl=RangeError("Insufficient data"),LK=new wW;class aX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=AW;bytes=QK;headByte=SX;stack=new dl;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??KX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??lX,this.maxBinLength=Z?.maxBinLength??lX,this.maxArrayLength=Z?.maxArrayLength??lX,this.maxMapLength=Z?.maxMapLength??lX,this.maxExtLength=Z?.maxExtLength??lX,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:LK,this.mapKeyConverter=Z?.mapKeyConverter??TK}clone(){return new aX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=SX,this.stack.reset()}setBuffer(Z){let X=yX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===SX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=yX(Z),V=new Uint8Array(X.length+W.length);V.set(X),V.set(W,X.length),this.setBuffer(V)}}hasRemaining(Z){return this.view.byteLength-this.pos>=Z}createExtraByteError(Z){let{view:X,pos:W}=this;return RangeError(`Extra ${X.byteLength-W} of ${X.byteLength} byte(s) found at buffer[${Z}]`)}decode(Z){if(this.entered)return this.clone().decode(Z);try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);let X=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return X}finally{this.entered=!1}}*decodeMulti(Z){if(this.entered){yield*this.clone().decodeMulti(Z);return}try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);while(this.hasRemaining(1))yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(Z){if(this.entered)return this.clone().decodeAsync(Z);try{this.entered=!0;let X=!1,W;for await(let G of Z){if(X)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(G);try{W=this.doDecodeSync(),X=!0}catch(m){if(!(m instanceof RangeError))throw m}this.totalPos+=this.pos}if(X){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return W}let{headByte:V,pos:l,totalPos:K}=this;throw RangeError(`Insufficient data in parsing ${_X(V)} at ${K} (${l} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(Z){return this.decodeMultiAsync(Z,!0)}decodeStream(Z){return this.decodeMultiAsync(Z,!1)}async*decodeMultiAsync(Z,X){if(this.entered){yield*this.clone().decodeMultiAsync(Z,X);return}try{this.entered=!0;let W=X,V=-1;for await(let l of Z){if(X&&V===0)throw this.createExtraByteError(this.totalPos);if(this.appendBuffer(l),W)V=this.readArraySize(),W=!1,this.complete();try{while(!0)if(yield this.doDecodeSync(),--V===0)break}catch(K){if(!(K instanceof RangeError))throw K}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){Z:while(!0){let Z=this.readHeadByte(),X;if(Z>=224)X=Z-256;else if(Z<192)if(Z<128)X=Z;else if(Z<144){let V=Z-128;if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z<160){let V=Z-144;if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else{let V=Z-160;X=this.decodeString(V,0)}else if(Z===192)X=null;else if(Z===194)X=!1;else if(Z===195)X=!0;else if(Z===202)X=this.readF32();else if(Z===203)X=this.readF64();else if(Z===204)X=this.readU8();else if(Z===205)X=this.readU16();else if(Z===206)X=this.readU32();else if(Z===207)if(this.useBigInt64)X=this.readU64AsBigInt();else X=this.readU64();else if(Z===208)X=this.readI8();else if(Z===209)X=this.readI16();else if(Z===210)X=this.readI32();else if(Z===211)if(this.useBigInt64)X=this.readI64AsBigInt();else X=this.readI64();else if(Z===217){let V=this.lookU8();X=this.decodeString(V,1)}else if(Z===218){let V=this.lookU16();X=this.decodeString(V,2)}else if(Z===219){let V=this.lookU32();X=this.decodeString(V,4)}else if(Z===220){let V=this.readU16();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===221){let V=this.readU32();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===222){let V=this.readU16();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===223){let V=this.readU32();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===196){let V=this.lookU8();X=this.decodeBinary(V,1)}else if(Z===197){let V=this.lookU16();X=this.decodeBinary(V,2)}else if(Z===198){let V=this.lookU32();X=this.decodeBinary(V,4)}else if(Z===212)X=this.decodeExtension(1,0);else if(Z===213)X=this.decodeExtension(2,0);else if(Z===214)X=this.decodeExtension(4,0);else if(Z===215)X=this.decodeExtension(8,0);else if(Z===216)X=this.decodeExtension(16,0);else if(Z===199){let V=this.lookU8();X=this.decodeExtension(V,1)}else if(Z===200){let V=this.lookU16();X=this.decodeExtension(V,2)}else if(Z===201){let V=this.lookU32();X=this.decodeExtension(V,4)}else throw new WZ(`Unrecognized type byte: ${_X(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===DW)if(V.array[V.position]=X,V.position++,V.position===V.size)X=V.array,W.release(V);else continue Z;else if(V.type===zX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=bl;continue Z}else if(V.map[V.key]=X,V.readCount++,V.readCount===V.size)X=V.map,W.release(V);else{V.key=null,V.type=zX;continue Z}}return X}}readHeadByte(){if(this.headByte===SX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=SX}readArraySize(){let Z=this.readHeadByte();switch(Z){case 220:return this.readU16();case 221:return this.readU32();default:if(Z<160)return Z-144;else throw new WZ(`Unrecognized array type byte: ${_X(Z)}`)}}pushMapState(Z){if(Z>this.maxMapLength)throw new WZ(`Max length exceeded: map length (${Z}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(Z)}pushArrayState(Z){if(Z>this.maxArrayLength)throw new WZ(`Max length exceeded: array length (${Z}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(Z)}decodeString(Z,X){if(!this.rawStrings||this.stateIsMapKey())return this.decodeUtf8String(Z,X);return this.decodeBinary(Z,X)}decodeUtf8String(Z,X){if(Z>this.maxStrLength)throw new WZ(`Max length exceeded: UTF-8 byte length (${Z}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+X+Z)throw Fl;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=Yl(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===zX;return!1}decodeBinary(Z,X){if(Z>this.maxBinLength)throw new WZ(`Max length exceeded: bin length (${Z}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(Z+X))throw Fl;let W=this.pos+X,V=this.bytes.subarray(W,W+Z);return this.pos+=X+Z,V}decodeExtension(Z,X){if(Z>this.maxExtLength)throw new WZ(`Max length exceeded: ext length (${Z}) > maxExtLength (${this.maxExtLength})`);let W=this.view.getInt8(this.pos+X),V=this.decodeBinary(Z,X+1);return this.extensionCodec.decode(V,W,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let Z=this.view.getUint8(this.pos);return this.pos++,Z}readI8(){let Z=this.view.getInt8(this.pos);return this.pos++,Z}readU16(){let Z=this.view.getUint16(this.pos);return this.pos+=2,Z}readI16(){let Z=this.view.getInt16(this.pos);return this.pos+=2,Z}readU32(){let Z=this.view.getUint32(this.pos);return this.pos+=4,Z}readI32(){let Z=this.view.getInt32(this.pos);return this.pos+=4,Z}readU64(){let Z=Rl(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=fX(this.view,this.pos);return this.pos+=8,Z}readU64AsBigInt(){let Z=this.view.getBigUint64(this.pos);return this.pos+=8,Z}readI64AsBigInt(){let Z=this.view.getBigInt64(this.pos);return this.pos+=8,Z}readF32(){let Z=this.view.getFloat32(this.pos);return this.pos+=4,Z}readF64(){let Z=this.view.getFloat64(this.pos);return this.pos+=8,Z}}function vW(Z,X){return new aX(X).decode(Z)}class UZ{listeners=new Map;addEventListener(Z,X){let W=this.listeners.get(Z);if(!W)W=new Set,this.listeners.set(Z,W);return W.add(X),()=>{this.removeEventListener(Z,X)}}removeEventListener(Z,X){let W=this.listeners.get(Z);if(W){if(W.delete(X),W.size===0)this.listeners.delete(Z)}}emit(Z,X){let W=this.listeners.get(Z);if(W){let V=Array.from(W);for(let l of V)l(X)}}emitAll(Z){let X=Array.from(this.listeners.keys());for(let W of X)this.emit(W,Z)}}class cZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new UZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(cZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(cZ.eventName,Z),()=>{this.emitter.removeEventListener(cZ.eventName,Z)}}}var jZ=64;var kl=32,uZ=8;var sX=32;var cl=30000,Il=512,z;((y)=>{y[y.Success=0]="Success";y[y.InvalidSignature=3]="InvalidSignature";y[y.ClockOutOfSync=4]="ClockOutOfSync";y[y.UserNotRegistered=5]="UserNotRegistered";y[y.ServerMisconfigured=6]="ServerMisconfigured";y[y.MissingBody=7]="MissingBody";y[y.ExtraBodyContent=8]="ExtraBodyContent";y[y.MissingParam=9]="MissingParam";y[y.InvalidParam=10]="InvalidParam";y[y.InvalidRequest=11]="InvalidRequest";y[y.InternalError=12]="InternalError";y[y.NotFound=13]="NotFound";y[y.InvalidMessage=14]="InvalidMessage";y[y.NoChange=15]="NoChange";y[y.DatabaseClosed=16]="DatabaseClosed";y[y.StorageError=17]="StorageError";y[y.DatabaseError=18]="DatabaseError";y[y.HashMismatch=19]="HashMismatch";y[y.DecryptionError=20]="DecryptionError";y[y.NotImplemented=21]="NotImplemented";y[y.MissingSeed=22]="MissingSeed";y[y.OutOfBounds=23]="OutOfBounds";y[y.HostError=24]="HostError";y[y.CommunicationError=25]="CommunicationError";y[y.VarLimitExceeded=26]="VarLimitExceeded";y[y.InvalidResponse=27]="InvalidResponse";y[y.ConnectionClosed=28]="ConnectionClosed";y[y.CryptoError=29]="CryptoError";y[y.WebAuthnError=30]="WebAuthnError"})(z||={});function b(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function pK(Z){if(Z<0)console.info("N",Z),console.trace();if(typeof Z!=="bigint")Z=BigInt(Z);if(Z<0n)return Y(10);let X=[];while(Z>0n){let W=Number(Z&0x7fn);if(Z>>=7n,Z>0n)X.push(W|128);else X.push(W)}if(X.length===0)return b(new Uint8Array([0]));if(X.length>8)return Y(26);return b(new Uint8Array(X))}function yK(Z,X=0){let W=0n,V=0,l=X;while(!0){if(l>=Z.length)return Y(14);let K=Z[l++];if(K===void 0)return Y(14);if(W|=BigInt(K&127)<<BigInt(V),(K&128)===0){if(l-X>8)return Y(26);return b({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class j{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new j(W)}readBigInt(){if(this.pos+8>this.data.length)return Y(7);let Z=new DataView(this.data.buffer,this.data.byteOffset+this.pos).getBigUint64(0,!1);return this.pos+=8,b(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return b(new Date(Z))}readVarInt(){let[Z,X]=yK(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return b(typeof W==="bigint"?Number(W):W)}readVarString(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);let l=new TextDecoder().decode(W);return b(l)}readBytes(Z){if(Z<0)return Y(10);if(this.pos+Z>this.data.length)return Y(23);let X=this.data.slice(this.pos,this.pos+Z);return this.pos+=Z,b(X)}readVarBytes(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return this.readBytes(Z)}readStruct(Z){return Z.decode(this)}readStructs(Z){let X=[];while(!this.done()){let[W,V]=this.readStruct(Z);if(V!==0)return Y(V);X.push(W)}return b(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return b(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class E{parts=[];writeBigInt(Z){let X=new Uint8Array(8);new DataView(X.buffer).setBigUint64(0,Z,!1),this.parts.push(X)}writeDate(Z){let X=Z.getTime();return this.writeVarInt(X)}writeVarInt(Z){let[X,W]=pK(Z);if(W!==0)return W;return this.parts.push(X),0}writeVarString(Z){let X=new TextEncoder().encode(Z),W=this.writeVarInt(X.length);if(W!==0)return W;return this.writeBytes(X),0}prependBytes(Z){this.parts.unshift(Z.slice())}writeBytes(Z){this.parts.push(Z.slice())}writeVarBytes(Z){let X=this.writeVarInt(Z.length);if(X!==0)return X;return this.writeBytes(Z),0}writeStruct(Z,X){return Z.encode(this,X)}writeStructs(Z,X){for(let W of X){let V=this.writeStruct(Z,W);if(V!==0)return V}return 0}writeBytesSeq(Z){for(let X of Z)this.writeBytes(X)}result(){let Z=this.parts.reduce((V,l)=>V+l.length,0),X=new Uint8Array(Z),W=0;for(let V of this.parts)X.set(V,W),W+=V.length;return X}wipe(){for(let Z of this.parts)Z.fill(0);this.parts.length=0}*scan(){for(let Z of this.parts)yield Z}}async function oW(Z,X){let W=new E,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return b({pubKey:Z.publicKey,sig:K,timestamp:X})}async function EZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>cl)return 4;let G=new E;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var s={encode(Z,X){let W=Z.writeVarBytes(X.id);if(W!==0)return W;let V=Z.writeDate(X.ts);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readDate();if(l!==0)return Y(l);return b({id:X,ts:V})}};function GX(Z){let X=new E,W=X.writeStruct(s,Z);if(W!==0)return Y(W);let V=X.result();return b(V)}async function SK(Z){return GX({id:Z,ts:new Date(0)})}var CZ={encode(Z,X){let W=Z.writeVarBytes(X.eid);if(W!==0)return W;let V=Z.writeVarInt(X.off);if(V!==0)return V;let l=Z.writeVarInt(X.ctr);if(l!==0)return l;let K=Z.writeVarInt(X.len);if(K!==0)return K;if(X.hsh)Z.writeBytes(X.hsh);return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let V=new j(X),[,l]=s.decode(V);if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,J]=Z.readVarInt();if(J!==0)return Y(J);let[R,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(R>0){let[d,k]=Z.readBytes(sX);if(k!==0)return Y(k);F=d}return b({eid:X,off:K,ctr:m,len:R,hsh:F})}};function YZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function xX(Z){if(Z.length%2!==0)throw Error("Invalid hex string");let X=new Uint8Array(Z.length/2);for(let W=0;W<Z.length;W+=2)X[W/2]=Number.parseInt(Z.substr(W,2),16);return X}function w(Z,X){if(Z===X)return!0;if(Z.byteLength!==X.byteLength)return!1;return Z.every((W,V)=>W===X[V])}var H;if(typeof Uint8Array.prototype.toBase64==="function")H=(Z)=>Z.toBase64();else H=(Z)=>btoa(String.fromCharCode(...Z));var e;if(typeof Uint8Array.fromBase64==="function")e=(Z)=>Uint8Array.fromBase64(Z);else e=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function zK(Z){return H(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function $W(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function SZ(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function Tl(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Ql(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new E,G=CZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),J=await X.kdmFor(m),R=V.deriveCipher(J,"encrypt"),C=await R.encrypt(m),F=Z.bod?await R.encrypt(Z.bod):new Uint8Array(0),d=await X.sign(C);return b({sig:d,kdm:J,headCph:C,bodyCph:F})}async function qW(Z,X,W,V,l){let K=new j(Z),[G,m]=CZ.decode(K);if(m!==0)return Y(14);let J;try{J=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let R=G.hsh&&J===void 0,C=G.hsh===void 0&&J!==void 0;if(R||C)return Y(19);if(G.hsh&&J){let d=await V.blake3(J);if(!w(d,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return b({msgHead:G,bod:J,headHash:F})}class OZ{now(){return new Date}}function Ll(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var MX={encode(Z,X){if(Z.writeVarInt(X.quota),X.quota>0){if(X.usage===void 0)return 9;Z.writeVarInt(X.usage)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let V;if(X>0){let[l,K]=Z.readVarInt();if(K!==0)return Y(K);V=l}return b({quota:X,usage:V})}};var fW={encode(Z,X){Z.writeBytes(new Uint8Array([X.status]));let W=Z.writeDate(X.timeRcvd);if(W!==0)return W;let V=Z.writeDate(X.timeSent);if(V!==0)return V;let l=Z.writeVarInt(X.subscription.term);if(l!==0)return l;let K=Z.writeVarInt(X.subscription.elapsed);if(K!==0)return K;let G=Z.writeStruct(MX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(MX,X.subscription.dyn);if(m!==0)return m;return 0},decode(Z){let[X,W]=Z.readBytes(1);if(W!==0)return Y(W);let V=X[0],[l,K]=Z.readDate();if(K!==0)return Y(K);let[G,m]=Z.readDate();if(m!==0)return Y(m);let[J,R]=Z.readVarInt();if(R!==0)return Y(R);let[C,F]=Z.readVarInt();if(F!==0)return Y(F);let[d,k]=Z.readStruct(MX);if(k!==0)return Y(k);let[c,I]=Z.readStruct(MX);if(I!==0)return Y(I);return b({status:V,timeRcvd:l,timeSent:G,subscription:{term:J,elapsed:C,stat:d,dyn:c}})}};var nW={encode(Z,X){let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.seq);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);return b({headCph:X,seq:V})}};var JZ={encode(Z,X){Z.writeBytes(X.pubKey),Z.writeBytes(X.sig);let W=Z.writeDate(X.timestamp);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(kl);if(W!==0)return Y(W);let[V,l]=Z.readBytes(jZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return b({pubKey:X,sig:V,timestamp:K})}};var pl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(JZ,W);if(K!==0)return K;for(let G of V)l.writeVarInt(G);return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(JZ);if(m!==0)return m;let J=await EZ(G,l,V);if(J!==0)return J;let{pubKey:R}=G,[C,F]=await K.hasUser(R);if(F!==0)return F;if(!C)return 5;let[d,k]=X.readVarInt();if(k!==0)return k;if(!X.done())return 8;let[c,I]=await K.listHeads(R,d);if(I!==0)return I;return W.writeStructs(nW,c)},decodeResp(Z){return Z.readStructs(nW)}};var _W={encode(Z,X){Z.writeVarInt(X.seq);let W=Z.writeVarBytes(X.bodyCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);return b({seq:X,bodyCph:V})}};var yl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(JZ,W);if(K!==0)return K;for(let G of V){let m=l.writeVarInt(G);if(m!==0)return m}return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(JZ);if(m!==0)return m;let J=await EZ(G,l,V);if(J!==0)return J;let{pubKey:R}=G,[C,F]=await K.hasUser(R);if(F!==0)return F;if(!C)return 5;let d=[];while(!X.done()){let[I,T]=X.readVarInt();if(T!==0)return T;d.push(I)}console.info(`PULL: ${d.length} bags`);let[k,c]=await K.getBodies(R,d);if(c!==0)return c;if(!k)return 17;for(let{seq:I,bodyCph:T}of k){let p={seq:I,bodyCph:T},L=W.writeStruct(_W,p);if(L!==0)return L}return 0},decodeResp(Z){return Z.readStructs(_W)}};var aW={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarBytes(X.bodyCph);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readBytes(jZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(uZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);let[m,J]=Z.readVarBytes();if(J!==0)return Y(J);return b({sig:X,kdm:V,headCph:K,bodyCph:m})}};var rX={encode(Z,X){let W=Z.writeVarInt(X.seq);if(W!==0)return W;let V=Z.writeVarBytes(X.headCph);if(V!==0)return V;let l=X.bodyCph?X.bodyCph.length:0,K=Z.writeVarInt(l);if(K!==0)return K;if(l>0){if(!X.bodyCph)return 10;Z.writeBytes(X.bodyCph)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[J,R]=Z.readBytes(K);if(R!==0)return Y(R);m=J}return b({seq:X,headCph:V,bodyCph:m})}};var tX={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(jZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(uZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return b({sig:X,kdm:V,headCph:K})}};var eX={encode(Z,X){if(Z.writeVarInt(X.idx),Z.writeBytes(new Uint8Array([X.status])),X.status===0)Z.writeVarInt(X.seq);return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readBytes(1);if(l!==0)return Y(l);let K=V[0];if(K!==0)return b({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return b({idx:X,status:K,seq:G})}};var Sl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(JZ,W);if(K!==0)return K;let G=l.writeStructs(aW,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,J]=X.readStruct(JZ);if(J!==0)return J;let R=await EZ(m,l,V);if(R!==0)return R;let{pubKey:C}=m,[F,d]=await K.hasUser(C);if(d!==0)return d;if(!F)return 5;let[k,c]=X.readStructs(aW);if(c!==0)return c;console.info(`PUSH: ${k.length} bags`);let I=[],T=[];for(let Q=0;Q<k.length;Q++){let M=k[Q];if(!await Tl(M,C,l)){let O={idx:Q,status:3},u=W.writeStruct(eX,O);if(u!==0)return u;continue}I.push(Q),T.push(M)}let[p,L]=await K.setBags(C,T);if(L!==0)return L;if(!p||p.length!==T.length)return 17;let S=[];for(let Q=0;Q<T.length;Q++){let M=T[Q],g=I[Q],O=p[Q],u=new E,P=u.writeStruct(tX,M);if(P!==0)return P;let B=u.result(),A={seq:O,headCph:B};if(k.length===1&&M.bodyCph.length<=Il)A.bodyCph=M.bodyCph;S.push(A);let $={idx:g,status:0,seq:O},y=W.writeStruct(eX,$);if(y!==0)return y}if(S.length>0){let Q=new E,M=Q.writeStructs(rX,S);if(M!==0)return M;let g=Q.result();await Promise.resolve(G.push(C,g))}return 0},decodeResp(Z){return Z.readStructs(eX)}};var zl={async encodeReq(Z,X,W,V,l){return l.writeStruct(JZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(JZ);if(m!==0)return m;let J=await EZ(G,l,V);if(J!==0)return J;let{pubKey:R}=G;if(!X.done())return 8;let[C,F]=await K.addUser(R);if(F!==0)return F;return 0},decodeResp(Z){return b(void 0)}};class sW{url;websocket;constructor(Z){this.url=Z}connected(){return this.websocket!==void 0&&this.websocket.readyState===WebSocket.OPEN}async connect(Z,X,W=()=>{},V=()=>{}){let{url:l}=this;if(this.websocket)this.websocket.close(),this.websocket=void 0;let K=new E;K.writeStruct(JZ,Z);let G=K.result(),m=YZ(G);return l.searchParams.set("t",m),this.websocket=new WebSocket(l),this.websocket.binaryType="arraybuffer",this.websocket.onopen=()=>{console.log("CONNECTED"),V()},this.websocket.onclose=()=>{console.log("DISCONNECTED"),this.websocket=void 0,W()},this.websocket.onmessage=(J)=>{let R=new Uint8Array(J.data);X(R)},this.websocket.onerror=(J)=>{console.log(`ERROR: ${JSON.stringify(J)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var r={user:{path:"/user",endpoint:zl,name:0},push:{path:"/push",endpoint:Sl,name:2},peek:{path:"/peek",endpoint:pl,name:1},pull:{path:"/pull",endpoint:yl,name:3}},xK={0:r.user,2:r.push,1:r.peek,3:r.pull},kR={[r.user.path]:r.user,[r.push.path]:r.push,[r.peek.path]:r.peek,[r.pull.path]:r.pull};class rW{url;listener;constructor(Z){this.url=Z;this.listener=new sW(Z)}async call(Z,X){let{path:W}=xK[Z],V=new URL(W,this.url);try{return await MK(V,X)}catch{return Y(25)}}}var tW=(Z)=>{return new rW(Z.handle)};async function MK(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await j.fromResponse(W);return b(V)}class ZW{enclave;crypto;host;clock;transport;updateHostMeta;constructor(Z,X,W,V,l,K){this.enclave=Z;this.crypto=X;this.host=W;this.clock=V;this.transport=l;this.updateHostMeta=K}async call(Z,X){let{clock:W,transport:V}=this,{endpoint:l,name:K}=Z,G=await this.identity(),m=W.now(),[J,R]=await oW(G,m);if(R!==0)return Y(R);let C=new E,F=await l.encodeReq(this,G,J,X,C);if(F!==0)return Y(F);let d=W.now(),[k,c]=await V.call(K,C),I=W.now();if(c!==0)return Y(c);let[T,p]=k.readStruct(fW);if(p!==0)return Y(p);if(T.status!==0)return Y(T.status);let S={clockOffset:Ll(d,T.timeRcvd,T.timeSent,I),subscription:T.subscription},Q=await this.updateHostMeta(S);if(Q!==0)return Y(Q);return l.decodeResp(k)}identity=()=>{let{host:Z,enclave:X}=this;return X.deriveIdentity(Z.label,Z.idx??0)};seal=async(Z)=>{let{crypto:X,enclave:W}=this,V=await this.identity();return Ql(Z,V,X,W)};register=()=>this.call(r.user,[]);peek=(Z)=>this.call(r.peek,[Z]);push=(Z)=>this.call(r.push,Z);pull=(Z)=>this.call(r.pull,Z);listen=async(Z,X,W)=>{let{clock:V,transport:l}=this,{listener:K}=l,G=await this.identity(),m=V.now(),[J,R]=await oW(G,m);if(R!==0)return R;return await K.connect(J,Z,X,W)};isConnected(){let Z=this.transport?.listener;if(Z&&typeof Z.connected==="function")return Z.connected();return!0}closeListener(){this.transport?.listener?.disconnect()}}var eW={encode(Z,X){let W=Z.writeVarString(X.lbl);if(W!==0)return W;let V=Z.writeVarInt(X.idx);if(V!==0)return V;let l=Z.writeVarInt(X.num);if(l!==0)return l;return Z.writeBytes(X.hsh),Z.writeBytes(X.sig),0},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,J]=Z.readBytes(sX);if(J!==0)return Y(J);let[R,C]=Z.readBytes(jZ);if(C!==0)return Y(C);return b({lbl:X,idx:V,num:K,hsh:m,sig:R})}};var ZV={encode(Z,X){let W=Z.writeStruct(eW,X.head);if(W!==0)return W;let V=Z.writeVarBytes(X.indexEnc);if(V!==0)return V;let l=Z.writeVarBytes(X.bodyEnc);if(l!==0)return l;return 0},decode(Z){let[X,W]=Z.readStruct(eW);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return b({head:X,indexEnc:V,bodyEnc:K})}};var XV={encode(Z,X){Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.lenBody);if(V!==0)return V;if(X.lenBody>0&&X.offBody!==void 0){let l=Z.writeVarInt(X.offBody);if(l!==0)return l}return 0},decode(Z){let[X,W]=Z.readBytes(uZ);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[J,R]=Z.readVarInt();if(R!==0)return Y(R);m=J}return b({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function xl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new E,m=new E,J=0,R=0;for(let p of W){let L=new E,S=L.writeStruct(CZ,p.head);if(S!==0)return Y(S);let Q=L.result(),M=await K.kdmFor(Q),g=l.deriveCipher(M,"encrypt"),O=await g.encrypt(Q),u=p.body?await g.encrypt(p.body):new Uint8Array(0),P=p.head.len>0&&p.head.hsh!==void 0?u.length:0,B={kdm:M,headCph:O,lenBody:P,offBody:P>0?R:void 0},A=G.writeStruct(XV,B);if(A!==0)return Y(A);if(p.body)m.writeBytes(u),R+=u.length;J++}let C=m.result(),F=G.result(),d=await V.blake3(F),k=await K.sign(d),c={lbl:Z,idx:X,num:J,hsh:d,sig:k},I=new E;I.writeStruct(ZV,{head:c,indexEnc:F,bodyEnc:C});let T=I.result();return b(T)}async function Ml(Z,X,W){let[V,l]=ZV.decode(new j(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,J=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,J.publicKey))return Y(3);let C=await X.blake3(G);if(!w(C,K.hsh))return Y(19);let F=new j(G),d=[];for(let c=0;c<K.num;c++){let[I,T]=F.readStruct(XV);if(T!==0)return Y(T);d.push(I)}if(d.length!==K.num)return Y(14);let k=[];for(let c of d){let I=W.deriveCipher(c.kdm,"decrypt"),T;try{T=await I.decrypt(c.headCph)}catch{return Y(20)}let[p,L]=CZ.decode(new j(T));if(L!==0)return Y(L);let S;if(c.lenBody>0&&c.offBody!==void 0){if(p.hsh===void 0)return Y(14);let Q=m.slice(c.offBody,c.offBody+c.lenBody);try{S=await I.decrypt(Q)}catch{return Y(20)}let M=await X.blake3(S);if(!w(M,p.hsh))return Y(19)}k.push({head:p,body:S})}return b(k)}async function Nl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new E,K=l.writeStruct(s,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return XW({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function XW({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new j(X),[G,m]=s.decode(K);if(m!==0)return Y(m);let J=Z.getTime()-G.ts.getTime(),R,C=V?.length??0;if(V&&C>0)R=await l.blake3(V);return b({eid:X,off:J,ctr:W,len:C,hsh:R})}function Hl(Z,X){let W=Z.length<X.length?Z.length:X.length;for(let V=0;V<W;V++)if(Z[V]!==X[V])return Z[V]-X[V];return Z.length-X.length}async function mX(Z,X){let W=Array.from(Z);W.sort(Hl);let V=0;for(let G of W)V+=G.length;let l=new Uint8Array(V),K=0;for(let G of W)l.set(G,K),K+=G.length;return X.blake3(l)}function gl(Z){let X=new E,W=X.writeVarBytes(Z.eid);if(W!==0)return Y(W);let V=X.writeDate(Z.updatedAt);if(V!==0)return Y(V);let l=X.writeVarInt(Z.ctr);if(l!==0)return Y(l);return b(X.result())}async function NX(Z,X){let W=[];for(let V of Z){let[l,K]=gl(V);if(K!==0||!l)return Y(K);W.push(l)}return b(await mX(W,X))}var YC=Symbol("MasterSeed"),JC=Symbol("SealedMasterKey"),kZ=32,WV=24+kZ+16;function VZ(Z){if(Z.byteLength!==kZ)return Y(10);return b(Z)}function iZ(Z){if(Z.byteLength!==WV)return Y(10);return b(Z)}var CC=Symbol("EntityID");function hl(Z){return"type"in Z}var FC=Symbol("DerivationSeed"),bC=Symbol("PublicKey"),dC=Symbol("PrivateKey"),kC=Symbol("HostSpecificKeyPair"),cC=Symbol("Hash");function NK(Z){if(!Z)return!1;if(typeof Z!=="object")return!1;if("body"in Z===!1)return!1;if("type"in Z===!1)return!1;return!0}function HK(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return b(V)}let X=vW(Z.bod);if(NK(X)===!1)return console.warn("msg body invalid",X),Y(14);let W={off:Z.off,ctr:Z.ctr,eid:Z.eid,gid:X.gid,pid:X.pid,tags:X.tags,type:X.type,body:X.body};return b(W)}class HX{applier;emitter=new UZ;clearer;onDirtyEids;cacheDriven;peerIngest;constructor(Z,X,W,V){this.applier=Z;this.clearer=X,this.onDirtyEids=W,this.cacheDriven=V?.cacheDriven??!1,this.peerIngest=V?.peerIngest}apply=async(Z)=>{let X=[],W=[];for(let m of Z){let[J,R]=HK(m);if(W.push(R),R!==0)continue;X.push(J)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let J=W[m],R=V[m];if(J!==0){G.push(J);continue}if(R!==0){G.push(R);continue}G.push(0)}if(!this.cacheDriven)for(let m of l)this.emitter.emit(m,null);if(K.length>0)this.onDirtyEids?.(K);return G};clear=async()=>{let Z=await this.clearer();if(Z!==0)return Z;return this.emitter.emitAll(null),Z};notify=(Z)=>{for(let X of Z)this.emitter.emit(X,null)};refresh=async(Z)=>{if(this.peerIngest){await this.peerIngest(Z);return}};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var VV={apply:async function(Z){return Z.map(()=>0)},clear:async function(){return 0},notify:function(Z){},refresh:async function(Z){},on:function(Z,X){},off:function(Z,X){}};var n="entities",WW="entity_type_created_at",KV="entity_type_updated_at",GV="entity_type_group_id",mV="entity_type_parent_id",YX="entity_tags",Pl="db",Ul=13;function gK(Z){return"typ"in Z}function hK(Z){let X={bod:Z.body,crd:Z.createdAt,...Z.ctr!==0?{ctr:Z.ctr}:{},eid:H(Z.eid),gid:Z.gid,pid:Z.pid?H(Z.pid):void 0,tgs:Z.tags,typ:Z.type,upd:Z.updatedAt};if(X.gid===void 0)delete X.gid;if(X.pid===void 0)delete X.pid;if(X.tgs===void 0)delete X.tgs;if(X.ctr===void 0)delete X.ctr;return X}function PK(Z){if(!o(Z))return{eid:H(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return hK(Z)}function JX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:e(Z.eid),gid:Z.gid,pid:Z.pid?e(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function lV(Z){if(gK(Z))return JX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class YV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=jK().then((Z)=>{return Z.onversionchange=()=>{if(Z.close(),this.db===Z)this.db=void 0},this.db=Z,this.opening=void 0,Z},(Z)=>{throw this.opening=void 0,Z}),this.opening}apply=async(Z)=>{let X=new Set,W=[],V;try{V=await this.ensureDb()}catch{return{stats:Z.map(()=>16),types:X,eids:W}}let l=V.transaction(n,"readwrite"),K=l.objectStore(n);return new Promise((G)=>{let m=Array(Z.length).fill(0);if(Z.length<1){G({stats:[],types:X,eids:W});return}l.oncomplete=()=>{G({stats:m,types:X,eids:W})},l.onerror=()=>{for(let R=0;R<m.length;R++)if(m[R]===void 0)m[R]=18;G({stats:m,types:X,eids:W})};let J=new Map;for(let R=0;R<Z.length;R++){let C=Z[R],F=H(C.eid),d={op:C,index:R},k=J.get(F);if(k)k.push(d);else J.set(F,[d])}for(let[R,C]of J){if(C.length<1)continue;let F=K.get(R);F.onsuccess=()=>{let d=F.result,k=d?lV(d):void 0,c=!1;for(let{op:I,index:T}of C){let[p,L]=RX(k,I);if(L!==0){m[T]=L;continue}if(p===void 0){m[T]=12;continue}c=!0;for(let S of CX(k,p))X.add(S);k=p}if(c)W.push(C[0].op.eid);if(k){let I=K.put(PK(k));I.onerror=(T)=>{T.preventDefault();for(let{index:p}of C)m[p]=18}}},F.onerror=()=>{for(let{index:d}of C)m[d]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(n,"readwrite"),W=X.objectStore(n);return new Promise((V)=>{X.oncomplete=()=>V(0),X.onerror=()=>V(18),W.clear()})}async getRow(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=H(Z),l=X.transaction(n,"readonly").objectStore(n);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(b(void 0));else K(b(lV(m)))},G.onerror=()=>K(Y(18))})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!o(X))return b(void 0);return b(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(n,"readonly").objectStore(n).index(KV);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let J=m.result;G(b(J.map(JX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(n,"readonly").objectStore(n).index(GV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(b(m.map(JX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(n,"readonly").objectStore(n).index(WW);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(b(G.map(JX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(n,"readonly").objectStore(n).index(YX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let J=G.result.filter((R)=>R.typ===Z).map(JX);K(b(J))},G.onerror=()=>K(Y(18))})}async getAllEntities(Z){if("pid"in Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=H(Z.pid),l=X.transaction(n,"readonly").objectStore(n).index(mV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let J=G.result.map(JX);K(b(J))},G.onerror=()=>K(Y(18))})}else if("gid"in Z)return await this.getGroupMembers(Z.type,Z.gid);else if("tag"in Z)return await this.getByTag(Z.type,Z.tag);else if("updatedBetween"in Z)return await this.getAllOfTypeUpdatedBetween(Z.type,Z.updatedBetween.start,Z.updatedBetween.end);return await this.getAllOfType(Z.type)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return b(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(n,"readonly").objectStore(n).index(WW);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(b(G.result)),G.onerror=()=>l(Y(18))})}async checksum(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(n,"readonly").objectStore(n),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let J=m.value;l.push(gX(lV(J))),m.continue()}else NX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function UK(Z,X){if(!Z.objectStoreNames.contains(n))Z.createObjectStore(n,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(n);if(!W.indexNames.contains(WW))W.createIndex(WW,["typ","crd"],{unique:!1});if(!W.indexNames.contains(KV))W.createIndex(KV,["typ","upd"],{unique:!1});if(!W.indexNames.contains(GV))W.createIndex(GV,["typ","gid"],{unique:!1});if(!W.indexNames.contains(mV))W.createIndex(mV,["typ","pid"],{unique:!1});if(W.indexNames.contains(YX)){if(W.index(YX).keyPath!=="tgs")W.deleteIndex(YX)}if(!W.indexNames.contains(YX))W.createIndex(YX,"tgs",{unique:!1,multiEntry:!0})}function jK(){return new Promise((Z,X)=>{let W=indexedDB.open(Pl,Ul);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{UK(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Pl} → v${Ul}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function jl(){let Z=new YV;return await Z.init(),Z}class VW{ents=new Map;useIndex;byType=new Map;byTypePid=new Map;byTypeGid=new Map;byTypeTag=new Map;constructor(Z=[],X){this.useIndex=X?.indexes!==!1;for(let W of Z)this.put(W)}put(Z){let X=H(Z.eid),W=this.ents.get(X);if(W!==void 0&&o(W))this.unindex(X,W);if(this.ents.set(X,Z),o(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(o(X))this.unindex(Z,X);this.ents.delete(Z)}index(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(!W)W=new Map,this.byType.set(X.type,W);if(W.set(Z,X),X.pid){let V=H(X.pid),l=this.byTypePid.get(X.type);if(!l)l=new Map,this.byTypePid.set(X.type,l);let K=l.get(V);if(!K)K=new Map,l.set(V,K);K.set(Z,X)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type);if(!V)V=new Map,this.byTypeGid.set(X.type,V);let l=V.get(X.gid);if(!l)l=new Map,V.set(X.gid,l);l.set(Z,X)}if(X.tags){let V=this.byTypeTag.get(X.type);if(!V)V=new Map,this.byTypeTag.set(X.type,V);for(let l of X.tags){let K=V.get(l);if(!K)K=new Map,V.set(l,K);K.set(Z,X)}}}unindex(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(W){if(W.delete(Z),W.size===0)this.byType.delete(X.type)}if(X.pid){let V=H(X.pid),l=this.byTypePid.get(X.type),K=l?.get(V);if(K){if(K.delete(Z),K.size===0)l?.delete(V)}if(l&&l.size===0)this.byTypePid.delete(X.type)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type),l=V?.get(X.gid);if(l){if(l.delete(Z),l.size===0)V?.delete(X.gid)}if(V&&V.size===0)this.byTypeGid.delete(X.type)}if(X.tags){let V=this.byTypeTag.get(X.type);if(V){for(let l of X.tags){let K=V.get(l);if(K){if(K.delete(Z),K.size===0)V.delete(l)}}if(V.size===0)this.byTypeTag.delete(X.type)}}}clearIndexes(){this.byType.clear(),this.byTypePid.clear(),this.byTypeGid.clear(),this.byTypeTag.clear()}bucketList(Z){if(!Z||Z.size===0)return[];let X=[];for(let W of Z.values())X.push(W);return X}async apply(Z){let X=new Set,W=[],V=[];for(let l of Z){let K=H(l.eid),G=this.ents.get(K),[m,J]=RX(G,l);if(J!==0){V.push(J);continue}if(m===void 0){V.push(12);continue}for(let R of CX(G,m))X.add(R);this.put(m),W.push(l.eid),V.push(0)}return{stats:V,types:X,eids:W}}async clear(){return this.ents.clear(),this.clearIndexes(),0}async getRow(Z){let X=H(Z),W=this.ents.get(X);return b(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!o(X))return b(void 0);return b(X)}async getAllEntities({type:Z,gid:X,pid:W,tag:V,updatedBetween:l}){if(this.useIndex){if(W!==void 0){let G=H(W);return b(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return b(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return b(this.bucketList(this.byTypeTag.get(Z)?.get(V)));if(l!==void 0){let G=[],m=this.byType.get(Z);if(m){for(let J of m.values())if(J.updatedAt>=l.start&&J.updatedAt<=l.end)G.push(J)}return b(G)}return b(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(o(G)&&G.type===Z&&G.pid&&w(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(o(G)&&G.type===Z&&(typeof G.gid==="string"&&G.gid===X))K.push(G)}else if(V!==void 0){for(let G of this.ents.values())if(o(G)&&G.type===Z&&G.tags&&G.tags.includes(V))K.push(G)}else if(l!==void 0){for(let G of this.ents.values())if(o(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(o(G)&&G.type===Z)K.push(G);return b(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return b(X)}async countEntities({type:Z}){if(this.useIndex)return b(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(o(W)&&W.type===Z)X+=1;return b(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(gX(W));return NX(X,Z)}}async function JV(Z){let X=await jl();if(Z?.cache===!1)return X;return new hX(X,void 0,{indexes:Z?.indexes})}class hX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new VW(X??[],{indexes:W?.indexes}),X)for(let V of X)this.warmed.add(V.type)}subscribe(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}emit(Z){if(Z.size<1)return;for(let X of this.listeners)X(Z)}run(Z){let X=this.chain.then(Z,Z);return this.chain=X.then(()=>{return},()=>{return}),X}apply(Z){return this.run(async()=>{await this.pullEids(Z.map((K)=>K.eid));let X=wK(this.mem,Z);this.emit(X.types);let W=await this.durable.apply(Z),{changed:V,status:l}=await this.pullEids(Z.map((K)=>K.eid));if(this.emit(V),l!==0)return{stats:Z.map(()=>l),types:W.types,eids:W.eids};return W})}clear(){return this.run(async()=>{let Z=await this.durable.clear();if(Z!==0)return Z;let X=this.mem.ents.size>0;return await this.mem.clear(),this.warmed.clear(),0})}ingestFromDurable(Z){return this.run(async()=>{let{changed:X,status:W}=await this.pullEids(Z);return this.emit(X),W})}async pullEids(Z){let X=new Set,W=new Set;for(let V of Z){let l=H(V);if(W.has(l))continue;W.add(l);let K=this.mem.ents.get(l),[G,m]=await this.durable.getRow(V);if(m!==0)return{changed:X,status:m};if(G){if(this.mem.put(G),!K||!uK(K,G)){if(o(G))X.add(G.type);if(K!==void 0&&o(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),o(K))X.add(K.type)}}return{changed:X,status:0}}async warmType(Z){if(this.warmed.has(Z))return 0;let[X,W]=await this.durable.getEntities({type:Z});if(W!==0)return W;if(X)for(let V of X){let l=H(V.eid),K=this.mem.ents.get(l);if(!K||BK(V,K))this.mem.put(V)}return this.warmed.add(Z),0}async getRow(Z){let X=H(Z);if(this.mem.ents.has(X))return this.mem.getRow(Z);return this.run(async()=>{if(this.mem.ents.has(X))return this.mem.getRow(Z);let[W,V]=await this.durable.getRow(Z);if(V!==0)return Y(V);if(W)this.mem.put(W);return b(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!o(X))return b(void 0);return b(X)}async getEntities(Z){if(!this.warmed.has(Z.type)){let X=await this.run(()=>this.warmType(Z.type));if(X!==0)return Y(X)}return this.mem.getEntities(Z)}async countEntities({type:Z}){if(!this.warmed.has(Z)){let X=await this.run(()=>this.warmType(Z));if(X!==0)return Y(X)}return this.mem.countEntities({type:Z})}async checksum(Z){return this.durable.checksum(Z)}}function uK(Z,X){if(o(Z)!==o(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!w(Z.eid,X.eid))return!1;if(!o(Z)||!o(X))return!0;if(Z.createdAt.getTime()!==X.createdAt.getTime())return!1;if(Z.type!==X.type)return!1;if(Z.gid!==X.gid)return!1;if(!OK(Z.pid,X.pid))return!1;if(!EK(Z.tags,X.tags))return!1;return iK(Z.body,X.body)}function EK(Z,X){if(Z===X)return!0;if(Z===void 0||X===void 0)return!1;if(Z.length!==X.length)return!1;for(let W=0;W<Z.length;W++)if(Z[W]!==X[W])return!1;return!0}function OK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return w(Z,X)}function iK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return w(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return w(qZ(Z),qZ(X))}catch{return!1}}function BK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function wK(Z,X){let W=new Set,V=[];for(let l of X){let K=H(l.eid),G=Z.ents.get(K),[m,J]=RX(G,l);if(J!==0){V.push(J);continue}if(m===void 0){V.push(12);continue}for(let R of CX(G,m))W.add(R);Z.put(m),V.push(0)}return{stats:V,types:W}}function lW(Z){if(Z instanceof hX){let X=new HX((W)=>Z.apply(W),()=>Z.clear(),void 0,{cacheDriven:!0,peerIngest:async(W)=>{await Z.ingestFromDurable(W)}});return Z.subscribe((W)=>X.notify(W)),X}return new HX((X)=>Z.apply(X),()=>Z.clear())}function o(Z){return"type"in Z}function DK(Z){return!o(Z)}function ul(Z){if(!Array.isArray(Z)||Z.length===0)return;let X=new Set,W=[];for(let V of Z){if(typeof V!=="string"||V.length===0)continue;if(X.has(V))continue;X.add(V),W.push(V)}return W.length>0?W:void 0}function gX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function RV(Z){let X=new j(Z.eid),[W,V]=X.readStruct(s);if(V!==0)return Y(V);return b({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function RX(Z,X){let W=new j(X.eid),[V,l]=W.readStruct(s);if(l!==0)return Y(l);let K=new Date(V.ts.getTime()+X.off);if(Z!==void 0&&K<=Z.updatedAt)return Y(15);if(hl(X)){let G=ul(X.tags);return b({eid:X.eid,gid:X.gid,pid:X.pid,...G!==void 0?{tags:G}:{},type:X.type,createdAt:V.ts,updatedAt:K,ctr:X.ctr,body:X.body})}return b({eid:X.eid,updatedAt:K,ctr:X.ctr})}function CX(Z,X){let W=new Set;if(Z!==void 0&&o(Z))W.add(Z.type);if(o(X))W.add(X.type);return[...W]}var AK={getEnt:async()=>Y(21),getRow:async()=>Y(21),getEntities:async(Z)=>Y(21),countEntities:async()=>Y(21),checksum:async()=>Y(21),apply:async(Z)=>({stats:Z.map(()=>21),types:new Set,eids:[]}),clear:async()=>21};class KW{inflight=null;again=!1;run(Z){if(this.again=!0,this.inflight)return this.inflight;return this.inflight=this.drain(Z),this.inflight}async flush(){if(!this.inflight)return;try{await this.inflight}catch{}}async drain(Z){try{this.again=!1;let X=await Z();while(this.again)this.again=!1,X=await Z();return X}finally{this.inflight=null}}}var GW=100;class PX{timer=null;delayMs;work;tail=new KW;constructor(Z,X){this.delayMs=Z<0?0:Z,this.work=X}schedule(){if(this.delayMs<=0){this.fire();return}if(this.timer!==null)clearTimeout(this.timer);this.timer=setTimeout(()=>{this.timer=null,this.fire()},this.delayMs)}async flush(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null,this.fire();await this.tail.flush()}cancel(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null}fire(){return this.tail.run(this.work)}}function El(Z){let X=new j(Z.eid),[W,V]=s.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function vK(Z,X){let W=El(Z),V=El(X);if(W===void 0&&V===void 0)return 0;if(W===void 0)return 1;if(V===void 0)return-1;if(V!==W)return V-W;return X.ctr-Z.ctr}function FX(Z,X){return Z.slice().sort((W,V)=>vK(X(W),X(V)))}var fZ={phase:"idle"},bX=50;function mW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function YW(Z,X){if(typeof navigator.msSaveOrOpenBlob==="function"){navigator.msSaveOrOpenBlob(Z,X);return}let W=URL.createObjectURL(Z),V=document.createElement("a");V.href=W,V.download=X,document.body.appendChild(V),V.click(),document.body.removeChild(V),URL.revokeObjectURL(W)}function Ol(Z,X,W){let V=[],l=[],K=0;for(let G of Z){let m=X(G);if(l.length>0&&K+m>W)V.push(l),l=[],K=0;if(l.push(G),K+=m,K>=W)V.push(l),l=[],K=0}if(l.length>0)V.push(l);return V}async function CV(Z,X,W){let V=Z.length;if(V<1)return[];let l=Array(V),K=0,G=Math.min(Math.max(1,X),V),m=async()=>{while(!0){let R=K;if(K+=1,R>=V)return;l[R]=await W(Z[R],R)}},J=[];for(let R=0;R<G;R++)J.push(m());return await Promise.all(J),l}async function JW(Z,X,W,V){let l=new j(Z.headCph),[K,G]=l.readStruct(tX);if(G!==0)return Y(G);let{sig:m,kdm:J,headCph:R}=K;if(!await V.checkSigEd25519(m,R,X))return Y(3);let F=W.deriveCipher(J,"decrypt"),d;try{d=await F.decrypt(R)}catch{return Y(20)}return b({kdm:J,headEnc:d})}var zZ="f",BZ="t",IZ="e";function oK(Z){return Z===zZ||Z===BZ||Z===IZ}function dX(Z){if(Z===!0||Z===BZ)return BZ;if(Z===IZ)return IZ;return zZ}function $K(Z){return dX(Z.apld)===zZ}function FV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function nZ(Z,X,W){if(Z.apld=X,X===IZ&&W!==void 0)Z.err=W;else delete Z.err}async function wZ(Z,X,W,V){let l=V?.body!==!1,K=dX(X.apld),G=X.body,m=G?.length??0,J;if(l&&G&&m>0)J=await W.blake3(G);let R={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:J},C={hash:Z,head:R,apld:K};if(l&&G!==void 0)C.body=G;if(K===IZ&&X.err!==void 0)C.err=X.err;return C}var bV=1048576,dV=1048576,Bl=64;function qK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function fK(Z,X,W,V,l){if(V.length<1)return 0;let[K,G]=await Z.push(V);if(G!==0)return G;if(!K)return 27;for(let J of K){if(J.status!==0){console.error("push err",J);continue}let R=l[J.idx];if(!R){console.error("no hash",J);continue}await X.uploads.deq(W,[R])}let m=await X.hosts.get(W);if(m){let J=m.lastSeq,R=J,C=[];for(let F of K)if(F.status===0)C.push(F.seq);C.sort((F,d)=>F-d);for(let F of C)if(F===J+1)J=F;if(J>R)await X.hosts.touch(W,J)}return 0}async function il(Z,X){if(X.length<1)return b([]);let W=new Map,V=[];for(let m of X)W.set(m.seq,m),V.push(m.seq);let[l,K]=await Z.pull(V);if(K!==0)return Y(K);if(!l)return Y(27);let G=[];for(let{seq:m,bodyCph:J}of l){let R=W.get(m);if(!R)continue;G.push({dl:R,bodyCph:J})}return b(G)}async function nK(Z,X,W,V){if(V.length<1)return b({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:R,bodyCph:C}of V){let{head:F,kdm:d,seq:k,host:c}=R,[I,T]=await wl(R,W);if(T!==0||!I){let P=m.get(c)??[];P.push(k),m.set(c,P);continue}let{headEnc:p,headEncHash:L}=I,S=X.deriveCipher(d,"decrypt"),[Q,M]=await qW(p,C,S,W,L);if(M!==0||!Q){let P=m.get(c)??[];P.push(k),m.set(c,P);continue}let g={head:F,body:Q.bod},O=Q.headHash;G.push({key:O,data:vl(g)}),l.push(g),K.push(O);let u=m.get(c)??[];u.push(k),m.set(c,u)}let J=await Z.messages.add(G);for(let[R,C]of m)await Z.downloads.deq(R,C);for(let R=0;R<J.length;R++){let C=J[R];if(C!==0&&C!==15)console.error("ERR storing",z[C],"for message",R)}return b({parts:l,hashes:K})}async function wl(Z,X){let W=Z.headEnc;if(!W){let l=new E,K=l.writeStruct(CZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return b({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return b({headEnc:W,headEncHash:V})}async function Dl(Z,X,W){let V=new Set;for(let G of X)V.add(H(G));if(V.size<1)return;let l=Array.from(await Z.downloads.list());if(l.length<1)return;let K=new Map;for(let G of l){let m;if(G.headEncHash)m=H(G.headEncHash);else{let[R,C]=await wl(G,W);if(C!==0||!R)continue;m=H(R.headEncHash)}if(!V.has(m))continue;let J=K.get(G.host)??[];J.push(G.seq),K.set(G.host,J)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function kV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let J=await Z.identity(),R=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let d=C.length,k=G??bX,c=m??Bl;if(K&&d>0)K({phase:"peek",host:V.label,done:0,total:d});let I=0,T=await CV(C,c,async(L)=>{let[S,Q]=await JW(L,J.publicKey,W,l),M;if(Q!==0||!S)M={ok:!1,seq:L.seq,stat:Q};else{let g=await l.blake3(S.headEnc);M={ok:!0,seq:L.seq,kdm:S.kdm,headEnc:S.headEnc,headEncHash:g}}if(I+=1,K&&mW(I,d,k))K({phase:"peek",host:V.label,done:I,total:d});return M}),p=new Set;for(let L of T){if(!L.ok){console.error("peek: decrypting item head",L.stat);continue}let S=H(L.headEncHash);if(await X.messages.has(L.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[L.headEncHash]),await X.downloads.deq(V.label,[L.seq]);continue}if(p.has(S)){await X.downloads.deq(V.label,[L.seq]);continue}let M=new j(L.headEnc),[g,O]=M.readStruct(CZ);if(O!==0){console.error("peek: reading item head",O);continue}p.add(S),R.push({kdm:L.kdm,head:g,seq:L.seq,host:V.label,headEnc:L.headEnc,headEncHash:L.headEncHash})}if(await X.downloads.enq(R),C.length>0){let L=Math.max(...C.map((S)=>S.seq));await X.hosts.recordStats(V.label,{lastSeq:L})}if(K)K({phase:"peek",host:V.label,done:d,total:d});return 0}async function Al({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??bV,G=await X.uploads.list(W.label),m=G.length,J=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let R=[],C=[],F=0,d=async()=>{if(R.length<1)return 0;let k=R.length,c=await fK(Z,X,W.label,R,C);if(R=[],C=[],F=0,c===0){if(J+=k,l)l({phase:"push",host:W.label,done:J,total:m})}return c};for(let k of G){let c=await X.messages.get(k);if(!c){J+=1;continue}let I={...c.head,bod:c.body},[T,p]=await Z.seal(I);if(p!==0)return p;if(!T)return 12;let L=qK(T);if(R.length>0&&F+L>K){let S=await d();if(S!==0)return S}if(R.push(T),C.push(k),F+=L,F>=K){let S=await d();if(S!==0)return S}}return d()}async function cV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let J=K??dV,R=await X.downloads.list(),C=Array.from(R).filter((T)=>T.host===V.label);if(C.length<1)return 15;let F=FX(C,(T)=>T.head),d=Ol(F,(T)=>T.head.len,J),k=F.length,c=0;if(G)G({phase:"pull",host:V.label,done:0,total:k});let I=il(Z,d[0]);for(let T=0;T<d.length;T++){let[p,L]=await I;if(L!==0||!p)return L;if(c+=d[T].length,G)G({phase:"pull",host:V.label,done:c,total:k});let S=d[T+1];if(S)I=il(Z,S);if(G)G({phase:"open",host:V.label,done:c,total:k});let Q=FX(p,(g)=>g.dl.head),[,M]=await nK(X,W,l,Q);if(M!==0)return M;if(m){if(G)G({phase:"exec",host:V.label,done:c,total:k});await m()}}return 0}function vl({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:zZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function ol(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let J=l.label,R=await X.identity(),C=new j(Z),[F,d]=C.readStructs(rX);if(d!==0){console.error("Failed decoding notif",z[d]);return}let k=!1,I=(await W.hosts.get(J))?.lastSeq,T=[],p=!1;for(let Q of F){let[M,g]=await JW({seq:Q.seq,headCph:Q.headCph},R.publicKey,V,K);if(g!==0){console.error("Failed decrypting notif",z[g]);continue}let O=await K.blake3(M.headEnc);if(await W.messages.has(O))continue;let u=new j(M.headEnc),[P,B]=u.readStruct(CZ);if(B!==0){console.error("Failed to parse head",z[B]);continue}if(!Q.bodyCph&&P.len>0)p=!0,await W.downloads.enq([{seq:Q.seq,host:J,kdm:M.kdm,head:P,headEnc:M.headEnc,headEncHash:O}]);else T.push({...M,head:P,bodyCph:Q.bodyCph,headEncHash:O});if(I===void 0||Q.seq!==I+1)console.log("out of seq",Q.seq,I),k=!0;else I=Q.seq}if(I!==void 0)await W.hosts.touch(l.label,I);let L=[];for(let Q of T){let M=V.deriveCipher(Q.kdm,"decrypt"),[g,O]=await qW(Q.headEnc,Q.bodyCph,M,K);if(O!==0){console.error("Failed to open body",z[O]);continue}L.push({key:Q.headEncHash,data:vl({head:Q.head,body:g.bod})})}let S=await W.messages.add(L);for(let Q=0;Q<S.length;Q++){let M=S[Q];if(M!==0&&M!==15)console.error("ERR storing",z[M],"for message",Q)}if(G&&L.length>0)G({phase:"open",host:l.label,done:L.length,total:L.length});if(k||p||L.length>0)m()}async function IV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:J,onProgress:R,peekProgressEvery:C,peekConcurrency:F}=Z,d=await l.identity(),[k,c]=await l.peek(0);if(c!==0)return Y(c);let I=k.length,T=C??bX,p=F??Bl;if(R&&I>0)R({phase:"peek",host:m.label,done:0,total:I});let L=0,S=await CV(k,p,async(h)=>{let[i,U]=await JW(h,d.publicKey,G,J),v;if(U!==0||!i)v={ok:!1,seq:h.seq,stat:U};else{let N=await J.blake3(i.headEnc);v={ok:!0,seq:h.seq,kdm:i.kdm,headEnc:i.headEnc,headEncHash:N}}if(L+=1,R&&mW(L,I,T))R({phase:"peek",host:m.label,done:L,total:I});return v}),Q=new Map;for(let h of S){if(!h.ok)continue;let i=H(h.headEncHash),U=Q.get(i);if(U)U.count+=1;else Q.set(i,{hash:h.headEncHash,count:1,sample:h})}let M=0,g=[];for(let h of Q.values()){if(h.count>1)M+=h.count-1;g.push(h.hash)}let O=k.length,u=Q.size,P=await mX(g,J),B=[],A=0;for(let h of Q.values()){if(await K.messages.has(h.hash)){await K.uploads.deq(m.label,[h.hash]);continue}if(A+=1,!W)continue;let U=h.sample,v=new j(U.headEnc),[N,_]=v.readStruct(CZ);if(_!==0){console.error("reconcile: reading msg header",_);continue}B.push({kdm:U.kdm,head:N,seq:U.seq,host:m.label,headEnc:U.headEnc,headEncHash:U.headEncHash})}if(B.length>0)await K.downloads.enq(B);let $=0;if(V){let h=await K.messages.listKeys(),i=new Set(Q.keys()),U=[];for(let v of h)if(!i.has(H(v)))$+=1,U.push(v);if(U.length>0)await K.uploads.enq(m.label,U)}else{let h=await K.messages.listKeys(),i=new Set(Q.keys());for(let U of h)if(!i.has(H(U)))$+=1}let y=k.length>0?Math.max(...k.map((h)=>h.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:y}),R)R({phase:"peek",host:m.label,done:I,total:I});return b({msgcheck:P,numBags:O,uniqueMsgs:u,numDupes:M,missingLocal:A,missingHost:$})}class kX{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new KW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=bX;lastProgress=fZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=bV,m=dV,J){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=J;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new cZ(()=>this.getClientState()),this.xferState=new cZ(()=>this.getXferState()),this.scheduledSync=new PX(GW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(R){console.error("Debounced sync failed:",R)}})}emitProgress=(Z)=>{this.lastProgress=Z,this.xferState.emit()};async setSeed(Z,X){await this.store.seed.save(Z,X),this.clientState.emit()}async getClientState(){let{store:Z,connections:X}=this,W=await Z.seed.load(),V=await Z.hosts.list(),l=!1;for(let K of X.values())if(K.isConnected()){l=!0;break}return{hasSeed:W!==void 0,hasHost:Array.from(V).length>0,connected:l}}async getXferState(){let{uploads:Z,downloads:X}=this.store,W=await Z.count();return{numDownloads:await X.count(),numUploads:W,progress:this.lastProgress}}apply=(Z,X)=>{return this.enqueueApplyJob(()=>this.doApply(Z,X))};async doApply(Z,X={enqueueUpload:!0,triggerUpload:!0}){let W=[],V=[];for(let{head:K,body:G}of Z){let m=new E;m.writeStruct(CZ,K);let J=m.result(),R=await this.crypto.blake3(J),C={eid:K.eid,body:G,apld:zZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(R),V.push({key:R,data:C})}await this.store.messages.add(V),await Dl(this.store,W,this.crypto);let l=await this.doApplyHashes(W);if(X.enqueueUpload){let K=[];for(let G=0;G<W.length;G++){let m=l[G];if(m===0||m===15)K.push(W[G])}if(K.length>0){let G=await this.store.hosts.list();for(let m of G)await this.store.uploads.enq(m.label,K);this.xferState.emit()}}if(X.triggerUpload)this.scheduleSync();return l}enqueueApplyJob(Z){let X=this.applyChain.then(Z,Z);return this.applyChain=X.then(()=>{return},()=>{return}),X}drainApplyQueue(){return this.enqueueApplyJob(()=>this.doDrainApplyQueue())}async doDrainApplyQueue(){let Z=await this.store.messages.list({apld:zZ});if(Z.length<1)return[];let X=FX(Z,(W)=>W.head);return this.applyStored(X)}applyHashes=(Z)=>{return this.enqueueApplyJob(()=>this.doApplyHashes(Z))};async doApplyHashes(Z){let X=[];for(let l of Z){let K=await this.store.messages.get(l);if(K)X.push(K)}let W=await this.applyStored(X),V=new Map;for(let l=0;l<X.length;l++)V.set(H(X[l].hash),W[l]??12);return Z.map((l)=>V.get(H(l))??13)}async applyStored(Z){if(Z.length<1)return[];let X=Z.map((K)=>({...K.head,bod:K.body})),W=await this.state.apply(X),V=[],l=[];for(let K=0;K<Z.length;K++){let G=W[K];if(G===0||G===15)V.push(Z[K].hash);else if(G!==void 0&&FV(G))l.push({key:Z[K].hash,err:G})}if(V.length>0)await this.store.messages.markApplied(V);if(l.length>0)await this.store.messages.markFailed(l);return W}async insertRaw(Z){let{clock:X,crypto:W}=this,[V,l]=await Nl({now:X.now(),bod:Z,crypto:W});if(l!==0)return Y(l);let G=(await this.apply([{head:V,body:Z}]))[0];if(G!==0&&G!==15)return Y(G??12);return b(V)}async makeUpdate(Z,X){let{clock:W,crypto:V}=this,l=W.now();if(Z.updatedAt.getTime()>l.getTime())return Y(4);let K=Z.ctr+1,[G,m]=await XW({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return b({head:G,body:X})}async updateWithSkew(Z,X,W){if(W===!1)return Y(4);let{clock:V,crypto:l}=this,K=V.now(),G=new j(Z.eid),[m,J]=G.readStruct(s);if(J!==0)return Y(J);let R=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:R+1,ctr:Z.ctr+1,len:0},d=(await this.apply([{head:C,body:void 0}]))[0];if(d!==0&&d!==15)return Y(d??12);if(X===void 0)return b(C);let[k,c]=GX({id:m.id,ts:K});if(c!==0)return Y(c);let[I,T]=await XW({now:K,eid:k,ctr:0,bod:X,crypto:l});if(T!==0)return Y(T);let L=(await this.apply([{head:I,body:X}]))[0];if(L!==0&&L!==15)return Y(L??12);return b(I)}async updateRaw(Z,X,W=this.forceSkewHandlingByDefault){if(Z.updatedAt.getTime()>this.clock.now().getTime())return this.updateWithSkew(Z,X,W);return this.enqueueApplyJob(async()=>{let[V,l]=await this.makeUpdate(Z,X);if(l!==0)return Y(l);let G=(await this.doApply([V]))[0];if(G!==0&&G!==15)return Y(G??12);return b(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=qZ({body:X,type:W,gid:V,pid:l,tags:K});return this.insertRaw(m)}async update(Z){let{prior:X,body:W,type:V,gid:l,pid:K,tags:G,force:m}=Z,R=qZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,R,m??this.forceSkewHandlingByDefault)}async delete(Z){let X=Z.force??!0;if("prior"in Z)return this.updateRaw(Z.prior,void 0,X);let[W,V]=await this.revFromArchive(Z.eid);if(V!==0)return Y(V);return this.updateRaw(W,void 0,X)}async revFromArchive(Z){let X=await this.store.messages.last(Z);if(X)return RV(X.head);let W=new j(Z),[V,l]=W.readStruct(s);if(l!==0)return Y(l);return b({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return GX({id:Z,ts:V});let l=await W.genRandomBytes(8);return GX({id:l,ts:V})}sync(){return this.syncRuns.run(()=>this.doSync())}async doSync(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;await this.drainApplyQueue();for(let[l,K]of Z){let G=await W.hosts.get(l);if(!G)continue;let m={conn:K,store:W,enclave:V,host:G,crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await kV(m);if(J!==0)return console.error(`Failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let R=await Al(m);if(R!==0)return console.error(`Failed to push: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let C=await cV(m,async()=>{await this.drainApplyQueue()});if(C!==0&&C!==15)return console.error(`Failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async rebuild(Z){if(this.scheduledSync.cancel(),await this.syncRuns.flush(),Z?.checkHost??!0){let W=await this.repull();if(W!==0)return W}return this.enqueueApplyJob(()=>this.replay())}async msgcheck(){let Z=await this.store.messages.listKeys();return mX(Z,this.crypto)}listMsgs(Z){return this.store.messages.list(Z)}countMsgs(Z){return this.store.messages.count(Z)}async reconcile(Z,X){this.scheduledSync.cancel(),await this.syncRuns.flush();let{connections:W,crypto:V,store:l}=this,K=await l.seed.load();if(!K)return Y(22);let G=await l.hosts.get(Z);if(!G)return Y(13);let m=W.get(Z);if(!m||!m.isConnected()){if(await this.connectToHost(G,!1,!1),G=await l.hosts.get(Z),!G)return Y(13);m=W.get(Z)}if(!m)return Y(12);let J={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[R,C]=await IV({...J,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!R)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),b(R);let F=await this.sync();if(F!==0)return Y(F);let d=await l.hosts.get(Z);if(!d)return Y(13);let[k,c]=await IV({...J,host:d},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),c!==0)return Y(c);if(!k)return Y(12);return b(k)}async repull(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;let l=Array.from(await W.hosts.list());if(l.length<1)return 0;for(let K of l){let G=Z.get(K.label);if(!G||!G.isConnected())await this.connectToHost(K,!1,!1)}for(let[K,G]of Z){let m=await W.hosts.get(K);if(!m)continue;let J={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},R=await kV(J);if(R!==0)return console.error(`rebuild: failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let C=await cV(J);if(C!==0&&C!==15)return console.error(`rebuild: failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async replay(){let Z=await this.state.clear();if(Z!==0)return Z;let X=await this.store.messages.list(),W=FX(X,(K)=>K.head),V=W.length;if(V<1)return this.emitProgress({phase:"idle"}),0;let l=0;while(l<W.length){let K=0,G=0,m=l;for(let R=l;R<W.length&&G<100&&K<102400;R++)K+=W[R].head.len,G++,m=R+1;let J=W.slice(l,m);await this.applyStored(J),this.emitProgress({phase:"exec",done:m,total:V}),l=m}return this.emitProgress({phase:"idle"}),0}async wipe(Z){let X=Z?.msgs!==!1,W=Z?.ents!==!1,V=Z?.meta!==!1,l=Z?.seed===!0;this.scheduledSync.cancel(),await this.disconnect(),await this.syncRuns.flush();let{store:K}=this;if(V)await K.hosts.wipe(),await K.uploads.wipe(),await K.downloads.wipe();if(X)await K.messages.wipe();if(l)await K.seed.wipe();if(W)await this.state.clear();this.lastProgress=fZ,this.clientState.emit(),this.xferState.emit()}import=async(Z,X)=>{let{crypto:W,store:V}=this,l=X?.onProgress,K=await V.seed.load();if(!K)return 22;console.time("import: decoding file...");let G=await Z.bytes(),[m,J]=await Ml(G,W,K);if(J!==0)return J;console.timeEnd("import: decoding file...");let R=0;while(R<m.length){let C=0,F=0,d=R;for(let I=R;I<m.length&&F<100&&C<102400;I++)C+=m[I].head.len,F++,d=I+1;let k=m.slice(R,d);console.time(`import: applying [${R}, ${d}]`);let c=await this.apply(k,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${R}, ${d}]`);for(let I=0;I<k.length;I++){let T=c[I];if(T!==0&&T!==15)console.warn(`failed to import msg ${R+I}: ${z[T]}`)}if(l)queueMicrotask(()=>l(d,m.length,0));this.emitProgress({phase:"import",done:d,total:m.length}),R=d}return this.scheduleSync(),this.emitProgress({phase:"idle"}),0};scheduleSync=()=>{if(this.onScheduleSync){this.onScheduleSync();return}this.scheduledSync.schedule()};async exportBytes(){let{crypto:Z,store:X}=this,W=await X.seed.load();if(!W)return Y(22);let V=await X.messages.list();return xl("export",0,V,Z,W)}async export(Z){let[X,W]=await this.exportBytes();if(W!==0)return W;if(!X)return 12;let V=new Blob([X.slice()]);return YW(V,Z),0}async link(Z,X=!0){if(await this.store.hosts.add(Z),this.clientState.emit(),X){let W=await this.store.hosts.get(Z.label);if(W)await this.connectToHost(W)}}async unlink(Z){await this.store.hosts.del(Z),this.clientState.emit()}async hosts(){return Array.from(await this.store.hosts.list())}connectToHost=async(Z,X=!0,W=!0)=>{let{clock:V,connections:l,crypto:K,store:G,transport:m}=this,J=l.get(Z.label);if(J){if(J.isConnected())return;try{J.closeListener()}catch{}l.delete(Z.label)}let R=await G.seed.load();if(!R)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new ZW(R,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let d={conn:C,store:G,enclave:R,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return ol(F,d,this.scheduleSync)},()=>this.clientState.emit(),()=>this.clientState.emit());if(l.set(Z.label,C),this.clientState.emit(),W)this.scheduleSync()};async connect(Z=!0,X=!0){let{connectToHost:W,scheduleSync:V,store:l}=this;if(!await l.seed.load())return;await this.drainApplyQueue();let G=await l.hosts.list();for(let m of G)await W(m,Z,!1);if(X)V()}disconnect=async()=>{for(let Z of this.connections.values())try{Z.closeListener()}catch{}this.connections.clear(),this.clientState.emit()}}var _Z=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function RW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function TV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!TV(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function QV(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function $l(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function LV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var xZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var _K=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!_K)throw Error("Non little-endian hardware is not supported");function aK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function CW(Z){if(typeof Z==="string")Z=aK(Z);else if(TV(Z))Z=FW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function ql(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function fl(Z,X){if(Z.length!==X.length)return!1;let W=0;for(let V=0;V<Z.length;V++)W|=Z[V]^X[V];return W===0}var nl=(Z,X)=>{function W(V,...l){if(a(V),Z.nonceLength!==void 0){let C=l[0];if(!C)throw Error("nonce / iv required");if(Z.varSizeNonce)a(C);else a(C,Z.nonceLength)}let K=Z.tagLength;if(K&&l[1]!==void 0)a(l[1]);let G=X(V,...l),m=(C,F)=>{if(F!==void 0){if(C!==2)throw Error("cipher output not supported");a(F)}},J=!1;return{encrypt(C,F){if(J)throw Error("cannot encrypt() twice with same key + nonce");return J=!0,a(C),m(G.encrypt.length,F),G.encrypt(C,F)},decrypt(C,F){if(a(C),K&&C.length<K)throw Error("invalid ciphertext length: smaller than tagLength="+K);return m(G.decrypt.length,F),G.decrypt(C,F)}}}return Object.assign(W,Z),W};function pV(Z,X,W=!0){if(X===void 0)return new Uint8Array(Z);if(X.length!==Z)throw Error("invalid output length, expected "+Z+", got: "+X.length);if(W&&!sK(X))throw Error("invalid output, must be aligned");return X}function sK(Z){return Z.byteOffset%4===0}function FW(Z){return Uint8Array.from(Z)}function TZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function UX(Z=32){if(_Z&&typeof _Z.getRandomValues==="function")return _Z.getRandomValues(new Uint8Array(Z));if(_Z&&typeof _Z.randomBytes==="function")return _Z.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var al=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),rK=al("expand 16-byte k"),tK=al("expand 32-byte k"),eK=xZ(rK),ZG=xZ(tK);function x(Z,X){return Z<<X|Z>>>32-X}function yV(Z){return Z.byteOffset%4===0}var bW=64,XG=16,sl=4294967295,_l=new Uint32Array;function WG(Z,X,W,V,l,K,G,m){let J=l.length,R=new Uint8Array(bW),C=xZ(R),F=yV(l)&&yV(K),d=F?xZ(l):_l,k=F?xZ(K):_l;for(let c=0;c<J;G++){if(Z(X,W,V,C,G,m),G>=sl)throw Error("arx: counter overflow");let I=Math.min(bW,J-c);if(F&&I===bW){let T=c/4;if(c%4!==0)throw Error("arx: invalid block position");for(let p=0,L;p<XG;p++)L=T+p,k[L]=d[L]^C[p];c+=bW;continue}for(let T=0,p;T<I;T++)p=c+T,K[p]=l[p]^R[T];c+=I}}function rl(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=ql({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return RW(l),RW(G),LV(K),LV(W),(m,J,R,C,F=0)=>{a(m),a(J),a(R);let d=R.length;if(C===void 0)C=new Uint8Array(d);if(a(C),RW(F),F<0||F>=sl)throw Error("arx: counter overflow");if(C.length<d)throw Error(`arx: output (${C.length}) is shorter than data (${d})`);let k=[],c=m.length,I,T;if(c===32)k.push(I=FW(m)),T=ZG;else if(c===16&&W)I=new Uint8Array(32),I.set(m),I.set(m,16),T=eK,k.push(I);else throw Error(`arx: invalid 32-byte key, got length=${c}`);if(!yV(J))k.push(J=FW(J));let p=xZ(I);if(V){if(J.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(T,p,xZ(J.subarray(0,16)),p),J=J.subarray(16)}let L=16-l;if(L!==J.length)throw Error(`arx: nonce must be ${L} or 16 bytes`);if(L!==12){let Q=new Uint8Array(12);Q.set(J,K?0:12-J.length),J=Q,k.push(J)}let S=xZ(J);return WG(Z,T,p,S,R,C,F,G),TZ(...k),C}}var t=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class tl{constructor(Z){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,Z=CW(Z),a(Z,32);let X=t(Z,0),W=t(Z,2),V=t(Z,4),l=t(Z,6),K=t(Z,8),G=t(Z,10),m=t(Z,12),J=t(Z,14);this.r[0]=X&8191,this.r[1]=(X>>>13|W<<3)&8191,this.r[2]=(W>>>10|V<<6)&7939,this.r[3]=(V>>>7|l<<9)&8191,this.r[4]=(l>>>4|K<<12)&255,this.r[5]=K>>>1&8190,this.r[6]=(K>>>14|G<<2)&8191,this.r[7]=(G>>>11|m<<5)&8065,this.r[8]=(m>>>8|J<<8)&8191,this.r[9]=J>>>5&127;for(let R=0;R<8;R++)this.pad[R]=t(Z,16+2*R)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],J=K[2],R=K[3],C=K[4],F=K[5],d=K[6],k=K[7],c=K[8],I=K[9],T=t(Z,X+0),p=t(Z,X+2),L=t(Z,X+4),S=t(Z,X+6),Q=t(Z,X+8),M=t(Z,X+10),g=t(Z,X+12),O=t(Z,X+14),u=l[0]+(T&8191),P=l[1]+((T>>>13|p<<3)&8191),B=l[2]+((p>>>10|L<<6)&8191),A=l[3]+((L>>>7|S<<9)&8191),$=l[4]+((S>>>4|Q<<12)&8191),y=l[5]+(Q>>>1&8191),h=l[6]+((Q>>>14|M<<2)&8191),i=l[7]+((M>>>11|g<<5)&8191),U=l[8]+((g>>>8|O<<8)&8191),v=l[9]+(O>>>5|V),N=0,_=N+u*G+P*(5*I)+B*(5*c)+A*(5*k)+$*(5*d);N=_>>>13,_&=8191,_+=y*(5*F)+h*(5*C)+i*(5*R)+U*(5*J)+v*(5*m),N+=_>>>13,_&=8191;let XZ=N+u*m+P*G+B*(5*I)+A*(5*c)+$*(5*k);N=XZ>>>13,XZ&=8191,XZ+=y*(5*d)+h*(5*F)+i*(5*C)+U*(5*R)+v*(5*J),N+=XZ>>>13,XZ&=8191;let mZ=N+u*J+P*m+B*G+A*(5*I)+$*(5*c);N=mZ>>>13,mZ&=8191,mZ+=y*(5*k)+h*(5*d)+i*(5*F)+U*(5*C)+v*(5*R),N+=mZ>>>13,mZ&=8191;let f=N+u*R+P*J+B*m+A*G+$*(5*I);N=f>>>13,f&=8191,f+=y*(5*c)+h*(5*k)+i*(5*d)+U*(5*F)+v*(5*C),N+=f>>>13,f&=8191;let yZ=N+u*C+P*R+B*J+A*m+$*G;N=yZ>>>13,yZ&=8191,yZ+=y*(5*I)+h*(5*c)+i*(5*k)+U*(5*d)+v*(5*F),N+=yZ>>>13,yZ&=8191;let tZ=N+u*F+P*C+B*R+A*J+$*m;N=tZ>>>13,tZ&=8191,tZ+=y*G+h*(5*I)+i*(5*c)+U*(5*k)+v*(5*d),N+=tZ>>>13,tZ&=8191;let eZ=N+u*d+P*F+B*C+A*R+$*J;N=eZ>>>13,eZ&=8191,eZ+=y*m+h*G+i*(5*I)+U*(5*c)+v*(5*k),N+=eZ>>>13,eZ&=8191;let ZX=N+u*k+P*d+B*F+A*C+$*R;N=ZX>>>13,ZX&=8191,ZX+=y*J+h*m+i*G+U*(5*I)+v*(5*c),N+=ZX>>>13,ZX&=8191;let XX=N+u*c+P*k+B*d+A*F+$*C;N=XX>>>13,XX&=8191,XX+=y*R+h*J+i*m+U*G+v*(5*I),N+=XX>>>13,XX&=8191;let WX=N+u*I+P*c+B*k+A*d+$*F;N=WX>>>13,WX&=8191,WX+=y*C+h*R+i*J+U*m+v*G,N+=WX>>>13,WX&=8191,N=(N<<2)+N|0,N=N+_|0,_=N&8191,N=N>>>13,XZ+=N,l[0]=_,l[1]=XZ,l[2]=mZ,l[3]=f,l[4]=yZ,l[5]=tZ,l[6]=eZ,l[7]=ZX,l[8]=XX,l[9]=WX}finalize(){let{h:Z,pad:X}=this,W=new Uint16Array(10),V=Z[1]>>>13;Z[1]&=8191;for(let G=2;G<10;G++)Z[G]+=V,V=Z[G]>>>13,Z[G]&=8191;Z[0]+=V*5,V=Z[0]>>>13,Z[0]&=8191,Z[1]+=V,V=Z[1]>>>13,Z[1]&=8191,Z[2]+=V,W[0]=Z[0]+5,V=W[0]>>>13,W[0]&=8191;for(let G=1;G<10;G++)W[G]=Z[G]+V,V=W[G]>>>13,W[G]&=8191;W[9]-=8192;let l=(V^1)-1;for(let G=0;G<10;G++)W[G]&=l;l=~l;for(let G=0;G<10;G++)Z[G]=Z[G]&l|W[G];Z[0]=(Z[0]|Z[1]<<13)&65535,Z[1]=(Z[1]>>>3|Z[2]<<10)&65535,Z[2]=(Z[2]>>>6|Z[3]<<7)&65535,Z[3]=(Z[3]>>>9|Z[4]<<4)&65535,Z[4]=(Z[4]>>>12|Z[5]<<1|Z[6]<<14)&65535,Z[5]=(Z[6]>>>2|Z[7]<<11)&65535,Z[6]=(Z[7]>>>5|Z[8]<<8)&65535,Z[7]=(Z[8]>>>8|Z[9]<<5)&65535;let K=Z[0]+X[0];Z[0]=K&65535;for(let G=1;G<8;G++)K=(Z[G]+X[G]|0)+(K>>>16)|0,Z[G]=K&65535;TZ(W)}update(Z){QV(this);let{buffer:X,blockLen:W}=this;Z=CW(Z);let V=Z.length;for(let l=0;l<V;){let K=Math.min(W-this.pos,V-l);if(K===W){for(;W<=V-l;l+=W)this.process(Z,l);continue}if(X.set(Z.subarray(l,l+K),this.pos),this.pos+=K,l+=K,this.pos===W)this.process(X,0,!1),this.pos=0}return this}destroy(){TZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){QV(this),$l(Z,this),this.finished=!0;let{buffer:X,h:W}=this,{pos:V}=this;if(V){X[V++]=1;for(;V<16;V++)X[V]=0;this.process(X,0,!0)}this.finalize();let l=0;for(let K=0;K<8;K++)Z[l++]=W[K]>>>0,Z[l++]=W[K]>>>8;return Z}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}}function VG(Z){let X=(V,l)=>Z(l).update(CW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var SV=VG((Z)=>new tl(Z));function lG(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],J=X[1],R=X[2],C=X[3],F=Z[1],d=W[0],k=W[1],c=l,I=0,T=Z[2],p=X[4],L=X[5],S=X[6],Q=X[7],M=Z[3],g=G,O=m,u=J,P=R,B=C,A=F,$=d,y=k,h=c,i=I,U=T,v=p,N=L,_=S,XZ=Q,mZ=M;for(let yZ=0;yZ<K;yZ+=2)B^=x(g+N|0,7),h^=x(B+g|0,9),N^=x(h+B|0,13),g^=x(N+h|0,18),i^=x(A+O|0,7),_^=x(i+A|0,9),O^=x(_+i|0,13),A^=x(O+_|0,18),XZ^=x(U+$|0,7),u^=x(XZ+U|0,9),$^=x(u+XZ|0,13),U^=x($+u|0,18),P^=x(mZ+v|0,7),y^=x(P+mZ|0,9),v^=x(y+P|0,13),mZ^=x(v+y|0,18),O^=x(g+P|0,7),u^=x(O+g|0,9),P^=x(u+O|0,13),g^=x(P+u|0,18),$^=x(A+B|0,7),y^=x($+A|0,9),B^=x(y+$|0,13),A^=x(B+y|0,18),v^=x(U+i|0,7),h^=x(v+U|0,9),i^=x(h+v|0,13),U^=x(i+h|0,18),N^=x(mZ+XZ|0,7),_^=x(N+mZ|0,9),XZ^=x(_+N|0,13),mZ^=x(XZ+_|0,18);let f=0;V[f++]=G+g|0,V[f++]=m+O|0,V[f++]=J+u|0,V[f++]=R+P|0,V[f++]=C+B|0,V[f++]=F+A|0,V[f++]=d+$|0,V[f++]=k+y|0,V[f++]=c+h|0,V[f++]=I+i|0,V[f++]=T+U|0,V[f++]=p+v|0,V[f++]=L+N|0,V[f++]=S+_|0,V[f++]=Q+XZ|0,V[f++]=M+mZ|0}function KG(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],J=X[3],R=Z[1],C=W[0],F=W[1],d=W[2],k=W[3],c=Z[2],I=X[4],T=X[5],p=X[6],L=X[7],S=Z[3];for(let M=0;M<20;M+=2)J^=x(l+T|0,7),d^=x(J+l|0,9),T^=x(d+J|0,13),l^=x(T+d|0,18),k^=x(R+K|0,7),p^=x(k+R|0,9),K^=x(p+k|0,13),R^=x(K+p|0,18),L^=x(c+C|0,7),G^=x(L+c|0,9),C^=x(G+L|0,13),c^=x(C+G|0,18),m^=x(S+I|0,7),F^=x(m+S|0,9),I^=x(F+m|0,13),S^=x(I+F|0,18),K^=x(l+m|0,7),G^=x(K+l|0,9),m^=x(G+K|0,13),l^=x(m+G|0,18),C^=x(R+J|0,7),F^=x(C+R|0,9),J^=x(F+C|0,13),R^=x(J+F|0,18),I^=x(c+k|0,7),d^=x(I+c|0,9),k^=x(d+I|0,13),c^=x(k+d|0,18),T^=x(S+L|0,7),p^=x(T+S|0,9),L^=x(p+T|0,13),S^=x(L+p|0,18);let Q=0;V[Q++]=l,V[Q++]=R,V[Q++]=c,V[Q++]=S,V[Q++]=C,V[Q++]=F,V[Q++]=d,V[Q++]=k}var zV=rl(lG,{counterRight:!0,extendNonceFn:KG}),xV=nl({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=pV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),TZ(l),zV(Z,X,V,V);let G=SV(K,l);return V.set(G,16),TZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=pV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),TZ(l);let m=zV(Z,X,l,l),J=SV(G,m);if(!fl(K,J))throw Error("invalid tag");return zV(Z,X,V.subarray(16),V.subarray(16)),TZ(l,K,J),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function GG(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function jX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function aZ(Z,...X){if(!GG(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function uX(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function dW(Z,X){aZ(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function el(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function cX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function IX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function EX(Z,X){return Z<<32-X|Z>>>X}var Z0=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function X0(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var W0=Z0?(Z)=>Z:(Z)=>X0(Z);function mG(Z){for(let X=0;X<Z.length;X++)Z[X]=X0(Z[X]);return Z}var lZ=Z0?(Z)=>Z:mG;function YG(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function TX(Z){if(typeof Z==="string")Z=YG(Z);return aZ(Z),Z}class MV{}function V0(Z){let X=(V,l)=>Z(l).update(TX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var l0=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var kW=BigInt(4294967295),K0=BigInt(32);function NV(Z,X=!1){if(X)return{h:Number(Z&kW),l:Number(Z>>K0&kW)};return{h:Number(Z>>K0&kW)|0,l:Number(Z&kW)|0}}function MZ(Z,X,W,V,l){return Z=Z+X+l|0,V=EX(V^Z,16),W=W+V|0,X=EX(X^W,12),{a:Z,b:X,c:W,d:V}}function NZ(Z,X,W,V,l){return Z=Z+X+l|0,V=EX(V^Z,8),W=W+V|0,X=EX(X^W,7),{a:Z,b:X,c:W,d:V}}class HV extends MV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,jX(Z),jX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=cX(this.buffer)}update(Z){uX(this),Z=TX(Z),aZ(Z);let{blockLen:X,buffer:W,buffer32:V}=this,l=Z.length,K=Z.byteOffset,G=Z.buffer;for(let m=0;m<l;){if(this.pos===X)lZ(V),this.compress(V,0,!1),lZ(V),this.pos=0;let J=Math.min(X-this.pos,l-m),R=K+m;if(J===X&&!(R%4)&&m+J<l){let C=new Uint32Array(G,R,Math.floor((l-m)/4));lZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);lZ(C);continue}W.set(Z.subarray(m,m+J),this.pos),this.pos+=J,this.length+=J,m+=J}return this}digestInto(Z){uX(this),dW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,IX(this.buffer.subarray(X)),lZ(W),this.compress(W,0,!0),lZ(W);let V=cX(Z);this.get().forEach((l,K)=>V[K]=W0(l))}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}_cloneInto(Z){let{buffer:X,length:W,finished:V,destroyed:l,outputLen:K,pos:G}=this;return Z||(Z=new this.constructor({dkLen:K})),Z.set(...this.get()),Z.buffer.set(X),Z.destroyed=l,Z.finished=V,Z.length=W,Z.pos=G,Z.outputLen=K,Z}clone(){return this._cloneInto()}}function gV(Z,X,W,V,l,K,G,m,J,R,C,F,d,k,c,I,T,p,L,S){let Q=0;for(let M=0;M<V;M++)({a:l,b:J,c:d,d:T}=MZ(l,J,d,T,W[X+Z[Q++]])),{a:l,b:J,c:d,d:T}=NZ(l,J,d,T,W[X+Z[Q++]]),{a:K,b:R,c:k,d:p}=MZ(K,R,k,p,W[X+Z[Q++]]),{a:K,b:R,c:k,d:p}=NZ(K,R,k,p,W[X+Z[Q++]]),{a:G,b:C,c,d:L}=MZ(G,C,c,L,W[X+Z[Q++]]),{a:G,b:C,c,d:L}=NZ(G,C,c,L,W[X+Z[Q++]]),{a:m,b:F,c:I,d:S}=MZ(m,F,I,S,W[X+Z[Q++]]),{a:m,b:F,c:I,d:S}=NZ(m,F,I,S,W[X+Z[Q++]]),{a:l,b:R,c,d:S}=MZ(l,R,c,S,W[X+Z[Q++]]),{a:l,b:R,c,d:S}=NZ(l,R,c,S,W[X+Z[Q++]]),{a:K,b:C,c:I,d:T}=MZ(K,C,I,T,W[X+Z[Q++]]),{a:K,b:C,c:I,d:T}=NZ(K,C,I,T,W[X+Z[Q++]]),{a:G,b:F,c:d,d:p}=MZ(G,F,d,p,W[X+Z[Q++]]),{a:G,b:F,c:d,d:p}=NZ(G,F,d,p,W[X+Z[Q++]]),{a:m,b:J,c:k,d:L}=MZ(m,J,k,L,W[X+Z[Q++]]),{a:m,b:J,c:k,d:L}=NZ(m,J,k,L,W[X+Z[Q++]]);return{v0:l,v1:K,v2:G,v3:m,v4:J,v5:R,v6:C,v7:F,v8:d,v9:k,v10:c,v11:I,v12:T,v13:p,v14:L,v15:S}}var QZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},HZ=l0.slice(),G0=(()=>{let Z=Array.from({length:16},(V,l)=>l),X=(V)=>[2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8].map((l)=>V[l]),W=[];for(let V=0,l=Z;V<7;V++,l=X(l))W.push(...l);return Uint8Array.from(W)})();class hV extends HV{constructor(Z={},X=0){super(64,Z.dkLen===void 0?32:Z.dkLen);this.chunkPos=0,this.chunksDone=0,this.flags=0,this.stack=[],this.posOut=0,this.bufferOut32=new Uint32Array(16),this.chunkOut=0,this.enableXOF=!0;let{key:W,context:V}=Z,l=V!==void 0;if(W!==void 0){if(l)throw Error('Only "key" or "context" can be specified at same time');let K=TX(W).slice();aZ(K,32),this.IV=cX(K),lZ(this.IV),this.flags=X|QZ.KEYED_HASH}else if(l){let K=TX(V),G=new hV({dkLen:32},QZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=cX(G),lZ(this.IV),this.flags=X|QZ.DERIVE_KEY_MATERIAL}else this.IV=HZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=el(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=NV(BigInt(Z),!0),{v0:J,v1:R,v2:C,v3:F,v4:d,v5:k,v6:c,v7:I,v8:T,v9:p,v10:L,v11:S,v12:Q,v13:M,v14:g,v15:O}=gV(G0,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],HZ[0],HZ[1],HZ[2],HZ[3],G,m,K,X);l[0]=J^T,l[1]=R^p,l[2]=C^L,l[3]=F^S,l[4]=d^Q,l[5]=k^M,l[6]=c^g,l[7]=I^O}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=QZ.CHUNK_START;if(this.chunkPos===15||W)V|=QZ.CHUNK_END;if(!W)this.pos=this.blockLen;if(this.b2Compress(this.chunksDone,V,Z,X),this.chunkPos+=1,this.chunkPos===16||W){let l=this.state;this.state=this.IV.slice();for(let K,G=this.chunksDone+1;W||!(G&1);G>>=1){if(!(K=this.stack.pop()))break;this.buffer32.set(K,0),this.buffer32.set(l,8),this.pos=this.blockLen,this.b2Compress(0,this.flags|QZ.PARENT,this.buffer32,0),l=this.state,this.state=this.IV.slice()}this.chunksDone++,this.chunkPos=0,this.stack.push(l)}this.pos=0}_cloneInto(Z){Z=super._cloneInto(Z);let{IV:X,flags:W,state:V,chunkPos:l,posOut:K,chunkOut:G,stack:m,chunksDone:J}=this;return Z.state.set(V.slice()),Z.stack=m.map((R)=>Uint32Array.from(R)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=J,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,IX(this.state,this.buffer32,this.IV,this.bufferOut32),IX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=NV(BigInt(this.chunkOut++));lZ(V);let{v0:m,v1:J,v2:R,v3:C,v4:F,v5:d,v6:k,v7:c,v8:I,v9:T,v10:p,v11:L,v12:S,v13:Q,v14:M,v15:g}=gV(G0,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],HZ[0],HZ[1],HZ[2],HZ[3],G,K,X,W);l[0]=m^I,l[1]=J^T,l[2]=R^p,l[3]=C^L,l[4]=F^S,l[5]=d^Q,l[6]=k^M,l[7]=c^g,l[8]=Z[0]^I,l[9]=Z[1]^T,l[10]=Z[2]^p,l[11]=Z[3]^L,l[12]=Z[4]^S,l[13]=Z[5]^Q,l[14]=Z[6]^M,l[15]=Z[7]^g,lZ(V),lZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,IX(this.buffer.subarray(this.pos));let Z=this.flags|QZ.ROOT;if(this.stack.length)Z|=QZ.PARENT,lZ(this.buffer32),this.compress(this.buffer32,0,!0),lZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?QZ.CHUNK_START:0)|QZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){uX(this,!1),aZ(Z),this.finish();let{blockLen:X,bufferOut:W}=this;for(let V=0,l=Z.length;V<l;){if(this.posOut>=X)this.b2CompressOut();let K=Math.min(X-this.posOut,l-V);Z.set(W.subarray(this.posOut,this.posOut+K),V),this.posOut+=K,V+=K}return Z}xofInto(Z){if(!this.enableXOF)throw Error("XOF is not possible after digest call");return this.writeInto(Z)}xof(Z){return jX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(dW(Z,this),this.finished)throw Error("digest() was already called");return this.enableXOF=!1,this.writeInto(Z),this.destroy(),Z}digest(){return this.digestInto(new Uint8Array(this.outputLen))}}var m0=V0((Z)=>new hV(Z));var JG=32,gF=Symbol("X25519Sk");function Y0(Z){if(Z.byteLength!==JG)return Y(10);return b(Z)}var D=(1n<<255n)-19n,RG=121665n,J0=new Uint8Array(32);J0[0]=9;function R0(Z){let X=0n;for(let W=Z.length-1;W>=0;W--)X=X<<8n|BigInt(Z[W]);return X}function CG(Z){let X=new Uint8Array(32),W=(Z%D+D)%D;for(let V=0;V<32;V++)X[V]=Number(W&0xffn),W>>=8n;return X}function FG(Z){let X=Z.slice();return X[31]&=127,R0(X)}function bG(Z){let X=Z.slice();return X[0]&=248,X[31]&=127,X[31]|=64,X}function cW(Z,X,W){let V=-Z,l=(X^W)&V;return[X^l,W^l]}function dG(Z){let X=D-2n,W=(Z%D+D)%D,V=1n;while(X>0n){if(X&1n)V=V*W%D;W=W*W%D,X>>=1n}return V}function kG(Z,X){let W=bG(Z),V=FG(X),l=1n,K=0n,G=V,m=1n,J=0n,R=R0(W);for(let C=254;C>=0;C--){let F=R>>BigInt(C)&1n;J^=F,[l,G]=cW(J,l,G),[K,m]=cW(J,K,m),J=F;let d=(l+K)%D,k=d*d%D,c=(l-K+D)%D,I=c*c%D,T=(k-I+D)%D,p=(G+m)%D,S=(G-m+D)%D*d%D,Q=p*c%D,M=(S+Q)%D,g=(S-Q+D)%D;G=M*M%D,m=V*g*g%D,l=k*I%D,K=T*(k+RG*T)%D}return[l,G]=cW(J,l,G),[K,m]=cW(J,K,m),W.fill(0),CG(l*dG(K)%D)}function C0(Z){return kG(Z,J0)}var PV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function F0(Z){let X=new Uint8Array(PV.length+32);return X.set(PV),X.set(Z.subarray(0,32),PV.length),X}var UV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);function b0(Z){let X=new Uint8Array(UV.length+32);return X.set(UV),X.set(Z.subarray(0,32),UV.length),X}function d0(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function gZ(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class sZ{verifyKeys=new Map;async genRandomBytes(Z){return UX(Z)}async gen256BitSecureRandomSeed(){return UX(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=UX(24),l=xV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return xV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=F0(X),V=gZ(W),l;try{let R=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",R)}finally{W.fill(0),new Uint8Array(V).fill(0)}if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=l.x;l.d=void 0;let G=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:K},{name:"Ed25519"},!0,["verify"]),m=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",G));this.verifyKeys.set(YZ(m),G);let J=new Uint8Array(64);return J.set(X,0),J.set(m,32),{keyType:"ed25519",privateKey:J,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=F0(X),V=gZ(W);try{return await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!1,["sign"])}finally{W.fill(0),new Uint8Array(V).fill(0)}}async importVerifyKey(Z){let X=YZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",gZ(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=d0(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,gZ(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=d0(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,gZ(Z),gZ(V))}catch{return!1}}async blake3(Z){return m0(Z)}async genX25519(){let Z=await UX(32);Z[0]&=248,Z[31]&=127,Z[31]|=64;let[X,W]=Y0(Z);if(W!==0||X===void 0)throw Z.fill(0),Error("X25519 scalar brand failed");let V=C0(X),l=b0(X),K=gZ(l);try{let G=await globalThis.crypto.subtle.importKey("pkcs8",K,{name:"X25519"},!0,["deriveBits"]),m=await globalThis.crypto.subtle.exportKey("jwk",G);if(typeof m.x!=="string")throw Error("X25519 JWK missing x");let J=$W(m.x);if(m.d=void 0,!w(J,V))throw Error("X25519 WebCrypto pub != RFC 7748");return{priv:X,pub:V}}catch(G){throw X.fill(0),G}finally{l.fill(0),new Uint8Array(K).fill(0)}}async x25519Shared(Z,X){let W=b0(Z),V=gZ(W);try{let l=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"X25519"},!1,["deriveBits"]),K=await globalThis.crypto.subtle.importKey("raw",gZ(X),{name:"X25519"},!1,[]),G=await globalThis.crypto.subtle.deriveBits({name:"X25519",public:K},l,256);return new Uint8Array(G)}finally{W.fill(0),new Uint8Array(V).fill(0)}}}var cG=new sZ,QX=cG;import{useEffect as iW,useState as eV}from"react";class jV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(FZ,"readwrite"),V=W.objectStore(FZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=`${G.host}:${G.seq}`;V.put(G,m)}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(FZ,"readwrite"),l=V.objectStore(FZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let J=`${Z}:${m}`;l.delete(J)}})}async list(){let X=this.db.transaction(FZ,"readonly").objectStore(FZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async count(){let X=this.db.transaction(FZ,"readonly").objectStore(FZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(FZ,"readwrite"),X=Z.objectStore(FZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function k0(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function IG(Z,X){let W={...Z};if(X.setLastSeq!==void 0)W.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0){let V=W.lastSeq||0;if(X.lastSeq>V)W.lastSeq=X.lastSeq}return delete W.numBags,delete W.numDupes,W}class uV{db;constructor(Z){this.db=Z}async add(Z){let X=await this.get(Z.label),W=X!==void 0&&X.handle.href===Z.handle.href&&(X.idx??0)===(Z.idx??0);return this.put({...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0})}async put(Z){let X={...Z,handle:Z.handle.toString(),lastSeq:Z.lastSeq??0},W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X)})}async touch(Z,X){return this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);let G=V.get(Z);G.onsuccess=()=>{let m=G.result;if(!m)return;V.put(IG(m,X))}})}async get(Z){let W=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(k0(G))},K.onerror=()=>l(K.error)})}async set(Z,X){let W=await this.get(Z);if(!W)return 13;try{return await this.put({...W,...X}),0}catch{return 18}}async del(Z){let X=this.db.transaction(KZ,"readwrite"),W=X.objectStore(KZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(k0))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(KZ,"readwrite"),X=Z.objectStore(KZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class EV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction(q,"readwrite"),W=X.objectStore(q);return new Promise((V)=>{if(Z.length===0){V([]);return}let l=Array(Z.length).fill(0);X.oncomplete=()=>V(l),X.onerror=()=>{for(let K=0;K<l.length;K++)l[K]=18;V(l)};for(let K=0;K<Z.length;K++){let{key:G,data:m}=Z[K],J=H(G),R=W.put(m,J);R.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(q,"readwrite"),V=W.objectStore(q);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=H(G);V.delete(m)}})}async get(Z){let W=this.db.transaction(q,"readonly").objectStore(q);return new Promise((V,l)=>{let K=H(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await wZ(Z,m,this.crypto));else V(void 0)},G.onerror=()=>l(G.error)})}async has(Z){return await this.get(Z)!==void 0}async list(Z){let X=Z?.apld,W=Z?.body!==!1,l=this.db.transaction(q,"readonly").objectStore(q);return new Promise((K,G)=>{let m=[],J=X===void 0?l.openCursor():l.index(OX).openCursor(IDBKeyRange.only(X));J.onsuccess=(R)=>{let C=R.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,d=C.value;m.push({hash:e(F),data:d}),C.continue()}else Promise.all(m.map(({hash:F,data:d})=>wZ(F,d,this.crypto,{body:W}))).then(K).catch(G)},J.onerror=()=>G(J.error)})}async count(Z){let W=this.db.transaction(q,"readonly").objectStore(q);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(OX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction(q,"readonly").objectStore(q);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(e(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction(q,"readonly").objectStore(q);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let J=m.target.result;if(J){let{key:R,value:C}=J;if(w(Z,C.eid)){if(!K||(C.ctr??0)>(K.data.ctr??0)||(C.ctr??0)===(K.data.ctr??0)&&(C.off??0)>(K.data.off??0))K={key:R,data:C}}J.continue()}else if(K){let R=e(K.key);V(await wZ(R,K.data,this.crypto))}else V(void 0)},G.onerror=()=>l(G.error)})}async markApplied(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(q,"readwrite"),V=W.objectStore(q);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=H(G),J=V.get(m);J.onsuccess=()=>{let R=J.result;if(!R)return;nZ(R,BZ),V.put(R,m)},J.onerror=(R)=>{R.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(q,"readwrite"),V=W.objectStore(q);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let J=H(G),R=V.get(J);R.onsuccess=()=>{let C=R.result;if(!C)return;nZ(C,IZ,m),V.put(C,J)},R.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction(q,"readwrite"),X=Z.objectStore(q);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var rZ={encode(Z,X){let W=Z.writeVarString(X.handle);if(W!==0)return W;let V=Z.writeVarString(X.label);if(V!==0)return V;return Z.writeVarInt(X.idx??0)},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarString();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);return b({handle:X,label:V,idx:K})}};var IW=1,OV={encode(Z,X){if(X.v!==IW)return 10;let[,W]=VZ(X.masterSeed);if(W!==0)return W;let V=Z.writeVarInt(X.v);if(V!==0)return V;Z.writeBytes(X.masterSeed);let l=Z.writeVarInt(X.hosts.length);if(l!==0)return l;for(let K of X.hosts){let G=Z.writeStruct(rZ,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==IW)return Y(14);let[V,l]=Z.readBytes(kZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=VZ(V);if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,J]=Z.readVarInt();if(J!==0)return Y(J);if(m===void 0||m<0)return Y(10);let R=[];for(let C=0;C<m;C++){let[F,d]=Z.readStruct(rZ);if(d!==0)return Y(d);if(F===void 0)return Y(14);R.push(F)}return b({v:IW,masterSeed:K,hosts:R})}};function c0(Z,X){let[W,V]=VZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=VZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return b({v:IW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var TW={encode(Z,X){let[,W]=VZ(X.masterSeed);if(W!==0)return W;Z.writeBytes(X.masterSeed);let V=Z.writeVarInt(X.hosts.length);if(V!==0)return V;for(let l of X.hosts){let K=Z.writeStruct(rZ,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(kZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=VZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);if(K===void 0||K<0)return Y(10);let m=[];for(let J=0;J<K;J++){let[R,C]=Z.readStruct(rZ);if(C!==0)return Y(C);if(R===void 0)return Y(14);m.push(R)}return b({masterSeed:V,hosts:m})}};var TG=new TextEncoder().encode("diplomatic.qrpair.v1"),iX=32,QG=iX+24+16,LG=32,Sb=Symbol("DHKEReq"),zb=Symbol("DHKEResp");function iV(Z){if(Z.byteLength!==iX)return Y(10);return b(Z)}function BV(Z){if(Z.byteLength<QG)return Y(10);return b(Z)}var QW=new sZ;async function wV(Z,X,W,V){let l;try{l=await QW.x25519Shared(Z,X)}catch{return Y(29)}try{if(l.byteLength!==iX||l.every((m)=>m===0))return Y(10);let K=SZ(l,TG),G=SZ(K,SZ(W,V));try{let m=await QW.blake3(G);return b(m.slice(0,LG))}finally{K.fill(0),G.fill(0)}}finally{l.fill(0)}}class BX{#Z;#X;constructor(Z,X){this.#Z=Z,this.#X=X}static async create(){let Z;try{let X=await QW.genX25519();Z=X.priv;let[W,V]=iV(X.pub);if(V!==0)return Y(V);if(W===void 0)return Y(10);let l=new BX(Z,W);return Z=void 0,b(l)}catch{return Y(29)}finally{Z?.fill(0)}}wipe(){this.#Z.fill(0)}get dhkeReq(){let[Z,X]=iV(this.#X.slice());if(Z===void 0)throw Error(`dhkeReq ${X}`);return Z}async finish(Z){let X=Z.subarray(0,iX),W=Z.subarray(iX),[V,l]=await wV(this.#Z,X,this.#X,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await QW.decryptXSalsa20Poly1305Combined(W,V)}catch{return Y(20)}let G=new j(K),[m,J]=G.readStruct(TW);if(J!==0)return Y(J);if(m===void 0)return Y(14);try{let[R,C]=ZZ.fromBytes(m.masterSeed);if(C!==0)return Y(C);if(R===void 0)return Y(12);return this.wipe(),b({enclave:R,hosts:m.hosts.map((F)=>({...F}))})}finally{m.masterSeed.fill(0)}}finally{V.fill(0),K?.fill(0)}}}function hZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var DZ=32,LW="DIPLOMATIC",LZ="public-key",T0=-7,Q0=-8,L0=-257,wX=[{type:LZ,alg:T0},{type:LZ,alg:Q0},{type:LZ,alg:L0}];function pW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function pZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function yW(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function AZ(Z){if(Z?.rpId!==void 0)return b(Z.rpId);if(typeof location>"u")return Y(9);return b(pW(location.hostname))}var AV="";function pG(){return AV}function vZ(Z){if(Z instanceof Error){AV=Z.message===""?Z.name:`${Z.name}: ${Z.message}`;return}AV=String(Z)}function oZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function $Z(Z){if(Z===null||Z.type!==LZ||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return b(Z)}async function DX(Z){if(typeof PublicKeyCredential>"u")return!1;let X=PublicKeyCredential.getClientCapabilities;if(typeof X!=="function")return!0;let W=await X.call(PublicKeyCredential);if(Z in W)return W[Z]===!0;return!0}function vV(Z){if(Z==="platform"||Z==="cross-platform")return Z;return}function p0(Z){if(/iPhone|iPad|iPod/i.test(Z))return"ios";if(/Android/i.test(Z))return"android";if(/Mac OS X|Macintosh/i.test(Z))return"macos";if(/Windows/i.test(Z))return"windows";if(/Linux/i.test(Z))return"linux";return"other"}function oV(Z){let X=Z.response;if(!("getTransports"in X))return;let W=X.getTransports;if(typeof W!=="function")return;let V=W.call(X);if(!Array.isArray(V))return;let l=[];for(let K of V)if(typeof K==="string"&&K.length>0)l.push(K);return l.length===0?void 0:l}var yG=32,SG=64,DV=37,I0=16;function y0(Z){let X=Z.response;if(!("getAuthenticatorData"in X))return;let W=X.getAuthenticatorData;if(typeof W!=="function")return;let V=W.call(X);if(!(V instanceof ArrayBuffer))return;let l=new Uint8Array(V);if(l.byteLength<DV+I0)return;let K=l[yG];if(K===void 0||(K&SG)===0)return;return l.slice(DV,DV+I0)}function S0(){return DX("extension:largeBlob")}async function SW(Z){let X=oZ();if(X!==0)return Y(X);let[W,V]=AZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-seed",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G={largeBlob:{support:"required"}},m;try{m=await navigator.credentials.create({publicKey:{challenge:hZ(DZ),rp:{id:W,name:Z?.rpName??LW},user:{id:hZ(16),name:l,displayName:l},pubKeyCredParams:wX,authenticatorSelection:K,extensions:G,...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch(F){return vZ(F),Y(30)}let[J,R]=$Z(m);if(R!==0)return Y(R);if(J===void 0)return Y(27);if(J.getClientExtensionResults().largeBlob?.supported!==!0)return Y(30);return b(new Uint8Array(J.rawId))}async function AX(Z,X,W){let V=oZ();if(V!==0)return V;let[l,K]=AZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:pZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:hZ(DZ),rpId:l,allowCredentials:[{type:LZ,id:pZ(Z)}],userVerification:"required",extensions:G,...W?.hints!==void 0?{hints:W.hints}:{}}})}catch(F){return vZ(F),30}let[J,R]=$Z(m);if(R!==0)return R;if(J===void 0)return 27;if(J.getClientExtensionResults().largeBlob?.written!==!0)return 30;return 0}async function $V(Z,X,W,V){let l={challenge:hZ(DZ),rpId:Z,userVerification:"preferred"};if(X?.hints!==void 0)l.hints=X.hints;if(W!==void 0)l.allowCredentials=[{type:LZ,id:pZ(W)}];if(V!==void 0)l.extensions=V;let K;try{K=await navigator.credentials.get({publicKey:l})}catch(J){return vZ(J),Y(30)}let[G,m]=$Z(K);if(m!==0)return Y(m);if(G===void 0)return Y(27);return b(G)}async function zW(Z,X){let W=oZ();if(W!==0)return Y(W);let[V,l]=AZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K=Z;if(K===void 0){let[F,d]=await $V(V,X);if(d!==0&&X?.hints!==void 0)[F,d]=await $V(V,{rpId:X.rpId,rpName:X.rpName});if(d!==0)return Y(d);if(F===void 0)return Y(27);K=new Uint8Array(F.rawId)}let[G,m]=await $V(V,X,K,{largeBlob:{read:!0}});if(m!==0)return Y(m);if(G===void 0)return Y(27);let R=G.getClientExtensionResults().largeBlob;if(R===void 0||R.blob===void 0)return Y(7);let C=yW(R.blob);if(C.byteLength===0)return Y(7);return b({blob:C,credId:new Uint8Array(G.rawId)})}var xW=new TextEncoder().encode("diplomatic.prf.v1"),LX="diplomatic-prf",qV=32;function zG(Z){if(Z===void 0)return[];if(Z instanceof Uint8Array)return[Z];return Z.filter((X)=>X.byteLength>0)}async function xG(){return DX("extension:prf")}async function z0(Z){let X=oZ();if(X!==0)return Y(X);let[W,V]=AZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??LX,K=Z?.displayName??l,G=hZ(16),m=Z?.authenticatorAttachment==="cross-platform",J={residentKey:m?"discouraged":"required",requireResidentKey:!m,userVerification:m?"preferred":"required"};if(Z?.authenticatorAttachment!==void 0)J.authenticatorAttachment=Z.authenticatorAttachment;let R={challenge:hZ(DZ),rp:{id:W,name:Z?.rpName??LW},user:{id:G,name:l,displayName:K},pubKeyCredParams:wX,authenticatorSelection:J,...Z?.hints!==void 0?{hints:Z.hints}:{},...Z?.excludeCredentials!==void 0&&Z.excludeCredentials.length>0?{excludeCredentials:Z.excludeCredentials.map((L)=>({type:LZ,id:pZ(L)}))}:{}},C=Z?.salt!==void 0?pZ(Z.salt):void 0,F=(L)=>navigator.credentials.create({publicKey:{...R,extensions:L&&C!==void 0?{prf:{eval:{first:C}}}:{prf:{}}}}),d;try{d=await F(C!==void 0)}catch(L){if(C===void 0||!MG(L))return vZ(L),Y(30);try{d=await F(!1)}catch(S){return vZ(S),Y(30)}}let[k,c]=$Z(d);if(c!==0)return Y(c);if(k===void 0)return Y(27);let I=k.getClientExtensionResults(),T=x0(I.prf?.results?.first),p=I.prf?.enabled===!0||T!==void 0;if(m&&T!==void 0)T.fill(0);return b({credId:new Uint8Array(k.rawId),userId:new Uint8Array(G),prfEnabled:p,prf:m?void 0:T,attachment:vV(k.authenticatorAttachment),transports:oV(k),aaguid:y0(k)})}function MG(Z){if(!(Z instanceof Error))return!1;return Z.name==="NotSupportedError"||Z.name==="TypeError"}function x0(Z){if(Z===void 0)return;let X=yW(Z);if(X.byteLength<qV){X.fill(0);return}if(X.byteLength===qV)return X;let W=X.slice(0,qV);return X.fill(0),W}async function fV(Z){let X=oZ();if(X!==0)return Y(X);let[W,V]=AZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??xW,K=pZ(l),G={challenge:hZ(DZ),rpId:W,userVerification:"preferred",extensions:{prf:{eval:{first:K}}}};if(Z?.hints!==void 0)G.hints=Z.hints;let m=zG(Z?.credId);if(m.length>0)G.allowCredentials=m.map((k)=>({type:LZ,id:pZ(k)}));let J;try{J=await navigator.credentials.get({publicKey:G})}catch(k){return vZ(k),Y(30)}let[R,C]=$Z(J);if(C!==0)return Y(C);if(R===void 0)return Y(27);let F=R.getClientExtensionResults().prf?.results;if(F?.first===void 0)return Y(7);let d=x0(F.first);if(d===void 0)return Y(27);return b({prf:d,credId:new Uint8Array(R.rawId),attachment:vV(R.authenticatorAttachment),transports:oV(R)})}var MW="dmFyIHgwPTY0O3ZhciBBWj0zMixCMD04O3ZhciBEJD0zMjt2YXIgTFo9MzAwMDAsX1o9NTEyLHc7KChqKT0+e2pbai5TdWNjZXNzPTBdPSJTdWNjZXNzIjtqW2ouSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7altqLkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7altqLlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7altqLlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO2pbai5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO2pbai5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50IjtqW2ouTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO2pbai5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO2pbai5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0IjtqW2ouSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO2pbai5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjtqW2ouSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7altqLk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO2pbai5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjtqW2ouU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjtqW2ouRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO2pbai5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO2pbai5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO2pbai5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjtqW2ouTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7altqLk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO2pbai5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO2pbai5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO2pbai5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7altqLkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7altqLkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIjtqW2ouQ3J5cHRvRXJyb3I9MjldPSJDcnlwdG9FcnJvciI7altqLldlYkF1dGhuRXJyb3I9MzBdPSJXZWJBdXRobkVycm9yIn0pKHd8fD17fSk7ZnVuY3Rpb24geFooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIEJaKCQpe2xldCBKPSQubGVuZ3RoLFo9MCxRPTA7d2hpbGUoUTxKKXtsZXQgVj0kLmNoYXJDb2RlQXQoUSsrKTtpZigoViY0Mjk0OTY3MTY4KT09PTApe1orKztjb250aW51ZX1lbHNlIGlmKChWJjQyOTQ5NjUyNDgpPT09MClaKz0yO2Vsc2V7aWYoVj49NTUyOTYmJlY8PTU2MzE5KXtpZihRPEope2xldCBYPSQuY2hhckNvZGVBdChRKTtpZigoWCY2NDUxMik9PT01NjMyMCkrK1EsVj0oKFYmMTAyMyk8PDEwKSsoWCYxMDIzKSs2NTUzNn19aWYoKFYmNDI5NDkwMTc2MCk9PT0wKVorPTM7ZWxzZSBaKz00fX1yZXR1cm4gWn1mdW5jdGlvbiBJVigkLEosWil7bGV0IFE9JC5sZW5ndGgsVj1aLFg9MDt3aGlsZShYPFEpe2xldCBZPSQuY2hhckNvZGVBdChYKyspO2lmKChZJjQyOTQ5NjcxNjgpPT09MCl7SltWKytdPVk7Y29udGludWV9ZWxzZSBpZigoWSY0Mjk0OTY1MjQ4KT09PTApSltWKytdPVk+PjYmMzF8MTkyO2Vsc2V7aWYoWT49NTUyOTYmJlk8PTU2MzE5KXtpZihYPFEpe2xldCBXPSQuY2hhckNvZGVBdChYKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1gsWT0oKFkmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFkmNDI5NDkwMTc2MCk9PT0wKUpbVisrXT1ZPj4xMiYxNXwyMjQsSltWKytdPVk+PjYmNjN8MTI4O2Vsc2UgSltWKytdPVk+PjE4Jjd8MjQwLEpbVisrXT1ZPj4xMiY2M3wxMjgsSltWKytdPVk+PjYmNjN8MTI4fUpbVisrXT1ZJjYzfDEyOH19dmFyIFBWPW5ldyBUZXh0RW5jb2RlcixqVj01MDtmdW5jdGlvbiBUVigkLEosWil7UFYuZW5jb2RlSW50bygkLEouc3ViYXJyYXkoWikpfWZ1bmN0aW9uIGZaKCQsSixaKXtpZigkLmxlbmd0aD5qVilUVigkLEosWik7ZWxzZSBJVigkLEosWil9dmFyIERWPTQwOTY7ZnVuY3Rpb24gRkooJCxKLFope2xldCBRPUosVj1RK1osWD1bXSxZPSIiO3doaWxlKFE8Vil7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVgucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztYLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1gucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTz0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE8+NjU1MzUpTy09NjU1MzYsWC5wdXNoKE8+Pj4xMCYxMDIzfDU1Mjk2KSxPPTU2MzIwfE8mMTAyMztYLnB1c2goTyl9ZWxzZSBYLnB1c2goVyk7aWYoWC5sZW5ndGg+PURWKVkrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWCksWC5sZW5ndGg9MH1pZihYLmxlbmd0aD4wKVkrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWCk7cmV0dXJuIFl9dmFyIHdWPW5ldyBUZXh0RGVjb2RlcixBVj0yMDA7ZnVuY3Rpb24gTFYoJCxKLFope2xldCBRPSQuc3ViYXJyYXkoSixKK1opO3JldHVybiB3Vi5kZWNvZGUoUSl9ZnVuY3Rpb24ga1ooJCxKLFope2lmKFo+QVYpcmV0dXJuIExWKCQsSixaKTtlbHNlIHJldHVybiBGSigkLEosWil9Y2xhc3MgYTB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsSil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPUp9fWNsYXNzIGUgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgSj1PYmplY3QuY3JlYXRlKGUucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxKKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOmUubmFtZX0pfX12YXIgczA9NDI5NDk2NzI5NTtmdW5jdGlvbiBtWigkLEosWil7bGV0IFE9Wi80Mjk0OTY3Mjk2LFY9WjskLnNldFVpbnQzMihKLFEpLCQuc2V0VWludDMyKEorNCxWKX1mdW5jdGlvbiB3JCgkLEosWil7bGV0IFE9TWF0aC5mbG9vcihaLzQyOTQ5NjcyOTYpLFY9WjskLnNldFVpbnQzMihKLFEpLCQuc2V0VWludDMyKEorNCxWKX1mdW5jdGlvbiBBJCgkLEope2xldCBaPSQuZ2V0SW50MzIoSiksUT0kLmdldFVpbnQzMihKKzQpO3JldHVybiBaKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBFWigkLEope2xldCBaPSQuZ2V0VWludDMyKEopLFE9JC5nZXRVaW50MzIoSis0KTtyZXR1cm4gWio0Mjk0OTY3Mjk2K1F9dmFyIF9WPS0xLHhWPTQyOTQ5NjcyOTUsQlY9MTcxNzk4NjkxODM7ZnVuY3Rpb24gZlYoe3NlYzokLG5zZWM6Sn0pe2lmKCQ+PTAmJko+PTAmJiQ8PUJWKWlmKEo9PT0wJiYkPD14Vil7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksWn1lbHNle2xldCBaPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxWPW5ldyBVaW50OEFycmF5KDgpLFg9bmV3IERhdGFWaWV3KFYuYnVmZmVyKTtyZXR1cm4gWC5zZXRVaW50MzIoMCxKPDwyfFomMyksWC5zZXRVaW50MzIoNCxRKSxWfWVsc2V7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KFouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxKKSx3JChRLDQsJCksWn19ZnVuY3Rpb24ga1YoJCl7bGV0IEo9JC5nZXRUaW1lKCksWj1NYXRoLmZsb29yKEovMTAwMCksUT0oSi1aKjEwMDApKjFlNixWPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6WitWLG5zZWM6US1WKjFlOX19ZnVuY3Rpb24gbVYoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBKPWtWKCQpO3JldHVybiBmVihKKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIEVWKCQpe2xldCBKPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBaPUouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOlosbnNlYzowfX1jYXNlIDg6e2xldCBaPUouZ2V0VWludDMyKDApLFE9Si5nZXRVaW50MzIoNCksVj0oWiYzKSo0Mjk0OTY3Mjk2K1EsWD1aPj4+MjtyZXR1cm57c2VjOlYsbnNlYzpYfX1jYXNlIDEyOntsZXQgWj1BJChKLDQpLFE9Si5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpaLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgZShgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uIGdWKCQpe2xldCBKPUVWKCQpO3JldHVybiBuZXcgRGF0ZShKLnNlYyoxMDAwK0oubnNlYy8xZTYpfXZhciBnWj17dHlwZTpfVixlbmNvZGU6bVYsZGVjb2RlOmdWfTtjbGFzcyB0MHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyB0MDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKGdaKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpKLGRlY29kZTpafSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPUosdGhpcy5kZWNvZGVyc1skXT1aO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1KLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPVp9fXRyeVRvRW5jb2RlKCQsSil7Zm9yKGxldCBaPTA7Wjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7WisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1taXTtpZihRIT1udWxsKXtsZXQgVj1RKCQsSik7aWYoViE9bnVsbCl7bGV0IFg9LTEtWjtyZXR1cm4gbmV3IGEwKFgsVil9fX1mb3IobGV0IFo9MDtaPHRoaXMuZW5jb2RlcnMubGVuZ3RoO1orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1taXTtpZihRIT1udWxsKXtsZXQgVj1RKCQsSik7aWYoViE9bnVsbClyZXR1cm4gbmV3IGEwKFosVil9fWlmKCQgaW5zdGFuY2VvZiBhMClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxKLFope2xldCBRPUo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1KXTp0aGlzLmRlY29kZXJzW0pdO2lmKFEpcmV0dXJuIFEoJCxKLFopO2Vsc2UgcmV0dXJuIG5ldyBhMChKLCQpfX1mdW5jdGlvbiBTVigkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gSyQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYoU1YoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgdlY9MTAwLHlWPTIwNDg7Y2xhc3MgTCR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz90MC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/dlYsdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/eVYsdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBMJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLEope2lmKEo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke0p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsSil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IEo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxKKXRoaXMucmVzaXplQnVmZmVyKEoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBKPW5ldyBBcnJheUJ1ZmZlcigkKSxaPW5ldyBVaW50OEFycmF5KEopLFE9bmV3IERhdGFWaWV3KEopO1ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Wn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBaPUJaKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStaKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKFopLGZaKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPVp9ZW5jb2RlT2JqZWN0KCQsSil7bGV0IFo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoWiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihaKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLEopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLEopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IEo9JC5ieXRlTGVuZ3RoO2lmKEo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChKKTtlbHNlIGlmKEo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihKKTtlbHNlIGlmKEo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKEopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Sn1gKTtsZXQgWj1LJCgkKTt0aGlzLndyaXRlVThhKFopfWVuY29kZUFycmF5KCQsSil7bGV0IFo9JC5sZW5ndGg7aWYoWjwxNil0aGlzLndyaXRlVTgoMTQ0K1opO2Vsc2UgaWYoWjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KFopO2Vsc2UgaWYoWjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoWik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke1p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLEorMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsSil7bGV0IFo9MDtmb3IobGV0IFEgb2YgSilpZigkW1FdIT09dm9pZCAwKVorKztyZXR1cm4gWn1lbmNvZGVNYXAoJCxKKXtsZXQgWj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKVouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsWik6Wi5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFYgb2YgWil7bGV0IFg9JFtWXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZYPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhWKSx0aGlzLmRvRW5jb2RlKFgsSisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgWj0kLmRhdGEodGhpcy5wb3MrNiksUT1aLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShaKTtyZXR1cm59bGV0IEo9JC5kYXRhLmxlbmd0aDtpZihKPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKEo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoSj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihKPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKEo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKEo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChKKTtlbHNlIGlmKEo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihKKTtlbHNlIGlmKEo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKEopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke0p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgSj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKEopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1KfXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksbVoodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdyQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBFMCgkLEope3JldHVybiBuZXcgTCQoSikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIF8kKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgYlY9MTYsaFY9MTY7Y2xhc3MgT0p7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9YlYsSj1oVil7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1KLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgWj0wO1o8dGhpcy5tYXhLZXlMZW5ndGg7WisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxKLFope2xldCBRPXRoaXMuY2FjaGVzW1otMV07JDpmb3IobGV0IFYgb2YgUSl7bGV0IFg9Vi5ieXRlcztmb3IobGV0IFk9MDtZPFo7WSsrKWlmKFhbWV0hPT0kW0orWV0pY29udGludWUgJDtyZXR1cm4gVi5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxKKXtsZXQgWj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpKfTtpZihaLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpWltNYXRoLnJhbmRvbSgpKloubGVuZ3RofDBdPVE7ZWxzZSBaLnB1c2goUSl9ZGVjb2RlKCQsSixaKXtsZXQgUT10aGlzLmZpbmQoJCxKLFopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgVj1GSigkLEosWiksWD1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsSixKK1opO3JldHVybiB0aGlzLnN0b3JlKFgsViksVn19dmFyIE5KPSJhcnJheSIsTyQ9Im1hcF9rZXkiLHZaPSJtYXBfdmFsdWUiLGxWPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IGUoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyB5WntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgSj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Si50eXBlPU5KLEoucG9zaXRpb249MCxKLnNpemU9JCxKLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgSj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Si50eXBlPU8kLEoucmVhZENvdW50PTAsSi5zaXplPSQsSi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1OSil7bGV0IFo9JDtaLnNpemU9MCxaLmFycmF5PXZvaWQgMCxaLnBvc2l0aW9uPTAsWi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1PJHx8JC50eXBlPT09dlope2xldCBaPSQ7Wi5zaXplPTAsWi5tYXA9dm9pZCAwLFoucmVhZENvdW50PTAsWi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciBGJD0tMSxISj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSx1Vj1uZXcgVWludDhBcnJheShISi5idWZmZXIpO3RyeXtISi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBTWj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLGlWPW5ldyBPSjtjbGFzcyB4JHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1ISjtieXRlcz11VjtoZWFkQnl0ZT1GJDtzdGFjaz1uZXcgeVo7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz90MC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/czAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9zMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9zMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P3MwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/czAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOmlWLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/bFZ9Y2xvbmUoKXtyZXR1cm4gbmV3IHgkKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPUYkLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IEo9SyQoJCk7dGhpcy5ieXRlcz1KLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoSi5idWZmZXIsSi5ieXRlT2Zmc2V0LEouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PUYkJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgSj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxaPUskKCQpLFE9bmV3IFVpbnQ4QXJyYXkoSi5sZW5ndGgrWi5sZW5ndGgpO1Euc2V0KEopLFEuc2V0KFosSi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OkoscG9zOlp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Si5ieXRlTGVuZ3RoLVp9IG9mICR7Si5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IEo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gSn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBKPSExLFo7Zm9yIGF3YWl0KGxldCBZIG9mICQpe2lmKEopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoWSk7dHJ5e1o9dGhpcy5kb0RlY29kZVN5bmMoKSxKPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoSil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gWn1sZXR7aGVhZEJ5dGU6USxwb3M6Vix0b3RhbFBvczpYfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHtfJChRKX0gYXQgJHtYfSAoJHtWfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLEope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxKKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgWj1KLFE9LTE7Zm9yIGF3YWl0KGxldCBWIG9mICQpe2lmKEomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoViksWilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLFo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goWCl7aWYoIShYIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgWH10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksSjtpZigkPj0yMjQpSj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KUo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNle2xldCBRPSQtMTYwO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpSj1udWxsO2Vsc2UgaWYoJD09PTE5NClKPSExO2Vsc2UgaWYoJD09PTE5NSlKPSEwO2Vsc2UgaWYoJD09PTIwMilKPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylKPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClKPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KUo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KUo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpSj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgSj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpSj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlKPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClKPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KUo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIEo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpSj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpSj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IGUoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7XyQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBaPXRoaXMuc3RhY2s7d2hpbGUoWi5sZW5ndGg+MCl7bGV0IFE9Wi50b3AoKTtpZihRLnR5cGU9PT1OSilpZihRLmFycmF5W1EucG9zaXRpb25dPUosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpSj1RLmFycmF5LFoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1PJCl7aWYoSj09PSJfX3Byb3RvX18iKXRocm93IG5ldyBlKCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKEopLFEudHlwZT12Wjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPUosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlKPVEubWFwLFoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPU8kO2NvbnRpbnVlICR9fXJldHVybiBKfX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09RiQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT1GJH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyBlKGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke18kKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsSil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLEopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLEopfWRlY29kZVV0ZjhTdHJpbmcoJCxKKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyBlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytKKyQpdGhyb3cgU1o7bGV0IFo9dGhpcy5wb3MrSixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLFosJCk7ZWxzZSBRPWtaKHRoaXMuYnl0ZXMsWiwkKTtyZXR1cm4gdGhpcy5wb3MrPUorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1PJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxKKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyBlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrSikpdGhyb3cgU1o7bGV0IFo9dGhpcy5wb3MrSixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoWixaKyQpO3JldHVybiB0aGlzLnBvcys9SiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsSil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBaPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK0opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxKKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLFosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPUVaKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPUEkKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIFJKKCQsSil7cmV0dXJuIG5ldyB4JChKKS5kZWNvZGUoJCl9Y2xhc3MgTiR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLEope2xldCBaPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighWilaPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsWik7cmV0dXJuIFouYWRkKEopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsSil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoWil7aWYoWi5kZWxldGUoSiksWi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoWil7bGV0IFE9QXJyYXkuZnJvbShaKTtmb3IobGV0IFYgb2YgUSlWKEopfX1lbWl0QWxsKCQpe2xldCBKPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IFogb2YgSil0aGlzLmVtaXQoWiwkKX19Y2xhc3MgZzB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgTiR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdChnMC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoZzAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoZzAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gTigkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gcFYoJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IEo9W107d2hpbGUoJD4wbil7bGV0IFo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKUoucHVzaChafDEyOCk7ZWxzZSBKLnB1c2goWil9aWYoSi5sZW5ndGg9PT0wKXJldHVybiBOKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKEoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBOKG5ldyBVaW50OEFycmF5KEopKX1mdW5jdGlvbiBjVigkLEo9MCl7bGV0IFo9MG4sUT0wLFY9Sjt3aGlsZSghMCl7aWYoVj49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBYPSRbVisrXTtpZihYPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihafD1CaWdJbnQoWCYxMjcpPDxCaWdJbnQoUSksKFgmMTI4KT09PTApe2lmKFYtSj44KXJldHVybiBHKDI2KTtyZXR1cm4gTih7dmFsdWU6Wj4weDFmZmZmZmZmZmZmZmZmbj9aOk51bWJlcihaKSxieXRlc1JlYWQ6Vi1KfSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIGd7ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBKPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxaPW5ldyBVaW50OEFycmF5KEopO3JldHVybiBuZXcgZyhaKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LE4oJCl9cmVhZERhdGUoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gTihuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLEpdPWNWKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoSiE9PTApcmV0dXJuIEcoSik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBaPSQudmFsdWU7cmV0dXJuIE4odHlwZW9mIFo9PT0iYmlnaW50Ij9OdW1iZXIoWik6Wil9cmVhZFZhclN0cmluZygpe2xldFskLEpdPXRoaXMucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtaLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBWPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShaKTtyZXR1cm4gTihWKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBKPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsTihKKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IEo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbWixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Si5wdXNoKFopfXJldHVybiBOKEopfXJlYWRCeXRlc1NlcSgkKXtsZXQgSj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtaLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO0oucHVzaChaKX1yZXR1cm4gTihKKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBKPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKEopfXdyaXRlRGF0ZSgkKXtsZXQgSj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChKKX13cml0ZVZhckludCgkKXtsZXRbSixaXT1wVigkKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKEopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IEo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLFo9dGhpcy53cml0ZVZhckludChKLmxlbmd0aCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhKKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJC5zbGljZSgpKX13cml0ZUJ5dGVzKCQpe3RoaXMucGFydHMucHVzaCgkLnNsaWNlKCkpfXdyaXRlVmFyQnl0ZXMoJCl7bGV0IEo9dGhpcy53cml0ZVZhckludCgkLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcygkKSwwfXdyaXRlU3RydWN0KCQsSil7cmV0dXJuICQuZW5jb2RlKHRoaXMsSil9d3JpdGVTdHJ1Y3RzKCQsSil7Zm9yKGxldCBaIG9mIEope2xldCBRPXRoaXMud3JpdGVTdHJ1Y3QoJCxaKTtpZihRIT09MClyZXR1cm4gUX1yZXR1cm4gMH13cml0ZUJ5dGVzU2VxKCQpe2ZvcihsZXQgSiBvZiAkKXRoaXMud3JpdGVCeXRlcyhKKX1yZXN1bHQoKXtsZXQgJD10aGlzLnBhcnRzLnJlZHVjZSgoUSxWKT0+UStWLmxlbmd0aCwwKSxKPW5ldyBVaW50OEFycmF5KCQpLFo9MDtmb3IobGV0IFEgb2YgdGhpcy5wYXJ0cylKLnNldChRLFopLForPVEubGVuZ3RoO3JldHVybiBKfXdpcGUoKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cykkLmZpbGwoMCk7dGhpcy5wYXJ0cy5sZW5ndGg9MH0qc2Nhbigpe2ZvcihsZXQgJCBvZiB0aGlzLnBhcnRzKXlpZWxkICR9fWFzeW5jIGZ1bmN0aW9uIHFKKCQsSil7bGV0IFo9bmV3IFMsUT1aLndyaXRlRGF0ZShKKTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgVj1aLnJlc3VsdCgpLFg9YXdhaXQgJC5zaWduKFYpO3JldHVybiBOKHtwdWJLZXk6JC5wdWJsaWNLZXksc2lnOlgsdGltZXN0YW1wOkp9KX1hc3luYyBmdW5jdGlvbiBmMCgkLEosWil7bGV0IFE9Wi5ub3coKS5nZXRUaW1lKCksVj0kLnRpbWVzdGFtcC5nZXRUaW1lKCk7aWYoTWF0aC5hYnMoUS1WKT5MWilyZXR1cm4gNDtsZXQgWT1uZXcgUztZLndyaXRlRGF0ZSgkLnRpbWVzdGFtcCk7bGV0IFc9WS5yZXN1bHQoKTtpZighYXdhaXQgSi5jaGVja1NpZ0VkMjU1MTkoJC5zaWcsVywkLnB1YktleSkpcmV0dXJuIDM7cmV0dXJuIDB9dmFyIFgwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5pZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZURhdGUoSi50cyk7aWYoUSE9PTApcmV0dXJuIFE7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJCeXRlcygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZERhdGUoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gTih7aWQ6Six0czpRfSl9fTtmdW5jdGlvbiBCJCgkKXtsZXQgSj1uZXcgUyxaPUoud3JpdGVTdHJ1Y3QoWDAsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9Si5yZXN1bHQoKTtyZXR1cm4gTihRKX12YXIgejA9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmVpZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLm9mZik7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFY9JC53cml0ZVZhckludChKLmN0cik7aWYoViE9PTApcmV0dXJuIFY7bGV0IFg9JC53cml0ZVZhckludChKLmxlbik7aWYoWCE9PTApcmV0dXJuIFg7aWYoSi5oc2gpJC53cml0ZUJ5dGVzKEouaHNoKTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckJ5dGVzKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9bmV3IGcoSiksWyxWXT1YMC5kZWNvZGUoUSk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1gsWV09JC5yZWFkVmFySW50KCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1csel09JC5yZWFkVmFySW50KCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkVmFySW50KCk7aWYoRiE9PTApcmV0dXJuIEcoRik7bGV0IE87aWYoSz4wKXtsZXRbSCxSXT0kLnJlYWRCeXRlcyhEJCk7aWYoUiE9PTApcmV0dXJuIEcoUik7Tz1IfXJldHVybiBOKHtlaWQ6SixvZmY6WCxjdHI6VyxsZW46Syxoc2g6T30pfX07ZnVuY3Rpb24gSDAoJCl7cmV0dXJuIEFycmF5LmZyb20oJCkubWFwKChaKT0+Wi50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX1mdW5jdGlvbiBiWigkKXtpZigkLmxlbmd0aCUyIT09MCl0aHJvdyBFcnJvcigiSW52YWxpZCBoZXggc3RyaW5nIik7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoJC5sZW5ndGgvMik7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKz0yKUpbWi8yXT1OdW1iZXIucGFyc2VJbnQoJC5zdWJzdHIoWiwyKSwxNik7cmV0dXJuIEp9ZnVuY3Rpb24gbigkLEope2lmKCQ9PT1KKXJldHVybiEwO2lmKCQuYnl0ZUxlbmd0aCE9PUouYnl0ZUxlbmd0aClyZXR1cm4hMTtyZXR1cm4gJC5ldmVyeSgoWixRKT0+Wj09PUpbUV0pfXZhciBCO2lmKHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS50b0Jhc2U2ND09PSJmdW5jdGlvbiIpQj0oJCk9PiQudG9CYXNlNjQoKTtlbHNlIEI9KCQpPT5idG9hKFN0cmluZy5mcm9tQ2hhckNvZGUoLi4uJCkpO3ZhciBPMDtpZih0eXBlb2YgVWludDhBcnJheS5mcm9tQmFzZTY0PT09ImZ1bmN0aW9uIilPMD0oJCk9PlVpbnQ4QXJyYXkuZnJvbUJhc2U2NCgkKTtlbHNlIE8wPSgkKT0+VWludDhBcnJheS5mcm9tKGF0b2IoJCksKEopPT5KLmNoYXJDb2RlQXQoMCkpO2Z1bmN0aW9uIGhaKCQpe2xldCBKPSQubGVuZ3RoJTQ9PT0wPyIiOiI9Ii5yZXBlYXQoNC0kLmxlbmd0aCU0KSxaPSQucmVwbGFjZSgvLS9nLCIrIikucmVwbGFjZSgvXy9nLCIvIikrSjtyZXR1cm4gTzAoWil9ZnVuY3Rpb24gSTAoJCxKKXtsZXQgWj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtKLmxlbmd0aCk7cmV0dXJuIFouc2V0KCQsMCksWi5zZXQoSiwkLmxlbmd0aCksWn1mdW5jdGlvbiBsWigkLEosWil7cmV0dXJuIFouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxKKX1hc3luYyBmdW5jdGlvbiB1WigkLEosWixRKXtsZXQgVjtpZigkLmJvZCYmJC5sZW4+MClWPWF3YWl0IFouYmxha2UzKCQuYm9kKTtsZXQgWD1uZXcgUyxZPXowLmVuY29kZShYLHsuLi4kLGhzaDpWfSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0IFc9WC5yZXN1bHQoKSx6PWF3YWl0IEoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE89JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxIPWF3YWl0IEouc2lnbihGKTtyZXR1cm4gTih7c2lnOkgsa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6T30pfWFzeW5jIGZ1bmN0aW9uIE1KKCQsSixaLFEsVil7bGV0IFg9bmV3IGcoJCksW1ksV109ejAuZGVjb2RlKFgpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1KJiZKLmxlbmd0aD4wP2F3YWl0IFouZGVjcnlwdChKKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVkuaHNoJiZ6PT09dm9pZCAwLEY9WS5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoWS5oc2gmJnope2xldCBIPWF3YWl0IFEuYmxha2UzKHopO2lmKCFuKEgsWS5oc2gpKXJldHVybiBHKDE5KX1sZXQgTz1WPz9hd2FpdCBRLmJsYWtlMygkKTtyZXR1cm4gTih7bXNnSGVhZDpZLGJvZDp6LGhlYWRIYXNoOk99KX1jbGFzcyBVSntub3coKXtyZXR1cm4gbmV3IERhdGV9fWZ1bmN0aW9uIGlaKCQsSixaLFEpe2xldCBWPUouZ2V0VGltZSgpLSQuZ2V0VGltZSgpLFg9Wi5nZXRUaW1lKCktUS5nZXRUaW1lKCk7cmV0dXJuKFYrWCkvMn12YXIgSCQ9e2VuY29kZSgkLEope2lmKCQud3JpdGVWYXJJbnQoSi5xdW90YSksSi5xdW90YT4wKXtpZihKLnVzYWdlPT09dm9pZCAwKXJldHVybiA5OyQud3JpdGVWYXJJbnQoSi51c2FnZSl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXQgUTtpZihKPjApe2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO1E9Vn1yZXR1cm4gTih7cXVvdGE6Six1c2FnZTpRfSl9fTt2YXIgQ0o9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbSi5zdGF0dXNdKSk7bGV0IFo9JC53cml0ZURhdGUoSi50aW1lUmN2ZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZURhdGUoSi50aW1lU2VudCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFY9JC53cml0ZVZhckludChKLnN1YnNjcmlwdGlvbi50ZXJtKTtpZihWIT09MClyZXR1cm4gVjtsZXQgWD0kLndyaXRlVmFySW50KEouc3Vic2NyaXB0aW9uLmVsYXBzZWQpO2lmKFghPT0wKXJldHVybiBYO2xldCBZPSQud3JpdGVTdHJ1Y3QoSCQsSi5zdWJzY3JpcHRpb24uc3RhdCk7aWYoWSE9PTApcmV0dXJuIFk7bGV0IFc9JC53cml0ZVN0cnVjdChIJCxKLnN1YnNjcmlwdGlvbi5keW4pO2lmKFchPT0wKXJldHVybiBXO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoMSk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9SlswXSxbVixYXT0kLnJlYWREYXRlKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1ksV109JC5yZWFkRGF0ZSgpO2lmKFchPT0wKXJldHVybiBHKFcpO2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO2xldFtGLE9dPSQucmVhZFZhckludCgpO2lmKE8hPT0wKXJldHVybiBHKE8pO2xldFtILFJdPSQucmVhZFN0cnVjdChIJCk7aWYoUiE9PTApcmV0dXJuIEcoUik7bGV0W3EsTV09JC5yZWFkU3RydWN0KEgkKTtpZihNIT09MClyZXR1cm4gRyhNKTtyZXR1cm4gTih7c3RhdHVzOlEsdGltZVJjdmQ6Vix0aW1lU2VudDpZLHN1YnNjcmlwdGlvbjp7dGVybTp6LGVsYXBzZWQ6RixzdGF0OkgsZHluOnF9fSl9fTt2YXIgSUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5zZXEpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFyQnl0ZXMoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gTih7aGVhZENwaDpKLHNlcTpRfSl9fTt2YXIgWTA9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnB1YktleSksJC53cml0ZUJ5dGVzKEouc2lnKTtsZXQgWj0kLndyaXRlRGF0ZShKLnRpbWVzdGFtcCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhBWik7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsVl09JC5yZWFkQnl0ZXMoeDApO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtYLFldPSQucmVhZERhdGUoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTih7cHViS2V5Okosc2lnOlEsdGltZXN0YW1wOlh9KX19O3ZhciBwWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsVil7bGV0IFg9Vi53cml0ZVN0cnVjdChZMCxaKTtpZihYIT09MClyZXR1cm4gWDtmb3IobGV0IFkgb2YgUSlWLndyaXRlVmFySW50KFkpO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpWLHN0b3JhZ2U6WH09JCxbWSxXXT1KLnJlYWRTdHJ1Y3QoWTApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IGYwKFksVixRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVksW0YsT109YXdhaXQgWC5oYXNVc2VyKEspO2lmKE8hPT0wKXJldHVybiBPO2lmKCFGKXJldHVybiA1O2xldFtILFJdPUoucmVhZFZhckludCgpO2lmKFIhPT0wKXJldHVybiBSO2lmKCFKLmRvbmUoKSlyZXR1cm4gODtsZXRbcSxNXT1hd2FpdCBYLmxpc3RIZWFkcyhLLEgpO2lmKE0hPT0wKXJldHVybiBNO3JldHVybiBaLndyaXRlU3RydWN0cyhJSixxKX0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhJSil9fTt2YXIgUEo9e2VuY29kZSgkLEopeyQud3JpdGVWYXJJbnQoSi5zZXEpO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlDcGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsVl09JC5yZWFkVmFyQnl0ZXMoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gTih7c2VxOkosYm9keUNwaDpRfSl9fTt2YXIgY1o9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFYpe2xldCBYPVYud3JpdGVTdHJ1Y3QoWTAsWik7aWYoWCE9PTApcmV0dXJuIFg7Zm9yKGxldCBZIG9mIFEpe2xldCBXPVYud3JpdGVWYXJJbnQoWSk7aWYoVyE9PTApcmV0dXJuIFd9cmV0dXJuIDB9LGFzeW5jIGhhbmRsZVJlcSgkLEosWil7bGV0e2Nsb2NrOlEsY3J5cHRvOlYsc3RvcmFnZTpYfT0kLFtZLFddPUoucmVhZFN0cnVjdChZMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgZjAoWSxWLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309WSxbRixPXT1hd2FpdCBYLmhhc1VzZXIoSyk7aWYoTyE9PTApcmV0dXJuIE87aWYoIUYpcmV0dXJuIDU7bGV0IEg9W107d2hpbGUoIUouZG9uZSgpKXtsZXRbTSxVXT1KLnJlYWRWYXJJbnQoKTtpZihVIT09MClyZXR1cm4gVTtILnB1c2goTSl9Y29uc29sZS5pbmZvKGBQVUxMOiAke0gubGVuZ3RofSBiYWdzYCk7bGV0W1IscV09YXdhaXQgWC5nZXRCb2RpZXMoSyxIKTtpZihxIT09MClyZXR1cm4gcTtpZighUilyZXR1cm4gMTc7Zm9yKGxldHtzZXE6TSxib2R5Q3BoOlV9b2YgUil7bGV0IFA9e3NlcTpNLGJvZHlDcGg6VX0sST1aLndyaXRlU3RydWN0KFBKLFApO2lmKEkhPT0wKXJldHVybiBJfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKFBKKX19O3ZhciBqSj17ZW5jb2RlKCQsSil7JC53cml0ZUJ5dGVzKEouc2lnKSwkLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlDcGgpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoeDApO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZEJ5dGVzKEIwKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWCxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtXLHpdPSQucmVhZFZhckJ5dGVzKCk7aWYoeiE9PTApcmV0dXJuIEcoeik7cmV0dXJuIE4oe3NpZzpKLGtkbTpRLGhlYWRDcGg6WCxib2R5Q3BoOld9KX19O3ZhciBmJD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhckludChKLnNlcSk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKEouaGVhZENwaCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFY9Si5ib2R5Q3BoP0ouYm9keUNwaC5sZW5ndGg6MCxYPSQud3JpdGVWYXJJbnQoVik7aWYoWCE9PTApcmV0dXJuIFg7aWYoVj4wKXtpZighSi5ib2R5Q3BoKXJldHVybiAxMDskLndyaXRlQnl0ZXMoSi5ib2R5Q3BoKX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZFZhckJ5dGVzKCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1gsWV09JC5yZWFkVmFySW50KCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0IFc7aWYoWD4wKXtsZXRbeixLXT0kLnJlYWRCeXRlcyhYKTtpZihLIT09MClyZXR1cm4gRyhLKTtXPXp9cmV0dXJuIE4oe3NlcTpKLGhlYWRDcGg6USxib2R5Q3BoOld9KX19O3ZhciBrJD17ZW5jb2RlKCQsSil7JC53cml0ZUJ5dGVzKEouc2lnKSwkLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoeDApO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZEJ5dGVzKEIwKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWCxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBOKHtzaWc6SixrZG06USxoZWFkQ3BoOlh9KX19O3ZhciBtJD17ZW5jb2RlKCQsSil7aWYoJC53cml0ZVZhckludChKLmlkeCksJC53cml0ZUJ5dGVzKG5ldyBVaW50OEFycmF5KFtKLnN0YXR1c10pKSxKLnN0YXR1cz09PTApJC53cml0ZVZhckludChKLnNlcSk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxWXT0kLnJlYWRCeXRlcygxKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD1RWzBdO2lmKFghPT0wKXJldHVybiBOKHtpZHg6SixzdGF0dXM6WH0pO2xldFtZLFddPSQucmVhZFZhckludCgpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBOKHtpZHg6SixzdGF0dXM6WCxzZXE6WX0pfX07dmFyIG5aPXthc3luYyBlbmNvZGVSZXEoJCxKLFosUSxWKXtsZXQgWD1WLndyaXRlU3RydWN0KFkwLFopO2lmKFghPT0wKXJldHVybiBYO2xldCBZPVYud3JpdGVTdHJ1Y3RzKGpKLFEpO2lmKFkhPT0wKXJldHVybiBZO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpWLHN0b3JhZ2U6WCxub3RpZmllcjpZfT0kLFtXLHpdPUoucmVhZFN0cnVjdChZMCk7aWYoeiE9PTApcmV0dXJuIHo7bGV0IEs9YXdhaXQgZjAoVyxWLFEpO2lmKEshPT0wKXJldHVybiBLO2xldHtwdWJLZXk6Rn09VyxbTyxIXT1hd2FpdCBYLmhhc1VzZXIoRik7aWYoSCE9PTApcmV0dXJuIEg7aWYoIU8pcmV0dXJuIDU7bGV0W1IscV09Si5yZWFkU3RydWN0cyhqSik7aWYocSE9PTApcmV0dXJuIHE7Y29uc29sZS5pbmZvKGBQVVNIOiAke1IubGVuZ3RofSBiYWdzYCk7bGV0IE09W10sVT1bXTtmb3IobGV0IEM9MDtDPFIubGVuZ3RoO0MrKyl7bGV0IEE9UltDXTtpZighYXdhaXQgbFooQSxGLFYpKXtsZXQgRT17aWR4OkMsc3RhdHVzOjN9LG09Wi53cml0ZVN0cnVjdChtJCxFKTtpZihtIT09MClyZXR1cm4gbTtjb250aW51ZX1NLnB1c2goQyksVS5wdXNoKEEpfWxldFtQLEldPWF3YWl0IFguc2V0QmFncyhGLFUpO2lmKEkhPT0wKXJldHVybiBJO2lmKCFQfHxQLmxlbmd0aCE9PVUubGVuZ3RoKXJldHVybiAxNztsZXQgVD1bXTtmb3IobGV0IEM9MDtDPFUubGVuZ3RoO0MrKyl7bGV0IEE9VVtDXSxfPU1bQ10sRT1QW0NdLG09bmV3IFMsZj1tLndyaXRlU3RydWN0KGskLEEpO2lmKGYhPT0wKXJldHVybiBmO2xldCB5PW0ucmVzdWx0KCksaD17c2VxOkUsaGVhZENwaDp5fTtpZihSLmxlbmd0aD09PTEmJkEuYm9keUNwaC5sZW5ndGg8PV9aKWguYm9keUNwaD1BLmJvZHlDcGg7VC5wdXNoKGgpO2xldCBpPXtpZHg6XyxzdGF0dXM6MCxzZXE6RX0saj1aLndyaXRlU3RydWN0KG0kLGkpO2lmKGohPT0wKXJldHVybiBqfWlmKFQubGVuZ3RoPjApe2xldCBDPW5ldyBTLEE9Qy53cml0ZVN0cnVjdHMoZiQsVCk7aWYoQSE9PTApcmV0dXJuIEE7bGV0IF89Qy5yZXN1bHQoKTthd2FpdCBQcm9taXNlLnJlc29sdmUoWS5wdXNoKEYsXykpfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKG0kKX19O3ZhciBkWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsVil7cmV0dXJuIFYud3JpdGVTdHJ1Y3QoWTAsWil9LGFzeW5jIGhhbmRsZVJlcSgkLEosWil7bGV0e2Nsb2NrOlEsY3J5cHRvOlYsc3RvcmFnZTpYfT0kLFtZLFddPUoucmVhZFN0cnVjdChZMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgZjAoWSxWLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309WTtpZighSi5kb25lKCkpcmV0dXJuIDg7bGV0W0YsT109YXdhaXQgWC5hZGRVc2VyKEspO2lmKE8hPT0wKXJldHVybiBPO3JldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiBOKHZvaWQgMCl9fTtjbGFzcyBUSnt1cmw7d2Vic29ja2V0O2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSR9Y29ubmVjdGVkKCl7cmV0dXJuIHRoaXMud2Vic29ja2V0IT09dm9pZCAwJiZ0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09V2ViU29ja2V0Lk9QRU59YXN5bmMgY29ubmVjdCgkLEosWj0oKT0+e30sUT0oKT0+e30pe2xldHt1cmw6Vn09dGhpcztpZih0aGlzLndlYnNvY2tldCl0aGlzLndlYnNvY2tldC5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMDtsZXQgWD1uZXcgUztYLndyaXRlU3RydWN0KFkwLCQpO2xldCBZPVgucmVzdWx0KCksVz1IMChZKTtyZXR1cm4gVi5zZWFyY2hQYXJhbXMuc2V0KCJ0IixXKSx0aGlzLndlYnNvY2tldD1uZXcgV2ViU29ja2V0KFYpLHRoaXMud2Vic29ja2V0LmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix0aGlzLndlYnNvY2tldC5vbm9wZW49KCk9Pntjb25zb2xlLmxvZygiQ09OTkVDVEVEIiksUSgpfSx0aGlzLndlYnNvY2tldC5vbmNsb3NlPSgpPT57Y29uc29sZS5sb2coIkRJU0NPTk5FQ1RFRCIpLHRoaXMud2Vic29ja2V0PXZvaWQgMCxaKCl9LHRoaXMud2Vic29ja2V0Lm9ubWVzc2FnZT0oeik9PntsZXQgSz1uZXcgVWludDhBcnJheSh6LmRhdGEpO0ooSyl9LHRoaXMud2Vic29ja2V0Lm9uZXJyb3I9KHopPT57Y29uc29sZS5sb2coYEVSUk9SOiAke0pTT04uc3RyaW5naWZ5KHopfWApLHRoaXMud2Vic29ja2V0PXZvaWQgMCxaKCl9LFByb21pc2UucmVzb2x2ZSgwKX1kaXNjb25uZWN0KCl7dGhpcy53ZWJzb2NrZXQ/LmNsb3NlKCksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwfX12YXIgYT17dXNlcjp7cGF0aDoiL3VzZXIiLGVuZHBvaW50OmRaLG5hbWU6MH0scHVzaDp7cGF0aDoiL3B1c2giLGVuZHBvaW50Om5aLG5hbWU6Mn0scGVlazp7cGF0aDoiL3BlZWsiLGVuZHBvaW50OnBaLG5hbWU6MX0scHVsbDp7cGF0aDoiL3B1bGwiLGVuZHBvaW50OmNaLG5hbWU6M319LG5WPXswOmEudXNlciwyOmEucHVzaCwxOmEucGVlaywzOmEucHVsbH0sSUc9e1thLnVzZXIucGF0aF06YS51c2VyLFthLnB1c2gucGF0aF06YS5wdXNoLFthLnBlZWsucGF0aF06YS5wZWVrLFthLnB1bGwucGF0aF06YS5wdWxsfTtjbGFzcyByWnt1cmw7bGlzdGVuZXI7Y29uc3RydWN0b3IoJCl7dGhpcy51cmw9JDt0aGlzLmxpc3RlbmVyPW5ldyBUSigkKX1hc3luYyBjYWxsKCQsSil7bGV0e3BhdGg6Wn09blZbJF0sUT1uZXcgVVJMKFosdGhpcy51cmwpO3RyeXtyZXR1cm4gYXdhaXQgZFYoUSxKKX1jYXRjaHtyZXR1cm4gRygyNSl9fX12YXIgb1o9KCQpPT57cmV0dXJuIG5ldyByWigkLmhhbmRsZSl9O2FzeW5jIGZ1bmN0aW9uIGRWKCQsSil7bGV0IFo9YXdhaXQgZmV0Y2goJCx7bWV0aG9kOiJQT1NUIixib2R5OkoucmVzdWx0KCkuc2xpY2UoKX0pO2lmKCFaLm9rKXJldHVybiBHKDI0KTtsZXQgUT1hd2FpdCBnLmZyb21SZXNwb25zZShaKTtyZXR1cm4gTihRKX1jbGFzcyBFJHtlbmNsYXZlO2NyeXB0bztob3N0O2Nsb2NrO3RyYW5zcG9ydDt1cGRhdGVIb3N0TWV0YTtjb25zdHJ1Y3RvcigkLEosWixRLFYsWCl7dGhpcy5lbmNsYXZlPSQ7dGhpcy5jcnlwdG89Sjt0aGlzLmhvc3Q9Wjt0aGlzLmNsb2NrPVE7dGhpcy50cmFuc3BvcnQ9Vjt0aGlzLnVwZGF0ZUhvc3RNZXRhPVh9YXN5bmMgY2FsbCgkLEope2xldHtjbG9jazpaLHRyYW5zcG9ydDpRfT10aGlzLHtlbmRwb2ludDpWLG5hbWU6WH09JCxZPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVoubm93KCksW3osS109YXdhaXQgcUooWSxXKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXQgRj1uZXcgUyxPPWF3YWl0IFYuZW5jb2RlUmVxKHRoaXMsWSx6LEosRik7aWYoTyE9PTApcmV0dXJuIEcoTyk7bGV0IEg9Wi5ub3coKSxbUixxXT1hd2FpdCBRLmNhbGwoWCxGKSxNPVoubm93KCk7aWYocSE9PTApcmV0dXJuIEcocSk7bGV0W1UsUF09Ui5yZWFkU3RydWN0KENKKTtpZihQIT09MClyZXR1cm4gRyhQKTtpZihVLnN0YXR1cyE9PTApcmV0dXJuIEcoVS5zdGF0dXMpO2xldCBUPXtjbG9ja09mZnNldDppWihILFUudGltZVJjdmQsVS50aW1lU2VudCxNKSxzdWJzY3JpcHRpb246VS5zdWJzY3JpcHRpb259LEM9YXdhaXQgdGhpcy51cGRhdGVIb3N0TWV0YShUKTtpZihDIT09MClyZXR1cm4gRyhDKTtyZXR1cm4gVi5kZWNvZGVSZXNwKFIpfWlkZW50aXR5PSgpPT57bGV0e2hvc3Q6JCxlbmNsYXZlOkp9PXRoaXM7cmV0dXJuIEouZGVyaXZlSWRlbnRpdHkoJC5sYWJlbCwkLmlkeD8/MCl9O3NlYWw9YXN5bmMoJCk9PntsZXR7Y3J5cHRvOkosZW5jbGF2ZTpafT10aGlzLFE9YXdhaXQgdGhpcy5pZGVudGl0eSgpO3JldHVybiB1WigkLFEsSixaKX07cmVnaXN0ZXI9KCk9PnRoaXMuY2FsbChhLnVzZXIsW10pO3BlZWs9KCQpPT50aGlzLmNhbGwoYS5wZWVrLFskXSk7cHVzaD0oJCk9PnRoaXMuY2FsbChhLnB1c2gsJCk7cHVsbD0oJCk9PnRoaXMuY2FsbChhLnB1bGwsJCk7bGlzdGVuPWFzeW5jKCQsSixaKT0+e2xldHtjbG9jazpRLHRyYW5zcG9ydDpWfT10aGlzLHtsaXN0ZW5lcjpYfT1WLFk9YXdhaXQgdGhpcy5pZGVudGl0eSgpLFc9US5ub3coKSxbeixLXT1hd2FpdCBxSihZLFcpO2lmKEshPT0wKXJldHVybiBLO3JldHVybiBhd2FpdCBYLmNvbm5lY3QoeiwkLEosWil9O2lzQ29ubmVjdGVkKCl7bGV0ICQ9dGhpcy50cmFuc3BvcnQ/Lmxpc3RlbmVyO2lmKCQmJnR5cGVvZiAkLmNvbm5lY3RlZD09PSJmdW5jdGlvbiIpcmV0dXJuICQuY29ubmVjdGVkKCk7cmV0dXJuITB9Y2xvc2VMaXN0ZW5lcigpe3RoaXMudHJhbnNwb3J0Py5saXN0ZW5lcj8uZGlzY29ubmVjdCgpfX12YXIgREo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJTdHJpbmcoSi5sYmwpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5pZHgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJJbnQoSi5udW0pO2lmKFYhPT0wKXJldHVybiBWO3JldHVybiAkLndyaXRlQnl0ZXMoSi5oc2gpLCQud3JpdGVCeXRlcyhKLnNpZyksMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhclN0cmluZygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtYLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtXLHpdPSQucmVhZEJ5dGVzKEQkKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRCeXRlcyh4MCk7aWYoRiE9PTApcmV0dXJuIEcoRik7cmV0dXJuIE4oe2xibDpKLGlkeDpRLG51bTpYLGhzaDpXLHNpZzpLfSl9fTt2YXIgd0o9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVTdHJ1Y3QoREosSi5oZWFkKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoSi5pbmRleEVuYyk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFY9JC53cml0ZVZhckJ5dGVzKEouYm9keUVuYyk7aWYoViE9PTApcmV0dXJuIFY7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRTdHJ1Y3QoREopO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZFZhckJ5dGVzKCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1gsWV09JC5yZWFkVmFyQnl0ZXMoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTih7aGVhZDpKLGluZGV4RW5jOlEsYm9keUVuYzpYfSl9fTt2YXIgQUo9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLmtkbSk7bGV0IFo9JC53cml0ZVZhckJ5dGVzKEouaGVhZENwaCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLmxlbkJvZHkpO2lmKFEhPT0wKXJldHVybiBRO2lmKEoubGVuQm9keT4wJiZKLm9mZkJvZHkhPT12b2lkIDApe2xldCBWPSQud3JpdGVWYXJJbnQoSi5vZmZCb2R5KTtpZihWIT09MClyZXR1cm4gVn1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEIwKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtYLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBXO2lmKFg+MCl7bGV0W3osS109JC5yZWFkVmFySW50KCk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBOKHtrZG06SixoZWFkQ3BoOlEsbGVuQm9keTpYLG9mZkJvZHk6V30pfX07YXN5bmMgZnVuY3Rpb24gYVooJCxKLFosUSxWKXtsZXQgWD1hd2FpdCBWLmRlcml2ZUlkZW50aXR5KCQsSiksWT1uZXcgUyxXPW5ldyBTLHo9MCxLPTA7Zm9yKGxldCBQIG9mIFope2xldCBJPW5ldyBTLFQ9SS53cml0ZVN0cnVjdCh6MCxQLmhlYWQpO2lmKFQhPT0wKXJldHVybiBHKFQpO2xldCBDPUkucmVzdWx0KCksQT1hd2FpdCBYLmtkbUZvcihDKSxfPVYuZGVyaXZlQ2lwaGVyKEEsImVuY3J5cHQiKSxFPWF3YWl0IF8uZW5jcnlwdChDKSxtPVAuYm9keT9hd2FpdCBfLmVuY3J5cHQoUC5ib2R5KTpuZXcgVWludDhBcnJheSgwKSxmPVAuaGVhZC5sZW4+MCYmUC5oZWFkLmhzaCE9PXZvaWQgMD9tLmxlbmd0aDowLHk9e2tkbTpBLGhlYWRDcGg6RSxsZW5Cb2R5OmYsb2ZmQm9keTpmPjA/Szp2b2lkIDB9LGg9WS53cml0ZVN0cnVjdChBSix5KTtpZihoIT09MClyZXR1cm4gRyhoKTtpZihQLmJvZHkpVy53cml0ZUJ5dGVzKG0pLEsrPW0ubGVuZ3RoO3orK31sZXQgRj1XLnJlc3VsdCgpLE89WS5yZXN1bHQoKSxIPWF3YWl0IFEuYmxha2UzKE8pLFI9YXdhaXQgWC5zaWduKEgpLHE9e2xibDokLGlkeDpKLG51bTp6LGhzaDpILHNpZzpSfSxNPW5ldyBTO00ud3JpdGVTdHJ1Y3Qod0ose2hlYWQ6cSxpbmRleEVuYzpPLGJvZHlFbmM6Rn0pO2xldCBVPU0ucmVzdWx0KCk7cmV0dXJuIE4oVSl9YXN5bmMgZnVuY3Rpb24gc1ooJCxKLFope2xldFtRLFZdPXdKLmRlY29kZShuZXcgZygkKSk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0e2hlYWQ6WCxpbmRleEVuYzpZLGJvZHlFbmM6V309USx6PWF3YWl0IFouZGVyaXZlSWRlbnRpdHkoWC5sYmwsWC5pZHgpO2lmKCFhd2FpdCBKLmNoZWNrU2lnRWQyNTUxOShYLnNpZyxYLmhzaCx6LnB1YmxpY0tleSkpcmV0dXJuIEcoMyk7bGV0IEY9YXdhaXQgSi5ibGFrZTMoWSk7aWYoIW4oRixYLmhzaCkpcmV0dXJuIEcoMTkpO2xldCBPPW5ldyBnKFkpLEg9W107Zm9yKGxldCBxPTA7cTxYLm51bTtxKyspe2xldFtNLFVdPU8ucmVhZFN0cnVjdChBSik7aWYoVSE9PTApcmV0dXJuIEcoVSk7SC5wdXNoKE0pfWlmKEgubGVuZ3RoIT09WC5udW0pcmV0dXJuIEcoMTQpO2xldCBSPVtdO2ZvcihsZXQgcSBvZiBIKXtsZXQgTT1aLmRlcml2ZUNpcGhlcihxLmtkbSwiZGVjcnlwdCIpLFU7dHJ5e1U9YXdhaXQgTS5kZWNyeXB0KHEuaGVhZENwaCl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldFtQLEldPXowLmRlY29kZShuZXcgZyhVKSk7aWYoSSE9PTApcmV0dXJuIEcoSSk7bGV0IFQ7aWYocS5sZW5Cb2R5PjAmJnEub2ZmQm9keSE9PXZvaWQgMCl7aWYoUC5oc2g9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldCBDPVcuc2xpY2UocS5vZmZCb2R5LHEub2ZmQm9keStxLmxlbkJvZHkpO3RyeXtUPWF3YWl0IE0uZGVjcnlwdChDKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IEE9YXdhaXQgSi5ibGFrZTMoVCk7aWYoIW4oQSxQLmhzaCkpcmV0dXJuIEcoMTkpfVIucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBOKFIpfWFzeW5jIGZ1bmN0aW9uIHRaKHtub3c6JCxib2Q6SixjcnlwdG86Wn0pe2xldCBRPWF3YWl0IFouZ2VuUmFuZG9tQnl0ZXMoOCksVj1uZXcgUyxYPVYud3JpdGVTdHJ1Y3QoWDAse2lkOlEsdHM6JH0pO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBZPVYucmVzdWx0KCk7cmV0dXJuIGckKHtub3c6JCxlaWQ6WSxjdHI6MCxib2Q6SixjcnlwdG86Wn0pfWFzeW5jIGZ1bmN0aW9uIGckKHtub3c6JCxlaWQ6SixjdHI6Wixib2Q6USxjcnlwdG86Vn0pe2xldCBYPW5ldyBnKEopLFtZLFddPVgwLmRlY29kZShYKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1ZLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFYuYmxha2UzKFEpO3JldHVybiBOKHtlaWQ6SixvZmY6eixjdHI6WixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIHJWKCQsSil7bGV0IFo9JC5sZW5ndGg8Si5sZW5ndGg/JC5sZW5ndGg6Si5sZW5ndGg7Zm9yKGxldCBRPTA7UTxaO1ErKylpZigkW1FdIT09SltRXSlyZXR1cm4gJFtRXS1KW1FdO3JldHVybiAkLmxlbmd0aC1KLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBSJCgkLEope2xldCBaPUFycmF5LmZyb20oJCk7Wi5zb3J0KHJWKTtsZXQgUT0wO2ZvcihsZXQgWSBvZiBaKVErPVkubGVuZ3RoO2xldCBWPW5ldyBVaW50OEFycmF5KFEpLFg9MDtmb3IobGV0IFkgb2YgWilWLnNldChZLFgpLFgrPVkubGVuZ3RoO3JldHVybiBKLmJsYWtlMyhWKX1mdW5jdGlvbiBvVigkKXtsZXQgSj1uZXcgUyxaPUoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9Si53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBWPUoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBOKEoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIFMkKCQsSil7bGV0IFo9W107Zm9yKGxldCBRIG9mICQpe2xldFtWLFhdPW9WKFEpO2lmKFghPT0wfHwhVilyZXR1cm4gRyhYKTtaLnB1c2goVil9cmV0dXJuIE4oYXdhaXQgUiQoWixKKSl9dmFyIE56PVN5bWJvbCgiTWFzdGVyU2VlZCIpLEh6PVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksUjA9MzIsZVo9MjQrUjArMTY7ZnVuY3Rpb24gJDAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09UjApcmV0dXJuIEcoMTApO3JldHVybiBOKCQpfWZ1bmN0aW9uIFMwKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PWVaKXJldHVybiBHKDEwKTtyZXR1cm4gTigkKX12YXIgcXo9U3ltYm9sKCJFbnRpdHlJRCIpO2Z1bmN0aW9uICRRKCQpe3JldHVybiJ0eXBlImluICR9dmFyIE16PVN5bWJvbCgiRGVyaXZhdGlvblNlZWQiKSxVej1TeW1ib2woIlB1YmxpY0tleSIpLEN6PVN5bWJvbCgiUHJpdmF0ZUtleSIpLEl6PVN5bWJvbCgiSG9zdFNwZWNpZmljS2V5UGFpciIpLFB6PVN5bWJvbCgiSGFzaCIpO2Z1bmN0aW9uIGFWKCQpe2lmKCEkKXJldHVybiExO2lmKHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoImJvZHkiaW4gJD09PSExKXJldHVybiExO2lmKCJ0eXBlImluICQ9PT0hMSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBzVigkKXtpZighJC5ib2R8fCQuYm9kLmxlbmd0aD09PTApe2xldCBRPXtvZmY6JC5vZmYsY3RyOiQuY3RyLGVpZDokLmVpZH07cmV0dXJuIE4oUSl9bGV0IEo9UkooJC5ib2QpO2lmKGFWKEopPT09ITEpcmV0dXJuIGNvbnNvbGUud2FybigibXNnIGJvZHkgaW52YWxpZCIsSiksRygxNCk7bGV0IFo9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkLGdpZDpKLmdpZCxwaWQ6Si5waWQsdGFnczpKLnRhZ3MsdHlwZTpKLnR5cGUsYm9keTpKLmJvZHl9O3JldHVybiBOKFopfWNsYXNzIHYke2FwcGxpZXI7ZW1pdHRlcj1uZXcgTiQ7Y2xlYXJlcjtvbkRpcnR5RWlkcztjYWNoZURyaXZlbjtwZWVySW5nZXN0O2NvbnN0cnVjdG9yKCQsSixaLFEpe3RoaXMuYXBwbGllcj0kO3RoaXMuY2xlYXJlcj1KLHRoaXMub25EaXJ0eUVpZHM9Wix0aGlzLmNhY2hlRHJpdmVuPVE/LmNhY2hlRHJpdmVuPz8hMSx0aGlzLnBlZXJJbmdlc3Q9UT8ucGVlckluZ2VzdH1hcHBseT1hc3luYygkKT0+e2xldCBKPVtdLFo9W107Zm9yKGxldCBXIG9mICQpe2xldFt6LEtdPXNWKFcpO2lmKFoucHVzaChLKSxLIT09MCljb250aW51ZTtKLnB1c2goeil9bGV0e3N0YXRzOlEsdHlwZXM6VixlaWRzOlh9PWF3YWl0IHRoaXMuYXBwbGllcihKKSxZPVtdO2ZvcihsZXQgVz0wO1c8JC5sZW5ndGg7VysrKXtsZXQgej1aW1ddLEs9UVtXXTtpZih6IT09MCl7WS5wdXNoKHopO2NvbnRpbnVlfWlmKEshPT0wKXtZLnB1c2goSyk7Y29udGludWV9WS5wdXNoKDApfWlmKCF0aGlzLmNhY2hlRHJpdmVuKWZvcihsZXQgVyBvZiBWKXRoaXMuZW1pdHRlci5lbWl0KFcsbnVsbCk7aWYoWC5sZW5ndGg+MCl0aGlzLm9uRGlydHlFaWRzPy4oWCk7cmV0dXJuIFl9O2NsZWFyPWFzeW5jKCk9PntsZXQgJD1hd2FpdCB0aGlzLmNsZWFyZXIoKTtpZigkIT09MClyZXR1cm4gJDtyZXR1cm4gdGhpcy5lbWl0dGVyLmVtaXRBbGwobnVsbCksJH07bm90aWZ5PSgkKT0+e2ZvcihsZXQgSiBvZiAkKXRoaXMuZW1pdHRlci5lbWl0KEosbnVsbCl9O3JlZnJlc2g9YXN5bmMoJCk9PntpZih0aGlzLnBlZXJJbmdlc3Qpe2F3YWl0IHRoaXMucGVlckluZ2VzdCgkKTtyZXR1cm59fTtvbj0oJCxKKT0+e3RoaXMuZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKCQsSil9O29mZj0oJCxKKT0+e3RoaXMuZW1pdHRlci5yZW1vdmVFdmVudExpc3RlbmVyKCQsSil9fXZhciBkPSJlbnRpdGllcyIseSQ9ImVudGl0eV90eXBlX2NyZWF0ZWRfYXQiLF9KPSJlbnRpdHlfdHlwZV91cGRhdGVkX2F0Iix4Sj0iZW50aXR5X3R5cGVfZ3JvdXBfaWQiLEJKPSJlbnRpdHlfdHlwZV9wYXJlbnRfaWQiLGUwPSJlbnRpdHlfdGFncyIsSlE9ImRiIixaUT0xMztmdW5jdGlvbiB0VigkKXtyZXR1cm4idHlwImluICR9ZnVuY3Rpb24gZVYoJCl7bGV0IEo9e2JvZDokLmJvZHksY3JkOiQuY3JlYXRlZEF0LC4uLiQuY3RyIT09MD97Y3RyOiQuY3RyfTp7fSxlaWQ6QigkLmVpZCksZ2lkOiQuZ2lkLHBpZDokLnBpZD9CKCQucGlkKTp2b2lkIDAsdGdzOiQudGFncyx0eXA6JC50eXBlLHVwZDokLnVwZGF0ZWRBdH07aWYoSi5naWQ9PT12b2lkIDApZGVsZXRlIEouZ2lkO2lmKEoucGlkPT09dm9pZCAwKWRlbGV0ZSBKLnBpZDtpZihKLnRncz09PXZvaWQgMClkZWxldGUgSi50Z3M7aWYoSi5jdHI9PT12b2lkIDApZGVsZXRlIEouY3RyO3JldHVybiBKfWZ1bmN0aW9uICRYKCQpe2lmKCF1KCQpKXJldHVybntlaWQ6QigkLmVpZCksdXBkOiQudXBkYXRlZEF0LC4uLiQuY3RyIT09MD97Y3RyOiQuY3RyfTp7fX07cmV0dXJuIGVWKCQpfWZ1bmN0aW9uICQkKCQpe3JldHVybntib2R5OiQuYm9kLGNyZWF0ZWRBdDokLmNyZCx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wLHR5cGU6JC50eXAsZWlkOk8wKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP08wKCQucGlkKTp2b2lkIDAsLi4uJC50Z3MhPT12b2lkIDA/e3RhZ3M6JC50Z3N9Ont9fX1mdW5jdGlvbiBMSigkKXtpZih0VigkKSlyZXR1cm4gJCQoJCk7cmV0dXJue2VpZDpPMCgkLmVpZCksdXBkYXRlZEF0OiQudXBkLGN0cjokLmN0cj8/MH19Y2xhc3MgUVF7ZGI7b3BlbmluZzthc3luYyBpbml0KCl7YXdhaXQgdGhpcy5lbnN1cmVEYigpfWFzeW5jIGVuc3VyZURiKCl7aWYodGhpcy5kYilyZXR1cm4gdGhpcy5kYjtpZih0aGlzLm9wZW5pbmcpcmV0dXJuIHRoaXMub3BlbmluZztyZXR1cm4gdGhpcy5vcGVuaW5nPVpYKCkudGhlbigoJCk9PntyZXR1cm4gJC5vbnZlcnNpb25jaGFuZ2U9KCk9PntpZigkLmNsb3NlKCksdGhpcy5kYj09PSQpdGhpcy5kYj12b2lkIDB9LHRoaXMuZGI9JCx0aGlzLm9wZW5pbmc9dm9pZCAwLCR9LCgkKT0+e3Rocm93IHRoaXMub3BlbmluZz12b2lkIDAsJH0pLHRoaXMub3BlbmluZ31hcHBseT1hc3luYygkKT0+e2xldCBKPW5ldyBTZXQsWj1bXSxRO3RyeXtRPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm57c3RhdHM6JC5tYXAoKCk9PjE2KSx0eXBlczpKLGVpZHM6Wn19bGV0IFY9US50cmFuc2FjdGlvbihkLCJyZWFkd3JpdGUiKSxYPVYub2JqZWN0U3RvcmUoZCk7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBXPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO2lmKCQubGVuZ3RoPDEpe1koe3N0YXRzOltdLHR5cGVzOkosZWlkczpafSk7cmV0dXJufVYub25jb21wbGV0ZT0oKT0+e1koe3N0YXRzOlcsdHlwZXM6SixlaWRzOlp9KX0sVi5vbmVycm9yPSgpPT57Zm9yKGxldCBLPTA7SzxXLmxlbmd0aDtLKyspaWYoV1tLXT09PXZvaWQgMClXW0tdPTE4O1koe3N0YXRzOlcsdHlwZXM6SixlaWRzOlp9KX07bGV0IHo9bmV3IE1hcDtmb3IobGV0IEs9MDtLPCQubGVuZ3RoO0srKyl7bGV0IEY9JFtLXSxPPUIoRi5laWQpLEg9e29wOkYsaW5kZXg6S30sUj16LmdldChPKTtpZihSKVIucHVzaChIKTtlbHNlIHouc2V0KE8sW0hdKX1mb3IobGV0W0ssRl1vZiB6KXtpZihGLmxlbmd0aDwxKWNvbnRpbnVlO2xldCBPPVguZ2V0KEspO08ub25zdWNjZXNzPSgpPT57bGV0IEg9Ty5yZXN1bHQsUj1IP0xKKEgpOnZvaWQgMCxxPSExO2ZvcihsZXR7b3A6TSxpbmRleDpVfW9mIEYpe2xldFtQLEldPUokKFIsTSk7aWYoSSE9PTApe1dbVV09STtjb250aW51ZX1pZihQPT09dm9pZCAwKXtXW1VdPTEyO2NvbnRpbnVlfXE9ITA7Zm9yKGxldCBUIG9mIFokKFIsUCkpSi5hZGQoVCk7Uj1QfWlmKHEpWi5wdXNoKEZbMF0ub3AuZWlkKTtpZihSKXtsZXQgTT1YLnB1dCgkWChSKSk7TS5vbmVycm9yPShVKT0+e1UucHJldmVudERlZmF1bHQoKTtmb3IobGV0e2luZGV4OlB9b2YgRilXW1BdPTE4fX19LE8ub25lcnJvcj0oKT0+e2ZvcihsZXR7aW5kZXg6SH1vZiBGKVdbSF09MTh9fX0pfTthc3luYyBjbGVhcigpe2xldCAkO3RyeXskPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gMTZ9bGV0IEo9JC50cmFuc2FjdGlvbihkLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUoZCk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e0oub25jb21wbGV0ZT0oKT0+USgwKSxKLm9uZXJyb3I9KCk9PlEoMTgpLFouY2xlYXIoKX0pfWFzeW5jIGdldFJvdygkKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBaPUIoJCksVj1KLnRyYW5zYWN0aW9uKGQsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoZCk7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBZPVYuZ2V0KFopO1kub25zdWNjZXNzPSgpPT57bGV0IFc9WS5yZXN1bHQ7aWYoIVcpWChOKHZvaWQgMCkpO2Vsc2UgWChOKExKKFcpKSl9LFkub25lcnJvcj0oKT0+WChHKDE4KSl9KX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IXUoSikpcmV0dXJuIE4odm9pZCAwKTtyZXR1cm4gTihKKX1hc3luYyBnZXRBbGxPZlR5cGVVcGRhdGVkQmV0d2VlbigkLEosWil7bGV0IFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWD1RLnRyYW5zYWN0aW9uKGQsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoZCkuaW5kZXgoX0opO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVz1YLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbJCxKXSxbJCxaXSkpO1cub25zdWNjZXNzPSgpPT57bGV0IHo9Vy5yZXN1bHQ7WShOKHoubWFwKCQkKSkpfSxXLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0R3JvdXBNZW1iZXJzKCQsSil7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgVj1aLnRyYW5zYWN0aW9uKGQsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoZCkuaW5kZXgoeEopO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgWT1WLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFskLEpdKSk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1ZLnJlc3VsdDtYKE4oVy5tYXAoJCQpKSl9LFkub25lcnJvcj0oKT0+WChHKDE4KSl9KX1hc3luYyBnZXRBbGxPZlR5cGUoJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1KLnRyYW5zYWN0aW9uKGQsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoZCkuaW5kZXgoeSQpO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1RLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgWT1YLnJlc3VsdDtWKE4oWS5tYXAoJCQpKSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRCeVRhZygkLEope2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFY9Wi50cmFuc2FjdGlvbihkLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGQpLmluZGV4KGUwKTtyZXR1cm4gbmV3IFByb21pc2UoKFgpPT57bGV0IFk9Vi5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShKKSk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgej1ZLnJlc3VsdC5maWx0ZXIoKEspPT5LLnR5cD09PSQpLm1hcCgkJCk7WChOKHopKX0sWS5vbmVycm9yPSgpPT5YKEcoMTgpKX0pfWFzeW5jIGdldEFsbEVudGl0aWVzKCQpe2lmKCJwaWQiaW4gJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWj1CKCQucGlkKSxWPUoudHJhbnNhY3Rpb24oZCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShkKS5pbmRleChCSik7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBZPVYuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQudHlwZSxaXSkpO1kub25zdWNjZXNzPSgpPT57bGV0IHo9WS5yZXN1bHQubWFwKCQkKTtYKE4oeikpfSxZLm9uZXJyb3I9KCk9PlgoRygxOCkpfSl9ZWxzZSBpZigiZ2lkImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0R3JvdXBNZW1iZXJzKCQudHlwZSwkLmdpZCk7ZWxzZSBpZigidGFnImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QnlUYWcoJC50eXBlLCQudGFnKTtlbHNlIGlmKCJ1cGRhdGVkQmV0d2VlbiJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQudHlwZSwkLnVwZGF0ZWRCZXR3ZWVuLnN0YXJ0LCQudXBkYXRlZEJldHdlZW4uZW5kKTtyZXR1cm4gYXdhaXQgdGhpcy5nZXRBbGxPZlR5cGUoJC50eXBlKX1hc3luYyBnZXRFbnRpdGllcygkKXtsZXRbSixaXT1hd2FpdCB0aGlzLmdldEFsbEVudGl0aWVzKCQpO2lmKFohPT0wKXJldHVybiBHKFopO3JldHVybiBOKEopfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihkLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGQpLmluZGV4KHkkKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9SURCS2V5UmFuZ2UuYm91bmQoWyRdLFskLFtdXSksWT1RLmNvdW50KFgpO1kub25zdWNjZXNzPSgpPT5WKE4oWS5yZXN1bHQpKSxZLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9YXN5bmMgY2hlY2tzdW0oJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1KLnRyYW5zYWN0aW9uKGQsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoZCksVj1bXTtyZXR1cm4gbmV3IFByb21pc2UoKFgpPT57bGV0IFk9US5vcGVuQ3Vyc29yKCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1ZLnJlc3VsdDtpZihXKXtsZXQgej1XLnZhbHVlO1YucHVzaChiJChMSih6KSkpLFcuY29udGludWUoKX1lbHNlIFMkKFYsJCkudGhlbihYKX0sWS5vbmVycm9yPSgpPT5YKEcoMTgpKX0pfX1mdW5jdGlvbiBKWCgkLEope2lmKCEkLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoZCkpJC5jcmVhdGVPYmplY3RTdG9yZShkLHtrZXlQYXRoOiJlaWQiLGF1dG9JbmNyZW1lbnQ6ITF9KTtsZXQgWj1KLm9iamVjdFN0b3JlKGQpO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoeSQpKVouY3JlYXRlSW5kZXgoeSQsWyJ0eXAiLCJjcmQiXSx7dW5pcXVlOiExfSk7aWYoIVouaW5kZXhOYW1lcy5jb250YWlucyhfSikpWi5jcmVhdGVJbmRleChfSixbInR5cCIsInVwZCJdLHt1bmlxdWU6ITF9KTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKHhKKSlaLmNyZWF0ZUluZGV4KHhKLFsidHlwIiwiZ2lkIl0se3VuaXF1ZTohMX0pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoQkopKVouY3JlYXRlSW5kZXgoQkosWyJ0eXAiLCJwaWQiXSx7dW5pcXVlOiExfSk7aWYoWi5pbmRleE5hbWVzLmNvbnRhaW5zKGUwKSl7aWYoWi5pbmRleChlMCkua2V5UGF0aCE9PSJ0Z3MiKVouZGVsZXRlSW5kZXgoZTApfWlmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoZTApKVouY3JlYXRlSW5kZXgoZTAsInRncyIse3VuaXF1ZTohMSxtdWx0aUVudHJ5OiEwfSl9ZnVuY3Rpb24gWlgoKXtyZXR1cm4gbmV3IFByb21pc2UoKCQsSik9PntsZXQgWj1pbmRleGVkREIub3BlbihKUSxaUSk7Wi5vbnVwZ3JhZGVuZWVkZWQ9KCk9PntsZXR7cmVzdWx0OlEsdHJhbnNhY3Rpb246Vn09WjtpZighVil7SihFcnJvcigiVHJhbnNhY3Rpb24gaXMgbnVsbCBkdXJpbmcgRW50REIgdXBncmFkZSIpKTtyZXR1cm59dHJ5e0pYKFEsVil9Y2F0Y2goWCl7SihYIGluc3RhbmNlb2YgRXJyb3I/WDpFcnJvcihTdHJpbmcoWCkpKX19LFoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gRW50REIgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtKUX0g4oaSIHYke1pRfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LFoub25zdWNjZXNzPSgpPT4kKFoucmVzdWx0KSxaLm9uZXJyb3I9KCk9PkooWi5lcnJvcj8/RXJyb3IoIkVudERCIEluZGV4ZWREQiBvcGVuIGZhaWxlZCIpKX0pfWFzeW5jIGZ1bmN0aW9uIFZRKCl7bGV0ICQ9bmV3IFFRO3JldHVybiBhd2FpdCAkLmluaXQoKSwkfWNsYXNzIGZKe2VudHM9bmV3IE1hcDt1c2VJbmRleDtieVR5cGU9bmV3IE1hcDtieVR5cGVQaWQ9bmV3IE1hcDtieVR5cGVHaWQ9bmV3IE1hcDtieVR5cGVUYWc9bmV3IE1hcDtjb25zdHJ1Y3RvcigkPVtdLEope3RoaXMudXNlSW5kZXg9Sj8uaW5kZXhlcyE9PSExO2ZvcihsZXQgWiBvZiAkKXRoaXMucHV0KFopfXB1dCgkKXtsZXQgSj1CKCQuZWlkKSxaPXRoaXMuZW50cy5nZXQoSik7aWYoWiE9PXZvaWQgMCYmdShaKSl0aGlzLnVuaW5kZXgoSixaKTtpZih0aGlzLmVudHMuc2V0KEosJCksdSgkKSl0aGlzLmluZGV4KEosJCl9ZGVsKCQpe2xldCBKPXRoaXMuZW50cy5nZXQoJCk7aWYoSj09PXZvaWQgMClyZXR1cm47aWYodShKKSl0aGlzLnVuaW5kZXgoJCxKKTt0aGlzLmVudHMuZGVsZXRlKCQpfWluZGV4KCQsSil7aWYoIXRoaXMudXNlSW5kZXgpcmV0dXJuO2xldCBaPXRoaXMuYnlUeXBlLmdldChKLnR5cGUpO2lmKCFaKVo9bmV3IE1hcCx0aGlzLmJ5VHlwZS5zZXQoSi50eXBlLFopO2lmKFouc2V0KCQsSiksSi5waWQpe2xldCBRPUIoSi5waWQpLFY9dGhpcy5ieVR5cGVQaWQuZ2V0KEoudHlwZSk7aWYoIVYpVj1uZXcgTWFwLHRoaXMuYnlUeXBlUGlkLnNldChKLnR5cGUsVik7bGV0IFg9Vi5nZXQoUSk7aWYoIVgpWD1uZXcgTWFwLFYuc2V0KFEsWCk7WC5zZXQoJCxKKX1pZih0eXBlb2YgSi5naWQ9PT0ic3RyaW5nIil7bGV0IFE9dGhpcy5ieVR5cGVHaWQuZ2V0KEoudHlwZSk7aWYoIVEpUT1uZXcgTWFwLHRoaXMuYnlUeXBlR2lkLnNldChKLnR5cGUsUSk7bGV0IFY9US5nZXQoSi5naWQpO2lmKCFWKVY9bmV3IE1hcCxRLnNldChKLmdpZCxWKTtWLnNldCgkLEopfWlmKEoudGFncyl7bGV0IFE9dGhpcy5ieVR5cGVUYWcuZ2V0KEoudHlwZSk7aWYoIVEpUT1uZXcgTWFwLHRoaXMuYnlUeXBlVGFnLnNldChKLnR5cGUsUSk7Zm9yKGxldCBWIG9mIEoudGFncyl7bGV0IFg9US5nZXQoVik7aWYoIVgpWD1uZXcgTWFwLFEuc2V0KFYsWCk7WC5zZXQoJCxKKX19fXVuaW5kZXgoJCxKKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IFo9dGhpcy5ieVR5cGUuZ2V0KEoudHlwZSk7aWYoWil7aWYoWi5kZWxldGUoJCksWi5zaXplPT09MCl0aGlzLmJ5VHlwZS5kZWxldGUoSi50eXBlKX1pZihKLnBpZCl7bGV0IFE9QihKLnBpZCksVj10aGlzLmJ5VHlwZVBpZC5nZXQoSi50eXBlKSxYPVY/LmdldChRKTtpZihYKXtpZihYLmRlbGV0ZSgkKSxYLnNpemU9PT0wKVY/LmRlbGV0ZShRKX1pZihWJiZWLnNpemU9PT0wKXRoaXMuYnlUeXBlUGlkLmRlbGV0ZShKLnR5cGUpfWlmKHR5cGVvZiBKLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoSi50eXBlKSxWPVE/LmdldChKLmdpZCk7aWYoVil7aWYoVi5kZWxldGUoJCksVi5zaXplPT09MClRPy5kZWxldGUoSi5naWQpfWlmKFEmJlEuc2l6ZT09PTApdGhpcy5ieVR5cGVHaWQuZGVsZXRlKEoudHlwZSl9aWYoSi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoSi50eXBlKTtpZihRKXtmb3IobGV0IFYgb2YgSi50YWdzKXtsZXQgWD1RLmdldChWKTtpZihYKXtpZihYLmRlbGV0ZSgkKSxYLnNpemU9PT0wKVEuZGVsZXRlKFYpfX1pZihRLnNpemU9PT0wKXRoaXMuYnlUeXBlVGFnLmRlbGV0ZShKLnR5cGUpfX19Y2xlYXJJbmRleGVzKCl7dGhpcy5ieVR5cGUuY2xlYXIoKSx0aGlzLmJ5VHlwZVBpZC5jbGVhcigpLHRoaXMuYnlUeXBlR2lkLmNsZWFyKCksdGhpcy5ieVR5cGVUYWcuY2xlYXIoKX1idWNrZXRMaXN0KCQpe2lmKCEkfHwkLnNpemU9PT0wKXJldHVybltdO2xldCBKPVtdO2ZvcihsZXQgWiBvZiAkLnZhbHVlcygpKUoucHVzaChaKTtyZXR1cm4gSn1hc3luYyBhcHBseSgkKXtsZXQgSj1uZXcgU2V0LFo9W10sUT1bXTtmb3IobGV0IFYgb2YgJCl7bGV0IFg9QihWLmVpZCksWT10aGlzLmVudHMuZ2V0KFgpLFtXLHpdPUokKFksVik7aWYoeiE9PTApe1EucHVzaCh6KTtjb250aW51ZX1pZihXPT09dm9pZCAwKXtRLnB1c2goMTIpO2NvbnRpbnVlfWZvcihsZXQgSyBvZiBaJChZLFcpKUouYWRkKEspO3RoaXMucHV0KFcpLFoucHVzaChWLmVpZCksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOkosZWlkczpafX1hc3luYyBjbGVhcigpe3JldHVybiB0aGlzLmVudHMuY2xlYXIoKSx0aGlzLmNsZWFySW5kZXhlcygpLDB9YXN5bmMgZ2V0Um93KCQpe2xldCBKPUIoJCksWj10aGlzLmVudHMuZ2V0KEopO3JldHVybiBOKFopfWFzeW5jIGdldEVudCgkKXtsZXRbSixaXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwfHwhdShKKSlyZXR1cm4gTih2b2lkIDApO3JldHVybiBOKEopfWFzeW5jIGdldEFsbEVudGl0aWVzKHt0eXBlOiQsZ2lkOkoscGlkOlosdGFnOlEsdXBkYXRlZEJldHdlZW46Vn0pe2lmKHRoaXMudXNlSW5kZXgpe2lmKFohPT12b2lkIDApe2xldCBZPUIoWik7cmV0dXJuIE4odGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlUGlkLmdldCgkKT8uZ2V0KFkpKSl9aWYoSiE9PXZvaWQgMClyZXR1cm4gTih0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVHaWQuZ2V0KCQpPy5nZXQoSikpKTtpZihRIT09dm9pZCAwKXJldHVybiBOKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZVRhZy5nZXQoJCk/LmdldChRKSkpO2lmKFYhPT12b2lkIDApe2xldCBZPVtdLFc9dGhpcy5ieVR5cGUuZ2V0KCQpO2lmKFcpe2ZvcihsZXQgeiBvZiBXLnZhbHVlcygpKWlmKHoudXBkYXRlZEF0Pj1WLnN0YXJ0JiZ6LnVwZGF0ZWRBdDw9Vi5lbmQpWS5wdXNoKHopfXJldHVybiBOKFkpfXJldHVybiBOKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZS5nZXQoJCkpKX1sZXQgWD1bXTtpZihaIT09dm9pZCAwKXtmb3IobGV0IFkgb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKHUoWSkmJlkudHlwZT09PSQmJlkucGlkJiZuKFkucGlkLFopKVgucHVzaChZKX1lbHNlIGlmKEohPT12b2lkIDApe2ZvcihsZXQgWSBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYodShZKSYmWS50eXBlPT09JCYmKHR5cGVvZiBZLmdpZD09PSJzdHJpbmciJiZZLmdpZD09PUopKVgucHVzaChZKX1lbHNlIGlmKFEhPT12b2lkIDApe2ZvcihsZXQgWSBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYodShZKSYmWS50eXBlPT09JCYmWS50YWdzJiZZLnRhZ3MuaW5jbHVkZXMoUSkpWC5wdXNoKFkpfWVsc2UgaWYoViE9PXZvaWQgMCl7Zm9yKGxldCBZIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZih1KFkpJiZZLnR5cGU9PT0kJiZZLnVwZGF0ZWRBdD49Vi5zdGFydCYmWS51cGRhdGVkQXQ8PVYuZW5kKVgucHVzaChZKX1lbHNlIGZvcihsZXQgWSBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYodShZKSYmWS50eXBlPT09JClYLnB1c2goWSk7cmV0dXJuIE4oWCl9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gTihKKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZih0aGlzLnVzZUluZGV4KXJldHVybiBOKHRoaXMuYnlUeXBlLmdldCgkKT8uc2l6ZT8/MCk7bGV0IEo9MDtmb3IobGV0IFogb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKHUoWikmJloudHlwZT09PSQpSis9MTtyZXR1cm4gTihKKX1hc3luYyBjaGVja3N1bSgkKXtsZXQgSj1bXTtmb3IobGV0IFogb2YgdGhpcy5lbnRzLnZhbHVlcygpKUoucHVzaChiJChaKSk7cmV0dXJuIFMkKEosJCl9fWFzeW5jIGZ1bmN0aW9uIFhRKCQpe2xldCBKPWF3YWl0IFZRKCk7aWYoJD8uY2FjaGU9PT0hMSlyZXR1cm4gSjtyZXR1cm4gbmV3IGtKKEosdm9pZCAwLHtpbmRleGVzOiQ/LmluZGV4ZXN9KX1jbGFzcyBrSnttZW07ZHVyYWJsZTt3YXJtZWQ9bmV3IFNldDtsaXN0ZW5lcnM9bmV3IFNldDtjaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtjb25zdHJ1Y3RvcigkLEosWil7aWYodGhpcy5kdXJhYmxlPSQsdGhpcy5tZW09bmV3IGZKKEo/P1tdLHtpbmRleGVzOlo/LmluZGV4ZXN9KSxKKWZvcihsZXQgUSBvZiBKKXRoaXMud2FybWVkLmFkZChRLnR5cGUpfXN1YnNjcmliZSgkKXtyZXR1cm4gdGhpcy5saXN0ZW5lcnMuYWRkKCQpLCgpPT57dGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQpe2lmKCQuc2l6ZTwxKXJldHVybjtmb3IobGV0IEogb2YgdGhpcy5saXN0ZW5lcnMpSigkKX1ydW4oJCl7bGV0IEo9dGhpcy5jaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuY2hhaW49Si50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLEp9YXBwbHkoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9Pnthd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChYKT0+WC5laWQpKTtsZXQgSj1HWCh0aGlzLm1lbSwkKTt0aGlzLmVtaXQoSi50eXBlcyk7bGV0IFo9YXdhaXQgdGhpcy5kdXJhYmxlLmFwcGx5KCQpLHtjaGFuZ2VkOlEsc3RhdHVzOlZ9PWF3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFgpPT5YLmVpZCkpO2lmKHRoaXMuZW1pdChRKSxWIT09MClyZXR1cm57c3RhdHM6JC5tYXAoKCk9PlYpLHR5cGVzOloudHlwZXMsZWlkczpaLmVpZHN9O3JldHVybiBafSl9Y2xlYXIoKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuZHVyYWJsZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBKPXRoaXMubWVtLmVudHMuc2l6ZT4wO3JldHVybiBhd2FpdCB0aGlzLm1lbS5jbGVhcigpLHRoaXMud2FybWVkLmNsZWFyKCksMH0pfWluZ2VzdEZyb21EdXJhYmxlKCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0e2NoYW5nZWQ6SixzdGF0dXM6Wn09YXdhaXQgdGhpcy5wdWxsRWlkcygkKTtyZXR1cm4gdGhpcy5lbWl0KEopLFp9KX1hc3luYyBwdWxsRWlkcygkKXtsZXQgSj1uZXcgU2V0LFo9bmV3IFNldDtmb3IobGV0IFEgb2YgJCl7bGV0IFY9QihRKTtpZihaLmhhcyhWKSljb250aW51ZTtaLmFkZChWKTtsZXQgWD10aGlzLm1lbS5lbnRzLmdldChWKSxbWSxXXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KFEpO2lmKFchPT0wKXJldHVybntjaGFuZ2VkOkosc3RhdHVzOld9O2lmKFkpe2lmKHRoaXMubWVtLnB1dChZKSwhWHx8IVFYKFgsWSkpe2lmKHUoWSkpSi5hZGQoWS50eXBlKTtpZihYIT09dm9pZCAwJiZ1KFgpKUouYWRkKFgudHlwZSl9fWVsc2UgaWYoWCE9PXZvaWQgMCl7aWYodGhpcy5tZW0uZGVsKFYpLHUoWCkpSi5hZGQoWC50eXBlKX19cmV0dXJue2NoYW5nZWQ6SixzdGF0dXM6MH19YXN5bmMgd2FybVR5cGUoJCl7aWYodGhpcy53YXJtZWQuaGFzKCQpKXJldHVybiAwO2xldFtKLFpdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRFbnRpdGllcyh7dHlwZTokfSk7aWYoWiE9PTApcmV0dXJuIFo7aWYoSilmb3IobGV0IFEgb2YgSil7bGV0IFY9QihRLmVpZCksWD10aGlzLm1lbS5lbnRzLmdldChWKTtpZighWHx8V1goUSxYKSl0aGlzLm1lbS5wdXQoUSl9cmV0dXJuIHRoaXMud2FybWVkLmFkZCgkKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgSj1CKCQpO2lmKHRoaXMubWVtLmVudHMuaGFzKEopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntpZih0aGlzLm1lbS5lbnRzLmhhcyhKKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO2xldFtaLFFdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWil0aGlzLm1lbS5wdXQoWik7cmV0dXJuIE4oWil9KX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IXUoSikpcmV0dXJuIE4odm9pZCAwKTtyZXR1cm4gTihKKX1hc3luYyBnZXRFbnRpdGllcygkKXtpZighdGhpcy53YXJtZWQuaGFzKCQudHlwZSkpe2xldCBKPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQudHlwZSkpO2lmKEohPT0wKXJldHVybiBHKEopfXJldHVybiB0aGlzLm1lbS5nZXRFbnRpdGllcygkKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZighdGhpcy53YXJtZWQuaGFzKCQpKXtsZXQgSj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkKSk7aWYoSiE9PTApcmV0dXJuIEcoSil9cmV0dXJuIHRoaXMubWVtLmNvdW50RW50aXRpZXMoe3R5cGU6JH0pfWFzeW5jIGNoZWNrc3VtKCQpe3JldHVybiB0aGlzLmR1cmFibGUuY2hlY2tzdW0oJCl9fWZ1bmN0aW9uIFFYKCQsSil7aWYodSgkKSE9PXUoSikpcmV0dXJuITE7aWYoJC5jdHIhPT1KLmN0cilyZXR1cm4hMTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCkhPT1KLnVwZGF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoIW4oJC5laWQsSi5laWQpKXJldHVybiExO2lmKCF1KCQpfHwhdShKKSlyZXR1cm4hMDtpZigkLmNyZWF0ZWRBdC5nZXRUaW1lKCkhPT1KLmNyZWF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoJC50eXBlIT09Si50eXBlKXJldHVybiExO2lmKCQuZ2lkIT09Si5naWQpcmV0dXJuITE7aWYoIVhYKCQucGlkLEoucGlkKSlyZXR1cm4hMTtpZighVlgoJC50YWdzLEoudGFncykpcmV0dXJuITE7cmV0dXJuIFlYKCQuYm9keSxKLmJvZHkpfWZ1bmN0aW9uIFZYKCQsSil7aWYoJD09PUopcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Sj09PXZvaWQgMClyZXR1cm4hMTtpZigkLmxlbmd0aCE9PUoubGVuZ3RoKXJldHVybiExO2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKWlmKCRbWl0hPT1KW1pdKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIFhYKCQsSil7aWYoJD09PXZvaWQgMCYmSj09PXZvaWQgMClyZXR1cm4hMDtpZigkPT09dm9pZCAwfHxKPT09dm9pZCAwKXJldHVybiExO3JldHVybiBuKCQsSil9ZnVuY3Rpb24gWVgoJCxKKXtpZihPYmplY3QuaXMoJCxKKSlyZXR1cm4hMDtpZigkIGluc3RhbmNlb2YgVWludDhBcnJheSYmSiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuIG4oJCxKKTtpZigkIGluc3RhbmNlb2YgRGF0ZSYmSiBpbnN0YW5jZW9mIERhdGUpcmV0dXJuICQuZ2V0VGltZSgpPT09Si5nZXRUaW1lKCk7dHJ5e3JldHVybiBuKEUwKCQpLEUwKEopKX1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gV1goJCxKKXtsZXQgWj0kLnVwZGF0ZWRBdC5nZXRUaW1lKCksUT1KLnVwZGF0ZWRBdC5nZXRUaW1lKCk7aWYoWiE9PVEpcmV0dXJuIFo+UTtyZXR1cm4gJC5jdHI+Si5jdHJ9ZnVuY3Rpb24gR1goJCxKKXtsZXQgWj1uZXcgU2V0LFE9W107Zm9yKGxldCBWIG9mIEope2xldCBYPUIoVi5laWQpLFk9JC5lbnRzLmdldChYKSxbVyx6XT1KJChZLFYpO2lmKHohPT0wKXtRLnB1c2goeik7Y29udGludWV9aWYoVz09PXZvaWQgMCl7US5wdXNoKDEyKTtjb250aW51ZX1mb3IobGV0IEsgb2YgWiQoWSxXKSlaLmFkZChLKTskLnB1dChXKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6Wn19ZnVuY3Rpb24gdSgkKXtyZXR1cm4idHlwZSJpbiAkfWZ1bmN0aW9uIHpYKCQpe2lmKCFBcnJheS5pc0FycmF5KCQpfHwkLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPW5ldyBTZXQsWj1bXTtmb3IobGV0IFEgb2YgJCl7aWYodHlwZW9mIFEhPT0ic3RyaW5nInx8US5sZW5ndGg9PT0wKWNvbnRpbnVlO2lmKEouaGFzKFEpKWNvbnRpbnVlO0ouYWRkKFEpLFoucHVzaChRKX1yZXR1cm4gWi5sZW5ndGg+MD9aOnZvaWQgMH1mdW5jdGlvbiBiJCgkKXtyZXR1cm57ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6JC51cGRhdGVkQXR9fWZ1bmN0aW9uIFlRKCQpe2xldCBKPW5ldyBnKCQuZWlkKSxbWixRXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiBOKHtlaWQ6JC5laWQsY3RyOiQuY3RyLHVwZGF0ZWRBdDpuZXcgRGF0ZShaLnRzLmdldFRpbWUoKSskLm9mZil9KX1mdW5jdGlvbiBKJCgkLEope2xldCBaPW5ldyBnKEouZWlkKSxbUSxWXT1aLnJlYWRTdHJ1Y3QoWDApO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBYPW5ldyBEYXRlKFEudHMuZ2V0VGltZSgpK0oub2ZmKTtpZigkIT09dm9pZCAwJiZYPD0kLnVwZGF0ZWRBdClyZXR1cm4gRygxNSk7aWYoJFEoSikpe2xldCBZPXpYKEoudGFncyk7cmV0dXJuIE4oe2VpZDpKLmVpZCxnaWQ6Si5naWQscGlkOkoucGlkLC4uLlkhPT12b2lkIDA/e3RhZ3M6WX06e30sdHlwZTpKLnR5cGUsY3JlYXRlZEF0OlEudHMsdXBkYXRlZEF0OlgsY3RyOkouY3RyLGJvZHk6Si5ib2R5fSl9cmV0dXJuIE4oe2VpZDpKLmVpZCx1cGRhdGVkQXQ6WCxjdHI6Si5jdHJ9KX1mdW5jdGlvbiBaJCgkLEope2xldCBaPW5ldyBTZXQ7aWYoJCE9PXZvaWQgMCYmdSgkKSlaLmFkZCgkLnR5cGUpO2lmKHUoSikpWi5hZGQoSi50eXBlKTtyZXR1cm5bLi4uWl19Y2xhc3MgaCR7aW5mbGlnaHQ9bnVsbDthZ2Fpbj0hMTtydW4oJCl7aWYodGhpcy5hZ2Fpbj0hMCx0aGlzLmluZmxpZ2h0KXJldHVybiB0aGlzLmluZmxpZ2h0O3JldHVybiB0aGlzLmluZmxpZ2h0PXRoaXMuZHJhaW4oJCksdGhpcy5pbmZsaWdodH1hc3luYyBmbHVzaCgpe2lmKCF0aGlzLmluZmxpZ2h0KXJldHVybjt0cnl7YXdhaXQgdGhpcy5pbmZsaWdodH1jYXRjaHt9fWFzeW5jIGRyYWluKCQpe3RyeXt0aGlzLmFnYWluPSExO2xldCBKPWF3YWl0ICQoKTt3aGlsZSh0aGlzLmFnYWluKXRoaXMuYWdhaW49ITEsSj1hd2FpdCAkKCk7cmV0dXJuIEp9ZmluYWxseXt0aGlzLmluZmxpZ2h0PW51bGx9fX12YXIgV1E9MTAwO2NsYXNzIG1Ke3RpbWVyPW51bGw7ZGVsYXlNczt3b3JrO3RhaWw9bmV3IGgkO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5kZWxheU1zPSQ8MD8wOiQsdGhpcy53b3JrPUp9c2NoZWR1bGUoKXtpZih0aGlzLmRlbGF5TXM8PTApe3RoaXMuZmlyZSgpO3JldHVybn1pZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lcik7dGhpcy50aW1lcj1zZXRUaW1lb3V0KCgpPT57dGhpcy50aW1lcj1udWxsLHRoaXMuZmlyZSgpfSx0aGlzLmRlbGF5TXMpfWFzeW5jIGZsdXNoKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKTthd2FpdCB0aGlzLnRhaWwuZmx1c2goKX1jYW5jZWwoKXtpZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj1udWxsfWZpcmUoKXtyZXR1cm4gdGhpcy50YWlsLnJ1bih0aGlzLndvcmspfX1mdW5jdGlvbiBHUSgkKXtsZXQgSj1uZXcgZygkLmVpZCksW1osUV09WDAuZGVjb2RlKEopO2lmKFEhPT0wKXJldHVybjtyZXR1cm4gWi50cy5nZXRUaW1lKCkrJC5vZmZ9ZnVuY3Rpb24gS1goJCxKKXtsZXQgWj1HUSgkKSxRPUdRKEopO2lmKFo9PT12b2lkIDAmJlE9PT12b2lkIDApcmV0dXJuIDA7aWYoWj09PXZvaWQgMClyZXR1cm4gMTtpZihRPT09dm9pZCAwKXJldHVybi0xO2lmKFEhPT1aKXJldHVybiBRLVo7cmV0dXJuIEouY3RyLSQuY3RyfWZ1bmN0aW9uIFEkKCQsSil7cmV0dXJuICQuc2xpY2UoKS5zb3J0KChaLFEpPT5LWChKKFopLEooUSkpKX12YXIgRUo9e3BoYXNlOiJpZGxlIn0scSQ9NTA7ZnVuY3Rpb24gZ0ooJCxKLFope2lmKCQ8PTB8fEo8PTApcmV0dXJuITE7aWYoJD09PTF8fCQ9PT1KKXJldHVybiEwO3JldHVybiAkJVo9PT0wfWZ1bmN0aW9uIHpRKCQsSil7aWYodHlwZW9mIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iPT09ImZ1bmN0aW9uIil7bmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IoJCxKKTtyZXR1cm59bGV0IFo9VVJMLmNyZWF0ZU9iamVjdFVSTCgkKSxRPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTtRLmhyZWY9WixRLmRvd25sb2FkPUosZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChRKSxRLmNsaWNrKCksZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChRKSxVUkwucmV2b2tlT2JqZWN0VVJMKFopfWZ1bmN0aW9uIEtRKCQsSixaKXtsZXQgUT1bXSxWPVtdLFg9MDtmb3IobGV0IFkgb2YgJCl7bGV0IFc9SihZKTtpZihWLmxlbmd0aD4wJiZYK1c+WilRLnB1c2goViksVj1bXSxYPTA7aWYoVi5wdXNoKFkpLFgrPVcsWD49WilRLnB1c2goViksVj1bXSxYPTB9aWYoVi5sZW5ndGg+MClRLnB1c2goVik7cmV0dXJuIFF9YXN5bmMgZnVuY3Rpb24gU0ooJCxKLFope2xldCBRPSQubGVuZ3RoO2lmKFE8MSlyZXR1cm5bXTtsZXQgVj1BcnJheShRKSxYPTAsWT1NYXRoLm1pbihNYXRoLm1heCgxLEopLFEpLFc9YXN5bmMoKT0+e3doaWxlKCEwKXtsZXQgSz1YO2lmKFgrPTEsSz49USlyZXR1cm47VltLXT1hd2FpdCBaKCRbS10sSyl9fSx6PVtdO2ZvcihsZXQgSz0wO0s8WTtLKyspei5wdXNoKFcoKSk7cmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKHopLFZ9YXN5bmMgZnVuY3Rpb24gbCQoJCxKLFosUSl7bGV0IFY9bmV3IGcoJC5oZWFkQ3BoKSxbWCxZXT1WLnJlYWRTdHJ1Y3QoayQpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldHtzaWc6VyxrZG06eixoZWFkQ3BoOkt9PVg7aWYoIWF3YWl0IFEuY2hlY2tTaWdFZDI1NTE5KFcsSyxKKSlyZXR1cm4gRygzKTtsZXQgTz1aLmRlcml2ZUNpcGhlcih6LCJkZWNyeXB0IiksSDt0cnl7SD1hd2FpdCBPLmRlY3J5cHQoSyl9Y2F0Y2h7cmV0dXJuIEcoMjApfXJldHVybiBOKHtrZG06eixoZWFkRW5jOkh9KX12YXIgWCQ9ImYiLHUkPSJ0IixWJD0iZSI7ZnVuY3Rpb24gRlgoJCl7aWYoJD09PSEwfHwkPT09dSQpcmV0dXJuIHUkO2lmKCQ9PT1WJClyZXR1cm4gViQ7cmV0dXJuIFgkfWZ1bmN0aW9uIEZRKCQpe3JldHVybiAkIT09MCYmJCE9PTE1JiYkIT09MTgmJiQhPT0xN31mdW5jdGlvbiB2SigkLEosWil7aWYoJC5hcGxkPUosSj09PVYkJiZaIT09dm9pZCAwKSQuZXJyPVo7ZWxzZSBkZWxldGUgJC5lcnJ9YXN5bmMgZnVuY3Rpb24gaSQoJCxKLFosUSl7bGV0IFY9UT8uYm9keSE9PSExLFg9RlgoSi5hcGxkKSxZPUouYm9keSxXPVk/Lmxlbmd0aD8/MCx6O2lmKFYmJlkmJlc+MCl6PWF3YWl0IFouYmxha2UzKFkpO2xldCBLPXtlaWQ6Si5laWQsb2ZmOkoub2ZmPz8wLGN0cjpKLmN0cj8/MCxsZW46Vyxoc2g6en0sRj17aGFzaDokLGhlYWQ6SyxhcGxkOlh9O2lmKFYmJlkhPT12b2lkIDApRi5ib2R5PVk7aWYoWD09PVYkJiZKLmVyciE9PXZvaWQgMClGLmVycj1KLmVycjtyZXR1cm4gRn12YXIgeUo9MTA0ODU3NixiSj0xMDQ4NTc2LE5RPTY0O2Z1bmN0aW9uIE9YKCQpe3JldHVybiAkLnNpZy5sZW5ndGgrJC5rZG0ubGVuZ3RoKyQuaGVhZENwaC5sZW5ndGgrJC5ib2R5Q3BoLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBOWCgkLEosWixRLFYpe2lmKFEubGVuZ3RoPDEpcmV0dXJuIDA7bGV0W1gsWV09YXdhaXQgJC5wdXNoKFEpO2lmKFkhPT0wKXJldHVybiBZO2lmKCFYKXJldHVybiAyNztmb3IobGV0IHogb2YgWCl7aWYoei5zdGF0dXMhPT0wKXtjb25zb2xlLmVycm9yKCJwdXNoIGVyciIseik7Y29udGludWV9bGV0IEs9Vlt6LmlkeF07aWYoIUspe2NvbnNvbGUuZXJyb3IoIm5vIGhhc2giLHopO2NvbnRpbnVlfWF3YWl0IEoudXBsb2Fkcy5kZXEoWixbS10pfWxldCBXPWF3YWl0IEouaG9zdHMuZ2V0KFopO2lmKFcpe2xldCB6PVcubGFzdFNlcSxLPXosRj1bXTtmb3IobGV0IE8gb2YgWClpZihPLnN0YXR1cz09PTApRi5wdXNoKE8uc2VxKTtGLnNvcnQoKE8sSCk9Pk8tSCk7Zm9yKGxldCBPIG9mIEYpaWYoTz09PXorMSl6PU87aWYoej5LKWF3YWl0IEouaG9zdHMudG91Y2goWix6KX1yZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBPUSgkLEope2lmKEoubGVuZ3RoPDEpcmV0dXJuIE4oW10pO2xldCBaPW5ldyBNYXAsUT1bXTtmb3IobGV0IFcgb2YgSilaLnNldChXLnNlcSxXKSxRLnB1c2goVy5zZXEpO2xldFtWLFhdPWF3YWl0ICQucHVsbChRKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZighVilyZXR1cm4gRygyNyk7bGV0IFk9W107Zm9yKGxldHtzZXE6Vyxib2R5Q3BoOnp9b2YgVil7bGV0IEs9Wi5nZXQoVyk7aWYoIUspY29udGludWU7WS5wdXNoKHtkbDpLLGJvZHlDcGg6en0pfXJldHVybiBOKFkpfWFzeW5jIGZ1bmN0aW9uIEhYKCQsSixaLFEpe2lmKFEubGVuZ3RoPDEpcmV0dXJuIE4oe3BhcnRzOltdLGhhc2hlczpbXX0pO2xldCBWPVtdLFg9W10sWT1bXSxXPW5ldyBNYXA7Zm9yKGxldHtkbDpLLGJvZHlDcGg6Rn1vZiBRKXtsZXR7aGVhZDpPLGtkbTpILHNlcTpSLGhvc3Q6cX09SyxbTSxVXT1hd2FpdCBIUShLLFopO2lmKFUhPT0wfHwhTSl7bGV0IGY9Vy5nZXQocSk/P1tdO2YucHVzaChSKSxXLnNldChxLGYpO2NvbnRpbnVlfWxldHtoZWFkRW5jOlAsaGVhZEVuY0hhc2g6SX09TSxUPUouZGVyaXZlQ2lwaGVyKEgsImRlY3J5cHQiKSxbQyxBXT1hd2FpdCBNSihQLEYsVCxaLEkpO2lmKEEhPT0wfHwhQyl7bGV0IGY9Vy5nZXQocSk/P1tdO2YucHVzaChSKSxXLnNldChxLGYpO2NvbnRpbnVlfWxldCBfPXtoZWFkOk8sYm9keTpDLmJvZH0sRT1DLmhlYWRIYXNoO1kucHVzaCh7a2V5OkUsZGF0YTpNUShfKX0pLFYucHVzaChfKSxYLnB1c2goRSk7bGV0IG09Vy5nZXQocSk/P1tdO20ucHVzaChSKSxXLnNldChxLG0pfWxldCB6PWF3YWl0ICQubWVzc2FnZXMuYWRkKFkpO2ZvcihsZXRbSyxGXW9mIFcpYXdhaXQgJC5kb3dubG9hZHMuZGVxKEssRik7Zm9yKGxldCBLPTA7Szx6Lmxlbmd0aDtLKyspe2xldCBGPXpbS107aWYoRiE9PTAmJkYhPT0xNSljb25zb2xlLmVycm9yKCJFUlIgc3RvcmluZyIsd1tGXSwiZm9yIG1lc3NhZ2UiLEspfXJldHVybiBOKHtwYXJ0czpWLGhhc2hlczpYfSl9YXN5bmMgZnVuY3Rpb24gSFEoJCxKKXtsZXQgWj0kLmhlYWRFbmM7aWYoIVope2xldCBWPW5ldyBTLFg9Vi53cml0ZVN0cnVjdCh6MCwkLmhlYWQpO2lmKFghPT0wKXJldHVybiBHKFgpO1o9Vi5yZXN1bHQoKX1pZigkLmhlYWRFbmNIYXNoKXJldHVybiBOKHtoZWFkRW5jOlosaGVhZEVuY0hhc2g6JC5oZWFkRW5jSGFzaH0pO2xldCBRPWF3YWl0IEouYmxha2UzKFopO3JldHVybiBOKHtoZWFkRW5jOlosaGVhZEVuY0hhc2g6UX0pfWFzeW5jIGZ1bmN0aW9uIFJRKCQsSixaKXtsZXQgUT1uZXcgU2V0O2ZvcihsZXQgWSBvZiBKKVEuYWRkKEIoWSkpO2lmKFEuc2l6ZTwxKXJldHVybjtsZXQgVj1BcnJheS5mcm9tKGF3YWl0ICQuZG93bmxvYWRzLmxpc3QoKSk7aWYoVi5sZW5ndGg8MSlyZXR1cm47bGV0IFg9bmV3IE1hcDtmb3IobGV0IFkgb2YgVil7bGV0IFc7aWYoWS5oZWFkRW5jSGFzaClXPUIoWS5oZWFkRW5jSGFzaCk7ZWxzZXtsZXRbSyxGXT1hd2FpdCBIUShZLFopO2lmKEYhPT0wfHwhSyljb250aW51ZTtXPUIoSy5oZWFkRW5jSGFzaCl9aWYoIVEuaGFzKFcpKWNvbnRpbnVlO2xldCB6PVguZ2V0KFkuaG9zdCk/P1tdO3oucHVzaChZLnNlcSksWC5zZXQoWS5ob3N0LHopfWZvcihsZXRbWSxXXW9mIFgpYXdhaXQgJC5kb3dubG9hZHMuZGVxKFksVyl9YXN5bmMgZnVuY3Rpb24gaEooe2Nvbm46JCxzdG9yZTpKLGVuY2xhdmU6Wixob3N0OlEsY3J5cHRvOlYsb25Qcm9ncmVzczpYLHBlZWtQcm9ncmVzc0V2ZXJ5OlkscGVla0NvbmN1cnJlbmN5Old9KXtsZXQgej1hd2FpdCAkLmlkZW50aXR5KCksSz1bXSxbRixPXT1hd2FpdCAkLnBlZWsoUS5sYXN0U2VxKTtpZihPIT09MClyZXR1cm4gTztsZXQgSD1GLmxlbmd0aCxSPVk/P3EkLHE9Vz8/TlE7aWYoWCYmSD4wKVgoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTowLHRvdGFsOkh9KTtsZXQgTT0wLFU9YXdhaXQgU0ooRixxLGFzeW5jKEkpPT57bGV0W1QsQ109YXdhaXQgbCQoSSx6LnB1YmxpY0tleSxaLFYpLEE7aWYoQyE9PTB8fCFUKUE9e29rOiExLHNlcTpJLnNlcSxzdGF0OkN9O2Vsc2V7bGV0IF89YXdhaXQgVi5ibGFrZTMoVC5oZWFkRW5jKTtBPXtvazohMCxzZXE6SS5zZXEsa2RtOlQua2RtLGhlYWRFbmM6VC5oZWFkRW5jLGhlYWRFbmNIYXNoOl99fWlmKE0rPTEsWCYmZ0ooTSxILFIpKVgoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTpNLHRvdGFsOkh9KTtyZXR1cm4gQX0pLFA9bmV3IFNldDtmb3IobGV0IEkgb2YgVSl7aWYoIUkub2spe2NvbnNvbGUuZXJyb3IoInBlZWs6IGRlY3J5cHRpbmcgaXRlbSBoZWFkIixJLnN0YXQpO2NvbnRpbnVlfWxldCBUPUIoSS5oZWFkRW5jSGFzaCk7aWYoYXdhaXQgSi5tZXNzYWdlcy5oYXMoSS5oZWFkRW5jSGFzaCkpe2NvbnNvbGUuaW5mbygicGVlazogbG9jYWwgbXNnOyBza2lwIGRvd25sb2FkLCBkZXEgdXBsb2FkIiksYXdhaXQgSi51cGxvYWRzLmRlcShRLmxhYmVsLFtJLmhlYWRFbmNIYXNoXSksYXdhaXQgSi5kb3dubG9hZHMuZGVxKFEubGFiZWwsW0kuc2VxXSk7Y29udGludWV9aWYoUC5oYXMoVCkpe2F3YWl0IEouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtJLnNlcV0pO2NvbnRpbnVlfWxldCBBPW5ldyBnKEkuaGVhZEVuYyksW18sRV09QS5yZWFkU3RydWN0KHowKTtpZihFIT09MCl7Y29uc29sZS5lcnJvcigicGVlazogcmVhZGluZyBpdGVtIGhlYWQiLEUpO2NvbnRpbnVlfVAuYWRkKFQpLEsucHVzaCh7a2RtOkkua2RtLGhlYWQ6XyxzZXE6SS5zZXEsaG9zdDpRLmxhYmVsLGhlYWRFbmM6SS5oZWFkRW5jLGhlYWRFbmNIYXNoOkkuaGVhZEVuY0hhc2h9KX1pZihhd2FpdCBKLmRvd25sb2Fkcy5lbnEoSyksRi5sZW5ndGg+MCl7bGV0IEk9TWF0aC5tYXgoLi4uRi5tYXAoKFQpPT5ULnNlcSkpO2F3YWl0IEouaG9zdHMucmVjb3JkU3RhdHMoUS5sYWJlbCx7bGFzdFNlcTpJfSl9aWYoWClYKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6SCx0b3RhbDpIfSk7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gcVEoe2Nvbm46JCxzdG9yZTpKLGhvc3Q6WixtYXhQdXNoQnl0ZXM6USxvblByb2dyZXNzOlZ9KXtsZXQgWD1RPz95SixZPWF3YWl0IEoudXBsb2Fkcy5saXN0KFoubGFiZWwpLFc9WS5sZW5ndGgsej0wO2lmKFYmJlc+MClWKHtwaGFzZToicHVzaCIsaG9zdDpaLmxhYmVsLGRvbmU6MCx0b3RhbDpXfSk7bGV0IEs9W10sRj1bXSxPPTAsSD1hc3luYygpPT57aWYoSy5sZW5ndGg8MSlyZXR1cm4gMDtsZXQgUj1LLmxlbmd0aCxxPWF3YWl0IE5YKCQsSixaLmxhYmVsLEssRik7aWYoSz1bXSxGPVtdLE89MCxxPT09MCl7aWYoeis9UixWKVYoe3BoYXNlOiJwdXNoIixob3N0OloubGFiZWwsZG9uZTp6LHRvdGFsOld9KX1yZXR1cm4gcX07Zm9yKGxldCBSIG9mIFkpe2xldCBxPWF3YWl0IEoubWVzc2FnZXMuZ2V0KFIpO2lmKCFxKXt6Kz0xO2NvbnRpbnVlfWxldCBNPXsuLi5xLmhlYWQsYm9kOnEuYm9keX0sW1UsUF09YXdhaXQgJC5zZWFsKE0pO2lmKFAhPT0wKXJldHVybiBQO2lmKCFVKXJldHVybiAxMjtsZXQgST1PWChVKTtpZihLLmxlbmd0aD4wJiZPK0k+WCl7bGV0IFQ9YXdhaXQgSCgpO2lmKFQhPT0wKXJldHVybiBUfWlmKEsucHVzaChVKSxGLnB1c2goUiksTys9SSxPPj1YKXtsZXQgVD1hd2FpdCBIKCk7aWYoVCE9PTApcmV0dXJuIFR9fXJldHVybiBIKCl9YXN5bmMgZnVuY3Rpb24gbEooe2Nvbm46JCxzdG9yZTpKLGVuY2xhdmU6Wixob3N0OlEsY3J5cHRvOlYsbWF4UHVsbEJ5dGVzOlgsb25Qcm9ncmVzczpZfSxXKXtsZXQgej1YPz9iSixLPWF3YWl0IEouZG93bmxvYWRzLmxpc3QoKSxGPUFycmF5LmZyb20oSykuZmlsdGVyKChVKT0+VS5ob3N0PT09US5sYWJlbCk7aWYoRi5sZW5ndGg8MSlyZXR1cm4gMTU7bGV0IE89USQoRiwoVSk9PlUuaGVhZCksSD1LUShPLChVKT0+VS5oZWFkLmxlbix6KSxSPU8ubGVuZ3RoLHE9MDtpZihZKVkoe3BoYXNlOiJwdWxsIixob3N0OlEubGFiZWwsZG9uZTowLHRvdGFsOlJ9KTtsZXQgTT1PUSgkLEhbMF0pO2ZvcihsZXQgVT0wO1U8SC5sZW5ndGg7VSsrKXtsZXRbUCxJXT1hd2FpdCBNO2lmKEkhPT0wfHwhUClyZXR1cm4gSTtpZihxKz1IW1VdLmxlbmd0aCxZKVkoe3BoYXNlOiJwdWxsIixob3N0OlEubGFiZWwsZG9uZTpxLHRvdGFsOlJ9KTtsZXQgVD1IW1UrMV07aWYoVClNPU9RKCQsVCk7aWYoWSlZKHtwaGFzZToib3BlbiIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpSfSk7bGV0IEM9USQoUCwoXyk9Pl8uZGwuaGVhZCksWyxBXT1hd2FpdCBIWChKLFosVixDKTtpZihBIT09MClyZXR1cm4gQTtpZihXKXtpZihZKVkoe3BoYXNlOiJleGVjIixob3N0OlEubGFiZWwsZG9uZTpxLHRvdGFsOlJ9KTthd2FpdCBXKCl9fXJldHVybiAwfWZ1bmN0aW9uIE1RKHtoZWFkOiQsYm9keTpKfSl7bGV0IFo9e2VpZDokLmVpZCxib2R5OkosYXBsZDpYJH07aWYoJC5vZmYhPT0wKVoub2ZmPSQub2ZmO2lmKCQuY3RyIT09MClaLmN0cj0kLmN0cjtyZXR1cm4gWn1hc3luYyBmdW5jdGlvbiBVUSgkLHtjb25uOkosc3RvcmU6WixlbmNsYXZlOlEsaG9zdDpWLGNyeXB0bzpYLG9uUHJvZ3Jlc3M6WX0sVyl7bGV0IHo9Vi5sYWJlbCxLPWF3YWl0IEouaWRlbnRpdHkoKSxGPW5ldyBnKCQpLFtPLEhdPUYucmVhZFN0cnVjdHMoZiQpO2lmKEghPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjb2Rpbmcgbm90aWYiLHdbSF0pO3JldHVybn1sZXQgUj0hMSxNPShhd2FpdCBaLmhvc3RzLmdldCh6KSk/Lmxhc3RTZXEsVT1bXSxQPSExO2ZvcihsZXQgQyBvZiBPKXtsZXRbQSxfXT1hd2FpdCBsJCh7c2VxOkMuc2VxLGhlYWRDcGg6Qy5oZWFkQ3BofSxLLnB1YmxpY0tleSxRLFgpO2lmKF8hPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjcnlwdGluZyBub3RpZiIsd1tfXSk7Y29udGludWV9bGV0IEU9YXdhaXQgWC5ibGFrZTMoQS5oZWFkRW5jKTtpZihhd2FpdCBaLm1lc3NhZ2VzLmhhcyhFKSljb250aW51ZTtsZXQgbT1uZXcgZyhBLmhlYWRFbmMpLFtmLHldPW0ucmVhZFN0cnVjdCh6MCk7aWYoeSE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBwYXJzZSBoZWFkIix3W3ldKTtjb250aW51ZX1pZighQy5ib2R5Q3BoJiZmLmxlbj4wKVA9ITAsYXdhaXQgWi5kb3dubG9hZHMuZW5xKFt7c2VxOkMuc2VxLGhvc3Q6eixrZG06QS5rZG0saGVhZDpmLGhlYWRFbmM6QS5oZWFkRW5jLGhlYWRFbmNIYXNoOkV9XSk7ZWxzZSBVLnB1c2goey4uLkEsaGVhZDpmLGJvZHlDcGg6Qy5ib2R5Q3BoLGhlYWRFbmNIYXNoOkV9KTtpZihNPT09dm9pZCAwfHxDLnNlcSE9PU0rMSljb25zb2xlLmxvZygib3V0IG9mIHNlcSIsQy5zZXEsTSksUj0hMDtlbHNlIE09Qy5zZXF9aWYoTSE9PXZvaWQgMClhd2FpdCBaLmhvc3RzLnRvdWNoKFYubGFiZWwsTSk7bGV0IEk9W107Zm9yKGxldCBDIG9mIFUpe2xldCBBPVEuZGVyaXZlQ2lwaGVyKEMua2RtLCJkZWNyeXB0IiksW18sRV09YXdhaXQgTUooQy5oZWFkRW5jLEMuYm9keUNwaCxBLFgpO2lmKEUhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gb3BlbiBib2R5Iix3W0VdKTtjb250aW51ZX1JLnB1c2goe2tleTpDLmhlYWRFbmNIYXNoLGRhdGE6TVEoe2hlYWQ6Qy5oZWFkLGJvZHk6Xy5ib2R9KX0pfWxldCBUPWF3YWl0IFoubWVzc2FnZXMuYWRkKEkpO2ZvcihsZXQgQz0wO0M8VC5sZW5ndGg7QysrKXtsZXQgQT1UW0NdO2lmKEEhPT0wJiZBIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLHdbQV0sImZvciBtZXNzYWdlIixDKX1pZihZJiZJLmxlbmd0aD4wKVkoe3BoYXNlOiJvcGVuIixob3N0OlYubGFiZWwsZG9uZTpJLmxlbmd0aCx0b3RhbDpJLmxlbmd0aH0pO2lmKFJ8fFB8fEkubGVuZ3RoPjApVygpfWFzeW5jIGZ1bmN0aW9uIHVKKCQsSj17fSl7bGV0IFo9Si5wdWxsIT09ITEsUT1KLnB1c2g9PT0hMCx7Y29ubjpWLHN0b3JlOlgsZW5jbGF2ZTpZLGhvc3Q6VyxjcnlwdG86eixvblByb2dyZXNzOksscGVla1Byb2dyZXNzRXZlcnk6RixwZWVrQ29uY3VycmVuY3k6T309JCxIPWF3YWl0IFYuaWRlbnRpdHkoKSxbUixxXT1hd2FpdCBWLnBlZWsoMCk7aWYocSE9PTApcmV0dXJuIEcocSk7bGV0IE09Ui5sZW5ndGgsVT1GPz9xJCxQPU8/P05RO2lmKEsmJk0+MClLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6MCx0b3RhbDpNfSk7bGV0IEk9MCxUPWF3YWl0IFNKKFIsUCxhc3luYyh4KT0+e2xldFt2LGtdPWF3YWl0IGwkKHgsSC5wdWJsaWNLZXksWSx6KSxsO2lmKGshPT0wfHwhdilsPXtvazohMSxzZXE6eC5zZXEsc3RhdDprfTtlbHNle2xldCBMPWF3YWl0IHouYmxha2UzKHYuaGVhZEVuYyk7bD17b2s6ITAsc2VxOnguc2VxLGtkbTp2LmtkbSxoZWFkRW5jOnYuaGVhZEVuYyxoZWFkRW5jSGFzaDpMfX1pZihJKz0xLEsmJmdKKEksTSxVKSlLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6SSx0b3RhbDpNfSk7cmV0dXJuIGx9KSxDPW5ldyBNYXA7Zm9yKGxldCB4IG9mIFQpe2lmKCF4Lm9rKWNvbnRpbnVlO2xldCB2PUIoeC5oZWFkRW5jSGFzaCksaz1DLmdldCh2KTtpZihrKWsuY291bnQrPTE7ZWxzZSBDLnNldCh2LHtoYXNoOnguaGVhZEVuY0hhc2gsY291bnQ6MSxzYW1wbGU6eH0pfWxldCBBPTAsXz1bXTtmb3IobGV0IHggb2YgQy52YWx1ZXMoKSl7aWYoeC5jb3VudD4xKUErPXguY291bnQtMTtfLnB1c2goeC5oYXNoKX1sZXQgRT1SLmxlbmd0aCxtPUMuc2l6ZSxmPWF3YWl0IFIkKF8seikseT1bXSxoPTA7Zm9yKGxldCB4IG9mIEMudmFsdWVzKCkpe2lmKGF3YWl0IFgubWVzc2FnZXMuaGFzKHguaGFzaCkpe2F3YWl0IFgudXBsb2Fkcy5kZXEoVy5sYWJlbCxbeC5oYXNoXSk7Y29udGludWV9aWYoaCs9MSwhWiljb250aW51ZTtsZXQgaz14LnNhbXBsZSxsPW5ldyBnKGsuaGVhZEVuYyksW0wscl09bC5yZWFkU3RydWN0KHowKTtpZihyIT09MCl7Y29uc29sZS5lcnJvcigicmVjb25jaWxlOiByZWFkaW5nIG1zZyBoZWFkZXIiLHIpO2NvbnRpbnVlfXkucHVzaCh7a2RtOmsua2RtLGhlYWQ6TCxzZXE6ay5zZXEsaG9zdDpXLmxhYmVsLGhlYWRFbmM6ay5oZWFkRW5jLGhlYWRFbmNIYXNoOmsuaGVhZEVuY0hhc2h9KX1pZih5Lmxlbmd0aD4wKWF3YWl0IFguZG93bmxvYWRzLmVucSh5KTtsZXQgaT0wO2lmKFEpe2xldCB4PWF3YWl0IFgubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoQy5rZXlzKCkpLGs9W107Zm9yKGxldCBsIG9mIHgpaWYoIXYuaGFzKEIobCkpKWkrPTEsay5wdXNoKGwpO2lmKGsubGVuZ3RoPjApYXdhaXQgWC51cGxvYWRzLmVucShXLmxhYmVsLGspfWVsc2V7bGV0IHg9YXdhaXQgWC5tZXNzYWdlcy5saXN0S2V5cygpLHY9bmV3IFNldChDLmtleXMoKSk7Zm9yKGxldCBrIG9mIHgpaWYoIXYuaGFzKEIoaykpKWkrPTF9bGV0IGo9Ui5sZW5ndGg+MD9NYXRoLm1heCguLi5SLm1hcCgoeCk9Pnguc2VxKSk6MDtpZihhd2FpdCBYLmhvc3RzLnJlY29yZFN0YXRzKFcubGFiZWwse3NldExhc3RTZXE6an0pLEspSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOk0sdG90YWw6TX0pO3JldHVybiBOKHttc2djaGVjazpmLG51bUJhZ3M6RSx1bmlxdWVNc2dzOm0sbnVtRHVwZXM6QSxtaXNzaW5nTG9jYWw6aCxtaXNzaW5nSG9zdDppfSl9Y2xhc3MgaUp7Y2xvY2s7c3RhdGU7c3RvcmU7dHJhbnNwb3J0O2NyeXB0bztmb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdDtvblNjaGVkdWxlU3luYztjb25uZWN0aW9ucz1uZXcgTWFwO2FwcGx5Q2hhaW49UHJvbWlzZS5yZXNvbHZlKCk7c3luY1J1bnM9bmV3IGgkO2NsaWVudFN0YXRlO3hmZXJTdGF0ZTttYXhQdXNoQnl0ZXM7bWF4UHVsbEJ5dGVzO3BlZWtQcm9ncmVzc0V2ZXJ5PXEkO2xhc3RQcm9ncmVzcz1FSjtzY2hlZHVsZWRTeW5jO2NvbnN0cnVjdG9yKCQsSixaLFEsVixYPSEwLFk9eUosVz1iSix6KXt0aGlzLmNsb2NrPSQ7dGhpcy5zdGF0ZT1KO3RoaXMuc3RvcmU9Wjt0aGlzLnRyYW5zcG9ydD1RO3RoaXMuY3J5cHRvPVY7dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdD1YO3RoaXMub25TY2hlZHVsZVN5bmM9ejt0aGlzLm1heFB1c2hCeXRlcz1ZLHRoaXMubWF4UHVsbEJ5dGVzPVcsdGhpcy5jbGllbnRTdGF0ZT1uZXcgZzAoKCk9PnRoaXMuZ2V0Q2xpZW50U3RhdGUoKSksdGhpcy54ZmVyU3RhdGU9bmV3IGcwKCgpPT50aGlzLmdldFhmZXJTdGF0ZSgpKSx0aGlzLnNjaGVkdWxlZFN5bmM9bmV3IG1KKFdRLGFzeW5jKCk9Pnt0cnl7Y29uc29sZS5pbmZvKCJSdW5uaW5nIHNjaGVkdWxlZCBzeW5jIiksYXdhaXQgdGhpcy5zeW5jKCl9Y2F0Y2goSyl7Y29uc29sZS5lcnJvcigiRGVib3VuY2VkIHN5bmMgZmFpbGVkOiIsSyl9fSl9ZW1pdFByb2dyZXNzPSgkKT0+e3RoaXMubGFzdFByb2dyZXNzPSQsdGhpcy54ZmVyU3RhdGUuZW1pdCgpfTthc3luYyBzZXRTZWVkKCQsSil7YXdhaXQgdGhpcy5zdG9yZS5zZWVkLnNhdmUoJCxKKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBnZXRDbGllbnRTdGF0ZSgpe2xldHtzdG9yZTokLGNvbm5lY3Rpb25zOkp9PXRoaXMsWj1hd2FpdCAkLnNlZWQubG9hZCgpLFE9YXdhaXQgJC5ob3N0cy5saXN0KCksVj0hMTtmb3IobGV0IFggb2YgSi52YWx1ZXMoKSlpZihYLmlzQ29ubmVjdGVkKCkpe1Y9ITA7YnJlYWt9cmV0dXJue2hhc1NlZWQ6WiE9PXZvaWQgMCxoYXNIb3N0OkFycmF5LmZyb20oUSkubGVuZ3RoPjAsY29ubmVjdGVkOlZ9fWFzeW5jIGdldFhmZXJTdGF0ZSgpe2xldHt1cGxvYWRzOiQsZG93bmxvYWRzOkp9PXRoaXMuc3RvcmUsWj1hd2FpdCAkLmNvdW50KCk7cmV0dXJue251bURvd25sb2Fkczphd2FpdCBKLmNvdW50KCksbnVtVXBsb2FkczpaLHByb2dyZXNzOnRoaXMubGFzdFByb2dyZXNzfX1hcHBseT0oJCxKKT0+e3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0FwcGx5KCQsSikpfTthc3luYyBkb0FwcGx5KCQsSj17ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiEwfSl7bGV0IFo9W10sUT1bXTtmb3IobGV0e2hlYWQ6WCxib2R5Oll9b2YgJCl7bGV0IFc9bmV3IFM7Vy53cml0ZVN0cnVjdCh6MCxYKTtsZXQgej1XLnJlc3VsdCgpLEs9YXdhaXQgdGhpcy5jcnlwdG8uYmxha2UzKHopLEY9e2VpZDpYLmVpZCxib2R5OlksYXBsZDpYJH07aWYoWC5vZmYhPT0wKUYub2ZmPVgub2ZmO2lmKFguY3RyIT09MClGLmN0cj1YLmN0cjtaLnB1c2goSyksUS5wdXNoKHtrZXk6SyxkYXRhOkZ9KX1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmFkZChRKSxhd2FpdCBSUSh0aGlzLnN0b3JlLFosdGhpcy5jcnlwdG8pO2xldCBWPWF3YWl0IHRoaXMuZG9BcHBseUhhc2hlcyhaKTtpZihKLmVucXVldWVVcGxvYWQpe2xldCBYPVtdO2ZvcihsZXQgWT0wO1k8Wi5sZW5ndGg7WSsrKXtsZXQgVz1WW1ldO2lmKFc9PT0wfHxXPT09MTUpWC5wdXNoKFpbWV0pfWlmKFgubGVuZ3RoPjApe2xldCBZPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpO2ZvcihsZXQgVyBvZiBZKWF3YWl0IHRoaXMuc3RvcmUudXBsb2Fkcy5lbnEoVy5sYWJlbCxYKTt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9fWlmKEoudHJpZ2dlclVwbG9hZCl0aGlzLnNjaGVkdWxlU3luYygpO3JldHVybiBWfWVucXVldWVBcHBseUpvYigkKXtsZXQgSj10aGlzLmFwcGx5Q2hhaW4udGhlbigkLCQpO3JldHVybiB0aGlzLmFwcGx5Q2hhaW49Si50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLEp9ZHJhaW5BcHBseVF1ZXVlKCl7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvRHJhaW5BcHBseVF1ZXVlKCkpfWFzeW5jIGRvRHJhaW5BcHBseVF1ZXVlKCl7bGV0ICQ9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KHthcGxkOlgkfSk7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgSj1RJCgkLChaKT0+Wi5oZWFkKTtyZXR1cm4gdGhpcy5hcHBseVN0b3JlZChKKX1hcHBseUhhc2hlcz0oJCk9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseUhhc2hlcygkKSl9O2FzeW5jIGRvQXBwbHlIYXNoZXMoJCl7bGV0IEo9W107Zm9yKGxldCBWIG9mICQpe2xldCBYPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMuZ2V0KFYpO2lmKFgpSi5wdXNoKFgpfWxldCBaPWF3YWl0IHRoaXMuYXBwbHlTdG9yZWQoSiksUT1uZXcgTWFwO2ZvcihsZXQgVj0wO1Y8Si5sZW5ndGg7VisrKVEuc2V0KEIoSltWXS5oYXNoKSxaW1ZdPz8xMik7cmV0dXJuICQubWFwKChWKT0+US5nZXQoQihWKSk/PzEzKX1hc3luYyBhcHBseVN0b3JlZCgkKXtpZigkLmxlbmd0aDwxKXJldHVybltdO2xldCBKPSQubWFwKChYKT0+KHsuLi5YLmhlYWQsYm9kOlguYm9keX0pKSxaPWF3YWl0IHRoaXMuc3RhdGUuYXBwbHkoSiksUT1bXSxWPVtdO2ZvcihsZXQgWD0wO1g8JC5sZW5ndGg7WCsrKXtsZXQgWT1aW1hdO2lmKFk9PT0wfHxZPT09MTUpUS5wdXNoKCRbWF0uaGFzaCk7ZWxzZSBpZihZIT09dm9pZCAwJiZGUShZKSlWLnB1c2goe2tleTokW1hdLmhhc2gsZXJyOll9KX1pZihRLmxlbmd0aD4wKWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubWFya0FwcGxpZWQoUSk7aWYoVi5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtGYWlsZWQoVik7cmV0dXJuIFp9YXN5bmMgaW5zZXJ0UmF3KCQpe2xldHtjbG9jazpKLGNyeXB0bzpafT10aGlzLFtRLFZdPWF3YWl0IHRaKHtub3c6Si5ub3coKSxib2Q6JCxjcnlwdG86Wn0pO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBZPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpRLGJvZHk6JH1dKSlbMF07aWYoWSE9PTAmJlkhPT0xNSlyZXR1cm4gRyhZPz8xMik7cmV0dXJuIE4oUSl9YXN5bmMgbWFrZVVwZGF0ZSgkLEope2xldHtjbG9jazpaLGNyeXB0bzpRfT10aGlzLFY9Wi5ub3coKTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCk+Vi5nZXRUaW1lKCkpcmV0dXJuIEcoNCk7bGV0IFg9JC5jdHIrMSxbWSxXXT1hd2FpdCBnJCh7bm93OlYsZWlkOiQuZWlkLGN0cjpYLGJvZDpKLGNyeXB0bzpRfSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7cmV0dXJuIE4oe2hlYWQ6WSxib2R5Okp9KX1hc3luYyB1cGRhdGVXaXRoU2tldygkLEosWil7aWYoWj09PSExKXJldHVybiBHKDQpO2xldHtjbG9jazpRLGNyeXB0bzpWfT10aGlzLFg9US5ub3coKSxZPW5ldyBnKCQuZWlkKSxbVyx6XT1ZLnJlYWRTdHJ1Y3QoWDApO2lmKHohPT0wKXJldHVybiBHKHopO2xldCBLPSQudXBkYXRlZEF0LmdldFRpbWUoKS1XLnRzLmdldFRpbWUoKSxGPXtlaWQ6JC5laWQsb2ZmOksrMSxjdHI6JC5jdHIrMSxsZW46MH0sSD0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6Rixib2R5OnZvaWQgMH1dKSlbMF07aWYoSCE9PTAmJkghPT0xNSlyZXR1cm4gRyhIPz8xMik7aWYoSj09PXZvaWQgMClyZXR1cm4gTihGKTtsZXRbUixxXT1CJCh7aWQ6Vy5pZCx0czpYfSk7aWYocSE9PTApcmV0dXJuIEcocSk7bGV0W00sVV09YXdhaXQgZyQoe25vdzpYLGVpZDpSLGN0cjowLGJvZDpKLGNyeXB0bzpWfSk7aWYoVSE9PTApcmV0dXJuIEcoVSk7bGV0IEk9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOk0sYm9keTpKfV0pKVswXTtpZihJIT09MCYmSSE9PTE1KXJldHVybiBHKEk/PzEyKTtyZXR1cm4gTihNKX1hc3luYyB1cGRhdGVSYXcoJCxKLFo9dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdCl7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPnRoaXMuY2xvY2subm93KCkuZ2V0VGltZSgpKXJldHVybiB0aGlzLnVwZGF0ZVdpdGhTa2V3KCQsSixaKTtyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoYXN5bmMoKT0+e2xldFtRLFZdPWF3YWl0IHRoaXMubWFrZVVwZGF0ZSgkLEopO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBZPShhd2FpdCB0aGlzLmRvQXBwbHkoW1FdKSlbMF07aWYoWSE9PTAmJlkhPT0xNSlyZXR1cm4gRyhZPz8xMik7cmV0dXJuIE4oUS5oZWFkKX0pfWFzeW5jIGluc2VydCgkKXtsZXR7Ym9keTpKLHR5cGU6WixnaWQ6USxwaWQ6Vix0YWdzOlh9PSQsVz1FMCh7Ym9keTpKLHR5cGU6WixnaWQ6USxwaWQ6Vix0YWdzOlh9KTtyZXR1cm4gdGhpcy5pbnNlcnRSYXcoVyl9YXN5bmMgdXBkYXRlKCQpe2xldHtwcmlvcjpKLGJvZHk6Wix0eXBlOlEsZ2lkOlYscGlkOlgsdGFnczpZLGZvcmNlOld9PSQsSz1FMCh7Ym9keTpaLHR5cGU6USxnaWQ6VixwaWQ6WCx0YWdzOll9KTtyZXR1cm4gdGhpcy51cGRhdGVSYXcoSixLLFc/P3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpfWFzeW5jIGRlbGV0ZSgkKXtsZXQgSj0kLmZvcmNlPz8hMDtpZigicHJpb3IiaW4gJClyZXR1cm4gdGhpcy51cGRhdGVSYXcoJC5wcmlvcix2b2lkIDAsSik7bGV0W1osUV09YXdhaXQgdGhpcy5yZXZGcm9tQXJjaGl2ZSgkLmVpZCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KFosdm9pZCAwLEopfWFzeW5jIHJldkZyb21BcmNoaXZlKCQpe2xldCBKPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGFzdCgkKTtpZihKKXJldHVybiBZUShKLmhlYWQpO2xldCBaPW5ldyBnKCQpLFtRLFZdPVoucmVhZFN0cnVjdChYMCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIE4oe2VpZDokLGN0cjotMSx1cGRhdGVkQXQ6US50c30pfWFzeW5jIGdlbkVJRCgkKXtsZXR7Y2xvY2s6SixjcnlwdG86Wn09dGhpcyxRPUoubm93KCk7aWYoJCE9PXZvaWQgMClyZXR1cm4gQiQoe2lkOiQsdHM6UX0pO2xldCBWPWF3YWl0IFouZ2VuUmFuZG9tQnl0ZXMoOCk7cmV0dXJuIEIkKHtpZDpWLHRzOlF9KX1zeW5jKCl7cmV0dXJuIHRoaXMuc3luY1J1bnMucnVuKCgpPT50aGlzLmRvU3luYygpKX1hc3luYyBkb1N5bmMoKXtsZXR7Y29ubmVjdGlvbnM6JCxjcnlwdG86SixzdG9yZTpafT10aGlzLFE9YXdhaXQgWi5zZWVkLmxvYWQoKTtpZighUSlyZXR1cm4gMjI7YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtmb3IobGV0W1YsWF1vZiAkKXtsZXQgWT1hd2FpdCBaLmhvc3RzLmdldChWKTtpZighWSljb250aW51ZTtsZXQgVz17Y29ubjpYLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6WSxjcnlwdG86SixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sej1hd2FpdCBoSihXKTtpZih6IT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHBlZWs6ICR7en1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksejt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEs9YXdhaXQgcVEoVyk7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwdXNoOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IGxKKFcsYXN5bmMoKT0+e2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCl9KTtpZihGIT09MCYmRiE9PTE1KXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVsbDogJHtGfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxGO3RoaXMueGZlclN0YXRlLmVtaXQoKX1yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgcmVidWlsZCgkKXtpZih0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpLCQ/LmNoZWNrSG9zdD8/ITApe2xldCBaPWF3YWl0IHRoaXMucmVwdWxsKCk7aWYoWiE9PTApcmV0dXJuIFp9cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLnJlcGxheSgpKX1hc3luYyBtc2djaGVjaygpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdEtleXMoKTtyZXR1cm4gUiQoJCx0aGlzLmNyeXB0byl9bGlzdE1zZ3MoJCl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCgkKX1jb3VudE1zZ3MoJCl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMuY291bnQoJCl9YXN5bmMgcmVjb25jaWxlKCQsSil7dGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKTtsZXR7Y29ubmVjdGlvbnM6WixjcnlwdG86USxzdG9yZTpWfT10aGlzLFg9YXdhaXQgVi5zZWVkLmxvYWQoKTtpZighWClyZXR1cm4gRygyMik7bGV0IFk9YXdhaXQgVi5ob3N0cy5nZXQoJCk7aWYoIVkpcmV0dXJuIEcoMTMpO2xldCBXPVouZ2V0KCQpO2lmKCFXfHwhVy5pc0Nvbm5lY3RlZCgpKXtpZihhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWSwhMSwhMSksWT1hd2FpdCBWLmhvc3RzLmdldCgkKSwhWSlyZXR1cm4gRygxMyk7Vz1aLmdldCgkKX1pZighVylyZXR1cm4gRygxMik7bGV0IHo9e2Nvbm46VyxzdG9yZTpWLGVuY2xhdmU6WCxjcnlwdG86USxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sW0ssRl09YXdhaXQgdUooey4uLnosaG9zdDpZfSxKKTtpZih0aGlzLnhmZXJTdGF0ZS5lbWl0KCksRiE9PTApcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxHKEYpO2lmKCFLKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRygxMik7aWYoSj8uc3luYz09PSExKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksTihLKTtsZXQgTz1hd2FpdCB0aGlzLnN5bmMoKTtpZihPIT09MClyZXR1cm4gRyhPKTtsZXQgSD1hd2FpdCBWLmhvc3RzLmdldCgkKTtpZighSClyZXR1cm4gRygxMyk7bGV0W1IscV09YXdhaXQgdUooey4uLnosaG9zdDpIfSx7cHVsbDohMSxwdXNoOiExfSk7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxxIT09MClyZXR1cm4gRyhxKTtpZighUilyZXR1cm4gRygxMik7cmV0dXJuIE4oUil9YXN5bmMgcmVwdWxsKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOkosc3RvcmU6Wn09dGhpcyxRPWF3YWl0IFouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2xldCBWPUFycmF5LmZyb20oYXdhaXQgWi5ob3N0cy5saXN0KCkpO2lmKFYubGVuZ3RoPDEpcmV0dXJuIDA7Zm9yKGxldCBYIG9mIFYpe2xldCBZPSQuZ2V0KFgubGFiZWwpO2lmKCFZfHwhWS5pc0Nvbm5lY3RlZCgpKWF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChYLCExLCExKX1mb3IobGV0W1gsWV1vZiAkKXtsZXQgVz1hd2FpdCBaLmhvc3RzLmdldChYKTtpZighVyljb250aW51ZTtsZXQgej17Y29ubjpZLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6ey4uLlcsbGFzdFNlcTowfSxjcnlwdG86SixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sSz1hd2FpdCBoSih6KTtpZihLIT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHBlZWs6ICR7S31gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksSzt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEY9YXdhaXQgbEooeik7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlcGxheSgpe2xldCAkPWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTtpZigkIT09MClyZXR1cm4gJDtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoKSxaPVEkKEosKFgpPT5YLmhlYWQpLFE9Wi5sZW5ndGg7aWYoUTwxKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMDtsZXQgVj0wO3doaWxlKFY8Wi5sZW5ndGgpe2xldCBYPTAsWT0wLFc9Vjtmb3IobGV0IEs9VjtLPFoubGVuZ3RoJiZZPDEwMCYmWDwxMDI0MDA7SysrKVgrPVpbS10uaGVhZC5sZW4sWSsrLFc9SysxO2xldCB6PVouc2xpY2UoVixXKTthd2FpdCB0aGlzLmFwcGx5U3RvcmVkKHopLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiZXhlYyIsZG9uZTpXLHRvdGFsOlF9KSxWPVd9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHdpcGUoJCl7bGV0IEo9JD8ubXNncyE9PSExLFo9JD8uZW50cyE9PSExLFE9JD8ubWV0YSE9PSExLFY9JD8uc2VlZD09PSEwO3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLmRpc2Nvbm5lY3QoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e3N0b3JlOlh9PXRoaXM7aWYoUSlhd2FpdCBYLmhvc3RzLndpcGUoKSxhd2FpdCBYLnVwbG9hZHMud2lwZSgpLGF3YWl0IFguZG93bmxvYWRzLndpcGUoKTtpZihKKWF3YWl0IFgubWVzc2FnZXMud2lwZSgpO2lmKFYpYXdhaXQgWC5zZWVkLndpcGUoKTtpZihaKWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTt0aGlzLmxhc3RQcm9ncmVzcz1FSix0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSx0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9aW1wb3J0PWFzeW5jKCQsSik9PntsZXR7Y3J5cHRvOlosc3RvcmU6UX09dGhpcyxWPUo/Lm9uUHJvZ3Jlc3MsWD1hd2FpdCBRLnNlZWQubG9hZCgpO2lmKCFYKXJldHVybiAyMjtjb25zb2xlLnRpbWUoImltcG9ydDogZGVjb2RpbmcgZmlsZS4uLiIpO2xldCBZPWF3YWl0ICQuYnl0ZXMoKSxbVyx6XT1hd2FpdCBzWihZLFosWCk7aWYoeiE9PTApcmV0dXJuIHo7Y29uc29sZS50aW1lRW5kKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgSz0wO3doaWxlKEs8Vy5sZW5ndGgpe2xldCBGPTAsTz0wLEg9Sztmb3IobGV0IE09SztNPFcubGVuZ3RoJiZPPDEwMCYmRjwxMDI0MDA7TSsrKUYrPVdbTV0uaGVhZC5sZW4sTysrLEg9TSsxO2xldCBSPVcuc2xpY2UoSyxIKTtjb25zb2xlLnRpbWUoYGltcG9ydDogYXBwbHlpbmcgWyR7S30sICR7SH1dYCk7bGV0IHE9YXdhaXQgdGhpcy5hcHBseShSLHtlbnF1ZXVlVXBsb2FkOiEwLHRyaWdnZXJVcGxvYWQ6ITF9KTtjb25zb2xlLnRpbWVFbmQoYGltcG9ydDogYXBwbHlpbmcgWyR7S30sICR7SH1dYCk7Zm9yKGxldCBNPTA7TTxSLmxlbmd0aDtNKyspe2xldCBVPXFbTV07aWYoVSE9PTAmJlUhPT0xNSljb25zb2xlLndhcm4oYGZhaWxlZCB0byBpbXBvcnQgbXNnICR7SytNfTogJHt3W1VdfWApfWlmKFYpcXVldWVNaWNyb3Rhc2soKCk9PlYoSCxXLmxlbmd0aCwwKSk7dGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpbXBvcnQiLGRvbmU6SCx0b3RhbDpXLmxlbmd0aH0pLEs9SH1yZXR1cm4gdGhpcy5zY2hlZHVsZVN5bmMoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH07c2NoZWR1bGVTeW5jPSgpPT57aWYodGhpcy5vblNjaGVkdWxlU3luYyl7dGhpcy5vblNjaGVkdWxlU3luYygpO3JldHVybn10aGlzLnNjaGVkdWxlZFN5bmMuc2NoZWR1bGUoKX07YXN5bmMgZXhwb3J0Qnl0ZXMoKXtsZXR7Y3J5cHRvOiQsc3RvcmU6Sn09dGhpcyxaPWF3YWl0IEouc2VlZC5sb2FkKCk7aWYoIVopcmV0dXJuIEcoMjIpO2xldCBRPWF3YWl0IEoubWVzc2FnZXMubGlzdCgpO3JldHVybiBhWigiZXhwb3J0IiwwLFEsJCxaKX1hc3luYyBleHBvcnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5leHBvcnRCeXRlcygpO2lmKFohPT0wKXJldHVybiBaO2lmKCFKKXJldHVybiAxMjtsZXQgUT1uZXcgQmxvYihbSi5zbGljZSgpXSk7cmV0dXJuIHpRKFEsJCksMH1hc3luYyBsaW5rKCQsSj0hMCl7aWYoYXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5hZGQoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksSil7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5nZXQoJC5sYWJlbCk7aWYoWilhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWil9fWFzeW5jIHVubGluaygkKXthd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmRlbCgkKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBob3N0cygpe3JldHVybiBBcnJheS5mcm9tKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpKX1jb25uZWN0VG9Ib3N0PWFzeW5jKCQsSj0hMCxaPSEwKT0+e2xldHtjbG9jazpRLGNvbm5lY3Rpb25zOlYsY3J5cHRvOlgsc3RvcmU6WSx0cmFuc3BvcnQ6V309dGhpcyx6PVYuZ2V0KCQubGFiZWwpO2lmKHope2lmKHouaXNDb25uZWN0ZWQoKSlyZXR1cm47dHJ5e3ouY2xvc2VMaXN0ZW5lcigpfWNhdGNoe31WLmRlbGV0ZSgkLmxhYmVsKX1sZXQgSz1hd2FpdCBZLnNlZWQubG9hZCgpO2lmKCFLKXJldHVybjtjb25zb2xlLmluZm8oYENvbm5lY3RpbmcgdG8gJHskLmhhbmRsZX0gKCR7JC5sYWJlbH0pYCk7bGV0IEY9bmV3IEUkKEssWCwkLFEsVygkKSwoTyk9PlkuaG9zdHMuc2V0KCQubGFiZWwsTykpO2lmKGF3YWl0IEYucmVnaXN0ZXIoKSxKKWF3YWl0IEYubGlzdGVuKGFzeW5jKE8pPT57bGV0IEg9e2Nvbm46RixzdG9yZTpZLGVuY2xhdmU6Syxob3N0OiQsY3J5cHRvOlgsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9O3JldHVybiBVUShPLEgsdGhpcy5zY2hlZHVsZVN5bmMpfSwoKT0+dGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpKTtpZihWLnNldCgkLmxhYmVsLEYpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLFopdGhpcy5zY2hlZHVsZVN5bmMoKX07YXN5bmMgY29ubmVjdCgkPSEwLEo9ITApe2xldHtjb25uZWN0VG9Ib3N0Olosc2NoZWR1bGVTeW5jOlEsc3RvcmU6Vn09dGhpcztpZighYXdhaXQgVi5zZWVkLmxvYWQoKSlyZXR1cm47YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtsZXQgWT1hd2FpdCBWLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWSlhd2FpdCBaKFcsJCwhMSk7aWYoSilRKCl9ZGlzY29ubmVjdD1hc3luYygpPT57Zm9yKGxldCAkIG9mIHRoaXMuY29ubmVjdGlvbnMudmFsdWVzKCkpdHJ5eyQuY2xvc2VMaXN0ZW5lcigpfWNhdGNoe310aGlzLmNvbm5lY3Rpb25zLmNsZWFyKCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9fXZhciB2MD10eXBlb2YgZ2xvYmFsVGhpcz09PSJvYmplY3QiJiYiY3J5cHRvImluIGdsb2JhbFRoaXM/Z2xvYmFsVGhpcy5jcnlwdG86dm9pZCAwO2Z1bmN0aW9uIHAkKCQpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcigkKXx8JDwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIiskKX1mdW5jdGlvbiBwSigkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldygkKSYmJC5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIG8oJCwuLi5KKXtpZighcEooJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihKLmxlbmd0aD4wJiYhSi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrSisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIGNKKCQsSj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoSiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIENRKCQsSil7bygkKTtsZXQgWj1KLm91dHB1dExlbjtpZigkLmxlbmd0aDxaKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK1opfWZ1bmN0aW9uIG5KKCQpe2lmKHR5cGVvZiAkIT09ImJvb2xlYW4iKXRocm93IEVycm9yKGBib29sZWFuIGV4cGVjdGVkLCBub3QgJHskfWApfS8qISBub2JsZS1jaXBoZXJzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjMgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovdmFyIFAwPSgkKT0+bmV3IFVpbnQzMkFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCxNYXRoLmZsb29yKCQuYnl0ZUxlbmd0aC80KSk7dmFyIFJYPW5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4O2lmKCFSWCl0aHJvdyBFcnJvcigiTm9uIGxpdHRsZS1lbmRpYW4gaGFyZHdhcmUgaXMgbm90IHN1cHBvcnRlZCIpO2Z1bmN0aW9uIHFYKCQpe2lmKHR5cGVvZiAkIT09InN0cmluZyIpdGhyb3cgRXJyb3IoInN0cmluZyBleHBlY3RlZCIpO3JldHVybiBuZXcgVWludDhBcnJheShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCkpfWZ1bmN0aW9uIGMkKCQpe2lmKHR5cGVvZiAkPT09InN0cmluZyIpJD1xWCgkKTtlbHNlIGlmKHBKKCQpKSQ9biQoJCk7ZWxzZSB0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCwgZ290ICIrdHlwZW9mICQpO3JldHVybiAkfWZ1bmN0aW9uIElRKCQsSil7aWYoSj09bnVsbHx8dHlwZW9mIEohPT0ib2JqZWN0Iil0aHJvdyBFcnJvcigib3B0aW9ucyBtdXN0IGJlIGRlZmluZWQiKTtyZXR1cm4gT2JqZWN0LmFzc2lnbigkLEopfWZ1bmN0aW9uIFBRKCQsSil7aWYoJC5sZW5ndGghPT1KLmxlbmd0aClyZXR1cm4hMTtsZXQgWj0wO2ZvcihsZXQgUT0wO1E8JC5sZW5ndGg7USsrKVp8PSRbUV1eSltRXTtyZXR1cm4gWj09PTB9dmFyIGpRPSgkLEopPT57ZnVuY3Rpb24gWihRLC4uLlYpe2lmKG8oUSksJC5ub25jZUxlbmd0aCE9PXZvaWQgMCl7bGV0IEY9VlswXTtpZighRil0aHJvdyBFcnJvcigibm9uY2UgLyBpdiByZXF1aXJlZCIpO2lmKCQudmFyU2l6ZU5vbmNlKW8oRik7ZWxzZSBvKEYsJC5ub25jZUxlbmd0aCl9bGV0IFg9JC50YWdMZW5ndGg7aWYoWCYmVlsxXSE9PXZvaWQgMClvKFZbMV0pO2xldCBZPUooUSwuLi5WKSxXPShGLE8pPT57aWYoTyE9PXZvaWQgMCl7aWYoRiE9PTIpdGhyb3cgRXJyb3IoImNpcGhlciBvdXRwdXQgbm90IHN1cHBvcnRlZCIpO28oTyl9fSx6PSExO3JldHVybntlbmNyeXB0KEYsTyl7aWYoeil0aHJvdyBFcnJvcigiY2Fubm90IGVuY3J5cHQoKSB0d2ljZSB3aXRoIHNhbWUga2V5ICsgbm9uY2UiKTtyZXR1cm4gej0hMCxvKEYpLFcoWS5lbmNyeXB0Lmxlbmd0aCxPKSxZLmVuY3J5cHQoRixPKX0sZGVjcnlwdChGLE8pe2lmKG8oRiksWCYmRi5sZW5ndGg8WCl0aHJvdyBFcnJvcigiaW52YWxpZCBjaXBoZXJ0ZXh0IGxlbmd0aDogc21hbGxlciB0aGFuIHRhZ0xlbmd0aD0iK1gpO3JldHVybiBXKFkuZGVjcnlwdC5sZW5ndGgsTyksWS5kZWNyeXB0KEYsTyl9fX1yZXR1cm4gT2JqZWN0LmFzc2lnbihaLCQpLFp9O2Z1bmN0aW9uIGRKKCQsSixaPSEwKXtpZihKPT09dm9pZCAwKXJldHVybiBuZXcgVWludDhBcnJheSgkKTtpZihKLmxlbmd0aCE9PSQpdGhyb3cgRXJyb3IoImludmFsaWQgb3V0cHV0IGxlbmd0aCwgZXhwZWN0ZWQgIiskKyIsIGdvdDogIitKLmxlbmd0aCk7aWYoWiYmIU1YKEopKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCwgbXVzdCBiZSBhbGlnbmVkIik7cmV0dXJuIEp9ZnVuY3Rpb24gTVgoJCl7cmV0dXJuICQuYnl0ZU9mZnNldCU0PT09MH1mdW5jdGlvbiBuJCgkKXtyZXR1cm4gVWludDhBcnJheS5mcm9tKCQpfWZ1bmN0aW9uIHEwKC4uLiQpe2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7SisrKSRbSl0uZmlsbCgwKX1mdW5jdGlvbiBNJCgkPTMyKXtpZih2MCYmdHlwZW9mIHYwLmdldFJhbmRvbVZhbHVlcz09PSJmdW5jdGlvbiIpcmV0dXJuIHYwLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheSgkKSk7aWYodjAmJnR5cGVvZiB2MC5yYW5kb21CeXRlcz09PSJmdW5jdGlvbiIpcmV0dXJuIHYwLnJhbmRvbUJ5dGVzKCQpO3Rocm93IEVycm9yKCJjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIG11c3QgYmUgZGVmaW5lZCIpfXZhciBEUT0oJCk9PlVpbnQ4QXJyYXkuZnJvbSgkLnNwbGl0KCIiKS5tYXAoKEopPT5KLmNoYXJDb2RlQXQoMCkpKSxVWD1EUSgiZXhwYW5kIDE2LWJ5dGUgayIpLENYPURRKCJleHBhbmQgMzItYnl0ZSBrIiksSVg9UDAoVVgpLFBYPVAwKENYKTtmdW5jdGlvbiBEKCQsSil7cmV0dXJuICQ8PEp8JD4+PjMyLUp9ZnVuY3Rpb24gckooJCl7cmV0dXJuICQuYnl0ZU9mZnNldCU0PT09MH12YXIgZCQ9NjQsalg9MTYsd1E9NDI5NDk2NzI5NSxUUT1uZXcgVWludDMyQXJyYXk7ZnVuY3Rpb24gVFgoJCxKLFosUSxWLFgsWSxXKXtsZXQgej1WLmxlbmd0aCxLPW5ldyBVaW50OEFycmF5KGQkKSxGPVAwKEspLE89ckooVikmJnJKKFgpLEg9Tz9QMChWKTpUUSxSPU8/UDAoWCk6VFE7Zm9yKGxldCBxPTA7cTx6O1krKyl7aWYoJChKLFosUSxGLFksVyksWT49d1EpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2xldCBNPU1hdGgubWluKGQkLHotcSk7aWYoTyYmTT09PWQkKXtsZXQgVT1xLzQ7aWYocSU0IT09MCl0aHJvdyBFcnJvcigiYXJ4OiBpbnZhbGlkIGJsb2NrIHBvc2l0aW9uIik7Zm9yKGxldCBQPTAsSTtQPGpYO1ArKylJPVUrUCxSW0ldPUhbSV1eRltQXTtxKz1kJDtjb250aW51ZX1mb3IobGV0IFU9MCxQO1U8TTtVKyspUD1xK1UsWFtQXT1WW1BdXktbVV07cSs9TX19ZnVuY3Rpb24gQVEoJCxKKXtsZXR7YWxsb3dTaG9ydEtleXM6WixleHRlbmROb25jZUZuOlEsY291bnRlckxlbmd0aDpWLGNvdW50ZXJSaWdodDpYLHJvdW5kczpZfT1JUSh7YWxsb3dTaG9ydEtleXM6ITEsY291bnRlckxlbmd0aDo4LGNvdW50ZXJSaWdodDohMSxyb3VuZHM6MjB9LEopO2lmKHR5cGVvZiAkIT09ImZ1bmN0aW9uIil0aHJvdyBFcnJvcigiY29yZSBtdXN0IGJlIGEgZnVuY3Rpb24iKTtyZXR1cm4gcCQoVikscCQoWSksbkooWCksbkooWiksKFcseixLLEYsTz0wKT0+e28oVyksbyh6KSxvKEspO2xldCBIPUsubGVuZ3RoO2lmKEY9PT12b2lkIDApRj1uZXcgVWludDhBcnJheShIKTtpZihvKEYpLHAkKE8pLE88MHx8Tz49d1EpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2lmKEYubGVuZ3RoPEgpdGhyb3cgRXJyb3IoYGFyeDogb3V0cHV0ICgke0YubGVuZ3RofSkgaXMgc2hvcnRlciB0aGFuIGRhdGEgKCR7SH0pYCk7bGV0IFI9W10scT1XLmxlbmd0aCxNLFU7aWYocT09PTMyKVIucHVzaChNPW4kKFcpKSxVPVBYO2Vsc2UgaWYocT09PTE2JiZaKU09bmV3IFVpbnQ4QXJyYXkoMzIpLE0uc2V0KFcpLE0uc2V0KFcsMTYpLFU9SVgsUi5wdXNoKE0pO2Vsc2UgdGhyb3cgRXJyb3IoYGFyeDogaW52YWxpZCAzMi1ieXRlIGtleSwgZ290IGxlbmd0aD0ke3F9YCk7aWYoIXJKKHopKVIucHVzaCh6PW4kKHopKTtsZXQgUD1QMChNKTtpZihRKXtpZih6Lmxlbmd0aCE9PTI0KXRocm93IEVycm9yKCJhcng6IGV4dGVuZGVkIG5vbmNlIG11c3QgYmUgMjQgYnl0ZXMiKTtRKFUsUCxQMCh6LnN1YmFycmF5KDAsMTYpKSxQKSx6PXouc3ViYXJyYXkoMTYpfWxldCBJPTE2LVY7aWYoSSE9PXoubGVuZ3RoKXRocm93IEVycm9yKGBhcng6IG5vbmNlIG11c3QgYmUgJHtJfSBvciAxNiBieXRlc2ApO2lmKEkhPT0xMil7bGV0IEM9bmV3IFVpbnQ4QXJyYXkoMTIpO0Muc2V0KHosWD8wOjEyLXoubGVuZ3RoKSx6PUMsUi5wdXNoKHopfWxldCBUPVAwKHopO3JldHVybiBUWCgkLFUsUCxULEssRixPLFkpLHEwKC4uLlIpLEZ9fXZhciBzPSgkLEopPT4kW0orK10mMjU1fCgkW0orK10mMjU1KTw8ODtjbGFzcyBMUXtjb25zdHJ1Y3RvcigkKXt0aGlzLmJsb2NrTGVuPTE2LHRoaXMub3V0cHV0TGVuPTE2LHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KDE2KSx0aGlzLnI9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLmg9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLnBhZD1uZXcgVWludDE2QXJyYXkoOCksdGhpcy5wb3M9MCx0aGlzLmZpbmlzaGVkPSExLCQ9YyQoJCksbygkLDMyKTtsZXQgSj1zKCQsMCksWj1zKCQsMiksUT1zKCQsNCksVj1zKCQsNiksWD1zKCQsOCksWT1zKCQsMTApLFc9cygkLDEyKSx6PXMoJCwxNCk7dGhpcy5yWzBdPUomODE5MSx0aGlzLnJbMV09KEo+Pj4xM3xaPDwzKSY4MTkxLHRoaXMuclsyXT0oWj4+PjEwfFE8PDYpJjc5MzksdGhpcy5yWzNdPShRPj4+N3xWPDw5KSY4MTkxLHRoaXMucls0XT0oVj4+PjR8WDw8MTIpJjI1NSx0aGlzLnJbNV09WD4+PjEmODE5MCx0aGlzLnJbNl09KFg+Pj4xNHxZPDwyKSY4MTkxLHRoaXMucls3XT0oWT4+PjExfFc8PDUpJjgwNjUsdGhpcy5yWzhdPShXPj4+OHx6PDw4KSY4MTkxLHRoaXMucls5XT16Pj4+NSYxMjc7Zm9yKGxldCBLPTA7Szw4O0srKyl0aGlzLnBhZFtLXT1zKCQsMTYrMipLKX1wcm9jZXNzKCQsSixaPSExKXtsZXQgUT1aPzA6MjA0OCx7aDpWLHI6WH09dGhpcyxZPVhbMF0sVz1YWzFdLHo9WFsyXSxLPVhbM10sRj1YWzRdLE89WFs1XSxIPVhbNl0sUj1YWzddLHE9WFs4XSxNPVhbOV0sVT1zKCQsSiswKSxQPXMoJCxKKzIpLEk9cygkLEorNCksVD1zKCQsSis2KSxDPXMoJCxKKzgpLEE9cygkLEorMTApLF89cygkLEorMTIpLEU9cygkLEorMTQpLG09VlswXSsoVSY4MTkxKSxmPVZbMV0rKChVPj4+MTN8UDw8MykmODE5MSkseT1WWzJdKygoUD4+PjEwfEk8PDYpJjgxOTEpLGg9VlszXSsoKEk+Pj43fFQ8PDkpJjgxOTEpLGk9Vls0XSsoKFQ+Pj40fEM8PDEyKSY4MTkxKSxqPVZbNV0rKEM+Pj4xJjgxOTEpLHg9Vls2XSsoKEM+Pj4xNHxBPDwyKSY4MTkxKSx2PVZbN10rKChBPj4+MTF8Xzw8NSkmODE5MSksaz1WWzhdKygoXz4+Pjh8RTw8OCkmODE5MSksbD1WWzldKyhFPj4+NXxRKSxMPTAscj1MK20qWStmKig1Kk0pK3kqKDUqcSkraCooNSpSKStpKig1KkgpO0w9cj4+PjEzLHImPTgxOTEscis9aiooNSpPKSt4Kig1KkYpK3YqKDUqSykrayooNSp6KStsKig1KlcpLEwrPXI+Pj4xMyxyJj04MTkxO2xldCB0PUwrbSpXK2YqWSt5Kig1Kk0pK2gqKDUqcSkraSooNSpSKTtMPXQ+Pj4xMyx0Jj04MTkxLHQrPWoqKDUqSCkreCooNSpPKSt2Kig1KkYpK2sqKDUqSykrbCooNSp6KSxMKz10Pj4+MTMsdCY9ODE5MTtsZXQgVjA9TCttKnorZipXK3kqWStoKig1Kk0pK2kqKDUqcSk7TD1WMD4+PjEzLFYwJj04MTkxLFYwKz1qKig1KlIpK3gqKDUqSCkrdiooNSpPKStrKig1KkYpK2wqKDUqSyksTCs9VjA+Pj4xMyxWMCY9ODE5MTtsZXQgYz1MK20qSytmKnoreSpXK2gqWStpKig1Kk0pO0w9Yz4+PjEzLGMmPTgxOTEsYys9aiooNSpxKSt4Kig1KlIpK3YqKDUqSCkrayooNSpPKStsKig1KkYpLEwrPWM+Pj4xMyxjJj04MTkxO2xldCBDMD1MK20qRitmKksreSp6K2gqVytpKlk7TD1DMD4+PjEzLEMwJj04MTkxLEMwKz1qKig1Kk0pK3gqKDUqcSkrdiooNSpSKStrKig1KkgpK2wqKDUqTyksTCs9QzA+Pj4xMyxDMCY9ODE5MTtsZXQgYzA9TCttKk8rZipGK3kqSytoKnoraSpXO0w9YzA+Pj4xMyxjMCY9ODE5MSxjMCs9aipZK3gqKDUqTSkrdiooNSpxKStrKig1KlIpK2wqKDUqSCksTCs9YzA+Pj4xMyxjMCY9ODE5MTtsZXQgbjA9TCttKkgrZipPK3kqRitoKksraSp6O0w9bjA+Pj4xMyxuMCY9ODE5MSxuMCs9aipXK3gqWSt2Kig1Kk0pK2sqKDUqcSkrbCooNSpSKSxMKz1uMD4+PjEzLG4wJj04MTkxO2xldCBkMD1MK20qUitmKkgreSpPK2gqRitpKks7TD1kMD4+PjEzLGQwJj04MTkxLGQwKz1qKnoreCpXK3YqWStrKig1Kk0pK2wqKDUqcSksTCs9ZDA+Pj4xMyxkMCY9ODE5MTtsZXQgcjA9TCttKnErZipSK3kqSCtoKk8raSpGO0w9cjA+Pj4xMyxyMCY9ODE5MSxyMCs9aipLK3gqeit2KlcraypZK2wqKDUqTSksTCs9cjA+Pj4xMyxyMCY9ODE5MTtsZXQgbzA9TCttKk0rZipxK3kqUitoKkgraSpPO0w9bzA+Pj4xMyxvMCY9ODE5MSxvMCs9aipGK3gqSyt2KnoraypXK2wqWSxMKz1vMD4+PjEzLG8wJj04MTkxLEw9KEw8PDIpK0x8MCxMPUwrcnwwLHI9TCY4MTkxLEw9TD4+PjEzLHQrPUwsVlswXT1yLFZbMV09dCxWWzJdPVYwLFZbM109YyxWWzRdPUMwLFZbNV09YzAsVls2XT1uMCxWWzddPWQwLFZbOF09cjAsVls5XT1vMH1maW5hbGl6ZSgpe2xldHtoOiQscGFkOkp9PXRoaXMsWj1uZXcgVWludDE2QXJyYXkoMTApLFE9JFsxXT4+PjEzOyRbMV0mPTgxOTE7Zm9yKGxldCBZPTI7WTwxMDtZKyspJFtZXSs9USxRPSRbWV0+Pj4xMywkW1ldJj04MTkxOyRbMF0rPVEqNSxRPSRbMF0+Pj4xMywkWzBdJj04MTkxLCRbMV0rPVEsUT0kWzFdPj4+MTMsJFsxXSY9ODE5MSwkWzJdKz1RLFpbMF09JFswXSs1LFE9WlswXT4+PjEzLFpbMF0mPTgxOTE7Zm9yKGxldCBZPTE7WTwxMDtZKyspWltZXT0kW1ldK1EsUT1aW1ldPj4+MTMsWltZXSY9ODE5MTtaWzldLT04MTkyO2xldCBWPShRXjEpLTE7Zm9yKGxldCBZPTA7WTwxMDtZKyspWltZXSY9VjtWPX5WO2ZvcihsZXQgWT0wO1k8MTA7WSsrKSRbWV09JFtZXSZWfFpbWV07JFswXT0oJFswXXwkWzFdPDwxMykmNjU1MzUsJFsxXT0oJFsxXT4+PjN8JFsyXTw8MTApJjY1NTM1LCRbMl09KCRbMl0+Pj42fCRbM108PDcpJjY1NTM1LCRbM109KCRbM10+Pj45fCRbNF08PDQpJjY1NTM1LCRbNF09KCRbNF0+Pj4xMnwkWzVdPDwxfCRbNl08PDE0KSY2NTUzNSwkWzVdPSgkWzZdPj4+MnwkWzddPDwxMSkmNjU1MzUsJFs2XT0oJFs3XT4+PjV8JFs4XTw8OCkmNjU1MzUsJFs3XT0oJFs4XT4+Pjh8JFs5XTw8NSkmNjU1MzU7bGV0IFg9JFswXStKWzBdOyRbMF09WCY2NTUzNTtmb3IobGV0IFk9MTtZPDg7WSsrKVg9KCRbWV0rSltZXXwwKSsoWD4+PjE2KXwwLCRbWV09WCY2NTUzNTtxMChaKX11cGRhdGUoJCl7Y0oodGhpcyk7bGV0e2J1ZmZlcjpKLGJsb2NrTGVuOlp9PXRoaXM7JD1jJCgkKTtsZXQgUT0kLmxlbmd0aDtmb3IobGV0IFY9MDtWPFE7KXtsZXQgWD1NYXRoLm1pbihaLXRoaXMucG9zLFEtVik7aWYoWD09PVope2Zvcig7Wjw9US1WO1YrPVopdGhpcy5wcm9jZXNzKCQsVik7Y29udGludWV9aWYoSi5zZXQoJC5zdWJhcnJheShWLFYrWCksdGhpcy5wb3MpLHRoaXMucG9zKz1YLFYrPVgsdGhpcy5wb3M9PT1aKXRoaXMucHJvY2VzcyhKLDAsITEpLHRoaXMucG9zPTB9cmV0dXJuIHRoaXN9ZGVzdHJveSgpe3EwKHRoaXMuaCx0aGlzLnIsdGhpcy5idWZmZXIsdGhpcy5wYWQpfWRpZ2VzdEludG8oJCl7Y0oodGhpcyksQ1EoJCx0aGlzKSx0aGlzLmZpbmlzaGVkPSEwO2xldHtidWZmZXI6SixoOlp9PXRoaXMse3BvczpRfT10aGlzO2lmKFEpe0pbUSsrXT0xO2Zvcig7UTwxNjtRKyspSltRXT0wO3RoaXMucHJvY2VzcyhKLDAsITApfXRoaXMuZmluYWxpemUoKTtsZXQgVj0wO2ZvcihsZXQgWD0wO1g8ODtYKyspJFtWKytdPVpbWF0+Pj4wLCRbVisrXT1aW1hdPj4+ODtyZXR1cm4gJH1kaWdlc3QoKXtsZXR7YnVmZmVyOiQsb3V0cHV0TGVuOkp9PXRoaXM7dGhpcy5kaWdlc3RJbnRvKCQpO2xldCBaPSQuc2xpY2UoMCxKKTtyZXR1cm4gdGhpcy5kZXN0cm95KCksWn19ZnVuY3Rpb24gRFgoJCl7bGV0IEo9KFEsVik9PiQoVikudXBkYXRlKGMkKFEpKS5kaWdlc3QoKSxaPSQobmV3IFVpbnQ4QXJyYXkoMzIpKTtyZXR1cm4gSi5vdXRwdXRMZW49Wi5vdXRwdXRMZW4sSi5ibG9ja0xlbj1aLmJsb2NrTGVuLEouY3JlYXRlPShRKT0+JChRKSxKfXZhciBvSj1EWCgoJCk9Pm5ldyBMUSgkKSk7ZnVuY3Rpb24gd1goJCxKLFosUSxWLFg9MjApe2xldCBZPSRbMF0sVz1KWzBdLHo9SlsxXSxLPUpbMl0sRj1KWzNdLE89JFsxXSxIPVpbMF0sUj1aWzFdLHE9VixNPTAsVT0kWzJdLFA9Sls0XSxJPUpbNV0sVD1KWzZdLEM9Sls3XSxBPSRbM10sXz1ZLEU9VyxtPXosZj1LLHk9RixoPU8saT1ILGo9Uix4PXEsdj1NLGs9VSxsPVAsTD1JLHI9VCx0PUMsVjA9QTtmb3IobGV0IEMwPTA7QzA8WDtDMCs9Mil5Xj1EKF8rTHwwLDcpLHhePUQoeStffDAsOSksTF49RCh4K3l8MCwxMyksX149RChMK3h8MCwxOCksdl49RChoK0V8MCw3KSxyXj1EKHYraHwwLDkpLEVePUQocit2fDAsMTMpLGhePUQoRStyfDAsMTgpLHRePUQoaytpfDAsNyksbV49RCh0K2t8MCw5KSxpXj1EKG0rdHwwLDEzKSxrXj1EKGkrbXwwLDE4KSxmXj1EKFYwK2x8MCw3KSxqXj1EKGYrVjB8MCw5KSxsXj1EKGorZnwwLDEzKSxWMF49RChsK2p8MCwxOCksRV49RChfK2Z8MCw3KSxtXj1EKEUrX3wwLDkpLGZePUQobStFfDAsMTMpLF9ePUQoZittfDAsMTgpLGlePUQoaCt5fDAsNyksal49RChpK2h8MCw5KSx5Xj1EKGoraXwwLDEzKSxoXj1EKHkranwwLDE4KSxsXj1EKGsrdnwwLDcpLHhePUQobCtrfDAsOSksdl49RCh4K2x8MCwxMyksa149RCh2K3h8MCwxOCksTF49RChWMCt0fDAsNykscl49RChMK1YwfDAsOSksdF49RChyK0x8MCwxMyksVjBePUQodCtyfDAsMTgpO2xldCBjPTA7UVtjKytdPVkrX3wwLFFbYysrXT1XK0V8MCxRW2MrK109eittfDAsUVtjKytdPUsrZnwwLFFbYysrXT1GK3l8MCxRW2MrK109TytofDAsUVtjKytdPUgraXwwLFFbYysrXT1SK2p8MCxRW2MrK109cSt4fDAsUVtjKytdPU0rdnwwLFFbYysrXT1VK2t8MCxRW2MrK109UCtsfDAsUVtjKytdPUkrTHwwLFFbYysrXT1UK3J8MCxRW2MrK109Qyt0fDAsUVtjKytdPUErVjB8MH1mdW5jdGlvbiBBWCgkLEosWixRKXtsZXQgVj0kWzBdLFg9SlswXSxZPUpbMV0sVz1KWzJdLHo9SlszXSxLPSRbMV0sRj1aWzBdLE89WlsxXSxIPVpbMl0sUj1aWzNdLHE9JFsyXSxNPUpbNF0sVT1KWzVdLFA9Sls2XSxJPUpbN10sVD0kWzNdO2ZvcihsZXQgQT0wO0E8MjA7QSs9Mil6Xj1EKFYrVXwwLDcpLEhePUQoeitWfDAsOSksVV49RChIK3p8MCwxMyksVl49RChVK0h8MCwxOCksUl49RChLK1h8MCw3KSxQXj1EKFIrS3wwLDkpLFhePUQoUCtSfDAsMTMpLEtePUQoWCtQfDAsMTgpLElePUQocStGfDAsNyksWV49RChJK3F8MCw5KSxGXj1EKFkrSXwwLDEzKSxxXj1EKEYrWXwwLDE4KSxXXj1EKFQrTXwwLDcpLE9ePUQoVytUfDAsOSksTV49RChPK1d8MCwxMyksVF49RChNK098MCwxOCksWF49RChWK1d8MCw3KSxZXj1EKFgrVnwwLDkpLFdePUQoWStYfDAsMTMpLFZePUQoVytZfDAsMTgpLEZePUQoSyt6fDAsNyksT149RChGK0t8MCw5KSx6Xj1EKE8rRnwwLDEzKSxLXj1EKHorT3wwLDE4KSxNXj1EKHErUnwwLDcpLEhePUQoTStxfDAsOSksUl49RChIK018MCwxMykscV49RChSK0h8MCwxOCksVV49RChUK0l8MCw3KSxQXj1EKFUrVHwwLDkpLElePUQoUCtVfDAsMTMpLFRePUQoSStQfDAsMTgpO2xldCBDPTA7UVtDKytdPVYsUVtDKytdPUssUVtDKytdPXEsUVtDKytdPVQsUVtDKytdPUYsUVtDKytdPU8sUVtDKytdPUgsUVtDKytdPVJ9dmFyIGFKPUFRKHdYLHtjb3VudGVyUmlnaHQ6ITAsZXh0ZW5kTm9uY2VGbjpBWH0pLHNKPWpRKHtibG9ja1NpemU6NjQsbm9uY2VMZW5ndGg6MjQsdGFnTGVuZ3RoOjE2fSwoJCxKKT0+e3JldHVybntlbmNyeXB0KFosUSl7UT1kSihaLmxlbmd0aCszMixRLCExKTtsZXQgVj1RLnN1YmFycmF5KDAsMzIpLFg9US5zdWJhcnJheSgzMik7US5zZXQoWiwzMikscTAoViksYUooJCxKLFEsUSk7bGV0IFk9b0ooWCxWKTtyZXR1cm4gUS5zZXQoWSwxNikscTAoUS5zdWJhcnJheSgwLDE2KSxZKSxRLnN1YmFycmF5KDE2KX0sZGVjcnlwdChaLFEpe28oWiksUT1kSihaLmxlbmd0aCszMixRLCExKTtsZXQgVj1RLnN1YmFycmF5KDAsMzIpLFg9US5zdWJhcnJheSgzMiw0OCksWT1RLnN1YmFycmF5KDQ4KTtRLnNldChaLDMyKSxxMChWKTtsZXQgVz1hSigkLEosVixWKSx6PW9KKFksVyk7aWYoIVBRKFgseikpdGhyb3cgRXJyb3IoImludmFsaWQgdGFnIik7cmV0dXJuIGFKKCQsSixRLnN1YmFycmF5KDE2KSxRLnN1YmFycmF5KDE2KSkscTAoVixYLHopLFl9fX0pOy8qISBub2JsZS1oYXNoZXMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi9mdW5jdGlvbiBMWCgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldygkKSYmJC5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIFUkKCQpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcigkKXx8JDwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIiskKX1mdW5jdGlvbiB5MCgkLC4uLkope2lmKCFMWCgkKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCIpO2lmKEoubGVuZ3RoPjAmJiFKLmluY2x1ZGVzKCQubGVuZ3RoKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCBvZiBsZW5ndGggIitKKyIsIGdvdCBsZW5ndGg9IiskLmxlbmd0aCl9ZnVuY3Rpb24gQyQoJCxKPSEwKXtpZigkLmRlc3Ryb3llZCl0aHJvdyBFcnJvcigiSGFzaCBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQiKTtpZihKJiYkLmZpbmlzaGVkKXRocm93IEVycm9yKCJIYXNoI2RpZ2VzdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIil9ZnVuY3Rpb24gciQoJCxKKXt5MCgkKTtsZXQgWj1KLm91dHB1dExlbjtpZigkLmxlbmd0aDxaKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK1opfWZ1bmN0aW9uIF9RKCQpe3JldHVybiBuZXcgVWludDhBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKX1mdW5jdGlvbiBZJCgkKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCxNYXRoLmZsb29yKCQuYnl0ZUxlbmd0aC80KSl9ZnVuY3Rpb24gVyQoLi4uJCl7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspJFtKXS5maWxsKDApfWZ1bmN0aW9uIEkkKCQsSil7cmV0dXJuICQ8PDMyLUp8JD4+Pkp9dmFyIHhRPSgoKT0+bmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQzMkFycmF5KFsyODc0NTQwMjBdKS5idWZmZXIpWzBdPT09NjgpKCk7ZnVuY3Rpb24gQlEoJCl7cmV0dXJuICQ8PDI0JjQyNzgxOTAwODB8JDw8OCYxNjcxMTY4MHwkPj4+OCY2NTI4MHwkPj4+MjQmMjU1fXZhciBmUT14UT8oJCk9PiQ6KCQpPT5CUSgkKTtmdW5jdGlvbiBfWCgkKXtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKykkW0pdPUJRKCRbSl0pO3JldHVybiAkfXZhciBKMD14UT8oJCk9PiQ6X1g7ZnVuY3Rpb24geFgoJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24gRyQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPXhYKCQpO3JldHVybiB5MCgkKSwkfWNsYXNzIHRKe31mdW5jdGlvbiBrUSgkKXtsZXQgSj0oUSxWKT0+JChWKS51cGRhdGUoRyQoUSkpLmRpZ2VzdCgpLFo9JCh7fSk7cmV0dXJuIEoub3V0cHV0TGVuPVoub3V0cHV0TGVuLEouYmxvY2tMZW49Wi5ibG9ja0xlbixKLmNyZWF0ZT0oUSk9PiQoUSksSn12YXIgbVE9VWludDMyQXJyYXkuZnJvbShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKTt2YXIgbyQ9QmlnSW50KDQyOTQ5NjcyOTUpLEVRPUJpZ0ludCgzMik7ZnVuY3Rpb24gZUooJCxKPSExKXtpZihKKXJldHVybntoOk51bWJlcigkJm8kKSxsOk51bWJlcigkPj5FUSZvJCl9O3JldHVybntoOk51bWJlcigkPj5FUSZvJCl8MCxsOk51bWJlcigkJm8kKXwwfX1mdW5jdGlvbiBqMCgkLEosWixRLFYpe3JldHVybiAkPSQrSitWfDAsUT1JJChRXiQsMTYpLFo9WitRfDAsSj1JJChKXlosMTIpLHthOiQsYjpKLGM6WixkOlF9fWZ1bmN0aW9uIFQwKCQsSixaLFEsVil7cmV0dXJuICQ9JCtKK1Z8MCxRPUkkKFFeJCw4KSxaPVorUXwwLEo9SSQoSl5aLDcpLHthOiQsYjpKLGM6WixkOlF9fWNsYXNzICRaIGV4dGVuZHMgdEp7Y29uc3RydWN0b3IoJCxKKXtzdXBlcigpO3RoaXMuZmluaXNoZWQ9ITEsdGhpcy5kZXN0cm95ZWQ9ITEsdGhpcy5sZW5ndGg9MCx0aGlzLnBvcz0wLFUkKCQpLFUkKEopLHRoaXMuYmxvY2tMZW49JCx0aGlzLm91dHB1dExlbj1KLHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KCQpLHRoaXMuYnVmZmVyMzI9WSQodGhpcy5idWZmZXIpfXVwZGF0ZSgkKXtDJCh0aGlzKSwkPUckKCQpLHkwKCQpO2xldHtibG9ja0xlbjpKLGJ1ZmZlcjpaLGJ1ZmZlcjMyOlF9PXRoaXMsVj0kLmxlbmd0aCxYPSQuYnl0ZU9mZnNldCxZPSQuYnVmZmVyO2ZvcihsZXQgVz0wO1c8Vjspe2lmKHRoaXMucG9zPT09SilKMChRKSx0aGlzLmNvbXByZXNzKFEsMCwhMSksSjAoUSksdGhpcy5wb3M9MDtsZXQgej1NYXRoLm1pbihKLXRoaXMucG9zLFYtVyksSz1YK1c7aWYoej09PUomJiEoSyU0KSYmVyt6PFYpe2xldCBGPW5ldyBVaW50MzJBcnJheShZLEssTWF0aC5mbG9vcigoVi1XKS80KSk7SjAoRik7Zm9yKGxldCBPPTA7VytKPFY7Tys9US5sZW5ndGgsVys9Sil0aGlzLmxlbmd0aCs9Six0aGlzLmNvbXByZXNzKEYsTywhMSk7SjAoRik7Y29udGludWV9Wi5zZXQoJC5zdWJhcnJheShXLFcreiksdGhpcy5wb3MpLHRoaXMucG9zKz16LHRoaXMubGVuZ3RoKz16LFcrPXp9cmV0dXJuIHRoaXN9ZGlnZXN0SW50bygkKXtDJCh0aGlzKSxyJCgkLHRoaXMpO2xldHtwb3M6SixidWZmZXIzMjpafT10aGlzO3RoaXMuZmluaXNoZWQ9ITAsVyQodGhpcy5idWZmZXIuc3ViYXJyYXkoSikpLEowKFopLHRoaXMuY29tcHJlc3MoWiwwLCEwKSxKMChaKTtsZXQgUT1ZJCgkKTt0aGlzLmdldCgpLmZvckVhY2goKFYsWCk9PlFbWF09ZlEoVikpfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Sn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IFo9JC5zbGljZSgwLEopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxafV9jbG9uZUludG8oJCl7bGV0e2J1ZmZlcjpKLGxlbmd0aDpaLGZpbmlzaGVkOlEsZGVzdHJveWVkOlYsb3V0cHV0TGVuOlgscG9zOll9PXRoaXM7cmV0dXJuICR8fCgkPW5ldyB0aGlzLmNvbnN0cnVjdG9yKHtka0xlbjpYfSkpLCQuc2V0KC4uLnRoaXMuZ2V0KCkpLCQuYnVmZmVyLnNldChKKSwkLmRlc3Ryb3llZD1WLCQuZmluaXNoZWQ9USwkLmxlbmd0aD1aLCQucG9zPVksJC5vdXRwdXRMZW49WCwkfWNsb25lKCl7cmV0dXJuIHRoaXMuX2Nsb25lSW50bygpfX1mdW5jdGlvbiBKWigkLEosWixRLFYsWCxZLFcseixLLEYsTyxILFIscSxNLFUsUCxJLFQpe2xldCBDPTA7Zm9yKGxldCBBPTA7QTxRO0ErKykoe2E6VixiOnosYzpILGQ6VX09ajAoVix6LEgsVSxaW0orJFtDKytdXSkpLHthOlYsYjp6LGM6SCxkOlV9PVQwKFYseixILFUsWltKKyRbQysrXV0pLHthOlgsYjpLLGM6UixkOlB9PWowKFgsSyxSLFAsWltKKyRbQysrXV0pLHthOlgsYjpLLGM6UixkOlB9PVQwKFgsSyxSLFAsWltKKyRbQysrXV0pLHthOlksYjpGLGM6cSxkOkl9PWowKFksRixxLEksWltKKyRbQysrXV0pLHthOlksYjpGLGM6cSxkOkl9PVQwKFksRixxLEksWltKKyRbQysrXV0pLHthOlcsYjpPLGM6TSxkOlR9PWowKFcsTyxNLFQsWltKKyRbQysrXV0pLHthOlcsYjpPLGM6TSxkOlR9PVQwKFcsTyxNLFQsWltKKyRbQysrXV0pLHthOlYsYjpLLGM6cSxkOlR9PWowKFYsSyxxLFQsWltKKyRbQysrXV0pLHthOlYsYjpLLGM6cSxkOlR9PVQwKFYsSyxxLFQsWltKKyRbQysrXV0pLHthOlgsYjpGLGM6TSxkOlV9PWowKFgsRixNLFUsWltKKyRbQysrXV0pLHthOlgsYjpGLGM6TSxkOlV9PVQwKFgsRixNLFUsWltKKyRbQysrXV0pLHthOlksYjpPLGM6SCxkOlB9PWowKFksTyxILFAsWltKKyRbQysrXV0pLHthOlksYjpPLGM6SCxkOlB9PVQwKFksTyxILFAsWltKKyRbQysrXV0pLHthOlcsYjp6LGM6UixkOkl9PWowKFcseixSLEksWltKKyRbQysrXV0pLHthOlcsYjp6LGM6UixkOkl9PVQwKFcseixSLEksWltKKyRbQysrXV0pO3JldHVybnt2MDpWLHYxOlgsdjI6WSx2MzpXLHY0OnosdjU6Syx2NjpGLHY3Ok8sdjg6SCx2OTpSLHYxMDpxLHYxMTpNLHYxMjpVLHYxMzpQLHYxNDpJLHYxNTpUfX12YXIgTTA9e0NIVU5LX1NUQVJUOjEsQ0hVTktfRU5EOjIsUEFSRU5UOjQsUk9PVDo4LEtFWUVEX0hBU0g6MTYsREVSSVZFX0tFWV9DT05URVhUOjMyLERFUklWRV9LRVlfTUFURVJJQUw6NjR9LEQwPW1RLnNsaWNlKCksZ1E9KCgpPT57bGV0ICQ9QXJyYXkuZnJvbSh7bGVuZ3RoOjE2fSwoUSxWKT0+ViksSj0oUSk9PlsyLDYsMywxMCw3LDAsNCwxMywxLDExLDEyLDUsOSwxNCwxNSw4XS5tYXAoKFYpPT5RW1ZdKSxaPVtdO2ZvcihsZXQgUT0wLFY9JDtRPDc7USsrLFY9SihWKSlaLnB1c2goLi4uVik7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShaKX0pKCk7Y2xhc3MgWlogZXh0ZW5kcyAkWntjb25zdHJ1Y3RvcigkPXt9LEo9MCl7c3VwZXIoNjQsJC5ka0xlbj09PXZvaWQgMD8zMjokLmRrTGVuKTt0aGlzLmNodW5rUG9zPTAsdGhpcy5jaHVua3NEb25lPTAsdGhpcy5mbGFncz0wLHRoaXMuc3RhY2s9W10sdGhpcy5wb3NPdXQ9MCx0aGlzLmJ1ZmZlck91dDMyPW5ldyBVaW50MzJBcnJheSgxNiksdGhpcy5jaHVua091dD0wLHRoaXMuZW5hYmxlWE9GPSEwO2xldHtrZXk6Wixjb250ZXh0OlF9PSQsVj1RIT09dm9pZCAwO2lmKFohPT12b2lkIDApe2lmKFYpdGhyb3cgRXJyb3IoJ09ubHkgImtleSIgb3IgImNvbnRleHQiIGNhbiBiZSBzcGVjaWZpZWQgYXQgc2FtZSB0aW1lJyk7bGV0IFg9RyQoWikuc2xpY2UoKTt5MChYLDMyKSx0aGlzLklWPVkkKFgpLEowKHRoaXMuSVYpLHRoaXMuZmxhZ3M9SnxNMC5LRVlFRF9IQVNIfWVsc2UgaWYoVil7bGV0IFg9RyQoUSksWT1uZXcgWlooe2RrTGVuOjMyfSxNMC5ERVJJVkVfS0VZX0NPTlRFWFQpLnVwZGF0ZShYKS5kaWdlc3QoKTt0aGlzLklWPVkkKFkpLEowKHRoaXMuSVYpLHRoaXMuZmxhZ3M9SnxNMC5ERVJJVkVfS0VZX01BVEVSSUFMfWVsc2UgdGhpcy5JVj1EMC5zbGljZSgpLHRoaXMuZmxhZ3M9Sjt0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKSx0aGlzLmJ1ZmZlck91dD1fUSh0aGlzLmJ1ZmZlck91dDMyKX1nZXQoKXtyZXR1cm5bXX1zZXQoKXt9YjJDb21wcmVzcygkLEosWixRPTApe2xldHtzdGF0ZTpWLHBvczpYfT10aGlzLHtoOlksbDpXfT1lSihCaWdJbnQoJCksITApLHt2MDp6LHYxOkssdjI6Rix2MzpPLHY0OkgsdjU6Uix2NjpxLHY3Ok0sdjg6VSx2OTpQLHYxMDpJLHYxMTpULHYxMjpDLHYxMzpBLHYxNDpfLHYxNTpFfT1KWihnUSxRLFosNyxWWzBdLFZbMV0sVlsyXSxWWzNdLFZbNF0sVls1XSxWWzZdLFZbN10sRDBbMF0sRDBbMV0sRDBbMl0sRDBbM10sWSxXLFgsSik7VlswXT16XlUsVlsxXT1LXlAsVlsyXT1GXkksVlszXT1PXlQsVls0XT1IXkMsVls1XT1SXkEsVls2XT1xXl8sVls3XT1NXkV9Y29tcHJlc3MoJCxKPTAsWj0hMSl7bGV0IFE9dGhpcy5mbGFncztpZighdGhpcy5jaHVua1BvcylRfD1NMC5DSFVOS19TVEFSVDtpZih0aGlzLmNodW5rUG9zPT09MTV8fFopUXw9TTAuQ0hVTktfRU5EO2lmKCFaKXRoaXMucG9zPXRoaXMuYmxvY2tMZW47aWYodGhpcy5iMkNvbXByZXNzKHRoaXMuY2h1bmtzRG9uZSxRLCQsSiksdGhpcy5jaHVua1Bvcys9MSx0aGlzLmNodW5rUG9zPT09MTZ8fFope2xldCBWPXRoaXMuc3RhdGU7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCk7Zm9yKGxldCBYLFk9dGhpcy5jaHVua3NEb25lKzE7Wnx8IShZJjEpO1k+Pj0xKXtpZighKFg9dGhpcy5zdGFjay5wb3AoKSkpYnJlYWs7dGhpcy5idWZmZXIzMi5zZXQoWCwwKSx0aGlzLmJ1ZmZlcjMyLnNldChWLDgpLHRoaXMucG9zPXRoaXMuYmxvY2tMZW4sdGhpcy5iMkNvbXByZXNzKDAsdGhpcy5mbGFnc3xNMC5QQVJFTlQsdGhpcy5idWZmZXIzMiwwKSxWPXRoaXMuc3RhdGUsdGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCl9dGhpcy5jaHVua3NEb25lKyssdGhpcy5jaHVua1Bvcz0wLHRoaXMuc3RhY2sucHVzaChWKX10aGlzLnBvcz0wfV9jbG9uZUludG8oJCl7JD1zdXBlci5fY2xvbmVJbnRvKCQpO2xldHtJVjpKLGZsYWdzOlosc3RhdGU6USxjaHVua1BvczpWLHBvc091dDpYLGNodW5rT3V0Olksc3RhY2s6VyxjaHVua3NEb25lOnp9PXRoaXM7cmV0dXJuICQuc3RhdGUuc2V0KFEuc2xpY2UoKSksJC5zdGFjaz1XLm1hcCgoSyk9PlVpbnQzMkFycmF5LmZyb20oSykpLCQuSVYuc2V0KEopLCQuZmxhZ3M9WiwkLmNodW5rUG9zPVYsJC5jaHVua3NEb25lPXosJC5wb3NPdXQ9WCwkLmNodW5rT3V0PVksJC5lbmFibGVYT0Y9dGhpcy5lbmFibGVYT0YsJC5idWZmZXJPdXQzMi5zZXQodGhpcy5idWZmZXJPdXQzMiksJH1kZXN0cm95KCl7dGhpcy5kZXN0cm95ZWQ9ITAsVyQodGhpcy5zdGF0ZSx0aGlzLmJ1ZmZlcjMyLHRoaXMuSVYsdGhpcy5idWZmZXJPdXQzMiksVyQoLi4udGhpcy5zdGFjayl9YjJDb21wcmVzc091dCgpe2xldHtzdGF0ZTokLHBvczpKLGZsYWdzOlosYnVmZmVyMzI6USxidWZmZXJPdXQzMjpWfT10aGlzLHtoOlgsbDpZfT1lSihCaWdJbnQodGhpcy5jaHVua091dCsrKSk7SjAoUSk7bGV0e3YwOlcsdjE6eix2MjpLLHYzOkYsdjQ6Tyx2NTpILHY2OlIsdjc6cSx2ODpNLHY5OlUsdjEwOlAsdjExOkksdjEyOlQsdjEzOkMsdjE0OkEsdjE1Ol99PUpaKGdRLDAsUSw3LCRbMF0sJFsxXSwkWzJdLCRbM10sJFs0XSwkWzVdLCRbNl0sJFs3XSxEMFswXSxEMFsxXSxEMFsyXSxEMFszXSxZLFgsSixaKTtWWzBdPVdeTSxWWzFdPXpeVSxWWzJdPUteUCxWWzNdPUZeSSxWWzRdPU9eVCxWWzVdPUheQyxWWzZdPVJeQSxWWzddPXFeXyxWWzhdPSRbMF1eTSxWWzldPSRbMV1eVSxWWzEwXT0kWzJdXlAsVlsxMV09JFszXV5JLFZbMTJdPSRbNF1eVCxWWzEzXT0kWzVdXkMsVlsxNF09JFs2XV5BLFZbMTVdPSRbN11eXyxKMChRKSxKMChWKSx0aGlzLnBvc091dD0wfWZpbmlzaCgpe2lmKHRoaXMuZmluaXNoZWQpcmV0dXJuO3RoaXMuZmluaXNoZWQ9ITAsVyQodGhpcy5idWZmZXIuc3ViYXJyYXkodGhpcy5wb3MpKTtsZXQgJD10aGlzLmZsYWdzfE0wLlJPT1Q7aWYodGhpcy5zdGFjay5sZW5ndGgpJHw9TTAuUEFSRU5ULEowKHRoaXMuYnVmZmVyMzIpLHRoaXMuY29tcHJlc3ModGhpcy5idWZmZXIzMiwwLCEwKSxKMCh0aGlzLmJ1ZmZlcjMyKSx0aGlzLmNodW5rc0RvbmU9MCx0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2Vsc2UgJHw9KCF0aGlzLmNodW5rUG9zP00wLkNIVU5LX1NUQVJUOjApfE0wLkNIVU5LX0VORDt0aGlzLmZsYWdzPSQsdGhpcy5iMkNvbXByZXNzT3V0KCl9d3JpdGVJbnRvKCQpe0MkKHRoaXMsITEpLHkwKCQpLHRoaXMuZmluaXNoKCk7bGV0e2Jsb2NrTGVuOkosYnVmZmVyT3V0Olp9PXRoaXM7Zm9yKGxldCBRPTAsVj0kLmxlbmd0aDtRPFY7KXtpZih0aGlzLnBvc091dD49Sil0aGlzLmIyQ29tcHJlc3NPdXQoKTtsZXQgWD1NYXRoLm1pbihKLXRoaXMucG9zT3V0LFYtUSk7JC5zZXQoWi5zdWJhcnJheSh0aGlzLnBvc091dCx0aGlzLnBvc091dCtYKSxRKSx0aGlzLnBvc091dCs9WCxRKz1YfXJldHVybiAkfXhvZkludG8oJCl7aWYoIXRoaXMuZW5hYmxlWE9GKXRocm93IEVycm9yKCJYT0YgaXMgbm90IHBvc3NpYmxlIGFmdGVyIGRpZ2VzdCBjYWxsIik7cmV0dXJuIHRoaXMud3JpdGVJbnRvKCQpfXhvZigkKXtyZXR1cm4gVSQoJCksdGhpcy54b2ZJbnRvKG5ldyBVaW50OEFycmF5KCQpKX1kaWdlc3RJbnRvKCQpe2lmKHIkKCQsdGhpcyksdGhpcy5maW5pc2hlZCl0aHJvdyBFcnJvcigiZGlnZXN0KCkgd2FzIGFscmVhZHkgY2FsbGVkIik7cmV0dXJuIHRoaXMuZW5hYmxlWE9GPSExLHRoaXMud3JpdGVJbnRvKCQpLHRoaXMuZGVzdHJveSgpLCR9ZGlnZXN0KCl7cmV0dXJuIHRoaXMuZGlnZXN0SW50byhuZXcgVWludDhBcnJheSh0aGlzLm91dHB1dExlbikpfX12YXIgU1E9a1EoKCQpPT5uZXcgWlooJCkpO3ZhciBCWD0zMixnRj1TeW1ib2woIlgyNTUxOVNrIik7ZnVuY3Rpb24gdlEoJCl7aWYoJC5ieXRlTGVuZ3RoIT09QlgpcmV0dXJuIEcoMTApO3JldHVybiBOKCQpfXZhciBiPSgxbjw8MjU1biktMTluLGZYPTEyMTY2NW4seVE9bmV3IFVpbnQ4QXJyYXkoMzIpO3lRWzBdPTk7ZnVuY3Rpb24gYlEoJCl7bGV0IEo9MG47Zm9yKGxldCBaPSQubGVuZ3RoLTE7Wj49MDtaLS0pSj1KPDw4bnxCaWdJbnQoJFtaXSk7cmV0dXJuIEp9ZnVuY3Rpb24ga1goJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMzIpLFo9KCQlYitiKSViO2ZvcihsZXQgUT0wO1E8MzI7USsrKUpbUV09TnVtYmVyKFomMHhmZm4pLFo+Pj04bjtyZXR1cm4gSn1mdW5jdGlvbiBtWCgkKXtsZXQgSj0kLnNsaWNlKCk7cmV0dXJuIEpbMzFdJj0xMjcsYlEoSil9ZnVuY3Rpb24gRVgoJCl7bGV0IEo9JC5zbGljZSgpO3JldHVybiBKWzBdJj0yNDgsSlszMV0mPTEyNyxKWzMxXXw9NjQsSn1mdW5jdGlvbiBhJCgkLEosWil7bGV0IFE9LSQsVj0oSl5aKSZRO3JldHVybltKXlYsWl5WXX1mdW5jdGlvbiBnWCgkKXtsZXQgSj1iLTJuLFo9KCQlYitiKSViLFE9MW47d2hpbGUoSj4wbil7aWYoSiYxbilRPVEqWiViO1o9WipaJWIsSj4+PTFufXJldHVybiBRfWZ1bmN0aW9uIFNYKCQsSil7bGV0IFo9RVgoJCksUT1tWChKKSxWPTFuLFg9MG4sWT1RLFc9MW4sej0wbixLPWJRKFopO2ZvcihsZXQgRj0yNTQ7Rj49MDtGLS0pe2xldCBPPUs+PkJpZ0ludChGKSYxbjt6Xj1PLFtWLFldPWEkKHosVixZKSxbWCxXXT1hJCh6LFgsVyksej1PO2xldCBIPShWK1gpJWIsUj1IKkglYixxPShWLVgrYiklYixNPXEqcSViLFU9KFItTStiKSViLFA9KFkrVyklYixUPShZLVcrYiklYipIJWIsQz1QKnElYixBPShUK0MpJWIsXz0oVC1DK2IpJWI7WT1BKkElYixXPVEqXypfJWIsVj1SKk0lYixYPVUqKFIrZlgqVSklYn1yZXR1cm5bVixZXT1hJCh6LFYsWSksW1gsV109YSQoeixYLFcpLFouZmlsbCgwKSxrWChWKmdYKFgpJWIpfWZ1bmN0aW9uIGhRKCQpe3JldHVybiBTWCgkLHlRKX12YXIgUVo9bmV3IFVpbnQ4QXJyYXkoWzQ4LDQ2LDIsMSwwLDQ4LDUsNiwzLDQzLDEwMSwxMTIsNCwzNCw0LDMyXSk7ZnVuY3Rpb24gbFEoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoUVoubGVuZ3RoKzMyKTtyZXR1cm4gSi5zZXQoUVopLEouc2V0KCQuc3ViYXJyYXkoMCwzMiksUVoubGVuZ3RoKSxKfXZhciBWWj1uZXcgVWludDhBcnJheShbNDgsNDYsMiwxLDAsNDgsNSw2LDMsNDMsMTAxLDExMCw0LDM0LDQsMzJdKTtmdW5jdGlvbiB1USgkKXtsZXQgSj1uZXcgVWludDhBcnJheShWWi5sZW5ndGgrMzIpO3JldHVybiBKLnNldChWWiksSi5zZXQoJC5zdWJhcnJheSgwLDMyKSxWWi5sZW5ndGgpLEp9ZnVuY3Rpb24gaVEoJCl7cmV0dXJuIHR5cGVvZiAkPT09InN0cmluZyI/bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpOiR9ZnVuY3Rpb24gdzAoJCl7bGV0IEo9bmV3IEFycmF5QnVmZmVyKCQuYnl0ZUxlbmd0aCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KEopLnNldCgkKSxKfWNsYXNzIGIwe3ZlcmlmeUtleXM9bmV3IE1hcDthc3luYyBnZW5SYW5kb21CeXRlcygkKXtyZXR1cm4gTSQoJCl9YXN5bmMgZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpe3JldHVybiBNJCgzMil9YXN5bmMgZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLEope2xldCBaPU0kKDI0KSxWPXNKKEosWikuZW5jcnlwdCgkKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWy4uLlosLi4uVl0pfWFzeW5jIGRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxKKXtsZXQgWj0kLnNsaWNlKDAsMjQpLFE9JC5zbGljZSgyNCk7cmV0dXJuIHNKKEosWikuZGVjcnlwdChRKX1hc3luYyBkZXJpdmVFZDI1NTE5S2V5UGFpcigkKXtsZXQgSj0kLFo9bFEoSiksUT13MChaKSxWO3RyeXtsZXQgSz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsic2lnbiJdKTtWPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoImp3ayIsSyl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX1pZih0eXBlb2YgVi54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIkVkMjU1MTkgSldLIG1pc3NpbmcgeCIpO2xldCBYPVYueDtWLmQ9dm9pZCAwO2xldCBZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoImp3ayIse2t0eToiT0tQIixjcnY6IkVkMjU1MTkiLHg6WH0se25hbWU6IkVkMjU1MTkifSwhMCxbInZlcmlmeSJdKSxXPW5ldyBVaW50OEFycmF5KGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoInJhdyIsWSkpO3RoaXMudmVyaWZ5S2V5cy5zZXQoSDAoVyksWSk7bGV0IHo9bmV3IFVpbnQ4QXJyYXkoNjQpO3JldHVybiB6LnNldChKLDApLHouc2V0KFcsMzIpLHtrZXlUeXBlOiJlZDI1NTE5Iixwcml2YXRlS2V5OnoscHVibGljS2V5Old9fWFzeW5jIGltcG9ydFNpZ25LZXkoJCl7bGV0IEo9JC5zdWJhcnJheSgwLDMyKSxaPWxRKEopLFE9dzAoWik7dHJ5e3JldHVybiBhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiRWQyNTUxOSJ9LCExLFsic2lnbiJdKX1maW5hbGx5e1ouZmlsbCgwKSxuZXcgVWludDhBcnJheShRKS5maWxsKDApfX1hc3luYyBpbXBvcnRWZXJpZnlLZXkoJCl7bGV0IEo9SDAoJCksWj10aGlzLnZlcmlmeUtleXMuZ2V0KEopO2lmKFopcmV0dXJuIFo7bGV0IFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3Iix3MCgkKSx7bmFtZToiRWQyNTUxOSJ9LCExLFsidmVyaWZ5Il0pO3JldHVybiB0aGlzLnZlcmlmeUtleXMuc2V0KEosUSksUX1hc3luYyBzaWduRWQyNTUxOSgkLEope2xldCBaPWlRKCQpLFE9YXdhaXQgdGhpcy5pbXBvcnRTaWduS2V5KEopLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnNpZ24oe25hbWU6IkVkMjU1MTkifSxRLHcwKFopKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoVil9YXN5bmMgY2hlY2tTaWdFZDI1NTE5KCQsSixaKXtsZXQgUT1pUShKKTt0cnl7bGV0IFY9YXdhaXQgdGhpcy5pbXBvcnRWZXJpZnlLZXkoWik7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS52ZXJpZnkoe25hbWU6IkVkMjU1MTkifSxWLHcwKCQpLHcwKFEpKX1jYXRjaHtyZXR1cm4hMX19YXN5bmMgYmxha2UzKCQpe3JldHVybiBTUSgkKX1hc3luYyBnZW5YMjU1MTkoKXtsZXQgJD1hd2FpdCBNJCgzMik7JFswXSY9MjQ4LCRbMzFdJj0xMjcsJFszMV18PTY0O2xldFtKLFpdPXZRKCQpO2lmKFohPT0wfHxKPT09dm9pZCAwKXRocm93ICQuZmlsbCgwKSxFcnJvcigiWDI1NTE5IHNjYWxhciBicmFuZCBmYWlsZWQiKTtsZXQgUT1oUShKKSxWPXVRKEopLFg9dzAoVik7dHJ5e2xldCBZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixYLHtuYW1lOiJYMjU1MTkifSwhMCxbImRlcml2ZUJpdHMiXSksVz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJqd2siLFkpO2lmKHR5cGVvZiBXLnghPT0ic3RyaW5nIil0aHJvdyBFcnJvcigiWDI1NTE5IEpXSyBtaXNzaW5nIHgiKTtsZXQgej1oWihXLngpO2lmKFcuZD12b2lkIDAsIW4oeixRKSl0aHJvdyBFcnJvcigiWDI1NTE5IFdlYkNyeXB0byBwdWIgIT0gUkZDIDc3NDgiKTtyZXR1cm57cHJpdjpKLHB1YjpRfX1jYXRjaChZKXt0aHJvdyBKLmZpbGwoMCksWX1maW5hbGx5e1YuZmlsbCgwKSxuZXcgVWludDhBcnJheShYKS5maWxsKDApfX1hc3luYyB4MjU1MTlTaGFyZWQoJCxKKXtsZXQgWj11USgkKSxRPXcwKFopO3RyeXtsZXQgVj1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiWDI1NTE5In0sITEsWyJkZXJpdmVCaXRzIl0pLFg9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3Iix3MChKKSx7bmFtZToiWDI1NTE5In0sITEsW10pLFk9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmRlcml2ZUJpdHMoe25hbWU6IlgyNTUxOSIscHVibGljOlh9LFYsMjU2KTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWSl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX19fXZhciB2WD1uZXcgYjAscyQ9dlg7dmFyIGgwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyU3RyaW5nKEouaGFuZGxlKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyU3RyaW5nKEoubGFiZWwpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAkLndyaXRlVmFySW50KEouaWR4Pz8wKX0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhclN0cmluZygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPSQucmVhZFZhclN0cmluZygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtYLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBOKHtoYW5kbGU6SixsYWJlbDpRLGlkeDpYfSl9fTt2YXIgdCQ9MSxYWj17ZW5jb2RlKCQsSil7aWYoSi52IT09dCQpcmV0dXJuIDEwO2xldFssWl09JDAoSi5tYXN0ZXJTZWVkKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEoudik7aWYoUSE9PTApcmV0dXJuIFE7JC53cml0ZUJ5dGVzKEoubWFzdGVyU2VlZCk7bGV0IFY9JC53cml0ZVZhckludChKLmhvc3RzLmxlbmd0aCk7aWYoViE9PTApcmV0dXJuIFY7Zm9yKGxldCBYIG9mIEouaG9zdHMpe2xldCBZPSQud3JpdGVTdHJ1Y3QoaDAsWCk7aWYoWSE9PTApcmV0dXJuIFl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKIT09dCQpcmV0dXJuIEcoMTQpO2xldFtRLFZdPSQucmVhZEJ5dGVzKFIwKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbWCxZXT0kMChRKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihYPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwfHxXPDApcmV0dXJuIEcoMTApO2xldCBLPVtdO2ZvcihsZXQgRj0wO0Y8VztGKyspe2xldFtPLEhdPSQucmVhZFN0cnVjdChoMCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7aWYoTz09PXZvaWQgMClyZXR1cm4gRygxNCk7Sy5wdXNoKE8pfXJldHVybiBOKHt2OnQkLG1hc3RlclNlZWQ6WCxob3N0czpLfSl9fTtmdW5jdGlvbiBwUSgkLEope2xldFtaLFFdPSQwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtWLFhdPSQwKFouc2xpY2UoKSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE4oe3Y6dCQsbWFzdGVyU2VlZDpWLGhvc3RzOkoubWFwKChZKT0+KHtoYW5kbGU6WS5oYW5kbGUsbGFiZWw6WS5sYWJlbCxpZHg6WS5pZHg/PzB9KSl9KX12YXIgZSQ9e2VuY29kZSgkLEope2xldFssWl09JDAoSi5tYXN0ZXJTZWVkKTtpZihaIT09MClyZXR1cm4gWjskLndyaXRlQnl0ZXMoSi5tYXN0ZXJTZWVkKTtsZXQgUT0kLndyaXRlVmFySW50KEouaG9zdHMubGVuZ3RoKTtpZihRIT09MClyZXR1cm4gUTtmb3IobGV0IFYgb2YgSi5ob3N0cyl7bGV0IFg9JC53cml0ZVN0cnVjdChoMCxWKTtpZihYIT09MClyZXR1cm4gWH1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKFIwKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbUSxWXT0kMChKKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbWCxZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihYPT09dm9pZCAwfHxYPDApcmV0dXJuIEcoMTApO2xldCBXPVtdO2ZvcihsZXQgej0wO3o8WDt6Kyspe2xldFtLLEZdPSQucmVhZFN0cnVjdChoMCk7aWYoRiE9PTApcmV0dXJuIEcoRik7aWYoSz09PXZvaWQgMClyZXR1cm4gRygxNCk7Vy5wdXNoKEspfXJldHVybiBOKHttYXN0ZXJTZWVkOlEsaG9zdHM6V30pfX07dmFyIHlYPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5xcnBhaXIudjEiKSxQJD0zMixiWD1QJCsyNCsxNixoWD0zMixONj1TeW1ib2woIkRIS0VSZXEiKSxINj1TeW1ib2woIkRIS0VSZXNwIik7ZnVuY3Rpb24gY1EoJCl7aWYoJC5ieXRlTGVuZ3RoIT09UCQpcmV0dXJuIEcoMTApO3JldHVybiBOKCQpfWZ1bmN0aW9uIG5RKCQpe2lmKCQuYnl0ZUxlbmd0aDxiWClyZXR1cm4gRygxMCk7cmV0dXJuIE4oJCl9dmFyICRKPW5ldyBiMDthc3luYyBmdW5jdGlvbiBZWigkLEosWixRKXtsZXQgVjt0cnl7Vj1hd2FpdCAkSi54MjU1MTlTaGFyZWQoJCxKKX1jYXRjaHtyZXR1cm4gRygyOSl9dHJ5e2lmKFYuYnl0ZUxlbmd0aCE9PVAkfHxWLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDEwKTtsZXQgWD1JMChWLHlYKSxZPUkwKFgsSTAoWixRKSk7dHJ5e2xldCBXPWF3YWl0ICRKLmJsYWtlMyhZKTtyZXR1cm4gTihXLnNsaWNlKDAsaFgpKX1maW5hbGx5e1guZmlsbCgwKSxZLmZpbGwoMCl9fWZpbmFsbHl7Vi5maWxsKDApfX1jbGFzcyBKSnsjJDsjSjtjb25zdHJ1Y3RvcigkLEope3RoaXMuIyQ9JCx0aGlzLiNKPUp9c3RhdGljIGFzeW5jIGNyZWF0ZSgpe2xldCAkO3RyeXtsZXQgSj1hd2FpdCAkSi5nZW5YMjU1MTkoKTskPUoucHJpdjtsZXRbWixRXT1jUShKLnB1Yik7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0IFY9bmV3IEpKKCQsWik7cmV0dXJuICQ9dm9pZCAwLE4oVil9Y2F0Y2h7cmV0dXJuIEcoMjkpfWZpbmFsbHl7JD8uZmlsbCgwKX19d2lwZSgpe3RoaXMuIyQuZmlsbCgwKX1nZXQgZGhrZVJlcSgpe2xldFskLEpdPWNRKHRoaXMuI0ouc2xpY2UoKSk7aWYoJD09PXZvaWQgMCl0aHJvdyBFcnJvcihgZGhrZVJlcSAke0p9YCk7cmV0dXJuICR9YXN5bmMgZmluaXNoKCQpe2xldCBKPSQuc3ViYXJyYXkoMCxQJCksWj0kLnN1YmFycmF5KFAkKSxbUSxWXT1hd2FpdCBZWih0aGlzLiMkLEosdGhpcy4jSixKKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgWDt0cnl7dHJ5e1g9YXdhaXQgJEouZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFEpfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgWT1uZXcgZyhYKSxbVyx6XT1ZLnJlYWRTdHJ1Y3QoZSQpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMTQpO3RyeXtsZXRbSyxGXT1XMC5mcm9tQnl0ZXMoVy5tYXN0ZXJTZWVkKTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gdGhpcy53aXBlKCksTih7ZW5jbGF2ZTpLLGhvc3RzOlcuaG9zdHMubWFwKChPKT0+KHsuLi5PfSkpfSl9ZmluYWxseXtXLm1hc3RlclNlZWQuZmlsbCgwKX19ZmluYWxseXtRLmZpbGwoMCksWD8uZmlsbCgwKX19fWZ1bmN0aW9uIEEwKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KCQpO2lmKCQ+MCljcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKEopO3JldHVybiBKfXZhciBsMD0zMixaSj0iRElQTE9NQVRJQyIsVTA9InB1YmxpYy1rZXkiLGxYPS03LHVYPS04LGlYPS0yNTcsUUo9W3t0eXBlOlUwLGFsZzpsWH0se3R5cGU6VTAsYWxnOnVYfSx7dHlwZTpVMCxhbGc6aVh9XTtmdW5jdGlvbiBwWCgkKXtyZXR1cm4gJC50cmltKCkudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cLiQvLCIiKXx8ImxvY2FsaG9zdCJ9ZnVuY3Rpb24gTDAoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoJC5ieXRlTGVuZ3RoKTtyZXR1cm4gSi5zZXQoJCksSi5idWZmZXJ9ZnVuY3Rpb24gVkooJCl7aWYoJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXJldHVybiBuZXcgVWludDhBcnJheSgkKS5zbGljZSgpO3JldHVybiBuZXcgVWludDhBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKS5zbGljZSgpfWZ1bmN0aW9uIHUwKCQpe2lmKCQ/LnJwSWQhPT12b2lkIDApcmV0dXJuIE4oJC5ycElkKTtpZih0eXBlb2YgbG9jYXRpb24+InUiKXJldHVybiBHKDkpO3JldHVybiBOKHBYKGxvY2F0aW9uLmhvc3RuYW1lKSl9dmFyIGRRPSIiO2Z1bmN0aW9uIGswKCQpe2lmKCQgaW5zdGFuY2VvZiBFcnJvcil7ZFE9JC5tZXNzYWdlPT09IiI/JC5uYW1lOmAkeyQubmFtZX06ICR7JC5tZXNzYWdlfWA7cmV0dXJufWRRPVN0cmluZygkKX1mdW5jdGlvbiBpMCgpe2lmKHR5cGVvZiBuYXZpZ2F0b3I+InUifHwhbmF2aWdhdG9yLmNyZWRlbnRpYWxzfHx0eXBlb2YgUHVibGljS2V5Q3JlZGVudGlhbD4idSIpcmV0dXJuIDI0O3JldHVybiAwfWZ1bmN0aW9uIHAwKCQpe2lmKCQ9PT1udWxsfHwkLnR5cGUhPT1VMHx8ISgicmF3SWQiaW4gJCl8fHR5cGVvZiAkLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMhPT0iZnVuY3Rpb24iKXJldHVybiBHKDI3KTtyZXR1cm4gTigkKX1mdW5jdGlvbiBHWigkKXtpZigkPT09InBsYXRmb3JtInx8JD09PSJjcm9zcy1wbGF0Zm9ybSIpcmV0dXJuICQ7cmV0dXJufWZ1bmN0aW9uIG9RKCQpe2lmKC9pUGhvbmV8aVBhZHxpUG9kL2kudGVzdCgkKSlyZXR1cm4iaW9zIjtpZigvQW5kcm9pZC9pLnRlc3QoJCkpcmV0dXJuImFuZHJvaWQiO2lmKC9NYWMgT1MgWHxNYWNpbnRvc2gvaS50ZXN0KCQpKXJldHVybiJtYWNvcyI7aWYoL1dpbmRvd3MvaS50ZXN0KCQpKXJldHVybiJ3aW5kb3dzIjtpZigvTGludXgvaS50ZXN0KCQpKXJldHVybiJsaW51eCI7cmV0dXJuIm90aGVyIn1mdW5jdGlvbiB6WigkKXtsZXQgSj0kLnJlc3BvbnNlO2lmKCEoImdldFRyYW5zcG9ydHMiaW4gSikpcmV0dXJuO2xldCBaPUouZ2V0VHJhbnNwb3J0cztpZih0eXBlb2YgWiE9PSJmdW5jdGlvbiIpcmV0dXJuO2xldCBRPVouY2FsbChKKTtpZighQXJyYXkuaXNBcnJheShRKSlyZXR1cm47bGV0IFY9W107Zm9yKGxldCBYIG9mIFEpaWYodHlwZW9mIFg9PT0ic3RyaW5nIiYmWC5sZW5ndGg+MClWLnB1c2goWCk7cmV0dXJuIFYubGVuZ3RoPT09MD92b2lkIDA6Vn12YXIgY1g9MzIsblg9NjQsV1o9MzcsclE9MTY7ZnVuY3Rpb24gYVEoJCl7bGV0IEo9JC5yZXNwb25zZTtpZighKCJnZXRBdXRoZW50aWNhdG9yRGF0YSJpbiBKKSlyZXR1cm47bGV0IFo9Si5nZXRBdXRoZW50aWNhdG9yRGF0YTtpZih0eXBlb2YgWiE9PSJmdW5jdGlvbiIpcmV0dXJuO2xldCBRPVouY2FsbChKKTtpZighKFEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpcmV0dXJuO2xldCBWPW5ldyBVaW50OEFycmF5KFEpO2lmKFYuYnl0ZUxlbmd0aDxXWityUSlyZXR1cm47bGV0IFg9VltjWF07aWYoWD09PXZvaWQgMHx8KFgmblgpPT09MClyZXR1cm47cmV0dXJuIFYuc2xpY2UoV1osV1orclEpfWFzeW5jIGZ1bmN0aW9uIHNRKCQpe2xldCBKPWkwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09dTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtc2VlZCIsWD17cmVzaWRlbnRLZXk6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6ITAsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQifTtpZigkPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClYLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PSQuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IFk9e2xhcmdlQmxvYjp7c3VwcG9ydDoicmVxdWlyZWQifX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpBMChsMCkscnA6e2lkOlosbmFtZTokPy5ycE5hbWU/P1pKfSx1c2VyOntpZDpBMCgxNiksbmFtZTpWLGRpc3BsYXlOYW1lOlZ9LHB1YktleUNyZWRQYXJhbXM6UUosYXV0aGVudGljYXRvclNlbGVjdGlvbjpYLGV4dGVuc2lvbnM6WSwuLi4kPy5oaW50cyE9PXZvaWQgMD97aGludHM6JC5oaW50c306e319fSl9Y2F0Y2goTyl7cmV0dXJuIGswKE8pLEcoMzApfWxldFt6LEtdPXAwKFcpO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMjcpO2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8uc3VwcG9ydGVkIT09ITApcmV0dXJuIEcoMzApO3JldHVybiBOKG5ldyBVaW50OEFycmF5KHoucmF3SWQpKX1hc3luYyBmdW5jdGlvbiBGWigkLEosWil7bGV0IFE9aTAoKTtpZihRIT09MClyZXR1cm4gUTtsZXRbVixYXT11MChaKTtpZihYIT09MClyZXR1cm4gWDtpZihWPT09dm9pZCAwKXJldHVybiA5O2xldCBZPXtsYXJnZUJsb2I6e3dyaXRlOkwwKEopfX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpBMChsMCkscnBJZDpWLGFsbG93Q3JlZGVudGlhbHM6W3t0eXBlOlUwLGlkOkwwKCQpfV0sdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQiLGV4dGVuc2lvbnM6WSwuLi5aPy5oaW50cyE9PXZvaWQgMD97aGludHM6Wi5oaW50c306e319fSl9Y2F0Y2goTyl7cmV0dXJuIGswKE8pLDMwfWxldFt6LEtdPXAwKFcpO2lmKEshPT0wKXJldHVybiBLO2lmKHo9PT12b2lkIDApcmV0dXJuIDI3O2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8ud3JpdHRlbiE9PSEwKXJldHVybiAzMDtyZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBLWigkLEosWixRKXtsZXQgVj17Y2hhbGxlbmdlOkEwKGwwKSxycElkOiQsdXNlclZlcmlmaWNhdGlvbjoicHJlZmVycmVkIn07aWYoSj8uaGludHMhPT12b2lkIDApVi5oaW50cz1KLmhpbnRzO2lmKFohPT12b2lkIDApVi5hbGxvd0NyZWRlbnRpYWxzPVt7dHlwZTpVMCxpZDpMMChaKX1dO2lmKFEhPT12b2lkIDApVi5leHRlbnNpb25zPVE7bGV0IFg7dHJ5e1g9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OlZ9KX1jYXRjaCh6KXtyZXR1cm4gazAoeiksRygzMCl9bGV0W1ksV109cDAoWCk7aWYoVyE9PTApcmV0dXJuIEcoVyk7aWYoWT09PXZvaWQgMClyZXR1cm4gRygyNyk7cmV0dXJuIE4oWSl9YXN5bmMgZnVuY3Rpb24gdFEoJCxKKXtsZXQgWj1pMCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFZdPXUwKEopO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFg9JDtpZihYPT09dm9pZCAwKXtsZXRbTyxIXT1hd2FpdCBLWihRLEopO2lmKEghPT0wJiZKPy5oaW50cyE9PXZvaWQgMClbTyxIXT1hd2FpdCBLWihRLHtycElkOkoucnBJZCxycE5hbWU6Si5ycE5hbWV9KTtpZihIIT09MClyZXR1cm4gRyhIKTtpZihPPT09dm9pZCAwKXJldHVybiBHKDI3KTtYPW5ldyBVaW50OEFycmF5KE8ucmF3SWQpfWxldFtZLFddPWF3YWl0IEtaKFEsSixYLHtsYXJnZUJsb2I6e3JlYWQ6ITB9fSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7aWYoWT09PXZvaWQgMClyZXR1cm4gRygyNyk7bGV0IEs9WS5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iO2lmKEs9PT12b2lkIDB8fEsuYmxvYj09PXZvaWQgMClyZXR1cm4gRyg3KTtsZXQgRj1WSihLLmJsb2IpO2lmKEYuYnl0ZUxlbmd0aD09PTApcmV0dXJuIEcoNyk7cmV0dXJuIE4oe2Jsb2I6RixjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoWS5yYXdJZCl9KX12YXIgTlo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCJkaXBsb21hdGljLnByZi52MSIpLHokPSJkaXBsb21hdGljLXByZiIsT1o9MzI7ZnVuY3Rpb24gclgoJCl7aWYoJD09PXZvaWQgMClyZXR1cm5bXTtpZigkIGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm5bJF07cmV0dXJuICQuZmlsdGVyKChKKT0+Si5ieXRlTGVuZ3RoPjApfWFzeW5jIGZ1bmN0aW9uIGVRKCQpe2xldCBKPWkwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09dTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kPy51c2VyTmFtZT8/eiQsWD0kPy5kaXNwbGF5TmFtZT8/VixZPUEwKDE2KSxXPSQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PT09ImNyb3NzLXBsYXRmb3JtIix6PXtyZXNpZGVudEtleTpXPyJkaXNjb3VyYWdlZCI6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6IVcsdXNlclZlcmlmaWNhdGlvbjpXPyJwcmVmZXJyZWQiOiJyZXF1aXJlZCJ9O2lmKCQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50IT09dm9pZCAwKXouYXV0aGVudGljYXRvckF0dGFjaG1lbnQ9JC5hdXRoZW50aWNhdG9yQXR0YWNobWVudDtsZXQgSz17Y2hhbGxlbmdlOkEwKGwwKSxycDp7aWQ6WixuYW1lOiQ/LnJwTmFtZT8/Wkp9LHVzZXI6e2lkOlksbmFtZTpWLGRpc3BsYXlOYW1lOlh9LHB1YktleUNyZWRQYXJhbXM6UUosYXV0aGVudGljYXRvclNlbGVjdGlvbjp6LC4uLiQ/LmhpbnRzIT09dm9pZCAwP3toaW50czokLmhpbnRzfTp7fSwuLi4kPy5leGNsdWRlQ3JlZGVudGlhbHMhPT12b2lkIDAmJiQuZXhjbHVkZUNyZWRlbnRpYWxzLmxlbmd0aD4wP3tleGNsdWRlQ3JlZGVudGlhbHM6JC5leGNsdWRlQ3JlZGVudGlhbHMubWFwKChJKT0+KHt0eXBlOlUwLGlkOkwwKEkpfSkpfTp7fX0sRj0kPy5zYWx0IT09dm9pZCAwP0wwKCQuc2FsdCk6dm9pZCAwLE89KEkpPT5uYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6ey4uLkssZXh0ZW5zaW9uczpJJiZGIT09dm9pZCAwP3twcmY6e2V2YWw6e2ZpcnN0OkZ9fX06e3ByZjp7fX19fSksSDt0cnl7SD1hd2FpdCBPKEYhPT12b2lkIDApfWNhdGNoKEkpe2lmKEY9PT12b2lkIDB8fCFvWChJKSlyZXR1cm4gazAoSSksRygzMCk7dHJ5e0g9YXdhaXQgTyghMSl9Y2F0Y2goVCl7cmV0dXJuIGswKFQpLEcoMzApfX1sZXRbUixxXT1wMChIKTtpZihxIT09MClyZXR1cm4gRyhxKTtpZihSPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgTT1SLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKSxVPSRWKE0ucHJmPy5yZXN1bHRzPy5maXJzdCksUD1NLnByZj8uZW5hYmxlZD09PSEwfHxVIT09dm9pZCAwO2lmKFcmJlUhPT12b2lkIDApVS5maWxsKDApO3JldHVybiBOKHtjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoUi5yYXdJZCksdXNlcklkOm5ldyBVaW50OEFycmF5KFkpLHByZkVuYWJsZWQ6UCxwcmY6Vz92b2lkIDA6VSxhdHRhY2htZW50OkdaKFIuYXV0aGVudGljYXRvckF0dGFjaG1lbnQpLHRyYW5zcG9ydHM6elooUiksYWFndWlkOmFRKFIpfSl9ZnVuY3Rpb24gb1goJCl7aWYoISgkIGluc3RhbmNlb2YgRXJyb3IpKXJldHVybiExO3JldHVybiAkLm5hbWU9PT0iTm90U3VwcG9ydGVkRXJyb3IifHwkLm5hbWU9PT0iVHlwZUVycm9yIn1mdW5jdGlvbiAkVigkKXtpZigkPT09dm9pZCAwKXJldHVybjtsZXQgSj1WSigkKTtpZihKLmJ5dGVMZW5ndGg8T1ope0ouZmlsbCgwKTtyZXR1cm59aWYoSi5ieXRlTGVuZ3RoPT09T1opcmV0dXJuIEo7bGV0IFo9Si5zbGljZSgwLE9aKTtyZXR1cm4gSi5maWxsKDApLFp9YXN5bmMgZnVuY3Rpb24gSFooJCl7bGV0IEo9aTAoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbWixRXT11MCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBWPSQ/LnNhbHQ/P05aLFg9TDAoViksWT17Y2hhbGxlbmdlOkEwKGwwKSxycElkOlosdXNlclZlcmlmaWNhdGlvbjoicHJlZmVycmVkIixleHRlbnNpb25zOntwcmY6e2V2YWw6e2ZpcnN0Olh9fX19O2lmKCQ/LmhpbnRzIT09dm9pZCAwKVkuaGludHM9JC5oaW50cztsZXQgVz1yWCgkPy5jcmVkSWQpO2lmKFcubGVuZ3RoPjApWS5hbGxvd0NyZWRlbnRpYWxzPVcubWFwKChSKT0+KHt0eXBlOlUwLGlkOkwwKFIpfSkpO2xldCB6O3RyeXt6PWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoe3B1YmxpY0tleTpZfSl9Y2F0Y2goUil7cmV0dXJuIGswKFIpLEcoMzApfWxldFtLLEZdPXAwKHopO2lmKEYhPT0wKXJldHVybiBHKEYpO2lmKEs9PT12b2lkIDApcmV0dXJuIEcoMjcpO2xldCBPPUsuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLnByZj8ucmVzdWx0cztpZihPPy5maXJzdD09PXZvaWQgMClyZXR1cm4gRyg3KTtsZXQgSD0kVihPLmZpcnN0KTtpZihIPT09dm9pZCAwKXJldHVybiBHKDI3KTtyZXR1cm4gTih7cHJmOkgsY3JlZElkOm5ldyBVaW50OEFycmF5KEsucmF3SWQpLGF0dGFjaG1lbnQ6R1ooSy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCksdHJhbnNwb3J0czp6WihLKX0pfXZhciBYSj0iIjt2YXIgV0o9dHlwZW9mIGdsb2JhbFRoaXMuV29ya2VyPT09ImZ1bmN0aW9uIj9nbG9iYWxUaGlzLldvcmtlcjp2b2lkIDAsUlo9V0o9PT12b2lkIDA/dm9pZCAwOldKLnByb3RvdHlwZS5wb3N0TWVzc2FnZSxZSjtmdW5jdGlvbiBhWCgpe2lmKHR5cGVvZiBYSiE9PSJzdHJpbmcifHxYSi5sZW5ndGg9PT0wKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gd29ya2VyIHNvdXJjZSBub3QgZW1iZWRkZWQ7IHJ1biBwa2cgYnVpbGQgYmVmb3JlIHNwYXduIik7cmV0dXJuIGF0b2IoWEopfWZ1bmN0aW9uIHNYKCl7aWYoWUohPT12b2lkIDApcmV0dXJuIFlKO2xldCAkPW5ldyBCbG9iKFthWCgpXSx7dHlwZToidGV4dC9qYXZhc2NyaXB0In0pO3JldHVybiBZSj1VUkwuY3JlYXRlT2JqZWN0VVJMKCQpLFlKfWZ1bmN0aW9uIEpWKCl7aWYoV0o9PT12b2lkIDApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSBXb3JrZXIgQVBJIHVuYXZhaWxhYmxlOyBjYW5ub3Qgc3Bhd24gc3luYyB3b3JrZXIiKTtyZXR1cm4gbmV3IFdKKHNYKCkse3R5cGU6Im1vZHVsZSJ9KX1mdW5jdGlvbiBaVigkLEosWil7aWYoUlo9PT12b2lkIDApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSBXb3JrZXIgQVBJIHVuYXZhaWxhYmxlOyBjYW5ub3QgcG9zdCB0byBzeW5jIHdvcmtlciIpO2lmKFohPT12b2lkIDAmJloubGVuZ3RoPjApUlouY2FsbCgkLEose3RyYW5zZmVyOlp9KTtlbHNlIFJaLmNhbGwoJCxKKX12YXIgdFg9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCJkaXBsb21hdGljLmJpbmQudjEiKSxxWj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMuYmluZHRhZy52MSIpLGVYPTMyLCRZPTMyLEpZPTE2LEcwPW5ldyBiMDtjbGFzcyBXMHsjJDtjb25zdHJ1Y3RvcigkKXt0aGlzLiMkPSR9c3RhdGljIGFzeW5jIGZyb21SYW5kb20oKXtsZXQgJD1hd2FpdCBHMC5nZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCksW0osWl09JDAoJCk7aWYoWiE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7Wn0pYCk7cmV0dXJuIG5ldyBXMChKKX1zdGF0aWMgZnJvbUJ5dGVzKCQpe2xldFtKLFpdPSQwKCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtRLFZdPSQwKEouc2xpY2UoKSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE4obmV3IFcwKFEpKX1hc3luYyBzZWFsV2l0aFBhc3NrZXkoJCl7bGV0IEo9JD8uc2FsdD8/TlosWj0kPy5jcmVkSWQsUT1aLFY9JD8uY3JlYXRlQ3JlZElmTmVlZGVkPT09ITAmJihaPT09dm9pZCAwfHwhKFogaW5zdGFuY2VvZiBVaW50OEFycmF5KSYmWi5sZW5ndGg9PT0wKSxYLFk7aWYoVil7bGV0W0YsT109YXdhaXQgZVEoe3JwSWQ6JD8ucnBJZCxycE5hbWU6JD8ucnBOYW1lLHVzZXJOYW1lOiQ/LnVzZXJOYW1lPz96JCxkaXNwbGF5TmFtZTokPy5kaXNwbGF5TmFtZSxhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCxoaW50czokPy5oaW50cyxleGNsdWRlQ3JlZGVudGlhbHM6JD8uZXhjbHVkZUNyZWRlbnRpYWxzLHNhbHQ6Sn0pO2lmKE8hPT0wKXJldHVybiBHKE8pO2lmKEY9PT12b2lkIDApcmV0dXJuIEcoMzApO2lmKCFGLnByZkVuYWJsZWQpcmV0dXJuIEcoMzApO1E9Ri5jcmVkSWQsWD1GLFk9Ri5wcmZ9bGV0IFc9YXN5bmMoRixPLEgsUik9Pnt0cnl7bGV0W3EsTV09YXdhaXQgdGhpcy4jVihGKTtpZihNIT09MClyZXR1cm4gRyhNKTtpZihxPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTih7c2VhbGVkTWFzdGVyOnEsc2FsdDpKLnNsaWNlKCksY3JlZElkOk8uc2xpY2UoKSx1c2VySWQ6WD8udXNlcklkPT09dm9pZCAwP3ZvaWQgMDpYLnVzZXJJZC5zbGljZSgpLGF0dGFjaG1lbnQ6SD8/WD8uYXR0YWNobWVudCx0cmFuc3BvcnRzOlI/P1g/LnRyYW5zcG9ydHMsYWFndWlkOlg/LmFhZ3VpZD09PXZvaWQgMD92b2lkIDA6WC5hYWd1aWQuc2xpY2UoKX0pfWZpbmFsbHl7Ri5maWxsKDApfX07aWYoWSE9PXZvaWQgMCYmWCE9PXZvaWQgMClyZXR1cm4gVyhZLFguY3JlZElkLFguYXR0YWNobWVudCxYLnRyYW5zcG9ydHMpO2xldFt6LEtdPWF3YWl0IEhaKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6USxzYWx0OkosaGludHM6JD8uaGludHN9KTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDcpO3JldHVybiBXKHoucHJmLHouY3JlZElkLHouYXR0YWNobWVudCx6LnRyYW5zcG9ydHMpfWFzeW5jIGJpbmQoJCxKKXtpZihKIT09dm9pZCAwKXtmb3IobGV0IFggb2YgSilpZighYXdhaXQgdGhpcy4jWihYLmNyZWRJZCxYLnRhZykpcmV0dXJuIEcoMTApfWxldFtaLFFdPWF3YWl0IHRoaXMuc2VhbFdpdGhQYXNza2V5KCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldCBWPWF3YWl0IHRoaXMuI1EoWi5jcmVkSWQpO3JldHVybiBOKHsuLi5aLHRhZzpWfSl9c3RhdGljIGFzeW5jIHVuc2VhbFdpdGhQYXNza2V5KCQsSil7aWYoJC5sZW5ndGg9PT0wKXJldHVybiBHKDIyKTtsZXQgWj1bXTtmb3IobGV0IFcgb2YgJClpZihXLmNyZWRJZC5ieXRlTGVuZ3RoPjApWi5wdXNoKFcuY3JlZElkKTtsZXRbUSxWXT1hd2FpdCBIWih7cnBJZDpKLnJwSWQscnBOYW1lOkoucnBOYW1lLGhpbnRzOkouaGludHMsY3JlZElkOloubGVuZ3RoPjA/Wjp2b2lkIDAsc2FsdDpKLnNhbHR9KTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO2xldCBYPSQuZmluZCgoVyk9Pm4oVy5jcmVkSWQsUS5jcmVkSWQpKSxZPVg9PT12b2lkIDA/JDpbWCwuLi4kLmZpbHRlcigoVyk9PlchPT1YKV07dHJ5e2ZvcihsZXQgVyBvZiBZKXtsZXRbel09YXdhaXQgVzAuI1goVy5zZWFsZWRNYXN0ZXIsUS5wcmYpO2lmKHohPT12b2lkIDApcmV0dXJuIE4oe2VuY2xhdmU6eixjcmVkSWQ6US5jcmVkSWQuc2xpY2UoKX0pfXJldHVybiBHKDIwKX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fWFzeW5jIHBlcnNpc3RUb0xhcmdlQmxvYigkPVtdLEope2xldCBaPUo/LmNyZWRJZDtpZihaPT09dm9pZCAwKXtsZXRbWCxZXT1hd2FpdCBzUShKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihYPT09dm9pZCAwKXJldHVybiBHKDMwKTtaPVh9bGV0W1EsVl09dGhpcy4jRygkKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFg9YXdhaXQgRlooWixRLEopO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBOKFopfWZpbmFsbHl7US5maWxsKDApfX1zdGF0aWMgYXN5bmMgZnJvbUxhcmdlQmxvYigkKXtsZXRbSixaXT1hd2FpdCB0USgkPy5jcmVkSWQsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7cmV0dXJuIFcwLiN6KEouYmxvYixKLmNyZWRJZCl9ZmluYWxseXtKLmJsb2IuZmlsbCgwKX19c3RhdGljIGFzeW5jIGNsZWFyTGFyZ2VCbG9iKCQsSil7cmV0dXJuIEZaKCQsbmV3IFVpbnQ4QXJyYXkoUjApLEopfXN0YXRpYyBwYWlyUmVxdWVzdCgpe3JldHVybiBKSi5jcmVhdGUoKX1hc3luYyBwYWlyQWNjZXB0KCQsSil7bGV0IFo7dHJ5e1o9YXdhaXQgRzAuZ2VuWDI1NTE5KCl9Y2F0Y2h7cmV0dXJuIEcoMjkpfXRyeXtsZXRbUSxWXT1hd2FpdCBZWihaLnByaXYsJCwkLFoucHViKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0W1gsWV09dGhpcy4jSihKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihYPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFc9YXdhaXQgRzAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChYLFEpO3JldHVybiBuUShJMChaLnB1YixXKSl9Y2F0Y2h7cmV0dXJuIEcoMTIpfWZpbmFsbHl7WC5maWxsKDApfX1maW5hbGx5e1EuZmlsbCgwKX19ZmluYWxseXtaLnByaXYuZmlsbCgwKX19I0ooJCl7bGV0IEo9dGhpcy4jJC5zbGljZSgpLFtaLFFdPSQwKEopO2lmKFEhPT0wKXJldHVybiBKLmZpbGwoMCksRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBKLmZpbGwoMCksRygxMCk7dHJ5e2xldCBWPXttYXN0ZXJTZWVkOlosaG9zdHM6JC5tYXAoKFkpPT4oe2hhbmRsZTpZLmhhbmRsZSxsYWJlbDpZLmxhYmVsLGlkeDpZLmlkeD8/MH0pKX0sWD1uZXcgUzt0cnl7bGV0IFk9WC53cml0ZVN0cnVjdChlJCxWKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTihYLnJlc3VsdCgpKX1maW5hbGx5e1gud2lwZSgpfX1maW5hbGx5e1ouZmlsbCgwKX19c3Bhd25TeW5jV29ya2VyKCQpe2xldCBKPUpWKCksWj10aGlzLiMkLnNsaWNlKCk7cmV0dXJuIFpWKEose2lkOiQuaWQsb3A6InNldFNlZWQiLHNlZWQ6WixwZXJzaXN0OiQucGVyc2lzdH0sW1ouYnVmZmVyXSksSn1kZXJpdmVDaXBoZXIoJCxKKXtsZXQgWj0kLnNsaWNlKCksUT0oWSk9PnRoaXMuI0soWixZKSxWPShZKT0+dGhpcy4jRihaLFkpO3JldHVybntlbmNyeXB0Ok9iamVjdC5mcmVlemUoe2VuY3J5cHQ6UX0pLGRlY3J5cHQ6T2JqZWN0LmZyZWV6ZSh7ZGVjcnlwdDpWfSksYm90aDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlEsZGVjcnlwdDpWfSl9W0pdfWFzeW5jIGRlcml2ZUlkZW50aXR5KCQsSj0wKXtsZXQgWj0kLFE9SixWPWF3YWl0IHRoaXMuI1coWixRKSxYPVYucHVibGljS2V5O3JldHVybiBWLnByaXZhdGVLZXkuZmlsbCgwKSxPYmplY3QuZnJlZXplKHtwdWJsaWNLZXk6WCxzaWduOihZKT0+dGhpcy4jTihaLFEsWSksa2RtRm9yOihZKT0+dGhpcy4jSChaLFEsWSl9KX1hc3luYyNRKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KHRoaXMuIyQuYnl0ZUxlbmd0aCtxWi5ieXRlTGVuZ3RoKyQuYnl0ZUxlbmd0aCk7Si5zZXQodGhpcy4jJCwwKSxKLnNldChxWix0aGlzLiMkLmJ5dGVMZW5ndGgpLEouc2V0KCQsdGhpcy4jJC5ieXRlTGVuZ3RoK3FaLmJ5dGVMZW5ndGgpO3RyeXtyZXR1cm4gYXdhaXQgRzAuYmxha2UzKEopfWZpbmFsbHl7Si5maWxsKDApfX1hc3luYyNaKCQsSil7aWYoSi5ieXRlTGVuZ3RoIT09ZVgpcmV0dXJuITE7bGV0IFo9YXdhaXQgdGhpcy4jUSgkKTt0cnl7aWYoWi5ieXRlTGVuZ3RoIT09Si5ieXRlTGVuZ3RoKXJldHVybiExO2xldCBRPTA7Zm9yKGxldCBWPTA7VjxaLmJ5dGVMZW5ndGg7VisrKXtsZXQgWD1aW1ZdLFk9SltWXTtpZihYPT09dm9pZCAwfHxZPT09dm9pZCAwKXJldHVybiExO1F8PVheWX1yZXR1cm4gUT09PTB9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI1YoJCl7bGV0W0osWl09YXdhaXQgUVYoRzAsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBRPWF3YWl0IEcwLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQodGhpcy4jJCxKKTtyZXR1cm4gUzAoUSl9Y2F0Y2h7cmV0dXJuIEcoMTIpfWZpbmFsbHl7Si5maWxsKDApfX1zdGF0aWMgYXN5bmMjWCgkLEope2xldFssWl09UzAoJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsVl09YXdhaXQgUVYoRzAsSik7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFg7dHJ5e3RyeXtYPWF3YWl0IEcwLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxRKX1jYXRjaHtyZXR1cm4gRygyMCl9cmV0dXJuIFcwLmZyb21CeXRlcyhYKX1maW5hbGx5e1EuZmlsbCgwKSxYPy5maWxsKDApfX0jRygkKXtsZXQgSj10aGlzLiMkLnNsaWNlKCksW1osUV09JDAoSik7aWYoUSE9PTApcmV0dXJuIEouZmlsbCgwKSxHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEouZmlsbCgwKSxHKDEwKTt0cnl7bGV0W1YsWF09cFEoWiwkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFk9bmV3IFMsVz1ZLndyaXRlU3RydWN0KFhaLFYpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBOKFkucmVzdWx0KCkpfWZpbmFsbHl7Vi5tYXN0ZXJTZWVkLmZpbGwoMCl9fWZpbmFsbHl7Wi5maWxsKDApfX1zdGF0aWMjeigkLEope2lmKCQuYnl0ZUxlbmd0aD09PTB8fCQuZXZlcnkoKFgpPT5YPT09MCkpcmV0dXJuIEcoMjIpO2lmKCQuYnl0ZUxlbmd0aD09PVIwKXtpZigkLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDIyKTtsZXRbWCxZXT1XMC5mcm9tQnl0ZXMoJCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIE4oe2VuY2xhdmU6WCxob3N0czpbXSxjcmVkSWQ6Sn0pfWxldCBaPW5ldyBnKCQpLFtRLFZdPVoucmVhZFN0cnVjdChYWik7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7dHJ5e2lmKFEubWFzdGVyU2VlZC5ldmVyeSgoVyk9Plc9PT0wKSlyZXR1cm4gRygyMik7bGV0W1gsWV09VzAuZnJvbUJ5dGVzKFEubWFzdGVyU2VlZCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIE4oe2VuY2xhdmU6WCxob3N0czpRLmhvc3RzLm1hcCgoVyk9Pih7Li4uV30pKSxjcmVkSWQ6Sn0pfWZpbmFsbHl7US5tYXN0ZXJTZWVkLmZpbGwoMCl9fWFzeW5jI0soJCxKKXtsZXQgWj1hd2FpdCB0aGlzLiNZKCQpO3RyeXtyZXR1cm4gYXdhaXQgRzAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChKLFopfWZpbmFsbHl7Wi5maWxsKDApfX1hc3luYyNGKCQsSil7bGV0IFo9YXdhaXQgdGhpcy4jWSgkKTt0cnl7cmV0dXJuIGF3YWl0IEcwLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoSixaKX1maW5hbGx5e1ouZmlsbCgwKX19YXN5bmMjWSgkKXtsZXQgSj1uZXcgVWludDhBcnJheSh0aGlzLiMkLmJ5dGVMZW5ndGgrJC5ieXRlTGVuZ3RoKTtKLnNldCh0aGlzLiMkLDApLEouc2V0KCQsdGhpcy4jJC5ieXRlTGVuZ3RoKTt0cnl7cmV0dXJuIGF3YWl0IEcwLmJsYWtlMyhKKX1maW5hbGx5e0ouZmlsbCgwKX19YXN5bmMjTygkLEope2xldCBaPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxRPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcoUS5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludChKKSwhMSksYXdhaXQgdGhpcy4jWShJMChaLFEpKX1hc3luYyNXKCQsSil7bGV0IFo9YXdhaXQgdGhpcy4jTygkLEopO3RyeXtyZXR1cm4gYXdhaXQgRzAuZGVyaXZlRWQyNTUxOUtleVBhaXIoWil9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI04oJCxKLFope2xldCBRPWF3YWl0IHRoaXMuI1coJCxKKTt0cnl7cmV0dXJuIGF3YWl0IEcwLnNpZ25FZDI1NTE5KFosUS5wcml2YXRlS2V5KX1maW5hbGx5e1EucHJpdmF0ZUtleS5maWxsKDApfX1hc3luYyNIKCQsSixaKXtsZXQgUT1hd2FpdCB0aGlzLiNXKCQsSiksVj1JMChRLnByaXZhdGVLZXksWik7US5wcml2YXRlS2V5LmZpbGwoMCk7dHJ5e3JldHVybihhd2FpdCBHMC5ibGFrZTMoVikpLnNsaWNlKDAsQjApfWZpbmFsbHl7Vi5maWxsKDApfX19YXN5bmMgZnVuY3Rpb24gUVYoJCxKLFo9dFgpe2lmKEouYnl0ZUxlbmd0aDxKWSlyZXR1cm4gRygxMCk7bGV0IFE9YXdhaXQgJC5ibGFrZTMoSTAoSixaKSk7cmV0dXJuIE4oUS5zbGljZSgwLCRZKSl9Y2xhc3MgTVp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkKXtsZXQgSj1bLi4uJF07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1oub25jb21wbGV0ZT0oKT0+VigpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKTtmb3IobGV0IFkgb2YgSil7bGV0IFc9YCR7WS5ob3N0fToke1kuc2VxfWA7US5wdXQoWSxXKX19KX1hc3luYyBkZXEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxWPVEub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e1Eub25jb21wbGV0ZT0oKT0+WCgpLFEub25lcnJvcj0oKT0+WShRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9YCR7JH06JHtXfWA7Vi5kZWxldGUoeil9fSl9YXN5bmMgbGlzdCgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBWPUouZ2V0QWxsKCk7Vi5vbnN1Y2Nlc3M9KCk9PlooVi5yZXN1bHQpLFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFY9Si5jb3VudCgpO1Yub25zdWNjZXNzPSgpPT5aKFYucmVzdWx0KSxWLm9uZXJyb3I9KCk9PlEoVi5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fWZ1bmN0aW9uIFZWKCQpe3JldHVybntsYWJlbDokLmxhYmVsLGhhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxpZHg6JC5pZHgsbGFzdFNlcTokLmxhc3RTZXF8fDAsY2xvY2tPZmZzZXQ6JC5jbG9ja09mZnNldCxzdWJzY3JpcHRpb246JC5zdWJzY3JpcHRpb259fWZ1bmN0aW9uIFpZKCQsSil7bGV0IFo9ey4uLiR9O2lmKEouc2V0TGFzdFNlcSE9PXZvaWQgMClaLmxhc3RTZXE9Si5zZXRMYXN0U2VxO2Vsc2UgaWYoSi5sYXN0U2VxIT09dm9pZCAwKXtsZXQgUT1aLmxhc3RTZXF8fDA7aWYoSi5sYXN0U2VxPlEpWi5sYXN0U2VxPUoubGFzdFNlcX1yZXR1cm4gZGVsZXRlIFoubnVtQmFncyxkZWxldGUgWi5udW1EdXBlcyxafWNsYXNzIFVae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IEo9YXdhaXQgdGhpcy5nZXQoJC5sYWJlbCksWj1KIT09dm9pZCAwJiZKLmhhbmRsZS5ocmVmPT09JC5oYW5kbGUuaHJlZiYmKEouaWR4Pz8wKT09PSgkLmlkeD8/MCk7cmV0dXJuIHRoaXMucHV0KHsuLi4kLGxhc3RTZXE6Wj9KLmxhc3RTZXE6MCxjbG9ja09mZnNldDpaP0ouY2xvY2tPZmZzZXQ6dm9pZCAwLHN1YnNjcmlwdGlvbjpaP0ouc3Vic2NyaXB0aW9uOnZvaWQgMH0pfWFzeW5jIHB1dCgkKXtsZXQgSj17Li4uJCxoYW5kbGU6JC5oYW5kbGUudG9TdHJpbmcoKSxsYXN0U2VxOiQubGFzdFNlcT8/MH0sWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1oub25jb21wbGV0ZT0oKT0+VigpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKSxRLnB1dChKKX0pfWFzeW5jIHRvdWNoKCQsSil7cmV0dXJuIHRoaXMucmVjb3JkU3RhdHMoJCx7bGFzdFNlcTpKfSl9YXN5bmMgcmVjb3JkU3RhdHMoJCxKKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1oub25jb21wbGV0ZT0oKT0+VigpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKTtsZXQgWT1RLmdldCgkKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVkucmVzdWx0O2lmKCFXKXJldHVybjtRLnB1dChaWShXLEopKX19KX1hc3luYyBnZXQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFg9Wi5nZXQoJCk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgWT1YLnJlc3VsdDtpZighWSlRKHZvaWQgMCk7ZWxzZSBRKFZWKFkpKX0sWC5vbmVycm9yPSgpPT5WKFguZXJyb3IpfSl9YXN5bmMgc2V0KCQsSil7bGV0IFo9YXdhaXQgdGhpcy5nZXQoJCk7aWYoIVopcmV0dXJuIDEzO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy5wdXQoey4uLlosLi4uSn0pLDB9Y2F0Y2h7cmV0dXJuIDE4fX1hc3luYyBkZWwoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsVik9PntKLm9uY29tcGxldGU9KCk9PlEoKSxKLm9uZXJyb3I9KCk9PlYoSi5lcnJvciksWi5kZWxldGUoJCl9KX1hc3luYyBsaXN0KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFY9Si5nZXRBbGwoKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBYPVYucmVzdWx0O1ooWC5tYXAoVlYpKX0sVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouY2xlYXIoKX0pfX1jbGFzcyBDWntjcnlwdG87ZGI7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmNyeXB0bz1KO3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e2lmKCQubGVuZ3RoPT09MCl7UShbXSk7cmV0dXJufWxldCBWPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO0oub25jb21wbGV0ZT0oKT0+UShWKSxKLm9uZXJyb3I9KCk9Pntmb3IobGV0IFg9MDtYPFYubGVuZ3RoO1grKylWW1hdPTE4O1EoVil9O2ZvcihsZXQgWD0wO1g8JC5sZW5ndGg7WCsrKXtsZXR7a2V5OlksZGF0YTpXfT0kW1hdLHo9QihZKSxLPVoucHV0KFcseik7Sy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKSxWW1hdPTE4fX19KX1hc3luYyBkZWwoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57Wi5vbmNvbXBsZXRlPSgpPT5WKCksWi5vbmVycm9yPSgpPT5YKFouZXJyb3IpO2ZvcihsZXQgWSBvZiBKKXtsZXQgVz1CKFkpO1EuZGVsZXRlKFcpfX0pfWFzeW5jIGdldCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFg9QigkKSxZPVouZ2V0KFgpO1kub25zdWNjZXNzPWFzeW5jKCk9PntsZXQgVz1ZLnJlc3VsdDtpZihXKVEoYXdhaXQgaSQoJCxXLHRoaXMuY3J5cHRvKSk7ZWxzZSBRKHZvaWQgMCl9LFkub25lcnJvcj0oKT0+VihZLmVycm9yKX0pfWFzeW5jIGhhcygkKXtyZXR1cm4gYXdhaXQgdGhpcy5nZXQoJCkhPT12b2lkIDB9YXN5bmMgbGlzdCgkKXtsZXQgSj0kPy5hcGxkLFo9JD8uYm9keSE9PSExLFY9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e2xldCBXPVtdLHo9Sj09PXZvaWQgMD9WLm9wZW5DdXJzb3IoKTpWLmluZGV4KGokKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoSikpO3oub25zdWNjZXNzPShLKT0+e2xldCBGPUsudGFyZ2V0LnJlc3VsdDtpZihGKXtsZXQgTz1KPT09dm9pZCAwP0Yua2V5OkYucHJpbWFyeUtleSxIPUYudmFsdWU7Vy5wdXNoKHtoYXNoOk8wKE8pLGRhdGE6SH0pLEYuY29udGludWUoKX1lbHNlIFByb21pc2UuYWxsKFcubWFwKCh7aGFzaDpPLGRhdGE6SH0pPT5pJChPLEgsdGhpcy5jcnlwdG8se2JvZHk6Wn0pKSkudGhlbihYKS5jYXRjaChZKX0sei5vbmVycm9yPSgpPT5ZKHouZXJyb3IpfSl9YXN5bmMgY291bnQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBYPSQ9PT12b2lkIDA/Wi5jb3VudCgpOlouaW5kZXgoaiQpLmNvdW50KElEQktleVJhbmdlLm9ubHkoJCkpO1gub25zdWNjZXNzPSgpPT5RKFgucmVzdWx0KSxYLm9uZXJyb3I9KCk9PlYoWC5lcnJvcil9KX1hc3luYyBsaXN0S2V5cygpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgVj1bXSxYPUoub3BlbktleUN1cnNvcigpO1gub25zdWNjZXNzPShZKT0+e2xldCBXPVkudGFyZ2V0LnJlc3VsdDtpZihXKVYucHVzaChPMChXLmtleSkpLFcuY29udGludWUoKTtlbHNlIFooVil9LFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfWFzeW5jIGxhc3QoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBYLFk9Wi5vcGVuQ3Vyc29yKCk7WS5vbnN1Y2Nlc3M9YXN5bmMoVyk9PntsZXQgej1XLnRhcmdldC5yZXN1bHQ7aWYoeil7bGV0e2tleTpLLHZhbHVlOkZ9PXo7aWYobigkLEYuZWlkKSl7aWYoIVh8fChGLmN0cj8/MCk+KFguZGF0YS5jdHI/PzApfHwoRi5jdHI/PzApPT09KFguZGF0YS5jdHI/PzApJiYoRi5vZmY/PzApPihYLmRhdGEub2ZmPz8wKSlYPXtrZXk6SyxkYXRhOkZ9fXouY29udGludWUoKX1lbHNlIGlmKFgpe2xldCBLPU8wKFgua2V5KTtRKGF3YWl0IGkkKEssWC5kYXRhLHRoaXMuY3J5cHRvKSl9ZWxzZSBRKHZvaWQgMCl9LFkub25lcnJvcj0oKT0+VihZLmVycm9yKX0pfWFzeW5jIG1hcmtBcHBsaWVkKCQpe2xldCBKPVsuLi4kXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1oub25jb21wbGV0ZT0oKT0+VigpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKTtmb3IobGV0IFkgb2YgSil7bGV0IFc9QihZKSx6PVEuZ2V0KFcpO3oub25zdWNjZXNzPSgpPT57bGV0IEs9ei5yZXN1bHQ7aWYoIUspcmV0dXJuO3ZKKEssdSQpLFEucHV0KEssVyl9LHoub25lcnJvcj0oSyk9PntLLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIG1hcmtGYWlsZWQoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57Wi5vbmNvbXBsZXRlPSgpPT5WKCksWi5vbmVycm9yPSgpPT5YKFouZXJyb3IpO2ZvcihsZXR7a2V5OlksZXJyOld9b2YgSil7bGV0IHo9QihZKSxLPVEuZ2V0KHopO0sub25zdWNjZXNzPSgpPT57bGV0IEY9Sy5yZXN1bHQ7aWYoIUYpcmV0dXJuO3ZKKEYsViQsVyksUS5wdXQoRix6KX0sSy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKX19fSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19dmFyIFFZPTg7Y2xhc3MgSVp7IyQ7I0o7I1E7I1o7Y29uc3RydWN0b3IoJCl7aWYodGhpcy4jWj0kLnBlcnNpc3RLZXlyaW5nLHRoaXMuI1E9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5rZXlyaW5nIT09dm9pZCAwKXRoaXMuI0o9XzAoJC5rZXlyaW5nKX1nZXQga2V5cmluZygpe3JldHVybiB0aGlzLiNKPT09dm9pZCAwP3ZvaWQgMDpfMCh0aGlzLiNKKX1saXN0KCl7aWYodGhpcy4jSj09PXZvaWQgMClyZXR1cm5bXTtyZXR1cm4gdGhpcy4jSi5lbnRyaWVzLm1hcChZWSl9YXN5bmMgc2F2ZSgkLEope2lmKEo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIGJpbmRBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3QgYSBiaW5kaW5nIikpO3JldHVybiB0aGlzLiMkPSQsdGhpcy4jJH1hc3luYyBiaW5kQW5kU2F2ZSgkLEope2xldCBaPXRoaXMuI0osUT1KPy5jcmVkSWQsVj1RIGluc3RhbmNlb2YgVWludDhBcnJheT9RLmJ5dGVMZW5ndGg+MDpRIT09dm9pZCAwJiZRLmxlbmd0aD4wO2lmKCFWJiZaIT09dm9pZCAwJiZaLmVudHJpZXMubGVuZ3RoPj1RWSlyZXR1cm4gRygyNik7bGV0IFg9WFYoSj8ubmljayksWT1KPy5leGNsdWRlQ3JlZGVudGlhbHM/PyhWP3ZvaWQgMDpXWShaKSksVz1KPy5zYWx0Pz9aPy5zYWx0LHo9Wj09PXZvaWQgMD92b2lkIDA6Wi5lbnRyaWVzLm1hcCgocSk9Pih7Y3JlZElkOnEuY3JlZElkLHRhZzpxLnRhZ30pKSxbSyxGXT1hd2FpdCAkLmJpbmQoey4uLnRoaXMuI1Esc2FsdDpXLGNyZWRJZDpRLGNyZWF0ZUNyZWRJZk5lZWRlZDpKPy5jcmVhdGVDcmVkSWZOZWVkZWQ/PyFWLGV4Y2x1ZGVDcmVkZW50aWFsczpZLHVzZXJOYW1lOnokLGRpc3BsYXlOYW1lOlg/P3okLGF1dGhlbnRpY2F0b3JBdHRhY2htZW50Oko/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50LGhpbnRzOko/LmhpbnRzfSx6KTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgTz1EYXRlLm5vdygpLEg9e3R5cGU6InByZiIsc2VhbGVkTWFzdGVyOksuc2VhbGVkTWFzdGVyLGNyZWRJZDpLLmNyZWRJZCx0YWc6Sy50YWcsdXNlcklkOksudXNlcklkLG5pY2s6WCxlbnJvbGxlZEF0Ok8sbGFzdFVzZWRBdDpPLGF0dGFjaG1lbnQ6Sy5hdHRhY2htZW50LHRyYW5zcG9ydHM6Sy50cmFuc3BvcnRzLGFhZ3VpZDpLLmFhZ3VpZCxlbnJvbGxlZE9zOlZZKCl9LFI9Wj09PXZvaWQgMD97c2FsdDpLLnNhbHQuc2xpY2UoKSxlbnRyaWVzOltdfTpfMChaKTtyZXR1cm4gdGhpcy4jSj1HWShSLEgpLHRoaXMuIyQ9JCxhd2FpdCB0aGlzLiNaKF8wKHRoaXMuI0opKSxOKHRoaXMuIyQpfWFzeW5jIGxvYWQoKXtyZXR1cm4gdGhpcy4jJH1hc3luYyB1bmxvY2soKXtsZXQgJD10aGlzLiNKO2lmKCQ9PT12b2lkIDB8fCQuZW50cmllcy5sZW5ndGg9PT0wKXJldHVybiBHKDIyKTtsZXRbSixaXT1hd2FpdCBXMC51bnNlYWxXaXRoUGFzc2tleSgkLmVudHJpZXMubWFwKChWKT0+KHtzZWFsZWRNYXN0ZXI6Vi5zZWFsZWRNYXN0ZXIsY3JlZElkOlYuY3JlZElkfSkpLHsuLi50aGlzLiNRLHNhbHQ6JC5zYWx0fSk7aWYoWiE9PTApcmV0dXJuIEcoWik7dGhpcy4jJD1KLmVuY2xhdmU7bGV0IFE9elkoJCxKLmNyZWRJZCk7aWYoUSE9PXZvaWQgMCl0aGlzLiNKPVEsYXdhaXQgdGhpcy4jWihfMChRKSk7cmV0dXJuIE4oSi5lbmNsYXZlKX1hc3luYyByZW5hbWUoJCxKKXtsZXQgWj10aGlzLiNKO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMjIpO2xldCBRPVouZW50cmllcy5maW5kSW5kZXgoKHopPT5uKHouY3JlZElkLCQpKTtpZihRPDApcmV0dXJuIEcoMTMpO2xldCBWPVouZW50cmllcy5tYXAoVCQpLFg9VltRXTtpZihYPT09dm9pZCAwKXJldHVybiBHKDEzKTtsZXQgWT1YVihKKTtWW1FdPXsuLi5YLG5pY2s6WX07bGV0IFc9e3NhbHQ6Wi5zYWx0LnNsaWNlKCksZW50cmllczpWfTtyZXR1cm4gdGhpcy4jSj1XLGF3YWl0IHRoaXMuI1ooXzAoVykpLE4odm9pZCAwKX1hc3luYyByZW1vdmUoJCl7bGV0IEo9dGhpcy4jSjtpZihKPT09dm9pZCAwKXJldHVybiBHKDIyKTtsZXQgWj1KLmVudHJpZXMuZmlsdGVyKChWKT0+IW4oVi5jcmVkSWQsJCkpO2lmKFoubGVuZ3RoPT09Si5lbnRyaWVzLmxlbmd0aClyZXR1cm4gRygxMyk7aWYoWi5sZW5ndGg9PT0wKXJldHVybiB0aGlzLiNKPXZvaWQgMCxhd2FpdCB0aGlzLiNaKHZvaWQgMCksTih2b2lkIDApO2xldCBRPXtzYWx0Okouc2FsdC5zbGljZSgpLGVudHJpZXM6Wi5tYXAoVCQpfTtyZXR1cm4gdGhpcy4jSj1RLGF3YWl0IHRoaXMuI1ooXzAoUSkpLE4odm9pZCAwKX1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDAsdGhpcy4jSj12b2lkIDAsYXdhaXQgdGhpcy4jWih2b2lkIDApfX1mdW5jdGlvbiBYVigkKXtpZigkPT09dm9pZCAwKXJldHVybjtsZXQgSj0kLnRyaW0oKTtyZXR1cm4gSj09PSIiP3ZvaWQgMDpKfWZ1bmN0aW9uIFZZKCl7aWYodHlwZW9mIG5hdmlnYXRvcj4idSIpcmV0dXJuO3JldHVybiBvUShuYXZpZ2F0b3IudXNlckFnZW50KX1mdW5jdGlvbiBUJCgkKXtsZXRbSixaXT1TMCgkLnNlYWxlZE1hc3Rlci5zbGljZSgpKTtyZXR1cm57dHlwZToicHJmIixzZWFsZWRNYXN0ZXI6Wj09PTAmJkohPT12b2lkIDA/SjokLnNlYWxlZE1hc3RlcixjcmVkSWQ6JC5jcmVkSWQuc2xpY2UoKSx0YWc6JC50YWcuc2xpY2UoKSx1c2VySWQ6JC51c2VySWQ9PT12b2lkIDA/dm9pZCAwOiQudXNlcklkLnNsaWNlKCksbmljazokLm5pY2ssZW5yb2xsZWRBdDokLmVucm9sbGVkQXQsbGFzdFVzZWRBdDokLmxhc3RVc2VkQXQsYXR0YWNobWVudDokLmF0dGFjaG1lbnQsdHJhbnNwb3J0czokLnRyYW5zcG9ydHM9PT12b2lkIDA/dm9pZCAwOlsuLi4kLnRyYW5zcG9ydHNdLGFhZ3VpZDokLmFhZ3VpZD09PXZvaWQgMD92b2lkIDA6JC5hYWd1aWQuc2xpY2UoKSxlbnJvbGxlZE9zOiQuZW5yb2xsZWRPc319ZnVuY3Rpb24gXzAoJCl7cmV0dXJue3NhbHQ6JC5zYWx0LnNsaWNlKCksZW50cmllczokLmVudHJpZXMubWFwKFQkKX19ZnVuY3Rpb24gWVYoJCl7cmV0dXJuICQhPT1udWxsJiZ0eXBlb2YgJD09PSJvYmplY3QifWZ1bmN0aW9uIFhZKCQpe2lmKCFZVigkKXx8JC50eXBlIT09InByZiIpcmV0dXJuO2lmKCEoJC5zZWFsZWRNYXN0ZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8ISgkLmNyZWRJZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhKCQudGFnIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCQudGFnLmJ5dGVMZW5ndGghPT0zMnx8dHlwZW9mICQuZW5yb2xsZWRBdCE9PSJudW1iZXIifHwhTnVtYmVyLmlzRmluaXRlKCQuZW5yb2xsZWRBdCkpcmV0dXJuO2xldFtKLFpdPVMwKCQuc2VhbGVkTWFzdGVyKTtpZihaIT09MHx8Sj09PXZvaWQgMClyZXR1cm47bGV0IFE9JC5hdHRhY2htZW50PT09InBsYXRmb3JtInx8JC5hdHRhY2htZW50PT09ImNyb3NzLXBsYXRmb3JtIj8kLmF0dGFjaG1lbnQ6dm9pZCAwLFY9JC5lbnJvbGxlZE9zLFg9Vj09PSJpb3MifHxWPT09Im1hY29zInx8Vj09PSJhbmRyb2lkInx8Vj09PSJ3aW5kb3dzInx8Vj09PSJsaW51eCJ8fFY9PT0ib3RoZXIiP1Y6dm9pZCAwLFk9QXJyYXkuaXNBcnJheSgkLnRyYW5zcG9ydHMpPyQudHJhbnNwb3J0cy5maWx0ZXIoKFcpPT50eXBlb2YgVz09PSJzdHJpbmciKTp2b2lkIDA7cmV0dXJue3R5cGU6InByZiIsc2VhbGVkTWFzdGVyOkosY3JlZElkOiQuY3JlZElkLnNsaWNlKCksdGFnOiQudGFnLnNsaWNlKCksdXNlcklkOiQudXNlcklkIGluc3RhbmNlb2YgVWludDhBcnJheT8kLnVzZXJJZC5zbGljZSgpOnZvaWQgMCxuaWNrOnR5cGVvZiAkLm5pY2s9PT0ic3RyaW5nIj8kLm5pY2s6dm9pZCAwLGVucm9sbGVkQXQ6JC5lbnJvbGxlZEF0LGxhc3RVc2VkQXQ6dHlwZW9mICQubGFzdFVzZWRBdD09PSJudW1iZXIiJiZOdW1iZXIuaXNGaW5pdGUoJC5sYXN0VXNlZEF0KT8kLmxhc3RVc2VkQXQ6dm9pZCAwLGF0dGFjaG1lbnQ6USx0cmFuc3BvcnRzOlk9PT12b2lkIDB8fFkubGVuZ3RoPT09MD92b2lkIDA6WSxhYWd1aWQ6JC5hYWd1aWQgaW5zdGFuY2VvZiBVaW50OEFycmF5PyQuYWFndWlkLnNsaWNlKCk6dm9pZCAwLGVucm9sbGVkT3M6WH19ZnVuY3Rpb24gV1YoJCl7aWYoIVlWKCQpKXJldHVybjtpZighKCQuc2FsdCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhQXJyYXkuaXNBcnJheSgkLmVudHJpZXMpKXJldHVybjtsZXQgSj1bXTtmb3IobGV0IFogb2YgJC5lbnRyaWVzKXtsZXQgUT1YWShaKTtpZihRIT09dm9pZCAwKUoucHVzaChRKX1pZihKLmxlbmd0aD09PTApcmV0dXJuO3JldHVybntzYWx0OiQuc2FsdC5zbGljZSgpLGVudHJpZXM6Sn19ZnVuY3Rpb24gWVkoJCl7cmV0dXJue3R5cGU6InByZiIsY3JlZElkOiQuY3JlZElkLnNsaWNlKCksdXNlcklkOiQudXNlcklkPT09dm9pZCAwP3ZvaWQgMDokLnVzZXJJZC5zbGljZSgpLG5pY2s6JC5uaWNrLGVucm9sbGVkQXQ6JC5lbnJvbGxlZEF0LGxhc3RVc2VkQXQ6JC5sYXN0VXNlZEF0LGF0dGFjaG1lbnQ6JC5hdHRhY2htZW50LHRyYW5zcG9ydHM6JC50cmFuc3BvcnRzPT09dm9pZCAwP3ZvaWQgMDpbLi4uJC50cmFuc3BvcnRzXSxhYWd1aWQ6JC5hYWd1aWQ9PT12b2lkIDA/dm9pZCAwOiQuYWFndWlkLnNsaWNlKCksZW5yb2xsZWRPczokLmVucm9sbGVkT3N9fWZ1bmN0aW9uIFdZKCQpe2lmKCQ9PT12b2lkIDApcmV0dXJuW107cmV0dXJuICQuZW50cmllcy5maWx0ZXIoKEopPT5KLmNyZWRJZC5ieXRlTGVuZ3RoPjApLm1hcCgoSik9PkouY3JlZElkLnNsaWNlKCkpfWZ1bmN0aW9uIEdZKCQsSil7bGV0IFo9JC5lbnRyaWVzLm1hcChUJCksUT1aLmZpbmRJbmRleCgoVik9Pm4oVi5jcmVkSWQsSi5jcmVkSWQpKTtpZihRPj0wKXtsZXQgVj1aW1FdO1pbUV09ey4uLkosZW5yb2xsZWRBdDpWPy5lbnJvbGxlZEF0Pz9KLmVucm9sbGVkQXQsbmljazpKLm5pY2s/P1Y/Lm5pY2t9fWVsc2UgWi5wdXNoKEopO3JldHVybntzYWx0OiQuc2FsdC5zbGljZSgpLGVudHJpZXM6Wn19ZnVuY3Rpb24gelkoJCxKKXtpZihKLmJ5dGVMZW5ndGg9PT0wKXJldHVybjtsZXQgWj0kLmVudHJpZXMuZmluZEluZGV4KChYKT0+bihYLmNyZWRJZCxKKSk7aWYoWjwwKXJldHVybjtsZXQgUT0kLmVudHJpZXMubWFwKFQkKSxWPVFbWl07aWYoVj09PXZvaWQgMClyZXR1cm47cmV0dXJuIFFbWl09ey4uLlYsbGFzdFVzZWRBdDpEYXRlLm5vdygpfSx7c2FsdDokLnNhbHQuc2xpY2UoKSxlbnRyaWVzOlF9fXZhciBSNz1HSigiZmJmYzMwMDcxNTRlNGVjYzhjMGI2ZTAyMDU1N2Q3YmQiKSxxNz1HSigiZWE5YjhkNjY0ZDAxMWQyMTNjZTRiNmI0OGNiNTc1ZDQiKSxNNz1HSigiMDg5ODcwNThjYWRjNGI4MWI2ZTEzMGRlNTBkY2JlOTYiKSxVNz1HSigiMmZjMDU3OWY4MTEzNDdlYWIxMTZiYjVhOGRiOTIwMmEiKTtmdW5jdGlvbiBHSigkKXtsZXQgSj1uZXcgVWludDhBcnJheSgxNik7Zm9yKGxldCBaPTA7WjwxNjtaKyspSltaXT1OdW1iZXIucGFyc2VJbnQoJC5zbGljZShaKjIsWioyKzIpLDE2KTtyZXR1cm4gSn12YXIgS1k9ImRpcGxvbWF0aWMucGluLyI7ZnVuY3Rpb24gRlkoJCl7cmV0dXJuIEtZK0gwKCQpfWFzeW5jIGZ1bmN0aW9uIEdWKCQsSixaKXtsZXQgUT1hd2FpdCBKLmRlcml2ZUlkZW50aXR5KEZZKFopLDApO3JldHVybiAkLmJsYWtlMyhRLnB1YmxpY0tleSl9YXN5bmMgZnVuY3Rpb24gelYoJCxKKXtsZXQgWj1hd2FpdCAkLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxRPWF3YWl0IEdWKCQsSixaKTtyZXR1cm57bjpaLGg6UX19YXN5bmMgZnVuY3Rpb24gS1YoJCxKLFope2xldCBRPWF3YWl0IEdWKCQsSixaLm4pO3JldHVybiBPWShRLFouaCl9ZnVuY3Rpb24gRlYoJCl7aWYoJD09PXZvaWQgMHx8JD09PW51bGx8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuO2xldCBKPSQ7aWYoIShKLm4gaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShKLmggaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47aWYoSi5uLmJ5dGVMZW5ndGg8MXx8Si5oLmJ5dGVMZW5ndGg8MSlyZXR1cm47cmV0dXJue246Si5uLnNsaWNlKCksaDpKLmguc2xpY2UoKX19ZnVuY3Rpb24gT1YoJCl7cmV0dXJue246JC5uLnNsaWNlKCksaDokLmguc2xpY2UoKX19ZnVuY3Rpb24gT1koJCxKKXtpZigkLmJ5dGVMZW5ndGghPT1KLmJ5dGVMZW5ndGgpcmV0dXJuITE7bGV0IFo9MDtmb3IobGV0IFE9MDtRPCQuYnl0ZUxlbmd0aDtRKyspWnw9JFtRXV5KW1FdO3JldHVybiBaPT09MH12YXIgeko9ImtleXJpbmciLE5WPSJwcmZNZXRhIixQWj0iaWRQaW4iLEhWPSJpZFB1YiI7Y2xhc3Mgalp7IyQ7ZGI7I0o7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmRiPSQsdGhpcy4jSj1KfWFzeW5jIHNhdmUoJCxKKXtyZXR1cm4gYXdhaXQgdGhpcy4jUSgkKSx0aGlzLiMkPSQsdGhpcy4jJH1hc3luYyBsb2FkKCl7cmV0dXJuIHRoaXMuIyR9YXN5bmMgY2xlYXJTZXNzaW9uKCl7dGhpcy4jJD12b2lkIDB9YXN5bmMgd2lwZSgpe3RoaXMuIyQ9dm9pZCAwO2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouZGVsZXRlKHpKKSxKLmRlbGV0ZShOViksSi5kZWxldGUoUFopLEouZGVsZXRlKEhWKX0pfWFzeW5jIGxvYWRLZXlyaW5nKCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFY9Si5nZXQoekopO1Yub25zdWNjZXNzPSgpPT57WihXVihWLnJlc3VsdCkpfSxWLm9uZXJyb3I9KCk9PlEoVi5lcnJvcil9KX1hc3luYyBwZXJzaXN0S2V5cmluZygkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2lmKEoub25jb21wbGV0ZT0oKT0+USgpLEoub25lcnJvcj0oKT0+VihKLmVycm9yKSxaLmRlbGV0ZShOViksJD09PXZvaWQgMCl7Wi5kZWxldGUoekopO3JldHVybn1aLnB1dChfMCgkKSx6Sil9KX1hc3luYyBoYXNLZXlyaW5nKCl7bGV0ICQ9YXdhaXQgdGhpcy5sb2FkS2V5cmluZygpO3JldHVybiAkIT09dm9pZCAwJiYkLmVudHJpZXMubGVuZ3RoPjB9YXN5bmMgb3BlblByZlN0b3JlKCQpe2xldCBKPWF3YWl0IHRoaXMubG9hZEtleXJpbmcoKTtyZXR1cm4gbmV3IElaKHtycElkOiQucnBJZCxycE5hbWU6JC5ycE5hbWUsa2V5cmluZzpKLHBlcnNpc3RLZXlyaW5nOihaKT0+dGhpcy5wZXJzaXN0S2V5cmluZyhaKX0pfWFzeW5jI1EoJCl7YXdhaXQgdGhpcy4jWChIVik7bGV0IEo9YXdhaXQgdGhpcy4jWigpO2lmKEohPT12b2lkIDApe2lmKCFhd2FpdCBLVih0aGlzLiNKLCQsSikpdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSBzZWVkIGRvZXMgbm90IG1hdGNoIHRoaXMgZGV2aWNlJ3MgaWRlbnRpdHkgKGxvY2FsIGRhdGEgd2FzIGNyZWF0ZWQgd2l0aCBhIGRpZmZlcmVudCBtYXN0ZXIgc2VlZCkiKTtyZXR1cm59bGV0IFo9YXdhaXQgelYodGhpcy4jSiwkKTthd2FpdCB0aGlzLiNWKFopfSNaKCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFY9Si5nZXQoUFopO1Yub25zdWNjZXNzPSgpPT5aKEZWKFYucmVzdWx0KSksVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9I1YoJCl7bGV0IEo9T1YoJCksWj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1oub25jb21wbGV0ZT0oKT0+VigpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKSxRLnB1dChKLFBaKX0pfSNYKCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWR3cml0ZSIpLFo9Si5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57Si5vbmNvbXBsZXRlPSgpPT5RKCksSi5vbmVycm9yPSgpPT5WKEouZXJyb3IpLFouZGVsZXRlKCQpfSl9fWNsYXNzIFRae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBlbnEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkd3JpdGUiKSxWPVEub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e1Eub25jb21wbGV0ZT0oKT0+WCgpLFEub25lcnJvcj0oKT0+WShRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9SDAoVyk7Vi5wdXQoe2hvc3Q6JCxoYXNoOnp9KX19KX1hc3luYyBkZXEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkd3JpdGUiKSxWPVEub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e1Eub25jb21wbGV0ZT0oKT0+WCgpLFEub25lcnJvcj0oKT0+WShRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9SDAoVyk7Vi5kZWxldGUoWyQsel0pfX0pfWFzeW5jIGxpc3QoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFg9Wi5nZXRBbGwoKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0LmZpbHRlcigoeik9PnouaG9zdD09PSQpLm1hcCgoeik9PnouaGFzaCk7UShXLm1hcCgoeik9PmJaKHopKSl9LFgub25lcnJvcj0oKT0+VihYLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFY9Si5jb3VudCgpO1Yub25zdWNjZXNzPSgpPT5aKFYucmVzdWx0KSxWLm9uZXJyb3I9KCk9PlEoVi5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fXZhciBRMD0ic2VlZE1ldGEiLFowPSJob3N0cyIsRjA9InVwbG9hZFF1ZXVlIixLMD0iZG93bmxvYWRRdWV1ZSIscD0ibWVzc2FnZXMiLGokPSJhcGxkIixSVj0zLHFWPSJkaXBsb21hdGljLXN0b3JlLWRiIjtjbGFzcyBNVntzZWVkO2hvc3RzO3VwbG9hZHM7ZG93bmxvYWRzO21lc3NhZ2VzO2RiO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5kYj0kLHRoaXMuc2VlZD1uZXcgalooJCxKKSx0aGlzLmhvc3RzPW5ldyBVWigkKSx0aGlzLnVwbG9hZHM9bmV3IFRaKCQpLHRoaXMuZG93bmxvYWRzPW5ldyBNWigkKSx0aGlzLm1lc3NhZ2VzPW5ldyBDWigkLEopfWFzeW5jIHdpcGUoKXthd2FpdCB0aGlzLmhvc3RzLndpcGUoKSxhd2FpdCB0aGlzLnVwbG9hZHMud2lwZSgpLGF3YWl0IHRoaXMuZG93bmxvYWRzLndpcGUoKSxhd2FpdCB0aGlzLm1lc3NhZ2VzLndpcGUoKX19YXN5bmMgZnVuY3Rpb24gTlkoKXtyZXR1cm4gbmV3IFByb21pc2UoKCQsSik9PntsZXQgWj1pbmRleGVkREIub3BlbihxVixSVik7Wi5vbnVwZ3JhZGVuZWVkZWQ9KCk9PntsZXR7cmVzdWx0OlEsdHJhbnNhY3Rpb246Vn09WjtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKFEwKSlRLmNyZWF0ZU9iamVjdFN0b3JlKFEwKTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKFowKSlRLmNyZWF0ZU9iamVjdFN0b3JlKFowLHtrZXlQYXRoOiJsYWJlbCJ9KTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKEYwKSlRLmNyZWF0ZU9iamVjdFN0b3JlKEYwLHtrZXlQYXRoOlsiaG9zdCIsImhhc2giXX0pO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoSzApKVEuY3JlYXRlT2JqZWN0U3RvcmUoSzApO2xldCBYO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMocCkpWD1RLmNyZWF0ZU9iamVjdFN0b3JlKHApO2Vsc2V7aWYoIVYpdGhyb3cgRXJyb3IoIm1pc3NpbmcgdXBncmFkZSB0cmFuc2FjdGlvbiBmb3IgbWVzc2FnZXMgc3RvcmUiKTtYPVYub2JqZWN0U3RvcmUocCl9aWYoIVguaW5kZXhOYW1lcy5jb250YWlucyhqJCkpWC5jcmVhdGVJbmRleChqJCwiYXBsZCIse3VuaXF1ZTohMX0pfSxaLm9uYmxvY2tlZD0oKT0+e2NvbnNvbGUud2FybihgW0RJUExPTUFUSUNdIHByb3RvY29sIHN0b3JlIElEQiB1cGdyYWRlIGJsb2NrZWQgKCR7cVZ9IOKGkiB2JHtSVn0pOyB3YWl0aW5nIGZvciBvdGhlciBjb25uZWN0aW9ucyB0byBjbG9zZWApfSxaLm9uc3VjY2Vzcz0oKT0+e2xldCBRPVoucmVzdWx0O1Eub252ZXJzaW9uY2hhbmdlPSgpPT57US5jbG9zZSgpfSwkKFEpfSxaLm9uZXJyb3I9KCk9PkooWi5lcnJvcj8/RXJyb3IoInByb3RvY29sIHN0b3JlIEluZGV4ZWREQiBvcGVuIGZhaWxlZCIpKX0pfWFzeW5jIGZ1bmN0aW9uIFVWKCQpe2xldCBKPWF3YWl0IE5ZKCk7aWYodHlwZW9mIG5hdmlnYXRvcjwidSImJm5hdmlnYXRvci5zdG9yYWdlPy5wZXJzaXN0KXRyeXthd2FpdCBQcm9taXNlLnJhY2UoW25hdmlnYXRvci5zdG9yYWdlLnBlcnNpc3QoKSxuZXcgUHJvbWlzZSgoWik9PntzZXRUaW1lb3V0KCgpPT5aKCExKSwyMDAwKX0pXSl9Y2F0Y2h7fXJldHVybiBuZXcgTVYoSiwkKX1jbGFzcyBEWntjbGllbnQ7ZW50REI7cG9zdDt3aGVuUmVhZHk7cmVzb2x2ZVJlYWR5O3JlamVjdFJlYWR5O2NvbnN0cnVjdG9yKCQpe3RoaXMucG9zdD0kLHRoaXMud2hlblJlYWR5PW5ldyBQcm9taXNlKChKLFopPT57dGhpcy5yZXNvbHZlUmVhZHk9Six0aGlzLnJlamVjdFJlYWR5PVp9KX1hc3luYyBpbml0KCl7dHJ5e2xldCAkPWF3YWl0IFVWKHMkKSxKPWF3YWl0IFhRKHtjYWNoZTohMX0pLFo9bmV3IHYkKEouYXBwbHksKCk9PkouY2xlYXIoKSwoWCk9PntpZihYLmxlbmd0aDwxKXJldHVybjt0aGlzLnBvc3Qoe2tpbmQ6ImRpcnR5IixlaWRzOlgubWFwKChZKT0+WS5zbGljZSgpKX0pfSksUT1aLmNsZWFyO1ouY2xlYXI9YXN5bmMoKT0+e2xldCBYPWF3YWl0IFEoKTtpZihYPT09MCl0aGlzLnBvc3Qoe2tpbmQ6IndpcGVkIn0pO3JldHVybiBYfTtsZXQgVj1uZXcgaUoobmV3IFVKLFosJCxvWixzJCk7dGhpcy5jbGllbnQ9Vix0aGlzLmVudERCPUosVi5jbGllbnRTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRDbGllbnRTdGF0ZSgpfSksVi54ZmVyU3RhdGUubGlzdGVuKCgpPT57dGhpcy5lbWl0WGZlclN0YXRlKCl9KSxhd2FpdCB0aGlzLmVtaXRYZmVyU3RhdGUoKSx0aGlzLnBvc3Qoe2tpbmQ6InJlYWR5In0pLHRoaXMubWFya1JlYWR5KCl9Y2F0Y2goJCl7bGV0IEo9JCBpbnN0YW5jZW9mIEVycm9yPyQ6RXJyb3IoU3RyaW5nKCQpKTt0aHJvdyB0aGlzLnBvc3Qoe2tpbmQ6ImluaXRFcnJvciIsbWVzc2FnZTpKLm1lc3NhZ2V9KSx0aGlzLmZhaWxSZWFkeShKKSxKfX1tYXJrUmVhZHkoKXtsZXQgJD10aGlzLnJlc29sdmVSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsJCkkKCl9ZmFpbFJlYWR5KCQpe2xldCBKPXRoaXMucmVqZWN0UmVhZHk7aWYodGhpcy5yZXNvbHZlUmVhZHk9dm9pZCAwLHRoaXMucmVqZWN0UmVhZHk9dm9pZCAwLEopSigkKX1yZXF1aXJlQ2xpZW50KCl7aWYoIXRoaXMuY2xpZW50KXRocm93IEVycm9yKCJXb3JrZXJSdW50aW1lIG5vdCBpbml0aWFsaXplZCIpO3JldHVybiB0aGlzLmNsaWVudH1hc3luYyBlbWl0Q2xpZW50U3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IEo9YXdhaXQgJC5jbGllbnRTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6ImNsaWVudFN0YXRlIixjb25uZWN0ZWQ6Si5jb25uZWN0ZWR9KX1hc3luYyBlbWl0WGZlclN0YXRlKCl7bGV0ICQ9dGhpcy5jbGllbnQ7aWYoISQpcmV0dXJuO2xldCBKPWF3YWl0ICQueGZlclN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoieGZlclN0YXRlIixzdGF0ZTpKfSl9aG9zdEZyb21TZXJpYWxpemVkKCQpe3JldHVybntoYW5kbGU6bmV3IFVSTCgkLmhhbmRsZSksbGFiZWw6JC5sYWJlbCxpZHg6JC5pZHh9fWFzeW5jIGhhbmRsZSgkKXthd2FpdCB0aGlzLndoZW5SZWFkeTtsZXQgSj10aGlzLnJlcXVpcmVDbGllbnQoKTtzd2l0Y2goJC5vcCl7Y2FzZSJwaW5nIjpyZXR1cm4icG9uZyI7Y2FzZSJzZXRTZWVkIjp7bGV0W1osUV09VzAuZnJvbUJ5dGVzKCQuc2VlZCk7aWYoJC5zZWVkLmZpbGwoMCksUSE9PTB8fFo9PT12b2lkIDApdGhyb3cgbmV3IE4wKFEpO2F3YWl0IEouc2V0U2VlZChaLHtwZXJzaXN0OiQucGVyc2lzdH0pO3JldHVybn1jYXNlImxpbmsiOnthd2FpdCBKLmxpbmsodGhpcy5ob3N0RnJvbVNlcmlhbGl6ZWQoJC5ob3N0KSwkLmNvbm5lY3Q/PyEwKTtyZXR1cm59Y2FzZSJ1bmxpbmsiOnthd2FpdCBKLnVubGluaygkLmxhYmVsKTtyZXR1cm59Y2FzZSJjb25uZWN0Ijp7YXdhaXQgSi5jb25uZWN0KCQubGlzdGVuPz8hMCwkLnN5bmM/PyEwKTtyZXR1cm59Y2FzZSJkaXNjb25uZWN0Ijp7YXdhaXQgSi5kaXNjb25uZWN0KCk7cmV0dXJufWNhc2Uic3luYyI6cmV0dXJuIGF3YWl0IEouc3luYygpO2Nhc2UicmVidWlsZCI6cmV0dXJuIGF3YWl0IEoucmVidWlsZCh7Y2hlY2tIb3N0OiQuY2hlY2tIb3N0Pz8hMH0pO2Nhc2UicmVjb25jaWxlIjp7bGV0W1osUV09YXdhaXQgSi5yZWNvbmNpbGUoJC5ob3N0TGFiZWwse3B1bGw6JC5wdWxsLHB1c2g6JC5wdXNoLHN5bmM6JC5zeW5jfSk7aWYoUSE9PTApdGhyb3cgbmV3IE4wKFEpO2lmKCFaKXRocm93IG5ldyBOMCgxMik7cmV0dXJuIFp9Y2FzZSJtc2djaGVjayI6cmV0dXJuIGF3YWl0IEoubXNnY2hlY2soKTtjYXNlImVudGNoZWNrIjp7bGV0IFo9dGhpcy5lbnREQjtpZighWil0aHJvdyBuZXcgTjAoMTIpO2xldFtRLFZdPWF3YWl0IFouY2hlY2tzdW0ocyQpO2lmKFYhPT0wKXRocm93IG5ldyBOMChWKTtpZighUSl0aHJvdyBuZXcgTjAoMTIpO3JldHVybiBRfWNhc2Uid2lwZSI6e2F3YWl0IEoud2lwZSh7bXNnczokLm1zZ3MsZW50czokLmVudHMsbWV0YTokLm1ldGEsc2VlZDokLnNlZWR9KTtyZXR1cm59Y2FzZSJpbXBvcnQiOntsZXQgWj0kLmJ5dGVzLnNsaWNlKCksUT1uZXcgQmxvYihbWl0pLFY9bmV3IEZpbGUoW1FdLCJpbXBvcnQuZGlwIik7cmV0dXJuIGF3YWl0IEouaW1wb3J0KFYpfWNhc2UiZXhwb3J0Ijp7bGV0W1osUV09YXdhaXQgSi5leHBvcnRCeXRlcygpO2lmKFEhPT0wKXRocm93IG5ldyBOMChRKTtpZighWil0aHJvdyBuZXcgTjAoMTIpO3JldHVybiBafWNhc2UiZ2V0WGZlclN0YXRlIjpyZXR1cm4gYXdhaXQgSi54ZmVyU3RhdGUuZ2V0KCk7ZGVmYXVsdDp7bGV0IFo9JDt0aHJvdyBFcnJvcigidW5rbm93biB3b3JrZXIgY29tbWFuZCIpfX19fWNsYXNzIE4wIGV4dGVuZHMgRXJyb3J7c3RhdHVzO2NvbnN0cnVjdG9yKCQpe3N1cGVyKGBXb3JrZXJTdGF0dXNFcnJvcjogJHt3WyRdfWApO3RoaXMuc3RhdHVzPSQ7dGhpcy5uYW1lPSJXb3JrZXJTdGF0dXNFcnJvciJ9fWZ1bmN0aW9uIEtKKCQsSil7cmV0dXJue2tpbmQ6InJlcGx5IixpZDokLG9rOiEwLHJlc3VsdDpKfX1mdW5jdGlvbiB3WigkLEope3JldHVybntraW5kOiJyZXBseSIsaWQ6JCxvazohMSxzdGF0dXM6Sn19dmFyIG0wPWdsb2JhbFRoaXMsQ1Y9bmV3IERaKCgkLEopPT57aWYoSiYmSi5sZW5ndGg+MCltMC5wb3N0TWVzc2FnZSgkLEopO2Vsc2UgbTAucG9zdE1lc3NhZ2UoJCl9KTttMC5vbm1lc3NhZ2U9KCQpPT57bGV0IEo9JC5kYXRhO2lmKCF4WihKKSlyZXR1cm47SFkoSil9O2FzeW5jIGZ1bmN0aW9uIEhZKCQpe3RyeXtsZXQgSj1hd2FpdCBDVi5oYW5kbGUoJCk7aWYoKCQub3A9PT0iZXhwb3J0Inx8JC5vcD09PSJtc2djaGVjayJ8fCQub3A9PT0iZW50Y2hlY2siKSYmSiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe2xldCBaPUouc2xpY2UoKTttMC5wb3N0TWVzc2FnZShLSigkLmlkLFopLFtaLmJ1ZmZlcl0pO3JldHVybn1pZigkLm9wPT09InJlY29uY2lsZSImJkomJnR5cGVvZiBKPT09Im9iamVjdCImJiJtc2djaGVjayJpbiBKJiZKLm1zZ2NoZWNrIGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IFo9Si5tc2djaGVjay5zbGljZSgpLFE9ey4uLkosbXNnY2hlY2s6Wn07bTAucG9zdE1lc3NhZ2UoS0ooJC5pZCxRKSxbWi5idWZmZXJdKTtyZXR1cm59bTAucG9zdE1lc3NhZ2UoS0ooJC5pZCxKKSl9Y2F0Y2goSil7aWYoSiBpbnN0YW5jZW9mIE4wKXttMC5wb3N0TWVzc2FnZSh3WigkLmlkLEouc3RhdHVzKSk7cmV0dXJufWNvbnNvbGUuZXJyb3IoIndvcmtlciBjb21tYW5kIGZhaWxlZCIsSiksbTAucG9zdE1lc3NhZ2Uod1ooJC5pZCwxMikpfX1DVi5pbml0KCkuY2F0Y2goKCQpPT57Y29uc29sZS5lcnJvcigid29ya2VyIGluaXQgZmFpbGVkIiwkKX0pOwo=";var HW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,nV=HW===void 0?void 0:HW.prototype.postMessage,NW;function NG(){if(typeof MW!=="string"||MW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(MW)}function HG(){if(NW!==void 0)return NW;let Z=new Blob([NG()],{type:"text/javascript"});return NW=URL.createObjectURL(Z),NW}function M0(){if(HW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new HW(HG(),{type:"module"})}function N0(Z,X,W){if(nV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)nV.call(Z,X,{transfer:W});else nV.call(Z,X)}var gG=new TextEncoder().encode("diplomatic.bind.v1"),_V=new TextEncoder().encode("diplomatic.bindtag.v1"),hG=32,PG=32,UG=16,RZ=new sZ;class ZZ{#Z;constructor(Z){this.#Z=Z}static async fromRandom(){let Z=await RZ.gen256BitSecureRandomSeed(),[X,W]=VZ(Z);if(W!==0||X===void 0)throw Error(`enclave: invalid random seed (${W})`);return new ZZ(X)}static fromBytes(Z){let[X,W]=VZ(Z);if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=VZ(X.slice());if(l!==0)return Y(l);if(V===void 0)return Y(10);return b(new ZZ(V))}async sealWithPasskey(Z){let X=Z?.salt??xW,W=Z?.credId,V=W,l=Z?.createCredIfNeeded===!0&&(W===void 0||!(W instanceof Uint8Array)&&W.length===0),K,G;if(l){let[C,F]=await z0({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??LX,displayName:Z?.displayName,authenticatorAttachment:Z?.authenticatorAttachment,hints:Z?.hints,excludeCredentials:Z?.excludeCredentials,salt:X});if(F!==0)return Y(F);if(C===void 0)return Y(30);if(!C.prfEnabled)return Y(30);V=C.credId,K=C,G=C.prf}let m=async(C,F,d,k)=>{try{let[c,I]=await this.#l(C);if(I!==0)return Y(I);if(c===void 0)return Y(12);return b({sealedMaster:c,salt:X.slice(),credId:F.slice(),userId:K?.userId===void 0?void 0:K.userId.slice(),attachment:d??K?.attachment,transports:k??K?.transports,aaguid:K?.aaguid===void 0?void 0:K.aaguid.slice()})}finally{C.fill(0)}};if(G!==void 0&&K!==void 0)return m(G,K.credId,K.attachment,K.transports);let[J,R]=await fV({rpId:Z?.rpId,rpName:Z?.rpName,credId:V,salt:X,hints:Z?.hints});if(R!==0)return Y(R);if(J===void 0)return Y(7);return m(J.prf,J.credId,J.attachment,J.transports)}async bind(Z,X){if(X!==void 0){for(let K of X)if(!await this.#V(K.credId,K.tag))return Y(10)}let[W,V]=await this.sealWithPasskey(Z);if(V!==0)return Y(V);if(W===void 0)return Y(12);let l=await this.#W(W.credId);return b({...W,tag:l})}static async unsealWithPasskey(Z,X){if(Z.length===0)return Y(22);let W=[];for(let m of Z)if(m.credId.byteLength>0)W.push(m.credId);let[V,l]=await fV({rpId:X.rpId,rpName:X.rpName,hints:X.hints,credId:W.length>0?W:void 0,salt:X.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);let K=Z.find((m)=>w(m.credId,V.credId)),G=K===void 0?Z:[K,...Z.filter((m)=>m!==K)];try{for(let m of G){let[J]=await ZZ.#K(m.sealedMaster,V.prf);if(J!==void 0)return b({enclave:J,credId:V.credId.slice()})}return Y(20)}finally{V.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await SW(X);if(G!==0)return Y(G);if(K===void 0)return Y(30);W=K}let[V,l]=this.#Y(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await AX(W,V,X);if(K!==0)return Y(K);return b(W)}finally{V.fill(0)}}static async fromLargeBlob(Z){let[X,W]=await zW(Z?.credId,Z);if(W!==0)return Y(W);if(X===void 0)return Y(7);try{return ZZ.#J(X.blob,X.credId)}finally{X.blob.fill(0)}}static async clearLargeBlob(Z,X){return AX(Z,new Uint8Array(kZ),X)}static pairRequest(){return BX.create()}async pairAccept(Z,X){let W;try{W=await RZ.genX25519()}catch{return Y(29)}try{let[V,l]=await wV(W.priv,Z,Z,W.pub);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let[K,G]=this.#X(X);if(G!==0)return Y(G);if(K===void 0)return Y(12);try{let m=await RZ.encryptXSalsa20Poly1305Combined(K,V);return BV(SZ(W.pub,m))}catch{return Y(12)}finally{K.fill(0)}}finally{V.fill(0)}}finally{W.priv.fill(0)}}#X(Z){let X=this.#Z.slice(),[W,V]=VZ(X);if(V!==0)return X.fill(0),Y(V);if(W===void 0)return X.fill(0),Y(10);try{let l={masterSeed:W,hosts:Z.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))},K=new E;try{let G=K.writeStruct(TW,l);if(G!==0)return Y(G);return b(K.result())}finally{K.wipe()}}finally{W.fill(0)}}spawnSyncWorker(Z){let X=M0(),W=this.#Z.slice();return N0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#R(W,G),l=(G)=>this.#C(W,G);return{encrypt:Object.freeze({encrypt:V}),decrypt:Object.freeze({decrypt:l}),both:Object.freeze({encrypt:V,decrypt:l})}[X]}async deriveIdentity(Z,X=0){let W=Z,V=X,l=await this.#m(W,V),K=l.publicKey;return l.privateKey.fill(0),Object.freeze({publicKey:K,sign:(G)=>this.#b(W,V,G),kdmFor:(G)=>this.#d(W,V,G)})}async#W(Z){let X=new Uint8Array(this.#Z.byteLength+_V.byteLength+Z.byteLength);X.set(this.#Z,0),X.set(_V,this.#Z.byteLength),X.set(Z,this.#Z.byteLength+_V.byteLength);try{return await RZ.blake3(X)}finally{X.fill(0)}}async#V(Z,X){if(X.byteLength!==hG)return!1;let W=await this.#W(Z);try{if(W.byteLength!==X.byteLength)return!1;let V=0;for(let l=0;l<W.byteLength;l++){let K=W[l],G=X[l];if(K===void 0||G===void 0)return!1;V|=K^G}return V===0}finally{W.fill(0)}}async#l(Z){let[X,W]=await H0(RZ,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await RZ.encryptXSalsa20Poly1305Combined(this.#Z,X);return iZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#K(Z,X){let[,W]=iZ(Z);if(W!==0)return Y(W);let[V,l]=await H0(RZ,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await RZ.decryptXSalsa20Poly1305Combined(Z,V)}catch{return Y(20)}return ZZ.fromBytes(K)}finally{V.fill(0),K?.fill(0)}}#Y(Z){let X=this.#Z.slice(),[W,V]=VZ(X);if(V!==0)return X.fill(0),Y(V);if(W===void 0)return X.fill(0),Y(10);try{let[l,K]=c0(W,Z);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=new E,m=G.writeStruct(OV,l);if(m!==0)return Y(m);return b(G.result())}finally{l.masterSeed.fill(0)}}finally{W.fill(0)}}static#J(Z,X){if(Z.byteLength===0||Z.every((K)=>K===0))return Y(22);if(Z.byteLength===kZ){if(Z.every((m)=>m===0))return Y(22);let[K,G]=ZZ.fromBytes(Z);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({enclave:K,hosts:[],credId:X})}let W=new j(Z),[V,l]=W.readStruct(OV);if(l!==0)return Y(l);if(V===void 0)return Y(14);try{if(V.masterSeed.every((m)=>m===0))return Y(22);let[K,G]=ZZ.fromBytes(V.masterSeed);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({enclave:K,hosts:V.hosts.map((m)=>({...m})),credId:X})}finally{V.masterSeed.fill(0)}}async#R(Z,X){let W=await this.#G(Z);try{return await RZ.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#C(Z,X){let W=await this.#G(Z);try{return await RZ.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){let X=new Uint8Array(this.#Z.byteLength+Z.byteLength);X.set(this.#Z,0),X.set(Z,this.#Z.byteLength);try{return await RZ.blake3(X)}finally{X.fill(0)}}async#F(Z,X){let W=new TextEncoder().encode(Z),V=new Uint8Array(8);return new DataView(V.buffer).setBigUint64(0,BigInt(X),!1),await this.#G(SZ(W,V))}async#m(Z,X){let W=await this.#F(Z,X);try{return await RZ.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#b(Z,X,W){let V=await this.#m(Z,X);try{return await RZ.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#d(Z,X,W){let V=await this.#m(Z,X),l=SZ(V.privateKey,W);V.privateKey.fill(0);try{return(await RZ.blake3(l)).slice(0,uZ)}finally{l.fill(0)}}}async function H0(Z,X,W=gG){if(X.byteLength<UG)return Y(10);let V=await Z.blake3(SZ(X,W));return b(V.slice(0,PG))}var h0=8;class gW{#Z;#X;#W;#V;constructor(Z){if(this.#V=Z.persistKeyring,this.#W={rpId:Z.rpId,rpName:Z.rpName},Z.keyring!==void 0)this.#X=PZ(Z.keyring)}get keyring(){return this.#X===void 0?void 0:PZ(this.#X)}list(){if(this.#X===void 0)return[];return this.#X.entries.map(EG)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use bindAndSave(enclave) to persist a binding"));return this.#Z=Z,this.#Z}async bindAndSave(Z,X){let W=this.#X,V=X?.credId,l=V instanceof Uint8Array?V.byteLength>0:V!==void 0&&V.length>0;if(!l&&W!==void 0&&W.entries.length>=h0)return Y(26);let K=g0(X?.nick),G=X?.excludeCredentials??(l?void 0:j0(W)),m=X?.salt??W?.salt,J=W===void 0?void 0:W.entries.map((c)=>({credId:c.credId,tag:c.tag})),[R,C]=await Z.bind({...this.#W,salt:m,credId:V,createCredIfNeeded:X?.createCredIfNeeded??!l,excludeCredentials:G,userName:LX,displayName:K??LX,authenticatorAttachment:X?.authenticatorAttachment,hints:X?.hints},J);if(C!==0)return Y(C);if(R===void 0)return Y(12);let F=Date.now(),d={type:"prf",sealedMaster:R.sealedMaster,credId:R.credId,tag:R.tag,userId:R.userId,nick:K,enrolledAt:F,lastUsedAt:F,attachment:R.attachment,transports:R.transports,aaguid:R.aaguid,enrolledOs:jG()},k=W===void 0?{salt:R.salt.slice(),entries:[]}:PZ(W);return this.#X=OG(k,d),this.#Z=Z,await this.#V(PZ(this.#X)),b(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0||Z.entries.length===0)return Y(22);let[X,W]=await ZZ.unsealWithPasskey(Z.entries.map((l)=>({sealedMaster:l.sealedMaster,credId:l.credId})),{...this.#W,salt:Z.salt});if(W!==0)return Y(W);this.#Z=X.enclave;let V=iG(Z,X.credId);if(V!==void 0)this.#X=V,await this.#V(PZ(V));return b(X.enclave)}async rename(Z,X){let W=this.#X;if(W===void 0)return Y(22);let V=W.entries.findIndex((J)=>w(J.credId,Z));if(V<0)return Y(13);let l=W.entries.map(vX),K=l[V];if(K===void 0)return Y(13);let G=g0(X);l[V]={...K,nick:G};let m={salt:W.salt.slice(),entries:l};return this.#X=m,await this.#V(PZ(m)),b(void 0)}async remove(Z){let X=this.#X;if(X===void 0)return Y(22);let W=X.entries.filter((l)=>!w(l.credId,Z));if(W.length===X.entries.length)return Y(13);if(W.length===0)return this.#X=void 0,await this.#V(void 0),b(void 0);let V={salt:X.salt.slice(),entries:W.map(vX)};return this.#X=V,await this.#V(PZ(V)),b(void 0)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function g0(Z){if(Z===void 0)return;let X=Z.trim();return X===""?void 0:X}function jG(){if(typeof navigator>"u")return;return p0(navigator.userAgent)}function vX(Z){let[X,W]=iZ(Z.sealedMaster.slice());return{type:"prf",sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,credId:Z.credId.slice(),tag:Z.tag.slice(),userId:Z.userId===void 0?void 0:Z.userId.slice(),nick:Z.nick,enrolledAt:Z.enrolledAt,lastUsedAt:Z.lastUsedAt,attachment:Z.attachment,transports:Z.transports===void 0?void 0:[...Z.transports],aaguid:Z.aaguid===void 0?void 0:Z.aaguid.slice(),enrolledOs:Z.enrolledOs}}function PZ(Z){return{salt:Z.salt.slice(),entries:Z.entries.map(vX)}}function P0(Z){return Z!==null&&typeof Z==="object"}function uG(Z){if(!P0(Z)||Z.type!=="prf")return;if(!(Z.sealedMaster instanceof Uint8Array)||!(Z.credId instanceof Uint8Array)||!(Z.tag instanceof Uint8Array)||Z.tag.byteLength!==32||typeof Z.enrolledAt!=="number"||!Number.isFinite(Z.enrolledAt))return;let[X,W]=iZ(Z.sealedMaster);if(W!==0||X===void 0)return;let V=Z.attachment==="platform"||Z.attachment==="cross-platform"?Z.attachment:void 0,l=Z.enrolledOs,K=l==="ios"||l==="macos"||l==="android"||l==="windows"||l==="linux"||l==="other"?l:void 0,G=Array.isArray(Z.transports)?Z.transports.filter((m)=>typeof m==="string"):void 0;return{type:"prf",sealedMaster:X,credId:Z.credId.slice(),tag:Z.tag.slice(),userId:Z.userId instanceof Uint8Array?Z.userId.slice():void 0,nick:typeof Z.nick==="string"?Z.nick:void 0,enrolledAt:Z.enrolledAt,lastUsedAt:typeof Z.lastUsedAt==="number"&&Number.isFinite(Z.lastUsedAt)?Z.lastUsedAt:void 0,attachment:V,transports:G===void 0||G.length===0?void 0:G,aaguid:Z.aaguid instanceof Uint8Array?Z.aaguid.slice():void 0,enrolledOs:K}}function U0(Z){if(!P0(Z))return;if(!(Z.salt instanceof Uint8Array)||!Array.isArray(Z.entries))return;let X=[];for(let W of Z.entries){let V=uG(W);if(V!==void 0)X.push(V)}if(X.length===0)return;return{salt:Z.salt.slice(),entries:X}}function EG(Z){return{type:"prf",credId:Z.credId.slice(),userId:Z.userId===void 0?void 0:Z.userId.slice(),nick:Z.nick,enrolledAt:Z.enrolledAt,lastUsedAt:Z.lastUsedAt,attachment:Z.attachment,transports:Z.transports===void 0?void 0:[...Z.transports],aaguid:Z.aaguid===void 0?void 0:Z.aaguid.slice(),enrolledOs:Z.enrolledOs}}function j0(Z){if(Z===void 0)return[];return Z.entries.filter((X)=>X.credId.byteLength>0).map((X)=>X.credId.slice())}function OG(Z,X){let W=Z.entries.map(vX),V=W.findIndex((l)=>w(l.credId,X.credId));if(V>=0){let l=W[V];W[V]={...X,enrolledAt:l?.enrolledAt??X.enrolledAt,nick:X.nick??l?.nick}}else W.push(X);return{salt:Z.salt.slice(),entries:W}}function iG(Z,X){if(X.byteLength===0)return;let W=Z.entries.findIndex((K)=>w(K.credId,X));if(W<0)return;let V=Z.entries.map(vX),l=V[W];if(l===void 0)return;return V[W]={...l,lastUsedAt:Date.now()},{salt:Z.salt.slice(),entries:V}}var BG=hW("fbfc3007154e4ecc8c0b6e020557d7bd"),wG=hW("ea9b8d664d011d213ce4b6b48cb575d4"),DG=hW("08987058cadc4b81b6e130de50dcbe96"),AG=hW("2fc0579f811347eab116bb5a8db9202a");function hW(Z){let X=new Uint8Array(16);for(let W=0;W<16;W++)X[W]=Number.parseInt(Z.slice(W*2,W*2+2),16);return X}function vG(Z){if(Z===void 0||Z.byteLength!==16)return;if(w(Z,BG))return"Apple Passkey";if(w(Z,wG))return"GPM";if(w(Z,DG))return"Windows Hello";if(w(Z,AG))return"YubiKey";return}function oG(Z){if(Z.attachment==="cross-platform")return!0;if(Z.transports===void 0)return!1;return Z.transports.some((X)=>X==="usb"||X==="nfc"||X==="ble")}function u0(Z){let X=vG(Z.aaguid);if(X!==void 0)return X;if(oG(Z))return"Security key";if(Z.attachment==="platform"){if(Z.enrolledOs==="ios"||Z.enrolledOs==="macos")return"Apple Passkey";if(Z.enrolledOs==="android")return"GPM";if(Z.enrolledOs==="windows")return"Windows Hello";return"Passkey"}return"Passkey"}function $G(Z){if(Z.byteLength===0)return"";let X=Math.min(4,Z.byteLength),W="";for(let V=Z.byteLength-X;V<Z.byteLength;V++){let l=Z[V];if(l===void 0)continue;W+=l.toString(16).padStart(2,"0")}return W}function qG(Z){if(Z.nick!==void 0&&Z.nick!=="")return Z.nick;let X=u0(Z),W=$G(Z.credId);return W===""?X:`${X} ${W}`}var fG="diplomatic.pin/";function nG(Z){return fG+YZ(Z)}async function E0(Z,X,W){let V=await X.deriveIdentity(nG(W),0);return Z.blake3(V.publicKey)}async function PW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await E0(Z,X,W);return{n:W,h:V}}async function UW(Z,X,W){let V=await E0(Z,X,W.n);return _G(V,W.h)}function O0(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.n instanceof Uint8Array)||!(X.h instanceof Uint8Array))return;if(X.n.byteLength<1||X.h.byteLength<1)return;return{n:X.n.slice(),h:X.h.slice()}}function jW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function _G(Z,X){if(Z.byteLength!==X.byteLength)return!1;let W=0;for(let V=0;V<Z.byteLength;V++)W|=Z[V]^X[V];return W===0}var uW="keyring",i0="prfMeta",aV="idPin",B0="idPub";class EW{#Z;db;#X;constructor(Z,X){this.db=Z,this.#X=X}async save(Z,X){return await this.#W(Z),this.#Z=Z,this.#Z}async load(){return this.#Z}async clearSession(){this.#Z=void 0}async wipe(){this.#Z=void 0;let Z=this.db.transaction(GZ,"readwrite"),X=Z.objectStore(GZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(uW),X.delete(i0),X.delete(aV),X.delete(B0)})}async loadKeyring(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(uW);l.onsuccess=()=>{W(U0(l.result))},l.onerror=()=>V(l.error)})}async persistKeyring(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(i0),Z===void 0){W.delete(uW);return}W.put(PZ(Z),uW)})}async hasKeyring(){let Z=await this.loadKeyring();return Z!==void 0&&Z.entries.length>0}async openPrfStore(Z){let X=await this.loadKeyring();return new gW({rpId:Z.rpId,rpName:Z.rpName,keyring:X,persistKeyring:(W)=>this.persistKeyring(W)})}async#W(Z){await this.#K(B0);let X=await this.#V();if(X!==void 0){if(!await UW(this.#X,Z,X))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)");return}let W=await PW(this.#X,Z);await this.#l(W)}#V(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(aV);l.onsuccess=()=>W(O0(l.result)),l.onerror=()=>V(l.error)})}#l(Z){let X=jW(Z),W=this.db.transaction(GZ,"readwrite"),V=W.objectStore(GZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X,aV)})}#K(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}}class sV{db;constructor(Z){this.db=Z}async enq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(bZ,"readwrite"),l=V.objectStore(bZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let J=YZ(m);l.put({host:Z,hash:J})}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(bZ,"readwrite"),l=V.objectStore(bZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let J=YZ(m);l.delete([Z,J])}})}async list(Z){let W=this.db.transaction(bZ,"readonly").objectStore(bZ);return new Promise((V,l)=>{let K=W.getAll();K.onsuccess=()=>{let m=K.result.filter((J)=>J.host===Z).map((J)=>J.hash);V(m.map((J)=>xX(J)))},K.onerror=()=>l(K.error)})}async count(){let X=this.db.transaction(bZ,"readonly").objectStore(bZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(bZ,"readwrite"),X=Z.objectStore(bZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var GZ="seedMeta",KZ="hosts",bZ="uploadQueue",FZ="downloadQueue",q="messages",OX="apld",w0=3,D0="diplomatic-store-db";class rV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new EW(Z,X),this.hosts=new uV(Z),this.uploads=new sV(Z),this.downloads=new jV(Z),this.messages=new EV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function aG(){return new Promise((Z,X)=>{let W=indexedDB.open(D0,w0);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(GZ))V.createObjectStore(GZ);if(!V.objectStoreNames.contains(KZ))V.createObjectStore(KZ,{keyPath:"label"});if(!V.objectStoreNames.contains(bZ))V.createObjectStore(bZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(FZ))V.createObjectStore(FZ);let K;if(!V.objectStoreNames.contains(q))K=V.createObjectStore(q);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore(q)}if(!K.indexNames.contains(OX))K.createIndex(OX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${D0} → v${w0}); waiting for other connections to close`)},W.onsuccess=()=>{let V=W.result;V.onversionchange=()=>{V.close()},Z(V)},W.onerror=()=>X(W.error??Error("protocol store IndexedDB open failed"))})}async function tV(Z){let X=await aG();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new rV(X,Z)}function A0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function v0(Z){if(typeof Z!=="number")return;return Z}function sG(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=rG(Z.phase);if(X===void 0)return;let W={phase:X};if("host"in Z&&typeof Z.host==="string")W.host=Z.host;if("done"in Z&&typeof Z.done==="number")W.done=Z.done;if("total"in Z&&typeof Z.total==="number")W.total=Z.total;if("bytesDone"in Z&&typeof Z.bytesDone==="number")W.bytesDone=Z.bytesDone;if("bytesTotal"in Z&&typeof Z.bytesTotal==="number")W.bytesTotal=Z.bytesTotal;return W}function rG(Z){if(Z==="peek"||Z==="pull"||Z==="open"||Z==="exec"||Z==="push"||Z==="import"||Z==="idle"||Z==="apply")return Z==="apply"?"exec":Z;return}function o0(Z){if(!Z||typeof Z!=="object")return;if(!("numUploads"in Z)||!("numDownloads"in Z))return;if(typeof Z.numUploads!=="number"||typeof Z.numDownloads!=="number")return;let X={phase:"idle"};if("progress"in Z){let W=sG(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var dZ="[DIPLOMATIC]";class $X{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:fZ};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new cZ(async()=>this.cachedClientState),this.xferState=new cZ(async()=>this.cachedXferState),this.scheduledSync=new PX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${dZ} worker sync after local write failed`,K)}}),this.local=new kX(W,Z,X,()=>{throw Error(`${dZ} local writer has no transport (use worker for network)`)},QX,!0,void 0,void 0,()=>{this.scheduledSync.schedule()}),this.local.xferState.listen((K)=>{this.cachedXferState={numUploads:K.numUploads,numDownloads:K.numDownloads,progress:this.cachedXferState.progress},this.xferState.emit()})}bindWorker(Z){let X=this.worker;if(X){X.onmessage=null,X.onerror=null,X.onmessageerror=null;try{X.terminate()}catch{}}this.worker=Z,Z.onmessage=(W)=>{this.onMessage(W.data)},Z.onerror=(W)=>{console.error(`${dZ} worker error`,W),this.failPending(Error(`${dZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${dZ} worker message error`))}}failPending(Z){for(let[,X]of this.pending)X.reject(Z);this.pending.clear()}async flushScheduledSync(){await this.scheduledSync.flush()}static async open(Z,X,W={}){let V=W.clock??new OZ,l=W.syncDebounceMs??GW,K=W.readyTimeoutMs??15000,G=new $X(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){await this.loadSession(!1);let X=await Z.uploads.count(),W=await Z.downloads.count();this.cachedXferState={numUploads:X,numDownloads:W,progress:fZ}}async loadSession(Z){let X=await this.store.seed.load(),W=await this.store.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:Z}}async pullRemoteXfer(){let Z=await this.request({id:this.allocId(),op:"getXferState"}),X=o0(Z);if(X!==void 0)this.cachedXferState=X}requireWorker(){if(!this.worker)throw Error(`${dZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${dZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${dZ} worker terminated`))}onMessage(Z){if(!A0(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${dZ} worker init failed: ${X.message}`));return}case"clientState":{if(this.cachedClientState.connected===X.connected)return;this.cachedClientState={...this.cachedClientState,connected:X.connected},this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(eG));return}case"wiped":{this.state.clear();return}case"reply":{let W=this.pending.get(X.id);if(!W)return;if(this.pending.delete(X.id),X.ok)W.resolve(X.result);else W.reject(new oX(X.status));return}default:return}}allocId(){let Z=this.nextId;return this.nextId+=1,Z}request(Z,X){let W=this.requireWorker();return new Promise((V,l)=>{if(this.pending.set(Z.id,{resolve:V,reject:l}),X&&X.length>0)W.postMessage(Z,X);else W.postMessage(Z)})}async requestStatus(Z,X){try{let W=await this.request(Z,X),V=v0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof oX)return W.status;return 12}}serializeHost(Z){return{handle:Z.handle.href,label:Z.label,idx:Z.idx??0}}async setSeed(Z,X){await this.local.setSeed(Z,X),await this.loadSession(!1),this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G=void 0,m=(J)=>{if(G!==void 0)clearTimeout(G);J()};this.pending.set(W,{resolve:(J)=>m(()=>l(J)),reject:(J)=>m(()=>K(J))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${dZ} setSeed worker timeout after ${V}ms`))},V);try{let J=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(J)}catch(J){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(J instanceof Error?J:Error(String(J)))}});try{await this.pullRemoteXfer()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),!this.worker)return;await this.request({id:this.allocId(),op:"unlink",label:Z})}async hosts(){return this.local.hosts()}async connect(Z=!0,X=!0){if(!this.worker)return;await this.request({id:this.allocId(),op:"connect",listen:Z,sync:X})}async disconnect(){if(!this.worker)return;await this.request({id:this.allocId(),op:"disconnect"})}async insertRaw(Z){return this.local.insertRaw(Z)}async updateRaw(Z,X,W){return this.local.updateRaw(Z,X,W)}async insert(Z){return this.local.insert(Z)}async update(Z){return this.local.update(Z)}async delete(Z){return this.local.delete(Z)}async genEID(Z){return this.local.genEID(Z)}async sync(){if(!this.worker)return 0;return this.requestStatus({id:this.allocId(),op:"sync"})}async rebuild(Z){return this.scheduledSync.cancel(),await this.scheduledSync.flush(),this.requestStatus({id:this.allocId(),op:"rebuild",checkHost:Z?.checkHost})}async listMsgs(Z){return this.local.listMsgs(Z)}async countMsgs(Z){return this.local.countMsgs(Z)}async reconcile(Z,X){try{let W=await this.request({id:this.allocId(),op:"reconcile",hostLabel:Z,pull:X?.pull,push:X?.push,sync:X?.sync});if(!tG(W))return Y(12);return b(W)}catch(W){if(W instanceof oX&&W.status!==0)return Y(W.status);return Y(12)}}async msgcheck(){let Z=await this.request({id:this.allocId(),op:"msgcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} entcheck: expected Uint8Array`);return Z}async wipe(Z){if(await this.local.wipe(Z),this.worker)await this.request({id:this.allocId(),op:"wipe",msgs:Z?.msgs,ents:Z?.ents,meta:Z?.meta,seed:Z?.seed});await this.hydrateStateFromStore(this.store),this.clientState.emit(),this.xferState.emit()}async import(Z){let X=new Uint8Array(await Z.arrayBuffer());return this.requestStatus({id:this.allocId(),op:"import",bytes:X},[X.buffer])}async export(Z,X){try{let W=await this.request({id:this.allocId(),op:"export"});if(!(W instanceof Uint8Array))return 12;let V=new Blob([W.slice()]);return YW(V,Z),0}catch(W){if(W instanceof oX)return W.status;return 12}}}class oX extends Error{status;constructor(Z){super(`WorkerReplyError: ${z[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function tG(Z){if(!Z||typeof Z!=="object")return!1;let X=Z;return X.msgcheck instanceof Uint8Array&&X.msgcheck.length===32&&typeof X.numBags==="number"&&typeof X.numDupes==="number"}function eG(Z){return Z}var pX="[DIPLOMATIC]";async function OW(Z){let X=Z.clock??new OZ;if(Z.worker===!0&&Zm(Z)!==void 0)throw Error(`${pX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${pX} sync on main thread `+"(no worker — app did not request a worker)");let l=await $0(Z.store);return Xm(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${pX} worker: true but Worker API is unavailable`);let W=await $0(void 0),V=await $X.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${pX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${pX} terminating sync worker`),V.terminate()}}}function Zm(Z){if("store"in Z)return Z.store;return}async function Xm(Z,X,W){let V=new kX(Z,X,W,tW,QX);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function $0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${pX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return tV(QX)}function Wm(Z){let[X,W]=eV();return iW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function Vm(Z){let[X,W]=eV();return iW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function lm(Z){iW(()=>{async function X(){try{if(!(await Z.clientState.get()).hasSeed)return;await Z.connect(),await Z.sync()}catch(K){console.error("reconnectAndSync failed",K)}}function W(){X()}function V(){if(typeof document<"u"&&document.visibilityState==="visible")X()}function l(){X()}if(globalThis.addEventListener("online",W),typeof document<"u")document.addEventListener("visibilitychange",V);return globalThis.addEventListener("focus",l),globalThis.addEventListener("pageshow",l),()=>{if(globalThis.removeEventListener("online",W),typeof document<"u")document.removeEventListener("visibilitychange",V);globalThis.removeEventListener("focus",l),globalThis.removeEventListener("pageshow",l)}},[Z])}function Km(Z={}){let X=Z.clock??new OZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,J]=eV({stateMgr:VV});return iW(()=>{let R=!1,C;return(async()=>{let F=await JV();if(R)return;let d=lW(F),k=K?await OW({state:d,clock:X,worker:!0,readyTimeoutMs:l}):await OW({state:d,clock:X,store:G,readyTimeoutMs:l});if(R){k.dispose();return}C=k.dispose;let{client:c,mode:I}=k;if(W)await c.setSeed(W);if(V)await c.link(V);if(R){C();return}J({client:c,entDB:F,stateMgr:d,mode:I,error:void 0})})().catch((F)=>{let d=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",d),!R)J((k)=>({...k,client:void 0,error:d}))}),()=>{R=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as Gm,useEffect as q0,useRef as mm,useState as Ym}from"react";function f0(Z,X,W){let[V,l]=Ym();return q0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function Jm(Z,X,W){let V=mm(W());return q0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),Gm(V.current)}function n0(Z,X){return`${Z}:${X}`}class Zl{queue=new Map;async enq(Z){for(let X of Z){let W=n0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=n0(Z,W);this.queue.delete(V)}}async list(){let Z=[];for(let X of this.queue.values())Z.push(X);return Z}async count(){return this.queue.size}async wipe(){this.queue.clear()}}function Rm(Z,X){if(X.setLastSeq!==void 0)Z.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0&&X.lastSeq>Z.lastSeq)Z.lastSeq=X.lastSeq}class Xl{hosts=new Map;async add(Z){let X=this.hosts.get(Z.label),W=X!==void 0&&X.handle===Z.handle&&(X.idx??0)===(Z.idx??0),V={...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0};this.hosts.set(Z.label,V)}async touch(Z,X){await this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.hosts.get(Z);if(!W)return;Rm(W,X),this.hosts.set(Z,{...W})}async get(Z){return this.hosts.get(Z)}async set(Z,X){let W=this.hosts.get(Z);if(!W)return 13;return this.hosts.set(Z,{...W,...X}),0}async del(Z){this.hosts.delete(Z)}async list(){return this.hosts.values()}async wipe(){this.hosts.clear()}}class Wl{crypto;messages=new Map;constructor(Z){this.crypto=Z}async add(Z){let X=[];for(let{key:W,data:V}of Z)this.messages.set(H(W),V),X.push(0);return X}async del(Z){for(let X of Z)this.messages.delete(H(X))}async get(Z){let X=this.messages.get(H(Z));if(X)return await wZ(Z,X,this.crypto);return}async has(Z){return this.messages.has(H(Z))}async list(Z){let X=Z?.apld,W=Z?.body!==!1,V=[];for(let[l,K]of this.messages){if(X!==void 0&&dX(K.apld)!==X)continue;let G=e(l);V.push(await wZ(G,K,this.crypto,{body:W}))}return V}async count(Z){if(Z===void 0)return this.messages.size;let X=0;for(let W of this.messages.values())if(dX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(e(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(w(Z,V.eid)===!1)continue;let l=e(W);if(X===void 0)X={hash:l,data:V};else if((V.ctr??0)>(X.data.ctr??0)||(V.ctr??0)===(X.data.ctr??0)&&(V.off??0)>(X.data.off??0))X={hash:l,data:V}}if(X)return await wZ(X.hash,X.data,this.crypto);return}async markApplied(Z){for(let X of Z){let W=this.messages.get(H(X));if(!W)continue;nZ(W,BZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(H(X));if(!V)continue;nZ(V,IZ,W)}}async wipe(){this.messages.clear()}}class Vl{#Z;#X;#W;constructor(Z){this.#X=Z}async save(Z,X){if(this.#W!==void 0){if(!await UW(this.#X,Z,this.#W))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)")}else this.#W=await PW(this.#X,Z);return this.#Z=Z,this.#Z}async load(){return this.#Z}async wipe(){this.#Z=void 0,this.#W=void 0}peekPin(){return this.#W===void 0?void 0:jW(this.#W)}}class ll{queue=new Map;async enq(Z,X){let W=this.queue.get(Z)||new Set;this.queue.set(Z,W);for(let V of X)W.add(YZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(YZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(xX(V));return W}async count(){let Z=0;for(let X of this.queue.values())Z+=X.size;return Z}async wipe(){this.queue.clear()}}class _0{seed;hosts=new Xl;uploads=new ll;downloads=new Zl;messages;constructor(Z){this.seed=new Vl(Z),this.messages=new Wl(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class a0{singletonType;latest;latestOff=-1;emitter=new UZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new j(X.eid),[V,l]=W.readStruct(s);if(l!==0)continue;let K=new E;K.writeVarString(this.singletonType);let G=K.result();if(V.id.length===G.length&&V.id.every((m,J)=>m===G[J])){if(this.latest===void 0||X.off>this.latestOff)this.latestOff=X.off,this.latest=X.bod,this.emitter.emit(this.singletonType,null)}}return Z.map(()=>0)}clear=async()=>{return this.latest=void 0,this.latestOff=-1,this.emitter.emit(this.singletonType,null),0};notify=(Z)=>{for(let X of Z)if(X===this.singletonType)this.emitter.emit(this.singletonType,null)};refresh=async(Z)=>{this.notify([this.singletonType])};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var Kl={capable(){return S0()},async createCred(Z){return SW(Z)},async write(Z,X,W){return AX(Z,X,W)},async read(Z,X){let[W,V]=await zW(Z,X);if(V!==0||W===void 0)return Y(V);return b(W.blob)}};class s0{#Z;#X;#W;#V;constructor(Z){if(this.#W=Z.rpId,this.#V=Z.rpName,Z.credId!==void 0)this.#X=Z.credId.slice()}get credId(){if(this.#X===void 0)return;return this.#X.slice()}setCredId(Z){this.#X=Z===void 0?void 0:Z.slice()}async save(Z,X){if(X?.persist!==!0)return this.#Z=Z,this.#Z;let[W,V]=await Z.persistToLargeBlob([],{rpId:this.#W,rpName:this.#V,credId:this.#X});if(V!==0||W===void 0)return Promise.reject(Error(`persistToLargeBlob status ${V}`));return this.#X=W,this.#Z=Z,this.#Z}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await ZZ.fromLargeBlob({rpId:this.#W,rpName:this.#V,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,b(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await ZZ.clearLargeBlob(Z,{rpId:this.#W});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}function $k(){return Kl.capable()}export{pG as webAuthnLastError,lm as useSyncOnResume,Jm as useStateWatcherSuspense,f0 as useStateWatcher,Vm as useClientXferState,Wm as useClientState,Km as useClient,mW as shouldEmitItemProgress,nZ as setApld,RV as revFromHead,gX as revFromEntity,xG as prfCapable,tV as openIDBStore,JV as openEntDB,OW as openDiplomaticClient,VV as nullStateManager,AK as nullEntDB,ul as normalizeTags,$k as largeBlobCapable,qG as keyringLabel,u0 as keyringKind,j0 as keyringCredIds,DK as isTombstone,FV as isTerminalApplyFailure,$K as isPendingApply,o as isLiveEnt,oK as isApldState,fZ as idleProgress,xX as htob,tW as hostHTTPTransport,SK as genSingletonEID,lW as entStateManager,gl as encodeEntRev,s as eidCodec,pW as defaultWebAuthnRpId,bX as defaultPeekProgressEvery,QX as crypto,Hl as cmpBytes,mX as checksumSet,NX as checksumEntRevs,YZ as btoh,zK as btob64url,H as btob64,$W as b64urltob,e as b64tob,iZ as asSealedMasterKey,BV as asDHKEResp,iV as asDHKEReq,dX as apldFromStored,$X as WorkerClient,UZ as TypedEventEmitter,kX as SyncClient,z as Status,HX as StateManager,a0 as SingletonStateManager,WV as SEALED_MASTER_KEY_LEN,gW as PrfSeedStore,s0 as PasskeySeedStore,BX as PairRequest,_0 as MemoryStore,kZ as MASTER_SEED_LEN,h0 as KEYRING_MAX,rV as IDBStore,EW as IDBSeedStore,rW as HTTPTransport,YV as EntIDB,VW as EntDBMemory,E as Encoder,ZZ as Enclave,j as Decoder,xW as DEFAULT_PRF_SALT,OZ as Clock,hX as CachedEntDB,zZ as APLD_PENDING,IZ as APLD_ERROR,BZ as APLD_APPLIED};
|
|
1
|
+
function oi(t){let e=t.length,s=0,n=0;while(n<e){let i=t.charCodeAt(n++);if((i&4294967168)===0){s++;continue}else if((i&4294965248)===0)s+=2;else{if(i>=55296&&i<=56319){if(n<e){let o=t.charCodeAt(n);if((o&64512)===56320)++n,i=((i&1023)<<10)+(o&1023)+65536}}if((i&4294901760)===0)s+=3;else s+=4}}return s}function $o(t,e,s){let n=t.length,i=s,o=0;while(o<n){let r=t.charCodeAt(o++);if((r&4294967168)===0){e[i++]=r;continue}else if((r&4294965248)===0)e[i++]=r>>6&31|192;else{if(r>=55296&&r<=56319){if(o<n){let l=t.charCodeAt(o);if((l&64512)===56320)++o,r=((r&1023)<<10)+(l&1023)+65536}}if((r&4294901760)===0)e[i++]=r>>12&15|224,e[i++]=r>>6&63|128;else e[i++]=r>>18&7|240,e[i++]=r>>12&63|128,e[i++]=r>>6&63|128}e[i++]=r&63|128}}var tr=new TextEncoder,er=50;function sr(t,e,s){tr.encodeInto(t,e.subarray(s))}function ri(t,e,s){if(t.length>er)sr(t,e,s);else $o(t,e,s)}var nr=4096;function Us(t,e,s){let n=e,i=n+s,o=[],r="";while(n<i){let l=t[n++];if((l&128)===0)o.push(l);else if((l&224)===192){let a=t[n++]&63;o.push((l&31)<<6|a)}else if((l&240)===224){let a=t[n++]&63,d=t[n++]&63;o.push((l&31)<<12|a<<6|d)}else if((l&248)===240){let a=t[n++]&63,d=t[n++]&63,u=t[n++]&63,p=(l&7)<<18|a<<12|d<<6|u;if(p>65535)p-=65536,o.push(p>>>10&1023|55296),p=56320|p&1023;o.push(p)}else o.push(l);if(o.length>=nr)r+=String.fromCharCode(...o),o.length=0}if(o.length>0)r+=String.fromCharCode(...o);return r}var ir=new TextDecoder,or=200;function rr(t,e,s){let n=t.subarray(e,e+s);return ir.decode(n)}function li(t,e,s){if(s>or)return rr(t,e,s);else return Us(t,e,s)}class se{type;data;constructor(t,e){this.type=t,this.data=e}}class nt extends Error{constructor(t){super(t);let e=Object.create(nt.prototype);Object.setPrototypeOf(this,e),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:nt.name})}}var ne=4294967295;function ci(t,e,s){let n=s/4294967296,i=s;t.setUint32(e,n),t.setUint32(e+4,i)}function Ee(t,e,s){let n=Math.floor(s/4294967296),i=s;t.setUint32(e,n),t.setUint32(e+4,i)}function Fe(t,e){let s=t.getInt32(e),n=t.getUint32(e+4);return s*4294967296+n}function ai(t,e){let s=t.getUint32(e),n=t.getUint32(e+4);return s*4294967296+n}var lr=-1,cr=4294967295,ar=17179869183;function dr({sec:t,nsec:e}){if(t>=0&&e>=0&&t<=ar)if(e===0&&t<=cr){let s=new Uint8Array(4);return new DataView(s.buffer).setUint32(0,t),s}else{let s=t/4294967296,n=t&4294967295,i=new Uint8Array(8),o=new DataView(i.buffer);return o.setUint32(0,e<<2|s&3),o.setUint32(4,n),i}else{let s=new Uint8Array(12),n=new DataView(s.buffer);return n.setUint32(0,e),Ee(n,4,t),s}}function ur(t){let e=t.getTime(),s=Math.floor(e/1000),n=(e-s*1000)*1e6,i=Math.floor(n/1e9);return{sec:s+i,nsec:n-i*1e9}}function pr(t){if(t instanceof Date){let e=ur(t);return dr(e)}else return null}function mr(t){let e=new DataView(t.buffer,t.byteOffset,t.byteLength);switch(t.byteLength){case 4:{let s=e.getUint32(0),n=0;return{sec:s,nsec:0}}case 8:{let s=e.getUint32(0),n=e.getUint32(4),i=(s&3)*4294967296+n,o=s>>>2;return{sec:i,nsec:o}}case 12:{let s=Fe(e,4),n=e.getUint32(0);return{sec:s,nsec:n}}default:throw new nt(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${t.length}`)}}function hr(t){let e=mr(t);return new Date(e.sec*1000+e.nsec/1e6)}var di={type:lr,encode:pr,decode:hr};class ie{static defaultCodec=new ie;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(di)}register({type:t,encode:e,decode:s}){if(t>=0)this.encoders[t]=e,this.decoders[t]=s;else{let n=-1-t;this.builtInEncoders[n]=e,this.builtInDecoders[n]=s}}tryToEncode(t,e){for(let s=0;s<this.builtInEncoders.length;s++){let n=this.builtInEncoders[s];if(n!=null){let i=n(t,e);if(i!=null){let o=-1-s;return new se(o,i)}}}for(let s=0;s<this.encoders.length;s++){let n=this.encoders[s];if(n!=null){let i=n(t,e);if(i!=null)return new se(s,i)}}if(t instanceof se)return t;return null}decode(t,e,s){let n=e<0?this.builtInDecoders[-1-e]:this.decoders[e];if(n)return n(t,e,s);else return new se(e,t)}}function yr(t){return t instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&t instanceof SharedArrayBuffer}function Se(t){if(t instanceof Uint8Array)return t;else if(ArrayBuffer.isView(t))return new Uint8Array(t.buffer,t.byteOffset,t.byteLength);else if(yr(t))return new Uint8Array(t);else return Uint8Array.from(t)}var br=100,Zr=2048;class Qe{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(t){this.extensionCodec=t?.extensionCodec??ie.defaultCodec,this.context=t?.context,this.useBigInt64=t?.useBigInt64??!1,this.maxDepth=t?.maxDepth??br,this.initialBufferSize=t?.initialBufferSize??Zr,this.sortKeys=t?.sortKeys??!1,this.forceFloat32=t?.forceFloat32??!1,this.ignoreUndefined=t?.ignoreUndefined??!1,this.forceIntegerToFloat=t?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new Qe({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(t){if(this.entered)return this.clone().encodeSharedRef(t);try{return this.entered=!0,this.reinitializeState(),this.doEncode(t,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(t){if(this.entered)return this.clone().encode(t);try{return this.entered=!0,this.reinitializeState(),this.doEncode(t,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(t,e){if(e>this.maxDepth)throw Error(`Too deep objects in depth ${e}`);if(t==null)this.encodeNil();else if(typeof t==="boolean")this.encodeBoolean(t);else if(typeof t==="number")if(!this.forceIntegerToFloat)this.encodeNumber(t);else this.encodeNumberAsFloat(t);else if(typeof t==="string")this.encodeString(t);else if(this.useBigInt64&&typeof t==="bigint")this.encodeBigInt64(t);else this.encodeObject(t,e)}ensureBufferSizeToWrite(t){let e=this.pos+t;if(this.view.byteLength<e)this.resizeBuffer(e*2)}resizeBuffer(t){let e=new ArrayBuffer(t),s=new Uint8Array(e),n=new DataView(e);s.set(this.bytes),this.view=n,this.bytes=s}encodeNil(){this.writeU8(192)}encodeBoolean(t){if(t===!1)this.writeU8(194);else this.writeU8(195)}encodeNumber(t){if(!this.forceIntegerToFloat&&Number.isSafeInteger(t))if(t>=0)if(t<128)this.writeU8(t);else if(t<256)this.writeU8(204),this.writeU8(t);else if(t<65536)this.writeU8(205),this.writeU16(t);else if(t<4294967296)this.writeU8(206),this.writeU32(t);else if(!this.useBigInt64)this.writeU8(207),this.writeU64(t);else this.encodeNumberAsFloat(t);else if(t>=-32)this.writeU8(224|t+32);else if(t>=-128)this.writeU8(208),this.writeI8(t);else if(t>=-32768)this.writeU8(209),this.writeI16(t);else if(t>=-2147483648)this.writeU8(210),this.writeI32(t);else if(!this.useBigInt64)this.writeU8(211),this.writeI64(t);else this.encodeNumberAsFloat(t);else this.encodeNumberAsFloat(t)}encodeNumberAsFloat(t){if(this.forceFloat32)this.writeU8(202),this.writeF32(t);else this.writeU8(203),this.writeF64(t)}encodeBigInt64(t){if(t>=BigInt(0))this.writeU8(207),this.writeBigUint64(t);else this.writeU8(211),this.writeBigInt64(t)}writeStringHeader(t){if(t<32)this.writeU8(160+t);else if(t<256)this.writeU8(217),this.writeU8(t);else if(t<65536)this.writeU8(218),this.writeU16(t);else if(t<4294967296)this.writeU8(219),this.writeU32(t);else throw Error(`Too long string: ${t} bytes in UTF-8`)}encodeString(t){let s=oi(t);this.ensureBufferSizeToWrite(5+s),this.writeStringHeader(s),ri(t,this.bytes,this.pos),this.pos+=s}encodeObject(t,e){let s=this.extensionCodec.tryToEncode(t,this.context);if(s!=null)this.encodeExtension(s);else if(Array.isArray(t))this.encodeArray(t,e);else if(ArrayBuffer.isView(t))this.encodeBinary(t);else if(typeof t==="object")this.encodeMap(t,e);else throw Error(`Unrecognized object: ${Object.prototype.toString.apply(t)}`)}encodeBinary(t){let e=t.byteLength;if(e<256)this.writeU8(196),this.writeU8(e);else if(e<65536)this.writeU8(197),this.writeU16(e);else if(e<4294967296)this.writeU8(198),this.writeU32(e);else throw Error(`Too large binary: ${e}`);let s=Se(t);this.writeU8a(s)}encodeArray(t,e){let s=t.length;if(s<16)this.writeU8(144+s);else if(s<65536)this.writeU8(220),this.writeU16(s);else if(s<4294967296)this.writeU8(221),this.writeU32(s);else throw Error(`Too large array: ${s}`);for(let n of t)this.doEncode(n,e+1)}countWithoutUndefined(t,e){let s=0;for(let n of e)if(t[n]!==void 0)s++;return s}encodeMap(t,e){let s=Object.keys(t);if(this.sortKeys)s.sort();let n=this.ignoreUndefined?this.countWithoutUndefined(t,s):s.length;if(n<16)this.writeU8(128+n);else if(n<65536)this.writeU8(222),this.writeU16(n);else if(n<4294967296)this.writeU8(223),this.writeU32(n);else throw Error(`Too large map object: ${n}`);for(let i of s){let o=t[i];if(!(this.ignoreUndefined&&o===void 0))this.encodeString(i),this.doEncode(o,e+1)}}encodeExtension(t){if(typeof t.data==="function"){let s=t.data(this.pos+6),n=s.length;if(n>=4294967296)throw Error(`Too large extension object: ${n}`);this.writeU8(201),this.writeU32(n),this.writeI8(t.type),this.writeU8a(s);return}let e=t.data.length;if(e===1)this.writeU8(212);else if(e===2)this.writeU8(213);else if(e===4)this.writeU8(214);else if(e===8)this.writeU8(215);else if(e===16)this.writeU8(216);else if(e<256)this.writeU8(199),this.writeU8(e);else if(e<65536)this.writeU8(200),this.writeU16(e);else if(e<4294967296)this.writeU8(201),this.writeU32(e);else throw Error(`Too large extension object: ${e}`);this.writeI8(t.type),this.writeU8a(t.data)}writeU8(t){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,t),this.pos++}writeU8a(t){let e=t.length;this.ensureBufferSizeToWrite(e),this.bytes.set(t,this.pos),this.pos+=e}writeI8(t){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,t),this.pos++}writeU16(t){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,t),this.pos+=2}writeI16(t){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,t),this.pos+=2}writeU32(t){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,t),this.pos+=4}writeI32(t){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,t),this.pos+=4}writeF32(t){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,t),this.pos+=4}writeF64(t){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,t),this.pos+=8}writeU64(t){this.ensureBufferSizeToWrite(8),ci(this.view,this.pos,t),this.pos+=8}writeI64(t){this.ensureBufferSizeToWrite(8),Ee(this.view,this.pos,t),this.pos+=8}writeBigUint64(t){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,t),this.pos+=8}writeBigInt64(t){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,t),this.pos+=8}}function Nt(t,e){return new Qe(e).encodeSharedRef(t)}function ve(t){return`${t<0?"-":""}0x${Math.abs(t).toString(16).padStart(2,"0")}`}var Xr=16,Gr=16;class Bs{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(t=Xr,e=Gr){this.maxKeyLength=t,this.maxLengthPerKey=e,this.caches=[];for(let s=0;s<this.maxKeyLength;s++)this.caches.push([])}canBeCached(t){return t>0&&t<=this.maxKeyLength}find(t,e,s){let n=this.caches[s-1];t:for(let i of n){let o=i.bytes;for(let r=0;r<s;r++)if(o[r]!==t[e+r])continue t;return i.str}return null}store(t,e){let s=this.caches[t.length-1],n={bytes:t,str:e};if(s.length>=this.maxLengthPerKey)s[Math.random()*s.length|0]=n;else s.push(n)}decode(t,e,s){let n=this.find(t,e,s);if(n!=null)return this.hit++,n;this.miss++;let i=Us(t,e,s),o=Uint8Array.prototype.slice.call(t,e,e+s);return this.store(o,i),i}}var Js="array",We="map_key",pi="map_value",fr=(t)=>{if(typeof t==="string"||typeof t==="number")return t;throw new nt("The type of key must be string or number but "+typeof t)};class mi{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(t){let e=this.getUninitializedStateFromPool();e.type=Js,e.position=0,e.size=t,e.array=Array(t)}pushMapState(t){let e=this.getUninitializedStateFromPool();e.type=We,e.readCount=0,e.size=t,e.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let t={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(t)}return this.stack[this.stackHeadPosition]}release(t){if(this.stack[this.stackHeadPosition]!==t)throw Error("Invalid stack state. Released state is not on top of the stack.");if(t.type===Js){let s=t;s.size=0,s.array=void 0,s.position=0,s.type=void 0}if(t.type===We||t.type===pi){let s=t;s.size=0,s.map=void 0,s.readCount=0,s.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}var Ve=-1,Ns=new DataView(new ArrayBuffer(0)),Ir=new Uint8Array(Ns.buffer);try{Ns.getInt8(0)}catch(t){if(!(t instanceof RangeError))throw Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var ui=RangeError("Insufficient data"),Sr=new Bs;class De{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=Ns;bytes=Ir;headByte=Ve;stack=new mi;entered=!1;constructor(t){this.extensionCodec=t?.extensionCodec??ie.defaultCodec,this.context=t?.context,this.useBigInt64=t?.useBigInt64??!1,this.rawStrings=t?.rawStrings??!1,this.maxStrLength=t?.maxStrLength??ne,this.maxBinLength=t?.maxBinLength??ne,this.maxArrayLength=t?.maxArrayLength??ne,this.maxMapLength=t?.maxMapLength??ne,this.maxExtLength=t?.maxExtLength??ne,this.keyDecoder=t?.keyDecoder!==void 0?t.keyDecoder:Sr,this.mapKeyConverter=t?.mapKeyConverter??fr}clone(){return new De({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=Ve,this.stack.reset()}setBuffer(t){let e=Se(t);this.bytes=e,this.view=new DataView(e.buffer,e.byteOffset,e.byteLength),this.pos=0}appendBuffer(t){if(this.headByte===Ve&&!this.hasRemaining(1))this.setBuffer(t);else{let e=this.bytes.subarray(this.pos),s=Se(t),n=new Uint8Array(e.length+s.length);n.set(e),n.set(s,e.length),this.setBuffer(n)}}hasRemaining(t){return this.view.byteLength-this.pos>=t}createExtraByteError(t){let{view:e,pos:s}=this;return RangeError(`Extra ${e.byteLength-s} of ${e.byteLength} byte(s) found at buffer[${t}]`)}decode(t){if(this.entered)return this.clone().decode(t);try{this.entered=!0,this.reinitializeState(),this.setBuffer(t);let e=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return e}finally{this.entered=!1}}*decodeMulti(t){if(this.entered){yield*this.clone().decodeMulti(t);return}try{this.entered=!0,this.reinitializeState(),this.setBuffer(t);while(this.hasRemaining(1))yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(t){if(this.entered)return this.clone().decodeAsync(t);try{this.entered=!0;let e=!1,s;for await(let r of t){if(e)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(r);try{s=this.doDecodeSync(),e=!0}catch(l){if(!(l instanceof RangeError))throw l}this.totalPos+=this.pos}if(e){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return s}let{headByte:n,pos:i,totalPos:o}=this;throw RangeError(`Insufficient data in parsing ${ve(n)} at ${o} (${i} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(t){return this.decodeMultiAsync(t,!0)}decodeStream(t){return this.decodeMultiAsync(t,!1)}async*decodeMultiAsync(t,e){if(this.entered){yield*this.clone().decodeMultiAsync(t,e);return}try{this.entered=!0;let s=e,n=-1;for await(let i of t){if(e&&n===0)throw this.createExtraByteError(this.totalPos);if(this.appendBuffer(i),s)n=this.readArraySize(),s=!1,this.complete();try{while(!0)if(yield this.doDecodeSync(),--n===0)break}catch(o){if(!(o instanceof RangeError))throw o}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){t:while(!0){let t=this.readHeadByte(),e;if(t>=224)e=t-256;else if(t<192)if(t<128)e=t;else if(t<144){let n=t-128;if(n!==0){this.pushMapState(n),this.complete();continue t}else e={}}else if(t<160){let n=t-144;if(n!==0){this.pushArrayState(n),this.complete();continue t}else e=[]}else{let n=t-160;e=this.decodeString(n,0)}else if(t===192)e=null;else if(t===194)e=!1;else if(t===195)e=!0;else if(t===202)e=this.readF32();else if(t===203)e=this.readF64();else if(t===204)e=this.readU8();else if(t===205)e=this.readU16();else if(t===206)e=this.readU32();else if(t===207)if(this.useBigInt64)e=this.readU64AsBigInt();else e=this.readU64();else if(t===208)e=this.readI8();else if(t===209)e=this.readI16();else if(t===210)e=this.readI32();else if(t===211)if(this.useBigInt64)e=this.readI64AsBigInt();else e=this.readI64();else if(t===217){let n=this.lookU8();e=this.decodeString(n,1)}else if(t===218){let n=this.lookU16();e=this.decodeString(n,2)}else if(t===219){let n=this.lookU32();e=this.decodeString(n,4)}else if(t===220){let n=this.readU16();if(n!==0){this.pushArrayState(n),this.complete();continue t}else e=[]}else if(t===221){let n=this.readU32();if(n!==0){this.pushArrayState(n),this.complete();continue t}else e=[]}else if(t===222){let n=this.readU16();if(n!==0){this.pushMapState(n),this.complete();continue t}else e={}}else if(t===223){let n=this.readU32();if(n!==0){this.pushMapState(n),this.complete();continue t}else e={}}else if(t===196){let n=this.lookU8();e=this.decodeBinary(n,1)}else if(t===197){let n=this.lookU16();e=this.decodeBinary(n,2)}else if(t===198){let n=this.lookU32();e=this.decodeBinary(n,4)}else if(t===212)e=this.decodeExtension(1,0);else if(t===213)e=this.decodeExtension(2,0);else if(t===214)e=this.decodeExtension(4,0);else if(t===215)e=this.decodeExtension(8,0);else if(t===216)e=this.decodeExtension(16,0);else if(t===199){let n=this.lookU8();e=this.decodeExtension(n,1)}else if(t===200){let n=this.lookU16();e=this.decodeExtension(n,2)}else if(t===201){let n=this.lookU32();e=this.decodeExtension(n,4)}else throw new nt(`Unrecognized type byte: ${ve(t)}`);this.complete();let s=this.stack;while(s.length>0){let n=s.top();if(n.type===Js)if(n.array[n.position]=e,n.position++,n.position===n.size)e=n.array,s.release(n);else continue t;else if(n.type===We){if(e==="__proto__")throw new nt("The key __proto__ is not allowed");n.key=this.mapKeyConverter(e),n.type=pi;continue t}else if(n.map[n.key]=e,n.readCount++,n.readCount===n.size)e=n.map,s.release(n);else{n.key=null,n.type=We;continue t}}return e}}readHeadByte(){if(this.headByte===Ve)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=Ve}readArraySize(){let t=this.readHeadByte();switch(t){case 220:return this.readU16();case 221:return this.readU32();default:if(t<160)return t-144;else throw new nt(`Unrecognized array type byte: ${ve(t)}`)}}pushMapState(t){if(t>this.maxMapLength)throw new nt(`Max length exceeded: map length (${t}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(t)}pushArrayState(t){if(t>this.maxArrayLength)throw new nt(`Max length exceeded: array length (${t}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(t)}decodeString(t,e){if(!this.rawStrings||this.stateIsMapKey())return this.decodeUtf8String(t,e);return this.decodeBinary(t,e)}decodeUtf8String(t,e){if(t>this.maxStrLength)throw new nt(`Max length exceeded: UTF-8 byte length (${t}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+e+t)throw ui;let s=this.pos+e,n;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(t))n=this.keyDecoder.decode(this.bytes,s,t);else n=li(this.bytes,s,t);return this.pos+=e+t,n}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===We;return!1}decodeBinary(t,e){if(t>this.maxBinLength)throw new nt(`Max length exceeded: bin length (${t}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(t+e))throw ui;let s=this.pos+e,n=this.bytes.subarray(s,s+t);return this.pos+=e+t,n}decodeExtension(t,e){if(t>this.maxExtLength)throw new nt(`Max length exceeded: ext length (${t}) > maxExtLength (${this.maxExtLength})`);let s=this.view.getInt8(this.pos+e),n=this.decodeBinary(t,e+1);return this.extensionCodec.decode(n,s,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let t=this.view.getUint8(this.pos);return this.pos++,t}readI8(){let t=this.view.getInt8(this.pos);return this.pos++,t}readU16(){let t=this.view.getUint16(this.pos);return this.pos+=2,t}readI16(){let t=this.view.getInt16(this.pos);return this.pos+=2,t}readU32(){let t=this.view.getUint32(this.pos);return this.pos+=4,t}readI32(){let t=this.view.getInt32(this.pos);return this.pos+=4,t}readU64(){let t=ai(this.view,this.pos);return this.pos+=8,t}readI64(){let t=Fe(this.view,this.pos);return this.pos+=8,t}readU64AsBigInt(){let t=this.view.getBigUint64(this.pos);return this.pos+=8,t}readI64AsBigInt(){let t=this.view.getBigInt64(this.pos);return this.pos+=8,t}readF32(){let t=this.view.getFloat32(this.pos);return this.pos+=4,t}readF64(){let t=this.view.getFloat64(this.pos);return this.pos+=8,t}}function zs(t,e){return new De(e).decode(t)}class Ct{listeners=new Map;addEventListener(t,e){let s=this.listeners.get(t);if(!s)s=new Set,this.listeners.set(t,s);return s.add(e),()=>{this.removeEventListener(t,e)}}removeEventListener(t,e){let s=this.listeners.get(t);if(s){if(s.delete(e),s.size===0)this.listeners.delete(t)}}emit(t,e){let s=this.listeners.get(t);if(s){let n=Array.from(s);for(let i of n)i(e)}}emitAll(t){let e=Array.from(this.listeners.keys());for(let s of e)this.emit(s,t)}}class bt{getter;static eventName="update";emitter;constructor(t){this.getter=t;this.emitter=new Ct}get=()=>this.getter();async emit(){let t=await this.getter();queueMicrotask(()=>this.emitter.emit(bt.eventName,t))}listen(t){return this.emitter.addEventListener(bt.eventName,t),()=>{this.emitter.removeEventListener(bt.eventName,t)}}}var kt=64;var hi=32,Tt=8;var Oe=32;var yi=30000,bi=512,W;((S)=>{S[S.Success=0]="Success";S[S.InvalidSignature=3]="InvalidSignature";S[S.ClockOutOfSync=4]="ClockOutOfSync";S[S.UserNotRegistered=5]="UserNotRegistered";S[S.ServerMisconfigured=6]="ServerMisconfigured";S[S.MissingBody=7]="MissingBody";S[S.ExtraBodyContent=8]="ExtraBodyContent";S[S.MissingParam=9]="MissingParam";S[S.InvalidParam=10]="InvalidParam";S[S.InvalidRequest=11]="InvalidRequest";S[S.InternalError=12]="InternalError";S[S.NotFound=13]="NotFound";S[S.InvalidMessage=14]="InvalidMessage";S[S.NoChange=15]="NoChange";S[S.DatabaseClosed=16]="DatabaseClosed";S[S.StorageError=17]="StorageError";S[S.DatabaseError=18]="DatabaseError";S[S.HashMismatch=19]="HashMismatch";S[S.DecryptionError=20]="DecryptionError";S[S.NotImplemented=21]="NotImplemented";S[S.MissingSeed=22]="MissingSeed";S[S.OutOfBounds=23]="OutOfBounds";S[S.HostError=24]="HostError";S[S.CommunicationError=25]="CommunicationError";S[S.VarLimitExceeded=26]="VarLimitExceeded";S[S.InvalidResponse=27]="InvalidResponse";S[S.ConnectionClosed=28]="ConnectionClosed";S[S.CryptoError=29]="CryptoError";S[S.WebAuthnError=30]="WebAuthnError"})(W||={});function m(t){return[t,0]}function c(t){return[void 0,t]}function Vr(t){if(t<0)console.info("N",t),console.trace();if(typeof t!=="bigint")t=BigInt(t);if(t<0n)return c(10);let e=[];while(t>0n){let s=Number(t&0x7fn);if(t>>=7n,t>0n)e.push(s|128);else e.push(s)}if(e.length===0)return m(new Uint8Array([0]));if(e.length>8)return c(26);return m(new Uint8Array(e))}function Wr(t,e=0){let s=0n,n=0,i=e;while(!0){if(i>=t.length)return c(14);let o=t[i++];if(o===void 0)return c(14);if(s|=BigInt(o&127)<<BigInt(n),(o&128)===0){if(i-e>8)return c(26);return m({value:s>0x1fffffffffffffn?s:Number(s),bytesRead:i-e})}if(n+=7,n>=56)return c(26)}}class M{data;pos=0;constructor(t){this.data=t}static async fromResponse(t){let e=await t.arrayBuffer(),s=new Uint8Array(e);return new M(s)}readBigInt(){if(this.pos+8>this.data.length)return c(7);let t=new DataView(this.data.buffer,this.data.byteOffset+this.pos).getBigUint64(0,!1);return this.pos+=8,m(t)}readDate(){let[t,e]=this.readVarInt();if(e!==0)return c(e);return m(new Date(t))}readVarInt(){let[t,e]=Wr(this.data,this.pos);if(e!==0)return c(e);this.pos+=t.bytesRead;let s=t.value;return m(typeof s==="bigint"?Number(s):s)}readVarString(){let[t,e]=this.readVarInt();if(e!==0)return c(e);let[s,n]=this.readBytes(t);if(n!==0)return c(n);let i=new TextDecoder().decode(s);return m(i)}readBytes(t){if(t<0)return c(10);if(this.pos+t>this.data.length)return c(23);let e=this.data.slice(this.pos,this.pos+t);return this.pos+=t,m(e)}readVarBytes(){let[t,e]=this.readVarInt();if(e!==0)return c(e);return this.readBytes(t)}readStruct(t){return t.decode(this)}readStructs(t){let e=[];while(!this.done()){let[s,n]=this.readStruct(t);if(n!==0)return c(n);e.push(s)}return m(e)}readBytesSeq(t){let e=[];while(!this.done()){let[s,n]=this.readBytes(t);if(n!==0)return c(n);e.push(s)}return m(e)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class P{parts=[];writeBigInt(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t,!1),this.parts.push(e)}writeDate(t){let e=t.getTime();return this.writeVarInt(e)}writeVarInt(t){let[e,s]=Vr(t);if(s!==0)return s;return this.parts.push(e),0}writeVarString(t){let e=new TextEncoder().encode(t),s=this.writeVarInt(e.length);if(s!==0)return s;return this.writeBytes(e),0}prependBytes(t){this.parts.unshift(t.slice())}writeBytes(t){this.parts.push(t.slice())}writeVarBytes(t){let e=this.writeVarInt(t.length);if(e!==0)return e;return this.writeBytes(t),0}writeStruct(t,e){return t.encode(this,e)}writeStructs(t,e){for(let s of e){let n=this.writeStruct(t,s);if(n!==0)return n}return 0}writeBytesSeq(t){for(let e of t)this.writeBytes(e)}result(){let t=this.parts.reduce((n,i)=>n+i.length,0),e=new Uint8Array(t),s=0;for(let n of this.parts)e.set(n,s),s+=n.length;return e}wipe(){for(let t of this.parts)t.fill(0);this.parts.length=0}*scan(){for(let t of this.parts)yield t}}async function Es(t,e){let s=new P,n=s.writeDate(e);if(n!==0)return c(n);let i=s.result(),o=await t.sign(i);return m({pubKey:t.publicKey,sig:o,timestamp:e})}async function Lt(t,e,s){let n=s.now().getTime(),i=t.timestamp.getTime();if(Math.abs(n-i)>yi)return 4;let r=new P;r.writeDate(t.timestamp);let l=r.result();if(!await e.checkSigEd25519(t.sig,l,t.pubKey))return 3;return 0}var A={encode(t,e){let s=t.writeVarBytes(e.id);if(s!==0)return s;let n=t.writeDate(e.ts);if(n!==0)return n;return 0},decode(t){let[e,s]=t.readVarBytes();if(s!==0)return c(s);let[n,i]=t.readDate();if(i!==0)return c(i);return m({id:e,ts:n})}};function oe(t){let e=new P,s=e.writeStruct(A,t);if(s!==0)return c(s);let n=e.result();return m(n)}async function gr(t){return oe({id:t,ts:new Date(0)})}var ut={encode(t,e){let s=t.writeVarBytes(e.eid);if(s!==0)return s;let n=t.writeVarInt(e.off);if(n!==0)return n;let i=t.writeVarInt(e.ctr);if(i!==0)return i;let o=t.writeVarInt(e.len);if(o!==0)return o;if(e.hsh)t.writeBytes(e.hsh);return 0},decode(t){let[e,s]=t.readVarBytes();if(s!==0)return c(s);let n=new M(e),[,i]=A.decode(n);if(i!==0)return c(i);let[o,r]=t.readVarInt();if(r!==0)return c(r);let[l,a]=t.readVarInt();if(a!==0)return c(a);let[d,u]=t.readVarInt();if(u!==0)return c(u);let p;if(d>0){let[h,y]=t.readBytes(Oe);if(y!==0)return c(y);p=h}return m({eid:e,off:o,ctr:l,len:d,hsh:p})}};function ct(t){return Array.from(t).map((s)=>s.toString(16).padStart(2,"0")).join("")}function ge(t){if(t.length%2!==0)throw Error("Invalid hex string");let e=new Uint8Array(t.length/2);for(let s=0;s<t.length;s+=2)e[s/2]=Number.parseInt(t.substr(s,2),16);return e}function B(t,e){if(t===e)return!0;if(t.byteLength!==e.byteLength)return!1;return t.every((s,n)=>s===e[n])}var R;if(typeof Uint8Array.prototype.toBase64==="function")R=(t)=>t.toBase64();else R=(t)=>btoa(String.fromCharCode(...t));var tt;if(typeof Uint8Array.fromBase64==="function")tt=(t)=>Uint8Array.fromBase64(t);else tt=(t)=>Uint8Array.from(atob(t),(e)=>e.charCodeAt(0));function Kr(t){return R(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Fs(t){let e=t.length%4===0?"":"=".repeat(4-t.length%4),s=t.replace(/-/g,"+").replace(/_/g,"/")+e;return tt(s)}function St(t,e){let s=new Uint8Array(t.length+e.length);return s.set(t,0),s.set(e,t.length),s}function Zi(t,e,s){return s.checkSigEd25519(t.sig,t.headCph,e)}async function Xi(t,e,s,n){let i;if(t.bod&&t.len>0)i=await s.blake3(t.bod);let o=new P,r=ut.encode(o,{...t,hsh:i});if(r!==0)return c(r);let l=o.result(),a=await e.kdmFor(l),d=n.deriveCipher(a,"encrypt"),u=await d.encrypt(l),p=t.bod?await d.encrypt(t.bod):new Uint8Array(0),h=await e.sign(u);return m({sig:h,kdm:a,headCph:u,bodyCph:p})}async function Qs(t,e,s,n,i){let o=new M(t),[r,l]=ut.decode(o);if(l!==0)return c(14);let a;try{a=e&&e.length>0?await s.decrypt(e):void 0}catch{return c(20)}let d=r.hsh&&a===void 0,u=r.hsh===void 0&&a!==void 0;if(d||u)return c(19);if(r.hsh&&a){let h=await n.blake3(a);if(!B(h,r.hsh))return c(19)}let p=i??await n.blake3(t);return m({msgHead:r,bod:a,headHash:p})}class Mt{now(){return new Date}}function Gi(t,e,s,n){let i=e.getTime()-t.getTime(),o=s.getTime()-n.getTime();return(i+o)/2}var Ke={encode(t,e){if(t.writeVarInt(e.quota),e.quota>0){if(e.usage===void 0)return 9;t.writeVarInt(e.usage)}return 0},decode(t){let[e,s]=t.readVarInt();if(s!==0)return c(s);let n;if(e>0){let[i,o]=t.readVarInt();if(o!==0)return c(o);n=i}return m({quota:e,usage:n})}};var vs={encode(t,e){t.writeBytes(new Uint8Array([e.status]));let s=t.writeDate(e.timeRcvd);if(s!==0)return s;let n=t.writeDate(e.timeSent);if(n!==0)return n;let i=t.writeVarInt(e.subscription.term);if(i!==0)return i;let o=t.writeVarInt(e.subscription.elapsed);if(o!==0)return o;let r=t.writeStruct(Ke,e.subscription.stat);if(r!==0)return r;let l=t.writeStruct(Ke,e.subscription.dyn);if(l!==0)return l;return 0},decode(t){let[e,s]=t.readBytes(1);if(s!==0)return c(s);let n=e[0],[i,o]=t.readDate();if(o!==0)return c(o);let[r,l]=t.readDate();if(l!==0)return c(l);let[a,d]=t.readVarInt();if(d!==0)return c(d);let[u,p]=t.readVarInt();if(p!==0)return c(p);let[h,y]=t.readStruct(Ke);if(y!==0)return c(y);let[b,Z]=t.readStruct(Ke);if(Z!==0)return c(Z);return m({status:n,timeRcvd:i,timeSent:r,subscription:{term:a,elapsed:u,stat:h,dyn:b}})}};var Ds={encode(t,e){let s=t.writeVarBytes(e.headCph);if(s!==0)return s;let n=t.writeVarInt(e.seq);if(n!==0)return n;return 0},decode(t){let[e,s]=t.readVarBytes();if(s!==0)return c(s);let[n,i]=t.readVarInt();if(i!==0)return c(i);return m({headCph:e,seq:n})}};var at={encode(t,e){t.writeBytes(e.pubKey),t.writeBytes(e.sig);let s=t.writeDate(e.timestamp);if(s!==0)return s;return 0},decode(t){let[e,s]=t.readBytes(hi);if(s!==0)return c(s);let[n,i]=t.readBytes(kt);if(i!==0)return c(i);let[o,r]=t.readDate();if(r!==0)return c(r);return m({pubKey:e,sig:n,timestamp:o})}};var fi={async encodeReq(t,e,s,n,i){let o=i.writeStruct(at,s);if(o!==0)return o;for(let r of n)i.writeVarInt(r);return 0},async handleReq(t,e,s){let{clock:n,crypto:i,storage:o}=t,[r,l]=e.readStruct(at);if(l!==0)return l;let a=await Lt(r,i,n);if(a!==0)return a;let{pubKey:d}=r,[u,p]=await o.hasUser(d);if(p!==0)return p;if(!u)return 5;let[h,y]=e.readVarInt();if(y!==0)return y;if(!e.done())return 8;let[b,Z]=await o.listHeads(d,h);if(Z!==0)return Z;return s.writeStructs(Ds,b)},decodeResp(t){return t.readStructs(Ds)}};var Os={encode(t,e){t.writeVarInt(e.seq);let s=t.writeVarBytes(e.bodyCph);if(s!==0)return s;return 0},decode(t){let[e,s]=t.readVarInt();if(s!==0)return c(s);let[n,i]=t.readVarBytes();if(i!==0)return c(i);return m({seq:e,bodyCph:n})}};var Ii={async encodeReq(t,e,s,n,i){let o=i.writeStruct(at,s);if(o!==0)return o;for(let r of n){let l=i.writeVarInt(r);if(l!==0)return l}return 0},async handleReq(t,e,s){let{clock:n,crypto:i,storage:o}=t,[r,l]=e.readStruct(at);if(l!==0)return l;let a=await Lt(r,i,n);if(a!==0)return a;let{pubKey:d}=r,[u,p]=await o.hasUser(d);if(p!==0)return p;if(!u)return 5;let h=[];while(!e.done()){let[Z,X]=e.readVarInt();if(X!==0)return X;h.push(Z)}console.info(`PULL: ${h.length} bags`);let[y,b]=await o.getBodies(d,h);if(b!==0)return b;if(!y)return 17;for(let{seq:Z,bodyCph:X}of y){let I={seq:Z,bodyCph:X},f=s.writeStruct(Os,I);if(f!==0)return f}return 0},decodeResp(t){return t.readStructs(Os)}};var js={encode(t,e){t.writeBytes(e.sig),t.writeBytes(e.kdm);let s=t.writeVarBytes(e.headCph);if(s!==0)return s;let n=t.writeVarBytes(e.bodyCph);if(n!==0)return n;return 0},decode(t){let[e,s]=t.readBytes(kt);if(s!==0)return c(s);let[n,i]=t.readBytes(Tt);if(i!==0)return c(i);let[o,r]=t.readVarBytes();if(r!==0)return c(r);let[l,a]=t.readVarBytes();if(a!==0)return c(a);return m({sig:e,kdm:n,headCph:o,bodyCph:l})}};var je={encode(t,e){let s=t.writeVarInt(e.seq);if(s!==0)return s;let n=t.writeVarBytes(e.headCph);if(n!==0)return n;let i=e.bodyCph?e.bodyCph.length:0,o=t.writeVarInt(i);if(o!==0)return o;if(i>0){if(!e.bodyCph)return 10;t.writeBytes(e.bodyCph)}return 0},decode(t){let[e,s]=t.readVarInt();if(s!==0)return c(s);let[n,i]=t.readVarBytes();if(i!==0)return c(i);let[o,r]=t.readVarInt();if(r!==0)return c(r);let l;if(o>0){let[a,d]=t.readBytes(o);if(d!==0)return c(d);l=a}return m({seq:e,headCph:n,bodyCph:l})}};var Ae={encode(t,e){t.writeBytes(e.sig),t.writeBytes(e.kdm);let s=t.writeVarBytes(e.headCph);if(s!==0)return s;return 0},decode(t){let[e,s]=t.readBytes(kt);if(s!==0)return c(s);let[n,i]=t.readBytes(Tt);if(i!==0)return c(i);let[o,r]=t.readVarBytes();if(r!==0)return c(r);return m({sig:e,kdm:n,headCph:o})}};var qe={encode(t,e){if(t.writeVarInt(e.idx),t.writeBytes(new Uint8Array([e.status])),e.status===0)t.writeVarInt(e.seq);return 0},decode(t){let[e,s]=t.readVarInt();if(s!==0)return c(s);let[n,i]=t.readBytes(1);if(i!==0)return c(i);let o=n[0];if(o!==0)return m({idx:e,status:o});let[r,l]=t.readVarInt();if(l!==0)return c(l);return m({idx:e,status:o,seq:r})}};var Si={async encodeReq(t,e,s,n,i){let o=i.writeStruct(at,s);if(o!==0)return o;let r=i.writeStructs(js,n);if(r!==0)return r;return 0},async handleReq(t,e,s){let{clock:n,crypto:i,storage:o,notifier:r}=t,[l,a]=e.readStruct(at);if(a!==0)return a;let d=await Lt(l,i,n);if(d!==0)return d;let{pubKey:u}=l,[p,h]=await o.hasUser(u);if(h!==0)return h;if(!p)return 5;let[y,b]=e.readStructs(js);if(b!==0)return b;console.info(`PUSH: ${y.length} bags`);let Z=[],X=[];for(let G=0;G<y.length;G++){let K=y[G];if(!await Zi(K,u,i)){let L={idx:G,status:3},T=s.writeStruct(qe,L);if(T!==0)return T;continue}Z.push(G),X.push(K)}let[I,f]=await o.setBags(u,X);if(f!==0)return f;if(!I||I.length!==X.length)return 17;let V=[];for(let G=0;G<X.length;G++){let K=X[G],H=Z[G],L=I[G],T=new P,C=T.writeStruct(Ae,K);if(C!==0)return C;let U=T.result(),N={seq:L,headCph:U};if(y.length===1&&K.bodyCph.length<=bi)N.bodyCph=K.bodyCph;V.push(N);let F={idx:H,status:0,seq:L},S=s.writeStruct(qe,F);if(S!==0)return S}if(V.length>0){let G=new P,K=G.writeStructs(je,V);if(K!==0)return K;let H=G.result();await Promise.resolve(r.push(u,H))}return 0},decodeResp(t){return t.readStructs(qe)}};var Vi={async encodeReq(t,e,s,n,i){return i.writeStruct(at,s)},async handleReq(t,e,s){let{clock:n,crypto:i,storage:o}=t,[r,l]=e.readStruct(at);if(l!==0)return l;let a=await Lt(r,i,n);if(a!==0)return a;let{pubKey:d}=r;if(!e.done())return 8;let[u,p]=await o.addUser(d);if(p!==0)return p;return 0},decodeResp(t){return m(void 0)}};class As{url;websocket;constructor(t){this.url=t}connected(){return this.websocket!==void 0&&this.websocket.readyState===WebSocket.OPEN}async connect(t,e,s=()=>{},n=()=>{}){let{url:i}=this;if(this.websocket)this.websocket.close(),this.websocket=void 0;let o=new P;o.writeStruct(at,t);let r=o.result(),l=ct(r);return i.searchParams.set("t",l),this.websocket=new WebSocket(i),this.websocket.binaryType="arraybuffer",this.websocket.onopen=()=>{console.log("CONNECTED"),n()},this.websocket.onclose=()=>{console.log("DISCONNECTED"),this.websocket=void 0,s()},this.websocket.onmessage=(a)=>{let d=new Uint8Array(a.data);e(d)},this.websocket.onerror=(a)=>{console.log(`ERROR: ${JSON.stringify(a)}`),this.websocket=void 0,s()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var q={user:{path:"/user",endpoint:Vi,name:0},push:{path:"/push",endpoint:Si,name:2},peek:{path:"/peek",endpoint:fi,name:1},pull:{path:"/pull",endpoint:Ii,name:3}},xr={0:q.user,2:q.push,1:q.peek,3:q.pull},Wu={[q.user.path]:q.user,[q.push.path]:q.push,[q.peek.path]:q.peek,[q.pull.path]:q.pull};class qs{url;listener;constructor(t){this.url=t;this.listener=new As(t)}async call(t,e){let{path:s}=xr[t],n=new URL(s,this.url);try{return await Rr(n,e)}catch{return c(25)}}}var _s=(t)=>new qs(t.handle);async function Rr(t,e){let s=await fetch(t,{method:"POST",body:e.result().slice()});if(!s.ok)return c(24);let n=await M.fromResponse(s);return m(n)}class _e{enclave;crypto;host;clock;transport;updateHostMeta;constructor(t,e,s,n,i,o){this.enclave=t;this.crypto=e;this.host=s;this.clock=n;this.transport=i;this.updateHostMeta=o}async call(t,e){let{clock:s,transport:n}=this,{endpoint:i,name:o}=t,r=await this.identity(),l=s.now(),[a,d]=await Es(r,l);if(d!==0)return c(d);let u=new P,p=await i.encodeReq(this,r,a,e,u);if(p!==0)return c(p);let h=s.now(),[y,b]=await n.call(o,u),Z=s.now();if(b!==0)return c(b);let[X,I]=y.readStruct(vs);if(I!==0)return c(I);if(X.status!==0)return c(X.status);let V={clockOffset:Gi(h,X.timeRcvd,X.timeSent,Z),subscription:X.subscription},G=await this.updateHostMeta(V);if(G!==0)return c(G);return i.decodeResp(y)}identity=()=>{let{host:t,enclave:e}=this;return e.deriveIdentity(t.label,t.idx??0)};seal=async(t)=>{let{crypto:e,enclave:s}=this,n=await this.identity();return Xi(t,n,e,s)};register=()=>this.call(q.user,[]);peek=(t)=>this.call(q.peek,[t]);push=(t)=>this.call(q.push,t);pull=(t)=>this.call(q.pull,t);listen=async(t,e,s)=>{let{clock:n,transport:i}=this,{listener:o}=i,r=await this.identity(),l=n.now(),[a,d]=await Es(r,l);if(d!==0)return d;return await o.connect(a,t,e,s)};isConnected(){let t=this.transport?.listener;if(t&&typeof t.connected==="function")return t.connected();return!0}closeListener(){this.transport?.listener?.disconnect()}}var $s={encode(t,e){let s=t.writeVarString(e.lbl);if(s!==0)return s;let n=t.writeVarInt(e.idx);if(n!==0)return n;let i=t.writeVarInt(e.num);if(i!==0)return i;return t.writeBytes(e.hsh),t.writeBytes(e.sig),0},decode(t){let[e,s]=t.readVarString();if(s!==0)return c(s);let[n,i]=t.readVarInt();if(i!==0)return c(i);let[o,r]=t.readVarInt();if(r!==0)return c(r);let[l,a]=t.readBytes(Oe);if(a!==0)return c(a);let[d,u]=t.readBytes(kt);if(u!==0)return c(u);return m({lbl:e,idx:n,num:o,hsh:l,sig:d})}};var tn={encode(t,e){let s=t.writeStruct($s,e.head);if(s!==0)return s;let n=t.writeVarBytes(e.indexEnc);if(n!==0)return n;let i=t.writeVarBytes(e.bodyEnc);if(i!==0)return i;return 0},decode(t){let[e,s]=t.readStruct($s);if(s!==0)return c(s);let[n,i]=t.readVarBytes();if(i!==0)return c(i);let[o,r]=t.readVarBytes();if(r!==0)return c(r);return m({head:e,indexEnc:n,bodyEnc:o})}};var en={encode(t,e){t.writeBytes(e.kdm);let s=t.writeVarBytes(e.headCph);if(s!==0)return s;let n=t.writeVarInt(e.lenBody);if(n!==0)return n;if(e.lenBody>0&&e.offBody!==void 0){let i=t.writeVarInt(e.offBody);if(i!==0)return i}return 0},decode(t){let[e,s]=t.readBytes(Tt);if(s!==0)return c(s);let[n,i]=t.readVarBytes();if(i!==0)return c(i);let[o,r]=t.readVarInt();if(r!==0)return c(r);let l;if(o>0){let[a,d]=t.readVarInt();if(d!==0)return c(d);l=a}return m({kdm:e,headCph:n,lenBody:o,offBody:l})}};async function Wi(t,e,s,n,i){let o=await i.deriveIdentity(t,e),r=new P,l=new P,a=0,d=0;for(let I of s){let f=new P,V=f.writeStruct(ut,I.head);if(V!==0)return c(V);let G=f.result(),K=await o.kdmFor(G),H=i.deriveCipher(K,"encrypt"),L=await H.encrypt(G),T=I.body?await H.encrypt(I.body):new Uint8Array(0),C=I.head.len>0&&I.head.hsh!==void 0?T.length:0,U={kdm:K,headCph:L,lenBody:C,offBody:C>0?d:void 0},N=r.writeStruct(en,U);if(N!==0)return c(N);if(I.body)l.writeBytes(T),d+=T.length;a++}let u=l.result(),p=r.result(),h=await n.blake3(p),y=await o.sign(h),b={lbl:t,idx:e,num:a,hsh:h,sig:y},Z=new P;Z.writeStruct(tn,{head:b,indexEnc:p,bodyEnc:u});let X=Z.result();return m(X)}async function gi(t,e,s){let[n,i]=tn.decode(new M(t));if(i!==0)return c(i);let{head:o,indexEnc:r,bodyEnc:l}=n,a=await s.deriveIdentity(o.lbl,o.idx);if(!await e.checkSigEd25519(o.sig,o.hsh,a.publicKey))return c(3);let u=await e.blake3(r);if(!B(u,o.hsh))return c(19);let p=new M(r),h=[];for(let b=0;b<o.num;b++){let[Z,X]=p.readStruct(en);if(X!==0)return c(X);h.push(Z)}if(h.length!==o.num)return c(14);let y=[];for(let b of h){let Z=s.deriveCipher(b.kdm,"decrypt"),X;try{X=await Z.decrypt(b.headCph)}catch{return c(20)}let[I,f]=ut.decode(new M(X));if(f!==0)return c(f);let V;if(b.lenBody>0&&b.offBody!==void 0){if(I.hsh===void 0)return c(14);let G=l.slice(b.offBody,b.offBody+b.lenBody);try{V=await Z.decrypt(G)}catch{return c(20)}let K=await e.blake3(V);if(!B(K,I.hsh))return c(19)}y.push({head:I,body:V})}return m(y)}async function Ki({now:t,bod:e,crypto:s}){let n=await s.genRandomBytes(8),i=new P,o=i.writeStruct(A,{id:n,ts:t});if(o!==0)return c(o);let r=i.result();return $e({now:t,eid:r,ctr:0,bod:e,crypto:s})}async function $e({now:t,eid:e,ctr:s,bod:n,crypto:i}){let o=new M(e),[r,l]=A.decode(o);if(l!==0)return c(l);let a=t.getTime()-r.ts.getTime(),d,u=n?.length??0;if(n&&u>0)d=await i.blake3(n);return m({eid:e,off:a,ctr:s,len:u,hsh:d})}function xi(t,e){let s=t.length<e.length?t.length:e.length;for(let n=0;n<s;n++)if(t[n]!==e[n])return t[n]-e[n];return t.length-e.length}async function re(t,e){let s=Array.from(t);s.sort(xi);let n=0;for(let r of s)n+=r.length;let i=new Uint8Array(n),o=0;for(let r of s)i.set(r,o),o+=r.length;return e.blake3(i)}function Ri(t){let e=new P,s=e.writeVarBytes(t.eid);if(s!==0)return c(s);let n=e.writeDate(t.updatedAt);if(n!==0)return c(n);let i=e.writeVarInt(t.ctr);if(i!==0)return c(i);return m(e.result())}async function xe(t,e){let s=[];for(let n of t){let[i,o]=Ri(n);if(o!==0||!i)return c(o);s.push(i)}return m(await re(s,e))}var Zp=Symbol("MasterSeed"),Xp=Symbol("SealedMasterKey"),yt=32,sn=24+yt+16;function Re(t){if(t.byteLength!==yt)return c(10);return m(t)}function Pt(t){if(t.byteLength!==sn)return c(10);return m(t)}var fp=Symbol("EntityID");function Hi(t){return"type"in t}var Ip=Symbol("DerivationSeed"),Sp=Symbol("PublicKey"),Vp=Symbol("PrivateKey"),Wp=Symbol("HostSpecificKeyPair"),gp=Symbol("Hash");function Hr(t){if(!t)return!1;if(typeof t!=="object")return!1;if("body"in t===!1)return!1;if("type"in t===!1)return!1;return!0}function Yr(t){if(!t.bod||t.bod.length===0){let n={off:t.off,ctr:t.ctr,eid:t.eid};return m(n)}let e=zs(t.bod);if(Hr(e)===!1)return console.warn("msg body invalid",e),c(14);let s={off:t.off,ctr:t.ctr,eid:t.eid,gid:e.gid,pid:e.pid,tags:e.tags,type:e.type,body:e.body};return m(s)}class He{applier;emitter=new Ct;clearer;onDirtyEids;cacheDriven;peerIngest;constructor(t,e,s,n){this.applier=t;this.clearer=e,this.onDirtyEids=s,this.cacheDriven=n?.cacheDriven??!1,this.peerIngest=n?.peerIngest}apply=async(t)=>{let e=[],s=[];for(let l of t){let[a,d]=Yr(l);if(s.push(d),d!==0)continue;e.push(a)}let{stats:n,types:i,eids:o}=await this.applier(e),r=[];for(let l=0;l<t.length;l++){let a=s[l],d=n[l];if(a!==0){r.push(a);continue}if(d!==0){r.push(d);continue}r.push(0)}if(!this.cacheDriven)for(let l of i)this.emitter.emit(l,null);if(o.length>0)this.onDirtyEids?.(o);return r};clear=async()=>{let t=await this.clearer();if(t!==0)return t;return this.emitter.emitAll(null),t};notify=(t)=>{for(let e of t)this.emitter.emit(e,null)};refresh=async(t)=>{if(this.peerIngest){await this.peerIngest(t);return}};on=(t,e)=>{this.emitter.addEventListener(t,e)};off=(t,e)=>{this.emitter.removeEventListener(t,e)}}var nn={apply:async function(t){return t.map(()=>0)},clear:async function(){return 0},notify:function(t){},refresh:async function(t){},on:function(t,e){},off:function(t,e){}};var D="entities",ts="entity_type_created_at",rn="entity_type_updated_at",ln="entity_type_group_id",cn="entity_type_parent_id",le="entity_tags",Yi="db",Ci=13;function Cr(t){return"typ"in t}function kr(t){let e={bod:t.body,crd:t.createdAt,...t.ctr!==0?{ctr:t.ctr}:{},eid:R(t.eid),gid:t.gid,pid:t.pid?R(t.pid):void 0,tgs:t.tags,typ:t.type,upd:t.updatedAt};if(e.gid===void 0)delete e.gid;if(e.pid===void 0)delete e.pid;if(e.tgs===void 0)delete e.tgs;if(e.ctr===void 0)delete e.ctr;return e}function Tr(t){if(!E(t))return{eid:R(t.eid),upd:t.updatedAt,...t.ctr!==0?{ctr:t.ctr}:{}};return kr(t)}function ce(t){return{body:t.bod,createdAt:t.crd,updatedAt:t.upd,ctr:t.ctr??0,type:t.typ,eid:tt(t.eid),gid:t.gid,pid:t.pid?tt(t.pid):void 0,...t.tgs!==void 0?{tags:t.tgs}:{}}}function on(t){if(Cr(t))return ce(t);return{eid:tt(t.eid),updatedAt:t.upd,ctr:t.ctr??0}}class an{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=Mr().then((t)=>(t.onversionchange=()=>{if(t.close(),this.db===t)this.db=void 0},this.db=t,this.opening=void 0,t),(t)=>{throw this.opening=void 0,t}),this.opening}apply=async(t)=>{let e=new Set,s=[],n;try{n=await this.ensureDb()}catch{return{stats:t.map(()=>16),types:e,eids:s}}let i=n.transaction(D,"readwrite"),o=i.objectStore(D);return new Promise((r)=>{let l=Array(t.length).fill(0);if(t.length<1){r({stats:[],types:e,eids:s});return}i.oncomplete=()=>{r({stats:l,types:e,eids:s})},i.onerror=()=>{for(let d=0;d<l.length;d++)if(l[d]===void 0)l[d]=18;r({stats:l,types:e,eids:s})};let a=new Map;for(let d=0;d<t.length;d++){let u=t[d],p=R(u.eid),h={op:u,index:d},y=a.get(p);if(y)y.push(h);else a.set(p,[h])}for(let[d,u]of a){if(u.length<1)continue;let p=o.get(d);p.onsuccess=()=>{let h=p.result,y=h?on(h):void 0,b=!1;for(let{op:Z,index:X}of u){let[I,f]=ae(y,Z);if(f!==0){l[X]=f;continue}if(I===void 0){l[X]=12;continue}b=!0;for(let V of de(y,I))e.add(V);y=I}if(b)s.push(u[0].op.eid);if(y){let Z=o.put(Tr(y));Z.onerror=(X)=>{X.preventDefault();for(let{index:I}of u)l[I]=18}}},p.onerror=()=>{for(let{index:h}of u)l[h]=18}}})};async clear(){let t;try{t=await this.ensureDb()}catch{return 16}let e=t.transaction(D,"readwrite"),s=e.objectStore(D);return new Promise((n)=>{e.oncomplete=()=>n(0),e.onerror=()=>n(18),s.clear()})}async getRow(t){let e;try{e=await this.ensureDb()}catch{return c(16)}let s=R(t),i=e.transaction(D,"readonly").objectStore(D);return new Promise((o)=>{let r=i.get(s);r.onsuccess=()=>{let l=r.result;if(!l)o(m(void 0));else o(m(on(l)))},r.onerror=()=>o(c(18))})}async getEnt(t){let[e,s]=await this.getRow(t);if(s!==0)return c(s);if(e===void 0||!E(e))return m(void 0);return m(e)}async getAllOfTypeUpdatedBetween(t,e,s){let n;try{n=await this.ensureDb()}catch{return c(16)}let o=n.transaction(D,"readonly").objectStore(D).index(rn);return new Promise((r)=>{let l=o.getAll(IDBKeyRange.bound([t,e],[t,s]));l.onsuccess=()=>{let a=l.result;r(m(a.map(ce)))},l.onerror=()=>r(c(18))})}async getGroupMembers(t,e){let s;try{s=await this.ensureDb()}catch{return c(16)}let i=s.transaction(D,"readonly").objectStore(D).index(ln);return new Promise((o)=>{let r=i.getAll(IDBKeyRange.only([t,e]));r.onsuccess=()=>{let l=r.result;o(m(l.map(ce)))},r.onerror=()=>o(c(18))})}async getAllOfType(t){let e;try{e=await this.ensureDb()}catch{return c(16)}let n=e.transaction(D,"readonly").objectStore(D).index(ts);return new Promise((i)=>{let o=n.getAll(IDBKeyRange.bound([t],[t,[]]));o.onsuccess=()=>{let r=o.result;i(m(r.map(ce)))},o.onerror=()=>i(c(18))})}async getByTag(t,e){let s;try{s=await this.ensureDb()}catch{return c(16)}let i=s.transaction(D,"readonly").objectStore(D).index(le);return new Promise((o)=>{let r=i.getAll(IDBKeyRange.only(e));r.onsuccess=()=>{let a=r.result.filter((d)=>d.typ===t).map(ce);o(m(a))},r.onerror=()=>o(c(18))})}async getAllEntities(t){if("pid"in t){let e;try{e=await this.ensureDb()}catch{return c(16)}let s=R(t.pid),i=e.transaction(D,"readonly").objectStore(D).index(cn);return new Promise((o)=>{let r=i.getAll(IDBKeyRange.only([t.type,s]));r.onsuccess=()=>{let a=r.result.map(ce);o(m(a))},r.onerror=()=>o(c(18))})}else if("gid"in t)return await this.getGroupMembers(t.type,t.gid);else if("tag"in t)return await this.getByTag(t.type,t.tag);else if("updatedBetween"in t)return await this.getAllOfTypeUpdatedBetween(t.type,t.updatedBetween.start,t.updatedBetween.end);return await this.getAllOfType(t.type)}async getEntities(t){let[e,s]=await this.getAllEntities(t);if(s!==0)return c(s);return m(e)}async countEntities({type:t}){let e;try{e=await this.ensureDb()}catch{return c(16)}let n=e.transaction(D,"readonly").objectStore(D).index(ts);return new Promise((i)=>{let o=IDBKeyRange.bound([t],[t,[]]),r=n.count(o);r.onsuccess=()=>i(m(r.result)),r.onerror=()=>i(c(18))})}async checksum(t){let e;try{e=await this.ensureDb()}catch{return c(16)}let n=e.transaction(D,"readonly").objectStore(D),i=[];return new Promise((o)=>{let r=n.openCursor();r.onsuccess=()=>{let l=r.result;if(l){let a=l.value;i.push(Ye(on(a))),l.continue()}else xe(i,t).then(o)},r.onerror=()=>o(c(18))})}}function Lr(t,e){if(!t.objectStoreNames.contains(D))t.createObjectStore(D,{keyPath:"eid",autoIncrement:!1});let s=e.objectStore(D);if(!s.indexNames.contains(ts))s.createIndex(ts,["typ","crd"],{unique:!1});if(!s.indexNames.contains(rn))s.createIndex(rn,["typ","upd"],{unique:!1});if(!s.indexNames.contains(ln))s.createIndex(ln,["typ","gid"],{unique:!1});if(!s.indexNames.contains(cn))s.createIndex(cn,["typ","pid"],{unique:!1});if(s.indexNames.contains(le)){if(s.index(le).keyPath!=="tgs")s.deleteIndex(le)}if(!s.indexNames.contains(le))s.createIndex(le,"tgs",{unique:!1,multiEntry:!0})}function Mr(){return new Promise((t,e)=>{let s=indexedDB.open(Yi,Ci);s.onupgradeneeded=()=>{let{result:n,transaction:i}=s;if(!i){e(Error("Transaction is null during EntDB upgrade"));return}try{Lr(n,i)}catch(o){e(o instanceof Error?o:Error(String(o)))}},s.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Yi} → v${Ci}); waiting for other connections to close`)},s.onsuccess=()=>t(s.result),s.onerror=()=>e(s.error??Error("EntDB IndexedDB open failed"))})}async function ki(){let t=new an;return await t.init(),t}class es{ents=new Map;useIndex;byType=new Map;byTypePid=new Map;byTypeGid=new Map;byTypeTag=new Map;constructor(t=[],e){this.useIndex=e?.indexes!==!1;for(let s of t)this.put(s)}put(t){let e=R(t.eid),s=this.ents.get(e);if(s!==void 0&&E(s))this.unindex(e,s);if(this.ents.set(e,t),E(t))this.index(e,t)}del(t){let e=this.ents.get(t);if(e===void 0)return;if(E(e))this.unindex(t,e);this.ents.delete(t)}index(t,e){if(!this.useIndex)return;let s=this.byType.get(e.type);if(!s)s=new Map,this.byType.set(e.type,s);if(s.set(t,e),e.pid){let n=R(e.pid),i=this.byTypePid.get(e.type);if(!i)i=new Map,this.byTypePid.set(e.type,i);let o=i.get(n);if(!o)o=new Map,i.set(n,o);o.set(t,e)}if(typeof e.gid==="string"){let n=this.byTypeGid.get(e.type);if(!n)n=new Map,this.byTypeGid.set(e.type,n);let i=n.get(e.gid);if(!i)i=new Map,n.set(e.gid,i);i.set(t,e)}if(e.tags){let n=this.byTypeTag.get(e.type);if(!n)n=new Map,this.byTypeTag.set(e.type,n);for(let i of e.tags){let o=n.get(i);if(!o)o=new Map,n.set(i,o);o.set(t,e)}}}unindex(t,e){if(!this.useIndex)return;let s=this.byType.get(e.type);if(s){if(s.delete(t),s.size===0)this.byType.delete(e.type)}if(e.pid){let n=R(e.pid),i=this.byTypePid.get(e.type),o=i?.get(n);if(o){if(o.delete(t),o.size===0)i?.delete(n)}if(i&&i.size===0)this.byTypePid.delete(e.type)}if(typeof e.gid==="string"){let n=this.byTypeGid.get(e.type),i=n?.get(e.gid);if(i){if(i.delete(t),i.size===0)n?.delete(e.gid)}if(n&&n.size===0)this.byTypeGid.delete(e.type)}if(e.tags){let n=this.byTypeTag.get(e.type);if(n){for(let i of e.tags){let o=n.get(i);if(o){if(o.delete(t),o.size===0)n.delete(i)}}if(n.size===0)this.byTypeTag.delete(e.type)}}}clearIndexes(){this.byType.clear(),this.byTypePid.clear(),this.byTypeGid.clear(),this.byTypeTag.clear()}bucketList(t){if(!t||t.size===0)return[];let e=[];for(let s of t.values())e.push(s);return e}async apply(t){let e=new Set,s=[],n=[];for(let i of t){let o=R(i.eid),r=this.ents.get(o),[l,a]=ae(r,i);if(a!==0){n.push(a);continue}if(l===void 0){n.push(12);continue}for(let d of de(r,l))e.add(d);this.put(l),s.push(i.eid),n.push(0)}return{stats:n,types:e,eids:s}}async clear(){return this.ents.clear(),this.clearIndexes(),0}async getRow(t){let e=R(t),s=this.ents.get(e);return m(s)}async getEnt(t){let[e,s]=await this.getRow(t);if(s!==0)return c(s);if(e===void 0||!E(e))return m(void 0);return m(e)}async getAllEntities({type:t,gid:e,pid:s,tag:n,updatedBetween:i}){if(this.useIndex){if(s!==void 0){let r=R(s);return m(this.bucketList(this.byTypePid.get(t)?.get(r)))}if(e!==void 0)return m(this.bucketList(this.byTypeGid.get(t)?.get(e)));if(n!==void 0)return m(this.bucketList(this.byTypeTag.get(t)?.get(n)));if(i!==void 0){let r=[],l=this.byType.get(t);if(l){for(let a of l.values())if(a.updatedAt>=i.start&&a.updatedAt<=i.end)r.push(a)}return m(r)}return m(this.bucketList(this.byType.get(t)))}let o=[];if(s!==void 0){for(let r of this.ents.values())if(E(r)&&r.type===t&&r.pid&&B(r.pid,s))o.push(r)}else if(e!==void 0){for(let r of this.ents.values())if(E(r)&&r.type===t&&(typeof r.gid==="string"&&r.gid===e))o.push(r)}else if(n!==void 0){for(let r of this.ents.values())if(E(r)&&r.type===t&&r.tags&&r.tags.includes(n))o.push(r)}else if(i!==void 0){for(let r of this.ents.values())if(E(r)&&r.type===t&&r.updatedAt>=i.start&&r.updatedAt<=i.end)o.push(r)}else for(let r of this.ents.values())if(E(r)&&r.type===t)o.push(r);return m(o)}async getEntities(t){let[e,s]=await this.getAllEntities(t);if(s!==0)return c(s);return m(e)}async countEntities({type:t}){if(this.useIndex)return m(this.byType.get(t)?.size??0);let e=0;for(let s of this.ents.values())if(E(s)&&s.type===t)e+=1;return m(e)}async checksum(t){let e=[];for(let s of this.ents.values())e.push(Ye(s));return xe(e,t)}}async function dn(t){let e=await ki();if(t?.cache===!1)return e;return new Ce(e,void 0,{indexes:t?.indexes})}class Ce{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(t,e,s){if(this.durable=t,this.mem=new es(e??[],{indexes:s?.indexes}),e)for(let n of e)this.warmed.add(n.type)}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}emit(t){if(t.size<1)return;for(let e of this.listeners)e(t)}run(t){let e=this.chain.then(t,t);return this.chain=e.then(()=>{return},()=>{return}),e}apply(t){return this.run(async()=>{await this.pullEids(t.map((o)=>o.eid));let e=Nr(this.mem,t);this.emit(e.types);let s=await this.durable.apply(t),{changed:n,status:i}=await this.pullEids(t.map((o)=>o.eid));if(this.emit(n),i!==0)return{stats:t.map(()=>i),types:s.types,eids:s.eids};return s})}clear(){return this.run(async()=>{let t=await this.durable.clear();if(t!==0)return t;let e=this.mem.ents.size>0;return await this.mem.clear(),this.warmed.clear(),0})}ingestFromDurable(t){return this.run(async()=>{let{changed:e,status:s}=await this.pullEids(t);return this.emit(e),s})}async pullEids(t){let e=new Set,s=new Set;for(let n of t){let i=R(n);if(s.has(i))continue;s.add(i);let o=this.mem.ents.get(i),[r,l]=await this.durable.getRow(n);if(l!==0)return{changed:e,status:l};if(r){if(this.mem.put(r),!o||!Pr(o,r)){if(E(r))e.add(r.type);if(o!==void 0&&E(o))e.add(o.type)}}else if(o!==void 0){if(this.mem.del(i),E(o))e.add(o.type)}}return{changed:e,status:0}}async warmType(t){if(this.warmed.has(t))return 0;let[e,s]=await this.durable.getEntities({type:t});if(s!==0)return s;if(e)for(let n of e){let i=R(n.eid),o=this.mem.ents.get(i);if(!o||Jr(n,o))this.mem.put(n)}return this.warmed.add(t),0}async getRow(t){let e=R(t);if(this.mem.ents.has(e))return this.mem.getRow(t);return this.run(async()=>{if(this.mem.ents.has(e))return this.mem.getRow(t);let[s,n]=await this.durable.getRow(t);if(n!==0)return c(n);if(s)this.mem.put(s);return m(s)})}async getEnt(t){let[e,s]=await this.getRow(t);if(s!==0)return c(s);if(e===void 0||!E(e))return m(void 0);return m(e)}async getEntities(t){if(!this.warmed.has(t.type)){let e=await this.run(()=>this.warmType(t.type));if(e!==0)return c(e)}return this.mem.getEntities(t)}async countEntities({type:t}){if(!this.warmed.has(t)){let e=await this.run(()=>this.warmType(t));if(e!==0)return c(e)}return this.mem.countEntities({type:t})}async checksum(t){return this.durable.checksum(t)}}function Pr(t,e){if(E(t)!==E(e))return!1;if(t.ctr!==e.ctr)return!1;if(t.updatedAt.getTime()!==e.updatedAt.getTime())return!1;if(!B(t.eid,e.eid))return!1;if(!E(t)||!E(e))return!0;if(t.createdAt.getTime()!==e.createdAt.getTime())return!1;if(t.type!==e.type)return!1;if(t.gid!==e.gid)return!1;if(!Ur(t.pid,e.pid))return!1;if(!wr(t.tags,e.tags))return!1;return Br(t.body,e.body)}function wr(t,e){if(t===e)return!0;if(t===void 0||e===void 0)return!1;if(t.length!==e.length)return!1;for(let s=0;s<t.length;s++)if(t[s]!==e[s])return!1;return!0}function Ur(t,e){if(t===void 0&&e===void 0)return!0;if(t===void 0||e===void 0)return!1;return B(t,e)}function Br(t,e){if(Object.is(t,e))return!0;if(t instanceof Uint8Array&&e instanceof Uint8Array)return B(t,e);if(t instanceof Date&&e instanceof Date)return t.getTime()===e.getTime();try{return B(Nt(t),Nt(e))}catch{return!1}}function Jr(t,e){let s=t.updatedAt.getTime(),n=e.updatedAt.getTime();if(s!==n)return s>n;return t.ctr>e.ctr}function Nr(t,e){let s=new Set,n=[];for(let i of e){let o=R(i.eid),r=t.ents.get(o),[l,a]=ae(r,i);if(a!==0){n.push(a);continue}if(l===void 0){n.push(12);continue}for(let d of de(r,l))s.add(d);t.put(l),n.push(0)}return{stats:n,types:s}}function ss(t){if(t instanceof Ce){let e=new He((s)=>t.apply(s),()=>t.clear(),void 0,{cacheDriven:!0,peerIngest:async(s)=>{await t.ingestFromDurable(s)}});return t.subscribe((s)=>e.notify(s)),e}return new He((e)=>t.apply(e),()=>t.clear())}function E(t){return"type"in t}function zr(t){return!E(t)}function Ti(t){if(!Array.isArray(t)||t.length===0)return;let e=new Set,s=[];for(let n of t){if(typeof n!=="string"||n.length===0)continue;if(e.has(n))continue;e.add(n),s.push(n)}return s.length>0?s:void 0}function Ye(t){return{eid:t.eid,ctr:t.ctr,updatedAt:t.updatedAt}}function un(t){let e=new M(t.eid),[s,n]=e.readStruct(A);if(n!==0)return c(n);return m({eid:t.eid,ctr:t.ctr,updatedAt:new Date(s.ts.getTime()+t.off)})}function ae(t,e){let s=new M(e.eid),[n,i]=s.readStruct(A);if(i!==0)return c(i);let o=new Date(n.ts.getTime()+e.off);if(t!==void 0&&o<=t.updatedAt)return c(15);if(Hi(e)){let r=Ti(e.tags);return m({eid:e.eid,gid:e.gid,pid:e.pid,...r!==void 0?{tags:r}:{},type:e.type,createdAt:n.ts,updatedAt:o,ctr:e.ctr,body:e.body})}return m({eid:e.eid,updatedAt:o,ctr:e.ctr})}function de(t,e){let s=new Set;if(t!==void 0&&E(t))s.add(t.type);if(E(e))s.add(e.type);return[...s]}var Er={getEnt:async()=>c(21),getRow:async()=>c(21),getEntities:async(t)=>c(21),countEntities:async()=>c(21),checksum:async()=>c(21),apply:async(t)=>({stats:t.map(()=>21),types:new Set,eids:[]}),clear:async()=>21};class ns{inflight=null;again=!1;run(t){if(this.again=!0,this.inflight)return this.inflight;return this.inflight=this.drain(t),this.inflight}async flush(){if(!this.inflight)return;try{await this.inflight}catch{}}async drain(t){try{this.again=!1;let e=await t();while(this.again)this.again=!1,e=await t();return e}finally{this.inflight=null}}}var is=100;class ke{timer=null;delayMs;work;tail=new ns;constructor(t,e){this.delayMs=t<0?0:t,this.work=e}schedule(){if(this.delayMs<=0){this.fire();return}if(this.timer!==null)clearTimeout(this.timer);this.timer=setTimeout(()=>{this.timer=null,this.fire()},this.delayMs)}async flush(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null,this.fire();await this.tail.flush()}cancel(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null}fire(){return this.tail.run(this.work)}}function Li(t){let e=new M(t.eid),[s,n]=A.decode(e);if(n!==0)return;return s.ts.getTime()+t.off}function Fr(t,e){let s=Li(t),n=Li(e);if(s===void 0&&n===void 0)return 0;if(s===void 0)return 1;if(n===void 0)return-1;if(n!==s)return n-s;return e.ctr-t.ctr}function ue(t,e){return t.slice().sort((s,n)=>Fr(e(s),e(n)))}var zt={phase:"idle"},pe=50;function os(t,e,s){if(t<=0||e<=0)return!1;if(t===1||t===e)return!0;return t%s===0}function rs(t,e){if(typeof navigator.msSaveOrOpenBlob==="function"){navigator.msSaveOrOpenBlob(t,e);return}let s=URL.createObjectURL(t),n=document.createElement("a");n.href=s,n.download=e,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(s)}function Mi(t,e,s){let n=[],i=[],o=0;for(let r of t){let l=e(r);if(i.length>0&&o+l>s)n.push(i),i=[],o=0;if(i.push(r),o+=l,o>=s)n.push(i),i=[],o=0}if(i.length>0)n.push(i);return n}async function pn(t,e,s){let n=t.length;if(n<1)return[];let i=Array(n),o=0,r=Math.min(Math.max(1,e),n),l=async()=>{while(!0){let d=o;if(o+=1,d>=n)return;i[d]=await s(t[d],d)}},a=[];for(let d=0;d<r;d++)a.push(l());return await Promise.all(a),i}async function ls(t,e,s,n){let i=new M(t.headCph),[o,r]=i.readStruct(Ae);if(r!==0)return c(r);let{sig:l,kdm:a,headCph:d}=o;if(!await n.checkSigEd25519(l,d,e))return c(3);let p=s.deriveCipher(a,"decrypt"),h;try{h=await p.decrypt(d)}catch{return c(20)}return m({kdm:a,headEnc:h})}var Vt="f",wt="t",Zt="e";function Qr(t){return t===Vt||t===wt||t===Zt}function me(t){if(t===!0||t===wt)return wt;if(t===Zt)return Zt;return Vt}function vr(t){return me(t.apld)===Vt}function mn(t){return t!==0&&t!==15&&t!==18&&t!==17}function Et(t,e,s){if(t.apld=e,e===Zt&&s!==void 0)t.err=s;else delete t.err}async function Ut(t,e,s,n){let i=n?.body!==!1,o=me(e.apld),r=e.body,l=r?.length??0,a;if(i&&r&&l>0)a=await s.blake3(r);let d={eid:e.eid,off:e.off??0,ctr:e.ctr??0,len:l,hsh:a},u={hash:t,head:d,apld:o};if(i&&r!==void 0)u.body=r;if(o===Zt&&e.err!==void 0)u.err=e.err;return u}var hn=1048576,yn=1048576,wi=64;function Dr(t){return t.sig.length+t.kdm.length+t.headCph.length+t.bodyCph.length}async function Or(t,e,s,n,i){if(n.length<1)return 0;let[o,r]=await t.push(n);if(r!==0)return r;if(!o)return 27;for(let a of o){if(a.status!==0){console.error("push err",a);continue}let d=i[a.idx];if(!d){console.error("no hash",a);continue}await e.uploads.deq(s,[d])}let l=await e.hosts.get(s);if(l){let a=l.lastSeq,d=a,u=[];for(let p of o)if(p.status===0)u.push(p.seq);u.sort((p,h)=>p-h);for(let p of u)if(p===a+1)a=p;if(a>d)await e.hosts.touch(s,a)}return 0}async function Pi(t,e){if(e.length<1)return m([]);let s=new Map,n=[];for(let l of e)s.set(l.seq,l),n.push(l.seq);let[i,o]=await t.pull(n);if(o!==0)return c(o);if(!i)return c(27);let r=[];for(let{seq:l,bodyCph:a}of i){let d=s.get(l);if(!d)continue;r.push({dl:d,bodyCph:a})}return m(r)}async function jr(t,e,s,n){if(n.length<1)return m({parts:[],hashes:[]});let i=[],o=[],r=[],l=new Map;for(let{dl:d,bodyCph:u}of n){let{head:p,kdm:h,seq:y,host:b}=d,[Z,X]=await Ui(d,s);if(X!==0||!Z){let C=l.get(b)??[];C.push(y),l.set(b,C);continue}let{headEnc:I,headEncHash:f}=Z,V=e.deriveCipher(h,"decrypt"),[G,K]=await Qs(I,u,V,s,f);if(K!==0||!G){let C=l.get(b)??[];C.push(y),l.set(b,C);continue}let H={head:p,body:G.bod},L=G.headHash;r.push({key:L,data:Ni(H)}),i.push(H),o.push(L);let T=l.get(b)??[];T.push(y),l.set(b,T)}let a=await t.messages.add(r);for(let[d,u]of l)await t.downloads.deq(d,u);for(let d=0;d<a.length;d++){let u=a[d];if(u!==0&&u!==15)console.error("ERR storing",W[u],"for message",d)}return m({parts:i,hashes:o})}async function Ui(t,e){let s=t.headEnc;if(!s){let i=new P,o=i.writeStruct(ut,t.head);if(o!==0)return c(o);s=i.result()}if(t.headEncHash)return m({headEnc:s,headEncHash:t.headEncHash});let n=await e.blake3(s);return m({headEnc:s,headEncHash:n})}async function Bi(t,e,s){let n=new Set;for(let r of e)n.add(R(r));if(n.size<1)return;let i=Array.from(await t.downloads.list());if(i.length<1)return;let o=new Map;for(let r of i){let l;if(r.headEncHash)l=R(r.headEncHash);else{let[d,u]=await Ui(r,s);if(u!==0||!d)continue;l=R(d.headEncHash)}if(!n.has(l))continue;let a=o.get(r.host)??[];a.push(r.seq),o.set(r.host,a)}for(let[r,l]of o)await t.downloads.deq(r,l)}async function bn({conn:t,store:e,enclave:s,host:n,crypto:i,onProgress:o,peekProgressEvery:r,peekConcurrency:l}){let a=await t.identity(),d=[],[u,p]=await t.peek(n.lastSeq);if(p!==0)return p;let h=u.length,y=r??pe,b=l??wi;if(o&&h>0)o({phase:"peek",host:n.label,done:0,total:h});let Z=0,X=await pn(u,b,async(f)=>{let[V,G]=await ls(f,a.publicKey,s,i),K;if(G!==0||!V)K={ok:!1,seq:f.seq,stat:G};else{let H=await i.blake3(V.headEnc);K={ok:!0,seq:f.seq,kdm:V.kdm,headEnc:V.headEnc,headEncHash:H}}if(Z+=1,o&&os(Z,h,y))o({phase:"peek",host:n.label,done:Z,total:h});return K}),I=new Set;for(let f of X){if(!f.ok){console.error("peek: decrypting item head",f.stat);continue}let V=R(f.headEncHash);if(await e.messages.has(f.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await e.uploads.deq(n.label,[f.headEncHash]),await e.downloads.deq(n.label,[f.seq]);continue}if(I.has(V)){await e.downloads.deq(n.label,[f.seq]);continue}let K=new M(f.headEnc),[H,L]=K.readStruct(ut);if(L!==0){console.error("peek: reading item head",L);continue}I.add(V),d.push({kdm:f.kdm,head:H,seq:f.seq,host:n.label,headEnc:f.headEnc,headEncHash:f.headEncHash})}if(await e.downloads.enq(d),u.length>0){let f=Math.max(...u.map((V)=>V.seq));await e.hosts.recordStats(n.label,{lastSeq:f})}if(o)o({phase:"peek",host:n.label,done:h,total:h});return 0}async function Ji({conn:t,store:e,host:s,maxPushBytes:n,onProgress:i}){let o=n??hn,r=await e.uploads.list(s.label),l=r.length,a=0;if(i&&l>0)i({phase:"push",host:s.label,done:0,total:l});let d=[],u=[],p=0,h=async()=>{if(d.length<1)return 0;let y=d.length,b=await Or(t,e,s.label,d,u);if(d=[],u=[],p=0,b===0){if(a+=y,i)i({phase:"push",host:s.label,done:a,total:l})}return b};for(let y of r){let b=await e.messages.get(y);if(!b){a+=1;continue}let Z={...b.head,bod:b.body},[X,I]=await t.seal(Z);if(I!==0)return I;if(!X)return 12;let f=Dr(X);if(d.length>0&&p+f>o){let V=await h();if(V!==0)return V}if(d.push(X),u.push(y),p+=f,p>=o){let V=await h();if(V!==0)return V}}return h()}async function Zn({conn:t,store:e,enclave:s,host:n,crypto:i,maxPullBytes:o,onProgress:r},l){let a=o??yn,d=await e.downloads.list(),u=Array.from(d).filter((X)=>X.host===n.label);if(u.length<1)return 15;let p=ue(u,(X)=>X.head),h=Mi(p,(X)=>X.head.len,a),y=p.length,b=0;if(r)r({phase:"pull",host:n.label,done:0,total:y});let Z=Pi(t,h[0]);for(let X=0;X<h.length;X++){let[I,f]=await Z;if(f!==0||!I)return f;if(b+=h[X].length,r)r({phase:"pull",host:n.label,done:b,total:y});let V=h[X+1];if(V)Z=Pi(t,V);if(r)r({phase:"open",host:n.label,done:b,total:y});let G=ue(I,(H)=>H.dl.head),[,K]=await jr(e,s,i,G);if(K!==0)return K;if(l){if(r)r({phase:"exec",host:n.label,done:b,total:y});await l()}}return 0}function Ni({head:t,body:e}){let s={eid:t.eid,body:e,apld:Vt};if(t.off!==0)s.off=t.off;if(t.ctr!==0)s.ctr=t.ctr;return s}async function zi(t,{conn:e,store:s,enclave:n,host:i,crypto:o,onProgress:r},l){let a=i.label,d=await e.identity(),u=new M(t),[p,h]=u.readStructs(je);if(h!==0){console.error("Failed decoding notif",W[h]);return}let y=!1,Z=(await s.hosts.get(a))?.lastSeq,X=[],I=!1;for(let G of p){let[K,H]=await ls({seq:G.seq,headCph:G.headCph},d.publicKey,n,o);if(H!==0){console.error("Failed decrypting notif",W[H]);continue}let L=await o.blake3(K.headEnc);if(await s.messages.has(L))continue;let T=new M(K.headEnc),[C,U]=T.readStruct(ut);if(U!==0){console.error("Failed to parse head",W[U]);continue}if(!G.bodyCph&&C.len>0)I=!0,await s.downloads.enq([{seq:G.seq,host:a,kdm:K.kdm,head:C,headEnc:K.headEnc,headEncHash:L}]);else X.push({...K,head:C,bodyCph:G.bodyCph,headEncHash:L});if(Z===void 0||G.seq!==Z+1)console.log("out of seq",G.seq,Z),y=!0;else Z=G.seq}if(Z!==void 0)await s.hosts.touch(i.label,Z);let f=[];for(let G of X){let K=n.deriveCipher(G.kdm,"decrypt"),[H,L]=await Qs(G.headEnc,G.bodyCph,K,o);if(L!==0){console.error("Failed to open body",W[L]);continue}f.push({key:G.headEncHash,data:Ni({head:G.head,body:H.bod})})}let V=await s.messages.add(f);for(let G=0;G<V.length;G++){let K=V[G];if(K!==0&&K!==15)console.error("ERR storing",W[K],"for message",G)}if(r&&f.length>0)r({phase:"open",host:i.label,done:f.length,total:f.length});if(y||I||f.length>0)l()}async function Xn(t,e={}){let s=e.pull!==!1,n=e.push===!0,{conn:i,store:o,enclave:r,host:l,crypto:a,onProgress:d,peekProgressEvery:u,peekConcurrency:p}=t,h=await i.identity(),[y,b]=await i.peek(0);if(b!==0)return c(b);let Z=y.length,X=u??pe,I=p??wi;if(d&&Z>0)d({phase:"peek",host:l.label,done:0,total:Z});let f=0,V=await pn(y,I,async(Y)=>{let[w,k]=await ls(Y,h.publicKey,r,a),z;if(k!==0||!w)z={ok:!1,seq:Y.seq,stat:k};else{let x=await a.blake3(w.headEnc);z={ok:!0,seq:Y.seq,kdm:w.kdm,headEnc:w.headEnc,headEncHash:x}}if(f+=1,d&&os(f,Z,X))d({phase:"peek",host:l.label,done:f,total:Z});return z}),G=new Map;for(let Y of V){if(!Y.ok)continue;let w=R(Y.headEncHash),k=G.get(w);if(k)k.count+=1;else G.set(w,{hash:Y.headEncHash,count:1,sample:Y})}let K=0,H=[];for(let Y of G.values()){if(Y.count>1)K+=Y.count-1;H.push(Y.hash)}let L=y.length,T=G.size,C=await re(H,a),U=[],N=0;for(let Y of G.values()){if(await o.messages.has(Y.hash)){await o.uploads.deq(l.label,[Y.hash]);continue}if(N+=1,!s)continue;let k=Y.sample,z=new M(k.headEnc),[x,O]=z.readStruct(ut);if(O!==0){console.error("reconcile: reading msg header",O);continue}U.push({kdm:k.kdm,head:x,seq:k.seq,host:l.label,headEnc:k.headEnc,headEncHash:k.headEncHash})}if(U.length>0)await o.downloads.enq(U);let F=0;if(n){let Y=await o.messages.listKeys(),w=new Set(G.keys()),k=[];for(let z of Y)if(!w.has(R(z)))F+=1,k.push(z);if(k.length>0)await o.uploads.enq(l.label,k)}else{let Y=await o.messages.listKeys(),w=new Set(G.keys());for(let k of Y)if(!w.has(R(k)))F+=1}let S=y.length>0?Math.max(...y.map((Y)=>Y.seq)):0;if(await o.hosts.recordStats(l.label,{setLastSeq:S}),d)d({phase:"peek",host:l.label,done:Z,total:Z});return m({msgcheck:C,numBags:L,uniqueMsgs:T,numDupes:K,missingLocal:N,missingHost:F})}class he{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new ns;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=pe;lastProgress=zt;scheduledSync;constructor(t,e,s,n,i,o=!0,r=hn,l=yn,a){this.clock=t;this.state=e;this.store=s;this.transport=n;this.crypto=i;this.forceSkewHandlingByDefault=o;this.onScheduleSync=a;this.maxPushBytes=r,this.maxPullBytes=l,this.clientState=new bt(()=>this.getClientState()),this.xferState=new bt(()=>this.getXferState()),this.scheduledSync=new ke(is,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(d){console.error("Debounced sync failed:",d)}})}emitProgress=(t)=>{this.lastProgress=t,this.xferState.emit()};async setSeed(t,e){await this.store.seed.save(t,e),this.clientState.emit()}async getClientState(){let{store:t,connections:e}=this,s=await t.seed.load(),n=await t.hosts.list(),i=!1;for(let o of e.values())if(o.isConnected()){i=!0;break}return{hasSeed:s!==void 0,hasHost:Array.from(n).length>0,connected:i}}async getXferState(){let{uploads:t,downloads:e}=this.store,s=await t.count();return{numDownloads:await e.count(),numUploads:s,progress:this.lastProgress}}apply=(t,e)=>this.enqueueApplyJob(()=>this.doApply(t,e));async doApply(t,e={enqueueUpload:!0,triggerUpload:!0}){let s=[],n=[];for(let{head:o,body:r}of t){let l=new P;l.writeStruct(ut,o);let a=l.result(),d=await this.crypto.blake3(a),u={eid:o.eid,body:r,apld:Vt};if(o.off!==0)u.off=o.off;if(o.ctr!==0)u.ctr=o.ctr;s.push(d),n.push({key:d,data:u})}await this.store.messages.add(n),await Bi(this.store,s,this.crypto);let i=await this.doApplyHashes(s);if(e.enqueueUpload){let o=[];for(let r=0;r<s.length;r++){let l=i[r];if(l===0||l===15)o.push(s[r])}if(o.length>0){let r=await this.store.hosts.list();for(let l of r)await this.store.uploads.enq(l.label,o);this.xferState.emit()}}if(e.triggerUpload)this.scheduleSync();return i}enqueueApplyJob(t){let e=this.applyChain.then(t,t);return this.applyChain=e.then(()=>{return},()=>{return}),e}drainApplyQueue(){return this.enqueueApplyJob(()=>this.doDrainApplyQueue())}async doDrainApplyQueue(){let t=await this.store.messages.list({apld:Vt});if(t.length<1)return[];let e=ue(t,(s)=>s.head);return this.applyStored(e)}applyHashes=(t)=>this.enqueueApplyJob(()=>this.doApplyHashes(t));async doApplyHashes(t){let e=[];for(let i of t){let o=await this.store.messages.get(i);if(o)e.push(o)}let s=await this.applyStored(e),n=new Map;for(let i=0;i<e.length;i++)n.set(R(e[i].hash),s[i]??12);return t.map((i)=>n.get(R(i))??13)}async applyStored(t){if(t.length<1)return[];let e=t.map((o)=>({...o.head,bod:o.body})),s=await this.state.apply(e),n=[],i=[];for(let o=0;o<t.length;o++){let r=s[o];if(r===0||r===15)n.push(t[o].hash);else if(r!==void 0&&mn(r))i.push({key:t[o].hash,err:r})}if(n.length>0)await this.store.messages.markApplied(n);if(i.length>0)await this.store.messages.markFailed(i);return s}async insertRaw(t){let{clock:e,crypto:s}=this,[n,i]=await Ki({now:e.now(),bod:t,crypto:s});if(i!==0)return c(i);let r=(await this.apply([{head:n,body:t}]))[0];if(r!==0&&r!==15)return c(r??12);return m(n)}async makeUpdate(t,e){let{clock:s,crypto:n}=this,i=s.now();if(t.updatedAt.getTime()>i.getTime())return c(4);let o=t.ctr+1,[r,l]=await $e({now:i,eid:t.eid,ctr:o,bod:e,crypto:n});if(l!==0)return c(l);return m({head:r,body:e})}async updateWithSkew(t,e,s){if(s===!1)return c(4);let{clock:n,crypto:i}=this,o=n.now(),r=new M(t.eid),[l,a]=r.readStruct(A);if(a!==0)return c(a);let d=t.updatedAt.getTime()-l.ts.getTime(),u={eid:t.eid,off:d+1,ctr:t.ctr+1,len:0},h=(await this.apply([{head:u,body:void 0}]))[0];if(h!==0&&h!==15)return c(h??12);if(e===void 0)return m(u);let[y,b]=oe({id:l.id,ts:o});if(b!==0)return c(b);let[Z,X]=await $e({now:o,eid:y,ctr:0,bod:e,crypto:i});if(X!==0)return c(X);let f=(await this.apply([{head:Z,body:e}]))[0];if(f!==0&&f!==15)return c(f??12);return m(Z)}async updateRaw(t,e,s=this.forceSkewHandlingByDefault){if(t.updatedAt.getTime()>this.clock.now().getTime())return this.updateWithSkew(t,e,s);return this.enqueueApplyJob(async()=>{let[n,i]=await this.makeUpdate(t,e);if(i!==0)return c(i);let r=(await this.doApply([n]))[0];if(r!==0&&r!==15)return c(r??12);return m(n.head)})}async insert(t){let{body:e,type:s,gid:n,pid:i,tags:o}=t,l=Nt({body:e,type:s,gid:n,pid:i,tags:o});return this.insertRaw(l)}async update(t){let{prior:e,body:s,type:n,gid:i,pid:o,tags:r,force:l}=t,d=Nt({body:s,type:n,gid:i,pid:o,tags:r});return this.updateRaw(e,d,l??this.forceSkewHandlingByDefault)}async delete(t){let e=t.force??!0;if("prior"in t)return this.updateRaw(t.prior,void 0,e);let[s,n]=await this.revFromArchive(t.eid);if(n!==0)return c(n);return this.updateRaw(s,void 0,e)}async revFromArchive(t){let e=await this.store.messages.last(t);if(e)return un(e.head);let s=new M(t),[n,i]=s.readStruct(A);if(i!==0)return c(i);return m({eid:t,ctr:-1,updatedAt:n.ts})}async genEID(t){let{clock:e,crypto:s}=this,n=e.now();if(t!==void 0)return oe({id:t,ts:n});let i=await s.genRandomBytes(8);return oe({id:i,ts:n})}sync(){return this.syncRuns.run(()=>this.doSync())}async doSync(){let{connections:t,crypto:e,store:s}=this,n=await s.seed.load();if(!n)return 22;await this.drainApplyQueue();for(let[i,o]of t){let r=await s.hosts.get(i);if(!r)continue;let l={conn:o,store:s,enclave:n,host:r,crypto:e,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},a=await bn(l);if(a!==0)return console.error(`Failed to peek: ${a}`),this.emitProgress({phase:"idle"}),a;this.xferState.emit();let d=await Ji(l);if(d!==0)return console.error(`Failed to push: ${d}`),this.emitProgress({phase:"idle"}),d;this.xferState.emit();let u=await Zn(l,async()=>{await this.drainApplyQueue()});if(u!==0&&u!==15)return console.error(`Failed to pull: ${u}`),this.emitProgress({phase:"idle"}),u;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async rebuild(t){if(this.scheduledSync.cancel(),await this.syncRuns.flush(),t?.checkHost??!0){let s=await this.repull();if(s!==0)return s}return this.enqueueApplyJob(()=>this.replay())}async msgcheck(){let t=await this.store.messages.listKeys();return re(t,this.crypto)}listMsgs(t){return this.store.messages.list(t)}countMsgs(t){return this.store.messages.count(t)}async reconcile(t,e){this.scheduledSync.cancel(),await this.syncRuns.flush();let{connections:s,crypto:n,store:i}=this,o=await i.seed.load();if(!o)return c(22);let r=await i.hosts.get(t);if(!r)return c(13);let l=s.get(t);if(!l||!l.isConnected()){if(await this.connectToHost(r,!1,!1),r=await i.hosts.get(t),!r)return c(13);l=s.get(t)}if(!l)return c(12);let a={conn:l,store:i,enclave:o,crypto:n,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[d,u]=await Xn({...a,host:r},e);if(this.xferState.emit(),u!==0)return this.emitProgress({phase:"idle"}),c(u);if(!d)return this.emitProgress({phase:"idle"}),c(12);if(e?.sync===!1)return this.emitProgress({phase:"idle"}),m(d);let p=await this.sync();if(p!==0)return c(p);let h=await i.hosts.get(t);if(!h)return c(13);let[y,b]=await Xn({...a,host:h},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),b!==0)return c(b);if(!y)return c(12);return m(y)}async repull(){let{connections:t,crypto:e,store:s}=this,n=await s.seed.load();if(!n)return 22;let i=Array.from(await s.hosts.list());if(i.length<1)return 0;for(let o of i){let r=t.get(o.label);if(!r||!r.isConnected())await this.connectToHost(o,!1,!1)}for(let[o,r]of t){let l=await s.hosts.get(o);if(!l)continue;let a={conn:r,store:s,enclave:n,host:{...l,lastSeq:0},crypto:e,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},d=await bn(a);if(d!==0)return console.error(`rebuild: failed to peek: ${d}`),this.emitProgress({phase:"idle"}),d;this.xferState.emit();let u=await Zn(a);if(u!==0&&u!==15)return console.error(`rebuild: failed to pull: ${u}`),this.emitProgress({phase:"idle"}),u;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async replay(){let t=await this.state.clear();if(t!==0)return t;let e=await this.store.messages.list(),s=ue(e,(o)=>o.head),n=s.length;if(n<1)return this.emitProgress({phase:"idle"}),0;let i=0;while(i<s.length){let o=0,r=0,l=i;for(let d=i;d<s.length&&r<100&&o<102400;d++)o+=s[d].head.len,r++,l=d+1;let a=s.slice(i,l);await this.applyStored(a),this.emitProgress({phase:"exec",done:l,total:n}),i=l}return this.emitProgress({phase:"idle"}),0}async wipe(t){let e=t?.msgs!==!1,s=t?.ents!==!1,n=t?.meta!==!1,i=t?.seed===!0;this.scheduledSync.cancel(),await this.disconnect(),await this.syncRuns.flush();let{store:o}=this;if(n)await o.hosts.wipe(),await o.uploads.wipe(),await o.downloads.wipe();if(e)await o.messages.wipe();if(i)await o.seed.wipe();if(s)await this.state.clear();this.lastProgress=zt,this.clientState.emit(),this.xferState.emit()}import=async(t,e)=>{let{crypto:s,store:n}=this,i=e?.onProgress,o=await n.seed.load();if(!o)return 22;console.time("import: decoding file...");let r=await t.bytes(),[l,a]=await gi(r,s,o);if(a!==0)return a;console.timeEnd("import: decoding file...");let d=0;while(d<l.length){let u=0,p=0,h=d;for(let Z=d;Z<l.length&&p<100&&u<102400;Z++)u+=l[Z].head.len,p++,h=Z+1;let y=l.slice(d,h);console.time(`import: applying [${d}, ${h}]`);let b=await this.apply(y,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${d}, ${h}]`);for(let Z=0;Z<y.length;Z++){let X=b[Z];if(X!==0&&X!==15)console.warn(`failed to import msg ${d+Z}: ${W[X]}`)}if(i)queueMicrotask(()=>i(h,l.length,0));this.emitProgress({phase:"import",done:h,total:l.length}),d=h}return this.scheduleSync(),this.emitProgress({phase:"idle"}),0};scheduleSync=()=>{if(this.onScheduleSync){this.onScheduleSync();return}this.scheduledSync.schedule()};async exportBytes(){let{crypto:t,store:e}=this,s=await e.seed.load();if(!s)return c(22);let n=await e.messages.list();return Wi("export",0,n,t,s)}async export(t){let[e,s]=await this.exportBytes();if(s!==0)return s;if(!e)return 12;let n=new Blob([e.slice()]);return rs(n,t),0}async link(t,e=!0){if(await this.store.hosts.add(t),this.clientState.emit(),e){let s=await this.store.hosts.get(t.label);if(s)await this.connectToHost(s)}}async unlink(t){await this.store.hosts.del(t),this.clientState.emit()}async hosts(){return Array.from(await this.store.hosts.list())}connectToHost=async(t,e=!0,s=!0)=>{let{clock:n,connections:i,crypto:o,store:r,transport:l}=this,a=i.get(t.label);if(a){if(a.isConnected())return;try{a.closeListener()}catch{}i.delete(t.label)}let d=await r.seed.load();if(!d)return;console.info(`Connecting to ${t.handle} (${t.label})`);let u=new _e(d,o,t,n,l(t),(p)=>r.hosts.set(t.label,p));if(await u.register(),e)await u.listen(async(p)=>{let h={conn:u,store:r,enclave:d,host:t,crypto:o,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return zi(p,h,this.scheduleSync)},()=>this.clientState.emit(),()=>this.clientState.emit());if(i.set(t.label,u),this.clientState.emit(),s)this.scheduleSync()};async connect(t=!0,e=!0){let{connectToHost:s,scheduleSync:n,store:i}=this;if(!await i.seed.load())return;await this.drainApplyQueue();let r=await i.hosts.list();for(let l of r)await s(l,t,!1);if(e)n()}disconnect=async()=>{for(let t of this.connections.values())try{t.closeListener()}catch{}this.connections.clear(),this.clientState.emit()}}var Ft=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function cs(t){if(!Number.isSafeInteger(t)||t<0)throw Error("positive integer expected, got "+t)}function Gn(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function j(t,...e){if(!Gn(t))throw Error("Uint8Array expected");if(e.length>0&&!e.includes(t.length))throw Error("Uint8Array expected of length "+e+", got length="+t.length)}function fn(t,e=!0){if(t.destroyed)throw Error("Hash instance has been destroyed");if(e&&t.finished)throw Error("Hash#digest() has already been called")}function Ei(t,e){j(t);let s=e.outputLen;if(t.length<s)throw Error("digestInto() expects output buffer of length at least "+s)}function In(t){if(typeof t!=="boolean")throw Error(`boolean expected, not ${t}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var Wt=(t)=>new Uint32Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/4));var Ar=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!Ar)throw Error("Non little-endian hardware is not supported");function qr(t){if(typeof t!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(t))}function as(t){if(typeof t==="string")t=qr(t);else if(Gn(t))t=ds(t);else throw Error("Uint8Array expected, got "+typeof t);return t}function Fi(t,e){if(e==null||typeof e!=="object")throw Error("options must be defined");return Object.assign(t,e)}function Qi(t,e){if(t.length!==e.length)return!1;let s=0;for(let n=0;n<t.length;n++)s|=t[n]^e[n];return s===0}var vi=(t,e)=>{function s(n,...i){if(j(n),t.nonceLength!==void 0){let u=i[0];if(!u)throw Error("nonce / iv required");if(t.varSizeNonce)j(u);else j(u,t.nonceLength)}let o=t.tagLength;if(o&&i[1]!==void 0)j(i[1]);let r=e(n,...i),l=(u,p)=>{if(p!==void 0){if(u!==2)throw Error("cipher output not supported");j(p)}},a=!1;return{encrypt(u,p){if(a)throw Error("cannot encrypt() twice with same key + nonce");return a=!0,j(u),l(r.encrypt.length,p),r.encrypt(u,p)},decrypt(u,p){if(j(u),o&&u.length<o)throw Error("invalid ciphertext length: smaller than tagLength="+o);return l(r.decrypt.length,p),r.decrypt(u,p)}}}return Object.assign(s,t),s};function Sn(t,e,s=!0){if(e===void 0)return new Uint8Array(t);if(e.length!==t)throw Error("invalid output length, expected "+t+", got: "+e.length);if(s&&!_r(e))throw Error("invalid output, must be aligned");return e}function _r(t){return t.byteOffset%4===0}function ds(t){return Uint8Array.from(t)}function Xt(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function Te(t=32){if(Ft&&typeof Ft.getRandomValues==="function")return Ft.getRandomValues(new Uint8Array(t));if(Ft&&typeof Ft.randomBytes==="function")return Ft.randomBytes(t);throw Error("crypto.getRandomValues must be defined")}var Oi=(t)=>Uint8Array.from(t.split("").map((e)=>e.charCodeAt(0))),$r=Oi("expand 16-byte k"),tl=Oi("expand 32-byte k"),el=Wt($r),sl=Wt(tl);function g(t,e){return t<<e|t>>>32-e}function Vn(t){return t.byteOffset%4===0}var us=64,nl=16,ji=4294967295,Di=new Uint32Array;function il(t,e,s,n,i,o,r,l){let a=i.length,d=new Uint8Array(us),u=Wt(d),p=Vn(i)&&Vn(o),h=p?Wt(i):Di,y=p?Wt(o):Di;for(let b=0;b<a;r++){if(t(e,s,n,u,r,l),r>=ji)throw Error("arx: counter overflow");let Z=Math.min(us,a-b);if(p&&Z===us){let X=b/4;if(b%4!==0)throw Error("arx: invalid block position");for(let I=0,f;I<nl;I++)f=X+I,y[f]=h[f]^u[I];b+=us;continue}for(let X=0,I;X<Z;X++)I=b+X,o[I]=i[I]^d[X];b+=Z}}function Ai(t,e){let{allowShortKeys:s,extendNonceFn:n,counterLength:i,counterRight:o,rounds:r}=Fi({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},e);if(typeof t!=="function")throw Error("core must be a function");return cs(i),cs(r),In(o),In(s),(l,a,d,u,p=0)=>{j(l),j(a),j(d);let h=d.length;if(u===void 0)u=new Uint8Array(h);if(j(u),cs(p),p<0||p>=ji)throw Error("arx: counter overflow");if(u.length<h)throw Error(`arx: output (${u.length}) is shorter than data (${h})`);let y=[],b=l.length,Z,X;if(b===32)y.push(Z=ds(l)),X=sl;else if(b===16&&s)Z=new Uint8Array(32),Z.set(l),Z.set(l,16),X=el,y.push(Z);else throw Error(`arx: invalid 32-byte key, got length=${b}`);if(!Vn(a))y.push(a=ds(a));let I=Wt(Z);if(n){if(a.length!==24)throw Error("arx: extended nonce must be 24 bytes");n(X,I,Wt(a.subarray(0,16)),I),a=a.subarray(16)}let f=16-i;if(f!==a.length)throw Error(`arx: nonce must be ${f} or 16 bytes`);if(f!==12){let G=new Uint8Array(12);G.set(a,o?0:12-a.length),a=G,y.push(a)}let V=Wt(a);return il(t,X,I,V,d,u,p,r),Xt(...y),u}}var _=(t,e)=>t[e++]&255|(t[e++]&255)<<8;class qi{constructor(t){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,t=as(t),j(t,32);let e=_(t,0),s=_(t,2),n=_(t,4),i=_(t,6),o=_(t,8),r=_(t,10),l=_(t,12),a=_(t,14);this.r[0]=e&8191,this.r[1]=(e>>>13|s<<3)&8191,this.r[2]=(s>>>10|n<<6)&7939,this.r[3]=(n>>>7|i<<9)&8191,this.r[4]=(i>>>4|o<<12)&255,this.r[5]=o>>>1&8190,this.r[6]=(o>>>14|r<<2)&8191,this.r[7]=(r>>>11|l<<5)&8065,this.r[8]=(l>>>8|a<<8)&8191,this.r[9]=a>>>5&127;for(let d=0;d<8;d++)this.pad[d]=_(t,16+2*d)}process(t,e,s=!1){let n=s?0:2048,{h:i,r:o}=this,r=o[0],l=o[1],a=o[2],d=o[3],u=o[4],p=o[5],h=o[6],y=o[7],b=o[8],Z=o[9],X=_(t,e+0),I=_(t,e+2),f=_(t,e+4),V=_(t,e+6),G=_(t,e+8),K=_(t,e+10),H=_(t,e+12),L=_(t,e+14),T=i[0]+(X&8191),C=i[1]+((X>>>13|I<<3)&8191),U=i[2]+((I>>>10|f<<6)&8191),N=i[3]+((f>>>7|V<<9)&8191),F=i[4]+((V>>>4|G<<12)&8191),S=i[5]+(G>>>1&8191),Y=i[6]+((G>>>14|K<<2)&8191),w=i[7]+((K>>>11|H<<5)&8191),k=i[8]+((H>>>8|L<<8)&8191),z=i[9]+(L>>>5|n),x=0,O=x+T*r+C*(5*Z)+U*(5*b)+N*(5*y)+F*(5*h);x=O>>>13,O&=8191,O+=S*(5*p)+Y*(5*u)+w*(5*d)+k*(5*a)+z*(5*l),x+=O>>>13,O&=8191;let st=x+T*l+C*r+U*(5*Z)+N*(5*b)+F*(5*y);x=st>>>13,st&=8191,st+=S*(5*h)+Y*(5*p)+w*(5*u)+k*(5*d)+z*(5*a),x+=st>>>13,st&=8191;let lt=x+T*a+C*l+U*r+N*(5*Z)+F*(5*b);x=lt>>>13,lt&=8191,lt+=S*(5*y)+Y*(5*h)+w*(5*p)+k*(5*u)+z*(5*d),x+=lt>>>13,lt&=8191;let v=x+T*d+C*a+U*l+N*r+F*(5*Z);x=v>>>13,v&=8191,v+=S*(5*b)+Y*(5*y)+w*(5*h)+k*(5*p)+z*(5*u),x+=v>>>13,v&=8191;let It=x+T*u+C*d+U*a+N*l+F*r;x=It>>>13,It&=8191,It+=S*(5*Z)+Y*(5*b)+w*(5*y)+k*(5*h)+z*(5*p),x+=It>>>13,It&=8191;let qt=x+T*p+C*u+U*d+N*a+F*l;x=qt>>>13,qt&=8191,qt+=S*r+Y*(5*Z)+w*(5*b)+k*(5*y)+z*(5*h),x+=qt>>>13,qt&=8191;let _t=x+T*h+C*p+U*u+N*d+F*a;x=_t>>>13,_t&=8191,_t+=S*l+Y*r+w*(5*Z)+k*(5*b)+z*(5*y),x+=_t>>>13,_t&=8191;let $t=x+T*y+C*h+U*p+N*u+F*d;x=$t>>>13,$t&=8191,$t+=S*a+Y*l+w*r+k*(5*Z)+z*(5*b),x+=$t>>>13,$t&=8191;let te=x+T*b+C*y+U*h+N*p+F*u;x=te>>>13,te&=8191,te+=S*d+Y*a+w*l+k*r+z*(5*Z),x+=te>>>13,te&=8191;let ee=x+T*Z+C*b+U*y+N*h+F*p;x=ee>>>13,ee&=8191,ee+=S*u+Y*d+w*a+k*l+z*r,x+=ee>>>13,ee&=8191,x=(x<<2)+x|0,x=x+O|0,O=x&8191,x=x>>>13,st+=x,i[0]=O,i[1]=st,i[2]=lt,i[3]=v,i[4]=It,i[5]=qt,i[6]=_t,i[7]=$t,i[8]=te,i[9]=ee}finalize(){let{h:t,pad:e}=this,s=new Uint16Array(10),n=t[1]>>>13;t[1]&=8191;for(let r=2;r<10;r++)t[r]+=n,n=t[r]>>>13,t[r]&=8191;t[0]+=n*5,n=t[0]>>>13,t[0]&=8191,t[1]+=n,n=t[1]>>>13,t[1]&=8191,t[2]+=n,s[0]=t[0]+5,n=s[0]>>>13,s[0]&=8191;for(let r=1;r<10;r++)s[r]=t[r]+n,n=s[r]>>>13,s[r]&=8191;s[9]-=8192;let i=(n^1)-1;for(let r=0;r<10;r++)s[r]&=i;i=~i;for(let r=0;r<10;r++)t[r]=t[r]&i|s[r];t[0]=(t[0]|t[1]<<13)&65535,t[1]=(t[1]>>>3|t[2]<<10)&65535,t[2]=(t[2]>>>6|t[3]<<7)&65535,t[3]=(t[3]>>>9|t[4]<<4)&65535,t[4]=(t[4]>>>12|t[5]<<1|t[6]<<14)&65535,t[5]=(t[6]>>>2|t[7]<<11)&65535,t[6]=(t[7]>>>5|t[8]<<8)&65535,t[7]=(t[8]>>>8|t[9]<<5)&65535;let o=t[0]+e[0];t[0]=o&65535;for(let r=1;r<8;r++)o=(t[r]+e[r]|0)+(o>>>16)|0,t[r]=o&65535;Xt(s)}update(t){fn(this);let{buffer:e,blockLen:s}=this;t=as(t);let n=t.length;for(let i=0;i<n;){let o=Math.min(s-this.pos,n-i);if(o===s){for(;s<=n-i;i+=s)this.process(t,i);continue}if(e.set(t.subarray(i,i+o),this.pos),this.pos+=o,i+=o,this.pos===s)this.process(e,0,!1),this.pos=0}return this}destroy(){Xt(this.h,this.r,this.buffer,this.pad)}digestInto(t){fn(this),Ei(t,this),this.finished=!0;let{buffer:e,h:s}=this,{pos:n}=this;if(n){e[n++]=1;for(;n<16;n++)e[n]=0;this.process(e,0,!0)}this.finalize();let i=0;for(let o=0;o<8;o++)t[i++]=s[o]>>>0,t[i++]=s[o]>>>8;return t}digest(){let{buffer:t,outputLen:e}=this;this.digestInto(t);let s=t.slice(0,e);return this.destroy(),s}}function ol(t){let e=(n,i)=>t(i).update(as(n)).digest(),s=t(new Uint8Array(32));return e.outputLen=s.outputLen,e.blockLen=s.blockLen,e.create=(n)=>t(n),e}var Wn=ol((t)=>new qi(t));function rl(t,e,s,n,i,o=20){let r=t[0],l=e[0],a=e[1],d=e[2],u=e[3],p=t[1],h=s[0],y=s[1],b=i,Z=0,X=t[2],I=e[4],f=e[5],V=e[6],G=e[7],K=t[3],H=r,L=l,T=a,C=d,U=u,N=p,F=h,S=y,Y=b,w=Z,k=X,z=I,x=f,O=V,st=G,lt=K;for(let It=0;It<o;It+=2)U^=g(H+x|0,7),Y^=g(U+H|0,9),x^=g(Y+U|0,13),H^=g(x+Y|0,18),w^=g(N+L|0,7),O^=g(w+N|0,9),L^=g(O+w|0,13),N^=g(L+O|0,18),st^=g(k+F|0,7),T^=g(st+k|0,9),F^=g(T+st|0,13),k^=g(F+T|0,18),C^=g(lt+z|0,7),S^=g(C+lt|0,9),z^=g(S+C|0,13),lt^=g(z+S|0,18),L^=g(H+C|0,7),T^=g(L+H|0,9),C^=g(T+L|0,13),H^=g(C+T|0,18),F^=g(N+U|0,7),S^=g(F+N|0,9),U^=g(S+F|0,13),N^=g(U+S|0,18),z^=g(k+w|0,7),Y^=g(z+k|0,9),w^=g(Y+z|0,13),k^=g(w+Y|0,18),x^=g(lt+st|0,7),O^=g(x+lt|0,9),st^=g(O+x|0,13),lt^=g(st+O|0,18);let v=0;n[v++]=r+H|0,n[v++]=l+L|0,n[v++]=a+T|0,n[v++]=d+C|0,n[v++]=u+U|0,n[v++]=p+N|0,n[v++]=h+F|0,n[v++]=y+S|0,n[v++]=b+Y|0,n[v++]=Z+w|0,n[v++]=X+k|0,n[v++]=I+z|0,n[v++]=f+x|0,n[v++]=V+O|0,n[v++]=G+st|0,n[v++]=K+lt|0}function ll(t,e,s,n){let i=t[0],o=e[0],r=e[1],l=e[2],a=e[3],d=t[1],u=s[0],p=s[1],h=s[2],y=s[3],b=t[2],Z=e[4],X=e[5],I=e[6],f=e[7],V=t[3];for(let K=0;K<20;K+=2)a^=g(i+X|0,7),h^=g(a+i|0,9),X^=g(h+a|0,13),i^=g(X+h|0,18),y^=g(d+o|0,7),I^=g(y+d|0,9),o^=g(I+y|0,13),d^=g(o+I|0,18),f^=g(b+u|0,7),r^=g(f+b|0,9),u^=g(r+f|0,13),b^=g(u+r|0,18),l^=g(V+Z|0,7),p^=g(l+V|0,9),Z^=g(p+l|0,13),V^=g(Z+p|0,18),o^=g(i+l|0,7),r^=g(o+i|0,9),l^=g(r+o|0,13),i^=g(l+r|0,18),u^=g(d+a|0,7),p^=g(u+d|0,9),a^=g(p+u|0,13),d^=g(a+p|0,18),Z^=g(b+y|0,7),h^=g(Z+b|0,9),y^=g(h+Z|0,13),b^=g(y+h|0,18),X^=g(V+f|0,7),I^=g(X+V|0,9),f^=g(I+X|0,13),V^=g(f+I|0,18);let G=0;n[G++]=i,n[G++]=d,n[G++]=b,n[G++]=V,n[G++]=u,n[G++]=p,n[G++]=h,n[G++]=y}var gn=Ai(rl,{counterRight:!0,extendNonceFn:ll}),Kn=vi({blockSize:64,nonceLength:24,tagLength:16},(t,e)=>({encrypt(s,n){n=Sn(s.length+32,n,!1);let i=n.subarray(0,32),o=n.subarray(32);n.set(s,32),Xt(i),gn(t,e,n,n);let r=Wn(o,i);return n.set(r,16),Xt(n.subarray(0,16),r),n.subarray(16)},decrypt(s,n){j(s),n=Sn(s.length+32,n,!1);let i=n.subarray(0,32),o=n.subarray(32,48),r=n.subarray(48);n.set(s,32),Xt(i);let l=gn(t,e,i,i),a=Wn(r,l);if(!Qi(o,a))throw Error("invalid tag");return gn(t,e,n.subarray(16),n.subarray(16)),Xt(i,o,a),r}}));/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function cl(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function Le(t){if(!Number.isSafeInteger(t)||t<0)throw Error("positive integer expected, got "+t)}function Qt(t,...e){if(!cl(t))throw Error("Uint8Array expected");if(e.length>0&&!e.includes(t.length))throw Error("Uint8Array expected of length "+e+", got length="+t.length)}function Me(t,e=!0){if(t.destroyed)throw Error("Hash instance has been destroyed");if(e&&t.finished)throw Error("Hash#digest() has already been called")}function ps(t,e){Qt(t);let s=e.outputLen;if(t.length<s)throw Error("digestInto() expects output buffer of length at least "+s)}function _i(t){return new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}function ye(t){return new Uint32Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/4))}function be(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function Pe(t,e){return t<<32-e|t>>>e}var $i=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function to(t){return t<<24&4278190080|t<<8&16711680|t>>>8&65280|t>>>24&255}var eo=$i?(t)=>t:(t)=>to(t);function al(t){for(let e=0;e<t.length;e++)t[e]=to(t[e]);return t}var it=$i?(t)=>t:al;function dl(t){if(typeof t!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(t))}function Ze(t){if(typeof t==="string")t=dl(t);return Qt(t),t}class xn{}function so(t){let e=(n,i)=>t(i).update(Ze(n)).digest(),s=t({});return e.outputLen=s.outputLen,e.blockLen=s.blockLen,e.create=(n)=>t(n),e}var no=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var ms=BigInt(4294967295),io=BigInt(32);function Rn(t,e=!1){if(e)return{h:Number(t&ms),l:Number(t>>io&ms)};return{h:Number(t>>io&ms)|0,l:Number(t&ms)|0}}function gt(t,e,s,n,i){return t=t+e+i|0,n=Pe(n^t,16),s=s+n|0,e=Pe(e^s,12),{a:t,b:e,c:s,d:n}}function Kt(t,e,s,n,i){return t=t+e+i|0,n=Pe(n^t,8),s=s+n|0,e=Pe(e^s,7),{a:t,b:e,c:s,d:n}}class Hn extends xn{constructor(t,e){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,Le(t),Le(e),this.blockLen=t,this.outputLen=e,this.buffer=new Uint8Array(t),this.buffer32=ye(this.buffer)}update(t){Me(this),t=Ze(t),Qt(t);let{blockLen:e,buffer:s,buffer32:n}=this,i=t.length,o=t.byteOffset,r=t.buffer;for(let l=0;l<i;){if(this.pos===e)it(n),this.compress(n,0,!1),it(n),this.pos=0;let a=Math.min(e-this.pos,i-l),d=o+l;if(a===e&&!(d%4)&&l+a<i){let u=new Uint32Array(r,d,Math.floor((i-l)/4));it(u);for(let p=0;l+e<i;p+=n.length,l+=e)this.length+=e,this.compress(u,p,!1);it(u);continue}s.set(t.subarray(l,l+a),this.pos),this.pos+=a,this.length+=a,l+=a}return this}digestInto(t){Me(this),ps(t,this);let{pos:e,buffer32:s}=this;this.finished=!0,be(this.buffer.subarray(e)),it(s),this.compress(s,0,!0),it(s);let n=ye(t);this.get().forEach((i,o)=>n[o]=eo(i))}digest(){let{buffer:t,outputLen:e}=this;this.digestInto(t);let s=t.slice(0,e);return this.destroy(),s}_cloneInto(t){let{buffer:e,length:s,finished:n,destroyed:i,outputLen:o,pos:r}=this;return t||(t=new this.constructor({dkLen:o})),t.set(...this.get()),t.buffer.set(e),t.destroyed=i,t.finished=n,t.length=s,t.pos=r,t.outputLen=o,t}clone(){return this._cloneInto()}}function Yn(t,e,s,n,i,o,r,l,a,d,u,p,h,y,b,Z,X,I,f,V){let G=0;for(let K=0;K<n;K++)({a:i,b:a,c:h,d:X}=gt(i,a,h,X,s[e+t[G++]])),{a:i,b:a,c:h,d:X}=Kt(i,a,h,X,s[e+t[G++]]),{a:o,b:d,c:y,d:I}=gt(o,d,y,I,s[e+t[G++]]),{a:o,b:d,c:y,d:I}=Kt(o,d,y,I,s[e+t[G++]]),{a:r,b:u,c:b,d:f}=gt(r,u,b,f,s[e+t[G++]]),{a:r,b:u,c:b,d:f}=Kt(r,u,b,f,s[e+t[G++]]),{a:l,b:p,c:Z,d:V}=gt(l,p,Z,V,s[e+t[G++]]),{a:l,b:p,c:Z,d:V}=Kt(l,p,Z,V,s[e+t[G++]]),{a:i,b:d,c:b,d:V}=gt(i,d,b,V,s[e+t[G++]]),{a:i,b:d,c:b,d:V}=Kt(i,d,b,V,s[e+t[G++]]),{a:o,b:u,c:Z,d:X}=gt(o,u,Z,X,s[e+t[G++]]),{a:o,b:u,c:Z,d:X}=Kt(o,u,Z,X,s[e+t[G++]]),{a:r,b:p,c:h,d:I}=gt(r,p,h,I,s[e+t[G++]]),{a:r,b:p,c:h,d:I}=Kt(r,p,h,I,s[e+t[G++]]),{a:l,b:a,c:y,d:f}=gt(l,a,y,f,s[e+t[G++]]),{a:l,b:a,c:y,d:f}=Kt(l,a,y,f,s[e+t[G++]]);return{v0:i,v1:o,v2:r,v3:l,v4:a,v5:d,v6:u,v7:p,v8:h,v9:y,v10:b,v11:Z,v12:X,v13:I,v14:f,v15:V}}var Gt={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},xt=no.slice(),oo=(()=>{let t=Array.from({length:16},(n,i)=>i),e=(n)=>[2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8].map((i)=>n[i]),s=[];for(let n=0,i=t;n<7;n++,i=e(i))s.push(...i);return Uint8Array.from(s)})();class Cn extends Hn{constructor(t={},e=0){super(64,t.dkLen===void 0?32:t.dkLen);this.chunkPos=0,this.chunksDone=0,this.flags=0,this.stack=[],this.posOut=0,this.bufferOut32=new Uint32Array(16),this.chunkOut=0,this.enableXOF=!0;let{key:s,context:n}=t,i=n!==void 0;if(s!==void 0){if(i)throw Error('Only "key" or "context" can be specified at same time');let o=Ze(s).slice();Qt(o,32),this.IV=ye(o),it(this.IV),this.flags=e|Gt.KEYED_HASH}else if(i){let o=Ze(n),r=new Cn({dkLen:32},Gt.DERIVE_KEY_CONTEXT).update(o).digest();this.IV=ye(r),it(this.IV),this.flags=e|Gt.DERIVE_KEY_MATERIAL}else this.IV=xt.slice(),this.flags=e;this.state=this.IV.slice(),this.bufferOut=_i(this.bufferOut32)}get(){return[]}set(){}b2Compress(t,e,s,n=0){let{state:i,pos:o}=this,{h:r,l}=Rn(BigInt(t),!0),{v0:a,v1:d,v2:u,v3:p,v4:h,v5:y,v6:b,v7:Z,v8:X,v9:I,v10:f,v11:V,v12:G,v13:K,v14:H,v15:L}=Yn(oo,n,s,7,i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],xt[0],xt[1],xt[2],xt[3],r,l,o,e);i[0]=a^X,i[1]=d^I,i[2]=u^f,i[3]=p^V,i[4]=h^G,i[5]=y^K,i[6]=b^H,i[7]=Z^L}compress(t,e=0,s=!1){let n=this.flags;if(!this.chunkPos)n|=Gt.CHUNK_START;if(this.chunkPos===15||s)n|=Gt.CHUNK_END;if(!s)this.pos=this.blockLen;if(this.b2Compress(this.chunksDone,n,t,e),this.chunkPos+=1,this.chunkPos===16||s){let i=this.state;this.state=this.IV.slice();for(let o,r=this.chunksDone+1;s||!(r&1);r>>=1){if(!(o=this.stack.pop()))break;this.buffer32.set(o,0),this.buffer32.set(i,8),this.pos=this.blockLen,this.b2Compress(0,this.flags|Gt.PARENT,this.buffer32,0),i=this.state,this.state=this.IV.slice()}this.chunksDone++,this.chunkPos=0,this.stack.push(i)}this.pos=0}_cloneInto(t){t=super._cloneInto(t);let{IV:e,flags:s,state:n,chunkPos:i,posOut:o,chunkOut:r,stack:l,chunksDone:a}=this;return t.state.set(n.slice()),t.stack=l.map((d)=>Uint32Array.from(d)),t.IV.set(e),t.flags=s,t.chunkPos=i,t.chunksDone=a,t.posOut=o,t.chunkOut=r,t.enableXOF=this.enableXOF,t.bufferOut32.set(this.bufferOut32),t}destroy(){this.destroyed=!0,be(this.state,this.buffer32,this.IV,this.bufferOut32),be(...this.stack)}b2CompressOut(){let{state:t,pos:e,flags:s,buffer32:n,bufferOut32:i}=this,{h:o,l:r}=Rn(BigInt(this.chunkOut++));it(n);let{v0:l,v1:a,v2:d,v3:u,v4:p,v5:h,v6:y,v7:b,v8:Z,v9:X,v10:I,v11:f,v12:V,v13:G,v14:K,v15:H}=Yn(oo,0,n,7,t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],xt[0],xt[1],xt[2],xt[3],r,o,e,s);i[0]=l^Z,i[1]=a^X,i[2]=d^I,i[3]=u^f,i[4]=p^V,i[5]=h^G,i[6]=y^K,i[7]=b^H,i[8]=t[0]^Z,i[9]=t[1]^X,i[10]=t[2]^I,i[11]=t[3]^f,i[12]=t[4]^V,i[13]=t[5]^G,i[14]=t[6]^K,i[15]=t[7]^H,it(n),it(i),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,be(this.buffer.subarray(this.pos));let t=this.flags|Gt.ROOT;if(this.stack.length)t|=Gt.PARENT,it(this.buffer32),this.compress(this.buffer32,0,!0),it(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else t|=(!this.chunkPos?Gt.CHUNK_START:0)|Gt.CHUNK_END;this.flags=t,this.b2CompressOut()}writeInto(t){Me(this,!1),Qt(t),this.finish();let{blockLen:e,bufferOut:s}=this;for(let n=0,i=t.length;n<i;){if(this.posOut>=e)this.b2CompressOut();let o=Math.min(e-this.posOut,i-n);t.set(s.subarray(this.posOut,this.posOut+o),n),this.posOut+=o,n+=o}return t}xofInto(t){if(!this.enableXOF)throw Error("XOF is not possible after digest call");return this.writeInto(t)}xof(t){return Le(t),this.xofInto(new Uint8Array(t))}digestInto(t){if(ps(t,this),this.finished)throw Error("digest() was already called");return this.enableXOF=!1,this.writeInto(t),this.destroy(),t}digest(){return this.digestInto(new Uint8Array(this.outputLen))}}var ro=so((t)=>new Cn(t));var ul=32,Uy=Symbol("X25519Sk");function lo(t){if(t.byteLength!==ul)return c(10);return m(t)}var J=(1n<<255n)-19n,pl=121665n,co=new Uint8Array(32);co[0]=9;function ao(t){let e=0n;for(let s=t.length-1;s>=0;s--)e=e<<8n|BigInt(t[s]);return e}function ml(t){let e=new Uint8Array(32),s=(t%J+J)%J;for(let n=0;n<32;n++)e[n]=Number(s&0xffn),s>>=8n;return e}function hl(t){let e=t.slice();return e[31]&=127,ao(e)}function yl(t){let e=t.slice();return e[0]&=248,e[31]&=127,e[31]|=64,e}function hs(t,e,s){let n=-t,i=(e^s)&n;return[e^i,s^i]}function bl(t){let e=J-2n,s=(t%J+J)%J,n=1n;while(e>0n){if(e&1n)n=n*s%J;s=s*s%J,e>>=1n}return n}function Zl(t,e){let s=yl(t),n=hl(e),i=1n,o=0n,r=n,l=1n,a=0n,d=ao(s);for(let u=254;u>=0;u--){let p=d>>BigInt(u)&1n;a^=p,[i,r]=hs(a,i,r),[o,l]=hs(a,o,l),a=p;let h=(i+o)%J,y=h*h%J,b=(i-o+J)%J,Z=b*b%J,X=(y-Z+J)%J,I=(r+l)%J,V=(r-l+J)%J*h%J,G=I*b%J,K=(V+G)%J,H=(V-G+J)%J;r=K*K%J,l=n*H*H%J,i=y*Z%J,o=X*(y+pl*X)%J}return[i,r]=hs(a,i,r),[o,l]=hs(a,o,l),s.fill(0),ml(i*bl(o)%J)}function uo(t){return Zl(t,co)}var kn=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function po(t){let e=new Uint8Array(kn.length+32);return e.set(kn),e.set(t.subarray(0,32),kn.length),e}var Tn=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);function mo(t){let e=new Uint8Array(Tn.length+32);return e.set(Tn),e.set(t.subarray(0,32),Tn.length),e}function ho(t){return typeof t==="string"?new TextEncoder().encode(t):t}function Rt(t){let e=new ArrayBuffer(t.byteLength);return new Uint8Array(e).set(t),e}class vt{verifyKeys=new Map;async genRandomBytes(t){return Te(t)}async gen256BitSecureRandomSeed(){return Te(32)}async encryptXSalsa20Poly1305Combined(t,e){let s=Te(24),i=Kn(e,s).encrypt(t);return new Uint8Array([...s,...i])}async decryptXSalsa20Poly1305Combined(t,e){let s=t.slice(0,24),n=t.slice(24);return Kn(e,s).decrypt(n)}async deriveEd25519KeyPair(t){let e=t,s=po(e),n=Rt(s),i;try{let d=await globalThis.crypto.subtle.importKey("pkcs8",n,{name:"Ed25519"},!0,["sign"]);i=await globalThis.crypto.subtle.exportKey("jwk",d)}finally{s.fill(0),new Uint8Array(n).fill(0)}if(typeof i.x!=="string")throw Error("Ed25519 JWK missing x");let o=i.x;i.d=void 0;let r=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:o},{name:"Ed25519"},!0,["verify"]),l=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",r));this.verifyKeys.set(ct(l),r);let a=new Uint8Array(64);return a.set(e,0),a.set(l,32),{keyType:"ed25519",privateKey:a,publicKey:l}}async importSignKey(t){let e=t.subarray(0,32),s=po(e),n=Rt(s);try{return await globalThis.crypto.subtle.importKey("pkcs8",n,{name:"Ed25519"},!1,["sign"])}finally{s.fill(0),new Uint8Array(n).fill(0)}}async importVerifyKey(t){let e=ct(t),s=this.verifyKeys.get(e);if(s)return s;let n=await globalThis.crypto.subtle.importKey("raw",Rt(t),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(e,n),n}async signEd25519(t,e){let s=ho(t),n=await this.importSignKey(e),i=await globalThis.crypto.subtle.sign({name:"Ed25519"},n,Rt(s));return new Uint8Array(i)}async checkSigEd25519(t,e,s){let n=ho(e);try{let i=await this.importVerifyKey(s);return await globalThis.crypto.subtle.verify({name:"Ed25519"},i,Rt(t),Rt(n))}catch{return!1}}async blake3(t){return ro(t)}async genX25519(){let t=await Te(32);t[0]&=248,t[31]&=127,t[31]|=64;let[e,s]=lo(t);if(s!==0||e===void 0)throw t.fill(0),Error("X25519 scalar brand failed");let n=uo(e),i=mo(e),o=Rt(i);try{let r=await globalThis.crypto.subtle.importKey("pkcs8",o,{name:"X25519"},!0,["deriveBits"]),l=await globalThis.crypto.subtle.exportKey("jwk",r);if(typeof l.x!=="string")throw Error("X25519 JWK missing x");let a=Fs(l.x);if(l.d=void 0,!B(a,n))throw Error("X25519 WebCrypto pub != RFC 7748");return{priv:e,pub:n}}catch(r){throw e.fill(0),r}finally{i.fill(0),new Uint8Array(o).fill(0)}}async x25519Shared(t,e){let s=mo(t),n=Rt(s);try{let i=await globalThis.crypto.subtle.importKey("pkcs8",n,{name:"X25519"},!1,["deriveBits"]),o=await globalThis.crypto.subtle.importKey("raw",Rt(e),{name:"X25519"},!1,[]),r=await globalThis.crypto.subtle.deriveBits({name:"X25519",public:o},i,256);return new Uint8Array(r)}finally{s.fill(0),new Uint8Array(n).fill(0)}}}var Xl=new vt,Xe=Xl;import{useEffect as ws,useState as $n}from"react";class Ln{db;constructor(t){this.db=t}async enq(t){let e=[...t];if(e.length===0)return;let s=this.db.transaction(pt,"readwrite"),n=s.objectStore(pt);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error);for(let r of e){let l=`${r.host}:${r.seq}`;n.put(r,l)}})}async deq(t,e){let s=[...e];if(s.length===0)return;let n=this.db.transaction(pt,"readwrite"),i=n.objectStore(pt);return new Promise((o,r)=>{n.oncomplete=()=>o(),n.onerror=()=>r(n.error);for(let l of s){let a=`${t}:${l}`;i.delete(a)}})}async list(){let e=this.db.transaction(pt,"readonly").objectStore(pt);return new Promise((s,n)=>{let i=e.getAll();i.onsuccess=()=>s(i.result),i.onerror=()=>n(i.error)})}async count(){let e=this.db.transaction(pt,"readonly").objectStore(pt);return new Promise((s,n)=>{let i=e.count();i.onsuccess=()=>s(i.result),i.onerror=()=>n(i.error)})}async wipe(){let t=this.db.transaction(pt,"readwrite"),e=t.objectStore(pt);return new Promise((s,n)=>{t.oncomplete=()=>s(),t.onerror=()=>n(t.error),e.clear()})}}function yo(t){return{label:t.label,handle:new URL(t.handle),idx:t.idx,lastSeq:t.lastSeq||0,clockOffset:t.clockOffset,subscription:t.subscription}}function Gl(t,e){let s={...t};if(e.setLastSeq!==void 0)s.lastSeq=e.setLastSeq;else if(e.lastSeq!==void 0){let n=s.lastSeq||0;if(e.lastSeq>n)s.lastSeq=e.lastSeq}return delete s.numBags,delete s.numDupes,s}class Mn{db;constructor(t){this.db=t}async add(t){let e=await this.get(t.label),s=e!==void 0&&e.handle.href===t.handle.href&&(e.idx??0)===(t.idx??0);return this.put({...t,lastSeq:s?e.lastSeq:0,clockOffset:s?e.clockOffset:void 0,subscription:s?e.subscription:void 0})}async put(t){let e={...t,handle:t.handle.toString(),lastSeq:t.lastSeq??0},s=this.db.transaction(ot,"readwrite"),n=s.objectStore(ot);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error),n.put(e)})}async touch(t,e){return this.recordStats(t,{lastSeq:e})}async recordStats(t,e){let s=this.db.transaction(ot,"readwrite"),n=s.objectStore(ot);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error);let r=n.get(t);r.onsuccess=()=>{let l=r.result;if(!l)return;n.put(Gl(l,e))}})}async get(t){let s=this.db.transaction(ot,"readonly").objectStore(ot);return new Promise((n,i)=>{let o=s.get(t);o.onsuccess=()=>{let r=o.result;if(!r)n(void 0);else n(yo(r))},o.onerror=()=>i(o.error)})}async set(t,e){let s=await this.get(t);if(!s)return 13;try{return await this.put({...s,...e}),0}catch{return 18}}async del(t){let e=this.db.transaction(ot,"readwrite"),s=e.objectStore(ot);return new Promise((n,i)=>{e.oncomplete=()=>n(),e.onerror=()=>i(e.error),s.delete(t)})}async list(){let e=this.db.transaction(ot,"readonly").objectStore(ot);return new Promise((s,n)=>{let i=e.getAll();i.onsuccess=()=>{let o=i.result;s(o.map(yo))},i.onerror=()=>n(i.error)})}async wipe(){let t=this.db.transaction(ot,"readwrite"),e=t.objectStore(ot);return new Promise((s,n)=>{t.oncomplete=()=>s(),t.onerror=()=>n(t.error),e.clear()})}}class Pn{crypto;db;constructor(t,e){this.crypto=e;this.db=t}async add(t){let e=this.db.transaction(Q,"readwrite"),s=e.objectStore(Q);return new Promise((n)=>{if(t.length===0){n([]);return}let i=Array(t.length).fill(0);e.oncomplete=()=>n(i),e.onerror=()=>{for(let o=0;o<i.length;o++)i[o]=18;n(i)};for(let o=0;o<t.length;o++){let{key:r,data:l}=t[o],a=R(r),d=s.put(l,a);d.onerror=(u)=>{u.preventDefault(),i[o]=18}}})}async del(t){let e=[...t];if(e.length===0)return;let s=this.db.transaction(Q,"readwrite"),n=s.objectStore(Q);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error);for(let r of e){let l=R(r);n.delete(l)}})}async get(t){let s=this.db.transaction(Q,"readonly").objectStore(Q);return new Promise((n,i)=>{let o=R(t),r=s.get(o);r.onsuccess=async()=>{let l=r.result;if(l)n(await Ut(t,l,this.crypto));else n(void 0)},r.onerror=()=>i(r.error)})}async has(t){return await this.get(t)!==void 0}async list(t){let e=t?.apld,s=t?.body!==!1,i=this.db.transaction(Q,"readonly").objectStore(Q);return new Promise((o,r)=>{let l=[],a=e===void 0?i.openCursor():i.index(we).openCursor(IDBKeyRange.only(e));a.onsuccess=(d)=>{let u=d.target.result;if(u){let p=e===void 0?u.key:u.primaryKey,h=u.value;l.push({hash:tt(p),data:h}),u.continue()}else Promise.all(l.map(({hash:p,data:h})=>Ut(p,h,this.crypto,{body:s}))).then(o).catch(r)},a.onerror=()=>r(a.error)})}async count(t){let s=this.db.transaction(Q,"readonly").objectStore(Q);return new Promise((n,i)=>{let o=t===void 0?s.count():s.index(we).count(IDBKeyRange.only(t));o.onsuccess=()=>n(o.result),o.onerror=()=>i(o.error)})}async listKeys(){let e=this.db.transaction(Q,"readonly").objectStore(Q);return new Promise((s,n)=>{let i=[],o=e.openKeyCursor();o.onsuccess=(r)=>{let l=r.target.result;if(l)i.push(tt(l.key)),l.continue();else s(i)},o.onerror=()=>n(o.error)})}async last(t){let s=this.db.transaction(Q,"readonly").objectStore(Q);return new Promise((n,i)=>{let o,r=s.openCursor();r.onsuccess=async(l)=>{let a=l.target.result;if(a){let{key:d,value:u}=a;if(B(t,u.eid)){if(!o||(u.ctr??0)>(o.data.ctr??0)||(u.ctr??0)===(o.data.ctr??0)&&(u.off??0)>(o.data.off??0))o={key:d,data:u}}a.continue()}else if(o){let d=tt(o.key);n(await Ut(d,o.data,this.crypto))}else n(void 0)},r.onerror=()=>i(r.error)})}async markApplied(t){let e=[...t];if(e.length===0)return;let s=this.db.transaction(Q,"readwrite"),n=s.objectStore(Q);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error);for(let r of e){let l=R(r),a=n.get(l);a.onsuccess=()=>{let d=a.result;if(!d)return;Et(d,wt),n.put(d,l)},a.onerror=(d)=>{d.preventDefault()}}})}async markFailed(t){let e=[...t];if(e.length===0)return;let s=this.db.transaction(Q,"readwrite"),n=s.objectStore(Q);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error);for(let{key:r,err:l}of e){let a=R(r),d=n.get(a);d.onsuccess=()=>{let u=d.result;if(!u)return;Et(u,Zt,l),n.put(u,a)},d.onerror=(u)=>{u.preventDefault()}}})}async wipe(){let t=this.db.transaction(Q,"readwrite"),e=t.objectStore(Q);return new Promise((s,n)=>{t.oncomplete=()=>s(),t.onerror=()=>n(t.error),e.clear()})}}var ys={encode(t,e){let s=t.writeVarString(e.handle);if(s!==0)return s;let n=t.writeVarString(e.label);if(n!==0)return n;return t.writeVarInt(e.idx??0)},decode(t){let[e,s]=t.readVarString();if(s!==0)return c(s);let[n,i]=t.readVarString();if(i!==0)return c(i);let[o,r]=t.readVarInt();if(r!==0)return c(r);return m({handle:e,label:n,idx:o})}};var wn={encode(t,e){let s=t.writeVarInt(e.hosts.length);if(s!==0)return s;for(let n of e.hosts){let i=t.writeStruct(ys,n);if(i!==0)return i}return 0},decode(t){let[e,s]=t.readVarInt();if(s!==0)return c(s);if(e===void 0||e<0)return c(10);let n=[];for(let i=0;i<e;i++){let[o,r]=t.readStruct(ys);if(r!==0)return c(r);if(o===void 0)return c(14);n.push(o)}return m({hosts:n})}};var fl=new TextEncoder().encode("diplomatic.qrpair.v1"),Ue=32,Il=Ue+24+16,Sl=32,Wb=Symbol("DHKEReq"),gb=Symbol("DHKEResp");function Un(t){if(t.byteLength!==Ue)return c(10);return m(t)}function Bn(t){if(t.byteLength<Il)return c(10);return m(t)}var bs=new vt;async function Jn(t,e,s,n){let i;try{i=await bs.x25519Shared(t,e)}catch{return c(29)}try{if(i.byteLength!==Ue||i.every((l)=>l===0))return c(10);let o=St(i,fl),r=St(o,St(s,n));try{let l=await bs.blake3(r);return m(l.slice(0,Sl))}finally{o.fill(0),r.fill(0)}}finally{i.fill(0)}}class Be{#t;#e;constructor(t,e){this.#t=t,this.#e=e}static async create(){let t;try{let e=await bs.genX25519();t=e.priv;let[s,n]=Un(e.pub);if(n!==0)return c(n);if(s===void 0)return c(10);let i=new Be(t,s);return t=void 0,m(i)}catch{return c(29)}finally{t?.fill(0)}}wipe(){this.#t.fill(0)}get dhkeReq(){let[t,e]=Un(this.#e.slice());if(t===void 0)throw Error(`dhkeReq ${e}`);return t}async finish(t){let e=t.subarray(0,Ue),s=t.subarray(Ue),[n,i]=await Jn(this.#t,e,this.#e,e);if(i!==0)return c(i);if(n===void 0)return c(12);let o;try{try{o=await bs.decryptXSalsa20Poly1305Combined(s,n)}catch{return c(20)}let[r,l]=et.fromPairPlain(o);if(l!==0)return c(l);if(r===void 0)return c(12);return this.wipe(),m(r)}finally{n.fill(0),o?.fill(0)}}}function Ht(t){let e=new Uint8Array(t);if(t>0)crypto.getRandomValues(e);return e}var Dt=32,Zs="DIPLOMATIC",ft="public-key",Vl=-7,Wl=-8,gl=-257,Xs=[{type:ft,alg:Vl},{type:ft,alg:Wl},{type:ft,alg:gl}];function Xo(t){return t.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function Bt(t){let e=new Uint8Array(t.byteLength);return e.set(t),e.buffer}function Gs(t){if(t instanceof ArrayBuffer)return new Uint8Array(t).slice();return new Uint8Array(t.buffer,t.byteOffset,t.byteLength).slice()}function Ot(t){if(t?.rpId!==void 0)return m(t.rpId);if(typeof location>"u")return c(9);return m(Xo(location.hostname))}var zn="";function Kl(){return zn}function Jt(t){if(t instanceof Error){zn=t.message===""?t.name:`${t.name}: ${t.message}`;return}zn=String(t)}function fs(t){if(!(t instanceof Error))return!1;return t.name==="NotAllowedError"&&t.message.toLowerCase().includes("does not have focus")}function bo(){if(typeof document>"u")return!0;return document.visibilityState!=="hidden"}function Ge(){if(typeof globalThis.focus!=="function")return;try{globalThis.focus()}catch{}}function Is(t=2500){if(bo())return Ge(),Promise.resolve();return new Promise((e)=>{let s=()=>{clearTimeout(i),document.removeEventListener("visibilitychange",n),Ge(),e()},n=()=>{if(bo())s()},i=setTimeout(s,t);document.addEventListener("visibilitychange",n),n()})}async function Ss(t){await Is();try{return await navigator.credentials.create(t)}catch(e){if(!fs(e))throw e;return Ge(),await navigator.credentials.create(t)}}async function Vs(t){await Is();try{return await navigator.credentials.get(t)}catch(e){if(!fs(e))throw e;return Ge(),await navigator.credentials.get(t)}}function jt(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function At(t){if(t===null||t.type!==ft||!("rawId"in t)||typeof t.getClientExtensionResults!=="function")return c(27);return m(t)}async function Ws(t){if(typeof PublicKeyCredential>"u")return!1;let e=PublicKeyCredential.getClientCapabilities;if(typeof e!=="function")return!0;let s=await e.call(PublicKeyCredential);if(t in s)return s[t]===!0;return!0}function En(t){if(t==="platform"||t==="cross-platform")return t;return}function Go(t){if(/iPhone|iPad|iPod/i.test(t))return"ios";if(/Android/i.test(t))return"android";if(/Mac OS X|Macintosh/i.test(t))return"macos";if(/Windows/i.test(t))return"windows";if(/Linux/i.test(t))return"linux";return"other"}function Fn(t){let e=t.response;if(!("getTransports"in e))return;let s=e.getTransports;if(typeof s!=="function")return;let n=s.call(e);if(!Array.isArray(n))return;let i=[];for(let o of n)if(typeof o==="string"&&o.length>0)i.push(o);return i.length===0?void 0:i}var xl=32,Rl=64,Nn=37,Zo=16;function fo(t){let e=t.response;if(!("getAuthenticatorData"in e))return;let s=e.getAuthenticatorData;if(typeof s!=="function")return;let n=s.call(e);if(!(n instanceof ArrayBuffer))return;let i=new Uint8Array(n);if(i.byteLength<Nn+Zo)return;let o=i[xl];if(o===void 0||(o&Rl)===0)return;return i.slice(Nn,Nn+Zo)}function Hl(){return Ws("extension:largeBlob")}async function Io(t){let e=jt();if(e!==0)return c(e);let[s,n]=Ot(t);if(n!==0)return c(n);if(s===void 0)return c(9);let i=t?.userName??"diplomatic-seed",o={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(t?.authenticatorAttachment!==void 0)o.authenticatorAttachment=t.authenticatorAttachment;let r={largeBlob:{support:"required"}},l;try{l=await Ss({publicKey:{challenge:Ht(Dt),rp:{id:s,name:t?.rpName??Zs},user:{id:Ht(16),name:i,displayName:i},pubKeyCredParams:Xs,authenticatorSelection:o,extensions:r,...t?.hints!==void 0?{hints:t.hints}:{}}})}catch(p){return Jt(p),c(30)}let[a,d]=At(l);if(d!==0)return c(d);if(a===void 0)return c(27);if(a.getClientExtensionResults().largeBlob?.supported!==!0)return c(30);return m(new Uint8Array(a.rawId))}async function Qn(t,e,s,n){let i={challenge:Ht(Dt),rpId:t,userVerification:"preferred"};if(e?.hints!==void 0)i.hints=e.hints;if(s!==void 0)i.allowCredentials=[{type:ft,id:Bt(s)}];if(n!==void 0)i.extensions=n;let o;try{o=await Vs({publicKey:i})}catch(a){return Jt(a),c(30)}let[r,l]=At(o);if(l!==0)return c(l);if(r===void 0)return c(27);return m(r)}async function So(t,e){let s=jt();if(s!==0)return c(s);let[n,i]=Ot(e);if(i!==0)return c(i);if(n===void 0)return c(9);let o=t;if(o===void 0){let[p,h]=await Qn(n,e);if(h!==0&&e?.hints!==void 0)[p,h]=await Qn(n,{rpId:e.rpId,rpName:e.rpName});if(h!==0)return c(h);if(p===void 0)return c(27);o=new Uint8Array(p.rawId)}let[r,l]=await Qn(n,e,o,{largeBlob:{read:!0}});if(l!==0)return c(l);if(r===void 0)return c(27);let d=r.getClientExtensionResults().largeBlob;if(d===void 0||d.blob===void 0)return c(7);let u=Gs(d.blob);if(u.byteLength===0)return c(7);return m({blob:u,credId:new Uint8Array(r.rawId)})}var gs=new TextEncoder().encode("diplomatic.prf.v1"),fe="diplomatic-prf";async function Yl(){return Ws("extension:prf")}var Ks="dmFyIGtlPTY0O3ZhciB2bj0zMix2ZT04O3ZhciBQdD0zMjt2YXIgRG49MzAwMDAsQ249NTEyLFU7KCh4KT0+e3hbeC5TdWNjZXNzPTBdPSJTdWNjZXNzIjt4W3guSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7eFt4LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7eFt4LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7eFt4LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3hbeC5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3hbeC5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt4W3guTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3hbeC5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3hbeC5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt4W3guSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3hbeC5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt4W3guSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7eFt4Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3hbeC5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt4W3guU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt4W3guRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3hbeC5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3hbeC5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3hbeC5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt4W3guTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7eFt4Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3hbeC5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3hbeC5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3hbeC5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7eFt4LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7eFt4LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIjt4W3guQ3J5cHRvRXJyb3I9MjldPSJDcnlwdG9FcnJvciI7eFt4LldlYkF1dGhuRXJyb3I9MzBdPSJXZWJBdXRobkVycm9yIn0pKFV8fD17fSk7ZnVuY3Rpb24gVG4oZSl7aWYoIWV8fHR5cGVvZiBlIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gZSl8fCEoImlkImluIGUpKXJldHVybiExO3JldHVybiB0eXBlb2YgZS5vcD09PSJzdHJpbmciJiZ0eXBlb2YgZS5pZD09PSJudW1iZXIifWZ1bmN0aW9uIEhuKGUpe2xldCB0PWUubGVuZ3RoLHI9MCxuPTA7d2hpbGUobjx0KXtsZXQgcz1lLmNoYXJDb2RlQXQobisrKTtpZigocyY0Mjk0OTY3MTY4KT09PTApe3IrKztjb250aW51ZX1lbHNlIGlmKChzJjQyOTQ5NjUyNDgpPT09MClyKz0yO2Vsc2V7aWYocz49NTUyOTYmJnM8PTU2MzE5KXtpZihuPHQpe2xldCBpPWUuY2hhckNvZGVBdChuKTtpZigoaSY2NDUxMik9PT01NjMyMCkrK24scz0oKHMmMTAyMyk8PDEwKSsoaSYxMDIzKSs2NTUzNn19aWYoKHMmNDI5NDkwMTc2MCk9PT0wKXIrPTM7ZWxzZSByKz00fX1yZXR1cm4gcn1mdW5jdGlvbiBVaShlLHQscil7bGV0IG49ZS5sZW5ndGgscz1yLGk9MDt3aGlsZShpPG4pe2xldCBvPWUuY2hhckNvZGVBdChpKyspO2lmKChvJjQyOTQ5NjcxNjgpPT09MCl7dFtzKytdPW87Y29udGludWV9ZWxzZSBpZigobyY0Mjk0OTY1MjQ4KT09PTApdFtzKytdPW8+PjYmMzF8MTkyO2Vsc2V7aWYobz49NTUyOTYmJm88PTU2MzE5KXtpZihpPG4pe2xldCBhPWUuY2hhckNvZGVBdChpKTtpZigoYSY2NDUxMik9PT01NjMyMCkrK2ksbz0oKG8mMTAyMyk8PDEwKSsoYSYxMDIzKSs2NTUzNn19aWYoKG8mNDI5NDkwMTc2MCk9PT0wKXRbcysrXT1vPj4xMiYxNXwyMjQsdFtzKytdPW8+PjYmNjN8MTI4O2Vsc2UgdFtzKytdPW8+PjE4Jjd8MjQwLHRbcysrXT1vPj4xMiY2M3wxMjgsdFtzKytdPW8+PjYmNjN8MTI4fXRbcysrXT1vJjYzfDEyOH19dmFyIEJpPW5ldyBUZXh0RW5jb2RlcixraT01MDtmdW5jdGlvbiB2aShlLHQscil7QmkuZW5jb2RlSW50byhlLHQuc3ViYXJyYXkocikpfWZ1bmN0aW9uIE1uKGUsdCxyKXtpZihlLmxlbmd0aD5raSl2aShlLHQscik7ZWxzZSBVaShlLHQscil9dmFyIERpPTQwOTY7ZnVuY3Rpb24geXIoZSx0LHIpe2xldCBuPXQscz1uK3IsaT1bXSxvPSIiO3doaWxlKG48cyl7bGV0IGE9ZVtuKytdO2lmKChhJjEyOCk9PT0wKWkucHVzaChhKTtlbHNlIGlmKChhJjIyNCk9PT0xOTIpe2xldCBkPWVbbisrXSY2MztpLnB1c2goKGEmMzEpPDw2fGQpfWVsc2UgaWYoKGEmMjQwKT09PTIyNCl7bGV0IGQ9ZVtuKytdJjYzLHU9ZVtuKytdJjYzO2kucHVzaCgoYSYzMSk8PDEyfGQ8PDZ8dSl9ZWxzZSBpZigoYSYyNDgpPT09MjQwKXtsZXQgZD1lW24rK10mNjMsdT1lW24rK10mNjMsbD1lW24rK10mNjMsZj0oYSY3KTw8MTh8ZDw8MTJ8dTw8NnxsO2lmKGY+NjU1MzUpZi09NjU1MzYsaS5wdXNoKGY+Pj4xMCYxMDIzfDU1Mjk2KSxmPTU2MzIwfGYmMTAyMztpLnB1c2goZil9ZWxzZSBpLnB1c2goYSk7aWYoaS5sZW5ndGg+PURpKW8rPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uaSksaS5sZW5ndGg9MH1pZihpLmxlbmd0aD4wKW8rPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uaSk7cmV0dXJuIG99dmFyIENpPW5ldyBUZXh0RGVjb2RlcixUaT0yMDA7ZnVuY3Rpb24gSGkoZSx0LHIpe2xldCBuPWUuc3ViYXJyYXkodCx0K3IpO3JldHVybiBDaS5kZWNvZGUobil9ZnVuY3Rpb24gUm4oZSx0LHIpe2lmKHI+VGkpcmV0dXJuIEhpKGUsdCxyKTtlbHNlIHJldHVybiB5cihlLHQscil9Y2xhc3MgJGV7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKGUsdCl7dGhpcy50eXBlPWUsdGhpcy5kYXRhPXR9fWNsYXNzIGVlIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoZSl7c3VwZXIoZSk7bGV0IHQ9T2JqZWN0LmNyZWF0ZShlZS5wcm90b3R5cGUpO09iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLHQpLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJuYW1lIix7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITEsdmFsdWU6ZWUubmFtZX0pfX12YXIgUWU9NDI5NDk2NzI5NTtmdW5jdGlvbiBMbihlLHQscil7bGV0IG49ci80Mjk0OTY3Mjk2LHM9cjtlLnNldFVpbnQzMih0LG4pLGUuc2V0VWludDMyKHQrNCxzKX1mdW5jdGlvbiBVdChlLHQscil7bGV0IG49TWF0aC5mbG9vcihyLzQyOTQ5NjcyOTYpLHM9cjtlLnNldFVpbnQzMih0LG4pLGUuc2V0VWludDMyKHQrNCxzKX1mdW5jdGlvbiBCdChlLHQpe2xldCByPWUuZ2V0SW50MzIodCksbj1lLmdldFVpbnQzMih0KzQpO3JldHVybiByKjQyOTQ5NjcyOTYrbn1mdW5jdGlvbiBPbihlLHQpe2xldCByPWUuZ2V0VWludDMyKHQpLG49ZS5nZXRVaW50MzIodCs0KTtyZXR1cm4gcio0Mjk0OTY3Mjk2K259dmFyIE1pPS0xLFJpPTQyOTQ5NjcyOTUsTGk9MTcxNzk4NjkxODM7ZnVuY3Rpb24gT2koe3NlYzplLG5zZWM6dH0pe2lmKGU+PTAmJnQ+PTAmJmU8PUxpKWlmKHQ9PT0wJiZlPD1SaSl7bGV0IHI9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhyLmJ1ZmZlcikuc2V0VWludDMyKDAsZSkscn1lbHNle2xldCByPWUvNDI5NDk2NzI5NixuPWUmNDI5NDk2NzI5NSxzPW5ldyBVaW50OEFycmF5KDgpLGk9bmV3IERhdGFWaWV3KHMuYnVmZmVyKTtyZXR1cm4gaS5zZXRVaW50MzIoMCx0PDwyfHImMyksaS5zZXRVaW50MzIoNCxuKSxzfWVsc2V7bGV0IHI9bmV3IFVpbnQ4QXJyYXkoMTIpLG49bmV3IERhdGFWaWV3KHIuYnVmZmVyKTtyZXR1cm4gbi5zZXRVaW50MzIoMCx0KSxVdChuLDQsZSkscn19ZnVuY3Rpb24gS2koZSl7bGV0IHQ9ZS5nZXRUaW1lKCkscj1NYXRoLmZsb29yKHQvMTAwMCksbj0odC1yKjEwMDApKjFlNixzPU1hdGguZmxvb3Iobi8xZTkpO3JldHVybntzZWM6citzLG5zZWM6bi1zKjFlOX19ZnVuY3Rpb24gVmkoZSl7aWYoZSBpbnN0YW5jZW9mIERhdGUpe2xldCB0PUtpKGUpO3JldHVybiBPaSh0KX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIF9pKGUpe2xldCB0PW5ldyBEYXRhVmlldyhlLmJ1ZmZlcixlLmJ5dGVPZmZzZXQsZS5ieXRlTGVuZ3RoKTtzd2l0Y2goZS5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCByPXQuZ2V0VWludDMyKDApLG49MDtyZXR1cm57c2VjOnIsbnNlYzowfX1jYXNlIDg6e2xldCByPXQuZ2V0VWludDMyKDApLG49dC5nZXRVaW50MzIoNCkscz0ociYzKSo0Mjk0OTY3Mjk2K24saT1yPj4+MjtyZXR1cm57c2VjOnMsbnNlYzppfX1jYXNlIDEyOntsZXQgcj1CdCh0LDQpLG49dC5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpyLG5zZWM6bn19ZGVmYXVsdDp0aHJvdyBuZXcgZWUoYFVucmVjb2duaXplZCBkYXRhIHNpemUgZm9yIHRpbWVzdGFtcCAoZXhwZWN0ZWQgNCwgOCwgb3IgMTIpOiAke2UubGVuZ3RofWApfX1mdW5jdGlvbiBOaShlKXtsZXQgdD1faShlKTtyZXR1cm4gbmV3IERhdGUodC5zZWMqMTAwMCt0Lm5zZWMvMWU2KX12YXIgS249e3R5cGU6TWksZW5jb2RlOlZpLGRlY29kZTpOaX07Y2xhc3MgWWV7c3RhdGljIGRlZmF1bHRDb2RlYz1uZXcgWWU7X19icmFuZDtidWlsdEluRW5jb2RlcnM9W107YnVpbHRJbkRlY29kZXJzPVtdO2VuY29kZXJzPVtdO2RlY29kZXJzPVtdO2NvbnN0cnVjdG9yKCl7dGhpcy5yZWdpc3RlcihLbil9cmVnaXN0ZXIoe3R5cGU6ZSxlbmNvZGU6dCxkZWNvZGU6cn0pe2lmKGU+PTApdGhpcy5lbmNvZGVyc1tlXT10LHRoaXMuZGVjb2RlcnNbZV09cjtlbHNle2xldCBuPS0xLWU7dGhpcy5idWlsdEluRW5jb2RlcnNbbl09dCx0aGlzLmJ1aWx0SW5EZWNvZGVyc1tuXT1yfX10cnlUb0VuY29kZShlLHQpe2ZvcihsZXQgcj0wO3I8dGhpcy5idWlsdEluRW5jb2RlcnMubGVuZ3RoO3IrKyl7bGV0IG49dGhpcy5idWlsdEluRW5jb2RlcnNbcl07aWYobiE9bnVsbCl7bGV0IHM9bihlLHQpO2lmKHMhPW51bGwpe2xldCBpPS0xLXI7cmV0dXJuIG5ldyAkZShpLHMpfX19Zm9yKGxldCByPTA7cjx0aGlzLmVuY29kZXJzLmxlbmd0aDtyKyspe2xldCBuPXRoaXMuZW5jb2RlcnNbcl07aWYobiE9bnVsbCl7bGV0IHM9bihlLHQpO2lmKHMhPW51bGwpcmV0dXJuIG5ldyAkZShyLHMpfX1pZihlIGluc3RhbmNlb2YgJGUpcmV0dXJuIGU7cmV0dXJuIG51bGx9ZGVjb2RlKGUsdCxyKXtsZXQgbj10PDA/dGhpcy5idWlsdEluRGVjb2RlcnNbLTEtdF06dGhpcy5kZWNvZGVyc1t0XTtpZihuKXJldHVybiBuKGUsdCxyKTtlbHNlIHJldHVybiBuZXcgJGUodCxlKX19ZnVuY3Rpb24gcWkoZSl7cmV0dXJuIGUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyPCJ1IiYmZSBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyfWZ1bmN0aW9uIHV0KGUpe2lmKGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybiBlO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KGUpKXJldHVybiBuZXcgVWludDhBcnJheShlLmJ1ZmZlcixlLmJ5dGVPZmZzZXQsZS5ieXRlTGVuZ3RoKTtlbHNlIGlmKHFpKGUpKXJldHVybiBuZXcgVWludDhBcnJheShlKTtlbHNlIHJldHVybiBVaW50OEFycmF5LmZyb20oZSl9dmFyIEZpPTEwMCxXaT0yMDQ4O2NsYXNzIGt0e2V4dGVuc2lvbkNvZGVjO2NvbnRleHQ7dXNlQmlnSW50NjQ7bWF4RGVwdGg7aW5pdGlhbEJ1ZmZlclNpemU7c29ydEtleXM7Zm9yY2VGbG9hdDMyO2lnbm9yZVVuZGVmaW5lZDtmb3JjZUludGVnZXJUb0Zsb2F0O3Bvczt2aWV3O2J5dGVzO2VudGVyZWQ9ITE7Y29uc3RydWN0b3IoZSl7dGhpcy5leHRlbnNpb25Db2RlYz1lPy5leHRlbnNpb25Db2RlYz8/WWUuZGVmYXVsdENvZGVjLHRoaXMuY29udGV4dD1lPy5jb250ZXh0LHRoaXMudXNlQmlnSW50NjQ9ZT8udXNlQmlnSW50NjQ/PyExLHRoaXMubWF4RGVwdGg9ZT8ubWF4RGVwdGg/P0ZpLHRoaXMuaW5pdGlhbEJ1ZmZlclNpemU9ZT8uaW5pdGlhbEJ1ZmZlclNpemU/P1dpLHRoaXMuc29ydEtleXM9ZT8uc29ydEtleXM/PyExLHRoaXMuZm9yY2VGbG9hdDMyPWU/LmZvcmNlRmxvYXQzMj8/ITEsdGhpcy5pZ25vcmVVbmRlZmluZWQ9ZT8uaWdub3JlVW5kZWZpbmVkPz8hMSx0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXQ9ZT8uZm9yY2VJbnRlZ2VyVG9GbG9hdD8/ITEsdGhpcy5wb3M9MCx0aGlzLnZpZXc9bmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcih0aGlzLmluaXRpYWxCdWZmZXJTaXplKSksdGhpcy5ieXRlcz1uZXcgVWludDhBcnJheSh0aGlzLnZpZXcuYnVmZmVyKX1jbG9uZSgpe3JldHVybiBuZXcga3Qoe2V4dGVuc2lvbkNvZGVjOnRoaXMuZXh0ZW5zaW9uQ29kZWMsY29udGV4dDp0aGlzLmNvbnRleHQsdXNlQmlnSW50NjQ6dGhpcy51c2VCaWdJbnQ2NCxtYXhEZXB0aDp0aGlzLm1heERlcHRoLGluaXRpYWxCdWZmZXJTaXplOnRoaXMuaW5pdGlhbEJ1ZmZlclNpemUsc29ydEtleXM6dGhpcy5zb3J0S2V5cyxmb3JjZUZsb2F0MzI6dGhpcy5mb3JjZUZsb2F0MzIsaWdub3JlVW5kZWZpbmVkOnRoaXMuaWdub3JlVW5kZWZpbmVkLGZvcmNlSW50ZWdlclRvRmxvYXQ6dGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0fSl9cmVpbml0aWFsaXplU3RhdGUoKXt0aGlzLnBvcz0wfWVuY29kZVNoYXJlZFJlZihlKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGVTaGFyZWRSZWYoZSk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoZSwxKSx0aGlzLmJ5dGVzLnN1YmFycmF5KDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1lbmNvZGUoZSl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZW5jb2RlKGUpO3RyeXtyZXR1cm4gdGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLmRvRW5jb2RlKGUsMSksdGhpcy5ieXRlcy5zbGljZSgwLHRoaXMucG9zKX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19ZG9FbmNvZGUoZSx0KXtpZih0PnRoaXMubWF4RGVwdGgpdGhyb3cgRXJyb3IoYFRvbyBkZWVwIG9iamVjdHMgaW4gZGVwdGggJHt0fWApO2lmKGU9PW51bGwpdGhpcy5lbmNvZGVOaWwoKTtlbHNlIGlmKHR5cGVvZiBlPT09ImJvb2xlYW4iKXRoaXMuZW5jb2RlQm9vbGVhbihlKTtlbHNlIGlmKHR5cGVvZiBlPT09Im51bWJlciIpaWYoIXRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdCl0aGlzLmVuY29kZU51bWJlcihlKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdChlKTtlbHNlIGlmKHR5cGVvZiBlPT09InN0cmluZyIpdGhpcy5lbmNvZGVTdHJpbmcoZSk7ZWxzZSBpZih0aGlzLnVzZUJpZ0ludDY0JiZ0eXBlb2YgZT09PSJiaWdpbnQiKXRoaXMuZW5jb2RlQmlnSW50NjQoZSk7ZWxzZSB0aGlzLmVuY29kZU9iamVjdChlLHQpfWVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKGUpe2xldCB0PXRoaXMucG9zK2U7aWYodGhpcy52aWV3LmJ5dGVMZW5ndGg8dCl0aGlzLnJlc2l6ZUJ1ZmZlcih0KjIpfXJlc2l6ZUJ1ZmZlcihlKXtsZXQgdD1uZXcgQXJyYXlCdWZmZXIoZSkscj1uZXcgVWludDhBcnJheSh0KSxuPW5ldyBEYXRhVmlldyh0KTtyLnNldCh0aGlzLmJ5dGVzKSx0aGlzLnZpZXc9bix0aGlzLmJ5dGVzPXJ9ZW5jb2RlTmlsKCl7dGhpcy53cml0ZVU4KDE5Mil9ZW5jb2RlQm9vbGVhbihlKXtpZihlPT09ITEpdGhpcy53cml0ZVU4KDE5NCk7ZWxzZSB0aGlzLndyaXRlVTgoMTk1KX1lbmNvZGVOdW1iZXIoZSl7aWYoIXRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdCYmTnVtYmVyLmlzU2FmZUludGVnZXIoZSkpaWYoZT49MClpZihlPDEyOCl0aGlzLndyaXRlVTgoZSk7ZWxzZSBpZihlPDI1Nil0aGlzLndyaXRlVTgoMjA0KSx0aGlzLndyaXRlVTgoZSk7ZWxzZSBpZihlPDY1NTM2KXRoaXMud3JpdGVVOCgyMDUpLHRoaXMud3JpdGVVMTYoZSk7ZWxzZSBpZihlPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDIwNiksdGhpcy53cml0ZVUzMihlKTtlbHNlIGlmKCF0aGlzLnVzZUJpZ0ludDY0KXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVVNjQoZSk7ZWxzZSB0aGlzLmVuY29kZU51bWJlckFzRmxvYXQoZSk7ZWxzZSBpZihlPj0tMzIpdGhpcy53cml0ZVU4KDIyNHxlKzMyKTtlbHNlIGlmKGU+PS0xMjgpdGhpcy53cml0ZVU4KDIwOCksdGhpcy53cml0ZUk4KGUpO2Vsc2UgaWYoZT49LTMyNzY4KXRoaXMud3JpdGVVOCgyMDkpLHRoaXMud3JpdGVJMTYoZSk7ZWxzZSBpZihlPj0tMjE0NzQ4MzY0OCl0aGlzLndyaXRlVTgoMjEwKSx0aGlzLndyaXRlSTMyKGUpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIxMSksdGhpcy53cml0ZUk2NChlKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdChlKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdChlKX1lbmNvZGVOdW1iZXJBc0Zsb2F0KGUpe2lmKHRoaXMuZm9yY2VGbG9hdDMyKXRoaXMud3JpdGVVOCgyMDIpLHRoaXMud3JpdGVGMzIoZSk7ZWxzZSB0aGlzLndyaXRlVTgoMjAzKSx0aGlzLndyaXRlRjY0KGUpfWVuY29kZUJpZ0ludDY0KGUpe2lmKGU+PUJpZ0ludCgwKSl0aGlzLndyaXRlVTgoMjA3KSx0aGlzLndyaXRlQmlnVWludDY0KGUpO2Vsc2UgdGhpcy53cml0ZVU4KDIxMSksdGhpcy53cml0ZUJpZ0ludDY0KGUpfXdyaXRlU3RyaW5nSGVhZGVyKGUpe2lmKGU8MzIpdGhpcy53cml0ZVU4KDE2MCtlKTtlbHNlIGlmKGU8MjU2KXRoaXMud3JpdGVVOCgyMTcpLHRoaXMud3JpdGVVOChlKTtlbHNlIGlmKGU8NjU1MzYpdGhpcy53cml0ZVU4KDIxOCksdGhpcy53cml0ZVUxNihlKTtlbHNlIGlmKGU8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjE5KSx0aGlzLndyaXRlVTMyKGUpO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsb25nIHN0cmluZzogJHtlfSBieXRlcyBpbiBVVEYtOGApfWVuY29kZVN0cmluZyhlKXtsZXQgcj1IbihlKTt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDUrciksdGhpcy53cml0ZVN0cmluZ0hlYWRlcihyKSxNbihlLHRoaXMuYnl0ZXMsdGhpcy5wb3MpLHRoaXMucG9zKz1yfWVuY29kZU9iamVjdChlLHQpe2xldCByPXRoaXMuZXh0ZW5zaW9uQ29kZWMudHJ5VG9FbmNvZGUoZSx0aGlzLmNvbnRleHQpO2lmKHIhPW51bGwpdGhpcy5lbmNvZGVFeHRlbnNpb24ocik7ZWxzZSBpZihBcnJheS5pc0FycmF5KGUpKXRoaXMuZW5jb2RlQXJyYXkoZSx0KTtlbHNlIGlmKEFycmF5QnVmZmVyLmlzVmlldyhlKSl0aGlzLmVuY29kZUJpbmFyeShlKTtlbHNlIGlmKHR5cGVvZiBlPT09Im9iamVjdCIpdGhpcy5lbmNvZGVNYXAoZSx0KTtlbHNlIHRocm93IEVycm9yKGBVbnJlY29nbml6ZWQgb2JqZWN0OiAke09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuYXBwbHkoZSl9YCl9ZW5jb2RlQmluYXJ5KGUpe2xldCB0PWUuYnl0ZUxlbmd0aDtpZih0PDI1Nil0aGlzLndyaXRlVTgoMTk2KSx0aGlzLndyaXRlVTgodCk7ZWxzZSBpZih0PDY1NTM2KXRoaXMud3JpdGVVOCgxOTcpLHRoaXMud3JpdGVVMTYodCk7ZWxzZSBpZih0PDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDE5OCksdGhpcy53cml0ZVUzMih0KTtlbHNlIHRocm93IEVycm9yKGBUb28gbGFyZ2UgYmluYXJ5OiAke3R9YCk7bGV0IHI9dXQoZSk7dGhpcy53cml0ZVU4YShyKX1lbmNvZGVBcnJheShlLHQpe2xldCByPWUubGVuZ3RoO2lmKHI8MTYpdGhpcy53cml0ZVU4KDE0NCtyKTtlbHNlIGlmKHI8NjU1MzYpdGhpcy53cml0ZVU4KDIyMCksdGhpcy53cml0ZVUxNihyKTtlbHNlIGlmKHI8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjIxKSx0aGlzLndyaXRlVTMyKHIpO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBhcnJheTogJHtyfWApO2ZvcihsZXQgbiBvZiBlKXRoaXMuZG9FbmNvZGUobix0KzEpfWNvdW50V2l0aG91dFVuZGVmaW5lZChlLHQpe2xldCByPTA7Zm9yKGxldCBuIG9mIHQpaWYoZVtuXSE9PXZvaWQgMClyKys7cmV0dXJuIHJ9ZW5jb2RlTWFwKGUsdCl7bGV0IHI9T2JqZWN0LmtleXMoZSk7aWYodGhpcy5zb3J0S2V5cylyLnNvcnQoKTtsZXQgbj10aGlzLmlnbm9yZVVuZGVmaW5lZD90aGlzLmNvdW50V2l0aG91dFVuZGVmaW5lZChlLHIpOnIubGVuZ3RoO2lmKG48MTYpdGhpcy53cml0ZVU4KDEyOCtuKTtlbHNlIGlmKG48NjU1MzYpdGhpcy53cml0ZVU4KDIyMiksdGhpcy53cml0ZVUxNihuKTtlbHNlIGlmKG48NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjIzKSx0aGlzLndyaXRlVTMyKG4pO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBtYXAgb2JqZWN0OiAke259YCk7Zm9yKGxldCBzIG9mIHIpe2xldCBpPWVbc107aWYoISh0aGlzLmlnbm9yZVVuZGVmaW5lZCYmaT09PXZvaWQgMCkpdGhpcy5lbmNvZGVTdHJpbmcocyksdGhpcy5kb0VuY29kZShpLHQrMSl9fWVuY29kZUV4dGVuc2lvbihlKXtpZih0eXBlb2YgZS5kYXRhPT09ImZ1bmN0aW9uIil7bGV0IHI9ZS5kYXRhKHRoaXMucG9zKzYpLG49ci5sZW5ndGg7aWYobj49NDI5NDk2NzI5Nil0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGV4dGVuc2lvbiBvYmplY3Q6ICR7bn1gKTt0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKG4pLHRoaXMud3JpdGVJOChlLnR5cGUpLHRoaXMud3JpdGVVOGEocik7cmV0dXJufWxldCB0PWUuZGF0YS5sZW5ndGg7aWYodD09PTEpdGhpcy53cml0ZVU4KDIxMik7ZWxzZSBpZih0PT09Mil0aGlzLndyaXRlVTgoMjEzKTtlbHNlIGlmKHQ9PT00KXRoaXMud3JpdGVVOCgyMTQpO2Vsc2UgaWYodD09PTgpdGhpcy53cml0ZVU4KDIxNSk7ZWxzZSBpZih0PT09MTYpdGhpcy53cml0ZVU4KDIxNik7ZWxzZSBpZih0PDI1Nil0aGlzLndyaXRlVTgoMTk5KSx0aGlzLndyaXRlVTgodCk7ZWxzZSBpZih0PDY1NTM2KXRoaXMud3JpdGVVOCgyMDApLHRoaXMud3JpdGVVMTYodCk7ZWxzZSBpZih0PDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDIwMSksdGhpcy53cml0ZVUzMih0KTtlbHNlIHRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHt0fWApO3RoaXMud3JpdGVJOChlLnR5cGUpLHRoaXMud3JpdGVVOGEoZS5kYXRhKX13cml0ZVU4KGUpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMSksdGhpcy52aWV3LnNldFVpbnQ4KHRoaXMucG9zLGUpLHRoaXMucG9zKyt9d3JpdGVVOGEoZSl7bGV0IHQ9ZS5sZW5ndGg7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSh0KSx0aGlzLmJ5dGVzLnNldChlLHRoaXMucG9zKSx0aGlzLnBvcys9dH13cml0ZUk4KGUpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMSksdGhpcy52aWV3LnNldEludDgodGhpcy5wb3MsZSksdGhpcy5wb3MrK313cml0ZVUxNihlKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRVaW50MTYodGhpcy5wb3MsZSksdGhpcy5wb3MrPTJ9d3JpdGVJMTYoZSl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgyKSx0aGlzLnZpZXcuc2V0SW50MTYodGhpcy5wb3MsZSksdGhpcy5wb3MrPTJ9d3JpdGVVMzIoZSl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0VWludDMyKHRoaXMucG9zLGUpLHRoaXMucG9zKz00fXdyaXRlSTMyKGUpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNCksdGhpcy52aWV3LnNldEludDMyKHRoaXMucG9zLGUpLHRoaXMucG9zKz00fXdyaXRlRjMyKGUpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNCksdGhpcy52aWV3LnNldEZsb2F0MzIodGhpcy5wb3MsZSksdGhpcy5wb3MrPTR9d3JpdGVGNjQoZSl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg4KSx0aGlzLnZpZXcuc2V0RmxvYXQ2NCh0aGlzLnBvcyxlKSx0aGlzLnBvcys9OH13cml0ZVU2NChlKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLExuKHRoaXMudmlldyx0aGlzLnBvcyxlKSx0aGlzLnBvcys9OH13cml0ZUk2NChlKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLFV0KHRoaXMudmlldyx0aGlzLnBvcyxlKSx0aGlzLnBvcys9OH13cml0ZUJpZ1VpbnQ2NChlKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5wb3MsZSksdGhpcy5wb3MrPTh9d3JpdGVCaWdJbnQ2NChlKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRCaWdJbnQ2NCh0aGlzLnBvcyxlKSx0aGlzLnBvcys9OH19ZnVuY3Rpb24gTWUoZSx0KXtyZXR1cm4gbmV3IGt0KHQpLmVuY29kZVNoYXJlZFJlZihlKX1mdW5jdGlvbiB2dChlKXtyZXR1cm5gJHtlPDA/Ii0iOiIifTB4JHtNYXRoLmFicyhlKS50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpfWB9dmFyIHppPTE2LFhpPTE2O2NsYXNzIG1ye2hpdD0wO21pc3M9MDtjYWNoZXM7bWF4S2V5TGVuZ3RoO21heExlbmd0aFBlcktleTtjb25zdHJ1Y3RvcihlPXppLHQ9WGkpe3RoaXMubWF4S2V5TGVuZ3RoPWUsdGhpcy5tYXhMZW5ndGhQZXJLZXk9dCx0aGlzLmNhY2hlcz1bXTtmb3IobGV0IHI9MDtyPHRoaXMubWF4S2V5TGVuZ3RoO3IrKyl0aGlzLmNhY2hlcy5wdXNoKFtdKX1jYW5CZUNhY2hlZChlKXtyZXR1cm4gZT4wJiZlPD10aGlzLm1heEtleUxlbmd0aH1maW5kKGUsdCxyKXtsZXQgbj10aGlzLmNhY2hlc1tyLTFdO2U6Zm9yKGxldCBzIG9mIG4pe2xldCBpPXMuYnl0ZXM7Zm9yKGxldCBvPTA7bzxyO28rKylpZihpW29dIT09ZVt0K29dKWNvbnRpbnVlIGU7cmV0dXJuIHMuc3RyfXJldHVybiBudWxsfXN0b3JlKGUsdCl7bGV0IHI9dGhpcy5jYWNoZXNbZS5sZW5ndGgtMV0sbj17Ynl0ZXM6ZSxzdHI6dH07aWYoci5sZW5ndGg+PXRoaXMubWF4TGVuZ3RoUGVyS2V5KXJbTWF0aC5yYW5kb20oKSpyLmxlbmd0aHwwXT1uO2Vsc2Ugci5wdXNoKG4pfWRlY29kZShlLHQscil7bGV0IG49dGhpcy5maW5kKGUsdCxyKTtpZihuIT1udWxsKXJldHVybiB0aGlzLmhpdCsrLG47dGhpcy5taXNzKys7bGV0IHM9eXIoZSx0LHIpLGk9VWludDhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChlLHQsdCtyKTtyZXR1cm4gdGhpcy5zdG9yZShpLHMpLHN9fXZhciBncj0iYXJyYXkiLGZ0PSJtYXBfa2V5Iixfbj0ibWFwX3ZhbHVlIixqaT0oZSk9PntpZih0eXBlb2YgZT09PSJzdHJpbmcifHx0eXBlb2YgZT09PSJudW1iZXIiKXJldHVybiBlO3Rocm93IG5ldyBlZSgiVGhlIHR5cGUgb2Yga2V5IG11c3QgYmUgc3RyaW5nIG9yIG51bWJlciBidXQgIit0eXBlb2YgZSl9O2NsYXNzIE5ue3N0YWNrPVtdO3N0YWNrSGVhZFBvc2l0aW9uPS0xO2dldCBsZW5ndGgoKXtyZXR1cm4gdGhpcy5zdGFja0hlYWRQb3NpdGlvbisxfXRvcCgpe3JldHVybiB0aGlzLnN0YWNrW3RoaXMuc3RhY2tIZWFkUG9zaXRpb25dfXB1c2hBcnJheVN0YXRlKGUpe2xldCB0PXRoaXMuZ2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKTt0LnR5cGU9Z3IsdC5wb3NpdGlvbj0wLHQuc2l6ZT1lLHQuYXJyYXk9QXJyYXkoZSl9cHVzaE1hcFN0YXRlKGUpe2xldCB0PXRoaXMuZ2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKTt0LnR5cGU9ZnQsdC5yZWFkQ291bnQ9MCx0LnNpemU9ZSx0Lm1hcD17fX1nZXRVbmluaXRpYWxpemVkU3RhdGVGcm9tUG9vbCgpe2lmKHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rKyx0aGlzLnN0YWNrSGVhZFBvc2l0aW9uPT09dGhpcy5zdGFjay5sZW5ndGgpe2xldCBlPXt0eXBlOnZvaWQgMCxzaXplOjAsYXJyYXk6dm9pZCAwLHBvc2l0aW9uOjAscmVhZENvdW50OjAsbWFwOnZvaWQgMCxrZXk6bnVsbH07dGhpcy5zdGFjay5wdXNoKGUpfXJldHVybiB0aGlzLnN0YWNrW3RoaXMuc3RhY2tIZWFkUG9zaXRpb25dfXJlbGVhc2UoZSl7aWYodGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXSE9PWUpdGhyb3cgRXJyb3IoIkludmFsaWQgc3RhY2sgc3RhdGUuIFJlbGVhc2VkIHN0YXRlIGlzIG5vdCBvbiB0b3Agb2YgdGhlIHN0YWNrLiIpO2lmKGUudHlwZT09PWdyKXtsZXQgcj1lO3Iuc2l6ZT0wLHIuYXJyYXk9dm9pZCAwLHIucG9zaXRpb249MCxyLnR5cGU9dm9pZCAwfWlmKGUudHlwZT09PWZ0fHxlLnR5cGU9PT1fbil7bGV0IHI9ZTtyLnNpemU9MCxyLm1hcD12b2lkIDAsci5yZWFkQ291bnQ9MCxyLnR5cGU9dm9pZCAwfXRoaXMuc3RhY2tIZWFkUG9zaXRpb24tLX1yZXNldCgpe3RoaXMuc3RhY2subGVuZ3RoPTAsdGhpcy5zdGFja0hlYWRQb3NpdGlvbj0tMX19dmFyIGx0PS0xLGJyPW5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoMCkpLEdpPW5ldyBVaW50OEFycmF5KGJyLmJ1ZmZlcik7dHJ5e2JyLmdldEludDgoMCl9Y2F0Y2goZSl7aWYoIShlIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgRXJyb3IoIlRoaXMgbW9kdWxlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGN1cnJlbnQgSmF2YVNjcmlwdCBlbmdpbmUgYmVjYXVzZSBEYXRhVmlldyBkb2VzIG5vdCB0aHJvdyBSYW5nZUVycm9yIG9uIG91dC1vZi1ib3VuZHMgYWNjZXNzIil9dmFyIFZuPVJhbmdlRXJyb3IoIkluc3VmZmljaWVudCBkYXRhIiksJGk9bmV3IG1yO2NsYXNzIER0e2V4dGVuc2lvbkNvZGVjO2NvbnRleHQ7dXNlQmlnSW50NjQ7cmF3U3RyaW5nczttYXhTdHJMZW5ndGg7bWF4QmluTGVuZ3RoO21heEFycmF5TGVuZ3RoO21heE1hcExlbmd0aDttYXhFeHRMZW5ndGg7a2V5RGVjb2RlcjttYXBLZXlDb252ZXJ0ZXI7dG90YWxQb3M9MDtwb3M9MDt2aWV3PWJyO2J5dGVzPUdpO2hlYWRCeXRlPWx0O3N0YWNrPW5ldyBObjtlbnRlcmVkPSExO2NvbnN0cnVjdG9yKGUpe3RoaXMuZXh0ZW5zaW9uQ29kZWM9ZT8uZXh0ZW5zaW9uQ29kZWM/P1llLmRlZmF1bHRDb2RlYyx0aGlzLmNvbnRleHQ9ZT8uY29udGV4dCx0aGlzLnVzZUJpZ0ludDY0PWU/LnVzZUJpZ0ludDY0Pz8hMSx0aGlzLnJhd1N0cmluZ3M9ZT8ucmF3U3RyaW5ncz8/ITEsdGhpcy5tYXhTdHJMZW5ndGg9ZT8ubWF4U3RyTGVuZ3RoPz9RZSx0aGlzLm1heEJpbkxlbmd0aD1lPy5tYXhCaW5MZW5ndGg/P1FlLHRoaXMubWF4QXJyYXlMZW5ndGg9ZT8ubWF4QXJyYXlMZW5ndGg/P1FlLHRoaXMubWF4TWFwTGVuZ3RoPWU/Lm1heE1hcExlbmd0aD8/UWUsdGhpcy5tYXhFeHRMZW5ndGg9ZT8ubWF4RXh0TGVuZ3RoPz9RZSx0aGlzLmtleURlY29kZXI9ZT8ua2V5RGVjb2RlciE9PXZvaWQgMD9lLmtleURlY29kZXI6JGksdGhpcy5tYXBLZXlDb252ZXJ0ZXI9ZT8ubWFwS2V5Q29udmVydGVyPz9qaX1jbG9uZSgpe3JldHVybiBuZXcgRHQoe2V4dGVuc2lvbkNvZGVjOnRoaXMuZXh0ZW5zaW9uQ29kZWMsY29udGV4dDp0aGlzLmNvbnRleHQsdXNlQmlnSW50NjQ6dGhpcy51c2VCaWdJbnQ2NCxyYXdTdHJpbmdzOnRoaXMucmF3U3RyaW5ncyxtYXhTdHJMZW5ndGg6dGhpcy5tYXhTdHJMZW5ndGgsbWF4QmluTGVuZ3RoOnRoaXMubWF4QmluTGVuZ3RoLG1heEFycmF5TGVuZ3RoOnRoaXMubWF4QXJyYXlMZW5ndGgsbWF4TWFwTGVuZ3RoOnRoaXMubWF4TWFwTGVuZ3RoLG1heEV4dExlbmd0aDp0aGlzLm1heEV4dExlbmd0aCxrZXlEZWNvZGVyOnRoaXMua2V5RGVjb2Rlcn0pfXJlaW5pdGlhbGl6ZVN0YXRlKCl7dGhpcy50b3RhbFBvcz0wLHRoaXMuaGVhZEJ5dGU9bHQsdGhpcy5zdGFjay5yZXNldCgpfXNldEJ1ZmZlcihlKXtsZXQgdD11dChlKTt0aGlzLmJ5dGVzPXQsdGhpcy52aWV3PW5ldyBEYXRhVmlldyh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQsdC5ieXRlTGVuZ3RoKSx0aGlzLnBvcz0wfWFwcGVuZEJ1ZmZlcihlKXtpZih0aGlzLmhlYWRCeXRlPT09bHQmJiF0aGlzLmhhc1JlbWFpbmluZygxKSl0aGlzLnNldEJ1ZmZlcihlKTtlbHNle2xldCB0PXRoaXMuYnl0ZXMuc3ViYXJyYXkodGhpcy5wb3MpLHI9dXQoZSksbj1uZXcgVWludDhBcnJheSh0Lmxlbmd0aCtyLmxlbmd0aCk7bi5zZXQodCksbi5zZXQocix0Lmxlbmd0aCksdGhpcy5zZXRCdWZmZXIobil9fWhhc1JlbWFpbmluZyhlKXtyZXR1cm4gdGhpcy52aWV3LmJ5dGVMZW5ndGgtdGhpcy5wb3M+PWV9Y3JlYXRlRXh0cmFCeXRlRXJyb3IoZSl7bGV0e3ZpZXc6dCxwb3M6cn09dGhpcztyZXR1cm4gUmFuZ2VFcnJvcihgRXh0cmEgJHt0LmJ5dGVMZW5ndGgtcn0gb2YgJHt0LmJ5dGVMZW5ndGh9IGJ5dGUocykgZm91bmQgYXQgYnVmZmVyWyR7ZX1dYCl9ZGVjb2RlKGUpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmRlY29kZShlKTt0cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcihlKTtsZXQgdD10aGlzLmRvRGVjb2RlU3luYygpO2lmKHRoaXMuaGFzUmVtYWluaW5nKDEpKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy5wb3MpO3JldHVybiB0fWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX0qZGVjb2RlTXVsdGkoZSl7aWYodGhpcy5lbnRlcmVkKXt5aWVsZCp0aGlzLmNsb25lKCkuZGVjb2RlTXVsdGkoZSk7cmV0dXJufXRyeXt0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuc2V0QnVmZmVyKGUpO3doaWxlKHRoaXMuaGFzUmVtYWluaW5nKDEpKXlpZWxkIHRoaXMuZG9EZWNvZGVTeW5jKCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWFzeW5jIGRlY29kZUFzeW5jKGUpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmRlY29kZUFzeW5jKGUpO3RyeXt0aGlzLmVudGVyZWQ9ITA7bGV0IHQ9ITEscjtmb3IgYXdhaXQobGV0IG8gb2YgZSl7aWYodCl0aHJvdyB0aGlzLmVudGVyZWQ9ITEsdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTt0aGlzLmFwcGVuZEJ1ZmZlcihvKTt0cnl7cj10aGlzLmRvRGVjb2RlU3luYygpLHQ9ITB9Y2F0Y2goYSl7aWYoIShhIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgYX10aGlzLnRvdGFsUG9zKz10aGlzLnBvc31pZih0KXtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMudG90YWxQb3MpO3JldHVybiByfWxldHtoZWFkQnl0ZTpuLHBvczpzLHRvdGFsUG9zOml9PXRoaXM7dGhyb3cgUmFuZ2VFcnJvcihgSW5zdWZmaWNpZW50IGRhdGEgaW4gcGFyc2luZyAke3Z0KG4pfSBhdCAke2l9ICgke3N9IGluIHRoZSBjdXJyZW50IGJ1ZmZlcilgKX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19ZGVjb2RlQXJyYXlTdHJlYW0oZSl7cmV0dXJuIHRoaXMuZGVjb2RlTXVsdGlBc3luYyhlLCEwKX1kZWNvZGVTdHJlYW0oZSl7cmV0dXJuIHRoaXMuZGVjb2RlTXVsdGlBc3luYyhlLCExKX1hc3luYypkZWNvZGVNdWx0aUFzeW5jKGUsdCl7aWYodGhpcy5lbnRlcmVkKXt5aWVsZCp0aGlzLmNsb25lKCkuZGVjb2RlTXVsdGlBc3luYyhlLHQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwO2xldCByPXQsbj0tMTtmb3IgYXdhaXQobGV0IHMgb2YgZSl7aWYodCYmbj09PTApdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtpZih0aGlzLmFwcGVuZEJ1ZmZlcihzKSxyKW49dGhpcy5yZWFkQXJyYXlTaXplKCkscj0hMSx0aGlzLmNvbXBsZXRlKCk7dHJ5e3doaWxlKCEwKWlmKHlpZWxkIHRoaXMuZG9EZWNvZGVTeW5jKCksLS1uPT09MClicmVha31jYXRjaChpKXtpZighKGkgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSl0aHJvdyBpfXRoaXMudG90YWxQb3MrPXRoaXMucG9zfX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19ZG9EZWNvZGVTeW5jKCl7ZTp3aGlsZSghMCl7bGV0IGU9dGhpcy5yZWFkSGVhZEJ5dGUoKSx0O2lmKGU+PTIyNCl0PWUtMjU2O2Vsc2UgaWYoZTwxOTIpaWYoZTwxMjgpdD1lO2Vsc2UgaWYoZTwxNDQpe2xldCBuPWUtMTI4O2lmKG4hPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShuKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgZX1lbHNlIHQ9e319ZWxzZSBpZihlPDE2MCl7bGV0IG49ZS0xNDQ7aWYobiE9PTApe3RoaXMucHVzaEFycmF5U3RhdGUobiksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlIGV9ZWxzZSB0PVtdfWVsc2V7bGV0IG49ZS0xNjA7dD10aGlzLmRlY29kZVN0cmluZyhuLDApfWVsc2UgaWYoZT09PTE5Mil0PW51bGw7ZWxzZSBpZihlPT09MTk0KXQ9ITE7ZWxzZSBpZihlPT09MTk1KXQ9ITA7ZWxzZSBpZihlPT09MjAyKXQ9dGhpcy5yZWFkRjMyKCk7ZWxzZSBpZihlPT09MjAzKXQ9dGhpcy5yZWFkRjY0KCk7ZWxzZSBpZihlPT09MjA0KXQ9dGhpcy5yZWFkVTgoKTtlbHNlIGlmKGU9PT0yMDUpdD10aGlzLnJlYWRVMTYoKTtlbHNlIGlmKGU9PT0yMDYpdD10aGlzLnJlYWRVMzIoKTtlbHNlIGlmKGU9PT0yMDcpaWYodGhpcy51c2VCaWdJbnQ2NCl0PXRoaXMucmVhZFU2NEFzQmlnSW50KCk7ZWxzZSB0PXRoaXMucmVhZFU2NCgpO2Vsc2UgaWYoZT09PTIwOCl0PXRoaXMucmVhZEk4KCk7ZWxzZSBpZihlPT09MjA5KXQ9dGhpcy5yZWFkSTE2KCk7ZWxzZSBpZihlPT09MjEwKXQ9dGhpcy5yZWFkSTMyKCk7ZWxzZSBpZihlPT09MjExKWlmKHRoaXMudXNlQmlnSW50NjQpdD10aGlzLnJlYWRJNjRBc0JpZ0ludCgpO2Vsc2UgdD10aGlzLnJlYWRJNjQoKTtlbHNlIGlmKGU9PT0yMTcpe2xldCBuPXRoaXMubG9va1U4KCk7dD10aGlzLmRlY29kZVN0cmluZyhuLDEpfWVsc2UgaWYoZT09PTIxOCl7bGV0IG49dGhpcy5sb29rVTE2KCk7dD10aGlzLmRlY29kZVN0cmluZyhuLDIpfWVsc2UgaWYoZT09PTIxOSl7bGV0IG49dGhpcy5sb29rVTMyKCk7dD10aGlzLmRlY29kZVN0cmluZyhuLDQpfWVsc2UgaWYoZT09PTIyMCl7bGV0IG49dGhpcy5yZWFkVTE2KCk7aWYobiE9PTApe3RoaXMucHVzaEFycmF5U3RhdGUobiksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlIGV9ZWxzZSB0PVtdfWVsc2UgaWYoZT09PTIyMSl7bGV0IG49dGhpcy5yZWFkVTMyKCk7aWYobiE9PTApe3RoaXMucHVzaEFycmF5U3RhdGUobiksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlIGV9ZWxzZSB0PVtdfWVsc2UgaWYoZT09PTIyMil7bGV0IG49dGhpcy5yZWFkVTE2KCk7aWYobiE9PTApe3RoaXMucHVzaE1hcFN0YXRlKG4pLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSBlfWVsc2UgdD17fX1lbHNlIGlmKGU9PT0yMjMpe2xldCBuPXRoaXMucmVhZFUzMigpO2lmKG4hPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShuKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgZX1lbHNlIHQ9e319ZWxzZSBpZihlPT09MTk2KXtsZXQgbj10aGlzLmxvb2tVOCgpO3Q9dGhpcy5kZWNvZGVCaW5hcnkobiwxKX1lbHNlIGlmKGU9PT0xOTcpe2xldCBuPXRoaXMubG9va1UxNigpO3Q9dGhpcy5kZWNvZGVCaW5hcnkobiwyKX1lbHNlIGlmKGU9PT0xOTgpe2xldCBuPXRoaXMubG9va1UzMigpO3Q9dGhpcy5kZWNvZGVCaW5hcnkobiw0KX1lbHNlIGlmKGU9PT0yMTIpdD10aGlzLmRlY29kZUV4dGVuc2lvbigxLDApO2Vsc2UgaWYoZT09PTIxMyl0PXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDIsMCk7ZWxzZSBpZihlPT09MjE0KXQ9dGhpcy5kZWNvZGVFeHRlbnNpb24oNCwwKTtlbHNlIGlmKGU9PT0yMTUpdD10aGlzLmRlY29kZUV4dGVuc2lvbig4LDApO2Vsc2UgaWYoZT09PTIxNil0PXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDE2LDApO2Vsc2UgaWYoZT09PTE5OSl7bGV0IG49dGhpcy5sb29rVTgoKTt0PXRoaXMuZGVjb2RlRXh0ZW5zaW9uKG4sMSl9ZWxzZSBpZihlPT09MjAwKXtsZXQgbj10aGlzLmxvb2tVMTYoKTt0PXRoaXMuZGVjb2RlRXh0ZW5zaW9uKG4sMil9ZWxzZSBpZihlPT09MjAxKXtsZXQgbj10aGlzLmxvb2tVMzIoKTt0PXRoaXMuZGVjb2RlRXh0ZW5zaW9uKG4sNCl9ZWxzZSB0aHJvdyBuZXcgZWUoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7dnQoZSl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCByPXRoaXMuc3RhY2s7d2hpbGUoci5sZW5ndGg+MCl7bGV0IG49ci50b3AoKTtpZihuLnR5cGU9PT1ncilpZihuLmFycmF5W24ucG9zaXRpb25dPXQsbi5wb3NpdGlvbisrLG4ucG9zaXRpb249PT1uLnNpemUpdD1uLmFycmF5LHIucmVsZWFzZShuKTtlbHNlIGNvbnRpbnVlIGU7ZWxzZSBpZihuLnR5cGU9PT1mdCl7aWYodD09PSJfX3Byb3RvX18iKXRocm93IG5ldyBlZSgiVGhlIGtleSBfX3Byb3RvX18gaXMgbm90IGFsbG93ZWQiKTtuLmtleT10aGlzLm1hcEtleUNvbnZlcnRlcih0KSxuLnR5cGU9X247Y29udGludWUgZX1lbHNlIGlmKG4ubWFwW24ua2V5XT10LG4ucmVhZENvdW50Kyssbi5yZWFkQ291bnQ9PT1uLnNpemUpdD1uLm1hcCxyLnJlbGVhc2Uobik7ZWxzZXtuLmtleT1udWxsLG4udHlwZT1mdDtjb250aW51ZSBlfX1yZXR1cm4gdH19cmVhZEhlYWRCeXRlKCl7aWYodGhpcy5oZWFkQnl0ZT09PWx0KXRoaXMuaGVhZEJ5dGU9dGhpcy5yZWFkVTgoKTtyZXR1cm4gdGhpcy5oZWFkQnl0ZX1jb21wbGV0ZSgpe3RoaXMuaGVhZEJ5dGU9bHR9cmVhZEFycmF5U2l6ZSgpe2xldCBlPXRoaXMucmVhZEhlYWRCeXRlKCk7c3dpdGNoKGUpe2Nhc2UgMjIwOnJldHVybiB0aGlzLnJlYWRVMTYoKTtjYXNlIDIyMTpyZXR1cm4gdGhpcy5yZWFkVTMyKCk7ZGVmYXVsdDppZihlPDE2MClyZXR1cm4gZS0xNDQ7ZWxzZSB0aHJvdyBuZXcgZWUoYFVucmVjb2duaXplZCBhcnJheSB0eXBlIGJ5dGU6ICR7dnQoZSl9YCl9fXB1c2hNYXBTdGF0ZShlKXtpZihlPnRoaXMubWF4TWFwTGVuZ3RoKXRocm93IG5ldyBlZShgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHtlfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKGUpfXB1c2hBcnJheVN0YXRlKGUpe2lmKGU+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgZWUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IGFycmF5IGxlbmd0aCAoJHtlfSkgPiBtYXhBcnJheUxlbmd0aCAoJHt0aGlzLm1heEFycmF5TGVuZ3RofSlgKTt0aGlzLnN0YWNrLnB1c2hBcnJheVN0YXRlKGUpfWRlY29kZVN0cmluZyhlLHQpe2lmKCF0aGlzLnJhd1N0cmluZ3N8fHRoaXMuc3RhdGVJc01hcEtleSgpKXJldHVybiB0aGlzLmRlY29kZVV0ZjhTdHJpbmcoZSx0KTtyZXR1cm4gdGhpcy5kZWNvZGVCaW5hcnkoZSx0KX1kZWNvZGVVdGY4U3RyaW5nKGUsdCl7aWYoZT50aGlzLm1heFN0ckxlbmd0aCl0aHJvdyBuZXcgZWUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IFVURi04IGJ5dGUgbGVuZ3RoICgke2V9KSA+IG1heFN0ckxlbmd0aCAoJHt0aGlzLm1heFN0ckxlbmd0aH0pYCk7aWYodGhpcy5ieXRlcy5ieXRlTGVuZ3RoPHRoaXMucG9zK3QrZSl0aHJvdyBWbjtsZXQgcj10aGlzLnBvcyt0LG47aWYodGhpcy5zdGF0ZUlzTWFwS2V5KCkmJnRoaXMua2V5RGVjb2Rlcj8uY2FuQmVDYWNoZWQoZSkpbj10aGlzLmtleURlY29kZXIuZGVjb2RlKHRoaXMuYnl0ZXMscixlKTtlbHNlIG49Um4odGhpcy5ieXRlcyxyLGUpO3JldHVybiB0aGlzLnBvcys9dCtlLG59c3RhdGVJc01hcEtleSgpe2lmKHRoaXMuc3RhY2subGVuZ3RoPjApcmV0dXJuIHRoaXMuc3RhY2sudG9wKCkudHlwZT09PWZ0O3JldHVybiExfWRlY29kZUJpbmFyeShlLHQpe2lmKGU+dGhpcy5tYXhCaW5MZW5ndGgpdGhyb3cgbmV3IGVlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgke2V9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKGUrdCkpdGhyb3cgVm47bGV0IHI9dGhpcy5wb3MrdCxuPXRoaXMuYnl0ZXMuc3ViYXJyYXkocixyK2UpO3JldHVybiB0aGlzLnBvcys9dCtlLG59ZGVjb2RlRXh0ZW5zaW9uKGUsdCl7aWYoZT50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgZWUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IGV4dCBsZW5ndGggKCR7ZX0pID4gbWF4RXh0TGVuZ3RoICgke3RoaXMubWF4RXh0TGVuZ3RofSlgKTtsZXQgcj10aGlzLnZpZXcuZ2V0SW50OCh0aGlzLnBvcyt0KSxuPXRoaXMuZGVjb2RlQmluYXJ5KGUsdCsxKTtyZXR1cm4gdGhpcy5leHRlbnNpb25Db2RlYy5kZWNvZGUobixyLHRoaXMuY29udGV4dCl9bG9va1U4KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50OCh0aGlzLnBvcyl9bG9va1UxNigpe3JldHVybiB0aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKX1sb29rVTMyKCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MzIodGhpcy5wb3MpfXJlYWRVOCgpe2xldCBlPXRoaXMudmlldy5nZXRVaW50OCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKyssZX1yZWFkSTgoKXtsZXQgZT10aGlzLnZpZXcuZ2V0SW50OCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKyssZX1yZWFkVTE2KCl7bGV0IGU9dGhpcy52aWV3LmdldFVpbnQxNih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz0yLGV9cmVhZEkxNigpe2xldCBlPXRoaXMudmlldy5nZXRJbnQxNih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz0yLGV9cmVhZFUzMigpe2xldCBlPXRoaXMudmlldy5nZXRVaW50MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCxlfXJlYWRJMzIoKXtsZXQgZT10aGlzLnZpZXcuZ2V0SW50MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCxlfXJlYWRVNjQoKXtsZXQgZT1Pbih0aGlzLnZpZXcsdGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCxlfXJlYWRJNjQoKXtsZXQgZT1CdCh0aGlzLnZpZXcsdGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCxlfXJlYWRVNjRBc0JpZ0ludCgpe2xldCBlPXRoaXMudmlldy5nZXRCaWdVaW50NjQodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCxlfXJlYWRJNjRBc0JpZ0ludCgpe2xldCBlPXRoaXMudmlldy5nZXRCaWdJbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LGV9cmVhZEYzMigpe2xldCBlPXRoaXMudmlldy5nZXRGbG9hdDMyKHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTQsZX1yZWFkRjY0KCl7bGV0IGU9dGhpcy52aWV3LmdldEZsb2F0NjQodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCxlfX1mdW5jdGlvbiBTcihlLHQpe3JldHVybiBuZXcgRHQodCkuZGVjb2RlKGUpfWNsYXNzIHB0e2xpc3RlbmVycz1uZXcgTWFwO2FkZEV2ZW50TGlzdGVuZXIoZSx0KXtsZXQgcj10aGlzLmxpc3RlbmVycy5nZXQoZSk7aWYoIXIpcj1uZXcgU2V0LHRoaXMubGlzdGVuZXJzLnNldChlLHIpO3JldHVybiByLmFkZCh0KSwoKT0+e3RoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLHQpfX1yZW1vdmVFdmVudExpc3RlbmVyKGUsdCl7bGV0IHI9dGhpcy5saXN0ZW5lcnMuZ2V0KGUpO2lmKHIpe2lmKHIuZGVsZXRlKHQpLHIuc2l6ZT09PTApdGhpcy5saXN0ZW5lcnMuZGVsZXRlKGUpfX1lbWl0KGUsdCl7bGV0IHI9dGhpcy5saXN0ZW5lcnMuZ2V0KGUpO2lmKHIpe2xldCBuPUFycmF5LmZyb20ocik7Zm9yKGxldCBzIG9mIG4pcyh0KX19ZW1pdEFsbChlKXtsZXQgdD1BcnJheS5mcm9tKHRoaXMubGlzdGVuZXJzLmtleXMoKSk7Zm9yKGxldCByIG9mIHQpdGhpcy5lbWl0KHIsZSl9fWNsYXNzIFJle2dldHRlcjtzdGF0aWMgZXZlbnROYW1lPSJ1cGRhdGUiO2VtaXR0ZXI7Y29uc3RydWN0b3IoZSl7dGhpcy5nZXR0ZXI9ZTt0aGlzLmVtaXR0ZXI9bmV3IHB0fWdldD0oKT0+dGhpcy5nZXR0ZXIoKTthc3luYyBlbWl0KCl7bGV0IGU9YXdhaXQgdGhpcy5nZXR0ZXIoKTtxdWV1ZU1pY3JvdGFzaygoKT0+dGhpcy5lbWl0dGVyLmVtaXQoUmUuZXZlbnROYW1lLGUpKX1saXN0ZW4oZSl7cmV0dXJuIHRoaXMuZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKFJlLmV2ZW50TmFtZSxlKSwoKT0+e3RoaXMuZW1pdHRlci5yZW1vdmVFdmVudExpc3RlbmVyKFJlLmV2ZW50TmFtZSxlKX19fWZ1bmN0aW9uIHAoZSl7cmV0dXJuW2UsMF19ZnVuY3Rpb24gYyhlKXtyZXR1cm5bdm9pZCAwLGVdfWZ1bmN0aW9uIFFpKGUpe2lmKGU8MCljb25zb2xlLmluZm8oIk4iLGUpLGNvbnNvbGUudHJhY2UoKTtpZih0eXBlb2YgZSE9PSJiaWdpbnQiKWU9QmlnSW50KGUpO2lmKGU8MG4pcmV0dXJuIGMoMTApO2xldCB0PVtdO3doaWxlKGU+MG4pe2xldCByPU51bWJlcihlJjB4N2ZuKTtpZihlPj49N24sZT4wbil0LnB1c2gocnwxMjgpO2Vsc2UgdC5wdXNoKHIpfWlmKHQubGVuZ3RoPT09MClyZXR1cm4gcChuZXcgVWludDhBcnJheShbMF0pKTtpZih0Lmxlbmd0aD44KXJldHVybiBjKDI2KTtyZXR1cm4gcChuZXcgVWludDhBcnJheSh0KSl9ZnVuY3Rpb24gWWkoZSx0PTApe2xldCByPTBuLG49MCxzPXQ7d2hpbGUoITApe2lmKHM+PWUubGVuZ3RoKXJldHVybiBjKDE0KTtsZXQgaT1lW3MrK107aWYoaT09PXZvaWQgMClyZXR1cm4gYygxNCk7aWYocnw9QmlnSW50KGkmMTI3KTw8QmlnSW50KG4pLChpJjEyOCk9PT0wKXtpZihzLXQ+OClyZXR1cm4gYygyNik7cmV0dXJuIHAoe3ZhbHVlOnI+MHgxZmZmZmZmZmZmZmZmZm4/cjpOdW1iZXIociksYnl0ZXNSZWFkOnMtdH0pfWlmKG4rPTcsbj49NTYpcmV0dXJuIGMoMjYpfX1jbGFzcyBMe2RhdGE7cG9zPTA7Y29uc3RydWN0b3IoZSl7dGhpcy5kYXRhPWV9c3RhdGljIGFzeW5jIGZyb21SZXNwb25zZShlKXtsZXQgdD1hd2FpdCBlLmFycmF5QnVmZmVyKCkscj1uZXcgVWludDhBcnJheSh0KTtyZXR1cm4gbmV3IEwocil9cmVhZEJpZ0ludCgpe2lmKHRoaXMucG9zKzg+dGhpcy5kYXRhLmxlbmd0aClyZXR1cm4gYyg3KTtsZXQgZT1uZXcgRGF0YVZpZXcodGhpcy5kYXRhLmJ1ZmZlcix0aGlzLmRhdGEuYnl0ZU9mZnNldCt0aGlzLnBvcykuZ2V0QmlnVWludDY0KDAsITEpO3JldHVybiB0aGlzLnBvcys9OCxwKGUpfXJlYWREYXRlKCl7bGV0W2UsdF09dGhpcy5yZWFkVmFySW50KCk7aWYodCE9PTApcmV0dXJuIGModCk7cmV0dXJuIHAobmV3IERhdGUoZSkpfXJlYWRWYXJJbnQoKXtsZXRbZSx0XT1ZaSh0aGlzLmRhdGEsdGhpcy5wb3MpO2lmKHQhPT0wKXJldHVybiBjKHQpO3RoaXMucG9zKz1lLmJ5dGVzUmVhZDtsZXQgcj1lLnZhbHVlO3JldHVybiBwKHR5cGVvZiByPT09ImJpZ2ludCI/TnVtYmVyKHIpOnIpfXJlYWRWYXJTdHJpbmcoKXtsZXRbZSx0XT10aGlzLnJlYWRWYXJJbnQoKTtpZih0IT09MClyZXR1cm4gYyh0KTtsZXRbcixuXT10aGlzLnJlYWRCeXRlcyhlKTtpZihuIT09MClyZXR1cm4gYyhuKTtsZXQgcz1uZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocik7cmV0dXJuIHAocyl9cmVhZEJ5dGVzKGUpe2lmKGU8MClyZXR1cm4gYygxMCk7aWYodGhpcy5wb3MrZT50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBjKDIzKTtsZXQgdD10aGlzLmRhdGEuc2xpY2UodGhpcy5wb3MsdGhpcy5wb3MrZSk7cmV0dXJuIHRoaXMucG9zKz1lLHAodCl9cmVhZFZhckJ5dGVzKCl7bGV0W2UsdF09dGhpcy5yZWFkVmFySW50KCk7aWYodCE9PTApcmV0dXJuIGModCk7cmV0dXJuIHRoaXMucmVhZEJ5dGVzKGUpfXJlYWRTdHJ1Y3QoZSl7cmV0dXJuIGUuZGVjb2RlKHRoaXMpfXJlYWRTdHJ1Y3RzKGUpe2xldCB0PVtdO3doaWxlKCF0aGlzLmRvbmUoKSl7bGV0W3Isbl09dGhpcy5yZWFkU3RydWN0KGUpO2lmKG4hPT0wKXJldHVybiBjKG4pO3QucHVzaChyKX1yZXR1cm4gcCh0KX1yZWFkQnl0ZXNTZXEoZSl7bGV0IHQ9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbcixuXT10aGlzLnJlYWRCeXRlcyhlKTtpZihuIT09MClyZXR1cm4gYyhuKTt0LnB1c2gocil9cmV0dXJuIHAodCl9ZG9uZSgpe3JldHVybiB0aGlzLnBvcz49dGhpcy5kYXRhLmxlbmd0aH1jb25zdW1lZCgpe3JldHVybiB0aGlzLnBvc319Y2xhc3MgT3twYXJ0cz1bXTt3cml0ZUJpZ0ludChlKXtsZXQgdD1uZXcgVWludDhBcnJheSg4KTtuZXcgRGF0YVZpZXcodC5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLGUsITEpLHRoaXMucGFydHMucHVzaCh0KX13cml0ZURhdGUoZSl7bGV0IHQ9ZS5nZXRUaW1lKCk7cmV0dXJuIHRoaXMud3JpdGVWYXJJbnQodCl9d3JpdGVWYXJJbnQoZSl7bGV0W3Qscl09UWkoZSk7aWYociE9PTApcmV0dXJuIHI7cmV0dXJuIHRoaXMucGFydHMucHVzaCh0KSwwfXdyaXRlVmFyU3RyaW5nKGUpe2xldCB0PW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShlKSxyPXRoaXMud3JpdGVWYXJJbnQodC5sZW5ndGgpO2lmKHIhPT0wKXJldHVybiByO3JldHVybiB0aGlzLndyaXRlQnl0ZXModCksMH1wcmVwZW5kQnl0ZXMoZSl7dGhpcy5wYXJ0cy51bnNoaWZ0KGUuc2xpY2UoKSl9d3JpdGVCeXRlcyhlKXt0aGlzLnBhcnRzLnB1c2goZS5zbGljZSgpKX13cml0ZVZhckJ5dGVzKGUpe2xldCB0PXRoaXMud3JpdGVWYXJJbnQoZS5sZW5ndGgpO2lmKHQhPT0wKXJldHVybiB0O3JldHVybiB0aGlzLndyaXRlQnl0ZXMoZSksMH13cml0ZVN0cnVjdChlLHQpe3JldHVybiBlLmVuY29kZSh0aGlzLHQpfXdyaXRlU3RydWN0cyhlLHQpe2ZvcihsZXQgciBvZiB0KXtsZXQgbj10aGlzLndyaXRlU3RydWN0KGUscik7aWYobiE9PTApcmV0dXJuIG59cmV0dXJuIDB9d3JpdGVCeXRlc1NlcShlKXtmb3IobGV0IHQgb2YgZSl0aGlzLndyaXRlQnl0ZXModCl9cmVzdWx0KCl7bGV0IGU9dGhpcy5wYXJ0cy5yZWR1Y2UoKG4scyk9Pm4rcy5sZW5ndGgsMCksdD1uZXcgVWludDhBcnJheShlKSxyPTA7Zm9yKGxldCBuIG9mIHRoaXMucGFydHMpdC5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gdH13aXBlKCl7Zm9yKGxldCBlIG9mIHRoaXMucGFydHMpZS5maWxsKDApO3RoaXMucGFydHMubGVuZ3RoPTB9KnNjYW4oKXtmb3IobGV0IGUgb2YgdGhpcy5wYXJ0cyl5aWVsZCBlfX1hc3luYyBmdW5jdGlvbiB3cihlLHQpe2xldCByPW5ldyBPLG49ci53cml0ZURhdGUodCk7aWYobiE9PTApcmV0dXJuIGMobik7bGV0IHM9ci5yZXN1bHQoKSxpPWF3YWl0IGUuc2lnbihzKTtyZXR1cm4gcCh7cHViS2V5OmUucHVibGljS2V5LHNpZzppLHRpbWVzdGFtcDp0fSl9YXN5bmMgZnVuY3Rpb24gRGUoZSx0LHIpe2xldCBuPXIubm93KCkuZ2V0VGltZSgpLHM9ZS50aW1lc3RhbXAuZ2V0VGltZSgpO2lmKE1hdGguYWJzKG4tcyk+RG4pcmV0dXJuIDQ7bGV0IG89bmV3IE87by53cml0ZURhdGUoZS50aW1lc3RhbXApO2xldCBhPW8ucmVzdWx0KCk7aWYoIWF3YWl0IHQuY2hlY2tTaWdFZDI1NTE5KGUuc2lnLGEsZS5wdWJLZXkpKXJldHVybiAzO3JldHVybiAwfXZhciBpZT17ZW5jb2RlKGUsdCl7bGV0IHI9ZS53cml0ZVZhckJ5dGVzKHQuaWQpO2lmKHIhPT0wKXJldHVybiByO2xldCBuPWUud3JpdGVEYXRlKHQudHMpO2lmKG4hPT0wKXJldHVybiBuO3JldHVybiAwfSxkZWNvZGUoZSl7bGV0W3Qscl09ZS5yZWFkVmFyQnl0ZXMoKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWREYXRlKCk7aWYocyE9PTApcmV0dXJuIGMocyk7cmV0dXJuIHAoe2lkOnQsdHM6bn0pfX07ZnVuY3Rpb24gQ3QoZSl7bGV0IHQ9bmV3IE8scj10LndyaXRlU3RydWN0KGllLGUpO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldCBuPXQucmVzdWx0KCk7cmV0dXJuIHAobil9dmFyIGRlPXtlbmNvZGUoZSx0KXtsZXQgcj1lLndyaXRlVmFyQnl0ZXModC5laWQpO2lmKHIhPT0wKXJldHVybiByO2xldCBuPWUud3JpdGVWYXJJbnQodC5vZmYpO2lmKG4hPT0wKXJldHVybiBuO2xldCBzPWUud3JpdGVWYXJJbnQodC5jdHIpO2lmKHMhPT0wKXJldHVybiBzO2xldCBpPWUud3JpdGVWYXJJbnQodC5sZW4pO2lmKGkhPT0wKXJldHVybiBpO2lmKHQuaHNoKWUud3JpdGVCeXRlcyh0LmhzaCk7cmV0dXJuIDB9LGRlY29kZShlKXtsZXRbdCxyXT1lLnJlYWRWYXJCeXRlcygpO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldCBuPW5ldyBMKHQpLFssc109aWUuZGVjb2RlKG4pO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldFtpLG9dPWUucmVhZFZhckludCgpO2lmKG8hPT0wKXJldHVybiBjKG8pO2xldFthLGRdPWUucmVhZFZhckludCgpO2lmKGQhPT0wKXJldHVybiBjKGQpO2xldFt1LGxdPWUucmVhZFZhckludCgpO2lmKGwhPT0wKXJldHVybiBjKGwpO2xldCBmO2lmKHU+MCl7bGV0W2gseV09ZS5yZWFkQnl0ZXMoUHQpO2lmKHkhPT0wKXJldHVybiBjKHkpO2Y9aH1yZXR1cm4gcCh7ZWlkOnQsb2ZmOmksY3RyOmEsbGVuOnUsaHNoOmZ9KX19O2Z1bmN0aW9uIGhlKGUpe3JldHVybiBBcnJheS5mcm9tKGUpLm1hcCgocik9PnIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKSkuam9pbigiIil9ZnVuY3Rpb24gcW4oZSl7aWYoZS5sZW5ndGglMiE9PTApdGhyb3cgRXJyb3IoIkludmFsaWQgaGV4IHN0cmluZyIpO2xldCB0PW5ldyBVaW50OEFycmF5KGUubGVuZ3RoLzIpO2ZvcihsZXQgcj0wO3I8ZS5sZW5ndGg7cis9Mil0W3IvMl09TnVtYmVyLnBhcnNlSW50KGUuc3Vic3RyKHIsMiksMTYpO3JldHVybiB0fWZ1bmN0aW9uIFgoZSx0KXtpZihlPT09dClyZXR1cm4hMDtpZihlLmJ5dGVMZW5ndGghPT10LmJ5dGVMZW5ndGgpcmV0dXJuITE7cmV0dXJuIGUuZXZlcnkoKHIsbik9PnI9PT10W25dKX12YXIgRDtpZih0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUudG9CYXNlNjQ9PT0iZnVuY3Rpb24iKUQ9KGUpPT5lLnRvQmFzZTY0KCk7ZWxzZSBEPShlKT0+YnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKC4uLmUpKTt2YXIgZmU7aWYodHlwZW9mIFVpbnQ4QXJyYXkuZnJvbUJhc2U2ND09PSJmdW5jdGlvbiIpZmU9KGUpPT5VaW50OEFycmF5LmZyb21CYXNlNjQoZSk7ZWxzZSBmZT0oZSk9PlVpbnQ4QXJyYXkuZnJvbShhdG9iKGUpLCh0KT0+dC5jaGFyQ29kZUF0KDApKTtmdW5jdGlvbiBGbihlKXtsZXQgdD1lLmxlbmd0aCU0PT09MD8iIjoiPSIucmVwZWF0KDQtZS5sZW5ndGglNCkscj1lLnJlcGxhY2UoLy0vZywiKyIpLnJlcGxhY2UoL18vZywiLyIpK3Q7cmV0dXJuIGZlKHIpfWZ1bmN0aW9uIHdlKGUsdCl7bGV0IHI9bmV3IFVpbnQ4QXJyYXkoZS5sZW5ndGgrdC5sZW5ndGgpO3JldHVybiByLnNldChlLDApLHIuc2V0KHQsZS5sZW5ndGgpLHJ9ZnVuY3Rpb24gV24oZSx0LHIpe3JldHVybiByLmNoZWNrU2lnRWQyNTUxOShlLnNpZyxlLmhlYWRDcGgsdCl9YXN5bmMgZnVuY3Rpb24gem4oZSx0LHIsbil7bGV0IHM7aWYoZS5ib2QmJmUubGVuPjApcz1hd2FpdCByLmJsYWtlMyhlLmJvZCk7bGV0IGk9bmV3IE8sbz1kZS5lbmNvZGUoaSx7Li4uZSxoc2g6c30pO2lmKG8hPT0wKXJldHVybiBjKG8pO2xldCBhPWkucmVzdWx0KCksZD1hd2FpdCB0LmtkbUZvcihhKSx1PW4uZGVyaXZlQ2lwaGVyKGQsImVuY3J5cHQiKSxsPWF3YWl0IHUuZW5jcnlwdChhKSxmPWUuYm9kP2F3YWl0IHUuZW5jcnlwdChlLmJvZCk6bmV3IFVpbnQ4QXJyYXkoMCksaD1hd2FpdCB0LnNpZ24obCk7cmV0dXJuIHAoe3NpZzpoLGtkbTpkLGhlYWRDcGg6bCxib2R5Q3BoOmZ9KX1hc3luYyBmdW5jdGlvbiBJcihlLHQscixuLHMpe2xldCBpPW5ldyBMKGUpLFtvLGFdPWRlLmRlY29kZShpKTtpZihhIT09MClyZXR1cm4gYygxNCk7bGV0IGQ7dHJ5e2Q9dCYmdC5sZW5ndGg+MD9hd2FpdCByLmRlY3J5cHQodCk6dm9pZCAwfWNhdGNoe3JldHVybiBjKDIwKX1sZXQgdT1vLmhzaCYmZD09PXZvaWQgMCxsPW8uaHNoPT09dm9pZCAwJiZkIT09dm9pZCAwO2lmKHV8fGwpcmV0dXJuIGMoMTkpO2lmKG8uaHNoJiZkKXtsZXQgaD1hd2FpdCBuLmJsYWtlMyhkKTtpZighWChoLG8uaHNoKSlyZXR1cm4gYygxOSl9bGV0IGY9cz8/YXdhaXQgbi5ibGFrZTMoZSk7cmV0dXJuIHAoe21zZ0hlYWQ6byxib2Q6ZCxoZWFkSGFzaDpmfSl9Y2xhc3MgeHJ7bm93KCl7cmV0dXJuIG5ldyBEYXRlfX1mdW5jdGlvbiBYbihlLHQscixuKXtsZXQgcz10LmdldFRpbWUoKS1lLmdldFRpbWUoKSxpPXIuZ2V0VGltZSgpLW4uZ2V0VGltZSgpO3JldHVybihzK2kpLzJ9dmFyIGh0PXtlbmNvZGUoZSx0KXtpZihlLndyaXRlVmFySW50KHQucXVvdGEpLHQucXVvdGE+MCl7aWYodC51c2FnZT09PXZvaWQgMClyZXR1cm4gOTtlLndyaXRlVmFySW50KHQudXNhZ2UpfXJldHVybiAwfSxkZWNvZGUoZSl7bGV0W3Qscl09ZS5yZWFkVmFySW50KCk7aWYociE9PTApcmV0dXJuIGMocik7bGV0IG47aWYodD4wKXtsZXRbcyxpXT1lLnJlYWRWYXJJbnQoKTtpZihpIT09MClyZXR1cm4gYyhpKTtuPXN9cmV0dXJuIHAoe3F1b3RhOnQsdXNhZ2U6bn0pfX07dmFyIEVyPXtlbmNvZGUoZSx0KXtlLndyaXRlQnl0ZXMobmV3IFVpbnQ4QXJyYXkoW3Quc3RhdHVzXSkpO2xldCByPWUud3JpdGVEYXRlKHQudGltZVJjdmQpO2lmKHIhPT0wKXJldHVybiByO2xldCBuPWUud3JpdGVEYXRlKHQudGltZVNlbnQpO2lmKG4hPT0wKXJldHVybiBuO2xldCBzPWUud3JpdGVWYXJJbnQodC5zdWJzY3JpcHRpb24udGVybSk7aWYocyE9PTApcmV0dXJuIHM7bGV0IGk9ZS53cml0ZVZhckludCh0LnN1YnNjcmlwdGlvbi5lbGFwc2VkKTtpZihpIT09MClyZXR1cm4gaTtsZXQgbz1lLndyaXRlU3RydWN0KGh0LHQuc3Vic2NyaXB0aW9uLnN0YXQpO2lmKG8hPT0wKXJldHVybiBvO2xldCBhPWUud3JpdGVTdHJ1Y3QoaHQsdC5zdWJzY3JpcHRpb24uZHluKTtpZihhIT09MClyZXR1cm4gYTtyZXR1cm4gMH0sZGVjb2RlKGUpe2xldFt0LHJdPWUucmVhZEJ5dGVzKDEpO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldCBuPXRbMF0sW3MsaV09ZS5yZWFkRGF0ZSgpO2lmKGkhPT0wKXJldHVybiBjKGkpO2xldFtvLGFdPWUucmVhZERhdGUoKTtpZihhIT09MClyZXR1cm4gYyhhKTtsZXRbZCx1XT1lLnJlYWRWYXJJbnQoKTtpZih1IT09MClyZXR1cm4gYyh1KTtsZXRbbCxmXT1lLnJlYWRWYXJJbnQoKTtpZihmIT09MClyZXR1cm4gYyhmKTtsZXRbaCx5XT1lLnJlYWRTdHJ1Y3QoaHQpO2lmKHkhPT0wKXJldHVybiBjKHkpO2xldFttLGddPWUucmVhZFN0cnVjdChodCk7aWYoZyE9PTApcmV0dXJuIGMoZyk7cmV0dXJuIHAoe3N0YXR1czpuLHRpbWVSY3ZkOnMsdGltZVNlbnQ6byxzdWJzY3JpcHRpb246e3Rlcm06ZCxlbGFwc2VkOmwsc3RhdDpoLGR5bjptfX0pfX07dmFyIEFyPXtlbmNvZGUoZSx0KXtsZXQgcj1lLndyaXRlVmFyQnl0ZXModC5oZWFkQ3BoKTtpZihyIT09MClyZXR1cm4gcjtsZXQgbj1lLndyaXRlVmFySW50KHQuc2VxKTtpZihuIT09MClyZXR1cm4gbjtyZXR1cm4gMH0sZGVjb2RlKGUpe2xldFt0LHJdPWUucmVhZFZhckJ5dGVzKCk7aWYociE9PTApcmV0dXJuIGMocik7bGV0W24sc109ZS5yZWFkVmFySW50KCk7aWYocyE9PTApcmV0dXJuIGMocyk7cmV0dXJuIHAoe2hlYWRDcGg6dCxzZXE6bn0pfX07dmFyIG9lPXtlbmNvZGUoZSx0KXtlLndyaXRlQnl0ZXModC5wdWJLZXkpLGUud3JpdGVCeXRlcyh0LnNpZyk7bGV0IHI9ZS53cml0ZURhdGUodC50aW1lc3RhbXApO2lmKHIhPT0wKXJldHVybiByO3JldHVybiAwfSxkZWNvZGUoZSl7bGV0W3Qscl09ZS5yZWFkQnl0ZXModm4pO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldFtuLHNdPWUucmVhZEJ5dGVzKGtlKTtpZihzIT09MClyZXR1cm4gYyhzKTtsZXRbaSxvXT1lLnJlYWREYXRlKCk7aWYobyE9PTApcmV0dXJuIGMobyk7cmV0dXJuIHAoe3B1YktleTp0LHNpZzpuLHRpbWVzdGFtcDppfSl9fTt2YXIgam49e2FzeW5jIGVuY29kZVJlcShlLHQscixuLHMpe2xldCBpPXMud3JpdGVTdHJ1Y3Qob2Uscik7aWYoaSE9PTApcmV0dXJuIGk7Zm9yKGxldCBvIG9mIG4pcy53cml0ZVZhckludChvKTtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKGUsdCxyKXtsZXR7Y2xvY2s6bixjcnlwdG86cyxzdG9yYWdlOml9PWUsW28sYV09dC5yZWFkU3RydWN0KG9lKTtpZihhIT09MClyZXR1cm4gYTtsZXQgZD1hd2FpdCBEZShvLHMsbik7aWYoZCE9PTApcmV0dXJuIGQ7bGV0e3B1YktleTp1fT1vLFtsLGZdPWF3YWl0IGkuaGFzVXNlcih1KTtpZihmIT09MClyZXR1cm4gZjtpZighbClyZXR1cm4gNTtsZXRbaCx5XT10LnJlYWRWYXJJbnQoKTtpZih5IT09MClyZXR1cm4geTtpZighdC5kb25lKCkpcmV0dXJuIDg7bGV0W20sZ109YXdhaXQgaS5saXN0SGVhZHModSxoKTtpZihnIT09MClyZXR1cm4gZztyZXR1cm4gci53cml0ZVN0cnVjdHMoQXIsbSl9LGRlY29kZVJlc3AoZSl7cmV0dXJuIGUucmVhZFN0cnVjdHMoQXIpfX07dmFyIFByPXtlbmNvZGUoZSx0KXtlLndyaXRlVmFySW50KHQuc2VxKTtsZXQgcj1lLndyaXRlVmFyQnl0ZXModC5ib2R5Q3BoKTtpZihyIT09MClyZXR1cm4gcjtyZXR1cm4gMH0sZGVjb2RlKGUpe2xldFt0LHJdPWUucmVhZFZhckludCgpO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldFtuLHNdPWUucmVhZFZhckJ5dGVzKCk7aWYocyE9PTApcmV0dXJuIGMocyk7cmV0dXJuIHAoe3NlcTp0LGJvZHlDcGg6bn0pfX07dmFyIEduPXthc3luYyBlbmNvZGVSZXEoZSx0LHIsbixzKXtsZXQgaT1zLndyaXRlU3RydWN0KG9lLHIpO2lmKGkhPT0wKXJldHVybiBpO2ZvcihsZXQgbyBvZiBuKXtsZXQgYT1zLndyaXRlVmFySW50KG8pO2lmKGEhPT0wKXJldHVybiBhfXJldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoZSx0LHIpe2xldHtjbG9jazpuLGNyeXB0bzpzLHN0b3JhZ2U6aX09ZSxbbyxhXT10LnJlYWRTdHJ1Y3Qob2UpO2lmKGEhPT0wKXJldHVybiBhO2xldCBkPWF3YWl0IERlKG8scyxuKTtpZihkIT09MClyZXR1cm4gZDtsZXR7cHViS2V5OnV9PW8sW2wsZl09YXdhaXQgaS5oYXNVc2VyKHUpO2lmKGYhPT0wKXJldHVybiBmO2lmKCFsKXJldHVybiA1O2xldCBoPVtdO3doaWxlKCF0LmRvbmUoKSl7bGV0W2csYl09dC5yZWFkVmFySW50KCk7aWYoYiE9PTApcmV0dXJuIGI7aC5wdXNoKGcpfWNvbnNvbGUuaW5mbyhgUFVMTDogJHtoLmxlbmd0aH0gYmFnc2ApO2xldFt5LG1dPWF3YWl0IGkuZ2V0Qm9kaWVzKHUsaCk7aWYobSE9PTApcmV0dXJuIG07aWYoIXkpcmV0dXJuIDE3O2ZvcihsZXR7c2VxOmcsYm9keUNwaDpifW9mIHkpe2xldCBJPXtzZXE6Zyxib2R5Q3BoOmJ9LHc9ci53cml0ZVN0cnVjdChQcixJKTtpZih3IT09MClyZXR1cm4gd31yZXR1cm4gMH0sZGVjb2RlUmVzcChlKXtyZXR1cm4gZS5yZWFkU3RydWN0cyhQcil9fTt2YXIgVXI9e2VuY29kZShlLHQpe2Uud3JpdGVCeXRlcyh0LnNpZyksZS53cml0ZUJ5dGVzKHQua2RtKTtsZXQgcj1lLndyaXRlVmFyQnl0ZXModC5oZWFkQ3BoKTtpZihyIT09MClyZXR1cm4gcjtsZXQgbj1lLndyaXRlVmFyQnl0ZXModC5ib2R5Q3BoKTtpZihuIT09MClyZXR1cm4gbjtyZXR1cm4gMH0sZGVjb2RlKGUpe2xldFt0LHJdPWUucmVhZEJ5dGVzKGtlKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWRCeXRlcyh2ZSk7aWYocyE9PTApcmV0dXJuIGMocyk7bGV0W2ksb109ZS5yZWFkVmFyQnl0ZXMoKTtpZihvIT09MClyZXR1cm4gYyhvKTtsZXRbYSxkXT1lLnJlYWRWYXJCeXRlcygpO2lmKGQhPT0wKXJldHVybiBjKGQpO3JldHVybiBwKHtzaWc6dCxrZG06bixoZWFkQ3BoOmksYm9keUNwaDphfSl9fTt2YXIgVHQ9e2VuY29kZShlLHQpe2xldCByPWUud3JpdGVWYXJJbnQodC5zZXEpO2lmKHIhPT0wKXJldHVybiByO2xldCBuPWUud3JpdGVWYXJCeXRlcyh0LmhlYWRDcGgpO2lmKG4hPT0wKXJldHVybiBuO2xldCBzPXQuYm9keUNwaD90LmJvZHlDcGgubGVuZ3RoOjAsaT1lLndyaXRlVmFySW50KHMpO2lmKGkhPT0wKXJldHVybiBpO2lmKHM+MCl7aWYoIXQuYm9keUNwaClyZXR1cm4gMTA7ZS53cml0ZUJ5dGVzKHQuYm9keUNwaCl9cmV0dXJuIDB9LGRlY29kZShlKXtsZXRbdCxyXT1lLnJlYWRWYXJJbnQoKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWRWYXJCeXRlcygpO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldFtpLG9dPWUucmVhZFZhckludCgpO2lmKG8hPT0wKXJldHVybiBjKG8pO2xldCBhO2lmKGk+MCl7bGV0W2QsdV09ZS5yZWFkQnl0ZXMoaSk7aWYodSE9PTApcmV0dXJuIGModSk7YT1kfXJldHVybiBwKHtzZXE6dCxoZWFkQ3BoOm4sYm9keUNwaDphfSl9fTt2YXIgSHQ9e2VuY29kZShlLHQpe2Uud3JpdGVCeXRlcyh0LnNpZyksZS53cml0ZUJ5dGVzKHQua2RtKTtsZXQgcj1lLndyaXRlVmFyQnl0ZXModC5oZWFkQ3BoKTtpZihyIT09MClyZXR1cm4gcjtyZXR1cm4gMH0sZGVjb2RlKGUpe2xldFt0LHJdPWUucmVhZEJ5dGVzKGtlKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWRCeXRlcyh2ZSk7aWYocyE9PTApcmV0dXJuIGMocyk7bGV0W2ksb109ZS5yZWFkVmFyQnl0ZXMoKTtpZihvIT09MClyZXR1cm4gYyhvKTtyZXR1cm4gcCh7c2lnOnQsa2RtOm4saGVhZENwaDppfSl9fTt2YXIgTXQ9e2VuY29kZShlLHQpe2lmKGUud3JpdGVWYXJJbnQodC5pZHgpLGUud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbdC5zdGF0dXNdKSksdC5zdGF0dXM9PT0wKWUud3JpdGVWYXJJbnQodC5zZXEpO3JldHVybiAwfSxkZWNvZGUoZSl7bGV0W3Qscl09ZS5yZWFkVmFySW50KCk7aWYociE9PTApcmV0dXJuIGMocik7bGV0W24sc109ZS5yZWFkQnl0ZXMoMSk7aWYocyE9PTApcmV0dXJuIGMocyk7bGV0IGk9blswXTtpZihpIT09MClyZXR1cm4gcCh7aWR4OnQsc3RhdHVzOml9KTtsZXRbbyxhXT1lLnJlYWRWYXJJbnQoKTtpZihhIT09MClyZXR1cm4gYyhhKTtyZXR1cm4gcCh7aWR4OnQsc3RhdHVzOmksc2VxOm99KX19O3ZhciAkbj17YXN5bmMgZW5jb2RlUmVxKGUsdCxyLG4scyl7bGV0IGk9cy53cml0ZVN0cnVjdChvZSxyKTtpZihpIT09MClyZXR1cm4gaTtsZXQgbz1zLndyaXRlU3RydWN0cyhVcixuKTtpZihvIT09MClyZXR1cm4gbztyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKGUsdCxyKXtsZXR7Y2xvY2s6bixjcnlwdG86cyxzdG9yYWdlOmksbm90aWZpZXI6b309ZSxbYSxkXT10LnJlYWRTdHJ1Y3Qob2UpO2lmKGQhPT0wKXJldHVybiBkO2xldCB1PWF3YWl0IERlKGEscyxuKTtpZih1IT09MClyZXR1cm4gdTtsZXR7cHViS2V5Omx9PWEsW2YsaF09YXdhaXQgaS5oYXNVc2VyKGwpO2lmKGghPT0wKXJldHVybiBoO2lmKCFmKXJldHVybiA1O2xldFt5LG1dPXQucmVhZFN0cnVjdHMoVXIpO2lmKG0hPT0wKXJldHVybiBtO2NvbnNvbGUuaW5mbyhgUFVTSDogJHt5Lmxlbmd0aH0gYmFnc2ApO2xldCBnPVtdLGI9W107Zm9yKGxldCBTPTA7Uzx5Lmxlbmd0aDtTKyspe2xldCBQPXlbU107aWYoIWF3YWl0IFduKFAsbCxzKSl7bGV0IE09e2lkeDpTLHN0YXR1czozfSxIPXIud3JpdGVTdHJ1Y3QoTXQsTSk7aWYoSCE9PTApcmV0dXJuIEg7Y29udGludWV9Zy5wdXNoKFMpLGIucHVzaChQKX1sZXRbSSx3XT1hd2FpdCBpLnNldEJhZ3MobCxiKTtpZih3IT09MClyZXR1cm4gdztpZighSXx8SS5sZW5ndGghPT1iLmxlbmd0aClyZXR1cm4gMTc7bGV0IEU9W107Zm9yKGxldCBTPTA7UzxiLmxlbmd0aDtTKyspe2xldCBQPWJbU10saz1nW1NdLE09SVtTXSxIPW5ldyBPLEM9SC53cml0ZVN0cnVjdChIdCxQKTtpZihDIT09MClyZXR1cm4gQztsZXQgSz1ILnJlc3VsdCgpLF89e3NlcTpNLGhlYWRDcGg6S307aWYoeS5sZW5ndGg9PT0xJiZQLmJvZHlDcGgubGVuZ3RoPD1DbilfLmJvZHlDcGg9UC5ib2R5Q3BoO0UucHVzaChfKTtsZXQgRj17aWR4Omssc3RhdHVzOjAsc2VxOk19LHg9ci53cml0ZVN0cnVjdChNdCxGKTtpZih4IT09MClyZXR1cm4geH1pZihFLmxlbmd0aD4wKXtsZXQgUz1uZXcgTyxQPVMud3JpdGVTdHJ1Y3RzKFR0LEUpO2lmKFAhPT0wKXJldHVybiBQO2xldCBrPVMucmVzdWx0KCk7YXdhaXQgUHJvbWlzZS5yZXNvbHZlKG8ucHVzaChsLGspKX1yZXR1cm4gMH0sZGVjb2RlUmVzcChlKXtyZXR1cm4gZS5yZWFkU3RydWN0cyhNdCl9fTt2YXIgUW49e2FzeW5jIGVuY29kZVJlcShlLHQscixuLHMpe3JldHVybiBzLndyaXRlU3RydWN0KG9lLHIpfSxhc3luYyBoYW5kbGVSZXEoZSx0LHIpe2xldHtjbG9jazpuLGNyeXB0bzpzLHN0b3JhZ2U6aX09ZSxbbyxhXT10LnJlYWRTdHJ1Y3Qob2UpO2lmKGEhPT0wKXJldHVybiBhO2xldCBkPWF3YWl0IERlKG8scyxuKTtpZihkIT09MClyZXR1cm4gZDtsZXR7cHViS2V5OnV9PW87aWYoIXQuZG9uZSgpKXJldHVybiA4O2xldFtsLGZdPWF3YWl0IGkuYWRkVXNlcih1KTtpZihmIT09MClyZXR1cm4gZjtyZXR1cm4gMH0sZGVjb2RlUmVzcChlKXtyZXR1cm4gcCh2b2lkIDApfX07Y2xhc3MgQnJ7dXJsO3dlYnNvY2tldDtjb25zdHJ1Y3RvcihlKXt0aGlzLnVybD1lfWNvbm5lY3RlZCgpe3JldHVybiB0aGlzLndlYnNvY2tldCE9PXZvaWQgMCYmdGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZT09PVdlYlNvY2tldC5PUEVOfWFzeW5jIGNvbm5lY3QoZSx0LHI9KCk9Pnt9LG49KCk9Pnt9KXtsZXR7dXJsOnN9PXRoaXM7aWYodGhpcy53ZWJzb2NrZXQpdGhpcy53ZWJzb2NrZXQuY2xvc2UoKSx0aGlzLndlYnNvY2tldD12b2lkIDA7bGV0IGk9bmV3IE87aS53cml0ZVN0cnVjdChvZSxlKTtsZXQgbz1pLnJlc3VsdCgpLGE9aGUobyk7cmV0dXJuIHMuc2VhcmNoUGFyYW1zLnNldCgidCIsYSksdGhpcy53ZWJzb2NrZXQ9bmV3IFdlYlNvY2tldChzKSx0aGlzLndlYnNvY2tldC5iaW5hcnlUeXBlPSJhcnJheWJ1ZmZlciIsdGhpcy53ZWJzb2NrZXQub25vcGVuPSgpPT57Y29uc29sZS5sb2coIkNPTk5FQ1RFRCIpLG4oKX0sdGhpcy53ZWJzb2NrZXQub25jbG9zZT0oKT0+e2NvbnNvbGUubG9nKCJESVNDT05ORUNURUQiKSx0aGlzLndlYnNvY2tldD12b2lkIDAscigpfSx0aGlzLndlYnNvY2tldC5vbm1lc3NhZ2U9KGQpPT57bGV0IHU9bmV3IFVpbnQ4QXJyYXkoZC5kYXRhKTt0KHUpfSx0aGlzLndlYnNvY2tldC5vbmVycm9yPShkKT0+e2NvbnNvbGUubG9nKGBFUlJPUjogJHtKU09OLnN0cmluZ2lmeShkKX1gKSx0aGlzLndlYnNvY2tldD12b2lkIDAscigpfSxQcm9taXNlLnJlc29sdmUoMCl9ZGlzY29ubmVjdCgpe3RoaXMud2Vic29ja2V0Py5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMH19dmFyIFk9e3VzZXI6e3BhdGg6Ii91c2VyIixlbmRwb2ludDpRbixuYW1lOjB9LHB1c2g6e3BhdGg6Ii9wdXNoIixlbmRwb2ludDokbixuYW1lOjJ9LHBlZWs6e3BhdGg6Ii9wZWVrIixlbmRwb2ludDpqbixuYW1lOjF9LHB1bGw6e3BhdGg6Ii9wdWxsIixlbmRwb2ludDpHbixuYW1lOjN9fSxKaT17MDpZLnVzZXIsMjpZLnB1c2gsMTpZLnBlZWssMzpZLnB1bGx9LER1PXtbWS51c2VyLnBhdGhdOlkudXNlcixbWS5wdXNoLnBhdGhdOlkucHVzaCxbWS5wZWVrLnBhdGhdOlkucGVlayxbWS5wdWxsLnBhdGhdOlkucHVsbH07Y2xhc3MgWW57dXJsO2xpc3RlbmVyO2NvbnN0cnVjdG9yKGUpe3RoaXMudXJsPWU7dGhpcy5saXN0ZW5lcj1uZXcgQnIoZSl9YXN5bmMgY2FsbChlLHQpe2xldHtwYXRoOnJ9PUppW2VdLG49bmV3IFVSTChyLHRoaXMudXJsKTt0cnl7cmV0dXJuIGF3YWl0IFppKG4sdCl9Y2F0Y2h7cmV0dXJuIGMoMjUpfX19dmFyIEpuPShlKT0+bmV3IFluKGUuaGFuZGxlKTthc3luYyBmdW5jdGlvbiBaaShlLHQpe2xldCByPWF3YWl0IGZldGNoKGUse21ldGhvZDoiUE9TVCIsYm9keTp0LnJlc3VsdCgpLnNsaWNlKCl9KTtpZighci5vaylyZXR1cm4gYygyNCk7bGV0IG49YXdhaXQgTC5mcm9tUmVzcG9uc2Uocik7cmV0dXJuIHAobil9Y2xhc3MgUnR7ZW5jbGF2ZTtjcnlwdG87aG9zdDtjbG9jazt0cmFuc3BvcnQ7dXBkYXRlSG9zdE1ldGE7Y29uc3RydWN0b3IoZSx0LHIsbixzLGkpe3RoaXMuZW5jbGF2ZT1lO3RoaXMuY3J5cHRvPXQ7dGhpcy5ob3N0PXI7dGhpcy5jbG9jaz1uO3RoaXMudHJhbnNwb3J0PXM7dGhpcy51cGRhdGVIb3N0TWV0YT1pfWFzeW5jIGNhbGwoZSx0KXtsZXR7Y2xvY2s6cix0cmFuc3BvcnQ6bn09dGhpcyx7ZW5kcG9pbnQ6cyxuYW1lOml9PWUsbz1hd2FpdCB0aGlzLmlkZW50aXR5KCksYT1yLm5vdygpLFtkLHVdPWF3YWl0IHdyKG8sYSk7aWYodSE9PTApcmV0dXJuIGModSk7bGV0IGw9bmV3IE8sZj1hd2FpdCBzLmVuY29kZVJlcSh0aGlzLG8sZCx0LGwpO2lmKGYhPT0wKXJldHVybiBjKGYpO2xldCBoPXIubm93KCksW3ksbV09YXdhaXQgbi5jYWxsKGksbCksZz1yLm5vdygpO2lmKG0hPT0wKXJldHVybiBjKG0pO2xldFtiLEldPXkucmVhZFN0cnVjdChFcik7aWYoSSE9PTApcmV0dXJuIGMoSSk7aWYoYi5zdGF0dXMhPT0wKXJldHVybiBjKGIuc3RhdHVzKTtsZXQgRT17Y2xvY2tPZmZzZXQ6WG4oaCxiLnRpbWVSY3ZkLGIudGltZVNlbnQsZyksc3Vic2NyaXB0aW9uOmIuc3Vic2NyaXB0aW9ufSxTPWF3YWl0IHRoaXMudXBkYXRlSG9zdE1ldGEoRSk7aWYoUyE9PTApcmV0dXJuIGMoUyk7cmV0dXJuIHMuZGVjb2RlUmVzcCh5KX1pZGVudGl0eT0oKT0+e2xldHtob3N0OmUsZW5jbGF2ZTp0fT10aGlzO3JldHVybiB0LmRlcml2ZUlkZW50aXR5KGUubGFiZWwsZS5pZHg/PzApfTtzZWFsPWFzeW5jKGUpPT57bGV0e2NyeXB0bzp0LGVuY2xhdmU6cn09dGhpcyxuPWF3YWl0IHRoaXMuaWRlbnRpdHkoKTtyZXR1cm4gem4oZSxuLHQscil9O3JlZ2lzdGVyPSgpPT50aGlzLmNhbGwoWS51c2VyLFtdKTtwZWVrPShlKT0+dGhpcy5jYWxsKFkucGVlayxbZV0pO3B1c2g9KGUpPT50aGlzLmNhbGwoWS5wdXNoLGUpO3B1bGw9KGUpPT50aGlzLmNhbGwoWS5wdWxsLGUpO2xpc3Rlbj1hc3luYyhlLHQscik9PntsZXR7Y2xvY2s6bix0cmFuc3BvcnQ6c309dGhpcyx7bGlzdGVuZXI6aX09cyxvPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxhPW4ubm93KCksW2QsdV09YXdhaXQgd3IobyxhKTtpZih1IT09MClyZXR1cm4gdTtyZXR1cm4gYXdhaXQgaS5jb25uZWN0KGQsZSx0LHIpfTtpc0Nvbm5lY3RlZCgpe2xldCBlPXRoaXMudHJhbnNwb3J0Py5saXN0ZW5lcjtpZihlJiZ0eXBlb2YgZS5jb25uZWN0ZWQ9PT0iZnVuY3Rpb24iKXJldHVybiBlLmNvbm5lY3RlZCgpO3JldHVybiEwfWNsb3NlTGlzdGVuZXIoKXt0aGlzLnRyYW5zcG9ydD8ubGlzdGVuZXI/LmRpc2Nvbm5lY3QoKX19dmFyIGtyPXtlbmNvZGUoZSx0KXtsZXQgcj1lLndyaXRlVmFyU3RyaW5nKHQubGJsKTtpZihyIT09MClyZXR1cm4gcjtsZXQgbj1lLndyaXRlVmFySW50KHQuaWR4KTtpZihuIT09MClyZXR1cm4gbjtsZXQgcz1lLndyaXRlVmFySW50KHQubnVtKTtpZihzIT09MClyZXR1cm4gcztyZXR1cm4gZS53cml0ZUJ5dGVzKHQuaHNoKSxlLndyaXRlQnl0ZXModC5zaWcpLDB9LGRlY29kZShlKXtsZXRbdCxyXT1lLnJlYWRWYXJTdHJpbmcoKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWRWYXJJbnQoKTtpZihzIT09MClyZXR1cm4gYyhzKTtsZXRbaSxvXT1lLnJlYWRWYXJJbnQoKTtpZihvIT09MClyZXR1cm4gYyhvKTtsZXRbYSxkXT1lLnJlYWRCeXRlcyhQdCk7aWYoZCE9PTApcmV0dXJuIGMoZCk7bGV0W3UsbF09ZS5yZWFkQnl0ZXMoa2UpO2lmKGwhPT0wKXJldHVybiBjKGwpO3JldHVybiBwKHtsYmw6dCxpZHg6bixudW06aSxoc2g6YSxzaWc6dX0pfX07dmFyIHZyPXtlbmNvZGUoZSx0KXtsZXQgcj1lLndyaXRlU3RydWN0KGtyLHQuaGVhZCk7aWYociE9PTApcmV0dXJuIHI7bGV0IG49ZS53cml0ZVZhckJ5dGVzKHQuaW5kZXhFbmMpO2lmKG4hPT0wKXJldHVybiBuO2xldCBzPWUud3JpdGVWYXJCeXRlcyh0LmJvZHlFbmMpO2lmKHMhPT0wKXJldHVybiBzO3JldHVybiAwfSxkZWNvZGUoZSl7bGV0W3Qscl09ZS5yZWFkU3RydWN0KGtyKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWRWYXJCeXRlcygpO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldFtpLG9dPWUucmVhZFZhckJ5dGVzKCk7aWYobyE9PTApcmV0dXJuIGMobyk7cmV0dXJuIHAoe2hlYWQ6dCxpbmRleEVuYzpuLGJvZHlFbmM6aX0pfX07dmFyIERyPXtlbmNvZGUoZSx0KXtlLndyaXRlQnl0ZXModC5rZG0pO2xldCByPWUud3JpdGVWYXJCeXRlcyh0LmhlYWRDcGgpO2lmKHIhPT0wKXJldHVybiByO2xldCBuPWUud3JpdGVWYXJJbnQodC5sZW5Cb2R5KTtpZihuIT09MClyZXR1cm4gbjtpZih0LmxlbkJvZHk+MCYmdC5vZmZCb2R5IT09dm9pZCAwKXtsZXQgcz1lLndyaXRlVmFySW50KHQub2ZmQm9keSk7aWYocyE9PTApcmV0dXJuIHN9cmV0dXJuIDB9LGRlY29kZShlKXtsZXRbdCxyXT1lLnJlYWRCeXRlcyh2ZSk7aWYociE9PTApcmV0dXJuIGMocik7bGV0W24sc109ZS5yZWFkVmFyQnl0ZXMoKTtpZihzIT09MClyZXR1cm4gYyhzKTtsZXRbaSxvXT1lLnJlYWRWYXJJbnQoKTtpZihvIT09MClyZXR1cm4gYyhvKTtsZXQgYTtpZihpPjApe2xldFtkLHVdPWUucmVhZFZhckludCgpO2lmKHUhPT0wKXJldHVybiBjKHUpO2E9ZH1yZXR1cm4gcCh7a2RtOnQsaGVhZENwaDpuLGxlbkJvZHk6aSxvZmZCb2R5OmF9KX19O2FzeW5jIGZ1bmN0aW9uIFpuKGUsdCxyLG4scyl7bGV0IGk9YXdhaXQgcy5kZXJpdmVJZGVudGl0eShlLHQpLG89bmV3IE8sYT1uZXcgTyxkPTAsdT0wO2ZvcihsZXQgSSBvZiByKXtsZXQgdz1uZXcgTyxFPXcud3JpdGVTdHJ1Y3QoZGUsSS5oZWFkKTtpZihFIT09MClyZXR1cm4gYyhFKTtsZXQgUz13LnJlc3VsdCgpLFA9YXdhaXQgaS5rZG1Gb3IoUyksaz1zLmRlcml2ZUNpcGhlcihQLCJlbmNyeXB0IiksTT1hd2FpdCBrLmVuY3J5cHQoUyksSD1JLmJvZHk/YXdhaXQgay5lbmNyeXB0KEkuYm9keSk6bmV3IFVpbnQ4QXJyYXkoMCksQz1JLmhlYWQubGVuPjAmJkkuaGVhZC5oc2ghPT12b2lkIDA/SC5sZW5ndGg6MCxLPXtrZG06UCxoZWFkQ3BoOk0sbGVuQm9keTpDLG9mZkJvZHk6Qz4wP3U6dm9pZCAwfSxfPW8ud3JpdGVTdHJ1Y3QoRHIsSyk7aWYoXyE9PTApcmV0dXJuIGMoXyk7aWYoSS5ib2R5KWEud3JpdGVCeXRlcyhIKSx1Kz1ILmxlbmd0aDtkKyt9bGV0IGw9YS5yZXN1bHQoKSxmPW8ucmVzdWx0KCksaD1hd2FpdCBuLmJsYWtlMyhmKSx5PWF3YWl0IGkuc2lnbihoKSxtPXtsYmw6ZSxpZHg6dCxudW06ZCxoc2g6aCxzaWc6eX0sZz1uZXcgTztnLndyaXRlU3RydWN0KHZyLHtoZWFkOm0saW5kZXhFbmM6Zixib2R5RW5jOmx9KTtsZXQgYj1nLnJlc3VsdCgpO3JldHVybiBwKGIpfWFzeW5jIGZ1bmN0aW9uIGVzKGUsdCxyKXtsZXRbbixzXT12ci5kZWNvZGUobmV3IEwoZSkpO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldHtoZWFkOmksaW5kZXhFbmM6byxib2R5RW5jOmF9PW4sZD1hd2FpdCByLmRlcml2ZUlkZW50aXR5KGkubGJsLGkuaWR4KTtpZighYXdhaXQgdC5jaGVja1NpZ0VkMjU1MTkoaS5zaWcsaS5oc2gsZC5wdWJsaWNLZXkpKXJldHVybiBjKDMpO2xldCBsPWF3YWl0IHQuYmxha2UzKG8pO2lmKCFYKGwsaS5oc2gpKXJldHVybiBjKDE5KTtsZXQgZj1uZXcgTChvKSxoPVtdO2ZvcihsZXQgbT0wO208aS5udW07bSsrKXtsZXRbZyxiXT1mLnJlYWRTdHJ1Y3QoRHIpO2lmKGIhPT0wKXJldHVybiBjKGIpO2gucHVzaChnKX1pZihoLmxlbmd0aCE9PWkubnVtKXJldHVybiBjKDE0KTtsZXQgeT1bXTtmb3IobGV0IG0gb2YgaCl7bGV0IGc9ci5kZXJpdmVDaXBoZXIobS5rZG0sImRlY3J5cHQiKSxiO3RyeXtiPWF3YWl0IGcuZGVjcnlwdChtLmhlYWRDcGgpfWNhdGNoe3JldHVybiBjKDIwKX1sZXRbSSx3XT1kZS5kZWNvZGUobmV3IEwoYikpO2lmKHchPT0wKXJldHVybiBjKHcpO2xldCBFO2lmKG0ubGVuQm9keT4wJiZtLm9mZkJvZHkhPT12b2lkIDApe2lmKEkuaHNoPT09dm9pZCAwKXJldHVybiBjKDE0KTtsZXQgUz1hLnNsaWNlKG0ub2ZmQm9keSxtLm9mZkJvZHkrbS5sZW5Cb2R5KTt0cnl7RT1hd2FpdCBnLmRlY3J5cHQoUyl9Y2F0Y2h7cmV0dXJuIGMoMjApfWxldCBQPWF3YWl0IHQuYmxha2UzKEUpO2lmKCFYKFAsSS5oc2gpKXJldHVybiBjKDE5KX15LnB1c2goe2hlYWQ6SSxib2R5OkV9KX1yZXR1cm4gcCh5KX1hc3luYyBmdW5jdGlvbiB0cyh7bm93OmUsYm9kOnQsY3J5cHRvOnJ9KXtsZXQgbj1hd2FpdCByLmdlblJhbmRvbUJ5dGVzKDgpLHM9bmV3IE8saT1zLndyaXRlU3RydWN0KGllLHtpZDpuLHRzOmV9KTtpZihpIT09MClyZXR1cm4gYyhpKTtsZXQgbz1zLnJlc3VsdCgpO3JldHVybiBMdCh7bm93OmUsZWlkOm8sY3RyOjAsYm9kOnQsY3J5cHRvOnJ9KX1hc3luYyBmdW5jdGlvbiBMdCh7bm93OmUsZWlkOnQsY3RyOnIsYm9kOm4sY3J5cHRvOnN9KXtsZXQgaT1uZXcgTCh0KSxbbyxhXT1pZS5kZWNvZGUoaSk7aWYoYSE9PTApcmV0dXJuIGMoYSk7bGV0IGQ9ZS5nZXRUaW1lKCktby50cy5nZXRUaW1lKCksdSxsPW4/Lmxlbmd0aD8/MDtpZihuJiZsPjApdT1hd2FpdCBzLmJsYWtlMyhuKTtyZXR1cm4gcCh7ZWlkOnQsb2ZmOmQsY3RyOnIsbGVuOmwsaHNoOnV9KX1mdW5jdGlvbiBlbyhlLHQpe2xldCByPWUubGVuZ3RoPHQubGVuZ3RoP2UubGVuZ3RoOnQubGVuZ3RoO2ZvcihsZXQgbj0wO248cjtuKyspaWYoZVtuXSE9PXRbbl0pcmV0dXJuIGVbbl0tdFtuXTtyZXR1cm4gZS5sZW5ndGgtdC5sZW5ndGh9YXN5bmMgZnVuY3Rpb24geXQoZSx0KXtsZXQgcj1BcnJheS5mcm9tKGUpO3Iuc29ydChlbyk7bGV0IG49MDtmb3IobGV0IG8gb2YgciluKz1vLmxlbmd0aDtsZXQgcz1uZXcgVWludDhBcnJheShuKSxpPTA7Zm9yKGxldCBvIG9mIHIpcy5zZXQobyxpKSxpKz1vLmxlbmd0aDtyZXR1cm4gdC5ibGFrZTMocyl9ZnVuY3Rpb24gdG8oZSl7bGV0IHQ9bmV3IE8scj10LndyaXRlVmFyQnl0ZXMoZS5laWQpO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldCBuPXQud3JpdGVEYXRlKGUudXBkYXRlZEF0KTtpZihuIT09MClyZXR1cm4gYyhuKTtsZXQgcz10LndyaXRlVmFySW50KGUuY3RyKTtpZihzIT09MClyZXR1cm4gYyhzKTtyZXR1cm4gcCh0LnJlc3VsdCgpKX1hc3luYyBmdW5jdGlvbiBPdChlLHQpe2xldCByPVtdO2ZvcihsZXQgbiBvZiBlKXtsZXRbcyxpXT10byhuKTtpZihpIT09MHx8IXMpcmV0dXJuIGMoaSk7ci5wdXNoKHMpfXJldHVybiBwKGF3YWl0IHl0KHIsdCkpfXZhciBFbD1TeW1ib2woIk1hc3RlclNlZWQiKSxBbD1TeW1ib2woIlNlYWxlZE1hc3RlcktleSIpLHllPTMyLHJzPTI0K3llKzE2O2Z1bmN0aW9uIG10KGUpe2lmKGUuYnl0ZUxlbmd0aCE9PXllKXJldHVybiBjKDEwKTtyZXR1cm4gcChlKX1mdW5jdGlvbiBMZShlKXtpZihlLmJ5dGVMZW5ndGghPT1ycylyZXR1cm4gYygxMCk7cmV0dXJuIHAoZSl9dmFyIFVsPVN5bWJvbCgiRW50aXR5SUQiKTtmdW5jdGlvbiBucyhlKXtyZXR1cm4idHlwZSJpbiBlfXZhciBCbD1TeW1ib2woIkRlcml2YXRpb25TZWVkIiksa2w9U3ltYm9sKCJQdWJsaWNLZXkiKSx2bD1TeW1ib2woIlByaXZhdGVLZXkiKSxEbD1TeW1ib2woIkhvc3RTcGVjaWZpY0tleVBhaXIiKSxDbD1TeW1ib2woIkhhc2giKTtmdW5jdGlvbiBybyhlKXtpZighZSlyZXR1cm4hMTtpZih0eXBlb2YgZSE9PSJvYmplY3QiKXJldHVybiExO2lmKCJib2R5ImluIGU9PT0hMSlyZXR1cm4hMTtpZigidHlwZSJpbiBlPT09ITEpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gbm8oZSl7aWYoIWUuYm9kfHxlLmJvZC5sZW5ndGg9PT0wKXtsZXQgbj17b2ZmOmUub2ZmLGN0cjplLmN0cixlaWQ6ZS5laWR9O3JldHVybiBwKG4pfWxldCB0PVNyKGUuYm9kKTtpZihybyh0KT09PSExKXJldHVybiBjb25zb2xlLndhcm4oIm1zZyBib2R5IGludmFsaWQiLHQpLGMoMTQpO2xldCByPXtvZmY6ZS5vZmYsY3RyOmUuY3RyLGVpZDplLmVpZCxnaWQ6dC5naWQscGlkOnQucGlkLHRhZ3M6dC50YWdzLHR5cGU6dC50eXBlLGJvZHk6dC5ib2R5fTtyZXR1cm4gcChyKX1jbGFzcyBLdHthcHBsaWVyO2VtaXR0ZXI9bmV3IHB0O2NsZWFyZXI7b25EaXJ0eUVpZHM7Y2FjaGVEcml2ZW47cGVlckluZ2VzdDtjb25zdHJ1Y3RvcihlLHQscixuKXt0aGlzLmFwcGxpZXI9ZTt0aGlzLmNsZWFyZXI9dCx0aGlzLm9uRGlydHlFaWRzPXIsdGhpcy5jYWNoZURyaXZlbj1uPy5jYWNoZURyaXZlbj8/ITEsdGhpcy5wZWVySW5nZXN0PW4/LnBlZXJJbmdlc3R9YXBwbHk9YXN5bmMoZSk9PntsZXQgdD1bXSxyPVtdO2ZvcihsZXQgYSBvZiBlKXtsZXRbZCx1XT1ubyhhKTtpZihyLnB1c2godSksdSE9PTApY29udGludWU7dC5wdXNoKGQpfWxldHtzdGF0czpuLHR5cGVzOnMsZWlkczppfT1hd2FpdCB0aGlzLmFwcGxpZXIodCksbz1bXTtmb3IobGV0IGE9MDthPGUubGVuZ3RoO2ErKyl7bGV0IGQ9clthXSx1PW5bYV07aWYoZCE9PTApe28ucHVzaChkKTtjb250aW51ZX1pZih1IT09MCl7by5wdXNoKHUpO2NvbnRpbnVlfW8ucHVzaCgwKX1pZighdGhpcy5jYWNoZURyaXZlbilmb3IobGV0IGEgb2Ygcyl0aGlzLmVtaXR0ZXIuZW1pdChhLG51bGwpO2lmKGkubGVuZ3RoPjApdGhpcy5vbkRpcnR5RWlkcz8uKGkpO3JldHVybiBvfTtjbGVhcj1hc3luYygpPT57bGV0IGU9YXdhaXQgdGhpcy5jbGVhcmVyKCk7aWYoZSE9PTApcmV0dXJuIGU7cmV0dXJuIHRoaXMuZW1pdHRlci5lbWl0QWxsKG51bGwpLGV9O25vdGlmeT0oZSk9Pntmb3IobGV0IHQgb2YgZSl0aGlzLmVtaXR0ZXIuZW1pdCh0LG51bGwpfTtyZWZyZXNoPWFzeW5jKGUpPT57aWYodGhpcy5wZWVySW5nZXN0KXthd2FpdCB0aGlzLnBlZXJJbmdlc3QoZSk7cmV0dXJufX07b249KGUsdCk9Pnt0aGlzLmVtaXR0ZXIuYWRkRXZlbnRMaXN0ZW5lcihlLHQpfTtvZmY9KGUsdCk9Pnt0aGlzLmVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLHQpfX12YXIgaj0iZW50aXRpZXMiLFZ0PSJlbnRpdHlfdHlwZV9jcmVhdGVkX2F0IixUcj0iZW50aXR5X3R5cGVfdXBkYXRlZF9hdCIsSHI9ImVudGl0eV90eXBlX2dyb3VwX2lkIixNcj0iZW50aXR5X3R5cGVfcGFyZW50X2lkIixKZT0iZW50aXR5X3RhZ3MiLHNzPSJkYiIsaXM9MTM7ZnVuY3Rpb24gc28oZSl7cmV0dXJuInR5cCJpbiBlfWZ1bmN0aW9uIGlvKGUpe2xldCB0PXtib2Q6ZS5ib2R5LGNyZDplLmNyZWF0ZWRBdCwuLi5lLmN0ciE9PTA/e2N0cjplLmN0cn06e30sZWlkOkQoZS5laWQpLGdpZDplLmdpZCxwaWQ6ZS5waWQ/RChlLnBpZCk6dm9pZCAwLHRnczplLnRhZ3MsdHlwOmUudHlwZSx1cGQ6ZS51cGRhdGVkQXR9O2lmKHQuZ2lkPT09dm9pZCAwKWRlbGV0ZSB0LmdpZDtpZih0LnBpZD09PXZvaWQgMClkZWxldGUgdC5waWQ7aWYodC50Z3M9PT12b2lkIDApZGVsZXRlIHQudGdzO2lmKHQuY3RyPT09dm9pZCAwKWRlbGV0ZSB0LmN0cjtyZXR1cm4gdH1mdW5jdGlvbiBvbyhlKXtpZighcShlKSlyZXR1cm57ZWlkOkQoZS5laWQpLHVwZDplLnVwZGF0ZWRBdCwuLi5lLmN0ciE9PTA/e2N0cjplLmN0cn06e319O3JldHVybiBpbyhlKX1mdW5jdGlvbiBaZShlKXtyZXR1cm57Ym9keTplLmJvZCxjcmVhdGVkQXQ6ZS5jcmQsdXBkYXRlZEF0OmUudXBkLGN0cjplLmN0cj8/MCx0eXBlOmUudHlwLGVpZDpmZShlLmVpZCksZ2lkOmUuZ2lkLHBpZDplLnBpZD9mZShlLnBpZCk6dm9pZCAwLC4uLmUudGdzIT09dm9pZCAwP3t0YWdzOmUudGdzfTp7fX19ZnVuY3Rpb24gQ3IoZSl7aWYoc28oZSkpcmV0dXJuIFplKGUpO3JldHVybntlaWQ6ZmUoZS5laWQpLHVwZGF0ZWRBdDplLnVwZCxjdHI6ZS5jdHI/PzB9fWNsYXNzIG9ze2RiO29wZW5pbmc7YXN5bmMgaW5pdCgpe2F3YWl0IHRoaXMuZW5zdXJlRGIoKX1hc3luYyBlbnN1cmVEYigpe2lmKHRoaXMuZGIpcmV0dXJuIHRoaXMuZGI7aWYodGhpcy5vcGVuaW5nKXJldHVybiB0aGlzLm9wZW5pbmc7cmV0dXJuIHRoaXMub3BlbmluZz1jbygpLnRoZW4oKGUpPT4oZS5vbnZlcnNpb25jaGFuZ2U9KCk9PntpZihlLmNsb3NlKCksdGhpcy5kYj09PWUpdGhpcy5kYj12b2lkIDB9LHRoaXMuZGI9ZSx0aGlzLm9wZW5pbmc9dm9pZCAwLGUpLChlKT0+e3Rocm93IHRoaXMub3BlbmluZz12b2lkIDAsZX0pLHRoaXMub3BlbmluZ31hcHBseT1hc3luYyhlKT0+e2xldCB0PW5ldyBTZXQscj1bXSxuO3RyeXtuPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm57c3RhdHM6ZS5tYXAoKCk9PjE2KSx0eXBlczp0LGVpZHM6cn19bGV0IHM9bi50cmFuc2FjdGlvbihqLCJyZWFkd3JpdGUiKSxpPXMub2JqZWN0U3RvcmUoaik7cmV0dXJuIG5ldyBQcm9taXNlKChvKT0+e2xldCBhPUFycmF5KGUubGVuZ3RoKS5maWxsKDApO2lmKGUubGVuZ3RoPDEpe28oe3N0YXRzOltdLHR5cGVzOnQsZWlkczpyfSk7cmV0dXJufXMub25jb21wbGV0ZT0oKT0+e28oe3N0YXRzOmEsdHlwZXM6dCxlaWRzOnJ9KX0scy5vbmVycm9yPSgpPT57Zm9yKGxldCB1PTA7dTxhLmxlbmd0aDt1KyspaWYoYVt1XT09PXZvaWQgMClhW3VdPTE4O28oe3N0YXRzOmEsdHlwZXM6dCxlaWRzOnJ9KX07bGV0IGQ9bmV3IE1hcDtmb3IobGV0IHU9MDt1PGUubGVuZ3RoO3UrKyl7bGV0IGw9ZVt1XSxmPUQobC5laWQpLGg9e29wOmwsaW5kZXg6dX0seT1kLmdldChmKTtpZih5KXkucHVzaChoKTtlbHNlIGQuc2V0KGYsW2hdKX1mb3IobGV0W3UsbF1vZiBkKXtpZihsLmxlbmd0aDwxKWNvbnRpbnVlO2xldCBmPWkuZ2V0KHUpO2Yub25zdWNjZXNzPSgpPT57bGV0IGg9Zi5yZXN1bHQseT1oP0NyKGgpOnZvaWQgMCxtPSExO2ZvcihsZXR7b3A6ZyxpbmRleDpifW9mIGwpe2xldFtJLHddPWV0KHksZyk7aWYodyE9PTApe2FbYl09dztjb250aW51ZX1pZihJPT09dm9pZCAwKXthW2JdPTEyO2NvbnRpbnVlfW09ITA7Zm9yKGxldCBFIG9mIHR0KHksSSkpdC5hZGQoRSk7eT1JfWlmKG0pci5wdXNoKGxbMF0ub3AuZWlkKTtpZih5KXtsZXQgZz1pLnB1dChvbyh5KSk7Zy5vbmVycm9yPShiKT0+e2IucHJldmVudERlZmF1bHQoKTtmb3IobGV0e2luZGV4Okl9b2YgbClhW0ldPTE4fX19LGYub25lcnJvcj0oKT0+e2ZvcihsZXR7aW5kZXg6aH1vZiBsKWFbaF09MTh9fX0pfTthc3luYyBjbGVhcigpe2xldCBlO3RyeXtlPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gMTZ9bGV0IHQ9ZS50cmFuc2FjdGlvbihqLCJyZWFkd3JpdGUiKSxyPXQub2JqZWN0U3RvcmUoaik7cmV0dXJuIG5ldyBQcm9taXNlKChuKT0+e3Qub25jb21wbGV0ZT0oKT0+bigwKSx0Lm9uZXJyb3I9KCk9Pm4oMTgpLHIuY2xlYXIoKX0pfWFzeW5jIGdldFJvdyhlKXtsZXQgdDt0cnl7dD1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIGMoMTYpfWxldCByPUQoZSkscz10LnRyYW5zYWN0aW9uKGosInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoaik7cmV0dXJuIG5ldyBQcm9taXNlKChpKT0+e2xldCBvPXMuZ2V0KHIpO28ub25zdWNjZXNzPSgpPT57bGV0IGE9by5yZXN1bHQ7aWYoIWEpaShwKHZvaWQgMCkpO2Vsc2UgaShwKENyKGEpKSl9LG8ub25lcnJvcj0oKT0+aShjKDE4KSl9KX1hc3luYyBnZXRFbnQoZSl7bGV0W3Qscl09YXdhaXQgdGhpcy5nZXRSb3coZSk7aWYociE9PTApcmV0dXJuIGMocik7aWYodD09PXZvaWQgMHx8IXEodCkpcmV0dXJuIHAodm9pZCAwKTtyZXR1cm4gcCh0KX1hc3luYyBnZXRBbGxPZlR5cGVVcGRhdGVkQmV0d2VlbihlLHQscil7bGV0IG47dHJ5e249YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBjKDE2KX1sZXQgaT1uLnRyYW5zYWN0aW9uKGosInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoaikuaW5kZXgoVHIpO3JldHVybiBuZXcgUHJvbWlzZSgobyk9PntsZXQgYT1pLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbZSx0XSxbZSxyXSkpO2Eub25zdWNjZXNzPSgpPT57bGV0IGQ9YS5yZXN1bHQ7byhwKGQubWFwKFplKSkpfSxhLm9uZXJyb3I9KCk9Pm8oYygxOCkpfSl9YXN5bmMgZ2V0R3JvdXBNZW1iZXJzKGUsdCl7bGV0IHI7dHJ5e3I9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBjKDE2KX1sZXQgcz1yLnRyYW5zYWN0aW9uKGosInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoaikuaW5kZXgoSHIpO3JldHVybiBuZXcgUHJvbWlzZSgoaSk9PntsZXQgbz1zLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFtlLHRdKSk7by5vbnN1Y2Nlc3M9KCk9PntsZXQgYT1vLnJlc3VsdDtpKHAoYS5tYXAoWmUpKSl9LG8ub25lcnJvcj0oKT0+aShjKDE4KSl9KX1hc3luYyBnZXRBbGxPZlR5cGUoZSl7bGV0IHQ7dHJ5e3Q9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBjKDE2KX1sZXQgbj10LnRyYW5zYWN0aW9uKGosInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoaikuaW5kZXgoVnQpO3JldHVybiBuZXcgUHJvbWlzZSgocyk9PntsZXQgaT1uLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbZV0sW2UsW11dKSk7aS5vbnN1Y2Nlc3M9KCk9PntsZXQgbz1pLnJlc3VsdDtzKHAoby5tYXAoWmUpKSl9LGkub25lcnJvcj0oKT0+cyhjKDE4KSl9KX1hc3luYyBnZXRCeVRhZyhlLHQpe2xldCByO3RyeXtyPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gYygxNil9bGV0IHM9ci50cmFuc2FjdGlvbihqLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGopLmluZGV4KEplKTtyZXR1cm4gbmV3IFByb21pc2UoKGkpPT57bGV0IG89cy5nZXRBbGwoSURCS2V5UmFuZ2Uub25seSh0KSk7by5vbnN1Y2Nlc3M9KCk9PntsZXQgZD1vLnJlc3VsdC5maWx0ZXIoKHUpPT51LnR5cD09PWUpLm1hcChaZSk7aShwKGQpKX0sby5vbmVycm9yPSgpPT5pKGMoMTgpKX0pfWFzeW5jIGdldEFsbEVudGl0aWVzKGUpe2lmKCJwaWQiaW4gZSl7bGV0IHQ7dHJ5e3Q9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBjKDE2KX1sZXQgcj1EKGUucGlkKSxzPXQudHJhbnNhY3Rpb24oaiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShqKS5pbmRleChNcik7cmV0dXJuIG5ldyBQcm9taXNlKChpKT0+e2xldCBvPXMuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoW2UudHlwZSxyXSkpO28ub25zdWNjZXNzPSgpPT57bGV0IGQ9by5yZXN1bHQubWFwKFplKTtpKHAoZCkpfSxvLm9uZXJyb3I9KCk9PmkoYygxOCkpfSl9ZWxzZSBpZigiZ2lkImluIGUpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0R3JvdXBNZW1iZXJzKGUudHlwZSxlLmdpZCk7ZWxzZSBpZigidGFnImluIGUpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QnlUYWcoZS50eXBlLGUudGFnKTtlbHNlIGlmKCJ1cGRhdGVkQmV0d2VlbiJpbiBlKXJldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKGUudHlwZSxlLnVwZGF0ZWRCZXR3ZWVuLnN0YXJ0LGUudXBkYXRlZEJldHdlZW4uZW5kKTtyZXR1cm4gYXdhaXQgdGhpcy5nZXRBbGxPZlR5cGUoZS50eXBlKX1hc3luYyBnZXRFbnRpdGllcyhlKXtsZXRbdCxyXT1hd2FpdCB0aGlzLmdldEFsbEVudGl0aWVzKGUpO2lmKHIhPT0wKXJldHVybiBjKHIpO3JldHVybiBwKHQpfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6ZX0pe2xldCB0O3RyeXt0PWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gYygxNil9bGV0IG49dC50cmFuc2FjdGlvbihqLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGopLmluZGV4KFZ0KTtyZXR1cm4gbmV3IFByb21pc2UoKHMpPT57bGV0IGk9SURCS2V5UmFuZ2UuYm91bmQoW2VdLFtlLFtdXSksbz1uLmNvdW50KGkpO28ub25zdWNjZXNzPSgpPT5zKHAoby5yZXN1bHQpKSxvLm9uZXJyb3I9KCk9PnMoYygxOCkpfSl9YXN5bmMgY2hlY2tzdW0oZSl7bGV0IHQ7dHJ5e3Q9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBjKDE2KX1sZXQgbj10LnRyYW5zYWN0aW9uKGosInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoaikscz1bXTtyZXR1cm4gbmV3IFByb21pc2UoKGkpPT57bGV0IG89bi5vcGVuQ3Vyc29yKCk7by5vbnN1Y2Nlc3M9KCk9PntsZXQgYT1vLnJlc3VsdDtpZihhKXtsZXQgZD1hLnZhbHVlO3MucHVzaChfdChDcihkKSkpLGEuY29udGludWUoKX1lbHNlIE90KHMsZSkudGhlbihpKX0sby5vbmVycm9yPSgpPT5pKGMoMTgpKX0pfX1mdW5jdGlvbiBhbyhlLHQpe2lmKCFlLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoaikpZS5jcmVhdGVPYmplY3RTdG9yZShqLHtrZXlQYXRoOiJlaWQiLGF1dG9JbmNyZW1lbnQ6ITF9KTtsZXQgcj10Lm9iamVjdFN0b3JlKGopO2lmKCFyLmluZGV4TmFtZXMuY29udGFpbnMoVnQpKXIuY3JlYXRlSW5kZXgoVnQsWyJ0eXAiLCJjcmQiXSx7dW5pcXVlOiExfSk7aWYoIXIuaW5kZXhOYW1lcy5jb250YWlucyhUcikpci5jcmVhdGVJbmRleChUcixbInR5cCIsInVwZCJdLHt1bmlxdWU6ITF9KTtpZighci5pbmRleE5hbWVzLmNvbnRhaW5zKEhyKSlyLmNyZWF0ZUluZGV4KEhyLFsidHlwIiwiZ2lkIl0se3VuaXF1ZTohMX0pO2lmKCFyLmluZGV4TmFtZXMuY29udGFpbnMoTXIpKXIuY3JlYXRlSW5kZXgoTXIsWyJ0eXAiLCJwaWQiXSx7dW5pcXVlOiExfSk7aWYoci5pbmRleE5hbWVzLmNvbnRhaW5zKEplKSl7aWYoci5pbmRleChKZSkua2V5UGF0aCE9PSJ0Z3MiKXIuZGVsZXRlSW5kZXgoSmUpfWlmKCFyLmluZGV4TmFtZXMuY29udGFpbnMoSmUpKXIuY3JlYXRlSW5kZXgoSmUsInRncyIse3VuaXF1ZTohMSxtdWx0aUVudHJ5OiEwfSl9ZnVuY3Rpb24gY28oKXtyZXR1cm4gbmV3IFByb21pc2UoKGUsdCk9PntsZXQgcj1pbmRleGVkREIub3Blbihzcyxpcyk7ci5vbnVwZ3JhZGVuZWVkZWQ9KCk9PntsZXR7cmVzdWx0Om4sdHJhbnNhY3Rpb246c309cjtpZighcyl7dChFcnJvcigiVHJhbnNhY3Rpb24gaXMgbnVsbCBkdXJpbmcgRW50REIgdXBncmFkZSIpKTtyZXR1cm59dHJ5e2FvKG4scyl9Y2F0Y2goaSl7dChpIGluc3RhbmNlb2YgRXJyb3I/aTpFcnJvcihTdHJpbmcoaSkpKX19LHIub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gRW50REIgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtzc30g4oaSIHYke2lzfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LHIub25zdWNjZXNzPSgpPT5lKHIucmVzdWx0KSxyLm9uZXJyb3I9KCk9PnQoci5lcnJvcj8/RXJyb3IoIkVudERCIEluZGV4ZWREQiBvcGVuIGZhaWxlZCIpKX0pfWFzeW5jIGZ1bmN0aW9uIGFzKCl7bGV0IGU9bmV3IG9zO3JldHVybiBhd2FpdCBlLmluaXQoKSxlfWNsYXNzIFJye2VudHM9bmV3IE1hcDt1c2VJbmRleDtieVR5cGU9bmV3IE1hcDtieVR5cGVQaWQ9bmV3IE1hcDtieVR5cGVHaWQ9bmV3IE1hcDtieVR5cGVUYWc9bmV3IE1hcDtjb25zdHJ1Y3RvcihlPVtdLHQpe3RoaXMudXNlSW5kZXg9dD8uaW5kZXhlcyE9PSExO2ZvcihsZXQgciBvZiBlKXRoaXMucHV0KHIpfXB1dChlKXtsZXQgdD1EKGUuZWlkKSxyPXRoaXMuZW50cy5nZXQodCk7aWYociE9PXZvaWQgMCYmcShyKSl0aGlzLnVuaW5kZXgodCxyKTtpZih0aGlzLmVudHMuc2V0KHQsZSkscShlKSl0aGlzLmluZGV4KHQsZSl9ZGVsKGUpe2xldCB0PXRoaXMuZW50cy5nZXQoZSk7aWYodD09PXZvaWQgMClyZXR1cm47aWYocSh0KSl0aGlzLnVuaW5kZXgoZSx0KTt0aGlzLmVudHMuZGVsZXRlKGUpfWluZGV4KGUsdCl7aWYoIXRoaXMudXNlSW5kZXgpcmV0dXJuO2xldCByPXRoaXMuYnlUeXBlLmdldCh0LnR5cGUpO2lmKCFyKXI9bmV3IE1hcCx0aGlzLmJ5VHlwZS5zZXQodC50eXBlLHIpO2lmKHIuc2V0KGUsdCksdC5waWQpe2xldCBuPUQodC5waWQpLHM9dGhpcy5ieVR5cGVQaWQuZ2V0KHQudHlwZSk7aWYoIXMpcz1uZXcgTWFwLHRoaXMuYnlUeXBlUGlkLnNldCh0LnR5cGUscyk7bGV0IGk9cy5nZXQobik7aWYoIWkpaT1uZXcgTWFwLHMuc2V0KG4saSk7aS5zZXQoZSx0KX1pZih0eXBlb2YgdC5naWQ9PT0ic3RyaW5nIil7bGV0IG49dGhpcy5ieVR5cGVHaWQuZ2V0KHQudHlwZSk7aWYoIW4pbj1uZXcgTWFwLHRoaXMuYnlUeXBlR2lkLnNldCh0LnR5cGUsbik7bGV0IHM9bi5nZXQodC5naWQpO2lmKCFzKXM9bmV3IE1hcCxuLnNldCh0LmdpZCxzKTtzLnNldChlLHQpfWlmKHQudGFncyl7bGV0IG49dGhpcy5ieVR5cGVUYWcuZ2V0KHQudHlwZSk7aWYoIW4pbj1uZXcgTWFwLHRoaXMuYnlUeXBlVGFnLnNldCh0LnR5cGUsbik7Zm9yKGxldCBzIG9mIHQudGFncyl7bGV0IGk9bi5nZXQocyk7aWYoIWkpaT1uZXcgTWFwLG4uc2V0KHMsaSk7aS5zZXQoZSx0KX19fXVuaW5kZXgoZSx0KXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IHI9dGhpcy5ieVR5cGUuZ2V0KHQudHlwZSk7aWYocil7aWYoci5kZWxldGUoZSksci5zaXplPT09MCl0aGlzLmJ5VHlwZS5kZWxldGUodC50eXBlKX1pZih0LnBpZCl7bGV0IG49RCh0LnBpZCkscz10aGlzLmJ5VHlwZVBpZC5nZXQodC50eXBlKSxpPXM/LmdldChuKTtpZihpKXtpZihpLmRlbGV0ZShlKSxpLnNpemU9PT0wKXM/LmRlbGV0ZShuKX1pZihzJiZzLnNpemU9PT0wKXRoaXMuYnlUeXBlUGlkLmRlbGV0ZSh0LnR5cGUpfWlmKHR5cGVvZiB0LmdpZD09PSJzdHJpbmciKXtsZXQgbj10aGlzLmJ5VHlwZUdpZC5nZXQodC50eXBlKSxzPW4/LmdldCh0LmdpZCk7aWYocyl7aWYocy5kZWxldGUoZSkscy5zaXplPT09MCluPy5kZWxldGUodC5naWQpfWlmKG4mJm4uc2l6ZT09PTApdGhpcy5ieVR5cGVHaWQuZGVsZXRlKHQudHlwZSl9aWYodC50YWdzKXtsZXQgbj10aGlzLmJ5VHlwZVRhZy5nZXQodC50eXBlKTtpZihuKXtmb3IobGV0IHMgb2YgdC50YWdzKXtsZXQgaT1uLmdldChzKTtpZihpKXtpZihpLmRlbGV0ZShlKSxpLnNpemU9PT0wKW4uZGVsZXRlKHMpfX1pZihuLnNpemU9PT0wKXRoaXMuYnlUeXBlVGFnLmRlbGV0ZSh0LnR5cGUpfX19Y2xlYXJJbmRleGVzKCl7dGhpcy5ieVR5cGUuY2xlYXIoKSx0aGlzLmJ5VHlwZVBpZC5jbGVhcigpLHRoaXMuYnlUeXBlR2lkLmNsZWFyKCksdGhpcy5ieVR5cGVUYWcuY2xlYXIoKX1idWNrZXRMaXN0KGUpe2lmKCFlfHxlLnNpemU9PT0wKXJldHVybltdO2xldCB0PVtdO2ZvcihsZXQgciBvZiBlLnZhbHVlcygpKXQucHVzaChyKTtyZXR1cm4gdH1hc3luYyBhcHBseShlKXtsZXQgdD1uZXcgU2V0LHI9W10sbj1bXTtmb3IobGV0IHMgb2YgZSl7bGV0IGk9RChzLmVpZCksbz10aGlzLmVudHMuZ2V0KGkpLFthLGRdPWV0KG8scyk7aWYoZCE9PTApe24ucHVzaChkKTtjb250aW51ZX1pZihhPT09dm9pZCAwKXtuLnB1c2goMTIpO2NvbnRpbnVlfWZvcihsZXQgdSBvZiB0dChvLGEpKXQuYWRkKHUpO3RoaXMucHV0KGEpLHIucHVzaChzLmVpZCksbi5wdXNoKDApfXJldHVybntzdGF0czpuLHR5cGVzOnQsZWlkczpyfX1hc3luYyBjbGVhcigpe3JldHVybiB0aGlzLmVudHMuY2xlYXIoKSx0aGlzLmNsZWFySW5kZXhlcygpLDB9YXN5bmMgZ2V0Um93KGUpe2xldCB0PUQoZSkscj10aGlzLmVudHMuZ2V0KHQpO3JldHVybiBwKHIpfWFzeW5jIGdldEVudChlKXtsZXRbdCxyXT1hd2FpdCB0aGlzLmdldFJvdyhlKTtpZihyIT09MClyZXR1cm4gYyhyKTtpZih0PT09dm9pZCAwfHwhcSh0KSlyZXR1cm4gcCh2b2lkIDApO3JldHVybiBwKHQpfWFzeW5jIGdldEFsbEVudGl0aWVzKHt0eXBlOmUsZ2lkOnQscGlkOnIsdGFnOm4sdXBkYXRlZEJldHdlZW46c30pe2lmKHRoaXMudXNlSW5kZXgpe2lmKHIhPT12b2lkIDApe2xldCBvPUQocik7cmV0dXJuIHAodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlUGlkLmdldChlKT8uZ2V0KG8pKSl9aWYodCE9PXZvaWQgMClyZXR1cm4gcCh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVHaWQuZ2V0KGUpPy5nZXQodCkpKTtpZihuIT09dm9pZCAwKXJldHVybiBwKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZVRhZy5nZXQoZSk/LmdldChuKSkpO2lmKHMhPT12b2lkIDApe2xldCBvPVtdLGE9dGhpcy5ieVR5cGUuZ2V0KGUpO2lmKGEpe2ZvcihsZXQgZCBvZiBhLnZhbHVlcygpKWlmKGQudXBkYXRlZEF0Pj1zLnN0YXJ0JiZkLnVwZGF0ZWRBdDw9cy5lbmQpby5wdXNoKGQpfXJldHVybiBwKG8pfXJldHVybiBwKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZS5nZXQoZSkpKX1sZXQgaT1bXTtpZihyIT09dm9pZCAwKXtmb3IobGV0IG8gb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKHEobykmJm8udHlwZT09PWUmJm8ucGlkJiZYKG8ucGlkLHIpKWkucHVzaChvKX1lbHNlIGlmKHQhPT12b2lkIDApe2ZvcihsZXQgbyBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYocShvKSYmby50eXBlPT09ZSYmKHR5cGVvZiBvLmdpZD09PSJzdHJpbmciJiZvLmdpZD09PXQpKWkucHVzaChvKX1lbHNlIGlmKG4hPT12b2lkIDApe2ZvcihsZXQgbyBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYocShvKSYmby50eXBlPT09ZSYmby50YWdzJiZvLnRhZ3MuaW5jbHVkZXMobikpaS5wdXNoKG8pfWVsc2UgaWYocyE9PXZvaWQgMCl7Zm9yKGxldCBvIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihxKG8pJiZvLnR5cGU9PT1lJiZvLnVwZGF0ZWRBdD49cy5zdGFydCYmby51cGRhdGVkQXQ8PXMuZW5kKWkucHVzaChvKX1lbHNlIGZvcihsZXQgbyBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYocShvKSYmby50eXBlPT09ZSlpLnB1c2gobyk7cmV0dXJuIHAoaSl9YXN5bmMgZ2V0RW50aXRpZXMoZSl7bGV0W3Qscl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcyhlKTtpZihyIT09MClyZXR1cm4gYyhyKTtyZXR1cm4gcCh0KX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOmV9KXtpZih0aGlzLnVzZUluZGV4KXJldHVybiBwKHRoaXMuYnlUeXBlLmdldChlKT8uc2l6ZT8/MCk7bGV0IHQ9MDtmb3IobGV0IHIgb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKHEocikmJnIudHlwZT09PWUpdCs9MTtyZXR1cm4gcCh0KX1hc3luYyBjaGVja3N1bShlKXtsZXQgdD1bXTtmb3IobGV0IHIgb2YgdGhpcy5lbnRzLnZhbHVlcygpKXQucHVzaChfdChyKSk7cmV0dXJuIE90KHQsZSl9fWFzeW5jIGZ1bmN0aW9uIGNzKGUpe2xldCB0PWF3YWl0IGFzKCk7aWYoZT8uY2FjaGU9PT0hMSlyZXR1cm4gdDtyZXR1cm4gbmV3IExyKHQsdm9pZCAwLHtpbmRleGVzOmU/LmluZGV4ZXN9KX1jbGFzcyBMcnttZW07ZHVyYWJsZTt3YXJtZWQ9bmV3IFNldDtsaXN0ZW5lcnM9bmV3IFNldDtjaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtjb25zdHJ1Y3RvcihlLHQscil7aWYodGhpcy5kdXJhYmxlPWUsdGhpcy5tZW09bmV3IFJyKHQ/P1tdLHtpbmRleGVzOnI/LmluZGV4ZXN9KSx0KWZvcihsZXQgbiBvZiB0KXRoaXMud2FybWVkLmFkZChuLnR5cGUpfXN1YnNjcmliZShlKXtyZXR1cm4gdGhpcy5saXN0ZW5lcnMuYWRkKGUpLCgpPT57dGhpcy5saXN0ZW5lcnMuZGVsZXRlKGUpfX1lbWl0KGUpe2lmKGUuc2l6ZTwxKXJldHVybjtmb3IobGV0IHQgb2YgdGhpcy5saXN0ZW5lcnMpdChlKX1ydW4oZSl7bGV0IHQ9dGhpcy5jaGFpbi50aGVuKGUsZSk7cmV0dXJuIHRoaXMuY2hhaW49dC50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLHR9YXBwbHkoZSl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9Pnthd2FpdCB0aGlzLnB1bGxFaWRzKGUubWFwKChpKT0+aS5laWQpKTtsZXQgdD15byh0aGlzLm1lbSxlKTt0aGlzLmVtaXQodC50eXBlcyk7bGV0IHI9YXdhaXQgdGhpcy5kdXJhYmxlLmFwcGx5KGUpLHtjaGFuZ2VkOm4sc3RhdHVzOnN9PWF3YWl0IHRoaXMucHVsbEVpZHMoZS5tYXAoKGkpPT5pLmVpZCkpO2lmKHRoaXMuZW1pdChuKSxzIT09MClyZXR1cm57c3RhdHM6ZS5tYXAoKCk9PnMpLHR5cGVzOnIudHlwZXMsZWlkczpyLmVpZHN9O3JldHVybiByfSl9Y2xlYXIoKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldCBlPWF3YWl0IHRoaXMuZHVyYWJsZS5jbGVhcigpO2lmKGUhPT0wKXJldHVybiBlO2xldCB0PXRoaXMubWVtLmVudHMuc2l6ZT4wO3JldHVybiBhd2FpdCB0aGlzLm1lbS5jbGVhcigpLHRoaXMud2FybWVkLmNsZWFyKCksMH0pfWluZ2VzdEZyb21EdXJhYmxlKGUpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0e2NoYW5nZWQ6dCxzdGF0dXM6cn09YXdhaXQgdGhpcy5wdWxsRWlkcyhlKTtyZXR1cm4gdGhpcy5lbWl0KHQpLHJ9KX1hc3luYyBwdWxsRWlkcyhlKXtsZXQgdD1uZXcgU2V0LHI9bmV3IFNldDtmb3IobGV0IG4gb2YgZSl7bGV0IHM9RChuKTtpZihyLmhhcyhzKSljb250aW51ZTtyLmFkZChzKTtsZXQgaT10aGlzLm1lbS5lbnRzLmdldChzKSxbbyxhXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KG4pO2lmKGEhPT0wKXJldHVybntjaGFuZ2VkOnQsc3RhdHVzOmF9O2lmKG8pe2lmKHRoaXMubWVtLnB1dChvKSwhaXx8IXVvKGksbykpe2lmKHEobykpdC5hZGQoby50eXBlKTtpZihpIT09dm9pZCAwJiZxKGkpKXQuYWRkKGkudHlwZSl9fWVsc2UgaWYoaSE9PXZvaWQgMCl7aWYodGhpcy5tZW0uZGVsKHMpLHEoaSkpdC5hZGQoaS50eXBlKX19cmV0dXJue2NoYW5nZWQ6dCxzdGF0dXM6MH19YXN5bmMgd2FybVR5cGUoZSl7aWYodGhpcy53YXJtZWQuaGFzKGUpKXJldHVybiAwO2xldFt0LHJdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRFbnRpdGllcyh7dHlwZTplfSk7aWYociE9PTApcmV0dXJuIHI7aWYodClmb3IobGV0IG4gb2YgdCl7bGV0IHM9RChuLmVpZCksaT10aGlzLm1lbS5lbnRzLmdldChzKTtpZighaXx8aG8obixpKSl0aGlzLm1lbS5wdXQobil9cmV0dXJuIHRoaXMud2FybWVkLmFkZChlKSwwfWFzeW5jIGdldFJvdyhlKXtsZXQgdD1EKGUpO2lmKHRoaXMubWVtLmVudHMuaGFzKHQpKXJldHVybiB0aGlzLm1lbS5nZXRSb3coZSk7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntpZih0aGlzLm1lbS5lbnRzLmhhcyh0KSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KGUpO2xldFtyLG5dPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coZSk7aWYobiE9PTApcmV0dXJuIGMobik7aWYocil0aGlzLm1lbS5wdXQocik7cmV0dXJuIHAocil9KX1hc3luYyBnZXRFbnQoZSl7bGV0W3Qscl09YXdhaXQgdGhpcy5nZXRSb3coZSk7aWYociE9PTApcmV0dXJuIGMocik7aWYodD09PXZvaWQgMHx8IXEodCkpcmV0dXJuIHAodm9pZCAwKTtyZXR1cm4gcCh0KX1hc3luYyBnZXRFbnRpdGllcyhlKXtpZighdGhpcy53YXJtZWQuaGFzKGUudHlwZSkpe2xldCB0PWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKGUudHlwZSkpO2lmKHQhPT0wKXJldHVybiBjKHQpfXJldHVybiB0aGlzLm1lbS5nZXRFbnRpdGllcyhlKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOmV9KXtpZighdGhpcy53YXJtZWQuaGFzKGUpKXtsZXQgdD1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZShlKSk7aWYodCE9PTApcmV0dXJuIGModCl9cmV0dXJuIHRoaXMubWVtLmNvdW50RW50aXRpZXMoe3R5cGU6ZX0pfWFzeW5jIGNoZWNrc3VtKGUpe3JldHVybiB0aGlzLmR1cmFibGUuY2hlY2tzdW0oZSl9fWZ1bmN0aW9uIHVvKGUsdCl7aWYocShlKSE9PXEodCkpcmV0dXJuITE7aWYoZS5jdHIhPT10LmN0cilyZXR1cm4hMTtpZihlLnVwZGF0ZWRBdC5nZXRUaW1lKCkhPT10LnVwZGF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoIVgoZS5laWQsdC5laWQpKXJldHVybiExO2lmKCFxKGUpfHwhcSh0KSlyZXR1cm4hMDtpZihlLmNyZWF0ZWRBdC5nZXRUaW1lKCkhPT10LmNyZWF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoZS50eXBlIT09dC50eXBlKXJldHVybiExO2lmKGUuZ2lkIT09dC5naWQpcmV0dXJuITE7aWYoIWZvKGUucGlkLHQucGlkKSlyZXR1cm4hMTtpZighbG8oZS50YWdzLHQudGFncykpcmV0dXJuITE7cmV0dXJuIHBvKGUuYm9keSx0LmJvZHkpfWZ1bmN0aW9uIGxvKGUsdCl7aWYoZT09PXQpcmV0dXJuITA7aWYoZT09PXZvaWQgMHx8dD09PXZvaWQgMClyZXR1cm4hMTtpZihlLmxlbmd0aCE9PXQubGVuZ3RoKXJldHVybiExO2ZvcihsZXQgcj0wO3I8ZS5sZW5ndGg7cisrKWlmKGVbcl0hPT10W3JdKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIGZvKGUsdCl7aWYoZT09PXZvaWQgMCYmdD09PXZvaWQgMClyZXR1cm4hMDtpZihlPT09dm9pZCAwfHx0PT09dm9pZCAwKXJldHVybiExO3JldHVybiBYKGUsdCl9ZnVuY3Rpb24gcG8oZSx0KXtpZihPYmplY3QuaXMoZSx0KSlyZXR1cm4hMDtpZihlIGluc3RhbmNlb2YgVWludDhBcnJheSYmdCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuIFgoZSx0KTtpZihlIGluc3RhbmNlb2YgRGF0ZSYmdCBpbnN0YW5jZW9mIERhdGUpcmV0dXJuIGUuZ2V0VGltZSgpPT09dC5nZXRUaW1lKCk7dHJ5e3JldHVybiBYKE1lKGUpLE1lKHQpKX1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gaG8oZSx0KXtsZXQgcj1lLnVwZGF0ZWRBdC5nZXRUaW1lKCksbj10LnVwZGF0ZWRBdC5nZXRUaW1lKCk7aWYociE9PW4pcmV0dXJuIHI+bjtyZXR1cm4gZS5jdHI+dC5jdHJ9ZnVuY3Rpb24geW8oZSx0KXtsZXQgcj1uZXcgU2V0LG49W107Zm9yKGxldCBzIG9mIHQpe2xldCBpPUQocy5laWQpLG89ZS5lbnRzLmdldChpKSxbYSxkXT1ldChvLHMpO2lmKGQhPT0wKXtuLnB1c2goZCk7Y29udGludWV9aWYoYT09PXZvaWQgMCl7bi5wdXNoKDEyKTtjb250aW51ZX1mb3IobGV0IHUgb2YgdHQobyxhKSlyLmFkZCh1KTtlLnB1dChhKSxuLnB1c2goMCl9cmV0dXJue3N0YXRzOm4sdHlwZXM6cn19ZnVuY3Rpb24gcShlKXtyZXR1cm4idHlwZSJpbiBlfWZ1bmN0aW9uIG1vKGUpe2lmKCFBcnJheS5pc0FycmF5KGUpfHxlLmxlbmd0aD09PTApcmV0dXJuO2xldCB0PW5ldyBTZXQscj1bXTtmb3IobGV0IG4gb2YgZSl7aWYodHlwZW9mIG4hPT0ic3RyaW5nInx8bi5sZW5ndGg9PT0wKWNvbnRpbnVlO2lmKHQuaGFzKG4pKWNvbnRpbnVlO3QuYWRkKG4pLHIucHVzaChuKX1yZXR1cm4gci5sZW5ndGg+MD9yOnZvaWQgMH1mdW5jdGlvbiBfdChlKXtyZXR1cm57ZWlkOmUuZWlkLGN0cjplLmN0cix1cGRhdGVkQXQ6ZS51cGRhdGVkQXR9fWZ1bmN0aW9uIGRzKGUpe2xldCB0PW5ldyBMKGUuZWlkKSxbcixuXT10LnJlYWRTdHJ1Y3QoaWUpO2lmKG4hPT0wKXJldHVybiBjKG4pO3JldHVybiBwKHtlaWQ6ZS5laWQsY3RyOmUuY3RyLHVwZGF0ZWRBdDpuZXcgRGF0ZShyLnRzLmdldFRpbWUoKStlLm9mZil9KX1mdW5jdGlvbiBldChlLHQpe2xldCByPW5ldyBMKHQuZWlkKSxbbixzXT1yLnJlYWRTdHJ1Y3QoaWUpO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldCBpPW5ldyBEYXRlKG4udHMuZ2V0VGltZSgpK3Qub2ZmKTtpZihlIT09dm9pZCAwJiZpPD1lLnVwZGF0ZWRBdClyZXR1cm4gYygxNSk7aWYobnModCkpe2xldCBvPW1vKHQudGFncyk7cmV0dXJuIHAoe2VpZDp0LmVpZCxnaWQ6dC5naWQscGlkOnQucGlkLC4uLm8hPT12b2lkIDA/e3RhZ3M6b306e30sdHlwZTp0LnR5cGUsY3JlYXRlZEF0Om4udHMsdXBkYXRlZEF0OmksY3RyOnQuY3RyLGJvZHk6dC5ib2R5fSl9cmV0dXJuIHAoe2VpZDp0LmVpZCx1cGRhdGVkQXQ6aSxjdHI6dC5jdHJ9KX1mdW5jdGlvbiB0dChlLHQpe2xldCByPW5ldyBTZXQ7aWYoZSE9PXZvaWQgMCYmcShlKSlyLmFkZChlLnR5cGUpO2lmKHEodCkpci5hZGQodC50eXBlKTtyZXR1cm5bLi4ucl19Y2xhc3MgTnR7aW5mbGlnaHQ9bnVsbDthZ2Fpbj0hMTtydW4oZSl7aWYodGhpcy5hZ2Fpbj0hMCx0aGlzLmluZmxpZ2h0KXJldHVybiB0aGlzLmluZmxpZ2h0O3JldHVybiB0aGlzLmluZmxpZ2h0PXRoaXMuZHJhaW4oZSksdGhpcy5pbmZsaWdodH1hc3luYyBmbHVzaCgpe2lmKCF0aGlzLmluZmxpZ2h0KXJldHVybjt0cnl7YXdhaXQgdGhpcy5pbmZsaWdodH1jYXRjaHt9fWFzeW5jIGRyYWluKGUpe3RyeXt0aGlzLmFnYWluPSExO2xldCB0PWF3YWl0IGUoKTt3aGlsZSh0aGlzLmFnYWluKXRoaXMuYWdhaW49ITEsdD1hd2FpdCBlKCk7cmV0dXJuIHR9ZmluYWxseXt0aGlzLmluZmxpZ2h0PW51bGx9fX12YXIgdXM9MTAwO2NsYXNzIE9ye3RpbWVyPW51bGw7ZGVsYXlNczt3b3JrO3RhaWw9bmV3IE50O2NvbnN0cnVjdG9yKGUsdCl7dGhpcy5kZWxheU1zPWU8MD8wOmUsdGhpcy53b3JrPXR9c2NoZWR1bGUoKXtpZih0aGlzLmRlbGF5TXM8PTApe3RoaXMuZmlyZSgpO3JldHVybn1pZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lcik7dGhpcy50aW1lcj1zZXRUaW1lb3V0KCgpPT57dGhpcy50aW1lcj1udWxsLHRoaXMuZmlyZSgpfSx0aGlzLmRlbGF5TXMpfWFzeW5jIGZsdXNoKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKTthd2FpdCB0aGlzLnRhaWwuZmx1c2goKX1jYW5jZWwoKXtpZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj1udWxsfWZpcmUoKXtyZXR1cm4gdGhpcy50YWlsLnJ1bih0aGlzLndvcmspfX1mdW5jdGlvbiBscyhlKXtsZXQgdD1uZXcgTChlLmVpZCksW3Isbl09aWUuZGVjb2RlKHQpO2lmKG4hPT0wKXJldHVybjtyZXR1cm4gci50cy5nZXRUaW1lKCkrZS5vZmZ9ZnVuY3Rpb24gZ28oZSx0KXtsZXQgcj1scyhlKSxuPWxzKHQpO2lmKHI9PT12b2lkIDAmJm49PT12b2lkIDApcmV0dXJuIDA7aWYocj09PXZvaWQgMClyZXR1cm4gMTtpZihuPT09dm9pZCAwKXJldHVybi0xO2lmKG4hPT1yKXJldHVybiBuLXI7cmV0dXJuIHQuY3RyLWUuY3RyfWZ1bmN0aW9uIHJ0KGUsdCl7cmV0dXJuIGUuc2xpY2UoKS5zb3J0KChyLG4pPT5nbyh0KHIpLHQobikpKX12YXIgS3I9e3BoYXNlOiJpZGxlIn0sZ3Q9NTA7ZnVuY3Rpb24gVnIoZSx0LHIpe2lmKGU8PTB8fHQ8PTApcmV0dXJuITE7aWYoZT09PTF8fGU9PT10KXJldHVybiEwO3JldHVybiBlJXI9PT0wfWZ1bmN0aW9uIGZzKGUsdCl7aWYodHlwZW9mIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iPT09ImZ1bmN0aW9uIil7bmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IoZSx0KTtyZXR1cm59bGV0IHI9VVJMLmNyZWF0ZU9iamVjdFVSTChlKSxuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTtuLmhyZWY9cixuLmRvd25sb2FkPXQsZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChuKSxuLmNsaWNrKCksZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChuKSxVUkwucmV2b2tlT2JqZWN0VVJMKHIpfWZ1bmN0aW9uIHBzKGUsdCxyKXtsZXQgbj1bXSxzPVtdLGk9MDtmb3IobGV0IG8gb2YgZSl7bGV0IGE9dChvKTtpZihzLmxlbmd0aD4wJiZpK2E+ciluLnB1c2gocykscz1bXSxpPTA7aWYocy5wdXNoKG8pLGkrPWEsaT49ciluLnB1c2gocykscz1bXSxpPTB9aWYocy5sZW5ndGg+MCluLnB1c2gocyk7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gX3IoZSx0LHIpe2xldCBuPWUubGVuZ3RoO2lmKG48MSlyZXR1cm5bXTtsZXQgcz1BcnJheShuKSxpPTAsbz1NYXRoLm1pbihNYXRoLm1heCgxLHQpLG4pLGE9YXN5bmMoKT0+e3doaWxlKCEwKXtsZXQgdT1pO2lmKGkrPTEsdT49bilyZXR1cm47c1t1XT1hd2FpdCByKGVbdV0sdSl9fSxkPVtdO2ZvcihsZXQgdT0wO3U8bzt1KyspZC5wdXNoKGEoKSk7cmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKGQpLHN9YXN5bmMgZnVuY3Rpb24gcXQoZSx0LHIsbil7bGV0IHM9bmV3IEwoZS5oZWFkQ3BoKSxbaSxvXT1zLnJlYWRTdHJ1Y3QoSHQpO2lmKG8hPT0wKXJldHVybiBjKG8pO2xldHtzaWc6YSxrZG06ZCxoZWFkQ3BoOnV9PWk7aWYoIWF3YWl0IG4uY2hlY2tTaWdFZDI1NTE5KGEsdSx0KSlyZXR1cm4gYygzKTtsZXQgZj1yLmRlcml2ZUNpcGhlcihkLCJkZWNyeXB0IiksaDt0cnl7aD1hd2FpdCBmLmRlY3J5cHQodSl9Y2F0Y2h7cmV0dXJuIGMoMjApfXJldHVybiBwKHtrZG06ZCxoZWFkRW5jOmh9KX12YXIgc3Q9ImYiLEZ0PSJ0IixudD0iZSI7ZnVuY3Rpb24gYm8oZSl7aWYoZT09PSEwfHxlPT09RnQpcmV0dXJuIEZ0O2lmKGU9PT1udClyZXR1cm4gbnQ7cmV0dXJuIHN0fWZ1bmN0aW9uIGhzKGUpe3JldHVybiBlIT09MCYmZSE9PTE1JiZlIT09MTgmJmUhPT0xN31mdW5jdGlvbiBOcihlLHQscil7aWYoZS5hcGxkPXQsdD09PW50JiZyIT09dm9pZCAwKWUuZXJyPXI7ZWxzZSBkZWxldGUgZS5lcnJ9YXN5bmMgZnVuY3Rpb24gV3QoZSx0LHIsbil7bGV0IHM9bj8uYm9keSE9PSExLGk9Ym8odC5hcGxkKSxvPXQuYm9keSxhPW8/Lmxlbmd0aD8/MCxkO2lmKHMmJm8mJmE+MClkPWF3YWl0IHIuYmxha2UzKG8pO2xldCB1PXtlaWQ6dC5laWQsb2ZmOnQub2ZmPz8wLGN0cjp0LmN0cj8/MCxsZW46YSxoc2g6ZH0sbD17aGFzaDplLGhlYWQ6dSxhcGxkOml9O2lmKHMmJm8hPT12b2lkIDApbC5ib2R5PW87aWYoaT09PW50JiZ0LmVyciE9PXZvaWQgMClsLmVycj10LmVycjtyZXR1cm4gbH12YXIgcXI9MTA0ODU3NixGcj0xMDQ4NTc2LG1zPTY0O2Z1bmN0aW9uIFNvKGUpe3JldHVybiBlLnNpZy5sZW5ndGgrZS5rZG0ubGVuZ3RoK2UuaGVhZENwaC5sZW5ndGgrZS5ib2R5Q3BoLmxlbmd0aH1hc3luYyBmdW5jdGlvbiB3byhlLHQscixuLHMpe2lmKG4ubGVuZ3RoPDEpcmV0dXJuIDA7bGV0W2ksb109YXdhaXQgZS5wdXNoKG4pO2lmKG8hPT0wKXJldHVybiBvO2lmKCFpKXJldHVybiAyNztmb3IobGV0IGQgb2YgaSl7aWYoZC5zdGF0dXMhPT0wKXtjb25zb2xlLmVycm9yKCJwdXNoIGVyciIsZCk7Y29udGludWV9bGV0IHU9c1tkLmlkeF07aWYoIXUpe2NvbnNvbGUuZXJyb3IoIm5vIGhhc2giLGQpO2NvbnRpbnVlfWF3YWl0IHQudXBsb2Fkcy5kZXEocixbdV0pfWxldCBhPWF3YWl0IHQuaG9zdHMuZ2V0KHIpO2lmKGEpe2xldCBkPWEubGFzdFNlcSx1PWQsbD1bXTtmb3IobGV0IGYgb2YgaSlpZihmLnN0YXR1cz09PTApbC5wdXNoKGYuc2VxKTtsLnNvcnQoKGYsaCk9PmYtaCk7Zm9yKGxldCBmIG9mIGwpaWYoZj09PWQrMSlkPWY7aWYoZD51KWF3YWl0IHQuaG9zdHMudG91Y2gocixkKX1yZXR1cm4gMH1hc3luYyBmdW5jdGlvbiB5cyhlLHQpe2lmKHQubGVuZ3RoPDEpcmV0dXJuIHAoW10pO2xldCByPW5ldyBNYXAsbj1bXTtmb3IobGV0IGEgb2YgdClyLnNldChhLnNlcSxhKSxuLnB1c2goYS5zZXEpO2xldFtzLGldPWF3YWl0IGUucHVsbChuKTtpZihpIT09MClyZXR1cm4gYyhpKTtpZighcylyZXR1cm4gYygyNyk7bGV0IG89W107Zm9yKGxldHtzZXE6YSxib2R5Q3BoOmR9b2Ygcyl7bGV0IHU9ci5nZXQoYSk7aWYoIXUpY29udGludWU7by5wdXNoKHtkbDp1LGJvZHlDcGg6ZH0pfXJldHVybiBwKG8pfWFzeW5jIGZ1bmN0aW9uIElvKGUsdCxyLG4pe2lmKG4ubGVuZ3RoPDEpcmV0dXJuIHAoe3BhcnRzOltdLGhhc2hlczpbXX0pO2xldCBzPVtdLGk9W10sbz1bXSxhPW5ldyBNYXA7Zm9yKGxldHtkbDp1LGJvZHlDcGg6bH1vZiBuKXtsZXR7aGVhZDpmLGtkbTpoLHNlcTp5LGhvc3Q6bX09dSxbZyxiXT1hd2FpdCBncyh1LHIpO2lmKGIhPT0wfHwhZyl7bGV0IEM9YS5nZXQobSk/P1tdO0MucHVzaCh5KSxhLnNldChtLEMpO2NvbnRpbnVlfWxldHtoZWFkRW5jOkksaGVhZEVuY0hhc2g6d309ZyxFPXQuZGVyaXZlQ2lwaGVyKGgsImRlY3J5cHQiKSxbUyxQXT1hd2FpdCBJcihJLGwsRSxyLHcpO2lmKFAhPT0wfHwhUyl7bGV0IEM9YS5nZXQobSk/P1tdO0MucHVzaCh5KSxhLnNldChtLEMpO2NvbnRpbnVlfWxldCBrPXtoZWFkOmYsYm9keTpTLmJvZH0sTT1TLmhlYWRIYXNoO28ucHVzaCh7a2V5Ok0sZGF0YTp3cyhrKX0pLHMucHVzaChrKSxpLnB1c2goTSk7bGV0IEg9YS5nZXQobSk/P1tdO0gucHVzaCh5KSxhLnNldChtLEgpfWxldCBkPWF3YWl0IGUubWVzc2FnZXMuYWRkKG8pO2ZvcihsZXRbdSxsXW9mIGEpYXdhaXQgZS5kb3dubG9hZHMuZGVxKHUsbCk7Zm9yKGxldCB1PTA7dTxkLmxlbmd0aDt1Kyspe2xldCBsPWRbdV07aWYobCE9PTAmJmwhPT0xNSljb25zb2xlLmVycm9yKCJFUlIgc3RvcmluZyIsVVtsXSwiZm9yIG1lc3NhZ2UiLHUpfXJldHVybiBwKHtwYXJ0czpzLGhhc2hlczppfSl9YXN5bmMgZnVuY3Rpb24gZ3MoZSx0KXtsZXQgcj1lLmhlYWRFbmM7aWYoIXIpe2xldCBzPW5ldyBPLGk9cy53cml0ZVN0cnVjdChkZSxlLmhlYWQpO2lmKGkhPT0wKXJldHVybiBjKGkpO3I9cy5yZXN1bHQoKX1pZihlLmhlYWRFbmNIYXNoKXJldHVybiBwKHtoZWFkRW5jOnIsaGVhZEVuY0hhc2g6ZS5oZWFkRW5jSGFzaH0pO2xldCBuPWF3YWl0IHQuYmxha2UzKHIpO3JldHVybiBwKHtoZWFkRW5jOnIsaGVhZEVuY0hhc2g6bn0pfWFzeW5jIGZ1bmN0aW9uIGJzKGUsdCxyKXtsZXQgbj1uZXcgU2V0O2ZvcihsZXQgbyBvZiB0KW4uYWRkKEQobykpO2lmKG4uc2l6ZTwxKXJldHVybjtsZXQgcz1BcnJheS5mcm9tKGF3YWl0IGUuZG93bmxvYWRzLmxpc3QoKSk7aWYocy5sZW5ndGg8MSlyZXR1cm47bGV0IGk9bmV3IE1hcDtmb3IobGV0IG8gb2Ygcyl7bGV0IGE7aWYoby5oZWFkRW5jSGFzaClhPUQoby5oZWFkRW5jSGFzaCk7ZWxzZXtsZXRbdSxsXT1hd2FpdCBncyhvLHIpO2lmKGwhPT0wfHwhdSljb250aW51ZTthPUQodS5oZWFkRW5jSGFzaCl9aWYoIW4uaGFzKGEpKWNvbnRpbnVlO2xldCBkPWkuZ2V0KG8uaG9zdCk/P1tdO2QucHVzaChvLnNlcSksaS5zZXQoby5ob3N0LGQpfWZvcihsZXRbbyxhXW9mIGkpYXdhaXQgZS5kb3dubG9hZHMuZGVxKG8sYSl9YXN5bmMgZnVuY3Rpb24gV3Ioe2Nvbm46ZSxzdG9yZTp0LGVuY2xhdmU6cixob3N0Om4sY3J5cHRvOnMsb25Qcm9ncmVzczppLHBlZWtQcm9ncmVzc0V2ZXJ5Om8scGVla0NvbmN1cnJlbmN5OmF9KXtsZXQgZD1hd2FpdCBlLmlkZW50aXR5KCksdT1bXSxbbCxmXT1hd2FpdCBlLnBlZWsobi5sYXN0U2VxKTtpZihmIT09MClyZXR1cm4gZjtsZXQgaD1sLmxlbmd0aCx5PW8/P2d0LG09YT8/bXM7aWYoaSYmaD4wKWkoe3BoYXNlOiJwZWVrIixob3N0Om4ubGFiZWwsZG9uZTowLHRvdGFsOmh9KTtsZXQgZz0wLGI9YXdhaXQgX3IobCxtLGFzeW5jKHcpPT57bGV0W0UsU109YXdhaXQgcXQodyxkLnB1YmxpY0tleSxyLHMpLFA7aWYoUyE9PTB8fCFFKVA9e29rOiExLHNlcTp3LnNlcSxzdGF0OlN9O2Vsc2V7bGV0IGs9YXdhaXQgcy5ibGFrZTMoRS5oZWFkRW5jKTtQPXtvazohMCxzZXE6dy5zZXEsa2RtOkUua2RtLGhlYWRFbmM6RS5oZWFkRW5jLGhlYWRFbmNIYXNoOmt9fWlmKGcrPTEsaSYmVnIoZyxoLHkpKWkoe3BoYXNlOiJwZWVrIixob3N0Om4ubGFiZWwsZG9uZTpnLHRvdGFsOmh9KTtyZXR1cm4gUH0pLEk9bmV3IFNldDtmb3IobGV0IHcgb2YgYil7aWYoIXcub2spe2NvbnNvbGUuZXJyb3IoInBlZWs6IGRlY3J5cHRpbmcgaXRlbSBoZWFkIix3LnN0YXQpO2NvbnRpbnVlfWxldCBFPUQody5oZWFkRW5jSGFzaCk7aWYoYXdhaXQgdC5tZXNzYWdlcy5oYXMody5oZWFkRW5jSGFzaCkpe2NvbnNvbGUuaW5mbygicGVlazogbG9jYWwgbXNnOyBza2lwIGRvd25sb2FkLCBkZXEgdXBsb2FkIiksYXdhaXQgdC51cGxvYWRzLmRlcShuLmxhYmVsLFt3LmhlYWRFbmNIYXNoXSksYXdhaXQgdC5kb3dubG9hZHMuZGVxKG4ubGFiZWwsW3cuc2VxXSk7Y29udGludWV9aWYoSS5oYXMoRSkpe2F3YWl0IHQuZG93bmxvYWRzLmRlcShuLmxhYmVsLFt3LnNlcV0pO2NvbnRpbnVlfWxldCBQPW5ldyBMKHcuaGVhZEVuYyksW2ssTV09UC5yZWFkU3RydWN0KGRlKTtpZihNIT09MCl7Y29uc29sZS5lcnJvcigicGVlazogcmVhZGluZyBpdGVtIGhlYWQiLE0pO2NvbnRpbnVlfUkuYWRkKEUpLHUucHVzaCh7a2RtOncua2RtLGhlYWQ6ayxzZXE6dy5zZXEsaG9zdDpuLmxhYmVsLGhlYWRFbmM6dy5oZWFkRW5jLGhlYWRFbmNIYXNoOncuaGVhZEVuY0hhc2h9KX1pZihhd2FpdCB0LmRvd25sb2Fkcy5lbnEodSksbC5sZW5ndGg+MCl7bGV0IHc9TWF0aC5tYXgoLi4ubC5tYXAoKEUpPT5FLnNlcSkpO2F3YWl0IHQuaG9zdHMucmVjb3JkU3RhdHMobi5sYWJlbCx7bGFzdFNlcTp3fSl9aWYoaSlpKHtwaGFzZToicGVlayIsaG9zdDpuLmxhYmVsLGRvbmU6aCx0b3RhbDpofSk7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gU3Moe2Nvbm46ZSxzdG9yZTp0LGhvc3Q6cixtYXhQdXNoQnl0ZXM6bixvblByb2dyZXNzOnN9KXtsZXQgaT1uPz9xcixvPWF3YWl0IHQudXBsb2Fkcy5saXN0KHIubGFiZWwpLGE9by5sZW5ndGgsZD0wO2lmKHMmJmE+MClzKHtwaGFzZToicHVzaCIsaG9zdDpyLmxhYmVsLGRvbmU6MCx0b3RhbDphfSk7bGV0IHU9W10sbD1bXSxmPTAsaD1hc3luYygpPT57aWYodS5sZW5ndGg8MSlyZXR1cm4gMDtsZXQgeT11Lmxlbmd0aCxtPWF3YWl0IHdvKGUsdCxyLmxhYmVsLHUsbCk7aWYodT1bXSxsPVtdLGY9MCxtPT09MCl7aWYoZCs9eSxzKXMoe3BoYXNlOiJwdXNoIixob3N0OnIubGFiZWwsZG9uZTpkLHRvdGFsOmF9KX1yZXR1cm4gbX07Zm9yKGxldCB5IG9mIG8pe2xldCBtPWF3YWl0IHQubWVzc2FnZXMuZ2V0KHkpO2lmKCFtKXtkKz0xO2NvbnRpbnVlfWxldCBnPXsuLi5tLmhlYWQsYm9kOm0uYm9keX0sW2IsSV09YXdhaXQgZS5zZWFsKGcpO2lmKEkhPT0wKXJldHVybiBJO2lmKCFiKXJldHVybiAxMjtsZXQgdz1TbyhiKTtpZih1Lmxlbmd0aD4wJiZmK3c+aSl7bGV0IEU9YXdhaXQgaCgpO2lmKEUhPT0wKXJldHVybiBFfWlmKHUucHVzaChiKSxsLnB1c2goeSksZis9dyxmPj1pKXtsZXQgRT1hd2FpdCBoKCk7aWYoRSE9PTApcmV0dXJuIEV9fXJldHVybiBoKCl9YXN5bmMgZnVuY3Rpb24genIoe2Nvbm46ZSxzdG9yZTp0LGVuY2xhdmU6cixob3N0Om4sY3J5cHRvOnMsbWF4UHVsbEJ5dGVzOmksb25Qcm9ncmVzczpvfSxhKXtsZXQgZD1pPz9Gcix1PWF3YWl0IHQuZG93bmxvYWRzLmxpc3QoKSxsPUFycmF5LmZyb20odSkuZmlsdGVyKChiKT0+Yi5ob3N0PT09bi5sYWJlbCk7aWYobC5sZW5ndGg8MSlyZXR1cm4gMTU7bGV0IGY9cnQobCwoYik9PmIuaGVhZCksaD1wcyhmLChiKT0+Yi5oZWFkLmxlbixkKSx5PWYubGVuZ3RoLG09MDtpZihvKW8oe3BoYXNlOiJwdWxsIixob3N0Om4ubGFiZWwsZG9uZTowLHRvdGFsOnl9KTtsZXQgZz15cyhlLGhbMF0pO2ZvcihsZXQgYj0wO2I8aC5sZW5ndGg7YisrKXtsZXRbSSx3XT1hd2FpdCBnO2lmKHchPT0wfHwhSSlyZXR1cm4gdztpZihtKz1oW2JdLmxlbmd0aCxvKW8oe3BoYXNlOiJwdWxsIixob3N0Om4ubGFiZWwsZG9uZTptLHRvdGFsOnl9KTtsZXQgRT1oW2IrMV07aWYoRSlnPXlzKGUsRSk7aWYobylvKHtwaGFzZToib3BlbiIsaG9zdDpuLmxhYmVsLGRvbmU6bSx0b3RhbDp5fSk7bGV0IFM9cnQoSSwoayk9PmsuZGwuaGVhZCksWyxQXT1hd2FpdCBJbyh0LHIscyxTKTtpZihQIT09MClyZXR1cm4gUDtpZihhKXtpZihvKW8oe3BoYXNlOiJleGVjIixob3N0Om4ubGFiZWwsZG9uZTptLHRvdGFsOnl9KTthd2FpdCBhKCl9fXJldHVybiAwfWZ1bmN0aW9uIHdzKHtoZWFkOmUsYm9keTp0fSl7bGV0IHI9e2VpZDplLmVpZCxib2R5OnQsYXBsZDpzdH07aWYoZS5vZmYhPT0wKXIub2ZmPWUub2ZmO2lmKGUuY3RyIT09MClyLmN0cj1lLmN0cjtyZXR1cm4gcn1hc3luYyBmdW5jdGlvbiBJcyhlLHtjb25uOnQsc3RvcmU6cixlbmNsYXZlOm4saG9zdDpzLGNyeXB0bzppLG9uUHJvZ3Jlc3M6b30sYSl7bGV0IGQ9cy5sYWJlbCx1PWF3YWl0IHQuaWRlbnRpdHkoKSxsPW5ldyBMKGUpLFtmLGhdPWwucmVhZFN0cnVjdHMoVHQpO2lmKGghPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjb2Rpbmcgbm90aWYiLFVbaF0pO3JldHVybn1sZXQgeT0hMSxnPShhd2FpdCByLmhvc3RzLmdldChkKSk/Lmxhc3RTZXEsYj1bXSxJPSExO2ZvcihsZXQgUyBvZiBmKXtsZXRbUCxrXT1hd2FpdCBxdCh7c2VxOlMuc2VxLGhlYWRDcGg6Uy5oZWFkQ3BofSx1LnB1YmxpY0tleSxuLGkpO2lmKGshPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjcnlwdGluZyBub3RpZiIsVVtrXSk7Y29udGludWV9bGV0IE09YXdhaXQgaS5ibGFrZTMoUC5oZWFkRW5jKTtpZihhd2FpdCByLm1lc3NhZ2VzLmhhcyhNKSljb250aW51ZTtsZXQgSD1uZXcgTChQLmhlYWRFbmMpLFtDLEtdPUgucmVhZFN0cnVjdChkZSk7aWYoSyE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBwYXJzZSBoZWFkIixVW0tdKTtjb250aW51ZX1pZighUy5ib2R5Q3BoJiZDLmxlbj4wKUk9ITAsYXdhaXQgci5kb3dubG9hZHMuZW5xKFt7c2VxOlMuc2VxLGhvc3Q6ZCxrZG06UC5rZG0saGVhZDpDLGhlYWRFbmM6UC5oZWFkRW5jLGhlYWRFbmNIYXNoOk19XSk7ZWxzZSBiLnB1c2goey4uLlAsaGVhZDpDLGJvZHlDcGg6Uy5ib2R5Q3BoLGhlYWRFbmNIYXNoOk19KTtpZihnPT09dm9pZCAwfHxTLnNlcSE9PWcrMSljb25zb2xlLmxvZygib3V0IG9mIHNlcSIsUy5zZXEsZykseT0hMDtlbHNlIGc9Uy5zZXF9aWYoZyE9PXZvaWQgMClhd2FpdCByLmhvc3RzLnRvdWNoKHMubGFiZWwsZyk7bGV0IHc9W107Zm9yKGxldCBTIG9mIGIpe2xldCBQPW4uZGVyaXZlQ2lwaGVyKFMua2RtLCJkZWNyeXB0IiksW2ssTV09YXdhaXQgSXIoUy5oZWFkRW5jLFMuYm9keUNwaCxQLGkpO2lmKE0hPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gb3BlbiBib2R5IixVW01dKTtjb250aW51ZX13LnB1c2goe2tleTpTLmhlYWRFbmNIYXNoLGRhdGE6d3Moe2hlYWQ6Uy5oZWFkLGJvZHk6ay5ib2R9KX0pfWxldCBFPWF3YWl0IHIubWVzc2FnZXMuYWRkKHcpO2ZvcihsZXQgUz0wO1M8RS5sZW5ndGg7UysrKXtsZXQgUD1FW1NdO2lmKFAhPT0wJiZQIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLFVbUF0sImZvciBtZXNzYWdlIixTKX1pZihvJiZ3Lmxlbmd0aD4wKW8oe3BoYXNlOiJvcGVuIixob3N0OnMubGFiZWwsZG9uZTp3Lmxlbmd0aCx0b3RhbDp3Lmxlbmd0aH0pO2lmKHl8fEl8fHcubGVuZ3RoPjApYSgpfWFzeW5jIGZ1bmN0aW9uIFhyKGUsdD17fSl7bGV0IHI9dC5wdWxsIT09ITEsbj10LnB1c2g9PT0hMCx7Y29ubjpzLHN0b3JlOmksZW5jbGF2ZTpvLGhvc3Q6YSxjcnlwdG86ZCxvblByb2dyZXNzOnUscGVla1Byb2dyZXNzRXZlcnk6bCxwZWVrQ29uY3VycmVuY3k6Zn09ZSxoPWF3YWl0IHMuaWRlbnRpdHkoKSxbeSxtXT1hd2FpdCBzLnBlZWsoMCk7aWYobSE9PTApcmV0dXJuIGMobSk7bGV0IGc9eS5sZW5ndGgsYj1sPz9ndCxJPWY/P21zO2lmKHUmJmc+MCl1KHtwaGFzZToicGVlayIsaG9zdDphLmxhYmVsLGRvbmU6MCx0b3RhbDpnfSk7bGV0IHc9MCxFPWF3YWl0IF9yKHksSSxhc3luYyh2KT0+e2xldFtSLFRdPWF3YWl0IHF0KHYsaC5wdWJsaWNLZXksbyxkKSxOO2lmKFQhPT0wfHwhUilOPXtvazohMSxzZXE6di5zZXEsc3RhdDpUfTtlbHNle2xldCBCPWF3YWl0IGQuYmxha2UzKFIuaGVhZEVuYyk7Tj17b2s6ITAsc2VxOnYuc2VxLGtkbTpSLmtkbSxoZWFkRW5jOlIuaGVhZEVuYyxoZWFkRW5jSGFzaDpCfX1pZih3Kz0xLHUmJlZyKHcsZyxiKSl1KHtwaGFzZToicGVlayIsaG9zdDphLmxhYmVsLGRvbmU6dyx0b3RhbDpnfSk7cmV0dXJuIE59KSxTPW5ldyBNYXA7Zm9yKGxldCB2IG9mIEUpe2lmKCF2Lm9rKWNvbnRpbnVlO2xldCBSPUQodi5oZWFkRW5jSGFzaCksVD1TLmdldChSKTtpZihUKVQuY291bnQrPTE7ZWxzZSBTLnNldChSLHtoYXNoOnYuaGVhZEVuY0hhc2gsY291bnQ6MSxzYW1wbGU6dn0pfWxldCBQPTAsaz1bXTtmb3IobGV0IHYgb2YgUy52YWx1ZXMoKSl7aWYodi5jb3VudD4xKVArPXYuY291bnQtMTtrLnB1c2godi5oYXNoKX1sZXQgTT15Lmxlbmd0aCxIPVMuc2l6ZSxDPWF3YWl0IHl0KGssZCksSz1bXSxfPTA7Zm9yKGxldCB2IG9mIFMudmFsdWVzKCkpe2lmKGF3YWl0IGkubWVzc2FnZXMuaGFzKHYuaGFzaCkpe2F3YWl0IGkudXBsb2Fkcy5kZXEoYS5sYWJlbCxbdi5oYXNoXSk7Y29udGludWV9aWYoXys9MSwhciljb250aW51ZTtsZXQgVD12LnNhbXBsZSxOPW5ldyBMKFQuaGVhZEVuYyksW0IsR109Ti5yZWFkU3RydWN0KGRlKTtpZihHIT09MCl7Y29uc29sZS5lcnJvcigicmVjb25jaWxlOiByZWFkaW5nIG1zZyBoZWFkZXIiLEcpO2NvbnRpbnVlfUsucHVzaCh7a2RtOlQua2RtLGhlYWQ6QixzZXE6VC5zZXEsaG9zdDphLmxhYmVsLGhlYWRFbmM6VC5oZWFkRW5jLGhlYWRFbmNIYXNoOlQuaGVhZEVuY0hhc2h9KX1pZihLLmxlbmd0aD4wKWF3YWl0IGkuZG93bmxvYWRzLmVucShLKTtsZXQgRj0wO2lmKG4pe2xldCB2PWF3YWl0IGkubWVzc2FnZXMubGlzdEtleXMoKSxSPW5ldyBTZXQoUy5rZXlzKCkpLFQ9W107Zm9yKGxldCBOIG9mIHYpaWYoIVIuaGFzKEQoTikpKUYrPTEsVC5wdXNoKE4pO2lmKFQubGVuZ3RoPjApYXdhaXQgaS51cGxvYWRzLmVucShhLmxhYmVsLFQpfWVsc2V7bGV0IHY9YXdhaXQgaS5tZXNzYWdlcy5saXN0S2V5cygpLFI9bmV3IFNldChTLmtleXMoKSk7Zm9yKGxldCBUIG9mIHYpaWYoIVIuaGFzKEQoVCkpKUYrPTF9bGV0IHg9eS5sZW5ndGg+MD9NYXRoLm1heCguLi55Lm1hcCgodik9PnYuc2VxKSk6MDtpZihhd2FpdCBpLmhvc3RzLnJlY29yZFN0YXRzKGEubGFiZWwse3NldExhc3RTZXE6eH0pLHUpdSh7cGhhc2U6InBlZWsiLGhvc3Q6YS5sYWJlbCxkb25lOmcsdG90YWw6Z30pO3JldHVybiBwKHttc2djaGVjazpDLG51bUJhZ3M6TSx1bmlxdWVNc2dzOkgsbnVtRHVwZXM6UCxtaXNzaW5nTG9jYWw6XyxtaXNzaW5nSG9zdDpGfSl9Y2xhc3MganJ7Y2xvY2s7c3RhdGU7c3RvcmU7dHJhbnNwb3J0O2NyeXB0bztmb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdDtvblNjaGVkdWxlU3luYztjb25uZWN0aW9ucz1uZXcgTWFwO2FwcGx5Q2hhaW49UHJvbWlzZS5yZXNvbHZlKCk7c3luY1J1bnM9bmV3IE50O2NsaWVudFN0YXRlO3hmZXJTdGF0ZTttYXhQdXNoQnl0ZXM7bWF4UHVsbEJ5dGVzO3BlZWtQcm9ncmVzc0V2ZXJ5PWd0O2xhc3RQcm9ncmVzcz1LcjtzY2hlZHVsZWRTeW5jO2NvbnN0cnVjdG9yKGUsdCxyLG4scyxpPSEwLG89cXIsYT1GcixkKXt0aGlzLmNsb2NrPWU7dGhpcy5zdGF0ZT10O3RoaXMuc3RvcmU9cjt0aGlzLnRyYW5zcG9ydD1uO3RoaXMuY3J5cHRvPXM7dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdD1pO3RoaXMub25TY2hlZHVsZVN5bmM9ZDt0aGlzLm1heFB1c2hCeXRlcz1vLHRoaXMubWF4UHVsbEJ5dGVzPWEsdGhpcy5jbGllbnRTdGF0ZT1uZXcgUmUoKCk9PnRoaXMuZ2V0Q2xpZW50U3RhdGUoKSksdGhpcy54ZmVyU3RhdGU9bmV3IFJlKCgpPT50aGlzLmdldFhmZXJTdGF0ZSgpKSx0aGlzLnNjaGVkdWxlZFN5bmM9bmV3IE9yKHVzLGFzeW5jKCk9Pnt0cnl7Y29uc29sZS5pbmZvKCJSdW5uaW5nIHNjaGVkdWxlZCBzeW5jIiksYXdhaXQgdGhpcy5zeW5jKCl9Y2F0Y2godSl7Y29uc29sZS5lcnJvcigiRGVib3VuY2VkIHN5bmMgZmFpbGVkOiIsdSl9fSl9ZW1pdFByb2dyZXNzPShlKT0+e3RoaXMubGFzdFByb2dyZXNzPWUsdGhpcy54ZmVyU3RhdGUuZW1pdCgpfTthc3luYyBzZXRTZWVkKGUsdCl7YXdhaXQgdGhpcy5zdG9yZS5zZWVkLnNhdmUoZSx0KSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBnZXRDbGllbnRTdGF0ZSgpe2xldHtzdG9yZTplLGNvbm5lY3Rpb25zOnR9PXRoaXMscj1hd2FpdCBlLnNlZWQubG9hZCgpLG49YXdhaXQgZS5ob3N0cy5saXN0KCkscz0hMTtmb3IobGV0IGkgb2YgdC52YWx1ZXMoKSlpZihpLmlzQ29ubmVjdGVkKCkpe3M9ITA7YnJlYWt9cmV0dXJue2hhc1NlZWQ6ciE9PXZvaWQgMCxoYXNIb3N0OkFycmF5LmZyb20obikubGVuZ3RoPjAsY29ubmVjdGVkOnN9fWFzeW5jIGdldFhmZXJTdGF0ZSgpe2xldHt1cGxvYWRzOmUsZG93bmxvYWRzOnR9PXRoaXMuc3RvcmUscj1hd2FpdCBlLmNvdW50KCk7cmV0dXJue251bURvd25sb2Fkczphd2FpdCB0LmNvdW50KCksbnVtVXBsb2FkczpyLHByb2dyZXNzOnRoaXMubGFzdFByb2dyZXNzfX1hcHBseT0oZSx0KT0+dGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseShlLHQpKTthc3luYyBkb0FwcGx5KGUsdD17ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiEwfSl7bGV0IHI9W10sbj1bXTtmb3IobGV0e2hlYWQ6aSxib2R5Om99b2YgZSl7bGV0IGE9bmV3IE87YS53cml0ZVN0cnVjdChkZSxpKTtsZXQgZD1hLnJlc3VsdCgpLHU9YXdhaXQgdGhpcy5jcnlwdG8uYmxha2UzKGQpLGw9e2VpZDppLmVpZCxib2R5Om8sYXBsZDpzdH07aWYoaS5vZmYhPT0wKWwub2ZmPWkub2ZmO2lmKGkuY3RyIT09MClsLmN0cj1pLmN0cjtyLnB1c2godSksbi5wdXNoKHtrZXk6dSxkYXRhOmx9KX1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmFkZChuKSxhd2FpdCBicyh0aGlzLnN0b3JlLHIsdGhpcy5jcnlwdG8pO2xldCBzPWF3YWl0IHRoaXMuZG9BcHBseUhhc2hlcyhyKTtpZih0LmVucXVldWVVcGxvYWQpe2xldCBpPVtdO2ZvcihsZXQgbz0wO288ci5sZW5ndGg7bysrKXtsZXQgYT1zW29dO2lmKGE9PT0wfHxhPT09MTUpaS5wdXNoKHJbb10pfWlmKGkubGVuZ3RoPjApe2xldCBvPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpO2ZvcihsZXQgYSBvZiBvKWF3YWl0IHRoaXMuc3RvcmUudXBsb2Fkcy5lbnEoYS5sYWJlbCxpKTt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9fWlmKHQudHJpZ2dlclVwbG9hZCl0aGlzLnNjaGVkdWxlU3luYygpO3JldHVybiBzfWVucXVldWVBcHBseUpvYihlKXtsZXQgdD10aGlzLmFwcGx5Q2hhaW4udGhlbihlLGUpO3JldHVybiB0aGlzLmFwcGx5Q2hhaW49dC50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLHR9ZHJhaW5BcHBseVF1ZXVlKCl7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvRHJhaW5BcHBseVF1ZXVlKCkpfWFzeW5jIGRvRHJhaW5BcHBseVF1ZXVlKCl7bGV0IGU9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KHthcGxkOnN0fSk7aWYoZS5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgdD1ydChlLChyKT0+ci5oZWFkKTtyZXR1cm4gdGhpcy5hcHBseVN0b3JlZCh0KX1hcHBseUhhc2hlcz0oZSk9PnRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHlIYXNoZXMoZSkpO2FzeW5jIGRvQXBwbHlIYXNoZXMoZSl7bGV0IHQ9W107Zm9yKGxldCBzIG9mIGUpe2xldCBpPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMuZ2V0KHMpO2lmKGkpdC5wdXNoKGkpfWxldCByPWF3YWl0IHRoaXMuYXBwbHlTdG9yZWQodCksbj1uZXcgTWFwO2ZvcihsZXQgcz0wO3M8dC5sZW5ndGg7cysrKW4uc2V0KEQodFtzXS5oYXNoKSxyW3NdPz8xMik7cmV0dXJuIGUubWFwKChzKT0+bi5nZXQoRChzKSk/PzEzKX1hc3luYyBhcHBseVN0b3JlZChlKXtpZihlLmxlbmd0aDwxKXJldHVybltdO2xldCB0PWUubWFwKChpKT0+KHsuLi5pLmhlYWQsYm9kOmkuYm9keX0pKSxyPWF3YWl0IHRoaXMuc3RhdGUuYXBwbHkodCksbj1bXSxzPVtdO2ZvcihsZXQgaT0wO2k8ZS5sZW5ndGg7aSsrKXtsZXQgbz1yW2ldO2lmKG89PT0wfHxvPT09MTUpbi5wdXNoKGVbaV0uaGFzaCk7ZWxzZSBpZihvIT09dm9pZCAwJiZocyhvKSlzLnB1c2goe2tleTplW2ldLmhhc2gsZXJyOm99KX1pZihuLmxlbmd0aD4wKWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubWFya0FwcGxpZWQobik7aWYocy5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtGYWlsZWQocyk7cmV0dXJuIHJ9YXN5bmMgaW5zZXJ0UmF3KGUpe2xldHtjbG9jazp0LGNyeXB0bzpyfT10aGlzLFtuLHNdPWF3YWl0IHRzKHtub3c6dC5ub3coKSxib2Q6ZSxjcnlwdG86cn0pO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldCBvPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpuLGJvZHk6ZX1dKSlbMF07aWYobyE9PTAmJm8hPT0xNSlyZXR1cm4gYyhvPz8xMik7cmV0dXJuIHAobil9YXN5bmMgbWFrZVVwZGF0ZShlLHQpe2xldHtjbG9jazpyLGNyeXB0bzpufT10aGlzLHM9ci5ub3coKTtpZihlLnVwZGF0ZWRBdC5nZXRUaW1lKCk+cy5nZXRUaW1lKCkpcmV0dXJuIGMoNCk7bGV0IGk9ZS5jdHIrMSxbbyxhXT1hd2FpdCBMdCh7bm93OnMsZWlkOmUuZWlkLGN0cjppLGJvZDp0LGNyeXB0bzpufSk7aWYoYSE9PTApcmV0dXJuIGMoYSk7cmV0dXJuIHAoe2hlYWQ6byxib2R5OnR9KX1hc3luYyB1cGRhdGVXaXRoU2tldyhlLHQscil7aWYocj09PSExKXJldHVybiBjKDQpO2xldHtjbG9jazpuLGNyeXB0bzpzfT10aGlzLGk9bi5ub3coKSxvPW5ldyBMKGUuZWlkKSxbYSxkXT1vLnJlYWRTdHJ1Y3QoaWUpO2lmKGQhPT0wKXJldHVybiBjKGQpO2xldCB1PWUudXBkYXRlZEF0LmdldFRpbWUoKS1hLnRzLmdldFRpbWUoKSxsPXtlaWQ6ZS5laWQsb2ZmOnUrMSxjdHI6ZS5jdHIrMSxsZW46MH0saD0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6bCxib2R5OnZvaWQgMH1dKSlbMF07aWYoaCE9PTAmJmghPT0xNSlyZXR1cm4gYyhoPz8xMik7aWYodD09PXZvaWQgMClyZXR1cm4gcChsKTtsZXRbeSxtXT1DdCh7aWQ6YS5pZCx0czppfSk7aWYobSE9PTApcmV0dXJuIGMobSk7bGV0W2csYl09YXdhaXQgTHQoe25vdzppLGVpZDp5LGN0cjowLGJvZDp0LGNyeXB0bzpzfSk7aWYoYiE9PTApcmV0dXJuIGMoYik7bGV0IHc9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOmcsYm9keTp0fV0pKVswXTtpZih3IT09MCYmdyE9PTE1KXJldHVybiBjKHc/PzEyKTtyZXR1cm4gcChnKX1hc3luYyB1cGRhdGVSYXcoZSx0LHI9dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdCl7aWYoZS51cGRhdGVkQXQuZ2V0VGltZSgpPnRoaXMuY2xvY2subm93KCkuZ2V0VGltZSgpKXJldHVybiB0aGlzLnVwZGF0ZVdpdGhTa2V3KGUsdCxyKTtyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoYXN5bmMoKT0+e2xldFtuLHNdPWF3YWl0IHRoaXMubWFrZVVwZGF0ZShlLHQpO2lmKHMhPT0wKXJldHVybiBjKHMpO2xldCBvPShhd2FpdCB0aGlzLmRvQXBwbHkoW25dKSlbMF07aWYobyE9PTAmJm8hPT0xNSlyZXR1cm4gYyhvPz8xMik7cmV0dXJuIHAobi5oZWFkKX0pfWFzeW5jIGluc2VydChlKXtsZXR7Ym9keTp0LHR5cGU6cixnaWQ6bixwaWQ6cyx0YWdzOml9PWUsYT1NZSh7Ym9keTp0LHR5cGU6cixnaWQ6bixwaWQ6cyx0YWdzOml9KTtyZXR1cm4gdGhpcy5pbnNlcnRSYXcoYSl9YXN5bmMgdXBkYXRlKGUpe2xldHtwcmlvcjp0LGJvZHk6cix0eXBlOm4sZ2lkOnMscGlkOmksdGFnczpvLGZvcmNlOmF9PWUsdT1NZSh7Ym9keTpyLHR5cGU6bixnaWQ6cyxwaWQ6aSx0YWdzOm99KTtyZXR1cm4gdGhpcy51cGRhdGVSYXcodCx1LGE/P3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpfWFzeW5jIGRlbGV0ZShlKXtsZXQgdD1lLmZvcmNlPz8hMDtpZigicHJpb3IiaW4gZSlyZXR1cm4gdGhpcy51cGRhdGVSYXcoZS5wcmlvcix2b2lkIDAsdCk7bGV0W3Isbl09YXdhaXQgdGhpcy5yZXZGcm9tQXJjaGl2ZShlLmVpZCk7aWYobiE9PTApcmV0dXJuIGMobik7cmV0dXJuIHRoaXMudXBkYXRlUmF3KHIsdm9pZCAwLHQpfWFzeW5jIHJldkZyb21BcmNoaXZlKGUpe2xldCB0PWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGFzdChlKTtpZih0KXJldHVybiBkcyh0LmhlYWQpO2xldCByPW5ldyBMKGUpLFtuLHNdPXIucmVhZFN0cnVjdChpZSk7aWYocyE9PTApcmV0dXJuIGMocyk7cmV0dXJuIHAoe2VpZDplLGN0cjotMSx1cGRhdGVkQXQ6bi50c30pfWFzeW5jIGdlbkVJRChlKXtsZXR7Y2xvY2s6dCxjcnlwdG86cn09dGhpcyxuPXQubm93KCk7aWYoZSE9PXZvaWQgMClyZXR1cm4gQ3Qoe2lkOmUsdHM6bn0pO2xldCBzPWF3YWl0IHIuZ2VuUmFuZG9tQnl0ZXMoOCk7cmV0dXJuIEN0KHtpZDpzLHRzOm59KX1zeW5jKCl7cmV0dXJuIHRoaXMuc3luY1J1bnMucnVuKCgpPT50aGlzLmRvU3luYygpKX1hc3luYyBkb1N5bmMoKXtsZXR7Y29ubmVjdGlvbnM6ZSxjcnlwdG86dCxzdG9yZTpyfT10aGlzLG49YXdhaXQgci5zZWVkLmxvYWQoKTtpZighbilyZXR1cm4gMjI7YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtmb3IobGV0W3MsaV1vZiBlKXtsZXQgbz1hd2FpdCByLmhvc3RzLmdldChzKTtpZighbyljb250aW51ZTtsZXQgYT17Y29ubjppLHN0b3JlOnIsZW5jbGF2ZTpuLGhvc3Q6byxjcnlwdG86dCxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sZD1hd2FpdCBXcihhKTtpZihkIT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHBlZWs6ICR7ZH1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksZDt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IHU9YXdhaXQgU3MoYSk7aWYodSE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwdXNoOiAke3V9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHU7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBsPWF3YWl0IHpyKGEsYXN5bmMoKT0+e2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCl9KTtpZihsIT09MCYmbCE9PTE1KXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVsbDogJHtsfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxsO3RoaXMueGZlclN0YXRlLmVtaXQoKX1yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgcmVidWlsZChlKXtpZih0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpLGU/LmNoZWNrSG9zdD8/ITApe2xldCByPWF3YWl0IHRoaXMucmVwdWxsKCk7aWYociE9PTApcmV0dXJuIHJ9cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLnJlcGxheSgpKX1hc3luYyBtc2djaGVjaygpe2xldCBlPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdEtleXMoKTtyZXR1cm4geXQoZSx0aGlzLmNyeXB0byl9bGlzdE1zZ3MoZSl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdChlKX1jb3VudE1zZ3MoZSl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMuY291bnQoZSl9YXN5bmMgcmVjb25jaWxlKGUsdCl7dGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKTtsZXR7Y29ubmVjdGlvbnM6cixjcnlwdG86bixzdG9yZTpzfT10aGlzLGk9YXdhaXQgcy5zZWVkLmxvYWQoKTtpZighaSlyZXR1cm4gYygyMik7bGV0IG89YXdhaXQgcy5ob3N0cy5nZXQoZSk7aWYoIW8pcmV0dXJuIGMoMTMpO2xldCBhPXIuZ2V0KGUpO2lmKCFhfHwhYS5pc0Nvbm5lY3RlZCgpKXtpZihhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QobywhMSwhMSksbz1hd2FpdCBzLmhvc3RzLmdldChlKSwhbylyZXR1cm4gYygxMyk7YT1yLmdldChlKX1pZighYSlyZXR1cm4gYygxMik7bGV0IGQ9e2Nvbm46YSxzdG9yZTpzLGVuY2xhdmU6aSxjcnlwdG86bixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sW3UsbF09YXdhaXQgWHIoey4uLmQsaG9zdDpvfSx0KTtpZih0aGlzLnhmZXJTdGF0ZS5lbWl0KCksbCE9PTApcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxjKGwpO2lmKCF1KXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksYygxMik7aWYodD8uc3luYz09PSExKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSkscCh1KTtsZXQgZj1hd2FpdCB0aGlzLnN5bmMoKTtpZihmIT09MClyZXR1cm4gYyhmKTtsZXQgaD1hd2FpdCBzLmhvc3RzLmdldChlKTtpZighaClyZXR1cm4gYygxMyk7bGV0W3ksbV09YXdhaXQgWHIoey4uLmQsaG9zdDpofSx7cHVsbDohMSxwdXNoOiExfSk7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxtIT09MClyZXR1cm4gYyhtKTtpZigheSlyZXR1cm4gYygxMik7cmV0dXJuIHAoeSl9YXN5bmMgcmVwdWxsKCl7bGV0e2Nvbm5lY3Rpb25zOmUsY3J5cHRvOnQsc3RvcmU6cn09dGhpcyxuPWF3YWl0IHIuc2VlZC5sb2FkKCk7aWYoIW4pcmV0dXJuIDIyO2xldCBzPUFycmF5LmZyb20oYXdhaXQgci5ob3N0cy5saXN0KCkpO2lmKHMubGVuZ3RoPDEpcmV0dXJuIDA7Zm9yKGxldCBpIG9mIHMpe2xldCBvPWUuZ2V0KGkubGFiZWwpO2lmKCFvfHwhby5pc0Nvbm5lY3RlZCgpKWF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChpLCExLCExKX1mb3IobGV0W2ksb11vZiBlKXtsZXQgYT1hd2FpdCByLmhvc3RzLmdldChpKTtpZighYSljb250aW51ZTtsZXQgZD17Y29ubjpvLHN0b3JlOnIsZW5jbGF2ZTpuLGhvc3Q6ey4uLmEsbGFzdFNlcTowfSxjcnlwdG86dCxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sdT1hd2FpdCBXcihkKTtpZih1IT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHBlZWs6ICR7dX1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksdTt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IGw9YXdhaXQgenIoZCk7aWYobCE9PTAmJmwhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHB1bGw6ICR7bH1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksbDt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlcGxheSgpe2xldCBlPWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTtpZihlIT09MClyZXR1cm4gZTtsZXQgdD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoKSxyPXJ0KHQsKGkpPT5pLmhlYWQpLG49ci5sZW5ndGg7aWYobjwxKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMDtsZXQgcz0wO3doaWxlKHM8ci5sZW5ndGgpe2xldCBpPTAsbz0wLGE9cztmb3IobGV0IHU9czt1PHIubGVuZ3RoJiZvPDEwMCYmaTwxMDI0MDA7dSsrKWkrPXJbdV0uaGVhZC5sZW4sbysrLGE9dSsxO2xldCBkPXIuc2xpY2UocyxhKTthd2FpdCB0aGlzLmFwcGx5U3RvcmVkKGQpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiZXhlYyIsZG9uZTphLHRvdGFsOm59KSxzPWF9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHdpcGUoZSl7bGV0IHQ9ZT8ubXNncyE9PSExLHI9ZT8uZW50cyE9PSExLG49ZT8ubWV0YSE9PSExLHM9ZT8uc2VlZD09PSEwO3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLmRpc2Nvbm5lY3QoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e3N0b3JlOml9PXRoaXM7aWYobilhd2FpdCBpLmhvc3RzLndpcGUoKSxhd2FpdCBpLnVwbG9hZHMud2lwZSgpLGF3YWl0IGkuZG93bmxvYWRzLndpcGUoKTtpZih0KWF3YWl0IGkubWVzc2FnZXMud2lwZSgpO2lmKHMpYXdhaXQgaS5zZWVkLndpcGUoKTtpZihyKWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTt0aGlzLmxhc3RQcm9ncmVzcz1Lcix0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSx0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9aW1wb3J0PWFzeW5jKGUsdCk9PntsZXR7Y3J5cHRvOnIsc3RvcmU6bn09dGhpcyxzPXQ/Lm9uUHJvZ3Jlc3MsaT1hd2FpdCBuLnNlZWQubG9hZCgpO2lmKCFpKXJldHVybiAyMjtjb25zb2xlLnRpbWUoImltcG9ydDogZGVjb2RpbmcgZmlsZS4uLiIpO2xldCBvPWF3YWl0IGUuYnl0ZXMoKSxbYSxkXT1hd2FpdCBlcyhvLHIsaSk7aWYoZCE9PTApcmV0dXJuIGQ7Y29uc29sZS50aW1lRW5kKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgdT0wO3doaWxlKHU8YS5sZW5ndGgpe2xldCBsPTAsZj0wLGg9dTtmb3IobGV0IGc9dTtnPGEubGVuZ3RoJiZmPDEwMCYmbDwxMDI0MDA7ZysrKWwrPWFbZ10uaGVhZC5sZW4sZisrLGg9ZysxO2xldCB5PWEuc2xpY2UodSxoKTtjb25zb2xlLnRpbWUoYGltcG9ydDogYXBwbHlpbmcgWyR7dX0sICR7aH1dYCk7bGV0IG09YXdhaXQgdGhpcy5hcHBseSh5LHtlbnF1ZXVlVXBsb2FkOiEwLHRyaWdnZXJVcGxvYWQ6ITF9KTtjb25zb2xlLnRpbWVFbmQoYGltcG9ydDogYXBwbHlpbmcgWyR7dX0sICR7aH1dYCk7Zm9yKGxldCBnPTA7Zzx5Lmxlbmd0aDtnKyspe2xldCBiPW1bZ107aWYoYiE9PTAmJmIhPT0xNSljb25zb2xlLndhcm4oYGZhaWxlZCB0byBpbXBvcnQgbXNnICR7dStnfTogJHtVW2JdfWApfWlmKHMpcXVldWVNaWNyb3Rhc2soKCk9PnMoaCxhLmxlbmd0aCwwKSk7dGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpbXBvcnQiLGRvbmU6aCx0b3RhbDphLmxlbmd0aH0pLHU9aH1yZXR1cm4gdGhpcy5zY2hlZHVsZVN5bmMoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH07c2NoZWR1bGVTeW5jPSgpPT57aWYodGhpcy5vblNjaGVkdWxlU3luYyl7dGhpcy5vblNjaGVkdWxlU3luYygpO3JldHVybn10aGlzLnNjaGVkdWxlZFN5bmMuc2NoZWR1bGUoKX07YXN5bmMgZXhwb3J0Qnl0ZXMoKXtsZXR7Y3J5cHRvOmUsc3RvcmU6dH09dGhpcyxyPWF3YWl0IHQuc2VlZC5sb2FkKCk7aWYoIXIpcmV0dXJuIGMoMjIpO2xldCBuPWF3YWl0IHQubWVzc2FnZXMubGlzdCgpO3JldHVybiBabigiZXhwb3J0IiwwLG4sZSxyKX1hc3luYyBleHBvcnQoZSl7bGV0W3Qscl09YXdhaXQgdGhpcy5leHBvcnRCeXRlcygpO2lmKHIhPT0wKXJldHVybiByO2lmKCF0KXJldHVybiAxMjtsZXQgbj1uZXcgQmxvYihbdC5zbGljZSgpXSk7cmV0dXJuIGZzKG4sZSksMH1hc3luYyBsaW5rKGUsdD0hMCl7aWYoYXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5hZGQoZSksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksdCl7bGV0IHI9YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5nZXQoZS5sYWJlbCk7aWYocilhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3Qocil9fWFzeW5jIHVubGluayhlKXthd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmRlbChlKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBob3N0cygpe3JldHVybiBBcnJheS5mcm9tKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpKX1jb25uZWN0VG9Ib3N0PWFzeW5jKGUsdD0hMCxyPSEwKT0+e2xldHtjbG9jazpuLGNvbm5lY3Rpb25zOnMsY3J5cHRvOmksc3RvcmU6byx0cmFuc3BvcnQ6YX09dGhpcyxkPXMuZ2V0KGUubGFiZWwpO2lmKGQpe2lmKGQuaXNDb25uZWN0ZWQoKSlyZXR1cm47dHJ5e2QuY2xvc2VMaXN0ZW5lcigpfWNhdGNoe31zLmRlbGV0ZShlLmxhYmVsKX1sZXQgdT1hd2FpdCBvLnNlZWQubG9hZCgpO2lmKCF1KXJldHVybjtjb25zb2xlLmluZm8oYENvbm5lY3RpbmcgdG8gJHtlLmhhbmRsZX0gKCR7ZS5sYWJlbH0pYCk7bGV0IGw9bmV3IFJ0KHUsaSxlLG4sYShlKSwoZik9Pm8uaG9zdHMuc2V0KGUubGFiZWwsZikpO2lmKGF3YWl0IGwucmVnaXN0ZXIoKSx0KWF3YWl0IGwubGlzdGVuKGFzeW5jKGYpPT57bGV0IGg9e2Nvbm46bCxzdG9yZTpvLGVuY2xhdmU6dSxob3N0OmUsY3J5cHRvOmksbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9O3JldHVybiBJcyhmLGgsdGhpcy5zY2hlZHVsZVN5bmMpfSwoKT0+dGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpKTtpZihzLnNldChlLmxhYmVsLGwpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLHIpdGhpcy5zY2hlZHVsZVN5bmMoKX07YXN5bmMgY29ubmVjdChlPSEwLHQ9ITApe2xldHtjb25uZWN0VG9Ib3N0OnIsc2NoZWR1bGVTeW5jOm4sc3RvcmU6c309dGhpcztpZighYXdhaXQgcy5zZWVkLmxvYWQoKSlyZXR1cm47YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtsZXQgbz1hd2FpdCBzLmhvc3RzLmxpc3QoKTtmb3IobGV0IGEgb2Ygbylhd2FpdCByKGEsZSwhMSk7aWYodCluKCl9ZGlzY29ubmVjdD1hc3luYygpPT57Zm9yKGxldCBlIG9mIHRoaXMuY29ubmVjdGlvbnMudmFsdWVzKCkpdHJ5e2UuY2xvc2VMaXN0ZW5lcigpfWNhdGNoe310aGlzLmNvbm5lY3Rpb25zLmNsZWFyKCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9fXZhciBPZT10eXBlb2YgZ2xvYmFsVGhpcz09PSJvYmplY3QiJiYiY3J5cHRvImluIGdsb2JhbFRoaXM/Z2xvYmFsVGhpcy5jcnlwdG86dm9pZCAwO2Z1bmN0aW9uIHp0KGUpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihlKXx8ZTwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIitlKX1mdW5jdGlvbiBHcihlKXtyZXR1cm4gZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldyhlKSYmZS5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIFEoZSwuLi50KXtpZighR3IoZSkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZih0Lmxlbmd0aD4wJiYhdC5pbmNsdWRlcyhlLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrdCsiLCBnb3QgbGVuZ3RoPSIrZS5sZW5ndGgpfWZ1bmN0aW9uICRyKGUsdD0hMCl7aWYoZS5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYodCYmZS5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIHhzKGUsdCl7UShlKTtsZXQgcj10Lm91dHB1dExlbjtpZihlLmxlbmd0aDxyKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK3IpfWZ1bmN0aW9uIFFyKGUpe2lmKHR5cGVvZiBlIT09ImJvb2xlYW4iKXRocm93IEVycm9yKGBib29sZWFuIGV4cGVjdGVkLCBub3QgJHtlfWApfS8qISBub2JsZS1jaXBoZXJzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjMgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovdmFyIEllPShlKT0+bmV3IFVpbnQzMkFycmF5KGUuYnVmZmVyLGUuYnl0ZU9mZnNldCxNYXRoLmZsb29yKGUuYnl0ZUxlbmd0aC80KSk7dmFyIHhvPW5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4O2lmKCF4byl0aHJvdyBFcnJvcigiTm9uIGxpdHRsZS1lbmRpYW4gaGFyZHdhcmUgaXMgbm90IHN1cHBvcnRlZCIpO2Z1bmN0aW9uIEVvKGUpe2lmKHR5cGVvZiBlIT09InN0cmluZyIpdGhyb3cgRXJyb3IoInN0cmluZyBleHBlY3RlZCIpO3JldHVybiBuZXcgVWludDhBcnJheShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZSkpfWZ1bmN0aW9uIFh0KGUpe2lmKHR5cGVvZiBlPT09InN0cmluZyIpZT1FbyhlKTtlbHNlIGlmKEdyKGUpKWU9anQoZSk7ZWxzZSB0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCwgZ290ICIrdHlwZW9mIGUpO3JldHVybiBlfWZ1bmN0aW9uIEVzKGUsdCl7aWYodD09bnVsbHx8dHlwZW9mIHQhPT0ib2JqZWN0Iil0aHJvdyBFcnJvcigib3B0aW9ucyBtdXN0IGJlIGRlZmluZWQiKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihlLHQpfWZ1bmN0aW9uIEFzKGUsdCl7aWYoZS5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtsZXQgcj0wO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKXJ8PWVbbl1edFtuXTtyZXR1cm4gcj09PTB9dmFyIFBzPShlLHQpPT57ZnVuY3Rpb24gcihuLC4uLnMpe2lmKFEobiksZS5ub25jZUxlbmd0aCE9PXZvaWQgMCl7bGV0IGw9c1swXTtpZighbCl0aHJvdyBFcnJvcigibm9uY2UgLyBpdiByZXF1aXJlZCIpO2lmKGUudmFyU2l6ZU5vbmNlKVEobCk7ZWxzZSBRKGwsZS5ub25jZUxlbmd0aCl9bGV0IGk9ZS50YWdMZW5ndGg7aWYoaSYmc1sxXSE9PXZvaWQgMClRKHNbMV0pO2xldCBvPXQobiwuLi5zKSxhPShsLGYpPT57aWYoZiE9PXZvaWQgMCl7aWYobCE9PTIpdGhyb3cgRXJyb3IoImNpcGhlciBvdXRwdXQgbm90IHN1cHBvcnRlZCIpO1EoZil9fSxkPSExO3JldHVybntlbmNyeXB0KGwsZil7aWYoZCl0aHJvdyBFcnJvcigiY2Fubm90IGVuY3J5cHQoKSB0d2ljZSB3aXRoIHNhbWUga2V5ICsgbm9uY2UiKTtyZXR1cm4gZD0hMCxRKGwpLGEoby5lbmNyeXB0Lmxlbmd0aCxmKSxvLmVuY3J5cHQobCxmKX0sZGVjcnlwdChsLGYpe2lmKFEobCksaSYmbC5sZW5ndGg8aSl0aHJvdyBFcnJvcigiaW52YWxpZCBjaXBoZXJ0ZXh0IGxlbmd0aDogc21hbGxlciB0aGFuIHRhZ0xlbmd0aD0iK2kpO3JldHVybiBhKG8uZGVjcnlwdC5sZW5ndGgsZiksby5kZWNyeXB0KGwsZil9fX1yZXR1cm4gT2JqZWN0LmFzc2lnbihyLGUpLHJ9O2Z1bmN0aW9uIFlyKGUsdCxyPSEwKXtpZih0PT09dm9pZCAwKXJldHVybiBuZXcgVWludDhBcnJheShlKTtpZih0Lmxlbmd0aCE9PWUpdGhyb3cgRXJyb3IoImludmFsaWQgb3V0cHV0IGxlbmd0aCwgZXhwZWN0ZWQgIitlKyIsIGdvdDogIit0Lmxlbmd0aCk7aWYociYmIUFvKHQpKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCwgbXVzdCBiZSBhbGlnbmVkIik7cmV0dXJuIHR9ZnVuY3Rpb24gQW8oZSl7cmV0dXJuIGUuYnl0ZU9mZnNldCU0PT09MH1mdW5jdGlvbiBqdChlKXtyZXR1cm4gVWludDhBcnJheS5mcm9tKGUpfWZ1bmN0aW9uIG1lKC4uLmUpe2ZvcihsZXQgdD0wO3Q8ZS5sZW5ndGg7dCsrKWVbdF0uZmlsbCgwKX1mdW5jdGlvbiBidChlPTMyKXtpZihPZSYmdHlwZW9mIE9lLmdldFJhbmRvbVZhbHVlcz09PSJmdW5jdGlvbiIpcmV0dXJuIE9lLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheShlKSk7aWYoT2UmJnR5cGVvZiBPZS5yYW5kb21CeXRlcz09PSJmdW5jdGlvbiIpcmV0dXJuIE9lLnJhbmRvbUJ5dGVzKGUpO3Rocm93IEVycm9yKCJjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIG11c3QgYmUgZGVmaW5lZCIpfXZhciBCcz0oZSk9PlVpbnQ4QXJyYXkuZnJvbShlLnNwbGl0KCIiKS5tYXAoKHQpPT50LmNoYXJDb2RlQXQoMCkpKSxQbz1CcygiZXhwYW5kIDE2LWJ5dGUgayIpLFVvPUJzKCJleHBhbmQgMzItYnl0ZSBrIiksQm89SWUoUG8pLGtvPUllKFVvKTtmdW5jdGlvbiBBKGUsdCl7cmV0dXJuIGU8PHR8ZT4+PjMyLXR9ZnVuY3Rpb24gSnIoZSl7cmV0dXJuIGUuYnl0ZU9mZnNldCU0PT09MH12YXIgR3Q9NjQsdm89MTYsa3M9NDI5NDk2NzI5NSxVcz1uZXcgVWludDMyQXJyYXk7ZnVuY3Rpb24gRG8oZSx0LHIsbixzLGksbyxhKXtsZXQgZD1zLmxlbmd0aCx1PW5ldyBVaW50OEFycmF5KEd0KSxsPUllKHUpLGY9SnIocykmJkpyKGkpLGg9Zj9JZShzKTpVcyx5PWY/SWUoaSk6VXM7Zm9yKGxldCBtPTA7bTxkO28rKyl7aWYoZSh0LHIsbixsLG8sYSksbz49a3MpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2xldCBnPU1hdGgubWluKEd0LGQtbSk7aWYoZiYmZz09PUd0KXtsZXQgYj1tLzQ7aWYobSU0IT09MCl0aHJvdyBFcnJvcigiYXJ4OiBpbnZhbGlkIGJsb2NrIHBvc2l0aW9uIik7Zm9yKGxldCBJPTAsdztJPHZvO0krKyl3PWIrSSx5W3ddPWhbd11ebFtJXTttKz1HdDtjb250aW51ZX1mb3IobGV0IGI9MCxJO2I8ZztiKyspST1tK2IsaVtJXT1zW0ldXnVbYl07bSs9Z319ZnVuY3Rpb24gdnMoZSx0KXtsZXR7YWxsb3dTaG9ydEtleXM6cixleHRlbmROb25jZUZuOm4sY291bnRlckxlbmd0aDpzLGNvdW50ZXJSaWdodDppLHJvdW5kczpvfT1Fcyh7YWxsb3dTaG9ydEtleXM6ITEsY291bnRlckxlbmd0aDo4LGNvdW50ZXJSaWdodDohMSxyb3VuZHM6MjB9LHQpO2lmKHR5cGVvZiBlIT09ImZ1bmN0aW9uIil0aHJvdyBFcnJvcigiY29yZSBtdXN0IGJlIGEgZnVuY3Rpb24iKTtyZXR1cm4genQocyksenQobyksUXIoaSksUXIociksKGEsZCx1LGwsZj0wKT0+e1EoYSksUShkKSxRKHUpO2xldCBoPXUubGVuZ3RoO2lmKGw9PT12b2lkIDApbD1uZXcgVWludDhBcnJheShoKTtpZihRKGwpLHp0KGYpLGY8MHx8Zj49a3MpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2lmKGwubGVuZ3RoPGgpdGhyb3cgRXJyb3IoYGFyeDogb3V0cHV0ICgke2wubGVuZ3RofSkgaXMgc2hvcnRlciB0aGFuIGRhdGEgKCR7aH0pYCk7bGV0IHk9W10sbT1hLmxlbmd0aCxnLGI7aWYobT09PTMyKXkucHVzaChnPWp0KGEpKSxiPWtvO2Vsc2UgaWYobT09PTE2JiZyKWc9bmV3IFVpbnQ4QXJyYXkoMzIpLGcuc2V0KGEpLGcuc2V0KGEsMTYpLGI9Qm8seS5wdXNoKGcpO2Vsc2UgdGhyb3cgRXJyb3IoYGFyeDogaW52YWxpZCAzMi1ieXRlIGtleSwgZ290IGxlbmd0aD0ke219YCk7aWYoIUpyKGQpKXkucHVzaChkPWp0KGQpKTtsZXQgST1JZShnKTtpZihuKXtpZihkLmxlbmd0aCE9PTI0KXRocm93IEVycm9yKCJhcng6IGV4dGVuZGVkIG5vbmNlIG11c3QgYmUgMjQgYnl0ZXMiKTtuKGIsSSxJZShkLnN1YmFycmF5KDAsMTYpKSxJKSxkPWQuc3ViYXJyYXkoMTYpfWxldCB3PTE2LXM7aWYodyE9PWQubGVuZ3RoKXRocm93IEVycm9yKGBhcng6IG5vbmNlIG11c3QgYmUgJHt3fSBvciAxNiBieXRlc2ApO2lmKHchPT0xMil7bGV0IFM9bmV3IFVpbnQ4QXJyYXkoMTIpO1Muc2V0KGQsaT8wOjEyLWQubGVuZ3RoKSxkPVMseS5wdXNoKGQpfWxldCBFPUllKGQpO3JldHVybiBEbyhlLGIsSSxFLHUsbCxmLG8pLG1lKC4uLnkpLGx9fXZhciBKPShlLHQpPT5lW3QrK10mMjU1fChlW3QrK10mMjU1KTw8ODtjbGFzcyBEc3tjb25zdHJ1Y3RvcihlKXt0aGlzLmJsb2NrTGVuPTE2LHRoaXMub3V0cHV0TGVuPTE2LHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KDE2KSx0aGlzLnI9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLmg9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLnBhZD1uZXcgVWludDE2QXJyYXkoOCksdGhpcy5wb3M9MCx0aGlzLmZpbmlzaGVkPSExLGU9WHQoZSksUShlLDMyKTtsZXQgdD1KKGUsMCkscj1KKGUsMiksbj1KKGUsNCkscz1KKGUsNiksaT1KKGUsOCksbz1KKGUsMTApLGE9SihlLDEyKSxkPUooZSwxNCk7dGhpcy5yWzBdPXQmODE5MSx0aGlzLnJbMV09KHQ+Pj4xM3xyPDwzKSY4MTkxLHRoaXMuclsyXT0ocj4+PjEwfG48PDYpJjc5MzksdGhpcy5yWzNdPShuPj4+N3xzPDw5KSY4MTkxLHRoaXMucls0XT0ocz4+PjR8aTw8MTIpJjI1NSx0aGlzLnJbNV09aT4+PjEmODE5MCx0aGlzLnJbNl09KGk+Pj4xNHxvPDwyKSY4MTkxLHRoaXMucls3XT0obz4+PjExfGE8PDUpJjgwNjUsdGhpcy5yWzhdPShhPj4+OHxkPDw4KSY4MTkxLHRoaXMucls5XT1kPj4+NSYxMjc7Zm9yKGxldCB1PTA7dTw4O3UrKyl0aGlzLnBhZFt1XT1KKGUsMTYrMip1KX1wcm9jZXNzKGUsdCxyPSExKXtsZXQgbj1yPzA6MjA0OCx7aDpzLHI6aX09dGhpcyxvPWlbMF0sYT1pWzFdLGQ9aVsyXSx1PWlbM10sbD1pWzRdLGY9aVs1XSxoPWlbNl0seT1pWzddLG09aVs4XSxnPWlbOV0sYj1KKGUsdCswKSxJPUooZSx0KzIpLHc9SihlLHQrNCksRT1KKGUsdCs2KSxTPUooZSx0KzgpLFA9SihlLHQrMTApLGs9SihlLHQrMTIpLE09SihlLHQrMTQpLEg9c1swXSsoYiY4MTkxKSxDPXNbMV0rKChiPj4+MTN8STw8MykmODE5MSksSz1zWzJdKygoST4+PjEwfHc8PDYpJjgxOTEpLF89c1szXSsoKHc+Pj43fEU8PDkpJjgxOTEpLEY9c1s0XSsoKEU+Pj40fFM8PDEyKSY4MTkxKSx4PXNbNV0rKFM+Pj4xJjgxOTEpLHY9c1s2XSsoKFM+Pj4xNHxQPDwyKSY4MTkxKSxSPXNbN10rKChQPj4+MTF8azw8NSkmODE5MSksVD1zWzhdKygoaz4+Pjh8TTw8OCkmODE5MSksTj1zWzldKyhNPj4+NXxuKSxCPTAsRz1CK0gqbytDKig1KmcpK0sqKDUqbSkrXyooNSp5KStGKig1KmgpO0I9Rz4+PjEzLEcmPTgxOTEsRys9eCooNSpmKSt2Kig1KmwpK1IqKDUqdSkrVCooNSpkKStOKig1KmEpLEIrPUc+Pj4xMyxHJj04MTkxO2xldCBaPUIrSCphK0MqbytLKig1KmcpK18qKDUqbSkrRiooNSp5KTtCPVo+Pj4xMyxaJj04MTkxLForPXgqKDUqaCkrdiooNSpmKStSKig1KmwpK1QqKDUqdSkrTiooNSpkKSxCKz1aPj4+MTMsWiY9ODE5MTtsZXQgc2U9QitIKmQrQyphK0sqbytfKig1KmcpK0YqKDUqbSk7Qj1zZT4+PjEzLHNlJj04MTkxLHNlKz14Kig1KnkpK3YqKDUqaCkrUiooNSpmKStUKig1KmwpK04qKDUqdSksQis9c2U+Pj4xMyxzZSY9ODE5MTtsZXQgej1CK0gqdStDKmQrSyphK18qbytGKig1KmcpO0I9ej4+PjEzLHomPTgxOTEseis9eCooNSptKSt2Kig1KnkpK1IqKDUqaCkrVCooNSpmKStOKig1KmwpLEIrPXo+Pj4xMyx6Jj04MTkxO2xldCBTZT1CK0gqbCtDKnUrSypkK18qYStGKm87Qj1TZT4+PjEzLFNlJj04MTkxLFNlKz14Kig1KmcpK3YqKDUqbSkrUiooNSp5KStUKig1KmgpK04qKDUqZiksQis9U2U+Pj4xMyxTZSY9ODE5MTtsZXQgV2U9QitIKmYrQypsK0sqdStfKmQrRiphO0I9V2U+Pj4xMyxXZSY9ODE5MSxXZSs9eCpvK3YqKDUqZykrUiooNSptKStUKig1KnkpK04qKDUqaCksQis9V2U+Pj4xMyxXZSY9ODE5MTtsZXQgemU9QitIKmgrQypmK0sqbCtfKnUrRipkO0I9emU+Pj4xMyx6ZSY9ODE5MSx6ZSs9eCphK3YqbytSKig1KmcpK1QqKDUqbSkrTiooNSp5KSxCKz16ZT4+PjEzLHplJj04MTkxO2xldCBYZT1CK0gqeStDKmgrSypmK18qbCtGKnU7Qj1YZT4+PjEzLFhlJj04MTkxLFhlKz14KmQrdiphK1IqbytUKig1KmcpK04qKDUqbSksQis9WGU+Pj4xMyxYZSY9ODE5MTtsZXQgamU9QitIKm0rQyp5K0sqaCtfKmYrRipsO0I9amU+Pj4xMyxqZSY9ODE5MSxqZSs9eCp1K3YqZCtSKmErVCpvK04qKDUqZyksQis9amU+Pj4xMyxqZSY9ODE5MTtsZXQgR2U9QitIKmcrQyptK0sqeStfKmgrRipmO0I9R2U+Pj4xMyxHZSY9ODE5MSxHZSs9eCpsK3YqdStSKmQrVCphK04qbyxCKz1HZT4+PjEzLEdlJj04MTkxLEI9KEI8PDIpK0J8MCxCPUIrR3wwLEc9QiY4MTkxLEI9Qj4+PjEzLForPUIsc1swXT1HLHNbMV09WixzWzJdPXNlLHNbM109eixzWzRdPVNlLHNbNV09V2Usc1s2XT16ZSxzWzddPVhlLHNbOF09amUsc1s5XT1HZX1maW5hbGl6ZSgpe2xldHtoOmUscGFkOnR9PXRoaXMscj1uZXcgVWludDE2QXJyYXkoMTApLG49ZVsxXT4+PjEzO2VbMV0mPTgxOTE7Zm9yKGxldCBvPTI7bzwxMDtvKyspZVtvXSs9bixuPWVbb10+Pj4xMyxlW29dJj04MTkxO2VbMF0rPW4qNSxuPWVbMF0+Pj4xMyxlWzBdJj04MTkxLGVbMV0rPW4sbj1lWzFdPj4+MTMsZVsxXSY9ODE5MSxlWzJdKz1uLHJbMF09ZVswXSs1LG49clswXT4+PjEzLHJbMF0mPTgxOTE7Zm9yKGxldCBvPTE7bzwxMDtvKyspcltvXT1lW29dK24sbj1yW29dPj4+MTMscltvXSY9ODE5MTtyWzldLT04MTkyO2xldCBzPShuXjEpLTE7Zm9yKGxldCBvPTA7bzwxMDtvKyspcltvXSY9cztzPX5zO2ZvcihsZXQgbz0wO288MTA7bysrKWVbb109ZVtvXSZzfHJbb107ZVswXT0oZVswXXxlWzFdPDwxMykmNjU1MzUsZVsxXT0oZVsxXT4+PjN8ZVsyXTw8MTApJjY1NTM1LGVbMl09KGVbMl0+Pj42fGVbM108PDcpJjY1NTM1LGVbM109KGVbM10+Pj45fGVbNF08PDQpJjY1NTM1LGVbNF09KGVbNF0+Pj4xMnxlWzVdPDwxfGVbNl08PDE0KSY2NTUzNSxlWzVdPShlWzZdPj4+MnxlWzddPDwxMSkmNjU1MzUsZVs2XT0oZVs3XT4+PjV8ZVs4XTw8OCkmNjU1MzUsZVs3XT0oZVs4XT4+Pjh8ZVs5XTw8NSkmNjU1MzU7bGV0IGk9ZVswXSt0WzBdO2VbMF09aSY2NTUzNTtmb3IobGV0IG89MTtvPDg7bysrKWk9KGVbb10rdFtvXXwwKSsoaT4+PjE2KXwwLGVbb109aSY2NTUzNTttZShyKX11cGRhdGUoZSl7JHIodGhpcyk7bGV0e2J1ZmZlcjp0LGJsb2NrTGVuOnJ9PXRoaXM7ZT1YdChlKTtsZXQgbj1lLmxlbmd0aDtmb3IobGV0IHM9MDtzPG47KXtsZXQgaT1NYXRoLm1pbihyLXRoaXMucG9zLG4tcyk7aWYoaT09PXIpe2Zvcig7cjw9bi1zO3MrPXIpdGhpcy5wcm9jZXNzKGUscyk7Y29udGludWV9aWYodC5zZXQoZS5zdWJhcnJheShzLHMraSksdGhpcy5wb3MpLHRoaXMucG9zKz1pLHMrPWksdGhpcy5wb3M9PT1yKXRoaXMucHJvY2Vzcyh0LDAsITEpLHRoaXMucG9zPTB9cmV0dXJuIHRoaXN9ZGVzdHJveSgpe21lKHRoaXMuaCx0aGlzLnIsdGhpcy5idWZmZXIsdGhpcy5wYWQpfWRpZ2VzdEludG8oZSl7JHIodGhpcykseHMoZSx0aGlzKSx0aGlzLmZpbmlzaGVkPSEwO2xldHtidWZmZXI6dCxoOnJ9PXRoaXMse3BvczpufT10aGlzO2lmKG4pe3RbbisrXT0xO2Zvcig7bjwxNjtuKyspdFtuXT0wO3RoaXMucHJvY2Vzcyh0LDAsITApfXRoaXMuZmluYWxpemUoKTtsZXQgcz0wO2ZvcihsZXQgaT0wO2k8ODtpKyspZVtzKytdPXJbaV0+Pj4wLGVbcysrXT1yW2ldPj4+ODtyZXR1cm4gZX1kaWdlc3QoKXtsZXR7YnVmZmVyOmUsb3V0cHV0TGVuOnR9PXRoaXM7dGhpcy5kaWdlc3RJbnRvKGUpO2xldCByPWUuc2xpY2UoMCx0KTtyZXR1cm4gdGhpcy5kZXN0cm95KCkscn19ZnVuY3Rpb24gQ28oZSl7bGV0IHQ9KG4scyk9PmUocykudXBkYXRlKFh0KG4pKS5kaWdlc3QoKSxyPWUobmV3IFVpbnQ4QXJyYXkoMzIpKTtyZXR1cm4gdC5vdXRwdXRMZW49ci5vdXRwdXRMZW4sdC5ibG9ja0xlbj1yLmJsb2NrTGVuLHQuY3JlYXRlPShuKT0+ZShuKSx0fXZhciBacj1DbygoZSk9Pm5ldyBEcyhlKSk7ZnVuY3Rpb24gVG8oZSx0LHIsbixzLGk9MjApe2xldCBvPWVbMF0sYT10WzBdLGQ9dFsxXSx1PXRbMl0sbD10WzNdLGY9ZVsxXSxoPXJbMF0seT1yWzFdLG09cyxnPTAsYj1lWzJdLEk9dFs0XSx3PXRbNV0sRT10WzZdLFM9dFs3XSxQPWVbM10saz1vLE09YSxIPWQsQz11LEs9bCxfPWYsRj1oLHg9eSx2PW0sUj1nLFQ9YixOPUksQj13LEc9RSxaPVMsc2U9UDtmb3IobGV0IFNlPTA7U2U8aTtTZSs9MilLXj1BKGsrQnwwLDcpLHZePUEoSytrfDAsOSksQl49QSh2K0t8MCwxMyksa149QShCK3Z8MCwxOCksUl49QShfK018MCw3KSxHXj1BKFIrX3wwLDkpLE1ePUEoRytSfDAsMTMpLF9ePUEoTStHfDAsMTgpLFpePUEoVCtGfDAsNyksSF49QShaK1R8MCw5KSxGXj1BKEgrWnwwLDEzKSxUXj1BKEYrSHwwLDE4KSxDXj1BKHNlK058MCw3KSx4Xj1BKEMrc2V8MCw5KSxOXj1BKHgrQ3wwLDEzKSxzZV49QShOK3h8MCwxOCksTV49QShrK0N8MCw3KSxIXj1BKE0ra3wwLDkpLENePUEoSCtNfDAsMTMpLGtePUEoQytIfDAsMTgpLEZePUEoXytLfDAsNykseF49QShGK198MCw5KSxLXj1BKHgrRnwwLDEzKSxfXj1BKEsreHwwLDE4KSxOXj1BKFQrUnwwLDcpLHZePUEoTitUfDAsOSksUl49QSh2K058MCwxMyksVF49QShSK3Z8MCwxOCksQl49QShzZStafDAsNyksR149QShCK3NlfDAsOSksWl49QShHK0J8MCwxMyksc2VePUEoWitHfDAsMTgpO2xldCB6PTA7blt6KytdPW8ra3wwLG5beisrXT1hK018MCxuW3orK109ZCtIfDAsblt6KytdPXUrQ3wwLG5beisrXT1sK0t8MCxuW3orK109ZitffDAsblt6KytdPWgrRnwwLG5beisrXT15K3h8MCxuW3orK109bSt2fDAsblt6KytdPWcrUnwwLG5beisrXT1iK1R8MCxuW3orK109SStOfDAsblt6KytdPXcrQnwwLG5beisrXT1FK0d8MCxuW3orK109UytafDAsblt6KytdPVArc2V8MH1mdW5jdGlvbiBIbyhlLHQscixuKXtsZXQgcz1lWzBdLGk9dFswXSxvPXRbMV0sYT10WzJdLGQ9dFszXSx1PWVbMV0sbD1yWzBdLGY9clsxXSxoPXJbMl0seT1yWzNdLG09ZVsyXSxnPXRbNF0sYj10WzVdLEk9dFs2XSx3PXRbN10sRT1lWzNdO2ZvcihsZXQgUD0wO1A8MjA7UCs9MilkXj1BKHMrYnwwLDcpLGhePUEoZCtzfDAsOSksYl49QShoK2R8MCwxMyksc149QShiK2h8MCwxOCkseV49QSh1K2l8MCw3KSxJXj1BKHkrdXwwLDkpLGlePUEoSSt5fDAsMTMpLHVePUEoaStJfDAsMTgpLHdePUEobStsfDAsNyksb149QSh3K218MCw5KSxsXj1BKG8rd3wwLDEzKSxtXj1BKGwrb3wwLDE4KSxhXj1BKEUrZ3wwLDcpLGZePUEoYStFfDAsOSksZ149QShmK2F8MCwxMyksRV49QShnK2Z8MCwxOCksaV49QShzK2F8MCw3KSxvXj1BKGkrc3wwLDkpLGFePUEobytpfDAsMTMpLHNePUEoYStvfDAsMTgpLGxePUEodStkfDAsNyksZl49QShsK3V8MCw5KSxkXj1BKGYrbHwwLDEzKSx1Xj1BKGQrZnwwLDE4KSxnXj1BKG0reXwwLDcpLGhePUEoZyttfDAsOSkseV49QShoK2d8MCwxMyksbV49QSh5K2h8MCwxOCksYl49QShFK3d8MCw3KSxJXj1BKGIrRXwwLDkpLHdePUEoSStifDAsMTMpLEVePUEodytJfDAsMTgpO2xldCBTPTA7bltTKytdPXMsbltTKytdPXUsbltTKytdPW0sbltTKytdPUUsbltTKytdPWwsbltTKytdPWYsbltTKytdPWgsbltTKytdPXl9dmFyIGVuPXZzKFRvLHtjb3VudGVyUmlnaHQ6ITAsZXh0ZW5kTm9uY2VGbjpIb30pLHRuPVBzKHtibG9ja1NpemU6NjQsbm9uY2VMZW5ndGg6MjQsdGFnTGVuZ3RoOjE2fSwoZSx0KT0+KHtlbmNyeXB0KHIsbil7bj1ZcihyLmxlbmd0aCszMixuLCExKTtsZXQgcz1uLnN1YmFycmF5KDAsMzIpLGk9bi5zdWJhcnJheSgzMik7bi5zZXQociwzMiksbWUocyksZW4oZSx0LG4sbik7bGV0IG89WnIoaSxzKTtyZXR1cm4gbi5zZXQobywxNiksbWUobi5zdWJhcnJheSgwLDE2KSxvKSxuLnN1YmFycmF5KDE2KX0sZGVjcnlwdChyLG4pe1Eociksbj1ZcihyLmxlbmd0aCszMixuLCExKTtsZXQgcz1uLnN1YmFycmF5KDAsMzIpLGk9bi5zdWJhcnJheSgzMiw0OCksbz1uLnN1YmFycmF5KDQ4KTtuLnNldChyLDMyKSxtZShzKTtsZXQgYT1lbihlLHQscyxzKSxkPVpyKG8sYSk7aWYoIUFzKGksZCkpdGhyb3cgRXJyb3IoImludmFsaWQgdGFnIik7cmV0dXJuIGVuKGUsdCxuLnN1YmFycmF5KDE2KSxuLnN1YmFycmF5KDE2KSksbWUocyxpLGQpLG99fSkpOy8qISBub2JsZS1oYXNoZXMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi9mdW5jdGlvbiBNbyhlKXtyZXR1cm4gZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldyhlKSYmZS5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIFN0KGUpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihlKXx8ZTwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIitlKX1mdW5jdGlvbiBLZShlLC4uLnQpe2lmKCFNbyhlKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCIpO2lmKHQubGVuZ3RoPjAmJiF0LmluY2x1ZGVzKGUubGVuZ3RoKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCBvZiBsZW5ndGggIit0KyIsIGdvdCBsZW5ndGg9IitlLmxlbmd0aCl9ZnVuY3Rpb24gd3QoZSx0PSEwKXtpZihlLmRlc3Ryb3llZCl0aHJvdyBFcnJvcigiSGFzaCBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQiKTtpZih0JiZlLmZpbmlzaGVkKXRocm93IEVycm9yKCJIYXNoI2RpZ2VzdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIil9ZnVuY3Rpb24gJHQoZSx0KXtLZShlKTtsZXQgcj10Lm91dHB1dExlbjtpZihlLmxlbmd0aDxyKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK3IpfWZ1bmN0aW9uIENzKGUpe3JldHVybiBuZXcgVWludDhBcnJheShlLmJ1ZmZlcixlLmJ5dGVPZmZzZXQsZS5ieXRlTGVuZ3RoKX1mdW5jdGlvbiBpdChlKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KGUuYnVmZmVyLGUuYnl0ZU9mZnNldCxNYXRoLmZsb29yKGUuYnl0ZUxlbmd0aC80KSl9ZnVuY3Rpb24gb3QoLi4uZSl7Zm9yKGxldCB0PTA7dDxlLmxlbmd0aDt0KyspZVt0XS5maWxsKDApfWZ1bmN0aW9uIEl0KGUsdCl7cmV0dXJuIGU8PDMyLXR8ZT4+PnR9dmFyIFRzPSgoKT0+bmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQzMkFycmF5KFsyODc0NTQwMjBdKS5idWZmZXIpWzBdPT09NjgpKCk7ZnVuY3Rpb24gSHMoZSl7cmV0dXJuIGU8PDI0JjQyNzgxOTAwODB8ZTw8OCYxNjcxMTY4MHxlPj4+OCY2NTI4MHxlPj4+MjQmMjU1fXZhciBNcz1Ucz8oZSk9PmU6KGUpPT5IcyhlKTtmdW5jdGlvbiBSbyhlKXtmb3IobGV0IHQ9MDt0PGUubGVuZ3RoO3QrKyllW3RdPUhzKGVbdF0pO3JldHVybiBlfXZhciB0ZT1Ucz8oZSk9PmU6Um87ZnVuY3Rpb24gTG8oZSl7aWYodHlwZW9mIGUhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShlKSl9ZnVuY3Rpb24gYXQoZSl7aWYodHlwZW9mIGU9PT0ic3RyaW5nIillPUxvKGUpO3JldHVybiBLZShlKSxlfWNsYXNzIHJue31mdW5jdGlvbiBScyhlKXtsZXQgdD0obixzKT0+ZShzKS51cGRhdGUoYXQobikpLmRpZ2VzdCgpLHI9ZSh7fSk7cmV0dXJuIHQub3V0cHV0TGVuPXIub3V0cHV0TGVuLHQuYmxvY2tMZW49ci5ibG9ja0xlbix0LmNyZWF0ZT0obik9PmUobiksdH12YXIgTHM9VWludDMyQXJyYXkuZnJvbShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKTt2YXIgUXQ9QmlnSW50KDQyOTQ5NjcyOTUpLE9zPUJpZ0ludCgzMik7ZnVuY3Rpb24gbm4oZSx0PSExKXtpZih0KXJldHVybntoOk51bWJlcihlJlF0KSxsOk51bWJlcihlPj5PcyZRdCl9O3JldHVybntoOk51bWJlcihlPj5PcyZRdCl8MCxsOk51bWJlcihlJlF0KXwwfX1mdW5jdGlvbiB4ZShlLHQscixuLHMpe3JldHVybiBlPWUrdCtzfDAsbj1JdChuXmUsMTYpLHI9citufDAsdD1JdCh0XnIsMTIpLHthOmUsYjp0LGM6cixkOm59fWZ1bmN0aW9uIEVlKGUsdCxyLG4scyl7cmV0dXJuIGU9ZSt0K3N8MCxuPUl0KG5eZSw4KSxyPXIrbnwwLHQ9SXQodF5yLDcpLHthOmUsYjp0LGM6cixkOm59fWNsYXNzIHNuIGV4dGVuZHMgcm57Y29uc3RydWN0b3IoZSx0KXtzdXBlcigpO3RoaXMuZmluaXNoZWQ9ITEsdGhpcy5kZXN0cm95ZWQ9ITEsdGhpcy5sZW5ndGg9MCx0aGlzLnBvcz0wLFN0KGUpLFN0KHQpLHRoaXMuYmxvY2tMZW49ZSx0aGlzLm91dHB1dExlbj10LHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KGUpLHRoaXMuYnVmZmVyMzI9aXQodGhpcy5idWZmZXIpfXVwZGF0ZShlKXt3dCh0aGlzKSxlPWF0KGUpLEtlKGUpO2xldHtibG9ja0xlbjp0LGJ1ZmZlcjpyLGJ1ZmZlcjMyOm59PXRoaXMscz1lLmxlbmd0aCxpPWUuYnl0ZU9mZnNldCxvPWUuYnVmZmVyO2ZvcihsZXQgYT0wO2E8czspe2lmKHRoaXMucG9zPT09dCl0ZShuKSx0aGlzLmNvbXByZXNzKG4sMCwhMSksdGUobiksdGhpcy5wb3M9MDtsZXQgZD1NYXRoLm1pbih0LXRoaXMucG9zLHMtYSksdT1pK2E7aWYoZD09PXQmJiEodSU0KSYmYStkPHMpe2xldCBsPW5ldyBVaW50MzJBcnJheShvLHUsTWF0aC5mbG9vcigocy1hKS80KSk7dGUobCk7Zm9yKGxldCBmPTA7YSt0PHM7Zis9bi5sZW5ndGgsYSs9dCl0aGlzLmxlbmd0aCs9dCx0aGlzLmNvbXByZXNzKGwsZiwhMSk7dGUobCk7Y29udGludWV9ci5zZXQoZS5zdWJhcnJheShhLGErZCksdGhpcy5wb3MpLHRoaXMucG9zKz1kLHRoaXMubGVuZ3RoKz1kLGErPWR9cmV0dXJuIHRoaXN9ZGlnZXN0SW50byhlKXt3dCh0aGlzKSwkdChlLHRoaXMpO2xldHtwb3M6dCxidWZmZXIzMjpyfT10aGlzO3RoaXMuZmluaXNoZWQ9ITAsb3QodGhpcy5idWZmZXIuc3ViYXJyYXkodCkpLHRlKHIpLHRoaXMuY29tcHJlc3MociwwLCEwKSx0ZShyKTtsZXQgbj1pdChlKTt0aGlzLmdldCgpLmZvckVhY2goKHMsaSk9Pm5baV09TXMocykpfWRpZ2VzdCgpe2xldHtidWZmZXI6ZSxvdXRwdXRMZW46dH09dGhpczt0aGlzLmRpZ2VzdEludG8oZSk7bGV0IHI9ZS5zbGljZSgwLHQpO3JldHVybiB0aGlzLmRlc3Ryb3koKSxyfV9jbG9uZUludG8oZSl7bGV0e2J1ZmZlcjp0LGxlbmd0aDpyLGZpbmlzaGVkOm4sZGVzdHJveWVkOnMsb3V0cHV0TGVuOmkscG9zOm99PXRoaXM7cmV0dXJuIGV8fChlPW5ldyB0aGlzLmNvbnN0cnVjdG9yKHtka0xlbjppfSkpLGUuc2V0KC4uLnRoaXMuZ2V0KCkpLGUuYnVmZmVyLnNldCh0KSxlLmRlc3Ryb3llZD1zLGUuZmluaXNoZWQ9bixlLmxlbmd0aD1yLGUucG9zPW8sZS5vdXRwdXRMZW49aSxlfWNsb25lKCl7cmV0dXJuIHRoaXMuX2Nsb25lSW50bygpfX1mdW5jdGlvbiBvbihlLHQscixuLHMsaSxvLGEsZCx1LGwsZixoLHksbSxnLGIsSSx3LEUpe2xldCBTPTA7Zm9yKGxldCBQPTA7UDxuO1ArKykoe2E6cyxiOmQsYzpoLGQ6Yn09eGUocyxkLGgsYixyW3QrZVtTKytdXSkpLHthOnMsYjpkLGM6aCxkOmJ9PUVlKHMsZCxoLGIsclt0K2VbUysrXV0pLHthOmksYjp1LGM6eSxkOkl9PXhlKGksdSx5LEksclt0K2VbUysrXV0pLHthOmksYjp1LGM6eSxkOkl9PUVlKGksdSx5LEksclt0K2VbUysrXV0pLHthOm8sYjpsLGM6bSxkOnd9PXhlKG8sbCxtLHcsclt0K2VbUysrXV0pLHthOm8sYjpsLGM6bSxkOnd9PUVlKG8sbCxtLHcsclt0K2VbUysrXV0pLHthLGI6ZixjOmcsZDpFfT14ZShhLGYsZyxFLHJbdCtlW1MrK11dKSx7YSxiOmYsYzpnLGQ6RX09RWUoYSxmLGcsRSxyW3QrZVtTKytdXSkse2E6cyxiOnUsYzptLGQ6RX09eGUocyx1LG0sRSxyW3QrZVtTKytdXSkse2E6cyxiOnUsYzptLGQ6RX09RWUocyx1LG0sRSxyW3QrZVtTKytdXSkse2E6aSxiOmwsYzpnLGQ6Yn09eGUoaSxsLGcsYixyW3QrZVtTKytdXSkse2E6aSxiOmwsYzpnLGQ6Yn09RWUoaSxsLGcsYixyW3QrZVtTKytdXSkse2E6byxiOmYsYzpoLGQ6SX09eGUobyxmLGgsSSxyW3QrZVtTKytdXSkse2E6byxiOmYsYzpoLGQ6SX09RWUobyxmLGgsSSxyW3QrZVtTKytdXSkse2EsYjpkLGM6eSxkOnd9PXhlKGEsZCx5LHcsclt0K2VbUysrXV0pLHthLGI6ZCxjOnksZDp3fT1FZShhLGQseSx3LHJbdCtlW1MrK11dKTtyZXR1cm57djA6cyx2MTppLHYyOm8sdjM6YSx2NDpkLHY1OnUsdjY6bCx2NzpmLHY4Omgsdjk6eSx2MTA6bSx2MTE6Zyx2MTI6Yix2MTM6SSx2MTQ6dyx2MTU6RX19dmFyIGdlPXtDSFVOS19TVEFSVDoxLENIVU5LX0VORDoyLFBBUkVOVDo0LFJPT1Q6OCxLRVlFRF9IQVNIOjE2LERFUklWRV9LRVlfQ09OVEVYVDozMixERVJJVkVfS0VZX01BVEVSSUFMOjY0fSxBZT1Mcy5zbGljZSgpLEtzPSgoKT0+e2xldCBlPUFycmF5LmZyb20oe2xlbmd0aDoxNn0sKG4scyk9PnMpLHQ9KG4pPT5bMiw2LDMsMTAsNywwLDQsMTMsMSwxMSwxMiw1LDksMTQsMTUsOF0ubWFwKChzKT0+bltzXSkscj1bXTtmb3IobGV0IG49MCxzPWU7bjw3O24rKyxzPXQocykpci5wdXNoKC4uLnMpO3JldHVybiBVaW50OEFycmF5LmZyb20ocil9KSgpO2NsYXNzIGFuIGV4dGVuZHMgc257Y29uc3RydWN0b3IoZT17fSx0PTApe3N1cGVyKDY0LGUuZGtMZW49PT12b2lkIDA/MzI6ZS5ka0xlbik7dGhpcy5jaHVua1Bvcz0wLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMuZmxhZ3M9MCx0aGlzLnN0YWNrPVtdLHRoaXMucG9zT3V0PTAsdGhpcy5idWZmZXJPdXQzMj1uZXcgVWludDMyQXJyYXkoMTYpLHRoaXMuY2h1bmtPdXQ9MCx0aGlzLmVuYWJsZVhPRj0hMDtsZXR7a2V5OnIsY29udGV4dDpufT1lLHM9biE9PXZvaWQgMDtpZihyIT09dm9pZCAwKXtpZihzKXRocm93IEVycm9yKCdPbmx5ICJrZXkiIG9yICJjb250ZXh0IiBjYW4gYmUgc3BlY2lmaWVkIGF0IHNhbWUgdGltZScpO2xldCBpPWF0KHIpLnNsaWNlKCk7S2UoaSwzMiksdGhpcy5JVj1pdChpKSx0ZSh0aGlzLklWKSx0aGlzLmZsYWdzPXR8Z2UuS0VZRURfSEFTSH1lbHNlIGlmKHMpe2xldCBpPWF0KG4pLG89bmV3IGFuKHtka0xlbjozMn0sZ2UuREVSSVZFX0tFWV9DT05URVhUKS51cGRhdGUoaSkuZGlnZXN0KCk7dGhpcy5JVj1pdChvKSx0ZSh0aGlzLklWKSx0aGlzLmZsYWdzPXR8Z2UuREVSSVZFX0tFWV9NQVRFUklBTH1lbHNlIHRoaXMuSVY9QWUuc2xpY2UoKSx0aGlzLmZsYWdzPXQ7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCksdGhpcy5idWZmZXJPdXQ9Q3ModGhpcy5idWZmZXJPdXQzMil9Z2V0KCl7cmV0dXJuW119c2V0KCl7fWIyQ29tcHJlc3MoZSx0LHIsbj0wKXtsZXR7c3RhdGU6cyxwb3M6aX09dGhpcyx7aDpvLGw6YX09bm4oQmlnSW50KGUpLCEwKSx7djA6ZCx2MTp1LHYyOmwsdjM6Zix2NDpoLHY1OnksdjY6bSx2NzpnLHY4OmIsdjk6SSx2MTA6dyx2MTE6RSx2MTI6Uyx2MTM6UCx2MTQ6ayx2MTU6TX09b24oS3MsbixyLDcsc1swXSxzWzFdLHNbMl0sc1szXSxzWzRdLHNbNV0sc1s2XSxzWzddLEFlWzBdLEFlWzFdLEFlWzJdLEFlWzNdLG8sYSxpLHQpO3NbMF09ZF5iLHNbMV09dV5JLHNbMl09bF53LHNbM109Zl5FLHNbNF09aF5TLHNbNV09eV5QLHNbNl09bV5rLHNbN109Z15NfWNvbXByZXNzKGUsdD0wLHI9ITEpe2xldCBuPXRoaXMuZmxhZ3M7aWYoIXRoaXMuY2h1bmtQb3Mpbnw9Z2UuQ0hVTktfU1RBUlQ7aWYodGhpcy5jaHVua1Bvcz09PTE1fHxyKW58PWdlLkNIVU5LX0VORDtpZighcil0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2lmKHRoaXMuYjJDb21wcmVzcyh0aGlzLmNodW5rc0RvbmUsbixlLHQpLHRoaXMuY2h1bmtQb3MrPTEsdGhpcy5jaHVua1Bvcz09PTE2fHxyKXtsZXQgcz10aGlzLnN0YXRlO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpO2ZvcihsZXQgaSxvPXRoaXMuY2h1bmtzRG9uZSsxO3J8fCEobyYxKTtvPj49MSl7aWYoIShpPXRoaXMuc3RhY2sucG9wKCkpKWJyZWFrO3RoaXMuYnVmZmVyMzIuc2V0KGksMCksdGhpcy5idWZmZXIzMi5zZXQocyw4KSx0aGlzLnBvcz10aGlzLmJsb2NrTGVuLHRoaXMuYjJDb21wcmVzcygwLHRoaXMuZmxhZ3N8Z2UuUEFSRU5ULHRoaXMuYnVmZmVyMzIsMCkscz10aGlzLnN0YXRlLHRoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpfXRoaXMuY2h1bmtzRG9uZSsrLHRoaXMuY2h1bmtQb3M9MCx0aGlzLnN0YWNrLnB1c2gocyl9dGhpcy5wb3M9MH1fY2xvbmVJbnRvKGUpe2U9c3VwZXIuX2Nsb25lSW50byhlKTtsZXR7SVY6dCxmbGFnczpyLHN0YXRlOm4sY2h1bmtQb3M6cyxwb3NPdXQ6aSxjaHVua091dDpvLHN0YWNrOmEsY2h1bmtzRG9uZTpkfT10aGlzO3JldHVybiBlLnN0YXRlLnNldChuLnNsaWNlKCkpLGUuc3RhY2s9YS5tYXAoKHUpPT5VaW50MzJBcnJheS5mcm9tKHUpKSxlLklWLnNldCh0KSxlLmZsYWdzPXIsZS5jaHVua1Bvcz1zLGUuY2h1bmtzRG9uZT1kLGUucG9zT3V0PWksZS5jaHVua091dD1vLGUuZW5hYmxlWE9GPXRoaXMuZW5hYmxlWE9GLGUuYnVmZmVyT3V0MzIuc2V0KHRoaXMuYnVmZmVyT3V0MzIpLGV9ZGVzdHJveSgpe3RoaXMuZGVzdHJveWVkPSEwLG90KHRoaXMuc3RhdGUsdGhpcy5idWZmZXIzMix0aGlzLklWLHRoaXMuYnVmZmVyT3V0MzIpLG90KC4uLnRoaXMuc3RhY2spfWIyQ29tcHJlc3NPdXQoKXtsZXR7c3RhdGU6ZSxwb3M6dCxmbGFnczpyLGJ1ZmZlcjMyOm4sYnVmZmVyT3V0MzI6c309dGhpcyx7aDppLGw6b309bm4oQmlnSW50KHRoaXMuY2h1bmtPdXQrKykpO3RlKG4pO2xldHt2MDphLHYxOmQsdjI6dSx2MzpsLHY0OmYsdjU6aCx2Njp5LHY3Om0sdjg6Zyx2OTpiLHYxMDpJLHYxMTp3LHYxMjpFLHYxMzpTLHYxNDpQLHYxNTprfT1vbihLcywwLG4sNyxlWzBdLGVbMV0sZVsyXSxlWzNdLGVbNF0sZVs1XSxlWzZdLGVbN10sQWVbMF0sQWVbMV0sQWVbMl0sQWVbM10sbyxpLHQscik7c1swXT1hXmcsc1sxXT1kXmIsc1syXT11Xkksc1szXT1sXncsc1s0XT1mXkUsc1s1XT1oXlMsc1s2XT15XlAsc1s3XT1tXmssc1s4XT1lWzBdXmcsc1s5XT1lWzFdXmIsc1sxMF09ZVsyXV5JLHNbMTFdPWVbM11edyxzWzEyXT1lWzRdXkUsc1sxM109ZVs1XV5TLHNbMTRdPWVbNl1eUCxzWzE1XT1lWzddXmssdGUobiksdGUocyksdGhpcy5wb3NPdXQ9MH1maW5pc2goKXtpZih0aGlzLmZpbmlzaGVkKXJldHVybjt0aGlzLmZpbmlzaGVkPSEwLG90KHRoaXMuYnVmZmVyLnN1YmFycmF5KHRoaXMucG9zKSk7bGV0IGU9dGhpcy5mbGFnc3xnZS5ST09UO2lmKHRoaXMuc3RhY2subGVuZ3RoKWV8PWdlLlBBUkVOVCx0ZSh0aGlzLmJ1ZmZlcjMyKSx0aGlzLmNvbXByZXNzKHRoaXMuYnVmZmVyMzIsMCwhMCksdGUodGhpcy5idWZmZXIzMiksdGhpcy5jaHVua3NEb25lPTAsdGhpcy5wb3M9dGhpcy5ibG9ja0xlbjtlbHNlIGV8PSghdGhpcy5jaHVua1Bvcz9nZS5DSFVOS19TVEFSVDowKXxnZS5DSFVOS19FTkQ7dGhpcy5mbGFncz1lLHRoaXMuYjJDb21wcmVzc091dCgpfXdyaXRlSW50byhlKXt3dCh0aGlzLCExKSxLZShlKSx0aGlzLmZpbmlzaCgpO2xldHtibG9ja0xlbjp0LGJ1ZmZlck91dDpyfT10aGlzO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzOyl7aWYodGhpcy5wb3NPdXQ+PXQpdGhpcy5iMkNvbXByZXNzT3V0KCk7bGV0IGk9TWF0aC5taW4odC10aGlzLnBvc091dCxzLW4pO2Uuc2V0KHIuc3ViYXJyYXkodGhpcy5wb3NPdXQsdGhpcy5wb3NPdXQraSksbiksdGhpcy5wb3NPdXQrPWksbis9aX1yZXR1cm4gZX14b2ZJbnRvKGUpe2lmKCF0aGlzLmVuYWJsZVhPRil0aHJvdyBFcnJvcigiWE9GIGlzIG5vdCBwb3NzaWJsZSBhZnRlciBkaWdlc3QgY2FsbCIpO3JldHVybiB0aGlzLndyaXRlSW50byhlKX14b2YoZSl7cmV0dXJuIFN0KGUpLHRoaXMueG9mSW50byhuZXcgVWludDhBcnJheShlKSl9ZGlnZXN0SW50byhlKXtpZigkdChlLHRoaXMpLHRoaXMuZmluaXNoZWQpdGhyb3cgRXJyb3IoImRpZ2VzdCgpIHdhcyBhbHJlYWR5IGNhbGxlZCIpO3JldHVybiB0aGlzLmVuYWJsZVhPRj0hMSx0aGlzLndyaXRlSW50byhlKSx0aGlzLmRlc3Ryb3koKSxlfWRpZ2VzdCgpe3JldHVybiB0aGlzLmRpZ2VzdEludG8obmV3IFVpbnQ4QXJyYXkodGhpcy5vdXRwdXRMZW4pKX19dmFyIFZzPVJzKChlKT0+bmV3IGFuKGUpKTt2YXIgT289MzIsWGg9U3ltYm9sKCJYMjU1MTlTayIpO2Z1bmN0aW9uIF9zKGUpe2lmKGUuYnl0ZUxlbmd0aCE9PU9vKXJldHVybiBjKDEwKTtyZXR1cm4gcChlKX12YXIgVj0oMW48PDI1NW4pLTE5bixLbz0xMjE2NjVuLE5zPW5ldyBVaW50OEFycmF5KDMyKTtOc1swXT05O2Z1bmN0aW9uIHFzKGUpe2xldCB0PTBuO2ZvcihsZXQgcj1lLmxlbmd0aC0xO3I+PTA7ci0tKXQ9dDw8OG58QmlnSW50KGVbcl0pO3JldHVybiB0fWZ1bmN0aW9uIFZvKGUpe2xldCB0PW5ldyBVaW50OEFycmF5KDMyKSxyPShlJVYrViklVjtmb3IobGV0IG49MDtuPDMyO24rKyl0W25dPU51bWJlcihyJjB4ZmZuKSxyPj49OG47cmV0dXJuIHR9ZnVuY3Rpb24gX28oZSl7bGV0IHQ9ZS5zbGljZSgpO3JldHVybiB0WzMxXSY9MTI3LHFzKHQpfWZ1bmN0aW9uIE5vKGUpe2xldCB0PWUuc2xpY2UoKTtyZXR1cm4gdFswXSY9MjQ4LHRbMzFdJj0xMjcsdFszMV18PTY0LHR9ZnVuY3Rpb24gWXQoZSx0LHIpe2xldCBuPS1lLHM9KHRecikmbjtyZXR1cm5bdF5zLHJec119ZnVuY3Rpb24gcW8oZSl7bGV0IHQ9Vi0ybixyPShlJVYrViklVixuPTFuO3doaWxlKHQ+MG4pe2lmKHQmMW4pbj1uKnIlVjtyPXIqciVWLHQ+Pj0xbn1yZXR1cm4gbn1mdW5jdGlvbiBGbyhlLHQpe2xldCByPU5vKGUpLG49X28odCkscz0xbixpPTBuLG89bixhPTFuLGQ9MG4sdT1xcyhyKTtmb3IobGV0IGw9MjU0O2w+PTA7bC0tKXtsZXQgZj11Pj5CaWdJbnQobCkmMW47ZF49ZixbcyxvXT1ZdChkLHMsbyksW2ksYV09WXQoZCxpLGEpLGQ9ZjtsZXQgaD0ocytpKSVWLHk9aCpoJVYsbT0ocy1pK1YpJVYsZz1tKm0lVixiPSh5LWcrViklVixJPShvK2EpJVYsRT0oby1hK1YpJVYqaCVWLFM9SSptJVYsUD0oRStTKSVWLGs9KEUtUytWKSVWO289UCpQJVYsYT1uKmsqayVWLHM9eSpnJVYsaT1iKih5K0tvKmIpJVZ9cmV0dXJuW3Msb109WXQoZCxzLG8pLFtpLGFdPVl0KGQsaSxhKSxyLmZpbGwoMCksVm8ocypxbyhpKSVWKX1mdW5jdGlvbiBGcyhlKXtyZXR1cm4gRm8oZSxOcyl9dmFyIGNuPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIFdzKGUpe2xldCB0PW5ldyBVaW50OEFycmF5KGNuLmxlbmd0aCszMik7cmV0dXJuIHQuc2V0KGNuKSx0LnNldChlLnN1YmFycmF5KDAsMzIpLGNuLmxlbmd0aCksdH12YXIgZG49bmV3IFVpbnQ4QXJyYXkoWzQ4LDQ2LDIsMSwwLDQ4LDUsNiwzLDQzLDEwMSwxMTAsNCwzNCw0LDMyXSk7ZnVuY3Rpb24genMoZSl7bGV0IHQ9bmV3IFVpbnQ4QXJyYXkoZG4ubGVuZ3RoKzMyKTtyZXR1cm4gdC5zZXQoZG4pLHQuc2V0KGUuc3ViYXJyYXkoMCwzMiksZG4ubGVuZ3RoKSx0fWZ1bmN0aW9uIFhzKGUpe3JldHVybiB0eXBlb2YgZT09PSJzdHJpbmciP25ldyBUZXh0RW5jb2RlcigpLmVuY29kZShlKTplfWZ1bmN0aW9uIFBlKGUpe2xldCB0PW5ldyBBcnJheUJ1ZmZlcihlLmJ5dGVMZW5ndGgpO3JldHVybiBuZXcgVWludDhBcnJheSh0KS5zZXQoZSksdH1jbGFzcyBWZXt2ZXJpZnlLZXlzPW5ldyBNYXA7YXN5bmMgZ2VuUmFuZG9tQnl0ZXMoZSl7cmV0dXJuIGJ0KGUpfWFzeW5jIGdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKXtyZXR1cm4gYnQoMzIpfWFzeW5jIGVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoZSx0KXtsZXQgcj1idCgyNCkscz10bih0LHIpLmVuY3J5cHQoZSk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFsuLi5yLC4uLnNdKX1hc3luYyBkZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKGUsdCl7bGV0IHI9ZS5zbGljZSgwLDI0KSxuPWUuc2xpY2UoMjQpO3JldHVybiB0bih0LHIpLmRlY3J5cHQobil9YXN5bmMgZGVyaXZlRWQyNTUxOUtleVBhaXIoZSl7bGV0IHQ9ZSxyPVdzKHQpLG49UGUociksczt0cnl7bGV0IHU9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLG4se25hbWU6IkVkMjU1MTkifSwhMCxbInNpZ24iXSk7cz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJqd2siLHUpfWZpbmFsbHl7ci5maWxsKDApLG5ldyBVaW50OEFycmF5KG4pLmZpbGwoMCl9aWYodHlwZW9mIHMueCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJFZDI1NTE5IEpXSyBtaXNzaW5nIHgiKTtsZXQgaT1zLng7cy5kPXZvaWQgMDtsZXQgbz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJqd2siLHtrdHk6Ik9LUCIsY3J2OiJFZDI1NTE5Iix4Oml9LHtuYW1lOiJFZDI1NTE5In0sITAsWyJ2ZXJpZnkiXSksYT1uZXcgVWludDhBcnJheShhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJyYXciLG8pKTt0aGlzLnZlcmlmeUtleXMuc2V0KGhlKGEpLG8pO2xldCBkPW5ldyBVaW50OEFycmF5KDY0KTtyZXR1cm4gZC5zZXQodCwwKSxkLnNldChhLDMyKSx7a2V5VHlwZToiZWQyNTUxOSIscHJpdmF0ZUtleTpkLHB1YmxpY0tleTphfX1hc3luYyBpbXBvcnRTaWduS2V5KGUpe2xldCB0PWUuc3ViYXJyYXkoMCwzMikscj1Xcyh0KSxuPVBlKHIpO3RyeXtyZXR1cm4gYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLG4se25hbWU6IkVkMjU1MTkifSwhMSxbInNpZ24iXSl9ZmluYWxseXtyLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkobikuZmlsbCgwKX19YXN5bmMgaW1wb3J0VmVyaWZ5S2V5KGUpe2xldCB0PWhlKGUpLHI9dGhpcy52ZXJpZnlLZXlzLmdldCh0KTtpZihyKXJldHVybiByO2xldCBuPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsUGUoZSkse25hbWU6IkVkMjU1MTkifSwhMSxbInZlcmlmeSJdKTtyZXR1cm4gdGhpcy52ZXJpZnlLZXlzLnNldCh0LG4pLG59YXN5bmMgc2lnbkVkMjU1MTkoZSx0KXtsZXQgcj1YcyhlKSxuPWF3YWl0IHRoaXMuaW1wb3J0U2lnbktleSh0KSxzPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5zaWduKHtuYW1lOiJFZDI1NTE5In0sbixQZShyKSk7cmV0dXJuIG5ldyBVaW50OEFycmF5KHMpfWFzeW5jIGNoZWNrU2lnRWQyNTUxOShlLHQscil7bGV0IG49WHModCk7dHJ5e2xldCBzPWF3YWl0IHRoaXMuaW1wb3J0VmVyaWZ5S2V5KHIpO3JldHVybiBhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUudmVyaWZ5KHtuYW1lOiJFZDI1NTE5In0scyxQZShlKSxQZShuKSl9Y2F0Y2h7cmV0dXJuITF9fWFzeW5jIGJsYWtlMyhlKXtyZXR1cm4gVnMoZSl9YXN5bmMgZ2VuWDI1NTE5KCl7bGV0IGU9YXdhaXQgYnQoMzIpO2VbMF0mPTI0OCxlWzMxXSY9MTI3LGVbMzFdfD02NDtsZXRbdCxyXT1fcyhlKTtpZihyIT09MHx8dD09PXZvaWQgMCl0aHJvdyBlLmZpbGwoMCksRXJyb3IoIlgyNTUxOSBzY2FsYXIgYnJhbmQgZmFpbGVkIik7bGV0IG49RnModCkscz16cyh0KSxpPVBlKHMpO3RyeXtsZXQgbz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsaSx7bmFtZToiWDI1NTE5In0sITAsWyJkZXJpdmVCaXRzIl0pLGE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixvKTtpZih0eXBlb2YgYS54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIlgyNTUxOSBKV0sgbWlzc2luZyB4Iik7bGV0IGQ9Rm4oYS54KTtpZihhLmQ9dm9pZCAwLCFYKGQsbikpdGhyb3cgRXJyb3IoIlgyNTUxOSBXZWJDcnlwdG8gcHViICE9IFJGQyA3NzQ4Iik7cmV0dXJue3ByaXY6dCxwdWI6bn19Y2F0Y2gobyl7dGhyb3cgdC5maWxsKDApLG99ZmluYWxseXtzLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoaSkuZmlsbCgwKX19YXN5bmMgeDI1NTE5U2hhcmVkKGUsdCl7bGV0IHI9enMoZSksbj1QZShyKTt0cnl7bGV0IHM9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLG4se25hbWU6IlgyNTUxOSJ9LCExLFsiZGVyaXZlQml0cyJdKSxpPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsUGUodCkse25hbWU6IlgyNTUxOSJ9LCExLFtdKSxvPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5kZXJpdmVCaXRzKHtuYW1lOiJYMjU1MTkiLHB1YmxpYzppfSxzLDI1Nik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG8pfWZpbmFsbHl7ci5maWxsKDApLG5ldyBVaW50OEFycmF5KG4pLmZpbGwoMCl9fX12YXIgV289bmV3IFZlLEp0PVdvO3ZhciBadD17ZW5jb2RlKGUsdCl7bGV0IHI9ZS53cml0ZVZhclN0cmluZyh0LmhhbmRsZSk7aWYociE9PTApcmV0dXJuIHI7bGV0IG49ZS53cml0ZVZhclN0cmluZyh0LmxhYmVsKTtpZihuIT09MClyZXR1cm4gbjtyZXR1cm4gZS53cml0ZVZhckludCh0LmlkeD8/MCl9LGRlY29kZShlKXtsZXRbdCxyXT1lLnJlYWRWYXJTdHJpbmcoKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1lLnJlYWRWYXJTdHJpbmcoKTtpZihzIT09MClyZXR1cm4gYyhzKTtsZXRbaSxvXT1lLnJlYWRWYXJJbnQoKTtpZihvIT09MClyZXR1cm4gYyhvKTtyZXR1cm4gcCh7aGFuZGxlOnQsbGFiZWw6bixpZHg6aX0pfX07dmFyIHVuPXtlbmNvZGUoZSx0KXtsZXQgcj1lLndyaXRlVmFySW50KHQuaG9zdHMubGVuZ3RoKTtpZihyIT09MClyZXR1cm4gcjtmb3IobGV0IG4gb2YgdC5ob3N0cyl7bGV0IHM9ZS53cml0ZVN0cnVjdChadCxuKTtpZihzIT09MClyZXR1cm4gc31yZXR1cm4gMH0sZGVjb2RlKGUpe2xldFt0LHJdPWUucmVhZFZhckludCgpO2lmKHIhPT0wKXJldHVybiBjKHIpO2lmKHQ9PT12b2lkIDB8fHQ8MClyZXR1cm4gYygxMCk7bGV0IG49W107Zm9yKGxldCBzPTA7czx0O3MrKyl7bGV0W2ksb109ZS5yZWFkU3RydWN0KFp0KTtpZihvIT09MClyZXR1cm4gYyhvKTtpZihpPT09dm9pZCAwKXJldHVybiBjKDE0KTtuLnB1c2goaSl9cmV0dXJuIHAoe2hvc3RzOm59KX19O3ZhciB6bz1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucXJwYWlyLnYxIikseHQ9MzIsWG89eHQrMjQrMTYsam89MzIsbXk9U3ltYm9sKCJESEtFUmVxIiksZ3k9U3ltYm9sKCJESEtFUmVzcCIpO2Z1bmN0aW9uIGpzKGUpe2lmKGUuYnl0ZUxlbmd0aCE9PXh0KXJldHVybiBjKDEwKTtyZXR1cm4gcChlKX1mdW5jdGlvbiBHcyhlKXtpZihlLmJ5dGVMZW5ndGg8WG8pcmV0dXJuIGMoMTApO3JldHVybiBwKGUpfXZhciBlcj1uZXcgVmU7YXN5bmMgZnVuY3Rpb24gbG4oZSx0LHIsbil7bGV0IHM7dHJ5e3M9YXdhaXQgZXIueDI1NTE5U2hhcmVkKGUsdCl9Y2F0Y2h7cmV0dXJuIGMoMjkpfXRyeXtpZihzLmJ5dGVMZW5ndGghPT14dHx8cy5ldmVyeSgoYSk9PmE9PT0wKSlyZXR1cm4gYygxMCk7bGV0IGk9d2Uocyx6byksbz13ZShpLHdlKHIsbikpO3RyeXtsZXQgYT1hd2FpdCBlci5ibGFrZTMobyk7cmV0dXJuIHAoYS5zbGljZSgwLGpvKSl9ZmluYWxseXtpLmZpbGwoMCksby5maWxsKDApfX1maW5hbGx5e3MuZmlsbCgwKX19Y2xhc3MgdHJ7I2U7I3Q7Y29uc3RydWN0b3IoZSx0KXt0aGlzLiNlPWUsdGhpcy4jdD10fXN0YXRpYyBhc3luYyBjcmVhdGUoKXtsZXQgZTt0cnl7bGV0IHQ9YXdhaXQgZXIuZ2VuWDI1NTE5KCk7ZT10LnByaXY7bGV0W3Isbl09anModC5wdWIpO2lmKG4hPT0wKXJldHVybiBjKG4pO2lmKHI9PT12b2lkIDApcmV0dXJuIGMoMTApO2xldCBzPW5ldyB0cihlLHIpO3JldHVybiBlPXZvaWQgMCxwKHMpfWNhdGNoe3JldHVybiBjKDI5KX1maW5hbGx5e2U/LmZpbGwoMCl9fXdpcGUoKXt0aGlzLiNlLmZpbGwoMCl9Z2V0IGRoa2VSZXEoKXtsZXRbZSx0XT1qcyh0aGlzLiN0LnNsaWNlKCkpO2lmKGU9PT12b2lkIDApdGhyb3cgRXJyb3IoYGRoa2VSZXEgJHt0fWApO3JldHVybiBlfWFzeW5jIGZpbmlzaChlKXtsZXQgdD1lLnN1YmFycmF5KDAseHQpLHI9ZS5zdWJhcnJheSh4dCksW24sc109YXdhaXQgbG4odGhpcy4jZSx0LHRoaXMuI3QsdCk7aWYocyE9PTApcmV0dXJuIGMocyk7aWYobj09PXZvaWQgMClyZXR1cm4gYygxMik7bGV0IGk7dHJ5e3RyeXtpPWF3YWl0IGVyLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQocixuKX1jYXRjaHtyZXR1cm4gYygyMCl9bGV0W28sYV09YWUuZnJvbVBhaXJQbGFpbihpKTtpZihhIT09MClyZXR1cm4gYyhhKTtpZihvPT09dm9pZCAwKXJldHVybiBjKDEyKTtyZXR1cm4gdGhpcy53aXBlKCkscChvKX1maW5hbGx5e24uZmlsbCgwKSxpPy5maWxsKDApfX19ZnVuY3Rpb24gVWUoZSl7bGV0IHQ9bmV3IFVpbnQ4QXJyYXkoZSk7aWYoZT4wKWNyeXB0by5nZXRSYW5kb21WYWx1ZXModCk7cmV0dXJuIHR9dmFyIF9lPTMyLHJyPSJESVBMT01BVElDIixiZT0icHVibGljLWtleSIsR289LTcsJG89LTgsUW89LTI1Nyxucj1be3R5cGU6YmUsYWxnOkdvfSx7dHlwZTpiZSxhbGc6JG99LHt0eXBlOmJlLGFsZzpRb31dO2Z1bmN0aW9uIFlvKGUpe3JldHVybiBlLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1wuJC8sIiIpfHwibG9jYWxob3N0In1mdW5jdGlvbiBDZShlKXtsZXQgdD1uZXcgVWludDhBcnJheShlLmJ5dGVMZW5ndGgpO3JldHVybiB0LnNldChlKSx0LmJ1ZmZlcn1mdW5jdGlvbiBzcihlKXtpZihlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpcmV0dXJuIG5ldyBVaW50OEFycmF5KGUpLnNsaWNlKCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KGUuYnVmZmVyLGUuYnl0ZU9mZnNldCxlLmJ5dGVMZW5ndGgpLnNsaWNlKCl9ZnVuY3Rpb24gTmUoZSl7aWYoZT8ucnBJZCE9PXZvaWQgMClyZXR1cm4gcChlLnJwSWQpO2lmKHR5cGVvZiBsb2NhdGlvbj4idSIpcmV0dXJuIGMoOSk7cmV0dXJuIHAoWW8obG9jYXRpb24uaG9zdG5hbWUpKX12YXIgJHM9IiI7ZnVuY3Rpb24gVGUoZSl7aWYoZSBpbnN0YW5jZW9mIEVycm9yKXskcz1lLm1lc3NhZ2U9PT0iIj9lLm5hbWU6YCR7ZS5uYW1lfTogJHtlLm1lc3NhZ2V9YDtyZXR1cm59JHM9U3RyaW5nKGUpfWZ1bmN0aW9uIGlyKGUpe2lmKCEoZSBpbnN0YW5jZW9mIEVycm9yKSlyZXR1cm4hMTtyZXR1cm4gZS5uYW1lPT09Ik5vdEFsbG93ZWRFcnJvciImJmUubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCJkb2VzIG5vdCBoYXZlIGZvY3VzIil9ZnVuY3Rpb24gUXMoKXtpZih0eXBlb2YgZG9jdW1lbnQ+InUiKXJldHVybiEwO3JldHVybiBkb2N1bWVudC52aXNpYmlsaXR5U3RhdGUhPT0iaGlkZGVuIn1mdW5jdGlvbiBjdCgpe2lmKHR5cGVvZiBnbG9iYWxUaGlzLmZvY3VzIT09ImZ1bmN0aW9uIilyZXR1cm47dHJ5e2dsb2JhbFRoaXMuZm9jdXMoKX1jYXRjaHt9fWZ1bmN0aW9uIG9yKGU9MjUwMCl7aWYoUXMoKSlyZXR1cm4gY3QoKSxQcm9taXNlLnJlc29sdmUoKTtyZXR1cm4gbmV3IFByb21pc2UoKHQpPT57bGV0IHI9KCk9PntjbGVhclRpbWVvdXQocyksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigidmlzaWJpbGl0eWNoYW5nZSIsbiksY3QoKSx0KCl9LG49KCk9PntpZihRcygpKXIoKX0scz1zZXRUaW1lb3V0KHIsZSk7ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigidmlzaWJpbGl0eWNoYW5nZSIsbiksbigpfSl9YXN5bmMgZnVuY3Rpb24gYXIoZSl7YXdhaXQgb3IoKTt0cnl7cmV0dXJuIGF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5jcmVhdGUoZSl9Y2F0Y2godCl7aWYoIWlyKHQpKXRocm93IHQ7cmV0dXJuIGN0KCksYXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmNyZWF0ZShlKX19YXN5bmMgZnVuY3Rpb24gY3IoZSl7YXdhaXQgb3IoKTt0cnl7cmV0dXJuIGF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoZSl9Y2F0Y2godCl7aWYoIWlyKHQpKXRocm93IHQ7cmV0dXJuIGN0KCksYXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldChlKX19ZnVuY3Rpb24gcWUoKXtpZih0eXBlb2YgbmF2aWdhdG9yPiJ1Inx8IW5hdmlnYXRvci5jcmVkZW50aWFsc3x8dHlwZW9mIFB1YmxpY0tleUNyZWRlbnRpYWw+InUiKXJldHVybiAyNDtyZXR1cm4gMH1mdW5jdGlvbiBGZShlKXtpZihlPT09bnVsbHx8ZS50eXBlIT09YmV8fCEoInJhd0lkImluIGUpfHx0eXBlb2YgZS5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzIT09ImZ1bmN0aW9uIilyZXR1cm4gYygyNyk7cmV0dXJuIHAoZSl9ZnVuY3Rpb24gcG4oZSl7aWYoZT09PSJwbGF0Zm9ybSJ8fGU9PT0iY3Jvc3MtcGxhdGZvcm0iKXJldHVybiBlO3JldHVybn1mdW5jdGlvbiBKcyhlKXtpZigvaVBob25lfGlQYWR8aVBvZC9pLnRlc3QoZSkpcmV0dXJuImlvcyI7aWYoL0FuZHJvaWQvaS50ZXN0KGUpKXJldHVybiJhbmRyb2lkIjtpZigvTWFjIE9TIFh8TWFjaW50b3NoL2kudGVzdChlKSlyZXR1cm4ibWFjb3MiO2lmKC9XaW5kb3dzL2kudGVzdChlKSlyZXR1cm4id2luZG93cyI7aWYoL0xpbnV4L2kudGVzdChlKSlyZXR1cm4ibGludXgiO3JldHVybiJvdGhlciJ9ZnVuY3Rpb24gaG4oZSl7bGV0IHQ9ZS5yZXNwb25zZTtpZighKCJnZXRUcmFuc3BvcnRzImluIHQpKXJldHVybjtsZXQgcj10LmdldFRyYW5zcG9ydHM7aWYodHlwZW9mIHIhPT0iZnVuY3Rpb24iKXJldHVybjtsZXQgbj1yLmNhbGwodCk7aWYoIUFycmF5LmlzQXJyYXkobikpcmV0dXJuO2xldCBzPVtdO2ZvcihsZXQgaSBvZiBuKWlmKHR5cGVvZiBpPT09InN0cmluZyImJmkubGVuZ3RoPjApcy5wdXNoKGkpO3JldHVybiBzLmxlbmd0aD09PTA/dm9pZCAwOnN9dmFyIEpvPTMyLFpvPTY0LGZuPTM3LFlzPTE2O2Z1bmN0aW9uIFpzKGUpe2xldCB0PWUucmVzcG9uc2U7aWYoISgiZ2V0QXV0aGVudGljYXRvckRhdGEiaW4gdCkpcmV0dXJuO2xldCByPXQuZ2V0QXV0aGVudGljYXRvckRhdGE7aWYodHlwZW9mIHIhPT0iZnVuY3Rpb24iKXJldHVybjtsZXQgbj1yLmNhbGwodCk7aWYoIShuIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKXJldHVybjtsZXQgcz1uZXcgVWludDhBcnJheShuKTtpZihzLmJ5dGVMZW5ndGg8Zm4rWXMpcmV0dXJuO2xldCBpPXNbSm9dO2lmKGk9PT12b2lkIDB8fChpJlpvKT09PTApcmV0dXJuO3JldHVybiBzLnNsaWNlKGZuLGZuK1lzKX1hc3luYyBmdW5jdGlvbiBlaShlKXtsZXQgdD1xZSgpO2lmKHQhPT0wKXJldHVybiBjKHQpO2xldFtyLG5dPU5lKGUpO2lmKG4hPT0wKXJldHVybiBjKG4pO2lmKHI9PT12b2lkIDApcmV0dXJuIGMoOSk7bGV0IHM9ZT8udXNlck5hbWU/PyJkaXBsb21hdGljLXNlZWQiLGk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIn07aWYoZT8uYXV0aGVudGljYXRvckF0dGFjaG1lbnQhPT12b2lkIDApaS5hdXRoZW50aWNhdG9yQXR0YWNobWVudD1lLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50O2xldCBvPXtsYXJnZUJsb2I6e3N1cHBvcnQ6InJlcXVpcmVkIn19LGE7dHJ5e2E9YXdhaXQgYXIoe3B1YmxpY0tleTp7Y2hhbGxlbmdlOlVlKF9lKSxycDp7aWQ6cixuYW1lOmU/LnJwTmFtZT8/cnJ9LHVzZXI6e2lkOlVlKDE2KSxuYW1lOnMsZGlzcGxheU5hbWU6c30scHViS2V5Q3JlZFBhcmFtczpucixhdXRoZW50aWNhdG9yU2VsZWN0aW9uOmksZXh0ZW5zaW9uczpvLC4uLmU/LmhpbnRzIT09dm9pZCAwP3toaW50czplLmhpbnRzfTp7fX19KX1jYXRjaChmKXtyZXR1cm4gVGUoZiksYygzMCl9bGV0W2QsdV09RmUoYSk7aWYodSE9PTApcmV0dXJuIGModSk7aWYoZD09PXZvaWQgMClyZXR1cm4gYygyNyk7aWYoZC5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iPy5zdXBwb3J0ZWQhPT0hMClyZXR1cm4gYygzMCk7cmV0dXJuIHAobmV3IFVpbnQ4QXJyYXkoZC5yYXdJZCkpfWFzeW5jIGZ1bmN0aW9uIHluKGUsdCxyLG4pe2xldCBzPXtjaGFsbGVuZ2U6VWUoX2UpLHJwSWQ6ZSx1c2VyVmVyaWZpY2F0aW9uOiJwcmVmZXJyZWQifTtpZih0Py5oaW50cyE9PXZvaWQgMClzLmhpbnRzPXQuaGludHM7aWYociE9PXZvaWQgMClzLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOmJlLGlkOkNlKHIpfV07aWYobiE9PXZvaWQgMClzLmV4dGVuc2lvbnM9bjtsZXQgaTt0cnl7aT1hd2FpdCBjcih7cHVibGljS2V5OnN9KX1jYXRjaChkKXtyZXR1cm4gVGUoZCksYygzMCl9bGV0W28sYV09RmUoaSk7aWYoYSE9PTApcmV0dXJuIGMoYSk7aWYobz09PXZvaWQgMClyZXR1cm4gYygyNyk7cmV0dXJuIHAobyl9YXN5bmMgZnVuY3Rpb24gdGkoZSx0KXtsZXQgcj1xZSgpO2lmKHIhPT0wKXJldHVybiBjKHIpO2xldFtuLHNdPU5lKHQpO2lmKHMhPT0wKXJldHVybiBjKHMpO2lmKG49PT12b2lkIDApcmV0dXJuIGMoOSk7bGV0IGk9ZTtpZihpPT09dm9pZCAwKXtsZXRbZixoXT1hd2FpdCB5bihuLHQpO2lmKGghPT0wJiZ0Py5oaW50cyE9PXZvaWQgMClbZixoXT1hd2FpdCB5bihuLHtycElkOnQucnBJZCxycE5hbWU6dC5ycE5hbWV9KTtpZihoIT09MClyZXR1cm4gYyhoKTtpZihmPT09dm9pZCAwKXJldHVybiBjKDI3KTtpPW5ldyBVaW50OEFycmF5KGYucmF3SWQpfWxldFtvLGFdPWF3YWl0IHluKG4sdCxpLHtsYXJnZUJsb2I6e3JlYWQ6ITB9fSk7aWYoYSE9PTApcmV0dXJuIGMoYSk7aWYobz09PXZvaWQgMClyZXR1cm4gYygyNyk7bGV0IHU9by5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iO2lmKHU9PT12b2lkIDB8fHUuYmxvYj09PXZvaWQgMClyZXR1cm4gYyg3KTtsZXQgbD1zcih1LmJsb2IpO2lmKGwuYnl0ZUxlbmd0aD09PTApcmV0dXJuIGMoNyk7cmV0dXJuIHAoe2Jsb2I6bCxjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoby5yYXdJZCl9KX12YXIgbW49bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCJkaXBsb21hdGljLnByZi52MSIpLGR0PSJkaXBsb21hdGljLXByZiI7dmFyIGRyPSIiO3ZhciBscj10eXBlb2YgZ2xvYmFsVGhpcy5Xb3JrZXI9PT0iZnVuY3Rpb24iP2dsb2JhbFRoaXMuV29ya2VyOnZvaWQgMCxnbj1scj09PXZvaWQgMD92b2lkIDA6bHIucHJvdG90eXBlLnBvc3RNZXNzYWdlLHVyO2Z1bmN0aW9uIHRhKCl7aWYodHlwZW9mIGRyIT09InN0cmluZyJ8fGRyLmxlbmd0aD09PTApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSB3b3JrZXIgc291cmNlIG5vdCBlbWJlZGRlZDsgcnVuIHBrZyBidWlsZCBiZWZvcmUgc3Bhd24iKTtyZXR1cm4gYXRvYihkcil9ZnVuY3Rpb24gcmEoKXtpZih1ciE9PXZvaWQgMClyZXR1cm4gdXI7bGV0IGU9bmV3IEJsb2IoW3RhKCldLHt0eXBlOiJ0ZXh0L2phdmFzY3JpcHQifSk7cmV0dXJuIHVyPVVSTC5jcmVhdGVPYmplY3RVUkwoZSksdXJ9ZnVuY3Rpb24gcmkoKXtpZihscj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBzcGF3biBzeW5jIHdvcmtlciIpO3JldHVybiBuZXcgbHIocmEoKSx7dHlwZToibW9kdWxlIn0pfWZ1bmN0aW9uIG5pKGUsdCxyKXtpZihnbj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBwb3N0IHRvIHN5bmMgd29ya2VyIik7aWYociE9PXZvaWQgMCYmci5sZW5ndGg+MClnbi5jYWxsKGUsdCx7dHJhbnNmZXI6cn0pO2Vsc2UgZ24uY2FsbChlLHQpfXZhciBuYT1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMuYmluZC52MSIpLGJuPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5iaW5kdGFnLnYxIiksc2E9MzIsaWE9MzIsb2E9MTYsY2U9bmV3IFZlO2Z1bmN0aW9uIGFhKGUpe3JldHVybiBlLm1hcCgodCk9Pih7aGFuZGxlOnQuaGFuZGxlLGxhYmVsOnQubGFiZWwsaWR4OnQuaWR4Pz8wfSkpfWZ1bmN0aW9uIHNpKGUpe2lmKGUuYnl0ZUxlbmd0aD09PTB8fGUuZXZlcnkoKGEpPT5hPT09MCkpcmV0dXJuIGMoMjIpO2lmKGUuYnl0ZUxlbmd0aDx5ZSsxKXJldHVybiBjKDE0KTtsZXQgdD1lLnN1YmFycmF5KDAseWUpO2lmKHQuZXZlcnkoKGEpPT5hPT09MCkpcmV0dXJuIGMoMjIpO2xldCByPW5ldyBMKGUuc3ViYXJyYXkoeWUpKSxbbixzXT1yLnJlYWRTdHJ1Y3QodW4pO2lmKHMhPT0wKXJldHVybiBjKHMpO2lmKG49PT12b2lkIDApcmV0dXJuIGMoMTQpO2lmKCFyLmRvbmUoKSlyZXR1cm4gYygxNCk7bGV0W2ksb109YWUuZnJvbUJ5dGVzKHQpO2lmKG8hPT0wKXJldHVybiBjKG8pO2lmKGk9PT12b2lkIDApcmV0dXJuIGMoMTIpO3JldHVybiBwKHtlbmNsYXZlOmksaG9zdHM6bi5ob3N0cy5tYXAoKGEpPT4oey4uLmF9KSl9KX1hc3luYyBmdW5jdGlvbiBpaShlLHQscil7bGV0IG49cWUoKTtpZihuIT09MClyZXR1cm4gbjtsZXRbcyxpXT1OZShyKTtpZihpIT09MClyZXR1cm4gaTtpZihzPT09dm9pZCAwKXJldHVybiA5O2F3YWl0IG9yKCk7bGV0IG89bmV3IFVpbnQ4QXJyYXkodC5ieXRlTGVuZ3RoKTtvLnNldCh0KTtsZXQgYT17bGFyZ2VCbG9iOnt3cml0ZTpvLmJ1ZmZlcn19LGQ9e3B1YmxpY0tleTp7Y2hhbGxlbmdlOlVlKF9lKSxycElkOnMsYWxsb3dDcmVkZW50aWFsczpbe3R5cGU6YmUsaWQ6Q2UoZSl9XSx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczphLC4uLnI/LmhpbnRzIT09dm9pZCAwP3toaW50czpyLmhpbnRzfTp7fX19LHU7dHJ5e3RyeXt1PWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoZCl9Y2F0Y2goeSl7aWYoIWlyKHkpKXRocm93IHk7Y3QoKSx1PWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoZCl9fWNhdGNoKHkpe3JldHVybiBUZSh5KSwzMH1maW5hbGx5e28uZmlsbCgwKX1sZXRbbCxmXT1GZSh1KTtpZihmIT09MClyZXR1cm4gZjtpZihsPT09dm9pZCAwKXJldHVybiAyNztpZihsLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LndyaXR0ZW4hPT0hMClyZXR1cm4gMzA7cmV0dXJuIDB9dmFyIFNuPTMyO2Z1bmN0aW9uIGNhKGUpe2lmKGU9PT12b2lkIDApcmV0dXJuW107aWYoZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuW2VdO3JldHVybiBlLmZpbHRlcigodCk9PnQuYnl0ZUxlbmd0aD4wKX1mdW5jdGlvbiBkYShlKXtpZighKGUgaW5zdGFuY2VvZiBFcnJvcikpcmV0dXJuITE7cmV0dXJuIGUubmFtZT09PSJOb3RTdXBwb3J0ZWRFcnJvciJ8fGUubmFtZT09PSJUeXBlRXJyb3IifWZ1bmN0aW9uIGNpKGUpe2lmKGU9PT12b2lkIDApcmV0dXJuO2xldCB0PXNyKGUpO2lmKHQuYnl0ZUxlbmd0aDxTbil7dC5maWxsKDApO3JldHVybn1pZih0LmJ5dGVMZW5ndGg9PT1TbilyZXR1cm4gdDtsZXQgcj10LnNsaWNlKDAsU24pO3JldHVybiB0LmZpbGwoMCkscn1hc3luYyBmdW5jdGlvbiB1YShlKXtsZXQgdD1xZSgpO2lmKHQhPT0wKXJldHVybiBjKHQpO2xldFtyLG5dPU5lKGUpO2lmKG4hPT0wKXJldHVybiBjKG4pO2lmKHI9PT12b2lkIDApcmV0dXJuIGMoOSk7bGV0IHM9ZT8udXNlck5hbWU/P2R0LGk9ZT8uZGlzcGxheU5hbWU/P3Msbz1VZSgxNiksYT1lPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudD09PSJjcm9zcy1wbGF0Zm9ybSIsZD17cmVzaWRlbnRLZXk6YT8iZGlzY291cmFnZWQiOiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiFhLHVzZXJWZXJpZmljYXRpb246YT8icHJlZmVycmVkIjoicmVxdWlyZWQifTtpZihlPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClkLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PWUuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IHU9e2NoYWxsZW5nZTpVZShfZSkscnA6e2lkOnIsbmFtZTplPy5ycE5hbWU/P3JyfSx1c2VyOntpZDpvLG5hbWU6cyxkaXNwbGF5TmFtZTppfSxwdWJLZXlDcmVkUGFyYW1zOm5yLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246ZCwuLi5lPy5oaW50cyE9PXZvaWQgMD97aGludHM6ZS5oaW50c306e30sLi4uZT8uZXhjbHVkZUNyZWRlbnRpYWxzIT09dm9pZCAwJiZlLmV4Y2x1ZGVDcmVkZW50aWFscy5sZW5ndGg+MD97ZXhjbHVkZUNyZWRlbnRpYWxzOmUuZXhjbHVkZUNyZWRlbnRpYWxzLm1hcCgodyk9Pih7dHlwZTpiZSxpZDpDZSh3KX0pKX06e319LGw9ZT8uc2FsdCE9PXZvaWQgMD9DZShlLnNhbHQpOnZvaWQgMCxmPSh3KT0+YXIoe3B1YmxpY0tleTp7Li4udSxleHRlbnNpb25zOncmJmwhPT12b2lkIDA/e3ByZjp7ZXZhbDp7Zmlyc3Q6bH19fTp7cHJmOnt9fX19KSxoO3RyeXtoPWF3YWl0IGYobCE9PXZvaWQgMCl9Y2F0Y2godyl7aWYobD09PXZvaWQgMHx8IWRhKHcpKXJldHVybiBUZSh3KSxjKDMwKTt0cnl7aD1hd2FpdCBmKCExKX1jYXRjaChFKXtyZXR1cm4gVGUoRSksYygzMCl9fWxldFt5LG1dPUZlKGgpO2lmKG0hPT0wKXJldHVybiBjKG0pO2lmKHk9PT12b2lkIDApcmV0dXJuIGMoMjcpO2xldCBnPXkuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLGI9Y2koZy5wcmY/LnJlc3VsdHM/LmZpcnN0KSxJPWcucHJmPy5lbmFibGVkPT09ITB8fGIhPT12b2lkIDA7aWYoYSYmYiE9PXZvaWQgMCliLmZpbGwoMCk7cmV0dXJuIHAoe2NyZWRJZDpuZXcgVWludDhBcnJheSh5LnJhd0lkKSx1c2VySWQ6bmV3IFVpbnQ4QXJyYXkobykscHJmRW5hYmxlZDpJLHByZjphP3ZvaWQgMDpiLGF0dGFjaG1lbnQ6cG4oeS5hdXRoZW50aWNhdG9yQXR0YWNobWVudCksdHJhbnNwb3J0czpobih5KSxhYWd1aWQ6WnMoeSl9KX1hc3luYyBmdW5jdGlvbiBvaShlKXtsZXQgdD1xZSgpO2lmKHQhPT0wKXJldHVybiBjKHQpO2xldFtyLG5dPU5lKGUpO2lmKG4hPT0wKXJldHVybiBjKG4pO2lmKHI9PT12b2lkIDApcmV0dXJuIGMoOSk7bGV0IHM9ZT8uc2FsdD8/bW4saT1DZShzKSxvPXtjaGFsbGVuZ2U6VWUoX2UpLHJwSWQ6cix1c2VyVmVyaWZpY2F0aW9uOiJwcmVmZXJyZWQiLGV4dGVuc2lvbnM6e3ByZjp7ZXZhbDp7Zmlyc3Q6aX19fX07aWYoZT8uaGludHMhPT12b2lkIDApby5oaW50cz1lLmhpbnRzO2xldCBhPWNhKGU/LmNyZWRJZCk7aWYoYS5sZW5ndGg+MClvLmFsbG93Q3JlZGVudGlhbHM9YS5tYXAoKHkpPT4oe3R5cGU6YmUsaWQ6Q2UoeSl9KSk7bGV0IGQ7dHJ5e2Q9YXdhaXQgY3Ioe3B1YmxpY0tleTpvfSl9Y2F0Y2goeSl7cmV0dXJuIFRlKHkpLGMoMzApfWxldFt1LGxdPUZlKGQpO2lmKGwhPT0wKXJldHVybiBjKGwpO2lmKHU9PT12b2lkIDApcmV0dXJuIGMoMjcpO2xldCBmPXUuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLnByZj8ucmVzdWx0cztpZihmPy5maXJzdD09PXZvaWQgMClyZXR1cm4gYyg3KTtsZXQgaD1jaShmLmZpcnN0KTtpZihoPT09dm9pZCAwKXJldHVybiBjKDI3KTtyZXR1cm4gcCh7cHJmOmgsY3JlZElkOm5ldyBVaW50OEFycmF5KHUucmF3SWQpLGF0dGFjaG1lbnQ6cG4odS5hdXRoZW50aWNhdG9yQXR0YWNobWVudCksdHJhbnNwb3J0czpobih1KX0pfWNsYXNzIGFleyNlO2NvbnN0cnVjdG9yKGUpe3RoaXMuI2U9ZX1zdGF0aWMgYXN5bmMgZnJvbVJhbmRvbSgpe2xldCBlPWF3YWl0IGNlLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxbdCxyXT1tdChlKTtpZihyIT09MHx8dD09PXZvaWQgMCl0aHJvdyBFcnJvcihgZW5jbGF2ZTogaW52YWxpZCByYW5kb20gc2VlZCAoJHtyfSlgKTtyZXR1cm4gbmV3IGFlKHQpfXN0YXRpYyBmcm9tQnl0ZXMoZSl7bGV0W3Qscl09bXQoZSk7aWYociE9PTApcmV0dXJuIGMocik7aWYodD09PXZvaWQgMClyZXR1cm4gYygxMCk7bGV0W24sc109bXQodC5zbGljZSgpKTtpZihzIT09MClyZXR1cm4gYyhzKTtpZihuPT09dm9pZCAwKXJldHVybiBjKDEwKTtyZXR1cm4gcChuZXcgYWUobikpfWFzeW5jIHNlYWxXaXRoUGFzc2tleShlKXtsZXQgdD1lPy5zYWx0Pz9tbixyPWU/LmNyZWRJZCxuPXIscz1lPy5jcmVhdGVDcmVkSWZOZWVkZWQ9PT0hMCYmKHI9PT12b2lkIDB8fCEociBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpJiZyLmxlbmd0aD09PTApLGksbztpZihzKXtsZXRbbCxmXT1hd2FpdCB1YSh7cnBJZDplPy5ycElkLHJwTmFtZTplPy5ycE5hbWUsdXNlck5hbWU6ZT8udXNlck5hbWU/P2R0LGRpc3BsYXlOYW1lOmU/LmRpc3BsYXlOYW1lLGF1dGhlbnRpY2F0b3JBdHRhY2htZW50OmU/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50LGhpbnRzOmU/LmhpbnRzLGV4Y2x1ZGVDcmVkZW50aWFsczplPy5leGNsdWRlQ3JlZGVudGlhbHMsc2FsdDp0fSk7aWYoZiE9PTApcmV0dXJuIGMoZik7aWYobD09PXZvaWQgMClyZXR1cm4gYygzMCk7aWYoIWwucHJmRW5hYmxlZClyZXR1cm4gYygzMCk7bj1sLmNyZWRJZCxpPWwsbz1sLnByZn1sZXQgYT1hc3luYyhsLGYsaCx5KT0+e3RyeXtsZXRbbSxnXT1hd2FpdCB0aGlzLiNyKGwpO2lmKGchPT0wKXJldHVybiBjKGcpO2lmKG09PT12b2lkIDApcmV0dXJuIGMoMTIpO3JldHVybiBwKHtzZWFsZWRNYXN0ZXI6bSxzYWx0OnQuc2xpY2UoKSxjcmVkSWQ6Zi5zbGljZSgpLHVzZXJJZDppPy51c2VySWQ9PT12b2lkIDA/dm9pZCAwOmkudXNlcklkLnNsaWNlKCksYXR0YWNobWVudDpoPz9pPy5hdHRhY2htZW50LHRyYW5zcG9ydHM6eT8/aT8udHJhbnNwb3J0cyxhYWd1aWQ6aT8uYWFndWlkPT09dm9pZCAwP3ZvaWQgMDppLmFhZ3VpZC5zbGljZSgpfSl9ZmluYWxseXtsLmZpbGwoMCl9fTtpZihvIT09dm9pZCAwJiZpIT09dm9pZCAwKXJldHVybiBhKG8saS5jcmVkSWQsaS5hdHRhY2htZW50LGkudHJhbnNwb3J0cyk7bGV0W2QsdV09YXdhaXQgb2koe3JwSWQ6ZT8ucnBJZCxycE5hbWU6ZT8ucnBOYW1lLGNyZWRJZDpuLHNhbHQ6dCxoaW50czplPy5oaW50c30pO2lmKHUhPT0wKXJldHVybiBjKHUpO2lmKGQ9PT12b2lkIDApcmV0dXJuIGMoNyk7cmV0dXJuIGEoZC5wcmYsZC5jcmVkSWQsZC5hdHRhY2htZW50LGQudHJhbnNwb3J0cyl9YXN5bmMgYmluZChlLHQpe2lmKHQhPT12b2lkIDApe2ZvcihsZXQgaSBvZiB0KWlmKCFhd2FpdCB0aGlzLiNuKGkuY3JlZElkLGkudGFnKSlyZXR1cm4gYygxMCl9bGV0W3Isbl09YXdhaXQgdGhpcy5zZWFsV2l0aFBhc3NrZXkoZSk7aWYobiE9PTApcmV0dXJuIGMobik7aWYocj09PXZvaWQgMClyZXR1cm4gYygxMik7bGV0IHM9YXdhaXQgdGhpcy4jdChyLmNyZWRJZCk7cmV0dXJuIHAoey4uLnIsdGFnOnN9KX1zdGF0aWMgYXN5bmMgdW5zZWFsV2l0aFBhc3NrZXkoZSx0KXtpZihlLmxlbmd0aD09PTApcmV0dXJuIGMoMjIpO2xldCByPVtdO2ZvcihsZXQgYSBvZiBlKWlmKGEuY3JlZElkLmJ5dGVMZW5ndGg+MClyLnB1c2goYS5jcmVkSWQpO2xldFtuLHNdPWF3YWl0IG9pKHtycElkOnQucnBJZCxycE5hbWU6dC5ycE5hbWUsaGludHM6dC5oaW50cyxjcmVkSWQ6ci5sZW5ndGg+MD9yOnZvaWQgMCxzYWx0OnQuc2FsdH0pO2lmKHMhPT0wKXJldHVybiBjKHMpO2lmKG49PT12b2lkIDApcmV0dXJuIGMoNyk7bGV0IGk9ZS5maW5kKChhKT0+WChhLmNyZWRJZCxuLmNyZWRJZCkpLG89aT09PXZvaWQgMD9lOltpLC4uLmUuZmlsdGVyKChhKT0+YSE9PWkpXTt0cnl7Zm9yKGxldCBhIG9mIG8pe2xldFtkXT1hd2FpdCBhZS4jaShhLnNlYWxlZE1hc3RlcixuLnByZik7aWYoZCE9PXZvaWQgMClyZXR1cm4gcCh7ZW5jbGF2ZTpkLGNyZWRJZDpuLmNyZWRJZC5zbGljZSgpfSl9cmV0dXJuIGMoMjApfWZpbmFsbHl7bi5wcmYuZmlsbCgwKX19YXN5bmMgcGVyc2lzdFRvTGFyZ2VCbG9iKGU9W10sdCl7bGV0IHI9dD8uY3JlZElkO2lmKHI9PT12b2lkIDApe2xldFtpLG9dPWF3YWl0IGVpKHQpO2lmKG8hPT0wKXJldHVybiBjKG8pO2lmKGk9PT12b2lkIDApcmV0dXJuIGMoMzApO3I9aX1sZXRbbixzXT10aGlzLiNzKGUpO2lmKHMhPT0wKXJldHVybiBjKHMpO2lmKG49PT12b2lkIDApcmV0dXJuIGMoMTIpO3RyeXtsZXQgaT1hd2FpdCBpaShyLG4sdCk7aWYoaSE9PTApcmV0dXJuIGMoaSk7cmV0dXJuIHAocil9ZmluYWxseXtuLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBmcm9tTGFyZ2VCbG9iKGUpe2xldFt0LHJdPWF3YWl0IHRpKGU/LmNyZWRJZCxlKTtpZihyIT09MClyZXR1cm4gYyhyKTtpZih0PT09dm9pZCAwKXJldHVybiBjKDcpO3RyeXtsZXRbbixzXT1zaSh0LmJsb2IpO2lmKHMhPT0wKXJldHVybiBjKHMpO2lmKG49PT12b2lkIDApcmV0dXJuIGMoMTIpO3JldHVybiBwKHsuLi5uLGNyZWRJZDp0LmNyZWRJZH0pfWZpbmFsbHl7dC5ibG9iLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBjbGVhckxhcmdlQmxvYihlLHQpe3JldHVybiBpaShlLG5ldyBVaW50OEFycmF5KHllKSx0KX1zdGF0aWMgZnJvbVBhaXJQbGFpbihlKXtyZXR1cm4gc2koZSl9c3RhdGljIHBhaXJSZXF1ZXN0KCl7cmV0dXJuIHRyLmNyZWF0ZSgpfWFzeW5jIHBhaXJBY2NlcHQoZSx0KXtsZXQgcjt0cnl7cj1hd2FpdCBjZS5nZW5YMjU1MTkoKX1jYXRjaHtyZXR1cm4gYygyOSl9dHJ5e2xldFtuLHNdPWF3YWl0IGxuKHIucHJpdixlLGUsci5wdWIpO2lmKHMhPT0wKXJldHVybiBjKHMpO2lmKG49PT12b2lkIDApcmV0dXJuIGMoMTIpO3RyeXtsZXRbaSxvXT10aGlzLiNzKHQpO2lmKG8hPT0wKXJldHVybiBjKG8pO2lmKGk9PT12b2lkIDApcmV0dXJuIGMoMTIpO3RyeXtsZXQgYT1hd2FpdCBjZS5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKGksbik7cmV0dXJuIEdzKHdlKHIucHViLGEpKX1jYXRjaHtyZXR1cm4gYygxMil9ZmluYWxseXtpLmZpbGwoMCl9fWZpbmFsbHl7bi5maWxsKDApfX1maW5hbGx5e3IucHJpdi5maWxsKDApfX1zcGF3blN5bmNXb3JrZXIoZSl7bGV0IHQ9cmkoKSxyPXRoaXMuI2Uuc2xpY2UoKTtyZXR1cm4gbmkodCx7aWQ6ZS5pZCxvcDoic2V0U2VlZCIsc2VlZDpyLHBlcnNpc3Q6ZS5wZXJzaXN0fSxbci5idWZmZXJdKSx0fWRlcml2ZUNpcGhlcihlLHQpe2xldCByPWUuc2xpY2UoKSxuPShvKT0+dGhpcy4jYyhyLG8pLHM9KG8pPT50aGlzLiNkKHIsbyk7cmV0dXJue2VuY3J5cHQ6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpufSksZGVjcnlwdDpPYmplY3QuZnJlZXplKHtkZWNyeXB0OnN9KSxib3RoOk9iamVjdC5mcmVlemUoe2VuY3J5cHQ6bixkZWNyeXB0OnN9KX1bdF19YXN5bmMgZGVyaXZlSWRlbnRpdHkoZSx0PTApe2xldCByPWUsbj10LHM9YXdhaXQgdGhpcy4jYShyLG4pLGk9cy5wdWJsaWNLZXk7cmV0dXJuIHMucHJpdmF0ZUtleS5maWxsKDApLE9iamVjdC5mcmVlemUoe3B1YmxpY0tleTppLHNpZ246KG8pPT50aGlzLiNsKHIsbixvKSxrZG1Gb3I6KG8pPT50aGlzLiNmKHIsbixvKX0pfWFzeW5jI3QoZSl7bGV0IHQ9bmV3IFVpbnQ4QXJyYXkodGhpcy4jZS5ieXRlTGVuZ3RoK2JuLmJ5dGVMZW5ndGgrZS5ieXRlTGVuZ3RoKTt0LnNldCh0aGlzLiNlLDApLHQuc2V0KGJuLHRoaXMuI2UuYnl0ZUxlbmd0aCksdC5zZXQoZSx0aGlzLiNlLmJ5dGVMZW5ndGgrYm4uYnl0ZUxlbmd0aCk7dHJ5e3JldHVybiBhd2FpdCBjZS5ibGFrZTModCl9ZmluYWxseXt0LmZpbGwoMCl9fWFzeW5jI24oZSx0KXtpZih0LmJ5dGVMZW5ndGghPT1zYSlyZXR1cm4hMTtsZXQgcj1hd2FpdCB0aGlzLiN0KGUpO3RyeXtpZihyLmJ5dGVMZW5ndGghPT10LmJ5dGVMZW5ndGgpcmV0dXJuITE7bGV0IG49MDtmb3IobGV0IHM9MDtzPHIuYnl0ZUxlbmd0aDtzKyspe2xldCBpPXJbc10sbz10W3NdO2lmKGk9PT12b2lkIDB8fG89PT12b2lkIDApcmV0dXJuITE7bnw9aV5vfXJldHVybiBuPT09MH1maW5hbGx5e3IuZmlsbCgwKX19YXN5bmMjcihlKXtsZXRbdCxyXT1hd2FpdCBhaShjZSxlKTtpZihyIT09MClyZXR1cm4gYyhyKTtpZih0PT09dm9pZCAwKXJldHVybiBjKDEyKTt0cnl7bGV0IG49YXdhaXQgY2UuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0aGlzLiNlLHQpO3JldHVybiBMZShuKX1jYXRjaHtyZXR1cm4gYygxMil9ZmluYWxseXt0LmZpbGwoMCl9fXN0YXRpYyBhc3luYyNpKGUsdCl7bGV0WyxyXT1MZShlKTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXRbbixzXT1hd2FpdCBhaShjZSx0KTtpZihzIT09MClyZXR1cm4gYyhzKTtpZihuPT09dm9pZCAwKXJldHVybiBjKDEyKTtsZXQgaTt0cnl7dHJ5e2k9YXdhaXQgY2UuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChlLG4pfWNhdGNoe3JldHVybiBjKDIwKX1yZXR1cm4gYWUuZnJvbUJ5dGVzKGkpfWZpbmFsbHl7bi5maWxsKDApLGk/LmZpbGwoMCl9fSNzKGUpe2xldCB0PW5ldyBPLHI9dC53cml0ZVN0cnVjdCh1bix7aG9zdHM6YWEoZSl9KTtpZihyIT09MClyZXR1cm4gYyhyKTtsZXQgbj10LnJlc3VsdCgpLHM9bmV3IFVpbnQ4QXJyYXkoeWUrbi5ieXRlTGVuZ3RoKTtyZXR1cm4gcy5zZXQodGhpcy4jZSwwKSxzLnNldChuLHllKSxwKHMpfWFzeW5jI2MoZSx0KXtsZXQgcj1hd2FpdCB0aGlzLiNvKGUpO3RyeXtyZXR1cm4gYXdhaXQgY2UuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0LHIpfWZpbmFsbHl7ci5maWxsKDApfX1hc3luYyNkKGUsdCl7bGV0IHI9YXdhaXQgdGhpcy4jbyhlKTt0cnl7cmV0dXJuIGF3YWl0IGNlLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQodCxyKX1maW5hbGx5e3IuZmlsbCgwKX19YXN5bmMjbyhlKXtsZXQgdD1uZXcgVWludDhBcnJheSh0aGlzLiNlLmJ5dGVMZW5ndGgrZS5ieXRlTGVuZ3RoKTt0LnNldCh0aGlzLiNlLDApLHQuc2V0KGUsdGhpcy4jZS5ieXRlTGVuZ3RoKTt0cnl7cmV0dXJuIGF3YWl0IGNlLmJsYWtlMyh0KX1maW5hbGx5e3QuZmlsbCgwKX19YXN5bmMjdShlLHQpe2xldCByPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShlKSxuPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcobi5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludCh0KSwhMSksYXdhaXQgdGhpcy4jbyh3ZShyLG4pKX1hc3luYyNhKGUsdCl7bGV0IHI9YXdhaXQgdGhpcy4jdShlLHQpO3RyeXtyZXR1cm4gYXdhaXQgY2UuZGVyaXZlRWQyNTUxOUtleVBhaXIocil9ZmluYWxseXtyLmZpbGwoMCl9fWFzeW5jI2woZSx0LHIpe2xldCBuPWF3YWl0IHRoaXMuI2EoZSx0KTt0cnl7cmV0dXJuIGF3YWl0IGNlLnNpZ25FZDI1NTE5KHIsbi5wcml2YXRlS2V5KX1maW5hbGx5e24ucHJpdmF0ZUtleS5maWxsKDApfX1hc3luYyNmKGUsdCxyKXtsZXQgbj1hd2FpdCB0aGlzLiNhKGUsdCkscz13ZShuLnByaXZhdGVLZXkscik7bi5wcml2YXRlS2V5LmZpbGwoMCk7dHJ5e3JldHVybihhd2FpdCBjZS5ibGFrZTMocykpLnNsaWNlKDAsdmUpfWZpbmFsbHl7cy5maWxsKDApfX19YXN5bmMgZnVuY3Rpb24gYWkoZSx0LHI9bmEpe2lmKHQuYnl0ZUxlbmd0aDxvYSlyZXR1cm4gYygxMCk7bGV0IG49YXdhaXQgZS5ibGFrZTMod2UodCxyKSk7cmV0dXJuIHAobi5zbGljZSgwLGlhKSl9dmFyIGxhPW5ldyBTZXQoWyJjb25zdHJ1Y3RvciIsInByb3RvdHlwZSIsImxlbmd0aCIsIm5hbWUiXSk7ZnVuY3Rpb24gZGkoZSl7Zm9yKGxldCB0IG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGUpKXtpZihsYS5oYXModCkpY29udGludWU7bGV0IHI9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLHQpO2lmKHI9PT12b2lkIDB8fHR5cGVvZiByLnZhbHVlIT09ImZ1bmN0aW9uIiljb250aW51ZTtPYmplY3QuZGVmaW5lUHJvcGVydHkoZSx0LHt2YWx1ZTpyLnZhbHVlLHdyaXRhYmxlOiExLGNvbmZpZ3VyYWJsZTohMX0pfX1kaShhZSk7ZGkoYWUucHJvdG90eXBlKTtjbGFzcyB3bntkYjtjb25zdHJ1Y3RvcihlKXt0aGlzLmRiPWV9YXN5bmMgZW5xKGUpe2xldCB0PVsuLi5lXTtpZih0Lmxlbmd0aD09PTApcmV0dXJuO2xldCByPXRoaXMuZGIudHJhbnNhY3Rpb24odWUsInJlYWR3cml0ZSIpLG49ci5vYmplY3RTdG9yZSh1ZSk7cmV0dXJuIG5ldyBQcm9taXNlKChzLGkpPT57ci5vbmNvbXBsZXRlPSgpPT5zKCksci5vbmVycm9yPSgpPT5pKHIuZXJyb3IpO2ZvcihsZXQgbyBvZiB0KXtsZXQgYT1gJHtvLmhvc3R9OiR7by5zZXF9YDtuLnB1dChvLGEpfX0pfWFzeW5jIGRlcShlLHQpe2xldCByPVsuLi50XTtpZihyLmxlbmd0aD09PTApcmV0dXJuO2xldCBuPXRoaXMuZGIudHJhbnNhY3Rpb24odWUsInJlYWR3cml0ZSIpLHM9bi5vYmplY3RTdG9yZSh1ZSk7cmV0dXJuIG5ldyBQcm9taXNlKChpLG8pPT57bi5vbmNvbXBsZXRlPSgpPT5pKCksbi5vbmVycm9yPSgpPT5vKG4uZXJyb3IpO2ZvcihsZXQgYSBvZiByKXtsZXQgZD1gJHtlfToke2F9YDtzLmRlbGV0ZShkKX19KX1hc3luYyBsaXN0KCl7bGV0IHQ9dGhpcy5kYi50cmFuc2FjdGlvbih1ZSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1ZSk7cmV0dXJuIG5ldyBQcm9taXNlKChyLG4pPT57bGV0IHM9dC5nZXRBbGwoKTtzLm9uc3VjY2Vzcz0oKT0+cihzLnJlc3VsdCkscy5vbmVycm9yPSgpPT5uKHMuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKHVlLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHVlKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntsZXQgcz10LmNvdW50KCk7cy5vbnN1Y2Nlc3M9KCk9PnIocy5yZXN1bHQpLHMub25lcnJvcj0oKT0+bihzLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgZT10aGlzLmRiLnRyYW5zYWN0aW9uKHVlLCJyZWFkd3JpdGUiKSx0PWUub2JqZWN0U3RvcmUodWUpO3JldHVybiBuZXcgUHJvbWlzZSgocixuKT0+e2Uub25jb21wbGV0ZT0oKT0+cigpLGUub25lcnJvcj0oKT0+bihlLmVycm9yKSx0LmNsZWFyKCl9KX19ZnVuY3Rpb24gdWkoZSl7cmV0dXJue2xhYmVsOmUubGFiZWwsaGFuZGxlOm5ldyBVUkwoZS5oYW5kbGUpLGlkeDplLmlkeCxsYXN0U2VxOmUubGFzdFNlcXx8MCxjbG9ja09mZnNldDplLmNsb2NrT2Zmc2V0LHN1YnNjcmlwdGlvbjplLnN1YnNjcmlwdGlvbn19ZnVuY3Rpb24gZmEoZSx0KXtsZXQgcj17Li4uZX07aWYodC5zZXRMYXN0U2VxIT09dm9pZCAwKXIubGFzdFNlcT10LnNldExhc3RTZXE7ZWxzZSBpZih0Lmxhc3RTZXEhPT12b2lkIDApe2xldCBuPXIubGFzdFNlcXx8MDtpZih0Lmxhc3RTZXE+bilyLmxhc3RTZXE9dC5sYXN0U2VxfXJldHVybiBkZWxldGUgci5udW1CYWdzLGRlbGV0ZSByLm51bUR1cGVzLHJ9Y2xhc3MgSW57ZGI7Y29uc3RydWN0b3IoZSl7dGhpcy5kYj1lfWFzeW5jIGFkZChlKXtsZXQgdD1hd2FpdCB0aGlzLmdldChlLmxhYmVsKSxyPXQhPT12b2lkIDAmJnQuaGFuZGxlLmhyZWY9PT1lLmhhbmRsZS5ocmVmJiYodC5pZHg/PzApPT09KGUuaWR4Pz8wKTtyZXR1cm4gdGhpcy5wdXQoey4uLmUsbGFzdFNlcTpyP3QubGFzdFNlcTowLGNsb2NrT2Zmc2V0OnI/dC5jbG9ja09mZnNldDp2b2lkIDAsc3Vic2NyaXB0aW9uOnI/dC5zdWJzY3JpcHRpb246dm9pZCAwfSl9YXN5bmMgcHV0KGUpe2xldCB0PXsuLi5lLGhhbmRsZTplLmhhbmRsZS50b1N0cmluZygpLGxhc3RTZXE6ZS5sYXN0U2VxPz8wfSxyPXRoaXMuZGIudHJhbnNhY3Rpb24ocmUsInJlYWR3cml0ZSIpLG49ci5vYmplY3RTdG9yZShyZSk7cmV0dXJuIG5ldyBQcm9taXNlKChzLGkpPT57ci5vbmNvbXBsZXRlPSgpPT5zKCksci5vbmVycm9yPSgpPT5pKHIuZXJyb3IpLG4ucHV0KHQpfSl9YXN5bmMgdG91Y2goZSx0KXtyZXR1cm4gdGhpcy5yZWNvcmRTdGF0cyhlLHtsYXN0U2VxOnR9KX1hc3luYyByZWNvcmRTdGF0cyhlLHQpe2xldCByPXRoaXMuZGIudHJhbnNhY3Rpb24ocmUsInJlYWR3cml0ZSIpLG49ci5vYmplY3RTdG9yZShyZSk7cmV0dXJuIG5ldyBQcm9taXNlKChzLGkpPT57ci5vbmNvbXBsZXRlPSgpPT5zKCksci5vbmVycm9yPSgpPT5pKHIuZXJyb3IpO2xldCBvPW4uZ2V0KGUpO28ub25zdWNjZXNzPSgpPT57bGV0IGE9by5yZXN1bHQ7aWYoIWEpcmV0dXJuO24ucHV0KGZhKGEsdCkpfX0pfWFzeW5jIGdldChlKXtsZXQgcj10aGlzLmRiLnRyYW5zYWN0aW9uKHJlLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHJlKTtyZXR1cm4gbmV3IFByb21pc2UoKG4scyk9PntsZXQgaT1yLmdldChlKTtpLm9uc3VjY2Vzcz0oKT0+e2xldCBvPWkucmVzdWx0O2lmKCFvKW4odm9pZCAwKTtlbHNlIG4odWkobykpfSxpLm9uZXJyb3I9KCk9PnMoaS5lcnJvcil9KX1hc3luYyBzZXQoZSx0KXtsZXQgcj1hd2FpdCB0aGlzLmdldChlKTtpZighcilyZXR1cm4gMTM7dHJ5e3JldHVybiBhd2FpdCB0aGlzLnB1dCh7Li4uciwuLi50fSksMH1jYXRjaHtyZXR1cm4gMTh9fWFzeW5jIGRlbChlKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKHJlLCJyZWFkd3JpdGUiKSxyPXQub2JqZWN0U3RvcmUocmUpO3JldHVybiBuZXcgUHJvbWlzZSgobixzKT0+e3Qub25jb21wbGV0ZT0oKT0+bigpLHQub25lcnJvcj0oKT0+cyh0LmVycm9yKSxyLmRlbGV0ZShlKX0pfWFzeW5jIGxpc3QoKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKHJlLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHJlKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntsZXQgcz10LmdldEFsbCgpO3Mub25zdWNjZXNzPSgpPT57bGV0IGk9cy5yZXN1bHQ7cihpLm1hcCh1aSkpfSxzLm9uZXJyb3I9KCk9Pm4ocy5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0IGU9dGhpcy5kYi50cmFuc2FjdGlvbihyZSwicmVhZHdyaXRlIiksdD1lLm9iamVjdFN0b3JlKHJlKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntlLm9uY29tcGxldGU9KCk9PnIoKSxlLm9uZXJyb3I9KCk9Pm4oZS5lcnJvciksdC5jbGVhcigpfSl9fWNsYXNzIHhue2NyeXB0bztkYjtjb25zdHJ1Y3RvcihlLHQpe3RoaXMuY3J5cHRvPXQ7dGhpcy5kYj1lfWFzeW5jIGFkZChlKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKFcsInJlYWR3cml0ZSIpLHI9dC5vYmplY3RTdG9yZShXKTtyZXR1cm4gbmV3IFByb21pc2UoKG4pPT57aWYoZS5sZW5ndGg9PT0wKXtuKFtdKTtyZXR1cm59bGV0IHM9QXJyYXkoZS5sZW5ndGgpLmZpbGwoMCk7dC5vbmNvbXBsZXRlPSgpPT5uKHMpLHQub25lcnJvcj0oKT0+e2ZvcihsZXQgaT0wO2k8cy5sZW5ndGg7aSsrKXNbaV09MTg7bihzKX07Zm9yKGxldCBpPTA7aTxlLmxlbmd0aDtpKyspe2xldHtrZXk6byxkYXRhOmF9PWVbaV0sZD1EKG8pLHU9ci5wdXQoYSxkKTt1Lm9uZXJyb3I9KGwpPT57bC5wcmV2ZW50RGVmYXVsdCgpLHNbaV09MTh9fX0pfWFzeW5jIGRlbChlKXtsZXQgdD1bLi4uZV07aWYodC5sZW5ndGg9PT0wKXJldHVybjtsZXQgcj10aGlzLmRiLnRyYW5zYWN0aW9uKFcsInJlYWR3cml0ZSIpLG49ci5vYmplY3RTdG9yZShXKTtyZXR1cm4gbmV3IFByb21pc2UoKHMsaSk9PntyLm9uY29tcGxldGU9KCk9PnMoKSxyLm9uZXJyb3I9KCk9Pmkoci5lcnJvcik7Zm9yKGxldCBvIG9mIHQpe2xldCBhPUQobyk7bi5kZWxldGUoYSl9fSl9YXN5bmMgZ2V0KGUpe2xldCByPXRoaXMuZGIudHJhbnNhY3Rpb24oVywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShXKTtyZXR1cm4gbmV3IFByb21pc2UoKG4scyk9PntsZXQgaT1EKGUpLG89ci5nZXQoaSk7by5vbnN1Y2Nlc3M9YXN5bmMoKT0+e2xldCBhPW8ucmVzdWx0O2lmKGEpbihhd2FpdCBXdChlLGEsdGhpcy5jcnlwdG8pKTtlbHNlIG4odm9pZCAwKX0sby5vbmVycm9yPSgpPT5zKG8uZXJyb3IpfSl9YXN5bmMgaGFzKGUpe3JldHVybiBhd2FpdCB0aGlzLmdldChlKSE9PXZvaWQgMH1hc3luYyBsaXN0KGUpe2xldCB0PWU/LmFwbGQscj1lPy5ib2R5IT09ITEscz10aGlzLmRiLnRyYW5zYWN0aW9uKFcsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoVyk7cmV0dXJuIG5ldyBQcm9taXNlKChpLG8pPT57bGV0IGE9W10sZD10PT09dm9pZCAwP3Mub3BlbkN1cnNvcigpOnMuaW5kZXgoRXQpLm9wZW5DdXJzb3IoSURCS2V5UmFuZ2Uub25seSh0KSk7ZC5vbnN1Y2Nlc3M9KHUpPT57bGV0IGw9dS50YXJnZXQucmVzdWx0O2lmKGwpe2xldCBmPXQ9PT12b2lkIDA/bC5rZXk6bC5wcmltYXJ5S2V5LGg9bC52YWx1ZTthLnB1c2goe2hhc2g6ZmUoZiksZGF0YTpofSksbC5jb250aW51ZSgpfWVsc2UgUHJvbWlzZS5hbGwoYS5tYXAoKHtoYXNoOmYsZGF0YTpofSk9Pld0KGYsaCx0aGlzLmNyeXB0byx7Ym9keTpyfSkpKS50aGVuKGkpLmNhdGNoKG8pfSxkLm9uZXJyb3I9KCk9Pm8oZC5lcnJvcil9KX1hc3luYyBjb3VudChlKXtsZXQgcj10aGlzLmRiLnRyYW5zYWN0aW9uKFcsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoVyk7cmV0dXJuIG5ldyBQcm9taXNlKChuLHMpPT57bGV0IGk9ZT09PXZvaWQgMD9yLmNvdW50KCk6ci5pbmRleChFdCkuY291bnQoSURCS2V5UmFuZ2Uub25seShlKSk7aS5vbnN1Y2Nlc3M9KCk9Pm4oaS5yZXN1bHQpLGkub25lcnJvcj0oKT0+cyhpLmVycm9yKX0pfWFzeW5jIGxpc3RLZXlzKCl7bGV0IHQ9dGhpcy5kYi50cmFuc2FjdGlvbihXLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKFcpO3JldHVybiBuZXcgUHJvbWlzZSgocixuKT0+e2xldCBzPVtdLGk9dC5vcGVuS2V5Q3Vyc29yKCk7aS5vbnN1Y2Nlc3M9KG8pPT57bGV0IGE9by50YXJnZXQucmVzdWx0O2lmKGEpcy5wdXNoKGZlKGEua2V5KSksYS5jb250aW51ZSgpO2Vsc2UgcihzKX0saS5vbmVycm9yPSgpPT5uKGkuZXJyb3IpfSl9YXN5bmMgbGFzdChlKXtsZXQgcj10aGlzLmRiLnRyYW5zYWN0aW9uKFcsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoVyk7cmV0dXJuIG5ldyBQcm9taXNlKChuLHMpPT57bGV0IGksbz1yLm9wZW5DdXJzb3IoKTtvLm9uc3VjY2Vzcz1hc3luYyhhKT0+e2xldCBkPWEudGFyZ2V0LnJlc3VsdDtpZihkKXtsZXR7a2V5OnUsdmFsdWU6bH09ZDtpZihYKGUsbC5laWQpKXtpZighaXx8KGwuY3RyPz8wKT4oaS5kYXRhLmN0cj8/MCl8fChsLmN0cj8/MCk9PT0oaS5kYXRhLmN0cj8/MCkmJihsLm9mZj8/MCk+KGkuZGF0YS5vZmY/PzApKWk9e2tleTp1LGRhdGE6bH19ZC5jb250aW51ZSgpfWVsc2UgaWYoaSl7bGV0IHU9ZmUoaS5rZXkpO24oYXdhaXQgV3QodSxpLmRhdGEsdGhpcy5jcnlwdG8pKX1lbHNlIG4odm9pZCAwKX0sby5vbmVycm9yPSgpPT5zKG8uZXJyb3IpfSl9YXN5bmMgbWFya0FwcGxpZWQoZSl7bGV0IHQ9Wy4uLmVdO2lmKHQubGVuZ3RoPT09MClyZXR1cm47bGV0IHI9dGhpcy5kYi50cmFuc2FjdGlvbihXLCJyZWFkd3JpdGUiKSxuPXIub2JqZWN0U3RvcmUoVyk7cmV0dXJuIG5ldyBQcm9taXNlKChzLGkpPT57ci5vbmNvbXBsZXRlPSgpPT5zKCksci5vbmVycm9yPSgpPT5pKHIuZXJyb3IpO2ZvcihsZXQgbyBvZiB0KXtsZXQgYT1EKG8pLGQ9bi5nZXQoYSk7ZC5vbnN1Y2Nlc3M9KCk9PntsZXQgdT1kLnJlc3VsdDtpZighdSlyZXR1cm47TnIodSxGdCksbi5wdXQodSxhKX0sZC5vbmVycm9yPSh1KT0+e3UucHJldmVudERlZmF1bHQoKX19fSl9YXN5bmMgbWFya0ZhaWxlZChlKXtsZXQgdD1bLi4uZV07aWYodC5sZW5ndGg9PT0wKXJldHVybjtsZXQgcj10aGlzLmRiLnRyYW5zYWN0aW9uKFcsInJlYWR3cml0ZSIpLG49ci5vYmplY3RTdG9yZShXKTtyZXR1cm4gbmV3IFByb21pc2UoKHMsaSk9PntyLm9uY29tcGxldGU9KCk9PnMoKSxyLm9uZXJyb3I9KCk9Pmkoci5lcnJvcik7Zm9yKGxldHtrZXk6byxlcnI6YX1vZiB0KXtsZXQgZD1EKG8pLHU9bi5nZXQoZCk7dS5vbnN1Y2Nlc3M9KCk9PntsZXQgbD11LnJlc3VsdDtpZighbClyZXR1cm47TnIobCxudCxhKSxuLnB1dChsLGQpfSx1Lm9uZXJyb3I9KGwpPT57bC5wcmV2ZW50RGVmYXVsdCgpfX19KX1hc3luYyB3aXBlKCl7bGV0IGU9dGhpcy5kYi50cmFuc2FjdGlvbihXLCJyZWFkd3JpdGUiKSx0PWUub2JqZWN0U3RvcmUoVyk7cmV0dXJuIG5ldyBQcm9taXNlKChyLG4pPT57ZS5vbmNvbXBsZXRlPSgpPT5yKCksZS5vbmVycm9yPSgpPT5uKGUuZXJyb3IpLHQuY2xlYXIoKX0pfX12YXIgcGE9ODtjbGFzcyBFbnsjZTsjdDsjbjsjcjtjb25zdHJ1Y3RvcihlKXtpZih0aGlzLiNyPWUucGVyc2lzdEtleXJpbmcsdGhpcy4jbj17cnBJZDplLnJwSWQscnBOYW1lOmUucnBOYW1lfSxlLmtleXJpbmchPT12b2lkIDApdGhpcy4jdD1CZShlLmtleXJpbmcpfWdldCBrZXlyaW5nKCl7cmV0dXJuIHRoaXMuI3Q9PT12b2lkIDA/dm9pZCAwOkJlKHRoaXMuI3QpfWxpc3QoKXtpZih0aGlzLiN0PT09dm9pZCAwKXJldHVybltdO3JldHVybiB0aGlzLiN0LmVudHJpZXMubWFwKG1hKX1hc3luYyBzYXZlKGUsdCl7aWYodD8ucGVyc2lzdD09PSEwKXJldHVybiBQcm9taXNlLnJlamVjdChFcnJvcigicHJmLXN0b3JlOiB1c2UgYmluZEFuZFNhdmUoZW5jbGF2ZSkgdG8gcGVyc2lzdCBhIGJpbmRpbmciKSk7cmV0dXJuIHRoaXMuI2U9ZSx0aGlzLiNlfWFzeW5jIGJpbmRBbmRTYXZlKGUsdCl7bGV0IHI9dGhpcy4jdCxuPXQ/LmNyZWRJZCxzPW4gaW5zdGFuY2VvZiBVaW50OEFycmF5P24uYnl0ZUxlbmd0aD4wOm4hPT12b2lkIDAmJm4ubGVuZ3RoPjA7aWYoIXMmJnIhPT12b2lkIDAmJnIuZW50cmllcy5sZW5ndGg+PXBhKXJldHVybiBjKDI2KTtsZXQgaT1saSh0Py5uaWNrKSxvPXQ/LmV4Y2x1ZGVDcmVkZW50aWFscz8/KHM/dm9pZCAwOmdhKHIpKSxhPXQ/LnNhbHQ/P3I/LnNhbHQsZD1yPT09dm9pZCAwP3ZvaWQgMDpyLmVudHJpZXMubWFwKChtKT0+KHtjcmVkSWQ6bS5jcmVkSWQsdGFnOm0udGFnfSkpLFt1LGxdPWF3YWl0IGUuYmluZCh7Li4udGhpcy4jbixzYWx0OmEsY3JlZElkOm4sY3JlYXRlQ3JlZElmTmVlZGVkOnQ/LmNyZWF0ZUNyZWRJZk5lZWRlZD8/IXMsZXhjbHVkZUNyZWRlbnRpYWxzOm8sdXNlck5hbWU6ZHQsZGlzcGxheU5hbWU6aT8/ZHQsYXV0aGVudGljYXRvckF0dGFjaG1lbnQ6dD8uYXV0aGVudGljYXRvckF0dGFjaG1lbnQsaGludHM6dD8uaGludHN9LGQpO2lmKGwhPT0wKXJldHVybiBjKGwpO2lmKHU9PT12b2lkIDApcmV0dXJuIGMoMTIpO2xldCBmPURhdGUubm93KCksaD17dHlwZToicHJmIixzZWFsZWRNYXN0ZXI6dS5zZWFsZWRNYXN0ZXIsY3JlZElkOnUuY3JlZElkLHRhZzp1LnRhZyx1c2VySWQ6dS51c2VySWQsbmljazppLGVucm9sbGVkQXQ6ZixsYXN0VXNlZEF0OmYsYXR0YWNobWVudDp1LmF0dGFjaG1lbnQsdHJhbnNwb3J0czp1LnRyYW5zcG9ydHMsYWFndWlkOnUuYWFndWlkLGVucm9sbGVkT3M6aGEoKX0seT1yPT09dm9pZCAwP3tzYWx0OnUuc2FsdC5zbGljZSgpLGVudHJpZXM6W119OkJlKHIpO3JldHVybiB0aGlzLiN0PWJhKHksaCksdGhpcy4jZT1lLGF3YWl0IHRoaXMuI3IoQmUodGhpcy4jdCkpLHAodGhpcy4jZSl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiNlfWFzeW5jIHVubG9jaygpe2xldCBlPXRoaXMuI3Q7aWYoZT09PXZvaWQgMHx8ZS5lbnRyaWVzLmxlbmd0aD09PTApcmV0dXJuIGMoMjIpO2xldFt0LHJdPWF3YWl0IGFlLnVuc2VhbFdpdGhQYXNza2V5KGUuZW50cmllcy5tYXAoKHMpPT4oe3NlYWxlZE1hc3RlcjpzLnNlYWxlZE1hc3RlcixjcmVkSWQ6cy5jcmVkSWR9KSksey4uLnRoaXMuI24sc2FsdDplLnNhbHR9KTtpZihyIT09MClyZXR1cm4gYyhyKTt0aGlzLiNlPXQuZW5jbGF2ZTtsZXQgbj1TYShlLHQuY3JlZElkKTtpZihuIT09dm9pZCAwKXRoaXMuI3Q9bixhd2FpdCB0aGlzLiNyKEJlKG4pKTtyZXR1cm4gcCh0LmVuY2xhdmUpfWFzeW5jIHJlbmFtZShlLHQpe2xldCByPXRoaXMuI3Q7aWYocj09PXZvaWQgMClyZXR1cm4gYygyMik7bGV0IG49ci5lbnRyaWVzLmZpbmRJbmRleCgoZCk9PlgoZC5jcmVkSWQsZSkpO2lmKG48MClyZXR1cm4gYygxMyk7bGV0IHM9ci5lbnRyaWVzLm1hcChBdCksaT1zW25dO2lmKGk9PT12b2lkIDApcmV0dXJuIGMoMTMpO2xldCBvPWxpKHQpO3Nbbl09ey4uLmksbmljazpvfTtsZXQgYT17c2FsdDpyLnNhbHQuc2xpY2UoKSxlbnRyaWVzOnN9O3JldHVybiB0aGlzLiN0PWEsYXdhaXQgdGhpcy4jcihCZShhKSkscCh2b2lkIDApfWFzeW5jIHJlbW92ZShlKXtsZXQgdD10aGlzLiN0O2lmKHQ9PT12b2lkIDApcmV0dXJuIGMoMjIpO2xldCByPXQuZW50cmllcy5maWx0ZXIoKHMpPT4hWChzLmNyZWRJZCxlKSk7aWYoci5sZW5ndGg9PT10LmVudHJpZXMubGVuZ3RoKXJldHVybiBjKDEzKTtpZihyLmxlbmd0aD09PTApcmV0dXJuIHRoaXMuI3Q9dm9pZCAwLGF3YWl0IHRoaXMuI3Iodm9pZCAwKSxwKHZvaWQgMCk7bGV0IG49e3NhbHQ6dC5zYWx0LnNsaWNlKCksZW50cmllczpyLm1hcChBdCl9O3JldHVybiB0aGlzLiN0PW4sYXdhaXQgdGhpcy4jcihCZShuKSkscCh2b2lkIDApfWFzeW5jIHdpcGUoKXt0aGlzLiNlPXZvaWQgMCx0aGlzLiN0PXZvaWQgMCxhd2FpdCB0aGlzLiNyKHZvaWQgMCl9fWZ1bmN0aW9uIGxpKGUpe2lmKGU9PT12b2lkIDApcmV0dXJuO2xldCB0PWUudHJpbSgpO3JldHVybiB0PT09IiI/dm9pZCAwOnR9ZnVuY3Rpb24gaGEoKXtpZih0eXBlb2YgbmF2aWdhdG9yPiJ1IilyZXR1cm47cmV0dXJuIEpzKG5hdmlnYXRvci51c2VyQWdlbnQpfWZ1bmN0aW9uIEF0KGUpe2xldFt0LHJdPUxlKGUuc2VhbGVkTWFzdGVyLnNsaWNlKCkpO3JldHVybnt0eXBlOiJwcmYiLHNlYWxlZE1hc3RlcjpyPT09MCYmdCE9PXZvaWQgMD90OmUuc2VhbGVkTWFzdGVyLGNyZWRJZDplLmNyZWRJZC5zbGljZSgpLHRhZzplLnRhZy5zbGljZSgpLHVzZXJJZDplLnVzZXJJZD09PXZvaWQgMD92b2lkIDA6ZS51c2VySWQuc2xpY2UoKSxuaWNrOmUubmljayxlbnJvbGxlZEF0OmUuZW5yb2xsZWRBdCxsYXN0VXNlZEF0OmUubGFzdFVzZWRBdCxhdHRhY2htZW50OmUuYXR0YWNobWVudCx0cmFuc3BvcnRzOmUudHJhbnNwb3J0cz09PXZvaWQgMD92b2lkIDA6Wy4uLmUudHJhbnNwb3J0c10sYWFndWlkOmUuYWFndWlkPT09dm9pZCAwP3ZvaWQgMDplLmFhZ3VpZC5zbGljZSgpLGVucm9sbGVkT3M6ZS5lbnJvbGxlZE9zfX1mdW5jdGlvbiBCZShlKXtyZXR1cm57c2FsdDplLnNhbHQuc2xpY2UoKSxlbnRyaWVzOmUuZW50cmllcy5tYXAoQXQpfX1mdW5jdGlvbiBmaShlKXtyZXR1cm4gZSE9PW51bGwmJnR5cGVvZiBlPT09Im9iamVjdCJ9ZnVuY3Rpb24geWEoZSl7aWYoIWZpKGUpfHxlLnR5cGUhPT0icHJmIilyZXR1cm47aWYoIShlLnNlYWxlZE1hc3RlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhKGUuY3JlZElkIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCEoZS50YWcgaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8ZS50YWcuYnl0ZUxlbmd0aCE9PTMyfHx0eXBlb2YgZS5lbnJvbGxlZEF0IT09Im51bWJlciJ8fCFOdW1iZXIuaXNGaW5pdGUoZS5lbnJvbGxlZEF0KSlyZXR1cm47bGV0W3Qscl09TGUoZS5zZWFsZWRNYXN0ZXIpO2lmKHIhPT0wfHx0PT09dm9pZCAwKXJldHVybjtsZXQgbj1lLmF0dGFjaG1lbnQ9PT0icGxhdGZvcm0ifHxlLmF0dGFjaG1lbnQ9PT0iY3Jvc3MtcGxhdGZvcm0iP2UuYXR0YWNobWVudDp2b2lkIDAscz1lLmVucm9sbGVkT3MsaT1zPT09ImlvcyJ8fHM9PT0ibWFjb3MifHxzPT09ImFuZHJvaWQifHxzPT09IndpbmRvd3MifHxzPT09ImxpbnV4Inx8cz09PSJvdGhlciI/czp2b2lkIDAsbz1BcnJheS5pc0FycmF5KGUudHJhbnNwb3J0cyk/ZS50cmFuc3BvcnRzLmZpbHRlcigoYSk9PnR5cGVvZiBhPT09InN0cmluZyIpOnZvaWQgMDtyZXR1cm57dHlwZToicHJmIixzZWFsZWRNYXN0ZXI6dCxjcmVkSWQ6ZS5jcmVkSWQuc2xpY2UoKSx0YWc6ZS50YWcuc2xpY2UoKSx1c2VySWQ6ZS51c2VySWQgaW5zdGFuY2VvZiBVaW50OEFycmF5P2UudXNlcklkLnNsaWNlKCk6dm9pZCAwLG5pY2s6dHlwZW9mIGUubmljaz09PSJzdHJpbmciP2Uubmljazp2b2lkIDAsZW5yb2xsZWRBdDplLmVucm9sbGVkQXQsbGFzdFVzZWRBdDp0eXBlb2YgZS5sYXN0VXNlZEF0PT09Im51bWJlciImJk51bWJlci5pc0Zpbml0ZShlLmxhc3RVc2VkQXQpP2UubGFzdFVzZWRBdDp2b2lkIDAsYXR0YWNobWVudDpuLHRyYW5zcG9ydHM6bz09PXZvaWQgMHx8by5sZW5ndGg9PT0wP3ZvaWQgMDpvLGFhZ3VpZDplLmFhZ3VpZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk/ZS5hYWd1aWQuc2xpY2UoKTp2b2lkIDAsZW5yb2xsZWRPczppfX1mdW5jdGlvbiBwaShlKXtpZighZmkoZSkpcmV0dXJuO2lmKCEoZS5zYWx0IGluc3RhbmNlb2YgVWludDhBcnJheSl8fCFBcnJheS5pc0FycmF5KGUuZW50cmllcykpcmV0dXJuO2xldCB0PVtdO2ZvcihsZXQgciBvZiBlLmVudHJpZXMpe2xldCBuPXlhKHIpO2lmKG4hPT12b2lkIDApdC5wdXNoKG4pfWlmKHQubGVuZ3RoPT09MClyZXR1cm47cmV0dXJue3NhbHQ6ZS5zYWx0LnNsaWNlKCksZW50cmllczp0fX1mdW5jdGlvbiBtYShlKXtyZXR1cm57dHlwZToicHJmIixjcmVkSWQ6ZS5jcmVkSWQuc2xpY2UoKSx1c2VySWQ6ZS51c2VySWQ9PT12b2lkIDA/dm9pZCAwOmUudXNlcklkLnNsaWNlKCksbmljazplLm5pY2ssZW5yb2xsZWRBdDplLmVucm9sbGVkQXQsbGFzdFVzZWRBdDplLmxhc3RVc2VkQXQsYXR0YWNobWVudDplLmF0dGFjaG1lbnQsdHJhbnNwb3J0czplLnRyYW5zcG9ydHM9PT12b2lkIDA/dm9pZCAwOlsuLi5lLnRyYW5zcG9ydHNdLGFhZ3VpZDplLmFhZ3VpZD09PXZvaWQgMD92b2lkIDA6ZS5hYWd1aWQuc2xpY2UoKSxlbnJvbGxlZE9zOmUuZW5yb2xsZWRPc319ZnVuY3Rpb24gZ2EoZSl7aWYoZT09PXZvaWQgMClyZXR1cm5bXTtyZXR1cm4gZS5lbnRyaWVzLmZpbHRlcigodCk9PnQuY3JlZElkLmJ5dGVMZW5ndGg+MCkubWFwKCh0KT0+dC5jcmVkSWQuc2xpY2UoKSl9ZnVuY3Rpb24gYmEoZSx0KXtsZXQgcj1lLmVudHJpZXMubWFwKEF0KSxuPXIuZmluZEluZGV4KChzKT0+WChzLmNyZWRJZCx0LmNyZWRJZCkpO2lmKG4+PTApe2xldCBzPXJbbl07cltuXT17Li4udCxlbnJvbGxlZEF0OnM/LmVucm9sbGVkQXQ/P3QuZW5yb2xsZWRBdCxuaWNrOnQubmljaz8/cz8ubmlja319ZWxzZSByLnB1c2godCk7cmV0dXJue3NhbHQ6ZS5zYWx0LnNsaWNlKCksZW50cmllczpyfX1mdW5jdGlvbiBTYShlLHQpe2lmKHQuYnl0ZUxlbmd0aD09PTApcmV0dXJuO2xldCByPWUuZW50cmllcy5maW5kSW5kZXgoKGkpPT5YKGkuY3JlZElkLHQpKTtpZihyPDApcmV0dXJuO2xldCBuPWUuZW50cmllcy5tYXAoQXQpLHM9bltyXTtpZihzPT09dm9pZCAwKXJldHVybjtyZXR1cm4gbltyXT17Li4ucyxsYXN0VXNlZEF0OkRhdGUubm93KCl9LHtzYWx0OmUuc2FsdC5zbGljZSgpLGVudHJpZXM6bn19dmFyIG1tPWZyKCJmYmZjMzAwNzE1NGU0ZWNjOGMwYjZlMDIwNTU3ZDdiZCIpLGdtPWZyKCJlYTliOGQ2NjRkMDExZDIxM2NlNGI2YjQ4Y2I1NzVkNCIpLGJtPWZyKCIwODk4NzA1OGNhZGM0YjgxYjZlMTMwZGU1MGRjYmU5NiIpLFNtPWZyKCIyZmMwNTc5ZjgxMTM0N2VhYjExNmJiNWE4ZGI5MjAyYSIpO2Z1bmN0aW9uIGZyKGUpe2xldCB0PW5ldyBVaW50OEFycmF5KDE2KTtmb3IobGV0IHI9MDtyPDE2O3IrKyl0W3JdPU51bWJlci5wYXJzZUludChlLnNsaWNlKHIqMixyKjIrMiksMTYpO3JldHVybiB0fXZhciB3YT0iZGlwbG9tYXRpYy5waW4vIjtmdW5jdGlvbiBJYShlKXtyZXR1cm4gd2EraGUoZSl9YXN5bmMgZnVuY3Rpb24gaGkoZSx0LHIpe2xldCBuPWF3YWl0IHQuZGVyaXZlSWRlbnRpdHkoSWEociksMCk7cmV0dXJuIGUuYmxha2UzKG4ucHVibGljS2V5KX1hc3luYyBmdW5jdGlvbiB5aShlLHQpe2xldCByPWF3YWl0IGUuZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpLG49YXdhaXQgaGkoZSx0LHIpO3JldHVybntuOnIsaDpufX1hc3luYyBmdW5jdGlvbiBtaShlLHQscil7bGV0IG49YXdhaXQgaGkoZSx0LHIubik7cmV0dXJuIHhhKG4sci5oKX1mdW5jdGlvbiBnaShlKXtpZihlPT09dm9pZCAwfHxlPT09bnVsbHx8dHlwZW9mIGUhPT0ib2JqZWN0IilyZXR1cm47bGV0IHQ9ZTtpZighKHQubiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhKHQuaCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKXJldHVybjtpZih0Lm4uYnl0ZUxlbmd0aDwxfHx0LmguYnl0ZUxlbmd0aDwxKXJldHVybjtyZXR1cm57bjp0Lm4uc2xpY2UoKSxoOnQuaC5zbGljZSgpfX1mdW5jdGlvbiBiaShlKXtyZXR1cm57bjplLm4uc2xpY2UoKSxoOmUuaC5zbGljZSgpfX1mdW5jdGlvbiB4YShlLHQpe2lmKGUuYnl0ZUxlbmd0aCE9PXQuYnl0ZUxlbmd0aClyZXR1cm4hMTtsZXQgcj0wO2ZvcihsZXQgbj0wO248ZS5ieXRlTGVuZ3RoO24rKylyfD1lW25dXnRbbl07cmV0dXJuIHI9PT0wfXZhciBwcj0ia2V5cmluZyIsU2k9InByZk1ldGEiLEFuPSJpZFBpbiIsd2k9ImlkUHViIjtjbGFzcyBQbnsjZTtkYjsjdDtjb25zdHJ1Y3RvcihlLHQpe3RoaXMuZGI9ZSx0aGlzLiN0PXR9YXN5bmMgc2F2ZShlLHQpe3JldHVybiBhd2FpdCB0aGlzLiNuKGUpLHRoaXMuI2U9ZSx0aGlzLiNlfWFzeW5jIGxvYWQoKXtyZXR1cm4gdGhpcy4jZX1hc3luYyBjbGVhclNlc3Npb24oKXt0aGlzLiNlPXZvaWQgMH1hc3luYyB3aXBlKCl7dGhpcy4jZT12b2lkIDA7bGV0IGU9dGhpcy5kYi50cmFuc2FjdGlvbihuZSwicmVhZHdyaXRlIiksdD1lLm9iamVjdFN0b3JlKG5lKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntlLm9uY29tcGxldGU9KCk9PnIoKSxlLm9uZXJyb3I9KCk9Pm4oZS5lcnJvciksdC5kZWxldGUocHIpLHQuZGVsZXRlKFNpKSx0LmRlbGV0ZShBbiksdC5kZWxldGUod2kpfSl9YXN5bmMgbG9hZEtleXJpbmcoKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKG5lLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG5lKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntsZXQgcz10LmdldChwcik7cy5vbnN1Y2Nlc3M9KCk9PntyKHBpKHMucmVzdWx0KSl9LHMub25lcnJvcj0oKT0+bihzLmVycm9yKX0pfWFzeW5jIHBlcnNpc3RLZXlyaW5nKGUpe2xldCB0PXRoaXMuZGIudHJhbnNhY3Rpb24obmUsInJlYWR3cml0ZSIpLHI9dC5vYmplY3RTdG9yZShuZSk7cmV0dXJuIG5ldyBQcm9taXNlKChuLHMpPT57aWYodC5vbmNvbXBsZXRlPSgpPT5uKCksdC5vbmVycm9yPSgpPT5zKHQuZXJyb3IpLHIuZGVsZXRlKFNpKSxlPT09dm9pZCAwKXtyLmRlbGV0ZShwcik7cmV0dXJufXIucHV0KEJlKGUpLHByKX0pfWFzeW5jIGhhc0tleXJpbmcoKXtsZXQgZT1hd2FpdCB0aGlzLmxvYWRLZXlyaW5nKCk7cmV0dXJuIGUhPT12b2lkIDAmJmUuZW50cmllcy5sZW5ndGg+MH1hc3luYyBvcGVuUHJmU3RvcmUoZSl7bGV0IHQ9YXdhaXQgdGhpcy5sb2FkS2V5cmluZygpO3JldHVybiBuZXcgRW4oe3JwSWQ6ZS5ycElkLHJwTmFtZTplLnJwTmFtZSxrZXlyaW5nOnQscGVyc2lzdEtleXJpbmc6KHIpPT50aGlzLnBlcnNpc3RLZXlyaW5nKHIpfSl9YXN5bmMjbihlKXthd2FpdCB0aGlzLiNzKHdpKTtsZXQgdD1hd2FpdCB0aGlzLiNyKCk7aWYodCE9PXZvaWQgMCl7aWYoIWF3YWl0IG1pKHRoaXMuI3QsZSx0KSl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIHNlZWQgZG9lcyBub3QgbWF0Y2ggdGhpcyBkZXZpY2UncyBpZGVudGl0eSAobG9jYWwgZGF0YSB3YXMgY3JlYXRlZCB3aXRoIGEgZGlmZmVyZW50IG1hc3RlciBzZWVkKSIpO3JldHVybn1sZXQgcj1hd2FpdCB5aSh0aGlzLiN0LGUpO2F3YWl0IHRoaXMuI2kocil9I3IoKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKG5lLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG5lKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntsZXQgcz10LmdldChBbik7cy5vbnN1Y2Nlc3M9KCk9PnIoZ2kocy5yZXN1bHQpKSxzLm9uZXJyb3I9KCk9Pm4ocy5lcnJvcil9KX0jaShlKXtsZXQgdD1iaShlKSxyPXRoaXMuZGIudHJhbnNhY3Rpb24obmUsInJlYWR3cml0ZSIpLG49ci5vYmplY3RTdG9yZShuZSk7cmV0dXJuIG5ldyBQcm9taXNlKChzLGkpPT57ci5vbmNvbXBsZXRlPSgpPT5zKCksci5vbmVycm9yPSgpPT5pKHIuZXJyb3IpLG4ucHV0KHQsQW4pfSl9I3MoZSl7bGV0IHQ9dGhpcy5kYi50cmFuc2FjdGlvbihuZSwicmVhZHdyaXRlIikscj10Lm9iamVjdFN0b3JlKG5lKTtyZXR1cm4gbmV3IFByb21pc2UoKG4scyk9Pnt0Lm9uY29tcGxldGU9KCk9Pm4oKSx0Lm9uZXJyb3I9KCk9PnModC5lcnJvciksci5kZWxldGUoZSl9KX19Y2xhc3MgVW57ZGI7Y29uc3RydWN0b3IoZSl7dGhpcy5kYj1lfWFzeW5jIGVucShlLHQpe2xldCByPVsuLi50XTtpZihyLmxlbmd0aD09PTApcmV0dXJuO2xldCBuPXRoaXMuZGIudHJhbnNhY3Rpb24obGUsInJlYWR3cml0ZSIpLHM9bi5vYmplY3RTdG9yZShsZSk7cmV0dXJuIG5ldyBQcm9taXNlKChpLG8pPT57bi5vbmNvbXBsZXRlPSgpPT5pKCksbi5vbmVycm9yPSgpPT5vKG4uZXJyb3IpO2ZvcihsZXQgYSBvZiByKXtsZXQgZD1oZShhKTtzLnB1dCh7aG9zdDplLGhhc2g6ZH0pfX0pfWFzeW5jIGRlcShlLHQpe2xldCByPVsuLi50XTtpZihyLmxlbmd0aD09PTApcmV0dXJuO2xldCBuPXRoaXMuZGIudHJhbnNhY3Rpb24obGUsInJlYWR3cml0ZSIpLHM9bi5vYmplY3RTdG9yZShsZSk7cmV0dXJuIG5ldyBQcm9taXNlKChpLG8pPT57bi5vbmNvbXBsZXRlPSgpPT5pKCksbi5vbmVycm9yPSgpPT5vKG4uZXJyb3IpO2ZvcihsZXQgYSBvZiByKXtsZXQgZD1oZShhKTtzLmRlbGV0ZShbZSxkXSl9fSl9YXN5bmMgbGlzdChlKXtsZXQgcj10aGlzLmRiLnRyYW5zYWN0aW9uKGxlLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGxlKTtyZXR1cm4gbmV3IFByb21pc2UoKG4scyk9PntsZXQgaT1yLmdldEFsbCgpO2kub25zdWNjZXNzPSgpPT57bGV0IGE9aS5yZXN1bHQuZmlsdGVyKChkKT0+ZC5ob3N0PT09ZSkubWFwKChkKT0+ZC5oYXNoKTtuKGEubWFwKChkKT0+cW4oZCkpKX0saS5vbmVycm9yPSgpPT5zKGkuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgdD10aGlzLmRiLnRyYW5zYWN0aW9uKGxlLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGxlKTtyZXR1cm4gbmV3IFByb21pc2UoKHIsbik9PntsZXQgcz10LmNvdW50KCk7cy5vbnN1Y2Nlc3M9KCk9PnIocy5yZXN1bHQpLHMub25lcnJvcj0oKT0+bihzLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgZT10aGlzLmRiLnRyYW5zYWN0aW9uKGxlLCJyZWFkd3JpdGUiKSx0PWUub2JqZWN0U3RvcmUobGUpO3JldHVybiBuZXcgUHJvbWlzZSgocixuKT0+e2Uub25jb21wbGV0ZT0oKT0+cigpLGUub25lcnJvcj0oKT0+bihlLmVycm9yKSx0LmNsZWFyKCl9KX19dmFyIG5lPSJzZWVkTWV0YSIscmU9Imhvc3RzIixsZT0idXBsb2FkUXVldWUiLHVlPSJkb3dubG9hZFF1ZXVlIixXPSJtZXNzYWdlcyIsRXQ9ImFwbGQiLElpPTMseGk9ImRpcGxvbWF0aWMtc3RvcmUtZGIiO2NsYXNzIEVpe3NlZWQ7aG9zdHM7dXBsb2Fkcztkb3dubG9hZHM7bWVzc2FnZXM7ZGI7Y29uc3RydWN0b3IoZSx0KXt0aGlzLmRiPWUsdGhpcy5zZWVkPW5ldyBQbihlLHQpLHRoaXMuaG9zdHM9bmV3IEluKGUpLHRoaXMudXBsb2Fkcz1uZXcgVW4oZSksdGhpcy5kb3dubG9hZHM9bmV3IHduKGUpLHRoaXMubWVzc2FnZXM9bmV3IHhuKGUsdCl9YXN5bmMgd2lwZSgpe2F3YWl0IHRoaXMuaG9zdHMud2lwZSgpLGF3YWl0IHRoaXMudXBsb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5kb3dubG9hZHMud2lwZSgpLGF3YWl0IHRoaXMubWVzc2FnZXMud2lwZSgpfX1hc3luYyBmdW5jdGlvbiBFYSgpe3JldHVybiBuZXcgUHJvbWlzZSgoZSx0KT0+e2xldCByPWluZGV4ZWREQi5vcGVuKHhpLElpKTtyLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6bix0cmFuc2FjdGlvbjpzfT1yO2lmKCFuLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMobmUpKW4uY3JlYXRlT2JqZWN0U3RvcmUobmUpO2lmKCFuLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMocmUpKW4uY3JlYXRlT2JqZWN0U3RvcmUocmUse2tleVBhdGg6ImxhYmVsIn0pO2lmKCFuLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMobGUpKW4uY3JlYXRlT2JqZWN0U3RvcmUobGUse2tleVBhdGg6WyJob3N0IiwiaGFzaCJdfSk7aWYoIW4ub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyh1ZSkpbi5jcmVhdGVPYmplY3RTdG9yZSh1ZSk7bGV0IGk7aWYoIW4ub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhXKSlpPW4uY3JlYXRlT2JqZWN0U3RvcmUoVyk7ZWxzZXtpZighcyl0aHJvdyBFcnJvcigibWlzc2luZyB1cGdyYWRlIHRyYW5zYWN0aW9uIGZvciBtZXNzYWdlcyBzdG9yZSIpO2k9cy5vYmplY3RTdG9yZShXKX1pZighaS5pbmRleE5hbWVzLmNvbnRhaW5zKEV0KSlpLmNyZWF0ZUluZGV4KEV0LCJhcGxkIix7dW5pcXVlOiExfSl9LHIub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gcHJvdG9jb2wgc3RvcmUgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHt4aX0g4oaSIHYke0lpfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LHIub25zdWNjZXNzPSgpPT57bGV0IG49ci5yZXN1bHQ7bi5vbnZlcnNpb25jaGFuZ2U9KCk9PntuLmNsb3NlKCl9LGUobil9LHIub25lcnJvcj0oKT0+dChyLmVycm9yPz9FcnJvcigicHJvdG9jb2wgc3RvcmUgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gQWkoZSl7bGV0IHQ9YXdhaXQgRWEoKTtpZih0eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yLnN0b3JhZ2U/LnBlcnNpc3QpdHJ5e2F3YWl0IFByb21pc2UucmFjZShbbmF2aWdhdG9yLnN0b3JhZ2UucGVyc2lzdCgpLG5ldyBQcm9taXNlKChyKT0+e3NldFRpbWVvdXQoKCk9PnIoITEpLDIwMDApfSldKX1jYXRjaHt9cmV0dXJuIG5ldyBFaSh0LGUpfWNsYXNzIEJue2NsaWVudDtlbnREQjtwb3N0O3doZW5SZWFkeTtyZXNvbHZlUmVhZHk7cmVqZWN0UmVhZHk7Y29uc3RydWN0b3IoZSl7dGhpcy5wb3N0PWUsdGhpcy53aGVuUmVhZHk9bmV3IFByb21pc2UoKHQscik9Pnt0aGlzLnJlc29sdmVSZWFkeT10LHRoaXMucmVqZWN0UmVhZHk9cn0pfWFzeW5jIGluaXQoKXt0cnl7bGV0IGU9YXdhaXQgQWkoSnQpLHQ9YXdhaXQgY3Moe2NhY2hlOiExfSkscj1uZXcgS3QodC5hcHBseSwoKT0+dC5jbGVhcigpLChpKT0+e2lmKGkubGVuZ3RoPDEpcmV0dXJuO3RoaXMucG9zdCh7a2luZDoiZGlydHkiLGVpZHM6aS5tYXAoKG8pPT5vLnNsaWNlKCkpfSl9KSxuPXIuY2xlYXI7ci5jbGVhcj1hc3luYygpPT57bGV0IGk9YXdhaXQgbigpO2lmKGk9PT0wKXRoaXMucG9zdCh7a2luZDoid2lwZWQifSk7cmV0dXJuIGl9O2xldCBzPW5ldyBqcihuZXcgeHIscixlLEpuLEp0KTt0aGlzLmNsaWVudD1zLHRoaXMuZW50REI9dCxzLmNsaWVudFN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdENsaWVudFN0YXRlKCl9KSxzLnhmZXJTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRYZmVyU3RhdGUoKX0pLGF3YWl0IHRoaXMuZW1pdFhmZXJTdGF0ZSgpLHRoaXMucG9zdCh7a2luZDoicmVhZHkifSksdGhpcy5tYXJrUmVhZHkoKX1jYXRjaChlKXtsZXQgdD1lIGluc3RhbmNlb2YgRXJyb3I/ZTpFcnJvcihTdHJpbmcoZSkpO3Rocm93IHRoaXMucG9zdCh7a2luZDoiaW5pdEVycm9yIixtZXNzYWdlOnQubWVzc2FnZX0pLHRoaXMuZmFpbFJlYWR5KHQpLHR9fW1hcmtSZWFkeSgpe2xldCBlPXRoaXMucmVzb2x2ZVJlYWR5O2lmKHRoaXMucmVzb2x2ZVJlYWR5PXZvaWQgMCx0aGlzLnJlamVjdFJlYWR5PXZvaWQgMCxlKWUoKX1mYWlsUmVhZHkoZSl7bGV0IHQ9dGhpcy5yZWplY3RSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsdCl0KGUpfXJlcXVpcmVDbGllbnQoKXtpZighdGhpcy5jbGllbnQpdGhyb3cgRXJyb3IoIldvcmtlclJ1bnRpbWUgbm90IGluaXRpYWxpemVkIik7cmV0dXJuIHRoaXMuY2xpZW50fWFzeW5jIGVtaXRDbGllbnRTdGF0ZSgpe2xldCBlPXRoaXMuY2xpZW50O2lmKCFlKXJldHVybjtsZXQgdD1hd2FpdCBlLmNsaWVudFN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoiY2xpZW50U3RhdGUiLGNvbm5lY3RlZDp0LmNvbm5lY3RlZH0pfWFzeW5jIGVtaXRYZmVyU3RhdGUoKXtsZXQgZT10aGlzLmNsaWVudDtpZighZSlyZXR1cm47bGV0IHQ9YXdhaXQgZS54ZmVyU3RhdGUuZ2V0KCk7dGhpcy5wb3N0KHtraW5kOiJ4ZmVyU3RhdGUiLHN0YXRlOnR9KX1ob3N0RnJvbVNlcmlhbGl6ZWQoZSl7cmV0dXJue2hhbmRsZTpuZXcgVVJMKGUuaGFuZGxlKSxsYWJlbDplLmxhYmVsLGlkeDplLmlkeH19YXN5bmMgaGFuZGxlKGUpe2F3YWl0IHRoaXMud2hlblJlYWR5O2xldCB0PXRoaXMucmVxdWlyZUNsaWVudCgpO3N3aXRjaChlLm9wKXtjYXNlInBpbmciOnJldHVybiJwb25nIjtjYXNlInNldFNlZWQiOntsZXRbcixuXT1hZS5mcm9tQnl0ZXMoZS5zZWVkKTtpZihlLnNlZWQuZmlsbCgwKSxuIT09MHx8cj09PXZvaWQgMCl0aHJvdyBuZXcgcGUobik7YXdhaXQgdC5zZXRTZWVkKHIse3BlcnNpc3Q6ZS5wZXJzaXN0fSk7cmV0dXJufWNhc2UibGluayI6e2F3YWl0IHQubGluayh0aGlzLmhvc3RGcm9tU2VyaWFsaXplZChlLmhvc3QpLGUuY29ubmVjdD8/ITApO3JldHVybn1jYXNlInVubGluayI6e2F3YWl0IHQudW5saW5rKGUubGFiZWwpO3JldHVybn1jYXNlImNvbm5lY3QiOnthd2FpdCB0LmNvbm5lY3QoZS5saXN0ZW4/PyEwLGUuc3luYz8/ITApO3JldHVybn1jYXNlImRpc2Nvbm5lY3QiOnthd2FpdCB0LmRpc2Nvbm5lY3QoKTtyZXR1cm59Y2FzZSJzeW5jIjpyZXR1cm4gYXdhaXQgdC5zeW5jKCk7Y2FzZSJyZWJ1aWxkIjpyZXR1cm4gYXdhaXQgdC5yZWJ1aWxkKHtjaGVja0hvc3Q6ZS5jaGVja0hvc3Q/PyEwfSk7Y2FzZSJyZWNvbmNpbGUiOntsZXRbcixuXT1hd2FpdCB0LnJlY29uY2lsZShlLmhvc3RMYWJlbCx7cHVsbDplLnB1bGwscHVzaDplLnB1c2gsc3luYzplLnN5bmN9KTtpZihuIT09MCl0aHJvdyBuZXcgcGUobik7aWYoIXIpdGhyb3cgbmV3IHBlKDEyKTtyZXR1cm4gcn1jYXNlIm1zZ2NoZWNrIjpyZXR1cm4gYXdhaXQgdC5tc2djaGVjaygpO2Nhc2UiZW50Y2hlY2siOntsZXQgcj10aGlzLmVudERCO2lmKCFyKXRocm93IG5ldyBwZSgxMik7bGV0W24sc109YXdhaXQgci5jaGVja3N1bShKdCk7aWYocyE9PTApdGhyb3cgbmV3IHBlKHMpO2lmKCFuKXRocm93IG5ldyBwZSgxMik7cmV0dXJuIG59Y2FzZSJ3aXBlIjp7YXdhaXQgdC53aXBlKHttc2dzOmUubXNncyxlbnRzOmUuZW50cyxtZXRhOmUubWV0YSxzZWVkOmUuc2VlZH0pO3JldHVybn1jYXNlImltcG9ydCI6e2xldCByPWUuYnl0ZXMuc2xpY2UoKSxuPW5ldyBCbG9iKFtyXSkscz1uZXcgRmlsZShbbl0sImltcG9ydC5kaXAiKTtyZXR1cm4gYXdhaXQgdC5pbXBvcnQocyl9Y2FzZSJleHBvcnQiOntsZXRbcixuXT1hd2FpdCB0LmV4cG9ydEJ5dGVzKCk7aWYobiE9PTApdGhyb3cgbmV3IHBlKG4pO2lmKCFyKXRocm93IG5ldyBwZSgxMik7cmV0dXJuIHJ9Y2FzZSJnZXRYZmVyU3RhdGUiOnJldHVybiBhd2FpdCB0LnhmZXJTdGF0ZS5nZXQoKTtkZWZhdWx0OntsZXQgcj1lO3Rocm93IEVycm9yKCJ1bmtub3duIHdvcmtlciBjb21tYW5kIil9fX19Y2xhc3MgcGUgZXh0ZW5kcyBFcnJvcntzdGF0dXM7Y29uc3RydWN0b3IoZSl7c3VwZXIoYFdvcmtlclN0YXR1c0Vycm9yOiAke1VbZV19YCk7dGhpcy5zdGF0dXM9ZTt0aGlzLm5hbWU9IldvcmtlclN0YXR1c0Vycm9yIn19ZnVuY3Rpb24gaHIoZSx0KXtyZXR1cm57a2luZDoicmVwbHkiLGlkOmUsb2s6ITAscmVzdWx0OnR9fWZ1bmN0aW9uIGtuKGUsdCl7cmV0dXJue2tpbmQ6InJlcGx5IixpZDplLG9rOiExLHN0YXR1czp0fX12YXIgSGU9Z2xvYmFsVGhpcyxQaT1uZXcgQm4oKGUsdCk9PntpZih0JiZ0Lmxlbmd0aD4wKUhlLnBvc3RNZXNzYWdlKGUsdCk7ZWxzZSBIZS5wb3N0TWVzc2FnZShlKX0pO0hlLm9ubWVzc2FnZT0oZSk9PntsZXQgdD1lLmRhdGE7aWYoIVRuKHQpKXJldHVybjtBYSh0KX07YXN5bmMgZnVuY3Rpb24gQWEoZSl7dHJ5e2xldCB0PWF3YWl0IFBpLmhhbmRsZShlKTtpZigoZS5vcD09PSJleHBvcnQifHxlLm9wPT09Im1zZ2NoZWNrInx8ZS5vcD09PSJlbnRjaGVjayIpJiZ0IGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IHI9dC5zbGljZSgpO0hlLnBvc3RNZXNzYWdlKGhyKGUuaWQsciksW3IuYnVmZmVyXSk7cmV0dXJufWlmKGUub3A9PT0icmVjb25jaWxlIiYmdCYmdHlwZW9mIHQ9PT0ib2JqZWN0IiYmIm1zZ2NoZWNrImluIHQmJnQubXNnY2hlY2sgaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgcj10Lm1zZ2NoZWNrLnNsaWNlKCksbj17Li4udCxtc2djaGVjazpyfTtIZS5wb3N0TWVzc2FnZShocihlLmlkLG4pLFtyLmJ1ZmZlcl0pO3JldHVybn1IZS5wb3N0TWVzc2FnZShocihlLmlkLHQpKX1jYXRjaCh0KXtpZih0IGluc3RhbmNlb2YgcGUpe0hlLnBvc3RNZXNzYWdlKGtuKGUuaWQsdC5zdGF0dXMpKTtyZXR1cm59Y29uc29sZS5lcnJvcigid29ya2VyIGNvbW1hbmQgZmFpbGVkIix0KSxIZS5wb3N0TWVzc2FnZShrbihlLmlkLDEyKSl9fVBpLmluaXQoKS5jYXRjaCgoZSk9Pntjb25zb2xlLmVycm9yKCJ3b3JrZXIgaW5pdCBmYWlsZWQiLGUpfSk7Cg==";var Rs=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,vn=Rs===void 0?void 0:Rs.prototype.postMessage,xs;function Cl(){if(typeof Ks!=="string"||Ks.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(Ks)}function kl(){if(xs!==void 0)return xs;let t=new Blob([Cl()],{type:"text/javascript"});return xs=URL.createObjectURL(t),xs}function Vo(){if(Rs===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new Rs(kl(),{type:"module"})}function Wo(t,e,s){if(vn===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(s!==void 0&&s.length>0)vn.call(t,e,{transfer:s});else vn.call(t,e)}var Tl=new TextEncoder().encode("diplomatic.bind.v1"),Dn=new TextEncoder().encode("diplomatic.bindtag.v1"),Ll=32,Ml=32,Pl=16,dt=new vt;function wl(t){return t.map((e)=>({handle:e.handle,label:e.label,idx:e.idx??0}))}function go(t){if(t.byteLength===0||t.every((l)=>l===0))return c(22);if(t.byteLength<yt+1)return c(14);let e=t.subarray(0,yt);if(e.every((l)=>l===0))return c(22);let s=new M(t.subarray(yt)),[n,i]=s.readStruct(wn);if(i!==0)return c(i);if(n===void 0)return c(14);if(!s.done())return c(14);let[o,r]=et.fromBytes(e);if(r!==0)return c(r);if(o===void 0)return c(12);return m({enclave:o,hosts:n.hosts.map((l)=>({...l}))})}async function Ko(t,e,s){let n=jt();if(n!==0)return n;let[i,o]=Ot(s);if(o!==0)return o;if(i===void 0)return 9;await Is();let r=new Uint8Array(e.byteLength);r.set(e);let l={largeBlob:{write:r.buffer}},a={publicKey:{challenge:Ht(Dt),rpId:i,allowCredentials:[{type:ft,id:Bt(t)}],userVerification:"required",extensions:l,...s?.hints!==void 0?{hints:s.hints}:{}}},d;try{try{d=await navigator.credentials.get(a)}catch(y){if(!fs(y))throw y;Ge(),d=await navigator.credentials.get(a)}}catch(y){return Jt(y),30}finally{r.fill(0)}let[u,p]=At(d);if(p!==0)return p;if(u===void 0)return 27;if(u.getClientExtensionResults().largeBlob?.written!==!0)return 30;return 0}var On=32;function Ul(t){if(t===void 0)return[];if(t instanceof Uint8Array)return[t];return t.filter((e)=>e.byteLength>0)}function Bl(t){if(!(t instanceof Error))return!1;return t.name==="NotSupportedError"||t.name==="TypeError"}function Ho(t){if(t===void 0)return;let e=Gs(t);if(e.byteLength<On){e.fill(0);return}if(e.byteLength===On)return e;let s=e.slice(0,On);return e.fill(0),s}async function Jl(t){let e=jt();if(e!==0)return c(e);let[s,n]=Ot(t);if(n!==0)return c(n);if(s===void 0)return c(9);let i=t?.userName??fe,o=t?.displayName??i,r=Ht(16),l=t?.authenticatorAttachment==="cross-platform",a={residentKey:l?"discouraged":"required",requireResidentKey:!l,userVerification:l?"preferred":"required"};if(t?.authenticatorAttachment!==void 0)a.authenticatorAttachment=t.authenticatorAttachment;let d={challenge:Ht(Dt),rp:{id:s,name:t?.rpName??Zs},user:{id:r,name:i,displayName:o},pubKeyCredParams:Xs,authenticatorSelection:a,...t?.hints!==void 0?{hints:t.hints}:{},...t?.excludeCredentials!==void 0&&t.excludeCredentials.length>0?{excludeCredentials:t.excludeCredentials.map((f)=>({type:ft,id:Bt(f)}))}:{}},u=t?.salt!==void 0?Bt(t.salt):void 0,p=(f)=>Ss({publicKey:{...d,extensions:f&&u!==void 0?{prf:{eval:{first:u}}}:{prf:{}}}}),h;try{h=await p(u!==void 0)}catch(f){if(u===void 0||!Bl(f))return Jt(f),c(30);try{h=await p(!1)}catch(V){return Jt(V),c(30)}}let[y,b]=At(h);if(b!==0)return c(b);if(y===void 0)return c(27);let Z=y.getClientExtensionResults(),X=Ho(Z.prf?.results?.first),I=Z.prf?.enabled===!0||X!==void 0;if(l&&X!==void 0)X.fill(0);return m({credId:new Uint8Array(y.rawId),userId:new Uint8Array(r),prfEnabled:I,prf:l?void 0:X,attachment:En(y.authenticatorAttachment),transports:Fn(y),aaguid:fo(y)})}async function xo(t){let e=jt();if(e!==0)return c(e);let[s,n]=Ot(t);if(n!==0)return c(n);if(s===void 0)return c(9);let i=t?.salt??gs,o=Bt(i),r={challenge:Ht(Dt),rpId:s,userVerification:"preferred",extensions:{prf:{eval:{first:o}}}};if(t?.hints!==void 0)r.hints=t.hints;let l=Ul(t?.credId);if(l.length>0)r.allowCredentials=l.map((y)=>({type:ft,id:Bt(y)}));let a;try{a=await Vs({publicKey:r})}catch(y){return Jt(y),c(30)}let[d,u]=At(a);if(u!==0)return c(u);if(d===void 0)return c(27);let p=d.getClientExtensionResults().prf?.results;if(p?.first===void 0)return c(7);let h=Ho(p.first);if(h===void 0)return c(27);return m({prf:h,credId:new Uint8Array(d.rawId),attachment:En(d.authenticatorAttachment),transports:Fn(d)})}class et{#t;constructor(t){this.#t=t}static async fromRandom(){let t=await dt.gen256BitSecureRandomSeed(),[e,s]=Re(t);if(s!==0||e===void 0)throw Error(`enclave: invalid random seed (${s})`);return new et(e)}static fromBytes(t){let[e,s]=Re(t);if(s!==0)return c(s);if(e===void 0)return c(10);let[n,i]=Re(e.slice());if(i!==0)return c(i);if(n===void 0)return c(10);return m(new et(n))}async sealWithPasskey(t){let e=t?.salt??gs,s=t?.credId,n=s,i=t?.createCredIfNeeded===!0&&(s===void 0||!(s instanceof Uint8Array)&&s.length===0),o,r;if(i){let[u,p]=await Jl({rpId:t?.rpId,rpName:t?.rpName,userName:t?.userName??fe,displayName:t?.displayName,authenticatorAttachment:t?.authenticatorAttachment,hints:t?.hints,excludeCredentials:t?.excludeCredentials,salt:e});if(p!==0)return c(p);if(u===void 0)return c(30);if(!u.prfEnabled)return c(30);n=u.credId,o=u,r=u.prf}let l=async(u,p,h,y)=>{try{let[b,Z]=await this.#n(u);if(Z!==0)return c(Z);if(b===void 0)return c(12);return m({sealedMaster:b,salt:e.slice(),credId:p.slice(),userId:o?.userId===void 0?void 0:o.userId.slice(),attachment:h??o?.attachment,transports:y??o?.transports,aaguid:o?.aaguid===void 0?void 0:o.aaguid.slice()})}finally{u.fill(0)}};if(r!==void 0&&o!==void 0)return l(r,o.credId,o.attachment,o.transports);let[a,d]=await xo({rpId:t?.rpId,rpName:t?.rpName,credId:n,salt:e,hints:t?.hints});if(d!==0)return c(d);if(a===void 0)return c(7);return l(a.prf,a.credId,a.attachment,a.transports)}async bind(t,e){if(e!==void 0){for(let o of e)if(!await this.#s(o.credId,o.tag))return c(10)}let[s,n]=await this.sealWithPasskey(t);if(n!==0)return c(n);if(s===void 0)return c(12);let i=await this.#e(s.credId);return m({...s,tag:i})}static async unsealWithPasskey(t,e){if(t.length===0)return c(22);let s=[];for(let l of t)if(l.credId.byteLength>0)s.push(l.credId);let[n,i]=await xo({rpId:e.rpId,rpName:e.rpName,hints:e.hints,credId:s.length>0?s:void 0,salt:e.salt});if(i!==0)return c(i);if(n===void 0)return c(7);let o=t.find((l)=>B(l.credId,n.credId)),r=o===void 0?t:[o,...t.filter((l)=>l!==o)];try{for(let l of r){let[a]=await et.#o(l.sealedMaster,n.prf);if(a!==void 0)return m({enclave:a,credId:n.credId.slice()})}return c(20)}finally{n.prf.fill(0)}}async persistToLargeBlob(t=[],e){let s=e?.credId;if(s===void 0){let[o,r]=await Io(e);if(r!==0)return c(r);if(o===void 0)return c(30);s=o}let[n,i]=this.#i(t);if(i!==0)return c(i);if(n===void 0)return c(12);try{let o=await Ko(s,n,e);if(o!==0)return c(o);return m(s)}finally{n.fill(0)}}static async fromLargeBlob(t){let[e,s]=await So(t?.credId,t);if(s!==0)return c(s);if(e===void 0)return c(7);try{let[n,i]=go(e.blob);if(i!==0)return c(i);if(n===void 0)return c(12);return m({...n,credId:e.credId})}finally{e.blob.fill(0)}}static async clearLargeBlob(t,e){return Ko(t,new Uint8Array(yt),e)}static fromPairPlain(t){return go(t)}static pairRequest(){return Be.create()}async pairAccept(t,e){let s;try{s=await dt.genX25519()}catch{return c(29)}try{let[n,i]=await Jn(s.priv,t,t,s.pub);if(i!==0)return c(i);if(n===void 0)return c(12);try{let[o,r]=this.#i(e);if(r!==0)return c(r);if(o===void 0)return c(12);try{let l=await dt.encryptXSalsa20Poly1305Combined(o,n);return Bn(St(s.pub,l))}catch{return c(12)}finally{o.fill(0)}}finally{n.fill(0)}}finally{s.priv.fill(0)}}spawnSyncWorker(t){let e=Vo(),s=this.#t.slice();return Wo(e,{id:t.id,op:"setSeed",seed:s,persist:t.persist},[s.buffer]),e}deriveCipher(t,e){let s=t.slice(),n=(r)=>this.#c(s,r),i=(r)=>this.#a(s,r);return{encrypt:Object.freeze({encrypt:n}),decrypt:Object.freeze({decrypt:i}),both:Object.freeze({encrypt:n,decrypt:i})}[e]}async deriveIdentity(t,e=0){let s=t,n=e,i=await this.#l(s,n),o=i.publicKey;return i.privateKey.fill(0),Object.freeze({publicKey:o,sign:(r)=>this.#u(s,n,r),kdmFor:(r)=>this.#p(s,n,r)})}async#e(t){let e=new Uint8Array(this.#t.byteLength+Dn.byteLength+t.byteLength);e.set(this.#t,0),e.set(Dn,this.#t.byteLength),e.set(t,this.#t.byteLength+Dn.byteLength);try{return await dt.blake3(e)}finally{e.fill(0)}}async#s(t,e){if(e.byteLength!==Ll)return!1;let s=await this.#e(t);try{if(s.byteLength!==e.byteLength)return!1;let n=0;for(let i=0;i<s.byteLength;i++){let o=s[i],r=e[i];if(o===void 0||r===void 0)return!1;n|=o^r}return n===0}finally{s.fill(0)}}async#n(t){let[e,s]=await Ro(dt,t);if(s!==0)return c(s);if(e===void 0)return c(12);try{let n=await dt.encryptXSalsa20Poly1305Combined(this.#t,e);return Pt(n)}catch{return c(12)}finally{e.fill(0)}}static async#o(t,e){let[,s]=Pt(t);if(s!==0)return c(s);let[n,i]=await Ro(dt,e);if(i!==0)return c(i);if(n===void 0)return c(12);let o;try{try{o=await dt.decryptXSalsa20Poly1305Combined(t,n)}catch{return c(20)}return et.fromBytes(o)}finally{n.fill(0),o?.fill(0)}}#i(t){let e=new P,s=e.writeStruct(wn,{hosts:wl(t)});if(s!==0)return c(s);let n=e.result(),i=new Uint8Array(yt+n.byteLength);return i.set(this.#t,0),i.set(n,yt),m(i)}async#c(t,e){let s=await this.#r(t);try{return await dt.encryptXSalsa20Poly1305Combined(e,s)}finally{s.fill(0)}}async#a(t,e){let s=await this.#r(t);try{return await dt.decryptXSalsa20Poly1305Combined(e,s)}finally{s.fill(0)}}async#r(t){let e=new Uint8Array(this.#t.byteLength+t.byteLength);e.set(this.#t,0),e.set(t,this.#t.byteLength);try{return await dt.blake3(e)}finally{e.fill(0)}}async#d(t,e){let s=new TextEncoder().encode(t),n=new Uint8Array(8);return new DataView(n.buffer).setBigUint64(0,BigInt(e),!1),await this.#r(St(s,n))}async#l(t,e){let s=await this.#d(t,e);try{return await dt.deriveEd25519KeyPair(s)}finally{s.fill(0)}}async#u(t,e,s){let n=await this.#l(t,e);try{return await dt.signEd25519(s,n.privateKey)}finally{n.privateKey.fill(0)}}async#p(t,e,s){let n=await this.#l(t,e),i=St(n.privateKey,s);n.privateKey.fill(0);try{return(await dt.blake3(i)).slice(0,Tt)}finally{i.fill(0)}}}async function Ro(t,e,s=Tl){if(e.byteLength<Pl)return c(10);let n=await t.blake3(St(e,s));return m(n.slice(0,Ml))}var Nl=new Set(["constructor","prototype","length","name"]);function Yo(t){for(let e of Object.getOwnPropertyNames(t)){if(Nl.has(e))continue;let s=Object.getOwnPropertyDescriptor(t,e);if(s===void 0||typeof s.value!=="function")continue;Object.defineProperty(t,e,{value:s.value,writable:!1,configurable:!1})}}Yo(et);Yo(et.prototype);var ko=8;class Hs{#t;#e;#s;#n;constructor(t){if(this.#n=t.persistKeyring,this.#s={rpId:t.rpId,rpName:t.rpName},t.keyring!==void 0)this.#e=Yt(t.keyring)}get keyring(){return this.#e===void 0?void 0:Yt(this.#e)}list(){if(this.#e===void 0)return[];return this.#e.entries.map(Fl)}async save(t,e){if(e?.persist===!0)return Promise.reject(Error("prf-store: use bindAndSave(enclave) to persist a binding"));return this.#t=t,this.#t}async bindAndSave(t,e){let s=this.#e,n=e?.credId,i=n instanceof Uint8Array?n.byteLength>0:n!==void 0&&n.length>0;if(!i&&s!==void 0&&s.entries.length>=ko)return c(26);let o=Co(e?.nick),r=e?.excludeCredentials??(i?void 0:Mo(s)),l=e?.salt??s?.salt,a=s===void 0?void 0:s.entries.map((b)=>({credId:b.credId,tag:b.tag})),[d,u]=await t.bind({...this.#s,salt:l,credId:n,createCredIfNeeded:e?.createCredIfNeeded??!i,excludeCredentials:r,userName:fe,displayName:o??fe,authenticatorAttachment:e?.authenticatorAttachment,hints:e?.hints},a);if(u!==0)return c(u);if(d===void 0)return c(12);let p=Date.now(),h={type:"prf",sealedMaster:d.sealedMaster,credId:d.credId,tag:d.tag,userId:d.userId,nick:o,enrolledAt:p,lastUsedAt:p,attachment:d.attachment,transports:d.transports,aaguid:d.aaguid,enrolledOs:zl()},y=s===void 0?{salt:d.salt.slice(),entries:[]}:Yt(s);return this.#e=Ql(y,h),this.#t=t,await this.#n(Yt(this.#e)),m(this.#t)}async load(){return this.#t}async unlock(){let t=this.#e;if(t===void 0||t.entries.length===0)return c(22);let[e,s]=await et.unsealWithPasskey(t.entries.map((i)=>({sealedMaster:i.sealedMaster,credId:i.credId})),{...this.#s,salt:t.salt});if(s!==0)return c(s);this.#t=e.enclave;let n=vl(t,e.credId);if(n!==void 0)this.#e=n,await this.#n(Yt(n));return m(e.enclave)}async rename(t,e){let s=this.#e;if(s===void 0)return c(22);let n=s.entries.findIndex((a)=>B(a.credId,t));if(n<0)return c(13);let i=s.entries.map(Je),o=i[n];if(o===void 0)return c(13);let r=Co(e);i[n]={...o,nick:r};let l={salt:s.salt.slice(),entries:i};return this.#e=l,await this.#n(Yt(l)),m(void 0)}async remove(t){let e=this.#e;if(e===void 0)return c(22);let s=e.entries.filter((i)=>!B(i.credId,t));if(s.length===e.entries.length)return c(13);if(s.length===0)return this.#e=void 0,await this.#n(void 0),m(void 0);let n={salt:e.salt.slice(),entries:s.map(Je)};return this.#e=n,await this.#n(Yt(n)),m(void 0)}async wipe(){this.#t=void 0,this.#e=void 0,await this.#n(void 0)}}function Co(t){if(t===void 0)return;let e=t.trim();return e===""?void 0:e}function zl(){if(typeof navigator>"u")return;return Go(navigator.userAgent)}function Je(t){let[e,s]=Pt(t.sealedMaster.slice());return{type:"prf",sealedMaster:s===0&&e!==void 0?e:t.sealedMaster,credId:t.credId.slice(),tag:t.tag.slice(),userId:t.userId===void 0?void 0:t.userId.slice(),nick:t.nick,enrolledAt:t.enrolledAt,lastUsedAt:t.lastUsedAt,attachment:t.attachment,transports:t.transports===void 0?void 0:[...t.transports],aaguid:t.aaguid===void 0?void 0:t.aaguid.slice(),enrolledOs:t.enrolledOs}}function Yt(t){return{salt:t.salt.slice(),entries:t.entries.map(Je)}}function To(t){return t!==null&&typeof t==="object"}function El(t){if(!To(t)||t.type!=="prf")return;if(!(t.sealedMaster instanceof Uint8Array)||!(t.credId instanceof Uint8Array)||!(t.tag instanceof Uint8Array)||t.tag.byteLength!==32||typeof t.enrolledAt!=="number"||!Number.isFinite(t.enrolledAt))return;let[e,s]=Pt(t.sealedMaster);if(s!==0||e===void 0)return;let n=t.attachment==="platform"||t.attachment==="cross-platform"?t.attachment:void 0,i=t.enrolledOs,o=i==="ios"||i==="macos"||i==="android"||i==="windows"||i==="linux"||i==="other"?i:void 0,r=Array.isArray(t.transports)?t.transports.filter((l)=>typeof l==="string"):void 0;return{type:"prf",sealedMaster:e,credId:t.credId.slice(),tag:t.tag.slice(),userId:t.userId instanceof Uint8Array?t.userId.slice():void 0,nick:typeof t.nick==="string"?t.nick:void 0,enrolledAt:t.enrolledAt,lastUsedAt:typeof t.lastUsedAt==="number"&&Number.isFinite(t.lastUsedAt)?t.lastUsedAt:void 0,attachment:n,transports:r===void 0||r.length===0?void 0:r,aaguid:t.aaguid instanceof Uint8Array?t.aaguid.slice():void 0,enrolledOs:o}}function Lo(t){if(!To(t))return;if(!(t.salt instanceof Uint8Array)||!Array.isArray(t.entries))return;let e=[];for(let s of t.entries){let n=El(s);if(n!==void 0)e.push(n)}if(e.length===0)return;return{salt:t.salt.slice(),entries:e}}function Fl(t){return{type:"prf",credId:t.credId.slice(),userId:t.userId===void 0?void 0:t.userId.slice(),nick:t.nick,enrolledAt:t.enrolledAt,lastUsedAt:t.lastUsedAt,attachment:t.attachment,transports:t.transports===void 0?void 0:[...t.transports],aaguid:t.aaguid===void 0?void 0:t.aaguid.slice(),enrolledOs:t.enrolledOs}}function Mo(t){if(t===void 0)return[];return t.entries.filter((e)=>e.credId.byteLength>0).map((e)=>e.credId.slice())}function Ql(t,e){let s=t.entries.map(Je),n=s.findIndex((i)=>B(i.credId,e.credId));if(n>=0){let i=s[n];s[n]={...e,enrolledAt:i?.enrolledAt??e.enrolledAt,nick:e.nick??i?.nick}}else s.push(e);return{salt:t.salt.slice(),entries:s}}function vl(t,e){if(e.byteLength===0)return;let s=t.entries.findIndex((o)=>B(o.credId,e));if(s<0)return;let n=t.entries.map(Je),i=n[s];if(i===void 0)return;return n[s]={...i,lastUsedAt:Date.now()},{salt:t.salt.slice(),entries:n}}var Dl=Ys("fbfc3007154e4ecc8c0b6e020557d7bd"),Ol=Ys("ea9b8d664d011d213ce4b6b48cb575d4"),jl=Ys("08987058cadc4b81b6e130de50dcbe96"),Al=Ys("2fc0579f811347eab116bb5a8db9202a");function Ys(t){let e=new Uint8Array(16);for(let s=0;s<16;s++)e[s]=Number.parseInt(t.slice(s*2,s*2+2),16);return e}function ql(t){if(t===void 0||t.byteLength!==16)return;if(B(t,Dl))return"Apple Passkey";if(B(t,Ol))return"GPM";if(B(t,jl))return"Windows Hello";if(B(t,Al))return"YubiKey";return}function _l(t){if(t.attachment==="cross-platform")return!0;if(t.transports===void 0)return!1;return t.transports.some((e)=>e==="usb"||e==="nfc"||e==="ble")}function Po(t){let e=ql(t.aaguid);if(e!==void 0)return e;if(_l(t))return"Security key";if(t.attachment==="platform"){if(t.enrolledOs==="ios"||t.enrolledOs==="macos")return"Apple Passkey";if(t.enrolledOs==="android")return"GPM";if(t.enrolledOs==="windows")return"Windows Hello";return"Passkey"}return"Passkey"}function $l(t){if(t.byteLength===0)return"";let e=Math.min(4,t.byteLength),s="";for(let n=t.byteLength-e;n<t.byteLength;n++){let i=t[n];if(i===void 0)continue;s+=i.toString(16).padStart(2,"0")}return s}function tc(t){if(t.nick!==void 0&&t.nick!=="")return t.nick;let e=Po(t),s=$l(t.credId);return s===""?e:`${e} ${s}`}var ec="diplomatic.pin/";function sc(t){return ec+ct(t)}async function wo(t,e,s){let n=await e.deriveIdentity(sc(s),0);return t.blake3(n.publicKey)}async function Cs(t,e){let s=await t.gen256BitSecureRandomSeed(),n=await wo(t,e,s);return{n:s,h:n}}async function ks(t,e,s){let n=await wo(t,e,s.n);return nc(n,s.h)}function Uo(t){if(t===void 0||t===null||typeof t!=="object")return;let e=t;if(!(e.n instanceof Uint8Array)||!(e.h instanceof Uint8Array))return;if(e.n.byteLength<1||e.h.byteLength<1)return;return{n:e.n.slice(),h:e.h.slice()}}function Ts(t){return{n:t.n.slice(),h:t.h.slice()}}function nc(t,e){if(t.byteLength!==e.byteLength)return!1;let s=0;for(let n=0;n<t.byteLength;n++)s|=t[n]^e[n];return s===0}var Ls="keyring",Bo="prfMeta",jn="idPin",Jo="idPub";class Ms{#t;db;#e;constructor(t,e){this.db=t,this.#e=e}async save(t,e){return await this.#s(t),this.#t=t,this.#t}async load(){return this.#t}async clearSession(){this.#t=void 0}async wipe(){this.#t=void 0;let t=this.db.transaction(rt,"readwrite"),e=t.objectStore(rt);return new Promise((s,n)=>{t.oncomplete=()=>s(),t.onerror=()=>n(t.error),e.delete(Ls),e.delete(Bo),e.delete(jn),e.delete(Jo)})}async loadKeyring(){let e=this.db.transaction(rt,"readonly").objectStore(rt);return new Promise((s,n)=>{let i=e.get(Ls);i.onsuccess=()=>{s(Lo(i.result))},i.onerror=()=>n(i.error)})}async persistKeyring(t){let e=this.db.transaction(rt,"readwrite"),s=e.objectStore(rt);return new Promise((n,i)=>{if(e.oncomplete=()=>n(),e.onerror=()=>i(e.error),s.delete(Bo),t===void 0){s.delete(Ls);return}s.put(Yt(t),Ls)})}async hasKeyring(){let t=await this.loadKeyring();return t!==void 0&&t.entries.length>0}async openPrfStore(t){let e=await this.loadKeyring();return new Hs({rpId:t.rpId,rpName:t.rpName,keyring:e,persistKeyring:(s)=>this.persistKeyring(s)})}async#s(t){await this.#i(Jo);let e=await this.#n();if(e!==void 0){if(!await ks(this.#e,t,e))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)");return}let s=await Cs(this.#e,t);await this.#o(s)}#n(){let e=this.db.transaction(rt,"readonly").objectStore(rt);return new Promise((s,n)=>{let i=e.get(jn);i.onsuccess=()=>s(Uo(i.result)),i.onerror=()=>n(i.error)})}#o(t){let e=Ts(t),s=this.db.transaction(rt,"readwrite"),n=s.objectStore(rt);return new Promise((i,o)=>{s.oncomplete=()=>i(),s.onerror=()=>o(s.error),n.put(e,jn)})}#i(t){let e=this.db.transaction(rt,"readwrite"),s=e.objectStore(rt);return new Promise((n,i)=>{e.oncomplete=()=>n(),e.onerror=()=>i(e.error),s.delete(t)})}}class An{db;constructor(t){this.db=t}async enq(t,e){let s=[...e];if(s.length===0)return;let n=this.db.transaction(mt,"readwrite"),i=n.objectStore(mt);return new Promise((o,r)=>{n.oncomplete=()=>o(),n.onerror=()=>r(n.error);for(let l of s){let a=ct(l);i.put({host:t,hash:a})}})}async deq(t,e){let s=[...e];if(s.length===0)return;let n=this.db.transaction(mt,"readwrite"),i=n.objectStore(mt);return new Promise((o,r)=>{n.oncomplete=()=>o(),n.onerror=()=>r(n.error);for(let l of s){let a=ct(l);i.delete([t,a])}})}async list(t){let s=this.db.transaction(mt,"readonly").objectStore(mt);return new Promise((n,i)=>{let o=s.getAll();o.onsuccess=()=>{let l=o.result.filter((a)=>a.host===t).map((a)=>a.hash);n(l.map((a)=>ge(a)))},o.onerror=()=>i(o.error)})}async count(){let e=this.db.transaction(mt,"readonly").objectStore(mt);return new Promise((s,n)=>{let i=e.count();i.onsuccess=()=>s(i.result),i.onerror=()=>n(i.error)})}async wipe(){let t=this.db.transaction(mt,"readwrite"),e=t.objectStore(mt);return new Promise((s,n)=>{t.oncomplete=()=>s(),t.onerror=()=>n(t.error),e.clear()})}}var rt="seedMeta",ot="hosts",mt="uploadQueue",pt="downloadQueue",Q="messages",we="apld",No=3,zo="diplomatic-store-db";class qn{seed;hosts;uploads;downloads;messages;db;constructor(t,e){this.db=t,this.seed=new Ms(t,e),this.hosts=new Mn(t),this.uploads=new An(t),this.downloads=new Ln(t),this.messages=new Pn(t,e)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function ic(){return new Promise((t,e)=>{let s=indexedDB.open(zo,No);s.onupgradeneeded=()=>{let{result:n,transaction:i}=s;if(!n.objectStoreNames.contains(rt))n.createObjectStore(rt);if(!n.objectStoreNames.contains(ot))n.createObjectStore(ot,{keyPath:"label"});if(!n.objectStoreNames.contains(mt))n.createObjectStore(mt,{keyPath:["host","hash"]});if(!n.objectStoreNames.contains(pt))n.createObjectStore(pt);let o;if(!n.objectStoreNames.contains(Q))o=n.createObjectStore(Q);else{if(!i)throw Error("missing upgrade transaction for messages store");o=i.objectStore(Q)}if(!o.indexNames.contains(we))o.createIndex(we,"apld",{unique:!1})},s.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${zo} → v${No}); waiting for other connections to close`)},s.onsuccess=()=>{let n=s.result;n.onversionchange=()=>{n.close()},t(n)},s.onerror=()=>e(s.error??Error("protocol store IndexedDB open failed"))})}async function _n(t){let e=await ic();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((s)=>{setTimeout(()=>s(!1),2000)})])}catch{}return new qn(e,t)}function Eo(t){if(!t||typeof t!=="object")return!1;if(!("kind"in t))return!1;return typeof t.kind==="string"}function Fo(t){if(typeof t!=="number")return;return t}function oc(t){if(!t||typeof t!=="object")return;if(!("phase"in t))return;let e=rc(t.phase);if(e===void 0)return;let s={phase:e};if("host"in t&&typeof t.host==="string")s.host=t.host;if("done"in t&&typeof t.done==="number")s.done=t.done;if("total"in t&&typeof t.total==="number")s.total=t.total;if("bytesDone"in t&&typeof t.bytesDone==="number")s.bytesDone=t.bytesDone;if("bytesTotal"in t&&typeof t.bytesTotal==="number")s.bytesTotal=t.bytesTotal;return s}function rc(t){if(t==="peek"||t==="pull"||t==="open"||t==="exec"||t==="push"||t==="import"||t==="idle"||t==="apply")return t==="apply"?"exec":t;return}function Qo(t){if(!t||typeof t!=="object")return;if(!("numUploads"in t)||!("numDownloads"in t))return;if(typeof t.numUploads!=="number"||typeof t.numDownloads!=="number")return;let e={phase:"idle"};if("progress"in t){let s=oc(t.progress);if(s===void 0)return;e=s}return{numUploads:t.numUploads,numDownloads:t.numDownloads,progress:e}}var ht="[DIPLOMATIC]";class ze{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:zt};clientState;xferState;constructor(t,e,s,n,i){this.state=t,this.store=e,this.readyTimeoutMs=i,this.clientState=new bt(async()=>this.cachedClientState),this.xferState=new bt(async()=>this.cachedXferState),this.scheduledSync=new ke(n,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(o){console.error(`${ht} worker sync after local write failed`,o)}}),this.local=new he(s,t,e,()=>{throw Error(`${ht} local writer has no transport (use worker for network)`)},Xe,!0,void 0,void 0,()=>{this.scheduledSync.schedule()}),this.local.xferState.listen((o)=>{this.cachedXferState={numUploads:o.numUploads,numDownloads:o.numDownloads,progress:this.cachedXferState.progress},this.xferState.emit()})}bindWorker(t){let e=this.worker;if(e){e.onmessage=null,e.onerror=null,e.onmessageerror=null;try{e.terminate()}catch{}}this.worker=t,t.onmessage=(s)=>{this.onMessage(s.data)},t.onerror=(s)=>{console.error(`${ht} worker error`,s),this.failPending(Error(`${ht} worker failed to load`))},t.onmessageerror=()=>{this.failPending(Error(`${ht} worker message error`))}}failPending(t){for(let[,e]of this.pending)e.reject(t);this.pending.clear()}async flushScheduledSync(){await this.scheduledSync.flush()}static async open(t,e,s={}){let n=s.clock??new Mt,i=s.syncDebounceMs??is,o=s.readyTimeoutMs??15000,r=new ze(t,e,n,i,o);return await r.hydrateStateFromStore(e),r}async hydrateStateFromStore(t){await this.loadSession(!1);let e=await t.uploads.count(),s=await t.downloads.count();this.cachedXferState={numUploads:e,numDownloads:s,progress:zt}}async loadSession(t){let e=await this.store.seed.load(),s=await this.store.hosts.list();this.cachedClientState={hasSeed:e!==void 0,hasHost:Array.from(s).length>0,connected:t}}async pullRemoteXfer(){let t=await this.request({id:this.allocId(),op:"getXferState"}),e=Qo(t);if(e!==void 0)this.cachedXferState=e}requireWorker(){if(!this.worker)throw Error(`${ht} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${ht} worker ping failed`)}terminate(){this.scheduledSync.cancel();let t=this.worker;if(this.worker=void 0,t)try{t.terminate()}catch{}this.failPending(Error(`${ht} worker terminated`))}onMessage(t){if(!Eo(t))return;let e=t;switch(e.kind){case"ready":return;case"initError":{this.failPending(Error(`${ht} worker init failed: ${e.message}`));return}case"clientState":{if(this.cachedClientState.connected===e.connected)return;this.cachedClientState={...this.cachedClientState,connected:e.connected},this.clientState.emit();return}case"xferState":{this.cachedXferState=e.state,this.xferState.emit();return}case"dirty":{this.state.refresh(e.eids.map(cc));return}case"wiped":{this.state.clear();return}case"reply":{let s=this.pending.get(e.id);if(!s)return;if(this.pending.delete(e.id),e.ok)s.resolve(e.result);else s.reject(new Ne(e.status));return}default:return}}allocId(){let t=this.nextId;return this.nextId+=1,t}request(t,e){let s=this.requireWorker();return new Promise((n,i)=>{if(this.pending.set(t.id,{resolve:n,reject:i}),e&&e.length>0)s.postMessage(t,e);else s.postMessage(t)})}async requestStatus(t,e){try{let s=await this.request(t,e),n=Fo(s);if(n!==void 0)return n;return 0}catch(s){if(s instanceof Ne)return s.status;return 12}}serializeHost(t){return{handle:t.handle.href,label:t.label,idx:t.idx??0}}async setSeed(t,e){await this.local.setSeed(t,e),await this.loadSession(!1),this.clientState.emit();let s=this.allocId(),n=this.readyTimeoutMs;await new Promise((i,o)=>{let r=void 0,l=(a)=>{if(r!==void 0)clearTimeout(r);a()};this.pending.set(s,{resolve:(a)=>l(()=>i(a)),reject:(a)=>l(()=>o(a))}),r=setTimeout(()=>{this.pending.delete(s),o(Error(`${ht} setSeed worker timeout after ${n}ms`))},n);try{let a=t.spawnSyncWorker({id:s,persist:e?.persist});this.bindWorker(a)}catch(a){if(this.pending.delete(s),r!==void 0)clearTimeout(r);o(a instanceof Error?a:Error(String(a)))}});try{await this.pullRemoteXfer()}catch{}}async link(t,e=!0){await this.local.link(t,!1),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(t),connect:e})}async unlink(t){if(await this.local.unlink(t),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),!this.worker)return;await this.request({id:this.allocId(),op:"unlink",label:t})}async hosts(){return this.local.hosts()}async connect(t=!0,e=!0){if(!this.worker)return;await this.request({id:this.allocId(),op:"connect",listen:t,sync:e})}async disconnect(){if(!this.worker)return;await this.request({id:this.allocId(),op:"disconnect"})}async insertRaw(t){return this.local.insertRaw(t)}async updateRaw(t,e,s){return this.local.updateRaw(t,e,s)}async insert(t){return this.local.insert(t)}async update(t){return this.local.update(t)}async delete(t){return this.local.delete(t)}async genEID(t){return this.local.genEID(t)}async sync(){if(!this.worker)return 0;return this.requestStatus({id:this.allocId(),op:"sync"})}async rebuild(t){return this.scheduledSync.cancel(),await this.scheduledSync.flush(),this.requestStatus({id:this.allocId(),op:"rebuild",checkHost:t?.checkHost})}async listMsgs(t){return this.local.listMsgs(t)}async countMsgs(t){return this.local.countMsgs(t)}async reconcile(t,e){try{let s=await this.request({id:this.allocId(),op:"reconcile",hostLabel:t,pull:e?.pull,push:e?.push,sync:e?.sync});if(!lc(s))return c(12);return m(s)}catch(s){if(s instanceof Ne&&s.status!==0)return c(s.status);return c(12)}}async msgcheck(){let t=await this.request({id:this.allocId(),op:"msgcheck"});if(!(t instanceof Uint8Array))throw Error(`${ht} msgcheck: expected Uint8Array`);return t}async entcheck(){let t=await this.request({id:this.allocId(),op:"entcheck"});if(!(t instanceof Uint8Array))throw Error(`${ht} entcheck: expected Uint8Array`);return t}async wipe(t){if(await this.local.wipe(t),this.worker)await this.request({id:this.allocId(),op:"wipe",msgs:t?.msgs,ents:t?.ents,meta:t?.meta,seed:t?.seed});await this.hydrateStateFromStore(this.store),this.clientState.emit(),this.xferState.emit()}async import(t){let e=new Uint8Array(await t.arrayBuffer());return this.requestStatus({id:this.allocId(),op:"import",bytes:e},[e.buffer])}async export(t,e){try{let s=await this.request({id:this.allocId(),op:"export"});if(!(s instanceof Uint8Array))return 12;let n=new Blob([s.slice()]);return rs(n,t),0}catch(s){if(s instanceof Ne)return s.status;return 12}}}class Ne extends Error{status;constructor(t){super(`WorkerReplyError: ${W[t]}`);this.status=t;this.name="WorkerReplyError"}}function lc(t){if(!t||typeof t!=="object")return!1;let e=t;return e.msgcheck instanceof Uint8Array&&e.msgcheck.length===32&&typeof e.numBags==="number"&&typeof e.numDupes==="number"}function cc(t){return t}var Ie="[DIPLOMATIC]";async function Ps(t){let e=t.clock??new Mt;if(t.worker===!0&&ac(t)!==void 0)throw Error(`${Ie} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(t.worker!==!0){console.info(`${Ie} sync on main thread `+"(no worker — app did not request a worker)");let i=await vo(t.store);return dc(e,t.state,i)}if(typeof Worker>"u")throw Error(`${Ie} worker: true but Worker API is unavailable`);let s=await vo(void 0),n=await ze.open(t.state,s,{readyTimeoutMs:t.readyTimeoutMs,clock:e,syncDebounceMs:t.syncDebounceMs});return console.info(`${Ie} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:n,mode:"worker",dispose:()=>{console.info(`${Ie} terminating sync worker`),n.terminate()}}}function ac(t){if("store"in t)return t.store;return}async function dc(t,e,s){let n=new he(t,e,s,_s,Xe);return{client:n,mode:"main",dispose:()=>{n.disconnect()}}}async function vo(t){if(t!==void 0)return t;if(typeof indexedDB>"u")throw Error(`${Ie} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return _n(Xe)}function uc(t){let[e,s]=$n();return ws(()=>{async function n(){let o=await t.clientState.get();s(o)}let i=t.clientState.listen(n);return n(),()=>{i()}},[t]),e}function pc(t){let[e,s]=$n();return ws(()=>{async function n(){let o=await t.xferState.get();s(o)}let i=t.xferState.listen(n);return n(),()=>{i()}},[t]),e}function mc(t){ws(()=>{async function e(){try{if(!(await t.clientState.get()).hasSeed)return;await t.connect(),await t.sync()}catch(o){console.error("reconnectAndSync failed",o)}}function s(){e()}function n(){if(typeof document<"u"&&document.visibilityState==="visible")e()}function i(){e()}if(globalThis.addEventListener("online",s),typeof document<"u")document.addEventListener("visibilitychange",n);return globalThis.addEventListener("focus",i),globalThis.addEventListener("pageshow",i),()=>{if(globalThis.removeEventListener("online",s),typeof document<"u")document.removeEventListener("visibilitychange",n);globalThis.removeEventListener("focus",i),globalThis.removeEventListener("pageshow",i)}},[t])}function hc(t={}){let e=t.clock??new Mt,{seed:s,host:n,readyTimeoutMs:i}=t,o=t.worker===!0,r="store"in t?t.store:void 0,[l,a]=$n({stateMgr:nn});return ws(()=>{let d=!1,u;return(async()=>{let p=await dn();if(d)return;let h=ss(p),y=o?await Ps({state:h,clock:e,worker:!0,readyTimeoutMs:i}):await Ps({state:h,clock:e,store:r,readyTimeoutMs:i});if(d){y.dispose();return}u=y.dispose;let{client:b,mode:Z}=y;if(s)await b.setSeed(s);if(n)await b.link(n);if(d){u();return}a({client:b,entDB:p,stateMgr:h,mode:Z,error:void 0})})().catch((p)=>{let h=p instanceof Error?p:Error(String(p));if(console.error("[DIPLOMATIC] useClient init failed",h),!d)a((y)=>({...y,client:void 0,error:h}))}),()=>{d=!0,u?.()}},[e,s,n,o,r,i]),l}import{use as yc,useEffect as Do,useRef as bc,useState as Zc}from"react";function Oo(t,e,s){let[n,i]=Zc();return Do(()=>{async function o(){let r=await s();i(r)}return o(),t.on(e,o),()=>{t.off(e,o)}},[t,e,s]),n}function Xc(t,e,s){let n=bc(s());return Do(()=>{async function i(){n.current=s()}return t.on(e,i),()=>{t.off(e,i)}},[t,e,s]),yc(n.current)}function jo(t,e){return`${t}:${e}`}class ti{queue=new Map;async enq(t){for(let e of t){let s=jo(e.host,e.seq);this.queue.set(s,e)}}async deq(t,e){for(let s of e){let n=jo(t,s);this.queue.delete(n)}}async list(){let t=[];for(let e of this.queue.values())t.push(e);return t}async count(){return this.queue.size}async wipe(){this.queue.clear()}}function Gc(t,e){if(e.setLastSeq!==void 0)t.lastSeq=e.setLastSeq;else if(e.lastSeq!==void 0&&e.lastSeq>t.lastSeq)t.lastSeq=e.lastSeq}class ei{hosts=new Map;async add(t){let e=this.hosts.get(t.label),s=e!==void 0&&e.handle===t.handle&&(e.idx??0)===(t.idx??0),n={...t,lastSeq:s?e.lastSeq:0,clockOffset:s?e.clockOffset:void 0,subscription:s?e.subscription:void 0};this.hosts.set(t.label,n)}async touch(t,e){await this.recordStats(t,{lastSeq:e})}async recordStats(t,e){let s=this.hosts.get(t);if(!s)return;Gc(s,e),this.hosts.set(t,{...s})}async get(t){return this.hosts.get(t)}async set(t,e){let s=this.hosts.get(t);if(!s)return 13;return this.hosts.set(t,{...s,...e}),0}async del(t){this.hosts.delete(t)}async list(){return this.hosts.values()}async wipe(){this.hosts.clear()}}class si{crypto;messages=new Map;constructor(t){this.crypto=t}async add(t){let e=[];for(let{key:s,data:n}of t)this.messages.set(R(s),n),e.push(0);return e}async del(t){for(let e of t)this.messages.delete(R(e))}async get(t){let e=this.messages.get(R(t));if(e)return await Ut(t,e,this.crypto);return}async has(t){return this.messages.has(R(t))}async list(t){let e=t?.apld,s=t?.body!==!1,n=[];for(let[i,o]of this.messages){if(e!==void 0&&me(o.apld)!==e)continue;let r=tt(i);n.push(await Ut(r,o,this.crypto,{body:s}))}return n}async count(t){if(t===void 0)return this.messages.size;let e=0;for(let s of this.messages.values())if(me(s.apld)===t)e++;return e}async listKeys(){let t=[];for(let e of this.messages.keys())t.push(tt(e));return t}async last(t){let e;for(let[s,n]of this.messages){if(B(t,n.eid)===!1)continue;let i=tt(s);if(e===void 0)e={hash:i,data:n};else if((n.ctr??0)>(e.data.ctr??0)||(n.ctr??0)===(e.data.ctr??0)&&(n.off??0)>(e.data.off??0))e={hash:i,data:n}}if(e)return await Ut(e.hash,e.data,this.crypto);return}async markApplied(t){for(let e of t){let s=this.messages.get(R(e));if(!s)continue;Et(s,wt)}}async markFailed(t){for(let{key:e,err:s}of t){let n=this.messages.get(R(e));if(!n)continue;Et(n,Zt,s)}}async wipe(){this.messages.clear()}}class ni{#t;#e;#s;constructor(t){this.#e=t}async save(t,e){if(this.#s!==void 0){if(!await ks(this.#e,t,this.#s))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)")}else this.#s=await Cs(this.#e,t);return this.#t=t,this.#t}async load(){return this.#t}async wipe(){this.#t=void 0,this.#s=void 0}peekPin(){return this.#s===void 0?void 0:Ts(this.#s)}}class ii{queue=new Map;async enq(t,e){let s=this.queue.get(t)||new Set;this.queue.set(t,s);for(let n of e)s.add(ct(n))}async deq(t,e){let s=this.queue.get(t);if(s)for(let n of e)s.delete(ct(n))}async list(t){let e=this.queue.get(t);if(!e)return[];let s=[];for(let n of e)s.push(ge(n));return s}async count(){let t=0;for(let e of this.queue.values())t+=e.size;return t}async wipe(){this.queue.clear()}}class Ao{seed;hosts=new ei;uploads=new ii;downloads=new ti;messages;constructor(t){this.seed=new ni(t),this.messages=new si(t)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class qo{singletonType;latest;latestOff=-1;emitter=new Ct;constructor(t){this.singletonType=t}async apply(t){for(let e of t){let s=new M(e.eid),[n,i]=s.readStruct(A);if(i!==0)continue;let o=new P;o.writeVarString(this.singletonType);let r=o.result();if(n.id.length===r.length&&n.id.every((l,a)=>l===r[a])){if(this.latest===void 0||e.off>this.latestOff)this.latestOff=e.off,this.latest=e.bod,this.emitter.emit(this.singletonType,null)}}return t.map(()=>0)}clear=async()=>(this.latest=void 0,this.latestOff=-1,this.emitter.emit(this.singletonType,null),0);notify=(t)=>{for(let e of t)if(e===this.singletonType)this.emitter.emit(this.singletonType,null)};refresh=async(t)=>{this.notify([this.singletonType])};on=(t,e)=>{this.emitter.addEventListener(t,e)};off=(t,e)=>{this.emitter.removeEventListener(t,e)}}class _o{#t;#e;#s;#n;constructor(t){if(this.#s=t.rpId,this.#n=t.rpName,t.credId!==void 0)this.#e=t.credId.slice()}get credId(){if(this.#e===void 0)return;return this.#e.slice()}setCredId(t){this.#e=t===void 0?void 0:t.slice()}async save(t,e){if(e?.persist!==!0)return this.#t=t,this.#t;let[s,n]=await t.persistToLargeBlob([],{rpId:this.#s,rpName:this.#n,credId:this.#e});if(n!==0||s===void 0)return Promise.reject(Error(`persistToLargeBlob status ${n}`));return this.#e=s,this.#t=t,this.#t}async load(){return this.#t}async unlock(){let t=this.#e;if(t===void 0)return c(22);let[e,s]=await et.fromLargeBlob({rpId:this.#s,rpName:this.#n,credId:t});if(s!==0||e===void 0)return c(s);return this.#t=e.enclave,m(e.enclave)}async wipe(){let t=this.#e;if(t!==void 0){let e=await et.clearLargeBlob(t,{rpId:this.#s});if(e!==0)return Promise.reject(Error(`clearLargeBlob status ${e}`))}this.#t=void 0,this.#e=void 0}}export{wt as APLD_APPLIED,Zt as APLD_ERROR,Vt as APLD_PENDING,Ce as CachedEntDB,Mt as Clock,gs as DEFAULT_PRF_SALT,M as Decoder,et as Enclave,P as Encoder,es as EntDBMemory,an as EntIDB,qs as HTTPTransport,Ms as IDBSeedStore,qn as IDBStore,ko as KEYRING_MAX,yt as MASTER_SEED_LEN,Ao as MemoryStore,Be as PairRequest,_o as PasskeySeedStore,Hs as PrfSeedStore,sn as SEALED_MASTER_KEY_LEN,qo as SingletonStateManager,He as StateManager,W as Status,he as SyncClient,Ct as TypedEventEmitter,ze as WorkerClient,me as apldFromStored,Un as asDHKEReq,Bn as asDHKEResp,Pt as asSealedMasterKey,tt as b64tob,Fs as b64urltob,R as btob64,Kr as btob64url,ct as btoh,xe as checksumEntRevs,re as checksumSet,xi as cmpBytes,Xe as crypto,pe as defaultPeekProgressEvery,Xo as defaultWebAuthnRpId,A as eidCodec,Ri as encodeEntRev,ss as entStateManager,gr as genSingletonEID,_s as hostHTTPTransport,ge as htob,zt as idleProgress,Qr as isApldState,E as isLiveEnt,vr as isPendingApply,mn as isTerminalApplyFailure,zr as isTombstone,Mo as keyringCredIds,Po as keyringKind,tc as keyringLabel,Hl as largeBlobCapable,Ti as normalizeTags,Er as nullEntDB,nn as nullStateManager,Ps as openDiplomaticClient,dn as openEntDB,_n as openIDBStore,Yl as prfCapable,Ye as revFromEntity,un as revFromHead,Et as setApld,os as shouldEmitItemProgress,hc as useClient,uc as useClientState,pc as useClientXferState,Oo as useStateWatcher,Xc as useStateWatcherSuspense,mc as useSyncOnResume,Kl as webAuthnLastError};
|