@interncom/diplomatic 0.13.4 → 0.13.6
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/web/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function aV(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 P0(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 U0=new TextEncoder,j0=50;function u0(Z,X,W){U0.encodeInto(Z,X.subarray(W))}function sV(Z,X,W){if(Z.length>j0)u0(Z,X,W);else P0(Z,X,W)}var i0=4096;function UW(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 R=Z[V++]&63;K.push((m&31)<<6|R)}else if((m&240)===224){let R=Z[V++]&63,J=Z[V++]&63;K.push((m&31)<<12|R<<6|J)}else if((m&248)===240){let R=Z[V++]&63,J=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|R<<12|J<<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>=i0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var E0=new TextDecoder,O0=200;function B0(Z,X,W){let V=Z.subarray(X,X+W);return E0.decode(V)}function rV(Z,X,W){if(W>O0)return B0(Z,X,W);else return UW(Z,X,W)}class WX{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 VX=4294967295;function tV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function vX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function oX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function eV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var w0=-1,D0=4294967295,A0=17179869183;function v0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=A0)if(X===0&&Z<=D0){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),vX(V,4,Z),W}}function o0(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 $0(Z){if(Z instanceof Date){let X=o0(Z);return v0(X)}else return null}function q0(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=oX(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 f0(Z){let X=q0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var Zl={type:w0,encode:$0,decode:f0};class lX{static defaultCodec=new lX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(Zl)}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 WX(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 WX(W,l)}}if(Z instanceof WX)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 WX(X,Z)}}function n0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function QX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(n0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var _0=100,a0=2048;class $X{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??lX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??_0,this.initialBufferSize=Z?.initialBufferSize??a0,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 $X({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=aV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),sV(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=QX(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),tV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),vX(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 vZ(Z,X){return new $X(X).encodeSharedRef(Z)}function qX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var s0=16,r0=16;class jW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=s0,X=r0){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=UW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var uW="array",yX="map_key",Wl="map_value",t0=(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 Vl{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=uW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=yX,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===uW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===yX||Z.type===Wl){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,iW=new DataView(new ArrayBuffer(0)),e0=new Uint8Array(iW.buffer);try{iW.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 Xl=RangeError("Insufficient data"),ZK=new jW;class fX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=iW;bytes=e0;headByte=SX;stack=new Vl;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??lX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??VX,this.maxBinLength=Z?.maxBinLength??VX,this.maxArrayLength=Z?.maxArrayLength??VX,this.maxMapLength=Z?.maxMapLength??VX,this.maxExtLength=Z?.maxExtLength??VX,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:ZK,this.mapKeyConverter=Z?.mapKeyConverter??t0}clone(){return new fX({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=QX(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=QX(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 ${qX(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: ${qX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===uW)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===yX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=Wl;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=yX;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: ${qX(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 Xl;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=rV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===yX;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 Xl;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=eV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=oX(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 EW(Z,X){return new fX(X).decode(Z)}class PZ{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 PZ}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 UZ=64;var ll=32,jZ=8;var nX=32;var Kl=30000,Gl=512,M;((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"})(M||={});function b(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function XK(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 WK(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]=WK(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 i{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]=XK(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 i,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 uZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>Kl)return 4;let G=new i;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 KX(Z){let X=new i,W=X.writeStruct(s,Z);if(W!==0)return Y(W);let V=X.result();return b(V)}async function VK(Z){return KX({id:Z,ts:new Date(0)})}var JZ={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,R]=Z.readVarInt();if(R!==0)return Y(R);let[J,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(J>0){let[d,k]=Z.readBytes(nX);if(k!==0)return Y(k);F=d}return b({eid:X,off:K,ctr:m,len:J,hsh:F})}};function YZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function pX(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 n(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 lK(Z){return H(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function BW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function TZ(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function ml(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Yl(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new i,G=JZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),R=await X.kdmFor(m),J=V.deriveCipher(R,"encrypt"),C=await J.encrypt(m),F=Z.bod?await J.encrypt(Z.bod):new Uint8Array(0),d=await X.sign(C);return b({sig:d,kdm:R,headCph:C,bodyCph:F})}async function wW(Z,X,W,V,l){let K=new j(Z),[G,m]=JZ.decode(K);if(m!==0)return Y(14);let R;try{R=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let J=G.hsh&&R===void 0,C=G.hsh===void 0&&R!==void 0;if(J||C)return Y(19);if(G.hsh&&R){let d=await V.blake3(R);if(!n(d,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return b({msgHead:G,bod:R,headHash:F})}class iZ{now(){return new Date}}function Rl(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 DW={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[R,J]=Z.readVarInt();if(J!==0)return Y(J);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,T]=Z.readStruct(MX);if(T!==0)return Y(T);return b({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:d,dyn:c}})}};var AW={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 RZ={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(ll);if(W!==0)return Y(W);let[V,l]=Z.readBytes(UZ);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 Jl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,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(RZ);if(m!==0)return m;let R=await uZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);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,T]=await K.listHeads(J,d);if(T!==0)return T;return W.writeStructs(AW,c)},decodeResp(Z){return Z.readStructs(AW)}};var vW={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 Cl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,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(RZ);if(m!==0)return m;let R=await uZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let d=[];while(!X.done()){let[T,I]=X.readVarInt();if(I!==0)return I;d.push(T)}console.info(`PULL: ${d.length} bags`);let[k,c]=await K.getBodies(J,d);if(c!==0)return c;if(!k)return 17;for(let{seq:T,bodyCph:I}of k){let S={seq:T,bodyCph:I},Q=W.writeStruct(vW,S);if(Q!==0)return Q}return 0},decodeResp(Z){return Z.readStructs(vW)}};var oW={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(UZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(jZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);return b({sig:X,kdm:V,headCph:K,bodyCph:m})}};var _X={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[R,J]=Z.readBytes(K);if(J!==0)return Y(J);m=R}return b({seq:X,headCph:V,bodyCph:m})}};var aX={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(UZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(jZ);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 sX={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 Fl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;let G=l.writeStructs(oW,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,R]=X.readStruct(RZ);if(R!==0)return R;let J=await uZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,d]=await K.hasUser(C);if(d!==0)return d;if(!F)return 5;let[k,c]=X.readStructs(oW);if(c!==0)return c;console.info(`PUSH: ${k.length} bags`);let T=[],I=[];for(let L=0;L<k.length;L++){let z=k[L];if(!await ml(z,C,l)){let E={idx:L,status:3},u=W.writeStruct(sX,E);if(u!==0)return u;continue}T.push(L),I.push(z)}let[S,Q]=await K.setBags(C,I);if(Q!==0)return Q;if(!S||S.length!==I.length)return 17;let p=[];for(let L=0;L<I.length;L++){let z=I[L],g=T[L],E=S[L],u=new i,P=u.writeStruct(aX,z);if(P!==0)return P;let B=u.result(),D={seq:E,headCph:B};if(k.length===1&&z.bodyCph.length<=Gl)D.bodyCph=z.bodyCph;p.push(D);let o={idx:g,status:0,seq:E},y=W.writeStruct(sX,o);if(y!==0)return y}if(p.length>0){let L=new i,z=L.writeStructs(_X,p);if(z!==0)return z;let g=L.result();await Promise.resolve(G.push(C,g))}return 0},decodeResp(Z){return Z.readStructs(sX)}};var bl={async encodeReq(Z,X,W,V,l){return l.writeStruct(RZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await uZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G;if(!X.done())return 8;let[C,F]=await K.addUser(J);if(F!==0)return F;return 0},decodeResp(Z){return b(void 0)}};class $W{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 i;K.writeStruct(RZ,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=(R)=>{let J=new Uint8Array(R.data);X(J)},this.websocket.onerror=(R)=>{console.log(`ERROR: ${JSON.stringify(R)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var r={user:{path:"/user",endpoint:bl,name:0},push:{path:"/push",endpoint:Fl,name:2},peek:{path:"/peek",endpoint:Jl,name:1},pull:{path:"/pull",endpoint:Cl,name:3}},KK={0:r.user,2:r.push,1:r.peek,3:r.pull},UR={[r.user.path]:r.user,[r.push.path]:r.push,[r.peek.path]:r.peek,[r.pull.path]:r.pull};class qW{url;listener;constructor(Z){this.url=Z;this.listener=new $W(Z)}async call(Z,X){let{path:W}=KK[Z],V=new URL(W,this.url);try{return await GK(V,X)}catch{return Y(25)}}}var fW=(Z)=>{return new qW(Z.handle)};async function GK(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 rX{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(),[R,J]=await OW(G,m);if(J!==0)return Y(J);let C=new i,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let d=W.now(),[k,c]=await V.call(K,C),T=W.now();if(c!==0)return Y(c);let[I,S]=k.readStruct(DW);if(S!==0)return Y(S);if(I.status!==0)return Y(I.status);let p={clockOffset:Rl(d,I.timeRcvd,I.timeSent,T),subscription:I.subscription},L=await this.updateHostMeta(p);if(L!==0)return Y(L);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 Yl(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(),[R,J]=await OW(G,m);if(J!==0)return J;return await K.connect(R,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 nW={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,R]=Z.readBytes(nX);if(R!==0)return Y(R);let[J,C]=Z.readBytes(UZ);if(C!==0)return Y(C);return b({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var _W={encode(Z,X){let W=Z.writeStruct(nW,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(nW);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 aW={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(jZ);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[R,J]=Z.readVarInt();if(J!==0)return Y(J);m=R}return b({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function dl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new i,m=new i,R=0,J=0;for(let S of W){let Q=new i,p=Q.writeStruct(JZ,S.head);if(p!==0)return Y(p);let L=Q.result(),z=await K.kdmFor(L),g=l.deriveCipher(z,"encrypt"),E=await g.encrypt(L),u=S.body?await g.encrypt(S.body):new Uint8Array(0),P=S.head.len>0&&S.head.hsh!==void 0?u.length:0,B={kdm:z,headCph:E,lenBody:P,offBody:P>0?J:void 0},D=G.writeStruct(aW,B);if(D!==0)return Y(D);if(S.body)m.writeBytes(u),J+=u.length;R++}let C=m.result(),F=G.result(),d=await V.blake3(F),k=await K.sign(d),c={lbl:Z,idx:X,num:R,hsh:d,sig:k},T=new i;T.writeStruct(_W,{head:c,indexEnc:F,bodyEnc:C});let I=T.result();return b(I)}async function kl(Z,X,W){let[V,l]=_W.decode(new j(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,R=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,R.publicKey))return Y(3);let C=await X.blake3(G);if(!n(C,K.hsh))return Y(19);let F=new j(G),d=[];for(let c=0;c<K.num;c++){let[T,I]=F.readStruct(aW);if(I!==0)return Y(I);d.push(T)}if(d.length!==K.num)return Y(14);let k=[];for(let c of d){let T=W.deriveCipher(c.kdm,"decrypt"),I;try{I=await T.decrypt(c.headCph)}catch{return Y(20)}let[S,Q]=JZ.decode(new j(I));if(Q!==0)return Y(Q);let p;if(c.lenBody>0&&c.offBody!==void 0){if(S.hsh===void 0)return Y(14);let L=m.slice(c.offBody,c.offBody+c.lenBody);try{p=await T.decrypt(L)}catch{return Y(20)}let z=await X.blake3(p);if(!n(z,S.hsh))return Y(19)}k.push({head:S,body:p})}return b(k)}async function cl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new i,K=l.writeStruct(s,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return tX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function tX({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 R=Z.getTime()-G.ts.getTime(),J,C=V?.length??0;if(V&&C>0)J=await l.blake3(V);return b({eid:X,off:R,ctr:W,len:C,hsh:J})}function Tl(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 GX(Z,X){let W=Array.from(Z);W.sort(Tl);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 Il(Z){let X=new i,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 xX(Z,X){let W=[];for(let V of Z){let[l,K]=Il(V);if(K!==0||!l)return Y(K);W.push(l)}return b(await GX(W,X))}var xJ=Symbol("MasterSeed"),zJ=Symbol("SealedMasterKey"),kZ=32,sW=24+kZ+16;function VZ(Z){if(Z.byteLength!==kZ)return Y(10);return b(Z)}function yZ(Z){if(Z.byteLength!==sW)return Y(10);return b(Z)}var HJ=Symbol("EntityID");function Ll(Z){return"type"in Z}var gJ=Symbol("DerivationSeed"),hJ=Symbol("PublicKey"),PJ=Symbol("PrivateKey"),UJ=Symbol("HostSpecificKeyPair"),jJ=Symbol("Hash");function mK(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 YK(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return b(V)}let X=EW(Z.bod);if(mK(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 zX{applier;emitter=new PZ;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[R,J]=YK(m);if(W.push(J),J!==0)continue;X.push(R)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let R=W[m],J=V[m];if(R!==0){G.push(R);continue}if(J!==0){G.push(J);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 rW={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 f="entities",eX="entity_type_created_at",eW="entity_type_updated_at",ZV="entity_type_group_id",XV="entity_type_parent_id",mX="entity_tags",Ql="db",Sl=13;function RK(Z){return"typ"in Z}function JK(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 CK(Z){if(!v(Z))return{eid:H(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return JK(Z)}function YX(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 tW(Z){if(RK(Z))return YX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class WV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=bK().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(f,"readwrite"),K=l.objectStore(f);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 J=0;J<m.length;J++)if(m[J]===void 0)m[J]=18;G({stats:m,types:X,eids:W})};let R=new Map;for(let J=0;J<Z.length;J++){let C=Z[J],F=H(C.eid),d={op:C,index:J},k=R.get(F);if(k)k.push(d);else R.set(F,[d])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let d=F.result,k=d?tW(d):void 0,c=!1;for(let{op:T,index:I}of C){let[S,Q]=RX(k,T);if(Q!==0){m[I]=Q;continue}if(S===void 0){m[I]=12;continue}c=!0;for(let p of JX(k,S))X.add(p);k=S}if(c)W.push(C[0].op.eid);if(k){let T=K.put(CK(k));T.onerror=(I)=>{I.preventDefault();for(let{index:S}of C)m[S]=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(f,"readwrite"),W=X.objectStore(f);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(f,"readonly").objectStore(f);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(b(void 0));else K(b(tW(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||!v(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(f,"readonly").objectStore(f).index(eW);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(b(R.map(YX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(ZV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(b(m.map(YX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(eX);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(b(G.map(YX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(mX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(YX);K(b(R))},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(f,"readonly").objectStore(f).index(XV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(YX);K(b(R))},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(f,"readonly").objectStore(f).index(eX);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(f,"readonly").objectStore(f),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(NX(tW(R))),m.continue()}else xX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function FK(Z,X){if(!Z.objectStoreNames.contains(f))Z.createObjectStore(f,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(f);if(!W.indexNames.contains(eX))W.createIndex(eX,["typ","crd"],{unique:!1});if(!W.indexNames.contains(eW))W.createIndex(eW,["typ","upd"],{unique:!1});if(!W.indexNames.contains(ZV))W.createIndex(ZV,["typ","gid"],{unique:!1});if(!W.indexNames.contains(XV))W.createIndex(XV,["typ","pid"],{unique:!1});if(W.indexNames.contains(mX)){if(W.index(mX).keyPath!=="tgs")W.deleteIndex(mX)}if(!W.indexNames.contains(mX))W.createIndex(mX,"tgs",{unique:!1,multiEntry:!0})}function bK(){return new Promise((Z,X)=>{let W=indexedDB.open(Ql,Sl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{FK(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Ql} → v${Sl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function yl(){let Z=new WV;return await Z.init(),Z}class ZW{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&&v(W))this.unindex(X,W);if(this.ents.set(X,Z),v(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(v(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,R]=RX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of JX(G,m))X.add(J);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||!v(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 R of m.values())if(R.updatedAt>=l.start&&R.updatedAt<=l.end)G.push(R)}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(v(G)&&G.type===Z&&G.pid&&n(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(v(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(v(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(v(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(v(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(v(W)&&W.type===Z)X+=1;return b(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(NX(W));return xX(X,Z)}}async function VV(Z){let X=await yl();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 ZW(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=LK(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||!dK(K,G)){if(v(G))X.add(G.type);if(K!==void 0&&v(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),v(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||IK(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||!v(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 dK(Z,X){if(v(Z)!==v(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!n(Z.eid,X.eid))return!1;if(!v(Z)||!v(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(!cK(Z.pid,X.pid))return!1;if(!kK(Z.tags,X.tags))return!1;return TK(Z.body,X.body)}function kK(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 cK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return n(Z,X)}function TK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return n(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return n(vZ(Z),vZ(X))}catch{return!1}}function IK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function LK(Z,X){let W=new Set,V=[];for(let l of X){let K=H(l.eid),G=Z.ents.get(K),[m,R]=RX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of JX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function XW(Z){if(Z instanceof HX){let X=new zX((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 zX((X)=>Z.apply(X),()=>Z.clear())}function v(Z){return"type"in Z}function QK(Z){return!v(Z)}function pl(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 NX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function lV(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(Ll(X)){let G=pl(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 JX(Z,X){let W=new Set;if(Z!==void 0&&v(Z))W.add(Z.type);if(v(X))W.add(X.type);return[...W]}var SK={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 WW{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 VW=100;class gX{timer=null;delayMs;work;tail=new WW;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 Ml(Z){let X=new j(Z.eid),[W,V]=s.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function yK(Z,X){let W=Ml(Z),V=Ml(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 CX(Z,X){return Z.slice().sort((W,V)=>yK(X(W),X(V)))}var oZ={phase:"idle"},FX=50;function lW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function KW(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 xl(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 KV(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 J=K;if(K+=1,J>=V)return;l[J]=await W(Z[J],J)}},R=[];for(let J=0;J<G;J++)R.push(m());return await Promise.all(R),l}async function GW(Z,X,W,V){let l=new j(Z.headCph),[K,G]=l.readStruct(aX);if(G!==0)return Y(G);let{sig:m,kdm:R,headCph:J}=K;if(!await V.checkSigEd25519(m,J,X))return Y(3);let F=W.deriveCipher(R,"decrypt"),d;try{d=await F.decrypt(J)}catch{return Y(20)}return b({kdm:R,headEnc:d})}var pZ="f",EZ="t",IZ="e";function pK(Z){return Z===pZ||Z===EZ||Z===IZ}function bX(Z){if(Z===!0||Z===EZ)return EZ;if(Z===IZ)return IZ;return pZ}function MK(Z){return bX(Z.apld)===pZ}function GV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function $Z(Z,X,W){if(Z.apld=X,X===IZ&&W!==void 0)Z.err=W;else delete Z.err}async function OZ(Z,X,W,V){let l=V?.body!==!1,K=bX(X.apld),G=X.body,m=G?.length??0,R;if(l&&G&&m>0)R=await W.blake3(G);let J={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:R},C={hash:Z,head:J,apld:K};if(l&&G!==void 0)C.body=G;if(K===IZ&&X.err!==void 0)C.err=X.err;return C}var mV=1048576,YV=1048576,Nl=64;function xK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function zK(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 R of K){if(R.status!==0){console.error("push err",R);continue}let J=l[R.idx];if(!J){console.error("no hash",R);continue}await X.uploads.deq(W,[J])}let m=await X.hosts.get(W);if(m){let R=m.lastSeq,J=R,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===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function zl(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:R}of l){let J=W.get(m);if(!J)continue;G.push({dl:J,bodyCph:R})}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:J,bodyCph:C}of V){let{head:F,kdm:d,seq:k,host:c}=J,[T,I]=await Hl(J,W);if(I!==0||!T){let P=m.get(c)??[];P.push(k),m.set(c,P);continue}let{headEnc:S,headEncHash:Q}=T,p=X.deriveCipher(d,"decrypt"),[L,z]=await wW(S,C,p,W,Q);if(z!==0||!L){let P=m.get(c)??[];P.push(k),m.set(c,P);continue}let g={head:F,body:L.bod},E=L.headHash;G.push({key:E,data:Pl(g)}),l.push(g),K.push(E);let u=m.get(c)??[];u.push(k),m.set(c,u)}let R=await Z.messages.add(G);for(let[J,C]of m)await Z.downloads.deq(J,C);for(let J=0;J<R.length;J++){let C=R[J];if(C!==0&&C!==15)console.error("ERR storing",M[C],"for message",J)}return b({parts:l,hashes:K})}async function Hl(Z,X){let W=Z.headEnc;if(!W){let l=new i,K=l.writeStruct(JZ,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 gl(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[J,C]=await Hl(G,W);if(C!==0||!J)continue;m=H(J.headEncHash)}if(!V.has(m))continue;let R=K.get(G.host)??[];R.push(G.seq),K.set(G.host,R)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function RV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let R=await Z.identity(),J=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let d=C.length,k=G??FX,c=m??Nl;if(K&&d>0)K({phase:"peek",host:V.label,done:0,total:d});let T=0,I=await KV(C,c,async(Q)=>{let[p,L]=await GW(Q,R.publicKey,W,l),z;if(L!==0||!p)z={ok:!1,seq:Q.seq,stat:L};else{let g=await l.blake3(p.headEnc);z={ok:!0,seq:Q.seq,kdm:p.kdm,headEnc:p.headEnc,headEncHash:g}}if(T+=1,K&&lW(T,d,k))K({phase:"peek",host:V.label,done:T,total:d});return z}),S=new Set;for(let Q of I){if(!Q.ok){console.error("peek: decrypting item head",Q.stat);continue}let p=H(Q.headEncHash);if(await X.messages.has(Q.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[Q.headEncHash]),await X.downloads.deq(V.label,[Q.seq]);continue}if(S.has(p)){await X.downloads.deq(V.label,[Q.seq]);continue}let z=new j(Q.headEnc),[g,E]=z.readStruct(JZ);if(E!==0){console.error("peek: reading item head",E);continue}S.add(p),J.push({kdm:Q.kdm,head:g,seq:Q.seq,host:V.label,headEnc:Q.headEnc,headEncHash:Q.headEncHash})}if(await X.downloads.enq(J),C.length>0){let Q=Math.max(...C.map((p)=>p.seq));await X.hosts.recordStats(V.label,{lastSeq:Q})}if(K)K({phase:"peek",host:V.label,done:d,total:d});return 0}async function hl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??mV,G=await X.uploads.list(W.label),m=G.length,R=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let J=[],C=[],F=0,d=async()=>{if(J.length<1)return 0;let k=J.length,c=await zK(Z,X,W.label,J,C);if(J=[],C=[],F=0,c===0){if(R+=k,l)l({phase:"push",host:W.label,done:R,total:m})}return c};for(let k of G){let c=await X.messages.get(k);if(!c){R+=1;continue}let T={...c.head,bod:c.body},[I,S]=await Z.seal(T);if(S!==0)return S;if(!I)return 12;let Q=xK(I);if(J.length>0&&F+Q>K){let p=await d();if(p!==0)return p}if(J.push(I),C.push(k),F+=Q,F>=K){let p=await d();if(p!==0)return p}}return d()}async function JV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??YV,J=await X.downloads.list(),C=Array.from(J).filter((I)=>I.host===V.label);if(C.length<1)return 15;let F=CX(C,(I)=>I.head),d=xl(F,(I)=>I.head.len,R),k=F.length,c=0;if(G)G({phase:"pull",host:V.label,done:0,total:k});let T=zl(Z,d[0]);for(let I=0;I<d.length;I++){let[S,Q]=await T;if(Q!==0||!S)return Q;if(c+=d[I].length,G)G({phase:"pull",host:V.label,done:c,total:k});let p=d[I+1];if(p)T=zl(Z,p);if(G)G({phase:"open",host:V.label,done:c,total:k});let L=CX(S,(g)=>g.dl.head),[,z]=await NK(X,W,l,L);if(z!==0)return z;if(m){if(G)G({phase:"exec",host:V.label,done:c,total:k});await m()}}return 0}function Pl({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:pZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function Ul(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new j(Z),[F,d]=C.readStructs(_X);if(d!==0){console.error("Failed decoding notif",M[d]);return}let k=!1,T=(await W.hosts.get(R))?.lastSeq,I=[],S=!1;for(let L of F){let[z,g]=await GW({seq:L.seq,headCph:L.headCph},J.publicKey,V,K);if(g!==0){console.error("Failed decrypting notif",M[g]);continue}let E=await K.blake3(z.headEnc);if(await W.messages.has(E))continue;let u=new j(z.headEnc),[P,B]=u.readStruct(JZ);if(B!==0){console.error("Failed to parse head",M[B]);continue}if(!L.bodyCph&&P.len>0)S=!0,await W.downloads.enq([{seq:L.seq,host:R,kdm:z.kdm,head:P,headEnc:z.headEnc,headEncHash:E}]);else I.push({...z,head:P,bodyCph:L.bodyCph,headEncHash:E});if(T===void 0||L.seq!==T+1)console.log("out of seq",L.seq,T),k=!0;else T=L.seq}if(T!==void 0)await W.hosts.touch(l.label,T);let Q=[];for(let L of I){let z=V.deriveCipher(L.kdm,"decrypt"),[g,E]=await wW(L.headEnc,L.bodyCph,z,K);if(E!==0){console.error("Failed to open body",M[E]);continue}Q.push({key:L.headEncHash,data:Pl({head:L.head,body:g.bod})})}let p=await W.messages.add(Q);for(let L=0;L<p.length;L++){let z=p[L];if(z!==0&&z!==15)console.error("ERR storing",M[z],"for message",L)}if(G&&Q.length>0)G({phase:"open",host:l.label,done:Q.length,total:Q.length});if(k||S||Q.length>0)m()}async function CV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:R,onProgress:J,peekProgressEvery:C,peekConcurrency:F}=Z,d=await l.identity(),[k,c]=await l.peek(0);if(c!==0)return Y(c);let T=k.length,I=C??FX,S=F??Nl;if(J&&T>0)J({phase:"peek",host:m.label,done:0,total:T});let Q=0,p=await KV(k,S,async(h)=>{let[O,U]=await GW(h,d.publicKey,G,R),A;if(U!==0||!O)A={ok:!1,seq:h.seq,stat:U};else{let N=await R.blake3(O.headEnc);A={ok:!0,seq:h.seq,kdm:O.kdm,headEnc:O.headEnc,headEncHash:N}}if(Q+=1,J&&lW(Q,T,I))J({phase:"peek",host:m.label,done:Q,total:T});return A}),L=new Map;for(let h of p){if(!h.ok)continue;let O=H(h.headEncHash),U=L.get(O);if(U)U.count+=1;else L.set(O,{hash:h.headEncHash,count:1,sample:h})}let z=0,g=[];for(let h of L.values()){if(h.count>1)z+=h.count-1;g.push(h.hash)}let E=k.length,u=L.size,P=await GX(g,R),B=[],D=0;for(let h of L.values()){if(await K.messages.has(h.hash)){await K.uploads.deq(m.label,[h.hash]);continue}if(D+=1,!W)continue;let U=h.sample,A=new j(U.headEnc),[N,_]=A.readStruct(JZ);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 o=0;if(V){let h=await K.messages.listKeys(),O=new Set(L.keys()),U=[];for(let A of h)if(!O.has(H(A)))o+=1,U.push(A);if(U.length>0)await K.uploads.enq(m.label,U)}else{let h=await K.messages.listKeys(),O=new Set(L.keys());for(let U of h)if(!O.has(H(U)))o+=1}let y=k.length>0?Math.max(...k.map((h)=>h.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:y}),J)J({phase:"peek",host:m.label,done:T,total:T});return b({msgcheck:P,numBags:E,uniqueMsgs:u,numDupes:z,missingLocal:D,missingHost:o})}class dX{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new WW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=FX;lastProgress=oZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=mV,m=YV,R){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=R;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new cZ(()=>this.getClientState()),this.xferState=new cZ(()=>this.getXferState()),this.scheduledSync=new gX(VW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(J){console.error("Debounced sync failed:",J)}})}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 i;m.writeStruct(JZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:pZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(J),V.push({key:J,data:C})}await this.store.messages.add(V),await gl(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:pZ});if(Z.length<1)return[];let X=CX(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&&GV(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 cl({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 tX({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,R]=G.readStruct(s);if(R!==0)return Y(R);let J=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:J+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]=KX({id:m.id,ts:K});if(c!==0)return Y(c);let[T,I]=await tX({now:K,eid:k,ctr:0,bod:X,crypto:l});if(I!==0)return Y(I);let Q=(await this.apply([{head:T,body:X}]))[0];if(Q!==0&&Q!==15)return Y(Q??12);return b(T)}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=vZ({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,J=vZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,J,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 lV(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 KX({id:Z,ts:V});let l=await W.genRandomBytes(8);return KX({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},R=await RV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await hl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await JV(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 GX(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 R={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[J,C]=await CV({...R,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!J)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),b(J);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 CV({...R,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 R={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await RV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await JV(R);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=CX(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 J=l;J<W.length&&G<100&&K<102400;J++)K+=W[J].head.len,G++,m=J+1;let R=W.slice(l,m);await this.applyStored(R),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=oZ,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,R]=await kl(G,W,K);if(R!==0)return R;console.timeEnd("import: decoding file...");let J=0;while(J<m.length){let C=0,F=0,d=J;for(let T=J;T<m.length&&F<100&&C<102400;T++)C+=m[T].head.len,F++,d=T+1;let k=m.slice(J,d);console.time(`import: applying [${J}, ${d}]`);let c=await this.apply(k,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${d}]`);for(let T=0;T<k.length;T++){let I=c[T];if(I!==0&&I!==15)console.warn(`failed to import msg ${J+T}: ${M[I]}`)}if(l)queueMicrotask(()=>l(d,m.length,0));this.emitProgress({phase:"import",done:d,total:m.length}),J=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 dl("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 KW(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,R=l.get(Z.label);if(R){if(R.isConnected())return;try{R.closeListener()}catch{}l.delete(Z.label)}let J=await G.seed.load();if(!J)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new rX(J,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:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return Ul(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 qZ=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function mW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function FV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!FV(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 bV(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 jl(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function dV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var MZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var HK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!HK)throw Error("Non little-endian hardware is not supported");function gK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function YW(Z){if(typeof Z==="string")Z=gK(Z);else if(FV(Z))Z=RW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function ul(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function il(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 El=(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)}},R=!1;return{encrypt(C,F){if(R)throw Error("cannot encrypt() twice with same key + nonce");return R=!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 kV(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&&!hK(X))throw Error("invalid output, must be aligned");return X}function hK(Z){return Z.byteOffset%4===0}function RW(Z){return Uint8Array.from(Z)}function LZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function hX(Z=32){if(qZ&&typeof qZ.getRandomValues==="function")return qZ.getRandomValues(new Uint8Array(Z));if(qZ&&typeof qZ.randomBytes==="function")return qZ.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var Bl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),PK=Bl("expand 16-byte k"),UK=Bl("expand 32-byte k"),jK=MZ(PK),uK=MZ(UK);function x(Z,X){return Z<<X|Z>>>32-X}function cV(Z){return Z.byteOffset%4===0}var JW=64,iK=16,wl=4294967295,Ol=new Uint32Array;function EK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(JW),C=MZ(J),F=cV(l)&&cV(K),d=F?MZ(l):Ol,k=F?MZ(K):Ol;for(let c=0;c<R;G++){if(Z(X,W,V,C,G,m),G>=wl)throw Error("arx: counter overflow");let T=Math.min(JW,R-c);if(F&&T===JW){let I=c/4;if(c%4!==0)throw Error("arx: invalid block position");for(let S=0,Q;S<iK;S++)Q=I+S,k[Q]=d[Q]^C[S];c+=JW;continue}for(let I=0,S;I<T;I++)S=c+I,K[S]=l[S]^J[I];c+=T}}function Dl(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=ul({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return mW(l),mW(G),dV(K),dV(W),(m,R,J,C,F=0)=>{a(m),a(R),a(J);let d=J.length;if(C===void 0)C=new Uint8Array(d);if(a(C),mW(F),F<0||F>=wl)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,T,I;if(c===32)k.push(T=RW(m)),I=uK;else if(c===16&&W)T=new Uint8Array(32),T.set(m),T.set(m,16),I=jK,k.push(T);else throw Error(`arx: invalid 32-byte key, got length=${c}`);if(!cV(R))k.push(R=RW(R));let S=MZ(T);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(I,S,MZ(R.subarray(0,16)),S),R=R.subarray(16)}let Q=16-l;if(Q!==R.length)throw Error(`arx: nonce must be ${Q} or 16 bytes`);if(Q!==12){let L=new Uint8Array(12);L.set(R,K?0:12-R.length),R=L,k.push(R)}let p=MZ(R);return EK(Z,I,S,p,J,C,F,G),LZ(...k),C}}var t=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class Al{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=YW(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),R=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|R<<8)&8191,this.r[9]=R>>>5&127;for(let J=0;J<8;J++)this.pad[J]=t(Z,16+2*J)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],R=K[2],J=K[3],C=K[4],F=K[5],d=K[6],k=K[7],c=K[8],T=K[9],I=t(Z,X+0),S=t(Z,X+2),Q=t(Z,X+4),p=t(Z,X+6),L=t(Z,X+8),z=t(Z,X+10),g=t(Z,X+12),E=t(Z,X+14),u=l[0]+(I&8191),P=l[1]+((I>>>13|S<<3)&8191),B=l[2]+((S>>>10|Q<<6)&8191),D=l[3]+((Q>>>7|p<<9)&8191),o=l[4]+((p>>>4|L<<12)&8191),y=l[5]+(L>>>1&8191),h=l[6]+((L>>>14|z<<2)&8191),O=l[7]+((z>>>11|g<<5)&8191),U=l[8]+((g>>>8|E<<8)&8191),A=l[9]+(E>>>5|V),N=0,_=N+u*G+P*(5*T)+B*(5*c)+D*(5*k)+o*(5*d);N=_>>>13,_&=8191,_+=y*(5*F)+h*(5*C)+O*(5*J)+U*(5*R)+A*(5*m),N+=_>>>13,_&=8191;let XZ=N+u*m+P*G+B*(5*T)+D*(5*c)+o*(5*k);N=XZ>>>13,XZ&=8191,XZ+=y*(5*d)+h*(5*F)+O*(5*C)+U*(5*J)+A*(5*R),N+=XZ>>>13,XZ&=8191;let mZ=N+u*R+P*m+B*G+D*(5*T)+o*(5*c);N=mZ>>>13,mZ&=8191,mZ+=y*(5*k)+h*(5*d)+O*(5*F)+U*(5*C)+A*(5*J),N+=mZ>>>13,mZ&=8191;let q=N+u*J+P*R+B*m+D*G+o*(5*T);N=q>>>13,q&=8191,q+=y*(5*c)+h*(5*k)+O*(5*d)+U*(5*F)+A*(5*C),N+=q>>>13,q&=8191;let SZ=N+u*C+P*J+B*R+D*m+o*G;N=SZ>>>13,SZ&=8191,SZ+=y*(5*T)+h*(5*c)+O*(5*k)+U*(5*d)+A*(5*F),N+=SZ>>>13,SZ&=8191;let rZ=N+u*F+P*C+B*J+D*R+o*m;N=rZ>>>13,rZ&=8191,rZ+=y*G+h*(5*T)+O*(5*c)+U*(5*k)+A*(5*d),N+=rZ>>>13,rZ&=8191;let tZ=N+u*d+P*F+B*C+D*J+o*R;N=tZ>>>13,tZ&=8191,tZ+=y*m+h*G+O*(5*T)+U*(5*c)+A*(5*k),N+=tZ>>>13,tZ&=8191;let eZ=N+u*k+P*d+B*F+D*C+o*J;N=eZ>>>13,eZ&=8191,eZ+=y*R+h*m+O*G+U*(5*T)+A*(5*c),N+=eZ>>>13,eZ&=8191;let ZX=N+u*c+P*k+B*d+D*F+o*C;N=ZX>>>13,ZX&=8191,ZX+=y*J+h*R+O*m+U*G+A*(5*T),N+=ZX>>>13,ZX&=8191;let XX=N+u*T+P*c+B*k+D*d+o*F;N=XX>>>13,XX&=8191,XX+=y*C+h*J+O*R+U*m+A*G,N+=XX>>>13,XX&=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]=q,l[4]=SZ,l[5]=rZ,l[6]=tZ,l[7]=eZ,l[8]=ZX,l[9]=XX}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;LZ(W)}update(Z){bV(this);let{buffer:X,blockLen:W}=this;Z=YW(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(){LZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){bV(this),jl(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 OK(Z){let X=(V,l)=>Z(l).update(YW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var TV=OK((Z)=>new Al(Z));function BK(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],R=X[1],J=X[2],C=X[3],F=Z[1],d=W[0],k=W[1],c=l,T=0,I=Z[2],S=X[4],Q=X[5],p=X[6],L=X[7],z=Z[3],g=G,E=m,u=R,P=J,B=C,D=F,o=d,y=k,h=c,O=T,U=I,A=S,N=Q,_=p,XZ=L,mZ=z;for(let SZ=0;SZ<K;SZ+=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),O^=x(D+E|0,7),_^=x(O+D|0,9),E^=x(_+O|0,13),D^=x(E+_|0,18),XZ^=x(U+o|0,7),u^=x(XZ+U|0,9),o^=x(u+XZ|0,13),U^=x(o+u|0,18),P^=x(mZ+A|0,7),y^=x(P+mZ|0,9),A^=x(y+P|0,13),mZ^=x(A+y|0,18),E^=x(g+P|0,7),u^=x(E+g|0,9),P^=x(u+E|0,13),g^=x(P+u|0,18),o^=x(D+B|0,7),y^=x(o+D|0,9),B^=x(y+o|0,13),D^=x(B+y|0,18),A^=x(U+O|0,7),h^=x(A+U|0,9),O^=x(h+A|0,13),U^=x(O+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 q=0;V[q++]=G+g|0,V[q++]=m+E|0,V[q++]=R+u|0,V[q++]=J+P|0,V[q++]=C+B|0,V[q++]=F+D|0,V[q++]=d+o|0,V[q++]=k+y|0,V[q++]=c+h|0,V[q++]=T+O|0,V[q++]=I+U|0,V[q++]=S+A|0,V[q++]=Q+N|0,V[q++]=p+_|0,V[q++]=L+XZ|0,V[q++]=z+mZ|0}function wK(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],R=X[3],J=Z[1],C=W[0],F=W[1],d=W[2],k=W[3],c=Z[2],T=X[4],I=X[5],S=X[6],Q=X[7],p=Z[3];for(let z=0;z<20;z+=2)R^=x(l+I|0,7),d^=x(R+l|0,9),I^=x(d+R|0,13),l^=x(I+d|0,18),k^=x(J+K|0,7),S^=x(k+J|0,9),K^=x(S+k|0,13),J^=x(K+S|0,18),Q^=x(c+C|0,7),G^=x(Q+c|0,9),C^=x(G+Q|0,13),c^=x(C+G|0,18),m^=x(p+T|0,7),F^=x(m+p|0,9),T^=x(F+m|0,13),p^=x(T+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(J+R|0,7),F^=x(C+J|0,9),R^=x(F+C|0,13),J^=x(R+F|0,18),T^=x(c+k|0,7),d^=x(T+c|0,9),k^=x(d+T|0,13),c^=x(k+d|0,18),I^=x(p+Q|0,7),S^=x(I+p|0,9),Q^=x(S+I|0,13),p^=x(Q+S|0,18);let L=0;V[L++]=l,V[L++]=J,V[L++]=c,V[L++]=p,V[L++]=C,V[L++]=F,V[L++]=d,V[L++]=k}var IV=Dl(BK,{counterRight:!0,extendNonceFn:wK}),LV=El({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=kV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),LZ(l),IV(Z,X,V,V);let G=TV(K,l);return V.set(G,16),LZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=kV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),LZ(l);let m=IV(Z,X,l,l),R=TV(G,m);if(!il(K,R))throw Error("invalid tag");return IV(Z,X,V.subarray(16),V.subarray(16)),LZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function DK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function PX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function fZ(Z,...X){if(!DK(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 CW(Z,X){fZ(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function vl(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function kX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function cX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function jX(Z,X){return Z<<32-X|Z>>>X}var ol=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function $l(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var ql=ol?(Z)=>Z:(Z)=>$l(Z);function AK(Z){for(let X=0;X<Z.length;X++)Z[X]=$l(Z[X]);return Z}var lZ=ol?(Z)=>Z:AK;function vK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function TX(Z){if(typeof Z==="string")Z=vK(Z);return fZ(Z),Z}class QV{}function fl(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 nl=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var FW=BigInt(4294967295),_l=BigInt(32);function SV(Z,X=!1){if(X)return{h:Number(Z&FW),l:Number(Z>>_l&FW)};return{h:Number(Z>>_l&FW)|0,l:Number(Z&FW)|0}}function xZ(Z,X,W,V,l){return Z=Z+X+l|0,V=jX(V^Z,16),W=W+V|0,X=jX(X^W,12),{a:Z,b:X,c:W,d:V}}function zZ(Z,X,W,V,l){return Z=Z+X+l|0,V=jX(V^Z,8),W=W+V|0,X=jX(X^W,7),{a:Z,b:X,c:W,d:V}}class yV extends QV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,PX(Z),PX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=kX(this.buffer)}update(Z){UX(this),Z=TX(Z),fZ(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 R=Math.min(X-this.pos,l-m),J=K+m;if(R===X&&!(J%4)&&m+R<l){let C=new Uint32Array(G,J,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+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){UX(this),CW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,cX(this.buffer.subarray(X)),lZ(W),this.compress(W,0,!0),lZ(W);let V=kX(Z);this.get().forEach((l,K)=>V[K]=ql(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 pV(Z,X,W,V,l,K,G,m,R,J,C,F,d,k,c,T,I,S,Q,p){let L=0;for(let z=0;z<V;z++)({a:l,b:R,c:d,d:I}=xZ(l,R,d,I,W[X+Z[L++]])),{a:l,b:R,c:d,d:I}=zZ(l,R,d,I,W[X+Z[L++]]),{a:K,b:J,c:k,d:S}=xZ(K,J,k,S,W[X+Z[L++]]),{a:K,b:J,c:k,d:S}=zZ(K,J,k,S,W[X+Z[L++]]),{a:G,b:C,c,d:Q}=xZ(G,C,c,Q,W[X+Z[L++]]),{a:G,b:C,c,d:Q}=zZ(G,C,c,Q,W[X+Z[L++]]),{a:m,b:F,c:T,d:p}=xZ(m,F,T,p,W[X+Z[L++]]),{a:m,b:F,c:T,d:p}=zZ(m,F,T,p,W[X+Z[L++]]),{a:l,b:J,c,d:p}=xZ(l,J,c,p,W[X+Z[L++]]),{a:l,b:J,c,d:p}=zZ(l,J,c,p,W[X+Z[L++]]),{a:K,b:C,c:T,d:I}=xZ(K,C,T,I,W[X+Z[L++]]),{a:K,b:C,c:T,d:I}=zZ(K,C,T,I,W[X+Z[L++]]),{a:G,b:F,c:d,d:S}=xZ(G,F,d,S,W[X+Z[L++]]),{a:G,b:F,c:d,d:S}=zZ(G,F,d,S,W[X+Z[L++]]),{a:m,b:R,c:k,d:Q}=xZ(m,R,k,Q,W[X+Z[L++]]),{a:m,b:R,c:k,d:Q}=zZ(m,R,k,Q,W[X+Z[L++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:d,v9:k,v10:c,v11:T,v12:I,v13:S,v14:Q,v15:p}}var QZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},NZ=nl.slice(),al=(()=>{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 MV extends yV{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();fZ(K,32),this.IV=kX(K),lZ(this.IV),this.flags=X|QZ.KEYED_HASH}else if(l){let K=TX(V),G=new MV({dkLen:32},QZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=kX(G),lZ(this.IV),this.flags=X|QZ.DERIVE_KEY_MATERIAL}else this.IV=NZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=vl(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=SV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:d,v5:k,v6:c,v7:T,v8:I,v9:S,v10:Q,v11:p,v12:L,v13:z,v14:g,v15:E}=pV(al,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],NZ[0],NZ[1],NZ[2],NZ[3],G,m,K,X);l[0]=R^I,l[1]=J^S,l[2]=C^Q,l[3]=F^p,l[4]=d^L,l[5]=k^z,l[6]=c^g,l[7]=T^E}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:R}=this;return Z.state.set(V.slice()),Z.stack=m.map((J)=>Uint32Array.from(J)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=R,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,cX(this.state,this.buffer32,this.IV,this.bufferOut32),cX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=SV(BigInt(this.chunkOut++));lZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:d,v6:k,v7:c,v8:T,v9:I,v10:S,v11:Q,v12:p,v13:L,v14:z,v15:g}=pV(al,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],NZ[0],NZ[1],NZ[2],NZ[3],G,K,X,W);l[0]=m^T,l[1]=R^I,l[2]=J^S,l[3]=C^Q,l[4]=F^p,l[5]=d^L,l[6]=k^z,l[7]=c^g,l[8]=Z[0]^T,l[9]=Z[1]^I,l[10]=Z[2]^S,l[11]=Z[3]^Q,l[12]=Z[4]^p,l[13]=Z[5]^L,l[14]=Z[6]^z,l[15]=Z[7]^g,lZ(V),lZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,cX(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),fZ(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 PX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(CW(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 sl=fl((Z)=>new MV(Z));var oK=32,fF=Symbol("X25519Sk");function rl(Z){if(Z.byteLength!==oK)return Y(10);return b(Z)}var w=(1n<<255n)-19n,$K=121665n,tl=new Uint8Array(32);tl[0]=9;function el(Z){let X=0n;for(let W=Z.length-1;W>=0;W--)X=X<<8n|BigInt(Z[W]);return X}function qK(Z){let X=new Uint8Array(32),W=(Z%w+w)%w;for(let V=0;V<32;V++)X[V]=Number(W&0xffn),W>>=8n;return X}function fK(Z){let X=Z.slice();return X[31]&=127,el(X)}function nK(Z){let X=Z.slice();return X[0]&=248,X[31]&=127,X[31]|=64,X}function bW(Z,X,W){let V=-Z,l=(X^W)&V;return[X^l,W^l]}function _K(Z){let X=w-2n,W=(Z%w+w)%w,V=1n;while(X>0n){if(X&1n)V=V*W%w;W=W*W%w,X>>=1n}return V}function aK(Z,X){let W=nK(Z),V=fK(X),l=1n,K=0n,G=V,m=1n,R=0n,J=el(W);for(let C=254;C>=0;C--){let F=J>>BigInt(C)&1n;R^=F,[l,G]=bW(R,l,G),[K,m]=bW(R,K,m),R=F;let d=(l+K)%w,k=d*d%w,c=(l-K+w)%w,T=c*c%w,I=(k-T+w)%w,S=(G+m)%w,p=(G-m+w)%w*d%w,L=S*c%w,z=(p+L)%w,g=(p-L+w)%w;G=z*z%w,m=V*g*g%w,l=k*T%w,K=I*(k+$K*I)%w}return[l,G]=bW(R,l,G),[K,m]=bW(R,K,m),W.fill(0),qK(l*_K(K)%w)}function Z0(Z){return aK(Z,tl)}var xV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function X0(Z){let X=new Uint8Array(xV.length+32);return X.set(xV),X.set(Z.subarray(0,32),xV.length),X}var zV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);function W0(Z){let X=new Uint8Array(zV.length+32);return X.set(zV),X.set(Z.subarray(0,32),zV.length),X}function V0(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function HZ(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class nZ{verifyKeys=new Map;async genRandomBytes(Z){return hX(Z)}async gen256BitSecureRandomSeed(){return hX(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=hX(24),l=LV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return LV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=X0(X),V=HZ(W),l;try{let J=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",J)}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 R=new Uint8Array(64);return R.set(X,0),R.set(m,32),{keyType:"ed25519",privateKey:R,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=X0(X),V=HZ(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",HZ(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=V0(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,HZ(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=V0(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,HZ(Z),HZ(V))}catch{return!1}}async blake3(Z){return sl(Z)}async genX25519(){let Z=await hX(32);Z[0]&=248,Z[31]&=127,Z[31]|=64;let[X,W]=rl(Z);if(W!==0||X===void 0)throw Z.fill(0),Error("X25519 scalar brand failed");let V=Z0(X),l=W0(X),K=HZ(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 R=BW(m.x);if(m.d=void 0,!n(R,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=W0(Z),V=HZ(W);try{let l=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"X25519"},!1,["deriveBits"]),K=await globalThis.crypto.subtle.importKey("raw",HZ(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 sK=new nZ,IX=sK;import{useEffect as PW,useState as vV}from"react";class NV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(CZ,"readwrite"),V=W.objectStore(CZ);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(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=`${Z}:${m}`;l.delete(R)}})}async list(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);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(CZ,"readonly").objectStore(CZ);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(CZ,"readwrite"),X=Z.objectStore(CZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function l0(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function rK(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 HV{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(rK(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(l0(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(l0))},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 gV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction($,"readwrite"),W=X.objectStore($);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],R=H(G),J=W.put(m,R);J.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);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($,"readonly").objectStore($);return new Promise((V,l)=>{let K=H(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await OZ(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($,"readonly").objectStore($);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(uX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.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})=>OZ(F,d,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(uX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction($,"readonly").objectStore($);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($,"readonly").objectStore($);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let R=m.target.result;if(R){let{key:J,value:C}=R;if(n(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:J,data:C}}R.continue()}else if(K){let J=e(K.key);V(await OZ(J,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($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=H(G),R=V.get(m);R.onsuccess=()=>{let J=R.result;if(!J)return;$Z(J,EZ),V.put(J,m)},R.onerror=(J)=>{J.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let R=H(G),J=V.get(R);J.onsuccess=()=>{let C=J.result;if(!C)return;$Z(C,IZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction($,"readwrite"),X=Z.objectStore($);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var _Z={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 dW=1,hV={encode(Z,X){if(X.v!==dW)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(_Z,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==dW)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,R]=Z.readVarInt();if(R!==0)return Y(R);if(m===void 0||m<0)return Y(10);let J=[];for(let C=0;C<m;C++){let[F,d]=Z.readStruct(_Z);if(d!==0)return Y(d);if(F===void 0)return Y(14);J.push(F)}return b({v:dW,masterSeed:K,hosts:J})}};function K0(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:dW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var kW={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(_Z,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 R=0;R<K;R++){let[J,C]=Z.readStruct(_Z);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return b({masterSeed:V,hosts:m})}};var tK=new TextEncoder().encode("diplomatic.qrpair.v1"),iX=32,eK=iX+24+16,ZG=32,D5=Symbol("DHKEReq"),A5=Symbol("DHKEResp");function PV(Z){if(Z.byteLength!==iX)return Y(10);return b(Z)}function UV(Z){if(Z.byteLength<eK)return Y(10);return b(Z)}var cW=new nZ;async function jV(Z,X,W,V){let l;try{l=await cW.x25519Shared(Z,X)}catch{return Y(29)}try{if(l.byteLength!==iX||l.every((m)=>m===0))return Y(10);let K=TZ(l,tK),G=TZ(K,TZ(W,V));try{let m=await cW.blake3(G);return b(m.slice(0,ZG))}finally{K.fill(0),G.fill(0)}}finally{l.fill(0)}}class EX{#Z;#X;constructor(Z,X){this.#Z=Z,this.#X=X}static async create(){let Z;try{let X=await cW.genX25519();Z=X.priv;let[W,V]=PV(X.pub);if(V!==0)return Y(V);if(W===void 0)return Y(10);let l=new EX(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]=PV(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 jV(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 cW.decryptXSalsa20Poly1305Combined(W,V)}catch{return Y(20)}let G=new j(K),[m,R]=G.readStruct(kW);if(R!==0)return Y(R);if(m===void 0)return Y(14);try{let[J,C]=ZZ.fromBytes(m.masterSeed);if(C!==0)return Y(C);if(J===void 0)return Y(12);return this.wipe(),b({enclave:J,hosts:m.hosts.map((F)=>({...F}))})}finally{m.masterSeed.fill(0)}}finally{V.fill(0),K?.fill(0)}}}function gZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var BZ=32,G0=-7,m0=-8,Y0=-257,OX=[{type:"public-key",alg:G0},{type:"public-key",alg:m0},{type:"public-key",alg:Y0}];function TW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function hZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function R0(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function wZ(Z){if(Z?.rpId!==void 0)return b(Z.rpId);if(typeof location>"u")return Y(9);return b(TW(location.hostname))}var uV="";function XG(){return uV}function aZ(Z){if(Z instanceof Error){uV=Z.message===""?Z.name:`${Z.name}: ${Z.message}`;return}uV=String(Z)}function DZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function AZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return b(Z)}async function BX(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 C0(){return BX("extension:largeBlob")}async function IW(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(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:gZ(BZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:OX,authenticatorSelection:K,extensions:G,...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch(F){return aZ(F),Y(30)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(30);return b(new Uint8Array(R.rawId))}async function wX(Z,X,W){let V=DZ();if(V!==0)return V;let[l,K]=wZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:hZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:gZ(BZ),rpId:l,allowCredentials:[{type:"public-key",id:hZ(Z)}],userVerification:"required",extensions:G,...W?.hints!==void 0?{hints:W.hints}:{}}})}catch(F){return aZ(F),30}let[R,J]=AZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 30;return 0}async function J0(Z,X,W,V){let l={challenge:gZ(BZ),rpId:Z,userVerification:"required"};if(X?.hints!==void 0)l.hints=X.hints;if(W!==void 0)l.allowCredentials=[{type:"public-key",id:hZ(W)}];if(V!==void 0)l.extensions=V;let K;try{K=await navigator.credentials.get({publicKey:l})}catch(R){return aZ(R),Y(30)}let[G,m]=AZ(K);if(m!==0)return Y(m);if(G===void 0)return Y(27);return b(G)}async function LW(Z,X){let W=DZ();if(W!==0)return Y(W);let[V,l]=wZ(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 J0(V,X);if(d!==0)return Y(d);if(F===void 0)return Y(27);K=new Uint8Array(F.rawId)}let[G,m]=await J0(V,X,K,{largeBlob:{read:!0}});if(m!==0)return Y(m);if(G===void 0)return Y(27);let J=G.getClientExtensionResults().largeBlob;if(J===void 0||J.blob===void 0)return Y(7);let C=R0(J.blob);if(C.byteLength===0)return Y(7);return b({blob:C,credId:new Uint8Array(G.rawId)})}var QW=new TextEncoder().encode("diplomatic.prf.v1"),iV=32;async function WG(){return BX("extension:prf")}async function F0(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-prf",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G=Z?.salt!==void 0?hZ(Z.salt):void 0,m=G===void 0?{}:{eval:{first:G}},R;try{R=await navigator.credentials.create({publicKey:{challenge:gZ(BZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:OX,authenticatorSelection:K,extensions:{prf:m},...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch(d){return aZ(d),Y(30)}let[J,C]=AZ(R);if(C!==0)return Y(C);if(J===void 0)return Y(27);let F=J.getClientExtensionResults();return b({credId:new Uint8Array(J.rawId),prfEnabled:F.prf?.enabled===!0})}async function EV(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??QW,K=hZ(l),G={challenge:gZ(BZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.hints!==void 0)G.hints=Z.hints;if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:hZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch(c){return aZ(c),Y(30)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults().prf?.results;if(C?.first===void 0)return Y(7);let F=C.first,d=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),k=d.byteLength>=iV?d.slice(0,iV):d;if(k.byteLength!==iV)return Y(27);return b({prf:k,credId:new Uint8Array(R.rawId)})}var SW="dmFyIEEwPTY0O3ZhciBSWj0zMixfMD04O3ZhciBQJD0zMjt2YXIgSFo9MzAwMDAscVo9NTEyLEQ7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIjt3W3cuQ3J5cHRvRXJyb3I9MjldPSJDcnlwdG9FcnJvciI7d1t3LldlYkF1dGhuRXJyb3I9MzBdPSJXZWJBdXRobkVycm9yIn0pKER8fD17fSk7ZnVuY3Rpb24gTVooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIElaKCQpe2xldCBKPSQubGVuZ3RoLFo9MCxRPTA7d2hpbGUoUTxKKXtsZXQgWT0kLmNoYXJDb2RlQXQoUSsrKTtpZigoWSY0Mjk0OTY3MTY4KT09PTApe1orKztjb250aW51ZX1lbHNlIGlmKChZJjQyOTQ5NjUyNDgpPT09MClaKz0yO2Vsc2V7aWYoWT49NTUyOTYmJlk8PTU2MzE5KXtpZihRPEope2xldCBWPSQuY2hhckNvZGVBdChRKTtpZigoViY2NDUxMik9PT01NjMyMCkrK1EsWT0oKFkmMTAyMyk8PDEwKSsoViYxMDIzKSs2NTUzNn19aWYoKFkmNDI5NDkwMTc2MCk9PT0wKVorPTM7ZWxzZSBaKz00fX1yZXR1cm4gWn1mdW5jdGlvbiBRWSgkLEosWil7bGV0IFE9JC5sZW5ndGgsWT1aLFY9MDt3aGlsZShWPFEpe2xldCBYPSQuY2hhckNvZGVBdChWKyspO2lmKChYJjQyOTQ5NjcxNjgpPT09MCl7SltZKytdPVg7Y29udGludWV9ZWxzZSBpZigoWCY0Mjk0OTY1MjQ4KT09PTApSltZKytdPVg+PjYmMzF8MTkyO2Vsc2V7aWYoWD49NTUyOTYmJlg8PTU2MzE5KXtpZihWPFEpe2xldCBXPSQuY2hhckNvZGVBdChWKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1YsWD0oKFgmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFgmNDI5NDkwMTc2MCk9PT0wKUpbWSsrXT1YPj4xMiYxNXwyMjQsSltZKytdPVg+PjYmNjN8MTI4O2Vsc2UgSltZKytdPVg+PjE4Jjd8MjQwLEpbWSsrXT1YPj4xMiY2M3wxMjgsSltZKytdPVg+PjYmNjN8MTI4fUpbWSsrXT1YJjYzfDEyOH19dmFyIFlZPW5ldyBUZXh0RW5jb2RlcixWWT01MDtmdW5jdGlvbiBYWSgkLEosWil7WVkuZW5jb2RlSW50bygkLEouc3ViYXJyYXkoWikpfWZ1bmN0aW9uIENaKCQsSixaKXtpZigkLmxlbmd0aD5WWSlYWSgkLEosWik7ZWxzZSBRWSgkLEosWil9dmFyIFdZPTQwOTY7ZnVuY3Rpb24gVkooJCxKLFope2xldCBRPUosWT1RK1osVj1bXSxYPSIiO3doaWxlKFE8WSl7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVYucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztWLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1YucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTj0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE4+NjU1MzUpTi09NjU1MzYsVi5wdXNoKE4+Pj4xMCYxMDIzfDU1Mjk2KSxOPTU2MzIwfE4mMTAyMztWLnB1c2goTil9ZWxzZSBWLnB1c2goVyk7aWYoVi5sZW5ndGg+PVdZKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uViksVi5sZW5ndGg9MH1pZihWLmxlbmd0aD4wKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uVik7cmV0dXJuIFh9dmFyIEdZPW5ldyBUZXh0RGVjb2Rlcix6WT0yMDA7ZnVuY3Rpb24gS1koJCxKLFope2xldCBRPSQuc3ViYXJyYXkoSixKK1opO3JldHVybiBHWS5kZWNvZGUoUSl9ZnVuY3Rpb24gUFooJCxKLFope2lmKFo+elkpcmV0dXJuIEtZKCQsSixaKTtlbHNlIHJldHVybiBWSigkLEosWil9Y2xhc3MgbzB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsSil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPUp9fWNsYXNzIGUgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgSj1PYmplY3QuY3JlYXRlKGUucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxKKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOmUubmFtZX0pfX12YXIgYTA9NDI5NDk2NzI5NTtmdW5jdGlvbiB3WigkLEosWil7bGV0IFE9Wi80Mjk0OTY3Mjk2LFk9WjskLnNldFVpbnQzMihKLFEpLCQuc2V0VWludDMyKEorNCxZKX1mdW5jdGlvbiB3JCgkLEosWil7bGV0IFE9TWF0aC5mbG9vcihaLzQyOTQ5NjcyOTYpLFk9WjskLnNldFVpbnQzMihKLFEpLCQuc2V0VWludDMyKEorNCxZKX1mdW5jdGlvbiBUJCgkLEope2xldCBaPSQuZ2V0SW50MzIoSiksUT0kLmdldFVpbnQzMihKKzQpO3JldHVybiBaKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBUWigkLEope2xldCBaPSQuZ2V0VWludDMyKEopLFE9JC5nZXRVaW50MzIoSis0KTtyZXR1cm4gWio0Mjk0OTY3Mjk2K1F9dmFyIEZZPS0xLE5ZPTQyOTQ5NjcyOTUsT1k9MTcxNzk4NjkxODM7ZnVuY3Rpb24gVVkoe3NlYzokLG5zZWM6Sn0pe2lmKCQ+PTAmJko+PTAmJiQ8PU9ZKWlmKEo9PT0wJiYkPD1OWSl7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksWn1lbHNle2xldCBaPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxZPW5ldyBVaW50OEFycmF5KDgpLFY9bmV3IERhdGFWaWV3KFkuYnVmZmVyKTtyZXR1cm4gVi5zZXRVaW50MzIoMCxKPDwyfFomMyksVi5zZXRVaW50MzIoNCxRKSxZfWVsc2V7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KFouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxKKSx3JChRLDQsJCksWn19ZnVuY3Rpb24gUlkoJCl7bGV0IEo9JC5nZXRUaW1lKCksWj1NYXRoLmZsb29yKEovMTAwMCksUT0oSi1aKjEwMDApKjFlNixZPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6WitZLG5zZWM6US1ZKjFlOX19ZnVuY3Rpb24gSFkoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBKPVJZKCQpO3JldHVybiBVWShKKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIHFZKCQpe2xldCBKPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBaPUouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOlosbnNlYzowfX1jYXNlIDg6e2xldCBaPUouZ2V0VWludDMyKDApLFE9Si5nZXRVaW50MzIoNCksWT0oWiYzKSo0Mjk0OTY3Mjk2K1EsVj1aPj4+MjtyZXR1cm57c2VjOlksbnNlYzpWfX1jYXNlIDEyOntsZXQgWj1UJChKLDQpLFE9Si5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpaLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgZShgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uIE1ZKCQpe2xldCBKPXFZKCQpO3JldHVybiBuZXcgRGF0ZShKLnNlYyoxMDAwK0oubnNlYy8xZTYpfXZhciBqWj17dHlwZTpGWSxlbmNvZGU6SFksZGVjb2RlOk1ZfTtjbGFzcyBzMHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyBzMDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKGpaKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpKLGRlY29kZTpafSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPUosdGhpcy5kZWNvZGVyc1skXT1aO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1KLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPVp9fXRyeVRvRW5jb2RlKCQsSil7Zm9yKGxldCBaPTA7Wjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7WisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1taXTtpZihRIT1udWxsKXtsZXQgWT1RKCQsSik7aWYoWSE9bnVsbCl7bGV0IFY9LTEtWjtyZXR1cm4gbmV3IG8wKFYsWSl9fX1mb3IobGV0IFo9MDtaPHRoaXMuZW5jb2RlcnMubGVuZ3RoO1orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1taXTtpZihRIT1udWxsKXtsZXQgWT1RKCQsSik7aWYoWSE9bnVsbClyZXR1cm4gbmV3IG8wKFosWSl9fWlmKCQgaW5zdGFuY2VvZiBvMClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxKLFope2xldCBRPUo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1KXTp0aGlzLmRlY29kZXJzW0pdO2lmKFEpcmV0dXJuIFEoJCxKLFopO2Vsc2UgcmV0dXJuIG5ldyBvMChKLCQpfX1mdW5jdGlvbiBJWSgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gRyQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYoSVkoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgQ1k9MTAwLFBZPTIwNDg7Y2xhc3MgaiR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9zMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/Q1ksdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/UFksdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBqJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLEope2lmKEo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke0p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsSil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IEo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxKKXRoaXMucmVzaXplQnVmZmVyKEoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBKPW5ldyBBcnJheUJ1ZmZlcigkKSxaPW5ldyBVaW50OEFycmF5KEopLFE9bmV3IERhdGFWaWV3KEopO1ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Wn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBaPUlaKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStaKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKFopLENaKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPVp9ZW5jb2RlT2JqZWN0KCQsSil7bGV0IFo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoWiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihaKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLEopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLEopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IEo9JC5ieXRlTGVuZ3RoO2lmKEo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChKKTtlbHNlIGlmKEo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihKKTtlbHNlIGlmKEo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKEopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Sn1gKTtsZXQgWj1HJCgkKTt0aGlzLndyaXRlVThhKFopfWVuY29kZUFycmF5KCQsSil7bGV0IFo9JC5sZW5ndGg7aWYoWjwxNil0aGlzLndyaXRlVTgoMTQ0K1opO2Vsc2UgaWYoWjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KFopO2Vsc2UgaWYoWjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoWik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke1p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLEorMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsSil7bGV0IFo9MDtmb3IobGV0IFEgb2YgSilpZigkW1FdIT09dm9pZCAwKVorKztyZXR1cm4gWn1lbmNvZGVNYXAoJCxKKXtsZXQgWj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKVouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsWik6Wi5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFkgb2YgWil7bGV0IFY9JFtZXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZWPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhZKSx0aGlzLmRvRW5jb2RlKFYsSisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgWj0kLmRhdGEodGhpcy5wb3MrNiksUT1aLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShaKTtyZXR1cm59bGV0IEo9JC5kYXRhLmxlbmd0aDtpZihKPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKEo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoSj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihKPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKEo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKEo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChKKTtlbHNlIGlmKEo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihKKTtlbHNlIGlmKEo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKEopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke0p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgSj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKEopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1KfXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksd1oodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdyQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBFMCgkLEope3JldHVybiBuZXcgaiQoSikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIEQkKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgd1k9MTYsVFk9MTY7Y2xhc3MgWEp7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9d1ksSj1UWSl7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1KLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgWj0wO1o8dGhpcy5tYXhLZXlMZW5ndGg7WisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxKLFope2xldCBRPXRoaXMuY2FjaGVzW1otMV07JDpmb3IobGV0IFkgb2YgUSl7bGV0IFY9WS5ieXRlcztmb3IobGV0IFg9MDtYPFo7WCsrKWlmKFZbWF0hPT0kW0orWF0pY29udGludWUgJDtyZXR1cm4gWS5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxKKXtsZXQgWj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpKfTtpZihaLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpWltNYXRoLnJhbmRvbSgpKloubGVuZ3RofDBdPVE7ZWxzZSBaLnB1c2goUSl9ZGVjb2RlKCQsSixaKXtsZXQgUT10aGlzLmZpbmQoJCxKLFopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgWT1WSigkLEosWiksVj1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsSixKK1opO3JldHVybiB0aGlzLnN0b3JlKFYsWSksWX19dmFyIFdKPSJhcnJheSIsSyQ9Im1hcF9rZXkiLEFaPSJtYXBfdmFsdWUiLGpZPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IGUoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyBfWntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgSj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Si50eXBlPVdKLEoucG9zaXRpb249MCxKLnNpemU9JCxKLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgSj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Si50eXBlPUskLEoucmVhZENvdW50PTAsSi5zaXplPSQsSi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1XSil7bGV0IFo9JDtaLnNpemU9MCxaLmFycmF5PXZvaWQgMCxaLnBvc2l0aW9uPTAsWi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1LJHx8JC50eXBlPT09QVope2xldCBaPSQ7Wi5zaXplPTAsWi5tYXA9dm9pZCAwLFoucmVhZENvdW50PTAsWi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciB6JD0tMSxHSj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSxEWT1uZXcgVWludDhBcnJheShHSi5idWZmZXIpO3RyeXtHSi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBEWj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLEFZPW5ldyBYSjtjbGFzcyBBJHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1HSjtieXRlcz1EWTtoZWFkQnl0ZT16JDtzdGFjaz1uZXcgX1o7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9zMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/YTAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9hMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9hMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P2EwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/YTAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOkFZLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/all9Y2xvbmUoKXtyZXR1cm4gbmV3IEEkKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPXokLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IEo9RyQoJCk7dGhpcy5ieXRlcz1KLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoSi5idWZmZXIsSi5ieXRlT2Zmc2V0LEouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PXokJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgSj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxaPUckKCQpLFE9bmV3IFVpbnQ4QXJyYXkoSi5sZW5ndGgrWi5sZW5ndGgpO1Euc2V0KEopLFEuc2V0KFosSi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OkoscG9zOlp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Si5ieXRlTGVuZ3RoLVp9IG9mICR7Si5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IEo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gSn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBKPSExLFo7Zm9yIGF3YWl0KGxldCBYIG9mICQpe2lmKEopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoWCk7dHJ5e1o9dGhpcy5kb0RlY29kZVN5bmMoKSxKPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoSil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gWn1sZXR7aGVhZEJ5dGU6USxwb3M6WSx0b3RhbFBvczpWfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHtEJChRKX0gYXQgJHtWfSAoJHtZfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLEope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxKKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgWj1KLFE9LTE7Zm9yIGF3YWl0KGxldCBZIG9mICQpe2lmKEomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoWSksWilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLFo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goVil7aWYoIShWIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgVn10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksSjtpZigkPj0yMjQpSj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KUo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNle2xldCBRPSQtMTYwO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpSj1udWxsO2Vsc2UgaWYoJD09PTE5NClKPSExO2Vsc2UgaWYoJD09PTE5NSlKPSEwO2Vsc2UgaWYoJD09PTIwMilKPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylKPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClKPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KUo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KUo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpSj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgSj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpSj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlKPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClKPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KUo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIEo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpSj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpSj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IGUoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7RCQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBaPXRoaXMuc3RhY2s7d2hpbGUoWi5sZW5ndGg+MCl7bGV0IFE9Wi50b3AoKTtpZihRLnR5cGU9PT1XSilpZihRLmFycmF5W1EucG9zaXRpb25dPUosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpSj1RLmFycmF5LFoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1LJCl7aWYoSj09PSJfX3Byb3RvX18iKXRocm93IG5ldyBlKCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKEopLFEudHlwZT1BWjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPUosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlKPVEubWFwLFoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPUskO2NvbnRpbnVlICR9fXJldHVybiBKfX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09eiQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT16JH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyBlKGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke0QkKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsSil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLEopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLEopfWRlY29kZVV0ZjhTdHJpbmcoJCxKKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyBlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytKKyQpdGhyb3cgRFo7bGV0IFo9dGhpcy5wb3MrSixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLFosJCk7ZWxzZSBRPVBaKHRoaXMuYnl0ZXMsWiwkKTtyZXR1cm4gdGhpcy5wb3MrPUorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1LJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxKKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyBlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrSikpdGhyb3cgRFo7bGV0IFo9dGhpcy5wb3MrSixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoWixaKyQpO3JldHVybiB0aGlzLnBvcys9SiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsSil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBaPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK0opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxKKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLFosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPVRaKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPVQkKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIHpKKCQsSil7cmV0dXJuIG5ldyBBJChKKS5kZWNvZGUoJCl9Y2xhc3MgRiR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLEope2xldCBaPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighWilaPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsWik7cmV0dXJuIFouYWRkKEopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsSil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoWil7aWYoWi5kZWxldGUoSiksWi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoWil7bGV0IFE9QXJyYXkuZnJvbShaKTtmb3IobGV0IFkgb2YgUSlZKEopfX1lbWl0QWxsKCQpe2xldCBKPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IFogb2YgSil0aGlzLmVtaXQoWiwkKX19Y2xhc3MgZjB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgRiR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdChmMC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoZjAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoZjAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gTygkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gX1koJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IEo9W107d2hpbGUoJD4wbil7bGV0IFo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKUoucHVzaChafDEyOCk7ZWxzZSBKLnB1c2goWil9aWYoSi5sZW5ndGg9PT0wKXJldHVybiBPKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKEoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBPKG5ldyBVaW50OEFycmF5KEopKX1mdW5jdGlvbiBMWSgkLEo9MCl7bGV0IFo9MG4sUT0wLFk9Sjt3aGlsZSghMCl7aWYoWT49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBWPSRbWSsrXTtpZihWPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihafD1CaWdJbnQoViYxMjcpPDxCaWdJbnQoUSksKFYmMTI4KT09PTApe2lmKFktSj44KXJldHVybiBHKDI2KTtyZXR1cm4gTyh7dmFsdWU6Wj4weDFmZmZmZmZmZmZmZmZmbj9aOk51bWJlcihaKSxieXRlc1JlYWQ6WS1KfSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIG17ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBKPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxaPW5ldyBVaW50OEFycmF5KEopO3JldHVybiBuZXcgbShaKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LE8oJCl9cmVhZERhdGUoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gTyhuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLEpdPUxZKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoSiE9PTApcmV0dXJuIEcoSik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBaPSQudmFsdWU7cmV0dXJuIE8odHlwZW9mIFo9PT0iYmlnaW50Ij9OdW1iZXIoWik6Wil9cmVhZFZhclN0cmluZygpe2xldFskLEpdPXRoaXMucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtaLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBZPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShaKTtyZXR1cm4gTyhZKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBKPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsTyhKKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IEo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbWixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Si5wdXNoKFopfXJldHVybiBPKEopfXJlYWRCeXRlc1NlcSgkKXtsZXQgSj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtaLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO0oucHVzaChaKX1yZXR1cm4gTyhKKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBKPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKEopfXdyaXRlRGF0ZSgkKXtsZXQgSj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChKKX13cml0ZVZhckludCgkKXtsZXRbSixaXT1fWSgkKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKEopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IEo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLFo9dGhpcy53cml0ZVZhckludChKLmxlbmd0aCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhKKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJC5zbGljZSgpKX13cml0ZUJ5dGVzKCQpe3RoaXMucGFydHMucHVzaCgkLnNsaWNlKCkpfXdyaXRlVmFyQnl0ZXMoJCl7bGV0IEo9dGhpcy53cml0ZVZhckludCgkLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcygkKSwwfXdyaXRlU3RydWN0KCQsSil7cmV0dXJuICQuZW5jb2RlKHRoaXMsSil9d3JpdGVTdHJ1Y3RzKCQsSil7Zm9yKGxldCBaIG9mIEope2xldCBRPXRoaXMud3JpdGVTdHJ1Y3QoJCxaKTtpZihRIT09MClyZXR1cm4gUX1yZXR1cm4gMH13cml0ZUJ5dGVzU2VxKCQpe2ZvcihsZXQgSiBvZiAkKXRoaXMud3JpdGVCeXRlcyhKKX1yZXN1bHQoKXtsZXQgJD10aGlzLnBhcnRzLnJlZHVjZSgoUSxZKT0+UStZLmxlbmd0aCwwKSxKPW5ldyBVaW50OEFycmF5KCQpLFo9MDtmb3IobGV0IFEgb2YgdGhpcy5wYXJ0cylKLnNldChRLFopLForPVEubGVuZ3RoO3JldHVybiBKfXdpcGUoKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cykkLmZpbGwoMCk7dGhpcy5wYXJ0cy5sZW5ndGg9MH0qc2Nhbigpe2ZvcihsZXQgJCBvZiB0aGlzLnBhcnRzKXlpZWxkICR9fWFzeW5jIGZ1bmN0aW9uIEtKKCQsSil7bGV0IFo9bmV3IFMsUT1aLndyaXRlRGF0ZShKKTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgWT1aLnJlc3VsdCgpLFY9YXdhaXQgJC5zaWduKFkpO3JldHVybiBPKHtwdWJLZXk6JC5wdWJsaWNLZXksc2lnOlYsdGltZXN0YW1wOkp9KX1hc3luYyBmdW5jdGlvbiBMMCgkLEosWil7bGV0IFE9Wi5ub3coKS5nZXRUaW1lKCksWT0kLnRpbWVzdGFtcC5nZXRUaW1lKCk7aWYoTWF0aC5hYnMoUS1ZKT5IWilyZXR1cm4gNDtsZXQgWD1uZXcgUztYLndyaXRlRGF0ZSgkLnRpbWVzdGFtcCk7bGV0IFc9WC5yZXN1bHQoKTtpZighYXdhaXQgSi5jaGVja1NpZ0VkMjU1MTkoJC5zaWcsVywkLnB1YktleSkpcmV0dXJuIDM7cmV0dXJuIDB9dmFyIFYwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5pZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZURhdGUoSi50cyk7aWYoUSE9PTApcmV0dXJuIFE7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJCeXRlcygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZERhdGUoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyh7aWQ6Six0czpRfSl9fTtmdW5jdGlvbiBfJCgkKXtsZXQgSj1uZXcgUyxaPUoud3JpdGVTdHJ1Y3QoVjAsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9Si5yZXN1bHQoKTtyZXR1cm4gTyhRKX12YXIgRzA9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmVpZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLm9mZik7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9JC53cml0ZVZhckludChKLmN0cik7aWYoWSE9PTApcmV0dXJuIFk7bGV0IFY9JC53cml0ZVZhckludChKLmxlbik7aWYoViE9PTApcmV0dXJuIFY7aWYoSi5oc2gpJC53cml0ZUJ5dGVzKEouaHNoKTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckJ5dGVzKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9bmV3IG0oSiksWyxZXT1WMC5kZWNvZGUoUSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1csel09JC5yZWFkVmFySW50KCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkVmFySW50KCk7aWYoRiE9PTApcmV0dXJuIEcoRik7bGV0IE47aWYoSz4wKXtsZXRbVSxSXT0kLnJlYWRCeXRlcyhQJCk7aWYoUiE9PTApcmV0dXJuIEcoUik7Tj1VfXJldHVybiBPKHtlaWQ6SixvZmY6VixjdHI6VyxsZW46Syxoc2g6Tn0pfX07ZnVuY3Rpb24gVTAoJCl7cmV0dXJuIEFycmF5LmZyb20oJCkubWFwKChaKT0+Wi50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX1mdW5jdGlvbiBMWigkKXtpZigkLmxlbmd0aCUyIT09MCl0aHJvdyBFcnJvcigiSW52YWxpZCBoZXggc3RyaW5nIik7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoJC5sZW5ndGgvMik7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKz0yKUpbWi8yXT1OdW1iZXIucGFyc2VJbnQoJC5zdWJzdHIoWiwyKSwxNik7cmV0dXJuIEp9ZnVuY3Rpb24gcigkLEope2lmKCQ9PT1KKXJldHVybiEwO2lmKCQuYnl0ZUxlbmd0aCE9PUouYnl0ZUxlbmd0aClyZXR1cm4hMTtyZXR1cm4gJC5ldmVyeSgoWixRKT0+Wj09PUpbUV0pfXZhciBCO2lmKHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS50b0Jhc2U2ND09PSJmdW5jdGlvbiIpQj0oJCk9PiQudG9CYXNlNjQoKTtlbHNlIEI9KCQpPT5idG9hKFN0cmluZy5mcm9tQ2hhckNvZGUoLi4uJCkpO3ZhciBOMDtpZih0eXBlb2YgVWludDhBcnJheS5mcm9tQmFzZTY0PT09ImZ1bmN0aW9uIilOMD0oJCk9PlVpbnQ4QXJyYXkuZnJvbUJhc2U2NCgkKTtlbHNlIE4wPSgkKT0+VWludDhBcnJheS5mcm9tKGF0b2IoJCksKEopPT5KLmNoYXJDb2RlQXQoMCkpO2Z1bmN0aW9uIHhaKCQpe2xldCBKPSQubGVuZ3RoJTQ9PT0wPyIiOiI9Ii5yZXBlYXQoNC0kLmxlbmd0aCU0KSxaPSQucmVwbGFjZSgvLS9nLCIrIikucmVwbGFjZSgvXy9nLCIvIikrSjtyZXR1cm4gTjAoWil9ZnVuY3Rpb24gUjAoJCxKKXtsZXQgWj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtKLmxlbmd0aCk7cmV0dXJuIFouc2V0KCQsMCksWi5zZXQoSiwkLmxlbmd0aCksWn1mdW5jdGlvbiBCWigkLEosWil7cmV0dXJuIFouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxKKX1hc3luYyBmdW5jdGlvbiBrWigkLEosWixRKXtsZXQgWTtpZigkLmJvZCYmJC5sZW4+MClZPWF3YWl0IFouYmxha2UzKCQuYm9kKTtsZXQgVj1uZXcgUyxYPUcwLmVuY29kZShWLHsuLi4kLGhzaDpZfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFc9Vi5yZXN1bHQoKSx6PWF3YWl0IEoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE49JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxVPWF3YWl0IEouc2lnbihGKTtyZXR1cm4gTyh7c2lnOlUsa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6Tn0pfWFzeW5jIGZ1bmN0aW9uIEZKKCQsSixaLFEsWSl7bGV0IFY9bmV3IG0oJCksW1gsV109RzAuZGVjb2RlKFYpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1KJiZKLmxlbmd0aD4wP2F3YWl0IFouZGVjcnlwdChKKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVguaHNoJiZ6PT09dm9pZCAwLEY9WC5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoWC5oc2gmJnope2xldCBVPWF3YWl0IFEuYmxha2UzKHopO2lmKCFyKFUsWC5oc2gpKXJldHVybiBHKDE5KX1sZXQgTj1ZPz9hd2FpdCBRLmJsYWtlMygkKTtyZXR1cm4gTyh7bXNnSGVhZDpYLGJvZDp6LGhlYWRIYXNoOk59KX1jbGFzcyBOSntub3coKXtyZXR1cm4gbmV3IERhdGV9fWZ1bmN0aW9uIEVaKCQsSixaLFEpe2xldCBZPUouZ2V0VGltZSgpLSQuZ2V0VGltZSgpLFY9Wi5nZXRUaW1lKCktUS5nZXRUaW1lKCk7cmV0dXJuKFkrVikvMn12YXIgTiQ9e2VuY29kZSgkLEope2lmKCQud3JpdGVWYXJJbnQoSi5xdW90YSksSi5xdW90YT4wKXtpZihKLnVzYWdlPT09dm9pZCAwKXJldHVybiA5OyQud3JpdGVWYXJJbnQoSi51c2FnZSl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXQgUTtpZihKPjApe2xldFtZLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO1E9WX1yZXR1cm4gTyh7cXVvdGE6Six1c2FnZTpRfSl9fTt2YXIgT0o9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbSi5zdGF0dXNdKSk7bGV0IFo9JC53cml0ZURhdGUoSi50aW1lUmN2ZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZURhdGUoSi50aW1lU2VudCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9JC53cml0ZVZhckludChKLnN1YnNjcmlwdGlvbi50ZXJtKTtpZihZIT09MClyZXR1cm4gWTtsZXQgVj0kLndyaXRlVmFySW50KEouc3Vic2NyaXB0aW9uLmVsYXBzZWQpO2lmKFYhPT0wKXJldHVybiBWO2xldCBYPSQud3JpdGVTdHJ1Y3QoTiQsSi5zdWJzY3JpcHRpb24uc3RhdCk7aWYoWCE9PTApcmV0dXJuIFg7bGV0IFc9JC53cml0ZVN0cnVjdChOJCxKLnN1YnNjcmlwdGlvbi5keW4pO2lmKFchPT0wKXJldHVybiBXO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoMSk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9SlswXSxbWSxWXT0kLnJlYWREYXRlKCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1gsV109JC5yZWFkRGF0ZSgpO2lmKFchPT0wKXJldHVybiBHKFcpO2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO2xldFtGLE5dPSQucmVhZFZhckludCgpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldFtVLFJdPSQucmVhZFN0cnVjdChOJCk7aWYoUiE9PTApcmV0dXJuIEcoUik7bGV0W0gscV09JC5yZWFkU3RydWN0KE4kKTtpZihxIT09MClyZXR1cm4gRyhxKTtyZXR1cm4gTyh7c3RhdHVzOlEsdGltZVJjdmQ6WSx0aW1lU2VudDpYLHN1YnNjcmlwdGlvbjp7dGVybTp6LGVsYXBzZWQ6RixzdGF0OlUsZHluOkh9fSl9fTt2YXIgVUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5zZXEpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFyQnl0ZXMoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyh7aGVhZENwaDpKLHNlcTpRfSl9fTt2YXIgWDA9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnB1YktleSksJC53cml0ZUJ5dGVzKEouc2lnKTtsZXQgWj0kLndyaXRlRGF0ZShKLnRpbWVzdGFtcCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhSWik7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkQnl0ZXMoQTApO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZERhdGUoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7cHViS2V5Okosc2lnOlEsdGltZXN0YW1wOlZ9KX19O3ZhciBmWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsWSl7bGV0IFY9WS53cml0ZVN0cnVjdChYMCxaKTtpZihWIT09MClyZXR1cm4gVjtmb3IobGV0IFggb2YgUSlZLndyaXRlVmFySW50KFgpO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vn09JCxbWCxXXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEwwKFgsWSxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVgsW0YsTl09YXdhaXQgVi5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldFtVLFJdPUoucmVhZFZhckludCgpO2lmKFIhPT0wKXJldHVybiBSO2lmKCFKLmRvbmUoKSlyZXR1cm4gODtsZXRbSCxxXT1hd2FpdCBWLmxpc3RIZWFkcyhLLFUpO2lmKHEhPT0wKXJldHVybiBxO3JldHVybiBaLndyaXRlU3RydWN0cyhVSixIKX0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhVSil9fTt2YXIgUko9e2VuY29kZSgkLEopeyQud3JpdGVWYXJJbnQoSi5zZXEpO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlDcGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkVmFyQnl0ZXMoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyh7c2VxOkosYm9keUNwaDpRfSl9fTt2YXIgZ1o9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFkpe2xldCBWPVkud3JpdGVTdHJ1Y3QoWDAsWik7aWYoViE9PTApcmV0dXJuIFY7Zm9yKGxldCBYIG9mIFEpe2xldCBXPVkud3JpdGVWYXJJbnQoWCk7aWYoVyE9PTApcmV0dXJuIFd9cmV0dXJuIDB9LGFzeW5jIGhhbmRsZVJlcSgkLEosWil7bGV0e2Nsb2NrOlEsY3J5cHRvOlksc3RvcmFnZTpWfT0kLFtYLFddPUoucmVhZFN0cnVjdChYMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgTDAoWCxZLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309WCxbRixOXT1hd2FpdCBWLmhhc1VzZXIoSyk7aWYoTiE9PTApcmV0dXJuIE47aWYoIUYpcmV0dXJuIDU7bGV0IFU9W107d2hpbGUoIUouZG9uZSgpKXtsZXRbcSxNXT1KLnJlYWRWYXJJbnQoKTtpZihNIT09MClyZXR1cm4gTTtVLnB1c2gocSl9Y29uc29sZS5pbmZvKGBQVUxMOiAke1UubGVuZ3RofSBiYWdzYCk7bGV0W1IsSF09YXdhaXQgVi5nZXRCb2RpZXMoSyxVKTtpZihIIT09MClyZXR1cm4gSDtpZighUilyZXR1cm4gMTc7Zm9yKGxldHtzZXE6cSxib2R5Q3BoOk19b2YgUil7bGV0IFA9e3NlcTpxLGJvZHlDcGg6TX0sQz1aLndyaXRlU3RydWN0KFJKLFApO2lmKEMhPT0wKXJldHVybiBDfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKFJKKX19O3ZhciBISj17ZW5jb2RlKCQsSil7JC53cml0ZUJ5dGVzKEouc2lnKSwkLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlDcGgpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoQTApO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZEJ5dGVzKF8wKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJCeXRlcygpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZFZhckJ5dGVzKCk7aWYoeiE9PTApcmV0dXJuIEcoeik7cmV0dXJuIE8oe3NpZzpKLGtkbTpRLGhlYWRDcGg6Vixib2R5Q3BoOld9KX19O3ZhciBMJD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhckludChKLnNlcSk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKEouaGVhZENwaCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9Si5ib2R5Q3BoP0ouYm9keUNwaC5sZW5ndGg6MCxWPSQud3JpdGVWYXJJbnQoWSk7aWYoViE9PTApcmV0dXJuIFY7aWYoWT4wKXtpZighSi5ib2R5Q3BoKXJldHVybiAxMDskLndyaXRlQnl0ZXMoSi5ib2R5Q3BoKX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckJ5dGVzKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFc7aWYoVj4wKXtsZXRbeixLXT0kLnJlYWRCeXRlcyhWKTtpZihLIT09MClyZXR1cm4gRyhLKTtXPXp9cmV0dXJuIE8oe3NlcTpKLGhlYWRDcGg6USxib2R5Q3BoOld9KX19O3ZhciB4JD17ZW5jb2RlKCQsSil7JC53cml0ZUJ5dGVzKEouc2lnKSwkLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoQTApO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZEJ5dGVzKF8wKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJCeXRlcygpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBPKHtzaWc6SixrZG06USxoZWFkQ3BoOlZ9KX19O3ZhciBCJD17ZW5jb2RlKCQsSil7aWYoJC53cml0ZVZhckludChKLmlkeCksJC53cml0ZUJ5dGVzKG5ldyBVaW50OEFycmF5KFtKLnN0YXR1c10pKSxKLnN0YXR1cz09PTApJC53cml0ZVZhckludChKLnNlcSk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRCeXRlcygxKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgVj1RWzBdO2lmKFYhPT0wKXJldHVybiBPKHtpZHg6SixzdGF0dXM6Vn0pO2xldFtYLFddPSQucmVhZFZhckludCgpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBPKHtpZHg6SixzdGF0dXM6VixzZXE6WH0pfX07dmFyIG1aPXthc3luYyBlbmNvZGVSZXEoJCxKLFosUSxZKXtsZXQgVj1ZLndyaXRlU3RydWN0KFgwLFopO2lmKFYhPT0wKXJldHVybiBWO2xldCBYPVkud3JpdGVTdHJ1Y3RzKEhKLFEpO2lmKFghPT0wKXJldHVybiBYO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vixub3RpZmllcjpYfT0kLFtXLHpdPUoucmVhZFN0cnVjdChYMCk7aWYoeiE9PTApcmV0dXJuIHo7bGV0IEs9YXdhaXQgTDAoVyxZLFEpO2lmKEshPT0wKXJldHVybiBLO2xldHtwdWJLZXk6Rn09VyxbTixVXT1hd2FpdCBWLmhhc1VzZXIoRik7aWYoVSE9PTApcmV0dXJuIFU7aWYoIU4pcmV0dXJuIDU7bGV0W1IsSF09Si5yZWFkU3RydWN0cyhISik7aWYoSCE9PTApcmV0dXJuIEg7Y29uc29sZS5pbmZvKGBQVVNIOiAke1IubGVuZ3RofSBiYWdzYCk7bGV0IHE9W10sTT1bXTtmb3IobGV0IEk9MDtJPFIubGVuZ3RoO0krKyl7bGV0IEE9UltJXTtpZighYXdhaXQgQlooQSxGLFkpKXtsZXQgZz17aWR4Okksc3RhdHVzOjN9LGY9Wi53cml0ZVN0cnVjdChCJCxnKTtpZihmIT09MClyZXR1cm4gZjtjb250aW51ZX1xLnB1c2goSSksTS5wdXNoKEEpfWxldFtQLENdPWF3YWl0IFYuc2V0QmFncyhGLE0pO2lmKEMhPT0wKXJldHVybiBDO2lmKCFQfHxQLmxlbmd0aCE9PU0ubGVuZ3RoKXJldHVybiAxNztsZXQgVD1bXTtmb3IobGV0IEk9MDtJPE0ubGVuZ3RoO0krKyl7bGV0IEE9TVtJXSxMPXFbSV0sZz1QW0ldLGY9bmV3IFMsaz1mLndyaXRlU3RydWN0KHgkLEEpO2lmKGshPT0wKXJldHVybiBrO2xldCB5PWYucmVzdWx0KCksaD17c2VxOmcsaGVhZENwaDp5fTtpZihSLmxlbmd0aD09PTEmJkEuYm9keUNwaC5sZW5ndGg8PXFaKWguYm9keUNwaD1BLmJvZHlDcGg7VC5wdXNoKGgpO2xldCB1PXtpZHg6TCxzdGF0dXM6MCxzZXE6Z30sdz1aLndyaXRlU3RydWN0KEIkLHUpO2lmKHchPT0wKXJldHVybiB3fWlmKFQubGVuZ3RoPjApe2xldCBJPW5ldyBTLEE9SS53cml0ZVN0cnVjdHMoTCQsVCk7aWYoQSE9PTApcmV0dXJuIEE7bGV0IEw9SS5yZXN1bHQoKTthd2FpdCBQcm9taXNlLnJlc29sdmUoWC5wdXNoKEYsTCkpfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKEIkKX19O3ZhciBTWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsWSl7cmV0dXJuIFkud3JpdGVTdHJ1Y3QoWDAsWil9LGFzeW5jIGhhbmRsZVJlcSgkLEosWil7bGV0e2Nsb2NrOlEsY3J5cHRvOlksc3RvcmFnZTpWfT0kLFtYLFddPUoucmVhZFN0cnVjdChYMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgTDAoWCxZLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309WDtpZighSi5kb25lKCkpcmV0dXJuIDg7bGV0W0YsTl09YXdhaXQgVi5hZGRVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO3JldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiBPKHZvaWQgMCl9fTtjbGFzcyBxSnt1cmw7d2Vic29ja2V0O2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSR9Y29ubmVjdGVkKCl7cmV0dXJuIHRoaXMud2Vic29ja2V0IT09dm9pZCAwJiZ0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09V2ViU29ja2V0Lk9QRU59YXN5bmMgY29ubmVjdCgkLEosWj0oKT0+e30sUT0oKT0+e30pe2xldHt1cmw6WX09dGhpcztpZih0aGlzLndlYnNvY2tldCl0aGlzLndlYnNvY2tldC5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMDtsZXQgVj1uZXcgUztWLndyaXRlU3RydWN0KFgwLCQpO2xldCBYPVYucmVzdWx0KCksVz1VMChYKTtyZXR1cm4gWS5zZWFyY2hQYXJhbXMuc2V0KCJ0IixXKSx0aGlzLndlYnNvY2tldD1uZXcgV2ViU29ja2V0KFkpLHRoaXMud2Vic29ja2V0LmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix0aGlzLndlYnNvY2tldC5vbm9wZW49KCk9Pntjb25zb2xlLmxvZygiQ09OTkVDVEVEIiksUSgpfSx0aGlzLndlYnNvY2tldC5vbmNsb3NlPSgpPT57Y29uc29sZS5sb2coIkRJU0NPTk5FQ1RFRCIpLHRoaXMud2Vic29ja2V0PXZvaWQgMCxaKCl9LHRoaXMud2Vic29ja2V0Lm9ubWVzc2FnZT0oeik9PntsZXQgSz1uZXcgVWludDhBcnJheSh6LmRhdGEpO0ooSyl9LHRoaXMud2Vic29ja2V0Lm9uZXJyb3I9KHopPT57Y29uc29sZS5sb2coYEVSUk9SOiAke0pTT04uc3RyaW5naWZ5KHopfWApLHRoaXMud2Vic29ja2V0PXZvaWQgMCxaKCl9LFByb21pc2UucmVzb2x2ZSgwKX1kaXNjb25uZWN0KCl7dGhpcy53ZWJzb2NrZXQ/LmNsb3NlKCksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwfX12YXIgYT17dXNlcjp7cGF0aDoiL3VzZXIiLGVuZHBvaW50OlNaLG5hbWU6MH0scHVzaDp7cGF0aDoiL3B1c2giLGVuZHBvaW50Om1aLG5hbWU6Mn0scGVlazp7cGF0aDoiL3BlZWsiLGVuZHBvaW50OmZaLG5hbWU6MX0scHVsbDp7cGF0aDoiL3B1bGwiLGVuZHBvaW50OmdaLG5hbWU6M319LHhZPXswOmEudXNlciwyOmEucHVzaCwxOmEucGVlaywzOmEucHVsbH0sblc9e1thLnVzZXIucGF0aF06YS51c2VyLFthLnB1c2gucGF0aF06YS5wdXNoLFthLnBlZWsucGF0aF06YS5wZWVrLFthLnB1bGwucGF0aF06YS5wdWxsfTtjbGFzcyB2Wnt1cmw7bGlzdGVuZXI7Y29uc3RydWN0b3IoJCl7dGhpcy51cmw9JDt0aGlzLmxpc3RlbmVyPW5ldyBxSigkKX1hc3luYyBjYWxsKCQsSil7bGV0e3BhdGg6Wn09eFlbJF0sUT1uZXcgVVJMKFosdGhpcy51cmwpO3RyeXtyZXR1cm4gYXdhaXQgQlkoUSxKKX1jYXRjaHtyZXR1cm4gRygyNSl9fX12YXIgeVo9KCQpPT57cmV0dXJuIG5ldyB2WigkLmhhbmRsZSl9O2FzeW5jIGZ1bmN0aW9uIEJZKCQsSil7bGV0IFo9YXdhaXQgZmV0Y2goJCx7bWV0aG9kOiJQT1NUIixib2R5OkoucmVzdWx0KCkuc2xpY2UoKX0pO2lmKCFaLm9rKXJldHVybiBHKDI0KTtsZXQgUT1hd2FpdCBtLmZyb21SZXNwb25zZShaKTtyZXR1cm4gTyhRKX1jbGFzcyBrJHtlbmNsYXZlO2NyeXB0bztob3N0O2Nsb2NrO3RyYW5zcG9ydDt1cGRhdGVIb3N0TWV0YTtjb25zdHJ1Y3RvcigkLEosWixRLFksVil7dGhpcy5lbmNsYXZlPSQ7dGhpcy5jcnlwdG89Sjt0aGlzLmhvc3Q9Wjt0aGlzLmNsb2NrPVE7dGhpcy50cmFuc3BvcnQ9WTt0aGlzLnVwZGF0ZUhvc3RNZXRhPVZ9YXN5bmMgY2FsbCgkLEope2xldHtjbG9jazpaLHRyYW5zcG9ydDpRfT10aGlzLHtlbmRwb2ludDpZLG5hbWU6Vn09JCxYPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVoubm93KCksW3osS109YXdhaXQgS0ooWCxXKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXQgRj1uZXcgUyxOPWF3YWl0IFkuZW5jb2RlUmVxKHRoaXMsWCx6LEosRik7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IFU9Wi5ub3coKSxbUixIXT1hd2FpdCBRLmNhbGwoVixGKSxxPVoubm93KCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7bGV0W00sUF09Ui5yZWFkU3RydWN0KE9KKTtpZihQIT09MClyZXR1cm4gRyhQKTtpZihNLnN0YXR1cyE9PTApcmV0dXJuIEcoTS5zdGF0dXMpO2xldCBUPXtjbG9ja09mZnNldDpFWihVLE0udGltZVJjdmQsTS50aW1lU2VudCxxKSxzdWJzY3JpcHRpb246TS5zdWJzY3JpcHRpb259LEk9YXdhaXQgdGhpcy51cGRhdGVIb3N0TWV0YShUKTtpZihJIT09MClyZXR1cm4gRyhJKTtyZXR1cm4gWS5kZWNvZGVSZXNwKFIpfWlkZW50aXR5PSgpPT57bGV0e2hvc3Q6JCxlbmNsYXZlOkp9PXRoaXM7cmV0dXJuIEouZGVyaXZlSWRlbnRpdHkoJC5sYWJlbCwkLmlkeD8/MCl9O3NlYWw9YXN5bmMoJCk9PntsZXR7Y3J5cHRvOkosZW5jbGF2ZTpafT10aGlzLFE9YXdhaXQgdGhpcy5pZGVudGl0eSgpO3JldHVybiBrWigkLFEsSixaKX07cmVnaXN0ZXI9KCk9PnRoaXMuY2FsbChhLnVzZXIsW10pO3BlZWs9KCQpPT50aGlzLmNhbGwoYS5wZWVrLFskXSk7cHVzaD0oJCk9PnRoaXMuY2FsbChhLnB1c2gsJCk7cHVsbD0oJCk9PnRoaXMuY2FsbChhLnB1bGwsJCk7bGlzdGVuPWFzeW5jKCQsSixaKT0+e2xldHtjbG9jazpRLHRyYW5zcG9ydDpZfT10aGlzLHtsaXN0ZW5lcjpWfT1ZLFg9YXdhaXQgdGhpcy5pZGVudGl0eSgpLFc9US5ub3coKSxbeixLXT1hd2FpdCBLSihYLFcpO2lmKEshPT0wKXJldHVybiBLO3JldHVybiBhd2FpdCBWLmNvbm5lY3QoeiwkLEosWil9O2lzQ29ubmVjdGVkKCl7bGV0ICQ9dGhpcy50cmFuc3BvcnQ/Lmxpc3RlbmVyO2lmKCQmJnR5cGVvZiAkLmNvbm5lY3RlZD09PSJmdW5jdGlvbiIpcmV0dXJuICQuY29ubmVjdGVkKCk7cmV0dXJuITB9Y2xvc2VMaXN0ZW5lcigpe3RoaXMudHJhbnNwb3J0Py5saXN0ZW5lcj8uZGlzY29ubmVjdCgpfX12YXIgTUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJTdHJpbmcoSi5sYmwpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5pZHgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJJbnQoSi5udW0pO2lmKFkhPT0wKXJldHVybiBZO3JldHVybiAkLndyaXRlQnl0ZXMoSi5oc2gpLCQud3JpdGVCeXRlcyhKLnNpZyksMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhclN0cmluZygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZEJ5dGVzKFAkKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRCeXRlcyhBMCk7aWYoRiE9PTApcmV0dXJuIEcoRik7cmV0dXJuIE8oe2xibDpKLGlkeDpRLG51bTpWLGhzaDpXLHNpZzpLfSl9fTt2YXIgSUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVTdHJ1Y3QoTUosSi5oZWFkKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoSi5pbmRleEVuYyk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9JC53cml0ZVZhckJ5dGVzKEouYm9keUVuYyk7aWYoWSE9PTApcmV0dXJuIFk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRTdHJ1Y3QoTUopO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckJ5dGVzKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7aGVhZDpKLGluZGV4RW5jOlEsYm9keUVuYzpWfSl9fTt2YXIgQ0o9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLmtkbSk7bGV0IFo9JC53cml0ZVZhckJ5dGVzKEouaGVhZENwaCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLmxlbkJvZHkpO2lmKFEhPT0wKXJldHVybiBRO2lmKEoubGVuQm9keT4wJiZKLm9mZkJvZHkhPT12b2lkIDApe2xldCBZPSQud3JpdGVWYXJJbnQoSi5vZmZCb2R5KTtpZihZIT09MClyZXR1cm4gWX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKF8wKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXO2lmKFY+MCl7bGV0W3osS109JC5yZWFkVmFySW50KCk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBPKHtrZG06SixoZWFkQ3BoOlEsbGVuQm9keTpWLG9mZkJvZHk6V30pfX07YXN5bmMgZnVuY3Rpb24gYlooJCxKLFosUSxZKXtsZXQgVj1hd2FpdCBZLmRlcml2ZUlkZW50aXR5KCQsSiksWD1uZXcgUyxXPW5ldyBTLHo9MCxLPTA7Zm9yKGxldCBQIG9mIFope2xldCBDPW5ldyBTLFQ9Qy53cml0ZVN0cnVjdChHMCxQLmhlYWQpO2lmKFQhPT0wKXJldHVybiBHKFQpO2xldCBJPUMucmVzdWx0KCksQT1hd2FpdCBWLmtkbUZvcihJKSxMPVkuZGVyaXZlQ2lwaGVyKEEsImVuY3J5cHQiKSxnPWF3YWl0IEwuZW5jcnlwdChJKSxmPVAuYm9keT9hd2FpdCBMLmVuY3J5cHQoUC5ib2R5KTpuZXcgVWludDhBcnJheSgwKSxrPVAuaGVhZC5sZW4+MCYmUC5oZWFkLmhzaCE9PXZvaWQgMD9mLmxlbmd0aDowLHk9e2tkbTpBLGhlYWRDcGg6ZyxsZW5Cb2R5Omssb2ZmQm9keTprPjA/Szp2b2lkIDB9LGg9WC53cml0ZVN0cnVjdChDSix5KTtpZihoIT09MClyZXR1cm4gRyhoKTtpZihQLmJvZHkpVy53cml0ZUJ5dGVzKGYpLEsrPWYubGVuZ3RoO3orK31sZXQgRj1XLnJlc3VsdCgpLE49WC5yZXN1bHQoKSxVPWF3YWl0IFEuYmxha2UzKE4pLFI9YXdhaXQgVi5zaWduKFUpLEg9e2xibDokLGlkeDpKLG51bTp6LGhzaDpVLHNpZzpSfSxxPW5ldyBTO3Eud3JpdGVTdHJ1Y3QoSUose2hlYWQ6SCxpbmRleEVuYzpOLGJvZHlFbmM6Rn0pO2xldCBNPXEucmVzdWx0KCk7cmV0dXJuIE8oTSl9YXN5bmMgZnVuY3Rpb24gaFooJCxKLFope2xldFtRLFldPUlKLmRlY29kZShuZXcgbSgkKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0e2hlYWQ6VixpbmRleEVuYzpYLGJvZHlFbmM6V309USx6PWF3YWl0IFouZGVyaXZlSWRlbnRpdHkoVi5sYmwsVi5pZHgpO2lmKCFhd2FpdCBKLmNoZWNrU2lnRWQyNTUxOShWLnNpZyxWLmhzaCx6LnB1YmxpY0tleSkpcmV0dXJuIEcoMyk7bGV0IEY9YXdhaXQgSi5ibGFrZTMoWCk7aWYoIXIoRixWLmhzaCkpcmV0dXJuIEcoMTkpO2xldCBOPW5ldyBtKFgpLFU9W107Zm9yKGxldCBIPTA7SDxWLm51bTtIKyspe2xldFtxLE1dPU4ucmVhZFN0cnVjdChDSik7aWYoTSE9PTApcmV0dXJuIEcoTSk7VS5wdXNoKHEpfWlmKFUubGVuZ3RoIT09Vi5udW0pcmV0dXJuIEcoMTQpO2xldCBSPVtdO2ZvcihsZXQgSCBvZiBVKXtsZXQgcT1aLmRlcml2ZUNpcGhlcihILmtkbSwiZGVjcnlwdCIpLE07dHJ5e009YXdhaXQgcS5kZWNyeXB0KEguaGVhZENwaCl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldFtQLENdPUcwLmRlY29kZShuZXcgbShNKSk7aWYoQyE9PTApcmV0dXJuIEcoQyk7bGV0IFQ7aWYoSC5sZW5Cb2R5PjAmJkgub2ZmQm9keSE9PXZvaWQgMCl7aWYoUC5oc2g9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldCBJPVcuc2xpY2UoSC5vZmZCb2R5LEgub2ZmQm9keStILmxlbkJvZHkpO3RyeXtUPWF3YWl0IHEuZGVjcnlwdChJKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IEE9YXdhaXQgSi5ibGFrZTMoVCk7aWYoIXIoQSxQLmhzaCkpcmV0dXJuIEcoMTkpfVIucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBPKFIpfWFzeW5jIGZ1bmN0aW9uIGlaKHtub3c6JCxib2Q6SixjcnlwdG86Wn0pe2xldCBRPWF3YWl0IFouZ2VuUmFuZG9tQnl0ZXMoOCksWT1uZXcgUyxWPVkud3JpdGVTdHJ1Y3QoVjAse2lkOlEsdHM6JH0pO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBYPVkucmVzdWx0KCk7cmV0dXJuIEUkKHtub3c6JCxlaWQ6WCxjdHI6MCxib2Q6SixjcnlwdG86Wn0pfWFzeW5jIGZ1bmN0aW9uIEUkKHtub3c6JCxlaWQ6SixjdHI6Wixib2Q6USxjcnlwdG86WX0pe2xldCBWPW5ldyBtKEopLFtYLFddPVYwLmRlY29kZShWKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1YLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFkuYmxha2UzKFEpO3JldHVybiBPKHtlaWQ6SixvZmY6eixjdHI6WixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIGtZKCQsSil7bGV0IFo9JC5sZW5ndGg8Si5sZW5ndGg/JC5sZW5ndGg6Si5sZW5ndGg7Zm9yKGxldCBRPTA7UTxaO1ErKylpZigkW1FdIT09SltRXSlyZXR1cm4gJFtRXS1KW1FdO3JldHVybiAkLmxlbmd0aC1KLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBPJCgkLEope2xldCBaPUFycmF5LmZyb20oJCk7Wi5zb3J0KGtZKTtsZXQgUT0wO2ZvcihsZXQgWCBvZiBaKVErPVgubGVuZ3RoO2xldCBZPW5ldyBVaW50OEFycmF5KFEpLFY9MDtmb3IobGV0IFggb2YgWilZLnNldChYLFYpLFYrPVgubGVuZ3RoO3JldHVybiBKLmJsYWtlMyhZKX1mdW5jdGlvbiBFWSgkKXtsZXQgSj1uZXcgUyxaPUoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9Si53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBZPUoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBPKEoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIGYkKCQsSil7bGV0IFo9W107Zm9yKGxldCBRIG9mICQpe2xldFtZLFZdPUVZKFEpO2lmKFYhPT0wfHwhWSlyZXR1cm4gRyhWKTtaLnB1c2goWSl9cmV0dXJuIE8oYXdhaXQgTyQoWixKKSl9dmFyIGJHPVN5bWJvbCgiTWFzdGVyU2VlZCIpLGhHPVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksSDA9MzIsbFo9MjQrSDArMTY7ZnVuY3Rpb24gJDAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09SDApcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfWZ1bmN0aW9uIHgwKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PWxaKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX12YXIgbEc9U3ltYm9sKCJFbnRpdHlJRCIpO2Z1bmN0aW9uIHVaKCQpe3JldHVybiJ0eXBlImluICR9dmFyIHVHPVN5bWJvbCgiRGVyaXZhdGlvblNlZWQiKSxwRz1TeW1ib2woIlB1YmxpY0tleSIpLGNHPVN5bWJvbCgiUHJpdmF0ZUtleSIpLG5HPVN5bWJvbCgiSG9zdFNwZWNpZmljS2V5UGFpciIpLGRHPVN5bWJvbCgiSGFzaCIpO2Z1bmN0aW9uIGZZKCQpe2lmKCEkKXJldHVybiExO2lmKHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoImJvZHkiaW4gJD09PSExKXJldHVybiExO2lmKCJ0eXBlImluICQ9PT0hMSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBnWSgkKXtpZighJC5ib2R8fCQuYm9kLmxlbmd0aD09PTApe2xldCBRPXtvZmY6JC5vZmYsY3RyOiQuY3RyLGVpZDokLmVpZH07cmV0dXJuIE8oUSl9bGV0IEo9ekooJC5ib2QpO2lmKGZZKEopPT09ITEpcmV0dXJuIGNvbnNvbGUud2FybigibXNnIGJvZHkgaW52YWxpZCIsSiksRygxNCk7bGV0IFo9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkLGdpZDpKLmdpZCxwaWQ6Si5waWQsdGFnczpKLnRhZ3MsdHlwZTpKLnR5cGUsYm9keTpKLmJvZHl9O3JldHVybiBPKFopfWNsYXNzIGcke2FwcGxpZXI7ZW1pdHRlcj1uZXcgRiQ7Y2xlYXJlcjtvbkRpcnR5RWlkcztjYWNoZURyaXZlbjtwZWVySW5nZXN0O2NvbnN0cnVjdG9yKCQsSixaLFEpe3RoaXMuYXBwbGllcj0kO3RoaXMuY2xlYXJlcj1KLHRoaXMub25EaXJ0eUVpZHM9Wix0aGlzLmNhY2hlRHJpdmVuPVE/LmNhY2hlRHJpdmVuPz8hMSx0aGlzLnBlZXJJbmdlc3Q9UT8ucGVlckluZ2VzdH1hcHBseT1hc3luYygkKT0+e2xldCBKPVtdLFo9W107Zm9yKGxldCBXIG9mICQpe2xldFt6LEtdPWdZKFcpO2lmKFoucHVzaChLKSxLIT09MCljb250aW51ZTtKLnB1c2goeil9bGV0e3N0YXRzOlEsdHlwZXM6WSxlaWRzOlZ9PWF3YWl0IHRoaXMuYXBwbGllcihKKSxYPVtdO2ZvcihsZXQgVz0wO1c8JC5sZW5ndGg7VysrKXtsZXQgej1aW1ddLEs9UVtXXTtpZih6IT09MCl7WC5wdXNoKHopO2NvbnRpbnVlfWlmKEshPT0wKXtYLnB1c2goSyk7Y29udGludWV9WC5wdXNoKDApfWlmKCF0aGlzLmNhY2hlRHJpdmVuKWZvcihsZXQgVyBvZiBZKXRoaXMuZW1pdHRlci5lbWl0KFcsbnVsbCk7aWYoVi5sZW5ndGg+MCl0aGlzLm9uRGlydHlFaWRzPy4oVik7cmV0dXJuIFh9O2NsZWFyPWFzeW5jKCk9PntsZXQgJD1hd2FpdCB0aGlzLmNsZWFyZXIoKTtpZigkIT09MClyZXR1cm4gJDtyZXR1cm4gdGhpcy5lbWl0dGVyLmVtaXRBbGwobnVsbCksJH07bm90aWZ5PSgkKT0+e2ZvcihsZXQgSiBvZiAkKXRoaXMuZW1pdHRlci5lbWl0KEosbnVsbCl9O3JlZnJlc2g9YXN5bmMoJCk9PntpZih0aGlzLnBlZXJJbmdlc3Qpe2F3YWl0IHRoaXMucGVlckluZ2VzdCgkKTtyZXR1cm59fTtvbj0oJCxKKT0+e3RoaXMuZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKCQsSil9O29mZj0oJCxKKT0+e3RoaXMuZW1pdHRlci5yZW1vdmVFdmVudExpc3RlbmVyKCQsSil9fXZhciBuPSJlbnRpdGllcyIsbSQ9ImVudGl0eV90eXBlX2NyZWF0ZWRfYXQiLHdKPSJlbnRpdHlfdHlwZV91cGRhdGVkX2F0IixUSj0iZW50aXR5X3R5cGVfZ3JvdXBfaWQiLGpKPSJlbnRpdHlfdHlwZV9wYXJlbnRfaWQiLHQwPSJlbnRpdHlfdGFncyIscFo9ImRiIixjWj0xMztmdW5jdGlvbiBtWSgkKXtyZXR1cm4idHlwImluICR9ZnVuY3Rpb24gU1koJCl7bGV0IEo9e2JvZDokLmJvZHksY3JkOiQuY3JlYXRlZEF0LC4uLiQuY3RyIT09MD97Y3RyOiQuY3RyfTp7fSxlaWQ6QigkLmVpZCksZ2lkOiQuZ2lkLHBpZDokLnBpZD9CKCQucGlkKTp2b2lkIDAsdGdzOiQudGFncyx0eXA6JC50eXBlLHVwZDokLnVwZGF0ZWRBdH07aWYoSi5naWQ9PT12b2lkIDApZGVsZXRlIEouZ2lkO2lmKEoucGlkPT09dm9pZCAwKWRlbGV0ZSBKLnBpZDtpZihKLnRncz09PXZvaWQgMClkZWxldGUgSi50Z3M7aWYoSi5jdHI9PT12b2lkIDApZGVsZXRlIEouY3RyO3JldHVybiBKfWZ1bmN0aW9uIHZZKCQpe2lmKCFsKCQpKXJldHVybntlaWQ6QigkLmVpZCksdXBkOiQudXBkYXRlZEF0LC4uLiQuY3RyIT09MD97Y3RyOiQuY3RyfTp7fX07cmV0dXJuIFNZKCQpfWZ1bmN0aW9uIGUwKCQpe3JldHVybntib2R5OiQuYm9kLGNyZWF0ZWRBdDokLmNyZCx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wLHR5cGU6JC50eXAsZWlkOk4wKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP04wKCQucGlkKTp2b2lkIDAsLi4uJC50Z3MhPT12b2lkIDA/e3RhZ3M6JC50Z3N9Ont9fX1mdW5jdGlvbiBQSigkKXtpZihtWSgkKSlyZXR1cm4gZTAoJCk7cmV0dXJue2VpZDpOMCgkLmVpZCksdXBkYXRlZEF0OiQudXBkLGN0cjokLmN0cj8/MH19Y2xhc3Mgblp7ZGI7b3BlbmluZzthc3luYyBpbml0KCl7YXdhaXQgdGhpcy5lbnN1cmVEYigpfWFzeW5jIGVuc3VyZURiKCl7aWYodGhpcy5kYilyZXR1cm4gdGhpcy5kYjtpZih0aGlzLm9wZW5pbmcpcmV0dXJuIHRoaXMub3BlbmluZztyZXR1cm4gdGhpcy5vcGVuaW5nPWJZKCkudGhlbigoJCk9PntyZXR1cm4gJC5vbnZlcnNpb25jaGFuZ2U9KCk9PntpZigkLmNsb3NlKCksdGhpcy5kYj09PSQpdGhpcy5kYj12b2lkIDB9LHRoaXMuZGI9JCx0aGlzLm9wZW5pbmc9dm9pZCAwLCR9LCgkKT0+e3Rocm93IHRoaXMub3BlbmluZz12b2lkIDAsJH0pLHRoaXMub3BlbmluZ31hcHBseT1hc3luYygkKT0+e2xldCBKPW5ldyBTZXQsWj1bXSxRO3RyeXtRPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm57c3RhdHM6JC5tYXAoKCk9PjE2KSx0eXBlczpKLGVpZHM6Wn19bGV0IFk9US50cmFuc2FjdGlvbihuLCJyZWFkd3JpdGUiKSxWPVkub2JqZWN0U3RvcmUobik7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBXPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO2lmKCQubGVuZ3RoPDEpe1goe3N0YXRzOltdLHR5cGVzOkosZWlkczpafSk7cmV0dXJufVkub25jb21wbGV0ZT0oKT0+e1goe3N0YXRzOlcsdHlwZXM6SixlaWRzOlp9KX0sWS5vbmVycm9yPSgpPT57Zm9yKGxldCBLPTA7SzxXLmxlbmd0aDtLKyspaWYoV1tLXT09PXZvaWQgMClXW0tdPTE4O1goe3N0YXRzOlcsdHlwZXM6SixlaWRzOlp9KX07bGV0IHo9bmV3IE1hcDtmb3IobGV0IEs9MDtLPCQubGVuZ3RoO0srKyl7bGV0IEY9JFtLXSxOPUIoRi5laWQpLFU9e29wOkYsaW5kZXg6S30sUj16LmdldChOKTtpZihSKVIucHVzaChVKTtlbHNlIHouc2V0KE4sW1VdKX1mb3IobGV0W0ssRl1vZiB6KXtpZihGLmxlbmd0aDwxKWNvbnRpbnVlO2xldCBOPVYuZ2V0KEspO04ub25zdWNjZXNzPSgpPT57bGV0IFU9Ti5yZXN1bHQsUj1VP1BKKFUpOnZvaWQgMCxIPSExO2ZvcihsZXR7b3A6cSxpbmRleDpNfW9mIEYpe2xldFtQLENdPSQkKFIscSk7aWYoQyE9PTApe1dbTV09Qztjb250aW51ZX1pZihQPT09dm9pZCAwKXtXW01dPTEyO2NvbnRpbnVlfUg9ITA7Zm9yKGxldCBUIG9mIEokKFIsUCkpSi5hZGQoVCk7Uj1QfWlmKEgpWi5wdXNoKEZbMF0ub3AuZWlkKTtpZihSKXtsZXQgcT1WLnB1dCh2WShSKSk7cS5vbmVycm9yPShNKT0+e00ucHJldmVudERlZmF1bHQoKTtmb3IobGV0e2luZGV4OlB9b2YgRilXW1BdPTE4fX19LE4ub25lcnJvcj0oKT0+e2ZvcihsZXR7aW5kZXg6VX1vZiBGKVdbVV09MTh9fX0pfTthc3luYyBjbGVhcigpe2xldCAkO3RyeXskPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gMTZ9bGV0IEo9JC50cmFuc2FjdGlvbihuLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUobik7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e0oub25jb21wbGV0ZT0oKT0+USgwKSxKLm9uZXJyb3I9KCk9PlEoMTgpLFouY2xlYXIoKX0pfWFzeW5jIGdldFJvdygkKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBaPUIoJCksWT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobik7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVkuZ2V0KFopO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7aWYoIVcpVihPKHZvaWQgMCkpO2Vsc2UgVihPKFBKKFcpKSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IWwoSikpcmV0dXJuIE8odm9pZCAwKTtyZXR1cm4gTyhKKX1hc3luYyBnZXRBbGxPZlR5cGVVcGRhdGVkQmV0d2VlbigkLEosWil7bGV0IFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgVj1RLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgod0opO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgVz1WLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbJCxKXSxbJCxaXSkpO1cub25zdWNjZXNzPSgpPT57bGV0IHo9Vy5yZXN1bHQ7WChPKHoubWFwKGUwKSkpfSxXLm9uZXJyb3I9KCk9PlgoRygxOCkpfSl9YXN5bmMgZ2V0R3JvdXBNZW1iZXJzKCQsSil7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWT1aLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgoVEopO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1ZLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFskLEpdKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtWKE8oVy5tYXAoZTApKSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRBbGxPZlR5cGUoJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgobSQpO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVj1RLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgWD1WLnJlc3VsdDtZKE8oWC5tYXAoZTApKSl9LFYub25lcnJvcj0oKT0+WShHKDE4KSl9KX1hc3luYyBnZXRCeVRhZygkLEope2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFk9Wi50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KHQwKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9WS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShKKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgej1YLnJlc3VsdC5maWx0ZXIoKEspPT5LLnR5cD09PSQpLm1hcChlMCk7VihPKHopKX0sWC5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfWFzeW5jIGdldEFsbEVudGl0aWVzKCQpe2lmKCJwaWQiaW4gJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWj1CKCQucGlkKSxZPUoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChqSik7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVkuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQudHlwZSxaXSkpO1gub25zdWNjZXNzPSgpPT57bGV0IHo9WC5yZXN1bHQubWFwKGUwKTtWKE8oeikpfSxYLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9ZWxzZSBpZigiZ2lkImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0R3JvdXBNZW1iZXJzKCQudHlwZSwkLmdpZCk7ZWxzZSBpZigidGFnImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QnlUYWcoJC50eXBlLCQudGFnKTtlbHNlIGlmKCJ1cGRhdGVkQmV0d2VlbiJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQudHlwZSwkLnVwZGF0ZWRCZXR3ZWVuLnN0YXJ0LCQudXBkYXRlZEJldHdlZW4uZW5kKTtyZXR1cm4gYXdhaXQgdGhpcy5nZXRBbGxPZlR5cGUoJC50eXBlKX1hc3luYyBnZXRFbnRpdGllcygkKXtsZXRbSixaXT1hd2FpdCB0aGlzLmdldEFsbEVudGl0aWVzKCQpO2lmKFohPT0wKXJldHVybiBHKFopO3JldHVybiBPKEopfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KG0kKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9SURCS2V5UmFuZ2UuYm91bmQoWyRdLFskLFtdXSksWD1RLmNvdW50KFYpO1gub25zdWNjZXNzPSgpPT5ZKE8oWC5yZXN1bHQpKSxYLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgY2hlY2tzdW0oJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobiksWT1bXTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9US5vcGVuQ3Vyc29yKCk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtpZihXKXtsZXQgej1XLnZhbHVlO1kucHVzaChTJChQSih6KSkpLFcuY29udGludWUoKX1lbHNlIGYkKFksJCkudGhlbihWKX0sWC5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfX1mdW5jdGlvbiB5WSgkLEope2lmKCEkLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMobikpJC5jcmVhdGVPYmplY3RTdG9yZShuLHtrZXlQYXRoOiJlaWQiLGF1dG9JbmNyZW1lbnQ6ITF9KTtsZXQgWj1KLm9iamVjdFN0b3JlKG4pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMobSQpKVouY3JlYXRlSW5kZXgobSQsWyJ0eXAiLCJjcmQiXSx7dW5pcXVlOiExfSk7aWYoIVouaW5kZXhOYW1lcy5jb250YWlucyh3SikpWi5jcmVhdGVJbmRleCh3SixbInR5cCIsInVwZCJdLHt1bmlxdWU6ITF9KTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKFRKKSlaLmNyZWF0ZUluZGV4KFRKLFsidHlwIiwiZ2lkIl0se3VuaXF1ZTohMX0pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoakopKVouY3JlYXRlSW5kZXgoakosWyJ0eXAiLCJwaWQiXSx7dW5pcXVlOiExfSk7aWYoWi5pbmRleE5hbWVzLmNvbnRhaW5zKHQwKSl7aWYoWi5pbmRleCh0MCkua2V5UGF0aCE9PSJ0Z3MiKVouZGVsZXRlSW5kZXgodDApfWlmKCFaLmluZGV4TmFtZXMuY29udGFpbnModDApKVouY3JlYXRlSW5kZXgodDAsInRncyIse3VuaXF1ZTohMSxtdWx0aUVudHJ5OiEwfSl9ZnVuY3Rpb24gYlkoKXtyZXR1cm4gbmV3IFByb21pc2UoKCQsSik9PntsZXQgWj1pbmRleGVkREIub3BlbihwWixjWik7Wi5vbnVwZ3JhZGVuZWVkZWQ9KCk9PntsZXR7cmVzdWx0OlEsdHJhbnNhY3Rpb246WX09WjtpZighWSl7SihFcnJvcigiVHJhbnNhY3Rpb24gaXMgbnVsbCBkdXJpbmcgRW50REIgdXBncmFkZSIpKTtyZXR1cm59dHJ5e3lZKFEsWSl9Y2F0Y2goVil7SihWIGluc3RhbmNlb2YgRXJyb3I/VjpFcnJvcihTdHJpbmcoVikpKX19LFoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gRW50REIgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtwWn0g4oaSIHYke2NafSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LFoub25zdWNjZXNzPSgpPT4kKFoucmVzdWx0KSxaLm9uZXJyb3I9KCk9PkooWi5lcnJvcj8/RXJyb3IoIkVudERCIEluZGV4ZWREQiBvcGVuIGZhaWxlZCIpKX0pfWFzeW5jIGZ1bmN0aW9uIGRaKCl7bGV0ICQ9bmV3IG5aO3JldHVybiBhd2FpdCAkLmluaXQoKSwkfWNsYXNzIERKe2VudHM9bmV3IE1hcDt1c2VJbmRleDtieVR5cGU9bmV3IE1hcDtieVR5cGVQaWQ9bmV3IE1hcDtieVR5cGVHaWQ9bmV3IE1hcDtieVR5cGVUYWc9bmV3IE1hcDtjb25zdHJ1Y3RvcigkPVtdLEope3RoaXMudXNlSW5kZXg9Sj8uaW5kZXhlcyE9PSExO2ZvcihsZXQgWiBvZiAkKXRoaXMucHV0KFopfXB1dCgkKXtsZXQgSj1CKCQuZWlkKSxaPXRoaXMuZW50cy5nZXQoSik7aWYoWiE9PXZvaWQgMCYmbChaKSl0aGlzLnVuaW5kZXgoSixaKTtpZih0aGlzLmVudHMuc2V0KEosJCksbCgkKSl0aGlzLmluZGV4KEosJCl9ZGVsKCQpe2xldCBKPXRoaXMuZW50cy5nZXQoJCk7aWYoSj09PXZvaWQgMClyZXR1cm47aWYobChKKSl0aGlzLnVuaW5kZXgoJCxKKTt0aGlzLmVudHMuZGVsZXRlKCQpfWluZGV4KCQsSil7aWYoIXRoaXMudXNlSW5kZXgpcmV0dXJuO2xldCBaPXRoaXMuYnlUeXBlLmdldChKLnR5cGUpO2lmKCFaKVo9bmV3IE1hcCx0aGlzLmJ5VHlwZS5zZXQoSi50eXBlLFopO2lmKFouc2V0KCQsSiksSi5waWQpe2xldCBRPUIoSi5waWQpLFk9dGhpcy5ieVR5cGVQaWQuZ2V0KEoudHlwZSk7aWYoIVkpWT1uZXcgTWFwLHRoaXMuYnlUeXBlUGlkLnNldChKLnR5cGUsWSk7bGV0IFY9WS5nZXQoUSk7aWYoIVYpVj1uZXcgTWFwLFkuc2V0KFEsVik7Vi5zZXQoJCxKKX1pZih0eXBlb2YgSi5naWQ9PT0ic3RyaW5nIil7bGV0IFE9dGhpcy5ieVR5cGVHaWQuZ2V0KEoudHlwZSk7aWYoIVEpUT1uZXcgTWFwLHRoaXMuYnlUeXBlR2lkLnNldChKLnR5cGUsUSk7bGV0IFk9US5nZXQoSi5naWQpO2lmKCFZKVk9bmV3IE1hcCxRLnNldChKLmdpZCxZKTtZLnNldCgkLEopfWlmKEoudGFncyl7bGV0IFE9dGhpcy5ieVR5cGVUYWcuZ2V0KEoudHlwZSk7aWYoIVEpUT1uZXcgTWFwLHRoaXMuYnlUeXBlVGFnLnNldChKLnR5cGUsUSk7Zm9yKGxldCBZIG9mIEoudGFncyl7bGV0IFY9US5nZXQoWSk7aWYoIVYpVj1uZXcgTWFwLFEuc2V0KFksVik7Vi5zZXQoJCxKKX19fXVuaW5kZXgoJCxKKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IFo9dGhpcy5ieVR5cGUuZ2V0KEoudHlwZSk7aWYoWil7aWYoWi5kZWxldGUoJCksWi5zaXplPT09MCl0aGlzLmJ5VHlwZS5kZWxldGUoSi50eXBlKX1pZihKLnBpZCl7bGV0IFE9QihKLnBpZCksWT10aGlzLmJ5VHlwZVBpZC5nZXQoSi50eXBlKSxWPVk/LmdldChRKTtpZihWKXtpZihWLmRlbGV0ZSgkKSxWLnNpemU9PT0wKVk/LmRlbGV0ZShRKX1pZihZJiZZLnNpemU9PT0wKXRoaXMuYnlUeXBlUGlkLmRlbGV0ZShKLnR5cGUpfWlmKHR5cGVvZiBKLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoSi50eXBlKSxZPVE/LmdldChKLmdpZCk7aWYoWSl7aWYoWS5kZWxldGUoJCksWS5zaXplPT09MClRPy5kZWxldGUoSi5naWQpfWlmKFEmJlEuc2l6ZT09PTApdGhpcy5ieVR5cGVHaWQuZGVsZXRlKEoudHlwZSl9aWYoSi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoSi50eXBlKTtpZihRKXtmb3IobGV0IFkgb2YgSi50YWdzKXtsZXQgVj1RLmdldChZKTtpZihWKXtpZihWLmRlbGV0ZSgkKSxWLnNpemU9PT0wKVEuZGVsZXRlKFkpfX1pZihRLnNpemU9PT0wKXRoaXMuYnlUeXBlVGFnLmRlbGV0ZShKLnR5cGUpfX19Y2xlYXJJbmRleGVzKCl7dGhpcy5ieVR5cGUuY2xlYXIoKSx0aGlzLmJ5VHlwZVBpZC5jbGVhcigpLHRoaXMuYnlUeXBlR2lkLmNsZWFyKCksdGhpcy5ieVR5cGVUYWcuY2xlYXIoKX1idWNrZXRMaXN0KCQpe2lmKCEkfHwkLnNpemU9PT0wKXJldHVybltdO2xldCBKPVtdO2ZvcihsZXQgWiBvZiAkLnZhbHVlcygpKUoucHVzaChaKTtyZXR1cm4gSn1hc3luYyBhcHBseSgkKXtsZXQgSj1uZXcgU2V0LFo9W10sUT1bXTtmb3IobGV0IFkgb2YgJCl7bGV0IFY9QihZLmVpZCksWD10aGlzLmVudHMuZ2V0KFYpLFtXLHpdPSQkKFgsWSk7aWYoeiE9PTApe1EucHVzaCh6KTtjb250aW51ZX1pZihXPT09dm9pZCAwKXtRLnB1c2goMTIpO2NvbnRpbnVlfWZvcihsZXQgSyBvZiBKJChYLFcpKUouYWRkKEspO3RoaXMucHV0KFcpLFoucHVzaChZLmVpZCksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOkosZWlkczpafX1hc3luYyBjbGVhcigpe3JldHVybiB0aGlzLmVudHMuY2xlYXIoKSx0aGlzLmNsZWFySW5kZXhlcygpLDB9YXN5bmMgZ2V0Um93KCQpe2xldCBKPUIoJCksWj10aGlzLmVudHMuZ2V0KEopO3JldHVybiBPKFopfWFzeW5jIGdldEVudCgkKXtsZXRbSixaXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwfHwhbChKKSlyZXR1cm4gTyh2b2lkIDApO3JldHVybiBPKEopfWFzeW5jIGdldEFsbEVudGl0aWVzKHt0eXBlOiQsZ2lkOkoscGlkOlosdGFnOlEsdXBkYXRlZEJldHdlZW46WX0pe2lmKHRoaXMudXNlSW5kZXgpe2lmKFohPT12b2lkIDApe2xldCBYPUIoWik7cmV0dXJuIE8odGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlUGlkLmdldCgkKT8uZ2V0KFgpKSl9aWYoSiE9PXZvaWQgMClyZXR1cm4gTyh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVHaWQuZ2V0KCQpPy5nZXQoSikpKTtpZihRIT09dm9pZCAwKXJldHVybiBPKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZVRhZy5nZXQoJCk/LmdldChRKSkpO2lmKFkhPT12b2lkIDApe2xldCBYPVtdLFc9dGhpcy5ieVR5cGUuZ2V0KCQpO2lmKFcpe2ZvcihsZXQgeiBvZiBXLnZhbHVlcygpKWlmKHoudXBkYXRlZEF0Pj1ZLnN0YXJ0JiZ6LnVwZGF0ZWRBdDw9WS5lbmQpWC5wdXNoKHopfXJldHVybiBPKFgpfXJldHVybiBPKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZS5nZXQoJCkpKX1sZXQgVj1bXTtpZihaIT09dm9pZCAwKXtmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQmJlgucGlkJiZyKFgucGlkLFopKVYucHVzaChYKX1lbHNlIGlmKEohPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JCYmKHR5cGVvZiBYLmdpZD09PSJzdHJpbmciJiZYLmdpZD09PUopKVYucHVzaChYKX1lbHNlIGlmKFEhPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JCYmWC50YWdzJiZYLnRhZ3MuaW5jbHVkZXMoUSkpVi5wdXNoKFgpfWVsc2UgaWYoWSE9PXZvaWQgMCl7Zm9yKGxldCBYIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihsKFgpJiZYLnR5cGU9PT0kJiZYLnVwZGF0ZWRBdD49WS5zdGFydCYmWC51cGRhdGVkQXQ8PVkuZW5kKVYucHVzaChYKX1lbHNlIGZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JClWLnB1c2goWCk7cmV0dXJuIE8oVil9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gTyhKKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZih0aGlzLnVzZUluZGV4KXJldHVybiBPKHRoaXMuYnlUeXBlLmdldCgkKT8uc2l6ZT8/MCk7bGV0IEo9MDtmb3IobGV0IFogb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWikmJloudHlwZT09PSQpSis9MTtyZXR1cm4gTyhKKX1hc3luYyBjaGVja3N1bSgkKXtsZXQgSj1bXTtmb3IobGV0IFogb2YgdGhpcy5lbnRzLnZhbHVlcygpKUoucHVzaChTJChaKSk7cmV0dXJuIGYkKEosJCl9fWFzeW5jIGZ1bmN0aW9uIHJaKCQpe2xldCBKPWF3YWl0IGRaKCk7aWYoJD8uY2FjaGU9PT0hMSlyZXR1cm4gSjtyZXR1cm4gbmV3IEFKKEosdm9pZCAwLHtpbmRleGVzOiQ/LmluZGV4ZXN9KX1jbGFzcyBBSnttZW07ZHVyYWJsZTt3YXJtZWQ9bmV3IFNldDtsaXN0ZW5lcnM9bmV3IFNldDtjaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtjb25zdHJ1Y3RvcigkLEosWil7aWYodGhpcy5kdXJhYmxlPSQsdGhpcy5tZW09bmV3IERKKEo/P1tdLHtpbmRleGVzOlo/LmluZGV4ZXN9KSxKKWZvcihsZXQgUSBvZiBKKXRoaXMud2FybWVkLmFkZChRLnR5cGUpfXN1YnNjcmliZSgkKXtyZXR1cm4gdGhpcy5saXN0ZW5lcnMuYWRkKCQpLCgpPT57dGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQpe2lmKCQuc2l6ZTwxKXJldHVybjtmb3IobGV0IEogb2YgdGhpcy5saXN0ZW5lcnMpSigkKX1ydW4oJCl7bGV0IEo9dGhpcy5jaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuY2hhaW49Si50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLEp9YXBwbHkoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9Pnthd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChWKT0+Vi5laWQpKTtsZXQgSj1jWSh0aGlzLm1lbSwkKTt0aGlzLmVtaXQoSi50eXBlcyk7bGV0IFo9YXdhaXQgdGhpcy5kdXJhYmxlLmFwcGx5KCQpLHtjaGFuZ2VkOlEsc3RhdHVzOll9PWF3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFYpPT5WLmVpZCkpO2lmKHRoaXMuZW1pdChRKSxZIT09MClyZXR1cm57c3RhdHM6JC5tYXAoKCk9PlkpLHR5cGVzOloudHlwZXMsZWlkczpaLmVpZHN9O3JldHVybiBafSl9Y2xlYXIoKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuZHVyYWJsZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBKPXRoaXMubWVtLmVudHMuc2l6ZT4wO3JldHVybiBhd2FpdCB0aGlzLm1lbS5jbGVhcigpLHRoaXMud2FybWVkLmNsZWFyKCksMH0pfWluZ2VzdEZyb21EdXJhYmxlKCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0e2NoYW5nZWQ6SixzdGF0dXM6Wn09YXdhaXQgdGhpcy5wdWxsRWlkcygkKTtyZXR1cm4gdGhpcy5lbWl0KEopLFp9KX1hc3luYyBwdWxsRWlkcygkKXtsZXQgSj1uZXcgU2V0LFo9bmV3IFNldDtmb3IobGV0IFEgb2YgJCl7bGV0IFk9QihRKTtpZihaLmhhcyhZKSljb250aW51ZTtaLmFkZChZKTtsZXQgVj10aGlzLm1lbS5lbnRzLmdldChZKSxbWCxXXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KFEpO2lmKFchPT0wKXJldHVybntjaGFuZ2VkOkosc3RhdHVzOld9O2lmKFgpe2lmKHRoaXMubWVtLnB1dChYKSwhVnx8IWhZKFYsWCkpe2lmKGwoWCkpSi5hZGQoWC50eXBlKTtpZihWIT09dm9pZCAwJiZsKFYpKUouYWRkKFYudHlwZSl9fWVsc2UgaWYoViE9PXZvaWQgMCl7aWYodGhpcy5tZW0uZGVsKFkpLGwoVikpSi5hZGQoVi50eXBlKX19cmV0dXJue2NoYW5nZWQ6SixzdGF0dXM6MH19YXN5bmMgd2FybVR5cGUoJCl7aWYodGhpcy53YXJtZWQuaGFzKCQpKXJldHVybiAwO2xldFtKLFpdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRFbnRpdGllcyh7dHlwZTokfSk7aWYoWiE9PTApcmV0dXJuIFo7aWYoSilmb3IobGV0IFEgb2YgSil7bGV0IFk9QihRLmVpZCksVj10aGlzLm1lbS5lbnRzLmdldChZKTtpZighVnx8cFkoUSxWKSl0aGlzLm1lbS5wdXQoUSl9cmV0dXJuIHRoaXMud2FybWVkLmFkZCgkKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgSj1CKCQpO2lmKHRoaXMubWVtLmVudHMuaGFzKEopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntpZih0aGlzLm1lbS5lbnRzLmhhcyhKKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO2xldFtaLFFdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWil0aGlzLm1lbS5wdXQoWik7cmV0dXJuIE8oWil9KX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IWwoSikpcmV0dXJuIE8odm9pZCAwKTtyZXR1cm4gTyhKKX1hc3luYyBnZXRFbnRpdGllcygkKXtpZighdGhpcy53YXJtZWQuaGFzKCQudHlwZSkpe2xldCBKPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQudHlwZSkpO2lmKEohPT0wKXJldHVybiBHKEopfXJldHVybiB0aGlzLm1lbS5nZXRFbnRpdGllcygkKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZighdGhpcy53YXJtZWQuaGFzKCQpKXtsZXQgSj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkKSk7aWYoSiE9PTApcmV0dXJuIEcoSil9cmV0dXJuIHRoaXMubWVtLmNvdW50RW50aXRpZXMoe3R5cGU6JH0pfWFzeW5jIGNoZWNrc3VtKCQpe3JldHVybiB0aGlzLmR1cmFibGUuY2hlY2tzdW0oJCl9fWZ1bmN0aW9uIGhZKCQsSil7aWYobCgkKSE9PWwoSikpcmV0dXJuITE7aWYoJC5jdHIhPT1KLmN0cilyZXR1cm4hMTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCkhPT1KLnVwZGF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoIXIoJC5laWQsSi5laWQpKXJldHVybiExO2lmKCFsKCQpfHwhbChKKSlyZXR1cm4hMDtpZigkLmNyZWF0ZWRBdC5nZXRUaW1lKCkhPT1KLmNyZWF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoJC50eXBlIT09Si50eXBlKXJldHVybiExO2lmKCQuZ2lkIT09Si5naWQpcmV0dXJuITE7aWYoIWxZKCQucGlkLEoucGlkKSlyZXR1cm4hMTtpZighaVkoJC50YWdzLEoudGFncykpcmV0dXJuITE7cmV0dXJuIHVZKCQuYm9keSxKLmJvZHkpfWZ1bmN0aW9uIGlZKCQsSil7aWYoJD09PUopcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Sj09PXZvaWQgMClyZXR1cm4hMTtpZigkLmxlbmd0aCE9PUoubGVuZ3RoKXJldHVybiExO2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKWlmKCRbWl0hPT1KW1pdKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIGxZKCQsSil7aWYoJD09PXZvaWQgMCYmSj09PXZvaWQgMClyZXR1cm4hMDtpZigkPT09dm9pZCAwfHxKPT09dm9pZCAwKXJldHVybiExO3JldHVybiByKCQsSil9ZnVuY3Rpb24gdVkoJCxKKXtpZihPYmplY3QuaXMoJCxKKSlyZXR1cm4hMDtpZigkIGluc3RhbmNlb2YgVWludDhBcnJheSYmSiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuIHIoJCxKKTtpZigkIGluc3RhbmNlb2YgRGF0ZSYmSiBpbnN0YW5jZW9mIERhdGUpcmV0dXJuICQuZ2V0VGltZSgpPT09Si5nZXRUaW1lKCk7dHJ5e3JldHVybiByKEUwKCQpLEUwKEopKX1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gcFkoJCxKKXtsZXQgWj0kLnVwZGF0ZWRBdC5nZXRUaW1lKCksUT1KLnVwZGF0ZWRBdC5nZXRUaW1lKCk7aWYoWiE9PVEpcmV0dXJuIFo+UTtyZXR1cm4gJC5jdHI+Si5jdHJ9ZnVuY3Rpb24gY1koJCxKKXtsZXQgWj1uZXcgU2V0LFE9W107Zm9yKGxldCBZIG9mIEope2xldCBWPUIoWS5laWQpLFg9JC5lbnRzLmdldChWKSxbVyx6XT0kJChYLFkpO2lmKHohPT0wKXtRLnB1c2goeik7Y29udGludWV9aWYoVz09PXZvaWQgMCl7US5wdXNoKDEyKTtjb250aW51ZX1mb3IobGV0IEsgb2YgSiQoWCxXKSlaLmFkZChLKTskLnB1dChXKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6Wn19ZnVuY3Rpb24gbCgkKXtyZXR1cm4idHlwZSJpbiAkfWZ1bmN0aW9uIG5ZKCQpe2lmKCFBcnJheS5pc0FycmF5KCQpfHwkLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPW5ldyBTZXQsWj1bXTtmb3IobGV0IFEgb2YgJCl7aWYodHlwZW9mIFEhPT0ic3RyaW5nInx8US5sZW5ndGg9PT0wKWNvbnRpbnVlO2lmKEouaGFzKFEpKWNvbnRpbnVlO0ouYWRkKFEpLFoucHVzaChRKX1yZXR1cm4gWi5sZW5ndGg+MD9aOnZvaWQgMH1mdW5jdGlvbiBTJCgkKXtyZXR1cm57ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6JC51cGRhdGVkQXR9fWZ1bmN0aW9uIG9aKCQpe2xldCBKPW5ldyBtKCQuZWlkKSxbWixRXT1KLnJlYWRTdHJ1Y3QoVjApO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiBPKHtlaWQ6JC5laWQsY3RyOiQuY3RyLHVwZGF0ZWRBdDpuZXcgRGF0ZShaLnRzLmdldFRpbWUoKSskLm9mZil9KX1mdW5jdGlvbiAkJCgkLEope2xldCBaPW5ldyBtKEouZWlkKSxbUSxZXT1aLnJlYWRTdHJ1Y3QoVjApO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBWPW5ldyBEYXRlKFEudHMuZ2V0VGltZSgpK0oub2ZmKTtpZigkIT09dm9pZCAwJiZWPD0kLnVwZGF0ZWRBdClyZXR1cm4gRygxNSk7aWYodVooSikpe2xldCBYPW5ZKEoudGFncyk7cmV0dXJuIE8oe2VpZDpKLmVpZCxnaWQ6Si5naWQscGlkOkoucGlkLC4uLlghPT12b2lkIDA/e3RhZ3M6WH06e30sdHlwZTpKLnR5cGUsY3JlYXRlZEF0OlEudHMsdXBkYXRlZEF0OlYsY3RyOkouY3RyLGJvZHk6Si5ib2R5fSl9cmV0dXJuIE8oe2VpZDpKLmVpZCx1cGRhdGVkQXQ6VixjdHI6Si5jdHJ9KX1mdW5jdGlvbiBKJCgkLEope2xldCBaPW5ldyBTZXQ7aWYoJCE9PXZvaWQgMCYmbCgkKSlaLmFkZCgkLnR5cGUpO2lmKGwoSikpWi5hZGQoSi50eXBlKTtyZXR1cm5bLi4uWl19Y2xhc3MgdiR7aW5mbGlnaHQ9bnVsbDthZ2Fpbj0hMTtydW4oJCl7aWYodGhpcy5hZ2Fpbj0hMCx0aGlzLmluZmxpZ2h0KXJldHVybiB0aGlzLmluZmxpZ2h0O3JldHVybiB0aGlzLmluZmxpZ2h0PXRoaXMuZHJhaW4oJCksdGhpcy5pbmZsaWdodH1hc3luYyBmbHVzaCgpe2lmKCF0aGlzLmluZmxpZ2h0KXJldHVybjt0cnl7YXdhaXQgdGhpcy5pbmZsaWdodH1jYXRjaHt9fWFzeW5jIGRyYWluKCQpe3RyeXt0aGlzLmFnYWluPSExO2xldCBKPWF3YWl0ICQoKTt3aGlsZSh0aGlzLmFnYWluKXRoaXMuYWdhaW49ITEsSj1hd2FpdCAkKCk7cmV0dXJuIEp9ZmluYWxseXt0aGlzLmluZmxpZ2h0PW51bGx9fX12YXIgYVo9MTAwO2NsYXNzIF9Ke3RpbWVyPW51bGw7ZGVsYXlNczt3b3JrO3RhaWw9bmV3IHYkO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5kZWxheU1zPSQ8MD8wOiQsdGhpcy53b3JrPUp9c2NoZWR1bGUoKXtpZih0aGlzLmRlbGF5TXM8PTApe3RoaXMuZmlyZSgpO3JldHVybn1pZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lcik7dGhpcy50aW1lcj1zZXRUaW1lb3V0KCgpPT57dGhpcy50aW1lcj1udWxsLHRoaXMuZmlyZSgpfSx0aGlzLmRlbGF5TXMpfWFzeW5jIGZsdXNoKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKTthd2FpdCB0aGlzLnRhaWwuZmx1c2goKX1jYW5jZWwoKXtpZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj1udWxsfWZpcmUoKXtyZXR1cm4gdGhpcy50YWlsLnJ1bih0aGlzLndvcmspfX1mdW5jdGlvbiBzWigkKXtsZXQgSj1uZXcgbSgkLmVpZCksW1osUV09VjAuZGVjb2RlKEopO2lmKFEhPT0wKXJldHVybjtyZXR1cm4gWi50cy5nZXRUaW1lKCkrJC5vZmZ9ZnVuY3Rpb24gZFkoJCxKKXtsZXQgWj1zWigkKSxRPXNaKEopO2lmKFo9PT12b2lkIDAmJlE9PT12b2lkIDApcmV0dXJuIDA7aWYoWj09PXZvaWQgMClyZXR1cm4gMTtpZihRPT09dm9pZCAwKXJldHVybi0xO2lmKFEhPT1aKXJldHVybiBRLVo7cmV0dXJuIEouY3RyLSQuY3RyfWZ1bmN0aW9uIFokKCQsSil7cmV0dXJuICQuc2xpY2UoKS5zb3J0KChaLFEpPT5kWShKKFopLEooUSkpKX12YXIgTEo9e3BoYXNlOiJpZGxlIn0sVSQ9NTA7ZnVuY3Rpb24geEooJCxKLFope2lmKCQ8PTB8fEo8PTApcmV0dXJuITE7aWYoJD09PTF8fCQ9PT1KKXJldHVybiEwO3JldHVybiAkJVo9PT0wfWZ1bmN0aW9uIHRaKCQsSil7aWYodHlwZW9mIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iPT09ImZ1bmN0aW9uIil7bmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IoJCxKKTtyZXR1cm59bGV0IFo9VVJMLmNyZWF0ZU9iamVjdFVSTCgkKSxRPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTtRLmhyZWY9WixRLmRvd25sb2FkPUosZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChRKSxRLmNsaWNrKCksZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChRKSxVUkwucmV2b2tlT2JqZWN0VVJMKFopfWZ1bmN0aW9uIGVaKCQsSixaKXtsZXQgUT1bXSxZPVtdLFY9MDtmb3IobGV0IFggb2YgJCl7bGV0IFc9SihYKTtpZihZLmxlbmd0aD4wJiZWK1c+WilRLnB1c2goWSksWT1bXSxWPTA7aWYoWS5wdXNoKFgpLFYrPVcsVj49WilRLnB1c2goWSksWT1bXSxWPTB9aWYoWS5sZW5ndGg+MClRLnB1c2goWSk7cmV0dXJuIFF9YXN5bmMgZnVuY3Rpb24gQkooJCxKLFope2xldCBRPSQubGVuZ3RoO2lmKFE8MSlyZXR1cm5bXTtsZXQgWT1BcnJheShRKSxWPTAsWD1NYXRoLm1pbihNYXRoLm1heCgxLEopLFEpLFc9YXN5bmMoKT0+e3doaWxlKCEwKXtsZXQgSz1WO2lmKFYrPTEsSz49USlyZXR1cm47WVtLXT1hd2FpdCBaKCRbS10sSyl9fSx6PVtdO2ZvcihsZXQgSz0wO0s8WDtLKyspei5wdXNoKFcoKSk7cmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKHopLFl9YXN5bmMgZnVuY3Rpb24geSQoJCxKLFosUSl7bGV0IFk9bmV3IG0oJC5oZWFkQ3BoKSxbVixYXT1ZLnJlYWRTdHJ1Y3QoeCQpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldHtzaWc6VyxrZG06eixoZWFkQ3BoOkt9PVY7aWYoIWF3YWl0IFEuY2hlY2tTaWdFZDI1NTE5KFcsSyxKKSlyZXR1cm4gRygzKTtsZXQgTj1aLmRlcml2ZUNpcGhlcih6LCJkZWNyeXB0IiksVTt0cnl7VT1hd2FpdCBOLmRlY3J5cHQoSyl9Y2F0Y2h7cmV0dXJuIEcoMjApfXJldHVybiBPKHtrZG06eixoZWFkRW5jOlV9KX12YXIgWSQ9ImYiLGIkPSJ0IixRJD0iZSI7ZnVuY3Rpb24gclkoJCl7aWYoJD09PSEwfHwkPT09YiQpcmV0dXJuIGIkO2lmKCQ9PT1RJClyZXR1cm4gUSQ7cmV0dXJuIFkkfWZ1bmN0aW9uICRRKCQpe3JldHVybiAkIT09MCYmJCE9PTE1JiYkIT09MTgmJiQhPT0xN31mdW5jdGlvbiBrSigkLEosWil7aWYoJC5hcGxkPUosSj09PVEkJiZaIT09dm9pZCAwKSQuZXJyPVo7ZWxzZSBkZWxldGUgJC5lcnJ9YXN5bmMgZnVuY3Rpb24gaCQoJCxKLFosUSl7bGV0IFk9UT8uYm9keSE9PSExLFY9clkoSi5hcGxkKSxYPUouYm9keSxXPVg/Lmxlbmd0aD8/MCx6O2lmKFkmJlgmJlc+MCl6PWF3YWl0IFouYmxha2UzKFgpO2xldCBLPXtlaWQ6Si5laWQsb2ZmOkoub2ZmPz8wLGN0cjpKLmN0cj8/MCxsZW46Vyxoc2g6en0sRj17aGFzaDokLGhlYWQ6SyxhcGxkOlZ9O2lmKFkmJlghPT12b2lkIDApRi5ib2R5PVg7aWYoVj09PVEkJiZKLmVyciE9PXZvaWQgMClGLmVycj1KLmVycjtyZXR1cm4gRn12YXIgRUo9MTA0ODU3NixmSj0xMDQ4NTc2LFpRPTY0O2Z1bmN0aW9uIG9ZKCQpe3JldHVybiAkLnNpZy5sZW5ndGgrJC5rZG0ubGVuZ3RoKyQuaGVhZENwaC5sZW5ndGgrJC5ib2R5Q3BoLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBhWSgkLEosWixRLFkpe2lmKFEubGVuZ3RoPDEpcmV0dXJuIDA7bGV0W1YsWF09YXdhaXQgJC5wdXNoKFEpO2lmKFghPT0wKXJldHVybiBYO2lmKCFWKXJldHVybiAyNztmb3IobGV0IHogb2YgVil7aWYoei5zdGF0dXMhPT0wKXtjb25zb2xlLmVycm9yKCJwdXNoIGVyciIseik7Y29udGludWV9bGV0IEs9WVt6LmlkeF07aWYoIUspe2NvbnNvbGUuZXJyb3IoIm5vIGhhc2giLHopO2NvbnRpbnVlfWF3YWl0IEoudXBsb2Fkcy5kZXEoWixbS10pfWxldCBXPWF3YWl0IEouaG9zdHMuZ2V0KFopO2lmKFcpe2xldCB6PVcubGFzdFNlcSxLPXosRj1bXTtmb3IobGV0IE4gb2YgVilpZihOLnN0YXR1cz09PTApRi5wdXNoKE4uc2VxKTtGLnNvcnQoKE4sVSk9Pk4tVSk7Zm9yKGxldCBOIG9mIEYpaWYoTj09PXorMSl6PU47aWYoej5LKWF3YWl0IEouaG9zdHMudG91Y2goWix6KX1yZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBKUSgkLEope2lmKEoubGVuZ3RoPDEpcmV0dXJuIE8oW10pO2xldCBaPW5ldyBNYXAsUT1bXTtmb3IobGV0IFcgb2YgSilaLnNldChXLnNlcSxXKSxRLnB1c2goVy5zZXEpO2xldFtZLFZdPWF3YWl0ICQucHVsbChRKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZighWSlyZXR1cm4gRygyNyk7bGV0IFg9W107Zm9yKGxldHtzZXE6Vyxib2R5Q3BoOnp9b2YgWSl7bGV0IEs9Wi5nZXQoVyk7aWYoIUspY29udGludWU7WC5wdXNoKHtkbDpLLGJvZHlDcGg6en0pfXJldHVybiBPKFgpfWFzeW5jIGZ1bmN0aW9uIHNZKCQsSixaLFEpe2lmKFEubGVuZ3RoPDEpcmV0dXJuIE8oe3BhcnRzOltdLGhhc2hlczpbXX0pO2xldCBZPVtdLFY9W10sWD1bXSxXPW5ldyBNYXA7Zm9yKGxldHtkbDpLLGJvZHlDcGg6Rn1vZiBRKXtsZXR7aGVhZDpOLGtkbTpVLHNlcTpSLGhvc3Q6SH09SyxbcSxNXT1hd2FpdCBRUShLLFopO2lmKE0hPT0wfHwhcSl7bGV0IGs9Vy5nZXQoSCk/P1tdO2sucHVzaChSKSxXLnNldChILGspO2NvbnRpbnVlfWxldHtoZWFkRW5jOlAsaGVhZEVuY0hhc2g6Q309cSxUPUouZGVyaXZlQ2lwaGVyKFUsImRlY3J5cHQiKSxbSSxBXT1hd2FpdCBGSihQLEYsVCxaLEMpO2lmKEEhPT0wfHwhSSl7bGV0IGs9Vy5nZXQoSCk/P1tdO2sucHVzaChSKSxXLnNldChILGspO2NvbnRpbnVlfWxldCBMPXtoZWFkOk4sYm9keTpJLmJvZH0sZz1JLmhlYWRIYXNoO1gucHVzaCh7a2V5OmcsZGF0YTpYUShMKX0pLFkucHVzaChMKSxWLnB1c2goZyk7bGV0IGY9Vy5nZXQoSCk/P1tdO2YucHVzaChSKSxXLnNldChILGYpfWxldCB6PWF3YWl0ICQubWVzc2FnZXMuYWRkKFgpO2ZvcihsZXRbSyxGXW9mIFcpYXdhaXQgJC5kb3dubG9hZHMuZGVxKEssRik7Zm9yKGxldCBLPTA7Szx6Lmxlbmd0aDtLKyspe2xldCBGPXpbS107aWYoRiE9PTAmJkYhPT0xNSljb25zb2xlLmVycm9yKCJFUlIgc3RvcmluZyIsRFtGXSwiZm9yIG1lc3NhZ2UiLEspfXJldHVybiBPKHtwYXJ0czpZLGhhc2hlczpWfSl9YXN5bmMgZnVuY3Rpb24gUVEoJCxKKXtsZXQgWj0kLmhlYWRFbmM7aWYoIVope2xldCBZPW5ldyBTLFY9WS53cml0ZVN0cnVjdChHMCwkLmhlYWQpO2lmKFYhPT0wKXJldHVybiBHKFYpO1o9WS5yZXN1bHQoKX1pZigkLmhlYWRFbmNIYXNoKXJldHVybiBPKHtoZWFkRW5jOlosaGVhZEVuY0hhc2g6JC5oZWFkRW5jSGFzaH0pO2xldCBRPWF3YWl0IEouYmxha2UzKFopO3JldHVybiBPKHtoZWFkRW5jOlosaGVhZEVuY0hhc2g6UX0pfWFzeW5jIGZ1bmN0aW9uIFlRKCQsSixaKXtsZXQgUT1uZXcgU2V0O2ZvcihsZXQgWCBvZiBKKVEuYWRkKEIoWCkpO2lmKFEuc2l6ZTwxKXJldHVybjtsZXQgWT1BcnJheS5mcm9tKGF3YWl0ICQuZG93bmxvYWRzLmxpc3QoKSk7aWYoWS5sZW5ndGg8MSlyZXR1cm47bGV0IFY9bmV3IE1hcDtmb3IobGV0IFggb2YgWSl7bGV0IFc7aWYoWC5oZWFkRW5jSGFzaClXPUIoWC5oZWFkRW5jSGFzaCk7ZWxzZXtsZXRbSyxGXT1hd2FpdCBRUShYLFopO2lmKEYhPT0wfHwhSyljb250aW51ZTtXPUIoSy5oZWFkRW5jSGFzaCl9aWYoIVEuaGFzKFcpKWNvbnRpbnVlO2xldCB6PVYuZ2V0KFguaG9zdCk/P1tdO3oucHVzaChYLnNlcSksVi5zZXQoWC5ob3N0LHopfWZvcihsZXRbWCxXXW9mIFYpYXdhaXQgJC5kb3dubG9hZHMuZGVxKFgsVyl9YXN5bmMgZnVuY3Rpb24gZ0ooe2Nvbm46JCxzdG9yZTpKLGVuY2xhdmU6Wixob3N0OlEsY3J5cHRvOlksb25Qcm9ncmVzczpWLHBlZWtQcm9ncmVzc0V2ZXJ5OlgscGVla0NvbmN1cnJlbmN5Old9KXtsZXQgej1hd2FpdCAkLmlkZW50aXR5KCksSz1bXSxbRixOXT1hd2FpdCAkLnBlZWsoUS5sYXN0U2VxKTtpZihOIT09MClyZXR1cm4gTjtsZXQgVT1GLmxlbmd0aCxSPVg/P1UkLEg9Vz8/WlE7aWYoViYmVT4wKVYoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTowLHRvdGFsOlV9KTtsZXQgcT0wLE09YXdhaXQgQkooRixILGFzeW5jKEMpPT57bGV0W1QsSV09YXdhaXQgeSQoQyx6LnB1YmxpY0tleSxaLFkpLEE7aWYoSSE9PTB8fCFUKUE9e29rOiExLHNlcTpDLnNlcSxzdGF0Okl9O2Vsc2V7bGV0IEw9YXdhaXQgWS5ibGFrZTMoVC5oZWFkRW5jKTtBPXtvazohMCxzZXE6Qy5zZXEsa2RtOlQua2RtLGhlYWRFbmM6VC5oZWFkRW5jLGhlYWRFbmNIYXNoOkx9fWlmKHErPTEsViYmeEoocSxVLFIpKVYoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTpxLHRvdGFsOlV9KTtyZXR1cm4gQX0pLFA9bmV3IFNldDtmb3IobGV0IEMgb2YgTSl7aWYoIUMub2spe2NvbnNvbGUuZXJyb3IoInBlZWs6IGRlY3J5cHRpbmcgaXRlbSBoZWFkIixDLnN0YXQpO2NvbnRpbnVlfWxldCBUPUIoQy5oZWFkRW5jSGFzaCk7aWYoYXdhaXQgSi5tZXNzYWdlcy5oYXMoQy5oZWFkRW5jSGFzaCkpe2NvbnNvbGUuaW5mbygicGVlazogbG9jYWwgbXNnOyBza2lwIGRvd25sb2FkLCBkZXEgdXBsb2FkIiksYXdhaXQgSi51cGxvYWRzLmRlcShRLmxhYmVsLFtDLmhlYWRFbmNIYXNoXSksYXdhaXQgSi5kb3dubG9hZHMuZGVxKFEubGFiZWwsW0Muc2VxXSk7Y29udGludWV9aWYoUC5oYXMoVCkpe2F3YWl0IEouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtDLnNlcV0pO2NvbnRpbnVlfWxldCBBPW5ldyBtKEMuaGVhZEVuYyksW0wsZ109QS5yZWFkU3RydWN0KEcwKTtpZihnIT09MCl7Y29uc29sZS5lcnJvcigicGVlazogcmVhZGluZyBpdGVtIGhlYWQiLGcpO2NvbnRpbnVlfVAuYWRkKFQpLEsucHVzaCh7a2RtOkMua2RtLGhlYWQ6TCxzZXE6Qy5zZXEsaG9zdDpRLmxhYmVsLGhlYWRFbmM6Qy5oZWFkRW5jLGhlYWRFbmNIYXNoOkMuaGVhZEVuY0hhc2h9KX1pZihhd2FpdCBKLmRvd25sb2Fkcy5lbnEoSyksRi5sZW5ndGg+MCl7bGV0IEM9TWF0aC5tYXgoLi4uRi5tYXAoKFQpPT5ULnNlcSkpO2F3YWl0IEouaG9zdHMucmVjb3JkU3RhdHMoUS5sYWJlbCx7bGFzdFNlcTpDfSl9aWYoVilWKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6VSx0b3RhbDpVfSk7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gVlEoe2Nvbm46JCxzdG9yZTpKLGhvc3Q6WixtYXhQdXNoQnl0ZXM6USxvblByb2dyZXNzOll9KXtsZXQgVj1RPz9FSixYPWF3YWl0IEoudXBsb2Fkcy5saXN0KFoubGFiZWwpLFc9WC5sZW5ndGgsej0wO2lmKFkmJlc+MClZKHtwaGFzZToicHVzaCIsaG9zdDpaLmxhYmVsLGRvbmU6MCx0b3RhbDpXfSk7bGV0IEs9W10sRj1bXSxOPTAsVT1hc3luYygpPT57aWYoSy5sZW5ndGg8MSlyZXR1cm4gMDtsZXQgUj1LLmxlbmd0aCxIPWF3YWl0IGFZKCQsSixaLmxhYmVsLEssRik7aWYoSz1bXSxGPVtdLE49MCxIPT09MCl7aWYoeis9UixZKVkoe3BoYXNlOiJwdXNoIixob3N0OloubGFiZWwsZG9uZTp6LHRvdGFsOld9KX1yZXR1cm4gSH07Zm9yKGxldCBSIG9mIFgpe2xldCBIPWF3YWl0IEoubWVzc2FnZXMuZ2V0KFIpO2lmKCFIKXt6Kz0xO2NvbnRpbnVlfWxldCBxPXsuLi5ILmhlYWQsYm9kOkguYm9keX0sW00sUF09YXdhaXQgJC5zZWFsKHEpO2lmKFAhPT0wKXJldHVybiBQO2lmKCFNKXJldHVybiAxMjtsZXQgQz1vWShNKTtpZihLLmxlbmd0aD4wJiZOK0M+Vil7bGV0IFQ9YXdhaXQgVSgpO2lmKFQhPT0wKXJldHVybiBUfWlmKEsucHVzaChNKSxGLnB1c2goUiksTis9QyxOPj1WKXtsZXQgVD1hd2FpdCBVKCk7aWYoVCE9PTApcmV0dXJuIFR9fXJldHVybiBVKCl9YXN5bmMgZnVuY3Rpb24gbUooe2Nvbm46JCxzdG9yZTpKLGVuY2xhdmU6Wixob3N0OlEsY3J5cHRvOlksbWF4UHVsbEJ5dGVzOlYsb25Qcm9ncmVzczpYfSxXKXtsZXQgej1WPz9mSixLPWF3YWl0IEouZG93bmxvYWRzLmxpc3QoKSxGPUFycmF5LmZyb20oSykuZmlsdGVyKChNKT0+TS5ob3N0PT09US5sYWJlbCk7aWYoRi5sZW5ndGg8MSlyZXR1cm4gMTU7bGV0IE49WiQoRiwoTSk9Pk0uaGVhZCksVT1lWihOLChNKT0+TS5oZWFkLmxlbix6KSxSPU4ubGVuZ3RoLEg9MDtpZihYKVgoe3BoYXNlOiJwdWxsIixob3N0OlEubGFiZWwsZG9uZTowLHRvdGFsOlJ9KTtsZXQgcT1KUSgkLFVbMF0pO2ZvcihsZXQgTT0wO008VS5sZW5ndGg7TSsrKXtsZXRbUCxDXT1hd2FpdCBxO2lmKEMhPT0wfHwhUClyZXR1cm4gQztpZihIKz1VW01dLmxlbmd0aCxYKVgoe3BoYXNlOiJwdWxsIixob3N0OlEubGFiZWwsZG9uZTpILHRvdGFsOlJ9KTtsZXQgVD1VW00rMV07aWYoVClxPUpRKCQsVCk7aWYoWClYKHtwaGFzZToib3BlbiIsaG9zdDpRLmxhYmVsLGRvbmU6SCx0b3RhbDpSfSk7bGV0IEk9WiQoUCwoTCk9PkwuZGwuaGVhZCksWyxBXT1hd2FpdCBzWShKLFosWSxJKTtpZihBIT09MClyZXR1cm4gQTtpZihXKXtpZihYKVgoe3BoYXNlOiJleGVjIixob3N0OlEubGFiZWwsZG9uZTpILHRvdGFsOlJ9KTthd2FpdCBXKCl9fXJldHVybiAwfWZ1bmN0aW9uIFhRKHtoZWFkOiQsYm9keTpKfSl7bGV0IFo9e2VpZDokLmVpZCxib2R5OkosYXBsZDpZJH07aWYoJC5vZmYhPT0wKVoub2ZmPSQub2ZmO2lmKCQuY3RyIT09MClaLmN0cj0kLmN0cjtyZXR1cm4gWn1hc3luYyBmdW5jdGlvbiBXUSgkLHtjb25uOkosc3RvcmU6WixlbmNsYXZlOlEsaG9zdDpZLGNyeXB0bzpWLG9uUHJvZ3Jlc3M6WH0sVyl7bGV0IHo9WS5sYWJlbCxLPWF3YWl0IEouaWRlbnRpdHkoKSxGPW5ldyBtKCQpLFtOLFVdPUYucmVhZFN0cnVjdHMoTCQpO2lmKFUhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjb2Rpbmcgbm90aWYiLERbVV0pO3JldHVybn1sZXQgUj0hMSxxPShhd2FpdCBaLmhvc3RzLmdldCh6KSk/Lmxhc3RTZXEsTT1bXSxQPSExO2ZvcihsZXQgSSBvZiBOKXtsZXRbQSxMXT1hd2FpdCB5JCh7c2VxOkkuc2VxLGhlYWRDcGg6SS5oZWFkQ3BofSxLLnB1YmxpY0tleSxRLFYpO2lmKEwhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjcnlwdGluZyBub3RpZiIsRFtMXSk7Y29udGludWV9bGV0IGc9YXdhaXQgVi5ibGFrZTMoQS5oZWFkRW5jKTtpZihhd2FpdCBaLm1lc3NhZ2VzLmhhcyhnKSljb250aW51ZTtsZXQgZj1uZXcgbShBLmhlYWRFbmMpLFtrLHldPWYucmVhZFN0cnVjdChHMCk7aWYoeSE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBwYXJzZSBoZWFkIixEW3ldKTtjb250aW51ZX1pZighSS5ib2R5Q3BoJiZrLmxlbj4wKVA9ITAsYXdhaXQgWi5kb3dubG9hZHMuZW5xKFt7c2VxOkkuc2VxLGhvc3Q6eixrZG06QS5rZG0saGVhZDprLGhlYWRFbmM6QS5oZWFkRW5jLGhlYWRFbmNIYXNoOmd9XSk7ZWxzZSBNLnB1c2goey4uLkEsaGVhZDprLGJvZHlDcGg6SS5ib2R5Q3BoLGhlYWRFbmNIYXNoOmd9KTtpZihxPT09dm9pZCAwfHxJLnNlcSE9PXErMSljb25zb2xlLmxvZygib3V0IG9mIHNlcSIsSS5zZXEscSksUj0hMDtlbHNlIHE9SS5zZXF9aWYocSE9PXZvaWQgMClhd2FpdCBaLmhvc3RzLnRvdWNoKFkubGFiZWwscSk7bGV0IEM9W107Zm9yKGxldCBJIG9mIE0pe2xldCBBPVEuZGVyaXZlQ2lwaGVyKEkua2RtLCJkZWNyeXB0IiksW0wsZ109YXdhaXQgRkooSS5oZWFkRW5jLEkuYm9keUNwaCxBLFYpO2lmKGchPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gb3BlbiBib2R5IixEW2ddKTtjb250aW51ZX1DLnB1c2goe2tleTpJLmhlYWRFbmNIYXNoLGRhdGE6WFEoe2hlYWQ6SS5oZWFkLGJvZHk6TC5ib2R9KX0pfWxldCBUPWF3YWl0IFoubWVzc2FnZXMuYWRkKEMpO2ZvcihsZXQgST0wO0k8VC5sZW5ndGg7SSsrKXtsZXQgQT1UW0ldO2lmKEEhPT0wJiZBIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLERbQV0sImZvciBtZXNzYWdlIixJKX1pZihYJiZDLmxlbmd0aD4wKVgoe3BoYXNlOiJvcGVuIixob3N0OlkubGFiZWwsZG9uZTpDLmxlbmd0aCx0b3RhbDpDLmxlbmd0aH0pO2lmKFJ8fFB8fEMubGVuZ3RoPjApVygpfWFzeW5jIGZ1bmN0aW9uIFNKKCQsSj17fSl7bGV0IFo9Si5wdWxsIT09ITEsUT1KLnB1c2g9PT0hMCx7Y29ubjpZLHN0b3JlOlYsZW5jbGF2ZTpYLGhvc3Q6VyxjcnlwdG86eixvblByb2dyZXNzOksscGVla1Byb2dyZXNzRXZlcnk6RixwZWVrQ29uY3VycmVuY3k6Tn09JCxVPWF3YWl0IFkuaWRlbnRpdHkoKSxbUixIXT1hd2FpdCBZLnBlZWsoMCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7bGV0IHE9Ui5sZW5ndGgsTT1GPz9VJCxQPU4/P1pRO2lmKEsmJnE+MClLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6MCx0b3RhbDpxfSk7bGV0IEM9MCxUPWF3YWl0IEJKKFIsUCxhc3luYyh4KT0+e2xldFt2LEVdPWF3YWl0IHkkKHgsVS5wdWJsaWNLZXksWCx6KSxpO2lmKEUhPT0wfHwhdilpPXtvazohMSxzZXE6eC5zZXEsc3RhdDpFfTtlbHNle2xldCBfPWF3YWl0IHouYmxha2UzKHYuaGVhZEVuYyk7aT17b2s6ITAsc2VxOnguc2VxLGtkbTp2LmtkbSxoZWFkRW5jOnYuaGVhZEVuYyxoZWFkRW5jSGFzaDpffX1pZihDKz0xLEsmJnhKKEMscSxNKSlLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6Qyx0b3RhbDpxfSk7cmV0dXJuIGl9KSxJPW5ldyBNYXA7Zm9yKGxldCB4IG9mIFQpe2lmKCF4Lm9rKWNvbnRpbnVlO2xldCB2PUIoeC5oZWFkRW5jSGFzaCksRT1JLmdldCh2KTtpZihFKUUuY291bnQrPTE7ZWxzZSBJLnNldCh2LHtoYXNoOnguaGVhZEVuY0hhc2gsY291bnQ6MSxzYW1wbGU6eH0pfWxldCBBPTAsTD1bXTtmb3IobGV0IHggb2YgSS52YWx1ZXMoKSl7aWYoeC5jb3VudD4xKUErPXguY291bnQtMTtMLnB1c2goeC5oYXNoKX1sZXQgZz1SLmxlbmd0aCxmPUkuc2l6ZSxrPWF3YWl0IE8kKEwseikseT1bXSxoPTA7Zm9yKGxldCB4IG9mIEkudmFsdWVzKCkpe2lmKGF3YWl0IFYubWVzc2FnZXMuaGFzKHguaGFzaCkpe2F3YWl0IFYudXBsb2Fkcy5kZXEoVy5sYWJlbCxbeC5oYXNoXSk7Y29udGludWV9aWYoaCs9MSwhWiljb250aW51ZTtsZXQgRT14LnNhbXBsZSxpPW5ldyBtKEUuaGVhZEVuYyksW18sZF09aS5yZWFkU3RydWN0KEcwKTtpZihkIT09MCl7Y29uc29sZS5lcnJvcigicmVjb25jaWxlOiByZWFkaW5nIG1zZyBoZWFkZXIiLGQpO2NvbnRpbnVlfXkucHVzaCh7a2RtOkUua2RtLGhlYWQ6XyxzZXE6RS5zZXEsaG9zdDpXLmxhYmVsLGhlYWRFbmM6RS5oZWFkRW5jLGhlYWRFbmNIYXNoOkUuaGVhZEVuY0hhc2h9KX1pZih5Lmxlbmd0aD4wKWF3YWl0IFYuZG93bmxvYWRzLmVucSh5KTtsZXQgdT0wO2lmKFEpe2xldCB4PWF3YWl0IFYubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoSS5rZXlzKCkpLEU9W107Zm9yKGxldCBpIG9mIHgpaWYoIXYuaGFzKEIoaSkpKXUrPTEsRS5wdXNoKGkpO2lmKEUubGVuZ3RoPjApYXdhaXQgVi51cGxvYWRzLmVucShXLmxhYmVsLEUpfWVsc2V7bGV0IHg9YXdhaXQgVi5tZXNzYWdlcy5saXN0S2V5cygpLHY9bmV3IFNldChJLmtleXMoKSk7Zm9yKGxldCBFIG9mIHgpaWYoIXYuaGFzKEIoRSkpKXUrPTF9bGV0IHc9Ui5sZW5ndGg+MD9NYXRoLm1heCguLi5SLm1hcCgoeCk9Pnguc2VxKSk6MDtpZihhd2FpdCBWLmhvc3RzLnJlY29yZFN0YXRzKFcubGFiZWwse3NldExhc3RTZXE6d30pLEspSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOnEsdG90YWw6cX0pO3JldHVybiBPKHttc2djaGVjazprLG51bUJhZ3M6Zyx1bmlxdWVNc2dzOmYsbnVtRHVwZXM6QSxtaXNzaW5nTG9jYWw6aCxtaXNzaW5nSG9zdDp1fSl9Y2xhc3Mgdkp7Y2xvY2s7c3RhdGU7c3RvcmU7dHJhbnNwb3J0O2NyeXB0bztmb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdDtvblNjaGVkdWxlU3luYztjb25uZWN0aW9ucz1uZXcgTWFwO2FwcGx5Q2hhaW49UHJvbWlzZS5yZXNvbHZlKCk7c3luY1J1bnM9bmV3IHYkO2NsaWVudFN0YXRlO3hmZXJTdGF0ZTttYXhQdXNoQnl0ZXM7bWF4UHVsbEJ5dGVzO3BlZWtQcm9ncmVzc0V2ZXJ5PVUkO2xhc3RQcm9ncmVzcz1MSjtzY2hlZHVsZWRTeW5jO2NvbnN0cnVjdG9yKCQsSixaLFEsWSxWPSEwLFg9RUosVz1mSix6KXt0aGlzLmNsb2NrPSQ7dGhpcy5zdGF0ZT1KO3RoaXMuc3RvcmU9Wjt0aGlzLnRyYW5zcG9ydD1RO3RoaXMuY3J5cHRvPVk7dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdD1WO3RoaXMub25TY2hlZHVsZVN5bmM9ejt0aGlzLm1heFB1c2hCeXRlcz1YLHRoaXMubWF4UHVsbEJ5dGVzPVcsdGhpcy5jbGllbnRTdGF0ZT1uZXcgZjAoKCk9PnRoaXMuZ2V0Q2xpZW50U3RhdGUoKSksdGhpcy54ZmVyU3RhdGU9bmV3IGYwKCgpPT50aGlzLmdldFhmZXJTdGF0ZSgpKSx0aGlzLnNjaGVkdWxlZFN5bmM9bmV3IF9KKGFaLGFzeW5jKCk9Pnt0cnl7Y29uc29sZS5pbmZvKCJSdW5uaW5nIHNjaGVkdWxlZCBzeW5jIiksYXdhaXQgdGhpcy5zeW5jKCl9Y2F0Y2goSyl7Y29uc29sZS5lcnJvcigiRGVib3VuY2VkIHN5bmMgZmFpbGVkOiIsSyl9fSl9ZW1pdFByb2dyZXNzPSgkKT0+e3RoaXMubGFzdFByb2dyZXNzPSQsdGhpcy54ZmVyU3RhdGUuZW1pdCgpfTthc3luYyBzZXRTZWVkKCQsSil7YXdhaXQgdGhpcy5zdG9yZS5zZWVkLnNhdmUoJCxKKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBnZXRDbGllbnRTdGF0ZSgpe2xldHtzdG9yZTokLGNvbm5lY3Rpb25zOkp9PXRoaXMsWj1hd2FpdCAkLnNlZWQubG9hZCgpLFE9YXdhaXQgJC5ob3N0cy5saXN0KCksWT0hMTtmb3IobGV0IFYgb2YgSi52YWx1ZXMoKSlpZihWLmlzQ29ubmVjdGVkKCkpe1k9ITA7YnJlYWt9cmV0dXJue2hhc1NlZWQ6WiE9PXZvaWQgMCxoYXNIb3N0OkFycmF5LmZyb20oUSkubGVuZ3RoPjAsY29ubmVjdGVkOll9fWFzeW5jIGdldFhmZXJTdGF0ZSgpe2xldHt1cGxvYWRzOiQsZG93bmxvYWRzOkp9PXRoaXMuc3RvcmUsWj1hd2FpdCAkLmNvdW50KCk7cmV0dXJue251bURvd25sb2Fkczphd2FpdCBKLmNvdW50KCksbnVtVXBsb2FkczpaLHByb2dyZXNzOnRoaXMubGFzdFByb2dyZXNzfX1hcHBseT0oJCxKKT0+e3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0FwcGx5KCQsSikpfTthc3luYyBkb0FwcGx5KCQsSj17ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiEwfSl7bGV0IFo9W10sUT1bXTtmb3IobGV0e2hlYWQ6Vixib2R5Olh9b2YgJCl7bGV0IFc9bmV3IFM7Vy53cml0ZVN0cnVjdChHMCxWKTtsZXQgej1XLnJlc3VsdCgpLEs9YXdhaXQgdGhpcy5jcnlwdG8uYmxha2UzKHopLEY9e2VpZDpWLmVpZCxib2R5OlgsYXBsZDpZJH07aWYoVi5vZmYhPT0wKUYub2ZmPVYub2ZmO2lmKFYuY3RyIT09MClGLmN0cj1WLmN0cjtaLnB1c2goSyksUS5wdXNoKHtrZXk6SyxkYXRhOkZ9KX1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmFkZChRKSxhd2FpdCBZUSh0aGlzLnN0b3JlLFosdGhpcy5jcnlwdG8pO2xldCBZPWF3YWl0IHRoaXMuZG9BcHBseUhhc2hlcyhaKTtpZihKLmVucXVldWVVcGxvYWQpe2xldCBWPVtdO2ZvcihsZXQgWD0wO1g8Wi5sZW5ndGg7WCsrKXtsZXQgVz1ZW1hdO2lmKFc9PT0wfHxXPT09MTUpVi5wdXNoKFpbWF0pfWlmKFYubGVuZ3RoPjApe2xldCBYPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpO2ZvcihsZXQgVyBvZiBYKWF3YWl0IHRoaXMuc3RvcmUudXBsb2Fkcy5lbnEoVy5sYWJlbCxWKTt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9fWlmKEoudHJpZ2dlclVwbG9hZCl0aGlzLnNjaGVkdWxlU3luYygpO3JldHVybiBZfWVucXVldWVBcHBseUpvYigkKXtsZXQgSj10aGlzLmFwcGx5Q2hhaW4udGhlbigkLCQpO3JldHVybiB0aGlzLmFwcGx5Q2hhaW49Si50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLEp9ZHJhaW5BcHBseVF1ZXVlKCl7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvRHJhaW5BcHBseVF1ZXVlKCkpfWFzeW5jIGRvRHJhaW5BcHBseVF1ZXVlKCl7bGV0ICQ9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KHthcGxkOlkkfSk7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgSj1aJCgkLChaKT0+Wi5oZWFkKTtyZXR1cm4gdGhpcy5hcHBseVN0b3JlZChKKX1hcHBseUhhc2hlcz0oJCk9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseUhhc2hlcygkKSl9O2FzeW5jIGRvQXBwbHlIYXNoZXMoJCl7bGV0IEo9W107Zm9yKGxldCBZIG9mICQpe2xldCBWPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMuZ2V0KFkpO2lmKFYpSi5wdXNoKFYpfWxldCBaPWF3YWl0IHRoaXMuYXBwbHlTdG9yZWQoSiksUT1uZXcgTWFwO2ZvcihsZXQgWT0wO1k8Si5sZW5ndGg7WSsrKVEuc2V0KEIoSltZXS5oYXNoKSxaW1ldPz8xMik7cmV0dXJuICQubWFwKChZKT0+US5nZXQoQihZKSk/PzEzKX1hc3luYyBhcHBseVN0b3JlZCgkKXtpZigkLmxlbmd0aDwxKXJldHVybltdO2xldCBKPSQubWFwKChWKT0+KHsuLi5WLmhlYWQsYm9kOlYuYm9keX0pKSxaPWF3YWl0IHRoaXMuc3RhdGUuYXBwbHkoSiksUT1bXSxZPVtdO2ZvcihsZXQgVj0wO1Y8JC5sZW5ndGg7VisrKXtsZXQgWD1aW1ZdO2lmKFg9PT0wfHxYPT09MTUpUS5wdXNoKCRbVl0uaGFzaCk7ZWxzZSBpZihYIT09dm9pZCAwJiYkUShYKSlZLnB1c2goe2tleTokW1ZdLmhhc2gsZXJyOlh9KX1pZihRLmxlbmd0aD4wKWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubWFya0FwcGxpZWQoUSk7aWYoWS5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtGYWlsZWQoWSk7cmV0dXJuIFp9YXN5bmMgaW5zZXJ0UmF3KCQpe2xldHtjbG9jazpKLGNyeXB0bzpafT10aGlzLFtRLFldPWF3YWl0IGlaKHtub3c6Si5ub3coKSxib2Q6JCxjcnlwdG86Wn0pO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBYPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpRLGJvZHk6JH1dKSlbMF07aWYoWCE9PTAmJlghPT0xNSlyZXR1cm4gRyhYPz8xMik7cmV0dXJuIE8oUSl9YXN5bmMgbWFrZVVwZGF0ZSgkLEope2xldHtjbG9jazpaLGNyeXB0bzpRfT10aGlzLFk9Wi5ub3coKTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCk+WS5nZXRUaW1lKCkpcmV0dXJuIEcoNCk7bGV0IFY9JC5jdHIrMSxbWCxXXT1hd2FpdCBFJCh7bm93OlksZWlkOiQuZWlkLGN0cjpWLGJvZDpKLGNyeXB0bzpRfSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7cmV0dXJuIE8oe2hlYWQ6WCxib2R5Okp9KX1hc3luYyB1cGRhdGVXaXRoU2tldygkLEosWil7aWYoWj09PSExKXJldHVybiBHKDQpO2xldHtjbG9jazpRLGNyeXB0bzpZfT10aGlzLFY9US5ub3coKSxYPW5ldyBtKCQuZWlkKSxbVyx6XT1YLnJlYWRTdHJ1Y3QoVjApO2lmKHohPT0wKXJldHVybiBHKHopO2xldCBLPSQudXBkYXRlZEF0LmdldFRpbWUoKS1XLnRzLmdldFRpbWUoKSxGPXtlaWQ6JC5laWQsb2ZmOksrMSxjdHI6JC5jdHIrMSxsZW46MH0sVT0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6Rixib2R5OnZvaWQgMH1dKSlbMF07aWYoVSE9PTAmJlUhPT0xNSlyZXR1cm4gRyhVPz8xMik7aWYoSj09PXZvaWQgMClyZXR1cm4gTyhGKTtsZXRbUixIXT1fJCh7aWQ6Vy5pZCx0czpWfSk7aWYoSCE9PTApcmV0dXJuIEcoSCk7bGV0W3EsTV09YXdhaXQgRSQoe25vdzpWLGVpZDpSLGN0cjowLGJvZDpKLGNyeXB0bzpZfSk7aWYoTSE9PTApcmV0dXJuIEcoTSk7bGV0IEM9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOnEsYm9keTpKfV0pKVswXTtpZihDIT09MCYmQyE9PTE1KXJldHVybiBHKEM/PzEyKTtyZXR1cm4gTyhxKX1hc3luYyB1cGRhdGVSYXcoJCxKLFo9dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdCl7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPnRoaXMuY2xvY2subm93KCkuZ2V0VGltZSgpKXJldHVybiB0aGlzLnVwZGF0ZVdpdGhTa2V3KCQsSixaKTtyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoYXN5bmMoKT0+e2xldFtRLFldPWF3YWl0IHRoaXMubWFrZVVwZGF0ZSgkLEopO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBYPShhd2FpdCB0aGlzLmRvQXBwbHkoW1FdKSlbMF07aWYoWCE9PTAmJlghPT0xNSlyZXR1cm4gRyhYPz8xMik7cmV0dXJuIE8oUS5oZWFkKX0pfWFzeW5jIGluc2VydCgkKXtsZXR7Ym9keTpKLHR5cGU6WixnaWQ6USxwaWQ6WSx0YWdzOlZ9PSQsVz1FMCh7Ym9keTpKLHR5cGU6WixnaWQ6USxwaWQ6WSx0YWdzOlZ9KTtyZXR1cm4gdGhpcy5pbnNlcnRSYXcoVyl9YXN5bmMgdXBkYXRlKCQpe2xldHtwcmlvcjpKLGJvZHk6Wix0eXBlOlEsZ2lkOlkscGlkOlYsdGFnczpYLGZvcmNlOld9PSQsSz1FMCh7Ym9keTpaLHR5cGU6USxnaWQ6WSxwaWQ6Vix0YWdzOlh9KTtyZXR1cm4gdGhpcy51cGRhdGVSYXcoSixLLFc/P3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpfWFzeW5jIGRlbGV0ZSgkKXtsZXQgSj0kLmZvcmNlPz8hMDtpZigicHJpb3IiaW4gJClyZXR1cm4gdGhpcy51cGRhdGVSYXcoJC5wcmlvcix2b2lkIDAsSik7bGV0W1osUV09YXdhaXQgdGhpcy5yZXZGcm9tQXJjaGl2ZSgkLmVpZCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KFosdm9pZCAwLEopfWFzeW5jIHJldkZyb21BcmNoaXZlKCQpe2xldCBKPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGFzdCgkKTtpZihKKXJldHVybiBvWihKLmhlYWQpO2xldCBaPW5ldyBtKCQpLFtRLFldPVoucmVhZFN0cnVjdChWMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe2VpZDokLGN0cjotMSx1cGRhdGVkQXQ6US50c30pfWFzeW5jIGdlbkVJRCgkKXtsZXR7Y2xvY2s6SixjcnlwdG86Wn09dGhpcyxRPUoubm93KCk7aWYoJCE9PXZvaWQgMClyZXR1cm4gXyQoe2lkOiQsdHM6UX0pO2xldCBZPWF3YWl0IFouZ2VuUmFuZG9tQnl0ZXMoOCk7cmV0dXJuIF8kKHtpZDpZLHRzOlF9KX1zeW5jKCl7cmV0dXJuIHRoaXMuc3luY1J1bnMucnVuKCgpPT50aGlzLmRvU3luYygpKX1hc3luYyBkb1N5bmMoKXtsZXR7Y29ubmVjdGlvbnM6JCxjcnlwdG86SixzdG9yZTpafT10aGlzLFE9YXdhaXQgWi5zZWVkLmxvYWQoKTtpZighUSlyZXR1cm4gMjI7YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtmb3IobGV0W1ksVl1vZiAkKXtsZXQgWD1hd2FpdCBaLmhvc3RzLmdldChZKTtpZighWCljb250aW51ZTtsZXQgVz17Y29ubjpWLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6WCxjcnlwdG86SixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sej1hd2FpdCBnSihXKTtpZih6IT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHBlZWs6ICR7en1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksejt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEs9YXdhaXQgVlEoVyk7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwdXNoOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IG1KKFcsYXN5bmMoKT0+e2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCl9KTtpZihGIT09MCYmRiE9PTE1KXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVsbDogJHtGfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxGO3RoaXMueGZlclN0YXRlLmVtaXQoKX1yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgcmVidWlsZCgkKXtpZih0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpLCQ/LmNoZWNrSG9zdD8/ITApe2xldCBaPWF3YWl0IHRoaXMucmVwdWxsKCk7aWYoWiE9PTApcmV0dXJuIFp9cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLnJlcGxheSgpKX1hc3luYyBtc2djaGVjaygpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdEtleXMoKTtyZXR1cm4gTyQoJCx0aGlzLmNyeXB0byl9bGlzdE1zZ3MoJCl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCgkKX1jb3VudE1zZ3MoJCl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMuY291bnQoJCl9YXN5bmMgcmVjb25jaWxlKCQsSil7dGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKTtsZXR7Y29ubmVjdGlvbnM6WixjcnlwdG86USxzdG9yZTpZfT10aGlzLFY9YXdhaXQgWS5zZWVkLmxvYWQoKTtpZighVilyZXR1cm4gRygyMik7bGV0IFg9YXdhaXQgWS5ob3N0cy5nZXQoJCk7aWYoIVgpcmV0dXJuIEcoMTMpO2xldCBXPVouZ2V0KCQpO2lmKCFXfHwhVy5pc0Nvbm5lY3RlZCgpKXtpZihhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWCwhMSwhMSksWD1hd2FpdCBZLmhvc3RzLmdldCgkKSwhWClyZXR1cm4gRygxMyk7Vz1aLmdldCgkKX1pZighVylyZXR1cm4gRygxMik7bGV0IHo9e2Nvbm46VyxzdG9yZTpZLGVuY2xhdmU6VixjcnlwdG86USxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sW0ssRl09YXdhaXQgU0ooey4uLnosaG9zdDpYfSxKKTtpZih0aGlzLnhmZXJTdGF0ZS5lbWl0KCksRiE9PTApcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxHKEYpO2lmKCFLKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRygxMik7aWYoSj8uc3luYz09PSExKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksTyhLKTtsZXQgTj1hd2FpdCB0aGlzLnN5bmMoKTtpZihOIT09MClyZXR1cm4gRyhOKTtsZXQgVT1hd2FpdCBZLmhvc3RzLmdldCgkKTtpZighVSlyZXR1cm4gRygxMyk7bGV0W1IsSF09YXdhaXQgU0ooey4uLnosaG9zdDpVfSx7cHVsbDohMSxwdXNoOiExfSk7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxIIT09MClyZXR1cm4gRyhIKTtpZighUilyZXR1cm4gRygxMik7cmV0dXJuIE8oUil9YXN5bmMgcmVwdWxsKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOkosc3RvcmU6Wn09dGhpcyxRPWF3YWl0IFouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2xldCBZPUFycmF5LmZyb20oYXdhaXQgWi5ob3N0cy5saXN0KCkpO2lmKFkubGVuZ3RoPDEpcmV0dXJuIDA7Zm9yKGxldCBWIG9mIFkpe2xldCBYPSQuZ2V0KFYubGFiZWwpO2lmKCFYfHwhWC5pc0Nvbm5lY3RlZCgpKWF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChWLCExLCExKX1mb3IobGV0W1YsWF1vZiAkKXtsZXQgVz1hd2FpdCBaLmhvc3RzLmdldChWKTtpZighVyljb250aW51ZTtsZXQgej17Y29ubjpYLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6ey4uLlcsbGFzdFNlcTowfSxjcnlwdG86SixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sSz1hd2FpdCBnSih6KTtpZihLIT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHBlZWs6ICR7S31gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksSzt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEY9YXdhaXQgbUooeik7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlcGxheSgpe2xldCAkPWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTtpZigkIT09MClyZXR1cm4gJDtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoKSxaPVokKEosKFYpPT5WLmhlYWQpLFE9Wi5sZW5ndGg7aWYoUTwxKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMDtsZXQgWT0wO3doaWxlKFk8Wi5sZW5ndGgpe2xldCBWPTAsWD0wLFc9WTtmb3IobGV0IEs9WTtLPFoubGVuZ3RoJiZYPDEwMCYmVjwxMDI0MDA7SysrKVYrPVpbS10uaGVhZC5sZW4sWCsrLFc9SysxO2xldCB6PVouc2xpY2UoWSxXKTthd2FpdCB0aGlzLmFwcGx5U3RvcmVkKHopLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiZXhlYyIsZG9uZTpXLHRvdGFsOlF9KSxZPVd9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHdpcGUoJCl7bGV0IEo9JD8ubXNncyE9PSExLFo9JD8uZW50cyE9PSExLFE9JD8ubWV0YSE9PSExLFk9JD8uc2VlZD09PSEwO3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLmRpc2Nvbm5lY3QoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e3N0b3JlOlZ9PXRoaXM7aWYoUSlhd2FpdCBWLmhvc3RzLndpcGUoKSxhd2FpdCBWLnVwbG9hZHMud2lwZSgpLGF3YWl0IFYuZG93bmxvYWRzLndpcGUoKTtpZihKKWF3YWl0IFYubWVzc2FnZXMud2lwZSgpO2lmKFkpYXdhaXQgVi5zZWVkLndpcGUoKTtpZihaKWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTt0aGlzLmxhc3RQcm9ncmVzcz1MSix0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSx0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9aW1wb3J0PWFzeW5jKCQsSik9PntsZXR7Y3J5cHRvOlosc3RvcmU6UX09dGhpcyxZPUo/Lm9uUHJvZ3Jlc3MsVj1hd2FpdCBRLnNlZWQubG9hZCgpO2lmKCFWKXJldHVybiAyMjtjb25zb2xlLnRpbWUoImltcG9ydDogZGVjb2RpbmcgZmlsZS4uLiIpO2xldCBYPWF3YWl0ICQuYnl0ZXMoKSxbVyx6XT1hd2FpdCBoWihYLFosVik7aWYoeiE9PTApcmV0dXJuIHo7Y29uc29sZS50aW1lRW5kKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgSz0wO3doaWxlKEs8Vy5sZW5ndGgpe2xldCBGPTAsTj0wLFU9Sztmb3IobGV0IHE9SztxPFcubGVuZ3RoJiZOPDEwMCYmRjwxMDI0MDA7cSsrKUYrPVdbcV0uaGVhZC5sZW4sTisrLFU9cSsxO2xldCBSPVcuc2xpY2UoSyxVKTtjb25zb2xlLnRpbWUoYGltcG9ydDogYXBwbHlpbmcgWyR7S30sICR7VX1dYCk7bGV0IEg9YXdhaXQgdGhpcy5hcHBseShSLHtlbnF1ZXVlVXBsb2FkOiEwLHRyaWdnZXJVcGxvYWQ6ITF9KTtjb25zb2xlLnRpbWVFbmQoYGltcG9ydDogYXBwbHlpbmcgWyR7S30sICR7VX1dYCk7Zm9yKGxldCBxPTA7cTxSLmxlbmd0aDtxKyspe2xldCBNPUhbcV07aWYoTSE9PTAmJk0hPT0xNSljb25zb2xlLndhcm4oYGZhaWxlZCB0byBpbXBvcnQgbXNnICR7SytxfTogJHtEW01dfWApfWlmKFkpcXVldWVNaWNyb3Rhc2soKCk9PlkoVSxXLmxlbmd0aCwwKSk7dGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpbXBvcnQiLGRvbmU6VSx0b3RhbDpXLmxlbmd0aH0pLEs9VX1yZXR1cm4gdGhpcy5zY2hlZHVsZVN5bmMoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH07c2NoZWR1bGVTeW5jPSgpPT57aWYodGhpcy5vblNjaGVkdWxlU3luYyl7dGhpcy5vblNjaGVkdWxlU3luYygpO3JldHVybn10aGlzLnNjaGVkdWxlZFN5bmMuc2NoZWR1bGUoKX07YXN5bmMgZXhwb3J0Qnl0ZXMoKXtsZXR7Y3J5cHRvOiQsc3RvcmU6Sn09dGhpcyxaPWF3YWl0IEouc2VlZC5sb2FkKCk7aWYoIVopcmV0dXJuIEcoMjIpO2xldCBRPWF3YWl0IEoubWVzc2FnZXMubGlzdCgpO3JldHVybiBiWigiZXhwb3J0IiwwLFEsJCxaKX1hc3luYyBleHBvcnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5leHBvcnRCeXRlcygpO2lmKFohPT0wKXJldHVybiBaO2lmKCFKKXJldHVybiAxMjtsZXQgUT1uZXcgQmxvYihbSi5zbGljZSgpXSk7cmV0dXJuIHRaKFEsJCksMH1hc3luYyBsaW5rKCQsSj0hMCl7aWYoYXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5hZGQoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksSil7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5nZXQoJC5sYWJlbCk7aWYoWilhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWil9fWFzeW5jIHVubGluaygkKXthd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmRlbCgkKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBob3N0cygpe3JldHVybiBBcnJheS5mcm9tKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpKX1jb25uZWN0VG9Ib3N0PWFzeW5jKCQsSj0hMCxaPSEwKT0+e2xldHtjbG9jazpRLGNvbm5lY3Rpb25zOlksY3J5cHRvOlYsc3RvcmU6WCx0cmFuc3BvcnQ6V309dGhpcyx6PVkuZ2V0KCQubGFiZWwpO2lmKHope2lmKHouaXNDb25uZWN0ZWQoKSlyZXR1cm47dHJ5e3ouY2xvc2VMaXN0ZW5lcigpfWNhdGNoe31ZLmRlbGV0ZSgkLmxhYmVsKX1sZXQgSz1hd2FpdCBYLnNlZWQubG9hZCgpO2lmKCFLKXJldHVybjtjb25zb2xlLmluZm8oYENvbm5lY3RpbmcgdG8gJHskLmhhbmRsZX0gKCR7JC5sYWJlbH0pYCk7bGV0IEY9bmV3IGskKEssViwkLFEsVygkKSwoTik9PlguaG9zdHMuc2V0KCQubGFiZWwsTikpO2lmKGF3YWl0IEYucmVnaXN0ZXIoKSxKKWF3YWl0IEYubGlzdGVuKGFzeW5jKE4pPT57bGV0IFU9e2Nvbm46RixzdG9yZTpYLGVuY2xhdmU6Syxob3N0OiQsY3J5cHRvOlYsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9O3JldHVybiBXUShOLFUsdGhpcy5zY2hlZHVsZVN5bmMpfSwoKT0+dGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpKTtpZihZLnNldCgkLmxhYmVsLEYpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLFopdGhpcy5zY2hlZHVsZVN5bmMoKX07YXN5bmMgY29ubmVjdCgkPSEwLEo9ITApe2xldHtjb25uZWN0VG9Ib3N0Olosc2NoZWR1bGVTeW5jOlEsc3RvcmU6WX09dGhpcztpZighYXdhaXQgWS5zZWVkLmxvYWQoKSlyZXR1cm47YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtsZXQgWD1hd2FpdCBZLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWClhd2FpdCBaKFcsJCwhMSk7aWYoSilRKCl9ZGlzY29ubmVjdD1hc3luYygpPT57Zm9yKGxldCAkIG9mIHRoaXMuY29ubmVjdGlvbnMudmFsdWVzKCkpdHJ5eyQuY2xvc2VMaXN0ZW5lcigpfWNhdGNoe310aGlzLmNvbm5lY3Rpb25zLmNsZWFyKCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9fXZhciBnMD10eXBlb2YgZ2xvYmFsVGhpcz09PSJvYmplY3QiJiYiY3J5cHRvImluIGdsb2JhbFRoaXM/Z2xvYmFsVGhpcy5jcnlwdG86dm9pZCAwO2Z1bmN0aW9uIGkkKCQpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcigkKXx8JDwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIiskKX1mdW5jdGlvbiB5SigkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldygkKSYmJC5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIG8oJCwuLi5KKXtpZigheUooJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihKLmxlbmd0aD4wJiYhSi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrSisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIGJKKCQsSj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoSiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIEdRKCQsSil7bygkKTtsZXQgWj1KLm91dHB1dExlbjtpZigkLmxlbmd0aDxaKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK1opfWZ1bmN0aW9uIGhKKCQpe2lmKHR5cGVvZiAkIT09ImJvb2xlYW4iKXRocm93IEVycm9yKGBib29sZWFuIGV4cGVjdGVkLCBub3QgJHskfWApfS8qISBub2JsZS1jaXBoZXJzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjMgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovdmFyIEMwPSgkKT0+bmV3IFVpbnQzMkFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCxNYXRoLmZsb29yKCQuYnl0ZUxlbmd0aC80KSk7dmFyIHRZPW5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4O2lmKCF0WSl0aHJvdyBFcnJvcigiTm9uIGxpdHRsZS1lbmRpYW4gaGFyZHdhcmUgaXMgbm90IHN1cHBvcnRlZCIpO2Z1bmN0aW9uIGVZKCQpe2lmKHR5cGVvZiAkIT09InN0cmluZyIpdGhyb3cgRXJyb3IoInN0cmluZyBleHBlY3RlZCIpO3JldHVybiBuZXcgVWludDhBcnJheShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCkpfWZ1bmN0aW9uIGwkKCQpe2lmKHR5cGVvZiAkPT09InN0cmluZyIpJD1lWSgkKTtlbHNlIGlmKHlKKCQpKSQ9dSQoJCk7ZWxzZSB0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCwgZ290ICIrdHlwZW9mICQpO3JldHVybiAkfWZ1bmN0aW9uIHpRKCQsSil7aWYoSj09bnVsbHx8dHlwZW9mIEohPT0ib2JqZWN0Iil0aHJvdyBFcnJvcigib3B0aW9ucyBtdXN0IGJlIGRlZmluZWQiKTtyZXR1cm4gT2JqZWN0LmFzc2lnbigkLEopfWZ1bmN0aW9uIEtRKCQsSil7aWYoJC5sZW5ndGghPT1KLmxlbmd0aClyZXR1cm4hMTtsZXQgWj0wO2ZvcihsZXQgUT0wO1E8JC5sZW5ndGg7USsrKVp8PSRbUV1eSltRXTtyZXR1cm4gWj09PTB9dmFyIEZRPSgkLEopPT57ZnVuY3Rpb24gWihRLC4uLlkpe2lmKG8oUSksJC5ub25jZUxlbmd0aCE9PXZvaWQgMCl7bGV0IEY9WVswXTtpZighRil0aHJvdyBFcnJvcigibm9uY2UgLyBpdiByZXF1aXJlZCIpO2lmKCQudmFyU2l6ZU5vbmNlKW8oRik7ZWxzZSBvKEYsJC5ub25jZUxlbmd0aCl9bGV0IFY9JC50YWdMZW5ndGg7aWYoViYmWVsxXSE9PXZvaWQgMClvKFlbMV0pO2xldCBYPUooUSwuLi5ZKSxXPShGLE4pPT57aWYoTiE9PXZvaWQgMCl7aWYoRiE9PTIpdGhyb3cgRXJyb3IoImNpcGhlciBvdXRwdXQgbm90IHN1cHBvcnRlZCIpO28oTil9fSx6PSExO3JldHVybntlbmNyeXB0KEYsTil7aWYoeil0aHJvdyBFcnJvcigiY2Fubm90IGVuY3J5cHQoKSB0d2ljZSB3aXRoIHNhbWUga2V5ICsgbm9uY2UiKTtyZXR1cm4gej0hMCxvKEYpLFcoWC5lbmNyeXB0Lmxlbmd0aCxOKSxYLmVuY3J5cHQoRixOKX0sZGVjcnlwdChGLE4pe2lmKG8oRiksViYmRi5sZW5ndGg8Vil0aHJvdyBFcnJvcigiaW52YWxpZCBjaXBoZXJ0ZXh0IGxlbmd0aDogc21hbGxlciB0aGFuIHRhZ0xlbmd0aD0iK1YpO3JldHVybiBXKFguZGVjcnlwdC5sZW5ndGgsTiksWC5kZWNyeXB0KEYsTil9fX1yZXR1cm4gT2JqZWN0LmFzc2lnbihaLCQpLFp9O2Z1bmN0aW9uIGlKKCQsSixaPSEwKXtpZihKPT09dm9pZCAwKXJldHVybiBuZXcgVWludDhBcnJheSgkKTtpZihKLmxlbmd0aCE9PSQpdGhyb3cgRXJyb3IoImludmFsaWQgb3V0cHV0IGxlbmd0aCwgZXhwZWN0ZWQgIiskKyIsIGdvdDogIitKLmxlbmd0aCk7aWYoWiYmISRWKEopKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCwgbXVzdCBiZSBhbGlnbmVkIik7cmV0dXJuIEp9ZnVuY3Rpb24gJFYoJCl7cmV0dXJuICQuYnl0ZU9mZnNldCU0PT09MH1mdW5jdGlvbiB1JCgkKXtyZXR1cm4gVWludDhBcnJheS5mcm9tKCQpfWZ1bmN0aW9uIHEwKC4uLiQpe2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7SisrKSRbSl0uZmlsbCgwKX1mdW5jdGlvbiBSJCgkPTMyKXtpZihnMCYmdHlwZW9mIGcwLmdldFJhbmRvbVZhbHVlcz09PSJmdW5jdGlvbiIpcmV0dXJuIGcwLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheSgkKSk7aWYoZzAmJnR5cGVvZiBnMC5yYW5kb21CeXRlcz09PSJmdW5jdGlvbiIpcmV0dXJuIGcwLnJhbmRvbUJ5dGVzKCQpO3Rocm93IEVycm9yKCJjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIG11c3QgYmUgZGVmaW5lZCIpfXZhciBPUT0oJCk9PlVpbnQ4QXJyYXkuZnJvbSgkLnNwbGl0KCIiKS5tYXAoKEopPT5KLmNoYXJDb2RlQXQoMCkpKSxKVj1PUSgiZXhwYW5kIDE2LWJ5dGUgayIpLFpWPU9RKCJleHBhbmQgMzItYnl0ZSBrIiksUVY9QzAoSlYpLFlWPUMwKFpWKTtmdW5jdGlvbiBqKCQsSil7cmV0dXJuICQ8PEp8JD4+PjMyLUp9ZnVuY3Rpb24gbEooJCl7cmV0dXJuICQuYnl0ZU9mZnNldCU0PT09MH12YXIgcCQ9NjQsVlY9MTYsVVE9NDI5NDk2NzI5NSxOUT1uZXcgVWludDMyQXJyYXk7ZnVuY3Rpb24gWFYoJCxKLFosUSxZLFYsWCxXKXtsZXQgej1ZLmxlbmd0aCxLPW5ldyBVaW50OEFycmF5KHAkKSxGPUMwKEspLE49bEooWSkmJmxKKFYpLFU9Tj9DMChZKTpOUSxSPU4/QzAoVik6TlE7Zm9yKGxldCBIPTA7SDx6O1grKyl7aWYoJChKLFosUSxGLFgsVyksWD49VVEpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2xldCBxPU1hdGgubWluKHAkLHotSCk7aWYoTiYmcT09PXAkKXtsZXQgTT1ILzQ7aWYoSCU0IT09MCl0aHJvdyBFcnJvcigiYXJ4OiBpbnZhbGlkIGJsb2NrIHBvc2l0aW9uIik7Zm9yKGxldCBQPTAsQztQPFZWO1ArKylDPU0rUCxSW0NdPVVbQ11eRltQXTtIKz1wJDtjb250aW51ZX1mb3IobGV0IE09MCxQO008cTtNKyspUD1IK00sVltQXT1ZW1BdXktbTV07SCs9cX19ZnVuY3Rpb24gUlEoJCxKKXtsZXR7YWxsb3dTaG9ydEtleXM6WixleHRlbmROb25jZUZuOlEsY291bnRlckxlbmd0aDpZLGNvdW50ZXJSaWdodDpWLHJvdW5kczpYfT16USh7YWxsb3dTaG9ydEtleXM6ITEsY291bnRlckxlbmd0aDo4LGNvdW50ZXJSaWdodDohMSxyb3VuZHM6MjB9LEopO2lmKHR5cGVvZiAkIT09ImZ1bmN0aW9uIil0aHJvdyBFcnJvcigiY29yZSBtdXN0IGJlIGEgZnVuY3Rpb24iKTtyZXR1cm4gaSQoWSksaSQoWCksaEooViksaEooWiksKFcseixLLEYsTj0wKT0+e28oVyksbyh6KSxvKEspO2xldCBVPUsubGVuZ3RoO2lmKEY9PT12b2lkIDApRj1uZXcgVWludDhBcnJheShVKTtpZihvKEYpLGkkKE4pLE48MHx8Tj49VVEpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2lmKEYubGVuZ3RoPFUpdGhyb3cgRXJyb3IoYGFyeDogb3V0cHV0ICgke0YubGVuZ3RofSkgaXMgc2hvcnRlciB0aGFuIGRhdGEgKCR7VX0pYCk7bGV0IFI9W10sSD1XLmxlbmd0aCxxLE07aWYoSD09PTMyKVIucHVzaChxPXUkKFcpKSxNPVlWO2Vsc2UgaWYoSD09PTE2JiZaKXE9bmV3IFVpbnQ4QXJyYXkoMzIpLHEuc2V0KFcpLHEuc2V0KFcsMTYpLE09UVYsUi5wdXNoKHEpO2Vsc2UgdGhyb3cgRXJyb3IoYGFyeDogaW52YWxpZCAzMi1ieXRlIGtleSwgZ290IGxlbmd0aD0ke0h9YCk7aWYoIWxKKHopKVIucHVzaCh6PXUkKHopKTtsZXQgUD1DMChxKTtpZihRKXtpZih6Lmxlbmd0aCE9PTI0KXRocm93IEVycm9yKCJhcng6IGV4dGVuZGVkIG5vbmNlIG11c3QgYmUgMjQgYnl0ZXMiKTtRKE0sUCxDMCh6LnN1YmFycmF5KDAsMTYpKSxQKSx6PXouc3ViYXJyYXkoMTYpfWxldCBDPTE2LVk7aWYoQyE9PXoubGVuZ3RoKXRocm93IEVycm9yKGBhcng6IG5vbmNlIG11c3QgYmUgJHtDfSBvciAxNiBieXRlc2ApO2lmKEMhPT0xMil7bGV0IEk9bmV3IFVpbnQ4QXJyYXkoMTIpO0kuc2V0KHosVj8wOjEyLXoubGVuZ3RoKSx6PUksUi5wdXNoKHopfWxldCBUPUMwKHopO3JldHVybiBYVigkLE0sUCxULEssRixOLFgpLHEwKC4uLlIpLEZ9fXZhciBzPSgkLEopPT4kW0orK10mMjU1fCgkW0orK10mMjU1KTw8ODtjbGFzcyBIUXtjb25zdHJ1Y3RvcigkKXt0aGlzLmJsb2NrTGVuPTE2LHRoaXMub3V0cHV0TGVuPTE2LHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KDE2KSx0aGlzLnI9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLmg9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLnBhZD1uZXcgVWludDE2QXJyYXkoOCksdGhpcy5wb3M9MCx0aGlzLmZpbmlzaGVkPSExLCQ9bCQoJCksbygkLDMyKTtsZXQgSj1zKCQsMCksWj1zKCQsMiksUT1zKCQsNCksWT1zKCQsNiksVj1zKCQsOCksWD1zKCQsMTApLFc9cygkLDEyKSx6PXMoJCwxNCk7dGhpcy5yWzBdPUomODE5MSx0aGlzLnJbMV09KEo+Pj4xM3xaPDwzKSY4MTkxLHRoaXMuclsyXT0oWj4+PjEwfFE8PDYpJjc5MzksdGhpcy5yWzNdPShRPj4+N3xZPDw5KSY4MTkxLHRoaXMucls0XT0oWT4+PjR8Vjw8MTIpJjI1NSx0aGlzLnJbNV09Vj4+PjEmODE5MCx0aGlzLnJbNl09KFY+Pj4xNHxYPDwyKSY4MTkxLHRoaXMucls3XT0oWD4+PjExfFc8PDUpJjgwNjUsdGhpcy5yWzhdPShXPj4+OHx6PDw4KSY4MTkxLHRoaXMucls5XT16Pj4+NSYxMjc7Zm9yKGxldCBLPTA7Szw4O0srKyl0aGlzLnBhZFtLXT1zKCQsMTYrMipLKX1wcm9jZXNzKCQsSixaPSExKXtsZXQgUT1aPzA6MjA0OCx7aDpZLHI6Vn09dGhpcyxYPVZbMF0sVz1WWzFdLHo9VlsyXSxLPVZbM10sRj1WWzRdLE49Vls1XSxVPVZbNl0sUj1WWzddLEg9Vls4XSxxPVZbOV0sTT1zKCQsSiswKSxQPXMoJCxKKzIpLEM9cygkLEorNCksVD1zKCQsSis2KSxJPXMoJCxKKzgpLEE9cygkLEorMTApLEw9cygkLEorMTIpLGc9cygkLEorMTQpLGY9WVswXSsoTSY4MTkxKSxrPVlbMV0rKChNPj4+MTN8UDw8MykmODE5MSkseT1ZWzJdKygoUD4+PjEwfEM8PDYpJjgxOTEpLGg9WVszXSsoKEM+Pj43fFQ8PDkpJjgxOTEpLHU9WVs0XSsoKFQ+Pj40fEk8PDEyKSY4MTkxKSx3PVlbNV0rKEk+Pj4xJjgxOTEpLHg9WVs2XSsoKEk+Pj4xNHxBPDwyKSY4MTkxKSx2PVlbN10rKChBPj4+MTF8TDw8NSkmODE5MSksRT1ZWzhdKygoTD4+Pjh8Zzw8OCkmODE5MSksaT1ZWzldKyhnPj4+NXxRKSxfPTAsZD1fK2YqWCtrKig1KnEpK3kqKDUqSCkraCooNSpSKSt1Kig1KlUpO189ZD4+PjEzLGQmPTgxOTEsZCs9dyooNSpOKSt4Kig1KkYpK3YqKDUqSykrRSooNSp6KStpKig1KlcpLF8rPWQ+Pj4xMyxkJj04MTkxO2xldCB0PV8rZipXK2sqWCt5Kig1KnEpK2gqKDUqSCkrdSooNSpSKTtfPXQ+Pj4xMyx0Jj04MTkxLHQrPXcqKDUqVSkreCooNSpOKSt2Kig1KkYpK0UqKDUqSykraSooNSp6KSxfKz10Pj4+MTMsdCY9ODE5MTtsZXQgWTA9XytmKnoraypXK3kqWCtoKig1KnEpK3UqKDUqSCk7Xz1ZMD4+PjEzLFkwJj04MTkxLFkwKz13Kig1KlIpK3gqKDUqVSkrdiooNSpOKStFKig1KkYpK2kqKDUqSyksXys9WTA+Pj4xMyxZMCY9ODE5MTtsZXQgYz1fK2YqSytrKnoreSpXK2gqWCt1Kig1KnEpO189Yz4+PjEzLGMmPTgxOTEsYys9dyooNSpIKSt4Kig1KlIpK3YqKDUqVSkrRSooNSpOKStpKig1KkYpLF8rPWM+Pj4xMyxjJj04MTkxO2xldCBJMD1fK2YqRitrKksreSp6K2gqVyt1Klg7Xz1JMD4+PjEzLEkwJj04MTkxLEkwKz13Kig1KnEpK3gqKDUqSCkrdiooNSpSKStFKig1KlUpK2kqKDUqTiksXys9STA+Pj4xMyxJMCY9ODE5MTtsZXQgcDA9XytmKk4raypGK3kqSytoKnordSpXO189cDA+Pj4xMyxwMCY9ODE5MSxwMCs9dypYK3gqKDUqcSkrdiooNSpIKStFKig1KlIpK2kqKDUqVSksXys9cDA+Pj4xMyxwMCY9ODE5MTtsZXQgYzA9XytmKlUraypOK3kqRitoKksrdSp6O189YzA+Pj4xMyxjMCY9ODE5MSxjMCs9dypXK3gqWCt2Kig1KnEpK0UqKDUqSCkraSooNSpSKSxfKz1jMD4+PjEzLGMwJj04MTkxO2xldCBuMD1fK2YqUitrKlUreSpOK2gqRit1Kks7Xz1uMD4+PjEzLG4wJj04MTkxLG4wKz13KnoreCpXK3YqWCtFKig1KnEpK2kqKDUqSCksXys9bjA+Pj4xMyxuMCY9ODE5MTtsZXQgZDA9XytmKkgraypSK3kqVStoKk4rdSpGO189ZDA+Pj4xMyxkMCY9ODE5MSxkMCs9dypLK3gqeit2KlcrRSpYK2kqKDUqcSksXys9ZDA+Pj4xMyxkMCY9ODE5MTtsZXQgcjA9XytmKnEraypIK3kqUitoKlUrdSpOO189cjA+Pj4xMyxyMCY9ODE5MSxyMCs9dypGK3gqSyt2KnorRSpXK2kqWCxfKz1yMD4+PjEzLHIwJj04MTkxLF89KF88PDIpK198MCxfPV8rZHwwLGQ9XyY4MTkxLF89Xz4+PjEzLHQrPV8sWVswXT1kLFlbMV09dCxZWzJdPVkwLFlbM109YyxZWzRdPUkwLFlbNV09cDAsWVs2XT1jMCxZWzddPW4wLFlbOF09ZDAsWVs5XT1yMH1maW5hbGl6ZSgpe2xldHtoOiQscGFkOkp9PXRoaXMsWj1uZXcgVWludDE2QXJyYXkoMTApLFE9JFsxXT4+PjEzOyRbMV0mPTgxOTE7Zm9yKGxldCBYPTI7WDwxMDtYKyspJFtYXSs9USxRPSRbWF0+Pj4xMywkW1hdJj04MTkxOyRbMF0rPVEqNSxRPSRbMF0+Pj4xMywkWzBdJj04MTkxLCRbMV0rPVEsUT0kWzFdPj4+MTMsJFsxXSY9ODE5MSwkWzJdKz1RLFpbMF09JFswXSs1LFE9WlswXT4+PjEzLFpbMF0mPTgxOTE7Zm9yKGxldCBYPTE7WDwxMDtYKyspWltYXT0kW1hdK1EsUT1aW1hdPj4+MTMsWltYXSY9ODE5MTtaWzldLT04MTkyO2xldCBZPShRXjEpLTE7Zm9yKGxldCBYPTA7WDwxMDtYKyspWltYXSY9WTtZPX5ZO2ZvcihsZXQgWD0wO1g8MTA7WCsrKSRbWF09JFtYXSZZfFpbWF07JFswXT0oJFswXXwkWzFdPDwxMykmNjU1MzUsJFsxXT0oJFsxXT4+PjN8JFsyXTw8MTApJjY1NTM1LCRbMl09KCRbMl0+Pj42fCRbM108PDcpJjY1NTM1LCRbM109KCRbM10+Pj45fCRbNF08PDQpJjY1NTM1LCRbNF09KCRbNF0+Pj4xMnwkWzVdPDwxfCRbNl08PDE0KSY2NTUzNSwkWzVdPSgkWzZdPj4+MnwkWzddPDwxMSkmNjU1MzUsJFs2XT0oJFs3XT4+PjV8JFs4XTw8OCkmNjU1MzUsJFs3XT0oJFs4XT4+Pjh8JFs5XTw8NSkmNjU1MzU7bGV0IFY9JFswXStKWzBdOyRbMF09ViY2NTUzNTtmb3IobGV0IFg9MTtYPDg7WCsrKVY9KCRbWF0rSltYXXwwKSsoVj4+PjE2KXwwLCRbWF09ViY2NTUzNTtxMChaKX11cGRhdGUoJCl7YkoodGhpcyk7bGV0e2J1ZmZlcjpKLGJsb2NrTGVuOlp9PXRoaXM7JD1sJCgkKTtsZXQgUT0kLmxlbmd0aDtmb3IobGV0IFk9MDtZPFE7KXtsZXQgVj1NYXRoLm1pbihaLXRoaXMucG9zLFEtWSk7aWYoVj09PVope2Zvcig7Wjw9US1ZO1krPVopdGhpcy5wcm9jZXNzKCQsWSk7Y29udGludWV9aWYoSi5zZXQoJC5zdWJhcnJheShZLFkrViksdGhpcy5wb3MpLHRoaXMucG9zKz1WLFkrPVYsdGhpcy5wb3M9PT1aKXRoaXMucHJvY2VzcyhKLDAsITEpLHRoaXMucG9zPTB9cmV0dXJuIHRoaXN9ZGVzdHJveSgpe3EwKHRoaXMuaCx0aGlzLnIsdGhpcy5idWZmZXIsdGhpcy5wYWQpfWRpZ2VzdEludG8oJCl7YkoodGhpcyksR1EoJCx0aGlzKSx0aGlzLmZpbmlzaGVkPSEwO2xldHtidWZmZXI6SixoOlp9PXRoaXMse3BvczpRfT10aGlzO2lmKFEpe0pbUSsrXT0xO2Zvcig7UTwxNjtRKyspSltRXT0wO3RoaXMucHJvY2VzcyhKLDAsITApfXRoaXMuZmluYWxpemUoKTtsZXQgWT0wO2ZvcihsZXQgVj0wO1Y8ODtWKyspJFtZKytdPVpbVl0+Pj4wLCRbWSsrXT1aW1ZdPj4+ODtyZXR1cm4gJH1kaWdlc3QoKXtsZXR7YnVmZmVyOiQsb3V0cHV0TGVuOkp9PXRoaXM7dGhpcy5kaWdlc3RJbnRvKCQpO2xldCBaPSQuc2xpY2UoMCxKKTtyZXR1cm4gdGhpcy5kZXN0cm95KCksWn19ZnVuY3Rpb24gV1YoJCl7bGV0IEo9KFEsWSk9PiQoWSkudXBkYXRlKGwkKFEpKS5kaWdlc3QoKSxaPSQobmV3IFVpbnQ4QXJyYXkoMzIpKTtyZXR1cm4gSi5vdXRwdXRMZW49Wi5vdXRwdXRMZW4sSi5ibG9ja0xlbj1aLmJsb2NrTGVuLEouY3JlYXRlPShRKT0+JChRKSxKfXZhciB1Sj1XVigoJCk9Pm5ldyBIUSgkKSk7ZnVuY3Rpb24gR1YoJCxKLFosUSxZLFY9MjApe2xldCBYPSRbMF0sVz1KWzBdLHo9SlsxXSxLPUpbMl0sRj1KWzNdLE49JFsxXSxVPVpbMF0sUj1aWzFdLEg9WSxxPTAsTT0kWzJdLFA9Sls0XSxDPUpbNV0sVD1KWzZdLEk9Sls3XSxBPSRbM10sTD1YLGc9VyxmPXosaz1LLHk9RixoPU4sdT1VLHc9Uix4PUgsdj1xLEU9TSxpPVAsXz1DLGQ9VCx0PUksWTA9QTtmb3IobGV0IEkwPTA7STA8VjtJMCs9Mil5Xj1qKEwrX3wwLDcpLHhePWooeStMfDAsOSksX149aih4K3l8MCwxMyksTF49aihfK3h8MCwxOCksdl49aihoK2d8MCw3KSxkXj1qKHYraHwwLDkpLGdePWooZCt2fDAsMTMpLGhePWooZytkfDAsMTgpLHRePWooRSt1fDAsNyksZl49aih0K0V8MCw5KSx1Xj1qKGYrdHwwLDEzKSxFXj1qKHUrZnwwLDE4KSxrXj1qKFkwK2l8MCw3KSx3Xj1qKGsrWTB8MCw5KSxpXj1qKHcra3wwLDEzKSxZMF49aihpK3d8MCwxOCksZ149aihMK2t8MCw3KSxmXj1qKGcrTHwwLDkpLGtePWooZitnfDAsMTMpLExePWooaytmfDAsMTgpLHVePWooaCt5fDAsNyksd149aih1K2h8MCw5KSx5Xj1qKHcrdXwwLDEzKSxoXj1qKHkrd3wwLDE4KSxpXj1qKEUrdnwwLDcpLHhePWooaStFfDAsOSksdl49aih4K2l8MCwxMyksRV49aih2K3h8MCwxOCksX149aihZMCt0fDAsNyksZF49aihfK1kwfDAsOSksdF49aihkK198MCwxMyksWTBePWoodCtkfDAsMTgpO2xldCBjPTA7UVtjKytdPVgrTHwwLFFbYysrXT1XK2d8MCxRW2MrK109eitmfDAsUVtjKytdPUsra3wwLFFbYysrXT1GK3l8MCxRW2MrK109TitofDAsUVtjKytdPVUrdXwwLFFbYysrXT1SK3d8MCxRW2MrK109SCt4fDAsUVtjKytdPXErdnwwLFFbYysrXT1NK0V8MCxRW2MrK109UCtpfDAsUVtjKytdPUMrX3wwLFFbYysrXT1UK2R8MCxRW2MrK109SSt0fDAsUVtjKytdPUErWTB8MH1mdW5jdGlvbiB6VigkLEosWixRKXtsZXQgWT0kWzBdLFY9SlswXSxYPUpbMV0sVz1KWzJdLHo9SlszXSxLPSRbMV0sRj1aWzBdLE49WlsxXSxVPVpbMl0sUj1aWzNdLEg9JFsyXSxxPUpbNF0sTT1KWzVdLFA9Sls2XSxDPUpbN10sVD0kWzNdO2ZvcihsZXQgQT0wO0E8MjA7QSs9Mil6Xj1qKFkrTXwwLDcpLFVePWooeitZfDAsOSksTV49aihVK3p8MCwxMyksWV49aihNK1V8MCwxOCksUl49aihLK1Z8MCw3KSxQXj1qKFIrS3wwLDkpLFZePWooUCtSfDAsMTMpLEtePWooVitQfDAsMTgpLENePWooSCtGfDAsNyksWF49aihDK0h8MCw5KSxGXj1qKFgrQ3wwLDEzKSxIXj1qKEYrWHwwLDE4KSxXXj1qKFQrcXwwLDcpLE5ePWooVytUfDAsOSkscV49aihOK1d8MCwxMyksVF49aihxK058MCwxOCksVl49aihZK1d8MCw3KSxYXj1qKFYrWXwwLDkpLFdePWooWCtWfDAsMTMpLFlePWooVytYfDAsMTgpLEZePWooSyt6fDAsNyksTl49aihGK0t8MCw5KSx6Xj1qKE4rRnwwLDEzKSxLXj1qKHorTnwwLDE4KSxxXj1qKEgrUnwwLDcpLFVePWoocStIfDAsOSksUl49aihVK3F8MCwxMyksSF49aihSK1V8MCwxOCksTV49aihUK0N8MCw3KSxQXj1qKE0rVHwwLDkpLENePWooUCtNfDAsMTMpLFRePWooQytQfDAsMTgpO2xldCBJPTA7UVtJKytdPVksUVtJKytdPUssUVtJKytdPUgsUVtJKytdPVQsUVtJKytdPUYsUVtJKytdPU4sUVtJKytdPVUsUVtJKytdPVJ9dmFyIHBKPVJRKEdWLHtjb3VudGVyUmlnaHQ6ITAsZXh0ZW5kTm9uY2VGbjp6Vn0pLGNKPUZRKHtibG9ja1NpemU6NjQsbm9uY2VMZW5ndGg6MjQsdGFnTGVuZ3RoOjE2fSwoJCxKKT0+e3JldHVybntlbmNyeXB0KFosUSl7UT1pSihaLmxlbmd0aCszMixRLCExKTtsZXQgWT1RLnN1YmFycmF5KDAsMzIpLFY9US5zdWJhcnJheSgzMik7US5zZXQoWiwzMikscTAoWSkscEooJCxKLFEsUSk7bGV0IFg9dUooVixZKTtyZXR1cm4gUS5zZXQoWCwxNikscTAoUS5zdWJhcnJheSgwLDE2KSxYKSxRLnN1YmFycmF5KDE2KX0sZGVjcnlwdChaLFEpe28oWiksUT1pSihaLmxlbmd0aCszMixRLCExKTtsZXQgWT1RLnN1YmFycmF5KDAsMzIpLFY9US5zdWJhcnJheSgzMiw0OCksWD1RLnN1YmFycmF5KDQ4KTtRLnNldChaLDMyKSxxMChZKTtsZXQgVz1wSigkLEosWSxZKSx6PXVKKFgsVyk7aWYoIUtRKFYseikpdGhyb3cgRXJyb3IoImludmFsaWQgdGFnIik7cmV0dXJuIHBKKCQsSixRLnN1YmFycmF5KDE2KSxRLnN1YmFycmF5KDE2KSkscTAoWSxWLHopLFh9fX0pOy8qISBub2JsZS1oYXNoZXMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi9mdW5jdGlvbiBLVigkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldygkKSYmJC5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIEgkKCQpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcigkKXx8JDwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIiskKX1mdW5jdGlvbiBtMCgkLC4uLkope2lmKCFLVigkKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCIpO2lmKEoubGVuZ3RoPjAmJiFKLmluY2x1ZGVzKCQubGVuZ3RoKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCBvZiBsZW5ndGggIitKKyIsIGdvdCBsZW5ndGg9IiskLmxlbmd0aCl9ZnVuY3Rpb24gcSQoJCxKPSEwKXtpZigkLmRlc3Ryb3llZCl0aHJvdyBFcnJvcigiSGFzaCBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQiKTtpZihKJiYkLmZpbmlzaGVkKXRocm93IEVycm9yKCJIYXNoI2RpZ2VzdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIil9ZnVuY3Rpb24gYyQoJCxKKXttMCgkKTtsZXQgWj1KLm91dHB1dExlbjtpZigkLmxlbmd0aDxaKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK1opfWZ1bmN0aW9uIHFRKCQpe3JldHVybiBuZXcgVWludDhBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKX1mdW5jdGlvbiBWJCgkKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCxNYXRoLmZsb29yKCQuYnl0ZUxlbmd0aC80KSl9ZnVuY3Rpb24gWCQoLi4uJCl7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspJFtKXS5maWxsKDApfWZ1bmN0aW9uIE0kKCQsSil7cmV0dXJuICQ8PDMyLUp8JD4+Pkp9dmFyIE1RPSgoKT0+bmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQzMkFycmF5KFsyODc0NTQwMjBdKS5idWZmZXIpWzBdPT09NjgpKCk7ZnVuY3Rpb24gSVEoJCl7cmV0dXJuICQ8PDI0JjQyNzgxOTAwODB8JDw8OCYxNjcxMTY4MHwkPj4+OCY2NTI4MHwkPj4+MjQmMjU1fXZhciBDUT1NUT8oJCk9PiQ6KCQpPT5JUSgkKTtmdW5jdGlvbiBGVigkKXtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKykkW0pdPUlRKCRbSl0pO3JldHVybiAkfXZhciBKMD1NUT8oJCk9PiQ6RlY7ZnVuY3Rpb24gTlYoJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24gVyQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPU5WKCQpO3JldHVybiBtMCgkKSwkfWNsYXNzIG5Ke31mdW5jdGlvbiBQUSgkKXtsZXQgSj0oUSxZKT0+JChZKS51cGRhdGUoVyQoUSkpLmRpZ2VzdCgpLFo9JCh7fSk7cmV0dXJuIEoub3V0cHV0TGVuPVoub3V0cHV0TGVuLEouYmxvY2tMZW49Wi5ibG9ja0xlbixKLmNyZWF0ZT0oUSk9PiQoUSksSn12YXIgd1E9VWludDMyQXJyYXkuZnJvbShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKTt2YXIgbiQ9QmlnSW50KDQyOTQ5NjcyOTUpLFRRPUJpZ0ludCgzMik7ZnVuY3Rpb24gZEooJCxKPSExKXtpZihKKXJldHVybntoOk51bWJlcigkJm4kKSxsOk51bWJlcigkPj5UUSZuJCl9O3JldHVybntoOk51bWJlcigkPj5UUSZuJCl8MCxsOk51bWJlcigkJm4kKXwwfX1mdW5jdGlvbiBQMCgkLEosWixRLFkpe3JldHVybiAkPSQrSitZfDAsUT1NJChRXiQsMTYpLFo9WitRfDAsSj1NJChKXlosMTIpLHthOiQsYjpKLGM6WixkOlF9fWZ1bmN0aW9uIHcwKCQsSixaLFEsWSl7cmV0dXJuICQ9JCtKK1l8MCxRPU0kKFFeJCw4KSxaPVorUXwwLEo9TSQoSl5aLDcpLHthOiQsYjpKLGM6WixkOlF9fWNsYXNzIHJKIGV4dGVuZHMgbkp7Y29uc3RydWN0b3IoJCxKKXtzdXBlcigpO3RoaXMuZmluaXNoZWQ9ITEsdGhpcy5kZXN0cm95ZWQ9ITEsdGhpcy5sZW5ndGg9MCx0aGlzLnBvcz0wLEgkKCQpLEgkKEopLHRoaXMuYmxvY2tMZW49JCx0aGlzLm91dHB1dExlbj1KLHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KCQpLHRoaXMuYnVmZmVyMzI9ViQodGhpcy5idWZmZXIpfXVwZGF0ZSgkKXtxJCh0aGlzKSwkPVckKCQpLG0wKCQpO2xldHtibG9ja0xlbjpKLGJ1ZmZlcjpaLGJ1ZmZlcjMyOlF9PXRoaXMsWT0kLmxlbmd0aCxWPSQuYnl0ZU9mZnNldCxYPSQuYnVmZmVyO2ZvcihsZXQgVz0wO1c8WTspe2lmKHRoaXMucG9zPT09SilKMChRKSx0aGlzLmNvbXByZXNzKFEsMCwhMSksSjAoUSksdGhpcy5wb3M9MDtsZXQgej1NYXRoLm1pbihKLXRoaXMucG9zLFktVyksSz1WK1c7aWYoej09PUomJiEoSyU0KSYmVyt6PFkpe2xldCBGPW5ldyBVaW50MzJBcnJheShYLEssTWF0aC5mbG9vcigoWS1XKS80KSk7SjAoRik7Zm9yKGxldCBOPTA7VytKPFk7Tis9US5sZW5ndGgsVys9Sil0aGlzLmxlbmd0aCs9Six0aGlzLmNvbXByZXNzKEYsTiwhMSk7SjAoRik7Y29udGludWV9Wi5zZXQoJC5zdWJhcnJheShXLFcreiksdGhpcy5wb3MpLHRoaXMucG9zKz16LHRoaXMubGVuZ3RoKz16LFcrPXp9cmV0dXJuIHRoaXN9ZGlnZXN0SW50bygkKXtxJCh0aGlzKSxjJCgkLHRoaXMpO2xldHtwb3M6SixidWZmZXIzMjpafT10aGlzO3RoaXMuZmluaXNoZWQ9ITAsWCQodGhpcy5idWZmZXIuc3ViYXJyYXkoSikpLEowKFopLHRoaXMuY29tcHJlc3MoWiwwLCEwKSxKMChaKTtsZXQgUT1WJCgkKTt0aGlzLmdldCgpLmZvckVhY2goKFksVik9PlFbVl09Q1EoWSkpfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Sn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IFo9JC5zbGljZSgwLEopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxafV9jbG9uZUludG8oJCl7bGV0e2J1ZmZlcjpKLGxlbmd0aDpaLGZpbmlzaGVkOlEsZGVzdHJveWVkOlksb3V0cHV0TGVuOlYscG9zOlh9PXRoaXM7cmV0dXJuICR8fCgkPW5ldyB0aGlzLmNvbnN0cnVjdG9yKHtka0xlbjpWfSkpLCQuc2V0KC4uLnRoaXMuZ2V0KCkpLCQuYnVmZmVyLnNldChKKSwkLmRlc3Ryb3llZD1ZLCQuZmluaXNoZWQ9USwkLmxlbmd0aD1aLCQucG9zPVgsJC5vdXRwdXRMZW49ViwkfWNsb25lKCl7cmV0dXJuIHRoaXMuX2Nsb25lSW50bygpfX1mdW5jdGlvbiBvSigkLEosWixRLFksVixYLFcseixLLEYsTixVLFIsSCxxLE0sUCxDLFQpe2xldCBJPTA7Zm9yKGxldCBBPTA7QTxRO0ErKykoe2E6WSxiOnosYzpVLGQ6TX09UDAoWSx6LFUsTSxaW0orJFtJKytdXSkpLHthOlksYjp6LGM6VSxkOk19PXcwKFkseixVLE0sWltKKyRbSSsrXV0pLHthOlYsYjpLLGM6UixkOlB9PVAwKFYsSyxSLFAsWltKKyRbSSsrXV0pLHthOlYsYjpLLGM6UixkOlB9PXcwKFYsSyxSLFAsWltKKyRbSSsrXV0pLHthOlgsYjpGLGM6SCxkOkN9PVAwKFgsRixILEMsWltKKyRbSSsrXV0pLHthOlgsYjpGLGM6SCxkOkN9PXcwKFgsRixILEMsWltKKyRbSSsrXV0pLHthOlcsYjpOLGM6cSxkOlR9PVAwKFcsTixxLFQsWltKKyRbSSsrXV0pLHthOlcsYjpOLGM6cSxkOlR9PXcwKFcsTixxLFQsWltKKyRbSSsrXV0pLHthOlksYjpLLGM6SCxkOlR9PVAwKFksSyxILFQsWltKKyRbSSsrXV0pLHthOlksYjpLLGM6SCxkOlR9PXcwKFksSyxILFQsWltKKyRbSSsrXV0pLHthOlYsYjpGLGM6cSxkOk19PVAwKFYsRixxLE0sWltKKyRbSSsrXV0pLHthOlYsYjpGLGM6cSxkOk19PXcwKFYsRixxLE0sWltKKyRbSSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PVAwKFgsTixVLFAsWltKKyRbSSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PXcwKFgsTixVLFAsWltKKyRbSSsrXV0pLHthOlcsYjp6LGM6UixkOkN9PVAwKFcseixSLEMsWltKKyRbSSsrXV0pLHthOlcsYjp6LGM6UixkOkN9PXcwKFcseixSLEMsWltKKyRbSSsrXV0pO3JldHVybnt2MDpZLHYxOlYsdjI6WCx2MzpXLHY0OnosdjU6Syx2NjpGLHY3Ok4sdjg6VSx2OTpSLHYxMDpILHYxMTpxLHYxMjpNLHYxMzpQLHYxNDpDLHYxNTpUfX12YXIgTTA9e0NIVU5LX1NUQVJUOjEsQ0hVTktfRU5EOjIsUEFSRU5UOjQsUk9PVDo4LEtFWUVEX0hBU0g6MTYsREVSSVZFX0tFWV9DT05URVhUOjMyLERFUklWRV9LRVlfTUFURVJJQUw6NjR9LFQwPXdRLnNsaWNlKCksalE9KCgpPT57bGV0ICQ9QXJyYXkuZnJvbSh7bGVuZ3RoOjE2fSwoUSxZKT0+WSksSj0oUSk9PlsyLDYsMywxMCw3LDAsNCwxMywxLDExLDEyLDUsOSwxNCwxNSw4XS5tYXAoKFkpPT5RW1ldKSxaPVtdO2ZvcihsZXQgUT0wLFk9JDtRPDc7USsrLFk9SihZKSlaLnB1c2goLi4uWSk7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShaKX0pKCk7Y2xhc3MgYUogZXh0ZW5kcyBySntjb25zdHJ1Y3RvcigkPXt9LEo9MCl7c3VwZXIoNjQsJC5ka0xlbj09PXZvaWQgMD8zMjokLmRrTGVuKTt0aGlzLmNodW5rUG9zPTAsdGhpcy5jaHVua3NEb25lPTAsdGhpcy5mbGFncz0wLHRoaXMuc3RhY2s9W10sdGhpcy5wb3NPdXQ9MCx0aGlzLmJ1ZmZlck91dDMyPW5ldyBVaW50MzJBcnJheSgxNiksdGhpcy5jaHVua091dD0wLHRoaXMuZW5hYmxlWE9GPSEwO2xldHtrZXk6Wixjb250ZXh0OlF9PSQsWT1RIT09dm9pZCAwO2lmKFohPT12b2lkIDApe2lmKFkpdGhyb3cgRXJyb3IoJ09ubHkgImtleSIgb3IgImNvbnRleHQiIGNhbiBiZSBzcGVjaWZpZWQgYXQgc2FtZSB0aW1lJyk7bGV0IFY9VyQoWikuc2xpY2UoKTttMChWLDMyKSx0aGlzLklWPVYkKFYpLEowKHRoaXMuSVYpLHRoaXMuZmxhZ3M9SnxNMC5LRVlFRF9IQVNIfWVsc2UgaWYoWSl7bGV0IFY9VyQoUSksWD1uZXcgYUooe2RrTGVuOjMyfSxNMC5ERVJJVkVfS0VZX0NPTlRFWFQpLnVwZGF0ZShWKS5kaWdlc3QoKTt0aGlzLklWPVYkKFgpLEowKHRoaXMuSVYpLHRoaXMuZmxhZ3M9SnxNMC5ERVJJVkVfS0VZX01BVEVSSUFMfWVsc2UgdGhpcy5JVj1UMC5zbGljZSgpLHRoaXMuZmxhZ3M9Sjt0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKSx0aGlzLmJ1ZmZlck91dD1xUSh0aGlzLmJ1ZmZlck91dDMyKX1nZXQoKXtyZXR1cm5bXX1zZXQoKXt9YjJDb21wcmVzcygkLEosWixRPTApe2xldHtzdGF0ZTpZLHBvczpWfT10aGlzLHtoOlgsbDpXfT1kSihCaWdJbnQoJCksITApLHt2MDp6LHYxOkssdjI6Rix2MzpOLHY0OlUsdjU6Uix2NjpILHY3OnEsdjg6TSx2OTpQLHYxMDpDLHYxMTpULHYxMjpJLHYxMzpBLHYxNDpMLHYxNTpnfT1vSihqUSxRLFosNyxZWzBdLFlbMV0sWVsyXSxZWzNdLFlbNF0sWVs1XSxZWzZdLFlbN10sVDBbMF0sVDBbMV0sVDBbMl0sVDBbM10sWCxXLFYsSik7WVswXT16Xk0sWVsxXT1LXlAsWVsyXT1GXkMsWVszXT1OXlQsWVs0XT1VXkksWVs1XT1SXkEsWVs2XT1IXkwsWVs3XT1xXmd9Y29tcHJlc3MoJCxKPTAsWj0hMSl7bGV0IFE9dGhpcy5mbGFncztpZighdGhpcy5jaHVua1BvcylRfD1NMC5DSFVOS19TVEFSVDtpZih0aGlzLmNodW5rUG9zPT09MTV8fFopUXw9TTAuQ0hVTktfRU5EO2lmKCFaKXRoaXMucG9zPXRoaXMuYmxvY2tMZW47aWYodGhpcy5iMkNvbXByZXNzKHRoaXMuY2h1bmtzRG9uZSxRLCQsSiksdGhpcy5jaHVua1Bvcys9MSx0aGlzLmNodW5rUG9zPT09MTZ8fFope2xldCBZPXRoaXMuc3RhdGU7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCk7Zm9yKGxldCBWLFg9dGhpcy5jaHVua3NEb25lKzE7Wnx8IShYJjEpO1g+Pj0xKXtpZighKFY9dGhpcy5zdGFjay5wb3AoKSkpYnJlYWs7dGhpcy5idWZmZXIzMi5zZXQoViwwKSx0aGlzLmJ1ZmZlcjMyLnNldChZLDgpLHRoaXMucG9zPXRoaXMuYmxvY2tMZW4sdGhpcy5iMkNvbXByZXNzKDAsdGhpcy5mbGFnc3xNMC5QQVJFTlQsdGhpcy5idWZmZXIzMiwwKSxZPXRoaXMuc3RhdGUsdGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCl9dGhpcy5jaHVua3NEb25lKyssdGhpcy5jaHVua1Bvcz0wLHRoaXMuc3RhY2sucHVzaChZKX10aGlzLnBvcz0wfV9jbG9uZUludG8oJCl7JD1zdXBlci5fY2xvbmVJbnRvKCQpO2xldHtJVjpKLGZsYWdzOlosc3RhdGU6USxjaHVua1BvczpZLHBvc091dDpWLGNodW5rT3V0Olgsc3RhY2s6VyxjaHVua3NEb25lOnp9PXRoaXM7cmV0dXJuICQuc3RhdGUuc2V0KFEuc2xpY2UoKSksJC5zdGFjaz1XLm1hcCgoSyk9PlVpbnQzMkFycmF5LmZyb20oSykpLCQuSVYuc2V0KEopLCQuZmxhZ3M9WiwkLmNodW5rUG9zPVksJC5jaHVua3NEb25lPXosJC5wb3NPdXQ9ViwkLmNodW5rT3V0PVgsJC5lbmFibGVYT0Y9dGhpcy5lbmFibGVYT0YsJC5idWZmZXJPdXQzMi5zZXQodGhpcy5idWZmZXJPdXQzMiksJH1kZXN0cm95KCl7dGhpcy5kZXN0cm95ZWQ9ITAsWCQodGhpcy5zdGF0ZSx0aGlzLmJ1ZmZlcjMyLHRoaXMuSVYsdGhpcy5idWZmZXJPdXQzMiksWCQoLi4udGhpcy5zdGFjayl9YjJDb21wcmVzc091dCgpe2xldHtzdGF0ZTokLHBvczpKLGZsYWdzOlosYnVmZmVyMzI6USxidWZmZXJPdXQzMjpZfT10aGlzLHtoOlYsbDpYfT1kSihCaWdJbnQodGhpcy5jaHVua091dCsrKSk7SjAoUSk7bGV0e3YwOlcsdjE6eix2MjpLLHYzOkYsdjQ6Tix2NTpVLHY2OlIsdjc6SCx2ODpxLHY5Ok0sdjEwOlAsdjExOkMsdjEyOlQsdjEzOkksdjE0OkEsdjE1Okx9PW9KKGpRLDAsUSw3LCRbMF0sJFsxXSwkWzJdLCRbM10sJFs0XSwkWzVdLCRbNl0sJFs3XSxUMFswXSxUMFsxXSxUMFsyXSxUMFszXSxYLFYsSixaKTtZWzBdPVdecSxZWzFdPXpeTSxZWzJdPUteUCxZWzNdPUZeQyxZWzRdPU5eVCxZWzVdPVVeSSxZWzZdPVJeQSxZWzddPUheTCxZWzhdPSRbMF1ecSxZWzldPSRbMV1eTSxZWzEwXT0kWzJdXlAsWVsxMV09JFszXV5DLFlbMTJdPSRbNF1eVCxZWzEzXT0kWzVdXkksWVsxNF09JFs2XV5BLFlbMTVdPSRbN11eTCxKMChRKSxKMChZKSx0aGlzLnBvc091dD0wfWZpbmlzaCgpe2lmKHRoaXMuZmluaXNoZWQpcmV0dXJuO3RoaXMuZmluaXNoZWQ9ITAsWCQodGhpcy5idWZmZXIuc3ViYXJyYXkodGhpcy5wb3MpKTtsZXQgJD10aGlzLmZsYWdzfE0wLlJPT1Q7aWYodGhpcy5zdGFjay5sZW5ndGgpJHw9TTAuUEFSRU5ULEowKHRoaXMuYnVmZmVyMzIpLHRoaXMuY29tcHJlc3ModGhpcy5idWZmZXIzMiwwLCEwKSxKMCh0aGlzLmJ1ZmZlcjMyKSx0aGlzLmNodW5rc0RvbmU9MCx0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2Vsc2UgJHw9KCF0aGlzLmNodW5rUG9zP00wLkNIVU5LX1NUQVJUOjApfE0wLkNIVU5LX0VORDt0aGlzLmZsYWdzPSQsdGhpcy5iMkNvbXByZXNzT3V0KCl9d3JpdGVJbnRvKCQpe3EkKHRoaXMsITEpLG0wKCQpLHRoaXMuZmluaXNoKCk7bGV0e2Jsb2NrTGVuOkosYnVmZmVyT3V0Olp9PXRoaXM7Zm9yKGxldCBRPTAsWT0kLmxlbmd0aDtRPFk7KXtpZih0aGlzLnBvc091dD49Sil0aGlzLmIyQ29tcHJlc3NPdXQoKTtsZXQgVj1NYXRoLm1pbihKLXRoaXMucG9zT3V0LFktUSk7JC5zZXQoWi5zdWJhcnJheSh0aGlzLnBvc091dCx0aGlzLnBvc091dCtWKSxRKSx0aGlzLnBvc091dCs9VixRKz1WfXJldHVybiAkfXhvZkludG8oJCl7aWYoIXRoaXMuZW5hYmxlWE9GKXRocm93IEVycm9yKCJYT0YgaXMgbm90IHBvc3NpYmxlIGFmdGVyIGRpZ2VzdCBjYWxsIik7cmV0dXJuIHRoaXMud3JpdGVJbnRvKCQpfXhvZigkKXtyZXR1cm4gSCQoJCksdGhpcy54b2ZJbnRvKG5ldyBVaW50OEFycmF5KCQpKX1kaWdlc3RJbnRvKCQpe2lmKGMkKCQsdGhpcyksdGhpcy5maW5pc2hlZCl0aHJvdyBFcnJvcigiZGlnZXN0KCkgd2FzIGFscmVhZHkgY2FsbGVkIik7cmV0dXJuIHRoaXMuZW5hYmxlWE9GPSExLHRoaXMud3JpdGVJbnRvKCQpLHRoaXMuZGVzdHJveSgpLCR9ZGlnZXN0KCl7cmV0dXJuIHRoaXMuZGlnZXN0SW50byhuZXcgVWludDhBcnJheSh0aGlzLm91dHB1dExlbikpfX12YXIgRFE9UFEoKCQpPT5uZXcgYUooJCkpO3ZhciBPVj0zMixXRj1TeW1ib2woIlgyNTUxOVNrIik7ZnVuY3Rpb24gQVEoJCl7aWYoJC5ieXRlTGVuZ3RoIT09T1YpcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfXZhciBiPSgxbjw8MjU1biktMTluLFVWPTEyMTY2NW4sX1E9bmV3IFVpbnQ4QXJyYXkoMzIpO19RWzBdPTk7ZnVuY3Rpb24gTFEoJCl7bGV0IEo9MG47Zm9yKGxldCBaPSQubGVuZ3RoLTE7Wj49MDtaLS0pSj1KPDw4bnxCaWdJbnQoJFtaXSk7cmV0dXJuIEp9ZnVuY3Rpb24gUlYoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMzIpLFo9KCQlYitiKSViO2ZvcihsZXQgUT0wO1E8MzI7USsrKUpbUV09TnVtYmVyKFomMHhmZm4pLFo+Pj04bjtyZXR1cm4gSn1mdW5jdGlvbiBIVigkKXtsZXQgSj0kLnNsaWNlKCk7cmV0dXJuIEpbMzFdJj0xMjcsTFEoSil9ZnVuY3Rpb24gcVYoJCl7bGV0IEo9JC5zbGljZSgpO3JldHVybiBKWzBdJj0yNDgsSlszMV0mPTEyNyxKWzMxXXw9NjQsSn1mdW5jdGlvbiBkJCgkLEosWil7bGV0IFE9LSQsWT0oSl5aKSZRO3JldHVybltKXlksWl5ZXX1mdW5jdGlvbiBNVigkKXtsZXQgSj1iLTJuLFo9KCQlYitiKSViLFE9MW47d2hpbGUoSj4wbil7aWYoSiYxbilRPVEqWiViO1o9WipaJWIsSj4+PTFufXJldHVybiBRfWZ1bmN0aW9uIElWKCQsSil7bGV0IFo9cVYoJCksUT1IVihKKSxZPTFuLFY9MG4sWD1RLFc9MW4sej0wbixLPUxRKFopO2ZvcihsZXQgRj0yNTQ7Rj49MDtGLS0pe2xldCBOPUs+PkJpZ0ludChGKSYxbjt6Xj1OLFtZLFhdPWQkKHosWSxYKSxbVixXXT1kJCh6LFYsVyksej1OO2xldCBVPShZK1YpJWIsUj1VKlUlYixIPShZLVYrYiklYixxPUgqSCViLE09KFItcStiKSViLFA9KFgrVyklYixUPShYLVcrYiklYipVJWIsST1QKkglYixBPShUK0kpJWIsTD0oVC1JK2IpJWI7WD1BKkElYixXPVEqTCpMJWIsWT1SKnElYixWPU0qKFIrVVYqTSklYn1yZXR1cm5bWSxYXT1kJCh6LFksWCksW1YsV109ZCQoeixWLFcpLFouZmlsbCgwKSxSVihZKk1WKFYpJWIpfWZ1bmN0aW9uIHhRKCQpe3JldHVybiBJVigkLF9RKX12YXIgc0o9bmV3IFVpbnQ4QXJyYXkoWzQ4LDQ2LDIsMSwwLDQ4LDUsNiwzLDQzLDEwMSwxMTIsNCwzNCw0LDMyXSk7ZnVuY3Rpb24gQlEoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoc0oubGVuZ3RoKzMyKTtyZXR1cm4gSi5zZXQoc0opLEouc2V0KCQuc3ViYXJyYXkoMCwzMiksc0oubGVuZ3RoKSxKfXZhciB0Sj1uZXcgVWludDhBcnJheShbNDgsNDYsMiwxLDAsNDgsNSw2LDMsNDMsMTAxLDExMCw0LDM0LDQsMzJdKTtmdW5jdGlvbiBrUSgkKXtsZXQgSj1uZXcgVWludDhBcnJheSh0Si5sZW5ndGgrMzIpO3JldHVybiBKLnNldCh0SiksSi5zZXQoJC5zdWJhcnJheSgwLDMyKSx0Si5sZW5ndGgpLEp9ZnVuY3Rpb24gRVEoJCl7cmV0dXJuIHR5cGVvZiAkPT09InN0cmluZyI/bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpOiR9ZnVuY3Rpb24gajAoJCl7bGV0IEo9bmV3IEFycmF5QnVmZmVyKCQuYnl0ZUxlbmd0aCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KEopLnNldCgkKSxKfWNsYXNzIFMwe3ZlcmlmeUtleXM9bmV3IE1hcDthc3luYyBnZW5SYW5kb21CeXRlcygkKXtyZXR1cm4gUiQoJCl9YXN5bmMgZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpe3JldHVybiBSJCgzMil9YXN5bmMgZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLEope2xldCBaPVIkKDI0KSxZPWNKKEosWikuZW5jcnlwdCgkKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWy4uLlosLi4uWV0pfWFzeW5jIGRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxKKXtsZXQgWj0kLnNsaWNlKDAsMjQpLFE9JC5zbGljZSgyNCk7cmV0dXJuIGNKKEosWikuZGVjcnlwdChRKX1hc3luYyBkZXJpdmVFZDI1NTE5S2V5UGFpcigkKXtsZXQgSj0kLFo9QlEoSiksUT1qMChaKSxZO3RyeXtsZXQgSz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsic2lnbiJdKTtZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoImp3ayIsSyl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX1pZih0eXBlb2YgWS54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIkVkMjU1MTkgSldLIG1pc3NpbmcgeCIpO2xldCBWPVkueDtZLmQ9dm9pZCAwO2xldCBYPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoImp3ayIse2t0eToiT0tQIixjcnY6IkVkMjU1MTkiLHg6Vn0se25hbWU6IkVkMjU1MTkifSwhMCxbInZlcmlmeSJdKSxXPW5ldyBVaW50OEFycmF5KGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoInJhdyIsWCkpO3RoaXMudmVyaWZ5S2V5cy5zZXQoVTAoVyksWCk7bGV0IHo9bmV3IFVpbnQ4QXJyYXkoNjQpO3JldHVybiB6LnNldChKLDApLHouc2V0KFcsMzIpLHtrZXlUeXBlOiJlZDI1NTE5Iixwcml2YXRlS2V5OnoscHVibGljS2V5Old9fWFzeW5jIGltcG9ydFNpZ25LZXkoJCl7bGV0IEo9JC5zdWJhcnJheSgwLDMyKSxaPUJRKEopLFE9ajAoWik7dHJ5e3JldHVybiBhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiRWQyNTUxOSJ9LCExLFsic2lnbiJdKX1maW5hbGx5e1ouZmlsbCgwKSxuZXcgVWludDhBcnJheShRKS5maWxsKDApfX1hc3luYyBpbXBvcnRWZXJpZnlLZXkoJCl7bGV0IEo9VTAoJCksWj10aGlzLnZlcmlmeUtleXMuZ2V0KEopO2lmKFopcmV0dXJuIFo7bGV0IFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixqMCgkKSx7bmFtZToiRWQyNTUxOSJ9LCExLFsidmVyaWZ5Il0pO3JldHVybiB0aGlzLnZlcmlmeUtleXMuc2V0KEosUSksUX1hc3luYyBzaWduRWQyNTUxOSgkLEope2xldCBaPUVRKCQpLFE9YXdhaXQgdGhpcy5pbXBvcnRTaWduS2V5KEopLFk9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnNpZ24oe25hbWU6IkVkMjU1MTkifSxRLGowKFopKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWSl9YXN5bmMgY2hlY2tTaWdFZDI1NTE5KCQsSixaKXtsZXQgUT1FUShKKTt0cnl7bGV0IFk9YXdhaXQgdGhpcy5pbXBvcnRWZXJpZnlLZXkoWik7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS52ZXJpZnkoe25hbWU6IkVkMjU1MTkifSxZLGowKCQpLGowKFEpKX1jYXRjaHtyZXR1cm4hMX19YXN5bmMgYmxha2UzKCQpe3JldHVybiBEUSgkKX1hc3luYyBnZW5YMjU1MTkoKXtsZXQgJD1hd2FpdCBSJCgzMik7JFswXSY9MjQ4LCRbMzFdJj0xMjcsJFszMV18PTY0O2xldFtKLFpdPUFRKCQpO2lmKFohPT0wfHxKPT09dm9pZCAwKXRocm93ICQuZmlsbCgwKSxFcnJvcigiWDI1NTE5IHNjYWxhciBicmFuZCBmYWlsZWQiKTtsZXQgUT14UShKKSxZPWtRKEopLFY9ajAoWSk7dHJ5e2xldCBYPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixWLHtuYW1lOiJYMjU1MTkifSwhMCxbImRlcml2ZUJpdHMiXSksVz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJqd2siLFgpO2lmKHR5cGVvZiBXLnghPT0ic3RyaW5nIil0aHJvdyBFcnJvcigiWDI1NTE5IEpXSyBtaXNzaW5nIHgiKTtsZXQgej14WihXLngpO2lmKFcuZD12b2lkIDAsIXIoeixRKSl0aHJvdyBFcnJvcigiWDI1NTE5IFdlYkNyeXB0byBwdWIgIT0gUkZDIDc3NDgiKTtyZXR1cm57cHJpdjpKLHB1YjpRfX1jYXRjaChYKXt0aHJvdyBKLmZpbGwoMCksWH1maW5hbGx5e1kuZmlsbCgwKSxuZXcgVWludDhBcnJheShWKS5maWxsKDApfX1hc3luYyB4MjU1MTlTaGFyZWQoJCxKKXtsZXQgWj1rUSgkKSxRPWowKFopO3RyeXtsZXQgWT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiWDI1NTE5In0sITEsWyJkZXJpdmVCaXRzIl0pLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixqMChKKSx7bmFtZToiWDI1NTE5In0sITEsW10pLFg9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmRlcml2ZUJpdHMoe25hbWU6IlgyNTUxOSIscHVibGljOlZ9LFksMjU2KTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWCl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX19fXZhciBDVj1uZXcgUzAsciQ9Q1Y7dmFyIHYwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyU3RyaW5nKEouaGFuZGxlKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyU3RyaW5nKEoubGFiZWwpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAkLndyaXRlVmFySW50KEouaWR4Pz8wKX0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhclN0cmluZygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhclN0cmluZygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBPKHtoYW5kbGU6SixsYWJlbDpRLGlkeDpWfSl9fTt2YXIgbyQ9MSxlSj17ZW5jb2RlKCQsSil7aWYoSi52IT09byQpcmV0dXJuIDEwO2xldFssWl09JDAoSi5tYXN0ZXJTZWVkKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEoudik7aWYoUSE9PTApcmV0dXJuIFE7JC53cml0ZUJ5dGVzKEoubWFzdGVyU2VlZCk7bGV0IFk9JC53cml0ZVZhckludChKLmhvc3RzLmxlbmd0aCk7aWYoWSE9PTApcmV0dXJuIFk7Zm9yKGxldCBWIG9mIEouaG9zdHMpe2xldCBYPSQud3JpdGVTdHJ1Y3QodjAsVik7aWYoWCE9PTApcmV0dXJuIFh9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKIT09byQpcmV0dXJuIEcoMTQpO2xldFtRLFldPSQucmVhZEJ5dGVzKEgwKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVixYXT0kMChRKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwfHxXPDApcmV0dXJuIEcoMTApO2xldCBLPVtdO2ZvcihsZXQgRj0wO0Y8VztGKyspe2xldFtOLFVdPSQucmVhZFN0cnVjdCh2MCk7aWYoVSE9PTApcmV0dXJuIEcoVSk7aWYoTj09PXZvaWQgMClyZXR1cm4gRygxNCk7Sy5wdXNoKE4pfXJldHVybiBPKHt2Om8kLG1hc3RlclNlZWQ6Vixob3N0czpLfSl9fTtmdW5jdGlvbiBmUSgkLEope2xldFtaLFFdPSQwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtZLFZdPSQwKFouc2xpY2UoKSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE8oe3Y6byQsbWFzdGVyU2VlZDpZLGhvc3RzOkoubWFwKChYKT0+KHtoYW5kbGU6WC5oYW5kbGUsbGFiZWw6WC5sYWJlbCxpZHg6WC5pZHg/PzB9KSl9KX12YXIgYSQ9e2VuY29kZSgkLEope2xldFssWl09JDAoSi5tYXN0ZXJTZWVkKTtpZihaIT09MClyZXR1cm4gWjskLndyaXRlQnl0ZXMoSi5tYXN0ZXJTZWVkKTtsZXQgUT0kLndyaXRlVmFySW50KEouaG9zdHMubGVuZ3RoKTtpZihRIT09MClyZXR1cm4gUTtmb3IobGV0IFkgb2YgSi5ob3N0cyl7bGV0IFY9JC53cml0ZVN0cnVjdCh2MCxZKTtpZihWIT09MClyZXR1cm4gVn1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEgwKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbUSxZXT0kMChKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwfHxWPDApcmV0dXJuIEcoMTApO2xldCBXPVtdO2ZvcihsZXQgej0wO3o8Vjt6Kyspe2xldFtLLEZdPSQucmVhZFN0cnVjdCh2MCk7aWYoRiE9PTApcmV0dXJuIEcoRik7aWYoSz09PXZvaWQgMClyZXR1cm4gRygxNCk7Vy5wdXNoKEspfXJldHVybiBPKHttYXN0ZXJTZWVkOlEsaG9zdHM6V30pfX07dmFyIFBWPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5xcnBhaXIudjEiKSxJJD0zMix3Vj1JJCsyNCsxNixUVj0zMixiRj1TeW1ib2woIkRIS0VSZXEiKSxoRj1TeW1ib2woIkRIS0VSZXNwIik7ZnVuY3Rpb24gZ1EoJCl7aWYoJC5ieXRlTGVuZ3RoIT09SSQpcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfWZ1bmN0aW9uIG1RKCQpe2lmKCQuYnl0ZUxlbmd0aDx3VilyZXR1cm4gRygxMCk7cmV0dXJuIE8oJCl9dmFyIHMkPW5ldyBTMDthc3luYyBmdW5jdGlvbiAkWigkLEosWixRKXtsZXQgWTt0cnl7WT1hd2FpdCBzJC54MjU1MTlTaGFyZWQoJCxKKX1jYXRjaHtyZXR1cm4gRygyOSl9dHJ5e2lmKFkuYnl0ZUxlbmd0aCE9PUkkfHxZLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDEwKTtsZXQgVj1SMChZLFBWKSxYPVIwKFYsUjAoWixRKSk7dHJ5e2xldCBXPWF3YWl0IHMkLmJsYWtlMyhYKTtyZXR1cm4gTyhXLnNsaWNlKDAsVFYpKX1maW5hbGx5e1YuZmlsbCgwKSxYLmZpbGwoMCl9fWZpbmFsbHl7WS5maWxsKDApfX1jbGFzcyB0JHsjJDsjSjtjb25zdHJ1Y3RvcigkLEope3RoaXMuIyQ9JCx0aGlzLiNKPUp9c3RhdGljIGFzeW5jIGNyZWF0ZSgpe2xldCAkO3RyeXtsZXQgSj1hd2FpdCBzJC5nZW5YMjU1MTkoKTskPUoucHJpdjtsZXRbWixRXT1nUShKLnB1Yik7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0IFk9bmV3IHQkKCQsWik7cmV0dXJuICQ9dm9pZCAwLE8oWSl9Y2F0Y2h7cmV0dXJuIEcoMjkpfWZpbmFsbHl7JD8uZmlsbCgwKX19d2lwZSgpe3RoaXMuIyQuZmlsbCgwKX1nZXQgZGhrZVJlcSgpe2xldFskLEpdPWdRKHRoaXMuI0ouc2xpY2UoKSk7aWYoJD09PXZvaWQgMCl0aHJvdyBFcnJvcihgZGhrZVJlcSAke0p9YCk7cmV0dXJuICR9YXN5bmMgZmluaXNoKCQpe2xldCBKPSQuc3ViYXJyYXkoMCxJJCksWj0kLnN1YmFycmF5KEkkKSxbUSxZXT1hd2FpdCAkWih0aGlzLiMkLEosdGhpcy4jSixKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgVjt0cnl7dHJ5e1Y9YXdhaXQgcyQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFEpfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgWD1uZXcgbShWKSxbVyx6XT1YLnJlYWRTdHJ1Y3QoYSQpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMTQpO3RyeXtsZXRbSyxGXT1XMC5mcm9tQnl0ZXMoVy5tYXN0ZXJTZWVkKTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gdGhpcy53aXBlKCksTyh7ZW5jbGF2ZTpLLGhvc3RzOlcuaG9zdHMubWFwKChOKT0+KHsuLi5OfSkpfSl9ZmluYWxseXtXLm1hc3RlclNlZWQuZmlsbCgwKX19ZmluYWxseXtRLmZpbGwoMCksVj8uZmlsbCgwKX19fWZ1bmN0aW9uIEQwKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KCQpO2lmKCQ+MCljcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKEopO3JldHVybiBKfXZhciB5MD0zMixqVj0tNyxEVj0tOCxBVj0tMjU3LGUkPVt7dHlwZToicHVibGljLWtleSIsYWxnOmpWfSx7dHlwZToicHVibGljLWtleSIsYWxnOkRWfSx7dHlwZToicHVibGljLWtleSIsYWxnOkFWfV07ZnVuY3Rpb24gX1YoJCl7cmV0dXJuICQudHJpbSgpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXC4kLywiIil8fCJsb2NhbGhvc3QifWZ1bmN0aW9uIEIwKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KCQuYnl0ZUxlbmd0aCk7cmV0dXJuIEouc2V0KCQpLEouYnVmZmVyfWZ1bmN0aW9uIHZRKCQpe2lmKCQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCkuc2xpY2UoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCkuc2xpY2UoKX1mdW5jdGlvbiBiMCgkKXtpZigkPy5ycElkIT09dm9pZCAwKXJldHVybiBPKCQucnBJZCk7aWYodHlwZW9mIGxvY2F0aW9uPiJ1IilyZXR1cm4gRyg5KTtyZXR1cm4gTyhfVihsb2NhdGlvbi5ob3N0bmFtZSkpfXZhciBTUT0iIjtmdW5jdGlvbiBoMCgkKXtpZigkIGluc3RhbmNlb2YgRXJyb3Ipe1NRPSQubWVzc2FnZT09PSIiPyQubmFtZTpgJHskLm5hbWV9OiAkeyQubWVzc2FnZX1gO3JldHVybn1TUT1TdHJpbmcoJCl9ZnVuY3Rpb24gaTAoKXtpZih0eXBlb2YgbmF2aWdhdG9yPiJ1Inx8IW5hdmlnYXRvci5jcmVkZW50aWFsc3x8dHlwZW9mIFB1YmxpY0tleUNyZWRlbnRpYWw+InUiKXJldHVybiAyNDtyZXR1cm4gMH1mdW5jdGlvbiBsMCgkKXtpZigkPT09bnVsbHx8JC50eXBlIT09InB1YmxpYy1rZXkifHwhKCJyYXdJZCJpbiAkKXx8dHlwZW9mICQuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cyE9PSJmdW5jdGlvbiIpcmV0dXJuIEcoMjcpO3JldHVybiBPKCQpfWFzeW5jIGZ1bmN0aW9uIGJRKCQpe2xldCBKPWkwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09YjAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtc2VlZCIsVj17cmVzaWRlbnRLZXk6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6ITAsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQifTtpZigkPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClWLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PSQuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IFg9e2xhcmdlQmxvYjp7c3VwcG9ydDoicmVxdWlyZWQifX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpEMCh5MCkscnA6e2lkOlosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6RDAoMTYpLG5hbWU6WSxkaXNwbGF5TmFtZTpZfSxwdWJLZXlDcmVkUGFyYW1zOmUkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246VixleHRlbnNpb25zOlgsLi4uJD8uaGludHMhPT12b2lkIDA/e2hpbnRzOiQuaGludHN9Ont9fX0pfWNhdGNoKE4pe3JldHVybiBoMChOKSxHKDMwKX1sZXRbeixLXT1sMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LnN1cHBvcnRlZCE9PSEwKXJldHVybiBHKDMwKTtyZXR1cm4gTyhuZXcgVWludDhBcnJheSh6LnJhd0lkKSl9YXN5bmMgZnVuY3Rpb24gSlooJCxKLFope2xldCBRPWkwKCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0W1ksVl09YjAoWik7aWYoViE9PTApcmV0dXJuIFY7aWYoWT09PXZvaWQgMClyZXR1cm4gOTtsZXQgWD17bGFyZ2VCbG9iOnt3cml0ZTpCMChKKX19LFc7dHJ5e1c9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OntjaGFsbGVuZ2U6RDAoeTApLHJwSWQ6WSxhbGxvd0NyZWRlbnRpYWxzOlt7dHlwZToicHVibGljLWtleSIsaWQ6QjAoJCl9XSx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpYLC4uLlo/LmhpbnRzIT09dm9pZCAwP3toaW50czpaLmhpbnRzfTp7fX19KX1jYXRjaChOKXtyZXR1cm4gaDAoTiksMzB9bGV0W3osS109bDAoVyk7aWYoSyE9PTApcmV0dXJuIEs7aWYoej09PXZvaWQgMClyZXR1cm4gMjc7aWYoei5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iPy53cml0dGVuIT09ITApcmV0dXJuIDMwO3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIHlRKCQsSixaLFEpe2xldCBZPXtjaGFsbGVuZ2U6RDAoeTApLHJwSWQ6JCx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCJ9O2lmKEo/LmhpbnRzIT09dm9pZCAwKVkuaGludHM9Si5oaW50cztpZihaIT09dm9pZCAwKVkuYWxsb3dDcmVkZW50aWFscz1be3R5cGU6InB1YmxpYy1rZXkiLGlkOkIwKFopfV07aWYoUSE9PXZvaWQgMClZLmV4dGVuc2lvbnM9UTtsZXQgVjt0cnl7Vj1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6WX0pfWNhdGNoKHope3JldHVybiBoMCh6KSxHKDMwKX1sZXRbWCxXXT1sMChWKTtpZihXIT09MClyZXR1cm4gRyhXKTtpZihYPT09dm9pZCAwKXJldHVybiBHKDI3KTtyZXR1cm4gTyhYKX1hc3luYyBmdW5jdGlvbiBoUSgkLEope2xldCBaPWkwKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09YjAoSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kO2lmKFY9PT12b2lkIDApe2xldFtOLFVdPWF3YWl0IHlRKFEsSik7aWYoVSE9PTApcmV0dXJuIEcoVSk7aWYoTj09PXZvaWQgMClyZXR1cm4gRygyNyk7Vj1uZXcgVWludDhBcnJheShOLnJhd0lkKX1sZXRbWCxXXT1hd2FpdCB5UShRLEosVix7bGFyZ2VCbG9iOntyZWFkOiEwfX0pO2lmKFchPT0wKXJldHVybiBHKFcpO2lmKFg9PT12b2lkIDApcmV0dXJuIEcoMjcpO2xldCBLPVguZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYjtpZihLPT09dm9pZCAwfHxLLmJsb2I9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IEY9dlEoSy5ibG9iKTtpZihGLmJ5dGVMZW5ndGg9PT0wKXJldHVybiBHKDcpO3JldHVybiBPKHtibG9iOkYsY3JlZElkOm5ldyBVaW50OEFycmF5KFgucmF3SWQpfSl9dmFyIFFaPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5wcmYudjEiKSxaWj0zMjthc3luYyBmdW5jdGlvbiBpUSgkKXtsZXQgSj1pMCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtaLFFdPWIwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFk9JD8udXNlck5hbWU/PyJkaXBsb21hdGljLXByZiIsVj17cmVzaWRlbnRLZXk6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6ITAsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQifTtpZigkPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClWLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PSQuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IFg9JD8uc2FsdCE9PXZvaWQgMD9CMCgkLnNhbHQpOnZvaWQgMCxXPVg9PT12b2lkIDA/e306e2V2YWw6e2ZpcnN0Olh9fSx6O3RyeXt6PWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5jcmVhdGUoe3B1YmxpY0tleTp7Y2hhbGxlbmdlOkQwKHkwKSxycDp7aWQ6WixuYW1lOiQ/LnJwTmFtZT8/IkRJUExPTUFUSUMifSx1c2VyOntpZDpEMCgxNiksbmFtZTpZLGRpc3BsYXlOYW1lOll9LHB1YktleUNyZWRQYXJhbXM6ZSQsYXV0aGVudGljYXRvclNlbGVjdGlvbjpWLGV4dGVuc2lvbnM6e3ByZjpXfSwuLi4kPy5oaW50cyE9PXZvaWQgMD97aGludHM6JC5oaW50c306e319fSl9Y2F0Y2goVSl7cmV0dXJuIGgwKFUpLEcoMzApfWxldFtLLEZdPWwwKHopO2lmKEYhPT0wKXJldHVybiBHKEYpO2lmKEs9PT12b2lkIDApcmV0dXJuIEcoMjcpO2xldCBOPUsuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpO3JldHVybiBPKHtjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoSy5yYXdJZCkscHJmRW5hYmxlZDpOLnByZj8uZW5hYmxlZD09PSEwfSl9YXN5bmMgZnVuY3Rpb24gWVooJCl7bGV0IEo9aTAoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbWixRXT1iMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBZPSQ/LnNhbHQ/P1FaLFY9QjAoWSksWD17Y2hhbGxlbmdlOkQwKHkwKSxycElkOlosdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQiLGV4dGVuc2lvbnM6e3ByZjp7ZXZhbDp7Zmlyc3Q6Vn19fX07aWYoJD8uaGludHMhPT12b2lkIDApWC5oaW50cz0kLmhpbnRzO2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClYLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpCMCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6WH0pfWNhdGNoKEgpe3JldHVybiBoMChIKSxHKDMwKX1sZXRbeixLXT1sMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxVPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxSPVUuYnl0ZUxlbmd0aD49Wlo/VS5zbGljZSgwLFpaKTpVO2lmKFIuYnl0ZUxlbmd0aCE9PVpaKXJldHVybiBHKDI3KTtyZXR1cm4gTyh7cHJmOlIsY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyICRKPSIiO3ZhciBaSj10eXBlb2YgZ2xvYmFsVGhpcy5Xb3JrZXI9PT0iZnVuY3Rpb24iP2dsb2JhbFRoaXMuV29ya2VyOnZvaWQgMCxWWj1aSj09PXZvaWQgMD92b2lkIDA6WkoucHJvdG90eXBlLnBvc3RNZXNzYWdlLEpKO2Z1bmN0aW9uIHhWKCl7aWYodHlwZW9mICRKIT09InN0cmluZyJ8fCRKLmxlbmd0aD09PTApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSB3b3JrZXIgc291cmNlIG5vdCBlbWJlZGRlZDsgcnVuIHBrZyBidWlsZCBiZWZvcmUgc3Bhd24iKTtyZXR1cm4gYXRvYigkSil9ZnVuY3Rpb24gQlYoKXtpZihKSiE9PXZvaWQgMClyZXR1cm4gSko7bGV0ICQ9bmV3IEJsb2IoW3hWKCldLHt0eXBlOiJ0ZXh0L2phdmFzY3JpcHQifSk7cmV0dXJuIEpKPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksSkp9ZnVuY3Rpb24gbFEoKXtpZihaSj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBzcGF3biBzeW5jIHdvcmtlciIpO3JldHVybiBuZXcgWkooQlYoKSx7dHlwZToibW9kdWxlIn0pfWZ1bmN0aW9uIHVRKCQsSixaKXtpZihWWj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBwb3N0IHRvIHN5bmMgd29ya2VyIik7aWYoWiE9PXZvaWQgMCYmWi5sZW5ndGg+MClWWi5jYWxsKCQsSix7dHJhbnNmZXI6Wn0pO2Vsc2UgVlouY2FsbCgkLEopfXZhciBrVj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMud3JhcC52MSIpLEVWPTMyLGZWPTE2LHowPW5ldyBTMDtjbGFzcyBXMHsjJDtjb25zdHJ1Y3RvcigkKXt0aGlzLiMkPSR9c3RhdGljIGFzeW5jIGZyb21SYW5kb20oKXtsZXQgJD1hd2FpdCB6MC5nZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCksW0osWl09JDAoJCk7aWYoWiE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7Wn0pYCk7cmV0dXJuIG5ldyBXMChKKX1zdGF0aWMgZnJvbUJ5dGVzKCQpe2xldFtKLFpdPSQwKCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtRLFldPSQwKEouc2xpY2UoKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE8obmV3IFcwKFEpKX1hc3luYyBzZWFsV2l0aFBhc3NrZXkoJCl7bGV0IEo9JD8uc2FsdD8/UVosWj0kPy5jcmVkSWQ7aWYoWj09PXZvaWQgMCYmJD8uY3JlYXRlQ3JlZElmTmVlZGVkPT09ITApe2xldFtWLFhdPWF3YWl0IGlRKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSx1c2VyTmFtZTokPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtcHJmIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCxoaW50czokPy5oaW50cyxzYWx0Okp9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDMwKTtpZighVi5wcmZFbmFibGVkKXJldHVybiBHKDMwKTtaPVYuY3JlZElkfWxldFtRLFldPWF3YWl0IFlaKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6WixzYWx0OkosaGludHM6JD8uaGludHN9KTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbVixYXT1hd2FpdCB0aGlzLiNRKFEucHJmKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7c2VhbGVkTWFzdGVyOlYsc2FsdDpKLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyB1bnNlYWxXaXRoUGFzc2tleSgkLEope2xldFtaLFFdPWF3YWl0IFlaKHtycElkOkoucnBJZCxycE5hbWU6Si5ycE5hbWUsaGludHM6Si5oaW50cyxjcmVkSWQ6Si5jcmVkSWQsc2FsdDpKLnNhbHR9KTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxWXT1hd2FpdCBXMC4jWigkLFoucHJmKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7ZW5jbGF2ZTpZLGNyZWRJZDpaLmNyZWRJZC5zbGljZSgpfSl9ZmluYWxseXtaLnByZi5maWxsKDApfX1hc3luYyBwZXJzaXN0VG9MYXJnZUJsb2IoJD1bXSxKKXtsZXQgWj1KPy5jcmVkSWQ7aWYoWj09PXZvaWQgMCl7bGV0W1YsWF09YXdhaXQgYlEoSik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygzMCk7Wj1WfWxldFtRLFldPXRoaXMuI1koJCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBWPWF3YWl0IEpaKFosUSxKKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gTyhaKX1maW5hbGx5e1EuZmlsbCgwKX19c3RhdGljIGFzeW5jIGZyb21MYXJnZUJsb2IoJCl7bGV0W0osWl09YXdhaXQgaFEoJD8uY3JlZElkLCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e3JldHVybiBXMC4jVihKLmJsb2IsSi5jcmVkSWQpfWZpbmFsbHl7Si5ibG9iLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBjbGVhckxhcmdlQmxvYigkLEope3JldHVybiBKWigkLG5ldyBVaW50OEFycmF5KEgwKSxKKX1zdGF0aWMgcGFpclJlcXVlc3QoKXtyZXR1cm4gdCQuY3JlYXRlKCl9YXN5bmMgcGFpckFjY2VwdCgkLEope2xldCBaO3RyeXtaPWF3YWl0IHowLmdlblgyNTUxOSgpfWNhdGNoe3JldHVybiBHKDI5KX10cnl7bGV0W1EsWV09YXdhaXQgJFooWi5wcml2LCQsJCxaLnB1Yik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldFtWLFhdPXRoaXMuI0ooSik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBXPWF3YWl0IHowLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoVixRKTtyZXR1cm4gbVEoUjAoWi5wdWIsVykpfWNhdGNoe3JldHVybiBHKDEyKX1maW5hbGx5e1YuZmlsbCgwKX19ZmluYWxseXtRLmZpbGwoMCl9fWZpbmFsbHl7Wi5wcml2LmZpbGwoMCl9fSNKKCQpe2xldCBKPXRoaXMuIyQuc2xpY2UoKSxbWixRXT0kMChKKTtpZihRIT09MClyZXR1cm4gSi5maWxsKDApLEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gSi5maWxsKDApLEcoMTApO3RyeXtsZXQgWT17bWFzdGVyU2VlZDpaLGhvc3RzOiQubWFwKChYKT0+KHtoYW5kbGU6WC5oYW5kbGUsbGFiZWw6WC5sYWJlbCxpZHg6WC5pZHg/PzB9KSl9LFY9bmV3IFM7dHJ5e2xldCBYPVYud3JpdGVTdHJ1Y3QoYSQsWSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIE8oVi5yZXN1bHQoKSl9ZmluYWxseXtWLndpcGUoKX19ZmluYWxseXtaLmZpbGwoMCl9fXNwYXduU3luY1dvcmtlcigkKXtsZXQgSj1sUSgpLFo9dGhpcy4jJC5zbGljZSgpO3JldHVybiB1UShKLHtpZDokLmlkLG9wOiJzZXRTZWVkIixzZWVkOloscGVyc2lzdDokLnBlcnNpc3R9LFtaLmJ1ZmZlcl0pLEp9ZGVyaXZlQ2lwaGVyKCQsSil7bGV0IFo9JC5zbGljZSgpLFE9KFgpPT50aGlzLiNHKFosWCksWT0oWCk9PnRoaXMuI3ooWixYKTtyZXR1cm57ZW5jcnlwdDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlF9KSxkZWNyeXB0Ok9iamVjdC5mcmVlemUoe2RlY3J5cHQ6WX0pLGJvdGg6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRLGRlY3J5cHQ6WX0pfVtKXX1hc3luYyBkZXJpdmVJZGVudGl0eSgkLEo9MCl7bGV0IFo9JCxRPUosWT1hd2FpdCB0aGlzLiNXKFosUSksVj1ZLnB1YmxpY0tleTtyZXR1cm4gWS5wcml2YXRlS2V5LmZpbGwoMCksT2JqZWN0LmZyZWV6ZSh7cHVibGljS2V5OlYsc2lnbjooWCk9PnRoaXMuI0YoWixRLFgpLGtkbUZvcjooWCk9PnRoaXMuI04oWixRLFgpfSl9YXN5bmMjUSgkKXtsZXRbSixaXT1hd2FpdCBwUSh6MCwkKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFE9YXdhaXQgejAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0aGlzLiMkLEopO3JldHVybiB4MChRKX1jYXRjaHtyZXR1cm4gRygxMil9ZmluYWxseXtKLmZpbGwoMCl9fXN0YXRpYyBhc3luYyNaKCQsSil7bGV0WyxaXT14MCgkKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT1hd2FpdCBwUSh6MCxKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgVjt0cnl7dHJ5e1Y9YXdhaXQgejAuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLFEpfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gVzAuZnJvbUJ5dGVzKFYpfWZpbmFsbHl7US5maWxsKDApLFY/LmZpbGwoMCl9fSNZKCQpe2xldCBKPXRoaXMuIyQuc2xpY2UoKSxbWixRXT0kMChKKTtpZihRIT09MClyZXR1cm4gSi5maWxsKDApLEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gSi5maWxsKDApLEcoMTApO3RyeXtsZXRbWSxWXT1mUShaLCQpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTIpO3RyeXtsZXQgWD1uZXcgUyxXPVgud3JpdGVTdHJ1Y3QoZUosWSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7cmV0dXJuIE8oWC5yZXN1bHQoKSl9ZmluYWxseXtZLm1hc3RlclNlZWQuZmlsbCgwKX19ZmluYWxseXtaLmZpbGwoMCl9fXN0YXRpYyNWKCQsSil7aWYoJC5ieXRlTGVuZ3RoPT09MHx8JC5ldmVyeSgoVik9PlY9PT0wKSlyZXR1cm4gRygyMik7aWYoJC5ieXRlTGVuZ3RoPT09SDApe2lmKCQuZXZlcnkoKFcpPT5XPT09MCkpcmV0dXJuIEcoMjIpO2xldFtWLFhdPVcwLmZyb21CeXRlcygkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7ZW5jbGF2ZTpWLGhvc3RzOltdLGNyZWRJZDpKfSl9bGV0IFo9bmV3IG0oJCksW1EsWV09Wi5yZWFkU3RydWN0KGVKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTt0cnl7aWYoUS5tYXN0ZXJTZWVkLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDIyKTtsZXRbVixYXT1XMC5mcm9tQnl0ZXMoUS5tYXN0ZXJTZWVkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7ZW5jbGF2ZTpWLGhvc3RzOlEuaG9zdHMubWFwKChXKT0+KHsuLi5XfSkpLGNyZWRJZDpKfSl9ZmluYWxseXtRLm1hc3RlclNlZWQuZmlsbCgwKX19YXN5bmMjRygkLEope2xldCBaPWF3YWl0IHRoaXMuI1goJCk7dHJ5e3JldHVybiBhd2FpdCB6MC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKEosWil9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI3ooJCxKKXtsZXQgWj1hd2FpdCB0aGlzLiNYKCQpO3RyeXtyZXR1cm4gYXdhaXQgejAuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChKLFopfWZpbmFsbHl7Wi5maWxsKDApfX1hc3luYyNYKCQpe3JldHVybiB6MC5ibGFrZTMoUjAodGhpcy4jJCwkKSl9YXN5bmMjSygkLEope2xldCBaPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxRPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcoUS5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludChKKSwhMSksYXdhaXQgdGhpcy4jWChSMChaLFEpKX1hc3luYyNXKCQsSil7bGV0IFo9YXdhaXQgdGhpcy4jSygkLEopO3RyeXtyZXR1cm4gYXdhaXQgejAuZGVyaXZlRWQyNTUxOUtleVBhaXIoWil9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI0YoJCxKLFope2xldCBRPWF3YWl0IHRoaXMuI1coJCxKKTt0cnl7cmV0dXJuIGF3YWl0IHowLnNpZ25FZDI1NTE5KFosUS5wcml2YXRlS2V5KX1maW5hbGx5e1EucHJpdmF0ZUtleS5maWxsKDApfX1hc3luYyNOKCQsSixaKXtsZXQgUT1hd2FpdCB0aGlzLiNXKCQsSiksWT1SMChRLnByaXZhdGVLZXksWik7US5wcml2YXRlS2V5LmZpbGwoMCk7dHJ5e3JldHVybihhd2FpdCB6MC5ibGFrZTMoWSkpLnNsaWNlKDAsXzApfWZpbmFsbHl7WS5maWxsKDApfX19YXN5bmMgZnVuY3Rpb24gcFEoJCxKLFo9a1Ype2lmKEouYnl0ZUxlbmd0aDxmVilyZXR1cm4gRygxMCk7bGV0IFE9YXdhaXQgJC5ibGFrZTMoUjAoSixaKSk7cmV0dXJuIE8oUS5zbGljZSgwLEVWKSl9Y2xhc3MgWFp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkKXtsZXQgSj1bLi4uJF07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtmb3IobGV0IFggb2YgSil7bGV0IFc9YCR7WC5ob3N0fToke1guc2VxfWA7US5wdXQoWCxXKX19KX1hc3luYyBkZXEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxZPVEub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1Eub25jb21wbGV0ZT0oKT0+VigpLFEub25lcnJvcj0oKT0+WChRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9YCR7JH06JHtXfWA7WS5kZWxldGUoeil9fSl9YXN5bmMgbGlzdCgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0QWxsKCk7WS5vbnN1Y2Nlc3M9KCk9PlooWS5yZXN1bHQpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5jb3VudCgpO1kub25zdWNjZXNzPSgpPT5aKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fWZ1bmN0aW9uIGNRKCQpe3JldHVybntsYWJlbDokLmxhYmVsLGhhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxpZHg6JC5pZHgsbGFzdFNlcTokLmxhc3RTZXF8fDAsY2xvY2tPZmZzZXQ6JC5jbG9ja09mZnNldCxzdWJzY3JpcHRpb246JC5zdWJzY3JpcHRpb259fWZ1bmN0aW9uIGdWKCQsSil7bGV0IFo9ey4uLiR9O2lmKEouc2V0TGFzdFNlcSE9PXZvaWQgMClaLmxhc3RTZXE9Si5zZXRMYXN0U2VxO2Vsc2UgaWYoSi5sYXN0U2VxIT09dm9pZCAwKXtsZXQgUT1aLmxhc3RTZXF8fDA7aWYoSi5sYXN0U2VxPlEpWi5sYXN0U2VxPUoubGFzdFNlcX1yZXR1cm4gZGVsZXRlIFoubnVtQmFncyxkZWxldGUgWi5udW1EdXBlcyxafWNsYXNzIFdae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IEo9YXdhaXQgdGhpcy5nZXQoJC5sYWJlbCksWj1KIT09dm9pZCAwJiZKLmhhbmRsZS5ocmVmPT09JC5oYW5kbGUuaHJlZiYmKEouaWR4Pz8wKT09PSgkLmlkeD8/MCk7cmV0dXJuIHRoaXMucHV0KHsuLi4kLGxhc3RTZXE6Wj9KLmxhc3RTZXE6MCxjbG9ja09mZnNldDpaP0ouY2xvY2tPZmZzZXQ6dm9pZCAwLHN1YnNjcmlwdGlvbjpaP0ouc3Vic2NyaXB0aW9uOnZvaWQgMH0pfWFzeW5jIHB1dCgkKXtsZXQgSj17Li4uJCxoYW5kbGU6JC5oYW5kbGUudG9TdHJpbmcoKSxsYXN0U2VxOiQubGFzdFNlcT8/MH0sWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKSxRLnB1dChKKX0pfWFzeW5jIHRvdWNoKCQsSil7cmV0dXJuIHRoaXMucmVjb3JkU3RhdHMoJCx7bGFzdFNlcTpKfSl9YXN5bmMgcmVjb3JkU3RhdHMoJCxKKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtsZXQgWD1RLmdldCgkKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKCFXKXJldHVybjtRLnB1dChnVihXLEopKX19KX1hc3luYyBnZXQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFY9Wi5nZXQoJCk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgWD1WLnJlc3VsdDtpZighWClRKHZvaWQgMCk7ZWxzZSBRKGNRKFgpKX0sVi5vbmVycm9yPSgpPT5ZKFYuZXJyb3IpfSl9YXN5bmMgc2V0KCQsSil7bGV0IFo9YXdhaXQgdGhpcy5nZXQoJCk7aWYoIVopcmV0dXJuIDEzO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy5wdXQoey4uLlosLi4uSn0pLDB9Y2F0Y2h7cmV0dXJuIDE4fX1hc3luYyBkZWwoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntKLm9uY29tcGxldGU9KCk9PlEoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksWi5kZWxldGUoJCl9KX1hc3luYyBsaXN0KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5nZXRBbGwoKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBWPVkucmVzdWx0O1ooVi5tYXAoY1EpKX0sWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouY2xlYXIoKX0pfX1jbGFzcyBHWntjcnlwdG87ZGI7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmNyeXB0bz1KO3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e2lmKCQubGVuZ3RoPT09MCl7UShbXSk7cmV0dXJufWxldCBZPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO0oub25jb21wbGV0ZT0oKT0+UShZKSxKLm9uZXJyb3I9KCk9Pntmb3IobGV0IFY9MDtWPFkubGVuZ3RoO1YrKylZW1ZdPTE4O1EoWSl9O2ZvcihsZXQgVj0wO1Y8JC5sZW5ndGg7VisrKXtsZXR7a2V5OlgsZGF0YTpXfT0kW1ZdLHo9QihYKSxLPVoucHV0KFcseik7Sy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKSxZW1ZdPTE4fX19KX1hc3luYyBkZWwoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2ZvcihsZXQgWCBvZiBKKXtsZXQgVz1CKFgpO1EuZGVsZXRlKFcpfX0pfWFzeW5jIGdldCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFY9QigkKSxYPVouZ2V0KFYpO1gub25zdWNjZXNzPWFzeW5jKCk9PntsZXQgVz1YLnJlc3VsdDtpZihXKVEoYXdhaXQgaCQoJCxXLHRoaXMuY3J5cHRvKSk7ZWxzZSBRKHZvaWQgMCl9LFgub25lcnJvcj0oKT0+WShYLmVycm9yKX0pfWFzeW5jIGhhcygkKXtyZXR1cm4gYXdhaXQgdGhpcy5nZXQoJCkhPT12b2lkIDB9YXN5bmMgbGlzdCgkKXtsZXQgSj0kPy5hcGxkLFo9JD8uYm9keSE9PSExLFk9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e2xldCBXPVtdLHo9Sj09PXZvaWQgMD9ZLm9wZW5DdXJzb3IoKTpZLmluZGV4KEMkKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoSikpO3oub25zdWNjZXNzPShLKT0+e2xldCBGPUsudGFyZ2V0LnJlc3VsdDtpZihGKXtsZXQgTj1KPT09dm9pZCAwP0Yua2V5OkYucHJpbWFyeUtleSxVPUYudmFsdWU7Vy5wdXNoKHtoYXNoOk4wKE4pLGRhdGE6VX0pLEYuY29udGludWUoKX1lbHNlIFByb21pc2UuYWxsKFcubWFwKCh7aGFzaDpOLGRhdGE6VX0pPT5oJChOLFUsdGhpcy5jcnlwdG8se2JvZHk6Wn0pKSkudGhlbihWKS5jYXRjaChYKX0sei5vbmVycm9yPSgpPT5YKHouZXJyb3IpfSl9YXN5bmMgY291bnQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWPSQ9PT12b2lkIDA/Wi5jb3VudCgpOlouaW5kZXgoQyQpLmNvdW50KElEQktleVJhbmdlLm9ubHkoJCkpO1Yub25zdWNjZXNzPSgpPT5RKFYucmVzdWx0KSxWLm9uZXJyb3I9KCk9PlkoVi5lcnJvcil9KX1hc3luYyBsaXN0S2V5cygpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1bXSxWPUoub3BlbktleUN1cnNvcigpO1Yub25zdWNjZXNzPShYKT0+e2xldCBXPVgudGFyZ2V0LnJlc3VsdDtpZihXKVkucHVzaChOMChXLmtleSkpLFcuY29udGludWUoKTtlbHNlIFooWSl9LFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfWFzeW5jIGxhc3QoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWLFg9Wi5vcGVuQ3Vyc29yKCk7WC5vbnN1Y2Nlc3M9YXN5bmMoVyk9PntsZXQgej1XLnRhcmdldC5yZXN1bHQ7aWYoeil7bGV0e2tleTpLLHZhbHVlOkZ9PXo7aWYocigkLEYuZWlkKSl7aWYoIVZ8fChGLmN0cj8/MCk+KFYuZGF0YS5jdHI/PzApfHwoRi5jdHI/PzApPT09KFYuZGF0YS5jdHI/PzApJiYoRi5vZmY/PzApPihWLmRhdGEub2ZmPz8wKSlWPXtrZXk6SyxkYXRhOkZ9fXouY29udGludWUoKX1lbHNlIGlmKFYpe2xldCBLPU4wKFYua2V5KTtRKGF3YWl0IGgkKEssVi5kYXRhLHRoaXMuY3J5cHRvKSl9ZWxzZSBRKHZvaWQgMCl9LFgub25lcnJvcj0oKT0+WShYLmVycm9yKX0pfWFzeW5jIG1hcmtBcHBsaWVkKCQpe2xldCBKPVsuLi4kXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtmb3IobGV0IFggb2YgSil7bGV0IFc9QihYKSx6PVEuZ2V0KFcpO3oub25zdWNjZXNzPSgpPT57bGV0IEs9ei5yZXN1bHQ7aWYoIUspcmV0dXJuO2tKKEssYiQpLFEucHV0KEssVyl9LHoub25lcnJvcj0oSyk9PntLLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIG1hcmtGYWlsZWQoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2ZvcihsZXR7a2V5OlgsZXJyOld9b2YgSil7bGV0IHo9QihYKSxLPVEuZ2V0KHopO0sub25zdWNjZXNzPSgpPT57bGV0IEY9Sy5yZXN1bHQ7aWYoIUYpcmV0dXJuO2tKKEYsUSQsVyksUS5wdXQoRix6KX0sSy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKX19fSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19Y2xhc3Mgelp7IyQ7I0o7I1E7I1o7Y29uc3RydWN0b3IoJCl7aWYodGhpcy4jWj0kLnBlcnNpc3RNZXRhLHRoaXMuI1E9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5tZXRhIT09dm9pZCAwKXRoaXMuI0o9dTAoJC5tZXRhKX1nZXQgbWV0YSgpe3JldHVybiB0aGlzLiNKPT09dm9pZCAwP3ZvaWQgMDp1MCh0aGlzLiNKKX1zZXRNZXRhKCQpe3RoaXMuI0o9JD09PXZvaWQgMD92b2lkIDA6dTAoJCl9YXN5bmMgc2F2ZSgkLEope2lmKEo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIHdyYXBBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3Qgc2VhbGVkIG1hc3RlciIpKTtyZXR1cm4gdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgd3JhcEFuZFNhdmUoJCxKKXtsZXRbWixRXT1hd2FpdCAkLnNlYWxXaXRoUGFzc2tleSh7Li4udGhpcy4jUSxzYWx0Oko/LnNhbHQsY3JlZElkOko/LmNyZWRJZD8/dGhpcy4jSj8uY3JlZElkLGNyZWF0ZUNyZWRJZk5lZWRlZDpKPy5jcmVhdGVDcmVkSWZOZWVkZWQ/P0o/LmNyZWRJZD09PXZvaWQgMCx1c2VyTmFtZToiZGlwbG9tYXRpYy1wcmYiLGF1dGhlbnRpY2F0b3JBdHRhY2htZW50Oko/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50LGhpbnRzOko/LmhpbnRzfSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFk9e3NlYWxlZE1hc3RlcjpaLnNlYWxlZE1hc3RlcixzYWx0Olouc2FsdCxjcmVkSWQ6Wi5jcmVkSWR9O3JldHVybiB0aGlzLiNKPVksdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1oodTAoWSkpLE8odGhpcy4jJCl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIHVubG9jaygpe2xldCAkPXRoaXMuI0o7aWYoJD09PXZvaWQgMClyZXR1cm4gRygyMik7bGV0W0osWl09YXdhaXQgVzAudW5zZWFsV2l0aFBhc3NrZXkoJC5zZWFsZWRNYXN0ZXIsey4uLnRoaXMuI1Esc2FsdDokLnNhbHQsY3JlZElkOiQuY3JlZElkfSk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYodGhpcy4jJD1KLmVuY2xhdmUsSi5jcmVkSWQuYnl0ZUxlbmd0aD4wJiYoJC5jcmVkSWQ9PT12b2lkIDB8fCFyKCQuY3JlZElkLEouY3JlZElkKSkpe2xldCBRPXtzZWFsZWRNYXN0ZXI6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQsY3JlZElkOkouY3JlZElkLnNsaWNlKCl9O3RoaXMuI0o9USxhd2FpdCB0aGlzLiNaKHUwKFEpKX1yZXR1cm4gTyhKLmVuY2xhdmUpfWFzeW5jIGFkb3B0U2VhbGVkKCQsSil7cmV0dXJuIHRoaXMuI0o9dTAoSiksdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1oodTAoSikpLE8odGhpcy4jJCl9YXN5bmMgd2lwZSgpe3RoaXMuIyQ9dm9pZCAwLHRoaXMuI0o9dm9pZCAwLGF3YWl0IHRoaXMuI1oodm9pZCAwKX19ZnVuY3Rpb24gdTAoJCl7bGV0W0osWl09eDAoJC5zZWFsZWRNYXN0ZXIuc2xpY2UoKSk7cmV0dXJue3NlYWxlZE1hc3RlcjpaPT09MCYmSiE9PXZvaWQgMD9KOiQuc2VhbGVkTWFzdGVyLHNhbHQ6JC5zYWx0LnNsaWNlKCksY3JlZElkOiQuY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfX12YXIgbVY9ImRpcGxvbWF0aWMucGluLyI7ZnVuY3Rpb24gU1YoJCl7cmV0dXJuIG1WK1UwKCQpfWFzeW5jIGZ1bmN0aW9uIG5RKCQsSixaKXtsZXQgUT1hd2FpdCBKLmRlcml2ZUlkZW50aXR5KFNWKFopLDApO3JldHVybiAkLmJsYWtlMyhRLnB1YmxpY0tleSl9YXN5bmMgZnVuY3Rpb24gZFEoJCxKKXtsZXQgWj1hd2FpdCAkLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxRPWF3YWl0IG5RKCQsSixaKTtyZXR1cm57bjpaLGg6UX19YXN5bmMgZnVuY3Rpb24gclEoJCxKLFope2xldCBRPWF3YWl0IG5RKCQsSixaLm4pO3JldHVybiB2VihRLFouaCl9ZnVuY3Rpb24gb1EoJCl7aWYoJD09PXZvaWQgMHx8JD09PW51bGx8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuO2xldCBKPSQ7aWYoIShKLm4gaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShKLmggaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47aWYoSi5uLmJ5dGVMZW5ndGg8MXx8Si5oLmJ5dGVMZW5ndGg8MSlyZXR1cm47cmV0dXJue246Si5uLnNsaWNlKCksaDpKLmguc2xpY2UoKX19ZnVuY3Rpb24gYVEoJCl7cmV0dXJue246JC5uLnNsaWNlKCksaDokLmguc2xpY2UoKX19ZnVuY3Rpb24gdlYoJCxKKXtpZigkLmJ5dGVMZW5ndGghPT1KLmJ5dGVMZW5ndGgpcmV0dXJuITE7bGV0IFo9MDtmb3IobGV0IFE9MDtRPCQuYnl0ZUxlbmd0aDtRKyspWnw9JFtRXV5KW1FdO3JldHVybiBaPT09MH12YXIgUUo9InByZk1ldGEiLEtaPSJpZFBpbiIsc1E9ImlkUHViIjtjbGFzcyBGWnsjJDtkYjsjSjtjb25zdHJ1Y3RvcigkLEope3RoaXMuZGI9JCx0aGlzLiNKPUp9YXN5bmMgc2F2ZSgkLEope3JldHVybiBhd2FpdCB0aGlzLiNRKCQpLHRoaXMuIyQ9JCx0aGlzLiMkfWFzeW5jIGxvYWQoKXtyZXR1cm4gdGhpcy4jJH1hc3luYyBjbGVhclNlc3Npb24oKXt0aGlzLiMkPXZvaWQgMH1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDA7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5kZWxldGUoUUopLEouZGVsZXRlKEtaKSxKLmRlbGV0ZShzUSl9KX1hc3luYyBsb2FkUHJmTWV0YSgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0KFFKKTtZLm9uc3VjY2Vzcz0oKT0+e1ooeVYoWS5yZXN1bHQpKX0sWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgcGVyc2lzdFByZk1ldGEoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntpZihKLm9uY29tcGxldGU9KCk9PlEoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksJD09PXZvaWQgMCl7Wi5kZWxldGUoUUopO3JldHVybn1sZXQgVj17c2VhbGVkTWFzdGVyOiQuc2VhbGVkTWFzdGVyLnNsaWNlKCksc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9O1oucHV0KFYsUUopfSl9YXN5bmMgaGFzUHJmTWV0YSgpe3JldHVybiBhd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCkhPT12b2lkIDB9YXN5bmMgbGFzdFByZkNyZWRJZCgpe2xldCAkPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gJD8uY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfWFzeW5jIG9wZW5QcmZTdG9yZSgkKXtsZXQgSj1hd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCk7cmV0dXJuIG5ldyB6Wih7cnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lLG1ldGE6SixwZXJzaXN0TWV0YTooWik9PnRoaXMucGVyc2lzdFByZk1ldGEoWil9KX1hc3luYyNRKCQpe2F3YWl0IHRoaXMuI1Yoc1EpO2xldCBKPWF3YWl0IHRoaXMuI1ooKTtpZihKIT09dm9pZCAwKXtpZighYXdhaXQgclEodGhpcy4jSiwkLEopKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gc2VlZCBkb2VzIG5vdCBtYXRjaCB0aGlzIGRldmljZSdzIGlkZW50aXR5IChsb2NhbCBkYXRhIHdhcyBjcmVhdGVkIHdpdGggYSBkaWZmZXJlbnQgbWFzdGVyIHNlZWQpIik7cmV0dXJufWxldCBaPWF3YWl0IGRRKHRoaXMuI0osJCk7YXdhaXQgdGhpcy4jWShaKX0jWigpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0KEtaKTtZLm9uc3VjY2Vzcz0oKT0+WihvUShZLnJlc3VsdCkpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfSNZKCQpe2xldCBKPWFRKCQpLFo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksUS5wdXQoSixLWil9KX0jVigkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e0oub25jb21wbGV0ZT0oKT0+USgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSxaLmRlbGV0ZSgkKX0pfX1mdW5jdGlvbiB5VigkKXtpZigkPT09dm9pZCAwfHwkPT09bnVsbHx8dHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm47bGV0IEo9JDtpZighKEouc2VhbGVkTWFzdGVyIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCEoSi5zYWx0IGluc3RhbmNlb2YgVWludDhBcnJheSkpcmV0dXJuO2xldFtaLFFdPXgwKEouc2VhbGVkTWFzdGVyKTtpZihRIT09MHx8Wj09PXZvaWQgMClyZXR1cm47cmV0dXJue3NlYWxlZE1hc3RlcjpaLHNhbHQ6Si5zYWx0LnNsaWNlKCksY3JlZElkOkouY3JlZElkIGluc3RhbmNlb2YgVWludDhBcnJheT9KLmNyZWRJZC5zbGljZSgpOnZvaWQgMH19Y2xhc3MgTlp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkLEope2xldCBaPVsuLi5KXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWR3cml0ZSIpLFk9US5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57US5vbmNvbXBsZXRlPSgpPT5WKCksUS5vbmVycm9yPSgpPT5YKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBaKXtsZXQgej1VMChXKTtZLnB1dCh7aG9zdDokLGhhc2g6en0pfX0pfWFzeW5jIGRlcSgkLEope2xldCBaPVsuLi5KXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWR3cml0ZSIpLFk9US5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57US5vbmNvbXBsZXRlPSgpPT5WKCksUS5vbmVycm9yPSgpPT5YKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBaKXtsZXQgej1VMChXKTtZLmRlbGV0ZShbJCx6XSl9fSl9YXN5bmMgbGlzdCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntsZXQgVj1aLmdldEFsbCgpO1Yub25zdWNjZXNzPSgpPT57bGV0IFc9Vi5yZXN1bHQuZmlsdGVyKCh6KT0+ei5ob3N0PT09JCkubWFwKCh6KT0+ei5oYXNoKTtRKFcubWFwKCh6KT0+TFooeikpKX0sVi5vbmVycm9yPSgpPT5ZKFYuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmNvdW50KCk7WS5vbnN1Y2Nlc3M9KCk9PlooWS5yZXN1bHQpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkd3JpdGUiKSxKPSQub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19dmFyIFEwPSJzZWVkTWV0YSIsWjA9Imhvc3RzIixGMD0idXBsb2FkUXVldWUiLEswPSJkb3dubG9hZFF1ZXVlIixwPSJtZXNzYWdlcyIsQyQ9ImFwbGQiLHRRPTMsZVE9ImRpcGxvbWF0aWMtc3RvcmUtZGIiO2NsYXNzICRZe3NlZWQ7aG9zdHM7dXBsb2Fkcztkb3dubG9hZHM7bWVzc2FnZXM7ZGI7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmRiPSQsdGhpcy5zZWVkPW5ldyBGWigkLEopLHRoaXMuaG9zdHM9bmV3IFdaKCQpLHRoaXMudXBsb2Fkcz1uZXcgTlooJCksdGhpcy5kb3dubG9hZHM9bmV3IFhaKCQpLHRoaXMubWVzc2FnZXM9bmV3IEdaKCQsSil9YXN5bmMgd2lwZSgpe2F3YWl0IHRoaXMuaG9zdHMud2lwZSgpLGF3YWl0IHRoaXMudXBsb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5kb3dubG9hZHMud2lwZSgpLGF3YWl0IHRoaXMubWVzc2FnZXMud2lwZSgpfX1hc3luYyBmdW5jdGlvbiBiVigpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxKKT0+e2xldCBaPWluZGV4ZWREQi5vcGVuKGVRLHRRKTtaLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpZfT1aO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoUTApKVEuY3JlYXRlT2JqZWN0U3RvcmUoUTApO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoWjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoWjAse2tleVBhdGg6ImxhYmVsIn0pO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoRjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoRjAse2tleVBhdGg6WyJob3N0IiwiaGFzaCJdfSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhLMCkpUS5jcmVhdGVPYmplY3RTdG9yZShLMCk7bGV0IFY7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhwKSlWPVEuY3JlYXRlT2JqZWN0U3RvcmUocCk7ZWxzZXtpZighWSl0aHJvdyBFcnJvcigibWlzc2luZyB1cGdyYWRlIHRyYW5zYWN0aW9uIGZvciBtZXNzYWdlcyBzdG9yZSIpO1Y9WS5vYmplY3RTdG9yZShwKX1pZighVi5pbmRleE5hbWVzLmNvbnRhaW5zKEMkKSlWLmNyZWF0ZUluZGV4KEMkLCJhcGxkIix7dW5pcXVlOiExfSl9LFoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gcHJvdG9jb2wgc3RvcmUgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtlUX0g4oaSIHYke3RRfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LFoub25zdWNjZXNzPSgpPT57bGV0IFE9Wi5yZXN1bHQ7US5vbnZlcnNpb25jaGFuZ2U9KCk9PntRLmNsb3NlKCl9LCQoUSl9LFoub25lcnJvcj0oKT0+SihaLmVycm9yPz9FcnJvcigicHJvdG9jb2wgc3RvcmUgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gSlkoJCl7bGV0IEo9YXdhaXQgYlYoKTtpZih0eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yLnN0b3JhZ2U/LnBlcnNpc3QpdHJ5e2F3YWl0IFByb21pc2UucmFjZShbbmF2aWdhdG9yLnN0b3JhZ2UucGVyc2lzdCgpLG5ldyBQcm9taXNlKChaKT0+e3NldFRpbWVvdXQoKCk9PlooITEpLDIwMDApfSldKX1jYXRjaHt9cmV0dXJuIG5ldyAkWShKLCQpfWNsYXNzIE9ae2NsaWVudDtlbnREQjtwb3N0O3doZW5SZWFkeTtyZXNvbHZlUmVhZHk7cmVqZWN0UmVhZHk7Y29uc3RydWN0b3IoJCl7dGhpcy5wb3N0PSQsdGhpcy53aGVuUmVhZHk9bmV3IFByb21pc2UoKEosWik9Pnt0aGlzLnJlc29sdmVSZWFkeT1KLHRoaXMucmVqZWN0UmVhZHk9Wn0pfWFzeW5jIGluaXQoKXt0cnl7bGV0ICQ9YXdhaXQgSlkociQpLEo9YXdhaXQgclooe2NhY2hlOiExfSksWj1uZXcgZyQoSi5hcHBseSwoKT0+Si5jbGVhcigpLChWKT0+e2lmKFYubGVuZ3RoPDEpcmV0dXJuO3RoaXMucG9zdCh7a2luZDoiZGlydHkiLGVpZHM6Vi5tYXAoKFgpPT5YLnNsaWNlKCkpfSl9KSxRPVouY2xlYXI7Wi5jbGVhcj1hc3luYygpPT57bGV0IFY9YXdhaXQgUSgpO2lmKFY9PT0wKXRoaXMucG9zdCh7a2luZDoid2lwZWQifSk7cmV0dXJuIFZ9O2xldCBZPW5ldyB2SihuZXcgTkosWiwkLHlaLHIkKTt0aGlzLmNsaWVudD1ZLHRoaXMuZW50REI9SixZLmNsaWVudFN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdENsaWVudFN0YXRlKCl9KSxZLnhmZXJTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRYZmVyU3RhdGUoKX0pLGF3YWl0IHRoaXMuZW1pdFhmZXJTdGF0ZSgpLHRoaXMucG9zdCh7a2luZDoicmVhZHkifSksdGhpcy5tYXJrUmVhZHkoKX1jYXRjaCgkKXtsZXQgSj0kIGluc3RhbmNlb2YgRXJyb3I/JDpFcnJvcihTdHJpbmcoJCkpO3Rocm93IHRoaXMucG9zdCh7a2luZDoiaW5pdEVycm9yIixtZXNzYWdlOkoubWVzc2FnZX0pLHRoaXMuZmFpbFJlYWR5KEopLEp9fW1hcmtSZWFkeSgpe2xldCAkPXRoaXMucmVzb2x2ZVJlYWR5O2lmKHRoaXMucmVzb2x2ZVJlYWR5PXZvaWQgMCx0aGlzLnJlamVjdFJlYWR5PXZvaWQgMCwkKSQoKX1mYWlsUmVhZHkoJCl7bGV0IEo9dGhpcy5yZWplY3RSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsSilKKCQpfXJlcXVpcmVDbGllbnQoKXtpZighdGhpcy5jbGllbnQpdGhyb3cgRXJyb3IoIldvcmtlclJ1bnRpbWUgbm90IGluaXRpYWxpemVkIik7cmV0dXJuIHRoaXMuY2xpZW50fWFzeW5jIGVtaXRDbGllbnRTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgSj1hd2FpdCAkLmNsaWVudFN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoiY2xpZW50U3RhdGUiLGNvbm5lY3RlZDpKLmNvbm5lY3RlZH0pfWFzeW5jIGVtaXRYZmVyU3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IEo9YXdhaXQgJC54ZmVyU3RhdGUuZ2V0KCk7dGhpcy5wb3N0KHtraW5kOiJ4ZmVyU3RhdGUiLHN0YXRlOkp9KX1ob3N0RnJvbVNlcmlhbGl6ZWQoJCl7cmV0dXJue2hhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxsYWJlbDokLmxhYmVsLGlkeDokLmlkeH19YXN5bmMgaGFuZGxlKCQpe2F3YWl0IHRoaXMud2hlblJlYWR5O2xldCBKPXRoaXMucmVxdWlyZUNsaWVudCgpO3N3aXRjaCgkLm9wKXtjYXNlInBpbmciOnJldHVybiJwb25nIjtjYXNlInNldFNlZWQiOntsZXRbWixRXT1XMC5mcm9tQnl0ZXMoJC5zZWVkKTtpZigkLnNlZWQuZmlsbCgwKSxRIT09MHx8Wj09PXZvaWQgMCl0aHJvdyBuZXcgTzAoUSk7YXdhaXQgSi5zZXRTZWVkKFose3BlcnNpc3Q6JC5wZXJzaXN0fSk7cmV0dXJufWNhc2UibGluayI6e2F3YWl0IEoubGluayh0aGlzLmhvc3RGcm9tU2VyaWFsaXplZCgkLmhvc3QpLCQuY29ubmVjdD8/ITApO3JldHVybn1jYXNlInVubGluayI6e2F3YWl0IEoudW5saW5rKCQubGFiZWwpO3JldHVybn1jYXNlImNvbm5lY3QiOnthd2FpdCBKLmNvbm5lY3QoJC5saXN0ZW4/PyEwLCQuc3luYz8/ITApO3JldHVybn1jYXNlImRpc2Nvbm5lY3QiOnthd2FpdCBKLmRpc2Nvbm5lY3QoKTtyZXR1cm59Y2FzZSJzeW5jIjpyZXR1cm4gYXdhaXQgSi5zeW5jKCk7Y2FzZSJyZWJ1aWxkIjpyZXR1cm4gYXdhaXQgSi5yZWJ1aWxkKHtjaGVja0hvc3Q6JC5jaGVja0hvc3Q/PyEwfSk7Y2FzZSJyZWNvbmNpbGUiOntsZXRbWixRXT1hd2FpdCBKLnJlY29uY2lsZSgkLmhvc3RMYWJlbCx7cHVsbDokLnB1bGwscHVzaDokLnB1c2gsc3luYzokLnN5bmN9KTtpZihRIT09MCl0aHJvdyBuZXcgTzAoUSk7aWYoIVopdGhyb3cgbmV3IE8wKDEyKTtyZXR1cm4gWn1jYXNlIm1zZ2NoZWNrIjpyZXR1cm4gYXdhaXQgSi5tc2djaGVjaygpO2Nhc2UiZW50Y2hlY2siOntsZXQgWj10aGlzLmVudERCO2lmKCFaKXRocm93IG5ldyBPMCgxMik7bGV0W1EsWV09YXdhaXQgWi5jaGVja3N1bShyJCk7aWYoWSE9PTApdGhyb3cgbmV3IE8wKFkpO2lmKCFRKXRocm93IG5ldyBPMCgxMik7cmV0dXJuIFF9Y2FzZSJ3aXBlIjp7YXdhaXQgSi53aXBlKHttc2dzOiQubXNncyxlbnRzOiQuZW50cyxtZXRhOiQubWV0YSxzZWVkOiQuc2VlZH0pO3JldHVybn1jYXNlImltcG9ydCI6e2xldCBaPSQuYnl0ZXMuc2xpY2UoKSxRPW5ldyBCbG9iKFtaXSksWT1uZXcgRmlsZShbUV0sImltcG9ydC5kaXAiKTtyZXR1cm4gYXdhaXQgSi5pbXBvcnQoWSl9Y2FzZSJleHBvcnQiOntsZXRbWixRXT1hd2FpdCBKLmV4cG9ydEJ5dGVzKCk7aWYoUSE9PTApdGhyb3cgbmV3IE8wKFEpO2lmKCFaKXRocm93IG5ldyBPMCgxMik7cmV0dXJuIFp9Y2FzZSJnZXRYZmVyU3RhdGUiOnJldHVybiBhd2FpdCBKLnhmZXJTdGF0ZS5nZXQoKTtkZWZhdWx0OntsZXQgWj0kO3Rocm93IEVycm9yKCJ1bmtub3duIHdvcmtlciBjb21tYW5kIil9fX19Y2xhc3MgTzAgZXh0ZW5kcyBFcnJvcntzdGF0dXM7Y29uc3RydWN0b3IoJCl7c3VwZXIoYFdvcmtlclN0YXR1c0Vycm9yOiAke0RbJF19YCk7dGhpcy5zdGF0dXM9JDt0aGlzLm5hbWU9IldvcmtlclN0YXR1c0Vycm9yIn19ZnVuY3Rpb24gWUooJCxKKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITAscmVzdWx0Okp9fWZ1bmN0aW9uIFVaKCQsSil7cmV0dXJue2tpbmQ6InJlcGx5IixpZDokLG9rOiExLHN0YXR1czpKfX12YXIgazA9Z2xvYmFsVGhpcyxaWT1uZXcgT1ooKCQsSik9PntpZihKJiZKLmxlbmd0aD4wKWswLnBvc3RNZXNzYWdlKCQsSik7ZWxzZSBrMC5wb3N0TWVzc2FnZSgkKX0pO2swLm9ubWVzc2FnZT0oJCk9PntsZXQgSj0kLmRhdGE7aWYoIU1aKEopKXJldHVybjtoVihKKX07YXN5bmMgZnVuY3Rpb24gaFYoJCl7dHJ5e2xldCBKPWF3YWl0IFpZLmhhbmRsZSgkKTtpZigoJC5vcD09PSJleHBvcnQifHwkLm9wPT09Im1zZ2NoZWNrInx8JC5vcD09PSJlbnRjaGVjayIpJiZKIGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IFo9Si5zbGljZSgpO2swLnBvc3RNZXNzYWdlKFlKKCQuaWQsWiksW1ouYnVmZmVyXSk7cmV0dXJufWlmKCQub3A9PT0icmVjb25jaWxlIiYmSiYmdHlwZW9mIEo9PT0ib2JqZWN0IiYmIm1zZ2NoZWNrImluIEomJkoubXNnY2hlY2sgaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgWj1KLm1zZ2NoZWNrLnNsaWNlKCksUT17Li4uSixtc2djaGVjazpafTtrMC5wb3N0TWVzc2FnZShZSigkLmlkLFEpLFtaLmJ1ZmZlcl0pO3JldHVybn1rMC5wb3N0TWVzc2FnZShZSigkLmlkLEopKX1jYXRjaChKKXtpZihKIGluc3RhbmNlb2YgTzApe2swLnBvc3RNZXNzYWdlKFVaKCQuaWQsSi5zdGF0dXMpKTtyZXR1cm59Y29uc29sZS5lcnJvcigid29ya2VyIGNvbW1hbmQgZmFpbGVkIixKKSxrMC5wb3N0TWVzc2FnZShVWigkLmlkLDEyKSl9fVpZLmluaXQoKS5jYXRjaCgoJCk9Pntjb25zb2xlLmVycm9yKCJ3b3JrZXIgaW5pdCBmYWlsZWQiLCQpfSk7Cg==";var pW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,OV=pW===void 0?void 0:pW.prototype.postMessage,yW;function VG(){if(typeof SW!=="string"||SW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(SW)}function lG(){if(yW!==void 0)return yW;let Z=new Blob([VG()],{type:"text/javascript"});return yW=URL.createObjectURL(Z),yW}function b0(){if(pW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new pW(lG(),{type:"module"})}function d0(Z,X,W){if(OV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)OV.call(Z,X,{transfer:W});else OV.call(Z,X)}var KG=new TextEncoder().encode("diplomatic.wrap.v1"),GG=32,mG=16,FZ=new nZ;class ZZ{#Z;constructor(Z){this.#Z=Z}static async fromRandom(){let Z=await FZ.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??QW,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await F0({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf",authenticatorAttachment:Z?.authenticatorAttachment,hints:Z?.hints,salt:X});if(G!==0)return Y(G);if(K===void 0)return Y(30);if(!K.prfEnabled)return Y(30);W=K.credId}let[V,l]=await EV({rpId:Z?.rpId,rpName:Z?.rpName,credId:W,salt:X,hints:Z?.hints});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await this.#W(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X){let[W,V]=await EV({rpId:X.rpId,rpName:X.rpName,hints:X.hints,credId:X.credId,salt:X.salt});if(V!==0)return Y(V);if(W===void 0)return Y(7);try{let[l,K]=await ZZ.#V(Z,W.prf);if(K!==0)return Y(K);if(l===void 0)return Y(12);return b({enclave:l,credId:W.credId.slice()})}finally{W.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await IW(X);if(G!==0)return Y(G);if(K===void 0)return Y(30);W=K}let[V,l]=this.#l(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await wX(W,V,X);if(K!==0)return Y(K);return b(W)}finally{V.fill(0)}}static async fromLargeBlob(Z){let[X,W]=await LW(Z?.credId,Z);if(W!==0)return Y(W);if(X===void 0)return Y(7);try{return ZZ.#K(X.blob,X.credId)}finally{X.blob.fill(0)}}static async clearLargeBlob(Z,X){return wX(Z,new Uint8Array(kZ),X)}static pairRequest(){return EX.create()}async pairAccept(Z,X){let W;try{W=await FZ.genX25519()}catch{return Y(29)}try{let[V,l]=await jV(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 FZ.encryptXSalsa20Poly1305Combined(K,V);return UV(TZ(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 i;try{let G=K.writeStruct(kW,l);if(G!==0)return Y(G);return b(K.result())}finally{K.wipe()}}finally{W.fill(0)}}spawnSyncWorker(Z){let X=b0(),W=this.#Z.slice();return d0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#Y(W,G),l=(G)=>this.#R(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.#C(W,V,G),kdmFor:(G)=>this.#F(W,V,G)})}async#W(Z){let[X,W]=await k0(FZ,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await FZ.encryptXSalsa20Poly1305Combined(this.#Z,X);return yZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#V(Z,X){let[,W]=yZ(Z);if(W!==0)return Y(W);let[V,l]=await k0(FZ,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await FZ.decryptXSalsa20Poly1305Combined(Z,V)}catch{return Y(20)}return ZZ.fromBytes(K)}finally{V.fill(0),K?.fill(0)}}#l(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]=K0(W,Z);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=new i,m=G.writeStruct(hV,l);if(m!==0)return Y(m);return b(G.result())}finally{l.masterSeed.fill(0)}}finally{W.fill(0)}}static#K(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(hV);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#Y(Z,X){let W=await this.#G(Z);try{return await FZ.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#R(Z,X){let W=await this.#G(Z);try{return await FZ.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){return FZ.blake3(TZ(this.#Z,Z))}async#J(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(TZ(W,V))}async#m(Z,X){let W=await this.#J(Z,X);try{return await FZ.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#C(Z,X,W){let V=await this.#m(Z,X);try{return await FZ.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#F(Z,X,W){let V=await this.#m(Z,X),l=TZ(V.privateKey,W);V.privateKey.fill(0);try{return(await FZ.blake3(l)).slice(0,jZ)}finally{l.fill(0)}}}async function k0(Z,X,W=KG){if(X.byteLength<mG)return Y(10);let V=await Z.blake3(TZ(X,W));return b(V.slice(0,GG))}class MW{#Z;#X;#W;#V;constructor(Z){if(this.#V=Z.persistMeta,this.#W={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=sZ(Z.meta)}get meta(){return this.#X===void 0?void 0:sZ(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:sZ(Z)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use wrapAndSave(enclave) to persist sealed master"));return this.#Z=Z,this.#Z}async wrapAndSave(Z,X){let[W,V]=await Z.sealWithPasskey({...this.#W,salt:X?.salt,credId:X?.credId??this.#X?.credId,createCredIfNeeded:X?.createCredIfNeeded??X?.credId===void 0,userName:"diplomatic-prf",authenticatorAttachment:X?.authenticatorAttachment,hints:X?.hints});if(V!==0)return Y(V);if(W===void 0)return Y(12);let l={sealedMaster:W.sealedMaster,salt:W.salt,credId:W.credId};return this.#X=l,this.#Z=Z,await this.#V(sZ(l)),b(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.unsealWithPasskey(Z.sealedMaster,{...this.#W,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(this.#Z=X.enclave,X.credId.byteLength>0&&(Z.credId===void 0||!n(Z.credId,X.credId))){let V={sealedMaster:Z.sealedMaster,salt:Z.salt,credId:X.credId.slice()};this.#X=V,await this.#V(sZ(V))}return b(X.enclave)}async adoptSealed(Z,X){return this.#X=sZ(X),this.#Z=Z,await this.#V(sZ(X)),b(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function sZ(Z){let[X,W]=yZ(Z.sealedMaster.slice());return{sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()}}var YG="diplomatic.pin/";function RG(Z){return YG+YZ(Z)}async function c0(Z,X,W){let V=await X.deriveIdentity(RG(W),0);return Z.blake3(V.publicKey)}async function xW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await c0(Z,X,W);return{n:W,h:V}}async function zW(Z,X,W){let V=await c0(Z,X,W.n);return JG(V,W.h)}function T0(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 NW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function JG(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 HW="prfMeta",BV="idPin",I0="idPub";class gW{#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(HW),X.delete(BV),X.delete(I0)})}async loadPrfMeta(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(HW);l.onsuccess=()=>{W(CG(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(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),Z===void 0){W.delete(HW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,HW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async lastPrfCredId(){let Z=await this.loadPrfMeta();return Z?.credId===void 0?void 0:Z.credId.slice()}async openPrfStore(Z){let X=await this.loadPrfMeta();return new MW({rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}async#W(Z){await this.#K(I0);let X=await this.#V();if(X!==void 0){if(!await zW(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 xW(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(BV);l.onsuccess=()=>W(T0(l.result)),l.onerror=()=>V(l.error)})}#l(Z){let X=NW(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,BV)})}#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)})}}function CG(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.sealedMaster instanceof Uint8Array)||!(X.salt instanceof Uint8Array))return;let[W,V]=yZ(X.sealedMaster);if(V!==0||W===void 0)return;return{sealedMaster:W,salt:X.salt.slice(),credId:X.credId instanceof Uint8Array?X.credId.slice():void 0}}class wV{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 R=YZ(m);l.put({host:Z,hash:R})}})}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 R=YZ(m);l.delete([Z,R])}})}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((R)=>R.host===Z).map((R)=>R.hash);V(m.map((R)=>pX(R)))},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",CZ="downloadQueue",$="messages",uX="apld",L0=3,Q0="diplomatic-store-db";class DV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new gW(Z,X),this.hosts=new HV(Z),this.uploads=new wV(Z),this.downloads=new NV(Z),this.messages=new gV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function FG(){return new Promise((Z,X)=>{let W=indexedDB.open(Q0,L0);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(CZ))V.createObjectStore(CZ);let K;if(!V.objectStoreNames.contains($))K=V.createObjectStore($);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore($)}if(!K.indexNames.contains(uX))K.createIndex(uX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${Q0} → v${L0}); 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 AV(Z){let X=await FG();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new DV(X,Z)}function S0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function y0(Z){if(typeof Z!=="number")return;return Z}function bG(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=dG(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 dG(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 p0(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=bG(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var dZ="[DIPLOMATIC]";class AX{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:oZ};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 gX(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 dX(W,Z,X,()=>{throw Error(`${dZ} local writer has no transport (use worker for network)`)},IX,!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 iZ,l=W.syncDebounceMs??VW,K=W.readyTimeoutMs??15000,G=new AX(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:oZ}}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=p0(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(!S0(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(cG));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 DX(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=y0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof DX)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=(R)=>{if(G!==void 0)clearTimeout(G);R()};this.pending.set(W,{resolve:(R)=>m(()=>l(R)),reject:(R)=>m(()=>K(R))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${dZ} setSeed worker timeout after ${V}ms`))},V);try{let R=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(R)}catch(R){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(R instanceof Error?R:Error(String(R)))}});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(!kG(W))return Y(12);return b(W)}catch(W){if(W instanceof DX&&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 KW(V,Z),0}catch(W){if(W instanceof DX)return W.status;return 12}}}class DX extends Error{status;constructor(Z){super(`WorkerReplyError: ${M[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function kG(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 cG(Z){return Z}var LX="[DIPLOMATIC]";async function hW(Z){let X=Z.clock??new iZ;if(Z.worker===!0&&TG(Z)!==void 0)throw Error(`${LX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${LX} sync on main thread `+"(no worker — app did not request a worker)");let l=await M0(Z.store);return IG(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${LX} worker: true but Worker API is unavailable`);let W=await M0(void 0),V=await AX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${LX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${LX} terminating sync worker`),V.terminate()}}}function TG(Z){if("store"in Z)return Z.store;return}async function IG(Z,X,W){let V=new dX(Z,X,W,fW,IX);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function M0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${LX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return AV(IX)}function LG(Z){let[X,W]=vV();return PW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function QG(Z){let[X,W]=vV();return PW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function SG(Z){PW(()=>{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 yG(Z={}){let X=Z.clock??new iZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=vV({stateMgr:rW});return PW(()=>{let J=!1,C;return(async()=>{let F=await VV();if(J)return;let d=XW(F),k=K?await hW({state:d,clock:X,worker:!0,readyTimeoutMs:l}):await hW({state:d,clock:X,store:G,readyTimeoutMs:l});if(J){k.dispose();return}C=k.dispose;let{client:c,mode:T}=k;if(W)await c.setSeed(W);if(V)await c.link(V);if(J){C();return}R({client:c,entDB:F,stateMgr:d,mode:T,error:void 0})})().catch((F)=>{let d=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",d),!J)R((k)=>({...k,client:void 0,error:d}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as pG,useEffect as x0,useRef as MG,useState as xG}from"react";function z0(Z,X,W){let[V,l]=xG();return x0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function zG(Z,X,W){let V=MG(W());return x0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),pG(V.current)}function N0(Z,X){return`${Z}:${X}`}class oV{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 NG(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 $V{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;NG(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 qV{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 OZ(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&&bX(K.apld)!==X)continue;let G=e(l);V.push(await OZ(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(bX(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(n(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 OZ(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;$Z(W,EZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(H(X));if(!V)continue;$Z(V,IZ,W)}}async wipe(){this.messages.clear()}}class fV{#Z;#X;#W;constructor(Z){this.#X=Z}async save(Z,X){if(this.#W!==void 0){if(!await zW(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 xW(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:NW(this.#W)}}class nV{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(pX(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 H0{seed;hosts=new $V;uploads=new nV;downloads=new oV;messages;constructor(Z){this.seed=new fV(Z),this.messages=new qV(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class g0{singletonType;latest;latestOff=-1;emitter=new PZ;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 i;K.writeVarString(this.singletonType);let G=K.result();if(V.id.length===G.length&&V.id.every((m,R)=>m===G[R])){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 _V={capable(){return C0()},async createCred(Z){return IW(Z)},async write(Z,X,W){return wX(Z,X,W)},async read(Z,X){let[W,V]=await LW(Z,X);if(V!==0||W===void 0)return Y(V);return b(W.blob)}};class h0{#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 mk(){return _V.capable()}export{XG as webAuthnLastError,SG as useSyncOnResume,zG as useStateWatcherSuspense,z0 as useStateWatcher,QG as useClientXferState,LG as useClientState,yG as useClient,lW as shouldEmitItemProgress,$Z as setApld,lV as revFromHead,NX as revFromEntity,WG as prfCapable,AV as openIDBStore,VV as openEntDB,hW as openDiplomaticClient,rW as nullStateManager,SK as nullEntDB,pl as normalizeTags,mk as largeBlobCapable,QK as isTombstone,GV as isTerminalApplyFailure,MK as isPendingApply,v as isLiveEnt,pK as isApldState,oZ as idleProgress,pX as htob,fW as hostHTTPTransport,VK as genSingletonEID,XW as entStateManager,Il as encodeEntRev,s as eidCodec,TW as defaultWebAuthnRpId,FX as defaultPeekProgressEvery,IX as crypto,Tl as cmpBytes,GX as checksumSet,xX as checksumEntRevs,YZ as btoh,lK as btob64url,H as btob64,BW as b64urltob,e as b64tob,yZ as asSealedMasterKey,UV as asDHKEResp,PV as asDHKEReq,bX as apldFromStored,AX as WorkerClient,PZ as TypedEventEmitter,dX as SyncClient,M as Status,zX as StateManager,g0 as SingletonStateManager,sW as SEALED_MASTER_KEY_LEN,MW as PrfSeedStore,h0 as PasskeySeedStore,EX as PairRequest,H0 as MemoryStore,kZ as MASTER_SEED_LEN,DV as IDBStore,gW as IDBSeedStore,qW as HTTPTransport,WV as EntIDB,ZW as EntDBMemory,i as Encoder,ZZ as Enclave,j as Decoder,QW as DEFAULT_PRF_SALT,iZ as Clock,HX as CachedEntDB,pZ as APLD_PENDING,IZ as APLD_ERROR,EZ as APLD_APPLIED};
|
|
1
|
+
function sV(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 P0(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 U0=new TextEncoder,j0=50;function u0(Z,X,W){U0.encodeInto(Z,X.subarray(W))}function rV(Z,X,W){if(Z.length>j0)u0(Z,X,W);else P0(Z,X,W)}var E0=4096;function UW(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 R=Z[V++]&63;K.push((m&31)<<6|R)}else if((m&240)===224){let R=Z[V++]&63,J=Z[V++]&63;K.push((m&31)<<12|R<<6|J)}else if((m&248)===240){let R=Z[V++]&63,J=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|R<<12|J<<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>=E0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var i0=new TextDecoder,O0=200;function B0(Z,X,W){let V=Z.subarray(X,X+W);return i0.decode(V)}function tV(Z,X,W){if(W>O0)return B0(Z,X,W);else return UW(Z,X,W)}class WX{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 VX=4294967295;function eV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function vX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function oX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function Zl(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var w0=-1,D0=4294967295,A0=17179869183;function v0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=A0)if(X===0&&Z<=D0){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),vX(V,4,Z),W}}function o0(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 $0(Z){if(Z instanceof Date){let X=o0(Z);return v0(X)}else return null}function q0(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=oX(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 f0(Z){let X=q0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var Xl={type:w0,encode:$0,decode:f0};class lX{static defaultCodec=new lX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(Xl)}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 WX(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 WX(W,l)}}if(Z instanceof WX)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 WX(X,Z)}}function n0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function QX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(n0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var _0=100,a0=2048;class $X{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??lX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??_0,this.initialBufferSize=Z?.initialBufferSize??a0,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 $X({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=sV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),rV(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=QX(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),eV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),vX(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 vZ(Z,X){return new $X(X).encodeSharedRef(Z)}function qX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var s0=16,r0=16;class jW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=s0,X=r0){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=UW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var uW="array",yX="map_key",Vl="map_value",t0=(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 ll{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=uW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=yX,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===uW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===yX||Z.type===Vl){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,EW=new DataView(new ArrayBuffer(0)),e0=new Uint8Array(EW.buffer);try{EW.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 Wl=RangeError("Insufficient data"),ZK=new jW;class fX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=EW;bytes=e0;headByte=SX;stack=new ll;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??lX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??VX,this.maxBinLength=Z?.maxBinLength??VX,this.maxArrayLength=Z?.maxArrayLength??VX,this.maxMapLength=Z?.maxMapLength??VX,this.maxExtLength=Z?.maxExtLength??VX,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:ZK,this.mapKeyConverter=Z?.mapKeyConverter??t0}clone(){return new fX({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=QX(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=QX(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 ${qX(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: ${qX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===uW)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===yX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=Vl;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=yX;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: ${qX(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 Wl;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=tV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===yX;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 Wl;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=Zl(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=oX(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 iW(Z,X){return new fX(X).decode(Z)}class hZ{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 hZ}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 PZ=64;var Kl=32,UZ=8;var nX=32;var Gl=30000,ml=512,M;((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"})(M||={});function b(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function XK(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 WK(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]=WK(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]=XK(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 jZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>Gl)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 KX(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 VK(Z){return KX({id:Z,ts:new Date(0)})}var JZ={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,R]=Z.readVarInt();if(R!==0)return Y(R);let[J,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(J>0){let[d,k]=Z.readBytes(nX);if(k!==0)return Y(k);F=d}return b({eid:X,off:K,ctr:m,len:J,hsh:F})}};function YZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function pX(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 n(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 lK(Z){return H(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function BW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function TZ(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function Yl(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Rl(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new E,G=JZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),R=await X.kdmFor(m),J=V.deriveCipher(R,"encrypt"),C=await J.encrypt(m),F=Z.bod?await J.encrypt(Z.bod):new Uint8Array(0),d=await X.sign(C);return b({sig:d,kdm:R,headCph:C,bodyCph:F})}async function wW(Z,X,W,V,l){let K=new j(Z),[G,m]=JZ.decode(K);if(m!==0)return Y(14);let R;try{R=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let J=G.hsh&&R===void 0,C=G.hsh===void 0&&R!==void 0;if(J||C)return Y(19);if(G.hsh&&R){let d=await V.blake3(R);if(!n(d,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return b({msgHead:G,bod:R,headHash:F})}class uZ{now(){return new Date}}function Jl(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 DW={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[R,J]=Z.readVarInt();if(J!==0)return Y(J);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,T]=Z.readStruct(MX);if(T!==0)return Y(T);return b({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:d,dyn:c}})}};var AW={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 RZ={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(PZ);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 Cl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,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(RZ);if(m!==0)return m;let R=await jZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);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,T]=await K.listHeads(J,d);if(T!==0)return T;return W.writeStructs(AW,c)},decodeResp(Z){return Z.readStructs(AW)}};var vW={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 Fl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,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(RZ);if(m!==0)return m;let R=await jZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let d=[];while(!X.done()){let[T,I]=X.readVarInt();if(I!==0)return I;d.push(T)}console.info(`PULL: ${d.length} bags`);let[k,c]=await K.getBodies(J,d);if(c!==0)return c;if(!k)return 17;for(let{seq:T,bodyCph:I}of k){let S={seq:T,bodyCph:I},Q=W.writeStruct(vW,S);if(Q!==0)return Q}return 0},decodeResp(Z){return Z.readStructs(vW)}};var oW={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(PZ);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,R]=Z.readVarBytes();if(R!==0)return Y(R);return b({sig:X,kdm:V,headCph:K,bodyCph:m})}};var _X={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[R,J]=Z.readBytes(K);if(J!==0)return Y(J);m=R}return b({seq:X,headCph:V,bodyCph:m})}};var aX={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(PZ);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 sX={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 bl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;let G=l.writeStructs(oW,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,R]=X.readStruct(RZ);if(R!==0)return R;let J=await jZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,d]=await K.hasUser(C);if(d!==0)return d;if(!F)return 5;let[k,c]=X.readStructs(oW);if(c!==0)return c;console.info(`PUSH: ${k.length} bags`);let T=[],I=[];for(let L=0;L<k.length;L++){let z=k[L];if(!await Yl(z,C,l)){let i={idx:L,status:3},u=W.writeStruct(sX,i);if(u!==0)return u;continue}T.push(L),I.push(z)}let[S,Q]=await K.setBags(C,I);if(Q!==0)return Q;if(!S||S.length!==I.length)return 17;let p=[];for(let L=0;L<I.length;L++){let z=I[L],g=T[L],i=S[L],u=new E,P=u.writeStruct(aX,z);if(P!==0)return P;let B=u.result(),D={seq:i,headCph:B};if(k.length===1&&z.bodyCph.length<=ml)D.bodyCph=z.bodyCph;p.push(D);let o={idx:g,status:0,seq:i},y=W.writeStruct(sX,o);if(y!==0)return y}if(p.length>0){let L=new E,z=L.writeStructs(_X,p);if(z!==0)return z;let g=L.result();await Promise.resolve(G.push(C,g))}return 0},decodeResp(Z){return Z.readStructs(sX)}};var dl={async encodeReq(Z,X,W,V,l){return l.writeStruct(RZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await jZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G;if(!X.done())return 8;let[C,F]=await K.addUser(J);if(F!==0)return F;return 0},decodeResp(Z){return b(void 0)}};class $W{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(RZ,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=(R)=>{let J=new Uint8Array(R.data);X(J)},this.websocket.onerror=(R)=>{console.log(`ERROR: ${JSON.stringify(R)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var r={user:{path:"/user",endpoint:dl,name:0},push:{path:"/push",endpoint:bl,name:2},peek:{path:"/peek",endpoint:Cl,name:1},pull:{path:"/pull",endpoint:Fl,name:3}},KK={0:r.user,2:r.push,1:r.peek,3:r.pull},UR={[r.user.path]:r.user,[r.push.path]:r.push,[r.peek.path]:r.peek,[r.pull.path]:r.pull};class qW{url;listener;constructor(Z){this.url=Z;this.listener=new $W(Z)}async call(Z,X){let{path:W}=KK[Z],V=new URL(W,this.url);try{return await GK(V,X)}catch{return Y(25)}}}var fW=(Z)=>{return new qW(Z.handle)};async function GK(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 rX{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(),[R,J]=await OW(G,m);if(J!==0)return Y(J);let C=new E,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let d=W.now(),[k,c]=await V.call(K,C),T=W.now();if(c!==0)return Y(c);let[I,S]=k.readStruct(DW);if(S!==0)return Y(S);if(I.status!==0)return Y(I.status);let p={clockOffset:Jl(d,I.timeRcvd,I.timeSent,T),subscription:I.subscription},L=await this.updateHostMeta(p);if(L!==0)return Y(L);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 Rl(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(),[R,J]=await OW(G,m);if(J!==0)return J;return await K.connect(R,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 nW={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,R]=Z.readBytes(nX);if(R!==0)return Y(R);let[J,C]=Z.readBytes(PZ);if(C!==0)return Y(C);return b({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var _W={encode(Z,X){let W=Z.writeStruct(nW,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(nW);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 aW={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[R,J]=Z.readVarInt();if(J!==0)return Y(J);m=R}return b({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function kl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new E,m=new E,R=0,J=0;for(let S of W){let Q=new E,p=Q.writeStruct(JZ,S.head);if(p!==0)return Y(p);let L=Q.result(),z=await K.kdmFor(L),g=l.deriveCipher(z,"encrypt"),i=await g.encrypt(L),u=S.body?await g.encrypt(S.body):new Uint8Array(0),P=S.head.len>0&&S.head.hsh!==void 0?u.length:0,B={kdm:z,headCph:i,lenBody:P,offBody:P>0?J:void 0},D=G.writeStruct(aW,B);if(D!==0)return Y(D);if(S.body)m.writeBytes(u),J+=u.length;R++}let C=m.result(),F=G.result(),d=await V.blake3(F),k=await K.sign(d),c={lbl:Z,idx:X,num:R,hsh:d,sig:k},T=new E;T.writeStruct(_W,{head:c,indexEnc:F,bodyEnc:C});let I=T.result();return b(I)}async function cl(Z,X,W){let[V,l]=_W.decode(new j(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,R=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,R.publicKey))return Y(3);let C=await X.blake3(G);if(!n(C,K.hsh))return Y(19);let F=new j(G),d=[];for(let c=0;c<K.num;c++){let[T,I]=F.readStruct(aW);if(I!==0)return Y(I);d.push(T)}if(d.length!==K.num)return Y(14);let k=[];for(let c of d){let T=W.deriveCipher(c.kdm,"decrypt"),I;try{I=await T.decrypt(c.headCph)}catch{return Y(20)}let[S,Q]=JZ.decode(new j(I));if(Q!==0)return Y(Q);let p;if(c.lenBody>0&&c.offBody!==void 0){if(S.hsh===void 0)return Y(14);let L=m.slice(c.offBody,c.offBody+c.lenBody);try{p=await T.decrypt(L)}catch{return Y(20)}let z=await X.blake3(p);if(!n(z,S.hsh))return Y(19)}k.push({head:S,body:p})}return b(k)}async function Tl({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 tX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function tX({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 R=Z.getTime()-G.ts.getTime(),J,C=V?.length??0;if(V&&C>0)J=await l.blake3(V);return b({eid:X,off:R,ctr:W,len:C,hsh:J})}function Il(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 GX(Z,X){let W=Array.from(Z);W.sort(Il);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 Ll(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 xX(Z,X){let W=[];for(let V of Z){let[l,K]=Ll(V);if(K!==0||!l)return Y(K);W.push(l)}return b(await GX(W,X))}var xJ=Symbol("MasterSeed"),zJ=Symbol("SealedMasterKey"),kZ=32,sW=24+kZ+16;function VZ(Z){if(Z.byteLength!==kZ)return Y(10);return b(Z)}function yZ(Z){if(Z.byteLength!==sW)return Y(10);return b(Z)}var HJ=Symbol("EntityID");function Ql(Z){return"type"in Z}var gJ=Symbol("DerivationSeed"),hJ=Symbol("PublicKey"),PJ=Symbol("PrivateKey"),UJ=Symbol("HostSpecificKeyPair"),jJ=Symbol("Hash");function mK(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 YK(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return b(V)}let X=iW(Z.bod);if(mK(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 zX{applier;emitter=new hZ;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[R,J]=YK(m);if(W.push(J),J!==0)continue;X.push(R)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let R=W[m],J=V[m];if(R!==0){G.push(R);continue}if(J!==0){G.push(J);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 rW={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 f="entities",eX="entity_type_created_at",eW="entity_type_updated_at",ZV="entity_type_group_id",XV="entity_type_parent_id",mX="entity_tags",Sl="db",yl=13;function RK(Z){return"typ"in Z}function JK(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 CK(Z){if(!v(Z))return{eid:H(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return JK(Z)}function YX(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 tW(Z){if(RK(Z))return YX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class WV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=bK().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(f,"readwrite"),K=l.objectStore(f);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 J=0;J<m.length;J++)if(m[J]===void 0)m[J]=18;G({stats:m,types:X,eids:W})};let R=new Map;for(let J=0;J<Z.length;J++){let C=Z[J],F=H(C.eid),d={op:C,index:J},k=R.get(F);if(k)k.push(d);else R.set(F,[d])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let d=F.result,k=d?tW(d):void 0,c=!1;for(let{op:T,index:I}of C){let[S,Q]=RX(k,T);if(Q!==0){m[I]=Q;continue}if(S===void 0){m[I]=12;continue}c=!0;for(let p of JX(k,S))X.add(p);k=S}if(c)W.push(C[0].op.eid);if(k){let T=K.put(CK(k));T.onerror=(I)=>{I.preventDefault();for(let{index:S}of C)m[S]=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(f,"readwrite"),W=X.objectStore(f);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(f,"readonly").objectStore(f);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(b(void 0));else K(b(tW(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||!v(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(f,"readonly").objectStore(f).index(eW);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(b(R.map(YX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(ZV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(b(m.map(YX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(eX);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(b(G.map(YX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(mX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(YX);K(b(R))},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(f,"readonly").objectStore(f).index(XV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(YX);K(b(R))},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(f,"readonly").objectStore(f).index(eX);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(f,"readonly").objectStore(f),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(NX(tW(R))),m.continue()}else xX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function FK(Z,X){if(!Z.objectStoreNames.contains(f))Z.createObjectStore(f,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(f);if(!W.indexNames.contains(eX))W.createIndex(eX,["typ","crd"],{unique:!1});if(!W.indexNames.contains(eW))W.createIndex(eW,["typ","upd"],{unique:!1});if(!W.indexNames.contains(ZV))W.createIndex(ZV,["typ","gid"],{unique:!1});if(!W.indexNames.contains(XV))W.createIndex(XV,["typ","pid"],{unique:!1});if(W.indexNames.contains(mX)){if(W.index(mX).keyPath!=="tgs")W.deleteIndex(mX)}if(!W.indexNames.contains(mX))W.createIndex(mX,"tgs",{unique:!1,multiEntry:!0})}function bK(){return new Promise((Z,X)=>{let W=indexedDB.open(Sl,yl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{FK(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Sl} → v${yl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function pl(){let Z=new WV;return await Z.init(),Z}class ZW{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&&v(W))this.unindex(X,W);if(this.ents.set(X,Z),v(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(v(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,R]=RX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of JX(G,m))X.add(J);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||!v(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 R of m.values())if(R.updatedAt>=l.start&&R.updatedAt<=l.end)G.push(R)}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(v(G)&&G.type===Z&&G.pid&&n(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(v(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(v(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(v(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(v(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(v(W)&&W.type===Z)X+=1;return b(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(NX(W));return xX(X,Z)}}async function VV(Z){let X=await pl();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 ZW(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=LK(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||!dK(K,G)){if(v(G))X.add(G.type);if(K!==void 0&&v(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),v(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||IK(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||!v(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 dK(Z,X){if(v(Z)!==v(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!n(Z.eid,X.eid))return!1;if(!v(Z)||!v(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(!cK(Z.pid,X.pid))return!1;if(!kK(Z.tags,X.tags))return!1;return TK(Z.body,X.body)}function kK(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 cK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return n(Z,X)}function TK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return n(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return n(vZ(Z),vZ(X))}catch{return!1}}function IK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function LK(Z,X){let W=new Set,V=[];for(let l of X){let K=H(l.eid),G=Z.ents.get(K),[m,R]=RX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of JX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function XW(Z){if(Z instanceof HX){let X=new zX((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 zX((X)=>Z.apply(X),()=>Z.clear())}function v(Z){return"type"in Z}function QK(Z){return!v(Z)}function Ml(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 NX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function lV(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(Ql(X)){let G=Ml(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 JX(Z,X){let W=new Set;if(Z!==void 0&&v(Z))W.add(Z.type);if(v(X))W.add(X.type);return[...W]}var SK={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 WW{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 VW=100;class gX{timer=null;delayMs;work;tail=new WW;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 xl(Z){let X=new j(Z.eid),[W,V]=s.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function yK(Z,X){let W=xl(Z),V=xl(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 CX(Z,X){return Z.slice().sort((W,V)=>yK(X(W),X(V)))}var oZ={phase:"idle"},FX=50;function lW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function KW(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 zl(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 KV(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 J=K;if(K+=1,J>=V)return;l[J]=await W(Z[J],J)}},R=[];for(let J=0;J<G;J++)R.push(m());return await Promise.all(R),l}async function GW(Z,X,W,V){let l=new j(Z.headCph),[K,G]=l.readStruct(aX);if(G!==0)return Y(G);let{sig:m,kdm:R,headCph:J}=K;if(!await V.checkSigEd25519(m,J,X))return Y(3);let F=W.deriveCipher(R,"decrypt"),d;try{d=await F.decrypt(J)}catch{return Y(20)}return b({kdm:R,headEnc:d})}var pZ="f",EZ="t",IZ="e";function pK(Z){return Z===pZ||Z===EZ||Z===IZ}function bX(Z){if(Z===!0||Z===EZ)return EZ;if(Z===IZ)return IZ;return pZ}function MK(Z){return bX(Z.apld)===pZ}function GV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function $Z(Z,X,W){if(Z.apld=X,X===IZ&&W!==void 0)Z.err=W;else delete Z.err}async function iZ(Z,X,W,V){let l=V?.body!==!1,K=bX(X.apld),G=X.body,m=G?.length??0,R;if(l&&G&&m>0)R=await W.blake3(G);let J={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:R},C={hash:Z,head:J,apld:K};if(l&&G!==void 0)C.body=G;if(K===IZ&&X.err!==void 0)C.err=X.err;return C}var mV=1048576,YV=1048576,Hl=64;function xK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function zK(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 R of K){if(R.status!==0){console.error("push err",R);continue}let J=l[R.idx];if(!J){console.error("no hash",R);continue}await X.uploads.deq(W,[J])}let m=await X.hosts.get(W);if(m){let R=m.lastSeq,J=R,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===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function Nl(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:R}of l){let J=W.get(m);if(!J)continue;G.push({dl:J,bodyCph:R})}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:J,bodyCph:C}of V){let{head:F,kdm:d,seq:k,host:c}=J,[T,I]=await gl(J,W);if(I!==0||!T){let P=m.get(c)??[];P.push(k),m.set(c,P);continue}let{headEnc:S,headEncHash:Q}=T,p=X.deriveCipher(d,"decrypt"),[L,z]=await wW(S,C,p,W,Q);if(z!==0||!L){let P=m.get(c)??[];P.push(k),m.set(c,P);continue}let g={head:F,body:L.bod},i=L.headHash;G.push({key:i,data:Ul(g)}),l.push(g),K.push(i);let u=m.get(c)??[];u.push(k),m.set(c,u)}let R=await Z.messages.add(G);for(let[J,C]of m)await Z.downloads.deq(J,C);for(let J=0;J<R.length;J++){let C=R[J];if(C!==0&&C!==15)console.error("ERR storing",M[C],"for message",J)}return b({parts:l,hashes:K})}async function gl(Z,X){let W=Z.headEnc;if(!W){let l=new E,K=l.writeStruct(JZ,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 hl(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[J,C]=await gl(G,W);if(C!==0||!J)continue;m=H(J.headEncHash)}if(!V.has(m))continue;let R=K.get(G.host)??[];R.push(G.seq),K.set(G.host,R)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function RV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let R=await Z.identity(),J=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let d=C.length,k=G??FX,c=m??Hl;if(K&&d>0)K({phase:"peek",host:V.label,done:0,total:d});let T=0,I=await KV(C,c,async(Q)=>{let[p,L]=await GW(Q,R.publicKey,W,l),z;if(L!==0||!p)z={ok:!1,seq:Q.seq,stat:L};else{let g=await l.blake3(p.headEnc);z={ok:!0,seq:Q.seq,kdm:p.kdm,headEnc:p.headEnc,headEncHash:g}}if(T+=1,K&&lW(T,d,k))K({phase:"peek",host:V.label,done:T,total:d});return z}),S=new Set;for(let Q of I){if(!Q.ok){console.error("peek: decrypting item head",Q.stat);continue}let p=H(Q.headEncHash);if(await X.messages.has(Q.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[Q.headEncHash]),await X.downloads.deq(V.label,[Q.seq]);continue}if(S.has(p)){await X.downloads.deq(V.label,[Q.seq]);continue}let z=new j(Q.headEnc),[g,i]=z.readStruct(JZ);if(i!==0){console.error("peek: reading item head",i);continue}S.add(p),J.push({kdm:Q.kdm,head:g,seq:Q.seq,host:V.label,headEnc:Q.headEnc,headEncHash:Q.headEncHash})}if(await X.downloads.enq(J),C.length>0){let Q=Math.max(...C.map((p)=>p.seq));await X.hosts.recordStats(V.label,{lastSeq:Q})}if(K)K({phase:"peek",host:V.label,done:d,total:d});return 0}async function Pl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??mV,G=await X.uploads.list(W.label),m=G.length,R=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let J=[],C=[],F=0,d=async()=>{if(J.length<1)return 0;let k=J.length,c=await zK(Z,X,W.label,J,C);if(J=[],C=[],F=0,c===0){if(R+=k,l)l({phase:"push",host:W.label,done:R,total:m})}return c};for(let k of G){let c=await X.messages.get(k);if(!c){R+=1;continue}let T={...c.head,bod:c.body},[I,S]=await Z.seal(T);if(S!==0)return S;if(!I)return 12;let Q=xK(I);if(J.length>0&&F+Q>K){let p=await d();if(p!==0)return p}if(J.push(I),C.push(k),F+=Q,F>=K){let p=await d();if(p!==0)return p}}return d()}async function JV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??YV,J=await X.downloads.list(),C=Array.from(J).filter((I)=>I.host===V.label);if(C.length<1)return 15;let F=CX(C,(I)=>I.head),d=zl(F,(I)=>I.head.len,R),k=F.length,c=0;if(G)G({phase:"pull",host:V.label,done:0,total:k});let T=Nl(Z,d[0]);for(let I=0;I<d.length;I++){let[S,Q]=await T;if(Q!==0||!S)return Q;if(c+=d[I].length,G)G({phase:"pull",host:V.label,done:c,total:k});let p=d[I+1];if(p)T=Nl(Z,p);if(G)G({phase:"open",host:V.label,done:c,total:k});let L=CX(S,(g)=>g.dl.head),[,z]=await NK(X,W,l,L);if(z!==0)return z;if(m){if(G)G({phase:"exec",host:V.label,done:c,total:k});await m()}}return 0}function Ul({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:pZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function jl(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new j(Z),[F,d]=C.readStructs(_X);if(d!==0){console.error("Failed decoding notif",M[d]);return}let k=!1,T=(await W.hosts.get(R))?.lastSeq,I=[],S=!1;for(let L of F){let[z,g]=await GW({seq:L.seq,headCph:L.headCph},J.publicKey,V,K);if(g!==0){console.error("Failed decrypting notif",M[g]);continue}let i=await K.blake3(z.headEnc);if(await W.messages.has(i))continue;let u=new j(z.headEnc),[P,B]=u.readStruct(JZ);if(B!==0){console.error("Failed to parse head",M[B]);continue}if(!L.bodyCph&&P.len>0)S=!0,await W.downloads.enq([{seq:L.seq,host:R,kdm:z.kdm,head:P,headEnc:z.headEnc,headEncHash:i}]);else I.push({...z,head:P,bodyCph:L.bodyCph,headEncHash:i});if(T===void 0||L.seq!==T+1)console.log("out of seq",L.seq,T),k=!0;else T=L.seq}if(T!==void 0)await W.hosts.touch(l.label,T);let Q=[];for(let L of I){let z=V.deriveCipher(L.kdm,"decrypt"),[g,i]=await wW(L.headEnc,L.bodyCph,z,K);if(i!==0){console.error("Failed to open body",M[i]);continue}Q.push({key:L.headEncHash,data:Ul({head:L.head,body:g.bod})})}let p=await W.messages.add(Q);for(let L=0;L<p.length;L++){let z=p[L];if(z!==0&&z!==15)console.error("ERR storing",M[z],"for message",L)}if(G&&Q.length>0)G({phase:"open",host:l.label,done:Q.length,total:Q.length});if(k||S||Q.length>0)m()}async function CV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:R,onProgress:J,peekProgressEvery:C,peekConcurrency:F}=Z,d=await l.identity(),[k,c]=await l.peek(0);if(c!==0)return Y(c);let T=k.length,I=C??FX,S=F??Hl;if(J&&T>0)J({phase:"peek",host:m.label,done:0,total:T});let Q=0,p=await KV(k,S,async(h)=>{let[O,U]=await GW(h,d.publicKey,G,R),A;if(U!==0||!O)A={ok:!1,seq:h.seq,stat:U};else{let N=await R.blake3(O.headEnc);A={ok:!0,seq:h.seq,kdm:O.kdm,headEnc:O.headEnc,headEncHash:N}}if(Q+=1,J&&lW(Q,T,I))J({phase:"peek",host:m.label,done:Q,total:T});return A}),L=new Map;for(let h of p){if(!h.ok)continue;let O=H(h.headEncHash),U=L.get(O);if(U)U.count+=1;else L.set(O,{hash:h.headEncHash,count:1,sample:h})}let z=0,g=[];for(let h of L.values()){if(h.count>1)z+=h.count-1;g.push(h.hash)}let i=k.length,u=L.size,P=await GX(g,R),B=[],D=0;for(let h of L.values()){if(await K.messages.has(h.hash)){await K.uploads.deq(m.label,[h.hash]);continue}if(D+=1,!W)continue;let U=h.sample,A=new j(U.headEnc),[N,_]=A.readStruct(JZ);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 o=0;if(V){let h=await K.messages.listKeys(),O=new Set(L.keys()),U=[];for(let A of h)if(!O.has(H(A)))o+=1,U.push(A);if(U.length>0)await K.uploads.enq(m.label,U)}else{let h=await K.messages.listKeys(),O=new Set(L.keys());for(let U of h)if(!O.has(H(U)))o+=1}let y=k.length>0?Math.max(...k.map((h)=>h.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:y}),J)J({phase:"peek",host:m.label,done:T,total:T});return b({msgcheck:P,numBags:i,uniqueMsgs:u,numDupes:z,missingLocal:D,missingHost:o})}class dX{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new WW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=FX;lastProgress=oZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=mV,m=YV,R){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=R;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new cZ(()=>this.getClientState()),this.xferState=new cZ(()=>this.getXferState()),this.scheduledSync=new gX(VW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(J){console.error("Debounced sync failed:",J)}})}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(JZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:pZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(J),V.push({key:J,data:C})}await this.store.messages.add(V),await hl(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:pZ});if(Z.length<1)return[];let X=CX(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&&GV(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 Tl({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 tX({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,R]=G.readStruct(s);if(R!==0)return Y(R);let J=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:J+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]=KX({id:m.id,ts:K});if(c!==0)return Y(c);let[T,I]=await tX({now:K,eid:k,ctr:0,bod:X,crypto:l});if(I!==0)return Y(I);let Q=(await this.apply([{head:T,body:X}]))[0];if(Q!==0&&Q!==15)return Y(Q??12);return b(T)}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=vZ({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,J=vZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,J,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 lV(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 KX({id:Z,ts:V});let l=await W.genRandomBytes(8);return KX({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},R=await RV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await Pl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await JV(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 GX(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 R={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[J,C]=await CV({...R,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!J)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),b(J);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 CV({...R,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 R={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await RV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await JV(R);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=CX(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 J=l;J<W.length&&G<100&&K<102400;J++)K+=W[J].head.len,G++,m=J+1;let R=W.slice(l,m);await this.applyStored(R),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=oZ,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,R]=await cl(G,W,K);if(R!==0)return R;console.timeEnd("import: decoding file...");let J=0;while(J<m.length){let C=0,F=0,d=J;for(let T=J;T<m.length&&F<100&&C<102400;T++)C+=m[T].head.len,F++,d=T+1;let k=m.slice(J,d);console.time(`import: applying [${J}, ${d}]`);let c=await this.apply(k,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${d}]`);for(let T=0;T<k.length;T++){let I=c[T];if(I!==0&&I!==15)console.warn(`failed to import msg ${J+T}: ${M[I]}`)}if(l)queueMicrotask(()=>l(d,m.length,0));this.emitProgress({phase:"import",done:d,total:m.length}),J=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 kl("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 KW(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,R=l.get(Z.label);if(R){if(R.isConnected())return;try{R.closeListener()}catch{}l.delete(Z.label)}let J=await G.seed.load();if(!J)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new rX(J,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:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return jl(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 qZ=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function mW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function FV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!FV(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 bV(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 ul(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function dV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var MZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var HK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!HK)throw Error("Non little-endian hardware is not supported");function gK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function YW(Z){if(typeof Z==="string")Z=gK(Z);else if(FV(Z))Z=RW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function El(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function il(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 Ol=(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)}},R=!1;return{encrypt(C,F){if(R)throw Error("cannot encrypt() twice with same key + nonce");return R=!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 kV(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&&!hK(X))throw Error("invalid output, must be aligned");return X}function hK(Z){return Z.byteOffset%4===0}function RW(Z){return Uint8Array.from(Z)}function LZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function hX(Z=32){if(qZ&&typeof qZ.getRandomValues==="function")return qZ.getRandomValues(new Uint8Array(Z));if(qZ&&typeof qZ.randomBytes==="function")return qZ.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var wl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),PK=wl("expand 16-byte k"),UK=wl("expand 32-byte k"),jK=MZ(PK),uK=MZ(UK);function x(Z,X){return Z<<X|Z>>>32-X}function cV(Z){return Z.byteOffset%4===0}var JW=64,EK=16,Dl=4294967295,Bl=new Uint32Array;function iK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(JW),C=MZ(J),F=cV(l)&&cV(K),d=F?MZ(l):Bl,k=F?MZ(K):Bl;for(let c=0;c<R;G++){if(Z(X,W,V,C,G,m),G>=Dl)throw Error("arx: counter overflow");let T=Math.min(JW,R-c);if(F&&T===JW){let I=c/4;if(c%4!==0)throw Error("arx: invalid block position");for(let S=0,Q;S<EK;S++)Q=I+S,k[Q]=d[Q]^C[S];c+=JW;continue}for(let I=0,S;I<T;I++)S=c+I,K[S]=l[S]^J[I];c+=T}}function Al(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=El({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return mW(l),mW(G),dV(K),dV(W),(m,R,J,C,F=0)=>{a(m),a(R),a(J);let d=J.length;if(C===void 0)C=new Uint8Array(d);if(a(C),mW(F),F<0||F>=Dl)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,T,I;if(c===32)k.push(T=RW(m)),I=uK;else if(c===16&&W)T=new Uint8Array(32),T.set(m),T.set(m,16),I=jK,k.push(T);else throw Error(`arx: invalid 32-byte key, got length=${c}`);if(!cV(R))k.push(R=RW(R));let S=MZ(T);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(I,S,MZ(R.subarray(0,16)),S),R=R.subarray(16)}let Q=16-l;if(Q!==R.length)throw Error(`arx: nonce must be ${Q} or 16 bytes`);if(Q!==12){let L=new Uint8Array(12);L.set(R,K?0:12-R.length),R=L,k.push(R)}let p=MZ(R);return iK(Z,I,S,p,J,C,F,G),LZ(...k),C}}var t=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class vl{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=YW(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),R=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|R<<8)&8191,this.r[9]=R>>>5&127;for(let J=0;J<8;J++)this.pad[J]=t(Z,16+2*J)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],R=K[2],J=K[3],C=K[4],F=K[5],d=K[6],k=K[7],c=K[8],T=K[9],I=t(Z,X+0),S=t(Z,X+2),Q=t(Z,X+4),p=t(Z,X+6),L=t(Z,X+8),z=t(Z,X+10),g=t(Z,X+12),i=t(Z,X+14),u=l[0]+(I&8191),P=l[1]+((I>>>13|S<<3)&8191),B=l[2]+((S>>>10|Q<<6)&8191),D=l[3]+((Q>>>7|p<<9)&8191),o=l[4]+((p>>>4|L<<12)&8191),y=l[5]+(L>>>1&8191),h=l[6]+((L>>>14|z<<2)&8191),O=l[7]+((z>>>11|g<<5)&8191),U=l[8]+((g>>>8|i<<8)&8191),A=l[9]+(i>>>5|V),N=0,_=N+u*G+P*(5*T)+B*(5*c)+D*(5*k)+o*(5*d);N=_>>>13,_&=8191,_+=y*(5*F)+h*(5*C)+O*(5*J)+U*(5*R)+A*(5*m),N+=_>>>13,_&=8191;let XZ=N+u*m+P*G+B*(5*T)+D*(5*c)+o*(5*k);N=XZ>>>13,XZ&=8191,XZ+=y*(5*d)+h*(5*F)+O*(5*C)+U*(5*J)+A*(5*R),N+=XZ>>>13,XZ&=8191;let mZ=N+u*R+P*m+B*G+D*(5*T)+o*(5*c);N=mZ>>>13,mZ&=8191,mZ+=y*(5*k)+h*(5*d)+O*(5*F)+U*(5*C)+A*(5*J),N+=mZ>>>13,mZ&=8191;let q=N+u*J+P*R+B*m+D*G+o*(5*T);N=q>>>13,q&=8191,q+=y*(5*c)+h*(5*k)+O*(5*d)+U*(5*F)+A*(5*C),N+=q>>>13,q&=8191;let SZ=N+u*C+P*J+B*R+D*m+o*G;N=SZ>>>13,SZ&=8191,SZ+=y*(5*T)+h*(5*c)+O*(5*k)+U*(5*d)+A*(5*F),N+=SZ>>>13,SZ&=8191;let rZ=N+u*F+P*C+B*J+D*R+o*m;N=rZ>>>13,rZ&=8191,rZ+=y*G+h*(5*T)+O*(5*c)+U*(5*k)+A*(5*d),N+=rZ>>>13,rZ&=8191;let tZ=N+u*d+P*F+B*C+D*J+o*R;N=tZ>>>13,tZ&=8191,tZ+=y*m+h*G+O*(5*T)+U*(5*c)+A*(5*k),N+=tZ>>>13,tZ&=8191;let eZ=N+u*k+P*d+B*F+D*C+o*J;N=eZ>>>13,eZ&=8191,eZ+=y*R+h*m+O*G+U*(5*T)+A*(5*c),N+=eZ>>>13,eZ&=8191;let ZX=N+u*c+P*k+B*d+D*F+o*C;N=ZX>>>13,ZX&=8191,ZX+=y*J+h*R+O*m+U*G+A*(5*T),N+=ZX>>>13,ZX&=8191;let XX=N+u*T+P*c+B*k+D*d+o*F;N=XX>>>13,XX&=8191,XX+=y*C+h*J+O*R+U*m+A*G,N+=XX>>>13,XX&=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]=q,l[4]=SZ,l[5]=rZ,l[6]=tZ,l[7]=eZ,l[8]=ZX,l[9]=XX}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;LZ(W)}update(Z){bV(this);let{buffer:X,blockLen:W}=this;Z=YW(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(){LZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){bV(this),ul(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 OK(Z){let X=(V,l)=>Z(l).update(YW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var TV=OK((Z)=>new vl(Z));function BK(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],R=X[1],J=X[2],C=X[3],F=Z[1],d=W[0],k=W[1],c=l,T=0,I=Z[2],S=X[4],Q=X[5],p=X[6],L=X[7],z=Z[3],g=G,i=m,u=R,P=J,B=C,D=F,o=d,y=k,h=c,O=T,U=I,A=S,N=Q,_=p,XZ=L,mZ=z;for(let SZ=0;SZ<K;SZ+=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),O^=x(D+i|0,7),_^=x(O+D|0,9),i^=x(_+O|0,13),D^=x(i+_|0,18),XZ^=x(U+o|0,7),u^=x(XZ+U|0,9),o^=x(u+XZ|0,13),U^=x(o+u|0,18),P^=x(mZ+A|0,7),y^=x(P+mZ|0,9),A^=x(y+P|0,13),mZ^=x(A+y|0,18),i^=x(g+P|0,7),u^=x(i+g|0,9),P^=x(u+i|0,13),g^=x(P+u|0,18),o^=x(D+B|0,7),y^=x(o+D|0,9),B^=x(y+o|0,13),D^=x(B+y|0,18),A^=x(U+O|0,7),h^=x(A+U|0,9),O^=x(h+A|0,13),U^=x(O+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 q=0;V[q++]=G+g|0,V[q++]=m+i|0,V[q++]=R+u|0,V[q++]=J+P|0,V[q++]=C+B|0,V[q++]=F+D|0,V[q++]=d+o|0,V[q++]=k+y|0,V[q++]=c+h|0,V[q++]=T+O|0,V[q++]=I+U|0,V[q++]=S+A|0,V[q++]=Q+N|0,V[q++]=p+_|0,V[q++]=L+XZ|0,V[q++]=z+mZ|0}function wK(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],R=X[3],J=Z[1],C=W[0],F=W[1],d=W[2],k=W[3],c=Z[2],T=X[4],I=X[5],S=X[6],Q=X[7],p=Z[3];for(let z=0;z<20;z+=2)R^=x(l+I|0,7),d^=x(R+l|0,9),I^=x(d+R|0,13),l^=x(I+d|0,18),k^=x(J+K|0,7),S^=x(k+J|0,9),K^=x(S+k|0,13),J^=x(K+S|0,18),Q^=x(c+C|0,7),G^=x(Q+c|0,9),C^=x(G+Q|0,13),c^=x(C+G|0,18),m^=x(p+T|0,7),F^=x(m+p|0,9),T^=x(F+m|0,13),p^=x(T+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(J+R|0,7),F^=x(C+J|0,9),R^=x(F+C|0,13),J^=x(R+F|0,18),T^=x(c+k|0,7),d^=x(T+c|0,9),k^=x(d+T|0,13),c^=x(k+d|0,18),I^=x(p+Q|0,7),S^=x(I+p|0,9),Q^=x(S+I|0,13),p^=x(Q+S|0,18);let L=0;V[L++]=l,V[L++]=J,V[L++]=c,V[L++]=p,V[L++]=C,V[L++]=F,V[L++]=d,V[L++]=k}var IV=Al(BK,{counterRight:!0,extendNonceFn:wK}),LV=Ol({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=kV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),LZ(l),IV(Z,X,V,V);let G=TV(K,l);return V.set(G,16),LZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=kV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),LZ(l);let m=IV(Z,X,l,l),R=TV(G,m);if(!il(K,R))throw Error("invalid tag");return IV(Z,X,V.subarray(16),V.subarray(16)),LZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function DK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function PX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function fZ(Z,...X){if(!DK(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 CW(Z,X){fZ(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function ol(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function kX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function cX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function jX(Z,X){return Z<<32-X|Z>>>X}var $l=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function ql(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var fl=$l?(Z)=>Z:(Z)=>ql(Z);function AK(Z){for(let X=0;X<Z.length;X++)Z[X]=ql(Z[X]);return Z}var lZ=$l?(Z)=>Z:AK;function vK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function TX(Z){if(typeof Z==="string")Z=vK(Z);return fZ(Z),Z}class QV{}function nl(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 _l=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var FW=BigInt(4294967295),al=BigInt(32);function SV(Z,X=!1){if(X)return{h:Number(Z&FW),l:Number(Z>>al&FW)};return{h:Number(Z>>al&FW)|0,l:Number(Z&FW)|0}}function xZ(Z,X,W,V,l){return Z=Z+X+l|0,V=jX(V^Z,16),W=W+V|0,X=jX(X^W,12),{a:Z,b:X,c:W,d:V}}function zZ(Z,X,W,V,l){return Z=Z+X+l|0,V=jX(V^Z,8),W=W+V|0,X=jX(X^W,7),{a:Z,b:X,c:W,d:V}}class yV extends QV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,PX(Z),PX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=kX(this.buffer)}update(Z){UX(this),Z=TX(Z),fZ(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 R=Math.min(X-this.pos,l-m),J=K+m;if(R===X&&!(J%4)&&m+R<l){let C=new Uint32Array(G,J,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+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){UX(this),CW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,cX(this.buffer.subarray(X)),lZ(W),this.compress(W,0,!0),lZ(W);let V=kX(Z);this.get().forEach((l,K)=>V[K]=fl(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 pV(Z,X,W,V,l,K,G,m,R,J,C,F,d,k,c,T,I,S,Q,p){let L=0;for(let z=0;z<V;z++)({a:l,b:R,c:d,d:I}=xZ(l,R,d,I,W[X+Z[L++]])),{a:l,b:R,c:d,d:I}=zZ(l,R,d,I,W[X+Z[L++]]),{a:K,b:J,c:k,d:S}=xZ(K,J,k,S,W[X+Z[L++]]),{a:K,b:J,c:k,d:S}=zZ(K,J,k,S,W[X+Z[L++]]),{a:G,b:C,c,d:Q}=xZ(G,C,c,Q,W[X+Z[L++]]),{a:G,b:C,c,d:Q}=zZ(G,C,c,Q,W[X+Z[L++]]),{a:m,b:F,c:T,d:p}=xZ(m,F,T,p,W[X+Z[L++]]),{a:m,b:F,c:T,d:p}=zZ(m,F,T,p,W[X+Z[L++]]),{a:l,b:J,c,d:p}=xZ(l,J,c,p,W[X+Z[L++]]),{a:l,b:J,c,d:p}=zZ(l,J,c,p,W[X+Z[L++]]),{a:K,b:C,c:T,d:I}=xZ(K,C,T,I,W[X+Z[L++]]),{a:K,b:C,c:T,d:I}=zZ(K,C,T,I,W[X+Z[L++]]),{a:G,b:F,c:d,d:S}=xZ(G,F,d,S,W[X+Z[L++]]),{a:G,b:F,c:d,d:S}=zZ(G,F,d,S,W[X+Z[L++]]),{a:m,b:R,c:k,d:Q}=xZ(m,R,k,Q,W[X+Z[L++]]),{a:m,b:R,c:k,d:Q}=zZ(m,R,k,Q,W[X+Z[L++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:d,v9:k,v10:c,v11:T,v12:I,v13:S,v14:Q,v15:p}}var QZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},NZ=_l.slice(),sl=(()=>{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 MV extends yV{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();fZ(K,32),this.IV=kX(K),lZ(this.IV),this.flags=X|QZ.KEYED_HASH}else if(l){let K=TX(V),G=new MV({dkLen:32},QZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=kX(G),lZ(this.IV),this.flags=X|QZ.DERIVE_KEY_MATERIAL}else this.IV=NZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=ol(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=SV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:d,v5:k,v6:c,v7:T,v8:I,v9:S,v10:Q,v11:p,v12:L,v13:z,v14:g,v15:i}=pV(sl,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],NZ[0],NZ[1],NZ[2],NZ[3],G,m,K,X);l[0]=R^I,l[1]=J^S,l[2]=C^Q,l[3]=F^p,l[4]=d^L,l[5]=k^z,l[6]=c^g,l[7]=T^i}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:R}=this;return Z.state.set(V.slice()),Z.stack=m.map((J)=>Uint32Array.from(J)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=R,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,cX(this.state,this.buffer32,this.IV,this.bufferOut32),cX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=SV(BigInt(this.chunkOut++));lZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:d,v6:k,v7:c,v8:T,v9:I,v10:S,v11:Q,v12:p,v13:L,v14:z,v15:g}=pV(sl,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],NZ[0],NZ[1],NZ[2],NZ[3],G,K,X,W);l[0]=m^T,l[1]=R^I,l[2]=J^S,l[3]=C^Q,l[4]=F^p,l[5]=d^L,l[6]=k^z,l[7]=c^g,l[8]=Z[0]^T,l[9]=Z[1]^I,l[10]=Z[2]^S,l[11]=Z[3]^Q,l[12]=Z[4]^p,l[13]=Z[5]^L,l[14]=Z[6]^z,l[15]=Z[7]^g,lZ(V),lZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,cX(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),fZ(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 PX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(CW(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 rl=nl((Z)=>new MV(Z));var oK=32,fF=Symbol("X25519Sk");function tl(Z){if(Z.byteLength!==oK)return Y(10);return b(Z)}var w=(1n<<255n)-19n,$K=121665n,el=new Uint8Array(32);el[0]=9;function Z0(Z){let X=0n;for(let W=Z.length-1;W>=0;W--)X=X<<8n|BigInt(Z[W]);return X}function qK(Z){let X=new Uint8Array(32),W=(Z%w+w)%w;for(let V=0;V<32;V++)X[V]=Number(W&0xffn),W>>=8n;return X}function fK(Z){let X=Z.slice();return X[31]&=127,Z0(X)}function nK(Z){let X=Z.slice();return X[0]&=248,X[31]&=127,X[31]|=64,X}function bW(Z,X,W){let V=-Z,l=(X^W)&V;return[X^l,W^l]}function _K(Z){let X=w-2n,W=(Z%w+w)%w,V=1n;while(X>0n){if(X&1n)V=V*W%w;W=W*W%w,X>>=1n}return V}function aK(Z,X){let W=nK(Z),V=fK(X),l=1n,K=0n,G=V,m=1n,R=0n,J=Z0(W);for(let C=254;C>=0;C--){let F=J>>BigInt(C)&1n;R^=F,[l,G]=bW(R,l,G),[K,m]=bW(R,K,m),R=F;let d=(l+K)%w,k=d*d%w,c=(l-K+w)%w,T=c*c%w,I=(k-T+w)%w,S=(G+m)%w,p=(G-m+w)%w*d%w,L=S*c%w,z=(p+L)%w,g=(p-L+w)%w;G=z*z%w,m=V*g*g%w,l=k*T%w,K=I*(k+$K*I)%w}return[l,G]=bW(R,l,G),[K,m]=bW(R,K,m),W.fill(0),qK(l*_K(K)%w)}function X0(Z){return aK(Z,el)}var xV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function W0(Z){let X=new Uint8Array(xV.length+32);return X.set(xV),X.set(Z.subarray(0,32),xV.length),X}var zV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);function V0(Z){let X=new Uint8Array(zV.length+32);return X.set(zV),X.set(Z.subarray(0,32),zV.length),X}function l0(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function HZ(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class nZ{verifyKeys=new Map;async genRandomBytes(Z){return hX(Z)}async gen256BitSecureRandomSeed(){return hX(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=hX(24),l=LV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return LV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=W0(X),V=HZ(W),l;try{let J=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",J)}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 R=new Uint8Array(64);return R.set(X,0),R.set(m,32),{keyType:"ed25519",privateKey:R,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=W0(X),V=HZ(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",HZ(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=l0(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,HZ(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=l0(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,HZ(Z),HZ(V))}catch{return!1}}async blake3(Z){return rl(Z)}async genX25519(){let Z=await hX(32);Z[0]&=248,Z[31]&=127,Z[31]|=64;let[X,W]=tl(Z);if(W!==0||X===void 0)throw Z.fill(0),Error("X25519 scalar brand failed");let V=X0(X),l=V0(X),K=HZ(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 R=BW(m.x);if(m.d=void 0,!n(R,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=V0(Z),V=HZ(W);try{let l=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"X25519"},!1,["deriveBits"]),K=await globalThis.crypto.subtle.importKey("raw",HZ(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 sK=new nZ,IX=sK;import{useEffect as PW,useState as oV}from"react";class NV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(CZ,"readwrite"),V=W.objectStore(CZ);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(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=`${Z}:${m}`;l.delete(R)}})}async list(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);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(CZ,"readonly").objectStore(CZ);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(CZ,"readwrite"),X=Z.objectStore(CZ);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 rK(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 HV{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(rK(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 gV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction($,"readwrite"),W=X.objectStore($);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],R=H(G),J=W.put(m,R);J.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);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($,"readonly").objectStore($);return new Promise((V,l)=>{let K=H(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await iZ(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($,"readonly").objectStore($);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(uX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.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})=>iZ(F,d,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(uX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction($,"readonly").objectStore($);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($,"readonly").objectStore($);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let R=m.target.result;if(R){let{key:J,value:C}=R;if(n(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:J,data:C}}R.continue()}else if(K){let J=e(K.key);V(await iZ(J,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($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=H(G),R=V.get(m);R.onsuccess=()=>{let J=R.result;if(!J)return;$Z(J,EZ),V.put(J,m)},R.onerror=(J)=>{J.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let R=H(G),J=V.get(R);J.onsuccess=()=>{let C=J.result;if(!C)return;$Z(C,IZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction($,"readwrite"),X=Z.objectStore($);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var _Z={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 dW=1,hV={encode(Z,X){if(X.v!==dW)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(_Z,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==dW)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,R]=Z.readVarInt();if(R!==0)return Y(R);if(m===void 0||m<0)return Y(10);let J=[];for(let C=0;C<m;C++){let[F,d]=Z.readStruct(_Z);if(d!==0)return Y(d);if(F===void 0)return Y(14);J.push(F)}return b({v:dW,masterSeed:K,hosts:J})}};function G0(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:dW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var kW={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(_Z,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 R=0;R<K;R++){let[J,C]=Z.readStruct(_Z);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return b({masterSeed:V,hosts:m})}};var tK=new TextEncoder().encode("diplomatic.qrpair.v1"),EX=32,eK=EX+24+16,ZG=32,D5=Symbol("DHKEReq"),A5=Symbol("DHKEResp");function PV(Z){if(Z.byteLength!==EX)return Y(10);return b(Z)}function UV(Z){if(Z.byteLength<eK)return Y(10);return b(Z)}var cW=new nZ;async function jV(Z,X,W,V){let l;try{l=await cW.x25519Shared(Z,X)}catch{return Y(29)}try{if(l.byteLength!==EX||l.every((m)=>m===0))return Y(10);let K=TZ(l,tK),G=TZ(K,TZ(W,V));try{let m=await cW.blake3(G);return b(m.slice(0,ZG))}finally{K.fill(0),G.fill(0)}}finally{l.fill(0)}}class iX{#Z;#X;constructor(Z,X){this.#Z=Z,this.#X=X}static async create(){let Z;try{let X=await cW.genX25519();Z=X.priv;let[W,V]=PV(X.pub);if(V!==0)return Y(V);if(W===void 0)return Y(10);let l=new iX(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]=PV(this.#X.slice());if(Z===void 0)throw Error(`dhkeReq ${X}`);return Z}async finish(Z){let X=Z.subarray(0,EX),W=Z.subarray(EX),[V,l]=await jV(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 cW.decryptXSalsa20Poly1305Combined(W,V)}catch{return Y(20)}let G=new j(K),[m,R]=G.readStruct(kW);if(R!==0)return Y(R);if(m===void 0)return Y(14);try{let[J,C]=ZZ.fromBytes(m.masterSeed);if(C!==0)return Y(C);if(J===void 0)return Y(12);return this.wipe(),b({enclave:J,hosts:m.hosts.map((F)=>({...F}))})}finally{m.masterSeed.fill(0)}}finally{V.fill(0),K?.fill(0)}}}function gZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var OZ=32,m0=-7,Y0=-8,R0=-257,OX=[{type:"public-key",alg:m0},{type:"public-key",alg:Y0},{type:"public-key",alg:R0}];function TW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function BZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function J0(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function wZ(Z){if(Z?.rpId!==void 0)return b(Z.rpId);if(typeof location>"u")return Y(9);return b(TW(location.hostname))}var uV="";function XG(){return uV}function aZ(Z){if(Z instanceof Error){uV=Z.message===""?Z.name:`${Z.name}: ${Z.message}`;return}uV=String(Z)}function DZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function AZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return b(Z)}async function BX(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 C0(){return BX("extension:largeBlob")}async function IW(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(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:gZ(OZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:OX,authenticatorSelection:K,extensions:G,...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch(F){return aZ(F),Y(30)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(30);return b(new Uint8Array(R.rawId))}async function wX(Z,X,W){let V=DZ();if(V!==0)return V;let[l,K]=wZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:BZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:gZ(OZ),rpId:l,allowCredentials:[{type:"public-key",id:BZ(Z)}],userVerification:"required",extensions:G,...W?.hints!==void 0?{hints:W.hints}:{}}})}catch(F){return aZ(F),30}let[R,J]=AZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 30;return 0}async function EV(Z,X,W,V){let l={challenge:gZ(OZ),rpId:Z,userVerification:"preferred"};if(X?.hints!==void 0)l.hints=X.hints;if(W!==void 0)l.allowCredentials=[{type:"public-key",id:BZ(W)}];if(V!==void 0)l.extensions=V;let K;try{K=await navigator.credentials.get({publicKey:l})}catch(R){return aZ(R),Y(30)}let[G,m]=AZ(K);if(m!==0)return Y(m);if(G===void 0)return Y(27);return b(G)}async function LW(Z,X){let W=DZ();if(W!==0)return Y(W);let[V,l]=wZ(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 EV(V,X);if(d!==0&&X?.hints!==void 0)[F,d]=await EV(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 EV(V,X,K,{largeBlob:{read:!0}});if(m!==0)return Y(m);if(G===void 0)return Y(27);let J=G.getClientExtensionResults().largeBlob;if(J===void 0||J.blob===void 0)return Y(7);let C=J0(J.blob);if(C.byteLength===0)return Y(7);return b({blob:C,credId:new Uint8Array(G.rawId)})}var QW=new TextEncoder().encode("diplomatic.prf.v1"),iV=32;async function WG(){return BX("extension:prf")}async function F0(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-prf",K=Z?.authenticatorAttachment==="cross-platform",G={residentKey:K?"discouraged":"required",requireResidentKey:!K,userVerification:K?"preferred":"required"};if(Z?.authenticatorAttachment!==void 0)G.authenticatorAttachment=Z.authenticatorAttachment;let m;try{m=await navigator.credentials.create({publicKey:{challenge:gZ(OZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:OX,authenticatorSelection:G,extensions:{prf:{}},...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch(F){return aZ(F),Y(30)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults();return b({credId:new Uint8Array(R.rawId),prfEnabled:C.prf?.enabled===!0})}async function OV(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??QW,K=BZ(l),G={challenge:gZ(OZ),rpId:W,userVerification:"preferred",extensions:{prf:{eval:{first:K}}}};if(Z?.hints!==void 0)G.hints=Z.hints;if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:BZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch(c){return aZ(c),Y(30)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults().prf?.results;if(C?.first===void 0)return Y(7);let F=C.first,d=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),k=d.byteLength>=iV?d.slice(0,iV):d;if(k.byteLength!==iV)return Y(27);return b({prf:k,credId:new Uint8Array(R.rawId)})}var SW="dmFyIEEwPTY0O3ZhciBIWj0zMixfMD04O3ZhciBQJD0zMjt2YXIgcVo9MzAwMDAsTVo9NTEyLEQ7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIjt3W3cuQ3J5cHRvRXJyb3I9MjldPSJDcnlwdG9FcnJvciI7d1t3LldlYkF1dGhuRXJyb3I9MzBdPSJXZWJBdXRobkVycm9yIn0pKER8fD17fSk7ZnVuY3Rpb24gSVooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIENaKCQpe2xldCBKPSQubGVuZ3RoLFo9MCxRPTA7d2hpbGUoUTxKKXtsZXQgWT0kLmNoYXJDb2RlQXQoUSsrKTtpZigoWSY0Mjk0OTY3MTY4KT09PTApe1orKztjb250aW51ZX1lbHNlIGlmKChZJjQyOTQ5NjUyNDgpPT09MClaKz0yO2Vsc2V7aWYoWT49NTUyOTYmJlk8PTU2MzE5KXtpZihRPEope2xldCBWPSQuY2hhckNvZGVBdChRKTtpZigoViY2NDUxMik9PT01NjMyMCkrK1EsWT0oKFkmMTAyMyk8PDEwKSsoViYxMDIzKSs2NTUzNn19aWYoKFkmNDI5NDkwMTc2MCk9PT0wKVorPTM7ZWxzZSBaKz00fX1yZXR1cm4gWn1mdW5jdGlvbiBRWSgkLEosWil7bGV0IFE9JC5sZW5ndGgsWT1aLFY9MDt3aGlsZShWPFEpe2xldCBYPSQuY2hhckNvZGVBdChWKyspO2lmKChYJjQyOTQ5NjcxNjgpPT09MCl7SltZKytdPVg7Y29udGludWV9ZWxzZSBpZigoWCY0Mjk0OTY1MjQ4KT09PTApSltZKytdPVg+PjYmMzF8MTkyO2Vsc2V7aWYoWD49NTUyOTYmJlg8PTU2MzE5KXtpZihWPFEpe2xldCBXPSQuY2hhckNvZGVBdChWKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1YsWD0oKFgmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFgmNDI5NDkwMTc2MCk9PT0wKUpbWSsrXT1YPj4xMiYxNXwyMjQsSltZKytdPVg+PjYmNjN8MTI4O2Vsc2UgSltZKytdPVg+PjE4Jjd8MjQwLEpbWSsrXT1YPj4xMiY2M3wxMjgsSltZKytdPVg+PjYmNjN8MTI4fUpbWSsrXT1YJjYzfDEyOH19dmFyIFlZPW5ldyBUZXh0RW5jb2RlcixWWT01MDtmdW5jdGlvbiBYWSgkLEosWil7WVkuZW5jb2RlSW50bygkLEouc3ViYXJyYXkoWikpfWZ1bmN0aW9uIFBaKCQsSixaKXtpZigkLmxlbmd0aD5WWSlYWSgkLEosWik7ZWxzZSBRWSgkLEosWil9dmFyIFdZPTQwOTY7ZnVuY3Rpb24gVkooJCxKLFope2xldCBRPUosWT1RK1osVj1bXSxYPSIiO3doaWxlKFE8WSl7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVYucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztWLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1YucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTj0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE4+NjU1MzUpTi09NjU1MzYsVi5wdXNoKE4+Pj4xMCYxMDIzfDU1Mjk2KSxOPTU2MzIwfE4mMTAyMztWLnB1c2goTil9ZWxzZSBWLnB1c2goVyk7aWYoVi5sZW5ndGg+PVdZKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uViksVi5sZW5ndGg9MH1pZihWLmxlbmd0aD4wKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uVik7cmV0dXJuIFh9dmFyIEdZPW5ldyBUZXh0RGVjb2Rlcix6WT0yMDA7ZnVuY3Rpb24gS1koJCxKLFope2xldCBRPSQuc3ViYXJyYXkoSixKK1opO3JldHVybiBHWS5kZWNvZGUoUSl9ZnVuY3Rpb24gd1ooJCxKLFope2lmKFo+elkpcmV0dXJuIEtZKCQsSixaKTtlbHNlIHJldHVybiBWSigkLEosWil9Y2xhc3MgbzB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsSil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPUp9fWNsYXNzIGUgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgSj1PYmplY3QuY3JlYXRlKGUucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxKKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOmUubmFtZX0pfX12YXIgYTA9NDI5NDk2NzI5NTtmdW5jdGlvbiBUWigkLEosWil7bGV0IFE9Wi80Mjk0OTY3Mjk2LFk9WjskLnNldFVpbnQzMihKLFEpLCQuc2V0VWludDMyKEorNCxZKX1mdW5jdGlvbiB3JCgkLEosWil7bGV0IFE9TWF0aC5mbG9vcihaLzQyOTQ5NjcyOTYpLFk9WjskLnNldFVpbnQzMihKLFEpLCQuc2V0VWludDMyKEorNCxZKX1mdW5jdGlvbiBUJCgkLEope2xldCBaPSQuZ2V0SW50MzIoSiksUT0kLmdldFVpbnQzMihKKzQpO3JldHVybiBaKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBqWigkLEope2xldCBaPSQuZ2V0VWludDMyKEopLFE9JC5nZXRVaW50MzIoSis0KTtyZXR1cm4gWio0Mjk0OTY3Mjk2K1F9dmFyIEZZPS0xLE5ZPTQyOTQ5NjcyOTUsT1k9MTcxNzk4NjkxODM7ZnVuY3Rpb24gVVkoe3NlYzokLG5zZWM6Sn0pe2lmKCQ+PTAmJko+PTAmJiQ8PU9ZKWlmKEo9PT0wJiYkPD1OWSl7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksWn1lbHNle2xldCBaPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxZPW5ldyBVaW50OEFycmF5KDgpLFY9bmV3IERhdGFWaWV3KFkuYnVmZmVyKTtyZXR1cm4gVi5zZXRVaW50MzIoMCxKPDwyfFomMyksVi5zZXRVaW50MzIoNCxRKSxZfWVsc2V7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KFouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxKKSx3JChRLDQsJCksWn19ZnVuY3Rpb24gUlkoJCl7bGV0IEo9JC5nZXRUaW1lKCksWj1NYXRoLmZsb29yKEovMTAwMCksUT0oSi1aKjEwMDApKjFlNixZPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6WitZLG5zZWM6US1ZKjFlOX19ZnVuY3Rpb24gSFkoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBKPVJZKCQpO3JldHVybiBVWShKKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIHFZKCQpe2xldCBKPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBaPUouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOlosbnNlYzowfX1jYXNlIDg6e2xldCBaPUouZ2V0VWludDMyKDApLFE9Si5nZXRVaW50MzIoNCksWT0oWiYzKSo0Mjk0OTY3Mjk2K1EsVj1aPj4+MjtyZXR1cm57c2VjOlksbnNlYzpWfX1jYXNlIDEyOntsZXQgWj1UJChKLDQpLFE9Si5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpaLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgZShgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uIE1ZKCQpe2xldCBKPXFZKCQpO3JldHVybiBuZXcgRGF0ZShKLnNlYyoxMDAwK0oubnNlYy8xZTYpfXZhciBEWj17dHlwZTpGWSxlbmNvZGU6SFksZGVjb2RlOk1ZfTtjbGFzcyBzMHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyBzMDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKERaKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpKLGRlY29kZTpafSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPUosdGhpcy5kZWNvZGVyc1skXT1aO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1KLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPVp9fXRyeVRvRW5jb2RlKCQsSil7Zm9yKGxldCBaPTA7Wjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7WisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1taXTtpZihRIT1udWxsKXtsZXQgWT1RKCQsSik7aWYoWSE9bnVsbCl7bGV0IFY9LTEtWjtyZXR1cm4gbmV3IG8wKFYsWSl9fX1mb3IobGV0IFo9MDtaPHRoaXMuZW5jb2RlcnMubGVuZ3RoO1orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1taXTtpZihRIT1udWxsKXtsZXQgWT1RKCQsSik7aWYoWSE9bnVsbClyZXR1cm4gbmV3IG8wKFosWSl9fWlmKCQgaW5zdGFuY2VvZiBvMClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxKLFope2xldCBRPUo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1KXTp0aGlzLmRlY29kZXJzW0pdO2lmKFEpcmV0dXJuIFEoJCxKLFopO2Vsc2UgcmV0dXJuIG5ldyBvMChKLCQpfX1mdW5jdGlvbiBJWSgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gRyQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYoSVkoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgQ1k9MTAwLFBZPTIwNDg7Y2xhc3MgaiR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9zMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/Q1ksdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/UFksdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBqJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLEope2lmKEo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke0p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsSil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IEo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxKKXRoaXMucmVzaXplQnVmZmVyKEoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBKPW5ldyBBcnJheUJ1ZmZlcigkKSxaPW5ldyBVaW50OEFycmF5KEopLFE9bmV3IERhdGFWaWV3KEopO1ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Wn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBaPUNaKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStaKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKFopLFBaKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPVp9ZW5jb2RlT2JqZWN0KCQsSil7bGV0IFo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoWiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihaKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLEopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLEopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IEo9JC5ieXRlTGVuZ3RoO2lmKEo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChKKTtlbHNlIGlmKEo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihKKTtlbHNlIGlmKEo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKEopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Sn1gKTtsZXQgWj1HJCgkKTt0aGlzLndyaXRlVThhKFopfWVuY29kZUFycmF5KCQsSil7bGV0IFo9JC5sZW5ndGg7aWYoWjwxNil0aGlzLndyaXRlVTgoMTQ0K1opO2Vsc2UgaWYoWjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KFopO2Vsc2UgaWYoWjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoWik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke1p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLEorMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsSil7bGV0IFo9MDtmb3IobGV0IFEgb2YgSilpZigkW1FdIT09dm9pZCAwKVorKztyZXR1cm4gWn1lbmNvZGVNYXAoJCxKKXtsZXQgWj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKVouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsWik6Wi5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFkgb2YgWil7bGV0IFY9JFtZXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZWPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhZKSx0aGlzLmRvRW5jb2RlKFYsSisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgWj0kLmRhdGEodGhpcy5wb3MrNiksUT1aLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShaKTtyZXR1cm59bGV0IEo9JC5kYXRhLmxlbmd0aDtpZihKPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKEo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoSj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihKPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKEo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKEo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChKKTtlbHNlIGlmKEo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihKKTtlbHNlIGlmKEo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKEopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke0p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgSj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKEopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1KfXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksVFoodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdyQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBrMCgkLEope3JldHVybiBuZXcgaiQoSikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIEQkKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgd1k9MTYsVFk9MTY7Y2xhc3MgWEp7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9d1ksSj1UWSl7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1KLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgWj0wO1o8dGhpcy5tYXhLZXlMZW5ndGg7WisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxKLFope2xldCBRPXRoaXMuY2FjaGVzW1otMV07JDpmb3IobGV0IFkgb2YgUSl7bGV0IFY9WS5ieXRlcztmb3IobGV0IFg9MDtYPFo7WCsrKWlmKFZbWF0hPT0kW0orWF0pY29udGludWUgJDtyZXR1cm4gWS5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxKKXtsZXQgWj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpKfTtpZihaLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpWltNYXRoLnJhbmRvbSgpKloubGVuZ3RofDBdPVE7ZWxzZSBaLnB1c2goUSl9ZGVjb2RlKCQsSixaKXtsZXQgUT10aGlzLmZpbmQoJCxKLFopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgWT1WSigkLEosWiksVj1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsSixKK1opO3JldHVybiB0aGlzLnN0b3JlKFYsWSksWX19dmFyIFdKPSJhcnJheSIsSyQ9Im1hcF9rZXkiLF9aPSJtYXBfdmFsdWUiLGpZPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IGUoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyBMWntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgSj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Si50eXBlPVdKLEoucG9zaXRpb249MCxKLnNpemU9JCxKLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgSj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Si50eXBlPUskLEoucmVhZENvdW50PTAsSi5zaXplPSQsSi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1XSil7bGV0IFo9JDtaLnNpemU9MCxaLmFycmF5PXZvaWQgMCxaLnBvc2l0aW9uPTAsWi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1LJHx8JC50eXBlPT09X1ope2xldCBaPSQ7Wi5zaXplPTAsWi5tYXA9dm9pZCAwLFoucmVhZENvdW50PTAsWi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciB6JD0tMSxHSj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSxEWT1uZXcgVWludDhBcnJheShHSi5idWZmZXIpO3RyeXtHSi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBBWj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLEFZPW5ldyBYSjtjbGFzcyBBJHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1HSjtieXRlcz1EWTtoZWFkQnl0ZT16JDtzdGFjaz1uZXcgTFo7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9zMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/YTAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9hMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9hMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P2EwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/YTAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOkFZLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/all9Y2xvbmUoKXtyZXR1cm4gbmV3IEEkKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPXokLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IEo9RyQoJCk7dGhpcy5ieXRlcz1KLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoSi5idWZmZXIsSi5ieXRlT2Zmc2V0LEouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PXokJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgSj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxaPUckKCQpLFE9bmV3IFVpbnQ4QXJyYXkoSi5sZW5ndGgrWi5sZW5ndGgpO1Euc2V0KEopLFEuc2V0KFosSi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OkoscG9zOlp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Si5ieXRlTGVuZ3RoLVp9IG9mICR7Si5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IEo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gSn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBKPSExLFo7Zm9yIGF3YWl0KGxldCBYIG9mICQpe2lmKEopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoWCk7dHJ5e1o9dGhpcy5kb0RlY29kZVN5bmMoKSxKPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoSil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gWn1sZXR7aGVhZEJ5dGU6USxwb3M6WSx0b3RhbFBvczpWfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHtEJChRKX0gYXQgJHtWfSAoJHtZfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLEope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxKKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgWj1KLFE9LTE7Zm9yIGF3YWl0KGxldCBZIG9mICQpe2lmKEomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoWSksWilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLFo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goVil7aWYoIShWIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgVn10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksSjtpZigkPj0yMjQpSj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KUo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNle2xldCBRPSQtMTYwO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpSj1udWxsO2Vsc2UgaWYoJD09PTE5NClKPSExO2Vsc2UgaWYoJD09PTE5NSlKPSEwO2Vsc2UgaWYoJD09PTIwMilKPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylKPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClKPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KUo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KUo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpSj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgSj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpSj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlKPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClKPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KUo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIEo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO0o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtKPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpSj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpSj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Sj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IGUoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7RCQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBaPXRoaXMuc3RhY2s7d2hpbGUoWi5sZW5ndGg+MCl7bGV0IFE9Wi50b3AoKTtpZihRLnR5cGU9PT1XSilpZihRLmFycmF5W1EucG9zaXRpb25dPUosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpSj1RLmFycmF5LFoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1LJCl7aWYoSj09PSJfX3Byb3RvX18iKXRocm93IG5ldyBlKCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKEopLFEudHlwZT1fWjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPUosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlKPVEubWFwLFoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPUskO2NvbnRpbnVlICR9fXJldHVybiBKfX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09eiQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT16JH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyBlKGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke0QkKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsSil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLEopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLEopfWRlY29kZVV0ZjhTdHJpbmcoJCxKKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyBlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytKKyQpdGhyb3cgQVo7bGV0IFo9dGhpcy5wb3MrSixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLFosJCk7ZWxzZSBRPXdaKHRoaXMuYnl0ZXMsWiwkKTtyZXR1cm4gdGhpcy5wb3MrPUorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1LJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxKKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyBlKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrSikpdGhyb3cgQVo7bGV0IFo9dGhpcy5wb3MrSixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoWixaKyQpO3JldHVybiB0aGlzLnBvcys9SiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsSil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBaPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK0opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxKKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLFosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPWpaKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPVQkKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIHpKKCQsSil7cmV0dXJuIG5ldyBBJChKKS5kZWNvZGUoJCl9Y2xhc3MgRiR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLEope2xldCBaPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighWilaPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsWik7cmV0dXJuIFouYWRkKEopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsSil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoWil7aWYoWi5kZWxldGUoSiksWi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoWil7bGV0IFE9QXJyYXkuZnJvbShaKTtmb3IobGV0IFkgb2YgUSlZKEopfX1lbWl0QWxsKCQpe2xldCBKPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IFogb2YgSil0aGlzLmVtaXQoWiwkKX19Y2xhc3MgZjB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgRiR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdChmMC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoZjAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoZjAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gTygkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gX1koJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IEo9W107d2hpbGUoJD4wbil7bGV0IFo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKUoucHVzaChafDEyOCk7ZWxzZSBKLnB1c2goWil9aWYoSi5sZW5ndGg9PT0wKXJldHVybiBPKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKEoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBPKG5ldyBVaW50OEFycmF5KEopKX1mdW5jdGlvbiBMWSgkLEo9MCl7bGV0IFo9MG4sUT0wLFk9Sjt3aGlsZSghMCl7aWYoWT49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBWPSRbWSsrXTtpZihWPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihafD1CaWdJbnQoViYxMjcpPDxCaWdJbnQoUSksKFYmMTI4KT09PTApe2lmKFktSj44KXJldHVybiBHKDI2KTtyZXR1cm4gTyh7dmFsdWU6Wj4weDFmZmZmZmZmZmZmZmZmbj9aOk51bWJlcihaKSxieXRlc1JlYWQ6WS1KfSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIG17ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBKPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxaPW5ldyBVaW50OEFycmF5KEopO3JldHVybiBuZXcgbShaKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LE8oJCl9cmVhZERhdGUoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gTyhuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLEpdPUxZKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoSiE9PTApcmV0dXJuIEcoSik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBaPSQudmFsdWU7cmV0dXJuIE8odHlwZW9mIFo9PT0iYmlnaW50Ij9OdW1iZXIoWik6Wil9cmVhZFZhclN0cmluZygpe2xldFskLEpdPXRoaXMucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtaLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBZPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShaKTtyZXR1cm4gTyhZKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBKPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsTyhKKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IEo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbWixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Si5wdXNoKFopfXJldHVybiBPKEopfXJlYWRCeXRlc1NlcSgkKXtsZXQgSj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtaLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO0oucHVzaChaKX1yZXR1cm4gTyhKKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBKPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKEopfXdyaXRlRGF0ZSgkKXtsZXQgSj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChKKX13cml0ZVZhckludCgkKXtsZXRbSixaXT1fWSgkKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKEopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IEo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLFo9dGhpcy53cml0ZVZhckludChKLmxlbmd0aCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhKKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJC5zbGljZSgpKX13cml0ZUJ5dGVzKCQpe3RoaXMucGFydHMucHVzaCgkLnNsaWNlKCkpfXdyaXRlVmFyQnl0ZXMoJCl7bGV0IEo9dGhpcy53cml0ZVZhckludCgkLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcygkKSwwfXdyaXRlU3RydWN0KCQsSil7cmV0dXJuICQuZW5jb2RlKHRoaXMsSil9d3JpdGVTdHJ1Y3RzKCQsSil7Zm9yKGxldCBaIG9mIEope2xldCBRPXRoaXMud3JpdGVTdHJ1Y3QoJCxaKTtpZihRIT09MClyZXR1cm4gUX1yZXR1cm4gMH13cml0ZUJ5dGVzU2VxKCQpe2ZvcihsZXQgSiBvZiAkKXRoaXMud3JpdGVCeXRlcyhKKX1yZXN1bHQoKXtsZXQgJD10aGlzLnBhcnRzLnJlZHVjZSgoUSxZKT0+UStZLmxlbmd0aCwwKSxKPW5ldyBVaW50OEFycmF5KCQpLFo9MDtmb3IobGV0IFEgb2YgdGhpcy5wYXJ0cylKLnNldChRLFopLForPVEubGVuZ3RoO3JldHVybiBKfXdpcGUoKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cykkLmZpbGwoMCk7dGhpcy5wYXJ0cy5sZW5ndGg9MH0qc2Nhbigpe2ZvcihsZXQgJCBvZiB0aGlzLnBhcnRzKXlpZWxkICR9fWFzeW5jIGZ1bmN0aW9uIEtKKCQsSil7bGV0IFo9bmV3IFMsUT1aLndyaXRlRGF0ZShKKTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgWT1aLnJlc3VsdCgpLFY9YXdhaXQgJC5zaWduKFkpO3JldHVybiBPKHtwdWJLZXk6JC5wdWJsaWNLZXksc2lnOlYsdGltZXN0YW1wOkp9KX1hc3luYyBmdW5jdGlvbiBMMCgkLEosWil7bGV0IFE9Wi5ub3coKS5nZXRUaW1lKCksWT0kLnRpbWVzdGFtcC5nZXRUaW1lKCk7aWYoTWF0aC5hYnMoUS1ZKT5xWilyZXR1cm4gNDtsZXQgWD1uZXcgUztYLndyaXRlRGF0ZSgkLnRpbWVzdGFtcCk7bGV0IFc9WC5yZXN1bHQoKTtpZighYXdhaXQgSi5jaGVja1NpZ0VkMjU1MTkoJC5zaWcsVywkLnB1YktleSkpcmV0dXJuIDM7cmV0dXJuIDB9dmFyIFYwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5pZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZURhdGUoSi50cyk7aWYoUSE9PTApcmV0dXJuIFE7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJCeXRlcygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZERhdGUoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyh7aWQ6Six0czpRfSl9fTtmdW5jdGlvbiBfJCgkKXtsZXQgSj1uZXcgUyxaPUoud3JpdGVTdHJ1Y3QoVjAsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9Si5yZXN1bHQoKTtyZXR1cm4gTyhRKX12YXIgRzA9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmVpZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLm9mZik7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9JC53cml0ZVZhckludChKLmN0cik7aWYoWSE9PTApcmV0dXJuIFk7bGV0IFY9JC53cml0ZVZhckludChKLmxlbik7aWYoViE9PTApcmV0dXJuIFY7aWYoSi5oc2gpJC53cml0ZUJ5dGVzKEouaHNoKTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckJ5dGVzKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9bmV3IG0oSiksWyxZXT1WMC5kZWNvZGUoUSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1csel09JC5yZWFkVmFySW50KCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkVmFySW50KCk7aWYoRiE9PTApcmV0dXJuIEcoRik7bGV0IE47aWYoSz4wKXtsZXRbVSxSXT0kLnJlYWRCeXRlcyhQJCk7aWYoUiE9PTApcmV0dXJuIEcoUik7Tj1VfXJldHVybiBPKHtlaWQ6SixvZmY6VixjdHI6VyxsZW46Syxoc2g6Tn0pfX07ZnVuY3Rpb24gVTAoJCl7cmV0dXJuIEFycmF5LmZyb20oJCkubWFwKChaKT0+Wi50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX1mdW5jdGlvbiB4WigkKXtpZigkLmxlbmd0aCUyIT09MCl0aHJvdyBFcnJvcigiSW52YWxpZCBoZXggc3RyaW5nIik7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoJC5sZW5ndGgvMik7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKz0yKUpbWi8yXT1OdW1iZXIucGFyc2VJbnQoJC5zdWJzdHIoWiwyKSwxNik7cmV0dXJuIEp9ZnVuY3Rpb24gcigkLEope2lmKCQ9PT1KKXJldHVybiEwO2lmKCQuYnl0ZUxlbmd0aCE9PUouYnl0ZUxlbmd0aClyZXR1cm4hMTtyZXR1cm4gJC5ldmVyeSgoWixRKT0+Wj09PUpbUV0pfXZhciBCO2lmKHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS50b0Jhc2U2ND09PSJmdW5jdGlvbiIpQj0oJCk9PiQudG9CYXNlNjQoKTtlbHNlIEI9KCQpPT5idG9hKFN0cmluZy5mcm9tQ2hhckNvZGUoLi4uJCkpO3ZhciBOMDtpZih0eXBlb2YgVWludDhBcnJheS5mcm9tQmFzZTY0PT09ImZ1bmN0aW9uIilOMD0oJCk9PlVpbnQ4QXJyYXkuZnJvbUJhc2U2NCgkKTtlbHNlIE4wPSgkKT0+VWludDhBcnJheS5mcm9tKGF0b2IoJCksKEopPT5KLmNoYXJDb2RlQXQoMCkpO2Z1bmN0aW9uIEJaKCQpe2xldCBKPSQubGVuZ3RoJTQ9PT0wPyIiOiI9Ii5yZXBlYXQoNC0kLmxlbmd0aCU0KSxaPSQucmVwbGFjZSgvLS9nLCIrIikucmVwbGFjZSgvXy9nLCIvIikrSjtyZXR1cm4gTjAoWil9ZnVuY3Rpb24gUjAoJCxKKXtsZXQgWj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtKLmxlbmd0aCk7cmV0dXJuIFouc2V0KCQsMCksWi5zZXQoSiwkLmxlbmd0aCksWn1mdW5jdGlvbiBrWigkLEosWil7cmV0dXJuIFouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxKKX1hc3luYyBmdW5jdGlvbiBmWigkLEosWixRKXtsZXQgWTtpZigkLmJvZCYmJC5sZW4+MClZPWF3YWl0IFouYmxha2UzKCQuYm9kKTtsZXQgVj1uZXcgUyxYPUcwLmVuY29kZShWLHsuLi4kLGhzaDpZfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFc9Vi5yZXN1bHQoKSx6PWF3YWl0IEoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE49JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxVPWF3YWl0IEouc2lnbihGKTtyZXR1cm4gTyh7c2lnOlUsa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6Tn0pfWFzeW5jIGZ1bmN0aW9uIEZKKCQsSixaLFEsWSl7bGV0IFY9bmV3IG0oJCksW1gsV109RzAuZGVjb2RlKFYpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1KJiZKLmxlbmd0aD4wP2F3YWl0IFouZGVjcnlwdChKKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVguaHNoJiZ6PT09dm9pZCAwLEY9WC5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoWC5oc2gmJnope2xldCBVPWF3YWl0IFEuYmxha2UzKHopO2lmKCFyKFUsWC5oc2gpKXJldHVybiBHKDE5KX1sZXQgTj1ZPz9hd2FpdCBRLmJsYWtlMygkKTtyZXR1cm4gTyh7bXNnSGVhZDpYLGJvZDp6LGhlYWRIYXNoOk59KX1jbGFzcyBOSntub3coKXtyZXR1cm4gbmV3IERhdGV9fWZ1bmN0aW9uIEVaKCQsSixaLFEpe2xldCBZPUouZ2V0VGltZSgpLSQuZ2V0VGltZSgpLFY9Wi5nZXRUaW1lKCktUS5nZXRUaW1lKCk7cmV0dXJuKFkrVikvMn12YXIgTiQ9e2VuY29kZSgkLEope2lmKCQud3JpdGVWYXJJbnQoSi5xdW90YSksSi5xdW90YT4wKXtpZihKLnVzYWdlPT09dm9pZCAwKXJldHVybiA5OyQud3JpdGVWYXJJbnQoSi51c2FnZSl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXQgUTtpZihKPjApe2xldFtZLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO1E9WX1yZXR1cm4gTyh7cXVvdGE6Six1c2FnZTpRfSl9fTt2YXIgT0o9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbSi5zdGF0dXNdKSk7bGV0IFo9JC53cml0ZURhdGUoSi50aW1lUmN2ZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZURhdGUoSi50aW1lU2VudCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9JC53cml0ZVZhckludChKLnN1YnNjcmlwdGlvbi50ZXJtKTtpZihZIT09MClyZXR1cm4gWTtsZXQgVj0kLndyaXRlVmFySW50KEouc3Vic2NyaXB0aW9uLmVsYXBzZWQpO2lmKFYhPT0wKXJldHVybiBWO2xldCBYPSQud3JpdGVTdHJ1Y3QoTiQsSi5zdWJzY3JpcHRpb24uc3RhdCk7aWYoWCE9PTApcmV0dXJuIFg7bGV0IFc9JC53cml0ZVN0cnVjdChOJCxKLnN1YnNjcmlwdGlvbi5keW4pO2lmKFchPT0wKXJldHVybiBXO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoMSk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9SlswXSxbWSxWXT0kLnJlYWREYXRlKCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1gsV109JC5yZWFkRGF0ZSgpO2lmKFchPT0wKXJldHVybiBHKFcpO2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO2xldFtGLE5dPSQucmVhZFZhckludCgpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldFtVLFJdPSQucmVhZFN0cnVjdChOJCk7aWYoUiE9PTApcmV0dXJuIEcoUik7bGV0W0gscV09JC5yZWFkU3RydWN0KE4kKTtpZihxIT09MClyZXR1cm4gRyhxKTtyZXR1cm4gTyh7c3RhdHVzOlEsdGltZVJjdmQ6WSx0aW1lU2VudDpYLHN1YnNjcmlwdGlvbjp7dGVybTp6LGVsYXBzZWQ6RixzdGF0OlUsZHluOkh9fSl9fTt2YXIgVUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5zZXEpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFyQnl0ZXMoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyh7aGVhZENwaDpKLHNlcTpRfSl9fTt2YXIgWDA9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnB1YktleSksJC53cml0ZUJ5dGVzKEouc2lnKTtsZXQgWj0kLndyaXRlRGF0ZShKLnRpbWVzdGFtcCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhIWik7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkQnl0ZXMoQTApO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZERhdGUoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7cHViS2V5Okosc2lnOlEsdGltZXN0YW1wOlZ9KX19O3ZhciBnWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsWSl7bGV0IFY9WS53cml0ZVN0cnVjdChYMCxaKTtpZihWIT09MClyZXR1cm4gVjtmb3IobGV0IFggb2YgUSlZLndyaXRlVmFySW50KFgpO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vn09JCxbWCxXXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEwwKFgsWSxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVgsW0YsTl09YXdhaXQgVi5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldFtVLFJdPUoucmVhZFZhckludCgpO2lmKFIhPT0wKXJldHVybiBSO2lmKCFKLmRvbmUoKSlyZXR1cm4gODtsZXRbSCxxXT1hd2FpdCBWLmxpc3RIZWFkcyhLLFUpO2lmKHEhPT0wKXJldHVybiBxO3JldHVybiBaLndyaXRlU3RydWN0cyhVSixIKX0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhVSil9fTt2YXIgUko9e2VuY29kZSgkLEopeyQud3JpdGVWYXJJbnQoSi5zZXEpO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlDcGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkVmFyQnl0ZXMoKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyh7c2VxOkosYm9keUNwaDpRfSl9fTt2YXIgbVo9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFkpe2xldCBWPVkud3JpdGVTdHJ1Y3QoWDAsWik7aWYoViE9PTApcmV0dXJuIFY7Zm9yKGxldCBYIG9mIFEpe2xldCBXPVkud3JpdGVWYXJJbnQoWCk7aWYoVyE9PTApcmV0dXJuIFd9cmV0dXJuIDB9LGFzeW5jIGhhbmRsZVJlcSgkLEosWil7bGV0e2Nsb2NrOlEsY3J5cHRvOlksc3RvcmFnZTpWfT0kLFtYLFddPUoucmVhZFN0cnVjdChYMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgTDAoWCxZLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309WCxbRixOXT1hd2FpdCBWLmhhc1VzZXIoSyk7aWYoTiE9PTApcmV0dXJuIE47aWYoIUYpcmV0dXJuIDU7bGV0IFU9W107d2hpbGUoIUouZG9uZSgpKXtsZXRbcSxNXT1KLnJlYWRWYXJJbnQoKTtpZihNIT09MClyZXR1cm4gTTtVLnB1c2gocSl9Y29uc29sZS5pbmZvKGBQVUxMOiAke1UubGVuZ3RofSBiYWdzYCk7bGV0W1IsSF09YXdhaXQgVi5nZXRCb2RpZXMoSyxVKTtpZihIIT09MClyZXR1cm4gSDtpZighUilyZXR1cm4gMTc7Zm9yKGxldHtzZXE6cSxib2R5Q3BoOk19b2YgUil7bGV0IFA9e3NlcTpxLGJvZHlDcGg6TX0sQz1aLndyaXRlU3RydWN0KFJKLFApO2lmKEMhPT0wKXJldHVybiBDfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKFJKKX19O3ZhciBISj17ZW5jb2RlKCQsSil7JC53cml0ZUJ5dGVzKEouc2lnKSwkLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlDcGgpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoQTApO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZEJ5dGVzKF8wKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJCeXRlcygpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZFZhckJ5dGVzKCk7aWYoeiE9PTApcmV0dXJuIEcoeik7cmV0dXJuIE8oe3NpZzpKLGtkbTpRLGhlYWRDcGg6Vixib2R5Q3BoOld9KX19O3ZhciBMJD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhckludChKLnNlcSk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKEouaGVhZENwaCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9Si5ib2R5Q3BoP0ouYm9keUNwaC5sZW5ndGg6MCxWPSQud3JpdGVWYXJJbnQoWSk7aWYoViE9PTApcmV0dXJuIFY7aWYoWT4wKXtpZighSi5ib2R5Q3BoKXJldHVybiAxMDskLndyaXRlQnl0ZXMoSi5ib2R5Q3BoKX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckJ5dGVzKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFc7aWYoVj4wKXtsZXRbeixLXT0kLnJlYWRCeXRlcyhWKTtpZihLIT09MClyZXR1cm4gRyhLKTtXPXp9cmV0dXJuIE8oe3NlcTpKLGhlYWRDcGg6USxib2R5Q3BoOld9KX19O3ZhciB4JD17ZW5jb2RlKCQsSil7JC53cml0ZUJ5dGVzKEouc2lnKSwkLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoQTApO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZEJ5dGVzKF8wKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJCeXRlcygpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBPKHtzaWc6SixrZG06USxoZWFkQ3BoOlZ9KX19O3ZhciBCJD17ZW5jb2RlKCQsSil7aWYoJC53cml0ZVZhckludChKLmlkeCksJC53cml0ZUJ5dGVzKG5ldyBVaW50OEFycmF5KFtKLnN0YXR1c10pKSxKLnN0YXR1cz09PTApJC53cml0ZVZhckludChKLnNlcSk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRCeXRlcygxKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgVj1RWzBdO2lmKFYhPT0wKXJldHVybiBPKHtpZHg6SixzdGF0dXM6Vn0pO2xldFtYLFddPSQucmVhZFZhckludCgpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBPKHtpZHg6SixzdGF0dXM6VixzZXE6WH0pfX07dmFyIFNaPXthc3luYyBlbmNvZGVSZXEoJCxKLFosUSxZKXtsZXQgVj1ZLndyaXRlU3RydWN0KFgwLFopO2lmKFYhPT0wKXJldHVybiBWO2xldCBYPVkud3JpdGVTdHJ1Y3RzKEhKLFEpO2lmKFghPT0wKXJldHVybiBYO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vixub3RpZmllcjpYfT0kLFtXLHpdPUoucmVhZFN0cnVjdChYMCk7aWYoeiE9PTApcmV0dXJuIHo7bGV0IEs9YXdhaXQgTDAoVyxZLFEpO2lmKEshPT0wKXJldHVybiBLO2xldHtwdWJLZXk6Rn09VyxbTixVXT1hd2FpdCBWLmhhc1VzZXIoRik7aWYoVSE9PTApcmV0dXJuIFU7aWYoIU4pcmV0dXJuIDU7bGV0W1IsSF09Si5yZWFkU3RydWN0cyhISik7aWYoSCE9PTApcmV0dXJuIEg7Y29uc29sZS5pbmZvKGBQVVNIOiAke1IubGVuZ3RofSBiYWdzYCk7bGV0IHE9W10sTT1bXTtmb3IobGV0IEk9MDtJPFIubGVuZ3RoO0krKyl7bGV0IEE9UltJXTtpZighYXdhaXQga1ooQSxGLFkpKXtsZXQgZz17aWR4Okksc3RhdHVzOjN9LEU9Wi53cml0ZVN0cnVjdChCJCxnKTtpZihFIT09MClyZXR1cm4gRTtjb250aW51ZX1xLnB1c2goSSksTS5wdXNoKEEpfWxldFtQLENdPWF3YWl0IFYuc2V0QmFncyhGLE0pO2lmKEMhPT0wKXJldHVybiBDO2lmKCFQfHxQLmxlbmd0aCE9PU0ubGVuZ3RoKXJldHVybiAxNztsZXQgVD1bXTtmb3IobGV0IEk9MDtJPE0ubGVuZ3RoO0krKyl7bGV0IEE9TVtJXSxMPXFbSV0sZz1QW0ldLEU9bmV3IFMsaz1FLndyaXRlU3RydWN0KHgkLEEpO2lmKGshPT0wKXJldHVybiBrO2xldCB5PUUucmVzdWx0KCksaD17c2VxOmcsaGVhZENwaDp5fTtpZihSLmxlbmd0aD09PTEmJkEuYm9keUNwaC5sZW5ndGg8PU1aKWguYm9keUNwaD1BLmJvZHlDcGg7VC5wdXNoKGgpO2xldCB1PXtpZHg6TCxzdGF0dXM6MCxzZXE6Z30sdz1aLndyaXRlU3RydWN0KEIkLHUpO2lmKHchPT0wKXJldHVybiB3fWlmKFQubGVuZ3RoPjApe2xldCBJPW5ldyBTLEE9SS53cml0ZVN0cnVjdHMoTCQsVCk7aWYoQSE9PTApcmV0dXJuIEE7bGV0IEw9SS5yZXN1bHQoKTthd2FpdCBQcm9taXNlLnJlc29sdmUoWC5wdXNoKEYsTCkpfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKEIkKX19O3ZhciB2Wj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsWSl7cmV0dXJuIFkud3JpdGVTdHJ1Y3QoWDAsWil9LGFzeW5jIGhhbmRsZVJlcSgkLEosWil7bGV0e2Nsb2NrOlEsY3J5cHRvOlksc3RvcmFnZTpWfT0kLFtYLFddPUoucmVhZFN0cnVjdChYMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgTDAoWCxZLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309WDtpZighSi5kb25lKCkpcmV0dXJuIDg7bGV0W0YsTl09YXdhaXQgVi5hZGRVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO3JldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiBPKHZvaWQgMCl9fTtjbGFzcyBxSnt1cmw7d2Vic29ja2V0O2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSR9Y29ubmVjdGVkKCl7cmV0dXJuIHRoaXMud2Vic29ja2V0IT09dm9pZCAwJiZ0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09V2ViU29ja2V0Lk9QRU59YXN5bmMgY29ubmVjdCgkLEosWj0oKT0+e30sUT0oKT0+e30pe2xldHt1cmw6WX09dGhpcztpZih0aGlzLndlYnNvY2tldCl0aGlzLndlYnNvY2tldC5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMDtsZXQgVj1uZXcgUztWLndyaXRlU3RydWN0KFgwLCQpO2xldCBYPVYucmVzdWx0KCksVz1VMChYKTtyZXR1cm4gWS5zZWFyY2hQYXJhbXMuc2V0KCJ0IixXKSx0aGlzLndlYnNvY2tldD1uZXcgV2ViU29ja2V0KFkpLHRoaXMud2Vic29ja2V0LmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix0aGlzLndlYnNvY2tldC5vbm9wZW49KCk9Pntjb25zb2xlLmxvZygiQ09OTkVDVEVEIiksUSgpfSx0aGlzLndlYnNvY2tldC5vbmNsb3NlPSgpPT57Y29uc29sZS5sb2coIkRJU0NPTk5FQ1RFRCIpLHRoaXMud2Vic29ja2V0PXZvaWQgMCxaKCl9LHRoaXMud2Vic29ja2V0Lm9ubWVzc2FnZT0oeik9PntsZXQgSz1uZXcgVWludDhBcnJheSh6LmRhdGEpO0ooSyl9LHRoaXMud2Vic29ja2V0Lm9uZXJyb3I9KHopPT57Y29uc29sZS5sb2coYEVSUk9SOiAke0pTT04uc3RyaW5naWZ5KHopfWApLHRoaXMud2Vic29ja2V0PXZvaWQgMCxaKCl9LFByb21pc2UucmVzb2x2ZSgwKX1kaXNjb25uZWN0KCl7dGhpcy53ZWJzb2NrZXQ/LmNsb3NlKCksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwfX12YXIgYT17dXNlcjp7cGF0aDoiL3VzZXIiLGVuZHBvaW50OnZaLG5hbWU6MH0scHVzaDp7cGF0aDoiL3B1c2giLGVuZHBvaW50OlNaLG5hbWU6Mn0scGVlazp7cGF0aDoiL3BlZWsiLGVuZHBvaW50OmdaLG5hbWU6MX0scHVsbDp7cGF0aDoiL3B1bGwiLGVuZHBvaW50Om1aLG5hbWU6M319LHhZPXswOmEudXNlciwyOmEucHVzaCwxOmEucGVlaywzOmEucHVsbH0sblc9e1thLnVzZXIucGF0aF06YS51c2VyLFthLnB1c2gucGF0aF06YS5wdXNoLFthLnBlZWsucGF0aF06YS5wZWVrLFthLnB1bGwucGF0aF06YS5wdWxsfTtjbGFzcyB5Wnt1cmw7bGlzdGVuZXI7Y29uc3RydWN0b3IoJCl7dGhpcy51cmw9JDt0aGlzLmxpc3RlbmVyPW5ldyBxSigkKX1hc3luYyBjYWxsKCQsSil7bGV0e3BhdGg6Wn09eFlbJF0sUT1uZXcgVVJMKFosdGhpcy51cmwpO3RyeXtyZXR1cm4gYXdhaXQgQlkoUSxKKX1jYXRjaHtyZXR1cm4gRygyNSl9fX12YXIgYlo9KCQpPT57cmV0dXJuIG5ldyB5WigkLmhhbmRsZSl9O2FzeW5jIGZ1bmN0aW9uIEJZKCQsSil7bGV0IFo9YXdhaXQgZmV0Y2goJCx7bWV0aG9kOiJQT1NUIixib2R5OkoucmVzdWx0KCkuc2xpY2UoKX0pO2lmKCFaLm9rKXJldHVybiBHKDI0KTtsZXQgUT1hd2FpdCBtLmZyb21SZXNwb25zZShaKTtyZXR1cm4gTyhRKX1jbGFzcyBrJHtlbmNsYXZlO2NyeXB0bztob3N0O2Nsb2NrO3RyYW5zcG9ydDt1cGRhdGVIb3N0TWV0YTtjb25zdHJ1Y3RvcigkLEosWixRLFksVil7dGhpcy5lbmNsYXZlPSQ7dGhpcy5jcnlwdG89Sjt0aGlzLmhvc3Q9Wjt0aGlzLmNsb2NrPVE7dGhpcy50cmFuc3BvcnQ9WTt0aGlzLnVwZGF0ZUhvc3RNZXRhPVZ9YXN5bmMgY2FsbCgkLEope2xldHtjbG9jazpaLHRyYW5zcG9ydDpRfT10aGlzLHtlbmRwb2ludDpZLG5hbWU6Vn09JCxYPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVoubm93KCksW3osS109YXdhaXQgS0ooWCxXKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXQgRj1uZXcgUyxOPWF3YWl0IFkuZW5jb2RlUmVxKHRoaXMsWCx6LEosRik7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IFU9Wi5ub3coKSxbUixIXT1hd2FpdCBRLmNhbGwoVixGKSxxPVoubm93KCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7bGV0W00sUF09Ui5yZWFkU3RydWN0KE9KKTtpZihQIT09MClyZXR1cm4gRyhQKTtpZihNLnN0YXR1cyE9PTApcmV0dXJuIEcoTS5zdGF0dXMpO2xldCBUPXtjbG9ja09mZnNldDpFWihVLE0udGltZVJjdmQsTS50aW1lU2VudCxxKSxzdWJzY3JpcHRpb246TS5zdWJzY3JpcHRpb259LEk9YXdhaXQgdGhpcy51cGRhdGVIb3N0TWV0YShUKTtpZihJIT09MClyZXR1cm4gRyhJKTtyZXR1cm4gWS5kZWNvZGVSZXNwKFIpfWlkZW50aXR5PSgpPT57bGV0e2hvc3Q6JCxlbmNsYXZlOkp9PXRoaXM7cmV0dXJuIEouZGVyaXZlSWRlbnRpdHkoJC5sYWJlbCwkLmlkeD8/MCl9O3NlYWw9YXN5bmMoJCk9PntsZXR7Y3J5cHRvOkosZW5jbGF2ZTpafT10aGlzLFE9YXdhaXQgdGhpcy5pZGVudGl0eSgpO3JldHVybiBmWigkLFEsSixaKX07cmVnaXN0ZXI9KCk9PnRoaXMuY2FsbChhLnVzZXIsW10pO3BlZWs9KCQpPT50aGlzLmNhbGwoYS5wZWVrLFskXSk7cHVzaD0oJCk9PnRoaXMuY2FsbChhLnB1c2gsJCk7cHVsbD0oJCk9PnRoaXMuY2FsbChhLnB1bGwsJCk7bGlzdGVuPWFzeW5jKCQsSixaKT0+e2xldHtjbG9jazpRLHRyYW5zcG9ydDpZfT10aGlzLHtsaXN0ZW5lcjpWfT1ZLFg9YXdhaXQgdGhpcy5pZGVudGl0eSgpLFc9US5ub3coKSxbeixLXT1hd2FpdCBLSihYLFcpO2lmKEshPT0wKXJldHVybiBLO3JldHVybiBhd2FpdCBWLmNvbm5lY3QoeiwkLEosWil9O2lzQ29ubmVjdGVkKCl7bGV0ICQ9dGhpcy50cmFuc3BvcnQ/Lmxpc3RlbmVyO2lmKCQmJnR5cGVvZiAkLmNvbm5lY3RlZD09PSJmdW5jdGlvbiIpcmV0dXJuICQuY29ubmVjdGVkKCk7cmV0dXJuITB9Y2xvc2VMaXN0ZW5lcigpe3RoaXMudHJhbnNwb3J0Py5saXN0ZW5lcj8uZGlzY29ubmVjdCgpfX12YXIgTUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJTdHJpbmcoSi5sYmwpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5pZHgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJJbnQoSi5udW0pO2lmKFkhPT0wKXJldHVybiBZO3JldHVybiAkLndyaXRlQnl0ZXMoSi5oc2gpLCQud3JpdGVCeXRlcyhKLnNpZyksMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhclN0cmluZygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZEJ5dGVzKFAkKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRCeXRlcyhBMCk7aWYoRiE9PTApcmV0dXJuIEcoRik7cmV0dXJuIE8oe2xibDpKLGlkeDpRLG51bTpWLGhzaDpXLHNpZzpLfSl9fTt2YXIgSUo9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVTdHJ1Y3QoTUosSi5oZWFkKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoSi5pbmRleEVuYyk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFk9JC53cml0ZVZhckJ5dGVzKEouYm9keUVuYyk7aWYoWSE9PTApcmV0dXJuIFk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRTdHJ1Y3QoTUopO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckJ5dGVzKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7aGVhZDpKLGluZGV4RW5jOlEsYm9keUVuYzpWfSl9fTt2YXIgQ0o9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLmtkbSk7bGV0IFo9JC53cml0ZVZhckJ5dGVzKEouaGVhZENwaCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLmxlbkJvZHkpO2lmKFEhPT0wKXJldHVybiBRO2lmKEoubGVuQm9keT4wJiZKLm9mZkJvZHkhPT12b2lkIDApe2xldCBZPSQud3JpdGVWYXJJbnQoSi5vZmZCb2R5KTtpZihZIT09MClyZXR1cm4gWX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKF8wKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXO2lmKFY+MCl7bGV0W3osS109JC5yZWFkVmFySW50KCk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBPKHtrZG06SixoZWFkQ3BoOlEsbGVuQm9keTpWLG9mZkJvZHk6V30pfX07YXN5bmMgZnVuY3Rpb24gaFooJCxKLFosUSxZKXtsZXQgVj1hd2FpdCBZLmRlcml2ZUlkZW50aXR5KCQsSiksWD1uZXcgUyxXPW5ldyBTLHo9MCxLPTA7Zm9yKGxldCBQIG9mIFope2xldCBDPW5ldyBTLFQ9Qy53cml0ZVN0cnVjdChHMCxQLmhlYWQpO2lmKFQhPT0wKXJldHVybiBHKFQpO2xldCBJPUMucmVzdWx0KCksQT1hd2FpdCBWLmtkbUZvcihJKSxMPVkuZGVyaXZlQ2lwaGVyKEEsImVuY3J5cHQiKSxnPWF3YWl0IEwuZW5jcnlwdChJKSxFPVAuYm9keT9hd2FpdCBMLmVuY3J5cHQoUC5ib2R5KTpuZXcgVWludDhBcnJheSgwKSxrPVAuaGVhZC5sZW4+MCYmUC5oZWFkLmhzaCE9PXZvaWQgMD9FLmxlbmd0aDowLHk9e2tkbTpBLGhlYWRDcGg6ZyxsZW5Cb2R5Omssb2ZmQm9keTprPjA/Szp2b2lkIDB9LGg9WC53cml0ZVN0cnVjdChDSix5KTtpZihoIT09MClyZXR1cm4gRyhoKTtpZihQLmJvZHkpVy53cml0ZUJ5dGVzKEUpLEsrPUUubGVuZ3RoO3orK31sZXQgRj1XLnJlc3VsdCgpLE49WC5yZXN1bHQoKSxVPWF3YWl0IFEuYmxha2UzKE4pLFI9YXdhaXQgVi5zaWduKFUpLEg9e2xibDokLGlkeDpKLG51bTp6LGhzaDpVLHNpZzpSfSxxPW5ldyBTO3Eud3JpdGVTdHJ1Y3QoSUose2hlYWQ6SCxpbmRleEVuYzpOLGJvZHlFbmM6Rn0pO2xldCBNPXEucmVzdWx0KCk7cmV0dXJuIE8oTSl9YXN5bmMgZnVuY3Rpb24gaVooJCxKLFope2xldFtRLFldPUlKLmRlY29kZShuZXcgbSgkKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0e2hlYWQ6VixpbmRleEVuYzpYLGJvZHlFbmM6V309USx6PWF3YWl0IFouZGVyaXZlSWRlbnRpdHkoVi5sYmwsVi5pZHgpO2lmKCFhd2FpdCBKLmNoZWNrU2lnRWQyNTUxOShWLnNpZyxWLmhzaCx6LnB1YmxpY0tleSkpcmV0dXJuIEcoMyk7bGV0IEY9YXdhaXQgSi5ibGFrZTMoWCk7aWYoIXIoRixWLmhzaCkpcmV0dXJuIEcoMTkpO2xldCBOPW5ldyBtKFgpLFU9W107Zm9yKGxldCBIPTA7SDxWLm51bTtIKyspe2xldFtxLE1dPU4ucmVhZFN0cnVjdChDSik7aWYoTSE9PTApcmV0dXJuIEcoTSk7VS5wdXNoKHEpfWlmKFUubGVuZ3RoIT09Vi5udW0pcmV0dXJuIEcoMTQpO2xldCBSPVtdO2ZvcihsZXQgSCBvZiBVKXtsZXQgcT1aLmRlcml2ZUNpcGhlcihILmtkbSwiZGVjcnlwdCIpLE07dHJ5e009YXdhaXQgcS5kZWNyeXB0KEguaGVhZENwaCl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldFtQLENdPUcwLmRlY29kZShuZXcgbShNKSk7aWYoQyE9PTApcmV0dXJuIEcoQyk7bGV0IFQ7aWYoSC5sZW5Cb2R5PjAmJkgub2ZmQm9keSE9PXZvaWQgMCl7aWYoUC5oc2g9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldCBJPVcuc2xpY2UoSC5vZmZCb2R5LEgub2ZmQm9keStILmxlbkJvZHkpO3RyeXtUPWF3YWl0IHEuZGVjcnlwdChJKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IEE9YXdhaXQgSi5ibGFrZTMoVCk7aWYoIXIoQSxQLmhzaCkpcmV0dXJuIEcoMTkpfVIucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBPKFIpfWFzeW5jIGZ1bmN0aW9uIGxaKHtub3c6JCxib2Q6SixjcnlwdG86Wn0pe2xldCBRPWF3YWl0IFouZ2VuUmFuZG9tQnl0ZXMoOCksWT1uZXcgUyxWPVkud3JpdGVTdHJ1Y3QoVjAse2lkOlEsdHM6JH0pO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBYPVkucmVzdWx0KCk7cmV0dXJuIGYkKHtub3c6JCxlaWQ6WCxjdHI6MCxib2Q6SixjcnlwdG86Wn0pfWFzeW5jIGZ1bmN0aW9uIGYkKHtub3c6JCxlaWQ6SixjdHI6Wixib2Q6USxjcnlwdG86WX0pe2xldCBWPW5ldyBtKEopLFtYLFddPVYwLmRlY29kZShWKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1YLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFkuYmxha2UzKFEpO3JldHVybiBPKHtlaWQ6SixvZmY6eixjdHI6WixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIGtZKCQsSil7bGV0IFo9JC5sZW5ndGg8Si5sZW5ndGg/JC5sZW5ndGg6Si5sZW5ndGg7Zm9yKGxldCBRPTA7UTxaO1ErKylpZigkW1FdIT09SltRXSlyZXR1cm4gJFtRXS1KW1FdO3JldHVybiAkLmxlbmd0aC1KLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBPJCgkLEope2xldCBaPUFycmF5LmZyb20oJCk7Wi5zb3J0KGtZKTtsZXQgUT0wO2ZvcihsZXQgWCBvZiBaKVErPVgubGVuZ3RoO2xldCBZPW5ldyBVaW50OEFycmF5KFEpLFY9MDtmb3IobGV0IFggb2YgWilZLnNldChYLFYpLFYrPVgubGVuZ3RoO3JldHVybiBKLmJsYWtlMyhZKX1mdW5jdGlvbiBmWSgkKXtsZXQgSj1uZXcgUyxaPUoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE9Si53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBZPUoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBPKEoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIEUkKCQsSil7bGV0IFo9W107Zm9yKGxldCBRIG9mICQpe2xldFtZLFZdPWZZKFEpO2lmKFYhPT0wfHwhWSlyZXR1cm4gRyhWKTtaLnB1c2goWSl9cmV0dXJuIE8oYXdhaXQgTyQoWixKKSl9dmFyIGJHPVN5bWJvbCgiTWFzdGVyU2VlZCIpLGhHPVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksSDA9MzIsdVo9MjQrSDArMTY7ZnVuY3Rpb24gJDAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09SDApcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfWZ1bmN0aW9uIHgwKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PXVaKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX12YXIgbEc9U3ltYm9sKCJFbnRpdHlJRCIpO2Z1bmN0aW9uIHBaKCQpe3JldHVybiJ0eXBlImluICR9dmFyIHVHPVN5bWJvbCgiRGVyaXZhdGlvblNlZWQiKSxwRz1TeW1ib2woIlB1YmxpY0tleSIpLGNHPVN5bWJvbCgiUHJpdmF0ZUtleSIpLG5HPVN5bWJvbCgiSG9zdFNwZWNpZmljS2V5UGFpciIpLGRHPVN5bWJvbCgiSGFzaCIpO2Z1bmN0aW9uIEVZKCQpe2lmKCEkKXJldHVybiExO2lmKHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoImJvZHkiaW4gJD09PSExKXJldHVybiExO2lmKCJ0eXBlImluICQ9PT0hMSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBnWSgkKXtpZighJC5ib2R8fCQuYm9kLmxlbmd0aD09PTApe2xldCBRPXtvZmY6JC5vZmYsY3RyOiQuY3RyLGVpZDokLmVpZH07cmV0dXJuIE8oUSl9bGV0IEo9ekooJC5ib2QpO2lmKEVZKEopPT09ITEpcmV0dXJuIGNvbnNvbGUud2FybigibXNnIGJvZHkgaW52YWxpZCIsSiksRygxNCk7bGV0IFo9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkLGdpZDpKLmdpZCxwaWQ6Si5waWQsdGFnczpKLnRhZ3MsdHlwZTpKLnR5cGUsYm9keTpKLmJvZHl9O3JldHVybiBPKFopfWNsYXNzIGcke2FwcGxpZXI7ZW1pdHRlcj1uZXcgRiQ7Y2xlYXJlcjtvbkRpcnR5RWlkcztjYWNoZURyaXZlbjtwZWVySW5nZXN0O2NvbnN0cnVjdG9yKCQsSixaLFEpe3RoaXMuYXBwbGllcj0kO3RoaXMuY2xlYXJlcj1KLHRoaXMub25EaXJ0eUVpZHM9Wix0aGlzLmNhY2hlRHJpdmVuPVE/LmNhY2hlRHJpdmVuPz8hMSx0aGlzLnBlZXJJbmdlc3Q9UT8ucGVlckluZ2VzdH1hcHBseT1hc3luYygkKT0+e2xldCBKPVtdLFo9W107Zm9yKGxldCBXIG9mICQpe2xldFt6LEtdPWdZKFcpO2lmKFoucHVzaChLKSxLIT09MCljb250aW51ZTtKLnB1c2goeil9bGV0e3N0YXRzOlEsdHlwZXM6WSxlaWRzOlZ9PWF3YWl0IHRoaXMuYXBwbGllcihKKSxYPVtdO2ZvcihsZXQgVz0wO1c8JC5sZW5ndGg7VysrKXtsZXQgej1aW1ddLEs9UVtXXTtpZih6IT09MCl7WC5wdXNoKHopO2NvbnRpbnVlfWlmKEshPT0wKXtYLnB1c2goSyk7Y29udGludWV9WC5wdXNoKDApfWlmKCF0aGlzLmNhY2hlRHJpdmVuKWZvcihsZXQgVyBvZiBZKXRoaXMuZW1pdHRlci5lbWl0KFcsbnVsbCk7aWYoVi5sZW5ndGg+MCl0aGlzLm9uRGlydHlFaWRzPy4oVik7cmV0dXJuIFh9O2NsZWFyPWFzeW5jKCk9PntsZXQgJD1hd2FpdCB0aGlzLmNsZWFyZXIoKTtpZigkIT09MClyZXR1cm4gJDtyZXR1cm4gdGhpcy5lbWl0dGVyLmVtaXRBbGwobnVsbCksJH07bm90aWZ5PSgkKT0+e2ZvcihsZXQgSiBvZiAkKXRoaXMuZW1pdHRlci5lbWl0KEosbnVsbCl9O3JlZnJlc2g9YXN5bmMoJCk9PntpZih0aGlzLnBlZXJJbmdlc3Qpe2F3YWl0IHRoaXMucGVlckluZ2VzdCgkKTtyZXR1cm59fTtvbj0oJCxKKT0+e3RoaXMuZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKCQsSil9O29mZj0oJCxKKT0+e3RoaXMuZW1pdHRlci5yZW1vdmVFdmVudExpc3RlbmVyKCQsSil9fXZhciBuPSJlbnRpdGllcyIsbSQ9ImVudGl0eV90eXBlX2NyZWF0ZWRfYXQiLHdKPSJlbnRpdHlfdHlwZV91cGRhdGVkX2F0IixUSj0iZW50aXR5X3R5cGVfZ3JvdXBfaWQiLGpKPSJlbnRpdHlfdHlwZV9wYXJlbnRfaWQiLHQwPSJlbnRpdHlfdGFncyIsY1o9ImRiIixuWj0xMztmdW5jdGlvbiBtWSgkKXtyZXR1cm4idHlwImluICR9ZnVuY3Rpb24gU1koJCl7bGV0IEo9e2JvZDokLmJvZHksY3JkOiQuY3JlYXRlZEF0LC4uLiQuY3RyIT09MD97Y3RyOiQuY3RyfTp7fSxlaWQ6QigkLmVpZCksZ2lkOiQuZ2lkLHBpZDokLnBpZD9CKCQucGlkKTp2b2lkIDAsdGdzOiQudGFncyx0eXA6JC50eXBlLHVwZDokLnVwZGF0ZWRBdH07aWYoSi5naWQ9PT12b2lkIDApZGVsZXRlIEouZ2lkO2lmKEoucGlkPT09dm9pZCAwKWRlbGV0ZSBKLnBpZDtpZihKLnRncz09PXZvaWQgMClkZWxldGUgSi50Z3M7aWYoSi5jdHI9PT12b2lkIDApZGVsZXRlIEouY3RyO3JldHVybiBKfWZ1bmN0aW9uIHZZKCQpe2lmKCFsKCQpKXJldHVybntlaWQ6QigkLmVpZCksdXBkOiQudXBkYXRlZEF0LC4uLiQuY3RyIT09MD97Y3RyOiQuY3RyfTp7fX07cmV0dXJuIFNZKCQpfWZ1bmN0aW9uIGUwKCQpe3JldHVybntib2R5OiQuYm9kLGNyZWF0ZWRBdDokLmNyZCx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wLHR5cGU6JC50eXAsZWlkOk4wKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP04wKCQucGlkKTp2b2lkIDAsLi4uJC50Z3MhPT12b2lkIDA/e3RhZ3M6JC50Z3N9Ont9fX1mdW5jdGlvbiBQSigkKXtpZihtWSgkKSlyZXR1cm4gZTAoJCk7cmV0dXJue2VpZDpOMCgkLmVpZCksdXBkYXRlZEF0OiQudXBkLGN0cjokLmN0cj8/MH19Y2xhc3MgZFp7ZGI7b3BlbmluZzthc3luYyBpbml0KCl7YXdhaXQgdGhpcy5lbnN1cmVEYigpfWFzeW5jIGVuc3VyZURiKCl7aWYodGhpcy5kYilyZXR1cm4gdGhpcy5kYjtpZih0aGlzLm9wZW5pbmcpcmV0dXJuIHRoaXMub3BlbmluZztyZXR1cm4gdGhpcy5vcGVuaW5nPWJZKCkudGhlbigoJCk9PntyZXR1cm4gJC5vbnZlcnNpb25jaGFuZ2U9KCk9PntpZigkLmNsb3NlKCksdGhpcy5kYj09PSQpdGhpcy5kYj12b2lkIDB9LHRoaXMuZGI9JCx0aGlzLm9wZW5pbmc9dm9pZCAwLCR9LCgkKT0+e3Rocm93IHRoaXMub3BlbmluZz12b2lkIDAsJH0pLHRoaXMub3BlbmluZ31hcHBseT1hc3luYygkKT0+e2xldCBKPW5ldyBTZXQsWj1bXSxRO3RyeXtRPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm57c3RhdHM6JC5tYXAoKCk9PjE2KSx0eXBlczpKLGVpZHM6Wn19bGV0IFk9US50cmFuc2FjdGlvbihuLCJyZWFkd3JpdGUiKSxWPVkub2JqZWN0U3RvcmUobik7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBXPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO2lmKCQubGVuZ3RoPDEpe1goe3N0YXRzOltdLHR5cGVzOkosZWlkczpafSk7cmV0dXJufVkub25jb21wbGV0ZT0oKT0+e1goe3N0YXRzOlcsdHlwZXM6SixlaWRzOlp9KX0sWS5vbmVycm9yPSgpPT57Zm9yKGxldCBLPTA7SzxXLmxlbmd0aDtLKyspaWYoV1tLXT09PXZvaWQgMClXW0tdPTE4O1goe3N0YXRzOlcsdHlwZXM6SixlaWRzOlp9KX07bGV0IHo9bmV3IE1hcDtmb3IobGV0IEs9MDtLPCQubGVuZ3RoO0srKyl7bGV0IEY9JFtLXSxOPUIoRi5laWQpLFU9e29wOkYsaW5kZXg6S30sUj16LmdldChOKTtpZihSKVIucHVzaChVKTtlbHNlIHouc2V0KE4sW1VdKX1mb3IobGV0W0ssRl1vZiB6KXtpZihGLmxlbmd0aDwxKWNvbnRpbnVlO2xldCBOPVYuZ2V0KEspO04ub25zdWNjZXNzPSgpPT57bGV0IFU9Ti5yZXN1bHQsUj1VP1BKKFUpOnZvaWQgMCxIPSExO2ZvcihsZXR7b3A6cSxpbmRleDpNfW9mIEYpe2xldFtQLENdPSQkKFIscSk7aWYoQyE9PTApe1dbTV09Qztjb250aW51ZX1pZihQPT09dm9pZCAwKXtXW01dPTEyO2NvbnRpbnVlfUg9ITA7Zm9yKGxldCBUIG9mIEokKFIsUCkpSi5hZGQoVCk7Uj1QfWlmKEgpWi5wdXNoKEZbMF0ub3AuZWlkKTtpZihSKXtsZXQgcT1WLnB1dCh2WShSKSk7cS5vbmVycm9yPShNKT0+e00ucHJldmVudERlZmF1bHQoKTtmb3IobGV0e2luZGV4OlB9b2YgRilXW1BdPTE4fX19LE4ub25lcnJvcj0oKT0+e2ZvcihsZXR7aW5kZXg6VX1vZiBGKVdbVV09MTh9fX0pfTthc3luYyBjbGVhcigpe2xldCAkO3RyeXskPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gMTZ9bGV0IEo9JC50cmFuc2FjdGlvbihuLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUobik7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e0oub25jb21wbGV0ZT0oKT0+USgwKSxKLm9uZXJyb3I9KCk9PlEoMTgpLFouY2xlYXIoKX0pfWFzeW5jIGdldFJvdygkKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBaPUIoJCksWT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobik7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVkuZ2V0KFopO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7aWYoIVcpVihPKHZvaWQgMCkpO2Vsc2UgVihPKFBKKFcpKSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IWwoSikpcmV0dXJuIE8odm9pZCAwKTtyZXR1cm4gTyhKKX1hc3luYyBnZXRBbGxPZlR5cGVVcGRhdGVkQmV0d2VlbigkLEosWil7bGV0IFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgVj1RLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgod0opO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgVz1WLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbJCxKXSxbJCxaXSkpO1cub25zdWNjZXNzPSgpPT57bGV0IHo9Vy5yZXN1bHQ7WChPKHoubWFwKGUwKSkpfSxXLm9uZXJyb3I9KCk9PlgoRygxOCkpfSl9YXN5bmMgZ2V0R3JvdXBNZW1iZXJzKCQsSil7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWT1aLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgoVEopO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1ZLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFskLEpdKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtWKE8oVy5tYXAoZTApKSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRBbGxPZlR5cGUoJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgobSQpO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVj1RLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgWD1WLnJlc3VsdDtZKE8oWC5tYXAoZTApKSl9LFYub25lcnJvcj0oKT0+WShHKDE4KSl9KX1hc3luYyBnZXRCeVRhZygkLEope2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFk9Wi50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KHQwKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9WS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShKKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgej1YLnJlc3VsdC5maWx0ZXIoKEspPT5LLnR5cD09PSQpLm1hcChlMCk7VihPKHopKX0sWC5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfWFzeW5jIGdldEFsbEVudGl0aWVzKCQpe2lmKCJwaWQiaW4gJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWj1CKCQucGlkKSxZPUoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChqSik7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVkuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQudHlwZSxaXSkpO1gub25zdWNjZXNzPSgpPT57bGV0IHo9WC5yZXN1bHQubWFwKGUwKTtWKE8oeikpfSxYLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9ZWxzZSBpZigiZ2lkImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0R3JvdXBNZW1iZXJzKCQudHlwZSwkLmdpZCk7ZWxzZSBpZigidGFnImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QnlUYWcoJC50eXBlLCQudGFnKTtlbHNlIGlmKCJ1cGRhdGVkQmV0d2VlbiJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQudHlwZSwkLnVwZGF0ZWRCZXR3ZWVuLnN0YXJ0LCQudXBkYXRlZEJldHdlZW4uZW5kKTtyZXR1cm4gYXdhaXQgdGhpcy5nZXRBbGxPZlR5cGUoJC50eXBlKX1hc3luYyBnZXRFbnRpdGllcygkKXtsZXRbSixaXT1hd2FpdCB0aGlzLmdldEFsbEVudGl0aWVzKCQpO2lmKFohPT0wKXJldHVybiBHKFopO3JldHVybiBPKEopfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KG0kKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9SURCS2V5UmFuZ2UuYm91bmQoWyRdLFskLFtdXSksWD1RLmNvdW50KFYpO1gub25zdWNjZXNzPSgpPT5ZKE8oWC5yZXN1bHQpKSxYLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgY2hlY2tzdW0oJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobiksWT1bXTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9US5vcGVuQ3Vyc29yKCk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtpZihXKXtsZXQgej1XLnZhbHVlO1kucHVzaChTJChQSih6KSkpLFcuY29udGludWUoKX1lbHNlIEUkKFksJCkudGhlbihWKX0sWC5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfX1mdW5jdGlvbiB5WSgkLEope2lmKCEkLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMobikpJC5jcmVhdGVPYmplY3RTdG9yZShuLHtrZXlQYXRoOiJlaWQiLGF1dG9JbmNyZW1lbnQ6ITF9KTtsZXQgWj1KLm9iamVjdFN0b3JlKG4pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMobSQpKVouY3JlYXRlSW5kZXgobSQsWyJ0eXAiLCJjcmQiXSx7dW5pcXVlOiExfSk7aWYoIVouaW5kZXhOYW1lcy5jb250YWlucyh3SikpWi5jcmVhdGVJbmRleCh3SixbInR5cCIsInVwZCJdLHt1bmlxdWU6ITF9KTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKFRKKSlaLmNyZWF0ZUluZGV4KFRKLFsidHlwIiwiZ2lkIl0se3VuaXF1ZTohMX0pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoakopKVouY3JlYXRlSW5kZXgoakosWyJ0eXAiLCJwaWQiXSx7dW5pcXVlOiExfSk7aWYoWi5pbmRleE5hbWVzLmNvbnRhaW5zKHQwKSl7aWYoWi5pbmRleCh0MCkua2V5UGF0aCE9PSJ0Z3MiKVouZGVsZXRlSW5kZXgodDApfWlmKCFaLmluZGV4TmFtZXMuY29udGFpbnModDApKVouY3JlYXRlSW5kZXgodDAsInRncyIse3VuaXF1ZTohMSxtdWx0aUVudHJ5OiEwfSl9ZnVuY3Rpb24gYlkoKXtyZXR1cm4gbmV3IFByb21pc2UoKCQsSik9PntsZXQgWj1pbmRleGVkREIub3BlbihjWixuWik7Wi5vbnVwZ3JhZGVuZWVkZWQ9KCk9PntsZXR7cmVzdWx0OlEsdHJhbnNhY3Rpb246WX09WjtpZighWSl7SihFcnJvcigiVHJhbnNhY3Rpb24gaXMgbnVsbCBkdXJpbmcgRW50REIgdXBncmFkZSIpKTtyZXR1cm59dHJ5e3lZKFEsWSl9Y2F0Y2goVil7SihWIGluc3RhbmNlb2YgRXJyb3I/VjpFcnJvcihTdHJpbmcoVikpKX19LFoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gRW50REIgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtjWn0g4oaSIHYke25afSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LFoub25zdWNjZXNzPSgpPT4kKFoucmVzdWx0KSxaLm9uZXJyb3I9KCk9PkooWi5lcnJvcj8/RXJyb3IoIkVudERCIEluZGV4ZWREQiBvcGVuIGZhaWxlZCIpKX0pfWFzeW5jIGZ1bmN0aW9uIHJaKCl7bGV0ICQ9bmV3IGRaO3JldHVybiBhd2FpdCAkLmluaXQoKSwkfWNsYXNzIERKe2VudHM9bmV3IE1hcDt1c2VJbmRleDtieVR5cGU9bmV3IE1hcDtieVR5cGVQaWQ9bmV3IE1hcDtieVR5cGVHaWQ9bmV3IE1hcDtieVR5cGVUYWc9bmV3IE1hcDtjb25zdHJ1Y3RvcigkPVtdLEope3RoaXMudXNlSW5kZXg9Sj8uaW5kZXhlcyE9PSExO2ZvcihsZXQgWiBvZiAkKXRoaXMucHV0KFopfXB1dCgkKXtsZXQgSj1CKCQuZWlkKSxaPXRoaXMuZW50cy5nZXQoSik7aWYoWiE9PXZvaWQgMCYmbChaKSl0aGlzLnVuaW5kZXgoSixaKTtpZih0aGlzLmVudHMuc2V0KEosJCksbCgkKSl0aGlzLmluZGV4KEosJCl9ZGVsKCQpe2xldCBKPXRoaXMuZW50cy5nZXQoJCk7aWYoSj09PXZvaWQgMClyZXR1cm47aWYobChKKSl0aGlzLnVuaW5kZXgoJCxKKTt0aGlzLmVudHMuZGVsZXRlKCQpfWluZGV4KCQsSil7aWYoIXRoaXMudXNlSW5kZXgpcmV0dXJuO2xldCBaPXRoaXMuYnlUeXBlLmdldChKLnR5cGUpO2lmKCFaKVo9bmV3IE1hcCx0aGlzLmJ5VHlwZS5zZXQoSi50eXBlLFopO2lmKFouc2V0KCQsSiksSi5waWQpe2xldCBRPUIoSi5waWQpLFk9dGhpcy5ieVR5cGVQaWQuZ2V0KEoudHlwZSk7aWYoIVkpWT1uZXcgTWFwLHRoaXMuYnlUeXBlUGlkLnNldChKLnR5cGUsWSk7bGV0IFY9WS5nZXQoUSk7aWYoIVYpVj1uZXcgTWFwLFkuc2V0KFEsVik7Vi5zZXQoJCxKKX1pZih0eXBlb2YgSi5naWQ9PT0ic3RyaW5nIil7bGV0IFE9dGhpcy5ieVR5cGVHaWQuZ2V0KEoudHlwZSk7aWYoIVEpUT1uZXcgTWFwLHRoaXMuYnlUeXBlR2lkLnNldChKLnR5cGUsUSk7bGV0IFk9US5nZXQoSi5naWQpO2lmKCFZKVk9bmV3IE1hcCxRLnNldChKLmdpZCxZKTtZLnNldCgkLEopfWlmKEoudGFncyl7bGV0IFE9dGhpcy5ieVR5cGVUYWcuZ2V0KEoudHlwZSk7aWYoIVEpUT1uZXcgTWFwLHRoaXMuYnlUeXBlVGFnLnNldChKLnR5cGUsUSk7Zm9yKGxldCBZIG9mIEoudGFncyl7bGV0IFY9US5nZXQoWSk7aWYoIVYpVj1uZXcgTWFwLFEuc2V0KFksVik7Vi5zZXQoJCxKKX19fXVuaW5kZXgoJCxKKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IFo9dGhpcy5ieVR5cGUuZ2V0KEoudHlwZSk7aWYoWil7aWYoWi5kZWxldGUoJCksWi5zaXplPT09MCl0aGlzLmJ5VHlwZS5kZWxldGUoSi50eXBlKX1pZihKLnBpZCl7bGV0IFE9QihKLnBpZCksWT10aGlzLmJ5VHlwZVBpZC5nZXQoSi50eXBlKSxWPVk/LmdldChRKTtpZihWKXtpZihWLmRlbGV0ZSgkKSxWLnNpemU9PT0wKVk/LmRlbGV0ZShRKX1pZihZJiZZLnNpemU9PT0wKXRoaXMuYnlUeXBlUGlkLmRlbGV0ZShKLnR5cGUpfWlmKHR5cGVvZiBKLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoSi50eXBlKSxZPVE/LmdldChKLmdpZCk7aWYoWSl7aWYoWS5kZWxldGUoJCksWS5zaXplPT09MClRPy5kZWxldGUoSi5naWQpfWlmKFEmJlEuc2l6ZT09PTApdGhpcy5ieVR5cGVHaWQuZGVsZXRlKEoudHlwZSl9aWYoSi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoSi50eXBlKTtpZihRKXtmb3IobGV0IFkgb2YgSi50YWdzKXtsZXQgVj1RLmdldChZKTtpZihWKXtpZihWLmRlbGV0ZSgkKSxWLnNpemU9PT0wKVEuZGVsZXRlKFkpfX1pZihRLnNpemU9PT0wKXRoaXMuYnlUeXBlVGFnLmRlbGV0ZShKLnR5cGUpfX19Y2xlYXJJbmRleGVzKCl7dGhpcy5ieVR5cGUuY2xlYXIoKSx0aGlzLmJ5VHlwZVBpZC5jbGVhcigpLHRoaXMuYnlUeXBlR2lkLmNsZWFyKCksdGhpcy5ieVR5cGVUYWcuY2xlYXIoKX1idWNrZXRMaXN0KCQpe2lmKCEkfHwkLnNpemU9PT0wKXJldHVybltdO2xldCBKPVtdO2ZvcihsZXQgWiBvZiAkLnZhbHVlcygpKUoucHVzaChaKTtyZXR1cm4gSn1hc3luYyBhcHBseSgkKXtsZXQgSj1uZXcgU2V0LFo9W10sUT1bXTtmb3IobGV0IFkgb2YgJCl7bGV0IFY9QihZLmVpZCksWD10aGlzLmVudHMuZ2V0KFYpLFtXLHpdPSQkKFgsWSk7aWYoeiE9PTApe1EucHVzaCh6KTtjb250aW51ZX1pZihXPT09dm9pZCAwKXtRLnB1c2goMTIpO2NvbnRpbnVlfWZvcihsZXQgSyBvZiBKJChYLFcpKUouYWRkKEspO3RoaXMucHV0KFcpLFoucHVzaChZLmVpZCksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOkosZWlkczpafX1hc3luYyBjbGVhcigpe3JldHVybiB0aGlzLmVudHMuY2xlYXIoKSx0aGlzLmNsZWFySW5kZXhlcygpLDB9YXN5bmMgZ2V0Um93KCQpe2xldCBKPUIoJCksWj10aGlzLmVudHMuZ2V0KEopO3JldHVybiBPKFopfWFzeW5jIGdldEVudCgkKXtsZXRbSixaXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwfHwhbChKKSlyZXR1cm4gTyh2b2lkIDApO3JldHVybiBPKEopfWFzeW5jIGdldEFsbEVudGl0aWVzKHt0eXBlOiQsZ2lkOkoscGlkOlosdGFnOlEsdXBkYXRlZEJldHdlZW46WX0pe2lmKHRoaXMudXNlSW5kZXgpe2lmKFohPT12b2lkIDApe2xldCBYPUIoWik7cmV0dXJuIE8odGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlUGlkLmdldCgkKT8uZ2V0KFgpKSl9aWYoSiE9PXZvaWQgMClyZXR1cm4gTyh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVHaWQuZ2V0KCQpPy5nZXQoSikpKTtpZihRIT09dm9pZCAwKXJldHVybiBPKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZVRhZy5nZXQoJCk/LmdldChRKSkpO2lmKFkhPT12b2lkIDApe2xldCBYPVtdLFc9dGhpcy5ieVR5cGUuZ2V0KCQpO2lmKFcpe2ZvcihsZXQgeiBvZiBXLnZhbHVlcygpKWlmKHoudXBkYXRlZEF0Pj1ZLnN0YXJ0JiZ6LnVwZGF0ZWRBdDw9WS5lbmQpWC5wdXNoKHopfXJldHVybiBPKFgpfXJldHVybiBPKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZS5nZXQoJCkpKX1sZXQgVj1bXTtpZihaIT09dm9pZCAwKXtmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQmJlgucGlkJiZyKFgucGlkLFopKVYucHVzaChYKX1lbHNlIGlmKEohPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JCYmKHR5cGVvZiBYLmdpZD09PSJzdHJpbmciJiZYLmdpZD09PUopKVYucHVzaChYKX1lbHNlIGlmKFEhPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JCYmWC50YWdzJiZYLnRhZ3MuaW5jbHVkZXMoUSkpVi5wdXNoKFgpfWVsc2UgaWYoWSE9PXZvaWQgMCl7Zm9yKGxldCBYIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihsKFgpJiZYLnR5cGU9PT0kJiZYLnVwZGF0ZWRBdD49WS5zdGFydCYmWC51cGRhdGVkQXQ8PVkuZW5kKVYucHVzaChYKX1lbHNlIGZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JClWLnB1c2goWCk7cmV0dXJuIE8oVil9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gTyhKKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZih0aGlzLnVzZUluZGV4KXJldHVybiBPKHRoaXMuYnlUeXBlLmdldCgkKT8uc2l6ZT8/MCk7bGV0IEo9MDtmb3IobGV0IFogb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWikmJloudHlwZT09PSQpSis9MTtyZXR1cm4gTyhKKX1hc3luYyBjaGVja3N1bSgkKXtsZXQgSj1bXTtmb3IobGV0IFogb2YgdGhpcy5lbnRzLnZhbHVlcygpKUoucHVzaChTJChaKSk7cmV0dXJuIEUkKEosJCl9fWFzeW5jIGZ1bmN0aW9uIG9aKCQpe2xldCBKPWF3YWl0IHJaKCk7aWYoJD8uY2FjaGU9PT0hMSlyZXR1cm4gSjtyZXR1cm4gbmV3IEFKKEosdm9pZCAwLHtpbmRleGVzOiQ/LmluZGV4ZXN9KX1jbGFzcyBBSnttZW07ZHVyYWJsZTt3YXJtZWQ9bmV3IFNldDtsaXN0ZW5lcnM9bmV3IFNldDtjaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtjb25zdHJ1Y3RvcigkLEosWil7aWYodGhpcy5kdXJhYmxlPSQsdGhpcy5tZW09bmV3IERKKEo/P1tdLHtpbmRleGVzOlo/LmluZGV4ZXN9KSxKKWZvcihsZXQgUSBvZiBKKXRoaXMud2FybWVkLmFkZChRLnR5cGUpfXN1YnNjcmliZSgkKXtyZXR1cm4gdGhpcy5saXN0ZW5lcnMuYWRkKCQpLCgpPT57dGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQpe2lmKCQuc2l6ZTwxKXJldHVybjtmb3IobGV0IEogb2YgdGhpcy5saXN0ZW5lcnMpSigkKX1ydW4oJCl7bGV0IEo9dGhpcy5jaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuY2hhaW49Si50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLEp9YXBwbHkoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9Pnthd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChWKT0+Vi5laWQpKTtsZXQgSj1jWSh0aGlzLm1lbSwkKTt0aGlzLmVtaXQoSi50eXBlcyk7bGV0IFo9YXdhaXQgdGhpcy5kdXJhYmxlLmFwcGx5KCQpLHtjaGFuZ2VkOlEsc3RhdHVzOll9PWF3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFYpPT5WLmVpZCkpO2lmKHRoaXMuZW1pdChRKSxZIT09MClyZXR1cm57c3RhdHM6JC5tYXAoKCk9PlkpLHR5cGVzOloudHlwZXMsZWlkczpaLmVpZHN9O3JldHVybiBafSl9Y2xlYXIoKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuZHVyYWJsZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBKPXRoaXMubWVtLmVudHMuc2l6ZT4wO3JldHVybiBhd2FpdCB0aGlzLm1lbS5jbGVhcigpLHRoaXMud2FybWVkLmNsZWFyKCksMH0pfWluZ2VzdEZyb21EdXJhYmxlKCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0e2NoYW5nZWQ6SixzdGF0dXM6Wn09YXdhaXQgdGhpcy5wdWxsRWlkcygkKTtyZXR1cm4gdGhpcy5lbWl0KEopLFp9KX1hc3luYyBwdWxsRWlkcygkKXtsZXQgSj1uZXcgU2V0LFo9bmV3IFNldDtmb3IobGV0IFEgb2YgJCl7bGV0IFk9QihRKTtpZihaLmhhcyhZKSljb250aW51ZTtaLmFkZChZKTtsZXQgVj10aGlzLm1lbS5lbnRzLmdldChZKSxbWCxXXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KFEpO2lmKFchPT0wKXJldHVybntjaGFuZ2VkOkosc3RhdHVzOld9O2lmKFgpe2lmKHRoaXMubWVtLnB1dChYKSwhVnx8IWhZKFYsWCkpe2lmKGwoWCkpSi5hZGQoWC50eXBlKTtpZihWIT09dm9pZCAwJiZsKFYpKUouYWRkKFYudHlwZSl9fWVsc2UgaWYoViE9PXZvaWQgMCl7aWYodGhpcy5tZW0uZGVsKFkpLGwoVikpSi5hZGQoVi50eXBlKX19cmV0dXJue2NoYW5nZWQ6SixzdGF0dXM6MH19YXN5bmMgd2FybVR5cGUoJCl7aWYodGhpcy53YXJtZWQuaGFzKCQpKXJldHVybiAwO2xldFtKLFpdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRFbnRpdGllcyh7dHlwZTokfSk7aWYoWiE9PTApcmV0dXJuIFo7aWYoSilmb3IobGV0IFEgb2YgSil7bGV0IFk9QihRLmVpZCksVj10aGlzLm1lbS5lbnRzLmdldChZKTtpZighVnx8cFkoUSxWKSl0aGlzLm1lbS5wdXQoUSl9cmV0dXJuIHRoaXMud2FybWVkLmFkZCgkKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgSj1CKCQpO2lmKHRoaXMubWVtLmVudHMuaGFzKEopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntpZih0aGlzLm1lbS5lbnRzLmhhcyhKKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO2xldFtaLFFdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWil0aGlzLm1lbS5wdXQoWik7cmV0dXJuIE8oWil9KX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IWwoSikpcmV0dXJuIE8odm9pZCAwKTtyZXR1cm4gTyhKKX1hc3luYyBnZXRFbnRpdGllcygkKXtpZighdGhpcy53YXJtZWQuaGFzKCQudHlwZSkpe2xldCBKPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQudHlwZSkpO2lmKEohPT0wKXJldHVybiBHKEopfXJldHVybiB0aGlzLm1lbS5nZXRFbnRpdGllcygkKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZighdGhpcy53YXJtZWQuaGFzKCQpKXtsZXQgSj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkKSk7aWYoSiE9PTApcmV0dXJuIEcoSil9cmV0dXJuIHRoaXMubWVtLmNvdW50RW50aXRpZXMoe3R5cGU6JH0pfWFzeW5jIGNoZWNrc3VtKCQpe3JldHVybiB0aGlzLmR1cmFibGUuY2hlY2tzdW0oJCl9fWZ1bmN0aW9uIGhZKCQsSil7aWYobCgkKSE9PWwoSikpcmV0dXJuITE7aWYoJC5jdHIhPT1KLmN0cilyZXR1cm4hMTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCkhPT1KLnVwZGF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoIXIoJC5laWQsSi5laWQpKXJldHVybiExO2lmKCFsKCQpfHwhbChKKSlyZXR1cm4hMDtpZigkLmNyZWF0ZWRBdC5nZXRUaW1lKCkhPT1KLmNyZWF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoJC50eXBlIT09Si50eXBlKXJldHVybiExO2lmKCQuZ2lkIT09Si5naWQpcmV0dXJuITE7aWYoIWxZKCQucGlkLEoucGlkKSlyZXR1cm4hMTtpZighaVkoJC50YWdzLEoudGFncykpcmV0dXJuITE7cmV0dXJuIHVZKCQuYm9keSxKLmJvZHkpfWZ1bmN0aW9uIGlZKCQsSil7aWYoJD09PUopcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Sj09PXZvaWQgMClyZXR1cm4hMTtpZigkLmxlbmd0aCE9PUoubGVuZ3RoKXJldHVybiExO2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKWlmKCRbWl0hPT1KW1pdKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIGxZKCQsSil7aWYoJD09PXZvaWQgMCYmSj09PXZvaWQgMClyZXR1cm4hMDtpZigkPT09dm9pZCAwfHxKPT09dm9pZCAwKXJldHVybiExO3JldHVybiByKCQsSil9ZnVuY3Rpb24gdVkoJCxKKXtpZihPYmplY3QuaXMoJCxKKSlyZXR1cm4hMDtpZigkIGluc3RhbmNlb2YgVWludDhBcnJheSYmSiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuIHIoJCxKKTtpZigkIGluc3RhbmNlb2YgRGF0ZSYmSiBpbnN0YW5jZW9mIERhdGUpcmV0dXJuICQuZ2V0VGltZSgpPT09Si5nZXRUaW1lKCk7dHJ5e3JldHVybiByKGswKCQpLGswKEopKX1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gcFkoJCxKKXtsZXQgWj0kLnVwZGF0ZWRBdC5nZXRUaW1lKCksUT1KLnVwZGF0ZWRBdC5nZXRUaW1lKCk7aWYoWiE9PVEpcmV0dXJuIFo+UTtyZXR1cm4gJC5jdHI+Si5jdHJ9ZnVuY3Rpb24gY1koJCxKKXtsZXQgWj1uZXcgU2V0LFE9W107Zm9yKGxldCBZIG9mIEope2xldCBWPUIoWS5laWQpLFg9JC5lbnRzLmdldChWKSxbVyx6XT0kJChYLFkpO2lmKHohPT0wKXtRLnB1c2goeik7Y29udGludWV9aWYoVz09PXZvaWQgMCl7US5wdXNoKDEyKTtjb250aW51ZX1mb3IobGV0IEsgb2YgSiQoWCxXKSlaLmFkZChLKTskLnB1dChXKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6Wn19ZnVuY3Rpb24gbCgkKXtyZXR1cm4idHlwZSJpbiAkfWZ1bmN0aW9uIG5ZKCQpe2lmKCFBcnJheS5pc0FycmF5KCQpfHwkLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPW5ldyBTZXQsWj1bXTtmb3IobGV0IFEgb2YgJCl7aWYodHlwZW9mIFEhPT0ic3RyaW5nInx8US5sZW5ndGg9PT0wKWNvbnRpbnVlO2lmKEouaGFzKFEpKWNvbnRpbnVlO0ouYWRkKFEpLFoucHVzaChRKX1yZXR1cm4gWi5sZW5ndGg+MD9aOnZvaWQgMH1mdW5jdGlvbiBTJCgkKXtyZXR1cm57ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6JC51cGRhdGVkQXR9fWZ1bmN0aW9uIGFaKCQpe2xldCBKPW5ldyBtKCQuZWlkKSxbWixRXT1KLnJlYWRTdHJ1Y3QoVjApO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiBPKHtlaWQ6JC5laWQsY3RyOiQuY3RyLHVwZGF0ZWRBdDpuZXcgRGF0ZShaLnRzLmdldFRpbWUoKSskLm9mZil9KX1mdW5jdGlvbiAkJCgkLEope2xldCBaPW5ldyBtKEouZWlkKSxbUSxZXT1aLnJlYWRTdHJ1Y3QoVjApO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBWPW5ldyBEYXRlKFEudHMuZ2V0VGltZSgpK0oub2ZmKTtpZigkIT09dm9pZCAwJiZWPD0kLnVwZGF0ZWRBdClyZXR1cm4gRygxNSk7aWYocFooSikpe2xldCBYPW5ZKEoudGFncyk7cmV0dXJuIE8oe2VpZDpKLmVpZCxnaWQ6Si5naWQscGlkOkoucGlkLC4uLlghPT12b2lkIDA/e3RhZ3M6WH06e30sdHlwZTpKLnR5cGUsY3JlYXRlZEF0OlEudHMsdXBkYXRlZEF0OlYsY3RyOkouY3RyLGJvZHk6Si5ib2R5fSl9cmV0dXJuIE8oe2VpZDpKLmVpZCx1cGRhdGVkQXQ6VixjdHI6Si5jdHJ9KX1mdW5jdGlvbiBKJCgkLEope2xldCBaPW5ldyBTZXQ7aWYoJCE9PXZvaWQgMCYmbCgkKSlaLmFkZCgkLnR5cGUpO2lmKGwoSikpWi5hZGQoSi50eXBlKTtyZXR1cm5bLi4uWl19Y2xhc3MgdiR7aW5mbGlnaHQ9bnVsbDthZ2Fpbj0hMTtydW4oJCl7aWYodGhpcy5hZ2Fpbj0hMCx0aGlzLmluZmxpZ2h0KXJldHVybiB0aGlzLmluZmxpZ2h0O3JldHVybiB0aGlzLmluZmxpZ2h0PXRoaXMuZHJhaW4oJCksdGhpcy5pbmZsaWdodH1hc3luYyBmbHVzaCgpe2lmKCF0aGlzLmluZmxpZ2h0KXJldHVybjt0cnl7YXdhaXQgdGhpcy5pbmZsaWdodH1jYXRjaHt9fWFzeW5jIGRyYWluKCQpe3RyeXt0aGlzLmFnYWluPSExO2xldCBKPWF3YWl0ICQoKTt3aGlsZSh0aGlzLmFnYWluKXRoaXMuYWdhaW49ITEsSj1hd2FpdCAkKCk7cmV0dXJuIEp9ZmluYWxseXt0aGlzLmluZmxpZ2h0PW51bGx9fX12YXIgc1o9MTAwO2NsYXNzIF9Ke3RpbWVyPW51bGw7ZGVsYXlNczt3b3JrO3RhaWw9bmV3IHYkO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5kZWxheU1zPSQ8MD8wOiQsdGhpcy53b3JrPUp9c2NoZWR1bGUoKXtpZih0aGlzLmRlbGF5TXM8PTApe3RoaXMuZmlyZSgpO3JldHVybn1pZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lcik7dGhpcy50aW1lcj1zZXRUaW1lb3V0KCgpPT57dGhpcy50aW1lcj1udWxsLHRoaXMuZmlyZSgpfSx0aGlzLmRlbGF5TXMpfWFzeW5jIGZsdXNoKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKTthd2FpdCB0aGlzLnRhaWwuZmx1c2goKX1jYW5jZWwoKXtpZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj1udWxsfWZpcmUoKXtyZXR1cm4gdGhpcy50YWlsLnJ1bih0aGlzLndvcmspfX1mdW5jdGlvbiB0WigkKXtsZXQgSj1uZXcgbSgkLmVpZCksW1osUV09VjAuZGVjb2RlKEopO2lmKFEhPT0wKXJldHVybjtyZXR1cm4gWi50cy5nZXRUaW1lKCkrJC5vZmZ9ZnVuY3Rpb24gZFkoJCxKKXtsZXQgWj10WigkKSxRPXRaKEopO2lmKFo9PT12b2lkIDAmJlE9PT12b2lkIDApcmV0dXJuIDA7aWYoWj09PXZvaWQgMClyZXR1cm4gMTtpZihRPT09dm9pZCAwKXJldHVybi0xO2lmKFEhPT1aKXJldHVybiBRLVo7cmV0dXJuIEouY3RyLSQuY3RyfWZ1bmN0aW9uIFokKCQsSil7cmV0dXJuICQuc2xpY2UoKS5zb3J0KChaLFEpPT5kWShKKFopLEooUSkpKX12YXIgTEo9e3BoYXNlOiJpZGxlIn0sVSQ9NTA7ZnVuY3Rpb24geEooJCxKLFope2lmKCQ8PTB8fEo8PTApcmV0dXJuITE7aWYoJD09PTF8fCQ9PT1KKXJldHVybiEwO3JldHVybiAkJVo9PT0wfWZ1bmN0aW9uIGVaKCQsSil7aWYodHlwZW9mIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iPT09ImZ1bmN0aW9uIil7bmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IoJCxKKTtyZXR1cm59bGV0IFo9VVJMLmNyZWF0ZU9iamVjdFVSTCgkKSxRPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTtRLmhyZWY9WixRLmRvd25sb2FkPUosZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChRKSxRLmNsaWNrKCksZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChRKSxVUkwucmV2b2tlT2JqZWN0VVJMKFopfWZ1bmN0aW9uICRRKCQsSixaKXtsZXQgUT1bXSxZPVtdLFY9MDtmb3IobGV0IFggb2YgJCl7bGV0IFc9SihYKTtpZihZLmxlbmd0aD4wJiZWK1c+WilRLnB1c2goWSksWT1bXSxWPTA7aWYoWS5wdXNoKFgpLFYrPVcsVj49WilRLnB1c2goWSksWT1bXSxWPTB9aWYoWS5sZW5ndGg+MClRLnB1c2goWSk7cmV0dXJuIFF9YXN5bmMgZnVuY3Rpb24gQkooJCxKLFope2xldCBRPSQubGVuZ3RoO2lmKFE8MSlyZXR1cm5bXTtsZXQgWT1BcnJheShRKSxWPTAsWD1NYXRoLm1pbihNYXRoLm1heCgxLEopLFEpLFc9YXN5bmMoKT0+e3doaWxlKCEwKXtsZXQgSz1WO2lmKFYrPTEsSz49USlyZXR1cm47WVtLXT1hd2FpdCBaKCRbS10sSyl9fSx6PVtdO2ZvcihsZXQgSz0wO0s8WDtLKyspei5wdXNoKFcoKSk7cmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKHopLFl9YXN5bmMgZnVuY3Rpb24geSQoJCxKLFosUSl7bGV0IFk9bmV3IG0oJC5oZWFkQ3BoKSxbVixYXT1ZLnJlYWRTdHJ1Y3QoeCQpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldHtzaWc6VyxrZG06eixoZWFkQ3BoOkt9PVY7aWYoIWF3YWl0IFEuY2hlY2tTaWdFZDI1NTE5KFcsSyxKKSlyZXR1cm4gRygzKTtsZXQgTj1aLmRlcml2ZUNpcGhlcih6LCJkZWNyeXB0IiksVTt0cnl7VT1hd2FpdCBOLmRlY3J5cHQoSyl9Y2F0Y2h7cmV0dXJuIEcoMjApfXJldHVybiBPKHtrZG06eixoZWFkRW5jOlV9KX12YXIgWSQ9ImYiLGIkPSJ0IixRJD0iZSI7ZnVuY3Rpb24gclkoJCl7aWYoJD09PSEwfHwkPT09YiQpcmV0dXJuIGIkO2lmKCQ9PT1RJClyZXR1cm4gUSQ7cmV0dXJuIFkkfWZ1bmN0aW9uIEpRKCQpe3JldHVybiAkIT09MCYmJCE9PTE1JiYkIT09MTgmJiQhPT0xN31mdW5jdGlvbiBrSigkLEosWil7aWYoJC5hcGxkPUosSj09PVEkJiZaIT09dm9pZCAwKSQuZXJyPVo7ZWxzZSBkZWxldGUgJC5lcnJ9YXN5bmMgZnVuY3Rpb24gaCQoJCxKLFosUSl7bGV0IFk9UT8uYm9keSE9PSExLFY9clkoSi5hcGxkKSxYPUouYm9keSxXPVg/Lmxlbmd0aD8/MCx6O2lmKFkmJlgmJlc+MCl6PWF3YWl0IFouYmxha2UzKFgpO2xldCBLPXtlaWQ6Si5laWQsb2ZmOkoub2ZmPz8wLGN0cjpKLmN0cj8/MCxsZW46Vyxoc2g6en0sRj17aGFzaDokLGhlYWQ6SyxhcGxkOlZ9O2lmKFkmJlghPT12b2lkIDApRi5ib2R5PVg7aWYoVj09PVEkJiZKLmVyciE9PXZvaWQgMClGLmVycj1KLmVycjtyZXR1cm4gRn12YXIgZko9MTA0ODU3NixFSj0xMDQ4NTc2LFFRPTY0O2Z1bmN0aW9uIG9ZKCQpe3JldHVybiAkLnNpZy5sZW5ndGgrJC5rZG0ubGVuZ3RoKyQuaGVhZENwaC5sZW5ndGgrJC5ib2R5Q3BoLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBhWSgkLEosWixRLFkpe2lmKFEubGVuZ3RoPDEpcmV0dXJuIDA7bGV0W1YsWF09YXdhaXQgJC5wdXNoKFEpO2lmKFghPT0wKXJldHVybiBYO2lmKCFWKXJldHVybiAyNztmb3IobGV0IHogb2YgVil7aWYoei5zdGF0dXMhPT0wKXtjb25zb2xlLmVycm9yKCJwdXNoIGVyciIseik7Y29udGludWV9bGV0IEs9WVt6LmlkeF07aWYoIUspe2NvbnNvbGUuZXJyb3IoIm5vIGhhc2giLHopO2NvbnRpbnVlfWF3YWl0IEoudXBsb2Fkcy5kZXEoWixbS10pfWxldCBXPWF3YWl0IEouaG9zdHMuZ2V0KFopO2lmKFcpe2xldCB6PVcubGFzdFNlcSxLPXosRj1bXTtmb3IobGV0IE4gb2YgVilpZihOLnN0YXR1cz09PTApRi5wdXNoKE4uc2VxKTtGLnNvcnQoKE4sVSk9Pk4tVSk7Zm9yKGxldCBOIG9mIEYpaWYoTj09PXorMSl6PU47aWYoej5LKWF3YWl0IEouaG9zdHMudG91Y2goWix6KX1yZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBaUSgkLEope2lmKEoubGVuZ3RoPDEpcmV0dXJuIE8oW10pO2xldCBaPW5ldyBNYXAsUT1bXTtmb3IobGV0IFcgb2YgSilaLnNldChXLnNlcSxXKSxRLnB1c2goVy5zZXEpO2xldFtZLFZdPWF3YWl0ICQucHVsbChRKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZighWSlyZXR1cm4gRygyNyk7bGV0IFg9W107Zm9yKGxldHtzZXE6Vyxib2R5Q3BoOnp9b2YgWSl7bGV0IEs9Wi5nZXQoVyk7aWYoIUspY29udGludWU7WC5wdXNoKHtkbDpLLGJvZHlDcGg6en0pfXJldHVybiBPKFgpfWFzeW5jIGZ1bmN0aW9uIHNZKCQsSixaLFEpe2lmKFEubGVuZ3RoPDEpcmV0dXJuIE8oe3BhcnRzOltdLGhhc2hlczpbXX0pO2xldCBZPVtdLFY9W10sWD1bXSxXPW5ldyBNYXA7Zm9yKGxldHtkbDpLLGJvZHlDcGg6Rn1vZiBRKXtsZXR7aGVhZDpOLGtkbTpVLHNlcTpSLGhvc3Q6SH09SyxbcSxNXT1hd2FpdCBZUShLLFopO2lmKE0hPT0wfHwhcSl7bGV0IGs9Vy5nZXQoSCk/P1tdO2sucHVzaChSKSxXLnNldChILGspO2NvbnRpbnVlfWxldHtoZWFkRW5jOlAsaGVhZEVuY0hhc2g6Q309cSxUPUouZGVyaXZlQ2lwaGVyKFUsImRlY3J5cHQiKSxbSSxBXT1hd2FpdCBGSihQLEYsVCxaLEMpO2lmKEEhPT0wfHwhSSl7bGV0IGs9Vy5nZXQoSCk/P1tdO2sucHVzaChSKSxXLnNldChILGspO2NvbnRpbnVlfWxldCBMPXtoZWFkOk4sYm9keTpJLmJvZH0sZz1JLmhlYWRIYXNoO1gucHVzaCh7a2V5OmcsZGF0YTpXUShMKX0pLFkucHVzaChMKSxWLnB1c2goZyk7bGV0IEU9Vy5nZXQoSCk/P1tdO0UucHVzaChSKSxXLnNldChILEUpfWxldCB6PWF3YWl0ICQubWVzc2FnZXMuYWRkKFgpO2ZvcihsZXRbSyxGXW9mIFcpYXdhaXQgJC5kb3dubG9hZHMuZGVxKEssRik7Zm9yKGxldCBLPTA7Szx6Lmxlbmd0aDtLKyspe2xldCBGPXpbS107aWYoRiE9PTAmJkYhPT0xNSljb25zb2xlLmVycm9yKCJFUlIgc3RvcmluZyIsRFtGXSwiZm9yIG1lc3NhZ2UiLEspfXJldHVybiBPKHtwYXJ0czpZLGhhc2hlczpWfSl9YXN5bmMgZnVuY3Rpb24gWVEoJCxKKXtsZXQgWj0kLmhlYWRFbmM7aWYoIVope2xldCBZPW5ldyBTLFY9WS53cml0ZVN0cnVjdChHMCwkLmhlYWQpO2lmKFYhPT0wKXJldHVybiBHKFYpO1o9WS5yZXN1bHQoKX1pZigkLmhlYWRFbmNIYXNoKXJldHVybiBPKHtoZWFkRW5jOlosaGVhZEVuY0hhc2g6JC5oZWFkRW5jSGFzaH0pO2xldCBRPWF3YWl0IEouYmxha2UzKFopO3JldHVybiBPKHtoZWFkRW5jOlosaGVhZEVuY0hhc2g6UX0pfWFzeW5jIGZ1bmN0aW9uIFZRKCQsSixaKXtsZXQgUT1uZXcgU2V0O2ZvcihsZXQgWCBvZiBKKVEuYWRkKEIoWCkpO2lmKFEuc2l6ZTwxKXJldHVybjtsZXQgWT1BcnJheS5mcm9tKGF3YWl0ICQuZG93bmxvYWRzLmxpc3QoKSk7aWYoWS5sZW5ndGg8MSlyZXR1cm47bGV0IFY9bmV3IE1hcDtmb3IobGV0IFggb2YgWSl7bGV0IFc7aWYoWC5oZWFkRW5jSGFzaClXPUIoWC5oZWFkRW5jSGFzaCk7ZWxzZXtsZXRbSyxGXT1hd2FpdCBZUShYLFopO2lmKEYhPT0wfHwhSyljb250aW51ZTtXPUIoSy5oZWFkRW5jSGFzaCl9aWYoIVEuaGFzKFcpKWNvbnRpbnVlO2xldCB6PVYuZ2V0KFguaG9zdCk/P1tdO3oucHVzaChYLnNlcSksVi5zZXQoWC5ob3N0LHopfWZvcihsZXRbWCxXXW9mIFYpYXdhaXQgJC5kb3dubG9hZHMuZGVxKFgsVyl9YXN5bmMgZnVuY3Rpb24gZ0ooe2Nvbm46JCxzdG9yZTpKLGVuY2xhdmU6Wixob3N0OlEsY3J5cHRvOlksb25Qcm9ncmVzczpWLHBlZWtQcm9ncmVzc0V2ZXJ5OlgscGVla0NvbmN1cnJlbmN5Old9KXtsZXQgej1hd2FpdCAkLmlkZW50aXR5KCksSz1bXSxbRixOXT1hd2FpdCAkLnBlZWsoUS5sYXN0U2VxKTtpZihOIT09MClyZXR1cm4gTjtsZXQgVT1GLmxlbmd0aCxSPVg/P1UkLEg9Vz8/UVE7aWYoViYmVT4wKVYoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTowLHRvdGFsOlV9KTtsZXQgcT0wLE09YXdhaXQgQkooRixILGFzeW5jKEMpPT57bGV0W1QsSV09YXdhaXQgeSQoQyx6LnB1YmxpY0tleSxaLFkpLEE7aWYoSSE9PTB8fCFUKUE9e29rOiExLHNlcTpDLnNlcSxzdGF0Okl9O2Vsc2V7bGV0IEw9YXdhaXQgWS5ibGFrZTMoVC5oZWFkRW5jKTtBPXtvazohMCxzZXE6Qy5zZXEsa2RtOlQua2RtLGhlYWRFbmM6VC5oZWFkRW5jLGhlYWRFbmNIYXNoOkx9fWlmKHErPTEsViYmeEoocSxVLFIpKVYoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTpxLHRvdGFsOlV9KTtyZXR1cm4gQX0pLFA9bmV3IFNldDtmb3IobGV0IEMgb2YgTSl7aWYoIUMub2spe2NvbnNvbGUuZXJyb3IoInBlZWs6IGRlY3J5cHRpbmcgaXRlbSBoZWFkIixDLnN0YXQpO2NvbnRpbnVlfWxldCBUPUIoQy5oZWFkRW5jSGFzaCk7aWYoYXdhaXQgSi5tZXNzYWdlcy5oYXMoQy5oZWFkRW5jSGFzaCkpe2NvbnNvbGUuaW5mbygicGVlazogbG9jYWwgbXNnOyBza2lwIGRvd25sb2FkLCBkZXEgdXBsb2FkIiksYXdhaXQgSi51cGxvYWRzLmRlcShRLmxhYmVsLFtDLmhlYWRFbmNIYXNoXSksYXdhaXQgSi5kb3dubG9hZHMuZGVxKFEubGFiZWwsW0Muc2VxXSk7Y29udGludWV9aWYoUC5oYXMoVCkpe2F3YWl0IEouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtDLnNlcV0pO2NvbnRpbnVlfWxldCBBPW5ldyBtKEMuaGVhZEVuYyksW0wsZ109QS5yZWFkU3RydWN0KEcwKTtpZihnIT09MCl7Y29uc29sZS5lcnJvcigicGVlazogcmVhZGluZyBpdGVtIGhlYWQiLGcpO2NvbnRpbnVlfVAuYWRkKFQpLEsucHVzaCh7a2RtOkMua2RtLGhlYWQ6TCxzZXE6Qy5zZXEsaG9zdDpRLmxhYmVsLGhlYWRFbmM6Qy5oZWFkRW5jLGhlYWRFbmNIYXNoOkMuaGVhZEVuY0hhc2h9KX1pZihhd2FpdCBKLmRvd25sb2Fkcy5lbnEoSyksRi5sZW5ndGg+MCl7bGV0IEM9TWF0aC5tYXgoLi4uRi5tYXAoKFQpPT5ULnNlcSkpO2F3YWl0IEouaG9zdHMucmVjb3JkU3RhdHMoUS5sYWJlbCx7bGFzdFNlcTpDfSl9aWYoVilWKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6VSx0b3RhbDpVfSk7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gWFEoe2Nvbm46JCxzdG9yZTpKLGhvc3Q6WixtYXhQdXNoQnl0ZXM6USxvblByb2dyZXNzOll9KXtsZXQgVj1RPz9mSixYPWF3YWl0IEoudXBsb2Fkcy5saXN0KFoubGFiZWwpLFc9WC5sZW5ndGgsej0wO2lmKFkmJlc+MClZKHtwaGFzZToicHVzaCIsaG9zdDpaLmxhYmVsLGRvbmU6MCx0b3RhbDpXfSk7bGV0IEs9W10sRj1bXSxOPTAsVT1hc3luYygpPT57aWYoSy5sZW5ndGg8MSlyZXR1cm4gMDtsZXQgUj1LLmxlbmd0aCxIPWF3YWl0IGFZKCQsSixaLmxhYmVsLEssRik7aWYoSz1bXSxGPVtdLE49MCxIPT09MCl7aWYoeis9UixZKVkoe3BoYXNlOiJwdXNoIixob3N0OloubGFiZWwsZG9uZTp6LHRvdGFsOld9KX1yZXR1cm4gSH07Zm9yKGxldCBSIG9mIFgpe2xldCBIPWF3YWl0IEoubWVzc2FnZXMuZ2V0KFIpO2lmKCFIKXt6Kz0xO2NvbnRpbnVlfWxldCBxPXsuLi5ILmhlYWQsYm9kOkguYm9keX0sW00sUF09YXdhaXQgJC5zZWFsKHEpO2lmKFAhPT0wKXJldHVybiBQO2lmKCFNKXJldHVybiAxMjtsZXQgQz1vWShNKTtpZihLLmxlbmd0aD4wJiZOK0M+Vil7bGV0IFQ9YXdhaXQgVSgpO2lmKFQhPT0wKXJldHVybiBUfWlmKEsucHVzaChNKSxGLnB1c2goUiksTis9QyxOPj1WKXtsZXQgVD1hd2FpdCBVKCk7aWYoVCE9PTApcmV0dXJuIFR9fXJldHVybiBVKCl9YXN5bmMgZnVuY3Rpb24gbUooe2Nvbm46JCxzdG9yZTpKLGVuY2xhdmU6Wixob3N0OlEsY3J5cHRvOlksbWF4UHVsbEJ5dGVzOlYsb25Qcm9ncmVzczpYfSxXKXtsZXQgej1WPz9FSixLPWF3YWl0IEouZG93bmxvYWRzLmxpc3QoKSxGPUFycmF5LmZyb20oSykuZmlsdGVyKChNKT0+TS5ob3N0PT09US5sYWJlbCk7aWYoRi5sZW5ndGg8MSlyZXR1cm4gMTU7bGV0IE49WiQoRiwoTSk9Pk0uaGVhZCksVT0kUShOLChNKT0+TS5oZWFkLmxlbix6KSxSPU4ubGVuZ3RoLEg9MDtpZihYKVgoe3BoYXNlOiJwdWxsIixob3N0OlEubGFiZWwsZG9uZTowLHRvdGFsOlJ9KTtsZXQgcT1aUSgkLFVbMF0pO2ZvcihsZXQgTT0wO008VS5sZW5ndGg7TSsrKXtsZXRbUCxDXT1hd2FpdCBxO2lmKEMhPT0wfHwhUClyZXR1cm4gQztpZihIKz1VW01dLmxlbmd0aCxYKVgoe3BoYXNlOiJwdWxsIixob3N0OlEubGFiZWwsZG9uZTpILHRvdGFsOlJ9KTtsZXQgVD1VW00rMV07aWYoVClxPVpRKCQsVCk7aWYoWClYKHtwaGFzZToib3BlbiIsaG9zdDpRLmxhYmVsLGRvbmU6SCx0b3RhbDpSfSk7bGV0IEk9WiQoUCwoTCk9PkwuZGwuaGVhZCksWyxBXT1hd2FpdCBzWShKLFosWSxJKTtpZihBIT09MClyZXR1cm4gQTtpZihXKXtpZihYKVgoe3BoYXNlOiJleGVjIixob3N0OlEubGFiZWwsZG9uZTpILHRvdGFsOlJ9KTthd2FpdCBXKCl9fXJldHVybiAwfWZ1bmN0aW9uIFdRKHtoZWFkOiQsYm9keTpKfSl7bGV0IFo9e2VpZDokLmVpZCxib2R5OkosYXBsZDpZJH07aWYoJC5vZmYhPT0wKVoub2ZmPSQub2ZmO2lmKCQuY3RyIT09MClaLmN0cj0kLmN0cjtyZXR1cm4gWn1hc3luYyBmdW5jdGlvbiBHUSgkLHtjb25uOkosc3RvcmU6WixlbmNsYXZlOlEsaG9zdDpZLGNyeXB0bzpWLG9uUHJvZ3Jlc3M6WH0sVyl7bGV0IHo9WS5sYWJlbCxLPWF3YWl0IEouaWRlbnRpdHkoKSxGPW5ldyBtKCQpLFtOLFVdPUYucmVhZFN0cnVjdHMoTCQpO2lmKFUhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjb2Rpbmcgbm90aWYiLERbVV0pO3JldHVybn1sZXQgUj0hMSxxPShhd2FpdCBaLmhvc3RzLmdldCh6KSk/Lmxhc3RTZXEsTT1bXSxQPSExO2ZvcihsZXQgSSBvZiBOKXtsZXRbQSxMXT1hd2FpdCB5JCh7c2VxOkkuc2VxLGhlYWRDcGg6SS5oZWFkQ3BofSxLLnB1YmxpY0tleSxRLFYpO2lmKEwhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgZGVjcnlwdGluZyBub3RpZiIsRFtMXSk7Y29udGludWV9bGV0IGc9YXdhaXQgVi5ibGFrZTMoQS5oZWFkRW5jKTtpZihhd2FpdCBaLm1lc3NhZ2VzLmhhcyhnKSljb250aW51ZTtsZXQgRT1uZXcgbShBLmhlYWRFbmMpLFtrLHldPUUucmVhZFN0cnVjdChHMCk7aWYoeSE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBwYXJzZSBoZWFkIixEW3ldKTtjb250aW51ZX1pZighSS5ib2R5Q3BoJiZrLmxlbj4wKVA9ITAsYXdhaXQgWi5kb3dubG9hZHMuZW5xKFt7c2VxOkkuc2VxLGhvc3Q6eixrZG06QS5rZG0saGVhZDprLGhlYWRFbmM6QS5oZWFkRW5jLGhlYWRFbmNIYXNoOmd9XSk7ZWxzZSBNLnB1c2goey4uLkEsaGVhZDprLGJvZHlDcGg6SS5ib2R5Q3BoLGhlYWRFbmNIYXNoOmd9KTtpZihxPT09dm9pZCAwfHxJLnNlcSE9PXErMSljb25zb2xlLmxvZygib3V0IG9mIHNlcSIsSS5zZXEscSksUj0hMDtlbHNlIHE9SS5zZXF9aWYocSE9PXZvaWQgMClhd2FpdCBaLmhvc3RzLnRvdWNoKFkubGFiZWwscSk7bGV0IEM9W107Zm9yKGxldCBJIG9mIE0pe2xldCBBPVEuZGVyaXZlQ2lwaGVyKEkua2RtLCJkZWNyeXB0IiksW0wsZ109YXdhaXQgRkooSS5oZWFkRW5jLEkuYm9keUNwaCxBLFYpO2lmKGchPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gb3BlbiBib2R5IixEW2ddKTtjb250aW51ZX1DLnB1c2goe2tleTpJLmhlYWRFbmNIYXNoLGRhdGE6V1Eoe2hlYWQ6SS5oZWFkLGJvZHk6TC5ib2R9KX0pfWxldCBUPWF3YWl0IFoubWVzc2FnZXMuYWRkKEMpO2ZvcihsZXQgST0wO0k8VC5sZW5ndGg7SSsrKXtsZXQgQT1UW0ldO2lmKEEhPT0wJiZBIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLERbQV0sImZvciBtZXNzYWdlIixJKX1pZihYJiZDLmxlbmd0aD4wKVgoe3BoYXNlOiJvcGVuIixob3N0OlkubGFiZWwsZG9uZTpDLmxlbmd0aCx0b3RhbDpDLmxlbmd0aH0pO2lmKFJ8fFB8fEMubGVuZ3RoPjApVygpfWFzeW5jIGZ1bmN0aW9uIFNKKCQsSj17fSl7bGV0IFo9Si5wdWxsIT09ITEsUT1KLnB1c2g9PT0hMCx7Y29ubjpZLHN0b3JlOlYsZW5jbGF2ZTpYLGhvc3Q6VyxjcnlwdG86eixvblByb2dyZXNzOksscGVla1Byb2dyZXNzRXZlcnk6RixwZWVrQ29uY3VycmVuY3k6Tn09JCxVPWF3YWl0IFkuaWRlbnRpdHkoKSxbUixIXT1hd2FpdCBZLnBlZWsoMCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7bGV0IHE9Ui5sZW5ndGgsTT1GPz9VJCxQPU4/P1FRO2lmKEsmJnE+MClLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6MCx0b3RhbDpxfSk7bGV0IEM9MCxUPWF3YWl0IEJKKFIsUCxhc3luYyh4KT0+e2xldFt2LGZdPWF3YWl0IHkkKHgsVS5wdWJsaWNLZXksWCx6KSxpO2lmKGYhPT0wfHwhdilpPXtvazohMSxzZXE6eC5zZXEsc3RhdDpmfTtlbHNle2xldCBfPWF3YWl0IHouYmxha2UzKHYuaGVhZEVuYyk7aT17b2s6ITAsc2VxOnguc2VxLGtkbTp2LmtkbSxoZWFkRW5jOnYuaGVhZEVuYyxoZWFkRW5jSGFzaDpffX1pZihDKz0xLEsmJnhKKEMscSxNKSlLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6Qyx0b3RhbDpxfSk7cmV0dXJuIGl9KSxJPW5ldyBNYXA7Zm9yKGxldCB4IG9mIFQpe2lmKCF4Lm9rKWNvbnRpbnVlO2xldCB2PUIoeC5oZWFkRW5jSGFzaCksZj1JLmdldCh2KTtpZihmKWYuY291bnQrPTE7ZWxzZSBJLnNldCh2LHtoYXNoOnguaGVhZEVuY0hhc2gsY291bnQ6MSxzYW1wbGU6eH0pfWxldCBBPTAsTD1bXTtmb3IobGV0IHggb2YgSS52YWx1ZXMoKSl7aWYoeC5jb3VudD4xKUErPXguY291bnQtMTtMLnB1c2goeC5oYXNoKX1sZXQgZz1SLmxlbmd0aCxFPUkuc2l6ZSxrPWF3YWl0IE8kKEwseikseT1bXSxoPTA7Zm9yKGxldCB4IG9mIEkudmFsdWVzKCkpe2lmKGF3YWl0IFYubWVzc2FnZXMuaGFzKHguaGFzaCkpe2F3YWl0IFYudXBsb2Fkcy5kZXEoVy5sYWJlbCxbeC5oYXNoXSk7Y29udGludWV9aWYoaCs9MSwhWiljb250aW51ZTtsZXQgZj14LnNhbXBsZSxpPW5ldyBtKGYuaGVhZEVuYyksW18sZF09aS5yZWFkU3RydWN0KEcwKTtpZihkIT09MCl7Y29uc29sZS5lcnJvcigicmVjb25jaWxlOiByZWFkaW5nIG1zZyBoZWFkZXIiLGQpO2NvbnRpbnVlfXkucHVzaCh7a2RtOmYua2RtLGhlYWQ6XyxzZXE6Zi5zZXEsaG9zdDpXLmxhYmVsLGhlYWRFbmM6Zi5oZWFkRW5jLGhlYWRFbmNIYXNoOmYuaGVhZEVuY0hhc2h9KX1pZih5Lmxlbmd0aD4wKWF3YWl0IFYuZG93bmxvYWRzLmVucSh5KTtsZXQgdT0wO2lmKFEpe2xldCB4PWF3YWl0IFYubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoSS5rZXlzKCkpLGY9W107Zm9yKGxldCBpIG9mIHgpaWYoIXYuaGFzKEIoaSkpKXUrPTEsZi5wdXNoKGkpO2lmKGYubGVuZ3RoPjApYXdhaXQgVi51cGxvYWRzLmVucShXLmxhYmVsLGYpfWVsc2V7bGV0IHg9YXdhaXQgVi5tZXNzYWdlcy5saXN0S2V5cygpLHY9bmV3IFNldChJLmtleXMoKSk7Zm9yKGxldCBmIG9mIHgpaWYoIXYuaGFzKEIoZikpKXUrPTF9bGV0IHc9Ui5sZW5ndGg+MD9NYXRoLm1heCguLi5SLm1hcCgoeCk9Pnguc2VxKSk6MDtpZihhd2FpdCBWLmhvc3RzLnJlY29yZFN0YXRzKFcubGFiZWwse3NldExhc3RTZXE6d30pLEspSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOnEsdG90YWw6cX0pO3JldHVybiBPKHttc2djaGVjazprLG51bUJhZ3M6Zyx1bmlxdWVNc2dzOkUsbnVtRHVwZXM6QSxtaXNzaW5nTG9jYWw6aCxtaXNzaW5nSG9zdDp1fSl9Y2xhc3Mgdkp7Y2xvY2s7c3RhdGU7c3RvcmU7dHJhbnNwb3J0O2NyeXB0bztmb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdDtvblNjaGVkdWxlU3luYztjb25uZWN0aW9ucz1uZXcgTWFwO2FwcGx5Q2hhaW49UHJvbWlzZS5yZXNvbHZlKCk7c3luY1J1bnM9bmV3IHYkO2NsaWVudFN0YXRlO3hmZXJTdGF0ZTttYXhQdXNoQnl0ZXM7bWF4UHVsbEJ5dGVzO3BlZWtQcm9ncmVzc0V2ZXJ5PVUkO2xhc3RQcm9ncmVzcz1MSjtzY2hlZHVsZWRTeW5jO2NvbnN0cnVjdG9yKCQsSixaLFEsWSxWPSEwLFg9ZkosVz1FSix6KXt0aGlzLmNsb2NrPSQ7dGhpcy5zdGF0ZT1KO3RoaXMuc3RvcmU9Wjt0aGlzLnRyYW5zcG9ydD1RO3RoaXMuY3J5cHRvPVk7dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdD1WO3RoaXMub25TY2hlZHVsZVN5bmM9ejt0aGlzLm1heFB1c2hCeXRlcz1YLHRoaXMubWF4UHVsbEJ5dGVzPVcsdGhpcy5jbGllbnRTdGF0ZT1uZXcgZjAoKCk9PnRoaXMuZ2V0Q2xpZW50U3RhdGUoKSksdGhpcy54ZmVyU3RhdGU9bmV3IGYwKCgpPT50aGlzLmdldFhmZXJTdGF0ZSgpKSx0aGlzLnNjaGVkdWxlZFN5bmM9bmV3IF9KKHNaLGFzeW5jKCk9Pnt0cnl7Y29uc29sZS5pbmZvKCJSdW5uaW5nIHNjaGVkdWxlZCBzeW5jIiksYXdhaXQgdGhpcy5zeW5jKCl9Y2F0Y2goSyl7Y29uc29sZS5lcnJvcigiRGVib3VuY2VkIHN5bmMgZmFpbGVkOiIsSyl9fSl9ZW1pdFByb2dyZXNzPSgkKT0+e3RoaXMubGFzdFByb2dyZXNzPSQsdGhpcy54ZmVyU3RhdGUuZW1pdCgpfTthc3luYyBzZXRTZWVkKCQsSil7YXdhaXQgdGhpcy5zdG9yZS5zZWVkLnNhdmUoJCxKKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBnZXRDbGllbnRTdGF0ZSgpe2xldHtzdG9yZTokLGNvbm5lY3Rpb25zOkp9PXRoaXMsWj1hd2FpdCAkLnNlZWQubG9hZCgpLFE9YXdhaXQgJC5ob3N0cy5saXN0KCksWT0hMTtmb3IobGV0IFYgb2YgSi52YWx1ZXMoKSlpZihWLmlzQ29ubmVjdGVkKCkpe1k9ITA7YnJlYWt9cmV0dXJue2hhc1NlZWQ6WiE9PXZvaWQgMCxoYXNIb3N0OkFycmF5LmZyb20oUSkubGVuZ3RoPjAsY29ubmVjdGVkOll9fWFzeW5jIGdldFhmZXJTdGF0ZSgpe2xldHt1cGxvYWRzOiQsZG93bmxvYWRzOkp9PXRoaXMuc3RvcmUsWj1hd2FpdCAkLmNvdW50KCk7cmV0dXJue251bURvd25sb2Fkczphd2FpdCBKLmNvdW50KCksbnVtVXBsb2FkczpaLHByb2dyZXNzOnRoaXMubGFzdFByb2dyZXNzfX1hcHBseT0oJCxKKT0+e3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0FwcGx5KCQsSikpfTthc3luYyBkb0FwcGx5KCQsSj17ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiEwfSl7bGV0IFo9W10sUT1bXTtmb3IobGV0e2hlYWQ6Vixib2R5Olh9b2YgJCl7bGV0IFc9bmV3IFM7Vy53cml0ZVN0cnVjdChHMCxWKTtsZXQgej1XLnJlc3VsdCgpLEs9YXdhaXQgdGhpcy5jcnlwdG8uYmxha2UzKHopLEY9e2VpZDpWLmVpZCxib2R5OlgsYXBsZDpZJH07aWYoVi5vZmYhPT0wKUYub2ZmPVYub2ZmO2lmKFYuY3RyIT09MClGLmN0cj1WLmN0cjtaLnB1c2goSyksUS5wdXNoKHtrZXk6SyxkYXRhOkZ9KX1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmFkZChRKSxhd2FpdCBWUSh0aGlzLnN0b3JlLFosdGhpcy5jcnlwdG8pO2xldCBZPWF3YWl0IHRoaXMuZG9BcHBseUhhc2hlcyhaKTtpZihKLmVucXVldWVVcGxvYWQpe2xldCBWPVtdO2ZvcihsZXQgWD0wO1g8Wi5sZW5ndGg7WCsrKXtsZXQgVz1ZW1hdO2lmKFc9PT0wfHxXPT09MTUpVi5wdXNoKFpbWF0pfWlmKFYubGVuZ3RoPjApe2xldCBYPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpO2ZvcihsZXQgVyBvZiBYKWF3YWl0IHRoaXMuc3RvcmUudXBsb2Fkcy5lbnEoVy5sYWJlbCxWKTt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9fWlmKEoudHJpZ2dlclVwbG9hZCl0aGlzLnNjaGVkdWxlU3luYygpO3JldHVybiBZfWVucXVldWVBcHBseUpvYigkKXtsZXQgSj10aGlzLmFwcGx5Q2hhaW4udGhlbigkLCQpO3JldHVybiB0aGlzLmFwcGx5Q2hhaW49Si50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLEp9ZHJhaW5BcHBseVF1ZXVlKCl7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvRHJhaW5BcHBseVF1ZXVlKCkpfWFzeW5jIGRvRHJhaW5BcHBseVF1ZXVlKCl7bGV0ICQ9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KHthcGxkOlkkfSk7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgSj1aJCgkLChaKT0+Wi5oZWFkKTtyZXR1cm4gdGhpcy5hcHBseVN0b3JlZChKKX1hcHBseUhhc2hlcz0oJCk9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseUhhc2hlcygkKSl9O2FzeW5jIGRvQXBwbHlIYXNoZXMoJCl7bGV0IEo9W107Zm9yKGxldCBZIG9mICQpe2xldCBWPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMuZ2V0KFkpO2lmKFYpSi5wdXNoKFYpfWxldCBaPWF3YWl0IHRoaXMuYXBwbHlTdG9yZWQoSiksUT1uZXcgTWFwO2ZvcihsZXQgWT0wO1k8Si5sZW5ndGg7WSsrKVEuc2V0KEIoSltZXS5oYXNoKSxaW1ldPz8xMik7cmV0dXJuICQubWFwKChZKT0+US5nZXQoQihZKSk/PzEzKX1hc3luYyBhcHBseVN0b3JlZCgkKXtpZigkLmxlbmd0aDwxKXJldHVybltdO2xldCBKPSQubWFwKChWKT0+KHsuLi5WLmhlYWQsYm9kOlYuYm9keX0pKSxaPWF3YWl0IHRoaXMuc3RhdGUuYXBwbHkoSiksUT1bXSxZPVtdO2ZvcihsZXQgVj0wO1Y8JC5sZW5ndGg7VisrKXtsZXQgWD1aW1ZdO2lmKFg9PT0wfHxYPT09MTUpUS5wdXNoKCRbVl0uaGFzaCk7ZWxzZSBpZihYIT09dm9pZCAwJiZKUShYKSlZLnB1c2goe2tleTokW1ZdLmhhc2gsZXJyOlh9KX1pZihRLmxlbmd0aD4wKWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubWFya0FwcGxpZWQoUSk7aWYoWS5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtGYWlsZWQoWSk7cmV0dXJuIFp9YXN5bmMgaW5zZXJ0UmF3KCQpe2xldHtjbG9jazpKLGNyeXB0bzpafT10aGlzLFtRLFldPWF3YWl0IGxaKHtub3c6Si5ub3coKSxib2Q6JCxjcnlwdG86Wn0pO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBYPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpRLGJvZHk6JH1dKSlbMF07aWYoWCE9PTAmJlghPT0xNSlyZXR1cm4gRyhYPz8xMik7cmV0dXJuIE8oUSl9YXN5bmMgbWFrZVVwZGF0ZSgkLEope2xldHtjbG9jazpaLGNyeXB0bzpRfT10aGlzLFk9Wi5ub3coKTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCk+WS5nZXRUaW1lKCkpcmV0dXJuIEcoNCk7bGV0IFY9JC5jdHIrMSxbWCxXXT1hd2FpdCBmJCh7bm93OlksZWlkOiQuZWlkLGN0cjpWLGJvZDpKLGNyeXB0bzpRfSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7cmV0dXJuIE8oe2hlYWQ6WCxib2R5Okp9KX1hc3luYyB1cGRhdGVXaXRoU2tldygkLEosWil7aWYoWj09PSExKXJldHVybiBHKDQpO2xldHtjbG9jazpRLGNyeXB0bzpZfT10aGlzLFY9US5ub3coKSxYPW5ldyBtKCQuZWlkKSxbVyx6XT1YLnJlYWRTdHJ1Y3QoVjApO2lmKHohPT0wKXJldHVybiBHKHopO2xldCBLPSQudXBkYXRlZEF0LmdldFRpbWUoKS1XLnRzLmdldFRpbWUoKSxGPXtlaWQ6JC5laWQsb2ZmOksrMSxjdHI6JC5jdHIrMSxsZW46MH0sVT0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6Rixib2R5OnZvaWQgMH1dKSlbMF07aWYoVSE9PTAmJlUhPT0xNSlyZXR1cm4gRyhVPz8xMik7aWYoSj09PXZvaWQgMClyZXR1cm4gTyhGKTtsZXRbUixIXT1fJCh7aWQ6Vy5pZCx0czpWfSk7aWYoSCE9PTApcmV0dXJuIEcoSCk7bGV0W3EsTV09YXdhaXQgZiQoe25vdzpWLGVpZDpSLGN0cjowLGJvZDpKLGNyeXB0bzpZfSk7aWYoTSE9PTApcmV0dXJuIEcoTSk7bGV0IEM9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOnEsYm9keTpKfV0pKVswXTtpZihDIT09MCYmQyE9PTE1KXJldHVybiBHKEM/PzEyKTtyZXR1cm4gTyhxKX1hc3luYyB1cGRhdGVSYXcoJCxKLFo9dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdCl7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPnRoaXMuY2xvY2subm93KCkuZ2V0VGltZSgpKXJldHVybiB0aGlzLnVwZGF0ZVdpdGhTa2V3KCQsSixaKTtyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoYXN5bmMoKT0+e2xldFtRLFldPWF3YWl0IHRoaXMubWFrZVVwZGF0ZSgkLEopO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBYPShhd2FpdCB0aGlzLmRvQXBwbHkoW1FdKSlbMF07aWYoWCE9PTAmJlghPT0xNSlyZXR1cm4gRyhYPz8xMik7cmV0dXJuIE8oUS5oZWFkKX0pfWFzeW5jIGluc2VydCgkKXtsZXR7Ym9keTpKLHR5cGU6WixnaWQ6USxwaWQ6WSx0YWdzOlZ9PSQsVz1rMCh7Ym9keTpKLHR5cGU6WixnaWQ6USxwaWQ6WSx0YWdzOlZ9KTtyZXR1cm4gdGhpcy5pbnNlcnRSYXcoVyl9YXN5bmMgdXBkYXRlKCQpe2xldHtwcmlvcjpKLGJvZHk6Wix0eXBlOlEsZ2lkOlkscGlkOlYsdGFnczpYLGZvcmNlOld9PSQsSz1rMCh7Ym9keTpaLHR5cGU6USxnaWQ6WSxwaWQ6Vix0YWdzOlh9KTtyZXR1cm4gdGhpcy51cGRhdGVSYXcoSixLLFc/P3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpfWFzeW5jIGRlbGV0ZSgkKXtsZXQgSj0kLmZvcmNlPz8hMDtpZigicHJpb3IiaW4gJClyZXR1cm4gdGhpcy51cGRhdGVSYXcoJC5wcmlvcix2b2lkIDAsSik7bGV0W1osUV09YXdhaXQgdGhpcy5yZXZGcm9tQXJjaGl2ZSgkLmVpZCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KFosdm9pZCAwLEopfWFzeW5jIHJldkZyb21BcmNoaXZlKCQpe2xldCBKPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGFzdCgkKTtpZihKKXJldHVybiBhWihKLmhlYWQpO2xldCBaPW5ldyBtKCQpLFtRLFldPVoucmVhZFN0cnVjdChWMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe2VpZDokLGN0cjotMSx1cGRhdGVkQXQ6US50c30pfWFzeW5jIGdlbkVJRCgkKXtsZXR7Y2xvY2s6SixjcnlwdG86Wn09dGhpcyxRPUoubm93KCk7aWYoJCE9PXZvaWQgMClyZXR1cm4gXyQoe2lkOiQsdHM6UX0pO2xldCBZPWF3YWl0IFouZ2VuUmFuZG9tQnl0ZXMoOCk7cmV0dXJuIF8kKHtpZDpZLHRzOlF9KX1zeW5jKCl7cmV0dXJuIHRoaXMuc3luY1J1bnMucnVuKCgpPT50aGlzLmRvU3luYygpKX1hc3luYyBkb1N5bmMoKXtsZXR7Y29ubmVjdGlvbnM6JCxjcnlwdG86SixzdG9yZTpafT10aGlzLFE9YXdhaXQgWi5zZWVkLmxvYWQoKTtpZighUSlyZXR1cm4gMjI7YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtmb3IobGV0W1ksVl1vZiAkKXtsZXQgWD1hd2FpdCBaLmhvc3RzLmdldChZKTtpZighWCljb250aW51ZTtsZXQgVz17Y29ubjpWLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6WCxjcnlwdG86SixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sej1hd2FpdCBnSihXKTtpZih6IT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHBlZWs6ICR7en1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksejt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEs9YXdhaXQgWFEoVyk7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwdXNoOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IG1KKFcsYXN5bmMoKT0+e2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCl9KTtpZihGIT09MCYmRiE9PTE1KXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVsbDogJHtGfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxGO3RoaXMueGZlclN0YXRlLmVtaXQoKX1yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgcmVidWlsZCgkKXtpZih0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpLCQ/LmNoZWNrSG9zdD8/ITApe2xldCBaPWF3YWl0IHRoaXMucmVwdWxsKCk7aWYoWiE9PTApcmV0dXJuIFp9cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLnJlcGxheSgpKX1hc3luYyBtc2djaGVjaygpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdEtleXMoKTtyZXR1cm4gTyQoJCx0aGlzLmNyeXB0byl9bGlzdE1zZ3MoJCl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCgkKX1jb3VudE1zZ3MoJCl7cmV0dXJuIHRoaXMuc3RvcmUubWVzc2FnZXMuY291bnQoJCl9YXN5bmMgcmVjb25jaWxlKCQsSil7dGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKTtsZXR7Y29ubmVjdGlvbnM6WixjcnlwdG86USxzdG9yZTpZfT10aGlzLFY9YXdhaXQgWS5zZWVkLmxvYWQoKTtpZighVilyZXR1cm4gRygyMik7bGV0IFg9YXdhaXQgWS5ob3N0cy5nZXQoJCk7aWYoIVgpcmV0dXJuIEcoMTMpO2xldCBXPVouZ2V0KCQpO2lmKCFXfHwhVy5pc0Nvbm5lY3RlZCgpKXtpZihhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWCwhMSwhMSksWD1hd2FpdCBZLmhvc3RzLmdldCgkKSwhWClyZXR1cm4gRygxMyk7Vz1aLmdldCgkKX1pZighVylyZXR1cm4gRygxMik7bGV0IHo9e2Nvbm46VyxzdG9yZTpZLGVuY2xhdmU6VixjcnlwdG86USxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sW0ssRl09YXdhaXQgU0ooey4uLnosaG9zdDpYfSxKKTtpZih0aGlzLnhmZXJTdGF0ZS5lbWl0KCksRiE9PTApcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxHKEYpO2lmKCFLKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRygxMik7aWYoSj8uc3luYz09PSExKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksTyhLKTtsZXQgTj1hd2FpdCB0aGlzLnN5bmMoKTtpZihOIT09MClyZXR1cm4gRyhOKTtsZXQgVT1hd2FpdCBZLmhvc3RzLmdldCgkKTtpZighVSlyZXR1cm4gRygxMyk7bGV0W1IsSF09YXdhaXQgU0ooey4uLnosaG9zdDpVfSx7cHVsbDohMSxwdXNoOiExfSk7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxIIT09MClyZXR1cm4gRyhIKTtpZighUilyZXR1cm4gRygxMik7cmV0dXJuIE8oUil9YXN5bmMgcmVwdWxsKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOkosc3RvcmU6Wn09dGhpcyxRPWF3YWl0IFouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2xldCBZPUFycmF5LmZyb20oYXdhaXQgWi5ob3N0cy5saXN0KCkpO2lmKFkubGVuZ3RoPDEpcmV0dXJuIDA7Zm9yKGxldCBWIG9mIFkpe2xldCBYPSQuZ2V0KFYubGFiZWwpO2lmKCFYfHwhWC5pc0Nvbm5lY3RlZCgpKWF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChWLCExLCExKX1mb3IobGV0W1YsWF1vZiAkKXtsZXQgVz1hd2FpdCBaLmhvc3RzLmdldChWKTtpZighVyljb250aW51ZTtsZXQgej17Y29ubjpYLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6ey4uLlcsbGFzdFNlcTowfSxjcnlwdG86SixtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX0sSz1hd2FpdCBnSih6KTtpZihLIT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHBlZWs6ICR7S31gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksSzt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEY9YXdhaXQgbUooeik7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgcmVidWlsZDogZmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlcGxheSgpe2xldCAkPWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTtpZigkIT09MClyZXR1cm4gJDtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoKSxaPVokKEosKFYpPT5WLmhlYWQpLFE9Wi5sZW5ndGg7aWYoUTwxKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMDtsZXQgWT0wO3doaWxlKFk8Wi5sZW5ndGgpe2xldCBWPTAsWD0wLFc9WTtmb3IobGV0IEs9WTtLPFoubGVuZ3RoJiZYPDEwMCYmVjwxMDI0MDA7SysrKVYrPVpbS10uaGVhZC5sZW4sWCsrLFc9SysxO2xldCB6PVouc2xpY2UoWSxXKTthd2FpdCB0aGlzLmFwcGx5U3RvcmVkKHopLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiZXhlYyIsZG9uZTpXLHRvdGFsOlF9KSxZPVd9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHdpcGUoJCl7bGV0IEo9JD8ubXNncyE9PSExLFo9JD8uZW50cyE9PSExLFE9JD8ubWV0YSE9PSExLFk9JD8uc2VlZD09PSEwO3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLmRpc2Nvbm5lY3QoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e3N0b3JlOlZ9PXRoaXM7aWYoUSlhd2FpdCBWLmhvc3RzLndpcGUoKSxhd2FpdCBWLnVwbG9hZHMud2lwZSgpLGF3YWl0IFYuZG93bmxvYWRzLndpcGUoKTtpZihKKWF3YWl0IFYubWVzc2FnZXMud2lwZSgpO2lmKFkpYXdhaXQgVi5zZWVkLndpcGUoKTtpZihaKWF3YWl0IHRoaXMuc3RhdGUuY2xlYXIoKTt0aGlzLmxhc3RQcm9ncmVzcz1MSix0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSx0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9aW1wb3J0PWFzeW5jKCQsSik9PntsZXR7Y3J5cHRvOlosc3RvcmU6UX09dGhpcyxZPUo/Lm9uUHJvZ3Jlc3MsVj1hd2FpdCBRLnNlZWQubG9hZCgpO2lmKCFWKXJldHVybiAyMjtjb25zb2xlLnRpbWUoImltcG9ydDogZGVjb2RpbmcgZmlsZS4uLiIpO2xldCBYPWF3YWl0ICQuYnl0ZXMoKSxbVyx6XT1hd2FpdCBpWihYLFosVik7aWYoeiE9PTApcmV0dXJuIHo7Y29uc29sZS50aW1lRW5kKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgSz0wO3doaWxlKEs8Vy5sZW5ndGgpe2xldCBGPTAsTj0wLFU9Sztmb3IobGV0IHE9SztxPFcubGVuZ3RoJiZOPDEwMCYmRjwxMDI0MDA7cSsrKUYrPVdbcV0uaGVhZC5sZW4sTisrLFU9cSsxO2xldCBSPVcuc2xpY2UoSyxVKTtjb25zb2xlLnRpbWUoYGltcG9ydDogYXBwbHlpbmcgWyR7S30sICR7VX1dYCk7bGV0IEg9YXdhaXQgdGhpcy5hcHBseShSLHtlbnF1ZXVlVXBsb2FkOiEwLHRyaWdnZXJVcGxvYWQ6ITF9KTtjb25zb2xlLnRpbWVFbmQoYGltcG9ydDogYXBwbHlpbmcgWyR7S30sICR7VX1dYCk7Zm9yKGxldCBxPTA7cTxSLmxlbmd0aDtxKyspe2xldCBNPUhbcV07aWYoTSE9PTAmJk0hPT0xNSljb25zb2xlLndhcm4oYGZhaWxlZCB0byBpbXBvcnQgbXNnICR7SytxfTogJHtEW01dfWApfWlmKFkpcXVldWVNaWNyb3Rhc2soKCk9PlkoVSxXLmxlbmd0aCwwKSk7dGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpbXBvcnQiLGRvbmU6VSx0b3RhbDpXLmxlbmd0aH0pLEs9VX1yZXR1cm4gdGhpcy5zY2hlZHVsZVN5bmMoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH07c2NoZWR1bGVTeW5jPSgpPT57aWYodGhpcy5vblNjaGVkdWxlU3luYyl7dGhpcy5vblNjaGVkdWxlU3luYygpO3JldHVybn10aGlzLnNjaGVkdWxlZFN5bmMuc2NoZWR1bGUoKX07YXN5bmMgZXhwb3J0Qnl0ZXMoKXtsZXR7Y3J5cHRvOiQsc3RvcmU6Sn09dGhpcyxaPWF3YWl0IEouc2VlZC5sb2FkKCk7aWYoIVopcmV0dXJuIEcoMjIpO2xldCBRPWF3YWl0IEoubWVzc2FnZXMubGlzdCgpO3JldHVybiBoWigiZXhwb3J0IiwwLFEsJCxaKX1hc3luYyBleHBvcnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5leHBvcnRCeXRlcygpO2lmKFohPT0wKXJldHVybiBaO2lmKCFKKXJldHVybiAxMjtsZXQgUT1uZXcgQmxvYihbSi5zbGljZSgpXSk7cmV0dXJuIGVaKFEsJCksMH1hc3luYyBsaW5rKCQsSj0hMCl7aWYoYXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5hZGQoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksSil7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5nZXQoJC5sYWJlbCk7aWYoWilhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWil9fWFzeW5jIHVubGluaygkKXthd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmRlbCgkKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX1hc3luYyBob3N0cygpe3JldHVybiBBcnJheS5mcm9tKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMubGlzdCgpKX1jb25uZWN0VG9Ib3N0PWFzeW5jKCQsSj0hMCxaPSEwKT0+e2xldHtjbG9jazpRLGNvbm5lY3Rpb25zOlksY3J5cHRvOlYsc3RvcmU6WCx0cmFuc3BvcnQ6V309dGhpcyx6PVkuZ2V0KCQubGFiZWwpO2lmKHope2lmKHouaXNDb25uZWN0ZWQoKSlyZXR1cm47dHJ5e3ouY2xvc2VMaXN0ZW5lcigpfWNhdGNoe31ZLmRlbGV0ZSgkLmxhYmVsKX1sZXQgSz1hd2FpdCBYLnNlZWQubG9hZCgpO2lmKCFLKXJldHVybjtjb25zb2xlLmluZm8oYENvbm5lY3RpbmcgdG8gJHskLmhhbmRsZX0gKCR7JC5sYWJlbH0pYCk7bGV0IEY9bmV3IGskKEssViwkLFEsVygkKSwoTik9PlguaG9zdHMuc2V0KCQubGFiZWwsTikpO2lmKGF3YWl0IEYucmVnaXN0ZXIoKSxKKWF3YWl0IEYubGlzdGVuKGFzeW5jKE4pPT57bGV0IFU9e2Nvbm46RixzdG9yZTpYLGVuY2xhdmU6Syxob3N0OiQsY3J5cHRvOlYsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9O3JldHVybiBHUShOLFUsdGhpcy5zY2hlZHVsZVN5bmMpfSwoKT0+dGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpKTtpZihZLnNldCgkLmxhYmVsLEYpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLFopdGhpcy5zY2hlZHVsZVN5bmMoKX07YXN5bmMgY29ubmVjdCgkPSEwLEo9ITApe2xldHtjb25uZWN0VG9Ib3N0Olosc2NoZWR1bGVTeW5jOlEsc3RvcmU6WX09dGhpcztpZighYXdhaXQgWS5zZWVkLmxvYWQoKSlyZXR1cm47YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKTtsZXQgWD1hd2FpdCBZLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWClhd2FpdCBaKFcsJCwhMSk7aWYoSilRKCl9ZGlzY29ubmVjdD1hc3luYygpPT57Zm9yKGxldCAkIG9mIHRoaXMuY29ubmVjdGlvbnMudmFsdWVzKCkpdHJ5eyQuY2xvc2VMaXN0ZW5lcigpfWNhdGNoe310aGlzLmNvbm5lY3Rpb25zLmNsZWFyKCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9fXZhciBFMD10eXBlb2YgZ2xvYmFsVGhpcz09PSJvYmplY3QiJiYiY3J5cHRvImluIGdsb2JhbFRoaXM/Z2xvYmFsVGhpcy5jcnlwdG86dm9pZCAwO2Z1bmN0aW9uIGkkKCQpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcigkKXx8JDwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIiskKX1mdW5jdGlvbiB5SigkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldygkKSYmJC5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIG8oJCwuLi5KKXtpZigheUooJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihKLmxlbmd0aD4wJiYhSi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrSisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIGJKKCQsSj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoSiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIHpRKCQsSil7bygkKTtsZXQgWj1KLm91dHB1dExlbjtpZigkLmxlbmd0aDxaKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK1opfWZ1bmN0aW9uIGhKKCQpe2lmKHR5cGVvZiAkIT09ImJvb2xlYW4iKXRocm93IEVycm9yKGBib29sZWFuIGV4cGVjdGVkLCBub3QgJHskfWApfS8qISBub2JsZS1jaXBoZXJzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjMgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovdmFyIEMwPSgkKT0+bmV3IFVpbnQzMkFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCxNYXRoLmZsb29yKCQuYnl0ZUxlbmd0aC80KSk7dmFyIHRZPW5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4O2lmKCF0WSl0aHJvdyBFcnJvcigiTm9uIGxpdHRsZS1lbmRpYW4gaGFyZHdhcmUgaXMgbm90IHN1cHBvcnRlZCIpO2Z1bmN0aW9uIGVZKCQpe2lmKHR5cGVvZiAkIT09InN0cmluZyIpdGhyb3cgRXJyb3IoInN0cmluZyBleHBlY3RlZCIpO3JldHVybiBuZXcgVWludDhBcnJheShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCkpfWZ1bmN0aW9uIGwkKCQpe2lmKHR5cGVvZiAkPT09InN0cmluZyIpJD1lWSgkKTtlbHNlIGlmKHlKKCQpKSQ9dSQoJCk7ZWxzZSB0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCwgZ290ICIrdHlwZW9mICQpO3JldHVybiAkfWZ1bmN0aW9uIEtRKCQsSil7aWYoSj09bnVsbHx8dHlwZW9mIEohPT0ib2JqZWN0Iil0aHJvdyBFcnJvcigib3B0aW9ucyBtdXN0IGJlIGRlZmluZWQiKTtyZXR1cm4gT2JqZWN0LmFzc2lnbigkLEopfWZ1bmN0aW9uIEZRKCQsSil7aWYoJC5sZW5ndGghPT1KLmxlbmd0aClyZXR1cm4hMTtsZXQgWj0wO2ZvcihsZXQgUT0wO1E8JC5sZW5ndGg7USsrKVp8PSRbUV1eSltRXTtyZXR1cm4gWj09PTB9dmFyIE5RPSgkLEopPT57ZnVuY3Rpb24gWihRLC4uLlkpe2lmKG8oUSksJC5ub25jZUxlbmd0aCE9PXZvaWQgMCl7bGV0IEY9WVswXTtpZighRil0aHJvdyBFcnJvcigibm9uY2UgLyBpdiByZXF1aXJlZCIpO2lmKCQudmFyU2l6ZU5vbmNlKW8oRik7ZWxzZSBvKEYsJC5ub25jZUxlbmd0aCl9bGV0IFY9JC50YWdMZW5ndGg7aWYoViYmWVsxXSE9PXZvaWQgMClvKFlbMV0pO2xldCBYPUooUSwuLi5ZKSxXPShGLE4pPT57aWYoTiE9PXZvaWQgMCl7aWYoRiE9PTIpdGhyb3cgRXJyb3IoImNpcGhlciBvdXRwdXQgbm90IHN1cHBvcnRlZCIpO28oTil9fSx6PSExO3JldHVybntlbmNyeXB0KEYsTil7aWYoeil0aHJvdyBFcnJvcigiY2Fubm90IGVuY3J5cHQoKSB0d2ljZSB3aXRoIHNhbWUga2V5ICsgbm9uY2UiKTtyZXR1cm4gej0hMCxvKEYpLFcoWC5lbmNyeXB0Lmxlbmd0aCxOKSxYLmVuY3J5cHQoRixOKX0sZGVjcnlwdChGLE4pe2lmKG8oRiksViYmRi5sZW5ndGg8Vil0aHJvdyBFcnJvcigiaW52YWxpZCBjaXBoZXJ0ZXh0IGxlbmd0aDogc21hbGxlciB0aGFuIHRhZ0xlbmd0aD0iK1YpO3JldHVybiBXKFguZGVjcnlwdC5sZW5ndGgsTiksWC5kZWNyeXB0KEYsTil9fX1yZXR1cm4gT2JqZWN0LmFzc2lnbihaLCQpLFp9O2Z1bmN0aW9uIGlKKCQsSixaPSEwKXtpZihKPT09dm9pZCAwKXJldHVybiBuZXcgVWludDhBcnJheSgkKTtpZihKLmxlbmd0aCE9PSQpdGhyb3cgRXJyb3IoImludmFsaWQgb3V0cHV0IGxlbmd0aCwgZXhwZWN0ZWQgIiskKyIsIGdvdDogIitKLmxlbmd0aCk7aWYoWiYmISRWKEopKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCwgbXVzdCBiZSBhbGlnbmVkIik7cmV0dXJuIEp9ZnVuY3Rpb24gJFYoJCl7cmV0dXJuICQuYnl0ZU9mZnNldCU0PT09MH1mdW5jdGlvbiB1JCgkKXtyZXR1cm4gVWludDhBcnJheS5mcm9tKCQpfWZ1bmN0aW9uIHEwKC4uLiQpe2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7SisrKSRbSl0uZmlsbCgwKX1mdW5jdGlvbiBSJCgkPTMyKXtpZihFMCYmdHlwZW9mIEUwLmdldFJhbmRvbVZhbHVlcz09PSJmdW5jdGlvbiIpcmV0dXJuIEUwLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheSgkKSk7aWYoRTAmJnR5cGVvZiBFMC5yYW5kb21CeXRlcz09PSJmdW5jdGlvbiIpcmV0dXJuIEUwLnJhbmRvbUJ5dGVzKCQpO3Rocm93IEVycm9yKCJjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIG11c3QgYmUgZGVmaW5lZCIpfXZhciBVUT0oJCk9PlVpbnQ4QXJyYXkuZnJvbSgkLnNwbGl0KCIiKS5tYXAoKEopPT5KLmNoYXJDb2RlQXQoMCkpKSxKVj1VUSgiZXhwYW5kIDE2LWJ5dGUgayIpLFpWPVVRKCJleHBhbmQgMzItYnl0ZSBrIiksUVY9QzAoSlYpLFlWPUMwKFpWKTtmdW5jdGlvbiBqKCQsSil7cmV0dXJuICQ8PEp8JD4+PjMyLUp9ZnVuY3Rpb24gbEooJCl7cmV0dXJuICQuYnl0ZU9mZnNldCU0PT09MH12YXIgcCQ9NjQsVlY9MTYsUlE9NDI5NDk2NzI5NSxPUT1uZXcgVWludDMyQXJyYXk7ZnVuY3Rpb24gWFYoJCxKLFosUSxZLFYsWCxXKXtsZXQgej1ZLmxlbmd0aCxLPW5ldyBVaW50OEFycmF5KHAkKSxGPUMwKEspLE49bEooWSkmJmxKKFYpLFU9Tj9DMChZKTpPUSxSPU4/QzAoVik6T1E7Zm9yKGxldCBIPTA7SDx6O1grKyl7aWYoJChKLFosUSxGLFgsVyksWD49UlEpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2xldCBxPU1hdGgubWluKHAkLHotSCk7aWYoTiYmcT09PXAkKXtsZXQgTT1ILzQ7aWYoSCU0IT09MCl0aHJvdyBFcnJvcigiYXJ4OiBpbnZhbGlkIGJsb2NrIHBvc2l0aW9uIik7Zm9yKGxldCBQPTAsQztQPFZWO1ArKylDPU0rUCxSW0NdPVVbQ11eRltQXTtIKz1wJDtjb250aW51ZX1mb3IobGV0IE09MCxQO008cTtNKyspUD1IK00sVltQXT1ZW1BdXktbTV07SCs9cX19ZnVuY3Rpb24gSFEoJCxKKXtsZXR7YWxsb3dTaG9ydEtleXM6WixleHRlbmROb25jZUZuOlEsY291bnRlckxlbmd0aDpZLGNvdW50ZXJSaWdodDpWLHJvdW5kczpYfT1LUSh7YWxsb3dTaG9ydEtleXM6ITEsY291bnRlckxlbmd0aDo4LGNvdW50ZXJSaWdodDohMSxyb3VuZHM6MjB9LEopO2lmKHR5cGVvZiAkIT09ImZ1bmN0aW9uIil0aHJvdyBFcnJvcigiY29yZSBtdXN0IGJlIGEgZnVuY3Rpb24iKTtyZXR1cm4gaSQoWSksaSQoWCksaEooViksaEooWiksKFcseixLLEYsTj0wKT0+e28oVyksbyh6KSxvKEspO2xldCBVPUsubGVuZ3RoO2lmKEY9PT12b2lkIDApRj1uZXcgVWludDhBcnJheShVKTtpZihvKEYpLGkkKE4pLE48MHx8Tj49UlEpdGhyb3cgRXJyb3IoImFyeDogY291bnRlciBvdmVyZmxvdyIpO2lmKEYubGVuZ3RoPFUpdGhyb3cgRXJyb3IoYGFyeDogb3V0cHV0ICgke0YubGVuZ3RofSkgaXMgc2hvcnRlciB0aGFuIGRhdGEgKCR7VX0pYCk7bGV0IFI9W10sSD1XLmxlbmd0aCxxLE07aWYoSD09PTMyKVIucHVzaChxPXUkKFcpKSxNPVlWO2Vsc2UgaWYoSD09PTE2JiZaKXE9bmV3IFVpbnQ4QXJyYXkoMzIpLHEuc2V0KFcpLHEuc2V0KFcsMTYpLE09UVYsUi5wdXNoKHEpO2Vsc2UgdGhyb3cgRXJyb3IoYGFyeDogaW52YWxpZCAzMi1ieXRlIGtleSwgZ290IGxlbmd0aD0ke0h9YCk7aWYoIWxKKHopKVIucHVzaCh6PXUkKHopKTtsZXQgUD1DMChxKTtpZihRKXtpZih6Lmxlbmd0aCE9PTI0KXRocm93IEVycm9yKCJhcng6IGV4dGVuZGVkIG5vbmNlIG11c3QgYmUgMjQgYnl0ZXMiKTtRKE0sUCxDMCh6LnN1YmFycmF5KDAsMTYpKSxQKSx6PXouc3ViYXJyYXkoMTYpfWxldCBDPTE2LVk7aWYoQyE9PXoubGVuZ3RoKXRocm93IEVycm9yKGBhcng6IG5vbmNlIG11c3QgYmUgJHtDfSBvciAxNiBieXRlc2ApO2lmKEMhPT0xMil7bGV0IEk9bmV3IFVpbnQ4QXJyYXkoMTIpO0kuc2V0KHosVj8wOjEyLXoubGVuZ3RoKSx6PUksUi5wdXNoKHopfWxldCBUPUMwKHopO3JldHVybiBYVigkLE0sUCxULEssRixOLFgpLHEwKC4uLlIpLEZ9fXZhciBzPSgkLEopPT4kW0orK10mMjU1fCgkW0orK10mMjU1KTw8ODtjbGFzcyBxUXtjb25zdHJ1Y3RvcigkKXt0aGlzLmJsb2NrTGVuPTE2LHRoaXMub3V0cHV0TGVuPTE2LHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KDE2KSx0aGlzLnI9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLmg9bmV3IFVpbnQxNkFycmF5KDEwKSx0aGlzLnBhZD1uZXcgVWludDE2QXJyYXkoOCksdGhpcy5wb3M9MCx0aGlzLmZpbmlzaGVkPSExLCQ9bCQoJCksbygkLDMyKTtsZXQgSj1zKCQsMCksWj1zKCQsMiksUT1zKCQsNCksWT1zKCQsNiksVj1zKCQsOCksWD1zKCQsMTApLFc9cygkLDEyKSx6PXMoJCwxNCk7dGhpcy5yWzBdPUomODE5MSx0aGlzLnJbMV09KEo+Pj4xM3xaPDwzKSY4MTkxLHRoaXMuclsyXT0oWj4+PjEwfFE8PDYpJjc5MzksdGhpcy5yWzNdPShRPj4+N3xZPDw5KSY4MTkxLHRoaXMucls0XT0oWT4+PjR8Vjw8MTIpJjI1NSx0aGlzLnJbNV09Vj4+PjEmODE5MCx0aGlzLnJbNl09KFY+Pj4xNHxYPDwyKSY4MTkxLHRoaXMucls3XT0oWD4+PjExfFc8PDUpJjgwNjUsdGhpcy5yWzhdPShXPj4+OHx6PDw4KSY4MTkxLHRoaXMucls5XT16Pj4+NSYxMjc7Zm9yKGxldCBLPTA7Szw4O0srKyl0aGlzLnBhZFtLXT1zKCQsMTYrMipLKX1wcm9jZXNzKCQsSixaPSExKXtsZXQgUT1aPzA6MjA0OCx7aDpZLHI6Vn09dGhpcyxYPVZbMF0sVz1WWzFdLHo9VlsyXSxLPVZbM10sRj1WWzRdLE49Vls1XSxVPVZbNl0sUj1WWzddLEg9Vls4XSxxPVZbOV0sTT1zKCQsSiswKSxQPXMoJCxKKzIpLEM9cygkLEorNCksVD1zKCQsSis2KSxJPXMoJCxKKzgpLEE9cygkLEorMTApLEw9cygkLEorMTIpLGc9cygkLEorMTQpLEU9WVswXSsoTSY4MTkxKSxrPVlbMV0rKChNPj4+MTN8UDw8MykmODE5MSkseT1ZWzJdKygoUD4+PjEwfEM8PDYpJjgxOTEpLGg9WVszXSsoKEM+Pj43fFQ8PDkpJjgxOTEpLHU9WVs0XSsoKFQ+Pj40fEk8PDEyKSY4MTkxKSx3PVlbNV0rKEk+Pj4xJjgxOTEpLHg9WVs2XSsoKEk+Pj4xNHxBPDwyKSY4MTkxKSx2PVlbN10rKChBPj4+MTF8TDw8NSkmODE5MSksZj1ZWzhdKygoTD4+Pjh8Zzw8OCkmODE5MSksaT1ZWzldKyhnPj4+NXxRKSxfPTAsZD1fK0UqWCtrKig1KnEpK3kqKDUqSCkraCooNSpSKSt1Kig1KlUpO189ZD4+PjEzLGQmPTgxOTEsZCs9dyooNSpOKSt4Kig1KkYpK3YqKDUqSykrZiooNSp6KStpKig1KlcpLF8rPWQ+Pj4xMyxkJj04MTkxO2xldCB0PV8rRSpXK2sqWCt5Kig1KnEpK2gqKDUqSCkrdSooNSpSKTtfPXQ+Pj4xMyx0Jj04MTkxLHQrPXcqKDUqVSkreCooNSpOKSt2Kig1KkYpK2YqKDUqSykraSooNSp6KSxfKz10Pj4+MTMsdCY9ODE5MTtsZXQgWTA9XytFKnoraypXK3kqWCtoKig1KnEpK3UqKDUqSCk7Xz1ZMD4+PjEzLFkwJj04MTkxLFkwKz13Kig1KlIpK3gqKDUqVSkrdiooNSpOKStmKig1KkYpK2kqKDUqSyksXys9WTA+Pj4xMyxZMCY9ODE5MTtsZXQgYz1fK0UqSytrKnoreSpXK2gqWCt1Kig1KnEpO189Yz4+PjEzLGMmPTgxOTEsYys9dyooNSpIKSt4Kig1KlIpK3YqKDUqVSkrZiooNSpOKStpKig1KkYpLF8rPWM+Pj4xMyxjJj04MTkxO2xldCBJMD1fK0UqRitrKksreSp6K2gqVyt1Klg7Xz1JMD4+PjEzLEkwJj04MTkxLEkwKz13Kig1KnEpK3gqKDUqSCkrdiooNSpSKStmKig1KlUpK2kqKDUqTiksXys9STA+Pj4xMyxJMCY9ODE5MTtsZXQgcDA9XytFKk4raypGK3kqSytoKnordSpXO189cDA+Pj4xMyxwMCY9ODE5MSxwMCs9dypYK3gqKDUqcSkrdiooNSpIKStmKig1KlIpK2kqKDUqVSksXys9cDA+Pj4xMyxwMCY9ODE5MTtsZXQgYzA9XytFKlUraypOK3kqRitoKksrdSp6O189YzA+Pj4xMyxjMCY9ODE5MSxjMCs9dypXK3gqWCt2Kig1KnEpK2YqKDUqSCkraSooNSpSKSxfKz1jMD4+PjEzLGMwJj04MTkxO2xldCBuMD1fK0UqUitrKlUreSpOK2gqRit1Kks7Xz1uMD4+PjEzLG4wJj04MTkxLG4wKz13KnoreCpXK3YqWCtmKig1KnEpK2kqKDUqSCksXys9bjA+Pj4xMyxuMCY9ODE5MTtsZXQgZDA9XytFKkgraypSK3kqVStoKk4rdSpGO189ZDA+Pj4xMyxkMCY9ODE5MSxkMCs9dypLK3gqeit2KlcrZipYK2kqKDUqcSksXys9ZDA+Pj4xMyxkMCY9ODE5MTtsZXQgcjA9XytFKnEraypIK3kqUitoKlUrdSpOO189cjA+Pj4xMyxyMCY9ODE5MSxyMCs9dypGK3gqSyt2KnorZipXK2kqWCxfKz1yMD4+PjEzLHIwJj04MTkxLF89KF88PDIpK198MCxfPV8rZHwwLGQ9XyY4MTkxLF89Xz4+PjEzLHQrPV8sWVswXT1kLFlbMV09dCxZWzJdPVkwLFlbM109YyxZWzRdPUkwLFlbNV09cDAsWVs2XT1jMCxZWzddPW4wLFlbOF09ZDAsWVs5XT1yMH1maW5hbGl6ZSgpe2xldHtoOiQscGFkOkp9PXRoaXMsWj1uZXcgVWludDE2QXJyYXkoMTApLFE9JFsxXT4+PjEzOyRbMV0mPTgxOTE7Zm9yKGxldCBYPTI7WDwxMDtYKyspJFtYXSs9USxRPSRbWF0+Pj4xMywkW1hdJj04MTkxOyRbMF0rPVEqNSxRPSRbMF0+Pj4xMywkWzBdJj04MTkxLCRbMV0rPVEsUT0kWzFdPj4+MTMsJFsxXSY9ODE5MSwkWzJdKz1RLFpbMF09JFswXSs1LFE9WlswXT4+PjEzLFpbMF0mPTgxOTE7Zm9yKGxldCBYPTE7WDwxMDtYKyspWltYXT0kW1hdK1EsUT1aW1hdPj4+MTMsWltYXSY9ODE5MTtaWzldLT04MTkyO2xldCBZPShRXjEpLTE7Zm9yKGxldCBYPTA7WDwxMDtYKyspWltYXSY9WTtZPX5ZO2ZvcihsZXQgWD0wO1g8MTA7WCsrKSRbWF09JFtYXSZZfFpbWF07JFswXT0oJFswXXwkWzFdPDwxMykmNjU1MzUsJFsxXT0oJFsxXT4+PjN8JFsyXTw8MTApJjY1NTM1LCRbMl09KCRbMl0+Pj42fCRbM108PDcpJjY1NTM1LCRbM109KCRbM10+Pj45fCRbNF08PDQpJjY1NTM1LCRbNF09KCRbNF0+Pj4xMnwkWzVdPDwxfCRbNl08PDE0KSY2NTUzNSwkWzVdPSgkWzZdPj4+MnwkWzddPDwxMSkmNjU1MzUsJFs2XT0oJFs3XT4+PjV8JFs4XTw8OCkmNjU1MzUsJFs3XT0oJFs4XT4+Pjh8JFs5XTw8NSkmNjU1MzU7bGV0IFY9JFswXStKWzBdOyRbMF09ViY2NTUzNTtmb3IobGV0IFg9MTtYPDg7WCsrKVY9KCRbWF0rSltYXXwwKSsoVj4+PjE2KXwwLCRbWF09ViY2NTUzNTtxMChaKX11cGRhdGUoJCl7YkoodGhpcyk7bGV0e2J1ZmZlcjpKLGJsb2NrTGVuOlp9PXRoaXM7JD1sJCgkKTtsZXQgUT0kLmxlbmd0aDtmb3IobGV0IFk9MDtZPFE7KXtsZXQgVj1NYXRoLm1pbihaLXRoaXMucG9zLFEtWSk7aWYoVj09PVope2Zvcig7Wjw9US1ZO1krPVopdGhpcy5wcm9jZXNzKCQsWSk7Y29udGludWV9aWYoSi5zZXQoJC5zdWJhcnJheShZLFkrViksdGhpcy5wb3MpLHRoaXMucG9zKz1WLFkrPVYsdGhpcy5wb3M9PT1aKXRoaXMucHJvY2VzcyhKLDAsITEpLHRoaXMucG9zPTB9cmV0dXJuIHRoaXN9ZGVzdHJveSgpe3EwKHRoaXMuaCx0aGlzLnIsdGhpcy5idWZmZXIsdGhpcy5wYWQpfWRpZ2VzdEludG8oJCl7YkoodGhpcykselEoJCx0aGlzKSx0aGlzLmZpbmlzaGVkPSEwO2xldHtidWZmZXI6SixoOlp9PXRoaXMse3BvczpRfT10aGlzO2lmKFEpe0pbUSsrXT0xO2Zvcig7UTwxNjtRKyspSltRXT0wO3RoaXMucHJvY2VzcyhKLDAsITApfXRoaXMuZmluYWxpemUoKTtsZXQgWT0wO2ZvcihsZXQgVj0wO1Y8ODtWKyspJFtZKytdPVpbVl0+Pj4wLCRbWSsrXT1aW1ZdPj4+ODtyZXR1cm4gJH1kaWdlc3QoKXtsZXR7YnVmZmVyOiQsb3V0cHV0TGVuOkp9PXRoaXM7dGhpcy5kaWdlc3RJbnRvKCQpO2xldCBaPSQuc2xpY2UoMCxKKTtyZXR1cm4gdGhpcy5kZXN0cm95KCksWn19ZnVuY3Rpb24gV1YoJCl7bGV0IEo9KFEsWSk9PiQoWSkudXBkYXRlKGwkKFEpKS5kaWdlc3QoKSxaPSQobmV3IFVpbnQ4QXJyYXkoMzIpKTtyZXR1cm4gSi5vdXRwdXRMZW49Wi5vdXRwdXRMZW4sSi5ibG9ja0xlbj1aLmJsb2NrTGVuLEouY3JlYXRlPShRKT0+JChRKSxKfXZhciB1Sj1XVigoJCk9Pm5ldyBxUSgkKSk7ZnVuY3Rpb24gR1YoJCxKLFosUSxZLFY9MjApe2xldCBYPSRbMF0sVz1KWzBdLHo9SlsxXSxLPUpbMl0sRj1KWzNdLE49JFsxXSxVPVpbMF0sUj1aWzFdLEg9WSxxPTAsTT0kWzJdLFA9Sls0XSxDPUpbNV0sVD1KWzZdLEk9Sls3XSxBPSRbM10sTD1YLGc9VyxFPXosaz1LLHk9RixoPU4sdT1VLHc9Uix4PUgsdj1xLGY9TSxpPVAsXz1DLGQ9VCx0PUksWTA9QTtmb3IobGV0IEkwPTA7STA8VjtJMCs9Mil5Xj1qKEwrX3wwLDcpLHhePWooeStMfDAsOSksX149aih4K3l8MCwxMyksTF49aihfK3h8MCwxOCksdl49aihoK2d8MCw3KSxkXj1qKHYraHwwLDkpLGdePWooZCt2fDAsMTMpLGhePWooZytkfDAsMTgpLHRePWooZit1fDAsNyksRV49aih0K2Z8MCw5KSx1Xj1qKEUrdHwwLDEzKSxmXj1qKHUrRXwwLDE4KSxrXj1qKFkwK2l8MCw3KSx3Xj1qKGsrWTB8MCw5KSxpXj1qKHcra3wwLDEzKSxZMF49aihpK3d8MCwxOCksZ149aihMK2t8MCw3KSxFXj1qKGcrTHwwLDkpLGtePWooRStnfDAsMTMpLExePWooaytFfDAsMTgpLHVePWooaCt5fDAsNyksd149aih1K2h8MCw5KSx5Xj1qKHcrdXwwLDEzKSxoXj1qKHkrd3wwLDE4KSxpXj1qKGYrdnwwLDcpLHhePWooaStmfDAsOSksdl49aih4K2l8MCwxMyksZl49aih2K3h8MCwxOCksX149aihZMCt0fDAsNyksZF49aihfK1kwfDAsOSksdF49aihkK198MCwxMyksWTBePWoodCtkfDAsMTgpO2xldCBjPTA7UVtjKytdPVgrTHwwLFFbYysrXT1XK2d8MCxRW2MrK109eitFfDAsUVtjKytdPUsra3wwLFFbYysrXT1GK3l8MCxRW2MrK109TitofDAsUVtjKytdPVUrdXwwLFFbYysrXT1SK3d8MCxRW2MrK109SCt4fDAsUVtjKytdPXErdnwwLFFbYysrXT1NK2Z8MCxRW2MrK109UCtpfDAsUVtjKytdPUMrX3wwLFFbYysrXT1UK2R8MCxRW2MrK109SSt0fDAsUVtjKytdPUErWTB8MH1mdW5jdGlvbiB6VigkLEosWixRKXtsZXQgWT0kWzBdLFY9SlswXSxYPUpbMV0sVz1KWzJdLHo9SlszXSxLPSRbMV0sRj1aWzBdLE49WlsxXSxVPVpbMl0sUj1aWzNdLEg9JFsyXSxxPUpbNF0sTT1KWzVdLFA9Sls2XSxDPUpbN10sVD0kWzNdO2ZvcihsZXQgQT0wO0E8MjA7QSs9Mil6Xj1qKFkrTXwwLDcpLFVePWooeitZfDAsOSksTV49aihVK3p8MCwxMyksWV49aihNK1V8MCwxOCksUl49aihLK1Z8MCw3KSxQXj1qKFIrS3wwLDkpLFZePWooUCtSfDAsMTMpLEtePWooVitQfDAsMTgpLENePWooSCtGfDAsNyksWF49aihDK0h8MCw5KSxGXj1qKFgrQ3wwLDEzKSxIXj1qKEYrWHwwLDE4KSxXXj1qKFQrcXwwLDcpLE5ePWooVytUfDAsOSkscV49aihOK1d8MCwxMyksVF49aihxK058MCwxOCksVl49aihZK1d8MCw3KSxYXj1qKFYrWXwwLDkpLFdePWooWCtWfDAsMTMpLFlePWooVytYfDAsMTgpLEZePWooSyt6fDAsNyksTl49aihGK0t8MCw5KSx6Xj1qKE4rRnwwLDEzKSxLXj1qKHorTnwwLDE4KSxxXj1qKEgrUnwwLDcpLFVePWoocStIfDAsOSksUl49aihVK3F8MCwxMyksSF49aihSK1V8MCwxOCksTV49aihUK0N8MCw3KSxQXj1qKE0rVHwwLDkpLENePWooUCtNfDAsMTMpLFRePWooQytQfDAsMTgpO2xldCBJPTA7UVtJKytdPVksUVtJKytdPUssUVtJKytdPUgsUVtJKytdPVQsUVtJKytdPUYsUVtJKytdPU4sUVtJKytdPVUsUVtJKytdPVJ9dmFyIHBKPUhRKEdWLHtjb3VudGVyUmlnaHQ6ITAsZXh0ZW5kTm9uY2VGbjp6Vn0pLGNKPU5RKHtibG9ja1NpemU6NjQsbm9uY2VMZW5ndGg6MjQsdGFnTGVuZ3RoOjE2fSwoJCxKKT0+e3JldHVybntlbmNyeXB0KFosUSl7UT1pSihaLmxlbmd0aCszMixRLCExKTtsZXQgWT1RLnN1YmFycmF5KDAsMzIpLFY9US5zdWJhcnJheSgzMik7US5zZXQoWiwzMikscTAoWSkscEooJCxKLFEsUSk7bGV0IFg9dUooVixZKTtyZXR1cm4gUS5zZXQoWCwxNikscTAoUS5zdWJhcnJheSgwLDE2KSxYKSxRLnN1YmFycmF5KDE2KX0sZGVjcnlwdChaLFEpe28oWiksUT1pSihaLmxlbmd0aCszMixRLCExKTtsZXQgWT1RLnN1YmFycmF5KDAsMzIpLFY9US5zdWJhcnJheSgzMiw0OCksWD1RLnN1YmFycmF5KDQ4KTtRLnNldChaLDMyKSxxMChZKTtsZXQgVz1wSigkLEosWSxZKSx6PXVKKFgsVyk7aWYoIUZRKFYseikpdGhyb3cgRXJyb3IoImludmFsaWQgdGFnIik7cmV0dXJuIHBKKCQsSixRLnN1YmFycmF5KDE2KSxRLnN1YmFycmF5KDE2KSkscTAoWSxWLHopLFh9fX0pOy8qISBub2JsZS1oYXNoZXMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi9mdW5jdGlvbiBLVigkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fEFycmF5QnVmZmVyLmlzVmlldygkKSYmJC5jb25zdHJ1Y3Rvci5uYW1lPT09IlVpbnQ4QXJyYXkifWZ1bmN0aW9uIEgkKCQpe2lmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcigkKXx8JDwwKXRocm93IEVycm9yKCJwb3NpdGl2ZSBpbnRlZ2VyIGV4cGVjdGVkLCBnb3QgIiskKX1mdW5jdGlvbiBnMCgkLC4uLkope2lmKCFLVigkKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCIpO2lmKEoubGVuZ3RoPjAmJiFKLmluY2x1ZGVzKCQubGVuZ3RoKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCBvZiBsZW5ndGggIitKKyIsIGdvdCBsZW5ndGg9IiskLmxlbmd0aCl9ZnVuY3Rpb24gcSQoJCxKPSEwKXtpZigkLmRlc3Ryb3llZCl0aHJvdyBFcnJvcigiSGFzaCBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQiKTtpZihKJiYkLmZpbmlzaGVkKXRocm93IEVycm9yKCJIYXNoI2RpZ2VzdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIil9ZnVuY3Rpb24gYyQoJCxKKXtnMCgkKTtsZXQgWj1KLm91dHB1dExlbjtpZigkLmxlbmd0aDxaKXRocm93IEVycm9yKCJkaWdlc3RJbnRvKCkgZXhwZWN0cyBvdXRwdXQgYnVmZmVyIG9mIGxlbmd0aCBhdCBsZWFzdCAiK1opfWZ1bmN0aW9uIE1RKCQpe3JldHVybiBuZXcgVWludDhBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKX1mdW5jdGlvbiBWJCgkKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCxNYXRoLmZsb29yKCQuYnl0ZUxlbmd0aC80KSl9ZnVuY3Rpb24gWCQoLi4uJCl7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspJFtKXS5maWxsKDApfWZ1bmN0aW9uIE0kKCQsSil7cmV0dXJuICQ8PDMyLUp8JD4+Pkp9dmFyIElRPSgoKT0+bmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQzMkFycmF5KFsyODc0NTQwMjBdKS5idWZmZXIpWzBdPT09NjgpKCk7ZnVuY3Rpb24gQ1EoJCl7cmV0dXJuICQ8PDI0JjQyNzgxOTAwODB8JDw8OCYxNjcxMTY4MHwkPj4+OCY2NTI4MHwkPj4+MjQmMjU1fXZhciBQUT1JUT8oJCk9PiQ6KCQpPT5DUSgkKTtmdW5jdGlvbiBGVigkKXtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKykkW0pdPUNRKCRbSl0pO3JldHVybiAkfXZhciBKMD1JUT8oJCk9PiQ6RlY7ZnVuY3Rpb24gTlYoJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24gVyQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPU5WKCQpO3JldHVybiBnMCgkKSwkfWNsYXNzIG5Ke31mdW5jdGlvbiB3USgkKXtsZXQgSj0oUSxZKT0+JChZKS51cGRhdGUoVyQoUSkpLmRpZ2VzdCgpLFo9JCh7fSk7cmV0dXJuIEoub3V0cHV0TGVuPVoub3V0cHV0TGVuLEouYmxvY2tMZW49Wi5ibG9ja0xlbixKLmNyZWF0ZT0oUSk9PiQoUSksSn12YXIgVFE9VWludDMyQXJyYXkuZnJvbShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKTt2YXIgbiQ9QmlnSW50KDQyOTQ5NjcyOTUpLGpRPUJpZ0ludCgzMik7ZnVuY3Rpb24gZEooJCxKPSExKXtpZihKKXJldHVybntoOk51bWJlcigkJm4kKSxsOk51bWJlcigkPj5qUSZuJCl9O3JldHVybntoOk51bWJlcigkPj5qUSZuJCl8MCxsOk51bWJlcigkJm4kKXwwfX1mdW5jdGlvbiBQMCgkLEosWixRLFkpe3JldHVybiAkPSQrSitZfDAsUT1NJChRXiQsMTYpLFo9WitRfDAsSj1NJChKXlosMTIpLHthOiQsYjpKLGM6WixkOlF9fWZ1bmN0aW9uIHcwKCQsSixaLFEsWSl7cmV0dXJuICQ9JCtKK1l8MCxRPU0kKFFeJCw4KSxaPVorUXwwLEo9TSQoSl5aLDcpLHthOiQsYjpKLGM6WixkOlF9fWNsYXNzIHJKIGV4dGVuZHMgbkp7Y29uc3RydWN0b3IoJCxKKXtzdXBlcigpO3RoaXMuZmluaXNoZWQ9ITEsdGhpcy5kZXN0cm95ZWQ9ITEsdGhpcy5sZW5ndGg9MCx0aGlzLnBvcz0wLEgkKCQpLEgkKEopLHRoaXMuYmxvY2tMZW49JCx0aGlzLm91dHB1dExlbj1KLHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KCQpLHRoaXMuYnVmZmVyMzI9ViQodGhpcy5idWZmZXIpfXVwZGF0ZSgkKXtxJCh0aGlzKSwkPVckKCQpLGcwKCQpO2xldHtibG9ja0xlbjpKLGJ1ZmZlcjpaLGJ1ZmZlcjMyOlF9PXRoaXMsWT0kLmxlbmd0aCxWPSQuYnl0ZU9mZnNldCxYPSQuYnVmZmVyO2ZvcihsZXQgVz0wO1c8WTspe2lmKHRoaXMucG9zPT09SilKMChRKSx0aGlzLmNvbXByZXNzKFEsMCwhMSksSjAoUSksdGhpcy5wb3M9MDtsZXQgej1NYXRoLm1pbihKLXRoaXMucG9zLFktVyksSz1WK1c7aWYoej09PUomJiEoSyU0KSYmVyt6PFkpe2xldCBGPW5ldyBVaW50MzJBcnJheShYLEssTWF0aC5mbG9vcigoWS1XKS80KSk7SjAoRik7Zm9yKGxldCBOPTA7VytKPFk7Tis9US5sZW5ndGgsVys9Sil0aGlzLmxlbmd0aCs9Six0aGlzLmNvbXByZXNzKEYsTiwhMSk7SjAoRik7Y29udGludWV9Wi5zZXQoJC5zdWJhcnJheShXLFcreiksdGhpcy5wb3MpLHRoaXMucG9zKz16LHRoaXMubGVuZ3RoKz16LFcrPXp9cmV0dXJuIHRoaXN9ZGlnZXN0SW50bygkKXtxJCh0aGlzKSxjJCgkLHRoaXMpO2xldHtwb3M6SixidWZmZXIzMjpafT10aGlzO3RoaXMuZmluaXNoZWQ9ITAsWCQodGhpcy5idWZmZXIuc3ViYXJyYXkoSikpLEowKFopLHRoaXMuY29tcHJlc3MoWiwwLCEwKSxKMChaKTtsZXQgUT1WJCgkKTt0aGlzLmdldCgpLmZvckVhY2goKFksVik9PlFbVl09UFEoWSkpfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Sn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IFo9JC5zbGljZSgwLEopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxafV9jbG9uZUludG8oJCl7bGV0e2J1ZmZlcjpKLGxlbmd0aDpaLGZpbmlzaGVkOlEsZGVzdHJveWVkOlksb3V0cHV0TGVuOlYscG9zOlh9PXRoaXM7cmV0dXJuICR8fCgkPW5ldyB0aGlzLmNvbnN0cnVjdG9yKHtka0xlbjpWfSkpLCQuc2V0KC4uLnRoaXMuZ2V0KCkpLCQuYnVmZmVyLnNldChKKSwkLmRlc3Ryb3llZD1ZLCQuZmluaXNoZWQ9USwkLmxlbmd0aD1aLCQucG9zPVgsJC5vdXRwdXRMZW49ViwkfWNsb25lKCl7cmV0dXJuIHRoaXMuX2Nsb25lSW50bygpfX1mdW5jdGlvbiBvSigkLEosWixRLFksVixYLFcseixLLEYsTixVLFIsSCxxLE0sUCxDLFQpe2xldCBJPTA7Zm9yKGxldCBBPTA7QTxRO0ErKykoe2E6WSxiOnosYzpVLGQ6TX09UDAoWSx6LFUsTSxaW0orJFtJKytdXSkpLHthOlksYjp6LGM6VSxkOk19PXcwKFkseixVLE0sWltKKyRbSSsrXV0pLHthOlYsYjpLLGM6UixkOlB9PVAwKFYsSyxSLFAsWltKKyRbSSsrXV0pLHthOlYsYjpLLGM6UixkOlB9PXcwKFYsSyxSLFAsWltKKyRbSSsrXV0pLHthOlgsYjpGLGM6SCxkOkN9PVAwKFgsRixILEMsWltKKyRbSSsrXV0pLHthOlgsYjpGLGM6SCxkOkN9PXcwKFgsRixILEMsWltKKyRbSSsrXV0pLHthOlcsYjpOLGM6cSxkOlR9PVAwKFcsTixxLFQsWltKKyRbSSsrXV0pLHthOlcsYjpOLGM6cSxkOlR9PXcwKFcsTixxLFQsWltKKyRbSSsrXV0pLHthOlksYjpLLGM6SCxkOlR9PVAwKFksSyxILFQsWltKKyRbSSsrXV0pLHthOlksYjpLLGM6SCxkOlR9PXcwKFksSyxILFQsWltKKyRbSSsrXV0pLHthOlYsYjpGLGM6cSxkOk19PVAwKFYsRixxLE0sWltKKyRbSSsrXV0pLHthOlYsYjpGLGM6cSxkOk19PXcwKFYsRixxLE0sWltKKyRbSSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PVAwKFgsTixVLFAsWltKKyRbSSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PXcwKFgsTixVLFAsWltKKyRbSSsrXV0pLHthOlcsYjp6LGM6UixkOkN9PVAwKFcseixSLEMsWltKKyRbSSsrXV0pLHthOlcsYjp6LGM6UixkOkN9PXcwKFcseixSLEMsWltKKyRbSSsrXV0pO3JldHVybnt2MDpZLHYxOlYsdjI6WCx2MzpXLHY0OnosdjU6Syx2NjpGLHY3Ok4sdjg6VSx2OTpSLHYxMDpILHYxMTpxLHYxMjpNLHYxMzpQLHYxNDpDLHYxNTpUfX12YXIgTTA9e0NIVU5LX1NUQVJUOjEsQ0hVTktfRU5EOjIsUEFSRU5UOjQsUk9PVDo4LEtFWUVEX0hBU0g6MTYsREVSSVZFX0tFWV9DT05URVhUOjMyLERFUklWRV9LRVlfTUFURVJJQUw6NjR9LFQwPVRRLnNsaWNlKCksRFE9KCgpPT57bGV0ICQ9QXJyYXkuZnJvbSh7bGVuZ3RoOjE2fSwoUSxZKT0+WSksSj0oUSk9PlsyLDYsMywxMCw3LDAsNCwxMywxLDExLDEyLDUsOSwxNCwxNSw4XS5tYXAoKFkpPT5RW1ldKSxaPVtdO2ZvcihsZXQgUT0wLFk9JDtRPDc7USsrLFk9SihZKSlaLnB1c2goLi4uWSk7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShaKX0pKCk7Y2xhc3MgYUogZXh0ZW5kcyBySntjb25zdHJ1Y3RvcigkPXt9LEo9MCl7c3VwZXIoNjQsJC5ka0xlbj09PXZvaWQgMD8zMjokLmRrTGVuKTt0aGlzLmNodW5rUG9zPTAsdGhpcy5jaHVua3NEb25lPTAsdGhpcy5mbGFncz0wLHRoaXMuc3RhY2s9W10sdGhpcy5wb3NPdXQ9MCx0aGlzLmJ1ZmZlck91dDMyPW5ldyBVaW50MzJBcnJheSgxNiksdGhpcy5jaHVua091dD0wLHRoaXMuZW5hYmxlWE9GPSEwO2xldHtrZXk6Wixjb250ZXh0OlF9PSQsWT1RIT09dm9pZCAwO2lmKFohPT12b2lkIDApe2lmKFkpdGhyb3cgRXJyb3IoJ09ubHkgImtleSIgb3IgImNvbnRleHQiIGNhbiBiZSBzcGVjaWZpZWQgYXQgc2FtZSB0aW1lJyk7bGV0IFY9VyQoWikuc2xpY2UoKTtnMChWLDMyKSx0aGlzLklWPVYkKFYpLEowKHRoaXMuSVYpLHRoaXMuZmxhZ3M9SnxNMC5LRVlFRF9IQVNIfWVsc2UgaWYoWSl7bGV0IFY9VyQoUSksWD1uZXcgYUooe2RrTGVuOjMyfSxNMC5ERVJJVkVfS0VZX0NPTlRFWFQpLnVwZGF0ZShWKS5kaWdlc3QoKTt0aGlzLklWPVYkKFgpLEowKHRoaXMuSVYpLHRoaXMuZmxhZ3M9SnxNMC5ERVJJVkVfS0VZX01BVEVSSUFMfWVsc2UgdGhpcy5JVj1UMC5zbGljZSgpLHRoaXMuZmxhZ3M9Sjt0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKSx0aGlzLmJ1ZmZlck91dD1NUSh0aGlzLmJ1ZmZlck91dDMyKX1nZXQoKXtyZXR1cm5bXX1zZXQoKXt9YjJDb21wcmVzcygkLEosWixRPTApe2xldHtzdGF0ZTpZLHBvczpWfT10aGlzLHtoOlgsbDpXfT1kSihCaWdJbnQoJCksITApLHt2MDp6LHYxOkssdjI6Rix2MzpOLHY0OlUsdjU6Uix2NjpILHY3OnEsdjg6TSx2OTpQLHYxMDpDLHYxMTpULHYxMjpJLHYxMzpBLHYxNDpMLHYxNTpnfT1vSihEUSxRLFosNyxZWzBdLFlbMV0sWVsyXSxZWzNdLFlbNF0sWVs1XSxZWzZdLFlbN10sVDBbMF0sVDBbMV0sVDBbMl0sVDBbM10sWCxXLFYsSik7WVswXT16Xk0sWVsxXT1LXlAsWVsyXT1GXkMsWVszXT1OXlQsWVs0XT1VXkksWVs1XT1SXkEsWVs2XT1IXkwsWVs3XT1xXmd9Y29tcHJlc3MoJCxKPTAsWj0hMSl7bGV0IFE9dGhpcy5mbGFncztpZighdGhpcy5jaHVua1BvcylRfD1NMC5DSFVOS19TVEFSVDtpZih0aGlzLmNodW5rUG9zPT09MTV8fFopUXw9TTAuQ0hVTktfRU5EO2lmKCFaKXRoaXMucG9zPXRoaXMuYmxvY2tMZW47aWYodGhpcy5iMkNvbXByZXNzKHRoaXMuY2h1bmtzRG9uZSxRLCQsSiksdGhpcy5jaHVua1Bvcys9MSx0aGlzLmNodW5rUG9zPT09MTZ8fFope2xldCBZPXRoaXMuc3RhdGU7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCk7Zm9yKGxldCBWLFg9dGhpcy5jaHVua3NEb25lKzE7Wnx8IShYJjEpO1g+Pj0xKXtpZighKFY9dGhpcy5zdGFjay5wb3AoKSkpYnJlYWs7dGhpcy5idWZmZXIzMi5zZXQoViwwKSx0aGlzLmJ1ZmZlcjMyLnNldChZLDgpLHRoaXMucG9zPXRoaXMuYmxvY2tMZW4sdGhpcy5iMkNvbXByZXNzKDAsdGhpcy5mbGFnc3xNMC5QQVJFTlQsdGhpcy5idWZmZXIzMiwwKSxZPXRoaXMuc3RhdGUsdGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCl9dGhpcy5jaHVua3NEb25lKyssdGhpcy5jaHVua1Bvcz0wLHRoaXMuc3RhY2sucHVzaChZKX10aGlzLnBvcz0wfV9jbG9uZUludG8oJCl7JD1zdXBlci5fY2xvbmVJbnRvKCQpO2xldHtJVjpKLGZsYWdzOlosc3RhdGU6USxjaHVua1BvczpZLHBvc091dDpWLGNodW5rT3V0Olgsc3RhY2s6VyxjaHVua3NEb25lOnp9PXRoaXM7cmV0dXJuICQuc3RhdGUuc2V0KFEuc2xpY2UoKSksJC5zdGFjaz1XLm1hcCgoSyk9PlVpbnQzMkFycmF5LmZyb20oSykpLCQuSVYuc2V0KEopLCQuZmxhZ3M9WiwkLmNodW5rUG9zPVksJC5jaHVua3NEb25lPXosJC5wb3NPdXQ9ViwkLmNodW5rT3V0PVgsJC5lbmFibGVYT0Y9dGhpcy5lbmFibGVYT0YsJC5idWZmZXJPdXQzMi5zZXQodGhpcy5idWZmZXJPdXQzMiksJH1kZXN0cm95KCl7dGhpcy5kZXN0cm95ZWQ9ITAsWCQodGhpcy5zdGF0ZSx0aGlzLmJ1ZmZlcjMyLHRoaXMuSVYsdGhpcy5idWZmZXJPdXQzMiksWCQoLi4udGhpcy5zdGFjayl9YjJDb21wcmVzc091dCgpe2xldHtzdGF0ZTokLHBvczpKLGZsYWdzOlosYnVmZmVyMzI6USxidWZmZXJPdXQzMjpZfT10aGlzLHtoOlYsbDpYfT1kSihCaWdJbnQodGhpcy5jaHVua091dCsrKSk7SjAoUSk7bGV0e3YwOlcsdjE6eix2MjpLLHYzOkYsdjQ6Tix2NTpVLHY2OlIsdjc6SCx2ODpxLHY5Ok0sdjEwOlAsdjExOkMsdjEyOlQsdjEzOkksdjE0OkEsdjE1Okx9PW9KKERRLDAsUSw3LCRbMF0sJFsxXSwkWzJdLCRbM10sJFs0XSwkWzVdLCRbNl0sJFs3XSxUMFswXSxUMFsxXSxUMFsyXSxUMFszXSxYLFYsSixaKTtZWzBdPVdecSxZWzFdPXpeTSxZWzJdPUteUCxZWzNdPUZeQyxZWzRdPU5eVCxZWzVdPVVeSSxZWzZdPVJeQSxZWzddPUheTCxZWzhdPSRbMF1ecSxZWzldPSRbMV1eTSxZWzEwXT0kWzJdXlAsWVsxMV09JFszXV5DLFlbMTJdPSRbNF1eVCxZWzEzXT0kWzVdXkksWVsxNF09JFs2XV5BLFlbMTVdPSRbN11eTCxKMChRKSxKMChZKSx0aGlzLnBvc091dD0wfWZpbmlzaCgpe2lmKHRoaXMuZmluaXNoZWQpcmV0dXJuO3RoaXMuZmluaXNoZWQ9ITAsWCQodGhpcy5idWZmZXIuc3ViYXJyYXkodGhpcy5wb3MpKTtsZXQgJD10aGlzLmZsYWdzfE0wLlJPT1Q7aWYodGhpcy5zdGFjay5sZW5ndGgpJHw9TTAuUEFSRU5ULEowKHRoaXMuYnVmZmVyMzIpLHRoaXMuY29tcHJlc3ModGhpcy5idWZmZXIzMiwwLCEwKSxKMCh0aGlzLmJ1ZmZlcjMyKSx0aGlzLmNodW5rc0RvbmU9MCx0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2Vsc2UgJHw9KCF0aGlzLmNodW5rUG9zP00wLkNIVU5LX1NUQVJUOjApfE0wLkNIVU5LX0VORDt0aGlzLmZsYWdzPSQsdGhpcy5iMkNvbXByZXNzT3V0KCl9d3JpdGVJbnRvKCQpe3EkKHRoaXMsITEpLGcwKCQpLHRoaXMuZmluaXNoKCk7bGV0e2Jsb2NrTGVuOkosYnVmZmVyT3V0Olp9PXRoaXM7Zm9yKGxldCBRPTAsWT0kLmxlbmd0aDtRPFk7KXtpZih0aGlzLnBvc091dD49Sil0aGlzLmIyQ29tcHJlc3NPdXQoKTtsZXQgVj1NYXRoLm1pbihKLXRoaXMucG9zT3V0LFktUSk7JC5zZXQoWi5zdWJhcnJheSh0aGlzLnBvc091dCx0aGlzLnBvc091dCtWKSxRKSx0aGlzLnBvc091dCs9VixRKz1WfXJldHVybiAkfXhvZkludG8oJCl7aWYoIXRoaXMuZW5hYmxlWE9GKXRocm93IEVycm9yKCJYT0YgaXMgbm90IHBvc3NpYmxlIGFmdGVyIGRpZ2VzdCBjYWxsIik7cmV0dXJuIHRoaXMud3JpdGVJbnRvKCQpfXhvZigkKXtyZXR1cm4gSCQoJCksdGhpcy54b2ZJbnRvKG5ldyBVaW50OEFycmF5KCQpKX1kaWdlc3RJbnRvKCQpe2lmKGMkKCQsdGhpcyksdGhpcy5maW5pc2hlZCl0aHJvdyBFcnJvcigiZGlnZXN0KCkgd2FzIGFscmVhZHkgY2FsbGVkIik7cmV0dXJuIHRoaXMuZW5hYmxlWE9GPSExLHRoaXMud3JpdGVJbnRvKCQpLHRoaXMuZGVzdHJveSgpLCR9ZGlnZXN0KCl7cmV0dXJuIHRoaXMuZGlnZXN0SW50byhuZXcgVWludDhBcnJheSh0aGlzLm91dHB1dExlbikpfX12YXIgQVE9d1EoKCQpPT5uZXcgYUooJCkpO3ZhciBPVj0zMixXRj1TeW1ib2woIlgyNTUxOVNrIik7ZnVuY3Rpb24gX1EoJCl7aWYoJC5ieXRlTGVuZ3RoIT09T1YpcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfXZhciBiPSgxbjw8MjU1biktMTluLFVWPTEyMTY2NW4sTFE9bmV3IFVpbnQ4QXJyYXkoMzIpO0xRWzBdPTk7ZnVuY3Rpb24geFEoJCl7bGV0IEo9MG47Zm9yKGxldCBaPSQubGVuZ3RoLTE7Wj49MDtaLS0pSj1KPDw4bnxCaWdJbnQoJFtaXSk7cmV0dXJuIEp9ZnVuY3Rpb24gUlYoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMzIpLFo9KCQlYitiKSViO2ZvcihsZXQgUT0wO1E8MzI7USsrKUpbUV09TnVtYmVyKFomMHhmZm4pLFo+Pj04bjtyZXR1cm4gSn1mdW5jdGlvbiBIVigkKXtsZXQgSj0kLnNsaWNlKCk7cmV0dXJuIEpbMzFdJj0xMjcseFEoSil9ZnVuY3Rpb24gcVYoJCl7bGV0IEo9JC5zbGljZSgpO3JldHVybiBKWzBdJj0yNDgsSlszMV0mPTEyNyxKWzMxXXw9NjQsSn1mdW5jdGlvbiBkJCgkLEosWil7bGV0IFE9LSQsWT0oSl5aKSZRO3JldHVybltKXlksWl5ZXX1mdW5jdGlvbiBNVigkKXtsZXQgSj1iLTJuLFo9KCQlYitiKSViLFE9MW47d2hpbGUoSj4wbil7aWYoSiYxbilRPVEqWiViO1o9WipaJWIsSj4+PTFufXJldHVybiBRfWZ1bmN0aW9uIElWKCQsSil7bGV0IFo9cVYoJCksUT1IVihKKSxZPTFuLFY9MG4sWD1RLFc9MW4sej0wbixLPXhRKFopO2ZvcihsZXQgRj0yNTQ7Rj49MDtGLS0pe2xldCBOPUs+PkJpZ0ludChGKSYxbjt6Xj1OLFtZLFhdPWQkKHosWSxYKSxbVixXXT1kJCh6LFYsVyksej1OO2xldCBVPShZK1YpJWIsUj1VKlUlYixIPShZLVYrYiklYixxPUgqSCViLE09KFItcStiKSViLFA9KFgrVyklYixUPShYLVcrYiklYipVJWIsST1QKkglYixBPShUK0kpJWIsTD0oVC1JK2IpJWI7WD1BKkElYixXPVEqTCpMJWIsWT1SKnElYixWPU0qKFIrVVYqTSklYn1yZXR1cm5bWSxYXT1kJCh6LFksWCksW1YsV109ZCQoeixWLFcpLFouZmlsbCgwKSxSVihZKk1WKFYpJWIpfWZ1bmN0aW9uIEJRKCQpe3JldHVybiBJVigkLExRKX12YXIgc0o9bmV3IFVpbnQ4QXJyYXkoWzQ4LDQ2LDIsMSwwLDQ4LDUsNiwzLDQzLDEwMSwxMTIsNCwzNCw0LDMyXSk7ZnVuY3Rpb24ga1EoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoc0oubGVuZ3RoKzMyKTtyZXR1cm4gSi5zZXQoc0opLEouc2V0KCQuc3ViYXJyYXkoMCwzMiksc0oubGVuZ3RoKSxKfXZhciB0Sj1uZXcgVWludDhBcnJheShbNDgsNDYsMiwxLDAsNDgsNSw2LDMsNDMsMTAxLDExMCw0LDM0LDQsMzJdKTtmdW5jdGlvbiBmUSgkKXtsZXQgSj1uZXcgVWludDhBcnJheSh0Si5sZW5ndGgrMzIpO3JldHVybiBKLnNldCh0SiksSi5zZXQoJC5zdWJhcnJheSgwLDMyKSx0Si5sZW5ndGgpLEp9ZnVuY3Rpb24gRVEoJCl7cmV0dXJuIHR5cGVvZiAkPT09InN0cmluZyI/bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpOiR9ZnVuY3Rpb24gajAoJCl7bGV0IEo9bmV3IEFycmF5QnVmZmVyKCQuYnl0ZUxlbmd0aCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KEopLnNldCgkKSxKfWNsYXNzIG0we3ZlcmlmeUtleXM9bmV3IE1hcDthc3luYyBnZW5SYW5kb21CeXRlcygkKXtyZXR1cm4gUiQoJCl9YXN5bmMgZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpe3JldHVybiBSJCgzMil9YXN5bmMgZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLEope2xldCBaPVIkKDI0KSxZPWNKKEosWikuZW5jcnlwdCgkKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWy4uLlosLi4uWV0pfWFzeW5jIGRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxKKXtsZXQgWj0kLnNsaWNlKDAsMjQpLFE9JC5zbGljZSgyNCk7cmV0dXJuIGNKKEosWikuZGVjcnlwdChRKX1hc3luYyBkZXJpdmVFZDI1NTE5S2V5UGFpcigkKXtsZXQgSj0kLFo9a1EoSiksUT1qMChaKSxZO3RyeXtsZXQgSz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsic2lnbiJdKTtZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoImp3ayIsSyl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX1pZih0eXBlb2YgWS54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIkVkMjU1MTkgSldLIG1pc3NpbmcgeCIpO2xldCBWPVkueDtZLmQ9dm9pZCAwO2xldCBYPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoImp3ayIse2t0eToiT0tQIixjcnY6IkVkMjU1MTkiLHg6Vn0se25hbWU6IkVkMjU1MTkifSwhMCxbInZlcmlmeSJdKSxXPW5ldyBVaW50OEFycmF5KGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoInJhdyIsWCkpO3RoaXMudmVyaWZ5S2V5cy5zZXQoVTAoVyksWCk7bGV0IHo9bmV3IFVpbnQ4QXJyYXkoNjQpO3JldHVybiB6LnNldChKLDApLHouc2V0KFcsMzIpLHtrZXlUeXBlOiJlZDI1NTE5Iixwcml2YXRlS2V5OnoscHVibGljS2V5Old9fWFzeW5jIGltcG9ydFNpZ25LZXkoJCl7bGV0IEo9JC5zdWJhcnJheSgwLDMyKSxaPWtRKEopLFE9ajAoWik7dHJ5e3JldHVybiBhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiRWQyNTUxOSJ9LCExLFsic2lnbiJdKX1maW5hbGx5e1ouZmlsbCgwKSxuZXcgVWludDhBcnJheShRKS5maWxsKDApfX1hc3luYyBpbXBvcnRWZXJpZnlLZXkoJCl7bGV0IEo9VTAoJCksWj10aGlzLnZlcmlmeUtleXMuZ2V0KEopO2lmKFopcmV0dXJuIFo7bGV0IFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixqMCgkKSx7bmFtZToiRWQyNTUxOSJ9LCExLFsidmVyaWZ5Il0pO3JldHVybiB0aGlzLnZlcmlmeUtleXMuc2V0KEosUSksUX1hc3luYyBzaWduRWQyNTUxOSgkLEope2xldCBaPUVRKCQpLFE9YXdhaXQgdGhpcy5pbXBvcnRTaWduS2V5KEopLFk9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnNpZ24oe25hbWU6IkVkMjU1MTkifSxRLGowKFopKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWSl9YXN5bmMgY2hlY2tTaWdFZDI1NTE5KCQsSixaKXtsZXQgUT1FUShKKTt0cnl7bGV0IFk9YXdhaXQgdGhpcy5pbXBvcnRWZXJpZnlLZXkoWik7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS52ZXJpZnkoe25hbWU6IkVkMjU1MTkifSxZLGowKCQpLGowKFEpKX1jYXRjaHtyZXR1cm4hMX19YXN5bmMgYmxha2UzKCQpe3JldHVybiBBUSgkKX1hc3luYyBnZW5YMjU1MTkoKXtsZXQgJD1hd2FpdCBSJCgzMik7JFswXSY9MjQ4LCRbMzFdJj0xMjcsJFszMV18PTY0O2xldFtKLFpdPV9RKCQpO2lmKFohPT0wfHxKPT09dm9pZCAwKXRocm93ICQuZmlsbCgwKSxFcnJvcigiWDI1NTE5IHNjYWxhciBicmFuZCBmYWlsZWQiKTtsZXQgUT1CUShKKSxZPWZRKEopLFY9ajAoWSk7dHJ5e2xldCBYPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixWLHtuYW1lOiJYMjU1MTkifSwhMCxbImRlcml2ZUJpdHMiXSksVz1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJqd2siLFgpO2lmKHR5cGVvZiBXLnghPT0ic3RyaW5nIil0aHJvdyBFcnJvcigiWDI1NTE5IEpXSyBtaXNzaW5nIHgiKTtsZXQgej1CWihXLngpO2lmKFcuZD12b2lkIDAsIXIoeixRKSl0aHJvdyBFcnJvcigiWDI1NTE5IFdlYkNyeXB0byBwdWIgIT0gUkZDIDc3NDgiKTtyZXR1cm57cHJpdjpKLHB1YjpRfX1jYXRjaChYKXt0aHJvdyBKLmZpbGwoMCksWH1maW5hbGx5e1kuZmlsbCgwKSxuZXcgVWludDhBcnJheShWKS5maWxsKDApfX1hc3luYyB4MjU1MTlTaGFyZWQoJCxKKXtsZXQgWj1mUSgkKSxRPWowKFopO3RyeXtsZXQgWT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsUSx7bmFtZToiWDI1NTE5In0sITEsWyJkZXJpdmVCaXRzIl0pLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixqMChKKSx7bmFtZToiWDI1NTE5In0sITEsW10pLFg9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmRlcml2ZUJpdHMoe25hbWU6IlgyNTUxOSIscHVibGljOlZ9LFksMjU2KTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWCl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX19fXZhciBDVj1uZXcgbTAsciQ9Q1Y7dmFyIFMwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyU3RyaW5nKEouaGFuZGxlKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyU3RyaW5nKEoubGFiZWwpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAkLndyaXRlVmFySW50KEouaWR4Pz8wKX0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhclN0cmluZygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhclN0cmluZygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBPKHtoYW5kbGU6SixsYWJlbDpRLGlkeDpWfSl9fTt2YXIgbyQ9MSxlSj17ZW5jb2RlKCQsSil7aWYoSi52IT09byQpcmV0dXJuIDEwO2xldFssWl09JDAoSi5tYXN0ZXJTZWVkKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEoudik7aWYoUSE9PTApcmV0dXJuIFE7JC53cml0ZUJ5dGVzKEoubWFzdGVyU2VlZCk7bGV0IFk9JC53cml0ZVZhckludChKLmhvc3RzLmxlbmd0aCk7aWYoWSE9PTApcmV0dXJuIFk7Zm9yKGxldCBWIG9mIEouaG9zdHMpe2xldCBYPSQud3JpdGVTdHJ1Y3QoUzAsVik7aWYoWCE9PTApcmV0dXJuIFh9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKIT09byQpcmV0dXJuIEcoMTQpO2xldFtRLFldPSQucmVhZEJ5dGVzKEgwKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVixYXT0kMChRKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwfHxXPDApcmV0dXJuIEcoMTApO2xldCBLPVtdO2ZvcihsZXQgRj0wO0Y8VztGKyspe2xldFtOLFVdPSQucmVhZFN0cnVjdChTMCk7aWYoVSE9PTApcmV0dXJuIEcoVSk7aWYoTj09PXZvaWQgMClyZXR1cm4gRygxNCk7Sy5wdXNoKE4pfXJldHVybiBPKHt2Om8kLG1hc3RlclNlZWQ6Vixob3N0czpLfSl9fTtmdW5jdGlvbiBnUSgkLEope2xldFtaLFFdPSQwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtZLFZdPSQwKFouc2xpY2UoKSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE8oe3Y6byQsbWFzdGVyU2VlZDpZLGhvc3RzOkoubWFwKChYKT0+KHtoYW5kbGU6WC5oYW5kbGUsbGFiZWw6WC5sYWJlbCxpZHg6WC5pZHg/PzB9KSl9KX12YXIgYSQ9e2VuY29kZSgkLEope2xldFssWl09JDAoSi5tYXN0ZXJTZWVkKTtpZihaIT09MClyZXR1cm4gWjskLndyaXRlQnl0ZXMoSi5tYXN0ZXJTZWVkKTtsZXQgUT0kLndyaXRlVmFySW50KEouaG9zdHMubGVuZ3RoKTtpZihRIT09MClyZXR1cm4gUTtmb3IobGV0IFkgb2YgSi5ob3N0cyl7bGV0IFY9JC53cml0ZVN0cnVjdChTMCxZKTtpZihWIT09MClyZXR1cm4gVn1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEgwKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbUSxZXT0kMChKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwfHxWPDApcmV0dXJuIEcoMTApO2xldCBXPVtdO2ZvcihsZXQgej0wO3o8Vjt6Kyspe2xldFtLLEZdPSQucmVhZFN0cnVjdChTMCk7aWYoRiE9PTApcmV0dXJuIEcoRik7aWYoSz09PXZvaWQgMClyZXR1cm4gRygxNCk7Vy5wdXNoKEspfXJldHVybiBPKHttYXN0ZXJTZWVkOlEsaG9zdHM6V30pfX07dmFyIFBWPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5xcnBhaXIudjEiKSxJJD0zMix3Vj1JJCsyNCsxNixUVj0zMixiRj1TeW1ib2woIkRIS0VSZXEiKSxoRj1TeW1ib2woIkRIS0VSZXNwIik7ZnVuY3Rpb24gbVEoJCl7aWYoJC5ieXRlTGVuZ3RoIT09SSQpcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfWZ1bmN0aW9uIFNRKCQpe2lmKCQuYnl0ZUxlbmd0aDx3VilyZXR1cm4gRygxMCk7cmV0dXJuIE8oJCl9dmFyIHMkPW5ldyBtMDthc3luYyBmdW5jdGlvbiAkWigkLEosWixRKXtsZXQgWTt0cnl7WT1hd2FpdCBzJC54MjU1MTlTaGFyZWQoJCxKKX1jYXRjaHtyZXR1cm4gRygyOSl9dHJ5e2lmKFkuYnl0ZUxlbmd0aCE9PUkkfHxZLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDEwKTtsZXQgVj1SMChZLFBWKSxYPVIwKFYsUjAoWixRKSk7dHJ5e2xldCBXPWF3YWl0IHMkLmJsYWtlMyhYKTtyZXR1cm4gTyhXLnNsaWNlKDAsVFYpKX1maW5hbGx5e1YuZmlsbCgwKSxYLmZpbGwoMCl9fWZpbmFsbHl7WS5maWxsKDApfX1jbGFzcyB0JHsjJDsjSjtjb25zdHJ1Y3RvcigkLEope3RoaXMuIyQ9JCx0aGlzLiNKPUp9c3RhdGljIGFzeW5jIGNyZWF0ZSgpe2xldCAkO3RyeXtsZXQgSj1hd2FpdCBzJC5nZW5YMjU1MTkoKTskPUoucHJpdjtsZXRbWixRXT1tUShKLnB1Yik7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0IFk9bmV3IHQkKCQsWik7cmV0dXJuICQ9dm9pZCAwLE8oWSl9Y2F0Y2h7cmV0dXJuIEcoMjkpfWZpbmFsbHl7JD8uZmlsbCgwKX19d2lwZSgpe3RoaXMuIyQuZmlsbCgwKX1nZXQgZGhrZVJlcSgpe2xldFskLEpdPW1RKHRoaXMuI0ouc2xpY2UoKSk7aWYoJD09PXZvaWQgMCl0aHJvdyBFcnJvcihgZGhrZVJlcSAke0p9YCk7cmV0dXJuICR9YXN5bmMgZmluaXNoKCQpe2xldCBKPSQuc3ViYXJyYXkoMCxJJCksWj0kLnN1YmFycmF5KEkkKSxbUSxZXT1hd2FpdCAkWih0aGlzLiMkLEosdGhpcy4jSixKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgVjt0cnl7dHJ5e1Y9YXdhaXQgcyQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFEpfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgWD1uZXcgbShWKSxbVyx6XT1YLnJlYWRTdHJ1Y3QoYSQpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMTQpO3RyeXtsZXRbSyxGXT1XMC5mcm9tQnl0ZXMoVy5tYXN0ZXJTZWVkKTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gdGhpcy53aXBlKCksTyh7ZW5jbGF2ZTpLLGhvc3RzOlcuaG9zdHMubWFwKChOKT0+KHsuLi5OfSkpfSl9ZmluYWxseXtXLm1hc3RlclNlZWQuZmlsbCgwKX19ZmluYWxseXtRLmZpbGwoMCksVj8uZmlsbCgwKX19fWZ1bmN0aW9uIEQwKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KCQpO2lmKCQ+MCljcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKEopO3JldHVybiBKfXZhciB2MD0zMixqVj0tNyxEVj0tOCxBVj0tMjU3LGUkPVt7dHlwZToicHVibGljLWtleSIsYWxnOmpWfSx7dHlwZToicHVibGljLWtleSIsYWxnOkRWfSx7dHlwZToicHVibGljLWtleSIsYWxnOkFWfV07ZnVuY3Rpb24gX1YoJCl7cmV0dXJuICQudHJpbSgpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXC4kLywiIil8fCJsb2NhbGhvc3QifWZ1bmN0aW9uIHkwKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KCQuYnl0ZUxlbmd0aCk7cmV0dXJuIEouc2V0KCQpLEouYnVmZmVyfWZ1bmN0aW9uIHlRKCQpe2lmKCQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCkuc2xpY2UoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCkuc2xpY2UoKX1mdW5jdGlvbiBiMCgkKXtpZigkPy5ycElkIT09dm9pZCAwKXJldHVybiBPKCQucnBJZCk7aWYodHlwZW9mIGxvY2F0aW9uPiJ1IilyZXR1cm4gRyg5KTtyZXR1cm4gTyhfVihsb2NhdGlvbi5ob3N0bmFtZSkpfXZhciB2UT0iIjtmdW5jdGlvbiBoMCgkKXtpZigkIGluc3RhbmNlb2YgRXJyb3Ipe3ZRPSQubWVzc2FnZT09PSIiPyQubmFtZTpgJHskLm5hbWV9OiAkeyQubWVzc2FnZX1gO3JldHVybn12UT1TdHJpbmcoJCl9ZnVuY3Rpb24gaTAoKXtpZih0eXBlb2YgbmF2aWdhdG9yPiJ1Inx8IW5hdmlnYXRvci5jcmVkZW50aWFsc3x8dHlwZW9mIFB1YmxpY0tleUNyZWRlbnRpYWw+InUiKXJldHVybiAyNDtyZXR1cm4gMH1mdW5jdGlvbiBsMCgkKXtpZigkPT09bnVsbHx8JC50eXBlIT09InB1YmxpYy1rZXkifHwhKCJyYXdJZCJpbiAkKXx8dHlwZW9mICQuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cyE9PSJmdW5jdGlvbiIpcmV0dXJuIEcoMjcpO3JldHVybiBPKCQpfWFzeW5jIGZ1bmN0aW9uIGJRKCQpe2xldCBKPWkwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09YjAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtc2VlZCIsVj17cmVzaWRlbnRLZXk6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6ITAsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQifTtpZigkPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClWLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PSQuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IFg9e2xhcmdlQmxvYjp7c3VwcG9ydDoicmVxdWlyZWQifX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpEMCh2MCkscnA6e2lkOlosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6RDAoMTYpLG5hbWU6WSxkaXNwbGF5TmFtZTpZfSxwdWJLZXlDcmVkUGFyYW1zOmUkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246VixleHRlbnNpb25zOlgsLi4uJD8uaGludHMhPT12b2lkIDA/e2hpbnRzOiQuaGludHN9Ont9fX0pfWNhdGNoKE4pe3JldHVybiBoMChOKSxHKDMwKX1sZXRbeixLXT1sMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LnN1cHBvcnRlZCE9PSEwKXJldHVybiBHKDMwKTtyZXR1cm4gTyhuZXcgVWludDhBcnJheSh6LnJhd0lkKSl9YXN5bmMgZnVuY3Rpb24gWlooJCxKLFope2xldCBRPWkwKCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0W1ksVl09YjAoWik7aWYoViE9PTApcmV0dXJuIFY7aWYoWT09PXZvaWQgMClyZXR1cm4gOTtsZXQgWD17bGFyZ2VCbG9iOnt3cml0ZTp5MChKKX19LFc7dHJ5e1c9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OntjaGFsbGVuZ2U6RDAodjApLHJwSWQ6WSxhbGxvd0NyZWRlbnRpYWxzOlt7dHlwZToicHVibGljLWtleSIsaWQ6eTAoJCl9XSx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpYLC4uLlo/LmhpbnRzIT09dm9pZCAwP3toaW50czpaLmhpbnRzfTp7fX19KX1jYXRjaChOKXtyZXR1cm4gaDAoTiksMzB9bGV0W3osS109bDAoVyk7aWYoSyE9PTApcmV0dXJuIEs7aWYoej09PXZvaWQgMClyZXR1cm4gMjc7aWYoei5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iPy53cml0dGVuIT09ITApcmV0dXJuIDMwO3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIEpaKCQsSixaLFEpe2xldCBZPXtjaGFsbGVuZ2U6RDAodjApLHJwSWQ6JCx1c2VyVmVyaWZpY2F0aW9uOiJwcmVmZXJyZWQifTtpZihKPy5oaW50cyE9PXZvaWQgMClZLmhpbnRzPUouaGludHM7aWYoWiE9PXZvaWQgMClZLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDp5MChaKX1dO2lmKFEhPT12b2lkIDApWS5leHRlbnNpb25zPVE7bGV0IFY7dHJ5e1Y9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5Oll9KX1jYXRjaCh6KXtyZXR1cm4gaDAoeiksRygzMCl9bGV0W1gsV109bDAoVik7aWYoVyE9PTApcmV0dXJuIEcoVyk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygyNyk7cmV0dXJuIE8oWCl9YXN5bmMgZnVuY3Rpb24gaFEoJCxKKXtsZXQgWj1pMCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPWIwKEopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFY9JDtpZihWPT09dm9pZCAwKXtsZXRbTixVXT1hd2FpdCBKWihRLEopO2lmKFUhPT0wJiZKPy5oaW50cyE9PXZvaWQgMClbTixVXT1hd2FpdCBKWihRLHtycElkOkoucnBJZCxycE5hbWU6Si5ycE5hbWV9KTtpZihVIT09MClyZXR1cm4gRyhVKTtpZihOPT09dm9pZCAwKXJldHVybiBHKDI3KTtWPW5ldyBVaW50OEFycmF5KE4ucmF3SWQpfWxldFtYLFddPWF3YWl0IEpaKFEsSixWLHtsYXJnZUJsb2I6e3JlYWQ6ITB9fSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygyNyk7bGV0IEs9WC5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iO2lmKEs9PT12b2lkIDB8fEsuYmxvYj09PXZvaWQgMClyZXR1cm4gRyg3KTtsZXQgRj15UShLLmJsb2IpO2lmKEYuYnl0ZUxlbmd0aD09PTApcmV0dXJuIEcoNyk7cmV0dXJuIE8oe2Jsb2I6RixjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoWC5yYXdJZCl9KX12YXIgWVo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCJkaXBsb21hdGljLnByZi52MSIpLFFaPTMyO2FzeW5jIGZ1bmN0aW9uIGlRKCQpe2xldCBKPWkwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09YjAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtcHJmIixWPSQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PT09ImNyb3NzLXBsYXRmb3JtIixYPXtyZXNpZGVudEtleTpWPyJkaXNjb3VyYWdlZCI6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6IVYsdXNlclZlcmlmaWNhdGlvbjpWPyJwcmVmZXJyZWQiOiJyZXF1aXJlZCJ9O2lmKCQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50IT09dm9pZCAwKVguYXV0aGVudGljYXRvckF0dGFjaG1lbnQ9JC5hdXRoZW50aWNhdG9yQXR0YWNobWVudDtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpEMCh2MCkscnA6e2lkOlosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6RDAoMTYpLG5hbWU6WSxkaXNwbGF5TmFtZTpZfSxwdWJLZXlDcmVkUGFyYW1zOmUkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WCxleHRlbnNpb25zOntwcmY6e319LC4uLiQ/LmhpbnRzIT09dm9pZCAwP3toaW50czokLmhpbnRzfTp7fX19KX1jYXRjaChOKXtyZXR1cm4gaDAoTiksRygzMCl9bGV0W3osS109bDAoVyk7aWYoSyE9PTApcmV0dXJuIEcoSyk7aWYoej09PXZvaWQgMClyZXR1cm4gRygyNyk7bGV0IEY9ei5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCk7cmV0dXJuIE8oe2NyZWRJZDpuZXcgVWludDhBcnJheSh6LnJhd0lkKSxwcmZFbmFibGVkOkYucHJmPy5lbmFibGVkPT09ITB9KX1hc3luYyBmdW5jdGlvbiBWWigkKXtsZXQgSj1pMCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtaLFFdPWIwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFk9JD8uc2FsdD8/WVosVj15MChZKSxYPXtjaGFsbGVuZ2U6RDAodjApLHJwSWQ6Wix1c2VyVmVyaWZpY2F0aW9uOiJwcmVmZXJyZWQiLGV4dGVuc2lvbnM6e3ByZjp7ZXZhbDp7Zmlyc3Q6Vn19fX07aWYoJD8uaGludHMhPT12b2lkIDApWC5oaW50cz0kLmhpbnRzO2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClYLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDp5MCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6WH0pfWNhdGNoKEgpe3JldHVybiBoMChIKSxHKDMwKX1sZXRbeixLXT1sMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxVPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxSPVUuYnl0ZUxlbmd0aD49UVo/VS5zbGljZSgwLFFaKTpVO2lmKFIuYnl0ZUxlbmd0aCE9PVFaKXJldHVybiBHKDI3KTtyZXR1cm4gTyh7cHJmOlIsY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyICRKPSIiO3ZhciBaSj10eXBlb2YgZ2xvYmFsVGhpcy5Xb3JrZXI9PT0iZnVuY3Rpb24iP2dsb2JhbFRoaXMuV29ya2VyOnZvaWQgMCxYWj1aSj09PXZvaWQgMD92b2lkIDA6WkoucHJvdG90eXBlLnBvc3RNZXNzYWdlLEpKO2Z1bmN0aW9uIHhWKCl7aWYodHlwZW9mICRKIT09InN0cmluZyJ8fCRKLmxlbmd0aD09PTApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSB3b3JrZXIgc291cmNlIG5vdCBlbWJlZGRlZDsgcnVuIHBrZyBidWlsZCBiZWZvcmUgc3Bhd24iKTtyZXR1cm4gYXRvYigkSil9ZnVuY3Rpb24gQlYoKXtpZihKSiE9PXZvaWQgMClyZXR1cm4gSko7bGV0ICQ9bmV3IEJsb2IoW3hWKCldLHt0eXBlOiJ0ZXh0L2phdmFzY3JpcHQifSk7cmV0dXJuIEpKPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksSkp9ZnVuY3Rpb24gbFEoKXtpZihaSj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBzcGF3biBzeW5jIHdvcmtlciIpO3JldHVybiBuZXcgWkooQlYoKSx7dHlwZToibW9kdWxlIn0pfWZ1bmN0aW9uIHVRKCQsSixaKXtpZihYWj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBwb3N0IHRvIHN5bmMgd29ya2VyIik7aWYoWiE9PXZvaWQgMCYmWi5sZW5ndGg+MClYWi5jYWxsKCQsSix7dHJhbnNmZXI6Wn0pO2Vsc2UgWFouY2FsbCgkLEopfXZhciBrVj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMud3JhcC52MSIpLGZWPTMyLEVWPTE2LHowPW5ldyBtMDtjbGFzcyBXMHsjJDtjb25zdHJ1Y3RvcigkKXt0aGlzLiMkPSR9c3RhdGljIGFzeW5jIGZyb21SYW5kb20oKXtsZXQgJD1hd2FpdCB6MC5nZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCksW0osWl09JDAoJCk7aWYoWiE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7Wn0pYCk7cmV0dXJuIG5ldyBXMChKKX1zdGF0aWMgZnJvbUJ5dGVzKCQpe2xldFtKLFpdPSQwKCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtRLFldPSQwKEouc2xpY2UoKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE8obmV3IFcwKFEpKX1hc3luYyBzZWFsV2l0aFBhc3NrZXkoJCl7bGV0IEo9JD8uc2FsdD8/WVosWj0kPy5jcmVkSWQ7aWYoWj09PXZvaWQgMCYmJD8uY3JlYXRlQ3JlZElmTmVlZGVkPT09ITApe2xldFtWLFhdPWF3YWl0IGlRKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSx1c2VyTmFtZTokPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtcHJmIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCxoaW50czokPy5oaW50cyxzYWx0Okp9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDMwKTtpZighVi5wcmZFbmFibGVkKXJldHVybiBHKDMwKTtaPVYuY3JlZElkfWxldFtRLFldPWF3YWl0IFZaKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6WixzYWx0OkosaGludHM6JD8uaGludHN9KTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbVixYXT1hd2FpdCB0aGlzLiNRKFEucHJmKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7c2VhbGVkTWFzdGVyOlYsc2FsdDpKLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyB1bnNlYWxXaXRoUGFzc2tleSgkLEope2xldFtaLFFdPWF3YWl0IFZaKHtycElkOkoucnBJZCxycE5hbWU6Si5ycE5hbWUsaGludHM6Si5oaW50cyxjcmVkSWQ6Si5jcmVkSWQsc2FsdDpKLnNhbHR9KTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxWXT1hd2FpdCBXMC4jWigkLFoucHJmKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7ZW5jbGF2ZTpZLGNyZWRJZDpaLmNyZWRJZC5zbGljZSgpfSl9ZmluYWxseXtaLnByZi5maWxsKDApfX1hc3luYyBwZXJzaXN0VG9MYXJnZUJsb2IoJD1bXSxKKXtsZXQgWj1KPy5jcmVkSWQ7aWYoWj09PXZvaWQgMCl7bGV0W1YsWF09YXdhaXQgYlEoSik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygzMCk7Wj1WfWxldFtRLFldPXRoaXMuI1koJCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBWPWF3YWl0IFpaKFosUSxKKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gTyhaKX1maW5hbGx5e1EuZmlsbCgwKX19c3RhdGljIGFzeW5jIGZyb21MYXJnZUJsb2IoJCl7bGV0W0osWl09YXdhaXQgaFEoJD8uY3JlZElkLCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e3JldHVybiBXMC4jVihKLmJsb2IsSi5jcmVkSWQpfWZpbmFsbHl7Si5ibG9iLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBjbGVhckxhcmdlQmxvYigkLEope3JldHVybiBaWigkLG5ldyBVaW50OEFycmF5KEgwKSxKKX1zdGF0aWMgcGFpclJlcXVlc3QoKXtyZXR1cm4gdCQuY3JlYXRlKCl9YXN5bmMgcGFpckFjY2VwdCgkLEope2xldCBaO3RyeXtaPWF3YWl0IHowLmdlblgyNTUxOSgpfWNhdGNoe3JldHVybiBHKDI5KX10cnl7bGV0W1EsWV09YXdhaXQgJFooWi5wcml2LCQsJCxaLnB1Yik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldFtWLFhdPXRoaXMuI0ooSik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBXPWF3YWl0IHowLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoVixRKTtyZXR1cm4gU1EoUjAoWi5wdWIsVykpfWNhdGNoe3JldHVybiBHKDEyKX1maW5hbGx5e1YuZmlsbCgwKX19ZmluYWxseXtRLmZpbGwoMCl9fWZpbmFsbHl7Wi5wcml2LmZpbGwoMCl9fSNKKCQpe2xldCBKPXRoaXMuIyQuc2xpY2UoKSxbWixRXT0kMChKKTtpZihRIT09MClyZXR1cm4gSi5maWxsKDApLEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gSi5maWxsKDApLEcoMTApO3RyeXtsZXQgWT17bWFzdGVyU2VlZDpaLGhvc3RzOiQubWFwKChYKT0+KHtoYW5kbGU6WC5oYW5kbGUsbGFiZWw6WC5sYWJlbCxpZHg6WC5pZHg/PzB9KSl9LFY9bmV3IFM7dHJ5e2xldCBYPVYud3JpdGVTdHJ1Y3QoYSQsWSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIE8oVi5yZXN1bHQoKSl9ZmluYWxseXtWLndpcGUoKX19ZmluYWxseXtaLmZpbGwoMCl9fXNwYXduU3luY1dvcmtlcigkKXtsZXQgSj1sUSgpLFo9dGhpcy4jJC5zbGljZSgpO3JldHVybiB1UShKLHtpZDokLmlkLG9wOiJzZXRTZWVkIixzZWVkOloscGVyc2lzdDokLnBlcnNpc3R9LFtaLmJ1ZmZlcl0pLEp9ZGVyaXZlQ2lwaGVyKCQsSil7bGV0IFo9JC5zbGljZSgpLFE9KFgpPT50aGlzLiNHKFosWCksWT0oWCk9PnRoaXMuI3ooWixYKTtyZXR1cm57ZW5jcnlwdDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlF9KSxkZWNyeXB0Ok9iamVjdC5mcmVlemUoe2RlY3J5cHQ6WX0pLGJvdGg6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRLGRlY3J5cHQ6WX0pfVtKXX1hc3luYyBkZXJpdmVJZGVudGl0eSgkLEo9MCl7bGV0IFo9JCxRPUosWT1hd2FpdCB0aGlzLiNXKFosUSksVj1ZLnB1YmxpY0tleTtyZXR1cm4gWS5wcml2YXRlS2V5LmZpbGwoMCksT2JqZWN0LmZyZWV6ZSh7cHVibGljS2V5OlYsc2lnbjooWCk9PnRoaXMuI0YoWixRLFgpLGtkbUZvcjooWCk9PnRoaXMuI04oWixRLFgpfSl9YXN5bmMjUSgkKXtsZXRbSixaXT1hd2FpdCBwUSh6MCwkKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFE9YXdhaXQgejAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0aGlzLiMkLEopO3JldHVybiB4MChRKX1jYXRjaHtyZXR1cm4gRygxMil9ZmluYWxseXtKLmZpbGwoMCl9fXN0YXRpYyBhc3luYyNaKCQsSil7bGV0WyxaXT14MCgkKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT1hd2FpdCBwUSh6MCxKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgVjt0cnl7dHJ5e1Y9YXdhaXQgejAuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLFEpfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gVzAuZnJvbUJ5dGVzKFYpfWZpbmFsbHl7US5maWxsKDApLFY/LmZpbGwoMCl9fSNZKCQpe2xldCBKPXRoaXMuIyQuc2xpY2UoKSxbWixRXT0kMChKKTtpZihRIT09MClyZXR1cm4gSi5maWxsKDApLEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gSi5maWxsKDApLEcoMTApO3RyeXtsZXRbWSxWXT1nUShaLCQpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTIpO3RyeXtsZXQgWD1uZXcgUyxXPVgud3JpdGVTdHJ1Y3QoZUosWSk7aWYoVyE9PTApcmV0dXJuIEcoVyk7cmV0dXJuIE8oWC5yZXN1bHQoKSl9ZmluYWxseXtZLm1hc3RlclNlZWQuZmlsbCgwKX19ZmluYWxseXtaLmZpbGwoMCl9fXN0YXRpYyNWKCQsSil7aWYoJC5ieXRlTGVuZ3RoPT09MHx8JC5ldmVyeSgoVik9PlY9PT0wKSlyZXR1cm4gRygyMik7aWYoJC5ieXRlTGVuZ3RoPT09SDApe2lmKCQuZXZlcnkoKFcpPT5XPT09MCkpcmV0dXJuIEcoMjIpO2xldFtWLFhdPVcwLmZyb21CeXRlcygkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7ZW5jbGF2ZTpWLGhvc3RzOltdLGNyZWRJZDpKfSl9bGV0IFo9bmV3IG0oJCksW1EsWV09Wi5yZWFkU3RydWN0KGVKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTt0cnl7aWYoUS5tYXN0ZXJTZWVkLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDIyKTtsZXRbVixYXT1XMC5mcm9tQnl0ZXMoUS5tYXN0ZXJTZWVkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7ZW5jbGF2ZTpWLGhvc3RzOlEuaG9zdHMubWFwKChXKT0+KHsuLi5XfSkpLGNyZWRJZDpKfSl9ZmluYWxseXtRLm1hc3RlclNlZWQuZmlsbCgwKX19YXN5bmMjRygkLEope2xldCBaPWF3YWl0IHRoaXMuI1goJCk7dHJ5e3JldHVybiBhd2FpdCB6MC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKEosWil9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI3ooJCxKKXtsZXQgWj1hd2FpdCB0aGlzLiNYKCQpO3RyeXtyZXR1cm4gYXdhaXQgejAuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChKLFopfWZpbmFsbHl7Wi5maWxsKDApfX1hc3luYyNYKCQpe3JldHVybiB6MC5ibGFrZTMoUjAodGhpcy4jJCwkKSl9YXN5bmMjSygkLEope2xldCBaPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxRPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcoUS5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludChKKSwhMSksYXdhaXQgdGhpcy4jWChSMChaLFEpKX1hc3luYyNXKCQsSil7bGV0IFo9YXdhaXQgdGhpcy4jSygkLEopO3RyeXtyZXR1cm4gYXdhaXQgejAuZGVyaXZlRWQyNTUxOUtleVBhaXIoWil9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI0YoJCxKLFope2xldCBRPWF3YWl0IHRoaXMuI1coJCxKKTt0cnl7cmV0dXJuIGF3YWl0IHowLnNpZ25FZDI1NTE5KFosUS5wcml2YXRlS2V5KX1maW5hbGx5e1EucHJpdmF0ZUtleS5maWxsKDApfX1hc3luYyNOKCQsSixaKXtsZXQgUT1hd2FpdCB0aGlzLiNXKCQsSiksWT1SMChRLnByaXZhdGVLZXksWik7US5wcml2YXRlS2V5LmZpbGwoMCk7dHJ5e3JldHVybihhd2FpdCB6MC5ibGFrZTMoWSkpLnNsaWNlKDAsXzApfWZpbmFsbHl7WS5maWxsKDApfX19YXN5bmMgZnVuY3Rpb24gcFEoJCxKLFo9a1Ype2lmKEouYnl0ZUxlbmd0aDxFVilyZXR1cm4gRygxMCk7bGV0IFE9YXdhaXQgJC5ibGFrZTMoUjAoSixaKSk7cmV0dXJuIE8oUS5zbGljZSgwLGZWKSl9Y2xhc3MgV1p7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkKXtsZXQgSj1bLi4uJF07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtmb3IobGV0IFggb2YgSil7bGV0IFc9YCR7WC5ob3N0fToke1guc2VxfWA7US5wdXQoWCxXKX19KX1hc3luYyBkZXEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxZPVEub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1Eub25jb21wbGV0ZT0oKT0+VigpLFEub25lcnJvcj0oKT0+WChRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9YCR7JH06JHtXfWA7WS5kZWxldGUoeil9fSl9YXN5bmMgbGlzdCgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0QWxsKCk7WS5vbnN1Y2Nlc3M9KCk9PlooWS5yZXN1bHQpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5jb3VudCgpO1kub25zdWNjZXNzPSgpPT5aKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fWZ1bmN0aW9uIGNRKCQpe3JldHVybntsYWJlbDokLmxhYmVsLGhhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxpZHg6JC5pZHgsbGFzdFNlcTokLmxhc3RTZXF8fDAsY2xvY2tPZmZzZXQ6JC5jbG9ja09mZnNldCxzdWJzY3JpcHRpb246JC5zdWJzY3JpcHRpb259fWZ1bmN0aW9uIGdWKCQsSil7bGV0IFo9ey4uLiR9O2lmKEouc2V0TGFzdFNlcSE9PXZvaWQgMClaLmxhc3RTZXE9Si5zZXRMYXN0U2VxO2Vsc2UgaWYoSi5sYXN0U2VxIT09dm9pZCAwKXtsZXQgUT1aLmxhc3RTZXF8fDA7aWYoSi5sYXN0U2VxPlEpWi5sYXN0U2VxPUoubGFzdFNlcX1yZXR1cm4gZGVsZXRlIFoubnVtQmFncyxkZWxldGUgWi5udW1EdXBlcyxafWNsYXNzIEdae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IEo9YXdhaXQgdGhpcy5nZXQoJC5sYWJlbCksWj1KIT09dm9pZCAwJiZKLmhhbmRsZS5ocmVmPT09JC5oYW5kbGUuaHJlZiYmKEouaWR4Pz8wKT09PSgkLmlkeD8/MCk7cmV0dXJuIHRoaXMucHV0KHsuLi4kLGxhc3RTZXE6Wj9KLmxhc3RTZXE6MCxjbG9ja09mZnNldDpaP0ouY2xvY2tPZmZzZXQ6dm9pZCAwLHN1YnNjcmlwdGlvbjpaP0ouc3Vic2NyaXB0aW9uOnZvaWQgMH0pfWFzeW5jIHB1dCgkKXtsZXQgSj17Li4uJCxoYW5kbGU6JC5oYW5kbGUudG9TdHJpbmcoKSxsYXN0U2VxOiQubGFzdFNlcT8/MH0sWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKSxRLnB1dChKKX0pfWFzeW5jIHRvdWNoKCQsSil7cmV0dXJuIHRoaXMucmVjb3JkU3RhdHMoJCx7bGFzdFNlcTpKfSl9YXN5bmMgcmVjb3JkU3RhdHMoJCxKKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtsZXQgWD1RLmdldCgkKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKCFXKXJldHVybjtRLnB1dChnVihXLEopKX19KX1hc3luYyBnZXQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFY9Wi5nZXQoJCk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgWD1WLnJlc3VsdDtpZighWClRKHZvaWQgMCk7ZWxzZSBRKGNRKFgpKX0sVi5vbmVycm9yPSgpPT5ZKFYuZXJyb3IpfSl9YXN5bmMgc2V0KCQsSil7bGV0IFo9YXdhaXQgdGhpcy5nZXQoJCk7aWYoIVopcmV0dXJuIDEzO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy5wdXQoey4uLlosLi4uSn0pLDB9Y2F0Y2h7cmV0dXJuIDE4fX1hc3luYyBkZWwoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntKLm9uY29tcGxldGU9KCk9PlEoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksWi5kZWxldGUoJCl9KX1hc3luYyBsaXN0KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5nZXRBbGwoKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBWPVkucmVzdWx0O1ooVi5tYXAoY1EpKX0sWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouY2xlYXIoKX0pfX1jbGFzcyB6WntjcnlwdG87ZGI7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmNyeXB0bz1KO3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e2lmKCQubGVuZ3RoPT09MCl7UShbXSk7cmV0dXJufWxldCBZPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO0oub25jb21wbGV0ZT0oKT0+UShZKSxKLm9uZXJyb3I9KCk9Pntmb3IobGV0IFY9MDtWPFkubGVuZ3RoO1YrKylZW1ZdPTE4O1EoWSl9O2ZvcihsZXQgVj0wO1Y8JC5sZW5ndGg7VisrKXtsZXR7a2V5OlgsZGF0YTpXfT0kW1ZdLHo9QihYKSxLPVoucHV0KFcseik7Sy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKSxZW1ZdPTE4fX19KX1hc3luYyBkZWwoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2ZvcihsZXQgWCBvZiBKKXtsZXQgVz1CKFgpO1EuZGVsZXRlKFcpfX0pfWFzeW5jIGdldCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFY9QigkKSxYPVouZ2V0KFYpO1gub25zdWNjZXNzPWFzeW5jKCk9PntsZXQgVz1YLnJlc3VsdDtpZihXKVEoYXdhaXQgaCQoJCxXLHRoaXMuY3J5cHRvKSk7ZWxzZSBRKHZvaWQgMCl9LFgub25lcnJvcj0oKT0+WShYLmVycm9yKX0pfWFzeW5jIGhhcygkKXtyZXR1cm4gYXdhaXQgdGhpcy5nZXQoJCkhPT12b2lkIDB9YXN5bmMgbGlzdCgkKXtsZXQgSj0kPy5hcGxkLFo9JD8uYm9keSE9PSExLFk9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e2xldCBXPVtdLHo9Sj09PXZvaWQgMD9ZLm9wZW5DdXJzb3IoKTpZLmluZGV4KEMkKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoSikpO3oub25zdWNjZXNzPShLKT0+e2xldCBGPUsudGFyZ2V0LnJlc3VsdDtpZihGKXtsZXQgTj1KPT09dm9pZCAwP0Yua2V5OkYucHJpbWFyeUtleSxVPUYudmFsdWU7Vy5wdXNoKHtoYXNoOk4wKE4pLGRhdGE6VX0pLEYuY29udGludWUoKX1lbHNlIFByb21pc2UuYWxsKFcubWFwKCh7aGFzaDpOLGRhdGE6VX0pPT5oJChOLFUsdGhpcy5jcnlwdG8se2JvZHk6Wn0pKSkudGhlbihWKS5jYXRjaChYKX0sei5vbmVycm9yPSgpPT5YKHouZXJyb3IpfSl9YXN5bmMgY291bnQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWPSQ9PT12b2lkIDA/Wi5jb3VudCgpOlouaW5kZXgoQyQpLmNvdW50KElEQktleVJhbmdlLm9ubHkoJCkpO1Yub25zdWNjZXNzPSgpPT5RKFYucmVzdWx0KSxWLm9uZXJyb3I9KCk9PlkoVi5lcnJvcil9KX1hc3luYyBsaXN0S2V5cygpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1bXSxWPUoub3BlbktleUN1cnNvcigpO1Yub25zdWNjZXNzPShYKT0+e2xldCBXPVgudGFyZ2V0LnJlc3VsdDtpZihXKVkucHVzaChOMChXLmtleSkpLFcuY29udGludWUoKTtlbHNlIFooWSl9LFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfWFzeW5jIGxhc3QoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWLFg9Wi5vcGVuQ3Vyc29yKCk7WC5vbnN1Y2Nlc3M9YXN5bmMoVyk9PntsZXQgej1XLnRhcmdldC5yZXN1bHQ7aWYoeil7bGV0e2tleTpLLHZhbHVlOkZ9PXo7aWYocigkLEYuZWlkKSl7aWYoIVZ8fChGLmN0cj8/MCk+KFYuZGF0YS5jdHI/PzApfHwoRi5jdHI/PzApPT09KFYuZGF0YS5jdHI/PzApJiYoRi5vZmY/PzApPihWLmRhdGEub2ZmPz8wKSlWPXtrZXk6SyxkYXRhOkZ9fXouY29udGludWUoKX1lbHNlIGlmKFYpe2xldCBLPU4wKFYua2V5KTtRKGF3YWl0IGgkKEssVi5kYXRhLHRoaXMuY3J5cHRvKSl9ZWxzZSBRKHZvaWQgMCl9LFgub25lcnJvcj0oKT0+WShYLmVycm9yKX0pfWFzeW5jIG1hcmtBcHBsaWVkKCQpe2xldCBKPVsuLi4kXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtmb3IobGV0IFggb2YgSil7bGV0IFc9QihYKSx6PVEuZ2V0KFcpO3oub25zdWNjZXNzPSgpPT57bGV0IEs9ei5yZXN1bHQ7aWYoIUspcmV0dXJuO2tKKEssYiQpLFEucHV0KEssVyl9LHoub25lcnJvcj0oSyk9PntLLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIG1hcmtGYWlsZWQoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUocCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2ZvcihsZXR7a2V5OlgsZXJyOld9b2YgSil7bGV0IHo9QihYKSxLPVEuZ2V0KHopO0sub25zdWNjZXNzPSgpPT57bGV0IEY9Sy5yZXN1bHQ7aWYoIUYpcmV0dXJuO2tKKEYsUSQsVyksUS5wdXQoRix6KX0sSy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKX19fSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24ocCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKHApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19Y2xhc3MgS1p7IyQ7I0o7I1E7I1o7Y29uc3RydWN0b3IoJCl7aWYodGhpcy4jWj0kLnBlcnNpc3RNZXRhLHRoaXMuI1E9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5tZXRhIT09dm9pZCAwKXRoaXMuI0o9dTAoJC5tZXRhKX1nZXQgbWV0YSgpe3JldHVybiB0aGlzLiNKPT09dm9pZCAwP3ZvaWQgMDp1MCh0aGlzLiNKKX1zZXRNZXRhKCQpe3RoaXMuI0o9JD09PXZvaWQgMD92b2lkIDA6dTAoJCl9YXN5bmMgc2F2ZSgkLEope2lmKEo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIHdyYXBBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3Qgc2VhbGVkIG1hc3RlciIpKTtyZXR1cm4gdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgd3JhcEFuZFNhdmUoJCxKKXtsZXRbWixRXT1hd2FpdCAkLnNlYWxXaXRoUGFzc2tleSh7Li4udGhpcy4jUSxzYWx0Oko/LnNhbHQsY3JlZElkOko/LmNyZWRJZD8/dGhpcy4jSj8uY3JlZElkLGNyZWF0ZUNyZWRJZk5lZWRlZDpKPy5jcmVhdGVDcmVkSWZOZWVkZWQ/P0o/LmNyZWRJZD09PXZvaWQgMCx1c2VyTmFtZToiZGlwbG9tYXRpYy1wcmYiLGF1dGhlbnRpY2F0b3JBdHRhY2htZW50Oko/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50LGhpbnRzOko/LmhpbnRzfSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFk9e3NlYWxlZE1hc3RlcjpaLnNlYWxlZE1hc3RlcixzYWx0Olouc2FsdCxjcmVkSWQ6Wi5jcmVkSWR9O3JldHVybiB0aGlzLiNKPVksdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1oodTAoWSkpLE8odGhpcy4jJCl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIHVubG9jaygpe2xldCAkPXRoaXMuI0o7aWYoJD09PXZvaWQgMClyZXR1cm4gRygyMik7bGV0W0osWl09YXdhaXQgVzAudW5zZWFsV2l0aFBhc3NrZXkoJC5zZWFsZWRNYXN0ZXIsey4uLnRoaXMuI1Esc2FsdDokLnNhbHQsY3JlZElkOiQuY3JlZElkfSk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYodGhpcy4jJD1KLmVuY2xhdmUsSi5jcmVkSWQuYnl0ZUxlbmd0aD4wJiYoJC5jcmVkSWQ9PT12b2lkIDB8fCFyKCQuY3JlZElkLEouY3JlZElkKSkpe2xldCBRPXtzZWFsZWRNYXN0ZXI6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQsY3JlZElkOkouY3JlZElkLnNsaWNlKCl9O3RoaXMuI0o9USxhd2FpdCB0aGlzLiNaKHUwKFEpKX1yZXR1cm4gTyhKLmVuY2xhdmUpfWFzeW5jIGFkb3B0U2VhbGVkKCQsSil7cmV0dXJuIHRoaXMuI0o9dTAoSiksdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1oodTAoSikpLE8odGhpcy4jJCl9YXN5bmMgd2lwZSgpe3RoaXMuIyQ9dm9pZCAwLHRoaXMuI0o9dm9pZCAwLGF3YWl0IHRoaXMuI1oodm9pZCAwKX19ZnVuY3Rpb24gdTAoJCl7bGV0W0osWl09eDAoJC5zZWFsZWRNYXN0ZXIuc2xpY2UoKSk7cmV0dXJue3NlYWxlZE1hc3RlcjpaPT09MCYmSiE9PXZvaWQgMD9KOiQuc2VhbGVkTWFzdGVyLHNhbHQ6JC5zYWx0LnNsaWNlKCksY3JlZElkOiQuY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfX12YXIgbVY9ImRpcGxvbWF0aWMucGluLyI7ZnVuY3Rpb24gU1YoJCl7cmV0dXJuIG1WK1UwKCQpfWFzeW5jIGZ1bmN0aW9uIG5RKCQsSixaKXtsZXQgUT1hd2FpdCBKLmRlcml2ZUlkZW50aXR5KFNWKFopLDApO3JldHVybiAkLmJsYWtlMyhRLnB1YmxpY0tleSl9YXN5bmMgZnVuY3Rpb24gZFEoJCxKKXtsZXQgWj1hd2FpdCAkLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxRPWF3YWl0IG5RKCQsSixaKTtyZXR1cm57bjpaLGg6UX19YXN5bmMgZnVuY3Rpb24gclEoJCxKLFope2xldCBRPWF3YWl0IG5RKCQsSixaLm4pO3JldHVybiB2VihRLFouaCl9ZnVuY3Rpb24gb1EoJCl7aWYoJD09PXZvaWQgMHx8JD09PW51bGx8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuO2xldCBKPSQ7aWYoIShKLm4gaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShKLmggaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47aWYoSi5uLmJ5dGVMZW5ndGg8MXx8Si5oLmJ5dGVMZW5ndGg8MSlyZXR1cm47cmV0dXJue246Si5uLnNsaWNlKCksaDpKLmguc2xpY2UoKX19ZnVuY3Rpb24gYVEoJCl7cmV0dXJue246JC5uLnNsaWNlKCksaDokLmguc2xpY2UoKX19ZnVuY3Rpb24gdlYoJCxKKXtpZigkLmJ5dGVMZW5ndGghPT1KLmJ5dGVMZW5ndGgpcmV0dXJuITE7bGV0IFo9MDtmb3IobGV0IFE9MDtRPCQuYnl0ZUxlbmd0aDtRKyspWnw9JFtRXV5KW1FdO3JldHVybiBaPT09MH12YXIgUUo9InByZk1ldGEiLEZaPSJpZFBpbiIsc1E9ImlkUHViIjtjbGFzcyBOWnsjJDtkYjsjSjtjb25zdHJ1Y3RvcigkLEope3RoaXMuZGI9JCx0aGlzLiNKPUp9YXN5bmMgc2F2ZSgkLEope3JldHVybiBhd2FpdCB0aGlzLiNRKCQpLHRoaXMuIyQ9JCx0aGlzLiMkfWFzeW5jIGxvYWQoKXtyZXR1cm4gdGhpcy4jJH1hc3luYyBjbGVhclNlc3Npb24oKXt0aGlzLiMkPXZvaWQgMH1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDA7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5kZWxldGUoUUopLEouZGVsZXRlKEZaKSxKLmRlbGV0ZShzUSl9KX1hc3luYyBsb2FkUHJmTWV0YSgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0KFFKKTtZLm9uc3VjY2Vzcz0oKT0+e1ooeVYoWS5yZXN1bHQpKX0sWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgcGVyc2lzdFByZk1ldGEoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntpZihKLm9uY29tcGxldGU9KCk9PlEoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksJD09PXZvaWQgMCl7Wi5kZWxldGUoUUopO3JldHVybn1sZXQgVj17c2VhbGVkTWFzdGVyOiQuc2VhbGVkTWFzdGVyLnNsaWNlKCksc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9O1oucHV0KFYsUUopfSl9YXN5bmMgaGFzUHJmTWV0YSgpe3JldHVybiBhd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCkhPT12b2lkIDB9YXN5bmMgbGFzdFByZkNyZWRJZCgpe2xldCAkPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gJD8uY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfWFzeW5jIG9wZW5QcmZTdG9yZSgkKXtsZXQgSj1hd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCk7cmV0dXJuIG5ldyBLWih7cnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lLG1ldGE6SixwZXJzaXN0TWV0YTooWik9PnRoaXMucGVyc2lzdFByZk1ldGEoWil9KX1hc3luYyNRKCQpe2F3YWl0IHRoaXMuI1Yoc1EpO2xldCBKPWF3YWl0IHRoaXMuI1ooKTtpZihKIT09dm9pZCAwKXtpZighYXdhaXQgclEodGhpcy4jSiwkLEopKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gc2VlZCBkb2VzIG5vdCBtYXRjaCB0aGlzIGRldmljZSdzIGlkZW50aXR5IChsb2NhbCBkYXRhIHdhcyBjcmVhdGVkIHdpdGggYSBkaWZmZXJlbnQgbWFzdGVyIHNlZWQpIik7cmV0dXJufWxldCBaPWF3YWl0IGRRKHRoaXMuI0osJCk7YXdhaXQgdGhpcy4jWShaKX0jWigpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0KEZaKTtZLm9uc3VjY2Vzcz0oKT0+WihvUShZLnJlc3VsdCkpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfSNZKCQpe2xldCBKPWFRKCQpLFo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksUS5wdXQoSixGWil9KX0jVigkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e0oub25jb21wbGV0ZT0oKT0+USgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSxaLmRlbGV0ZSgkKX0pfX1mdW5jdGlvbiB5VigkKXtpZigkPT09dm9pZCAwfHwkPT09bnVsbHx8dHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm47bGV0IEo9JDtpZighKEouc2VhbGVkTWFzdGVyIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCEoSi5zYWx0IGluc3RhbmNlb2YgVWludDhBcnJheSkpcmV0dXJuO2xldFtaLFFdPXgwKEouc2VhbGVkTWFzdGVyKTtpZihRIT09MHx8Wj09PXZvaWQgMClyZXR1cm47cmV0dXJue3NlYWxlZE1hc3RlcjpaLHNhbHQ6Si5zYWx0LnNsaWNlKCksY3JlZElkOkouY3JlZElkIGluc3RhbmNlb2YgVWludDhBcnJheT9KLmNyZWRJZC5zbGljZSgpOnZvaWQgMH19Y2xhc3MgT1p7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkLEope2xldCBaPVsuLi5KXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWR3cml0ZSIpLFk9US5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57US5vbmNvbXBsZXRlPSgpPT5WKCksUS5vbmVycm9yPSgpPT5YKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBaKXtsZXQgej1VMChXKTtZLnB1dCh7aG9zdDokLGhhc2g6en0pfX0pfWFzeW5jIGRlcSgkLEope2xldCBaPVsuLi5KXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWR3cml0ZSIpLFk9US5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57US5vbmNvbXBsZXRlPSgpPT5WKCksUS5vbmVycm9yPSgpPT5YKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBaKXtsZXQgej1VMChXKTtZLmRlbGV0ZShbJCx6XSl9fSl9YXN5bmMgbGlzdCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntsZXQgVj1aLmdldEFsbCgpO1Yub25zdWNjZXNzPSgpPT57bGV0IFc9Vi5yZXN1bHQuZmlsdGVyKCh6KT0+ei5ob3N0PT09JCkubWFwKCh6KT0+ei5oYXNoKTtRKFcubWFwKCh6KT0+eFooeikpKX0sVi5vbmVycm9yPSgpPT5ZKFYuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmNvdW50KCk7WS5vbnN1Y2Nlc3M9KCk9PlooWS5yZXN1bHQpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkd3JpdGUiKSxKPSQub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19dmFyIFEwPSJzZWVkTWV0YSIsWjA9Imhvc3RzIixGMD0idXBsb2FkUXVldWUiLEswPSJkb3dubG9hZFF1ZXVlIixwPSJtZXNzYWdlcyIsQyQ9ImFwbGQiLHRRPTMsZVE9ImRpcGxvbWF0aWMtc3RvcmUtZGIiO2NsYXNzICRZe3NlZWQ7aG9zdHM7dXBsb2Fkcztkb3dubG9hZHM7bWVzc2FnZXM7ZGI7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmRiPSQsdGhpcy5zZWVkPW5ldyBOWigkLEopLHRoaXMuaG9zdHM9bmV3IEdaKCQpLHRoaXMudXBsb2Fkcz1uZXcgT1ooJCksdGhpcy5kb3dubG9hZHM9bmV3IFdaKCQpLHRoaXMubWVzc2FnZXM9bmV3IHpaKCQsSil9YXN5bmMgd2lwZSgpe2F3YWl0IHRoaXMuaG9zdHMud2lwZSgpLGF3YWl0IHRoaXMudXBsb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5kb3dubG9hZHMud2lwZSgpLGF3YWl0IHRoaXMubWVzc2FnZXMud2lwZSgpfX1hc3luYyBmdW5jdGlvbiBiVigpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxKKT0+e2xldCBaPWluZGV4ZWREQi5vcGVuKGVRLHRRKTtaLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpZfT1aO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoUTApKVEuY3JlYXRlT2JqZWN0U3RvcmUoUTApO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoWjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoWjAse2tleVBhdGg6ImxhYmVsIn0pO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoRjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoRjAse2tleVBhdGg6WyJob3N0IiwiaGFzaCJdfSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhLMCkpUS5jcmVhdGVPYmplY3RTdG9yZShLMCk7bGV0IFY7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhwKSlWPVEuY3JlYXRlT2JqZWN0U3RvcmUocCk7ZWxzZXtpZighWSl0aHJvdyBFcnJvcigibWlzc2luZyB1cGdyYWRlIHRyYW5zYWN0aW9uIGZvciBtZXNzYWdlcyBzdG9yZSIpO1Y9WS5vYmplY3RTdG9yZShwKX1pZighVi5pbmRleE5hbWVzLmNvbnRhaW5zKEMkKSlWLmNyZWF0ZUluZGV4KEMkLCJhcGxkIix7dW5pcXVlOiExfSl9LFoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gcHJvdG9jb2wgc3RvcmUgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtlUX0g4oaSIHYke3RRfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LFoub25zdWNjZXNzPSgpPT57bGV0IFE9Wi5yZXN1bHQ7US5vbnZlcnNpb25jaGFuZ2U9KCk9PntRLmNsb3NlKCl9LCQoUSl9LFoub25lcnJvcj0oKT0+SihaLmVycm9yPz9FcnJvcigicHJvdG9jb2wgc3RvcmUgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gSlkoJCl7bGV0IEo9YXdhaXQgYlYoKTtpZih0eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yLnN0b3JhZ2U/LnBlcnNpc3QpdHJ5e2F3YWl0IFByb21pc2UucmFjZShbbmF2aWdhdG9yLnN0b3JhZ2UucGVyc2lzdCgpLG5ldyBQcm9taXNlKChaKT0+e3NldFRpbWVvdXQoKCk9PlooITEpLDIwMDApfSldKX1jYXRjaHt9cmV0dXJuIG5ldyAkWShKLCQpfWNsYXNzIFVae2NsaWVudDtlbnREQjtwb3N0O3doZW5SZWFkeTtyZXNvbHZlUmVhZHk7cmVqZWN0UmVhZHk7Y29uc3RydWN0b3IoJCl7dGhpcy5wb3N0PSQsdGhpcy53aGVuUmVhZHk9bmV3IFByb21pc2UoKEosWik9Pnt0aGlzLnJlc29sdmVSZWFkeT1KLHRoaXMucmVqZWN0UmVhZHk9Wn0pfWFzeW5jIGluaXQoKXt0cnl7bGV0ICQ9YXdhaXQgSlkociQpLEo9YXdhaXQgb1ooe2NhY2hlOiExfSksWj1uZXcgZyQoSi5hcHBseSwoKT0+Si5jbGVhcigpLChWKT0+e2lmKFYubGVuZ3RoPDEpcmV0dXJuO3RoaXMucG9zdCh7a2luZDoiZGlydHkiLGVpZHM6Vi5tYXAoKFgpPT5YLnNsaWNlKCkpfSl9KSxRPVouY2xlYXI7Wi5jbGVhcj1hc3luYygpPT57bGV0IFY9YXdhaXQgUSgpO2lmKFY9PT0wKXRoaXMucG9zdCh7a2luZDoid2lwZWQifSk7cmV0dXJuIFZ9O2xldCBZPW5ldyB2SihuZXcgTkosWiwkLGJaLHIkKTt0aGlzLmNsaWVudD1ZLHRoaXMuZW50REI9SixZLmNsaWVudFN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdENsaWVudFN0YXRlKCl9KSxZLnhmZXJTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRYZmVyU3RhdGUoKX0pLGF3YWl0IHRoaXMuZW1pdFhmZXJTdGF0ZSgpLHRoaXMucG9zdCh7a2luZDoicmVhZHkifSksdGhpcy5tYXJrUmVhZHkoKX1jYXRjaCgkKXtsZXQgSj0kIGluc3RhbmNlb2YgRXJyb3I/JDpFcnJvcihTdHJpbmcoJCkpO3Rocm93IHRoaXMucG9zdCh7a2luZDoiaW5pdEVycm9yIixtZXNzYWdlOkoubWVzc2FnZX0pLHRoaXMuZmFpbFJlYWR5KEopLEp9fW1hcmtSZWFkeSgpe2xldCAkPXRoaXMucmVzb2x2ZVJlYWR5O2lmKHRoaXMucmVzb2x2ZVJlYWR5PXZvaWQgMCx0aGlzLnJlamVjdFJlYWR5PXZvaWQgMCwkKSQoKX1mYWlsUmVhZHkoJCl7bGV0IEo9dGhpcy5yZWplY3RSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsSilKKCQpfXJlcXVpcmVDbGllbnQoKXtpZighdGhpcy5jbGllbnQpdGhyb3cgRXJyb3IoIldvcmtlclJ1bnRpbWUgbm90IGluaXRpYWxpemVkIik7cmV0dXJuIHRoaXMuY2xpZW50fWFzeW5jIGVtaXRDbGllbnRTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgSj1hd2FpdCAkLmNsaWVudFN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoiY2xpZW50U3RhdGUiLGNvbm5lY3RlZDpKLmNvbm5lY3RlZH0pfWFzeW5jIGVtaXRYZmVyU3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IEo9YXdhaXQgJC54ZmVyU3RhdGUuZ2V0KCk7dGhpcy5wb3N0KHtraW5kOiJ4ZmVyU3RhdGUiLHN0YXRlOkp9KX1ob3N0RnJvbVNlcmlhbGl6ZWQoJCl7cmV0dXJue2hhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxsYWJlbDokLmxhYmVsLGlkeDokLmlkeH19YXN5bmMgaGFuZGxlKCQpe2F3YWl0IHRoaXMud2hlblJlYWR5O2xldCBKPXRoaXMucmVxdWlyZUNsaWVudCgpO3N3aXRjaCgkLm9wKXtjYXNlInBpbmciOnJldHVybiJwb25nIjtjYXNlInNldFNlZWQiOntsZXRbWixRXT1XMC5mcm9tQnl0ZXMoJC5zZWVkKTtpZigkLnNlZWQuZmlsbCgwKSxRIT09MHx8Wj09PXZvaWQgMCl0aHJvdyBuZXcgTzAoUSk7YXdhaXQgSi5zZXRTZWVkKFose3BlcnNpc3Q6JC5wZXJzaXN0fSk7cmV0dXJufWNhc2UibGluayI6e2F3YWl0IEoubGluayh0aGlzLmhvc3RGcm9tU2VyaWFsaXplZCgkLmhvc3QpLCQuY29ubmVjdD8/ITApO3JldHVybn1jYXNlInVubGluayI6e2F3YWl0IEoudW5saW5rKCQubGFiZWwpO3JldHVybn1jYXNlImNvbm5lY3QiOnthd2FpdCBKLmNvbm5lY3QoJC5saXN0ZW4/PyEwLCQuc3luYz8/ITApO3JldHVybn1jYXNlImRpc2Nvbm5lY3QiOnthd2FpdCBKLmRpc2Nvbm5lY3QoKTtyZXR1cm59Y2FzZSJzeW5jIjpyZXR1cm4gYXdhaXQgSi5zeW5jKCk7Y2FzZSJyZWJ1aWxkIjpyZXR1cm4gYXdhaXQgSi5yZWJ1aWxkKHtjaGVja0hvc3Q6JC5jaGVja0hvc3Q/PyEwfSk7Y2FzZSJyZWNvbmNpbGUiOntsZXRbWixRXT1hd2FpdCBKLnJlY29uY2lsZSgkLmhvc3RMYWJlbCx7cHVsbDokLnB1bGwscHVzaDokLnB1c2gsc3luYzokLnN5bmN9KTtpZihRIT09MCl0aHJvdyBuZXcgTzAoUSk7aWYoIVopdGhyb3cgbmV3IE8wKDEyKTtyZXR1cm4gWn1jYXNlIm1zZ2NoZWNrIjpyZXR1cm4gYXdhaXQgSi5tc2djaGVjaygpO2Nhc2UiZW50Y2hlY2siOntsZXQgWj10aGlzLmVudERCO2lmKCFaKXRocm93IG5ldyBPMCgxMik7bGV0W1EsWV09YXdhaXQgWi5jaGVja3N1bShyJCk7aWYoWSE9PTApdGhyb3cgbmV3IE8wKFkpO2lmKCFRKXRocm93IG5ldyBPMCgxMik7cmV0dXJuIFF9Y2FzZSJ3aXBlIjp7YXdhaXQgSi53aXBlKHttc2dzOiQubXNncyxlbnRzOiQuZW50cyxtZXRhOiQubWV0YSxzZWVkOiQuc2VlZH0pO3JldHVybn1jYXNlImltcG9ydCI6e2xldCBaPSQuYnl0ZXMuc2xpY2UoKSxRPW5ldyBCbG9iKFtaXSksWT1uZXcgRmlsZShbUV0sImltcG9ydC5kaXAiKTtyZXR1cm4gYXdhaXQgSi5pbXBvcnQoWSl9Y2FzZSJleHBvcnQiOntsZXRbWixRXT1hd2FpdCBKLmV4cG9ydEJ5dGVzKCk7aWYoUSE9PTApdGhyb3cgbmV3IE8wKFEpO2lmKCFaKXRocm93IG5ldyBPMCgxMik7cmV0dXJuIFp9Y2FzZSJnZXRYZmVyU3RhdGUiOnJldHVybiBhd2FpdCBKLnhmZXJTdGF0ZS5nZXQoKTtkZWZhdWx0OntsZXQgWj0kO3Rocm93IEVycm9yKCJ1bmtub3duIHdvcmtlciBjb21tYW5kIil9fX19Y2xhc3MgTzAgZXh0ZW5kcyBFcnJvcntzdGF0dXM7Y29uc3RydWN0b3IoJCl7c3VwZXIoYFdvcmtlclN0YXR1c0Vycm9yOiAke0RbJF19YCk7dGhpcy5zdGF0dXM9JDt0aGlzLm5hbWU9IldvcmtlclN0YXR1c0Vycm9yIn19ZnVuY3Rpb24gWUooJCxKKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITAscmVzdWx0Okp9fWZ1bmN0aW9uIFJaKCQsSil7cmV0dXJue2tpbmQ6InJlcGx5IixpZDokLG9rOiExLHN0YXR1czpKfX12YXIgQjA9Z2xvYmFsVGhpcyxaWT1uZXcgVVooKCQsSik9PntpZihKJiZKLmxlbmd0aD4wKUIwLnBvc3RNZXNzYWdlKCQsSik7ZWxzZSBCMC5wb3N0TWVzc2FnZSgkKX0pO0IwLm9ubWVzc2FnZT0oJCk9PntsZXQgSj0kLmRhdGE7aWYoIUlaKEopKXJldHVybjtoVihKKX07YXN5bmMgZnVuY3Rpb24gaFYoJCl7dHJ5e2xldCBKPWF3YWl0IFpZLmhhbmRsZSgkKTtpZigoJC5vcD09PSJleHBvcnQifHwkLm9wPT09Im1zZ2NoZWNrInx8JC5vcD09PSJlbnRjaGVjayIpJiZKIGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IFo9Si5zbGljZSgpO0IwLnBvc3RNZXNzYWdlKFlKKCQuaWQsWiksW1ouYnVmZmVyXSk7cmV0dXJufWlmKCQub3A9PT0icmVjb25jaWxlIiYmSiYmdHlwZW9mIEo9PT0ib2JqZWN0IiYmIm1zZ2NoZWNrImluIEomJkoubXNnY2hlY2sgaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgWj1KLm1zZ2NoZWNrLnNsaWNlKCksUT17Li4uSixtc2djaGVjazpafTtCMC5wb3N0TWVzc2FnZShZSigkLmlkLFEpLFtaLmJ1ZmZlcl0pO3JldHVybn1CMC5wb3N0TWVzc2FnZShZSigkLmlkLEopKX1jYXRjaChKKXtpZihKIGluc3RhbmNlb2YgTzApe0IwLnBvc3RNZXNzYWdlKFJaKCQuaWQsSi5zdGF0dXMpKTtyZXR1cm59Y29uc29sZS5lcnJvcigid29ya2VyIGNvbW1hbmQgZmFpbGVkIixKKSxCMC5wb3N0TWVzc2FnZShSWigkLmlkLDEyKSl9fVpZLmluaXQoKS5jYXRjaCgoJCk9Pntjb25zb2xlLmVycm9yKCJ3b3JrZXIgaW5pdCBmYWlsZWQiLCQpfSk7Cg==";var pW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,BV=pW===void 0?void 0:pW.prototype.postMessage,yW;function VG(){if(typeof SW!=="string"||SW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(SW)}function lG(){if(yW!==void 0)return yW;let Z=new Blob([VG()],{type:"text/javascript"});return yW=URL.createObjectURL(Z),yW}function b0(){if(pW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new pW(lG(),{type:"module"})}function d0(Z,X,W){if(BV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)BV.call(Z,X,{transfer:W});else BV.call(Z,X)}var KG=new TextEncoder().encode("diplomatic.wrap.v1"),GG=32,mG=16,FZ=new nZ;class ZZ{#Z;constructor(Z){this.#Z=Z}static async fromRandom(){let Z=await FZ.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??QW,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await F0({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf",authenticatorAttachment:Z?.authenticatorAttachment,hints:Z?.hints,salt:X});if(G!==0)return Y(G);if(K===void 0)return Y(30);if(!K.prfEnabled)return Y(30);W=K.credId}let[V,l]=await OV({rpId:Z?.rpId,rpName:Z?.rpName,credId:W,salt:X,hints:Z?.hints});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await this.#W(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X){let[W,V]=await OV({rpId:X.rpId,rpName:X.rpName,hints:X.hints,credId:X.credId,salt:X.salt});if(V!==0)return Y(V);if(W===void 0)return Y(7);try{let[l,K]=await ZZ.#V(Z,W.prf);if(K!==0)return Y(K);if(l===void 0)return Y(12);return b({enclave:l,credId:W.credId.slice()})}finally{W.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await IW(X);if(G!==0)return Y(G);if(K===void 0)return Y(30);W=K}let[V,l]=this.#l(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await wX(W,V,X);if(K!==0)return Y(K);return b(W)}finally{V.fill(0)}}static async fromLargeBlob(Z){let[X,W]=await LW(Z?.credId,Z);if(W!==0)return Y(W);if(X===void 0)return Y(7);try{return ZZ.#K(X.blob,X.credId)}finally{X.blob.fill(0)}}static async clearLargeBlob(Z,X){return wX(Z,new Uint8Array(kZ),X)}static pairRequest(){return iX.create()}async pairAccept(Z,X){let W;try{W=await FZ.genX25519()}catch{return Y(29)}try{let[V,l]=await jV(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 FZ.encryptXSalsa20Poly1305Combined(K,V);return UV(TZ(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(kW,l);if(G!==0)return Y(G);return b(K.result())}finally{K.wipe()}}finally{W.fill(0)}}spawnSyncWorker(Z){let X=b0(),W=this.#Z.slice();return d0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#Y(W,G),l=(G)=>this.#R(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.#C(W,V,G),kdmFor:(G)=>this.#F(W,V,G)})}async#W(Z){let[X,W]=await k0(FZ,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await FZ.encryptXSalsa20Poly1305Combined(this.#Z,X);return yZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#V(Z,X){let[,W]=yZ(Z);if(W!==0)return Y(W);let[V,l]=await k0(FZ,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await FZ.decryptXSalsa20Poly1305Combined(Z,V)}catch{return Y(20)}return ZZ.fromBytes(K)}finally{V.fill(0),K?.fill(0)}}#l(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]=G0(W,Z);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=new E,m=G.writeStruct(hV,l);if(m!==0)return Y(m);return b(G.result())}finally{l.masterSeed.fill(0)}}finally{W.fill(0)}}static#K(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(hV);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#Y(Z,X){let W=await this.#G(Z);try{return await FZ.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#R(Z,X){let W=await this.#G(Z);try{return await FZ.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){return FZ.blake3(TZ(this.#Z,Z))}async#J(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(TZ(W,V))}async#m(Z,X){let W=await this.#J(Z,X);try{return await FZ.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#C(Z,X,W){let V=await this.#m(Z,X);try{return await FZ.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#F(Z,X,W){let V=await this.#m(Z,X),l=TZ(V.privateKey,W);V.privateKey.fill(0);try{return(await FZ.blake3(l)).slice(0,UZ)}finally{l.fill(0)}}}async function k0(Z,X,W=KG){if(X.byteLength<mG)return Y(10);let V=await Z.blake3(TZ(X,W));return b(V.slice(0,GG))}class MW{#Z;#X;#W;#V;constructor(Z){if(this.#V=Z.persistMeta,this.#W={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=sZ(Z.meta)}get meta(){return this.#X===void 0?void 0:sZ(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:sZ(Z)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use wrapAndSave(enclave) to persist sealed master"));return this.#Z=Z,this.#Z}async wrapAndSave(Z,X){let[W,V]=await Z.sealWithPasskey({...this.#W,salt:X?.salt,credId:X?.credId??this.#X?.credId,createCredIfNeeded:X?.createCredIfNeeded??X?.credId===void 0,userName:"diplomatic-prf",authenticatorAttachment:X?.authenticatorAttachment,hints:X?.hints});if(V!==0)return Y(V);if(W===void 0)return Y(12);let l={sealedMaster:W.sealedMaster,salt:W.salt,credId:W.credId};return this.#X=l,this.#Z=Z,await this.#V(sZ(l)),b(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.unsealWithPasskey(Z.sealedMaster,{...this.#W,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(this.#Z=X.enclave,X.credId.byteLength>0&&(Z.credId===void 0||!n(Z.credId,X.credId))){let V={sealedMaster:Z.sealedMaster,salt:Z.salt,credId:X.credId.slice()};this.#X=V,await this.#V(sZ(V))}return b(X.enclave)}async adoptSealed(Z,X){return this.#X=sZ(X),this.#Z=Z,await this.#V(sZ(X)),b(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function sZ(Z){let[X,W]=yZ(Z.sealedMaster.slice());return{sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()}}var YG="diplomatic.pin/";function RG(Z){return YG+YZ(Z)}async function c0(Z,X,W){let V=await X.deriveIdentity(RG(W),0);return Z.blake3(V.publicKey)}async function xW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await c0(Z,X,W);return{n:W,h:V}}async function zW(Z,X,W){let V=await c0(Z,X,W.n);return JG(V,W.h)}function T0(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 NW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function JG(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 HW="prfMeta",wV="idPin",I0="idPub";class gW{#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(HW),X.delete(wV),X.delete(I0)})}async loadPrfMeta(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(HW);l.onsuccess=()=>{W(CG(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(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),Z===void 0){W.delete(HW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,HW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async lastPrfCredId(){let Z=await this.loadPrfMeta();return Z?.credId===void 0?void 0:Z.credId.slice()}async openPrfStore(Z){let X=await this.loadPrfMeta();return new MW({rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}async#W(Z){await this.#K(I0);let X=await this.#V();if(X!==void 0){if(!await zW(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 xW(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(wV);l.onsuccess=()=>W(T0(l.result)),l.onerror=()=>V(l.error)})}#l(Z){let X=NW(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,wV)})}#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)})}}function CG(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.sealedMaster instanceof Uint8Array)||!(X.salt instanceof Uint8Array))return;let[W,V]=yZ(X.sealedMaster);if(V!==0||W===void 0)return;return{sealedMaster:W,salt:X.salt.slice(),credId:X.credId instanceof Uint8Array?X.credId.slice():void 0}}class DV{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 R=YZ(m);l.put({host:Z,hash:R})}})}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 R=YZ(m);l.delete([Z,R])}})}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((R)=>R.host===Z).map((R)=>R.hash);V(m.map((R)=>pX(R)))},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",CZ="downloadQueue",$="messages",uX="apld",L0=3,Q0="diplomatic-store-db";class AV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new gW(Z,X),this.hosts=new HV(Z),this.uploads=new DV(Z),this.downloads=new NV(Z),this.messages=new gV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function FG(){return new Promise((Z,X)=>{let W=indexedDB.open(Q0,L0);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(CZ))V.createObjectStore(CZ);let K;if(!V.objectStoreNames.contains($))K=V.createObjectStore($);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore($)}if(!K.indexNames.contains(uX))K.createIndex(uX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${Q0} → v${L0}); 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 vV(Z){let X=await FG();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new AV(X,Z)}function S0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function y0(Z){if(typeof Z!=="number")return;return Z}function bG(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=dG(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 dG(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 p0(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=bG(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var dZ="[DIPLOMATIC]";class AX{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:oZ};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 gX(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 dX(W,Z,X,()=>{throw Error(`${dZ} local writer has no transport (use worker for network)`)},IX,!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 uZ,l=W.syncDebounceMs??VW,K=W.readyTimeoutMs??15000,G=new AX(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:oZ}}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=p0(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(!S0(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(cG));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 DX(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=y0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof DX)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=(R)=>{if(G!==void 0)clearTimeout(G);R()};this.pending.set(W,{resolve:(R)=>m(()=>l(R)),reject:(R)=>m(()=>K(R))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${dZ} setSeed worker timeout after ${V}ms`))},V);try{let R=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(R)}catch(R){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(R instanceof Error?R:Error(String(R)))}});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(!kG(W))return Y(12);return b(W)}catch(W){if(W instanceof DX&&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 KW(V,Z),0}catch(W){if(W instanceof DX)return W.status;return 12}}}class DX extends Error{status;constructor(Z){super(`WorkerReplyError: ${M[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function kG(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 cG(Z){return Z}var LX="[DIPLOMATIC]";async function hW(Z){let X=Z.clock??new uZ;if(Z.worker===!0&&TG(Z)!==void 0)throw Error(`${LX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${LX} sync on main thread `+"(no worker — app did not request a worker)");let l=await M0(Z.store);return IG(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${LX} worker: true but Worker API is unavailable`);let W=await M0(void 0),V=await AX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${LX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${LX} terminating sync worker`),V.terminate()}}}function TG(Z){if("store"in Z)return Z.store;return}async function IG(Z,X,W){let V=new dX(Z,X,W,fW,IX);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function M0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${LX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return vV(IX)}function LG(Z){let[X,W]=oV();return PW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function QG(Z){let[X,W]=oV();return PW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function SG(Z){PW(()=>{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 yG(Z={}){let X=Z.clock??new uZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=oV({stateMgr:rW});return PW(()=>{let J=!1,C;return(async()=>{let F=await VV();if(J)return;let d=XW(F),k=K?await hW({state:d,clock:X,worker:!0,readyTimeoutMs:l}):await hW({state:d,clock:X,store:G,readyTimeoutMs:l});if(J){k.dispose();return}C=k.dispose;let{client:c,mode:T}=k;if(W)await c.setSeed(W);if(V)await c.link(V);if(J){C();return}R({client:c,entDB:F,stateMgr:d,mode:T,error:void 0})})().catch((F)=>{let d=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",d),!J)R((k)=>({...k,client:void 0,error:d}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as pG,useEffect as x0,useRef as MG,useState as xG}from"react";function z0(Z,X,W){let[V,l]=xG();return x0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function zG(Z,X,W){let V=MG(W());return x0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),pG(V.current)}function N0(Z,X){return`${Z}:${X}`}class $V{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 NG(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 qV{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;NG(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 fV{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 iZ(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&&bX(K.apld)!==X)continue;let G=e(l);V.push(await iZ(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(bX(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(n(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 iZ(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;$Z(W,EZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(H(X));if(!V)continue;$Z(V,IZ,W)}}async wipe(){this.messages.clear()}}class nV{#Z;#X;#W;constructor(Z){this.#X=Z}async save(Z,X){if(this.#W!==void 0){if(!await zW(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 xW(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:NW(this.#W)}}class _V{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(pX(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 H0{seed;hosts=new qV;uploads=new _V;downloads=new $V;messages;constructor(Z){this.seed=new nV(Z),this.messages=new fV(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class g0{singletonType;latest;latestOff=-1;emitter=new hZ;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,R)=>m===G[R])){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 aV={capable(){return C0()},async createCred(Z){return IW(Z)},async write(Z,X,W){return wX(Z,X,W)},async read(Z,X){let[W,V]=await LW(Z,X);if(V!==0||W===void 0)return Y(V);return b(W.blob)}};class h0{#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 mk(){return aV.capable()}export{XG as webAuthnLastError,SG as useSyncOnResume,zG as useStateWatcherSuspense,z0 as useStateWatcher,QG as useClientXferState,LG as useClientState,yG as useClient,lW as shouldEmitItemProgress,$Z as setApld,lV as revFromHead,NX as revFromEntity,WG as prfCapable,vV as openIDBStore,VV as openEntDB,hW as openDiplomaticClient,rW as nullStateManager,SK as nullEntDB,Ml as normalizeTags,mk as largeBlobCapable,QK as isTombstone,GV as isTerminalApplyFailure,MK as isPendingApply,v as isLiveEnt,pK as isApldState,oZ as idleProgress,pX as htob,fW as hostHTTPTransport,VK as genSingletonEID,XW as entStateManager,Ll as encodeEntRev,s as eidCodec,TW as defaultWebAuthnRpId,FX as defaultPeekProgressEvery,IX as crypto,Il as cmpBytes,GX as checksumSet,xX as checksumEntRevs,YZ as btoh,lK as btob64url,H as btob64,BW as b64urltob,e as b64tob,yZ as asSealedMasterKey,UV as asDHKEResp,PV as asDHKEReq,bX as apldFromStored,AX as WorkerClient,hZ as TypedEventEmitter,dX as SyncClient,M as Status,zX as StateManager,g0 as SingletonStateManager,sW as SEALED_MASTER_KEY_LEN,MW as PrfSeedStore,h0 as PasskeySeedStore,iX as PairRequest,H0 as MemoryStore,kZ as MASTER_SEED_LEN,AV as IDBStore,gW as IDBSeedStore,qW as HTTPTransport,WV as EntIDB,ZW as EntDBMemory,E as Encoder,ZZ as Enclave,j as Decoder,QW as DEFAULT_PRF_SALT,uZ as Clock,HX as CachedEntDB,pZ as APLD_PENDING,IZ as APLD_ERROR,EZ as APLD_APPLIED};
|