vis-core 0.28.23 → 0.28.25
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/editor/command/AddMaterial.d.ts +3 -3
- package/dist/editor/viewport.d.ts +8 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.module.js +84 -32
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function(){"use strict";try{if(typeof document!="undefined"){var t=document.createElement("style");t.appendChild(document.createTextNode(".-translate-x-1\\/2,.-translate-y-1\\/2,.transform{--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1 }.shadow{--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000 }.invert,.filter{--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: }.visible{visibility:visible}.static{position:static}.absolute{position:absolute}.left-1\\/2{left:50%}.top-1\\/2{top:50%}.-translate-x-1\\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.resize{resize:both}.whitespace-nowrap{white-space:nowrap}.text-center{text-align:center}.text-sm{font-size:14px;line-height:20px}.leading-\\[1\\]{line-height:1}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.text-opacity-80{--tw-text-opacity: .8 }.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}")),document.head.appendChild(t)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}})();
|
|
2
|
-
"use strict";var Kn=Object.defineProperty,Fn=Object.defineProperties;var An=Object.getOwnPropertyDescriptors;var Pn=Object.getOwnPropertySymbols,kn=Object.getPrototypeOf,Hn=Object.prototype.hasOwnProperty,Yn=Object.prototype.propertyIsEnumerable,Bn=Reflect.get;var Ln=(g,t)=>(t=Symbol[g])?t:Symbol.for("Symbol."+g),Un=g=>{throw TypeError(g)},mn=Math.pow,Vn=(g,t,r)=>t in g?Kn(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,q0=(g,t)=>{for(var r in t||(t={}))Hn.call(t,r)&&Vn(g,r,t[r]);if(Pn)for(var r of Pn(t))Yn.call(t,r)&&Vn(g,r,t[r]);return g},Ji=(g,t)=>Fn(g,An(t));var C0=(g,t,r)=>Vn(g,typeof t!="symbol"?t+"":t,r);var yn=(g,t,r)=>Bn(kn(g),r,t);var U0=(g,t,r)=>new Promise((m,v)=>{var C=I=>{try{w(r.next(I))}catch(O){v(O)}},_=I=>{try{w(r.throw(I))}catch(O){v(O)}},w=I=>I.done?m(I.value):Promise.resolve(I.value).then(C,_);w((r=r.apply(g,t)).next())}),Dn=function(g,t){this[0]=g,this[1]=t};var En=g=>{var t=g[Ln("asyncIterator")],r=!1,m,v={};return t==null?(t=g[Ln("iterator")](),m=C=>v[C]=_=>t[C](_)):(t=t.call(g),m=C=>v[C]=_=>{if(r){if(r=!1,C==="throw")throw _;return _}return r=!0,{done:!1,value:new Dn(new Promise(w=>{var I=t[C](_);I instanceof Object||Un("Object expected"),w(I)}),1)}}),v[Ln("iterator")]=()=>v,m("next"),"throw"in t?m("throw"):v.throw=C=>{throw C},"return"in t&&m("return"),v},In=(g,t,r)=>(t=g[Ln("asyncIterator")])?t.call(g):(g=g[Ln("iterator")](),t={},r=(m,v)=>(v=g[m])&&(t[m]=C=>new Promise((_,w,I)=>(C=v.call(g,C),I=C.done,Promise.resolve(C.value).then(O=>_({value:O,done:I}),w)))),r("next"),r("return"),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const jsrsasign=require("jsrsasign"),CryptoJS=require("crypto-js"),esusLite=require("esus-lite"),events=require("events"),turf=require("@turf/turf"),world$1=require("geojson-cn/json/0.json"),json100000Lite=require("geojson-cn/json-lite/100000.json"),json100000=require("geojson-cn/json/100000.json"),adcodeAll=require("geojson-cn/json-lite/all.json"),geojsonCn=require("geojson-cn");Array.prototype.at||(Array.prototype.at=function(g){return g<0&&(g=this.length+g),this[g]});const publicKeyPEM="LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEyTG1aVVQzVG9LZEVRRUdrdUU1QQo3dnlYTzRMM1Z6NDA5RFF2a2xzRHZ2SytNM2M2OGl4ZEVhZDZFcnZGS2FKQ1QrNTZNdU1XSXhUTnlDZDVQSkFGCjVYdzI4cW1iVkVCR3FGdXVIZTltSm5GUmRXN1NpK1Z1cTZvRWxwQkRkeEFIQ0dsWVVpU1R3WmhBbjJaVXJLSUYKd1J2c1k1bi9uWWNhZnl5QW9tRjhmNVRsTkpwS1JtbDU3WlRSWjBMdzdQRDFSeHFIbmJ0YWFETkpiSDV5eFd6cQpaVTBwQWhxMFNkNHdlOW1DUTJWWXc5czhtUERLbW4rU083eGovSUsrR1ZEaEJNOUpaZ3VIcGFZUGt3bWd5UkdwCkx6V0tHMkZULzJRalZUT1dRT09mRFVtVitDSVlsN1hVVlh1Q0toYWFNQ0ZVa1JQOHg4aEZucmNFeklHQ1JpM3IKK3dJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t",accessToken={token:void 0,getInfo(){if(!this.token)return"";const[g,t,r]=this.token.split(":::"),m=jsrsasign.KEYUTIL.getKey(atob(publicKeyPEM)),v=CryptoJS.enc.Base64.parse(t),C=CryptoJS.enc.Base64.parse(r),_=CryptoJS.lib.WordArray.create(v.words.slice(0,4)),w=CryptoJS.lib.WordArray.create(v.words.slice(4)),I=jsrsasign.KJUR.crypto.Util.hashHex(v.toString(),"sha256"),O=m.verifyWithMessageHashPSS(I,jsrsasign.b64tohex(g),"sha256",32);if(!O)return this.token=void 0,"";const Ne=CryptoJS.AES.decrypt({ciphertext:w},C,{iv:_,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8),Fe=JSON.parse(Ne),Ae=Date.now();return!Fe.s||Fe.s>Ae?(this.token=void 0,""):Fe.e&&Fe.e<Ae?(this.token=void 0,""):(Fe.isValid=O,Fe)}},version="0.28.
|
|
2
|
+
"use strict";var Kn=Object.defineProperty,Fn=Object.defineProperties;var An=Object.getOwnPropertyDescriptors;var Pn=Object.getOwnPropertySymbols,kn=Object.getPrototypeOf,Hn=Object.prototype.hasOwnProperty,Yn=Object.prototype.propertyIsEnumerable,Bn=Reflect.get;var Ln=(g,t)=>(t=Symbol[g])?t:Symbol.for("Symbol."+g),Un=g=>{throw TypeError(g)},mn=Math.pow,Vn=(g,t,r)=>t in g?Kn(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,q0=(g,t)=>{for(var r in t||(t={}))Hn.call(t,r)&&Vn(g,r,t[r]);if(Pn)for(var r of Pn(t))Yn.call(t,r)&&Vn(g,r,t[r]);return g},Ji=(g,t)=>Fn(g,An(t));var C0=(g,t,r)=>Vn(g,typeof t!="symbol"?t+"":t,r);var yn=(g,t,r)=>Bn(kn(g),r,t);var U0=(g,t,r)=>new Promise((m,v)=>{var C=I=>{try{w(r.next(I))}catch(O){v(O)}},_=I=>{try{w(r.throw(I))}catch(O){v(O)}},w=I=>I.done?m(I.value):Promise.resolve(I.value).then(C,_);w((r=r.apply(g,t)).next())}),Dn=function(g,t){this[0]=g,this[1]=t};var En=g=>{var t=g[Ln("asyncIterator")],r=!1,m,v={};return t==null?(t=g[Ln("iterator")](),m=C=>v[C]=_=>t[C](_)):(t=t.call(g),m=C=>v[C]=_=>{if(r){if(r=!1,C==="throw")throw _;return _}return r=!0,{done:!1,value:new Dn(new Promise(w=>{var I=t[C](_);I instanceof Object||Un("Object expected"),w(I)}),1)}}),v[Ln("iterator")]=()=>v,m("next"),"throw"in t?m("throw"):v.throw=C=>{throw C},"return"in t&&m("return"),v},In=(g,t,r)=>(t=g[Ln("asyncIterator")])?t.call(g):(g=g[Ln("iterator")](),t={},r=(m,v)=>(v=g[m])&&(t[m]=C=>new Promise((_,w,I)=>(C=v.call(g,C),I=C.done,Promise.resolve(C.value).then(O=>_({value:O,done:I}),w)))),r("next"),r("return"),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const jsrsasign=require("jsrsasign"),CryptoJS=require("crypto-js"),esusLite=require("esus-lite"),events=require("events"),turf=require("@turf/turf"),world$1=require("geojson-cn/json/0.json"),json100000Lite=require("geojson-cn/json-lite/100000.json"),json100000=require("geojson-cn/json/100000.json"),adcodeAll=require("geojson-cn/json-lite/all.json"),geojsonCn=require("geojson-cn");Array.prototype.at||(Array.prototype.at=function(g){return g<0&&(g=this.length+g),this[g]});const publicKeyPEM="LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEyTG1aVVQzVG9LZEVRRUdrdUU1QQo3dnlYTzRMM1Z6NDA5RFF2a2xzRHZ2SytNM2M2OGl4ZEVhZDZFcnZGS2FKQ1QrNTZNdU1XSXhUTnlDZDVQSkFGCjVYdzI4cW1iVkVCR3FGdXVIZTltSm5GUmRXN1NpK1Z1cTZvRWxwQkRkeEFIQ0dsWVVpU1R3WmhBbjJaVXJLSUYKd1J2c1k1bi9uWWNhZnl5QW9tRjhmNVRsTkpwS1JtbDU3WlRSWjBMdzdQRDFSeHFIbmJ0YWFETkpiSDV5eFd6cQpaVTBwQWhxMFNkNHdlOW1DUTJWWXc5czhtUERLbW4rU083eGovSUsrR1ZEaEJNOUpaZ3VIcGFZUGt3bWd5UkdwCkx6V0tHMkZULzJRalZUT1dRT09mRFVtVitDSVlsN1hVVlh1Q0toYWFNQ0ZVa1JQOHg4aEZucmNFeklHQ1JpM3IKK3dJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t",accessToken={token:void 0,getInfo(){if(!this.token)return"";const[g,t,r]=this.token.split(":::"),m=jsrsasign.KEYUTIL.getKey(atob(publicKeyPEM)),v=CryptoJS.enc.Base64.parse(t),C=CryptoJS.enc.Base64.parse(r),_=CryptoJS.lib.WordArray.create(v.words.slice(0,4)),w=CryptoJS.lib.WordArray.create(v.words.slice(4)),I=jsrsasign.KJUR.crypto.Util.hashHex(v.toString(),"sha256"),O=m.verifyWithMessageHashPSS(I,jsrsasign.b64tohex(g),"sha256",32);if(!O)return this.token=void 0,"";const Ne=CryptoJS.AES.decrypt({ciphertext:w},C,{iv:_,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8),Fe=JSON.parse(Ne),Ae=Date.now();return!Fe.s||Fe.s>Ae?(this.token=void 0,""):Fe.e&&Fe.e<Ae?(this.token=void 0,""):(Fe.isValid=O,Fe)}},version="0.28.25";/**
|
|
3
3
|
* @license
|
|
4
4
|
* Copyright 2010-2025 Three.js Authors
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
@@ -4852,7 +4852,7 @@ version 0.8.2
|
|
|
4852
4852
|
gl_FragColor = ( base_color + vec4( 1.0 ) * bloom_color );
|
|
4853
4853
|
}
|
|
4854
4854
|
}
|
|
4855
|
-
`,defines:{}}),"baseTexture");return t.needsSwap=!0,t},zs=new MeshBasicMaterial({color:"black"}),ks=new PointsMaterial({color:"black",sizeAttenuation:!1}),Fs=new PointsMaterial({color:"black",sizeAttenuation:!0}),Ns=new SpriteMaterial({color:"black",sizeAttenuation:!0}),js=new SpriteMaterial({color:"black",sizeAttenuation:!1}),Is=new We$1({color:"black",sizeAttenuation:0,lineWidth:0}),Hs={kernelRadius:8,minDistance:.005,maxDistance:.1},Bs={threshold:0,strength:.4,radius:.1,bloomAlphaType:0},Vs={multisampling:4,premultiplieAlpha:!1};class Ys{constructor(t){this.bloomComposerActive=!1,this.active=!0,this.bloomSelection=new Set,this.bloomLayer=new Layers,this.bloomMaterials={},this.bloomVisible={},this.bloomComposerRenderIng=!1,this.pipViewportState=null,this.options=t;const{rendererController:r,sceneController:m,cameraController:v,composerParams:C}=t,{renderer:_}=r;this.renderer=_;const{multisampling:w}=C,{maxSamples:I}=_.capabilities,O=_.getDrawingBufferSize(new Vector2),Pe=new WebGLRenderTarget(O.width,O.height,{samples:Math.min(w,I),type:HalfFloatType}),Ne=new EffectComposer(_,Pe),Fe=this.getSize();Ne.setSize(Fe.width,Fe.height);const Ae=new RenderPass(m.scene,v.camera);Ne.addPass(Ae),this.scene=m.scene,this.camera=v.camera,this.finalComposer=Ne,this.renderPass=Ae,v.event.on("pageChange",De=>{this.changeCamera(De)}),m.event.on("pageChange",De=>{this.changeScene(De)})}changeCamera(t){this.renderPass.camera=t,this.camera=t}changeScene(t){this.renderPass.scene=t,this.ssaoPass&&(this.ssaoPass.scene=t),this.scene=t}addOutputPass(){const{premultiplieAlpha:t}=this.options.composerParams,r=new Ds;this.outputPass=r,this.setPremultiplieAlpha(t),this.finalComposer.addPass(r)}setPremultiplieAlpha(t){this.outputPass&&(this.outputPass.uniforms.premultiplieAlpha.value=t?1:0)}addSSAOPass(t){const{scene:r,camera:m,renderer:v}=this,C=v.getSize(new Vector2),_=C.width,w=C.height,I=new SSAOPass(r,m,_,w);I.kernelRadius=t.kernelRadius,I.minDistance=t.minDistance,I.maxDistance=t.maxDistance,this.ssaoPass=I,this.finalComposer.addPass(I)}addBloomPass(t){const{renderer:r}=this,{threshold:m,strength:v,radius:C,bloomAlphaType:_}=t,w=new UnrealBloomPass(new Vector2(window.innerWidth,window.innerHeight),v,C,m);this.bloomPass=w;const I=new EffectComposer(r);I.renderToScreen=!1,I.addPass(this.renderPass),I.addPass(w),this.bloomComposer=I;const O=Us(I);O.uniforms.bloomAlphaType.value=_,this.bloomComposer=I,this.finalComposer.addPass(O),this.mixPass=O,this.bloomLayer.set(Te$1)}setBloomSelection(t,r){if(!this.bloomComposer){console.warn("err:pencil.options.bloom");return}t.traverse(m=>{const{object3d:v}=m;v&&(r?(this.bloomSelection.add(m),v.layers.enable(Te$1)):(this.bloomSelection.delete(m),v.layers.disable(Te$1)))}),this.bloomSelection.size===0?this.bloomComposerActive=!1:this.bloomComposerActive=!0}enable(){this.active||(this.active=!0)}disable(){this.active&&(this.active=!1)}setSize(t,r){var m;(m=this.bloomComposer)==null||m.setSize(t,r),this.finalComposer.setSize(t,r)}setPixelRatio(t){var r;(r=this.bloomComposer)==null||r.setPixelRatio(t),this.finalComposer.setPixelRatio(t)}darkenNonBloomed(){const t=[],r=[];this.scene.children.forEach(m=>{m.isTransformControls||m.isTransformControlsRoot||m.type==="RectAreaLightHelper"?t.push(m):r.push(m)}),r.forEach(m=>{m.traverse(v=>{var C;const _=v,w=v,I=v;(C=_.material)!=null&&C.isShadowMaterial?t.push(_):_.material&&this.bloomLayer.test(_.layers)===!1&&(this.bloomMaterials[_.uuid]=_.material,w.isSprite?w.material.sizeAttenuation?w.material=Ns:w.material=js:_.material instanceof We$1?_.material=Is:I.isPoints?I.material.sizeAttenuation?I.material=Fs:I.material=ks:_.material=zs)})}),t.forEach(m=>{this.bloomVisible[m.uuid]=m.visible,m.visible=!1})}restoreNonBloomed(){this.scene.traverse(t=>{const r=t;this.bloomMaterials[r.uuid]?(r.material=this.bloomMaterials[r.uuid],delete this.bloomMaterials[r.uuid]):this.bloomVisible[r.uuid]!==void 0&&(r.visible=this.bloomVisible[r.uuid],delete this.bloomVisible[r.uuid])})}finalComposerRender(){this.bloomComposerActive&&this.bloomComposer?(this.bloomComposerRenderIng=!0,this.mixPass.enabled=!0,this.darkenNonBloomed(),this.bloomComposer.render(),this.restoreNonBloomed(),this.bloomComposerRenderIng=!1):this.mixPass&&(this.mixPass.enabled=!1),this.finalComposer.render()}getSize(){return this.renderer.getSize(new Vector2)}render(){if(!this.active)return;const{cameraController:t,rendererController:r,sceneController:m}=this.options;if(this.finalComposerRender(),this.pipViewportState){t.setPageActive(31),t.setAspect(this.pipViewportState.width/this.pipViewportState.height),r.setViewport(te(U({},this.pipViewportState),{scissor:!0,scissorTest:!0})),this.finalComposerRender(),t.setPageActive(m.activeIndex);const v=this.getSize();r.setViewport({x:0,y:0,width:v.width,height:v.height,scissor:!0,scissorTest:!1})}}dispose(){var t;this.bloomMaterials={},this.bloomVisible={},this.bloomSelection.clear(),this.finalComposer.dispose(),(t=this.bloomComposer)==null||t.dispose()}}class Zs extends ee{constructor(t){super(),this.autoRotateSpeed=0,this.options=t;const r={Vector2,Vector3,Vector4,Quaternion,Matrix4,Spherical,Box3,Sphere:Sphere$1,Raycaster};J$1.install({THREE:r})}get cameraControls(){return this.controller}addCameraControls(t,r){const{domElement:m}=this.options.controlsParams,v=new J$1(t,m);return v.setLookAt(0,0,400,0,0,0,!1),this.addController(v,r)}setPageActive(t){super.setPageActive(t,(r,m)=>{r.enabled=m})}removePage(t){super.removePage(t,r=>{r.dispose()})}enable(){this.activeControllerSet.forEach(t=>{t.enabled=!0})}disable(){this.activeControllerSet.forEach(t=>{t.enabled=!1})}update(t,r){super.update(t,r),this.autoRotateSpeed&&this.cameraControls&&(this.cameraControls.azimuthAngle+=this.autoRotateSpeed*t*MathUtils.DEG2RAD)}}const Xe=new Vector3,Ws=new Quaternion,qe=new Vector3,j=new Matrix4,Ks=new Matrix4;class $s{constructor(t={}){const r=this;let m,v,C,_;const w={camera:{style:""},objects:new WeakMap},I=t.element!==void 0?t.element:document.createElement("div");I.style.overflow="hidden",this.domElement=I;const O=document.createElement("div");O.style.transformOrigin="0 0",O.style.pointerEvents="none",I.appendChild(O);const Pe=document.createElement("div");Pe.style.transformStyle="preserve-3d",O.appendChild(Pe),this.getSize=function(){return{width:m,height:v}},this.render=function(je,ke){const at=ke.projectionMatrix.elements[5]*_;ke.view&&ke.view.enabled?(O.style.transform=`translate( ${-ke.view.offsetX*(m/ke.view.width)}px, ${-ke.view.offsetY*(v/ke.view.height)}px )`,O.style.transform+=`scale( ${ke.view.fullWidth/ke.view.width}, ${ke.view.fullHeight/ke.view.height} )`):O.style.transform="",je.matrixWorldAutoUpdate===!0&&je.updateMatrixWorld(),ke.parent===null&&ke.matrixWorldAutoUpdate===!0&&ke.updateMatrixWorld();let ct,Gt;ke.isOrthographicCamera&&(ct=-(ke.right+ke.left)/2,Gt=(ke.top+ke.bottom)/2);const Lt=ke.view&&ke.view.enabled?ke.view.height/ke.view.fullHeight:1,Wt=ke.isOrthographicCamera?`scale( ${Lt} )scale(`+at+")translate("+Ne(ct)+"px,"+Ne(Gt)+"px)"+Fe(ke.matrixWorldInverse):`scale( ${Lt} )translateZ(`+at+"px)"+Fe(ke.matrixWorldInverse),Pt=(ke.isPerspectiveCamera?"perspective("+at+"px) ":"")+Wt+"translate("+C+"px,"+_+"px)";w.camera.style!==Pt&&(Pe.style.transform=Pt,w.camera.style=Pt),xt(je,je,ke)},this.setSize=function(je,ke){m=je,v=ke,C=m/2,_=v/2,I.style.width=je+"px",I.style.height=ke+"px",O.style.width=je+"px",O.style.height=ke+"px",Pe.style.width=je+"px",Pe.style.height=ke+"px"};function Ne(je){return Math.abs(je)<1e-10?0:je}function Fe(je){const ke=je.elements;return"matrix3d("+Ne(ke[0])+","+Ne(-ke[1])+","+Ne(ke[2])+","+Ne(ke[3])+","+Ne(ke[4])+","+Ne(-ke[5])+","+Ne(ke[6])+","+Ne(ke[7])+","+Ne(ke[8])+","+Ne(-ke[9])+","+Ne(ke[10])+","+Ne(ke[11])+","+Ne(ke[12])+","+Ne(-ke[13])+","+Ne(ke[14])+","+Ne(ke[15])+")"}function Ae(je){const ke=je.elements;return"translate(-50%,-50%)"+("matrix3d("+Ne(ke[0])+","+Ne(ke[1])+","+Ne(ke[2])+","+Ne(ke[3])+","+Ne(-ke[4])+","+Ne(-ke[5])+","+Ne(-ke[6])+","+Ne(-ke[7])+","+Ne(ke[8])+","+Ne(ke[9])+","+Ne(ke[10])+","+Ne(ke[11])+","+Ne(ke[12])+","+Ne(ke[13])+","+Ne(ke[14])+","+Ne(ke[15])+")")}function De(je){je.isCSS3DObject&&(je.element.style.display="none");for(let ke=0,at=je.children.length;ke<at;ke++)De(je.children[ke])}function xt(je,ke,at,ct){if(je.visible===!1){De(je);return}if(je.isCSS3DObject){const Gt=je.layers.test(at.layers)===!0,Lt=je.element;if(Lt.style.display=Gt===!0?"":"none",Gt===!0){je.onBeforeRender(r,ke,at);let Wt;je.isCSS3DSprite?(j.copy(at.matrixWorldInverse),j.transpose(),je.rotation2D!==0&&j.multiply(Ks.makeRotationZ(je.rotation2D)),je.matrixWorld.decompose(Xe,Ws,qe),j.setPosition(Xe),j.scale(qe),j.elements[3]=0,j.elements[7]=0,j.elements[11]=0,j.elements[15]=1,Wt=Ae(j)):Wt=Ae(je.matrixWorld);const Pt=w.objects.get(je);if(Pt===void 0||Pt.style!==Wt){Lt.style.transform=Wt;const zt={style:Wt};w.objects.set(je,zt)}Lt.parentNode!==Pe&&Pe.appendChild(Lt),je.onAfterRender(r,ke,at)}}for(let Gt=0,Lt=je.children.length;Gt<Lt;Gt++)xt(je.children[Gt],ke,at)}}}const q=new Vector3,Qe=new Matrix4,Je=new Matrix4,et=new Vector3,tt=new Vector3;class Gs{constructor(t={}){const r=this;let m,v,C,_;const w={objects:new WeakMap},I=t.element!==void 0?t.element:document.createElement("div");I.style.overflow="hidden",this.domElement=I,this.getSize=function(){return{width:m,height:v}},this.render=function(De,xt){De.matrixWorldAutoUpdate===!0&&De.updateMatrixWorld(),xt.parent===null&&xt.matrixWorldAutoUpdate===!0&&xt.updateMatrixWorld(),Qe.copy(xt.matrixWorldInverse),Je.multiplyMatrices(xt.projectionMatrix,Qe),Pe(De,De,xt),Ae(De)},this.setSize=function(De,xt){m=De,v=xt,C=m/2,_=v/2,I.style.width=De+"px",I.style.height=xt+"px"};function O(De){De.isCSS2DObject&&(De.element.style.display="none");for(let xt=0,je=De.children.length;xt<je;xt++)O(De.children[xt])}function Pe(De,xt,je){if(De.visible===!1){O(De);return}if(De.isCSS2DObject){q.setFromMatrixPosition(De.matrixWorld),q.applyMatrix4(Je);const ke=q.z>=-1&&q.z<=1&&De.layers.test(je.layers)===!0,at=De.element;at.style.display=ke===!0?"":"none",ke===!0&&(De.onBeforeRender(r,xt,je),at.style.transform="translate("+-100*De.center.x+"%,"+-100*De.center.y+"%)translate("+(q.x*C+C)+"px,"+(-q.y*_+_)+"px)",at.parentNode!==I&&I.appendChild(at),De.onAfterRender(r,xt,je));const ct={distanceToCameraSquared:Ne(je,De)};w.objects.set(De,ct)}for(let ke=0,at=De.children.length;ke<at;ke++)Pe(De.children[ke],xt,je)}function Ne(De,xt){return et.setFromMatrixPosition(De.matrixWorld),tt.setFromMatrixPosition(xt.matrixWorld),et.distanceToSquared(tt)}function Fe(De){const xt=[];return De.traverseVisible(function(je){je.isCSS2DObject&&xt.push(je)}),xt}function Ae(De){const xt=Fe(De).sort(function(ke,at){if(ke.renderOrder!==at.renderOrder)return at.renderOrder-ke.renderOrder;const ct=w.objects.get(ke).distanceToCameraSquared,Gt=w.objects.get(at).distanceToCameraSquared;return ct-Gt}),je=xt.length;for(let ke=0,at=xt.length;ke<at;ke++)xt[ke].element.style.zIndex=je-ke}}}const st={zIndex:"auto"};class Xs{constructor(t){this.container=t}addRenderer(t,r){const m=r.container||this.container,v=m.offsetWidth,C=m.offsetHeight,_=t==="css2d"?new Gs:new $s;_.domElement.style.position="absolute",_.domElement.style.top="0",_.domElement.style.pointerEvents="none",_.domElement.style.zIndex=r.zIndex,_.setSize(v,C),m.appendChild(_.domElement),t==="css2d"?this.css2Drenderer=_:t==="css3d"&&(this.css3Drenderer=_)}setSize(t,r){var m,v;(m=this.css2Drenderer)==null||m.setSize(t,r),(v=this.css3Drenderer)==null||v.setSize(t,r)}render(t,r){var m,v;(m=this.css2Drenderer)==null||m.render(t,r),(v=this.css3Drenderer)==null||v.render(t,r)}dispose(){var t,r;(t=this.css2Drenderer)==null||t.domElement.remove(),(r=this.css3Drenderer)==null||r.domElement.remove(),this.css2Drenderer=void 0,this.css3Drenderer=void 0}}class qs{constructor(t){this.helpers={},this.options=t}add(t){const r=t.uuid,{sceneController:m}=this.options;let v=this.helpers[r];if(v===void 0){if(t.isScene)v=new AxesHelper(100);else if(t.isCamera)v=new CameraHelper(t);else if(t.isPointLight)v=new PointLightHelper(t,1);else if(t.isDirectionalLight)v=new DirectionalLightHelper(t,1);else if(t.isSpotLight)v=new SpotLightHelper(t);else if(t.isHemisphereLight)v=new HemisphereLightHelper(t,10);else if(t.isRectAreaLight)v=new RectAreaLightHelper(t);else{const C=new Box3;if(C.setFromObject(t,!0),C.isEmpty()===!1){v=new Box3Helper(C);const _=v.material;_.userData.object=t,_.depthTest=!1,_.transparent=!0}else return}m.scene.add(v),this.helpers[r]=v}}addViewHelper(){const{cameraController:t,container:r}=this.options,m=new ViewHelper(t.camera,r);r.addEventListener("pointerdown",v=>{v.preventDefault(),m.handleClick(v)}),this.viewHelper=m}remove(t){var r;const m=t.uuid,{sceneController:v}=this.options;if(this.helpers[m]!==void 0){const C=this.helpers[m];v.scene.remove(C),delete this.helpers[m],(r=C.dispose)==null||r.call(C)}}removeAll(){Object.keys(this.helpers).forEach(t=>{this.remove({uuid:t})}),this.helpers={}}removeAllExcludeScene(){Object.keys(this.helpers).forEach(t=>{this.helpers[t]instanceof AxesHelper||this.remove({uuid:t})})}update(t,r,m){var v,C;const{cameraController:_}=this.options;Object.values(this.helpers).forEach(w=>{if(w.update&&w.update(),w instanceof Box3Helper){const I=w.material,{object:O}=I.userData;O&&w.box.setFromObject(O,!0)}}),((v=this.viewHelper)==null?void 0:v.animating)===!0&&(this.viewHelper.update(t),(C=r.cameraControls)==null||C.setPosition(..._.camera.position.toArray()),this.viewHelper.center.copy(m))}renderViewHelper(t){if(!this.viewHelper)return;const r=t.autoClear;t.autoClear=!1,this.viewHelper.render(t),t.autoClear=r}dispose(){var t;this.helpers={},(t=this.viewHelper)==null||t.dispose()}}function it(g){let t=!1,r=[];return function(...m){r=m,t||(t=!0,requestAnimationFrame(()=>{t=!1,g(...r)}))}}class Qs{constructor(t){var r;this.enabled=!0,this.pickFunctionsMap=new Map,this.pickNodeFunctionsMap=new Map,this.pickFunctionsMapIndex=-1,this.pickNodeFunctionsMapIndex=-1,this.activeObjects=new Set,this.activeObject=null,this.prevActiveObjects=new Set,this.objCallbackMap=new Map,this.pickListener={move:!1,down:!1},this.pencil=t,this.domElement=((r=t.options.controls)==null?void 0:r.domElement)||t.options.container}addPickListener(t){const r=new Set(["move","enter","leave"]),m=new Set(["down","downOutside","click"]),v=C=>{var _;if(!this.enabled)return;C.preventDefault();const w=t==="move"?r:m,I=[];if(this.pickFunctionsMap.forEach(Ae=>{w.has(Ae.type)&&I.push(te(U({},Ae),{objArr:Ae.objArr instanceof Function?Ae.objArr():Ae.objArr}))}),I.length===0)return;this.activeObjects.clear(),this.objCallbackMap.clear(),this.activeObject=null;const O=this.objCallbackMap;for(const Ae of I)for(const De of Ae.objArr){if(!De.object3d||!De.visibleWithAncestors)continue;O.has(De)||O.set(De,new Map);const xt=O.get(De);xt.has(Ae.type)||xt.set(Ae.type,[]),xt.get(Ae.type).push(Ae.cb)}if(O.size===0)return;const Pe=[...O.keys()].map(Ae=>Ae.object3d),Ne=(_=this.pencil.pick(C,Pe,!0))==null?void 0:_.intersects;if(!Ne||Ne.length===0)t==="down"?this.handleDownOutside(C):t==="move"&&this.handleLeaveEvents(C);else{const Ae=Ne[0];this.processIntersection(Ae,C,t)}const Fe=this.prevActiveObjects;this.prevActiveObjects=this.activeObjects,this.activeObjects=Fe,this.activeObjects.clear()};this.domElement.addEventListener(`pointer${t}`,it(v),{passive:!1})}processIntersection(t,r,m){const v=this.objCallbackMap,C=t.index||-1;let _=t.object;for(;_;){const w=this.pencil.lead.objMap.get(_);w&&w.visible&&(this.activeObject||(this.activeObject=w),v.has(w)&&this.activeObjects.add(w)),_=_.parent}m==="move"?this.handleLeaveEvents(r):m==="down"&&this.handleDownOutside(r),this.processObjectHierarchy(r,m,C)}processObjectHierarchy(t,r,m){const v=this.objCallbackMap;let C=!1;const _=()=>{C=!0};for(const w of this.activeObjects){if(C)break;const I=v.get(w);if(I)if(r==="move"){const O=I.get("enter");if(O&&!this.prevActiveObjects.has(w))for(const Ne of O)Ne({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const Pe=I.get("move");if(Pe)for(const Ne of Pe)Ne({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m})}else{const O=I.get("down");if(O)for(const Ne of O)Ne({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const Pe=I.get("click");if(Pe){const Ne=Fe=>{Fe.preventDefault();const Ae=5;if(!C&&Math.abs(Fe.clientX-t.clientX)<=Ae&&Math.abs(Fe.clientY-t.clientY)<=Ae)for(const De of Pe)De({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});this.domElement.removeEventListener("pointerup",Ne)};this.domElement.addEventListener("pointerup",Ne)}}}}handleLeaveEvents(t){this.objCallbackMap.forEach((r,m)=>{const v=r.get("leave");if(v&&this.prevActiveObjects.has(m)&&!this.activeObjects.has(m))for(const C of v)C({baseObject:m,mouseEvent:t})})}handleDownOutside(t){this.objCallbackMap.forEach((r,m)=>{const v=r.get("downOutside");if(v&&!this.activeObjects.has(m))for(const C of v)C({baseObject:m,mouseEvent:t})})}handlePick(t,r,m){let v=r;v==="mousemove"?v="move":v==="mouseenter"?v="enter":v==="mouseleave"&&(v="leave"),this.pickFunctionsMapIndex+=1;const C=this.pickFunctionsMapIndex;return this.pickFunctionsMap.set(C,{objArr:t,type:v,cb:m}),this.pickListener.move||Array.from(this.pickFunctionsMap.values()).some(_=>["move","enter","leave"].includes(_.type))&&(this.pickListener.move=!0,this.addPickListener("move")),this.pickListener.down||Array.from(this.pickFunctionsMap.values()).some(_=>["down","downOutside","click"].includes(_.type))&&(this.pickListener.down=!0,this.addPickListener("down")),C}removePick(t){this.pickFunctionsMap.delete(t)}handlePickNode(t,r,m){if(r==="downOutside")return console.warn("handlePickNode:err:不支持 downOutside"),-1;this.pickNodeFunctionsMapIndex+=1;const v=this.pickNodeFunctionsMapIndex,C=t instanceof Function?t():t,_=[];for(const w of C){const I=w;I.element.style.pointerEvents="auto";const O=Ne=>{this.enabled&&(Ne.preventDefault(),m({baseObject:I,mouseEvent:Ne}))},Pe=`pointer${r}`;I.element.addEventListener(Pe,it(O),!1),_.push({arr:I,type:Pe,listener:O})}return this.pickNodeFunctionsMap.set(v,_),v}removePickNode(t){const r=this.pickNodeFunctionsMap.get(t);if(r){for(const m of r)m.arr.element.style.pointerEvents="none",m.arr.element.removeEventListener(m.type,m.listener,!1);this.pickNodeFunctionsMap.delete(t)}}dispose(){this.pickFunctionsMap.clear(),this.pickNodeFunctionsMap.clear(),this.activeObjects.clear(),this.prevActiveObjects.clear(),this.objCallbackMap.clear()}}class Js extends Qs{constructor(t,r){super(t),this.objMap=new Map,this.objects=new Map,this.objectsPm=new Map,this.objectWrapChindIdMap=new Map,this.objectNamesToFactories=new Map,this.mList=r.mList,this.scene=this.createBaseObject(r.scene||new Scene,{key:"@Scene",name:"场景",mList:!1}),this.group=this.createBaseObject(new Group$1,{key:"@Group",name:"物体组",target:this.scene,mList:!1}),this.prefabGroup=this.createBaseObject(new Group$1,{key:"@PrefabGroup",name:"预制组",target:this.scene,mList:!1})}get objectsPromise(){return this.objectsPm.values()}createBaseObject(t,r={}){const m=U({mList:!0},r),v=new ht;if(v.object3d=t,v.pencil=this.pencil,v.lead=this,v.mList=this.mList,m.key)v.key=m.key;else if(m.target){const C=m.target.key;if(C==="@Scene"&&t instanceof Camera$1)v.key="@Camera";else{const _=this.objectWrapChindIdMap.get(m.target)?this.objectWrapChindIdMap.get(m.target)+1:0;this.objectWrapChindIdMap.set(m.target,_),v.key=`${C}__c__${_}`}}return m.name&&(t.name=m.name),m.target&&m.target.object3d.add(v.object3d),this.objects.set(v.key,v),this.objMap.set(v.object3d,v),m.mList&&(this.mList.proxyBaseObject(v),this.mList.addBaseObjectMap(v)),t.children&&t.children.forEach(C=>{this.createBaseObject(C,{target:v,mList:m.mList})}),v}init(t){return Object.keys(t).forEach(r=>{const m=class{create(v={}){return new t[r](v)}};this.objectNamesToFactories.set(r,m)}),this}getObject(t,r){t.includes("#")&&console.warn("getObject:err:不支持 #",t);const{key:m}=r||{},v=`${t}${m?`#${m}`:""}`;return this.objects.get(v)}getAllObject(t,r){t.includes("#")&&console.warn("getAllObject:err:不支持 #",t);const{key:m}=r||{},v=`${t}${m?`#${m}`:""}`,C=[];return this.objects.forEach((_,w)=>{(w.startsWith(m?v:`${v}#`)||w===v)&&C.push(_)}),C}draw(t,r,m){return se(this,null,function*(){var v,C,_,w;const I=this.objectNamesToFactories.get(t);if(I){r||(r={}),r.target===void 0&&(r.target=m);const O=r.target,Pe=(v=r.onTop)!=null?v:0,Ne=(C=r.prefab)!=null?C:!1,Fe=(_=r.create)!=null?_:!0,Ae=new I().create(r);let De;return O===null?De=null:typeof O=="string"?De=this.objects.get(O):(w=O==null?void 0:O.objectType)!=null&&w.startsWith("BaseObject")||O?De=O:Ne?De=this.prefabGroup:De=this.group,Fe===!1?Ae.create=()=>{}:Fe!==!0&&(Ae.create=()=>{Fe(Ae)}),Ae.pencil=this.pencil,Ae.lead=this,Ae.mList=this.mList,Ae.prefab=Ne,Ae.objectType=`BaseObject#${t}`,Ae.objectOptions=r,this.setBaseObjectKey(Ae,r.key?`$t:#${r.key}`:"$t:",De==null?void 0:De.key),this.objectsPm.set(Ae,this.addBaseObject(Ae,De,Pe)),yield this.objectsPm.get(Ae),this.objectsPm.delete(Ae),Ae}throw new Error(`Unrecognized:${t}`)})}setBaseObjectKey(t,r,m){const v=t.objectType,[,C]=v.split("#");let _=r.replace("$t:",C);if(m){const[,w]=m.split("#");_=_.replace("$p:",w)}return this.objects.has(_)&&(_.includes("#")?_+=`-${esusLite.generateUUID()}`:_+=`#${esusLite.generateUUID()}`),t.key=_,this.objects.set(_,t),_}updateBaseObjectKey(t,r){var m;let v;for(const[w,I]of this.objects.entries())if(I===t){v=w;break}const C=(m=t.parent)==null?void 0:m.key,_=this.setBaseObjectKey(t,r,C);return v&&this.objects.delete(v),this.pencil.event.emit("lead.updateKey",{baseObject:t,key:_,oldKey:v}),t.children.forEach((w,I)=>{w.key.includes("__c__")&&this.updateBaseObjectKey(w,`${_}__c__${I}`)}),_}addBaseObject(t,r,m){return se(this,null,function*(){if(yield t.create(),t.object3d){const v=t.object3d;v.material&&Array.isArray(v.material)&&(v.material=v.material.slice()),this.mList.proxyBaseObject(t),this.mList.addBaseObjectMap(t),m&&t.setTop(m),r!==null&&r.object3d.add(t.object3d),this.objMap.set(t.object3d,t),v.children.forEach(C=>{this.objMap.get(C)||this.createBaseObject(C,{target:t})})}t.render(),this.pencil.event.emit("lead.draw",{baseObject:t})})}erase(...t){this.handleErase(!0,...t)}eraseWithoutMaterial(...t){this.handleErase(!1,...t)}handleErase(t,...r){[...r].forEach(m=>{const v=[];if(typeof m=="string"){const[C,_]=m.split("#");v.push(...this.getAllObject(C,{key:_}))}else v.push(m);v.forEach(C=>{C.disposeMaterialIfNotUsed=t,C.dispose()})}),this.pencil.event.emit("lead.erase")}update(t,r){this.objects.forEach(m=>{m.update(t,r)})}setSize(t,r){this.objects.forEach(m=>{m.resize(t,r)})}eraseAll(){this.group&&(this.objects.forEach(t=>{t.key.startsWith("Node")&&this.erase(t)}),this.erase(this.group))}dispose(){super.dispose(),this.scene.erase(),this.objects.forEach(t=>{t.erase()}),this.objects.clear(),this.objectsPm.clear(),this.objMap.clear(),this.objectWrapChindIdMap.clear(),this.objectNamesToFactories.clear()}}class ei extends ee{get lead(){return this.controller}constructor(t){super(),this.options=t}addLead(t,r,m){const{pencil:v}=this.options,C=new Js(v,{scene:t,mList:r});return this.addController(C,m)}removePage(t){super.removePage(t,r=>{r.dispose()})}setPageActive(t){super.setPageActive(t,(r,m)=>{r.enabled=m})}setSize(t,r){this.controllerMap.forEach((m,v)=>{v.setSize(t,r)})}}class rt extends Loader{constructor(t){super(t),this.options={type:"image"}}setOptions(t){return this.options=t,this}load(t,r,m,v){let C,_;this.options.type==="image"?(_=document.createElement("img"),C=new Texture(_)):this.options.type==="video"?(_=document.createElement("video"),_.preload="auto",_.autoplay=!1,_.loop=!1,_.muted=!0,_.setAttribute("webkit-playsinline","webkit-playsinline"),_.setAttribute("playsinline",""),C=new VideoTexture(_)):C=new Texture;const w=new FileLoader(this.manager);return w.setResponseType("blob"),w.setRequestHeader(this.requestHeader),w.setPath(this.path),w.setWithCredentials(this.withCredentials),w.load(t,I=>{let O=I;const Pe=t.split(".").pop(),Ne=this.options.type==="image"?`image/${Pe||"png"}`:`video/${Pe||"mp4"}`;O=O.slice(0,I.size,Ne);const Fe=()=>{_.removeEventListener("load",Ae,!1),_.removeEventListener("error",De,!1)},Ae=()=>{Fe(),C.needsUpdate=!0,r&&r(C)},De=je=>{Fe(),v&&v(je),this.manager.itemError(t),this.manager.itemEnd(t)};_.addEventListener("load",Ae,!1),_.addEventListener("error",De,!1);const xt=window.URL.createObjectURL(O);_.src=xt},m,v),C}}class ti extends Loader{constructor(t){super(t)}load(t,r,m,v){const C=new FileLoader(this.manager);C.setResponseType("blob"),C.setRequestHeader(this.requestHeader),C.setPath(this.path),C.setWithCredentials(this.withCredentials),C.load(t,_=>{const w=_,I=new DecompressionStream("gzip"),O=w.stream().pipeThrough(I);new Response(O).json().then(Pe=>{r==null||r(Pe)}).catch(Pe=>{v==null||v(Pe)})},m,v)}}const si={images:["png","jpg","jpeg","ico","webp","avif"],media:["mp4","webm","ogg"],gltf:["gltf","glb"],json:["json","geojson"],gzipJson:["json.gzip"],exr:["exr"],lottie:["lottie.json"]};class ii{constructor(t){this.loadObj=[],this.delLoadArr=[],this.assets=new Map,this.event=new ye.EventEmitter,this.options=U({simpleTexture4deleted:!1,prefix:""},t),this.loadingManager=new LoadingManager(()=>{},(r,m,v)=>{this.emit("progress",m,v)},r=>{console.warn(`Failed to load ${r}`)})}emit(t,...r){this.event.emit(t,...r)}on(t,r){this.event.on(t,r)}getAsset(t){const r=this.getAssetType(t);if(!r)return;const m=this.assets.get(t);if(!m){if((r==="images"||r==="media"||r==="exr")&&this.options.simpleTexture4deleted&&this.delLoadArr.includes(t))return new Texture;console.warn(`Asset ${t} not found`)}return m}getAssetType(t){var r;const m=(r=t.split(".").pop())==null?void 0:r.toLowerCase();if(m){if(t.endsWith("lottie.json"))return"lottie";if(t.endsWith("json.gzip"))return"gzipJson"}else return;for(const[v,C]of Object.entries(si))if(C.includes(m))return v}getLoader(t,r){if(t==="images")return this.textureLoader||(this.textureLoader=new rt(this.loadingManager),this.options.prefix&&this.textureLoader.setPath(this.options.prefix)),this.textureLoader;if(t==="media")return this.videoTextureLoader||(this.videoTextureLoader=new rt(this.loadingManager),this.videoTextureLoader.setOptions({type:"video"}),this.options.prefix&&this.videoTextureLoader.setPath(this.options.prefix)),this.videoTextureLoader;if(t==="gltf"&&r!=null&&r.dracoPath)return this.dracoGltfLoader||(this.dracoGltfLoader=new GLTFLoader(this.loadingManager),this.dracoLoader=new DRACOLoader,this.dracoLoader.setDecoderPath(r==null?void 0:r.dracoPath),this.dracoGltfLoader.setDRACOLoader(this.dracoLoader),this.options.prefix&&this.dracoGltfLoader.setPath(this.options.prefix)),this.dracoGltfLoader;if(t==="gltf")return this.gltfLoader||(this.gltfLoader=new GLTFLoader(this.loadingManager),this.options.prefix&&this.gltfLoader.setPath(this.options.prefix)),this.gltfLoader;if(t==="lottie")return this.lottieLoader||(this.lottieLoader=new LottieLoader(this.loadingManager),this.options.prefix&&this.lottieLoader.setPath(this.options.prefix)),this.lottieLoader;if(t==="gzipJson")return this.gzipJsonLoader||(this.gzipJsonLoader=new ti(this.loadingManager),this.options.prefix&&this.gzipJsonLoader.setPath(this.options.prefix)),this.gzipJsonLoader;if(t==="json")return this.jsonLoader||(this.jsonLoader=new FileLoader(this.loadingManager),this.jsonLoader.setResponseType("json"),this.options.prefix&&this.jsonLoader.setPath(this.options.prefix)),this.jsonLoader;if(t==="exr")return this.exrLoader||(this.exrLoader=new EXRLoader(this.loadingManager),this.options.prefix&&this.exrLoader.setPath(this.options.prefix)),this.exrLoader}add(t,r){typeof t=="string"&&(t=[t]),t.forEach(m=>{const v=U({src:m},r);this.loadObj.push(v)})}getSrcByAsset(t,r=this.assets){let m;return r.forEach((v,C)=>{v===t&&(m=C)}),m}get textureAssets(){const t=new Map;return this.assets.forEach((r,m)=>{(r instanceof Texture||r instanceof DataTexture||r instanceof VideoTexture)&&t.set(m,r)}),t}loadAll(){return se(this,null,function*(){const t=this.loadObj.filter(r=>!this.delLoadArr.includes(r.src));return yield Promise.all(t.map(r=>this.load(r.src,r)))})}load(t,r){return se(this,null,function*(){var m,v;const C=(m=r==null?void 0:r.type)!=null?m:this.getAssetType(t);if(!C)return;const _=(r==null?void 0:r.cache)!==!1,w=esusLite.makePromiseCreator();if(_){if(this.assets.has(t))return this.assets.get(t);this.assets.set(t,w.promise)}const I=this.getLoader(C,r);try{const O=yield I.loadAsync(t);if(this.assets.set(t,O),w.resolve(O),C==="images"||C==="media"||C==="exr"||C==="lottie"){(r==null?void 0:r.colorCorrection)!==!1&&l({texture:O});const Pe=(v=r==null?void 0:r.anisotropy)!=null?v:this.options.anisotropy;O.anisotropy=Pe}return O}catch(O){w.reject(`Failed to load ${t}`);return}})}getUnusedAssets(){const{scene:t}=this.options;if(!t)return[...this.delLoadArr];const r=new Set,m=this.textureAssets;t.traverse(C=>{const _=C;_.material&&(Array.isArray(_.material)?_.material:[_.material]).forEach(w=>{[w.map,w.emissiveMap,w.normalMap,w.roughnessMap,w.metalnessMap,w.aoMap].forEach(I=>{if(I){const O=this.getSrcByAsset(I,m);O&&r.add(O)}})})});const v=new Set(this.textureAssets.keys());return r.forEach(C=>{v.delete(C)}),[...v,...this.delLoadArr]}dispose(){var t;this.assets.clear(),(t=this.dracoLoader)==null||t.dispose(),this.event.removeAllListeners(),this.delLoadArr.length=0,this.loadObj.length=0}}const ri={prefix:""};class oi extends ee{get loader(){return this.controller}constructor(t){super(),this.options=t}addLoader(t,r){const{loaderParams:m}=this.options,v=new ii(te(U({},m),{scene:t}));return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}class ni{constructor(t){this.materials=new Map,this.fixBaseObjects=new Map,this.materialBaseObjectMap=new Map,this.pencil=t}add(t,r){this.materials.set(t,r);const m={object3d:new Proxy({material:r},{set:(v,C,_)=>{var w;if(C==="material"&&!((w=this.pencil.composerController)!=null&&w.bloomComposerRenderIng)){const I=v.material;return v.material=_,this.materials.set(t,_),this.disposeMaterial(I),this.syncChangeMaterial(I,_),!0}return v[C]=_,!0}})};this.fixBaseObjects.set(t,m),this.pencil.event.emit("mList.add",{key:t,material:r,baseObject:m})}get(t){const r=this.materials.get(t);return r||console.warn(`Material with key "${t}" not found.`),r}getByName(t){for(const[r,m]of this.materials.entries())if(m.name===t)return m;console.warn(`Material with name "${t}" not found.`)}getKey(t){for(const[r,m]of this.materials.entries())if(m===t)return r}getKeyByName(t){for(const[r,m]of this.materials.entries())if(m.name===t)return r;console.warn(`Material key with name "${t}" not found.`)}addMultiple(t,r){for(const[m,v]of Object.entries(r)){const C=`${t}#${m}`;v&&this.add(C,v)}}getMultiple(t){const r={},m=`${t}#`;let v=!1;for(const[C,_]of this.materials.entries())if(C.startsWith(m)){const w=C.substring(m.length);r[w]=_,v=!0}return v?r:null}copy(t,r,m={}){const v=this.get(t);if(!v)return console.warn(`Material with key "${t}" not found.`),null;const C=v.clone();return m.name&&(C.name=m.name),this.add(r,C),C}copyMultiple(t,r){const m={},v=`${t}#`;for(const[C,_]of this.materials.entries())if(C.startsWith(v)){const w=C.substring(v.length),I=_.clone();m[w]=I;const O=`${r}#${w}`;this.add(O,I)}return m}disposeMaterial(t){if(!t)return;const r=new se$1;r.track(Array.isArray(t)?t:[t]),r.dispose()}remove(t){const r=this.materials.get(t);r&&this.disposeMaterial(r),this.materials.delete(t),this.fixBaseObjects.delete(t),this.pencil.event.emit("mList.remove",{key:t,material:r})}removeByMaterial(t){[...this.materials.entries()].some(([r,m])=>m===t?(this.remove(r),!0):!1)}proxyBaseObject(t){const r=t.object3d;if(!r.material)return;const m=_=>{if(_.hasOwnProperty("__isProxy"))return _;const w=new Proxy(_,{set:(I,O,Pe)=>{if(typeof O=="string"&&!isNaN(Number(O))){const Ne=Number(O);if(Ne>=0&&Ne<I.length){const Fe=I[Ne];return this.rmBaseObjectMap(t,Fe),I[Ne]=Pe,Pe&&this.addBaseObjectMap(t),!0}}return I[O]=Pe,!0}});return Object.defineProperty(w,"__isProxy",{value:!0,enumerable:!1}),w};t.materialList&&(t.materialList=new Proxy(t.materialList,{set:(_,w,I)=>{if(typeof w=="string"){const O=_[w];return this.rmBaseObjectMap(t,O),_[w]=I,I&&this.addBaseObjectMap(t),!0}return _[w]=I,!0},get:(_,w)=>{if(typeof w=="string"&&_[w]){const I=_[w];if(Array.isArray(I)){const O=m(I);return O!==I&&(_[w]=O),O}return I}return _[w]},deleteProperty:(_,w)=>{if(typeof w=="string"&&_[w]){const I=_[w];this.rmBaseObjectMap(t,I)}return delete _[w],!0}}));const v=r.material,C="_enhancedMaterial";r[C]=v,Object.defineProperty(r,"material",{get:()=>{var _;const w=r[C];if(!((_=this.pencil.composerController)!=null&&_.bloomComposerRenderIng)&&Array.isArray(w)){const I=m(w);return I!==w&&(r[C]=I),I}return w},set:_=>{var w;if((w=this.pencil.composerController)!=null&&w.bloomComposerRenderIng)r[C]=_;else{if(t.materialList&&Object.values(t.materialList).includes(_)){r[C]=_;return}this.rmBaseObjectMap(t),r[C]=_,this.addBaseObjectMap(t)}},enumerable:!0,configurable:!0})}material2array(t){return Array.isArray(t)?t:[t]}addBaseObjectMap(t){const r=t.object3d;r.material&&([...Object.values(t.materialList),r.material].forEach(m=>{m&&this.material2array(m).forEach(v=>{const C=this.materialBaseObjectMap.get(v);C?C.add(t):this.materialBaseObjectMap.set(v,new Set([t]))})}),this.pencil.event.emit("mList.addBaseObjectMap"))}rmBaseObjectMap(t,r,m=!0){const v=r&&this.material2array(r);this.materialBaseObjectMap.forEach((C,_)=>{v&&!v.includes(_)||C.has(t)&&(C.delete(t),C.size===0&&m&&(this.materialBaseObjectMap.delete(_),this.disposeMaterial(_)))}),this.pencil.event.emit("mList.rmBaseObjectMap")}getBaseObjectMap(t){return this.materialBaseObjectMap.get(t)||new Set}syncChangeMaterial(t,r){const m=this.materialBaseObjectMap.get(t);m&&m.forEach(v=>{const C=v.object3d,_=C.material;if(Array.isArray(_)){const w=_.indexOf(t);w!==-1&&(_[w]=r)}else _===t&&(C.material=r);v.materialList&&Object.keys(v.materialList).forEach(w=>{const I=v.materialList[w];if(Array.isArray(I)){const O=I.indexOf(t);O!==-1&&(I[O]=r)}else I===t&&(v.materialList[w]=r)})})}dispose(){const t=new se$1;t.track([...this.materials.values()]),t.dispose(),this.materials.clear(),this.fixBaseObjects.clear(),this.materialBaseObjectMap.clear()}}class ai extends ee{get mList(){return this.controller}constructor(t){super(),this.options=t}addMList(t,r){const{pencil:m}=this.options,v=new ni(m);return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}const li={antialias:!1,devicePixelRatio:window.devicePixelRatio,powerPreference:"high-performance",toneMappingExposure:1,alpha:!1,outputColorSpace:e.sRGB,logarithmicDepthBuffer:!1,preserveDrawingBuffer:!1,stencil:!1,depth:!1};class hi{constructor(t){this.options=t;const{width:r,height:m,rendererParams:v}=t,{alpha:C,devicePixelRatio:_,antialias:w,powerPreference:I,toneMappingExposure:O,outputColorSpace:Pe,logarithmicDepthBuffer:Ne,preserveDrawingBuffer:Fe,stencil:Ae,depth:De}=v,xt=new WebGLRenderer({alpha:C,antialias:w,powerPreference:I,logarithmicDepthBuffer:Ne,preserveDrawingBuffer:Fe,stencil:Ae,depth:De});xt.setSize(r,m),xt.setPixelRatio(_),xt.toneMappingExposure=O,xt.outputColorSpace=Pe,this.renderer=xt}setSize(t,r){this.renderer.setSize(t,r)}setPixelRatio(t){this.renderer.setPixelRatio(t)}render(t,r){this.renderer.render(t,r)}setViewport(t){var r,m;const{x:v,y:C,width:_,height:w}=t,I=(r=t.scissor)!=null?r:!1,O=(m=t.scissorTest)!=null?m:!1;this.renderer.setViewport(v,C,_,w),I&&(this.renderer.setScissor(v,C,_,w),this.renderer.setScissorTest(O))}dispose(){var t,r;this.setSize(1,1),(t=this.renderer)==null||t.clear(),(r=this.renderer)==null||r.dispose()}}const ci={background:null};class di extends ee{get scene(){return this.controller}constructor(t){super(),this.options=t}addScene(t,r){const m=new Scene;return t!=null&&t.background&&(m.background=t.background),this.addController(m,r)}removePage(t){super.removePage(t,r=>{const m=new se$1;m.track(r),m.dispose()})}setPageActive(t){super.setPageActive(t,(r,m)=>{r.visible=m})}}class mi{constructor(t){this.event=new ye.EventEmitter;const{renderer:r,scene:m,camera:v}=t,C=new TransformControls(v,r.domElement);if(C.getHelper){const _=C.getHelper();m.add(_),+REVISION<170}else C instanceof Object3D&&m.add(C);this.controls=C,this.addEvent()}get detach(){return this.controls.detach.bind(this.controls)}get attach(){return this.controls.attach.bind(this.controls)}addEvent(){let t=null,r=null,m=null;const v=this.controls;v.addEventListener("change",()=>{const C=v.object;C!==void 0&&this.event.emit("change",C)}),v.addEventListener("mouseDown",()=>{const C=v.object;t=C.position.clone(),r=C.rotation.clone(),m=C.scale.clone(),this.event.emit("mouseDown",C)}),v.addEventListener("mouseUp",()=>{const C=v.object;if(C!==void 0)switch(v.getMode()){case"translate":t.equals(C.position)||this.event.emit("translate",C,C.position,t);break;case"rotate":r.equals(C.rotation)||this.event.emit("rotate",C,C.rotation,r);break;case"scale":m.equals(C.scale)||this.event.emit("scale",C,C.scale,m);break}this.event.emit("mouseUp")})}dispose(){var t;this.event.removeAllListeners(),(t=this.controls)==null||t.dispose()}}const pi={antialias:!0,devicePixelRatio:window.devicePixelRatio};class fi{constructor(t){this.options=t;const{width:r,height:m,rendererParams:v,renderer:C}=t,{devicePixelRatio:_,antialias:w}=v,I=new C({antialias:w});I.setSize(r,m),I.setPixelRatio(_),this.renderer=I}setSize(t,r){this.renderer.setSize(t,r)}render(t,r){this.renderer.render(t,r)}dispose(){var t,r;this.setSize(1,1),(t=this.renderer)==null||t.clear(),(r=this.renderer)==null||r.dispose()}}const _e=class Nn{constructor(t){var r,m;this.raycaster=new Raycaster,this.maxBackufferArea=5760*5760,this.installPlugins=new Map,this._cameraPositon=new Vector3,this._cameraTarget=new Vector3,this.event=new ye.EventEmitter,this.timer=new Timer,this.userData={},this.pageActiveIndex=0,this.pageCountIndex=0,this.userSetDprCache=1,this.viewPadding=[0,0,0,0],this.event.setMaxListeners(1/0),(m=(r=this.timer).connect)==null||m.call(r,document),this.options=Ut(Nn.options,t,{isMergeableObject:f$1}),this.userSetDprCache=this.options.renderer.devicePixelRatio;const{container:v,stats:C,transformControls:_}=this.options;if(this.init(),this.options.WebGPUTHREE||this.initComposer(),this.initCSSRenderer(),_&&this.initTransformControls(),C){const w=new Stats({horizontal:!1});w.dom.style.position="absolute",w.init(this.renderer),v.appendChild(w.dom),this.stats=w}this.initResizeObserver(),this.tweenUpdateRaf()}getPlugin(t){return this.installPlugins.get(t)}get renderer(){return this.rendererController.renderer}get maxAnisotropy(){return this.options.WebGPUTHREE?0:this.renderer.capabilities.getMaxAnisotropy()}get controls(){return this.controlsController.cameraControls}get cameraPositon(){return this.controls.getPosition(this._cameraPositon,!1)}get cameraTarget(){return this.controls.getTarget(this._cameraTarget,!1)}get camera(){return this.cameraController.camera}get scene(){return this.sceneController.scene}get loader(){return this.loaderController.loader}get lead(){return this.leadController.lead}get mList(){return this.mListController.mList}tweenUpdateRaf(){update(),this.TweenRaf=requestAnimationFrame(this.tweenUpdateRaf.bind(this))}use(t,...r){this.installPlugins.has(t.pluginName)?console.log("plugin already installed"):typeof t.install=="function"&&(t.install(this,...r),this.installPlugins.set(t.pluginName,t))}addPage({sceneOptions:t,cameraOptions:r}={}){const m=this.pageCountIndex+1,v=this.cameraController.addPerspectiveCamera(r,m),C=this.sceneController.addScene(t,m);C.add(v),this.controlsController.addCameraControls(v,m),this.loaderController.addLoader(C,m);const _=this.mListController.addMList(null,m);return this.leadController.addLead(C,_,m),this.pageCountIndex=m,m}removePage(t){this.cameraController.removePage(t),this.sceneController.removePage(t),this.controlsController.removePage(t),this.loaderController.removePage(t),this.mListController.removePage(t),this.leadController.removePage(t),this.pageCountIndex===t&&(this.pageCountIndex-=1),this.pageActiveIndex===t&&(this.render(),this.showPage(0))}showPage(t){var r;if(t===this.pageActiveIndex)return;const m=this.scene;this.sceneController.setPageActive(t),m&&((r=this.cssRendererController)==null||r.render(m,this.camera)),this.cameraController.setPageActive(t),this.controlsController.setPageActive(t),this.loaderController.setPageActive(t),this.mListController.setPageActive(t),this.leadController.setPageActive(t),this.pageActiveIndex=t}init(){var t;const{container:r,WebGPUTHREE:m,helper:v,viewHelper:C,renderer:_,controls:w,loader:I}=this.options,{width:O,height:Pe}=this.getSize(),Ne=m?new fi({width:O,height:Pe,renderer:m.WebGPURenderer,rendererParams:pi}):new hi({width:O,height:Pe,rendererParams:te(U({},_),{antialias:!1})}),Fe=new Ms({width:O,height:Pe}),Ae=new di({}),De=new Zs({controlsParams:{domElement:(t=w==null?void 0:w.domElement)!=null?t:Ne.renderer.domElement}}),xt=new oi({loaderParams:U({anisotropy:Ne.renderer.capabilities.getMaxAnisotropy()},I)}),je=new ai({pencil:this}),ke=new ei({pencil:this});this.sceneController=Ae,this.cameraController=Fe,this.controlsController=De,this.rendererController=Ne,this.loaderController=xt,this.mListController=je,this.leadController=ke;const at=this.addPage({sceneOptions:this.options.scene,cameraOptions:this.options.camera});if(this.showPage(at),v){const ct=new qs({container:r,sceneController:Ae,cameraController:Fe});ct.add(Ae.scene),this.helperController=ct,C&&ct.addViewHelper()}r.appendChild(Ne.renderer.domElement)}initComposer(){const{bloom:t,bloomParams:r,ssao:m,ssaoParams:v,composer:C}=this.options,_=new Ys({rendererController:this.rendererController,sceneController:this.sceneController,cameraController:this.cameraController,composerParams:C});this.composerController=_,t&&_.addBloomPass(U({},r)),m&&_.addSSAOPass(U({},v)),_.addOutputPass()}initCSSRenderer(){const{container:t,css2DRenderer:r,css3DRenderer:m,css2DRendererParams:v,css3DRendererParams:C}=this.options;if(r||m){const _=new Xs(t);r&&_.addRenderer("css2d",v),m&&_.addRenderer("css3d",C),this.cssRendererController=_}}initTransformControls(){const t=new mi({camera:this.camera,renderer:this.renderer,scene:this.scene});t.event.on("mouseDown",()=>{var r;(r=this.controlsController)==null||r.disable()}),t.event.on("mouseUp",()=>{var r;(r=this.controlsController)==null||r.enable()}),this.transformController=t}getSize(){const{container:t}=this.options;return{width:t.offsetWidth,height:t.offsetHeight}}initResizeObserver(){const{container:t}=this.options;if(this.resizeObserver)return;const r=new ResizeObserver(m=>{for(const v of m){const C=v.contentRect;this.handeleResize(C.width,C.height),this.setDevicePixelRatio(this.userSetDprCache)}});r.observe(t),this.resizeObserver=r}handeleResize(t,r,m=!0){const{rendererController:v,cameraController:C,composerController:_,cssRendererController:w,leadController:I}=this,O=this.renderer.getSize(new Vector2);O.x===t&&O.y===r||(C.setSize(t,r),v.setSize(t,r),_==null||_.setSize(t,r),w==null||w.setSize(t,r),I.setSize(t,r),this.installPlugins.forEach(Pe=>{var Ne;(Ne=Pe.setSize)==null||Ne.call(Pe,t,r)}),this.viewPadding.some(Pe=>Pe!==0)&&this.setViewPadding(...this.viewPadding),this.render(),m&&this.event.emit("resize",{width:t,height:r}))}setDevicePixelRatio(t){var r;this.userSetDprCache=t;const{width:m,height:v}=this.getSize();let C=Math.sqrt(this.maxBackufferArea/(m*v));C=(C*100|0)/100;const _=Math.min(t,C);_!==t&&console.warn("maxBackufferArea:",this.maxBackufferArea," the pixel ratio is set to",_);const w=this.renderer.getPixelRatio();_!==w&&(this.rendererController.setPixelRatio(_),(r=this.composerController)==null||r.setPixelRatio(_),this.viewPadding.some(I=>I!==0)&&this.setViewPadding(...this.viewPadding))}setViewPadding(t=0,r=0,m=0,v=0){const{width:C,height:_}=this.renderer.getSize(new Vector2),w={x:v,y:m,width:C-v-r,height:_-t-m};this.rendererController.setViewport(w),this.cameraController.setAspect(w.width/w.height),this.viewPadding=[t,r,m,v]}pick(t,r,m=!0){const{raycaster:v,options:C}=this,{container:_}=C,w=new Vector2,I=_.getBoundingClientRect();if(w.x=(t.clientX-I.left)/(I.right-I.left)*2-1,w.y=-((t.clientY-I.top)/(I.bottom-I.top))*2+1,this.camera&&this.scene){v.setFromCamera(w,this.camera);const O=v.intersectObjects(r||this.scene.children,m);if(O.length)return{object:O[0].object,index:O[0].index,intersects:O}}}render(){var t,r,m,v,C,_;if(!this.camera||!this.scene)return;this.event.emit("beforeRender"),this.timer.update(),update();const w=this.timer.getDelta(),I=this.timer.getElapsed();this.controlsController.update(w,I),this.leadController.update(w,I),this.installPlugins.forEach(O=>{var Pe;(Pe=O.update)==null||Pe.call(O,w,I)}),(t=this.helperController)==null||t.update(w,this.controlsController,this.cameraTarget),(r=this.composerController)!=null&&r.active?this.composerController.render():(m=this.rendererController)==null||m.render(this.scene,this.camera),(v=this.helperController)==null||v.renderViewHelper(this.renderer),(C=this.cssRendererController)==null||C.render(this.scene,this.camera),(_=this.stats)==null||_.update(),this.event.emit("render",{delta:w,elapsed:I})}start(){var t;window.cancelAnimationFrame(this.TweenRaf),(t=this.renderer)==null||t.setAnimationLoop(this.render.bind(this)),this.event.emit("start")}stop(){var t;this.tweenUpdateRaf(),(t=this.renderer)==null||t.setAnimationLoop(null),this.event.emit("stop")}autoRotate(t){this.controlsController.autoRotateSpeed=t}showPipViewport(t){this.composerController.pipViewportState=t;let r=this.pipCameraControls;if(t){const{width:m,height:v}=this.getSize(),C=new DOMRect(t.x/m,(v-t.y-t.height)/v,t.width/m,t.height/v);if(r)r.enabled=!0,r.camera.position.copy(this.camera.position);else{const _=this.cameraController.cloneCamera(31);_.aspect=t.width/t.height,_.updateProjectionMatrix(),r=this.controlsController.addCameraControls(_,this.sceneController.activeIndex),r.addEventListener("update",()=>{this.controls.enabled=!1}),r.addEventListener("sleep",()=>{this.controls.enabled=!0}),this.pipCameraControls=r}r.interactiveArea=C}}dispose(){var t,r,m,v,C,_,w,I,O,Pe,Ne,Fe,Ae,De;this.stop(),this.timer.dispose(),removeAll(),this.event.removeAllListeners(),(t=this.resizeObserver)==null||t.unobserve(this.options.container),this.installPlugins.forEach(xt=>{var je;(je=xt.dispose)==null||je.call(xt)}),(r=this.controlsController)==null||r.dispose(),(m=this.transformController)==null||m.dispose(),(v=this.cssRendererController)==null||v.dispose(),(C=this.sceneController)==null||C.dispose(),(_=this.cameraController)==null||_.dispose(),(w=this.helperController)==null||w.dispose(),(I=this.composerController)==null||I.dispose(),(O=this.rendererController)==null||O.dispose(),(Pe=this.loaderController)==null||Pe.dispose(),(Ne=this.leadController)==null||Ne.dispose(),(Fe=this.mListController)==null||Fe.dispose(),this.cssRendererController=void 0,this.installPlugins.clear(),(Ae=this.stats)==null||Ae.dom.remove(),(De=this.renderer)==null||De.domElement.remove()}};_e.options={stats:Le$1,helper:Le$1,viewHelper:Le$1,controls:!0,transformControls:Le$1,renderer:li,composer:Vs,scene:ci,camera:wt,bloom:!1,bloomParams:Bs,ssao:!1,loader:ri,ssaoParams:Hs,css2DRenderer:!1,css2DRendererParams:U({},st),css3DRenderer:!1,css3DRendererParams:U({},st)};let ot=_e;const Gi=J$1.ACTION;class Point extends ht{constructor(r){super();C0(this,"options");C0(this,"scaleValue",1);this.options=q0({sprite:!0},r)}get material(){var r;return(r=this.object3d)==null?void 0:r.material}getMaterial(){const{sprite:r}=this.options,m=document.createElement("canvas");m.width=100,m.height=100;const v=m.getContext("2d");v.beginPath(),v.arc(50,50,50,0,2*Math.PI),v.fillStyle="#ffffff",v.fill(),v.closePath();const C=new CanvasTexture(m);return r?new SpriteMaterial({transparent:!0,map:C}):new MeshBasicMaterial({color:16777215,transparent:!0,map:C})}create(){return U0(this,null,function*(){const{sprite:r}=this.options,m=this.getMaterial();r?this.createSprite(m):this.createMesh(new PlaneGeometry(1,1),m),this.setScale(1),this.object3d.scale.multiplyScalar(.1)})}setScale(r){this.scaleValue=r;const m=this.material.map;m!=null&&m.image?this.object3d.scale.set(m.image.width*r,m.image.height*r,1):this.object3d.scale.set(r,r,1)}}const p={mercator:i$3,equirectangular:s$1,winkel3:l$1},a$1={},f=g=>{var t,r,m;const v=JSON.stringify(g);if(a$1[v])return a$1[v];const C=p[(t=g.projectionType)!=null?t:"mercator"]().center(g.center).scale(g.scale).translate((r=g.translate)!=null?r:[0,0]).precision((m=g.precision)!=null?m:.1);return g.rotate&&C.rotate(g.rotate),a$1[v]=C,C},getLineTexture=(g,t="rgba(255,255,255,1)",r="rgba(0,0,0,0)")=>{const m=document.createElement("canvas");m.width=256,m.height=1;const v=m.getContext("2d"),C=v.createLinearGradient(0,0,256,1);C.addColorStop(0,t),C.addColorStop(g,t),C.addColorStop(g,r),C.addColorStop(1,r),v.fillStyle=C,v.fillRect(0,0,256,1);const _=new CanvasTexture(m);return _.wrapS=RepeatWrapping,_.wrapT=RepeatWrapping,_.needsUpdate=!0,_},createFlyPath=(g,t,r=40)=>{const m=g.angleTo(t);let v=g.clone().add(t);v=v.normalize().multiplyScalar(r);let C;m<=1?C=r/5*m:m>1&&m<2?C=r/5*mn(m,2):C=r/5*mn(m,1.5);const _=g.clone().add(v).normalize().multiplyScalar(r+C),w=t.clone().add(v).normalize().multiplyScalar(r+C);return new CubicBezierCurve3(g,_,w,t)},createFlyPath2=(g,t,r=40)=>{const m=new Vector3().lerpVectors(g,t,.25),v=new Vector3().lerpVectors(g,t,.75);return m.z+=r,v.z+=r,new CubicBezierCurve3(g,m,v,t)},pixel2unit=(g,t)=>{const m=g.camera.fov*Math.PI/180,v=g.controls.getPosition(new Vector3,!1),C=2*Math.tan(m/2)*v.z,_=g.getSize(),w=_.width/_.width,I=C*w;return t*g.renderer.getPixelRatio()/_.width/(1/I)};let map;class Arc extends ht{constructor(r){super();C0(this,"options");C0(this,"line");C0(this,"helperMesh");C0(this,"helperMeshPosition");C0(this,"pickTube",null);this.options=q0({color:"#ffffff",lineWidth:6,globe:!1,offsetLoop:!0},r),this.options.repeat&&this.options.repeat[0]===.5&&(this.options.offsetLoop=!1)}static getInitOptions(r,m){const v=pixel2unit(r,200),C=m.globe?new Vector3(0,0,0).add(new Vector3(-v/2,v/2,0)):new Vector3(0,0,0).sub(new Vector3(v/2,v/2,v/2)),_=m.globe?new Vector3(0,0,0).add(new Vector3(v/2,v/2,0)):new Vector3(0,0,0).add(new Vector3(v/2,v/2,v/2));return{from:C.toArray(),to:_.toArray()}}create(){return U0(this,null,function*(){map||(map=getLineTexture(.5));const{color:r,lineWidth:m,globe:v}=this.options;let{radius:C}=this.options;const _=h(this.options.from||[0,0,0]),w=h(this.options.to||[0,0,0]);C=C!=null?C:_.distanceTo(w);const I=v?createFlyPath(_,w,C):createFlyPath2(_,w,C),O=I.getPoints(1500),Pe=this.pencil.lead,Ne=yield Pe.draw("Line",{nodes:O,setPointWidth:je=>je*1,materialParameters:{color:r,map,useMap:1,transparent:!0,sizeAttenuation:0,lineWidth:m}},null);this.line=Ne,this.object3d=Ne.object3d;const[Fe,Ae,De,xt]=yield Promise.all([{key:"Arc_起点",position:I.v0},{key:"Arc_第一控制点",position:I.v1},{key:"Arc_第二控制点",position:I.v2},{key:"Arc_终点",position:I.v3}].map(at=>U0(this,[at],function*({key:je,position:ke}){const ct=yield Pe.draw("Group",{},this);return ct.position.copy(ke),ct.userData.disabledC=!0,ct.userData.disabledR=!0,Pe.updateBaseObjectKey(ct,`${je}_${this.options.key}`),ct})));this.helperMesh=[Fe,Ae,De,xt],this.helperMeshPosition=[Fe.position.clone(),Ae.position.clone(),De.position.clone(),xt.position.clone()]})}instantiate(){return U0(this,null,function*(){this.update();const r=yield this.line.instantiate({recursive:!1}),m=yield yn(Arc.prototype,this,"instantiate").call(this,{create:v=>{v.line=r,v.object3d=r.object3d}});return m.position.set(0,0,0),m.rotation.set(0,0,0),m.scale.set(1,1,1),m})}setPath(r,m,v,C=_=>_*1){const{globe:_}=this.options;r=h(r),m=h(m);const I=(_?createFlyPath(r,m,v):createFlyPath2(r,m,v)).getPoints(1500);this.line.options.nodes=I,this.line.setGeometry(I,C),this.pickTube&&this.addPickTarget(this.pickTube.options.radius)}addPickTarget(r=1,m=!1){return U0(this,null,function*(){const v=this.pickTube,C=this.pencil.lead,_=this.line.options.nodes,w=new CurvePath;for(let Pe=0;Pe<_.length-1;Pe++)w.add(new LineCurve3(_[Pe],_[Pe+1]));const I=yield C.draw("Tube",{path:w,radius:r,multiplyScalar:1},this),O=I.object3d;return O.material=new MeshBasicMaterial({color:16711680,transparent:!0,opacity:m?1:0}),v&&(v.userData._pe_&&I.onPointerEvent(...v.userData._pe_),v.erase()),this.pickTube=I,I})}onPointerEvent(...r){this.pickTube?(this.pickTube.onPointerEvent(...r),this.pickTube.userData._pe_=[...r]):this.pencil.userData.EditorEnv||console.warn("addPickTarget first")}setColor(r){this.line&&(this.line.material.uniforms.color.value=new Color$1(r))}animateIn({duration:r=2e3,delay:m=0,repeat:v=1/0,onComplete:C,onRepeat:_}={}){this.line.material.userData.tween&&(this.line.material.userData.tween.stop(),remove(this.line.material.userData.tween),this.line.material.userData.tween=null,this.line.material.uniforms.offset.value.x=0),r&&(this.line.material.uniforms.offset.value.x=1,this.line.material.uniforms.offsetLoop.value=0,this.line.animate({duration:r,repeat:v,delay:m,lineLoop:this.options.offsetLoop,onRepeat:_,onComplete:C}))}update(){var r;if((r=this.helperMesh)!=null&&r.length&&this.helperMesh.find((v,C)=>v.position.distanceTo(this.helperMeshPosition[C])>.01)){this.helperMesh.forEach((_,w)=>{this.helperMeshPosition[w].copy(_.position)});const C=new CubicBezierCurve3(this.helperMeshPosition[0],this.helperMeshPosition[1],this.helperMeshPosition[2],this.helperMeshPosition[3]).getPoints(1500);this.line.setGeometry(C,this.line.object3d.geometry.widthCallback)}}render(){this.mList.rmBaseObjectMap(this.line),setTimeout(()=>{!this.pencil.userData.EditorEnv&&this.prefab||this.line.material.userData.tween||this.animateIn()})}dispose(){this.line.dispose(),super.dispose()}}class CrossPlane extends ht{constructor(r){super();C0(this,"options");this.options=q0({},r)}create(){return U0(this,null,function*(){this.createGroup();const r=this.options.material||new MeshBasicMaterial({color:"#ffffff",side:DoubleSide,blending:AdditiveBlending});r.depthWrite=!1;const m=this.pencil.lead,[v,C]=yield Promise.all([m.draw("Plane",{key:"crossPlane_item1_"+this.options.key},this),m.draw("Plane",{key:"crossPlane_item2_"+this.options.key},this)]);v.object3d.material=r,C.object3d.material=r,v.rotation.x=-Math.PI*.5,C.rotation.x=-Math.PI*.5,C.rotation.y=-Math.PI*.5})}}class PlaneShadow extends ht{create(){return U0(this,null,function*(){const t=new PlaneGeometry(100,100,2,2),r=new ShadowMaterial;r.opacity=.5,r.depthWrite=!1,this.createMesh(t,r),this.object3d.receiveShadow=!0,this.position.z=.1,this.object3d.name="阴影接受"})}}class Model extends ht{constructor(r){super();C0(this,"options");this.options=q0({},r)}create(){return U0(this,null,function*(){const r=this.pencil.loader,m=this.options.src,v=yield r.load(m,{type:"gltf",cache:!1});this.object3d=v.scene})}}class Box extends ht{create(){const t=new BoxGeometry(1,1,1,1,1,1);this.createMesh(t),this.scale.multiplyScalar(20)}}class Capsule extends ht{create(){const t=new CapsuleGeometry(1,1,4,8);this.createMesh(t),this.scale.multiplyScalar(20)}}class Circle extends ht{create(){const t=new CircleGeometry(1,32,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Cylinder extends ht{create(){const t=new CylinderGeometry(1,1,1,32,1,!1,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Dodecahedron extends ht{create(){const t=new DodecahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Icosahedron extends ht{create(){const t=new IcosahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Lathe extends ht{create(){const t=new LatheGeometry;this.createMesh(t,new MeshStandardMaterial({side:DoubleSide})),this.scale.multiplyScalar(20)}}class Octahedron extends ht{create(){const t=new OctahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Plane extends ht{create(){const t=new PlaneGeometry(1,1,2,2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Ring extends ht{create(){const t=new RingGeometry(.5,1,32,1,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Sphere extends ht{constructor(){super(...arguments);C0(this,"radius",100);C0(this,"material");C0(this,"options")}create(){var m;(m=this.options)!=null&&m.radius&&(this.radius=this.options.radius);const r=new SphereGeometry(this.radius,128,90);this.createMesh(r,this.material),this.object3d.rotation.y=Math.PI/180*90}}class Sprite extends ht{create(){this.createSprite(new SpriteMaterial),this.scale.multiplyScalar(20)}setDesiredPixelSize(t){var m;const r=this.object3d;if((m=r.material.map)!=null&&m.image){const v=this.pencil.camera,C=new Vector3;v.matrixWorld.decompose(C,new Quaternion,new Vector3);const _=MathUtils.degToRad(v.fov),I=this.pencil.getSize().height*(1/(2*Math.tan(_/2))),O=t/I,{width:Pe,height:Ne}=r.material.map.image;r.scale.set(Pe/Ne*O,O,1)}}}class Tetrahedron extends ht{create(){const t=new TetrahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Torus extends ht{create(){const t=new TorusGeometry(1,.4,12,48,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class TorusKnot extends ht{create(){const t=new TorusKnotGeometry(1,.4,64,8,2,3);this.createMesh(t),this.scale.multiplyScalar(20)}}class Tube extends ht{constructor(r){super();C0(this,"options");this.options=r}create(){var _,w;const r=this.options.path||new CatmullRomCurve3([new Vector3(2,2,-2),new Vector3(2,-2,-.6666666666666667),new Vector3(-2,-2,.6666666666666667),new Vector3(-2,2,2)]),m=(_=this.options.radius)!=null?_:1,v=(w=this.options.multiplyScalar)!=null?w:20,C=new TubeGeometry(r,64,m,8,!1);this.createMesh(C),this.scale.multiplyScalar(v)}}const baseObjs={Node:Xe$1,Line:es,Line2:Ke$1,ExtrudePolygon:is,ConicPolygon:ss,Group:Qe$1,Light,Point,Arc,Model},expObjs={Plane,CrossPlane,PlaneShadow,Ring,Sphere,Sprite,Tetrahedron,Torus,TorusKnot,Tube,Box,Capsule,Circle,Cylinder,Dodecahedron,Icosahedron,Lathe,Octahedron},prefabType=Object.keys(Ji(q0({},expObjs),{Arc,Model})).map(g=>g),objs$3=q0(q0({},baseObjs),expObjs);function promisifyRequest(g){return new Promise((t,r)=>{g.oncomplete=g.onsuccess=()=>t(g.result),g.onabort=g.onerror=()=>r(g.error)})}function createStore(g,t){const r=indexedDB.open(g);r.onupgradeneeded=()=>r.result.createObjectStore(t);const m=promisifyRequest(r);return(v,C)=>m.then(_=>C(_.transaction(t,v).objectStore(t)))}let defaultGetStoreFunc;function defaultGetStore(){return defaultGetStoreFunc||(defaultGetStoreFunc=createStore("keyval-store","keyval")),defaultGetStoreFunc}function get(g,t=defaultGetStore()){return t("readonly",r=>promisifyRequest(r.get(g)))}function setMany(g,t=defaultGetStore()){return t("readwrite",r=>(g.forEach(m=>r.put(m[1],m[0])),promisifyRequest(r.transaction)))}var H=Object.defineProperty,y=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable,s=(g,t,r)=>t in g?H(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,W=(g,t)=>{for(var r in t||(t={}))a.call(t,r)&&s(g,r,t[r]);if(y)for(var r of y(t))x.call(t,r)&&s(g,r,t[r]);return g},Y=(g,t)=>{var r={};for(var m in g)a.call(g,m)&&t.indexOf(m)<0&&(r[m]=g[m]);if(g!=null&&y)for(var m of y(g))t.indexOf(m)<0&&x.call(g,m)&&(r[m]=g[m]);return r},V=(g,t,r)=>new Promise((m,v)=>{var C=I=>{try{w(r.next(I))}catch(O){v(O)}},_=I=>{try{w(r.throw(I))}catch(O){v(O)}},w=I=>I.done?m(I.value):Promise.resolve(I.value).then(C,_);w((r=r.apply(g,t)).next())});const o="dmFyIEJnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxGZz1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgSWc9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIFFyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIFp1PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksWHU9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgZ2M9KEosUSk9PihRPVN5bWJvbFtKXSk/UTpTeW1ib2wuZm9yKCJTeW1ib2wuIitKKSxrZz1KPT57dGhyb3cgVHlwZUVycm9yKEopfSx5aT1NYXRoLnBvdyxHdT0oSixRLG10KT0+USBpbiBKP0JnKEosUSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6bXR9KTpKW1FdPW10LEZ0PShKLFEpPT57Zm9yKHZhciBtdCBpbiBRfHwoUT17fSkpWnUuY2FsbChRLG10KSYmR3UoSixtdCxRW210XSk7aWYoUXIpZm9yKHZhciBtdCBvZiBRcihRKSlYdS5jYWxsKFEsbXQpJiZHdShKLG10LFFbbXRdKTtyZXR1cm4gSn0sWmU9KEosUSk9PkZnKEosSWcoUSkpO3ZhciBKdT0oSixRKT0+e3ZhciBtdD17fTtmb3IodmFyIE10IGluIEopWnUuY2FsbChKLE10KSYmUS5pbmRleE9mKE10KTwwJiYobXRbTXRdPUpbTXRdKTtpZihKIT1udWxsJiZRcilmb3IodmFyIE10IG9mIFFyKEopKVEuaW5kZXhPZihNdCk8MCYmWHUuY2FsbChKLE10KSYmKG10W010XT1KW010XSk7cmV0dXJuIG10fTt2YXIgTmc9ZnVuY3Rpb24oSixRKXt0aGlzWzBdPUosdGhpc1sxXT1RfTt2YXIgWXU9Sj0+e3ZhciBRPUpbZ2MoImFzeW5jSXRlcmF0b3IiKV0sbXQ9ITEsTXQsY249e307cmV0dXJuIFE9PW51bGw/KFE9SltnYygiaXRlcmF0b3IiKV0oKSxNdD1TZT0+Y25bU2VdPUJuPT5RW1NlXShCbikpOihRPVEuY2FsbChKKSxNdD1TZT0+Y25bU2VdPUJuPT57aWYobXQpe2lmKG10PSExLFNlPT09InRocm93Iil0aHJvdyBCbjtyZXR1cm4gQm59cmV0dXJuIG10PSEwLHtkb25lOiExLHZhbHVlOm5ldyBOZyhuZXcgUHJvbWlzZSh4Yz0+e3ZhciBLcj1RW1NlXShCbik7S3IgaW5zdGFuY2VvZiBPYmplY3R8fGtnKCJPYmplY3QgZXhwZWN0ZWQiKSx4YyhLcil9KSwxKX19KSxjbltnYygiaXRlcmF0b3IiKV09KCk9PmNuLE10KCJuZXh0IiksInRocm93ImluIFE/TXQoInRocm93Iik6Y24udGhyb3c9U2U9Pnt0aHJvdyBTZX0sInJldHVybiJpbiBRJiZNdCgicmV0dXJuIiksY259OyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTAtMjAyNSBUaHJlZS5qcyBBdXRob3JzCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKICovY29uc3QgSj0iMTc4Iix3Yz0iIixvZT0ic3JnYiIsYmM9InNyZ2ItbGluZWFyIixNYz0ibGluZWFyIix0bz0ic3JnYiI7Y2xhc3Mgb3N7YWRkRXZlbnRMaXN0ZW5lcih0LGUpe3RoaXMuX2xpc3RlbmVycz09PXZvaWQgMCYmKHRoaXMuX2xpc3RlbmVycz17fSk7Y29uc3Qgbj10aGlzLl9saXN0ZW5lcnM7blt0XT09PXZvaWQgMCYmKG5bdF09W10pLG5bdF0uaW5kZXhPZihlKT09PS0xJiZuW3RdLnB1c2goZSl9aGFzRXZlbnRMaXN0ZW5lcih0LGUpe2NvbnN0IG49dGhpcy5fbGlzdGVuZXJzO3JldHVybiBuPT09dm9pZCAwPyExOm5bdF0hPT12b2lkIDAmJm5bdF0uaW5kZXhPZihlKSE9PS0xfXJlbW92ZUV2ZW50TGlzdGVuZXIodCxlKXtjb25zdCBuPXRoaXMuX2xpc3RlbmVycztpZihuPT09dm9pZCAwKXJldHVybjtjb25zdCBzPW5bdF07aWYocyE9PXZvaWQgMCl7Y29uc3Qgcj1zLmluZGV4T2YoZSk7ciE9PS0xJiZzLnNwbGljZShyLDEpfX1kaXNwYXRjaEV2ZW50KHQpe2NvbnN0IGU9dGhpcy5fbGlzdGVuZXJzO2lmKGU9PT12b2lkIDApcmV0dXJuO2NvbnN0IG49ZVt0LnR5cGVdO2lmKG4hPT12b2lkIDApe3QudGFyZ2V0PXRoaXM7Y29uc3Qgcz1uLnNsaWNlKDApO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLmNhbGwodGhpcyx0KTt0LnRhcmdldD1udWxsfX19Y29uc3QgQXQ9WyIwMCIsIjAxIiwiMDIiLCIwMyIsIjA0IiwiMDUiLCIwNiIsIjA3IiwiMDgiLCIwOSIsIjBhIiwiMGIiLCIwYyIsIjBkIiwiMGUiLCIwZiIsIjEwIiwiMTEiLCIxMiIsIjEzIiwiMTQiLCIxNSIsIjE2IiwiMTciLCIxOCIsIjE5IiwiMWEiLCIxYiIsIjFjIiwiMWQiLCIxZSIsIjFmIiwiMjAiLCIyMSIsIjIyIiwiMjMiLCIyNCIsIjI1IiwiMjYiLCIyNyIsIjI4IiwiMjkiLCIyYSIsIjJiIiwiMmMiLCIyZCIsIjJlIiwiMmYiLCIzMCIsIjMxIiwiMzIiLCIzMyIsIjM0IiwiMzUiLCIzNiIsIjM3IiwiMzgiLCIzOSIsIjNhIiwiM2IiLCIzYyIsIjNkIiwiM2UiLCIzZiIsIjQwIiwiNDEiLCI0MiIsIjQzIiwiNDQiLCI0NSIsIjQ2IiwiNDciLCI0OCIsIjQ5IiwiNGEiLCI0YiIsIjRjIiwiNGQiLCI0ZSIsIjRmIiwiNTAiLCI1MSIsIjUyIiwiNTMiLCI1NCIsIjU1IiwiNTYiLCI1NyIsIjU4IiwiNTkiLCI1YSIsIjViIiwiNWMiLCI1ZCIsIjVlIiwiNWYiLCI2MCIsIjYxIiwiNjIiLCI2MyIsIjY0IiwiNjUiLCI2NiIsIjY3IiwiNjgiLCI2OSIsIjZhIiwiNmIiLCI2YyIsIjZkIiwiNmUiLCI2ZiIsIjcwIiwiNzEiLCI3MiIsIjczIiwiNzQiLCI3NSIsIjc2IiwiNzciLCI3OCIsIjc5IiwiN2EiLCI3YiIsIjdjIiwiN2QiLCI3ZSIsIjdmIiwiODAiLCI4MSIsIjgyIiwiODMiLCI4NCIsIjg1IiwiODYiLCI4NyIsIjg4IiwiODkiLCI4YSIsIjhiIiwiOGMiLCI4ZCIsIjhlIiwiOGYiLCI5MCIsIjkxIiwiOTIiLCI5MyIsIjk0IiwiOTUiLCI5NiIsIjk3IiwiOTgiLCI5OSIsIjlhIiwiOWIiLCI5YyIsIjlkIiwiOWUiLCI5ZiIsImEwIiwiYTEiLCJhMiIsImEzIiwiYTQiLCJhNSIsImE2IiwiYTciLCJhOCIsImE5IiwiYWEiLCJhYiIsImFjIiwiYWQiLCJhZSIsImFmIiwiYjAiLCJiMSIsImIyIiwiYjMiLCJiNCIsImI1IiwiYjYiLCJiNyIsImI4IiwiYjkiLCJiYSIsImJiIiwiYmMiLCJiZCIsImJlIiwiYmYiLCJjMCIsImMxIiwiYzIiLCJjMyIsImM0IiwiYzUiLCJjNiIsImM3IiwiYzgiLCJjOSIsImNhIiwiY2IiLCJjYyIsImNkIiwiY2UiLCJjZiIsImQwIiwiZDEiLCJkMiIsImQzIiwiZDQiLCJkNSIsImQ2IiwiZDciLCJkOCIsImQ5IiwiZGEiLCJkYiIsImRjIiwiZGQiLCJkZSIsImRmIiwiZTAiLCJlMSIsImUyIiwiZTMiLCJlNCIsImU1IiwiZTYiLCJlNyIsImU4IiwiZTkiLCJlYSIsImViIiwiZWMiLCJlZCIsImVlIiwiZWYiLCJmMCIsImYxIiwiZjIiLCJmMyIsImY0IiwiZjUiLCJmNiIsImY3IiwiZjgiLCJmOSIsImZhIiwiZmIiLCJmYyIsImZkIiwiZmUiLCJmZiJdO2Z1bmN0aW9uIEZuKCl7Y29uc3QgaT1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MCx0PU1hdGgucmFuZG9tKCkqNDI5NDk2NzI5NXwwLGU9TWF0aC5yYW5kb20oKSo0Mjk0OTY3Mjk1fDAsbj1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MDtyZXR1cm4oQXRbaSYyNTVdK0F0W2k+PjgmMjU1XStBdFtpPj4xNiYyNTVdK0F0W2k+PjI0JjI1NV0rIi0iK0F0W3QmMjU1XStBdFt0Pj44JjI1NV0rIi0iK0F0W3Q+PjE2JjE1fDY0XStBdFt0Pj4yNCYyNTVdKyItIitBdFtlJjYzfDEyOF0rQXRbZT4+OCYyNTVdKyItIitBdFtlPj4xNiYyNTVdK0F0W2U+PjI0JjI1NV0rQXRbbiYyNTVdK0F0W24+PjgmMjU1XStBdFtuPj4xNiYyNTVdK0F0W24+PjI0JjI1NV0pLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gWihpLHQsZSl7cmV0dXJuIE1hdGgubWF4KHQsTWF0aC5taW4oZSxpKSl9ZnVuY3Rpb24ganUoaSx0KXtyZXR1cm4oaSV0K3QpJXR9ZnVuY3Rpb24gZW8oaSx0LGUpe3JldHVybigxLWUpKmkrZSp0fWZ1bmN0aW9uIG1pKGksdCl7c3dpdGNoKHQuY29uc3RydWN0b3Ipe2Nhc2UgRmxvYXQzMkFycmF5OnJldHVybiBpO2Nhc2UgVWludDMyQXJyYXk6cmV0dXJuIGkvNDI5NDk2NzI5NTtjYXNlIFVpbnQxNkFycmF5OnJldHVybiBpLzY1NTM1O2Nhc2UgVWludDhBcnJheTpyZXR1cm4gaS8yNTU7Y2FzZSBJbnQzMkFycmF5OnJldHVybiBNYXRoLm1heChpLzIxNDc0ODM2NDcsLTEpO2Nhc2UgSW50MTZBcnJheTpyZXR1cm4gTWF0aC5tYXgoaS8zMjc2NywtMSk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgubWF4KGkvMTI3LC0xKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiSW52YWxpZCBjb21wb25lbnQgdHlwZS4iKX19ZnVuY3Rpb24gSXQoaSx0KXtzd2l0Y2godC5jb25zdHJ1Y3Rvcil7Y2FzZSBGbG9hdDMyQXJyYXk6cmV0dXJuIGk7Y2FzZSBVaW50MzJBcnJheTpyZXR1cm4gTWF0aC5yb3VuZChpKjQyOTQ5NjcyOTUpO2Nhc2UgVWludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSo2NTUzNSk7Y2FzZSBVaW50OEFycmF5OnJldHVybiBNYXRoLnJvdW5kKGkqMjU1KTtjYXNlIEludDMyQXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoyMTQ3NDgzNjQ3KTtjYXNlIEludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSozMjc2Nyk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoxMjcpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGNvbXBvbmVudCB0eXBlLiIpfX1jbGFzcyBSe2NvbnN0cnVjdG9yKHQ9MCxlPTApe1IucHJvdG90eXBlLmlzVmVjdG9yMj0hMCx0aGlzLng9dCx0aGlzLnk9ZX1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy54fXNldCB3aWR0aCh0KXt0aGlzLng9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMueX1zZXQgaGVpZ2h0KHQpe3RoaXMueT10fXNldCh0LGUpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Q29tcG9uZW50KHQsZSl7c3dpdGNoKHQpe2Nhc2UgMDp0aGlzLng9ZTticmVhaztjYXNlIDE6dGhpcy55PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnkpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PXNbMF0qZStzWzNdKm4rc1s2XSx0aGlzLnk9c1sxXSplK3NbNF0qbitzWzddLHRoaXN9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueX1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSl9bWFuaGF0dGFuTGVuZ3RoKCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueCkrTWF0aC5hYnModGhpcy55KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9YW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMigtdGhpcy55LC10aGlzLngpK01hdGguUEl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnk7cmV0dXJuIGUqZStuKm59bWFuaGF0dGFuRGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5hYnModGhpcy54LXQueCkrTWF0aC5hYnModGhpcy55LXQueSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXN9cm90YXRlQXJvdW5kKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9dGhpcy54LXQueCxvPXRoaXMueS10Lnk7cmV0dXJuIHRoaXMueD1yKm4tbypzK3QueCx0aGlzLnk9cipzK28qbit0LnksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55fX1jbGFzcyBnaXtjb25zdHJ1Y3Rvcih0PTAsZT0wLG49MCxzPTEpe3RoaXMuaXNRdWF0ZXJuaW9uPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9c31zdGF0aWMgc2xlcnBGbGF0KHQsZSxuLHMscixvLGEpe2xldCBjPW5bcyswXSxsPW5bcysxXSxoPW5bcysyXSx1PW5bcyszXTtjb25zdCBmPXJbbyswXSxkPXJbbysxXSxwPXJbbysyXSx5PXJbbyszXTtpZihhPT09MCl7dFtlKzBdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXU7cmV0dXJufWlmKGE9PT0xKXt0W2UrMF09Zix0W2UrMV09ZCx0W2UrMl09cCx0W2UrM109eTtyZXR1cm59aWYodSE9PXl8fGMhPT1mfHxsIT09ZHx8aCE9PXApe2xldCBtPTEtYTtjb25zdCBnPWMqZitsKmQraCpwK3UqeSxiPWc+PTA/MTotMSx3PTEtZypnO2lmKHc+TnVtYmVyLkVQU0lMT04pe2NvbnN0IE09TWF0aC5zcXJ0KHcpLEE9TWF0aC5hdGFuMihNLGcqYik7bT1NYXRoLnNpbihtKkEpL00sYT1NYXRoLnNpbihhKkEpL019Y29uc3QgeD1hKmI7aWYoYz1jKm0rZip4LGw9bCptK2QqeCxoPWgqbStwKngsdT11Km0reSp4LG09PT0xLWEpe2NvbnN0IE09MS9NYXRoLnNxcnQoYypjK2wqbCtoKmgrdSp1KTtjKj1NLGwqPU0saCo9TSx1Kj1NfX10W2VdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXV9c3RhdGljIG11bHRpcGx5UXVhdGVybmlvbnNGbGF0KHQsZSxuLHMscixvKXtjb25zdCBhPW5bc10sYz1uW3MrMV0sbD1uW3MrMl0saD1uW3MrM10sdT1yW29dLGY9cltvKzFdLGQ9cltvKzJdLHA9cltvKzNdO3JldHVybiB0W2VdPWEqcCtoKnUrYypkLWwqZix0W2UrMV09YypwK2gqZitsKnUtYSpkLHRbZSsyXT1sKnAraCpkK2EqZi1jKnUsdFtlKzNdPWgqcC1hKnUtYypmLWwqZCx0fWdldCB4KCl7cmV0dXJuIHRoaXMuX3h9c2V0IHgodCl7dGhpcy5feD10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeSgpe3JldHVybiB0aGlzLl95fXNldCB5KHQpe3RoaXMuX3k9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHooKXtyZXR1cm4gdGhpcy5fen1zZXQgeih0KXt0aGlzLl96PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB3KCl7cmV0dXJuIHRoaXMuX3d9c2V0IHcodCl7dGhpcy5fdz10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scyl7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9cyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl94LHRoaXMuX3ksdGhpcy5feix0aGlzLl93KX1jb3B5KHQpe3JldHVybiB0aGlzLl94PXQueCx0aGlzLl95PXQueSx0aGlzLl96PXQueix0aGlzLl93PXQudyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zZXRGcm9tRXVsZXIodCxlPSEwKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX29yZGVyLGE9TWF0aC5jb3MsYz1NYXRoLnNpbixsPWEobi8yKSxoPWEocy8yKSx1PWEoci8yKSxmPWMobi8yKSxkPWMocy8yKSxwPWMoci8yKTtzd2l0Y2gobyl7Y2FzZSJYWVoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJZWFoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJaWFkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJZWlgiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJYWlkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLlF1YXRlcm5pb246IC5zZXRGcm9tRXVsZXIoKSBlbmNvdW50ZXJlZCBhbiB1bmtub3duIG9yZGVyOiAiK28pfXJldHVybiBlPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21BeGlzQW5nbGUodCxlKXtjb25zdCBuPWUvMixzPU1hdGguc2luKG4pO3JldHVybiB0aGlzLl94PXQueCpzLHRoaXMuX3k9dC55KnMsdGhpcy5fej10Lnoqcyx0aGlzLl93PU1hdGguY29zKG4pLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0KXtjb25zdCBlPXQuZWxlbWVudHMsbj1lWzBdLHM9ZVs0XSxyPWVbOF0sbz1lWzFdLGE9ZVs1XSxjPWVbOV0sbD1lWzJdLGg9ZVs2XSx1PWVbMTBdLGY9bithK3U7aWYoZj4wKXtjb25zdCBkPS41L01hdGguc3FydChmKzEpO3RoaXMuX3c9LjI1L2QsdGhpcy5feD0oaC1jKSpkLHRoaXMuX3k9KHItbCkqZCx0aGlzLl96PShvLXMpKmR9ZWxzZSBpZihuPmEmJm4+dSl7Y29uc3QgZD0yKk1hdGguc3FydCgxK24tYS11KTt0aGlzLl93PShoLWMpL2QsdGhpcy5feD0uMjUqZCx0aGlzLl95PShzK28pL2QsdGhpcy5fej0ocitsKS9kfWVsc2UgaWYoYT51KXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErYS1uLXUpO3RoaXMuX3c9KHItbCkvZCx0aGlzLl94PShzK28pL2QsdGhpcy5feT0uMjUqZCx0aGlzLl96PShjK2gpL2R9ZWxzZXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErdS1uLWEpO3RoaXMuX3c9KG8tcykvZCx0aGlzLl94PShyK2wpL2QsdGhpcy5feT0oYytoKS9kLHRoaXMuX3o9LjI1KmR9cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Vbml0VmVjdG9ycyh0LGUpe2xldCBuPXQuZG90KGUpKzE7cmV0dXJuIG48MWUtOD8obj0wLE1hdGguYWJzKHQueCk+TWF0aC5hYnModC56KT8odGhpcy5feD0tdC55LHRoaXMuX3k9dC54LHRoaXMuX3o9MCx0aGlzLl93PW4pOih0aGlzLl94PTAsdGhpcy5feT0tdC56LHRoaXMuX3o9dC55LHRoaXMuX3c9bikpOih0aGlzLl94PXQueSplLnotdC56KmUueSx0aGlzLl95PXQueiplLngtdC54KmUueix0aGlzLl96PXQueCplLnktdC55KmUueCx0aGlzLl93PW4pLHRoaXMubm9ybWFsaXplKCl9YW5nbGVUbyh0KXtyZXR1cm4gMipNYXRoLmFjb3MoTWF0aC5hYnMoWih0aGlzLmRvdCh0KSwtMSwxKSkpfXJvdGF0ZVRvd2FyZHModCxlKXtjb25zdCBuPXRoaXMuYW5nbGVUbyh0KTtpZihuPT09MClyZXR1cm4gdGhpcztjb25zdCBzPU1hdGgubWluKDEsZS9uKTtyZXR1cm4gdGhpcy5zbGVycCh0LHMpLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMSl9aW52ZXJ0KCl7cmV0dXJuIHRoaXMuY29uanVnYXRlKCl9Y29uanVnYXRlKCl7cmV0dXJuIHRoaXMuX3gqPS0xLHRoaXMuX3kqPS0xLHRoaXMuX3oqPS0xLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfWRvdCh0KXtyZXR1cm4gdGhpcy5feCp0Ll94K3RoaXMuX3kqdC5feSt0aGlzLl96KnQuX3ordGhpcy5fdyp0Ll93fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fd31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fdyl9bm9ybWFsaXplKCl7bGV0IHQ9dGhpcy5sZW5ndGgoKTtyZXR1cm4gdD09PTA/KHRoaXMuX3g9MCx0aGlzLl95PTAsdGhpcy5fej0wLHRoaXMuX3c9MSk6KHQ9MS90LHRoaXMuX3g9dGhpcy5feCp0LHRoaXMuX3k9dGhpcy5feSp0LHRoaXMuX3o9dGhpcy5feip0LHRoaXMuX3c9dGhpcy5fdyp0KSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseVF1YXRlcm5pb25zKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlRdWF0ZXJuaW9ucyh0LHRoaXMpfW11bHRpcGx5UXVhdGVybmlvbnModCxlKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX3csYT1lLl94LGM9ZS5feSxsPWUuX3osaD1lLl93O3JldHVybiB0aGlzLl94PW4qaCtvKmErcypsLXIqYyx0aGlzLl95PXMqaCtvKmMrciphLW4qbCx0aGlzLl96PXIqaCtvKmwrbipjLXMqYSx0aGlzLl93PW8qaC1uKmEtcypjLXIqbCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zbGVycCh0LGUpe2lmKGU9PT0wKXJldHVybiB0aGlzO2lmKGU9PT0xKXJldHVybiB0aGlzLmNvcHkodCk7Y29uc3Qgbj10aGlzLl94LHM9dGhpcy5feSxyPXRoaXMuX3osbz10aGlzLl93O2xldCBhPW8qdC5fdytuKnQuX3grcyp0Ll95K3IqdC5fejtpZihhPDA/KHRoaXMuX3c9LXQuX3csdGhpcy5feD0tdC5feCx0aGlzLl95PS10Ll95LHRoaXMuX3o9LXQuX3osYT0tYSk6dGhpcy5jb3B5KHQpLGE+PTEpcmV0dXJuIHRoaXMuX3c9byx0aGlzLl94PW4sdGhpcy5feT1zLHRoaXMuX3o9cix0aGlzO2NvbnN0IGM9MS1hKmE7aWYoYzw9TnVtYmVyLkVQU0lMT04pe2NvbnN0IGQ9MS1lO3JldHVybiB0aGlzLl93PWQqbytlKnRoaXMuX3csdGhpcy5feD1kKm4rZSp0aGlzLl94LHRoaXMuX3k9ZCpzK2UqdGhpcy5feSx0aGlzLl96PWQqcitlKnRoaXMuX3osdGhpcy5ub3JtYWxpemUoKSx0aGlzfWNvbnN0IGw9TWF0aC5zcXJ0KGMpLGg9TWF0aC5hdGFuMihsLGEpLHU9TWF0aC5zaW4oKDEtZSkqaCkvbCxmPU1hdGguc2luKGUqaCkvbDtyZXR1cm4gdGhpcy5fdz1vKnUrdGhpcy5fdypmLHRoaXMuX3g9bip1K3RoaXMuX3gqZix0aGlzLl95PXMqdSt0aGlzLl95KmYsdGhpcy5fej1yKnUrdGhpcy5feipmLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNsZXJwUXVhdGVybmlvbnModCxlLG4pe3JldHVybiB0aGlzLmNvcHkodCkuc2xlcnAoZSxuKX1yYW5kb20oKXtjb25zdCB0PTIqTWF0aC5QSSpNYXRoLnJhbmRvbSgpLGU9MipNYXRoLlBJKk1hdGgucmFuZG9tKCksbj1NYXRoLnJhbmRvbSgpLHM9TWF0aC5zcXJ0KDEtbikscj1NYXRoLnNxcnQobik7cmV0dXJuIHRoaXMuc2V0KHMqTWF0aC5zaW4odCkscypNYXRoLmNvcyh0KSxyKk1hdGguc2luKGUpLHIqTWF0aC5jb3MoZSkpfWVxdWFscyh0KXtyZXR1cm4gdC5feD09PXRoaXMuX3gmJnQuX3k9PT10aGlzLl95JiZ0Ll96PT09dGhpcy5feiYmdC5fdz09PXRoaXMuX3d9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy5feD10W2VdLHRoaXMuX3k9dFtlKzFdLHRoaXMuX3o9dFtlKzJdLHRoaXMuX3c9dFtlKzNdLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMuX3gsdFtlKzFdPXRoaXMuX3ksdFtlKzJdPXRoaXMuX3osdFtlKzNdPXRoaXMuX3csdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMuX3g9dC5nZXRYKGUpLHRoaXMuX3k9dC5nZXRZKGUpLHRoaXMuX3o9dC5nZXRaKGUpLHRoaXMuX3c9dC5nZXRXKGUpLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvSlNPTigpe3JldHVybiB0aGlzLnRvQXJyYXkoKX1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX3d9fWNsYXNzIFR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTApe1QucHJvdG90eXBlLmlzVmVjdG9yMz0hMCx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bn1zZXQodCxlLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj10aGlzLnopLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXN9c2V0U2NhbGFyKHQpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9dCx0aGlzLno9dCx0aGlzfXNldFgodCl7cmV0dXJuIHRoaXMueD10LHRoaXN9c2V0WSh0KXtyZXR1cm4gdGhpcy55PXQsdGhpc31zZXRaKHQpe3JldHVybiB0aGlzLno9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAiK3QpfXJldHVybiB0aGlzfWdldENvbXBvbmVudCh0KXtzd2l0Y2godCl7Y2FzZSAwOnJldHVybiB0aGlzLng7Y2FzZSAxOnJldHVybiB0aGlzLnk7Y2FzZSAyOnJldHVybiB0aGlzLno7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX19Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy54LHRoaXMueSx0aGlzLnopfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzLno9dC56LHRoaXN9YWRkKHQpe3JldHVybiB0aGlzLngrPXQueCx0aGlzLnkrPXQueSx0aGlzLnorPXQueix0aGlzfWFkZFNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kz10LHRoaXMueSs9dCx0aGlzLnorPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXMuej10LnorZS56LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzLnorPXQueiplLHRoaXN9c3ViKHQpe3JldHVybiB0aGlzLngtPXQueCx0aGlzLnktPXQueSx0aGlzLnotPXQueix0aGlzfXN1YlNjYWxhcih0KXtyZXR1cm4gdGhpcy54LT10LHRoaXMueS09dCx0aGlzLnotPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXMuej10LnotZS56LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXMueio9dC56LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpcy56Kj10LHRoaXN9bXVsdGlwbHlWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngqZS54LHRoaXMueT10LnkqZS55LHRoaXMuej10LnoqZS56LHRoaXN9YXBwbHlFdWxlcih0KXtyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oQWMuc2V0RnJvbUV1bGVyKHQpKX1hcHBseUF4aXNBbmdsZSh0LGUpe3JldHVybiB0aGlzLmFwcGx5UXVhdGVybmlvbihBYy5zZXRGcm9tQXhpc0FuZ2xlKHQsZSkpfWFwcGx5TWF0cml4Myh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrclszXSpuK3JbNl0qcyx0aGlzLnk9clsxXSplK3JbNF0qbityWzddKnMsdGhpcy56PXJbMl0qZStyWzVdKm4rcls4XSpzLHRoaXN9YXBwbHlOb3JtYWxNYXRyaXgodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXgzKHQpLm5vcm1hbGl6ZSgpfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHMsbz0xLyhyWzNdKmUrcls3XSpuK3JbMTFdKnMrclsxNV0pO3JldHVybiB0aGlzLng9KHJbMF0qZStyWzRdKm4rcls4XSpzK3JbMTJdKSpvLHRoaXMueT0oclsxXSplK3JbNV0qbityWzldKnMrclsxM10pKm8sdGhpcy56PShyWzJdKmUrcls2XSpuK3JbMTBdKnMrclsxNF0pKm8sdGhpc31hcHBseVF1YXRlcm5pb24odCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10Lngsbz10LnksYT10LnosYz10LncsbD0yKihvKnMtYSpuKSxoPTIqKGEqZS1yKnMpLHU9MioocipuLW8qZSk7cmV0dXJuIHRoaXMueD1lK2MqbCtvKnUtYSpoLHRoaXMueT1uK2MqaCthKmwtcip1LHRoaXMuej1zK2MqdStyKmgtbypsLHRoaXN9cHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZEludmVyc2UpLmFwcGx5TWF0cml4NCh0LnByb2plY3Rpb25NYXRyaXgpfXVucHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5wcm9qZWN0aW9uTWF0cml4SW52ZXJzZSkuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpfXRyYW5zZm9ybURpcmVjdGlvbih0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrcls0XSpuK3JbOF0qcyx0aGlzLnk9clsxXSplK3JbNV0qbityWzldKnMsdGhpcy56PXJbMl0qZStyWzZdKm4rclsxMF0qcyx0aGlzLm5vcm1hbGl6ZSgpfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1taW4odCl7cmV0dXJuIHRoaXMueD1NYXRoLm1pbih0aGlzLngsdC54KSx0aGlzLnk9TWF0aC5taW4odGhpcy55LHQueSksdGhpcy56PU1hdGgubWluKHRoaXMueix0LnopLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzfWNsYW1wKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LngsZS54KSx0aGlzLnk9Wih0aGlzLnksdC55LGUueSksdGhpcy56PVoodGhpcy56LHQueixlLnopLHRoaXN9Y2xhbXBTY2FsYXIodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQsZSksdGhpcy55PVoodGhpcy55LHQsZSksdGhpcy56PVoodGhpcy56LHQsZSksdGhpc31jbGFtcExlbmd0aCh0LGUpe2NvbnN0IG49dGhpcy5sZW5ndGgoKTtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIobnx8MSkubXVsdGlwbHlTY2FsYXIoWihuLHQsZSkpfWZsb29yKCl7cmV0dXJuIHRoaXMueD1NYXRoLmZsb29yKHRoaXMueCksdGhpcy55PU1hdGguZmxvb3IodGhpcy55KSx0aGlzLno9TWF0aC5mbG9vcih0aGlzLnopLHRoaXN9Y2VpbCgpe3JldHVybiB0aGlzLng9TWF0aC5jZWlsKHRoaXMueCksdGhpcy55PU1hdGguY2VpbCh0aGlzLnkpLHRoaXMuej1NYXRoLmNlaWwodGhpcy56KSx0aGlzfXJvdW5kKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJvdW5kKHRoaXMueCksdGhpcy55PU1hdGgucm91bmQodGhpcy55KSx0aGlzLno9TWF0aC5yb3VuZCh0aGlzLnopLHRoaXN9cm91bmRUb1plcm8oKXtyZXR1cm4gdGhpcy54PU1hdGgudHJ1bmModGhpcy54KSx0aGlzLnk9TWF0aC50cnVuYyh0aGlzLnkpLHRoaXMuej1NYXRoLnRydW5jKHRoaXMueiksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56fWxlbmd0aCgpe3JldHVybiBNYXRoLnNxcnQodGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnopfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXMueis9KHQuei10aGlzLnopKmUsdGhpc31sZXJwVmVjdG9ycyh0LGUsbil7cmV0dXJuIHRoaXMueD10LngrKGUueC10LngpKm4sdGhpcy55PXQueSsoZS55LXQueSkqbix0aGlzLno9dC56KyhlLnotdC56KSpuLHRoaXN9Y3Jvc3ModCl7cmV0dXJuIHRoaXMuY3Jvc3NWZWN0b3JzKHRoaXMsdCl9Y3Jvc3NWZWN0b3JzKHQsZSl7Y29uc3Qgbj10Lngscz10Lnkscj10Lnosbz1lLngsYT1lLnksYz1lLno7cmV0dXJuIHRoaXMueD1zKmMtciphLHRoaXMueT1yKm8tbipjLHRoaXMuej1uKmEtcypvLHRoaXN9cHJvamVjdE9uVmVjdG9yKHQpe2NvbnN0IGU9dC5sZW5ndGhTcSgpO2lmKGU9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCk7Y29uc3Qgbj10LmRvdCh0aGlzKS9lO3JldHVybiB0aGlzLmNvcHkodCkubXVsdGlwbHlTY2FsYXIobil9cHJvamVjdE9uUGxhbmUodCl7cmV0dXJuIG5vLmNvcHkodGhpcykucHJvamVjdE9uVmVjdG9yKHQpLHRoaXMuc3ViKG5vKX1yZWZsZWN0KHQpe3JldHVybiB0aGlzLnN1Yihuby5jb3B5KHQpLm11bHRpcGx5U2NhbGFyKDIqdGhpcy5kb3QodCkpKX1hbmdsZVRvKHQpe2NvbnN0IGU9TWF0aC5zcXJ0KHRoaXMubGVuZ3RoU3EoKSp0Lmxlbmd0aFNxKCkpO2lmKGU9PT0wKXJldHVybiBNYXRoLlBJLzI7Y29uc3Qgbj10aGlzLmRvdCh0KS9lO3JldHVybiBNYXRoLmFjb3MoWihuLC0xLDEpKX1kaXN0YW5jZVRvKHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVRvU3F1YXJlZCh0KSl9ZGlzdGFuY2VUb1NxdWFyZWQodCl7Y29uc3QgZT10aGlzLngtdC54LG49dGhpcy55LXQueSxzPXRoaXMuei10Lno7cmV0dXJuIGUqZStuKm4rcypzfW1hbmhhdHRhbkRpc3RhbmNlVG8odCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueC10LngpK01hdGguYWJzKHRoaXMueS10LnkpK01hdGguYWJzKHRoaXMuei10LnopfXNldEZyb21TcGhlcmljYWwodCl7cmV0dXJuIHRoaXMuc2V0RnJvbVNwaGVyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnBoaSx0LnRoZXRhKX1zZXRGcm9tU3BoZXJpY2FsQ29vcmRzKHQsZSxuKXtjb25zdCBzPU1hdGguc2luKGUpKnQ7cmV0dXJuIHRoaXMueD1zKk1hdGguc2luKG4pLHRoaXMueT1NYXRoLmNvcyhlKSp0LHRoaXMuej1zKk1hdGguY29zKG4pLHRoaXN9c2V0RnJvbUN5bGluZHJpY2FsKHQpe3JldHVybiB0aGlzLnNldEZyb21DeWxpbmRyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnRoZXRhLHQueSl9c2V0RnJvbUN5bGluZHJpY2FsQ29vcmRzKHQsZSxuKXtyZXR1cm4gdGhpcy54PXQqTWF0aC5zaW4oZSksdGhpcy55PW4sdGhpcy56PXQqTWF0aC5jb3MoZSksdGhpc31zZXRGcm9tTWF0cml4UG9zaXRpb24odCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9ZVsxMl0sdGhpcy55PWVbMTNdLHRoaXMuej1lWzE0XSx0aGlzfXNldEZyb21NYXRyaXhTY2FsZSh0KXtjb25zdCBlPXRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLG49dGhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCkscz10aGlzLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gdGhpcy54PWUsdGhpcy55PW4sdGhpcy56PXMsdGhpc31zZXRGcm9tTWF0cml4Q29sdW1uKHQsZSl7cmV0dXJuIHRoaXMuZnJvbUFycmF5KHQuZWxlbWVudHMsZSo0KX1zZXRGcm9tTWF0cml4M0NvbHVtbih0LGUpe3JldHVybiB0aGlzLmZyb21BcnJheSh0LmVsZW1lbnRzLGUqMyl9c2V0RnJvbUV1bGVyKHQpe3JldHVybiB0aGlzLng9dC5feCx0aGlzLnk9dC5feSx0aGlzLno9dC5feix0aGlzfXNldEZyb21Db2xvcih0KXtyZXR1cm4gdGhpcy54PXQucix0aGlzLnk9dC5nLHRoaXMuej10LmIsdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55JiZ0Lno9PT10aGlzLnp9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy54LHRbZSsxXT10aGlzLnksdFtlKzJdPXRoaXMueix0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXMuej10LmdldFooZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpc31yYW5kb21EaXJlY3Rpb24oKXtjb25zdCB0PU1hdGgucmFuZG9tKCkqTWF0aC5QSSoyLGU9TWF0aC5yYW5kb20oKSoyLTEsbj1NYXRoLnNxcnQoMS1lKmUpO3JldHVybiB0aGlzLng9bipNYXRoLmNvcyh0KSx0aGlzLnk9ZSx0aGlzLno9bipNYXRoLnNpbih0KSx0aGlzfSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMueCx5aWVsZCB0aGlzLnkseWllbGQgdGhpcy56fX1jb25zdCBubz1uZXcgVCxBYz1uZXcgZ2k7Y2xhc3MgZ2V7Y29uc3RydWN0b3IodCxlLG4scyxyLG8sYSxjLGwpe2dlLnByb3RvdHlwZS5pc01hdHJpeDM9ITAsdGhpcy5lbGVtZW50cz1bMSwwLDAsMCwxLDAsMCwwLDFdLHQhPT12b2lkIDAmJnRoaXMuc2V0KHQsZSxuLHMscixvLGEsYyxsKX1zZXQodCxlLG4scyxyLG8sYSxjLGwpe2NvbnN0IGg9dGhpcy5lbGVtZW50cztyZXR1cm4gaFswXT10LGhbMV09cyxoWzJdPWEsaFszXT1lLGhbNF09cixoWzVdPWMsaFs2XT1uLGhbN109byxoWzhdPWwsdGhpc31pZGVudGl0eSgpe3JldHVybiB0aGlzLnNldCgxLDAsMCwwLDEsMCwwLDAsMSksdGhpc31jb3B5KHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7cmV0dXJuIGVbMF09blswXSxlWzFdPW5bMV0sZVsyXT1uWzJdLGVbM109blszXSxlWzRdPW5bNF0sZVs1XT1uWzVdLGVbNl09bls2XSxlWzddPW5bN10sZVs4XT1uWzhdLHRoaXN9ZXh0cmFjdEJhc2lzKHQsZSxuKXtyZXR1cm4gdC5zZXRGcm9tTWF0cml4M0NvbHVtbih0aGlzLDApLGUuc2V0RnJvbU1hdHJpeDNDb2x1bW4odGhpcywxKSxuLnNldEZyb21NYXRyaXgzQ29sdW1uKHRoaXMsMiksdGhpc31zZXRGcm9tTWF0cml4NCh0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMuc2V0KGVbMF0sZVs0XSxlWzhdLGVbMV0sZVs1XSxlWzldLGVbMl0sZVs2XSxlWzEwXSksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0LHRoaXMpfW11bHRpcGx5TWF0cmljZXModCxlKXtjb25zdCBuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzLHI9dGhpcy5lbGVtZW50cyxvPW5bMF0sYT1uWzNdLGM9bls2XSxsPW5bMV0saD1uWzRdLHU9bls3XSxmPW5bMl0sZD1uWzVdLHA9bls4XSx5PXNbMF0sbT1zWzNdLGc9c1s2XSxiPXNbMV0sdz1zWzRdLHg9c1s3XSxNPXNbMl0sQT1zWzVdLFM9c1s4XTtyZXR1cm4gclswXT1vKnkrYSpiK2MqTSxyWzNdPW8qbSthKncrYypBLHJbNl09bypnK2EqeCtjKlMsclsxXT1sKnkraCpiK3UqTSxyWzRdPWwqbStoKncrdSpBLHJbN109bCpnK2gqeCt1KlMsclsyXT1mKnkrZCpiK3AqTSxyWzVdPWYqbStkKncrcCpBLHJbOF09ZipnK2QqeCtwKlMsdGhpc31tdWx0aXBseVNjYWxhcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIGVbMF0qPXQsZVszXSo9dCxlWzZdKj10LGVbMV0qPXQsZVs0XSo9dCxlWzddKj10LGVbMl0qPXQsZVs1XSo9dCxlWzhdKj10LHRoaXN9ZGV0ZXJtaW5hbnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFsxXSxzPXRbMl0scj10WzNdLG89dFs0XSxhPXRbNV0sYz10WzZdLGw9dFs3XSxoPXRbOF07cmV0dXJuIGUqbypoLWUqYSpsLW4qcipoK24qYSpjK3MqcipsLXMqbypjfWludmVydCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSx1PWgqby1hKmwsZj1hKmMtaCpyLGQ9bCpyLW8qYyxwPWUqdStuKmYrcypkO2lmKHA9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCwwLDAsMCwwLDAsMCk7Y29uc3QgeT0xL3A7cmV0dXJuIHRbMF09dSp5LHRbMV09KHMqbC1oKm4pKnksdFsyXT0oYSpuLXMqbykqeSx0WzNdPWYqeSx0WzRdPShoKmUtcypjKSp5LHRbNV09KHMqci1hKmUpKnksdFs2XT1kKnksdFs3XT0obipjLWwqZSkqeSx0WzhdPShvKmUtbipyKSp5LHRoaXN9dHJhbnNwb3NlKCl7bGV0IHQ7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiB0PWVbMV0sZVsxXT1lWzNdLGVbM109dCx0PWVbMl0sZVsyXT1lWzZdLGVbNl09dCx0PWVbNV0sZVs1XT1lWzddLGVbN109dCx0aGlzfWdldE5vcm1hbE1hdHJpeCh0KXtyZXR1cm4gdGhpcy5zZXRGcm9tTWF0cml4NCh0KS5pbnZlcnQoKS50cmFuc3Bvc2UoKX10cmFuc3Bvc2VJbnRvQXJyYXkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzNdLHRbMl09ZVs2XSx0WzNdPWVbMV0sdFs0XT1lWzRdLHRbNV09ZVs3XSx0WzZdPWVbMl0sdFs3XT1lWzVdLHRbOF09ZVs4XSx0aGlzfXNldFV2VHJhbnNmb3JtKHQsZSxuLHMscixvLGEpe2NvbnN0IGM9TWF0aC5jb3MociksbD1NYXRoLnNpbihyKTtyZXR1cm4gdGhpcy5zZXQobipjLG4qbCwtbiooYypvK2wqYSkrbyt0LC1zKmwscypjLC1zKigtbCpvK2MqYSkrYStlLDAsMCwxKSx0aGlzfXNjYWxlKHQsZSl7cmV0dXJuIHRoaXMucHJlbXVsdGlwbHkoaW8ubWFrZVNjYWxlKHQsZSkpLHRoaXN9cm90YXRlKHQpe3JldHVybiB0aGlzLnByZW11bHRpcGx5KGlvLm1ha2VSb3RhdGlvbigtdCkpLHRoaXN9dHJhbnNsYXRlKHQsZSl7cmV0dXJuIHRoaXMucHJlbXVsdGlwbHkoaW8ubWFrZVRyYW5zbGF0aW9uKHQsZSkpLHRoaXN9bWFrZVRyYW5zbGF0aW9uKHQsZSl7cmV0dXJuIHQuaXNWZWN0b3IyP3RoaXMuc2V0KDEsMCx0LngsMCwxLHQueSwwLDAsMSk6dGhpcy5zZXQoMSwwLHQsMCwxLGUsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoZSwtbiwwLG4sZSwwLDAsMCwxKSx0aGlzfW1ha2VTY2FsZSh0LGUpe3JldHVybiB0aGlzLnNldCh0LDAsMCwwLGUsMCwwLDAsMSksdGhpc31lcXVhbHModCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztmb3IobGV0IHM9MDtzPDk7cysrKWlmKGVbc10hPT1uW3NdKXJldHVybiExO3JldHVybiEwfWZyb21BcnJheSh0LGU9MCl7Zm9yKGxldCBuPTA7bjw5O24rKyl0aGlzLmVsZW1lbnRzW25dPXRbbitlXTtyZXR1cm4gdGhpc310b0FycmF5KHQ9W10sZT0wKXtjb25zdCBuPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbZV09blswXSx0W2UrMV09blsxXSx0W2UrMl09blsyXSx0W2UrM109blszXSx0W2UrNF09bls0XSx0W2UrNV09bls1XSx0W2UrNl09bls2XSx0W2UrN109bls3XSx0W2UrOF09bls4XSx0fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuZnJvbUFycmF5KHRoaXMuZWxlbWVudHMpfX1jb25zdCBpbz1uZXcgZ2U7ZnVuY3Rpb24gUXUoaSl7Zm9yKGxldCB0PWkubGVuZ3RoLTE7dD49MDstLXQpaWYoaVt0XT49NjU1MzUpcmV0dXJuITA7cmV0dXJuITF9ZnVuY3Rpb24gU2MoaSl7cmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsaSl9Y29uc3QgX2M9e307ZnVuY3Rpb24gdmMoaSl7aSBpbiBfY3x8KF9jW2ldPSEwLGNvbnNvbGUud2FybihpKSl9Y29uc3QgemM9bmV3IGdlKCkuc2V0KC40MTIzOTA4LC4zNTc1ODQzLC4xODA0ODA4LC4yMTI2MzksLjcxNTE2ODcsLjA3MjE5MjMsLjAxOTMzMDgsLjExOTE5NDgsLjk1MDUzMjIpLFRjPW5ldyBnZSgpLnNldCgzLjI0MDk2OTksLTEuNTM3MzgzMiwtLjQ5ODYxMDgsLS45NjkyNDM2LDEuODc1OTY3NSwuMDQxNTU1MSwuMDU1NjMwMSwtLjIwMzk3NywxLjA1Njk3MTUpO2Z1bmN0aW9uIEt1KCl7Y29uc3QgaT17ZW5hYmxlZDohMCx3b3JraW5nQ29sb3JTcGFjZTpiYyxzcGFjZXM6e30sY29udmVydDpmdW5jdGlvbihzLHIsbyl7cmV0dXJuIHRoaXMuZW5hYmxlZD09PSExfHxyPT09b3x8IXJ8fCFvfHwodGhpcy5zcGFjZXNbcl0udHJhbnNmZXI9PT10byYmKHMucj1fZShzLnIpLHMuZz1fZShzLmcpLHMuYj1fZShzLmIpKSx0aGlzLnNwYWNlc1tyXS5wcmltYXJpZXMhPT10aGlzLnNwYWNlc1tvXS5wcmltYXJpZXMmJihzLmFwcGx5TWF0cml4Myh0aGlzLnNwYWNlc1tyXS50b1hZWikscy5hcHBseU1hdHJpeDModGhpcy5zcGFjZXNbb10uZnJvbVhZWikpLHRoaXMuc3BhY2VzW29dLnRyYW5zZmVyPT09dG8mJihzLnI9SW4ocy5yKSxzLmc9SW4ocy5nKSxzLmI9SW4ocy5iKSkpLHN9LHdvcmtpbmdUb0NvbG9yU3BhY2U6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdGhpcy5jb252ZXJ0KHMsdGhpcy53b3JraW5nQ29sb3JTcGFjZSxyKX0sY29sb3JTcGFjZVRvV29ya2luZzpmdW5jdGlvbihzLHIpe3JldHVybiB0aGlzLmNvbnZlcnQocyxyLHRoaXMud29ya2luZ0NvbG9yU3BhY2UpfSxnZXRQcmltYXJpZXM6ZnVuY3Rpb24ocyl7cmV0dXJuIHRoaXMuc3BhY2VzW3NdLnByaW1hcmllc30sZ2V0VHJhbnNmZXI6ZnVuY3Rpb24ocyl7cmV0dXJuIHM9PT13Yz9NYzp0aGlzLnNwYWNlc1tzXS50cmFuc2Zlcn0sZ2V0THVtaW5hbmNlQ29lZmZpY2llbnRzOmZ1bmN0aW9uKHMscj10aGlzLndvcmtpbmdDb2xvclNwYWNlKXtyZXR1cm4gcy5mcm9tQXJyYXkodGhpcy5zcGFjZXNbcl0ubHVtaW5hbmNlQ29lZmZpY2llbnRzKX0sZGVmaW5lOmZ1bmN0aW9uKHMpe09iamVjdC5hc3NpZ24odGhpcy5zcGFjZXMscyl9LF9nZXRNYXRyaXg6ZnVuY3Rpb24ocyxyLG8pe3JldHVybiBzLmNvcHkodGhpcy5zcGFjZXNbcl0udG9YWVopLm11bHRpcGx5KHRoaXMuc3BhY2VzW29dLmZyb21YWVopfSxfZ2V0RHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6ZnVuY3Rpb24ocyl7cmV0dXJuIHRoaXMuc3BhY2VzW3NdLm91dHB1dENvbG9yU3BhY2VDb25maWcuZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2V9LF9nZXRVbnBhY2tDb2xvclNwYWNlOmZ1bmN0aW9uKHM9dGhpcy53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHRoaXMuc3BhY2VzW3NdLndvcmtpbmdDb2xvclNwYWNlQ29uZmlnLnVucGFja0NvbG9yU3BhY2V9LGZyb21Xb3JraW5nQ29sb3JTcGFjZTpmdW5jdGlvbihzLHIpe3JldHVybiB2YygiVEhSRUUuQ29sb3JNYW5hZ2VtZW50OiAuZnJvbVdvcmtpbmdDb2xvclNwYWNlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAud29ya2luZ1RvQ29sb3JTcGFjZSgpLiIpLGkud29ya2luZ1RvQ29sb3JTcGFjZShzLHIpfSx0b1dvcmtpbmdDb2xvclNwYWNlOmZ1bmN0aW9uKHMscil7cmV0dXJuIHZjKCJUSFJFRS5Db2xvck1hbmFnZW1lbnQ6IC50b1dvcmtpbmdDb2xvclNwYWNlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAuY29sb3JTcGFjZVRvV29ya2luZygpLiIpLGkuY29sb3JTcGFjZVRvV29ya2luZyhzLHIpfX0sdD1bLjY0LC4zMywuMywuNiwuMTUsLjA2XSxlPVsuMjEyNiwuNzE1MiwuMDcyMl0sbj1bLjMxMjcsLjMyOV07cmV0dXJuIGkuZGVmaW5lKHtbYmNdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6TWMsdG9YWVo6emMsZnJvbVhZWjpUYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSx3b3JraW5nQ29sb3JTcGFjZUNvbmZpZzp7dW5wYWNrQ29sb3JTcGFjZTpvZX0sb3V0cHV0Q29sb3JTcGFjZUNvbmZpZzp7ZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6b2V9fSxbb2VdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6dG8sdG9YWVo6emMsZnJvbVhZWjpUYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSxvdXRwdXRDb2xvclNwYWNlQ29uZmlnOntkcmF3aW5nQnVmZmVyQ29sb3JTcGFjZTpvZX19fSksaX1jb25zdCBhZT1LdSgpO2Z1bmN0aW9uIF9lKGkpe3JldHVybiBpPC4wNDA0NT9pKi4wNzczOTkzODA4Ok1hdGgucG93KGkqLjk0Nzg2NzI5ODYrLjA1MjEzMjcwMTQsMi40KX1mdW5jdGlvbiBJbihpKXtyZXR1cm4gaTwuMDAzMTMwOD9pKjEyLjkyOjEuMDU1Kk1hdGgucG93KGksLjQxNjY2KS0uMDU1fWxldCBrbjtjbGFzcyB0ZntzdGF0aWMgZ2V0RGF0YVVSTCh0LGU9ImltYWdlL3BuZyIpe2lmKC9eZGF0YTovaS50ZXN0KHQuc3JjKXx8dHlwZW9mIEhUTUxDYW52YXNFbGVtZW50PT0idW5kZWZpbmVkIilyZXR1cm4gdC5zcmM7bGV0IG47aWYodCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KW49dDtlbHNle2tuPT09dm9pZCAwJiYoa249U2MoImNhbnZhcyIpKSxrbi53aWR0aD10LndpZHRoLGtuLmhlaWdodD10LmhlaWdodDtjb25zdCBzPWtuLmdldENvbnRleHQoIjJkIik7dCBpbnN0YW5jZW9mIEltYWdlRGF0YT9zLnB1dEltYWdlRGF0YSh0LDAsMCk6cy5kcmF3SW1hZ2UodCwwLDAsdC53aWR0aCx0LmhlaWdodCksbj1rbn1yZXR1cm4gbi50b0RhdGFVUkwoZSl9c3RhdGljIHNSR0JUb0xpbmVhcih0KXtpZih0eXBlb2YgSFRNTEltYWdlRWxlbWVudCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50fHx0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnR8fHR5cGVvZiBJbWFnZUJpdG1hcCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcCl7Y29uc3QgZT1TYygiY2FudmFzIik7ZS53aWR0aD10LndpZHRoLGUuaGVpZ2h0PXQuaGVpZ2h0O2NvbnN0IG49ZS5nZXRDb250ZXh0KCIyZCIpO24uZHJhd0ltYWdlKHQsMCwwLHQud2lkdGgsdC5oZWlnaHQpO2NvbnN0IHM9bi5nZXRJbWFnZURhdGEoMCwwLHQud2lkdGgsdC5oZWlnaHQpLHI9cy5kYXRhO2ZvcihsZXQgbz0wO288ci5sZW5ndGg7bysrKXJbb109X2UocltvXS8yNTUpKjI1NTtyZXR1cm4gbi5wdXRJbWFnZURhdGEocywwLDApLGV9ZWxzZSBpZih0LmRhdGEpe2NvbnN0IGU9dC5kYXRhLnNsaWNlKDApO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxlIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXk/ZVtuXT1NYXRoLmZsb29yKF9lKGVbbl0vMjU1KSoyNTUpOmVbbl09X2UoZVtuXSk7cmV0dXJue2RhdGE6ZSx3aWR0aDp0LndpZHRoLGhlaWdodDp0LmhlaWdodH19ZWxzZSByZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5JbWFnZVV0aWxzLnNSR0JUb0xpbmVhcigpOiBVbnN1cHBvcnRlZCBpbWFnZSB0eXBlLiBObyBjb2xvciBzcGFjZSBjb252ZXJzaW9uIGFwcGxpZWQuIiksdH19bGV0IGVmPTA7Y2xhc3MgbmZ7Y29uc3RydWN0b3IodD1udWxsKXt0aGlzLmlzU291cmNlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOmVmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLmRhdGE9dCx0aGlzLmRhdGFSZWFkeT0hMCx0aGlzLnZlcnNpb249MH1nZXRTaXplKHQpe2NvbnN0IGU9dGhpcy5kYXRhO3JldHVybiBlIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudD90LnNldChlLnZpZGVvV2lkdGgsZS52aWRlb0hlaWdodCk6ZSE9PW51bGw/dC5zZXQoZS53aWR0aCxlLmhlaWdodCxlLmRlcHRofHwwKTp0LnNldCgwLDAsMCksdH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK310b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQuaW1hZ2VzW3RoaXMudXVpZF0hPT12b2lkIDApcmV0dXJuIHQuaW1hZ2VzW3RoaXMudXVpZF07Y29uc3Qgbj17dXVpZDp0aGlzLnV1aWQsdXJsOiIifSxzPXRoaXMuZGF0YTtpZihzIT09bnVsbCl7bGV0IHI7aWYoQXJyYXkuaXNBcnJheShzKSl7cj1bXTtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTtvKyspc1tvXS5pc0RhdGFUZXh0dXJlP3IucHVzaChzbyhzW29dLmltYWdlKSk6ci5wdXNoKHNvKHNbb10pKX1lbHNlIHI9c28ocyk7bi51cmw9cn1yZXR1cm4gZXx8KHQuaW1hZ2VzW3RoaXMudXVpZF09biksbn19ZnVuY3Rpb24gc28oaSl7cmV0dXJuIHR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50IT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnR8fHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudHx8dHlwZW9mIEltYWdlQml0bWFwIT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEltYWdlQml0bWFwP3RmLmdldERhdGFVUkwoaSk6aS5kYXRhP3tkYXRhOkFycmF5LmZyb20oaS5kYXRhKSx3aWR0aDppLndpZHRoLGhlaWdodDppLmhlaWdodCx0eXBlOmkuZGF0YS5jb25zdHJ1Y3Rvci5uYW1lfTooY29uc29sZS53YXJuKCJUSFJFRS5UZXh0dXJlOiBVbmFibGUgdG8gc2VyaWFsaXplIFRleHR1cmUuIikse30pfWxldCBzZj0wO2NvbnN0IHJvPW5ldyBUO2NsYXNzIGxuIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IodD1sbi5ERUZBVUxUX0lNQUdFLGU9bG4uREVGQVVMVF9NQVBQSU5HLG49MTAwMSxzPTEwMDEscj0xMDA2LG89MTAwOCxhPTEwMjMsYz0xMDA5LGw9bG4uREVGQVVMVF9BTklTT1RST1BZLGg9d2Mpe3N1cGVyKCksdGhpcy5pc1RleHR1cmU9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6c2YrK30pLHRoaXMudXVpZD1GbigpLHRoaXMubmFtZT0iIix0aGlzLnNvdXJjZT1uZXcgbmYodCksdGhpcy5taXBtYXBzPVtdLHRoaXMubWFwcGluZz1lLHRoaXMuY2hhbm5lbD0wLHRoaXMud3JhcFM9bix0aGlzLndyYXBUPXMsdGhpcy5tYWdGaWx0ZXI9cix0aGlzLm1pbkZpbHRlcj1vLHRoaXMuYW5pc290cm9weT1sLHRoaXMuZm9ybWF0PWEsdGhpcy5pbnRlcm5hbEZvcm1hdD1udWxsLHRoaXMudHlwZT1jLHRoaXMub2Zmc2V0PW5ldyBSKDAsMCksdGhpcy5yZXBlYXQ9bmV3IFIoMSwxKSx0aGlzLmNlbnRlcj1uZXcgUigwLDApLHRoaXMucm90YXRpb249MCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9ITAsdGhpcy5tYXRyaXg9bmV3IGdlLHRoaXMuZ2VuZXJhdGVNaXBtYXBzPSEwLHRoaXMucHJlbXVsdGlwbHlBbHBoYT0hMSx0aGlzLmZsaXBZPSEwLHRoaXMudW5wYWNrQWxpZ25tZW50PTQsdGhpcy5jb2xvclNwYWNlPWgsdGhpcy51c2VyRGF0YT17fSx0aGlzLnVwZGF0ZVJhbmdlcz1bXSx0aGlzLnZlcnNpb249MCx0aGlzLm9uVXBkYXRlPW51bGwsdGhpcy5yZW5kZXJUYXJnZXQ9bnVsbCx0aGlzLmlzUmVuZGVyVGFyZ2V0VGV4dHVyZT0hMSx0aGlzLmlzQXJyYXlUZXh0dXJlPSEhKHQmJnQuZGVwdGgmJnQuZGVwdGg+MSksdGhpcy5wbXJlbVZlcnNpb249MH1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy5zb3VyY2UuZ2V0U2l6ZShybykueH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMuc291cmNlLmdldFNpemUocm8pLnl9Z2V0IGRlcHRoKCl7cmV0dXJuIHRoaXMuc291cmNlLmdldFNpemUocm8pLnp9Z2V0IGltYWdlKCl7cmV0dXJuIHRoaXMuc291cmNlLmRhdGF9c2V0IGltYWdlKHQ9bnVsbCl7dGhpcy5zb3VyY2UuZGF0YT10fXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LnNldFV2VHJhbnNmb3JtKHRoaXMub2Zmc2V0LngsdGhpcy5vZmZzZXQueSx0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnksdGhpcy5yb3RhdGlvbix0aGlzLmNlbnRlci54LHRoaXMuY2VudGVyLnkpfWFkZFVwZGF0ZVJhbmdlKHQsZSl7dGhpcy51cGRhdGVSYW5nZXMucHVzaCh7c3RhcnQ6dCxjb3VudDplfSl9Y2xlYXJVcGRhdGVSYW5nZXMoKXt0aGlzLnVwZGF0ZVJhbmdlcy5sZW5ndGg9MH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5uYW1lPXQubmFtZSx0aGlzLnNvdXJjZT10LnNvdXJjZSx0aGlzLm1pcG1hcHM9dC5taXBtYXBzLnNsaWNlKDApLHRoaXMubWFwcGluZz10Lm1hcHBpbmcsdGhpcy5jaGFubmVsPXQuY2hhbm5lbCx0aGlzLndyYXBTPXQud3JhcFMsdGhpcy53cmFwVD10LndyYXBULHRoaXMubWFnRmlsdGVyPXQubWFnRmlsdGVyLHRoaXMubWluRmlsdGVyPXQubWluRmlsdGVyLHRoaXMuYW5pc290cm9weT10LmFuaXNvdHJvcHksdGhpcy5mb3JtYXQ9dC5mb3JtYXQsdGhpcy5pbnRlcm5hbEZvcm1hdD10LmludGVybmFsRm9ybWF0LHRoaXMudHlwZT10LnR5cGUsdGhpcy5vZmZzZXQuY29weSh0Lm9mZnNldCksdGhpcy5yZXBlYXQuY29weSh0LnJlcGVhdCksdGhpcy5jZW50ZXIuY29weSh0LmNlbnRlciksdGhpcy5yb3RhdGlvbj10LnJvdGF0aW9uLHRoaXMubWF0cml4QXV0b1VwZGF0ZT10Lm1hdHJpeEF1dG9VcGRhdGUsdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5nZW5lcmF0ZU1pcG1hcHM9dC5nZW5lcmF0ZU1pcG1hcHMsdGhpcy5wcmVtdWx0aXBseUFscGhhPXQucHJlbXVsdGlwbHlBbHBoYSx0aGlzLmZsaXBZPXQuZmxpcFksdGhpcy51bnBhY2tBbGlnbm1lbnQ9dC51bnBhY2tBbGlnbm1lbnQsdGhpcy5jb2xvclNwYWNlPXQuY29sb3JTcGFjZSx0aGlzLnJlbmRlclRhcmdldD10LnJlbmRlclRhcmdldCx0aGlzLmlzUmVuZGVyVGFyZ2V0VGV4dHVyZT10LmlzUmVuZGVyVGFyZ2V0VGV4dHVyZSx0aGlzLmlzQXJyYXlUZXh0dXJlPXQuaXNBcnJheVRleHR1cmUsdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSx0aGlzLm5lZWRzVXBkYXRlPSEwLHRoaXN9c2V0VmFsdWVzKHQpe2Zvcihjb25zdCBlIGluIHQpe2NvbnN0IG49dFtlXTtpZihuPT09dm9pZCAwKXtjb25zb2xlLndhcm4oYFRIUkVFLlRleHR1cmUuc2V0VmFsdWVzKCk6IHBhcmFtZXRlciAnJHtlfScgaGFzIHZhbHVlIG9mIHVuZGVmaW5lZC5gKTtjb250aW51ZX1jb25zdCBzPXRoaXNbZV07aWYocz09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5UZXh0dXJlLnNldFZhbHVlcygpOiBwcm9wZXJ0eSAnJHtlfScgZG9lcyBub3QgZXhpc3QuYCk7Y29udGludWV9cyYmbiYmcy5pc1ZlY3RvcjImJm4uaXNWZWN0b3IyfHxzJiZuJiZzLmlzVmVjdG9yMyYmbi5pc1ZlY3RvcjN8fHMmJm4mJnMuaXNNYXRyaXgzJiZuLmlzTWF0cml4Mz9zLmNvcHkobik6dGhpc1tlXT1ufX10b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQudGV4dHVyZXNbdGhpcy51dWlkXSE9PXZvaWQgMClyZXR1cm4gdC50ZXh0dXJlc1t0aGlzLnV1aWRdO2NvbnN0IG49e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJUZXh0dXJlIixnZW5lcmF0b3I6IlRleHR1cmUudG9KU09OIn0sdXVpZDp0aGlzLnV1aWQsbmFtZTp0aGlzLm5hbWUsaW1hZ2U6dGhpcy5zb3VyY2UudG9KU09OKHQpLnV1aWQsbWFwcGluZzp0aGlzLm1hcHBpbmcsY2hhbm5lbDp0aGlzLmNoYW5uZWwscmVwZWF0Olt0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnldLG9mZnNldDpbdGhpcy5vZmZzZXQueCx0aGlzLm9mZnNldC55XSxjZW50ZXI6W3RoaXMuY2VudGVyLngsdGhpcy5jZW50ZXIueV0scm90YXRpb246dGhpcy5yb3RhdGlvbix3cmFwOlt0aGlzLndyYXBTLHRoaXMud3JhcFRdLGZvcm1hdDp0aGlzLmZvcm1hdCxpbnRlcm5hbEZvcm1hdDp0aGlzLmludGVybmFsRm9ybWF0LHR5cGU6dGhpcy50eXBlLGNvbG9yU3BhY2U6dGhpcy5jb2xvclNwYWNlLG1pbkZpbHRlcjp0aGlzLm1pbkZpbHRlcixtYWdGaWx0ZXI6dGhpcy5tYWdGaWx0ZXIsYW5pc290cm9weTp0aGlzLmFuaXNvdHJvcHksZmxpcFk6dGhpcy5mbGlwWSxnZW5lcmF0ZU1pcG1hcHM6dGhpcy5nZW5lcmF0ZU1pcG1hcHMscHJlbXVsdGlwbHlBbHBoYTp0aGlzLnByZW11bHRpcGx5QWxwaGEsdW5wYWNrQWxpZ25tZW50OnRoaXMudW5wYWNrQWxpZ25tZW50fTtyZXR1cm4gT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihuLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLGV8fCh0LnRleHR1cmVzW3RoaXMudXVpZF09biksbn1kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfXRyYW5zZm9ybVV2KHQpe2lmKHRoaXMubWFwcGluZyE9PTMwMClyZXR1cm4gdDtpZih0LmFwcGx5TWF0cml4Myh0aGlzLm1hdHJpeCksdC54PDB8fHQueD4xKXN3aXRjaCh0aGlzLndyYXBTKXtjYXNlIDFlMzp0Lng9dC54LU1hdGguZmxvb3IodC54KTticmVhaztjYXNlIDEwMDE6dC54PXQueDwwPzA6MTticmVhaztjYXNlIDEwMDI6TWF0aC5hYnMoTWF0aC5mbG9vcih0LngpJTIpPT09MT90Lng9TWF0aC5jZWlsKHQueCktdC54OnQueD10LngtTWF0aC5mbG9vcih0LngpO2JyZWFrfWlmKHQueTwwfHx0Lnk+MSlzd2l0Y2godGhpcy53cmFwVCl7Y2FzZSAxZTM6dC55PXQueS1NYXRoLmZsb29yKHQueSk7YnJlYWs7Y2FzZSAxMDAxOnQueT10Lnk8MD8wOjE7YnJlYWs7Y2FzZSAxMDAyOk1hdGguYWJzKE1hdGguZmxvb3IodC55KSUyKT09PTE/dC55PU1hdGguY2VpbCh0LnkpLXQueTp0Lnk9dC55LU1hdGguZmxvb3IodC55KTticmVha31yZXR1cm4gdGhpcy5mbGlwWSYmKHQueT0xLXQueSksdH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiYodGhpcy52ZXJzaW9uKyssdGhpcy5zb3VyY2UubmVlZHNVcGRhdGU9ITApfXNldCBuZWVkc1BNUkVNVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy5wbXJlbVZlcnNpb24rK319bG4uREVGQVVMVF9JTUFHRT1udWxsLGxuLkRFRkFVTFRfTUFQUElORz0zMDAsbG4uREVGQVVMVF9BTklTT1RST1BZPTE7Y2xhc3MgWXR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTAscz0xKXtZdC5wcm90b3R5cGUuaXNWZWN0b3I0PSEwLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXMudz1zfWdldCB3aWR0aCgpe3JldHVybiB0aGlzLnp9c2V0IHdpZHRoKHQpe3RoaXMuej10fWdldCBoZWlnaHQoKXtyZXR1cm4gdGhpcy53fXNldCBoZWlnaHQodCl7dGhpcy53PXR9c2V0KHQsZSxuLHMpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzLnc9cyx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpcy56PXQsdGhpcy53PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Wih0KXtyZXR1cm4gdGhpcy56PXQsdGhpc31zZXRXKHQpe3JldHVybiB0aGlzLnc9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztjYXNlIDM6dGhpcy53PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2Nhc2UgMjpyZXR1cm4gdGhpcy56O2Nhc2UgMzpyZXR1cm4gdGhpcy53O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnksdGhpcy56LHRoaXMudyl9Y29weSh0KXtyZXR1cm4gdGhpcy54PXQueCx0aGlzLnk9dC55LHRoaXMuej10LnosdGhpcy53PXQudyE9PXZvaWQgMD90Lnc6MSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpcy56Kz10LnosdGhpcy53Kz10LncsdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpcy56Kz10LHRoaXMudys9dCx0aGlzfWFkZFZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueCtlLngsdGhpcy55PXQueStlLnksdGhpcy56PXQueitlLnosdGhpcy53PXQudytlLncsdGhpc31hZGRTY2FsZWRWZWN0b3IodCxlKXtyZXR1cm4gdGhpcy54Kz10LngqZSx0aGlzLnkrPXQueSplLHRoaXMueis9dC56KmUsdGhpcy53Kz10LncqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpcy56LT10LnosdGhpcy53LT10LncsdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpcy56LT10LHRoaXMudy09dCx0aGlzfXN1YlZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueC1lLngsdGhpcy55PXQueS1lLnksdGhpcy56PXQuei1lLnosdGhpcy53PXQudy1lLncsdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy54Kj10LngsdGhpcy55Kj10LnksdGhpcy56Kj10LnosdGhpcy53Kj10LncsdGhpc31tdWx0aXBseVNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kj10LHRoaXMueSo9dCx0aGlzLnoqPXQsdGhpcy53Kj10LHRoaXN9YXBwbHlNYXRyaXg0KHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dGhpcy56LHI9dGhpcy53LG89dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PW9bMF0qZStvWzRdKm4rb1s4XSpzK29bMTJdKnIsdGhpcy55PW9bMV0qZStvWzVdKm4rb1s5XSpzK29bMTNdKnIsdGhpcy56PW9bMl0qZStvWzZdKm4rb1sxMF0qcytvWzE0XSpyLHRoaXMudz1vWzNdKmUrb1s3XSpuK29bMTFdKnMrb1sxNV0qcix0aGlzfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpcy53Lz10LncsdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1zZXRBeGlzQW5nbGVGcm9tUXVhdGVybmlvbih0KXt0aGlzLnc9MipNYXRoLmFjb3ModC53KTtjb25zdCBlPU1hdGguc3FydCgxLXQudyp0LncpO3JldHVybiBlPDFlLTQ/KHRoaXMueD0xLHRoaXMueT0wLHRoaXMuej0wKToodGhpcy54PXQueC9lLHRoaXMueT10LnkvZSx0aGlzLno9dC56L2UpLHRoaXN9c2V0QXhpc0FuZ2xlRnJvbVJvdGF0aW9uTWF0cml4KHQpe2xldCBlLG4scyxyO2NvbnN0IGM9dC5lbGVtZW50cyxsPWNbMF0saD1jWzRdLHU9Y1s4XSxmPWNbMV0sZD1jWzVdLHA9Y1s5XSx5PWNbMl0sbT1jWzZdLGc9Y1sxMF07aWYoTWF0aC5hYnMoaC1mKTwuMDEmJk1hdGguYWJzKHUteSk8LjAxJiZNYXRoLmFicyhwLW0pPC4wMSl7aWYoTWF0aC5hYnMoaCtmKTwuMSYmTWF0aC5hYnModSt5KTwuMSYmTWF0aC5hYnMocCttKTwuMSYmTWF0aC5hYnMobCtkK2ctMyk8LjEpcmV0dXJuIHRoaXMuc2V0KDEsMCwwLDApLHRoaXM7ZT1NYXRoLlBJO2NvbnN0IHc9KGwrMSkvMix4PShkKzEpLzIsTT0oZysxKS8yLEE9KGgrZikvNCxTPSh1K3kpLzQsXz0ocCttKS80O3JldHVybiB3PngmJnc+TT93PC4wMT8obj0wLHM9LjcwNzEwNjc4MSxyPS43MDcxMDY3ODEpOihuPU1hdGguc3FydCh3KSxzPUEvbixyPVMvbik6eD5NP3g8LjAxPyhuPS43MDcxMDY3ODEscz0wLHI9LjcwNzEwNjc4MSk6KHM9TWF0aC5zcXJ0KHgpLG49QS9zLHI9Xy9zKTpNPC4wMT8obj0uNzA3MTA2NzgxLHM9LjcwNzEwNjc4MSxyPTApOihyPU1hdGguc3FydChNKSxuPVMvcixzPV8vciksdGhpcy5zZXQobixzLHIsZSksdGhpc31sZXQgYj1NYXRoLnNxcnQoKG0tcCkqKG0tcCkrKHUteSkqKHUteSkrKGYtaCkqKGYtaCkpO3JldHVybiBNYXRoLmFicyhiKTwuMDAxJiYoYj0xKSx0aGlzLng9KG0tcCkvYix0aGlzLnk9KHUteSkvYix0aGlzLno9KGYtaCkvYix0aGlzLnc9TWF0aC5hY29zKChsK2QrZy0xKS8yKSx0aGlzfXNldEZyb21NYXRyaXhQb3NpdGlvbih0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1lWzEyXSx0aGlzLnk9ZVsxM10sdGhpcy56PWVbMTRdLHRoaXMudz1lWzE1XSx0aGlzfW1pbih0KXtyZXR1cm4gdGhpcy54PU1hdGgubWluKHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1pbih0aGlzLnksdC55KSx0aGlzLno9TWF0aC5taW4odGhpcy56LHQueiksdGhpcy53PU1hdGgubWluKHRoaXMudyx0LncpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzLnc9TWF0aC5tYXgodGhpcy53LHQudyksdGhpc31jbGFtcCh0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdC54LGUueCksdGhpcy55PVoodGhpcy55LHQueSxlLnkpLHRoaXMuej1aKHRoaXMueix0LnosZS56KSx0aGlzLnc9Wih0aGlzLncsdC53LGUudyksdGhpc31jbGFtcFNjYWxhcih0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdCxlKSx0aGlzLnk9Wih0aGlzLnksdCxlKSx0aGlzLno9Wih0aGlzLnosdCxlKSx0aGlzLnc9Wih0aGlzLncsdCxlKSx0aGlzfWNsYW1wTGVuZ3RoKHQsZSl7Y29uc3Qgbj10aGlzLmxlbmd0aCgpO3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcihufHwxKS5tdWx0aXBseVNjYWxhcihaKG4sdCxlKSl9Zmxvb3IoKXtyZXR1cm4gdGhpcy54PU1hdGguZmxvb3IodGhpcy54KSx0aGlzLnk9TWF0aC5mbG9vcih0aGlzLnkpLHRoaXMuej1NYXRoLmZsb29yKHRoaXMueiksdGhpcy53PU1hdGguZmxvb3IodGhpcy53KSx0aGlzfWNlaWwoKXtyZXR1cm4gdGhpcy54PU1hdGguY2VpbCh0aGlzLngpLHRoaXMueT1NYXRoLmNlaWwodGhpcy55KSx0aGlzLno9TWF0aC5jZWlsKHRoaXMueiksdGhpcy53PU1hdGguY2VpbCh0aGlzLncpLHRoaXN9cm91bmQoKXtyZXR1cm4gdGhpcy54PU1hdGgucm91bmQodGhpcy54KSx0aGlzLnk9TWF0aC5yb3VuZCh0aGlzLnkpLHRoaXMuej1NYXRoLnJvdW5kKHRoaXMueiksdGhpcy53PU1hdGgucm91bmQodGhpcy53KSx0aGlzfXJvdW5kVG9aZXJvKCl7cmV0dXJuIHRoaXMueD1NYXRoLnRydW5jKHRoaXMueCksdGhpcy55PU1hdGgudHJ1bmModGhpcy55KSx0aGlzLno9TWF0aC50cnVuYyh0aGlzLnopLHRoaXMudz1NYXRoLnRydW5jKHRoaXMudyksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpcy53PS10aGlzLncsdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56K3RoaXMudyp0Lnd9bGVuZ3RoU3EoKXtyZXR1cm4gdGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnordGhpcy53KnRoaXMud31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56K3RoaXMudyp0aGlzLncpfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KStNYXRoLmFicyh0aGlzLncpfW5vcm1hbGl6ZSgpe3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcih0aGlzLmxlbmd0aCgpfHwxKX1zZXRMZW5ndGgodCl7cmV0dXJuIHRoaXMubm9ybWFsaXplKCkubXVsdGlwbHlTY2FsYXIodCl9bGVycCh0LGUpe3JldHVybiB0aGlzLngrPSh0LngtdGhpcy54KSplLHRoaXMueSs9KHQueS10aGlzLnkpKmUsdGhpcy56Kz0odC56LXRoaXMueikqZSx0aGlzLncrPSh0LnctdGhpcy53KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpcy56PXQueisoZS56LXQueikqbix0aGlzLnc9dC53KyhlLnctdC53KSpuLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lng9PT10aGlzLngmJnQueT09PXRoaXMueSYmdC56PT09dGhpcy56JiZ0Lnc9PT10aGlzLnd9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXMudz10W2UrM10sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0W2UrMl09dGhpcy56LHRbZSszXT10aGlzLncsdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMueD10LmdldFgoZSksdGhpcy55PXQuZ2V0WShlKSx0aGlzLno9dC5nZXRaKGUpLHRoaXMudz10LmdldFcoZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpcy53PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55LHlpZWxkIHRoaXMueix5aWVsZCB0aGlzLnd9fWNsYXNzIGd0e2NvbnN0cnVjdG9yKHQ9bmV3IFQoMS8wLDEvMCwxLzApLGU9bmV3IFQoLTEvMCwtMS8wLC0xLzApKXt0aGlzLmlzQm94Mz0hMCx0aGlzLm1pbj10LHRoaXMubWF4PWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMubWluLmNvcHkodCksdGhpcy5tYXguY29weShlKSx0aGlzfXNldEZyb21BcnJheSh0KXt0aGlzLm1ha2VFbXB0eSgpO2ZvcihsZXQgZT0wLG49dC5sZW5ndGg7ZTxuO2UrPTMpdGhpcy5leHBhbmRCeVBvaW50KGNlLmZyb21BcnJheSh0LGUpKTtyZXR1cm4gdGhpc31zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHQpe3RoaXMubWFrZUVtcHR5KCk7Zm9yKGxldCBlPTAsbj10LmNvdW50O2U8bjtlKyspdGhpcy5leHBhbmRCeVBvaW50KGNlLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKSk7cmV0dXJuIHRoaXN9c2V0RnJvbVBvaW50cyh0KXt0aGlzLm1ha2VFbXB0eSgpO2ZvcihsZXQgZT0wLG49dC5sZW5ndGg7ZTxuO2UrKyl0aGlzLmV4cGFuZEJ5UG9pbnQodFtlXSk7cmV0dXJuIHRoaXN9c2V0RnJvbUNlbnRlckFuZFNpemUodCxlKXtjb25zdCBuPWNlLmNvcHkoZSkubXVsdGlwbHlTY2FsYXIoLjUpO3JldHVybiB0aGlzLm1pbi5jb3B5KHQpLnN1YihuKSx0aGlzLm1heC5jb3B5KHQpLmFkZChuKSx0aGlzfXNldEZyb21PYmplY3QodCxlPSExKXtyZXR1cm4gdGhpcy5tYWtlRW1wdHkoKSx0aGlzLmV4cGFuZEJ5T2JqZWN0KHQsZSl9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7cmV0dXJuIHRoaXMubWluLmNvcHkodC5taW4pLHRoaXMubWF4LmNvcHkodC5tYXgpLHRoaXN9bWFrZUVtcHR5KCl7cmV0dXJuIHRoaXMubWluLng9dGhpcy5taW4ueT10aGlzLm1pbi56PTEvMCx0aGlzLm1heC54PXRoaXMubWF4Lnk9dGhpcy5tYXguej0tMS8wLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLm1heC54PHRoaXMubWluLnh8fHRoaXMubWF4Lnk8dGhpcy5taW4ueXx8dGhpcy5tYXguejx0aGlzLm1pbi56fWdldENlbnRlcih0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dC5zZXQoMCwwLDApOnQuYWRkVmVjdG9ycyh0aGlzLm1pbix0aGlzLm1heCkubXVsdGlwbHlTY2FsYXIoLjUpfWdldFNpemUodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3Quc2V0KDAsMCwwKTp0LnN1YlZlY3RvcnModGhpcy5tYXgsdGhpcy5taW4pfWV4cGFuZEJ5UG9pbnQodCl7cmV0dXJuIHRoaXMubWluLm1pbih0KSx0aGlzLm1heC5tYXgodCksdGhpc31leHBhbmRCeVZlY3Rvcih0KXtyZXR1cm4gdGhpcy5taW4uc3ViKHQpLHRoaXMubWF4LmFkZCh0KSx0aGlzfWV4cGFuZEJ5U2NhbGFyKHQpe3JldHVybiB0aGlzLm1pbi5hZGRTY2FsYXIoLXQpLHRoaXMubWF4LmFkZFNjYWxhcih0KSx0aGlzfWV4cGFuZEJ5T2JqZWN0KHQsZT0hMSl7dC51cGRhdGVXb3JsZE1hdHJpeCghMSwhMSk7Y29uc3Qgbj10Lmdlb21ldHJ5O2lmKG4hPT12b2lkIDApe2NvbnN0IHI9bi5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIik7aWYoZT09PSEwJiZyIT09dm9pZCAwJiZ0LmlzSW5zdGFuY2VkTWVzaCE9PSEwKWZvcihsZXQgbz0wLGE9ci5jb3VudDtvPGE7bysrKXQuaXNNZXNoPT09ITA/dC5nZXRWZXJ0ZXhQb3NpdGlvbihvLGNlKTpjZS5mcm9tQnVmZmVyQXR0cmlidXRlKHIsbyksY2UuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpLHRoaXMuZXhwYW5kQnlQb2ludChjZSk7ZWxzZSB0LmJvdW5kaW5nQm94IT09dm9pZCAwPyh0LmJvdW5kaW5nQm94PT09bnVsbCYmdC5jb21wdXRlQm91bmRpbmdCb3goKSxhcy5jb3B5KHQuYm91bmRpbmdCb3gpKToobi5ib3VuZGluZ0JveD09PW51bGwmJm4uY29tcHV0ZUJvdW5kaW5nQm94KCksYXMuY29weShuLmJvdW5kaW5nQm94KSksYXMuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpLHRoaXMudW5pb24oYXMpfWNvbnN0IHM9dC5jaGlsZHJlbjtmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKyspdGhpcy5leHBhbmRCeU9iamVjdChzW3JdLGUpO3JldHVybiB0aGlzfWNvbnRhaW5zUG9pbnQodCl7cmV0dXJuIHQueD49dGhpcy5taW4ueCYmdC54PD10aGlzLm1heC54JiZ0Lnk+PXRoaXMubWluLnkmJnQueTw9dGhpcy5tYXgueSYmdC56Pj10aGlzLm1pbi56JiZ0Lno8PXRoaXMubWF4Lnp9Y29udGFpbnNCb3godCl7cmV0dXJuIHRoaXMubWluLng8PXQubWluLngmJnQubWF4Lng8PXRoaXMubWF4LngmJnRoaXMubWluLnk8PXQubWluLnkmJnQubWF4Lnk8PXRoaXMubWF4LnkmJnRoaXMubWluLno8PXQubWluLnomJnQubWF4Lno8PXRoaXMubWF4Lnp9Z2V0UGFyYW1ldGVyKHQsZSl7cmV0dXJuIGUuc2V0KCh0LngtdGhpcy5taW4ueCkvKHRoaXMubWF4LngtdGhpcy5taW4ueCksKHQueS10aGlzLm1pbi55KS8odGhpcy5tYXgueS10aGlzLm1pbi55KSwodC56LXRoaXMubWluLnopLyh0aGlzLm1heC56LXRoaXMubWluLnopKX1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0Lm1heC54Pj10aGlzLm1pbi54JiZ0Lm1pbi54PD10aGlzLm1heC54JiZ0Lm1heC55Pj10aGlzLm1pbi55JiZ0Lm1pbi55PD10aGlzLm1heC55JiZ0Lm1heC56Pj10aGlzLm1pbi56JiZ0Lm1pbi56PD10aGlzLm1heC56fWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHRoaXMuY2xhbXBQb2ludCh0LmNlbnRlcixjZSksY2UuZGlzdGFuY2VUb1NxdWFyZWQodC5jZW50ZXIpPD10LnJhZGl1cyp0LnJhZGl1c31pbnRlcnNlY3RzUGxhbmUodCl7bGV0IGUsbjtyZXR1cm4gdC5ub3JtYWwueD4wPyhlPXQubm9ybWFsLngqdGhpcy5taW4ueCxuPXQubm9ybWFsLngqdGhpcy5tYXgueCk6KGU9dC5ub3JtYWwueCp0aGlzLm1heC54LG49dC5ub3JtYWwueCp0aGlzLm1pbi54KSx0Lm5vcm1hbC55PjA/KGUrPXQubm9ybWFsLnkqdGhpcy5taW4ueSxuKz10Lm5vcm1hbC55KnRoaXMubWF4LnkpOihlKz10Lm5vcm1hbC55KnRoaXMubWF4Lnksbis9dC5ub3JtYWwueSp0aGlzLm1pbi55KSx0Lm5vcm1hbC56PjA/KGUrPXQubm9ybWFsLnoqdGhpcy5taW4ueixuKz10Lm5vcm1hbC56KnRoaXMubWF4LnopOihlKz10Lm5vcm1hbC56KnRoaXMubWF4Lnosbis9dC5ub3JtYWwueip0aGlzLm1pbi56KSxlPD0tdC5jb25zdGFudCYmbj49LXQuY29uc3RhbnR9aW50ZXJzZWN0c1RyaWFuZ2xlKHQpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiExO3RoaXMuZ2V0Q2VudGVyKHhpKSxjcy5zdWJWZWN0b3JzKHRoaXMubWF4LHhpKSxObi5zdWJWZWN0b3JzKHQuYSx4aSksUm4uc3ViVmVjdG9ycyh0LmIseGkpLExuLnN1YlZlY3RvcnModC5jLHhpKSxYZS5zdWJWZWN0b3JzKFJuLE5uKSxKZS5zdWJWZWN0b3JzKExuLFJuKSxobi5zdWJWZWN0b3JzKE5uLExuKTtsZXQgZT1bMCwtWGUueixYZS55LDAsLUplLnosSmUueSwwLC1obi56LGhuLnksWGUueiwwLC1YZS54LEplLnosMCwtSmUueCxobi56LDAsLWhuLngsLVhlLnksWGUueCwwLC1KZS55LEplLngsMCwtaG4ueSxobi54LDBdO3JldHVybiFvbyhlLE5uLFJuLExuLGNzKXx8KGU9WzEsMCwwLDAsMSwwLDAsMCwxXSwhb28oZSxObixSbixMbixjcykpPyExOihscy5jcm9zc1ZlY3RvcnMoWGUsSmUpLGU9W2xzLngsbHMueSxscy56XSxvbyhlLE5uLFJuLExuLGNzKSl9Y2xhbXBQb2ludCh0LGUpe3JldHVybiBlLmNvcHkodCkuY2xhbXAodGhpcy5taW4sdGhpcy5tYXgpfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdGhpcy5jbGFtcFBvaW50KHQsY2UpLmRpc3RhbmNlVG8odCl9Z2V0Qm91bmRpbmdTcGhlcmUodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3QubWFrZUVtcHR5KCk6KHRoaXMuZ2V0Q2VudGVyKHQuY2VudGVyKSx0LnJhZGl1cz10aGlzLmdldFNpemUoY2UpLmxlbmd0aCgpKi41KSx0fWludGVyc2VjdCh0KXtyZXR1cm4gdGhpcy5taW4ubWF4KHQubWluKSx0aGlzLm1heC5taW4odC5tYXgpLHRoaXMuaXNFbXB0eSgpJiZ0aGlzLm1ha2VFbXB0eSgpLHRoaXN9dW5pb24odCl7cmV0dXJuIHRoaXMubWluLm1pbih0Lm1pbiksdGhpcy5tYXgubWF4KHQubWF4KSx0aGlzfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dGhpczoodmVbMF0uc2V0KHRoaXMubWluLngsdGhpcy5taW4ueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbMV0uc2V0KHRoaXMubWluLngsdGhpcy5taW4ueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdmVbMl0uc2V0KHRoaXMubWluLngsdGhpcy5tYXgueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbM10uc2V0KHRoaXMubWluLngsdGhpcy5tYXgueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdmVbNF0uc2V0KHRoaXMubWF4LngsdGhpcy5taW4ueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbNV0uc2V0KHRoaXMubWF4LngsdGhpcy5taW4ueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdmVbNl0uc2V0KHRoaXMubWF4LngsdGhpcy5tYXgueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbN10uc2V0KHRoaXMubWF4LngsdGhpcy5tYXgueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdGhpcy5zZXRGcm9tUG9pbnRzKHZlKSx0aGlzKX10cmFuc2xhdGUodCl7cmV0dXJuIHRoaXMubWluLmFkZCh0KSx0aGlzLm1heC5hZGQodCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQubWluLmVxdWFscyh0aGlzLm1pbikmJnQubWF4LmVxdWFscyh0aGlzLm1heCl9dG9KU09OKCl7cmV0dXJue21pbjp0aGlzLm1pbi50b0FycmF5KCksbWF4OnRoaXMubWF4LnRvQXJyYXkoKX19ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMubWluLmZyb21BcnJheSh0Lm1pbiksdGhpcy5tYXguZnJvbUFycmF5KHQubWF4KSx0aGlzfX1jb25zdCB2ZT1bbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFRdLGNlPW5ldyBULGFzPW5ldyBndCxObj1uZXcgVCxSbj1uZXcgVCxMbj1uZXcgVCxYZT1uZXcgVCxKZT1uZXcgVCxobj1uZXcgVCx4aT1uZXcgVCxjcz1uZXcgVCxscz1uZXcgVCx1bj1uZXcgVDtmdW5jdGlvbiBvbyhpLHQsZSxuLHMpe2ZvcihsZXQgcj0wLG89aS5sZW5ndGgtMztyPD1vO3IrPTMpe3VuLmZyb21BcnJheShpLHIpO2NvbnN0IGE9cy54Kk1hdGguYWJzKHVuLngpK3MueSpNYXRoLmFicyh1bi55KStzLnoqTWF0aC5hYnModW4ueiksYz10LmRvdCh1biksbD1lLmRvdCh1biksaD1uLmRvdCh1bik7aWYoTWF0aC5tYXgoLU1hdGgubWF4KGMsbCxoKSxNYXRoLm1pbihjLGwsaCkpPmEpcmV0dXJuITF9cmV0dXJuITB9Y29uc3QgcmY9bmV3IGd0LHdpPW5ldyBULGFvPW5ldyBUO2NsYXNzIGNve2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT0tMSl7dGhpcy5pc1NwaGVyZT0hMCx0aGlzLmNlbnRlcj10LHRoaXMucmFkaXVzPWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMuY2VudGVyLmNvcHkodCksdGhpcy5yYWRpdXM9ZSx0aGlzfXNldEZyb21Qb2ludHModCxlKXtjb25zdCBuPXRoaXMuY2VudGVyO2UhPT12b2lkIDA/bi5jb3B5KGUpOnJmLnNldEZyb21Qb2ludHModCkuZ2V0Q2VudGVyKG4pO2xldCBzPTA7Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXM9TWF0aC5tYXgocyxuLmRpc3RhbmNlVG9TcXVhcmVkKHRbcl0pKTtyZXR1cm4gdGhpcy5yYWRpdXM9TWF0aC5zcXJ0KHMpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuY29weSh0LmNlbnRlciksdGhpcy5yYWRpdXM9dC5yYWRpdXMsdGhpc31pc0VtcHR5KCl7cmV0dXJuIHRoaXMucmFkaXVzPDB9bWFrZUVtcHR5KCl7cmV0dXJuIHRoaXMuY2VudGVyLnNldCgwLDAsMCksdGhpcy5yYWRpdXM9LTEsdGhpc31jb250YWluc1BvaW50KHQpe3JldHVybiB0LmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuY2VudGVyKTw9dGhpcy5yYWRpdXMqdGhpcy5yYWRpdXN9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiB0LmRpc3RhbmNlVG8odGhpcy5jZW50ZXIpLXRoaXMucmFkaXVzfWludGVyc2VjdHNTcGhlcmUodCl7Y29uc3QgZT10aGlzLnJhZGl1cyt0LnJhZGl1cztyZXR1cm4gdC5jZW50ZXIuZGlzdGFuY2VUb1NxdWFyZWQodGhpcy5jZW50ZXIpPD1lKmV9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdC5pbnRlcnNlY3RzU3BoZXJlKHRoaXMpfWludGVyc2VjdHNQbGFuZSh0KXtyZXR1cm4gTWF0aC5hYnModC5kaXN0YW5jZVRvUG9pbnQodGhpcy5jZW50ZXIpKTw9dGhpcy5yYWRpdXN9Y2xhbXBQb2ludCh0LGUpe2NvbnN0IG49dGhpcy5jZW50ZXIuZGlzdGFuY2VUb1NxdWFyZWQodCk7cmV0dXJuIGUuY29weSh0KSxuPnRoaXMucmFkaXVzKnRoaXMucmFkaXVzJiYoZS5zdWIodGhpcy5jZW50ZXIpLm5vcm1hbGl6ZSgpLGUubXVsdGlwbHlTY2FsYXIodGhpcy5yYWRpdXMpLmFkZCh0aGlzLmNlbnRlcikpLGV9Z2V0Qm91bmRpbmdCb3godCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpPyh0Lm1ha2VFbXB0eSgpLHQpOih0LnNldCh0aGlzLmNlbnRlcix0aGlzLmNlbnRlciksdC5leHBhbmRCeVNjYWxhcih0aGlzLnJhZGl1cyksdCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLmNlbnRlci5hcHBseU1hdHJpeDQodCksdGhpcy5yYWRpdXM9dGhpcy5yYWRpdXMqdC5nZXRNYXhTY2FsZU9uQXhpcygpLHRoaXN9dHJhbnNsYXRlKHQpe3JldHVybiB0aGlzLmNlbnRlci5hZGQodCksdGhpc31leHBhbmRCeVBvaW50KHQpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiB0aGlzLmNlbnRlci5jb3B5KHQpLHRoaXMucmFkaXVzPTAsdGhpczt3aS5zdWJWZWN0b3JzKHQsdGhpcy5jZW50ZXIpO2NvbnN0IGU9d2kubGVuZ3RoU3EoKTtpZihlPnRoaXMucmFkaXVzKnRoaXMucmFkaXVzKXtjb25zdCBuPU1hdGguc3FydChlKSxzPShuLXRoaXMucmFkaXVzKSouNTt0aGlzLmNlbnRlci5hZGRTY2FsZWRWZWN0b3Iod2kscy9uKSx0aGlzLnJhZGl1cys9c31yZXR1cm4gdGhpc311bmlvbih0KXtyZXR1cm4gdC5pc0VtcHR5KCk/dGhpczp0aGlzLmlzRW1wdHkoKT8odGhpcy5jb3B5KHQpLHRoaXMpOih0aGlzLmNlbnRlci5lcXVhbHModC5jZW50ZXIpPT09ITA/dGhpcy5yYWRpdXM9TWF0aC5tYXgodGhpcy5yYWRpdXMsdC5yYWRpdXMpOihhby5zdWJWZWN0b3JzKHQuY2VudGVyLHRoaXMuY2VudGVyKS5zZXRMZW5ndGgodC5yYWRpdXMpLHRoaXMuZXhwYW5kQnlQb2ludCh3aS5jb3B5KHQuY2VudGVyKS5hZGQoYW8pKSx0aGlzLmV4cGFuZEJ5UG9pbnQod2kuY29weSh0LmNlbnRlcikuc3ViKGFvKSkpLHRoaXMpfWVxdWFscyh0KXtyZXR1cm4gdC5jZW50ZXIuZXF1YWxzKHRoaXMuY2VudGVyKSYmdC5yYWRpdXM9PT10aGlzLnJhZGl1c31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9dG9KU09OKCl7cmV0dXJue3JhZGl1czp0aGlzLnJhZGl1cyxjZW50ZXI6dGhpcy5jZW50ZXIudG9BcnJheSgpfX1mcm9tSlNPTih0KXtyZXR1cm4gdGhpcy5yYWRpdXM9dC5yYWRpdXMsdGhpcy5jZW50ZXIuZnJvbUFycmF5KHQuY2VudGVyKSx0aGlzfX1jb25zdCB6ZT1uZXcgVCxsbz1uZXcgVCxocz1uZXcgVCxZZT1uZXcgVCxobz1uZXcgVCx1cz1uZXcgVCx1bz1uZXcgVDtjbGFzcyBmb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQoMCwwLC0xKSl7dGhpcy5vcmlnaW49dCx0aGlzLmRpcmVjdGlvbj1lfXNldCh0LGUpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQpLHRoaXMuZGlyZWN0aW9uLmNvcHkoZSksdGhpc31jb3B5KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQub3JpZ2luKSx0aGlzLmRpcmVjdGlvbi5jb3B5KHQuZGlyZWN0aW9uKSx0aGlzfWF0KHQsZSl7cmV0dXJuIGUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLHQpfWxvb2tBdCh0KXtyZXR1cm4gdGhpcy5kaXJlY3Rpb24uY29weSh0KS5zdWIodGhpcy5vcmlnaW4pLm5vcm1hbGl6ZSgpLHRoaXN9cmVjYXN0KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHRoaXMuYXQodCx6ZSkpLHRoaXN9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUpe2Uuc3ViVmVjdG9ycyh0LHRoaXMub3JpZ2luKTtjb25zdCBuPWUuZG90KHRoaXMuZGlyZWN0aW9uKTtyZXR1cm4gbjwwP2UuY29weSh0aGlzLm9yaWdpbik6ZS5jb3B5KHRoaXMub3JpZ2luKS5hZGRTY2FsZWRWZWN0b3IodGhpcy5kaXJlY3Rpb24sbil9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVNxVG9Qb2ludCh0KSl9ZGlzdGFuY2VTcVRvUG9pbnQodCl7Y29uc3QgZT16ZS5zdWJWZWN0b3JzKHQsdGhpcy5vcmlnaW4pLmRvdCh0aGlzLmRpcmVjdGlvbik7cmV0dXJuIGU8MD90aGlzLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZCh0KTooemUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLGUpLHplLmRpc3RhbmNlVG9TcXVhcmVkKHQpKX1kaXN0YW5jZVNxVG9TZWdtZW50KHQsZSxuLHMpe2xvLmNvcHkodCkuYWRkKGUpLm11bHRpcGx5U2NhbGFyKC41KSxocy5jb3B5KGUpLnN1Yih0KS5ub3JtYWxpemUoKSxZZS5jb3B5KHRoaXMub3JpZ2luKS5zdWIobG8pO2NvbnN0IHI9dC5kaXN0YW5jZVRvKGUpKi41LG89LXRoaXMuZGlyZWN0aW9uLmRvdChocyksYT1ZZS5kb3QodGhpcy5kaXJlY3Rpb24pLGM9LVllLmRvdChocyksbD1ZZS5sZW5ndGhTcSgpLGg9TWF0aC5hYnMoMS1vKm8pO2xldCB1LGYsZCxwO2lmKGg+MClpZih1PW8qYy1hLGY9byphLWMscD1yKmgsdT49MClpZihmPj0tcClpZihmPD1wKXtjb25zdCB5PTEvaDt1Kj15LGYqPXksZD11Kih1K28qZisyKmEpK2YqKG8qdStmKzIqYykrbH1lbHNlIGY9cix1PU1hdGgubWF4KDAsLShvKmYrYSkpLGQ9LXUqdStmKihmKzIqYykrbDtlbHNlIGY9LXIsdT1NYXRoLm1heCgwLC0obypmK2EpKSxkPS11KnUrZiooZisyKmMpK2w7ZWxzZSBmPD0tcD8odT1NYXRoLm1heCgwLC0oLW8qcithKSksZj11PjA/LXI6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk6Zjw9cD8odT0wLGY9TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9ZiooZisyKmMpK2wpOih1PU1hdGgubWF4KDAsLShvKnIrYSkpLGY9dT4wP3I6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk7ZWxzZSBmPW8+MD8tcjpyLHU9TWF0aC5tYXgoMCwtKG8qZithKSksZD0tdSp1K2YqKGYrMipjKStsO3JldHVybiBuJiZuLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbix1KSxzJiZzLmNvcHkobG8pLmFkZFNjYWxlZFZlY3RvcihocyxmKSxkfWludGVyc2VjdFNwaGVyZSh0LGUpe3plLnN1YlZlY3RvcnModC5jZW50ZXIsdGhpcy5vcmlnaW4pO2NvbnN0IG49emUuZG90KHRoaXMuZGlyZWN0aW9uKSxzPXplLmRvdCh6ZSktbipuLHI9dC5yYWRpdXMqdC5yYWRpdXM7aWYocz5yKXJldHVybiBudWxsO2NvbnN0IG89TWF0aC5zcXJ0KHItcyksYT1uLW8sYz1uK287cmV0dXJuIGM8MD9udWxsOmE8MD90aGlzLmF0KGMsZSk6dGhpcy5hdChhLGUpfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHQucmFkaXVzPDA/ITE6dGhpcy5kaXN0YW5jZVNxVG9Qb2ludCh0LmNlbnRlcik8PXQucmFkaXVzKnQucmFkaXVzfWRpc3RhbmNlVG9QbGFuZSh0KXtjb25zdCBlPXQubm9ybWFsLmRvdCh0aGlzLmRpcmVjdGlvbik7aWYoZT09PTApcmV0dXJuIHQuZGlzdGFuY2VUb1BvaW50KHRoaXMub3JpZ2luKT09PTA/MDpudWxsO2NvbnN0IG49LSh0aGlzLm9yaWdpbi5kb3QodC5ub3JtYWwpK3QuY29uc3RhbnQpL2U7cmV0dXJuIG4+PTA/bjpudWxsfWludGVyc2VjdFBsYW5lKHQsZSl7Y29uc3Qgbj10aGlzLmRpc3RhbmNlVG9QbGFuZSh0KTtyZXR1cm4gbj09PW51bGw/bnVsbDp0aGlzLmF0KG4sZSl9aW50ZXJzZWN0c1BsYW5lKHQpe2NvbnN0IGU9dC5kaXN0YW5jZVRvUG9pbnQodGhpcy5vcmlnaW4pO3JldHVybiBlPT09MHx8dC5ub3JtYWwuZG90KHRoaXMuZGlyZWN0aW9uKSplPDB9aW50ZXJzZWN0Qm94KHQsZSl7bGV0IG4scyxyLG8sYSxjO2NvbnN0IGw9MS90aGlzLmRpcmVjdGlvbi54LGg9MS90aGlzLmRpcmVjdGlvbi55LHU9MS90aGlzLmRpcmVjdGlvbi56LGY9dGhpcy5vcmlnaW47cmV0dXJuIGw+PTA/KG49KHQubWluLngtZi54KSpsLHM9KHQubWF4LngtZi54KSpsKToobj0odC5tYXgueC1mLngpKmwscz0odC5taW4ueC1mLngpKmwpLGg+PTA/KHI9KHQubWluLnktZi55KSpoLG89KHQubWF4LnktZi55KSpoKToocj0odC5tYXgueS1mLnkpKmgsbz0odC5taW4ueS1mLnkpKmgpLG4+b3x8cj5zfHwoKHI+bnx8aXNOYU4obikpJiYobj1yKSwobzxzfHxpc05hTihzKSkmJihzPW8pLHU+PTA/KGE9KHQubWluLnotZi56KSp1LGM9KHQubWF4LnotZi56KSp1KTooYT0odC5tYXguei1mLnopKnUsYz0odC5taW4uei1mLnopKnUpLG4+Y3x8YT5zKXx8KChhPm58fG4hPT1uKSYmKG49YSksKGM8c3x8cyE9PXMpJiYocz1jKSxzPDApP251bGw6dGhpcy5hdChuPj0wP246cyxlKX1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0aGlzLmludGVyc2VjdEJveCh0LHplKSE9PW51bGx9aW50ZXJzZWN0VHJpYW5nbGUodCxlLG4scyxyKXtoby5zdWJWZWN0b3JzKGUsdCksdXMuc3ViVmVjdG9ycyhuLHQpLHVvLmNyb3NzVmVjdG9ycyhobyx1cyk7bGV0IG89dGhpcy5kaXJlY3Rpb24uZG90KHVvKSxhO2lmKG8+MCl7aWYocylyZXR1cm4gbnVsbDthPTF9ZWxzZSBpZihvPDApYT0tMSxvPS1vO2Vsc2UgcmV0dXJuIG51bGw7WWUuc3ViVmVjdG9ycyh0aGlzLm9yaWdpbix0KTtjb25zdCBjPWEqdGhpcy5kaXJlY3Rpb24uZG90KHVzLmNyb3NzVmVjdG9ycyhZZSx1cykpO2lmKGM8MClyZXR1cm4gbnVsbDtjb25zdCBsPWEqdGhpcy5kaXJlY3Rpb24uZG90KGhvLmNyb3NzKFllKSk7aWYobDwwfHxjK2w+bylyZXR1cm4gbnVsbDtjb25zdCBoPS1hKlllLmRvdCh1byk7cmV0dXJuIGg8MD9udWxsOnRoaXMuYXQoaC9vLHIpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5vcmlnaW4uYXBwbHlNYXRyaXg0KHQpLHRoaXMuZGlyZWN0aW9uLnRyYW5zZm9ybURpcmVjdGlvbih0KSx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5vcmlnaW4uZXF1YWxzKHRoaXMub3JpZ2luKSYmdC5kaXJlY3Rpb24uZXF1YWxzKHRoaXMuZGlyZWN0aW9uKX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9fWNsYXNzIHN0e2NvbnN0cnVjdG9yKHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pe3N0LnByb3RvdHlwZS5pc01hdHJpeDQ9ITAsdGhpcy5lbGVtZW50cz1bMSwwLDAsMCwwLDEsMCwwLDAsMCwxLDAsMCwwLDAsMV0sdCE9PXZvaWQgMCYmdGhpcy5zZXQodCxlLG4scyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbSl9c2V0KHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pe2NvbnN0IGc9dGhpcy5lbGVtZW50cztyZXR1cm4gZ1swXT10LGdbNF09ZSxnWzhdPW4sZ1sxMl09cyxnWzFdPXIsZ1s1XT1vLGdbOV09YSxnWzEzXT1jLGdbMl09bCxnWzZdPWgsZ1sxMF09dSxnWzE0XT1mLGdbM109ZCxnWzddPXAsZ1sxMV09eSxnWzE1XT1tLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwwLDEsMCwwLDAsMCwxLDAsMCwwLDAsMSksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgc3QoKS5mcm9tQXJyYXkodGhpcy5lbGVtZW50cyl9Y29weSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzO3JldHVybiBlWzBdPW5bMF0sZVsxXT1uWzFdLGVbMl09blsyXSxlWzNdPW5bM10sZVs0XT1uWzRdLGVbNV09bls1XSxlWzZdPW5bNl0sZVs3XT1uWzddLGVbOF09bls4XSxlWzldPW5bOV0sZVsxMF09blsxMF0sZVsxMV09blsxMV0sZVsxMl09blsxMl0sZVsxM109blsxM10sZVsxNF09blsxNF0sZVsxNV09blsxNV0sdGhpc31jb3B5UG9zaXRpb24odCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVsxMl09blsxMl0sZVsxM109blsxM10sZVsxNF09blsxNF0sdGhpc31zZXRGcm9tTWF0cml4Myh0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMuc2V0KGVbMF0sZVszXSxlWzZdLDAsZVsxXSxlWzRdLGVbN10sMCxlWzJdLGVbNV0sZVs4XSwwLDAsMCwwLDEpLHRoaXN9ZXh0cmFjdEJhc2lzKHQsZSxuKXtyZXR1cm4gdC5zZXRGcm9tTWF0cml4Q29sdW1uKHRoaXMsMCksZS5zZXRGcm9tTWF0cml4Q29sdW1uKHRoaXMsMSksbi5zZXRGcm9tTWF0cml4Q29sdW1uKHRoaXMsMiksdGhpc31tYWtlQmFzaXModCxlLG4pe3JldHVybiB0aGlzLnNldCh0LngsZS54LG4ueCwwLHQueSxlLnksbi55LDAsdC56LGUueixuLnosMCwwLDAsMCwxKSx0aGlzfWV4dHJhY3RSb3RhdGlvbih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzLHM9MS9Pbi5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMCkubGVuZ3RoKCkscj0xL09uLnNldEZyb21NYXRyaXhDb2x1bW4odCwxKS5sZW5ndGgoKSxvPTEvT24uc2V0RnJvbU1hdHJpeENvbHVtbih0LDIpLmxlbmd0aCgpO3JldHVybiBlWzBdPW5bMF0qcyxlWzFdPW5bMV0qcyxlWzJdPW5bMl0qcyxlWzNdPTAsZVs0XT1uWzRdKnIsZVs1XT1uWzVdKnIsZVs2XT1uWzZdKnIsZVs3XT0wLGVbOF09bls4XSpvLGVbOV09bls5XSpvLGVbMTBdPW5bMTBdKm8sZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLHRoaXN9bWFrZVJvdGF0aW9uRnJvbUV1bGVyKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQueCxzPXQueSxyPXQueixvPU1hdGguY29zKG4pLGE9TWF0aC5zaW4obiksYz1NYXRoLmNvcyhzKSxsPU1hdGguc2luKHMpLGg9TWF0aC5jb3MociksdT1NYXRoLnNpbihyKTtpZih0Lm9yZGVyPT09IlhZWiIpe2NvbnN0IGY9bypoLGQ9byp1LHA9YSpoLHk9YSp1O2VbMF09YypoLGVbNF09LWMqdSxlWzhdPWwsZVsxXT1kK3AqbCxlWzVdPWYteSpsLGVbOV09LWEqYyxlWzJdPXktZipsLGVbNl09cCtkKmwsZVsxMF09bypjfWVsc2UgaWYodC5vcmRlcj09PSJZWFoiKXtjb25zdCBmPWMqaCxkPWMqdSxwPWwqaCx5PWwqdTtlWzBdPWYreSphLGVbNF09cCphLWQsZVs4XT1vKmwsZVsxXT1vKnUsZVs1XT1vKmgsZVs5XT0tYSxlWzJdPWQqYS1wLGVbNl09eStmKmEsZVsxMF09bypjfWVsc2UgaWYodC5vcmRlcj09PSJaWFkiKXtjb25zdCBmPWMqaCxkPWMqdSxwPWwqaCx5PWwqdTtlWzBdPWYteSphLGVbNF09LW8qdSxlWzhdPXArZCphLGVbMV09ZCtwKmEsZVs1XT1vKmgsZVs5XT15LWYqYSxlWzJdPS1vKmwsZVs2XT1hLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWllYIil7Y29uc3QgZj1vKmgsZD1vKnUscD1hKmgseT1hKnU7ZVswXT1jKmgsZVs0XT1wKmwtZCxlWzhdPWYqbCt5LGVbMV09Yyp1LGVbNV09eSpsK2YsZVs5XT1kKmwtcCxlWzJdPS1sLGVbNl09YSpjLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWVpYIil7Y29uc3QgZj1vKmMsZD1vKmwscD1hKmMseT1hKmw7ZVswXT1jKmgsZVs0XT15LWYqdSxlWzhdPXAqdStkLGVbMV09dSxlWzVdPW8qaCxlWzldPS1hKmgsZVsyXT0tbCpoLGVbNl09ZCp1K3AsZVsxMF09Zi15KnV9ZWxzZSBpZih0Lm9yZGVyPT09IlhaWSIpe2NvbnN0IGY9bypjLGQ9bypsLHA9YSpjLHk9YSpsO2VbMF09YypoLGVbNF09LXUsZVs4XT1sKmgsZVsxXT1mKnUreSxlWzVdPW8qaCxlWzldPWQqdS1wLGVbMl09cCp1LWQsZVs2XT1hKmgsZVsxMF09eSp1K2Z9cmV0dXJuIGVbM109MCxlWzddPTAsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLHRoaXN9bWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCl7cmV0dXJuIHRoaXMuY29tcG9zZShvZix0LGFmKX1sb29rQXQodCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cztyZXR1cm4gJHQuc3ViVmVjdG9ycyh0LGUpLCR0Lmxlbmd0aFNxKCk9PT0wJiYoJHQuej0xKSwkdC5ub3JtYWxpemUoKSxqZS5jcm9zc1ZlY3RvcnMobiwkdCksamUubGVuZ3RoU3EoKT09PTAmJihNYXRoLmFicyhuLnopPT09MT8kdC54Kz0xZS00OiR0LnorPTFlLTQsJHQubm9ybWFsaXplKCksamUuY3Jvc3NWZWN0b3JzKG4sJHQpKSxqZS5ub3JtYWxpemUoKSxmcy5jcm9zc1ZlY3RvcnMoJHQsamUpLHNbMF09amUueCxzWzRdPWZzLngsc1s4XT0kdC54LHNbMV09amUueSxzWzVdPWZzLnksc1s5XT0kdC55LHNbMl09amUueixzWzZdPWZzLnosc1sxMF09JHQueix0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXModGhpcyx0KX1wcmVtdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHQsdGhpcyl9bXVsdGlwbHlNYXRyaWNlcyh0LGUpe2NvbnN0IG49dC5lbGVtZW50cyxzPWUuZWxlbWVudHMscj10aGlzLmVsZW1lbnRzLG89blswXSxhPW5bNF0sYz1uWzhdLGw9blsxMl0saD1uWzFdLHU9bls1XSxmPW5bOV0sZD1uWzEzXSxwPW5bMl0seT1uWzZdLG09blsxMF0sZz1uWzE0XSxiPW5bM10sdz1uWzddLHg9blsxMV0sTT1uWzE1XSxBPXNbMF0sUz1zWzRdLF89c1s4XSxFPXNbMTJdLHo9c1sxXSx2PXNbNV0sQz1zWzldLFA9c1sxM10sRj1zWzJdLEI9c1s2XSxJPXNbMTBdLGs9c1sxNF0sRD1zWzNdLFU9c1s3XSxqPXNbMTFdLGR0PXNbMTVdO3JldHVybiByWzBdPW8qQSthKnorYypGK2wqRCxyWzRdPW8qUythKnYrYypCK2wqVSxyWzhdPW8qXythKkMrYypJK2wqaixyWzEyXT1vKkUrYSpQK2MqaytsKmR0LHJbMV09aCpBK3UqeitmKkYrZCpELHJbNV09aCpTK3UqditmKkIrZCpVLHJbOV09aCpfK3UqQytmKkkrZCpqLHJbMTNdPWgqRSt1KlArZiprK2QqZHQsclsyXT1wKkEreSp6K20qRitnKkQscls2XT1wKlMreSp2K20qQitnKlUsclsxMF09cCpfK3kqQyttKkkrZypqLHJbMTRdPXAqRSt5KlArbSprK2cqZHQsclszXT1iKkErdyp6K3gqRitNKkQscls3XT1iKlMrdyp2K3gqQitNKlUsclsxMV09YipfK3cqQyt4KkkrTSpqLHJbMTVdPWIqRSt3KlAreCprK00qZHQsdGhpc31tdWx0aXBseVNjYWxhcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIGVbMF0qPXQsZVs0XSo9dCxlWzhdKj10LGVbMTJdKj10LGVbMV0qPXQsZVs1XSo9dCxlWzldKj10LGVbMTNdKj10LGVbMl0qPXQsZVs2XSo9dCxlWzEwXSo9dCxlWzE0XSo9dCxlWzNdKj10LGVbN10qPXQsZVsxMV0qPXQsZVsxNV0qPXQsdGhpc31kZXRlcm1pbmFudCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzRdLHM9dFs4XSxyPXRbMTJdLG89dFsxXSxhPXRbNV0sYz10WzldLGw9dFsxM10saD10WzJdLHU9dFs2XSxmPXRbMTBdLGQ9dFsxNF0scD10WzNdLHk9dFs3XSxtPXRbMTFdLGc9dFsxNV07cmV0dXJuIHAqKCtyKmMqdS1zKmwqdS1yKmEqZituKmwqZitzKmEqZC1uKmMqZCkreSooK2UqYypkLWUqbCpmK3IqbypmLXMqbypkK3MqbCpoLXIqYypoKSttKigrZSpsKnUtZSphKmQtcipvKnUrbipvKmQrciphKmgtbipsKmgpK2cqKC1zKmEqaC1lKmMqdStlKmEqZitzKm8qdS1uKm8qZituKmMqaCl9dHJhbnNwb3NlKCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzO2xldCBlO3JldHVybiBlPXRbMV0sdFsxXT10WzRdLHRbNF09ZSxlPXRbMl0sdFsyXT10WzhdLHRbOF09ZSxlPXRbNl0sdFs2XT10WzldLHRbOV09ZSxlPXRbM10sdFszXT10WzEyXSx0WzEyXT1lLGU9dFs3XSx0WzddPXRbMTNdLHRbMTNdPWUsZT10WzExXSx0WzExXT10WzE0XSx0WzE0XT1lLHRoaXN9c2V0UG9zaXRpb24odCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cztyZXR1cm4gdC5pc1ZlY3RvcjM/KHNbMTJdPXQueCxzWzEzXT10Lnksc1sxNF09dC56KTooc1sxMl09dCxzWzEzXT1lLHNbMTRdPW4pLHRoaXN9aW52ZXJ0KCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzLGU9dFswXSxuPXRbMV0scz10WzJdLHI9dFszXSxvPXRbNF0sYT10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdLHU9dFs5XSxmPXRbMTBdLGQ9dFsxMV0scD10WzEyXSx5PXRbMTNdLG09dFsxNF0sZz10WzE1XSxiPXUqbSpsLXkqZipsK3kqYypkLWEqbSpkLXUqYypnK2EqZipnLHc9cCpmKmwtaCptKmwtcCpjKmQrbyptKmQraCpjKmctbypmKmcseD1oKnkqbC1wKnUqbCtwKmEqZC1vKnkqZC1oKmEqZytvKnUqZyxNPXAqdSpjLWgqeSpjLXAqYSpmK28qeSpmK2gqYSptLW8qdSptLEE9ZSpiK24qdytzKngrcipNO2lmKEE9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwKTtjb25zdCBTPTEvQTtyZXR1cm4gdFswXT1iKlMsdFsxXT0oeSpmKnItdSptKnIteSpzKmQrbiptKmQrdSpzKmctbipmKmcpKlMsdFsyXT0oYSptKnIteSpjKnIreSpzKmwtbiptKmwtYSpzKmcrbipjKmcpKlMsdFszXT0odSpjKnItYSpmKnItdSpzKmwrbipmKmwrYSpzKmQtbipjKmQpKlMsdFs0XT13KlMsdFs1XT0oaCptKnItcCpmKnIrcCpzKmQtZSptKmQtaCpzKmcrZSpmKmcpKlMsdFs2XT0ocCpjKnItbyptKnItcCpzKmwrZSptKmwrbypzKmctZSpjKmcpKlMsdFs3XT0obypmKnItaCpjKnIraCpzKmwtZSpmKmwtbypzKmQrZSpjKmQpKlMsdFs4XT14KlMsdFs5XT0ocCp1KnItaCp5KnItcCpuKmQrZSp5KmQraCpuKmctZSp1KmcpKlMsdFsxMF09KG8qeSpyLXAqYSpyK3AqbipsLWUqeSpsLW8qbipnK2UqYSpnKSpTLHRbMTFdPShoKmEqci1vKnUqci1oKm4qbCtlKnUqbCtvKm4qZC1lKmEqZCkqUyx0WzEyXT1NKlMsdFsxM109KGgqeSpzLXAqdSpzK3AqbipmLWUqeSpmLWgqbiptK2UqdSptKSpTLHRbMTRdPShwKmEqcy1vKnkqcy1wKm4qYytlKnkqYytvKm4qbS1lKmEqbSkqUyx0WzE1XT0obyp1KnMtaCphKnMraCpuKmMtZSp1KmMtbypuKmYrZSphKmYpKlMsdGhpc31zY2FsZSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10Lngscz10Lnkscj10Lno7cmV0dXJuIGVbMF0qPW4sZVs0XSo9cyxlWzhdKj1yLGVbMV0qPW4sZVs1XSo9cyxlWzldKj1yLGVbMl0qPW4sZVs2XSo9cyxlWzEwXSo9cixlWzNdKj1uLGVbN10qPXMsZVsxMV0qPXIsdGhpc31nZXRNYXhTY2FsZU9uQXhpcygpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0qdFswXSt0WzFdKnRbMV0rdFsyXSp0WzJdLG49dFs0XSp0WzRdK3RbNV0qdFs1XSt0WzZdKnRbNl0scz10WzhdKnRbOF0rdFs5XSp0WzldK3RbMTBdKnRbMTBdO3JldHVybiBNYXRoLnNxcnQoTWF0aC5tYXgoZSxuLHMpKX1tYWtlVHJhbnNsYXRpb24odCxlLG4pe3JldHVybiB0LmlzVmVjdG9yMz90aGlzLnNldCgxLDAsMCx0LngsMCwxLDAsdC55LDAsMCwxLHQueiwwLDAsMCwxKTp0aGlzLnNldCgxLDAsMCx0LDAsMSwwLGUsMCwwLDEsbiwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvblgodCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldCgxLDAsMCwwLDAsZSwtbiwwLDAsbixlLDAsMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25ZKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoZSwwLG4sMCwwLDEsMCwwLC1uLDAsZSwwLDAsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uWih0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsLW4sMCwwLG4sZSwwLDAsMCwwLDEsMCwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbkF4aXModCxlKXtjb25zdCBuPU1hdGguY29zKGUpLHM9TWF0aC5zaW4oZSkscj0xLW4sbz10LngsYT10LnksYz10LnosbD1yKm8saD1yKmE7cmV0dXJuIHRoaXMuc2V0KGwqbytuLGwqYS1zKmMsbCpjK3MqYSwwLGwqYStzKmMsaCphK24saCpjLXMqbywwLGwqYy1zKmEsaCpjK3MqbyxyKmMqYytuLDAsMCwwLDAsMSksdGhpc31tYWtlU2NhbGUodCxlLG4pe3JldHVybiB0aGlzLnNldCh0LDAsMCwwLDAsZSwwLDAsMCwwLG4sMCwwLDAsMCwxKSx0aGlzfW1ha2VTaGVhcih0LGUsbixzLHIsbyl7cmV0dXJuIHRoaXMuc2V0KDEsbixyLDAsdCwxLG8sMCxlLHMsMSwwLDAsMCwwLDEpLHRoaXN9Y29tcG9zZSh0LGUsbil7Y29uc3Qgcz10aGlzLmVsZW1lbnRzLHI9ZS5feCxvPWUuX3ksYT1lLl96LGM9ZS5fdyxsPXIrcixoPW8rbyx1PWErYSxmPXIqbCxkPXIqaCxwPXIqdSx5PW8qaCxtPW8qdSxnPWEqdSxiPWMqbCx3PWMqaCx4PWMqdSxNPW4ueCxBPW4ueSxTPW4uejtyZXR1cm4gc1swXT0oMS0oeStnKSkqTSxzWzFdPShkK3gpKk0sc1syXT0ocC13KSpNLHNbM109MCxzWzRdPShkLXgpKkEsc1s1XT0oMS0oZitnKSkqQSxzWzZdPShtK2IpKkEsc1s3XT0wLHNbOF09KHArdykqUyxzWzldPShtLWIpKlMsc1sxMF09KDEtKGYreSkpKlMsc1sxMV09MCxzWzEyXT10Lngsc1sxM109dC55LHNbMTRdPXQueixzWzE1XT0xLHRoaXN9ZGVjb21wb3NlKHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7bGV0IHI9T24uc2V0KHNbMF0sc1sxXSxzWzJdKS5sZW5ndGgoKTtjb25zdCBvPU9uLnNldChzWzRdLHNbNV0sc1s2XSkubGVuZ3RoKCksYT1Pbi5zZXQoc1s4XSxzWzldLHNbMTBdKS5sZW5ndGgoKTt0aGlzLmRldGVybWluYW50KCk8MCYmKHI9LXIpLHQueD1zWzEyXSx0Lnk9c1sxM10sdC56PXNbMTRdLGxlLmNvcHkodGhpcyk7Y29uc3QgbD0xL3IsaD0xL28sdT0xL2E7cmV0dXJuIGxlLmVsZW1lbnRzWzBdKj1sLGxlLmVsZW1lbnRzWzFdKj1sLGxlLmVsZW1lbnRzWzJdKj1sLGxlLmVsZW1lbnRzWzRdKj1oLGxlLmVsZW1lbnRzWzVdKj1oLGxlLmVsZW1lbnRzWzZdKj1oLGxlLmVsZW1lbnRzWzhdKj11LGxlLmVsZW1lbnRzWzldKj11LGxlLmVsZW1lbnRzWzEwXSo9dSxlLnNldEZyb21Sb3RhdGlvbk1hdHJpeChsZSksbi54PXIsbi55PW8sbi56PWEsdGhpc31tYWtlUGVyc3BlY3RpdmUodCxlLG4scyxyLG8sYT0yZTMpe2NvbnN0IGM9dGhpcy5lbGVtZW50cyxsPTIqci8oZS10KSxoPTIqci8obi1zKSx1PShlK3QpLyhlLXQpLGY9KG4rcykvKG4tcyk7bGV0IGQscDtpZihhPT09MmUzKWQ9LShvK3IpLyhvLXIpLHA9LTIqbypyLyhvLXIpO2Vsc2UgaWYoYT09PTIwMDEpZD0tby8oby1yKSxwPS1vKnIvKG8tcik7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIlRIUkVFLk1hdHJpeDQubWFrZVBlcnNwZWN0aXZlKCk6IEludmFsaWQgY29vcmRpbmF0ZSBzeXN0ZW06ICIrYSk7cmV0dXJuIGNbMF09bCxjWzRdPTAsY1s4XT11LGNbMTJdPTAsY1sxXT0wLGNbNV09aCxjWzldPWYsY1sxM109MCxjWzJdPTAsY1s2XT0wLGNbMTBdPWQsY1sxNF09cCxjWzNdPTAsY1s3XT0wLGNbMTFdPS0xLGNbMTVdPTAsdGhpc31tYWtlT3J0aG9ncmFwaGljKHQsZSxuLHMscixvLGE9MmUzKXtjb25zdCBjPXRoaXMuZWxlbWVudHMsbD0xLyhlLXQpLGg9MS8obi1zKSx1PTEvKG8tciksZj0oZSt0KSpsLGQ9KG4rcykqaDtsZXQgcCx5O2lmKGE9PT0yZTMpcD0obytyKSp1LHk9LTIqdTtlbHNlIGlmKGE9PT0yMDAxKXA9cip1LHk9LTEqdTtlbHNlIHRocm93IG5ldyBFcnJvcigiVEhSRUUuTWF0cml4NC5tYWtlT3J0aG9ncmFwaGljKCk6IEludmFsaWQgY29vcmRpbmF0ZSBzeXN0ZW06ICIrYSk7cmV0dXJuIGNbMF09MipsLGNbNF09MCxjWzhdPTAsY1sxMl09LWYsY1sxXT0wLGNbNV09MipoLGNbOV09MCxjWzEzXT0tZCxjWzJdPTAsY1s2XT0wLGNbMTBdPXksY1sxNF09LXAsY1szXT0wLGNbN109MCxjWzExXT0wLGNbMTVdPTEsdGhpc31lcXVhbHModCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztmb3IobGV0IHM9MDtzPDE2O3MrKylpZihlW3NdIT09bltzXSlyZXR1cm4hMTtyZXR1cm4hMH1mcm9tQXJyYXkodCxlPTApe2ZvcihsZXQgbj0wO248MTY7bisrKXRoaXMuZWxlbWVudHNbbl09dFtuK2VdO3JldHVybiB0aGlzfXRvQXJyYXkodD1bXSxlPTApe2NvbnN0IG49dGhpcy5lbGVtZW50cztyZXR1cm4gdFtlXT1uWzBdLHRbZSsxXT1uWzFdLHRbZSsyXT1uWzJdLHRbZSszXT1uWzNdLHRbZSs0XT1uWzRdLHRbZSs1XT1uWzVdLHRbZSs2XT1uWzZdLHRbZSs3XT1uWzddLHRbZSs4XT1uWzhdLHRbZSs5XT1uWzldLHRbZSsxMF09blsxMF0sdFtlKzExXT1uWzExXSx0W2UrMTJdPW5bMTJdLHRbZSsxM109blsxM10sdFtlKzE0XT1uWzE0XSx0W2UrMTVdPW5bMTVdLHR9fWNvbnN0IE9uPW5ldyBULGxlPW5ldyBzdCxvZj1uZXcgVCgwLDAsMCksYWY9bmV3IFQoMSwxLDEpLGplPW5ldyBULGZzPW5ldyBULCR0PW5ldyBULEVjPW5ldyBzdCxQYz1uZXcgZ2k7Y2xhc3MgYml7Y29uc3RydWN0b3IodD0wLGU9MCxuPTAscz1iaS5ERUZBVUxUX09SREVSKXt0aGlzLmlzRXVsZXI9ITAsdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fb3JkZXI9c31nZXQgeCgpe3JldHVybiB0aGlzLl94fXNldCB4KHQpe3RoaXMuX3g9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHkoKXtyZXR1cm4gdGhpcy5feX1zZXQgeSh0KXt0aGlzLl95PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB6KCl7cmV0dXJuIHRoaXMuX3p9c2V0IHoodCl7dGhpcy5fej10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgb3JkZXIoKXtyZXR1cm4gdGhpcy5fb3JkZXJ9c2V0IG9yZGVyKHQpe3RoaXMuX29yZGVyPXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfXNldCh0LGUsbixzPXRoaXMuX29yZGVyKXtyZXR1cm4gdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fb3JkZXI9cyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl94LHRoaXMuX3ksdGhpcy5feix0aGlzLl9vcmRlcil9Y29weSh0KXtyZXR1cm4gdGhpcy5feD10Ll94LHRoaXMuX3k9dC5feSx0aGlzLl96PXQuX3osdGhpcy5fb3JkZXI9dC5fb3JkZXIsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVJvdGF0aW9uTWF0cml4KHQsZT10aGlzLl9vcmRlcixuPSEwKXtjb25zdCBzPXQuZWxlbWVudHMscj1zWzBdLG89c1s0XSxhPXNbOF0sYz1zWzFdLGw9c1s1XSxoPXNbOV0sdT1zWzJdLGY9c1s2XSxkPXNbMTBdO3N3aXRjaChlKXtjYXNlIlhZWiI6dGhpcy5feT1NYXRoLmFzaW4oWihhLC0xLDEpKSxNYXRoLmFicyhhKTwuOTk5OTk5OT8odGhpcy5feD1NYXRoLmF0YW4yKC1oLGQpLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxyKSk6KHRoaXMuX3g9TWF0aC5hdGFuMihmLGwpLHRoaXMuX3o9MCk7YnJlYWs7Y2FzZSJZWFoiOnRoaXMuX3g9TWF0aC5hc2luKC1aKGgsLTEsMSkpLE1hdGguYWJzKGgpPC45OTk5OTk5Pyh0aGlzLl95PU1hdGguYXRhbjIoYSxkKSx0aGlzLl96PU1hdGguYXRhbjIoYyxsKSk6KHRoaXMuX3k9TWF0aC5hdGFuMigtdSxyKSx0aGlzLl96PTApO2JyZWFrO2Nhc2UiWlhZIjp0aGlzLl94PU1hdGguYXNpbihaKGYsLTEsMSkpLE1hdGguYWJzKGYpPC45OTk5OTk5Pyh0aGlzLl95PU1hdGguYXRhbjIoLXUsZCksdGhpcy5fej1NYXRoLmF0YW4yKC1vLGwpKToodGhpcy5feT0wLHRoaXMuX3o9TWF0aC5hdGFuMihjLHIpKTticmVhaztjYXNlIlpZWCI6dGhpcy5feT1NYXRoLmFzaW4oLVoodSwtMSwxKSksTWF0aC5hYnModSk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMihmLGQpLHRoaXMuX3o9TWF0aC5hdGFuMihjLHIpKToodGhpcy5feD0wLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxsKSk7YnJlYWs7Y2FzZSJZWlgiOnRoaXMuX3o9TWF0aC5hc2luKFooYywtMSwxKSksTWF0aC5hYnMoYyk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMigtaCxsKSx0aGlzLl95PU1hdGguYXRhbjIoLXUscikpOih0aGlzLl94PTAsdGhpcy5feT1NYXRoLmF0YW4yKGEsZCkpO2JyZWFrO2Nhc2UiWFpZIjp0aGlzLl96PU1hdGguYXNpbigtWihvLC0xLDEpKSxNYXRoLmFicyhvKTwuOTk5OTk5OT8odGhpcy5feD1NYXRoLmF0YW4yKGYsbCksdGhpcy5feT1NYXRoLmF0YW4yKGEscikpOih0aGlzLl94PU1hdGguYXRhbjIoLWgsZCksdGhpcy5feT0wKTticmVhaztkZWZhdWx0OmNvbnNvbGUud2FybigiVEhSRUUuRXVsZXI6IC5zZXRGcm9tUm90YXRpb25NYXRyaXgoKSBlbmNvdW50ZXJlZCBhbiB1bmtub3duIG9yZGVyOiAiK2UpfXJldHVybiB0aGlzLl9vcmRlcj1lLG49PT0hMCYmdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVF1YXRlcm5pb24odCxlLG4pe3JldHVybiBFYy5tYWtlUm90YXRpb25Gcm9tUXVhdGVybmlvbih0KSx0aGlzLnNldEZyb21Sb3RhdGlvbk1hdHJpeChFYyxlLG4pfXNldEZyb21WZWN0b3IzKHQsZT10aGlzLl9vcmRlcil7cmV0dXJuIHRoaXMuc2V0KHQueCx0LnksdC56LGUpfXJlb3JkZXIodCl7cmV0dXJuIFBjLnNldEZyb21FdWxlcih0aGlzKSx0aGlzLnNldEZyb21RdWF0ZXJuaW9uKFBjLHQpfWVxdWFscyh0KXtyZXR1cm4gdC5feD09PXRoaXMuX3gmJnQuX3k9PT10aGlzLl95JiZ0Ll96PT09dGhpcy5feiYmdC5fb3JkZXI9PT10aGlzLl9vcmRlcn1mcm9tQXJyYXkodCl7cmV0dXJuIHRoaXMuX3g9dFswXSx0aGlzLl95PXRbMV0sdGhpcy5fej10WzJdLHRbM10hPT12b2lkIDAmJih0aGlzLl9vcmRlcj10WzNdKSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLl94LHRbZSsxXT10aGlzLl95LHRbZSsyXT10aGlzLl96LHRbZSszXT10aGlzLl9vcmRlcix0fV9vbkNoYW5nZSh0KXtyZXR1cm4gdGhpcy5fb25DaGFuZ2VDYWxsYmFjaz10LHRoaXN9X29uQ2hhbmdlQ2FsbGJhY2soKXt9KltTeW1ib2wuaXRlcmF0b3JdKCl7eWllbGQgdGhpcy5feCx5aWVsZCB0aGlzLl95LHlpZWxkIHRoaXMuX3oseWllbGQgdGhpcy5fb3JkZXJ9fWJpLkRFRkFVTFRfT1JERVI9IlhZWiI7Y2xhc3MgY2Z7Y29uc3RydWN0b3IoKXt0aGlzLm1hc2s9MX1zZXQodCl7dGhpcy5tYXNrPSgxPDx0fDApPj4+MH1lbmFibGUodCl7dGhpcy5tYXNrfD0xPDx0fDB9ZW5hYmxlQWxsKCl7dGhpcy5tYXNrPS0xfXRvZ2dsZSh0KXt0aGlzLm1hc2tePTE8PHR8MH1kaXNhYmxlKHQpe3RoaXMubWFzayY9figxPDx0fDApfWRpc2FibGVBbGwoKXt0aGlzLm1hc2s9MH10ZXN0KHQpe3JldHVybih0aGlzLm1hc2smdC5tYXNrKSE9PTB9aXNFbmFibGVkKHQpe3JldHVybih0aGlzLm1hc2smKDE8PHR8MCkpIT09MH19bGV0IGxmPTA7Y29uc3QgQ2M9bmV3IFQsRG49bmV3IGdpLFRlPW5ldyBzdCxkcz1uZXcgVCxNaT1uZXcgVCxoZj1uZXcgVCx1Zj1uZXcgZ2ksQmM9bmV3IFQoMSwwLDApLEZjPW5ldyBUKDAsMSwwKSxJYz1uZXcgVCgwLDAsMSksa2M9e3R5cGU6ImFkZGVkIn0sZmY9e3R5cGU6InJlbW92ZWQifSwkbj17dHlwZToiY2hpbGRhZGRlZCIsY2hpbGQ6bnVsbH0scG89e3R5cGU6ImNoaWxkcmVtb3ZlZCIsY2hpbGQ6bnVsbH07Y2xhc3MgRWUgZXh0ZW5kcyBvc3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy5pc09iamVjdDNEPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOmxmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy50eXBlPSJPYmplY3QzRCIsdGhpcy5wYXJlbnQ9bnVsbCx0aGlzLmNoaWxkcmVuPVtdLHRoaXMudXA9RWUuREVGQVVMVF9VUC5jbG9uZSgpO2NvbnN0IHQ9bmV3IFQsZT1uZXcgYmksbj1uZXcgZ2kscz1uZXcgVCgxLDEsMSk7ZnVuY3Rpb24gcigpe24uc2V0RnJvbUV1bGVyKGUsITEpfWZ1bmN0aW9uIG8oKXtlLnNldEZyb21RdWF0ZXJuaW9uKG4sdm9pZCAwLCExKX1lLl9vbkNoYW5nZShyKSxuLl9vbkNoYW5nZShvKSxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLHtwb3NpdGlvbjp7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITAsdmFsdWU6dH0scm90YXRpb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOmV9LHF1YXRlcm5pb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOm59LHNjYWxlOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTpzfSxtb2RlbFZpZXdNYXRyaXg6e3ZhbHVlOm5ldyBzdH0sbm9ybWFsTWF0cml4Ont2YWx1ZTpuZXcgZ2V9fSksdGhpcy5tYXRyaXg9bmV3IHN0LHRoaXMubWF0cml4V29ybGQ9bmV3IHN0LHRoaXMubWF0cml4QXV0b1VwZGF0ZT1FZS5ERUZBVUxUX01BVFJJWF9BVVRPX1VQREFURSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT1FZS5ERUZBVUxUX01BVFJJWF9XT1JMRF9BVVRPX1VQREFURSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITEsdGhpcy5sYXllcnM9bmV3IGNmLHRoaXMudmlzaWJsZT0hMCx0aGlzLmNhc3RTaGFkb3c9ITEsdGhpcy5yZWNlaXZlU2hhZG93PSExLHRoaXMuZnJ1c3R1bUN1bGxlZD0hMCx0aGlzLnJlbmRlck9yZGVyPTAsdGhpcy5hbmltYXRpb25zPVtdLHRoaXMuY3VzdG9tRGVwdGhNYXRlcmlhbD12b2lkIDAsdGhpcy5jdXN0b21EaXN0YW5jZU1hdGVyaWFsPXZvaWQgMCx0aGlzLnVzZXJEYXRhPXt9fW9uQmVmb3JlU2hhZG93KCl7fW9uQWZ0ZXJTaGFkb3coKXt9b25CZWZvcmVSZW5kZXIoKXt9b25BZnRlclJlbmRlcigpe31hcHBseU1hdHJpeDQodCl7dGhpcy5tYXRyaXhBdXRvVXBkYXRlJiZ0aGlzLnVwZGF0ZU1hdHJpeCgpLHRoaXMubWF0cml4LnByZW11bHRpcGx5KHQpLHRoaXMubWF0cml4LmRlY29tcG9zZSh0aGlzLnBvc2l0aW9uLHRoaXMucXVhdGVybmlvbix0aGlzLnNjYWxlKX1hcHBseVF1YXRlcm5pb24odCl7cmV0dXJuIHRoaXMucXVhdGVybmlvbi5wcmVtdWx0aXBseSh0KSx0aGlzfXNldFJvdGF0aW9uRnJvbUF4aXNBbmdsZSh0LGUpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSl9c2V0Um90YXRpb25Gcm9tRXVsZXIodCl7dGhpcy5xdWF0ZXJuaW9uLnNldEZyb21FdWxlcih0LCEwKX1zZXRSb3RhdGlvbkZyb21NYXRyaXgodCl7dGhpcy5xdWF0ZXJuaW9uLnNldEZyb21Sb3RhdGlvbk1hdHJpeCh0KX1zZXRSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpe3RoaXMucXVhdGVybmlvbi5jb3B5KHQpfXJvdGF0ZU9uQXhpcyh0LGUpe3JldHVybiBEbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSksdGhpcy5xdWF0ZXJuaW9uLm11bHRpcGx5KERuKSx0aGlzfXJvdGF0ZU9uV29ybGRBeGlzKHQsZSl7cmV0dXJuIERuLnNldEZyb21BeGlzQW5nbGUodCxlKSx0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkoRG4pLHRoaXN9cm90YXRlWCh0KXtyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoQmMsdCl9cm90YXRlWSh0KXtyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoRmMsdCl9cm90YXRlWih0KXtyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoSWMsdCl9dHJhbnNsYXRlT25BeGlzKHQsZSl7cmV0dXJuIENjLmNvcHkodCkuYXBwbHlRdWF0ZXJuaW9uKHRoaXMucXVhdGVybmlvbiksdGhpcy5wb3NpdGlvbi5hZGQoQ2MubXVsdGlwbHlTY2FsYXIoZSkpLHRoaXN9dHJhbnNsYXRlWCh0KXtyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoQmMsdCl9dHJhbnNsYXRlWSh0KXtyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoRmMsdCl9dHJhbnNsYXRlWih0KXtyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoSWMsdCl9bG9jYWxUb1dvcmxkKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0LmFwcGx5TWF0cml4NCh0aGlzLm1hdHJpeFdvcmxkKX13b3JsZFRvTG9jYWwodCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHQuYXBwbHlNYXRyaXg0KFRlLmNvcHkodGhpcy5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkpfWxvb2tBdCh0LGUsbil7dC5pc1ZlY3RvcjM/ZHMuY29weSh0KTpkcy5zZXQodCxlLG4pO2NvbnN0IHM9dGhpcy5wYXJlbnQ7dGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksTWkuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKHRoaXMubWF0cml4V29ybGQpLHRoaXMuaXNDYW1lcmF8fHRoaXMuaXNMaWdodD9UZS5sb29rQXQoTWksZHMsdGhpcy51cCk6VGUubG9va0F0KGRzLE1pLHRoaXMudXApLHRoaXMucXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgoVGUpLHMmJihUZS5leHRyYWN0Um90YXRpb24ocy5tYXRyaXhXb3JsZCksRG4uc2V0RnJvbVJvdGF0aW9uTWF0cml4KFRlKSx0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkoRG4uaW52ZXJ0KCkpKX1hZGQodCl7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IobGV0IGU9MDtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXRoaXMuYWRkKGFyZ3VtZW50c1tlXSk7cmV0dXJuIHRoaXN9cmV0dXJuIHQ9PT10aGlzPyhjb25zb2xlLmVycm9yKCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBjYW4ndCBiZSBhZGRlZCBhcyBhIGNoaWxkIG9mIGl0c2VsZi4iLHQpLHRoaXMpOih0JiZ0LmlzT2JqZWN0M0Q/KHQucmVtb3ZlRnJvbVBhcmVudCgpLHQucGFyZW50PXRoaXMsdGhpcy5jaGlsZHJlbi5wdXNoKHQpLHQuZGlzcGF0Y2hFdmVudChrYyksJG4uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQoJG4pLCRuLmNoaWxkPW51bGwpOmNvbnNvbGUuZXJyb3IoIlRIUkVFLk9iamVjdDNELmFkZDogb2JqZWN0IG5vdCBhbiBpbnN0YW5jZSBvZiBUSFJFRS5PYmplY3QzRC4iLHQpLHRoaXMpfXJlbW92ZSh0KXtpZihhcmd1bWVudHMubGVuZ3RoPjEpe2ZvcihsZXQgbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspdGhpcy5yZW1vdmUoYXJndW1lbnRzW25dKTtyZXR1cm4gdGhpc31jb25zdCBlPXRoaXMuY2hpbGRyZW4uaW5kZXhPZih0KTtyZXR1cm4gZSE9PS0xJiYodC5wYXJlbnQ9bnVsbCx0aGlzLmNoaWxkcmVuLnNwbGljZShlLDEpLHQuZGlzcGF0Y2hFdmVudChmZikscG8uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQocG8pLHBvLmNoaWxkPW51bGwpLHRoaXN9cmVtb3ZlRnJvbVBhcmVudCgpe2NvbnN0IHQ9dGhpcy5wYXJlbnQ7cmV0dXJuIHQhPT1udWxsJiZ0LnJlbW92ZSh0aGlzKSx0aGlzfWNsZWFyKCl7cmV0dXJuIHRoaXMucmVtb3ZlKC4uLnRoaXMuY2hpbGRyZW4pfWF0dGFjaCh0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksVGUuY29weSh0aGlzLm1hdHJpeFdvcmxkKS5pbnZlcnQoKSx0LnBhcmVudCE9PW51bGwmJih0LnBhcmVudC51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksVGUubXVsdGlwbHkodC5wYXJlbnQubWF0cml4V29ybGQpKSx0LmFwcGx5TWF0cml4NChUZSksdC5yZW1vdmVGcm9tUGFyZW50KCksdC5wYXJlbnQ9dGhpcyx0aGlzLmNoaWxkcmVuLnB1c2godCksdC51cGRhdGVXb3JsZE1hdHJpeCghMSwhMCksdC5kaXNwYXRjaEV2ZW50KGtjKSwkbi5jaGlsZD10LHRoaXMuZGlzcGF0Y2hFdmVudCgkbiksJG4uY2hpbGQ9bnVsbCx0aGlzfWdldE9iamVjdEJ5SWQodCl7cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlQcm9wZXJ0eSgiaWQiLHQpfWdldE9iamVjdEJ5TmFtZSh0KXtyZXR1cm4gdGhpcy5nZXRPYmplY3RCeVByb3BlcnR5KCJuYW1lIix0KX1nZXRPYmplY3RCeVByb3BlcnR5KHQsZSl7aWYodGhpc1t0XT09PWUpcmV0dXJuIHRoaXM7Zm9yKGxldCBuPTAscz10aGlzLmNoaWxkcmVuLmxlbmd0aDtuPHM7bisrKXtjb25zdCBvPXRoaXMuY2hpbGRyZW5bbl0uZ2V0T2JqZWN0QnlQcm9wZXJ0eSh0LGUpO2lmKG8hPT12b2lkIDApcmV0dXJuIG99fWdldE9iamVjdHNCeVByb3BlcnR5KHQsZSxuPVtdKXt0aGlzW3RdPT09ZSYmbi5wdXNoKHRoaXMpO2NvbnN0IHM9dGhpcy5jaGlsZHJlbjtmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKyspc1tyXS5nZXRPYmplY3RzQnlQcm9wZXJ0eSh0LGUsbik7cmV0dXJuIG59Z2V0V29ybGRQb3NpdGlvbih0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdC5zZXRGcm9tTWF0cml4UG9zaXRpb24odGhpcy5tYXRyaXhXb3JsZCl9Z2V0V29ybGRRdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZShNaSx0LGhmKSx0fWdldFdvcmxkU2NhbGUodCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHRoaXMubWF0cml4V29ybGQuZGVjb21wb3NlKE1pLHVmLHQpLHR9Z2V0V29ybGREaXJlY3Rpb24odCl7dGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSk7Y29uc3QgZT10aGlzLm1hdHJpeFdvcmxkLmVsZW1lbnRzO3JldHVybiB0LnNldChlWzhdLGVbOV0sZVsxMF0pLm5vcm1hbGl6ZSgpfXJheWNhc3QoKXt9dHJhdmVyc2UodCl7dCh0aGlzKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udHJhdmVyc2UodCl9dHJhdmVyc2VWaXNpYmxlKHQpe2lmKHRoaXMudmlzaWJsZT09PSExKXJldHVybjt0KHRoaXMpO2NvbnN0IGU9dGhpcy5jaGlsZHJlbjtmb3IobGV0IG49MCxzPWUubGVuZ3RoO248cztuKyspZVtuXS50cmF2ZXJzZVZpc2libGUodCl9dHJhdmVyc2VBbmNlc3RvcnModCl7Y29uc3QgZT10aGlzLnBhcmVudDtlIT09bnVsbCYmKHQoZSksZS50cmF2ZXJzZUFuY2VzdG9ycyh0KSl9dXBkYXRlTWF0cml4KCl7dGhpcy5tYXRyaXguY29tcG9zZSh0aGlzLnBvc2l0aW9uLHRoaXMucXVhdGVybmlvbix0aGlzLnNjYWxlKSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITB9dXBkYXRlTWF0cml4V29ybGQodCl7dGhpcy5tYXRyaXhBdXRvVXBkYXRlJiZ0aGlzLnVwZGF0ZU1hdHJpeCgpLCh0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGV8fHQpJiYodGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9PT0hMCYmKHRoaXMucGFyZW50PT09bnVsbD90aGlzLm1hdHJpeFdvcmxkLmNvcHkodGhpcy5tYXRyaXgpOnRoaXMubWF0cml4V29ybGQubXVsdGlwbHlNYXRyaWNlcyh0aGlzLnBhcmVudC5tYXRyaXhXb3JsZCx0aGlzLm1hdHJpeCkpLHRoaXMubWF0cml4V29ybGROZWVkc1VwZGF0ZT0hMSx0PSEwKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udXBkYXRlTWF0cml4V29ybGQodCl9dXBkYXRlV29ybGRNYXRyaXgodCxlKXtjb25zdCBuPXRoaXMucGFyZW50O2lmKHQ9PT0hMCYmbiE9PW51bGwmJm4udXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHRoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT09PSEwJiYodGhpcy5wYXJlbnQ9PT1udWxsP3RoaXMubWF0cml4V29ybGQuY29weSh0aGlzLm1hdHJpeCk6dGhpcy5tYXRyaXhXb3JsZC5tdWx0aXBseU1hdHJpY2VzKHRoaXMucGFyZW50Lm1hdHJpeFdvcmxkLHRoaXMubWF0cml4KSksZT09PSEwKXtjb25zdCBzPXRoaXMuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXNbcl0udXBkYXRlV29ybGRNYXRyaXgoITEsITApfX10b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyIsbj17fTtlJiYodD17Z2VvbWV0cmllczp7fSxtYXRlcmlhbHM6e30sdGV4dHVyZXM6e30saW1hZ2VzOnt9LHNoYXBlczp7fSxza2VsZXRvbnM6e30sYW5pbWF0aW9uczp7fSxub2Rlczp7fX0sbi5tZXRhZGF0YT17dmVyc2lvbjo0LjcsdHlwZToiT2JqZWN0IixnZW5lcmF0b3I6Ik9iamVjdDNELnRvSlNPTiJ9KTtjb25zdCBzPXt9O3MudXVpZD10aGlzLnV1aWQscy50eXBlPXRoaXMudHlwZSx0aGlzLm5hbWUhPT0iIiYmKHMubmFtZT10aGlzLm5hbWUpLHRoaXMuY2FzdFNoYWRvdz09PSEwJiYocy5jYXN0U2hhZG93PSEwKSx0aGlzLnJlY2VpdmVTaGFkb3c9PT0hMCYmKHMucmVjZWl2ZVNoYWRvdz0hMCksdGhpcy52aXNpYmxlPT09ITEmJihzLnZpc2libGU9ITEpLHRoaXMuZnJ1c3R1bUN1bGxlZD09PSExJiYocy5mcnVzdHVtQ3VsbGVkPSExKSx0aGlzLnJlbmRlck9yZGVyIT09MCYmKHMucmVuZGVyT3JkZXI9dGhpcy5yZW5kZXJPcmRlciksT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihzLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLHMubGF5ZXJzPXRoaXMubGF5ZXJzLm1hc2sscy5tYXRyaXg9dGhpcy5tYXRyaXgudG9BcnJheSgpLHMudXA9dGhpcy51cC50b0FycmF5KCksdGhpcy5tYXRyaXhBdXRvVXBkYXRlPT09ITEmJihzLm1hdHJpeEF1dG9VcGRhdGU9ITEpLHRoaXMuaXNJbnN0YW5jZWRNZXNoJiYocy50eXBlPSJJbnN0YW5jZWRNZXNoIixzLmNvdW50PXRoaXMuY291bnQscy5pbnN0YW5jZU1hdHJpeD10aGlzLmluc3RhbmNlTWF0cml4LnRvSlNPTigpLHRoaXMuaW5zdGFuY2VDb2xvciE9PW51bGwmJihzLmluc3RhbmNlQ29sb3I9dGhpcy5pbnN0YW5jZUNvbG9yLnRvSlNPTigpKSksdGhpcy5pc0JhdGNoZWRNZXNoJiYocy50eXBlPSJCYXRjaGVkTWVzaCIscy5wZXJPYmplY3RGcnVzdHVtQ3VsbGVkPXRoaXMucGVyT2JqZWN0RnJ1c3R1bUN1bGxlZCxzLnNvcnRPYmplY3RzPXRoaXMuc29ydE9iamVjdHMscy5kcmF3UmFuZ2VzPXRoaXMuX2RyYXdSYW5nZXMscy5yZXNlcnZlZFJhbmdlcz10aGlzLl9yZXNlcnZlZFJhbmdlcyxzLmdlb21ldHJ5SW5mbz10aGlzLl9nZW9tZXRyeUluZm8ubWFwKGE9PlplKEZ0KHt9LGEpLHtib3VuZGluZ0JveDphLmJvdW5kaW5nQm94P2EuYm91bmRpbmdCb3gudG9KU09OKCk6dm9pZCAwLGJvdW5kaW5nU3BoZXJlOmEuYm91bmRpbmdTcGhlcmU/YS5ib3VuZGluZ1NwaGVyZS50b0pTT04oKTp2b2lkIDB9KSkscy5pbnN0YW5jZUluZm89dGhpcy5faW5zdGFuY2VJbmZvLm1hcChhPT5GdCh7fSxhKSkscy5hdmFpbGFibGVJbnN0YW5jZUlkcz10aGlzLl9hdmFpbGFibGVJbnN0YW5jZUlkcy5zbGljZSgpLHMuYXZhaWxhYmxlR2VvbWV0cnlJZHM9dGhpcy5fYXZhaWxhYmxlR2VvbWV0cnlJZHMuc2xpY2UoKSxzLm5leHRJbmRleFN0YXJ0PXRoaXMuX25leHRJbmRleFN0YXJ0LHMubmV4dFZlcnRleFN0YXJ0PXRoaXMuX25leHRWZXJ0ZXhTdGFydCxzLmdlb21ldHJ5Q291bnQ9dGhpcy5fZ2VvbWV0cnlDb3VudCxzLm1heEluc3RhbmNlQ291bnQ9dGhpcy5fbWF4SW5zdGFuY2VDb3VudCxzLm1heFZlcnRleENvdW50PXRoaXMuX21heFZlcnRleENvdW50LHMubWF4SW5kZXhDb3VudD10aGlzLl9tYXhJbmRleENvdW50LHMuZ2VvbWV0cnlJbml0aWFsaXplZD10aGlzLl9nZW9tZXRyeUluaXRpYWxpemVkLHMubWF0cmljZXNUZXh0dXJlPXRoaXMuX21hdHJpY2VzVGV4dHVyZS50b0pTT04odCkscy5pbmRpcmVjdFRleHR1cmU9dGhpcy5faW5kaXJlY3RUZXh0dXJlLnRvSlNPTih0KSx0aGlzLl9jb2xvcnNUZXh0dXJlIT09bnVsbCYmKHMuY29sb3JzVGV4dHVyZT10aGlzLl9jb2xvcnNUZXh0dXJlLnRvSlNPTih0KSksdGhpcy5ib3VuZGluZ1NwaGVyZSE9PW51bGwmJihzLmJvdW5kaW5nU3BoZXJlPXRoaXMuYm91bmRpbmdTcGhlcmUudG9KU09OKCkpLHRoaXMuYm91bmRpbmdCb3ghPT1udWxsJiYocy5ib3VuZGluZ0JveD10aGlzLmJvdW5kaW5nQm94LnRvSlNPTigpKSk7ZnVuY3Rpb24gcihhLGMpe3JldHVybiBhW2MudXVpZF09PT12b2lkIDAmJihhW2MudXVpZF09Yy50b0pTT04odCkpLGMudXVpZH1pZih0aGlzLmlzU2NlbmUpdGhpcy5iYWNrZ3JvdW5kJiYodGhpcy5iYWNrZ3JvdW5kLmlzQ29sb3I/cy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04oKTp0aGlzLmJhY2tncm91bmQuaXNUZXh0dXJlJiYocy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04odCkudXVpZCkpLHRoaXMuZW52aXJvbm1lbnQmJnRoaXMuZW52aXJvbm1lbnQuaXNUZXh0dXJlJiZ0aGlzLmVudmlyb25tZW50LmlzUmVuZGVyVGFyZ2V0VGV4dHVyZSE9PSEwJiYocy5lbnZpcm9ubWVudD10aGlzLmVudmlyb25tZW50LnRvSlNPTih0KS51dWlkKTtlbHNlIGlmKHRoaXMuaXNNZXNofHx0aGlzLmlzTGluZXx8dGhpcy5pc1BvaW50cyl7cy5nZW9tZXRyeT1yKHQuZ2VvbWV0cmllcyx0aGlzLmdlb21ldHJ5KTtjb25zdCBhPXRoaXMuZ2VvbWV0cnkucGFyYW1ldGVycztpZihhIT09dm9pZCAwJiZhLnNoYXBlcyE9PXZvaWQgMCl7Y29uc3QgYz1hLnNoYXBlcztpZihBcnJheS5pc0FycmF5KGMpKWZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyl7Y29uc3QgdT1jW2xdO3IodC5zaGFwZXMsdSl9ZWxzZSByKHQuc2hhcGVzLGMpfX1pZih0aGlzLmlzU2tpbm5lZE1lc2gmJihzLmJpbmRNb2RlPXRoaXMuYmluZE1vZGUscy5iaW5kTWF0cml4PXRoaXMuYmluZE1hdHJpeC50b0FycmF5KCksdGhpcy5za2VsZXRvbiE9PXZvaWQgMCYmKHIodC5za2VsZXRvbnMsdGhpcy5za2VsZXRvbikscy5za2VsZXRvbj10aGlzLnNrZWxldG9uLnV1aWQpKSx0aGlzLm1hdGVyaWFsIT09dm9pZCAwKWlmKEFycmF5LmlzQXJyYXkodGhpcy5tYXRlcmlhbCkpe2NvbnN0IGE9W107Zm9yKGxldCBjPTAsbD10aGlzLm1hdGVyaWFsLmxlbmd0aDtjPGw7YysrKWEucHVzaChyKHQubWF0ZXJpYWxzLHRoaXMubWF0ZXJpYWxbY10pKTtzLm1hdGVyaWFsPWF9ZWxzZSBzLm1hdGVyaWFsPXIodC5tYXRlcmlhbHMsdGhpcy5tYXRlcmlhbCk7aWYodGhpcy5jaGlsZHJlbi5sZW5ndGg+MCl7cy5jaGlsZHJlbj1bXTtmb3IobGV0IGE9MDthPHRoaXMuY2hpbGRyZW4ubGVuZ3RoO2ErKylzLmNoaWxkcmVuLnB1c2godGhpcy5jaGlsZHJlblthXS50b0pTT04odCkub2JqZWN0KX1pZih0aGlzLmFuaW1hdGlvbnMubGVuZ3RoPjApe3MuYW5pbWF0aW9ucz1bXTtmb3IobGV0IGE9MDthPHRoaXMuYW5pbWF0aW9ucy5sZW5ndGg7YSsrKXtjb25zdCBjPXRoaXMuYW5pbWF0aW9uc1thXTtzLmFuaW1hdGlvbnMucHVzaChyKHQuYW5pbWF0aW9ucyxjKSl9fWlmKGUpe2NvbnN0IGE9byh0Lmdlb21ldHJpZXMpLGM9byh0Lm1hdGVyaWFscyksbD1vKHQudGV4dHVyZXMpLGg9byh0LmltYWdlcyksdT1vKHQuc2hhcGVzKSxmPW8odC5za2VsZXRvbnMpLGQ9byh0LmFuaW1hdGlvbnMpLHA9byh0Lm5vZGVzKTthLmxlbmd0aD4wJiYobi5nZW9tZXRyaWVzPWEpLGMubGVuZ3RoPjAmJihuLm1hdGVyaWFscz1jKSxsLmxlbmd0aD4wJiYobi50ZXh0dXJlcz1sKSxoLmxlbmd0aD4wJiYobi5pbWFnZXM9aCksdS5sZW5ndGg+MCYmKG4uc2hhcGVzPXUpLGYubGVuZ3RoPjAmJihuLnNrZWxldG9ucz1mKSxkLmxlbmd0aD4wJiYobi5hbmltYXRpb25zPWQpLHAubGVuZ3RoPjAmJihuLm5vZGVzPXApfXJldHVybiBuLm9iamVjdD1zLG47ZnVuY3Rpb24gbyhhKXtjb25zdCBjPVtdO2Zvcihjb25zdCBsIGluIGEpe2NvbnN0IGg9YVtsXTtkZWxldGUgaC5tZXRhZGF0YSxjLnB1c2goaCl9cmV0dXJuIGN9fWNsb25lKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyx0KX1jb3B5KHQsZT0hMCl7aWYodGhpcy5uYW1lPXQubmFtZSx0aGlzLnVwLmNvcHkodC51cCksdGhpcy5wb3NpdGlvbi5jb3B5KHQucG9zaXRpb24pLHRoaXMucm90YXRpb24ub3JkZXI9dC5yb3RhdGlvbi5vcmRlcix0aGlzLnF1YXRlcm5pb24uY29weSh0LnF1YXRlcm5pb24pLHRoaXMuc2NhbGUuY29weSh0LnNjYWxlKSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLm1hdHJpeFdvcmxkLmNvcHkodC5tYXRyaXhXb3JsZCksdGhpcy5tYXRyaXhBdXRvVXBkYXRlPXQubWF0cml4QXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT10Lm1hdHJpeFdvcmxkQXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9dC5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlLHRoaXMubGF5ZXJzLm1hc2s9dC5sYXllcnMubWFzayx0aGlzLnZpc2libGU9dC52aXNpYmxlLHRoaXMuY2FzdFNoYWRvdz10LmNhc3RTaGFkb3csdGhpcy5yZWNlaXZlU2hhZG93PXQucmVjZWl2ZVNoYWRvdyx0aGlzLmZydXN0dW1DdWxsZWQ9dC5mcnVzdHVtQ3VsbGVkLHRoaXMucmVuZGVyT3JkZXI9dC5yZW5kZXJPcmRlcix0aGlzLmFuaW1hdGlvbnM9dC5hbmltYXRpb25zLnNsaWNlKCksdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSxlPT09ITApZm9yKGxldCBuPTA7bjx0LmNoaWxkcmVuLmxlbmd0aDtuKyspe2NvbnN0IHM9dC5jaGlsZHJlbltuXTt0aGlzLmFkZChzLmNsb25lKCkpfXJldHVybiB0aGlzfX1FZS5ERUZBVUxUX1VQPW5ldyBUKDAsMSwwKSxFZS5ERUZBVUxUX01BVFJJWF9BVVRPX1VQREFURT0hMCxFZS5ERUZBVUxUX01BVFJJWF9XT1JMRF9BVVRPX1VQREFURT0hMDtjb25zdCBoZT1uZXcgVCxQZT1uZXcgVCx5bz1uZXcgVCxDZT1uZXcgVCxWbj1uZXcgVCxVbj1uZXcgVCxOYz1uZXcgVCxtbz1uZXcgVCxnbz1uZXcgVCx4bz1uZXcgVCx3bz1uZXcgWXQsYm89bmV3IFl0LE1vPW5ldyBZdDtjbGFzcyBldHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCl7dGhpcy5hPXQsdGhpcy5iPWUsdGhpcy5jPW59c3RhdGljIGdldE5vcm1hbCh0LGUsbixzKXtzLnN1YlZlY3RvcnMobixlKSxoZS5zdWJWZWN0b3JzKHQsZSkscy5jcm9zcyhoZSk7Y29uc3Qgcj1zLmxlbmd0aFNxKCk7cmV0dXJuIHI+MD9zLm11bHRpcGx5U2NhbGFyKDEvTWF0aC5zcXJ0KHIpKTpzLnNldCgwLDAsMCl9c3RhdGljIGdldEJhcnljb29yZCh0LGUsbixzLHIpe2hlLnN1YlZlY3RvcnMocyxlKSxQZS5zdWJWZWN0b3JzKG4sZSkseW8uc3ViVmVjdG9ycyh0LGUpO2NvbnN0IG89aGUuZG90KGhlKSxhPWhlLmRvdChQZSksYz1oZS5kb3QoeW8pLGw9UGUuZG90KFBlKSxoPVBlLmRvdCh5byksdT1vKmwtYSphO2lmKHU9PT0wKXJldHVybiByLnNldCgwLDAsMCksbnVsbDtjb25zdCBmPTEvdSxkPShsKmMtYSpoKSpmLHA9KG8qaC1hKmMpKmY7cmV0dXJuIHIuc2V0KDEtZC1wLHAsZCl9c3RhdGljIGNvbnRhaW5zUG9pbnQodCxlLG4scyl7cmV0dXJuIHRoaXMuZ2V0QmFyeWNvb3JkKHQsZSxuLHMsQ2UpPT09bnVsbD8hMTpDZS54Pj0wJiZDZS55Pj0wJiZDZS54K0NlLnk8PTF9c3RhdGljIGdldEludGVycG9sYXRpb24odCxlLG4scyxyLG8sYSxjKXtyZXR1cm4gdGhpcy5nZXRCYXJ5Y29vcmQodCxlLG4scyxDZSk9PT1udWxsPyhjLng9MCxjLnk9MCwieiJpbiBjJiYoYy56PTApLCJ3ImluIGMmJihjLnc9MCksbnVsbCk6KGMuc2V0U2NhbGFyKDApLGMuYWRkU2NhbGVkVmVjdG9yKHIsQ2UueCksYy5hZGRTY2FsZWRWZWN0b3IobyxDZS55KSxjLmFkZFNjYWxlZFZlY3RvcihhLENlLnopLGMpfXN0YXRpYyBnZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUodCxlLG4scyxyLG8pe3JldHVybiB3by5zZXRTY2FsYXIoMCksYm8uc2V0U2NhbGFyKDApLE1vLnNldFNjYWxhcigwKSx3by5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSksYm8uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG4pLE1vLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSxvLnNldFNjYWxhcigwKSxvLmFkZFNjYWxlZFZlY3Rvcih3byxyLngpLG8uYWRkU2NhbGVkVmVjdG9yKGJvLHIueSksby5hZGRTY2FsZWRWZWN0b3IoTW8sci56KSxvfXN0YXRpYyBpc0Zyb250RmFjaW5nKHQsZSxuLHMpe3JldHVybiBoZS5zdWJWZWN0b3JzKG4sZSksUGUuc3ViVmVjdG9ycyh0LGUpLGhlLmNyb3NzKFBlKS5kb3Qocyk8MH1zZXQodCxlLG4pe3JldHVybiB0aGlzLmEuY29weSh0KSx0aGlzLmIuY29weShlKSx0aGlzLmMuY29weShuKSx0aGlzfXNldEZyb21Qb2ludHNBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuY29weSh0W2VdKSx0aGlzLmIuY29weSh0W25dKSx0aGlzLmMuY29weSh0W3NdKSx0aGlzfXNldEZyb21BdHRyaWJ1dGVBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLHRoaXMuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsbiksdGhpcy5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLmEuY29weSh0LmEpLHRoaXMuYi5jb3B5KHQuYiksdGhpcy5jLmNvcHkodC5jKSx0aGlzfWdldEFyZWEoKXtyZXR1cm4gaGUuc3ViVmVjdG9ycyh0aGlzLmMsdGhpcy5iKSxQZS5zdWJWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLGhlLmNyb3NzKFBlKS5sZW5ndGgoKSouNX1nZXRNaWRwb2ludCh0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLmFkZCh0aGlzLmMpLm11bHRpcGx5U2NhbGFyKDEvMyl9Z2V0Tm9ybWFsKHQpe3JldHVybiBldC5nZXROb3JtYWwodGhpcy5hLHRoaXMuYix0aGlzLmMsdCl9Z2V0UGxhbmUodCl7cmV0dXJuIHQuc2V0RnJvbUNvcGxhbmFyUG9pbnRzKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1nZXRCYXJ5Y29vcmQodCxlKXtyZXR1cm4gZXQuZ2V0QmFyeWNvb3JkKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSl9Z2V0SW50ZXJwb2xhdGlvbih0LGUsbixzLHIpe3JldHVybiBldC5nZXRJbnRlcnBvbGF0aW9uKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSxuLHMscil9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gZXQuY29udGFpbnNQb2ludCh0LHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1pc0Zyb250RmFjaW5nKHQpe3JldHVybiBldC5pc0Zyb250RmFjaW5nKHRoaXMuYSx0aGlzLmIsdGhpcy5jLHQpfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1RyaWFuZ2xlKHRoaXMpfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuYSxzPXRoaXMuYixyPXRoaXMuYztsZXQgbyxhO1ZuLnN1YlZlY3RvcnMocyxuKSxVbi5zdWJWZWN0b3JzKHIsbiksbW8uc3ViVmVjdG9ycyh0LG4pO2NvbnN0IGM9Vm4uZG90KG1vKSxsPVVuLmRvdChtbyk7aWYoYzw9MCYmbDw9MClyZXR1cm4gZS5jb3B5KG4pO2dvLnN1YlZlY3RvcnModCxzKTtjb25zdCBoPVZuLmRvdChnbyksdT1Vbi5kb3QoZ28pO2lmKGg+PTAmJnU8PWgpcmV0dXJuIGUuY29weShzKTtjb25zdCBmPWMqdS1oKmw7aWYoZjw9MCYmYz49MCYmaDw9MClyZXR1cm4gbz1jLyhjLWgpLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoVm4sbyk7eG8uc3ViVmVjdG9ycyh0LHIpO2NvbnN0IGQ9Vm4uZG90KHhvKSxwPVVuLmRvdCh4byk7aWYocD49MCYmZDw9cClyZXR1cm4gZS5jb3B5KHIpO2NvbnN0IHk9ZCpsLWMqcDtpZih5PD0wJiZsPj0wJiZwPD0wKXJldHVybiBhPWwvKGwtcCksZS5jb3B5KG4pLmFkZFNjYWxlZFZlY3RvcihVbixhKTtjb25zdCBtPWgqcC1kKnU7aWYobTw9MCYmdS1oPj0wJiZkLXA+PTApcmV0dXJuIE5jLnN1YlZlY3RvcnMocixzKSxhPSh1LWgpLyh1LWgrKGQtcCkpLGUuY29weShzKS5hZGRTY2FsZWRWZWN0b3IoTmMsYSk7Y29uc3QgZz0xLyhtK3krZik7cmV0dXJuIG89eSpnLGE9ZipnLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoVm4sbykuYWRkU2NhbGVkVmVjdG9yKFVuLGEpfWVxdWFscyh0KXtyZXR1cm4gdC5hLmVxdWFscyh0aGlzLmEpJiZ0LmIuZXF1YWxzKHRoaXMuYikmJnQuYy5lcXVhbHModGhpcy5jKX19Y29uc3QgUmM9e2FsaWNlYmx1ZToxNTc5MjM4MyxhbnRpcXVld2hpdGU6MTY0NDQzNzUsYXF1YTo2NTUzNSxhcXVhbWFyaW5lOjgzODg1NjQsYXp1cmU6MTU3OTQxNzUsYmVpZ2U6MTYxMTkyNjAsYmlzcXVlOjE2NzcwMjQ0LGJsYWNrOjAsYmxhbmNoZWRhbG1vbmQ6MTY3NzIwNDUsYmx1ZToyNTUsYmx1ZXZpb2xldDo5MDU1MjAyLGJyb3duOjEwODI0MjM0LGJ1cmx5d29vZDoxNDU5NjIzMSxjYWRldGJsdWU6NjI2NjUyOCxjaGFydHJldXNlOjgzODgzNTIsY2hvY29sYXRlOjEzNzg5NDcwLGNvcmFsOjE2NzQ0MjcyLGNvcm5mbG93ZXJibHVlOjY1OTE5ODEsY29ybnNpbGs6MTY3NzUzODgsY3JpbXNvbjoxNDQyMzEwMCxjeWFuOjY1NTM1LGRhcmtibHVlOjEzOSxkYXJrY3lhbjozNTcyMyxkYXJrZ29sZGVucm9kOjEyMDkyOTM5LGRhcmtncmF5OjExMTE5MDE3LGRhcmtncmVlbjoyNTYwMCxkYXJrZ3JleToxMTExOTAxNyxkYXJra2hha2k6MTI0MzMyNTksZGFya21hZ2VudGE6OTEwOTY0MyxkYXJrb2xpdmVncmVlbjo1NTk3OTk5LGRhcmtvcmFuZ2U6MTY3NDc1MjAsZGFya29yY2hpZDoxMDA0MDAxMixkYXJrcmVkOjkxMDk1MDQsZGFya3NhbG1vbjoxNTMwODQxMCxkYXJrc2VhZ3JlZW46OTQxOTkxOSxkYXJrc2xhdGVibHVlOjQ3MzQzNDcsZGFya3NsYXRlZ3JheTozMTAwNDk1LGRhcmtzbGF0ZWdyZXk6MzEwMDQ5NSxkYXJrdHVycXVvaXNlOjUyOTQ1LGRhcmt2aW9sZXQ6OTY5OTUzOSxkZWVwcGluazoxNjcxNjk0NyxkZWVwc2t5Ymx1ZTo0OTE1MSxkaW1ncmF5OjY5MDgyNjUsZGltZ3JleTo2OTA4MjY1LGRvZGdlcmJsdWU6MjAwMzE5OSxmaXJlYnJpY2s6MTE2NzQxNDYsZmxvcmFsd2hpdGU6MTY3NzU5MjAsZm9yZXN0Z3JlZW46MjI2Mzg0MixmdWNoc2lhOjE2NzExOTM1LGdhaW5zYm9ybzoxNDQ3NDQ2MCxnaG9zdHdoaXRlOjE2MzE2NjcxLGdvbGQ6MTY3NjY3MjAsZ29sZGVucm9kOjE0MzI5MTIwLGdyYXk6ODQyMTUwNCxncmVlbjozMjc2OCxncmVlbnllbGxvdzoxMTQwMzA1NSxncmV5Ojg0MjE1MDQsaG9uZXlkZXc6MTU3OTQxNjAsaG90cGluazoxNjczODc0MCxpbmRpYW5yZWQ6MTM0NTg1MjQsaW5kaWdvOjQ5MTUzMzAsaXZvcnk6MTY3NzcyMDAsa2hha2k6MTU3ODc2NjAsbGF2ZW5kZXI6MTUxMzI0MTAsbGF2ZW5kZXJibHVzaDoxNjc3MzM2NSxsYXduZ3JlZW46ODE5MDk3NixsZW1vbmNoaWZmb246MTY3NzU4ODUsbGlnaHRibHVlOjExMzkzMjU0LGxpZ2h0Y29yYWw6MTU3NjE1MzYsbGlnaHRjeWFuOjE0NzQ1NTk5LGxpZ2h0Z29sZGVucm9keWVsbG93OjE2NDQ4MjEwLGxpZ2h0Z3JheToxMzg4MjMyMyxsaWdodGdyZWVuOjk0OTgyNTYsbGlnaHRncmV5OjEzODgyMzIzLGxpZ2h0cGluazoxNjc1ODQ2NSxsaWdodHNhbG1vbjoxNjc1Mjc2MixsaWdodHNlYWdyZWVuOjIxNDI4OTAsbGlnaHRza3libHVlOjg5MDAzNDYsbGlnaHRzbGF0ZWdyYXk6NzgzMzc1MyxsaWdodHNsYXRlZ3JleTo3ODMzNzUzLGxpZ2h0c3RlZWxibHVlOjExNTg0NzM0LGxpZ2h0eWVsbG93OjE2Nzc3MTg0LGxpbWU6NjUyODAsbGltZWdyZWVuOjMzMjkzMzAsbGluZW46MTY0NDU2NzAsbWFnZW50YToxNjcxMTkzNSxtYXJvb246ODM4ODYwOCxtZWRpdW1hcXVhbWFyaW5lOjY3MzczMjIsbWVkaXVtYmx1ZToyMDUsbWVkaXVtb3JjaGlkOjEyMjExNjY3LG1lZGl1bXB1cnBsZTo5NjYyNjgzLG1lZGl1bXNlYWdyZWVuOjM5NzgwOTcsbWVkaXVtc2xhdGVibHVlOjgwODc3OTAsbWVkaXVtc3ByaW5nZ3JlZW46NjQxNTQsbWVkaXVtdHVycXVvaXNlOjQ3NzIzMDAsbWVkaXVtdmlvbGV0cmVkOjEzMDQ3MTczLG1pZG5pZ2h0Ymx1ZToxNjQ0OTEyLG1pbnRjcmVhbToxNjEyMTg1MCxtaXN0eXJvc2U6MTY3NzAyNzMsbW9jY2FzaW46MTY3NzAyMjksbmF2YWpvd2hpdGU6MTY3Njg2ODUsbmF2eToxMjgsb2xkbGFjZToxNjY0MzU1OCxvbGl2ZTo4NDIxMzc2LG9saXZlZHJhYjo3MDQ4NzM5LG9yYW5nZToxNjc1MzkyMCxvcmFuZ2VyZWQ6MTY3MjkzNDQsb3JjaGlkOjE0MzE1NzM0LHBhbGVnb2xkZW5yb2Q6MTU2NTcxMzAscGFsZWdyZWVuOjEwMDI1ODgwLHBhbGV0dXJxdW9pc2U6MTE1Mjk5NjYscGFsZXZpb2xldHJlZDoxNDM4MTIwMyxwYXBheWF3aGlwOjE2NzczMDc3LHBlYWNocHVmZjoxNjc2NzY3MyxwZXJ1OjEzNDY4OTkxLHBpbms6MTY3NjEwMzUscGx1bToxNDUyNDYzNyxwb3dkZXJibHVlOjExNTkxOTEwLHB1cnBsZTo4Mzg4NzM2LHJlYmVjY2FwdXJwbGU6NjY5Nzg4MSxyZWQ6MTY3MTE2ODAscm9zeWJyb3duOjEyMzU3NTE5LHJveWFsYmx1ZTo0Mjg2OTQ1LHNhZGRsZWJyb3duOjkxMjcxODcsc2FsbW9uOjE2NDE2ODgyLHNhbmR5YnJvd246MTYwMzI4NjQsc2VhZ3JlZW46MzA1MDMyNyxzZWFzaGVsbDoxNjc3NDYzOCxzaWVubmE6MTA1MDY3OTcsc2lsdmVyOjEyNjMyMjU2LHNreWJsdWU6ODkwMDMzMSxzbGF0ZWJsdWU6Njk3MDA2MSxzbGF0ZWdyYXk6NzM3Mjk0NCxzbGF0ZWdyZXk6NzM3Mjk0NCxzbm93OjE2Nzc1OTMwLHNwcmluZ2dyZWVuOjY1NDA3LHN0ZWVsYmx1ZTo0NjIwOTgwLHRhbjoxMzgwODc4MCx0ZWFsOjMyODk2LHRoaXN0bGU6MTQyMDQ4ODgsdG9tYXRvOjE2NzM3MDk1LHR1cnF1b2lzZTo0MjUxODU2LHZpb2xldDoxNTYzMTA4Nix3aGVhdDoxNjExMzMzMSx3aGl0ZToxNjc3NzIxNSx3aGl0ZXNtb2tlOjE2MTE5Mjg1LHllbGxvdzoxNjc3Njk2MCx5ZWxsb3dncmVlbjoxMDE0NTA3NH0sUWU9e2g6MCxzOjAsbDowfSxwcz17aDowLHM6MCxsOjB9O2Z1bmN0aW9uIEFvKGksdCxlKXtyZXR1cm4gZTwwJiYoZSs9MSksZT4xJiYoZS09MSksZTwxLzY/aSsodC1pKSo2KmU6ZTwxLzI/dDplPDIvMz9pKyh0LWkpKjYqKDIvMy1lKTppfWxldCB5cz1jbGFzc3tjb25zdHJ1Y3Rvcih0LGUsbil7cmV0dXJuIHRoaXMuaXNDb2xvcj0hMCx0aGlzLnI9MSx0aGlzLmc9MSx0aGlzLmI9MSx0aGlzLnNldCh0LGUsbil9c2V0KHQsZSxuKXtpZihlPT09dm9pZCAwJiZuPT09dm9pZCAwKXtjb25zdCBzPXQ7cyYmcy5pc0NvbG9yP3RoaXMuY29weShzKTp0eXBlb2Ygcz09Im51bWJlciI/dGhpcy5zZXRIZXgocyk6dHlwZW9mIHM9PSJzdHJpbmciJiZ0aGlzLnNldFN0eWxlKHMpfWVsc2UgdGhpcy5zZXRSR0IodCxlLG4pO3JldHVybiB0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy5yPXQsdGhpcy5nPXQsdGhpcy5iPXQsdGhpc31zZXRIZXgodCxlPW9lKXtyZXR1cm4gdD1NYXRoLmZsb29yKHQpLHRoaXMucj0odD4+MTYmMjU1KS8yNTUsdGhpcy5nPSh0Pj44JjI1NSkvMjU1LHRoaXMuYj0odCYyNTUpLzI1NSxhZS5jb2xvclNwYWNlVG9Xb3JraW5nKHRoaXMsZSksdGhpc31zZXRSR0IodCxlLG4scz1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHRoaXMucj10LHRoaXMuZz1lLHRoaXMuYj1uLGFlLmNvbG9yU3BhY2VUb1dvcmtpbmcodGhpcyxzKSx0aGlzfXNldEhTTCh0LGUsbixzPWFlLndvcmtpbmdDb2xvclNwYWNlKXtpZih0PWp1KHQsMSksZT1aKGUsMCwxKSxuPVoobiwwLDEpLGU9PT0wKXRoaXMucj10aGlzLmc9dGhpcy5iPW47ZWxzZXtjb25zdCByPW48PS41P24qKDErZSk6bitlLW4qZSxvPTIqbi1yO3RoaXMucj1BbyhvLHIsdCsxLzMpLHRoaXMuZz1BbyhvLHIsdCksdGhpcy5iPUFvKG8scix0LTEvMyl9cmV0dXJuIGFlLmNvbG9yU3BhY2VUb1dvcmtpbmcodGhpcyxzKSx0aGlzfXNldFN0eWxlKHQsZT1vZSl7ZnVuY3Rpb24gbihyKXtyIT09dm9pZCAwJiZwYXJzZUZsb2F0KHIpPDEmJmNvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IEFscGhhIGNvbXBvbmVudCBvZiAiK3QrIiB3aWxsIGJlIGlnbm9yZWQuIil9bGV0IHM7aWYocz0vXihcdyspXCgoW15cKV0qKVwpLy5leGVjKHQpKXtsZXQgcjtjb25zdCBvPXNbMV0sYT1zWzJdO3N3aXRjaChvKXtjYXNlInJnYiI6Y2FzZSJyZ2JhIjppZihyPS9eXHMqKFxkKylccyosXHMqKFxkKylccyosXHMqKFxkKylccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRSR0IoTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMV0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMl0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbM10sMTApKS8yNTUsZSk7aWYocj0vXlxzKihcZCspXCVccyosXHMqKFxkKylcJVxzKixccyooXGQrKVwlXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0UkdCKE1hdGgubWluKDEwMCxwYXJzZUludChyWzFdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzJdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzNdLDEwKSkvMTAwLGUpO2JyZWFrO2Nhc2UiaHNsIjpjYXNlImhzbGEiOmlmKHI9L15ccyooXGQqXC4/XGQrKVxzKixccyooXGQqXC4/XGQrKVwlXHMqLFxzKihcZCpcLj9cZCspXCVccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRIU0wocGFyc2VGbG9hdChyWzFdKS8zNjAscGFyc2VGbG9hdChyWzJdKS8xMDAscGFyc2VGbG9hdChyWzNdKS8xMDAsZSk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkNvbG9yOiBVbmtub3duIGNvbG9yIG1vZGVsICIrdCl9fWVsc2UgaWYocz0vXlwjKFtBLUZhLWZcZF0rKSQvLmV4ZWModCkpe2NvbnN0IHI9c1sxXSxvPXIubGVuZ3RoO2lmKG89PT0zKXJldHVybiB0aGlzLnNldFJHQihwYXJzZUludChyLmNoYXJBdCgwKSwxNikvMTUscGFyc2VJbnQoci5jaGFyQXQoMSksMTYpLzE1LHBhcnNlSW50KHIuY2hhckF0KDIpLDE2KS8xNSxlKTtpZihvPT09NilyZXR1cm4gdGhpcy5zZXRIZXgocGFyc2VJbnQociwxNiksZSk7Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogSW52YWxpZCBoZXggY29sb3IgIit0KX1lbHNlIGlmKHQmJnQubGVuZ3RoPjApcmV0dXJuIHRoaXMuc2V0Q29sb3JOYW1lKHQsZSk7cmV0dXJuIHRoaXN9c2V0Q29sb3JOYW1lKHQsZT1vZSl7Y29uc3Qgbj1SY1t0LnRvTG93ZXJDYXNlKCldO3JldHVybiBuIT09dm9pZCAwP3RoaXMuc2V0SGV4KG4sZSk6Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogVW5rbm93biBjb2xvciAiK3QpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5yLHRoaXMuZyx0aGlzLmIpfWNvcHkodCl7cmV0dXJuIHRoaXMucj10LnIsdGhpcy5nPXQuZyx0aGlzLmI9dC5iLHRoaXN9Y29weVNSR0JUb0xpbmVhcih0KXtyZXR1cm4gdGhpcy5yPV9lKHQuciksdGhpcy5nPV9lKHQuZyksdGhpcy5iPV9lKHQuYiksdGhpc31jb3B5TGluZWFyVG9TUkdCKHQpe3JldHVybiB0aGlzLnI9SW4odC5yKSx0aGlzLmc9SW4odC5nKSx0aGlzLmI9SW4odC5iKSx0aGlzfWNvbnZlcnRTUkdCVG9MaW5lYXIoKXtyZXR1cm4gdGhpcy5jb3B5U1JHQlRvTGluZWFyKHRoaXMpLHRoaXN9Y29udmVydExpbmVhclRvU1JHQigpe3JldHVybiB0aGlzLmNvcHlMaW5lYXJUb1NSR0IodGhpcyksdGhpc31nZXRIZXgodD1vZSl7cmV0dXJuIGFlLndvcmtpbmdUb0NvbG9yU3BhY2UoU3QuY29weSh0aGlzKSx0KSxNYXRoLnJvdW5kKFooU3QucioyNTUsMCwyNTUpKSo2NTUzNitNYXRoLnJvdW5kKFooU3QuZyoyNTUsMCwyNTUpKSoyNTYrTWF0aC5yb3VuZChaKFN0LmIqMjU1LDAsMjU1KSl9Z2V0SGV4U3RyaW5nKHQ9b2Upe3JldHVybigiMDAwMDAwIit0aGlzLmdldEhleCh0KS50b1N0cmluZygxNikpLnNsaWNlKC02KX1nZXRIU0wodCxlPWFlLndvcmtpbmdDb2xvclNwYWNlKXthZS53b3JraW5nVG9Db2xvclNwYWNlKFN0LmNvcHkodGhpcyksZSk7Y29uc3Qgbj1TdC5yLHM9U3QuZyxyPVN0LmIsbz1NYXRoLm1heChuLHMsciksYT1NYXRoLm1pbihuLHMscik7bGV0IGMsbDtjb25zdCBoPShhK28pLzI7aWYoYT09PW8pYz0wLGw9MDtlbHNle2NvbnN0IHU9by1hO3N3aXRjaChsPWg8PS41P3UvKG8rYSk6dS8oMi1vLWEpLG8pe2Nhc2UgbjpjPShzLXIpL3UrKHM8cj82OjApO2JyZWFrO2Nhc2UgczpjPShyLW4pL3UrMjticmVhaztjYXNlIHI6Yz0obi1zKS91KzQ7YnJlYWt9Yy89Nn1yZXR1cm4gdC5oPWMsdC5zPWwsdC5sPWgsdH1nZXRSR0IodCxlPWFlLndvcmtpbmdDb2xvclNwYWNlKXtyZXR1cm4gYWUud29ya2luZ1RvQ29sb3JTcGFjZShTdC5jb3B5KHRoaXMpLGUpLHQucj1TdC5yLHQuZz1TdC5nLHQuYj1TdC5iLHR9Z2V0U3R5bGUodD1vZSl7YWUud29ya2luZ1RvQ29sb3JTcGFjZShTdC5jb3B5KHRoaXMpLHQpO2NvbnN0IGU9U3QucixuPVN0Lmcscz1TdC5iO3JldHVybiB0IT09b2U/YGNvbG9yKCR7dH0gJHtlLnRvRml4ZWQoMyl9ICR7bi50b0ZpeGVkKDMpfSAke3MudG9GaXhlZCgzKX0pYDpgcmdiKCR7TWF0aC5yb3VuZChlKjI1NSl9LCR7TWF0aC5yb3VuZChuKjI1NSl9LCR7TWF0aC5yb3VuZChzKjI1NSl9KWB9b2Zmc2V0SFNMKHQsZSxuKXtyZXR1cm4gdGhpcy5nZXRIU0woUWUpLHRoaXMuc2V0SFNMKFFlLmgrdCxRZS5zK2UsUWUubCtuKX1hZGQodCl7cmV0dXJuIHRoaXMucis9dC5yLHRoaXMuZys9dC5nLHRoaXMuYis9dC5iLHRoaXN9YWRkQ29sb3JzKHQsZSl7cmV0dXJuIHRoaXMucj10LnIrZS5yLHRoaXMuZz10LmcrZS5nLHRoaXMuYj10LmIrZS5iLHRoaXN9YWRkU2NhbGFyKHQpe3JldHVybiB0aGlzLnIrPXQsdGhpcy5nKz10LHRoaXMuYis9dCx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy5yPU1hdGgubWF4KDAsdGhpcy5yLXQuciksdGhpcy5nPU1hdGgubWF4KDAsdGhpcy5nLXQuZyksdGhpcy5iPU1hdGgubWF4KDAsdGhpcy5iLXQuYiksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5yKj10LnIsdGhpcy5nKj10LmcsdGhpcy5iKj10LmIsdGhpc31tdWx0aXBseVNjYWxhcih0KXtyZXR1cm4gdGhpcy5yKj10LHRoaXMuZyo9dCx0aGlzLmIqPXQsdGhpc31sZXJwKHQsZSl7cmV0dXJuIHRoaXMucis9KHQuci10aGlzLnIpKmUsdGhpcy5nKz0odC5nLXRoaXMuZykqZSx0aGlzLmIrPSh0LmItdGhpcy5iKSplLHRoaXN9bGVycENvbG9ycyh0LGUsbil7cmV0dXJuIHRoaXMucj10LnIrKGUuci10LnIpKm4sdGhpcy5nPXQuZysoZS5nLXQuZykqbix0aGlzLmI9dC5iKyhlLmItdC5iKSpuLHRoaXN9bGVycEhTTCh0LGUpe3RoaXMuZ2V0SFNMKFFlKSx0LmdldEhTTChwcyk7Y29uc3Qgbj1lbyhRZS5oLHBzLmgsZSkscz1lbyhRZS5zLHBzLnMsZSkscj1lbyhRZS5sLHBzLmwsZSk7cmV0dXJuIHRoaXMuc2V0SFNMKG4scyxyKSx0aGlzfXNldEZyb21WZWN0b3IzKHQpe3JldHVybiB0aGlzLnI9dC54LHRoaXMuZz10LnksdGhpcy5iPXQueix0aGlzfWFwcGx5TWF0cml4Myh0KXtjb25zdCBlPXRoaXMucixuPXRoaXMuZyxzPXRoaXMuYixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMucj1yWzBdKmUrclszXSpuK3JbNl0qcyx0aGlzLmc9clsxXSplK3JbNF0qbityWzddKnMsdGhpcy5iPXJbMl0qZStyWzVdKm4rcls4XSpzLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0LnI9PT10aGlzLnImJnQuZz09PXRoaXMuZyYmdC5iPT09dGhpcy5ifWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMucj10W2VdLHRoaXMuZz10W2UrMV0sdGhpcy5iPXRbZSsyXSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMucix0W2UrMV09dGhpcy5nLHRbZSsyXT10aGlzLmIsdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMucj10LmdldFgoZSksdGhpcy5nPXQuZ2V0WShlKSx0aGlzLmI9dC5nZXRaKGUpLHRoaXN9dG9KU09OKCl7cmV0dXJuIHRoaXMuZ2V0SGV4KCl9KltTeW1ib2wuaXRlcmF0b3JdKCl7eWllbGQgdGhpcy5yLHlpZWxkIHRoaXMuZyx5aWVsZCB0aGlzLmJ9fTtjb25zdCBTdD1uZXcgeXM7eXMuTkFNRVM9UmM7bGV0IGRmPTA7Y2xhc3MgcGYgZXh0ZW5kcyBvc3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy5pc01hdGVyaWFsPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOmRmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy50eXBlPSJNYXRlcmlhbCIsdGhpcy5ibGVuZGluZz0xLHRoaXMuc2lkZT0wLHRoaXMudmVydGV4Q29sb3JzPSExLHRoaXMub3BhY2l0eT0xLHRoaXMudHJhbnNwYXJlbnQ9ITEsdGhpcy5hbHBoYUhhc2g9ITEsdGhpcy5ibGVuZFNyYz0yMDQsdGhpcy5ibGVuZERzdD0yMDUsdGhpcy5ibGVuZEVxdWF0aW9uPTEwMCx0aGlzLmJsZW5kU3JjQWxwaGE9bnVsbCx0aGlzLmJsZW5kRHN0QWxwaGE9bnVsbCx0aGlzLmJsZW5kRXF1YXRpb25BbHBoYT1udWxsLHRoaXMuYmxlbmRDb2xvcj1uZXcgeXMoMCwwLDApLHRoaXMuYmxlbmRBbHBoYT0wLHRoaXMuZGVwdGhGdW5jPTMsdGhpcy5kZXB0aFRlc3Q9ITAsdGhpcy5kZXB0aFdyaXRlPSEwLHRoaXMuc3RlbmNpbFdyaXRlTWFzaz0yNTUsdGhpcy5zdGVuY2lsRnVuYz01MTksdGhpcy5zdGVuY2lsUmVmPTAsdGhpcy5zdGVuY2lsRnVuY01hc2s9MjU1LHRoaXMuc3RlbmNpbEZhaWw9NzY4MCx0aGlzLnN0ZW5jaWxaRmFpbD03NjgwLHRoaXMuc3RlbmNpbFpQYXNzPTc2ODAsdGhpcy5zdGVuY2lsV3JpdGU9ITEsdGhpcy5jbGlwcGluZ1BsYW5lcz1udWxsLHRoaXMuY2xpcEludGVyc2VjdGlvbj0hMSx0aGlzLmNsaXBTaGFkb3dzPSExLHRoaXMuc2hhZG93U2lkZT1udWxsLHRoaXMuY29sb3JXcml0ZT0hMCx0aGlzLnByZWNpc2lvbj1udWxsLHRoaXMucG9seWdvbk9mZnNldD0hMSx0aGlzLnBvbHlnb25PZmZzZXRGYWN0b3I9MCx0aGlzLnBvbHlnb25PZmZzZXRVbml0cz0wLHRoaXMuZGl0aGVyaW5nPSExLHRoaXMuYWxwaGFUb0NvdmVyYWdlPSExLHRoaXMucHJlbXVsdGlwbGllZEFscGhhPSExLHRoaXMuZm9yY2VTaW5nbGVQYXNzPSExLHRoaXMuYWxsb3dPdmVycmlkZT0hMCx0aGlzLnZpc2libGU9ITAsdGhpcy50b25lTWFwcGVkPSEwLHRoaXMudXNlckRhdGE9e30sdGhpcy52ZXJzaW9uPTAsdGhpcy5fYWxwaGFUZXN0PTB9Z2V0IGFscGhhVGVzdCgpe3JldHVybiB0aGlzLl9hbHBoYVRlc3R9c2V0IGFscGhhVGVzdCh0KXt0aGlzLl9hbHBoYVRlc3Q+MCE9dD4wJiZ0aGlzLnZlcnNpb24rKyx0aGlzLl9hbHBoYVRlc3Q9dH1vbkJlZm9yZVJlbmRlcigpe31vbkJlZm9yZUNvbXBpbGUoKXt9Y3VzdG9tUHJvZ3JhbUNhY2hlS2V5KCl7cmV0dXJuIHRoaXMub25CZWZvcmVDb21waWxlLnRvU3RyaW5nKCl9c2V0VmFsdWVzKHQpe2lmKHQhPT12b2lkIDApZm9yKGNvbnN0IGUgaW4gdCl7Y29uc3Qgbj10W2VdO2lmKG49PT12b2lkIDApe2NvbnNvbGUud2FybihgVEhSRUUuTWF0ZXJpYWw6IHBhcmFtZXRlciAnJHtlfScgaGFzIHZhbHVlIG9mIHVuZGVmaW5lZC5gKTtjb250aW51ZX1jb25zdCBzPXRoaXNbZV07aWYocz09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5NYXRlcmlhbDogJyR7ZX0nIGlzIG5vdCBhIHByb3BlcnR5IG9mIFRIUkVFLiR7dGhpcy50eXBlfS5gKTtjb250aW51ZX1zJiZzLmlzQ29sb3I/cy5zZXQobik6cyYmcy5pc1ZlY3RvcjMmJm4mJm4uaXNWZWN0b3IzP3MuY29weShuKTp0aGlzW2VdPW59fXRvSlNPTih0KXtjb25zdCBlPXQ9PT12b2lkIDB8fHR5cGVvZiB0PT0ic3RyaW5nIjtlJiYodD17dGV4dHVyZXM6e30saW1hZ2VzOnt9fSk7Y29uc3Qgbj17bWV0YWRhdGE6e3ZlcnNpb246NC43LHR5cGU6Ik1hdGVyaWFsIixnZW5lcmF0b3I6Ik1hdGVyaWFsLnRvSlNPTiJ9fTtuLnV1aWQ9dGhpcy51dWlkLG4udHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJihuLm5hbWU9dGhpcy5uYW1lKSx0aGlzLmNvbG9yJiZ0aGlzLmNvbG9yLmlzQ29sb3ImJihuLmNvbG9yPXRoaXMuY29sb3IuZ2V0SGV4KCkpLHRoaXMucm91Z2huZXNzIT09dm9pZCAwJiYobi5yb3VnaG5lc3M9dGhpcy5yb3VnaG5lc3MpLHRoaXMubWV0YWxuZXNzIT09dm9pZCAwJiYobi5tZXRhbG5lc3M9dGhpcy5tZXRhbG5lc3MpLHRoaXMuc2hlZW4hPT12b2lkIDAmJihuLnNoZWVuPXRoaXMuc2hlZW4pLHRoaXMuc2hlZW5Db2xvciYmdGhpcy5zaGVlbkNvbG9yLmlzQ29sb3ImJihuLnNoZWVuQ29sb3I9dGhpcy5zaGVlbkNvbG9yLmdldEhleCgpKSx0aGlzLnNoZWVuUm91Z2huZXNzIT09dm9pZCAwJiYobi5zaGVlblJvdWdobmVzcz10aGlzLnNoZWVuUm91Z2huZXNzKSx0aGlzLmVtaXNzaXZlJiZ0aGlzLmVtaXNzaXZlLmlzQ29sb3ImJihuLmVtaXNzaXZlPXRoaXMuZW1pc3NpdmUuZ2V0SGV4KCkpLHRoaXMuZW1pc3NpdmVJbnRlbnNpdHkhPT12b2lkIDAmJnRoaXMuZW1pc3NpdmVJbnRlbnNpdHkhPT0xJiYobi5lbWlzc2l2ZUludGVuc2l0eT10aGlzLmVtaXNzaXZlSW50ZW5zaXR5KSx0aGlzLnNwZWN1bGFyJiZ0aGlzLnNwZWN1bGFyLmlzQ29sb3ImJihuLnNwZWN1bGFyPXRoaXMuc3BlY3VsYXIuZ2V0SGV4KCkpLHRoaXMuc3BlY3VsYXJJbnRlbnNpdHkhPT12b2lkIDAmJihuLnNwZWN1bGFySW50ZW5zaXR5PXRoaXMuc3BlY3VsYXJJbnRlbnNpdHkpLHRoaXMuc3BlY3VsYXJDb2xvciYmdGhpcy5zcGVjdWxhckNvbG9yLmlzQ29sb3ImJihuLnNwZWN1bGFyQ29sb3I9dGhpcy5zcGVjdWxhckNvbG9yLmdldEhleCgpKSx0aGlzLnNoaW5pbmVzcyE9PXZvaWQgMCYmKG4uc2hpbmluZXNzPXRoaXMuc2hpbmluZXNzKSx0aGlzLmNsZWFyY29hdCE9PXZvaWQgMCYmKG4uY2xlYXJjb2F0PXRoaXMuY2xlYXJjb2F0KSx0aGlzLmNsZWFyY29hdFJvdWdobmVzcyE9PXZvaWQgMCYmKG4uY2xlYXJjb2F0Um91Z2huZXNzPXRoaXMuY2xlYXJjb2F0Um91Z2huZXNzKSx0aGlzLmNsZWFyY29hdE1hcCYmdGhpcy5jbGVhcmNvYXRNYXAuaXNUZXh0dXJlJiYobi5jbGVhcmNvYXRNYXA9dGhpcy5jbGVhcmNvYXRNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuY2xlYXJjb2F0Um91Z2huZXNzTWFwJiZ0aGlzLmNsZWFyY29hdFJvdWdobmVzc01hcC5pc1RleHR1cmUmJihuLmNsZWFyY29hdFJvdWdobmVzc01hcD10aGlzLmNsZWFyY29hdFJvdWdobmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5jbGVhcmNvYXROb3JtYWxNYXAmJnRoaXMuY2xlYXJjb2F0Tm9ybWFsTWFwLmlzVGV4dHVyZSYmKG4uY2xlYXJjb2F0Tm9ybWFsTWFwPXRoaXMuY2xlYXJjb2F0Tm9ybWFsTWFwLnRvSlNPTih0KS51dWlkLG4uY2xlYXJjb2F0Tm9ybWFsU2NhbGU9dGhpcy5jbGVhcmNvYXROb3JtYWxTY2FsZS50b0FycmF5KCkpLHRoaXMuZGlzcGVyc2lvbiE9PXZvaWQgMCYmKG4uZGlzcGVyc2lvbj10aGlzLmRpc3BlcnNpb24pLHRoaXMuaXJpZGVzY2VuY2UhPT12b2lkIDAmJihuLmlyaWRlc2NlbmNlPXRoaXMuaXJpZGVzY2VuY2UpLHRoaXMuaXJpZGVzY2VuY2VJT1IhPT12b2lkIDAmJihuLmlyaWRlc2NlbmNlSU9SPXRoaXMuaXJpZGVzY2VuY2VJT1IpLHRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NSYW5nZSE9PXZvaWQgMCYmKG4uaXJpZGVzY2VuY2VUaGlja25lc3NSYW5nZT10aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzUmFuZ2UpLHRoaXMuaXJpZGVzY2VuY2VNYXAmJnRoaXMuaXJpZGVzY2VuY2VNYXAuaXNUZXh0dXJlJiYobi5pcmlkZXNjZW5jZU1hcD10aGlzLmlyaWRlc2NlbmNlTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwJiZ0aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwLmlzVGV4dHVyZSYmKG4uaXJpZGVzY2VuY2VUaGlja25lc3NNYXA9dGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5hbmlzb3Ryb3B5IT09dm9pZCAwJiYobi5hbmlzb3Ryb3B5PXRoaXMuYW5pc290cm9weSksdGhpcy5hbmlzb3Ryb3B5Um90YXRpb24hPT12b2lkIDAmJihuLmFuaXNvdHJvcHlSb3RhdGlvbj10aGlzLmFuaXNvdHJvcHlSb3RhdGlvbiksdGhpcy5hbmlzb3Ryb3B5TWFwJiZ0aGlzLmFuaXNvdHJvcHlNYXAuaXNUZXh0dXJlJiYobi5hbmlzb3Ryb3B5TWFwPXRoaXMuYW5pc290cm9weU1hcC50b0pTT04odCkudXVpZCksdGhpcy5tYXAmJnRoaXMubWFwLmlzVGV4dHVyZSYmKG4ubWFwPXRoaXMubWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLm1hdGNhcCYmdGhpcy5tYXRjYXAuaXNUZXh0dXJlJiYobi5tYXRjYXA9dGhpcy5tYXRjYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuYWxwaGFNYXAmJnRoaXMuYWxwaGFNYXAuaXNUZXh0dXJlJiYobi5hbHBoYU1hcD10aGlzLmFscGhhTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmxpZ2h0TWFwJiZ0aGlzLmxpZ2h0TWFwLmlzVGV4dHVyZSYmKG4ubGlnaHRNYXA9dGhpcy5saWdodE1hcC50b0pTT04odCkudXVpZCxuLmxpZ2h0TWFwSW50ZW5zaXR5PXRoaXMubGlnaHRNYXBJbnRlbnNpdHkpLHRoaXMuYW9NYXAmJnRoaXMuYW9NYXAuaXNUZXh0dXJlJiYobi5hb01hcD10aGlzLmFvTWFwLnRvSlNPTih0KS51dWlkLG4uYW9NYXBJbnRlbnNpdHk9dGhpcy5hb01hcEludGVuc2l0eSksdGhpcy5idW1wTWFwJiZ0aGlzLmJ1bXBNYXAuaXNUZXh0dXJlJiYobi5idW1wTWFwPXRoaXMuYnVtcE1hcC50b0pTT04odCkudXVpZCxuLmJ1bXBTY2FsZT10aGlzLmJ1bXBTY2FsZSksdGhpcy5ub3JtYWxNYXAmJnRoaXMubm9ybWFsTWFwLmlzVGV4dHVyZSYmKG4ubm9ybWFsTWFwPXRoaXMubm9ybWFsTWFwLnRvSlNPTih0KS51dWlkLG4ubm9ybWFsTWFwVHlwZT10aGlzLm5vcm1hbE1hcFR5cGUsbi5ub3JtYWxTY2FsZT10aGlzLm5vcm1hbFNjYWxlLnRvQXJyYXkoKSksdGhpcy5kaXNwbGFjZW1lbnRNYXAmJnRoaXMuZGlzcGxhY2VtZW50TWFwLmlzVGV4dHVyZSYmKG4uZGlzcGxhY2VtZW50TWFwPXRoaXMuZGlzcGxhY2VtZW50TWFwLnRvSlNPTih0KS51dWlkLG4uZGlzcGxhY2VtZW50U2NhbGU9dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSxuLmRpc3BsYWNlbWVudEJpYXM9dGhpcy5kaXNwbGFjZW1lbnRCaWFzKSx0aGlzLnJvdWdobmVzc01hcCYmdGhpcy5yb3VnaG5lc3NNYXAuaXNUZXh0dXJlJiYobi5yb3VnaG5lc3NNYXA9dGhpcy5yb3VnaG5lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubWV0YWxuZXNzTWFwJiZ0aGlzLm1ldGFsbmVzc01hcC5pc1RleHR1cmUmJihuLm1ldGFsbmVzc01hcD10aGlzLm1ldGFsbmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5lbWlzc2l2ZU1hcCYmdGhpcy5lbWlzc2l2ZU1hcC5pc1RleHR1cmUmJihuLmVtaXNzaXZlTWFwPXRoaXMuZW1pc3NpdmVNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuc3BlY3VsYXJNYXAmJnRoaXMuc3BlY3VsYXJNYXAuaXNUZXh0dXJlJiYobi5zcGVjdWxhck1hcD10aGlzLnNwZWN1bGFyTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnNwZWN1bGFySW50ZW5zaXR5TWFwJiZ0aGlzLnNwZWN1bGFySW50ZW5zaXR5TWFwLmlzVGV4dHVyZSYmKG4uc3BlY3VsYXJJbnRlbnNpdHlNYXA9dGhpcy5zcGVjdWxhckludGVuc2l0eU1hcC50b0pTT04odCkudXVpZCksdGhpcy5zcGVjdWxhckNvbG9yTWFwJiZ0aGlzLnNwZWN1bGFyQ29sb3JNYXAuaXNUZXh0dXJlJiYobi5zcGVjdWxhckNvbG9yTWFwPXRoaXMuc3BlY3VsYXJDb2xvck1hcC50b0pTT04odCkudXVpZCksdGhpcy5lbnZNYXAmJnRoaXMuZW52TWFwLmlzVGV4dHVyZSYmKG4uZW52TWFwPXRoaXMuZW52TWFwLnRvSlNPTih0KS51dWlkLHRoaXMuY29tYmluZSE9PXZvaWQgMCYmKG4uY29tYmluZT10aGlzLmNvbWJpbmUpKSx0aGlzLmVudk1hcFJvdGF0aW9uIT09dm9pZCAwJiYobi5lbnZNYXBSb3RhdGlvbj10aGlzLmVudk1hcFJvdGF0aW9uLnRvQXJyYXkoKSksdGhpcy5lbnZNYXBJbnRlbnNpdHkhPT12b2lkIDAmJihuLmVudk1hcEludGVuc2l0eT10aGlzLmVudk1hcEludGVuc2l0eSksdGhpcy5yZWZsZWN0aXZpdHkhPT12b2lkIDAmJihuLnJlZmxlY3Rpdml0eT10aGlzLnJlZmxlY3Rpdml0eSksdGhpcy5yZWZyYWN0aW9uUmF0aW8hPT12b2lkIDAmJihuLnJlZnJhY3Rpb25SYXRpbz10aGlzLnJlZnJhY3Rpb25SYXRpbyksdGhpcy5ncmFkaWVudE1hcCYmdGhpcy5ncmFkaWVudE1hcC5pc1RleHR1cmUmJihuLmdyYWRpZW50TWFwPXRoaXMuZ3JhZGllbnRNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMudHJhbnNtaXNzaW9uIT09dm9pZCAwJiYobi50cmFuc21pc3Npb249dGhpcy50cmFuc21pc3Npb24pLHRoaXMudHJhbnNtaXNzaW9uTWFwJiZ0aGlzLnRyYW5zbWlzc2lvbk1hcC5pc1RleHR1cmUmJihuLnRyYW5zbWlzc2lvbk1hcD10aGlzLnRyYW5zbWlzc2lvbk1hcC50b0pTT04odCkudXVpZCksdGhpcy50aGlja25lc3MhPT12b2lkIDAmJihuLnRoaWNrbmVzcz10aGlzLnRoaWNrbmVzcyksdGhpcy50aGlja25lc3NNYXAmJnRoaXMudGhpY2tuZXNzTWFwLmlzVGV4dHVyZSYmKG4udGhpY2tuZXNzTWFwPXRoaXMudGhpY2tuZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmF0dGVudWF0aW9uRGlzdGFuY2UhPT12b2lkIDAmJnRoaXMuYXR0ZW51YXRpb25EaXN0YW5jZSE9PTEvMCYmKG4uYXR0ZW51YXRpb25EaXN0YW5jZT10aGlzLmF0dGVudWF0aW9uRGlzdGFuY2UpLHRoaXMuYXR0ZW51YXRpb25Db2xvciE9PXZvaWQgMCYmKG4uYXR0ZW51YXRpb25Db2xvcj10aGlzLmF0dGVudWF0aW9uQ29sb3IuZ2V0SGV4KCkpLHRoaXMuc2l6ZSE9PXZvaWQgMCYmKG4uc2l6ZT10aGlzLnNpemUpLHRoaXMuc2hhZG93U2lkZSE9PW51bGwmJihuLnNoYWRvd1NpZGU9dGhpcy5zaGFkb3dTaWRlKSx0aGlzLnNpemVBdHRlbnVhdGlvbiE9PXZvaWQgMCYmKG4uc2l6ZUF0dGVudWF0aW9uPXRoaXMuc2l6ZUF0dGVudWF0aW9uKSx0aGlzLmJsZW5kaW5nIT09MSYmKG4uYmxlbmRpbmc9dGhpcy5ibGVuZGluZyksdGhpcy5zaWRlIT09MCYmKG4uc2lkZT10aGlzLnNpZGUpLHRoaXMudmVydGV4Q29sb3JzPT09ITAmJihuLnZlcnRleENvbG9ycz0hMCksdGhpcy5vcGFjaXR5PDEmJihuLm9wYWNpdHk9dGhpcy5vcGFjaXR5KSx0aGlzLnRyYW5zcGFyZW50PT09ITAmJihuLnRyYW5zcGFyZW50PSEwKSx0aGlzLmJsZW5kU3JjIT09MjA0JiYobi5ibGVuZFNyYz10aGlzLmJsZW5kU3JjKSx0aGlzLmJsZW5kRHN0IT09MjA1JiYobi5ibGVuZERzdD10aGlzLmJsZW5kRHN0KSx0aGlzLmJsZW5kRXF1YXRpb24hPT0xMDAmJihuLmJsZW5kRXF1YXRpb249dGhpcy5ibGVuZEVxdWF0aW9uKSx0aGlzLmJsZW5kU3JjQWxwaGEhPT1udWxsJiYobi5ibGVuZFNyY0FscGhhPXRoaXMuYmxlbmRTcmNBbHBoYSksdGhpcy5ibGVuZERzdEFscGhhIT09bnVsbCYmKG4uYmxlbmREc3RBbHBoYT10aGlzLmJsZW5kRHN0QWxwaGEpLHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhIT09bnVsbCYmKG4uYmxlbmRFcXVhdGlvbkFscGhhPXRoaXMuYmxlbmRFcXVhdGlvbkFscGhhKSx0aGlzLmJsZW5kQ29sb3ImJnRoaXMuYmxlbmRDb2xvci5pc0NvbG9yJiYobi5ibGVuZENvbG9yPXRoaXMuYmxlbmRDb2xvci5nZXRIZXgoKSksdGhpcy5ibGVuZEFscGhhIT09MCYmKG4uYmxlbmRBbHBoYT10aGlzLmJsZW5kQWxwaGEpLHRoaXMuZGVwdGhGdW5jIT09MyYmKG4uZGVwdGhGdW5jPXRoaXMuZGVwdGhGdW5jKSx0aGlzLmRlcHRoVGVzdD09PSExJiYobi5kZXB0aFRlc3Q9dGhpcy5kZXB0aFRlc3QpLHRoaXMuZGVwdGhXcml0ZT09PSExJiYobi5kZXB0aFdyaXRlPXRoaXMuZGVwdGhXcml0ZSksdGhpcy5jb2xvcldyaXRlPT09ITEmJihuLmNvbG9yV3JpdGU9dGhpcy5jb2xvcldyaXRlKSx0aGlzLnN0ZW5jaWxXcml0ZU1hc2shPT0yNTUmJihuLnN0ZW5jaWxXcml0ZU1hc2s9dGhpcy5zdGVuY2lsV3JpdGVNYXNrKSx0aGlzLnN0ZW5jaWxGdW5jIT09NTE5JiYobi5zdGVuY2lsRnVuYz10aGlzLnN0ZW5jaWxGdW5jKSx0aGlzLnN0ZW5jaWxSZWYhPT0wJiYobi5zdGVuY2lsUmVmPXRoaXMuc3RlbmNpbFJlZiksdGhpcy5zdGVuY2lsRnVuY01hc2shPT0yNTUmJihuLnN0ZW5jaWxGdW5jTWFzaz10aGlzLnN0ZW5jaWxGdW5jTWFzayksdGhpcy5zdGVuY2lsRmFpbCE9PTc2ODAmJihuLnN0ZW5jaWxGYWlsPXRoaXMuc3RlbmNpbEZhaWwpLHRoaXMuc3RlbmNpbFpGYWlsIT09NzY4MCYmKG4uc3RlbmNpbFpGYWlsPXRoaXMuc3RlbmNpbFpGYWlsKSx0aGlzLnN0ZW5jaWxaUGFzcyE9PTc2ODAmJihuLnN0ZW5jaWxaUGFzcz10aGlzLnN0ZW5jaWxaUGFzcyksdGhpcy5zdGVuY2lsV3JpdGU9PT0hMCYmKG4uc3RlbmNpbFdyaXRlPXRoaXMuc3RlbmNpbFdyaXRlKSx0aGlzLnJvdGF0aW9uIT09dm9pZCAwJiZ0aGlzLnJvdGF0aW9uIT09MCYmKG4ucm90YXRpb249dGhpcy5yb3RhdGlvbiksdGhpcy5wb2x5Z29uT2Zmc2V0PT09ITAmJihuLnBvbHlnb25PZmZzZXQ9ITApLHRoaXMucG9seWdvbk9mZnNldEZhY3RvciE9PTAmJihuLnBvbHlnb25PZmZzZXRGYWN0b3I9dGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yKSx0aGlzLnBvbHlnb25PZmZzZXRVbml0cyE9PTAmJihuLnBvbHlnb25PZmZzZXRVbml0cz10aGlzLnBvbHlnb25PZmZzZXRVbml0cyksdGhpcy5saW5ld2lkdGghPT12b2lkIDAmJnRoaXMubGluZXdpZHRoIT09MSYmKG4ubGluZXdpZHRoPXRoaXMubGluZXdpZHRoKSx0aGlzLmRhc2hTaXplIT09dm9pZCAwJiYobi5kYXNoU2l6ZT10aGlzLmRhc2hTaXplKSx0aGlzLmdhcFNpemUhPT12b2lkIDAmJihuLmdhcFNpemU9dGhpcy5nYXBTaXplKSx0aGlzLnNjYWxlIT09dm9pZCAwJiYobi5zY2FsZT10aGlzLnNjYWxlKSx0aGlzLmRpdGhlcmluZz09PSEwJiYobi5kaXRoZXJpbmc9ITApLHRoaXMuYWxwaGFUZXN0PjAmJihuLmFscGhhVGVzdD10aGlzLmFscGhhVGVzdCksdGhpcy5hbHBoYUhhc2g9PT0hMCYmKG4uYWxwaGFIYXNoPSEwKSx0aGlzLmFscGhhVG9Db3ZlcmFnZT09PSEwJiYobi5hbHBoYVRvQ292ZXJhZ2U9ITApLHRoaXMucHJlbXVsdGlwbGllZEFscGhhPT09ITAmJihuLnByZW11bHRpcGxpZWRBbHBoYT0hMCksdGhpcy5mb3JjZVNpbmdsZVBhc3M9PT0hMCYmKG4uZm9yY2VTaW5nbGVQYXNzPSEwKSx0aGlzLndpcmVmcmFtZT09PSEwJiYobi53aXJlZnJhbWU9ITApLHRoaXMud2lyZWZyYW1lTGluZXdpZHRoPjEmJihuLndpcmVmcmFtZUxpbmV3aWR0aD10aGlzLndpcmVmcmFtZUxpbmV3aWR0aCksdGhpcy53aXJlZnJhbWVMaW5lY2FwIT09InJvdW5kIiYmKG4ud2lyZWZyYW1lTGluZWNhcD10aGlzLndpcmVmcmFtZUxpbmVjYXApLHRoaXMud2lyZWZyYW1lTGluZWpvaW4hPT0icm91bmQiJiYobi53aXJlZnJhbWVMaW5lam9pbj10aGlzLndpcmVmcmFtZUxpbmVqb2luKSx0aGlzLmZsYXRTaGFkaW5nPT09ITAmJihuLmZsYXRTaGFkaW5nPSEwKSx0aGlzLnZpc2libGU9PT0hMSYmKG4udmlzaWJsZT0hMSksdGhpcy50b25lTWFwcGVkPT09ITEmJihuLnRvbmVNYXBwZWQ9ITEpLHRoaXMuZm9nPT09ITEmJihuLmZvZz0hMSksT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihuLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpO2Z1bmN0aW9uIHMocil7Y29uc3Qgbz1bXTtmb3IoY29uc3QgYSBpbiByKXtjb25zdCBjPXJbYV07ZGVsZXRlIGMubWV0YWRhdGEsby5wdXNoKGMpfXJldHVybiBvfWlmKGUpe2NvbnN0IHI9cyh0LnRleHR1cmVzKSxvPXModC5pbWFnZXMpO3IubGVuZ3RoPjAmJihuLnRleHR1cmVzPXIpLG8ubGVuZ3RoPjAmJihuLmltYWdlcz1vKX1yZXR1cm4gbn1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXt0aGlzLm5hbWU9dC5uYW1lLHRoaXMuYmxlbmRpbmc9dC5ibGVuZGluZyx0aGlzLnNpZGU9dC5zaWRlLHRoaXMudmVydGV4Q29sb3JzPXQudmVydGV4Q29sb3JzLHRoaXMub3BhY2l0eT10Lm9wYWNpdHksdGhpcy50cmFuc3BhcmVudD10LnRyYW5zcGFyZW50LHRoaXMuYmxlbmRTcmM9dC5ibGVuZFNyYyx0aGlzLmJsZW5kRHN0PXQuYmxlbmREc3QsdGhpcy5ibGVuZEVxdWF0aW9uPXQuYmxlbmRFcXVhdGlvbix0aGlzLmJsZW5kU3JjQWxwaGE9dC5ibGVuZFNyY0FscGhhLHRoaXMuYmxlbmREc3RBbHBoYT10LmJsZW5kRHN0QWxwaGEsdGhpcy5ibGVuZEVxdWF0aW9uQWxwaGE9dC5ibGVuZEVxdWF0aW9uQWxwaGEsdGhpcy5ibGVuZENvbG9yLmNvcHkodC5ibGVuZENvbG9yKSx0aGlzLmJsZW5kQWxwaGE9dC5ibGVuZEFscGhhLHRoaXMuZGVwdGhGdW5jPXQuZGVwdGhGdW5jLHRoaXMuZGVwdGhUZXN0PXQuZGVwdGhUZXN0LHRoaXMuZGVwdGhXcml0ZT10LmRlcHRoV3JpdGUsdGhpcy5zdGVuY2lsV3JpdGVNYXNrPXQuc3RlbmNpbFdyaXRlTWFzayx0aGlzLnN0ZW5jaWxGdW5jPXQuc3RlbmNpbEZ1bmMsdGhpcy5zdGVuY2lsUmVmPXQuc3RlbmNpbFJlZix0aGlzLnN0ZW5jaWxGdW5jTWFzaz10LnN0ZW5jaWxGdW5jTWFzayx0aGlzLnN0ZW5jaWxGYWlsPXQuc3RlbmNpbEZhaWwsdGhpcy5zdGVuY2lsWkZhaWw9dC5zdGVuY2lsWkZhaWwsdGhpcy5zdGVuY2lsWlBhc3M9dC5zdGVuY2lsWlBhc3MsdGhpcy5zdGVuY2lsV3JpdGU9dC5zdGVuY2lsV3JpdGU7Y29uc3QgZT10LmNsaXBwaW5nUGxhbmVzO2xldCBuPW51bGw7aWYoZSE9PW51bGwpe2NvbnN0IHM9ZS5sZW5ndGg7bj1uZXcgQXJyYXkocyk7Zm9yKGxldCByPTA7ciE9PXM7KytyKW5bcl09ZVtyXS5jbG9uZSgpfXJldHVybiB0aGlzLmNsaXBwaW5nUGxhbmVzPW4sdGhpcy5jbGlwSW50ZXJzZWN0aW9uPXQuY2xpcEludGVyc2VjdGlvbix0aGlzLmNsaXBTaGFkb3dzPXQuY2xpcFNoYWRvd3MsdGhpcy5zaGFkb3dTaWRlPXQuc2hhZG93U2lkZSx0aGlzLmNvbG9yV3JpdGU9dC5jb2xvcldyaXRlLHRoaXMucHJlY2lzaW9uPXQucHJlY2lzaW9uLHRoaXMucG9seWdvbk9mZnNldD10LnBvbHlnb25PZmZzZXQsdGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yPXQucG9seWdvbk9mZnNldEZhY3Rvcix0aGlzLnBvbHlnb25PZmZzZXRVbml0cz10LnBvbHlnb25PZmZzZXRVbml0cyx0aGlzLmRpdGhlcmluZz10LmRpdGhlcmluZyx0aGlzLmFscGhhVGVzdD10LmFscGhhVGVzdCx0aGlzLmFscGhhSGFzaD10LmFscGhhSGFzaCx0aGlzLmFscGhhVG9Db3ZlcmFnZT10LmFscGhhVG9Db3ZlcmFnZSx0aGlzLnByZW11bHRpcGxpZWRBbHBoYT10LnByZW11bHRpcGxpZWRBbHBoYSx0aGlzLmZvcmNlU2luZ2xlUGFzcz10LmZvcmNlU2luZ2xlUGFzcyx0aGlzLnZpc2libGU9dC52aXNpYmxlLHRoaXMudG9uZU1hcHBlZD10LnRvbmVNYXBwZWQsdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSx0aGlzfWRpc3Bvc2UoKXt0aGlzLmRpc3BhdGNoRXZlbnQoe3R5cGU6ImRpc3Bvc2UifSl9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy52ZXJzaW9uKyt9fWNsYXNzIHlmIGV4dGVuZHMgcGZ7Y29uc3RydWN0b3IodCl7c3VwZXIoKSx0aGlzLmlzTWVzaEJhc2ljTWF0ZXJpYWw9ITAsdGhpcy50eXBlPSJNZXNoQmFzaWNNYXRlcmlhbCIsdGhpcy5jb2xvcj1uZXcgeXMoMTY3NzcyMTUpLHRoaXMubWFwPW51bGwsdGhpcy5saWdodE1hcD1udWxsLHRoaXMubGlnaHRNYXBJbnRlbnNpdHk9MSx0aGlzLmFvTWFwPW51bGwsdGhpcy5hb01hcEludGVuc2l0eT0xLHRoaXMuc3BlY3VsYXJNYXA9bnVsbCx0aGlzLmFscGhhTWFwPW51bGwsdGhpcy5lbnZNYXA9bnVsbCx0aGlzLmVudk1hcFJvdGF0aW9uPW5ldyBiaSx0aGlzLmNvbWJpbmU9MCx0aGlzLnJlZmxlY3Rpdml0eT0xLHRoaXMucmVmcmFjdGlvblJhdGlvPS45OCx0aGlzLndpcmVmcmFtZT0hMSx0aGlzLndpcmVmcmFtZUxpbmV3aWR0aD0xLHRoaXMud2lyZWZyYW1lTGluZWNhcD0icm91bmQiLHRoaXMud2lyZWZyYW1lTGluZWpvaW49InJvdW5kIix0aGlzLmZvZz0hMCx0aGlzLnNldFZhbHVlcyh0KX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMuY29sb3IuY29weSh0LmNvbG9yKSx0aGlzLm1hcD10Lm1hcCx0aGlzLmxpZ2h0TWFwPXQubGlnaHRNYXAsdGhpcy5saWdodE1hcEludGVuc2l0eT10LmxpZ2h0TWFwSW50ZW5zaXR5LHRoaXMuYW9NYXA9dC5hb01hcCx0aGlzLmFvTWFwSW50ZW5zaXR5PXQuYW9NYXBJbnRlbnNpdHksdGhpcy5zcGVjdWxhck1hcD10LnNwZWN1bGFyTWFwLHRoaXMuYWxwaGFNYXA9dC5hbHBoYU1hcCx0aGlzLmVudk1hcD10LmVudk1hcCx0aGlzLmVudk1hcFJvdGF0aW9uLmNvcHkodC5lbnZNYXBSb3RhdGlvbiksdGhpcy5jb21iaW5lPXQuY29tYmluZSx0aGlzLnJlZmxlY3Rpdml0eT10LnJlZmxlY3Rpdml0eSx0aGlzLnJlZnJhY3Rpb25SYXRpbz10LnJlZnJhY3Rpb25SYXRpbyx0aGlzLndpcmVmcmFtZT10LndpcmVmcmFtZSx0aGlzLndpcmVmcmFtZUxpbmV3aWR0aD10LndpcmVmcmFtZUxpbmV3aWR0aCx0aGlzLndpcmVmcmFtZUxpbmVjYXA9dC53aXJlZnJhbWVMaW5lY2FwLHRoaXMud2lyZWZyYW1lTGluZWpvaW49dC53aXJlZnJhbWVMaW5lam9pbix0aGlzLmZvZz10LmZvZyx0aGlzfX1jb25zdCBwdD1uZXcgVCxtcz1uZXcgUjtsZXQgbWY9MDtjbGFzcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbj0hMSl7aWYoQXJyYXkuaXNBcnJheSh0KSl0aHJvdyBuZXcgVHlwZUVycm9yKCJUSFJFRS5CdWZmZXJBdHRyaWJ1dGU6IGFycmF5IHNob3VsZCBiZSBhIFR5cGVkIEFycmF5LiIpO3RoaXMuaXNCdWZmZXJBdHRyaWJ1dGU9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6bWYrK30pLHRoaXMubmFtZT0iIix0aGlzLmFycmF5PXQsdGhpcy5pdGVtU2l6ZT1lLHRoaXMuY291bnQ9dCE9PXZvaWQgMD90Lmxlbmd0aC9lOjAsdGhpcy5ub3JtYWxpemVkPW4sdGhpcy51c2FnZT0zNTA0NCx0aGlzLnVwZGF0ZVJhbmdlcz1bXSx0aGlzLmdwdVR5cGU9MTAxNSx0aGlzLnZlcnNpb249MH1vblVwbG9hZENhbGxiYWNrKCl7fXNldCBuZWVkc1VwZGF0ZSh0KXt0PT09ITAmJnRoaXMudmVyc2lvbisrfXNldFVzYWdlKHQpe3JldHVybiB0aGlzLnVzYWdlPXQsdGhpc31hZGRVcGRhdGVSYW5nZSh0LGUpe3RoaXMudXBkYXRlUmFuZ2VzLnB1c2goe3N0YXJ0OnQsY291bnQ6ZX0pfWNsZWFyVXBkYXRlUmFuZ2VzKCl7dGhpcy51cGRhdGVSYW5nZXMubGVuZ3RoPTB9Y29weSh0KXtyZXR1cm4gdGhpcy5uYW1lPXQubmFtZSx0aGlzLmFycmF5PW5ldyB0LmFycmF5LmNvbnN0cnVjdG9yKHQuYXJyYXkpLHRoaXMuaXRlbVNpemU9dC5pdGVtU2l6ZSx0aGlzLmNvdW50PXQuY291bnQsdGhpcy5ub3JtYWxpemVkPXQubm9ybWFsaXplZCx0aGlzLnVzYWdlPXQudXNhZ2UsdGhpcy5ncHVUeXBlPXQuZ3B1VHlwZSx0aGlzfWNvcHlBdCh0LGUsbil7dCo9dGhpcy5pdGVtU2l6ZSxuKj1lLml0ZW1TaXplO2ZvcihsZXQgcz0wLHI9dGhpcy5pdGVtU2l6ZTtzPHI7cysrKXRoaXMuYXJyYXlbdCtzXT1lLmFycmF5W24rc107cmV0dXJuIHRoaXN9Y29weUFycmF5KHQpe3JldHVybiB0aGlzLmFycmF5LnNldCh0KSx0aGlzfWFwcGx5TWF0cml4Myh0KXtpZih0aGlzLml0ZW1TaXplPT09Milmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKyltcy5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSksbXMuYXBwbHlNYXRyaXgzKHQpLHRoaXMuc2V0WFkoZSxtcy54LG1zLnkpO2Vsc2UgaWYodGhpcy5pdGVtU2l6ZT09PTMpZm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LmFwcGx5TWF0cml4Myh0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc31hcHBseU1hdHJpeDQodCl7Zm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LmFwcGx5TWF0cml4NCh0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc31hcHBseU5vcm1hbE1hdHJpeCh0KXtmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQuYXBwbHlOb3JtYWxNYXRyaXgodCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9dHJhbnNmb3JtRGlyZWN0aW9uKHQpe2ZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC50cmFuc2Zvcm1EaXJlY3Rpb24odCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9c2V0KHQsZT0wKXtyZXR1cm4gdGhpcy5hcnJheS5zZXQodCxlKSx0aGlzfWdldENvbXBvbmVudCh0LGUpe2xldCBuPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplK2VdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihuPW1pKG4sdGhpcy5hcnJheSkpLG59c2V0Q29tcG9uZW50KHQsZSxuKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYobj1JdChuLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZStlXT1uLHRoaXN9Z2V0WCh0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZV07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9bWkoZSx0aGlzLmFycmF5KSksZX1zZXRYKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemVdPWUsdGhpc31nZXRZKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzFdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0WSh0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzFdPWUsdGhpc31nZXRaKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzJdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0Wih0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzJdPWUsdGhpc31nZXRXKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzNdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0Vyh0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzNdPWUsdGhpc31zZXRYWSh0LGUsbil7cmV0dXJuIHQqPXRoaXMuaXRlbVNpemUsdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpLG49SXQobix0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KzBdPWUsdGhpcy5hcnJheVt0KzFdPW4sdGhpc31zZXRYWVoodCxlLG4scyl7cmV0dXJuIHQqPXRoaXMuaXRlbVNpemUsdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpLG49SXQobix0aGlzLmFycmF5KSxzPUl0KHMsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCswXT1lLHRoaXMuYXJyYXlbdCsxXT1uLHRoaXMuYXJyYXlbdCsyXT1zLHRoaXN9c2V0WFlaVyh0LGUsbixzLHIpe3JldHVybiB0Kj10aGlzLml0ZW1TaXplLHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSxuPUl0KG4sdGhpcy5hcnJheSkscz1JdChzLHRoaXMuYXJyYXkpLHI9SXQocix0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KzBdPWUsdGhpcy5hcnJheVt0KzFdPW4sdGhpcy5hcnJheVt0KzJdPXMsdGhpcy5hcnJheVt0KzNdPXIsdGhpc31vblVwbG9hZCh0KXtyZXR1cm4gdGhpcy5vblVwbG9hZENhbGxiYWNrPXQsdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmFycmF5LHRoaXMuaXRlbVNpemUpLmNvcHkodGhpcyl9dG9KU09OKCl7Y29uc3QgdD17aXRlbVNpemU6dGhpcy5pdGVtU2l6ZSx0eXBlOnRoaXMuYXJyYXkuY29uc3RydWN0b3IubmFtZSxhcnJheTpBcnJheS5mcm9tKHRoaXMuYXJyYXkpLG5vcm1hbGl6ZWQ6dGhpcy5ub3JtYWxpemVkfTtyZXR1cm4gdGhpcy5uYW1lIT09IiImJih0Lm5hbWU9dGhpcy5uYW1lKSx0aGlzLnVzYWdlIT09MzUwNDQmJih0LnVzYWdlPXRoaXMudXNhZ2UpLHR9fWNsYXNzIGdmIGV4dGVuZHMgeHR7Y29uc3RydWN0b3IodCxlLG4pe3N1cGVyKG5ldyBVaW50MTZBcnJheSh0KSxlLG4pfX1jbGFzcyB4ZiBleHRlbmRzIHh0e2NvbnN0cnVjdG9yKHQsZSxuKXtzdXBlcihuZXcgVWludDMyQXJyYXkodCksZSxuKX19Y2xhc3MgQmUgZXh0ZW5kcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbil7c3VwZXIobmV3IEZsb2F0MzJBcnJheSh0KSxlLG4pfX1sZXQgd2Y9MDtjb25zdCBqdD1uZXcgc3QsU289bmV3IEVlLHFuPW5ldyBULFZ0PW5ldyBndCxBaT1uZXcgZ3QsYnQ9bmV3IFQ7Y2xhc3MgdWUgZXh0ZW5kcyBvc3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy5pc0J1ZmZlckdlb21ldHJ5PSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOndmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy50eXBlPSJCdWZmZXJHZW9tZXRyeSIsdGhpcy5pbmRleD1udWxsLHRoaXMuaW5kaXJlY3Q9bnVsbCx0aGlzLmF0dHJpYnV0ZXM9e30sdGhpcy5tb3JwaEF0dHJpYnV0ZXM9e30sdGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT0hMSx0aGlzLmdyb3Vwcz1bXSx0aGlzLmJvdW5kaW5nQm94PW51bGwsdGhpcy5ib3VuZGluZ1NwaGVyZT1udWxsLHRoaXMuZHJhd1JhbmdlPXtzdGFydDowLGNvdW50OjEvMH0sdGhpcy51c2VyRGF0YT17fX1nZXRJbmRleCgpe3JldHVybiB0aGlzLmluZGV4fXNldEluZGV4KHQpe3JldHVybiBBcnJheS5pc0FycmF5KHQpP3RoaXMuaW5kZXg9bmV3KFF1KHQpP3hmOmdmKSh0LDEpOnRoaXMuaW5kZXg9dCx0aGlzfXNldEluZGlyZWN0KHQpe3JldHVybiB0aGlzLmluZGlyZWN0PXQsdGhpc31nZXRJbmRpcmVjdCgpe3JldHVybiB0aGlzLmluZGlyZWN0fWdldEF0dHJpYnV0ZSh0KXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdfXNldEF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF09ZSx0aGlzfWRlbGV0ZUF0dHJpYnV0ZSh0KXtyZXR1cm4gZGVsZXRlIHRoaXMuYXR0cmlidXRlc1t0XSx0aGlzfWhhc0F0dHJpYnV0ZSh0KXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdIT09dm9pZCAwfWFkZEdyb3VwKHQsZSxuPTApe3RoaXMuZ3JvdXBzLnB1c2goe3N0YXJ0OnQsY291bnQ6ZSxtYXRlcmlhbEluZGV4Om59KX1jbGVhckdyb3Vwcygpe3RoaXMuZ3JvdXBzPVtdfXNldERyYXdSYW5nZSh0LGUpe3RoaXMuZHJhd1JhbmdlLnN0YXJ0PXQsdGhpcy5kcmF3UmFuZ2UuY291bnQ9ZX1hcHBseU1hdHJpeDQodCl7Y29uc3QgZT10aGlzLmF0dHJpYnV0ZXMucG9zaXRpb247ZSE9PXZvaWQgMCYmKGUuYXBwbHlNYXRyaXg0KHQpLGUubmVlZHNVcGRhdGU9ITApO2NvbnN0IG49dGhpcy5hdHRyaWJ1dGVzLm5vcm1hbDtpZihuIT09dm9pZCAwKXtjb25zdCByPW5ldyBnZSgpLmdldE5vcm1hbE1hdHJpeCh0KTtuLmFwcGx5Tm9ybWFsTWF0cml4KHIpLG4ubmVlZHNVcGRhdGU9ITB9Y29uc3Qgcz10aGlzLmF0dHJpYnV0ZXMudGFuZ2VudDtyZXR1cm4gcyE9PXZvaWQgMCYmKHMudHJhbnNmb3JtRGlyZWN0aW9uKHQpLHMubmVlZHNVcGRhdGU9ITApLHRoaXMuYm91bmRpbmdCb3ghPT1udWxsJiZ0aGlzLmNvbXB1dGVCb3VuZGluZ0JveCgpLHRoaXMuYm91bmRpbmdTcGhlcmUhPT1udWxsJiZ0aGlzLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpLHRoaXN9YXBwbHlRdWF0ZXJuaW9uKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25Gcm9tUXVhdGVybmlvbih0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31yb3RhdGVYKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25YKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXJvdGF0ZVkodCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvblkodCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9cm90YXRlWih0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uWih0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc310cmFuc2xhdGUodCxlLG4pe3JldHVybiBqdC5tYWtlVHJhbnNsYXRpb24odCxlLG4pLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXNjYWxlKHQsZSxuKXtyZXR1cm4ganQubWFrZVNjYWxlKHQsZSxuKSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31sb29rQXQodCl7cmV0dXJuIFNvLmxvb2tBdCh0KSxTby51cGRhdGVNYXRyaXgoKSx0aGlzLmFwcGx5TWF0cml4NChTby5tYXRyaXgpLHRoaXN9Y2VudGVyKCl7cmV0dXJuIHRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCksdGhpcy5ib3VuZGluZ0JveC5nZXRDZW50ZXIocW4pLm5lZ2F0ZSgpLHRoaXMudHJhbnNsYXRlKHFuLngscW4ueSxxbi56KSx0aGlzfXNldEZyb21Qb2ludHModCl7Y29uc3QgZT10aGlzLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKTtpZihlPT09dm9pZCAwKXtjb25zdCBuPVtdO2ZvcihsZXQgcz0wLHI9dC5sZW5ndGg7czxyO3MrKyl7Y29uc3Qgbz10W3NdO24ucHVzaChvLngsby55LG8uenx8MCl9dGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQmUobiwzKSl9ZWxzZXtjb25zdCBuPU1hdGgubWluKHQubGVuZ3RoLGUuY291bnQpO2ZvcihsZXQgcz0wO3M8bjtzKyspe2NvbnN0IHI9dFtzXTtlLnNldFhZWihzLHIueCxyLnksci56fHwwKX10Lmxlbmd0aD5lLmNvdW50JiZjb25zb2xlLndhcm4oIlRIUkVFLkJ1ZmZlckdlb21ldHJ5OiBCdWZmZXIgc2l6ZSB0b28gc21hbGwgZm9yIHBvaW50cyBkYXRhLiBVc2UgLmRpc3Bvc2UoKSBhbmQgY3JlYXRlIGEgbmV3IGdlb21ldHJ5LiIpLGUubmVlZHNVcGRhdGU9ITB9cmV0dXJuIHRoaXN9Y29tcHV0ZUJvdW5kaW5nQm94KCl7dGhpcy5ib3VuZGluZ0JveD09PW51bGwmJih0aGlzLmJvdW5kaW5nQm94PW5ldyBndCk7Y29uc3QgdD10aGlzLmF0dHJpYnV0ZXMucG9zaXRpb24sZT10aGlzLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbjtpZih0JiZ0LmlzR0xCdWZmZXJBdHRyaWJ1dGUpe2NvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ0JveCgpOiBHTEJ1ZmZlckF0dHJpYnV0ZSByZXF1aXJlcyBhIG1hbnVhbCBib3VuZGluZyBib3guIix0aGlzKSx0aGlzLmJvdW5kaW5nQm94LnNldChuZXcgVCgtMS8wLC0xLzAsLTEvMCksbmV3IFQoMS8wLDEvMCwxLzApKTtyZXR1cm59aWYodCE9PXZvaWQgMCl7aWYodGhpcy5ib3VuZGluZ0JveC5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHQpLGUpZm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKXtjb25zdCByPWVbbl07VnQuc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZShyKSx0aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPyhidC5hZGRWZWN0b3JzKHRoaXMuYm91bmRpbmdCb3gubWluLFZ0Lm1pbiksdGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KGJ0KSxidC5hZGRWZWN0b3JzKHRoaXMuYm91bmRpbmdCb3gubWF4LFZ0Lm1heCksdGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KGJ0KSk6KHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChWdC5taW4pLHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChWdC5tYXgpKX19ZWxzZSB0aGlzLmJvdW5kaW5nQm94Lm1ha2VFbXB0eSgpOyhpc05hTih0aGlzLmJvdW5kaW5nQm94Lm1pbi54KXx8aXNOYU4odGhpcy5ib3VuZGluZ0JveC5taW4ueSl8fGlzTmFOKHRoaXMuYm91bmRpbmdCb3gubWluLnopKSYmY29uc29sZS5lcnJvcignVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94KCk6IENvbXB1dGVkIG1pbi9tYXggaGF2ZSBOYU4gdmFsdWVzLiBUaGUgInBvc2l0aW9uIiBhdHRyaWJ1dGUgaXMgbGlrZWx5IHRvIGhhdmUgTmFOIHZhbHVlcy4nLHRoaXMpfWNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpe3RoaXMuYm91bmRpbmdTcGhlcmU9PT1udWxsJiYodGhpcy5ib3VuZGluZ1NwaGVyZT1uZXcgY28pO2NvbnN0IHQ9dGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uLGU9dGhpcy5tb3JwaEF0dHJpYnV0ZXMucG9zaXRpb247aWYodCYmdC5pc0dMQnVmZmVyQXR0cmlidXRlKXtjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTogR0xCdWZmZXJBdHRyaWJ1dGUgcmVxdWlyZXMgYSBtYW51YWwgYm91bmRpbmcgc3BoZXJlLiIsdGhpcyksdGhpcy5ib3VuZGluZ1NwaGVyZS5zZXQobmV3IFQsMS8wKTtyZXR1cm59aWYodCl7Y29uc3Qgbj10aGlzLmJvdW5kaW5nU3BoZXJlLmNlbnRlcjtpZihWdC5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHQpLGUpZm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl07QWkuc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZShhKSx0aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPyhidC5hZGRWZWN0b3JzKFZ0Lm1pbixBaS5taW4pLFZ0LmV4cGFuZEJ5UG9pbnQoYnQpLGJ0LmFkZFZlY3RvcnMoVnQubWF4LEFpLm1heCksVnQuZXhwYW5kQnlQb2ludChidCkpOihWdC5leHBhbmRCeVBvaW50KEFpLm1pbiksVnQuZXhwYW5kQnlQb2ludChBaS5tYXgpKX1WdC5nZXRDZW50ZXIobik7bGV0IHM9MDtmb3IobGV0IHI9MCxvPXQuY291bnQ7cjxvO3IrKylidC5mcm9tQnVmZmVyQXR0cmlidXRlKHQscikscz1NYXRoLm1heChzLG4uZGlzdGFuY2VUb1NxdWFyZWQoYnQpKTtpZihlKWZvcihsZXQgcj0wLG89ZS5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1lW3JdLGM9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZTtmb3IobGV0IGw9MCxoPWEuY291bnQ7bDxoO2wrKylidC5mcm9tQnVmZmVyQXR0cmlidXRlKGEsbCksYyYmKHFuLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxsKSxidC5hZGQocW4pKSxzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZChidCkpfXRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzPU1hdGguc3FydChzKSxpc05hTih0aGlzLmJvdW5kaW5nU3BoZXJlLnJhZGl1cykmJmNvbnNvbGUuZXJyb3IoJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpOiBDb21wdXRlZCByYWRpdXMgaXMgTmFOLiBUaGUgInBvc2l0aW9uIiBhdHRyaWJ1dGUgaXMgbGlrZWx5IHRvIGhhdmUgTmFOIHZhbHVlcy4nLHRoaXMpfX1jb21wdXRlVGFuZ2VudHMoKXtjb25zdCB0PXRoaXMuaW5kZXgsZT10aGlzLmF0dHJpYnV0ZXM7aWYodD09PW51bGx8fGUucG9zaXRpb249PT12b2lkIDB8fGUubm9ybWFsPT09dm9pZCAwfHxlLnV2PT09dm9pZCAwKXtjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmNvbXB1dGVUYW5nZW50cygpIGZhaWxlZC4gTWlzc2luZyByZXF1aXJlZCBhdHRyaWJ1dGVzIChpbmRleCwgcG9zaXRpb24sIG5vcm1hbCBvciB1dikiKTtyZXR1cm59Y29uc3Qgbj1lLnBvc2l0aW9uLHM9ZS5ub3JtYWwscj1lLnV2O3RoaXMuaGFzQXR0cmlidXRlKCJ0YW5nZW50Iik9PT0hMSYmdGhpcy5zZXRBdHRyaWJ1dGUoInRhbmdlbnQiLG5ldyB4dChuZXcgRmxvYXQzMkFycmF5KDQqbi5jb3VudCksNCkpO2NvbnN0IG89dGhpcy5nZXRBdHRyaWJ1dGUoInRhbmdlbnQiKSxhPVtdLGM9W107Zm9yKGxldCBfPTA7XzxuLmNvdW50O18rKylhW19dPW5ldyBULGNbX109bmV3IFQ7Y29uc3QgbD1uZXcgVCxoPW5ldyBULHU9bmV3IFQsZj1uZXcgUixkPW5ldyBSLHA9bmV3IFIseT1uZXcgVCxtPW5ldyBUO2Z1bmN0aW9uIGcoXyxFLHope2wuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLF8pLGguZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLEUpLHUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHopLGYuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLF8pLGQuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLEUpLHAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLHopLGguc3ViKGwpLHUuc3ViKGwpLGQuc3ViKGYpLHAuc3ViKGYpO2NvbnN0IHY9MS8oZC54KnAueS1wLngqZC55KTtpc0Zpbml0ZSh2KSYmKHkuY29weShoKS5tdWx0aXBseVNjYWxhcihwLnkpLmFkZFNjYWxlZFZlY3Rvcih1LC1kLnkpLm11bHRpcGx5U2NhbGFyKHYpLG0uY29weSh1KS5tdWx0aXBseVNjYWxhcihkLngpLmFkZFNjYWxlZFZlY3RvcihoLC1wLngpLm11bHRpcGx5U2NhbGFyKHYpLGFbX10uYWRkKHkpLGFbRV0uYWRkKHkpLGFbel0uYWRkKHkpLGNbX10uYWRkKG0pLGNbRV0uYWRkKG0pLGNbel0uYWRkKG0pKX1sZXQgYj10aGlzLmdyb3VwcztiLmxlbmd0aD09PTAmJihiPVt7c3RhcnQ6MCxjb3VudDp0LmNvdW50fV0pO2ZvcihsZXQgXz0wLEU9Yi5sZW5ndGg7XzxFOysrXyl7Y29uc3Qgej1iW19dLHY9ei5zdGFydCxDPXouY291bnQ7Zm9yKGxldCBQPXYsRj12K0M7UDxGO1ArPTMpZyh0LmdldFgoUCswKSx0LmdldFgoUCsxKSx0LmdldFgoUCsyKSl9Y29uc3Qgdz1uZXcgVCx4PW5ldyBULE09bmV3IFQsQT1uZXcgVDtmdW5jdGlvbiBTKF8pe00uZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLF8pLEEuY29weShNKTtjb25zdCBFPWFbX107dy5jb3B5KEUpLHcuc3ViKE0ubXVsdGlwbHlTY2FsYXIoTS5kb3QoRSkpKS5ub3JtYWxpemUoKSx4LmNyb3NzVmVjdG9ycyhBLEUpO2NvbnN0IHY9eC5kb3QoY1tfXSk8MD8tMToxO28uc2V0WFlaVyhfLHcueCx3Lnksdy56LHYpfWZvcihsZXQgXz0wLEU9Yi5sZW5ndGg7XzxFOysrXyl7Y29uc3Qgej1iW19dLHY9ei5zdGFydCxDPXouY291bnQ7Zm9yKGxldCBQPXYsRj12K0M7UDxGO1ArPTMpUyh0LmdldFgoUCswKSksUyh0LmdldFgoUCsxKSksUyh0LmdldFgoUCsyKSl9fWNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCl7Y29uc3QgdD10aGlzLmluZGV4LGU9dGhpcy5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIik7aWYoZSE9PXZvaWQgMCl7bGV0IG49dGhpcy5nZXRBdHRyaWJ1dGUoIm5vcm1hbCIpO2lmKG49PT12b2lkIDApbj1uZXcgeHQobmV3IEZsb2F0MzJBcnJheShlLmNvdW50KjMpLDMpLHRoaXMuc2V0QXR0cmlidXRlKCJub3JtYWwiLG4pO2Vsc2UgZm9yKGxldCBmPTAsZD1uLmNvdW50O2Y8ZDtmKyspbi5zZXRYWVooZiwwLDAsMCk7Y29uc3Qgcz1uZXcgVCxyPW5ldyBULG89bmV3IFQsYT1uZXcgVCxjPW5ldyBULGw9bmV3IFQsaD1uZXcgVCx1PW5ldyBUO2lmKHQpZm9yKGxldCBmPTAsZD10LmNvdW50O2Y8ZDtmKz0zKXtjb25zdCBwPXQuZ2V0WChmKzApLHk9dC5nZXRYKGYrMSksbT10LmdldFgoZisyKTtzLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxwKSxyLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSx5KSxvLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxtKSxoLnN1YlZlY3RvcnMobyxyKSx1LnN1YlZlY3RvcnMocyxyKSxoLmNyb3NzKHUpLGEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHApLGMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHkpLGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLG0pLGEuYWRkKGgpLGMuYWRkKGgpLGwuYWRkKGgpLG4uc2V0WFlaKHAsYS54LGEueSxhLnopLG4uc2V0WFlaKHksYy54LGMueSxjLnopLG4uc2V0WFlaKG0sbC54LGwueSxsLnopfWVsc2UgZm9yKGxldCBmPTAsZD1lLmNvdW50O2Y8ZDtmKz0zKXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLGYrMCksci5mcm9tQnVmZmVyQXR0cmlidXRlKGUsZisxKSxvLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxmKzIpLGguc3ViVmVjdG9ycyhvLHIpLHUuc3ViVmVjdG9ycyhzLHIpLGguY3Jvc3ModSksbi5zZXRYWVooZiswLGgueCxoLnksaC56KSxuLnNldFhZWihmKzEsaC54LGgueSxoLnopLG4uc2V0WFlaKGYrMixoLngsaC55LGgueik7dGhpcy5ub3JtYWxpemVOb3JtYWxzKCksbi5uZWVkc1VwZGF0ZT0hMH19bm9ybWFsaXplTm9ybWFscygpe2NvbnN0IHQ9dGhpcy5hdHRyaWJ1dGVzLm5vcm1hbDtmb3IobGV0IGU9MCxuPXQuY291bnQ7ZTxuO2UrKylidC5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSksYnQubm9ybWFsaXplKCksdC5zZXRYWVooZSxidC54LGJ0LnksYnQueil9dG9Ob25JbmRleGVkKCl7ZnVuY3Rpb24gdChhLGMpe2NvbnN0IGw9YS5hcnJheSxoPWEuaXRlbVNpemUsdT1hLm5vcm1hbGl6ZWQsZj1uZXcgbC5jb25zdHJ1Y3RvcihjLmxlbmd0aCpoKTtsZXQgZD0wLHA9MDtmb3IobGV0IHk9MCxtPWMubGVuZ3RoO3k8bTt5Kyspe2EuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZT9kPWNbeV0qYS5kYXRhLnN0cmlkZSthLm9mZnNldDpkPWNbeV0qaDtmb3IobGV0IGc9MDtnPGg7ZysrKWZbcCsrXT1sW2QrK119cmV0dXJuIG5ldyB4dChmLGgsdSl9aWYodGhpcy5pbmRleD09PW51bGwpcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnkudG9Ob25JbmRleGVkKCk6IEJ1ZmZlckdlb21ldHJ5IGlzIGFscmVhZHkgbm9uLWluZGV4ZWQuIiksdGhpcztjb25zdCBlPW5ldyB1ZSxuPXRoaXMuaW5kZXguYXJyYXkscz10aGlzLmF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGEgaW4gcyl7Y29uc3QgYz1zW2FdLGw9dChjLG4pO2Uuc2V0QXR0cmlidXRlKGEsbCl9Y29uc3Qgcj10aGlzLm1vcnBoQXR0cmlidXRlcztmb3IoY29uc3QgYSBpbiByKXtjb25zdCBjPVtdLGw9clthXTtmb3IobGV0IGg9MCx1PWwubGVuZ3RoO2g8dTtoKyspe2NvbnN0IGY9bFtoXSxkPXQoZixuKTtjLnB1c2goZCl9ZS5tb3JwaEF0dHJpYnV0ZXNbYV09Y31lLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU7Y29uc3Qgbz10aGlzLmdyb3Vwcztmb3IobGV0IGE9MCxjPW8ubGVuZ3RoO2E8YzthKyspe2NvbnN0IGw9b1thXTtlLmFkZEdyb3VwKGwuc3RhcnQsbC5jb3VudCxsLm1hdGVyaWFsSW5kZXgpfXJldHVybiBlfXRvSlNPTigpe2NvbnN0IHQ9e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJCdWZmZXJHZW9tZXRyeSIsZ2VuZXJhdG9yOiJCdWZmZXJHZW9tZXRyeS50b0pTT04ifX07aWYodC51dWlkPXRoaXMudXVpZCx0LnR5cGU9dGhpcy50eXBlLHRoaXMubmFtZSE9PSIiJiYodC5uYW1lPXRoaXMubmFtZSksT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJih0LnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLHRoaXMucGFyYW1ldGVycyE9PXZvaWQgMCl7Y29uc3QgYz10aGlzLnBhcmFtZXRlcnM7Zm9yKGNvbnN0IGwgaW4gYyljW2xdIT09dm9pZCAwJiYodFtsXT1jW2xdKTtyZXR1cm4gdH10LmRhdGE9e2F0dHJpYnV0ZXM6e319O2NvbnN0IGU9dGhpcy5pbmRleDtlIT09bnVsbCYmKHQuZGF0YS5pbmRleD17dHlwZTplLmFycmF5LmNvbnN0cnVjdG9yLm5hbWUsYXJyYXk6QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZS5hcnJheSl9KTtjb25zdCBuPXRoaXMuYXR0cmlidXRlcztmb3IoY29uc3QgYyBpbiBuKXtjb25zdCBsPW5bY107dC5kYXRhLmF0dHJpYnV0ZXNbY109bC50b0pTT04odC5kYXRhKX1jb25zdCBzPXt9O2xldCByPSExO2Zvcihjb25zdCBjIGluIHRoaXMubW9ycGhBdHRyaWJ1dGVzKXtjb25zdCBsPXRoaXMubW9ycGhBdHRyaWJ1dGVzW2NdLGg9W107Zm9yKGxldCB1PTAsZj1sLmxlbmd0aDt1PGY7dSsrKXtjb25zdCBkPWxbdV07aC5wdXNoKGQudG9KU09OKHQuZGF0YSkpfWgubGVuZ3RoPjAmJihzW2NdPWgscj0hMCl9ciYmKHQuZGF0YS5tb3JwaEF0dHJpYnV0ZXM9cyx0LmRhdGEubW9ycGhUYXJnZXRzUmVsYXRpdmU9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZSk7Y29uc3Qgbz10aGlzLmdyb3VwcztvLmxlbmd0aD4wJiYodC5kYXRhLmdyb3Vwcz1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG8pKSk7Y29uc3QgYT10aGlzLmJvdW5kaW5nU3BoZXJlO3JldHVybiBhIT09bnVsbCYmKHQuZGF0YS5ib3VuZGluZ1NwaGVyZT1hLnRvSlNPTigpKSx0fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3RoaXMuaW5kZXg9bnVsbCx0aGlzLmF0dHJpYnV0ZXM9e30sdGhpcy5tb3JwaEF0dHJpYnV0ZXM9e30sdGhpcy5ncm91cHM9W10sdGhpcy5ib3VuZGluZ0JveD1udWxsLHRoaXMuYm91bmRpbmdTcGhlcmU9bnVsbDtjb25zdCBlPXt9O3RoaXMubmFtZT10Lm5hbWU7Y29uc3Qgbj10LmluZGV4O24hPT1udWxsJiZ0aGlzLnNldEluZGV4KG4uY2xvbmUoKSk7Y29uc3Qgcz10LmF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGwgaW4gcyl7Y29uc3QgaD1zW2xdO3RoaXMuc2V0QXR0cmlidXRlKGwsaC5jbG9uZShlKSl9Y29uc3Qgcj10Lm1vcnBoQXR0cmlidXRlcztmb3IoY29uc3QgbCBpbiByKXtjb25zdCBoPVtdLHU9cltsXTtmb3IobGV0IGY9MCxkPXUubGVuZ3RoO2Y8ZDtmKyspaC5wdXNoKHVbZl0uY2xvbmUoZSkpO3RoaXMubW9ycGhBdHRyaWJ1dGVzW2xdPWh9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT10Lm1vcnBoVGFyZ2V0c1JlbGF0aXZlO2NvbnN0IG89dC5ncm91cHM7Zm9yKGxldCBsPTAsaD1vLmxlbmd0aDtsPGg7bCsrKXtjb25zdCB1PW9bbF07dGhpcy5hZGRHcm91cCh1LnN0YXJ0LHUuY291bnQsdS5tYXRlcmlhbEluZGV4KX1jb25zdCBhPXQuYm91bmRpbmdCb3g7YSE9PW51bGwmJih0aGlzLmJvdW5kaW5nQm94PWEuY2xvbmUoKSk7Y29uc3QgYz10LmJvdW5kaW5nU3BoZXJlO3JldHVybiBjIT09bnVsbCYmKHRoaXMuYm91bmRpbmdTcGhlcmU9Yy5jbG9uZSgpKSx0aGlzLmRyYXdSYW5nZS5zdGFydD10LmRyYXdSYW5nZS5zdGFydCx0aGlzLmRyYXdSYW5nZS5jb3VudD10LmRyYXdSYW5nZS5jb3VudCx0aGlzLnVzZXJEYXRhPXQudXNlckRhdGEsdGhpc31kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfX1jb25zdCBMYz1uZXcgc3QsZm49bmV3IGZvLGdzPW5ldyBjbyxPYz1uZXcgVCx4cz1uZXcgVCx3cz1uZXcgVCxicz1uZXcgVCxfbz1uZXcgVCxNcz1uZXcgVCxEYz1uZXcgVCxBcz1uZXcgVDtjbGFzcyBiZiBleHRlbmRzIEVle2NvbnN0cnVjdG9yKHQ9bmV3IHVlLGU9bmV3IHlmKXtzdXBlcigpLHRoaXMuaXNNZXNoPSEwLHRoaXMudHlwZT0iTWVzaCIsdGhpcy5nZW9tZXRyeT10LHRoaXMubWF0ZXJpYWw9ZSx0aGlzLm1vcnBoVGFyZ2V0RGljdGlvbmFyeT12b2lkIDAsdGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXM9dm9pZCAwLHRoaXMuY291bnQ9MSx0aGlzLnVwZGF0ZU1vcnBoVGFyZ2V0cygpfWNvcHkodCxlKXtyZXR1cm4gc3VwZXIuY29weSh0LGUpLHQubW9ycGhUYXJnZXRJbmZsdWVuY2VzIT09dm9pZCAwJiYodGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXM9dC5tb3JwaFRhcmdldEluZmx1ZW5jZXMuc2xpY2UoKSksdC5tb3JwaFRhcmdldERpY3Rpb25hcnkhPT12b2lkIDAmJih0aGlzLm1vcnBoVGFyZ2V0RGljdGlvbmFyeT1PYmplY3QuYXNzaWduKHt9LHQubW9ycGhUYXJnZXREaWN0aW9uYXJ5KSksdGhpcy5tYXRlcmlhbD1BcnJheS5pc0FycmF5KHQubWF0ZXJpYWwpP3QubWF0ZXJpYWwuc2xpY2UoKTp0Lm1hdGVyaWFsLHRoaXMuZ2VvbWV0cnk9dC5nZW9tZXRyeSx0aGlzfXVwZGF0ZU1vcnBoVGFyZ2V0cygpe2NvbnN0IGU9dGhpcy5nZW9tZXRyeS5tb3JwaEF0dHJpYnV0ZXMsbj1PYmplY3Qua2V5cyhlKTtpZihuLmxlbmd0aD4wKXtjb25zdCBzPWVbblswXV07aWYocyE9PXZvaWQgMCl7dGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXM9W10sdGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9e307Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXNbcl0ubmFtZXx8U3RyaW5nKHIpO3RoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzLnB1c2goMCksdGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnlbYV09cn19fX1nZXRWZXJ0ZXhQb3NpdGlvbih0LGUpe2NvbnN0IG49dGhpcy5nZW9tZXRyeSxzPW4uYXR0cmlidXRlcy5wb3NpdGlvbixyPW4ubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uLG89bi5tb3JwaFRhcmdldHNSZWxhdGl2ZTtlLmZyb21CdWZmZXJBdHRyaWJ1dGUocyx0KTtjb25zdCBhPXRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzO2lmKHImJmEpe01zLnNldCgwLDAsMCk7Zm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPWFbY10sdT1yW2NdO2ghPT0wJiYoX28uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LHQpLG8/TXMuYWRkU2NhbGVkVmVjdG9yKF9vLGgpOk1zLmFkZFNjYWxlZFZlY3Rvcihfby5zdWIoZSksaCkpfWUuYWRkKE1zKX1yZXR1cm4gZX1yYXljYXN0KHQsZSl7Y29uc3Qgbj10aGlzLmdlb21ldHJ5LHM9dGhpcy5tYXRlcmlhbCxyPXRoaXMubWF0cml4V29ybGQ7cyE9PXZvaWQgMCYmKG4uYm91bmRpbmdTcGhlcmU9PT1udWxsJiZuLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpLGdzLmNvcHkobi5ib3VuZGluZ1NwaGVyZSksZ3MuYXBwbHlNYXRyaXg0KHIpLGZuLmNvcHkodC5yYXkpLnJlY2FzdCh0Lm5lYXIpLCEoZ3MuY29udGFpbnNQb2ludChmbi5vcmlnaW4pPT09ITEmJihmbi5pbnRlcnNlY3RTcGhlcmUoZ3MsT2MpPT09bnVsbHx8Zm4ub3JpZ2luLmRpc3RhbmNlVG9TcXVhcmVkKE9jKT55aSh0LmZhci10Lm5lYXIsMikpKSYmKExjLmNvcHkocikuaW52ZXJ0KCksZm4uY29weSh0LnJheSkuYXBwbHlNYXRyaXg0KExjKSwhKG4uYm91bmRpbmdCb3ghPT1udWxsJiZmbi5pbnRlcnNlY3RzQm94KG4uYm91bmRpbmdCb3gpPT09ITEpJiZ0aGlzLl9jb21wdXRlSW50ZXJzZWN0aW9ucyh0LGUsZm4pKSl9X2NvbXB1dGVJbnRlcnNlY3Rpb25zKHQsZSxuKXtsZXQgcztjb25zdCByPXRoaXMuZ2VvbWV0cnksbz10aGlzLm1hdGVyaWFsLGE9ci5pbmRleCxjPXIuYXR0cmlidXRlcy5wb3NpdGlvbixsPXIuYXR0cmlidXRlcy51dixoPXIuYXR0cmlidXRlcy51djEsdT1yLmF0dHJpYnV0ZXMubm9ybWFsLGY9ci5ncm91cHMsZD1yLmRyYXdSYW5nZTtpZihhIT09bnVsbClpZihBcnJheS5pc0FycmF5KG8pKWZvcihsZXQgcD0wLHk9Zi5sZW5ndGg7cDx5O3ArKyl7Y29uc3QgbT1mW3BdLGc9b1ttLm1hdGVyaWFsSW5kZXhdLGI9TWF0aC5tYXgobS5zdGFydCxkLnN0YXJ0KSx3PU1hdGgubWluKGEuY291bnQsTWF0aC5taW4obS5zdGFydCttLmNvdW50LGQuc3RhcnQrZC5jb3VudCkpO2ZvcihsZXQgeD1iLE09dzt4PE07eCs9Myl7Y29uc3QgQT1hLmdldFgoeCksUz1hLmdldFgoeCsxKSxfPWEuZ2V0WCh4KzIpO3M9U3ModGhpcyxnLHQsbixsLGgsdSxBLFMsXykscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IoeC8zKSxzLmZhY2UubWF0ZXJpYWxJbmRleD1tLm1hdGVyaWFsSW5kZXgsZS5wdXNoKHMpKX19ZWxzZXtjb25zdCBwPU1hdGgubWF4KDAsZC5zdGFydCkseT1NYXRoLm1pbihhLmNvdW50LGQuc3RhcnQrZC5jb3VudCk7Zm9yKGxldCBtPXAsZz15O208ZzttKz0zKXtjb25zdCBiPWEuZ2V0WChtKSx3PWEuZ2V0WChtKzEpLHg9YS5nZXRYKG0rMik7cz1Tcyh0aGlzLG8sdCxuLGwsaCx1LGIsdyx4KSxzJiYocy5mYWNlSW5kZXg9TWF0aC5mbG9vcihtLzMpLGUucHVzaChzKSl9fWVsc2UgaWYoYyE9PXZvaWQgMClpZihBcnJheS5pc0FycmF5KG8pKWZvcihsZXQgcD0wLHk9Zi5sZW5ndGg7cDx5O3ArKyl7Y29uc3QgbT1mW3BdLGc9b1ttLm1hdGVyaWFsSW5kZXhdLGI9TWF0aC5tYXgobS5zdGFydCxkLnN0YXJ0KSx3PU1hdGgubWluKGMuY291bnQsTWF0aC5taW4obS5zdGFydCttLmNvdW50LGQuc3RhcnQrZC5jb3VudCkpO2ZvcihsZXQgeD1iLE09dzt4PE07eCs9Myl7Y29uc3QgQT14LFM9eCsxLF89eCsyO3M9U3ModGhpcyxnLHQsbixsLGgsdSxBLFMsXykscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IoeC8zKSxzLmZhY2UubWF0ZXJpYWxJbmRleD1tLm1hdGVyaWFsSW5kZXgsZS5wdXNoKHMpKX19ZWxzZXtjb25zdCBwPU1hdGgubWF4KDAsZC5zdGFydCkseT1NYXRoLm1pbihjLmNvdW50LGQuc3RhcnQrZC5jb3VudCk7Zm9yKGxldCBtPXAsZz15O208ZzttKz0zKXtjb25zdCBiPW0sdz1tKzEseD1tKzI7cz1Tcyh0aGlzLG8sdCxuLGwsaCx1LGIsdyx4KSxzJiYocy5mYWNlSW5kZXg9TWF0aC5mbG9vcihtLzMpLGUucHVzaChzKSl9fX19ZnVuY3Rpb24gTWYoaSx0LGUsbixzLHIsbyxhKXtsZXQgYztpZih0LnNpZGU9PT0xP2M9bi5pbnRlcnNlY3RUcmlhbmdsZShvLHIscywhMCxhKTpjPW4uaW50ZXJzZWN0VHJpYW5nbGUocyxyLG8sdC5zaWRlPT09MCxhKSxjPT09bnVsbClyZXR1cm4gbnVsbDtBcy5jb3B5KGEpLEFzLmFwcGx5TWF0cml4NChpLm1hdHJpeFdvcmxkKTtjb25zdCBsPWUucmF5Lm9yaWdpbi5kaXN0YW5jZVRvKEFzKTtyZXR1cm4gbDxlLm5lYXJ8fGw+ZS5mYXI/bnVsbDp7ZGlzdGFuY2U6bCxwb2ludDpBcy5jbG9uZSgpLG9iamVjdDppfX1mdW5jdGlvbiBTcyhpLHQsZSxuLHMscixvLGEsYyxsKXtpLmdldFZlcnRleFBvc2l0aW9uKGEseHMpLGkuZ2V0VmVydGV4UG9zaXRpb24oYyx3cyksaS5nZXRWZXJ0ZXhQb3NpdGlvbihsLGJzKTtjb25zdCBoPU1mKGksdCxlLG4seHMsd3MsYnMsRGMpO2lmKGgpe2NvbnN0IHU9bmV3IFQ7ZXQuZ2V0QmFyeWNvb3JkKERjLHhzLHdzLGJzLHUpLHMmJihoLnV2PWV0LmdldEludGVycG9sYXRlZEF0dHJpYnV0ZShzLGEsYyxsLHUsbmV3IFIpKSxyJiYoaC51djE9ZXQuZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKHIsYSxjLGwsdSxuZXcgUikpLG8mJihoLm5vcm1hbD1ldC5nZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUobyxhLGMsbCx1LG5ldyBUKSxoLm5vcm1hbC5kb3Qobi5kaXJlY3Rpb24pPjAmJmgubm9ybWFsLm11bHRpcGx5U2NhbGFyKC0xKSk7Y29uc3QgZj17YSxiOmMsYzpsLG5vcm1hbDpuZXcgVCxtYXRlcmlhbEluZGV4OjB9O2V0LmdldE5vcm1hbCh4cyx3cyxicyxmLm5vcm1hbCksaC5mYWNlPWYsaC5iYXJ5Y29vcmQ9dX1yZXR1cm4gaH1jb25zdCB2bz1uZXcgVCxBZj1uZXcgVCxTZj1uZXcgZ2U7Y2xhc3Mgem97Y29uc3RydWN0b3IodD1uZXcgVCgxLDAsMCksZT0wKXt0aGlzLmlzUGxhbmU9ITAsdGhpcy5ub3JtYWw9dCx0aGlzLmNvbnN0YW50PWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsLmNvcHkodCksdGhpcy5jb25zdGFudD1lLHRoaXN9c2V0Q29tcG9uZW50cyh0LGUsbixzKXtyZXR1cm4gdGhpcy5ub3JtYWwuc2V0KHQsZSxuKSx0aGlzLmNvbnN0YW50PXMsdGhpc31zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbC5jb3B5KHQpLHRoaXMuY29uc3RhbnQ9LWUuZG90KHRoaXMubm9ybWFsKSx0aGlzfXNldEZyb21Db3BsYW5hclBvaW50cyh0LGUsbil7Y29uc3Qgcz12by5zdWJWZWN0b3JzKG4sZSkuY3Jvc3MoQWYuc3ViVmVjdG9ycyh0LGUpKS5ub3JtYWxpemUoKTtyZXR1cm4gdGhpcy5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChzLHQpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5ub3JtYWwuY29weSh0Lm5vcm1hbCksdGhpcy5jb25zdGFudD10LmNvbnN0YW50LHRoaXN9bm9ybWFsaXplKCl7Y29uc3QgdD0xL3RoaXMubm9ybWFsLmxlbmd0aCgpO3JldHVybiB0aGlzLm5vcm1hbC5tdWx0aXBseVNjYWxhcih0KSx0aGlzLmNvbnN0YW50Kj10LHRoaXN9bmVnYXRlKCl7cmV0dXJuIHRoaXMuY29uc3RhbnQqPS0xLHRoaXMubm9ybWFsLm5lZ2F0ZSgpLHRoaXN9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiB0aGlzLm5vcm1hbC5kb3QodCkrdGhpcy5jb25zdGFudH1kaXN0YW5jZVRvU3BoZXJlKHQpe3JldHVybiB0aGlzLmRpc3RhbmNlVG9Qb2ludCh0LmNlbnRlciktdC5yYWRpdXN9cHJvamVjdFBvaW50KHQsZSl7cmV0dXJuIGUuY29weSh0KS5hZGRTY2FsZWRWZWN0b3IodGhpcy5ub3JtYWwsLXRoaXMuZGlzdGFuY2VUb1BvaW50KHQpKX1pbnRlcnNlY3RMaW5lKHQsZSl7Y29uc3Qgbj10LmRlbHRhKHZvKSxzPXRoaXMubm9ybWFsLmRvdChuKTtpZihzPT09MClyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQodC5zdGFydCk9PT0wP2UuY29weSh0LnN0YXJ0KTpudWxsO2NvbnN0IHI9LSh0LnN0YXJ0LmRvdCh0aGlzLm5vcm1hbCkrdGhpcy5jb25zdGFudCkvcztyZXR1cm4gcjwwfHxyPjE/bnVsbDplLmNvcHkodC5zdGFydCkuYWRkU2NhbGVkVmVjdG9yKG4scil9aW50ZXJzZWN0c0xpbmUodCl7Y29uc3QgZT10aGlzLmRpc3RhbmNlVG9Qb2ludCh0LnN0YXJ0KSxuPXRoaXMuZGlzdGFuY2VUb1BvaW50KHQuZW5kKTtyZXR1cm4gZTwwJiZuPjB8fG48MCYmZT4wfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1BsYW5lKHRoaXMpfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHQuaW50ZXJzZWN0c1BsYW5lKHRoaXMpfWNvcGxhbmFyUG9pbnQodCl7cmV0dXJuIHQuY29weSh0aGlzLm5vcm1hbCkubXVsdGlwbHlTY2FsYXIoLXRoaXMuY29uc3RhbnQpfWFwcGx5TWF0cml4NCh0LGUpe2NvbnN0IG49ZXx8U2YuZ2V0Tm9ybWFsTWF0cml4KHQpLHM9dGhpcy5jb3BsYW5hclBvaW50KHZvKS5hcHBseU1hdHJpeDQodCkscj10aGlzLm5vcm1hbC5hcHBseU1hdHJpeDMobikubm9ybWFsaXplKCk7cmV0dXJuIHRoaXMuY29uc3RhbnQ9LXMuZG90KHIpLHRoaXN9dHJhbnNsYXRlKHQpe3JldHVybiB0aGlzLmNvbnN0YW50LT10LmRvdCh0aGlzLm5vcm1hbCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQubm9ybWFsLmVxdWFscyh0aGlzLm5vcm1hbCkmJnQuY29uc3RhbnQ9PT10aGlzLmNvbnN0YW50fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX19bGV0IHhlPWNsYXNze2NvbnN0cnVjdG9yKCl7dGhpcy50eXBlPSJDdXJ2ZSIsdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9MjAwLHRoaXMubmVlZHNVcGRhdGU9ITEsdGhpcy5jYWNoZUFyY0xlbmd0aHM9bnVsbH1nZXRQb2ludCgpe2NvbnNvbGUud2FybigiVEhSRUUuQ3VydmU6IC5nZXRQb2ludCgpIG5vdCBpbXBsZW1lbnRlZC4iKX1nZXRQb2ludEF0KHQsZSl7Y29uc3Qgbj10aGlzLmdldFV0b1RtYXBwaW5nKHQpO3JldHVybiB0aGlzLmdldFBvaW50KG4sZSl9Z2V0UG9pbnRzKHQ9NSl7Y29uc3QgZT1bXTtmb3IobGV0IG49MDtuPD10O24rKyllLnB1c2godGhpcy5nZXRQb2ludChuL3QpKTtyZXR1cm4gZX1nZXRTcGFjZWRQb2ludHModD01KXtjb25zdCBlPVtdO2ZvcihsZXQgbj0wO248PXQ7bisrKWUucHVzaCh0aGlzLmdldFBvaW50QXQobi90KSk7cmV0dXJuIGV9Z2V0TGVuZ3RoKCl7Y29uc3QgdD10aGlzLmdldExlbmd0aHMoKTtyZXR1cm4gdFt0Lmxlbmd0aC0xXX1nZXRMZW5ndGhzKHQ9dGhpcy5hcmNMZW5ndGhEaXZpc2lvbnMpe2lmKHRoaXMuY2FjaGVBcmNMZW5ndGhzJiZ0aGlzLmNhY2hlQXJjTGVuZ3Rocy5sZW5ndGg9PT10KzEmJiF0aGlzLm5lZWRzVXBkYXRlKXJldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3Roczt0aGlzLm5lZWRzVXBkYXRlPSExO2NvbnN0IGU9W107bGV0IG4scz10aGlzLmdldFBvaW50KDApLHI9MDtlLnB1c2goMCk7Zm9yKGxldCBvPTE7bzw9dDtvKyspbj10aGlzLmdldFBvaW50KG8vdCkscis9bi5kaXN0YW5jZVRvKHMpLGUucHVzaChyKSxzPW47cmV0dXJuIHRoaXMuY2FjaGVBcmNMZW5ndGhzPWUsZX11cGRhdGVBcmNMZW5ndGhzKCl7dGhpcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLmdldExlbmd0aHMoKX1nZXRVdG9UbWFwcGluZyh0LGU9bnVsbCl7Y29uc3Qgbj10aGlzLmdldExlbmd0aHMoKTtsZXQgcz0wO2NvbnN0IHI9bi5sZW5ndGg7bGV0IG87ZT9vPWU6bz10Km5bci0xXTtsZXQgYT0wLGM9ci0xLGw7Zm9yKDthPD1jOylpZihzPU1hdGguZmxvb3IoYSsoYy1hKS8yKSxsPW5bc10tbyxsPDApYT1zKzE7ZWxzZSBpZihsPjApYz1zLTE7ZWxzZXtjPXM7YnJlYWt9aWYocz1jLG5bc109PT1vKXJldHVybiBzLyhyLTEpO2NvbnN0IGg9bltzXSxmPW5bcysxXS1oLGQ9KG8taCkvZjtyZXR1cm4ocytkKS8oci0xKX1nZXRUYW5nZW50KHQsZSl7bGV0IHM9dC0xZS00LHI9dCsxZS00O3M8MCYmKHM9MCkscj4xJiYocj0xKTtjb25zdCBvPXRoaXMuZ2V0UG9pbnQocyksYT10aGlzLmdldFBvaW50KHIpLGM9ZXx8KG8uaXNWZWN0b3IyP25ldyBSOm5ldyBUKTtyZXR1cm4gYy5jb3B5KGEpLnN1YihvKS5ub3JtYWxpemUoKSxjfWdldFRhbmdlbnRBdCh0LGUpe2NvbnN0IG49dGhpcy5nZXRVdG9UbWFwcGluZyh0KTtyZXR1cm4gdGhpcy5nZXRUYW5nZW50KG4sZSl9Y29tcHV0ZUZyZW5ldEZyYW1lcyh0LGU9ITEpe2NvbnN0IG49bmV3IFQscz1bXSxyPVtdLG89W10sYT1uZXcgVCxjPW5ldyBzdDtmb3IobGV0IGQ9MDtkPD10O2QrKyl7Y29uc3QgcD1kL3Q7c1tkXT10aGlzLmdldFRhbmdlbnRBdChwLG5ldyBUKX1yWzBdPW5ldyBULG9bMF09bmV3IFQ7bGV0IGw9TnVtYmVyLk1BWF9WQUxVRTtjb25zdCBoPU1hdGguYWJzKHNbMF0ueCksdT1NYXRoLmFicyhzWzBdLnkpLGY9TWF0aC5hYnMoc1swXS56KTtoPD1sJiYobD1oLG4uc2V0KDEsMCwwKSksdTw9bCYmKGw9dSxuLnNldCgwLDEsMCkpLGY8PWwmJm4uc2V0KDAsMCwxKSxhLmNyb3NzVmVjdG9ycyhzWzBdLG4pLm5vcm1hbGl6ZSgpLHJbMF0uY3Jvc3NWZWN0b3JzKHNbMF0sYSksb1swXS5jcm9zc1ZlY3RvcnMoc1swXSxyWzBdKTtmb3IobGV0IGQ9MTtkPD10O2QrKyl7aWYocltkXT1yW2QtMV0uY2xvbmUoKSxvW2RdPW9bZC0xXS5jbG9uZSgpLGEuY3Jvc3NWZWN0b3JzKHNbZC0xXSxzW2RdKSxhLmxlbmd0aCgpPk51bWJlci5FUFNJTE9OKXthLm5vcm1hbGl6ZSgpO2NvbnN0IHA9TWF0aC5hY29zKFooc1tkLTFdLmRvdChzW2RdKSwtMSwxKSk7cltkXS5hcHBseU1hdHJpeDQoYy5tYWtlUm90YXRpb25BeGlzKGEscCkpfW9bZF0uY3Jvc3NWZWN0b3JzKHNbZF0scltkXSl9aWYoZT09PSEwKXtsZXQgZD1NYXRoLmFjb3MoWihyWzBdLmRvdChyW3RdKSwtMSwxKSk7ZC89dCxzWzBdLmRvdChhLmNyb3NzVmVjdG9ycyhyWzBdLHJbdF0pKT4wJiYoZD0tZCk7Zm9yKGxldCBwPTE7cDw9dDtwKyspcltwXS5hcHBseU1hdHJpeDQoYy5tYWtlUm90YXRpb25BeGlzKHNbcF0sZCpwKSksb1twXS5jcm9zc1ZlY3RvcnMoc1twXSxyW3BdKX1yZXR1cm57dGFuZ2VudHM6cyxub3JtYWxzOnIsYmlub3JtYWxzOm99fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLmFyY0xlbmd0aERpdmlzaW9ucz10LmFyY0xlbmd0aERpdmlzaW9ucyx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJDdXJ2ZSIsZ2VuZXJhdG9yOiJDdXJ2ZS50b0pTT04ifX07cmV0dXJuIHQuYXJjTGVuZ3RoRGl2aXNpb25zPXRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zLHQudHlwZT10aGlzLnR5cGUsdH1mcm9tSlNPTih0KXtyZXR1cm4gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9dC5hcmNMZW5ndGhEaXZpc2lvbnMsdGhpc319O2NsYXNzIF9zIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IodD0wLGU9MCxuPTEscz0xLHI9MCxvPU1hdGguUEkqMixhPSExLGM9MCl7c3VwZXIoKSx0aGlzLmlzRWxsaXBzZUN1cnZlPSEwLHRoaXMudHlwZT0iRWxsaXBzZUN1cnZlIix0aGlzLmFYPXQsdGhpcy5hWT1lLHRoaXMueFJhZGl1cz1uLHRoaXMueVJhZGl1cz1zLHRoaXMuYVN0YXJ0QW5nbGU9cix0aGlzLmFFbmRBbmdsZT1vLHRoaXMuYUNsb2Nrd2lzZT1hLHRoaXMuYVJvdGF0aW9uPWN9Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz1NYXRoLlBJKjI7bGV0IHI9dGhpcy5hRW5kQW5nbGUtdGhpcy5hU3RhcnRBbmdsZTtjb25zdCBvPU1hdGguYWJzKHIpPE51bWJlci5FUFNJTE9OO2Zvcig7cjwwOylyKz1zO2Zvcig7cj5zOylyLT1zO3I8TnVtYmVyLkVQU0lMT04mJihvP3I9MDpyPXMpLHRoaXMuYUNsb2Nrd2lzZT09PSEwJiYhbyYmKHI9PT1zP3I9LXM6cj1yLXMpO2NvbnN0IGE9dGhpcy5hU3RhcnRBbmdsZSt0KnI7bGV0IGM9dGhpcy5hWCt0aGlzLnhSYWRpdXMqTWF0aC5jb3MoYSksbD10aGlzLmFZK3RoaXMueVJhZGl1cypNYXRoLnNpbihhKTtpZih0aGlzLmFSb3RhdGlvbiE9PTApe2NvbnN0IGg9TWF0aC5jb3ModGhpcy5hUm90YXRpb24pLHU9TWF0aC5zaW4odGhpcy5hUm90YXRpb24pLGY9Yy10aGlzLmFYLGQ9bC10aGlzLmFZO2M9ZipoLWQqdSt0aGlzLmFYLGw9Zip1K2QqaCt0aGlzLmFZfXJldHVybiBuLnNldChjLGwpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5hWD10LmFYLHRoaXMuYVk9dC5hWSx0aGlzLnhSYWRpdXM9dC54UmFkaXVzLHRoaXMueVJhZGl1cz10LnlSYWRpdXMsdGhpcy5hU3RhcnRBbmdsZT10LmFTdGFydEFuZ2xlLHRoaXMuYUVuZEFuZ2xlPXQuYUVuZEFuZ2xlLHRoaXMuYUNsb2Nrd2lzZT10LmFDbG9ja3dpc2UsdGhpcy5hUm90YXRpb249dC5hUm90YXRpb24sdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LmFYPXRoaXMuYVgsdC5hWT10aGlzLmFZLHQueFJhZGl1cz10aGlzLnhSYWRpdXMsdC55UmFkaXVzPXRoaXMueVJhZGl1cyx0LmFTdGFydEFuZ2xlPXRoaXMuYVN0YXJ0QW5nbGUsdC5hRW5kQW5nbGU9dGhpcy5hRW5kQW5nbGUsdC5hQ2xvY2t3aXNlPXRoaXMuYUNsb2Nrd2lzZSx0LmFSb3RhdGlvbj10aGlzLmFSb3RhdGlvbix0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLmFYPXQuYVgsdGhpcy5hWT10LmFZLHRoaXMueFJhZGl1cz10LnhSYWRpdXMsdGhpcy55UmFkaXVzPXQueVJhZGl1cyx0aGlzLmFTdGFydEFuZ2xlPXQuYVN0YXJ0QW5nbGUsdGhpcy5hRW5kQW5nbGU9dC5hRW5kQW5nbGUsdGhpcy5hQ2xvY2t3aXNlPXQuYUNsb2Nrd2lzZSx0aGlzLmFSb3RhdGlvbj10LmFSb3RhdGlvbix0aGlzfX1jbGFzcyAkYyBleHRlbmRzIF9ze2NvbnN0cnVjdG9yKHQsZSxuLHMscixvKXtzdXBlcih0LGUsbixuLHMscixvKSx0aGlzLmlzQXJjQ3VydmU9ITAsdGhpcy50eXBlPSJBcmNDdXJ2ZSJ9fWZ1bmN0aW9uIFRvKCl7bGV0IGk9MCx0PTAsZT0wLG49MDtmdW5jdGlvbiBzKHIsbyxhLGMpe2k9cix0PWEsZT0tMypyKzMqby0yKmEtYyxuPTIqci0yKm8rYStjfXJldHVybntpbml0Q2F0bXVsbFJvbTpmdW5jdGlvbihyLG8sYSxjLGwpe3MobyxhLGwqKGEtciksbCooYy1vKSl9LGluaXROb251bmlmb3JtQ2F0bXVsbFJvbTpmdW5jdGlvbihyLG8sYSxjLGwsaCx1KXtsZXQgZj0oby1yKS9sLShhLXIpLyhsK2gpKyhhLW8pL2gsZD0oYS1vKS9oLShjLW8pLyhoK3UpKyhjLWEpL3U7Zio9aCxkKj1oLHMobyxhLGYsZCl9LGNhbGM6ZnVuY3Rpb24ocil7Y29uc3Qgbz1yKnIsYT1vKnI7cmV0dXJuIGkrdCpyK2UqbytuKmF9fX1jb25zdCB2cz1uZXcgVCxFbz1uZXcgVG8sUG89bmV3IFRvLENvPW5ldyBUbztjbGFzcyBWYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9W10sZT0hMSxuPSJjZW50cmlwZXRhbCIscz0uNSl7c3VwZXIoKSx0aGlzLmlzQ2F0bXVsbFJvbUN1cnZlMz0hMCx0aGlzLnR5cGU9IkNhdG11bGxSb21DdXJ2ZTMiLHRoaXMucG9pbnRzPXQsdGhpcy5jbG9zZWQ9ZSx0aGlzLmN1cnZlVHlwZT1uLHRoaXMudGVuc2lvbj1zfWdldFBvaW50KHQsZT1uZXcgVCl7Y29uc3Qgbj1lLHM9dGhpcy5wb2ludHMscj1zLmxlbmd0aCxvPShyLSh0aGlzLmNsb3NlZD8wOjEpKSp0O2xldCBhPU1hdGguZmxvb3IobyksYz1vLWE7dGhpcy5jbG9zZWQ/YSs9YT4wPzA6KE1hdGguZmxvb3IoTWF0aC5hYnMoYSkvcikrMSkqcjpjPT09MCYmYT09PXItMSYmKGE9ci0yLGM9MSk7bGV0IGwsaDt0aGlzLmNsb3NlZHx8YT4wP2w9c1soYS0xKSVyXToodnMuc3ViVmVjdG9ycyhzWzBdLHNbMV0pLmFkZChzWzBdKSxsPXZzKTtjb25zdCB1PXNbYSVyXSxmPXNbKGErMSklcl07aWYodGhpcy5jbG9zZWR8fGErMjxyP2g9c1soYSsyKSVyXToodnMuc3ViVmVjdG9ycyhzW3ItMV0sc1tyLTJdKS5hZGQoc1tyLTFdKSxoPXZzKSx0aGlzLmN1cnZlVHlwZT09PSJjZW50cmlwZXRhbCJ8fHRoaXMuY3VydmVUeXBlPT09ImNob3JkYWwiKXtjb25zdCBkPXRoaXMuY3VydmVUeXBlPT09ImNob3JkYWwiPy41Oi4yNTtsZXQgcD1NYXRoLnBvdyhsLmRpc3RhbmNlVG9TcXVhcmVkKHUpLGQpLHk9TWF0aC5wb3codS5kaXN0YW5jZVRvU3F1YXJlZChmKSxkKSxtPU1hdGgucG93KGYuZGlzdGFuY2VUb1NxdWFyZWQoaCksZCk7eTwxZS00JiYoeT0xKSxwPDFlLTQmJihwPXkpLG08MWUtNCYmKG09eSksRW8uaW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tKGwueCx1LngsZi54LGgueCxwLHksbSksUG8uaW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tKGwueSx1LnksZi55LGgueSxwLHksbSksQ28uaW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tKGwueix1LnosZi56LGgueixwLHksbSl9ZWxzZSB0aGlzLmN1cnZlVHlwZT09PSJjYXRtdWxscm9tIiYmKEVvLmluaXRDYXRtdWxsUm9tKGwueCx1LngsZi54LGgueCx0aGlzLnRlbnNpb24pLFBvLmluaXRDYXRtdWxsUm9tKGwueSx1LnksZi55LGgueSx0aGlzLnRlbnNpb24pLENvLmluaXRDYXRtdWxsUm9tKGwueix1LnosZi56LGgueix0aGlzLnRlbnNpb24pKTtyZXR1cm4gbi5zZXQoRW8uY2FsYyhjKSxQby5jYWxjKGMpLENvLmNhbGMoYykpLG59Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzLmNsb3NlZD10LmNsb3NlZCx0aGlzLmN1cnZlVHlwZT10LmN1cnZlVHlwZSx0aGlzLnRlbnNpb249dC50ZW5zaW9uLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXRoaXMucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMucG9pbnRzW2VdO3QucG9pbnRzLnB1c2gocy50b0FycmF5KCkpfXJldHVybiB0LmNsb3NlZD10aGlzLmNsb3NlZCx0LmN1cnZlVHlwZT10aGlzLmN1cnZlVHlwZSx0LnRlbnNpb249dGhpcy50ZW5zaW9uLHR9ZnJvbUpTT04odCl7c3VwZXIuZnJvbUpTT04odCksdGhpcy5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10LnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10LnBvaW50c1tlXTt0aGlzLnBvaW50cy5wdXNoKG5ldyBUKCkuZnJvbUFycmF5KHMpKX1yZXR1cm4gdGhpcy5jbG9zZWQ9dC5jbG9zZWQsdGhpcy5jdXJ2ZVR5cGU9dC5jdXJ2ZVR5cGUsdGhpcy50ZW5zaW9uPXQudGVuc2lvbix0aGlzfX1mdW5jdGlvbiBVYyhpLHQsZSxuLHMpe2NvbnN0IHI9KG4tdCkqLjUsbz0ocy1lKSouNSxhPWkqaSxjPWkqYTtyZXR1cm4oMiplLTIqbityK28pKmMrKC0zKmUrMypuLTIqci1vKSphK3IqaStlfWZ1bmN0aW9uIF9mKGksdCl7Y29uc3QgZT0xLWk7cmV0dXJuIGUqZSp0fWZ1bmN0aW9uIHZmKGksdCl7cmV0dXJuIDIqKDEtaSkqaSp0fWZ1bmN0aW9uIHpmKGksdCl7cmV0dXJuIGkqaSp0fWZ1bmN0aW9uIFNpKGksdCxlLG4pe3JldHVybiBfZihpLHQpK3ZmKGksZSkremYoaSxuKX1mdW5jdGlvbiBUZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiBlKmUqZSp0fWZ1bmN0aW9uIEVmKGksdCl7Y29uc3QgZT0xLWk7cmV0dXJuIDMqZSplKmkqdH1mdW5jdGlvbiBQZihpLHQpe3JldHVybiAzKigxLWkpKmkqaSp0fWZ1bmN0aW9uIENmKGksdCl7cmV0dXJuIGkqaSppKnR9ZnVuY3Rpb24gX2koaSx0LGUsbixzKXtyZXR1cm4gVGYoaSx0KStFZihpLGUpK1BmKGksbikrQ2YoaSxzKX1jbGFzcyBCbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFIsZT1uZXcgUixuPW5ldyBSLHM9bmV3IFIpe3N1cGVyKCksdGhpcy5pc0N1YmljQmV6aWVyQ3VydmU9ITAsdGhpcy50eXBlPSJDdWJpY0JlemllckN1cnZlIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bix0aGlzLnYzPXN9Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjIsYT10aGlzLnYzO3JldHVybiBuLnNldChfaSh0LHMueCxyLngsby54LGEueCksX2kodCxzLnksci55LG8ueSxhLnkpKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpcy52My5jb3B5KHQudjMpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdC52Mz10aGlzLnYzLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzLnYzLmZyb21BcnJheSh0LnYzKSx0aGlzfX1jbGFzcyBxYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCxuPW5ldyBULHM9bmV3IFQpe3N1cGVyKCksdGhpcy5pc0N1YmljQmV6aWVyQ3VydmUzPSEwLHRoaXMudHlwZT0iQ3ViaWNCZXppZXJDdXJ2ZTMiLHRoaXMudjA9dCx0aGlzLnYxPWUsdGhpcy52Mj1uLHRoaXMudjM9c31nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZSxzPXRoaXMudjAscj10aGlzLnYxLG89dGhpcy52MixhPXRoaXMudjM7cmV0dXJuIG4uc2V0KF9pKHQscy54LHIueCxvLngsYS54KSxfaSh0LHMueSxyLnksby55LGEueSksX2kodCxzLnosci56LG8ueixhLnopKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpcy52My5jb3B5KHQudjMpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdC52Mz10aGlzLnYzLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzLnYzLmZyb21BcnJheSh0LnYzKSx0aGlzfX1jbGFzcyBGbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFIsZT1uZXcgUil7c3VwZXIoKSx0aGlzLmlzTGluZUN1cnZlPSEwLHRoaXMudHlwZT0iTGluZUN1cnZlIix0aGlzLnYxPXQsdGhpcy52Mj1lfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lO3JldHVybiB0PT09MT9uLmNvcHkodGhpcy52Mik6KG4uY29weSh0aGlzLnYyKS5zdWIodGhpcy52MSksbi5tdWx0aXBseVNjYWxhcih0KS5hZGQodGhpcy52MSkpLG59Z2V0UG9pbnRBdCh0LGUpe3JldHVybiB0aGlzLmdldFBvaW50KHQsZSl9Z2V0VGFuZ2VudCh0LGU9bmV3IFIpe3JldHVybiBlLnN1YlZlY3RvcnModGhpcy52Mix0aGlzLnYxKS5ub3JtYWxpemUoKX1nZXRUYW5nZW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRUYW5nZW50KHQsZSl9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHR9ZnJvbUpTT04odCl7cmV0dXJuIHN1cGVyLmZyb21KU09OKHQpLHRoaXMudjEuZnJvbUFycmF5KHQudjEpLHRoaXMudjIuZnJvbUFycmF5KHQudjIpLHRoaXN9fWNsYXNzIEhjIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNMaW5lQ3VydmUzPSEwLHRoaXMudHlwZT0iTGluZUN1cnZlMyIsdGhpcy52MT10LHRoaXMudjI9ZX1nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZTtyZXR1cm4gdD09PTE/bi5jb3B5KHRoaXMudjIpOihuLmNvcHkodGhpcy52Mikuc3ViKHRoaXMudjEpLG4ubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMudjEpKSxufWdldFBvaW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRQb2ludCh0LGUpfWdldFRhbmdlbnQodCxlPW5ldyBUKXtyZXR1cm4gZS5zdWJWZWN0b3JzKHRoaXMudjIsdGhpcy52MSkubm9ybWFsaXplKCl9Z2V0VGFuZ2VudEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudCh0LGUpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBJbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFIsZT1uZXcgUixuPW5ldyBSKXtzdXBlcigpLHRoaXMuaXNRdWFkcmF0aWNCZXppZXJDdXJ2ZT0hMCx0aGlzLnR5cGU9IlF1YWRyYXRpY0JlemllckN1cnZlIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bn1nZXRQb2ludCh0LGU9bmV3IFIpe2NvbnN0IG49ZSxzPXRoaXMudjAscj10aGlzLnYxLG89dGhpcy52MjtyZXR1cm4gbi5zZXQoU2kodCxzLngsci54LG8ueCksU2kodCxzLnksci55LG8ueSkpLG59Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnYwLmNvcHkodC52MCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHR9ZnJvbUpTT04odCl7cmV0dXJuIHN1cGVyLmZyb21KU09OKHQpLHRoaXMudjAuZnJvbUFycmF5KHQudjApLHRoaXMudjEuZnJvbUFycmF5KHQudjEpLHRoaXMudjIuZnJvbUFycmF5KHQudjIpLHRoaXN9fWNsYXNzIFdjIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBULG49bmV3IFQpe3N1cGVyKCksdGhpcy5pc1F1YWRyYXRpY0JlemllckN1cnZlMz0hMCx0aGlzLnR5cGU9IlF1YWRyYXRpY0JlemllckN1cnZlMyIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW59Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjI7cmV0dXJuIG4uc2V0KFNpKHQscy54LHIueCxvLngpLFNpKHQscy55LHIueSxvLnkpLFNpKHQscy56LHIueixvLnopKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYwPXRoaXMudjAudG9BcnJheSgpLHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBrbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9W10pe3N1cGVyKCksdGhpcy5pc1NwbGluZUN1cnZlPSEwLHRoaXMudHlwZT0iU3BsaW5lQ3VydmUiLHRoaXMucG9pbnRzPXR9Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnBvaW50cyxyPShzLmxlbmd0aC0xKSp0LG89TWF0aC5mbG9vcihyKSxhPXItbyxjPXNbbz09PTA/bzpvLTFdLGw9c1tvXSxoPXNbbz5zLmxlbmd0aC0yP3MubGVuZ3RoLTE6bysxXSx1PXNbbz5zLmxlbmd0aC0zP3MubGVuZ3RoLTE6bysyXTtyZXR1cm4gbi5zZXQoVWMoYSxjLngsbC54LGgueCx1LngpLFVjKGEsYy55LGwueSxoLnksdS55KSksbn1jb3B5KHQpe3N1cGVyLmNvcHkodCksdGhpcy5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10LnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10LnBvaW50c1tlXTt0aGlzLnBvaW50cy5wdXNoKHMuY2xvbmUoKSl9cmV0dXJuIHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXRoaXMucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMucG9pbnRzW2VdO3QucG9pbnRzLnB1c2gocy50b0FycmF5KCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChuZXcgUigpLmZyb21BcnJheShzKSl9cmV0dXJuIHRoaXN9fXZhciBHYz1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxBcmNDdXJ2ZTokYyxDYXRtdWxsUm9tQ3VydmUzOlZjLEN1YmljQmV6aWVyQ3VydmU6Qm8sQ3ViaWNCZXppZXJDdXJ2ZTM6cWMsRWxsaXBzZUN1cnZlOl9zLExpbmVDdXJ2ZTpGbyxMaW5lQ3VydmUzOkhjLFF1YWRyYXRpY0JlemllckN1cnZlOklvLFF1YWRyYXRpY0JlemllckN1cnZlMzpXYyxTcGxpbmVDdXJ2ZTprb30pO2NsYXNzIEJmIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMudHlwZT0iQ3VydmVQYXRoIix0aGlzLmN1cnZlcz1bXSx0aGlzLmF1dG9DbG9zZT0hMX1hZGQodCl7dGhpcy5jdXJ2ZXMucHVzaCh0KX1jbG9zZVBhdGgoKXtjb25zdCB0PXRoaXMuY3VydmVzWzBdLmdldFBvaW50KDApLGU9dGhpcy5jdXJ2ZXNbdGhpcy5jdXJ2ZXMubGVuZ3RoLTFdLmdldFBvaW50KDEpO2lmKCF0LmVxdWFscyhlKSl7Y29uc3Qgbj10LmlzVmVjdG9yMj09PSEwPyJMaW5lQ3VydmUiOiJMaW5lQ3VydmUzIjt0aGlzLmN1cnZlcy5wdXNoKG5ldyBHY1tuXShlLHQpKX1yZXR1cm4gdGhpc31nZXRQb2ludCh0LGUpe2NvbnN0IG49dCp0aGlzLmdldExlbmd0aCgpLHM9dGhpcy5nZXRDdXJ2ZUxlbmd0aHMoKTtsZXQgcj0wO2Zvcig7cjxzLmxlbmd0aDspe2lmKHNbcl0+PW4pe2NvbnN0IG89c1tyXS1uLGE9dGhpcy5jdXJ2ZXNbcl0sYz1hLmdldExlbmd0aCgpLGw9Yz09PTA/MDoxLW8vYztyZXR1cm4gYS5nZXRQb2ludEF0KGwsZSl9cisrfXJldHVybiBudWxsfWdldExlbmd0aCgpe2NvbnN0IHQ9dGhpcy5nZXRDdXJ2ZUxlbmd0aHMoKTtyZXR1cm4gdFt0Lmxlbmd0aC0xXX11cGRhdGVBcmNMZW5ndGhzKCl7dGhpcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLmNhY2hlTGVuZ3Rocz1udWxsLHRoaXMuZ2V0Q3VydmVMZW5ndGhzKCl9Z2V0Q3VydmVMZW5ndGhzKCl7aWYodGhpcy5jYWNoZUxlbmd0aHMmJnRoaXMuY2FjaGVMZW5ndGhzLmxlbmd0aD09PXRoaXMuY3VydmVzLmxlbmd0aClyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM7Y29uc3QgdD1bXTtsZXQgZT0wO2ZvcihsZXQgbj0wLHM9dGhpcy5jdXJ2ZXMubGVuZ3RoO248cztuKyspZSs9dGhpcy5jdXJ2ZXNbbl0uZ2V0TGVuZ3RoKCksdC5wdXNoKGUpO3JldHVybiB0aGlzLmNhY2hlTGVuZ3Rocz10LHR9Z2V0U3BhY2VkUG9pbnRzKHQ9NDApe2NvbnN0IGU9W107Zm9yKGxldCBuPTA7bjw9dDtuKyspZS5wdXNoKHRoaXMuZ2V0UG9pbnQobi90KSk7cmV0dXJuIHRoaXMuYXV0b0Nsb3NlJiZlLnB1c2goZVswXSksZX1nZXRQb2ludHModD0xMil7Y29uc3QgZT1bXTtsZXQgbjtmb3IobGV0IHM9MCxyPXRoaXMuY3VydmVzO3M8ci5sZW5ndGg7cysrKXtjb25zdCBvPXJbc10sYT1vLmlzRWxsaXBzZUN1cnZlP3QqMjpvLmlzTGluZUN1cnZlfHxvLmlzTGluZUN1cnZlMz8xOm8uaXNTcGxpbmVDdXJ2ZT90Km8ucG9pbnRzLmxlbmd0aDp0LGM9by5nZXRQb2ludHMoYSk7Zm9yKGxldCBsPTA7bDxjLmxlbmd0aDtsKyspe2NvbnN0IGg9Y1tsXTtuJiZuLmVxdWFscyhoKXx8KGUucHVzaChoKSxuPWgpfX1yZXR1cm4gdGhpcy5hdXRvQ2xvc2UmJmUubGVuZ3RoPjEmJiFlW2UubGVuZ3RoLTFdLmVxdWFscyhlWzBdKSYmZS5wdXNoKGVbMF0pLGV9Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dC5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5jdXJ2ZXNbZV07dGhpcy5jdXJ2ZXMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzLmF1dG9DbG9zZT10LmF1dG9DbG9zZSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5hdXRvQ2xvc2U9dGhpcy5hdXRvQ2xvc2UsdC5jdXJ2ZXM9W107Zm9yKGxldCBlPTAsbj10aGlzLmN1cnZlcy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLmN1cnZlc1tlXTt0LmN1cnZlcy5wdXNoKHMudG9KU09OKCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMuYXV0b0Nsb3NlPXQuYXV0b0Nsb3NlLHRoaXMuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dC5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5jdXJ2ZXNbZV07dGhpcy5jdXJ2ZXMucHVzaChuZXcgR2Nbcy50eXBlXSgpLmZyb21KU09OKHMpKX1yZXR1cm4gdGhpc319bGV0IFpjPWNsYXNzIGV4dGVuZHMgQmZ7Y29uc3RydWN0b3IodCl7c3VwZXIoKSx0aGlzLnR5cGU9IlBhdGgiLHRoaXMuY3VycmVudFBvaW50PW5ldyBSLHQmJnRoaXMuc2V0RnJvbVBvaW50cyh0KX1zZXRGcm9tUG9pbnRzKHQpe3RoaXMubW92ZVRvKHRbMF0ueCx0WzBdLnkpO2ZvcihsZXQgZT0xLG49dC5sZW5ndGg7ZTxuO2UrKyl0aGlzLmxpbmVUbyh0W2VdLngsdFtlXS55KTtyZXR1cm4gdGhpc31tb3ZlVG8odCxlKXtyZXR1cm4gdGhpcy5jdXJyZW50UG9pbnQuc2V0KHQsZSksdGhpc31saW5lVG8odCxlKXtjb25zdCBuPW5ldyBGbyh0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLG5ldyBSKHQsZSkpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKG4pLHRoaXMuY3VycmVudFBvaW50LnNldCh0LGUpLHRoaXN9cXVhZHJhdGljQ3VydmVUbyh0LGUsbixzKXtjb25zdCByPW5ldyBJbyh0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLG5ldyBSKHQsZSksbmV3IFIobixzKSk7cmV0dXJuIHRoaXMuY3VydmVzLnB1c2gociksdGhpcy5jdXJyZW50UG9pbnQuc2V0KG4scyksdGhpc31iZXppZXJDdXJ2ZVRvKHQsZSxuLHMscixvKXtjb25zdCBhPW5ldyBCbyh0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLG5ldyBSKHQsZSksbmV3IFIobixzKSxuZXcgUihyLG8pKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChhKSx0aGlzLmN1cnJlbnRQb2ludC5zZXQocixvKSx0aGlzfXNwbGluZVRocnUodCl7Y29uc3QgZT1bdGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKV0uY29uY2F0KHQpLG49bmV3IGtvKGUpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKG4pLHRoaXMuY3VycmVudFBvaW50LmNvcHkodFt0Lmxlbmd0aC0xXSksdGhpc31hcmModCxlLG4scyxyLG8pe2NvbnN0IGE9dGhpcy5jdXJyZW50UG9pbnQueCxjPXRoaXMuY3VycmVudFBvaW50Lnk7cmV0dXJuIHRoaXMuYWJzYXJjKHQrYSxlK2MsbixzLHIsbyksdGhpc31hYnNhcmModCxlLG4scyxyLG8pe3JldHVybiB0aGlzLmFic2VsbGlwc2UodCxlLG4sbixzLHIsbyksdGhpc31lbGxpcHNlKHQsZSxuLHMscixvLGEsYyl7Y29uc3QgbD10aGlzLmN1cnJlbnRQb2ludC54LGg9dGhpcy5jdXJyZW50UG9pbnQueTtyZXR1cm4gdGhpcy5hYnNlbGxpcHNlKHQrbCxlK2gsbixzLHIsbyxhLGMpLHRoaXN9YWJzZWxsaXBzZSh0LGUsbixzLHIsbyxhLGMpe2NvbnN0IGw9bmV3IF9zKHQsZSxuLHMscixvLGEsYyk7aWYodGhpcy5jdXJ2ZXMubGVuZ3RoPjApe2NvbnN0IHU9bC5nZXRQb2ludCgwKTt1LmVxdWFscyh0aGlzLmN1cnJlbnRQb2ludCl8fHRoaXMubGluZVRvKHUueCx1LnkpfXRoaXMuY3VydmVzLnB1c2gobCk7Y29uc3QgaD1sLmdldFBvaW50KDEpO3JldHVybiB0aGlzLmN1cnJlbnRQb2ludC5jb3B5KGgpLHRoaXN9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLmN1cnJlbnRQb2ludC5jb3B5KHQuY3VycmVudFBvaW50KSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQuY3VycmVudFBvaW50PXRoaXMuY3VycmVudFBvaW50LnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLmN1cnJlbnRQb2ludC5mcm9tQXJyYXkodC5jdXJyZW50UG9pbnQpLHRoaXN9fTtjbGFzcyBYYyBleHRlbmRzIFpje2NvbnN0cnVjdG9yKHQpe3N1cGVyKHQpLHRoaXMudXVpZD1GbigpLHRoaXMudHlwZT0iU2hhcGUiLHRoaXMuaG9sZXM9W119Z2V0UG9pbnRzSG9sZXModCl7Y29uc3QgZT1bXTtmb3IobGV0IG49MCxzPXRoaXMuaG9sZXMubGVuZ3RoO248cztuKyspZVtuXT10aGlzLmhvbGVzW25dLmdldFBvaW50cyh0KTtyZXR1cm4gZX1leHRyYWN0UG9pbnRzKHQpe3JldHVybntzaGFwZTp0aGlzLmdldFBvaW50cyh0KSxob2xlczp0aGlzLmdldFBvaW50c0hvbGVzKHQpfX1jb3B5KHQpe3N1cGVyLmNvcHkodCksdGhpcy5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXQuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5ob2xlc1tlXTt0aGlzLmhvbGVzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3QudXVpZD10aGlzLnV1aWQsdC5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXRoaXMuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dGhpcy5ob2xlc1tlXTt0LmhvbGVzLnB1c2gocy50b0pTT04oKSl9cmV0dXJuIHR9ZnJvbUpTT04odCl7c3VwZXIuZnJvbUpTT04odCksdGhpcy51dWlkPXQudXVpZCx0aGlzLmhvbGVzPVtdO2ZvcihsZXQgZT0wLG49dC5ob2xlcy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10LmhvbGVzW2VdO3RoaXMuaG9sZXMucHVzaChuZXcgWmMoKS5mcm9tSlNPTihzKSl9cmV0dXJuIHRoaXN9fWZ1bmN0aW9uIEZmKGksdCxlPTIpe2NvbnN0IG49dCYmdC5sZW5ndGgscz1uP3RbMF0qZTppLmxlbmd0aDtsZXQgcj1KYyhpLDAscyxlLCEwKTtjb25zdCBvPVtdO2lmKCFyfHxyLm5leHQ9PT1yLnByZXYpcmV0dXJuIG87bGV0IGEsYyxsO2lmKG4mJihyPUxmKGksdCxyLGUpKSxpLmxlbmd0aD44MCplKXthPTEvMCxjPTEvMDtsZXQgaD0tMS8wLHU9LTEvMDtmb3IobGV0IGY9ZTtmPHM7Zis9ZSl7Y29uc3QgZD1pW2ZdLHA9aVtmKzFdO2Q8YSYmKGE9ZCkscDxjJiYoYz1wKSxkPmgmJihoPWQpLHA+dSYmKHU9cCl9bD1NYXRoLm1heChoLWEsdS1jKSxsPWwhPT0wPzMyNzY3L2w6MH1yZXR1cm4gdmkocixvLGUsYSxjLGwsMCksb31mdW5jdGlvbiBKYyhpLHQsZSxuLHMpe2xldCByO2lmKHM9PT1YZihpLHQsZSxuKT4wKWZvcihsZXQgbz10O288ZTtvKz1uKXI9S2Moby9ufDAsaVtvXSxpW28rMV0scik7ZWxzZSBmb3IobGV0IG89ZS1uO28+PXQ7by09bilyPUtjKG8vbnwwLGlbb10saVtvKzFdLHIpO3JldHVybiByJiZIbihyLHIubmV4dCkmJihFaShyKSxyPXIubmV4dCkscn1mdW5jdGlvbiBkbihpLHQpe2lmKCFpKXJldHVybiBpO3R8fCh0PWkpO2xldCBlPWksbjtkbyBpZihuPSExLCFlLnN0ZWluZXImJihIbihlLGUubmV4dCl8fHJ0KGUucHJldixlLGUubmV4dCk9PT0wKSl7aWYoRWkoZSksZT10PWUucHJldixlPT09ZS5uZXh0KWJyZWFrO249ITB9ZWxzZSBlPWUubmV4dDt3aGlsZShufHxlIT09dCk7cmV0dXJuIHR9ZnVuY3Rpb24gdmkoaSx0LGUsbixzLHIsbyl7aWYoIWkpcmV0dXJuOyFvJiZyJiZVZihpLG4scyxyKTtsZXQgYT1pO2Zvcig7aS5wcmV2IT09aS5uZXh0Oyl7Y29uc3QgYz1pLnByZXYsbD1pLm5leHQ7aWYocj9rZihpLG4scyxyKTpJZihpKSl7dC5wdXNoKGMuaSxpLmksbC5pKSxFaShpKSxpPWwubmV4dCxhPWwubmV4dDtjb250aW51ZX1pZihpPWwsaT09PWEpe28/bz09PTE/KGk9TmYoZG4oaSksdCksdmkoaSx0LGUsbixzLHIsMikpOm89PT0yJiZSZihpLHQsZSxuLHMscik6dmkoZG4oaSksdCxlLG4scyxyLDEpO2JyZWFrfX19ZnVuY3Rpb24gSWYoaSl7Y29uc3QgdD1pLnByZXYsZT1pLG49aS5uZXh0O2lmKHJ0KHQsZSxuKT49MClyZXR1cm4hMTtjb25zdCBzPXQueCxyPWUueCxvPW4ueCxhPXQueSxjPWUueSxsPW4ueSxoPU1hdGgubWluKHMscixvKSx1PU1hdGgubWluKGEsYyxsKSxmPU1hdGgubWF4KHMscixvKSxkPU1hdGgubWF4KGEsYyxsKTtsZXQgcD1uLm5leHQ7Zm9yKDtwIT09dDspe2lmKHAueD49aCYmcC54PD1mJiZwLnk+PXUmJnAueTw9ZCYmemkocyxhLHIsYyxvLGwscC54LHAueSkmJnJ0KHAucHJldixwLHAubmV4dCk+PTApcmV0dXJuITE7cD1wLm5leHR9cmV0dXJuITB9ZnVuY3Rpb24ga2YoaSx0LGUsbil7Y29uc3Qgcz1pLnByZXYscj1pLG89aS5uZXh0O2lmKHJ0KHMscixvKT49MClyZXR1cm4hMTtjb25zdCBhPXMueCxjPXIueCxsPW8ueCxoPXMueSx1PXIueSxmPW8ueSxkPU1hdGgubWluKGEsYyxsKSxwPU1hdGgubWluKGgsdSxmKSx5PU1hdGgubWF4KGEsYyxsKSxtPU1hdGgubWF4KGgsdSxmKSxnPU5vKGQscCx0LGUsbiksYj1Obyh5LG0sdCxlLG4pO2xldCB3PWkucHJldloseD1pLm5leHRaO2Zvcig7dyYmdy56Pj1nJiZ4JiZ4Lno8PWI7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmemkoYSxoLGMsdSxsLGYsdy54LHcueSkmJnJ0KHcucHJldix3LHcubmV4dCk+PTB8fCh3PXcucHJldloseC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJnppKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZydCh4LnByZXYseCx4Lm5leHQpPj0wKSlyZXR1cm4hMTt4PXgubmV4dFp9Zm9yKDt3JiZ3Lno+PWc7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmemkoYSxoLGMsdSxsLGYsdy54LHcueSkmJnJ0KHcucHJldix3LHcubmV4dCk+PTApcmV0dXJuITE7dz13LnByZXZafWZvcig7eCYmeC56PD1iOyl7aWYoeC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJnppKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZydCh4LnByZXYseCx4Lm5leHQpPj0wKXJldHVybiExO3g9eC5uZXh0Wn1yZXR1cm4hMH1mdW5jdGlvbiBOZihpLHQpe2xldCBlPWk7ZG97Y29uc3Qgbj1lLnByZXYscz1lLm5leHQubmV4dDshSG4obixzKSYmamMobixlLGUubmV4dCxzKSYmVGkobixzKSYmVGkocyxuKSYmKHQucHVzaChuLmksZS5pLHMuaSksRWkoZSksRWkoZS5uZXh0KSxlPWk9cyksZT1lLm5leHR9d2hpbGUoZSE9PWkpO3JldHVybiBkbihlKX1mdW5jdGlvbiBSZihpLHQsZSxuLHMscil7bGV0IG89aTtkb3tsZXQgYT1vLm5leHQubmV4dDtmb3IoO2EhPT1vLnByZXY7KXtpZihvLmkhPT1hLmkmJldmKG8sYSkpe2xldCBjPVFjKG8sYSk7bz1kbihvLG8ubmV4dCksYz1kbihjLGMubmV4dCksdmkobyx0LGUsbixzLHIsMCksdmkoYyx0LGUsbixzLHIsMCk7cmV0dXJufWE9YS5uZXh0fW89by5uZXh0fXdoaWxlKG8hPT1pKX1mdW5jdGlvbiBMZihpLHQsZSxuKXtjb25zdCBzPVtdO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdKm4sYz1yPG8tMT90W3IrMV0qbjppLmxlbmd0aCxsPUpjKGksYSxjLG4sITEpO2w9PT1sLm5leHQmJihsLnN0ZWluZXI9ITApLHMucHVzaChIZihsKSl9cy5zb3J0KE9mKTtmb3IobGV0IHI9MDtyPHMubGVuZ3RoO3IrKyllPURmKHNbcl0sZSk7cmV0dXJuIGV9ZnVuY3Rpb24gT2YoaSx0KXtsZXQgZT1pLngtdC54O2lmKGU9PT0wJiYoZT1pLnktdC55LGU9PT0wKSl7Y29uc3Qgbj0oaS5uZXh0LnktaS55KS8oaS5uZXh0LngtaS54KSxzPSh0Lm5leHQueS10LnkpLyh0Lm5leHQueC10LngpO2U9bi1zfXJldHVybiBlfWZ1bmN0aW9uIERmKGksdCl7Y29uc3QgZT0kZihpLHQpO2lmKCFlKXJldHVybiB0O2NvbnN0IG49UWMoZSxpKTtyZXR1cm4gZG4obixuLm5leHQpLGRuKGUsZS5uZXh0KX1mdW5jdGlvbiAkZihpLHQpe2xldCBlPXQ7Y29uc3Qgbj1pLngscz1pLnk7bGV0IHI9LTEvMCxvO2lmKEhuKGksZSkpcmV0dXJuIGU7ZG97aWYoSG4oaSxlLm5leHQpKXJldHVybiBlLm5leHQ7aWYoczw9ZS55JiZzPj1lLm5leHQueSYmZS5uZXh0LnkhPT1lLnkpe2NvbnN0IHU9ZS54KyhzLWUueSkqKGUubmV4dC54LWUueCkvKGUubmV4dC55LWUueSk7aWYodTw9biYmdT5yJiYocj11LG89ZS54PGUubmV4dC54P2U6ZS5uZXh0LHU9PT1uKSlyZXR1cm4gb31lPWUubmV4dH13aGlsZShlIT09dCk7aWYoIW8pcmV0dXJuIG51bGw7Y29uc3QgYT1vLGM9by54LGw9by55O2xldCBoPTEvMDtlPW87ZG97aWYobj49ZS54JiZlLng+PWMmJm4hPT1lLngmJlljKHM8bD9uOnIscyxjLGwsczxsP3I6bixzLGUueCxlLnkpKXtjb25zdCB1PU1hdGguYWJzKHMtZS55KS8obi1lLngpO1RpKGUsaSkmJih1PGh8fHU9PT1oJiYoZS54Pm8ueHx8ZS54PT09by54JiZWZihvLGUpKSkmJihvPWUsaD11KX1lPWUubmV4dH13aGlsZShlIT09YSk7cmV0dXJuIG99ZnVuY3Rpb24gVmYoaSx0KXtyZXR1cm4gcnQoaS5wcmV2LGksdC5wcmV2KTwwJiZydCh0Lm5leHQsaSxpLm5leHQpPDB9ZnVuY3Rpb24gVWYoaSx0LGUsbil7bGV0IHM9aTtkbyBzLno9PT0wJiYocy56PU5vKHMueCxzLnksdCxlLG4pKSxzLnByZXZaPXMucHJldixzLm5leHRaPXMubmV4dCxzPXMubmV4dDt3aGlsZShzIT09aSk7cy5wcmV2Wi5uZXh0Wj1udWxsLHMucHJldlo9bnVsbCxxZihzKX1mdW5jdGlvbiBxZihpKXtsZXQgdCxlPTE7ZG97bGV0IG49aSxzO2k9bnVsbDtsZXQgcj1udWxsO2Zvcih0PTA7bjspe3QrKztsZXQgbz1uLGE9MDtmb3IobGV0IGw9MDtsPGUmJihhKyssbz1vLm5leHRaLCEhbyk7bCsrKTtsZXQgYz1lO2Zvcig7YT4wfHxjPjAmJm87KWEhPT0wJiYoYz09PTB8fCFvfHxuLno8PW8ueik/KHM9bixuPW4ubmV4dFosYS0tKToocz1vLG89by5uZXh0WixjLS0pLHI/ci5uZXh0Wj1zOmk9cyxzLnByZXZaPXIscj1zO249b31yLm5leHRaPW51bGwsZSo9Mn13aGlsZSh0PjEpO3JldHVybiBpfWZ1bmN0aW9uIE5vKGksdCxlLG4scyl7cmV0dXJuIGk9KGktZSkqc3wwLHQ9KHQtbikqc3wwLGk9KGl8aTw8OCkmMTY3MTE5MzUsaT0oaXxpPDw0KSYyNTI2NDUxMzUsaT0oaXxpPDwyKSY4NTg5OTM0NTksaT0oaXxpPDwxKSYxNDMxNjU1NzY1LHQ9KHR8dDw8OCkmMTY3MTE5MzUsdD0odHx0PDw0KSYyNTI2NDUxMzUsdD0odHx0PDwyKSY4NTg5OTM0NTksdD0odHx0PDwxKSYxNDMxNjU1NzY1LGl8dDw8MX1mdW5jdGlvbiBIZihpKXtsZXQgdD1pLGU9aTtkbyh0Lng8ZS54fHx0Lng9PT1lLngmJnQueTxlLnkpJiYoZT10KSx0PXQubmV4dDt3aGlsZSh0IT09aSk7cmV0dXJuIGV9ZnVuY3Rpb24gWWMoaSx0LGUsbixzLHIsbyxhKXtyZXR1cm4ocy1vKSoodC1hKT49KGktbykqKHItYSkmJihpLW8pKihuLWEpPj0oZS1vKSoodC1hKSYmKGUtbykqKHItYSk+PShzLW8pKihuLWEpfWZ1bmN0aW9uIHppKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuIShpPT09byYmdD09PWEpJiZZYyhpLHQsZSxuLHMscixvLGEpfWZ1bmN0aW9uIFdmKGksdCl7cmV0dXJuIGkubmV4dC5pIT09dC5pJiZpLnByZXYuaSE9PXQuaSYmIUdmKGksdCkmJihUaShpLHQpJiZUaSh0LGkpJiZaZihpLHQpJiYocnQoaS5wcmV2LGksdC5wcmV2KXx8cnQoaSx0LnByZXYsdCkpfHxIbihpLHQpJiZydChpLnByZXYsaSxpLm5leHQpPjAmJnJ0KHQucHJldix0LHQubmV4dCk+MCl9ZnVuY3Rpb24gcnQoaSx0LGUpe3JldHVybih0LnktaS55KSooZS54LXQueCktKHQueC1pLngpKihlLnktdC55KX1mdW5jdGlvbiBIbihpLHQpe3JldHVybiBpLng9PT10LngmJmkueT09PXQueX1mdW5jdGlvbiBqYyhpLHQsZSxuKXtjb25zdCBzPVRzKHJ0KGksdCxlKSkscj1UcyhydChpLHQsbikpLG89VHMocnQoZSxuLGkpKSxhPVRzKHJ0KGUsbix0KSk7cmV0dXJuISEocyE9PXImJm8hPT1hfHxzPT09MCYmenMoaSxlLHQpfHxyPT09MCYmenMoaSxuLHQpfHxvPT09MCYmenMoZSxpLG4pfHxhPT09MCYmenMoZSx0LG4pKX1mdW5jdGlvbiB6cyhpLHQsZSl7cmV0dXJuIHQueDw9TWF0aC5tYXgoaS54LGUueCkmJnQueD49TWF0aC5taW4oaS54LGUueCkmJnQueTw9TWF0aC5tYXgoaS55LGUueSkmJnQueT49TWF0aC5taW4oaS55LGUueSl9ZnVuY3Rpb24gVHMoaSl7cmV0dXJuIGk+MD8xOmk8MD8tMTowfWZ1bmN0aW9uIEdmKGksdCl7bGV0IGU9aTtkb3tpZihlLmkhPT1pLmkmJmUubmV4dC5pIT09aS5pJiZlLmkhPT10LmkmJmUubmV4dC5pIT09dC5pJiZqYyhlLGUubmV4dCxpLHQpKXJldHVybiEwO2U9ZS5uZXh0fXdoaWxlKGUhPT1pKTtyZXR1cm4hMX1mdW5jdGlvbiBUaShpLHQpe3JldHVybiBydChpLnByZXYsaSxpLm5leHQpPDA/cnQoaSx0LGkubmV4dCk+PTAmJnJ0KGksaS5wcmV2LHQpPj0wOnJ0KGksdCxpLnByZXYpPDB8fHJ0KGksaS5uZXh0LHQpPDB9ZnVuY3Rpb24gWmYoaSx0KXtsZXQgZT1pLG49ITE7Y29uc3Qgcz0oaS54K3QueCkvMixyPShpLnkrdC55KS8yO2RvIGUueT5yIT1lLm5leHQueT5yJiZlLm5leHQueSE9PWUueSYmczwoZS5uZXh0LngtZS54KSooci1lLnkpLyhlLm5leHQueS1lLnkpK2UueCYmKG49IW4pLGU9ZS5uZXh0O3doaWxlKGUhPT1pKTtyZXR1cm4gbn1mdW5jdGlvbiBRYyhpLHQpe2NvbnN0IGU9Um8oaS5pLGkueCxpLnkpLG49Um8odC5pLHQueCx0LnkpLHM9aS5uZXh0LHI9dC5wcmV2O3JldHVybiBpLm5leHQ9dCx0LnByZXY9aSxlLm5leHQ9cyxzLnByZXY9ZSxuLm5leHQ9ZSxlLnByZXY9bixyLm5leHQ9bixuLnByZXY9cixufWZ1bmN0aW9uIEtjKGksdCxlLG4pe2NvbnN0IHM9Um8oaSx0LGUpO3JldHVybiBuPyhzLm5leHQ9bi5uZXh0LHMucHJldj1uLG4ubmV4dC5wcmV2PXMsbi5uZXh0PXMpOihzLnByZXY9cyxzLm5leHQ9cyksc31mdW5jdGlvbiBFaShpKXtpLm5leHQucHJldj1pLnByZXYsaS5wcmV2Lm5leHQ9aS5uZXh0LGkucHJldlomJihpLnByZXZaLm5leHRaPWkubmV4dFopLGkubmV4dFomJihpLm5leHRaLnByZXZaPWkucHJldlopfWZ1bmN0aW9uIFJvKGksdCxlKXtyZXR1cm57aSx4OnQseTplLHByZXY6bnVsbCxuZXh0Om51bGwsejowLHByZXZaOm51bGwsbmV4dFo6bnVsbCxzdGVpbmVyOiExfX1mdW5jdGlvbiBYZihpLHQsZSxuKXtsZXQgcz0wO2ZvcihsZXQgcj10LG89ZS1uO3I8ZTtyKz1uKXMrPShpW29dLWlbcl0pKihpW3IrMV0raVtvKzFdKSxvPXI7cmV0dXJuIHN9Y2xhc3MgSmZ7c3RhdGljIHRyaWFuZ3VsYXRlKHQsZSxuPTIpe3JldHVybiBGZih0LGUsbil9fWNsYXNzIFdue3N0YXRpYyBhcmVhKHQpe2NvbnN0IGU9dC5sZW5ndGg7bGV0IG49MDtmb3IobGV0IHM9ZS0xLHI9MDtyPGU7cz1yKyspbis9dFtzXS54KnRbcl0ueS10W3JdLngqdFtzXS55O3JldHVybiBuKi41fXN0YXRpYyBpc0Nsb2NrV2lzZSh0KXtyZXR1cm4gV24uYXJlYSh0KTwwfXN0YXRpYyB0cmlhbmd1bGF0ZVNoYXBlKHQsZSl7Y29uc3Qgbj1bXSxzPVtdLHI9W107dGwodCksZWwobix0KTtsZXQgbz10Lmxlbmd0aDtlLmZvckVhY2godGwpO2ZvcihsZXQgYz0wO2M8ZS5sZW5ndGg7YysrKXMucHVzaChvKSxvKz1lW2NdLmxlbmd0aCxlbChuLGVbY10pO2NvbnN0IGE9SmYudHJpYW5ndWxhdGUobixzKTtmb3IobGV0IGM9MDtjPGEubGVuZ3RoO2MrPTMpci5wdXNoKGEuc2xpY2UoYyxjKzMpKTtyZXR1cm4gcn19ZnVuY3Rpb24gdGwoaSl7Y29uc3QgdD1pLmxlbmd0aDt0PjImJmlbdC0xXS5lcXVhbHMoaVswXSkmJmkucG9wKCl9ZnVuY3Rpb24gZWwoaSx0KXtmb3IobGV0IGU9MDtlPHQubGVuZ3RoO2UrKylpLnB1c2godFtlXS54KSxpLnB1c2godFtlXS55KX1jbGFzcyBMbyBleHRlbmRzIHVle2NvbnN0cnVjdG9yKHQ9MSxlPTEsbj0xLHM9MSl7c3VwZXIoKSx0aGlzLnR5cGU9IlBsYW5lR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz17d2lkdGg6dCxoZWlnaHQ6ZSx3aWR0aFNlZ21lbnRzOm4saGVpZ2h0U2VnbWVudHM6c307Y29uc3Qgcj10LzIsbz1lLzIsYT1NYXRoLmZsb29yKG4pLGM9TWF0aC5mbG9vcihzKSxsPWErMSxoPWMrMSx1PXQvYSxmPWUvYyxkPVtdLHA9W10seT1bXSxtPVtdO2ZvcihsZXQgZz0wO2c8aDtnKyspe2NvbnN0IGI9ZypmLW87Zm9yKGxldCB3PTA7dzxsO3crKyl7Y29uc3QgeD13KnUtcjtwLnB1c2goeCwtYiwwKSx5LnB1c2goMCwwLDEpLG0ucHVzaCh3L2EpLG0ucHVzaCgxLWcvYyl9fWZvcihsZXQgZz0wO2c8YztnKyspZm9yKGxldCBiPTA7YjxhO2IrKyl7Y29uc3Qgdz1iK2wqZyx4PWIrbCooZysxKSxNPWIrMStsKihnKzEpLEE9YisxK2wqZztkLnB1c2godyx4LEEpLGQucHVzaCh4LE0sQSl9dGhpcy5zZXRJbmRleChkKSx0aGlzLnNldEF0dHJpYnV0ZSgicG9zaXRpb24iLG5ldyBCZShwLDMpKSx0aGlzLnNldEF0dHJpYnV0ZSgibm9ybWFsIixuZXcgQmUoeSwzKSksdGhpcy5zZXRBdHRyaWJ1dGUoInV2IixuZXcgQmUobSwyKSl9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnBhcmFtZXRlcnM9T2JqZWN0LmFzc2lnbih7fSx0LnBhcmFtZXRlcnMpLHRoaXN9c3RhdGljIGZyb21KU09OKHQpe3JldHVybiBuZXcgTG8odC53aWR0aCx0LmhlaWdodCx0LndpZHRoU2VnbWVudHMsdC5oZWlnaHRTZWdtZW50cyl9fWNvbnN0IG5sPW5ldyBULEVzPW5ldyBUO2NsYXNzIFF0e2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCl7dGhpcy5zdGFydD10LHRoaXMuZW5kPWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMuc3RhcnQuY29weSh0KSx0aGlzLmVuZC5jb3B5KGUpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5zdGFydC5jb3B5KHQuc3RhcnQpLHRoaXMuZW5kLmNvcHkodC5lbmQpLHRoaXN9Z2V0Q2VudGVyKHQpe3JldHVybiB0LmFkZFZlY3RvcnModGhpcy5zdGFydCx0aGlzLmVuZCkubXVsdGlwbHlTY2FsYXIoLjUpfWRlbHRhKHQpe3JldHVybiB0LnN1YlZlY3RvcnModGhpcy5lbmQsdGhpcy5zdGFydCl9ZGlzdGFuY2VTcSgpe3JldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuZW5kKX1kaXN0YW5jZSgpe3JldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG8odGhpcy5lbmQpfWF0KHQsZSl7cmV0dXJuIHRoaXMuZGVsdGEoZSkubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMuc3RhcnQpfWNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxlKXtubC5zdWJWZWN0b3JzKHQsdGhpcy5zdGFydCksRXMuc3ViVmVjdG9ycyh0aGlzLmVuZCx0aGlzLnN0YXJ0KTtjb25zdCBuPUVzLmRvdChFcyk7bGV0IHI9RXMuZG90KG5sKS9uO3JldHVybiBlJiYocj1aKHIsMCwxKSkscn1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZSxuKXtjb25zdCBzPXRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludFBhcmFtZXRlcih0LGUpO3JldHVybiB0aGlzLmRlbHRhKG4pLm11bHRpcGx5U2NhbGFyKHMpLmFkZCh0aGlzLnN0YXJ0KX1hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMuc3RhcnQuYXBwbHlNYXRyaXg0KHQpLHRoaXMuZW5kLmFwcGx5TWF0cml4NCh0KSx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5zdGFydC5lcXVhbHModGhpcy5zdGFydCkmJnQuZW5kLmVxdWFscyh0aGlzLmVuZCl9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX10eXBlb2YgX19USFJFRV9ERVZUT09MU19fIT0idW5kZWZpbmVkIiYmX19USFJFRV9ERVZUT09MU19fLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCJyZWdpc3RlciIse2RldGFpbDp7cmV2aXNpb246Sn19KSksdHlwZW9mIHdpbmRvdyE9InVuZGVmaW5lZCImJih3aW5kb3cuX19USFJFRV9fP2NvbnNvbGUud2FybigiV0FSTklORzogTXVsdGlwbGUgaW5zdGFuY2VzIG9mIFRocmVlLmpzIGJlaW5nIGltcG9ydGVkLiIpOndpbmRvdy5fX1RIUkVFX189Sik7Y29uc3QgcG49bmV3IE1hcCxZZj0oaT17fSk9Pih7Z2VuZXJhdGVUb3BVVih0LGUsbixzLHIpe2NvbnN0IG89ZVtuKjNdLGE9ZVtuKjMrMV0sYz1lW3MqM10sbD1lW3MqMysxXSxoPWVbciozXSx1PWVbciozKzFdO2xldCBmO2lmKHBuLmhhcyh0KSlmPXBuLmdldCh0KTtlbHNle2xldCBtPWkuYm94MztpZighbSl7bT1uZXcgZ3Q7Y29uc3Qgdz10LnBhcmFtZXRlcnMuc2hhcGVzLmdldFBvaW50cygpLm1hcCh4PT5beC54LHgueSwwXSkuZmxhdCgpO20uc2V0RnJvbUFycmF5KHcpfWNvbnN0IGc9bS5nZXRTaXplKG5ldyBUKTtpLnNwbGl0JiYoZy55Lz1pLnNwbGl0KSxmPXtib3g6bSxzaXplOmd9LHBuLnNldCh0LGYpfWNvbnN0e2JveDpkLHNpemU6cH09Zix5PWkuc3BsaXQ/MS1pLnNwbGl0OjA7cmV0dXJuW25ldyBSKChvLWQubWluLngpL3AueCwoYS1kLm1pbi55KS9wLnkreSksbmV3IFIoKGMtZC5taW4ueCkvcC54LChsLWQubWluLnkpL3AueSt5KSxuZXcgUigoaC1kLm1pbi54KS9wLngsKHUtZC5taW4ueSkvcC55K3kpXX0sZ2VuZXJhdGVTaWRlV2FsbFVWKHQsZSxuLHMscixvKXtjb25zdCBhPWVbbiozXSxjPWVbbiozKzFdLGw9ZVtuKjMrMl0saD1lW3MqM10sdT1lW3MqMysxXSxmPWVbcyozKzJdLGQ9ZVtyKjNdLHA9ZVtyKjMrMV0seT1lW3IqMysyXSxtPWVbbyozXSxnPWVbbyozKzFdLGI9ZVtvKjMrMl07bGV0IHc7aWYocG4uaGFzKGUpKXc9cG4uZ2V0KGUpO2Vsc2V7Y29uc3QgQT1uZXcgZ3Q7QS5zZXRGcm9tQXJyYXkoZSk7Y29uc3QgUz1BLmdldFNpemUobmV3IFQpO2kuc3BsaXQmJihTLnovPTEtaS5zcGxpdCksaS5zaWRlUmVwZWF0JiYoUy56Lz1pLnNpZGVSZXBlYXQpLHc9e2JveDpBLHNpemU6U30scG4uc2V0KGUsdyl9Y29uc3R7Ym94Ongsc2l6ZTpNfT13O3JldHVybiBNYXRoLmFicyhjLXUpPE1hdGguYWJzKGEtaCk/W25ldyBSKChhLXgubWluLngpL00ueCwobC14Lm1pbi56KS9NLnopLG5ldyBSKChoLXgubWluLngpL00ueCwoZi14Lm1pbi56KS9NLnopLG5ldyBSKChkLXgubWluLngpL00ueCwoeS14Lm1pbi56KS9NLnopLG5ldyBSKChtLXgubWluLngpL00ueCwoYi14Lm1pbi56KS9NLnopXTpbbmV3IFIoKGMteC5taW4ueSkvTS55LChsLXgubWluLnopL00ueiksbmV3IFIoKHUteC5taW4ueSkvTS55LChmLXgubWluLnopL00ueiksbmV3IFIoKHAteC5taW4ueSkvTS55LCh5LXgubWluLnopL00ueiksbmV3IFIoKGcteC5taW4ueSkvTS55LChiLXgubWluLnopL00ueildfX0pLGpmPSgpPT57cG4uY2xlYXIoKX0sUWY9e0FyY0N1cnZlOiRjLENhdG11bGxSb21DdXJ2ZTM6VmMsQ3ViaWNCZXppZXJDdXJ2ZTpCbyxDdWJpY0JlemllckN1cnZlMzpxYyxFbGxpcHNlQ3VydmU6X3MsTGluZUN1cnZlOkZvLExpbmVDdXJ2ZTM6SGMsUXVhZHJhdGljQmV6aWVyQ3VydmU6SW8sUXVhZHJhdGljQmV6aWVyQ3VydmUzOldjLFNwbGluZUN1cnZlOmtvfTtjbGFzcyBHbiBleHRlbmRzIHVle2NvbnN0cnVjdG9yKHQ9bmV3IFhjKFtuZXcgUiguNSwuNSksbmV3IFIoLS41LC41KSxuZXcgUigtLjUsLS41KSxuZXcgUiguNSwtLjUpXSksZT17fSl7c3VwZXIoKSx0aGlzLnR5cGU9IkV4dHJ1ZGVHZW9tZXRyeSIsdGhpcy5wYXJhbWV0ZXJzPXtzaGFwZXM6dCxvcHRpb25zOmV9LHQ9QXJyYXkuaXNBcnJheSh0KT90Olt0XTtjb25zdCBuPXRoaXMscz1bXSxyPVtdO2ZvcihsZXQgYT0wLGM9dC5sZW5ndGg7YTxjO2ErKyl7Y29uc3QgbD10W2FdO28obCl9dGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQmUocywzKSksdGhpcy5zZXRBdHRyaWJ1dGUoInV2IixuZXcgQmUociwyKSksdGhpcy5jb21wdXRlVmVydGV4Tm9ybWFscygpO2Z1bmN0aW9uIG8oYSl7dmFyIE91LER1LCR1O2NvbnN0IGM9W10sbD1lLmN1cnZlU2VnbWVudHMhPT12b2lkIDA/ZS5jdXJ2ZVNlZ21lbnRzOjEyLGg9ZS5zdGVwcyE9PXZvaWQgMD9lLnN0ZXBzOjEsdT1lLmRlcHRoIT09dm9pZCAwP2UuZGVwdGg6MTtsZXQgZj1lLmJldmVsRW5hYmxlZCE9PXZvaWQgMD9lLmJldmVsRW5hYmxlZDohMCxkPWUuYmV2ZWxUaGlja25lc3MhPT12b2lkIDA/ZS5iZXZlbFRoaWNrbmVzczouMixwPWUuYmV2ZWxTaXplIT09dm9pZCAwP2UuYmV2ZWxTaXplOmQtLjEseT1lLmJldmVsT2Zmc2V0IT09dm9pZCAwP2UuYmV2ZWxPZmZzZXQ6MCxtPWUuYmV2ZWxTZWdtZW50cyE9PXZvaWQgMD9lLmJldmVsU2VnbWVudHM6Mztjb25zdCBnPWUuZXh0cnVkZVBhdGgsYj1lLlVWR2VuZXJhdG9yIT09dm9pZCAwP2UuVVZHZW5lcmF0b3I6S2Ysdz0oT3U9ZS5oYXNUb3ApIT1udWxsP091OiEwLHg9KER1PWUuaGFzQm90dG9tKSE9bnVsbD9EdTohMCxNPSgkdT1lLmhhc1NpZGUpIT1udWxsPyR1OiEwO2xldCBBLFM9ITEsXyxFLHosdjtnJiYoQT1nLmdldFNwYWNlZFBvaW50cyhoKSxTPSEwLGY9ITEsXz1nLmNvbXB1dGVGcmVuZXRGcmFtZXMoaCwhMSksRT1uZXcgVCx6PW5ldyBULHY9bmV3IFQpLGZ8fChtPTAsZD0wLHA9MCx5PTApO2NvbnN0IEM9YS5leHRyYWN0UG9pbnRzKGwpO2xldCBQPUMuc2hhcGU7Y29uc3QgRj1DLmhvbGVzO2lmKCFXbi5pc0Nsb2NrV2lzZShQKSl7UD1QLnJldmVyc2UoKTtmb3IobGV0IE49MCxMPUYubGVuZ3RoO048TDtOKyspe2NvbnN0IE89RltOXTtXbi5pc0Nsb2NrV2lzZShPKSYmKEZbTl09Ty5yZXZlcnNlKCkpfX1mdW5jdGlvbiBJKE4pe2NvbnN0IE89MTAwMDAwMDAwMDAwMDAwMDFlLTM2O2xldCBWPU5bMF07Zm9yKGxldCAkPTE7JDw9Ti5sZW5ndGg7JCsrKXtjb25zdCBZPSQlTi5sZW5ndGgsRz1OW1ldLGl0PUcueC1WLngsY3Q9Ry55LVYueSx3dD1pdCppdCtjdCpjdCxYdD1NYXRoLm1heChNYXRoLmFicyhHLngpLE1hdGguYWJzKEcueSksTWF0aC5hYnMoVi54KSxNYXRoLmFicyhWLnkpKSxDbj1PKlh0Klh0O2lmKHd0PD1Dbil7Ti5zcGxpY2UoWSwxKSwkLS07Y29udGludWV9Vj1HfX1JKFApLEYuZm9yRWFjaChJKTtjb25zdCBrPUYubGVuZ3RoLEQ9UDtmb3IobGV0IE49MDtOPGs7TisrKXtjb25zdCBMPUZbTl07UD1QLmNvbmNhdChMKX1mdW5jdGlvbiBVKE4sTCxPKXtyZXR1cm4gTHx8Y29uc29sZS5lcnJvcigiVEhSRUUuRXh0cnVkZUdlb21ldHJ5OiB2ZWMgZG9lcyBub3QgZXhpc3QiKSxOLmNsb25lKCkuYWRkU2NhbGVkVmVjdG9yKEwsTyl9Y29uc3Qgaj1QLmxlbmd0aDtmdW5jdGlvbiBkdChOLEwsTyl7bGV0IFYsJCxZO2NvbnN0IEc9Ti54LUwueCxpdD1OLnktTC55LGN0PU8ueC1OLngsd3Q9Ty55LU4ueSxYdD1HKkcraXQqaXQsQ249Ryp3dC1pdCpjdDtpZihNYXRoLmFicyhDbik+TnVtYmVyLkVQU0lMT04pe2NvbnN0IEp0PU1hdGguc3FydChYdCksVnU9TWF0aC5zcXJ0KGN0KmN0K3d0Knd0KSxVdT1MLngtaXQvSnQscXU9TC55K0cvSnQsUGc9Ty54LXd0L1Z1LENnPU8ueStjdC9WdSxIdT0oKFBnLVV1KSp3dC0oQ2ctcXUpKmN0KS8oRyp3dC1pdCpjdCk7Vj1VdStHKkh1LU4ueCwkPXF1K2l0Kkh1LU4ueTtjb25zdCBXdT1WKlYrJCokO2lmKFd1PD0yKXJldHVybiBuZXcgUihWLCQpO1k9TWF0aC5zcXJ0KFd1LzIpfWVsc2V7bGV0IEp0PSExO0c+TnVtYmVyLkVQU0lMT04/Y3Q+TnVtYmVyLkVQU0lMT04mJihKdD0hMCk6RzwtTnVtYmVyLkVQU0lMT04/Y3Q8LU51bWJlci5FUFNJTE9OJiYoSnQ9ITApOk1hdGguc2lnbihpdCk9PT1NYXRoLnNpZ24od3QpJiYoSnQ9ITApLEp0PyhWPS1pdCwkPUcsWT1NYXRoLnNxcnQoWHQpKTooVj1HLCQ9aXQsWT1NYXRoLnNxcnQoWHQvMikpfXJldHVybiBuZXcgUihWL1ksJC9ZKX1jb25zdCBEdD1bXTtmb3IobGV0IE49MCxMPUQubGVuZ3RoLE89TC0xLFY9TisxO048TDtOKyssTysrLFYrKylPPT09TCYmKE89MCksVj09PUwmJihWPTApLER0W05dPWR0KERbTl0sRFtPXSxEW1ZdKTtjb25zdCBHdD1bXTtsZXQgWnQsbWU9RHQuY29uY2F0KCk7Zm9yKGxldCBOPTAsTD1rO048TDtOKyspe2NvbnN0IE89RltOXTtadD1bXTtmb3IobGV0IFY9MCwkPU8ubGVuZ3RoLFk9JC0xLEc9VisxO1Y8JDtWKyssWSsrLEcrKylZPT09JCYmKFk9MCksRz09PSQmJihHPTApLFp0W1ZdPWR0KE9bVl0sT1tZXSxPW0ddKTtHdC5wdXNoKFp0KSxtZT1tZS5jb25jYXQoWnQpfWxldCBQbjtpZihtPT09MClQbj1Xbi50cmlhbmd1bGF0ZVNoYXBlKEQsRik7ZWxzZXtjb25zdCBOPVtdLEw9W107Zm9yKGxldCBPPTA7TzxtO08rKyl7Y29uc3QgVj1PL20sJD1kKk1hdGguY29zKFYqTWF0aC5QSS8yKSxZPXAqTWF0aC5zaW4oVipNYXRoLlBJLzIpK3k7Zm9yKGxldCBHPTAsaXQ9RC5sZW5ndGg7RzxpdDtHKyspe2NvbnN0IGN0PVUoRFtHXSxEdFtHXSxZKTtIZShjdC54LGN0LnksLSQpLFY9PT0wJiZOLnB1c2goY3QpfWZvcihsZXQgRz0wLGl0PWs7RzxpdDtHKyspe2NvbnN0IGN0PUZbR107WnQ9R3RbR107Y29uc3Qgd3Q9W107Zm9yKGxldCBYdD0wLENuPWN0Lmxlbmd0aDtYdDxDbjtYdCsrKXtjb25zdCBKdD1VKGN0W1h0XSxadFtYdF0sWSk7SGUoSnQueCxKdC55LC0kKSxWPT09MCYmd3QucHVzaChKdCl9Vj09PTAmJkwucHVzaCh3dCl9fVBuPVduLnRyaWFuZ3VsYXRlU2hhcGUoTixMKX1jb25zdCBZcj1Qbi5sZW5ndGgsUnU9cCt5O2ZvcihsZXQgTj0wO048ajtOKyspe2NvbnN0IEw9Zj9VKFBbTl0sbWVbTl0sUnUpOlBbTl07Uz8oei5jb3B5KF8ubm9ybWFsc1swXSkubXVsdGlwbHlTY2FsYXIoTC54KSxFLmNvcHkoXy5iaW5vcm1hbHNbMF0pLm11bHRpcGx5U2NhbGFyKEwueSksdi5jb3B5KEFbMF0pLmFkZCh6KS5hZGQoRSksSGUodi54LHYueSx2LnopKTpIZShMLngsTC55LDApfWZvcihsZXQgTj0xO048PWg7TisrKWZvcihsZXQgTD0wO0w8ajtMKyspe2NvbnN0IE89Zj9VKFBbTF0sbWVbTF0sUnUpOlBbTF07Uz8oei5jb3B5KF8ubm9ybWFsc1tOXSkubXVsdGlwbHlTY2FsYXIoTy54KSxFLmNvcHkoXy5iaW5vcm1hbHNbTl0pLm11bHRpcGx5U2NhbGFyKE8ueSksdi5jb3B5KEFbTl0pLmFkZCh6KS5hZGQoRSksSGUodi54LHYueSx2LnopKTpIZShPLngsTy55LHUvaCpOKX1mb3IobGV0IE49bS0xO04+PTA7Ti0tKXtjb25zdCBMPU4vbSxPPWQqTWF0aC5jb3MoTCpNYXRoLlBJLzIpLFY9cCpNYXRoLnNpbihMKk1hdGguUEkvMikreTtmb3IobGV0ICQ9MCxZPUQubGVuZ3RoOyQ8WTskKyspe2NvbnN0IEc9VShEWyRdLER0WyRdLFYpO0hlKEcueCxHLnksdStPKX1mb3IobGV0ICQ9MCxZPUYubGVuZ3RoOyQ8WTskKyspe2NvbnN0IEc9RlskXTtadD1HdFskXTtmb3IobGV0IGl0PTAsY3Q9Ry5sZW5ndGg7aXQ8Y3Q7aXQrKyl7Y29uc3Qgd3Q9VShHW2l0XSxadFtpdF0sVik7Uz9IZSh3dC54LHd0LnkrQVtoLTFdLnksQVtoLTFdLngrTyk6SGUod3QueCx3dC55LHUrTyl9fX16ZygpLE0mJlRnKCk7ZnVuY3Rpb24gemcoKXtjb25zdCBOPXMubGVuZ3RoLzM7aWYoZil7bGV0IEw9MCxPPWoqTDtpZih4KWZvcihsZXQgVj0wO1Y8WXI7VisrKXtjb25zdCAkPVBuW1ZdO2pyKCRbMl0rTywkWzFdK08sJFswXStPKX1pZihMPWgrbSoyLE89aipMLHcpZm9yKGxldCBWPTA7VjxZcjtWKyspe2NvbnN0ICQ9UG5bVl07anIoJFswXStPLCRbMV0rTywkWzJdK08pfX1lbHNle2lmKHgpZm9yKGxldCBMPTA7TDxZcjtMKyspe2NvbnN0IE89UG5bTF07anIoT1syXSxPWzFdLE9bMF0pfWlmKHcpZm9yKGxldCBMPTA7TDxZcjtMKyspe2NvbnN0IE89UG5bTF07anIoT1swXStqKmgsT1sxXStqKmgsT1syXStqKmgpfX1uLmFkZEdyb3VwKE4scy5sZW5ndGgvMy1OLDApfWZ1bmN0aW9uIFRnKCl7Y29uc3QgTj1zLmxlbmd0aC8zO2xldCBMPTA7THUoRCxMKSxMKz1ELmxlbmd0aDtmb3IobGV0IE89MCxWPUYubGVuZ3RoO088VjtPKyspe2NvbnN0ICQ9RltPXTtMdSgkLEwpLEwrPSQubGVuZ3RofW4uYWRkR3JvdXAoTixzLmxlbmd0aC8zLU4sMSl9ZnVuY3Rpb24gTHUoTixMKXtsZXQgTz1OLmxlbmd0aDtmb3IoOy0tTz49MDspe2NvbnN0IFY9TztsZXQgJD1PLTE7JDwwJiYoJD1OLmxlbmd0aC0xKTtmb3IobGV0IFk9MCxHPWgrbSoyO1k8RztZKyspe2NvbnN0IGl0PWoqWSxjdD1qKihZKzEpLHd0PUwrVitpdCxYdD1MKyQraXQsQ249TCskK2N0LEp0PUwrVitjdDtFZyh3dCxYdCxDbixKdCl9fX1mdW5jdGlvbiBIZShOLEwsTyl7Yy5wdXNoKE4pLGMucHVzaChMKSxjLnB1c2goTyl9ZnVuY3Rpb24ganIoTixMLE8pe1dlKE4pLFdlKEwpLFdlKE8pO2NvbnN0IFY9cy5sZW5ndGgvMywkPWIuZ2VuZXJhdGVUb3BVVihuLHMsVi0zLFYtMixWLTEpO0dlKCRbMF0pLEdlKCRbMV0pLEdlKCRbMl0pfWZ1bmN0aW9uIEVnKE4sTCxPLFYpe1dlKE4pLFdlKEwpLFdlKFYpLFdlKEwpLFdlKE8pLFdlKFYpO2NvbnN0ICQ9cy5sZW5ndGgvMyxZPWIuZ2VuZXJhdGVTaWRlV2FsbFVWKG4scywkLTYsJC0zLCQtMiwkLTEpO0dlKFlbMF0pLEdlKFlbMV0pLEdlKFlbM10pLEdlKFlbMV0pLEdlKFlbMl0pLEdlKFlbM10pfWZ1bmN0aW9uIFdlKE4pe3MucHVzaChjW04qMyswXSkscy5wdXNoKGNbTiozKzFdKSxzLnB1c2goY1tOKjMrMl0pfWZ1bmN0aW9uIEdlKE4pe3IucHVzaChOLngpLHIucHVzaChOLnkpfX19Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnBhcmFtZXRlcnM9T2JqZWN0LmFzc2lnbih7fSx0LnBhcmFtZXRlcnMpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKSxlPXRoaXMucGFyYW1ldGVycy5zaGFwZXMsbj10aGlzLnBhcmFtZXRlcnMub3B0aW9ucztyZXR1cm4gdGQoZSxuLHQpfXN0YXRpYyBmcm9tSlNPTih0LGUpe2NvbnN0IG49W107Zm9yKGxldCByPTAsbz10LnNoYXBlcy5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1lW3Quc2hhcGVzW3JdXTtuLnB1c2goYSl9Y29uc3Qgcz10Lm9wdGlvbnMuZXh0cnVkZVBhdGg7cmV0dXJuIHMhPT12b2lkIDAmJih0Lm9wdGlvbnMuZXh0cnVkZVBhdGg9bmV3IFFmW2Ake3MudHlwZX1gXSgpLmZyb21KU09OKHMpKSxuZXcgR24obix0Lm9wdGlvbnMpfX1jb25zdCBLZj17Z2VuZXJhdGVUb3BVVjpmdW5jdGlvbihpLHQsZSxuLHMpe2NvbnN0IHI9dFtlKjNdLG89dFtlKjMrMV0sYT10W24qM10sYz10W24qMysxXSxsPXRbcyozXSxoPXRbcyozKzFdO3JldHVybltuZXcgUihyLG8pLG5ldyBSKGEsYyksbmV3IFIobCxoKV19LGdlbmVyYXRlU2lkZVdhbGxVVjpmdW5jdGlvbihpLHQsZSxuLHMscil7Y29uc3Qgbz10W2UqM10sYT10W2UqMysxXSxjPXRbZSozKzJdLGw9dFtuKjNdLGg9dFtuKjMrMV0sdT10W24qMysyXSxmPXRbcyozXSxkPXRbcyozKzFdLHA9dFtzKjMrMl0seT10W3IqM10sbT10W3IqMysxXSxnPXRbciozKzJdO3JldHVybiBNYXRoLmFicyhhLWgpPE1hdGguYWJzKG8tbCk/W25ldyBSKG8sMS1jKSxuZXcgUihsLDEtdSksbmV3IFIoZiwxLXApLG5ldyBSKHksMS1nKV06W25ldyBSKGEsMS1jKSxuZXcgUihoLDEtdSksbmV3IFIoZCwxLXApLG5ldyBSKG0sMS1nKV19fTtmdW5jdGlvbiB0ZChpLHQsZSl7aWYoZS5zaGFwZXM9W10sQXJyYXkuaXNBcnJheShpKSlmb3IobGV0IG49MCxzPWkubGVuZ3RoO248cztuKyspe2NvbnN0IHI9aVtuXTtlLnNoYXBlcy5wdXNoKHIudXVpZCl9ZWxzZSBlLnNoYXBlcy5wdXNoKGkudXVpZCk7cmV0dXJuIGUub3B0aW9ucz1PYmplY3QuYXNzaWduKHt9LHQpLHQuZXh0cnVkZVBhdGghPT12b2lkIDAmJihlLm9wdGlvbnMuZXh0cnVkZVBhdGg9dC5leHRydWRlUGF0aC50b0pTT04oKSksZX1jb25zdCBpbD0wLGVkPTEsbmQ9MixzbD0yLE9vPTEuMjUscmw9MSxQaT02KjQrNCs0LFBzPTY1NTM1LGlkPU1hdGgucG93KDIsLTI0KSxEbz1TeW1ib2woIlNLSVBfR0VORVJBVElPTiIpO2Z1bmN0aW9uIHNkKGkpe3JldHVybiBpLmluZGV4P2kuaW5kZXguY291bnQ6aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWZ1bmN0aW9uIFpuKGkpe3JldHVybiBzZChpKS8zfWZ1bmN0aW9uIHJkKGksdD1BcnJheUJ1ZmZlcil7cmV0dXJuIGk+NjU1MzU/bmV3IFVpbnQzMkFycmF5KG5ldyB0KDQqaSkpOm5ldyBVaW50MTZBcnJheShuZXcgdCgyKmkpKX1mdW5jdGlvbiBvZChpLHQpe2lmKCFpLmluZGV4KXtjb25zdCBlPWkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudCxuPXQudXNlU2hhcmVkQXJyYXlCdWZmZXI/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1yZChlLG4pO2kuc2V0SW5kZXgobmV3IHh0KHMsMSkpO2ZvcihsZXQgcj0wO3I8ZTtyKyspc1tyXT1yfX1mdW5jdGlvbiBvbChpLHQpe2NvbnN0IGU9Wm4oaSksbj10fHxpLmRyYXdSYW5nZSxzPW4uc3RhcnQvMyxyPShuLnN0YXJ0K24uY291bnQpLzMsbz1NYXRoLm1heCgwLHMpLGE9TWF0aC5taW4oZSxyKS1vO3JldHVyblt7b2Zmc2V0Ok1hdGguZmxvb3IobyksY291bnQ6TWF0aC5mbG9vcihhKX1dfWZ1bmN0aW9uIGFsKGksdCl7aWYoIWkuZ3JvdXBzfHwhaS5ncm91cHMubGVuZ3RoKXJldHVybiBvbChpLHQpO2NvbnN0IGU9W10sbj1uZXcgU2V0LHM9dHx8aS5kcmF3UmFuZ2Uscj1zLnN0YXJ0LzMsbz0ocy5zdGFydCtzLmNvdW50KS8zO2Zvcihjb25zdCBjIG9mIGkuZ3JvdXBzKXtjb25zdCBsPWMuc3RhcnQvMyxoPShjLnN0YXJ0K2MuY291bnQpLzM7bi5hZGQoTWF0aC5tYXgocixsKSksbi5hZGQoTWF0aC5taW4obyxoKSl9Y29uc3QgYT1BcnJheS5mcm9tKG4udmFsdWVzKCkpLnNvcnQoKGMsbCk9PmMtbCk7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aC0xO2MrKyl7Y29uc3QgbD1hW2NdLGg9YVtjKzFdO2UucHVzaCh7b2Zmc2V0Ok1hdGguZmxvb3IobCksY291bnQ6TWF0aC5mbG9vcihoLWwpfSl9cmV0dXJuIGV9ZnVuY3Rpb24gYWQoaSx0KXtjb25zdCBlPVpuKGkpLG49YWwoaSx0KS5zb3J0KChvLGEpPT5vLm9mZnNldC1hLm9mZnNldCkscz1uW24ubGVuZ3RoLTFdO3MuY291bnQ9TWF0aC5taW4oZS1zLm9mZnNldCxzLmNvdW50KTtsZXQgcj0wO3JldHVybiBuLmZvckVhY2goKHtjb3VudDpvfSk9PnIrPW8pLGUhPT1yfWZ1bmN0aW9uICRvKGksdCxlLG4scyl7bGV0IHI9MS8wLG89MS8wLGE9MS8wLGM9LTEvMCxsPS0xLzAsaD0tMS8wLHU9MS8wLGY9MS8wLGQ9MS8wLHA9LTEvMCx5PS0xLzAsbT0tMS8wO2ZvcihsZXQgZz10KjYsYj0odCtlKSo2O2c8YjtnKz02KXtjb25zdCB3PWlbZyswXSx4PWlbZysxXSxNPXcteCxBPXcreDtNPHImJihyPU0pLEE+YyYmKGM9QSksdzx1JiYodT13KSx3PnAmJihwPXcpO2NvbnN0IFM9aVtnKzJdLF89aVtnKzNdLEU9Uy1fLHo9UytfO0U8byYmKG89RSksej5sJiYobD16KSxTPGYmJihmPVMpLFM+eSYmKHk9Uyk7Y29uc3Qgdj1pW2crNF0sQz1pW2crNV0sUD12LUMsRj12K0M7UDxhJiYoYT1QKSxGPmgmJihoPUYpLHY8ZCYmKGQ9diksdj5tJiYobT12KX1uWzBdPXIsblsxXT1vLG5bMl09YSxuWzNdPWMsbls0XT1sLG5bNV09aCxzWzBdPXUsc1sxXT1mLHNbMl09ZCxzWzNdPXAsc1s0XT15LHNbNV09bX1mdW5jdGlvbiBjZChpLHQ9bnVsbCxlPW51bGwsbj1udWxsKXtjb25zdCBzPWkuYXR0cmlidXRlcy5wb3NpdGlvbixyPWkuaW5kZXg/aS5pbmRleC5hcnJheTpudWxsLG89Wm4oaSksYT1zLm5vcm1hbGl6ZWQ7bGV0IGM7dD09PW51bGw/KGM9bmV3IEZsb2F0MzJBcnJheShvKjYpLGU9MCxuPW8pOihjPXQsZT1lfHwwLG49bnx8byk7Y29uc3QgbD1zLmFycmF5LGg9cy5vZmZzZXR8fDA7bGV0IHU9MztzLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUmJih1PXMuZGF0YS5zdHJpZGUpO2NvbnN0IGY9WyJnZXRYIiwiZ2V0WSIsImdldFoiXTtmb3IobGV0IGQ9ZTtkPGUrbjtkKyspe2NvbnN0IHA9ZCozLHk9ZCo2O2xldCBtPXArMCxnPXArMSxiPXArMjtyJiYobT1yW21dLGc9cltnXSxiPXJbYl0pLGF8fChtPW0qdStoLGc9Zyp1K2gsYj1iKnUraCk7Zm9yKGxldCB3PTA7dzwzO3crKyl7bGV0IHgsTSxBO2E/KHg9c1tmW3ddXShtKSxNPXNbZlt3XV0oZyksQT1zW2Zbd11dKGIpKTooeD1sW20rd10sTT1sW2crd10sQT1sW2Ird10pO2xldCBTPXg7TTxTJiYoUz1NKSxBPFMmJihTPUEpO2xldCBfPXg7TT5fJiYoXz1NKSxBPl8mJihfPUEpO2NvbnN0IEU9KF8tUykvMix6PXcqMjtjW3kreiswXT1TK0UsY1t5K3orMV09RSsoTWF0aC5hYnMoUykrRSkqaWR9fXJldHVybiBjfWZ1bmN0aW9uIGx0KGksdCxlKXtyZXR1cm4gZS5taW4ueD10W2ldLGUubWluLnk9dFtpKzFdLGUubWluLno9dFtpKzJdLGUubWF4Lng9dFtpKzNdLGUubWF4Lnk9dFtpKzRdLGUubWF4Lno9dFtpKzVdLGV9ZnVuY3Rpb24gY2woaSl7bGV0IHQ9LTEsZT0tMS8wO2ZvcihsZXQgbj0wO248MztuKyspe2NvbnN0IHM9aVtuKzNdLWlbbl07cz5lJiYoZT1zLHQ9bil9cmV0dXJuIHR9ZnVuY3Rpb24gbGwoaSx0KXt0LnNldChpKX1mdW5jdGlvbiBobChpLHQsZSl7bGV0IG4scztmb3IobGV0IHI9MDtyPDM7cisrKXtjb25zdCBvPXIrMztuPWlbcl0scz10W3JdLGVbcl09bjxzP246cyxuPWlbb10scz10W29dLGVbb109bj5zP246c319ZnVuY3Rpb24gQ3MoaSx0LGUpe2ZvcihsZXQgbj0wO248MztuKyspe2NvbnN0IHM9dFtpKzIqbl0scj10W2krMipuKzFdLG89cy1yLGE9cytyO288ZVtuXSYmKGVbbl09byksYT5lW24rM10mJihlW24rM109YSl9fWZ1bmN0aW9uIENpKGkpe2NvbnN0IHQ9aVszXS1pWzBdLGU9aVs0XS1pWzFdLG49aVs1XS1pWzJdO3JldHVybiAyKih0KmUrZSpuK24qdCl9Y29uc3QgRmU9MzIsbGQ9KGksdCk9PmkuY2FuZGlkYXRlLXQuY2FuZGlkYXRlLEtlPW5ldyBBcnJheShGZSkuZmlsbCgpLm1hcCgoKT0+KHtjb3VudDowLGJvdW5kczpuZXcgRmxvYXQzMkFycmF5KDYpLHJpZ2h0Q2FjaGVCb3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxsZWZ0Q2FjaGVCb3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxjYW5kaWRhdGU6MH0pKSxCcz1uZXcgRmxvYXQzMkFycmF5KDYpO2Z1bmN0aW9uIGhkKGksdCxlLG4scyxyKXtsZXQgbz0tMSxhPTA7aWYocj09PWlsKW89Y2wodCksbyE9PS0xJiYoYT0odFtvXSt0W28rM10pLzIpO2Vsc2UgaWYocj09PWVkKW89Y2woaSksbyE9PS0xJiYoYT11ZChlLG4scyxvKSk7ZWxzZSBpZihyPT09bmQpe2NvbnN0IGM9Q2koaSk7bGV0IGw9T28qcztjb25zdCBoPW4qNix1PShuK3MpKjY7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD10W2ZdLG09KHRbZiszXS1kKS9GZTtpZihzPEZlLzQpe2NvbnN0IGc9Wy4uLktlXTtnLmxlbmd0aD1zO2xldCBiPTA7Zm9yKGxldCB4PWg7eDx1O3grPTYsYisrKXtjb25zdCBNPWdbYl07TS5jYW5kaWRhdGU9ZVt4KzIqZl0sTS5jb3VudD0wO2NvbnN0e2JvdW5kczpBLGxlZnRDYWNoZUJvdW5kczpTLHJpZ2h0Q2FjaGVCb3VuZHM6X309TTtmb3IobGV0IEU9MDtFPDM7RSsrKV9bRV09MS8wLF9bRSszXT0tMS8wLFNbRV09MS8wLFNbRSszXT0tMS8wLEFbRV09MS8wLEFbRSszXT0tMS8wO0NzKHgsZSxBKX1nLnNvcnQobGQpO2xldCB3PXM7Zm9yKGxldCB4PTA7eDx3O3grKyl7Y29uc3QgTT1nW3hdO2Zvcig7eCsxPHcmJmdbeCsxXS5jYW5kaWRhdGU9PT1NLmNhbmRpZGF0ZTspZy5zcGxpY2UoeCsxLDEpLHctLX1mb3IobGV0IHg9aDt4PHU7eCs9Nil7Y29uc3QgTT1lW3grMipmXTtmb3IobGV0IEE9MDtBPHc7QSsrKXtjb25zdCBTPWdbQV07TT49Uy5jYW5kaWRhdGU/Q3MoeCxlLFMucmlnaHRDYWNoZUJvdW5kcyk6KENzKHgsZSxTLmxlZnRDYWNoZUJvdW5kcyksUy5jb3VudCsrKX19Zm9yKGxldCB4PTA7eDx3O3grKyl7Y29uc3QgTT1nW3hdLEE9TS5jb3VudCxTPXMtTS5jb3VudCxfPU0ubGVmdENhY2hlQm91bmRzLEU9TS5yaWdodENhY2hlQm91bmRzO2xldCB6PTA7QSE9PTAmJih6PUNpKF8pL2MpO2xldCB2PTA7UyE9PTAmJih2PUNpKEUpL2MpO2NvbnN0IEM9cmwrT28qKHoqQSt2KlMpO0M8bCYmKG89ZixsPUMsYT1NLmNhbmRpZGF0ZSl9fWVsc2V7Zm9yKGxldCB3PTA7dzxGZTt3Kyspe2NvbnN0IHg9S2Vbd107eC5jb3VudD0wLHguY2FuZGlkYXRlPWQrbSt3Km07Y29uc3QgTT14LmJvdW5kcztmb3IobGV0IEE9MDtBPDM7QSsrKU1bQV09MS8wLE1bQSszXT0tMS8wfWZvcihsZXQgdz1oO3c8dTt3Kz02KXtsZXQgQT1+figoZVt3KzIqZl0tZCkvbSk7QT49RmUmJihBPUZlLTEpO2NvbnN0IFM9S2VbQV07Uy5jb3VudCsrLENzKHcsZSxTLmJvdW5kcyl9Y29uc3QgZz1LZVtGZS0xXTtsbChnLmJvdW5kcyxnLnJpZ2h0Q2FjaGVCb3VuZHMpO2ZvcihsZXQgdz1GZS0yO3c+PTA7dy0tKXtjb25zdCB4PUtlW3ddLE09S2VbdysxXTtobCh4LmJvdW5kcyxNLnJpZ2h0Q2FjaGVCb3VuZHMseC5yaWdodENhY2hlQm91bmRzKX1sZXQgYj0wO2ZvcihsZXQgdz0wO3c8RmUtMTt3Kyspe2NvbnN0IHg9S2Vbd10sTT14LmNvdW50LEE9eC5ib3VuZHMsXz1LZVt3KzFdLnJpZ2h0Q2FjaGVCb3VuZHM7TSE9PTAmJihiPT09MD9sbChBLEJzKTpobChBLEJzLEJzKSksYis9TTtsZXQgRT0wLHo9MDtiIT09MCYmKEU9Q2koQnMpL2MpO2NvbnN0IHY9cy1iO3YhPT0wJiYoej1DaShfKS9jKTtjb25zdCBDPXJsK09vKihFKmIreip2KTtDPGwmJihvPWYsbD1DLGE9eC5jYW5kaWRhdGUpfX19fWVsc2UgY29uc29sZS53YXJuKGBNZXNoQlZIOiBJbnZhbGlkIGJ1aWxkIHN0cmF0ZWd5IHZhbHVlICR7cn0gdXNlZC5gKTtyZXR1cm57YXhpczpvLHBvczphfX1mdW5jdGlvbiB1ZChpLHQsZSxuKXtsZXQgcz0wO2ZvcihsZXQgcj10LG89dCtlO3I8bztyKyspcys9aVtyKjYrbioyXTtyZXR1cm4gcy9lfWNsYXNzIFZve2NvbnN0cnVjdG9yKCl7dGhpcy5ib3VuZGluZ0RhdGE9bmV3IEZsb2F0MzJBcnJheSg2KX19ZnVuY3Rpb24gZmQoaSx0LGUsbixzLHIpe2xldCBvPW4sYT1uK3MtMTtjb25zdCBjPXIucG9zLGw9ci5heGlzKjI7Zm9yKDs7KXtmb3IoO288PWEmJmVbbyo2K2xdPGM7KW8rKztmb3IoO288PWEmJmVbYSo2K2xdPj1jOylhLS07aWYobzxhKXtmb3IobGV0IGg9MDtoPDM7aCsrKXtsZXQgdT10W28qMytoXTt0W28qMytoXT10W2EqMytoXSx0W2EqMytoXT11fWZvcihsZXQgaD0wO2g8NjtoKyspe2xldCB1PWVbbyo2K2hdO2Vbbyo2K2hdPWVbYSo2K2hdLGVbYSo2K2hdPXV9bysrLGEtLX1lbHNlIHJldHVybiBvfX1mdW5jdGlvbiBkZChpLHQsZSxuLHMscil7bGV0IG89bixhPW4rcy0xO2NvbnN0IGM9ci5wb3MsbD1yLmF4aXMqMjtmb3IoOzspe2Zvcig7bzw9YSYmZVtvKjYrbF08YzspbysrO2Zvcig7bzw9YSYmZVthKjYrbF0+PWM7KWEtLTtpZihvPGEpe2xldCBoPWlbb107aVtvXT1pW2FdLGlbYV09aDtmb3IobGV0IHU9MDt1PDY7dSsrKXtsZXQgZj1lW28qNit1XTtlW28qNit1XT1lW2EqNit1XSxlW2EqNit1XT1mfW8rKyxhLS19ZWxzZSByZXR1cm4gb319ZnVuY3Rpb24ga3QoaSx0KXtyZXR1cm4gdFtpKzE1XT09PTY1NTM1fWZ1bmN0aW9uIFV0KGksdCl7cmV0dXJuIHRbaSs2XX1mdW5jdGlvbiBLdChpLHQpe3JldHVybiB0W2krMTRdfWZ1bmN0aW9uIHRlKGkpe3JldHVybiBpKzh9ZnVuY3Rpb24gZWUoaSx0KXtyZXR1cm4gdFtpKzZdfWZ1bmN0aW9uIHVsKGksdCl7cmV0dXJuIHRbaSs3XX1mdW5jdGlvbiBqZyhpKXtyZXR1cm4gaX1sZXQgZmwsQmksRnMsZGw7Y29uc3QgcGQ9TWF0aC5wb3coMiwzMik7ZnVuY3Rpb24gVW8oaSl7cmV0dXJuImNvdW50ImluIGk/MToxK1VvKGkubGVmdCkrVW8oaS5yaWdodCl9ZnVuY3Rpb24geWQoaSx0LGUpe3JldHVybiBmbD1uZXcgRmxvYXQzMkFycmF5KGUpLEJpPW5ldyBVaW50MzJBcnJheShlKSxGcz1uZXcgVWludDE2QXJyYXkoZSksZGw9bmV3IFVpbnQ4QXJyYXkoZSkscW8oaSx0KX1mdW5jdGlvbiBxbyhpLHQpe2NvbnN0IGU9aS80LG49aS8yLHM9ImNvdW50ImluIHQscj10LmJvdW5kaW5nRGF0YTtmb3IobGV0IG89MDtvPDY7bysrKWZsW2Urb109cltvXTtpZihzKWlmKHQuYnVmZmVyKXtjb25zdCBvPXQuYnVmZmVyO2RsLnNldChuZXcgVWludDhBcnJheShvKSxpKTtmb3IobGV0IGE9aSxjPWkrby5ieXRlTGVuZ3RoO2E8YzthKz1QaSl7Y29uc3QgbD1hLzI7a3QobCxGcyl8fChCaVthLzQrNl0rPWUpfXJldHVybiBpK28uYnl0ZUxlbmd0aH1lbHNle2NvbnN0IG89dC5vZmZzZXQsYT10LmNvdW50O3JldHVybiBCaVtlKzZdPW8sRnNbbisxNF09YSxGc1tuKzE1XT1QcyxpK1BpfWVsc2V7Y29uc3Qgbz10LmxlZnQsYT10LnJpZ2h0LGM9dC5zcGxpdEF4aXM7bGV0IGw7aWYobD1xbyhpK1BpLG8pLGwvND5wZCl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IENhbm5vdCBzdG9yZSBjaGlsZCBwb2ludGVyIGdyZWF0ZXIgdGhhbiAzMiBiaXRzLiIpO3JldHVybiBCaVtlKzZdPWwvNCxsPXFvKGwsYSksQmlbZSs3XT1jLGx9fWZ1bmN0aW9uIG1kKGksdCl7Y29uc3QgZT0oaS5pbmRleD9pLmluZGV4LmNvdW50OmkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudCkvMyxuPWU+eWkoMiwxNikscz1uPzQ6MixyPXQ/bmV3IFNoYXJlZEFycmF5QnVmZmVyKGUqcyk6bmV3IEFycmF5QnVmZmVyKGUqcyksbz1uP25ldyBVaW50MzJBcnJheShyKTpuZXcgVWludDE2QXJyYXkocik7Zm9yKGxldCBhPTAsYz1vLmxlbmd0aDthPGM7YSsrKW9bYV09YTtyZXR1cm4gb31mdW5jdGlvbiBnZChpLHQsZSxuLHMpe2NvbnN0e21heERlcHRoOnIsdmVyYm9zZTpvLG1heExlYWZUcmlzOmEsc3RyYXRlZ3k6YyxvblByb2dyZXNzOmwsaW5kaXJlY3Q6aH09cyx1PWkuX2luZGlyZWN0QnVmZmVyLGY9aS5nZW9tZXRyeSxkPWYuaW5kZXg/Zi5pbmRleC5hcnJheTpudWxsLHA9aD9kZDpmZCx5PVpuKGYpLG09bmV3IEZsb2F0MzJBcnJheSg2KTtsZXQgZz0hMTtjb25zdCBiPW5ldyBWbztyZXR1cm4gJG8odCxlLG4sYi5ib3VuZGluZ0RhdGEsbSkseChiLGUsbixtKSxiO2Z1bmN0aW9uIHcoTSl7bCYmbChNL3kpfWZ1bmN0aW9uIHgoTSxBLFMsXz1udWxsLEU9MCl7aWYoIWcmJkU+PXImJihnPSEwLG8mJihjb25zb2xlLndhcm4oYE1lc2hCVkg6IE1heCBkZXB0aCBvZiAke3J9IHJlYWNoZWQgd2hlbiBnZW5lcmF0aW5nIEJWSC4gQ29uc2lkZXIgaW5jcmVhc2luZyBtYXhEZXB0aC5gKSxjb25zb2xlLndhcm4oZikpKSxTPD1hfHxFPj1yKXJldHVybiB3KEErUyksTS5vZmZzZXQ9QSxNLmNvdW50PVMsTTtjb25zdCB6PWhkKE0uYm91bmRpbmdEYXRhLF8sdCxBLFMsYyk7aWYoei5heGlzPT09LTEpcmV0dXJuIHcoQStTKSxNLm9mZnNldD1BLE0uY291bnQ9UyxNO2NvbnN0IHY9cCh1LGQsdCxBLFMseik7aWYodj09PUF8fHY9PT1BK1MpdyhBK1MpLE0ub2Zmc2V0PUEsTS5jb3VudD1TO2Vsc2V7TS5zcGxpdEF4aXM9ei5heGlzO2NvbnN0IEM9bmV3IFZvLFA9QSxGPXYtQTtNLmxlZnQ9Qywkbyh0LFAsRixDLmJvdW5kaW5nRGF0YSxtKSx4KEMsUCxGLG0sRSsxKTtjb25zdCBCPW5ldyBWbyxJPXYsaz1TLUY7TS5yaWdodD1CLCRvKHQsSSxrLEIuYm91bmRpbmdEYXRhLG0pLHgoQixJLGssbSxFKzEpfXJldHVybiBNfX1mdW5jdGlvbiB4ZChpLHQpe2NvbnN0IGU9aS5nZW9tZXRyeTt0LmluZGlyZWN0JiYoaS5faW5kaXJlY3RCdWZmZXI9bWQoZSx0LnVzZVNoYXJlZEFycmF5QnVmZmVyKSxhZChlLHQucmFuZ2UpJiYhdC52ZXJib3NlJiZjb25zb2xlLndhcm4oJ01lc2hCVkg6IFByb3ZpZGVkIGdlb21ldHJ5IGNvbnRhaW5zIGdyb3VwcyBvciBhIHJhbmdlIHRoYXQgZG8gbm90IGZ1bGx5IHNwYW4gdGhlIHZlcnRleCBjb250ZW50cyB3aGlsZSB1c2luZyB0aGUgImluZGlyZWN0IiBvcHRpb24uIEJWSCBtYXkgaW5jb3JyZWN0bHkgcmVwb3J0IGludGVyc2VjdGlvbnMgb24gdW5yZW5kZXJlZCBwb3J0aW9ucyBvZiB0aGUgZ2VvbWV0cnkuJykpLGkuX2luZGlyZWN0QnVmZmVyfHxvZChlLHQpO2NvbnN0IG49dC51c2VTaGFyZWRBcnJheUJ1ZmZlcj9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPWNkKGUpLHI9dC5pbmRpcmVjdD9vbChlLHQucmFuZ2UpOmFsKGUsdC5yYW5nZSk7aS5fcm9vdHM9ci5tYXAobz0+e2NvbnN0IGE9Z2QoaSxzLG8ub2Zmc2V0LG8uY291bnQsdCksYz1VbyhhKSxsPW5ldyBuKFBpKmMpO3JldHVybiB5ZCgwLGEsbCksbH0pfWNsYXNzIElle2NvbnN0cnVjdG9yKCl7dGhpcy5taW49MS8wLHRoaXMubWF4PS0xLzB9c2V0RnJvbVBvaW50c0ZpZWxkKHQsZSl7bGV0IG49MS8wLHM9LTEvMDtmb3IobGV0IHI9MCxvPXQubGVuZ3RoO3I8bztyKyspe2NvbnN0IGM9dFtyXVtlXTtuPWM8bj9jOm4scz1jPnM/YzpzfXRoaXMubWluPW4sdGhpcy5tYXg9c31zZXRGcm9tUG9pbnRzKHQsZSl7bGV0IG49MS8wLHM9LTEvMDtmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVtyXSxjPXQuZG90KGEpO249YzxuP2M6bixzPWM+cz9jOnN9dGhpcy5taW49bix0aGlzLm1heD1zfWlzU2VwYXJhdGVkKHQpe3JldHVybiB0aGlzLm1pbj50Lm1heHx8dC5taW4+dGhpcy5tYXh9fUllLnByb3RvdHlwZS5zZXRGcm9tQm94PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSxuKXtjb25zdCBzPW4ubWluLHI9bi5tYXg7bGV0IG89MS8wLGE9LTEvMDtmb3IobGV0IGM9MDtjPD0xO2MrKylmb3IobGV0IGw9MDtsPD0xO2wrKylmb3IobGV0IGg9MDtoPD0xO2grKyl7aS54PXMueCpjK3IueCooMS1jKSxpLnk9cy55Kmwrci55KigxLWwpLGkuej1zLnoqaCtyLnoqKDEtaCk7Y29uc3QgdT1lLmRvdChpKTtvPU1hdGgubWluKHUsbyksYT1NYXRoLm1heCh1LGEpfXRoaXMubWluPW8sdGhpcy5tYXg9YX19KCk7Y29uc3Qgd2Q9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24ocyxyLG8pe2NvbnN0IGE9cy5zdGFydCxjPWksbD1yLnN0YXJ0LGg9dDtlLnN1YlZlY3RvcnMoYSxsKSxpLnN1YlZlY3RvcnMocy5lbmQscy5zdGFydCksdC5zdWJWZWN0b3JzKHIuZW5kLHIuc3RhcnQpO2NvbnN0IHU9ZS5kb3QoaCksZj1oLmRvdChjKSxkPWguZG90KGgpLHA9ZS5kb3QoYyksbT1jLmRvdChjKSpkLWYqZjtsZXQgZyxiO20hPT0wP2c9KHUqZi1wKmQpL206Zz0wLGI9KHUrZypmKS9kLG8ueD1nLG8ueT1ifX0oKSxIbz1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFIsdD1uZXcgVCxlPW5ldyBUO3JldHVybiBmdW5jdGlvbihzLHIsbyxhKXt3ZChzLHIsaSk7bGV0IGM9aS54LGw9aS55O2lmKGM+PTAmJmM8PTEmJmw+PTAmJmw8PTEpe3MuYXQoYyxvKSxyLmF0KGwsYSk7cmV0dXJufWVsc2UgaWYoYz49MCYmYzw9MSl7bDwwP3IuYXQoMCxhKTpyLmF0KDEsYSkscy5jbG9zZXN0UG9pbnRUb1BvaW50KGEsITAsbyk7cmV0dXJufWVsc2UgaWYobD49MCYmbDw9MSl7YzwwP3MuYXQoMCxvKTpzLmF0KDEsbyksci5jbG9zZXN0UG9pbnRUb1BvaW50KG8sITAsYSk7cmV0dXJufWVsc2V7bGV0IGg7YzwwP2g9cy5zdGFydDpoPXMuZW5kO2xldCB1O2w8MD91PXIuc3RhcnQ6dT1yLmVuZDtjb25zdCBmPXQsZD1lO2lmKHMuY2xvc2VzdFBvaW50VG9Qb2ludCh1LCEwLHQpLHIuY2xvc2VzdFBvaW50VG9Qb2ludChoLCEwLGUpLGYuZGlzdGFuY2VUb1NxdWFyZWQodSk8PWQuZGlzdGFuY2VUb1NxdWFyZWQoaCkpe28uY29weShmKSxhLmNvcHkodSk7cmV0dXJufWVsc2V7by5jb3B5KGgpLGEuY29weShkKTtyZXR1cm59fX19KCksYmQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgem8sbj1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKHIsbyl7Y29uc3R7cmFkaXVzOmEsY2VudGVyOmN9PXIse2E6bCxiOmgsYzp1fT1vO2lmKG4uc3RhcnQ9bCxuLmVuZD1oLG4uY2xvc2VzdFBvaW50VG9Qb2ludChjLCEwLGkpLmRpc3RhbmNlVG8oYyk8PWF8fChuLnN0YXJ0PWwsbi5lbmQ9dSxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hKXx8KG4uc3RhcnQ9aCxuLmVuZD11LG4uY2xvc2VzdFBvaW50VG9Qb2ludChjLCEwLGkpLmRpc3RhbmNlVG8oYyk8PWEpKXJldHVybiEwO2NvbnN0IHk9by5nZXRQbGFuZShlKTtpZihNYXRoLmFicyh5LmRpc3RhbmNlVG9Qb2ludChjKSk8PWEpe2NvbnN0IGc9eS5wcm9qZWN0UG9pbnQoYyx0KTtpZihvLmNvbnRhaW5zUG9pbnQoZykpcmV0dXJuITB9cmV0dXJuITF9fSgpLE1kPTFlLTE1O2Z1bmN0aW9uIFdvKGkpe3JldHVybiBNYXRoLmFicyhpKTxNZH1jbGFzcyBuZSBleHRlbmRzIGV0e2NvbnN0cnVjdG9yKC4uLnQpe3N1cGVyKC4uLnQpLHRoaXMuaXNFeHRlbmRlZFRyaWFuZ2xlPSEwLHRoaXMuc2F0QXhlcz1uZXcgQXJyYXkoNCkuZmlsbCgpLm1hcCgoKT0+bmV3IFQpLHRoaXMuc2F0Qm91bmRzPW5ldyBBcnJheSg0KS5maWxsKCkubWFwKCgpPT5uZXcgSWUpLHRoaXMucG9pbnRzPVt0aGlzLmEsdGhpcy5iLHRoaXMuY10sdGhpcy5zcGhlcmU9bmV3IGNvLHRoaXMucGxhbmU9bmV3IHpvLHRoaXMubmVlZHNVcGRhdGU9ITB9aW50ZXJzZWN0c1NwaGVyZSh0KXtyZXR1cm4gYmQodCx0aGlzKX11cGRhdGUoKXtjb25zdCB0PXRoaXMuYSxlPXRoaXMuYixuPXRoaXMuYyxzPXRoaXMucG9pbnRzLHI9dGhpcy5zYXRBeGVzLG89dGhpcy5zYXRCb3VuZHMsYT1yWzBdLGM9b1swXTt0aGlzLmdldE5vcm1hbChhKSxjLnNldEZyb21Qb2ludHMoYSxzKTtjb25zdCBsPXJbMV0saD1vWzFdO2wuc3ViVmVjdG9ycyh0LGUpLGguc2V0RnJvbVBvaW50cyhsLHMpO2NvbnN0IHU9clsyXSxmPW9bMl07dS5zdWJWZWN0b3JzKGUsbiksZi5zZXRGcm9tUG9pbnRzKHUscyk7Y29uc3QgZD1yWzNdLHA9b1szXTtkLnN1YlZlY3RvcnMobix0KSxwLnNldEZyb21Qb2ludHMoZCxzKSx0aGlzLnNwaGVyZS5zZXRGcm9tUG9pbnRzKHRoaXMucG9pbnRzKSx0aGlzLnBsYW5lLnNldEZyb21Ob3JtYWxBbmRDb3BsYW5hclBvaW50KGEsdCksdGhpcy5uZWVkc1VwZGF0ZT0hMX19bmUucHJvdG90eXBlLmNsb3Nlc3RQb2ludFRvU2VnbWVudD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQsdD1uZXcgVCxlPW5ldyBRdDtyZXR1cm4gZnVuY3Rpb24ocyxyPW51bGwsbz1udWxsKXtjb25zdHtzdGFydDphLGVuZDpjfT1zLGw9dGhpcy5wb2ludHM7bGV0IGgsdT0xLzA7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD0oZisxKSUzO2Uuc3RhcnQuY29weShsW2ZdKSxlLmVuZC5jb3B5KGxbZF0pLEhvKGUscyxpLHQpLGg9aS5kaXN0YW5jZVRvU3F1YXJlZCh0KSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weSh0KSl9cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChhLGkpLGg9YS5kaXN0YW5jZVRvU3F1YXJlZChpKSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weShhKSksdGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50KGMsaSksaD1jLmRpc3RhbmNlVG9TcXVhcmVkKGkpLGg8dSYmKHU9aCxyJiZyLmNvcHkoaSksbyYmby5jb3B5KGMpKSxNYXRoLnNxcnQodSl9fSgpLG5lLnByb3RvdHlwZS5pbnRlcnNlY3RzVHJpYW5nbGU9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBuZSx0PW5ldyBBcnJheSgzKSxlPW5ldyBBcnJheSgzKSxuPW5ldyBJZSxzPW5ldyBJZSxyPW5ldyBULG89bmV3IFQsYT1uZXcgVCxjPW5ldyBULGw9bmV3IFQsaD1uZXcgUXQsdT1uZXcgUXQsZj1uZXcgUXQsZD1uZXcgVDtmdW5jdGlvbiBwKHksbSxnKXtjb25zdCBiPXkucG9pbnRzO2xldCB3PTAseD0tMTtmb3IobGV0IE09MDtNPDM7TSsrKXtjb25zdHtzdGFydDpBLGVuZDpTfT1oO0EuY29weShiW01dKSxTLmNvcHkoYlsoTSsxKSUzXSksaC5kZWx0YShvKTtjb25zdCBfPVdvKG0uZGlzdGFuY2VUb1BvaW50KEEpKTtpZihXbyhtLm5vcm1hbC5kb3QobykpJiZfKXtnLmNvcHkoaCksdz0yO2JyZWFrfWNvbnN0IEU9bS5pbnRlcnNlY3RMaW5lKGgsZCk7aWYoIUUmJl8mJmQuY29weShBKSwoRXx8XykmJiFXbyhkLmRpc3RhbmNlVG8oUykpKXtpZih3PD0xKSh3PT09MT9nLnN0YXJ0OmcuZW5kKS5jb3B5KGQpLF8mJih4PXcpO2Vsc2UgaWYodz49Mil7KHg9PT0xP2cuc3RhcnQ6Zy5lbmQpLmNvcHkoZCksdz0yO2JyZWFrfWlmKHcrKyx3PT09MiYmeD09PS0xKWJyZWFrfX1yZXR1cm4gd31yZXR1cm4gZnVuY3Rpb24obSxnPW51bGwsYj0hMSl7dGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxtLmlzRXh0ZW5kZWRUcmlhbmdsZT9tLm5lZWRzVXBkYXRlJiZtLnVwZGF0ZSgpOihpLmNvcHkobSksaS51cGRhdGUoKSxtPWkpO2NvbnN0IHc9dGhpcy5wbGFuZSx4PW0ucGxhbmU7aWYoTWF0aC5hYnMody5ub3JtYWwuZG90KHgubm9ybWFsKSk+MS0xZS0xMCl7Y29uc3QgTT10aGlzLnNhdEJvdW5kcyxBPXRoaXMuc2F0QXhlcztlWzBdPW0uYSxlWzFdPW0uYixlWzJdPW0uYztmb3IobGV0IEU9MDtFPDQ7RSsrKXtjb25zdCB6PU1bRV0sdj1BW0VdO2lmKG4uc2V0RnJvbVBvaW50cyh2LGUpLHouaXNTZXBhcmF0ZWQobikpcmV0dXJuITF9Y29uc3QgUz1tLnNhdEJvdW5kcyxfPW0uc2F0QXhlczt0WzBdPXRoaXMuYSx0WzFdPXRoaXMuYix0WzJdPXRoaXMuYztmb3IobGV0IEU9MDtFPDQ7RSsrKXtjb25zdCB6PVNbRV0sdj1fW0VdO2lmKG4uc2V0RnJvbVBvaW50cyh2LHQpLHouaXNTZXBhcmF0ZWQobikpcmV0dXJuITF9Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1BW0VdO2ZvcihsZXQgdj0wO3Y8NDt2Kyspe2NvbnN0IEM9X1t2XTtpZihyLmNyb3NzVmVjdG9ycyh6LEMpLG4uc2V0RnJvbVBvaW50cyhyLHQpLHMuc2V0RnJvbVBvaW50cyhyLGUpLG4uaXNTZXBhcmF0ZWQocykpcmV0dXJuITF9fXJldHVybiBnJiYoYnx8Y29uc29sZS53YXJuKCJFeHRlbmRlZFRyaWFuZ2xlLmludGVyc2VjdHNUcmlhbmdsZTogVHJpYW5nbGVzIGFyZSBjb3BsYW5hciB3aGljaCBkb2VzIG5vdCBzdXBwb3J0IGFuIG91dHB1dCBlZGdlLiBTZXR0aW5nIGVkZ2UgdG8gMCwgMCwgMC4iKSxnLnN0YXJ0LnNldCgwLDAsMCksZy5lbmQuc2V0KDAsMCwwKSksITB9ZWxzZXtjb25zdCBNPXAodGhpcyx4LHUpO2lmKE09PT0xJiZtLmNvbnRhaW5zUG9pbnQodS5lbmQpKXJldHVybiBnJiYoZy5zdGFydC5jb3B5KHUuZW5kKSxnLmVuZC5jb3B5KHUuZW5kKSksITA7aWYoTSE9PTIpcmV0dXJuITE7Y29uc3QgQT1wKG0sdyxmKTtpZihBPT09MSYmdGhpcy5jb250YWluc1BvaW50KGYuZW5kKSlyZXR1cm4gZyYmKGcuc3RhcnQuY29weShmLmVuZCksZy5lbmQuY29weShmLmVuZCkpLCEwO2lmKEEhPT0yKXJldHVybiExO2lmKHUuZGVsdGEoYSksZi5kZWx0YShjKSxhLmRvdChjKTwwKXtsZXQgUD1mLnN0YXJ0O2Yuc3RhcnQ9Zi5lbmQsZi5lbmQ9UH1jb25zdCBTPXUuc3RhcnQuZG90KGEpLF89dS5lbmQuZG90KGEpLEU9Zi5zdGFydC5kb3QoYSksej1mLmVuZC5kb3QoYSksdj1fPEUsQz1TPHo7cmV0dXJuIFMhPT16JiZFIT09XyYmdj09PUM/ITE6KGcmJihsLnN1YlZlY3RvcnModS5zdGFydCxmLnN0YXJ0KSxsLmRvdChhKT4wP2cuc3RhcnQuY29weSh1LnN0YXJ0KTpnLnN0YXJ0LmNvcHkoZi5zdGFydCksbC5zdWJWZWN0b3JzKHUuZW5kLGYuZW5kKSxsLmRvdChhKTwwP2cuZW5kLmNvcHkodS5lbmQpOmcuZW5kLmNvcHkoZi5lbmQpKSwhMCl9fX0oKSxuZS5wcm90b3R5cGUuZGlzdGFuY2VUb1BvaW50PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChlLGkpLGUuZGlzdGFuY2VUbyhpKX19KCksbmUucHJvdG90eXBlLmRpc3RhbmNlVG9UcmlhbmdsZT1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQsdD1uZXcgVCxlPVsiYSIsImIiLCJjIl0sbj1uZXcgUXQscz1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKG8sYT1udWxsLGM9bnVsbCl7Y29uc3QgbD1hfHxjP246bnVsbDtpZih0aGlzLmludGVyc2VjdHNUcmlhbmdsZShvLGwpKXJldHVybihhfHxjKSYmKGEmJmwuZ2V0Q2VudGVyKGEpLGMmJmwuZ2V0Q2VudGVyKGMpKSwwO2xldCBoPTEvMDtmb3IobGV0IHU9MDt1PDM7dSsrKXtsZXQgZjtjb25zdCBkPWVbdV0scD1vW2RdO3RoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChwLGkpLGY9cC5kaXN0YW5jZVRvU3F1YXJlZChpKSxmPGgmJihoPWYsYSYmYS5jb3B5KGkpLGMmJmMuY29weShwKSk7Y29uc3QgeT10aGlzW2RdO28uY2xvc2VzdFBvaW50VG9Qb2ludCh5LGkpLGY9eS5kaXN0YW5jZVRvU3F1YXJlZChpKSxmPGgmJihoPWYsYSYmYS5jb3B5KHkpLGMmJmMuY29weShpKSl9Zm9yKGxldCB1PTA7dTwzO3UrKyl7Y29uc3QgZj1lW3VdLGQ9ZVsodSsxKSUzXTtuLnNldCh0aGlzW2ZdLHRoaXNbZF0pO2ZvcihsZXQgcD0wO3A8MztwKyspe2NvbnN0IHk9ZVtwXSxtPWVbKHArMSklM107cy5zZXQob1t5XSxvW21dKSxIbyhuLHMsaSx0KTtjb25zdCBnPWkuZGlzdGFuY2VUb1NxdWFyZWQodCk7ZzxoJiYoaD1nLGEmJmEuY29weShpKSxjJiZjLmNvcHkodCkpfX1yZXR1cm4gTWF0aC5zcXJ0KGgpfX0oKTtjbGFzcyB6dHtjb25zdHJ1Y3Rvcih0LGUsbil7dGhpcy5pc09yaWVudGVkQm94PSEwLHRoaXMubWluPW5ldyBULHRoaXMubWF4PW5ldyBULHRoaXMubWF0cml4PW5ldyBzdCx0aGlzLmludk1hdHJpeD1uZXcgc3QsdGhpcy5wb2ludHM9bmV3IEFycmF5KDgpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEF4ZXM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEJvdW5kcz1uZXcgQXJyYXkoMykuZmlsbCgpLm1hcCgoKT0+bmV3IEllKSx0aGlzLmFsaWduZWRTYXRCb3VuZHM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBJZSksdGhpcy5uZWVkc1VwZGF0ZT0hMSx0JiZ0aGlzLm1pbi5jb3B5KHQpLGUmJnRoaXMubWF4LmNvcHkoZSksbiYmdGhpcy5tYXRyaXguY29weShuKX1zZXQodCxlLG4pe3RoaXMubWluLmNvcHkodCksdGhpcy5tYXguY29weShlKSx0aGlzLm1hdHJpeC5jb3B5KG4pLHRoaXMubmVlZHNVcGRhdGU9ITB9Y29weSh0KXt0aGlzLm1pbi5jb3B5KHQubWluKSx0aGlzLm1heC5jb3B5KHQubWF4KSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLm5lZWRzVXBkYXRlPSEwfX16dC5wcm90b3R5cGUudXBkYXRlPWZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKCl7Y29uc3QgdD10aGlzLm1hdHJpeCxlPXRoaXMubWluLG49dGhpcy5tYXgscz10aGlzLnBvaW50cztmb3IobGV0IGw9MDtsPD0xO2wrKylmb3IobGV0IGg9MDtoPD0xO2grKylmb3IobGV0IHU9MDt1PD0xO3UrKyl7Y29uc3QgZj0xKmx8MipofDQqdSxkPXNbZl07ZC54PWw/bi54OmUueCxkLnk9aD9uLnk6ZS55LGQuej11P24uejplLnosZC5hcHBseU1hdHJpeDQodCl9Y29uc3Qgcj10aGlzLnNhdEJvdW5kcyxvPXRoaXMuc2F0QXhlcyxhPXNbMF07Zm9yKGxldCBsPTA7bDwzO2wrKyl7Y29uc3QgaD1vW2xdLHU9cltsXSxmPTE8PGwsZD1zW2ZdO2guc3ViVmVjdG9ycyhhLGQpLHUuc2V0RnJvbVBvaW50cyhoLHMpfWNvbnN0IGM9dGhpcy5hbGlnbmVkU2F0Qm91bmRzO2NbMF0uc2V0RnJvbVBvaW50c0ZpZWxkKHMsIngiKSxjWzFdLnNldEZyb21Qb2ludHNGaWVsZChzLCJ5IiksY1syXS5zZXRGcm9tUG9pbnRzRmllbGQocywieiIpLHRoaXMuaW52TWF0cml4LmNvcHkodGhpcy5tYXRyaXgpLmludmVydCgpLHRoaXMubmVlZHNVcGRhdGU9ITF9fSgpLHp0LnByb3RvdHlwZS5pbnRlcnNlY3RzQm94PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgSWU7cmV0dXJuIGZ1bmN0aW9uKGUpe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCk7Y29uc3Qgbj1lLm1pbixzPWUubWF4LHI9dGhpcy5zYXRCb3VuZHMsbz10aGlzLnNhdEF4ZXMsYT10aGlzLmFsaWduZWRTYXRCb3VuZHM7aWYoaS5taW49bi54LGkubWF4PXMueCxhWzBdLmlzU2VwYXJhdGVkKGkpfHwoaS5taW49bi55LGkubWF4PXMueSxhWzFdLmlzU2VwYXJhdGVkKGkpKXx8KGkubWluPW4ueixpLm1heD1zLnosYVsyXS5pc1NlcGFyYXRlZChpKSkpcmV0dXJuITE7Zm9yKGxldCBjPTA7YzwzO2MrKyl7Y29uc3QgbD1vW2NdLGg9cltjXTtpZihpLnNldEZyb21Cb3gobCxlKSxoLmlzU2VwYXJhdGVkKGkpKXJldHVybiExfXJldHVybiEwfX0oKSx6dC5wcm90b3R5cGUuaW50ZXJzZWN0c1RyaWFuZ2xlPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgbmUsdD1uZXcgQXJyYXkoMyksZT1uZXcgSWUsbj1uZXcgSWUscz1uZXcgVDtyZXR1cm4gZnVuY3Rpb24obyl7dGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxvLmlzRXh0ZW5kZWRUcmlhbmdsZT9vLm5lZWRzVXBkYXRlJiZvLnVwZGF0ZSgpOihpLmNvcHkobyksaS51cGRhdGUoKSxvPWkpO2NvbnN0IGE9dGhpcy5zYXRCb3VuZHMsYz10aGlzLnNhdEF4ZXM7dFswXT1vLmEsdFsxXT1vLmIsdFsyXT1vLmM7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1hW2ZdLHA9Y1tmXTtpZihlLnNldEZyb21Qb2ludHMocCx0KSxkLmlzU2VwYXJhdGVkKGUpKXJldHVybiExfWNvbnN0IGw9by5zYXRCb3VuZHMsaD1vLnNhdEF4ZXMsdT10aGlzLnBvaW50cztmb3IobGV0IGY9MDtmPDM7ZisrKXtjb25zdCBkPWxbZl0scD1oW2ZdO2lmKGUuc2V0RnJvbVBvaW50cyhwLHUpLGQuaXNTZXBhcmF0ZWQoZSkpcmV0dXJuITF9Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1jW2ZdO2ZvcihsZXQgcD0wO3A8NDtwKyspe2NvbnN0IHk9aFtwXTtpZihzLmNyb3NzVmVjdG9ycyhkLHkpLGUuc2V0RnJvbVBvaW50cyhzLHQpLG4uc2V0RnJvbVBvaW50cyhzLHUpLGUuaXNTZXBhcmF0ZWQobikpcmV0dXJuITF9fXJldHVybiEwfX0oKSx6dC5wcm90b3R5cGUuY2xvc2VzdFBvaW50VG9Qb2ludD1mdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpLGUuY29weSh0KS5hcHBseU1hdHJpeDQodGhpcy5pbnZNYXRyaXgpLmNsYW1wKHRoaXMubWluLHRoaXMubWF4KS5hcHBseU1hdHJpeDQodGhpcy5tYXRyaXgpLGV9fSgpLHp0LnByb3RvdHlwZS5kaXN0YW5jZVRvUG9pbnQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBUO3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50KGUsaSksZS5kaXN0YW5jZVRvKGkpfX0oKSx6dC5wcm90b3R5cGUuZGlzdGFuY2VUb0JveD1mdW5jdGlvbigpe2NvbnN0IGk9WyJ4IiwieSIsInoiXSx0PW5ldyBBcnJheSgxMikuZmlsbCgpLm1hcCgoKT0+bmV3IFF0KSxlPW5ldyBBcnJheSgxMikuZmlsbCgpLm1hcCgoKT0+bmV3IFF0KSxuPW5ldyBULHM9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKG8sYT0wLGM9bnVsbCxsPW51bGwpe2lmKHRoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksdGhpcy5pbnRlcnNlY3RzQm94KG8pKXJldHVybihjfHxsKSYmKG8uZ2V0Q2VudGVyKHMpLHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChzLG4pLG8uY2xvc2VzdFBvaW50VG9Qb2ludChuLHMpLGMmJmMuY29weShuKSxsJiZsLmNvcHkocykpLDA7Y29uc3QgaD1hKmEsdT1vLm1pbixmPW8ubWF4LGQ9dGhpcy5wb2ludHM7bGV0IHA9MS8wO2ZvcihsZXQgbT0wO208ODttKyspe2NvbnN0IGc9ZFttXTtzLmNvcHkoZykuY2xhbXAodSxmKTtjb25zdCBiPWcuZGlzdGFuY2VUb1NxdWFyZWQocyk7aWYoYjxwJiYocD1iLGMmJmMuY29weShnKSxsJiZsLmNvcHkocyksYjxoKSlyZXR1cm4gTWF0aC5zcXJ0KGIpfWxldCB5PTA7Zm9yKGxldCBtPTA7bTwzO20rKylmb3IobGV0IGc9MDtnPD0xO2crKylmb3IobGV0IGI9MDtiPD0xO2IrKyl7Y29uc3Qgdz0obSsxKSUzLHg9KG0rMiklMyxNPWc8PHd8Yjw8eCxBPTE8PG18Zzw8d3xiPDx4LFM9ZFtNXSxfPWRbQV07dFt5XS5zZXQoUyxfKTtjb25zdCB6PWlbbV0sdj1pW3ddLEM9aVt4XSxQPWVbeV0sRj1QLnN0YXJ0LEI9UC5lbmQ7Rlt6XT11W3pdLEZbdl09Zz91W3ZdOmZbdl0sRltDXT1iP3VbQ106Zlt2XSxCW3pdPWZbel0sQlt2XT1nP3Vbdl06Zlt2XSxCW0NdPWI/dVtDXTpmW3ZdLHkrK31mb3IobGV0IG09MDttPD0xO20rKylmb3IobGV0IGc9MDtnPD0xO2crKylmb3IobGV0IGI9MDtiPD0xO2IrKyl7cy54PW0/Zi54OnUueCxzLnk9Zz9mLnk6dS55LHMuej1iP2Yuejp1LnosdGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50KHMsbik7Y29uc3Qgdz1zLmRpc3RhbmNlVG9TcXVhcmVkKG4pO2lmKHc8cCYmKHA9dyxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpLHc8aCkpcmV0dXJuIE1hdGguc3FydCh3KX1mb3IobGV0IG09MDttPDEyO20rKyl7Y29uc3QgZz10W21dO2ZvcihsZXQgYj0wO2I8MTI7YisrKXtjb25zdCB3PWVbYl07SG8oZyx3LG4scyk7Y29uc3QgeD1uLmRpc3RhbmNlVG9TcXVhcmVkKHMpO2lmKHg8cCYmKHA9eCxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpLHg8aCkpcmV0dXJuIE1hdGguc3FydCh4KX19cmV0dXJuIE1hdGguc3FydChwKX19KCk7Y2xhc3MgR297Y29uc3RydWN0b3IodCl7dGhpcy5fZ2V0TmV3UHJpbWl0aXZlPXQsdGhpcy5fcHJpbWl0aXZlcz1bXX1nZXRQcmltaXRpdmUoKXtjb25zdCB0PXRoaXMuX3ByaW1pdGl2ZXM7cmV0dXJuIHQubGVuZ3RoPT09MD90aGlzLl9nZXROZXdQcmltaXRpdmUoKTp0LnBvcCgpfXJlbGVhc2VQcmltaXRpdmUodCl7dGhpcy5fcHJpbWl0aXZlcy5wdXNoKHQpfX1jbGFzcyBBZCBleHRlbmRzIEdve2NvbnN0cnVjdG9yKCl7c3VwZXIoKCk9Pm5ldyBuZSl9fWNvbnN0IGllPW5ldyBBZDtjbGFzcyBTZHtjb25zdHJ1Y3Rvcigpe3RoaXMuZmxvYXQzMkFycmF5PW51bGwsdGhpcy51aW50MTZBcnJheT1udWxsLHRoaXMudWludDMyQXJyYXk9bnVsbDtjb25zdCB0PVtdO2xldCBlPW51bGw7dGhpcy5zZXRCdWZmZXI9bj0+e2UmJnQucHVzaChlKSxlPW4sdGhpcy5mbG9hdDMyQXJyYXk9bmV3IEZsb2F0MzJBcnJheShuKSx0aGlzLnVpbnQxNkFycmF5PW5ldyBVaW50MTZBcnJheShuKSx0aGlzLnVpbnQzMkFycmF5PW5ldyBVaW50MzJBcnJheShuKX0sdGhpcy5jbGVhckJ1ZmZlcj0oKT0+e2U9bnVsbCx0aGlzLmZsb2F0MzJBcnJheT1udWxsLHRoaXMudWludDE2QXJyYXk9bnVsbCx0aGlzLnVpbnQzMkFycmF5PW51bGwsdC5sZW5ndGghPT0wJiZ0aGlzLnNldEJ1ZmZlcih0LnBvcCgpKX19fWNvbnN0IG50PW5ldyBTZDtsZXQgdG4sWG47Y29uc3QgSm49W10sSXM9bmV3IEdvKCgpPT5uZXcgZ3QpO2Z1bmN0aW9uIF9kKGksdCxlLG4scyxyKXt0bj1Jcy5nZXRQcmltaXRpdmUoKSxYbj1Jcy5nZXRQcmltaXRpdmUoKSxKbi5wdXNoKHRuLFhuKSxudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IG89Wm8oMCxpLmdlb21ldHJ5LGUsbixzLHIpO250LmNsZWFyQnVmZmVyKCksSXMucmVsZWFzZVByaW1pdGl2ZSh0biksSXMucmVsZWFzZVByaW1pdGl2ZShYbiksSm4ucG9wKCksSm4ucG9wKCk7Y29uc3QgYT1Kbi5sZW5ndGg7cmV0dXJuIGE+MCYmKFhuPUpuW2EtMV0sdG49Sm5bYS0yXSksb31mdW5jdGlvbiBabyhpLHQsZSxuLHM9bnVsbCxyPTAsbz0wKXtjb25zdHtmbG9hdDMyQXJyYXk6YSx1aW50MTZBcnJheTpjLHVpbnQzMkFycmF5Omx9PW50O2xldCBoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVV0KGksbCksZD1LdChoLGMpO3JldHVybiBsdChpLGEsdG4pLG4oZixkLCExLG8scitpLHRuKX1lbHNle2xldCB6PWZ1bmN0aW9uKEMpe2NvbnN0e3VpbnQxNkFycmF5OlAsdWludDMyQXJyYXk6Rn09bnQ7bGV0IEI9QyoyO2Zvcig7IWt0KEIsUCk7KUM9dGUoQyksQj1DKjI7cmV0dXJuIFV0KEMsRil9LHY9ZnVuY3Rpb24oQyl7Y29uc3R7dWludDE2QXJyYXk6UCx1aW50MzJBcnJheTpGfT1udDtsZXQgQj1DKjI7Zm9yKDsha3QoQixQKTspQz1lZShDLEYpLEI9QyoyO3JldHVybiBVdChDLEYpK0t0KEIsUCl9O2NvbnN0IGY9dGUoaSksZD1lZShpLGwpO2xldCBwPWYseT1kLG0sZyxiLHc7aWYocyYmKGI9dG4sdz1YbixsdChwLGEsYiksbHQoeSxhLHcpLG09cyhiKSxnPXModyksZzxtKSl7cD1kLHk9Zjtjb25zdCBDPW07bT1nLGc9QyxiPXd9Ynx8KGI9dG4sbHQocCxhLGIpKTtjb25zdCB4PWt0KHAqMixjKSxNPWUoYix4LG0sbysxLHIrcCk7bGV0IEE7aWYoTT09PXNsKXtjb25zdCBDPXoocCksRj12KHApLUM7QT1uKEMsRiwhMCxvKzEscitwLGIpfWVsc2UgQT1NJiZabyhwLHQsZSxuLHMscixvKzEpO2lmKEEpcmV0dXJuITA7dz1YbixsdCh5LGEsdyk7Y29uc3QgUz1rdCh5KjIsYyksXz1lKHcsUyxnLG8rMSxyK3kpO2xldCBFO2lmKF89PT1zbCl7Y29uc3QgQz16KHkpLEY9dih5KS1DO0U9bihDLEYsITAsbysxLHIreSx3KX1lbHNlIEU9XyYmWm8oeSx0LGUsbixzLHIsbysxKTtyZXR1cm4hIUV9fWNvbnN0IEZpPW5ldyBULFhvPW5ldyBUO2Z1bmN0aW9uIHZkKGksdCxlPXt9LG49MCxzPTEvMCl7Y29uc3Qgcj1uKm4sbz1zKnM7bGV0IGE9MS8wLGM9bnVsbDtpZihpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpoPT4oRmkuY29weSh0KS5jbGFtcChoLm1pbixoLm1heCksRmkuZGlzdGFuY2VUb1NxdWFyZWQodCkpLGludGVyc2VjdHNCb3VuZHM6KGgsdSxmKT0+ZjxhJiZmPG8saW50ZXJzZWN0c1RyaWFuZ2xlOihoLHUpPT57aC5jbG9zZXN0UG9pbnRUb1BvaW50KHQsRmkpO2NvbnN0IGY9dC5kaXN0YW5jZVRvU3F1YXJlZChGaSk7cmV0dXJuIGY8YSYmKFhvLmNvcHkoRmkpLGE9ZixjPXUpLGY8cn19KSxhPT09MS8wKXJldHVybiBudWxsO2NvbnN0IGw9TWF0aC5zcXJ0KGEpO3JldHVybiBlLnBvaW50P2UucG9pbnQuY29weShYbyk6ZS5wb2ludD1Yby5jbG9uZSgpLGUuZGlzdGFuY2U9bCxlLmZhY2VJbmRleD1jLGV9Y29uc3QgemQ9cGFyc2VJbnQoSik+PTE2OSx5bj1uZXcgVCxtbj1uZXcgVCxnbj1uZXcgVCxrcz1uZXcgUixOcz1uZXcgUixScz1uZXcgUixwbD1uZXcgVCx5bD1uZXcgVCxtbD1uZXcgVCxJaT1uZXcgVDtmdW5jdGlvbiBUZChpLHQsZSxuLHMscixvLGEpe2xldCBjO2lmKHI9PT0xP2M9aS5pbnRlcnNlY3RUcmlhbmdsZShuLGUsdCwhMCxzKTpjPWkuaW50ZXJzZWN0VHJpYW5nbGUodCxlLG4sciE9PTIscyksYz09PW51bGwpcmV0dXJuIG51bGw7Y29uc3QgbD1pLm9yaWdpbi5kaXN0YW5jZVRvKHMpO3JldHVybiBsPG98fGw+YT9udWxsOntkaXN0YW5jZTpsLHBvaW50OnMuY2xvbmUoKX19ZnVuY3Rpb24gRWQoaSx0LGUsbixzLHIsbyxhLGMsbCxoKXt5bi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsciksbW4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG8pLGduLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxhKTtjb25zdCB1PVRkKGkseW4sbW4sZ24sSWksYyxsLGgpO2lmKHUpe2NvbnN0IGY9bmV3IFQ7ZXQuZ2V0QmFyeWNvb3JkKElpLHluLG1uLGduLGYpLG4mJihrcy5mcm9tQnVmZmVyQXR0cmlidXRlKG4sciksTnMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLG8pLFJzLmZyb21CdWZmZXJBdHRyaWJ1dGUobixhKSx1LnV2PWV0LmdldEludGVycG9sYXRpb24oSWkseW4sbW4sZ24sa3MsTnMsUnMsbmV3IFIpKSxzJiYoa3MuZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLHIpLE5zLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxvKSxScy5mcm9tQnVmZmVyQXR0cmlidXRlKHMsYSksdS51djE9ZXQuZ2V0SW50ZXJwb2xhdGlvbihJaSx5bixtbixnbixrcyxOcyxScyxuZXcgUikpLGUmJihwbC5mcm9tQnVmZmVyQXR0cmlidXRlKGUscikseWwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLG8pLG1sLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxhKSx1Lm5vcm1hbD1ldC5nZXRJbnRlcnBvbGF0aW9uKElpLHluLG1uLGduLHBsLHlsLG1sLG5ldyBUKSx1Lm5vcm1hbC5kb3QoaS5kaXJlY3Rpb24pPjAmJnUubm9ybWFsLm11bHRpcGx5U2NhbGFyKC0xKSk7Y29uc3QgZD17YTpyLGI6byxjOmEsbm9ybWFsOm5ldyBULG1hdGVyaWFsSW5kZXg6MH07ZXQuZ2V0Tm9ybWFsKHluLG1uLGduLGQubm9ybWFsKSx1LmZhY2U9ZCx1LmZhY2VJbmRleD1yLHpkJiYodS5iYXJ5Y29vcmQ9Zil9cmV0dXJuIHV9ZnVuY3Rpb24gTHMoaSx0LGUsbixzLHIsbyl7Y29uc3QgYT1uKjM7bGV0IGM9YSswLGw9YSsxLGg9YSsyO2NvbnN0IHU9aS5pbmRleDtpLmluZGV4JiYoYz11LmdldFgoYyksbD11LmdldFgobCksaD11LmdldFgoaCkpO2NvbnN0e3Bvc2l0aW9uOmYsbm9ybWFsOmQsdXY6cCx1djE6eX09aS5hdHRyaWJ1dGVzLG09RWQoZSxmLGQscCx5LGMsbCxoLHQscixvKTtyZXR1cm4gbT8obS5mYWNlSW5kZXg9bixzJiZzLnB1c2gobSksbSk6bnVsbH1mdW5jdGlvbiB5dChpLHQsZSxuKXtjb25zdCBzPWkuYSxyPWkuYixvPWkuYztsZXQgYT10LGM9dCsxLGw9dCsyO2UmJihhPWUuZ2V0WChhKSxjPWUuZ2V0WChjKSxsPWUuZ2V0WChsKSkscy54PW4uZ2V0WChhKSxzLnk9bi5nZXRZKGEpLHMuej1uLmdldFooYSksci54PW4uZ2V0WChjKSxyLnk9bi5nZXRZKGMpLHIuej1uLmdldFooYyksby54PW4uZ2V0WChsKSxvLnk9bi5nZXRZKGwpLG8uej1uLmdldFoobCl9ZnVuY3Rpb24gUGQoaSx0LGUsbixzLHIsbyxhKXtjb25zdHtnZW9tZXRyeTpjLF9pbmRpcmVjdEJ1ZmZlcjpsfT1pO2ZvcihsZXQgaD1uLHU9bitzO2g8dTtoKyspTHMoYyx0LGUsaCxyLG8sYSl9ZnVuY3Rpb24gQ2QoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YSxfaW5kaXJlY3RCdWZmZXI6Y309aTtsZXQgbD0xLzAsaD1udWxsO2ZvcihsZXQgdT1uLGY9bitzO3U8Zjt1Kyspe2xldCBkO2Q9THMoYSx0LGUsdSxudWxsLHIsbyksZCYmZC5kaXN0YW5jZTxsJiYoaD1kLGw9ZC5kaXN0YW5jZSl9cmV0dXJuIGh9ZnVuY3Rpb24gQmQoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YX09ZSx7aW5kZXg6Y309YSxsPWEuYXR0cmlidXRlcy5wb3NpdGlvbjtmb3IobGV0IGg9aSx1PXQraTtoPHU7aCsrKXtsZXQgZjtpZihmPWgseXQobyxmKjMsYyxsKSxvLm5lZWRzVXBkYXRlPSEwLG4obyxmLHMscikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gRmQoaSx0PW51bGwpe3QmJkFycmF5LmlzQXJyYXkodCkmJih0PW5ldyBTZXQodCkpO2NvbnN0IGU9aS5nZW9tZXRyeSxuPWUuaW5kZXg/ZS5pbmRleC5hcnJheTpudWxsLHM9ZS5hdHRyaWJ1dGVzLnBvc2l0aW9uO2xldCByLG8sYSxjLGw9MDtjb25zdCBoPWkuX3Jvb3RzO2ZvcihsZXQgZj0wLGQ9aC5sZW5ndGg7ZjxkO2YrKylyPWhbZl0sbz1uZXcgVWludDMyQXJyYXkociksYT1uZXcgVWludDE2QXJyYXkociksYz1uZXcgRmxvYXQzMkFycmF5KHIpLHUoMCxsKSxsKz1yLmJ5dGVMZW5ndGg7ZnVuY3Rpb24gdShmLGQscD0hMSl7Y29uc3QgeT1mKjI7aWYoYVt5KzE1XT09PVBzKXtjb25zdCBnPW9bZis2XSxiPWFbeSsxNF07bGV0IHc9MS8wLHg9MS8wLE09MS8wLEE9LTEvMCxTPS0xLzAsXz0tMS8wO2ZvcihsZXQgRT0zKmcsej0zKihnK2IpO0U8ejtFKyspe2xldCB2PW5bRV07Y29uc3QgQz1zLmdldFgodiksUD1zLmdldFkodiksRj1zLmdldFoodik7Qzx3JiYodz1DKSxDPkEmJihBPUMpLFA8eCYmKHg9UCksUD5TJiYoUz1QKSxGPE0mJihNPUYpLEY+XyYmKF89Ril9cmV0dXJuIGNbZiswXSE9PXd8fGNbZisxXSE9PXh8fGNbZisyXSE9PU18fGNbZiszXSE9PUF8fGNbZis0XSE9PVN8fGNbZis1XSE9PV8/KGNbZiswXT13LGNbZisxXT14LGNbZisyXT1NLGNbZiszXT1BLGNbZis0XT1TLGNbZis1XT1fLCEwKTohMX1lbHNle2NvbnN0IGc9Zis4LGI9b1tmKzZdLHc9ZytkLHg9YitkO2xldCBNPXAsQT0hMSxTPSExO3Q/TXx8KEE9dC5oYXModyksUz10Lmhhcyh4KSxNPSFBJiYhUyk6KEE9ITAsUz0hMCk7Y29uc3QgXz1NfHxBLEU9TXx8UztsZXQgej0hMTtfJiYoej11KGcsZCxNKSk7bGV0IHY9ITE7RSYmKHY9dShiLGQsTSkpO2NvbnN0IEM9enx8djtpZihDKWZvcihsZXQgUD0wO1A8MztQKyspe2NvbnN0IEY9ZytQLEI9YitQLEk9Y1tGXSxrPWNbRiszXSxEPWNbQl0sVT1jW0IrM107Y1tmK1BdPUk8RD9JOkQsY1tmK1ArM109az5VP2s6VX1yZXR1cm4gQ319fWZ1bmN0aW9uIGVuKGksdCxlLG4scyl7bGV0IHIsbyxhLGMsbCxoO2NvbnN0IHU9MS9lLmRpcmVjdGlvbi54LGY9MS9lLmRpcmVjdGlvbi55LGQ9MS9lLmRpcmVjdGlvbi56LHA9ZS5vcmlnaW4ueCx5PWUub3JpZ2luLnksbT1lLm9yaWdpbi56O2xldCBnPXRbaV0sYj10W2krM10sdz10W2krMV0seD10W2krMysxXSxNPXRbaSsyXSxBPXRbaSszKzJdO3JldHVybiB1Pj0wPyhyPShnLXApKnUsbz0oYi1wKSp1KToocj0oYi1wKSp1LG89KGctcCkqdSksZj49MD8oYT0ody15KSpmLGM9KHgteSkqZik6KGE9KHgteSkqZixjPSh3LXkpKmYpLHI+Y3x8YT5vfHwoKGE+cnx8aXNOYU4ocikpJiYocj1hKSwoYzxvfHxpc05hTihvKSkmJihvPWMpLGQ+PTA/KGw9KE0tbSkqZCxoPShBLW0pKmQpOihsPShBLW0pKmQsaD0oTS1tKSpkKSxyPmh8fGw+byk/ITE6KChsPnJ8fHIhPT1yKSYmKHI9bCksKGg8b3x8byE9PW8pJiYobz1oKSxyPD1zJiZvPj1uKX1mdW5jdGlvbiBJZChpLHQsZSxuLHMscixvLGEpe2NvbnN0e2dlb21ldHJ5OmMsX2luZGlyZWN0QnVmZmVyOmx9PWk7Zm9yKGxldCBoPW4sdT1uK3M7aDx1O2grKyl7bGV0IGY9bD9sW2hdOmg7THMoYyx0LGUsZixyLG8sYSl9fWZ1bmN0aW9uIGtkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmEsX2luZGlyZWN0QnVmZmVyOmN9PWk7bGV0IGw9MS8wLGg9bnVsbDtmb3IobGV0IHU9bixmPW4rczt1PGY7dSsrKXtsZXQgZDtkPUxzKGEsdCxlLGM/Y1t1XTp1LG51bGwscixvKSxkJiZkLmRpc3RhbmNlPGwmJihoPWQsbD1kLmRpc3RhbmNlKX1yZXR1cm4gaH1mdW5jdGlvbiBOZChpLHQsZSxuLHMscixvKXtjb25zdHtnZW9tZXRyeTphfT1lLHtpbmRleDpjfT1hLGw9YS5hdHRyaWJ1dGVzLnBvc2l0aW9uO2ZvcihsZXQgaD1pLHU9dCtpO2g8dTtoKyspe2xldCBmO2lmKGY9ZS5yZXNvbHZlVHJpYW5nbGVJbmRleChoKSx5dChvLGYqMyxjLGwpLG8ubmVlZHNVcGRhdGU9ITAsbihvLGYscyxyKSlyZXR1cm4hMH1yZXR1cm4hMX1mdW5jdGlvbiBSZChpLHQsZSxuLHMscixvKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pLEpvKDAsaSxlLG4scyxyLG8pLG50LmNsZWFyQnVmZmVyKCl9ZnVuY3Rpb24gSm8oaSx0LGUsbixzLHIsbyl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udCxoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVV0KGksbCksZD1LdChoLGMpO1BkKHQsZSxuLGYsZCxzLHIsbyl9ZWxzZXtjb25zdCBmPXRlKGkpO2VuKGYsYSxuLHIsbykmJkpvKGYsdCxlLG4scyxyLG8pO2NvbnN0IGQ9ZWUoaSxsKTtlbihkLGEsbixyLG8pJiZKbyhkLHQsZSxuLHMscixvKX19Y29uc3QgTGQ9WyJ4IiwieSIsInoiXTtmdW5jdGlvbiBPZChpLHQsZSxuLHMscil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPVlvKDAsaSxlLG4scyxyKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxvfWZ1bmN0aW9uIFlvKGksdCxlLG4scyxyKXtjb25zdHtmbG9hdDMyQXJyYXk6byx1aW50MTZBcnJheTphLHVpbnQzMkFycmF5OmN9PW50O2xldCBsPWkqMjtpZihrdChsLGEpKXtjb25zdCB1PVV0KGksYyksZj1LdChsLGEpO3JldHVybiBDZCh0LGUsbix1LGYscyxyKX1lbHNle2NvbnN0IHU9dWwoaSxjKSxmPUxkW3VdLHA9bi5kaXJlY3Rpb25bZl0+PTA7bGV0IHksbTtwPyh5PXRlKGkpLG09ZWUoaSxjKSk6KHk9ZWUoaSxjKSxtPXRlKGkpKTtjb25zdCBiPWVuKHksbyxuLHMscik/WW8oeSx0LGUsbixzLHIpOm51bGw7aWYoYil7Y29uc3QgTT1iLnBvaW50W2ZdO2lmKHA/TTw9b1ttK3VdOk0+PW9bbSt1KzNdKXJldHVybiBifWNvbnN0IHg9ZW4obSxvLG4scyxyKT9ZbyhtLHQsZSxuLHMscik6bnVsbDtyZXR1cm4gYiYmeD9iLmRpc3RhbmNlPD14LmRpc3RhbmNlP2I6eDpifHx4fHxudWxsfX1jb25zdCBPcz1uZXcgZ3QsWW49bmV3IG5lLGpuPW5ldyBuZSxraT1uZXcgc3QsZ2w9bmV3IHp0LERzPW5ldyB6dDtmdW5jdGlvbiBEZChpLHQsZSxuKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IHM9am8oMCxpLGUsbik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksc31mdW5jdGlvbiBqbyhpLHQsZSxuLHM9bnVsbCl7Y29uc3R7ZmxvYXQzMkFycmF5OnIsdWludDE2QXJyYXk6byx1aW50MzJBcnJheTphfT1udDtsZXQgYz1pKjI7aWYocz09PW51bGwmJihlLmJvdW5kaW5nQm94fHxlLmNvbXB1dGVCb3VuZGluZ0JveCgpLGdsLnNldChlLmJvdW5kaW5nQm94Lm1pbixlLmJvdW5kaW5nQm94Lm1heCxuKSxzPWdsKSxrdChjLG8pKXtjb25zdCBoPXQuZ2VvbWV0cnksdT1oLmluZGV4LGY9aC5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9ZS5pbmRleCxwPWUuYXR0cmlidXRlcy5wb3NpdGlvbix5PVV0KGksYSksbT1LdChjLG8pO2lmKGtpLmNvcHkobikuaW52ZXJ0KCksZS5ib3VuZHNUcmVlKXJldHVybiBsdChpLHIsRHMpLERzLm1hdHJpeC5jb3B5KGtpKSxEcy5uZWVkc1VwZGF0ZT0hMCxlLmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmI9PkRzLmludGVyc2VjdHNCb3goYiksaW50ZXJzZWN0c1RyaWFuZ2xlOmI9PntiLmEuYXBwbHlNYXRyaXg0KG4pLGIuYi5hcHBseU1hdHJpeDQobiksYi5jLmFwcGx5TWF0cml4NChuKSxiLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgdz15KjMseD0obSt5KSozO3c8eDt3Kz0zKWlmKHl0KGpuLHcsdSxmKSxqbi5uZWVkc1VwZGF0ZT0hMCxiLmludGVyc2VjdHNUcmlhbmdsZShqbikpcmV0dXJuITA7cmV0dXJuITF9fSk7Zm9yKGxldCBnPXkqMyxiPShtK3kpKjM7ZzxiO2crPTMpe3l0KFluLGcsdSxmKSxZbi5hLmFwcGx5TWF0cml4NChraSksWW4uYi5hcHBseU1hdHJpeDQoa2kpLFluLmMuYXBwbHlNYXRyaXg0KGtpKSxZbi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHc9MCx4PWQuY291bnQ7dzx4O3crPTMpaWYoeXQoam4sdyxkLHApLGpuLm5lZWRzVXBkYXRlPSEwLFluLmludGVyc2VjdHNUcmlhbmdsZShqbikpcmV0dXJuITB9fWVsc2V7Y29uc3QgaD1pKzgsdT1hW2krNl07cmV0dXJuIGx0KGgscixPcyksISEocy5pbnRlcnNlY3RzQm94KE9zKSYmam8oaCx0LGUsbixzKXx8KGx0KHUscixPcykscy5pbnRlcnNlY3RzQm94KE9zKSYmam8odSx0LGUsbixzKSkpfX1jb25zdCAkcz1uZXcgc3QsUW89bmV3IHp0LE5pPW5ldyB6dCwkZD1uZXcgVCxWZD1uZXcgVCxVZD1uZXcgVCxxZD1uZXcgVDtmdW5jdGlvbiBIZChpLHQsZSxuPXt9LHM9e30scj0wLG89MS8wKXt0LmJvdW5kaW5nQm94fHx0LmNvbXB1dGVCb3VuZGluZ0JveCgpLFFvLnNldCh0LmJvdW5kaW5nQm94Lm1pbix0LmJvdW5kaW5nQm94Lm1heCxlKSxRby5uZWVkc1VwZGF0ZT0hMDtjb25zdCBhPWkuZ2VvbWV0cnksYz1hLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1hLmluZGV4LGg9dC5hdHRyaWJ1dGVzLnBvc2l0aW9uLHU9dC5pbmRleCxmPWllLmdldFByaW1pdGl2ZSgpLGQ9aWUuZ2V0UHJpbWl0aXZlKCk7bGV0IHA9JGQseT1WZCxtPW51bGwsZz1udWxsO3MmJihtPVVkLGc9cWQpO2xldCBiPTEvMCx3PW51bGwseD1udWxsO3JldHVybiAkcy5jb3B5KGUpLmludmVydCgpLE5pLm1hdHJpeC5jb3B5KCRzKSxpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpNPT5Rby5kaXN0YW5jZVRvQm94KE0pLGludGVyc2VjdHNCb3VuZHM6KE0sQSxTKT0+UzxiJiZTPG8/KEEmJihOaS5taW4uY29weShNLm1pbiksTmkubWF4LmNvcHkoTS5tYXgpLE5pLm5lZWRzVXBkYXRlPSEwKSwhMCk6ITEsaW50ZXJzZWN0c1JhbmdlOihNLEEpPT57aWYodC5ib3VuZHNUcmVlKXJldHVybiB0LmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtib3VuZHNUcmF2ZXJzZU9yZGVyOl89Pk5pLmRpc3RhbmNlVG9Cb3goXyksaW50ZXJzZWN0c0JvdW5kczooXyxFLHopPT56PGImJno8byxpbnRlcnNlY3RzUmFuZ2U6KF8sRSk9Pntmb3IobGV0IHo9Xyx2PV8rRTt6PHY7eisrKXt5dChkLDMqeix1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCBDPU0sUD1NK0E7QzxQO0MrKyl7eXQoZiwzKkMsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IEY9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKEY8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1GLHc9Qyx4PXopLEY8cilyZXR1cm4hMH19fX0pO3tjb25zdCBTPVpuKHQpO2ZvcihsZXQgXz0wLEU9UztfPEU7XysrKXt5dChkLDMqXyx1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB6PU0sdj1NK0E7ejx2O3orKyl7eXQoZiwzKnosbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IEM9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKEM8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1DLHc9eix4PV8pLEM8cilyZXR1cm4hMH19fX19KSxpZS5yZWxlYXNlUHJpbWl0aXZlKGYpLGllLnJlbGVhc2VQcmltaXRpdmUoZCksYj09PTEvMD9udWxsOihuLnBvaW50P24ucG9pbnQuY29weSh5KTpuLnBvaW50PXkuY2xvbmUoKSxuLmRpc3RhbmNlPWIsbi5mYWNlSW5kZXg9dyxzJiYocy5wb2ludD9zLnBvaW50LmNvcHkoZyk6cy5wb2ludD1nLmNsb25lKCkscy5wb2ludC5hcHBseU1hdHJpeDQoJHMpLHkuYXBwbHlNYXRyaXg0KCRzKSxzLmRpc3RhbmNlPXkuc3ViKHMucG9pbnQpLmxlbmd0aCgpLHMuZmFjZUluZGV4PXgpLG4pfWZ1bmN0aW9uIFdkKGksdD1udWxsKXt0JiZBcnJheS5pc0FycmF5KHQpJiYodD1uZXcgU2V0KHQpKTtjb25zdCBlPWkuZ2VvbWV0cnksbj1lLmluZGV4P2UuaW5kZXguYXJyYXk6bnVsbCxzPWUuYXR0cmlidXRlcy5wb3NpdGlvbjtsZXQgcixvLGEsYyxsPTA7Y29uc3QgaD1pLl9yb290cztmb3IobGV0IGY9MCxkPWgubGVuZ3RoO2Y8ZDtmKyspcj1oW2ZdLG89bmV3IFVpbnQzMkFycmF5KHIpLGE9bmV3IFVpbnQxNkFycmF5KHIpLGM9bmV3IEZsb2F0MzJBcnJheShyKSx1KDAsbCksbCs9ci5ieXRlTGVuZ3RoO2Z1bmN0aW9uIHUoZixkLHA9ITEpe2NvbnN0IHk9ZioyO2lmKGFbeSsxNV09PT1Qcyl7Y29uc3QgZz1vW2YrNl0sYj1hW3krMTRdO2xldCB3PTEvMCx4PTEvMCxNPTEvMCxBPS0xLzAsUz0tMS8wLF89LTEvMDtmb3IobGV0IEU9Zyx6PWcrYjtFPHo7RSsrKXtjb25zdCB2PTMqaS5yZXNvbHZlVHJpYW5nbGVJbmRleChFKTtmb3IobGV0IEM9MDtDPDM7QysrKXtsZXQgUD12K0M7UD1uP25bUF06UDtjb25zdCBGPXMuZ2V0WChQKSxCPXMuZ2V0WShQKSxJPXMuZ2V0WihQKTtGPHcmJih3PUYpLEY+QSYmKEE9RiksQjx4JiYoeD1CKSxCPlMmJihTPUIpLEk8TSYmKE09SSksST5fJiYoXz1JKX19cmV0dXJuIGNbZiswXSE9PXd8fGNbZisxXSE9PXh8fGNbZisyXSE9PU18fGNbZiszXSE9PUF8fGNbZis0XSE9PVN8fGNbZis1XSE9PV8/KGNbZiswXT13LGNbZisxXT14LGNbZisyXT1NLGNbZiszXT1BLGNbZis0XT1TLGNbZis1XT1fLCEwKTohMX1lbHNle2NvbnN0IGc9Zis4LGI9b1tmKzZdLHc9ZytkLHg9YitkO2xldCBNPXAsQT0hMSxTPSExO3Q/TXx8KEE9dC5oYXModyksUz10Lmhhcyh4KSxNPSFBJiYhUyk6KEE9ITAsUz0hMCk7Y29uc3QgXz1NfHxBLEU9TXx8UztsZXQgej0hMTtfJiYoej11KGcsZCxNKSk7bGV0IHY9ITE7RSYmKHY9dShiLGQsTSkpO2NvbnN0IEM9enx8djtpZihDKWZvcihsZXQgUD0wO1A8MztQKyspe2NvbnN0IEY9ZytQLEI9YitQLEk9Y1tGXSxrPWNbRiszXSxEPWNbQl0sVT1jW0IrM107Y1tmK1BdPUk8RD9JOkQsY1tmK1ArM109az5VP2s6VX1yZXR1cm4gQ319fWZ1bmN0aW9uIEdkKGksdCxlLG4scyxyLG8pe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSksS28oMCxpLGUsbixzLHIsbyksbnQuY2xlYXJCdWZmZXIoKX1mdW5jdGlvbiBLbyhpLHQsZSxuLHMscixvKXtjb25zdHtmbG9hdDMyQXJyYXk6YSx1aW50MTZBcnJheTpjLHVpbnQzMkFycmF5Omx9PW50LGg9aSoyO2lmKGt0KGgsYykpe2NvbnN0IGY9VXQoaSxsKSxkPUt0KGgsYyk7SWQodCxlLG4sZixkLHMscixvKX1lbHNle2NvbnN0IGY9dGUoaSk7ZW4oZixhLG4scixvKSYmS28oZix0LGUsbixzLHIsbyk7Y29uc3QgZD1lZShpLGwpO2VuKGQsYSxuLHIsbykmJktvKGQsdCxlLG4scyxyLG8pfX1jb25zdCBaZD1bIngiLCJ5IiwieiJdO2Z1bmN0aW9uIFhkKGksdCxlLG4scyxyKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IG89dGEoMCxpLGUsbixzLHIpO3JldHVybiBudC5jbGVhckJ1ZmZlcigpLG99ZnVuY3Rpb24gdGEoaSx0LGUsbixzLHIpe2NvbnN0e2Zsb2F0MzJBcnJheTpvLHVpbnQxNkFycmF5OmEsdWludDMyQXJyYXk6Y309bnQ7bGV0IGw9aSoyO2lmKGt0KGwsYSkpe2NvbnN0IHU9VXQoaSxjKSxmPUt0KGwsYSk7cmV0dXJuIGtkKHQsZSxuLHUsZixzLHIpfWVsc2V7Y29uc3QgdT11bChpLGMpLGY9WmRbdV0scD1uLmRpcmVjdGlvbltmXT49MDtsZXQgeSxtO3A/KHk9dGUoaSksbT1lZShpLGMpKTooeT1lZShpLGMpLG09dGUoaSkpO2NvbnN0IGI9ZW4oeSxvLG4scyxyKT90YSh5LHQsZSxuLHMscik6bnVsbDtpZihiKXtjb25zdCBNPWIucG9pbnRbZl07aWYocD9NPD1vW20rdV06TT49b1ttK3UrM10pcmV0dXJuIGJ9Y29uc3QgeD1lbihtLG8sbixzLHIpP3RhKG0sdCxlLG4scyxyKTpudWxsO3JldHVybiBiJiZ4P2IuZGlzdGFuY2U8PXguZGlzdGFuY2U/Yjp4OmJ8fHh8fG51bGx9fWNvbnN0IFZzPW5ldyBndCxRbj1uZXcgbmUsS249bmV3IG5lLFJpPW5ldyBzdCx4bD1uZXcgenQsVXM9bmV3IHp0O2Z1bmN0aW9uIEpkKGksdCxlLG4pe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSk7Y29uc3Qgcz1lYSgwLGksZSxuKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxzfWZ1bmN0aW9uIGVhKGksdCxlLG4scz1udWxsKXtjb25zdHtmbG9hdDMyQXJyYXk6cix1aW50MTZBcnJheTpvLHVpbnQzMkFycmF5OmF9PW50O2xldCBjPWkqMjtpZihzPT09bnVsbCYmKGUuYm91bmRpbmdCb3h8fGUuY29tcHV0ZUJvdW5kaW5nQm94KCkseGwuc2V0KGUuYm91bmRpbmdCb3gubWluLGUuYm91bmRpbmdCb3gubWF4LG4pLHM9eGwpLGt0KGMsbykpe2NvbnN0IGg9dC5nZW9tZXRyeSx1PWguaW5kZXgsZj1oLmF0dHJpYnV0ZXMucG9zaXRpb24sZD1lLmluZGV4LHA9ZS5hdHRyaWJ1dGVzLnBvc2l0aW9uLHk9VXQoaSxhKSxtPUt0KGMsbyk7aWYoUmkuY29weShuKS5pbnZlcnQoKSxlLmJvdW5kc1RyZWUpcmV0dXJuIGx0KGkscixVcyksVXMubWF0cml4LmNvcHkoUmkpLFVzLm5lZWRzVXBkYXRlPSEwLGUuYm91bmRzVHJlZS5zaGFwZWNhc3Qoe2ludGVyc2VjdHNCb3VuZHM6Yj0+VXMuaW50ZXJzZWN0c0JveChiKSxpbnRlcnNlY3RzVHJpYW5nbGU6Yj0+e2IuYS5hcHBseU1hdHJpeDQobiksYi5iLmFwcGx5TWF0cml4NChuKSxiLmMuYXBwbHlNYXRyaXg0KG4pLGIubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB3PXkseD1tK3k7dzx4O3crKylpZih5dChLbiwzKnQucmVzb2x2ZVRyaWFuZ2xlSW5kZXgodyksdSxmKSxLbi5uZWVkc1VwZGF0ZT0hMCxiLmludGVyc2VjdHNUcmlhbmdsZShLbikpcmV0dXJuITA7cmV0dXJuITF9fSk7Zm9yKGxldCBnPXksYj1tK3k7ZzxiO2crKyl7Y29uc3Qgdz10LnJlc29sdmVUcmlhbmdsZUluZGV4KGcpO3l0KFFuLDMqdyx1LGYpLFFuLmEuYXBwbHlNYXRyaXg0KFJpKSxRbi5iLmFwcGx5TWF0cml4NChSaSksUW4uYy5hcHBseU1hdHJpeDQoUmkpLFFuLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgeD0wLE09ZC5jb3VudDt4PE07eCs9MylpZih5dChLbix4LGQscCksS24ubmVlZHNVcGRhdGU9ITAsUW4uaW50ZXJzZWN0c1RyaWFuZ2xlKEtuKSlyZXR1cm4hMH19ZWxzZXtjb25zdCBoPWkrOCx1PWFbaSs2XTtyZXR1cm4gbHQoaCxyLFZzKSwhIShzLmludGVyc2VjdHNCb3goVnMpJiZlYShoLHQsZSxuLHMpfHwobHQodSxyLFZzKSxzLmludGVyc2VjdHNCb3goVnMpJiZlYSh1LHQsZSxuLHMpKSl9fWNvbnN0IHFzPW5ldyBzdCxuYT1uZXcgenQsTGk9bmV3IHp0LFlkPW5ldyBULGpkPW5ldyBULFFkPW5ldyBULEtkPW5ldyBUO2Z1bmN0aW9uIHQwKGksdCxlLG49e30scz17fSxyPTAsbz0xLzApe3QuYm91bmRpbmdCb3h8fHQuY29tcHV0ZUJvdW5kaW5nQm94KCksbmEuc2V0KHQuYm91bmRpbmdCb3gubWluLHQuYm91bmRpbmdCb3gubWF4LGUpLG5hLm5lZWRzVXBkYXRlPSEwO2NvbnN0IGE9aS5nZW9tZXRyeSxjPWEuYXR0cmlidXRlcy5wb3NpdGlvbixsPWEuaW5kZXgsaD10LmF0dHJpYnV0ZXMucG9zaXRpb24sdT10LmluZGV4LGY9aWUuZ2V0UHJpbWl0aXZlKCksZD1pZS5nZXRQcmltaXRpdmUoKTtsZXQgcD1ZZCx5PWpkLG09bnVsbCxnPW51bGw7cyYmKG09UWQsZz1LZCk7bGV0IGI9MS8wLHc9bnVsbCx4PW51bGw7cmV0dXJuIHFzLmNvcHkoZSkuaW52ZXJ0KCksTGkubWF0cml4LmNvcHkocXMpLGkuc2hhcGVjYXN0KHtib3VuZHNUcmF2ZXJzZU9yZGVyOk09Pm5hLmRpc3RhbmNlVG9Cb3goTSksaW50ZXJzZWN0c0JvdW5kczooTSxBLFMpPT5TPGImJlM8bz8oQSYmKExpLm1pbi5jb3B5KE0ubWluKSxMaS5tYXguY29weShNLm1heCksTGkubmVlZHNVcGRhdGU9ITApLCEwKTohMSxpbnRlcnNlY3RzUmFuZ2U6KE0sQSk9PntpZih0LmJvdW5kc1RyZWUpe2NvbnN0IFM9dC5ib3VuZHNUcmVlO3JldHVybiBTLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpfPT5MaS5kaXN0YW5jZVRvQm94KF8pLGludGVyc2VjdHNCb3VuZHM6KF8sRSx6KT0+ejxiJiZ6PG8saW50ZXJzZWN0c1JhbmdlOihfLEUpPT57Zm9yKGxldCB6PV8sdj1fK0U7ejx2O3orKyl7Y29uc3QgQz1TLnJlc29sdmVUcmlhbmdsZUluZGV4KHopO3l0KGQsMypDLHUsaCksZC5hLmFwcGx5TWF0cml4NChlKSxkLmIuYXBwbHlNYXRyaXg0KGUpLGQuYy5hcHBseU1hdHJpeDQoZSksZC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IFA9TSxGPU0rQTtQPEY7UCsrKXtjb25zdCBCPWkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoUCk7eXQoZiwzKkIsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IEk9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKEk8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1JLHc9UCx4PXopLEk8cilyZXR1cm4hMH19fX0pfWVsc2V7Y29uc3QgUz1abih0KTtmb3IobGV0IF89MCxFPVM7XzxFO18rKyl7eXQoZCwzKl8sdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgej1NLHY9TStBO3o8djt6Kyspe2NvbnN0IEM9aS5yZXNvbHZlVHJpYW5nbGVJbmRleCh6KTt5dChmLDMqQyxsLGMpLGYubmVlZHNVcGRhdGU9ITA7Y29uc3QgUD1mLmRpc3RhbmNlVG9UcmlhbmdsZShkLHAsbSk7aWYoUDxiJiYoeS5jb3B5KHApLGcmJmcuY29weShtKSxiPVAsdz16LHg9XyksUDxyKXJldHVybiEwfX19fX0pLGllLnJlbGVhc2VQcmltaXRpdmUoZiksaWUucmVsZWFzZVByaW1pdGl2ZShkKSxiPT09MS8wP251bGw6KG4ucG9pbnQ/bi5wb2ludC5jb3B5KHkpOm4ucG9pbnQ9eS5jbG9uZSgpLG4uZGlzdGFuY2U9YixuLmZhY2VJbmRleD13LHMmJihzLnBvaW50P3MucG9pbnQuY29weShnKTpzLnBvaW50PWcuY2xvbmUoKSxzLnBvaW50LmFwcGx5TWF0cml4NChxcykseS5hcHBseU1hdHJpeDQocXMpLHMuZGlzdGFuY2U9eS5zdWIocy5wb2ludCkubGVuZ3RoKCkscy5mYWNlSW5kZXg9eCksbil9ZnVuY3Rpb24gZTAoKXtyZXR1cm4gdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIn1jb25zdCBPaT1uZXcgbnQuY29uc3RydWN0b3IsSHM9bmV3IG50LmNvbnN0cnVjdG9yLG5uPW5ldyBHbygoKT0+bmV3IGd0KSx0aT1uZXcgZ3QsZWk9bmV3IGd0LGlhPW5ldyBndCxzYT1uZXcgZ3Q7bGV0IHJhPSExO2Z1bmN0aW9uIG4wKGksdCxlLG4pe2lmKHJhKXRocm93IG5ldyBFcnJvcigiTWVzaEJWSDogUmVjdXJzaXZlIGNhbGxzIHRvIGJ2aGNhc3Qgbm90IHN1cHBvcnRlZC4iKTtyYT0hMDtjb25zdCBzPWkuX3Jvb3RzLHI9dC5fcm9vdHM7bGV0IG8sYT0wLGM9MDtjb25zdCBsPW5ldyBzdCgpLmNvcHkoZSkuaW52ZXJ0KCk7Zm9yKGxldCBoPTAsdT1zLmxlbmd0aDtoPHU7aCsrKXtPaS5zZXRCdWZmZXIoc1toXSksYz0wO2NvbnN0IGY9bm4uZ2V0UHJpbWl0aXZlKCk7bHQoMCxPaS5mbG9hdDMyQXJyYXksZiksZi5hcHBseU1hdHJpeDQobCk7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHAmJihIcy5zZXRCdWZmZXIocltkXSksbz1mZSgwLDAsZSxsLG4sYSxjLDAsMCxmKSxIcy5jbGVhckJ1ZmZlcigpLGMrPXJbZF0ubGVuZ3RoLCFvKTtkKyspO2lmKG5uLnJlbGVhc2VQcmltaXRpdmUoZiksT2kuY2xlYXJCdWZmZXIoKSxhKz1zW2hdLmxlbmd0aCxvKWJyZWFrfXJldHVybiByYT0hMSxvfWZ1bmN0aW9uIGZlKGksdCxlLG4scyxyPTAsbz0wLGE9MCxjPTAsbD1udWxsLGg9ITEpe2xldCB1LGY7aD8odT1IcyxmPU9pKToodT1PaSxmPUhzKTtjb25zdCBkPXUuZmxvYXQzMkFycmF5LHA9dS51aW50MzJBcnJheSx5PXUudWludDE2QXJyYXksbT1mLmZsb2F0MzJBcnJheSxnPWYudWludDMyQXJyYXksYj1mLnVpbnQxNkFycmF5LHc9aSoyLHg9dCoyLE09a3Qodyx5KSxBPWt0KHgsYik7bGV0IFM9ITE7aWYoQSYmTSloP1M9cyhVdCh0LGcpLEt0KHQqMixiKSxVdChpLHApLEt0KGkqMix5KSxjLG8rdCxhLHIraSk6Uz1zKFV0KGkscCksS3QoaSoyLHkpLFV0KHQsZyksS3QodCoyLGIpLGEscitpLGMsbyt0KTtlbHNlIGlmKEEpe2NvbnN0IF89bm4uZ2V0UHJpbWl0aXZlKCk7bHQodCxtLF8pLF8uYXBwbHlNYXRyaXg0KGUpO2NvbnN0IEU9dGUoaSksej1lZShpLHApO2x0KEUsZCx0aSksbHQoeixkLGVpKTtjb25zdCB2PV8uaW50ZXJzZWN0c0JveCh0aSksQz1fLmludGVyc2VjdHNCb3goZWkpO1M9diYmZmUodCxFLG4sZSxzLG8scixjLGErMSxfLCFoKXx8QyYmZmUodCx6LG4sZSxzLG8scixjLGErMSxfLCFoKSxubi5yZWxlYXNlUHJpbWl0aXZlKF8pfWVsc2V7Y29uc3QgXz10ZSh0KSxFPWVlKHQsZyk7bHQoXyxtLGlhKSxsdChFLG0sc2EpO2NvbnN0IHo9bC5pbnRlcnNlY3RzQm94KGlhKSx2PWwuaW50ZXJzZWN0c0JveChzYSk7aWYoeiYmdilTPWZlKGksXyxlLG4scyxyLG8sYSxjKzEsbCxoKXx8ZmUoaSxFLGUsbixzLHIsbyxhLGMrMSxsLGgpO2Vsc2UgaWYoeilpZihNKVM9ZmUoaSxfLGUsbixzLHIsbyxhLGMrMSxsLGgpO2Vsc2V7Y29uc3QgQz1ubi5nZXRQcmltaXRpdmUoKTtDLmNvcHkoaWEpLmFwcGx5TWF0cml4NChlKTtjb25zdCBQPXRlKGkpLEY9ZWUoaSxwKTtsdChQLGQsdGkpLGx0KEYsZCxlaSk7Y29uc3QgQj1DLmludGVyc2VjdHNCb3godGkpLEk9Qy5pbnRlcnNlY3RzQm94KGVpKTtTPUImJmZlKF8sUCxuLGUscyxvLHIsYyxhKzEsQywhaCl8fEkmJmZlKF8sRixuLGUscyxvLHIsYyxhKzEsQywhaCksbm4ucmVsZWFzZVByaW1pdGl2ZShDKX1lbHNlIGlmKHYpaWYoTSlTPWZlKGksRSxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNle2NvbnN0IEM9bm4uZ2V0UHJpbWl0aXZlKCk7Qy5jb3B5KHNhKS5hcHBseU1hdHJpeDQoZSk7Y29uc3QgUD10ZShpKSxGPWVlKGkscCk7bHQoUCxkLHRpKSxsdChGLGQsZWkpO2NvbnN0IEI9Qy5pbnRlcnNlY3RzQm94KHRpKSxJPUMuaW50ZXJzZWN0c0JveChlaSk7Uz1CJiZmZShFLFAsbixlLHMsbyxyLGMsYSsxLEMsIWgpfHxJJiZmZShFLEYsbixlLHMsbyxyLGMsYSsxLEMsIWgpLG5uLnJlbGVhc2VQcmltaXRpdmUoQyl9fXJldHVybiBTfWNvbnN0IFdzPW5ldyB6dCx3bD1uZXcgZ3QsaTA9e3N0cmF0ZWd5OmlsLG1heERlcHRoOjQwLG1heExlYWZUcmlzOjEwLHVzZVNoYXJlZEFycmF5QnVmZmVyOiExLHNldEJvdW5kaW5nQm94OiEwLG9uUHJvZ3Jlc3M6bnVsbCxpbmRpcmVjdDohMSx2ZXJib3NlOiEwLHJhbmdlOm51bGx9O2NsYXNzIG9he3N0YXRpYyBzZXJpYWxpemUodCxlPXt9KXtlPUZ0KHtjbG9uZUJ1ZmZlcnM6ITB9LGUpO2NvbnN0IG49dC5nZW9tZXRyeSxzPXQuX3Jvb3RzLHI9dC5faW5kaXJlY3RCdWZmZXIsbz1uLmdldEluZGV4KCk7bGV0IGE7cmV0dXJuIGUuY2xvbmVCdWZmZXJzP2E9e3Jvb3RzOnMubWFwKGM9PmMuc2xpY2UoKSksaW5kZXg6bz9vLmFycmF5LnNsaWNlKCk6bnVsbCxpbmRpcmVjdEJ1ZmZlcjpyP3Iuc2xpY2UoKTpudWxsfTphPXtyb290czpzLGluZGV4Om8/by5hcnJheTpudWxsLGluZGlyZWN0QnVmZmVyOnJ9LGF9c3RhdGljIGRlc2VyaWFsaXplKHQsZSxuPXt9KXtuPUZ0KHtzZXRJbmRleDohMCxpbmRpcmVjdDohIXQuaW5kaXJlY3RCdWZmZXJ9LG4pO2NvbnN0e2luZGV4OnMscm9vdHM6cixpbmRpcmVjdEJ1ZmZlcjpvfT10LGE9bmV3IG9hKGUsWmUoRnQoe30sbikse1tEb106ITB9KSk7aWYoYS5fcm9vdHM9cixhLl9pbmRpcmVjdEJ1ZmZlcj1vfHxudWxsLG4uc2V0SW5kZXgpe2NvbnN0IGM9ZS5nZXRJbmRleCgpO2lmKGM9PT1udWxsKXtjb25zdCBsPW5ldyB4dCh0LmluZGV4LDEsITEpO2Uuc2V0SW5kZXgobCl9ZWxzZSBjLmFycmF5IT09cyYmKGMuYXJyYXkuc2V0KHMpLGMubmVlZHNVcGRhdGU9ITApfXJldHVybiBhfWdldCBpbmRpcmVjdCgpe3JldHVybiEhdGhpcy5faW5kaXJlY3RCdWZmZXJ9Y29uc3RydWN0b3IodCxlPXt9KXtpZih0LmlzQnVmZmVyR2VvbWV0cnkpe2lmKHQuaW5kZXgmJnQuaW5kZXguaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IEludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHRoZSBpbmRleCBhdHRyaWJ1dGUuIil9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IE9ubHkgQnVmZmVyR2VvbWV0cmllcyBhcmUgc3VwcG9ydGVkLiIpO2lmKGU9T2JqZWN0LmFzc2lnbihaZShGdCh7fSxpMCkse1tEb106ITF9KSxlKSxlLnVzZVNoYXJlZEFycmF5QnVmZmVyJiYhZTAoKSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IFNoYXJlZEFycmF5QnVmZmVyIGlzIG5vdCBhdmFpbGFibGUuIik7dGhpcy5nZW9tZXRyeT10LHRoaXMuX3Jvb3RzPW51bGwsdGhpcy5faW5kaXJlY3RCdWZmZXI9bnVsbCxlW0RvXXx8KHhkKHRoaXMsZSksIXQuYm91bmRpbmdCb3gmJmUuc2V0Qm91bmRpbmdCb3gmJih0LmJvdW5kaW5nQm94PXRoaXMuZ2V0Qm91bmRpbmdCb3gobmV3IGd0KSkpLHRoaXMucmVzb2x2ZVRyaWFuZ2xlSW5kZXg9ZS5pbmRpcmVjdD9uPT50aGlzLl9pbmRpcmVjdEJ1ZmZlcltuXTpuPT5ufXJlZml0KHQ9bnVsbCl7cmV0dXJuKHRoaXMuaW5kaXJlY3Q/V2Q6RmQpKHRoaXMsdCl9dHJhdmVyc2UodCxlPTApe2NvbnN0IG49dGhpcy5fcm9vdHNbZV0scz1uZXcgVWludDMyQXJyYXkobikscj1uZXcgVWludDE2QXJyYXkobik7bygwKTtmdW5jdGlvbiBvKGEsYz0wKXtjb25zdCBsPWEqMixoPXJbbCsxNV09PT1QcztpZihoKXtjb25zdCB1PXNbYSs2XSxmPXJbbCsxNF07dChjLGgsbmV3IEZsb2F0MzJBcnJheShuLGEqNCw2KSx1LGYpfWVsc2V7Y29uc3QgdT1hK1BpLzQsZj1zW2ErNl0sZD1zW2ErN107dChjLGgsbmV3IEZsb2F0MzJBcnJheShuLGEqNCw2KSxkKXx8KG8odSxjKzEpLG8oZixjKzEpKX19fXJheWNhc3QodCxlPTAsbj0wLHM9MS8wKXtjb25zdCByPXRoaXMuX3Jvb3RzLG89dGhpcy5nZW9tZXRyeSxhPVtdLGM9ZS5pc01hdGVyaWFsLGw9QXJyYXkuaXNBcnJheShlKSxoPW8uZ3JvdXBzLHU9Yz9lLnNpZGU6ZSxmPXRoaXMuaW5kaXJlY3Q/R2Q6UmQ7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHA7ZCsrKXtjb25zdCB5PWw/ZVtoW2RdLm1hdGVyaWFsSW5kZXhdLnNpZGU6dSxtPWEubGVuZ3RoO2lmKGYodGhpcyxkLHksdCxhLG4scyksbCl7Y29uc3QgZz1oW2RdLm1hdGVyaWFsSW5kZXg7Zm9yKGxldCBiPW0sdz1hLmxlbmd0aDtiPHc7YisrKWFbYl0uZmFjZS5tYXRlcmlhbEluZGV4PWd9fXJldHVybiBhfXJheWNhc3RGaXJzdCh0LGU9MCxuPTAscz0xLzApe2NvbnN0IHI9dGhpcy5fcm9vdHMsbz10aGlzLmdlb21ldHJ5LGE9ZS5pc01hdGVyaWFsLGM9QXJyYXkuaXNBcnJheShlKTtsZXQgbD1udWxsO2NvbnN0IGg9by5ncm91cHMsdT1hP2Uuc2lkZTplLGY9dGhpcy5pbmRpcmVjdD9YZDpPZDtmb3IobGV0IGQ9MCxwPXIubGVuZ3RoO2Q8cDtkKyspe2NvbnN0IHk9Yz9lW2hbZF0ubWF0ZXJpYWxJbmRleF0uc2lkZTp1LG09Zih0aGlzLGQseSx0LG4scyk7bSE9bnVsbCYmKGw9PW51bGx8fG0uZGlzdGFuY2U8bC5kaXN0YW5jZSkmJihsPW0sYyYmKG0uZmFjZS5tYXRlcmlhbEluZGV4PWhbZF0ubWF0ZXJpYWxJbmRleCkpfXJldHVybiBsfWludGVyc2VjdHNHZW9tZXRyeSh0LGUpe2xldCBuPSExO2NvbnN0IHM9dGhpcy5fcm9vdHMscj10aGlzLmluZGlyZWN0P0pkOkRkO2ZvcihsZXQgbz0wLGE9cy5sZW5ndGg7bzxhJiYobj1yKHRoaXMsbyx0LGUpLCFuKTtvKyspO3JldHVybiBufXNoYXBlY2FzdCh0KXtjb25zdCBlPWllLmdldFByaW1pdGl2ZSgpLG49dGhpcy5pbmRpcmVjdD9OZDpCZDtsZXR7Ym91bmRzVHJhdmVyc2VPcmRlcjpzLGludGVyc2VjdHNCb3VuZHM6cixpbnRlcnNlY3RzUmFuZ2U6byxpbnRlcnNlY3RzVHJpYW5nbGU6YX09dDtpZihvJiZhKXtjb25zdCB1PW87bz0oZixkLHAseSxtKT0+dShmLGQscCx5LG0pPyEwOm4oZixkLHRoaXMsYSxwLHksZSl9ZWxzZSBvfHwoYT9vPSh1LGYsZCxwKT0+bih1LGYsdGhpcyxhLGQscCxlKTpvPSh1LGYsZCk9PmQpO2xldCBjPSExLGw9MDtjb25zdCBoPXRoaXMuX3Jvb3RzO2ZvcihsZXQgdT0wLGY9aC5sZW5ndGg7dTxmO3UrKyl7Y29uc3QgZD1oW3VdO2lmKGM9X2QodGhpcyx1LHIsbyxzLGwpLGMpYnJlYWs7bCs9ZC5ieXRlTGVuZ3RofXJldHVybiBpZS5yZWxlYXNlUHJpbWl0aXZlKGUpLGN9YnZoY2FzdCh0LGUsbil7bGV0e2ludGVyc2VjdHNSYW5nZXM6cyxpbnRlcnNlY3RzVHJpYW5nbGVzOnJ9PW47Y29uc3Qgbz1pZS5nZXRQcmltaXRpdmUoKSxhPXRoaXMuZ2VvbWV0cnkuaW5kZXgsYz10aGlzLmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb24sbD10aGlzLmluZGlyZWN0P3A9Pntjb25zdCB5PXRoaXMucmVzb2x2ZVRyaWFuZ2xlSW5kZXgocCk7eXQobyx5KjMsYSxjKX06cD0+e3l0KG8scCozLGEsYyl9LGg9aWUuZ2V0UHJpbWl0aXZlKCksdT10Lmdlb21ldHJ5LmluZGV4LGY9dC5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9dC5pbmRpcmVjdD9wPT57Y29uc3QgeT10LnJlc29sdmVUcmlhbmdsZUluZGV4KHApO3l0KGgseSozLHUsZil9OnA9Pnt5dChoLHAqMyx1LGYpfTtpZihyKXtjb25zdCBwPSh5LG0sZyxiLHcseCxNLEEpPT57Zm9yKGxldCBTPWcsXz1nK2I7UzxfO1MrKyl7ZChTKSxoLmEuYXBwbHlNYXRyaXg0KGUpLGguYi5hcHBseU1hdHJpeDQoZSksaC5jLmFwcGx5TWF0cml4NChlKSxoLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgRT15LHo9eSttO0U8ejtFKyspaWYobChFKSxvLm5lZWRzVXBkYXRlPSEwLHIobyxoLEUsUyx3LHgsTSxBKSlyZXR1cm4hMH1yZXR1cm4hMX07aWYocyl7Y29uc3QgeT1zO3M9ZnVuY3Rpb24obSxnLGIsdyx4LE0sQSxTKXtyZXR1cm4geShtLGcsYix3LHgsTSxBLFMpPyEwOnAobSxnLGIsdyx4LE0sQSxTKX19ZWxzZSBzPXB9cmV0dXJuIG4wKHRoaXMsdCxlLHMpfWludGVyc2VjdHNCb3godCxlKXtyZXR1cm4gV3Muc2V0KHQubWluLHQubWF4LGUpLFdzLm5lZWRzVXBkYXRlPSEwLHRoaXMuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOm49PldzLmludGVyc2VjdHNCb3gobiksaW50ZXJzZWN0c1RyaWFuZ2xlOm49PldzLmludGVyc2VjdHNUcmlhbmdsZShuKX0pfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHRoaXMuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmU9PnQuaW50ZXJzZWN0c0JveChlKSxpbnRlcnNlY3RzVHJpYW5nbGU6ZT0+ZS5pbnRlcnNlY3RzU3BoZXJlKHQpfSl9Y2xvc2VzdFBvaW50VG9HZW9tZXRyeSh0LGUsbj17fSxzPXt9LHI9MCxvPTEvMCl7cmV0dXJuKHRoaXMuaW5kaXJlY3Q/dDA6SGQpKHRoaXMsdCxlLG4scyxyLG8pfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlPXt9LG49MCxzPTEvMCl7cmV0dXJuIHZkKHRoaXMsdCxlLG4scyl9Z2V0Qm91bmRpbmdCb3godCl7cmV0dXJuIHQubWFrZUVtcHR5KCksdGhpcy5fcm9vdHMuZm9yRWFjaChuPT57bHQoMCxuZXcgRmxvYXQzMkFycmF5KG4pLHdsKSx0LnVuaW9uKHdsKX0pLHR9fWNvbnN0IGJsPTFlLTYsczA9YmwqLjUsTWw9TWF0aC5wb3coMTAsLU1hdGgubG9nMTAoYmwpKSxyMD1zMCpNbDtmdW5jdGlvbiB3ZShpKXtyZXR1cm5+fihpKk1sK3IwKX1mdW5jdGlvbiBvMChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9YH1mdW5jdGlvbiBBbChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9LCR7d2UoaS56KX1gfWZ1bmN0aW9uIGEwKGkpe3JldHVybmAke3dlKGkueCl9LCR7d2UoaS55KX0sJHt3ZShpLnopfSwke3dlKGkudyl9YH1mdW5jdGlvbiBjMChpLHQsZSl7ZS5kaXJlY3Rpb24uc3ViVmVjdG9ycyh0LGkpLm5vcm1hbGl6ZSgpO2NvbnN0IG49aS5kb3QoZS5kaXJlY3Rpb24pO3JldHVybiBlLm9yaWdpbi5jb3B5KGkpLmFkZFNjYWxlZFZlY3RvcihlLmRpcmVjdGlvbiwtbiksZX1mdW5jdGlvbiBTbCgpe3JldHVybiB0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIhPSJ1bmRlZmluZWQifWZ1bmN0aW9uIGwwKGkpe2lmKGkuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXIpcmV0dXJuIGk7Y29uc3QgdD1pLmNvbnN0cnVjdG9yLGU9aS5idWZmZXIsbj1uZXcgU2hhcmVkQXJyYXlCdWZmZXIoZS5ieXRlTGVuZ3RoKSxzPW5ldyBVaW50OEFycmF5KGUpO3JldHVybiBuZXcgVWludDhBcnJheShuKS5zZXQocywwKSxuZXcgdChuKX1mdW5jdGlvbiBoMChpLHQ9QXJyYXlCdWZmZXIpe3JldHVybiBpPjY1NTM1P25ldyBVaW50MzJBcnJheShuZXcgdCg0KmkpKTpuZXcgVWludDE2QXJyYXkobmV3IHQoMippKSl9ZnVuY3Rpb24gdTAoaSx0KXtpZighaS5pbmRleCl7Y29uc3QgZT1pLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQsbj10LnVzZVNoYXJlZEFycmF5QnVmZmVyP1NoYXJlZEFycmF5QnVmZmVyOkFycmF5QnVmZmVyLHM9aDAoZSxuKTtpLnNldEluZGV4KG5ldyB4dChzLDEpKTtmb3IobGV0IHI9MDtyPGU7cisrKXNbcl09cn19ZnVuY3Rpb24gZjAoaSl7cmV0dXJuIGkuaW5kZXg/aS5pbmRleC5jb3VudDppLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnR9ZnVuY3Rpb24gYWEoaSl7cmV0dXJuIGYwKGkpLzN9Y29uc3QgZDA9MWUtOCxwMD1uZXcgVDtmdW5jdGlvbiB5MChpKXtyZXR1cm5+fihpLzMpfWZ1bmN0aW9uIG0wKGkpe3JldHVybiBpJTN9ZnVuY3Rpb24gX2woaSx0KXtyZXR1cm4gaS5zdGFydC10LnN0YXJ0fWZ1bmN0aW9uIHZsKGksdCl7cmV0dXJuIHAwLnN1YlZlY3RvcnModCxpLm9yaWdpbikuZG90KGkuZGlyZWN0aW9uKX1mdW5jdGlvbiBnMChpLHQsZSxuPWQwKXtpLnNvcnQoX2wpLHQuc29ydChfbCk7Zm9yKGxldCBhPTA7YTxpLmxlbmd0aDthKyspe2NvbnN0IGM9aVthXTtmb3IobGV0IGw9MDtsPHQubGVuZ3RoO2wrKyl7Y29uc3QgaD10W2xdO2lmKCEoaC5zdGFydD5jLmVuZCkpe2lmKGMuZW5kPGguc3RhcnR8fGguZW5kPGMuc3RhcnQpY29udGludWU7aWYoYy5zdGFydDw9aC5zdGFydCYmYy5lbmQ+PWguZW5kKXIoaC5lbmQsYy5lbmQpfHxpLnNwbGljZShhKzEsMCx7c3RhcnQ6aC5lbmQsZW5kOmMuZW5kLGluZGV4OmMuaW5kZXh9KSxjLmVuZD1oLnN0YXJ0LGguc3RhcnQ9MCxoLmVuZD0wO2Vsc2UgaWYoYy5zdGFydD49aC5zdGFydCYmYy5lbmQ8PWguZW5kKXIoYy5lbmQsaC5lbmQpfHx0LnNwbGljZShsKzEsMCx7c3RhcnQ6Yy5lbmQsZW5kOmguZW5kLGluZGV4OmguaW5kZXh9KSxoLmVuZD1jLnN0YXJ0LGMuc3RhcnQ9MCxjLmVuZD0wO2Vsc2UgaWYoYy5zdGFydDw9aC5zdGFydCYmYy5lbmQ8PWguZW5kKXtjb25zdCB1PWMuZW5kO2MuZW5kPWguc3RhcnQsaC5zdGFydD11fWVsc2UgaWYoYy5zdGFydD49aC5zdGFydCYmYy5lbmQ+PWguZW5kKXtjb25zdCB1PWguZW5kO2guZW5kPWMuc3RhcnQsYy5zdGFydD11fWVsc2UgdGhyb3cgbmV3IEVycm9yfWlmKGUuaGFzKGMuaW5kZXgpfHxlLnNldChjLmluZGV4LFtdKSxlLmhhcyhoLmluZGV4KXx8ZS5zZXQoaC5pbmRleCxbXSksZS5nZXQoYy5pbmRleCkucHVzaChoLmluZGV4KSxlLmdldChoLmluZGV4KS5wdXNoKGMuaW5kZXgpLG8oaCkmJih0LnNwbGljZShsLDEpLGwtLSksbyhjKSl7aS5zcGxpY2UoYSwxKSxhLS07YnJlYWt9fX1zKGkpLHModCk7ZnVuY3Rpb24gcyhhKXtmb3IobGV0IGM9MDtjPGEubGVuZ3RoO2MrKylvKGFbY10pJiYoYS5zcGxpY2UoYywxKSxjLS0pfWZ1bmN0aW9uIHIoYSxjKXtyZXR1cm4gTWF0aC5hYnMoYy1hKTxufWZ1bmN0aW9uIG8oYSl7cmV0dXJuIE1hdGguYWJzKGEuZW5kLWEuc3RhcnQpPG59fWNvbnN0IHpsPTFlLTUsVGw9MWUtNDtjbGFzcyB4MHtjb25zdHJ1Y3Rvcigpe3RoaXMuX3JheXM9W119YWRkUmF5KHQpe3RoaXMuX3JheXMucHVzaCh0KX1maW5kQ2xvc2VzdFJheSh0KXtjb25zdCBlPXRoaXMuX3JheXMsbj10LmNsb25lKCk7bi5kaXJlY3Rpb24ubXVsdGlwbHlTY2FsYXIoLTEpO2xldCBzPTEvMCxyPW51bGw7Zm9yKGxldCBjPTAsbD1lLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPWVbY107aWYobyhoLHQpJiZvKGgsbikpY29udGludWU7Y29uc3QgdT1hKGgsdCksZj1hKGgsbiksZD1NYXRoLm1pbih1LGYpO2Q8cyYmKHM9ZCxyPWgpfXJldHVybiByO2Z1bmN0aW9uIG8oYyxsKXtjb25zdCBoPWMub3JpZ2luLmRpc3RhbmNlVG8obC5vcmlnaW4pPnpsO3JldHVybiBjLmRpcmVjdGlvbi5hbmdsZVRvKGwuZGlyZWN0aW9uKT5UbHx8aH1mdW5jdGlvbiBhKGMsbCl7Y29uc3QgaD1jLm9yaWdpbi5kaXN0YW5jZVRvKGwub3JpZ2luKSx1PWMuZGlyZWN0aW9uLmFuZ2xlVG8obC5kaXJlY3Rpb24pO3JldHVybiBoL3psK3UvVGx9fX1jb25zdCBjYT1uZXcgVCxsYT1uZXcgVCxHcz1uZXcgZm87ZnVuY3Rpb24gdzAoaSx0LGUpe2NvbnN0IG49aS5hdHRyaWJ1dGVzLHM9aS5pbmRleCxyPW4ucG9zaXRpb24sbz1uZXcgTWFwLGE9bmV3IE1hcCxjPUFycmF5LmZyb20odCksbD1uZXcgeDA7Zm9yKGxldCBoPTAsdT1jLmxlbmd0aDtoPHU7aCsrKXtjb25zdCBmPWNbaF0sZD15MChmKSxwPW0wKGYpO2xldCB5PTMqZCtwLG09MypkKyhwKzEpJTM7cyYmKHk9cy5nZXRYKHkpLG09cy5nZXRYKG0pKSxjYS5mcm9tQnVmZmVyQXR0cmlidXRlKHIseSksbGEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLG0pLGMwKGNhLGxhLEdzKTtsZXQgZyxiPWwuZmluZENsb3Nlc3RSYXkoR3MpO2I9PT1udWxsJiYoYj1Hcy5jbG9uZSgpLGwuYWRkUmF5KGIpKSxhLmhhcyhiKXx8YS5zZXQoYix7Zm9yd2FyZDpbXSxyZXZlcnNlOltdLHJheTpifSksZz1hLmdldChiKTtsZXQgdz12bChiLGNhKSx4PXZsKGIsbGEpO3c+eCYmKFt3LHhdPVt4LHddKSxHcy5kaXJlY3Rpb24uZG90KGIuZGlyZWN0aW9uKTwwP2cucmV2ZXJzZS5wdXNoKHtzdGFydDp3LGVuZDp4LGluZGV4OmZ9KTpnLmZvcndhcmQucHVzaCh7c3RhcnQ6dyxlbmQ6eCxpbmRleDpmfSl9cmV0dXJuIGEuZm9yRWFjaCgoe2ZvcndhcmQ6aCxyZXZlcnNlOnV9LGYpPT57ZzAoaCx1LG8sZSksaC5sZW5ndGg9PT0wJiZ1Lmxlbmd0aD09PTAmJmEuZGVsZXRlKGYpfSkse2Rpc2pvaW50Q29ubmVjdGl2aXR5TWFwOm8sZnJhZ21lbnRNYXA6YX19Y29uc3QgYjA9bmV3IFIsaGE9bmV3IFQsTTA9bmV3IFl0LHVhPVsiIiwiIiwiIl07Y2xhc3MgQTB7Y29uc3RydWN0b3IodD1udWxsKXt0aGlzLmRhdGE9bnVsbCx0aGlzLmRpc2pvaW50Q29ubmVjdGlvbnM9bnVsbCx0aGlzLnVubWF0Y2hlZERpc2pvaW50RWRnZXM9bnVsbCx0aGlzLnVubWF0Y2hlZEVkZ2VzPS0xLHRoaXMubWF0Y2hlZEVkZ2VzPS0xLHRoaXMudXNlRHJhd1JhbmdlPSEwLHRoaXMudXNlQWxsQXR0cmlidXRlcz0hMSx0aGlzLm1hdGNoRGlzam9pbnRFZGdlcz0hMSx0aGlzLmRlZ2VuZXJhdGVFcHNpbG9uPTFlLTgsdCYmdGhpcy51cGRhdGVGcm9tKHQpfWdldFNpYmxpbmdUcmlhbmdsZUluZGV4KHQsZSl7Y29uc3Qgbj10aGlzLmRhdGFbdCozK2VdO3JldHVybiBuPT09LTE/LTE6fn4obi8zKX1nZXRTaWJsaW5nRWRnZUluZGV4KHQsZSl7Y29uc3Qgbj10aGlzLmRhdGFbdCozK2VdO3JldHVybiBuPT09LTE/LTE6biUzfWdldERpc2pvaW50U2libGluZ1RyaWFuZ2xlSW5kaWNlcyh0LGUpe2NvbnN0IG49dCozK2Uscz10aGlzLmRpc2pvaW50Q29ubmVjdGlvbnMuZ2V0KG4pO3JldHVybiBzP3MubWFwKHI9Pn5+KHIvMykpOltdfWdldERpc2pvaW50U2libGluZ0VkZ2VJbmRpY2VzKHQsZSl7Y29uc3Qgbj10KjMrZSxzPXRoaXMuZGlzam9pbnRDb25uZWN0aW9ucy5nZXQobik7cmV0dXJuIHM/cy5tYXAocj0+ciUzKTpbXX1pc0Z1bGx5Q29ubmVjdGVkKCl7cmV0dXJuIHRoaXMudW5tYXRjaGVkRWRnZXM9PT0wfXVwZGF0ZUZyb20odCl7Y29uc3R7dXNlQWxsQXR0cmlidXRlczplLHVzZURyYXdSYW5nZTpuLG1hdGNoRGlzam9pbnRFZGdlczpzLGRlZ2VuZXJhdGVFcHNpbG9uOnJ9PXRoaXMsbz1lP3c6YixhPW5ldyBNYXAse2F0dHJpYnV0ZXM6Y309dCxsPWU/T2JqZWN0LmtleXMoYyk6bnVsbCxoPXQuaW5kZXgsdT1jLnBvc2l0aW9uO2xldCBmPWFhKHQpO2NvbnN0IGQ9ZjtsZXQgcD0wO24mJihwPXQuZHJhd1JhbmdlLnN0YXJ0LHQuZHJhd1JhbmdlLmNvdW50IT09MS8wJiYoZj1+fih0LmRyYXdSYW5nZS5jb3VudC8zKSkpO2xldCB5PXRoaXMuZGF0YTsoIXl8fHkubGVuZ3RoPDMqZCkmJih5PW5ldyBJbnQzMkFycmF5KDMqZCkpLHkuZmlsbCgtMSk7bGV0IG09MCxnPW5ldyBTZXQ7Zm9yKGxldCB4PXAsTT1mKjMrcDt4PE07eCs9Myl7Y29uc3QgQT14O2ZvcihsZXQgUz0wO1M8MztTKyspe2xldCBfPUErUztoJiYoXz1oLmdldFgoXykpLHVhW1NdPW8oXyl9Zm9yKGxldCBTPTA7UzwzO1MrKyl7Y29uc3QgXz0oUysxKSUzLEU9dWFbU10sej11YVtfXSx2PWAke3p9XyR7RX1gO2lmKGEuaGFzKHYpKXtjb25zdCBDPUErUyxQPWEuZ2V0KHYpO3lbQ109UCx5W1BdPUMsYS5kZWxldGUodiksbSs9MixnLmRlbGV0ZShQKX1lbHNle2NvbnN0IEM9YCR7RX1fJHt6fWAsUD1BK1M7YS5zZXQoQyxQKSxnLmFkZChQKX19fWlmKHMpe2NvbnN0e2ZyYWdtZW50TWFwOngsZGlzam9pbnRDb25uZWN0aXZpdHlNYXA6TX09dzAodCxnLHIpO2cuY2xlYXIoKSx4LmZvckVhY2goKHtmb3J3YXJkOkEscmV2ZXJzZTpTfSk9PntBLmZvckVhY2goKHtpbmRleDpffSk9PmcuYWRkKF8pKSxTLmZvckVhY2goKHtpbmRleDpffSk9PmcuYWRkKF8pKX0pLHRoaXMudW5tYXRjaGVkRGlzam9pbnRFZGdlcz14LHRoaXMuZGlzam9pbnRDb25uZWN0aW9ucz1NLG09ZiozLWcuc2l6ZX10aGlzLm1hdGNoZWRFZGdlcz1tLHRoaXMudW5tYXRjaGVkRWRnZXM9Zy5zaXplLHRoaXMuZGF0YT15O2Z1bmN0aW9uIGIoeCl7cmV0dXJuIGhhLmZyb21CdWZmZXJBdHRyaWJ1dGUodSx4KSxBbChoYSl9ZnVuY3Rpb24gdyh4KXtsZXQgTT0iIjtmb3IobGV0IEE9MCxTPWwubGVuZ3RoO0E8UztBKyspe2NvbnN0IF89Y1tsW0FdXTtsZXQgRTtzd2l0Y2goXy5pdGVtU2l6ZSl7Y2FzZSAxOkU9d2UoXy5nZXRYKHgpKTticmVhaztjYXNlIDI6RT1vMChiMC5mcm9tQnVmZmVyQXR0cmlidXRlKF8seCkpO2JyZWFrO2Nhc2UgMzpFPUFsKGhhLmZyb21CdWZmZXJBdHRyaWJ1dGUoXyx4KSk7YnJlYWs7Y2FzZSA0OkU9YTAoTTAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShfLHgpKTticmVha31NIT09IiImJihNKz0ifCIpLE0rPUV9cmV0dXJuIE19fX1jbGFzcyBacyBleHRlbmRzIGJme2NvbnN0cnVjdG9yKC4uLnQpe3N1cGVyKC4uLnQpLHRoaXMuaXNCcnVzaD0hMCx0aGlzLl9wcmV2aW91c01hdHJpeD1uZXcgc3QsdGhpcy5fcHJldmlvdXNNYXRyaXguZWxlbWVudHMuZmlsbCgwKX1tYXJrVXBkYXRlZCgpe3RoaXMuX3ByZXZpb3VzTWF0cml4LmNvcHkodGhpcy5tYXRyaXgpfWlzRGlydHkoKXtjb25zdHttYXRyaXg6dCxfcHJldmlvdXNNYXRyaXg6ZX09dGhpcyxuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzO2ZvcihsZXQgcj0wO3I8MTY7cisrKWlmKG5bcl0hPT1zW3JdKXJldHVybiEwO3JldHVybiExfXByZXBhcmVHZW9tZXRyeSgpe2NvbnN0IHQ9dGhpcy5nZW9tZXRyeSxlPXQuYXR0cmlidXRlcyxuPVNsKCk7aWYobilmb3IoY29uc3QgcyBpbiBlKXtjb25zdCByPWVbc107aWYoci5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlKXRocm93IG5ldyBFcnJvcigiQnJ1c2g6IEludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlcyBhcmUgbm90IHN1cHBvcnRlZC4iKTtyLmFycmF5PWwwKHIuYXJyYXkpfWlmKHQuYm91bmRzVHJlZXx8KHUwKHQse3VzZVNoYXJlZEFycmF5QnVmZmVyOm59KSx0LmJvdW5kc1RyZWU9bmV3IG9hKHQse21heExlYWZUcmlzOjMsaW5kaXJlY3Q6ITAsdXNlU2hhcmVkQXJyYXlCdWZmZXI6bn0pKSx0LmhhbGZFZGdlc3x8KHQuaGFsZkVkZ2VzPW5ldyBBMCh0KSksIXQuZ3JvdXBJbmRpY2VzKXtjb25zdCBzPWFhKHQpLHI9bmV3IFVpbnQxNkFycmF5KHMpLG89dC5ncm91cHM7Zm9yKGxldCBhPTAsYz1vLmxlbmd0aDthPGM7YSsrKXtjb25zdHtzdGFydDpsLGNvdW50Omh9PW9bYV07Zm9yKGxldCB1PWwvMyxmPShsK2gpLzM7dTxmO3UrKylyW3VdPWF9dC5ncm91cEluZGljZXM9cn19ZGlzcG9zZUNhY2hlRGF0YSgpe2NvbnN0e2dlb21ldHJ5OnR9PXRoaXM7dC5oYWxmRWRnZXM9bnVsbCx0LmJvdW5kc1RyZWU9bnVsbCx0Lmdyb3VwSW5kaWNlcz1udWxsfX1jb25zdCBTMD0xZS0xNCxmYT1uZXcgVCxFbD1uZXcgVCxQbD1uZXcgVDtmdW5jdGlvbiBzbihpLHQ9UzApe2ZhLnN1YlZlY3RvcnMoaS5iLGkuYSksRWwuc3ViVmVjdG9ycyhpLmMsaS5hKSxQbC5zdWJWZWN0b3JzKGkuYixpLmMpO2NvbnN0IGU9ZmEuYW5nbGVUbyhFbCksbj1mYS5hbmdsZVRvKFBsKSxzPU1hdGguUEktZS1uO3JldHVybiBNYXRoLmFicyhlKTx0fHxNYXRoLmFicyhuKTx0fHxNYXRoLmFicyhzKTx0fHxpLmEuZGlzdGFuY2VUb1NxdWFyZWQoaS5iKTx0fHxpLmEuZGlzdGFuY2VUb1NxdWFyZWQoaS5jKTx0fHxpLmIuZGlzdGFuY2VUb1NxdWFyZWQoaS5jKTx0fWNvbnN0IGRhPTFlLTEwLERpPTFlLTEwLF8wPTFlLTEwLGtlPW5ldyBRdCxmdD1uZXcgUXQsTmU9bmV3IFQscGE9bmV3IFQsQ2w9bmV3IFQsWHM9bmV3IHpvLHlhPW5ldyBuZTtjbGFzcyB2MHtjb25zdHJ1Y3Rvcigpe3RoaXMuX3Bvb2w9W10sdGhpcy5faW5kZXg9MH1nZXRUcmlhbmdsZSgpe3JldHVybiB0aGlzLl9pbmRleD49dGhpcy5fcG9vbC5sZW5ndGgmJnRoaXMuX3Bvb2wucHVzaChuZXcgZXQpLHRoaXMuX3Bvb2xbdGhpcy5faW5kZXgrK119Y2xlYXIoKXt0aGlzLl9pbmRleD0wfXJlc2V0KCl7dGhpcy5fcG9vbC5sZW5ndGg9MCx0aGlzLl9pbmRleD0wfX1jbGFzcyB6MHtjb25zdHJ1Y3Rvcigpe3RoaXMudHJpYW5nbGVQb29sPW5ldyB2MCx0aGlzLnRyaWFuZ2xlcz1bXSx0aGlzLm5vcm1hbD1uZXcgVCx0aGlzLmNvcGxhbmFyVHJpYW5nbGVVc2VkPSExfWluaXRpYWxpemUodCl7dGhpcy5yZXNldCgpO2NvbnN0e3RyaWFuZ2xlczplLHRyaWFuZ2xlUG9vbDpuLG5vcm1hbDpzfT10aGlzO2lmKEFycmF5LmlzQXJyYXkodCkpZm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXRbcl07aWYocj09PTApYS5nZXROb3JtYWwocyk7ZWxzZSBpZihNYXRoLmFicygxLWEuZ2V0Tm9ybWFsKE5lKS5kb3QocykpPmRhKXRocm93IG5ldyBFcnJvcigiVHJpYW5nbGUgU3BsaXR0ZXI6IENhbm5vdCBpbml0aWFsaXplIHdpdGggdHJpYW5nbGVzIHRoYXQgaGF2ZSBkaWZmZXJlbnQgbm9ybWFscy4iKTtjb25zdCBjPW4uZ2V0VHJpYW5nbGUoKTtjLmNvcHkoYSksZS5wdXNoKGMpfWVsc2V7dC5nZXROb3JtYWwocyk7Y29uc3Qgcj1uLmdldFRyaWFuZ2xlKCk7ci5jb3B5KHQpLGUucHVzaChyKX19c3BsaXRCeVRyaWFuZ2xlKHQpe2NvbnN0e25vcm1hbDplLHRyaWFuZ2xlczpufT10aGlzO2lmKHQuZ2V0Tm9ybWFsKHBhKS5ub3JtYWxpemUoKSxNYXRoLmFicygxLU1hdGguYWJzKHBhLmRvdChlKSkpPF8wKXt0aGlzLmNvcGxhbmFyVHJpYW5nbGVVc2VkPSEwO2ZvcihsZXQgcj0wLG89bi5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1uW3JdO2EuY29wbGFuYXJDb3VudD0wfWNvbnN0IHM9W3QuYSx0LmIsdC5jXTtmb3IobGV0IHI9MDtyPDM7cisrKXtjb25zdCBvPShyKzEpJTMsYT1zW3JdLGM9c1tvXTtOZS5zdWJWZWN0b3JzKGMsYSkubm9ybWFsaXplKCksQ2wuY3Jvc3NWZWN0b3JzKHBhLE5lKSxYcy5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChDbCxhKSx0aGlzLnNwbGl0QnlQbGFuZShYcyx0KX19ZWxzZSB0LmdldFBsYW5lKFhzKSx0aGlzLnNwbGl0QnlQbGFuZShYcyx0KX1zcGxpdEJ5UGxhbmUodCxlKXtjb25zdHt0cmlhbmdsZXM6bix0cmlhbmdsZVBvb2w6c309dGhpczt5YS5jb3B5KGUpLHlhLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgcj0wLG89bi5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1uW3JdO2lmKCF5YS5pbnRlcnNlY3RzVHJpYW5nbGUoYSxrZSwhMCkpY29udGludWU7Y29uc3R7YTpjLGI6bCxjOmh9PWE7bGV0IHU9MCxmPS0xLGQ9ITEscD1bXSx5PVtdO2NvbnN0IG09W2MsbCxoXTtmb3IobGV0IGc9MDtnPDM7ZysrKXtjb25zdCBiPShnKzEpJTM7a2Uuc3RhcnQuY29weShtW2ddKSxrZS5lbmQuY29weShtW2JdKTtjb25zdCB3PXQuZGlzdGFuY2VUb1BvaW50KGtlLnN0YXJ0KSx4PXQuZGlzdGFuY2VUb1BvaW50KGtlLmVuZCk7aWYoTWF0aC5hYnModyk8RGkmJk1hdGguYWJzKHgpPERpKXtkPSEwO2JyZWFrfWlmKHc+MD9wLnB1c2goZyk6eS5wdXNoKGcpLE1hdGguYWJzKHcpPERpKWNvbnRpbnVlO2xldCBNPSEhdC5pbnRlcnNlY3RMaW5lKGtlLE5lKTshTSYmTWF0aC5hYnMoeCk8RGkmJihOZS5jb3B5KGtlLmVuZCksTT0hMCksTSYmIShOZS5kaXN0YW5jZVRvKGtlLnN0YXJ0KTxkYSkmJihOZS5kaXN0YW5jZVRvKGtlLmVuZCk8ZGEmJihmPWcpLHU9PT0wP2Z0LnN0YXJ0LmNvcHkoTmUpOmZ0LmVuZC5jb3B5KE5lKSx1KyspfWlmKCFkJiZ1PT09MiYmZnQuZGlzdGFuY2UoKT5EaSlpZihmIT09LTEpe2Y9KGYrMSklMztsZXQgZz0wO2c9PT1mJiYoZz0oZysxKSUzKTtsZXQgYj1nKzE7Yj09PWYmJihiPShiKzEpJTMpO2NvbnN0IHc9cy5nZXRUcmlhbmdsZSgpO3cuYS5jb3B5KG1bYl0pLHcuYi5jb3B5KGZ0LmVuZCksdy5jLmNvcHkoZnQuc3RhcnQpLHNuKHcpfHxuLnB1c2godyksYS5hLmNvcHkobVtnXSksYS5iLmNvcHkoZnQuc3RhcnQpLGEuYy5jb3B5KGZ0LmVuZCksc24oYSkmJihuLnNwbGljZShyLDEpLHItLSxvLS0pfWVsc2V7Y29uc3QgZz1wLmxlbmd0aD49Mj95WzBdOnBbMF07aWYoZz09PTApe2xldCBBPWZ0LnN0YXJ0O2Z0LnN0YXJ0PWZ0LmVuZCxmdC5lbmQ9QX1jb25zdCBiPShnKzEpJTMsdz0oZysyKSUzLHg9cy5nZXRUcmlhbmdsZSgpLE09cy5nZXRUcmlhbmdsZSgpO21bYl0uZGlzdGFuY2VUb1NxdWFyZWQoZnQuc3RhcnQpPG1bd10uZGlzdGFuY2VUb1NxdWFyZWQoZnQuZW5kKT8oeC5hLmNvcHkobVtiXSkseC5iLmNvcHkoZnQuc3RhcnQpLHguYy5jb3B5KGZ0LmVuZCksTS5hLmNvcHkobVtiXSksTS5iLmNvcHkobVt3XSksTS5jLmNvcHkoZnQuc3RhcnQpKTooeC5hLmNvcHkobVt3XSkseC5iLmNvcHkoZnQuc3RhcnQpLHguYy5jb3B5KGZ0LmVuZCksTS5hLmNvcHkobVtiXSksTS5iLmNvcHkobVt3XSksTS5jLmNvcHkoZnQuZW5kKSksYS5hLmNvcHkobVtnXSksYS5iLmNvcHkoZnQuZW5kKSxhLmMuY29weShmdC5zdGFydCksc24oeCl8fG4ucHVzaCh4KSxzbihNKXx8bi5wdXNoKE0pLHNuKGEpJiYobi5zcGxpY2UociwxKSxyLS0sby0tKX1lbHNlIHU9PT0zJiZjb25zb2xlLndhcm4oIlRyaWFuZ2xlQ2xpcHBlcjogQ29wbGFuYXIgY2xpcCBub3QgaGFuZGxlZCIpfX1yZXNldCgpe3RoaXMudHJpYW5nbGVzLmxlbmd0aD0wLHRoaXMudHJpYW5nbGVQb29sLmNsZWFyKCksdGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMX19ZnVuY3Rpb24gVDAoaSl7cmV0dXJuIGk9fn5pLGkrNC1pJTR9Y2xhc3MgQmx7Y29uc3RydWN0b3IodCxlPTUwMCl7dGhpcy5leHBhbnNpb25GYWN0b3I9MS41LHRoaXMudHlwZT10LHRoaXMubGVuZ3RoPTAsdGhpcy5hcnJheT1udWxsLHRoaXMuc2V0U2l6ZShlKX1zZXRUeXBlKHQpe2lmKHRoaXMubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoIlR5cGVCYWNrZWRBcnJheTogQ2Fubm90IGNoYW5nZSB0aGUgdHlwZSB3aGlsZSB0aGVyZSBpcyB1c2VkIGRhdGEgaW4gdGhlIGJ1ZmZlci4iKTtjb25zdCBlPXRoaXMuYXJyYXkuYnVmZmVyO3RoaXMuYXJyYXk9bmV3IHQoZSksdGhpcy50eXBlPXR9c2V0U2l6ZSh0KXtpZih0aGlzLmFycmF5JiZ0PT09dGhpcy5hcnJheS5sZW5ndGgpcmV0dXJuO2NvbnN0IGU9dGhpcy50eXBlLG49U2woKT9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPW5ldyBlKG5ldyBuKFQwKHQqZS5CWVRFU19QRVJfRUxFTUVOVCkpKTt0aGlzLmFycmF5JiZzLnNldCh0aGlzLmFycmF5LDApLHRoaXMuYXJyYXk9c31leHBhbmQoKXtjb25zdHthcnJheTp0LGV4cGFuc2lvbkZhY3RvcjplfT10aGlzO3RoaXMuc2V0U2l6ZSh0Lmxlbmd0aCplKX1wdXNoKC4uLnQpe2xldHthcnJheTplLGxlbmd0aDpufT10aGlzO24rdC5sZW5ndGg+ZS5sZW5ndGgmJih0aGlzLmV4cGFuZCgpLGU9dGhpcy5hcnJheSk7Zm9yKGxldCBzPTAscj10Lmxlbmd0aDtzPHI7cysrKWVbbitzXT10W3NdO3RoaXMubGVuZ3RoKz10Lmxlbmd0aH1jbGVhcigpe3RoaXMubGVuZ3RoPTB9fWNsYXNzIEUwe2NvbnN0cnVjdG9yKCl7dGhpcy5ncm91cEF0dHJpYnV0ZXM9W3t9XSx0aGlzLmdyb3VwQ291bnQ9MH1nZXRUeXBlKHQpe3JldHVybiB0aGlzLmdyb3VwQXR0cmlidXRlc1swXVt0XS50eXBlfWdldEl0ZW1TaXplKHQpe3JldHVybiB0aGlzLmdyb3VwQXR0cmlidXRlc1swXVt0XS5pdGVtU2l6ZX1nZXROb3JtYWxpemVkKHQpe3JldHVybiB0aGlzLmdyb3VwQXR0cmlidXRlc1swXVt0XS5ub3JtYWxpemVkfWdldENvdW50KHQpe2lmKHRoaXMuZ3JvdXBDb3VudDw9dClyZXR1cm4gMDtjb25zdCBlPXRoaXMuZ2V0R3JvdXBBdHRyQXJyYXkoInBvc2l0aW9uIix0KTtyZXR1cm4gZS5sZW5ndGgvZS5pdGVtU2l6ZX1nZXRUb3RhbExlbmd0aCh0KXtjb25zdHtncm91cENvdW50OmUsZ3JvdXBBdHRyaWJ1dGVzOm59PXRoaXM7bGV0IHM9MDtmb3IobGV0IHI9MDtyPGU7cisrKXtjb25zdCBvPW5bcl07cys9b1t0XS5sZW5ndGh9cmV0dXJuIHN9Z2V0R3JvdXBBdHRyU2V0KHQ9MCl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOmV9PXRoaXM7aWYoZVt0XSlyZXR1cm4gdGhpcy5ncm91cENvdW50PU1hdGgubWF4KHRoaXMuZ3JvdXBDb3VudCx0KzEpLGVbdF07Y29uc3Qgbj1lWzBdO2Zvcih0aGlzLmdyb3VwQ291bnQ9TWF0aC5tYXgodGhpcy5ncm91cENvdW50LHQrMSk7dD49ZS5sZW5ndGg7KXtjb25zdCBzPXt9O2UucHVzaChzKTtmb3IoY29uc3QgciBpbiBuKXtjb25zdCBvPW5bcl0sYT1uZXcgQmwoby50eXBlKTthLml0ZW1TaXplPW8uaXRlbVNpemUsYS5ub3JtYWxpemVkPW8ubm9ybWFsaXplZCxzW3JdPWF9fXJldHVybiBlW3RdfWdldEdyb3VwQXR0ckFycmF5KHQsZT0wKXtjb25zdHtncm91cEF0dHJpYnV0ZXM6bn09dGhpcztpZighblswXVt0XSl0aHJvdyBuZXcgRXJyb3IoYFR5cGVkQXR0cmlidXRlRGF0YTogQXR0cmlidXRlIHdpdGggIiR7dH0iIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZGApO3JldHVybiB0aGlzLmdldEdyb3VwQXR0clNldChlKVt0XX1pbml0aWFsaXplQXJyYXkodCxlLG4scyl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOnJ9PXRoaXMsYT1yWzBdW3RdO2lmKGEpe2lmKGEudHlwZSE9PWUpZm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPXJbY11bdF07aC5zZXRUeXBlKGUpLGguaXRlbVNpemU9bixoLm5vcm1hbGl6ZWQ9c319ZWxzZSBmb3IobGV0IGM9MCxsPXIubGVuZ3RoO2M8bDtjKyspe2NvbnN0IGg9bmV3IEJsKGUpO2guaXRlbVNpemU9bixoLm5vcm1hbGl6ZWQ9cyxyW2NdW3RdPWh9fWNsZWFyKCl7dGhpcy5ncm91cENvdW50PTA7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOnR9PXRoaXM7dC5mb3JFYWNoKGU9Pntmb3IoY29uc3QgbiBpbiBlKWVbbl0uY2xlYXIoKX0pfWRlbGV0ZSh0KXt0aGlzLmdyb3VwQXR0cmlidXRlcy5mb3JFYWNoKGU9PntkZWxldGUgZVt0XX0pfXJlc2V0KCl7dGhpcy5ncm91cEF0dHJpYnV0ZXM9W10sdGhpcy5ncm91cENvdW50PTB9fWNsYXNzIEZse2NvbnN0cnVjdG9yKCl7dGhpcy5pbnRlcnNlY3Rpb25TZXQ9e30sdGhpcy5pZHM9W119YWRkKHQsZSl7Y29uc3R7aW50ZXJzZWN0aW9uU2V0Om4saWRzOnN9PXRoaXM7blt0XXx8KG5bdF09W10scy5wdXNoKHQpKSxuW3RdLnB1c2goZSl9fWNvbnN0IFAwPTAsQzA9MSxCMD0yLElsPTMsRjA9NCxrbD01LE5sPTYsc2U9bmV3IGZvLFJsPW5ldyBzdCxUdD1uZXcgZXQsUmU9bmV3IFQsTGw9bmV3IFl0LE9sPW5ldyBZdCxEbD1uZXcgWXQsbWE9bmV3IFl0LEpzPW5ldyBZdCxZcz1uZXcgWXQsJGw9bmV3IFF0LGdhPW5ldyBULHhhPTFlLTgsSTA9MWUtMTUseG49LTEsd249MSxqcz0tMixRcz0yLCRpPTAsYm49MSx3YT0yLGswPTFlLTE0O2xldCBLcz1udWxsO2Z1bmN0aW9uIFZsKGkpe0tzPWl9ZnVuY3Rpb24gVWwoaSx0KXtpLmdldE1pZHBvaW50KHNlLm9yaWdpbiksaS5nZXROb3JtYWwoc2UuZGlyZWN0aW9uKTtjb25zdCBlPXQucmF5Y2FzdEZpcnN0KHNlLDIpO3JldHVybiEhKGUmJnNlLmRpcmVjdGlvbi5kb3QoZS5mYWNlLm5vcm1hbCk+MCk/eG46d259ZnVuY3Rpb24gTjAoaSx0KXtmdW5jdGlvbiBlKCl7cmV0dXJuIE1hdGgucmFuZG9tKCktLjV9aS5nZXROb3JtYWwoZ2EpLHNlLmRpcmVjdGlvbi5jb3B5KGdhKSxpLmdldE1pZHBvaW50KHNlLm9yaWdpbik7Y29uc3Qgbj0zO2xldCBzPTAscj0xLzA7Zm9yKGxldCBvPTA7bzxuO28rKyl7c2UuZGlyZWN0aW9uLngrPWUoKSp4YSxzZS5kaXJlY3Rpb24ueSs9ZSgpKnhhLHNlLmRpcmVjdGlvbi56Kz1lKCkqeGEsc2UuZGlyZWN0aW9uLm11bHRpcGx5U2NhbGFyKC0xKTtjb25zdCBhPXQucmF5Y2FzdEZpcnN0KHNlLDIpO2lmKCEhKGEmJnNlLmRpcmVjdGlvbi5kb3QoYS5mYWNlLm5vcm1hbCk+MCkmJnMrKyxhIT09bnVsbCYmKHI9TWF0aC5taW4ocixhLmRpc3RhbmNlKSkscjw9STApcmV0dXJuIGEuZmFjZS5ub3JtYWwuZG90KGdhKT4wP1FzOmpzO2lmKHMvbj4uNXx8KG8tcysxKS9uPi41KWJyZWFrfXJldHVybiBzL24+LjU/eG46d259ZnVuY3Rpb24gUjAoaSx0KXtjb25zdCBlPW5ldyBGbCxuPW5ldyBGbDtyZXR1cm4gUmwuY29weShpLm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseSh0Lm1hdHJpeFdvcmxkKSxpLmdlb21ldHJ5LmJvdW5kc1RyZWUuYnZoY2FzdCh0Lmdlb21ldHJ5LmJvdW5kc1RyZWUsUmwse2ludGVyc2VjdHNUcmlhbmdsZXMocyxyLG8sYSl7aWYoIXNuKHMpJiYhc24ocikpe2xldCBjPXMuaW50ZXJzZWN0c1RyaWFuZ2xlKHIsJGwsITApO2lmKCFjKXtjb25zdCBsPXMucGxhbmUsaD1yLnBsYW5lLHU9bC5ub3JtYWwsZj1oLm5vcm1hbDt1LmRvdChmKT09PTEmJk1hdGguYWJzKGwuY29uc3RhbnQtaC5jb25zdGFudCk8azAmJihjPSEwKX1pZihjKXtsZXQgbD1pLmdlb21ldHJ5LmJvdW5kc1RyZWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgobyksaD10Lmdlb21ldHJ5LmJvdW5kc1RyZWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoYSk7ZS5hZGQobCxoKSxuLmFkZChoLGwpLEtzJiYoS3MuYWRkRWRnZSgkbCksS3MuYWRkSW50ZXJzZWN0aW5nVHJpYW5nbGVzKG8scyxhLHIpKX19cmV0dXJuITF9fSkse2FJbnRlcnNlY3Rpb25zOmUsYkludGVyc2VjdGlvbnM6bn19ZnVuY3Rpb24gTDAoaSx0LGUsbixzLHIsbz0hMSl7Y29uc3QgYT1lLmF0dHJpYnV0ZXMsYz1lLmluZGV4LGw9aSozLGg9Yy5nZXRYKGwrMCksdT1jLmdldFgobCsxKSxmPWMuZ2V0WChsKzIpO2Zvcihjb25zdCBkIGluIHIpe2NvbnN0IHA9YVtkXSx5PXJbZF07aWYoIShkIGluIGEpKXRocm93IG5ldyBFcnJvcihgQ1NHIE9wZXJhdGlvbnM6IEF0dHJpYnV0ZSAke2R9IG5vdCBhdmFpbGFibGUgb24gZ2VvbWV0cnkuYCk7Y29uc3QgbT1wLml0ZW1TaXplO2Q9PT0icG9zaXRpb24iPyhUdC5hLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKS5hcHBseU1hdHJpeDQobiksVHQuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSkuYXBwbHlNYXRyaXg0KG4pLFR0LmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGYpLmFwcGx5TWF0cml4NChuKSxiYShUdC5hLFR0LmIsVHQuYyx0LDMseSxvKSk6ZD09PSJub3JtYWwiPyhUdC5hLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKS5hcHBseU5vcm1hbE1hdHJpeChzKSxUdC5iLmZyb21CdWZmZXJBdHRyaWJ1dGUocCx1KS5hcHBseU5vcm1hbE1hdHJpeChzKSxUdC5jLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxmKS5hcHBseU5vcm1hbE1hdHJpeChzKSxvJiYoVHQuYS5tdWx0aXBseVNjYWxhcigtMSksVHQuYi5tdWx0aXBseVNjYWxhcigtMSksVHQuYy5tdWx0aXBseVNjYWxhcigtMSkpLGJhKFR0LmEsVHQuYixUdC5jLHQsMyx5LG8sITApKTooTGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGgpLE9sLmZyb21CdWZmZXJBdHRyaWJ1dGUocCx1KSxEbC5mcm9tQnVmZmVyQXR0cmlidXRlKHAsZiksYmEoTGwsT2wsRGwsdCxtLHksbykpfX1mdW5jdGlvbiBPMChpLHQsZSxuLHMscixvLGE9ITEpe01hKGksbixzLHIsbyxhKSxNYShhP2U6dCxuLHMscixvLGEpLE1hKGE/dDplLG4scyxyLG8sYSl9ZnVuY3Rpb24gcWwoaSx0LGU9ITEpe3N3aXRjaChpKXtjYXNlIFAwOmlmKHQ9PT13bnx8dD09PVFzJiYhZSlyZXR1cm4gYm47YnJlYWs7Y2FzZSBDMDppZihlKXtpZih0PT09eG4pcmV0dXJuICRpfWVsc2UgaWYodD09PXdufHx0PT09anMpcmV0dXJuIGJuO2JyZWFrO2Nhc2UgQjA6aWYoZSl7aWYodD09PXdufHx0PT09anMpcmV0dXJuIGJufWVsc2UgaWYodD09PXhuKXJldHVybiAkaTticmVhaztjYXNlIEYwOmlmKHQ9PT14bilyZXR1cm4gJGk7aWYodD09PXduKXJldHVybiBibjticmVhaztjYXNlIElsOmlmKHQ9PT14bnx8dD09PVFzJiYhZSlyZXR1cm4gYm47YnJlYWs7Y2FzZSBrbDppZighZSYmKHQ9PT13bnx8dD09PWpzKSlyZXR1cm4gYm47YnJlYWs7Y2FzZSBObDppZighZSYmKHQ9PT14bnx8dD09PVFzKSlyZXR1cm4gYm47YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBDU0cgb3BlcmF0aW9uIGVudW0gIiR7aX0iLmApfXJldHVybiB3YX1mdW5jdGlvbiBiYShpLHQsZSxuLHMscixvPSExLGE9ITEpe2NvbnN0IGM9bD0+e3IucHVzaChsLngpLHM+MSYmci5wdXNoKGwueSkscz4yJiZyLnB1c2gobC56KSxzPjMmJnIucHVzaChsLncpfTttYS5zZXQoMCwwLDAsMCkuYWRkU2NhbGVkVmVjdG9yKGksbi5hLngpLmFkZFNjYWxlZFZlY3Rvcih0LG4uYS55KS5hZGRTY2FsZWRWZWN0b3IoZSxuLmEueiksSnMuc2V0KDAsMCwwLDApLmFkZFNjYWxlZFZlY3RvcihpLG4uYi54KS5hZGRTY2FsZWRWZWN0b3IodCxuLmIueSkuYWRkU2NhbGVkVmVjdG9yKGUsbi5iLnopLFlzLnNldCgwLDAsMCwwKS5hZGRTY2FsZWRWZWN0b3IoaSxuLmMueCkuYWRkU2NhbGVkVmVjdG9yKHQsbi5jLnkpLmFkZFNjYWxlZFZlY3RvcihlLG4uYy56KSxhJiYobWEubm9ybWFsaXplKCksSnMubm9ybWFsaXplKCksWXMubm9ybWFsaXplKCkpLGMobWEpLG8/KGMoWXMpLGMoSnMpKTooYyhKcyksYyhZcykpfWZ1bmN0aW9uIE1hKGksdCxlLG4scyxyPSExKXtmb3IoY29uc3QgbyBpbiBzKXtjb25zdCBhPXRbb10sYz1zW29dO2lmKCEobyBpbiB0KSl0aHJvdyBuZXcgRXJyb3IoYENTRyBPcGVyYXRpb25zOiBBdHRyaWJ1dGUgJHtvfSBubyBhdmFpbGFibGUgb24gZ2VvbWV0cnkuYCk7Y29uc3QgbD1hLml0ZW1TaXplO289PT0icG9zaXRpb24iPyhSZS5mcm9tQnVmZmVyQXR0cmlidXRlKGEsaSkuYXBwbHlNYXRyaXg0KGUpLGMucHVzaChSZS54LFJlLnksUmUueikpOm89PT0ibm9ybWFsIj8oUmUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGkpLmFwcGx5Tm9ybWFsTWF0cml4KG4pLHImJlJlLm11bHRpcGx5U2NhbGFyKC0xKSxjLnB1c2goUmUueCxSZS55LFJlLnopKTooYy5wdXNoKGEuZ2V0WChpKSksbD4xJiZjLnB1c2goYS5nZXRZKGkpKSxsPjImJmMucHVzaChhLmdldFooaSkpLGw+MyYmYy5wdXNoKGEuZ2V0VyhpKSkpfX1jbGFzcyBEMHtjb25zdHJ1Y3Rvcih0KXt0aGlzLnRyaWFuZ2xlPW5ldyBldCgpLmNvcHkodCksdGhpcy5pbnRlcnNlY3RzPXt9fWFkZFRyaWFuZ2xlKHQsZSl7dGhpcy5pbnRlcnNlY3RzW3RdPW5ldyBldCgpLmNvcHkoZSl9Z2V0SW50ZXJzZWN0QXJyYXkoKXtjb25zdCB0PVtdLHtpbnRlcnNlY3RzOmV9PXRoaXM7Zm9yKGNvbnN0IG4gaW4gZSl0LnB1c2goZVtuXSk7cmV0dXJuIHR9fWNsYXNzIEhse2NvbnN0cnVjdG9yKCl7dGhpcy5kYXRhPXt9fWFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKHQsZSxuLHMpe2NvbnN0e2RhdGE6cn09dGhpcztyW3RdfHwoclt0XT1uZXcgRDAoZSkpLHJbdF0uYWRkVHJpYW5nbGUobixzKX1nZXRUcmlhbmdsZXNBc0FycmF5KHQ9bnVsbCl7Y29uc3R7ZGF0YTplfT10aGlzLG49W107aWYodCE9PW51bGwpdCBpbiBlJiZuLnB1c2goZVt0XS50cmlhbmdsZSk7ZWxzZSBmb3IoY29uc3QgcyBpbiBlKW4ucHVzaChlW3NdLnRyaWFuZ2xlKTtyZXR1cm4gbn1nZXRUcmlhbmdsZUluZGljZXMoKXtyZXR1cm4gT2JqZWN0LmtleXModGhpcy5kYXRhKS5tYXAodD0+cGFyc2VJbnQodCkpfWdldEludGVyc2VjdGlvbkluZGljZXModCl7Y29uc3R7ZGF0YTplfT10aGlzO3JldHVybiBlW3RdP09iamVjdC5rZXlzKGVbdF0uaW50ZXJzZWN0cykubWFwKG49PnBhcnNlSW50KG4pKTpbXX1nZXRJbnRlcnNlY3Rpb25zQXNBcnJheSh0PW51bGwsZT1udWxsKXtjb25zdHtkYXRhOm59PXRoaXMscz1uZXcgU2V0LHI9W10sbz1hPT57aWYoblthXSlpZihlIT09bnVsbCluW2FdLmludGVyc2VjdHNbZV0mJnIucHVzaChuW2FdLmludGVyc2VjdHNbZV0pO2Vsc2V7Y29uc3QgYz1uW2FdLmludGVyc2VjdHM7Zm9yKGNvbnN0IGwgaW4gYylzLmhhcyhsKXx8KHMuYWRkKGwpLHIucHVzaChjW2xdKSl9fTtpZih0IT09bnVsbClvKHQpO2Vsc2UgZm9yKGNvbnN0IGEgaW4gbilvKGEpO3JldHVybiByfXJlc2V0KCl7dGhpcy5kYXRhPXt9fX1jbGFzcyAkMHtjb25zdHJ1Y3Rvcigpe3RoaXMuZW5hYmxlZD0hMSx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0E9bmV3IEhsLHRoaXMudHJpYW5nbGVJbnRlcnNlY3RzQj1uZXcgSGwsdGhpcy5pbnRlcnNlY3Rpb25FZGdlcz1bXX1hZGRJbnRlcnNlY3RpbmdUcmlhbmdsZXModCxlLG4scyl7Y29uc3R7dHJpYW5nbGVJbnRlcnNlY3RzQTpyLHRyaWFuZ2xlSW50ZXJzZWN0c0I6b309dGhpcztyLmFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKHQsZSxuLHMpLG8uYWRkVHJpYW5nbGVJbnRlcnNlY3Rpb24obixzLHQsZSl9YWRkRWRnZSh0KXt0aGlzLmludGVyc2VjdGlvbkVkZ2VzLnB1c2godC5jbG9uZSgpKX1yZXNldCgpe3RoaXMudHJpYW5nbGVJbnRlcnNlY3RzQS5yZXNldCgpLHRoaXMudHJpYW5nbGVJbnRlcnNlY3RzQi5yZXNldCgpLHRoaXMuaW50ZXJzZWN0aW9uRWRnZXM9W119aW5pdCgpe3RoaXMuZW5hYmxlZCYmKHRoaXMucmVzZXQoKSxWbCh0aGlzKSl9Y29tcGxldGUoKXt0aGlzLmVuYWJsZWQmJlZsKG51bGwpfX1jb25zdCBybj1uZXcgc3QsdHI9bmV3IGdlLE1uPW5ldyBldCxlcj1uZXcgZXQsb249bmV3IGV0LG5yPW5ldyBldCxkZT1bXSxBbj1bXTtmdW5jdGlvbiBWMChpKXtmb3IoY29uc3QgdCBvZiBpKXJldHVybiB0fWZ1bmN0aW9uIFUwKGksdCxlLG4scyxyPXt9KXtjb25zdHt1c2VHcm91cHM6bz0hMH09cix7YUludGVyc2VjdGlvbnM6YSxiSW50ZXJzZWN0aW9uczpjfT1SMChpLHQpLGw9W107bGV0IGg9bnVsbCx1O3JldHVybiB1PW8/MDotMSxXbChpLHQsYSxlLCExLG4scyx1KSxHbChpLHQsYSxlLCExLHMsdSksZS5maW5kSW5kZXgoZD0+ZCE9PU5sJiZkIT09a2wpIT09LTEmJih1PW8/aS5nZW9tZXRyeS5ncm91cHMubGVuZ3RofHwxOi0xLFdsKHQsaSxjLGUsITAsbixzLHUpLEdsKHQsaSxjLGUsITAscyx1KSksZGUubGVuZ3RoPTAsQW4ubGVuZ3RoPTAse2dyb3VwczpsLG1hdGVyaWFsczpofX1mdW5jdGlvbiBXbChpLHQsZSxuLHMscixvLGE9MCl7Y29uc3QgYz1pLm1hdHJpeFdvcmxkLmRldGVybWluYW50KCk8MDtybi5jb3B5KHQubWF0cml4V29ybGQpLmludmVydCgpLm11bHRpcGx5KGkubWF0cml4V29ybGQpLHRyLmdldE5vcm1hbE1hdHJpeChpLm1hdHJpeFdvcmxkKS5tdWx0aXBseVNjYWxhcihjPy0xOjEpO2NvbnN0IGw9aS5nZW9tZXRyeS5ncm91cEluZGljZXMsaD1pLmdlb21ldHJ5LmluZGV4LHU9aS5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGY9dC5nZW9tZXRyeS5ib3VuZHNUcmVlLGQ9dC5nZW9tZXRyeS5pbmRleCxwPXQuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbix5PWUuaWRzLG09ZS5pbnRlcnNlY3Rpb25TZXQ7Zm9yKGxldCBnPTAsYj15Lmxlbmd0aDtnPGI7ZysrKXtjb25zdCB3PXlbZ10seD1hPT09LTE/MDpsW3ddK2EsTT0zKncsQT1oLmdldFgoTSswKSxTPWguZ2V0WChNKzEpLF89aC5nZXRYKE0rMik7TW4uYS5mcm9tQnVmZmVyQXR0cmlidXRlKHUsQSkuYXBwbHlNYXRyaXg0KHJuKSxNbi5iLmZyb21CdWZmZXJBdHRyaWJ1dGUodSxTKS5hcHBseU1hdHJpeDQocm4pLE1uLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LF8pLmFwcGx5TWF0cml4NChybiksci5yZXNldCgpLHIuaW5pdGlhbGl6ZShNbik7Y29uc3QgRT1tW3ddO2ZvcihsZXQgdj0wLEM9RS5sZW5ndGg7djxDO3YrKyl7Y29uc3QgUD0zKkVbdl0sRj1kLmdldFgoUCswKSxCPWQuZ2V0WChQKzEpLEk9ZC5nZXRYKFArMik7ZXIuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsRiksZXIuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsQiksZXIuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHAsSSksci5zcGxpdEJ5VHJpYW5nbGUoZXIpfWNvbnN0IHo9ci50cmlhbmdsZXM7Zm9yKGxldCB2PTAsQz16Lmxlbmd0aDt2PEM7disrKXtjb25zdCBQPXpbdl0sRj1yLmNvcGxhbmFyVHJpYW5nbGVVc2VkP04wKFAsZik6VWwoUCxmKTtkZS5sZW5ndGg9MCxBbi5sZW5ndGg9MDtmb3IobGV0IEI9MCxJPW4ubGVuZ3RoO0I8STtCKyspe2NvbnN0IGs9cWwobltCXSxGLHMpO2shPT13YSYmKEFuLnB1c2goayksZGUucHVzaChvW0JdLmdldEdyb3VwQXR0clNldCh4KSkpfWlmKGRlLmxlbmd0aCE9PTApe01uLmdldEJhcnljb29yZChQLmEsbnIuYSksTW4uZ2V0QmFyeWNvb3JkKFAuYixuci5iKSxNbi5nZXRCYXJ5Y29vcmQoUC5jLG5yLmMpO2ZvcihsZXQgQj0wLEk9ZGUubGVuZ3RoO0I8STtCKyspe2NvbnN0IGs9ZGVbQl0sVT1BbltCXT09PSRpO0wwKHcsbnIsaS5nZW9tZXRyeSxpLm1hdHJpeFdvcmxkLHRyLGssYyE9PVUpfX19fXJldHVybiB5Lmxlbmd0aH1mdW5jdGlvbiBHbChpLHQsZSxuLHMscixvPTApe2NvbnN0IGE9aS5tYXRyaXhXb3JsZC5kZXRlcm1pbmFudCgpPDA7cm4uY29weSh0Lm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseShpLm1hdHJpeFdvcmxkKSx0ci5nZXROb3JtYWxNYXRyaXgoaS5tYXRyaXhXb3JsZCkubXVsdGlwbHlTY2FsYXIoYT8tMToxKTtjb25zdCBjPXQuZ2VvbWV0cnkuYm91bmRzVHJlZSxsPWkuZ2VvbWV0cnkuZ3JvdXBJbmRpY2VzLGg9aS5nZW9tZXRyeS5pbmRleCx1PWkuZ2VvbWV0cnkuYXR0cmlidXRlcyxmPXUucG9zaXRpb24sZD1bXSxwPWkuZ2VvbWV0cnkuaGFsZkVkZ2VzLHk9bmV3IFNldCxtPWFhKGkuZ2VvbWV0cnkpO2ZvcihsZXQgZz0wLGI9bTtnPGI7ZysrKWcgaW4gZS5pbnRlcnNlY3Rpb25TZXR8fHkuYWRkKGcpO2Zvcig7eS5zaXplPjA7KXtjb25zdCBnPVYwKHkpO3kuZGVsZXRlKGcpLGQucHVzaChnKTtjb25zdCBiPTMqZyx3PWguZ2V0WChiKzApLHg9aC5nZXRYKGIrMSksTT1oLmdldFgoYisyKTtvbi5hLmZyb21CdWZmZXJBdHRyaWJ1dGUoZix3KS5hcHBseU1hdHJpeDQocm4pLG9uLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHgpLmFwcGx5TWF0cml4NChybiksb24uYy5mcm9tQnVmZmVyQXR0cmlidXRlKGYsTSkuYXBwbHlNYXRyaXg0KHJuKTtjb25zdCBBPVVsKG9uLGMpO0FuLmxlbmd0aD0wLGRlLmxlbmd0aD0wO2ZvcihsZXQgUz0wLF89bi5sZW5ndGg7UzxfO1MrKyl7Y29uc3QgRT1xbChuW1NdLEEscyk7RSE9PXdhJiYoQW4ucHVzaChFKSxkZS5wdXNoKHJbU10pKX1mb3IoO2QubGVuZ3RoPjA7KXtjb25zdCBTPWQucG9wKCk7Zm9yKGxldCBfPTA7XzwzO18rKyl7Y29uc3QgRT1wLmdldFNpYmxpbmdUcmlhbmdsZUluZGV4KFMsXyk7RSE9PS0xJiZ5LmhhcyhFKSYmKGQucHVzaChFKSx5LmRlbGV0ZShFKSl9aWYoZGUubGVuZ3RoIT09MCl7Y29uc3QgXz0zKlMsRT1oLmdldFgoXyswKSx6PWguZ2V0WChfKzEpLHY9aC5nZXRYKF8rMiksQz1vPT09LTE/MDpsW1NdK287aWYob24uYS5mcm9tQnVmZmVyQXR0cmlidXRlKGYsRSksb24uYi5mcm9tQnVmZmVyQXR0cmlidXRlKGYseiksb24uYy5mcm9tQnVmZmVyQXR0cmlidXRlKGYsdiksIXNuKG9uKSlmb3IobGV0IFA9MCxGPWRlLmxlbmd0aDtQPEY7UCsrKXtjb25zdCBCPUFuW1BdLEk9ZGVbUF0uZ2V0R3JvdXBBdHRyU2V0KEMpLGs9Qj09PSRpO08wKEUseix2LHUsaS5tYXRyaXhXb3JsZCx0cixJLGshPT1hKX19fX19ZnVuY3Rpb24gcTAoaSl7Zm9yKGxldCB0PTA7dDxpLmxlbmd0aC0xO3QrKyl7Y29uc3QgZT1pW3RdLG49aVt0KzFdO2lmKGUubWF0ZXJpYWxJbmRleD09PW4ubWF0ZXJpYWxJbmRleCl7Y29uc3Qgcz1lLnN0YXJ0LHI9bi5zdGFydCtuLmNvdW50O24uc3RhcnQ9cyxuLmNvdW50PXItcyxpLnNwbGljZSh0LDEpLHQtLX19fWZ1bmN0aW9uIEgwKGksdCxlLG4pe2UuY2xlYXIoKTtjb25zdCBzPWkuYXR0cmlidXRlcztmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXSxjPXNbYV07ZS5pbml0aWFsaXplQXJyYXkoYSxjLmFycmF5LmNvbnN0cnVjdG9yLGMuaXRlbVNpemUsYy5ub3JtYWxpemVkKX1mb3IoY29uc3QgciBpbiBlLmF0dHJpYnV0ZXMpbi5pbmNsdWRlcyhyKXx8ZS5kZWxldGUocik7Zm9yKGNvbnN0IHIgaW4gdC5hdHRyaWJ1dGVzKW4uaW5jbHVkZXMocil8fCh0LmRlbGV0ZUF0dHJpYnV0ZShyKSx0LmRpc3Bvc2UoKSl9ZnVuY3Rpb24gVzAoaSx0LGUpe2xldCBuPSExLHM9LTE7Y29uc3Qgcj1pLmF0dHJpYnV0ZXMsbz10Lmdyb3VwQXR0cmlidXRlc1swXTtmb3IoY29uc3QgYyBpbiBvKXtjb25zdCBsPXQuZ2V0VG90YWxMZW5ndGgoYyksaD10LmdldFR5cGUoYyksdT10LmdldEl0ZW1TaXplKGMpLGY9dC5nZXROb3JtYWxpemVkKGMpO2xldCBkPXJbY107KCFkfHxkLmFycmF5Lmxlbmd0aDxsKSYmKGQ9bmV3IHh0KG5ldyBoKGwpLHUsZiksaS5zZXRBdHRyaWJ1dGUoYyxkKSxuPSEwKTtsZXQgcD0wO2ZvcihsZXQgeT0wLG09TWF0aC5taW4oZS5sZW5ndGgsdC5ncm91cENvdW50KTt5PG07eSsrKXtjb25zdCBnPWVbeV0uaW5kZXgse2FycmF5OmIsdHlwZTp3LGxlbmd0aDp4fT10Lmdyb3VwQXR0cmlidXRlc1tnXVtjXSxNPW5ldyB3KGIuYnVmZmVyLDAseCk7ZC5hcnJheS5zZXQoTSxwKSxwKz1NLmxlbmd0aH1kLm5lZWRzVXBkYXRlPSEwLHM9bC9kLml0ZW1TaXplfWlmKGkuaW5kZXgpe2NvbnN0IGM9aS5pbmRleC5hcnJheTtpZihjLmxlbmd0aDxzKWkuaW5kZXg9bnVsbCxuPSEwO2Vsc2UgZm9yKGxldCBsPTAsaD1jLmxlbmd0aDtsPGg7bCsrKWNbbF09bH1sZXQgYT0wO2kuY2xlYXJHcm91cHMoKTtmb3IobGV0IGM9MCxsPU1hdGgubWluKGUubGVuZ3RoLHQuZ3JvdXBDb3VudCk7YzxsO2MrKyl7Y29uc3R7aW5kZXg6aCxtYXRlcmlhbEluZGV4OnV9PWVbY10sZj10LmdldENvdW50KGgpO2YhPT0wJiYoaS5hZGRHcm91cChhLGYsdSksYSs9Zil9aS5zZXREcmF3UmFuZ2UoMCxzKSxpLmJvdW5kc1RyZWU9bnVsbCxuJiZpLmRpc3Bvc2UoKX1mdW5jdGlvbiBabChpLHQpe2xldCBlPXQ7cmV0dXJuIEFycmF5LmlzQXJyYXkodCl8fChlPVtdLGkuZm9yRWFjaChuPT57ZVtuLm1hdGVyaWFsSW5kZXhdPXR9KSksZX1jbGFzcyBHMHtjb25zdHJ1Y3Rvcigpe3RoaXMudHJpYW5nbGVTcGxpdHRlcj1uZXcgejAsdGhpcy5hdHRyaWJ1dGVEYXRhPVtdLHRoaXMuYXR0cmlidXRlcz1bInBvc2l0aW9uIiwidXYiLCJub3JtYWwiXSx0aGlzLnVzZUdyb3Vwcz0hMCx0aGlzLmNvbnNvbGlkYXRlR3JvdXBzPSEwLHRoaXMuZGVidWc9bmV3ICQwfWdldEdyb3VwUmFuZ2VzKHQpe3JldHVybiF0aGlzLnVzZUdyb3Vwc3x8dC5ncm91cHMubGVuZ3RoPT09MD9be3N0YXJ0OjAsY291bnQ6MS8wLG1hdGVyaWFsSW5kZXg6MH1dOnQuZ3JvdXBzLm1hcChlPT5GdCh7fSxlKSl9ZXZhbHVhdGUodCxlLG4scz1uZXcgWnMpe2xldCByPSEwO2lmKEFycmF5LmlzQXJyYXkobil8fChuPVtuXSksQXJyYXkuaXNBcnJheShzKXx8KHM9W3NdLHI9ITEpLHMubGVuZ3RoIT09bi5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKCJFdmFsdWF0b3I6IG9wZXJhdGlvbnMgYW5kIHRhcmdldCBhcnJheSBwYXNzZWQgYXMgZGlmZmVyZW50IHNpemVzLiIpO3QucHJlcGFyZUdlb21ldHJ5KCksZS5wcmVwYXJlR2VvbWV0cnkoKTtjb25zdHt0cmlhbmdsZVNwbGl0dGVyOm8sYXR0cmlidXRlRGF0YTphLGF0dHJpYnV0ZXM6Yyx1c2VHcm91cHM6bCxjb25zb2xpZGF0ZUdyb3VwczpoLGRlYnVnOnV9PXRoaXM7Zm9yKDthLmxlbmd0aDxzLmxlbmd0aDspYS5wdXNoKG5ldyBFMCk7cy5mb3JFYWNoKChnLGIpPT57SDAodC5nZW9tZXRyeSxnLmdlb21ldHJ5LGFbYl0sYyl9KSx1LmluaXQoKSxVMCh0LGUsbixvLGEse3VzZUdyb3VwczpsfSksdS5jb21wbGV0ZSgpO2NvbnN0IGY9dGhpcy5nZXRHcm91cFJhbmdlcyh0Lmdlb21ldHJ5KSxkPVpsKGYsdC5tYXRlcmlhbCkscD10aGlzLmdldEdyb3VwUmFuZ2VzKGUuZ2VvbWV0cnkpLHk9WmwocCxlLm1hdGVyaWFsKTtwLmZvckVhY2goZz0+Zy5tYXRlcmlhbEluZGV4Kz1kLmxlbmd0aCk7bGV0IG09Wy4uLmYsLi4ucF0ubWFwKChnLGIpPT5aZShGdCh7fSxnKSx7aW5kZXg6Yn0pKTtpZihsKXtjb25zdCBnPVsuLi5kLC4uLnldO2gmJihtPW0ubWFwKHc9Pntjb25zdCB4PWdbdy5tYXRlcmlhbEluZGV4XTtyZXR1cm4gdy5tYXRlcmlhbEluZGV4PWcuaW5kZXhPZih4KSx3fSkuc29ydCgodyx4KT0+dy5tYXRlcmlhbEluZGV4LXgubWF0ZXJpYWxJbmRleCkpO2NvbnN0IGI9W107Zm9yKGxldCB3PTAseD1nLmxlbmd0aDt3PHg7dysrKXtsZXQgTT0hMTtmb3IobGV0IEE9MCxTPW0ubGVuZ3RoO0E8UztBKyspe2NvbnN0IF89bVtBXTtfLm1hdGVyaWFsSW5kZXg9PT13JiYoTT0hMCxfLm1hdGVyaWFsSW5kZXg9Yi5sZW5ndGgpfU0mJmIucHVzaChnW3ddKX1zLmZvckVhY2godz0+e3cubWF0ZXJpYWw9Yn0pfWVsc2UgbT1be3N0YXJ0OjAsY291bnQ6MS8wLGluZGV4OjAsbWF0ZXJpYWxJbmRleDowfV0scy5mb3JFYWNoKGc9PntnLm1hdGVyaWFsPWRbMF19KTtyZXR1cm4gcy5mb3JFYWNoKChnLGIpPT57Y29uc3Qgdz1nLmdlb21ldHJ5O1cwKHcsYVtiXSxtKSxoJiZxMCh3Lmdyb3Vwcyl9KSxyP3M6c1swXX1ldmFsdWF0ZUhpZXJhcmNoeSh0LGU9bmV3IFpzKXt0LnVwZGF0ZU1hdHJpeFdvcmxkKCEwKTtjb25zdCBuPShyLG8pPT57Y29uc3QgYT1yLmNoaWxkcmVuO2ZvcihsZXQgYz0wLGw9YS5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1hW2NdO2guaXNPcGVyYXRpb25Hcm91cD9uKGgsbyk6byhoKX19LHM9cj0+e2NvbnN0IG89ci5jaGlsZHJlbjtsZXQgYT0hMTtmb3IobGV0IGw9MCxoPW8ubGVuZ3RoO2w8aDtsKyspe2NvbnN0IHU9b1tsXTthPXModSl8fGF9Y29uc3QgYz1yLmlzRGlydHkoKTtpZihjJiZyLm1hcmtVcGRhdGVkKCksYSYmIXIuaXNPcGVyYXRpb25Hcm91cCl7bGV0IGw7cmV0dXJuIG4ocixoPT57bD9sPXRoaXMuZXZhbHVhdGUobCxoLGgub3BlcmF0aW9uKTpsPXRoaXMuZXZhbHVhdGUocixoLGgub3BlcmF0aW9uKX0pLHIuX2NhY2hlZEdlb21ldHJ5PWwuZ2VvbWV0cnksci5fY2FjaGVkTWF0ZXJpYWxzPWwubWF0ZXJpYWwsITB9ZWxzZSByZXR1cm4gYXx8Y307cmV0dXJuIHModCksZS5nZW9tZXRyeT10Ll9jYWNoZWRHZW9tZXRyeSxlLm1hdGVyaWFsPXQuX2NhY2hlZE1hdGVyaWFscyxlfXJlc2V0KCl7dGhpcy50cmlhbmdsZVNwbGl0dGVyLnJlc2V0KCl9fWZ1bmN0aW9uIFhsKGkpe2xldCB0LGUsbixzPS0xLHI9MDtmb3IobGV0IGw9MDtsPGkubGVuZ3RoOysrbCl7Y29uc3QgaD1pW2xdO2lmKHQ9PT12b2lkIDAmJih0PWguYXJyYXkuY29uc3RydWN0b3IpLHQhPT1oLmFycmF5LmNvbnN0cnVjdG9yKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuYXJyYXkgbXVzdCBiZSBvZiBjb25zaXN0ZW50IGFycmF5IHR5cGVzIGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7aWYoZT09PXZvaWQgMCYmKGU9aC5pdGVtU2l6ZSksZSE9PWguaXRlbVNpemUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUF0dHJpYnV0ZXMoKSBmYWlsZWQuIEJ1ZmZlckF0dHJpYnV0ZS5pdGVtU2l6ZSBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihuPT09dm9pZCAwJiYobj1oLm5vcm1hbGl6ZWQpLG4hPT1oLm5vcm1hbGl6ZWQpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUF0dHJpYnV0ZXMoKSBmYWlsZWQuIEJ1ZmZlckF0dHJpYnV0ZS5ub3JtYWxpemVkIG11c3QgYmUgY29uc2lzdGVudCBhY3Jvc3MgbWF0Y2hpbmcgYXR0cmlidXRlcy4iKSxudWxsO2lmKHM9PT0tMSYmKHM9aC5ncHVUeXBlKSxzIT09aC5ncHVUeXBlKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuZ3B1VHlwZSBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtyKz1oLmNvdW50KmV9Y29uc3Qgbz1uZXcgdChyKSxhPW5ldyB4dChvLGUsbik7bGV0IGM9MDtmb3IobGV0IGw9MDtsPGkubGVuZ3RoOysrbCl7Y29uc3QgaD1pW2xdO2lmKGguaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl7Y29uc3QgdT1jL2U7Zm9yKGxldCBmPTAsZD1oLmNvdW50O2Y8ZDtmKyspZm9yKGxldCBwPTA7cDxlO3ArKyl7Y29uc3QgeT1oLmdldENvbXBvbmVudChmLHApO2Euc2V0Q29tcG9uZW50KGYrdSxwLHkpfX1lbHNlIG8uc2V0KGguYXJyYXksYyk7Yys9aC5jb3VudCplfXJldHVybiBzIT09dm9pZCAwJiYoYS5ncHVUeXBlPXMpLGF9ZnVuY3Rpb24gWjAoaSl7aWYoaS5ncm91cHMubGVuZ3RoPT09MClyZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzLm1lcmdlR3JvdXBzKCk6IE5vIGdyb3VwcyBhcmUgZGVmaW5lZC4gTm90aGluZyB0byBtZXJnZS4iKSxpO2xldCB0PWkuZ3JvdXBzO2lmKHQ9dC5zb3J0KChvLGEpPT5vLm1hdGVyaWFsSW5kZXghPT1hLm1hdGVyaWFsSW5kZXg/by5tYXRlcmlhbEluZGV4LWEubWF0ZXJpYWxJbmRleDpvLnN0YXJ0LWEuc3RhcnQpLGkuZ2V0SW5kZXgoKT09PW51bGwpe2NvbnN0IG89aS5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIiksYT1bXTtmb3IobGV0IGM9MDtjPG8uY291bnQ7Yys9MylhLnB1c2goYyxjKzEsYysyKTtpLnNldEluZGV4KGEpfWNvbnN0IGU9aS5nZXRJbmRleCgpLG49W107Zm9yKGxldCBvPTA7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXSxjPWEuc3RhcnQsbD1jK2EuY291bnQ7Zm9yKGxldCBoPWM7aDxsO2grKyluLnB1c2goZS5nZXRYKGgpKX1pLmRpc3Bvc2UoKSxpLnNldEluZGV4KG4pO2xldCBzPTA7Zm9yKGxldCBvPTA7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXTthLnN0YXJ0PXMscys9YS5jb3VudH1sZXQgcj10WzBdO2kuZ3JvdXBzPVtyXTtmb3IobGV0IG89MTtvPHQubGVuZ3RoO28rKyl7Y29uc3QgYT10W29dO3IubWF0ZXJpYWxJbmRleD09PWEubWF0ZXJpYWxJbmRleD9yLmNvdW50Kz1hLmNvdW50OihyPWEsaS5ncm91cHMucHVzaChyKSl9cmV0dXJuIGl9ZnVuY3Rpb24gSmwoaSx0PTApe2NvbnN0IGU9aVswXS5pbmRleCE9PW51bGwsbj1uZXcgU2V0KE9iamVjdC5rZXlzKGlbMF0uYXR0cmlidXRlcykpLHM9bmV3IFNldChPYmplY3Qua2V5cyhpWzBdLm1vcnBoQXR0cmlidXRlcykpLHI9e30sbz17fSxhPWlbMF0ubW9ycGhUYXJnZXRzUmVsYXRpdmUsYz1uZXcgdWU7bGV0IGw9MDtmb3IobGV0IGg9MDtoPGkubGVuZ3RoOysraCl7Y29uc3QgdT1pW2hdO2xldCBmPTA7aWYoZSE9PSh1LmluZGV4IT09bnVsbCkpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gQWxsIGdlb21ldHJpZXMgbXVzdCBoYXZlIGNvbXBhdGlibGUgYXR0cmlidXRlczsgbWFrZSBzdXJlIGluZGV4IGF0dHJpYnV0ZSBleGlzdHMgYW1vbmcgYWxsIGdlb21ldHJpZXMsIG9yIGluIG5vbmUgb2YgdGhlbS4iKSxudWxsO2Zvcihjb25zdCBkIGluIHUuYXR0cmlidXRlcyl7aWYoIW4uaGFzKGQpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKycuIEFsbCBnZW9tZXRyaWVzIG11c3QgaGF2ZSBjb21wYXRpYmxlIGF0dHJpYnV0ZXM7IG1ha2Ugc3VyZSAiJytkKyciIGF0dHJpYnV0ZSBleGlzdHMgYW1vbmcgYWxsIGdlb21ldHJpZXMsIG9yIGluIG5vbmUgb2YgdGhlbS4nKSxudWxsO3JbZF09PT12b2lkIDAmJihyW2RdPVtdKSxyW2RdLnB1c2godS5hdHRyaWJ1dGVzW2RdKSxmKyt9aWYoZiE9PW4uc2l6ZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiBNYWtlIHN1cmUgYWxsIGdlb21ldHJpZXMgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgYXR0cmlidXRlcy4iKSxudWxsO2lmKGEhPT11Lm1vcnBoVGFyZ2V0c1JlbGF0aXZlKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIC5tb3JwaFRhcmdldHNSZWxhdGl2ZSBtdXN0IGJlIGNvbnNpc3RlbnQgdGhyb3VnaG91dCBhbGwgZ2VvbWV0cmllcy4iKSxudWxsO2Zvcihjb25zdCBkIGluIHUubW9ycGhBdHRyaWJ1dGVzKXtpZighcy5oYXMoZCkpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gIC5tb3JwaEF0dHJpYnV0ZXMgbXVzdCBiZSBjb25zaXN0ZW50IHRocm91Z2hvdXQgYWxsIGdlb21ldHJpZXMuIiksbnVsbDtvW2RdPT09dm9pZCAwJiYob1tkXT1bXSksb1tkXS5wdXNoKHUubW9ycGhBdHRyaWJ1dGVzW2RdKX1pZih0KXtsZXQgZDtpZihlKWQ9dS5pbmRleC5jb3VudDtlbHNlIGlmKHUuYXR0cmlidXRlcy5wb3NpdGlvbiE9PXZvaWQgMClkPXUuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudDtlbHNlIHJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIFRoZSBnZW9tZXRyeSBtdXN0IGhhdmUgZWl0aGVyIGFuIGluZGV4IG9yIGEgcG9zaXRpb24gYXR0cmlidXRlIiksbnVsbDtpZih0PT09MSljLmFkZEdyb3VwKGwsZCxoKTtlbHNlIGlmKHQ9PT0yJiZ1Lmdyb3Vwcy5sZW5ndGg+MClmb3IobGV0IHAgb2YgdS5ncm91cHMpe2xldCB5PXAubWF0ZXJpYWxJbmRleDtjLmFkZEdyb3VwKGwrcC5zdGFydCxNYXRoLm1pbihwLmNvdW50LGQpLHkpfWwrPWR9fWlmKGUpe2xldCBoPTA7Y29uc3QgdT1bXTtmb3IobGV0IGY9MDtmPGkubGVuZ3RoOysrZil7Y29uc3QgZD1pW2ZdLmluZGV4O2ZvcihsZXQgcD0wO3A8ZC5jb3VudDsrK3ApdS5wdXNoKGQuZ2V0WChwKStoKTtoKz1pW2ZdLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnR9Yy5zZXRJbmRleCh1KX1mb3IoY29uc3QgaCBpbiByKXtjb25zdCB1PVhsKHJbaF0pO2lmKCF1KXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdoaWxlIHRyeWluZyB0byBtZXJnZSB0aGUgIitoKyIgYXR0cmlidXRlLiIpLG51bGw7Yy5zZXRBdHRyaWJ1dGUoaCx1KX1mb3IoY29uc3QgaCBpbiBvKXtjb25zdCB1PW9baF1bMF0ubGVuZ3RoO2lmKHU9PT0wKWJyZWFrO2MubW9ycGhBdHRyaWJ1dGVzPWMubW9ycGhBdHRyaWJ1dGVzfHx7fSxjLm1vcnBoQXR0cmlidXRlc1toXT1bXTtmb3IobGV0IGY9MDtmPHU7KytmKXtjb25zdCBkPVtdO2ZvcihsZXQgeT0wO3k8b1toXS5sZW5ndGg7Kyt5KWQucHVzaChvW2hdW3ldW2ZdKTtjb25zdCBwPVhsKGQpO2lmKCFwKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdoaWxlIHRyeWluZyB0byBtZXJnZSB0aGUgIitoKyIgbW9ycGhBdHRyaWJ1dGUuIiksbnVsbDtjLm1vcnBoQXR0cmlidXRlc1toXS5wdXNoKHApfX1yZXR1cm4gdD09PTI/WjAoYyk6Y31jbGFzcyBYMCBleHRlbmRzIEdue2NvbnN0cnVjdG9yKHQsZSl7c3VwZXIodCxlKTtjb25zdCBuPW5ldyBacyhuZXcgR24odCxaZShGdCh7fSxlKSx7aGFzVG9wOiEwLGhhc1NpZGU6ITAsaGFzQm90dG9tOiExfSkpKTtuLnVwZGF0ZU1hdHJpeFdvcmxkKCk7Y29uc3Qgcz1uZXcgZ3QoKS5zZXRGcm9tT2JqZWN0KG4pLHI9bmV3IFQ7cy5nZXRTaXplKHIpO2NvbnN0IG89bmV3IFQocy5taW4ueCtyLngvMixzLm1pbi55K3IueS8yLDApO2xldCBhPWUudG9wU2VnbWVudHMsYz1lLmJveDM7aWYoYyl7Yz1jLnVuaW9uKHMpO2NvbnN0IGc9bmV3IFQ7Yy5nZXRTaXplKGcpO2NvbnN0IGI9TWF0aC5tYXgoci54L2cueCxyLnkvZy55KTthPU1hdGguY2VpbChlLnRvcFNlZ21lbnRzKmIpfWlmKGE8NClyZXR1cm4gdGhpcztjb25zdCBsPW5ldyBMbyhyLngsci55LGEsYSksaD1uZXcgWnMobCk7aC5wb3NpdGlvbi5zZXQoby54LG8ueSxvLnopLGgudXBkYXRlTWF0cml4V29ybGQoKTtjb25zdCBmPW5ldyBHMCgpLmV2YWx1YXRlKGgsbixJbCksZD1mLmdlb21ldHJ5LmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKSxwPW5ldyBCZShkLmNvdW50KjIsMik7Zm9yKGxldCBnPTA7ZzxkLmNvdW50O2crKyl7Y29uc3QgYj1kLmdldFooZyk7ZC5zZXRaKGcsZS5kZXB0aCtiKX1pZihjKXtjb25zdCBnPWMubWluLGI9Yy5tYXgsdz1uZXcgVCgpLnN1YlZlY3RvcnMoYixnKTtmb3IobGV0IHg9MDt4PGQuY291bnQ7eCsrKXtjb25zdCBNPWQuZ2V0WCh4KSxBPWQuZ2V0WSh4KSxTPShNLWcueCkvdy54LF89KEEtZy55KS93Lnk7cC5zZXRYWSh4LFMsXyl9Zi5nZW9tZXRyeS5zZXRBdHRyaWJ1dGUoInV2IixwKX1kLm5lZWRzVXBkYXRlPSEwO2NvbnN0IHk9bmV3IEduKHQsWmUoRnQoe30sZSkse2hhc1RvcDohMX0pKSxtPUpsKFtmLmdlb21ldHJ5LHldLDIpO3RoaXMuY29weShtLnRvTm9uSW5kZXhlZCgpKX19dmFyIEowPWk9Pntjb25zdHtzcGxpdDp0LGRlcHRoOmUscG9pbnRzOm4sYm94MzpzLGhhc1RvcDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSxzaWRlUmVwZWF0OmMsdG9wU2VnbWVudHM6bH09aSxoPWw/WDA6R24sdT1uZXcgaChuZXcgWGMobikse2RlcHRoOmUsYmV2ZWxFbmFibGVkOiExLGJveDM6cyxVVkdlbmVyYXRvcjpZZih7c3BsaXQ6dCxib3gzOnMsc2lkZVJlcGVhdDpjfSksaGFzVG9wOnIsaGFzQm90dG9tOm8saGFzU2lkZTphLHRvcFNlZ21lbnRzOmx9KTtyZXR1cm4gamYoKSx1fTtmdW5jdGlvbiBZMChpLHQsZT0wKXtjb25zdCBuPSg5MC10KSpNYXRoLlBJLzE4MCxzPSg5MC1pKSpNYXRoLlBJLzE4MDtyZXR1cm5bZSpNYXRoLnNpbihuKSpNYXRoLmNvcyhzKSxlKk1hdGguY29zKG4pLGUqTWF0aC5zaW4obikqTWF0aC5zaW4ocyldfWZ1bmN0aW9uIGlyKGksdCl7cmV0dXJuIGk9PW51bGx8fHQ9PW51bGw/TmFOOmk8dD8tMTppPnQ/MTppPj10PzA6TmFOfWZ1bmN0aW9uIGowKGksdCl7cmV0dXJuIGk9PW51bGx8fHQ9PW51bGw/TmFOOnQ8aT8tMTp0Pmk/MTp0Pj1pPzA6TmFOfWZ1bmN0aW9uIFlsKGkpe2xldCB0LGUsbjtpLmxlbmd0aCE9PTI/KHQ9aXIsZT0oYSxjKT0+aXIoaShhKSxjKSxuPShhLGMpPT5pKGEpLWMpOih0PWk9PT1pcnx8aT09PWowP2k6UTAsZT1pLG49aSk7ZnVuY3Rpb24gcyhhLGMsbD0wLGg9YS5sZW5ndGgpe2lmKGw8aCl7aWYodChjLGMpIT09MClyZXR1cm4gaDtkb3tjb25zdCB1PWwraD4+PjE7ZShhW3VdLGMpPDA/bD11KzE6aD11fXdoaWxlKGw8aCl9cmV0dXJuIGx9ZnVuY3Rpb24gcihhLGMsbD0wLGg9YS5sZW5ndGgpe2lmKGw8aCl7aWYodChjLGMpIT09MClyZXR1cm4gaDtkb3tjb25zdCB1PWwraD4+PjE7ZShhW3VdLGMpPD0wP2w9dSsxOmg9dX13aGlsZShsPGgpfXJldHVybiBsfWZ1bmN0aW9uIG8oYSxjLGw9MCxoPWEubGVuZ3RoKXtjb25zdCB1PXMoYSxjLGwsaC0xKTtyZXR1cm4gdT5sJiZuKGFbdS0xXSxjKT4tbihhW3VdLGMpP3UtMTp1fXJldHVybntsZWZ0OnMsY2VudGVyOm8scmlnaHQ6cn19ZnVuY3Rpb24gUTAoKXtyZXR1cm4gMH1mdW5jdGlvbiBLMChpKXtyZXR1cm4gaT09PW51bGw/TmFOOitpfWNvbnN0IHRwPVlsKGlyKS5yaWdodDtZbChLMCkuY2VudGVyO2Z1bmN0aW9uIHNyKGksdCl7bGV0IGUsbjtpZih0PT09dm9pZCAwKWZvcihjb25zdCBzIG9mIGkpcyE9bnVsbCYmKGU9PT12b2lkIDA/cz49cyYmKGU9bj1zKTooZT5zJiYoZT1zKSxuPHMmJihuPXMpKSk7ZWxzZXtsZXQgcz0tMTtmb3IobGV0IHIgb2YgaSkocj10KHIsKytzLGkpKSE9bnVsbCYmKGU9PT12b2lkIDA/cj49ciYmKGU9bj1yKTooZT5yJiYoZT1yKSxuPHImJihuPXIpKSl9cmV0dXJuW2Usbl19Y2xhc3MgTGV7Y29uc3RydWN0b3IoKXt0aGlzLl9wYXJ0aWFscz1uZXcgRmxvYXQ2NEFycmF5KDMyKSx0aGlzLl9uPTB9YWRkKHQpe2NvbnN0IGU9dGhpcy5fcGFydGlhbHM7bGV0IG49MDtmb3IobGV0IHM9MDtzPHRoaXMuX24mJnM8MzI7cysrKXtjb25zdCByPWVbc10sbz10K3IsYT1NYXRoLmFicyh0KTxNYXRoLmFicyhyKT90LShvLXIpOnItKG8tdCk7YSYmKGVbbisrXT1hKSx0PW99cmV0dXJuIGVbbl09dCx0aGlzLl9uPW4rMSx0aGlzfXZhbHVlT2YoKXtjb25zdCB0PXRoaXMuX3BhcnRpYWxzO2xldCBlPXRoaXMuX24sbixzLHIsbz0wO2lmKGU+MCl7Zm9yKG89dFstLWVdO2U+MCYmKG49byxzPXRbLS1lXSxvPW4rcyxyPXMtKG8tbiksIXIpOyk7ZT4wJiYocjwwJiZ0W2UtMV08MHx8cj4wJiZ0W2UtMV0+MCkmJihzPXIqMixuPW8rcyxzPT1uLW8mJihvPW4pKX1yZXR1cm4gb319Y29uc3QgZXA9TWF0aC5zcXJ0KDUwKSxucD1NYXRoLnNxcnQoMTApLGlwPU1hdGguc3FydCgyKTtmdW5jdGlvbiBycihpLHQsZSl7Y29uc3Qgbj0odC1pKS9NYXRoLm1heCgwLGUpLHM9TWF0aC5mbG9vcihNYXRoLmxvZzEwKG4pKSxyPW4vTWF0aC5wb3coMTAscyksbz1yPj1lcD8xMDpyPj1ucD81OnI+PWlwPzI6MTtsZXQgYSxjLGw7cmV0dXJuIHM8MD8obD1NYXRoLnBvdygxMCwtcykvbyxhPU1hdGgucm91bmQoaSpsKSxjPU1hdGgucm91bmQodCpsKSxhL2w8aSYmKythLGMvbD50JiYtLWMsbD0tbCk6KGw9TWF0aC5wb3coMTAscykqbyxhPU1hdGgucm91bmQoaS9sKSxjPU1hdGgucm91bmQodC9sKSxhKmw8aSYmKythLGMqbD50JiYtLWMpLGM8YSYmLjU8PWUmJmU8Mj9ycihpLHQsZSoyKTpbYSxjLGxdfWZ1bmN0aW9uIHNwKGksdCxlKXtpZih0PSt0LGk9K2ksZT0rZSwhKGU+MCkpcmV0dXJuW107aWYoaT09PXQpcmV0dXJuW2ldO2NvbnN0IG49dDxpLFtzLHIsb109bj9ycih0LGksZSk6cnIoaSx0LGUpO2lmKCEocj49cykpcmV0dXJuW107Y29uc3QgYT1yLXMrMSxjPW5ldyBBcnJheShhKTtpZihuKWlmKG88MClmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHItbCkvLW87ZWxzZSBmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHItbCkqbztlbHNlIGlmKG88MClmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHMrbCkvLW87ZWxzZSBmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHMrbCkqbztyZXR1cm4gY31mdW5jdGlvbiBBYShpLHQsZSl7cmV0dXJuIHQ9K3QsaT0raSxlPStlLHJyKGksdCxlKVsyXX1mdW5jdGlvbiBycChpLHQsZSl7dD0rdCxpPStpLGU9K2U7Y29uc3Qgbj10PGkscz1uP0FhKHQsaSxlKTpBYShpLHQsZSk7cmV0dXJuKG4/LTE6MSkqKHM8MD8xLy1zOnMpfWZ1bmN0aW9uIG9wKGksdCl7bGV0IGU9MCxuPTA7aWYodD09PXZvaWQgMClmb3IobGV0IHMgb2YgaSlzIT1udWxsJiYocz0rcyk+PXMmJigrK2Usbis9cyk7ZWxzZXtsZXQgcz0tMTtmb3IobGV0IHIgb2YgaSkocj10KHIsKytzLGkpKSE9bnVsbCYmKHI9K3IpPj1yJiYoKytlLG4rPXIpfWlmKGUpcmV0dXJuIG4vZX1mdW5jdGlvbiphcChpKXtmb3IoY29uc3QgdCBvZiBpKXlpZWxkKll1KHQpfWZ1bmN0aW9uIFZpKGkpe3JldHVybiBBcnJheS5mcm9tKGFwKGkpKX12YXIgSz0xZS02LG9yPTFlLTEyLFg9TWF0aC5QSSxOdD1YLzIsYXI9WC80LFJ0PVgqMixodD0xODAvWCxIPVgvMTgwLHR0PU1hdGguYWJzLFNhPU1hdGguYXRhbixyZT1NYXRoLmF0YW4yLFc9TWF0aC5jb3MsY3A9TWF0aC5leHAsX2E9TWF0aC5oeXBvdCxscD1NYXRoLmxvZyxxPU1hdGguc2luLGhwPU1hdGguc2lnbnx8ZnVuY3Rpb24oaSl7cmV0dXJuIGk+MD8xOmk8MD8tMTowfSxPZT1NYXRoLnNxcnQsdXA9TWF0aC50YW47ZnVuY3Rpb24gZnAoaSl7cmV0dXJuIGk+MT8wOmk8LTE/WDpNYXRoLmFjb3MoaSl9ZnVuY3Rpb24gRGUoaSl7cmV0dXJuIGk+MT9OdDppPC0xPy1OdDpNYXRoLmFzaW4oaSl9ZnVuY3Rpb24gamwoaSl7cmV0dXJuKGk9cShpLzIpKSppfWZ1bmN0aW9uIF90KCl7fWZ1bmN0aW9uIGNyKGksdCl7aSYmS2wuaGFzT3duUHJvcGVydHkoaS50eXBlKSYmS2xbaS50eXBlXShpLHQpfXZhciBRbD17RmVhdHVyZTpmdW5jdGlvbihpLHQpe2NyKGkuZ2VvbWV0cnksdCl9LEZlYXR1cmVDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZmVhdHVyZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOyljcihlW25dLmdlb21ldHJ5LHQpfX0sS2w9e1NwaGVyZTpmdW5jdGlvbihpLHQpe3Quc3BoZXJlKCl9LFBvaW50OmZ1bmN0aW9uKGksdCl7aT1pLmNvb3JkaW5hdGVzLHQucG9pbnQoaVswXSxpWzFdLGlbMl0pfSxNdWx0aVBvaW50OmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpPWVbbl0sdC5wb2ludChpWzBdLGlbMV0saVsyXSl9LExpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXt2YShpLmNvb3JkaW5hdGVzLHQsMCl9LE11bHRpTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspdmEoZVtuXSx0LDApfSxQb2x5Z29uOmZ1bmN0aW9uKGksdCl7dGgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2x5Z29uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOyl0aChlW25dLHQpfSxHZW9tZXRyeUNvbGxlY3Rpb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5nZW9tZXRyaWVzLG49LTEscz1lLmxlbmd0aDsrK248czspY3IoZVtuXSx0KX19O2Z1bmN0aW9uIHZhKGksdCxlKXt2YXIgbj0tMSxzPWkubGVuZ3RoLWUscjtmb3IodC5saW5lU3RhcnQoKTsrK248czspcj1pW25dLHQucG9pbnQoclswXSxyWzFdLHJbMl0pO3QubGluZUVuZCgpfWZ1bmN0aW9uIHRoKGksdCl7dmFyIGU9LTEsbj1pLmxlbmd0aDtmb3IodC5wb2x5Z29uU3RhcnQoKTsrK2U8bjspdmEoaVtlXSx0LDEpO3QucG9seWdvbkVuZCgpfWZ1bmN0aW9uIGxyKGksdCl7aSYmUWwuaGFzT3duUHJvcGVydHkoaS50eXBlKT9RbFtpLnR5cGVdKGksdCk6Y3IoaSx0KX12YXIgaHI9bmV3IExlLGVoPW5ldyBMZSxuaCxpaCx6YSxUYSxFYSwkZT17cG9pbnQ6X3QsbGluZVN0YXJ0Ol90LGxpbmVFbmQ6X3QscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7aHI9bmV3IExlLCRlLmxpbmVTdGFydD1kcCwkZS5saW5lRW5kPXBwfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7dmFyIGk9K2hyO2VoLmFkZChpPDA/UnQraTppKSx0aGlzLmxpbmVTdGFydD10aGlzLmxpbmVFbmQ9dGhpcy5wb2ludD1fdH0sc3BoZXJlOmZ1bmN0aW9uKCl7ZWguYWRkKFJ0KX19O2Z1bmN0aW9uIGRwKCl7JGUucG9pbnQ9eXB9ZnVuY3Rpb24gcHAoKXtzaChuaCxpaCl9ZnVuY3Rpb24geXAoaSx0KXskZS5wb2ludD1zaCxuaD1pLGloPXQsaSo9SCx0Kj1ILHphPWksVGE9Vyh0PXQvMithciksRWE9cSh0KX1mdW5jdGlvbiBzaChpLHQpe2kqPUgsdCo9SCx0PXQvMithcjt2YXIgZT1pLXphLG49ZT49MD8xOi0xLHM9biplLHI9Vyh0KSxvPXEodCksYT1FYSpvLGM9VGEqcithKlcocyksbD1hKm4qcShzKTtoci5hZGQocmUobCxjKSksemE9aSxUYT1yLEVhPW99ZnVuY3Rpb24gdXIoaSl7cmV0dXJuW3JlKGlbMV0saVswXSksRGUoaVsyXSldfWZ1bmN0aW9uIFNuKGkpe3ZhciB0PWlbMF0sZT1pWzFdLG49VyhlKTtyZXR1cm5bbipXKHQpLG4qcSh0KSxxKGUpXX1mdW5jdGlvbiBmcihpLHQpe3JldHVybiBpWzBdKnRbMF0raVsxXSp0WzFdK2lbMl0qdFsyXX1mdW5jdGlvbiBuaShpLHQpe3JldHVybltpWzFdKnRbMl0taVsyXSp0WzFdLGlbMl0qdFswXS1pWzBdKnRbMl0saVswXSp0WzFdLWlbMV0qdFswXV19ZnVuY3Rpb24gUGEoaSx0KXtpWzBdKz10WzBdLGlbMV0rPXRbMV0saVsyXSs9dFsyXX1mdW5jdGlvbiBkcihpLHQpe3JldHVybltpWzBdKnQsaVsxXSp0LGlbMl0qdF19ZnVuY3Rpb24gcHIoaSl7dmFyIHQ9T2UoaVswXSppWzBdK2lbMV0qaVsxXStpWzJdKmlbMl0pO2lbMF0vPXQsaVsxXS89dCxpWzJdLz10fXZhciBvdCxMdCx1dCxxdCxfbixyaCxvaCxpaSxVaSxhbixWZSxVZT17cG9pbnQ6Q2EsbGluZVN0YXJ0OmNoLGxpbmVFbmQ6bGgscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7VWUucG9pbnQ9aGgsVWUubGluZVN0YXJ0PW1wLFVlLmxpbmVFbmQ9Z3AsVWk9bmV3IExlLCRlLnBvbHlnb25TdGFydCgpfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7JGUucG9seWdvbkVuZCgpLFVlLnBvaW50PUNhLFVlLmxpbmVTdGFydD1jaCxVZS5saW5lRW5kPWxoLGhyPDA/KG90PS0odXQ9MTgwKSxMdD0tKHF0PTkwKSk6VWk+Sz9xdD05MDpVaTwtSyYmKEx0PS05MCksVmVbMF09b3QsVmVbMV09dXR9LHNwaGVyZTpmdW5jdGlvbigpe290PS0odXQ9MTgwKSxMdD0tKHF0PTkwKX19O2Z1bmN0aW9uIENhKGksdCl7YW4ucHVzaChWZT1bb3Q9aSx1dD1pXSksdDxMdCYmKEx0PXQpLHQ+cXQmJihxdD10KX1mdW5jdGlvbiBhaChpLHQpe3ZhciBlPVNuKFtpKkgsdCpIXSk7aWYoaWkpe3ZhciBuPW5pKGlpLGUpLHM9W25bMV0sLW5bMF0sMF0scj1uaShzLG4pO3ByKHIpLHI9dXIocik7dmFyIG89aS1fbixhPW8+MD8xOi0xLGM9clswXSpodCphLGwsaD10dChvKT4xODA7aF4oYSpfbjxjJiZjPGEqaSk/KGw9clsxXSpodCxsPnF0JiYocXQ9bCkpOihjPShjKzM2MCklMzYwLTE4MCxoXihhKl9uPGMmJmM8YSppKT8obD0tclsxXSpodCxsPEx0JiYoTHQ9bCkpOih0PEx0JiYoTHQ9dCksdD5xdCYmKHF0PXQpKSksaD9pPF9uP0h0KG90LGkpPkh0KG90LHV0KSYmKHV0PWkpOkh0KGksdXQpPkh0KG90LHV0KSYmKG90PWkpOnV0Pj1vdD8oaTxvdCYmKG90PWkpLGk+dXQmJih1dD1pKSk6aT5fbj9IdChvdCxpKT5IdChvdCx1dCkmJih1dD1pKTpIdChpLHV0KT5IdChvdCx1dCkmJihvdD1pKX1lbHNlIGFuLnB1c2goVmU9W290PWksdXQ9aV0pO3Q8THQmJihMdD10KSx0PnF0JiYocXQ9dCksaWk9ZSxfbj1pfWZ1bmN0aW9uIGNoKCl7VWUucG9pbnQ9YWh9ZnVuY3Rpb24gbGgoKXtWZVswXT1vdCxWZVsxXT11dCxVZS5wb2ludD1DYSxpaT1udWxsfWZ1bmN0aW9uIGhoKGksdCl7aWYoaWkpe3ZhciBlPWktX247VWkuYWRkKHR0KGUpPjE4MD9lKyhlPjA/MzYwOi0zNjApOmUpfWVsc2Ugcmg9aSxvaD10OyRlLnBvaW50KGksdCksYWgoaSx0KX1mdW5jdGlvbiBtcCgpeyRlLmxpbmVTdGFydCgpfWZ1bmN0aW9uIGdwKCl7aGgocmgsb2gpLCRlLmxpbmVFbmQoKSx0dChVaSk+SyYmKG90PS0odXQ9MTgwKSksVmVbMF09b3QsVmVbMV09dXQsaWk9bnVsbH1mdW5jdGlvbiBIdChpLHQpe3JldHVybih0LT1pKTwwP3QrMzYwOnR9ZnVuY3Rpb24geHAoaSx0KXtyZXR1cm4gaVswXS10WzBdfWZ1bmN0aW9uIHVoKGksdCl7cmV0dXJuIGlbMF08PWlbMV0/aVswXTw9dCYmdDw9aVsxXTp0PGlbMF18fGlbMV08dH1mdW5jdGlvbiBmaChpKXt2YXIgdCxlLG4scyxyLG8sYTtpZihxdD11dD0tKG90PUx0PTEvMCksYW49W10sbHIoaSxVZSksZT1hbi5sZW5ndGgpe2Zvcihhbi5zb3J0KHhwKSx0PTEsbj1hblswXSxyPVtuXTt0PGU7Kyt0KXM9YW5bdF0sdWgobixzWzBdKXx8dWgobixzWzFdKT8oSHQoblswXSxzWzFdKT5IdChuWzBdLG5bMV0pJiYoblsxXT1zWzFdKSxIdChzWzBdLG5bMV0pPkh0KG5bMF0sblsxXSkmJihuWzBdPXNbMF0pKTpyLnB1c2gobj1zKTtmb3Iobz0tMS8wLGU9ci5sZW5ndGgtMSx0PTAsbj1yW2VdO3Q8PWU7bj1zLCsrdClzPXJbdF0sKGE9SHQoblsxXSxzWzBdKSk+byYmKG89YSxvdD1zWzBdLHV0PW5bMV0pfXJldHVybiBhbj1WZT1udWxsLG90PT09MS8wfHxMdD09PTEvMD9bW05hTixOYU5dLFtOYU4sTmFOXV06W1tvdCxMdF0sW3V0LHF0XV19dmFyIHFpLHlyLG1yLGdyLHhyLHdyLGJyLE1yLEJhLEZhLElhLGRoLHBoLEV0LFB0LEN0LHBlPXtzcGhlcmU6X3QscG9pbnQ6a2EsbGluZVN0YXJ0OnloLGxpbmVFbmQ6bWgscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7cGUubGluZVN0YXJ0PU1wLHBlLmxpbmVFbmQ9QXB9LHBvbHlnb25FbmQ6ZnVuY3Rpb24oKXtwZS5saW5lU3RhcnQ9eWgscGUubGluZUVuZD1taH19O2Z1bmN0aW9uIGthKGksdCl7aSo9SCx0Kj1IO3ZhciBlPVcodCk7SGkoZSpXKGkpLGUqcShpKSxxKHQpKX1mdW5jdGlvbiBIaShpLHQsZSl7KytxaSxtcis9KGktbXIpL3FpLGdyKz0odC1ncikvcWkseHIrPShlLXhyKS9xaX1mdW5jdGlvbiB5aCgpe3BlLnBvaW50PXdwfWZ1bmN0aW9uIHdwKGksdCl7aSo9SCx0Kj1IO3ZhciBlPVcodCk7RXQ9ZSpXKGkpLFB0PWUqcShpKSxDdD1xKHQpLHBlLnBvaW50PWJwLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiBicChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpLG49ZSpXKGkpLHM9ZSpxKGkpLHI9cSh0KSxvPXJlKE9lKChvPVB0KnItQ3Qqcykqbysobz1DdCpuLUV0KnIpKm8rKG89RXQqcy1QdCpuKSpvKSxFdCpuK1B0KnMrQ3Qqcik7eXIrPW8sd3IrPW8qKEV0KyhFdD1uKSksYnIrPW8qKFB0KyhQdD1zKSksTXIrPW8qKEN0KyhDdD1yKSksSGkoRXQsUHQsQ3QpfWZ1bmN0aW9uIG1oKCl7cGUucG9pbnQ9a2F9ZnVuY3Rpb24gTXAoKXtwZS5wb2ludD1TcH1mdW5jdGlvbiBBcCgpe2doKGRoLHBoKSxwZS5wb2ludD1rYX1mdW5jdGlvbiBTcChpLHQpe2RoPWkscGg9dCxpKj1ILHQqPUgscGUucG9pbnQ9Z2g7dmFyIGU9Vyh0KTtFdD1lKlcoaSksUHQ9ZSpxKGkpLEN0PXEodCksSGkoRXQsUHQsQ3QpfWZ1bmN0aW9uIGdoKGksdCl7aSo9SCx0Kj1IO3ZhciBlPVcodCksbj1lKlcoaSkscz1lKnEoaSkscj1xKHQpLG89UHQqci1DdCpzLGE9Q3Qqbi1FdCpyLGM9RXQqcy1QdCpuLGw9X2EobyxhLGMpLGg9RGUobCksdT1sJiYtaC9sO0JhLmFkZCh1Km8pLEZhLmFkZCh1KmEpLElhLmFkZCh1KmMpLHlyKz1oLHdyKz1oKihFdCsoRXQ9bikpLGJyKz1oKihQdCsoUHQ9cykpLE1yKz1oKihDdCsoQ3Q9cikpLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiB4aChpKXtxaT15cj1tcj1ncj14cj13cj1icj1Ncj0wLEJhPW5ldyBMZSxGYT1uZXcgTGUsSWE9bmV3IExlLGxyKGkscGUpO3ZhciB0PStCYSxlPStGYSxuPStJYSxzPV9hKHQsZSxuKTtyZXR1cm4gczxvciYmKHQ9d3IsZT1icixuPU1yLHlyPEsmJih0PW1yLGU9Z3Isbj14cikscz1fYSh0LGUsbiksczxvcik/W05hTixOYU5dOltyZShlLHQpKmh0LERlKG4vcykqaHRdfWZ1bmN0aW9uIE5hKGksdCl7ZnVuY3Rpb24gZShuLHMpe3JldHVybiBuPWkobixzKSx0KG5bMF0sblsxXSl9cmV0dXJuIGkuaW52ZXJ0JiZ0LmludmVydCYmKGUuaW52ZXJ0PWZ1bmN0aW9uKG4scyl7cmV0dXJuIG49dC5pbnZlcnQobixzKSxuJiZpLmludmVydChuWzBdLG5bMV0pfSksZX1mdW5jdGlvbiBSYShpLHQpe3JldHVybiB0dChpKT5YJiYoaS09TWF0aC5yb3VuZChpL1J0KSpSdCksW2ksdF19UmEuaW52ZXJ0PVJhO2Z1bmN0aW9uIHdoKGksdCxlKXtyZXR1cm4oaSU9UnQpP3R8fGU/TmEoTWgoaSksQWgodCxlKSk6TWgoaSk6dHx8ZT9BaCh0LGUpOlJhfWZ1bmN0aW9uIGJoKGkpe3JldHVybiBmdW5jdGlvbih0LGUpe3JldHVybiB0Kz1pLHR0KHQpPlgmJih0LT1NYXRoLnJvdW5kKHQvUnQpKlJ0KSxbdCxlXX19ZnVuY3Rpb24gTWgoaSl7dmFyIHQ9YmgoaSk7cmV0dXJuIHQuaW52ZXJ0PWJoKC1pKSx0fWZ1bmN0aW9uIEFoKGksdCl7dmFyIGU9VyhpKSxuPXEoaSkscz1XKHQpLHI9cSh0KTtmdW5jdGlvbiBvKGEsYyl7dmFyIGw9VyhjKSxoPVcoYSkqbCx1PXEoYSkqbCxmPXEoYyksZD1mKmUraCpuO3JldHVybltyZSh1KnMtZCpyLGgqZS1mKm4pLERlKGQqcyt1KnIpXX1yZXR1cm4gby5pbnZlcnQ9ZnVuY3Rpb24oYSxjKXt2YXIgbD1XKGMpLGg9VyhhKSpsLHU9cShhKSpsLGY9cShjKSxkPWYqcy11KnI7cmV0dXJuW3JlKHUqcytmKnIsaCplK2QqbiksRGUoZCplLWgqbildfSxvfWZ1bmN0aW9uIFNoKGkpe2k9d2goaVswXSpILGlbMV0qSCxpLmxlbmd0aD4yP2lbMl0qSDowKTtmdW5jdGlvbiB0KGUpe3JldHVybiBlPWkoZVswXSpILGVbMV0qSCksZVswXSo9aHQsZVsxXSo9aHQsZX1yZXR1cm4gdC5pbnZlcnQ9ZnVuY3Rpb24oZSl7cmV0dXJuIGU9aS5pbnZlcnQoZVswXSpILGVbMV0qSCksZVswXSo9aHQsZVsxXSo9aHQsZX0sdH1mdW5jdGlvbiBfcChpLHQsZSxuLHMscil7aWYoZSl7dmFyIG89Vyh0KSxhPXEodCksYz1uKmU7cz09bnVsbD8ocz10K24qUnQscj10LWMvMik6KHM9X2gobyxzKSxyPV9oKG8sciksKG4+MD9zPHI6cz5yKSYmKHMrPW4qUnQpKTtmb3IodmFyIGwsaD1zO24+MD9oPnI6aDxyO2gtPWMpbD11cihbbywtYSpXKGgpLC1hKnEoaCldKSxpLnBvaW50KGxbMF0sbFsxXSl9fWZ1bmN0aW9uIF9oKGksdCl7dD1Tbih0KSx0WzBdLT1pLHByKHQpO3ZhciBlPWZwKC10WzFdKTtyZXR1cm4oKC10WzJdPDA/LWU6ZSkrUnQtSyklUnR9ZnVuY3Rpb24gdmgoKXt2YXIgaT1bXSx0O3JldHVybntwb2ludDpmdW5jdGlvbihlLG4scyl7dC5wdXNoKFtlLG4sc10pfSxsaW5lU3RhcnQ6ZnVuY3Rpb24oKXtpLnB1c2godD1bXSl9LGxpbmVFbmQ6X3QscmVqb2luOmZ1bmN0aW9uKCl7aS5sZW5ndGg+MSYmaS5wdXNoKGkucG9wKCkuY29uY2F0KGkuc2hpZnQoKSkpfSxyZXN1bHQ6ZnVuY3Rpb24oKXt2YXIgZT1pO3JldHVybiBpPVtdLHQ9bnVsbCxlfX19ZnVuY3Rpb24gQXIoaSx0KXtyZXR1cm4gdHQoaVswXS10WzBdKTxLJiZ0dChpWzFdLXRbMV0pPEt9ZnVuY3Rpb24gU3IoaSx0LGUsbil7dGhpcy54PWksdGhpcy56PXQsdGhpcy5vPWUsdGhpcy5lPW4sdGhpcy52PSExLHRoaXMubj10aGlzLnA9bnVsbH1mdW5jdGlvbiB6aChpLHQsZSxuLHMpe3ZhciByPVtdLG89W10sYSxjO2lmKGkuZm9yRWFjaChmdW5jdGlvbihwKXtpZighKCh5PXAubGVuZ3RoLTEpPD0wKSl7dmFyIHksbT1wWzBdLGc9cFt5XSxiO2lmKEFyKG0sZykpe2lmKCFtWzJdJiYhZ1syXSl7Zm9yKHMubGluZVN0YXJ0KCksYT0wO2E8eTsrK2Epcy5wb2ludCgobT1wW2FdKVswXSxtWzFdKTtzLmxpbmVFbmQoKTtyZXR1cm59Z1swXSs9MipLfXIucHVzaChiPW5ldyBTcihtLHAsbnVsbCwhMCkpLG8ucHVzaChiLm89bmV3IFNyKG0sbnVsbCxiLCExKSksci5wdXNoKGI9bmV3IFNyKGcscCxudWxsLCExKSksby5wdXNoKGIubz1uZXcgU3IoZyxudWxsLGIsITApKX19KSwhIXIubGVuZ3RoKXtmb3Ioby5zb3J0KHQpLFRoKHIpLFRoKG8pLGE9MCxjPW8ubGVuZ3RoO2E8YzsrK2Epb1thXS5lPWU9IWU7Zm9yKHZhciBsPXJbMF0saCx1Ozspe2Zvcih2YXIgZj1sLGQ9ITA7Zi52OylpZigoZj1mLm4pPT09bClyZXR1cm47aD1mLnoscy5saW5lU3RhcnQoKTtkb3tpZihmLnY9Zi5vLnY9ITAsZi5lKXtpZihkKWZvcihhPTAsYz1oLmxlbmd0aDthPGM7KythKXMucG9pbnQoKHU9aFthXSlbMF0sdVsxXSk7ZWxzZSBuKGYueCxmLm4ueCwxLHMpO2Y9Zi5ufWVsc2V7aWYoZClmb3IoaD1mLnAueixhPWgubGVuZ3RoLTE7YT49MDstLWEpcy5wb2ludCgodT1oW2FdKVswXSx1WzFdKTtlbHNlIG4oZi54LGYucC54LC0xLHMpO2Y9Zi5wfWY9Zi5vLGg9Zi56LGQ9IWR9d2hpbGUoIWYudik7cy5saW5lRW5kKCl9fX1mdW5jdGlvbiBUaChpKXtpZih0PWkubGVuZ3RoKXtmb3IodmFyIHQsZT0wLG49aVswXSxzOysrZTx0OyluLm49cz1pW2VdLHMucD1uLG49cztuLm49cz1pWzBdLHMucD1ufX1mdW5jdGlvbiBMYShpKXtyZXR1cm4gdHQoaVswXSk8PVg/aVswXTpocChpWzBdKSooKHR0KGlbMF0pK1gpJVJ0LVgpfWZ1bmN0aW9uIEVoKGksdCl7dmFyIGU9TGEodCksbj10WzFdLHM9cShuKSxyPVtxKGUpLC1XKGUpLDBdLG89MCxhPTAsYz1uZXcgTGU7cz09PTE/bj1OdCtLOnM9PT0tMSYmKG49LU50LUspO2Zvcih2YXIgbD0wLGg9aS5sZW5ndGg7bDxoOysrbClpZihmPSh1PWlbbF0pLmxlbmd0aClmb3IodmFyIHUsZixkPXVbZi0xXSxwPUxhKGQpLHk9ZFsxXS8yK2FyLG09cSh5KSxnPVcoeSksYj0wO2I8ZjsrK2IscD14LG09QSxnPVMsZD13KXt2YXIgdz11W2JdLHg9TGEodyksTT13WzFdLzIrYXIsQT1xKE0pLFM9VyhNKSxfPXgtcCxFPV8+PTA/MTotMSx6PUUqXyx2PXo+WCxDPW0qQTtpZihjLmFkZChyZShDKkUqcSh6KSxnKlMrQypXKHopKSksbys9dj9fK0UqUnQ6Xyx2XnA+PWVeeD49ZSl7dmFyIFA9bmkoU24oZCksU24odykpO3ByKFApO3ZhciBGPW5pKHIsUCk7cHIoRik7dmFyIEI9KHZeXz49MD8tMToxKSpEZShGWzJdKTsobj5CfHxuPT09QiYmKFBbMF18fFBbMV0pKSYmKGErPXZeXz49MD8xOi0xKX19cmV0dXJuKG88LUt8fG88SyYmYzwtb3IpXmEmMX1mdW5jdGlvbiBQaChpLHQsZSxuKXtyZXR1cm4gZnVuY3Rpb24ocyl7dmFyIHI9dChzKSxvPXZoKCksYT10KG8pLGM9ITEsbCxoLHUsZj17cG9pbnQ6ZCxsaW5lU3RhcnQ6eSxsaW5lRW5kOm0scG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7Zi5wb2ludD1nLGYubGluZVN0YXJ0PWIsZi5saW5lRW5kPXcsaD1bXSxsPVtdfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7Zi5wb2ludD1kLGYubGluZVN0YXJ0PXksZi5saW5lRW5kPW0saD1WaShoKTt2YXIgeD1FaChsLG4pO2gubGVuZ3RoPyhjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSx6aChoLHpwLHgsZSxzKSk6eCYmKGN8fChzLnBvbHlnb25TdGFydCgpLGM9ITApLHMubGluZVN0YXJ0KCksZShudWxsLG51bGwsMSxzKSxzLmxpbmVFbmQoKSksYyYmKHMucG9seWdvbkVuZCgpLGM9ITEpLGg9bD1udWxsfSxzcGhlcmU6ZnVuY3Rpb24oKXtzLnBvbHlnb25TdGFydCgpLHMubGluZVN0YXJ0KCksZShudWxsLG51bGwsMSxzKSxzLmxpbmVFbmQoKSxzLnBvbHlnb25FbmQoKX19O2Z1bmN0aW9uIGQoeCxNKXtpKHgsTSkmJnMucG9pbnQoeCxNKX1mdW5jdGlvbiBwKHgsTSl7ci5wb2ludCh4LE0pfWZ1bmN0aW9uIHkoKXtmLnBvaW50PXAsci5saW5lU3RhcnQoKX1mdW5jdGlvbiBtKCl7Zi5wb2ludD1kLHIubGluZUVuZCgpfWZ1bmN0aW9uIGcoeCxNKXt1LnB1c2goW3gsTV0pLGEucG9pbnQoeCxNKX1mdW5jdGlvbiBiKCl7YS5saW5lU3RhcnQoKSx1PVtdfWZ1bmN0aW9uIHcoKXtnKHVbMF1bMF0sdVswXVsxXSksYS5saW5lRW5kKCk7dmFyIHg9YS5jbGVhbigpLE09by5yZXN1bHQoKSxBLFM9TS5sZW5ndGgsXyxFLHo7aWYodS5wb3AoKSxsLnB1c2godSksdT1udWxsLCEhUyl7aWYoeCYxKXtpZihFPU1bMF0sKF89RS5sZW5ndGgtMSk+MCl7Zm9yKGN8fChzLnBvbHlnb25TdGFydCgpLGM9ITApLHMubGluZVN0YXJ0KCksQT0wO0E8XzsrK0Epcy5wb2ludCgoej1FW0FdKVswXSx6WzFdKTtzLmxpbmVFbmQoKX1yZXR1cm59Uz4xJiZ4JjImJk0ucHVzaChNLnBvcCgpLmNvbmNhdChNLnNoaWZ0KCkpKSxoLnB1c2goTS5maWx0ZXIodnApKX19cmV0dXJuIGZ9fWZ1bmN0aW9uIHZwKGkpe3JldHVybiBpLmxlbmd0aD4xfWZ1bmN0aW9uIHpwKGksdCl7cmV0dXJuKChpPWkueClbMF08MD9pWzFdLU50LUs6TnQtaVsxXSktKCh0PXQueClbMF08MD90WzFdLU50LUs6TnQtdFsxXSl9dmFyIENoPVBoKGZ1bmN0aW9uKCl7cmV0dXJuITB9LFRwLFBwLFstWCwtTnRdKTtmdW5jdGlvbiBUcChpKXt2YXIgdD1OYU4sZT1OYU4sbj1OYU4scztyZXR1cm57bGluZVN0YXJ0OmZ1bmN0aW9uKCl7aS5saW5lU3RhcnQoKSxzPTF9LHBvaW50OmZ1bmN0aW9uKHIsbyl7dmFyIGE9cj4wP1g6LVgsYz10dChyLXQpO3R0KGMtWCk8Sz8oaS5wb2ludCh0LGU9KGUrbykvMj4wP050Oi1OdCksaS5wb2ludChuLGUpLGkubGluZUVuZCgpLGkubGluZVN0YXJ0KCksaS5wb2ludChhLGUpLGkucG9pbnQocixlKSxzPTApOm4hPT1hJiZjPj1YJiYodHQodC1uKTxLJiYodC09bipLKSx0dChyLWEpPEsmJihyLT1hKkspLGU9RXAodCxlLHIsbyksaS5wb2ludChuLGUpLGkubGluZUVuZCgpLGkubGluZVN0YXJ0KCksaS5wb2ludChhLGUpLHM9MCksaS5wb2ludCh0PXIsZT1vKSxuPWF9LGxpbmVFbmQ6ZnVuY3Rpb24oKXtpLmxpbmVFbmQoKSx0PWU9TmFOfSxjbGVhbjpmdW5jdGlvbigpe3JldHVybiAyLXN9fX1mdW5jdGlvbiBFcChpLHQsZSxuKXt2YXIgcyxyLG89cShpLWUpO3JldHVybiB0dChvKT5LP1NhKChxKHQpKihyPVcobikpKnEoZSktcShuKSoocz1XKHQpKSpxKGkpKS8ocypyKm8pKToodCtuKS8yfWZ1bmN0aW9uIFBwKGksdCxlLG4pe3ZhciBzO2lmKGk9PW51bGwpcz1lKk50LG4ucG9pbnQoLVgscyksbi5wb2ludCgwLHMpLG4ucG9pbnQoWCxzKSxuLnBvaW50KFgsMCksbi5wb2ludChYLC1zKSxuLnBvaW50KDAsLXMpLG4ucG9pbnQoLVgsLXMpLG4ucG9pbnQoLVgsMCksbi5wb2ludCgtWCxzKTtlbHNlIGlmKHR0KGlbMF0tdFswXSk+Syl7dmFyIHI9aVswXTx0WzBdP1g6LVg7cz1lKnIvMixuLnBvaW50KC1yLHMpLG4ucG9pbnQoMCxzKSxuLnBvaW50KHIscyl9ZWxzZSBuLnBvaW50KHRbMF0sdFsxXSl9ZnVuY3Rpb24gQ3AoaSl7dmFyIHQ9VyhpKSxlPTIqSCxuPXQ+MCxzPXR0KHQpPks7ZnVuY3Rpb24gcihoLHUsZixkKXtfcChkLGksZSxmLGgsdSl9ZnVuY3Rpb24gbyhoLHUpe3JldHVybiBXKGgpKlcodSk+dH1mdW5jdGlvbiBhKGgpe3ZhciB1LGYsZCxwLHk7cmV0dXJue2xpbmVTdGFydDpmdW5jdGlvbigpe3A9ZD0hMSx5PTF9LHBvaW50OmZ1bmN0aW9uKG0sZyl7dmFyIGI9W20sZ10sdyx4PW8obSxnKSxNPW4/eD8wOmwobSxnKTp4P2wobSsobTwwP1g6LVgpLGcpOjA7aWYoIXUmJihwPWQ9eCkmJmgubGluZVN0YXJ0KCkseCE9PWQmJih3PWModSxiKSwoIXd8fEFyKHUsdyl8fEFyKGIsdykpJiYoYlsyXT0xKSkseCE9PWQpeT0wLHg/KGgubGluZVN0YXJ0KCksdz1jKGIsdSksaC5wb2ludCh3WzBdLHdbMV0pKToodz1jKHUsYiksaC5wb2ludCh3WzBdLHdbMV0sMiksaC5saW5lRW5kKCkpLHU9dztlbHNlIGlmKHMmJnUmJm5eeCl7dmFyIEE7IShNJmYpJiYoQT1jKGIsdSwhMCkpJiYoeT0wLG4/KGgubGluZVN0YXJ0KCksaC5wb2ludChBWzBdWzBdLEFbMF1bMV0pLGgucG9pbnQoQVsxXVswXSxBWzFdWzFdKSxoLmxpbmVFbmQoKSk6KGgucG9pbnQoQVsxXVswXSxBWzFdWzFdKSxoLmxpbmVFbmQoKSxoLmxpbmVTdGFydCgpLGgucG9pbnQoQVswXVswXSxBWzBdWzFdLDMpKSl9eCYmKCF1fHwhQXIodSxiKSkmJmgucG9pbnQoYlswXSxiWzFdKSx1PWIsZD14LGY9TX0sbGluZUVuZDpmdW5jdGlvbigpe2QmJmgubGluZUVuZCgpLHU9bnVsbH0sY2xlYW46ZnVuY3Rpb24oKXtyZXR1cm4geXwocCYmZCk8PDF9fX1mdW5jdGlvbiBjKGgsdSxmKXt2YXIgZD1TbihoKSxwPVNuKHUpLHk9WzEsMCwwXSxtPW5pKGQscCksZz1mcihtLG0pLGI9bVswXSx3PWctYipiO2lmKCF3KXJldHVybiFmJiZoO3ZhciB4PXQqZy93LE09LXQqYi93LEE9bmkoeSxtKSxTPWRyKHkseCksXz1kcihtLE0pO1BhKFMsXyk7dmFyIEU9QSx6PWZyKFMsRSksdj1mcihFLEUpLEM9eip6LXYqKGZyKFMsUyktMSk7aWYoIShDPDApKXt2YXIgUD1PZShDKSxGPWRyKEUsKC16LVApL3YpO2lmKFBhKEYsUyksRj11cihGKSwhZilyZXR1cm4gRjt2YXIgQj1oWzBdLEk9dVswXSxrPWhbMV0sRD11WzFdLFU7STxCJiYoVT1CLEI9SSxJPVUpO3ZhciBqPUktQixkdD10dChqLVgpPEssRHQ9ZHR8fGo8SztpZighZHQmJkQ8ayYmKFU9ayxrPUQsRD1VKSxEdD9kdD9rK0Q+MF5GWzFdPCh0dChGWzBdLUIpPEs/azpEKTprPD1GWzFdJiZGWzFdPD1EOmo+WF4oQjw9RlswXSYmRlswXTw9SSkpe3ZhciBHdD1kcihFLCgteitQKS92KTtyZXR1cm4gUGEoR3QsUyksW0YsdXIoR3QpXX19fWZ1bmN0aW9uIGwoaCx1KXt2YXIgZj1uP2k6WC1pLGQ9MDtyZXR1cm4gaDwtZj9kfD0xOmg+ZiYmKGR8PTIpLHU8LWY/ZHw9NDp1PmYmJihkfD04KSxkfXJldHVybiBQaChvLGEscixuP1swLC1pXTpbLVgsaS1YXSl9ZnVuY3Rpb24gQnAoaSx0LGUsbixzLHIpe3ZhciBvPWlbMF0sYT1pWzFdLGM9dFswXSxsPXRbMV0saD0wLHU9MSxmPWMtbyxkPWwtYSxwO2lmKHA9ZS1vLCEoIWYmJnA+MCkpe2lmKHAvPWYsZjwwKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9ZWxzZSBpZihmPjApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1pZihwPXMtbywhKCFmJiZwPDApKXtpZihwLz1mLGY8MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWVsc2UgaWYoZj4wKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9aWYocD1uLWEsISghZCYmcD4wKSl7aWYocC89ZCxkPDApe2lmKHA8aClyZXR1cm47cDx1JiYodT1wKX1lbHNlIGlmKGQ+MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWlmKHA9ci1hLCEoIWQmJnA8MCkpe2lmKHAvPWQsZDwwKXtpZihwPnUpcmV0dXJuO3A+aCYmKGg9cCl9ZWxzZSBpZihkPjApe2lmKHA8aClyZXR1cm47cDx1JiYodT1wKX1yZXR1cm4gaD4wJiYoaVswXT1vK2gqZixpWzFdPWEraCpkKSx1PDEmJih0WzBdPW8rdSpmLHRbMV09YSt1KmQpLCEwfX19fX12YXIgV2k9MWU5LF9yPS1XaTtmdW5jdGlvbiBGcChpLHQsZSxuKXtmdW5jdGlvbiBzKGwsaCl7cmV0dXJuIGk8PWwmJmw8PWUmJnQ8PWgmJmg8PW59ZnVuY3Rpb24gcihsLGgsdSxmKXt2YXIgZD0wLHA9MDtpZihsPT1udWxsfHwoZD1vKGwsdSkpIT09KHA9byhoLHUpKXx8YyhsLGgpPDBedT4wKWRvIGYucG9pbnQoZD09PTB8fGQ9PT0zP2k6ZSxkPjE/bjp0KTt3aGlsZSgoZD0oZCt1KzQpJTQpIT09cCk7ZWxzZSBmLnBvaW50KGhbMF0saFsxXSl9ZnVuY3Rpb24gbyhsLGgpe3JldHVybiB0dChsWzBdLWkpPEs/aD4wPzA6Mzp0dChsWzBdLWUpPEs/aD4wPzI6MTp0dChsWzFdLXQpPEs/aD4wPzE6MDpoPjA/MzoyfWZ1bmN0aW9uIGEobCxoKXtyZXR1cm4gYyhsLngsaC54KX1mdW5jdGlvbiBjKGwsaCl7dmFyIHU9byhsLDEpLGY9byhoLDEpO3JldHVybiB1IT09Zj91LWY6dT09PTA/aFsxXS1sWzFdOnU9PT0xP2xbMF0taFswXTp1PT09Mj9sWzFdLWhbMV06aFswXS1sWzBdfXJldHVybiBmdW5jdGlvbihsKXt2YXIgaD1sLHU9dmgoKSxmLGQscCx5LG0sZyxiLHcseCxNLEEsUz17cG9pbnQ6XyxsaW5lU3RhcnQ6QyxsaW5lRW5kOlAscG9seWdvblN0YXJ0OnoscG9seWdvbkVuZDp2fTtmdW5jdGlvbiBfKEIsSSl7cyhCLEkpJiZoLnBvaW50KEIsSSl9ZnVuY3Rpb24gRSgpe2Zvcih2YXIgQj0wLEk9MCxrPWQubGVuZ3RoO0k8azsrK0kpZm9yKHZhciBEPWRbSV0sVT0xLGo9RC5sZW5ndGgsZHQ9RFswXSxEdCxHdCxadD1kdFswXSxtZT1kdFsxXTtVPGo7KytVKUR0PVp0LEd0PW1lLGR0PURbVV0sWnQ9ZHRbMF0sbWU9ZHRbMV0sR3Q8PW4/bWU+biYmKFp0LUR0KSoobi1HdCk+KG1lLUd0KSooaS1EdCkmJisrQjptZTw9biYmKFp0LUR0KSoobi1HdCk8KG1lLUd0KSooaS1EdCkmJi0tQjtyZXR1cm4gQn1mdW5jdGlvbiB6KCl7aD11LGY9W10sZD1bXSxBPSEwfWZ1bmN0aW9uIHYoKXt2YXIgQj1FKCksST1BJiZCLGs9KGY9VmkoZikpLmxlbmd0aDsoSXx8aykmJihsLnBvbHlnb25TdGFydCgpLEkmJihsLmxpbmVTdGFydCgpLHIobnVsbCxudWxsLDEsbCksbC5saW5lRW5kKCkpLGsmJnpoKGYsYSxCLHIsbCksbC5wb2x5Z29uRW5kKCkpLGg9bCxmPWQ9cD1udWxsfWZ1bmN0aW9uIEMoKXtTLnBvaW50PUYsZCYmZC5wdXNoKHA9W10pLE09ITAseD0hMSxiPXc9TmFOfWZ1bmN0aW9uIFAoKXtmJiYoRih5LG0pLGcmJngmJnUucmVqb2luKCksZi5wdXNoKHUucmVzdWx0KCkpKSxTLnBvaW50PV8seCYmaC5saW5lRW5kKCl9ZnVuY3Rpb24gRihCLEkpe3ZhciBrPXMoQixJKTtpZihkJiZwLnB1c2goW0IsSV0pLE0peT1CLG09SSxnPWssTT0hMSxrJiYoaC5saW5lU3RhcnQoKSxoLnBvaW50KEIsSSkpO2Vsc2UgaWYoayYmeCloLnBvaW50KEIsSSk7ZWxzZXt2YXIgRD1bYj1NYXRoLm1heChfcixNYXRoLm1pbihXaSxiKSksdz1NYXRoLm1heChfcixNYXRoLm1pbihXaSx3KSldLFU9W0I9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksQikpLEk9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksSSkpXTtCcChELFUsaSx0LGUsbik/KHh8fChoLmxpbmVTdGFydCgpLGgucG9pbnQoRFswXSxEWzFdKSksaC5wb2ludChVWzBdLFVbMV0pLGt8fGgubGluZUVuZCgpLEE9ITEpOmsmJihoLmxpbmVTdGFydCgpLGgucG9pbnQoQixJKSxBPSExKX1iPUIsdz1JLHg9a31yZXR1cm4gU319dmFyIE9hLERhLHZyLHpyLHNpPXtzcGhlcmU6X3QscG9pbnQ6X3QsbGluZVN0YXJ0OklwLGxpbmVFbmQ6X3QscG9seWdvblN0YXJ0Ol90LHBvbHlnb25FbmQ6X3R9O2Z1bmN0aW9uIElwKCl7c2kucG9pbnQ9TnAsc2kubGluZUVuZD1rcH1mdW5jdGlvbiBrcCgpe3NpLnBvaW50PXNpLmxpbmVFbmQ9X3R9ZnVuY3Rpb24gTnAoaSx0KXtpKj1ILHQqPUgsRGE9aSx2cj1xKHQpLHpyPVcodCksc2kucG9pbnQ9UnB9ZnVuY3Rpb24gUnAoaSx0KXtpKj1ILHQqPUg7dmFyIGU9cSh0KSxuPVcodCkscz10dChpLURhKSxyPVcocyksbz1xKHMpLGE9bipvLGM9enIqZS12cipuKnIsbD12ciplK3pyKm4qcjtPYS5hZGQocmUoT2UoYSphK2MqYyksbCkpLERhPWksdnI9ZSx6cj1ufWZ1bmN0aW9uIExwKGkpe3JldHVybiBPYT1uZXcgTGUsbHIoaSxzaSksK09hfXZhciAkYT1bbnVsbCxudWxsXSxPcD17dHlwZToiTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6JGF9O2Z1bmN0aW9uIHJpKGksdCl7cmV0dXJuICRhWzBdPWksJGFbMV09dCxMcChPcCl9dmFyIEJoPXtGZWF0dXJlOmZ1bmN0aW9uKGksdCl7cmV0dXJuIFRyKGkuZ2VvbWV0cnksdCl9LEZlYXR1cmVDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZmVhdHVyZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihUcihlW25dLmdlb21ldHJ5LHQpKXJldHVybiEwO3JldHVybiExfX0sRmg9e1NwaGVyZTpmdW5jdGlvbigpe3JldHVybiEwfSxQb2ludDpmdW5jdGlvbihpLHQpe3JldHVybiBJaChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aVBvaW50OmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihJaChlW25dLHQpKXJldHVybiEwO3JldHVybiExfSxMaW5lU3RyaW5nOmZ1bmN0aW9uKGksdCl7cmV0dXJuIGtoKGkuY29vcmRpbmF0ZXMsdCl9LE11bHRpTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoa2goZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX0sUG9seWdvbjpmdW5jdGlvbihpLHQpe3JldHVybiBOaChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aVBvbHlnb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWlmKE5oKGVbbl0sdCkpcmV0dXJuITA7cmV0dXJuITF9LEdlb21ldHJ5Q29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmdlb21ldHJpZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihUcihlW25dLHQpKXJldHVybiEwO3JldHVybiExfX07ZnVuY3Rpb24gVHIoaSx0KXtyZXR1cm4gaSYmRmguaGFzT3duUHJvcGVydHkoaS50eXBlKT9GaFtpLnR5cGVdKGksdCk6ITF9ZnVuY3Rpb24gSWgoaSx0KXtyZXR1cm4gcmkoaSx0KT09PTB9ZnVuY3Rpb24ga2goaSx0KXtmb3IodmFyIGUsbixzLHI9MCxvPWkubGVuZ3RoO3I8bztyKyspe2lmKG49cmkoaVtyXSx0KSxuPT09MHx8cj4wJiYocz1yaShpW3JdLGlbci0xXSkscz4wJiZlPD1zJiZuPD1zJiYoZStuLXMpKigxLU1hdGgucG93KChlLW4pL3MsMikpPG9yKnMpKXJldHVybiEwO2U9bn1yZXR1cm4hMX1mdW5jdGlvbiBOaChpLHQpe3JldHVybiEhRWgoaS5tYXAoRHApLFJoKHQpKX1mdW5jdGlvbiBEcChpKXtyZXR1cm4gaT1pLm1hcChSaCksaS5wb3AoKSxpfWZ1bmN0aW9uIFJoKGkpe3JldHVybltpWzBdKkgsaVsxXSpIXX1mdW5jdGlvbiAkcChpLHQpe3JldHVybihpJiZCaC5oYXNPd25Qcm9wZXJ0eShpLnR5cGUpP0JoW2kudHlwZV06VHIpKGksdCl9ZnVuY3Rpb24gVnAoaSx0KXt2YXIgZT1pWzBdKkgsbj1pWzFdKkgscz10WzBdKkgscj10WzFdKkgsbz1XKG4pLGE9cShuKSxjPVcociksbD1xKHIpLGg9bypXKGUpLHU9bypxKGUpLGY9YypXKHMpLGQ9YypxKHMpLHA9MipEZShPZShqbChyLW4pK28qYypqbChzLWUpKSkseT1xKHApLG09cD9mdW5jdGlvbihnKXt2YXIgYj1xKGcqPXApL3ksdz1xKHAtZykveSx4PXcqaCtiKmYsTT13KnUrYipkLEE9dyphK2IqbDtyZXR1cm5bcmUoTSx4KSpodCxyZShBLE9lKHgqeCtNKk0pKSpodF19OmZ1bmN0aW9uKCl7cmV0dXJuW2UqaHQsbipodF19O3JldHVybiBtLmRpc3RhbmNlPXAsbX12YXIgTGg9aT0+aSxvaT0xLzAsRXI9b2ksR2k9LW9pLFByPUdpLE9oPXtwb2ludDpVcCxsaW5lU3RhcnQ6X3QsbGluZUVuZDpfdCxwb2x5Z29uU3RhcnQ6X3QscG9seWdvbkVuZDpfdCxyZXN1bHQ6ZnVuY3Rpb24oKXt2YXIgaT1bW29pLEVyXSxbR2ksUHJdXTtyZXR1cm4gR2k9UHI9LShFcj1vaT0xLzApLGl9fTtmdW5jdGlvbiBVcChpLHQpe2k8b2kmJihvaT1pKSxpPkdpJiYoR2k9aSksdDxFciYmKEVyPXQpLHQ+UHImJihQcj10KX1mdW5jdGlvbiBWYShpKXtyZXR1cm4gZnVuY3Rpb24odCl7dmFyIGU9bmV3IFVhO2Zvcih2YXIgbiBpbiBpKWVbbl09aVtuXTtyZXR1cm4gZS5zdHJlYW09dCxlfX1mdW5jdGlvbiBVYSgpe31VYS5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlVhLHBvaW50OmZ1bmN0aW9uKGksdCl7dGhpcy5zdHJlYW0ucG9pbnQoaSx0KX0sc3BoZXJlOmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0uc3BoZXJlKCl9LGxpbmVTdGFydDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLmxpbmVTdGFydCgpfSxsaW5lRW5kOmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0ubGluZUVuZCgpfSxwb2x5Z29uU3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5wb2x5Z29uU3RhcnQoKX0scG9seWdvbkVuZDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLnBvbHlnb25FbmQoKX19O2Z1bmN0aW9uIHFhKGksdCxlKXt2YXIgbj1pLmNsaXBFeHRlbnQmJmkuY2xpcEV4dGVudCgpO3JldHVybiBpLnNjYWxlKDE1MCkudHJhbnNsYXRlKFswLDBdKSxuIT1udWxsJiZpLmNsaXBFeHRlbnQobnVsbCksbHIoZSxpLnN0cmVhbShPaCkpLHQoT2gucmVzdWx0KCkpLG4hPW51bGwmJmkuY2xpcEV4dGVudChuKSxpfWZ1bmN0aW9uIERoKGksdCxlKXtyZXR1cm4gcWEoaSxmdW5jdGlvbihuKXt2YXIgcz10WzFdWzBdLXRbMF1bMF0scj10WzFdWzFdLXRbMF1bMV0sbz1NYXRoLm1pbihzLyhuWzFdWzBdLW5bMF1bMF0pLHIvKG5bMV1bMV0tblswXVsxXSkpLGE9K3RbMF1bMF0rKHMtbyooblsxXVswXStuWzBdWzBdKSkvMixjPSt0WzBdWzFdKyhyLW8qKG5bMV1bMV0rblswXVsxXSkpLzI7aS5zY2FsZSgxNTAqbykudHJhbnNsYXRlKFthLGNdKX0sZSl9ZnVuY3Rpb24gcXAoaSx0LGUpe3JldHVybiBEaChpLFtbMCwwXSx0XSxlKX1mdW5jdGlvbiBIcChpLHQsZSl7cmV0dXJuIHFhKGksZnVuY3Rpb24obil7dmFyIHM9K3Qscj1zLyhuWzFdWzBdLW5bMF1bMF0pLG89KHMtciooblsxXVswXStuWzBdWzBdKSkvMixhPS1yKm5bMF1bMV07aS5zY2FsZSgxNTAqcikudHJhbnNsYXRlKFtvLGFdKX0sZSl9ZnVuY3Rpb24gV3AoaSx0LGUpe3JldHVybiBxYShpLGZ1bmN0aW9uKG4pe3ZhciBzPSt0LHI9cy8oblsxXVsxXS1uWzBdWzFdKSxvPS1yKm5bMF1bMF0sYT0ocy1yKihuWzFdWzFdK25bMF1bMV0pKS8yO2kuc2NhbGUoMTUwKnIpLnRyYW5zbGF0ZShbbyxhXSl9LGUpfXZhciAkaD0xNixHcD1XKDMwKkgpO2Z1bmN0aW9uIFZoKGksdCl7cmV0dXJuK3Q/WHAoaSx0KTpacChpKX1mdW5jdGlvbiBacChpKXtyZXR1cm4gVmEoe3BvaW50OmZ1bmN0aW9uKHQsZSl7dD1pKHQsZSksdGhpcy5zdHJlYW0ucG9pbnQodFswXSx0WzFdKX19KX1mdW5jdGlvbiBYcChpLHQpe2Z1bmN0aW9uIGUobixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXt2YXIgZz1sLW4sYj1oLXMsdz1nKmcrYipiO2lmKHc+NCp0JiZ5LS0pe3ZhciB4PW8rZixNPWErZCxBPWMrcCxTPU9lKHgqeCtNKk0rQSpBKSxfPURlKEEvPVMpLEU9dHQodHQoQSktMSk8S3x8dHQoci11KTxLPyhyK3UpLzI6cmUoTSx4KSx6PWkoRSxfKSx2PXpbMF0sQz16WzFdLFA9di1uLEY9Qy1zLEI9YipQLWcqRjsoQipCL3c+dHx8dHQoKGcqUCtiKkYpL3ctLjUpPi4zfHxvKmYrYSpkK2MqcDxHcCkmJihlKG4scyxyLG8sYSxjLHYsQyxFLHgvPVMsTS89UyxBLHksbSksbS5wb2ludCh2LEMpLGUodixDLEUseCxNLEEsbCxoLHUsZixkLHAseSxtKSl9fXJldHVybiBmdW5jdGlvbihuKXt2YXIgcyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbT17cG9pbnQ6ZyxsaW5lU3RhcnQ6YixsaW5lRW5kOngscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7bi5wb2x5Z29uU3RhcnQoKSxtLmxpbmVTdGFydD1NfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7bi5wb2x5Z29uRW5kKCksbS5saW5lU3RhcnQ9Yn19O2Z1bmN0aW9uIGcoXyxFKXtfPWkoXyxFKSxuLnBvaW50KF9bMF0sX1sxXSl9ZnVuY3Rpb24gYigpe3U9TmFOLG0ucG9pbnQ9dyxuLmxpbmVTdGFydCgpfWZ1bmN0aW9uIHcoXyxFKXt2YXIgej1TbihbXyxFXSksdj1pKF8sRSk7ZSh1LGYsaCxkLHAseSx1PXZbMF0sZj12WzFdLGg9XyxkPXpbMF0scD16WzFdLHk9elsyXSwkaCxuKSxuLnBvaW50KHUsZil9ZnVuY3Rpb24geCgpe20ucG9pbnQ9ZyxuLmxpbmVFbmQoKX1mdW5jdGlvbiBNKCl7YigpLG0ucG9pbnQ9QSxtLmxpbmVFbmQ9U31mdW5jdGlvbiBBKF8sRSl7dyhzPV8sRSkscj11LG89ZixhPWQsYz1wLGw9eSxtLnBvaW50PXd9ZnVuY3Rpb24gUygpe2UodSxmLGgsZCxwLHkscixvLHMsYSxjLGwsJGgsbiksbS5saW5lRW5kPXgseCgpfXJldHVybiBtfX12YXIgSnA9VmEoe3BvaW50OmZ1bmN0aW9uKGksdCl7dGhpcy5zdHJlYW0ucG9pbnQoaSpILHQqSCl9fSk7ZnVuY3Rpb24gWXAoaSl7cmV0dXJuIFZhKHtwb2ludDpmdW5jdGlvbih0LGUpe3ZhciBuPWkodCxlKTtyZXR1cm4gdGhpcy5zdHJlYW0ucG9pbnQoblswXSxuWzFdKX19KX1mdW5jdGlvbiBqcChpLHQsZSxuLHMpe2Z1bmN0aW9uIHIobyxhKXtyZXR1cm4gbyo9bixhKj1zLFt0K2kqbyxlLWkqYV19cmV0dXJuIHIuaW52ZXJ0PWZ1bmN0aW9uKG8sYSl7cmV0dXJuWyhvLXQpL2kqbiwoZS1hKS9pKnNdfSxyfWZ1bmN0aW9uIFVoKGksdCxlLG4scyxyKXtpZighcilyZXR1cm4ganAoaSx0LGUsbixzKTt2YXIgbz1XKHIpLGE9cShyKSxjPW8qaSxsPWEqaSxoPW8vaSx1PWEvaSxmPShhKmUtbyp0KS9pLGQ9KGEqdCtvKmUpL2k7ZnVuY3Rpb24gcCh5LG0pe3JldHVybiB5Kj1uLG0qPXMsW2MqeS1sKm0rdCxlLWwqeS1jKm1dfXJldHVybiBwLmludmVydD1mdW5jdGlvbih5LG0pe3JldHVybltuKihoKnktdSptK2YpLHMqKGQtdSp5LWgqbSldfSxwfWZ1bmN0aW9uIENyKGkpe3JldHVybiBRcChmdW5jdGlvbigpe3JldHVybiBpfSkoKX1mdW5jdGlvbiBRcChpKXt2YXIgdCxlPTE1MCxuPTQ4MCxzPTI1MCxyPTAsbz0wLGE9MCxjPTAsbD0wLGgsdT0wLGY9MSxkPTEscD1udWxsLHk9Q2gsbT1udWxsLGcsYix3LHg9TGgsTT0uNSxBLFMsXyxFLHo7ZnVuY3Rpb24gdihCKXtyZXR1cm4gXyhCWzBdKkgsQlsxXSpIKX1mdW5jdGlvbiBDKEIpe3JldHVybiBCPV8uaW52ZXJ0KEJbMF0sQlsxXSksQiYmW0JbMF0qaHQsQlsxXSpodF19di5zdHJlYW09ZnVuY3Rpb24oQil7cmV0dXJuIEUmJno9PT1CP0U6RT1KcChZcChoKSh5KEEoeCh6PUIpKSkpKX0sdi5wcmVjbGlwPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh5PUIscD12b2lkIDAsRigpKTp5fSx2LnBvc3RjbGlwPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh4PUIsbT1nPWI9dz1udWxsLEYoKSk6eH0sdi5jbGlwQW5nbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHk9K0I/Q3AocD1CKkgpOihwPW51bGwsQ2gpLEYoKSk6cCpodH0sdi5jbGlwRXh0ZW50PWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh4PUI9PW51bGw/KG09Zz1iPXc9bnVsbCxMaCk6RnAobT0rQlswXVswXSxnPStCWzBdWzFdLGI9K0JbMV1bMF0sdz0rQlsxXVsxXSksRigpKTptPT1udWxsP251bGw6W1ttLGddLFtiLHddXX0sdi5zY2FsZT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZT0rQixQKCkpOmV9LHYudHJhbnNsYXRlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhuPStCWzBdLHM9K0JbMV0sUCgpKTpbbixzXX0sdi5jZW50ZXI9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHI9QlswXSUzNjAqSCxvPUJbMV0lMzYwKkgsUCgpKTpbcipodCxvKmh0XX0sdi5yb3RhdGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGE9QlswXSUzNjAqSCxjPUJbMV0lMzYwKkgsbD1CLmxlbmd0aD4yP0JbMl0lMzYwKkg6MCxQKCkpOlthKmh0LGMqaHQsbCpodF19LHYuYW5nbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHU9QiUzNjAqSCxQKCkpOnUqaHR9LHYucmVmbGVjdFg9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGY9Qj8tMToxLFAoKSk6ZjwwfSx2LnJlZmxlY3RZPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhkPUI/LTE6MSxQKCkpOmQ8MH0sdi5wcmVjaXNpb249ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KEE9VmgoUyxNPUIqQiksRigpKTpPZShNKX0sdi5maXRFeHRlbnQ9ZnVuY3Rpb24oQixJKXtyZXR1cm4gRGgodixCLEkpfSx2LmZpdFNpemU9ZnVuY3Rpb24oQixJKXtyZXR1cm4gcXAodixCLEkpfSx2LmZpdFdpZHRoPWZ1bmN0aW9uKEIsSSl7cmV0dXJuIEhwKHYsQixJKX0sdi5maXRIZWlnaHQ9ZnVuY3Rpb24oQixJKXtyZXR1cm4gV3AodixCLEkpfTtmdW5jdGlvbiBQKCl7dmFyIEI9VWgoZSwwLDAsZixkLHUpLmFwcGx5KG51bGwsdChyLG8pKSxJPVVoKGUsbi1CWzBdLHMtQlsxXSxmLGQsdSk7cmV0dXJuIGg9d2goYSxjLGwpLFM9TmEodCxJKSxfPU5hKGgsUyksQT1WaChTLE0pLEYoKX1mdW5jdGlvbiBGKCl7cmV0dXJuIEU9ej1udWxsLHZ9cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHQ9aS5hcHBseSh0aGlzLGFyZ3VtZW50cyksdi5pbnZlcnQ9dC5pbnZlcnQmJkMsUCgpfX1mdW5jdGlvbiBLcChpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXt2YXIgbj1PZSh0KnQrZSplKSxzPWkobikscj1xKHMpLG89VyhzKTtyZXR1cm5bcmUodCpyLG4qbyksRGUobiYmZSpyL24pXX19ZnVuY3Rpb24gSGEoaSx0KXtyZXR1cm5baSxscCh1cCgoTnQrdCkvMikpXX1IYS5pbnZlcnQ9ZnVuY3Rpb24oaSx0KXtyZXR1cm5baSwyKlNhKGNwKHQpKS1OdF19O2Z1bmN0aW9uIHR5KCl7cmV0dXJuIGV5KEhhKS5zY2FsZSg5NjEvUnQpfWZ1bmN0aW9uIGV5KGkpe3ZhciB0PUNyKGkpLGU9dC5jZW50ZXIsbj10LnNjYWxlLHM9dC50cmFuc2xhdGUscj10LmNsaXBFeHRlbnQsbz1udWxsLGEsYyxsO3Quc2NhbGU9ZnVuY3Rpb24odSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KG4odSksaCgpKTpuKCl9LHQudHJhbnNsYXRlPWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhzKHUpLGgoKSk6cygpfSx0LmNlbnRlcj1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZSh1KSxoKCkpOmUoKX0sdC5jbGlwRXh0ZW50PWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh1PT1udWxsP289YT1jPWw9bnVsbDoobz0rdVswXVswXSxhPSt1WzBdWzFdLGM9K3VbMV1bMF0sbD0rdVsxXVsxXSksaCgpKTpvPT1udWxsP251bGw6W1tvLGFdLFtjLGxdXX07ZnVuY3Rpb24gaCgpe3ZhciB1PVgqbigpLGY9dChTaCh0LnJvdGF0ZSgpKS5pbnZlcnQoWzAsMF0pKTtyZXR1cm4gcihvPT1udWxsP1tbZlswXS11LGZbMV0tdV0sW2ZbMF0rdSxmWzFdK3VdXTppPT09SGE/W1tNYXRoLm1heChmWzBdLXUsbyksYV0sW01hdGgubWluKGZbMF0rdSxjKSxsXV06W1tvLE1hdGgubWF4KGZbMV0tdSxhKV0sW2MsTWF0aC5taW4oZlsxXSt1LGwpXV0pfXJldHVybiBoKCl9ZnVuY3Rpb24gV2EoaSx0KXtyZXR1cm5baSx0XX1XYS5pbnZlcnQ9V2E7ZnVuY3Rpb24gbnkoKXtyZXR1cm4gQ3IoV2EpLnNjYWxlKDE1Mi42Myl9ZnVuY3Rpb24gcWgoaSx0KXt2YXIgZT1XKHQpLG49MStXKGkpKmU7cmV0dXJuW2UqcShpKS9uLHEodCkvbl19cWguaW52ZXJ0PUtwKGZ1bmN0aW9uKGkpe3JldHVybiAyKlNhKGkpfSk7ZnVuY3Rpb24gaXkoKXtyZXR1cm4gQ3IocWgpLnNjYWxlKDI1MCkuY2xpcEFuZ2xlKDE0Mil9dmFyIEJyPU1hdGguYWJzLGFpPU1hdGguY29zLGJlPU1hdGguc2luLFppPTFlLTYsRnI9TWF0aC5QSSxHYT1Gci8yO2Z1bmN0aW9uIHN5KGkpe3JldHVybiBpP2kvTWF0aC5zaW4oaSk6MX1mdW5jdGlvbiBaYShpKXtyZXR1cm4gaT4xPzA6aTwtMT9GcjpNYXRoLmFjb3MoaSl9ZnVuY3Rpb24gSGgoaSl7cmV0dXJuIGk+MD9NYXRoLnNxcnQoaSk6MH1mdW5jdGlvbiBXaChpLHQpe3ZhciBlPWFpKHQpLG49c3koWmEoZSphaShpLz0yKSkpO3JldHVyblsyKmUqYmUoaSkqbixiZSh0KSpuXX1XaC5pbnZlcnQ9ZnVuY3Rpb24oaSx0KXtpZighKGkqaSs0KnQqdD5GcipGcitaaSkpe3ZhciBlPWksbj10LHM9MjU7ZG97dmFyIHI9YmUoZSksbz1iZShlLzIpLGE9YWkoZS8yKSxjPWJlKG4pLGw9YWkobiksaD1iZSgyKm4pLHU9YypjLGY9bCpsLGQ9bypvLHA9MS1mKmEqYSx5PXA/WmEobCphKSpIaChtPTEvcCk6bT0wLG0sZz0yKnkqbCpvLWksYj15KmMtdCx3PW0qKGYqZCt5KmwqYSp1KSx4PW0qKC41KnIqaC15KjIqYypvKSxNPW0qLjI1KihoKm8teSpjKmYqciksQT1tKih1KmEreSpkKmwpLFM9eCpNLUEqdztpZighUylicmVhazt2YXIgXz0oYip4LWcqQSkvUyxFPShnKk0tYip3KS9TO2UtPV8sbi09RX13aGlsZSgoQnIoXyk+Wml8fEJyKEUpPlppKSYmLS1zPjApO3JldHVybltlLG5dfX07ZnVuY3Rpb24gR2goaSx0KXt2YXIgZT1XaChpLHQpO3JldHVyblsoZVswXStpL0dhKS8yLChlWzFdK3QpLzJdfUdoLmludmVydD1mdW5jdGlvbihpLHQpe3ZhciBlPWksbj10LHM9MjU7ZG97dmFyIHI9YWkobiksbz1iZShuKSxhPWJlKDIqbiksYz1vKm8sbD1yKnIsaD1iZShlKSx1PWFpKGUvMiksZj1iZShlLzIpLGQ9ZipmLHA9MS1sKnUqdSx5PXA/WmEocip1KSpIaChtPTEvcCk6bT0wLG0sZz0uNSooMip5KnIqZitlL0dhKS1pLGI9LjUqKHkqbytuKS10LHc9LjUqbSoobCpkK3kqcip1KmMpKy41L0dhLHg9bSooaCphLzQteSpvKmYpLE09LjEyNSptKihhKmYteSpvKmwqaCksQT0uNSptKihjKnUreSpkKnIpKy41LFM9eCpNLUEqdyxfPShiKngtZypBKS9TLEU9KGcqTS1iKncpL1M7ZS09XyxuLT1FfXdoaWxlKChCcihfKT5aaXx8QnIoRSk+WmkpJiYtLXM+MCk7cmV0dXJuW2Usbl19O2Z1bmN0aW9uIHJ5KCl7cmV0dXJuIENyKEdoKS5zY2FsZSgxNTguODM3KX1jb25zdCBveT17bWVyY2F0b3I6dHksZXF1aXJlY3Rhbmd1bGFyOm55LHdpbmtlbDM6cnl9LFhhPXt9LFhpPWk9Pnt2YXIgbixzLHI7Y29uc3QgdD1KU09OLnN0cmluZ2lmeShpKTtpZihYYVt0XSlyZXR1cm4gWGFbdF07Y29uc3QgZT1veVsobj1pLnByb2plY3Rpb25UeXBlKSE9bnVsbD9uOiJtZXJjYXRvciJdKCkuY2VudGVyKGkuY2VudGVyKS5zY2FsZShpLnNjYWxlKS50cmFuc2xhdGUoKHM9aS50cmFuc2xhdGUpIT1udWxsP3M6WzAsMF0pLnByZWNpc2lvbigocj1pLnByZWNpc2lvbikhPW51bGw/cjouMSk7cmV0dXJuIGkucm90YXRlJiZlLnJvdGF0ZShpLnJvdGF0ZSksWGFbdF09ZSxlfSxJcj0oaSx0KT0+aS5tYXAoKFtlLG5dKT0+e2xldCBzO2lmKHQpe2NvbnN0W3Isb109dChbZSxuXSk7cz1uZXcgUihyLC1vKX1lbHNlIHM9bmV3IFIoZSxuKTtyZXR1cm4gc30pO3ZhciBKaT0oaSx0KT0+e2NvbnN0IGU9SmwoaSx0IT1udWxsP3Q6MCksbj17fSxzPVtdLHI9T2JqZWN0LmtleXMoZS5hdHRyaWJ1dGVzKTtyZXR1cm4gZS5pbmRleCYmci5wdXNoKCJpbmRleCIpLHIuZm9yRWFjaChvPT57Y29uc3QgYT1vPT09ImluZGV4Ij9lLmluZGV4OmUuYXR0cmlidXRlc1tvXTtuW29dPXthcnJheTphLmFycmF5LGl0ZW1TaXplOmEuaXRlbVNpemV9LHMucHVzaChhLmFycmF5LmJ1ZmZlcil9KSx0JiYobi5ncm91cHM9ZS5ncm91cHMpLGUuZGlzcG9zZSgpLGkuZm9yRWFjaChvPT57by5kaXNwb3NlKCl9KSx7bWVzc2FnZTpuLHRyYW5zZmVyOnN9fSxKYT0oaSx0PTMwMCk9Pntjb25zdCBlPVtdO3JldHVybiBpLmZvckVhY2gobj0+e2xldCBzPSExO2ZvcihsZXQgcj0xO3I8bi5sZW5ndGg7cisrKWlmKE1hdGguYWJzKG5bcl0ueC1uW3ItMV0ueCk+dCl7cz0hMDticmVha31pZihzKXtjb25zdCByPVtdLG89W107bi5mb3JFYWNoKGE9PnthLng8MD9yLnB1c2goYSk6by5wdXNoKGEpfSksZS5wdXNoKHIsbyl9ZWxzZSBlLnB1c2gobil9KSxlfTtmdW5jdGlvbiBheShpLHQsZT0wKXtjb25zdFtuLHMscixvXT1pO2xldCBhPTEvMCxjPTEvMCxsPS0xLzAsaD0tMS8wO2ZvcihsZXQgdT0wO3U8PWU7dSsrKXtjb25zdCBmPWUmJnUvZTtJcihbW24rZiooci1uKSxzXSxbbitmKihyLW4pLG9dLFtuLHMrZiooby1zKV0sW3IscytmKihvLXMpXV0sdCkuZm9yRWFjaChkPT57YT1NYXRoLm1pbihhLGQueCksYz1NYXRoLm1pbihjLGQueSksbD1NYXRoLm1heChsLGQueCksaD1NYXRoLm1heChoLGQueSl9KX1yZXR1cm5bW2EsY10sW2wsaF1dfWNvbnN0IGN5PSh7Y29vcmRpbmF0ZXNBcnI6aSxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxiYm94Om4sZGVwdGg6cyxwcm9qZWN0aW9uOnIsdXNlR3JvdXBzOm8saGFzVG9wOmEsaGFzQm90dG9tOmMsaGFzU2lkZTpsLHNwbGl0UG9seWdvbnM6aCx0b3BTZWdtZW50czp1fSk9Pntjb25zdCBmPXImJlhpKHIpO2xldCBkPWkubWFwKG09PklyKG0sZikpO2gmJihkPUphKGQsaCkpO2xldCBwO2lmKG4pe2NvbnN0W20sZ109YXkobixyIT1udWxsJiZyLnJvdGF0ZT9YaShaZShGdCh7fSxyKSx7cm90YXRlOnZvaWQgMH0pKTpmLChyPT1udWxsP3ZvaWQgMDpyLnByb2plY3Rpb25UeXBlKT09PSJ3aW5rZWwzIj8xMDowKTtwPW5ldyBndChuZXcgVChtWzBdLG1bMV0sMCksbmV3IFQoZ1swXSxnWzFdLDApKX1jb25zdCB5PWQubWFwKChtLGcpPT57dmFyIGI7cmV0dXJuIEowKHtwb2ludHM6bSxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxkZXB0aDooYj1zW2ddKSE9bnVsbD9iOnNbMF0saGFzVG9wOmEsaGFzQm90dG9tOmMsaGFzU2lkZTpsLGJveDM6cCx0b3BTZWdtZW50czp1fSl9KTtyZXR1cm4gSmkoeSxvKX07ZnVuY3Rpb24gWWEoaSx0LGUsbixzKXtsZXQgcjtpZihpPWkuc3ViYXJyYXl8fGkuc2xpY2U/aTppLmJ1ZmZlcixlPWUuc3ViYXJyYXl8fGUuc2xpY2U/ZTplLmJ1ZmZlcixpPXQ/aS5zdWJhcnJheT9pLnN1YmFycmF5KHQscyYmdCtzKTppLnNsaWNlKHQscyYmdCtzKTppLGUuc2V0KWUuc2V0KGksbik7ZWxzZSBmb3Iocj0wO3I8aS5sZW5ndGg7cisrKWVbcituXT1pW3JdO3JldHVybiBlfWZ1bmN0aW9uIGx5KGkpe3JldHVybiBpIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5P2k6aSBpbnN0YW5jZW9mIHVlP2kuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLmFycmF5OmkubWFwKHQ9Pntjb25zdCBlPUFycmF5LmlzQXJyYXkodCk7cmV0dXJuIHQgaW5zdGFuY2VvZiBUP1t0LngsdC55LHQuel06dCBpbnN0YW5jZW9mIFI/W3QueCx0LnksMF06ZSYmdC5sZW5ndGg9PT0zP1t0WzBdLHRbMV0sdFsyXV06ZSYmdC5sZW5ndGg9PT0yP1t0WzBdLHRbMV0sMF06dH0pLmZsYXQoKX1jbGFzcyBoeSBleHRlbmRzIHVle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9Ik1lc2hMaW5lIix0aGlzLmlzTWVzaExpbmU9ITAsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdLHRoaXMuY291bnRlcnM9W10sdGhpcy53aWR0aENhbGxiYWNrPW51bGwsdGhpcy5fcG9pbnRzPVtdLHRoaXMubWF0cml4V29ybGQ9bmV3IHN0LE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMse3BvaW50czp7ZW51bWVyYWJsZTohMCxnZXQoKXtyZXR1cm4gdGhpcy5fcG9pbnRzfSxzZXQodCl7dGhpcy5zZXRQb2ludHModCx0aGlzLndpZHRoQ2FsbGJhY2spfX19KX1zZXRNYXRyaXhXb3JsZCh0KXt0aGlzLm1hdHJpeFdvcmxkPXR9c2V0UG9pbnRzKHQsZSl7aWYodD1seSh0KSx0aGlzLl9wb2ludHM9dCx0aGlzLndpZHRoQ2FsbGJhY2s9ZSE9bnVsbD9lOm51bGwsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5jb3VudGVycz1bXSx0Lmxlbmd0aCYmdFswXWluc3RhbmNlb2YgVClmb3IobGV0IG49MDtuPHQubGVuZ3RoO24rKyl7Y29uc3Qgcz10W25dLHI9bi8odC5sZW5ndGgtMSk7dGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5jb3VudGVycy5wdXNoKHIpLHRoaXMuY291bnRlcnMucHVzaChyKX1lbHNlIGZvcihsZXQgbj0wO248dC5sZW5ndGg7bis9Myl7Y29uc3Qgcz1uLyh0Lmxlbmd0aC0xKTt0aGlzLnBvc2l0aW9ucy5wdXNoKHRbbl0sdFtuKzFdLHRbbisyXSksdGhpcy5wb3NpdGlvbnMucHVzaCh0W25dLHRbbisxXSx0W24rMl0pLHRoaXMuY291bnRlcnMucHVzaChzKSx0aGlzLmNvdW50ZXJzLnB1c2gocyl9dGhpcy5wcm9jZXNzKCl9Y29tcGFyZVYzKHQsZSl7Y29uc3Qgbj10KjYscz1lKjY7cmV0dXJuIHRoaXMucG9zaXRpb25zW25dPT09dGhpcy5wb3NpdGlvbnNbc10mJnRoaXMucG9zaXRpb25zW24rMV09PT10aGlzLnBvc2l0aW9uc1tzKzFdJiZ0aGlzLnBvc2l0aW9uc1tuKzJdPT09dGhpcy5wb3NpdGlvbnNbcysyXX1jb3B5VjModCl7Y29uc3QgZT10KjY7cmV0dXJuW3RoaXMucG9zaXRpb25zW2VdLHRoaXMucG9zaXRpb25zW2UrMV0sdGhpcy5wb3NpdGlvbnNbZSsyXV19cHJvY2Vzcygpe2NvbnN0IHQ9dGhpcy5wb3NpdGlvbnMubGVuZ3RoLzY7dGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdO2xldCBlLG47dGhpcy5jb21wYXJlVjMoMCx0LTEpP249dGhpcy5jb3B5VjModC0yKTpuPXRoaXMuY29weVYzKDApLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKTtmb3IobGV0IHM9MDtzPHQ7cysrKXtpZih0aGlzLnNpZGUucHVzaCgxKSx0aGlzLnNpZGUucHVzaCgtMSksdGhpcy53aWR0aENhbGxiYWNrP2U9dGhpcy53aWR0aENhbGxiYWNrKHMvKHQtMSkpOmU9MSx0aGlzLndpZHRoLnB1c2goZSksdGhpcy53aWR0aC5wdXNoKGUpLHRoaXMudXZzLnB1c2gocy8odC0xKSwwKSx0aGlzLnV2cy5wdXNoKHMvKHQtMSksMSksczx0LTEpe249dGhpcy5jb3B5VjMocyksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLnByZXZpb3VzLnB1c2goblswXSxuWzFdLG5bMl0pO2NvbnN0IHI9cyoyO3RoaXMuaW5kaWNlc19hcnJheS5wdXNoKHIscisxLHIrMiksdGhpcy5pbmRpY2VzX2FycmF5LnB1c2gocisyLHIrMSxyKzMpfXM+MCYmKG49dGhpcy5jb3B5VjMocyksdGhpcy5uZXh0LnB1c2goblswXSxuWzFdLG5bMl0pLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSl9dGhpcy5jb21wYXJlVjModC0xLDApP249dGhpcy5jb3B5VjMoMSk6bj10aGlzLmNvcHlWMyh0LTEpLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSksIXRoaXMuX2F0dHJpYnV0ZXN8fHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uY291bnQhPT10aGlzLmNvdW50ZXJzLmxlbmd0aD90aGlzLl9hdHRyaWJ1dGVzPXtwb3NpdGlvbjpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucyksMykscHJldmlvdXM6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wcmV2aW91cyksMyksbmV4dDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLm5leHQpLDMpLHNpZGU6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaWRlKSwxKSx3aWR0aDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSwxKSx1djpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnV2cyksMiksaW5kZXg6bmV3IHh0KG5ldyBVaW50MTZBcnJheSh0aGlzLmluZGljZXNfYXJyYXkpLDEpLGNvdW50ZXJzOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMuY291bnRlcnMpLDEpfToodGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucykpLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24ubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnByZXZpb3VzKSksdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLm5leHQuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5uZXh0KSksdGhpcy5fYXR0cmlidXRlcy5uZXh0Lm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMuc2lkZS5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnNpZGUpKSx0aGlzLl9hdHRyaWJ1dGVzLnNpZGUubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy53aWR0aC5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSksdGhpcy5fYXR0cmlidXRlcy53aWR0aC5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnV2LmNvcHlBcnJheShuZXcgRmxvYXQzMkFycmF5KHRoaXMudXZzKSksdGhpcy5fYXR0cmlidXRlcy51di5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLmluZGV4LmNvcHlBcnJheShuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzX2FycmF5KSksdGhpcy5fYXR0cmlidXRlcy5pbmRleC5uZWVkc1VwZGF0ZT0hMCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIix0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uKSx0aGlzLnNldEF0dHJpYnV0ZSgicHJldmlvdXMiLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMpLHRoaXMuc2V0QXR0cmlidXRlKCJuZXh0Iix0aGlzLl9hdHRyaWJ1dGVzLm5leHQpLHRoaXMuc2V0QXR0cmlidXRlKCJzaWRlIix0aGlzLl9hdHRyaWJ1dGVzLnNpZGUpLHRoaXMuc2V0QXR0cmlidXRlKCJ3aWR0aCIsdGhpcy5fYXR0cmlidXRlcy53aWR0aCksdGhpcy5zZXRBdHRyaWJ1dGUoInV2Iix0aGlzLl9hdHRyaWJ1dGVzLnV2KSx0aGlzLnNldEF0dHJpYnV0ZSgiY291bnRlcnMiLHRoaXMuX2F0dHJpYnV0ZXMuY291bnRlcnMpLHRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbiksdGhpcy5zZXRBdHRyaWJ1dGUoInByZXZpb3VzIix0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzKSx0aGlzLnNldEF0dHJpYnV0ZSgibmV4dCIsdGhpcy5fYXR0cmlidXRlcy5uZXh0KSx0aGlzLnNldEF0dHJpYnV0ZSgic2lkZSIsdGhpcy5fYXR0cmlidXRlcy5zaWRlKSx0aGlzLnNldEF0dHJpYnV0ZSgid2lkdGgiLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsdGhpcy5fYXR0cmlidXRlcy51diksdGhpcy5zZXRBdHRyaWJ1dGUoImNvdW50ZXJzIix0aGlzLl9hdHRyaWJ1dGVzLmNvdW50ZXJzKSx0aGlzLnNldEluZGV4KHRoaXMuX2F0dHJpYnV0ZXMuaW5kZXgpLHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCksdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKX1hZHZhbmNlKHt4OnQseTplLHo6bn0pe2NvbnN0IHM9dGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5hcnJheSxyPXRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMuYXJyYXksbz10aGlzLl9hdHRyaWJ1dGVzLm5leHQuYXJyYXksYT1zLmxlbmd0aDtZYShzLDAsciwwLGEpLFlhKHMsNixzLDAsYS02KSxzW2EtNl09dCxzW2EtNV09ZSxzW2EtNF09bixzW2EtM109dCxzW2EtMl09ZSxzW2EtMV09bixZYShzLDYsbywwLGEtNiksb1thLTZdPXQsb1thLTVdPWUsb1thLTRdPW4sb1thLTNdPXQsb1thLTJdPWUsb1thLTFdPW4sdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMubmV4dC5uZWVkc1VwZGF0ZT0hMH19dmFyIFpoPWk9Pntjb25zdHtzZXRQb2ludFdpZHRoOnQsbm9kZXM6ZX09aSxuPW5ldyBoeTtyZXR1cm4gbi5zZXRQb2ludHMoZSx0KSxufTtjb25zdCB1eT0oe2Nvb3JkaW5hdGVzQXJyOmkscHJvamVjdGlvbjp0LGxpbmVXaWR0aDplLHVzZUdyb3VwczpuLHNwbGl0UG9seWdvbnM6c30pPT57Y29uc3Qgcj10JiZYaSh0KTtsZXQgbz1pLm1hcChjPT5JcihjLHIpKTtzJiYobz1KYShvLHMpKTtjb25zdCBhPW8ubWFwKChjLGwpPT57dmFyIHU7Y29uc3QgaD0odT1lW2xdKSE9bnVsbD91OmVbMF07cmV0dXJuIFpoKHtub2RlczpjLHNldFBvaW50V2lkdGg6KCk9Pmh9KX0pO3JldHVybiBKaShhLG4pfTt2YXIgZnk9aT0+e2NvbnN0e3BvaW50czp0fT1pLGU9dC5yZWR1Y2UoKHMscixvKT0+KG88dC5sZW5ndGgtMSYmcy5wdXNoKHIsdFtvKzFdKSxzKSxbXSk7cmV0dXJuIG5ldyB1ZSgpLnNldEZyb21Qb2ludHMoZSl9O2NvbnN0IGR5PSh7Y29vcmRpbmF0ZXNBcnI6aSxwcm9qZWN0aW9uOnQsbGluZVdpZHRoOmUsdXNlR3JvdXBzOm4sc3BsaXRQb2x5Z29uczpzfSk9Pntjb25zdCByPXQmJlhpKHQpO2xldCBvPWkubWFwKGM9PklyKGMscikpO3MmJihvPUphKG8scykpO2NvbnN0IGE9by5tYXAoKGMsbCk9PmZ5KHtwb2ludHM6Yy5tYXAoaD0+bmV3IFQoaC54LGgueSwwKSl9KSk7cmV0dXJuIEppKGEsbil9O2Z1bmN0aW9uIHB5KGksdCxlPTIpe2NvbnN0IG49dCYmdC5sZW5ndGgscz1uP3RbMF0qZTppLmxlbmd0aDtsZXQgcj1YaChpLDAscyxlLCEwKTtjb25zdCBvPVtdO2lmKCFyfHxyLm5leHQ9PT1yLnByZXYpcmV0dXJuIG87bGV0IGEsYyxsO2lmKG4mJihyPXd5KGksdCxyLGUpKSxpLmxlbmd0aD44MCplKXthPTEvMCxjPTEvMDtsZXQgaD0tMS8wLHU9LTEvMDtmb3IobGV0IGY9ZTtmPHM7Zis9ZSl7Y29uc3QgZD1pW2ZdLHA9aVtmKzFdO2Q8YSYmKGE9ZCkscDxjJiYoYz1wKSxkPmgmJihoPWQpLHA+dSYmKHU9cCl9bD1NYXRoLm1heChoLWEsdS1jKSxsPWwhPT0wPzMyNzY3L2w6MH1yZXR1cm4gWWkocixvLGUsYSxjLGwsMCksb31mdW5jdGlvbiBYaChpLHQsZSxuLHMpe2xldCByO2lmKHM9PT1DeShpLHQsZSxuKT4wKWZvcihsZXQgbz10O288ZTtvKz1uKXI9amgoby9ufDAsaVtvXSxpW28rMV0scik7ZWxzZSBmb3IobGV0IG89ZS1uO28+PXQ7by09bilyPWpoKG8vbnwwLGlbb10saVtvKzFdLHIpO3JldHVybiByJiZrcihyLHIubmV4dCkmJihRaShyKSxyPXIubmV4dCkscn1mdW5jdGlvbiB2bihpLHQpe2lmKCFpKXJldHVybiBpO3R8fCh0PWkpO2xldCBlPWksbjtkbyBpZihuPSExLCFlLnN0ZWluZXImJihrcihlLGUubmV4dCl8fGF0KGUucHJldixlLGUubmV4dCk9PT0wKSl7aWYoUWkoZSksZT10PWUucHJldixlPT09ZS5uZXh0KWJyZWFrO249ITB9ZWxzZSBlPWUubmV4dDt3aGlsZShufHxlIT09dCk7cmV0dXJuIHR9ZnVuY3Rpb24gWWkoaSx0LGUsbixzLHIsbyl7aWYoIWkpcmV0dXJuOyFvJiZyJiZfeShpLG4scyxyKTtsZXQgYT1pO2Zvcig7aS5wcmV2IT09aS5uZXh0Oyl7Y29uc3QgYz1pLnByZXYsbD1pLm5leHQ7aWYocj9teShpLG4scyxyKTp5eShpKSl7dC5wdXNoKGMuaSxpLmksbC5pKSxRaShpKSxpPWwubmV4dCxhPWwubmV4dDtjb250aW51ZX1pZihpPWwsaT09PWEpe28/bz09PTE/KGk9Z3kodm4oaSksdCksWWkoaSx0LGUsbixzLHIsMikpOm89PT0yJiZ4eShpLHQsZSxuLHMscik6WWkodm4oaSksdCxlLG4scyxyLDEpO2JyZWFrfX19ZnVuY3Rpb24geXkoaSl7Y29uc3QgdD1pLnByZXYsZT1pLG49aS5uZXh0O2lmKGF0KHQsZSxuKT49MClyZXR1cm4hMTtjb25zdCBzPXQueCxyPWUueCxvPW4ueCxhPXQueSxjPWUueSxsPW4ueSxoPXM8cj9zPG8/czpvOnI8bz9yOm8sdT1hPGM/YTxsP2E6bDpjPGw/YzpsLGY9cz5yP3M+bz9zOm86cj5vP3I6byxkPWE+Yz9hPmw/YTpsOmM+bD9jOmw7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJmNpKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZhdChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIG15KGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihhdChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1hPGM/YTxsP2E6bDpjPGw/YzpsLHA9aDx1P2g8Zj9oOmY6dTxmP3U6Zix5PWE+Yz9hPmw/YTpsOmM+bD9jOmwsbT1oPnU/aD5mP2g6Zjp1PmY/dTpmLGc9amEoZCxwLHQsZSxuKSxiPWphKHksbSx0LGUsbik7bGV0IHc9aS5wcmV2Wix4PWkubmV4dFo7Zm9yKDt3JiZ3Lno+PWcmJngmJnguejw9Yjspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZjaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MHx8KHc9dy5wcmV2Wix4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmY2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApKXJldHVybiExO3g9eC5uZXh0Wn1mb3IoO3cmJncuej49Zzspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZjaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MClyZXR1cm4hMTt3PXcucHJldlp9Zm9yKDt4JiZ4Lno8PWI7KXtpZih4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmY2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApcmV0dXJuITE7eD14Lm5leHRafXJldHVybiEwfWZ1bmN0aW9uIGd5KGksdCl7bGV0IGU9aTtkb3tjb25zdCBuPWUucHJldixzPWUubmV4dC5uZXh0OyFrcihuLHMpJiZKaChuLGUsZS5uZXh0LHMpJiZqaShuLHMpJiZqaShzLG4pJiYodC5wdXNoKG4uaSxlLmkscy5pKSxRaShlKSxRaShlLm5leHQpLGU9aT1zKSxlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuIHZuKGUpfWZ1bmN0aW9uIHh5KGksdCxlLG4scyxyKXtsZXQgbz1pO2Rve2xldCBhPW8ubmV4dC5uZXh0O2Zvcig7YSE9PW8ucHJldjspe2lmKG8uaSE9PWEuaSYmVHkobyxhKSl7bGV0IGM9WWgobyxhKTtvPXZuKG8sby5uZXh0KSxjPXZuKGMsYy5uZXh0KSxZaShvLHQsZSxuLHMsciwwKSxZaShjLHQsZSxuLHMsciwwKTtyZXR1cm59YT1hLm5leHR9bz1vLm5leHR9d2hpbGUobyE9PWkpfWZ1bmN0aW9uIHd5KGksdCxlLG4pe2NvbnN0IHM9W107Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXRbcl0qbixjPXI8by0xP3RbcisxXSpuOmkubGVuZ3RoLGw9WGgoaSxhLGMsbiwhMSk7bD09PWwubmV4dCYmKGwuc3RlaW5lcj0hMCkscy5wdXNoKHp5KGwpKX1zLnNvcnQoYnkpO2ZvcihsZXQgcj0wO3I8cy5sZW5ndGg7cisrKWU9TXkoc1tyXSxlKTtyZXR1cm4gZX1mdW5jdGlvbiBieShpLHQpe3JldHVybiBpLngtdC54fWZ1bmN0aW9uIE15KGksdCl7Y29uc3QgZT1BeShpLHQpO2lmKCFlKXJldHVybiB0O2NvbnN0IG49WWgoZSxpKTtyZXR1cm4gdm4obixuLm5leHQpLHZuKGUsZS5uZXh0KX1mdW5jdGlvbiBBeShpLHQpe2xldCBlPXQ7Y29uc3Qgbj1pLngscz1pLnk7bGV0IHI9LTEvMCxvO2Rve2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZjaShzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTtqaShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmU3kobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIFN5KGksdCl7cmV0dXJuIGF0KGkucHJldixpLHQucHJldik8MCYmYXQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIF95KGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1qYShzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwsdnkocyl9ZnVuY3Rpb24gdnkoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBqYShpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24genkoaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIGNpKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiBUeShpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFFeShpLHQpJiYoamkoaSx0KSYmamkodCxpKSYmUHkoaSx0KSYmKGF0KGkucHJldixpLHQucHJldil8fGF0KGksdC5wcmV2LHQpKXx8a3IoaSx0KSYmYXQoaS5wcmV2LGksaS5uZXh0KT4wJiZhdCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIGF0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24ga3IoaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gSmgoaSx0LGUsbil7Y29uc3Qgcz1ScihhdChpLHQsZSkpLHI9UnIoYXQoaSx0LG4pKSxvPVJyKGF0KGUsbixpKSksYT1ScihhdChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJk5yKGksZSx0KXx8cj09PTAmJk5yKGksbix0KXx8bz09PTAmJk5yKGUsaSxuKXx8YT09PTAmJk5yKGUsdCxuKSl9ZnVuY3Rpb24gTnIoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIFJyKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBFeShpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmSmgoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gamkoaSx0KXtyZXR1cm4gYXQoaS5wcmV2LGksaS5uZXh0KTwwP2F0KGksdCxpLm5leHQpPj0wJiZhdChpLGkucHJldix0KT49MDphdChpLHQsaS5wcmV2KTwwfHxhdChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIFB5KGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gWWgoaSx0KXtjb25zdCBlPVFhKGkuaSxpLngsaS55KSxuPVFhKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBqaChpLHQsZSxuKXtjb25zdCBzPVFhKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gUWkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBRYShpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gQ3koaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWZ1bmN0aW9uIFFoKGkpe2NvbnN0IHQ9W10sZT1bXSxuPWlbMF1bMF0ubGVuZ3RoO2xldCBzPTAscj0wO2Zvcihjb25zdCBvIG9mIGkpe2Zvcihjb25zdCBhIG9mIG8pZm9yKGxldCBjPTA7YzxuO2MrKyl0LnB1c2goYVtjXSk7ciYmKHMrPXIsZS5wdXNoKHMpKSxyPW8ubGVuZ3RofXJldHVybnt2ZXJ0aWNlczp0LGhvbGVzOmUsZGltZW5zaW9uczpufX1mdW5jdGlvbiBCeShpKXtpZighaSl0aHJvdyBuZXcgRXJyb3IoImNvb3JkIGlzIHJlcXVpcmVkIik7aWYoIUFycmF5LmlzQXJyYXkoaSkpe2lmKGkudHlwZT09PSJGZWF0dXJlIiYmaS5nZW9tZXRyeSE9PW51bGwmJmkuZ2VvbWV0cnkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuZ2VvbWV0cnkuY29vcmRpbmF0ZXNdO2lmKGkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuY29vcmRpbmF0ZXNdfWlmKEFycmF5LmlzQXJyYXkoaSkmJmkubGVuZ3RoPj0yJiYhQXJyYXkuaXNBcnJheShpWzBdKSYmIUFycmF5LmlzQXJyYXkoaVsxXSkpcmV0dXJuWy4uLmldO3Rocm93IG5ldyBFcnJvcigiY29vcmQgbXVzdCBiZSBHZW9KU09OIFBvaW50IG9yIGFuIEFycmF5IG9mIG51bWJlcnMiKX1mdW5jdGlvbiBGeShpKXtpZihBcnJheS5pc0FycmF5KGkpKXJldHVybiBpO2lmKGkudHlwZT09PSJGZWF0dXJlIil7aWYoaS5nZW9tZXRyeSE9PW51bGwpcmV0dXJuIGkuZ2VvbWV0cnkuY29vcmRpbmF0ZXN9ZWxzZSBpZihpLmNvb3JkaW5hdGVzKXJldHVybiBpLmNvb3JkaW5hdGVzO3Rocm93IG5ldyBFcnJvcigiY29vcmRzIG11c3QgYmUgR2VvSlNPTiBGZWF0dXJlLCBHZW9tZXRyeSBPYmplY3Qgb3IgYW4gQXJyYXkiKX1mdW5jdGlvbiBJeShpKXtyZXR1cm4gaS50eXBlPT09IkZlYXR1cmUiP2kuZ2VvbWV0cnk6aX1mdW5jdGlvbiBreShpKXtjb25zdCB0PUZ5KGkpO2xldCBlPTAsbj0xLHMscjtmb3IoO248dC5sZW5ndGg7KXM9cnx8dFswXSxyPXRbbl0sZSs9KHJbMF0tc1swXSkqKHJbMV0rc1sxXSksbisrO3JldHVybiBlPjB9dmFyIE55PWt5O2NvbnN0IHFlPTExMTAyMjMwMjQ2MjUxNTY1ZS0zMix2dD0xMzQyMTc3MjksUnk9KDMrOCpxZSkqcWU7ZnVuY3Rpb24gS2EoaSx0LGUsbixzKXtsZXQgcixvLGEsYyxsPXRbMF0saD1uWzBdLHU9MCxmPTA7aD5sPT1oPi1sPyhyPWwsbD10WysrdV0pOihyPWgsaD1uWysrZl0pO2xldCBkPTA7aWYodTxpJiZmPGUpZm9yKGg+bD09aD4tbD8obz1sK3IsYT1yLShvLWwpLGw9dFsrK3VdKToobz1oK3IsYT1yLShvLWgpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7dTxpJiZmPGU7KWg+bD09aD4tbD8obz1yK2wsYz1vLXIsYT1yLShvLWMpKyhsLWMpLGw9dFsrK3VdKToobz1yK2gsYz1vLXIsYT1yLShvLWMpKyhoLWMpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDt1PGk7KW89citsLGM9by1yLGE9ci0oby1jKSsobC1jKSxsPXRbKyt1XSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDtmPGU7KW89citoLGM9by1yLGE9ci0oby1jKSsoaC1jKSxoPW5bKytmXSxyPW8sYSE9PTAmJihzW2QrK109YSk7cmV0dXJuKHIhPT0wfHxkPT09MCkmJihzW2QrK109ciksZH1mdW5jdGlvbiBMeShpLHQpe2xldCBlPXRbMF07Zm9yKGxldCBuPTE7bjxpO24rKyllKz10W25dO3JldHVybiBlfWZ1bmN0aW9uIEtpKGkpe3JldHVybiBuZXcgRmxvYXQ2NEFycmF5KGkpfWNvbnN0IE95PSgzKzE2KnFlKSpxZSxEeT0oMisxMipxZSkqcWUsJHk9KDkrNjQqcWUpKnFlKnFlLGxpPUtpKDQpLEtoPUtpKDgpLHR1PUtpKDEyKSxldT1LaSgxNiksQnQ9S2koNCk7ZnVuY3Rpb24gVnkoaSx0LGUsbixzLHIsbyl7bGV0IGEsYyxsLGgsdSxmLGQscCx5LG0sZyxiLHcseCxNLEEsUyxfO2NvbnN0IEU9aS1zLHo9ZS1zLHY9dC1yLEM9bi1yO3g9RSpDLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpDLHk9Zi0oZi1DKSxtPUMteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KnosZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KnoseT1mLShmLXopLG09ei15LFM9cCptLShBLWQqeS1wKnktZCptKSxnPU0tUyx1PU0tZyxsaVswXT1NLShnK3UpKyh1LVMpLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxsaVsxXT13LShnK3UpKyh1LUEpLF89YitnLHU9Xy1iLGxpWzJdPWItKF8tdSkrKGctdSksbGlbM109XztsZXQgUD1MeSg0LGxpKSxGPUR5Km87aWYoUD49Rnx8LVA+PUZ8fCh1PWktRSxhPWktKEUrdSkrKHUtcyksdT1lLXosbD1lLSh6K3UpKyh1LXMpLHU9dC12LGM9dC0odit1KSsodS1yKSx1PW4tQyxoPW4tKEMrdSkrKHUtciksYT09PTAmJmM9PT0wJiZsPT09MCYmaD09PTApfHwoRj0keSpvK1J5Kk1hdGguYWJzKFApLFArPUUqaCtDKmEtKHYqbCt6KmMpLFA+PUZ8fC1QPj1GKSlyZXR1cm4gUDt4PWEqQyxmPXZ0KmEsZD1mLShmLWEpLHA9YS1kLGY9dnQqQyx5PWYtKGYtQyksbT1DLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9Yyp6LGY9dnQqYyxkPWYtKGYtYykscD1jLWQsZj12dCp6LHk9Zi0oZi16KSxtPXoteSxTPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLVMsdT1NLWcsQnRbMF09TS0oZyt1KSsodS1TKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsQnRbMV09dy0oZyt1KSsodS1BKSxfPWIrZyx1PV8tYixCdFsyXT1iLShfLXUpKyhnLXUpLEJ0WzNdPV87Y29uc3QgQj1LYSg0LGxpLDQsQnQsS2gpO3g9RSpoLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpoLHk9Zi0oZi1oKSxtPWgteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KmwsZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KmwseT1mLShmLWwpLG09bC15LFM9cCptLShBLWQqeS1wKnktZCptKSxnPU0tUyx1PU0tZyxCdFswXT1NLShnK3UpKyh1LVMpLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxCdFsxXT13LShnK3UpKyh1LUEpLF89YitnLHU9Xy1iLEJ0WzJdPWItKF8tdSkrKGctdSksQnRbM109Xztjb25zdCBJPUthKEIsS2gsNCxCdCx0dSk7eD1hKmgsZj12dCphLGQ9Zi0oZi1hKSxwPWEtZCxmPXZ0KmgseT1mLShmLWgpLG09aC15LE09cCptLSh4LWQqeS1wKnktZCptKSxBPWMqbCxmPXZ0KmMsZD1mLShmLWMpLHA9Yy1kLGY9dnQqbCx5PWYtKGYtbCksbT1sLXksUz1wKm0tKEEtZCp5LXAqeS1kKm0pLGc9TS1TLHU9TS1nLEJ0WzBdPU0tKGcrdSkrKHUtUyksYj14K2csdT1iLXgsdz14LShiLXUpKyhnLXUpLGc9dy1BLHU9dy1nLEJ0WzFdPXctKGcrdSkrKHUtQSksXz1iK2csdT1fLWIsQnRbMl09Yi0oXy11KSsoZy11KSxCdFszXT1fO2NvbnN0IGs9S2EoSSx0dSw0LEJ0LGV1KTtyZXR1cm4gZXVbay0xXX1mdW5jdGlvbiBMcihpLHQsZSxuLHMscil7Y29uc3Qgbz0odC1yKSooZS1zKSxhPShpLXMpKihuLXIpLGM9by1hO2lmKG89PT0wfHxhPT09MHx8bz4wIT1hPjApcmV0dXJuIGM7Y29uc3QgbD1NYXRoLmFicyhvK2EpO3JldHVybiBNYXRoLmFicyhjKT49T3kqbD9jOi1WeShpLHQsZSxuLHMscixsKX1jb25zdCBudT1NYXRoLnBvdygyLC01MiksT3I9bmV3IFVpbnQzMkFycmF5KDUxMik7Y2xhc3MgdHN7c3RhdGljIGZyb20odCxlPUd5LG49Wnkpe2NvbnN0IHM9dC5sZW5ndGgscj1uZXcgRmxvYXQ2NEFycmF5KHMqMik7Zm9yKGxldCBvPTA7bzxzO28rKyl7Y29uc3QgYT10W29dO3JbMipvXT1lKGEpLHJbMipvKzFdPW4oYSl9cmV0dXJuIG5ldyB0cyhyKX1jb25zdHJ1Y3Rvcih0KXtjb25zdCBlPXQubGVuZ3RoPj4xO2lmKGU+MCYmdHlwZW9mIHRbMF0hPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcigiRXhwZWN0ZWQgY29vcmRzIHRvIGNvbnRhaW4gbnVtYmVycy4iKTt0aGlzLmNvb3Jkcz10O2NvbnN0IG49TWF0aC5tYXgoMiplLTUsMCk7dGhpcy5fdHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheShuKjMpLHRoaXMuX2hhbGZlZGdlcz1uZXcgSW50MzJBcnJheShuKjMpLHRoaXMuX2hhc2hTaXplPU1hdGguY2VpbChNYXRoLnNxcnQoZSkpLHRoaXMuX2h1bGxQcmV2PW5ldyBVaW50MzJBcnJheShlKSx0aGlzLl9odWxsTmV4dD1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbFRyaT1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbEhhc2g9bmV3IEludDMyQXJyYXkodGhpcy5faGFzaFNpemUpLmZpbGwoLTEpLHRoaXMuX2lkcz1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5fZGlzdHM9bmV3IEZsb2F0NjRBcnJheShlKSx0aGlzLnVwZGF0ZSgpfXVwZGF0ZSgpe2NvbnN0e2Nvb3Jkczp0LF9odWxsUHJldjplLF9odWxsTmV4dDpuLF9odWxsVHJpOnMsX2h1bGxIYXNoOnJ9PXRoaXMsbz10Lmxlbmd0aD4+MTtsZXQgYT0xLzAsYz0xLzAsbD0tMS8wLGg9LTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtjb25zdCB2PXRbMip6XSxDPXRbMip6KzFdO3Y8YSYmKGE9diksQzxjJiYoYz1DKSx2PmwmJihsPXYpLEM+aCYmKGg9QyksdGhpcy5faWRzW3pdPXp9Y29uc3QgdT0oYStsKS8yLGY9KGMraCkvMjtsZXQgZD0xLzAscCx5LG07Zm9yKGxldCB6PTA7ejxvO3orKyl7Y29uc3Qgdj10Yyh1LGYsdFsyKnpdLHRbMip6KzFdKTt2PGQmJihwPXosZD12KX1jb25zdCBnPXRbMipwXSxiPXRbMipwKzFdO2Q9MS8wO2ZvcihsZXQgej0wO3o8bzt6Kyspe2lmKHo9PT1wKWNvbnRpbnVlO2NvbnN0IHY9dGMoZyxiLHRbMip6XSx0WzIqeisxXSk7djxkJiZ2PjAmJih5PXosZD12KX1sZXQgdz10WzIqeV0seD10WzIqeSsxXSxNPTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtpZih6PT09cHx8ej09PXkpY29udGludWU7Y29uc3Qgdj1IeShnLGIsdyx4LHRbMip6XSx0WzIqeisxXSk7djxNJiYobT16LE09dil9bGV0IEE9dFsyKm1dLFM9dFsyKm0rMV07aWYoTT09PTEvMCl7Zm9yKGxldCBDPTA7QzxvO0MrKyl0aGlzLl9kaXN0c1tDXT10WzIqQ10tdFswXXx8dFsyKkMrMV0tdFsxXTtoaSh0aGlzLl9pZHMsdGhpcy5fZGlzdHMsMCxvLTEpO2NvbnN0IHo9bmV3IFVpbnQzMkFycmF5KG8pO2xldCB2PTA7Zm9yKGxldCBDPTAsUD0tMS8wO0M8bztDKyspe2NvbnN0IEY9dGhpcy5faWRzW0NdO3RoaXMuX2Rpc3RzW0ZdPlAmJih6W3YrK109RixQPXRoaXMuX2Rpc3RzW0ZdKX10aGlzLmh1bGw9ei5zdWJhcnJheSgwLHYpLHRoaXMudHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheSgwKSx0aGlzLmhhbGZlZGdlcz1uZXcgVWludDMyQXJyYXkoMCk7cmV0dXJufWlmKExyKGcsYix3LHgsQSxTKTwwKXtjb25zdCB6PXksdj13LEM9eDt5PW0sdz1BLHg9UyxtPXosQT12LFM9Q31jb25zdCBfPVd5KGcsYix3LHgsQSxTKTt0aGlzLl9jeD1fLngsdGhpcy5fY3k9Xy55O2ZvcihsZXQgej0wO3o8bzt6KyspdGhpcy5fZGlzdHNbel09dGModFsyKnpdLHRbMip6KzFdLF8ueCxfLnkpO2hpKHRoaXMuX2lkcyx0aGlzLl9kaXN0cywwLG8tMSksdGhpcy5faHVsbFN0YXJ0PXA7bGV0IEU9MztuW3BdPWVbbV09eSxuW3ldPWVbcF09bSxuW21dPWVbeV09cCxzW3BdPTAsc1t5XT0xLHNbbV09MixyLmZpbGwoLTEpLHJbdGhpcy5faGFzaEtleShnLGIpXT1wLHJbdGhpcy5faGFzaEtleSh3LHgpXT15LHJbdGhpcy5faGFzaEtleShBLFMpXT1tLHRoaXMudHJpYW5nbGVzTGVuPTAsdGhpcy5fYWRkVHJpYW5nbGUocCx5LG0sLTEsLTEsLTEpO2ZvcihsZXQgej0wLHYsQzt6PHRoaXMuX2lkcy5sZW5ndGg7eisrKXtjb25zdCBQPXRoaXMuX2lkc1t6XSxGPXRbMipQXSxCPXRbMipQKzFdO2lmKHo+MCYmTWF0aC5hYnMoRi12KTw9bnUmJk1hdGguYWJzKEItQyk8PW51fHwodj1GLEM9QixQPT09cHx8UD09PXl8fFA9PT1tKSljb250aW51ZTtsZXQgST0wO2ZvcihsZXQgZHQ9MCxEdD10aGlzLl9oYXNoS2V5KEYsQik7ZHQ8dGhpcy5faGFzaFNpemUmJihJPXJbKER0K2R0KSV0aGlzLl9oYXNoU2l6ZV0sIShJIT09LTEmJkkhPT1uW0ldKSk7ZHQrKyk7ST1lW0ldO2xldCBrPUksRDtmb3IoO0Q9bltrXSxMcihGLEIsdFsyKmtdLHRbMiprKzFdLHRbMipEXSx0WzIqRCsxXSk+PTA7KWlmKGs9RCxrPT09SSl7az0tMTticmVha31pZihrPT09LTEpY29udGludWU7bGV0IFU9dGhpcy5fYWRkVHJpYW5nbGUoayxQLG5ba10sLTEsLTEsc1trXSk7c1tQXT10aGlzLl9sZWdhbGl6ZShVKzIpLHNba109VSxFKys7bGV0IGo9bltrXTtmb3IoO0Q9bltqXSxMcihGLEIsdFsyKmpdLHRbMipqKzFdLHRbMipEXSx0WzIqRCsxXSk8MDspVT10aGlzLl9hZGRUcmlhbmdsZShqLFAsRCxzW1BdLC0xLHNbal0pLHNbUF09dGhpcy5fbGVnYWxpemUoVSsyKSxuW2pdPWosRS0tLGo9RDtpZihrPT09SSlmb3IoO0Q9ZVtrXSxMcihGLEIsdFsyKkRdLHRbMipEKzFdLHRbMiprXSx0WzIqaysxXSk8MDspVT10aGlzLl9hZGRUcmlhbmdsZShELFAsaywtMSxzW2tdLHNbRF0pLHRoaXMuX2xlZ2FsaXplKFUrMiksc1tEXT1VLG5ba109ayxFLS0saz1EO3RoaXMuX2h1bGxTdGFydD1lW1BdPWssbltrXT1lW2pdPVAsbltQXT1qLHJbdGhpcy5faGFzaEtleShGLEIpXT1QLHJbdGhpcy5faGFzaEtleSh0WzIqa10sdFsyKmsrMV0pXT1rfXRoaXMuaHVsbD1uZXcgVWludDMyQXJyYXkoRSk7Zm9yKGxldCB6PTAsdj10aGlzLl9odWxsU3RhcnQ7ejxFO3orKyl0aGlzLmh1bGxbel09dix2PW5bdl07dGhpcy50cmlhbmdsZXM9dGhpcy5fdHJpYW5nbGVzLnN1YmFycmF5KDAsdGhpcy50cmlhbmdsZXNMZW4pLHRoaXMuaGFsZmVkZ2VzPXRoaXMuX2hhbGZlZGdlcy5zdWJhcnJheSgwLHRoaXMudHJpYW5nbGVzTGVuKX1faGFzaEtleSh0LGUpe3JldHVybiBNYXRoLmZsb29yKFV5KHQtdGhpcy5fY3gsZS10aGlzLl9jeSkqdGhpcy5faGFzaFNpemUpJXRoaXMuX2hhc2hTaXplfV9sZWdhbGl6ZSh0KXtjb25zdHtfdHJpYW5nbGVzOmUsX2hhbGZlZGdlczpuLGNvb3JkczpzfT10aGlzO2xldCByPTAsbz0wO2Zvcig7Oyl7Y29uc3QgYT1uW3RdLGM9dC10JTM7aWYobz1jKyh0KzIpJTMsYT09PS0xKXtpZihyPT09MClicmVhazt0PU9yWy0tcl07Y29udGludWV9Y29uc3QgbD1hLWElMyxoPWMrKHQrMSklMyx1PWwrKGErMiklMyxmPWVbb10sZD1lW3RdLHA9ZVtoXSx5PWVbdV07aWYocXkoc1syKmZdLHNbMipmKzFdLHNbMipkXSxzWzIqZCsxXSxzWzIqcF0sc1syKnArMV0sc1syKnldLHNbMip5KzFdKSl7ZVt0XT15LGVbYV09Zjtjb25zdCBnPW5bdV07aWYoZz09PS0xKXtsZXQgdz10aGlzLl9odWxsU3RhcnQ7ZG97aWYodGhpcy5faHVsbFRyaVt3XT09PXUpe3RoaXMuX2h1bGxUcmlbd109dDticmVha313PXRoaXMuX2h1bGxQcmV2W3ddfXdoaWxlKHchPT10aGlzLl9odWxsU3RhcnQpfXRoaXMuX2xpbmsodCxnKSx0aGlzLl9saW5rKGEsbltvXSksdGhpcy5fbGluayhvLHUpO2NvbnN0IGI9bCsoYSsxKSUzO3I8T3IubGVuZ3RoJiYoT3JbcisrXT1iKX1lbHNle2lmKHI9PT0wKWJyZWFrO3Q9T3JbLS1yXX19cmV0dXJuIG99X2xpbmsodCxlKXt0aGlzLl9oYWxmZWRnZXNbdF09ZSxlIT09LTEmJih0aGlzLl9oYWxmZWRnZXNbZV09dCl9X2FkZFRyaWFuZ2xlKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMudHJpYW5nbGVzTGVuO3JldHVybiB0aGlzLl90cmlhbmdsZXNbYV09dCx0aGlzLl90cmlhbmdsZXNbYSsxXT1lLHRoaXMuX3RyaWFuZ2xlc1thKzJdPW4sdGhpcy5fbGluayhhLHMpLHRoaXMuX2xpbmsoYSsxLHIpLHRoaXMuX2xpbmsoYSsyLG8pLHRoaXMudHJpYW5nbGVzTGVuKz0zLGF9fWZ1bmN0aW9uIFV5KGksdCl7Y29uc3QgZT1pLyhNYXRoLmFicyhpKStNYXRoLmFicyh0KSk7cmV0dXJuKHQ+MD8zLWU6MStlKS80fWZ1bmN0aW9uIHRjKGksdCxlLG4pe2NvbnN0IHM9aS1lLHI9dC1uO3JldHVybiBzKnMrcipyfWZ1bmN0aW9uIHF5KGksdCxlLG4scyxyLG8sYSl7Y29uc3QgYz1pLW8sbD10LWEsaD1lLW8sdT1uLWEsZj1zLW8sZD1yLWEscD1jKmMrbCpsLHk9aCpoK3UqdSxtPWYqZitkKmQ7cmV0dXJuIGMqKHUqbS15KmQpLWwqKGgqbS15KmYpK3AqKGgqZC11KmYpPDB9ZnVuY3Rpb24gSHkoaSx0LGUsbixzLHIpe2NvbnN0IG89ZS1pLGE9bi10LGM9cy1pLGw9ci10LGg9bypvK2EqYSx1PWMqYytsKmwsZj0uNS8obypsLWEqYyksZD0obCpoLWEqdSkqZixwPShvKnUtYypoKSpmO3JldHVybiBkKmQrcCpwfWZ1bmN0aW9uIFd5KGksdCxlLG4scyxyKXtjb25zdCBvPWUtaSxhPW4tdCxjPXMtaSxsPXItdCxoPW8qbythKmEsdT1jKmMrbCpsLGY9LjUvKG8qbC1hKmMpLGQ9aSsobCpoLWEqdSkqZixwPXQrKG8qdS1jKmgpKmY7cmV0dXJue3g6ZCx5OnB9fWZ1bmN0aW9uIGhpKGksdCxlLG4pe2lmKG4tZTw9MjApZm9yKGxldCBzPWUrMTtzPD1uO3MrKyl7Y29uc3Qgcj1pW3NdLG89dFtyXTtsZXQgYT1zLTE7Zm9yKDthPj1lJiZ0W2lbYV1dPm87KWlbYSsxXT1pW2EtLV07aVthKzFdPXJ9ZWxzZXtjb25zdCBzPWUrbj4+MTtsZXQgcj1lKzEsbz1uO2VzKGkscyxyKSx0W2lbZV1dPnRbaVtuXV0mJmVzKGksZSxuKSx0W2lbcl1dPnRbaVtuXV0mJmVzKGkscixuKSx0W2lbZV1dPnRbaVtyXV0mJmVzKGksZSxyKTtjb25zdCBhPWlbcl0sYz10W2FdO2Zvcig7Oyl7ZG8gcisrO3doaWxlKHRbaVtyXV08Yyk7ZG8gby0tO3doaWxlKHRbaVtvXV0+Yyk7aWYobzxyKWJyZWFrO2VzKGkscixvKX1pW2UrMV09aVtvXSxpW29dPWEsbi1yKzE+PW8tZT8oaGkoaSx0LHIsbiksaGkoaSx0LGUsby0xKSk6KGhpKGksdCxlLG8tMSksaGkoaSx0LHIsbikpfX1mdW5jdGlvbiBlcyhpLHQsZSl7Y29uc3Qgbj1pW3RdO2lbdF09aVtlXSxpW2VdPW59ZnVuY3Rpb24gR3koaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gWnkoaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gWHkoaSx0KXt2YXIgZT0wLG49MCxzPTAscj0wLG89MCxhPTAsYz0wLGw9MCxoPW51bGwsdT1udWxsLGY9aVswXSxkPWlbMV0scD10Lmxlbmd0aDtmb3IoZTtlPHA7ZSsrKXtuPTA7dmFyIHk9dFtlXS5sZW5ndGgtMSxtPXRbZV07aWYoaD1tWzBdLGhbMF0hPT1tW3ldWzBdJiZoWzFdIT09bVt5XVsxXSl0aHJvdyBuZXcgRXJyb3IoIkZpcnN0IGFuZCBsYXN0IGNvb3JkaW5hdGVzIGluIGEgcmluZyBtdXN0IGJlIHRoZSBzYW1lIik7Zm9yKG89aFswXS1mLGE9aFsxXS1kLG47bjx5O24rKyl7aWYodT1tW24rMV0sbD11WzFdLWQsYTwwJiZsPDB8fGE+MCYmbD4wKXtoPXUsYT1sLG89aFswXS1mO2NvbnRpbnVlfWlmKGM9dVswXS1pWzBdLGw+MCYmYTw9MCl7aWYocj1vKmwtYyphLHI+MClzPXMrMTtlbHNlIGlmKHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT4wJiZsPD0wKXtpZihyPW8qbC1jKmEscjwwKXM9cysxO2Vsc2UgaWYocj09PTApcmV0dXJuIDB9ZWxzZSBpZihsPT09MCYmYTwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbDwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbD09PTApe2lmKGM8PTAmJm8+PTApcmV0dXJuIDA7aWYobzw9MCYmYz49MClyZXR1cm4gMH1oPXUsYT1sLG89Y319cmV0dXJuIHMlMiE9PTB9ZnVuY3Rpb24gSnkoaSx0LGU9e30pe2lmKCFpKXRocm93IG5ldyBFcnJvcigicG9pbnQgaXMgcmVxdWlyZWQiKTtpZighdCl0aHJvdyBuZXcgRXJyb3IoInBvbHlnb24gaXMgcmVxdWlyZWQiKTtjb25zdCBuPUJ5KGkpLHM9SXkodCkscj1zLnR5cGUsbz10LmJib3g7bGV0IGE9cy5jb29yZGluYXRlcztpZihvJiZZeShuLG8pPT09ITEpcmV0dXJuITE7cj09PSJQb2x5Z29uIiYmKGE9W2FdKTtsZXQgYz0hMTtmb3IodmFyIGw9MDtsPGEubGVuZ3RoOysrbCl7Y29uc3QgaD1YeShuLGFbbF0pO2lmKGg9PT0wKXJldHVybiFlLmlnbm9yZUJvdW5kYXJ5O2gmJihjPSEwKX1yZXR1cm4gY31mdW5jdGlvbiBZeShpLHQpe3JldHVybiB0WzBdPD1pWzBdJiZ0WzFdPD1pWzFdJiZ0WzJdPj1pWzBdJiZ0WzNdPj1pWzFdfXZhciBqeT1KeTtjb25zdCBpdT0xZS02O2NsYXNzIHpue2NvbnN0cnVjdG9yKCl7dGhpcy5feDA9dGhpcy5feTA9dGhpcy5feDE9dGhpcy5feTE9bnVsbCx0aGlzLl89IiJ9bW92ZVRvKHQsZSl7dGhpcy5fKz1gTSR7dGhpcy5feDA9dGhpcy5feDE9K3R9LCR7dGhpcy5feTA9dGhpcy5feTE9K2V9YH1jbG9zZVBhdGgoKXt0aGlzLl94MSE9PW51bGwmJih0aGlzLl94MT10aGlzLl94MCx0aGlzLl95MT10aGlzLl95MCx0aGlzLl8rPSJaIil9bGluZVRvKHQsZSl7dGhpcy5fKz1gTCR7dGhpcy5feDE9K3R9LCR7dGhpcy5feTE9K2V9YH1hcmModCxlLG4pe3Q9K3QsZT0rZSxuPStuO2NvbnN0IHM9dCtuLHI9ZTtpZihuPDApdGhyb3cgbmV3IEVycm9yKCJuZWdhdGl2ZSByYWRpdXMiKTt0aGlzLl94MT09PW51bGw/dGhpcy5fKz1gTSR7c30sJHtyfWA6KE1hdGguYWJzKHRoaXMuX3gxLXMpPml1fHxNYXRoLmFicyh0aGlzLl95MS1yKT5pdSkmJih0aGlzLl8rPSJMIitzKyIsIityKSxuJiYodGhpcy5fKz1gQSR7bn0sJHtufSwwLDEsMSwke3Qtbn0sJHtlfUEke259LCR7bn0sMCwxLDEsJHt0aGlzLl94MT1zfSwke3RoaXMuX3kxPXJ9YCl9cmVjdCh0LGUsbixzKXt0aGlzLl8rPWBNJHt0aGlzLl94MD10aGlzLl94MT0rdH0sJHt0aGlzLl95MD10aGlzLl95MT0rZX1oJHsrbn12JHsrc31oJHstbn1aYH12YWx1ZSgpe3JldHVybiB0aGlzLl98fG51bGx9fWNsYXNzIGVje2NvbnN0cnVjdG9yKCl7dGhpcy5fPVtdfW1vdmVUbyh0LGUpe3RoaXMuXy5wdXNoKFt0LGVdKX1jbG9zZVBhdGgoKXt0aGlzLl8ucHVzaCh0aGlzLl9bMF0uc2xpY2UoKSl9bGluZVRvKHQsZSl7dGhpcy5fLnB1c2goW3QsZV0pfXZhbHVlKCl7cmV0dXJuIHRoaXMuXy5sZW5ndGg/dGhpcy5fOm51bGx9fWNsYXNzIFF5e2NvbnN0cnVjdG9yKHQsW2UsbixzLHJdPVswLDAsOTYwLDUwMF0pe2lmKCEoKHM9K3MpPj0oZT0rZSkpfHwhKChyPStyKT49KG49K24pKSl0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgYm91bmRzIik7dGhpcy5kZWxhdW5heT10LHRoaXMuX2NpcmN1bWNlbnRlcnM9bmV3IEZsb2F0NjRBcnJheSh0LnBvaW50cy5sZW5ndGgqMiksdGhpcy52ZWN0b3JzPW5ldyBGbG9hdDY0QXJyYXkodC5wb2ludHMubGVuZ3RoKjIpLHRoaXMueG1heD1zLHRoaXMueG1pbj1lLHRoaXMueW1heD1yLHRoaXMueW1pbj1uLHRoaXMuX2luaXQoKX11cGRhdGUoKXtyZXR1cm4gdGhpcy5kZWxhdW5heS51cGRhdGUoKSx0aGlzLl9pbml0KCksdGhpc31faW5pdCgpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dCxodWxsOmUsdHJpYW5nbGVzOm59LHZlY3RvcnM6c309dGhpcyxyPXRoaXMuY2lyY3VtY2VudGVycz10aGlzLl9jaXJjdW1jZW50ZXJzLnN1YmFycmF5KDAsbi5sZW5ndGgvMyoyKTtmb3IobGV0IGQ9MCxwPTAseT1uLmxlbmd0aCxtLGc7ZDx5O2QrPTMscCs9Mil7Y29uc3QgYj1uW2RdKjIsdz1uW2QrMV0qMix4PW5bZCsyXSoyLE09dFtiXSxBPXRbYisxXSxTPXRbd10sXz10W3crMV0sRT10W3hdLHo9dFt4KzFdLHY9Uy1NLEM9Xy1BLFA9RS1NLEY9ei1BLEI9KHYqRi1DKlApKjI7aWYoTWF0aC5hYnMoQik8MWUtOSl7bGV0IEk9MWU5O2NvbnN0IGs9blswXSoyO0kqPU1hdGguc2lnbigodFtrXS1NKSpGLSh0W2srMV0tQSkqUCksbT0oTStFKS8yLUkqRixnPShBK3opLzIrSSpQfWVsc2V7Y29uc3QgST0xL0Isaz12KnYrQypDLEQ9UCpQK0YqRjttPU0rKEYqay1DKkQpKkksZz1BKyh2KkQtUCprKSpJfXJbcF09bSxyW3ArMV09Z31sZXQgbz1lW2UubGVuZ3RoLTFdLGEsYz1vKjQsbCxoPXRbMipvXSx1LGY9dFsyKm8rMV07cy5maWxsKDApO2ZvcihsZXQgZD0wO2Q8ZS5sZW5ndGg7KytkKW89ZVtkXSxhPWMsbD1oLHU9ZixjPW8qNCxoPXRbMipvXSxmPXRbMipvKzFdLHNbYSsyXT1zW2NdPXUtZixzW2ErM109c1tjKzFdPWgtbH1yZW5kZXIodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7ZGVsYXVuYXk6e2hhbGZlZGdlczpuLGluZWRnZXM6cyxodWxsOnJ9LGNpcmN1bWNlbnRlcnM6byx2ZWN0b3JzOmF9PXRoaXM7aWYoci5sZW5ndGg8PTEpcmV0dXJuIG51bGw7Zm9yKGxldCBoPTAsdT1uLmxlbmd0aDtoPHU7KytoKXtjb25zdCBmPW5baF07aWYoZjxoKWNvbnRpbnVlO2NvbnN0IGQ9TWF0aC5mbG9vcihoLzMpKjIscD1NYXRoLmZsb29yKGYvMykqMix5PW9bZF0sbT1vW2QrMV0sZz1vW3BdLGI9b1twKzFdO3RoaXMuX3JlbmRlclNlZ21lbnQoeSxtLGcsYix0KX1sZXQgYyxsPXJbci5sZW5ndGgtMV07Zm9yKGxldCBoPTA7aDxyLmxlbmd0aDsrK2gpe2M9bCxsPXJbaF07Y29uc3QgdT1NYXRoLmZsb29yKHNbbF0vMykqMixmPW9bdV0sZD1vW3UrMV0scD1jKjQseT10aGlzLl9wcm9qZWN0KGYsZCxhW3ArMl0sYVtwKzNdKTt5JiZ0aGlzLl9yZW5kZXJTZWdtZW50KGYsZCx5WzBdLHlbMV0sdCl9cmV0dXJuIGUmJmUudmFsdWUoKX1yZW5kZXJCb3VuZHModCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMDtyZXR1cm4gdC5yZWN0KHRoaXMueG1pbix0aGlzLnltaW4sdGhpcy54bWF4LXRoaXMueG1pbix0aGlzLnltYXgtdGhpcy55bWluKSxlJiZlLnZhbHVlKCl9cmVuZGVyQ2VsbCh0LGUpe2NvbnN0IG49ZT09bnVsbD9lPW5ldyB6bjp2b2lkIDAscz10aGlzLl9jbGlwKHQpO2lmKHM9PT1udWxsfHwhcy5sZW5ndGgpcmV0dXJuO2UubW92ZVRvKHNbMF0sc1sxXSk7bGV0IHI9cy5sZW5ndGg7Zm9yKDtzWzBdPT09c1tyLTJdJiZzWzFdPT09c1tyLTFdJiZyPjE7KXItPTI7Zm9yKGxldCBvPTI7bzxyO28rPTIpKHNbb10hPT1zW28tMl18fHNbbysxXSE9PXNbby0xXSkmJmUubGluZVRvKHNbb10sc1tvKzFdKTtyZXR1cm4gZS5jbG9zZVBhdGgoKSxuJiZuLnZhbHVlKCl9KmNlbGxQb2x5Z29ucygpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dH19PXRoaXM7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aC8yO2U8bjsrK2Upe2NvbnN0IHM9dGhpcy5jZWxsUG9seWdvbihlKTtzJiYocy5pbmRleD1lLHlpZWxkIHMpfX1jZWxsUG9seWdvbih0KXtjb25zdCBlPW5ldyBlYztyZXR1cm4gdGhpcy5yZW5kZXJDZWxsKHQsZSksZS52YWx1ZSgpfV9yZW5kZXJTZWdtZW50KHQsZSxuLHMscil7bGV0IG87Y29uc3QgYT10aGlzLl9yZWdpb25jb2RlKHQsZSksYz10aGlzLl9yZWdpb25jb2RlKG4scyk7YT09PTAmJmM9PT0wPyhyLm1vdmVUbyh0LGUpLHIubGluZVRvKG4scykpOihvPXRoaXMuX2NsaXBTZWdtZW50KHQsZSxuLHMsYSxjKSkmJihyLm1vdmVUbyhvWzBdLG9bMV0pLHIubGluZVRvKG9bMl0sb1szXSkpfWNvbnRhaW5zKHQsZSxuKXtyZXR1cm4gZT0rZSxlIT09ZXx8KG49K24sbiE9PW4pPyExOnRoaXMuZGVsYXVuYXkuX3N0ZXAodCxlLG4pPT09dH0qbmVpZ2hib3JzKHQpe2NvbnN0IGU9dGhpcy5fY2xpcCh0KTtpZihlKWZvcihjb25zdCBuIG9mIHRoaXMuZGVsYXVuYXkubmVpZ2hib3JzKHQpKXtjb25zdCBzPXRoaXMuX2NsaXAobik7aWYocyl7dDpmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKz0yKWZvcihsZXQgYT0wLGM9cy5sZW5ndGg7YTxjO2ErPTIpaWYoZVtyXT09c1thXSYmZVtyKzFdPT1zW2ErMV0mJmVbKHIrMiklb109PXNbKGErYy0yKSVjXSYmZVsociszKSVvXT09c1soYStjLTEpJWNdKXt5aWVsZCBuO2JyZWFrIHR9fX19X2NlbGwodCl7Y29uc3R7Y2lyY3VtY2VudGVyczplLGRlbGF1bmF5OntpbmVkZ2VzOm4saGFsZmVkZ2VzOnMsdHJpYW5nbGVzOnJ9fT10aGlzLG89blt0XTtpZihvPT09LTEpcmV0dXJuIG51bGw7Y29uc3QgYT1bXTtsZXQgYz1vO2Rve2NvbnN0IGw9TWF0aC5mbG9vcihjLzMpO2lmKGEucHVzaChlW2wqMl0sZVtsKjIrMV0pLGM9YyUzPT09Mj9jLTI6YysxLHJbY10hPT10KWJyZWFrO2M9c1tjXX13aGlsZShjIT09byYmYyE9PS0xKTtyZXR1cm4gYX1fY2xpcCh0KXtpZih0PT09MCYmdGhpcy5kZWxhdW5heS5odWxsLmxlbmd0aD09PTEpcmV0dXJuW3RoaXMueG1heCx0aGlzLnltaW4sdGhpcy54bWF4LHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltaW5dO2NvbnN0IGU9dGhpcy5fY2VsbCh0KTtpZihlPT09bnVsbClyZXR1cm4gbnVsbDtjb25zdHt2ZWN0b3JzOm59PXRoaXMscz10KjQ7cmV0dXJuIG5bc118fG5bcysxXT90aGlzLl9jbGlwSW5maW5pdGUodCxlLG5bc10sbltzKzFdLG5bcysyXSxuW3MrM10pOnRoaXMuX2NsaXBGaW5pdGUodCxlKX1fY2xpcEZpbml0ZSh0LGUpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHM9bnVsbCxyLG8sYT1lW24tMl0sYz1lW24tMV0sbCxoPXRoaXMuX3JlZ2lvbmNvZGUoYSxjKSx1LGY9MDtmb3IobGV0IGQ9MDtkPG47ZCs9MilpZihyPWEsbz1jLGE9ZVtkXSxjPWVbZCsxXSxsPWgsaD10aGlzLl9yZWdpb25jb2RlKGEsYyksbD09PTAmJmg9PT0wKXU9ZixmPTAscz9zLnB1c2goYSxjKTpzPVthLGNdO2Vsc2V7bGV0IHAseSxtLGcsYjtpZihsPT09MCl7aWYoKHA9dGhpcy5fY2xpcFNlZ21lbnQocixvLGEsYyxsLGgpKT09PW51bGwpY29udGludWU7W3ksbSxnLGJdPXB9ZWxzZXtpZigocD10aGlzLl9jbGlwU2VnbWVudChhLGMscixvLGgsbCkpPT09bnVsbCljb250aW51ZTtbZyxiLHksbV09cCx1PWYsZj10aGlzLl9lZGdlY29kZSh5LG0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCkscz9zLnB1c2goeSxtKTpzPVt5LG1dfXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGcsYiksdSYmZiYmdGhpcy5fZWRnZSh0LHUsZixzLHMubGVuZ3RoKSxzP3MucHVzaChnLGIpOnM9W2csYl19aWYocyl1PWYsZj10aGlzLl9lZGdlY29kZShzWzBdLHNbMV0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCk7ZWxzZSBpZih0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpKXJldHVyblt0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWluXTtyZXR1cm4gc31fY2xpcFNlZ21lbnQodCxlLG4scyxyLG8pe2Zvcig7Oyl7aWYocj09PTAmJm89PT0wKXJldHVyblt0LGUsbixzXTtpZihyJm8pcmV0dXJuIG51bGw7bGV0IGEsYyxsPXJ8fG87bCY4PyhhPXQrKG4tdCkqKHRoaXMueW1heC1lKS8ocy1lKSxjPXRoaXMueW1heCk6bCY0PyhhPXQrKG4tdCkqKHRoaXMueW1pbi1lKS8ocy1lKSxjPXRoaXMueW1pbik6bCYyPyhjPWUrKHMtZSkqKHRoaXMueG1heC10KS8obi10KSxhPXRoaXMueG1heCk6KGM9ZSsocy1lKSoodGhpcy54bWluLXQpLyhuLXQpLGE9dGhpcy54bWluKSxyPyh0PWEsZT1jLHI9dGhpcy5fcmVnaW9uY29kZSh0LGUpKToobj1hLHM9YyxvPXRoaXMuX3JlZ2lvbmNvZGUobixzKSl9fV9jbGlwSW5maW5pdGUodCxlLG4scyxyLG8pe2xldCBhPUFycmF5LmZyb20oZSksYztpZigoYz10aGlzLl9wcm9qZWN0KGFbMF0sYVsxXSxuLHMpKSYmYS51bnNoaWZ0KGNbMF0sY1sxXSksKGM9dGhpcy5fcHJvamVjdChhW2EubGVuZ3RoLTJdLGFbYS5sZW5ndGgtMV0scixvKSkmJmEucHVzaChjWzBdLGNbMV0pLGE9dGhpcy5fY2xpcEZpbml0ZSh0LGEpKWZvcihsZXQgbD0wLGg9YS5sZW5ndGgsdSxmPXRoaXMuX2VkZ2Vjb2RlKGFbaC0yXSxhW2gtMV0pO2w8aDtsKz0yKXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGFbbF0sYVtsKzFdKSx1JiZmJiYobD10aGlzLl9lZGdlKHQsdSxmLGEsbCksaD1hLmxlbmd0aCk7ZWxzZSB0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpJiYoYT1bdGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heF0pO3JldHVybiBhfV9lZGdlKHQsZSxuLHMscil7Zm9yKDtlIT09bjspe2xldCBvLGE7c3dpdGNoKGUpe2Nhc2UgNTplPTQ7Y29udGludWU7Y2FzZSA0OmU9NixvPXRoaXMueG1heCxhPXRoaXMueW1pbjticmVhaztjYXNlIDY6ZT0yO2NvbnRpbnVlO2Nhc2UgMjplPTEwLG89dGhpcy54bWF4LGE9dGhpcy55bWF4O2JyZWFrO2Nhc2UgMTA6ZT04O2NvbnRpbnVlO2Nhc2UgODplPTksbz10aGlzLnhtaW4sYT10aGlzLnltYXg7YnJlYWs7Y2FzZSA5OmU9MTtjb250aW51ZTtjYXNlIDE6ZT01LG89dGhpcy54bWluLGE9dGhpcy55bWluO2JyZWFrfShzW3JdIT09b3x8c1tyKzFdIT09YSkmJnRoaXMuY29udGFpbnModCxvLGEpJiYocy5zcGxpY2UociwwLG8sYSkscis9Mil9aWYocy5sZW5ndGg+NClmb3IobGV0IG89MDtvPHMubGVuZ3RoO28rPTIpe2NvbnN0IGE9KG8rMiklcy5sZW5ndGgsYz0obys0KSVzLmxlbmd0aDsoc1tvXT09PXNbYV0mJnNbYV09PT1zW2NdfHxzW28rMV09PT1zW2ErMV0mJnNbYSsxXT09PXNbYysxXSkmJihzLnNwbGljZShhLDIpLG8tPTIpfXJldHVybiByfV9wcm9qZWN0KHQsZSxuLHMpe2xldCByPTEvMCxvLGEsYztpZihzPDApe2lmKGU8PXRoaXMueW1pbilyZXR1cm4gbnVsbDsobz0odGhpcy55bWluLWUpL3MpPHImJihjPXRoaXMueW1pbixhPXQrKHI9bykqbil9ZWxzZSBpZihzPjApe2lmKGU+PXRoaXMueW1heClyZXR1cm4gbnVsbDsobz0odGhpcy55bWF4LWUpL3MpPHImJihjPXRoaXMueW1heCxhPXQrKHI9bykqbil9aWYobj4wKXtpZih0Pj10aGlzLnhtYXgpcmV0dXJuIG51bGw7KG89KHRoaXMueG1heC10KS9uKTxyJiYoYT10aGlzLnhtYXgsYz1lKyhyPW8pKnMpfWVsc2UgaWYobjwwKXtpZih0PD10aGlzLnhtaW4pcmV0dXJuIG51bGw7KG89KHRoaXMueG1pbi10KS9uKTxyJiYoYT10aGlzLnhtaW4sYz1lKyhyPW8pKnMpfXJldHVyblthLGNdfV9lZGdlY29kZSh0LGUpe3JldHVybih0PT09dGhpcy54bWluPzE6dD09PXRoaXMueG1heD8yOjApfChlPT09dGhpcy55bWluPzQ6ZT09PXRoaXMueW1heD84OjApfV9yZWdpb25jb2RlKHQsZSl7cmV0dXJuKHQ8dGhpcy54bWluPzE6dD50aGlzLnhtYXg/MjowKXwoZTx0aGlzLnltaW4/NDplPnRoaXMueW1heD84OjApfX1jb25zdCBLeT0yKk1hdGguUEksdWk9TWF0aC5wb3c7ZnVuY3Rpb24gdG0oaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gZW0oaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gbm0oaSl7Y29uc3R7dHJpYW5nbGVzOnQsY29vcmRzOmV9PWk7Zm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKz0zKXtjb25zdCBzPTIqdFtuXSxyPTIqdFtuKzFdLG89Mip0W24rMl07aWYoKGVbb10tZVtzXSkqKGVbcisxXS1lW3MrMV0pLShlW3JdLWVbc10pKihlW28rMV0tZVtzKzFdKT4xZS0xMClyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBpbShpLHQsZSl7cmV0dXJuW2krTWF0aC5zaW4oaSt0KSplLHQrTWF0aC5jb3MoaS10KSplXX1jbGFzcyBuY3tzdGF0aWMgZnJvbSh0LGU9dG0sbj1lbSxzKXtyZXR1cm4gbmV3IG5jKCJsZW5ndGgiaW4gdD9zbSh0LGUsbixzKTpGbG9hdDY0QXJyYXkuZnJvbShybSh0LGUsbixzKSkpfWNvbnN0cnVjdG9yKHQpe3RoaXMuX2RlbGF1bmF0b3I9bmV3IHRzKHQpLHRoaXMuaW5lZGdlcz1uZXcgSW50MzJBcnJheSh0Lmxlbmd0aC8yKSx0aGlzLl9odWxsSW5kZXg9bmV3IEludDMyQXJyYXkodC5sZW5ndGgvMiksdGhpcy5wb2ludHM9dGhpcy5fZGVsYXVuYXRvci5jb29yZHMsdGhpcy5faW5pdCgpfXVwZGF0ZSgpe3JldHVybiB0aGlzLl9kZWxhdW5hdG9yLnVwZGF0ZSgpLHRoaXMuX2luaXQoKSx0aGlzfV9pbml0KCl7Y29uc3QgdD10aGlzLl9kZWxhdW5hdG9yLGU9dGhpcy5wb2ludHM7aWYodC5odWxsJiZ0Lmh1bGwubGVuZ3RoPjImJm5tKHQpKXt0aGlzLmNvbGxpbmVhcj1JbnQzMkFycmF5LmZyb20oe2xlbmd0aDplLmxlbmd0aC8yfSwoZixkKT0+ZCkuc29ydCgoZixkKT0+ZVsyKmZdLWVbMipkXXx8ZVsyKmYrMV0tZVsyKmQrMV0pO2NvbnN0IGM9dGhpcy5jb2xsaW5lYXJbMF0sbD10aGlzLmNvbGxpbmVhclt0aGlzLmNvbGxpbmVhci5sZW5ndGgtMV0saD1bZVsyKmNdLGVbMipjKzFdLGVbMipsXSxlWzIqbCsxXV0sdT0xZS04Kk1hdGguaHlwb3QoaFszXS1oWzFdLGhbMl0taFswXSk7Zm9yKGxldCBmPTAsZD1lLmxlbmd0aC8yO2Y8ZDsrK2Ype2NvbnN0IHA9aW0oZVsyKmZdLGVbMipmKzFdLHUpO2VbMipmXT1wWzBdLGVbMipmKzFdPXBbMV19dGhpcy5fZGVsYXVuYXRvcj1uZXcgdHMoZSl9ZWxzZSBkZWxldGUgdGhpcy5jb2xsaW5lYXI7Y29uc3Qgbj10aGlzLmhhbGZlZGdlcz10aGlzLl9kZWxhdW5hdG9yLmhhbGZlZGdlcyxzPXRoaXMuaHVsbD10aGlzLl9kZWxhdW5hdG9yLmh1bGwscj10aGlzLnRyaWFuZ2xlcz10aGlzLl9kZWxhdW5hdG9yLnRyaWFuZ2xlcyxvPXRoaXMuaW5lZGdlcy5maWxsKC0xKSxhPXRoaXMuX2h1bGxJbmRleC5maWxsKC0xKTtmb3IobGV0IGM9MCxsPW4ubGVuZ3RoO2M8bDsrK2Mpe2NvbnN0IGg9cltjJTM9PT0yP2MtMjpjKzFdOyhuW2NdPT09LTF8fG9baF09PT0tMSkmJihvW2hdPWMpfWZvcihsZXQgYz0wLGw9cy5sZW5ndGg7YzxsOysrYylhW3NbY11dPWM7cy5sZW5ndGg8PTImJnMubGVuZ3RoPjAmJih0aGlzLnRyaWFuZ2xlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLmhhbGZlZGdlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLnRyaWFuZ2xlc1swXT1zWzBdLG9bc1swXV09MSxzLmxlbmd0aD09PTImJihvW3NbMV1dPTAsdGhpcy50cmlhbmdsZXNbMV09c1sxXSx0aGlzLnRyaWFuZ2xlc1syXT1zWzFdKSl9dm9yb25vaSh0KXtyZXR1cm4gbmV3IFF5KHRoaXMsdCl9Km5laWdoYm9ycyh0KXtjb25zdHtpbmVkZ2VzOmUsaHVsbDpuLF9odWxsSW5kZXg6cyxoYWxmZWRnZXM6cix0cmlhbmdsZXM6byxjb2xsaW5lYXI6YX09dGhpcztpZihhKXtjb25zdCB1PWEuaW5kZXhPZih0KTt1PjAmJih5aWVsZCBhW3UtMV0pLHU8YS5sZW5ndGgtMSYmKHlpZWxkIGFbdSsxXSk7cmV0dXJufWNvbnN0IGM9ZVt0XTtpZihjPT09LTEpcmV0dXJuO2xldCBsPWMsaD0tMTtkb3tpZih5aWVsZCBoPW9bbF0sbD1sJTM9PT0yP2wtMjpsKzEsb1tsXSE9PXQpcmV0dXJuO2lmKGw9cltsXSxsPT09LTEpe2NvbnN0IHU9blsoc1t0XSsxKSVuLmxlbmd0aF07dSE9PWgmJih5aWVsZCB1KTtyZXR1cm59fXdoaWxlKGwhPT1jKX1maW5kKHQsZSxuPTApe2lmKHQ9K3QsdCE9PXR8fChlPStlLGUhPT1lKSlyZXR1cm4tMTtjb25zdCBzPW47bGV0IHI7Zm9yKDsocj10aGlzLl9zdGVwKG4sdCxlKSk+PTAmJnIhPT1uJiZyIT09czspbj1yO3JldHVybiByfV9zdGVwKHQsZSxuKXtjb25zdHtpbmVkZ2VzOnMsaHVsbDpyLF9odWxsSW5kZXg6byxoYWxmZWRnZXM6YSx0cmlhbmdsZXM6Yyxwb2ludHM6bH09dGhpcztpZihzW3RdPT09LTF8fCFsLmxlbmd0aClyZXR1cm4odCsxKSUobC5sZW5ndGg+PjEpO2xldCBoPXQsdT11aShlLWxbdCoyXSwyKSt1aShuLWxbdCoyKzFdLDIpO2NvbnN0IGY9c1t0XTtsZXQgZD1mO2Rve2xldCBwPWNbZF07Y29uc3QgeT11aShlLWxbcCoyXSwyKSt1aShuLWxbcCoyKzFdLDIpO2lmKHk8dSYmKHU9eSxoPXApLGQ9ZCUzPT09Mj9kLTI6ZCsxLGNbZF0hPT10KWJyZWFrO2lmKGQ9YVtkXSxkPT09LTEpe2lmKGQ9clsob1t0XSsxKSVyLmxlbmd0aF0sZCE9PXAmJnVpKGUtbFtkKjJdLDIpK3VpKG4tbFtkKjIrMV0sMik8dSlyZXR1cm4gZDticmVha319d2hpbGUoZCE9PWYpO3JldHVybiBofXJlbmRlcih0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgem46dm9pZCAwLHtwb2ludHM6bixoYWxmZWRnZXM6cyx0cmlhbmdsZXM6cn09dGhpcztmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTsrK28pe2NvbnN0IGM9c1tvXTtpZihjPG8pY29udGludWU7Y29uc3QgbD1yW29dKjIsaD1yW2NdKjI7dC5tb3ZlVG8obltsXSxuW2wrMV0pLHQubGluZVRvKG5baF0sbltoKzFdKX1yZXR1cm4gdGhpcy5yZW5kZXJIdWxsKHQpLGUmJmUudmFsdWUoKX1yZW5kZXJQb2ludHModCxlKXtlPT09dm9pZCAwJiYoIXR8fHR5cGVvZiB0Lm1vdmVUbyE9ImZ1bmN0aW9uIikmJihlPXQsdD1udWxsKSxlPWU9PW51bGw/MjorZTtjb25zdCBuPXQ9PW51bGw/dD1uZXcgem46dm9pZCAwLHtwb2ludHM6c309dGhpcztmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKz0yKXtjb25zdCBhPXNbcl0sYz1zW3IrMV07dC5tb3ZlVG8oYStlLGMpLHQuYXJjKGEsYyxlLDAsS3kpfXJldHVybiBuJiZuLnZhbHVlKCl9cmVuZGVySHVsbCh0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgem46dm9pZCAwLHtodWxsOm4scG9pbnRzOnN9PXRoaXMscj1uWzBdKjIsbz1uLmxlbmd0aDt0Lm1vdmVUbyhzW3JdLHNbcisxXSk7Zm9yKGxldCBhPTE7YTxvOysrYSl7Y29uc3QgYz0yKm5bYV07dC5saW5lVG8oc1tjXSxzW2MrMV0pfXJldHVybiB0LmNsb3NlUGF0aCgpLGUmJmUudmFsdWUoKX1odWxsUG9seWdvbigpe2NvbnN0IHQ9bmV3IGVjO3JldHVybiB0aGlzLnJlbmRlckh1bGwodCksdC52YWx1ZSgpfXJlbmRlclRyaWFuZ2xlKHQsZSl7Y29uc3Qgbj1lPT1udWxsP2U9bmV3IHpuOnZvaWQgMCx7cG9pbnRzOnMsdHJpYW5nbGVzOnJ9PXRoaXMsbz1yW3QqPTNdKjIsYT1yW3QrMV0qMixjPXJbdCsyXSoyO3JldHVybiBlLm1vdmVUbyhzW29dLHNbbysxXSksZS5saW5lVG8oc1thXSxzW2ErMV0pLGUubGluZVRvKHNbY10sc1tjKzFdKSxlLmNsb3NlUGF0aCgpLG4mJm4udmFsdWUoKX0qdHJpYW5nbGVQb2x5Z29ucygpe2NvbnN0e3RyaWFuZ2xlczp0fT10aGlzO2ZvcihsZXQgZT0wLG49dC5sZW5ndGgvMztlPG47KytlKXlpZWxkIHRoaXMudHJpYW5nbGVQb2x5Z29uKGUpfXRyaWFuZ2xlUG9seWdvbih0KXtjb25zdCBlPW5ldyBlYztyZXR1cm4gdGhpcy5yZW5kZXJUcmlhbmdsZSh0LGUpLGUudmFsdWUoKX19ZnVuY3Rpb24gc20oaSx0LGUsbil7Y29uc3Qgcz1pLmxlbmd0aCxyPW5ldyBGbG9hdDY0QXJyYXkocyoyKTtmb3IobGV0IG89MDtvPHM7KytvKXtjb25zdCBhPWlbb107cltvKjJdPXQuY2FsbChuLGEsbyxpKSxyW28qMisxXT1lLmNhbGwobixhLG8saSl9cmV0dXJuIHJ9ZnVuY3Rpb24qcm0oaSx0LGUsbil7bGV0IHM9MDtmb3IoY29uc3QgciBvZiBpKXlpZWxkIHQuY2FsbChuLHIscyxpKSx5aWVsZCBlLmNhbGwobixyLHMsaSksKytzfWNvbnN0IGljPU1hdGguUEksc3U9aWMvMixydT0xODAvaWMsb3U9aWMvMTgwLG9tPU1hdGguYXRhbjIsYXU9TWF0aC5jb3MsYW09TWF0aC5tYXgsY209TWF0aC5taW4sY3U9TWF0aC5zaW4sbG09TWF0aC5zaWdufHxmdW5jdGlvbihpKXtyZXR1cm4gaT4wPzE6aTwwPy0xOjB9LGx1PU1hdGguc3FydDtmdW5jdGlvbiBobShpKXtyZXR1cm4gaT4xP3N1Omk8LTE/LXN1Ok1hdGguYXNpbihpKX1mdW5jdGlvbiBodShpLHQpe3JldHVybiBpWzBdKnRbMF0raVsxXSp0WzFdK2lbMl0qdFsyXX1mdW5jdGlvbiBXdChpLHQpe3JldHVybltpWzFdKnRbMl0taVsyXSp0WzFdLGlbMl0qdFswXS1pWzBdKnRbMl0saVswXSp0WzFdLWlbMV0qdFswXV19ZnVuY3Rpb24gRHIoaSx0KXtyZXR1cm5baVswXSt0WzBdLGlbMV0rdFsxXSxpWzJdK3RbMl1dfWZ1bmN0aW9uICRyKGkpe3ZhciB0PWx1KGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtyZXR1cm5baVswXS90LGlbMV0vdCxpWzJdL3RdfWZ1bmN0aW9uIHNjKGkpe3JldHVybltvbShpWzFdLGlbMF0pKnJ1LGhtKGFtKC0xLGNtKDEsaVsyXSkpKSpydV19ZnVuY3Rpb24gTWUoaSl7Y29uc3QgdD1pWzBdKm91LGU9aVsxXSpvdSxuPWF1KGUpO3JldHVybltuKmF1KHQpLG4qY3UodCksY3UoZSldfWZ1bmN0aW9uIHJjKGkpe3JldHVybiBpPWkubWFwKHQ9Pk1lKHQpKSxodShpWzBdLFd0KGlbMl0saVsxXSkpfWZ1bmN0aW9uIHVtKGkpe2NvbnN0IHQ9ZG0oaSksZT15bSh0KSxuPXBtKGUsaSkscz1nbShlLGkubGVuZ3RoKSxyPWZtKHMsaSksbz1tbShlLGkpLHtwb2x5Z29uczphLGNlbnRlcnM6Y309eG0obyxlLGkpLGw9d20oYSksaD1NbShlLGkpLHU9Ym0obixlKTtyZXR1cm57ZGVsYXVuYXk6dCxlZGdlczpuLHRyaWFuZ2xlczplLGNlbnRlcnM6YyxuZWlnaGJvcnM6cyxwb2x5Z29uczphLG1lc2g6bCxodWxsOmgsdXJxdWhhcnQ6dSxmaW5kOnJ9fWZ1bmN0aW9uIGZtKGksdCl7ZnVuY3Rpb24gZShuLHMpe2xldCByPW5bMF0tc1swXSxvPW5bMV0tc1sxXSxhPW5bMl0tc1syXTtyZXR1cm4gcipyK28qbythKmF9cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtvPT09dm9pZCAwJiYobz0wKTtsZXQgYSxjLGw9bztjb25zdCBoPU1lKFtzLHJdKTtkbyBhPW8sbz1udWxsLGM9ZShoLE1lKHRbYV0pKSxpW2FdLmZvckVhY2godT0+e2xldCBmPWUoaCxNZSh0W3VdKSk7aWYoZjxjKXtjPWYsbz11LGw9dTtyZXR1cm59fSk7d2hpbGUobyE9PW51bGwpO3JldHVybiBsfX1mdW5jdGlvbiBkbShpKXtpZihpLmxlbmd0aDwyKXJldHVybnt9O2xldCB0PTA7Zm9yKDtpc05hTihpW3RdWzBdK2lbdF1bMV0pJiZ0Kys8aS5sZW5ndGg7KTtjb25zdCBlPVNoKGlbdF0pLG49aXkoKS50cmFuc2xhdGUoWzAsMF0pLnNjYWxlKDEpLnJvdGF0ZShlLmludmVydChbMTgwLDBdKSk7aT1pLm1hcChuKTtjb25zdCBzPVtdO2xldCByPTE7Zm9yKGxldCB1PTAsZj1pLmxlbmd0aDt1PGY7dSsrKXtsZXQgZD15aShpW3VdWzBdLDIpK3lpKGlbdV1bMV0sMik7IWlzRmluaXRlKGQpfHxkPjFlMzI/cy5wdXNoKHUpOmQ+ciYmKHI9ZCl9Y29uc3Qgbz0xZTYqbHUocik7cy5mb3JFYWNoKHU9PmlbdV09W28sMF0pLGkucHVzaChbMCxvXSksaS5wdXNoKFstbywwXSksaS5wdXNoKFswLC1vXSk7Y29uc3QgYT1uYy5mcm9tKGkpO2EucHJvamVjdGlvbj1uO2NvbnN0e3RyaWFuZ2xlczpjLGhhbGZlZGdlczpsLGluZWRnZXM6aH09YTtmb3IobGV0IHU9MCxmPWwubGVuZ3RoO3U8Zjt1KyspaWYobFt1XTwwKXtjb25zdCBkPXUlMz09Mj91LTI6dSsxLHA9dSUzPT0wP3UrMjp1LTEseT1sW2RdLG09bFtwXTtsW3ldPW0sbFttXT15LGxbZF09bFtwXT0tMSxjW3VdPWNbZF09Y1twXT10LGhbY1t5XV09eSUzPT0wP3krMjp5LTEsaFtjW21dXT1tJTM9PTA/bSsyOm0tMSx1Kz0yLXUlM31lbHNlIGNbdV0+aS5sZW5ndGgtMy0xJiYoY1t1XT10KTtyZXR1cm4gYX1mdW5jdGlvbiBwbShpLHQpe2NvbnN0IGU9bmV3IFNldDtyZXR1cm4gdC5sZW5ndGg9PT0yP1tbMCwxXV06KGkuZm9yRWFjaChuPT57aWYoblswXSE9PW5bMV0mJiEocmMobi5tYXAocz0+dFtzXSkpPDApKWZvcihsZXQgcz0wLHI7czwzO3MrKylyPShzKzEpJTMsZS5hZGQoc3IoW25bc10sbltyXV0pLmpvaW4oIi0iKSl9KSxBcnJheS5mcm9tKGUsbj0+bi5zcGxpdCgiLSIpLm1hcChOdW1iZXIpKSl9ZnVuY3Rpb24geW0oaSl7Y29uc3R7dHJpYW5nbGVzOnR9PWk7aWYoIXQpcmV0dXJuW107Y29uc3QgZT1bXTtmb3IobGV0IG49MCxzPXQubGVuZ3RoLzM7bjxzO24rKyl7Y29uc3Qgcj10WzMqbl0sbz10WzMqbisxXSxhPXRbMypuKzJdO3IhPT1vJiZvIT09YSYmZS5wdXNoKFtyLGEsb10pfXJldHVybiBlfWZ1bmN0aW9uIG1tKGksdCl7cmV0dXJuIGkubWFwKGU9Pntjb25zdCBuPWUubWFwKHI9PnRbcl0pLm1hcChNZSkscz1EcihEcihXdChuWzFdLG5bMF0pLFd0KG5bMl0sblsxXSkpLFd0KG5bMF0sblsyXSkpO3JldHVybiBzYygkcihzKSl9KX1mdW5jdGlvbiBnbShpLHQpe2NvbnN0IGU9W107cmV0dXJuIGkuZm9yRWFjaChuPT57Zm9yKGxldCBzPTA7czwzO3MrKyl7Y29uc3Qgcj1uW3NdLG89blsocysxKSUzXTtlW3JdPWVbcl18fFtdLGVbcl0ucHVzaChvKX19KSxpLmxlbmd0aD09PTAmJih0PT09Mj8oZVswXT1bMV0sZVsxXT1bMF0pOnQ9PT0xJiYoZVswXT1bXSkpLGV9ZnVuY3Rpb24geG0oaSx0LGUpe2NvbnN0IG49W10scz1pLnNsaWNlKCk7aWYodC5sZW5ndGg9PT0wKXtpZihlLmxlbmd0aDwyKXJldHVybntwb2x5Z29uczpuLGNlbnRlcnM6c307aWYoZS5sZW5ndGg9PT0yKXtjb25zdCBhPU1lKGVbMF0pLGM9TWUoZVsxXSksbD0kcihEcihhLGMpKSxoPSRyKFd0KGEsYykpLHU9V3QobCxoKSxmPVtsLFd0KGwsdSksV3QoV3QobCx1KSx1KSxXdChXdChXdChsLHUpLHUpLHUpXS5tYXAoc2MpLm1hcChvKTtyZXR1cm4gbi5wdXNoKGYpLG4ucHVzaChmLnNsaWNlKCkucmV2ZXJzZSgpKSx7cG9seWdvbnM6bixjZW50ZXJzOnN9fX10LmZvckVhY2goKGEsYyk9Pntmb3IobGV0IGw9MDtsPDM7bCsrKXtjb25zdCBoPWFbbF0sdT1hWyhsKzEpJTNdLGY9YVsobCsyKSUzXTtuW2hdPW5baF18fFtdLG5baF0ucHVzaChbdSxmLGMsW2gsdSxmXV0pfX0pO2NvbnN0IHI9bi5tYXAoYT0+e2NvbnN0IGM9W2FbMF1bMl1dO2xldCBsPWFbMF1bMV07Zm9yKGxldCBoPTE7aDxhLmxlbmd0aDtoKyspZm9yKGxldCB1PTA7dTxhLmxlbmd0aDt1KyspaWYoYVt1XVswXT09bCl7bD1hW3VdWzFdLGMucHVzaChhW3VdWzJdKTticmVha31pZihjLmxlbmd0aD4yKXJldHVybiBjO2lmKGMubGVuZ3RoPT0yKXtjb25zdCBoPXV1KGVbYVswXVszXVswXV0sZVthWzBdWzNdWzFdXSxzW2NbMF1dKSx1PXV1KGVbYVswXVszXVsyXV0sZVthWzBdWzNdWzBdXSxzW2NbMF1dKSxmPW8oaCksZD1vKHUpO3JldHVybltjWzBdLGQsY1sxXSxmXX19KTtmdW5jdGlvbiBvKGEpe2xldCBjPS0xO3JldHVybiBzLnNsaWNlKHQubGVuZ3RoLDEvMCkuZm9yRWFjaCgobCxoKT0+e2xbMF09PT1hWzBdJiZsWzFdPT09YVsxXSYmKGM9aCt0Lmxlbmd0aCl9KSxjPDAmJihjPXMubGVuZ3RoLHMucHVzaChhKSksY31yZXR1cm57cG9seWdvbnM6cixjZW50ZXJzOnN9fWZ1bmN0aW9uIHV1KGksdCxlKXtpPU1lKGkpLHQ9TWUodCksZT1NZShlKTtjb25zdCBuPWxtKGh1KFd0KHQsaSksZSkpO3JldHVybiBzYygkcihEcihpLHQpKS5tYXAocz0+bipzKSl9ZnVuY3Rpb24gd20oaSl7Y29uc3QgdD1bXTtyZXR1cm4gaS5mb3JFYWNoKGU9PntpZighZSlyZXR1cm47bGV0IG49ZVtlLmxlbmd0aC0xXTtmb3IobGV0IHMgb2YgZSlzPm4mJnQucHVzaChbbixzXSksbj1zfSksdH1mdW5jdGlvbiBibShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtjb25zdCBuPW5ldyBNYXAscz1uZXcgTWFwO3JldHVybiBpLmZvckVhY2goKHIsbyk9Pntjb25zdCBhPXIuam9pbigiLSIpO24uc2V0KGEsZVtvXSkscy5zZXQoYSwhMCl9KSx0LmZvckVhY2gocj0+e2xldCBvPTAsYT0tMTtmb3IobGV0IGM9MDtjPDM7YysrKXtsZXQgbD1zcihbcltjXSxyWyhjKzEpJTNdXSkuam9pbigiLSIpO24uZ2V0KGwpPm8mJihvPW4uZ2V0KGwpLGE9bCl9cy5zZXQoYSwhMSl9KSxpLm1hcChyPT5zLmdldChyLmpvaW4oIi0iKSkpfX1mdW5jdGlvbiBNbShpLHQpe2NvbnN0IGU9bmV3IFNldCxuPVtdO2kubWFwKGE9PntpZighKHJjKGEubWFwKGM9PnRbYz50Lmxlbmd0aD8wOmNdKSk+MWUtMTIpKWZvcihsZXQgYz0wO2M8MztjKyspe2xldCBsPVthW2NdLGFbKGMrMSklM11dLGg9YCR7bFswXX0tJHtsWzFdfWA7ZS5oYXMoaCk/ZS5kZWxldGUoaCk6ZS5hZGQoYCR7bFsxXX0tJHtsWzBdfWApfX0pO2NvbnN0IHM9bmV3IE1hcDtsZXQgcjtpZihlLmZvckVhY2goYT0+e2E9YS5zcGxpdCgiLSIpLm1hcChOdW1iZXIpLHMuc2V0KGFbMF0sYVsxXSkscj1hWzBdfSkscj09PXZvaWQgMClyZXR1cm4gbjtsZXQgbz1yO2Rve24ucHVzaChvKTtsZXQgYT1zLmdldChvKTtzLnNldChvLC0xKSxvPWF9d2hpbGUobz4tMSYmbyE9PXIpO3JldHVybiBufWZ1bmN0aW9uIEFtKGkpe2NvbnN0IHQ9ZnVuY3Rpb24oZSl7aWYodC5kZWxhdW5heT1udWxsLHQuX2RhdGE9ZSx0eXBlb2YgdC5fZGF0YT09Im9iamVjdCImJnQuX2RhdGEudHlwZT09PSJGZWF0dXJlQ29sbGVjdGlvbiImJih0Ll9kYXRhPXQuX2RhdGEuZmVhdHVyZXMpLHR5cGVvZiB0Ll9kYXRhPT0ib2JqZWN0Iil7Y29uc3Qgbj10Ll9kYXRhLm1hcChzPT5bdC5fdngocyksdC5fdnkocyksc10pLmZpbHRlcihzPT5pc0Zpbml0ZShzWzBdK3NbMV0pKTt0LnBvaW50cz1uLm1hcChzPT5bc1swXSxzWzFdXSksdC52YWxpZD1uLm1hcChzPT5zWzJdKSx0LmRlbGF1bmF5PXVtKHQucG9pbnRzKX1yZXR1cm4gdH07cmV0dXJuIHQuX3Z4PWZ1bmN0aW9uKGUpe2lmKHR5cGVvZiBlPT0ib2JqZWN0IiYmInR5cGUiaW4gZSlyZXR1cm4geGgoZSlbMF07aWYoMCBpbiBlKXJldHVybiBlWzBdfSx0Ll92eT1mdW5jdGlvbihlKXtpZih0eXBlb2YgZT09Im9iamVjdCImJiJ0eXBlImluIGUpcmV0dXJuIHhoKGUpWzFdO2lmKDEgaW4gZSlyZXR1cm4gZVsxXX0sdC54PWZ1bmN0aW9uKGUpe3JldHVybiBlPyh0Ll92eD1lLHQpOnQuX3Z4fSx0Lnk9ZnVuY3Rpb24oZSl7cmV0dXJuIGU/KHQuX3Z5PWUsdCk6dC5fdnl9LHQucG9seWdvbnM9ZnVuY3Rpb24oZSl7aWYoZSE9PXZvaWQgMCYmdChlKSwhdC5kZWxhdW5heSlyZXR1cm4hMTtjb25zdCBuPXt0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6W119O3JldHVybiB0LnZhbGlkLmxlbmd0aD09PTB8fCh0LmRlbGF1bmF5LnBvbHlnb25zLmZvckVhY2goKHMscik9Pm4uZmVhdHVyZXMucHVzaCh7dHlwZToiRmVhdHVyZSIsZ2VvbWV0cnk6cz97dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5zLHNbMF1dLm1hcChvPT50LmRlbGF1bmF5LmNlbnRlcnNbb10pXX06bnVsbCxwcm9wZXJ0aWVzOntzaXRlOnQudmFsaWRbcl0sc2l0ZWNvb3JkaW5hdGVzOnQucG9pbnRzW3JdLG5laWdoYm91cnM6dC5kZWxhdW5heS5uZWlnaGJvcnNbcl19fSkpLHQudmFsaWQubGVuZ3RoPT09MSYmbi5mZWF0dXJlcy5wdXNoKHt0eXBlOiJGZWF0dXJlIixnZW9tZXRyeTp7dHlwZToiU3BoZXJlIn0scHJvcGVydGllczp7c2l0ZTp0LnZhbGlkWzBdLHNpdGVjb29yZGluYXRlczp0LnBvaW50c1swXSxuZWlnaGJvdXJzOltdfX0pKSxufSx0LnRyaWFuZ2xlcz1mdW5jdGlvbihlKXtyZXR1cm4gZSE9PXZvaWQgMCYmdChlKSx0LmRlbGF1bmF5P3t0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6dC5kZWxhdW5heS50cmlhbmdsZXMubWFwKChuLHMpPT4obj1uLm1hcChyPT50LnBvaW50c1tyXSksbi5jZW50ZXI9dC5kZWxhdW5heS5jZW50ZXJzW3NdLG4pKS5maWx0ZXIobj0+cmMobik+MCkubWFwKG49Pih7dHlwZToiRmVhdHVyZSIscHJvcGVydGllczp7Y2lyY3VtY2VudGVyOm4uY2VudGVyfSxnZW9tZXRyeTp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLG5bMF1dXX19KSl9OiExfSx0LmxpbmtzPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3Qgbj10LmRlbGF1bmF5LmVkZ2VzLm1hcChyPT5yaSh0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXSkpLHM9dC5kZWxhdW5heS51cnF1aGFydChuKTtyZXR1cm57dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOnQuZGVsYXVuYXkuZWRnZXMubWFwKChyLG8pPT4oe3R5cGU6IkZlYXR1cmUiLHByb3BlcnRpZXM6e3NvdXJjZTp0LnZhbGlkW3JbMF1dLHRhcmdldDp0LnZhbGlkW3JbMV1dLGxlbmd0aDpuW29dLHVycXVoYXJ0OiEhc1tvXX0sZ2VvbWV0cnk6e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOlt0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXV19fSkpfX0sdC5tZXNoPWZ1bmN0aW9uKGUpe3JldHVybiBlIT09dm9pZCAwJiZ0KGUpLHQuZGVsYXVuYXk/e3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6dC5kZWxhdW5heS5lZGdlcy5tYXAobj0+W3QucG9pbnRzW25bMF1dLHQucG9pbnRzW25bMV1dXSl9OiExfSx0LmNlbGxNZXNoPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3R7Y2VudGVyczpuLHBvbHlnb25zOnN9PXQuZGVsYXVuYXkscj1bXTtmb3IoY29uc3QgbyBvZiBzKWlmKG8pZm9yKGxldCBhPW8ubGVuZ3RoLGM9b1thLTFdLGw9b1swXSxoPTA7aDxhO2M9bCxsPW9bKytoXSlsPmMmJnIucHVzaChbbltjXSxuW2xdXSk7cmV0dXJue3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6cn19LHQuX2ZvdW5kPXZvaWQgMCx0LmZpbmQ9ZnVuY3Rpb24oZSxuLHMpe2lmKHQuX2ZvdW5kPXQuZGVsYXVuYXkuZmluZChlLG4sdC5fZm91bmQpLCFzfHxyaShbZSxuXSx0LnBvaW50c1t0Ll9mb3VuZF0pPHMpcmV0dXJuIHQuX2ZvdW5kfSx0Lmh1bGw9ZnVuY3Rpb24oZSl7ZSE9PXZvaWQgMCYmdChlKTtjb25zdCBuPXQuZGVsYXVuYXkuaHVsbCxzPXQucG9pbnRzO3JldHVybiBuLmxlbmd0aD09PTA/bnVsbDp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLm1hcChyPT5zW3JdKSxzW25bMF1dXV19fSxpP3QoaSk6dH1mdW5jdGlvbiBTbShpLHQpe3N3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtjYXNlIDA6YnJlYWs7Y2FzZSAxOnRoaXMucmFuZ2UoaSk7YnJlYWs7ZGVmYXVsdDp0aGlzLnJhbmdlKHQpLmRvbWFpbihpKTticmVha31yZXR1cm4gdGhpc31mdW5jdGlvbiBvYyhpLHQsZSl7aS5wcm90b3R5cGU9dC5wcm90b3R5cGU9ZSxlLmNvbnN0cnVjdG9yPWl9ZnVuY3Rpb24gZnUoaSx0KXt2YXIgZT1PYmplY3QuY3JlYXRlKGkucHJvdG90eXBlKTtmb3IodmFyIG4gaW4gdCllW25dPXRbbl07cmV0dXJuIGV9ZnVuY3Rpb24gbnMoKXt9dmFyIGlzPS43LFZyPTEvaXMsZmk9IlxccyooWystXT9cXGQrKVxccyoiLHNzPSJcXHMqKFsrLV0/KD86XFxkKlxcLik/XFxkKyg/OltlRV1bKy1dP1xcZCspPylcXHMqIixBZT0iXFxzKihbKy1dPyg/OlxcZCpcXC4pP1xcZCsoPzpbZUVdWystXT9cXGQrKT8pJVxccyoiLF9tPS9eIyhbMC05YS1mXXszLDh9KSQvLHZtPW5ldyBSZWdFeHAoYF5yZ2JcXCgke2ZpfSwke2ZpfSwke2ZpfVxcKSRgKSx6bT1uZXcgUmVnRXhwKGBecmdiXFwoJHtBZX0sJHtBZX0sJHtBZX1cXCkkYCksVG09bmV3IFJlZ0V4cChgXnJnYmFcXCgke2ZpfSwke2ZpfSwke2ZpfSwke3NzfVxcKSRgKSxFbT1uZXcgUmVnRXhwKGBecmdiYVxcKCR7QWV9LCR7QWV9LCR7QWV9LCR7c3N9XFwpJGApLFBtPW5ldyBSZWdFeHAoYF5oc2xcXCgke3NzfSwke0FlfSwke0FlfVxcKSRgKSxDbT1uZXcgUmVnRXhwKGBeaHNsYVxcKCR7c3N9LCR7QWV9LCR7QWV9LCR7c3N9XFwpJGApLGR1PXthbGljZWJsdWU6MTU3OTIzODMsYW50aXF1ZXdoaXRlOjE2NDQ0Mzc1LGFxdWE6NjU1MzUsYXF1YW1hcmluZTo4Mzg4NTY0LGF6dXJlOjE1Nzk0MTc1LGJlaWdlOjE2MTE5MjYwLGJpc3F1ZToxNjc3MDI0NCxibGFjazowLGJsYW5jaGVkYWxtb25kOjE2NzcyMDQ1LGJsdWU6MjU1LGJsdWV2aW9sZXQ6OTA1NTIwMixicm93bjoxMDgyNDIzNCxidXJseXdvb2Q6MTQ1OTYyMzEsY2FkZXRibHVlOjYyNjY1MjgsY2hhcnRyZXVzZTo4Mzg4MzUyLGNob2NvbGF0ZToxMzc4OTQ3MCxjb3JhbDoxNjc0NDI3Mixjb3JuZmxvd2VyYmx1ZTo2NTkxOTgxLGNvcm5zaWxrOjE2Nzc1Mzg4LGNyaW1zb246MTQ0MjMxMDAsY3lhbjo2NTUzNSxkYXJrYmx1ZToxMzksZGFya2N5YW46MzU3MjMsZGFya2dvbGRlbnJvZDoxMjA5MjkzOSxkYXJrZ3JheToxMTExOTAxNyxkYXJrZ3JlZW46MjU2MDAsZGFya2dyZXk6MTExMTkwMTcsZGFya2toYWtpOjEyNDMzMjU5LGRhcmttYWdlbnRhOjkxMDk2NDMsZGFya29saXZlZ3JlZW46NTU5Nzk5OSxkYXJrb3JhbmdlOjE2NzQ3NTIwLGRhcmtvcmNoaWQ6MTAwNDAwMTIsZGFya3JlZDo5MTA5NTA0LGRhcmtzYWxtb246MTUzMDg0MTAsZGFya3NlYWdyZWVuOjk0MTk5MTksZGFya3NsYXRlYmx1ZTo0NzM0MzQ3LGRhcmtzbGF0ZWdyYXk6MzEwMDQ5NSxkYXJrc2xhdGVncmV5OjMxMDA0OTUsZGFya3R1cnF1b2lzZTo1Mjk0NSxkYXJrdmlvbGV0Ojk2OTk1MzksZGVlcHBpbms6MTY3MTY5NDcsZGVlcHNreWJsdWU6NDkxNTEsZGltZ3JheTo2OTA4MjY1LGRpbWdyZXk6NjkwODI2NSxkb2RnZXJibHVlOjIwMDMxOTksZmlyZWJyaWNrOjExNjc0MTQ2LGZsb3JhbHdoaXRlOjE2Nzc1OTIwLGZvcmVzdGdyZWVuOjIyNjM4NDIsZnVjaHNpYToxNjcxMTkzNSxnYWluc2Jvcm86MTQ0NzQ0NjAsZ2hvc3R3aGl0ZToxNjMxNjY3MSxnb2xkOjE2NzY2NzIwLGdvbGRlbnJvZDoxNDMyOTEyMCxncmF5Ojg0MjE1MDQsZ3JlZW46MzI3NjgsZ3JlZW55ZWxsb3c6MTE0MDMwNTUsZ3JleTo4NDIxNTA0LGhvbmV5ZGV3OjE1Nzk0MTYwLGhvdHBpbms6MTY3Mzg3NDAsaW5kaWFucmVkOjEzNDU4NTI0LGluZGlnbzo0OTE1MzMwLGl2b3J5OjE2Nzc3MjAwLGtoYWtpOjE1Nzg3NjYwLGxhdmVuZGVyOjE1MTMyNDEwLGxhdmVuZGVyYmx1c2g6MTY3NzMzNjUsbGF3bmdyZWVuOjgxOTA5NzYsbGVtb25jaGlmZm9uOjE2Nzc1ODg1LGxpZ2h0Ymx1ZToxMTM5MzI1NCxsaWdodGNvcmFsOjE1NzYxNTM2LGxpZ2h0Y3lhbjoxNDc0NTU5OSxsaWdodGdvbGRlbnJvZHllbGxvdzoxNjQ0ODIxMCxsaWdodGdyYXk6MTM4ODIzMjMsbGlnaHRncmVlbjo5NDk4MjU2LGxpZ2h0Z3JleToxMzg4MjMyMyxsaWdodHBpbms6MTY3NTg0NjUsbGlnaHRzYWxtb246MTY3NTI3NjIsbGlnaHRzZWFncmVlbjoyMTQyODkwLGxpZ2h0c2t5Ymx1ZTo4OTAwMzQ2LGxpZ2h0c2xhdGVncmF5Ojc4MzM3NTMsbGlnaHRzbGF0ZWdyZXk6NzgzMzc1MyxsaWdodHN0ZWVsYmx1ZToxMTU4NDczNCxsaWdodHllbGxvdzoxNjc3NzE4NCxsaW1lOjY1MjgwLGxpbWVncmVlbjozMzI5MzMwLGxpbmVuOjE2NDQ1NjcwLG1hZ2VudGE6MTY3MTE5MzUsbWFyb29uOjgzODg2MDgsbWVkaXVtYXF1YW1hcmluZTo2NzM3MzIyLG1lZGl1bWJsdWU6MjA1LG1lZGl1bW9yY2hpZDoxMjIxMTY2NyxtZWRpdW1wdXJwbGU6OTY2MjY4MyxtZWRpdW1zZWFncmVlbjozOTc4MDk3LG1lZGl1bXNsYXRlYmx1ZTo4MDg3NzkwLG1lZGl1bXNwcmluZ2dyZWVuOjY0MTU0LG1lZGl1bXR1cnF1b2lzZTo0NzcyMzAwLG1lZGl1bXZpb2xldHJlZDoxMzA0NzE3MyxtaWRuaWdodGJsdWU6MTY0NDkxMixtaW50Y3JlYW06MTYxMjE4NTAsbWlzdHlyb3NlOjE2NzcwMjczLG1vY2Nhc2luOjE2NzcwMjI5LG5hdmFqb3doaXRlOjE2NzY4Njg1LG5hdnk6MTI4LG9sZGxhY2U6MTY2NDM1NTgsb2xpdmU6ODQyMTM3NixvbGl2ZWRyYWI6NzA0ODczOSxvcmFuZ2U6MTY3NTM5MjAsb3JhbmdlcmVkOjE2NzI5MzQ0LG9yY2hpZDoxNDMxNTczNCxwYWxlZ29sZGVucm9kOjE1NjU3MTMwLHBhbGVncmVlbjoxMDAyNTg4MCxwYWxldHVycXVvaXNlOjExNTI5OTY2LHBhbGV2aW9sZXRyZWQ6MTQzODEyMDMscGFwYXlhd2hpcDoxNjc3MzA3NyxwZWFjaHB1ZmY6MTY3Njc2NzMscGVydToxMzQ2ODk5MSxwaW5rOjE2NzYxMDM1LHBsdW06MTQ1MjQ2MzcscG93ZGVyYmx1ZToxMTU5MTkxMCxwdXJwbGU6ODM4ODczNixyZWJlY2NhcHVycGxlOjY2OTc4ODEscmVkOjE2NzExNjgwLHJvc3licm93bjoxMjM1NzUxOSxyb3lhbGJsdWU6NDI4Njk0NSxzYWRkbGVicm93bjo5MTI3MTg3LHNhbG1vbjoxNjQxNjg4MixzYW5keWJyb3duOjE2MDMyODY0LHNlYWdyZWVuOjMwNTAzMjcsc2Vhc2hlbGw6MTY3NzQ2Mzgsc2llbm5hOjEwNTA2Nzk3LHNpbHZlcjoxMjYzMjI1Nixza3libHVlOjg5MDAzMzEsc2xhdGVibHVlOjY5NzAwNjEsc2xhdGVncmF5OjczNzI5NDQsc2xhdGVncmV5OjczNzI5NDQsc25vdzoxNjc3NTkzMCxzcHJpbmdncmVlbjo2NTQwNyxzdGVlbGJsdWU6NDYyMDk4MCx0YW46MTM4MDg3ODAsdGVhbDozMjg5Nix0aGlzdGxlOjE0MjA0ODg4LHRvbWF0bzoxNjczNzA5NSx0dXJxdW9pc2U6NDI1MTg1Nix2aW9sZXQ6MTU2MzEwODYsd2hlYXQ6MTYxMTMzMzEsd2hpdGU6MTY3NzcyMTUsd2hpdGVzbW9rZToxNjExOTI4NSx5ZWxsb3c6MTY3NzY5NjAseWVsbG93Z3JlZW46MTAxNDUwNzR9O29jKG5zLHJzLHtjb3B5KGkpe3JldHVybiBPYmplY3QuYXNzaWduKG5ldyB0aGlzLmNvbnN0cnVjdG9yLHRoaXMsaSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuIHRoaXMucmdiKCkuZGlzcGxheWFibGUoKX0saGV4OnB1LGZvcm1hdEhleDpwdSxmb3JtYXRIZXg4OkJtLGZvcm1hdEhzbDpGbSxmb3JtYXRSZ2I6eXUsdG9TdHJpbmc6eXV9KTtmdW5jdGlvbiBwdSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleCgpfWZ1bmN0aW9uIEJtKCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0SGV4OCgpfWZ1bmN0aW9uIEZtKCl7cmV0dXJuIGJ1KHRoaXMpLmZvcm1hdEhzbCgpfWZ1bmN0aW9uIHl1KCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0UmdiKCl9ZnVuY3Rpb24gcnMoaSl7dmFyIHQsZTtyZXR1cm4gaT0oaSsiIikudHJpbSgpLnRvTG93ZXJDYXNlKCksKHQ9X20uZXhlYyhpKSk/KGU9dFsxXS5sZW5ndGgsdD1wYXJzZUludCh0WzFdLDE2KSxlPT09Nj9tdSh0KTplPT09Mz9uZXcgT3QodD4+OCYxNXx0Pj40JjI0MCx0Pj40JjE1fHQmMjQwLCh0JjE1KTw8NHx0JjE1LDEpOmU9PT04P1VyKHQ+PjI0JjI1NSx0Pj4xNiYyNTUsdD4+OCYyNTUsKHQmMjU1KS8yNTUpOmU9PT00P1VyKHQ+PjEyJjE1fHQ+PjgmMjQwLHQ+PjgmMTV8dD4+NCYyNDAsdD4+NCYxNXx0JjI0MCwoKHQmMTUpPDw0fHQmMTUpLzI1NSk6bnVsbCk6KHQ9dm0uZXhlYyhpKSk/bmV3IE90KHRbMV0sdFsyXSx0WzNdLDEpOih0PXptLmV4ZWMoaSkpP25ldyBPdCh0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCwxKToodD1UbS5leGVjKGkpKT9Vcih0WzFdLHRbMl0sdFszXSx0WzRdKToodD1FbS5leGVjKGkpKT9Vcih0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCx0WzRdKToodD1QbS5leGVjKGkpKT93dSh0WzFdLHRbMl0vMTAwLHRbM10vMTAwLDEpOih0PUNtLmV4ZWMoaSkpP3d1KHRbMV0sdFsyXS8xMDAsdFszXS8xMDAsdFs0XSk6ZHUuaGFzT3duUHJvcGVydHkoaSk/bXUoZHVbaV0pOmk9PT0idHJhbnNwYXJlbnQiP25ldyBPdChOYU4sTmFOLE5hTiwwKTpudWxsfWZ1bmN0aW9uIG11KGkpe3JldHVybiBuZXcgT3QoaT4+MTYmMjU1LGk+PjgmMjU1LGkmMjU1LDEpfWZ1bmN0aW9uIFVyKGksdCxlLG4pe3JldHVybiBuPD0wJiYoaT10PWU9TmFOKSxuZXcgT3QoaSx0LGUsbil9ZnVuY3Rpb24gSW0oaSl7cmV0dXJuIGkgaW5zdGFuY2VvZiBuc3x8KGk9cnMoaSkpLGk/KGk9aS5yZ2IoKSxuZXcgT3QoaS5yLGkuZyxpLmIsaS5vcGFjaXR5KSk6bmV3IE90fWZ1bmN0aW9uIGFjKGksdCxlLG4pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT9JbShpKTpuZXcgT3QoaSx0LGUsbj09bnVsbD8xOm4pfWZ1bmN0aW9uIE90KGksdCxlLG4pe3RoaXMucj0raSx0aGlzLmc9K3QsdGhpcy5iPStlLHRoaXMub3BhY2l0eT0rbn1vYyhPdCxhYyxmdShucyx7YnJpZ2h0ZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9WcjpNYXRoLnBvdyhWcixpKSxuZXcgT3QodGhpcy5yKmksdGhpcy5nKmksdGhpcy5iKmksdGhpcy5vcGFjaXR5KX0sZGFya2VyKGkpe3JldHVybiBpPWk9PW51bGw/aXM6TWF0aC5wb3coaXMsaSksbmV3IE90KHRoaXMucippLHRoaXMuZyppLHRoaXMuYippLHRoaXMub3BhY2l0eSl9LHJnYigpe3JldHVybiB0aGlzfSxjbGFtcCgpe3JldHVybiBuZXcgT3QoVG4odGhpcy5yKSxUbih0aGlzLmcpLFRuKHRoaXMuYikscXIodGhpcy5vcGFjaXR5KSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuLS41PD10aGlzLnImJnRoaXMucjwyNTUuNSYmLS41PD10aGlzLmcmJnRoaXMuZzwyNTUuNSYmLS41PD10aGlzLmImJnRoaXMuYjwyNTUuNSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGhleDpndSxmb3JtYXRIZXg6Z3UsZm9ybWF0SGV4ODprbSxmb3JtYXRSZ2I6eHUsdG9TdHJpbmc6eHV9KSk7ZnVuY3Rpb24gZ3UoKXtyZXR1cm5gIyR7RW4odGhpcy5yKX0ke0VuKHRoaXMuZyl9JHtFbih0aGlzLmIpfWB9ZnVuY3Rpb24ga20oKXtyZXR1cm5gIyR7RW4odGhpcy5yKX0ke0VuKHRoaXMuZyl9JHtFbih0aGlzLmIpfSR7RW4oKGlzTmFOKHRoaXMub3BhY2l0eSk/MTp0aGlzLm9wYWNpdHkpKjI1NSl9YH1mdW5jdGlvbiB4dSgpe2NvbnN0IGk9cXIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8icmdiKCI6InJnYmEoIn0ke1RuKHRoaXMucil9LCAke1RuKHRoaXMuZyl9LCAke1RuKHRoaXMuYil9JHtpPT09MT8iKSI6YCwgJHtpfSlgfWB9ZnVuY3Rpb24gcXIoaSl7cmV0dXJuIGlzTmFOKGkpPzE6TWF0aC5tYXgoMCxNYXRoLm1pbigxLGkpKX1mdW5jdGlvbiBUbihpKXtyZXR1cm4gTWF0aC5tYXgoMCxNYXRoLm1pbigyNTUsTWF0aC5yb3VuZChpKXx8MCkpfWZ1bmN0aW9uIEVuKGkpe3JldHVybiBpPVRuKGkpLChpPDE2PyIwIjoiIikraS50b1N0cmluZygxNil9ZnVuY3Rpb24gd3UoaSx0LGUsbil7cmV0dXJuIG48PTA/aT10PWU9TmFOOmU8PTB8fGU+PTE/aT10PU5hTjp0PD0wJiYoaT1OYU4pLG5ldyB5ZShpLHQsZSxuKX1mdW5jdGlvbiBidShpKXtpZihpIGluc3RhbmNlb2YgeWUpcmV0dXJuIG5ldyB5ZShpLmgsaS5zLGkubCxpLm9wYWNpdHkpO2lmKGkgaW5zdGFuY2VvZiBuc3x8KGk9cnMoaSkpLCFpKXJldHVybiBuZXcgeWU7aWYoaSBpbnN0YW5jZW9mIHllKXJldHVybiBpO2k9aS5yZ2IoKTt2YXIgdD1pLnIvMjU1LGU9aS5nLzI1NSxuPWkuYi8yNTUscz1NYXRoLm1pbih0LGUsbikscj1NYXRoLm1heCh0LGUsbiksbz1OYU4sYT1yLXMsYz0ocitzKS8yO3JldHVybiBhPyh0PT09cj9vPShlLW4pL2ErKGU8bikqNjplPT09cj9vPShuLXQpL2ErMjpvPSh0LWUpL2ErNCxhLz1jPC41P3IrczoyLXItcyxvKj02MCk6YT1jPjAmJmM8MT8wOm8sbmV3IHllKG8sYSxjLGkub3BhY2l0eSl9ZnVuY3Rpb24gTm0oaSx0LGUsbil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg9PT0xP2J1KGkpOm5ldyB5ZShpLHQsZSxuPT1udWxsPzE6bil9ZnVuY3Rpb24geWUoaSx0LGUsbil7dGhpcy5oPStpLHRoaXMucz0rdCx0aGlzLmw9K2UsdGhpcy5vcGFjaXR5PStufW9jKHllLE5tLGZ1KG5zLHticmlnaHRlcihpKXtyZXR1cm4gaT1pPT1udWxsP1ZyOk1hdGgucG93KFZyLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LGRhcmtlcihpKXtyZXR1cm4gaT1pPT1udWxsP2lzOk1hdGgucG93KGlzLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LHJnYigpe3ZhciBpPXRoaXMuaCUzNjArKHRoaXMuaDwwKSozNjAsdD1pc05hTihpKXx8aXNOYU4odGhpcy5zKT8wOnRoaXMucyxlPXRoaXMubCxuPWUrKGU8LjU/ZToxLWUpKnQscz0yKmUtbjtyZXR1cm4gbmV3IE90KGNjKGk+PTI0MD9pLTI0MDppKzEyMCxzLG4pLGNjKGkscyxuKSxjYyhpPDEyMD9pKzI0MDppLTEyMCxzLG4pLHRoaXMub3BhY2l0eSl9LGNsYW1wKCl7cmV0dXJuIG5ldyB5ZShNdSh0aGlzLmgpLEhyKHRoaXMucyksSHIodGhpcy5sKSxxcih0aGlzLm9wYWNpdHkpKX0sZGlzcGxheWFibGUoKXtyZXR1cm4oMDw9dGhpcy5zJiZ0aGlzLnM8PTF8fGlzTmFOKHRoaXMucykpJiYwPD10aGlzLmwmJnRoaXMubDw9MSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGZvcm1hdEhzbCgpe2NvbnN0IGk9cXIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8iaHNsKCI6ImhzbGEoIn0ke011KHRoaXMuaCl9LCAke0hyKHRoaXMucykqMTAwfSUsICR7SHIodGhpcy5sKSoxMDB9JSR7aT09PTE/IikiOmAsICR7aX0pYH1gfX0pKTtmdW5jdGlvbiBNdShpKXtyZXR1cm4gaT0oaXx8MCklMzYwLGk8MD9pKzM2MDppfWZ1bmN0aW9uIEhyKGkpe3JldHVybiBNYXRoLm1heCgwLE1hdGgubWluKDEsaXx8MCkpfWZ1bmN0aW9uIGNjKGksdCxlKXtyZXR1cm4oaTw2MD90KyhlLXQpKmkvNjA6aTwxODA/ZTppPDI0MD90KyhlLXQpKigyNDAtaSkvNjA6dCkqMjU1fXZhciBsYz1pPT4oKT0+aTtmdW5jdGlvbiBSbShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gaStlKnR9fWZ1bmN0aW9uIExtKGksdCxlKXtyZXR1cm4gaT1NYXRoLnBvdyhpLGUpLHQ9TWF0aC5wb3codCxlKS1pLGU9MS9lLGZ1bmN0aW9uKG4pe3JldHVybiBNYXRoLnBvdyhpK24qdCxlKX19ZnVuY3Rpb24gT20oaSl7cmV0dXJuKGk9K2kpPT0xP0F1OmZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUtdD9MbSh0LGUsaSk6bGMoaXNOYU4odCk/ZTp0KX19ZnVuY3Rpb24gQXUoaSx0KXt2YXIgZT10LWk7cmV0dXJuIGU/Um0oaSxlKTpsYyhpc05hTihpKT90OmkpfXZhciBTdT1mdW5jdGlvbiBpKHQpe3ZhciBlPU9tKHQpO2Z1bmN0aW9uIG4ocyxyKXt2YXIgbz1lKChzPWFjKHMpKS5yLChyPWFjKHIpKS5yKSxhPWUocy5nLHIuZyksYz1lKHMuYixyLmIpLGw9QXUocy5vcGFjaXR5LHIub3BhY2l0eSk7cmV0dXJuIGZ1bmN0aW9uKGgpe3JldHVybiBzLnI9byhoKSxzLmc9YShoKSxzLmI9YyhoKSxzLm9wYWNpdHk9bChoKSxzKyIifX1yZXR1cm4gbi5nYW1tYT1pLG59KDEpO2Z1bmN0aW9uIERtKGksdCl7dHx8KHQ9W10pO3ZhciBlPWk/TWF0aC5taW4odC5sZW5ndGgsaS5sZW5ndGgpOjAsbj10LnNsaWNlKCkscztyZXR1cm4gZnVuY3Rpb24ocil7Zm9yKHM9MDtzPGU7KytzKW5bc109aVtzXSooMS1yKSt0W3NdKnI7cmV0dXJuIG59fWZ1bmN0aW9uICRtKGkpe3JldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoaSkmJiEoaSBpbnN0YW5jZW9mIERhdGFWaWV3KX1mdW5jdGlvbiBWbShpLHQpe3ZhciBlPXQ/dC5sZW5ndGg6MCxuPWk/TWF0aC5taW4oZSxpLmxlbmd0aCk6MCxzPW5ldyBBcnJheShuKSxyPW5ldyBBcnJheShlKSxvO2ZvcihvPTA7bzxuOysrbylzW29dPWZjKGlbb10sdFtvXSk7Zm9yKDtvPGU7KytvKXJbb109dFtvXTtyZXR1cm4gZnVuY3Rpb24oYSl7Zm9yKG89MDtvPG47KytvKXJbb109c1tvXShhKTtyZXR1cm4gcn19ZnVuY3Rpb24gVW0oaSx0KXt2YXIgZT1uZXcgRGF0ZTtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKG4pe3JldHVybiBlLnNldFRpbWUoaSooMS1uKSt0Km4pLGV9fWZ1bmN0aW9uIFdyKGksdCl7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihlKXtyZXR1cm4gaSooMS1lKSt0KmV9fWZ1bmN0aW9uIHFtKGksdCl7dmFyIGU9e30sbj17fSxzOyhpPT09bnVsbHx8dHlwZW9mIGkhPSJvYmplY3QiKSYmKGk9e30pLCh0PT09bnVsbHx8dHlwZW9mIHQhPSJvYmplY3QiKSYmKHQ9e30pO2ZvcihzIGluIHQpcyBpbiBpP2Vbc109ZmMoaVtzXSx0W3NdKTpuW3NdPXRbc107cmV0dXJuIGZ1bmN0aW9uKHIpe2ZvcihzIGluIGUpbltzXT1lW3NdKHIpO3JldHVybiBufX12YXIgaGM9L1stK10/KD86XGQrXC4/XGQqfFwuP1xkKykoPzpbZUVdWy0rXT9cZCspPy9nLHVjPW5ldyBSZWdFeHAoaGMuc291cmNlLCJnIik7ZnVuY3Rpb24gSG0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIFdtKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gaSh0KSsiIn19ZnVuY3Rpb24gR20oaSx0KXt2YXIgZT1oYy5sYXN0SW5kZXg9dWMubGFzdEluZGV4PTAsbixzLHIsbz0tMSxhPVtdLGM9W107Zm9yKGk9aSsiIix0PXQrIiI7KG49aGMuZXhlYyhpKSkmJihzPXVjLmV4ZWModCkpOykocj1zLmluZGV4KT5lJiYocj10LnNsaWNlKGUsciksYVtvXT9hW29dKz1yOmFbKytvXT1yKSwobj1uWzBdKT09PShzPXNbMF0pP2Fbb10/YVtvXSs9czphWysrb109czooYVsrK29dPW51bGwsYy5wdXNoKHtpOm8seDpXcihuLHMpfSkpLGU9dWMubGFzdEluZGV4O3JldHVybiBlPHQubGVuZ3RoJiYocj10LnNsaWNlKGUpLGFbb10/YVtvXSs9cjphWysrb109ciksYS5sZW5ndGg8Mj9jWzBdP1dtKGNbMF0ueCk6SG0odCk6KHQ9Yy5sZW5ndGgsZnVuY3Rpb24obCl7Zm9yKHZhciBoPTAsdTtoPHQ7KytoKWFbKHU9Y1toXSkuaV09dS54KGwpO3JldHVybiBhLmpvaW4oIiIpfSl9ZnVuY3Rpb24gZmMoaSx0KXt2YXIgZT10eXBlb2YgdCxuO3JldHVybiB0PT1udWxsfHxlPT09ImJvb2xlYW4iP2xjKHQpOihlPT09Im51bWJlciI/V3I6ZT09PSJzdHJpbmciPyhuPXJzKHQpKT8odD1uLFN1KTpHbTp0IGluc3RhbmNlb2YgcnM/U3U6dCBpbnN0YW5jZW9mIERhdGU/VW06JG0odCk/RG06QXJyYXkuaXNBcnJheSh0KT9WbTp0eXBlb2YgdC52YWx1ZU9mIT0iZnVuY3Rpb24iJiZ0eXBlb2YgdC50b1N0cmluZyE9ImZ1bmN0aW9uInx8aXNOYU4odCk/cW06V3IpKGksdCl9ZnVuY3Rpb24gWm0oaSx0KXtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKGUpe3JldHVybiBNYXRoLnJvdW5kKGkqKDEtZSkrdCplKX19ZnVuY3Rpb24gWG0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIEptKGkpe3JldHVybitpfXZhciBfdT1bMCwxXTtmdW5jdGlvbiBkaShpKXtyZXR1cm4gaX1mdW5jdGlvbiBkYyhpLHQpe3JldHVybih0LT1pPStpKT9mdW5jdGlvbihlKXtyZXR1cm4oZS1pKS90fTpYbShpc05hTih0KT9OYU46LjUpfWZ1bmN0aW9uIFltKGksdCl7dmFyIGU7cmV0dXJuIGk+dCYmKGU9aSxpPXQsdD1lKSxmdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5tYXgoaSxNYXRoLm1pbih0LG4pKX19ZnVuY3Rpb24gam0oaSx0LGUpe3ZhciBuPWlbMF0scz1pWzFdLHI9dFswXSxvPXRbMV07cmV0dXJuIHM8bj8obj1kYyhzLG4pLHI9ZShvLHIpKToobj1kYyhuLHMpLHI9ZShyLG8pKSxmdW5jdGlvbihhKXtyZXR1cm4gcihuKGEpKX19ZnVuY3Rpb24gUW0oaSx0LGUpe3ZhciBuPU1hdGgubWluKGkubGVuZ3RoLHQubGVuZ3RoKS0xLHM9bmV3IEFycmF5KG4pLHI9bmV3IEFycmF5KG4pLG89LTE7Zm9yKGlbbl08aVswXSYmKGk9aS5zbGljZSgpLnJldmVyc2UoKSx0PXQuc2xpY2UoKS5yZXZlcnNlKCkpOysrbzxuOylzW29dPWRjKGlbb10saVtvKzFdKSxyW29dPWUodFtvXSx0W28rMV0pO3JldHVybiBmdW5jdGlvbihhKXt2YXIgYz10cChpLGEsMSxuKS0xO3JldHVybiByW2NdKHNbY10oYSkpfX1mdW5jdGlvbiBLbShpLHQpe3JldHVybiB0LmRvbWFpbihpLmRvbWFpbigpKS5yYW5nZShpLnJhbmdlKCkpLmludGVycG9sYXRlKGkuaW50ZXJwb2xhdGUoKSkuY2xhbXAoaS5jbGFtcCgpKS51bmtub3duKGkudW5rbm93bigpKX1mdW5jdGlvbiB0Zygpe3ZhciBpPV91LHQ9X3UsZT1mYyxuLHMscixvPWRpLGEsYyxsO2Z1bmN0aW9uIGgoKXt2YXIgZj1NYXRoLm1pbihpLmxlbmd0aCx0Lmxlbmd0aCk7cmV0dXJuIG8hPT1kaSYmKG89WW0oaVswXSxpW2YtMV0pKSxhPWY+Mj9RbTpqbSxjPWw9bnVsbCx1fWZ1bmN0aW9uIHUoZil7cmV0dXJuIGY9PW51bGx8fGlzTmFOKGY9K2YpP3I6KGN8fChjPWEoaS5tYXAobiksdCxlKSkpKG4obyhmKSkpfXJldHVybiB1LmludmVydD1mdW5jdGlvbihmKXtyZXR1cm4gbyhzKChsfHwobD1hKHQsaS5tYXAobiksV3IpKSkoZikpKX0sdS5kb21haW49ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGk9QXJyYXkuZnJvbShmLEptKSxoKCkpOmkuc2xpY2UoKX0sdS5yYW5nZT1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odD1BcnJheS5mcm9tKGYpLGgoKSk6dC5zbGljZSgpfSx1LnJhbmdlUm91bmQ9ZnVuY3Rpb24oZil7cmV0dXJuIHQ9QXJyYXkuZnJvbShmKSxlPVptLGgoKX0sdS5jbGFtcD1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obz1mPyEwOmRpLGgoKSk6byE9PWRpfSx1LmludGVycG9sYXRlPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhlPWYsaCgpKTplfSx1LnVua25vd249ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHI9Zix1KTpyfSxmdW5jdGlvbihmLGQpe3JldHVybiBuPWYscz1kLGgoKX19ZnVuY3Rpb24gZWcoKXtyZXR1cm4gdGcoKShkaSxkaSl9ZnVuY3Rpb24gbmcoaSl7cmV0dXJuIE1hdGguYWJzKGk9TWF0aC5yb3VuZChpKSk+PTFlMjE/aS50b0xvY2FsZVN0cmluZygiZW4iKS5yZXBsYWNlKC8sL2csIiIpOmkudG9TdHJpbmcoMTApfWZ1bmN0aW9uIEdyKGksdCl7aWYoKGU9KGk9dD9pLnRvRXhwb25lbnRpYWwodC0xKTppLnRvRXhwb25lbnRpYWwoKSkuaW5kZXhPZigiZSIpKTwwKXJldHVybiBudWxsO3ZhciBlLG49aS5zbGljZSgwLGUpO3JldHVybltuLmxlbmd0aD4xP25bMF0rbi5zbGljZSgyKTpuLCtpLnNsaWNlKGUrMSldfWZ1bmN0aW9uIHBpKGkpe3JldHVybiBpPUdyKE1hdGguYWJzKGkpKSxpP2lbMV06TmFOfWZ1bmN0aW9uIGlnKGksdCl7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Zm9yKHZhciBzPWUubGVuZ3RoLHI9W10sbz0wLGE9aVswXSxjPTA7cz4wJiZhPjAmJihjK2ErMT5uJiYoYT1NYXRoLm1heCgxLG4tYykpLHIucHVzaChlLnN1YnN0cmluZyhzLT1hLHMrYSkpLCEoKGMrPWErMSk+bikpOylhPWlbbz0obysxKSVpLmxlbmd0aF07cmV0dXJuIHIucmV2ZXJzZSgpLmpvaW4odCl9fWZ1bmN0aW9uIHNnKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdC5yZXBsYWNlKC9bMC05XS9nLGZ1bmN0aW9uKGUpe3JldHVybiBpWytlXX0pfX12YXIgcmc9L14oPzooLik/KFs8Pj1eXSkpPyhbK1wtKCBdKT8oWyQjXSk/KDApPyhcZCspPygsKT8oXC5cZCspPyh+KT8oW2EteiVdKT8kL2k7ZnVuY3Rpb24gWnIoaSl7aWYoISh0PXJnLmV4ZWMoaSkpKXRocm93IG5ldyBFcnJvcigiaW52YWxpZCBmb3JtYXQ6ICIraSk7dmFyIHQ7cmV0dXJuIG5ldyBwYyh7ZmlsbDp0WzFdLGFsaWduOnRbMl0sc2lnbjp0WzNdLHN5bWJvbDp0WzRdLHplcm86dFs1XSx3aWR0aDp0WzZdLGNvbW1hOnRbN10scHJlY2lzaW9uOnRbOF0mJnRbOF0uc2xpY2UoMSksdHJpbTp0WzldLHR5cGU6dFsxMF19KX1aci5wcm90b3R5cGU9cGMucHJvdG90eXBlO2Z1bmN0aW9uIHBjKGkpe3RoaXMuZmlsbD1pLmZpbGw9PT12b2lkIDA/IiAiOmkuZmlsbCsiIix0aGlzLmFsaWduPWkuYWxpZ249PT12b2lkIDA/Ij4iOmkuYWxpZ24rIiIsdGhpcy5zaWduPWkuc2lnbj09PXZvaWQgMD8iLSI6aS5zaWduKyIiLHRoaXMuc3ltYm9sPWkuc3ltYm9sPT09dm9pZCAwPyIiOmkuc3ltYm9sKyIiLHRoaXMuemVybz0hIWkuemVybyx0aGlzLndpZHRoPWkud2lkdGg9PT12b2lkIDA/dm9pZCAwOitpLndpZHRoLHRoaXMuY29tbWE9ISFpLmNvbW1hLHRoaXMucHJlY2lzaW9uPWkucHJlY2lzaW9uPT09dm9pZCAwP3ZvaWQgMDoraS5wcmVjaXNpb24sdGhpcy50cmltPSEhaS50cmltLHRoaXMudHlwZT1pLnR5cGU9PT12b2lkIDA/IiI6aS50eXBlKyIifXBjLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmZpbGwrdGhpcy5hbGlnbit0aGlzLnNpZ24rdGhpcy5zeW1ib2wrKHRoaXMuemVybz8iMCI6IiIpKyh0aGlzLndpZHRoPT09dm9pZCAwPyIiOk1hdGgubWF4KDEsdGhpcy53aWR0aHwwKSkrKHRoaXMuY29tbWE/IiwiOiIiKSsodGhpcy5wcmVjaXNpb249PT12b2lkIDA/IiI6Ii4iK01hdGgubWF4KDAsdGhpcy5wcmVjaXNpb258MCkpKyh0aGlzLnRyaW0/In4iOiIiKSt0aGlzLnR5cGV9O2Z1bmN0aW9uIG9nKGkpe3Q6Zm9yKHZhciB0PWkubGVuZ3RoLGU9MSxuPS0xLHM7ZTx0OysrZSlzd2l0Y2goaVtlXSl7Y2FzZSIuIjpuPXM9ZTticmVhaztjYXNlIjAiOm49PT0wJiYobj1lKSxzPWU7YnJlYWs7ZGVmYXVsdDppZighK2lbZV0pYnJlYWsgdDtuPjAmJihuPTApO2JyZWFrfXJldHVybiBuPjA/aS5zbGljZSgwLG4pK2kuc2xpY2UocysxKTppfXZhciB2dTtmdW5jdGlvbiBhZyhpLHQpe3ZhciBlPUdyKGksdCk7aWYoIWUpcmV0dXJuIGkrIiI7dmFyIG49ZVswXSxzPWVbMV0scj1zLSh2dT1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3Iocy8zKSkpKjMpKzEsbz1uLmxlbmd0aDtyZXR1cm4gcj09PW8/bjpyPm8/bituZXcgQXJyYXkoci1vKzEpLmpvaW4oIjAiKTpyPjA/bi5zbGljZSgwLHIpKyIuIituLnNsaWNlKHIpOiIwLiIrbmV3IEFycmF5KDEtcikuam9pbigiMCIpK0dyKGksTWF0aC5tYXgoMCx0K3ItMSkpWzBdfWZ1bmN0aW9uIHp1KGksdCl7dmFyIGU9R3IoaSx0KTtpZighZSlyZXR1cm4gaSsiIjt2YXIgbj1lWzBdLHM9ZVsxXTtyZXR1cm4gczwwPyIwLiIrbmV3IEFycmF5KC1zKS5qb2luKCIwIikrbjpuLmxlbmd0aD5zKzE/bi5zbGljZSgwLHMrMSkrIi4iK24uc2xpY2UocysxKTpuK25ldyBBcnJheShzLW4ubGVuZ3RoKzIpLmpvaW4oIjAiKX12YXIgVHU9eyIlIjooaSx0KT0+KGkqMTAwKS50b0ZpeGVkKHQpLGI6aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZygyKSxjOmk9PmkrIiIsZDpuZyxlOihpLHQpPT5pLnRvRXhwb25lbnRpYWwodCksZjooaSx0KT0+aS50b0ZpeGVkKHQpLGc6KGksdCk9PmkudG9QcmVjaXNpb24odCksbzppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDgpLHA6KGksdCk9Pnp1KGkqMTAwLHQpLHI6enUsczphZyxYOmk9Pk1hdGgucm91bmQoaSkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkseDppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDE2KX07ZnVuY3Rpb24gRXUoaSl7cmV0dXJuIGl9dmFyIFB1PUFycmF5LnByb3RvdHlwZS5tYXAsQ3U9WyJ5IiwieiIsImEiLCJmIiwicCIsIm4iLCLCtSIsIm0iLCIiLCJrIiwiTSIsIkciLCJUIiwiUCIsIkUiLCJaIiwiWSJdO2Z1bmN0aW9uIGNnKGkpe3ZhciB0PWkuZ3JvdXBpbmc9PT12b2lkIDB8fGkudGhvdXNhbmRzPT09dm9pZCAwP0V1OmlnKFB1LmNhbGwoaS5ncm91cGluZyxOdW1iZXIpLGkudGhvdXNhbmRzKyIiKSxlPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVswXSsiIixuPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVsxXSsiIixzPWkuZGVjaW1hbD09PXZvaWQgMD8iLiI6aS5kZWNpbWFsKyIiLHI9aS5udW1lcmFscz09PXZvaWQgMD9FdTpzZyhQdS5jYWxsKGkubnVtZXJhbHMsU3RyaW5nKSksbz1pLnBlcmNlbnQ9PT12b2lkIDA/IiUiOmkucGVyY2VudCsiIixhPWkubWludXM9PT12b2lkIDA/IuKIkiI6aS5taW51cysiIixjPWkubmFuPT09dm9pZCAwPyJOYU4iOmkubmFuKyIiO2Z1bmN0aW9uIGwodSl7dT1acih1KTt2YXIgZj11LmZpbGwsZD11LmFsaWduLHA9dS5zaWduLHk9dS5zeW1ib2wsbT11Lnplcm8sZz11LndpZHRoLGI9dS5jb21tYSx3PXUucHJlY2lzaW9uLHg9dS50cmltLE09dS50eXBlO009PT0ibiI/KGI9ITAsTT0iZyIpOlR1W01dfHwodz09PXZvaWQgMCYmKHc9MTIpLHg9ITAsTT0iZyIpLChtfHxmPT09IjAiJiZkPT09Ij0iKSYmKG09ITAsZj0iMCIsZD0iPSIpO3ZhciBBPXk9PT0iJCI/ZTp5PT09IiMiJiYvW2JveFhdLy50ZXN0KE0pPyIwIitNLnRvTG93ZXJDYXNlKCk6IiIsUz15PT09IiQiP246L1slcF0vLnRlc3QoTSk/bzoiIixfPVR1W01dLEU9L1tkZWZncHJzJV0vLnRlc3QoTSk7dz13PT09dm9pZCAwPzY6L1tncHJzXS8udGVzdChNKT9NYXRoLm1heCgxLE1hdGgubWluKDIxLHcpKTpNYXRoLm1heCgwLE1hdGgubWluKDIwLHcpKTtmdW5jdGlvbiB6KHYpe3ZhciBDPUEsUD1TLEYsQixJO2lmKE09PT0iYyIpUD1fKHYpK1Asdj0iIjtlbHNle3Y9K3Y7dmFyIGs9djwwfHwxL3Y8MDtpZih2PWlzTmFOKHYpP2M6XyhNYXRoLmFicyh2KSx3KSx4JiYodj1vZyh2KSksayYmK3Y9PTAmJnAhPT0iKyImJihrPSExKSxDPShrP3A9PT0iKCI/cDphOnA9PT0iLSJ8fHA9PT0iKCI/IiI6cCkrQyxQPShNPT09InMiP0N1WzgrdnUvM106IiIpK1ArKGsmJnA9PT0iKCI/IikiOiIiKSxFKXtmb3IoRj0tMSxCPXYubGVuZ3RoOysrRjxCOylpZihJPXYuY2hhckNvZGVBdChGKSw0OD5JfHxJPjU3KXtQPShJPT09NDY/cyt2LnNsaWNlKEYrMSk6di5zbGljZShGKSkrUCx2PXYuc2xpY2UoMCxGKTticmVha319fWImJiFtJiYodj10KHYsMS8wKSk7dmFyIEQ9Qy5sZW5ndGgrdi5sZW5ndGgrUC5sZW5ndGgsVT1EPGc/bmV3IEFycmF5KGctRCsxKS5qb2luKGYpOiIiO3N3aXRjaChiJiZtJiYodj10KFUrdixVLmxlbmd0aD9nLVAubGVuZ3RoOjEvMCksVT0iIiksZCl7Y2FzZSI8Ijp2PUMrditQK1U7YnJlYWs7Y2FzZSI9Ijp2PUMrVSt2K1A7YnJlYWs7Y2FzZSJeIjp2PVUuc2xpY2UoMCxEPVUubGVuZ3RoPj4xKStDK3YrUCtVLnNsaWNlKEQpO2JyZWFrO2RlZmF1bHQ6dj1VK0MrditQO2JyZWFrfXJldHVybiByKHYpfXJldHVybiB6LnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHUrIiJ9LHp9ZnVuY3Rpb24gaCh1LGYpe3ZhciBkPWwoKHU9WnIodSksdS50eXBlPSJmIix1KSkscD1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3IocGkoZikvMykpKSozLHk9TWF0aC5wb3coMTAsLXApLG09Q3VbOCtwLzNdO3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZCh5KmcpK219fXJldHVybntmb3JtYXQ6bCxmb3JtYXRQcmVmaXg6aH19dmFyIFhyLEJ1LEZ1O2xnKHt0aG91c2FuZHM6IiwiLGdyb3VwaW5nOlszXSxjdXJyZW5jeTpbIiQiLCIiXX0pO2Z1bmN0aW9uIGxnKGkpe3JldHVybiBYcj1jZyhpKSxCdT1Yci5mb3JtYXQsRnU9WHIuZm9ybWF0UHJlZml4LFhyfWZ1bmN0aW9uIGhnKGkpe3JldHVybiBNYXRoLm1heCgwLC1waShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIHVnKGksdCl7cmV0dXJuIE1hdGgubWF4KDAsTWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKHBpKHQpLzMpKSkqMy1waShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIGZnKGksdCl7cmV0dXJuIGk9TWF0aC5hYnMoaSksdD1NYXRoLmFicyh0KS1pLE1hdGgubWF4KDAscGkodCktcGkoaSkpKzF9ZnVuY3Rpb24gZGcoaSx0LGUsbil7dmFyIHM9cnAoaSx0LGUpLHI7c3dpdGNoKG49WnIobj09bnVsbD8iLGYiOm4pLG4udHlwZSl7Y2FzZSJzIjp7dmFyIG89TWF0aC5tYXgoTWF0aC5hYnMoaSksTWF0aC5hYnModCkpO3JldHVybiBuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9dWcocyxvKSkmJihuLnByZWNpc2lvbj1yKSxGdShuLG8pfWNhc2UiIjpjYXNlImUiOmNhc2UiZyI6Y2FzZSJwIjpjYXNlInIiOntuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9ZmcocyxNYXRoLm1heChNYXRoLmFicyhpKSxNYXRoLmFicyh0KSkpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSJlIikpO2JyZWFrfWNhc2UiZiI6Y2FzZSIlIjp7bi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPWhnKHMpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSIlIikqMik7YnJlYWt9fXJldHVybiBCdShuKX1mdW5jdGlvbiBwZyhpKXt2YXIgdD1pLmRvbWFpbjtyZXR1cm4gaS50aWNrcz1mdW5jdGlvbihlKXt2YXIgbj10KCk7cmV0dXJuIHNwKG5bMF0sbltuLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUpfSxpLnRpY2tGb3JtYXQ9ZnVuY3Rpb24oZSxuKXt2YXIgcz10KCk7cmV0dXJuIGRnKHNbMF0sc1tzLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUsbil9LGkubmljZT1mdW5jdGlvbihlKXtlPT1udWxsJiYoZT0xMCk7dmFyIG49dCgpLHM9MCxyPW4ubGVuZ3RoLTEsbz1uW3NdLGE9bltyXSxjLGwsaD0xMDtmb3IoYTxvJiYobD1vLG89YSxhPWwsbD1zLHM9cixyPWwpO2gtLSA+MDspe2lmKGw9QWEobyxhLGUpLGw9PT1jKXJldHVybiBuW3NdPW8sbltyXT1hLHQobik7aWYobD4wKW89TWF0aC5mbG9vcihvL2wpKmwsYT1NYXRoLmNlaWwoYS9sKSpsO2Vsc2UgaWYobDwwKW89TWF0aC5jZWlsKG8qbCkvbCxhPU1hdGguZmxvb3IoYSpsKS9sO2Vsc2UgYnJlYWs7Yz1sfXJldHVybiBpfSxpfWZ1bmN0aW9uIHljKCl7dmFyIGk9ZWcoKTtyZXR1cm4gaS5jb3B5PWZ1bmN0aW9uKCl7cmV0dXJuIEttKGkseWMoKSl9LFNtLmFwcGx5KGksYXJndW1lbnRzKSxwZyhpKX1mdW5jdGlvbiB5ZyhpLHQpe3JldHVybiBpLm1hcChlPT57Y29uc3Qgbj1bXTtsZXQgcztyZXR1cm4gZS5mb3JFYWNoKHI9PntpZihzKXtjb25zdCBvPXJpKHIscykqMTgwL01hdGguUEk7aWYobz50KXtjb25zdCBhPVZwKHMsciksYz0xL01hdGguY2VpbChvL3QpO2xldCBsPWM7Zm9yKDtsPDE7KW4ucHVzaChhKGwpKSxsKz1jfX1uLnB1c2gocz1yKX0pLG59KX1mdW5jdGlvbiBtZyhpLHttaW5Mbmc6dCxtYXhMbmc6ZSxtaW5MYXQ6bixtYXhMYXQ6c309e30pe2NvbnN0IHI9TWF0aC5yb3VuZCh5aSgzNjAvaSwyKS9NYXRoLlBJKSxvPSgxK01hdGguc3FydCg1KSkvMixhPWQ9PmQvbyozNjAlMzYwLTE4MCxjPWQ9Pk1hdGguYWNvcygyKmQvci0xKS9NYXRoLlBJKjE4MC05MCxsPWQ9PnIqKE1hdGguY29zKChkKzkwKSpNYXRoLlBJLzE4MCkrMSkvMixoPVtzIT09dm9pZCAwP01hdGguY2VpbChsKHMpKTowLG4hPT12b2lkIDA/TWF0aC5mbG9vcihsKG4pKTpyLTFdLHU9dD09PXZvaWQgMCYmZT09PXZvaWQgMD8oKT0+ITA6dD09PXZvaWQgMD9kPT5kPD1lOmU9PT12b2lkIDA/ZD0+ZD49dDplPj10P2Q9PmQ+PXQmJmQ8PWU6ZD0+ZD49dHx8ZDw9ZSxmPVtdO2ZvcihsZXQgZD1oWzBdO2Q8PWhbMV07ZCsrKXtjb25zdCBwPWEoZCk7dShwKSYmZi5wdXNoKFtwLGMoZCldKX1yZXR1cm4gZn1mdW5jdGlvbiBtYyhpLHQsZT0hMSl7cmV0dXJuIGU/JHAodCxpKTpqeShpLHQpfWZ1bmN0aW9uIGdnKGksdCl7Y29uc3QgZT17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tuLHNdLFtyLG9dXT1maChlKTtpZihNYXRoLm1pbihNYXRoLmFicyhyLW4pLE1hdGguYWJzKG8tcykpPHQpcmV0dXJuW107Y29uc3QgYT1uPnJ8fG8+PTg5fHxzPD0tODk7cmV0dXJuIG1nKHQse21pbkxuZzpuLG1heExuZzpyLG1pbkxhdDpzLG1heExhdDpvfSkuZmlsdGVyKGM9Pm1jKGMsZSxhKSl9ZnVuY3Rpb24geGcoaSx7cmVzb2x1dGlvbjp0PTEvMCxiYm94OmUscHJvamVjdGlvbjpufT17fSl7Y29uc3Qgcz15ZyhpLHQpLHI9Vmkocyksbz1nZyhpLHQpLGE9Wy4uLnIsLi4ub10sYz17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tsLGhdLFt1LGZdXT1maChjKSxkPWw+dXx8Zj49ODl8fGg8PS04OTtsZXQgcD1bXTtpZihkKXtjb25zdCBNPUFtKGEpLnRyaWFuZ2xlcygpLEE9bmV3IE1hcChhLm1hcCgoW1MsX10sRSk9PltgJHtTfS0ke199YCxFXSkpO00uZmVhdHVyZXMuZm9yRWFjaChTPT57Y29uc3QgXz1TLmdlb21ldHJ5LmNvb3JkaW5hdGVzWzBdLnNsaWNlKDAsMykucmV2ZXJzZSgpLEU9W107aWYoXy5mb3JFYWNoKChbeix2XSk9Pntjb25zdCBDPWAke3p9LSR7dn1gO0EuaGFzKEMpJiZFLnB1c2goQS5nZXQoQykpfSksRS5sZW5ndGg9PT0zKXtpZihFLnNvbWUoej0+ejxyLmxlbmd0aCkpe2NvbnN0IHo9Uy5wcm9wZXJ0aWVzLmNpcmN1bWNlbnRlcjtpZighbWMoeixjLGQpKXJldHVybn1wLnB1c2goLi4uRSl9fSl9ZWxzZSBpZihvLmxlbmd0aCl7Y29uc3QgTT10cy5mcm9tKGEpO2ZvcihsZXQgQT0wLFM9TS50cmlhbmdsZXMubGVuZ3RoO0E8UztBKz0zKXtjb25zdCBfPVsyLDEsMF0ubWFwKHo9Pk0udHJpYW5nbGVzW0Erel0pLEU9Xy5tYXAoej0+YVt6XSk7aWYoXy5zb21lKHo9Pno8ci5sZW5ndGgpKXtjb25zdCB6PVswLDFdLm1hcCh2PT5vcChFLEM9PkNbdl0pKTtpZighbWMoeixjLGQpKWNvbnRpbnVlfXAucHVzaCguLi5fKX19ZWxzZXtjb25zdHt2ZXJ0aWNlczpNLGhvbGVzOkE9W119PVFoKHMpO3A9cHkoTSxBLDIpfWxldCB5PWU/W2VbMF0sZVsyXV06c3IoYSxNPT5NWzBdKSxtPWU/W2VbMV0sZVszXV06c3IoYSxNPT5NWzFdKTtpZihuKXtjb25zdFtNLEFdPW4oW3lbMF0sbVswXV0pLFtTLF9dPW4oW3lbMV0sbVsxXV0pO3k9W00sU10sbT1bLUEsLV9dfWNvbnN0IGc9eWMoeSxbMCwxXSksYj15YyhtLFswLDFdKSx3PWEubWFwKChbTSxBXSk9PntpZihuKXtjb25zdFtTLF9dPW4oW00sQV0pO3JldHVybltnKFMpLGIoLV8pXX1lbHNlIHJldHVybltnKE0pLGIoQSldfSk7cmV0dXJue2NvbnRvdXI6cyx0cmlhbmdsZXM6e3BvaW50czphLGluZGljZXM6cCx1dnM6d319fWNvbnN0IEl1PW5ldyB1ZSgpLnNldEF0dHJpYnV0ZT8ic2V0QXR0cmlidXRlIjoiYWRkQXR0cmlidXRlIjtmdW5jdGlvbiBKcihpLHQsZSxuKXtjb25zdCBzPWkubWFwKHI9PnIubWFwKChbbyxhXSk9PntpZihuKXtjb25zdFtjLGxdPW4oW28sYV0pO3JldHVybltjLC1sLHRdfXJldHVybiBlP1kwKG8sYSx0KTpbbyxhLHRdfSkpO3JldHVybiBRaChzKX1mdW5jdGlvbiB3ZyhpLHQsZSxuLHMpe2NvbnN0e3ZlcnRpY2VzOnIsaG9sZXM6b309SnIoaSx0LG4scykse3ZlcnRpY2VzOmF9PUpyKGksZSxuLHMpLGM9VmkoW2Escl0pLGw9TWF0aC5yb3VuZChhLmxlbmd0aC8zKSxoPW5ldyBTZXQobyk7bGV0IHU9MDtjb25zdCBmPVtdO2ZvcihsZXQgcD0wO3A8bDtwKyspe2xldCB5PXArMTtpZih5PT09bCl5PXU7ZWxzZSBpZihoLmhhcyh5KSl7Y29uc3QgbT15O3k9dSx1PW19Zi5wdXNoKHAscCtsLHkrbCksZi5wdXNoKHkrbCx5LHApfWNvbnN0IGQ9W107Zm9yKGxldCBwPTE7cD49MDtwLS0pZm9yKGxldCB5PTA7eTxsO3krPTEpZC5wdXNoKHkvKGwtMSkscCk7cmV0dXJue2luZGljZXM6Zix2ZXJ0aWNlczpjLHV2czpkLHRvcFZlcnRzOmF9fWZ1bmN0aW9uIGt1KGksdCxlLG4scyxyKXtyZXR1cm57aW5kaWNlczpuP2kuaW5kaWNlczppLmluZGljZXMuc2xpY2UoKS5yZXZlcnNlKCksdmVydGljZXM6SnIoW2kucG9pbnRzXSx0LHMscikudmVydGljZXMsdXZzOmV9fWNvbnN0IE51PSh7cG9seWdvbkdlb0pzb246aSxzdGFydEhlaWdodDp0LGVuZEhlaWdodDplLGN1cnZhdHVyZVJlc29sdXRpb246bj0xLGNhcnRlc2lhbjpzPSEwLGhhc1NpZGU6cj0hMCxoYXNCb3R0b206bz0hMSxoYXNUb3A6YT0hMSxwcm9qZWN0aW9uOmMsYmJveDpsfSk9PntpLmZvckVhY2goZz0+e055KGcpfHxnLnJldmVyc2UoKX0pO2NvbnN0e2NvbnRvdXI6aCx0cmlhbmdsZXM6dX09eGcoaSx7cmVzb2x1dGlvbjpuLGJib3g6bCxwcm9qZWN0aW9uOmN9KTtsZXQgZj17fSxkO3ImJihmPXdnKGgsdCE9bnVsbD90OmUsZSE9bnVsbD9lOnQscyxjKSxkPWYudG9wVmVydHMpO2xldCBwPVtdOyhvfHxhKSYmKHA9VmkodS51dnMpKTtsZXQgeT17fTtvJiYoeT1rdSh1LHQscCwhMSxzLGMpKTtsZXQgbT17fTtyZXR1cm4gYSYmKG09a3UodSxlLHAsITAscyxjKSkse2NvbnRvdXI6aCx0cmlhbmdsZXM6dSxzaWRlVG9yc286Zixib3R0b21DYXA6eSx0b3BDYXA6bSx0b3BWZXJ0czpkfX07Y2xhc3MgYmcgZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0LGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJQb2x5Z29uQnVmZmVyR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz1GdCh7cG9seWdvbkdlb0pzb246dCxzdGFydEhlaWdodDowLGVuZEhlaWdodDoxLGhhc1RvcDohMCx0b3BGaXJzdDohMSxoYXNCb3R0b206ITAsaGFzU2lkZTohMCxjdXJ2YXR1cmVSZXNvbHV0aW9uOjEsY2FydGVzaWFuOiEwLHVzZXJEYXRhUnNvT2Zmc2V0OjB9LGUpO2NvbnN0e2VuZEhlaWdodDpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHVzZXJEYXRhUnNvT2Zmc2V0OmwscHJvamVjdGlvbjpofT10aGlzLnBhcmFtZXRlcnMse2NvbnRvdXI6dSxzaWRlVG9yc286Zix0b3BWZXJ0czpkLGJvdHRvbUNhcDpwLHRvcENhcDp5fT1OdShGdCh7fSx0aGlzLnBhcmFtZXRlcnMpKTtsZXQgbT1bXSxnPVtdLGI9W10sdz0wO2NvbnN0IHg9TT0+e2NvbnN0IEE9TWF0aC5yb3VuZChtLmxlbmd0aC8zKSxTPWIubGVuZ3RoO209bS5jb25jYXQoTS52ZXJ0aWNlcyksZz1nLmNvbmNhdChNLnV2cyksYj1iLmNvbmNhdChBP00uaW5kaWNlcy5tYXAoXz0+XytBKTpNLmluZGljZXMpLHRoaXMuYWRkR3JvdXAoUyxiLmxlbmd0aC1TLHcrKyl9O3MmJnImJngoeSksYSYmKHgoZiksdGhpcy51c2VyRGF0YS50b3BWZXJ0cz1sP0pyKHUsbitsLGMsaCkudmVydGljZXM6ZCksbyYmeChwKSxzJiYhciYmeCh5KSx0aGlzLnNldEluZGV4KGIpLHRoaXNbSXVdKCJwb3NpdGlvbiIsbmV3IEJlKG0sMykpLHRoaXNbSXVdKCJ1diIsbmV3IEJlKGcsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKX19dmFyIE1nPWk9Pntjb25zdCBhPWkse2Nvb3JkaW5hdGU6dCxzdGFydEhlaWdodDplLGhlaWdodDpufT1hLHM9SnUoYSxbImNvb3JkaW5hdGUiLCJzdGFydEhlaWdodCIsImhlaWdodCJdKTtsZXQgcj1lfHwwO3JldHVybiB0eXBlb2YgZSE9InVuZGVmaW5lZCImJnR5cGVvZiBuIT0idW5kZWZpbmVkIiYmKHI9ZStuKSxuZXcgYmcoW3RdLFplKEZ0KHt9LHMpLHtzdGFydEhlaWdodDplLGVuZEhlaWdodDpyfSkpfTtjb25zdCBBZz0oe2Nvb3JkaW5hdGVzQXJyOmksc3RhcnQ6dCxkZXB0aDplLHVzZUdyb3VwczpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHByb2plY3Rpb246bCxjdXJ2YXR1cmVSZXNvbHV0aW9uOmgsYmJveDp1fSk9Pntjb25zdCBmPWwmJlhpKGwpO2YmJihjPSExKSx0fHwodD1bMF0pO2NvbnN0IGQ9aS5tYXAoKHAseSk9Pnt2YXIgbSxnO3JldHVybiBNZyh7Y29vcmRpbmF0ZTpwLHByb2plY3Rpb246ZixzdGFydEhlaWdodDoobT10W3ldKSE9bnVsbD9tOnRbMF0saGVpZ2h0OihnPWVbeV0pIT1udWxsP2c6ZVswXSxoYXNUb3A6cyE9bnVsbD9zOiEwLHRvcEZpcnN0OnIhPW51bGw/cjohMSxoYXNCb3R0b206byE9bnVsbD9vOiEwLGhhc1NpZGU6YSE9bnVsbD9hOiEwLGNhcnRlc2lhbjpjIT1udWxsP2M6ITAsY3VydmF0dXJlUmVzb2x1dGlvbjpoIT1udWxsP2g6MSxiYm94OnV9KX0pO3JldHVybiBKaShkLG4pfSxTZz0oe2Nvb3JkaW5hdGVzQXJyOmksbGluZVdpZHRoOnQsc3RhcnQ6ZSx1c2VHcm91cHM6bn0pPT57Y29uc3Qgcj1pLm1hcCgobyxhKT0+e3ZhciBjO3JldHVybiBOdSh7cG9seWdvbkdlb0pzb246W29dLHN0YXJ0SGVpZ2h0OihjPWVbYV0pIT1udWxsP2M6ZVswXX0pLnRvcFZlcnRzfSkubWFwKChvLGEpPT57dmFyIGw7Y29uc3QgYz0obD10W2FdKSE9bnVsbD9sOnRbMF07cmV0dXJuIFpoKHtub2RlczpvLHNldFBvaW50V2lkdGg6KCk9PmN9KX0pO3JldHVybiBKaShyLG4pfTt2YXIgX2c9KGksdCxlKT0+bmV3IFByb21pc2UoKG4scyk9Pnt2YXIgcj1jPT57dHJ5e2EoZS5uZXh0KGMpKX1jYXRjaChsKXtzKGwpfX0sbz1jPT57dHJ5e2EoZS50aHJvdyhjKSl9Y2F0Y2gobCl7cyhsKX19LGE9Yz0+Yy5kb25lP24oYy52YWx1ZSk6UHJvbWlzZS5yZXNvbHZlKGMudmFsdWUpLnRoZW4ocixvKTthKChlPWUuYXBwbHkoaSx0KSkubmV4dCgpKX0pO2Z1bmN0aW9uIHZnKGkpe3JldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhpKS5yZWR1Y2UoZnVuY3Rpb24odCxlKXtyZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSx7dmFsdWU6aVtlXSxlbnVtZXJhYmxlOiEwfSl9LHt9KX0oaT0+e2NvbnN0IHQ9e3J1bihlLG4pe2NvbnN0IHM9bmV3IEZ1bmN0aW9uKCJyZXR1cm4gKCIrZSsiKS5hcHBseShudWxsLCBhcmd1bWVudHMpOyIpO3JldHVybiBzLmFwcGx5KHMsbil9LG1ldGhvZHMoKXtyZXR1cm4gT2JqZWN0LmtleXModCl9fTthZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIixlPT5fZyh2b2lkIDAsW2VdLGZ1bmN0aW9uKih7ZGF0YTpufSl7dHJ5e2NvbnN0IHM9dFtuLm1ldGhvZF07aWYocyl7Y29uc3Qgcj15aWVsZCBzLmFwcGx5KHMsbi5wYXJhbXMpO3IudHJhbnNmZXImJnIubWVzc2FnZT9wb3N0TWVzc2FnZSh7aWQ6bi5pZCxyZXN1bHQ6ci5tZXNzYWdlLGVycm9yOm51bGx9LHIudHJhbnNmZXIpOnBvc3RNZXNzYWdlKHtpZDpuLmlkLHJlc3VsdDpyLGVycm9yOm51bGx9KX1lbHNlIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXRob2QgIicrbi5tZXRob2QrJyInKX1jYXRjaChzKXtwb3N0TWVzc2FnZSh7aWQ6bi5pZCxyZXN1bHQ6bnVsbCxlcnJvcjp2ZyhzKX0pfX0pKSxPYmplY3Qua2V5cyhpKS5mb3JFYWNoKGU9Pnt0W2VdPWlbZV19KSxwb3N0TWVzc2FnZSgicmVhZHkiKX0pKHtleHRydWRlUG9seWdvbjpjeSxsaW5lOnV5LGxpbmUyOmR5LGNvbmljUG9seWdvbjpBZyxjb25pY0xpbmU6U2d9KX0pKCk7Cg==",J=g=>Uint8Array.from(atob(g),t=>t.charCodeAt(0)),z=typeof window!="undefined"&&window.Blob&&new Blob([J(o)],{type:"text/javascript;charset=utf-8"});function T(g){let t;try{if(t=z&&(window.URL||window.webkitURL).createObjectURL(z),!t)throw"";const r=new Worker(t,{name:g==null?void 0:g.name});return r.addEventListener("error",()=>{(window.URL||window.webkitURL).revokeObjectURL(t)}),r}catch(r){return new Worker("data:text/javascript;base64,"+o,{name:g==null?void 0:g.name})}finally{t&&(window.URL||window.webkitURL).revokeObjectURL(t)}}const R=g=>{const t=new BufferGeometry;return Object.keys(g).forEach(r=>{r==="groups"?g[r].forEach(m=>{t.addGroup(m.start,m.count,m.materialIndex)}):r==="index"?t.setIndex(new BufferAttribute(g[r].array,g[r].itemSize)):t.setAttribute(r,new BufferAttribute(g[r].array,g[r].itemSize))}),t};class Q{constructor(t){this.pluginName="worker",this.bufferGeometryLoader=new BufferGeometryLoader,this.cacheObj={},this._dispose=!1,this.options=W({dbName:"base",cacheVersion:"1"},t),this.store=createStore(this.options.dbName,"attributes")}install(t){this.pencil=t;const r=new esusLite.WorkerPool(T,{maxWorkers:this.options.maxWorkers});this.pool=r}geoGeometry(t,r){return V(this,null,function*(){const{mesaage:m,cacheKey:v,userData:C,cacheVersion:_,cb:w}=W(W({},this.options),r),I=this.pool,{err:O,res:Pe}=yield I.exec(t,[W({},m)],void 0,!0);if(O)throw O;const Ne=R(Pe);if(Object.assign(Ne.userData,W({},C)),w&&(yield w(Ne)),v){const{cacheObj:Fe}=this;Fe[v]||(Fe[v]={[_]:[]}),Fe[v][_].push(W({attributes:Pe},C))}return Ne})}getCachedGeometry(t){return V(this,null,function*(){const{cacheKey:r,cacheVersion:m}=t;if(r){const v=yield get(r,this.store),C=m||this.options.cacheVersion;return v!=null&&v[C]?v[C].map(_=>{const w=_,{attributes:I}=w,O=Y(w,["attributes"]),Pe=R(I);return Object.assign(Pe.userData,W({},O)),Pe}):[]}else return[]})}saveCache(){setMany(Object.entries(this.cacheObj),this.store)}dispose(){this.cacheObj={},this.pool.dispose(),this._dispose=!0}}class RoomEnvironment extends Scene{constructor(){super();const t=new BoxGeometry;t.deleteAttribute("uv");const r=new MeshStandardMaterial({side:BackSide}),m=new MeshStandardMaterial,v=new PointLight(16777215,900,28,2);v.position.set(.418,16.199,.3),this.add(v);const C=new Mesh(t,r);C.position.set(-.757,13.219,.717),C.scale.set(31.713,28.305,28.591),this.add(C);const _=new InstancedMesh(t,m,6),w=new Object3D;w.position.set(-10.906,2.009,1.846),w.rotation.set(0,-.195,0),w.scale.set(2.328,7.905,4.651),w.updateMatrix(),_.setMatrixAt(0,w.matrix),w.position.set(-5.607,-.754,-.758),w.rotation.set(0,.994,0),w.scale.set(1.97,1.534,3.955),w.updateMatrix(),_.setMatrixAt(1,w.matrix),w.position.set(6.167,.857,7.803),w.rotation.set(0,.561,0),w.scale.set(3.927,6.285,3.687),w.updateMatrix(),_.setMatrixAt(2,w.matrix),w.position.set(-2.017,.018,6.124),w.rotation.set(0,.333,0),w.scale.set(2.002,4.566,2.064),w.updateMatrix(),_.setMatrixAt(3,w.matrix),w.position.set(2.291,-.756,-2.621),w.rotation.set(0,-.286,0),w.scale.set(1.546,1.552,1.496),w.updateMatrix(),_.setMatrixAt(4,w.matrix),w.position.set(-2.193,-.369,-5.547),w.rotation.set(0,.516,0),w.scale.set(3.875,3.487,2.986),w.updateMatrix(),_.setMatrixAt(5,w.matrix),this.add(_);const I=new Mesh(t,createAreaLightMaterial(50));I.position.set(-16.116,14.37,8.208),I.scale.set(.1,2.428,2.739),this.add(I);const O=new Mesh(t,createAreaLightMaterial(50));O.position.set(-16.109,18.021,-8.207),O.scale.set(.1,2.425,2.751),this.add(O);const Pe=new Mesh(t,createAreaLightMaterial(17));Pe.position.set(14.904,12.198,-1.832),Pe.scale.set(.15,4.265,6.331),this.add(Pe);const Ne=new Mesh(t,createAreaLightMaterial(43));Ne.position.set(-.462,8.89,14.52),Ne.scale.set(4.38,5.441,.088),this.add(Ne);const Fe=new Mesh(t,createAreaLightMaterial(20));Fe.position.set(3.235,11.486,-12.541),Fe.scale.set(2.5,2,.1),this.add(Fe);const Ae=new Mesh(t,createAreaLightMaterial(100));Ae.position.set(0,20,0),Ae.scale.set(1,.1,1),this.add(Ae)}dispose(){const t=new Set;this.traverse(r=>{r.isMesh&&(t.add(r.geometry),t.add(r.material))});for(const r of t)r.dispose()}}function createAreaLightMaterial(g){const t=new MeshBasicMaterial;return t.color.setScalar(g),t}const BLOCKLISTED_GPUS=["geforce 320m","geforce 8600","geforce 8600m gt","geforce 8800 gs","geforce 8800 gt","geforce 9400","geforce 9400m g","geforce 9400m","geforce 9600m gt","geforce 9600m","geforce fx go5200","geforce gt 120","geforce gt 130","geforce gt 330m","geforce gtx 285","google swiftshader","intel g41","intel g45","intel gma 4500mhd","intel gma x3100","intel hd 3000","intel q45","legacy","mali-2","mali-3","mali-4","quadro fx 1500","quadro fx 4","quadro fx 5","radeon hd 2400","radeon hd 2600","radeon hd 4670","radeon hd 4850","radeon hd 4870","radeon hd 5670","radeon hd 5750","radeon hd 6290","radeon hd 6300","radeon hd 6310","radeon hd 6320","radeon hd 6490m","radeon hd 6630m","radeon hd 6750m","radeon hd 6770m","radeon hd 6970m","sgx 543","sgx543"],apple=[],amd=["2","3","4","6","12","15","25","48","455","535","555","575","600","610","625","630","640","694","699","740","880","900","2000","2270","2600","3200","3800","3900","4000","4150","4170","4190","4250","4800","5170","5400","5450","5470","5650","5670","5730","5750","5950","6150","6230","6250","6290","6300","6310","6320","6350","6370","6380","6410","6450","6460","6470","6480","6490","6510","6520","6530","6540","6550","6570","6620","6630","6670","6730","6760","6790","6980","7290","7310","7340","7400","7420","7450","7480","7500","7520","7540","7550","7610","7620","7640","7650","7670","7730","7820","8180","8210","8240","8250","8330","8350","8400","8410","8450","8490","8500","8510","8530","8600","8610","8690","8730","8760","8850","9171","9173","9874","10000","v","9999999999"],radeon=["2","3","4","6","25","48","455","535","555","575","610","625","630","640","740","880","1305","1605","2600","3200","4150","4250","5000","5400","5450","5470","5650","5670","5730","5750","5770","6230","6250","6290","6300","6310","6320","6350","6370","6380","6410","6450","6460","6470","6480","6490","6510","6520","6530","6540","6550","6570","6620","6630","6670","6730","6760","6790","7000","7290","7310","7340","7400","7420","7450","7480","7500","7520","7540","7550","7610","7620","7640","7650","7670","7730","8180","8210","8240","8250","8330","8350","8400","8410","8450","8490","8500","8510","8530","8600","8610","8690","8730","8850","9171","9173"],nvidia=["1","6","15","51","120","130","140","160","180","210","220","260","295","310","315","320","410","415","420","425","430","440","445","510","525","530","540","545","555","590","605","610","615","625","630","635","705","710","720","730","735","755","765","800","810","820","840","845","860","910","945","1010","1100","1800","2800","5010","5400","8400","8600","9300","9400","9600","9800","gpu","prexpe"],geforce=["10","120","130","210","240","280","295","320","410","415","420","425","430","440","445","510","520","525","530","540","545","555","590","605","610","615","620","625","630","635","705","710","720","730","735","755","765","800","810","820","840","845","860","910","945","1010","2075","8400","8600","9300","9400","9600","9800","gpu","prexpe"],adreno=["5","7","540","618","630","675","680","685"],tier0GPU={apple,amd,radeon,nvidia,geforce,adreno},types=["intel","apple","amd","radeon","nvidia","geforce","adreno"];class Benchmarks{constructor(t){C0(this,"renderer");this.renderer=t}query(){const t=this.renderer,r=this.getGpuType();if(!r)return this.queryFallback();if(r==="intel")return{tier:0,gpu:t};const m=tier0GPU[r],v=this.getGPUVersion();return m.includes(v)?{tier:0,renderer:t}:this.queryFallback()}getGpuType(){const t=this.renderer;for(const r of types)if(t.includes(r))return r}getGPUVersion(){var v;const r=this.renderer.replace(/\([^)]+\)/,""),m=r.match(/\d+/)||r.match(/(\W|^)([A-Za-z]{1,3})(\W|$)/g);return(v=m==null?void 0:m.join("").replace(/\W|amd/g,""))!=null?v:""}queryFallback(){const t=this.renderer,r=BLOCKLISTED_GPUS.find(m=>t.includes(m));return r?{tier:0,gpu:r}:{tier:3,gpu:t}}}class WebGL{constructor(){C0(this,"rawRenderer");C0(this,"renderer");const t=this.getRawRenderer();this.rawRenderer=t;const r=this.getRenderer();this.renderer=r}getRawRenderer(){try{const r=document.createElement("canvas").getContext("webgl"),m=r==null?void 0:r.getExtension("WEBGL_debug_renderer_info");return r&&m?r.getParameter(m.UNMASKED_RENDERER_WEBGL):""}catch(t){return""}}getRenderer(){const t=this.rawRenderer;return t?t.toLowerCase().replace(/.*angle ?\((.+)\)(?: on vulkan [0-9.]+)?$/i,"$1").replace(/\s(\d{1,2}gb|direct3d.+$)|\(r\)| \([^)]+\)$/g,"").replace(/(?:vulkan|opengl) \d+\.\d+(?:\.\d+)?(?: \((.*)\))?/,"$1"):""}query(){return{WebP:this.isWebPAvailable(),WebGL:this.isWebGLAvailable(),WebGL2:this.isWebGL2Available(),WebGL2RC:this.isWebGL2RenderingContextAvailable(),isGPUAcceleratorEnabled:this.isGPUAcceleratorAvailable()}}isWebGLAvailable(){try{const t=document.createElement("canvas");return!!(window.WebGLRenderingContext&&(t.getContext("webgl")||t.getContext("experimental-webgl")))}catch(t){return!1}}isWebGL2Available(){try{const t=document.createElement("canvas");return!!(window.WebGL2RenderingContext&&t.getContext("webgl2"))}catch(t){return!1}}isWebGL2RenderingContextAvailable(){return typeof window.WebGL2RenderingContext!="undefined"}isGPUAcceleratorAvailable(){const t=this.rawRenderer;return!/SwiftShader/gi.test(t)}isColorSpaceAvailable(t){try{const r=document.createElement("canvas"),m=window.WebGL2RenderingContext&&r.getContext("webgl2");return m?(m.drawingBufferColorSpace=t,m.drawingBufferColorSpace===t):!1}catch(r){return!1}}isWebPAvailable(){try{return document.createElement("canvas").toDataURL("image/webp").indexOf("data:image/webp")===0}catch(t){return!1}}}const detect=()=>{try{const g=new WebGL,t=new Benchmarks(g.renderer);return q0(q0({},g.query()),t.query())}catch(g){return console.error("vis-core: feature detection failed",g),{tier:0}}},isGzip=g=>!!(g.endsWith(".gzip")||g.endsWith(".gz")),jsonFetch=(g,t,r=isGzip)=>{const m=esusLite.makePromiseCreator(!0);return window.fetch(g).then(v=>{let C=v;if(C.ok)return r(g)&&C.headers.get("content-encoding")!=="gzip"?C.blob().then(_=>{const w=new DecompressionStream("gzip"),I=_.stream().pipeThrough(w);return new Response(I)}):C;throw new Error("Network response was not ok.")}).then(v=>v.json()).then(v=>{m.resolve(v)}).catch(v=>{m.reject(v)}),m.promise},compareVersion=(g,t)=>{if(!g&&!t)return 0;if(!g&&t)return-1;if(g&&!t)return 1;const r=g.split("."),m=t.split("."),v=Math.max(r.length,m.length);for(;r.length<v;)r.push("0");for(;m.length<v;)m.push("0");for(let C=0;C<v;C++){const _=parseInt(r[C]),w=parseInt(m[C]);if(_>w)return 1;if(_<w)return-1}return 0};class Config{constructor(t){C0(this,"editor");C0(this,"meta",{name:"",key:"",open:!1,jsonVersion:"0.0.0",sdkVersion:"0.0.0"});this.editor=t}setConfig(t,r){this.meta[t]=r,this.editor.emit("configChanged",q0({},this.meta))}fromJSON(t){Object.keys(t).forEach(r=>{const m=r==="version"?"jsonVersion":r;m in this.meta&&this.setConfig(m,t[r])})}compareVersion(){compareVersion(this.meta.jsonVersion,this.meta.sdkVersion)===1&&console.warn("vis-core 版本过低,可能会出现问题","json:"+this.meta.jsonVersion,"sdk:"+this.meta.sdkVersion)}toJSON(){return{version:this.meta.sdkVersion}}}function applyFixes(g,t){const r=[{version:"0.5.38",fix:()=>{var _;(_=t.v)!=null&&_.eo&&Object.keys(t.v.eo).forEach(w=>{["mouseLeft","mouseRight","mouseWheel","label","labelLite","shadowMap","autoRotate","equirectangular"].includes(w)&&(t.v.eo[w]=!!t.v.eo[w])}),t.h.u.forEach(w=>{w.type==="SetSetting"&&(w.attributeName==="阴影"&&(w.attributeName="shadowMap"),w.newValue=!!w.newValue,w.oldValue=!!w.oldValue)})}},{version:"0.7.14",fix:()=>{t.h.u.forEach(_=>{_.objectUuid&&(_.objectUuid=_.objectUuid.replace(_.objectUuid[0],_.objectUuid[0].toLowerCase()))})}},{version:"0.13.0",fix:()=>{if(t.h.u[0]&&t.h.u[0].visType==="city"&&(t.h.u[0].visOptions.jsonName||(t.h.u=[])),t.h.u[0]&&t.h.u[0].visType==="map"){if(t.h.u[0].visOptions.geojson){const{geojson:_,adcode:w,geojsonLite:I}=t.h.u[0].visOptions;t.h.u[0].visOptions=Ji(q0({},t.h.u[0].visOptions),{geojsonMap:{[w]:_},extrudeLineGeojsonMap:{[w]:I}}),delete t.h.u[0].visOptions.geojson,delete t.h.u[0].visOptions.geojsonLite}if(t.h.u[0].visOptions.bbox){const{bbox:_,bboxMap:w,adcode:I}=t.h.u[0].visOptions;t.h.u[0].visOptions=Ji(q0({},t.h.u[0].visOptions),{bboxMap:w||{[I]:_}}),delete t.h.u[0].visOptions.bbox}if(t.h.u[0].visOptions.worldBg){const{worldBg:_}=t.h.u[0].visOptions;t.h.u[0].visOptions=Ji(q0({},t.h.u[0].visOptions),{parentBg:_}),delete t.h.u[0].visOptions.worldBg}t.h.u[0].visOptions.adcode===0&&(t.h.u[0].visType="world")}t.h.u[0]&&t.h.u[0].visType==="world"&&(t.h.u[0].visType="map",t.h.u[0].visOptions={adcode:0,mapDepth:5,lineWidth:2,worldPacificCentre:!0,extrudeLine:!1})}},{version:"0.18.1",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="FJ"&&(t.h.u[0].visType="map2"),t.h.u[0]&&t.h.u[0].visType==="earth3"&&(t.h.u[0].visType="earth",t.h.u[0].visOptions.style="countryPlate")}},{version:"0.18.14",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u.forEach(_=>{if(_.type==="SetSetting"&&_.attributeName.startsWith("测试")&&typeof _.newValue=="string"&&_.newValue.includes(":::")){const w=_.newValue.split(":::")[1];_.attributeName+=":::"+w,_.newValue=_.newValue.split(":::")[0],_.oldValue&&typeof _.oldValue=="string"&&(_.oldValue=_.oldValue.split(":::")[0])}})}},{version:"0.18.16",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u.forEach(_=>{if(_.type==="SetSetting"&&_.attributeName.startsWith("测试")&&_.attributeName.includes(":::")&&!_.attributeName.includes("caId")){const w=_.attributeName.split(":::")[1];_.attributeName=_.attributeName.replace(w,`caId.${w}`)}})}},{version:"0.21.24",fix:()=>{var _,w;t.h.u[0]&&t.h.u[0].visType==="map"&&((w=(_=t.v)==null?void 0:_.eo)!=null&&w.parentBgCurvatureResolution)&&delete t.v.eo.parentBgCurvatureResolution}},{version:"0.23.1",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map2"&&!t.h.u[0].visOptions.cityOnMap&&(t.v.eo||(t.v.eo={}),t.v.eo.clickHandleDrillDown=!0)}},{version:"0.24.1",fix:()=>{var _,w;t.h.u[0]&&t.h.u[0].visType==="map"&&((w=(_=t.v)==null?void 0:_.eo)!=null&&w.drillDownTopMatTwo)&&(delete t.v.eo.drillDownTopMatTwo,t.v.eo.drillDownSecondLevelMats=!0)}},{version:"0.24.2",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map2"&&t.h.u.forEach(_=>{_.objectUuid==="plane#topMatOne"?(_.objectUuid="area",_.materialSlot=0):_.objectUuid==="plane#sideMat"?(_.objectUuid="area",_.materialSlot=1):_.objectUuid==="plane#lineMat"?_.objectUuid="line":_.objectUuid==="plane#extrudeLineMat"?_.objectUuid="extrudeLine":_.objectUuid==="plane#bgTopMatOne"?_.objectUuid="bgPlane#topMat":_.objectUuid==="plane#bgSideMat"?_.objectUuid="bgPlane#sideMat":_.objectUuid==="plane#bgLineMat"?_.objectUuid="bgPlane#lineMat":_.objectUuid==="plane#bgExtrudeLineMat"?_.objectUuid="bgPlane#extrudeLineMat":_.objectUuid==="parentPlane#topMat"?(_.objectUuid="100000area",_.materialSlot=0):_.objectUuid==="parentPlane#sideMat"?(_.objectUuid="100000area",_.materialSlot=1):_.objectUuid==="parentPlane#lineMat"?_.objectUuid="100000line":_.objectUuid==="worldPlane#topMat"?(_.objectUuid="worldarea",_.materialSlot=0):_.objectUuid==="worldPlane#sideMat"?(_.objectUuid="worldarea",_.materialSlot=1):_.objectUuid==="worldPlane#lineMat"?_.objectUuid="worldline":_.objectUuid==="continents#topMat"?(_.objectUuid="continentsArea",_.materialSlot=0):_.objectUuid==="continents#sideMat"?(_.objectUuid="continentsArea",_.materialSlot=1):_.objectUuid==="continents#lineMat"?_.objectUuid="continentsLine":_.objectUuid==="area#river"?_.objectUuid="geography#river":_.objectUuid==="area#grassland"?_.objectUuid="geography#grassland":_.objectUuid==="area-grey#river"?_.objectUuid="geography-grey#river":_.objectUuid==="area-grey#grassland"&&(_.objectUuid="geography-grey#grassland")})}},{version:"0.26.0",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map2"&&(t.v.eo||(t.v.eo={}),t.h.u[0].visType="map",t.h.u[0].visOptions.cityOnMap?(t.h.u[0].visOptions.style="map2CityOnMap",delete t.h.u[0].visOptions.cityOnMap):(t.h.u[0].visOptions.style="map2Base",t.v.eo.bottomPlane=!0))}},{version:"0.26.6",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="earth2"&&(t.h.u[0].visType="earth",t.h.u[0].visOptions.style="base")}},{version:"0.26.13",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&(t.h.u[0].visOptions.clickHandleDrillDown||t.v.eo.clickHandleDrillDown)&&t.v.eo.drillDownFirstLevelUseBgMats===void 0&&(t.v.eo.drillDownFirstLevelUseBgMats=!0)}},{version:"0.27.0",fix:()=>{if(t.h.u[0]&&t.h.u[0].visType==="map"){const _={};t.h.u.forEach((w,I)=>{var O,Pe,Ne;if(w.objectUuid==="area"&&w.materialSlot===0)w.objectUuid="plane#topMat",delete w.materialSlot;else if(w.objectUuid==="area"&&w.materialSlot===1)w.objectUuid="plane#sideMat",delete w.materialSlot;else if(w.objectUuid==="line")w.objectUuid="plane#lineMat";else if(w.objectUuid==="continentsArea"&&w.materialSlot===0)w.objectUuid="continents#topMat",delete w.materialSlot;else if(w.objectUuid==="continentsArea"&&w.materialSlot===1)w.objectUuid="continents#sideMat",delete w.materialSlot;else if(w.objectUuid==="continentsLine")w.objectUuid="continents#lineMat";else if(w.type==="SetSetting"&&((O=w.attributeName)!=null&&O.startsWith("测试"))&&w.attributeName.includes(":::caId.")){const Fe=w.attributeName.split(":::caId.")[1],Ae=t.h.u[0].visOptions.adcode;t.h.u[I]=[{id:w.id,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`extrudePolygon#${Ae}-${Fe}`,copyObjectUuid:`ExtrudePolygon#${Ae}-${Fe}_${w.id}`},{id:w.id+.1,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`line#${Ae}-${Fe}`,copyObjectUuid:`line#${Ae}-${Fe}_${w.id+.1}`}],_[Fe]=w.id}else if((Pe=w.objectUuid)!=null&&Pe.startsWith("planeCopyExtrudePolygon")){const Fe=w.objectUuid.split("CopyExtrudePolygon")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`extrudePolygon#${Ae}-${Fe}_${_[Fe]}`})}else if((Ne=w.objectUuid)!=null&&Ne.startsWith("planeCopyLine")){const Fe=w.objectUuid.split("CopyLine")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`line#${Ae}-${Fe}_${_[Fe]+.1}`})}}),t.h.u=t.h.u.flat()}}},{version:"0.27.8",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&(t.h.u[0].visOptions.mergeSide=!0,t.h.u.forEach(_=>{_.objectUuid==="extrudeLine"?_.objectUuid="plane#lineMat":_.objectUuid==="plane#lineMat"&&(_.objectUuid="extrudeLine")}))}},{version:"0.27.9",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&t.h.u.forEach(_=>{_.objectUuid==="plane#extrudeLineMat"&&(_.objectUuid="plane#lineMat")})}},{version:"0.27.14",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&t.h.u.forEach(_=>{_.objectUuid==="building"&&(_.objectUuid="building#group")})}},{version:"0.29.0",fix:()=>!1}];let m=0,v=r.length-1,C=r.length;for(;m<=v;){const _=Math.floor((m+v)/2);compareVersion(r[_].version,g)>0?(C=_,v=_-1):m=_+1}for(let _=C;_<r.length;_++)r[_].fix()!==!1&&(t.c.version=r[_].version)}const fixJSON=g=>{var t;return g.c||(g={h:{u:g.u},v:{eo:g.eo,bg:g.bg},c:{name:g.name,version:g.v}}),(t=g.c)!=null&&t.key&&delete g.c.key,applyFixes(g.c.version,g),g};class Command{constructor(t){C0(this,"id");C0(this,"updatable");C0(this,"type");C0(this,"name");C0(this,"editor");C0(this,"json",{});this.id=-1,this.updatable=!1,this.type="",this.name="",this.editor=t}toJSON(){const t={};return t.type=this.type,t.id=this.id,t.name=this.name,t.updatable=this.updatable,t}fromJSON(t){if(this.type=t.type,this.id=t.id,this.name=t.name,this.updatable=t.updatable,!this.editor.config.meta.jsonVersion&&t.objectUuid){const r=this.editor.objectByUuid(t.objectUuid);r&&(t.objectUuid=this.editor.uuidByObject(r));const m=this.editor.baseObjectByUuid(t.objectUuid);m&&(t.objectUuid=this.editor.uuidByBaseObject(m))}}fixJSON(){}}class SetColor extends Command{constructor(t,r,m,v){super(t),this.type="SetColor",this.name=`Set ${m}`,this.updatable=!0,this.object=r,this.attributeName=m,this.oldValue=r!==void 0?this.object[this.attributeName].getHex():void 0,this.newValue=v}execute(){this.object&&(this.object[this.attributeName].setHex(this.newValue),this.editor.emit("objectChanged",this.object))}undo(){this.object[this.attributeName].setHex(this.oldValue),this.editor.emit("objectChanged",this.object)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue}}class SetMaterialColor extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialColor",this.name=`Set Material.${m}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[m].getHex():void 0,this.newValue=v,this.attributeName=m}execute(){this.material[this.attributeName].setHex(this.newValue),this.editor.emit("materialChanged",this.material)}undo(){this.material[this.attributeName].setHex(this.oldValue),this.editor.emit("materialChanged",this.material)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetMaterial extends Command{constructor(t,r,m,v){super(t),this.type="SetMaterial",this.name="New Material",this.object=r,this.materialSlot=v,this.oldMaterial=this.editor.getObjectMaterial(r,v),this.newMaterial=m}execute(){this.editor.setObjectMaterial(this.object,this.materialSlot,this.newMaterial),this.editor.emit("materialChanged",this.newMaterial)}undo(){this.editor.setObjectMaterial(this.object,this.materialSlot,this.oldMaterial),this.editor.emit("materialChanged",this.oldMaterial)}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.newMaterial=this.newMaterial.toJSON(),t}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.materialSlot=t.materialSlot,this.oldMaterial=this.editor.getObjectMaterial(this.object,this.materialSlot),this.newMaterial=parseMaterial(t.newMaterial),((r=this.newMaterial.envMap)==null?void 0:r.name)==="PMREM.cubeUv"&&(this.newMaterial.envMap=this.editor.viewport.vis.getRoomEnvMap())}fixJSON(){const t=this.json;if(t&&t.oldMaterial&&delete t.oldMaterial,this.oldMaterial){const r=this.editor.pencil.mList.getKey(this.oldMaterial);r&&r!==t.objectUuid&&(console.warn("SetMaterial:fix:",t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}function parseMaterial(g){if(!g)return null;const t=new ObjectLoader,r=t.parseImages(g.images),m=t.parseTextures(g.textures,r);return t.parseMaterials([g],m)[g.uuid]}const TEXTURE_MAPPING={UVMapping,CubeReflectionMapping,CubeRefractionMapping,EquirectangularReflectionMapping,EquirectangularRefractionMapping,CubeUVReflectionMapping},TEXTURE_WRAPPING={RepeatWrapping,ClampToEdgeWrapping,MirroredRepeatWrapping},TEXTURE_FILTER={NearestFilter,NearestMipmapNearestFilter,NearestMipmapLinearFilter,LinearFilter,LinearMipmapNearestFilter,LinearMipmapLinearFilter};class SetMaterialMap extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialMap",this.name=`Set Material.${m}`,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldMap=r!==void 0?this.material[m]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=m}execute(){if(this.material.hasOwnProperty(this.mapName)){if(this.oldMap){const t=new se$1;t.track(this.oldMap),t.dispose()}this.newMap&&(this.newMap.name==="PMREM.cubeUv"&&(this.newMap=this.editor.viewport.vis.getRoomEnvMap()),this.newMap.anisotropy=this.editor.viewport.vis.tier0?1:this.editor.pencil.maxAnisotropy),this.material[this.mapName]=this.newMap,this.playVideo(this.newMap),this.material instanceof We$1&&(this.material.useMap=!!this.newMap,this.newMap&&this.newMap.wrapS!==RepeatWrapping&&(this.newMap.wrapS=RepeatWrapping,this.newMap.wrapT=RepeatWrapping,this.newMap.needsUpdate=!0)),(!this.oldMap&&this.newMap||this.oldMap&&!this.newMap)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material)}}undo(){this.material[this.mapName]=this.oldMap,this.playVideo(this.oldMap),this.material instanceof We$1&&(this.material.useMap=!!this.newMap),(!this.oldMap&&this.newMap||this.oldMap&&!this.newMap)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material)}playVideo(t){if(t&&t instanceof VideoTexture){const r=t.source.data;r&&r.play()}}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.mapName=this.mapName,t.newMap=serializeMap(this.newMap),t}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.mapName=t.mapName,this.oldMap=this.object&&this.material?this.material[this.mapName]:void 0,((r=t.newMap)==null?void 0:r.name)==="PMREM.cubeUv"?this.newMap=this.editor.viewport.vis.getRoomEnvMap():this.newMap=parseTexture(t.newMap)}fixJSON(){const t=this.json;if(t&&t.oldMap&&delete t.oldMap,this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}function parseTexture(g){let t=null;if(g){const r=new ObjectLoader;if(g.isVideoTexture){const m=document.createElement("video");m.src=g.images[0].url,m.muted=!0,m.loop=!0,m.preload="auto";const v={[g.images[0].uuid]:new VideoTexture(m)};t=parseVideoTextures([g],v)[g.uuid]}else{const m=r.parseImages(g.images);t=r.parseTextures([g],m)[g.uuid]}t.sourceFile=g.sourceFile}return t}const parseVideoTextures=(g,t)=>{function r(v,C){return typeof v=="number"?v:(console.warn("THREE.ObjectLoader.parseTexture: Constant should be in numeric form.",v),C[v])}const m={};if(g!==void 0)for(let v=0,C=g.length;v<C;v++){const _=g[v];let w=t[_.image];w.needsUpdate=!0,w.uuid=_.uuid,_.name!==void 0&&(w.name=_.name),_.mapping!==void 0&&(w.mapping=r(_.mapping,TEXTURE_MAPPING)),_.channel!==void 0&&(w.channel=_.channel),_.offset!==void 0&&w.offset.fromArray(_.offset),_.repeat!==void 0&&w.repeat.fromArray(_.repeat),_.center!==void 0&&w.center.fromArray(_.center),_.rotation!==void 0&&(w.rotation=_.rotation),_.wrap!==void 0&&(w.wrapS=r(_.wrap[0],TEXTURE_WRAPPING),w.wrapT=r(_.wrap[1],TEXTURE_WRAPPING)),_.format!==void 0&&(w.format=_.format),_.internalFormat!==void 0&&(w.internalFormat=_.internalFormat),_.type!==void 0&&(w.type=_.type),_.colorSpace!==void 0&&(w.colorSpace=_.colorSpace),_.encoding!==void 0&&(w.encoding=_.encoding),_.minFilter!==void 0&&(w.minFilter=r(_.minFilter,TEXTURE_FILTER)),_.magFilter!==void 0&&(w.magFilter=r(_.magFilter,TEXTURE_FILTER)),_.anisotropy!==void 0&&(w.anisotropy=_.anisotropy),_.flipY!==void 0&&(w.flipY=_.flipY),_.generateMipmaps!==void 0&&(w.generateMipmaps=_.generateMipmaps),_.premultiplyAlpha!==void 0&&(w.premultiplyAlpha=_.premultiplyAlpha),_.unpackAlignment!==void 0&&(w.unpackAlignment=_.unpackAlignment),_.compareFunction!==void 0&&(w.compareFunction=_.compareFunction),_.userData!==void 0&&(w.userData=_.userData),m[_.uuid]=w}return m};function serializeMap(g){if(g==null)return null;if(g.name==="PMREM.cubeUv")return{name:"PMREM.cubeUv"};const t={geometries:{},materials:{},textures:{},images:{}},r=g.toJSON(t),m=extractFromCache(t.images);return g instanceof VideoTexture&&(m[0].url=g.source.data.src,r.isVideoTexture=!0),m.length>0&&(r.images=m),r.sourceFile=g.sourceFile,r}function extractFromCache(g){const t=[];for(const r in g){const m=g[r];delete m.metadata,t.push(m)}return t}const needsUpdateAttributeName=["transparent","alphaTest","fog","vertexColors","vertexShader","fragmentShader","sizeAttenuation"];class SetMaterialValue extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialValue",this.name=`Set Material.${m}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[m]:void 0,this.newValue=v,this.attributeName=m}execute(){this.material!==void 0&&(this.material[this.attributeName]=this.newValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material),this.attributeName==="name"&&this.editor.emit("mListChange"))}undo(){this.material[this.attributeName]=this.oldValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("mListChange")})}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue,this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot)}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetMaterialVector extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialVector",this.name=`Set Material.${m}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[m].toArray():void 0,this.newValue=v,this.attributeName=m}execute(){this.material[this.attributeName].fromArray(this.newValue),this.editor.emit("materialChanged",this.material)}undo(){this.material[this.attributeName].fromArray(this.oldValue),this.editor.emit("materialChanged",this.material)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetMaterialMapVector extends Command{constructor(t,r,m,v,C,_="repeat"){var w,I,O,Pe;super(t),this.type="SetMaterialMapVector",this.attributeName2=_,this.name=`Set Material.${m}.${_}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.material instanceof We$1&&m==="map"&&_==="repeat"?this.oldValue=this.material.repeat.toArray():((I=(w=this.material)==null?void 0:w[m])==null?void 0:I[_])instanceof Vector2?this.oldValue=this.material[m][_].toArray():typeof((Pe=(O=this.material)==null?void 0:O[m])==null?void 0:Pe[_])!="undefined"&&(this.oldValue=this.material[m][_]),this.newValue=v,this.attributeName=m}execute(){var t,r,m,v,C;if((t=this.material)!=null&&t[this.attributeName]){const _=this.attributeName;this.material[_].wrapS!==RepeatWrapping&&(this.material[_].wrapS=RepeatWrapping,this.material[_].wrapT=RepeatWrapping,this.material[_].needsUpdate=!0)}this.material instanceof We$1&&this.attributeName==="map"&&this.attributeName2==="repeat"?this.material[this.attributeName2].fromArray(this.newValue):((m=(r=this.material)==null?void 0:r[this.attributeName])==null?void 0:m[this.attributeName2])instanceof Vector2?this.material[this.attributeName][this.attributeName2].fromArray(this.newValue):typeof((C=(v=this.material)==null?void 0:v[this.attributeName])==null?void 0:C[this.attributeName2])!="undefined"&&(this.material[this.attributeName][this.attributeName2]=this.newValue),this.editor.emit("materialChanged",this.material)}undo(){var t,r,m,v;this.material instanceof We$1&&this.attributeName==="map"&&this.attributeName2==="repeat"?this.material[this.attributeName2].fromArray(this.oldValue):((r=(t=this.material)==null?void 0:t[this.attributeName])==null?void 0:r[this.attributeName2])instanceof Vector2?this.material[this.attributeName][this.attributeName2].fromArray(this.oldValue):typeof((v=(m=this.material)==null?void 0:m[this.attributeName])==null?void 0:v[this.attributeName2])!="undefined"&&(this.material[this.attributeName][this.attributeName2]=this.oldValue),this.editor.emit("materialChanged",this.material)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.attributeName2=this.attributeName2,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.attributeName=t.attributeName,t.attributeName2&&(this.attributeName2=t.attributeName2),this.oldValue=t.oldValue,this.newValue=t.newValue,this.attributeName==="repeat"&&(this.attributeName="map")}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetPosition extends Command{constructor(t,r,m,v,C){super(t),this.type="SetPosition",this.name="Set Position",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&m!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=m.clone()),v!==void 0&&(this.oldPosition=v.clone())}execute(){this.cameraControls?this.cameraControls.setPosition(this.newPosition.x,this.newPosition.y,this.newPosition.z,!1):(this.object.position.copy(this.newPosition),this.object.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}undo(){this.cameraControls?this.cameraControls.setPosition(this.oldPosition.x,this.oldPosition.y,this.oldPosition.z,!1):(this.object.position.copy(this.oldPosition),this.object.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}update(t){this.newPosition.copy(t.newPosition)}toJSON(){var r;const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldPosition=(r=this.oldPosition)==null?void 0:r.toArray(),t.newPosition=this.newPosition.toArray(),t.cameraControls=!!this.cameraControls,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldPosition&&(this.oldPosition=new Vector3().fromArray(t.oldPosition)),this.newPosition=new Vector3().fromArray(t.newPosition),t.cameraControls&&(this.cameraControls=this.editor.pencil.controls)}}class SetRotation extends Command{constructor(t,r,m,v){super(t),this.type="SetRotation",this.name="Set Rotation",this.updatable=!0,this.object=r,r!==void 0&&m!==void 0&&(this.oldRotation=r.rotation.clone(),this.newRotation=m.clone()),v!==void 0&&(this.oldRotation=v.clone())}execute(){this.object.rotation.copy(this.newRotation),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}undo(){this.object.rotation.copy(this.oldRotation),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}update(t){this.newRotation.copy(t.newRotation)}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldRotation=this.oldRotation.toArray(),t.newRotation=this.newRotation.toArray(),t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldRotation&&(this.oldRotation=new Euler().fromArray(t.oldRotation)),this.newRotation=new Euler().fromArray(t.newRotation)}}class SetScale extends Command{constructor(t,r,m,v){super(t),this.type="SetScale",this.name="Set Scale",this.updatable=!0,this.object=r,r!==void 0&&m!==void 0&&(this.oldScale=r.scale.clone(),this.newScale=m.clone()),v!==void 0&&(this.oldScale=v.clone())}execute(){this.object.scale.copy(this.newScale),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}undo(){this.object.scale.copy(this.oldScale),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}update(t){this.newScale.copy(t.newScale)}toJSON(){var r;const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldScale=(r=this.oldScale)==null?void 0:r.toArray(),t.newScale=this.newScale.toArray(),t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldScale&&(this.oldScale=new Vector3().fromArray(t.oldScale)),this.newScale=new Vector3().fromArray(t.newScale)}}class SetValue extends Command{constructor(t,r,m,v,C){super(t),this.type="SetValue",this.name=`Set ${m}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=m;const _=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=_!==void 0?_[m]:void 0,this.newValue=v}execute(){const t=this.properties?this.object[this.properties]:this.object;t&&((t instanceof RectAreaLight||t instanceof AmbientLight)&&this.attributeName==="castShadow"||(t[this.attributeName]=this.newValue,this.fixObj(),this.editor.emit("objectChanged",this.object)))}fixObj(){const t=this.properties?this.object[this.properties]:this.object;if(t.isCamera&&["fov","left","right","top","bottom","near","far"].includes(this.attributeName)&&t.updateProjectionMatrix(),this.attributeName==="visible"){const r=this.editor.pencil.lead.objMap.get(this.object);r&&r[t[this.attributeName]?"show":"hide"]()}(this.attributeName==="name"||this.attributeName==="prefab"||this.attributeName==="visible"||this.attributeName==="keepCamera"||this.attributeName==="castShadow"&&this.object instanceof DirectionalLight)&&this.editor.emit("baseObjectListChange"),this.attributeName==="keepCamera"&&(this.editor.select(null),this.editor.emit("baseObjectListChange"))}undo(){const t=this.properties?this.object[this.properties]:this.object;t[this.attributeName]=this.oldValue,this.fixObj(),this.editor.emit("objectChanged",this.object)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.properties=this.properties,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue,this.object=this.editor.objectByUuid(t.objectUuid),this.properties=t.properties}}class SetVector extends Command{constructor(t,r,m,v,C){super(t),this.type="SetVector",this.name=`Set ${m}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=m;const _=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=_!==void 0?_[m].toArray():void 0,this.newValue=v}execute(){const t=this.properties?this.object[this.properties]:this.object;t&&(t[this.attributeName].fromArray(this.newValue),this.fixObj(),this.editor.emit("objectChanged",this.object))}fixObj(){this.editor.playing||this.attributeName==="mapSize"&&this.object[this.properties].map&&(this.object[this.properties].map.dispose(),this.object[this.properties].map=null)}undo(){(this.properties?this.object[this.properties]:this.object)[this.attributeName].fromArray(this.oldValue),this.fixObj(),this.editor.emit("objectChanged",this.object)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.properties=this.properties,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue,this.properties=t.properties}}class AddVis extends Command{constructor(r,m,v){super(r);C0(this,"visType");C0(this,"visOptions");this.type="AddVis",this.visType=m,this.visOptions=v,m!==void 0&&(this.name=`Add Vis: ${m}`)}execute(){return U0(this,null,function*(){yield this.editor.viewport.setVis(this.visType,this.visOptions),this.editor.select(null)})}undo(){const r=window.confirm("将删除所有记录,是否继续?");return r&&this.editor.viewport.dispose(),r}toJSON(){const r=super.toJSON();return r.visType=this.visType,r.visOptions=this.visOptions,r}fromJSON(r){super.fromJSON(r),this.visType=r.visType,this.visOptions=r.visOptions}}class AddObject extends Command{constructor(r,m,v){super(r);C0(this,"objectType");C0(this,"objectOptions");C0(this,"obj");C0(this,"addObjectUuid");this.type="AddObject",this.objectType=m,this.objectOptions=v,m!==void 0&&(this.name=`Add Object: ${m}`)}execute(){return U0(this,null,function*(){var m;const r=this.editor.viewport.vis;this.obj=yield r.lead.draw(this.objectType,Ji(q0({},this.objectOptions),{key:`${this.id}`})),this.obj.userData.updateKey!==!1&&r.lead.updateBaseObjectKey(this.obj,`$t:_${this.id}`),this.addObjectUuid=this.obj.key,this.editor.select(this.obj.key),(m=this.editor.viewport.vis)==null||m.initBaseObjectUserData(this.obj)})}undo(){this.obj.erase(),this.editor.select(null)}toJSON(){const r=super.toJSON();return r.objectType=this.objectType,r.objectOptions=this.objectOptions,r.addObjectUuid=this.addObjectUuid,r}fromJSON(r){super.fromJSON(r),this.objectType=r.objectType,this.objectOptions=r.objectOptions,this.addObjectUuid=r.addObjectUuid}fixJSON(){const r=this.json;r&&!r.addObjectUuid&&(r.addObjectUuid=this.addObjectUuid)}}class RemoveObject extends Command{constructor(r,m){super(r);C0(this,"object");C0(this,"objectUuid");this.type="RemoveObject",this.name="Remove Object",this.object=m,this.objectUuid=this.editor.uuidByBaseObject(m)}execute(){this.editor.playing?this.object.erase():(this.object.hide(),this.object.userData.selectHide=!0,this.object.mList.rmBaseObjectMap(this.object)),this.editor.emit("baseObjectListChange"),this.editor.select(null)}undo(){return U0(this,null,function*(){this.object.show(),this.object.mList.addBaseObjectMap(this.object),delete this.object.userData.selectHide,this.editor.emit("baseObjectListChange")})}toJSON(){const r=super.toJSON();return r.objectUuid=this.objectUuid,r}fromJSON(r){super.fromJSON(r),this.object=this.editor.baseObjectByUuid(r.objectUuid)}}class CopyObject extends Command{constructor(r,m){super(r);C0(this,"object");C0(this,"copyObject",null);C0(this,"copyObjectUuid");C0(this,"mListUuid",[]);this.type="CopyObject",this.name="Copy Object",this.object=m}execute(){return U0(this,null,function*(){var C;const r=this.editor.viewport.vis,m=this.object.key,v=yield this.object.instantiate({key:`${this.id}`});this.copyObject=v,v.userData.updateKey!==!1&&r.lead.updateBaseObjectKey(v,`${m}_${this.id}`),this.copyObjectUuid=v.key,this.editor.select(this.copyObjectUuid),(C=this.editor.viewport.vis)==null||C.initBaseObjectUserData(v)})}undo(){return U0(this,null,function*(){var r;(r=this.copyObject)==null||r.erase(),this.editor.select(null)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.editor.uuidByBaseObject(this.object),r.copyObjectUuid=this.copyObjectUuid,r.mListUuid=this.mListUuid,r}fromJSON(r){super.fromJSON(r),this.object=this.editor.baseObjectByUuid(r.objectUuid),this.copyObjectUuid=r.copyObjectUuid,this.mListUuid=r.mListUuid}fixJSON(){const r=this.json;if(r&&!r.copyObjectUuid&&(r.copyObjectUuid=this.copyObjectUuid),r){const m=this.object.object3d.material;if(m){const v=Array.isArray(m)?m:[m];r.mListUuid=v.map(C=>this.editor.pencil.mList.getKey(C)).filter(Boolean),r.mListUuid.length&&console.log("fixJSON CopyObject mListUuid",r.mListUuid)}}}}class AddMaterial extends Command{constructor(r,m){super(r);C0(this,"materialType");C0(this,"flag",!1);C0(this,"addObjectUuid");this.type="AddMaterial",this.name="Add Material",this.materialType=m}execute(){return U0(this,null,function*(){this.addObjectUuid=`material_${this.id}`;const r=this.editor.pencil.mList;let m;if(this.materialType.startsWith("k:")){const v=this.materialType.match(/k:([^|]+)\|s:([^|]+)/);if(v){const C=v[1],_=v[2],w=this.editor.pencil.lead.getObject(C);if(w){const I=w.object3d;m=Array.isArray(I.material)?I.material[+_]:I.material,this.flag=!0}else console.warn(`Base object with key ${C} not found.`),m=new MeshBasicMaterial}else console.warn(`Material type ${this.materialType} is not valid.`),m=new MeshBasicMaterial}else this.materialType==="MeshLineMaterial"?m=new We$1({color:new Color$1(16777215),lineWidth:1,sizeAttenuation:0}):m=new THREE[this.materialType];m.name=`材质_${this.id}`,r.add(this.addObjectUuid,m),this.flag&&this.editor.emit("materialChanged")})}undo(){return U0(this,null,function*(){this.editor.pencil.mList.remove(this.addObjectUuid),this.flag&&this.editor.emit("materialChanged")})}toJSON(){const r=super.toJSON();return r.materialType=this.materialType,r.addObjectUuid=this.addObjectUuid,r}fromJSON(r){super.fromJSON(r),this.materialType=r.materialType,this.addObjectUuid=r.addObjectUuid}}class CopyMaterial extends Command{constructor(r,m){super(r);C0(this,"objectUuid");C0(this,"copyObjectUuid");this.type="CopyMaterial",this.name="Copy Material",this.objectUuid=m}execute(){return U0(this,null,function*(){this.copyObjectUuid=`material_${this.id}`,this.editor.pencil.mList.copy(this.objectUuid,this.copyObjectUuid,{name:`材质_${this.id}`})})}undo(){return U0(this,null,function*(){this.editor.pencil.mList.remove(this.copyObjectUuid)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.objectUuid,r.copyObjectUuid=this.copyObjectUuid,r}fromJSON(r){super.fromJSON(r),this.objectUuid=r.objectUuid||r.materialKey||r.originKey,this.copyObjectUuid=r.copyObjectUuid||r.copyKey}fixJSON(){const r=this.json;r&&!r.objectUuid&&(r.objectUuid=r.objectUuid||r.materialKey||r.originKey),r&&!r.copyObjectUuid&&(r.copyObjectUuid=r.copyObjectUuid||r.copyKey)}}class RemoveMaterial extends Command{constructor(r,m){super(r);C0(this,"objectUuid");C0(this,"material");this.type="RemoveMaterial",this.name="Remove Material",this.objectUuid=m}execute(){return U0(this,null,function*(){const r=this.editor.pencil.mList;this.material=r.get(this.objectUuid),r.remove(this.objectUuid)})}undo(){return U0(this,null,function*(){const r=this.editor.pencil.mList;this.material&&r.add(this.objectUuid,this.material)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.objectUuid,r}fromJSON(r){super.fromJSON(r),this.objectUuid=r.objectUuid||r.materialKey}fixJSON(){const r=this.json;r&&!r.objectUuid&&(r.objectUuid=r.objectUuid||r.materialKey)}}class SetObjectMaterial extends Command{constructor(r,m,v,C){var w;super(r);C0(this,"object");C0(this,"oldValue");C0(this,"newValue");C0(this,"materialSlot");this.type="SetObjectMaterial",this.name="Set Object Material",this.object=m,this.materialSlot=v;const _=this.editor.getObjectMaterial(m,v);this.oldValue=(w=this.editor.pencil)==null?void 0:w.mList.getKey(_),this.newValue=C}execute(){return U0(this,null,function*(){const r=this.editor.pencil.mList;r.get(this.newValue)&&(this.editor.setObjectMaterial(this.object,this.materialSlot,r.get(this.newValue)),this.editor.emit("materialChanged",this.object))})}undo(){return U0(this,null,function*(){const r=this.editor.pencil.mList;this.editor.setObjectMaterial(this.object,this.materialSlot,r.get(this.oldValue)),this.editor.emit("materialChanged",this.object)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.editor.uuidByObject(this.object),r.oldValue=this.oldValue,r.newValue=this.newValue,r.materialSlot=this.materialSlot,r}fromJSON(r){super.fromJSON(r),this.object=this.editor.objectByUuid(r.objectUuid),this.oldValue=r.oldValue,this.newValue=r.newValue,this.materialSlot=r.materialSlot}}class SetSetting extends Command{constructor(r,m,v){super(r);C0(this,"attributeName");C0(this,"newValue");C0(this,"oldValue");this.type="SetSetting",this.updatable=!0,this.name=`Set Setting.${m}`,this.attributeName=m,this.newValue=v,r.viewport.vis&&(this.oldValue=r.viewport.vis.settings[m])}execute(){return U0(this,null,function*(){const r=this.editor.viewport.vis;r.settings[this.attributeName]=this.newValue,yield r.settings[this.attributeName],this.editor.emit("settingsChanged")})}undo(){return U0(this,null,function*(){const r=this.editor.viewport.vis;r.settings[this.attributeName]=this.oldValue,yield r.settings[this.attributeName],this.editor.emit("settingsChanged")})}update(r){this.newValue=r.newValue}toJSON(){const r=super.toJSON();return r.name=this.name,r.attributeName=this.attributeName,r.newValue=this.newValue,r.oldValue=this.oldValue,r}fromJSON(r){super.fromJSON(r),this.name=r.name,this.attributeName=r.attributeName||r.name,this.newValue=r.newValue,this.oldValue=r.oldValue}}class SetTarget extends Command{constructor(t,r,m,v,C){super(t),this.type="SetTarget",this.name="Set Target",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&m!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=m.clone()),v!==void 0&&(this.oldPosition=v.clone())}execute(){this.cameraControls?this.cameraControls.setTarget(this.newPosition.x,this.newPosition.y,this.newPosition.z,!1):(this.object.target.copy(this.newPosition),this.object.target.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}undo(){this.cameraControls?this.cameraControls.setTarget(this.oldPosition.x,this.oldPosition.y,this.oldPosition.z,!1):(this.object.target.copy(this.oldPosition),this.object.target.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}update(t){this.newPosition.copy(t.newPosition)}toJSON(){var r;const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldPosition=(r=this.oldPosition)==null?void 0:r.toArray(),t.newPosition=this.newPosition.toArray(),t.cameraControls=!!this.cameraControls,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldPosition&&(this.oldPosition=new Vector3().fromArray(t.oldPosition)),this.newPosition=new Vector3().fromArray(t.newPosition),t.cameraControls&&(this.cameraControls=this.editor.pencil.controls)}}class SetSceenMap extends SetMaterialMap{constructor(t,r,m,v,C){super(t),this.type="SetSceenMap",this.name="Set Sceen.background",this.object=r,this.materialSlot=C,this.material=r!==void 0?r[C]:void 0,this.oldMap=r!==void 0?this.material[m]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=m}fromJSON(t){super.fromJSON(t),this.oldMap=this.object[this.materialSlot][this.mapName],this.material=this.object[this.materialSlot]}}class SetGeometry extends Command{constructor(t,r=null,m){super(t),this.type="SetGeometry",this.name="Set Geometry",this.updatable=!0,this.object=r,this.oldGeometry=r!==null?r.geometry:null,this.newGeometry=m||null}execute(){this.object.geometry.dispose(),this.object.geometry=this.newGeometry,this.object.geometry.computeBoundingSphere(),this.editor.emit("geometryChanged",this.object)}undo(){this.object.geometry.dispose(),this.object.geometry=this.oldGeometry,this.object.geometry.computeBoundingSphere(),this.editor.emit("geometryChanged",this.object)}update(t){this.newGeometry=t.newGeometry}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.newGeometry=this.geometryToJSON(this.newGeometry),t}geometryToJSON(t){return t?t.type==="MeshLine"?{type:"MeshLine",points:t.points,variableWidth:!!t.widthCallback}:t.toJSON():void 0}parseGeometry(t){if(!t)return;if(t.type==="MeshLine"){const v=new Be$1;return v.setPoints(t.points,t.variableWidth?C=>C:void 0),v}return new ObjectLoader().parseGeometries([t])[t.uuid]}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.oldGeometry=((r=this.object)==null?void 0:r.geometry)||null,this.newGeometry=this.parseGeometry(t.newGeometry)}}const Commands=Object.freeze(Object.defineProperty({__proto__:null,AddMaterial,AddObject,AddVis,CopyMaterial,CopyObject,RemoveMaterial,RemoveObject,SetColor,SetGeometry,SetMaterial,SetMaterialColor,SetMaterialMap,SetMaterialMapVector,SetMaterialValue,SetMaterialVector,SetObjectMaterial,SetPosition,SetRotation,SetScale,SetSceenMap,SetSetting,SetTarget,SetValue,SetVector},Symbol.toStringTag,{value:"Module"})),encodings="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function encodeArrayBufferToUrlSafeBase64(g){let t="";const r=new Uint8Array(g),m=r.byteLength,v=m%3,C=m-v;let _,w,I,O,Pe;for(let Ne=0;Ne<C;Ne=Ne+3)Pe=r[Ne]<<16|r[Ne+1]<<8|r[Ne+2],_=(Pe&16515072)>>18,w=(Pe&258048)>>12,I=(Pe&4032)>>6,O=Pe&63,t+=encodings[_]+encodings[w]+encodings[I]+encodings[O];return v===1?(Pe=r[C],_=(Pe&252)>>2,w=(Pe&3)<<4,t+=encodings[_]+encodings[w]):v===2&&(Pe=r[C]<<8|r[C+1],_=(Pe&64512)>>10,w=(Pe&1008)>>4,I=(Pe&15)<<2,t+=encodings[_]+encodings[w]+encodings[I]),t}function charCodeToNumber(g){if(g>=65&&g<=90)return g-65;if(g>=97&&g<=122)return g-71;if(g>=48&&g<=57)return g+4;if(g===45)return 62;if(g===95)return 63;throw new Error("Invalid char code in url safe base64: "+g)}function decodeUrlSafeBase64ToArrayBuffer(g){const t=g.length%4;let r=0,m=0,v=0;if(t===0)r=g.length/4*3,m=g.length;else{if(t===1)throw new Error("invalid url safe base64 encoded string: "+g);t===2?(r=(g.length-2)/4*3,m=g.length-2,v=1):(r=(g.length-3)/4*3,m=g.length-3,v=2)}let C;const _=new Uint8Array(r+v);let w,I,O,Pe;for(let Ne=0,Fe=0;Ne<m;Ne+=4,Fe+=3)w=charCodeToNumber(g.charCodeAt(Ne)),I=charCodeToNumber(g.charCodeAt(Ne+1)),O=charCodeToNumber(g.charCodeAt(Ne+2)),Pe=charCodeToNumber(g.charCodeAt(Ne+3)),C=(w<<18)+(I<<12)+(O<<6)+Pe,_.set([(C&16711680)>>16,(C&65280)>>8,C&255],Fe);return t===2?(w=charCodeToNumber(g.charCodeAt(m)),I=charCodeToNumber(g.charCodeAt(m+1)),C=(w<<2)+(I>>4),_.set([C&255],r)):t===3&&(w=charCodeToNumber(g.charCodeAt(m)),I=charCodeToNumber(g.charCodeAt(m+1)),O=charCodeToNumber(g.charCodeAt(m+2)),C=(w<<10)+(I<<4)+(O>>2),_.set([(C&65280)>>8,C&255],r)),_.buffer}class History{constructor(t){C0(this,"editor");C0(this,"undos");C0(this,"redos");C0(this,"lastCmdTime");C0(this,"idCounter");C0(this,"historyDisabled");this.editor=t,this.undos=[],this.redos=[],this.lastCmdTime=Date.now(),this.idCounter=0,this.historyDisabled=!1}execute(t,r){return U0(this,null,function*(){const m=this.undos[this.undos.length-1],v=Date.now()-this.lastCmdTime;m&&m.updatable&&t.updatable&&m.object===t.object&&m.objectUuid===t.objectUuid&&m.type===t.type&&m.attributeName===t.attributeName&&m.attributeName2===t.attributeName2&&m.name===t.name&&m.materialSlot===t.materialSlot&&v<500?(m.update(t),t=m):(this.undos.push(t),t.id=++this.idCounter),t.name=r!==void 0?r:t.name;try{yield t.execute()}catch(_){console.error(_,t)}t.json=t.toJSON(),this.lastCmdTime=Date.now(),this.redos=[],this.editor.emit("historyChanged",t)})}undo(){if(this.historyDisabled)return;let t;if(this.undos.length>0&&(t=this.undos.pop()),t!==void 0){if(!t.name){console.log("压缩配置,不支持 undo"),this.undos.push(t);return}t.undo(),this.redos.push(t),this.editor.emit("historyChanged",t)}return t}redo(){if(this.historyDisabled)return;let t;return this.redos.length>0&&(t=this.redos.pop()),t!==void 0&&(t.execute(),this.undos.push(t),this.editor.emit("historyChanged",t)),t}toJSON(){var r,m,v;const t={u:[],i:[]};for(let C=0;C<this.undos.length;C++)if(this.undos[C].hasOwnProperty("json")){const _=this.undos[C].json;if((r=_.newMap)!=null&&r.images||(m=_.newMaterial)!=null&&m.images){const w=(v=_.newMap)!=null&&v.images?"newMap":"newMaterial";t.u.push(Ji(q0({},_),{[w]:Ji(q0({},_[w]),{images:_[w].images.map(I=>{var Ne;if(typeof I.url!="string")if(((Ne=I.url)==null?void 0:Ne.type)==="Uint16Array"){const Fe=encodeArrayBufferToUrlSafeBase64(new Uint16Array(I.url.data).buffer);I._url=q0({},I.url),delete I._url.data,I.url=Fe}else return q0({},I);const O=t.i.findIndex(Fe=>Fe===I.url);let Pe=I.url;return O===-1?(t.i.push(I.url),Pe=`$rp-${t.i.length-1}`):Pe=`$rp-${O}`,Ji(q0({},I),{url:Pe})})})}))}else t.u.push(q0({},_))}return t}fromJSON(t){var v,C,_;if(t===void 0)return;let r=-1;const m=t.i;for(let w=0;w<t.u.length;w++){const I=t.u[w];if(m!=null&&m.length&&((v=I.newMap)!=null&&v.images||(C=I.newMaterial)!=null&&C.images)){const Pe=(_=I.newMap)!=null&&_.images?"newMap":"newMaterial";I[Pe].images.forEach(Ne=>{if(typeof Ne.url=="string"&&Ne.url.startsWith("$rp-")){const Fe=parseInt(Ne.url.replace("$rp-",""));Ne._url?(Ne.url=Ji(q0({},Ne._url),{data:decodeUrlSafeBase64ToArrayBuffer(m[Fe])}),delete Ne._url):Ne.url=m[Fe]}})}if(I.id<=r){console.error("历史记录id错误");continue}if(I.type==="SetOption"||!I.type)continue;I.type.endsWith("Command")&&(I.type=I.type.replace("Command",""));const O=new Commands[I.type](this.editor);O.json=I,O.id=I.id,O.name=I.name,this.undos.push(O),this.idCounter=I.id>this.idCounter?I.id:this.idCounter,r=I.id}this.editor.emit("historyChanged",this.undos[this.undos.length-1])}processUndos(t=1e3/60){return new Promise((r,m)=>{const v=[...this.undos],C=v.length;let _=0;const w=()=>U0(this,null,function*(){const I=performance.now();for(;v.length>0&&performance.now()-I<t;){if(this.editor._dispose){m("dispose");return}const O=v.shift(),Pe=this.editor.hooks.events.beforeExecuteUndo.length?this.editor.hooks.dispatch("beforeExecuteUndo",O):O;Pe&&(yield this.executeUndo(Pe)),this.editor.hooks.events.afterExecuteUndo.length&&this.editor.hooks.dispatch("afterExecuteUndo",O),_+=1}this.editor.emit("progress",{type:"还原场景",value:_/C*100|0}),v.length>0?requestAnimationFrame(w):r("")});requestAnimationFrame(w)})}executeUndo(t){return U0(this,null,function*(){t.fromJSON(t.json);try{!["AddObject","CopyMaterial","RemoveMaterial"].includes(t.json.type)&&t.json.objectUuid&&!t.object||(yield t.execute(),this.editor.playing||t.fixJSON())}catch(r){console.error(r,t)}})}clear(){this.undos.length=0,this.redos.length=0,this.idCounter=0,this.editor.emit("historyChanged",this.undos[this.undos.length-1])}}class Hooks{constructor(t){C0(this,"editor");C0(this,"events",{beforeSetVisOptions:[],beforeExecuteUndo:[],afterExecuteUndo:[],beforeShow:[],afterShow:[],beforeFromJSON:[],afterFromJSON:[],errorFromJSON:[]});C0(this,"source","");this.editor=t,this.addEvents({beforeFromJSON:()=>{window.postMessage({type:"vis-core.fromJSON.start"}),console.time("vis-core:time.fromJSON")},afterFromJSON:()=>{window.postMessage({type:"vis-core.fromJSON.end"}),console.timeEnd("vis-core:time.fromJSON")},errorFromJSON:()=>{window.postMessage({type:"vis-core.fromJSON.error"}),console.timeEnd("vis-core:time.fromJSON")}})}addEvents(t){var r;for(const m in t){const v=m;this.events[v]&&this.events[v].push(t[v].bind(t)),v==="afterShow"&&((r=this.editor.viewport.vis)==null?void 0:r.showState)===!0&&t[v](this.editor.viewport.vis)}}addStaticEvents(t){this.addEvents(t());const r=t.toString().replace(/\/\/.*?(?:\r\n|\n|\r|$)/g,"").replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s+/gm,"").replace(/(\r\n|\n|\r)/gm,"").trim();this.source!==r&&(this.source=r,this.editor.emit("scriptsChanged"))}fromJSON(t){if(!t)this.source="";else try{const r=new Function(`return ${t}()`)();this.addEvents(r),this.source=t}catch(r){console.error(r)}this.editor.emit("scriptsChanged")}toJSON(){return this.source}clear(){Object.keys(this.events).forEach(t=>{this.events[t]=[]})}dispatch(t,...r){let m;for(const v of this.events[t])if(t==="beforeSetVisOptions"?m=v(m!=null?m:r[0]):m=v(this.editor.viewport.vis,...r),m===!1)break;return m}}class Viewport{constructor(t,r){C0(this,"editor");C0(this,"vis");C0(this,"extendsOptions",{});C0(this,"cameraState",{});C0(this,"delLoadObj");C0(this,"options");this.options=r,this.editor=t}setSaveCamera(t){var r,m;this.vis.setSaveCamera(t),(r=this.vis.pencil.controls)==null||r.saveState(),this.cameraState=q0({},(m=this.vis)==null?void 0:m.cameraState),this.editor.emit("cameraStateChanged")}addVis(m){return U0(this,arguments,function*(t,r={}){this.replaceVis()&&(yield this.editor.execute(new AddVis(this.editor,t,r)))})}replaceVis(){if(this.vis){const t=window.confirm("将删除所有记录,是否继续?");return t&&this.dispose(),t}return!0}setVis(m){return U0(this,arguments,function*(t,r={}){if(!this.options.visFactories&&(this.editor.setViewportVis(t),!this.options.visFactories)){console.error("visFactories is not defined");return}if(this.vis=this.options.visFactories,this.vis.visName!==t)throw new Error(`visName is not match, import {${t}}`);let v=q0(q0({},r),this.extendsOptions);v=this.editor.hooks.events.beforeSetVisOptions.length?this.editor.hooks.dispatch("beforeSetVisOptions",v):v,this.vis.setOptions(v),this.vis.cameraState=q0({},this.cameraState),this.delLoadObj&&(this.vis.delLoadArr=this.delLoadObj),this.vis.playing=this.editor.playing,this.vis._baseObjectByUuid=this.editor.baseObjectByUuid.bind(this.editor),this.vis._objectByUuid=this.editor.objectByUuid.bind(this.editor),this.vis.on("loaderProgress",(_,w)=>{this.editor.emit("progress",{type:"下载资源",value:_/w*100|0})}),this.vis.on("settingsChanged",()=>{this.editor.emit("settingsChanged")}),this.vis.on("show",()=>{this.editor.changeSelectOption(),this.editor.emit("visShow",!0)}),yield this.vis.init();const{pencil:C}=this.vis;C.userData.EditorEnv=!this.editor.playing,this.editor.pencil=C,this.editor.changeSelectOption(),this.editor.changeMListOptions(),this.editor.playing||(this.initEvent(),this.editor.emit("visChanged",this.vis)),this.editor.on("baseObjectListChange",()=>{this.editor.changeSelectOption()}),this.editor.on("mListChange",()=>{this.editor.changeMListOptions()}),C.event.on("lead.updateKey",()=>{this.editor.emit("baseObjectListChange")}),C.event.on("lead.draw",()=>{this.editor.emit("baseObjectListChange")}),C.event.on("lead.erase",()=>{this.editor.emit("baseObjectListChange")}),C.event.on("mList.add",()=>{this.editor.emit("mListChange")}),C.event.on("mList.remove",()=>{this.editor.emit("mListChange")}),C.event.on("mList.addBaseObjectMap",()=>{this.editor.emit("mListChange")}),C.event.on("mList.rmBaseObjectMap",()=>{this.editor.emit("mListChange")})})}setResetCameraUp(){var _,w,I;const r=((_=this.vis)==null?void 0:_.pencil.lead.group).getSize(),m=(r.max.x+r.min.x)/2,v=(r.max.y+r.min.y)/2,C=(w=this.vis)==null?void 0:w.pencil.cameraPositon.z;(I=this.vis)==null||I.pencil.controls.setLookAt(m,v,C,m,v,0,!0)}initEvent(){var r,m,v,C;const{pencil:t}=this.vis;t.controls.addEventListener("update",()=>{this.editor.emit("refreshSidebarObject3D",t.camera)}),(r=t.transformController)==null||r.event.on("change",_=>{this.editor.emit("refreshSidebarObject3D",_)}),(m=t.transformController)==null||m.event.on("translate",(_,w,I)=>{this.editor.execute(new SetPosition(this.editor,_,w,I))}),(v=t.transformController)==null||v.event.on("rotate",(_,w,I)=>{this.editor.execute(new SetRotation(this.editor,_,w,I))}),(C=t.transformController)==null||C.event.on("scale",(_,w,I)=>{this.editor.execute(new SetScale(this.editor,_,w,I))})}addObj(m){return U0(this,arguments,function*(t,r={}){const v=objs$3[t].getInitOptions;v&&Object.assign(r,v(this.vis.pencil,r)),yield this.editor.execute(new AddObject(this.editor,t,r))})}removeObj(t){return U0(this,null,function*(){const{vis:r}=this;if(!r)return;const m=this.editor.baseObjectByUuid(t);this.editor.execute(new RemoveObject(this.editor,m))})}copyObj(t){return U0(this,null,function*(){const{vis:r}=this;if(!r)return;const m=this.editor.baseObjectByUuid(t);this.editor.execute(new CopyObject(this.editor,m))})}addMListMaterial(t="MeshBasicMaterial"){return U0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new AddMaterial(this.editor,t))})}removeMListMaterial(t){return U0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new RemoveMaterial(this.editor,t))})}copyMListMaterial(t){return U0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new CopyMaterial(this.editor,t))})}setExtendsOptions(t,r){this.extendsOptions[t]=r,this.vis.extendsOptions[t]=r,this.editor.emit("optionsChanged"),setTimeout(()=>{const m=this.editor.toJSON();this.dispose(),this.editor.fromJSON(m)})}toJSON(){var r;const t=(r=this.vis)==null?void 0:r.loader.getUnusedAssets();return{eo:this.extendsOptions,cs:this.cameraState,delLoadObj:t}}fromJSON(t){this.extendsOptions=t.eo||{},this.cameraState=t.cs||{},t.delLoadObj&&t.delLoadObj.length&&(this.delLoadObj=[...t.delLoadObj])}getLoadObj(){return this.vis?[...this.vis.loader.assets.keys()].filter(r=>this.vis.loader.delLoadArr.indexOf(r)===-1):[]}setTransformControlsModal(t){var m;const{pencil:r}=this.vis;(m=r.transformController)==null||m.controls.setMode(t)}dispose(){var t;this.editor.emit("visShow",!1),(t=this.vis)==null||t.dispose(),this.options.visFactories=void 0,this.extendsOptions={},this.cameraState={},this.delLoadObj=void 0,this.vis=void 0,this.editor.history.clear()}}class Editor{constructor(t){C0(this,"selected",null);C0(this,"playing",!0);C0(this,"currentMaterialSlot",0);C0(this,"events",new events.EventEmitter);C0(this,"history");C0(this,"viewport");C0(this,"hooks");C0(this,"config");C0(this,"pencil");C0(this,"on",this.events.on.bind(this.events));C0(this,"emit",this.events.emit.bind(this.events));C0(this,"options");C0(this,"selectOption",[]);C0(this,"mListOptions",[]);C0(this,"_dispose",!1);this.options=q0({assetsPrefix:"",processUndosMaxFrameTime:Number.MAX_VALUE},t),this.events.setMaxListeners(9999999),this.viewport=new Viewport(this,{visFactories:t.visFactories}),this.history=new History(this),this.hooks=new Hooks(this),this.config=new Config(this),this.config.setConfig("sdkVersion",version)}getObjectMaterial(t,r){if(!t)return;let m=t.material;return Array.isArray(m)&&r!==void 0&&(m=m[r]),m}getMListFixBaseObjectByObject(t,r){var v;const m=this.getObjectMaterial(t,r);return m?((v=this.findMListSelectItem("material",m))==null?void 0:v.object)||t:null}materialObjectByUuid(t){const r=this.findMListSelectItem("key",t);return r?r.object:this.objectByUuid(t)}uuidByMaterialObject(t){const r=this.findMListSelectItem("object",t);return r?r.key:this.uuidByObject(t)}setObjectMaterial(t,r,m){let v=t.material;Array.isArray(t.material)&&r!==void 0?(v=t.material[r],t.material[r]=m):t.material=m,v!=null&&v.onBeforeCompile&&(m.onBeforeCompile=v.onBeforeCompile),v!=null&&v.name&&!m.name&&(m.name=v.name),m instanceof We$1&&(m.resolution=new Vector2(this.pencil.renderer.domElement.width,this.pencil.renderer.domElement.height))}uuidByObject(t){var r;return(r=this.findSelectItem(this.selectOption,"object",t))==null?void 0:r.key}objectByUuid(t){var r;return(r=this.findSelectItem(this.selectOption,"key",t))==null?void 0:r.object}uuidByBaseObject(t){var r;return(r=this.findSelectItem(this.selectOption,"baseObject",t))==null?void 0:r.key}baseObjectByUuid(t){var r;return(r=this.findSelectItem(this.selectOption,"key",t))==null?void 0:r.baseObject}findSelectItem(t,r,m){for(let v=0;v<t.length;v++){const C=t[v];if(C[r]===m)return C;if(C.children){const _=this.findSelectItem(C.children,r,m);if(_)return _}}}changeSelectOption(){const t=this.viewport.vis,r=m=>m.filter(v=>v.userData.selectHide!==!0).map(v=>{const C=[...v.children];if(v.key||console.warn("baseObject.key is empty, this may cause issues in the editor.",v),v.object3d.target){const De=v.options.type;C.unshift({key:v.key.replace(De,De+"Target"),object3d:v.object3d.target,userData:{disabledC:!0,disabledR:!0,disabledTC:v.userData.disabledTC},children:[]})}if(v.object3d.isDirectionalLight&&v.object3d.castShadow){const De=v.options.type;C.unshift({key:v.key.replace(De,De+"Shadow"),object3d:v.object3d.shadow.camera,userData:{disabledC:!0,disabledR:!0,disabledTC:!0},children:[]})}const w=C.length>0?r(C):[],I=v.object3d.isGroup,O=I||["@Scene","@Camera"].includes(v.key)||v.userData.disabledC||v.key.includes("__c__"),Pe=["@Scene","@Camera"].includes(v.key)||v.userData.disabledR||v.key.includes("__c__");if(w.length===0&&I)return null;const Ne=v.key.replace(v.key[0],v.key[0].toLowerCase()),Fe=["@Scene","@Camera"].includes(v.key)||v.userData.disabledTC,Ae=["@Scene","@Camera"].includes(v.key);return{key:Ne==="@Scene"?"scene":Ne==="@Camera"?"camera":Ne,name:v.object3d.name,object:v.object3d,visible:Ae?!0:v.object3d.visible,useMaterialType:v.useMaterialType,disabledC:O,disabledR:Pe,disabledTC:Fe,disabledVisible:Ae,baseObject:v,children:w}}).filter(v=>v!==null);this.selectOption=r([t.lead.scene]),this.emit("sceneGraphChanged")}findMListSelectItem(t,r){return this.mListOptions.find(m=>m[t]===r)}changeMListOptions(){if(!this.pencil)return[];this.mListOptions=Array.from(this.pencil.mList.fixBaseObjects.entries()).map(([t,r])=>{const m=this.pencil.mList.get(t);return{key:t,name:m.name,type:m.type,object:r.object3d,baseObject:r,material:m,use:this.pencil.mList.getBaseObjectMap(m).size}}),this.emit("mListGraphChanged")}execute(t,r){return U0(this,null,function*(){yield this.history.execute(t,r)})}fromJSON(t,r){return U0(this,null,function*(){var m,v,C,_;try{r&&!f$1(r)?console.warn("fromJSON 第二个参数已修改,{beforeSetVisOptions:(r)=>r} 替代"):r&&this.hooks.addEvents(r);let w;if(typeof t=="string"){const I=this.options.assetsPrefix+t;console.time("vis-core:time.json-fetch");const{res:O,err:Pe}=yield jsonFetch(I);if(console.timeEnd("vis-core:time.json-fetch"),Pe)throw new Error("fromJSON error:"+Pe);w=O}else w=t;if(this.hooks.dispatch("beforeFromJSON"),w=fixJSON(w),w.at&&(accessToken.token=w.at),!this.storage){if(!accessToken.token)throw new Error("设置 token 或平台重新下载 JSON 文件");const I=accessToken.getInfo();if(!I||!I.isValid)throw new Error("need accessToken")}if(this.config.fromJSON(w.c),this.history.fromJSON(w.h),this.viewport.fromJSON(w.v),this.hooks.fromJSON(w.s),this.config.compareVersion(),yield this.history.processUndos(this.options.processUndosMaxFrameTime),(m=w.v.bg)!=null&&m.texture&&this.viewport.vis){const I=parseTexture(w.v.bg.texture);I.colorSpace=SRGBColorSpace,this.viewport.vis.pencil.scene.background=I}return this.hooks.dispatch("beforeShow"),(v=this.viewport.vis)==null||v.show(),this.hooks.dispatch("afterShow"),(C=this.pencil.controls)==null||C.saveState(),this.select(null),(_=this.viewport.vis)!=null&&_.workerOnce&&this.playing&&window.requestIdleCallback(()=>{var I;(I=this.viewport.vis)==null||I.worker.dispose()}),this.hooks.dispatch("afterFromJSON"),w}catch(w){throw this.hooks.dispatch("errorFromJSON"),new Error("fromJSON error:"+w)}})}toJSON(){return{}}select(...t){}setViewportVis(...t){}getDataURL(){return this.pencil?(this.pencil.render(),this.pencil.renderer.domElement.toDataURL()):""}dispose(){this.events.removeAllListeners(),this.viewport.dispose(),this.history.clear(),this.hooks.clear(),this._dispose=!0}}const getScale=g=>{const r=window.getComputedStyle(g).transform;if(r&&r!=="none"){const m=new DOMMatrix(r);return Math.max(m.a,m.d)}};function observeScale(g,t){let r=g,m=1;for(;r;){const I=getScale(r);if(I!==void 0){m=I;break}if(r=r.parentElement,r===document.body){r=null;break}}if(!r)return null;const v=I=>{const O=getScale(r)||1;m!==O&&(m=O,t(O,I))},C=I=>{I.propertyName==="transform"&&v("transitionEnd")},_=new MutationObserver(I=>{for(const O of I)if(O.type==="attributes"&&O.attributeName==="style"){v("MutationObserver");return}});_.observe(r,{attributes:!0,attributeFilter:["style"]}),r.addEventListener("transitionend",C),t(m,"init");const w=_.disconnect;return _.disconnect=function(){w.call(_),r==null||r.removeEventListener("transitionend",C)},_}class Event{constructor(){C0(this,"event",new events.EventEmitter);C0(this,"eventHandlers",{});C0(this,"on",this.event.on.bind(this.event));C0(this,"emit",this.event.emit.bind(this.event))}addListener(t,r,m,v=!1){r in this.eventHandlers||(this.eventHandlers[r]=[]),this.eventHandlers[r].push({node:t,handler:m,capture:v}),t.addEventListener(r,m,v)}removeListener(t,r){this.eventHandlers[r].filter(({node:m})=>t?m===t:!0).forEach(({node:m,handler:v,capture:C})=>m.removeEventListener(r,v,C)),this.eventHandlers[r]=this.eventHandlers[r].filter(({node:m})=>t?m!==t:!1)}removeAllListeners(){Object.keys(this.eventHandlers).forEach(t=>{this.removeListener("",t)}),this.eventHandlers={}}dispose(){this.removeAllListeners(),this.event.removeAllListeners()}}class Camera extends Event{constructor(){super(...arguments);C0(this,"container");C0(this,"pencil");C0(this,"cameraState",{})}setSaveCamera(r){const m=this.pencil,v=m.cameraPositon,C=m.cameraTarget;this.cameraState[r]=[v.x,v.y,v.z,C.x,C.y,C.z]}useSaveCamera(r,m=!1){return U0(this,null,function*(){const v=this.cameraState[r];return v?(yield this.lookAt(v[0],v[1],v[2],v[3],v[4],v[5],m),!0):!1})}lookAt(r,m,v,C,_,w,I=!1,O=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=O/1e3,yield this.pencil.controls.setLookAt(r,m,v,C,_,w,I),this.pencil.controls.smoothTime=250/1e3})}truck(r,m,v=!1,C=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=C/1e3,this.pencil.controls.restThreshold=0,yield this.pencil.controls.truck(r,m,v),this.pencil.controls.restThreshold=.0025,this.pencil.controls.smoothTime=250/1e3})}dollyTo(r,m=!1,v=250){return U0(this,null,function*(){let C=r;if(typeof C=="string"){const[_,w]=C.split("=");_==="+"?C=this.pencil.controls.distance+ +w:_==="-"?C=this.pencil.controls.distance-+w:_==="*"?C=this.pencil.controls.distance*+w:_==="/"?C=this.pencil.controls.distance/+w:console.error("dollyTo distance error")}this.pencil.controls.smoothTime=v/1e3,yield this.pencil.controls.dollyTo(C,m),this.pencil.controls.smoothTime=250/1e3})}absoluteAngle(r,m){const v=Math.PI*2,C=r-m;return MathUtils.euclideanModulo(C+Math.PI,v)-Math.PI}lookAtTarget(r,m=!1,v=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=v/1e3;const C=this.pencil.controls.azimuthAngle,_=this.pencil.controls.polarAngle,w=this.pencil.controls.distance,I=this.pencil.cameraTarget.clone(),O=r.azimuthAngle||C,Pe=r.polarAngle||_,Ne=r.distance||w,Fe=r.target||I;yield Promise.all([this.pencil.controls.moveTo(Fe.x,Fe.y,Fe.z,m),this.pencil.controls.dollyTo(Ne,m),this.pencil.controls.rotateTo(C+this.absoluteAngle(O,C),_+this.absoluteAngle(Pe,_),m)]),this.pencil.controls.smoothTime=250/1e3})}paddingInCssPixel(r,m,v,C,_,w){const{camera:I,controls:O}=this.pencil,Pe=I.fov*MathUtils.DEG2RAD,Ne=this.pencil.getSize().height,{size:Fe}=r.getSize(),Ae=Fe.x,De=Fe.y,xt=Fe.z;let je=O.getDistanceToFitBox(Ae,De,xt),ke=0,at=0,ct=0,Gt=0;for(let Lt=0;Lt<10;Lt++){const Wt=je-xt*.5,Pt=2*Math.tan(Pe*.5)*Math.abs(Wt)/Ne;ke=m*Pt,at=C*Pt,ct=_*Pt,Gt=v*Pt,je=O.getDistanceToFitBox(Ae+ct+Gt,De+ke+at,xt)}return O.fitToBox(r.object3d,w,{paddingLeft:ct,paddingRight:Gt,paddingBottom:at,paddingTop:ke})}resetCamera(r=!1,m=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=m/1e3,yield this.pencil.controls.reset(r),this.pencil.controls.smoothTime=250/1e3})}unproject(r,m=0){const v=new Vector3,C=new Vector3,{left:_,top:w,width:I,height:O}=this.container.getBoundingClientRect(),Pe=(r.clientX-_)/I*2-1,Ne=-((r.clientY-w)/O)*2+1,Fe=this.pencil.cameraPositon.clone();v.set(Pe,Ne,.5),v.unproject(this.pencil.camera),v.sub(Fe).normalize();const Ae=(m-Fe.z)/v.z;return C.copy(Fe).add(v.multiplyScalar(Ae)),C}dispose(){super.dispose(),this.cameraState={}}}const IS_DEV=!1;class Base extends Camera{constructor(r){var m;super();C0(this,"playing",!0);C0(this,"leftTruck",!0);C0(this,"options");C0(this,"showState",!1);C0(this,"settings",{});C0(this,"delLoadArr");C0(this,"extendsOptions",{});C0(this,"leadObjs",objs$3);C0(this,"lead");C0(this,"mList");C0(this,"workerOnce",!0);C0(this,"tier0",!1);C0(this,"pmremGenerator",null);C0(this,"re",null);C0(this,"roomEnvMap");C0(this,"visName");C0(this,"editor");C0(this,"publicDir",{});C0(this,"_baseObjectByUuid");C0(this,"_objectByUuid");C0(this,"observeScale",null);C0(this,"sceneActive",-1);C0(this,"initSettingsObj");C0(this,"mouseButtonsActiveStore",null);if(this.container=r.container,this.options=q0({assetsPrefix:"",editor:!0,logarithmicDepthBuffer:!0,observeParentScale:!0},r),!this.options.assetsPrefix){let v="/";v==="/"&&(v=""),this.options.assetsPrefix=v}this.options.workerOnce!==void 0&&(this.workerOnce=this.options.workerOnce);try{const v=window.location.search.match(/v_ldb=(\d+)/);if(v){const C=!!+v[1];this.options.logarithmicDepthBuffer=C}}catch(v){console.error(v)}if(this.options.editor){const v=detect();let C=(m=this.options.tier)!=null?m:v.tier;try{const _=window.location.search.match(/v_tier=(\d+)/);_&&(C=+_[1])}catch(_){console.error(_)}this.tier0=C!==3,this.editor=new Editor({assetsPrefix:this.options.assetsPrefix,visFactories:this}),console.info("vis-core:detect",version,JSON.stringify(Ji(q0({},v),{ldb:this.options.logarithmicDepthBuffer,tier0:this.tier0}),null,2))}this.visName=this.constructor.VisName}get loader(){return this.pencil.loader}get worker(){return this.pencil.installPlugins.get("worker")}setOptions(r){this.options=q0(q0({},this.options),r)}get fromJSON(){return this.editor.fromJSON.bind(this.editor)}get baseObjectByUuid(){var r;return((r=this.editor)==null?void 0:r.baseObjectByUuid.bind(this.editor))||this._baseObjectByUuid}get objectByUuid(){var r;return((r=this.editor)==null?void 0:r.objectByUuid.bind(this.editor))||this._objectByUuid}get getDataURL(){return this.editor.getDataURL.bind(this.editor)}loaderAdd(...r){}initMaterial(...r){return U0(this,null,function*(){})}initVis(...r){return U0(this,null,function*(){})}init(...r){return U0(this,null,function*(){yield this.initPencil(),this.loaderAdd(),console.time(`vis-core:time.${this.visName}-loader`),yield this.loader.loadAll(),console.timeEnd(`vis-core:time.${this.visName}-loader`),yield this.initMaterial(),yield this.initVis(),yield Promise.all(this.lead.objectsPromise)})}initPencil(){return U0(this,null,function*(){var v,C,_,w,I,O,Pe,Ne;if(this.pencil)return;const r=q0({},this.options.pencilConfig);if(this.options.css2DContainer&&(r.css2DRendererParams={container:this.options.css2DContainer}),this.options.pencil)this.pencil=this.options.pencil,this.pencil.stop(),this.sceneActive=this.pencil.addPage({cameraOptions:{fov:(C=(v=r.camera)==null?void 0:v.fov)!=null?C:45,near:(w=(_=r.camera)==null?void 0:_.near)!=null?w:.1,far:(O=(I=r.camera)==null?void 0:I.far)!=null?O:1e3,up:(Ne=(Pe=r.camera)==null?void 0:Pe.up)!=null?Ne:new Vector3(0,1,0)},sceneOptions:{background:new Color$1(0)}}),this.setSceneActive();else if(this.options.pencil2){this.pencil=this.options.pencil2,this.lead=this.pencil.lead.init(this.leadObjs),this.mList=this.pencil.mList,this.sceneActive=this.pencil.pageActiveIndex;return}else{const Fe=new ot(q0(Ji(q0({container:this.container,stats:!this.playing&&IS_DEV,helper:!this.playing,viewHelper:!this.playing,transformControls:!this.playing,css2DRenderer:!0},this.tier0?{composer:{multisampling:0}}:{}),{renderer:{alpha:!0,logarithmicDepthBuffer:this.options.logarithmicDepthBuffer},camera:{near:.1,far:1e3,fov:45,up:new Vector3(0,1,0)},bloom:!0,ssao:!0,ssaoParams:{minDistance:.001},scene:{background:new Color$1(0)},loader:q0({prefix:this.options.assetsPrefix,simpleTexture4deleted:!0},this.tier0?{anisotropy:1}:{})}),r));if(this.options.observeParentScale&&this.playing){const xt=()=>{this.observeScale||(this.observeScale=observeScale(this.container,(je,ke)=>{Fe.setDevicePixelRatio(window.devicePixelRatio*je)}))};xt(),Fe.event.on("resize",()=>{xt()})}if(this.tier0){const xt=new Map;Fe.event.on("beforeRender",()=>{Fe.scene.traverse(je=>{const ke=je;if(ke.material){const at=ke.material;(Array.isArray(at)?at:[at]).forEach(Gt=>{!xt.has(Gt)&&Gt.name&&(xt.set(Gt,Gt.name),Gt.name="")})}})}),Fe.event.on("render",()=>{[...xt.keys()].forEach(je=>{const ke=xt.get(je);ke&&(je.name=ke)}),xt.clear()})}this.pencil=Fe,this.sceneActive=1;const Ae=Fe.composerController.ssaoPass;Ae&&(Ae.enabled=!1);const De=new Q({dbName:this.visName,cacheVersion:version});Fe.use(De),this.playing||(window.vis=this,window.pencil=Fe)}const m=this.pencil;this.lead=m.lead.init(this.leadObjs),this.mList=m.mList,this.delLoadArr&&(m.loader.delLoadArr=this.delLoadArr),m.loader.on("progress",(...Fe)=>{this.showState!==!0&&this.emit("loaderProgress",...Fe)}),this.leftTruck&&(m.controls.mouseButtons.left=Gi.TRUCK,m.controls.mouseButtons.right=Gi.ROTATE),this.lead.group.hide(),this.lead.prefabGroup.hide(),this.initSceneUserData(),this.initCameraUserData(),this.initSettings()})}setSceneActive(){this.pencil.showPage(this.sceneActive)}initCameraUserData(){const r=this.pencil;r.camera.userData=new Proxy({up:r.camera.up.toArray().join(",")},{set:(m,v,C)=>{if(v==="up"){const _=C.split(",").map(w=>+w);r.camera.up.fromArray(_),r.controls.updateCameraUp()}return Reflect.set(m,v,C)}})}initSceneUserData(){var w,I,O,Pe,Ne,Fe;const r=this.pencil,m=r.scene.background,v=m instanceof Color$1?"Color":m instanceof Texture?"Texture":"None",C=v==="Texture"?m:null,_=v==="Color"?"#"+m.getHexString():"#000000";r.scene.userData=new Proxy({backgroundType:v,backgroundColor:_,backgroundTexture:C,shadowMapEnabled:this.pencil.renderer.shadowMap.enabled,shadowMapType:this.pencil.renderer.shadowMap.type,bloomThreshold:(I=(w=this.pencil.composerController)==null?void 0:w.bloomPass)==null?void 0:I.threshold,bloomRadius:(Pe=(O=this.pencil.composerController)==null?void 0:O.bloomPass)==null?void 0:Pe.radius,bloomStrength:(Fe=(Ne=this.pencil.composerController)==null?void 0:Ne.bloomPass)==null?void 0:Fe.strength},{set:(Ae,De,xt)=>(De==="shadowMapEnabled"||De==="shadowMapType"?(De==="shadowMapEnabled"?this.pencil.renderer.shadowMap.enabled=xt:De==="shadowMapType"&&(this.pencil.renderer.shadowMap.type=xt),this.pencil.scene.traverse(je=>{const ke=je;if(ke.receiveShadow&&ke.material){const at=ke.material;Array.isArray(at)?at.forEach(ct=>{ct.needsUpdate=!0}):at.needsUpdate=!0}})):De==="backgroundType"?xt==="None"?r.scene.background=null:r.scene.userData.backgroundColor?r.scene.background=new Color$1(r.scene.userData.backgroundColor):r.scene.userData.backgroundTexture&&(r.scene.background=r.scene.userData.backgroundTexture):De==="backgroundColor"?r.scene.background=new Color$1(xt):De==="backgroundTexture"?r.scene.background=xt:De==="bloomThreshold"?r.composerController.bloomPass&&(r.composerController.bloomPass.threshold=xt):De==="bloomRadius"?r.composerController.bloomPass&&(r.composerController.bloomPass.radius=xt):De==="bloomStrength"&&r.composerController.bloomPass&&(r.composerController.bloomPass.strength=xt),Reflect.set(Ae,De,xt))})}initBaseObjectUserData(r){const m=Ji(q0({},r.object3d.userData),{bloom:!1});if(r.objectType==="BaseObject#Light")return;const v=r.objectType==="BaseObject#Arc",C=r.objectType==="BaseObject#Line",_=r.object3d instanceof Group$1;v?m.animationDuration=2e3:C&&(m.animationDuration=0),prefabType.includes(r.objectType.split("#")[1])&&(m.prefab=r.prefab),r.object3d.userData=new Proxy(m,{set:(w,I,O)=>(I==="bloom"?O?r.enableBloom():r.disableBloom():I==="prefab"?(r.prefab=O,O?this.lead.prefabGroup.attach(r):this.lead.group.attach(r)):I==="animationDuration"&&v?r.animateIn({duration:O}):I==="animationDuration"&&(C||_)&&(C?[r]:r.children).forEach(Ne=>{Ne.material.userData.tween&&(Ne.material.userData.tween.stop(),remove(Ne.material.userData.tween),Ne.material.userData.tween=null),O&&(Ne.material.uniforms.offset.value.x=1,Ne.material.uniforms.offsetLoop.value=1,Ne.animate({duration:O,repeat:1/0,lineLoop:!0,startShow:!0}))}),Reflect.set(w,I,O))})}addCSS3DRenderer(){this.pencil&&this.pencil.cssRendererController.addRenderer("css3d",{container:this.pencil.cssRendererController.container,zIndex:"auto"})}initSettings(){const r={mouseLeft:this.pencil.controls.mouseButtons.left,mouseRight:this.pencil.controls.mouseButtons.right,mouseWheel:this.pencil.controls.mouseButtons.wheel};this.settings=new Proxy(Ji(q0(q0({},this.initSettingsObj),r),{mouseNone:!1,viewportPadding:[0,0,0,0]}),{set:(m,v,C)=>{if(!(v in m)&&!(v.replace(/(:::.+)\..*$/,"$1")in m))return Reflect.set({},v,C);v==="mouseWheel"?typeof C=="boolean"&&(C=C?r.mouseWheel:Gi.NONE):v==="mouseLeft"?typeof C=="boolean"&&(C=C?r.mouseLeft:Gi.NONE):v==="mouseRight"&&typeof C=="boolean"&&(C=C?r.mouseRight:Gi.NONE);const _=v.includes(":::");return Reflect.set(m,_?v.replace(/(:::.+)\..*$/,"$1"):v,this.handleSetting(v,C))},get:(m,v)=>{const _=v.includes(":::")?v.replace(/(:::.+)\..*$/,"$1"):v,w=Reflect.get(m,_);return w instanceof Promise?w.then(I=>(Reflect.set(m,_,I),I)):w}})}handleSetting(r,m){return U0(this,null,function*(){const{pencil:v}=this;if(r==="mouseWheel"||r==="mouseLeft"||r==="mouseRight"){const C=r.replace("mouse","").toLowerCase();(m||this.playing)&&(v.controls.mouseButtons[C]=m)}else r==="mouseNone"?m?(this.mouseButtonsActiveStore={mouseLeft:v.controls.mouseButtons.left,mouseRight:v.controls.mouseButtons.right,mouseWheel:v.controls.mouseButtons.wheel},v.controls.mouseButtons.left=Gi.NONE,v.controls.mouseButtons.right=Gi.NONE,v.controls.mouseButtons.wheel=Gi.NONE):this.mouseButtonsActiveStore&&(v.controls.mouseButtons.left=this.mouseButtonsActiveStore.mouseLeft,v.controls.mouseButtons.right=this.mouseButtonsActiveStore.mouseRight,v.controls.mouseButtons.wheel=this.mouseButtonsActiveStore.mouseWheel):r==="viewportPadding"&&v.setViewPadding(...m);return m})}show(){this.showState||(this.useSaveCamera("visShow"),this.options.disableInitShow||this.showAction())}showAction(){this.showState||(this.lead.group.show(),this.playing||this.lead.prefabGroup.show(),this.pencil.start(),this.showState=!0,this.emit("show"))}hide(){this.showState&&(this.lead.group.hide(),this.lead.prefabGroup.hide(),this.showState=!1,this.emit("hide"))}addCSS2D(v){return U0(this,arguments,function*(r,m={}){typeof m=="string"&&(m={display:m}),m.display&&(r.style.display=m.display);let C=0;typeof m.onTop!="undefined"&&(C=m.onTop);const _=yield this.lead.draw("Node",{onTop:C});return _.setChildren(r),_})}addCSS3D(v){return U0(this,arguments,function*(r,m={}){m.display&&(r.style.display=m.display);let C=0;typeof m.onTop!="undefined"&&(C=m.onTop);let _="3d";typeof m.type!="undefined"&&(_=m.type);const w=yield this.lead.draw("Node",{onTop:C,type:_});return w.setChildren(r),w})}getRoomEnvMap(){if(this.roomEnvMap)return this.roomEnvMap;const r=new PMREMGenerator(this.pencil.renderer);r.compileEquirectangularShader();const m=new RoomEnvironment,v=r.fromScene(m,.04).texture;return this.pmremGenerator=r,this.re=m,this.roomEnvMap=v,v}handlePick(r,m,v){console.warn("handlePick is deprecated, use BaseObject.onPointerEvent"),this.lead.handlePick(r,m,v)}getScreenPosition(r,m,v){const C=new Vector3(r,m,v);C.project(this.pencil.camera);const{width:_,height:w}=this.pencil.getSize(),I=(C.x*.5+.5)*_,O=(C.y*-.5+.5)*w;return{x:I,y:O}}dispose(){var r,m,v,C;super.dispose(),this.editor&&(this.editor.viewport.vis=void 0,this.editor.dispose()),this.publicDir={},this.options.pencil?this.pencil.removePage(this.sceneActive):this.options.pencil2||(r=this.pencil)==null||r.dispose(),(m=this.pmremGenerator)==null||m.dispose(),(v=this.re)==null||v.dispose(),(C=this.observeScale)==null||C.disconnect()}}C0(Base,"VisName","base");function clipGeojson(g,t){const r=turf.flatten(g).features,m=turf.flatten(t).features,v={type:"FeatureCollection",features:[]};for(let C=r.length-1;C>=0;C--){const _=r[C];for(let w=m.length-1;w>=0;w--){const I=m[w];if(contains(_,I))v.features.push(I);else if(contains(I,_))_.properties=I.properties,v.features.push(_);else{const O=turf.intersect(_,I);O&&(O.properties=I.properties,v.features.push(O))}}}return v}function contains(g,t){let r=!0;const m=turf.explode(t).features;for(let v=m.length-1;v>=0;v--)if(!turf.inside(m[v],g)){r=!1;break}return r}const getBoxMultiPoly=g=>{const t=g.features.map(r=>r.geometry.type==="Polygon"?[r.geometry.coordinates]:r.geometry.coordinates).flat();return Array.from({length:t.length},(r,m)=>turf.polygon(t[m]))};class Building extends ht{constructor(r){super();C0(this,"options");C0(this,"building",{});C0(this,"outJson",new Map);C0(this,"worldPositionZ",{value:0});this.options=q0({},r)}create(){return U0(this,null,function*(){const{json:r,projection:m,cacheKey:v,meters:C,grey:_,clip:w}=this.options,I=this.pencil.mList,O=this.pencil.getPlugin("worker"),Pe=this.pencil.lead,Ne=_?"-grey":"";this.createGroup();const Fe=I.getMultiple("building"+Ne);let Ae=v?yield O.getCachedGeometry({cacheKey:v}):[];if(Ae.length)w&&this.outJson.set(1,!0);else{let De;w&&(De=getBoxMultiPoly(w));const xt={};(r.features||r).forEach(ke=>{const at=typeof ke.properties.h=="string"?ke.properties.h.split(".")[1]:0,ct=Number(ke.properties.h)|0;xt[at]||(xt[at]={}),xt[at][ct]||(xt[at][ct]=[]),De?De.some(Lt=>{ke.geometry.coordinates[1]&&console.log(ke.geometry.coordinates[1]);const Wt=turf.polygon(ke.geometry.coordinates[0]);return turf.booleanContains(Lt,Wt)?(xt[at][ct].push(ke),!0):!1})||this.outJson.set(ke,!1):xt[at][ct].push(ke)});const je=Object.keys(xt).map(ke=>{const at=xt[ke];return Object.keys(at).map(ct=>{const Gt=at[ct];return{z:+ke,h:+ct,coordinatesArr:Gt.map(Lt=>Lt.geometry.type==="Polygon"?Lt.geometry.coordinates[0]:Lt.geometry.coordinates[0][0])}})}).flat().filter(ke=>ke.coordinatesArr.length);Ae=yield Promise.all(je.map(ke=>{const{h:at,z:ct,coordinatesArr:Gt}=ke,Lt=+at<=20?+at/18:+at<=60?+at/27:+at/12;return O.geoGeometry("extrudePolygon",{cacheKey:v,userData:{z:ct,h:at},mesaage:{coordinatesArr:Gt,projection:m,useGroups:2,depth:[Number(at)*(C||1)],hasBottom:!1,sideRepeat:Lt}})}))}yield Promise.all(Ae.map(De=>U0(this,null,function*(){const{h:xt,z:je}=De.userData,ke=xt+je,at=ke<=20?"20":ke<=60?"60":"max";let ct=this.options.material;ct||(ct=[Fe[at+"Top"],Fe[at+"Side"]]);const Gt=yield Pe.draw("ExtrudePolygon",{key:`$p:-${xt}-${je}`,geometry:De,material:ct},this);this.options.grey||(Gt.object3d.castShadow=!0),this.building[xt]||(this.building[xt]=[]),this.building[xt].push(Gt),Gt.position.z=Number(je)*(C||1)}))),this.options.sideGradient&&this.sideGradient(),this.object3d.name="建筑",_||this.lead.updateBaseObjectKey(this,`building${Ne?"-grey":""}#group`)})}sideGradient(r="#052438",m=.05/100){this.traverse(v=>{if(v instanceof is){const C=v.object3d.material;C[1].onBeforeCompile=_=>{_.uniforms.gradientColor={value:new Color$1(r)},_.uniforms.maxGradientHeight={value:m},_.uniforms.worldPositionZ=this.worldPositionZ,_.vertexShader=`
|
|
4855
|
+
`,defines:{}}),"baseTexture");return t.needsSwap=!0,t},zs=new MeshBasicMaterial({color:"black"}),ks=new PointsMaterial({color:"black",sizeAttenuation:!1}),Fs=new PointsMaterial({color:"black",sizeAttenuation:!0}),Ns=new SpriteMaterial({color:"black",sizeAttenuation:!0}),js=new SpriteMaterial({color:"black",sizeAttenuation:!1}),Is=new We$1({color:"black",sizeAttenuation:0,lineWidth:0}),Hs={kernelRadius:8,minDistance:.005,maxDistance:.1},Bs={threshold:0,strength:.4,radius:.1,bloomAlphaType:0},Vs={multisampling:4,premultiplieAlpha:!1};class Ys{constructor(t){this.bloomComposerActive=!1,this.active=!0,this.bloomSelection=new Set,this.bloomLayer=new Layers,this.bloomMaterials={},this.bloomVisible={},this.bloomComposerRenderIng=!1,this.pipViewportState=null,this.options=t;const{rendererController:r,sceneController:m,cameraController:v,composerParams:C}=t,{renderer:_}=r;this.renderer=_;const{multisampling:w}=C,{maxSamples:I}=_.capabilities,O=_.getDrawingBufferSize(new Vector2),Pe=new WebGLRenderTarget(O.width,O.height,{samples:Math.min(w,I),type:HalfFloatType}),Ne=new EffectComposer(_,Pe),Fe=this.getSize();Ne.setSize(Fe.width,Fe.height);const Ae=new RenderPass(m.scene,v.camera);Ne.addPass(Ae),this.scene=m.scene,this.camera=v.camera,this.finalComposer=Ne,this.renderPass=Ae,v.event.on("pageChange",De=>{this.changeCamera(De)}),m.event.on("pageChange",De=>{this.changeScene(De)})}changeCamera(t){this.renderPass.camera=t,this.camera=t}changeScene(t){this.renderPass.scene=t,this.ssaoPass&&(this.ssaoPass.scene=t),this.scene=t}addOutputPass(){const{premultiplieAlpha:t}=this.options.composerParams,r=new Ds;this.outputPass=r,this.setPremultiplieAlpha(t),this.finalComposer.addPass(r)}setPremultiplieAlpha(t){this.outputPass&&(this.outputPass.uniforms.premultiplieAlpha.value=t?1:0)}addSSAOPass(t){const{scene:r,camera:m,renderer:v}=this,C=v.getSize(new Vector2),_=C.width,w=C.height,I=new SSAOPass(r,m,_,w);I.kernelRadius=t.kernelRadius,I.minDistance=t.minDistance,I.maxDistance=t.maxDistance,this.ssaoPass=I,this.finalComposer.addPass(I)}addBloomPass(t){const{renderer:r}=this,{threshold:m,strength:v,radius:C,bloomAlphaType:_}=t,w=new UnrealBloomPass(new Vector2(window.innerWidth,window.innerHeight),v,C,m);this.bloomPass=w;const I=new EffectComposer(r);I.renderToScreen=!1,I.addPass(this.renderPass),I.addPass(w),this.bloomComposer=I;const O=Us(I);O.uniforms.bloomAlphaType.value=_,this.bloomComposer=I,this.finalComposer.addPass(O),this.mixPass=O,this.bloomLayer.set(Te$1)}setBloomSelection(t,r){if(!this.bloomComposer){console.warn("err:pencil.options.bloom");return}t.traverse(m=>{const{object3d:v}=m;v&&(r?(this.bloomSelection.add(m),v.layers.enable(Te$1)):(this.bloomSelection.delete(m),v.layers.disable(Te$1)))}),this.bloomSelection.size===0?this.bloomComposerActive=!1:this.bloomComposerActive=!0}enable(){this.active||(this.active=!0)}disable(){this.active&&(this.active=!1)}setSize(t,r){var m;(m=this.bloomComposer)==null||m.setSize(t,r),this.finalComposer.setSize(t,r)}setPixelRatio(t){var r;(r=this.bloomComposer)==null||r.setPixelRatio(t),this.finalComposer.setPixelRatio(t)}darkenNonBloomed(){const t=[],r=[];this.scene.children.forEach(m=>{m.isTransformControls||m.isTransformControlsRoot||m.type==="RectAreaLightHelper"?t.push(m):r.push(m)}),r.forEach(m=>{m.traverse(v=>{var C;const _=v,w=v,I=v;(C=_.material)!=null&&C.isShadowMaterial?t.push(_):_.material&&this.bloomLayer.test(_.layers)===!1&&(this.bloomMaterials[_.uuid]=_.material,w.isSprite?w.material.sizeAttenuation?w.material=Ns:w.material=js:_.material instanceof We$1?_.material=Is:I.isPoints?I.material.sizeAttenuation?I.material=Fs:I.material=ks:_.material=zs)})}),t.forEach(m=>{this.bloomVisible[m.uuid]=m.visible,m.visible=!1})}restoreNonBloomed(){this.scene.traverse(t=>{const r=t;this.bloomMaterials[r.uuid]?(r.material=this.bloomMaterials[r.uuid],delete this.bloomMaterials[r.uuid]):this.bloomVisible[r.uuid]!==void 0&&(r.visible=this.bloomVisible[r.uuid],delete this.bloomVisible[r.uuid])})}finalComposerRender(){this.bloomComposerActive&&this.bloomComposer?(this.bloomComposerRenderIng=!0,this.mixPass.enabled=!0,this.darkenNonBloomed(),this.bloomComposer.render(),this.restoreNonBloomed(),this.bloomComposerRenderIng=!1):this.mixPass&&(this.mixPass.enabled=!1),this.finalComposer.render()}getSize(){return this.renderer.getSize(new Vector2)}render(){if(!this.active)return;const{cameraController:t,rendererController:r,sceneController:m}=this.options;if(this.finalComposerRender(),this.pipViewportState){t.setPageActive(31),t.setAspect(this.pipViewportState.width/this.pipViewportState.height),r.setViewport(te(U({},this.pipViewportState),{scissor:!0,scissorTest:!0})),this.finalComposerRender(),t.setPageActive(m.activeIndex);const v=this.getSize();r.setViewport({x:0,y:0,width:v.width,height:v.height,scissor:!0,scissorTest:!1})}}dispose(){var t;this.bloomMaterials={},this.bloomVisible={},this.bloomSelection.clear(),this.finalComposer.dispose(),(t=this.bloomComposer)==null||t.dispose()}}class Zs extends ee{constructor(t){super(),this.autoRotateSpeed=0,this.options=t;const r={Vector2,Vector3,Vector4,Quaternion,Matrix4,Spherical,Box3,Sphere:Sphere$1,Raycaster};J$1.install({THREE:r})}get cameraControls(){return this.controller}addCameraControls(t,r){const{domElement:m}=this.options.controlsParams,v=new J$1(t,m);return v.setLookAt(0,0,400,0,0,0,!1),this.addController(v,r)}setPageActive(t){super.setPageActive(t,(r,m)=>{r.enabled=m})}removePage(t){super.removePage(t,r=>{r.dispose()})}enable(){this.activeControllerSet.forEach(t=>{t.enabled=!0})}disable(){this.activeControllerSet.forEach(t=>{t.enabled=!1})}update(t,r){super.update(t,r),this.autoRotateSpeed&&this.cameraControls&&(this.cameraControls.azimuthAngle+=this.autoRotateSpeed*t*MathUtils.DEG2RAD)}}const Xe=new Vector3,Ws=new Quaternion,qe=new Vector3,j=new Matrix4,Ks=new Matrix4;class $s{constructor(t={}){const r=this;let m,v,C,_;const w={camera:{style:""},objects:new WeakMap},I=t.element!==void 0?t.element:document.createElement("div");I.style.overflow="hidden",this.domElement=I;const O=document.createElement("div");O.style.transformOrigin="0 0",O.style.pointerEvents="none",I.appendChild(O);const Pe=document.createElement("div");Pe.style.transformStyle="preserve-3d",O.appendChild(Pe),this.getSize=function(){return{width:m,height:v}},this.render=function(je,ke){const at=ke.projectionMatrix.elements[5]*_;ke.view&&ke.view.enabled?(O.style.transform=`translate( ${-ke.view.offsetX*(m/ke.view.width)}px, ${-ke.view.offsetY*(v/ke.view.height)}px )`,O.style.transform+=`scale( ${ke.view.fullWidth/ke.view.width}, ${ke.view.fullHeight/ke.view.height} )`):O.style.transform="",je.matrixWorldAutoUpdate===!0&&je.updateMatrixWorld(),ke.parent===null&&ke.matrixWorldAutoUpdate===!0&&ke.updateMatrixWorld();let ct,Gt;ke.isOrthographicCamera&&(ct=-(ke.right+ke.left)/2,Gt=(ke.top+ke.bottom)/2);const Lt=ke.view&&ke.view.enabled?ke.view.height/ke.view.fullHeight:1,Wt=ke.isOrthographicCamera?`scale( ${Lt} )scale(`+at+")translate("+Ne(ct)+"px,"+Ne(Gt)+"px)"+Fe(ke.matrixWorldInverse):`scale( ${Lt} )translateZ(`+at+"px)"+Fe(ke.matrixWorldInverse),Pt=(ke.isPerspectiveCamera?"perspective("+at+"px) ":"")+Wt+"translate("+C+"px,"+_+"px)";w.camera.style!==Pt&&(Pe.style.transform=Pt,w.camera.style=Pt),xt(je,je,ke)},this.setSize=function(je,ke){m=je,v=ke,C=m/2,_=v/2,I.style.width=je+"px",I.style.height=ke+"px",O.style.width=je+"px",O.style.height=ke+"px",Pe.style.width=je+"px",Pe.style.height=ke+"px"};function Ne(je){return Math.abs(je)<1e-10?0:je}function Fe(je){const ke=je.elements;return"matrix3d("+Ne(ke[0])+","+Ne(-ke[1])+","+Ne(ke[2])+","+Ne(ke[3])+","+Ne(ke[4])+","+Ne(-ke[5])+","+Ne(ke[6])+","+Ne(ke[7])+","+Ne(ke[8])+","+Ne(-ke[9])+","+Ne(ke[10])+","+Ne(ke[11])+","+Ne(ke[12])+","+Ne(-ke[13])+","+Ne(ke[14])+","+Ne(ke[15])+")"}function Ae(je){const ke=je.elements;return"translate(-50%,-50%)"+("matrix3d("+Ne(ke[0])+","+Ne(ke[1])+","+Ne(ke[2])+","+Ne(ke[3])+","+Ne(-ke[4])+","+Ne(-ke[5])+","+Ne(-ke[6])+","+Ne(-ke[7])+","+Ne(ke[8])+","+Ne(ke[9])+","+Ne(ke[10])+","+Ne(ke[11])+","+Ne(ke[12])+","+Ne(ke[13])+","+Ne(ke[14])+","+Ne(ke[15])+")")}function De(je){je.isCSS3DObject&&(je.element.style.display="none");for(let ke=0,at=je.children.length;ke<at;ke++)De(je.children[ke])}function xt(je,ke,at,ct){if(je.visible===!1){De(je);return}if(je.isCSS3DObject){const Gt=je.layers.test(at.layers)===!0,Lt=je.element;if(Lt.style.display=Gt===!0?"":"none",Gt===!0){je.onBeforeRender(r,ke,at);let Wt;je.isCSS3DSprite?(j.copy(at.matrixWorldInverse),j.transpose(),je.rotation2D!==0&&j.multiply(Ks.makeRotationZ(je.rotation2D)),je.matrixWorld.decompose(Xe,Ws,qe),j.setPosition(Xe),j.scale(qe),j.elements[3]=0,j.elements[7]=0,j.elements[11]=0,j.elements[15]=1,Wt=Ae(j)):Wt=Ae(je.matrixWorld);const Pt=w.objects.get(je);if(Pt===void 0||Pt.style!==Wt){Lt.style.transform=Wt;const zt={style:Wt};w.objects.set(je,zt)}Lt.parentNode!==Pe&&Pe.appendChild(Lt),je.onAfterRender(r,ke,at)}}for(let Gt=0,Lt=je.children.length;Gt<Lt;Gt++)xt(je.children[Gt],ke,at)}}}const q=new Vector3,Qe=new Matrix4,Je=new Matrix4,et=new Vector3,tt=new Vector3;class Gs{constructor(t={}){const r=this;let m,v,C,_;const w={objects:new WeakMap},I=t.element!==void 0?t.element:document.createElement("div");I.style.overflow="hidden",this.domElement=I,this.getSize=function(){return{width:m,height:v}},this.render=function(De,xt){De.matrixWorldAutoUpdate===!0&&De.updateMatrixWorld(),xt.parent===null&&xt.matrixWorldAutoUpdate===!0&&xt.updateMatrixWorld(),Qe.copy(xt.matrixWorldInverse),Je.multiplyMatrices(xt.projectionMatrix,Qe),Pe(De,De,xt),Ae(De)},this.setSize=function(De,xt){m=De,v=xt,C=m/2,_=v/2,I.style.width=De+"px",I.style.height=xt+"px"};function O(De){De.isCSS2DObject&&(De.element.style.display="none");for(let xt=0,je=De.children.length;xt<je;xt++)O(De.children[xt])}function Pe(De,xt,je){if(De.visible===!1){O(De);return}if(De.isCSS2DObject){q.setFromMatrixPosition(De.matrixWorld),q.applyMatrix4(Je);const ke=q.z>=-1&&q.z<=1&&De.layers.test(je.layers)===!0,at=De.element;at.style.display=ke===!0?"":"none",ke===!0&&(De.onBeforeRender(r,xt,je),at.style.transform="translate("+-100*De.center.x+"%,"+-100*De.center.y+"%)translate("+(q.x*C+C)+"px,"+(-q.y*_+_)+"px)",at.parentNode!==I&&I.appendChild(at),De.onAfterRender(r,xt,je));const ct={distanceToCameraSquared:Ne(je,De)};w.objects.set(De,ct)}for(let ke=0,at=De.children.length;ke<at;ke++)Pe(De.children[ke],xt,je)}function Ne(De,xt){return et.setFromMatrixPosition(De.matrixWorld),tt.setFromMatrixPosition(xt.matrixWorld),et.distanceToSquared(tt)}function Fe(De){const xt=[];return De.traverseVisible(function(je){je.isCSS2DObject&&xt.push(je)}),xt}function Ae(De){const xt=Fe(De).sort(function(ke,at){if(ke.renderOrder!==at.renderOrder)return at.renderOrder-ke.renderOrder;const ct=w.objects.get(ke).distanceToCameraSquared,Gt=w.objects.get(at).distanceToCameraSquared;return ct-Gt}),je=xt.length;for(let ke=0,at=xt.length;ke<at;ke++)xt[ke].element.style.zIndex=je-ke}}}const st={zIndex:"auto"};class Xs{constructor(t){this.container=t}addRenderer(t,r){const m=r.container||this.container,v=m.offsetWidth,C=m.offsetHeight,_=t==="css2d"?new Gs:new $s;_.domElement.style.position="absolute",_.domElement.style.top="0",_.domElement.style.pointerEvents="none",_.domElement.style.zIndex=r.zIndex,_.setSize(v,C),m.appendChild(_.domElement),t==="css2d"?this.css2Drenderer=_:t==="css3d"&&(this.css3Drenderer=_)}setSize(t,r){var m,v;(m=this.css2Drenderer)==null||m.setSize(t,r),(v=this.css3Drenderer)==null||v.setSize(t,r)}render(t,r){var m,v;(m=this.css2Drenderer)==null||m.render(t,r),(v=this.css3Drenderer)==null||v.render(t,r)}dispose(){var t,r;(t=this.css2Drenderer)==null||t.domElement.remove(),(r=this.css3Drenderer)==null||r.domElement.remove(),this.css2Drenderer=void 0,this.css3Drenderer=void 0}}class qs{constructor(t){this.helpers={},this.options=t}add(t){const r=t.uuid,{sceneController:m}=this.options;let v=this.helpers[r];if(v===void 0){if(t.isScene)v=new AxesHelper(100);else if(t.isCamera)v=new CameraHelper(t);else if(t.isPointLight)v=new PointLightHelper(t,1);else if(t.isDirectionalLight)v=new DirectionalLightHelper(t,1);else if(t.isSpotLight)v=new SpotLightHelper(t);else if(t.isHemisphereLight)v=new HemisphereLightHelper(t,10);else if(t.isRectAreaLight)v=new RectAreaLightHelper(t);else{const C=new Box3;if(C.setFromObject(t,!0),C.isEmpty()===!1){v=new Box3Helper(C);const _=v.material;_.userData.object=t,_.depthTest=!1,_.transparent=!0}else return}m.scene.add(v),this.helpers[r]=v}}addViewHelper(){const{cameraController:t,container:r}=this.options,m=new ViewHelper(t.camera,r);r.addEventListener("pointerdown",v=>{v.preventDefault(),m.handleClick(v)}),this.viewHelper=m}remove(t){var r;const m=t.uuid,{sceneController:v}=this.options;if(this.helpers[m]!==void 0){const C=this.helpers[m];v.scene.remove(C),delete this.helpers[m],(r=C.dispose)==null||r.call(C)}}removeAll(){Object.keys(this.helpers).forEach(t=>{this.remove({uuid:t})}),this.helpers={}}removeAllExcludeScene(){Object.keys(this.helpers).forEach(t=>{this.helpers[t]instanceof AxesHelper||this.remove({uuid:t})})}update(t,r,m){var v,C;const{cameraController:_}=this.options;Object.values(this.helpers).forEach(w=>{if(w.update&&w.update(),w instanceof Box3Helper){const I=w.material,{object:O}=I.userData;O&&w.box.setFromObject(O,!0)}}),((v=this.viewHelper)==null?void 0:v.animating)===!0&&(this.viewHelper.update(t),(C=r.cameraControls)==null||C.setPosition(..._.camera.position.toArray()),this.viewHelper.center.copy(m))}renderViewHelper(t){if(!this.viewHelper)return;const r=t.autoClear;t.autoClear=!1,this.viewHelper.render(t),t.autoClear=r}dispose(){var t;this.helpers={},(t=this.viewHelper)==null||t.dispose()}}function it(g){let t=!1,r=[];return function(...m){r=m,t||(t=!0,requestAnimationFrame(()=>{t=!1,g(...r)}))}}class Qs{constructor(t){var r;this.enabled=!0,this.pickFunctionsMap=new Map,this.pickNodeFunctionsMap=new Map,this.pickFunctionsMapIndex=-1,this.pickNodeFunctionsMapIndex=-1,this.activeObjects=new Set,this.activeObject=null,this.prevActiveObjects=new Set,this.objCallbackMap=new Map,this.pickListener={move:!1,down:!1},this.pencil=t,this.domElement=((r=t.options.controls)==null?void 0:r.domElement)||t.options.container}addPickListener(t){const r=new Set(["move","enter","leave"]),m=new Set(["down","downOutside","click"]),v=C=>{var _;if(!this.enabled)return;C.preventDefault();const w=t==="move"?r:m,I=[];if(this.pickFunctionsMap.forEach(Ae=>{w.has(Ae.type)&&I.push(te(U({},Ae),{objArr:Ae.objArr instanceof Function?Ae.objArr():Ae.objArr}))}),I.length===0)return;this.activeObjects.clear(),this.objCallbackMap.clear(),this.activeObject=null;const O=this.objCallbackMap;for(const Ae of I)for(const De of Ae.objArr){if(!De.object3d||!De.visibleWithAncestors)continue;O.has(De)||O.set(De,new Map);const xt=O.get(De);xt.has(Ae.type)||xt.set(Ae.type,[]),xt.get(Ae.type).push(Ae.cb)}if(O.size===0)return;const Pe=[...O.keys()].map(Ae=>Ae.object3d),Ne=(_=this.pencil.pick(C,Pe,!0))==null?void 0:_.intersects;if(!Ne||Ne.length===0)t==="down"?this.handleDownOutside(C):t==="move"&&this.handleLeaveEvents(C);else{const Ae=Ne[0];this.processIntersection(Ae,C,t)}const Fe=this.prevActiveObjects;this.prevActiveObjects=this.activeObjects,this.activeObjects=Fe,this.activeObjects.clear()};this.domElement.addEventListener(`pointer${t}`,it(v),{passive:!1})}processIntersection(t,r,m){const v=this.objCallbackMap,C=t.index||-1;let _=t.object;for(;_;){const w=this.pencil.lead.objMap.get(_);w&&w.visible&&(this.activeObject||(this.activeObject=w),v.has(w)&&this.activeObjects.add(w)),_=_.parent}m==="move"?this.handleLeaveEvents(r):m==="down"&&this.handleDownOutside(r),this.processObjectHierarchy(r,m,C)}processObjectHierarchy(t,r,m){const v=this.objCallbackMap;let C=!1;const _=()=>{C=!0};for(const w of this.activeObjects){if(C)break;const I=v.get(w);if(I)if(r==="move"){const O=I.get("enter");if(O&&!this.prevActiveObjects.has(w))for(const Ne of O)Ne({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const Pe=I.get("move");if(Pe)for(const Ne of Pe)Ne({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m})}else{const O=I.get("down");if(O)for(const Ne of O)Ne({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const Pe=I.get("click");if(Pe){const Ne=Fe=>{Fe.preventDefault();const Ae=5;if(!C&&Math.abs(Fe.clientX-t.clientX)<=Ae&&Math.abs(Fe.clientY-t.clientY)<=Ae)for(const De of Pe)De({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});this.domElement.removeEventListener("pointerup",Ne)};this.domElement.addEventListener("pointerup",Ne)}}}}handleLeaveEvents(t){this.objCallbackMap.forEach((r,m)=>{const v=r.get("leave");if(v&&this.prevActiveObjects.has(m)&&!this.activeObjects.has(m))for(const C of v)C({baseObject:m,mouseEvent:t})})}handleDownOutside(t){this.objCallbackMap.forEach((r,m)=>{const v=r.get("downOutside");if(v&&!this.activeObjects.has(m))for(const C of v)C({baseObject:m,mouseEvent:t})})}handlePick(t,r,m){let v=r;v==="mousemove"?v="move":v==="mouseenter"?v="enter":v==="mouseleave"&&(v="leave"),this.pickFunctionsMapIndex+=1;const C=this.pickFunctionsMapIndex;return this.pickFunctionsMap.set(C,{objArr:t,type:v,cb:m}),this.pickListener.move||Array.from(this.pickFunctionsMap.values()).some(_=>["move","enter","leave"].includes(_.type))&&(this.pickListener.move=!0,this.addPickListener("move")),this.pickListener.down||Array.from(this.pickFunctionsMap.values()).some(_=>["down","downOutside","click"].includes(_.type))&&(this.pickListener.down=!0,this.addPickListener("down")),C}removePick(t){this.pickFunctionsMap.delete(t)}handlePickNode(t,r,m){if(r==="downOutside")return console.warn("handlePickNode:err:不支持 downOutside"),-1;this.pickNodeFunctionsMapIndex+=1;const v=this.pickNodeFunctionsMapIndex,C=t instanceof Function?t():t,_=[];for(const w of C){const I=w;I.element.style.pointerEvents="auto";const O=Ne=>{this.enabled&&(Ne.preventDefault(),m({baseObject:I,mouseEvent:Ne}))},Pe=`pointer${r}`;I.element.addEventListener(Pe,it(O),!1),_.push({arr:I,type:Pe,listener:O})}return this.pickNodeFunctionsMap.set(v,_),v}removePickNode(t){const r=this.pickNodeFunctionsMap.get(t);if(r){for(const m of r)m.arr.element.style.pointerEvents="none",m.arr.element.removeEventListener(m.type,m.listener,!1);this.pickNodeFunctionsMap.delete(t)}}dispose(){this.pickFunctionsMap.clear(),this.pickNodeFunctionsMap.clear(),this.activeObjects.clear(),this.prevActiveObjects.clear(),this.objCallbackMap.clear()}}class Js extends Qs{constructor(t,r){super(t),this.objMap=new Map,this.objects=new Map,this.objectsPm=new Map,this.objectWrapChindIdMap=new Map,this.objectNamesToFactories=new Map,this.mList=r.mList,this.scene=this.createBaseObject(r.scene||new Scene,{key:"@Scene",name:"场景",mList:!1}),this.group=this.createBaseObject(new Group$1,{key:"@Group",name:"物体组",target:this.scene,mList:!1}),this.prefabGroup=this.createBaseObject(new Group$1,{key:"@PrefabGroup",name:"预制组",target:this.scene,mList:!1})}get objectsPromise(){return this.objectsPm.values()}createBaseObject(t,r={}){const m=U({mList:!0},r),v=new ht;if(v.object3d=t,v.pencil=this.pencil,v.lead=this,v.mList=this.mList,m.key)v.key=m.key;else if(m.target){const C=m.target.key;if(C==="@Scene"&&t instanceof Camera$1)v.key="@Camera";else{const _=this.objectWrapChindIdMap.get(m.target)?this.objectWrapChindIdMap.get(m.target)+1:0;this.objectWrapChindIdMap.set(m.target,_),v.key=`${C}__c__${_}`}}return m.name&&(t.name=m.name),m.target&&m.target.object3d.add(v.object3d),this.objects.set(v.key,v),this.objMap.set(v.object3d,v),m.mList&&(this.mList.proxyBaseObject(v),this.mList.addBaseObjectMap(v)),t.children&&t.children.forEach(C=>{this.createBaseObject(C,{target:v,mList:m.mList})}),v}init(t){return Object.keys(t).forEach(r=>{const m=class{create(v={}){return new t[r](v)}};this.objectNamesToFactories.set(r,m)}),this}getObject(t,r){t.includes("#")&&console.warn("getObject:err:不支持 #",t);const{key:m}=r||{},v=`${t}${m?`#${m}`:""}`;return this.objects.get(v)}getAllObject(t,r){t.includes("#")&&console.warn("getAllObject:err:不支持 #",t);const{key:m}=r||{},v=`${t}${m?`#${m}`:""}`,C=[];return this.objects.forEach((_,w)=>{(w.startsWith(m?v:`${v}#`)||w===v)&&C.push(_)}),C}draw(t,r,m){return se(this,null,function*(){var v,C,_,w;const I=this.objectNamesToFactories.get(t);if(I){r||(r={}),r.target===void 0&&(r.target=m);const O=r.target,Pe=(v=r.onTop)!=null?v:0,Ne=(C=r.prefab)!=null?C:!1,Fe=(_=r.create)!=null?_:!0,Ae=new I().create(r);let De;return O===null?De=null:typeof O=="string"?De=this.objects.get(O):(w=O==null?void 0:O.objectType)!=null&&w.startsWith("BaseObject")||O?De=O:Ne?De=this.prefabGroup:De=this.group,Fe===!1?Ae.create=()=>{}:Fe!==!0&&(Ae.create=()=>{Fe(Ae)}),Ae.pencil=this.pencil,Ae.lead=this,Ae.mList=this.mList,Ae.prefab=Ne,Ae.objectType=`BaseObject#${t}`,Ae.objectOptions=r,this.setBaseObjectKey(Ae,r.key?`$t:#${r.key}`:"$t:",De==null?void 0:De.key),this.objectsPm.set(Ae,this.addBaseObject(Ae,De,Pe)),yield this.objectsPm.get(Ae),this.objectsPm.delete(Ae),Ae}throw new Error(`Unrecognized:${t}`)})}setBaseObjectKey(t,r,m){const v=t.objectType,[,C]=v.split("#");let _=r.replace("$t:",C);if(m){const[,w]=m.split("#");_=_.replace("$p:",w)}return this.objects.has(_)&&(_.includes("#")?_+=`-${esusLite.generateUUID()}`:_+=`#${esusLite.generateUUID()}`),t.key=_,this.objects.set(_,t),_}updateBaseObjectKey(t,r){var m;let v;for(const[w,I]of this.objects.entries())if(I===t){v=w;break}const C=(m=t.parent)==null?void 0:m.key,_=this.setBaseObjectKey(t,r,C);return v&&this.objects.delete(v),this.pencil.event.emit("lead.updateKey",{baseObject:t,key:_,oldKey:v}),t.children.forEach((w,I)=>{w.key.includes("__c__")&&this.updateBaseObjectKey(w,`${_}__c__${I}`)}),_}addBaseObject(t,r,m){return se(this,null,function*(){if(yield t.create(),t.object3d){const v=t.object3d;v.material&&Array.isArray(v.material)&&(v.material=v.material.slice()),this.mList.proxyBaseObject(t),this.mList.addBaseObjectMap(t),m&&t.setTop(m),r!==null&&r.object3d.add(t.object3d),this.objMap.set(t.object3d,t),v.children.forEach(C=>{this.objMap.get(C)||this.createBaseObject(C,{target:t})})}t.render(),this.pencil.event.emit("lead.draw",{baseObject:t})})}erase(...t){this.handleErase(!0,...t)}eraseWithoutMaterial(...t){this.handleErase(!1,...t)}handleErase(t,...r){[...r].forEach(m=>{const v=[];if(typeof m=="string"){const[C,_]=m.split("#");v.push(...this.getAllObject(C,{key:_}))}else v.push(m);v.forEach(C=>{C.disposeMaterialIfNotUsed=t,C.dispose()})}),this.pencil.event.emit("lead.erase")}update(t,r){this.objects.forEach(m=>{m.update(t,r)})}setSize(t,r){this.objects.forEach(m=>{m.resize(t,r)})}eraseAll(){this.group&&(this.objects.forEach(t=>{t.key.startsWith("Node")&&this.erase(t)}),this.erase(this.group))}dispose(){super.dispose(),this.scene.erase(),this.objects.forEach(t=>{t.erase()}),this.objects.clear(),this.objectsPm.clear(),this.objMap.clear(),this.objectWrapChindIdMap.clear(),this.objectNamesToFactories.clear()}}class ei extends ee{get lead(){return this.controller}constructor(t){super(),this.options=t}addLead(t,r,m){const{pencil:v}=this.options,C=new Js(v,{scene:t,mList:r});return this.addController(C,m)}removePage(t){super.removePage(t,r=>{r.dispose()})}setPageActive(t){super.setPageActive(t,(r,m)=>{r.enabled=m})}setSize(t,r){this.controllerMap.forEach((m,v)=>{v.setSize(t,r)})}}class rt extends Loader{constructor(t){super(t),this.options={type:"image"}}setOptions(t){return this.options=t,this}load(t,r,m,v){let C,_;this.options.type==="image"?(_=document.createElement("img"),C=new Texture(_)):this.options.type==="video"?(_=document.createElement("video"),_.preload="auto",_.autoplay=!1,_.loop=!1,_.muted=!0,_.setAttribute("webkit-playsinline","webkit-playsinline"),_.setAttribute("playsinline",""),C=new VideoTexture(_)):C=new Texture;const w=new FileLoader(this.manager);return w.setResponseType("blob"),w.setRequestHeader(this.requestHeader),w.setPath(this.path),w.setWithCredentials(this.withCredentials),w.load(t,I=>{let O=I;const Pe=t.split(".").pop(),Ne=this.options.type==="image"?`image/${Pe||"png"}`:`video/${Pe||"mp4"}`;O=O.slice(0,I.size,Ne);const Fe=()=>{_.removeEventListener("load",Ae,!1),_.removeEventListener("error",De,!1)},Ae=()=>{Fe(),C.needsUpdate=!0,r&&r(C)},De=je=>{Fe(),v&&v(je),this.manager.itemError(t),this.manager.itemEnd(t)};_.addEventListener("load",Ae,!1),_.addEventListener("error",De,!1);const xt=window.URL.createObjectURL(O);_.src=xt},m,v),C}}class ti extends Loader{constructor(t){super(t)}load(t,r,m,v){const C=new FileLoader(this.manager);C.setResponseType("blob"),C.setRequestHeader(this.requestHeader),C.setPath(this.path),C.setWithCredentials(this.withCredentials),C.load(t,_=>{const w=_,I=new DecompressionStream("gzip"),O=w.stream().pipeThrough(I);new Response(O).json().then(Pe=>{r==null||r(Pe)}).catch(Pe=>{v==null||v(Pe)})},m,v)}}const si={images:["png","jpg","jpeg","ico","webp","avif"],media:["mp4","webm","ogg"],gltf:["gltf","glb"],json:["json","geojson"],gzipJson:["json.gzip"],exr:["exr"],lottie:["lottie.json"]};class ii{constructor(t){this.loadObj=[],this.delLoadArr=[],this.assets=new Map,this.event=new ye.EventEmitter,this.options=U({simpleTexture4deleted:!1,prefix:""},t),this.loadingManager=new LoadingManager(()=>{},(r,m,v)=>{this.emit("progress",m,v)},r=>{console.warn(`Failed to load ${r}`)})}emit(t,...r){this.event.emit(t,...r)}on(t,r){this.event.on(t,r)}getAsset(t){const r=this.getAssetType(t);if(!r)return;const m=this.assets.get(t);if(!m){if((r==="images"||r==="media"||r==="exr")&&this.options.simpleTexture4deleted&&this.delLoadArr.includes(t))return new Texture;console.warn(`Asset ${t} not found`)}return m}getAssetType(t){var r;const m=(r=t.split(".").pop())==null?void 0:r.toLowerCase();if(m){if(t.endsWith("lottie.json"))return"lottie";if(t.endsWith("json.gzip"))return"gzipJson"}else return;for(const[v,C]of Object.entries(si))if(C.includes(m))return v}getLoader(t,r){if(t==="images")return this.textureLoader||(this.textureLoader=new rt(this.loadingManager),this.options.prefix&&this.textureLoader.setPath(this.options.prefix)),this.textureLoader;if(t==="media")return this.videoTextureLoader||(this.videoTextureLoader=new rt(this.loadingManager),this.videoTextureLoader.setOptions({type:"video"}),this.options.prefix&&this.videoTextureLoader.setPath(this.options.prefix)),this.videoTextureLoader;if(t==="gltf"&&r!=null&&r.dracoPath)return this.dracoGltfLoader||(this.dracoGltfLoader=new GLTFLoader(this.loadingManager),this.dracoLoader=new DRACOLoader,this.dracoLoader.setDecoderPath(r==null?void 0:r.dracoPath),this.dracoGltfLoader.setDRACOLoader(this.dracoLoader),this.options.prefix&&this.dracoGltfLoader.setPath(this.options.prefix)),this.dracoGltfLoader;if(t==="gltf")return this.gltfLoader||(this.gltfLoader=new GLTFLoader(this.loadingManager),this.options.prefix&&this.gltfLoader.setPath(this.options.prefix)),this.gltfLoader;if(t==="lottie")return this.lottieLoader||(this.lottieLoader=new LottieLoader(this.loadingManager),this.options.prefix&&this.lottieLoader.setPath(this.options.prefix)),this.lottieLoader;if(t==="gzipJson")return this.gzipJsonLoader||(this.gzipJsonLoader=new ti(this.loadingManager),this.options.prefix&&this.gzipJsonLoader.setPath(this.options.prefix)),this.gzipJsonLoader;if(t==="json")return this.jsonLoader||(this.jsonLoader=new FileLoader(this.loadingManager),this.jsonLoader.setResponseType("json"),this.options.prefix&&this.jsonLoader.setPath(this.options.prefix)),this.jsonLoader;if(t==="exr")return this.exrLoader||(this.exrLoader=new EXRLoader(this.loadingManager),this.options.prefix&&this.exrLoader.setPath(this.options.prefix)),this.exrLoader}add(t,r){typeof t=="string"&&(t=[t]),t.forEach(m=>{const v=U({src:m},r);this.loadObj.push(v)})}getSrcByAsset(t,r=this.assets){let m;return r.forEach((v,C)=>{v===t&&(m=C)}),m}get textureAssets(){const t=new Map;return this.assets.forEach((r,m)=>{(r instanceof Texture||r instanceof DataTexture||r instanceof VideoTexture)&&t.set(m,r)}),t}loadAll(){return se(this,null,function*(){const t=this.loadObj.filter(r=>!this.delLoadArr.includes(r.src));return yield Promise.all(t.map(r=>this.load(r.src,r)))})}load(t,r){return se(this,null,function*(){var m,v;const C=(m=r==null?void 0:r.type)!=null?m:this.getAssetType(t);if(!C)return;const _=(r==null?void 0:r.cache)!==!1,w=esusLite.makePromiseCreator();if(_){if(this.assets.has(t))return this.assets.get(t);this.assets.set(t,w.promise)}const I=this.getLoader(C,r);try{const O=yield I.loadAsync(t);if(this.assets.set(t,O),w.resolve(O),C==="images"||C==="media"||C==="exr"||C==="lottie"){(r==null?void 0:r.colorCorrection)!==!1&&l({texture:O});const Pe=(v=r==null?void 0:r.anisotropy)!=null?v:this.options.anisotropy;O.anisotropy=Pe}return O}catch(O){w.reject(`Failed to load ${t}`);return}})}getUnusedAssets(){const{scene:t}=this.options;if(!t)return[...this.delLoadArr];const r=new Set,m=this.textureAssets;t.traverse(C=>{const _=C;_.material&&(Array.isArray(_.material)?_.material:[_.material]).forEach(w=>{[w.map,w.emissiveMap,w.normalMap,w.roughnessMap,w.metalnessMap,w.aoMap].forEach(I=>{if(I){const O=this.getSrcByAsset(I,m);O&&r.add(O)}})})});const v=new Set(this.textureAssets.keys());return r.forEach(C=>{v.delete(C)}),[...v,...this.delLoadArr]}dispose(){var t;this.assets.clear(),(t=this.dracoLoader)==null||t.dispose(),this.event.removeAllListeners(),this.delLoadArr.length=0,this.loadObj.length=0}}const ri={prefix:""};class oi extends ee{get loader(){return this.controller}constructor(t){super(),this.options=t}addLoader(t,r){const{loaderParams:m}=this.options,v=new ii(te(U({},m),{scene:t}));return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}class ni{constructor(t){this.materials=new Map,this.fixBaseObjects=new Map,this.materialBaseObjectMap=new Map,this.pencil=t}add(t,r){this.materials.set(t,r);const m={object3d:new Proxy({material:r},{set:(v,C,_)=>{var w;if(C==="material"&&!((w=this.pencil.composerController)!=null&&w.bloomComposerRenderIng)){const I=v.material;return v.material=_,this.materials.set(t,_),this.disposeMaterial(I),this.syncChangeMaterial(I,_),!0}return v[C]=_,!0}})};this.fixBaseObjects.set(t,m),this.pencil.event.emit("mList.add",{key:t,material:r,baseObject:m})}get(t){const r=this.materials.get(t);return r||console.warn(`Material with key "${t}" not found.`),r}getByName(t){for(const[r,m]of this.materials.entries())if(m.name===t)return m;console.warn(`Material with name "${t}" not found.`)}getKey(t){for(const[r,m]of this.materials.entries())if(m===t)return r}getKeyByName(t){for(const[r,m]of this.materials.entries())if(m.name===t)return r;console.warn(`Material key with name "${t}" not found.`)}addMultiple(t,r){for(const[m,v]of Object.entries(r)){const C=`${t}#${m}`;v&&this.add(C,v)}}getMultiple(t){const r={},m=`${t}#`;let v=!1;for(const[C,_]of this.materials.entries())if(C.startsWith(m)){const w=C.substring(m.length);r[w]=_,v=!0}return v?r:null}copy(t,r,m={}){const v=this.get(t);if(!v)return console.warn(`Material with key "${t}" not found.`),null;const C=v.clone();return m.name&&(C.name=m.name),this.add(r,C),C}copyMultiple(t,r){const m={},v=`${t}#`;for(const[C,_]of this.materials.entries())if(C.startsWith(v)){const w=C.substring(v.length),I=_.clone();m[w]=I;const O=`${r}#${w}`;this.add(O,I)}return m}disposeMaterial(t){if(!t)return;const r=new se$1;r.track(Array.isArray(t)?t:[t]),r.dispose()}remove(t){const r=this.materials.get(t);r&&this.disposeMaterial(r),this.materials.delete(t),this.fixBaseObjects.delete(t),this.pencil.event.emit("mList.remove",{key:t,material:r})}removeByMaterial(t){[...this.materials.entries()].some(([r,m])=>m===t?(this.remove(r),!0):!1)}proxyBaseObject(t){const r=t.object3d;if(!r.material)return;const m=_=>{if(_.hasOwnProperty("__isProxy"))return _;const w=new Proxy(_,{set:(I,O,Pe)=>{if(typeof O=="string"&&!isNaN(Number(O))){const Ne=Number(O);if(Ne>=0&&Ne<I.length){const Fe=I[Ne];return this.rmBaseObjectMap(t,Fe),I[Ne]=Pe,Pe&&this.addBaseObjectMap(t),!0}}return I[O]=Pe,!0}});return Object.defineProperty(w,"__isProxy",{value:!0,enumerable:!1}),w};t.materialList&&(t.materialList=new Proxy(t.materialList,{set:(_,w,I)=>{if(typeof w=="string"){const O=_[w];return this.rmBaseObjectMap(t,O),_[w]=I,I&&this.addBaseObjectMap(t),!0}return _[w]=I,!0},get:(_,w)=>{if(typeof w=="string"&&_[w]){const I=_[w];if(Array.isArray(I)){const O=m(I);return O!==I&&(_[w]=O),O}return I}return _[w]},deleteProperty:(_,w)=>{if(typeof w=="string"&&_[w]){const I=_[w];this.rmBaseObjectMap(t,I)}return delete _[w],!0}}));const v=r.material,C="_enhancedMaterial";r[C]=v,Object.defineProperty(r,"material",{get:()=>{var _;const w=r[C];if(!((_=this.pencil.composerController)!=null&&_.bloomComposerRenderIng)&&Array.isArray(w)){const I=m(w);return I!==w&&(r[C]=I),I}return w},set:_=>{var w;if((w=this.pencil.composerController)!=null&&w.bloomComposerRenderIng)r[C]=_;else{if(t.materialList&&Object.values(t.materialList).includes(_)){r[C]=_;return}this.rmBaseObjectMap(t),r[C]=_,this.addBaseObjectMap(t)}},enumerable:!0,configurable:!0})}material2array(t){return Array.isArray(t)?t:[t]}addBaseObjectMap(t){const r=t.object3d;r.material&&([...Object.values(t.materialList),r.material].forEach(m=>{m&&this.material2array(m).forEach(v=>{const C=this.materialBaseObjectMap.get(v);C?C.add(t):this.materialBaseObjectMap.set(v,new Set([t]))})}),this.pencil.event.emit("mList.addBaseObjectMap"))}rmBaseObjectMap(t,r,m=!0){const v=r&&this.material2array(r);this.materialBaseObjectMap.forEach((C,_)=>{v&&!v.includes(_)||C.has(t)&&(C.delete(t),C.size===0&&m&&(this.materialBaseObjectMap.delete(_),this.disposeMaterial(_)))}),this.pencil.event.emit("mList.rmBaseObjectMap")}getBaseObjectMap(t){return this.materialBaseObjectMap.get(t)||new Set}syncChangeMaterial(t,r){const m=this.materialBaseObjectMap.get(t);m&&m.forEach(v=>{const C=v.object3d,_=C.material;if(Array.isArray(_)){const w=_.indexOf(t);w!==-1&&(_[w]=r)}else _===t&&(C.material=r);v.materialList&&Object.keys(v.materialList).forEach(w=>{const I=v.materialList[w];if(Array.isArray(I)){const O=I.indexOf(t);O!==-1&&(I[O]=r)}else I===t&&(v.materialList[w]=r)})})}dispose(){const t=new se$1;t.track([...this.materials.values()]),t.dispose(),this.materials.clear(),this.fixBaseObjects.clear(),this.materialBaseObjectMap.clear()}}class ai extends ee{get mList(){return this.controller}constructor(t){super(),this.options=t}addMList(t,r){const{pencil:m}=this.options,v=new ni(m);return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}const li={antialias:!1,devicePixelRatio:window.devicePixelRatio,powerPreference:"high-performance",toneMappingExposure:1,alpha:!1,outputColorSpace:e.sRGB,logarithmicDepthBuffer:!1,preserveDrawingBuffer:!1,stencil:!1,depth:!1};class hi{constructor(t){this.options=t;const{width:r,height:m,rendererParams:v}=t,{alpha:C,devicePixelRatio:_,antialias:w,powerPreference:I,toneMappingExposure:O,outputColorSpace:Pe,logarithmicDepthBuffer:Ne,preserveDrawingBuffer:Fe,stencil:Ae,depth:De}=v,xt=new WebGLRenderer({alpha:C,antialias:w,powerPreference:I,logarithmicDepthBuffer:Ne,preserveDrawingBuffer:Fe,stencil:Ae,depth:De});xt.setSize(r,m),xt.setPixelRatio(_),xt.toneMappingExposure=O,xt.outputColorSpace=Pe,this.renderer=xt}setSize(t,r){this.renderer.setSize(t,r)}setPixelRatio(t){this.renderer.setPixelRatio(t)}render(t,r){this.renderer.render(t,r)}setViewport(t){var r,m;const{x:v,y:C,width:_,height:w}=t,I=(r=t.scissor)!=null?r:!1,O=(m=t.scissorTest)!=null?m:!1;this.renderer.setViewport(v,C,_,w),I&&(this.renderer.setScissor(v,C,_,w),this.renderer.setScissorTest(O))}dispose(){var t,r;this.setSize(1,1),(t=this.renderer)==null||t.clear(),(r=this.renderer)==null||r.dispose()}}const ci={background:null};class di extends ee{get scene(){return this.controller}constructor(t){super(),this.options=t}addScene(t,r){const m=new Scene;return t!=null&&t.background&&(m.background=t.background),this.addController(m,r)}removePage(t){super.removePage(t,r=>{const m=new se$1;m.track(r),m.dispose()})}setPageActive(t){super.setPageActive(t,(r,m)=>{r.visible=m})}}class mi{constructor(t){this.event=new ye.EventEmitter;const{renderer:r,scene:m,camera:v}=t,C=new TransformControls(v,r.domElement);if(C.getHelper){const _=C.getHelper();m.add(_),+REVISION<170}else C instanceof Object3D&&m.add(C);this.controls=C,this.addEvent()}get detach(){return this.controls.detach.bind(this.controls)}get attach(){return this.controls.attach.bind(this.controls)}addEvent(){let t=null,r=null,m=null;const v=this.controls;v.addEventListener("change",()=>{const C=v.object;C!==void 0&&this.event.emit("change",C)}),v.addEventListener("mouseDown",()=>{const C=v.object;t=C.position.clone(),r=C.rotation.clone(),m=C.scale.clone(),this.event.emit("mouseDown",C)}),v.addEventListener("mouseUp",()=>{const C=v.object;if(C!==void 0)switch(v.getMode()){case"translate":t.equals(C.position)||this.event.emit("translate",C,C.position,t);break;case"rotate":r.equals(C.rotation)||this.event.emit("rotate",C,C.rotation,r);break;case"scale":m.equals(C.scale)||this.event.emit("scale",C,C.scale,m);break}this.event.emit("mouseUp")})}dispose(){var t;this.event.removeAllListeners(),(t=this.controls)==null||t.dispose()}}const pi={antialias:!0,devicePixelRatio:window.devicePixelRatio};class fi{constructor(t){this.options=t;const{width:r,height:m,rendererParams:v,renderer:C}=t,{devicePixelRatio:_,antialias:w}=v,I=new C({antialias:w});I.setSize(r,m),I.setPixelRatio(_),this.renderer=I}setSize(t,r){this.renderer.setSize(t,r)}render(t,r){this.renderer.render(t,r)}dispose(){var t,r;this.setSize(1,1),(t=this.renderer)==null||t.clear(),(r=this.renderer)==null||r.dispose()}}const _e=class Nn{constructor(t){var r,m;this.raycaster=new Raycaster,this.maxBackufferArea=5760*5760,this.installPlugins=new Map,this._cameraPositon=new Vector3,this._cameraTarget=new Vector3,this.event=new ye.EventEmitter,this.timer=new Timer,this.userData={},this.pageActiveIndex=0,this.pageCountIndex=0,this.userSetDprCache=1,this.viewPadding=[0,0,0,0],this.event.setMaxListeners(1/0),(m=(r=this.timer).connect)==null||m.call(r,document),this.options=Ut(Nn.options,t,{isMergeableObject:f$1}),this.userSetDprCache=this.options.renderer.devicePixelRatio;const{container:v,stats:C,transformControls:_}=this.options;if(this.init(),this.options.WebGPUTHREE||this.initComposer(),this.initCSSRenderer(),_&&this.initTransformControls(),C){const w=new Stats({horizontal:!1});w.dom.style.position="absolute",w.init(this.renderer),v.appendChild(w.dom),this.stats=w}this.initResizeObserver(),this.tweenUpdateRaf()}getPlugin(t){return this.installPlugins.get(t)}get renderer(){return this.rendererController.renderer}get maxAnisotropy(){return this.options.WebGPUTHREE?0:this.renderer.capabilities.getMaxAnisotropy()}get controls(){return this.controlsController.cameraControls}get cameraPositon(){return this.controls.getPosition(this._cameraPositon,!1)}get cameraTarget(){return this.controls.getTarget(this._cameraTarget,!1)}get camera(){return this.cameraController.camera}get scene(){return this.sceneController.scene}get loader(){return this.loaderController.loader}get lead(){return this.leadController.lead}get mList(){return this.mListController.mList}tweenUpdateRaf(){update(),this.TweenRaf=requestAnimationFrame(this.tweenUpdateRaf.bind(this))}use(t,...r){this.installPlugins.has(t.pluginName)?console.log("plugin already installed"):typeof t.install=="function"&&(t.install(this,...r),this.installPlugins.set(t.pluginName,t))}addPage({sceneOptions:t,cameraOptions:r}={}){const m=this.pageCountIndex+1,v=this.cameraController.addPerspectiveCamera(r,m),C=this.sceneController.addScene(t,m);C.add(v),this.controlsController.addCameraControls(v,m),this.loaderController.addLoader(C,m);const _=this.mListController.addMList(null,m);return this.leadController.addLead(C,_,m),this.pageCountIndex=m,m}removePage(t){this.cameraController.removePage(t),this.sceneController.removePage(t),this.controlsController.removePage(t),this.loaderController.removePage(t),this.mListController.removePage(t),this.leadController.removePage(t),this.pageCountIndex===t&&(this.pageCountIndex-=1),this.pageActiveIndex===t&&(this.render(),this.showPage(0))}showPage(t){var r;if(t===this.pageActiveIndex)return;const m=this.scene;this.sceneController.setPageActive(t),m&&((r=this.cssRendererController)==null||r.render(m,this.camera)),this.cameraController.setPageActive(t),this.controlsController.setPageActive(t),this.loaderController.setPageActive(t),this.mListController.setPageActive(t),this.leadController.setPageActive(t),this.pageActiveIndex=t}init(){var t;const{container:r,WebGPUTHREE:m,helper:v,viewHelper:C,renderer:_,controls:w,loader:I}=this.options,{width:O,height:Pe}=this.getSize(),Ne=m?new fi({width:O,height:Pe,renderer:m.WebGPURenderer,rendererParams:pi}):new hi({width:O,height:Pe,rendererParams:te(U({},_),{antialias:!1})}),Fe=new Ms({width:O,height:Pe}),Ae=new di({}),De=new Zs({controlsParams:{domElement:(t=w==null?void 0:w.domElement)!=null?t:Ne.renderer.domElement}}),xt=new oi({loaderParams:U({anisotropy:Ne.renderer.capabilities.getMaxAnisotropy()},I)}),je=new ai({pencil:this}),ke=new ei({pencil:this});this.sceneController=Ae,this.cameraController=Fe,this.controlsController=De,this.rendererController=Ne,this.loaderController=xt,this.mListController=je,this.leadController=ke;const at=this.addPage({sceneOptions:this.options.scene,cameraOptions:this.options.camera});if(this.showPage(at),v){const ct=new qs({container:r,sceneController:Ae,cameraController:Fe});ct.add(Ae.scene),this.helperController=ct,C&&ct.addViewHelper()}r.appendChild(Ne.renderer.domElement)}initComposer(){const{bloom:t,bloomParams:r,ssao:m,ssaoParams:v,composer:C}=this.options,_=new Ys({rendererController:this.rendererController,sceneController:this.sceneController,cameraController:this.cameraController,composerParams:C});this.composerController=_,t&&_.addBloomPass(U({},r)),m&&_.addSSAOPass(U({},v)),_.addOutputPass()}initCSSRenderer(){const{container:t,css2DRenderer:r,css3DRenderer:m,css2DRendererParams:v,css3DRendererParams:C}=this.options;if(r||m){const _=new Xs(t);r&&_.addRenderer("css2d",v),m&&_.addRenderer("css3d",C),this.cssRendererController=_}}initTransformControls(){const t=new mi({camera:this.camera,renderer:this.renderer,scene:this.scene});t.event.on("mouseDown",()=>{var r;(r=this.controlsController)==null||r.disable()}),t.event.on("mouseUp",()=>{var r;(r=this.controlsController)==null||r.enable()}),this.transformController=t}getSize(){const{container:t}=this.options;return{width:t.offsetWidth,height:t.offsetHeight}}initResizeObserver(){const{container:t}=this.options;if(this.resizeObserver)return;const r=new ResizeObserver(m=>{for(const v of m){const C=v.contentRect;this.handeleResize(C.width,C.height),this.setDevicePixelRatio(this.userSetDprCache)}});r.observe(t),this.resizeObserver=r}handeleResize(t,r,m=!0){const{rendererController:v,cameraController:C,composerController:_,cssRendererController:w,leadController:I}=this,O=this.renderer.getSize(new Vector2);O.x===t&&O.y===r||(C.setSize(t,r),v.setSize(t,r),_==null||_.setSize(t,r),w==null||w.setSize(t,r),I.setSize(t,r),this.installPlugins.forEach(Pe=>{var Ne;(Ne=Pe.setSize)==null||Ne.call(Pe,t,r)}),this.viewPadding.some(Pe=>Pe!==0)&&this.setViewPadding(...this.viewPadding),this.render(),m&&this.event.emit("resize",{width:t,height:r}))}setDevicePixelRatio(t){var r;this.userSetDprCache=t;const{width:m,height:v}=this.getSize();let C=Math.sqrt(this.maxBackufferArea/(m*v));C=(C*100|0)/100;const _=Math.min(t,C);_!==t&&console.warn("maxBackufferArea:",this.maxBackufferArea," the pixel ratio is set to",_);const w=this.renderer.getPixelRatio();_!==w&&(this.rendererController.setPixelRatio(_),(r=this.composerController)==null||r.setPixelRatio(_),this.viewPadding.some(I=>I!==0)&&this.setViewPadding(...this.viewPadding))}setViewPadding(t=0,r=0,m=0,v=0){const{width:C,height:_}=this.renderer.getSize(new Vector2),w={x:v,y:m,width:C-v-r,height:_-t-m};this.rendererController.setViewport(w),this.cameraController.setAspect(w.width/w.height),this.viewPadding=[t,r,m,v]}pick(t,r,m=!0){const{raycaster:v,options:C}=this,{container:_}=C,w=new Vector2,I=_.getBoundingClientRect();if(w.x=(t.clientX-I.left)/(I.right-I.left)*2-1,w.y=-((t.clientY-I.top)/(I.bottom-I.top))*2+1,this.camera&&this.scene){v.setFromCamera(w,this.camera);const O=v.intersectObjects(r||this.scene.children,m);if(O.length)return{object:O[0].object,index:O[0].index,intersects:O}}}render(){var t,r,m,v,C,_;if(!this.camera||!this.scene)return;this.event.emit("beforeRender"),this.timer.update(),update();const w=this.timer.getDelta(),I=this.timer.getElapsed();this.controlsController.update(w,I),this.leadController.update(w,I),this.installPlugins.forEach(O=>{var Pe;(Pe=O.update)==null||Pe.call(O,w,I)}),(t=this.helperController)==null||t.update(w,this.controlsController,this.cameraTarget),(r=this.composerController)!=null&&r.active?this.composerController.render():(m=this.rendererController)==null||m.render(this.scene,this.camera),(v=this.helperController)==null||v.renderViewHelper(this.renderer),(C=this.cssRendererController)==null||C.render(this.scene,this.camera),(_=this.stats)==null||_.update(),this.event.emit("render",{delta:w,elapsed:I})}start(){var t;window.cancelAnimationFrame(this.TweenRaf),(t=this.renderer)==null||t.setAnimationLoop(this.render.bind(this)),this.event.emit("start")}stop(){var t;this.tweenUpdateRaf(),(t=this.renderer)==null||t.setAnimationLoop(null),this.event.emit("stop")}autoRotate(t){this.controlsController.autoRotateSpeed=t}showPipViewport(t){this.composerController.pipViewportState=t;let r=this.pipCameraControls;if(t){const{width:m,height:v}=this.getSize(),C=new DOMRect(t.x/m,(v-t.y-t.height)/v,t.width/m,t.height/v);if(r)r.enabled=!0,r.camera.position.copy(this.camera.position);else{const _=this.cameraController.cloneCamera(31);_.aspect=t.width/t.height,_.updateProjectionMatrix(),r=this.controlsController.addCameraControls(_,this.sceneController.activeIndex),r.addEventListener("update",()=>{this.controls.enabled=!1}),r.addEventListener("sleep",()=>{this.controls.enabled=!0}),this.pipCameraControls=r}r.interactiveArea=C}}dispose(){var t,r,m,v,C,_,w,I,O,Pe,Ne,Fe,Ae,De;this.stop(),this.timer.dispose(),removeAll(),this.event.removeAllListeners(),(t=this.resizeObserver)==null||t.unobserve(this.options.container),this.installPlugins.forEach(xt=>{var je;(je=xt.dispose)==null||je.call(xt)}),(r=this.controlsController)==null||r.dispose(),(m=this.transformController)==null||m.dispose(),(v=this.cssRendererController)==null||v.dispose(),(C=this.sceneController)==null||C.dispose(),(_=this.cameraController)==null||_.dispose(),(w=this.helperController)==null||w.dispose(),(I=this.composerController)==null||I.dispose(),(O=this.rendererController)==null||O.dispose(),(Pe=this.loaderController)==null||Pe.dispose(),(Ne=this.leadController)==null||Ne.dispose(),(Fe=this.mListController)==null||Fe.dispose(),this.cssRendererController=void 0,this.installPlugins.clear(),(Ae=this.stats)==null||Ae.dom.remove(),(De=this.renderer)==null||De.domElement.remove()}};_e.options={stats:Le$1,helper:Le$1,viewHelper:Le$1,controls:!0,transformControls:Le$1,renderer:li,composer:Vs,scene:ci,camera:wt,bloom:!1,bloomParams:Bs,ssao:!1,loader:ri,ssaoParams:Hs,css2DRenderer:!1,css2DRendererParams:U({},st),css3DRenderer:!1,css3DRendererParams:U({},st)};let ot=_e;const Gi=J$1.ACTION;class Point extends ht{constructor(r){super();C0(this,"options");C0(this,"scaleValue",1);this.options=q0({sprite:!0},r)}get material(){var r;return(r=this.object3d)==null?void 0:r.material}getMaterial(){const{sprite:r}=this.options,m=document.createElement("canvas");m.width=100,m.height=100;const v=m.getContext("2d");v.beginPath(),v.arc(50,50,50,0,2*Math.PI),v.fillStyle="#ffffff",v.fill(),v.closePath();const C=new CanvasTexture(m);return r?new SpriteMaterial({transparent:!0,map:C}):new MeshBasicMaterial({color:16777215,transparent:!0,map:C})}create(){return U0(this,null,function*(){const{sprite:r}=this.options,m=this.getMaterial();r?this.createSprite(m):this.createMesh(new PlaneGeometry(1,1),m),this.setScale(1),this.object3d.scale.multiplyScalar(.1)})}setScale(r){this.scaleValue=r;const m=this.material.map;m!=null&&m.image?this.object3d.scale.set(m.image.width*r,m.image.height*r,1):this.object3d.scale.set(r,r,1)}}const p={mercator:i$3,equirectangular:s$1,winkel3:l$1},a$1={},f=g=>{var t,r,m;const v=JSON.stringify(g);if(a$1[v])return a$1[v];const C=p[(t=g.projectionType)!=null?t:"mercator"]().center(g.center).scale(g.scale).translate((r=g.translate)!=null?r:[0,0]).precision((m=g.precision)!=null?m:.1);return g.rotate&&C.rotate(g.rotate),a$1[v]=C,C},getLineTexture=(g,t="rgba(255,255,255,1)",r="rgba(0,0,0,0)")=>{const m=document.createElement("canvas");m.width=256,m.height=1;const v=m.getContext("2d"),C=v.createLinearGradient(0,0,256,1);C.addColorStop(0,t),C.addColorStop(g,t),C.addColorStop(g,r),C.addColorStop(1,r),v.fillStyle=C,v.fillRect(0,0,256,1);const _=new CanvasTexture(m);return _.wrapS=RepeatWrapping,_.wrapT=RepeatWrapping,_.needsUpdate=!0,_},createFlyPath=(g,t,r=40)=>{const m=g.angleTo(t);let v=g.clone().add(t);v=v.normalize().multiplyScalar(r);let C;m<=1?C=r/5*m:m>1&&m<2?C=r/5*mn(m,2):C=r/5*mn(m,1.5);const _=g.clone().add(v).normalize().multiplyScalar(r+C),w=t.clone().add(v).normalize().multiplyScalar(r+C);return new CubicBezierCurve3(g,_,w,t)},createFlyPath2=(g,t,r=40)=>{const m=new Vector3().lerpVectors(g,t,.25),v=new Vector3().lerpVectors(g,t,.75);return m.z+=r,v.z+=r,new CubicBezierCurve3(g,m,v,t)},pixel2unit=(g,t)=>{const m=g.camera.fov*Math.PI/180,v=g.controls.getPosition(new Vector3,!1),C=2*Math.tan(m/2)*v.z,_=g.getSize(),w=_.width/_.width,I=C*w;return t*g.renderer.getPixelRatio()/_.width/(1/I)};let map;class Arc extends ht{constructor(r){super();C0(this,"options");C0(this,"line");C0(this,"helperMesh");C0(this,"helperMeshPosition");C0(this,"pickTube",null);this.options=q0({color:"#ffffff",lineWidth:6,globe:!1,offsetLoop:!0},r),this.options.repeat&&this.options.repeat[0]===.5&&(this.options.offsetLoop=!1)}static getInitOptions(r,m){const v=pixel2unit(r,200),C=m.globe?new Vector3(0,0,0).add(new Vector3(-v/2,v/2,0)):new Vector3(0,0,0).sub(new Vector3(v/2,v/2,v/2)),_=m.globe?new Vector3(0,0,0).add(new Vector3(v/2,v/2,0)):new Vector3(0,0,0).add(new Vector3(v/2,v/2,v/2));return{from:C.toArray(),to:_.toArray()}}create(){return U0(this,null,function*(){map||(map=getLineTexture(.5));const{color:r,lineWidth:m,globe:v}=this.options;let{radius:C}=this.options;const _=h(this.options.from||[0,0,0]),w=h(this.options.to||[0,0,0]);C=C!=null?C:_.distanceTo(w);const I=v?createFlyPath(_,w,C):createFlyPath2(_,w,C),O=I.getPoints(1500),Pe=this.pencil.lead,Ne=yield Pe.draw("Line",{nodes:O,setPointWidth:je=>je*1,materialParameters:{color:r,map,useMap:1,transparent:!0,sizeAttenuation:0,lineWidth:m}},null);this.line=Ne,this.object3d=Ne.object3d;const[Fe,Ae,De,xt]=yield Promise.all([{key:"Arc_起点",position:I.v0},{key:"Arc_第一控制点",position:I.v1},{key:"Arc_第二控制点",position:I.v2},{key:"Arc_终点",position:I.v3}].map(at=>U0(this,[at],function*({key:je,position:ke}){const ct=yield Pe.draw("Group",{},this);return ct.position.copy(ke),ct.userData.disabledC=!0,ct.userData.disabledR=!0,Pe.updateBaseObjectKey(ct,`${je}_${this.options.key}`),ct})));this.helperMesh=[Fe,Ae,De,xt],this.helperMeshPosition=[Fe.position.clone(),Ae.position.clone(),De.position.clone(),xt.position.clone()]})}instantiate(){return U0(this,null,function*(){this.update();const r=yield this.line.instantiate({recursive:!1}),m=yield yn(Arc.prototype,this,"instantiate").call(this,{create:v=>{v.line=r,v.object3d=r.object3d}});return m.position.set(0,0,0),m.rotation.set(0,0,0),m.scale.set(1,1,1),m})}setPath(r,m,v,C=_=>_*1){const{globe:_}=this.options;r=h(r),m=h(m);const I=(_?createFlyPath(r,m,v):createFlyPath2(r,m,v)).getPoints(1500);this.line.options.nodes=I,this.line.setGeometry(I,C),this.pickTube&&this.addPickTarget(this.pickTube.options.radius)}addPickTarget(r=1,m=!1){return U0(this,null,function*(){const v=this.pickTube,C=this.pencil.lead,_=this.line.options.nodes,w=new CurvePath;for(let Pe=0;Pe<_.length-1;Pe++)w.add(new LineCurve3(_[Pe],_[Pe+1]));const I=yield C.draw("Tube",{path:w,radius:r,multiplyScalar:1},this),O=I.object3d;return O.material=new MeshBasicMaterial({color:16711680,transparent:!0,opacity:m?1:0}),v&&(v.userData._pe_&&I.onPointerEvent(...v.userData._pe_),v.erase()),this.pickTube=I,I})}onPointerEvent(...r){this.pickTube?(this.pickTube.onPointerEvent(...r),this.pickTube.userData._pe_=[...r]):this.pencil.userData.EditorEnv||console.warn("addPickTarget first")}setColor(r){this.line&&(this.line.material.uniforms.color.value=new Color$1(r))}animateIn({duration:r=2e3,delay:m=0,repeat:v=1/0,onComplete:C,onRepeat:_}={}){this.line.material.userData.tween&&(this.line.material.userData.tween.stop(),remove(this.line.material.userData.tween),this.line.material.userData.tween=null,this.line.material.uniforms.offset.value.x=0),r&&(this.line.material.uniforms.offset.value.x=1,this.line.material.uniforms.offsetLoop.value=0,this.line.animate({duration:r,repeat:v,delay:m,lineLoop:this.options.offsetLoop,onRepeat:_,onComplete:C}))}update(){var r;if((r=this.helperMesh)!=null&&r.length&&this.helperMesh.find((v,C)=>v.position.distanceTo(this.helperMeshPosition[C])>.01)){this.helperMesh.forEach((_,w)=>{this.helperMeshPosition[w].copy(_.position)});const C=new CubicBezierCurve3(this.helperMeshPosition[0],this.helperMeshPosition[1],this.helperMeshPosition[2],this.helperMeshPosition[3]).getPoints(1500);this.line.setGeometry(C,this.line.object3d.geometry.widthCallback)}}render(){this.mList.rmBaseObjectMap(this.line),setTimeout(()=>{!this.pencil.userData.EditorEnv&&this.prefab||this.line.material.userData.tween||this.animateIn()})}dispose(){this.line.dispose(),super.dispose()}}class CrossPlane extends ht{constructor(r){super();C0(this,"options");this.options=q0({},r)}create(){return U0(this,null,function*(){this.createGroup();const r=this.options.material||new MeshBasicMaterial({color:"#ffffff",side:DoubleSide,blending:AdditiveBlending});r.depthWrite=!1;const m=this.pencil.lead,[v,C]=yield Promise.all([m.draw("Plane",{key:"crossPlane_item1_"+this.options.key},this),m.draw("Plane",{key:"crossPlane_item2_"+this.options.key},this)]);v.object3d.material=r,C.object3d.material=r,v.rotation.x=-Math.PI*.5,C.rotation.x=-Math.PI*.5,C.rotation.y=-Math.PI*.5})}}class PlaneShadow extends ht{create(){return U0(this,null,function*(){const t=new PlaneGeometry(100,100,2,2),r=new ShadowMaterial;r.opacity=.5,r.depthWrite=!1,this.createMesh(t,r),this.object3d.receiveShadow=!0,this.position.z=.1,this.object3d.name="阴影接受"})}}class Model extends ht{constructor(r){super();C0(this,"options");this.options=q0({},r)}create(){return U0(this,null,function*(){const r=this.pencil.loader,m=this.options.src,v=yield r.load(m,{type:"gltf",cache:!1});this.object3d=v.scene})}}class Box extends ht{create(){const t=new BoxGeometry(1,1,1,1,1,1);this.createMesh(t),this.scale.multiplyScalar(20)}}class Capsule extends ht{create(){const t=new CapsuleGeometry(1,1,4,8);this.createMesh(t),this.scale.multiplyScalar(20)}}class Circle extends ht{create(){const t=new CircleGeometry(1,32,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Cylinder extends ht{create(){const t=new CylinderGeometry(1,1,1,32,1,!1,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Dodecahedron extends ht{create(){const t=new DodecahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Icosahedron extends ht{create(){const t=new IcosahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Lathe extends ht{create(){const t=new LatheGeometry;this.createMesh(t,new MeshStandardMaterial({side:DoubleSide})),this.scale.multiplyScalar(20)}}class Octahedron extends ht{create(){const t=new OctahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Plane extends ht{create(){const t=new PlaneGeometry(1,1,2,2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Ring extends ht{create(){const t=new RingGeometry(.5,1,32,1,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Sphere extends ht{constructor(){super(...arguments);C0(this,"radius",100);C0(this,"material");C0(this,"options")}create(){var m;(m=this.options)!=null&&m.radius&&(this.radius=this.options.radius);const r=new SphereGeometry(this.radius,128,90);this.createMesh(r,this.material),this.object3d.rotation.y=Math.PI/180*90}}class Sprite extends ht{create(){this.createSprite(new SpriteMaterial),this.scale.multiplyScalar(20)}setDesiredPixelSize(t){var m;const r=this.object3d;if((m=r.material.map)!=null&&m.image){const v=this.pencil.camera,C=new Vector3;v.matrixWorld.decompose(C,new Quaternion,new Vector3);const _=MathUtils.degToRad(v.fov),I=this.pencil.getSize().height*(1/(2*Math.tan(_/2))),O=t/I,{width:Pe,height:Ne}=r.material.map.image;r.scale.set(Pe/Ne*O,O,1)}}}class Tetrahedron extends ht{create(){const t=new TetrahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Torus extends ht{create(){const t=new TorusGeometry(1,.4,12,48,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class TorusKnot extends ht{create(){const t=new TorusKnotGeometry(1,.4,64,8,2,3);this.createMesh(t),this.scale.multiplyScalar(20)}}class Tube extends ht{constructor(r){super();C0(this,"options");this.options=r}create(){var _,w;const r=this.options.path||new CatmullRomCurve3([new Vector3(2,2,-2),new Vector3(2,-2,-.6666666666666667),new Vector3(-2,-2,.6666666666666667),new Vector3(-2,2,2)]),m=(_=this.options.radius)!=null?_:1,v=(w=this.options.multiplyScalar)!=null?w:20,C=new TubeGeometry(r,64,m,8,!1);this.createMesh(C),this.scale.multiplyScalar(v)}}const baseObjs={Node:Xe$1,Line:es,Line2:Ke$1,ExtrudePolygon:is,ConicPolygon:ss,Group:Qe$1,Light,Point,Arc,Model},expObjs={Plane,CrossPlane,PlaneShadow,Ring,Sphere,Sprite,Tetrahedron,Torus,TorusKnot,Tube,Box,Capsule,Circle,Cylinder,Dodecahedron,Icosahedron,Lathe,Octahedron},prefabType=Object.keys(Ji(q0({},expObjs),{Arc,Model})).map(g=>g),objs$3=q0(q0({},baseObjs),expObjs);function promisifyRequest(g){return new Promise((t,r)=>{g.oncomplete=g.onsuccess=()=>t(g.result),g.onabort=g.onerror=()=>r(g.error)})}function createStore(g,t){const r=indexedDB.open(g);r.onupgradeneeded=()=>r.result.createObjectStore(t);const m=promisifyRequest(r);return(v,C)=>m.then(_=>C(_.transaction(t,v).objectStore(t)))}let defaultGetStoreFunc;function defaultGetStore(){return defaultGetStoreFunc||(defaultGetStoreFunc=createStore("keyval-store","keyval")),defaultGetStoreFunc}function get(g,t=defaultGetStore()){return t("readonly",r=>promisifyRequest(r.get(g)))}function setMany(g,t=defaultGetStore()){return t("readwrite",r=>(g.forEach(m=>r.put(m[1],m[0])),promisifyRequest(r.transaction)))}function del(g,t=defaultGetStore()){return t("readwrite",r=>(r.delete(g),promisifyRequest(r.transaction)))}var H=Object.defineProperty,y=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable,s=(g,t,r)=>t in g?H(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,W=(g,t)=>{for(var r in t||(t={}))a.call(t,r)&&s(g,r,t[r]);if(y)for(var r of y(t))x.call(t,r)&&s(g,r,t[r]);return g},Y=(g,t)=>{var r={};for(var m in g)a.call(g,m)&&t.indexOf(m)<0&&(r[m]=g[m]);if(g!=null&&y)for(var m of y(g))t.indexOf(m)<0&&x.call(g,m)&&(r[m]=g[m]);return r},V=(g,t,r)=>new Promise((m,v)=>{var C=I=>{try{w(r.next(I))}catch(O){v(O)}},_=I=>{try{w(r.throw(I))}catch(O){v(O)}},w=I=>I.done?m(I.value):Promise.resolve(I.value).then(C,_);w((r=r.apply(g,t)).next())});const o="dmFyIEJnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxGZz1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgSWc9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIFFyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIFp1PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksWHU9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgZ2M9KEosUSk9PihRPVN5bWJvbFtKXSk/UTpTeW1ib2wuZm9yKCJTeW1ib2wuIitKKSxrZz1KPT57dGhyb3cgVHlwZUVycm9yKEopfSx5aT1NYXRoLnBvdyxHdT0oSixRLG10KT0+USBpbiBKP0JnKEosUSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6bXR9KTpKW1FdPW10LEZ0PShKLFEpPT57Zm9yKHZhciBtdCBpbiBRfHwoUT17fSkpWnUuY2FsbChRLG10KSYmR3UoSixtdCxRW210XSk7aWYoUXIpZm9yKHZhciBtdCBvZiBRcihRKSlYdS5jYWxsKFEsbXQpJiZHdShKLG10LFFbbXRdKTtyZXR1cm4gSn0sWmU9KEosUSk9PkZnKEosSWcoUSkpO3ZhciBKdT0oSixRKT0+e3ZhciBtdD17fTtmb3IodmFyIE10IGluIEopWnUuY2FsbChKLE10KSYmUS5pbmRleE9mKE10KTwwJiYobXRbTXRdPUpbTXRdKTtpZihKIT1udWxsJiZRcilmb3IodmFyIE10IG9mIFFyKEopKVEuaW5kZXhPZihNdCk8MCYmWHUuY2FsbChKLE10KSYmKG10W010XT1KW010XSk7cmV0dXJuIG10fTt2YXIgTmc9ZnVuY3Rpb24oSixRKXt0aGlzWzBdPUosdGhpc1sxXT1RfTt2YXIgWXU9Sj0+e3ZhciBRPUpbZ2MoImFzeW5jSXRlcmF0b3IiKV0sbXQ9ITEsTXQsY249e307cmV0dXJuIFE9PW51bGw/KFE9SltnYygiaXRlcmF0b3IiKV0oKSxNdD1TZT0+Y25bU2VdPUJuPT5RW1NlXShCbikpOihRPVEuY2FsbChKKSxNdD1TZT0+Y25bU2VdPUJuPT57aWYobXQpe2lmKG10PSExLFNlPT09InRocm93Iil0aHJvdyBCbjtyZXR1cm4gQm59cmV0dXJuIG10PSEwLHtkb25lOiExLHZhbHVlOm5ldyBOZyhuZXcgUHJvbWlzZSh4Yz0+e3ZhciBLcj1RW1NlXShCbik7S3IgaW5zdGFuY2VvZiBPYmplY3R8fGtnKCJPYmplY3QgZXhwZWN0ZWQiKSx4YyhLcil9KSwxKX19KSxjbltnYygiaXRlcmF0b3IiKV09KCk9PmNuLE10KCJuZXh0IiksInRocm93ImluIFE/TXQoInRocm93Iik6Y24udGhyb3c9U2U9Pnt0aHJvdyBTZX0sInJldHVybiJpbiBRJiZNdCgicmV0dXJuIiksY259OyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTAtMjAyNSBUaHJlZS5qcyBBdXRob3JzCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKICovY29uc3QgSj0iMTc4Iix3Yz0iIixvZT0ic3JnYiIsYmM9InNyZ2ItbGluZWFyIixNYz0ibGluZWFyIix0bz0ic3JnYiI7Y2xhc3Mgb3N7YWRkRXZlbnRMaXN0ZW5lcih0LGUpe3RoaXMuX2xpc3RlbmVycz09PXZvaWQgMCYmKHRoaXMuX2xpc3RlbmVycz17fSk7Y29uc3Qgbj10aGlzLl9saXN0ZW5lcnM7blt0XT09PXZvaWQgMCYmKG5bdF09W10pLG5bdF0uaW5kZXhPZihlKT09PS0xJiZuW3RdLnB1c2goZSl9aGFzRXZlbnRMaXN0ZW5lcih0LGUpe2NvbnN0IG49dGhpcy5fbGlzdGVuZXJzO3JldHVybiBuPT09dm9pZCAwPyExOm5bdF0hPT12b2lkIDAmJm5bdF0uaW5kZXhPZihlKSE9PS0xfXJlbW92ZUV2ZW50TGlzdGVuZXIodCxlKXtjb25zdCBuPXRoaXMuX2xpc3RlbmVycztpZihuPT09dm9pZCAwKXJldHVybjtjb25zdCBzPW5bdF07aWYocyE9PXZvaWQgMCl7Y29uc3Qgcj1zLmluZGV4T2YoZSk7ciE9PS0xJiZzLnNwbGljZShyLDEpfX1kaXNwYXRjaEV2ZW50KHQpe2NvbnN0IGU9dGhpcy5fbGlzdGVuZXJzO2lmKGU9PT12b2lkIDApcmV0dXJuO2NvbnN0IG49ZVt0LnR5cGVdO2lmKG4hPT12b2lkIDApe3QudGFyZ2V0PXRoaXM7Y29uc3Qgcz1uLnNsaWNlKDApO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLmNhbGwodGhpcyx0KTt0LnRhcmdldD1udWxsfX19Y29uc3QgQXQ9WyIwMCIsIjAxIiwiMDIiLCIwMyIsIjA0IiwiMDUiLCIwNiIsIjA3IiwiMDgiLCIwOSIsIjBhIiwiMGIiLCIwYyIsIjBkIiwiMGUiLCIwZiIsIjEwIiwiMTEiLCIxMiIsIjEzIiwiMTQiLCIxNSIsIjE2IiwiMTciLCIxOCIsIjE5IiwiMWEiLCIxYiIsIjFjIiwiMWQiLCIxZSIsIjFmIiwiMjAiLCIyMSIsIjIyIiwiMjMiLCIyNCIsIjI1IiwiMjYiLCIyNyIsIjI4IiwiMjkiLCIyYSIsIjJiIiwiMmMiLCIyZCIsIjJlIiwiMmYiLCIzMCIsIjMxIiwiMzIiLCIzMyIsIjM0IiwiMzUiLCIzNiIsIjM3IiwiMzgiLCIzOSIsIjNhIiwiM2IiLCIzYyIsIjNkIiwiM2UiLCIzZiIsIjQwIiwiNDEiLCI0MiIsIjQzIiwiNDQiLCI0NSIsIjQ2IiwiNDciLCI0OCIsIjQ5IiwiNGEiLCI0YiIsIjRjIiwiNGQiLCI0ZSIsIjRmIiwiNTAiLCI1MSIsIjUyIiwiNTMiLCI1NCIsIjU1IiwiNTYiLCI1NyIsIjU4IiwiNTkiLCI1YSIsIjViIiwiNWMiLCI1ZCIsIjVlIiwiNWYiLCI2MCIsIjYxIiwiNjIiLCI2MyIsIjY0IiwiNjUiLCI2NiIsIjY3IiwiNjgiLCI2OSIsIjZhIiwiNmIiLCI2YyIsIjZkIiwiNmUiLCI2ZiIsIjcwIiwiNzEiLCI3MiIsIjczIiwiNzQiLCI3NSIsIjc2IiwiNzciLCI3OCIsIjc5IiwiN2EiLCI3YiIsIjdjIiwiN2QiLCI3ZSIsIjdmIiwiODAiLCI4MSIsIjgyIiwiODMiLCI4NCIsIjg1IiwiODYiLCI4NyIsIjg4IiwiODkiLCI4YSIsIjhiIiwiOGMiLCI4ZCIsIjhlIiwiOGYiLCI5MCIsIjkxIiwiOTIiLCI5MyIsIjk0IiwiOTUiLCI5NiIsIjk3IiwiOTgiLCI5OSIsIjlhIiwiOWIiLCI5YyIsIjlkIiwiOWUiLCI5ZiIsImEwIiwiYTEiLCJhMiIsImEzIiwiYTQiLCJhNSIsImE2IiwiYTciLCJhOCIsImE5IiwiYWEiLCJhYiIsImFjIiwiYWQiLCJhZSIsImFmIiwiYjAiLCJiMSIsImIyIiwiYjMiLCJiNCIsImI1IiwiYjYiLCJiNyIsImI4IiwiYjkiLCJiYSIsImJiIiwiYmMiLCJiZCIsImJlIiwiYmYiLCJjMCIsImMxIiwiYzIiLCJjMyIsImM0IiwiYzUiLCJjNiIsImM3IiwiYzgiLCJjOSIsImNhIiwiY2IiLCJjYyIsImNkIiwiY2UiLCJjZiIsImQwIiwiZDEiLCJkMiIsImQzIiwiZDQiLCJkNSIsImQ2IiwiZDciLCJkOCIsImQ5IiwiZGEiLCJkYiIsImRjIiwiZGQiLCJkZSIsImRmIiwiZTAiLCJlMSIsImUyIiwiZTMiLCJlNCIsImU1IiwiZTYiLCJlNyIsImU4IiwiZTkiLCJlYSIsImViIiwiZWMiLCJlZCIsImVlIiwiZWYiLCJmMCIsImYxIiwiZjIiLCJmMyIsImY0IiwiZjUiLCJmNiIsImY3IiwiZjgiLCJmOSIsImZhIiwiZmIiLCJmYyIsImZkIiwiZmUiLCJmZiJdO2Z1bmN0aW9uIEZuKCl7Y29uc3QgaT1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MCx0PU1hdGgucmFuZG9tKCkqNDI5NDk2NzI5NXwwLGU9TWF0aC5yYW5kb20oKSo0Mjk0OTY3Mjk1fDAsbj1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MDtyZXR1cm4oQXRbaSYyNTVdK0F0W2k+PjgmMjU1XStBdFtpPj4xNiYyNTVdK0F0W2k+PjI0JjI1NV0rIi0iK0F0W3QmMjU1XStBdFt0Pj44JjI1NV0rIi0iK0F0W3Q+PjE2JjE1fDY0XStBdFt0Pj4yNCYyNTVdKyItIitBdFtlJjYzfDEyOF0rQXRbZT4+OCYyNTVdKyItIitBdFtlPj4xNiYyNTVdK0F0W2U+PjI0JjI1NV0rQXRbbiYyNTVdK0F0W24+PjgmMjU1XStBdFtuPj4xNiYyNTVdK0F0W24+PjI0JjI1NV0pLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gWihpLHQsZSl7cmV0dXJuIE1hdGgubWF4KHQsTWF0aC5taW4oZSxpKSl9ZnVuY3Rpb24ganUoaSx0KXtyZXR1cm4oaSV0K3QpJXR9ZnVuY3Rpb24gZW8oaSx0LGUpe3JldHVybigxLWUpKmkrZSp0fWZ1bmN0aW9uIG1pKGksdCl7c3dpdGNoKHQuY29uc3RydWN0b3Ipe2Nhc2UgRmxvYXQzMkFycmF5OnJldHVybiBpO2Nhc2UgVWludDMyQXJyYXk6cmV0dXJuIGkvNDI5NDk2NzI5NTtjYXNlIFVpbnQxNkFycmF5OnJldHVybiBpLzY1NTM1O2Nhc2UgVWludDhBcnJheTpyZXR1cm4gaS8yNTU7Y2FzZSBJbnQzMkFycmF5OnJldHVybiBNYXRoLm1heChpLzIxNDc0ODM2NDcsLTEpO2Nhc2UgSW50MTZBcnJheTpyZXR1cm4gTWF0aC5tYXgoaS8zMjc2NywtMSk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgubWF4KGkvMTI3LC0xKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiSW52YWxpZCBjb21wb25lbnQgdHlwZS4iKX19ZnVuY3Rpb24gSXQoaSx0KXtzd2l0Y2godC5jb25zdHJ1Y3Rvcil7Y2FzZSBGbG9hdDMyQXJyYXk6cmV0dXJuIGk7Y2FzZSBVaW50MzJBcnJheTpyZXR1cm4gTWF0aC5yb3VuZChpKjQyOTQ5NjcyOTUpO2Nhc2UgVWludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSo2NTUzNSk7Y2FzZSBVaW50OEFycmF5OnJldHVybiBNYXRoLnJvdW5kKGkqMjU1KTtjYXNlIEludDMyQXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoyMTQ3NDgzNjQ3KTtjYXNlIEludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSozMjc2Nyk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoxMjcpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGNvbXBvbmVudCB0eXBlLiIpfX1jbGFzcyBSe2NvbnN0cnVjdG9yKHQ9MCxlPTApe1IucHJvdG90eXBlLmlzVmVjdG9yMj0hMCx0aGlzLng9dCx0aGlzLnk9ZX1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy54fXNldCB3aWR0aCh0KXt0aGlzLng9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMueX1zZXQgaGVpZ2h0KHQpe3RoaXMueT10fXNldCh0LGUpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Q29tcG9uZW50KHQsZSl7c3dpdGNoKHQpe2Nhc2UgMDp0aGlzLng9ZTticmVhaztjYXNlIDE6dGhpcy55PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnkpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PXNbMF0qZStzWzNdKm4rc1s2XSx0aGlzLnk9c1sxXSplK3NbNF0qbitzWzddLHRoaXN9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueX1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSl9bWFuaGF0dGFuTGVuZ3RoKCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueCkrTWF0aC5hYnModGhpcy55KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9YW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMigtdGhpcy55LC10aGlzLngpK01hdGguUEl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnk7cmV0dXJuIGUqZStuKm59bWFuaGF0dGFuRGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5hYnModGhpcy54LXQueCkrTWF0aC5hYnModGhpcy55LXQueSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXN9cm90YXRlQXJvdW5kKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9dGhpcy54LXQueCxvPXRoaXMueS10Lnk7cmV0dXJuIHRoaXMueD1yKm4tbypzK3QueCx0aGlzLnk9cipzK28qbit0LnksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55fX1jbGFzcyBnaXtjb25zdHJ1Y3Rvcih0PTAsZT0wLG49MCxzPTEpe3RoaXMuaXNRdWF0ZXJuaW9uPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9c31zdGF0aWMgc2xlcnBGbGF0KHQsZSxuLHMscixvLGEpe2xldCBjPW5bcyswXSxsPW5bcysxXSxoPW5bcysyXSx1PW5bcyszXTtjb25zdCBmPXJbbyswXSxkPXJbbysxXSxwPXJbbysyXSx5PXJbbyszXTtpZihhPT09MCl7dFtlKzBdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXU7cmV0dXJufWlmKGE9PT0xKXt0W2UrMF09Zix0W2UrMV09ZCx0W2UrMl09cCx0W2UrM109eTtyZXR1cm59aWYodSE9PXl8fGMhPT1mfHxsIT09ZHx8aCE9PXApe2xldCBtPTEtYTtjb25zdCBnPWMqZitsKmQraCpwK3UqeSxiPWc+PTA/MTotMSx3PTEtZypnO2lmKHc+TnVtYmVyLkVQU0lMT04pe2NvbnN0IE09TWF0aC5zcXJ0KHcpLEE9TWF0aC5hdGFuMihNLGcqYik7bT1NYXRoLnNpbihtKkEpL00sYT1NYXRoLnNpbihhKkEpL019Y29uc3QgeD1hKmI7aWYoYz1jKm0rZip4LGw9bCptK2QqeCxoPWgqbStwKngsdT11Km0reSp4LG09PT0xLWEpe2NvbnN0IE09MS9NYXRoLnNxcnQoYypjK2wqbCtoKmgrdSp1KTtjKj1NLGwqPU0saCo9TSx1Kj1NfX10W2VdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXV9c3RhdGljIG11bHRpcGx5UXVhdGVybmlvbnNGbGF0KHQsZSxuLHMscixvKXtjb25zdCBhPW5bc10sYz1uW3MrMV0sbD1uW3MrMl0saD1uW3MrM10sdT1yW29dLGY9cltvKzFdLGQ9cltvKzJdLHA9cltvKzNdO3JldHVybiB0W2VdPWEqcCtoKnUrYypkLWwqZix0W2UrMV09YypwK2gqZitsKnUtYSpkLHRbZSsyXT1sKnAraCpkK2EqZi1jKnUsdFtlKzNdPWgqcC1hKnUtYypmLWwqZCx0fWdldCB4KCl7cmV0dXJuIHRoaXMuX3h9c2V0IHgodCl7dGhpcy5feD10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeSgpe3JldHVybiB0aGlzLl95fXNldCB5KHQpe3RoaXMuX3k9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHooKXtyZXR1cm4gdGhpcy5fen1zZXQgeih0KXt0aGlzLl96PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB3KCl7cmV0dXJuIHRoaXMuX3d9c2V0IHcodCl7dGhpcy5fdz10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scyl7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9cyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl94LHRoaXMuX3ksdGhpcy5feix0aGlzLl93KX1jb3B5KHQpe3JldHVybiB0aGlzLl94PXQueCx0aGlzLl95PXQueSx0aGlzLl96PXQueix0aGlzLl93PXQudyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zZXRGcm9tRXVsZXIodCxlPSEwKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX29yZGVyLGE9TWF0aC5jb3MsYz1NYXRoLnNpbixsPWEobi8yKSxoPWEocy8yKSx1PWEoci8yKSxmPWMobi8yKSxkPWMocy8yKSxwPWMoci8yKTtzd2l0Y2gobyl7Y2FzZSJYWVoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJZWFoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJaWFkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJZWlgiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJYWlkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLlF1YXRlcm5pb246IC5zZXRGcm9tRXVsZXIoKSBlbmNvdW50ZXJlZCBhbiB1bmtub3duIG9yZGVyOiAiK28pfXJldHVybiBlPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21BeGlzQW5nbGUodCxlKXtjb25zdCBuPWUvMixzPU1hdGguc2luKG4pO3JldHVybiB0aGlzLl94PXQueCpzLHRoaXMuX3k9dC55KnMsdGhpcy5fej10Lnoqcyx0aGlzLl93PU1hdGguY29zKG4pLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0KXtjb25zdCBlPXQuZWxlbWVudHMsbj1lWzBdLHM9ZVs0XSxyPWVbOF0sbz1lWzFdLGE9ZVs1XSxjPWVbOV0sbD1lWzJdLGg9ZVs2XSx1PWVbMTBdLGY9bithK3U7aWYoZj4wKXtjb25zdCBkPS41L01hdGguc3FydChmKzEpO3RoaXMuX3c9LjI1L2QsdGhpcy5feD0oaC1jKSpkLHRoaXMuX3k9KHItbCkqZCx0aGlzLl96PShvLXMpKmR9ZWxzZSBpZihuPmEmJm4+dSl7Y29uc3QgZD0yKk1hdGguc3FydCgxK24tYS11KTt0aGlzLl93PShoLWMpL2QsdGhpcy5feD0uMjUqZCx0aGlzLl95PShzK28pL2QsdGhpcy5fej0ocitsKS9kfWVsc2UgaWYoYT51KXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErYS1uLXUpO3RoaXMuX3c9KHItbCkvZCx0aGlzLl94PShzK28pL2QsdGhpcy5feT0uMjUqZCx0aGlzLl96PShjK2gpL2R9ZWxzZXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErdS1uLWEpO3RoaXMuX3c9KG8tcykvZCx0aGlzLl94PShyK2wpL2QsdGhpcy5feT0oYytoKS9kLHRoaXMuX3o9LjI1KmR9cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Vbml0VmVjdG9ycyh0LGUpe2xldCBuPXQuZG90KGUpKzE7cmV0dXJuIG48MWUtOD8obj0wLE1hdGguYWJzKHQueCk+TWF0aC5hYnModC56KT8odGhpcy5feD0tdC55LHRoaXMuX3k9dC54LHRoaXMuX3o9MCx0aGlzLl93PW4pOih0aGlzLl94PTAsdGhpcy5feT0tdC56LHRoaXMuX3o9dC55LHRoaXMuX3c9bikpOih0aGlzLl94PXQueSplLnotdC56KmUueSx0aGlzLl95PXQueiplLngtdC54KmUueix0aGlzLl96PXQueCplLnktdC55KmUueCx0aGlzLl93PW4pLHRoaXMubm9ybWFsaXplKCl9YW5nbGVUbyh0KXtyZXR1cm4gMipNYXRoLmFjb3MoTWF0aC5hYnMoWih0aGlzLmRvdCh0KSwtMSwxKSkpfXJvdGF0ZVRvd2FyZHModCxlKXtjb25zdCBuPXRoaXMuYW5nbGVUbyh0KTtpZihuPT09MClyZXR1cm4gdGhpcztjb25zdCBzPU1hdGgubWluKDEsZS9uKTtyZXR1cm4gdGhpcy5zbGVycCh0LHMpLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMSl9aW52ZXJ0KCl7cmV0dXJuIHRoaXMuY29uanVnYXRlKCl9Y29uanVnYXRlKCl7cmV0dXJuIHRoaXMuX3gqPS0xLHRoaXMuX3kqPS0xLHRoaXMuX3oqPS0xLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfWRvdCh0KXtyZXR1cm4gdGhpcy5feCp0Ll94K3RoaXMuX3kqdC5feSt0aGlzLl96KnQuX3ordGhpcy5fdyp0Ll93fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fd31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fdyl9bm9ybWFsaXplKCl7bGV0IHQ9dGhpcy5sZW5ndGgoKTtyZXR1cm4gdD09PTA/KHRoaXMuX3g9MCx0aGlzLl95PTAsdGhpcy5fej0wLHRoaXMuX3c9MSk6KHQ9MS90LHRoaXMuX3g9dGhpcy5feCp0LHRoaXMuX3k9dGhpcy5feSp0LHRoaXMuX3o9dGhpcy5feip0LHRoaXMuX3c9dGhpcy5fdyp0KSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseVF1YXRlcm5pb25zKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlRdWF0ZXJuaW9ucyh0LHRoaXMpfW11bHRpcGx5UXVhdGVybmlvbnModCxlKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX3csYT1lLl94LGM9ZS5feSxsPWUuX3osaD1lLl93O3JldHVybiB0aGlzLl94PW4qaCtvKmErcypsLXIqYyx0aGlzLl95PXMqaCtvKmMrciphLW4qbCx0aGlzLl96PXIqaCtvKmwrbipjLXMqYSx0aGlzLl93PW8qaC1uKmEtcypjLXIqbCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zbGVycCh0LGUpe2lmKGU9PT0wKXJldHVybiB0aGlzO2lmKGU9PT0xKXJldHVybiB0aGlzLmNvcHkodCk7Y29uc3Qgbj10aGlzLl94LHM9dGhpcy5feSxyPXRoaXMuX3osbz10aGlzLl93O2xldCBhPW8qdC5fdytuKnQuX3grcyp0Ll95K3IqdC5fejtpZihhPDA/KHRoaXMuX3c9LXQuX3csdGhpcy5feD0tdC5feCx0aGlzLl95PS10Ll95LHRoaXMuX3o9LXQuX3osYT0tYSk6dGhpcy5jb3B5KHQpLGE+PTEpcmV0dXJuIHRoaXMuX3c9byx0aGlzLl94PW4sdGhpcy5feT1zLHRoaXMuX3o9cix0aGlzO2NvbnN0IGM9MS1hKmE7aWYoYzw9TnVtYmVyLkVQU0lMT04pe2NvbnN0IGQ9MS1lO3JldHVybiB0aGlzLl93PWQqbytlKnRoaXMuX3csdGhpcy5feD1kKm4rZSp0aGlzLl94LHRoaXMuX3k9ZCpzK2UqdGhpcy5feSx0aGlzLl96PWQqcitlKnRoaXMuX3osdGhpcy5ub3JtYWxpemUoKSx0aGlzfWNvbnN0IGw9TWF0aC5zcXJ0KGMpLGg9TWF0aC5hdGFuMihsLGEpLHU9TWF0aC5zaW4oKDEtZSkqaCkvbCxmPU1hdGguc2luKGUqaCkvbDtyZXR1cm4gdGhpcy5fdz1vKnUrdGhpcy5fdypmLHRoaXMuX3g9bip1K3RoaXMuX3gqZix0aGlzLl95PXMqdSt0aGlzLl95KmYsdGhpcy5fej1yKnUrdGhpcy5feipmLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNsZXJwUXVhdGVybmlvbnModCxlLG4pe3JldHVybiB0aGlzLmNvcHkodCkuc2xlcnAoZSxuKX1yYW5kb20oKXtjb25zdCB0PTIqTWF0aC5QSSpNYXRoLnJhbmRvbSgpLGU9MipNYXRoLlBJKk1hdGgucmFuZG9tKCksbj1NYXRoLnJhbmRvbSgpLHM9TWF0aC5zcXJ0KDEtbikscj1NYXRoLnNxcnQobik7cmV0dXJuIHRoaXMuc2V0KHMqTWF0aC5zaW4odCkscypNYXRoLmNvcyh0KSxyKk1hdGguc2luKGUpLHIqTWF0aC5jb3MoZSkpfWVxdWFscyh0KXtyZXR1cm4gdC5feD09PXRoaXMuX3gmJnQuX3k9PT10aGlzLl95JiZ0Ll96PT09dGhpcy5feiYmdC5fdz09PXRoaXMuX3d9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy5feD10W2VdLHRoaXMuX3k9dFtlKzFdLHRoaXMuX3o9dFtlKzJdLHRoaXMuX3c9dFtlKzNdLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMuX3gsdFtlKzFdPXRoaXMuX3ksdFtlKzJdPXRoaXMuX3osdFtlKzNdPXRoaXMuX3csdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMuX3g9dC5nZXRYKGUpLHRoaXMuX3k9dC5nZXRZKGUpLHRoaXMuX3o9dC5nZXRaKGUpLHRoaXMuX3c9dC5nZXRXKGUpLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvSlNPTigpe3JldHVybiB0aGlzLnRvQXJyYXkoKX1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX3d9fWNsYXNzIFR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTApe1QucHJvdG90eXBlLmlzVmVjdG9yMz0hMCx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bn1zZXQodCxlLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj10aGlzLnopLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXN9c2V0U2NhbGFyKHQpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9dCx0aGlzLno9dCx0aGlzfXNldFgodCl7cmV0dXJuIHRoaXMueD10LHRoaXN9c2V0WSh0KXtyZXR1cm4gdGhpcy55PXQsdGhpc31zZXRaKHQpe3JldHVybiB0aGlzLno9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAiK3QpfXJldHVybiB0aGlzfWdldENvbXBvbmVudCh0KXtzd2l0Y2godCl7Y2FzZSAwOnJldHVybiB0aGlzLng7Y2FzZSAxOnJldHVybiB0aGlzLnk7Y2FzZSAyOnJldHVybiB0aGlzLno7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX19Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy54LHRoaXMueSx0aGlzLnopfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzLno9dC56LHRoaXN9YWRkKHQpe3JldHVybiB0aGlzLngrPXQueCx0aGlzLnkrPXQueSx0aGlzLnorPXQueix0aGlzfWFkZFNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kz10LHRoaXMueSs9dCx0aGlzLnorPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXMuej10LnorZS56LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzLnorPXQueiplLHRoaXN9c3ViKHQpe3JldHVybiB0aGlzLngtPXQueCx0aGlzLnktPXQueSx0aGlzLnotPXQueix0aGlzfXN1YlNjYWxhcih0KXtyZXR1cm4gdGhpcy54LT10LHRoaXMueS09dCx0aGlzLnotPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXMuej10LnotZS56LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXMueio9dC56LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpcy56Kj10LHRoaXN9bXVsdGlwbHlWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngqZS54LHRoaXMueT10LnkqZS55LHRoaXMuej10LnoqZS56LHRoaXN9YXBwbHlFdWxlcih0KXtyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oQWMuc2V0RnJvbUV1bGVyKHQpKX1hcHBseUF4aXNBbmdsZSh0LGUpe3JldHVybiB0aGlzLmFwcGx5UXVhdGVybmlvbihBYy5zZXRGcm9tQXhpc0FuZ2xlKHQsZSkpfWFwcGx5TWF0cml4Myh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrclszXSpuK3JbNl0qcyx0aGlzLnk9clsxXSplK3JbNF0qbityWzddKnMsdGhpcy56PXJbMl0qZStyWzVdKm4rcls4XSpzLHRoaXN9YXBwbHlOb3JtYWxNYXRyaXgodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXgzKHQpLm5vcm1hbGl6ZSgpfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHMsbz0xLyhyWzNdKmUrcls3XSpuK3JbMTFdKnMrclsxNV0pO3JldHVybiB0aGlzLng9KHJbMF0qZStyWzRdKm4rcls4XSpzK3JbMTJdKSpvLHRoaXMueT0oclsxXSplK3JbNV0qbityWzldKnMrclsxM10pKm8sdGhpcy56PShyWzJdKmUrcls2XSpuK3JbMTBdKnMrclsxNF0pKm8sdGhpc31hcHBseVF1YXRlcm5pb24odCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10Lngsbz10LnksYT10LnosYz10LncsbD0yKihvKnMtYSpuKSxoPTIqKGEqZS1yKnMpLHU9MioocipuLW8qZSk7cmV0dXJuIHRoaXMueD1lK2MqbCtvKnUtYSpoLHRoaXMueT1uK2MqaCthKmwtcip1LHRoaXMuej1zK2MqdStyKmgtbypsLHRoaXN9cHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZEludmVyc2UpLmFwcGx5TWF0cml4NCh0LnByb2plY3Rpb25NYXRyaXgpfXVucHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5wcm9qZWN0aW9uTWF0cml4SW52ZXJzZSkuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpfXRyYW5zZm9ybURpcmVjdGlvbih0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrcls0XSpuK3JbOF0qcyx0aGlzLnk9clsxXSplK3JbNV0qbityWzldKnMsdGhpcy56PXJbMl0qZStyWzZdKm4rclsxMF0qcyx0aGlzLm5vcm1hbGl6ZSgpfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1taW4odCl7cmV0dXJuIHRoaXMueD1NYXRoLm1pbih0aGlzLngsdC54KSx0aGlzLnk9TWF0aC5taW4odGhpcy55LHQueSksdGhpcy56PU1hdGgubWluKHRoaXMueix0LnopLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzfWNsYW1wKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LngsZS54KSx0aGlzLnk9Wih0aGlzLnksdC55LGUueSksdGhpcy56PVoodGhpcy56LHQueixlLnopLHRoaXN9Y2xhbXBTY2FsYXIodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQsZSksdGhpcy55PVoodGhpcy55LHQsZSksdGhpcy56PVoodGhpcy56LHQsZSksdGhpc31jbGFtcExlbmd0aCh0LGUpe2NvbnN0IG49dGhpcy5sZW5ndGgoKTtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIobnx8MSkubXVsdGlwbHlTY2FsYXIoWihuLHQsZSkpfWZsb29yKCl7cmV0dXJuIHRoaXMueD1NYXRoLmZsb29yKHRoaXMueCksdGhpcy55PU1hdGguZmxvb3IodGhpcy55KSx0aGlzLno9TWF0aC5mbG9vcih0aGlzLnopLHRoaXN9Y2VpbCgpe3JldHVybiB0aGlzLng9TWF0aC5jZWlsKHRoaXMueCksdGhpcy55PU1hdGguY2VpbCh0aGlzLnkpLHRoaXMuej1NYXRoLmNlaWwodGhpcy56KSx0aGlzfXJvdW5kKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJvdW5kKHRoaXMueCksdGhpcy55PU1hdGgucm91bmQodGhpcy55KSx0aGlzLno9TWF0aC5yb3VuZCh0aGlzLnopLHRoaXN9cm91bmRUb1plcm8oKXtyZXR1cm4gdGhpcy54PU1hdGgudHJ1bmModGhpcy54KSx0aGlzLnk9TWF0aC50cnVuYyh0aGlzLnkpLHRoaXMuej1NYXRoLnRydW5jKHRoaXMueiksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56fWxlbmd0aCgpe3JldHVybiBNYXRoLnNxcnQodGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnopfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXMueis9KHQuei10aGlzLnopKmUsdGhpc31sZXJwVmVjdG9ycyh0LGUsbil7cmV0dXJuIHRoaXMueD10LngrKGUueC10LngpKm4sdGhpcy55PXQueSsoZS55LXQueSkqbix0aGlzLno9dC56KyhlLnotdC56KSpuLHRoaXN9Y3Jvc3ModCl7cmV0dXJuIHRoaXMuY3Jvc3NWZWN0b3JzKHRoaXMsdCl9Y3Jvc3NWZWN0b3JzKHQsZSl7Y29uc3Qgbj10Lngscz10Lnkscj10Lnosbz1lLngsYT1lLnksYz1lLno7cmV0dXJuIHRoaXMueD1zKmMtciphLHRoaXMueT1yKm8tbipjLHRoaXMuej1uKmEtcypvLHRoaXN9cHJvamVjdE9uVmVjdG9yKHQpe2NvbnN0IGU9dC5sZW5ndGhTcSgpO2lmKGU9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCk7Y29uc3Qgbj10LmRvdCh0aGlzKS9lO3JldHVybiB0aGlzLmNvcHkodCkubXVsdGlwbHlTY2FsYXIobil9cHJvamVjdE9uUGxhbmUodCl7cmV0dXJuIG5vLmNvcHkodGhpcykucHJvamVjdE9uVmVjdG9yKHQpLHRoaXMuc3ViKG5vKX1yZWZsZWN0KHQpe3JldHVybiB0aGlzLnN1Yihuby5jb3B5KHQpLm11bHRpcGx5U2NhbGFyKDIqdGhpcy5kb3QodCkpKX1hbmdsZVRvKHQpe2NvbnN0IGU9TWF0aC5zcXJ0KHRoaXMubGVuZ3RoU3EoKSp0Lmxlbmd0aFNxKCkpO2lmKGU9PT0wKXJldHVybiBNYXRoLlBJLzI7Y29uc3Qgbj10aGlzLmRvdCh0KS9lO3JldHVybiBNYXRoLmFjb3MoWihuLC0xLDEpKX1kaXN0YW5jZVRvKHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVRvU3F1YXJlZCh0KSl9ZGlzdGFuY2VUb1NxdWFyZWQodCl7Y29uc3QgZT10aGlzLngtdC54LG49dGhpcy55LXQueSxzPXRoaXMuei10Lno7cmV0dXJuIGUqZStuKm4rcypzfW1hbmhhdHRhbkRpc3RhbmNlVG8odCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueC10LngpK01hdGguYWJzKHRoaXMueS10LnkpK01hdGguYWJzKHRoaXMuei10LnopfXNldEZyb21TcGhlcmljYWwodCl7cmV0dXJuIHRoaXMuc2V0RnJvbVNwaGVyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnBoaSx0LnRoZXRhKX1zZXRGcm9tU3BoZXJpY2FsQ29vcmRzKHQsZSxuKXtjb25zdCBzPU1hdGguc2luKGUpKnQ7cmV0dXJuIHRoaXMueD1zKk1hdGguc2luKG4pLHRoaXMueT1NYXRoLmNvcyhlKSp0LHRoaXMuej1zKk1hdGguY29zKG4pLHRoaXN9c2V0RnJvbUN5bGluZHJpY2FsKHQpe3JldHVybiB0aGlzLnNldEZyb21DeWxpbmRyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnRoZXRhLHQueSl9c2V0RnJvbUN5bGluZHJpY2FsQ29vcmRzKHQsZSxuKXtyZXR1cm4gdGhpcy54PXQqTWF0aC5zaW4oZSksdGhpcy55PW4sdGhpcy56PXQqTWF0aC5jb3MoZSksdGhpc31zZXRGcm9tTWF0cml4UG9zaXRpb24odCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9ZVsxMl0sdGhpcy55PWVbMTNdLHRoaXMuej1lWzE0XSx0aGlzfXNldEZyb21NYXRyaXhTY2FsZSh0KXtjb25zdCBlPXRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLG49dGhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCkscz10aGlzLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gdGhpcy54PWUsdGhpcy55PW4sdGhpcy56PXMsdGhpc31zZXRGcm9tTWF0cml4Q29sdW1uKHQsZSl7cmV0dXJuIHRoaXMuZnJvbUFycmF5KHQuZWxlbWVudHMsZSo0KX1zZXRGcm9tTWF0cml4M0NvbHVtbih0LGUpe3JldHVybiB0aGlzLmZyb21BcnJheSh0LmVsZW1lbnRzLGUqMyl9c2V0RnJvbUV1bGVyKHQpe3JldHVybiB0aGlzLng9dC5feCx0aGlzLnk9dC5feSx0aGlzLno9dC5feix0aGlzfXNldEZyb21Db2xvcih0KXtyZXR1cm4gdGhpcy54PXQucix0aGlzLnk9dC5nLHRoaXMuej10LmIsdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55JiZ0Lno9PT10aGlzLnp9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy54LHRbZSsxXT10aGlzLnksdFtlKzJdPXRoaXMueix0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXMuej10LmdldFooZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpc31yYW5kb21EaXJlY3Rpb24oKXtjb25zdCB0PU1hdGgucmFuZG9tKCkqTWF0aC5QSSoyLGU9TWF0aC5yYW5kb20oKSoyLTEsbj1NYXRoLnNxcnQoMS1lKmUpO3JldHVybiB0aGlzLng9bipNYXRoLmNvcyh0KSx0aGlzLnk9ZSx0aGlzLno9bipNYXRoLnNpbih0KSx0aGlzfSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMueCx5aWVsZCB0aGlzLnkseWllbGQgdGhpcy56fX1jb25zdCBubz1uZXcgVCxBYz1uZXcgZ2k7Y2xhc3MgZ2V7Y29uc3RydWN0b3IodCxlLG4scyxyLG8sYSxjLGwpe2dlLnByb3RvdHlwZS5pc01hdHJpeDM9ITAsdGhpcy5lbGVtZW50cz1bMSwwLDAsMCwxLDAsMCwwLDFdLHQhPT12b2lkIDAmJnRoaXMuc2V0KHQsZSxuLHMscixvLGEsYyxsKX1zZXQodCxlLG4scyxyLG8sYSxjLGwpe2NvbnN0IGg9dGhpcy5lbGVtZW50cztyZXR1cm4gaFswXT10LGhbMV09cyxoWzJdPWEsaFszXT1lLGhbNF09cixoWzVdPWMsaFs2XT1uLGhbN109byxoWzhdPWwsdGhpc31pZGVudGl0eSgpe3JldHVybiB0aGlzLnNldCgxLDAsMCwwLDEsMCwwLDAsMSksdGhpc31jb3B5KHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7cmV0dXJuIGVbMF09blswXSxlWzFdPW5bMV0sZVsyXT1uWzJdLGVbM109blszXSxlWzRdPW5bNF0sZVs1XT1uWzVdLGVbNl09bls2XSxlWzddPW5bN10sZVs4XT1uWzhdLHRoaXN9ZXh0cmFjdEJhc2lzKHQsZSxuKXtyZXR1cm4gdC5zZXRGcm9tTWF0cml4M0NvbHVtbih0aGlzLDApLGUuc2V0RnJvbU1hdHJpeDNDb2x1bW4odGhpcywxKSxuLnNldEZyb21NYXRyaXgzQ29sdW1uKHRoaXMsMiksdGhpc31zZXRGcm9tTWF0cml4NCh0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMuc2V0KGVbMF0sZVs0XSxlWzhdLGVbMV0sZVs1XSxlWzldLGVbMl0sZVs2XSxlWzEwXSksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0LHRoaXMpfW11bHRpcGx5TWF0cmljZXModCxlKXtjb25zdCBuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzLHI9dGhpcy5lbGVtZW50cyxvPW5bMF0sYT1uWzNdLGM9bls2XSxsPW5bMV0saD1uWzRdLHU9bls3XSxmPW5bMl0sZD1uWzVdLHA9bls4XSx5PXNbMF0sbT1zWzNdLGc9c1s2XSxiPXNbMV0sdz1zWzRdLHg9c1s3XSxNPXNbMl0sQT1zWzVdLFM9c1s4XTtyZXR1cm4gclswXT1vKnkrYSpiK2MqTSxyWzNdPW8qbSthKncrYypBLHJbNl09bypnK2EqeCtjKlMsclsxXT1sKnkraCpiK3UqTSxyWzRdPWwqbStoKncrdSpBLHJbN109bCpnK2gqeCt1KlMsclsyXT1mKnkrZCpiK3AqTSxyWzVdPWYqbStkKncrcCpBLHJbOF09ZipnK2QqeCtwKlMsdGhpc31tdWx0aXBseVNjYWxhcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIGVbMF0qPXQsZVszXSo9dCxlWzZdKj10LGVbMV0qPXQsZVs0XSo9dCxlWzddKj10LGVbMl0qPXQsZVs1XSo9dCxlWzhdKj10LHRoaXN9ZGV0ZXJtaW5hbnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFsxXSxzPXRbMl0scj10WzNdLG89dFs0XSxhPXRbNV0sYz10WzZdLGw9dFs3XSxoPXRbOF07cmV0dXJuIGUqbypoLWUqYSpsLW4qcipoK24qYSpjK3MqcipsLXMqbypjfWludmVydCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSx1PWgqby1hKmwsZj1hKmMtaCpyLGQ9bCpyLW8qYyxwPWUqdStuKmYrcypkO2lmKHA9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCwwLDAsMCwwLDAsMCk7Y29uc3QgeT0xL3A7cmV0dXJuIHRbMF09dSp5LHRbMV09KHMqbC1oKm4pKnksdFsyXT0oYSpuLXMqbykqeSx0WzNdPWYqeSx0WzRdPShoKmUtcypjKSp5LHRbNV09KHMqci1hKmUpKnksdFs2XT1kKnksdFs3XT0obipjLWwqZSkqeSx0WzhdPShvKmUtbipyKSp5LHRoaXN9dHJhbnNwb3NlKCl7bGV0IHQ7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiB0PWVbMV0sZVsxXT1lWzNdLGVbM109dCx0PWVbMl0sZVsyXT1lWzZdLGVbNl09dCx0PWVbNV0sZVs1XT1lWzddLGVbN109dCx0aGlzfWdldE5vcm1hbE1hdHJpeCh0KXtyZXR1cm4gdGhpcy5zZXRGcm9tTWF0cml4NCh0KS5pbnZlcnQoKS50cmFuc3Bvc2UoKX10cmFuc3Bvc2VJbnRvQXJyYXkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzNdLHRbMl09ZVs2XSx0WzNdPWVbMV0sdFs0XT1lWzRdLHRbNV09ZVs3XSx0WzZdPWVbMl0sdFs3XT1lWzVdLHRbOF09ZVs4XSx0aGlzfXNldFV2VHJhbnNmb3JtKHQsZSxuLHMscixvLGEpe2NvbnN0IGM9TWF0aC5jb3MociksbD1NYXRoLnNpbihyKTtyZXR1cm4gdGhpcy5zZXQobipjLG4qbCwtbiooYypvK2wqYSkrbyt0LC1zKmwscypjLC1zKigtbCpvK2MqYSkrYStlLDAsMCwxKSx0aGlzfXNjYWxlKHQsZSl7cmV0dXJuIHRoaXMucHJlbXVsdGlwbHkoaW8ubWFrZVNjYWxlKHQsZSkpLHRoaXN9cm90YXRlKHQpe3JldHVybiB0aGlzLnByZW11bHRpcGx5KGlvLm1ha2VSb3RhdGlvbigtdCkpLHRoaXN9dHJhbnNsYXRlKHQsZSl7cmV0dXJuIHRoaXMucHJlbXVsdGlwbHkoaW8ubWFrZVRyYW5zbGF0aW9uKHQsZSkpLHRoaXN9bWFrZVRyYW5zbGF0aW9uKHQsZSl7cmV0dXJuIHQuaXNWZWN0b3IyP3RoaXMuc2V0KDEsMCx0LngsMCwxLHQueSwwLDAsMSk6dGhpcy5zZXQoMSwwLHQsMCwxLGUsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoZSwtbiwwLG4sZSwwLDAsMCwxKSx0aGlzfW1ha2VTY2FsZSh0LGUpe3JldHVybiB0aGlzLnNldCh0LDAsMCwwLGUsMCwwLDAsMSksdGhpc31lcXVhbHModCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztmb3IobGV0IHM9MDtzPDk7cysrKWlmKGVbc10hPT1uW3NdKXJldHVybiExO3JldHVybiEwfWZyb21BcnJheSh0LGU9MCl7Zm9yKGxldCBuPTA7bjw5O24rKyl0aGlzLmVsZW1lbnRzW25dPXRbbitlXTtyZXR1cm4gdGhpc310b0FycmF5KHQ9W10sZT0wKXtjb25zdCBuPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbZV09blswXSx0W2UrMV09blsxXSx0W2UrMl09blsyXSx0W2UrM109blszXSx0W2UrNF09bls0XSx0W2UrNV09bls1XSx0W2UrNl09bls2XSx0W2UrN109bls3XSx0W2UrOF09bls4XSx0fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuZnJvbUFycmF5KHRoaXMuZWxlbWVudHMpfX1jb25zdCBpbz1uZXcgZ2U7ZnVuY3Rpb24gUXUoaSl7Zm9yKGxldCB0PWkubGVuZ3RoLTE7dD49MDstLXQpaWYoaVt0XT49NjU1MzUpcmV0dXJuITA7cmV0dXJuITF9ZnVuY3Rpb24gU2MoaSl7cmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsaSl9Y29uc3QgX2M9e307ZnVuY3Rpb24gdmMoaSl7aSBpbiBfY3x8KF9jW2ldPSEwLGNvbnNvbGUud2FybihpKSl9Y29uc3QgemM9bmV3IGdlKCkuc2V0KC40MTIzOTA4LC4zNTc1ODQzLC4xODA0ODA4LC4yMTI2MzksLjcxNTE2ODcsLjA3MjE5MjMsLjAxOTMzMDgsLjExOTE5NDgsLjk1MDUzMjIpLFRjPW5ldyBnZSgpLnNldCgzLjI0MDk2OTksLTEuNTM3MzgzMiwtLjQ5ODYxMDgsLS45NjkyNDM2LDEuODc1OTY3NSwuMDQxNTU1MSwuMDU1NjMwMSwtLjIwMzk3NywxLjA1Njk3MTUpO2Z1bmN0aW9uIEt1KCl7Y29uc3QgaT17ZW5hYmxlZDohMCx3b3JraW5nQ29sb3JTcGFjZTpiYyxzcGFjZXM6e30sY29udmVydDpmdW5jdGlvbihzLHIsbyl7cmV0dXJuIHRoaXMuZW5hYmxlZD09PSExfHxyPT09b3x8IXJ8fCFvfHwodGhpcy5zcGFjZXNbcl0udHJhbnNmZXI9PT10byYmKHMucj1fZShzLnIpLHMuZz1fZShzLmcpLHMuYj1fZShzLmIpKSx0aGlzLnNwYWNlc1tyXS5wcmltYXJpZXMhPT10aGlzLnNwYWNlc1tvXS5wcmltYXJpZXMmJihzLmFwcGx5TWF0cml4Myh0aGlzLnNwYWNlc1tyXS50b1hZWikscy5hcHBseU1hdHJpeDModGhpcy5zcGFjZXNbb10uZnJvbVhZWikpLHRoaXMuc3BhY2VzW29dLnRyYW5zZmVyPT09dG8mJihzLnI9SW4ocy5yKSxzLmc9SW4ocy5nKSxzLmI9SW4ocy5iKSkpLHN9LHdvcmtpbmdUb0NvbG9yU3BhY2U6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdGhpcy5jb252ZXJ0KHMsdGhpcy53b3JraW5nQ29sb3JTcGFjZSxyKX0sY29sb3JTcGFjZVRvV29ya2luZzpmdW5jdGlvbihzLHIpe3JldHVybiB0aGlzLmNvbnZlcnQocyxyLHRoaXMud29ya2luZ0NvbG9yU3BhY2UpfSxnZXRQcmltYXJpZXM6ZnVuY3Rpb24ocyl7cmV0dXJuIHRoaXMuc3BhY2VzW3NdLnByaW1hcmllc30sZ2V0VHJhbnNmZXI6ZnVuY3Rpb24ocyl7cmV0dXJuIHM9PT13Yz9NYzp0aGlzLnNwYWNlc1tzXS50cmFuc2Zlcn0sZ2V0THVtaW5hbmNlQ29lZmZpY2llbnRzOmZ1bmN0aW9uKHMscj10aGlzLndvcmtpbmdDb2xvclNwYWNlKXtyZXR1cm4gcy5mcm9tQXJyYXkodGhpcy5zcGFjZXNbcl0ubHVtaW5hbmNlQ29lZmZpY2llbnRzKX0sZGVmaW5lOmZ1bmN0aW9uKHMpe09iamVjdC5hc3NpZ24odGhpcy5zcGFjZXMscyl9LF9nZXRNYXRyaXg6ZnVuY3Rpb24ocyxyLG8pe3JldHVybiBzLmNvcHkodGhpcy5zcGFjZXNbcl0udG9YWVopLm11bHRpcGx5KHRoaXMuc3BhY2VzW29dLmZyb21YWVopfSxfZ2V0RHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6ZnVuY3Rpb24ocyl7cmV0dXJuIHRoaXMuc3BhY2VzW3NdLm91dHB1dENvbG9yU3BhY2VDb25maWcuZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2V9LF9nZXRVbnBhY2tDb2xvclNwYWNlOmZ1bmN0aW9uKHM9dGhpcy53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHRoaXMuc3BhY2VzW3NdLndvcmtpbmdDb2xvclNwYWNlQ29uZmlnLnVucGFja0NvbG9yU3BhY2V9LGZyb21Xb3JraW5nQ29sb3JTcGFjZTpmdW5jdGlvbihzLHIpe3JldHVybiB2YygiVEhSRUUuQ29sb3JNYW5hZ2VtZW50OiAuZnJvbVdvcmtpbmdDb2xvclNwYWNlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAud29ya2luZ1RvQ29sb3JTcGFjZSgpLiIpLGkud29ya2luZ1RvQ29sb3JTcGFjZShzLHIpfSx0b1dvcmtpbmdDb2xvclNwYWNlOmZ1bmN0aW9uKHMscil7cmV0dXJuIHZjKCJUSFJFRS5Db2xvck1hbmFnZW1lbnQ6IC50b1dvcmtpbmdDb2xvclNwYWNlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAuY29sb3JTcGFjZVRvV29ya2luZygpLiIpLGkuY29sb3JTcGFjZVRvV29ya2luZyhzLHIpfX0sdD1bLjY0LC4zMywuMywuNiwuMTUsLjA2XSxlPVsuMjEyNiwuNzE1MiwuMDcyMl0sbj1bLjMxMjcsLjMyOV07cmV0dXJuIGkuZGVmaW5lKHtbYmNdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6TWMsdG9YWVo6emMsZnJvbVhZWjpUYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSx3b3JraW5nQ29sb3JTcGFjZUNvbmZpZzp7dW5wYWNrQ29sb3JTcGFjZTpvZX0sb3V0cHV0Q29sb3JTcGFjZUNvbmZpZzp7ZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6b2V9fSxbb2VdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6dG8sdG9YWVo6emMsZnJvbVhZWjpUYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSxvdXRwdXRDb2xvclNwYWNlQ29uZmlnOntkcmF3aW5nQnVmZmVyQ29sb3JTcGFjZTpvZX19fSksaX1jb25zdCBhZT1LdSgpO2Z1bmN0aW9uIF9lKGkpe3JldHVybiBpPC4wNDA0NT9pKi4wNzczOTkzODA4Ok1hdGgucG93KGkqLjk0Nzg2NzI5ODYrLjA1MjEzMjcwMTQsMi40KX1mdW5jdGlvbiBJbihpKXtyZXR1cm4gaTwuMDAzMTMwOD9pKjEyLjkyOjEuMDU1Kk1hdGgucG93KGksLjQxNjY2KS0uMDU1fWxldCBrbjtjbGFzcyB0ZntzdGF0aWMgZ2V0RGF0YVVSTCh0LGU9ImltYWdlL3BuZyIpe2lmKC9eZGF0YTovaS50ZXN0KHQuc3JjKXx8dHlwZW9mIEhUTUxDYW52YXNFbGVtZW50PT0idW5kZWZpbmVkIilyZXR1cm4gdC5zcmM7bGV0IG47aWYodCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KW49dDtlbHNle2tuPT09dm9pZCAwJiYoa249U2MoImNhbnZhcyIpKSxrbi53aWR0aD10LndpZHRoLGtuLmhlaWdodD10LmhlaWdodDtjb25zdCBzPWtuLmdldENvbnRleHQoIjJkIik7dCBpbnN0YW5jZW9mIEltYWdlRGF0YT9zLnB1dEltYWdlRGF0YSh0LDAsMCk6cy5kcmF3SW1hZ2UodCwwLDAsdC53aWR0aCx0LmhlaWdodCksbj1rbn1yZXR1cm4gbi50b0RhdGFVUkwoZSl9c3RhdGljIHNSR0JUb0xpbmVhcih0KXtpZih0eXBlb2YgSFRNTEltYWdlRWxlbWVudCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50fHx0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnR8fHR5cGVvZiBJbWFnZUJpdG1hcCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcCl7Y29uc3QgZT1TYygiY2FudmFzIik7ZS53aWR0aD10LndpZHRoLGUuaGVpZ2h0PXQuaGVpZ2h0O2NvbnN0IG49ZS5nZXRDb250ZXh0KCIyZCIpO24uZHJhd0ltYWdlKHQsMCwwLHQud2lkdGgsdC5oZWlnaHQpO2NvbnN0IHM9bi5nZXRJbWFnZURhdGEoMCwwLHQud2lkdGgsdC5oZWlnaHQpLHI9cy5kYXRhO2ZvcihsZXQgbz0wO288ci5sZW5ndGg7bysrKXJbb109X2UocltvXS8yNTUpKjI1NTtyZXR1cm4gbi5wdXRJbWFnZURhdGEocywwLDApLGV9ZWxzZSBpZih0LmRhdGEpe2NvbnN0IGU9dC5kYXRhLnNsaWNlKDApO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxlIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXk/ZVtuXT1NYXRoLmZsb29yKF9lKGVbbl0vMjU1KSoyNTUpOmVbbl09X2UoZVtuXSk7cmV0dXJue2RhdGE6ZSx3aWR0aDp0LndpZHRoLGhlaWdodDp0LmhlaWdodH19ZWxzZSByZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5JbWFnZVV0aWxzLnNSR0JUb0xpbmVhcigpOiBVbnN1cHBvcnRlZCBpbWFnZSB0eXBlLiBObyBjb2xvciBzcGFjZSBjb252ZXJzaW9uIGFwcGxpZWQuIiksdH19bGV0IGVmPTA7Y2xhc3MgbmZ7Y29uc3RydWN0b3IodD1udWxsKXt0aGlzLmlzU291cmNlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOmVmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLmRhdGE9dCx0aGlzLmRhdGFSZWFkeT0hMCx0aGlzLnZlcnNpb249MH1nZXRTaXplKHQpe2NvbnN0IGU9dGhpcy5kYXRhO3JldHVybiBlIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudD90LnNldChlLnZpZGVvV2lkdGgsZS52aWRlb0hlaWdodCk6ZSE9PW51bGw/dC5zZXQoZS53aWR0aCxlLmhlaWdodCxlLmRlcHRofHwwKTp0LnNldCgwLDAsMCksdH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK310b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQuaW1hZ2VzW3RoaXMudXVpZF0hPT12b2lkIDApcmV0dXJuIHQuaW1hZ2VzW3RoaXMudXVpZF07Y29uc3Qgbj17dXVpZDp0aGlzLnV1aWQsdXJsOiIifSxzPXRoaXMuZGF0YTtpZihzIT09bnVsbCl7bGV0IHI7aWYoQXJyYXkuaXNBcnJheShzKSl7cj1bXTtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTtvKyspc1tvXS5pc0RhdGFUZXh0dXJlP3IucHVzaChzbyhzW29dLmltYWdlKSk6ci5wdXNoKHNvKHNbb10pKX1lbHNlIHI9c28ocyk7bi51cmw9cn1yZXR1cm4gZXx8KHQuaW1hZ2VzW3RoaXMudXVpZF09biksbn19ZnVuY3Rpb24gc28oaSl7cmV0dXJuIHR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50IT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnR8fHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudHx8dHlwZW9mIEltYWdlQml0bWFwIT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEltYWdlQml0bWFwP3RmLmdldERhdGFVUkwoaSk6aS5kYXRhP3tkYXRhOkFycmF5LmZyb20oaS5kYXRhKSx3aWR0aDppLndpZHRoLGhlaWdodDppLmhlaWdodCx0eXBlOmkuZGF0YS5jb25zdHJ1Y3Rvci5uYW1lfTooY29uc29sZS53YXJuKCJUSFJFRS5UZXh0dXJlOiBVbmFibGUgdG8gc2VyaWFsaXplIFRleHR1cmUuIikse30pfWxldCBzZj0wO2NvbnN0IHJvPW5ldyBUO2NsYXNzIGxuIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IodD1sbi5ERUZBVUxUX0lNQUdFLGU9bG4uREVGQVVMVF9NQVBQSU5HLG49MTAwMSxzPTEwMDEscj0xMDA2LG89MTAwOCxhPTEwMjMsYz0xMDA5LGw9bG4uREVGQVVMVF9BTklTT1RST1BZLGg9d2Mpe3N1cGVyKCksdGhpcy5pc1RleHR1cmU9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6c2YrK30pLHRoaXMudXVpZD1GbigpLHRoaXMubmFtZT0iIix0aGlzLnNvdXJjZT1uZXcgbmYodCksdGhpcy5taXBtYXBzPVtdLHRoaXMubWFwcGluZz1lLHRoaXMuY2hhbm5lbD0wLHRoaXMud3JhcFM9bix0aGlzLndyYXBUPXMsdGhpcy5tYWdGaWx0ZXI9cix0aGlzLm1pbkZpbHRlcj1vLHRoaXMuYW5pc290cm9weT1sLHRoaXMuZm9ybWF0PWEsdGhpcy5pbnRlcm5hbEZvcm1hdD1udWxsLHRoaXMudHlwZT1jLHRoaXMub2Zmc2V0PW5ldyBSKDAsMCksdGhpcy5yZXBlYXQ9bmV3IFIoMSwxKSx0aGlzLmNlbnRlcj1uZXcgUigwLDApLHRoaXMucm90YXRpb249MCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9ITAsdGhpcy5tYXRyaXg9bmV3IGdlLHRoaXMuZ2VuZXJhdGVNaXBtYXBzPSEwLHRoaXMucHJlbXVsdGlwbHlBbHBoYT0hMSx0aGlzLmZsaXBZPSEwLHRoaXMudW5wYWNrQWxpZ25tZW50PTQsdGhpcy5jb2xvclNwYWNlPWgsdGhpcy51c2VyRGF0YT17fSx0aGlzLnVwZGF0ZVJhbmdlcz1bXSx0aGlzLnZlcnNpb249MCx0aGlzLm9uVXBkYXRlPW51bGwsdGhpcy5yZW5kZXJUYXJnZXQ9bnVsbCx0aGlzLmlzUmVuZGVyVGFyZ2V0VGV4dHVyZT0hMSx0aGlzLmlzQXJyYXlUZXh0dXJlPSEhKHQmJnQuZGVwdGgmJnQuZGVwdGg+MSksdGhpcy5wbXJlbVZlcnNpb249MH1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy5zb3VyY2UuZ2V0U2l6ZShybykueH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMuc291cmNlLmdldFNpemUocm8pLnl9Z2V0IGRlcHRoKCl7cmV0dXJuIHRoaXMuc291cmNlLmdldFNpemUocm8pLnp9Z2V0IGltYWdlKCl7cmV0dXJuIHRoaXMuc291cmNlLmRhdGF9c2V0IGltYWdlKHQ9bnVsbCl7dGhpcy5zb3VyY2UuZGF0YT10fXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LnNldFV2VHJhbnNmb3JtKHRoaXMub2Zmc2V0LngsdGhpcy5vZmZzZXQueSx0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnksdGhpcy5yb3RhdGlvbix0aGlzLmNlbnRlci54LHRoaXMuY2VudGVyLnkpfWFkZFVwZGF0ZVJhbmdlKHQsZSl7dGhpcy51cGRhdGVSYW5nZXMucHVzaCh7c3RhcnQ6dCxjb3VudDplfSl9Y2xlYXJVcGRhdGVSYW5nZXMoKXt0aGlzLnVwZGF0ZVJhbmdlcy5sZW5ndGg9MH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5uYW1lPXQubmFtZSx0aGlzLnNvdXJjZT10LnNvdXJjZSx0aGlzLm1pcG1hcHM9dC5taXBtYXBzLnNsaWNlKDApLHRoaXMubWFwcGluZz10Lm1hcHBpbmcsdGhpcy5jaGFubmVsPXQuY2hhbm5lbCx0aGlzLndyYXBTPXQud3JhcFMsdGhpcy53cmFwVD10LndyYXBULHRoaXMubWFnRmlsdGVyPXQubWFnRmlsdGVyLHRoaXMubWluRmlsdGVyPXQubWluRmlsdGVyLHRoaXMuYW5pc290cm9weT10LmFuaXNvdHJvcHksdGhpcy5mb3JtYXQ9dC5mb3JtYXQsdGhpcy5pbnRlcm5hbEZvcm1hdD10LmludGVybmFsRm9ybWF0LHRoaXMudHlwZT10LnR5cGUsdGhpcy5vZmZzZXQuY29weSh0Lm9mZnNldCksdGhpcy5yZXBlYXQuY29weSh0LnJlcGVhdCksdGhpcy5jZW50ZXIuY29weSh0LmNlbnRlciksdGhpcy5yb3RhdGlvbj10LnJvdGF0aW9uLHRoaXMubWF0cml4QXV0b1VwZGF0ZT10Lm1hdHJpeEF1dG9VcGRhdGUsdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5nZW5lcmF0ZU1pcG1hcHM9dC5nZW5lcmF0ZU1pcG1hcHMsdGhpcy5wcmVtdWx0aXBseUFscGhhPXQucHJlbXVsdGlwbHlBbHBoYSx0aGlzLmZsaXBZPXQuZmxpcFksdGhpcy51bnBhY2tBbGlnbm1lbnQ9dC51bnBhY2tBbGlnbm1lbnQsdGhpcy5jb2xvclNwYWNlPXQuY29sb3JTcGFjZSx0aGlzLnJlbmRlclRhcmdldD10LnJlbmRlclRhcmdldCx0aGlzLmlzUmVuZGVyVGFyZ2V0VGV4dHVyZT10LmlzUmVuZGVyVGFyZ2V0VGV4dHVyZSx0aGlzLmlzQXJyYXlUZXh0dXJlPXQuaXNBcnJheVRleHR1cmUsdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSx0aGlzLm5lZWRzVXBkYXRlPSEwLHRoaXN9c2V0VmFsdWVzKHQpe2Zvcihjb25zdCBlIGluIHQpe2NvbnN0IG49dFtlXTtpZihuPT09dm9pZCAwKXtjb25zb2xlLndhcm4oYFRIUkVFLlRleHR1cmUuc2V0VmFsdWVzKCk6IHBhcmFtZXRlciAnJHtlfScgaGFzIHZhbHVlIG9mIHVuZGVmaW5lZC5gKTtjb250aW51ZX1jb25zdCBzPXRoaXNbZV07aWYocz09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5UZXh0dXJlLnNldFZhbHVlcygpOiBwcm9wZXJ0eSAnJHtlfScgZG9lcyBub3QgZXhpc3QuYCk7Y29udGludWV9cyYmbiYmcy5pc1ZlY3RvcjImJm4uaXNWZWN0b3IyfHxzJiZuJiZzLmlzVmVjdG9yMyYmbi5pc1ZlY3RvcjN8fHMmJm4mJnMuaXNNYXRyaXgzJiZuLmlzTWF0cml4Mz9zLmNvcHkobik6dGhpc1tlXT1ufX10b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQudGV4dHVyZXNbdGhpcy51dWlkXSE9PXZvaWQgMClyZXR1cm4gdC50ZXh0dXJlc1t0aGlzLnV1aWRdO2NvbnN0IG49e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJUZXh0dXJlIixnZW5lcmF0b3I6IlRleHR1cmUudG9KU09OIn0sdXVpZDp0aGlzLnV1aWQsbmFtZTp0aGlzLm5hbWUsaW1hZ2U6dGhpcy5zb3VyY2UudG9KU09OKHQpLnV1aWQsbWFwcGluZzp0aGlzLm1hcHBpbmcsY2hhbm5lbDp0aGlzLmNoYW5uZWwscmVwZWF0Olt0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnldLG9mZnNldDpbdGhpcy5vZmZzZXQueCx0aGlzLm9mZnNldC55XSxjZW50ZXI6W3RoaXMuY2VudGVyLngsdGhpcy5jZW50ZXIueV0scm90YXRpb246dGhpcy5yb3RhdGlvbix3cmFwOlt0aGlzLndyYXBTLHRoaXMud3JhcFRdLGZvcm1hdDp0aGlzLmZvcm1hdCxpbnRlcm5hbEZvcm1hdDp0aGlzLmludGVybmFsRm9ybWF0LHR5cGU6dGhpcy50eXBlLGNvbG9yU3BhY2U6dGhpcy5jb2xvclNwYWNlLG1pbkZpbHRlcjp0aGlzLm1pbkZpbHRlcixtYWdGaWx0ZXI6dGhpcy5tYWdGaWx0ZXIsYW5pc290cm9weTp0aGlzLmFuaXNvdHJvcHksZmxpcFk6dGhpcy5mbGlwWSxnZW5lcmF0ZU1pcG1hcHM6dGhpcy5nZW5lcmF0ZU1pcG1hcHMscHJlbXVsdGlwbHlBbHBoYTp0aGlzLnByZW11bHRpcGx5QWxwaGEsdW5wYWNrQWxpZ25tZW50OnRoaXMudW5wYWNrQWxpZ25tZW50fTtyZXR1cm4gT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihuLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLGV8fCh0LnRleHR1cmVzW3RoaXMudXVpZF09biksbn1kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfXRyYW5zZm9ybVV2KHQpe2lmKHRoaXMubWFwcGluZyE9PTMwMClyZXR1cm4gdDtpZih0LmFwcGx5TWF0cml4Myh0aGlzLm1hdHJpeCksdC54PDB8fHQueD4xKXN3aXRjaCh0aGlzLndyYXBTKXtjYXNlIDFlMzp0Lng9dC54LU1hdGguZmxvb3IodC54KTticmVhaztjYXNlIDEwMDE6dC54PXQueDwwPzA6MTticmVhaztjYXNlIDEwMDI6TWF0aC5hYnMoTWF0aC5mbG9vcih0LngpJTIpPT09MT90Lng9TWF0aC5jZWlsKHQueCktdC54OnQueD10LngtTWF0aC5mbG9vcih0LngpO2JyZWFrfWlmKHQueTwwfHx0Lnk+MSlzd2l0Y2godGhpcy53cmFwVCl7Y2FzZSAxZTM6dC55PXQueS1NYXRoLmZsb29yKHQueSk7YnJlYWs7Y2FzZSAxMDAxOnQueT10Lnk8MD8wOjE7YnJlYWs7Y2FzZSAxMDAyOk1hdGguYWJzKE1hdGguZmxvb3IodC55KSUyKT09PTE/dC55PU1hdGguY2VpbCh0LnkpLXQueTp0Lnk9dC55LU1hdGguZmxvb3IodC55KTticmVha31yZXR1cm4gdGhpcy5mbGlwWSYmKHQueT0xLXQueSksdH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiYodGhpcy52ZXJzaW9uKyssdGhpcy5zb3VyY2UubmVlZHNVcGRhdGU9ITApfXNldCBuZWVkc1BNUkVNVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy5wbXJlbVZlcnNpb24rK319bG4uREVGQVVMVF9JTUFHRT1udWxsLGxuLkRFRkFVTFRfTUFQUElORz0zMDAsbG4uREVGQVVMVF9BTklTT1RST1BZPTE7Y2xhc3MgWXR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTAscz0xKXtZdC5wcm90b3R5cGUuaXNWZWN0b3I0PSEwLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXMudz1zfWdldCB3aWR0aCgpe3JldHVybiB0aGlzLnp9c2V0IHdpZHRoKHQpe3RoaXMuej10fWdldCBoZWlnaHQoKXtyZXR1cm4gdGhpcy53fXNldCBoZWlnaHQodCl7dGhpcy53PXR9c2V0KHQsZSxuLHMpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzLnc9cyx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpcy56PXQsdGhpcy53PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Wih0KXtyZXR1cm4gdGhpcy56PXQsdGhpc31zZXRXKHQpe3JldHVybiB0aGlzLnc9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztjYXNlIDM6dGhpcy53PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2Nhc2UgMjpyZXR1cm4gdGhpcy56O2Nhc2UgMzpyZXR1cm4gdGhpcy53O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnksdGhpcy56LHRoaXMudyl9Y29weSh0KXtyZXR1cm4gdGhpcy54PXQueCx0aGlzLnk9dC55LHRoaXMuej10LnosdGhpcy53PXQudyE9PXZvaWQgMD90Lnc6MSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpcy56Kz10LnosdGhpcy53Kz10LncsdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpcy56Kz10LHRoaXMudys9dCx0aGlzfWFkZFZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueCtlLngsdGhpcy55PXQueStlLnksdGhpcy56PXQueitlLnosdGhpcy53PXQudytlLncsdGhpc31hZGRTY2FsZWRWZWN0b3IodCxlKXtyZXR1cm4gdGhpcy54Kz10LngqZSx0aGlzLnkrPXQueSplLHRoaXMueis9dC56KmUsdGhpcy53Kz10LncqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpcy56LT10LnosdGhpcy53LT10LncsdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpcy56LT10LHRoaXMudy09dCx0aGlzfXN1YlZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueC1lLngsdGhpcy55PXQueS1lLnksdGhpcy56PXQuei1lLnosdGhpcy53PXQudy1lLncsdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy54Kj10LngsdGhpcy55Kj10LnksdGhpcy56Kj10LnosdGhpcy53Kj10LncsdGhpc31tdWx0aXBseVNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kj10LHRoaXMueSo9dCx0aGlzLnoqPXQsdGhpcy53Kj10LHRoaXN9YXBwbHlNYXRyaXg0KHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dGhpcy56LHI9dGhpcy53LG89dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PW9bMF0qZStvWzRdKm4rb1s4XSpzK29bMTJdKnIsdGhpcy55PW9bMV0qZStvWzVdKm4rb1s5XSpzK29bMTNdKnIsdGhpcy56PW9bMl0qZStvWzZdKm4rb1sxMF0qcytvWzE0XSpyLHRoaXMudz1vWzNdKmUrb1s3XSpuK29bMTFdKnMrb1sxNV0qcix0aGlzfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpcy53Lz10LncsdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1zZXRBeGlzQW5nbGVGcm9tUXVhdGVybmlvbih0KXt0aGlzLnc9MipNYXRoLmFjb3ModC53KTtjb25zdCBlPU1hdGguc3FydCgxLXQudyp0LncpO3JldHVybiBlPDFlLTQ/KHRoaXMueD0xLHRoaXMueT0wLHRoaXMuej0wKToodGhpcy54PXQueC9lLHRoaXMueT10LnkvZSx0aGlzLno9dC56L2UpLHRoaXN9c2V0QXhpc0FuZ2xlRnJvbVJvdGF0aW9uTWF0cml4KHQpe2xldCBlLG4scyxyO2NvbnN0IGM9dC5lbGVtZW50cyxsPWNbMF0saD1jWzRdLHU9Y1s4XSxmPWNbMV0sZD1jWzVdLHA9Y1s5XSx5PWNbMl0sbT1jWzZdLGc9Y1sxMF07aWYoTWF0aC5hYnMoaC1mKTwuMDEmJk1hdGguYWJzKHUteSk8LjAxJiZNYXRoLmFicyhwLW0pPC4wMSl7aWYoTWF0aC5hYnMoaCtmKTwuMSYmTWF0aC5hYnModSt5KTwuMSYmTWF0aC5hYnMocCttKTwuMSYmTWF0aC5hYnMobCtkK2ctMyk8LjEpcmV0dXJuIHRoaXMuc2V0KDEsMCwwLDApLHRoaXM7ZT1NYXRoLlBJO2NvbnN0IHc9KGwrMSkvMix4PShkKzEpLzIsTT0oZysxKS8yLEE9KGgrZikvNCxTPSh1K3kpLzQsXz0ocCttKS80O3JldHVybiB3PngmJnc+TT93PC4wMT8obj0wLHM9LjcwNzEwNjc4MSxyPS43MDcxMDY3ODEpOihuPU1hdGguc3FydCh3KSxzPUEvbixyPVMvbik6eD5NP3g8LjAxPyhuPS43MDcxMDY3ODEscz0wLHI9LjcwNzEwNjc4MSk6KHM9TWF0aC5zcXJ0KHgpLG49QS9zLHI9Xy9zKTpNPC4wMT8obj0uNzA3MTA2NzgxLHM9LjcwNzEwNjc4MSxyPTApOihyPU1hdGguc3FydChNKSxuPVMvcixzPV8vciksdGhpcy5zZXQobixzLHIsZSksdGhpc31sZXQgYj1NYXRoLnNxcnQoKG0tcCkqKG0tcCkrKHUteSkqKHUteSkrKGYtaCkqKGYtaCkpO3JldHVybiBNYXRoLmFicyhiKTwuMDAxJiYoYj0xKSx0aGlzLng9KG0tcCkvYix0aGlzLnk9KHUteSkvYix0aGlzLno9KGYtaCkvYix0aGlzLnc9TWF0aC5hY29zKChsK2QrZy0xKS8yKSx0aGlzfXNldEZyb21NYXRyaXhQb3NpdGlvbih0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1lWzEyXSx0aGlzLnk9ZVsxM10sdGhpcy56PWVbMTRdLHRoaXMudz1lWzE1XSx0aGlzfW1pbih0KXtyZXR1cm4gdGhpcy54PU1hdGgubWluKHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1pbih0aGlzLnksdC55KSx0aGlzLno9TWF0aC5taW4odGhpcy56LHQueiksdGhpcy53PU1hdGgubWluKHRoaXMudyx0LncpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzLnc9TWF0aC5tYXgodGhpcy53LHQudyksdGhpc31jbGFtcCh0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdC54LGUueCksdGhpcy55PVoodGhpcy55LHQueSxlLnkpLHRoaXMuej1aKHRoaXMueix0LnosZS56KSx0aGlzLnc9Wih0aGlzLncsdC53LGUudyksdGhpc31jbGFtcFNjYWxhcih0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdCxlKSx0aGlzLnk9Wih0aGlzLnksdCxlKSx0aGlzLno9Wih0aGlzLnosdCxlKSx0aGlzLnc9Wih0aGlzLncsdCxlKSx0aGlzfWNsYW1wTGVuZ3RoKHQsZSl7Y29uc3Qgbj10aGlzLmxlbmd0aCgpO3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcihufHwxKS5tdWx0aXBseVNjYWxhcihaKG4sdCxlKSl9Zmxvb3IoKXtyZXR1cm4gdGhpcy54PU1hdGguZmxvb3IodGhpcy54KSx0aGlzLnk9TWF0aC5mbG9vcih0aGlzLnkpLHRoaXMuej1NYXRoLmZsb29yKHRoaXMueiksdGhpcy53PU1hdGguZmxvb3IodGhpcy53KSx0aGlzfWNlaWwoKXtyZXR1cm4gdGhpcy54PU1hdGguY2VpbCh0aGlzLngpLHRoaXMueT1NYXRoLmNlaWwodGhpcy55KSx0aGlzLno9TWF0aC5jZWlsKHRoaXMueiksdGhpcy53PU1hdGguY2VpbCh0aGlzLncpLHRoaXN9cm91bmQoKXtyZXR1cm4gdGhpcy54PU1hdGgucm91bmQodGhpcy54KSx0aGlzLnk9TWF0aC5yb3VuZCh0aGlzLnkpLHRoaXMuej1NYXRoLnJvdW5kKHRoaXMueiksdGhpcy53PU1hdGgucm91bmQodGhpcy53KSx0aGlzfXJvdW5kVG9aZXJvKCl7cmV0dXJuIHRoaXMueD1NYXRoLnRydW5jKHRoaXMueCksdGhpcy55PU1hdGgudHJ1bmModGhpcy55KSx0aGlzLno9TWF0aC50cnVuYyh0aGlzLnopLHRoaXMudz1NYXRoLnRydW5jKHRoaXMudyksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpcy53PS10aGlzLncsdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56K3RoaXMudyp0Lnd9bGVuZ3RoU3EoKXtyZXR1cm4gdGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnordGhpcy53KnRoaXMud31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56K3RoaXMudyp0aGlzLncpfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KStNYXRoLmFicyh0aGlzLncpfW5vcm1hbGl6ZSgpe3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcih0aGlzLmxlbmd0aCgpfHwxKX1zZXRMZW5ndGgodCl7cmV0dXJuIHRoaXMubm9ybWFsaXplKCkubXVsdGlwbHlTY2FsYXIodCl9bGVycCh0LGUpe3JldHVybiB0aGlzLngrPSh0LngtdGhpcy54KSplLHRoaXMueSs9KHQueS10aGlzLnkpKmUsdGhpcy56Kz0odC56LXRoaXMueikqZSx0aGlzLncrPSh0LnctdGhpcy53KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpcy56PXQueisoZS56LXQueikqbix0aGlzLnc9dC53KyhlLnctdC53KSpuLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lng9PT10aGlzLngmJnQueT09PXRoaXMueSYmdC56PT09dGhpcy56JiZ0Lnc9PT10aGlzLnd9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXMudz10W2UrM10sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0W2UrMl09dGhpcy56LHRbZSszXT10aGlzLncsdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMueD10LmdldFgoZSksdGhpcy55PXQuZ2V0WShlKSx0aGlzLno9dC5nZXRaKGUpLHRoaXMudz10LmdldFcoZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpcy53PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55LHlpZWxkIHRoaXMueix5aWVsZCB0aGlzLnd9fWNsYXNzIGd0e2NvbnN0cnVjdG9yKHQ9bmV3IFQoMS8wLDEvMCwxLzApLGU9bmV3IFQoLTEvMCwtMS8wLC0xLzApKXt0aGlzLmlzQm94Mz0hMCx0aGlzLm1pbj10LHRoaXMubWF4PWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMubWluLmNvcHkodCksdGhpcy5tYXguY29weShlKSx0aGlzfXNldEZyb21BcnJheSh0KXt0aGlzLm1ha2VFbXB0eSgpO2ZvcihsZXQgZT0wLG49dC5sZW5ndGg7ZTxuO2UrPTMpdGhpcy5leHBhbmRCeVBvaW50KGNlLmZyb21BcnJheSh0LGUpKTtyZXR1cm4gdGhpc31zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHQpe3RoaXMubWFrZUVtcHR5KCk7Zm9yKGxldCBlPTAsbj10LmNvdW50O2U8bjtlKyspdGhpcy5leHBhbmRCeVBvaW50KGNlLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKSk7cmV0dXJuIHRoaXN9c2V0RnJvbVBvaW50cyh0KXt0aGlzLm1ha2VFbXB0eSgpO2ZvcihsZXQgZT0wLG49dC5sZW5ndGg7ZTxuO2UrKyl0aGlzLmV4cGFuZEJ5UG9pbnQodFtlXSk7cmV0dXJuIHRoaXN9c2V0RnJvbUNlbnRlckFuZFNpemUodCxlKXtjb25zdCBuPWNlLmNvcHkoZSkubXVsdGlwbHlTY2FsYXIoLjUpO3JldHVybiB0aGlzLm1pbi5jb3B5KHQpLnN1YihuKSx0aGlzLm1heC5jb3B5KHQpLmFkZChuKSx0aGlzfXNldEZyb21PYmplY3QodCxlPSExKXtyZXR1cm4gdGhpcy5tYWtlRW1wdHkoKSx0aGlzLmV4cGFuZEJ5T2JqZWN0KHQsZSl9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7cmV0dXJuIHRoaXMubWluLmNvcHkodC5taW4pLHRoaXMubWF4LmNvcHkodC5tYXgpLHRoaXN9bWFrZUVtcHR5KCl7cmV0dXJuIHRoaXMubWluLng9dGhpcy5taW4ueT10aGlzLm1pbi56PTEvMCx0aGlzLm1heC54PXRoaXMubWF4Lnk9dGhpcy5tYXguej0tMS8wLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLm1heC54PHRoaXMubWluLnh8fHRoaXMubWF4Lnk8dGhpcy5taW4ueXx8dGhpcy5tYXguejx0aGlzLm1pbi56fWdldENlbnRlcih0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dC5zZXQoMCwwLDApOnQuYWRkVmVjdG9ycyh0aGlzLm1pbix0aGlzLm1heCkubXVsdGlwbHlTY2FsYXIoLjUpfWdldFNpemUodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3Quc2V0KDAsMCwwKTp0LnN1YlZlY3RvcnModGhpcy5tYXgsdGhpcy5taW4pfWV4cGFuZEJ5UG9pbnQodCl7cmV0dXJuIHRoaXMubWluLm1pbih0KSx0aGlzLm1heC5tYXgodCksdGhpc31leHBhbmRCeVZlY3Rvcih0KXtyZXR1cm4gdGhpcy5taW4uc3ViKHQpLHRoaXMubWF4LmFkZCh0KSx0aGlzfWV4cGFuZEJ5U2NhbGFyKHQpe3JldHVybiB0aGlzLm1pbi5hZGRTY2FsYXIoLXQpLHRoaXMubWF4LmFkZFNjYWxhcih0KSx0aGlzfWV4cGFuZEJ5T2JqZWN0KHQsZT0hMSl7dC51cGRhdGVXb3JsZE1hdHJpeCghMSwhMSk7Y29uc3Qgbj10Lmdlb21ldHJ5O2lmKG4hPT12b2lkIDApe2NvbnN0IHI9bi5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIik7aWYoZT09PSEwJiZyIT09dm9pZCAwJiZ0LmlzSW5zdGFuY2VkTWVzaCE9PSEwKWZvcihsZXQgbz0wLGE9ci5jb3VudDtvPGE7bysrKXQuaXNNZXNoPT09ITA/dC5nZXRWZXJ0ZXhQb3NpdGlvbihvLGNlKTpjZS5mcm9tQnVmZmVyQXR0cmlidXRlKHIsbyksY2UuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpLHRoaXMuZXhwYW5kQnlQb2ludChjZSk7ZWxzZSB0LmJvdW5kaW5nQm94IT09dm9pZCAwPyh0LmJvdW5kaW5nQm94PT09bnVsbCYmdC5jb21wdXRlQm91bmRpbmdCb3goKSxhcy5jb3B5KHQuYm91bmRpbmdCb3gpKToobi5ib3VuZGluZ0JveD09PW51bGwmJm4uY29tcHV0ZUJvdW5kaW5nQm94KCksYXMuY29weShuLmJvdW5kaW5nQm94KSksYXMuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpLHRoaXMudW5pb24oYXMpfWNvbnN0IHM9dC5jaGlsZHJlbjtmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKyspdGhpcy5leHBhbmRCeU9iamVjdChzW3JdLGUpO3JldHVybiB0aGlzfWNvbnRhaW5zUG9pbnQodCl7cmV0dXJuIHQueD49dGhpcy5taW4ueCYmdC54PD10aGlzLm1heC54JiZ0Lnk+PXRoaXMubWluLnkmJnQueTw9dGhpcy5tYXgueSYmdC56Pj10aGlzLm1pbi56JiZ0Lno8PXRoaXMubWF4Lnp9Y29udGFpbnNCb3godCl7cmV0dXJuIHRoaXMubWluLng8PXQubWluLngmJnQubWF4Lng8PXRoaXMubWF4LngmJnRoaXMubWluLnk8PXQubWluLnkmJnQubWF4Lnk8PXRoaXMubWF4LnkmJnRoaXMubWluLno8PXQubWluLnomJnQubWF4Lno8PXRoaXMubWF4Lnp9Z2V0UGFyYW1ldGVyKHQsZSl7cmV0dXJuIGUuc2V0KCh0LngtdGhpcy5taW4ueCkvKHRoaXMubWF4LngtdGhpcy5taW4ueCksKHQueS10aGlzLm1pbi55KS8odGhpcy5tYXgueS10aGlzLm1pbi55KSwodC56LXRoaXMubWluLnopLyh0aGlzLm1heC56LXRoaXMubWluLnopKX1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0Lm1heC54Pj10aGlzLm1pbi54JiZ0Lm1pbi54PD10aGlzLm1heC54JiZ0Lm1heC55Pj10aGlzLm1pbi55JiZ0Lm1pbi55PD10aGlzLm1heC55JiZ0Lm1heC56Pj10aGlzLm1pbi56JiZ0Lm1pbi56PD10aGlzLm1heC56fWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHRoaXMuY2xhbXBQb2ludCh0LmNlbnRlcixjZSksY2UuZGlzdGFuY2VUb1NxdWFyZWQodC5jZW50ZXIpPD10LnJhZGl1cyp0LnJhZGl1c31pbnRlcnNlY3RzUGxhbmUodCl7bGV0IGUsbjtyZXR1cm4gdC5ub3JtYWwueD4wPyhlPXQubm9ybWFsLngqdGhpcy5taW4ueCxuPXQubm9ybWFsLngqdGhpcy5tYXgueCk6KGU9dC5ub3JtYWwueCp0aGlzLm1heC54LG49dC5ub3JtYWwueCp0aGlzLm1pbi54KSx0Lm5vcm1hbC55PjA/KGUrPXQubm9ybWFsLnkqdGhpcy5taW4ueSxuKz10Lm5vcm1hbC55KnRoaXMubWF4LnkpOihlKz10Lm5vcm1hbC55KnRoaXMubWF4Lnksbis9dC5ub3JtYWwueSp0aGlzLm1pbi55KSx0Lm5vcm1hbC56PjA/KGUrPXQubm9ybWFsLnoqdGhpcy5taW4ueixuKz10Lm5vcm1hbC56KnRoaXMubWF4LnopOihlKz10Lm5vcm1hbC56KnRoaXMubWF4Lnosbis9dC5ub3JtYWwueip0aGlzLm1pbi56KSxlPD0tdC5jb25zdGFudCYmbj49LXQuY29uc3RhbnR9aW50ZXJzZWN0c1RyaWFuZ2xlKHQpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiExO3RoaXMuZ2V0Q2VudGVyKHhpKSxjcy5zdWJWZWN0b3JzKHRoaXMubWF4LHhpKSxObi5zdWJWZWN0b3JzKHQuYSx4aSksUm4uc3ViVmVjdG9ycyh0LmIseGkpLExuLnN1YlZlY3RvcnModC5jLHhpKSxYZS5zdWJWZWN0b3JzKFJuLE5uKSxKZS5zdWJWZWN0b3JzKExuLFJuKSxobi5zdWJWZWN0b3JzKE5uLExuKTtsZXQgZT1bMCwtWGUueixYZS55LDAsLUplLnosSmUueSwwLC1obi56LGhuLnksWGUueiwwLC1YZS54LEplLnosMCwtSmUueCxobi56LDAsLWhuLngsLVhlLnksWGUueCwwLC1KZS55LEplLngsMCwtaG4ueSxobi54LDBdO3JldHVybiFvbyhlLE5uLFJuLExuLGNzKXx8KGU9WzEsMCwwLDAsMSwwLDAsMCwxXSwhb28oZSxObixSbixMbixjcykpPyExOihscy5jcm9zc1ZlY3RvcnMoWGUsSmUpLGU9W2xzLngsbHMueSxscy56XSxvbyhlLE5uLFJuLExuLGNzKSl9Y2xhbXBQb2ludCh0LGUpe3JldHVybiBlLmNvcHkodCkuY2xhbXAodGhpcy5taW4sdGhpcy5tYXgpfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdGhpcy5jbGFtcFBvaW50KHQsY2UpLmRpc3RhbmNlVG8odCl9Z2V0Qm91bmRpbmdTcGhlcmUodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3QubWFrZUVtcHR5KCk6KHRoaXMuZ2V0Q2VudGVyKHQuY2VudGVyKSx0LnJhZGl1cz10aGlzLmdldFNpemUoY2UpLmxlbmd0aCgpKi41KSx0fWludGVyc2VjdCh0KXtyZXR1cm4gdGhpcy5taW4ubWF4KHQubWluKSx0aGlzLm1heC5taW4odC5tYXgpLHRoaXMuaXNFbXB0eSgpJiZ0aGlzLm1ha2VFbXB0eSgpLHRoaXN9dW5pb24odCl7cmV0dXJuIHRoaXMubWluLm1pbih0Lm1pbiksdGhpcy5tYXgubWF4KHQubWF4KSx0aGlzfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dGhpczoodmVbMF0uc2V0KHRoaXMubWluLngsdGhpcy5taW4ueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbMV0uc2V0KHRoaXMubWluLngsdGhpcy5taW4ueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdmVbMl0uc2V0KHRoaXMubWluLngsdGhpcy5tYXgueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbM10uc2V0KHRoaXMubWluLngsdGhpcy5tYXgueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdmVbNF0uc2V0KHRoaXMubWF4LngsdGhpcy5taW4ueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbNV0uc2V0KHRoaXMubWF4LngsdGhpcy5taW4ueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdmVbNl0uc2V0KHRoaXMubWF4LngsdGhpcy5tYXgueSx0aGlzLm1pbi56KS5hcHBseU1hdHJpeDQodCksdmVbN10uc2V0KHRoaXMubWF4LngsdGhpcy5tYXgueSx0aGlzLm1heC56KS5hcHBseU1hdHJpeDQodCksdGhpcy5zZXRGcm9tUG9pbnRzKHZlKSx0aGlzKX10cmFuc2xhdGUodCl7cmV0dXJuIHRoaXMubWluLmFkZCh0KSx0aGlzLm1heC5hZGQodCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQubWluLmVxdWFscyh0aGlzLm1pbikmJnQubWF4LmVxdWFscyh0aGlzLm1heCl9dG9KU09OKCl7cmV0dXJue21pbjp0aGlzLm1pbi50b0FycmF5KCksbWF4OnRoaXMubWF4LnRvQXJyYXkoKX19ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMubWluLmZyb21BcnJheSh0Lm1pbiksdGhpcy5tYXguZnJvbUFycmF5KHQubWF4KSx0aGlzfX1jb25zdCB2ZT1bbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFQsbmV3IFRdLGNlPW5ldyBULGFzPW5ldyBndCxObj1uZXcgVCxSbj1uZXcgVCxMbj1uZXcgVCxYZT1uZXcgVCxKZT1uZXcgVCxobj1uZXcgVCx4aT1uZXcgVCxjcz1uZXcgVCxscz1uZXcgVCx1bj1uZXcgVDtmdW5jdGlvbiBvbyhpLHQsZSxuLHMpe2ZvcihsZXQgcj0wLG89aS5sZW5ndGgtMztyPD1vO3IrPTMpe3VuLmZyb21BcnJheShpLHIpO2NvbnN0IGE9cy54Kk1hdGguYWJzKHVuLngpK3MueSpNYXRoLmFicyh1bi55KStzLnoqTWF0aC5hYnModW4ueiksYz10LmRvdCh1biksbD1lLmRvdCh1biksaD1uLmRvdCh1bik7aWYoTWF0aC5tYXgoLU1hdGgubWF4KGMsbCxoKSxNYXRoLm1pbihjLGwsaCkpPmEpcmV0dXJuITF9cmV0dXJuITB9Y29uc3QgcmY9bmV3IGd0LHdpPW5ldyBULGFvPW5ldyBUO2NsYXNzIGNve2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT0tMSl7dGhpcy5pc1NwaGVyZT0hMCx0aGlzLmNlbnRlcj10LHRoaXMucmFkaXVzPWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMuY2VudGVyLmNvcHkodCksdGhpcy5yYWRpdXM9ZSx0aGlzfXNldEZyb21Qb2ludHModCxlKXtjb25zdCBuPXRoaXMuY2VudGVyO2UhPT12b2lkIDA/bi5jb3B5KGUpOnJmLnNldEZyb21Qb2ludHModCkuZ2V0Q2VudGVyKG4pO2xldCBzPTA7Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXM9TWF0aC5tYXgocyxuLmRpc3RhbmNlVG9TcXVhcmVkKHRbcl0pKTtyZXR1cm4gdGhpcy5yYWRpdXM9TWF0aC5zcXJ0KHMpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuY29weSh0LmNlbnRlciksdGhpcy5yYWRpdXM9dC5yYWRpdXMsdGhpc31pc0VtcHR5KCl7cmV0dXJuIHRoaXMucmFkaXVzPDB9bWFrZUVtcHR5KCl7cmV0dXJuIHRoaXMuY2VudGVyLnNldCgwLDAsMCksdGhpcy5yYWRpdXM9LTEsdGhpc31jb250YWluc1BvaW50KHQpe3JldHVybiB0LmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuY2VudGVyKTw9dGhpcy5yYWRpdXMqdGhpcy5yYWRpdXN9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiB0LmRpc3RhbmNlVG8odGhpcy5jZW50ZXIpLXRoaXMucmFkaXVzfWludGVyc2VjdHNTcGhlcmUodCl7Y29uc3QgZT10aGlzLnJhZGl1cyt0LnJhZGl1cztyZXR1cm4gdC5jZW50ZXIuZGlzdGFuY2VUb1NxdWFyZWQodGhpcy5jZW50ZXIpPD1lKmV9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdC5pbnRlcnNlY3RzU3BoZXJlKHRoaXMpfWludGVyc2VjdHNQbGFuZSh0KXtyZXR1cm4gTWF0aC5hYnModC5kaXN0YW5jZVRvUG9pbnQodGhpcy5jZW50ZXIpKTw9dGhpcy5yYWRpdXN9Y2xhbXBQb2ludCh0LGUpe2NvbnN0IG49dGhpcy5jZW50ZXIuZGlzdGFuY2VUb1NxdWFyZWQodCk7cmV0dXJuIGUuY29weSh0KSxuPnRoaXMucmFkaXVzKnRoaXMucmFkaXVzJiYoZS5zdWIodGhpcy5jZW50ZXIpLm5vcm1hbGl6ZSgpLGUubXVsdGlwbHlTY2FsYXIodGhpcy5yYWRpdXMpLmFkZCh0aGlzLmNlbnRlcikpLGV9Z2V0Qm91bmRpbmdCb3godCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpPyh0Lm1ha2VFbXB0eSgpLHQpOih0LnNldCh0aGlzLmNlbnRlcix0aGlzLmNlbnRlciksdC5leHBhbmRCeVNjYWxhcih0aGlzLnJhZGl1cyksdCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLmNlbnRlci5hcHBseU1hdHJpeDQodCksdGhpcy5yYWRpdXM9dGhpcy5yYWRpdXMqdC5nZXRNYXhTY2FsZU9uQXhpcygpLHRoaXN9dHJhbnNsYXRlKHQpe3JldHVybiB0aGlzLmNlbnRlci5hZGQodCksdGhpc31leHBhbmRCeVBvaW50KHQpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiB0aGlzLmNlbnRlci5jb3B5KHQpLHRoaXMucmFkaXVzPTAsdGhpczt3aS5zdWJWZWN0b3JzKHQsdGhpcy5jZW50ZXIpO2NvbnN0IGU9d2kubGVuZ3RoU3EoKTtpZihlPnRoaXMucmFkaXVzKnRoaXMucmFkaXVzKXtjb25zdCBuPU1hdGguc3FydChlKSxzPShuLXRoaXMucmFkaXVzKSouNTt0aGlzLmNlbnRlci5hZGRTY2FsZWRWZWN0b3Iod2kscy9uKSx0aGlzLnJhZGl1cys9c31yZXR1cm4gdGhpc311bmlvbih0KXtyZXR1cm4gdC5pc0VtcHR5KCk/dGhpczp0aGlzLmlzRW1wdHkoKT8odGhpcy5jb3B5KHQpLHRoaXMpOih0aGlzLmNlbnRlci5lcXVhbHModC5jZW50ZXIpPT09ITA/dGhpcy5yYWRpdXM9TWF0aC5tYXgodGhpcy5yYWRpdXMsdC5yYWRpdXMpOihhby5zdWJWZWN0b3JzKHQuY2VudGVyLHRoaXMuY2VudGVyKS5zZXRMZW5ndGgodC5yYWRpdXMpLHRoaXMuZXhwYW5kQnlQb2ludCh3aS5jb3B5KHQuY2VudGVyKS5hZGQoYW8pKSx0aGlzLmV4cGFuZEJ5UG9pbnQod2kuY29weSh0LmNlbnRlcikuc3ViKGFvKSkpLHRoaXMpfWVxdWFscyh0KXtyZXR1cm4gdC5jZW50ZXIuZXF1YWxzKHRoaXMuY2VudGVyKSYmdC5yYWRpdXM9PT10aGlzLnJhZGl1c31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9dG9KU09OKCl7cmV0dXJue3JhZGl1czp0aGlzLnJhZGl1cyxjZW50ZXI6dGhpcy5jZW50ZXIudG9BcnJheSgpfX1mcm9tSlNPTih0KXtyZXR1cm4gdGhpcy5yYWRpdXM9dC5yYWRpdXMsdGhpcy5jZW50ZXIuZnJvbUFycmF5KHQuY2VudGVyKSx0aGlzfX1jb25zdCB6ZT1uZXcgVCxsbz1uZXcgVCxocz1uZXcgVCxZZT1uZXcgVCxobz1uZXcgVCx1cz1uZXcgVCx1bz1uZXcgVDtjbGFzcyBmb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQoMCwwLC0xKSl7dGhpcy5vcmlnaW49dCx0aGlzLmRpcmVjdGlvbj1lfXNldCh0LGUpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQpLHRoaXMuZGlyZWN0aW9uLmNvcHkoZSksdGhpc31jb3B5KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQub3JpZ2luKSx0aGlzLmRpcmVjdGlvbi5jb3B5KHQuZGlyZWN0aW9uKSx0aGlzfWF0KHQsZSl7cmV0dXJuIGUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLHQpfWxvb2tBdCh0KXtyZXR1cm4gdGhpcy5kaXJlY3Rpb24uY29weSh0KS5zdWIodGhpcy5vcmlnaW4pLm5vcm1hbGl6ZSgpLHRoaXN9cmVjYXN0KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHRoaXMuYXQodCx6ZSkpLHRoaXN9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUpe2Uuc3ViVmVjdG9ycyh0LHRoaXMub3JpZ2luKTtjb25zdCBuPWUuZG90KHRoaXMuZGlyZWN0aW9uKTtyZXR1cm4gbjwwP2UuY29weSh0aGlzLm9yaWdpbik6ZS5jb3B5KHRoaXMub3JpZ2luKS5hZGRTY2FsZWRWZWN0b3IodGhpcy5kaXJlY3Rpb24sbil9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVNxVG9Qb2ludCh0KSl9ZGlzdGFuY2VTcVRvUG9pbnQodCl7Y29uc3QgZT16ZS5zdWJWZWN0b3JzKHQsdGhpcy5vcmlnaW4pLmRvdCh0aGlzLmRpcmVjdGlvbik7cmV0dXJuIGU8MD90aGlzLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZCh0KTooemUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLGUpLHplLmRpc3RhbmNlVG9TcXVhcmVkKHQpKX1kaXN0YW5jZVNxVG9TZWdtZW50KHQsZSxuLHMpe2xvLmNvcHkodCkuYWRkKGUpLm11bHRpcGx5U2NhbGFyKC41KSxocy5jb3B5KGUpLnN1Yih0KS5ub3JtYWxpemUoKSxZZS5jb3B5KHRoaXMub3JpZ2luKS5zdWIobG8pO2NvbnN0IHI9dC5kaXN0YW5jZVRvKGUpKi41LG89LXRoaXMuZGlyZWN0aW9uLmRvdChocyksYT1ZZS5kb3QodGhpcy5kaXJlY3Rpb24pLGM9LVllLmRvdChocyksbD1ZZS5sZW5ndGhTcSgpLGg9TWF0aC5hYnMoMS1vKm8pO2xldCB1LGYsZCxwO2lmKGg+MClpZih1PW8qYy1hLGY9byphLWMscD1yKmgsdT49MClpZihmPj0tcClpZihmPD1wKXtjb25zdCB5PTEvaDt1Kj15LGYqPXksZD11Kih1K28qZisyKmEpK2YqKG8qdStmKzIqYykrbH1lbHNlIGY9cix1PU1hdGgubWF4KDAsLShvKmYrYSkpLGQ9LXUqdStmKihmKzIqYykrbDtlbHNlIGY9LXIsdT1NYXRoLm1heCgwLC0obypmK2EpKSxkPS11KnUrZiooZisyKmMpK2w7ZWxzZSBmPD0tcD8odT1NYXRoLm1heCgwLC0oLW8qcithKSksZj11PjA/LXI6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk6Zjw9cD8odT0wLGY9TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9ZiooZisyKmMpK2wpOih1PU1hdGgubWF4KDAsLShvKnIrYSkpLGY9dT4wP3I6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk7ZWxzZSBmPW8+MD8tcjpyLHU9TWF0aC5tYXgoMCwtKG8qZithKSksZD0tdSp1K2YqKGYrMipjKStsO3JldHVybiBuJiZuLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbix1KSxzJiZzLmNvcHkobG8pLmFkZFNjYWxlZFZlY3RvcihocyxmKSxkfWludGVyc2VjdFNwaGVyZSh0LGUpe3plLnN1YlZlY3RvcnModC5jZW50ZXIsdGhpcy5vcmlnaW4pO2NvbnN0IG49emUuZG90KHRoaXMuZGlyZWN0aW9uKSxzPXplLmRvdCh6ZSktbipuLHI9dC5yYWRpdXMqdC5yYWRpdXM7aWYocz5yKXJldHVybiBudWxsO2NvbnN0IG89TWF0aC5zcXJ0KHItcyksYT1uLW8sYz1uK287cmV0dXJuIGM8MD9udWxsOmE8MD90aGlzLmF0KGMsZSk6dGhpcy5hdChhLGUpfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHQucmFkaXVzPDA/ITE6dGhpcy5kaXN0YW5jZVNxVG9Qb2ludCh0LmNlbnRlcik8PXQucmFkaXVzKnQucmFkaXVzfWRpc3RhbmNlVG9QbGFuZSh0KXtjb25zdCBlPXQubm9ybWFsLmRvdCh0aGlzLmRpcmVjdGlvbik7aWYoZT09PTApcmV0dXJuIHQuZGlzdGFuY2VUb1BvaW50KHRoaXMub3JpZ2luKT09PTA/MDpudWxsO2NvbnN0IG49LSh0aGlzLm9yaWdpbi5kb3QodC5ub3JtYWwpK3QuY29uc3RhbnQpL2U7cmV0dXJuIG4+PTA/bjpudWxsfWludGVyc2VjdFBsYW5lKHQsZSl7Y29uc3Qgbj10aGlzLmRpc3RhbmNlVG9QbGFuZSh0KTtyZXR1cm4gbj09PW51bGw/bnVsbDp0aGlzLmF0KG4sZSl9aW50ZXJzZWN0c1BsYW5lKHQpe2NvbnN0IGU9dC5kaXN0YW5jZVRvUG9pbnQodGhpcy5vcmlnaW4pO3JldHVybiBlPT09MHx8dC5ub3JtYWwuZG90KHRoaXMuZGlyZWN0aW9uKSplPDB9aW50ZXJzZWN0Qm94KHQsZSl7bGV0IG4scyxyLG8sYSxjO2NvbnN0IGw9MS90aGlzLmRpcmVjdGlvbi54LGg9MS90aGlzLmRpcmVjdGlvbi55LHU9MS90aGlzLmRpcmVjdGlvbi56LGY9dGhpcy5vcmlnaW47cmV0dXJuIGw+PTA/KG49KHQubWluLngtZi54KSpsLHM9KHQubWF4LngtZi54KSpsKToobj0odC5tYXgueC1mLngpKmwscz0odC5taW4ueC1mLngpKmwpLGg+PTA/KHI9KHQubWluLnktZi55KSpoLG89KHQubWF4LnktZi55KSpoKToocj0odC5tYXgueS1mLnkpKmgsbz0odC5taW4ueS1mLnkpKmgpLG4+b3x8cj5zfHwoKHI+bnx8aXNOYU4obikpJiYobj1yKSwobzxzfHxpc05hTihzKSkmJihzPW8pLHU+PTA/KGE9KHQubWluLnotZi56KSp1LGM9KHQubWF4LnotZi56KSp1KTooYT0odC5tYXguei1mLnopKnUsYz0odC5taW4uei1mLnopKnUpLG4+Y3x8YT5zKXx8KChhPm58fG4hPT1uKSYmKG49YSksKGM8c3x8cyE9PXMpJiYocz1jKSxzPDApP251bGw6dGhpcy5hdChuPj0wP246cyxlKX1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0aGlzLmludGVyc2VjdEJveCh0LHplKSE9PW51bGx9aW50ZXJzZWN0VHJpYW5nbGUodCxlLG4scyxyKXtoby5zdWJWZWN0b3JzKGUsdCksdXMuc3ViVmVjdG9ycyhuLHQpLHVvLmNyb3NzVmVjdG9ycyhobyx1cyk7bGV0IG89dGhpcy5kaXJlY3Rpb24uZG90KHVvKSxhO2lmKG8+MCl7aWYocylyZXR1cm4gbnVsbDthPTF9ZWxzZSBpZihvPDApYT0tMSxvPS1vO2Vsc2UgcmV0dXJuIG51bGw7WWUuc3ViVmVjdG9ycyh0aGlzLm9yaWdpbix0KTtjb25zdCBjPWEqdGhpcy5kaXJlY3Rpb24uZG90KHVzLmNyb3NzVmVjdG9ycyhZZSx1cykpO2lmKGM8MClyZXR1cm4gbnVsbDtjb25zdCBsPWEqdGhpcy5kaXJlY3Rpb24uZG90KGhvLmNyb3NzKFllKSk7aWYobDwwfHxjK2w+bylyZXR1cm4gbnVsbDtjb25zdCBoPS1hKlllLmRvdCh1byk7cmV0dXJuIGg8MD9udWxsOnRoaXMuYXQoaC9vLHIpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5vcmlnaW4uYXBwbHlNYXRyaXg0KHQpLHRoaXMuZGlyZWN0aW9uLnRyYW5zZm9ybURpcmVjdGlvbih0KSx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5vcmlnaW4uZXF1YWxzKHRoaXMub3JpZ2luKSYmdC5kaXJlY3Rpb24uZXF1YWxzKHRoaXMuZGlyZWN0aW9uKX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9fWNsYXNzIHN0e2NvbnN0cnVjdG9yKHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pe3N0LnByb3RvdHlwZS5pc01hdHJpeDQ9ITAsdGhpcy5lbGVtZW50cz1bMSwwLDAsMCwwLDEsMCwwLDAsMCwxLDAsMCwwLDAsMV0sdCE9PXZvaWQgMCYmdGhpcy5zZXQodCxlLG4scyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbSl9c2V0KHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pe2NvbnN0IGc9dGhpcy5lbGVtZW50cztyZXR1cm4gZ1swXT10LGdbNF09ZSxnWzhdPW4sZ1sxMl09cyxnWzFdPXIsZ1s1XT1vLGdbOV09YSxnWzEzXT1jLGdbMl09bCxnWzZdPWgsZ1sxMF09dSxnWzE0XT1mLGdbM109ZCxnWzddPXAsZ1sxMV09eSxnWzE1XT1tLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwwLDEsMCwwLDAsMCwxLDAsMCwwLDAsMSksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgc3QoKS5mcm9tQXJyYXkodGhpcy5lbGVtZW50cyl9Y29weSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzO3JldHVybiBlWzBdPW5bMF0sZVsxXT1uWzFdLGVbMl09blsyXSxlWzNdPW5bM10sZVs0XT1uWzRdLGVbNV09bls1XSxlWzZdPW5bNl0sZVs3XT1uWzddLGVbOF09bls4XSxlWzldPW5bOV0sZVsxMF09blsxMF0sZVsxMV09blsxMV0sZVsxMl09blsxMl0sZVsxM109blsxM10sZVsxNF09blsxNF0sZVsxNV09blsxNV0sdGhpc31jb3B5UG9zaXRpb24odCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVsxMl09blsxMl0sZVsxM109blsxM10sZVsxNF09blsxNF0sdGhpc31zZXRGcm9tTWF0cml4Myh0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMuc2V0KGVbMF0sZVszXSxlWzZdLDAsZVsxXSxlWzRdLGVbN10sMCxlWzJdLGVbNV0sZVs4XSwwLDAsMCwwLDEpLHRoaXN9ZXh0cmFjdEJhc2lzKHQsZSxuKXtyZXR1cm4gdC5zZXRGcm9tTWF0cml4Q29sdW1uKHRoaXMsMCksZS5zZXRGcm9tTWF0cml4Q29sdW1uKHRoaXMsMSksbi5zZXRGcm9tTWF0cml4Q29sdW1uKHRoaXMsMiksdGhpc31tYWtlQmFzaXModCxlLG4pe3JldHVybiB0aGlzLnNldCh0LngsZS54LG4ueCwwLHQueSxlLnksbi55LDAsdC56LGUueixuLnosMCwwLDAsMCwxKSx0aGlzfWV4dHJhY3RSb3RhdGlvbih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzLHM9MS9Pbi5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMCkubGVuZ3RoKCkscj0xL09uLnNldEZyb21NYXRyaXhDb2x1bW4odCwxKS5sZW5ndGgoKSxvPTEvT24uc2V0RnJvbU1hdHJpeENvbHVtbih0LDIpLmxlbmd0aCgpO3JldHVybiBlWzBdPW5bMF0qcyxlWzFdPW5bMV0qcyxlWzJdPW5bMl0qcyxlWzNdPTAsZVs0XT1uWzRdKnIsZVs1XT1uWzVdKnIsZVs2XT1uWzZdKnIsZVs3XT0wLGVbOF09bls4XSpvLGVbOV09bls5XSpvLGVbMTBdPW5bMTBdKm8sZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLHRoaXN9bWFrZVJvdGF0aW9uRnJvbUV1bGVyKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQueCxzPXQueSxyPXQueixvPU1hdGguY29zKG4pLGE9TWF0aC5zaW4obiksYz1NYXRoLmNvcyhzKSxsPU1hdGguc2luKHMpLGg9TWF0aC5jb3MociksdT1NYXRoLnNpbihyKTtpZih0Lm9yZGVyPT09IlhZWiIpe2NvbnN0IGY9bypoLGQ9byp1LHA9YSpoLHk9YSp1O2VbMF09YypoLGVbNF09LWMqdSxlWzhdPWwsZVsxXT1kK3AqbCxlWzVdPWYteSpsLGVbOV09LWEqYyxlWzJdPXktZipsLGVbNl09cCtkKmwsZVsxMF09bypjfWVsc2UgaWYodC5vcmRlcj09PSJZWFoiKXtjb25zdCBmPWMqaCxkPWMqdSxwPWwqaCx5PWwqdTtlWzBdPWYreSphLGVbNF09cCphLWQsZVs4XT1vKmwsZVsxXT1vKnUsZVs1XT1vKmgsZVs5XT0tYSxlWzJdPWQqYS1wLGVbNl09eStmKmEsZVsxMF09bypjfWVsc2UgaWYodC5vcmRlcj09PSJaWFkiKXtjb25zdCBmPWMqaCxkPWMqdSxwPWwqaCx5PWwqdTtlWzBdPWYteSphLGVbNF09LW8qdSxlWzhdPXArZCphLGVbMV09ZCtwKmEsZVs1XT1vKmgsZVs5XT15LWYqYSxlWzJdPS1vKmwsZVs2XT1hLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWllYIil7Y29uc3QgZj1vKmgsZD1vKnUscD1hKmgseT1hKnU7ZVswXT1jKmgsZVs0XT1wKmwtZCxlWzhdPWYqbCt5LGVbMV09Yyp1LGVbNV09eSpsK2YsZVs5XT1kKmwtcCxlWzJdPS1sLGVbNl09YSpjLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWVpYIil7Y29uc3QgZj1vKmMsZD1vKmwscD1hKmMseT1hKmw7ZVswXT1jKmgsZVs0XT15LWYqdSxlWzhdPXAqdStkLGVbMV09dSxlWzVdPW8qaCxlWzldPS1hKmgsZVsyXT0tbCpoLGVbNl09ZCp1K3AsZVsxMF09Zi15KnV9ZWxzZSBpZih0Lm9yZGVyPT09IlhaWSIpe2NvbnN0IGY9bypjLGQ9bypsLHA9YSpjLHk9YSpsO2VbMF09YypoLGVbNF09LXUsZVs4XT1sKmgsZVsxXT1mKnUreSxlWzVdPW8qaCxlWzldPWQqdS1wLGVbMl09cCp1LWQsZVs2XT1hKmgsZVsxMF09eSp1K2Z9cmV0dXJuIGVbM109MCxlWzddPTAsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLHRoaXN9bWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCl7cmV0dXJuIHRoaXMuY29tcG9zZShvZix0LGFmKX1sb29rQXQodCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cztyZXR1cm4gJHQuc3ViVmVjdG9ycyh0LGUpLCR0Lmxlbmd0aFNxKCk9PT0wJiYoJHQuej0xKSwkdC5ub3JtYWxpemUoKSxqZS5jcm9zc1ZlY3RvcnMobiwkdCksamUubGVuZ3RoU3EoKT09PTAmJihNYXRoLmFicyhuLnopPT09MT8kdC54Kz0xZS00OiR0LnorPTFlLTQsJHQubm9ybWFsaXplKCksamUuY3Jvc3NWZWN0b3JzKG4sJHQpKSxqZS5ub3JtYWxpemUoKSxmcy5jcm9zc1ZlY3RvcnMoJHQsamUpLHNbMF09amUueCxzWzRdPWZzLngsc1s4XT0kdC54LHNbMV09amUueSxzWzVdPWZzLnksc1s5XT0kdC55LHNbMl09amUueixzWzZdPWZzLnosc1sxMF09JHQueix0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXModGhpcyx0KX1wcmVtdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHQsdGhpcyl9bXVsdGlwbHlNYXRyaWNlcyh0LGUpe2NvbnN0IG49dC5lbGVtZW50cyxzPWUuZWxlbWVudHMscj10aGlzLmVsZW1lbnRzLG89blswXSxhPW5bNF0sYz1uWzhdLGw9blsxMl0saD1uWzFdLHU9bls1XSxmPW5bOV0sZD1uWzEzXSxwPW5bMl0seT1uWzZdLG09blsxMF0sZz1uWzE0XSxiPW5bM10sdz1uWzddLHg9blsxMV0sTT1uWzE1XSxBPXNbMF0sUz1zWzRdLF89c1s4XSxFPXNbMTJdLHo9c1sxXSx2PXNbNV0sQz1zWzldLFA9c1sxM10sRj1zWzJdLEI9c1s2XSxJPXNbMTBdLGs9c1sxNF0sRD1zWzNdLFU9c1s3XSxqPXNbMTFdLGR0PXNbMTVdO3JldHVybiByWzBdPW8qQSthKnorYypGK2wqRCxyWzRdPW8qUythKnYrYypCK2wqVSxyWzhdPW8qXythKkMrYypJK2wqaixyWzEyXT1vKkUrYSpQK2MqaytsKmR0LHJbMV09aCpBK3UqeitmKkYrZCpELHJbNV09aCpTK3UqditmKkIrZCpVLHJbOV09aCpfK3UqQytmKkkrZCpqLHJbMTNdPWgqRSt1KlArZiprK2QqZHQsclsyXT1wKkEreSp6K20qRitnKkQscls2XT1wKlMreSp2K20qQitnKlUsclsxMF09cCpfK3kqQyttKkkrZypqLHJbMTRdPXAqRSt5KlArbSprK2cqZHQsclszXT1iKkErdyp6K3gqRitNKkQscls3XT1iKlMrdyp2K3gqQitNKlUsclsxMV09YipfK3cqQyt4KkkrTSpqLHJbMTVdPWIqRSt3KlAreCprK00qZHQsdGhpc31tdWx0aXBseVNjYWxhcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIGVbMF0qPXQsZVs0XSo9dCxlWzhdKj10LGVbMTJdKj10LGVbMV0qPXQsZVs1XSo9dCxlWzldKj10LGVbMTNdKj10LGVbMl0qPXQsZVs2XSo9dCxlWzEwXSo9dCxlWzE0XSo9dCxlWzNdKj10LGVbN10qPXQsZVsxMV0qPXQsZVsxNV0qPXQsdGhpc31kZXRlcm1pbmFudCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzRdLHM9dFs4XSxyPXRbMTJdLG89dFsxXSxhPXRbNV0sYz10WzldLGw9dFsxM10saD10WzJdLHU9dFs2XSxmPXRbMTBdLGQ9dFsxNF0scD10WzNdLHk9dFs3XSxtPXRbMTFdLGc9dFsxNV07cmV0dXJuIHAqKCtyKmMqdS1zKmwqdS1yKmEqZituKmwqZitzKmEqZC1uKmMqZCkreSooK2UqYypkLWUqbCpmK3IqbypmLXMqbypkK3MqbCpoLXIqYypoKSttKigrZSpsKnUtZSphKmQtcipvKnUrbipvKmQrciphKmgtbipsKmgpK2cqKC1zKmEqaC1lKmMqdStlKmEqZitzKm8qdS1uKm8qZituKmMqaCl9dHJhbnNwb3NlKCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzO2xldCBlO3JldHVybiBlPXRbMV0sdFsxXT10WzRdLHRbNF09ZSxlPXRbMl0sdFsyXT10WzhdLHRbOF09ZSxlPXRbNl0sdFs2XT10WzldLHRbOV09ZSxlPXRbM10sdFszXT10WzEyXSx0WzEyXT1lLGU9dFs3XSx0WzddPXRbMTNdLHRbMTNdPWUsZT10WzExXSx0WzExXT10WzE0XSx0WzE0XT1lLHRoaXN9c2V0UG9zaXRpb24odCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cztyZXR1cm4gdC5pc1ZlY3RvcjM/KHNbMTJdPXQueCxzWzEzXT10Lnksc1sxNF09dC56KTooc1sxMl09dCxzWzEzXT1lLHNbMTRdPW4pLHRoaXN9aW52ZXJ0KCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzLGU9dFswXSxuPXRbMV0scz10WzJdLHI9dFszXSxvPXRbNF0sYT10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdLHU9dFs5XSxmPXRbMTBdLGQ9dFsxMV0scD10WzEyXSx5PXRbMTNdLG09dFsxNF0sZz10WzE1XSxiPXUqbSpsLXkqZipsK3kqYypkLWEqbSpkLXUqYypnK2EqZipnLHc9cCpmKmwtaCptKmwtcCpjKmQrbyptKmQraCpjKmctbypmKmcseD1oKnkqbC1wKnUqbCtwKmEqZC1vKnkqZC1oKmEqZytvKnUqZyxNPXAqdSpjLWgqeSpjLXAqYSpmK28qeSpmK2gqYSptLW8qdSptLEE9ZSpiK24qdytzKngrcipNO2lmKEE9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwKTtjb25zdCBTPTEvQTtyZXR1cm4gdFswXT1iKlMsdFsxXT0oeSpmKnItdSptKnIteSpzKmQrbiptKmQrdSpzKmctbipmKmcpKlMsdFsyXT0oYSptKnIteSpjKnIreSpzKmwtbiptKmwtYSpzKmcrbipjKmcpKlMsdFszXT0odSpjKnItYSpmKnItdSpzKmwrbipmKmwrYSpzKmQtbipjKmQpKlMsdFs0XT13KlMsdFs1XT0oaCptKnItcCpmKnIrcCpzKmQtZSptKmQtaCpzKmcrZSpmKmcpKlMsdFs2XT0ocCpjKnItbyptKnItcCpzKmwrZSptKmwrbypzKmctZSpjKmcpKlMsdFs3XT0obypmKnItaCpjKnIraCpzKmwtZSpmKmwtbypzKmQrZSpjKmQpKlMsdFs4XT14KlMsdFs5XT0ocCp1KnItaCp5KnItcCpuKmQrZSp5KmQraCpuKmctZSp1KmcpKlMsdFsxMF09KG8qeSpyLXAqYSpyK3AqbipsLWUqeSpsLW8qbipnK2UqYSpnKSpTLHRbMTFdPShoKmEqci1vKnUqci1oKm4qbCtlKnUqbCtvKm4qZC1lKmEqZCkqUyx0WzEyXT1NKlMsdFsxM109KGgqeSpzLXAqdSpzK3AqbipmLWUqeSpmLWgqbiptK2UqdSptKSpTLHRbMTRdPShwKmEqcy1vKnkqcy1wKm4qYytlKnkqYytvKm4qbS1lKmEqbSkqUyx0WzE1XT0obyp1KnMtaCphKnMraCpuKmMtZSp1KmMtbypuKmYrZSphKmYpKlMsdGhpc31zY2FsZSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10Lngscz10Lnkscj10Lno7cmV0dXJuIGVbMF0qPW4sZVs0XSo9cyxlWzhdKj1yLGVbMV0qPW4sZVs1XSo9cyxlWzldKj1yLGVbMl0qPW4sZVs2XSo9cyxlWzEwXSo9cixlWzNdKj1uLGVbN10qPXMsZVsxMV0qPXIsdGhpc31nZXRNYXhTY2FsZU9uQXhpcygpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0qdFswXSt0WzFdKnRbMV0rdFsyXSp0WzJdLG49dFs0XSp0WzRdK3RbNV0qdFs1XSt0WzZdKnRbNl0scz10WzhdKnRbOF0rdFs5XSp0WzldK3RbMTBdKnRbMTBdO3JldHVybiBNYXRoLnNxcnQoTWF0aC5tYXgoZSxuLHMpKX1tYWtlVHJhbnNsYXRpb24odCxlLG4pe3JldHVybiB0LmlzVmVjdG9yMz90aGlzLnNldCgxLDAsMCx0LngsMCwxLDAsdC55LDAsMCwxLHQueiwwLDAsMCwxKTp0aGlzLnNldCgxLDAsMCx0LDAsMSwwLGUsMCwwLDEsbiwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvblgodCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldCgxLDAsMCwwLDAsZSwtbiwwLDAsbixlLDAsMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25ZKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoZSwwLG4sMCwwLDEsMCwwLC1uLDAsZSwwLDAsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uWih0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsLW4sMCwwLG4sZSwwLDAsMCwwLDEsMCwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbkF4aXModCxlKXtjb25zdCBuPU1hdGguY29zKGUpLHM9TWF0aC5zaW4oZSkscj0xLW4sbz10LngsYT10LnksYz10LnosbD1yKm8saD1yKmE7cmV0dXJuIHRoaXMuc2V0KGwqbytuLGwqYS1zKmMsbCpjK3MqYSwwLGwqYStzKmMsaCphK24saCpjLXMqbywwLGwqYy1zKmEsaCpjK3MqbyxyKmMqYytuLDAsMCwwLDAsMSksdGhpc31tYWtlU2NhbGUodCxlLG4pe3JldHVybiB0aGlzLnNldCh0LDAsMCwwLDAsZSwwLDAsMCwwLG4sMCwwLDAsMCwxKSx0aGlzfW1ha2VTaGVhcih0LGUsbixzLHIsbyl7cmV0dXJuIHRoaXMuc2V0KDEsbixyLDAsdCwxLG8sMCxlLHMsMSwwLDAsMCwwLDEpLHRoaXN9Y29tcG9zZSh0LGUsbil7Y29uc3Qgcz10aGlzLmVsZW1lbnRzLHI9ZS5feCxvPWUuX3ksYT1lLl96LGM9ZS5fdyxsPXIrcixoPW8rbyx1PWErYSxmPXIqbCxkPXIqaCxwPXIqdSx5PW8qaCxtPW8qdSxnPWEqdSxiPWMqbCx3PWMqaCx4PWMqdSxNPW4ueCxBPW4ueSxTPW4uejtyZXR1cm4gc1swXT0oMS0oeStnKSkqTSxzWzFdPShkK3gpKk0sc1syXT0ocC13KSpNLHNbM109MCxzWzRdPShkLXgpKkEsc1s1XT0oMS0oZitnKSkqQSxzWzZdPShtK2IpKkEsc1s3XT0wLHNbOF09KHArdykqUyxzWzldPShtLWIpKlMsc1sxMF09KDEtKGYreSkpKlMsc1sxMV09MCxzWzEyXT10Lngsc1sxM109dC55LHNbMTRdPXQueixzWzE1XT0xLHRoaXN9ZGVjb21wb3NlKHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7bGV0IHI9T24uc2V0KHNbMF0sc1sxXSxzWzJdKS5sZW5ndGgoKTtjb25zdCBvPU9uLnNldChzWzRdLHNbNV0sc1s2XSkubGVuZ3RoKCksYT1Pbi5zZXQoc1s4XSxzWzldLHNbMTBdKS5sZW5ndGgoKTt0aGlzLmRldGVybWluYW50KCk8MCYmKHI9LXIpLHQueD1zWzEyXSx0Lnk9c1sxM10sdC56PXNbMTRdLGxlLmNvcHkodGhpcyk7Y29uc3QgbD0xL3IsaD0xL28sdT0xL2E7cmV0dXJuIGxlLmVsZW1lbnRzWzBdKj1sLGxlLmVsZW1lbnRzWzFdKj1sLGxlLmVsZW1lbnRzWzJdKj1sLGxlLmVsZW1lbnRzWzRdKj1oLGxlLmVsZW1lbnRzWzVdKj1oLGxlLmVsZW1lbnRzWzZdKj1oLGxlLmVsZW1lbnRzWzhdKj11LGxlLmVsZW1lbnRzWzldKj11LGxlLmVsZW1lbnRzWzEwXSo9dSxlLnNldEZyb21Sb3RhdGlvbk1hdHJpeChsZSksbi54PXIsbi55PW8sbi56PWEsdGhpc31tYWtlUGVyc3BlY3RpdmUodCxlLG4scyxyLG8sYT0yZTMpe2NvbnN0IGM9dGhpcy5lbGVtZW50cyxsPTIqci8oZS10KSxoPTIqci8obi1zKSx1PShlK3QpLyhlLXQpLGY9KG4rcykvKG4tcyk7bGV0IGQscDtpZihhPT09MmUzKWQ9LShvK3IpLyhvLXIpLHA9LTIqbypyLyhvLXIpO2Vsc2UgaWYoYT09PTIwMDEpZD0tby8oby1yKSxwPS1vKnIvKG8tcik7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIlRIUkVFLk1hdHJpeDQubWFrZVBlcnNwZWN0aXZlKCk6IEludmFsaWQgY29vcmRpbmF0ZSBzeXN0ZW06ICIrYSk7cmV0dXJuIGNbMF09bCxjWzRdPTAsY1s4XT11LGNbMTJdPTAsY1sxXT0wLGNbNV09aCxjWzldPWYsY1sxM109MCxjWzJdPTAsY1s2XT0wLGNbMTBdPWQsY1sxNF09cCxjWzNdPTAsY1s3XT0wLGNbMTFdPS0xLGNbMTVdPTAsdGhpc31tYWtlT3J0aG9ncmFwaGljKHQsZSxuLHMscixvLGE9MmUzKXtjb25zdCBjPXRoaXMuZWxlbWVudHMsbD0xLyhlLXQpLGg9MS8obi1zKSx1PTEvKG8tciksZj0oZSt0KSpsLGQ9KG4rcykqaDtsZXQgcCx5O2lmKGE9PT0yZTMpcD0obytyKSp1LHk9LTIqdTtlbHNlIGlmKGE9PT0yMDAxKXA9cip1LHk9LTEqdTtlbHNlIHRocm93IG5ldyBFcnJvcigiVEhSRUUuTWF0cml4NC5tYWtlT3J0aG9ncmFwaGljKCk6IEludmFsaWQgY29vcmRpbmF0ZSBzeXN0ZW06ICIrYSk7cmV0dXJuIGNbMF09MipsLGNbNF09MCxjWzhdPTAsY1sxMl09LWYsY1sxXT0wLGNbNV09MipoLGNbOV09MCxjWzEzXT0tZCxjWzJdPTAsY1s2XT0wLGNbMTBdPXksY1sxNF09LXAsY1szXT0wLGNbN109MCxjWzExXT0wLGNbMTVdPTEsdGhpc31lcXVhbHModCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztmb3IobGV0IHM9MDtzPDE2O3MrKylpZihlW3NdIT09bltzXSlyZXR1cm4hMTtyZXR1cm4hMH1mcm9tQXJyYXkodCxlPTApe2ZvcihsZXQgbj0wO248MTY7bisrKXRoaXMuZWxlbWVudHNbbl09dFtuK2VdO3JldHVybiB0aGlzfXRvQXJyYXkodD1bXSxlPTApe2NvbnN0IG49dGhpcy5lbGVtZW50cztyZXR1cm4gdFtlXT1uWzBdLHRbZSsxXT1uWzFdLHRbZSsyXT1uWzJdLHRbZSszXT1uWzNdLHRbZSs0XT1uWzRdLHRbZSs1XT1uWzVdLHRbZSs2XT1uWzZdLHRbZSs3XT1uWzddLHRbZSs4XT1uWzhdLHRbZSs5XT1uWzldLHRbZSsxMF09blsxMF0sdFtlKzExXT1uWzExXSx0W2UrMTJdPW5bMTJdLHRbZSsxM109blsxM10sdFtlKzE0XT1uWzE0XSx0W2UrMTVdPW5bMTVdLHR9fWNvbnN0IE9uPW5ldyBULGxlPW5ldyBzdCxvZj1uZXcgVCgwLDAsMCksYWY9bmV3IFQoMSwxLDEpLGplPW5ldyBULGZzPW5ldyBULCR0PW5ldyBULEVjPW5ldyBzdCxQYz1uZXcgZ2k7Y2xhc3MgYml7Y29uc3RydWN0b3IodD0wLGU9MCxuPTAscz1iaS5ERUZBVUxUX09SREVSKXt0aGlzLmlzRXVsZXI9ITAsdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fb3JkZXI9c31nZXQgeCgpe3JldHVybiB0aGlzLl94fXNldCB4KHQpe3RoaXMuX3g9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHkoKXtyZXR1cm4gdGhpcy5feX1zZXQgeSh0KXt0aGlzLl95PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB6KCl7cmV0dXJuIHRoaXMuX3p9c2V0IHoodCl7dGhpcy5fej10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgb3JkZXIoKXtyZXR1cm4gdGhpcy5fb3JkZXJ9c2V0IG9yZGVyKHQpe3RoaXMuX29yZGVyPXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfXNldCh0LGUsbixzPXRoaXMuX29yZGVyKXtyZXR1cm4gdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fb3JkZXI9cyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl94LHRoaXMuX3ksdGhpcy5feix0aGlzLl9vcmRlcil9Y29weSh0KXtyZXR1cm4gdGhpcy5feD10Ll94LHRoaXMuX3k9dC5feSx0aGlzLl96PXQuX3osdGhpcy5fb3JkZXI9dC5fb3JkZXIsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVJvdGF0aW9uTWF0cml4KHQsZT10aGlzLl9vcmRlcixuPSEwKXtjb25zdCBzPXQuZWxlbWVudHMscj1zWzBdLG89c1s0XSxhPXNbOF0sYz1zWzFdLGw9c1s1XSxoPXNbOV0sdT1zWzJdLGY9c1s2XSxkPXNbMTBdO3N3aXRjaChlKXtjYXNlIlhZWiI6dGhpcy5feT1NYXRoLmFzaW4oWihhLC0xLDEpKSxNYXRoLmFicyhhKTwuOTk5OTk5OT8odGhpcy5feD1NYXRoLmF0YW4yKC1oLGQpLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxyKSk6KHRoaXMuX3g9TWF0aC5hdGFuMihmLGwpLHRoaXMuX3o9MCk7YnJlYWs7Y2FzZSJZWFoiOnRoaXMuX3g9TWF0aC5hc2luKC1aKGgsLTEsMSkpLE1hdGguYWJzKGgpPC45OTk5OTk5Pyh0aGlzLl95PU1hdGguYXRhbjIoYSxkKSx0aGlzLl96PU1hdGguYXRhbjIoYyxsKSk6KHRoaXMuX3k9TWF0aC5hdGFuMigtdSxyKSx0aGlzLl96PTApO2JyZWFrO2Nhc2UiWlhZIjp0aGlzLl94PU1hdGguYXNpbihaKGYsLTEsMSkpLE1hdGguYWJzKGYpPC45OTk5OTk5Pyh0aGlzLl95PU1hdGguYXRhbjIoLXUsZCksdGhpcy5fej1NYXRoLmF0YW4yKC1vLGwpKToodGhpcy5feT0wLHRoaXMuX3o9TWF0aC5hdGFuMihjLHIpKTticmVhaztjYXNlIlpZWCI6dGhpcy5feT1NYXRoLmFzaW4oLVoodSwtMSwxKSksTWF0aC5hYnModSk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMihmLGQpLHRoaXMuX3o9TWF0aC5hdGFuMihjLHIpKToodGhpcy5feD0wLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxsKSk7YnJlYWs7Y2FzZSJZWlgiOnRoaXMuX3o9TWF0aC5hc2luKFooYywtMSwxKSksTWF0aC5hYnMoYyk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMigtaCxsKSx0aGlzLl95PU1hdGguYXRhbjIoLXUscikpOih0aGlzLl94PTAsdGhpcy5feT1NYXRoLmF0YW4yKGEsZCkpO2JyZWFrO2Nhc2UiWFpZIjp0aGlzLl96PU1hdGguYXNpbigtWihvLC0xLDEpKSxNYXRoLmFicyhvKTwuOTk5OTk5OT8odGhpcy5feD1NYXRoLmF0YW4yKGYsbCksdGhpcy5feT1NYXRoLmF0YW4yKGEscikpOih0aGlzLl94PU1hdGguYXRhbjIoLWgsZCksdGhpcy5feT0wKTticmVhaztkZWZhdWx0OmNvbnNvbGUud2FybigiVEhSRUUuRXVsZXI6IC5zZXRGcm9tUm90YXRpb25NYXRyaXgoKSBlbmNvdW50ZXJlZCBhbiB1bmtub3duIG9yZGVyOiAiK2UpfXJldHVybiB0aGlzLl9vcmRlcj1lLG49PT0hMCYmdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVF1YXRlcm5pb24odCxlLG4pe3JldHVybiBFYy5tYWtlUm90YXRpb25Gcm9tUXVhdGVybmlvbih0KSx0aGlzLnNldEZyb21Sb3RhdGlvbk1hdHJpeChFYyxlLG4pfXNldEZyb21WZWN0b3IzKHQsZT10aGlzLl9vcmRlcil7cmV0dXJuIHRoaXMuc2V0KHQueCx0LnksdC56LGUpfXJlb3JkZXIodCl7cmV0dXJuIFBjLnNldEZyb21FdWxlcih0aGlzKSx0aGlzLnNldEZyb21RdWF0ZXJuaW9uKFBjLHQpfWVxdWFscyh0KXtyZXR1cm4gdC5feD09PXRoaXMuX3gmJnQuX3k9PT10aGlzLl95JiZ0Ll96PT09dGhpcy5feiYmdC5fb3JkZXI9PT10aGlzLl9vcmRlcn1mcm9tQXJyYXkodCl7cmV0dXJuIHRoaXMuX3g9dFswXSx0aGlzLl95PXRbMV0sdGhpcy5fej10WzJdLHRbM10hPT12b2lkIDAmJih0aGlzLl9vcmRlcj10WzNdKSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLl94LHRbZSsxXT10aGlzLl95LHRbZSsyXT10aGlzLl96LHRbZSszXT10aGlzLl9vcmRlcix0fV9vbkNoYW5nZSh0KXtyZXR1cm4gdGhpcy5fb25DaGFuZ2VDYWxsYmFjaz10LHRoaXN9X29uQ2hhbmdlQ2FsbGJhY2soKXt9KltTeW1ib2wuaXRlcmF0b3JdKCl7eWllbGQgdGhpcy5feCx5aWVsZCB0aGlzLl95LHlpZWxkIHRoaXMuX3oseWllbGQgdGhpcy5fb3JkZXJ9fWJpLkRFRkFVTFRfT1JERVI9IlhZWiI7Y2xhc3MgY2Z7Y29uc3RydWN0b3IoKXt0aGlzLm1hc2s9MX1zZXQodCl7dGhpcy5tYXNrPSgxPDx0fDApPj4+MH1lbmFibGUodCl7dGhpcy5tYXNrfD0xPDx0fDB9ZW5hYmxlQWxsKCl7dGhpcy5tYXNrPS0xfXRvZ2dsZSh0KXt0aGlzLm1hc2tePTE8PHR8MH1kaXNhYmxlKHQpe3RoaXMubWFzayY9figxPDx0fDApfWRpc2FibGVBbGwoKXt0aGlzLm1hc2s9MH10ZXN0KHQpe3JldHVybih0aGlzLm1hc2smdC5tYXNrKSE9PTB9aXNFbmFibGVkKHQpe3JldHVybih0aGlzLm1hc2smKDE8PHR8MCkpIT09MH19bGV0IGxmPTA7Y29uc3QgQ2M9bmV3IFQsRG49bmV3IGdpLFRlPW5ldyBzdCxkcz1uZXcgVCxNaT1uZXcgVCxoZj1uZXcgVCx1Zj1uZXcgZ2ksQmM9bmV3IFQoMSwwLDApLEZjPW5ldyBUKDAsMSwwKSxJYz1uZXcgVCgwLDAsMSksa2M9e3R5cGU6ImFkZGVkIn0sZmY9e3R5cGU6InJlbW92ZWQifSwkbj17dHlwZToiY2hpbGRhZGRlZCIsY2hpbGQ6bnVsbH0scG89e3R5cGU6ImNoaWxkcmVtb3ZlZCIsY2hpbGQ6bnVsbH07Y2xhc3MgRWUgZXh0ZW5kcyBvc3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy5pc09iamVjdDNEPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOmxmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy50eXBlPSJPYmplY3QzRCIsdGhpcy5wYXJlbnQ9bnVsbCx0aGlzLmNoaWxkcmVuPVtdLHRoaXMudXA9RWUuREVGQVVMVF9VUC5jbG9uZSgpO2NvbnN0IHQ9bmV3IFQsZT1uZXcgYmksbj1uZXcgZ2kscz1uZXcgVCgxLDEsMSk7ZnVuY3Rpb24gcigpe24uc2V0RnJvbUV1bGVyKGUsITEpfWZ1bmN0aW9uIG8oKXtlLnNldEZyb21RdWF0ZXJuaW9uKG4sdm9pZCAwLCExKX1lLl9vbkNoYW5nZShyKSxuLl9vbkNoYW5nZShvKSxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLHtwb3NpdGlvbjp7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITAsdmFsdWU6dH0scm90YXRpb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOmV9LHF1YXRlcm5pb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOm59LHNjYWxlOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTpzfSxtb2RlbFZpZXdNYXRyaXg6e3ZhbHVlOm5ldyBzdH0sbm9ybWFsTWF0cml4Ont2YWx1ZTpuZXcgZ2V9fSksdGhpcy5tYXRyaXg9bmV3IHN0LHRoaXMubWF0cml4V29ybGQ9bmV3IHN0LHRoaXMubWF0cml4QXV0b1VwZGF0ZT1FZS5ERUZBVUxUX01BVFJJWF9BVVRPX1VQREFURSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT1FZS5ERUZBVUxUX01BVFJJWF9XT1JMRF9BVVRPX1VQREFURSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITEsdGhpcy5sYXllcnM9bmV3IGNmLHRoaXMudmlzaWJsZT0hMCx0aGlzLmNhc3RTaGFkb3c9ITEsdGhpcy5yZWNlaXZlU2hhZG93PSExLHRoaXMuZnJ1c3R1bUN1bGxlZD0hMCx0aGlzLnJlbmRlck9yZGVyPTAsdGhpcy5hbmltYXRpb25zPVtdLHRoaXMuY3VzdG9tRGVwdGhNYXRlcmlhbD12b2lkIDAsdGhpcy5jdXN0b21EaXN0YW5jZU1hdGVyaWFsPXZvaWQgMCx0aGlzLnVzZXJEYXRhPXt9fW9uQmVmb3JlU2hhZG93KCl7fW9uQWZ0ZXJTaGFkb3coKXt9b25CZWZvcmVSZW5kZXIoKXt9b25BZnRlclJlbmRlcigpe31hcHBseU1hdHJpeDQodCl7dGhpcy5tYXRyaXhBdXRvVXBkYXRlJiZ0aGlzLnVwZGF0ZU1hdHJpeCgpLHRoaXMubWF0cml4LnByZW11bHRpcGx5KHQpLHRoaXMubWF0cml4LmRlY29tcG9zZSh0aGlzLnBvc2l0aW9uLHRoaXMucXVhdGVybmlvbix0aGlzLnNjYWxlKX1hcHBseVF1YXRlcm5pb24odCl7cmV0dXJuIHRoaXMucXVhdGVybmlvbi5wcmVtdWx0aXBseSh0KSx0aGlzfXNldFJvdGF0aW9uRnJvbUF4aXNBbmdsZSh0LGUpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSl9c2V0Um90YXRpb25Gcm9tRXVsZXIodCl7dGhpcy5xdWF0ZXJuaW9uLnNldEZyb21FdWxlcih0LCEwKX1zZXRSb3RhdGlvbkZyb21NYXRyaXgodCl7dGhpcy5xdWF0ZXJuaW9uLnNldEZyb21Sb3RhdGlvbk1hdHJpeCh0KX1zZXRSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpe3RoaXMucXVhdGVybmlvbi5jb3B5KHQpfXJvdGF0ZU9uQXhpcyh0LGUpe3JldHVybiBEbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSksdGhpcy5xdWF0ZXJuaW9uLm11bHRpcGx5KERuKSx0aGlzfXJvdGF0ZU9uV29ybGRBeGlzKHQsZSl7cmV0dXJuIERuLnNldEZyb21BeGlzQW5nbGUodCxlKSx0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkoRG4pLHRoaXN9cm90YXRlWCh0KXtyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoQmMsdCl9cm90YXRlWSh0KXtyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoRmMsdCl9cm90YXRlWih0KXtyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoSWMsdCl9dHJhbnNsYXRlT25BeGlzKHQsZSl7cmV0dXJuIENjLmNvcHkodCkuYXBwbHlRdWF0ZXJuaW9uKHRoaXMucXVhdGVybmlvbiksdGhpcy5wb3NpdGlvbi5hZGQoQ2MubXVsdGlwbHlTY2FsYXIoZSkpLHRoaXN9dHJhbnNsYXRlWCh0KXtyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoQmMsdCl9dHJhbnNsYXRlWSh0KXtyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoRmMsdCl9dHJhbnNsYXRlWih0KXtyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoSWMsdCl9bG9jYWxUb1dvcmxkKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0LmFwcGx5TWF0cml4NCh0aGlzLm1hdHJpeFdvcmxkKX13b3JsZFRvTG9jYWwodCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHQuYXBwbHlNYXRyaXg0KFRlLmNvcHkodGhpcy5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkpfWxvb2tBdCh0LGUsbil7dC5pc1ZlY3RvcjM/ZHMuY29weSh0KTpkcy5zZXQodCxlLG4pO2NvbnN0IHM9dGhpcy5wYXJlbnQ7dGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksTWkuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKHRoaXMubWF0cml4V29ybGQpLHRoaXMuaXNDYW1lcmF8fHRoaXMuaXNMaWdodD9UZS5sb29rQXQoTWksZHMsdGhpcy51cCk6VGUubG9va0F0KGRzLE1pLHRoaXMudXApLHRoaXMucXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgoVGUpLHMmJihUZS5leHRyYWN0Um90YXRpb24ocy5tYXRyaXhXb3JsZCksRG4uc2V0RnJvbVJvdGF0aW9uTWF0cml4KFRlKSx0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkoRG4uaW52ZXJ0KCkpKX1hZGQodCl7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IobGV0IGU9MDtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXRoaXMuYWRkKGFyZ3VtZW50c1tlXSk7cmV0dXJuIHRoaXN9cmV0dXJuIHQ9PT10aGlzPyhjb25zb2xlLmVycm9yKCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBjYW4ndCBiZSBhZGRlZCBhcyBhIGNoaWxkIG9mIGl0c2VsZi4iLHQpLHRoaXMpOih0JiZ0LmlzT2JqZWN0M0Q/KHQucmVtb3ZlRnJvbVBhcmVudCgpLHQucGFyZW50PXRoaXMsdGhpcy5jaGlsZHJlbi5wdXNoKHQpLHQuZGlzcGF0Y2hFdmVudChrYyksJG4uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQoJG4pLCRuLmNoaWxkPW51bGwpOmNvbnNvbGUuZXJyb3IoIlRIUkVFLk9iamVjdDNELmFkZDogb2JqZWN0IG5vdCBhbiBpbnN0YW5jZSBvZiBUSFJFRS5PYmplY3QzRC4iLHQpLHRoaXMpfXJlbW92ZSh0KXtpZihhcmd1bWVudHMubGVuZ3RoPjEpe2ZvcihsZXQgbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspdGhpcy5yZW1vdmUoYXJndW1lbnRzW25dKTtyZXR1cm4gdGhpc31jb25zdCBlPXRoaXMuY2hpbGRyZW4uaW5kZXhPZih0KTtyZXR1cm4gZSE9PS0xJiYodC5wYXJlbnQ9bnVsbCx0aGlzLmNoaWxkcmVuLnNwbGljZShlLDEpLHQuZGlzcGF0Y2hFdmVudChmZikscG8uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQocG8pLHBvLmNoaWxkPW51bGwpLHRoaXN9cmVtb3ZlRnJvbVBhcmVudCgpe2NvbnN0IHQ9dGhpcy5wYXJlbnQ7cmV0dXJuIHQhPT1udWxsJiZ0LnJlbW92ZSh0aGlzKSx0aGlzfWNsZWFyKCl7cmV0dXJuIHRoaXMucmVtb3ZlKC4uLnRoaXMuY2hpbGRyZW4pfWF0dGFjaCh0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksVGUuY29weSh0aGlzLm1hdHJpeFdvcmxkKS5pbnZlcnQoKSx0LnBhcmVudCE9PW51bGwmJih0LnBhcmVudC51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksVGUubXVsdGlwbHkodC5wYXJlbnQubWF0cml4V29ybGQpKSx0LmFwcGx5TWF0cml4NChUZSksdC5yZW1vdmVGcm9tUGFyZW50KCksdC5wYXJlbnQ9dGhpcyx0aGlzLmNoaWxkcmVuLnB1c2godCksdC51cGRhdGVXb3JsZE1hdHJpeCghMSwhMCksdC5kaXNwYXRjaEV2ZW50KGtjKSwkbi5jaGlsZD10LHRoaXMuZGlzcGF0Y2hFdmVudCgkbiksJG4uY2hpbGQ9bnVsbCx0aGlzfWdldE9iamVjdEJ5SWQodCl7cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlQcm9wZXJ0eSgiaWQiLHQpfWdldE9iamVjdEJ5TmFtZSh0KXtyZXR1cm4gdGhpcy5nZXRPYmplY3RCeVByb3BlcnR5KCJuYW1lIix0KX1nZXRPYmplY3RCeVByb3BlcnR5KHQsZSl7aWYodGhpc1t0XT09PWUpcmV0dXJuIHRoaXM7Zm9yKGxldCBuPTAscz10aGlzLmNoaWxkcmVuLmxlbmd0aDtuPHM7bisrKXtjb25zdCBvPXRoaXMuY2hpbGRyZW5bbl0uZ2V0T2JqZWN0QnlQcm9wZXJ0eSh0LGUpO2lmKG8hPT12b2lkIDApcmV0dXJuIG99fWdldE9iamVjdHNCeVByb3BlcnR5KHQsZSxuPVtdKXt0aGlzW3RdPT09ZSYmbi5wdXNoKHRoaXMpO2NvbnN0IHM9dGhpcy5jaGlsZHJlbjtmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKyspc1tyXS5nZXRPYmplY3RzQnlQcm9wZXJ0eSh0LGUsbik7cmV0dXJuIG59Z2V0V29ybGRQb3NpdGlvbih0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdC5zZXRGcm9tTWF0cml4UG9zaXRpb24odGhpcy5tYXRyaXhXb3JsZCl9Z2V0V29ybGRRdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZShNaSx0LGhmKSx0fWdldFdvcmxkU2NhbGUodCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHRoaXMubWF0cml4V29ybGQuZGVjb21wb3NlKE1pLHVmLHQpLHR9Z2V0V29ybGREaXJlY3Rpb24odCl7dGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSk7Y29uc3QgZT10aGlzLm1hdHJpeFdvcmxkLmVsZW1lbnRzO3JldHVybiB0LnNldChlWzhdLGVbOV0sZVsxMF0pLm5vcm1hbGl6ZSgpfXJheWNhc3QoKXt9dHJhdmVyc2UodCl7dCh0aGlzKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udHJhdmVyc2UodCl9dHJhdmVyc2VWaXNpYmxlKHQpe2lmKHRoaXMudmlzaWJsZT09PSExKXJldHVybjt0KHRoaXMpO2NvbnN0IGU9dGhpcy5jaGlsZHJlbjtmb3IobGV0IG49MCxzPWUubGVuZ3RoO248cztuKyspZVtuXS50cmF2ZXJzZVZpc2libGUodCl9dHJhdmVyc2VBbmNlc3RvcnModCl7Y29uc3QgZT10aGlzLnBhcmVudDtlIT09bnVsbCYmKHQoZSksZS50cmF2ZXJzZUFuY2VzdG9ycyh0KSl9dXBkYXRlTWF0cml4KCl7dGhpcy5tYXRyaXguY29tcG9zZSh0aGlzLnBvc2l0aW9uLHRoaXMucXVhdGVybmlvbix0aGlzLnNjYWxlKSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITB9dXBkYXRlTWF0cml4V29ybGQodCl7dGhpcy5tYXRyaXhBdXRvVXBkYXRlJiZ0aGlzLnVwZGF0ZU1hdHJpeCgpLCh0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGV8fHQpJiYodGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9PT0hMCYmKHRoaXMucGFyZW50PT09bnVsbD90aGlzLm1hdHJpeFdvcmxkLmNvcHkodGhpcy5tYXRyaXgpOnRoaXMubWF0cml4V29ybGQubXVsdGlwbHlNYXRyaWNlcyh0aGlzLnBhcmVudC5tYXRyaXhXb3JsZCx0aGlzLm1hdHJpeCkpLHRoaXMubWF0cml4V29ybGROZWVkc1VwZGF0ZT0hMSx0PSEwKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udXBkYXRlTWF0cml4V29ybGQodCl9dXBkYXRlV29ybGRNYXRyaXgodCxlKXtjb25zdCBuPXRoaXMucGFyZW50O2lmKHQ9PT0hMCYmbiE9PW51bGwmJm4udXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHRoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT09PSEwJiYodGhpcy5wYXJlbnQ9PT1udWxsP3RoaXMubWF0cml4V29ybGQuY29weSh0aGlzLm1hdHJpeCk6dGhpcy5tYXRyaXhXb3JsZC5tdWx0aXBseU1hdHJpY2VzKHRoaXMucGFyZW50Lm1hdHJpeFdvcmxkLHRoaXMubWF0cml4KSksZT09PSEwKXtjb25zdCBzPXRoaXMuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXNbcl0udXBkYXRlV29ybGRNYXRyaXgoITEsITApfX10b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyIsbj17fTtlJiYodD17Z2VvbWV0cmllczp7fSxtYXRlcmlhbHM6e30sdGV4dHVyZXM6e30saW1hZ2VzOnt9LHNoYXBlczp7fSxza2VsZXRvbnM6e30sYW5pbWF0aW9uczp7fSxub2Rlczp7fX0sbi5tZXRhZGF0YT17dmVyc2lvbjo0LjcsdHlwZToiT2JqZWN0IixnZW5lcmF0b3I6Ik9iamVjdDNELnRvSlNPTiJ9KTtjb25zdCBzPXt9O3MudXVpZD10aGlzLnV1aWQscy50eXBlPXRoaXMudHlwZSx0aGlzLm5hbWUhPT0iIiYmKHMubmFtZT10aGlzLm5hbWUpLHRoaXMuY2FzdFNoYWRvdz09PSEwJiYocy5jYXN0U2hhZG93PSEwKSx0aGlzLnJlY2VpdmVTaGFkb3c9PT0hMCYmKHMucmVjZWl2ZVNoYWRvdz0hMCksdGhpcy52aXNpYmxlPT09ITEmJihzLnZpc2libGU9ITEpLHRoaXMuZnJ1c3R1bUN1bGxlZD09PSExJiYocy5mcnVzdHVtQ3VsbGVkPSExKSx0aGlzLnJlbmRlck9yZGVyIT09MCYmKHMucmVuZGVyT3JkZXI9dGhpcy5yZW5kZXJPcmRlciksT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihzLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLHMubGF5ZXJzPXRoaXMubGF5ZXJzLm1hc2sscy5tYXRyaXg9dGhpcy5tYXRyaXgudG9BcnJheSgpLHMudXA9dGhpcy51cC50b0FycmF5KCksdGhpcy5tYXRyaXhBdXRvVXBkYXRlPT09ITEmJihzLm1hdHJpeEF1dG9VcGRhdGU9ITEpLHRoaXMuaXNJbnN0YW5jZWRNZXNoJiYocy50eXBlPSJJbnN0YW5jZWRNZXNoIixzLmNvdW50PXRoaXMuY291bnQscy5pbnN0YW5jZU1hdHJpeD10aGlzLmluc3RhbmNlTWF0cml4LnRvSlNPTigpLHRoaXMuaW5zdGFuY2VDb2xvciE9PW51bGwmJihzLmluc3RhbmNlQ29sb3I9dGhpcy5pbnN0YW5jZUNvbG9yLnRvSlNPTigpKSksdGhpcy5pc0JhdGNoZWRNZXNoJiYocy50eXBlPSJCYXRjaGVkTWVzaCIscy5wZXJPYmplY3RGcnVzdHVtQ3VsbGVkPXRoaXMucGVyT2JqZWN0RnJ1c3R1bUN1bGxlZCxzLnNvcnRPYmplY3RzPXRoaXMuc29ydE9iamVjdHMscy5kcmF3UmFuZ2VzPXRoaXMuX2RyYXdSYW5nZXMscy5yZXNlcnZlZFJhbmdlcz10aGlzLl9yZXNlcnZlZFJhbmdlcyxzLmdlb21ldHJ5SW5mbz10aGlzLl9nZW9tZXRyeUluZm8ubWFwKGE9PlplKEZ0KHt9LGEpLHtib3VuZGluZ0JveDphLmJvdW5kaW5nQm94P2EuYm91bmRpbmdCb3gudG9KU09OKCk6dm9pZCAwLGJvdW5kaW5nU3BoZXJlOmEuYm91bmRpbmdTcGhlcmU/YS5ib3VuZGluZ1NwaGVyZS50b0pTT04oKTp2b2lkIDB9KSkscy5pbnN0YW5jZUluZm89dGhpcy5faW5zdGFuY2VJbmZvLm1hcChhPT5GdCh7fSxhKSkscy5hdmFpbGFibGVJbnN0YW5jZUlkcz10aGlzLl9hdmFpbGFibGVJbnN0YW5jZUlkcy5zbGljZSgpLHMuYXZhaWxhYmxlR2VvbWV0cnlJZHM9dGhpcy5fYXZhaWxhYmxlR2VvbWV0cnlJZHMuc2xpY2UoKSxzLm5leHRJbmRleFN0YXJ0PXRoaXMuX25leHRJbmRleFN0YXJ0LHMubmV4dFZlcnRleFN0YXJ0PXRoaXMuX25leHRWZXJ0ZXhTdGFydCxzLmdlb21ldHJ5Q291bnQ9dGhpcy5fZ2VvbWV0cnlDb3VudCxzLm1heEluc3RhbmNlQ291bnQ9dGhpcy5fbWF4SW5zdGFuY2VDb3VudCxzLm1heFZlcnRleENvdW50PXRoaXMuX21heFZlcnRleENvdW50LHMubWF4SW5kZXhDb3VudD10aGlzLl9tYXhJbmRleENvdW50LHMuZ2VvbWV0cnlJbml0aWFsaXplZD10aGlzLl9nZW9tZXRyeUluaXRpYWxpemVkLHMubWF0cmljZXNUZXh0dXJlPXRoaXMuX21hdHJpY2VzVGV4dHVyZS50b0pTT04odCkscy5pbmRpcmVjdFRleHR1cmU9dGhpcy5faW5kaXJlY3RUZXh0dXJlLnRvSlNPTih0KSx0aGlzLl9jb2xvcnNUZXh0dXJlIT09bnVsbCYmKHMuY29sb3JzVGV4dHVyZT10aGlzLl9jb2xvcnNUZXh0dXJlLnRvSlNPTih0KSksdGhpcy5ib3VuZGluZ1NwaGVyZSE9PW51bGwmJihzLmJvdW5kaW5nU3BoZXJlPXRoaXMuYm91bmRpbmdTcGhlcmUudG9KU09OKCkpLHRoaXMuYm91bmRpbmdCb3ghPT1udWxsJiYocy5ib3VuZGluZ0JveD10aGlzLmJvdW5kaW5nQm94LnRvSlNPTigpKSk7ZnVuY3Rpb24gcihhLGMpe3JldHVybiBhW2MudXVpZF09PT12b2lkIDAmJihhW2MudXVpZF09Yy50b0pTT04odCkpLGMudXVpZH1pZih0aGlzLmlzU2NlbmUpdGhpcy5iYWNrZ3JvdW5kJiYodGhpcy5iYWNrZ3JvdW5kLmlzQ29sb3I/cy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04oKTp0aGlzLmJhY2tncm91bmQuaXNUZXh0dXJlJiYocy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04odCkudXVpZCkpLHRoaXMuZW52aXJvbm1lbnQmJnRoaXMuZW52aXJvbm1lbnQuaXNUZXh0dXJlJiZ0aGlzLmVudmlyb25tZW50LmlzUmVuZGVyVGFyZ2V0VGV4dHVyZSE9PSEwJiYocy5lbnZpcm9ubWVudD10aGlzLmVudmlyb25tZW50LnRvSlNPTih0KS51dWlkKTtlbHNlIGlmKHRoaXMuaXNNZXNofHx0aGlzLmlzTGluZXx8dGhpcy5pc1BvaW50cyl7cy5nZW9tZXRyeT1yKHQuZ2VvbWV0cmllcyx0aGlzLmdlb21ldHJ5KTtjb25zdCBhPXRoaXMuZ2VvbWV0cnkucGFyYW1ldGVycztpZihhIT09dm9pZCAwJiZhLnNoYXBlcyE9PXZvaWQgMCl7Y29uc3QgYz1hLnNoYXBlcztpZihBcnJheS5pc0FycmF5KGMpKWZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyl7Y29uc3QgdT1jW2xdO3IodC5zaGFwZXMsdSl9ZWxzZSByKHQuc2hhcGVzLGMpfX1pZih0aGlzLmlzU2tpbm5lZE1lc2gmJihzLmJpbmRNb2RlPXRoaXMuYmluZE1vZGUscy5iaW5kTWF0cml4PXRoaXMuYmluZE1hdHJpeC50b0FycmF5KCksdGhpcy5za2VsZXRvbiE9PXZvaWQgMCYmKHIodC5za2VsZXRvbnMsdGhpcy5za2VsZXRvbikscy5za2VsZXRvbj10aGlzLnNrZWxldG9uLnV1aWQpKSx0aGlzLm1hdGVyaWFsIT09dm9pZCAwKWlmKEFycmF5LmlzQXJyYXkodGhpcy5tYXRlcmlhbCkpe2NvbnN0IGE9W107Zm9yKGxldCBjPTAsbD10aGlzLm1hdGVyaWFsLmxlbmd0aDtjPGw7YysrKWEucHVzaChyKHQubWF0ZXJpYWxzLHRoaXMubWF0ZXJpYWxbY10pKTtzLm1hdGVyaWFsPWF9ZWxzZSBzLm1hdGVyaWFsPXIodC5tYXRlcmlhbHMsdGhpcy5tYXRlcmlhbCk7aWYodGhpcy5jaGlsZHJlbi5sZW5ndGg+MCl7cy5jaGlsZHJlbj1bXTtmb3IobGV0IGE9MDthPHRoaXMuY2hpbGRyZW4ubGVuZ3RoO2ErKylzLmNoaWxkcmVuLnB1c2godGhpcy5jaGlsZHJlblthXS50b0pTT04odCkub2JqZWN0KX1pZih0aGlzLmFuaW1hdGlvbnMubGVuZ3RoPjApe3MuYW5pbWF0aW9ucz1bXTtmb3IobGV0IGE9MDthPHRoaXMuYW5pbWF0aW9ucy5sZW5ndGg7YSsrKXtjb25zdCBjPXRoaXMuYW5pbWF0aW9uc1thXTtzLmFuaW1hdGlvbnMucHVzaChyKHQuYW5pbWF0aW9ucyxjKSl9fWlmKGUpe2NvbnN0IGE9byh0Lmdlb21ldHJpZXMpLGM9byh0Lm1hdGVyaWFscyksbD1vKHQudGV4dHVyZXMpLGg9byh0LmltYWdlcyksdT1vKHQuc2hhcGVzKSxmPW8odC5za2VsZXRvbnMpLGQ9byh0LmFuaW1hdGlvbnMpLHA9byh0Lm5vZGVzKTthLmxlbmd0aD4wJiYobi5nZW9tZXRyaWVzPWEpLGMubGVuZ3RoPjAmJihuLm1hdGVyaWFscz1jKSxsLmxlbmd0aD4wJiYobi50ZXh0dXJlcz1sKSxoLmxlbmd0aD4wJiYobi5pbWFnZXM9aCksdS5sZW5ndGg+MCYmKG4uc2hhcGVzPXUpLGYubGVuZ3RoPjAmJihuLnNrZWxldG9ucz1mKSxkLmxlbmd0aD4wJiYobi5hbmltYXRpb25zPWQpLHAubGVuZ3RoPjAmJihuLm5vZGVzPXApfXJldHVybiBuLm9iamVjdD1zLG47ZnVuY3Rpb24gbyhhKXtjb25zdCBjPVtdO2Zvcihjb25zdCBsIGluIGEpe2NvbnN0IGg9YVtsXTtkZWxldGUgaC5tZXRhZGF0YSxjLnB1c2goaCl9cmV0dXJuIGN9fWNsb25lKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyx0KX1jb3B5KHQsZT0hMCl7aWYodGhpcy5uYW1lPXQubmFtZSx0aGlzLnVwLmNvcHkodC51cCksdGhpcy5wb3NpdGlvbi5jb3B5KHQucG9zaXRpb24pLHRoaXMucm90YXRpb24ub3JkZXI9dC5yb3RhdGlvbi5vcmRlcix0aGlzLnF1YXRlcm5pb24uY29weSh0LnF1YXRlcm5pb24pLHRoaXMuc2NhbGUuY29weSh0LnNjYWxlKSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLm1hdHJpeFdvcmxkLmNvcHkodC5tYXRyaXhXb3JsZCksdGhpcy5tYXRyaXhBdXRvVXBkYXRlPXQubWF0cml4QXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT10Lm1hdHJpeFdvcmxkQXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9dC5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlLHRoaXMubGF5ZXJzLm1hc2s9dC5sYXllcnMubWFzayx0aGlzLnZpc2libGU9dC52aXNpYmxlLHRoaXMuY2FzdFNoYWRvdz10LmNhc3RTaGFkb3csdGhpcy5yZWNlaXZlU2hhZG93PXQucmVjZWl2ZVNoYWRvdyx0aGlzLmZydXN0dW1DdWxsZWQ9dC5mcnVzdHVtQ3VsbGVkLHRoaXMucmVuZGVyT3JkZXI9dC5yZW5kZXJPcmRlcix0aGlzLmFuaW1hdGlvbnM9dC5hbmltYXRpb25zLnNsaWNlKCksdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSxlPT09ITApZm9yKGxldCBuPTA7bjx0LmNoaWxkcmVuLmxlbmd0aDtuKyspe2NvbnN0IHM9dC5jaGlsZHJlbltuXTt0aGlzLmFkZChzLmNsb25lKCkpfXJldHVybiB0aGlzfX1FZS5ERUZBVUxUX1VQPW5ldyBUKDAsMSwwKSxFZS5ERUZBVUxUX01BVFJJWF9BVVRPX1VQREFURT0hMCxFZS5ERUZBVUxUX01BVFJJWF9XT1JMRF9BVVRPX1VQREFURT0hMDtjb25zdCBoZT1uZXcgVCxQZT1uZXcgVCx5bz1uZXcgVCxDZT1uZXcgVCxWbj1uZXcgVCxVbj1uZXcgVCxOYz1uZXcgVCxtbz1uZXcgVCxnbz1uZXcgVCx4bz1uZXcgVCx3bz1uZXcgWXQsYm89bmV3IFl0LE1vPW5ldyBZdDtjbGFzcyBldHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCl7dGhpcy5hPXQsdGhpcy5iPWUsdGhpcy5jPW59c3RhdGljIGdldE5vcm1hbCh0LGUsbixzKXtzLnN1YlZlY3RvcnMobixlKSxoZS5zdWJWZWN0b3JzKHQsZSkscy5jcm9zcyhoZSk7Y29uc3Qgcj1zLmxlbmd0aFNxKCk7cmV0dXJuIHI+MD9zLm11bHRpcGx5U2NhbGFyKDEvTWF0aC5zcXJ0KHIpKTpzLnNldCgwLDAsMCl9c3RhdGljIGdldEJhcnljb29yZCh0LGUsbixzLHIpe2hlLnN1YlZlY3RvcnMocyxlKSxQZS5zdWJWZWN0b3JzKG4sZSkseW8uc3ViVmVjdG9ycyh0LGUpO2NvbnN0IG89aGUuZG90KGhlKSxhPWhlLmRvdChQZSksYz1oZS5kb3QoeW8pLGw9UGUuZG90KFBlKSxoPVBlLmRvdCh5byksdT1vKmwtYSphO2lmKHU9PT0wKXJldHVybiByLnNldCgwLDAsMCksbnVsbDtjb25zdCBmPTEvdSxkPShsKmMtYSpoKSpmLHA9KG8qaC1hKmMpKmY7cmV0dXJuIHIuc2V0KDEtZC1wLHAsZCl9c3RhdGljIGNvbnRhaW5zUG9pbnQodCxlLG4scyl7cmV0dXJuIHRoaXMuZ2V0QmFyeWNvb3JkKHQsZSxuLHMsQ2UpPT09bnVsbD8hMTpDZS54Pj0wJiZDZS55Pj0wJiZDZS54K0NlLnk8PTF9c3RhdGljIGdldEludGVycG9sYXRpb24odCxlLG4scyxyLG8sYSxjKXtyZXR1cm4gdGhpcy5nZXRCYXJ5Y29vcmQodCxlLG4scyxDZSk9PT1udWxsPyhjLng9MCxjLnk9MCwieiJpbiBjJiYoYy56PTApLCJ3ImluIGMmJihjLnc9MCksbnVsbCk6KGMuc2V0U2NhbGFyKDApLGMuYWRkU2NhbGVkVmVjdG9yKHIsQ2UueCksYy5hZGRTY2FsZWRWZWN0b3IobyxDZS55KSxjLmFkZFNjYWxlZFZlY3RvcihhLENlLnopLGMpfXN0YXRpYyBnZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUodCxlLG4scyxyLG8pe3JldHVybiB3by5zZXRTY2FsYXIoMCksYm8uc2V0U2NhbGFyKDApLE1vLnNldFNjYWxhcigwKSx3by5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSksYm8uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG4pLE1vLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSxvLnNldFNjYWxhcigwKSxvLmFkZFNjYWxlZFZlY3Rvcih3byxyLngpLG8uYWRkU2NhbGVkVmVjdG9yKGJvLHIueSksby5hZGRTY2FsZWRWZWN0b3IoTW8sci56KSxvfXN0YXRpYyBpc0Zyb250RmFjaW5nKHQsZSxuLHMpe3JldHVybiBoZS5zdWJWZWN0b3JzKG4sZSksUGUuc3ViVmVjdG9ycyh0LGUpLGhlLmNyb3NzKFBlKS5kb3Qocyk8MH1zZXQodCxlLG4pe3JldHVybiB0aGlzLmEuY29weSh0KSx0aGlzLmIuY29weShlKSx0aGlzLmMuY29weShuKSx0aGlzfXNldEZyb21Qb2ludHNBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuY29weSh0W2VdKSx0aGlzLmIuY29weSh0W25dKSx0aGlzLmMuY29weSh0W3NdKSx0aGlzfXNldEZyb21BdHRyaWJ1dGVBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLHRoaXMuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsbiksdGhpcy5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLmEuY29weSh0LmEpLHRoaXMuYi5jb3B5KHQuYiksdGhpcy5jLmNvcHkodC5jKSx0aGlzfWdldEFyZWEoKXtyZXR1cm4gaGUuc3ViVmVjdG9ycyh0aGlzLmMsdGhpcy5iKSxQZS5zdWJWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLGhlLmNyb3NzKFBlKS5sZW5ndGgoKSouNX1nZXRNaWRwb2ludCh0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLmFkZCh0aGlzLmMpLm11bHRpcGx5U2NhbGFyKDEvMyl9Z2V0Tm9ybWFsKHQpe3JldHVybiBldC5nZXROb3JtYWwodGhpcy5hLHRoaXMuYix0aGlzLmMsdCl9Z2V0UGxhbmUodCl7cmV0dXJuIHQuc2V0RnJvbUNvcGxhbmFyUG9pbnRzKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1nZXRCYXJ5Y29vcmQodCxlKXtyZXR1cm4gZXQuZ2V0QmFyeWNvb3JkKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSl9Z2V0SW50ZXJwb2xhdGlvbih0LGUsbixzLHIpe3JldHVybiBldC5nZXRJbnRlcnBvbGF0aW9uKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSxuLHMscil9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gZXQuY29udGFpbnNQb2ludCh0LHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1pc0Zyb250RmFjaW5nKHQpe3JldHVybiBldC5pc0Zyb250RmFjaW5nKHRoaXMuYSx0aGlzLmIsdGhpcy5jLHQpfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1RyaWFuZ2xlKHRoaXMpfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuYSxzPXRoaXMuYixyPXRoaXMuYztsZXQgbyxhO1ZuLnN1YlZlY3RvcnMocyxuKSxVbi5zdWJWZWN0b3JzKHIsbiksbW8uc3ViVmVjdG9ycyh0LG4pO2NvbnN0IGM9Vm4uZG90KG1vKSxsPVVuLmRvdChtbyk7aWYoYzw9MCYmbDw9MClyZXR1cm4gZS5jb3B5KG4pO2dvLnN1YlZlY3RvcnModCxzKTtjb25zdCBoPVZuLmRvdChnbyksdT1Vbi5kb3QoZ28pO2lmKGg+PTAmJnU8PWgpcmV0dXJuIGUuY29weShzKTtjb25zdCBmPWMqdS1oKmw7aWYoZjw9MCYmYz49MCYmaDw9MClyZXR1cm4gbz1jLyhjLWgpLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoVm4sbyk7eG8uc3ViVmVjdG9ycyh0LHIpO2NvbnN0IGQ9Vm4uZG90KHhvKSxwPVVuLmRvdCh4byk7aWYocD49MCYmZDw9cClyZXR1cm4gZS5jb3B5KHIpO2NvbnN0IHk9ZCpsLWMqcDtpZih5PD0wJiZsPj0wJiZwPD0wKXJldHVybiBhPWwvKGwtcCksZS5jb3B5KG4pLmFkZFNjYWxlZFZlY3RvcihVbixhKTtjb25zdCBtPWgqcC1kKnU7aWYobTw9MCYmdS1oPj0wJiZkLXA+PTApcmV0dXJuIE5jLnN1YlZlY3RvcnMocixzKSxhPSh1LWgpLyh1LWgrKGQtcCkpLGUuY29weShzKS5hZGRTY2FsZWRWZWN0b3IoTmMsYSk7Y29uc3QgZz0xLyhtK3krZik7cmV0dXJuIG89eSpnLGE9ZipnLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoVm4sbykuYWRkU2NhbGVkVmVjdG9yKFVuLGEpfWVxdWFscyh0KXtyZXR1cm4gdC5hLmVxdWFscyh0aGlzLmEpJiZ0LmIuZXF1YWxzKHRoaXMuYikmJnQuYy5lcXVhbHModGhpcy5jKX19Y29uc3QgUmM9e2FsaWNlYmx1ZToxNTc5MjM4MyxhbnRpcXVld2hpdGU6MTY0NDQzNzUsYXF1YTo2NTUzNSxhcXVhbWFyaW5lOjgzODg1NjQsYXp1cmU6MTU3OTQxNzUsYmVpZ2U6MTYxMTkyNjAsYmlzcXVlOjE2NzcwMjQ0LGJsYWNrOjAsYmxhbmNoZWRhbG1vbmQ6MTY3NzIwNDUsYmx1ZToyNTUsYmx1ZXZpb2xldDo5MDU1MjAyLGJyb3duOjEwODI0MjM0LGJ1cmx5d29vZDoxNDU5NjIzMSxjYWRldGJsdWU6NjI2NjUyOCxjaGFydHJldXNlOjgzODgzNTIsY2hvY29sYXRlOjEzNzg5NDcwLGNvcmFsOjE2NzQ0MjcyLGNvcm5mbG93ZXJibHVlOjY1OTE5ODEsY29ybnNpbGs6MTY3NzUzODgsY3JpbXNvbjoxNDQyMzEwMCxjeWFuOjY1NTM1LGRhcmtibHVlOjEzOSxkYXJrY3lhbjozNTcyMyxkYXJrZ29sZGVucm9kOjEyMDkyOTM5LGRhcmtncmF5OjExMTE5MDE3LGRhcmtncmVlbjoyNTYwMCxkYXJrZ3JleToxMTExOTAxNyxkYXJra2hha2k6MTI0MzMyNTksZGFya21hZ2VudGE6OTEwOTY0MyxkYXJrb2xpdmVncmVlbjo1NTk3OTk5LGRhcmtvcmFuZ2U6MTY3NDc1MjAsZGFya29yY2hpZDoxMDA0MDAxMixkYXJrcmVkOjkxMDk1MDQsZGFya3NhbG1vbjoxNTMwODQxMCxkYXJrc2VhZ3JlZW46OTQxOTkxOSxkYXJrc2xhdGVibHVlOjQ3MzQzNDcsZGFya3NsYXRlZ3JheTozMTAwNDk1LGRhcmtzbGF0ZWdyZXk6MzEwMDQ5NSxkYXJrdHVycXVvaXNlOjUyOTQ1LGRhcmt2aW9sZXQ6OTY5OTUzOSxkZWVwcGluazoxNjcxNjk0NyxkZWVwc2t5Ymx1ZTo0OTE1MSxkaW1ncmF5OjY5MDgyNjUsZGltZ3JleTo2OTA4MjY1LGRvZGdlcmJsdWU6MjAwMzE5OSxmaXJlYnJpY2s6MTE2NzQxNDYsZmxvcmFsd2hpdGU6MTY3NzU5MjAsZm9yZXN0Z3JlZW46MjI2Mzg0MixmdWNoc2lhOjE2NzExOTM1LGdhaW5zYm9ybzoxNDQ3NDQ2MCxnaG9zdHdoaXRlOjE2MzE2NjcxLGdvbGQ6MTY3NjY3MjAsZ29sZGVucm9kOjE0MzI5MTIwLGdyYXk6ODQyMTUwNCxncmVlbjozMjc2OCxncmVlbnllbGxvdzoxMTQwMzA1NSxncmV5Ojg0MjE1MDQsaG9uZXlkZXc6MTU3OTQxNjAsaG90cGluazoxNjczODc0MCxpbmRpYW5yZWQ6MTM0NTg1MjQsaW5kaWdvOjQ5MTUzMzAsaXZvcnk6MTY3NzcyMDAsa2hha2k6MTU3ODc2NjAsbGF2ZW5kZXI6MTUxMzI0MTAsbGF2ZW5kZXJibHVzaDoxNjc3MzM2NSxsYXduZ3JlZW46ODE5MDk3NixsZW1vbmNoaWZmb246MTY3NzU4ODUsbGlnaHRibHVlOjExMzkzMjU0LGxpZ2h0Y29yYWw6MTU3NjE1MzYsbGlnaHRjeWFuOjE0NzQ1NTk5LGxpZ2h0Z29sZGVucm9keWVsbG93OjE2NDQ4MjEwLGxpZ2h0Z3JheToxMzg4MjMyMyxsaWdodGdyZWVuOjk0OTgyNTYsbGlnaHRncmV5OjEzODgyMzIzLGxpZ2h0cGluazoxNjc1ODQ2NSxsaWdodHNhbG1vbjoxNjc1Mjc2MixsaWdodHNlYWdyZWVuOjIxNDI4OTAsbGlnaHRza3libHVlOjg5MDAzNDYsbGlnaHRzbGF0ZWdyYXk6NzgzMzc1MyxsaWdodHNsYXRlZ3JleTo3ODMzNzUzLGxpZ2h0c3RlZWxibHVlOjExNTg0NzM0LGxpZ2h0eWVsbG93OjE2Nzc3MTg0LGxpbWU6NjUyODAsbGltZWdyZWVuOjMzMjkzMzAsbGluZW46MTY0NDU2NzAsbWFnZW50YToxNjcxMTkzNSxtYXJvb246ODM4ODYwOCxtZWRpdW1hcXVhbWFyaW5lOjY3MzczMjIsbWVkaXVtYmx1ZToyMDUsbWVkaXVtb3JjaGlkOjEyMjExNjY3LG1lZGl1bXB1cnBsZTo5NjYyNjgzLG1lZGl1bXNlYWdyZWVuOjM5NzgwOTcsbWVkaXVtc2xhdGVibHVlOjgwODc3OTAsbWVkaXVtc3ByaW5nZ3JlZW46NjQxNTQsbWVkaXVtdHVycXVvaXNlOjQ3NzIzMDAsbWVkaXVtdmlvbGV0cmVkOjEzMDQ3MTczLG1pZG5pZ2h0Ymx1ZToxNjQ0OTEyLG1pbnRjcmVhbToxNjEyMTg1MCxtaXN0eXJvc2U6MTY3NzAyNzMsbW9jY2FzaW46MTY3NzAyMjksbmF2YWpvd2hpdGU6MTY3Njg2ODUsbmF2eToxMjgsb2xkbGFjZToxNjY0MzU1OCxvbGl2ZTo4NDIxMzc2LG9saXZlZHJhYjo3MDQ4NzM5LG9yYW5nZToxNjc1MzkyMCxvcmFuZ2VyZWQ6MTY3MjkzNDQsb3JjaGlkOjE0MzE1NzM0LHBhbGVnb2xkZW5yb2Q6MTU2NTcxMzAscGFsZWdyZWVuOjEwMDI1ODgwLHBhbGV0dXJxdW9pc2U6MTE1Mjk5NjYscGFsZXZpb2xldHJlZDoxNDM4MTIwMyxwYXBheWF3aGlwOjE2NzczMDc3LHBlYWNocHVmZjoxNjc2NzY3MyxwZXJ1OjEzNDY4OTkxLHBpbms6MTY3NjEwMzUscGx1bToxNDUyNDYzNyxwb3dkZXJibHVlOjExNTkxOTEwLHB1cnBsZTo4Mzg4NzM2LHJlYmVjY2FwdXJwbGU6NjY5Nzg4MSxyZWQ6MTY3MTE2ODAscm9zeWJyb3duOjEyMzU3NTE5LHJveWFsYmx1ZTo0Mjg2OTQ1LHNhZGRsZWJyb3duOjkxMjcxODcsc2FsbW9uOjE2NDE2ODgyLHNhbmR5YnJvd246MTYwMzI4NjQsc2VhZ3JlZW46MzA1MDMyNyxzZWFzaGVsbDoxNjc3NDYzOCxzaWVubmE6MTA1MDY3OTcsc2lsdmVyOjEyNjMyMjU2LHNreWJsdWU6ODkwMDMzMSxzbGF0ZWJsdWU6Njk3MDA2MSxzbGF0ZWdyYXk6NzM3Mjk0NCxzbGF0ZWdyZXk6NzM3Mjk0NCxzbm93OjE2Nzc1OTMwLHNwcmluZ2dyZWVuOjY1NDA3LHN0ZWVsYmx1ZTo0NjIwOTgwLHRhbjoxMzgwODc4MCx0ZWFsOjMyODk2LHRoaXN0bGU6MTQyMDQ4ODgsdG9tYXRvOjE2NzM3MDk1LHR1cnF1b2lzZTo0MjUxODU2LHZpb2xldDoxNTYzMTA4Nix3aGVhdDoxNjExMzMzMSx3aGl0ZToxNjc3NzIxNSx3aGl0ZXNtb2tlOjE2MTE5Mjg1LHllbGxvdzoxNjc3Njk2MCx5ZWxsb3dncmVlbjoxMDE0NTA3NH0sUWU9e2g6MCxzOjAsbDowfSxwcz17aDowLHM6MCxsOjB9O2Z1bmN0aW9uIEFvKGksdCxlKXtyZXR1cm4gZTwwJiYoZSs9MSksZT4xJiYoZS09MSksZTwxLzY/aSsodC1pKSo2KmU6ZTwxLzI/dDplPDIvMz9pKyh0LWkpKjYqKDIvMy1lKTppfWxldCB5cz1jbGFzc3tjb25zdHJ1Y3Rvcih0LGUsbil7cmV0dXJuIHRoaXMuaXNDb2xvcj0hMCx0aGlzLnI9MSx0aGlzLmc9MSx0aGlzLmI9MSx0aGlzLnNldCh0LGUsbil9c2V0KHQsZSxuKXtpZihlPT09dm9pZCAwJiZuPT09dm9pZCAwKXtjb25zdCBzPXQ7cyYmcy5pc0NvbG9yP3RoaXMuY29weShzKTp0eXBlb2Ygcz09Im51bWJlciI/dGhpcy5zZXRIZXgocyk6dHlwZW9mIHM9PSJzdHJpbmciJiZ0aGlzLnNldFN0eWxlKHMpfWVsc2UgdGhpcy5zZXRSR0IodCxlLG4pO3JldHVybiB0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy5yPXQsdGhpcy5nPXQsdGhpcy5iPXQsdGhpc31zZXRIZXgodCxlPW9lKXtyZXR1cm4gdD1NYXRoLmZsb29yKHQpLHRoaXMucj0odD4+MTYmMjU1KS8yNTUsdGhpcy5nPSh0Pj44JjI1NSkvMjU1LHRoaXMuYj0odCYyNTUpLzI1NSxhZS5jb2xvclNwYWNlVG9Xb3JraW5nKHRoaXMsZSksdGhpc31zZXRSR0IodCxlLG4scz1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHRoaXMucj10LHRoaXMuZz1lLHRoaXMuYj1uLGFlLmNvbG9yU3BhY2VUb1dvcmtpbmcodGhpcyxzKSx0aGlzfXNldEhTTCh0LGUsbixzPWFlLndvcmtpbmdDb2xvclNwYWNlKXtpZih0PWp1KHQsMSksZT1aKGUsMCwxKSxuPVoobiwwLDEpLGU9PT0wKXRoaXMucj10aGlzLmc9dGhpcy5iPW47ZWxzZXtjb25zdCByPW48PS41P24qKDErZSk6bitlLW4qZSxvPTIqbi1yO3RoaXMucj1BbyhvLHIsdCsxLzMpLHRoaXMuZz1BbyhvLHIsdCksdGhpcy5iPUFvKG8scix0LTEvMyl9cmV0dXJuIGFlLmNvbG9yU3BhY2VUb1dvcmtpbmcodGhpcyxzKSx0aGlzfXNldFN0eWxlKHQsZT1vZSl7ZnVuY3Rpb24gbihyKXtyIT09dm9pZCAwJiZwYXJzZUZsb2F0KHIpPDEmJmNvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IEFscGhhIGNvbXBvbmVudCBvZiAiK3QrIiB3aWxsIGJlIGlnbm9yZWQuIil9bGV0IHM7aWYocz0vXihcdyspXCgoW15cKV0qKVwpLy5leGVjKHQpKXtsZXQgcjtjb25zdCBvPXNbMV0sYT1zWzJdO3N3aXRjaChvKXtjYXNlInJnYiI6Y2FzZSJyZ2JhIjppZihyPS9eXHMqKFxkKylccyosXHMqKFxkKylccyosXHMqKFxkKylccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRSR0IoTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMV0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMl0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbM10sMTApKS8yNTUsZSk7aWYocj0vXlxzKihcZCspXCVccyosXHMqKFxkKylcJVxzKixccyooXGQrKVwlXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0UkdCKE1hdGgubWluKDEwMCxwYXJzZUludChyWzFdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzJdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzNdLDEwKSkvMTAwLGUpO2JyZWFrO2Nhc2UiaHNsIjpjYXNlImhzbGEiOmlmKHI9L15ccyooXGQqXC4/XGQrKVxzKixccyooXGQqXC4/XGQrKVwlXHMqLFxzKihcZCpcLj9cZCspXCVccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRIU0wocGFyc2VGbG9hdChyWzFdKS8zNjAscGFyc2VGbG9hdChyWzJdKS8xMDAscGFyc2VGbG9hdChyWzNdKS8xMDAsZSk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkNvbG9yOiBVbmtub3duIGNvbG9yIG1vZGVsICIrdCl9fWVsc2UgaWYocz0vXlwjKFtBLUZhLWZcZF0rKSQvLmV4ZWModCkpe2NvbnN0IHI9c1sxXSxvPXIubGVuZ3RoO2lmKG89PT0zKXJldHVybiB0aGlzLnNldFJHQihwYXJzZUludChyLmNoYXJBdCgwKSwxNikvMTUscGFyc2VJbnQoci5jaGFyQXQoMSksMTYpLzE1LHBhcnNlSW50KHIuY2hhckF0KDIpLDE2KS8xNSxlKTtpZihvPT09NilyZXR1cm4gdGhpcy5zZXRIZXgocGFyc2VJbnQociwxNiksZSk7Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogSW52YWxpZCBoZXggY29sb3IgIit0KX1lbHNlIGlmKHQmJnQubGVuZ3RoPjApcmV0dXJuIHRoaXMuc2V0Q29sb3JOYW1lKHQsZSk7cmV0dXJuIHRoaXN9c2V0Q29sb3JOYW1lKHQsZT1vZSl7Y29uc3Qgbj1SY1t0LnRvTG93ZXJDYXNlKCldO3JldHVybiBuIT09dm9pZCAwP3RoaXMuc2V0SGV4KG4sZSk6Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogVW5rbm93biBjb2xvciAiK3QpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5yLHRoaXMuZyx0aGlzLmIpfWNvcHkodCl7cmV0dXJuIHRoaXMucj10LnIsdGhpcy5nPXQuZyx0aGlzLmI9dC5iLHRoaXN9Y29weVNSR0JUb0xpbmVhcih0KXtyZXR1cm4gdGhpcy5yPV9lKHQuciksdGhpcy5nPV9lKHQuZyksdGhpcy5iPV9lKHQuYiksdGhpc31jb3B5TGluZWFyVG9TUkdCKHQpe3JldHVybiB0aGlzLnI9SW4odC5yKSx0aGlzLmc9SW4odC5nKSx0aGlzLmI9SW4odC5iKSx0aGlzfWNvbnZlcnRTUkdCVG9MaW5lYXIoKXtyZXR1cm4gdGhpcy5jb3B5U1JHQlRvTGluZWFyKHRoaXMpLHRoaXN9Y29udmVydExpbmVhclRvU1JHQigpe3JldHVybiB0aGlzLmNvcHlMaW5lYXJUb1NSR0IodGhpcyksdGhpc31nZXRIZXgodD1vZSl7cmV0dXJuIGFlLndvcmtpbmdUb0NvbG9yU3BhY2UoU3QuY29weSh0aGlzKSx0KSxNYXRoLnJvdW5kKFooU3QucioyNTUsMCwyNTUpKSo2NTUzNitNYXRoLnJvdW5kKFooU3QuZyoyNTUsMCwyNTUpKSoyNTYrTWF0aC5yb3VuZChaKFN0LmIqMjU1LDAsMjU1KSl9Z2V0SGV4U3RyaW5nKHQ9b2Upe3JldHVybigiMDAwMDAwIit0aGlzLmdldEhleCh0KS50b1N0cmluZygxNikpLnNsaWNlKC02KX1nZXRIU0wodCxlPWFlLndvcmtpbmdDb2xvclNwYWNlKXthZS53b3JraW5nVG9Db2xvclNwYWNlKFN0LmNvcHkodGhpcyksZSk7Y29uc3Qgbj1TdC5yLHM9U3QuZyxyPVN0LmIsbz1NYXRoLm1heChuLHMsciksYT1NYXRoLm1pbihuLHMscik7bGV0IGMsbDtjb25zdCBoPShhK28pLzI7aWYoYT09PW8pYz0wLGw9MDtlbHNle2NvbnN0IHU9by1hO3N3aXRjaChsPWg8PS41P3UvKG8rYSk6dS8oMi1vLWEpLG8pe2Nhc2UgbjpjPShzLXIpL3UrKHM8cj82OjApO2JyZWFrO2Nhc2UgczpjPShyLW4pL3UrMjticmVhaztjYXNlIHI6Yz0obi1zKS91KzQ7YnJlYWt9Yy89Nn1yZXR1cm4gdC5oPWMsdC5zPWwsdC5sPWgsdH1nZXRSR0IodCxlPWFlLndvcmtpbmdDb2xvclNwYWNlKXtyZXR1cm4gYWUud29ya2luZ1RvQ29sb3JTcGFjZShTdC5jb3B5KHRoaXMpLGUpLHQucj1TdC5yLHQuZz1TdC5nLHQuYj1TdC5iLHR9Z2V0U3R5bGUodD1vZSl7YWUud29ya2luZ1RvQ29sb3JTcGFjZShTdC5jb3B5KHRoaXMpLHQpO2NvbnN0IGU9U3QucixuPVN0Lmcscz1TdC5iO3JldHVybiB0IT09b2U/YGNvbG9yKCR7dH0gJHtlLnRvRml4ZWQoMyl9ICR7bi50b0ZpeGVkKDMpfSAke3MudG9GaXhlZCgzKX0pYDpgcmdiKCR7TWF0aC5yb3VuZChlKjI1NSl9LCR7TWF0aC5yb3VuZChuKjI1NSl9LCR7TWF0aC5yb3VuZChzKjI1NSl9KWB9b2Zmc2V0SFNMKHQsZSxuKXtyZXR1cm4gdGhpcy5nZXRIU0woUWUpLHRoaXMuc2V0SFNMKFFlLmgrdCxRZS5zK2UsUWUubCtuKX1hZGQodCl7cmV0dXJuIHRoaXMucis9dC5yLHRoaXMuZys9dC5nLHRoaXMuYis9dC5iLHRoaXN9YWRkQ29sb3JzKHQsZSl7cmV0dXJuIHRoaXMucj10LnIrZS5yLHRoaXMuZz10LmcrZS5nLHRoaXMuYj10LmIrZS5iLHRoaXN9YWRkU2NhbGFyKHQpe3JldHVybiB0aGlzLnIrPXQsdGhpcy5nKz10LHRoaXMuYis9dCx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy5yPU1hdGgubWF4KDAsdGhpcy5yLXQuciksdGhpcy5nPU1hdGgubWF4KDAsdGhpcy5nLXQuZyksdGhpcy5iPU1hdGgubWF4KDAsdGhpcy5iLXQuYiksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5yKj10LnIsdGhpcy5nKj10LmcsdGhpcy5iKj10LmIsdGhpc31tdWx0aXBseVNjYWxhcih0KXtyZXR1cm4gdGhpcy5yKj10LHRoaXMuZyo9dCx0aGlzLmIqPXQsdGhpc31sZXJwKHQsZSl7cmV0dXJuIHRoaXMucis9KHQuci10aGlzLnIpKmUsdGhpcy5nKz0odC5nLXRoaXMuZykqZSx0aGlzLmIrPSh0LmItdGhpcy5iKSplLHRoaXN9bGVycENvbG9ycyh0LGUsbil7cmV0dXJuIHRoaXMucj10LnIrKGUuci10LnIpKm4sdGhpcy5nPXQuZysoZS5nLXQuZykqbix0aGlzLmI9dC5iKyhlLmItdC5iKSpuLHRoaXN9bGVycEhTTCh0LGUpe3RoaXMuZ2V0SFNMKFFlKSx0LmdldEhTTChwcyk7Y29uc3Qgbj1lbyhRZS5oLHBzLmgsZSkscz1lbyhRZS5zLHBzLnMsZSkscj1lbyhRZS5sLHBzLmwsZSk7cmV0dXJuIHRoaXMuc2V0SFNMKG4scyxyKSx0aGlzfXNldEZyb21WZWN0b3IzKHQpe3JldHVybiB0aGlzLnI9dC54LHRoaXMuZz10LnksdGhpcy5iPXQueix0aGlzfWFwcGx5TWF0cml4Myh0KXtjb25zdCBlPXRoaXMucixuPXRoaXMuZyxzPXRoaXMuYixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMucj1yWzBdKmUrclszXSpuK3JbNl0qcyx0aGlzLmc9clsxXSplK3JbNF0qbityWzddKnMsdGhpcy5iPXJbMl0qZStyWzVdKm4rcls4XSpzLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0LnI9PT10aGlzLnImJnQuZz09PXRoaXMuZyYmdC5iPT09dGhpcy5ifWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMucj10W2VdLHRoaXMuZz10W2UrMV0sdGhpcy5iPXRbZSsyXSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMucix0W2UrMV09dGhpcy5nLHRbZSsyXT10aGlzLmIsdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMucj10LmdldFgoZSksdGhpcy5nPXQuZ2V0WShlKSx0aGlzLmI9dC5nZXRaKGUpLHRoaXN9dG9KU09OKCl7cmV0dXJuIHRoaXMuZ2V0SGV4KCl9KltTeW1ib2wuaXRlcmF0b3JdKCl7eWllbGQgdGhpcy5yLHlpZWxkIHRoaXMuZyx5aWVsZCB0aGlzLmJ9fTtjb25zdCBTdD1uZXcgeXM7eXMuTkFNRVM9UmM7bGV0IGRmPTA7Y2xhc3MgcGYgZXh0ZW5kcyBvc3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy5pc01hdGVyaWFsPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOmRmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy50eXBlPSJNYXRlcmlhbCIsdGhpcy5ibGVuZGluZz0xLHRoaXMuc2lkZT0wLHRoaXMudmVydGV4Q29sb3JzPSExLHRoaXMub3BhY2l0eT0xLHRoaXMudHJhbnNwYXJlbnQ9ITEsdGhpcy5hbHBoYUhhc2g9ITEsdGhpcy5ibGVuZFNyYz0yMDQsdGhpcy5ibGVuZERzdD0yMDUsdGhpcy5ibGVuZEVxdWF0aW9uPTEwMCx0aGlzLmJsZW5kU3JjQWxwaGE9bnVsbCx0aGlzLmJsZW5kRHN0QWxwaGE9bnVsbCx0aGlzLmJsZW5kRXF1YXRpb25BbHBoYT1udWxsLHRoaXMuYmxlbmRDb2xvcj1uZXcgeXMoMCwwLDApLHRoaXMuYmxlbmRBbHBoYT0wLHRoaXMuZGVwdGhGdW5jPTMsdGhpcy5kZXB0aFRlc3Q9ITAsdGhpcy5kZXB0aFdyaXRlPSEwLHRoaXMuc3RlbmNpbFdyaXRlTWFzaz0yNTUsdGhpcy5zdGVuY2lsRnVuYz01MTksdGhpcy5zdGVuY2lsUmVmPTAsdGhpcy5zdGVuY2lsRnVuY01hc2s9MjU1LHRoaXMuc3RlbmNpbEZhaWw9NzY4MCx0aGlzLnN0ZW5jaWxaRmFpbD03NjgwLHRoaXMuc3RlbmNpbFpQYXNzPTc2ODAsdGhpcy5zdGVuY2lsV3JpdGU9ITEsdGhpcy5jbGlwcGluZ1BsYW5lcz1udWxsLHRoaXMuY2xpcEludGVyc2VjdGlvbj0hMSx0aGlzLmNsaXBTaGFkb3dzPSExLHRoaXMuc2hhZG93U2lkZT1udWxsLHRoaXMuY29sb3JXcml0ZT0hMCx0aGlzLnByZWNpc2lvbj1udWxsLHRoaXMucG9seWdvbk9mZnNldD0hMSx0aGlzLnBvbHlnb25PZmZzZXRGYWN0b3I9MCx0aGlzLnBvbHlnb25PZmZzZXRVbml0cz0wLHRoaXMuZGl0aGVyaW5nPSExLHRoaXMuYWxwaGFUb0NvdmVyYWdlPSExLHRoaXMucHJlbXVsdGlwbGllZEFscGhhPSExLHRoaXMuZm9yY2VTaW5nbGVQYXNzPSExLHRoaXMuYWxsb3dPdmVycmlkZT0hMCx0aGlzLnZpc2libGU9ITAsdGhpcy50b25lTWFwcGVkPSEwLHRoaXMudXNlckRhdGE9e30sdGhpcy52ZXJzaW9uPTAsdGhpcy5fYWxwaGFUZXN0PTB9Z2V0IGFscGhhVGVzdCgpe3JldHVybiB0aGlzLl9hbHBoYVRlc3R9c2V0IGFscGhhVGVzdCh0KXt0aGlzLl9hbHBoYVRlc3Q+MCE9dD4wJiZ0aGlzLnZlcnNpb24rKyx0aGlzLl9hbHBoYVRlc3Q9dH1vbkJlZm9yZVJlbmRlcigpe31vbkJlZm9yZUNvbXBpbGUoKXt9Y3VzdG9tUHJvZ3JhbUNhY2hlS2V5KCl7cmV0dXJuIHRoaXMub25CZWZvcmVDb21waWxlLnRvU3RyaW5nKCl9c2V0VmFsdWVzKHQpe2lmKHQhPT12b2lkIDApZm9yKGNvbnN0IGUgaW4gdCl7Y29uc3Qgbj10W2VdO2lmKG49PT12b2lkIDApe2NvbnNvbGUud2FybihgVEhSRUUuTWF0ZXJpYWw6IHBhcmFtZXRlciAnJHtlfScgaGFzIHZhbHVlIG9mIHVuZGVmaW5lZC5gKTtjb250aW51ZX1jb25zdCBzPXRoaXNbZV07aWYocz09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5NYXRlcmlhbDogJyR7ZX0nIGlzIG5vdCBhIHByb3BlcnR5IG9mIFRIUkVFLiR7dGhpcy50eXBlfS5gKTtjb250aW51ZX1zJiZzLmlzQ29sb3I/cy5zZXQobik6cyYmcy5pc1ZlY3RvcjMmJm4mJm4uaXNWZWN0b3IzP3MuY29weShuKTp0aGlzW2VdPW59fXRvSlNPTih0KXtjb25zdCBlPXQ9PT12b2lkIDB8fHR5cGVvZiB0PT0ic3RyaW5nIjtlJiYodD17dGV4dHVyZXM6e30saW1hZ2VzOnt9fSk7Y29uc3Qgbj17bWV0YWRhdGE6e3ZlcnNpb246NC43LHR5cGU6Ik1hdGVyaWFsIixnZW5lcmF0b3I6Ik1hdGVyaWFsLnRvSlNPTiJ9fTtuLnV1aWQ9dGhpcy51dWlkLG4udHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJihuLm5hbWU9dGhpcy5uYW1lKSx0aGlzLmNvbG9yJiZ0aGlzLmNvbG9yLmlzQ29sb3ImJihuLmNvbG9yPXRoaXMuY29sb3IuZ2V0SGV4KCkpLHRoaXMucm91Z2huZXNzIT09dm9pZCAwJiYobi5yb3VnaG5lc3M9dGhpcy5yb3VnaG5lc3MpLHRoaXMubWV0YWxuZXNzIT09dm9pZCAwJiYobi5tZXRhbG5lc3M9dGhpcy5tZXRhbG5lc3MpLHRoaXMuc2hlZW4hPT12b2lkIDAmJihuLnNoZWVuPXRoaXMuc2hlZW4pLHRoaXMuc2hlZW5Db2xvciYmdGhpcy5zaGVlbkNvbG9yLmlzQ29sb3ImJihuLnNoZWVuQ29sb3I9dGhpcy5zaGVlbkNvbG9yLmdldEhleCgpKSx0aGlzLnNoZWVuUm91Z2huZXNzIT09dm9pZCAwJiYobi5zaGVlblJvdWdobmVzcz10aGlzLnNoZWVuUm91Z2huZXNzKSx0aGlzLmVtaXNzaXZlJiZ0aGlzLmVtaXNzaXZlLmlzQ29sb3ImJihuLmVtaXNzaXZlPXRoaXMuZW1pc3NpdmUuZ2V0SGV4KCkpLHRoaXMuZW1pc3NpdmVJbnRlbnNpdHkhPT12b2lkIDAmJnRoaXMuZW1pc3NpdmVJbnRlbnNpdHkhPT0xJiYobi5lbWlzc2l2ZUludGVuc2l0eT10aGlzLmVtaXNzaXZlSW50ZW5zaXR5KSx0aGlzLnNwZWN1bGFyJiZ0aGlzLnNwZWN1bGFyLmlzQ29sb3ImJihuLnNwZWN1bGFyPXRoaXMuc3BlY3VsYXIuZ2V0SGV4KCkpLHRoaXMuc3BlY3VsYXJJbnRlbnNpdHkhPT12b2lkIDAmJihuLnNwZWN1bGFySW50ZW5zaXR5PXRoaXMuc3BlY3VsYXJJbnRlbnNpdHkpLHRoaXMuc3BlY3VsYXJDb2xvciYmdGhpcy5zcGVjdWxhckNvbG9yLmlzQ29sb3ImJihuLnNwZWN1bGFyQ29sb3I9dGhpcy5zcGVjdWxhckNvbG9yLmdldEhleCgpKSx0aGlzLnNoaW5pbmVzcyE9PXZvaWQgMCYmKG4uc2hpbmluZXNzPXRoaXMuc2hpbmluZXNzKSx0aGlzLmNsZWFyY29hdCE9PXZvaWQgMCYmKG4uY2xlYXJjb2F0PXRoaXMuY2xlYXJjb2F0KSx0aGlzLmNsZWFyY29hdFJvdWdobmVzcyE9PXZvaWQgMCYmKG4uY2xlYXJjb2F0Um91Z2huZXNzPXRoaXMuY2xlYXJjb2F0Um91Z2huZXNzKSx0aGlzLmNsZWFyY29hdE1hcCYmdGhpcy5jbGVhcmNvYXRNYXAuaXNUZXh0dXJlJiYobi5jbGVhcmNvYXRNYXA9dGhpcy5jbGVhcmNvYXRNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuY2xlYXJjb2F0Um91Z2huZXNzTWFwJiZ0aGlzLmNsZWFyY29hdFJvdWdobmVzc01hcC5pc1RleHR1cmUmJihuLmNsZWFyY29hdFJvdWdobmVzc01hcD10aGlzLmNsZWFyY29hdFJvdWdobmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5jbGVhcmNvYXROb3JtYWxNYXAmJnRoaXMuY2xlYXJjb2F0Tm9ybWFsTWFwLmlzVGV4dHVyZSYmKG4uY2xlYXJjb2F0Tm9ybWFsTWFwPXRoaXMuY2xlYXJjb2F0Tm9ybWFsTWFwLnRvSlNPTih0KS51dWlkLG4uY2xlYXJjb2F0Tm9ybWFsU2NhbGU9dGhpcy5jbGVhcmNvYXROb3JtYWxTY2FsZS50b0FycmF5KCkpLHRoaXMuZGlzcGVyc2lvbiE9PXZvaWQgMCYmKG4uZGlzcGVyc2lvbj10aGlzLmRpc3BlcnNpb24pLHRoaXMuaXJpZGVzY2VuY2UhPT12b2lkIDAmJihuLmlyaWRlc2NlbmNlPXRoaXMuaXJpZGVzY2VuY2UpLHRoaXMuaXJpZGVzY2VuY2VJT1IhPT12b2lkIDAmJihuLmlyaWRlc2NlbmNlSU9SPXRoaXMuaXJpZGVzY2VuY2VJT1IpLHRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NSYW5nZSE9PXZvaWQgMCYmKG4uaXJpZGVzY2VuY2VUaGlja25lc3NSYW5nZT10aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzUmFuZ2UpLHRoaXMuaXJpZGVzY2VuY2VNYXAmJnRoaXMuaXJpZGVzY2VuY2VNYXAuaXNUZXh0dXJlJiYobi5pcmlkZXNjZW5jZU1hcD10aGlzLmlyaWRlc2NlbmNlTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwJiZ0aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwLmlzVGV4dHVyZSYmKG4uaXJpZGVzY2VuY2VUaGlja25lc3NNYXA9dGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5hbmlzb3Ryb3B5IT09dm9pZCAwJiYobi5hbmlzb3Ryb3B5PXRoaXMuYW5pc290cm9weSksdGhpcy5hbmlzb3Ryb3B5Um90YXRpb24hPT12b2lkIDAmJihuLmFuaXNvdHJvcHlSb3RhdGlvbj10aGlzLmFuaXNvdHJvcHlSb3RhdGlvbiksdGhpcy5hbmlzb3Ryb3B5TWFwJiZ0aGlzLmFuaXNvdHJvcHlNYXAuaXNUZXh0dXJlJiYobi5hbmlzb3Ryb3B5TWFwPXRoaXMuYW5pc290cm9weU1hcC50b0pTT04odCkudXVpZCksdGhpcy5tYXAmJnRoaXMubWFwLmlzVGV4dHVyZSYmKG4ubWFwPXRoaXMubWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLm1hdGNhcCYmdGhpcy5tYXRjYXAuaXNUZXh0dXJlJiYobi5tYXRjYXA9dGhpcy5tYXRjYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuYWxwaGFNYXAmJnRoaXMuYWxwaGFNYXAuaXNUZXh0dXJlJiYobi5hbHBoYU1hcD10aGlzLmFscGhhTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmxpZ2h0TWFwJiZ0aGlzLmxpZ2h0TWFwLmlzVGV4dHVyZSYmKG4ubGlnaHRNYXA9dGhpcy5saWdodE1hcC50b0pTT04odCkudXVpZCxuLmxpZ2h0TWFwSW50ZW5zaXR5PXRoaXMubGlnaHRNYXBJbnRlbnNpdHkpLHRoaXMuYW9NYXAmJnRoaXMuYW9NYXAuaXNUZXh0dXJlJiYobi5hb01hcD10aGlzLmFvTWFwLnRvSlNPTih0KS51dWlkLG4uYW9NYXBJbnRlbnNpdHk9dGhpcy5hb01hcEludGVuc2l0eSksdGhpcy5idW1wTWFwJiZ0aGlzLmJ1bXBNYXAuaXNUZXh0dXJlJiYobi5idW1wTWFwPXRoaXMuYnVtcE1hcC50b0pTT04odCkudXVpZCxuLmJ1bXBTY2FsZT10aGlzLmJ1bXBTY2FsZSksdGhpcy5ub3JtYWxNYXAmJnRoaXMubm9ybWFsTWFwLmlzVGV4dHVyZSYmKG4ubm9ybWFsTWFwPXRoaXMubm9ybWFsTWFwLnRvSlNPTih0KS51dWlkLG4ubm9ybWFsTWFwVHlwZT10aGlzLm5vcm1hbE1hcFR5cGUsbi5ub3JtYWxTY2FsZT10aGlzLm5vcm1hbFNjYWxlLnRvQXJyYXkoKSksdGhpcy5kaXNwbGFjZW1lbnRNYXAmJnRoaXMuZGlzcGxhY2VtZW50TWFwLmlzVGV4dHVyZSYmKG4uZGlzcGxhY2VtZW50TWFwPXRoaXMuZGlzcGxhY2VtZW50TWFwLnRvSlNPTih0KS51dWlkLG4uZGlzcGxhY2VtZW50U2NhbGU9dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSxuLmRpc3BsYWNlbWVudEJpYXM9dGhpcy5kaXNwbGFjZW1lbnRCaWFzKSx0aGlzLnJvdWdobmVzc01hcCYmdGhpcy5yb3VnaG5lc3NNYXAuaXNUZXh0dXJlJiYobi5yb3VnaG5lc3NNYXA9dGhpcy5yb3VnaG5lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubWV0YWxuZXNzTWFwJiZ0aGlzLm1ldGFsbmVzc01hcC5pc1RleHR1cmUmJihuLm1ldGFsbmVzc01hcD10aGlzLm1ldGFsbmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5lbWlzc2l2ZU1hcCYmdGhpcy5lbWlzc2l2ZU1hcC5pc1RleHR1cmUmJihuLmVtaXNzaXZlTWFwPXRoaXMuZW1pc3NpdmVNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuc3BlY3VsYXJNYXAmJnRoaXMuc3BlY3VsYXJNYXAuaXNUZXh0dXJlJiYobi5zcGVjdWxhck1hcD10aGlzLnNwZWN1bGFyTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnNwZWN1bGFySW50ZW5zaXR5TWFwJiZ0aGlzLnNwZWN1bGFySW50ZW5zaXR5TWFwLmlzVGV4dHVyZSYmKG4uc3BlY3VsYXJJbnRlbnNpdHlNYXA9dGhpcy5zcGVjdWxhckludGVuc2l0eU1hcC50b0pTT04odCkudXVpZCksdGhpcy5zcGVjdWxhckNvbG9yTWFwJiZ0aGlzLnNwZWN1bGFyQ29sb3JNYXAuaXNUZXh0dXJlJiYobi5zcGVjdWxhckNvbG9yTWFwPXRoaXMuc3BlY3VsYXJDb2xvck1hcC50b0pTT04odCkudXVpZCksdGhpcy5lbnZNYXAmJnRoaXMuZW52TWFwLmlzVGV4dHVyZSYmKG4uZW52TWFwPXRoaXMuZW52TWFwLnRvSlNPTih0KS51dWlkLHRoaXMuY29tYmluZSE9PXZvaWQgMCYmKG4uY29tYmluZT10aGlzLmNvbWJpbmUpKSx0aGlzLmVudk1hcFJvdGF0aW9uIT09dm9pZCAwJiYobi5lbnZNYXBSb3RhdGlvbj10aGlzLmVudk1hcFJvdGF0aW9uLnRvQXJyYXkoKSksdGhpcy5lbnZNYXBJbnRlbnNpdHkhPT12b2lkIDAmJihuLmVudk1hcEludGVuc2l0eT10aGlzLmVudk1hcEludGVuc2l0eSksdGhpcy5yZWZsZWN0aXZpdHkhPT12b2lkIDAmJihuLnJlZmxlY3Rpdml0eT10aGlzLnJlZmxlY3Rpdml0eSksdGhpcy5yZWZyYWN0aW9uUmF0aW8hPT12b2lkIDAmJihuLnJlZnJhY3Rpb25SYXRpbz10aGlzLnJlZnJhY3Rpb25SYXRpbyksdGhpcy5ncmFkaWVudE1hcCYmdGhpcy5ncmFkaWVudE1hcC5pc1RleHR1cmUmJihuLmdyYWRpZW50TWFwPXRoaXMuZ3JhZGllbnRNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMudHJhbnNtaXNzaW9uIT09dm9pZCAwJiYobi50cmFuc21pc3Npb249dGhpcy50cmFuc21pc3Npb24pLHRoaXMudHJhbnNtaXNzaW9uTWFwJiZ0aGlzLnRyYW5zbWlzc2lvbk1hcC5pc1RleHR1cmUmJihuLnRyYW5zbWlzc2lvbk1hcD10aGlzLnRyYW5zbWlzc2lvbk1hcC50b0pTT04odCkudXVpZCksdGhpcy50aGlja25lc3MhPT12b2lkIDAmJihuLnRoaWNrbmVzcz10aGlzLnRoaWNrbmVzcyksdGhpcy50aGlja25lc3NNYXAmJnRoaXMudGhpY2tuZXNzTWFwLmlzVGV4dHVyZSYmKG4udGhpY2tuZXNzTWFwPXRoaXMudGhpY2tuZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmF0dGVudWF0aW9uRGlzdGFuY2UhPT12b2lkIDAmJnRoaXMuYXR0ZW51YXRpb25EaXN0YW5jZSE9PTEvMCYmKG4uYXR0ZW51YXRpb25EaXN0YW5jZT10aGlzLmF0dGVudWF0aW9uRGlzdGFuY2UpLHRoaXMuYXR0ZW51YXRpb25Db2xvciE9PXZvaWQgMCYmKG4uYXR0ZW51YXRpb25Db2xvcj10aGlzLmF0dGVudWF0aW9uQ29sb3IuZ2V0SGV4KCkpLHRoaXMuc2l6ZSE9PXZvaWQgMCYmKG4uc2l6ZT10aGlzLnNpemUpLHRoaXMuc2hhZG93U2lkZSE9PW51bGwmJihuLnNoYWRvd1NpZGU9dGhpcy5zaGFkb3dTaWRlKSx0aGlzLnNpemVBdHRlbnVhdGlvbiE9PXZvaWQgMCYmKG4uc2l6ZUF0dGVudWF0aW9uPXRoaXMuc2l6ZUF0dGVudWF0aW9uKSx0aGlzLmJsZW5kaW5nIT09MSYmKG4uYmxlbmRpbmc9dGhpcy5ibGVuZGluZyksdGhpcy5zaWRlIT09MCYmKG4uc2lkZT10aGlzLnNpZGUpLHRoaXMudmVydGV4Q29sb3JzPT09ITAmJihuLnZlcnRleENvbG9ycz0hMCksdGhpcy5vcGFjaXR5PDEmJihuLm9wYWNpdHk9dGhpcy5vcGFjaXR5KSx0aGlzLnRyYW5zcGFyZW50PT09ITAmJihuLnRyYW5zcGFyZW50PSEwKSx0aGlzLmJsZW5kU3JjIT09MjA0JiYobi5ibGVuZFNyYz10aGlzLmJsZW5kU3JjKSx0aGlzLmJsZW5kRHN0IT09MjA1JiYobi5ibGVuZERzdD10aGlzLmJsZW5kRHN0KSx0aGlzLmJsZW5kRXF1YXRpb24hPT0xMDAmJihuLmJsZW5kRXF1YXRpb249dGhpcy5ibGVuZEVxdWF0aW9uKSx0aGlzLmJsZW5kU3JjQWxwaGEhPT1udWxsJiYobi5ibGVuZFNyY0FscGhhPXRoaXMuYmxlbmRTcmNBbHBoYSksdGhpcy5ibGVuZERzdEFscGhhIT09bnVsbCYmKG4uYmxlbmREc3RBbHBoYT10aGlzLmJsZW5kRHN0QWxwaGEpLHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhIT09bnVsbCYmKG4uYmxlbmRFcXVhdGlvbkFscGhhPXRoaXMuYmxlbmRFcXVhdGlvbkFscGhhKSx0aGlzLmJsZW5kQ29sb3ImJnRoaXMuYmxlbmRDb2xvci5pc0NvbG9yJiYobi5ibGVuZENvbG9yPXRoaXMuYmxlbmRDb2xvci5nZXRIZXgoKSksdGhpcy5ibGVuZEFscGhhIT09MCYmKG4uYmxlbmRBbHBoYT10aGlzLmJsZW5kQWxwaGEpLHRoaXMuZGVwdGhGdW5jIT09MyYmKG4uZGVwdGhGdW5jPXRoaXMuZGVwdGhGdW5jKSx0aGlzLmRlcHRoVGVzdD09PSExJiYobi5kZXB0aFRlc3Q9dGhpcy5kZXB0aFRlc3QpLHRoaXMuZGVwdGhXcml0ZT09PSExJiYobi5kZXB0aFdyaXRlPXRoaXMuZGVwdGhXcml0ZSksdGhpcy5jb2xvcldyaXRlPT09ITEmJihuLmNvbG9yV3JpdGU9dGhpcy5jb2xvcldyaXRlKSx0aGlzLnN0ZW5jaWxXcml0ZU1hc2shPT0yNTUmJihuLnN0ZW5jaWxXcml0ZU1hc2s9dGhpcy5zdGVuY2lsV3JpdGVNYXNrKSx0aGlzLnN0ZW5jaWxGdW5jIT09NTE5JiYobi5zdGVuY2lsRnVuYz10aGlzLnN0ZW5jaWxGdW5jKSx0aGlzLnN0ZW5jaWxSZWYhPT0wJiYobi5zdGVuY2lsUmVmPXRoaXMuc3RlbmNpbFJlZiksdGhpcy5zdGVuY2lsRnVuY01hc2shPT0yNTUmJihuLnN0ZW5jaWxGdW5jTWFzaz10aGlzLnN0ZW5jaWxGdW5jTWFzayksdGhpcy5zdGVuY2lsRmFpbCE9PTc2ODAmJihuLnN0ZW5jaWxGYWlsPXRoaXMuc3RlbmNpbEZhaWwpLHRoaXMuc3RlbmNpbFpGYWlsIT09NzY4MCYmKG4uc3RlbmNpbFpGYWlsPXRoaXMuc3RlbmNpbFpGYWlsKSx0aGlzLnN0ZW5jaWxaUGFzcyE9PTc2ODAmJihuLnN0ZW5jaWxaUGFzcz10aGlzLnN0ZW5jaWxaUGFzcyksdGhpcy5zdGVuY2lsV3JpdGU9PT0hMCYmKG4uc3RlbmNpbFdyaXRlPXRoaXMuc3RlbmNpbFdyaXRlKSx0aGlzLnJvdGF0aW9uIT09dm9pZCAwJiZ0aGlzLnJvdGF0aW9uIT09MCYmKG4ucm90YXRpb249dGhpcy5yb3RhdGlvbiksdGhpcy5wb2x5Z29uT2Zmc2V0PT09ITAmJihuLnBvbHlnb25PZmZzZXQ9ITApLHRoaXMucG9seWdvbk9mZnNldEZhY3RvciE9PTAmJihuLnBvbHlnb25PZmZzZXRGYWN0b3I9dGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yKSx0aGlzLnBvbHlnb25PZmZzZXRVbml0cyE9PTAmJihuLnBvbHlnb25PZmZzZXRVbml0cz10aGlzLnBvbHlnb25PZmZzZXRVbml0cyksdGhpcy5saW5ld2lkdGghPT12b2lkIDAmJnRoaXMubGluZXdpZHRoIT09MSYmKG4ubGluZXdpZHRoPXRoaXMubGluZXdpZHRoKSx0aGlzLmRhc2hTaXplIT09dm9pZCAwJiYobi5kYXNoU2l6ZT10aGlzLmRhc2hTaXplKSx0aGlzLmdhcFNpemUhPT12b2lkIDAmJihuLmdhcFNpemU9dGhpcy5nYXBTaXplKSx0aGlzLnNjYWxlIT09dm9pZCAwJiYobi5zY2FsZT10aGlzLnNjYWxlKSx0aGlzLmRpdGhlcmluZz09PSEwJiYobi5kaXRoZXJpbmc9ITApLHRoaXMuYWxwaGFUZXN0PjAmJihuLmFscGhhVGVzdD10aGlzLmFscGhhVGVzdCksdGhpcy5hbHBoYUhhc2g9PT0hMCYmKG4uYWxwaGFIYXNoPSEwKSx0aGlzLmFscGhhVG9Db3ZlcmFnZT09PSEwJiYobi5hbHBoYVRvQ292ZXJhZ2U9ITApLHRoaXMucHJlbXVsdGlwbGllZEFscGhhPT09ITAmJihuLnByZW11bHRpcGxpZWRBbHBoYT0hMCksdGhpcy5mb3JjZVNpbmdsZVBhc3M9PT0hMCYmKG4uZm9yY2VTaW5nbGVQYXNzPSEwKSx0aGlzLndpcmVmcmFtZT09PSEwJiYobi53aXJlZnJhbWU9ITApLHRoaXMud2lyZWZyYW1lTGluZXdpZHRoPjEmJihuLndpcmVmcmFtZUxpbmV3aWR0aD10aGlzLndpcmVmcmFtZUxpbmV3aWR0aCksdGhpcy53aXJlZnJhbWVMaW5lY2FwIT09InJvdW5kIiYmKG4ud2lyZWZyYW1lTGluZWNhcD10aGlzLndpcmVmcmFtZUxpbmVjYXApLHRoaXMud2lyZWZyYW1lTGluZWpvaW4hPT0icm91bmQiJiYobi53aXJlZnJhbWVMaW5lam9pbj10aGlzLndpcmVmcmFtZUxpbmVqb2luKSx0aGlzLmZsYXRTaGFkaW5nPT09ITAmJihuLmZsYXRTaGFkaW5nPSEwKSx0aGlzLnZpc2libGU9PT0hMSYmKG4udmlzaWJsZT0hMSksdGhpcy50b25lTWFwcGVkPT09ITEmJihuLnRvbmVNYXBwZWQ9ITEpLHRoaXMuZm9nPT09ITEmJihuLmZvZz0hMSksT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihuLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpO2Z1bmN0aW9uIHMocil7Y29uc3Qgbz1bXTtmb3IoY29uc3QgYSBpbiByKXtjb25zdCBjPXJbYV07ZGVsZXRlIGMubWV0YWRhdGEsby5wdXNoKGMpfXJldHVybiBvfWlmKGUpe2NvbnN0IHI9cyh0LnRleHR1cmVzKSxvPXModC5pbWFnZXMpO3IubGVuZ3RoPjAmJihuLnRleHR1cmVzPXIpLG8ubGVuZ3RoPjAmJihuLmltYWdlcz1vKX1yZXR1cm4gbn1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXt0aGlzLm5hbWU9dC5uYW1lLHRoaXMuYmxlbmRpbmc9dC5ibGVuZGluZyx0aGlzLnNpZGU9dC5zaWRlLHRoaXMudmVydGV4Q29sb3JzPXQudmVydGV4Q29sb3JzLHRoaXMub3BhY2l0eT10Lm9wYWNpdHksdGhpcy50cmFuc3BhcmVudD10LnRyYW5zcGFyZW50LHRoaXMuYmxlbmRTcmM9dC5ibGVuZFNyYyx0aGlzLmJsZW5kRHN0PXQuYmxlbmREc3QsdGhpcy5ibGVuZEVxdWF0aW9uPXQuYmxlbmRFcXVhdGlvbix0aGlzLmJsZW5kU3JjQWxwaGE9dC5ibGVuZFNyY0FscGhhLHRoaXMuYmxlbmREc3RBbHBoYT10LmJsZW5kRHN0QWxwaGEsdGhpcy5ibGVuZEVxdWF0aW9uQWxwaGE9dC5ibGVuZEVxdWF0aW9uQWxwaGEsdGhpcy5ibGVuZENvbG9yLmNvcHkodC5ibGVuZENvbG9yKSx0aGlzLmJsZW5kQWxwaGE9dC5ibGVuZEFscGhhLHRoaXMuZGVwdGhGdW5jPXQuZGVwdGhGdW5jLHRoaXMuZGVwdGhUZXN0PXQuZGVwdGhUZXN0LHRoaXMuZGVwdGhXcml0ZT10LmRlcHRoV3JpdGUsdGhpcy5zdGVuY2lsV3JpdGVNYXNrPXQuc3RlbmNpbFdyaXRlTWFzayx0aGlzLnN0ZW5jaWxGdW5jPXQuc3RlbmNpbEZ1bmMsdGhpcy5zdGVuY2lsUmVmPXQuc3RlbmNpbFJlZix0aGlzLnN0ZW5jaWxGdW5jTWFzaz10LnN0ZW5jaWxGdW5jTWFzayx0aGlzLnN0ZW5jaWxGYWlsPXQuc3RlbmNpbEZhaWwsdGhpcy5zdGVuY2lsWkZhaWw9dC5zdGVuY2lsWkZhaWwsdGhpcy5zdGVuY2lsWlBhc3M9dC5zdGVuY2lsWlBhc3MsdGhpcy5zdGVuY2lsV3JpdGU9dC5zdGVuY2lsV3JpdGU7Y29uc3QgZT10LmNsaXBwaW5nUGxhbmVzO2xldCBuPW51bGw7aWYoZSE9PW51bGwpe2NvbnN0IHM9ZS5sZW5ndGg7bj1uZXcgQXJyYXkocyk7Zm9yKGxldCByPTA7ciE9PXM7KytyKW5bcl09ZVtyXS5jbG9uZSgpfXJldHVybiB0aGlzLmNsaXBwaW5nUGxhbmVzPW4sdGhpcy5jbGlwSW50ZXJzZWN0aW9uPXQuY2xpcEludGVyc2VjdGlvbix0aGlzLmNsaXBTaGFkb3dzPXQuY2xpcFNoYWRvd3MsdGhpcy5zaGFkb3dTaWRlPXQuc2hhZG93U2lkZSx0aGlzLmNvbG9yV3JpdGU9dC5jb2xvcldyaXRlLHRoaXMucHJlY2lzaW9uPXQucHJlY2lzaW9uLHRoaXMucG9seWdvbk9mZnNldD10LnBvbHlnb25PZmZzZXQsdGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yPXQucG9seWdvbk9mZnNldEZhY3Rvcix0aGlzLnBvbHlnb25PZmZzZXRVbml0cz10LnBvbHlnb25PZmZzZXRVbml0cyx0aGlzLmRpdGhlcmluZz10LmRpdGhlcmluZyx0aGlzLmFscGhhVGVzdD10LmFscGhhVGVzdCx0aGlzLmFscGhhSGFzaD10LmFscGhhSGFzaCx0aGlzLmFscGhhVG9Db3ZlcmFnZT10LmFscGhhVG9Db3ZlcmFnZSx0aGlzLnByZW11bHRpcGxpZWRBbHBoYT10LnByZW11bHRpcGxpZWRBbHBoYSx0aGlzLmZvcmNlU2luZ2xlUGFzcz10LmZvcmNlU2luZ2xlUGFzcyx0aGlzLnZpc2libGU9dC52aXNpYmxlLHRoaXMudG9uZU1hcHBlZD10LnRvbmVNYXBwZWQsdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSx0aGlzfWRpc3Bvc2UoKXt0aGlzLmRpc3BhdGNoRXZlbnQoe3R5cGU6ImRpc3Bvc2UifSl9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy52ZXJzaW9uKyt9fWNsYXNzIHlmIGV4dGVuZHMgcGZ7Y29uc3RydWN0b3IodCl7c3VwZXIoKSx0aGlzLmlzTWVzaEJhc2ljTWF0ZXJpYWw9ITAsdGhpcy50eXBlPSJNZXNoQmFzaWNNYXRlcmlhbCIsdGhpcy5jb2xvcj1uZXcgeXMoMTY3NzcyMTUpLHRoaXMubWFwPW51bGwsdGhpcy5saWdodE1hcD1udWxsLHRoaXMubGlnaHRNYXBJbnRlbnNpdHk9MSx0aGlzLmFvTWFwPW51bGwsdGhpcy5hb01hcEludGVuc2l0eT0xLHRoaXMuc3BlY3VsYXJNYXA9bnVsbCx0aGlzLmFscGhhTWFwPW51bGwsdGhpcy5lbnZNYXA9bnVsbCx0aGlzLmVudk1hcFJvdGF0aW9uPW5ldyBiaSx0aGlzLmNvbWJpbmU9MCx0aGlzLnJlZmxlY3Rpdml0eT0xLHRoaXMucmVmcmFjdGlvblJhdGlvPS45OCx0aGlzLndpcmVmcmFtZT0hMSx0aGlzLndpcmVmcmFtZUxpbmV3aWR0aD0xLHRoaXMud2lyZWZyYW1lTGluZWNhcD0icm91bmQiLHRoaXMud2lyZWZyYW1lTGluZWpvaW49InJvdW5kIix0aGlzLmZvZz0hMCx0aGlzLnNldFZhbHVlcyh0KX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMuY29sb3IuY29weSh0LmNvbG9yKSx0aGlzLm1hcD10Lm1hcCx0aGlzLmxpZ2h0TWFwPXQubGlnaHRNYXAsdGhpcy5saWdodE1hcEludGVuc2l0eT10LmxpZ2h0TWFwSW50ZW5zaXR5LHRoaXMuYW9NYXA9dC5hb01hcCx0aGlzLmFvTWFwSW50ZW5zaXR5PXQuYW9NYXBJbnRlbnNpdHksdGhpcy5zcGVjdWxhck1hcD10LnNwZWN1bGFyTWFwLHRoaXMuYWxwaGFNYXA9dC5hbHBoYU1hcCx0aGlzLmVudk1hcD10LmVudk1hcCx0aGlzLmVudk1hcFJvdGF0aW9uLmNvcHkodC5lbnZNYXBSb3RhdGlvbiksdGhpcy5jb21iaW5lPXQuY29tYmluZSx0aGlzLnJlZmxlY3Rpdml0eT10LnJlZmxlY3Rpdml0eSx0aGlzLnJlZnJhY3Rpb25SYXRpbz10LnJlZnJhY3Rpb25SYXRpbyx0aGlzLndpcmVmcmFtZT10LndpcmVmcmFtZSx0aGlzLndpcmVmcmFtZUxpbmV3aWR0aD10LndpcmVmcmFtZUxpbmV3aWR0aCx0aGlzLndpcmVmcmFtZUxpbmVjYXA9dC53aXJlZnJhbWVMaW5lY2FwLHRoaXMud2lyZWZyYW1lTGluZWpvaW49dC53aXJlZnJhbWVMaW5lam9pbix0aGlzLmZvZz10LmZvZyx0aGlzfX1jb25zdCBwdD1uZXcgVCxtcz1uZXcgUjtsZXQgbWY9MDtjbGFzcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbj0hMSl7aWYoQXJyYXkuaXNBcnJheSh0KSl0aHJvdyBuZXcgVHlwZUVycm9yKCJUSFJFRS5CdWZmZXJBdHRyaWJ1dGU6IGFycmF5IHNob3VsZCBiZSBhIFR5cGVkIEFycmF5LiIpO3RoaXMuaXNCdWZmZXJBdHRyaWJ1dGU9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6bWYrK30pLHRoaXMubmFtZT0iIix0aGlzLmFycmF5PXQsdGhpcy5pdGVtU2l6ZT1lLHRoaXMuY291bnQ9dCE9PXZvaWQgMD90Lmxlbmd0aC9lOjAsdGhpcy5ub3JtYWxpemVkPW4sdGhpcy51c2FnZT0zNTA0NCx0aGlzLnVwZGF0ZVJhbmdlcz1bXSx0aGlzLmdwdVR5cGU9MTAxNSx0aGlzLnZlcnNpb249MH1vblVwbG9hZENhbGxiYWNrKCl7fXNldCBuZWVkc1VwZGF0ZSh0KXt0PT09ITAmJnRoaXMudmVyc2lvbisrfXNldFVzYWdlKHQpe3JldHVybiB0aGlzLnVzYWdlPXQsdGhpc31hZGRVcGRhdGVSYW5nZSh0LGUpe3RoaXMudXBkYXRlUmFuZ2VzLnB1c2goe3N0YXJ0OnQsY291bnQ6ZX0pfWNsZWFyVXBkYXRlUmFuZ2VzKCl7dGhpcy51cGRhdGVSYW5nZXMubGVuZ3RoPTB9Y29weSh0KXtyZXR1cm4gdGhpcy5uYW1lPXQubmFtZSx0aGlzLmFycmF5PW5ldyB0LmFycmF5LmNvbnN0cnVjdG9yKHQuYXJyYXkpLHRoaXMuaXRlbVNpemU9dC5pdGVtU2l6ZSx0aGlzLmNvdW50PXQuY291bnQsdGhpcy5ub3JtYWxpemVkPXQubm9ybWFsaXplZCx0aGlzLnVzYWdlPXQudXNhZ2UsdGhpcy5ncHVUeXBlPXQuZ3B1VHlwZSx0aGlzfWNvcHlBdCh0LGUsbil7dCo9dGhpcy5pdGVtU2l6ZSxuKj1lLml0ZW1TaXplO2ZvcihsZXQgcz0wLHI9dGhpcy5pdGVtU2l6ZTtzPHI7cysrKXRoaXMuYXJyYXlbdCtzXT1lLmFycmF5W24rc107cmV0dXJuIHRoaXN9Y29weUFycmF5KHQpe3JldHVybiB0aGlzLmFycmF5LnNldCh0KSx0aGlzfWFwcGx5TWF0cml4Myh0KXtpZih0aGlzLml0ZW1TaXplPT09Milmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKyltcy5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSksbXMuYXBwbHlNYXRyaXgzKHQpLHRoaXMuc2V0WFkoZSxtcy54LG1zLnkpO2Vsc2UgaWYodGhpcy5pdGVtU2l6ZT09PTMpZm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LmFwcGx5TWF0cml4Myh0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc31hcHBseU1hdHJpeDQodCl7Zm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LmFwcGx5TWF0cml4NCh0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc31hcHBseU5vcm1hbE1hdHJpeCh0KXtmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQuYXBwbHlOb3JtYWxNYXRyaXgodCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9dHJhbnNmb3JtRGlyZWN0aW9uKHQpe2ZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC50cmFuc2Zvcm1EaXJlY3Rpb24odCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9c2V0KHQsZT0wKXtyZXR1cm4gdGhpcy5hcnJheS5zZXQodCxlKSx0aGlzfWdldENvbXBvbmVudCh0LGUpe2xldCBuPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplK2VdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihuPW1pKG4sdGhpcy5hcnJheSkpLG59c2V0Q29tcG9uZW50KHQsZSxuKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYobj1JdChuLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZStlXT1uLHRoaXN9Z2V0WCh0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZV07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9bWkoZSx0aGlzLmFycmF5KSksZX1zZXRYKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemVdPWUsdGhpc31nZXRZKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzFdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0WSh0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzFdPWUsdGhpc31nZXRaKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzJdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0Wih0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzJdPWUsdGhpc31nZXRXKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzNdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0Vyh0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplKzNdPWUsdGhpc31zZXRYWSh0LGUsbil7cmV0dXJuIHQqPXRoaXMuaXRlbVNpemUsdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpLG49SXQobix0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KzBdPWUsdGhpcy5hcnJheVt0KzFdPW4sdGhpc31zZXRYWVoodCxlLG4scyl7cmV0dXJuIHQqPXRoaXMuaXRlbVNpemUsdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpLG49SXQobix0aGlzLmFycmF5KSxzPUl0KHMsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCswXT1lLHRoaXMuYXJyYXlbdCsxXT1uLHRoaXMuYXJyYXlbdCsyXT1zLHRoaXN9c2V0WFlaVyh0LGUsbixzLHIpe3JldHVybiB0Kj10aGlzLml0ZW1TaXplLHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSxuPUl0KG4sdGhpcy5hcnJheSkscz1JdChzLHRoaXMuYXJyYXkpLHI9SXQocix0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KzBdPWUsdGhpcy5hcnJheVt0KzFdPW4sdGhpcy5hcnJheVt0KzJdPXMsdGhpcy5hcnJheVt0KzNdPXIsdGhpc31vblVwbG9hZCh0KXtyZXR1cm4gdGhpcy5vblVwbG9hZENhbGxiYWNrPXQsdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmFycmF5LHRoaXMuaXRlbVNpemUpLmNvcHkodGhpcyl9dG9KU09OKCl7Y29uc3QgdD17aXRlbVNpemU6dGhpcy5pdGVtU2l6ZSx0eXBlOnRoaXMuYXJyYXkuY29uc3RydWN0b3IubmFtZSxhcnJheTpBcnJheS5mcm9tKHRoaXMuYXJyYXkpLG5vcm1hbGl6ZWQ6dGhpcy5ub3JtYWxpemVkfTtyZXR1cm4gdGhpcy5uYW1lIT09IiImJih0Lm5hbWU9dGhpcy5uYW1lKSx0aGlzLnVzYWdlIT09MzUwNDQmJih0LnVzYWdlPXRoaXMudXNhZ2UpLHR9fWNsYXNzIGdmIGV4dGVuZHMgeHR7Y29uc3RydWN0b3IodCxlLG4pe3N1cGVyKG5ldyBVaW50MTZBcnJheSh0KSxlLG4pfX1jbGFzcyB4ZiBleHRlbmRzIHh0e2NvbnN0cnVjdG9yKHQsZSxuKXtzdXBlcihuZXcgVWludDMyQXJyYXkodCksZSxuKX19Y2xhc3MgQmUgZXh0ZW5kcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbil7c3VwZXIobmV3IEZsb2F0MzJBcnJheSh0KSxlLG4pfX1sZXQgd2Y9MDtjb25zdCBqdD1uZXcgc3QsU289bmV3IEVlLHFuPW5ldyBULFZ0PW5ldyBndCxBaT1uZXcgZ3QsYnQ9bmV3IFQ7Y2xhc3MgdWUgZXh0ZW5kcyBvc3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy5pc0J1ZmZlckdlb21ldHJ5PSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOndmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy50eXBlPSJCdWZmZXJHZW9tZXRyeSIsdGhpcy5pbmRleD1udWxsLHRoaXMuaW5kaXJlY3Q9bnVsbCx0aGlzLmF0dHJpYnV0ZXM9e30sdGhpcy5tb3JwaEF0dHJpYnV0ZXM9e30sdGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT0hMSx0aGlzLmdyb3Vwcz1bXSx0aGlzLmJvdW5kaW5nQm94PW51bGwsdGhpcy5ib3VuZGluZ1NwaGVyZT1udWxsLHRoaXMuZHJhd1JhbmdlPXtzdGFydDowLGNvdW50OjEvMH0sdGhpcy51c2VyRGF0YT17fX1nZXRJbmRleCgpe3JldHVybiB0aGlzLmluZGV4fXNldEluZGV4KHQpe3JldHVybiBBcnJheS5pc0FycmF5KHQpP3RoaXMuaW5kZXg9bmV3KFF1KHQpP3hmOmdmKSh0LDEpOnRoaXMuaW5kZXg9dCx0aGlzfXNldEluZGlyZWN0KHQpe3JldHVybiB0aGlzLmluZGlyZWN0PXQsdGhpc31nZXRJbmRpcmVjdCgpe3JldHVybiB0aGlzLmluZGlyZWN0fWdldEF0dHJpYnV0ZSh0KXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdfXNldEF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF09ZSx0aGlzfWRlbGV0ZUF0dHJpYnV0ZSh0KXtyZXR1cm4gZGVsZXRlIHRoaXMuYXR0cmlidXRlc1t0XSx0aGlzfWhhc0F0dHJpYnV0ZSh0KXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdIT09dm9pZCAwfWFkZEdyb3VwKHQsZSxuPTApe3RoaXMuZ3JvdXBzLnB1c2goe3N0YXJ0OnQsY291bnQ6ZSxtYXRlcmlhbEluZGV4Om59KX1jbGVhckdyb3Vwcygpe3RoaXMuZ3JvdXBzPVtdfXNldERyYXdSYW5nZSh0LGUpe3RoaXMuZHJhd1JhbmdlLnN0YXJ0PXQsdGhpcy5kcmF3UmFuZ2UuY291bnQ9ZX1hcHBseU1hdHJpeDQodCl7Y29uc3QgZT10aGlzLmF0dHJpYnV0ZXMucG9zaXRpb247ZSE9PXZvaWQgMCYmKGUuYXBwbHlNYXRyaXg0KHQpLGUubmVlZHNVcGRhdGU9ITApO2NvbnN0IG49dGhpcy5hdHRyaWJ1dGVzLm5vcm1hbDtpZihuIT09dm9pZCAwKXtjb25zdCByPW5ldyBnZSgpLmdldE5vcm1hbE1hdHJpeCh0KTtuLmFwcGx5Tm9ybWFsTWF0cml4KHIpLG4ubmVlZHNVcGRhdGU9ITB9Y29uc3Qgcz10aGlzLmF0dHJpYnV0ZXMudGFuZ2VudDtyZXR1cm4gcyE9PXZvaWQgMCYmKHMudHJhbnNmb3JtRGlyZWN0aW9uKHQpLHMubmVlZHNVcGRhdGU9ITApLHRoaXMuYm91bmRpbmdCb3ghPT1udWxsJiZ0aGlzLmNvbXB1dGVCb3VuZGluZ0JveCgpLHRoaXMuYm91bmRpbmdTcGhlcmUhPT1udWxsJiZ0aGlzLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpLHRoaXN9YXBwbHlRdWF0ZXJuaW9uKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25Gcm9tUXVhdGVybmlvbih0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31yb3RhdGVYKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25YKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXJvdGF0ZVkodCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvblkodCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9cm90YXRlWih0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uWih0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc310cmFuc2xhdGUodCxlLG4pe3JldHVybiBqdC5tYWtlVHJhbnNsYXRpb24odCxlLG4pLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXNjYWxlKHQsZSxuKXtyZXR1cm4ganQubWFrZVNjYWxlKHQsZSxuKSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31sb29rQXQodCl7cmV0dXJuIFNvLmxvb2tBdCh0KSxTby51cGRhdGVNYXRyaXgoKSx0aGlzLmFwcGx5TWF0cml4NChTby5tYXRyaXgpLHRoaXN9Y2VudGVyKCl7cmV0dXJuIHRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCksdGhpcy5ib3VuZGluZ0JveC5nZXRDZW50ZXIocW4pLm5lZ2F0ZSgpLHRoaXMudHJhbnNsYXRlKHFuLngscW4ueSxxbi56KSx0aGlzfXNldEZyb21Qb2ludHModCl7Y29uc3QgZT10aGlzLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKTtpZihlPT09dm9pZCAwKXtjb25zdCBuPVtdO2ZvcihsZXQgcz0wLHI9dC5sZW5ndGg7czxyO3MrKyl7Y29uc3Qgbz10W3NdO24ucHVzaChvLngsby55LG8uenx8MCl9dGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQmUobiwzKSl9ZWxzZXtjb25zdCBuPU1hdGgubWluKHQubGVuZ3RoLGUuY291bnQpO2ZvcihsZXQgcz0wO3M8bjtzKyspe2NvbnN0IHI9dFtzXTtlLnNldFhZWihzLHIueCxyLnksci56fHwwKX10Lmxlbmd0aD5lLmNvdW50JiZjb25zb2xlLndhcm4oIlRIUkVFLkJ1ZmZlckdlb21ldHJ5OiBCdWZmZXIgc2l6ZSB0b28gc21hbGwgZm9yIHBvaW50cyBkYXRhLiBVc2UgLmRpc3Bvc2UoKSBhbmQgY3JlYXRlIGEgbmV3IGdlb21ldHJ5LiIpLGUubmVlZHNVcGRhdGU9ITB9cmV0dXJuIHRoaXN9Y29tcHV0ZUJvdW5kaW5nQm94KCl7dGhpcy5ib3VuZGluZ0JveD09PW51bGwmJih0aGlzLmJvdW5kaW5nQm94PW5ldyBndCk7Y29uc3QgdD10aGlzLmF0dHJpYnV0ZXMucG9zaXRpb24sZT10aGlzLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbjtpZih0JiZ0LmlzR0xCdWZmZXJBdHRyaWJ1dGUpe2NvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ0JveCgpOiBHTEJ1ZmZlckF0dHJpYnV0ZSByZXF1aXJlcyBhIG1hbnVhbCBib3VuZGluZyBib3guIix0aGlzKSx0aGlzLmJvdW5kaW5nQm94LnNldChuZXcgVCgtMS8wLC0xLzAsLTEvMCksbmV3IFQoMS8wLDEvMCwxLzApKTtyZXR1cm59aWYodCE9PXZvaWQgMCl7aWYodGhpcy5ib3VuZGluZ0JveC5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHQpLGUpZm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKXtjb25zdCByPWVbbl07VnQuc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZShyKSx0aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPyhidC5hZGRWZWN0b3JzKHRoaXMuYm91bmRpbmdCb3gubWluLFZ0Lm1pbiksdGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KGJ0KSxidC5hZGRWZWN0b3JzKHRoaXMuYm91bmRpbmdCb3gubWF4LFZ0Lm1heCksdGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KGJ0KSk6KHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChWdC5taW4pLHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChWdC5tYXgpKX19ZWxzZSB0aGlzLmJvdW5kaW5nQm94Lm1ha2VFbXB0eSgpOyhpc05hTih0aGlzLmJvdW5kaW5nQm94Lm1pbi54KXx8aXNOYU4odGhpcy5ib3VuZGluZ0JveC5taW4ueSl8fGlzTmFOKHRoaXMuYm91bmRpbmdCb3gubWluLnopKSYmY29uc29sZS5lcnJvcignVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94KCk6IENvbXB1dGVkIG1pbi9tYXggaGF2ZSBOYU4gdmFsdWVzLiBUaGUgInBvc2l0aW9uIiBhdHRyaWJ1dGUgaXMgbGlrZWx5IHRvIGhhdmUgTmFOIHZhbHVlcy4nLHRoaXMpfWNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpe3RoaXMuYm91bmRpbmdTcGhlcmU9PT1udWxsJiYodGhpcy5ib3VuZGluZ1NwaGVyZT1uZXcgY28pO2NvbnN0IHQ9dGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uLGU9dGhpcy5tb3JwaEF0dHJpYnV0ZXMucG9zaXRpb247aWYodCYmdC5pc0dMQnVmZmVyQXR0cmlidXRlKXtjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTogR0xCdWZmZXJBdHRyaWJ1dGUgcmVxdWlyZXMgYSBtYW51YWwgYm91bmRpbmcgc3BoZXJlLiIsdGhpcyksdGhpcy5ib3VuZGluZ1NwaGVyZS5zZXQobmV3IFQsMS8wKTtyZXR1cm59aWYodCl7Y29uc3Qgbj10aGlzLmJvdW5kaW5nU3BoZXJlLmNlbnRlcjtpZihWdC5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHQpLGUpZm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl07QWkuc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZShhKSx0aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPyhidC5hZGRWZWN0b3JzKFZ0Lm1pbixBaS5taW4pLFZ0LmV4cGFuZEJ5UG9pbnQoYnQpLGJ0LmFkZFZlY3RvcnMoVnQubWF4LEFpLm1heCksVnQuZXhwYW5kQnlQb2ludChidCkpOihWdC5leHBhbmRCeVBvaW50KEFpLm1pbiksVnQuZXhwYW5kQnlQb2ludChBaS5tYXgpKX1WdC5nZXRDZW50ZXIobik7bGV0IHM9MDtmb3IobGV0IHI9MCxvPXQuY291bnQ7cjxvO3IrKylidC5mcm9tQnVmZmVyQXR0cmlidXRlKHQscikscz1NYXRoLm1heChzLG4uZGlzdGFuY2VUb1NxdWFyZWQoYnQpKTtpZihlKWZvcihsZXQgcj0wLG89ZS5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1lW3JdLGM9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZTtmb3IobGV0IGw9MCxoPWEuY291bnQ7bDxoO2wrKylidC5mcm9tQnVmZmVyQXR0cmlidXRlKGEsbCksYyYmKHFuLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxsKSxidC5hZGQocW4pKSxzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZChidCkpfXRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzPU1hdGguc3FydChzKSxpc05hTih0aGlzLmJvdW5kaW5nU3BoZXJlLnJhZGl1cykmJmNvbnNvbGUuZXJyb3IoJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpOiBDb21wdXRlZCByYWRpdXMgaXMgTmFOLiBUaGUgInBvc2l0aW9uIiBhdHRyaWJ1dGUgaXMgbGlrZWx5IHRvIGhhdmUgTmFOIHZhbHVlcy4nLHRoaXMpfX1jb21wdXRlVGFuZ2VudHMoKXtjb25zdCB0PXRoaXMuaW5kZXgsZT10aGlzLmF0dHJpYnV0ZXM7aWYodD09PW51bGx8fGUucG9zaXRpb249PT12b2lkIDB8fGUubm9ybWFsPT09dm9pZCAwfHxlLnV2PT09dm9pZCAwKXtjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmNvbXB1dGVUYW5nZW50cygpIGZhaWxlZC4gTWlzc2luZyByZXF1aXJlZCBhdHRyaWJ1dGVzIChpbmRleCwgcG9zaXRpb24sIG5vcm1hbCBvciB1dikiKTtyZXR1cm59Y29uc3Qgbj1lLnBvc2l0aW9uLHM9ZS5ub3JtYWwscj1lLnV2O3RoaXMuaGFzQXR0cmlidXRlKCJ0YW5nZW50Iik9PT0hMSYmdGhpcy5zZXRBdHRyaWJ1dGUoInRhbmdlbnQiLG5ldyB4dChuZXcgRmxvYXQzMkFycmF5KDQqbi5jb3VudCksNCkpO2NvbnN0IG89dGhpcy5nZXRBdHRyaWJ1dGUoInRhbmdlbnQiKSxhPVtdLGM9W107Zm9yKGxldCBfPTA7XzxuLmNvdW50O18rKylhW19dPW5ldyBULGNbX109bmV3IFQ7Y29uc3QgbD1uZXcgVCxoPW5ldyBULHU9bmV3IFQsZj1uZXcgUixkPW5ldyBSLHA9bmV3IFIseT1uZXcgVCxtPW5ldyBUO2Z1bmN0aW9uIGcoXyxFLHope2wuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLF8pLGguZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLEUpLHUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHopLGYuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLF8pLGQuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLEUpLHAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLHopLGguc3ViKGwpLHUuc3ViKGwpLGQuc3ViKGYpLHAuc3ViKGYpO2NvbnN0IHY9MS8oZC54KnAueS1wLngqZC55KTtpc0Zpbml0ZSh2KSYmKHkuY29weShoKS5tdWx0aXBseVNjYWxhcihwLnkpLmFkZFNjYWxlZFZlY3Rvcih1LC1kLnkpLm11bHRpcGx5U2NhbGFyKHYpLG0uY29weSh1KS5tdWx0aXBseVNjYWxhcihkLngpLmFkZFNjYWxlZFZlY3RvcihoLC1wLngpLm11bHRpcGx5U2NhbGFyKHYpLGFbX10uYWRkKHkpLGFbRV0uYWRkKHkpLGFbel0uYWRkKHkpLGNbX10uYWRkKG0pLGNbRV0uYWRkKG0pLGNbel0uYWRkKG0pKX1sZXQgYj10aGlzLmdyb3VwcztiLmxlbmd0aD09PTAmJihiPVt7c3RhcnQ6MCxjb3VudDp0LmNvdW50fV0pO2ZvcihsZXQgXz0wLEU9Yi5sZW5ndGg7XzxFOysrXyl7Y29uc3Qgej1iW19dLHY9ei5zdGFydCxDPXouY291bnQ7Zm9yKGxldCBQPXYsRj12K0M7UDxGO1ArPTMpZyh0LmdldFgoUCswKSx0LmdldFgoUCsxKSx0LmdldFgoUCsyKSl9Y29uc3Qgdz1uZXcgVCx4PW5ldyBULE09bmV3IFQsQT1uZXcgVDtmdW5jdGlvbiBTKF8pe00uZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLF8pLEEuY29weShNKTtjb25zdCBFPWFbX107dy5jb3B5KEUpLHcuc3ViKE0ubXVsdGlwbHlTY2FsYXIoTS5kb3QoRSkpKS5ub3JtYWxpemUoKSx4LmNyb3NzVmVjdG9ycyhBLEUpO2NvbnN0IHY9eC5kb3QoY1tfXSk8MD8tMToxO28uc2V0WFlaVyhfLHcueCx3Lnksdy56LHYpfWZvcihsZXQgXz0wLEU9Yi5sZW5ndGg7XzxFOysrXyl7Y29uc3Qgej1iW19dLHY9ei5zdGFydCxDPXouY291bnQ7Zm9yKGxldCBQPXYsRj12K0M7UDxGO1ArPTMpUyh0LmdldFgoUCswKSksUyh0LmdldFgoUCsxKSksUyh0LmdldFgoUCsyKSl9fWNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCl7Y29uc3QgdD10aGlzLmluZGV4LGU9dGhpcy5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIik7aWYoZSE9PXZvaWQgMCl7bGV0IG49dGhpcy5nZXRBdHRyaWJ1dGUoIm5vcm1hbCIpO2lmKG49PT12b2lkIDApbj1uZXcgeHQobmV3IEZsb2F0MzJBcnJheShlLmNvdW50KjMpLDMpLHRoaXMuc2V0QXR0cmlidXRlKCJub3JtYWwiLG4pO2Vsc2UgZm9yKGxldCBmPTAsZD1uLmNvdW50O2Y8ZDtmKyspbi5zZXRYWVooZiwwLDAsMCk7Y29uc3Qgcz1uZXcgVCxyPW5ldyBULG89bmV3IFQsYT1uZXcgVCxjPW5ldyBULGw9bmV3IFQsaD1uZXcgVCx1PW5ldyBUO2lmKHQpZm9yKGxldCBmPTAsZD10LmNvdW50O2Y8ZDtmKz0zKXtjb25zdCBwPXQuZ2V0WChmKzApLHk9dC5nZXRYKGYrMSksbT10LmdldFgoZisyKTtzLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxwKSxyLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSx5KSxvLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxtKSxoLnN1YlZlY3RvcnMobyxyKSx1LnN1YlZlY3RvcnMocyxyKSxoLmNyb3NzKHUpLGEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHApLGMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHkpLGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLG0pLGEuYWRkKGgpLGMuYWRkKGgpLGwuYWRkKGgpLG4uc2V0WFlaKHAsYS54LGEueSxhLnopLG4uc2V0WFlaKHksYy54LGMueSxjLnopLG4uc2V0WFlaKG0sbC54LGwueSxsLnopfWVsc2UgZm9yKGxldCBmPTAsZD1lLmNvdW50O2Y8ZDtmKz0zKXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLGYrMCksci5mcm9tQnVmZmVyQXR0cmlidXRlKGUsZisxKSxvLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxmKzIpLGguc3ViVmVjdG9ycyhvLHIpLHUuc3ViVmVjdG9ycyhzLHIpLGguY3Jvc3ModSksbi5zZXRYWVooZiswLGgueCxoLnksaC56KSxuLnNldFhZWihmKzEsaC54LGgueSxoLnopLG4uc2V0WFlaKGYrMixoLngsaC55LGgueik7dGhpcy5ub3JtYWxpemVOb3JtYWxzKCksbi5uZWVkc1VwZGF0ZT0hMH19bm9ybWFsaXplTm9ybWFscygpe2NvbnN0IHQ9dGhpcy5hdHRyaWJ1dGVzLm5vcm1hbDtmb3IobGV0IGU9MCxuPXQuY291bnQ7ZTxuO2UrKylidC5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSksYnQubm9ybWFsaXplKCksdC5zZXRYWVooZSxidC54LGJ0LnksYnQueil9dG9Ob25JbmRleGVkKCl7ZnVuY3Rpb24gdChhLGMpe2NvbnN0IGw9YS5hcnJheSxoPWEuaXRlbVNpemUsdT1hLm5vcm1hbGl6ZWQsZj1uZXcgbC5jb25zdHJ1Y3RvcihjLmxlbmd0aCpoKTtsZXQgZD0wLHA9MDtmb3IobGV0IHk9MCxtPWMubGVuZ3RoO3k8bTt5Kyspe2EuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZT9kPWNbeV0qYS5kYXRhLnN0cmlkZSthLm9mZnNldDpkPWNbeV0qaDtmb3IobGV0IGc9MDtnPGg7ZysrKWZbcCsrXT1sW2QrK119cmV0dXJuIG5ldyB4dChmLGgsdSl9aWYodGhpcy5pbmRleD09PW51bGwpcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnkudG9Ob25JbmRleGVkKCk6IEJ1ZmZlckdlb21ldHJ5IGlzIGFscmVhZHkgbm9uLWluZGV4ZWQuIiksdGhpcztjb25zdCBlPW5ldyB1ZSxuPXRoaXMuaW5kZXguYXJyYXkscz10aGlzLmF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGEgaW4gcyl7Y29uc3QgYz1zW2FdLGw9dChjLG4pO2Uuc2V0QXR0cmlidXRlKGEsbCl9Y29uc3Qgcj10aGlzLm1vcnBoQXR0cmlidXRlcztmb3IoY29uc3QgYSBpbiByKXtjb25zdCBjPVtdLGw9clthXTtmb3IobGV0IGg9MCx1PWwubGVuZ3RoO2g8dTtoKyspe2NvbnN0IGY9bFtoXSxkPXQoZixuKTtjLnB1c2goZCl9ZS5tb3JwaEF0dHJpYnV0ZXNbYV09Y31lLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU7Y29uc3Qgbz10aGlzLmdyb3Vwcztmb3IobGV0IGE9MCxjPW8ubGVuZ3RoO2E8YzthKyspe2NvbnN0IGw9b1thXTtlLmFkZEdyb3VwKGwuc3RhcnQsbC5jb3VudCxsLm1hdGVyaWFsSW5kZXgpfXJldHVybiBlfXRvSlNPTigpe2NvbnN0IHQ9e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJCdWZmZXJHZW9tZXRyeSIsZ2VuZXJhdG9yOiJCdWZmZXJHZW9tZXRyeS50b0pTT04ifX07aWYodC51dWlkPXRoaXMudXVpZCx0LnR5cGU9dGhpcy50eXBlLHRoaXMubmFtZSE9PSIiJiYodC5uYW1lPXRoaXMubmFtZSksT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJih0LnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLHRoaXMucGFyYW1ldGVycyE9PXZvaWQgMCl7Y29uc3QgYz10aGlzLnBhcmFtZXRlcnM7Zm9yKGNvbnN0IGwgaW4gYyljW2xdIT09dm9pZCAwJiYodFtsXT1jW2xdKTtyZXR1cm4gdH10LmRhdGE9e2F0dHJpYnV0ZXM6e319O2NvbnN0IGU9dGhpcy5pbmRleDtlIT09bnVsbCYmKHQuZGF0YS5pbmRleD17dHlwZTplLmFycmF5LmNvbnN0cnVjdG9yLm5hbWUsYXJyYXk6QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZS5hcnJheSl9KTtjb25zdCBuPXRoaXMuYXR0cmlidXRlcztmb3IoY29uc3QgYyBpbiBuKXtjb25zdCBsPW5bY107dC5kYXRhLmF0dHJpYnV0ZXNbY109bC50b0pTT04odC5kYXRhKX1jb25zdCBzPXt9O2xldCByPSExO2Zvcihjb25zdCBjIGluIHRoaXMubW9ycGhBdHRyaWJ1dGVzKXtjb25zdCBsPXRoaXMubW9ycGhBdHRyaWJ1dGVzW2NdLGg9W107Zm9yKGxldCB1PTAsZj1sLmxlbmd0aDt1PGY7dSsrKXtjb25zdCBkPWxbdV07aC5wdXNoKGQudG9KU09OKHQuZGF0YSkpfWgubGVuZ3RoPjAmJihzW2NdPWgscj0hMCl9ciYmKHQuZGF0YS5tb3JwaEF0dHJpYnV0ZXM9cyx0LmRhdGEubW9ycGhUYXJnZXRzUmVsYXRpdmU9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZSk7Y29uc3Qgbz10aGlzLmdyb3VwcztvLmxlbmd0aD4wJiYodC5kYXRhLmdyb3Vwcz1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG8pKSk7Y29uc3QgYT10aGlzLmJvdW5kaW5nU3BoZXJlO3JldHVybiBhIT09bnVsbCYmKHQuZGF0YS5ib3VuZGluZ1NwaGVyZT1hLnRvSlNPTigpKSx0fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3RoaXMuaW5kZXg9bnVsbCx0aGlzLmF0dHJpYnV0ZXM9e30sdGhpcy5tb3JwaEF0dHJpYnV0ZXM9e30sdGhpcy5ncm91cHM9W10sdGhpcy5ib3VuZGluZ0JveD1udWxsLHRoaXMuYm91bmRpbmdTcGhlcmU9bnVsbDtjb25zdCBlPXt9O3RoaXMubmFtZT10Lm5hbWU7Y29uc3Qgbj10LmluZGV4O24hPT1udWxsJiZ0aGlzLnNldEluZGV4KG4uY2xvbmUoKSk7Y29uc3Qgcz10LmF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGwgaW4gcyl7Y29uc3QgaD1zW2xdO3RoaXMuc2V0QXR0cmlidXRlKGwsaC5jbG9uZShlKSl9Y29uc3Qgcj10Lm1vcnBoQXR0cmlidXRlcztmb3IoY29uc3QgbCBpbiByKXtjb25zdCBoPVtdLHU9cltsXTtmb3IobGV0IGY9MCxkPXUubGVuZ3RoO2Y8ZDtmKyspaC5wdXNoKHVbZl0uY2xvbmUoZSkpO3RoaXMubW9ycGhBdHRyaWJ1dGVzW2xdPWh9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT10Lm1vcnBoVGFyZ2V0c1JlbGF0aXZlO2NvbnN0IG89dC5ncm91cHM7Zm9yKGxldCBsPTAsaD1vLmxlbmd0aDtsPGg7bCsrKXtjb25zdCB1PW9bbF07dGhpcy5hZGRHcm91cCh1LnN0YXJ0LHUuY291bnQsdS5tYXRlcmlhbEluZGV4KX1jb25zdCBhPXQuYm91bmRpbmdCb3g7YSE9PW51bGwmJih0aGlzLmJvdW5kaW5nQm94PWEuY2xvbmUoKSk7Y29uc3QgYz10LmJvdW5kaW5nU3BoZXJlO3JldHVybiBjIT09bnVsbCYmKHRoaXMuYm91bmRpbmdTcGhlcmU9Yy5jbG9uZSgpKSx0aGlzLmRyYXdSYW5nZS5zdGFydD10LmRyYXdSYW5nZS5zdGFydCx0aGlzLmRyYXdSYW5nZS5jb3VudD10LmRyYXdSYW5nZS5jb3VudCx0aGlzLnVzZXJEYXRhPXQudXNlckRhdGEsdGhpc31kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfX1jb25zdCBMYz1uZXcgc3QsZm49bmV3IGZvLGdzPW5ldyBjbyxPYz1uZXcgVCx4cz1uZXcgVCx3cz1uZXcgVCxicz1uZXcgVCxfbz1uZXcgVCxNcz1uZXcgVCxEYz1uZXcgVCxBcz1uZXcgVDtjbGFzcyBiZiBleHRlbmRzIEVle2NvbnN0cnVjdG9yKHQ9bmV3IHVlLGU9bmV3IHlmKXtzdXBlcigpLHRoaXMuaXNNZXNoPSEwLHRoaXMudHlwZT0iTWVzaCIsdGhpcy5nZW9tZXRyeT10LHRoaXMubWF0ZXJpYWw9ZSx0aGlzLm1vcnBoVGFyZ2V0RGljdGlvbmFyeT12b2lkIDAsdGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXM9dm9pZCAwLHRoaXMuY291bnQ9MSx0aGlzLnVwZGF0ZU1vcnBoVGFyZ2V0cygpfWNvcHkodCxlKXtyZXR1cm4gc3VwZXIuY29weSh0LGUpLHQubW9ycGhUYXJnZXRJbmZsdWVuY2VzIT09dm9pZCAwJiYodGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXM9dC5tb3JwaFRhcmdldEluZmx1ZW5jZXMuc2xpY2UoKSksdC5tb3JwaFRhcmdldERpY3Rpb25hcnkhPT12b2lkIDAmJih0aGlzLm1vcnBoVGFyZ2V0RGljdGlvbmFyeT1PYmplY3QuYXNzaWduKHt9LHQubW9ycGhUYXJnZXREaWN0aW9uYXJ5KSksdGhpcy5tYXRlcmlhbD1BcnJheS5pc0FycmF5KHQubWF0ZXJpYWwpP3QubWF0ZXJpYWwuc2xpY2UoKTp0Lm1hdGVyaWFsLHRoaXMuZ2VvbWV0cnk9dC5nZW9tZXRyeSx0aGlzfXVwZGF0ZU1vcnBoVGFyZ2V0cygpe2NvbnN0IGU9dGhpcy5nZW9tZXRyeS5tb3JwaEF0dHJpYnV0ZXMsbj1PYmplY3Qua2V5cyhlKTtpZihuLmxlbmd0aD4wKXtjb25zdCBzPWVbblswXV07aWYocyE9PXZvaWQgMCl7dGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXM9W10sdGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9e307Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXNbcl0ubmFtZXx8U3RyaW5nKHIpO3RoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzLnB1c2goMCksdGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnlbYV09cn19fX1nZXRWZXJ0ZXhQb3NpdGlvbih0LGUpe2NvbnN0IG49dGhpcy5nZW9tZXRyeSxzPW4uYXR0cmlidXRlcy5wb3NpdGlvbixyPW4ubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uLG89bi5tb3JwaFRhcmdldHNSZWxhdGl2ZTtlLmZyb21CdWZmZXJBdHRyaWJ1dGUocyx0KTtjb25zdCBhPXRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzO2lmKHImJmEpe01zLnNldCgwLDAsMCk7Zm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPWFbY10sdT1yW2NdO2ghPT0wJiYoX28uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LHQpLG8/TXMuYWRkU2NhbGVkVmVjdG9yKF9vLGgpOk1zLmFkZFNjYWxlZFZlY3Rvcihfby5zdWIoZSksaCkpfWUuYWRkKE1zKX1yZXR1cm4gZX1yYXljYXN0KHQsZSl7Y29uc3Qgbj10aGlzLmdlb21ldHJ5LHM9dGhpcy5tYXRlcmlhbCxyPXRoaXMubWF0cml4V29ybGQ7cyE9PXZvaWQgMCYmKG4uYm91bmRpbmdTcGhlcmU9PT1udWxsJiZuLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpLGdzLmNvcHkobi5ib3VuZGluZ1NwaGVyZSksZ3MuYXBwbHlNYXRyaXg0KHIpLGZuLmNvcHkodC5yYXkpLnJlY2FzdCh0Lm5lYXIpLCEoZ3MuY29udGFpbnNQb2ludChmbi5vcmlnaW4pPT09ITEmJihmbi5pbnRlcnNlY3RTcGhlcmUoZ3MsT2MpPT09bnVsbHx8Zm4ub3JpZ2luLmRpc3RhbmNlVG9TcXVhcmVkKE9jKT55aSh0LmZhci10Lm5lYXIsMikpKSYmKExjLmNvcHkocikuaW52ZXJ0KCksZm4uY29weSh0LnJheSkuYXBwbHlNYXRyaXg0KExjKSwhKG4uYm91bmRpbmdCb3ghPT1udWxsJiZmbi5pbnRlcnNlY3RzQm94KG4uYm91bmRpbmdCb3gpPT09ITEpJiZ0aGlzLl9jb21wdXRlSW50ZXJzZWN0aW9ucyh0LGUsZm4pKSl9X2NvbXB1dGVJbnRlcnNlY3Rpb25zKHQsZSxuKXtsZXQgcztjb25zdCByPXRoaXMuZ2VvbWV0cnksbz10aGlzLm1hdGVyaWFsLGE9ci5pbmRleCxjPXIuYXR0cmlidXRlcy5wb3NpdGlvbixsPXIuYXR0cmlidXRlcy51dixoPXIuYXR0cmlidXRlcy51djEsdT1yLmF0dHJpYnV0ZXMubm9ybWFsLGY9ci5ncm91cHMsZD1yLmRyYXdSYW5nZTtpZihhIT09bnVsbClpZihBcnJheS5pc0FycmF5KG8pKWZvcihsZXQgcD0wLHk9Zi5sZW5ndGg7cDx5O3ArKyl7Y29uc3QgbT1mW3BdLGc9b1ttLm1hdGVyaWFsSW5kZXhdLGI9TWF0aC5tYXgobS5zdGFydCxkLnN0YXJ0KSx3PU1hdGgubWluKGEuY291bnQsTWF0aC5taW4obS5zdGFydCttLmNvdW50LGQuc3RhcnQrZC5jb3VudCkpO2ZvcihsZXQgeD1iLE09dzt4PE07eCs9Myl7Y29uc3QgQT1hLmdldFgoeCksUz1hLmdldFgoeCsxKSxfPWEuZ2V0WCh4KzIpO3M9U3ModGhpcyxnLHQsbixsLGgsdSxBLFMsXykscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IoeC8zKSxzLmZhY2UubWF0ZXJpYWxJbmRleD1tLm1hdGVyaWFsSW5kZXgsZS5wdXNoKHMpKX19ZWxzZXtjb25zdCBwPU1hdGgubWF4KDAsZC5zdGFydCkseT1NYXRoLm1pbihhLmNvdW50LGQuc3RhcnQrZC5jb3VudCk7Zm9yKGxldCBtPXAsZz15O208ZzttKz0zKXtjb25zdCBiPWEuZ2V0WChtKSx3PWEuZ2V0WChtKzEpLHg9YS5nZXRYKG0rMik7cz1Tcyh0aGlzLG8sdCxuLGwsaCx1LGIsdyx4KSxzJiYocy5mYWNlSW5kZXg9TWF0aC5mbG9vcihtLzMpLGUucHVzaChzKSl9fWVsc2UgaWYoYyE9PXZvaWQgMClpZihBcnJheS5pc0FycmF5KG8pKWZvcihsZXQgcD0wLHk9Zi5sZW5ndGg7cDx5O3ArKyl7Y29uc3QgbT1mW3BdLGc9b1ttLm1hdGVyaWFsSW5kZXhdLGI9TWF0aC5tYXgobS5zdGFydCxkLnN0YXJ0KSx3PU1hdGgubWluKGMuY291bnQsTWF0aC5taW4obS5zdGFydCttLmNvdW50LGQuc3RhcnQrZC5jb3VudCkpO2ZvcihsZXQgeD1iLE09dzt4PE07eCs9Myl7Y29uc3QgQT14LFM9eCsxLF89eCsyO3M9U3ModGhpcyxnLHQsbixsLGgsdSxBLFMsXykscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IoeC8zKSxzLmZhY2UubWF0ZXJpYWxJbmRleD1tLm1hdGVyaWFsSW5kZXgsZS5wdXNoKHMpKX19ZWxzZXtjb25zdCBwPU1hdGgubWF4KDAsZC5zdGFydCkseT1NYXRoLm1pbihjLmNvdW50LGQuc3RhcnQrZC5jb3VudCk7Zm9yKGxldCBtPXAsZz15O208ZzttKz0zKXtjb25zdCBiPW0sdz1tKzEseD1tKzI7cz1Tcyh0aGlzLG8sdCxuLGwsaCx1LGIsdyx4KSxzJiYocy5mYWNlSW5kZXg9TWF0aC5mbG9vcihtLzMpLGUucHVzaChzKSl9fX19ZnVuY3Rpb24gTWYoaSx0LGUsbixzLHIsbyxhKXtsZXQgYztpZih0LnNpZGU9PT0xP2M9bi5pbnRlcnNlY3RUcmlhbmdsZShvLHIscywhMCxhKTpjPW4uaW50ZXJzZWN0VHJpYW5nbGUocyxyLG8sdC5zaWRlPT09MCxhKSxjPT09bnVsbClyZXR1cm4gbnVsbDtBcy5jb3B5KGEpLEFzLmFwcGx5TWF0cml4NChpLm1hdHJpeFdvcmxkKTtjb25zdCBsPWUucmF5Lm9yaWdpbi5kaXN0YW5jZVRvKEFzKTtyZXR1cm4gbDxlLm5lYXJ8fGw+ZS5mYXI/bnVsbDp7ZGlzdGFuY2U6bCxwb2ludDpBcy5jbG9uZSgpLG9iamVjdDppfX1mdW5jdGlvbiBTcyhpLHQsZSxuLHMscixvLGEsYyxsKXtpLmdldFZlcnRleFBvc2l0aW9uKGEseHMpLGkuZ2V0VmVydGV4UG9zaXRpb24oYyx3cyksaS5nZXRWZXJ0ZXhQb3NpdGlvbihsLGJzKTtjb25zdCBoPU1mKGksdCxlLG4seHMsd3MsYnMsRGMpO2lmKGgpe2NvbnN0IHU9bmV3IFQ7ZXQuZ2V0QmFyeWNvb3JkKERjLHhzLHdzLGJzLHUpLHMmJihoLnV2PWV0LmdldEludGVycG9sYXRlZEF0dHJpYnV0ZShzLGEsYyxsLHUsbmV3IFIpKSxyJiYoaC51djE9ZXQuZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKHIsYSxjLGwsdSxuZXcgUikpLG8mJihoLm5vcm1hbD1ldC5nZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUobyxhLGMsbCx1LG5ldyBUKSxoLm5vcm1hbC5kb3Qobi5kaXJlY3Rpb24pPjAmJmgubm9ybWFsLm11bHRpcGx5U2NhbGFyKC0xKSk7Y29uc3QgZj17YSxiOmMsYzpsLG5vcm1hbDpuZXcgVCxtYXRlcmlhbEluZGV4OjB9O2V0LmdldE5vcm1hbCh4cyx3cyxicyxmLm5vcm1hbCksaC5mYWNlPWYsaC5iYXJ5Y29vcmQ9dX1yZXR1cm4gaH1jb25zdCB2bz1uZXcgVCxBZj1uZXcgVCxTZj1uZXcgZ2U7Y2xhc3Mgem97Y29uc3RydWN0b3IodD1uZXcgVCgxLDAsMCksZT0wKXt0aGlzLmlzUGxhbmU9ITAsdGhpcy5ub3JtYWw9dCx0aGlzLmNvbnN0YW50PWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsLmNvcHkodCksdGhpcy5jb25zdGFudD1lLHRoaXN9c2V0Q29tcG9uZW50cyh0LGUsbixzKXtyZXR1cm4gdGhpcy5ub3JtYWwuc2V0KHQsZSxuKSx0aGlzLmNvbnN0YW50PXMsdGhpc31zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbC5jb3B5KHQpLHRoaXMuY29uc3RhbnQ9LWUuZG90KHRoaXMubm9ybWFsKSx0aGlzfXNldEZyb21Db3BsYW5hclBvaW50cyh0LGUsbil7Y29uc3Qgcz12by5zdWJWZWN0b3JzKG4sZSkuY3Jvc3MoQWYuc3ViVmVjdG9ycyh0LGUpKS5ub3JtYWxpemUoKTtyZXR1cm4gdGhpcy5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChzLHQpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5ub3JtYWwuY29weSh0Lm5vcm1hbCksdGhpcy5jb25zdGFudD10LmNvbnN0YW50LHRoaXN9bm9ybWFsaXplKCl7Y29uc3QgdD0xL3RoaXMubm9ybWFsLmxlbmd0aCgpO3JldHVybiB0aGlzLm5vcm1hbC5tdWx0aXBseVNjYWxhcih0KSx0aGlzLmNvbnN0YW50Kj10LHRoaXN9bmVnYXRlKCl7cmV0dXJuIHRoaXMuY29uc3RhbnQqPS0xLHRoaXMubm9ybWFsLm5lZ2F0ZSgpLHRoaXN9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiB0aGlzLm5vcm1hbC5kb3QodCkrdGhpcy5jb25zdGFudH1kaXN0YW5jZVRvU3BoZXJlKHQpe3JldHVybiB0aGlzLmRpc3RhbmNlVG9Qb2ludCh0LmNlbnRlciktdC5yYWRpdXN9cHJvamVjdFBvaW50KHQsZSl7cmV0dXJuIGUuY29weSh0KS5hZGRTY2FsZWRWZWN0b3IodGhpcy5ub3JtYWwsLXRoaXMuZGlzdGFuY2VUb1BvaW50KHQpKX1pbnRlcnNlY3RMaW5lKHQsZSl7Y29uc3Qgbj10LmRlbHRhKHZvKSxzPXRoaXMubm9ybWFsLmRvdChuKTtpZihzPT09MClyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQodC5zdGFydCk9PT0wP2UuY29weSh0LnN0YXJ0KTpudWxsO2NvbnN0IHI9LSh0LnN0YXJ0LmRvdCh0aGlzLm5vcm1hbCkrdGhpcy5jb25zdGFudCkvcztyZXR1cm4gcjwwfHxyPjE/bnVsbDplLmNvcHkodC5zdGFydCkuYWRkU2NhbGVkVmVjdG9yKG4scil9aW50ZXJzZWN0c0xpbmUodCl7Y29uc3QgZT10aGlzLmRpc3RhbmNlVG9Qb2ludCh0LnN0YXJ0KSxuPXRoaXMuZGlzdGFuY2VUb1BvaW50KHQuZW5kKTtyZXR1cm4gZTwwJiZuPjB8fG48MCYmZT4wfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1BsYW5lKHRoaXMpfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHQuaW50ZXJzZWN0c1BsYW5lKHRoaXMpfWNvcGxhbmFyUG9pbnQodCl7cmV0dXJuIHQuY29weSh0aGlzLm5vcm1hbCkubXVsdGlwbHlTY2FsYXIoLXRoaXMuY29uc3RhbnQpfWFwcGx5TWF0cml4NCh0LGUpe2NvbnN0IG49ZXx8U2YuZ2V0Tm9ybWFsTWF0cml4KHQpLHM9dGhpcy5jb3BsYW5hclBvaW50KHZvKS5hcHBseU1hdHJpeDQodCkscj10aGlzLm5vcm1hbC5hcHBseU1hdHJpeDMobikubm9ybWFsaXplKCk7cmV0dXJuIHRoaXMuY29uc3RhbnQ9LXMuZG90KHIpLHRoaXN9dHJhbnNsYXRlKHQpe3JldHVybiB0aGlzLmNvbnN0YW50LT10LmRvdCh0aGlzLm5vcm1hbCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQubm9ybWFsLmVxdWFscyh0aGlzLm5vcm1hbCkmJnQuY29uc3RhbnQ9PT10aGlzLmNvbnN0YW50fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX19bGV0IHhlPWNsYXNze2NvbnN0cnVjdG9yKCl7dGhpcy50eXBlPSJDdXJ2ZSIsdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9MjAwLHRoaXMubmVlZHNVcGRhdGU9ITEsdGhpcy5jYWNoZUFyY0xlbmd0aHM9bnVsbH1nZXRQb2ludCgpe2NvbnNvbGUud2FybigiVEhSRUUuQ3VydmU6IC5nZXRQb2ludCgpIG5vdCBpbXBsZW1lbnRlZC4iKX1nZXRQb2ludEF0KHQsZSl7Y29uc3Qgbj10aGlzLmdldFV0b1RtYXBwaW5nKHQpO3JldHVybiB0aGlzLmdldFBvaW50KG4sZSl9Z2V0UG9pbnRzKHQ9NSl7Y29uc3QgZT1bXTtmb3IobGV0IG49MDtuPD10O24rKyllLnB1c2godGhpcy5nZXRQb2ludChuL3QpKTtyZXR1cm4gZX1nZXRTcGFjZWRQb2ludHModD01KXtjb25zdCBlPVtdO2ZvcihsZXQgbj0wO248PXQ7bisrKWUucHVzaCh0aGlzLmdldFBvaW50QXQobi90KSk7cmV0dXJuIGV9Z2V0TGVuZ3RoKCl7Y29uc3QgdD10aGlzLmdldExlbmd0aHMoKTtyZXR1cm4gdFt0Lmxlbmd0aC0xXX1nZXRMZW5ndGhzKHQ9dGhpcy5hcmNMZW5ndGhEaXZpc2lvbnMpe2lmKHRoaXMuY2FjaGVBcmNMZW5ndGhzJiZ0aGlzLmNhY2hlQXJjTGVuZ3Rocy5sZW5ndGg9PT10KzEmJiF0aGlzLm5lZWRzVXBkYXRlKXJldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3Roczt0aGlzLm5lZWRzVXBkYXRlPSExO2NvbnN0IGU9W107bGV0IG4scz10aGlzLmdldFBvaW50KDApLHI9MDtlLnB1c2goMCk7Zm9yKGxldCBvPTE7bzw9dDtvKyspbj10aGlzLmdldFBvaW50KG8vdCkscis9bi5kaXN0YW5jZVRvKHMpLGUucHVzaChyKSxzPW47cmV0dXJuIHRoaXMuY2FjaGVBcmNMZW5ndGhzPWUsZX11cGRhdGVBcmNMZW5ndGhzKCl7dGhpcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLmdldExlbmd0aHMoKX1nZXRVdG9UbWFwcGluZyh0LGU9bnVsbCl7Y29uc3Qgbj10aGlzLmdldExlbmd0aHMoKTtsZXQgcz0wO2NvbnN0IHI9bi5sZW5ndGg7bGV0IG87ZT9vPWU6bz10Km5bci0xXTtsZXQgYT0wLGM9ci0xLGw7Zm9yKDthPD1jOylpZihzPU1hdGguZmxvb3IoYSsoYy1hKS8yKSxsPW5bc10tbyxsPDApYT1zKzE7ZWxzZSBpZihsPjApYz1zLTE7ZWxzZXtjPXM7YnJlYWt9aWYocz1jLG5bc109PT1vKXJldHVybiBzLyhyLTEpO2NvbnN0IGg9bltzXSxmPW5bcysxXS1oLGQ9KG8taCkvZjtyZXR1cm4ocytkKS8oci0xKX1nZXRUYW5nZW50KHQsZSl7bGV0IHM9dC0xZS00LHI9dCsxZS00O3M8MCYmKHM9MCkscj4xJiYocj0xKTtjb25zdCBvPXRoaXMuZ2V0UG9pbnQocyksYT10aGlzLmdldFBvaW50KHIpLGM9ZXx8KG8uaXNWZWN0b3IyP25ldyBSOm5ldyBUKTtyZXR1cm4gYy5jb3B5KGEpLnN1YihvKS5ub3JtYWxpemUoKSxjfWdldFRhbmdlbnRBdCh0LGUpe2NvbnN0IG49dGhpcy5nZXRVdG9UbWFwcGluZyh0KTtyZXR1cm4gdGhpcy5nZXRUYW5nZW50KG4sZSl9Y29tcHV0ZUZyZW5ldEZyYW1lcyh0LGU9ITEpe2NvbnN0IG49bmV3IFQscz1bXSxyPVtdLG89W10sYT1uZXcgVCxjPW5ldyBzdDtmb3IobGV0IGQ9MDtkPD10O2QrKyl7Y29uc3QgcD1kL3Q7c1tkXT10aGlzLmdldFRhbmdlbnRBdChwLG5ldyBUKX1yWzBdPW5ldyBULG9bMF09bmV3IFQ7bGV0IGw9TnVtYmVyLk1BWF9WQUxVRTtjb25zdCBoPU1hdGguYWJzKHNbMF0ueCksdT1NYXRoLmFicyhzWzBdLnkpLGY9TWF0aC5hYnMoc1swXS56KTtoPD1sJiYobD1oLG4uc2V0KDEsMCwwKSksdTw9bCYmKGw9dSxuLnNldCgwLDEsMCkpLGY8PWwmJm4uc2V0KDAsMCwxKSxhLmNyb3NzVmVjdG9ycyhzWzBdLG4pLm5vcm1hbGl6ZSgpLHJbMF0uY3Jvc3NWZWN0b3JzKHNbMF0sYSksb1swXS5jcm9zc1ZlY3RvcnMoc1swXSxyWzBdKTtmb3IobGV0IGQ9MTtkPD10O2QrKyl7aWYocltkXT1yW2QtMV0uY2xvbmUoKSxvW2RdPW9bZC0xXS5jbG9uZSgpLGEuY3Jvc3NWZWN0b3JzKHNbZC0xXSxzW2RdKSxhLmxlbmd0aCgpPk51bWJlci5FUFNJTE9OKXthLm5vcm1hbGl6ZSgpO2NvbnN0IHA9TWF0aC5hY29zKFooc1tkLTFdLmRvdChzW2RdKSwtMSwxKSk7cltkXS5hcHBseU1hdHJpeDQoYy5tYWtlUm90YXRpb25BeGlzKGEscCkpfW9bZF0uY3Jvc3NWZWN0b3JzKHNbZF0scltkXSl9aWYoZT09PSEwKXtsZXQgZD1NYXRoLmFjb3MoWihyWzBdLmRvdChyW3RdKSwtMSwxKSk7ZC89dCxzWzBdLmRvdChhLmNyb3NzVmVjdG9ycyhyWzBdLHJbdF0pKT4wJiYoZD0tZCk7Zm9yKGxldCBwPTE7cDw9dDtwKyspcltwXS5hcHBseU1hdHJpeDQoYy5tYWtlUm90YXRpb25BeGlzKHNbcF0sZCpwKSksb1twXS5jcm9zc1ZlY3RvcnMoc1twXSxyW3BdKX1yZXR1cm57dGFuZ2VudHM6cyxub3JtYWxzOnIsYmlub3JtYWxzOm99fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLmFyY0xlbmd0aERpdmlzaW9ucz10LmFyY0xlbmd0aERpdmlzaW9ucyx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJDdXJ2ZSIsZ2VuZXJhdG9yOiJDdXJ2ZS50b0pTT04ifX07cmV0dXJuIHQuYXJjTGVuZ3RoRGl2aXNpb25zPXRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zLHQudHlwZT10aGlzLnR5cGUsdH1mcm9tSlNPTih0KXtyZXR1cm4gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9dC5hcmNMZW5ndGhEaXZpc2lvbnMsdGhpc319O2NsYXNzIF9zIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IodD0wLGU9MCxuPTEscz0xLHI9MCxvPU1hdGguUEkqMixhPSExLGM9MCl7c3VwZXIoKSx0aGlzLmlzRWxsaXBzZUN1cnZlPSEwLHRoaXMudHlwZT0iRWxsaXBzZUN1cnZlIix0aGlzLmFYPXQsdGhpcy5hWT1lLHRoaXMueFJhZGl1cz1uLHRoaXMueVJhZGl1cz1zLHRoaXMuYVN0YXJ0QW5nbGU9cix0aGlzLmFFbmRBbmdsZT1vLHRoaXMuYUNsb2Nrd2lzZT1hLHRoaXMuYVJvdGF0aW9uPWN9Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz1NYXRoLlBJKjI7bGV0IHI9dGhpcy5hRW5kQW5nbGUtdGhpcy5hU3RhcnRBbmdsZTtjb25zdCBvPU1hdGguYWJzKHIpPE51bWJlci5FUFNJTE9OO2Zvcig7cjwwOylyKz1zO2Zvcig7cj5zOylyLT1zO3I8TnVtYmVyLkVQU0lMT04mJihvP3I9MDpyPXMpLHRoaXMuYUNsb2Nrd2lzZT09PSEwJiYhbyYmKHI9PT1zP3I9LXM6cj1yLXMpO2NvbnN0IGE9dGhpcy5hU3RhcnRBbmdsZSt0KnI7bGV0IGM9dGhpcy5hWCt0aGlzLnhSYWRpdXMqTWF0aC5jb3MoYSksbD10aGlzLmFZK3RoaXMueVJhZGl1cypNYXRoLnNpbihhKTtpZih0aGlzLmFSb3RhdGlvbiE9PTApe2NvbnN0IGg9TWF0aC5jb3ModGhpcy5hUm90YXRpb24pLHU9TWF0aC5zaW4odGhpcy5hUm90YXRpb24pLGY9Yy10aGlzLmFYLGQ9bC10aGlzLmFZO2M9ZipoLWQqdSt0aGlzLmFYLGw9Zip1K2QqaCt0aGlzLmFZfXJldHVybiBuLnNldChjLGwpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5hWD10LmFYLHRoaXMuYVk9dC5hWSx0aGlzLnhSYWRpdXM9dC54UmFkaXVzLHRoaXMueVJhZGl1cz10LnlSYWRpdXMsdGhpcy5hU3RhcnRBbmdsZT10LmFTdGFydEFuZ2xlLHRoaXMuYUVuZEFuZ2xlPXQuYUVuZEFuZ2xlLHRoaXMuYUNsb2Nrd2lzZT10LmFDbG9ja3dpc2UsdGhpcy5hUm90YXRpb249dC5hUm90YXRpb24sdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LmFYPXRoaXMuYVgsdC5hWT10aGlzLmFZLHQueFJhZGl1cz10aGlzLnhSYWRpdXMsdC55UmFkaXVzPXRoaXMueVJhZGl1cyx0LmFTdGFydEFuZ2xlPXRoaXMuYVN0YXJ0QW5nbGUsdC5hRW5kQW5nbGU9dGhpcy5hRW5kQW5nbGUsdC5hQ2xvY2t3aXNlPXRoaXMuYUNsb2Nrd2lzZSx0LmFSb3RhdGlvbj10aGlzLmFSb3RhdGlvbix0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLmFYPXQuYVgsdGhpcy5hWT10LmFZLHRoaXMueFJhZGl1cz10LnhSYWRpdXMsdGhpcy55UmFkaXVzPXQueVJhZGl1cyx0aGlzLmFTdGFydEFuZ2xlPXQuYVN0YXJ0QW5nbGUsdGhpcy5hRW5kQW5nbGU9dC5hRW5kQW5nbGUsdGhpcy5hQ2xvY2t3aXNlPXQuYUNsb2Nrd2lzZSx0aGlzLmFSb3RhdGlvbj10LmFSb3RhdGlvbix0aGlzfX1jbGFzcyAkYyBleHRlbmRzIF9ze2NvbnN0cnVjdG9yKHQsZSxuLHMscixvKXtzdXBlcih0LGUsbixuLHMscixvKSx0aGlzLmlzQXJjQ3VydmU9ITAsdGhpcy50eXBlPSJBcmNDdXJ2ZSJ9fWZ1bmN0aW9uIFRvKCl7bGV0IGk9MCx0PTAsZT0wLG49MDtmdW5jdGlvbiBzKHIsbyxhLGMpe2k9cix0PWEsZT0tMypyKzMqby0yKmEtYyxuPTIqci0yKm8rYStjfXJldHVybntpbml0Q2F0bXVsbFJvbTpmdW5jdGlvbihyLG8sYSxjLGwpe3MobyxhLGwqKGEtciksbCooYy1vKSl9LGluaXROb251bmlmb3JtQ2F0bXVsbFJvbTpmdW5jdGlvbihyLG8sYSxjLGwsaCx1KXtsZXQgZj0oby1yKS9sLShhLXIpLyhsK2gpKyhhLW8pL2gsZD0oYS1vKS9oLShjLW8pLyhoK3UpKyhjLWEpL3U7Zio9aCxkKj1oLHMobyxhLGYsZCl9LGNhbGM6ZnVuY3Rpb24ocil7Y29uc3Qgbz1yKnIsYT1vKnI7cmV0dXJuIGkrdCpyK2UqbytuKmF9fX1jb25zdCB2cz1uZXcgVCxFbz1uZXcgVG8sUG89bmV3IFRvLENvPW5ldyBUbztjbGFzcyBWYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9W10sZT0hMSxuPSJjZW50cmlwZXRhbCIscz0uNSl7c3VwZXIoKSx0aGlzLmlzQ2F0bXVsbFJvbUN1cnZlMz0hMCx0aGlzLnR5cGU9IkNhdG11bGxSb21DdXJ2ZTMiLHRoaXMucG9pbnRzPXQsdGhpcy5jbG9zZWQ9ZSx0aGlzLmN1cnZlVHlwZT1uLHRoaXMudGVuc2lvbj1zfWdldFBvaW50KHQsZT1uZXcgVCl7Y29uc3Qgbj1lLHM9dGhpcy5wb2ludHMscj1zLmxlbmd0aCxvPShyLSh0aGlzLmNsb3NlZD8wOjEpKSp0O2xldCBhPU1hdGguZmxvb3IobyksYz1vLWE7dGhpcy5jbG9zZWQ/YSs9YT4wPzA6KE1hdGguZmxvb3IoTWF0aC5hYnMoYSkvcikrMSkqcjpjPT09MCYmYT09PXItMSYmKGE9ci0yLGM9MSk7bGV0IGwsaDt0aGlzLmNsb3NlZHx8YT4wP2w9c1soYS0xKSVyXToodnMuc3ViVmVjdG9ycyhzWzBdLHNbMV0pLmFkZChzWzBdKSxsPXZzKTtjb25zdCB1PXNbYSVyXSxmPXNbKGErMSklcl07aWYodGhpcy5jbG9zZWR8fGErMjxyP2g9c1soYSsyKSVyXToodnMuc3ViVmVjdG9ycyhzW3ItMV0sc1tyLTJdKS5hZGQoc1tyLTFdKSxoPXZzKSx0aGlzLmN1cnZlVHlwZT09PSJjZW50cmlwZXRhbCJ8fHRoaXMuY3VydmVUeXBlPT09ImNob3JkYWwiKXtjb25zdCBkPXRoaXMuY3VydmVUeXBlPT09ImNob3JkYWwiPy41Oi4yNTtsZXQgcD1NYXRoLnBvdyhsLmRpc3RhbmNlVG9TcXVhcmVkKHUpLGQpLHk9TWF0aC5wb3codS5kaXN0YW5jZVRvU3F1YXJlZChmKSxkKSxtPU1hdGgucG93KGYuZGlzdGFuY2VUb1NxdWFyZWQoaCksZCk7eTwxZS00JiYoeT0xKSxwPDFlLTQmJihwPXkpLG08MWUtNCYmKG09eSksRW8uaW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tKGwueCx1LngsZi54LGgueCxwLHksbSksUG8uaW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tKGwueSx1LnksZi55LGgueSxwLHksbSksQ28uaW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tKGwueix1LnosZi56LGgueixwLHksbSl9ZWxzZSB0aGlzLmN1cnZlVHlwZT09PSJjYXRtdWxscm9tIiYmKEVvLmluaXRDYXRtdWxsUm9tKGwueCx1LngsZi54LGgueCx0aGlzLnRlbnNpb24pLFBvLmluaXRDYXRtdWxsUm9tKGwueSx1LnksZi55LGgueSx0aGlzLnRlbnNpb24pLENvLmluaXRDYXRtdWxsUm9tKGwueix1LnosZi56LGgueix0aGlzLnRlbnNpb24pKTtyZXR1cm4gbi5zZXQoRW8uY2FsYyhjKSxQby5jYWxjKGMpLENvLmNhbGMoYykpLG59Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzLmNsb3NlZD10LmNsb3NlZCx0aGlzLmN1cnZlVHlwZT10LmN1cnZlVHlwZSx0aGlzLnRlbnNpb249dC50ZW5zaW9uLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXRoaXMucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMucG9pbnRzW2VdO3QucG9pbnRzLnB1c2gocy50b0FycmF5KCkpfXJldHVybiB0LmNsb3NlZD10aGlzLmNsb3NlZCx0LmN1cnZlVHlwZT10aGlzLmN1cnZlVHlwZSx0LnRlbnNpb249dGhpcy50ZW5zaW9uLHR9ZnJvbUpTT04odCl7c3VwZXIuZnJvbUpTT04odCksdGhpcy5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10LnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10LnBvaW50c1tlXTt0aGlzLnBvaW50cy5wdXNoKG5ldyBUKCkuZnJvbUFycmF5KHMpKX1yZXR1cm4gdGhpcy5jbG9zZWQ9dC5jbG9zZWQsdGhpcy5jdXJ2ZVR5cGU9dC5jdXJ2ZVR5cGUsdGhpcy50ZW5zaW9uPXQudGVuc2lvbix0aGlzfX1mdW5jdGlvbiBVYyhpLHQsZSxuLHMpe2NvbnN0IHI9KG4tdCkqLjUsbz0ocy1lKSouNSxhPWkqaSxjPWkqYTtyZXR1cm4oMiplLTIqbityK28pKmMrKC0zKmUrMypuLTIqci1vKSphK3IqaStlfWZ1bmN0aW9uIF9mKGksdCl7Y29uc3QgZT0xLWk7cmV0dXJuIGUqZSp0fWZ1bmN0aW9uIHZmKGksdCl7cmV0dXJuIDIqKDEtaSkqaSp0fWZ1bmN0aW9uIHpmKGksdCl7cmV0dXJuIGkqaSp0fWZ1bmN0aW9uIFNpKGksdCxlLG4pe3JldHVybiBfZihpLHQpK3ZmKGksZSkremYoaSxuKX1mdW5jdGlvbiBUZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiBlKmUqZSp0fWZ1bmN0aW9uIEVmKGksdCl7Y29uc3QgZT0xLWk7cmV0dXJuIDMqZSplKmkqdH1mdW5jdGlvbiBQZihpLHQpe3JldHVybiAzKigxLWkpKmkqaSp0fWZ1bmN0aW9uIENmKGksdCl7cmV0dXJuIGkqaSppKnR9ZnVuY3Rpb24gX2koaSx0LGUsbixzKXtyZXR1cm4gVGYoaSx0KStFZihpLGUpK1BmKGksbikrQ2YoaSxzKX1jbGFzcyBCbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFIsZT1uZXcgUixuPW5ldyBSLHM9bmV3IFIpe3N1cGVyKCksdGhpcy5pc0N1YmljQmV6aWVyQ3VydmU9ITAsdGhpcy50eXBlPSJDdWJpY0JlemllckN1cnZlIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bix0aGlzLnYzPXN9Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjIsYT10aGlzLnYzO3JldHVybiBuLnNldChfaSh0LHMueCxyLngsby54LGEueCksX2kodCxzLnksci55LG8ueSxhLnkpKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpcy52My5jb3B5KHQudjMpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdC52Mz10aGlzLnYzLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzLnYzLmZyb21BcnJheSh0LnYzKSx0aGlzfX1jbGFzcyBxYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCxuPW5ldyBULHM9bmV3IFQpe3N1cGVyKCksdGhpcy5pc0N1YmljQmV6aWVyQ3VydmUzPSEwLHRoaXMudHlwZT0iQ3ViaWNCZXppZXJDdXJ2ZTMiLHRoaXMudjA9dCx0aGlzLnYxPWUsdGhpcy52Mj1uLHRoaXMudjM9c31nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZSxzPXRoaXMudjAscj10aGlzLnYxLG89dGhpcy52MixhPXRoaXMudjM7cmV0dXJuIG4uc2V0KF9pKHQscy54LHIueCxvLngsYS54KSxfaSh0LHMueSxyLnksby55LGEueSksX2kodCxzLnosci56LG8ueixhLnopKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpcy52My5jb3B5KHQudjMpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdC52Mz10aGlzLnYzLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzLnYzLmZyb21BcnJheSh0LnYzKSx0aGlzfX1jbGFzcyBGbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFIsZT1uZXcgUil7c3VwZXIoKSx0aGlzLmlzTGluZUN1cnZlPSEwLHRoaXMudHlwZT0iTGluZUN1cnZlIix0aGlzLnYxPXQsdGhpcy52Mj1lfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lO3JldHVybiB0PT09MT9uLmNvcHkodGhpcy52Mik6KG4uY29weSh0aGlzLnYyKS5zdWIodGhpcy52MSksbi5tdWx0aXBseVNjYWxhcih0KS5hZGQodGhpcy52MSkpLG59Z2V0UG9pbnRBdCh0LGUpe3JldHVybiB0aGlzLmdldFBvaW50KHQsZSl9Z2V0VGFuZ2VudCh0LGU9bmV3IFIpe3JldHVybiBlLnN1YlZlY3RvcnModGhpcy52Mix0aGlzLnYxKS5ub3JtYWxpemUoKX1nZXRUYW5nZW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRUYW5nZW50KHQsZSl9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHR9ZnJvbUpTT04odCl7cmV0dXJuIHN1cGVyLmZyb21KU09OKHQpLHRoaXMudjEuZnJvbUFycmF5KHQudjEpLHRoaXMudjIuZnJvbUFycmF5KHQudjIpLHRoaXN9fWNsYXNzIEhjIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNMaW5lQ3VydmUzPSEwLHRoaXMudHlwZT0iTGluZUN1cnZlMyIsdGhpcy52MT10LHRoaXMudjI9ZX1nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZTtyZXR1cm4gdD09PTE/bi5jb3B5KHRoaXMudjIpOihuLmNvcHkodGhpcy52Mikuc3ViKHRoaXMudjEpLG4ubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMudjEpKSxufWdldFBvaW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRQb2ludCh0LGUpfWdldFRhbmdlbnQodCxlPW5ldyBUKXtyZXR1cm4gZS5zdWJWZWN0b3JzKHRoaXMudjIsdGhpcy52MSkubm9ybWFsaXplKCl9Z2V0VGFuZ2VudEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudCh0LGUpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBJbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFIsZT1uZXcgUixuPW5ldyBSKXtzdXBlcigpLHRoaXMuaXNRdWFkcmF0aWNCZXppZXJDdXJ2ZT0hMCx0aGlzLnR5cGU9IlF1YWRyYXRpY0JlemllckN1cnZlIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bn1nZXRQb2ludCh0LGU9bmV3IFIpe2NvbnN0IG49ZSxzPXRoaXMudjAscj10aGlzLnYxLG89dGhpcy52MjtyZXR1cm4gbi5zZXQoU2kodCxzLngsci54LG8ueCksU2kodCxzLnksci55LG8ueSkpLG59Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnYwLmNvcHkodC52MCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHR9ZnJvbUpTT04odCl7cmV0dXJuIHN1cGVyLmZyb21KU09OKHQpLHRoaXMudjAuZnJvbUFycmF5KHQudjApLHRoaXMudjEuZnJvbUFycmF5KHQudjEpLHRoaXMudjIuZnJvbUFycmF5KHQudjIpLHRoaXN9fWNsYXNzIFdjIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBULG49bmV3IFQpe3N1cGVyKCksdGhpcy5pc1F1YWRyYXRpY0JlemllckN1cnZlMz0hMCx0aGlzLnR5cGU9IlF1YWRyYXRpY0JlemllckN1cnZlMyIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW59Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjI7cmV0dXJuIG4uc2V0KFNpKHQscy54LHIueCxvLngpLFNpKHQscy55LHIueSxvLnkpLFNpKHQscy56LHIueixvLnopKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYwPXRoaXMudjAudG9BcnJheSgpLHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBrbyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9W10pe3N1cGVyKCksdGhpcy5pc1NwbGluZUN1cnZlPSEwLHRoaXMudHlwZT0iU3BsaW5lQ3VydmUiLHRoaXMucG9pbnRzPXR9Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnBvaW50cyxyPShzLmxlbmd0aC0xKSp0LG89TWF0aC5mbG9vcihyKSxhPXItbyxjPXNbbz09PTA/bzpvLTFdLGw9c1tvXSxoPXNbbz5zLmxlbmd0aC0yP3MubGVuZ3RoLTE6bysxXSx1PXNbbz5zLmxlbmd0aC0zP3MubGVuZ3RoLTE6bysyXTtyZXR1cm4gbi5zZXQoVWMoYSxjLngsbC54LGgueCx1LngpLFVjKGEsYy55LGwueSxoLnksdS55KSksbn1jb3B5KHQpe3N1cGVyLmNvcHkodCksdGhpcy5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10LnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10LnBvaW50c1tlXTt0aGlzLnBvaW50cy5wdXNoKHMuY2xvbmUoKSl9cmV0dXJuIHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXRoaXMucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMucG9pbnRzW2VdO3QucG9pbnRzLnB1c2gocy50b0FycmF5KCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChuZXcgUigpLmZyb21BcnJheShzKSl9cmV0dXJuIHRoaXN9fXZhciBHYz1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxBcmNDdXJ2ZTokYyxDYXRtdWxsUm9tQ3VydmUzOlZjLEN1YmljQmV6aWVyQ3VydmU6Qm8sQ3ViaWNCZXppZXJDdXJ2ZTM6cWMsRWxsaXBzZUN1cnZlOl9zLExpbmVDdXJ2ZTpGbyxMaW5lQ3VydmUzOkhjLFF1YWRyYXRpY0JlemllckN1cnZlOklvLFF1YWRyYXRpY0JlemllckN1cnZlMzpXYyxTcGxpbmVDdXJ2ZTprb30pO2NsYXNzIEJmIGV4dGVuZHMgeGV7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMudHlwZT0iQ3VydmVQYXRoIix0aGlzLmN1cnZlcz1bXSx0aGlzLmF1dG9DbG9zZT0hMX1hZGQodCl7dGhpcy5jdXJ2ZXMucHVzaCh0KX1jbG9zZVBhdGgoKXtjb25zdCB0PXRoaXMuY3VydmVzWzBdLmdldFBvaW50KDApLGU9dGhpcy5jdXJ2ZXNbdGhpcy5jdXJ2ZXMubGVuZ3RoLTFdLmdldFBvaW50KDEpO2lmKCF0LmVxdWFscyhlKSl7Y29uc3Qgbj10LmlzVmVjdG9yMj09PSEwPyJMaW5lQ3VydmUiOiJMaW5lQ3VydmUzIjt0aGlzLmN1cnZlcy5wdXNoKG5ldyBHY1tuXShlLHQpKX1yZXR1cm4gdGhpc31nZXRQb2ludCh0LGUpe2NvbnN0IG49dCp0aGlzLmdldExlbmd0aCgpLHM9dGhpcy5nZXRDdXJ2ZUxlbmd0aHMoKTtsZXQgcj0wO2Zvcig7cjxzLmxlbmd0aDspe2lmKHNbcl0+PW4pe2NvbnN0IG89c1tyXS1uLGE9dGhpcy5jdXJ2ZXNbcl0sYz1hLmdldExlbmd0aCgpLGw9Yz09PTA/MDoxLW8vYztyZXR1cm4gYS5nZXRQb2ludEF0KGwsZSl9cisrfXJldHVybiBudWxsfWdldExlbmd0aCgpe2NvbnN0IHQ9dGhpcy5nZXRDdXJ2ZUxlbmd0aHMoKTtyZXR1cm4gdFt0Lmxlbmd0aC0xXX11cGRhdGVBcmNMZW5ndGhzKCl7dGhpcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLmNhY2hlTGVuZ3Rocz1udWxsLHRoaXMuZ2V0Q3VydmVMZW5ndGhzKCl9Z2V0Q3VydmVMZW5ndGhzKCl7aWYodGhpcy5jYWNoZUxlbmd0aHMmJnRoaXMuY2FjaGVMZW5ndGhzLmxlbmd0aD09PXRoaXMuY3VydmVzLmxlbmd0aClyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM7Y29uc3QgdD1bXTtsZXQgZT0wO2ZvcihsZXQgbj0wLHM9dGhpcy5jdXJ2ZXMubGVuZ3RoO248cztuKyspZSs9dGhpcy5jdXJ2ZXNbbl0uZ2V0TGVuZ3RoKCksdC5wdXNoKGUpO3JldHVybiB0aGlzLmNhY2hlTGVuZ3Rocz10LHR9Z2V0U3BhY2VkUG9pbnRzKHQ9NDApe2NvbnN0IGU9W107Zm9yKGxldCBuPTA7bjw9dDtuKyspZS5wdXNoKHRoaXMuZ2V0UG9pbnQobi90KSk7cmV0dXJuIHRoaXMuYXV0b0Nsb3NlJiZlLnB1c2goZVswXSksZX1nZXRQb2ludHModD0xMil7Y29uc3QgZT1bXTtsZXQgbjtmb3IobGV0IHM9MCxyPXRoaXMuY3VydmVzO3M8ci5sZW5ndGg7cysrKXtjb25zdCBvPXJbc10sYT1vLmlzRWxsaXBzZUN1cnZlP3QqMjpvLmlzTGluZUN1cnZlfHxvLmlzTGluZUN1cnZlMz8xOm8uaXNTcGxpbmVDdXJ2ZT90Km8ucG9pbnRzLmxlbmd0aDp0LGM9by5nZXRQb2ludHMoYSk7Zm9yKGxldCBsPTA7bDxjLmxlbmd0aDtsKyspe2NvbnN0IGg9Y1tsXTtuJiZuLmVxdWFscyhoKXx8KGUucHVzaChoKSxuPWgpfX1yZXR1cm4gdGhpcy5hdXRvQ2xvc2UmJmUubGVuZ3RoPjEmJiFlW2UubGVuZ3RoLTFdLmVxdWFscyhlWzBdKSYmZS5wdXNoKGVbMF0pLGV9Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dC5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5jdXJ2ZXNbZV07dGhpcy5jdXJ2ZXMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzLmF1dG9DbG9zZT10LmF1dG9DbG9zZSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5hdXRvQ2xvc2U9dGhpcy5hdXRvQ2xvc2UsdC5jdXJ2ZXM9W107Zm9yKGxldCBlPTAsbj10aGlzLmN1cnZlcy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLmN1cnZlc1tlXTt0LmN1cnZlcy5wdXNoKHMudG9KU09OKCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMuYXV0b0Nsb3NlPXQuYXV0b0Nsb3NlLHRoaXMuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dC5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5jdXJ2ZXNbZV07dGhpcy5jdXJ2ZXMucHVzaChuZXcgR2Nbcy50eXBlXSgpLmZyb21KU09OKHMpKX1yZXR1cm4gdGhpc319bGV0IFpjPWNsYXNzIGV4dGVuZHMgQmZ7Y29uc3RydWN0b3IodCl7c3VwZXIoKSx0aGlzLnR5cGU9IlBhdGgiLHRoaXMuY3VycmVudFBvaW50PW5ldyBSLHQmJnRoaXMuc2V0RnJvbVBvaW50cyh0KX1zZXRGcm9tUG9pbnRzKHQpe3RoaXMubW92ZVRvKHRbMF0ueCx0WzBdLnkpO2ZvcihsZXQgZT0xLG49dC5sZW5ndGg7ZTxuO2UrKyl0aGlzLmxpbmVUbyh0W2VdLngsdFtlXS55KTtyZXR1cm4gdGhpc31tb3ZlVG8odCxlKXtyZXR1cm4gdGhpcy5jdXJyZW50UG9pbnQuc2V0KHQsZSksdGhpc31saW5lVG8odCxlKXtjb25zdCBuPW5ldyBGbyh0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLG5ldyBSKHQsZSkpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKG4pLHRoaXMuY3VycmVudFBvaW50LnNldCh0LGUpLHRoaXN9cXVhZHJhdGljQ3VydmVUbyh0LGUsbixzKXtjb25zdCByPW5ldyBJbyh0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLG5ldyBSKHQsZSksbmV3IFIobixzKSk7cmV0dXJuIHRoaXMuY3VydmVzLnB1c2gociksdGhpcy5jdXJyZW50UG9pbnQuc2V0KG4scyksdGhpc31iZXppZXJDdXJ2ZVRvKHQsZSxuLHMscixvKXtjb25zdCBhPW5ldyBCbyh0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLG5ldyBSKHQsZSksbmV3IFIobixzKSxuZXcgUihyLG8pKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChhKSx0aGlzLmN1cnJlbnRQb2ludC5zZXQocixvKSx0aGlzfXNwbGluZVRocnUodCl7Y29uc3QgZT1bdGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKV0uY29uY2F0KHQpLG49bmV3IGtvKGUpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKG4pLHRoaXMuY3VycmVudFBvaW50LmNvcHkodFt0Lmxlbmd0aC0xXSksdGhpc31hcmModCxlLG4scyxyLG8pe2NvbnN0IGE9dGhpcy5jdXJyZW50UG9pbnQueCxjPXRoaXMuY3VycmVudFBvaW50Lnk7cmV0dXJuIHRoaXMuYWJzYXJjKHQrYSxlK2MsbixzLHIsbyksdGhpc31hYnNhcmModCxlLG4scyxyLG8pe3JldHVybiB0aGlzLmFic2VsbGlwc2UodCxlLG4sbixzLHIsbyksdGhpc31lbGxpcHNlKHQsZSxuLHMscixvLGEsYyl7Y29uc3QgbD10aGlzLmN1cnJlbnRQb2ludC54LGg9dGhpcy5jdXJyZW50UG9pbnQueTtyZXR1cm4gdGhpcy5hYnNlbGxpcHNlKHQrbCxlK2gsbixzLHIsbyxhLGMpLHRoaXN9YWJzZWxsaXBzZSh0LGUsbixzLHIsbyxhLGMpe2NvbnN0IGw9bmV3IF9zKHQsZSxuLHMscixvLGEsYyk7aWYodGhpcy5jdXJ2ZXMubGVuZ3RoPjApe2NvbnN0IHU9bC5nZXRQb2ludCgwKTt1LmVxdWFscyh0aGlzLmN1cnJlbnRQb2ludCl8fHRoaXMubGluZVRvKHUueCx1LnkpfXRoaXMuY3VydmVzLnB1c2gobCk7Y29uc3QgaD1sLmdldFBvaW50KDEpO3JldHVybiB0aGlzLmN1cnJlbnRQb2ludC5jb3B5KGgpLHRoaXN9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLmN1cnJlbnRQb2ludC5jb3B5KHQuY3VycmVudFBvaW50KSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQuY3VycmVudFBvaW50PXRoaXMuY3VycmVudFBvaW50LnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLmN1cnJlbnRQb2ludC5mcm9tQXJyYXkodC5jdXJyZW50UG9pbnQpLHRoaXN9fTtjbGFzcyBYYyBleHRlbmRzIFpje2NvbnN0cnVjdG9yKHQpe3N1cGVyKHQpLHRoaXMudXVpZD1GbigpLHRoaXMudHlwZT0iU2hhcGUiLHRoaXMuaG9sZXM9W119Z2V0UG9pbnRzSG9sZXModCl7Y29uc3QgZT1bXTtmb3IobGV0IG49MCxzPXRoaXMuaG9sZXMubGVuZ3RoO248cztuKyspZVtuXT10aGlzLmhvbGVzW25dLmdldFBvaW50cyh0KTtyZXR1cm4gZX1leHRyYWN0UG9pbnRzKHQpe3JldHVybntzaGFwZTp0aGlzLmdldFBvaW50cyh0KSxob2xlczp0aGlzLmdldFBvaW50c0hvbGVzKHQpfX1jb3B5KHQpe3N1cGVyLmNvcHkodCksdGhpcy5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXQuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5ob2xlc1tlXTt0aGlzLmhvbGVzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3QudXVpZD10aGlzLnV1aWQsdC5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXRoaXMuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dGhpcy5ob2xlc1tlXTt0LmhvbGVzLnB1c2gocy50b0pTT04oKSl9cmV0dXJuIHR9ZnJvbUpTT04odCl7c3VwZXIuZnJvbUpTT04odCksdGhpcy51dWlkPXQudXVpZCx0aGlzLmhvbGVzPVtdO2ZvcihsZXQgZT0wLG49dC5ob2xlcy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10LmhvbGVzW2VdO3RoaXMuaG9sZXMucHVzaChuZXcgWmMoKS5mcm9tSlNPTihzKSl9cmV0dXJuIHRoaXN9fWZ1bmN0aW9uIEZmKGksdCxlPTIpe2NvbnN0IG49dCYmdC5sZW5ndGgscz1uP3RbMF0qZTppLmxlbmd0aDtsZXQgcj1KYyhpLDAscyxlLCEwKTtjb25zdCBvPVtdO2lmKCFyfHxyLm5leHQ9PT1yLnByZXYpcmV0dXJuIG87bGV0IGEsYyxsO2lmKG4mJihyPUxmKGksdCxyLGUpKSxpLmxlbmd0aD44MCplKXthPTEvMCxjPTEvMDtsZXQgaD0tMS8wLHU9LTEvMDtmb3IobGV0IGY9ZTtmPHM7Zis9ZSl7Y29uc3QgZD1pW2ZdLHA9aVtmKzFdO2Q8YSYmKGE9ZCkscDxjJiYoYz1wKSxkPmgmJihoPWQpLHA+dSYmKHU9cCl9bD1NYXRoLm1heChoLWEsdS1jKSxsPWwhPT0wPzMyNzY3L2w6MH1yZXR1cm4gdmkocixvLGUsYSxjLGwsMCksb31mdW5jdGlvbiBKYyhpLHQsZSxuLHMpe2xldCByO2lmKHM9PT1YZihpLHQsZSxuKT4wKWZvcihsZXQgbz10O288ZTtvKz1uKXI9S2Moby9ufDAsaVtvXSxpW28rMV0scik7ZWxzZSBmb3IobGV0IG89ZS1uO28+PXQ7by09bilyPUtjKG8vbnwwLGlbb10saVtvKzFdLHIpO3JldHVybiByJiZIbihyLHIubmV4dCkmJihFaShyKSxyPXIubmV4dCkscn1mdW5jdGlvbiBkbihpLHQpe2lmKCFpKXJldHVybiBpO3R8fCh0PWkpO2xldCBlPWksbjtkbyBpZihuPSExLCFlLnN0ZWluZXImJihIbihlLGUubmV4dCl8fHJ0KGUucHJldixlLGUubmV4dCk9PT0wKSl7aWYoRWkoZSksZT10PWUucHJldixlPT09ZS5uZXh0KWJyZWFrO249ITB9ZWxzZSBlPWUubmV4dDt3aGlsZShufHxlIT09dCk7cmV0dXJuIHR9ZnVuY3Rpb24gdmkoaSx0LGUsbixzLHIsbyl7aWYoIWkpcmV0dXJuOyFvJiZyJiZVZihpLG4scyxyKTtsZXQgYT1pO2Zvcig7aS5wcmV2IT09aS5uZXh0Oyl7Y29uc3QgYz1pLnByZXYsbD1pLm5leHQ7aWYocj9rZihpLG4scyxyKTpJZihpKSl7dC5wdXNoKGMuaSxpLmksbC5pKSxFaShpKSxpPWwubmV4dCxhPWwubmV4dDtjb250aW51ZX1pZihpPWwsaT09PWEpe28/bz09PTE/KGk9TmYoZG4oaSksdCksdmkoaSx0LGUsbixzLHIsMikpOm89PT0yJiZSZihpLHQsZSxuLHMscik6dmkoZG4oaSksdCxlLG4scyxyLDEpO2JyZWFrfX19ZnVuY3Rpb24gSWYoaSl7Y29uc3QgdD1pLnByZXYsZT1pLG49aS5uZXh0O2lmKHJ0KHQsZSxuKT49MClyZXR1cm4hMTtjb25zdCBzPXQueCxyPWUueCxvPW4ueCxhPXQueSxjPWUueSxsPW4ueSxoPU1hdGgubWluKHMscixvKSx1PU1hdGgubWluKGEsYyxsKSxmPU1hdGgubWF4KHMscixvKSxkPU1hdGgubWF4KGEsYyxsKTtsZXQgcD1uLm5leHQ7Zm9yKDtwIT09dDspe2lmKHAueD49aCYmcC54PD1mJiZwLnk+PXUmJnAueTw9ZCYmemkocyxhLHIsYyxvLGwscC54LHAueSkmJnJ0KHAucHJldixwLHAubmV4dCk+PTApcmV0dXJuITE7cD1wLm5leHR9cmV0dXJuITB9ZnVuY3Rpb24ga2YoaSx0LGUsbil7Y29uc3Qgcz1pLnByZXYscj1pLG89aS5uZXh0O2lmKHJ0KHMscixvKT49MClyZXR1cm4hMTtjb25zdCBhPXMueCxjPXIueCxsPW8ueCxoPXMueSx1PXIueSxmPW8ueSxkPU1hdGgubWluKGEsYyxsKSxwPU1hdGgubWluKGgsdSxmKSx5PU1hdGgubWF4KGEsYyxsKSxtPU1hdGgubWF4KGgsdSxmKSxnPU5vKGQscCx0LGUsbiksYj1Obyh5LG0sdCxlLG4pO2xldCB3PWkucHJldloseD1pLm5leHRaO2Zvcig7dyYmdy56Pj1nJiZ4JiZ4Lno8PWI7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmemkoYSxoLGMsdSxsLGYsdy54LHcueSkmJnJ0KHcucHJldix3LHcubmV4dCk+PTB8fCh3PXcucHJldloseC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJnppKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZydCh4LnByZXYseCx4Lm5leHQpPj0wKSlyZXR1cm4hMTt4PXgubmV4dFp9Zm9yKDt3JiZ3Lno+PWc7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmemkoYSxoLGMsdSxsLGYsdy54LHcueSkmJnJ0KHcucHJldix3LHcubmV4dCk+PTApcmV0dXJuITE7dz13LnByZXZafWZvcig7eCYmeC56PD1iOyl7aWYoeC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJnppKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZydCh4LnByZXYseCx4Lm5leHQpPj0wKXJldHVybiExO3g9eC5uZXh0Wn1yZXR1cm4hMH1mdW5jdGlvbiBOZihpLHQpe2xldCBlPWk7ZG97Y29uc3Qgbj1lLnByZXYscz1lLm5leHQubmV4dDshSG4obixzKSYmamMobixlLGUubmV4dCxzKSYmVGkobixzKSYmVGkocyxuKSYmKHQucHVzaChuLmksZS5pLHMuaSksRWkoZSksRWkoZS5uZXh0KSxlPWk9cyksZT1lLm5leHR9d2hpbGUoZSE9PWkpO3JldHVybiBkbihlKX1mdW5jdGlvbiBSZihpLHQsZSxuLHMscil7bGV0IG89aTtkb3tsZXQgYT1vLm5leHQubmV4dDtmb3IoO2EhPT1vLnByZXY7KXtpZihvLmkhPT1hLmkmJldmKG8sYSkpe2xldCBjPVFjKG8sYSk7bz1kbihvLG8ubmV4dCksYz1kbihjLGMubmV4dCksdmkobyx0LGUsbixzLHIsMCksdmkoYyx0LGUsbixzLHIsMCk7cmV0dXJufWE9YS5uZXh0fW89by5uZXh0fXdoaWxlKG8hPT1pKX1mdW5jdGlvbiBMZihpLHQsZSxuKXtjb25zdCBzPVtdO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdKm4sYz1yPG8tMT90W3IrMV0qbjppLmxlbmd0aCxsPUpjKGksYSxjLG4sITEpO2w9PT1sLm5leHQmJihsLnN0ZWluZXI9ITApLHMucHVzaChIZihsKSl9cy5zb3J0KE9mKTtmb3IobGV0IHI9MDtyPHMubGVuZ3RoO3IrKyllPURmKHNbcl0sZSk7cmV0dXJuIGV9ZnVuY3Rpb24gT2YoaSx0KXtsZXQgZT1pLngtdC54O2lmKGU9PT0wJiYoZT1pLnktdC55LGU9PT0wKSl7Y29uc3Qgbj0oaS5uZXh0LnktaS55KS8oaS5uZXh0LngtaS54KSxzPSh0Lm5leHQueS10LnkpLyh0Lm5leHQueC10LngpO2U9bi1zfXJldHVybiBlfWZ1bmN0aW9uIERmKGksdCl7Y29uc3QgZT0kZihpLHQpO2lmKCFlKXJldHVybiB0O2NvbnN0IG49UWMoZSxpKTtyZXR1cm4gZG4obixuLm5leHQpLGRuKGUsZS5uZXh0KX1mdW5jdGlvbiAkZihpLHQpe2xldCBlPXQ7Y29uc3Qgbj1pLngscz1pLnk7bGV0IHI9LTEvMCxvO2lmKEhuKGksZSkpcmV0dXJuIGU7ZG97aWYoSG4oaSxlLm5leHQpKXJldHVybiBlLm5leHQ7aWYoczw9ZS55JiZzPj1lLm5leHQueSYmZS5uZXh0LnkhPT1lLnkpe2NvbnN0IHU9ZS54KyhzLWUueSkqKGUubmV4dC54LWUueCkvKGUubmV4dC55LWUueSk7aWYodTw9biYmdT5yJiYocj11LG89ZS54PGUubmV4dC54P2U6ZS5uZXh0LHU9PT1uKSlyZXR1cm4gb31lPWUubmV4dH13aGlsZShlIT09dCk7aWYoIW8pcmV0dXJuIG51bGw7Y29uc3QgYT1vLGM9by54LGw9by55O2xldCBoPTEvMDtlPW87ZG97aWYobj49ZS54JiZlLng+PWMmJm4hPT1lLngmJlljKHM8bD9uOnIscyxjLGwsczxsP3I6bixzLGUueCxlLnkpKXtjb25zdCB1PU1hdGguYWJzKHMtZS55KS8obi1lLngpO1RpKGUsaSkmJih1PGh8fHU9PT1oJiYoZS54Pm8ueHx8ZS54PT09by54JiZWZihvLGUpKSkmJihvPWUsaD11KX1lPWUubmV4dH13aGlsZShlIT09YSk7cmV0dXJuIG99ZnVuY3Rpb24gVmYoaSx0KXtyZXR1cm4gcnQoaS5wcmV2LGksdC5wcmV2KTwwJiZydCh0Lm5leHQsaSxpLm5leHQpPDB9ZnVuY3Rpb24gVWYoaSx0LGUsbil7bGV0IHM9aTtkbyBzLno9PT0wJiYocy56PU5vKHMueCxzLnksdCxlLG4pKSxzLnByZXZaPXMucHJldixzLm5leHRaPXMubmV4dCxzPXMubmV4dDt3aGlsZShzIT09aSk7cy5wcmV2Wi5uZXh0Wj1udWxsLHMucHJldlo9bnVsbCxxZihzKX1mdW5jdGlvbiBxZihpKXtsZXQgdCxlPTE7ZG97bGV0IG49aSxzO2k9bnVsbDtsZXQgcj1udWxsO2Zvcih0PTA7bjspe3QrKztsZXQgbz1uLGE9MDtmb3IobGV0IGw9MDtsPGUmJihhKyssbz1vLm5leHRaLCEhbyk7bCsrKTtsZXQgYz1lO2Zvcig7YT4wfHxjPjAmJm87KWEhPT0wJiYoYz09PTB8fCFvfHxuLno8PW8ueik/KHM9bixuPW4ubmV4dFosYS0tKToocz1vLG89by5uZXh0WixjLS0pLHI/ci5uZXh0Wj1zOmk9cyxzLnByZXZaPXIscj1zO249b31yLm5leHRaPW51bGwsZSo9Mn13aGlsZSh0PjEpO3JldHVybiBpfWZ1bmN0aW9uIE5vKGksdCxlLG4scyl7cmV0dXJuIGk9KGktZSkqc3wwLHQ9KHQtbikqc3wwLGk9KGl8aTw8OCkmMTY3MTE5MzUsaT0oaXxpPDw0KSYyNTI2NDUxMzUsaT0oaXxpPDwyKSY4NTg5OTM0NTksaT0oaXxpPDwxKSYxNDMxNjU1NzY1LHQ9KHR8dDw8OCkmMTY3MTE5MzUsdD0odHx0PDw0KSYyNTI2NDUxMzUsdD0odHx0PDwyKSY4NTg5OTM0NTksdD0odHx0PDwxKSYxNDMxNjU1NzY1LGl8dDw8MX1mdW5jdGlvbiBIZihpKXtsZXQgdD1pLGU9aTtkbyh0Lng8ZS54fHx0Lng9PT1lLngmJnQueTxlLnkpJiYoZT10KSx0PXQubmV4dDt3aGlsZSh0IT09aSk7cmV0dXJuIGV9ZnVuY3Rpb24gWWMoaSx0LGUsbixzLHIsbyxhKXtyZXR1cm4ocy1vKSoodC1hKT49KGktbykqKHItYSkmJihpLW8pKihuLWEpPj0oZS1vKSoodC1hKSYmKGUtbykqKHItYSk+PShzLW8pKihuLWEpfWZ1bmN0aW9uIHppKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuIShpPT09byYmdD09PWEpJiZZYyhpLHQsZSxuLHMscixvLGEpfWZ1bmN0aW9uIFdmKGksdCl7cmV0dXJuIGkubmV4dC5pIT09dC5pJiZpLnByZXYuaSE9PXQuaSYmIUdmKGksdCkmJihUaShpLHQpJiZUaSh0LGkpJiZaZihpLHQpJiYocnQoaS5wcmV2LGksdC5wcmV2KXx8cnQoaSx0LnByZXYsdCkpfHxIbihpLHQpJiZydChpLnByZXYsaSxpLm5leHQpPjAmJnJ0KHQucHJldix0LHQubmV4dCk+MCl9ZnVuY3Rpb24gcnQoaSx0LGUpe3JldHVybih0LnktaS55KSooZS54LXQueCktKHQueC1pLngpKihlLnktdC55KX1mdW5jdGlvbiBIbihpLHQpe3JldHVybiBpLng9PT10LngmJmkueT09PXQueX1mdW5jdGlvbiBqYyhpLHQsZSxuKXtjb25zdCBzPVRzKHJ0KGksdCxlKSkscj1UcyhydChpLHQsbikpLG89VHMocnQoZSxuLGkpKSxhPVRzKHJ0KGUsbix0KSk7cmV0dXJuISEocyE9PXImJm8hPT1hfHxzPT09MCYmenMoaSxlLHQpfHxyPT09MCYmenMoaSxuLHQpfHxvPT09MCYmenMoZSxpLG4pfHxhPT09MCYmenMoZSx0LG4pKX1mdW5jdGlvbiB6cyhpLHQsZSl7cmV0dXJuIHQueDw9TWF0aC5tYXgoaS54LGUueCkmJnQueD49TWF0aC5taW4oaS54LGUueCkmJnQueTw9TWF0aC5tYXgoaS55LGUueSkmJnQueT49TWF0aC5taW4oaS55LGUueSl9ZnVuY3Rpb24gVHMoaSl7cmV0dXJuIGk+MD8xOmk8MD8tMTowfWZ1bmN0aW9uIEdmKGksdCl7bGV0IGU9aTtkb3tpZihlLmkhPT1pLmkmJmUubmV4dC5pIT09aS5pJiZlLmkhPT10LmkmJmUubmV4dC5pIT09dC5pJiZqYyhlLGUubmV4dCxpLHQpKXJldHVybiEwO2U9ZS5uZXh0fXdoaWxlKGUhPT1pKTtyZXR1cm4hMX1mdW5jdGlvbiBUaShpLHQpe3JldHVybiBydChpLnByZXYsaSxpLm5leHQpPDA/cnQoaSx0LGkubmV4dCk+PTAmJnJ0KGksaS5wcmV2LHQpPj0wOnJ0KGksdCxpLnByZXYpPDB8fHJ0KGksaS5uZXh0LHQpPDB9ZnVuY3Rpb24gWmYoaSx0KXtsZXQgZT1pLG49ITE7Y29uc3Qgcz0oaS54K3QueCkvMixyPShpLnkrdC55KS8yO2RvIGUueT5yIT1lLm5leHQueT5yJiZlLm5leHQueSE9PWUueSYmczwoZS5uZXh0LngtZS54KSooci1lLnkpLyhlLm5leHQueS1lLnkpK2UueCYmKG49IW4pLGU9ZS5uZXh0O3doaWxlKGUhPT1pKTtyZXR1cm4gbn1mdW5jdGlvbiBRYyhpLHQpe2NvbnN0IGU9Um8oaS5pLGkueCxpLnkpLG49Um8odC5pLHQueCx0LnkpLHM9aS5uZXh0LHI9dC5wcmV2O3JldHVybiBpLm5leHQ9dCx0LnByZXY9aSxlLm5leHQ9cyxzLnByZXY9ZSxuLm5leHQ9ZSxlLnByZXY9bixyLm5leHQ9bixuLnByZXY9cixufWZ1bmN0aW9uIEtjKGksdCxlLG4pe2NvbnN0IHM9Um8oaSx0LGUpO3JldHVybiBuPyhzLm5leHQ9bi5uZXh0LHMucHJldj1uLG4ubmV4dC5wcmV2PXMsbi5uZXh0PXMpOihzLnByZXY9cyxzLm5leHQ9cyksc31mdW5jdGlvbiBFaShpKXtpLm5leHQucHJldj1pLnByZXYsaS5wcmV2Lm5leHQ9aS5uZXh0LGkucHJldlomJihpLnByZXZaLm5leHRaPWkubmV4dFopLGkubmV4dFomJihpLm5leHRaLnByZXZaPWkucHJldlopfWZ1bmN0aW9uIFJvKGksdCxlKXtyZXR1cm57aSx4OnQseTplLHByZXY6bnVsbCxuZXh0Om51bGwsejowLHByZXZaOm51bGwsbmV4dFo6bnVsbCxzdGVpbmVyOiExfX1mdW5jdGlvbiBYZihpLHQsZSxuKXtsZXQgcz0wO2ZvcihsZXQgcj10LG89ZS1uO3I8ZTtyKz1uKXMrPShpW29dLWlbcl0pKihpW3IrMV0raVtvKzFdKSxvPXI7cmV0dXJuIHN9Y2xhc3MgSmZ7c3RhdGljIHRyaWFuZ3VsYXRlKHQsZSxuPTIpe3JldHVybiBGZih0LGUsbil9fWNsYXNzIFdue3N0YXRpYyBhcmVhKHQpe2NvbnN0IGU9dC5sZW5ndGg7bGV0IG49MDtmb3IobGV0IHM9ZS0xLHI9MDtyPGU7cz1yKyspbis9dFtzXS54KnRbcl0ueS10W3JdLngqdFtzXS55O3JldHVybiBuKi41fXN0YXRpYyBpc0Nsb2NrV2lzZSh0KXtyZXR1cm4gV24uYXJlYSh0KTwwfXN0YXRpYyB0cmlhbmd1bGF0ZVNoYXBlKHQsZSl7Y29uc3Qgbj1bXSxzPVtdLHI9W107dGwodCksZWwobix0KTtsZXQgbz10Lmxlbmd0aDtlLmZvckVhY2godGwpO2ZvcihsZXQgYz0wO2M8ZS5sZW5ndGg7YysrKXMucHVzaChvKSxvKz1lW2NdLmxlbmd0aCxlbChuLGVbY10pO2NvbnN0IGE9SmYudHJpYW5ndWxhdGUobixzKTtmb3IobGV0IGM9MDtjPGEubGVuZ3RoO2MrPTMpci5wdXNoKGEuc2xpY2UoYyxjKzMpKTtyZXR1cm4gcn19ZnVuY3Rpb24gdGwoaSl7Y29uc3QgdD1pLmxlbmd0aDt0PjImJmlbdC0xXS5lcXVhbHMoaVswXSkmJmkucG9wKCl9ZnVuY3Rpb24gZWwoaSx0KXtmb3IobGV0IGU9MDtlPHQubGVuZ3RoO2UrKylpLnB1c2godFtlXS54KSxpLnB1c2godFtlXS55KX1jbGFzcyBMbyBleHRlbmRzIHVle2NvbnN0cnVjdG9yKHQ9MSxlPTEsbj0xLHM9MSl7c3VwZXIoKSx0aGlzLnR5cGU9IlBsYW5lR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz17d2lkdGg6dCxoZWlnaHQ6ZSx3aWR0aFNlZ21lbnRzOm4saGVpZ2h0U2VnbWVudHM6c307Y29uc3Qgcj10LzIsbz1lLzIsYT1NYXRoLmZsb29yKG4pLGM9TWF0aC5mbG9vcihzKSxsPWErMSxoPWMrMSx1PXQvYSxmPWUvYyxkPVtdLHA9W10seT1bXSxtPVtdO2ZvcihsZXQgZz0wO2c8aDtnKyspe2NvbnN0IGI9ZypmLW87Zm9yKGxldCB3PTA7dzxsO3crKyl7Y29uc3QgeD13KnUtcjtwLnB1c2goeCwtYiwwKSx5LnB1c2goMCwwLDEpLG0ucHVzaCh3L2EpLG0ucHVzaCgxLWcvYyl9fWZvcihsZXQgZz0wO2c8YztnKyspZm9yKGxldCBiPTA7YjxhO2IrKyl7Y29uc3Qgdz1iK2wqZyx4PWIrbCooZysxKSxNPWIrMStsKihnKzEpLEE9YisxK2wqZztkLnB1c2godyx4LEEpLGQucHVzaCh4LE0sQSl9dGhpcy5zZXRJbmRleChkKSx0aGlzLnNldEF0dHJpYnV0ZSgicG9zaXRpb24iLG5ldyBCZShwLDMpKSx0aGlzLnNldEF0dHJpYnV0ZSgibm9ybWFsIixuZXcgQmUoeSwzKSksdGhpcy5zZXRBdHRyaWJ1dGUoInV2IixuZXcgQmUobSwyKSl9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnBhcmFtZXRlcnM9T2JqZWN0LmFzc2lnbih7fSx0LnBhcmFtZXRlcnMpLHRoaXN9c3RhdGljIGZyb21KU09OKHQpe3JldHVybiBuZXcgTG8odC53aWR0aCx0LmhlaWdodCx0LndpZHRoU2VnbWVudHMsdC5oZWlnaHRTZWdtZW50cyl9fWNvbnN0IG5sPW5ldyBULEVzPW5ldyBUO2NsYXNzIFF0e2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCl7dGhpcy5zdGFydD10LHRoaXMuZW5kPWV9c2V0KHQsZSl7cmV0dXJuIHRoaXMuc3RhcnQuY29weSh0KSx0aGlzLmVuZC5jb3B5KGUpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5zdGFydC5jb3B5KHQuc3RhcnQpLHRoaXMuZW5kLmNvcHkodC5lbmQpLHRoaXN9Z2V0Q2VudGVyKHQpe3JldHVybiB0LmFkZFZlY3RvcnModGhpcy5zdGFydCx0aGlzLmVuZCkubXVsdGlwbHlTY2FsYXIoLjUpfWRlbHRhKHQpe3JldHVybiB0LnN1YlZlY3RvcnModGhpcy5lbmQsdGhpcy5zdGFydCl9ZGlzdGFuY2VTcSgpe3JldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuZW5kKX1kaXN0YW5jZSgpe3JldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG8odGhpcy5lbmQpfWF0KHQsZSl7cmV0dXJuIHRoaXMuZGVsdGEoZSkubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMuc3RhcnQpfWNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxlKXtubC5zdWJWZWN0b3JzKHQsdGhpcy5zdGFydCksRXMuc3ViVmVjdG9ycyh0aGlzLmVuZCx0aGlzLnN0YXJ0KTtjb25zdCBuPUVzLmRvdChFcyk7bGV0IHI9RXMuZG90KG5sKS9uO3JldHVybiBlJiYocj1aKHIsMCwxKSkscn1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZSxuKXtjb25zdCBzPXRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludFBhcmFtZXRlcih0LGUpO3JldHVybiB0aGlzLmRlbHRhKG4pLm11bHRpcGx5U2NhbGFyKHMpLmFkZCh0aGlzLnN0YXJ0KX1hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMuc3RhcnQuYXBwbHlNYXRyaXg0KHQpLHRoaXMuZW5kLmFwcGx5TWF0cml4NCh0KSx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5zdGFydC5lcXVhbHModGhpcy5zdGFydCkmJnQuZW5kLmVxdWFscyh0aGlzLmVuZCl9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX10eXBlb2YgX19USFJFRV9ERVZUT09MU19fIT0idW5kZWZpbmVkIiYmX19USFJFRV9ERVZUT09MU19fLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCJyZWdpc3RlciIse2RldGFpbDp7cmV2aXNpb246Sn19KSksdHlwZW9mIHdpbmRvdyE9InVuZGVmaW5lZCImJih3aW5kb3cuX19USFJFRV9fP2NvbnNvbGUud2FybigiV0FSTklORzogTXVsdGlwbGUgaW5zdGFuY2VzIG9mIFRocmVlLmpzIGJlaW5nIGltcG9ydGVkLiIpOndpbmRvdy5fX1RIUkVFX189Sik7Y29uc3QgcG49bmV3IE1hcCxZZj0oaT17fSk9Pih7Z2VuZXJhdGVUb3BVVih0LGUsbixzLHIpe2NvbnN0IG89ZVtuKjNdLGE9ZVtuKjMrMV0sYz1lW3MqM10sbD1lW3MqMysxXSxoPWVbciozXSx1PWVbciozKzFdO2xldCBmO2lmKHBuLmhhcyh0KSlmPXBuLmdldCh0KTtlbHNle2xldCBtPWkuYm94MztpZighbSl7bT1uZXcgZ3Q7Y29uc3Qgdz10LnBhcmFtZXRlcnMuc2hhcGVzLmdldFBvaW50cygpLm1hcCh4PT5beC54LHgueSwwXSkuZmxhdCgpO20uc2V0RnJvbUFycmF5KHcpfWNvbnN0IGc9bS5nZXRTaXplKG5ldyBUKTtpLnNwbGl0JiYoZy55Lz1pLnNwbGl0KSxmPXtib3g6bSxzaXplOmd9LHBuLnNldCh0LGYpfWNvbnN0e2JveDpkLHNpemU6cH09Zix5PWkuc3BsaXQ/MS1pLnNwbGl0OjA7cmV0dXJuW25ldyBSKChvLWQubWluLngpL3AueCwoYS1kLm1pbi55KS9wLnkreSksbmV3IFIoKGMtZC5taW4ueCkvcC54LChsLWQubWluLnkpL3AueSt5KSxuZXcgUigoaC1kLm1pbi54KS9wLngsKHUtZC5taW4ueSkvcC55K3kpXX0sZ2VuZXJhdGVTaWRlV2FsbFVWKHQsZSxuLHMscixvKXtjb25zdCBhPWVbbiozXSxjPWVbbiozKzFdLGw9ZVtuKjMrMl0saD1lW3MqM10sdT1lW3MqMysxXSxmPWVbcyozKzJdLGQ9ZVtyKjNdLHA9ZVtyKjMrMV0seT1lW3IqMysyXSxtPWVbbyozXSxnPWVbbyozKzFdLGI9ZVtvKjMrMl07bGV0IHc7aWYocG4uaGFzKGUpKXc9cG4uZ2V0KGUpO2Vsc2V7Y29uc3QgQT1uZXcgZ3Q7QS5zZXRGcm9tQXJyYXkoZSk7Y29uc3QgUz1BLmdldFNpemUobmV3IFQpO2kuc3BsaXQmJihTLnovPTEtaS5zcGxpdCksaS5zaWRlUmVwZWF0JiYoUy56Lz1pLnNpZGVSZXBlYXQpLHc9e2JveDpBLHNpemU6U30scG4uc2V0KGUsdyl9Y29uc3R7Ym94Ongsc2l6ZTpNfT13O3JldHVybiBNYXRoLmFicyhjLXUpPE1hdGguYWJzKGEtaCk/W25ldyBSKChhLXgubWluLngpL00ueCwobC14Lm1pbi56KS9NLnopLG5ldyBSKChoLXgubWluLngpL00ueCwoZi14Lm1pbi56KS9NLnopLG5ldyBSKChkLXgubWluLngpL00ueCwoeS14Lm1pbi56KS9NLnopLG5ldyBSKChtLXgubWluLngpL00ueCwoYi14Lm1pbi56KS9NLnopXTpbbmV3IFIoKGMteC5taW4ueSkvTS55LChsLXgubWluLnopL00ueiksbmV3IFIoKHUteC5taW4ueSkvTS55LChmLXgubWluLnopL00ueiksbmV3IFIoKHAteC5taW4ueSkvTS55LCh5LXgubWluLnopL00ueiksbmV3IFIoKGcteC5taW4ueSkvTS55LChiLXgubWluLnopL00ueildfX0pLGpmPSgpPT57cG4uY2xlYXIoKX0sUWY9e0FyY0N1cnZlOiRjLENhdG11bGxSb21DdXJ2ZTM6VmMsQ3ViaWNCZXppZXJDdXJ2ZTpCbyxDdWJpY0JlemllckN1cnZlMzpxYyxFbGxpcHNlQ3VydmU6X3MsTGluZUN1cnZlOkZvLExpbmVDdXJ2ZTM6SGMsUXVhZHJhdGljQmV6aWVyQ3VydmU6SW8sUXVhZHJhdGljQmV6aWVyQ3VydmUzOldjLFNwbGluZUN1cnZlOmtvfTtjbGFzcyBHbiBleHRlbmRzIHVle2NvbnN0cnVjdG9yKHQ9bmV3IFhjKFtuZXcgUiguNSwuNSksbmV3IFIoLS41LC41KSxuZXcgUigtLjUsLS41KSxuZXcgUiguNSwtLjUpXSksZT17fSl7c3VwZXIoKSx0aGlzLnR5cGU9IkV4dHJ1ZGVHZW9tZXRyeSIsdGhpcy5wYXJhbWV0ZXJzPXtzaGFwZXM6dCxvcHRpb25zOmV9LHQ9QXJyYXkuaXNBcnJheSh0KT90Olt0XTtjb25zdCBuPXRoaXMscz1bXSxyPVtdO2ZvcihsZXQgYT0wLGM9dC5sZW5ndGg7YTxjO2ErKyl7Y29uc3QgbD10W2FdO28obCl9dGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQmUocywzKSksdGhpcy5zZXRBdHRyaWJ1dGUoInV2IixuZXcgQmUociwyKSksdGhpcy5jb21wdXRlVmVydGV4Tm9ybWFscygpO2Z1bmN0aW9uIG8oYSl7dmFyIE91LER1LCR1O2NvbnN0IGM9W10sbD1lLmN1cnZlU2VnbWVudHMhPT12b2lkIDA/ZS5jdXJ2ZVNlZ21lbnRzOjEyLGg9ZS5zdGVwcyE9PXZvaWQgMD9lLnN0ZXBzOjEsdT1lLmRlcHRoIT09dm9pZCAwP2UuZGVwdGg6MTtsZXQgZj1lLmJldmVsRW5hYmxlZCE9PXZvaWQgMD9lLmJldmVsRW5hYmxlZDohMCxkPWUuYmV2ZWxUaGlja25lc3MhPT12b2lkIDA/ZS5iZXZlbFRoaWNrbmVzczouMixwPWUuYmV2ZWxTaXplIT09dm9pZCAwP2UuYmV2ZWxTaXplOmQtLjEseT1lLmJldmVsT2Zmc2V0IT09dm9pZCAwP2UuYmV2ZWxPZmZzZXQ6MCxtPWUuYmV2ZWxTZWdtZW50cyE9PXZvaWQgMD9lLmJldmVsU2VnbWVudHM6Mztjb25zdCBnPWUuZXh0cnVkZVBhdGgsYj1lLlVWR2VuZXJhdG9yIT09dm9pZCAwP2UuVVZHZW5lcmF0b3I6S2Ysdz0oT3U9ZS5oYXNUb3ApIT1udWxsP091OiEwLHg9KER1PWUuaGFzQm90dG9tKSE9bnVsbD9EdTohMCxNPSgkdT1lLmhhc1NpZGUpIT1udWxsPyR1OiEwO2xldCBBLFM9ITEsXyxFLHosdjtnJiYoQT1nLmdldFNwYWNlZFBvaW50cyhoKSxTPSEwLGY9ITEsXz1nLmNvbXB1dGVGcmVuZXRGcmFtZXMoaCwhMSksRT1uZXcgVCx6PW5ldyBULHY9bmV3IFQpLGZ8fChtPTAsZD0wLHA9MCx5PTApO2NvbnN0IEM9YS5leHRyYWN0UG9pbnRzKGwpO2xldCBQPUMuc2hhcGU7Y29uc3QgRj1DLmhvbGVzO2lmKCFXbi5pc0Nsb2NrV2lzZShQKSl7UD1QLnJldmVyc2UoKTtmb3IobGV0IE49MCxMPUYubGVuZ3RoO048TDtOKyspe2NvbnN0IE89RltOXTtXbi5pc0Nsb2NrV2lzZShPKSYmKEZbTl09Ty5yZXZlcnNlKCkpfX1mdW5jdGlvbiBJKE4pe2NvbnN0IE89MTAwMDAwMDAwMDAwMDAwMDFlLTM2O2xldCBWPU5bMF07Zm9yKGxldCAkPTE7JDw9Ti5sZW5ndGg7JCsrKXtjb25zdCBZPSQlTi5sZW5ndGgsRz1OW1ldLGl0PUcueC1WLngsY3Q9Ry55LVYueSx3dD1pdCppdCtjdCpjdCxYdD1NYXRoLm1heChNYXRoLmFicyhHLngpLE1hdGguYWJzKEcueSksTWF0aC5hYnMoVi54KSxNYXRoLmFicyhWLnkpKSxDbj1PKlh0Klh0O2lmKHd0PD1Dbil7Ti5zcGxpY2UoWSwxKSwkLS07Y29udGludWV9Vj1HfX1JKFApLEYuZm9yRWFjaChJKTtjb25zdCBrPUYubGVuZ3RoLEQ9UDtmb3IobGV0IE49MDtOPGs7TisrKXtjb25zdCBMPUZbTl07UD1QLmNvbmNhdChMKX1mdW5jdGlvbiBVKE4sTCxPKXtyZXR1cm4gTHx8Y29uc29sZS5lcnJvcigiVEhSRUUuRXh0cnVkZUdlb21ldHJ5OiB2ZWMgZG9lcyBub3QgZXhpc3QiKSxOLmNsb25lKCkuYWRkU2NhbGVkVmVjdG9yKEwsTyl9Y29uc3Qgaj1QLmxlbmd0aDtmdW5jdGlvbiBkdChOLEwsTyl7bGV0IFYsJCxZO2NvbnN0IEc9Ti54LUwueCxpdD1OLnktTC55LGN0PU8ueC1OLngsd3Q9Ty55LU4ueSxYdD1HKkcraXQqaXQsQ249Ryp3dC1pdCpjdDtpZihNYXRoLmFicyhDbik+TnVtYmVyLkVQU0lMT04pe2NvbnN0IEp0PU1hdGguc3FydChYdCksVnU9TWF0aC5zcXJ0KGN0KmN0K3d0Knd0KSxVdT1MLngtaXQvSnQscXU9TC55K0cvSnQsUGc9Ty54LXd0L1Z1LENnPU8ueStjdC9WdSxIdT0oKFBnLVV1KSp3dC0oQ2ctcXUpKmN0KS8oRyp3dC1pdCpjdCk7Vj1VdStHKkh1LU4ueCwkPXF1K2l0Kkh1LU4ueTtjb25zdCBXdT1WKlYrJCokO2lmKFd1PD0yKXJldHVybiBuZXcgUihWLCQpO1k9TWF0aC5zcXJ0KFd1LzIpfWVsc2V7bGV0IEp0PSExO0c+TnVtYmVyLkVQU0lMT04/Y3Q+TnVtYmVyLkVQU0lMT04mJihKdD0hMCk6RzwtTnVtYmVyLkVQU0lMT04/Y3Q8LU51bWJlci5FUFNJTE9OJiYoSnQ9ITApOk1hdGguc2lnbihpdCk9PT1NYXRoLnNpZ24od3QpJiYoSnQ9ITApLEp0PyhWPS1pdCwkPUcsWT1NYXRoLnNxcnQoWHQpKTooVj1HLCQ9aXQsWT1NYXRoLnNxcnQoWHQvMikpfXJldHVybiBuZXcgUihWL1ksJC9ZKX1jb25zdCBEdD1bXTtmb3IobGV0IE49MCxMPUQubGVuZ3RoLE89TC0xLFY9TisxO048TDtOKyssTysrLFYrKylPPT09TCYmKE89MCksVj09PUwmJihWPTApLER0W05dPWR0KERbTl0sRFtPXSxEW1ZdKTtjb25zdCBHdD1bXTtsZXQgWnQsbWU9RHQuY29uY2F0KCk7Zm9yKGxldCBOPTAsTD1rO048TDtOKyspe2NvbnN0IE89RltOXTtadD1bXTtmb3IobGV0IFY9MCwkPU8ubGVuZ3RoLFk9JC0xLEc9VisxO1Y8JDtWKyssWSsrLEcrKylZPT09JCYmKFk9MCksRz09PSQmJihHPTApLFp0W1ZdPWR0KE9bVl0sT1tZXSxPW0ddKTtHdC5wdXNoKFp0KSxtZT1tZS5jb25jYXQoWnQpfWxldCBQbjtpZihtPT09MClQbj1Xbi50cmlhbmd1bGF0ZVNoYXBlKEQsRik7ZWxzZXtjb25zdCBOPVtdLEw9W107Zm9yKGxldCBPPTA7TzxtO08rKyl7Y29uc3QgVj1PL20sJD1kKk1hdGguY29zKFYqTWF0aC5QSS8yKSxZPXAqTWF0aC5zaW4oVipNYXRoLlBJLzIpK3k7Zm9yKGxldCBHPTAsaXQ9RC5sZW5ndGg7RzxpdDtHKyspe2NvbnN0IGN0PVUoRFtHXSxEdFtHXSxZKTtIZShjdC54LGN0LnksLSQpLFY9PT0wJiZOLnB1c2goY3QpfWZvcihsZXQgRz0wLGl0PWs7RzxpdDtHKyspe2NvbnN0IGN0PUZbR107WnQ9R3RbR107Y29uc3Qgd3Q9W107Zm9yKGxldCBYdD0wLENuPWN0Lmxlbmd0aDtYdDxDbjtYdCsrKXtjb25zdCBKdD1VKGN0W1h0XSxadFtYdF0sWSk7SGUoSnQueCxKdC55LC0kKSxWPT09MCYmd3QucHVzaChKdCl9Vj09PTAmJkwucHVzaCh3dCl9fVBuPVduLnRyaWFuZ3VsYXRlU2hhcGUoTixMKX1jb25zdCBZcj1Qbi5sZW5ndGgsUnU9cCt5O2ZvcihsZXQgTj0wO048ajtOKyspe2NvbnN0IEw9Zj9VKFBbTl0sbWVbTl0sUnUpOlBbTl07Uz8oei5jb3B5KF8ubm9ybWFsc1swXSkubXVsdGlwbHlTY2FsYXIoTC54KSxFLmNvcHkoXy5iaW5vcm1hbHNbMF0pLm11bHRpcGx5U2NhbGFyKEwueSksdi5jb3B5KEFbMF0pLmFkZCh6KS5hZGQoRSksSGUodi54LHYueSx2LnopKTpIZShMLngsTC55LDApfWZvcihsZXQgTj0xO048PWg7TisrKWZvcihsZXQgTD0wO0w8ajtMKyspe2NvbnN0IE89Zj9VKFBbTF0sbWVbTF0sUnUpOlBbTF07Uz8oei5jb3B5KF8ubm9ybWFsc1tOXSkubXVsdGlwbHlTY2FsYXIoTy54KSxFLmNvcHkoXy5iaW5vcm1hbHNbTl0pLm11bHRpcGx5U2NhbGFyKE8ueSksdi5jb3B5KEFbTl0pLmFkZCh6KS5hZGQoRSksSGUodi54LHYueSx2LnopKTpIZShPLngsTy55LHUvaCpOKX1mb3IobGV0IE49bS0xO04+PTA7Ti0tKXtjb25zdCBMPU4vbSxPPWQqTWF0aC5jb3MoTCpNYXRoLlBJLzIpLFY9cCpNYXRoLnNpbihMKk1hdGguUEkvMikreTtmb3IobGV0ICQ9MCxZPUQubGVuZ3RoOyQ8WTskKyspe2NvbnN0IEc9VShEWyRdLER0WyRdLFYpO0hlKEcueCxHLnksdStPKX1mb3IobGV0ICQ9MCxZPUYubGVuZ3RoOyQ8WTskKyspe2NvbnN0IEc9RlskXTtadD1HdFskXTtmb3IobGV0IGl0PTAsY3Q9Ry5sZW5ndGg7aXQ8Y3Q7aXQrKyl7Y29uc3Qgd3Q9VShHW2l0XSxadFtpdF0sVik7Uz9IZSh3dC54LHd0LnkrQVtoLTFdLnksQVtoLTFdLngrTyk6SGUod3QueCx3dC55LHUrTyl9fX16ZygpLE0mJlRnKCk7ZnVuY3Rpb24gemcoKXtjb25zdCBOPXMubGVuZ3RoLzM7aWYoZil7bGV0IEw9MCxPPWoqTDtpZih4KWZvcihsZXQgVj0wO1Y8WXI7VisrKXtjb25zdCAkPVBuW1ZdO2pyKCRbMl0rTywkWzFdK08sJFswXStPKX1pZihMPWgrbSoyLE89aipMLHcpZm9yKGxldCBWPTA7VjxZcjtWKyspe2NvbnN0ICQ9UG5bVl07anIoJFswXStPLCRbMV0rTywkWzJdK08pfX1lbHNle2lmKHgpZm9yKGxldCBMPTA7TDxZcjtMKyspe2NvbnN0IE89UG5bTF07anIoT1syXSxPWzFdLE9bMF0pfWlmKHcpZm9yKGxldCBMPTA7TDxZcjtMKyspe2NvbnN0IE89UG5bTF07anIoT1swXStqKmgsT1sxXStqKmgsT1syXStqKmgpfX1uLmFkZEdyb3VwKE4scy5sZW5ndGgvMy1OLDApfWZ1bmN0aW9uIFRnKCl7Y29uc3QgTj1zLmxlbmd0aC8zO2xldCBMPTA7THUoRCxMKSxMKz1ELmxlbmd0aDtmb3IobGV0IE89MCxWPUYubGVuZ3RoO088VjtPKyspe2NvbnN0ICQ9RltPXTtMdSgkLEwpLEwrPSQubGVuZ3RofW4uYWRkR3JvdXAoTixzLmxlbmd0aC8zLU4sMSl9ZnVuY3Rpb24gTHUoTixMKXtsZXQgTz1OLmxlbmd0aDtmb3IoOy0tTz49MDspe2NvbnN0IFY9TztsZXQgJD1PLTE7JDwwJiYoJD1OLmxlbmd0aC0xKTtmb3IobGV0IFk9MCxHPWgrbSoyO1k8RztZKyspe2NvbnN0IGl0PWoqWSxjdD1qKihZKzEpLHd0PUwrVitpdCxYdD1MKyQraXQsQ249TCskK2N0LEp0PUwrVitjdDtFZyh3dCxYdCxDbixKdCl9fX1mdW5jdGlvbiBIZShOLEwsTyl7Yy5wdXNoKE4pLGMucHVzaChMKSxjLnB1c2goTyl9ZnVuY3Rpb24ganIoTixMLE8pe1dlKE4pLFdlKEwpLFdlKE8pO2NvbnN0IFY9cy5sZW5ndGgvMywkPWIuZ2VuZXJhdGVUb3BVVihuLHMsVi0zLFYtMixWLTEpO0dlKCRbMF0pLEdlKCRbMV0pLEdlKCRbMl0pfWZ1bmN0aW9uIEVnKE4sTCxPLFYpe1dlKE4pLFdlKEwpLFdlKFYpLFdlKEwpLFdlKE8pLFdlKFYpO2NvbnN0ICQ9cy5sZW5ndGgvMyxZPWIuZ2VuZXJhdGVTaWRlV2FsbFVWKG4scywkLTYsJC0zLCQtMiwkLTEpO0dlKFlbMF0pLEdlKFlbMV0pLEdlKFlbM10pLEdlKFlbMV0pLEdlKFlbMl0pLEdlKFlbM10pfWZ1bmN0aW9uIFdlKE4pe3MucHVzaChjW04qMyswXSkscy5wdXNoKGNbTiozKzFdKSxzLnB1c2goY1tOKjMrMl0pfWZ1bmN0aW9uIEdlKE4pe3IucHVzaChOLngpLHIucHVzaChOLnkpfX19Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLnBhcmFtZXRlcnM9T2JqZWN0LmFzc2lnbih7fSx0LnBhcmFtZXRlcnMpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKSxlPXRoaXMucGFyYW1ldGVycy5zaGFwZXMsbj10aGlzLnBhcmFtZXRlcnMub3B0aW9ucztyZXR1cm4gdGQoZSxuLHQpfXN0YXRpYyBmcm9tSlNPTih0LGUpe2NvbnN0IG49W107Zm9yKGxldCByPTAsbz10LnNoYXBlcy5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1lW3Quc2hhcGVzW3JdXTtuLnB1c2goYSl9Y29uc3Qgcz10Lm9wdGlvbnMuZXh0cnVkZVBhdGg7cmV0dXJuIHMhPT12b2lkIDAmJih0Lm9wdGlvbnMuZXh0cnVkZVBhdGg9bmV3IFFmW2Ake3MudHlwZX1gXSgpLmZyb21KU09OKHMpKSxuZXcgR24obix0Lm9wdGlvbnMpfX1jb25zdCBLZj17Z2VuZXJhdGVUb3BVVjpmdW5jdGlvbihpLHQsZSxuLHMpe2NvbnN0IHI9dFtlKjNdLG89dFtlKjMrMV0sYT10W24qM10sYz10W24qMysxXSxsPXRbcyozXSxoPXRbcyozKzFdO3JldHVybltuZXcgUihyLG8pLG5ldyBSKGEsYyksbmV3IFIobCxoKV19LGdlbmVyYXRlU2lkZVdhbGxVVjpmdW5jdGlvbihpLHQsZSxuLHMscil7Y29uc3Qgbz10W2UqM10sYT10W2UqMysxXSxjPXRbZSozKzJdLGw9dFtuKjNdLGg9dFtuKjMrMV0sdT10W24qMysyXSxmPXRbcyozXSxkPXRbcyozKzFdLHA9dFtzKjMrMl0seT10W3IqM10sbT10W3IqMysxXSxnPXRbciozKzJdO3JldHVybiBNYXRoLmFicyhhLWgpPE1hdGguYWJzKG8tbCk/W25ldyBSKG8sMS1jKSxuZXcgUihsLDEtdSksbmV3IFIoZiwxLXApLG5ldyBSKHksMS1nKV06W25ldyBSKGEsMS1jKSxuZXcgUihoLDEtdSksbmV3IFIoZCwxLXApLG5ldyBSKG0sMS1nKV19fTtmdW5jdGlvbiB0ZChpLHQsZSl7aWYoZS5zaGFwZXM9W10sQXJyYXkuaXNBcnJheShpKSlmb3IobGV0IG49MCxzPWkubGVuZ3RoO248cztuKyspe2NvbnN0IHI9aVtuXTtlLnNoYXBlcy5wdXNoKHIudXVpZCl9ZWxzZSBlLnNoYXBlcy5wdXNoKGkudXVpZCk7cmV0dXJuIGUub3B0aW9ucz1PYmplY3QuYXNzaWduKHt9LHQpLHQuZXh0cnVkZVBhdGghPT12b2lkIDAmJihlLm9wdGlvbnMuZXh0cnVkZVBhdGg9dC5leHRydWRlUGF0aC50b0pTT04oKSksZX1jb25zdCBpbD0wLGVkPTEsbmQ9MixzbD0yLE9vPTEuMjUscmw9MSxQaT02KjQrNCs0LFBzPTY1NTM1LGlkPU1hdGgucG93KDIsLTI0KSxEbz1TeW1ib2woIlNLSVBfR0VORVJBVElPTiIpO2Z1bmN0aW9uIHNkKGkpe3JldHVybiBpLmluZGV4P2kuaW5kZXguY291bnQ6aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWZ1bmN0aW9uIFpuKGkpe3JldHVybiBzZChpKS8zfWZ1bmN0aW9uIHJkKGksdD1BcnJheUJ1ZmZlcil7cmV0dXJuIGk+NjU1MzU/bmV3IFVpbnQzMkFycmF5KG5ldyB0KDQqaSkpOm5ldyBVaW50MTZBcnJheShuZXcgdCgyKmkpKX1mdW5jdGlvbiBvZChpLHQpe2lmKCFpLmluZGV4KXtjb25zdCBlPWkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudCxuPXQudXNlU2hhcmVkQXJyYXlCdWZmZXI/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1yZChlLG4pO2kuc2V0SW5kZXgobmV3IHh0KHMsMSkpO2ZvcihsZXQgcj0wO3I8ZTtyKyspc1tyXT1yfX1mdW5jdGlvbiBvbChpLHQpe2NvbnN0IGU9Wm4oaSksbj10fHxpLmRyYXdSYW5nZSxzPW4uc3RhcnQvMyxyPShuLnN0YXJ0K24uY291bnQpLzMsbz1NYXRoLm1heCgwLHMpLGE9TWF0aC5taW4oZSxyKS1vO3JldHVyblt7b2Zmc2V0Ok1hdGguZmxvb3IobyksY291bnQ6TWF0aC5mbG9vcihhKX1dfWZ1bmN0aW9uIGFsKGksdCl7aWYoIWkuZ3JvdXBzfHwhaS5ncm91cHMubGVuZ3RoKXJldHVybiBvbChpLHQpO2NvbnN0IGU9W10sbj1uZXcgU2V0LHM9dHx8aS5kcmF3UmFuZ2Uscj1zLnN0YXJ0LzMsbz0ocy5zdGFydCtzLmNvdW50KS8zO2Zvcihjb25zdCBjIG9mIGkuZ3JvdXBzKXtjb25zdCBsPWMuc3RhcnQvMyxoPShjLnN0YXJ0K2MuY291bnQpLzM7bi5hZGQoTWF0aC5tYXgocixsKSksbi5hZGQoTWF0aC5taW4obyxoKSl9Y29uc3QgYT1BcnJheS5mcm9tKG4udmFsdWVzKCkpLnNvcnQoKGMsbCk9PmMtbCk7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aC0xO2MrKyl7Y29uc3QgbD1hW2NdLGg9YVtjKzFdO2UucHVzaCh7b2Zmc2V0Ok1hdGguZmxvb3IobCksY291bnQ6TWF0aC5mbG9vcihoLWwpfSl9cmV0dXJuIGV9ZnVuY3Rpb24gYWQoaSx0KXtjb25zdCBlPVpuKGkpLG49YWwoaSx0KS5zb3J0KChvLGEpPT5vLm9mZnNldC1hLm9mZnNldCkscz1uW24ubGVuZ3RoLTFdO3MuY291bnQ9TWF0aC5taW4oZS1zLm9mZnNldCxzLmNvdW50KTtsZXQgcj0wO3JldHVybiBuLmZvckVhY2goKHtjb3VudDpvfSk9PnIrPW8pLGUhPT1yfWZ1bmN0aW9uICRvKGksdCxlLG4scyl7bGV0IHI9MS8wLG89MS8wLGE9MS8wLGM9LTEvMCxsPS0xLzAsaD0tMS8wLHU9MS8wLGY9MS8wLGQ9MS8wLHA9LTEvMCx5PS0xLzAsbT0tMS8wO2ZvcihsZXQgZz10KjYsYj0odCtlKSo2O2c8YjtnKz02KXtjb25zdCB3PWlbZyswXSx4PWlbZysxXSxNPXcteCxBPXcreDtNPHImJihyPU0pLEE+YyYmKGM9QSksdzx1JiYodT13KSx3PnAmJihwPXcpO2NvbnN0IFM9aVtnKzJdLF89aVtnKzNdLEU9Uy1fLHo9UytfO0U8byYmKG89RSksej5sJiYobD16KSxTPGYmJihmPVMpLFM+eSYmKHk9Uyk7Y29uc3Qgdj1pW2crNF0sQz1pW2crNV0sUD12LUMsRj12K0M7UDxhJiYoYT1QKSxGPmgmJihoPUYpLHY8ZCYmKGQ9diksdj5tJiYobT12KX1uWzBdPXIsblsxXT1vLG5bMl09YSxuWzNdPWMsbls0XT1sLG5bNV09aCxzWzBdPXUsc1sxXT1mLHNbMl09ZCxzWzNdPXAsc1s0XT15LHNbNV09bX1mdW5jdGlvbiBjZChpLHQ9bnVsbCxlPW51bGwsbj1udWxsKXtjb25zdCBzPWkuYXR0cmlidXRlcy5wb3NpdGlvbixyPWkuaW5kZXg/aS5pbmRleC5hcnJheTpudWxsLG89Wm4oaSksYT1zLm5vcm1hbGl6ZWQ7bGV0IGM7dD09PW51bGw/KGM9bmV3IEZsb2F0MzJBcnJheShvKjYpLGU9MCxuPW8pOihjPXQsZT1lfHwwLG49bnx8byk7Y29uc3QgbD1zLmFycmF5LGg9cy5vZmZzZXR8fDA7bGV0IHU9MztzLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUmJih1PXMuZGF0YS5zdHJpZGUpO2NvbnN0IGY9WyJnZXRYIiwiZ2V0WSIsImdldFoiXTtmb3IobGV0IGQ9ZTtkPGUrbjtkKyspe2NvbnN0IHA9ZCozLHk9ZCo2O2xldCBtPXArMCxnPXArMSxiPXArMjtyJiYobT1yW21dLGc9cltnXSxiPXJbYl0pLGF8fChtPW0qdStoLGc9Zyp1K2gsYj1iKnUraCk7Zm9yKGxldCB3PTA7dzwzO3crKyl7bGV0IHgsTSxBO2E/KHg9c1tmW3ddXShtKSxNPXNbZlt3XV0oZyksQT1zW2Zbd11dKGIpKTooeD1sW20rd10sTT1sW2crd10sQT1sW2Ird10pO2xldCBTPXg7TTxTJiYoUz1NKSxBPFMmJihTPUEpO2xldCBfPXg7TT5fJiYoXz1NKSxBPl8mJihfPUEpO2NvbnN0IEU9KF8tUykvMix6PXcqMjtjW3kreiswXT1TK0UsY1t5K3orMV09RSsoTWF0aC5hYnMoUykrRSkqaWR9fXJldHVybiBjfWZ1bmN0aW9uIGx0KGksdCxlKXtyZXR1cm4gZS5taW4ueD10W2ldLGUubWluLnk9dFtpKzFdLGUubWluLno9dFtpKzJdLGUubWF4Lng9dFtpKzNdLGUubWF4Lnk9dFtpKzRdLGUubWF4Lno9dFtpKzVdLGV9ZnVuY3Rpb24gY2woaSl7bGV0IHQ9LTEsZT0tMS8wO2ZvcihsZXQgbj0wO248MztuKyspe2NvbnN0IHM9aVtuKzNdLWlbbl07cz5lJiYoZT1zLHQ9bil9cmV0dXJuIHR9ZnVuY3Rpb24gbGwoaSx0KXt0LnNldChpKX1mdW5jdGlvbiBobChpLHQsZSl7bGV0IG4scztmb3IobGV0IHI9MDtyPDM7cisrKXtjb25zdCBvPXIrMztuPWlbcl0scz10W3JdLGVbcl09bjxzP246cyxuPWlbb10scz10W29dLGVbb109bj5zP246c319ZnVuY3Rpb24gQ3MoaSx0LGUpe2ZvcihsZXQgbj0wO248MztuKyspe2NvbnN0IHM9dFtpKzIqbl0scj10W2krMipuKzFdLG89cy1yLGE9cytyO288ZVtuXSYmKGVbbl09byksYT5lW24rM10mJihlW24rM109YSl9fWZ1bmN0aW9uIENpKGkpe2NvbnN0IHQ9aVszXS1pWzBdLGU9aVs0XS1pWzFdLG49aVs1XS1pWzJdO3JldHVybiAyKih0KmUrZSpuK24qdCl9Y29uc3QgRmU9MzIsbGQ9KGksdCk9PmkuY2FuZGlkYXRlLXQuY2FuZGlkYXRlLEtlPW5ldyBBcnJheShGZSkuZmlsbCgpLm1hcCgoKT0+KHtjb3VudDowLGJvdW5kczpuZXcgRmxvYXQzMkFycmF5KDYpLHJpZ2h0Q2FjaGVCb3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxsZWZ0Q2FjaGVCb3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxjYW5kaWRhdGU6MH0pKSxCcz1uZXcgRmxvYXQzMkFycmF5KDYpO2Z1bmN0aW9uIGhkKGksdCxlLG4scyxyKXtsZXQgbz0tMSxhPTA7aWYocj09PWlsKW89Y2wodCksbyE9PS0xJiYoYT0odFtvXSt0W28rM10pLzIpO2Vsc2UgaWYocj09PWVkKW89Y2woaSksbyE9PS0xJiYoYT11ZChlLG4scyxvKSk7ZWxzZSBpZihyPT09bmQpe2NvbnN0IGM9Q2koaSk7bGV0IGw9T28qcztjb25zdCBoPW4qNix1PShuK3MpKjY7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD10W2ZdLG09KHRbZiszXS1kKS9GZTtpZihzPEZlLzQpe2NvbnN0IGc9Wy4uLktlXTtnLmxlbmd0aD1zO2xldCBiPTA7Zm9yKGxldCB4PWg7eDx1O3grPTYsYisrKXtjb25zdCBNPWdbYl07TS5jYW5kaWRhdGU9ZVt4KzIqZl0sTS5jb3VudD0wO2NvbnN0e2JvdW5kczpBLGxlZnRDYWNoZUJvdW5kczpTLHJpZ2h0Q2FjaGVCb3VuZHM6X309TTtmb3IobGV0IEU9MDtFPDM7RSsrKV9bRV09MS8wLF9bRSszXT0tMS8wLFNbRV09MS8wLFNbRSszXT0tMS8wLEFbRV09MS8wLEFbRSszXT0tMS8wO0NzKHgsZSxBKX1nLnNvcnQobGQpO2xldCB3PXM7Zm9yKGxldCB4PTA7eDx3O3grKyl7Y29uc3QgTT1nW3hdO2Zvcig7eCsxPHcmJmdbeCsxXS5jYW5kaWRhdGU9PT1NLmNhbmRpZGF0ZTspZy5zcGxpY2UoeCsxLDEpLHctLX1mb3IobGV0IHg9aDt4PHU7eCs9Nil7Y29uc3QgTT1lW3grMipmXTtmb3IobGV0IEE9MDtBPHc7QSsrKXtjb25zdCBTPWdbQV07TT49Uy5jYW5kaWRhdGU/Q3MoeCxlLFMucmlnaHRDYWNoZUJvdW5kcyk6KENzKHgsZSxTLmxlZnRDYWNoZUJvdW5kcyksUy5jb3VudCsrKX19Zm9yKGxldCB4PTA7eDx3O3grKyl7Y29uc3QgTT1nW3hdLEE9TS5jb3VudCxTPXMtTS5jb3VudCxfPU0ubGVmdENhY2hlQm91bmRzLEU9TS5yaWdodENhY2hlQm91bmRzO2xldCB6PTA7QSE9PTAmJih6PUNpKF8pL2MpO2xldCB2PTA7UyE9PTAmJih2PUNpKEUpL2MpO2NvbnN0IEM9cmwrT28qKHoqQSt2KlMpO0M8bCYmKG89ZixsPUMsYT1NLmNhbmRpZGF0ZSl9fWVsc2V7Zm9yKGxldCB3PTA7dzxGZTt3Kyspe2NvbnN0IHg9S2Vbd107eC5jb3VudD0wLHguY2FuZGlkYXRlPWQrbSt3Km07Y29uc3QgTT14LmJvdW5kcztmb3IobGV0IEE9MDtBPDM7QSsrKU1bQV09MS8wLE1bQSszXT0tMS8wfWZvcihsZXQgdz1oO3c8dTt3Kz02KXtsZXQgQT1+figoZVt3KzIqZl0tZCkvbSk7QT49RmUmJihBPUZlLTEpO2NvbnN0IFM9S2VbQV07Uy5jb3VudCsrLENzKHcsZSxTLmJvdW5kcyl9Y29uc3QgZz1LZVtGZS0xXTtsbChnLmJvdW5kcyxnLnJpZ2h0Q2FjaGVCb3VuZHMpO2ZvcihsZXQgdz1GZS0yO3c+PTA7dy0tKXtjb25zdCB4PUtlW3ddLE09S2VbdysxXTtobCh4LmJvdW5kcyxNLnJpZ2h0Q2FjaGVCb3VuZHMseC5yaWdodENhY2hlQm91bmRzKX1sZXQgYj0wO2ZvcihsZXQgdz0wO3c8RmUtMTt3Kyspe2NvbnN0IHg9S2Vbd10sTT14LmNvdW50LEE9eC5ib3VuZHMsXz1LZVt3KzFdLnJpZ2h0Q2FjaGVCb3VuZHM7TSE9PTAmJihiPT09MD9sbChBLEJzKTpobChBLEJzLEJzKSksYis9TTtsZXQgRT0wLHo9MDtiIT09MCYmKEU9Q2koQnMpL2MpO2NvbnN0IHY9cy1iO3YhPT0wJiYoej1DaShfKS9jKTtjb25zdCBDPXJsK09vKihFKmIreip2KTtDPGwmJihvPWYsbD1DLGE9eC5jYW5kaWRhdGUpfX19fWVsc2UgY29uc29sZS53YXJuKGBNZXNoQlZIOiBJbnZhbGlkIGJ1aWxkIHN0cmF0ZWd5IHZhbHVlICR7cn0gdXNlZC5gKTtyZXR1cm57YXhpczpvLHBvczphfX1mdW5jdGlvbiB1ZChpLHQsZSxuKXtsZXQgcz0wO2ZvcihsZXQgcj10LG89dCtlO3I8bztyKyspcys9aVtyKjYrbioyXTtyZXR1cm4gcy9lfWNsYXNzIFZve2NvbnN0cnVjdG9yKCl7dGhpcy5ib3VuZGluZ0RhdGE9bmV3IEZsb2F0MzJBcnJheSg2KX19ZnVuY3Rpb24gZmQoaSx0LGUsbixzLHIpe2xldCBvPW4sYT1uK3MtMTtjb25zdCBjPXIucG9zLGw9ci5heGlzKjI7Zm9yKDs7KXtmb3IoO288PWEmJmVbbyo2K2xdPGM7KW8rKztmb3IoO288PWEmJmVbYSo2K2xdPj1jOylhLS07aWYobzxhKXtmb3IobGV0IGg9MDtoPDM7aCsrKXtsZXQgdT10W28qMytoXTt0W28qMytoXT10W2EqMytoXSx0W2EqMytoXT11fWZvcihsZXQgaD0wO2g8NjtoKyspe2xldCB1PWVbbyo2K2hdO2Vbbyo2K2hdPWVbYSo2K2hdLGVbYSo2K2hdPXV9bysrLGEtLX1lbHNlIHJldHVybiBvfX1mdW5jdGlvbiBkZChpLHQsZSxuLHMscil7bGV0IG89bixhPW4rcy0xO2NvbnN0IGM9ci5wb3MsbD1yLmF4aXMqMjtmb3IoOzspe2Zvcig7bzw9YSYmZVtvKjYrbF08YzspbysrO2Zvcig7bzw9YSYmZVthKjYrbF0+PWM7KWEtLTtpZihvPGEpe2xldCBoPWlbb107aVtvXT1pW2FdLGlbYV09aDtmb3IobGV0IHU9MDt1PDY7dSsrKXtsZXQgZj1lW28qNit1XTtlW28qNit1XT1lW2EqNit1XSxlW2EqNit1XT1mfW8rKyxhLS19ZWxzZSByZXR1cm4gb319ZnVuY3Rpb24ga3QoaSx0KXtyZXR1cm4gdFtpKzE1XT09PTY1NTM1fWZ1bmN0aW9uIFV0KGksdCl7cmV0dXJuIHRbaSs2XX1mdW5jdGlvbiBLdChpLHQpe3JldHVybiB0W2krMTRdfWZ1bmN0aW9uIHRlKGkpe3JldHVybiBpKzh9ZnVuY3Rpb24gZWUoaSx0KXtyZXR1cm4gdFtpKzZdfWZ1bmN0aW9uIHVsKGksdCl7cmV0dXJuIHRbaSs3XX1mdW5jdGlvbiBqZyhpKXtyZXR1cm4gaX1sZXQgZmwsQmksRnMsZGw7Y29uc3QgcGQ9TWF0aC5wb3coMiwzMik7ZnVuY3Rpb24gVW8oaSl7cmV0dXJuImNvdW50ImluIGk/MToxK1VvKGkubGVmdCkrVW8oaS5yaWdodCl9ZnVuY3Rpb24geWQoaSx0LGUpe3JldHVybiBmbD1uZXcgRmxvYXQzMkFycmF5KGUpLEJpPW5ldyBVaW50MzJBcnJheShlKSxGcz1uZXcgVWludDE2QXJyYXkoZSksZGw9bmV3IFVpbnQ4QXJyYXkoZSkscW8oaSx0KX1mdW5jdGlvbiBxbyhpLHQpe2NvbnN0IGU9aS80LG49aS8yLHM9ImNvdW50ImluIHQscj10LmJvdW5kaW5nRGF0YTtmb3IobGV0IG89MDtvPDY7bysrKWZsW2Urb109cltvXTtpZihzKWlmKHQuYnVmZmVyKXtjb25zdCBvPXQuYnVmZmVyO2RsLnNldChuZXcgVWludDhBcnJheShvKSxpKTtmb3IobGV0IGE9aSxjPWkrby5ieXRlTGVuZ3RoO2E8YzthKz1QaSl7Y29uc3QgbD1hLzI7a3QobCxGcyl8fChCaVthLzQrNl0rPWUpfXJldHVybiBpK28uYnl0ZUxlbmd0aH1lbHNle2NvbnN0IG89dC5vZmZzZXQsYT10LmNvdW50O3JldHVybiBCaVtlKzZdPW8sRnNbbisxNF09YSxGc1tuKzE1XT1QcyxpK1BpfWVsc2V7Y29uc3Qgbz10LmxlZnQsYT10LnJpZ2h0LGM9dC5zcGxpdEF4aXM7bGV0IGw7aWYobD1xbyhpK1BpLG8pLGwvND5wZCl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IENhbm5vdCBzdG9yZSBjaGlsZCBwb2ludGVyIGdyZWF0ZXIgdGhhbiAzMiBiaXRzLiIpO3JldHVybiBCaVtlKzZdPWwvNCxsPXFvKGwsYSksQmlbZSs3XT1jLGx9fWZ1bmN0aW9uIG1kKGksdCl7Y29uc3QgZT0oaS5pbmRleD9pLmluZGV4LmNvdW50OmkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudCkvMyxuPWU+eWkoMiwxNikscz1uPzQ6MixyPXQ/bmV3IFNoYXJlZEFycmF5QnVmZmVyKGUqcyk6bmV3IEFycmF5QnVmZmVyKGUqcyksbz1uP25ldyBVaW50MzJBcnJheShyKTpuZXcgVWludDE2QXJyYXkocik7Zm9yKGxldCBhPTAsYz1vLmxlbmd0aDthPGM7YSsrKW9bYV09YTtyZXR1cm4gb31mdW5jdGlvbiBnZChpLHQsZSxuLHMpe2NvbnN0e21heERlcHRoOnIsdmVyYm9zZTpvLG1heExlYWZUcmlzOmEsc3RyYXRlZ3k6YyxvblByb2dyZXNzOmwsaW5kaXJlY3Q6aH09cyx1PWkuX2luZGlyZWN0QnVmZmVyLGY9aS5nZW9tZXRyeSxkPWYuaW5kZXg/Zi5pbmRleC5hcnJheTpudWxsLHA9aD9kZDpmZCx5PVpuKGYpLG09bmV3IEZsb2F0MzJBcnJheSg2KTtsZXQgZz0hMTtjb25zdCBiPW5ldyBWbztyZXR1cm4gJG8odCxlLG4sYi5ib3VuZGluZ0RhdGEsbSkseChiLGUsbixtKSxiO2Z1bmN0aW9uIHcoTSl7bCYmbChNL3kpfWZ1bmN0aW9uIHgoTSxBLFMsXz1udWxsLEU9MCl7aWYoIWcmJkU+PXImJihnPSEwLG8mJihjb25zb2xlLndhcm4oYE1lc2hCVkg6IE1heCBkZXB0aCBvZiAke3J9IHJlYWNoZWQgd2hlbiBnZW5lcmF0aW5nIEJWSC4gQ29uc2lkZXIgaW5jcmVhc2luZyBtYXhEZXB0aC5gKSxjb25zb2xlLndhcm4oZikpKSxTPD1hfHxFPj1yKXJldHVybiB3KEErUyksTS5vZmZzZXQ9QSxNLmNvdW50PVMsTTtjb25zdCB6PWhkKE0uYm91bmRpbmdEYXRhLF8sdCxBLFMsYyk7aWYoei5heGlzPT09LTEpcmV0dXJuIHcoQStTKSxNLm9mZnNldD1BLE0uY291bnQ9UyxNO2NvbnN0IHY9cCh1LGQsdCxBLFMseik7aWYodj09PUF8fHY9PT1BK1MpdyhBK1MpLE0ub2Zmc2V0PUEsTS5jb3VudD1TO2Vsc2V7TS5zcGxpdEF4aXM9ei5heGlzO2NvbnN0IEM9bmV3IFZvLFA9QSxGPXYtQTtNLmxlZnQ9Qywkbyh0LFAsRixDLmJvdW5kaW5nRGF0YSxtKSx4KEMsUCxGLG0sRSsxKTtjb25zdCBCPW5ldyBWbyxJPXYsaz1TLUY7TS5yaWdodD1CLCRvKHQsSSxrLEIuYm91bmRpbmdEYXRhLG0pLHgoQixJLGssbSxFKzEpfXJldHVybiBNfX1mdW5jdGlvbiB4ZChpLHQpe2NvbnN0IGU9aS5nZW9tZXRyeTt0LmluZGlyZWN0JiYoaS5faW5kaXJlY3RCdWZmZXI9bWQoZSx0LnVzZVNoYXJlZEFycmF5QnVmZmVyKSxhZChlLHQucmFuZ2UpJiYhdC52ZXJib3NlJiZjb25zb2xlLndhcm4oJ01lc2hCVkg6IFByb3ZpZGVkIGdlb21ldHJ5IGNvbnRhaW5zIGdyb3VwcyBvciBhIHJhbmdlIHRoYXQgZG8gbm90IGZ1bGx5IHNwYW4gdGhlIHZlcnRleCBjb250ZW50cyB3aGlsZSB1c2luZyB0aGUgImluZGlyZWN0IiBvcHRpb24uIEJWSCBtYXkgaW5jb3JyZWN0bHkgcmVwb3J0IGludGVyc2VjdGlvbnMgb24gdW5yZW5kZXJlZCBwb3J0aW9ucyBvZiB0aGUgZ2VvbWV0cnkuJykpLGkuX2luZGlyZWN0QnVmZmVyfHxvZChlLHQpO2NvbnN0IG49dC51c2VTaGFyZWRBcnJheUJ1ZmZlcj9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPWNkKGUpLHI9dC5pbmRpcmVjdD9vbChlLHQucmFuZ2UpOmFsKGUsdC5yYW5nZSk7aS5fcm9vdHM9ci5tYXAobz0+e2NvbnN0IGE9Z2QoaSxzLG8ub2Zmc2V0LG8uY291bnQsdCksYz1VbyhhKSxsPW5ldyBuKFBpKmMpO3JldHVybiB5ZCgwLGEsbCksbH0pfWNsYXNzIElle2NvbnN0cnVjdG9yKCl7dGhpcy5taW49MS8wLHRoaXMubWF4PS0xLzB9c2V0RnJvbVBvaW50c0ZpZWxkKHQsZSl7bGV0IG49MS8wLHM9LTEvMDtmb3IobGV0IHI9MCxvPXQubGVuZ3RoO3I8bztyKyspe2NvbnN0IGM9dFtyXVtlXTtuPWM8bj9jOm4scz1jPnM/YzpzfXRoaXMubWluPW4sdGhpcy5tYXg9c31zZXRGcm9tUG9pbnRzKHQsZSl7bGV0IG49MS8wLHM9LTEvMDtmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVtyXSxjPXQuZG90KGEpO249YzxuP2M6bixzPWM+cz9jOnN9dGhpcy5taW49bix0aGlzLm1heD1zfWlzU2VwYXJhdGVkKHQpe3JldHVybiB0aGlzLm1pbj50Lm1heHx8dC5taW4+dGhpcy5tYXh9fUllLnByb3RvdHlwZS5zZXRGcm9tQm94PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSxuKXtjb25zdCBzPW4ubWluLHI9bi5tYXg7bGV0IG89MS8wLGE9LTEvMDtmb3IobGV0IGM9MDtjPD0xO2MrKylmb3IobGV0IGw9MDtsPD0xO2wrKylmb3IobGV0IGg9MDtoPD0xO2grKyl7aS54PXMueCpjK3IueCooMS1jKSxpLnk9cy55Kmwrci55KigxLWwpLGkuej1zLnoqaCtyLnoqKDEtaCk7Y29uc3QgdT1lLmRvdChpKTtvPU1hdGgubWluKHUsbyksYT1NYXRoLm1heCh1LGEpfXRoaXMubWluPW8sdGhpcy5tYXg9YX19KCk7Y29uc3Qgd2Q9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24ocyxyLG8pe2NvbnN0IGE9cy5zdGFydCxjPWksbD1yLnN0YXJ0LGg9dDtlLnN1YlZlY3RvcnMoYSxsKSxpLnN1YlZlY3RvcnMocy5lbmQscy5zdGFydCksdC5zdWJWZWN0b3JzKHIuZW5kLHIuc3RhcnQpO2NvbnN0IHU9ZS5kb3QoaCksZj1oLmRvdChjKSxkPWguZG90KGgpLHA9ZS5kb3QoYyksbT1jLmRvdChjKSpkLWYqZjtsZXQgZyxiO20hPT0wP2c9KHUqZi1wKmQpL206Zz0wLGI9KHUrZypmKS9kLG8ueD1nLG8ueT1ifX0oKSxIbz1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFIsdD1uZXcgVCxlPW5ldyBUO3JldHVybiBmdW5jdGlvbihzLHIsbyxhKXt3ZChzLHIsaSk7bGV0IGM9aS54LGw9aS55O2lmKGM+PTAmJmM8PTEmJmw+PTAmJmw8PTEpe3MuYXQoYyxvKSxyLmF0KGwsYSk7cmV0dXJufWVsc2UgaWYoYz49MCYmYzw9MSl7bDwwP3IuYXQoMCxhKTpyLmF0KDEsYSkscy5jbG9zZXN0UG9pbnRUb1BvaW50KGEsITAsbyk7cmV0dXJufWVsc2UgaWYobD49MCYmbDw9MSl7YzwwP3MuYXQoMCxvKTpzLmF0KDEsbyksci5jbG9zZXN0UG9pbnRUb1BvaW50KG8sITAsYSk7cmV0dXJufWVsc2V7bGV0IGg7YzwwP2g9cy5zdGFydDpoPXMuZW5kO2xldCB1O2w8MD91PXIuc3RhcnQ6dT1yLmVuZDtjb25zdCBmPXQsZD1lO2lmKHMuY2xvc2VzdFBvaW50VG9Qb2ludCh1LCEwLHQpLHIuY2xvc2VzdFBvaW50VG9Qb2ludChoLCEwLGUpLGYuZGlzdGFuY2VUb1NxdWFyZWQodSk8PWQuZGlzdGFuY2VUb1NxdWFyZWQoaCkpe28uY29weShmKSxhLmNvcHkodSk7cmV0dXJufWVsc2V7by5jb3B5KGgpLGEuY29weShkKTtyZXR1cm59fX19KCksYmQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgem8sbj1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKHIsbyl7Y29uc3R7cmFkaXVzOmEsY2VudGVyOmN9PXIse2E6bCxiOmgsYzp1fT1vO2lmKG4uc3RhcnQ9bCxuLmVuZD1oLG4uY2xvc2VzdFBvaW50VG9Qb2ludChjLCEwLGkpLmRpc3RhbmNlVG8oYyk8PWF8fChuLnN0YXJ0PWwsbi5lbmQ9dSxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hKXx8KG4uc3RhcnQ9aCxuLmVuZD11LG4uY2xvc2VzdFBvaW50VG9Qb2ludChjLCEwLGkpLmRpc3RhbmNlVG8oYyk8PWEpKXJldHVybiEwO2NvbnN0IHk9by5nZXRQbGFuZShlKTtpZihNYXRoLmFicyh5LmRpc3RhbmNlVG9Qb2ludChjKSk8PWEpe2NvbnN0IGc9eS5wcm9qZWN0UG9pbnQoYyx0KTtpZihvLmNvbnRhaW5zUG9pbnQoZykpcmV0dXJuITB9cmV0dXJuITF9fSgpLE1kPTFlLTE1O2Z1bmN0aW9uIFdvKGkpe3JldHVybiBNYXRoLmFicyhpKTxNZH1jbGFzcyBuZSBleHRlbmRzIGV0e2NvbnN0cnVjdG9yKC4uLnQpe3N1cGVyKC4uLnQpLHRoaXMuaXNFeHRlbmRlZFRyaWFuZ2xlPSEwLHRoaXMuc2F0QXhlcz1uZXcgQXJyYXkoNCkuZmlsbCgpLm1hcCgoKT0+bmV3IFQpLHRoaXMuc2F0Qm91bmRzPW5ldyBBcnJheSg0KS5maWxsKCkubWFwKCgpPT5uZXcgSWUpLHRoaXMucG9pbnRzPVt0aGlzLmEsdGhpcy5iLHRoaXMuY10sdGhpcy5zcGhlcmU9bmV3IGNvLHRoaXMucGxhbmU9bmV3IHpvLHRoaXMubmVlZHNVcGRhdGU9ITB9aW50ZXJzZWN0c1NwaGVyZSh0KXtyZXR1cm4gYmQodCx0aGlzKX11cGRhdGUoKXtjb25zdCB0PXRoaXMuYSxlPXRoaXMuYixuPXRoaXMuYyxzPXRoaXMucG9pbnRzLHI9dGhpcy5zYXRBeGVzLG89dGhpcy5zYXRCb3VuZHMsYT1yWzBdLGM9b1swXTt0aGlzLmdldE5vcm1hbChhKSxjLnNldEZyb21Qb2ludHMoYSxzKTtjb25zdCBsPXJbMV0saD1vWzFdO2wuc3ViVmVjdG9ycyh0LGUpLGguc2V0RnJvbVBvaW50cyhsLHMpO2NvbnN0IHU9clsyXSxmPW9bMl07dS5zdWJWZWN0b3JzKGUsbiksZi5zZXRGcm9tUG9pbnRzKHUscyk7Y29uc3QgZD1yWzNdLHA9b1szXTtkLnN1YlZlY3RvcnMobix0KSxwLnNldEZyb21Qb2ludHMoZCxzKSx0aGlzLnNwaGVyZS5zZXRGcm9tUG9pbnRzKHRoaXMucG9pbnRzKSx0aGlzLnBsYW5lLnNldEZyb21Ob3JtYWxBbmRDb3BsYW5hclBvaW50KGEsdCksdGhpcy5uZWVkc1VwZGF0ZT0hMX19bmUucHJvdG90eXBlLmNsb3Nlc3RQb2ludFRvU2VnbWVudD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQsdD1uZXcgVCxlPW5ldyBRdDtyZXR1cm4gZnVuY3Rpb24ocyxyPW51bGwsbz1udWxsKXtjb25zdHtzdGFydDphLGVuZDpjfT1zLGw9dGhpcy5wb2ludHM7bGV0IGgsdT0xLzA7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD0oZisxKSUzO2Uuc3RhcnQuY29weShsW2ZdKSxlLmVuZC5jb3B5KGxbZF0pLEhvKGUscyxpLHQpLGg9aS5kaXN0YW5jZVRvU3F1YXJlZCh0KSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weSh0KSl9cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChhLGkpLGg9YS5kaXN0YW5jZVRvU3F1YXJlZChpKSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weShhKSksdGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50KGMsaSksaD1jLmRpc3RhbmNlVG9TcXVhcmVkKGkpLGg8dSYmKHU9aCxyJiZyLmNvcHkoaSksbyYmby5jb3B5KGMpKSxNYXRoLnNxcnQodSl9fSgpLG5lLnByb3RvdHlwZS5pbnRlcnNlY3RzVHJpYW5nbGU9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBuZSx0PW5ldyBBcnJheSgzKSxlPW5ldyBBcnJheSgzKSxuPW5ldyBJZSxzPW5ldyBJZSxyPW5ldyBULG89bmV3IFQsYT1uZXcgVCxjPW5ldyBULGw9bmV3IFQsaD1uZXcgUXQsdT1uZXcgUXQsZj1uZXcgUXQsZD1uZXcgVDtmdW5jdGlvbiBwKHksbSxnKXtjb25zdCBiPXkucG9pbnRzO2xldCB3PTAseD0tMTtmb3IobGV0IE09MDtNPDM7TSsrKXtjb25zdHtzdGFydDpBLGVuZDpTfT1oO0EuY29weShiW01dKSxTLmNvcHkoYlsoTSsxKSUzXSksaC5kZWx0YShvKTtjb25zdCBfPVdvKG0uZGlzdGFuY2VUb1BvaW50KEEpKTtpZihXbyhtLm5vcm1hbC5kb3QobykpJiZfKXtnLmNvcHkoaCksdz0yO2JyZWFrfWNvbnN0IEU9bS5pbnRlcnNlY3RMaW5lKGgsZCk7aWYoIUUmJl8mJmQuY29weShBKSwoRXx8XykmJiFXbyhkLmRpc3RhbmNlVG8oUykpKXtpZih3PD0xKSh3PT09MT9nLnN0YXJ0OmcuZW5kKS5jb3B5KGQpLF8mJih4PXcpO2Vsc2UgaWYodz49Mil7KHg9PT0xP2cuc3RhcnQ6Zy5lbmQpLmNvcHkoZCksdz0yO2JyZWFrfWlmKHcrKyx3PT09MiYmeD09PS0xKWJyZWFrfX1yZXR1cm4gd31yZXR1cm4gZnVuY3Rpb24obSxnPW51bGwsYj0hMSl7dGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxtLmlzRXh0ZW5kZWRUcmlhbmdsZT9tLm5lZWRzVXBkYXRlJiZtLnVwZGF0ZSgpOihpLmNvcHkobSksaS51cGRhdGUoKSxtPWkpO2NvbnN0IHc9dGhpcy5wbGFuZSx4PW0ucGxhbmU7aWYoTWF0aC5hYnMody5ub3JtYWwuZG90KHgubm9ybWFsKSk+MS0xZS0xMCl7Y29uc3QgTT10aGlzLnNhdEJvdW5kcyxBPXRoaXMuc2F0QXhlcztlWzBdPW0uYSxlWzFdPW0uYixlWzJdPW0uYztmb3IobGV0IEU9MDtFPDQ7RSsrKXtjb25zdCB6PU1bRV0sdj1BW0VdO2lmKG4uc2V0RnJvbVBvaW50cyh2LGUpLHouaXNTZXBhcmF0ZWQobikpcmV0dXJuITF9Y29uc3QgUz1tLnNhdEJvdW5kcyxfPW0uc2F0QXhlczt0WzBdPXRoaXMuYSx0WzFdPXRoaXMuYix0WzJdPXRoaXMuYztmb3IobGV0IEU9MDtFPDQ7RSsrKXtjb25zdCB6PVNbRV0sdj1fW0VdO2lmKG4uc2V0RnJvbVBvaW50cyh2LHQpLHouaXNTZXBhcmF0ZWQobikpcmV0dXJuITF9Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1BW0VdO2ZvcihsZXQgdj0wO3Y8NDt2Kyspe2NvbnN0IEM9X1t2XTtpZihyLmNyb3NzVmVjdG9ycyh6LEMpLG4uc2V0RnJvbVBvaW50cyhyLHQpLHMuc2V0RnJvbVBvaW50cyhyLGUpLG4uaXNTZXBhcmF0ZWQocykpcmV0dXJuITF9fXJldHVybiBnJiYoYnx8Y29uc29sZS53YXJuKCJFeHRlbmRlZFRyaWFuZ2xlLmludGVyc2VjdHNUcmlhbmdsZTogVHJpYW5nbGVzIGFyZSBjb3BsYW5hciB3aGljaCBkb2VzIG5vdCBzdXBwb3J0IGFuIG91dHB1dCBlZGdlLiBTZXR0aW5nIGVkZ2UgdG8gMCwgMCwgMC4iKSxnLnN0YXJ0LnNldCgwLDAsMCksZy5lbmQuc2V0KDAsMCwwKSksITB9ZWxzZXtjb25zdCBNPXAodGhpcyx4LHUpO2lmKE09PT0xJiZtLmNvbnRhaW5zUG9pbnQodS5lbmQpKXJldHVybiBnJiYoZy5zdGFydC5jb3B5KHUuZW5kKSxnLmVuZC5jb3B5KHUuZW5kKSksITA7aWYoTSE9PTIpcmV0dXJuITE7Y29uc3QgQT1wKG0sdyxmKTtpZihBPT09MSYmdGhpcy5jb250YWluc1BvaW50KGYuZW5kKSlyZXR1cm4gZyYmKGcuc3RhcnQuY29weShmLmVuZCksZy5lbmQuY29weShmLmVuZCkpLCEwO2lmKEEhPT0yKXJldHVybiExO2lmKHUuZGVsdGEoYSksZi5kZWx0YShjKSxhLmRvdChjKTwwKXtsZXQgUD1mLnN0YXJ0O2Yuc3RhcnQ9Zi5lbmQsZi5lbmQ9UH1jb25zdCBTPXUuc3RhcnQuZG90KGEpLF89dS5lbmQuZG90KGEpLEU9Zi5zdGFydC5kb3QoYSksej1mLmVuZC5kb3QoYSksdj1fPEUsQz1TPHo7cmV0dXJuIFMhPT16JiZFIT09XyYmdj09PUM/ITE6KGcmJihsLnN1YlZlY3RvcnModS5zdGFydCxmLnN0YXJ0KSxsLmRvdChhKT4wP2cuc3RhcnQuY29weSh1LnN0YXJ0KTpnLnN0YXJ0LmNvcHkoZi5zdGFydCksbC5zdWJWZWN0b3JzKHUuZW5kLGYuZW5kKSxsLmRvdChhKTwwP2cuZW5kLmNvcHkodS5lbmQpOmcuZW5kLmNvcHkoZi5lbmQpKSwhMCl9fX0oKSxuZS5wcm90b3R5cGUuZGlzdGFuY2VUb1BvaW50PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChlLGkpLGUuZGlzdGFuY2VUbyhpKX19KCksbmUucHJvdG90eXBlLmRpc3RhbmNlVG9UcmlhbmdsZT1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQsdD1uZXcgVCxlPVsiYSIsImIiLCJjIl0sbj1uZXcgUXQscz1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKG8sYT1udWxsLGM9bnVsbCl7Y29uc3QgbD1hfHxjP246bnVsbDtpZih0aGlzLmludGVyc2VjdHNUcmlhbmdsZShvLGwpKXJldHVybihhfHxjKSYmKGEmJmwuZ2V0Q2VudGVyKGEpLGMmJmwuZ2V0Q2VudGVyKGMpKSwwO2xldCBoPTEvMDtmb3IobGV0IHU9MDt1PDM7dSsrKXtsZXQgZjtjb25zdCBkPWVbdV0scD1vW2RdO3RoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChwLGkpLGY9cC5kaXN0YW5jZVRvU3F1YXJlZChpKSxmPGgmJihoPWYsYSYmYS5jb3B5KGkpLGMmJmMuY29weShwKSk7Y29uc3QgeT10aGlzW2RdO28uY2xvc2VzdFBvaW50VG9Qb2ludCh5LGkpLGY9eS5kaXN0YW5jZVRvU3F1YXJlZChpKSxmPGgmJihoPWYsYSYmYS5jb3B5KHkpLGMmJmMuY29weShpKSl9Zm9yKGxldCB1PTA7dTwzO3UrKyl7Y29uc3QgZj1lW3VdLGQ9ZVsodSsxKSUzXTtuLnNldCh0aGlzW2ZdLHRoaXNbZF0pO2ZvcihsZXQgcD0wO3A8MztwKyspe2NvbnN0IHk9ZVtwXSxtPWVbKHArMSklM107cy5zZXQob1t5XSxvW21dKSxIbyhuLHMsaSx0KTtjb25zdCBnPWkuZGlzdGFuY2VUb1NxdWFyZWQodCk7ZzxoJiYoaD1nLGEmJmEuY29weShpKSxjJiZjLmNvcHkodCkpfX1yZXR1cm4gTWF0aC5zcXJ0KGgpfX0oKTtjbGFzcyB6dHtjb25zdHJ1Y3Rvcih0LGUsbil7dGhpcy5pc09yaWVudGVkQm94PSEwLHRoaXMubWluPW5ldyBULHRoaXMubWF4PW5ldyBULHRoaXMubWF0cml4PW5ldyBzdCx0aGlzLmludk1hdHJpeD1uZXcgc3QsdGhpcy5wb2ludHM9bmV3IEFycmF5KDgpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEF4ZXM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEJvdW5kcz1uZXcgQXJyYXkoMykuZmlsbCgpLm1hcCgoKT0+bmV3IEllKSx0aGlzLmFsaWduZWRTYXRCb3VuZHM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBJZSksdGhpcy5uZWVkc1VwZGF0ZT0hMSx0JiZ0aGlzLm1pbi5jb3B5KHQpLGUmJnRoaXMubWF4LmNvcHkoZSksbiYmdGhpcy5tYXRyaXguY29weShuKX1zZXQodCxlLG4pe3RoaXMubWluLmNvcHkodCksdGhpcy5tYXguY29weShlKSx0aGlzLm1hdHJpeC5jb3B5KG4pLHRoaXMubmVlZHNVcGRhdGU9ITB9Y29weSh0KXt0aGlzLm1pbi5jb3B5KHQubWluKSx0aGlzLm1heC5jb3B5KHQubWF4KSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLm5lZWRzVXBkYXRlPSEwfX16dC5wcm90b3R5cGUudXBkYXRlPWZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKCl7Y29uc3QgdD10aGlzLm1hdHJpeCxlPXRoaXMubWluLG49dGhpcy5tYXgscz10aGlzLnBvaW50cztmb3IobGV0IGw9MDtsPD0xO2wrKylmb3IobGV0IGg9MDtoPD0xO2grKylmb3IobGV0IHU9MDt1PD0xO3UrKyl7Y29uc3QgZj0xKmx8MipofDQqdSxkPXNbZl07ZC54PWw/bi54OmUueCxkLnk9aD9uLnk6ZS55LGQuej11P24uejplLnosZC5hcHBseU1hdHJpeDQodCl9Y29uc3Qgcj10aGlzLnNhdEJvdW5kcyxvPXRoaXMuc2F0QXhlcyxhPXNbMF07Zm9yKGxldCBsPTA7bDwzO2wrKyl7Y29uc3QgaD1vW2xdLHU9cltsXSxmPTE8PGwsZD1zW2ZdO2guc3ViVmVjdG9ycyhhLGQpLHUuc2V0RnJvbVBvaW50cyhoLHMpfWNvbnN0IGM9dGhpcy5hbGlnbmVkU2F0Qm91bmRzO2NbMF0uc2V0RnJvbVBvaW50c0ZpZWxkKHMsIngiKSxjWzFdLnNldEZyb21Qb2ludHNGaWVsZChzLCJ5IiksY1syXS5zZXRGcm9tUG9pbnRzRmllbGQocywieiIpLHRoaXMuaW52TWF0cml4LmNvcHkodGhpcy5tYXRyaXgpLmludmVydCgpLHRoaXMubmVlZHNVcGRhdGU9ITF9fSgpLHp0LnByb3RvdHlwZS5pbnRlcnNlY3RzQm94PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgSWU7cmV0dXJuIGZ1bmN0aW9uKGUpe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCk7Y29uc3Qgbj1lLm1pbixzPWUubWF4LHI9dGhpcy5zYXRCb3VuZHMsbz10aGlzLnNhdEF4ZXMsYT10aGlzLmFsaWduZWRTYXRCb3VuZHM7aWYoaS5taW49bi54LGkubWF4PXMueCxhWzBdLmlzU2VwYXJhdGVkKGkpfHwoaS5taW49bi55LGkubWF4PXMueSxhWzFdLmlzU2VwYXJhdGVkKGkpKXx8KGkubWluPW4ueixpLm1heD1zLnosYVsyXS5pc1NlcGFyYXRlZChpKSkpcmV0dXJuITE7Zm9yKGxldCBjPTA7YzwzO2MrKyl7Y29uc3QgbD1vW2NdLGg9cltjXTtpZihpLnNldEZyb21Cb3gobCxlKSxoLmlzU2VwYXJhdGVkKGkpKXJldHVybiExfXJldHVybiEwfX0oKSx6dC5wcm90b3R5cGUuaW50ZXJzZWN0c1RyaWFuZ2xlPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgbmUsdD1uZXcgQXJyYXkoMyksZT1uZXcgSWUsbj1uZXcgSWUscz1uZXcgVDtyZXR1cm4gZnVuY3Rpb24obyl7dGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxvLmlzRXh0ZW5kZWRUcmlhbmdsZT9vLm5lZWRzVXBkYXRlJiZvLnVwZGF0ZSgpOihpLmNvcHkobyksaS51cGRhdGUoKSxvPWkpO2NvbnN0IGE9dGhpcy5zYXRCb3VuZHMsYz10aGlzLnNhdEF4ZXM7dFswXT1vLmEsdFsxXT1vLmIsdFsyXT1vLmM7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1hW2ZdLHA9Y1tmXTtpZihlLnNldEZyb21Qb2ludHMocCx0KSxkLmlzU2VwYXJhdGVkKGUpKXJldHVybiExfWNvbnN0IGw9by5zYXRCb3VuZHMsaD1vLnNhdEF4ZXMsdT10aGlzLnBvaW50cztmb3IobGV0IGY9MDtmPDM7ZisrKXtjb25zdCBkPWxbZl0scD1oW2ZdO2lmKGUuc2V0RnJvbVBvaW50cyhwLHUpLGQuaXNTZXBhcmF0ZWQoZSkpcmV0dXJuITF9Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1jW2ZdO2ZvcihsZXQgcD0wO3A8NDtwKyspe2NvbnN0IHk9aFtwXTtpZihzLmNyb3NzVmVjdG9ycyhkLHkpLGUuc2V0RnJvbVBvaW50cyhzLHQpLG4uc2V0RnJvbVBvaW50cyhzLHUpLGUuaXNTZXBhcmF0ZWQobikpcmV0dXJuITF9fXJldHVybiEwfX0oKSx6dC5wcm90b3R5cGUuY2xvc2VzdFBvaW50VG9Qb2ludD1mdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpLGUuY29weSh0KS5hcHBseU1hdHJpeDQodGhpcy5pbnZNYXRyaXgpLmNsYW1wKHRoaXMubWluLHRoaXMubWF4KS5hcHBseU1hdHJpeDQodGhpcy5tYXRyaXgpLGV9fSgpLHp0LnByb3RvdHlwZS5kaXN0YW5jZVRvUG9pbnQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBUO3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50KGUsaSksZS5kaXN0YW5jZVRvKGkpfX0oKSx6dC5wcm90b3R5cGUuZGlzdGFuY2VUb0JveD1mdW5jdGlvbigpe2NvbnN0IGk9WyJ4IiwieSIsInoiXSx0PW5ldyBBcnJheSgxMikuZmlsbCgpLm1hcCgoKT0+bmV3IFF0KSxlPW5ldyBBcnJheSgxMikuZmlsbCgpLm1hcCgoKT0+bmV3IFF0KSxuPW5ldyBULHM9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKG8sYT0wLGM9bnVsbCxsPW51bGwpe2lmKHRoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksdGhpcy5pbnRlcnNlY3RzQm94KG8pKXJldHVybihjfHxsKSYmKG8uZ2V0Q2VudGVyKHMpLHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChzLG4pLG8uY2xvc2VzdFBvaW50VG9Qb2ludChuLHMpLGMmJmMuY29weShuKSxsJiZsLmNvcHkocykpLDA7Y29uc3QgaD1hKmEsdT1vLm1pbixmPW8ubWF4LGQ9dGhpcy5wb2ludHM7bGV0IHA9MS8wO2ZvcihsZXQgbT0wO208ODttKyspe2NvbnN0IGc9ZFttXTtzLmNvcHkoZykuY2xhbXAodSxmKTtjb25zdCBiPWcuZGlzdGFuY2VUb1NxdWFyZWQocyk7aWYoYjxwJiYocD1iLGMmJmMuY29weShnKSxsJiZsLmNvcHkocyksYjxoKSlyZXR1cm4gTWF0aC5zcXJ0KGIpfWxldCB5PTA7Zm9yKGxldCBtPTA7bTwzO20rKylmb3IobGV0IGc9MDtnPD0xO2crKylmb3IobGV0IGI9MDtiPD0xO2IrKyl7Y29uc3Qgdz0obSsxKSUzLHg9KG0rMiklMyxNPWc8PHd8Yjw8eCxBPTE8PG18Zzw8d3xiPDx4LFM9ZFtNXSxfPWRbQV07dFt5XS5zZXQoUyxfKTtjb25zdCB6PWlbbV0sdj1pW3ddLEM9aVt4XSxQPWVbeV0sRj1QLnN0YXJ0LEI9UC5lbmQ7Rlt6XT11W3pdLEZbdl09Zz91W3ZdOmZbdl0sRltDXT1iP3VbQ106Zlt2XSxCW3pdPWZbel0sQlt2XT1nP3Vbdl06Zlt2XSxCW0NdPWI/dVtDXTpmW3ZdLHkrK31mb3IobGV0IG09MDttPD0xO20rKylmb3IobGV0IGc9MDtnPD0xO2crKylmb3IobGV0IGI9MDtiPD0xO2IrKyl7cy54PW0/Zi54OnUueCxzLnk9Zz9mLnk6dS55LHMuej1iP2Yuejp1LnosdGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50KHMsbik7Y29uc3Qgdz1zLmRpc3RhbmNlVG9TcXVhcmVkKG4pO2lmKHc8cCYmKHA9dyxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpLHc8aCkpcmV0dXJuIE1hdGguc3FydCh3KX1mb3IobGV0IG09MDttPDEyO20rKyl7Y29uc3QgZz10W21dO2ZvcihsZXQgYj0wO2I8MTI7YisrKXtjb25zdCB3PWVbYl07SG8oZyx3LG4scyk7Y29uc3QgeD1uLmRpc3RhbmNlVG9TcXVhcmVkKHMpO2lmKHg8cCYmKHA9eCxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpLHg8aCkpcmV0dXJuIE1hdGguc3FydCh4KX19cmV0dXJuIE1hdGguc3FydChwKX19KCk7Y2xhc3MgR297Y29uc3RydWN0b3IodCl7dGhpcy5fZ2V0TmV3UHJpbWl0aXZlPXQsdGhpcy5fcHJpbWl0aXZlcz1bXX1nZXRQcmltaXRpdmUoKXtjb25zdCB0PXRoaXMuX3ByaW1pdGl2ZXM7cmV0dXJuIHQubGVuZ3RoPT09MD90aGlzLl9nZXROZXdQcmltaXRpdmUoKTp0LnBvcCgpfXJlbGVhc2VQcmltaXRpdmUodCl7dGhpcy5fcHJpbWl0aXZlcy5wdXNoKHQpfX1jbGFzcyBBZCBleHRlbmRzIEdve2NvbnN0cnVjdG9yKCl7c3VwZXIoKCk9Pm5ldyBuZSl9fWNvbnN0IGllPW5ldyBBZDtjbGFzcyBTZHtjb25zdHJ1Y3Rvcigpe3RoaXMuZmxvYXQzMkFycmF5PW51bGwsdGhpcy51aW50MTZBcnJheT1udWxsLHRoaXMudWludDMyQXJyYXk9bnVsbDtjb25zdCB0PVtdO2xldCBlPW51bGw7dGhpcy5zZXRCdWZmZXI9bj0+e2UmJnQucHVzaChlKSxlPW4sdGhpcy5mbG9hdDMyQXJyYXk9bmV3IEZsb2F0MzJBcnJheShuKSx0aGlzLnVpbnQxNkFycmF5PW5ldyBVaW50MTZBcnJheShuKSx0aGlzLnVpbnQzMkFycmF5PW5ldyBVaW50MzJBcnJheShuKX0sdGhpcy5jbGVhckJ1ZmZlcj0oKT0+e2U9bnVsbCx0aGlzLmZsb2F0MzJBcnJheT1udWxsLHRoaXMudWludDE2QXJyYXk9bnVsbCx0aGlzLnVpbnQzMkFycmF5PW51bGwsdC5sZW5ndGghPT0wJiZ0aGlzLnNldEJ1ZmZlcih0LnBvcCgpKX19fWNvbnN0IG50PW5ldyBTZDtsZXQgdG4sWG47Y29uc3QgSm49W10sSXM9bmV3IEdvKCgpPT5uZXcgZ3QpO2Z1bmN0aW9uIF9kKGksdCxlLG4scyxyKXt0bj1Jcy5nZXRQcmltaXRpdmUoKSxYbj1Jcy5nZXRQcmltaXRpdmUoKSxKbi5wdXNoKHRuLFhuKSxudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IG89Wm8oMCxpLmdlb21ldHJ5LGUsbixzLHIpO250LmNsZWFyQnVmZmVyKCksSXMucmVsZWFzZVByaW1pdGl2ZSh0biksSXMucmVsZWFzZVByaW1pdGl2ZShYbiksSm4ucG9wKCksSm4ucG9wKCk7Y29uc3QgYT1Kbi5sZW5ndGg7cmV0dXJuIGE+MCYmKFhuPUpuW2EtMV0sdG49Sm5bYS0yXSksb31mdW5jdGlvbiBabyhpLHQsZSxuLHM9bnVsbCxyPTAsbz0wKXtjb25zdHtmbG9hdDMyQXJyYXk6YSx1aW50MTZBcnJheTpjLHVpbnQzMkFycmF5Omx9PW50O2xldCBoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVV0KGksbCksZD1LdChoLGMpO3JldHVybiBsdChpLGEsdG4pLG4oZixkLCExLG8scitpLHRuKX1lbHNle2xldCB6PWZ1bmN0aW9uKEMpe2NvbnN0e3VpbnQxNkFycmF5OlAsdWludDMyQXJyYXk6Rn09bnQ7bGV0IEI9QyoyO2Zvcig7IWt0KEIsUCk7KUM9dGUoQyksQj1DKjI7cmV0dXJuIFV0KEMsRil9LHY9ZnVuY3Rpb24oQyl7Y29uc3R7dWludDE2QXJyYXk6UCx1aW50MzJBcnJheTpGfT1udDtsZXQgQj1DKjI7Zm9yKDsha3QoQixQKTspQz1lZShDLEYpLEI9QyoyO3JldHVybiBVdChDLEYpK0t0KEIsUCl9O2NvbnN0IGY9dGUoaSksZD1lZShpLGwpO2xldCBwPWYseT1kLG0sZyxiLHc7aWYocyYmKGI9dG4sdz1YbixsdChwLGEsYiksbHQoeSxhLHcpLG09cyhiKSxnPXModyksZzxtKSl7cD1kLHk9Zjtjb25zdCBDPW07bT1nLGc9QyxiPXd9Ynx8KGI9dG4sbHQocCxhLGIpKTtjb25zdCB4PWt0KHAqMixjKSxNPWUoYix4LG0sbysxLHIrcCk7bGV0IEE7aWYoTT09PXNsKXtjb25zdCBDPXoocCksRj12KHApLUM7QT1uKEMsRiwhMCxvKzEscitwLGIpfWVsc2UgQT1NJiZabyhwLHQsZSxuLHMscixvKzEpO2lmKEEpcmV0dXJuITA7dz1YbixsdCh5LGEsdyk7Y29uc3QgUz1rdCh5KjIsYyksXz1lKHcsUyxnLG8rMSxyK3kpO2xldCBFO2lmKF89PT1zbCl7Y29uc3QgQz16KHkpLEY9dih5KS1DO0U9bihDLEYsITAsbysxLHIreSx3KX1lbHNlIEU9XyYmWm8oeSx0LGUsbixzLHIsbysxKTtyZXR1cm4hIUV9fWNvbnN0IEZpPW5ldyBULFhvPW5ldyBUO2Z1bmN0aW9uIHZkKGksdCxlPXt9LG49MCxzPTEvMCl7Y29uc3Qgcj1uKm4sbz1zKnM7bGV0IGE9MS8wLGM9bnVsbDtpZihpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpoPT4oRmkuY29weSh0KS5jbGFtcChoLm1pbixoLm1heCksRmkuZGlzdGFuY2VUb1NxdWFyZWQodCkpLGludGVyc2VjdHNCb3VuZHM6KGgsdSxmKT0+ZjxhJiZmPG8saW50ZXJzZWN0c1RyaWFuZ2xlOihoLHUpPT57aC5jbG9zZXN0UG9pbnRUb1BvaW50KHQsRmkpO2NvbnN0IGY9dC5kaXN0YW5jZVRvU3F1YXJlZChGaSk7cmV0dXJuIGY8YSYmKFhvLmNvcHkoRmkpLGE9ZixjPXUpLGY8cn19KSxhPT09MS8wKXJldHVybiBudWxsO2NvbnN0IGw9TWF0aC5zcXJ0KGEpO3JldHVybiBlLnBvaW50P2UucG9pbnQuY29weShYbyk6ZS5wb2ludD1Yby5jbG9uZSgpLGUuZGlzdGFuY2U9bCxlLmZhY2VJbmRleD1jLGV9Y29uc3QgemQ9cGFyc2VJbnQoSik+PTE2OSx5bj1uZXcgVCxtbj1uZXcgVCxnbj1uZXcgVCxrcz1uZXcgUixOcz1uZXcgUixScz1uZXcgUixwbD1uZXcgVCx5bD1uZXcgVCxtbD1uZXcgVCxJaT1uZXcgVDtmdW5jdGlvbiBUZChpLHQsZSxuLHMscixvLGEpe2xldCBjO2lmKHI9PT0xP2M9aS5pbnRlcnNlY3RUcmlhbmdsZShuLGUsdCwhMCxzKTpjPWkuaW50ZXJzZWN0VHJpYW5nbGUodCxlLG4sciE9PTIscyksYz09PW51bGwpcmV0dXJuIG51bGw7Y29uc3QgbD1pLm9yaWdpbi5kaXN0YW5jZVRvKHMpO3JldHVybiBsPG98fGw+YT9udWxsOntkaXN0YW5jZTpsLHBvaW50OnMuY2xvbmUoKX19ZnVuY3Rpb24gRWQoaSx0LGUsbixzLHIsbyxhLGMsbCxoKXt5bi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsciksbW4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG8pLGduLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxhKTtjb25zdCB1PVRkKGkseW4sbW4sZ24sSWksYyxsLGgpO2lmKHUpe2NvbnN0IGY9bmV3IFQ7ZXQuZ2V0QmFyeWNvb3JkKElpLHluLG1uLGduLGYpLG4mJihrcy5mcm9tQnVmZmVyQXR0cmlidXRlKG4sciksTnMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLG8pLFJzLmZyb21CdWZmZXJBdHRyaWJ1dGUobixhKSx1LnV2PWV0LmdldEludGVycG9sYXRpb24oSWkseW4sbW4sZ24sa3MsTnMsUnMsbmV3IFIpKSxzJiYoa3MuZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLHIpLE5zLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxvKSxScy5mcm9tQnVmZmVyQXR0cmlidXRlKHMsYSksdS51djE9ZXQuZ2V0SW50ZXJwb2xhdGlvbihJaSx5bixtbixnbixrcyxOcyxScyxuZXcgUikpLGUmJihwbC5mcm9tQnVmZmVyQXR0cmlidXRlKGUscikseWwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLG8pLG1sLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxhKSx1Lm5vcm1hbD1ldC5nZXRJbnRlcnBvbGF0aW9uKElpLHluLG1uLGduLHBsLHlsLG1sLG5ldyBUKSx1Lm5vcm1hbC5kb3QoaS5kaXJlY3Rpb24pPjAmJnUubm9ybWFsLm11bHRpcGx5U2NhbGFyKC0xKSk7Y29uc3QgZD17YTpyLGI6byxjOmEsbm9ybWFsOm5ldyBULG1hdGVyaWFsSW5kZXg6MH07ZXQuZ2V0Tm9ybWFsKHluLG1uLGduLGQubm9ybWFsKSx1LmZhY2U9ZCx1LmZhY2VJbmRleD1yLHpkJiYodS5iYXJ5Y29vcmQ9Zil9cmV0dXJuIHV9ZnVuY3Rpb24gTHMoaSx0LGUsbixzLHIsbyl7Y29uc3QgYT1uKjM7bGV0IGM9YSswLGw9YSsxLGg9YSsyO2NvbnN0IHU9aS5pbmRleDtpLmluZGV4JiYoYz11LmdldFgoYyksbD11LmdldFgobCksaD11LmdldFgoaCkpO2NvbnN0e3Bvc2l0aW9uOmYsbm9ybWFsOmQsdXY6cCx1djE6eX09aS5hdHRyaWJ1dGVzLG09RWQoZSxmLGQscCx5LGMsbCxoLHQscixvKTtyZXR1cm4gbT8obS5mYWNlSW5kZXg9bixzJiZzLnB1c2gobSksbSk6bnVsbH1mdW5jdGlvbiB5dChpLHQsZSxuKXtjb25zdCBzPWkuYSxyPWkuYixvPWkuYztsZXQgYT10LGM9dCsxLGw9dCsyO2UmJihhPWUuZ2V0WChhKSxjPWUuZ2V0WChjKSxsPWUuZ2V0WChsKSkscy54PW4uZ2V0WChhKSxzLnk9bi5nZXRZKGEpLHMuej1uLmdldFooYSksci54PW4uZ2V0WChjKSxyLnk9bi5nZXRZKGMpLHIuej1uLmdldFooYyksby54PW4uZ2V0WChsKSxvLnk9bi5nZXRZKGwpLG8uej1uLmdldFoobCl9ZnVuY3Rpb24gUGQoaSx0LGUsbixzLHIsbyxhKXtjb25zdHtnZW9tZXRyeTpjLF9pbmRpcmVjdEJ1ZmZlcjpsfT1pO2ZvcihsZXQgaD1uLHU9bitzO2g8dTtoKyspTHMoYyx0LGUsaCxyLG8sYSl9ZnVuY3Rpb24gQ2QoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YSxfaW5kaXJlY3RCdWZmZXI6Y309aTtsZXQgbD0xLzAsaD1udWxsO2ZvcihsZXQgdT1uLGY9bitzO3U8Zjt1Kyspe2xldCBkO2Q9THMoYSx0LGUsdSxudWxsLHIsbyksZCYmZC5kaXN0YW5jZTxsJiYoaD1kLGw9ZC5kaXN0YW5jZSl9cmV0dXJuIGh9ZnVuY3Rpb24gQmQoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YX09ZSx7aW5kZXg6Y309YSxsPWEuYXR0cmlidXRlcy5wb3NpdGlvbjtmb3IobGV0IGg9aSx1PXQraTtoPHU7aCsrKXtsZXQgZjtpZihmPWgseXQobyxmKjMsYyxsKSxvLm5lZWRzVXBkYXRlPSEwLG4obyxmLHMscikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gRmQoaSx0PW51bGwpe3QmJkFycmF5LmlzQXJyYXkodCkmJih0PW5ldyBTZXQodCkpO2NvbnN0IGU9aS5nZW9tZXRyeSxuPWUuaW5kZXg/ZS5pbmRleC5hcnJheTpudWxsLHM9ZS5hdHRyaWJ1dGVzLnBvc2l0aW9uO2xldCByLG8sYSxjLGw9MDtjb25zdCBoPWkuX3Jvb3RzO2ZvcihsZXQgZj0wLGQ9aC5sZW5ndGg7ZjxkO2YrKylyPWhbZl0sbz1uZXcgVWludDMyQXJyYXkociksYT1uZXcgVWludDE2QXJyYXkociksYz1uZXcgRmxvYXQzMkFycmF5KHIpLHUoMCxsKSxsKz1yLmJ5dGVMZW5ndGg7ZnVuY3Rpb24gdShmLGQscD0hMSl7Y29uc3QgeT1mKjI7aWYoYVt5KzE1XT09PVBzKXtjb25zdCBnPW9bZis2XSxiPWFbeSsxNF07bGV0IHc9MS8wLHg9MS8wLE09MS8wLEE9LTEvMCxTPS0xLzAsXz0tMS8wO2ZvcihsZXQgRT0zKmcsej0zKihnK2IpO0U8ejtFKyspe2xldCB2PW5bRV07Y29uc3QgQz1zLmdldFgodiksUD1zLmdldFkodiksRj1zLmdldFoodik7Qzx3JiYodz1DKSxDPkEmJihBPUMpLFA8eCYmKHg9UCksUD5TJiYoUz1QKSxGPE0mJihNPUYpLEY+XyYmKF89Ril9cmV0dXJuIGNbZiswXSE9PXd8fGNbZisxXSE9PXh8fGNbZisyXSE9PU18fGNbZiszXSE9PUF8fGNbZis0XSE9PVN8fGNbZis1XSE9PV8/KGNbZiswXT13LGNbZisxXT14LGNbZisyXT1NLGNbZiszXT1BLGNbZis0XT1TLGNbZis1XT1fLCEwKTohMX1lbHNle2NvbnN0IGc9Zis4LGI9b1tmKzZdLHc9ZytkLHg9YitkO2xldCBNPXAsQT0hMSxTPSExO3Q/TXx8KEE9dC5oYXModyksUz10Lmhhcyh4KSxNPSFBJiYhUyk6KEE9ITAsUz0hMCk7Y29uc3QgXz1NfHxBLEU9TXx8UztsZXQgej0hMTtfJiYoej11KGcsZCxNKSk7bGV0IHY9ITE7RSYmKHY9dShiLGQsTSkpO2NvbnN0IEM9enx8djtpZihDKWZvcihsZXQgUD0wO1A8MztQKyspe2NvbnN0IEY9ZytQLEI9YitQLEk9Y1tGXSxrPWNbRiszXSxEPWNbQl0sVT1jW0IrM107Y1tmK1BdPUk8RD9JOkQsY1tmK1ArM109az5VP2s6VX1yZXR1cm4gQ319fWZ1bmN0aW9uIGVuKGksdCxlLG4scyl7bGV0IHIsbyxhLGMsbCxoO2NvbnN0IHU9MS9lLmRpcmVjdGlvbi54LGY9MS9lLmRpcmVjdGlvbi55LGQ9MS9lLmRpcmVjdGlvbi56LHA9ZS5vcmlnaW4ueCx5PWUub3JpZ2luLnksbT1lLm9yaWdpbi56O2xldCBnPXRbaV0sYj10W2krM10sdz10W2krMV0seD10W2krMysxXSxNPXRbaSsyXSxBPXRbaSszKzJdO3JldHVybiB1Pj0wPyhyPShnLXApKnUsbz0oYi1wKSp1KToocj0oYi1wKSp1LG89KGctcCkqdSksZj49MD8oYT0ody15KSpmLGM9KHgteSkqZik6KGE9KHgteSkqZixjPSh3LXkpKmYpLHI+Y3x8YT5vfHwoKGE+cnx8aXNOYU4ocikpJiYocj1hKSwoYzxvfHxpc05hTihvKSkmJihvPWMpLGQ+PTA/KGw9KE0tbSkqZCxoPShBLW0pKmQpOihsPShBLW0pKmQsaD0oTS1tKSpkKSxyPmh8fGw+byk/ITE6KChsPnJ8fHIhPT1yKSYmKHI9bCksKGg8b3x8byE9PW8pJiYobz1oKSxyPD1zJiZvPj1uKX1mdW5jdGlvbiBJZChpLHQsZSxuLHMscixvLGEpe2NvbnN0e2dlb21ldHJ5OmMsX2luZGlyZWN0QnVmZmVyOmx9PWk7Zm9yKGxldCBoPW4sdT1uK3M7aDx1O2grKyl7bGV0IGY9bD9sW2hdOmg7THMoYyx0LGUsZixyLG8sYSl9fWZ1bmN0aW9uIGtkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmEsX2luZGlyZWN0QnVmZmVyOmN9PWk7bGV0IGw9MS8wLGg9bnVsbDtmb3IobGV0IHU9bixmPW4rczt1PGY7dSsrKXtsZXQgZDtkPUxzKGEsdCxlLGM/Y1t1XTp1LG51bGwscixvKSxkJiZkLmRpc3RhbmNlPGwmJihoPWQsbD1kLmRpc3RhbmNlKX1yZXR1cm4gaH1mdW5jdGlvbiBOZChpLHQsZSxuLHMscixvKXtjb25zdHtnZW9tZXRyeTphfT1lLHtpbmRleDpjfT1hLGw9YS5hdHRyaWJ1dGVzLnBvc2l0aW9uO2ZvcihsZXQgaD1pLHU9dCtpO2g8dTtoKyspe2xldCBmO2lmKGY9ZS5yZXNvbHZlVHJpYW5nbGVJbmRleChoKSx5dChvLGYqMyxjLGwpLG8ubmVlZHNVcGRhdGU9ITAsbihvLGYscyxyKSlyZXR1cm4hMH1yZXR1cm4hMX1mdW5jdGlvbiBSZChpLHQsZSxuLHMscixvKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pLEpvKDAsaSxlLG4scyxyLG8pLG50LmNsZWFyQnVmZmVyKCl9ZnVuY3Rpb24gSm8oaSx0LGUsbixzLHIsbyl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udCxoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVV0KGksbCksZD1LdChoLGMpO1BkKHQsZSxuLGYsZCxzLHIsbyl9ZWxzZXtjb25zdCBmPXRlKGkpO2VuKGYsYSxuLHIsbykmJkpvKGYsdCxlLG4scyxyLG8pO2NvbnN0IGQ9ZWUoaSxsKTtlbihkLGEsbixyLG8pJiZKbyhkLHQsZSxuLHMscixvKX19Y29uc3QgTGQ9WyJ4IiwieSIsInoiXTtmdW5jdGlvbiBPZChpLHQsZSxuLHMscil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPVlvKDAsaSxlLG4scyxyKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxvfWZ1bmN0aW9uIFlvKGksdCxlLG4scyxyKXtjb25zdHtmbG9hdDMyQXJyYXk6byx1aW50MTZBcnJheTphLHVpbnQzMkFycmF5OmN9PW50O2xldCBsPWkqMjtpZihrdChsLGEpKXtjb25zdCB1PVV0KGksYyksZj1LdChsLGEpO3JldHVybiBDZCh0LGUsbix1LGYscyxyKX1lbHNle2NvbnN0IHU9dWwoaSxjKSxmPUxkW3VdLHA9bi5kaXJlY3Rpb25bZl0+PTA7bGV0IHksbTtwPyh5PXRlKGkpLG09ZWUoaSxjKSk6KHk9ZWUoaSxjKSxtPXRlKGkpKTtjb25zdCBiPWVuKHksbyxuLHMscik/WW8oeSx0LGUsbixzLHIpOm51bGw7aWYoYil7Y29uc3QgTT1iLnBvaW50W2ZdO2lmKHA/TTw9b1ttK3VdOk0+PW9bbSt1KzNdKXJldHVybiBifWNvbnN0IHg9ZW4obSxvLG4scyxyKT9ZbyhtLHQsZSxuLHMscik6bnVsbDtyZXR1cm4gYiYmeD9iLmRpc3RhbmNlPD14LmRpc3RhbmNlP2I6eDpifHx4fHxudWxsfX1jb25zdCBPcz1uZXcgZ3QsWW49bmV3IG5lLGpuPW5ldyBuZSxraT1uZXcgc3QsZ2w9bmV3IHp0LERzPW5ldyB6dDtmdW5jdGlvbiBEZChpLHQsZSxuKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IHM9am8oMCxpLGUsbik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksc31mdW5jdGlvbiBqbyhpLHQsZSxuLHM9bnVsbCl7Y29uc3R7ZmxvYXQzMkFycmF5OnIsdWludDE2QXJyYXk6byx1aW50MzJBcnJheTphfT1udDtsZXQgYz1pKjI7aWYocz09PW51bGwmJihlLmJvdW5kaW5nQm94fHxlLmNvbXB1dGVCb3VuZGluZ0JveCgpLGdsLnNldChlLmJvdW5kaW5nQm94Lm1pbixlLmJvdW5kaW5nQm94Lm1heCxuKSxzPWdsKSxrdChjLG8pKXtjb25zdCBoPXQuZ2VvbWV0cnksdT1oLmluZGV4LGY9aC5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9ZS5pbmRleCxwPWUuYXR0cmlidXRlcy5wb3NpdGlvbix5PVV0KGksYSksbT1LdChjLG8pO2lmKGtpLmNvcHkobikuaW52ZXJ0KCksZS5ib3VuZHNUcmVlKXJldHVybiBsdChpLHIsRHMpLERzLm1hdHJpeC5jb3B5KGtpKSxEcy5uZWVkc1VwZGF0ZT0hMCxlLmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmI9PkRzLmludGVyc2VjdHNCb3goYiksaW50ZXJzZWN0c1RyaWFuZ2xlOmI9PntiLmEuYXBwbHlNYXRyaXg0KG4pLGIuYi5hcHBseU1hdHJpeDQobiksYi5jLmFwcGx5TWF0cml4NChuKSxiLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgdz15KjMseD0obSt5KSozO3c8eDt3Kz0zKWlmKHl0KGpuLHcsdSxmKSxqbi5uZWVkc1VwZGF0ZT0hMCxiLmludGVyc2VjdHNUcmlhbmdsZShqbikpcmV0dXJuITA7cmV0dXJuITF9fSk7Zm9yKGxldCBnPXkqMyxiPShtK3kpKjM7ZzxiO2crPTMpe3l0KFluLGcsdSxmKSxZbi5hLmFwcGx5TWF0cml4NChraSksWW4uYi5hcHBseU1hdHJpeDQoa2kpLFluLmMuYXBwbHlNYXRyaXg0KGtpKSxZbi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHc9MCx4PWQuY291bnQ7dzx4O3crPTMpaWYoeXQoam4sdyxkLHApLGpuLm5lZWRzVXBkYXRlPSEwLFluLmludGVyc2VjdHNUcmlhbmdsZShqbikpcmV0dXJuITB9fWVsc2V7Y29uc3QgaD1pKzgsdT1hW2krNl07cmV0dXJuIGx0KGgscixPcyksISEocy5pbnRlcnNlY3RzQm94KE9zKSYmam8oaCx0LGUsbixzKXx8KGx0KHUscixPcykscy5pbnRlcnNlY3RzQm94KE9zKSYmam8odSx0LGUsbixzKSkpfX1jb25zdCAkcz1uZXcgc3QsUW89bmV3IHp0LE5pPW5ldyB6dCwkZD1uZXcgVCxWZD1uZXcgVCxVZD1uZXcgVCxxZD1uZXcgVDtmdW5jdGlvbiBIZChpLHQsZSxuPXt9LHM9e30scj0wLG89MS8wKXt0LmJvdW5kaW5nQm94fHx0LmNvbXB1dGVCb3VuZGluZ0JveCgpLFFvLnNldCh0LmJvdW5kaW5nQm94Lm1pbix0LmJvdW5kaW5nQm94Lm1heCxlKSxRby5uZWVkc1VwZGF0ZT0hMDtjb25zdCBhPWkuZ2VvbWV0cnksYz1hLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1hLmluZGV4LGg9dC5hdHRyaWJ1dGVzLnBvc2l0aW9uLHU9dC5pbmRleCxmPWllLmdldFByaW1pdGl2ZSgpLGQ9aWUuZ2V0UHJpbWl0aXZlKCk7bGV0IHA9JGQseT1WZCxtPW51bGwsZz1udWxsO3MmJihtPVVkLGc9cWQpO2xldCBiPTEvMCx3PW51bGwseD1udWxsO3JldHVybiAkcy5jb3B5KGUpLmludmVydCgpLE5pLm1hdHJpeC5jb3B5KCRzKSxpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpNPT5Rby5kaXN0YW5jZVRvQm94KE0pLGludGVyc2VjdHNCb3VuZHM6KE0sQSxTKT0+UzxiJiZTPG8/KEEmJihOaS5taW4uY29weShNLm1pbiksTmkubWF4LmNvcHkoTS5tYXgpLE5pLm5lZWRzVXBkYXRlPSEwKSwhMCk6ITEsaW50ZXJzZWN0c1JhbmdlOihNLEEpPT57aWYodC5ib3VuZHNUcmVlKXJldHVybiB0LmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtib3VuZHNUcmF2ZXJzZU9yZGVyOl89Pk5pLmRpc3RhbmNlVG9Cb3goXyksaW50ZXJzZWN0c0JvdW5kczooXyxFLHopPT56PGImJno8byxpbnRlcnNlY3RzUmFuZ2U6KF8sRSk9Pntmb3IobGV0IHo9Xyx2PV8rRTt6PHY7eisrKXt5dChkLDMqeix1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCBDPU0sUD1NK0E7QzxQO0MrKyl7eXQoZiwzKkMsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IEY9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKEY8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1GLHc9Qyx4PXopLEY8cilyZXR1cm4hMH19fX0pO3tjb25zdCBTPVpuKHQpO2ZvcihsZXQgXz0wLEU9UztfPEU7XysrKXt5dChkLDMqXyx1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB6PU0sdj1NK0E7ejx2O3orKyl7eXQoZiwzKnosbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IEM9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKEM8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1DLHc9eix4PV8pLEM8cilyZXR1cm4hMH19fX19KSxpZS5yZWxlYXNlUHJpbWl0aXZlKGYpLGllLnJlbGVhc2VQcmltaXRpdmUoZCksYj09PTEvMD9udWxsOihuLnBvaW50P24ucG9pbnQuY29weSh5KTpuLnBvaW50PXkuY2xvbmUoKSxuLmRpc3RhbmNlPWIsbi5mYWNlSW5kZXg9dyxzJiYocy5wb2ludD9zLnBvaW50LmNvcHkoZyk6cy5wb2ludD1nLmNsb25lKCkscy5wb2ludC5hcHBseU1hdHJpeDQoJHMpLHkuYXBwbHlNYXRyaXg0KCRzKSxzLmRpc3RhbmNlPXkuc3ViKHMucG9pbnQpLmxlbmd0aCgpLHMuZmFjZUluZGV4PXgpLG4pfWZ1bmN0aW9uIFdkKGksdD1udWxsKXt0JiZBcnJheS5pc0FycmF5KHQpJiYodD1uZXcgU2V0KHQpKTtjb25zdCBlPWkuZ2VvbWV0cnksbj1lLmluZGV4P2UuaW5kZXguYXJyYXk6bnVsbCxzPWUuYXR0cmlidXRlcy5wb3NpdGlvbjtsZXQgcixvLGEsYyxsPTA7Y29uc3QgaD1pLl9yb290cztmb3IobGV0IGY9MCxkPWgubGVuZ3RoO2Y8ZDtmKyspcj1oW2ZdLG89bmV3IFVpbnQzMkFycmF5KHIpLGE9bmV3IFVpbnQxNkFycmF5KHIpLGM9bmV3IEZsb2F0MzJBcnJheShyKSx1KDAsbCksbCs9ci5ieXRlTGVuZ3RoO2Z1bmN0aW9uIHUoZixkLHA9ITEpe2NvbnN0IHk9ZioyO2lmKGFbeSsxNV09PT1Qcyl7Y29uc3QgZz1vW2YrNl0sYj1hW3krMTRdO2xldCB3PTEvMCx4PTEvMCxNPTEvMCxBPS0xLzAsUz0tMS8wLF89LTEvMDtmb3IobGV0IEU9Zyx6PWcrYjtFPHo7RSsrKXtjb25zdCB2PTMqaS5yZXNvbHZlVHJpYW5nbGVJbmRleChFKTtmb3IobGV0IEM9MDtDPDM7QysrKXtsZXQgUD12K0M7UD1uP25bUF06UDtjb25zdCBGPXMuZ2V0WChQKSxCPXMuZ2V0WShQKSxJPXMuZ2V0WihQKTtGPHcmJih3PUYpLEY+QSYmKEE9RiksQjx4JiYoeD1CKSxCPlMmJihTPUIpLEk8TSYmKE09SSksST5fJiYoXz1JKX19cmV0dXJuIGNbZiswXSE9PXd8fGNbZisxXSE9PXh8fGNbZisyXSE9PU18fGNbZiszXSE9PUF8fGNbZis0XSE9PVN8fGNbZis1XSE9PV8/KGNbZiswXT13LGNbZisxXT14LGNbZisyXT1NLGNbZiszXT1BLGNbZis0XT1TLGNbZis1XT1fLCEwKTohMX1lbHNle2NvbnN0IGc9Zis4LGI9b1tmKzZdLHc9ZytkLHg9YitkO2xldCBNPXAsQT0hMSxTPSExO3Q/TXx8KEE9dC5oYXModyksUz10Lmhhcyh4KSxNPSFBJiYhUyk6KEE9ITAsUz0hMCk7Y29uc3QgXz1NfHxBLEU9TXx8UztsZXQgej0hMTtfJiYoej11KGcsZCxNKSk7bGV0IHY9ITE7RSYmKHY9dShiLGQsTSkpO2NvbnN0IEM9enx8djtpZihDKWZvcihsZXQgUD0wO1A8MztQKyspe2NvbnN0IEY9ZytQLEI9YitQLEk9Y1tGXSxrPWNbRiszXSxEPWNbQl0sVT1jW0IrM107Y1tmK1BdPUk8RD9JOkQsY1tmK1ArM109az5VP2s6VX1yZXR1cm4gQ319fWZ1bmN0aW9uIEdkKGksdCxlLG4scyxyLG8pe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSksS28oMCxpLGUsbixzLHIsbyksbnQuY2xlYXJCdWZmZXIoKX1mdW5jdGlvbiBLbyhpLHQsZSxuLHMscixvKXtjb25zdHtmbG9hdDMyQXJyYXk6YSx1aW50MTZBcnJheTpjLHVpbnQzMkFycmF5Omx9PW50LGg9aSoyO2lmKGt0KGgsYykpe2NvbnN0IGY9VXQoaSxsKSxkPUt0KGgsYyk7SWQodCxlLG4sZixkLHMscixvKX1lbHNle2NvbnN0IGY9dGUoaSk7ZW4oZixhLG4scixvKSYmS28oZix0LGUsbixzLHIsbyk7Y29uc3QgZD1lZShpLGwpO2VuKGQsYSxuLHIsbykmJktvKGQsdCxlLG4scyxyLG8pfX1jb25zdCBaZD1bIngiLCJ5IiwieiJdO2Z1bmN0aW9uIFhkKGksdCxlLG4scyxyKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IG89dGEoMCxpLGUsbixzLHIpO3JldHVybiBudC5jbGVhckJ1ZmZlcigpLG99ZnVuY3Rpb24gdGEoaSx0LGUsbixzLHIpe2NvbnN0e2Zsb2F0MzJBcnJheTpvLHVpbnQxNkFycmF5OmEsdWludDMyQXJyYXk6Y309bnQ7bGV0IGw9aSoyO2lmKGt0KGwsYSkpe2NvbnN0IHU9VXQoaSxjKSxmPUt0KGwsYSk7cmV0dXJuIGtkKHQsZSxuLHUsZixzLHIpfWVsc2V7Y29uc3QgdT11bChpLGMpLGY9WmRbdV0scD1uLmRpcmVjdGlvbltmXT49MDtsZXQgeSxtO3A/KHk9dGUoaSksbT1lZShpLGMpKTooeT1lZShpLGMpLG09dGUoaSkpO2NvbnN0IGI9ZW4oeSxvLG4scyxyKT90YSh5LHQsZSxuLHMscik6bnVsbDtpZihiKXtjb25zdCBNPWIucG9pbnRbZl07aWYocD9NPD1vW20rdV06TT49b1ttK3UrM10pcmV0dXJuIGJ9Y29uc3QgeD1lbihtLG8sbixzLHIpP3RhKG0sdCxlLG4scyxyKTpudWxsO3JldHVybiBiJiZ4P2IuZGlzdGFuY2U8PXguZGlzdGFuY2U/Yjp4OmJ8fHh8fG51bGx9fWNvbnN0IFZzPW5ldyBndCxRbj1uZXcgbmUsS249bmV3IG5lLFJpPW5ldyBzdCx4bD1uZXcgenQsVXM9bmV3IHp0O2Z1bmN0aW9uIEpkKGksdCxlLG4pe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSk7Y29uc3Qgcz1lYSgwLGksZSxuKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxzfWZ1bmN0aW9uIGVhKGksdCxlLG4scz1udWxsKXtjb25zdHtmbG9hdDMyQXJyYXk6cix1aW50MTZBcnJheTpvLHVpbnQzMkFycmF5OmF9PW50O2xldCBjPWkqMjtpZihzPT09bnVsbCYmKGUuYm91bmRpbmdCb3h8fGUuY29tcHV0ZUJvdW5kaW5nQm94KCkseGwuc2V0KGUuYm91bmRpbmdCb3gubWluLGUuYm91bmRpbmdCb3gubWF4LG4pLHM9eGwpLGt0KGMsbykpe2NvbnN0IGg9dC5nZW9tZXRyeSx1PWguaW5kZXgsZj1oLmF0dHJpYnV0ZXMucG9zaXRpb24sZD1lLmluZGV4LHA9ZS5hdHRyaWJ1dGVzLnBvc2l0aW9uLHk9VXQoaSxhKSxtPUt0KGMsbyk7aWYoUmkuY29weShuKS5pbnZlcnQoKSxlLmJvdW5kc1RyZWUpcmV0dXJuIGx0KGkscixVcyksVXMubWF0cml4LmNvcHkoUmkpLFVzLm5lZWRzVXBkYXRlPSEwLGUuYm91bmRzVHJlZS5zaGFwZWNhc3Qoe2ludGVyc2VjdHNCb3VuZHM6Yj0+VXMuaW50ZXJzZWN0c0JveChiKSxpbnRlcnNlY3RzVHJpYW5nbGU6Yj0+e2IuYS5hcHBseU1hdHJpeDQobiksYi5iLmFwcGx5TWF0cml4NChuKSxiLmMuYXBwbHlNYXRyaXg0KG4pLGIubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB3PXkseD1tK3k7dzx4O3crKylpZih5dChLbiwzKnQucmVzb2x2ZVRyaWFuZ2xlSW5kZXgodyksdSxmKSxLbi5uZWVkc1VwZGF0ZT0hMCxiLmludGVyc2VjdHNUcmlhbmdsZShLbikpcmV0dXJuITA7cmV0dXJuITF9fSk7Zm9yKGxldCBnPXksYj1tK3k7ZzxiO2crKyl7Y29uc3Qgdz10LnJlc29sdmVUcmlhbmdsZUluZGV4KGcpO3l0KFFuLDMqdyx1LGYpLFFuLmEuYXBwbHlNYXRyaXg0KFJpKSxRbi5iLmFwcGx5TWF0cml4NChSaSksUW4uYy5hcHBseU1hdHJpeDQoUmkpLFFuLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgeD0wLE09ZC5jb3VudDt4PE07eCs9MylpZih5dChLbix4LGQscCksS24ubmVlZHNVcGRhdGU9ITAsUW4uaW50ZXJzZWN0c1RyaWFuZ2xlKEtuKSlyZXR1cm4hMH19ZWxzZXtjb25zdCBoPWkrOCx1PWFbaSs2XTtyZXR1cm4gbHQoaCxyLFZzKSwhIShzLmludGVyc2VjdHNCb3goVnMpJiZlYShoLHQsZSxuLHMpfHwobHQodSxyLFZzKSxzLmludGVyc2VjdHNCb3goVnMpJiZlYSh1LHQsZSxuLHMpKSl9fWNvbnN0IHFzPW5ldyBzdCxuYT1uZXcgenQsTGk9bmV3IHp0LFlkPW5ldyBULGpkPW5ldyBULFFkPW5ldyBULEtkPW5ldyBUO2Z1bmN0aW9uIHQwKGksdCxlLG49e30scz17fSxyPTAsbz0xLzApe3QuYm91bmRpbmdCb3h8fHQuY29tcHV0ZUJvdW5kaW5nQm94KCksbmEuc2V0KHQuYm91bmRpbmdCb3gubWluLHQuYm91bmRpbmdCb3gubWF4LGUpLG5hLm5lZWRzVXBkYXRlPSEwO2NvbnN0IGE9aS5nZW9tZXRyeSxjPWEuYXR0cmlidXRlcy5wb3NpdGlvbixsPWEuaW5kZXgsaD10LmF0dHJpYnV0ZXMucG9zaXRpb24sdT10LmluZGV4LGY9aWUuZ2V0UHJpbWl0aXZlKCksZD1pZS5nZXRQcmltaXRpdmUoKTtsZXQgcD1ZZCx5PWpkLG09bnVsbCxnPW51bGw7cyYmKG09UWQsZz1LZCk7bGV0IGI9MS8wLHc9bnVsbCx4PW51bGw7cmV0dXJuIHFzLmNvcHkoZSkuaW52ZXJ0KCksTGkubWF0cml4LmNvcHkocXMpLGkuc2hhcGVjYXN0KHtib3VuZHNUcmF2ZXJzZU9yZGVyOk09Pm5hLmRpc3RhbmNlVG9Cb3goTSksaW50ZXJzZWN0c0JvdW5kczooTSxBLFMpPT5TPGImJlM8bz8oQSYmKExpLm1pbi5jb3B5KE0ubWluKSxMaS5tYXguY29weShNLm1heCksTGkubmVlZHNVcGRhdGU9ITApLCEwKTohMSxpbnRlcnNlY3RzUmFuZ2U6KE0sQSk9PntpZih0LmJvdW5kc1RyZWUpe2NvbnN0IFM9dC5ib3VuZHNUcmVlO3JldHVybiBTLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpfPT5MaS5kaXN0YW5jZVRvQm94KF8pLGludGVyc2VjdHNCb3VuZHM6KF8sRSx6KT0+ejxiJiZ6PG8saW50ZXJzZWN0c1JhbmdlOihfLEUpPT57Zm9yKGxldCB6PV8sdj1fK0U7ejx2O3orKyl7Y29uc3QgQz1TLnJlc29sdmVUcmlhbmdsZUluZGV4KHopO3l0KGQsMypDLHUsaCksZC5hLmFwcGx5TWF0cml4NChlKSxkLmIuYXBwbHlNYXRyaXg0KGUpLGQuYy5hcHBseU1hdHJpeDQoZSksZC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IFA9TSxGPU0rQTtQPEY7UCsrKXtjb25zdCBCPWkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoUCk7eXQoZiwzKkIsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IEk9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKEk8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1JLHc9UCx4PXopLEk8cilyZXR1cm4hMH19fX0pfWVsc2V7Y29uc3QgUz1abih0KTtmb3IobGV0IF89MCxFPVM7XzxFO18rKyl7eXQoZCwzKl8sdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgej1NLHY9TStBO3o8djt6Kyspe2NvbnN0IEM9aS5yZXNvbHZlVHJpYW5nbGVJbmRleCh6KTt5dChmLDMqQyxsLGMpLGYubmVlZHNVcGRhdGU9ITA7Y29uc3QgUD1mLmRpc3RhbmNlVG9UcmlhbmdsZShkLHAsbSk7aWYoUDxiJiYoeS5jb3B5KHApLGcmJmcuY29weShtKSxiPVAsdz16LHg9XyksUDxyKXJldHVybiEwfX19fX0pLGllLnJlbGVhc2VQcmltaXRpdmUoZiksaWUucmVsZWFzZVByaW1pdGl2ZShkKSxiPT09MS8wP251bGw6KG4ucG9pbnQ/bi5wb2ludC5jb3B5KHkpOm4ucG9pbnQ9eS5jbG9uZSgpLG4uZGlzdGFuY2U9YixuLmZhY2VJbmRleD13LHMmJihzLnBvaW50P3MucG9pbnQuY29weShnKTpzLnBvaW50PWcuY2xvbmUoKSxzLnBvaW50LmFwcGx5TWF0cml4NChxcykseS5hcHBseU1hdHJpeDQocXMpLHMuZGlzdGFuY2U9eS5zdWIocy5wb2ludCkubGVuZ3RoKCkscy5mYWNlSW5kZXg9eCksbil9ZnVuY3Rpb24gZTAoKXtyZXR1cm4gdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIn1jb25zdCBPaT1uZXcgbnQuY29uc3RydWN0b3IsSHM9bmV3IG50LmNvbnN0cnVjdG9yLG5uPW5ldyBHbygoKT0+bmV3IGd0KSx0aT1uZXcgZ3QsZWk9bmV3IGd0LGlhPW5ldyBndCxzYT1uZXcgZ3Q7bGV0IHJhPSExO2Z1bmN0aW9uIG4wKGksdCxlLG4pe2lmKHJhKXRocm93IG5ldyBFcnJvcigiTWVzaEJWSDogUmVjdXJzaXZlIGNhbGxzIHRvIGJ2aGNhc3Qgbm90IHN1cHBvcnRlZC4iKTtyYT0hMDtjb25zdCBzPWkuX3Jvb3RzLHI9dC5fcm9vdHM7bGV0IG8sYT0wLGM9MDtjb25zdCBsPW5ldyBzdCgpLmNvcHkoZSkuaW52ZXJ0KCk7Zm9yKGxldCBoPTAsdT1zLmxlbmd0aDtoPHU7aCsrKXtPaS5zZXRCdWZmZXIoc1toXSksYz0wO2NvbnN0IGY9bm4uZ2V0UHJpbWl0aXZlKCk7bHQoMCxPaS5mbG9hdDMyQXJyYXksZiksZi5hcHBseU1hdHJpeDQobCk7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHAmJihIcy5zZXRCdWZmZXIocltkXSksbz1mZSgwLDAsZSxsLG4sYSxjLDAsMCxmKSxIcy5jbGVhckJ1ZmZlcigpLGMrPXJbZF0ubGVuZ3RoLCFvKTtkKyspO2lmKG5uLnJlbGVhc2VQcmltaXRpdmUoZiksT2kuY2xlYXJCdWZmZXIoKSxhKz1zW2hdLmxlbmd0aCxvKWJyZWFrfXJldHVybiByYT0hMSxvfWZ1bmN0aW9uIGZlKGksdCxlLG4scyxyPTAsbz0wLGE9MCxjPTAsbD1udWxsLGg9ITEpe2xldCB1LGY7aD8odT1IcyxmPU9pKToodT1PaSxmPUhzKTtjb25zdCBkPXUuZmxvYXQzMkFycmF5LHA9dS51aW50MzJBcnJheSx5PXUudWludDE2QXJyYXksbT1mLmZsb2F0MzJBcnJheSxnPWYudWludDMyQXJyYXksYj1mLnVpbnQxNkFycmF5LHc9aSoyLHg9dCoyLE09a3Qodyx5KSxBPWt0KHgsYik7bGV0IFM9ITE7aWYoQSYmTSloP1M9cyhVdCh0LGcpLEt0KHQqMixiKSxVdChpLHApLEt0KGkqMix5KSxjLG8rdCxhLHIraSk6Uz1zKFV0KGkscCksS3QoaSoyLHkpLFV0KHQsZyksS3QodCoyLGIpLGEscitpLGMsbyt0KTtlbHNlIGlmKEEpe2NvbnN0IF89bm4uZ2V0UHJpbWl0aXZlKCk7bHQodCxtLF8pLF8uYXBwbHlNYXRyaXg0KGUpO2NvbnN0IEU9dGUoaSksej1lZShpLHApO2x0KEUsZCx0aSksbHQoeixkLGVpKTtjb25zdCB2PV8uaW50ZXJzZWN0c0JveCh0aSksQz1fLmludGVyc2VjdHNCb3goZWkpO1M9diYmZmUodCxFLG4sZSxzLG8scixjLGErMSxfLCFoKXx8QyYmZmUodCx6LG4sZSxzLG8scixjLGErMSxfLCFoKSxubi5yZWxlYXNlUHJpbWl0aXZlKF8pfWVsc2V7Y29uc3QgXz10ZSh0KSxFPWVlKHQsZyk7bHQoXyxtLGlhKSxsdChFLG0sc2EpO2NvbnN0IHo9bC5pbnRlcnNlY3RzQm94KGlhKSx2PWwuaW50ZXJzZWN0c0JveChzYSk7aWYoeiYmdilTPWZlKGksXyxlLG4scyxyLG8sYSxjKzEsbCxoKXx8ZmUoaSxFLGUsbixzLHIsbyxhLGMrMSxsLGgpO2Vsc2UgaWYoeilpZihNKVM9ZmUoaSxfLGUsbixzLHIsbyxhLGMrMSxsLGgpO2Vsc2V7Y29uc3QgQz1ubi5nZXRQcmltaXRpdmUoKTtDLmNvcHkoaWEpLmFwcGx5TWF0cml4NChlKTtjb25zdCBQPXRlKGkpLEY9ZWUoaSxwKTtsdChQLGQsdGkpLGx0KEYsZCxlaSk7Y29uc3QgQj1DLmludGVyc2VjdHNCb3godGkpLEk9Qy5pbnRlcnNlY3RzQm94KGVpKTtTPUImJmZlKF8sUCxuLGUscyxvLHIsYyxhKzEsQywhaCl8fEkmJmZlKF8sRixuLGUscyxvLHIsYyxhKzEsQywhaCksbm4ucmVsZWFzZVByaW1pdGl2ZShDKX1lbHNlIGlmKHYpaWYoTSlTPWZlKGksRSxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNle2NvbnN0IEM9bm4uZ2V0UHJpbWl0aXZlKCk7Qy5jb3B5KHNhKS5hcHBseU1hdHJpeDQoZSk7Y29uc3QgUD10ZShpKSxGPWVlKGkscCk7bHQoUCxkLHRpKSxsdChGLGQsZWkpO2NvbnN0IEI9Qy5pbnRlcnNlY3RzQm94KHRpKSxJPUMuaW50ZXJzZWN0c0JveChlaSk7Uz1CJiZmZShFLFAsbixlLHMsbyxyLGMsYSsxLEMsIWgpfHxJJiZmZShFLEYsbixlLHMsbyxyLGMsYSsxLEMsIWgpLG5uLnJlbGVhc2VQcmltaXRpdmUoQyl9fXJldHVybiBTfWNvbnN0IFdzPW5ldyB6dCx3bD1uZXcgZ3QsaTA9e3N0cmF0ZWd5OmlsLG1heERlcHRoOjQwLG1heExlYWZUcmlzOjEwLHVzZVNoYXJlZEFycmF5QnVmZmVyOiExLHNldEJvdW5kaW5nQm94OiEwLG9uUHJvZ3Jlc3M6bnVsbCxpbmRpcmVjdDohMSx2ZXJib3NlOiEwLHJhbmdlOm51bGx9O2NsYXNzIG9he3N0YXRpYyBzZXJpYWxpemUodCxlPXt9KXtlPUZ0KHtjbG9uZUJ1ZmZlcnM6ITB9LGUpO2NvbnN0IG49dC5nZW9tZXRyeSxzPXQuX3Jvb3RzLHI9dC5faW5kaXJlY3RCdWZmZXIsbz1uLmdldEluZGV4KCk7bGV0IGE7cmV0dXJuIGUuY2xvbmVCdWZmZXJzP2E9e3Jvb3RzOnMubWFwKGM9PmMuc2xpY2UoKSksaW5kZXg6bz9vLmFycmF5LnNsaWNlKCk6bnVsbCxpbmRpcmVjdEJ1ZmZlcjpyP3Iuc2xpY2UoKTpudWxsfTphPXtyb290czpzLGluZGV4Om8/by5hcnJheTpudWxsLGluZGlyZWN0QnVmZmVyOnJ9LGF9c3RhdGljIGRlc2VyaWFsaXplKHQsZSxuPXt9KXtuPUZ0KHtzZXRJbmRleDohMCxpbmRpcmVjdDohIXQuaW5kaXJlY3RCdWZmZXJ9LG4pO2NvbnN0e2luZGV4OnMscm9vdHM6cixpbmRpcmVjdEJ1ZmZlcjpvfT10LGE9bmV3IG9hKGUsWmUoRnQoe30sbikse1tEb106ITB9KSk7aWYoYS5fcm9vdHM9cixhLl9pbmRpcmVjdEJ1ZmZlcj1vfHxudWxsLG4uc2V0SW5kZXgpe2NvbnN0IGM9ZS5nZXRJbmRleCgpO2lmKGM9PT1udWxsKXtjb25zdCBsPW5ldyB4dCh0LmluZGV4LDEsITEpO2Uuc2V0SW5kZXgobCl9ZWxzZSBjLmFycmF5IT09cyYmKGMuYXJyYXkuc2V0KHMpLGMubmVlZHNVcGRhdGU9ITApfXJldHVybiBhfWdldCBpbmRpcmVjdCgpe3JldHVybiEhdGhpcy5faW5kaXJlY3RCdWZmZXJ9Y29uc3RydWN0b3IodCxlPXt9KXtpZih0LmlzQnVmZmVyR2VvbWV0cnkpe2lmKHQuaW5kZXgmJnQuaW5kZXguaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IEludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHRoZSBpbmRleCBhdHRyaWJ1dGUuIil9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IE9ubHkgQnVmZmVyR2VvbWV0cmllcyBhcmUgc3VwcG9ydGVkLiIpO2lmKGU9T2JqZWN0LmFzc2lnbihaZShGdCh7fSxpMCkse1tEb106ITF9KSxlKSxlLnVzZVNoYXJlZEFycmF5QnVmZmVyJiYhZTAoKSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IFNoYXJlZEFycmF5QnVmZmVyIGlzIG5vdCBhdmFpbGFibGUuIik7dGhpcy5nZW9tZXRyeT10LHRoaXMuX3Jvb3RzPW51bGwsdGhpcy5faW5kaXJlY3RCdWZmZXI9bnVsbCxlW0RvXXx8KHhkKHRoaXMsZSksIXQuYm91bmRpbmdCb3gmJmUuc2V0Qm91bmRpbmdCb3gmJih0LmJvdW5kaW5nQm94PXRoaXMuZ2V0Qm91bmRpbmdCb3gobmV3IGd0KSkpLHRoaXMucmVzb2x2ZVRyaWFuZ2xlSW5kZXg9ZS5pbmRpcmVjdD9uPT50aGlzLl9pbmRpcmVjdEJ1ZmZlcltuXTpuPT5ufXJlZml0KHQ9bnVsbCl7cmV0dXJuKHRoaXMuaW5kaXJlY3Q/V2Q6RmQpKHRoaXMsdCl9dHJhdmVyc2UodCxlPTApe2NvbnN0IG49dGhpcy5fcm9vdHNbZV0scz1uZXcgVWludDMyQXJyYXkobikscj1uZXcgVWludDE2QXJyYXkobik7bygwKTtmdW5jdGlvbiBvKGEsYz0wKXtjb25zdCBsPWEqMixoPXJbbCsxNV09PT1QcztpZihoKXtjb25zdCB1PXNbYSs2XSxmPXJbbCsxNF07dChjLGgsbmV3IEZsb2F0MzJBcnJheShuLGEqNCw2KSx1LGYpfWVsc2V7Y29uc3QgdT1hK1BpLzQsZj1zW2ErNl0sZD1zW2ErN107dChjLGgsbmV3IEZsb2F0MzJBcnJheShuLGEqNCw2KSxkKXx8KG8odSxjKzEpLG8oZixjKzEpKX19fXJheWNhc3QodCxlPTAsbj0wLHM9MS8wKXtjb25zdCByPXRoaXMuX3Jvb3RzLG89dGhpcy5nZW9tZXRyeSxhPVtdLGM9ZS5pc01hdGVyaWFsLGw9QXJyYXkuaXNBcnJheShlKSxoPW8uZ3JvdXBzLHU9Yz9lLnNpZGU6ZSxmPXRoaXMuaW5kaXJlY3Q/R2Q6UmQ7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHA7ZCsrKXtjb25zdCB5PWw/ZVtoW2RdLm1hdGVyaWFsSW5kZXhdLnNpZGU6dSxtPWEubGVuZ3RoO2lmKGYodGhpcyxkLHksdCxhLG4scyksbCl7Y29uc3QgZz1oW2RdLm1hdGVyaWFsSW5kZXg7Zm9yKGxldCBiPW0sdz1hLmxlbmd0aDtiPHc7YisrKWFbYl0uZmFjZS5tYXRlcmlhbEluZGV4PWd9fXJldHVybiBhfXJheWNhc3RGaXJzdCh0LGU9MCxuPTAscz0xLzApe2NvbnN0IHI9dGhpcy5fcm9vdHMsbz10aGlzLmdlb21ldHJ5LGE9ZS5pc01hdGVyaWFsLGM9QXJyYXkuaXNBcnJheShlKTtsZXQgbD1udWxsO2NvbnN0IGg9by5ncm91cHMsdT1hP2Uuc2lkZTplLGY9dGhpcy5pbmRpcmVjdD9YZDpPZDtmb3IobGV0IGQ9MCxwPXIubGVuZ3RoO2Q8cDtkKyspe2NvbnN0IHk9Yz9lW2hbZF0ubWF0ZXJpYWxJbmRleF0uc2lkZTp1LG09Zih0aGlzLGQseSx0LG4scyk7bSE9bnVsbCYmKGw9PW51bGx8fG0uZGlzdGFuY2U8bC5kaXN0YW5jZSkmJihsPW0sYyYmKG0uZmFjZS5tYXRlcmlhbEluZGV4PWhbZF0ubWF0ZXJpYWxJbmRleCkpfXJldHVybiBsfWludGVyc2VjdHNHZW9tZXRyeSh0LGUpe2xldCBuPSExO2NvbnN0IHM9dGhpcy5fcm9vdHMscj10aGlzLmluZGlyZWN0P0pkOkRkO2ZvcihsZXQgbz0wLGE9cy5sZW5ndGg7bzxhJiYobj1yKHRoaXMsbyx0LGUpLCFuKTtvKyspO3JldHVybiBufXNoYXBlY2FzdCh0KXtjb25zdCBlPWllLmdldFByaW1pdGl2ZSgpLG49dGhpcy5pbmRpcmVjdD9OZDpCZDtsZXR7Ym91bmRzVHJhdmVyc2VPcmRlcjpzLGludGVyc2VjdHNCb3VuZHM6cixpbnRlcnNlY3RzUmFuZ2U6byxpbnRlcnNlY3RzVHJpYW5nbGU6YX09dDtpZihvJiZhKXtjb25zdCB1PW87bz0oZixkLHAseSxtKT0+dShmLGQscCx5LG0pPyEwOm4oZixkLHRoaXMsYSxwLHksZSl9ZWxzZSBvfHwoYT9vPSh1LGYsZCxwKT0+bih1LGYsdGhpcyxhLGQscCxlKTpvPSh1LGYsZCk9PmQpO2xldCBjPSExLGw9MDtjb25zdCBoPXRoaXMuX3Jvb3RzO2ZvcihsZXQgdT0wLGY9aC5sZW5ndGg7dTxmO3UrKyl7Y29uc3QgZD1oW3VdO2lmKGM9X2QodGhpcyx1LHIsbyxzLGwpLGMpYnJlYWs7bCs9ZC5ieXRlTGVuZ3RofXJldHVybiBpZS5yZWxlYXNlUHJpbWl0aXZlKGUpLGN9YnZoY2FzdCh0LGUsbil7bGV0e2ludGVyc2VjdHNSYW5nZXM6cyxpbnRlcnNlY3RzVHJpYW5nbGVzOnJ9PW47Y29uc3Qgbz1pZS5nZXRQcmltaXRpdmUoKSxhPXRoaXMuZ2VvbWV0cnkuaW5kZXgsYz10aGlzLmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb24sbD10aGlzLmluZGlyZWN0P3A9Pntjb25zdCB5PXRoaXMucmVzb2x2ZVRyaWFuZ2xlSW5kZXgocCk7eXQobyx5KjMsYSxjKX06cD0+e3l0KG8scCozLGEsYyl9LGg9aWUuZ2V0UHJpbWl0aXZlKCksdT10Lmdlb21ldHJ5LmluZGV4LGY9dC5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9dC5pbmRpcmVjdD9wPT57Y29uc3QgeT10LnJlc29sdmVUcmlhbmdsZUluZGV4KHApO3l0KGgseSozLHUsZil9OnA9Pnt5dChoLHAqMyx1LGYpfTtpZihyKXtjb25zdCBwPSh5LG0sZyxiLHcseCxNLEEpPT57Zm9yKGxldCBTPWcsXz1nK2I7UzxfO1MrKyl7ZChTKSxoLmEuYXBwbHlNYXRyaXg0KGUpLGguYi5hcHBseU1hdHJpeDQoZSksaC5jLmFwcGx5TWF0cml4NChlKSxoLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgRT15LHo9eSttO0U8ejtFKyspaWYobChFKSxvLm5lZWRzVXBkYXRlPSEwLHIobyxoLEUsUyx3LHgsTSxBKSlyZXR1cm4hMH1yZXR1cm4hMX07aWYocyl7Y29uc3QgeT1zO3M9ZnVuY3Rpb24obSxnLGIsdyx4LE0sQSxTKXtyZXR1cm4geShtLGcsYix3LHgsTSxBLFMpPyEwOnAobSxnLGIsdyx4LE0sQSxTKX19ZWxzZSBzPXB9cmV0dXJuIG4wKHRoaXMsdCxlLHMpfWludGVyc2VjdHNCb3godCxlKXtyZXR1cm4gV3Muc2V0KHQubWluLHQubWF4LGUpLFdzLm5lZWRzVXBkYXRlPSEwLHRoaXMuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOm49PldzLmludGVyc2VjdHNCb3gobiksaW50ZXJzZWN0c1RyaWFuZ2xlOm49PldzLmludGVyc2VjdHNUcmlhbmdsZShuKX0pfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHRoaXMuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmU9PnQuaW50ZXJzZWN0c0JveChlKSxpbnRlcnNlY3RzVHJpYW5nbGU6ZT0+ZS5pbnRlcnNlY3RzU3BoZXJlKHQpfSl9Y2xvc2VzdFBvaW50VG9HZW9tZXRyeSh0LGUsbj17fSxzPXt9LHI9MCxvPTEvMCl7cmV0dXJuKHRoaXMuaW5kaXJlY3Q/dDA6SGQpKHRoaXMsdCxlLG4scyxyLG8pfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlPXt9LG49MCxzPTEvMCl7cmV0dXJuIHZkKHRoaXMsdCxlLG4scyl9Z2V0Qm91bmRpbmdCb3godCl7cmV0dXJuIHQubWFrZUVtcHR5KCksdGhpcy5fcm9vdHMuZm9yRWFjaChuPT57bHQoMCxuZXcgRmxvYXQzMkFycmF5KG4pLHdsKSx0LnVuaW9uKHdsKX0pLHR9fWNvbnN0IGJsPTFlLTYsczA9YmwqLjUsTWw9TWF0aC5wb3coMTAsLU1hdGgubG9nMTAoYmwpKSxyMD1zMCpNbDtmdW5jdGlvbiB3ZShpKXtyZXR1cm5+fihpKk1sK3IwKX1mdW5jdGlvbiBvMChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9YH1mdW5jdGlvbiBBbChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9LCR7d2UoaS56KX1gfWZ1bmN0aW9uIGEwKGkpe3JldHVybmAke3dlKGkueCl9LCR7d2UoaS55KX0sJHt3ZShpLnopfSwke3dlKGkudyl9YH1mdW5jdGlvbiBjMChpLHQsZSl7ZS5kaXJlY3Rpb24uc3ViVmVjdG9ycyh0LGkpLm5vcm1hbGl6ZSgpO2NvbnN0IG49aS5kb3QoZS5kaXJlY3Rpb24pO3JldHVybiBlLm9yaWdpbi5jb3B5KGkpLmFkZFNjYWxlZFZlY3RvcihlLmRpcmVjdGlvbiwtbiksZX1mdW5jdGlvbiBTbCgpe3JldHVybiB0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIhPSJ1bmRlZmluZWQifWZ1bmN0aW9uIGwwKGkpe2lmKGkuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXIpcmV0dXJuIGk7Y29uc3QgdD1pLmNvbnN0cnVjdG9yLGU9aS5idWZmZXIsbj1uZXcgU2hhcmVkQXJyYXlCdWZmZXIoZS5ieXRlTGVuZ3RoKSxzPW5ldyBVaW50OEFycmF5KGUpO3JldHVybiBuZXcgVWludDhBcnJheShuKS5zZXQocywwKSxuZXcgdChuKX1mdW5jdGlvbiBoMChpLHQ9QXJyYXlCdWZmZXIpe3JldHVybiBpPjY1NTM1P25ldyBVaW50MzJBcnJheShuZXcgdCg0KmkpKTpuZXcgVWludDE2QXJyYXkobmV3IHQoMippKSl9ZnVuY3Rpb24gdTAoaSx0KXtpZighaS5pbmRleCl7Y29uc3QgZT1pLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQsbj10LnVzZVNoYXJlZEFycmF5QnVmZmVyP1NoYXJlZEFycmF5QnVmZmVyOkFycmF5QnVmZmVyLHM9aDAoZSxuKTtpLnNldEluZGV4KG5ldyB4dChzLDEpKTtmb3IobGV0IHI9MDtyPGU7cisrKXNbcl09cn19ZnVuY3Rpb24gZjAoaSl7cmV0dXJuIGkuaW5kZXg/aS5pbmRleC5jb3VudDppLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnR9ZnVuY3Rpb24gYWEoaSl7cmV0dXJuIGYwKGkpLzN9Y29uc3QgZDA9MWUtOCxwMD1uZXcgVDtmdW5jdGlvbiB5MChpKXtyZXR1cm5+fihpLzMpfWZ1bmN0aW9uIG0wKGkpe3JldHVybiBpJTN9ZnVuY3Rpb24gX2woaSx0KXtyZXR1cm4gaS5zdGFydC10LnN0YXJ0fWZ1bmN0aW9uIHZsKGksdCl7cmV0dXJuIHAwLnN1YlZlY3RvcnModCxpLm9yaWdpbikuZG90KGkuZGlyZWN0aW9uKX1mdW5jdGlvbiBnMChpLHQsZSxuPWQwKXtpLnNvcnQoX2wpLHQuc29ydChfbCk7Zm9yKGxldCBhPTA7YTxpLmxlbmd0aDthKyspe2NvbnN0IGM9aVthXTtmb3IobGV0IGw9MDtsPHQubGVuZ3RoO2wrKyl7Y29uc3QgaD10W2xdO2lmKCEoaC5zdGFydD5jLmVuZCkpe2lmKGMuZW5kPGguc3RhcnR8fGguZW5kPGMuc3RhcnQpY29udGludWU7aWYoYy5zdGFydDw9aC5zdGFydCYmYy5lbmQ+PWguZW5kKXIoaC5lbmQsYy5lbmQpfHxpLnNwbGljZShhKzEsMCx7c3RhcnQ6aC5lbmQsZW5kOmMuZW5kLGluZGV4OmMuaW5kZXh9KSxjLmVuZD1oLnN0YXJ0LGguc3RhcnQ9MCxoLmVuZD0wO2Vsc2UgaWYoYy5zdGFydD49aC5zdGFydCYmYy5lbmQ8PWguZW5kKXIoYy5lbmQsaC5lbmQpfHx0LnNwbGljZShsKzEsMCx7c3RhcnQ6Yy5lbmQsZW5kOmguZW5kLGluZGV4OmguaW5kZXh9KSxoLmVuZD1jLnN0YXJ0LGMuc3RhcnQ9MCxjLmVuZD0wO2Vsc2UgaWYoYy5zdGFydDw9aC5zdGFydCYmYy5lbmQ8PWguZW5kKXtjb25zdCB1PWMuZW5kO2MuZW5kPWguc3RhcnQsaC5zdGFydD11fWVsc2UgaWYoYy5zdGFydD49aC5zdGFydCYmYy5lbmQ+PWguZW5kKXtjb25zdCB1PWguZW5kO2guZW5kPWMuc3RhcnQsYy5zdGFydD11fWVsc2UgdGhyb3cgbmV3IEVycm9yfWlmKGUuaGFzKGMuaW5kZXgpfHxlLnNldChjLmluZGV4LFtdKSxlLmhhcyhoLmluZGV4KXx8ZS5zZXQoaC5pbmRleCxbXSksZS5nZXQoYy5pbmRleCkucHVzaChoLmluZGV4KSxlLmdldChoLmluZGV4KS5wdXNoKGMuaW5kZXgpLG8oaCkmJih0LnNwbGljZShsLDEpLGwtLSksbyhjKSl7aS5zcGxpY2UoYSwxKSxhLS07YnJlYWt9fX1zKGkpLHModCk7ZnVuY3Rpb24gcyhhKXtmb3IobGV0IGM9MDtjPGEubGVuZ3RoO2MrKylvKGFbY10pJiYoYS5zcGxpY2UoYywxKSxjLS0pfWZ1bmN0aW9uIHIoYSxjKXtyZXR1cm4gTWF0aC5hYnMoYy1hKTxufWZ1bmN0aW9uIG8oYSl7cmV0dXJuIE1hdGguYWJzKGEuZW5kLWEuc3RhcnQpPG59fWNvbnN0IHpsPTFlLTUsVGw9MWUtNDtjbGFzcyB4MHtjb25zdHJ1Y3Rvcigpe3RoaXMuX3JheXM9W119YWRkUmF5KHQpe3RoaXMuX3JheXMucHVzaCh0KX1maW5kQ2xvc2VzdFJheSh0KXtjb25zdCBlPXRoaXMuX3JheXMsbj10LmNsb25lKCk7bi5kaXJlY3Rpb24ubXVsdGlwbHlTY2FsYXIoLTEpO2xldCBzPTEvMCxyPW51bGw7Zm9yKGxldCBjPTAsbD1lLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPWVbY107aWYobyhoLHQpJiZvKGgsbikpY29udGludWU7Y29uc3QgdT1hKGgsdCksZj1hKGgsbiksZD1NYXRoLm1pbih1LGYpO2Q8cyYmKHM9ZCxyPWgpfXJldHVybiByO2Z1bmN0aW9uIG8oYyxsKXtjb25zdCBoPWMub3JpZ2luLmRpc3RhbmNlVG8obC5vcmlnaW4pPnpsO3JldHVybiBjLmRpcmVjdGlvbi5hbmdsZVRvKGwuZGlyZWN0aW9uKT5UbHx8aH1mdW5jdGlvbiBhKGMsbCl7Y29uc3QgaD1jLm9yaWdpbi5kaXN0YW5jZVRvKGwub3JpZ2luKSx1PWMuZGlyZWN0aW9uLmFuZ2xlVG8obC5kaXJlY3Rpb24pO3JldHVybiBoL3psK3UvVGx9fX1jb25zdCBjYT1uZXcgVCxsYT1uZXcgVCxHcz1uZXcgZm87ZnVuY3Rpb24gdzAoaSx0LGUpe2NvbnN0IG49aS5hdHRyaWJ1dGVzLHM9aS5pbmRleCxyPW4ucG9zaXRpb24sbz1uZXcgTWFwLGE9bmV3IE1hcCxjPUFycmF5LmZyb20odCksbD1uZXcgeDA7Zm9yKGxldCBoPTAsdT1jLmxlbmd0aDtoPHU7aCsrKXtjb25zdCBmPWNbaF0sZD15MChmKSxwPW0wKGYpO2xldCB5PTMqZCtwLG09MypkKyhwKzEpJTM7cyYmKHk9cy5nZXRYKHkpLG09cy5nZXRYKG0pKSxjYS5mcm9tQnVmZmVyQXR0cmlidXRlKHIseSksbGEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLG0pLGMwKGNhLGxhLEdzKTtsZXQgZyxiPWwuZmluZENsb3Nlc3RSYXkoR3MpO2I9PT1udWxsJiYoYj1Hcy5jbG9uZSgpLGwuYWRkUmF5KGIpKSxhLmhhcyhiKXx8YS5zZXQoYix7Zm9yd2FyZDpbXSxyZXZlcnNlOltdLHJheTpifSksZz1hLmdldChiKTtsZXQgdz12bChiLGNhKSx4PXZsKGIsbGEpO3c+eCYmKFt3LHhdPVt4LHddKSxHcy5kaXJlY3Rpb24uZG90KGIuZGlyZWN0aW9uKTwwP2cucmV2ZXJzZS5wdXNoKHtzdGFydDp3LGVuZDp4LGluZGV4OmZ9KTpnLmZvcndhcmQucHVzaCh7c3RhcnQ6dyxlbmQ6eCxpbmRleDpmfSl9cmV0dXJuIGEuZm9yRWFjaCgoe2ZvcndhcmQ6aCxyZXZlcnNlOnV9LGYpPT57ZzAoaCx1LG8sZSksaC5sZW5ndGg9PT0wJiZ1Lmxlbmd0aD09PTAmJmEuZGVsZXRlKGYpfSkse2Rpc2pvaW50Q29ubmVjdGl2aXR5TWFwOm8sZnJhZ21lbnRNYXA6YX19Y29uc3QgYjA9bmV3IFIsaGE9bmV3IFQsTTA9bmV3IFl0LHVhPVsiIiwiIiwiIl07Y2xhc3MgQTB7Y29uc3RydWN0b3IodD1udWxsKXt0aGlzLmRhdGE9bnVsbCx0aGlzLmRpc2pvaW50Q29ubmVjdGlvbnM9bnVsbCx0aGlzLnVubWF0Y2hlZERpc2pvaW50RWRnZXM9bnVsbCx0aGlzLnVubWF0Y2hlZEVkZ2VzPS0xLHRoaXMubWF0Y2hlZEVkZ2VzPS0xLHRoaXMudXNlRHJhd1JhbmdlPSEwLHRoaXMudXNlQWxsQXR0cmlidXRlcz0hMSx0aGlzLm1hdGNoRGlzam9pbnRFZGdlcz0hMSx0aGlzLmRlZ2VuZXJhdGVFcHNpbG9uPTFlLTgsdCYmdGhpcy51cGRhdGVGcm9tKHQpfWdldFNpYmxpbmdUcmlhbmdsZUluZGV4KHQsZSl7Y29uc3Qgbj10aGlzLmRhdGFbdCozK2VdO3JldHVybiBuPT09LTE/LTE6fn4obi8zKX1nZXRTaWJsaW5nRWRnZUluZGV4KHQsZSl7Y29uc3Qgbj10aGlzLmRhdGFbdCozK2VdO3JldHVybiBuPT09LTE/LTE6biUzfWdldERpc2pvaW50U2libGluZ1RyaWFuZ2xlSW5kaWNlcyh0LGUpe2NvbnN0IG49dCozK2Uscz10aGlzLmRpc2pvaW50Q29ubmVjdGlvbnMuZ2V0KG4pO3JldHVybiBzP3MubWFwKHI9Pn5+KHIvMykpOltdfWdldERpc2pvaW50U2libGluZ0VkZ2VJbmRpY2VzKHQsZSl7Y29uc3Qgbj10KjMrZSxzPXRoaXMuZGlzam9pbnRDb25uZWN0aW9ucy5nZXQobik7cmV0dXJuIHM/cy5tYXAocj0+ciUzKTpbXX1pc0Z1bGx5Q29ubmVjdGVkKCl7cmV0dXJuIHRoaXMudW5tYXRjaGVkRWRnZXM9PT0wfXVwZGF0ZUZyb20odCl7Y29uc3R7dXNlQWxsQXR0cmlidXRlczplLHVzZURyYXdSYW5nZTpuLG1hdGNoRGlzam9pbnRFZGdlczpzLGRlZ2VuZXJhdGVFcHNpbG9uOnJ9PXRoaXMsbz1lP3c6YixhPW5ldyBNYXAse2F0dHJpYnV0ZXM6Y309dCxsPWU/T2JqZWN0LmtleXMoYyk6bnVsbCxoPXQuaW5kZXgsdT1jLnBvc2l0aW9uO2xldCBmPWFhKHQpO2NvbnN0IGQ9ZjtsZXQgcD0wO24mJihwPXQuZHJhd1JhbmdlLnN0YXJ0LHQuZHJhd1JhbmdlLmNvdW50IT09MS8wJiYoZj1+fih0LmRyYXdSYW5nZS5jb3VudC8zKSkpO2xldCB5PXRoaXMuZGF0YTsoIXl8fHkubGVuZ3RoPDMqZCkmJih5PW5ldyBJbnQzMkFycmF5KDMqZCkpLHkuZmlsbCgtMSk7bGV0IG09MCxnPW5ldyBTZXQ7Zm9yKGxldCB4PXAsTT1mKjMrcDt4PE07eCs9Myl7Y29uc3QgQT14O2ZvcihsZXQgUz0wO1M8MztTKyspe2xldCBfPUErUztoJiYoXz1oLmdldFgoXykpLHVhW1NdPW8oXyl9Zm9yKGxldCBTPTA7UzwzO1MrKyl7Y29uc3QgXz0oUysxKSUzLEU9dWFbU10sej11YVtfXSx2PWAke3p9XyR7RX1gO2lmKGEuaGFzKHYpKXtjb25zdCBDPUErUyxQPWEuZ2V0KHYpO3lbQ109UCx5W1BdPUMsYS5kZWxldGUodiksbSs9MixnLmRlbGV0ZShQKX1lbHNle2NvbnN0IEM9YCR7RX1fJHt6fWAsUD1BK1M7YS5zZXQoQyxQKSxnLmFkZChQKX19fWlmKHMpe2NvbnN0e2ZyYWdtZW50TWFwOngsZGlzam9pbnRDb25uZWN0aXZpdHlNYXA6TX09dzAodCxnLHIpO2cuY2xlYXIoKSx4LmZvckVhY2goKHtmb3J3YXJkOkEscmV2ZXJzZTpTfSk9PntBLmZvckVhY2goKHtpbmRleDpffSk9PmcuYWRkKF8pKSxTLmZvckVhY2goKHtpbmRleDpffSk9PmcuYWRkKF8pKX0pLHRoaXMudW5tYXRjaGVkRGlzam9pbnRFZGdlcz14LHRoaXMuZGlzam9pbnRDb25uZWN0aW9ucz1NLG09ZiozLWcuc2l6ZX10aGlzLm1hdGNoZWRFZGdlcz1tLHRoaXMudW5tYXRjaGVkRWRnZXM9Zy5zaXplLHRoaXMuZGF0YT15O2Z1bmN0aW9uIGIoeCl7cmV0dXJuIGhhLmZyb21CdWZmZXJBdHRyaWJ1dGUodSx4KSxBbChoYSl9ZnVuY3Rpb24gdyh4KXtsZXQgTT0iIjtmb3IobGV0IEE9MCxTPWwubGVuZ3RoO0E8UztBKyspe2NvbnN0IF89Y1tsW0FdXTtsZXQgRTtzd2l0Y2goXy5pdGVtU2l6ZSl7Y2FzZSAxOkU9d2UoXy5nZXRYKHgpKTticmVhaztjYXNlIDI6RT1vMChiMC5mcm9tQnVmZmVyQXR0cmlidXRlKF8seCkpO2JyZWFrO2Nhc2UgMzpFPUFsKGhhLmZyb21CdWZmZXJBdHRyaWJ1dGUoXyx4KSk7YnJlYWs7Y2FzZSA0OkU9YTAoTTAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShfLHgpKTticmVha31NIT09IiImJihNKz0ifCIpLE0rPUV9cmV0dXJuIE19fX1jbGFzcyBacyBleHRlbmRzIGJme2NvbnN0cnVjdG9yKC4uLnQpe3N1cGVyKC4uLnQpLHRoaXMuaXNCcnVzaD0hMCx0aGlzLl9wcmV2aW91c01hdHJpeD1uZXcgc3QsdGhpcy5fcHJldmlvdXNNYXRyaXguZWxlbWVudHMuZmlsbCgwKX1tYXJrVXBkYXRlZCgpe3RoaXMuX3ByZXZpb3VzTWF0cml4LmNvcHkodGhpcy5tYXRyaXgpfWlzRGlydHkoKXtjb25zdHttYXRyaXg6dCxfcHJldmlvdXNNYXRyaXg6ZX09dGhpcyxuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzO2ZvcihsZXQgcj0wO3I8MTY7cisrKWlmKG5bcl0hPT1zW3JdKXJldHVybiEwO3JldHVybiExfXByZXBhcmVHZW9tZXRyeSgpe2NvbnN0IHQ9dGhpcy5nZW9tZXRyeSxlPXQuYXR0cmlidXRlcyxuPVNsKCk7aWYobilmb3IoY29uc3QgcyBpbiBlKXtjb25zdCByPWVbc107aWYoci5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlKXRocm93IG5ldyBFcnJvcigiQnJ1c2g6IEludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlcyBhcmUgbm90IHN1cHBvcnRlZC4iKTtyLmFycmF5PWwwKHIuYXJyYXkpfWlmKHQuYm91bmRzVHJlZXx8KHUwKHQse3VzZVNoYXJlZEFycmF5QnVmZmVyOm59KSx0LmJvdW5kc1RyZWU9bmV3IG9hKHQse21heExlYWZUcmlzOjMsaW5kaXJlY3Q6ITAsdXNlU2hhcmVkQXJyYXlCdWZmZXI6bn0pKSx0LmhhbGZFZGdlc3x8KHQuaGFsZkVkZ2VzPW5ldyBBMCh0KSksIXQuZ3JvdXBJbmRpY2VzKXtjb25zdCBzPWFhKHQpLHI9bmV3IFVpbnQxNkFycmF5KHMpLG89dC5ncm91cHM7Zm9yKGxldCBhPTAsYz1vLmxlbmd0aDthPGM7YSsrKXtjb25zdHtzdGFydDpsLGNvdW50Omh9PW9bYV07Zm9yKGxldCB1PWwvMyxmPShsK2gpLzM7dTxmO3UrKylyW3VdPWF9dC5ncm91cEluZGljZXM9cn19ZGlzcG9zZUNhY2hlRGF0YSgpe2NvbnN0e2dlb21ldHJ5OnR9PXRoaXM7dC5oYWxmRWRnZXM9bnVsbCx0LmJvdW5kc1RyZWU9bnVsbCx0Lmdyb3VwSW5kaWNlcz1udWxsfX1jb25zdCBTMD0xZS0xNCxmYT1uZXcgVCxFbD1uZXcgVCxQbD1uZXcgVDtmdW5jdGlvbiBzbihpLHQ9UzApe2ZhLnN1YlZlY3RvcnMoaS5iLGkuYSksRWwuc3ViVmVjdG9ycyhpLmMsaS5hKSxQbC5zdWJWZWN0b3JzKGkuYixpLmMpO2NvbnN0IGU9ZmEuYW5nbGVUbyhFbCksbj1mYS5hbmdsZVRvKFBsKSxzPU1hdGguUEktZS1uO3JldHVybiBNYXRoLmFicyhlKTx0fHxNYXRoLmFicyhuKTx0fHxNYXRoLmFicyhzKTx0fHxpLmEuZGlzdGFuY2VUb1NxdWFyZWQoaS5iKTx0fHxpLmEuZGlzdGFuY2VUb1NxdWFyZWQoaS5jKTx0fHxpLmIuZGlzdGFuY2VUb1NxdWFyZWQoaS5jKTx0fWNvbnN0IGRhPTFlLTEwLERpPTFlLTEwLF8wPTFlLTEwLGtlPW5ldyBRdCxmdD1uZXcgUXQsTmU9bmV3IFQscGE9bmV3IFQsQ2w9bmV3IFQsWHM9bmV3IHpvLHlhPW5ldyBuZTtjbGFzcyB2MHtjb25zdHJ1Y3Rvcigpe3RoaXMuX3Bvb2w9W10sdGhpcy5faW5kZXg9MH1nZXRUcmlhbmdsZSgpe3JldHVybiB0aGlzLl9pbmRleD49dGhpcy5fcG9vbC5sZW5ndGgmJnRoaXMuX3Bvb2wucHVzaChuZXcgZXQpLHRoaXMuX3Bvb2xbdGhpcy5faW5kZXgrK119Y2xlYXIoKXt0aGlzLl9pbmRleD0wfXJlc2V0KCl7dGhpcy5fcG9vbC5sZW5ndGg9MCx0aGlzLl9pbmRleD0wfX1jbGFzcyB6MHtjb25zdHJ1Y3Rvcigpe3RoaXMudHJpYW5nbGVQb29sPW5ldyB2MCx0aGlzLnRyaWFuZ2xlcz1bXSx0aGlzLm5vcm1hbD1uZXcgVCx0aGlzLmNvcGxhbmFyVHJpYW5nbGVVc2VkPSExfWluaXRpYWxpemUodCl7dGhpcy5yZXNldCgpO2NvbnN0e3RyaWFuZ2xlczplLHRyaWFuZ2xlUG9vbDpuLG5vcm1hbDpzfT10aGlzO2lmKEFycmF5LmlzQXJyYXkodCkpZm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXRbcl07aWYocj09PTApYS5nZXROb3JtYWwocyk7ZWxzZSBpZihNYXRoLmFicygxLWEuZ2V0Tm9ybWFsKE5lKS5kb3QocykpPmRhKXRocm93IG5ldyBFcnJvcigiVHJpYW5nbGUgU3BsaXR0ZXI6IENhbm5vdCBpbml0aWFsaXplIHdpdGggdHJpYW5nbGVzIHRoYXQgaGF2ZSBkaWZmZXJlbnQgbm9ybWFscy4iKTtjb25zdCBjPW4uZ2V0VHJpYW5nbGUoKTtjLmNvcHkoYSksZS5wdXNoKGMpfWVsc2V7dC5nZXROb3JtYWwocyk7Y29uc3Qgcj1uLmdldFRyaWFuZ2xlKCk7ci5jb3B5KHQpLGUucHVzaChyKX19c3BsaXRCeVRyaWFuZ2xlKHQpe2NvbnN0e25vcm1hbDplLHRyaWFuZ2xlczpufT10aGlzO2lmKHQuZ2V0Tm9ybWFsKHBhKS5ub3JtYWxpemUoKSxNYXRoLmFicygxLU1hdGguYWJzKHBhLmRvdChlKSkpPF8wKXt0aGlzLmNvcGxhbmFyVHJpYW5nbGVVc2VkPSEwO2ZvcihsZXQgcj0wLG89bi5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1uW3JdO2EuY29wbGFuYXJDb3VudD0wfWNvbnN0IHM9W3QuYSx0LmIsdC5jXTtmb3IobGV0IHI9MDtyPDM7cisrKXtjb25zdCBvPShyKzEpJTMsYT1zW3JdLGM9c1tvXTtOZS5zdWJWZWN0b3JzKGMsYSkubm9ybWFsaXplKCksQ2wuY3Jvc3NWZWN0b3JzKHBhLE5lKSxYcy5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChDbCxhKSx0aGlzLnNwbGl0QnlQbGFuZShYcyx0KX19ZWxzZSB0LmdldFBsYW5lKFhzKSx0aGlzLnNwbGl0QnlQbGFuZShYcyx0KX1zcGxpdEJ5UGxhbmUodCxlKXtjb25zdHt0cmlhbmdsZXM6bix0cmlhbmdsZVBvb2w6c309dGhpczt5YS5jb3B5KGUpLHlhLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgcj0wLG89bi5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1uW3JdO2lmKCF5YS5pbnRlcnNlY3RzVHJpYW5nbGUoYSxrZSwhMCkpY29udGludWU7Y29uc3R7YTpjLGI6bCxjOmh9PWE7bGV0IHU9MCxmPS0xLGQ9ITEscD1bXSx5PVtdO2NvbnN0IG09W2MsbCxoXTtmb3IobGV0IGc9MDtnPDM7ZysrKXtjb25zdCBiPShnKzEpJTM7a2Uuc3RhcnQuY29weShtW2ddKSxrZS5lbmQuY29weShtW2JdKTtjb25zdCB3PXQuZGlzdGFuY2VUb1BvaW50KGtlLnN0YXJ0KSx4PXQuZGlzdGFuY2VUb1BvaW50KGtlLmVuZCk7aWYoTWF0aC5hYnModyk8RGkmJk1hdGguYWJzKHgpPERpKXtkPSEwO2JyZWFrfWlmKHc+MD9wLnB1c2goZyk6eS5wdXNoKGcpLE1hdGguYWJzKHcpPERpKWNvbnRpbnVlO2xldCBNPSEhdC5pbnRlcnNlY3RMaW5lKGtlLE5lKTshTSYmTWF0aC5hYnMoeCk8RGkmJihOZS5jb3B5KGtlLmVuZCksTT0hMCksTSYmIShOZS5kaXN0YW5jZVRvKGtlLnN0YXJ0KTxkYSkmJihOZS5kaXN0YW5jZVRvKGtlLmVuZCk8ZGEmJihmPWcpLHU9PT0wP2Z0LnN0YXJ0LmNvcHkoTmUpOmZ0LmVuZC5jb3B5KE5lKSx1KyspfWlmKCFkJiZ1PT09MiYmZnQuZGlzdGFuY2UoKT5EaSlpZihmIT09LTEpe2Y9KGYrMSklMztsZXQgZz0wO2c9PT1mJiYoZz0oZysxKSUzKTtsZXQgYj1nKzE7Yj09PWYmJihiPShiKzEpJTMpO2NvbnN0IHc9cy5nZXRUcmlhbmdsZSgpO3cuYS5jb3B5KG1bYl0pLHcuYi5jb3B5KGZ0LmVuZCksdy5jLmNvcHkoZnQuc3RhcnQpLHNuKHcpfHxuLnB1c2godyksYS5hLmNvcHkobVtnXSksYS5iLmNvcHkoZnQuc3RhcnQpLGEuYy5jb3B5KGZ0LmVuZCksc24oYSkmJihuLnNwbGljZShyLDEpLHItLSxvLS0pfWVsc2V7Y29uc3QgZz1wLmxlbmd0aD49Mj95WzBdOnBbMF07aWYoZz09PTApe2xldCBBPWZ0LnN0YXJ0O2Z0LnN0YXJ0PWZ0LmVuZCxmdC5lbmQ9QX1jb25zdCBiPShnKzEpJTMsdz0oZysyKSUzLHg9cy5nZXRUcmlhbmdsZSgpLE09cy5nZXRUcmlhbmdsZSgpO21bYl0uZGlzdGFuY2VUb1NxdWFyZWQoZnQuc3RhcnQpPG1bd10uZGlzdGFuY2VUb1NxdWFyZWQoZnQuZW5kKT8oeC5hLmNvcHkobVtiXSkseC5iLmNvcHkoZnQuc3RhcnQpLHguYy5jb3B5KGZ0LmVuZCksTS5hLmNvcHkobVtiXSksTS5iLmNvcHkobVt3XSksTS5jLmNvcHkoZnQuc3RhcnQpKTooeC5hLmNvcHkobVt3XSkseC5iLmNvcHkoZnQuc3RhcnQpLHguYy5jb3B5KGZ0LmVuZCksTS5hLmNvcHkobVtiXSksTS5iLmNvcHkobVt3XSksTS5jLmNvcHkoZnQuZW5kKSksYS5hLmNvcHkobVtnXSksYS5iLmNvcHkoZnQuZW5kKSxhLmMuY29weShmdC5zdGFydCksc24oeCl8fG4ucHVzaCh4KSxzbihNKXx8bi5wdXNoKE0pLHNuKGEpJiYobi5zcGxpY2UociwxKSxyLS0sby0tKX1lbHNlIHU9PT0zJiZjb25zb2xlLndhcm4oIlRyaWFuZ2xlQ2xpcHBlcjogQ29wbGFuYXIgY2xpcCBub3QgaGFuZGxlZCIpfX1yZXNldCgpe3RoaXMudHJpYW5nbGVzLmxlbmd0aD0wLHRoaXMudHJpYW5nbGVQb29sLmNsZWFyKCksdGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMX19ZnVuY3Rpb24gVDAoaSl7cmV0dXJuIGk9fn5pLGkrNC1pJTR9Y2xhc3MgQmx7Y29uc3RydWN0b3IodCxlPTUwMCl7dGhpcy5leHBhbnNpb25GYWN0b3I9MS41LHRoaXMudHlwZT10LHRoaXMubGVuZ3RoPTAsdGhpcy5hcnJheT1udWxsLHRoaXMuc2V0U2l6ZShlKX1zZXRUeXBlKHQpe2lmKHRoaXMubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoIlR5cGVCYWNrZWRBcnJheTogQ2Fubm90IGNoYW5nZSB0aGUgdHlwZSB3aGlsZSB0aGVyZSBpcyB1c2VkIGRhdGEgaW4gdGhlIGJ1ZmZlci4iKTtjb25zdCBlPXRoaXMuYXJyYXkuYnVmZmVyO3RoaXMuYXJyYXk9bmV3IHQoZSksdGhpcy50eXBlPXR9c2V0U2l6ZSh0KXtpZih0aGlzLmFycmF5JiZ0PT09dGhpcy5hcnJheS5sZW5ndGgpcmV0dXJuO2NvbnN0IGU9dGhpcy50eXBlLG49U2woKT9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPW5ldyBlKG5ldyBuKFQwKHQqZS5CWVRFU19QRVJfRUxFTUVOVCkpKTt0aGlzLmFycmF5JiZzLnNldCh0aGlzLmFycmF5LDApLHRoaXMuYXJyYXk9c31leHBhbmQoKXtjb25zdHthcnJheTp0LGV4cGFuc2lvbkZhY3RvcjplfT10aGlzO3RoaXMuc2V0U2l6ZSh0Lmxlbmd0aCplKX1wdXNoKC4uLnQpe2xldHthcnJheTplLGxlbmd0aDpufT10aGlzO24rdC5sZW5ndGg+ZS5sZW5ndGgmJih0aGlzLmV4cGFuZCgpLGU9dGhpcy5hcnJheSk7Zm9yKGxldCBzPTAscj10Lmxlbmd0aDtzPHI7cysrKWVbbitzXT10W3NdO3RoaXMubGVuZ3RoKz10Lmxlbmd0aH1jbGVhcigpe3RoaXMubGVuZ3RoPTB9fWNsYXNzIEUwe2NvbnN0cnVjdG9yKCl7dGhpcy5ncm91cEF0dHJpYnV0ZXM9W3t9XSx0aGlzLmdyb3VwQ291bnQ9MH1nZXRUeXBlKHQpe3JldHVybiB0aGlzLmdyb3VwQXR0cmlidXRlc1swXVt0XS50eXBlfWdldEl0ZW1TaXplKHQpe3JldHVybiB0aGlzLmdyb3VwQXR0cmlidXRlc1swXVt0XS5pdGVtU2l6ZX1nZXROb3JtYWxpemVkKHQpe3JldHVybiB0aGlzLmdyb3VwQXR0cmlidXRlc1swXVt0XS5ub3JtYWxpemVkfWdldENvdW50KHQpe2lmKHRoaXMuZ3JvdXBDb3VudDw9dClyZXR1cm4gMDtjb25zdCBlPXRoaXMuZ2V0R3JvdXBBdHRyQXJyYXkoInBvc2l0aW9uIix0KTtyZXR1cm4gZS5sZW5ndGgvZS5pdGVtU2l6ZX1nZXRUb3RhbExlbmd0aCh0KXtjb25zdHtncm91cENvdW50OmUsZ3JvdXBBdHRyaWJ1dGVzOm59PXRoaXM7bGV0IHM9MDtmb3IobGV0IHI9MDtyPGU7cisrKXtjb25zdCBvPW5bcl07cys9b1t0XS5sZW5ndGh9cmV0dXJuIHN9Z2V0R3JvdXBBdHRyU2V0KHQ9MCl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOmV9PXRoaXM7aWYoZVt0XSlyZXR1cm4gdGhpcy5ncm91cENvdW50PU1hdGgubWF4KHRoaXMuZ3JvdXBDb3VudCx0KzEpLGVbdF07Y29uc3Qgbj1lWzBdO2Zvcih0aGlzLmdyb3VwQ291bnQ9TWF0aC5tYXgodGhpcy5ncm91cENvdW50LHQrMSk7dD49ZS5sZW5ndGg7KXtjb25zdCBzPXt9O2UucHVzaChzKTtmb3IoY29uc3QgciBpbiBuKXtjb25zdCBvPW5bcl0sYT1uZXcgQmwoby50eXBlKTthLml0ZW1TaXplPW8uaXRlbVNpemUsYS5ub3JtYWxpemVkPW8ubm9ybWFsaXplZCxzW3JdPWF9fXJldHVybiBlW3RdfWdldEdyb3VwQXR0ckFycmF5KHQsZT0wKXtjb25zdHtncm91cEF0dHJpYnV0ZXM6bn09dGhpcztpZighblswXVt0XSl0aHJvdyBuZXcgRXJyb3IoYFR5cGVkQXR0cmlidXRlRGF0YTogQXR0cmlidXRlIHdpdGggIiR7dH0iIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZGApO3JldHVybiB0aGlzLmdldEdyb3VwQXR0clNldChlKVt0XX1pbml0aWFsaXplQXJyYXkodCxlLG4scyl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOnJ9PXRoaXMsYT1yWzBdW3RdO2lmKGEpe2lmKGEudHlwZSE9PWUpZm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPXJbY11bdF07aC5zZXRUeXBlKGUpLGguaXRlbVNpemU9bixoLm5vcm1hbGl6ZWQ9c319ZWxzZSBmb3IobGV0IGM9MCxsPXIubGVuZ3RoO2M8bDtjKyspe2NvbnN0IGg9bmV3IEJsKGUpO2guaXRlbVNpemU9bixoLm5vcm1hbGl6ZWQ9cyxyW2NdW3RdPWh9fWNsZWFyKCl7dGhpcy5ncm91cENvdW50PTA7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOnR9PXRoaXM7dC5mb3JFYWNoKGU9Pntmb3IoY29uc3QgbiBpbiBlKWVbbl0uY2xlYXIoKX0pfWRlbGV0ZSh0KXt0aGlzLmdyb3VwQXR0cmlidXRlcy5mb3JFYWNoKGU9PntkZWxldGUgZVt0XX0pfXJlc2V0KCl7dGhpcy5ncm91cEF0dHJpYnV0ZXM9W10sdGhpcy5ncm91cENvdW50PTB9fWNsYXNzIEZse2NvbnN0cnVjdG9yKCl7dGhpcy5pbnRlcnNlY3Rpb25TZXQ9e30sdGhpcy5pZHM9W119YWRkKHQsZSl7Y29uc3R7aW50ZXJzZWN0aW9uU2V0Om4saWRzOnN9PXRoaXM7blt0XXx8KG5bdF09W10scy5wdXNoKHQpKSxuW3RdLnB1c2goZSl9fWNvbnN0IFAwPTAsQzA9MSxCMD0yLElsPTMsRjA9NCxrbD01LE5sPTYsc2U9bmV3IGZvLFJsPW5ldyBzdCxUdD1uZXcgZXQsUmU9bmV3IFQsTGw9bmV3IFl0LE9sPW5ldyBZdCxEbD1uZXcgWXQsbWE9bmV3IFl0LEpzPW5ldyBZdCxZcz1uZXcgWXQsJGw9bmV3IFF0LGdhPW5ldyBULHhhPTFlLTgsSTA9MWUtMTUseG49LTEsd249MSxqcz0tMixRcz0yLCRpPTAsYm49MSx3YT0yLGswPTFlLTE0O2xldCBLcz1udWxsO2Z1bmN0aW9uIFZsKGkpe0tzPWl9ZnVuY3Rpb24gVWwoaSx0KXtpLmdldE1pZHBvaW50KHNlLm9yaWdpbiksaS5nZXROb3JtYWwoc2UuZGlyZWN0aW9uKTtjb25zdCBlPXQucmF5Y2FzdEZpcnN0KHNlLDIpO3JldHVybiEhKGUmJnNlLmRpcmVjdGlvbi5kb3QoZS5mYWNlLm5vcm1hbCk+MCk/eG46d259ZnVuY3Rpb24gTjAoaSx0KXtmdW5jdGlvbiBlKCl7cmV0dXJuIE1hdGgucmFuZG9tKCktLjV9aS5nZXROb3JtYWwoZ2EpLHNlLmRpcmVjdGlvbi5jb3B5KGdhKSxpLmdldE1pZHBvaW50KHNlLm9yaWdpbik7Y29uc3Qgbj0zO2xldCBzPTAscj0xLzA7Zm9yKGxldCBvPTA7bzxuO28rKyl7c2UuZGlyZWN0aW9uLngrPWUoKSp4YSxzZS5kaXJlY3Rpb24ueSs9ZSgpKnhhLHNlLmRpcmVjdGlvbi56Kz1lKCkqeGEsc2UuZGlyZWN0aW9uLm11bHRpcGx5U2NhbGFyKC0xKTtjb25zdCBhPXQucmF5Y2FzdEZpcnN0KHNlLDIpO2lmKCEhKGEmJnNlLmRpcmVjdGlvbi5kb3QoYS5mYWNlLm5vcm1hbCk+MCkmJnMrKyxhIT09bnVsbCYmKHI9TWF0aC5taW4ocixhLmRpc3RhbmNlKSkscjw9STApcmV0dXJuIGEuZmFjZS5ub3JtYWwuZG90KGdhKT4wP1FzOmpzO2lmKHMvbj4uNXx8KG8tcysxKS9uPi41KWJyZWFrfXJldHVybiBzL24+LjU/eG46d259ZnVuY3Rpb24gUjAoaSx0KXtjb25zdCBlPW5ldyBGbCxuPW5ldyBGbDtyZXR1cm4gUmwuY29weShpLm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseSh0Lm1hdHJpeFdvcmxkKSxpLmdlb21ldHJ5LmJvdW5kc1RyZWUuYnZoY2FzdCh0Lmdlb21ldHJ5LmJvdW5kc1RyZWUsUmwse2ludGVyc2VjdHNUcmlhbmdsZXMocyxyLG8sYSl7aWYoIXNuKHMpJiYhc24ocikpe2xldCBjPXMuaW50ZXJzZWN0c1RyaWFuZ2xlKHIsJGwsITApO2lmKCFjKXtjb25zdCBsPXMucGxhbmUsaD1yLnBsYW5lLHU9bC5ub3JtYWwsZj1oLm5vcm1hbDt1LmRvdChmKT09PTEmJk1hdGguYWJzKGwuY29uc3RhbnQtaC5jb25zdGFudCk8azAmJihjPSEwKX1pZihjKXtsZXQgbD1pLmdlb21ldHJ5LmJvdW5kc1RyZWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgobyksaD10Lmdlb21ldHJ5LmJvdW5kc1RyZWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoYSk7ZS5hZGQobCxoKSxuLmFkZChoLGwpLEtzJiYoS3MuYWRkRWRnZSgkbCksS3MuYWRkSW50ZXJzZWN0aW5nVHJpYW5nbGVzKG8scyxhLHIpKX19cmV0dXJuITF9fSkse2FJbnRlcnNlY3Rpb25zOmUsYkludGVyc2VjdGlvbnM6bn19ZnVuY3Rpb24gTDAoaSx0LGUsbixzLHIsbz0hMSl7Y29uc3QgYT1lLmF0dHJpYnV0ZXMsYz1lLmluZGV4LGw9aSozLGg9Yy5nZXRYKGwrMCksdT1jLmdldFgobCsxKSxmPWMuZ2V0WChsKzIpO2Zvcihjb25zdCBkIGluIHIpe2NvbnN0IHA9YVtkXSx5PXJbZF07aWYoIShkIGluIGEpKXRocm93IG5ldyBFcnJvcihgQ1NHIE9wZXJhdGlvbnM6IEF0dHJpYnV0ZSAke2R9IG5vdCBhdmFpbGFibGUgb24gZ2VvbWV0cnkuYCk7Y29uc3QgbT1wLml0ZW1TaXplO2Q9PT0icG9zaXRpb24iPyhUdC5hLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKS5hcHBseU1hdHJpeDQobiksVHQuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSkuYXBwbHlNYXRyaXg0KG4pLFR0LmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGYpLmFwcGx5TWF0cml4NChuKSxiYShUdC5hLFR0LmIsVHQuYyx0LDMseSxvKSk6ZD09PSJub3JtYWwiPyhUdC5hLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKS5hcHBseU5vcm1hbE1hdHJpeChzKSxUdC5iLmZyb21CdWZmZXJBdHRyaWJ1dGUocCx1KS5hcHBseU5vcm1hbE1hdHJpeChzKSxUdC5jLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxmKS5hcHBseU5vcm1hbE1hdHJpeChzKSxvJiYoVHQuYS5tdWx0aXBseVNjYWxhcigtMSksVHQuYi5tdWx0aXBseVNjYWxhcigtMSksVHQuYy5tdWx0aXBseVNjYWxhcigtMSkpLGJhKFR0LmEsVHQuYixUdC5jLHQsMyx5LG8sITApKTooTGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGgpLE9sLmZyb21CdWZmZXJBdHRyaWJ1dGUocCx1KSxEbC5mcm9tQnVmZmVyQXR0cmlidXRlKHAsZiksYmEoTGwsT2wsRGwsdCxtLHksbykpfX1mdW5jdGlvbiBPMChpLHQsZSxuLHMscixvLGE9ITEpe01hKGksbixzLHIsbyxhKSxNYShhP2U6dCxuLHMscixvLGEpLE1hKGE/dDplLG4scyxyLG8sYSl9ZnVuY3Rpb24gcWwoaSx0LGU9ITEpe3N3aXRjaChpKXtjYXNlIFAwOmlmKHQ9PT13bnx8dD09PVFzJiYhZSlyZXR1cm4gYm47YnJlYWs7Y2FzZSBDMDppZihlKXtpZih0PT09eG4pcmV0dXJuICRpfWVsc2UgaWYodD09PXdufHx0PT09anMpcmV0dXJuIGJuO2JyZWFrO2Nhc2UgQjA6aWYoZSl7aWYodD09PXdufHx0PT09anMpcmV0dXJuIGJufWVsc2UgaWYodD09PXhuKXJldHVybiAkaTticmVhaztjYXNlIEYwOmlmKHQ9PT14bilyZXR1cm4gJGk7aWYodD09PXduKXJldHVybiBibjticmVhaztjYXNlIElsOmlmKHQ9PT14bnx8dD09PVFzJiYhZSlyZXR1cm4gYm47YnJlYWs7Y2FzZSBrbDppZighZSYmKHQ9PT13bnx8dD09PWpzKSlyZXR1cm4gYm47YnJlYWs7Y2FzZSBObDppZighZSYmKHQ9PT14bnx8dD09PVFzKSlyZXR1cm4gYm47YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBDU0cgb3BlcmF0aW9uIGVudW0gIiR7aX0iLmApfXJldHVybiB3YX1mdW5jdGlvbiBiYShpLHQsZSxuLHMscixvPSExLGE9ITEpe2NvbnN0IGM9bD0+e3IucHVzaChsLngpLHM+MSYmci5wdXNoKGwueSkscz4yJiZyLnB1c2gobC56KSxzPjMmJnIucHVzaChsLncpfTttYS5zZXQoMCwwLDAsMCkuYWRkU2NhbGVkVmVjdG9yKGksbi5hLngpLmFkZFNjYWxlZFZlY3Rvcih0LG4uYS55KS5hZGRTY2FsZWRWZWN0b3IoZSxuLmEueiksSnMuc2V0KDAsMCwwLDApLmFkZFNjYWxlZFZlY3RvcihpLG4uYi54KS5hZGRTY2FsZWRWZWN0b3IodCxuLmIueSkuYWRkU2NhbGVkVmVjdG9yKGUsbi5iLnopLFlzLnNldCgwLDAsMCwwKS5hZGRTY2FsZWRWZWN0b3IoaSxuLmMueCkuYWRkU2NhbGVkVmVjdG9yKHQsbi5jLnkpLmFkZFNjYWxlZFZlY3RvcihlLG4uYy56KSxhJiYobWEubm9ybWFsaXplKCksSnMubm9ybWFsaXplKCksWXMubm9ybWFsaXplKCkpLGMobWEpLG8/KGMoWXMpLGMoSnMpKTooYyhKcyksYyhZcykpfWZ1bmN0aW9uIE1hKGksdCxlLG4scyxyPSExKXtmb3IoY29uc3QgbyBpbiBzKXtjb25zdCBhPXRbb10sYz1zW29dO2lmKCEobyBpbiB0KSl0aHJvdyBuZXcgRXJyb3IoYENTRyBPcGVyYXRpb25zOiBBdHRyaWJ1dGUgJHtvfSBubyBhdmFpbGFibGUgb24gZ2VvbWV0cnkuYCk7Y29uc3QgbD1hLml0ZW1TaXplO289PT0icG9zaXRpb24iPyhSZS5mcm9tQnVmZmVyQXR0cmlidXRlKGEsaSkuYXBwbHlNYXRyaXg0KGUpLGMucHVzaChSZS54LFJlLnksUmUueikpOm89PT0ibm9ybWFsIj8oUmUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGkpLmFwcGx5Tm9ybWFsTWF0cml4KG4pLHImJlJlLm11bHRpcGx5U2NhbGFyKC0xKSxjLnB1c2goUmUueCxSZS55LFJlLnopKTooYy5wdXNoKGEuZ2V0WChpKSksbD4xJiZjLnB1c2goYS5nZXRZKGkpKSxsPjImJmMucHVzaChhLmdldFooaSkpLGw+MyYmYy5wdXNoKGEuZ2V0VyhpKSkpfX1jbGFzcyBEMHtjb25zdHJ1Y3Rvcih0KXt0aGlzLnRyaWFuZ2xlPW5ldyBldCgpLmNvcHkodCksdGhpcy5pbnRlcnNlY3RzPXt9fWFkZFRyaWFuZ2xlKHQsZSl7dGhpcy5pbnRlcnNlY3RzW3RdPW5ldyBldCgpLmNvcHkoZSl9Z2V0SW50ZXJzZWN0QXJyYXkoKXtjb25zdCB0PVtdLHtpbnRlcnNlY3RzOmV9PXRoaXM7Zm9yKGNvbnN0IG4gaW4gZSl0LnB1c2goZVtuXSk7cmV0dXJuIHR9fWNsYXNzIEhse2NvbnN0cnVjdG9yKCl7dGhpcy5kYXRhPXt9fWFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKHQsZSxuLHMpe2NvbnN0e2RhdGE6cn09dGhpcztyW3RdfHwoclt0XT1uZXcgRDAoZSkpLHJbdF0uYWRkVHJpYW5nbGUobixzKX1nZXRUcmlhbmdsZXNBc0FycmF5KHQ9bnVsbCl7Y29uc3R7ZGF0YTplfT10aGlzLG49W107aWYodCE9PW51bGwpdCBpbiBlJiZuLnB1c2goZVt0XS50cmlhbmdsZSk7ZWxzZSBmb3IoY29uc3QgcyBpbiBlKW4ucHVzaChlW3NdLnRyaWFuZ2xlKTtyZXR1cm4gbn1nZXRUcmlhbmdsZUluZGljZXMoKXtyZXR1cm4gT2JqZWN0LmtleXModGhpcy5kYXRhKS5tYXAodD0+cGFyc2VJbnQodCkpfWdldEludGVyc2VjdGlvbkluZGljZXModCl7Y29uc3R7ZGF0YTplfT10aGlzO3JldHVybiBlW3RdP09iamVjdC5rZXlzKGVbdF0uaW50ZXJzZWN0cykubWFwKG49PnBhcnNlSW50KG4pKTpbXX1nZXRJbnRlcnNlY3Rpb25zQXNBcnJheSh0PW51bGwsZT1udWxsKXtjb25zdHtkYXRhOm59PXRoaXMscz1uZXcgU2V0LHI9W10sbz1hPT57aWYoblthXSlpZihlIT09bnVsbCluW2FdLmludGVyc2VjdHNbZV0mJnIucHVzaChuW2FdLmludGVyc2VjdHNbZV0pO2Vsc2V7Y29uc3QgYz1uW2FdLmludGVyc2VjdHM7Zm9yKGNvbnN0IGwgaW4gYylzLmhhcyhsKXx8KHMuYWRkKGwpLHIucHVzaChjW2xdKSl9fTtpZih0IT09bnVsbClvKHQpO2Vsc2UgZm9yKGNvbnN0IGEgaW4gbilvKGEpO3JldHVybiByfXJlc2V0KCl7dGhpcy5kYXRhPXt9fX1jbGFzcyAkMHtjb25zdHJ1Y3Rvcigpe3RoaXMuZW5hYmxlZD0hMSx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0E9bmV3IEhsLHRoaXMudHJpYW5nbGVJbnRlcnNlY3RzQj1uZXcgSGwsdGhpcy5pbnRlcnNlY3Rpb25FZGdlcz1bXX1hZGRJbnRlcnNlY3RpbmdUcmlhbmdsZXModCxlLG4scyl7Y29uc3R7dHJpYW5nbGVJbnRlcnNlY3RzQTpyLHRyaWFuZ2xlSW50ZXJzZWN0c0I6b309dGhpcztyLmFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKHQsZSxuLHMpLG8uYWRkVHJpYW5nbGVJbnRlcnNlY3Rpb24obixzLHQsZSl9YWRkRWRnZSh0KXt0aGlzLmludGVyc2VjdGlvbkVkZ2VzLnB1c2godC5jbG9uZSgpKX1yZXNldCgpe3RoaXMudHJpYW5nbGVJbnRlcnNlY3RzQS5yZXNldCgpLHRoaXMudHJpYW5nbGVJbnRlcnNlY3RzQi5yZXNldCgpLHRoaXMuaW50ZXJzZWN0aW9uRWRnZXM9W119aW5pdCgpe3RoaXMuZW5hYmxlZCYmKHRoaXMucmVzZXQoKSxWbCh0aGlzKSl9Y29tcGxldGUoKXt0aGlzLmVuYWJsZWQmJlZsKG51bGwpfX1jb25zdCBybj1uZXcgc3QsdHI9bmV3IGdlLE1uPW5ldyBldCxlcj1uZXcgZXQsb249bmV3IGV0LG5yPW5ldyBldCxkZT1bXSxBbj1bXTtmdW5jdGlvbiBWMChpKXtmb3IoY29uc3QgdCBvZiBpKXJldHVybiB0fWZ1bmN0aW9uIFUwKGksdCxlLG4scyxyPXt9KXtjb25zdHt1c2VHcm91cHM6bz0hMH09cix7YUludGVyc2VjdGlvbnM6YSxiSW50ZXJzZWN0aW9uczpjfT1SMChpLHQpLGw9W107bGV0IGg9bnVsbCx1O3JldHVybiB1PW8/MDotMSxXbChpLHQsYSxlLCExLG4scyx1KSxHbChpLHQsYSxlLCExLHMsdSksZS5maW5kSW5kZXgoZD0+ZCE9PU5sJiZkIT09a2wpIT09LTEmJih1PW8/aS5nZW9tZXRyeS5ncm91cHMubGVuZ3RofHwxOi0xLFdsKHQsaSxjLGUsITAsbixzLHUpLEdsKHQsaSxjLGUsITAscyx1KSksZGUubGVuZ3RoPTAsQW4ubGVuZ3RoPTAse2dyb3VwczpsLG1hdGVyaWFsczpofX1mdW5jdGlvbiBXbChpLHQsZSxuLHMscixvLGE9MCl7Y29uc3QgYz1pLm1hdHJpeFdvcmxkLmRldGVybWluYW50KCk8MDtybi5jb3B5KHQubWF0cml4V29ybGQpLmludmVydCgpLm11bHRpcGx5KGkubWF0cml4V29ybGQpLHRyLmdldE5vcm1hbE1hdHJpeChpLm1hdHJpeFdvcmxkKS5tdWx0aXBseVNjYWxhcihjPy0xOjEpO2NvbnN0IGw9aS5nZW9tZXRyeS5ncm91cEluZGljZXMsaD1pLmdlb21ldHJ5LmluZGV4LHU9aS5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGY9dC5nZW9tZXRyeS5ib3VuZHNUcmVlLGQ9dC5nZW9tZXRyeS5pbmRleCxwPXQuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbix5PWUuaWRzLG09ZS5pbnRlcnNlY3Rpb25TZXQ7Zm9yKGxldCBnPTAsYj15Lmxlbmd0aDtnPGI7ZysrKXtjb25zdCB3PXlbZ10seD1hPT09LTE/MDpsW3ddK2EsTT0zKncsQT1oLmdldFgoTSswKSxTPWguZ2V0WChNKzEpLF89aC5nZXRYKE0rMik7TW4uYS5mcm9tQnVmZmVyQXR0cmlidXRlKHUsQSkuYXBwbHlNYXRyaXg0KHJuKSxNbi5iLmZyb21CdWZmZXJBdHRyaWJ1dGUodSxTKS5hcHBseU1hdHJpeDQocm4pLE1uLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LF8pLmFwcGx5TWF0cml4NChybiksci5yZXNldCgpLHIuaW5pdGlhbGl6ZShNbik7Y29uc3QgRT1tW3ddO2ZvcihsZXQgdj0wLEM9RS5sZW5ndGg7djxDO3YrKyl7Y29uc3QgUD0zKkVbdl0sRj1kLmdldFgoUCswKSxCPWQuZ2V0WChQKzEpLEk9ZC5nZXRYKFArMik7ZXIuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsRiksZXIuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsQiksZXIuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHAsSSksci5zcGxpdEJ5VHJpYW5nbGUoZXIpfWNvbnN0IHo9ci50cmlhbmdsZXM7Zm9yKGxldCB2PTAsQz16Lmxlbmd0aDt2PEM7disrKXtjb25zdCBQPXpbdl0sRj1yLmNvcGxhbmFyVHJpYW5nbGVVc2VkP04wKFAsZik6VWwoUCxmKTtkZS5sZW5ndGg9MCxBbi5sZW5ndGg9MDtmb3IobGV0IEI9MCxJPW4ubGVuZ3RoO0I8STtCKyspe2NvbnN0IGs9cWwobltCXSxGLHMpO2shPT13YSYmKEFuLnB1c2goayksZGUucHVzaChvW0JdLmdldEdyb3VwQXR0clNldCh4KSkpfWlmKGRlLmxlbmd0aCE9PTApe01uLmdldEJhcnljb29yZChQLmEsbnIuYSksTW4uZ2V0QmFyeWNvb3JkKFAuYixuci5iKSxNbi5nZXRCYXJ5Y29vcmQoUC5jLG5yLmMpO2ZvcihsZXQgQj0wLEk9ZGUubGVuZ3RoO0I8STtCKyspe2NvbnN0IGs9ZGVbQl0sVT1BbltCXT09PSRpO0wwKHcsbnIsaS5nZW9tZXRyeSxpLm1hdHJpeFdvcmxkLHRyLGssYyE9PVUpfX19fXJldHVybiB5Lmxlbmd0aH1mdW5jdGlvbiBHbChpLHQsZSxuLHMscixvPTApe2NvbnN0IGE9aS5tYXRyaXhXb3JsZC5kZXRlcm1pbmFudCgpPDA7cm4uY29weSh0Lm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseShpLm1hdHJpeFdvcmxkKSx0ci5nZXROb3JtYWxNYXRyaXgoaS5tYXRyaXhXb3JsZCkubXVsdGlwbHlTY2FsYXIoYT8tMToxKTtjb25zdCBjPXQuZ2VvbWV0cnkuYm91bmRzVHJlZSxsPWkuZ2VvbWV0cnkuZ3JvdXBJbmRpY2VzLGg9aS5nZW9tZXRyeS5pbmRleCx1PWkuZ2VvbWV0cnkuYXR0cmlidXRlcyxmPXUucG9zaXRpb24sZD1bXSxwPWkuZ2VvbWV0cnkuaGFsZkVkZ2VzLHk9bmV3IFNldCxtPWFhKGkuZ2VvbWV0cnkpO2ZvcihsZXQgZz0wLGI9bTtnPGI7ZysrKWcgaW4gZS5pbnRlcnNlY3Rpb25TZXR8fHkuYWRkKGcpO2Zvcig7eS5zaXplPjA7KXtjb25zdCBnPVYwKHkpO3kuZGVsZXRlKGcpLGQucHVzaChnKTtjb25zdCBiPTMqZyx3PWguZ2V0WChiKzApLHg9aC5nZXRYKGIrMSksTT1oLmdldFgoYisyKTtvbi5hLmZyb21CdWZmZXJBdHRyaWJ1dGUoZix3KS5hcHBseU1hdHJpeDQocm4pLG9uLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHgpLmFwcGx5TWF0cml4NChybiksb24uYy5mcm9tQnVmZmVyQXR0cmlidXRlKGYsTSkuYXBwbHlNYXRyaXg0KHJuKTtjb25zdCBBPVVsKG9uLGMpO0FuLmxlbmd0aD0wLGRlLmxlbmd0aD0wO2ZvcihsZXQgUz0wLF89bi5sZW5ndGg7UzxfO1MrKyl7Y29uc3QgRT1xbChuW1NdLEEscyk7RSE9PXdhJiYoQW4ucHVzaChFKSxkZS5wdXNoKHJbU10pKX1mb3IoO2QubGVuZ3RoPjA7KXtjb25zdCBTPWQucG9wKCk7Zm9yKGxldCBfPTA7XzwzO18rKyl7Y29uc3QgRT1wLmdldFNpYmxpbmdUcmlhbmdsZUluZGV4KFMsXyk7RSE9PS0xJiZ5LmhhcyhFKSYmKGQucHVzaChFKSx5LmRlbGV0ZShFKSl9aWYoZGUubGVuZ3RoIT09MCl7Y29uc3QgXz0zKlMsRT1oLmdldFgoXyswKSx6PWguZ2V0WChfKzEpLHY9aC5nZXRYKF8rMiksQz1vPT09LTE/MDpsW1NdK287aWYob24uYS5mcm9tQnVmZmVyQXR0cmlidXRlKGYsRSksb24uYi5mcm9tQnVmZmVyQXR0cmlidXRlKGYseiksb24uYy5mcm9tQnVmZmVyQXR0cmlidXRlKGYsdiksIXNuKG9uKSlmb3IobGV0IFA9MCxGPWRlLmxlbmd0aDtQPEY7UCsrKXtjb25zdCBCPUFuW1BdLEk9ZGVbUF0uZ2V0R3JvdXBBdHRyU2V0KEMpLGs9Qj09PSRpO08wKEUseix2LHUsaS5tYXRyaXhXb3JsZCx0cixJLGshPT1hKX19fX19ZnVuY3Rpb24gcTAoaSl7Zm9yKGxldCB0PTA7dDxpLmxlbmd0aC0xO3QrKyl7Y29uc3QgZT1pW3RdLG49aVt0KzFdO2lmKGUubWF0ZXJpYWxJbmRleD09PW4ubWF0ZXJpYWxJbmRleCl7Y29uc3Qgcz1lLnN0YXJ0LHI9bi5zdGFydCtuLmNvdW50O24uc3RhcnQ9cyxuLmNvdW50PXItcyxpLnNwbGljZSh0LDEpLHQtLX19fWZ1bmN0aW9uIEgwKGksdCxlLG4pe2UuY2xlYXIoKTtjb25zdCBzPWkuYXR0cmlidXRlcztmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXSxjPXNbYV07ZS5pbml0aWFsaXplQXJyYXkoYSxjLmFycmF5LmNvbnN0cnVjdG9yLGMuaXRlbVNpemUsYy5ub3JtYWxpemVkKX1mb3IoY29uc3QgciBpbiBlLmF0dHJpYnV0ZXMpbi5pbmNsdWRlcyhyKXx8ZS5kZWxldGUocik7Zm9yKGNvbnN0IHIgaW4gdC5hdHRyaWJ1dGVzKW4uaW5jbHVkZXMocil8fCh0LmRlbGV0ZUF0dHJpYnV0ZShyKSx0LmRpc3Bvc2UoKSl9ZnVuY3Rpb24gVzAoaSx0LGUpe2xldCBuPSExLHM9LTE7Y29uc3Qgcj1pLmF0dHJpYnV0ZXMsbz10Lmdyb3VwQXR0cmlidXRlc1swXTtmb3IoY29uc3QgYyBpbiBvKXtjb25zdCBsPXQuZ2V0VG90YWxMZW5ndGgoYyksaD10LmdldFR5cGUoYyksdT10LmdldEl0ZW1TaXplKGMpLGY9dC5nZXROb3JtYWxpemVkKGMpO2xldCBkPXJbY107KCFkfHxkLmFycmF5Lmxlbmd0aDxsKSYmKGQ9bmV3IHh0KG5ldyBoKGwpLHUsZiksaS5zZXRBdHRyaWJ1dGUoYyxkKSxuPSEwKTtsZXQgcD0wO2ZvcihsZXQgeT0wLG09TWF0aC5taW4oZS5sZW5ndGgsdC5ncm91cENvdW50KTt5PG07eSsrKXtjb25zdCBnPWVbeV0uaW5kZXgse2FycmF5OmIsdHlwZTp3LGxlbmd0aDp4fT10Lmdyb3VwQXR0cmlidXRlc1tnXVtjXSxNPW5ldyB3KGIuYnVmZmVyLDAseCk7ZC5hcnJheS5zZXQoTSxwKSxwKz1NLmxlbmd0aH1kLm5lZWRzVXBkYXRlPSEwLHM9bC9kLml0ZW1TaXplfWlmKGkuaW5kZXgpe2NvbnN0IGM9aS5pbmRleC5hcnJheTtpZihjLmxlbmd0aDxzKWkuaW5kZXg9bnVsbCxuPSEwO2Vsc2UgZm9yKGxldCBsPTAsaD1jLmxlbmd0aDtsPGg7bCsrKWNbbF09bH1sZXQgYT0wO2kuY2xlYXJHcm91cHMoKTtmb3IobGV0IGM9MCxsPU1hdGgubWluKGUubGVuZ3RoLHQuZ3JvdXBDb3VudCk7YzxsO2MrKyl7Y29uc3R7aW5kZXg6aCxtYXRlcmlhbEluZGV4OnV9PWVbY10sZj10LmdldENvdW50KGgpO2YhPT0wJiYoaS5hZGRHcm91cChhLGYsdSksYSs9Zil9aS5zZXREcmF3UmFuZ2UoMCxzKSxpLmJvdW5kc1RyZWU9bnVsbCxuJiZpLmRpc3Bvc2UoKX1mdW5jdGlvbiBabChpLHQpe2xldCBlPXQ7cmV0dXJuIEFycmF5LmlzQXJyYXkodCl8fChlPVtdLGkuZm9yRWFjaChuPT57ZVtuLm1hdGVyaWFsSW5kZXhdPXR9KSksZX1jbGFzcyBHMHtjb25zdHJ1Y3Rvcigpe3RoaXMudHJpYW5nbGVTcGxpdHRlcj1uZXcgejAsdGhpcy5hdHRyaWJ1dGVEYXRhPVtdLHRoaXMuYXR0cmlidXRlcz1bInBvc2l0aW9uIiwidXYiLCJub3JtYWwiXSx0aGlzLnVzZUdyb3Vwcz0hMCx0aGlzLmNvbnNvbGlkYXRlR3JvdXBzPSEwLHRoaXMuZGVidWc9bmV3ICQwfWdldEdyb3VwUmFuZ2VzKHQpe3JldHVybiF0aGlzLnVzZUdyb3Vwc3x8dC5ncm91cHMubGVuZ3RoPT09MD9be3N0YXJ0OjAsY291bnQ6MS8wLG1hdGVyaWFsSW5kZXg6MH1dOnQuZ3JvdXBzLm1hcChlPT5GdCh7fSxlKSl9ZXZhbHVhdGUodCxlLG4scz1uZXcgWnMpe2xldCByPSEwO2lmKEFycmF5LmlzQXJyYXkobil8fChuPVtuXSksQXJyYXkuaXNBcnJheShzKXx8KHM9W3NdLHI9ITEpLHMubGVuZ3RoIT09bi5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKCJFdmFsdWF0b3I6IG9wZXJhdGlvbnMgYW5kIHRhcmdldCBhcnJheSBwYXNzZWQgYXMgZGlmZmVyZW50IHNpemVzLiIpO3QucHJlcGFyZUdlb21ldHJ5KCksZS5wcmVwYXJlR2VvbWV0cnkoKTtjb25zdHt0cmlhbmdsZVNwbGl0dGVyOm8sYXR0cmlidXRlRGF0YTphLGF0dHJpYnV0ZXM6Yyx1c2VHcm91cHM6bCxjb25zb2xpZGF0ZUdyb3VwczpoLGRlYnVnOnV9PXRoaXM7Zm9yKDthLmxlbmd0aDxzLmxlbmd0aDspYS5wdXNoKG5ldyBFMCk7cy5mb3JFYWNoKChnLGIpPT57SDAodC5nZW9tZXRyeSxnLmdlb21ldHJ5LGFbYl0sYyl9KSx1LmluaXQoKSxVMCh0LGUsbixvLGEse3VzZUdyb3VwczpsfSksdS5jb21wbGV0ZSgpO2NvbnN0IGY9dGhpcy5nZXRHcm91cFJhbmdlcyh0Lmdlb21ldHJ5KSxkPVpsKGYsdC5tYXRlcmlhbCkscD10aGlzLmdldEdyb3VwUmFuZ2VzKGUuZ2VvbWV0cnkpLHk9WmwocCxlLm1hdGVyaWFsKTtwLmZvckVhY2goZz0+Zy5tYXRlcmlhbEluZGV4Kz1kLmxlbmd0aCk7bGV0IG09Wy4uLmYsLi4ucF0ubWFwKChnLGIpPT5aZShGdCh7fSxnKSx7aW5kZXg6Yn0pKTtpZihsKXtjb25zdCBnPVsuLi5kLC4uLnldO2gmJihtPW0ubWFwKHc9Pntjb25zdCB4PWdbdy5tYXRlcmlhbEluZGV4XTtyZXR1cm4gdy5tYXRlcmlhbEluZGV4PWcuaW5kZXhPZih4KSx3fSkuc29ydCgodyx4KT0+dy5tYXRlcmlhbEluZGV4LXgubWF0ZXJpYWxJbmRleCkpO2NvbnN0IGI9W107Zm9yKGxldCB3PTAseD1nLmxlbmd0aDt3PHg7dysrKXtsZXQgTT0hMTtmb3IobGV0IEE9MCxTPW0ubGVuZ3RoO0E8UztBKyspe2NvbnN0IF89bVtBXTtfLm1hdGVyaWFsSW5kZXg9PT13JiYoTT0hMCxfLm1hdGVyaWFsSW5kZXg9Yi5sZW5ndGgpfU0mJmIucHVzaChnW3ddKX1zLmZvckVhY2godz0+e3cubWF0ZXJpYWw9Yn0pfWVsc2UgbT1be3N0YXJ0OjAsY291bnQ6MS8wLGluZGV4OjAsbWF0ZXJpYWxJbmRleDowfV0scy5mb3JFYWNoKGc9PntnLm1hdGVyaWFsPWRbMF19KTtyZXR1cm4gcy5mb3JFYWNoKChnLGIpPT57Y29uc3Qgdz1nLmdlb21ldHJ5O1cwKHcsYVtiXSxtKSxoJiZxMCh3Lmdyb3Vwcyl9KSxyP3M6c1swXX1ldmFsdWF0ZUhpZXJhcmNoeSh0LGU9bmV3IFpzKXt0LnVwZGF0ZU1hdHJpeFdvcmxkKCEwKTtjb25zdCBuPShyLG8pPT57Y29uc3QgYT1yLmNoaWxkcmVuO2ZvcihsZXQgYz0wLGw9YS5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1hW2NdO2guaXNPcGVyYXRpb25Hcm91cD9uKGgsbyk6byhoKX19LHM9cj0+e2NvbnN0IG89ci5jaGlsZHJlbjtsZXQgYT0hMTtmb3IobGV0IGw9MCxoPW8ubGVuZ3RoO2w8aDtsKyspe2NvbnN0IHU9b1tsXTthPXModSl8fGF9Y29uc3QgYz1yLmlzRGlydHkoKTtpZihjJiZyLm1hcmtVcGRhdGVkKCksYSYmIXIuaXNPcGVyYXRpb25Hcm91cCl7bGV0IGw7cmV0dXJuIG4ocixoPT57bD9sPXRoaXMuZXZhbHVhdGUobCxoLGgub3BlcmF0aW9uKTpsPXRoaXMuZXZhbHVhdGUocixoLGgub3BlcmF0aW9uKX0pLHIuX2NhY2hlZEdlb21ldHJ5PWwuZ2VvbWV0cnksci5fY2FjaGVkTWF0ZXJpYWxzPWwubWF0ZXJpYWwsITB9ZWxzZSByZXR1cm4gYXx8Y307cmV0dXJuIHModCksZS5nZW9tZXRyeT10Ll9jYWNoZWRHZW9tZXRyeSxlLm1hdGVyaWFsPXQuX2NhY2hlZE1hdGVyaWFscyxlfXJlc2V0KCl7dGhpcy50cmlhbmdsZVNwbGl0dGVyLnJlc2V0KCl9fWZ1bmN0aW9uIFhsKGkpe2xldCB0LGUsbixzPS0xLHI9MDtmb3IobGV0IGw9MDtsPGkubGVuZ3RoOysrbCl7Y29uc3QgaD1pW2xdO2lmKHQ9PT12b2lkIDAmJih0PWguYXJyYXkuY29uc3RydWN0b3IpLHQhPT1oLmFycmF5LmNvbnN0cnVjdG9yKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuYXJyYXkgbXVzdCBiZSBvZiBjb25zaXN0ZW50IGFycmF5IHR5cGVzIGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7aWYoZT09PXZvaWQgMCYmKGU9aC5pdGVtU2l6ZSksZSE9PWguaXRlbVNpemUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUF0dHJpYnV0ZXMoKSBmYWlsZWQuIEJ1ZmZlckF0dHJpYnV0ZS5pdGVtU2l6ZSBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihuPT09dm9pZCAwJiYobj1oLm5vcm1hbGl6ZWQpLG4hPT1oLm5vcm1hbGl6ZWQpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUF0dHJpYnV0ZXMoKSBmYWlsZWQuIEJ1ZmZlckF0dHJpYnV0ZS5ub3JtYWxpemVkIG11c3QgYmUgY29uc2lzdGVudCBhY3Jvc3MgbWF0Y2hpbmcgYXR0cmlidXRlcy4iKSxudWxsO2lmKHM9PT0tMSYmKHM9aC5ncHVUeXBlKSxzIT09aC5ncHVUeXBlKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuZ3B1VHlwZSBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtyKz1oLmNvdW50KmV9Y29uc3Qgbz1uZXcgdChyKSxhPW5ldyB4dChvLGUsbik7bGV0IGM9MDtmb3IobGV0IGw9MDtsPGkubGVuZ3RoOysrbCl7Y29uc3QgaD1pW2xdO2lmKGguaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl7Y29uc3QgdT1jL2U7Zm9yKGxldCBmPTAsZD1oLmNvdW50O2Y8ZDtmKyspZm9yKGxldCBwPTA7cDxlO3ArKyl7Y29uc3QgeT1oLmdldENvbXBvbmVudChmLHApO2Euc2V0Q29tcG9uZW50KGYrdSxwLHkpfX1lbHNlIG8uc2V0KGguYXJyYXksYyk7Yys9aC5jb3VudCplfXJldHVybiBzIT09dm9pZCAwJiYoYS5ncHVUeXBlPXMpLGF9ZnVuY3Rpb24gWjAoaSl7aWYoaS5ncm91cHMubGVuZ3RoPT09MClyZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzLm1lcmdlR3JvdXBzKCk6IE5vIGdyb3VwcyBhcmUgZGVmaW5lZC4gTm90aGluZyB0byBtZXJnZS4iKSxpO2xldCB0PWkuZ3JvdXBzO2lmKHQ9dC5zb3J0KChvLGEpPT5vLm1hdGVyaWFsSW5kZXghPT1hLm1hdGVyaWFsSW5kZXg/by5tYXRlcmlhbEluZGV4LWEubWF0ZXJpYWxJbmRleDpvLnN0YXJ0LWEuc3RhcnQpLGkuZ2V0SW5kZXgoKT09PW51bGwpe2NvbnN0IG89aS5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIiksYT1bXTtmb3IobGV0IGM9MDtjPG8uY291bnQ7Yys9MylhLnB1c2goYyxjKzEsYysyKTtpLnNldEluZGV4KGEpfWNvbnN0IGU9aS5nZXRJbmRleCgpLG49W107Zm9yKGxldCBvPTA7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXSxjPWEuc3RhcnQsbD1jK2EuY291bnQ7Zm9yKGxldCBoPWM7aDxsO2grKyluLnB1c2goZS5nZXRYKGgpKX1pLmRpc3Bvc2UoKSxpLnNldEluZGV4KG4pO2xldCBzPTA7Zm9yKGxldCBvPTA7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXTthLnN0YXJ0PXMscys9YS5jb3VudH1sZXQgcj10WzBdO2kuZ3JvdXBzPVtyXTtmb3IobGV0IG89MTtvPHQubGVuZ3RoO28rKyl7Y29uc3QgYT10W29dO3IubWF0ZXJpYWxJbmRleD09PWEubWF0ZXJpYWxJbmRleD9yLmNvdW50Kz1hLmNvdW50OihyPWEsaS5ncm91cHMucHVzaChyKSl9cmV0dXJuIGl9ZnVuY3Rpb24gSmwoaSx0PTApe2NvbnN0IGU9aVswXS5pbmRleCE9PW51bGwsbj1uZXcgU2V0KE9iamVjdC5rZXlzKGlbMF0uYXR0cmlidXRlcykpLHM9bmV3IFNldChPYmplY3Qua2V5cyhpWzBdLm1vcnBoQXR0cmlidXRlcykpLHI9e30sbz17fSxhPWlbMF0ubW9ycGhUYXJnZXRzUmVsYXRpdmUsYz1uZXcgdWU7bGV0IGw9MDtmb3IobGV0IGg9MDtoPGkubGVuZ3RoOysraCl7Y29uc3QgdT1pW2hdO2xldCBmPTA7aWYoZSE9PSh1LmluZGV4IT09bnVsbCkpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gQWxsIGdlb21ldHJpZXMgbXVzdCBoYXZlIGNvbXBhdGlibGUgYXR0cmlidXRlczsgbWFrZSBzdXJlIGluZGV4IGF0dHJpYnV0ZSBleGlzdHMgYW1vbmcgYWxsIGdlb21ldHJpZXMsIG9yIGluIG5vbmUgb2YgdGhlbS4iKSxudWxsO2Zvcihjb25zdCBkIGluIHUuYXR0cmlidXRlcyl7aWYoIW4uaGFzKGQpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKycuIEFsbCBnZW9tZXRyaWVzIG11c3QgaGF2ZSBjb21wYXRpYmxlIGF0dHJpYnV0ZXM7IG1ha2Ugc3VyZSAiJytkKyciIGF0dHJpYnV0ZSBleGlzdHMgYW1vbmcgYWxsIGdlb21ldHJpZXMsIG9yIGluIG5vbmUgb2YgdGhlbS4nKSxudWxsO3JbZF09PT12b2lkIDAmJihyW2RdPVtdKSxyW2RdLnB1c2godS5hdHRyaWJ1dGVzW2RdKSxmKyt9aWYoZiE9PW4uc2l6ZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiBNYWtlIHN1cmUgYWxsIGdlb21ldHJpZXMgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgYXR0cmlidXRlcy4iKSxudWxsO2lmKGEhPT11Lm1vcnBoVGFyZ2V0c1JlbGF0aXZlKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIC5tb3JwaFRhcmdldHNSZWxhdGl2ZSBtdXN0IGJlIGNvbnNpc3RlbnQgdGhyb3VnaG91dCBhbGwgZ2VvbWV0cmllcy4iKSxudWxsO2Zvcihjb25zdCBkIGluIHUubW9ycGhBdHRyaWJ1dGVzKXtpZighcy5oYXMoZCkpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gIC5tb3JwaEF0dHJpYnV0ZXMgbXVzdCBiZSBjb25zaXN0ZW50IHRocm91Z2hvdXQgYWxsIGdlb21ldHJpZXMuIiksbnVsbDtvW2RdPT09dm9pZCAwJiYob1tkXT1bXSksb1tkXS5wdXNoKHUubW9ycGhBdHRyaWJ1dGVzW2RdKX1pZih0KXtsZXQgZDtpZihlKWQ9dS5pbmRleC5jb3VudDtlbHNlIGlmKHUuYXR0cmlidXRlcy5wb3NpdGlvbiE9PXZvaWQgMClkPXUuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudDtlbHNlIHJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIFRoZSBnZW9tZXRyeSBtdXN0IGhhdmUgZWl0aGVyIGFuIGluZGV4IG9yIGEgcG9zaXRpb24gYXR0cmlidXRlIiksbnVsbDtpZih0PT09MSljLmFkZEdyb3VwKGwsZCxoKTtlbHNlIGlmKHQ9PT0yJiZ1Lmdyb3Vwcy5sZW5ndGg+MClmb3IobGV0IHAgb2YgdS5ncm91cHMpe2xldCB5PXAubWF0ZXJpYWxJbmRleDtjLmFkZEdyb3VwKGwrcC5zdGFydCxNYXRoLm1pbihwLmNvdW50LGQpLHkpfWwrPWR9fWlmKGUpe2xldCBoPTA7Y29uc3QgdT1bXTtmb3IobGV0IGY9MDtmPGkubGVuZ3RoOysrZil7Y29uc3QgZD1pW2ZdLmluZGV4O2ZvcihsZXQgcD0wO3A8ZC5jb3VudDsrK3ApdS5wdXNoKGQuZ2V0WChwKStoKTtoKz1pW2ZdLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnR9Yy5zZXRJbmRleCh1KX1mb3IoY29uc3QgaCBpbiByKXtjb25zdCB1PVhsKHJbaF0pO2lmKCF1KXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdoaWxlIHRyeWluZyB0byBtZXJnZSB0aGUgIitoKyIgYXR0cmlidXRlLiIpLG51bGw7Yy5zZXRBdHRyaWJ1dGUoaCx1KX1mb3IoY29uc3QgaCBpbiBvKXtjb25zdCB1PW9baF1bMF0ubGVuZ3RoO2lmKHU9PT0wKWJyZWFrO2MubW9ycGhBdHRyaWJ1dGVzPWMubW9ycGhBdHRyaWJ1dGVzfHx7fSxjLm1vcnBoQXR0cmlidXRlc1toXT1bXTtmb3IobGV0IGY9MDtmPHU7KytmKXtjb25zdCBkPVtdO2ZvcihsZXQgeT0wO3k8b1toXS5sZW5ndGg7Kyt5KWQucHVzaChvW2hdW3ldW2ZdKTtjb25zdCBwPVhsKGQpO2lmKCFwKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdoaWxlIHRyeWluZyB0byBtZXJnZSB0aGUgIitoKyIgbW9ycGhBdHRyaWJ1dGUuIiksbnVsbDtjLm1vcnBoQXR0cmlidXRlc1toXS5wdXNoKHApfX1yZXR1cm4gdD09PTI/WjAoYyk6Y31jbGFzcyBYMCBleHRlbmRzIEdue2NvbnN0cnVjdG9yKHQsZSl7c3VwZXIodCxlKTtjb25zdCBuPW5ldyBacyhuZXcgR24odCxaZShGdCh7fSxlKSx7aGFzVG9wOiEwLGhhc1NpZGU6ITAsaGFzQm90dG9tOiExfSkpKTtuLnVwZGF0ZU1hdHJpeFdvcmxkKCk7Y29uc3Qgcz1uZXcgZ3QoKS5zZXRGcm9tT2JqZWN0KG4pLHI9bmV3IFQ7cy5nZXRTaXplKHIpO2NvbnN0IG89bmV3IFQocy5taW4ueCtyLngvMixzLm1pbi55K3IueS8yLDApO2xldCBhPWUudG9wU2VnbWVudHMsYz1lLmJveDM7aWYoYyl7Yz1jLnVuaW9uKHMpO2NvbnN0IGc9bmV3IFQ7Yy5nZXRTaXplKGcpO2NvbnN0IGI9TWF0aC5tYXgoci54L2cueCxyLnkvZy55KTthPU1hdGguY2VpbChlLnRvcFNlZ21lbnRzKmIpfWlmKGE8NClyZXR1cm4gdGhpcztjb25zdCBsPW5ldyBMbyhyLngsci55LGEsYSksaD1uZXcgWnMobCk7aC5wb3NpdGlvbi5zZXQoby54LG8ueSxvLnopLGgudXBkYXRlTWF0cml4V29ybGQoKTtjb25zdCBmPW5ldyBHMCgpLmV2YWx1YXRlKGgsbixJbCksZD1mLmdlb21ldHJ5LmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKSxwPW5ldyBCZShkLmNvdW50KjIsMik7Zm9yKGxldCBnPTA7ZzxkLmNvdW50O2crKyl7Y29uc3QgYj1kLmdldFooZyk7ZC5zZXRaKGcsZS5kZXB0aCtiKX1pZihjKXtjb25zdCBnPWMubWluLGI9Yy5tYXgsdz1uZXcgVCgpLnN1YlZlY3RvcnMoYixnKTtmb3IobGV0IHg9MDt4PGQuY291bnQ7eCsrKXtjb25zdCBNPWQuZ2V0WCh4KSxBPWQuZ2V0WSh4KSxTPShNLWcueCkvdy54LF89KEEtZy55KS93Lnk7cC5zZXRYWSh4LFMsXyl9Zi5nZW9tZXRyeS5zZXRBdHRyaWJ1dGUoInV2IixwKX1kLm5lZWRzVXBkYXRlPSEwO2NvbnN0IHk9bmV3IEduKHQsWmUoRnQoe30sZSkse2hhc1RvcDohMX0pKSxtPUpsKFtmLmdlb21ldHJ5LHldLDIpO3RoaXMuY29weShtLnRvTm9uSW5kZXhlZCgpKX19dmFyIEowPWk9Pntjb25zdHtzcGxpdDp0LGRlcHRoOmUscG9pbnRzOm4sYm94MzpzLGhhc1RvcDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSxzaWRlUmVwZWF0OmMsdG9wU2VnbWVudHM6bH09aSxoPWw/WDA6R24sdT1uZXcgaChuZXcgWGMobikse2RlcHRoOmUsYmV2ZWxFbmFibGVkOiExLGJveDM6cyxVVkdlbmVyYXRvcjpZZih7c3BsaXQ6dCxib3gzOnMsc2lkZVJlcGVhdDpjfSksaGFzVG9wOnIsaGFzQm90dG9tOm8saGFzU2lkZTphLHRvcFNlZ21lbnRzOmx9KTtyZXR1cm4gamYoKSx1fTtmdW5jdGlvbiBZMChpLHQsZT0wKXtjb25zdCBuPSg5MC10KSpNYXRoLlBJLzE4MCxzPSg5MC1pKSpNYXRoLlBJLzE4MDtyZXR1cm5bZSpNYXRoLnNpbihuKSpNYXRoLmNvcyhzKSxlKk1hdGguY29zKG4pLGUqTWF0aC5zaW4obikqTWF0aC5zaW4ocyldfWZ1bmN0aW9uIGlyKGksdCl7cmV0dXJuIGk9PW51bGx8fHQ9PW51bGw/TmFOOmk8dD8tMTppPnQ/MTppPj10PzA6TmFOfWZ1bmN0aW9uIGowKGksdCl7cmV0dXJuIGk9PW51bGx8fHQ9PW51bGw/TmFOOnQ8aT8tMTp0Pmk/MTp0Pj1pPzA6TmFOfWZ1bmN0aW9uIFlsKGkpe2xldCB0LGUsbjtpLmxlbmd0aCE9PTI/KHQ9aXIsZT0oYSxjKT0+aXIoaShhKSxjKSxuPShhLGMpPT5pKGEpLWMpOih0PWk9PT1pcnx8aT09PWowP2k6UTAsZT1pLG49aSk7ZnVuY3Rpb24gcyhhLGMsbD0wLGg9YS5sZW5ndGgpe2lmKGw8aCl7aWYodChjLGMpIT09MClyZXR1cm4gaDtkb3tjb25zdCB1PWwraD4+PjE7ZShhW3VdLGMpPDA/bD11KzE6aD11fXdoaWxlKGw8aCl9cmV0dXJuIGx9ZnVuY3Rpb24gcihhLGMsbD0wLGg9YS5sZW5ndGgpe2lmKGw8aCl7aWYodChjLGMpIT09MClyZXR1cm4gaDtkb3tjb25zdCB1PWwraD4+PjE7ZShhW3VdLGMpPD0wP2w9dSsxOmg9dX13aGlsZShsPGgpfXJldHVybiBsfWZ1bmN0aW9uIG8oYSxjLGw9MCxoPWEubGVuZ3RoKXtjb25zdCB1PXMoYSxjLGwsaC0xKTtyZXR1cm4gdT5sJiZuKGFbdS0xXSxjKT4tbihhW3VdLGMpP3UtMTp1fXJldHVybntsZWZ0OnMsY2VudGVyOm8scmlnaHQ6cn19ZnVuY3Rpb24gUTAoKXtyZXR1cm4gMH1mdW5jdGlvbiBLMChpKXtyZXR1cm4gaT09PW51bGw/TmFOOitpfWNvbnN0IHRwPVlsKGlyKS5yaWdodDtZbChLMCkuY2VudGVyO2Z1bmN0aW9uIHNyKGksdCl7bGV0IGUsbjtpZih0PT09dm9pZCAwKWZvcihjb25zdCBzIG9mIGkpcyE9bnVsbCYmKGU9PT12b2lkIDA/cz49cyYmKGU9bj1zKTooZT5zJiYoZT1zKSxuPHMmJihuPXMpKSk7ZWxzZXtsZXQgcz0tMTtmb3IobGV0IHIgb2YgaSkocj10KHIsKytzLGkpKSE9bnVsbCYmKGU9PT12b2lkIDA/cj49ciYmKGU9bj1yKTooZT5yJiYoZT1yKSxuPHImJihuPXIpKSl9cmV0dXJuW2Usbl19Y2xhc3MgTGV7Y29uc3RydWN0b3IoKXt0aGlzLl9wYXJ0aWFscz1uZXcgRmxvYXQ2NEFycmF5KDMyKSx0aGlzLl9uPTB9YWRkKHQpe2NvbnN0IGU9dGhpcy5fcGFydGlhbHM7bGV0IG49MDtmb3IobGV0IHM9MDtzPHRoaXMuX24mJnM8MzI7cysrKXtjb25zdCByPWVbc10sbz10K3IsYT1NYXRoLmFicyh0KTxNYXRoLmFicyhyKT90LShvLXIpOnItKG8tdCk7YSYmKGVbbisrXT1hKSx0PW99cmV0dXJuIGVbbl09dCx0aGlzLl9uPW4rMSx0aGlzfXZhbHVlT2YoKXtjb25zdCB0PXRoaXMuX3BhcnRpYWxzO2xldCBlPXRoaXMuX24sbixzLHIsbz0wO2lmKGU+MCl7Zm9yKG89dFstLWVdO2U+MCYmKG49byxzPXRbLS1lXSxvPW4rcyxyPXMtKG8tbiksIXIpOyk7ZT4wJiYocjwwJiZ0W2UtMV08MHx8cj4wJiZ0W2UtMV0+MCkmJihzPXIqMixuPW8rcyxzPT1uLW8mJihvPW4pKX1yZXR1cm4gb319Y29uc3QgZXA9TWF0aC5zcXJ0KDUwKSxucD1NYXRoLnNxcnQoMTApLGlwPU1hdGguc3FydCgyKTtmdW5jdGlvbiBycihpLHQsZSl7Y29uc3Qgbj0odC1pKS9NYXRoLm1heCgwLGUpLHM9TWF0aC5mbG9vcihNYXRoLmxvZzEwKG4pKSxyPW4vTWF0aC5wb3coMTAscyksbz1yPj1lcD8xMDpyPj1ucD81OnI+PWlwPzI6MTtsZXQgYSxjLGw7cmV0dXJuIHM8MD8obD1NYXRoLnBvdygxMCwtcykvbyxhPU1hdGgucm91bmQoaSpsKSxjPU1hdGgucm91bmQodCpsKSxhL2w8aSYmKythLGMvbD50JiYtLWMsbD0tbCk6KGw9TWF0aC5wb3coMTAscykqbyxhPU1hdGgucm91bmQoaS9sKSxjPU1hdGgucm91bmQodC9sKSxhKmw8aSYmKythLGMqbD50JiYtLWMpLGM8YSYmLjU8PWUmJmU8Mj9ycihpLHQsZSoyKTpbYSxjLGxdfWZ1bmN0aW9uIHNwKGksdCxlKXtpZih0PSt0LGk9K2ksZT0rZSwhKGU+MCkpcmV0dXJuW107aWYoaT09PXQpcmV0dXJuW2ldO2NvbnN0IG49dDxpLFtzLHIsb109bj9ycih0LGksZSk6cnIoaSx0LGUpO2lmKCEocj49cykpcmV0dXJuW107Y29uc3QgYT1yLXMrMSxjPW5ldyBBcnJheShhKTtpZihuKWlmKG88MClmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHItbCkvLW87ZWxzZSBmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHItbCkqbztlbHNlIGlmKG88MClmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHMrbCkvLW87ZWxzZSBmb3IobGV0IGw9MDtsPGE7KytsKWNbbF09KHMrbCkqbztyZXR1cm4gY31mdW5jdGlvbiBBYShpLHQsZSl7cmV0dXJuIHQ9K3QsaT0raSxlPStlLHJyKGksdCxlKVsyXX1mdW5jdGlvbiBycChpLHQsZSl7dD0rdCxpPStpLGU9K2U7Y29uc3Qgbj10PGkscz1uP0FhKHQsaSxlKTpBYShpLHQsZSk7cmV0dXJuKG4/LTE6MSkqKHM8MD8xLy1zOnMpfWZ1bmN0aW9uIG9wKGksdCl7bGV0IGU9MCxuPTA7aWYodD09PXZvaWQgMClmb3IobGV0IHMgb2YgaSlzIT1udWxsJiYocz0rcyk+PXMmJigrK2Usbis9cyk7ZWxzZXtsZXQgcz0tMTtmb3IobGV0IHIgb2YgaSkocj10KHIsKytzLGkpKSE9bnVsbCYmKHI9K3IpPj1yJiYoKytlLG4rPXIpfWlmKGUpcmV0dXJuIG4vZX1mdW5jdGlvbiphcChpKXtmb3IoY29uc3QgdCBvZiBpKXlpZWxkKll1KHQpfWZ1bmN0aW9uIFZpKGkpe3JldHVybiBBcnJheS5mcm9tKGFwKGkpKX12YXIgSz0xZS02LG9yPTFlLTEyLFg9TWF0aC5QSSxOdD1YLzIsYXI9WC80LFJ0PVgqMixodD0xODAvWCxIPVgvMTgwLHR0PU1hdGguYWJzLFNhPU1hdGguYXRhbixyZT1NYXRoLmF0YW4yLFc9TWF0aC5jb3MsY3A9TWF0aC5leHAsX2E9TWF0aC5oeXBvdCxscD1NYXRoLmxvZyxxPU1hdGguc2luLGhwPU1hdGguc2lnbnx8ZnVuY3Rpb24oaSl7cmV0dXJuIGk+MD8xOmk8MD8tMTowfSxPZT1NYXRoLnNxcnQsdXA9TWF0aC50YW47ZnVuY3Rpb24gZnAoaSl7cmV0dXJuIGk+MT8wOmk8LTE/WDpNYXRoLmFjb3MoaSl9ZnVuY3Rpb24gRGUoaSl7cmV0dXJuIGk+MT9OdDppPC0xPy1OdDpNYXRoLmFzaW4oaSl9ZnVuY3Rpb24gamwoaSl7cmV0dXJuKGk9cShpLzIpKSppfWZ1bmN0aW9uIF90KCl7fWZ1bmN0aW9uIGNyKGksdCl7aSYmS2wuaGFzT3duUHJvcGVydHkoaS50eXBlKSYmS2xbaS50eXBlXShpLHQpfXZhciBRbD17RmVhdHVyZTpmdW5jdGlvbihpLHQpe2NyKGkuZ2VvbWV0cnksdCl9LEZlYXR1cmVDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZmVhdHVyZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOyljcihlW25dLmdlb21ldHJ5LHQpfX0sS2w9e1NwaGVyZTpmdW5jdGlvbihpLHQpe3Quc3BoZXJlKCl9LFBvaW50OmZ1bmN0aW9uKGksdCl7aT1pLmNvb3JkaW5hdGVzLHQucG9pbnQoaVswXSxpWzFdLGlbMl0pfSxNdWx0aVBvaW50OmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpPWVbbl0sdC5wb2ludChpWzBdLGlbMV0saVsyXSl9LExpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXt2YShpLmNvb3JkaW5hdGVzLHQsMCl9LE11bHRpTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspdmEoZVtuXSx0LDApfSxQb2x5Z29uOmZ1bmN0aW9uKGksdCl7dGgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2x5Z29uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOyl0aChlW25dLHQpfSxHZW9tZXRyeUNvbGxlY3Rpb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5nZW9tZXRyaWVzLG49LTEscz1lLmxlbmd0aDsrK248czspY3IoZVtuXSx0KX19O2Z1bmN0aW9uIHZhKGksdCxlKXt2YXIgbj0tMSxzPWkubGVuZ3RoLWUscjtmb3IodC5saW5lU3RhcnQoKTsrK248czspcj1pW25dLHQucG9pbnQoclswXSxyWzFdLHJbMl0pO3QubGluZUVuZCgpfWZ1bmN0aW9uIHRoKGksdCl7dmFyIGU9LTEsbj1pLmxlbmd0aDtmb3IodC5wb2x5Z29uU3RhcnQoKTsrK2U8bjspdmEoaVtlXSx0LDEpO3QucG9seWdvbkVuZCgpfWZ1bmN0aW9uIGxyKGksdCl7aSYmUWwuaGFzT3duUHJvcGVydHkoaS50eXBlKT9RbFtpLnR5cGVdKGksdCk6Y3IoaSx0KX12YXIgaHI9bmV3IExlLGVoPW5ldyBMZSxuaCxpaCx6YSxUYSxFYSwkZT17cG9pbnQ6X3QsbGluZVN0YXJ0Ol90LGxpbmVFbmQ6X3QscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7aHI9bmV3IExlLCRlLmxpbmVTdGFydD1kcCwkZS5saW5lRW5kPXBwfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7dmFyIGk9K2hyO2VoLmFkZChpPDA/UnQraTppKSx0aGlzLmxpbmVTdGFydD10aGlzLmxpbmVFbmQ9dGhpcy5wb2ludD1fdH0sc3BoZXJlOmZ1bmN0aW9uKCl7ZWguYWRkKFJ0KX19O2Z1bmN0aW9uIGRwKCl7JGUucG9pbnQ9eXB9ZnVuY3Rpb24gcHAoKXtzaChuaCxpaCl9ZnVuY3Rpb24geXAoaSx0KXskZS5wb2ludD1zaCxuaD1pLGloPXQsaSo9SCx0Kj1ILHphPWksVGE9Vyh0PXQvMithciksRWE9cSh0KX1mdW5jdGlvbiBzaChpLHQpe2kqPUgsdCo9SCx0PXQvMithcjt2YXIgZT1pLXphLG49ZT49MD8xOi0xLHM9biplLHI9Vyh0KSxvPXEodCksYT1FYSpvLGM9VGEqcithKlcocyksbD1hKm4qcShzKTtoci5hZGQocmUobCxjKSksemE9aSxUYT1yLEVhPW99ZnVuY3Rpb24gdXIoaSl7cmV0dXJuW3JlKGlbMV0saVswXSksRGUoaVsyXSldfWZ1bmN0aW9uIFNuKGkpe3ZhciB0PWlbMF0sZT1pWzFdLG49VyhlKTtyZXR1cm5bbipXKHQpLG4qcSh0KSxxKGUpXX1mdW5jdGlvbiBmcihpLHQpe3JldHVybiBpWzBdKnRbMF0raVsxXSp0WzFdK2lbMl0qdFsyXX1mdW5jdGlvbiBuaShpLHQpe3JldHVybltpWzFdKnRbMl0taVsyXSp0WzFdLGlbMl0qdFswXS1pWzBdKnRbMl0saVswXSp0WzFdLWlbMV0qdFswXV19ZnVuY3Rpb24gUGEoaSx0KXtpWzBdKz10WzBdLGlbMV0rPXRbMV0saVsyXSs9dFsyXX1mdW5jdGlvbiBkcihpLHQpe3JldHVybltpWzBdKnQsaVsxXSp0LGlbMl0qdF19ZnVuY3Rpb24gcHIoaSl7dmFyIHQ9T2UoaVswXSppWzBdK2lbMV0qaVsxXStpWzJdKmlbMl0pO2lbMF0vPXQsaVsxXS89dCxpWzJdLz10fXZhciBvdCxMdCx1dCxxdCxfbixyaCxvaCxpaSxVaSxhbixWZSxVZT17cG9pbnQ6Q2EsbGluZVN0YXJ0OmNoLGxpbmVFbmQ6bGgscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7VWUucG9pbnQ9aGgsVWUubGluZVN0YXJ0PW1wLFVlLmxpbmVFbmQ9Z3AsVWk9bmV3IExlLCRlLnBvbHlnb25TdGFydCgpfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7JGUucG9seWdvbkVuZCgpLFVlLnBvaW50PUNhLFVlLmxpbmVTdGFydD1jaCxVZS5saW5lRW5kPWxoLGhyPDA/KG90PS0odXQ9MTgwKSxMdD0tKHF0PTkwKSk6VWk+Sz9xdD05MDpVaTwtSyYmKEx0PS05MCksVmVbMF09b3QsVmVbMV09dXR9LHNwaGVyZTpmdW5jdGlvbigpe290PS0odXQ9MTgwKSxMdD0tKHF0PTkwKX19O2Z1bmN0aW9uIENhKGksdCl7YW4ucHVzaChWZT1bb3Q9aSx1dD1pXSksdDxMdCYmKEx0PXQpLHQ+cXQmJihxdD10KX1mdW5jdGlvbiBhaChpLHQpe3ZhciBlPVNuKFtpKkgsdCpIXSk7aWYoaWkpe3ZhciBuPW5pKGlpLGUpLHM9W25bMV0sLW5bMF0sMF0scj1uaShzLG4pO3ByKHIpLHI9dXIocik7dmFyIG89aS1fbixhPW8+MD8xOi0xLGM9clswXSpodCphLGwsaD10dChvKT4xODA7aF4oYSpfbjxjJiZjPGEqaSk/KGw9clsxXSpodCxsPnF0JiYocXQ9bCkpOihjPShjKzM2MCklMzYwLTE4MCxoXihhKl9uPGMmJmM8YSppKT8obD0tclsxXSpodCxsPEx0JiYoTHQ9bCkpOih0PEx0JiYoTHQ9dCksdD5xdCYmKHF0PXQpKSksaD9pPF9uP0h0KG90LGkpPkh0KG90LHV0KSYmKHV0PWkpOkh0KGksdXQpPkh0KG90LHV0KSYmKG90PWkpOnV0Pj1vdD8oaTxvdCYmKG90PWkpLGk+dXQmJih1dD1pKSk6aT5fbj9IdChvdCxpKT5IdChvdCx1dCkmJih1dD1pKTpIdChpLHV0KT5IdChvdCx1dCkmJihvdD1pKX1lbHNlIGFuLnB1c2goVmU9W290PWksdXQ9aV0pO3Q8THQmJihMdD10KSx0PnF0JiYocXQ9dCksaWk9ZSxfbj1pfWZ1bmN0aW9uIGNoKCl7VWUucG9pbnQ9YWh9ZnVuY3Rpb24gbGgoKXtWZVswXT1vdCxWZVsxXT11dCxVZS5wb2ludD1DYSxpaT1udWxsfWZ1bmN0aW9uIGhoKGksdCl7aWYoaWkpe3ZhciBlPWktX247VWkuYWRkKHR0KGUpPjE4MD9lKyhlPjA/MzYwOi0zNjApOmUpfWVsc2Ugcmg9aSxvaD10OyRlLnBvaW50KGksdCksYWgoaSx0KX1mdW5jdGlvbiBtcCgpeyRlLmxpbmVTdGFydCgpfWZ1bmN0aW9uIGdwKCl7aGgocmgsb2gpLCRlLmxpbmVFbmQoKSx0dChVaSk+SyYmKG90PS0odXQ9MTgwKSksVmVbMF09b3QsVmVbMV09dXQsaWk9bnVsbH1mdW5jdGlvbiBIdChpLHQpe3JldHVybih0LT1pKTwwP3QrMzYwOnR9ZnVuY3Rpb24geHAoaSx0KXtyZXR1cm4gaVswXS10WzBdfWZ1bmN0aW9uIHVoKGksdCl7cmV0dXJuIGlbMF08PWlbMV0/aVswXTw9dCYmdDw9aVsxXTp0PGlbMF18fGlbMV08dH1mdW5jdGlvbiBmaChpKXt2YXIgdCxlLG4scyxyLG8sYTtpZihxdD11dD0tKG90PUx0PTEvMCksYW49W10sbHIoaSxVZSksZT1hbi5sZW5ndGgpe2Zvcihhbi5zb3J0KHhwKSx0PTEsbj1hblswXSxyPVtuXTt0PGU7Kyt0KXM9YW5bdF0sdWgobixzWzBdKXx8dWgobixzWzFdKT8oSHQoblswXSxzWzFdKT5IdChuWzBdLG5bMV0pJiYoblsxXT1zWzFdKSxIdChzWzBdLG5bMV0pPkh0KG5bMF0sblsxXSkmJihuWzBdPXNbMF0pKTpyLnB1c2gobj1zKTtmb3Iobz0tMS8wLGU9ci5sZW5ndGgtMSx0PTAsbj1yW2VdO3Q8PWU7bj1zLCsrdClzPXJbdF0sKGE9SHQoblsxXSxzWzBdKSk+byYmKG89YSxvdD1zWzBdLHV0PW5bMV0pfXJldHVybiBhbj1WZT1udWxsLG90PT09MS8wfHxMdD09PTEvMD9bW05hTixOYU5dLFtOYU4sTmFOXV06W1tvdCxMdF0sW3V0LHF0XV19dmFyIHFpLHlyLG1yLGdyLHhyLHdyLGJyLE1yLEJhLEZhLElhLGRoLHBoLEV0LFB0LEN0LHBlPXtzcGhlcmU6X3QscG9pbnQ6a2EsbGluZVN0YXJ0OnloLGxpbmVFbmQ6bWgscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7cGUubGluZVN0YXJ0PU1wLHBlLmxpbmVFbmQ9QXB9LHBvbHlnb25FbmQ6ZnVuY3Rpb24oKXtwZS5saW5lU3RhcnQ9eWgscGUubGluZUVuZD1taH19O2Z1bmN0aW9uIGthKGksdCl7aSo9SCx0Kj1IO3ZhciBlPVcodCk7SGkoZSpXKGkpLGUqcShpKSxxKHQpKX1mdW5jdGlvbiBIaShpLHQsZSl7KytxaSxtcis9KGktbXIpL3FpLGdyKz0odC1ncikvcWkseHIrPShlLXhyKS9xaX1mdW5jdGlvbiB5aCgpe3BlLnBvaW50PXdwfWZ1bmN0aW9uIHdwKGksdCl7aSo9SCx0Kj1IO3ZhciBlPVcodCk7RXQ9ZSpXKGkpLFB0PWUqcShpKSxDdD1xKHQpLHBlLnBvaW50PWJwLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiBicChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpLG49ZSpXKGkpLHM9ZSpxKGkpLHI9cSh0KSxvPXJlKE9lKChvPVB0KnItQ3Qqcykqbysobz1DdCpuLUV0KnIpKm8rKG89RXQqcy1QdCpuKSpvKSxFdCpuK1B0KnMrQ3Qqcik7eXIrPW8sd3IrPW8qKEV0KyhFdD1uKSksYnIrPW8qKFB0KyhQdD1zKSksTXIrPW8qKEN0KyhDdD1yKSksSGkoRXQsUHQsQ3QpfWZ1bmN0aW9uIG1oKCl7cGUucG9pbnQ9a2F9ZnVuY3Rpb24gTXAoKXtwZS5wb2ludD1TcH1mdW5jdGlvbiBBcCgpe2doKGRoLHBoKSxwZS5wb2ludD1rYX1mdW5jdGlvbiBTcChpLHQpe2RoPWkscGg9dCxpKj1ILHQqPUgscGUucG9pbnQ9Z2g7dmFyIGU9Vyh0KTtFdD1lKlcoaSksUHQ9ZSpxKGkpLEN0PXEodCksSGkoRXQsUHQsQ3QpfWZ1bmN0aW9uIGdoKGksdCl7aSo9SCx0Kj1IO3ZhciBlPVcodCksbj1lKlcoaSkscz1lKnEoaSkscj1xKHQpLG89UHQqci1DdCpzLGE9Q3Qqbi1FdCpyLGM9RXQqcy1QdCpuLGw9X2EobyxhLGMpLGg9RGUobCksdT1sJiYtaC9sO0JhLmFkZCh1Km8pLEZhLmFkZCh1KmEpLElhLmFkZCh1KmMpLHlyKz1oLHdyKz1oKihFdCsoRXQ9bikpLGJyKz1oKihQdCsoUHQ9cykpLE1yKz1oKihDdCsoQ3Q9cikpLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiB4aChpKXtxaT15cj1tcj1ncj14cj13cj1icj1Ncj0wLEJhPW5ldyBMZSxGYT1uZXcgTGUsSWE9bmV3IExlLGxyKGkscGUpO3ZhciB0PStCYSxlPStGYSxuPStJYSxzPV9hKHQsZSxuKTtyZXR1cm4gczxvciYmKHQ9d3IsZT1icixuPU1yLHlyPEsmJih0PW1yLGU9Z3Isbj14cikscz1fYSh0LGUsbiksczxvcik/W05hTixOYU5dOltyZShlLHQpKmh0LERlKG4vcykqaHRdfWZ1bmN0aW9uIE5hKGksdCl7ZnVuY3Rpb24gZShuLHMpe3JldHVybiBuPWkobixzKSx0KG5bMF0sblsxXSl9cmV0dXJuIGkuaW52ZXJ0JiZ0LmludmVydCYmKGUuaW52ZXJ0PWZ1bmN0aW9uKG4scyl7cmV0dXJuIG49dC5pbnZlcnQobixzKSxuJiZpLmludmVydChuWzBdLG5bMV0pfSksZX1mdW5jdGlvbiBSYShpLHQpe3JldHVybiB0dChpKT5YJiYoaS09TWF0aC5yb3VuZChpL1J0KSpSdCksW2ksdF19UmEuaW52ZXJ0PVJhO2Z1bmN0aW9uIHdoKGksdCxlKXtyZXR1cm4oaSU9UnQpP3R8fGU/TmEoTWgoaSksQWgodCxlKSk6TWgoaSk6dHx8ZT9BaCh0LGUpOlJhfWZ1bmN0aW9uIGJoKGkpe3JldHVybiBmdW5jdGlvbih0LGUpe3JldHVybiB0Kz1pLHR0KHQpPlgmJih0LT1NYXRoLnJvdW5kKHQvUnQpKlJ0KSxbdCxlXX19ZnVuY3Rpb24gTWgoaSl7dmFyIHQ9YmgoaSk7cmV0dXJuIHQuaW52ZXJ0PWJoKC1pKSx0fWZ1bmN0aW9uIEFoKGksdCl7dmFyIGU9VyhpKSxuPXEoaSkscz1XKHQpLHI9cSh0KTtmdW5jdGlvbiBvKGEsYyl7dmFyIGw9VyhjKSxoPVcoYSkqbCx1PXEoYSkqbCxmPXEoYyksZD1mKmUraCpuO3JldHVybltyZSh1KnMtZCpyLGgqZS1mKm4pLERlKGQqcyt1KnIpXX1yZXR1cm4gby5pbnZlcnQ9ZnVuY3Rpb24oYSxjKXt2YXIgbD1XKGMpLGg9VyhhKSpsLHU9cShhKSpsLGY9cShjKSxkPWYqcy11KnI7cmV0dXJuW3JlKHUqcytmKnIsaCplK2QqbiksRGUoZCplLWgqbildfSxvfWZ1bmN0aW9uIFNoKGkpe2k9d2goaVswXSpILGlbMV0qSCxpLmxlbmd0aD4yP2lbMl0qSDowKTtmdW5jdGlvbiB0KGUpe3JldHVybiBlPWkoZVswXSpILGVbMV0qSCksZVswXSo9aHQsZVsxXSo9aHQsZX1yZXR1cm4gdC5pbnZlcnQ9ZnVuY3Rpb24oZSl7cmV0dXJuIGU9aS5pbnZlcnQoZVswXSpILGVbMV0qSCksZVswXSo9aHQsZVsxXSo9aHQsZX0sdH1mdW5jdGlvbiBfcChpLHQsZSxuLHMscil7aWYoZSl7dmFyIG89Vyh0KSxhPXEodCksYz1uKmU7cz09bnVsbD8ocz10K24qUnQscj10LWMvMik6KHM9X2gobyxzKSxyPV9oKG8sciksKG4+MD9zPHI6cz5yKSYmKHMrPW4qUnQpKTtmb3IodmFyIGwsaD1zO24+MD9oPnI6aDxyO2gtPWMpbD11cihbbywtYSpXKGgpLC1hKnEoaCldKSxpLnBvaW50KGxbMF0sbFsxXSl9fWZ1bmN0aW9uIF9oKGksdCl7dD1Tbih0KSx0WzBdLT1pLHByKHQpO3ZhciBlPWZwKC10WzFdKTtyZXR1cm4oKC10WzJdPDA/LWU6ZSkrUnQtSyklUnR9ZnVuY3Rpb24gdmgoKXt2YXIgaT1bXSx0O3JldHVybntwb2ludDpmdW5jdGlvbihlLG4scyl7dC5wdXNoKFtlLG4sc10pfSxsaW5lU3RhcnQ6ZnVuY3Rpb24oKXtpLnB1c2godD1bXSl9LGxpbmVFbmQ6X3QscmVqb2luOmZ1bmN0aW9uKCl7aS5sZW5ndGg+MSYmaS5wdXNoKGkucG9wKCkuY29uY2F0KGkuc2hpZnQoKSkpfSxyZXN1bHQ6ZnVuY3Rpb24oKXt2YXIgZT1pO3JldHVybiBpPVtdLHQ9bnVsbCxlfX19ZnVuY3Rpb24gQXIoaSx0KXtyZXR1cm4gdHQoaVswXS10WzBdKTxLJiZ0dChpWzFdLXRbMV0pPEt9ZnVuY3Rpb24gU3IoaSx0LGUsbil7dGhpcy54PWksdGhpcy56PXQsdGhpcy5vPWUsdGhpcy5lPW4sdGhpcy52PSExLHRoaXMubj10aGlzLnA9bnVsbH1mdW5jdGlvbiB6aChpLHQsZSxuLHMpe3ZhciByPVtdLG89W10sYSxjO2lmKGkuZm9yRWFjaChmdW5jdGlvbihwKXtpZighKCh5PXAubGVuZ3RoLTEpPD0wKSl7dmFyIHksbT1wWzBdLGc9cFt5XSxiO2lmKEFyKG0sZykpe2lmKCFtWzJdJiYhZ1syXSl7Zm9yKHMubGluZVN0YXJ0KCksYT0wO2E8eTsrK2Epcy5wb2ludCgobT1wW2FdKVswXSxtWzFdKTtzLmxpbmVFbmQoKTtyZXR1cm59Z1swXSs9MipLfXIucHVzaChiPW5ldyBTcihtLHAsbnVsbCwhMCkpLG8ucHVzaChiLm89bmV3IFNyKG0sbnVsbCxiLCExKSksci5wdXNoKGI9bmV3IFNyKGcscCxudWxsLCExKSksby5wdXNoKGIubz1uZXcgU3IoZyxudWxsLGIsITApKX19KSwhIXIubGVuZ3RoKXtmb3Ioby5zb3J0KHQpLFRoKHIpLFRoKG8pLGE9MCxjPW8ubGVuZ3RoO2E8YzsrK2Epb1thXS5lPWU9IWU7Zm9yKHZhciBsPXJbMF0saCx1Ozspe2Zvcih2YXIgZj1sLGQ9ITA7Zi52OylpZigoZj1mLm4pPT09bClyZXR1cm47aD1mLnoscy5saW5lU3RhcnQoKTtkb3tpZihmLnY9Zi5vLnY9ITAsZi5lKXtpZihkKWZvcihhPTAsYz1oLmxlbmd0aDthPGM7KythKXMucG9pbnQoKHU9aFthXSlbMF0sdVsxXSk7ZWxzZSBuKGYueCxmLm4ueCwxLHMpO2Y9Zi5ufWVsc2V7aWYoZClmb3IoaD1mLnAueixhPWgubGVuZ3RoLTE7YT49MDstLWEpcy5wb2ludCgodT1oW2FdKVswXSx1WzFdKTtlbHNlIG4oZi54LGYucC54LC0xLHMpO2Y9Zi5wfWY9Zi5vLGg9Zi56LGQ9IWR9d2hpbGUoIWYudik7cy5saW5lRW5kKCl9fX1mdW5jdGlvbiBUaChpKXtpZih0PWkubGVuZ3RoKXtmb3IodmFyIHQsZT0wLG49aVswXSxzOysrZTx0OyluLm49cz1pW2VdLHMucD1uLG49cztuLm49cz1pWzBdLHMucD1ufX1mdW5jdGlvbiBMYShpKXtyZXR1cm4gdHQoaVswXSk8PVg/aVswXTpocChpWzBdKSooKHR0KGlbMF0pK1gpJVJ0LVgpfWZ1bmN0aW9uIEVoKGksdCl7dmFyIGU9TGEodCksbj10WzFdLHM9cShuKSxyPVtxKGUpLC1XKGUpLDBdLG89MCxhPTAsYz1uZXcgTGU7cz09PTE/bj1OdCtLOnM9PT0tMSYmKG49LU50LUspO2Zvcih2YXIgbD0wLGg9aS5sZW5ndGg7bDxoOysrbClpZihmPSh1PWlbbF0pLmxlbmd0aClmb3IodmFyIHUsZixkPXVbZi0xXSxwPUxhKGQpLHk9ZFsxXS8yK2FyLG09cSh5KSxnPVcoeSksYj0wO2I8ZjsrK2IscD14LG09QSxnPVMsZD13KXt2YXIgdz11W2JdLHg9TGEodyksTT13WzFdLzIrYXIsQT1xKE0pLFM9VyhNKSxfPXgtcCxFPV8+PTA/MTotMSx6PUUqXyx2PXo+WCxDPW0qQTtpZihjLmFkZChyZShDKkUqcSh6KSxnKlMrQypXKHopKSksbys9dj9fK0UqUnQ6Xyx2XnA+PWVeeD49ZSl7dmFyIFA9bmkoU24oZCksU24odykpO3ByKFApO3ZhciBGPW5pKHIsUCk7cHIoRik7dmFyIEI9KHZeXz49MD8tMToxKSpEZShGWzJdKTsobj5CfHxuPT09QiYmKFBbMF18fFBbMV0pKSYmKGErPXZeXz49MD8xOi0xKX19cmV0dXJuKG88LUt8fG88SyYmYzwtb3IpXmEmMX1mdW5jdGlvbiBQaChpLHQsZSxuKXtyZXR1cm4gZnVuY3Rpb24ocyl7dmFyIHI9dChzKSxvPXZoKCksYT10KG8pLGM9ITEsbCxoLHUsZj17cG9pbnQ6ZCxsaW5lU3RhcnQ6eSxsaW5lRW5kOm0scG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7Zi5wb2ludD1nLGYubGluZVN0YXJ0PWIsZi5saW5lRW5kPXcsaD1bXSxsPVtdfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7Zi5wb2ludD1kLGYubGluZVN0YXJ0PXksZi5saW5lRW5kPW0saD1WaShoKTt2YXIgeD1FaChsLG4pO2gubGVuZ3RoPyhjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSx6aChoLHpwLHgsZSxzKSk6eCYmKGN8fChzLnBvbHlnb25TdGFydCgpLGM9ITApLHMubGluZVN0YXJ0KCksZShudWxsLG51bGwsMSxzKSxzLmxpbmVFbmQoKSksYyYmKHMucG9seWdvbkVuZCgpLGM9ITEpLGg9bD1udWxsfSxzcGhlcmU6ZnVuY3Rpb24oKXtzLnBvbHlnb25TdGFydCgpLHMubGluZVN0YXJ0KCksZShudWxsLG51bGwsMSxzKSxzLmxpbmVFbmQoKSxzLnBvbHlnb25FbmQoKX19O2Z1bmN0aW9uIGQoeCxNKXtpKHgsTSkmJnMucG9pbnQoeCxNKX1mdW5jdGlvbiBwKHgsTSl7ci5wb2ludCh4LE0pfWZ1bmN0aW9uIHkoKXtmLnBvaW50PXAsci5saW5lU3RhcnQoKX1mdW5jdGlvbiBtKCl7Zi5wb2ludD1kLHIubGluZUVuZCgpfWZ1bmN0aW9uIGcoeCxNKXt1LnB1c2goW3gsTV0pLGEucG9pbnQoeCxNKX1mdW5jdGlvbiBiKCl7YS5saW5lU3RhcnQoKSx1PVtdfWZ1bmN0aW9uIHcoKXtnKHVbMF1bMF0sdVswXVsxXSksYS5saW5lRW5kKCk7dmFyIHg9YS5jbGVhbigpLE09by5yZXN1bHQoKSxBLFM9TS5sZW5ndGgsXyxFLHo7aWYodS5wb3AoKSxsLnB1c2godSksdT1udWxsLCEhUyl7aWYoeCYxKXtpZihFPU1bMF0sKF89RS5sZW5ndGgtMSk+MCl7Zm9yKGN8fChzLnBvbHlnb25TdGFydCgpLGM9ITApLHMubGluZVN0YXJ0KCksQT0wO0E8XzsrK0Epcy5wb2ludCgoej1FW0FdKVswXSx6WzFdKTtzLmxpbmVFbmQoKX1yZXR1cm59Uz4xJiZ4JjImJk0ucHVzaChNLnBvcCgpLmNvbmNhdChNLnNoaWZ0KCkpKSxoLnB1c2goTS5maWx0ZXIodnApKX19cmV0dXJuIGZ9fWZ1bmN0aW9uIHZwKGkpe3JldHVybiBpLmxlbmd0aD4xfWZ1bmN0aW9uIHpwKGksdCl7cmV0dXJuKChpPWkueClbMF08MD9pWzFdLU50LUs6TnQtaVsxXSktKCh0PXQueClbMF08MD90WzFdLU50LUs6TnQtdFsxXSl9dmFyIENoPVBoKGZ1bmN0aW9uKCl7cmV0dXJuITB9LFRwLFBwLFstWCwtTnRdKTtmdW5jdGlvbiBUcChpKXt2YXIgdD1OYU4sZT1OYU4sbj1OYU4scztyZXR1cm57bGluZVN0YXJ0OmZ1bmN0aW9uKCl7aS5saW5lU3RhcnQoKSxzPTF9LHBvaW50OmZ1bmN0aW9uKHIsbyl7dmFyIGE9cj4wP1g6LVgsYz10dChyLXQpO3R0KGMtWCk8Sz8oaS5wb2ludCh0LGU9KGUrbykvMj4wP050Oi1OdCksaS5wb2ludChuLGUpLGkubGluZUVuZCgpLGkubGluZVN0YXJ0KCksaS5wb2ludChhLGUpLGkucG9pbnQocixlKSxzPTApOm4hPT1hJiZjPj1YJiYodHQodC1uKTxLJiYodC09bipLKSx0dChyLWEpPEsmJihyLT1hKkspLGU9RXAodCxlLHIsbyksaS5wb2ludChuLGUpLGkubGluZUVuZCgpLGkubGluZVN0YXJ0KCksaS5wb2ludChhLGUpLHM9MCksaS5wb2ludCh0PXIsZT1vKSxuPWF9LGxpbmVFbmQ6ZnVuY3Rpb24oKXtpLmxpbmVFbmQoKSx0PWU9TmFOfSxjbGVhbjpmdW5jdGlvbigpe3JldHVybiAyLXN9fX1mdW5jdGlvbiBFcChpLHQsZSxuKXt2YXIgcyxyLG89cShpLWUpO3JldHVybiB0dChvKT5LP1NhKChxKHQpKihyPVcobikpKnEoZSktcShuKSoocz1XKHQpKSpxKGkpKS8ocypyKm8pKToodCtuKS8yfWZ1bmN0aW9uIFBwKGksdCxlLG4pe3ZhciBzO2lmKGk9PW51bGwpcz1lKk50LG4ucG9pbnQoLVgscyksbi5wb2ludCgwLHMpLG4ucG9pbnQoWCxzKSxuLnBvaW50KFgsMCksbi5wb2ludChYLC1zKSxuLnBvaW50KDAsLXMpLG4ucG9pbnQoLVgsLXMpLG4ucG9pbnQoLVgsMCksbi5wb2ludCgtWCxzKTtlbHNlIGlmKHR0KGlbMF0tdFswXSk+Syl7dmFyIHI9aVswXTx0WzBdP1g6LVg7cz1lKnIvMixuLnBvaW50KC1yLHMpLG4ucG9pbnQoMCxzKSxuLnBvaW50KHIscyl9ZWxzZSBuLnBvaW50KHRbMF0sdFsxXSl9ZnVuY3Rpb24gQ3AoaSl7dmFyIHQ9VyhpKSxlPTIqSCxuPXQ+MCxzPXR0KHQpPks7ZnVuY3Rpb24gcihoLHUsZixkKXtfcChkLGksZSxmLGgsdSl9ZnVuY3Rpb24gbyhoLHUpe3JldHVybiBXKGgpKlcodSk+dH1mdW5jdGlvbiBhKGgpe3ZhciB1LGYsZCxwLHk7cmV0dXJue2xpbmVTdGFydDpmdW5jdGlvbigpe3A9ZD0hMSx5PTF9LHBvaW50OmZ1bmN0aW9uKG0sZyl7dmFyIGI9W20sZ10sdyx4PW8obSxnKSxNPW4/eD8wOmwobSxnKTp4P2wobSsobTwwP1g6LVgpLGcpOjA7aWYoIXUmJihwPWQ9eCkmJmgubGluZVN0YXJ0KCkseCE9PWQmJih3PWModSxiKSwoIXd8fEFyKHUsdyl8fEFyKGIsdykpJiYoYlsyXT0xKSkseCE9PWQpeT0wLHg/KGgubGluZVN0YXJ0KCksdz1jKGIsdSksaC5wb2ludCh3WzBdLHdbMV0pKToodz1jKHUsYiksaC5wb2ludCh3WzBdLHdbMV0sMiksaC5saW5lRW5kKCkpLHU9dztlbHNlIGlmKHMmJnUmJm5eeCl7dmFyIEE7IShNJmYpJiYoQT1jKGIsdSwhMCkpJiYoeT0wLG4/KGgubGluZVN0YXJ0KCksaC5wb2ludChBWzBdWzBdLEFbMF1bMV0pLGgucG9pbnQoQVsxXVswXSxBWzFdWzFdKSxoLmxpbmVFbmQoKSk6KGgucG9pbnQoQVsxXVswXSxBWzFdWzFdKSxoLmxpbmVFbmQoKSxoLmxpbmVTdGFydCgpLGgucG9pbnQoQVswXVswXSxBWzBdWzFdLDMpKSl9eCYmKCF1fHwhQXIodSxiKSkmJmgucG9pbnQoYlswXSxiWzFdKSx1PWIsZD14LGY9TX0sbGluZUVuZDpmdW5jdGlvbigpe2QmJmgubGluZUVuZCgpLHU9bnVsbH0sY2xlYW46ZnVuY3Rpb24oKXtyZXR1cm4geXwocCYmZCk8PDF9fX1mdW5jdGlvbiBjKGgsdSxmKXt2YXIgZD1TbihoKSxwPVNuKHUpLHk9WzEsMCwwXSxtPW5pKGQscCksZz1mcihtLG0pLGI9bVswXSx3PWctYipiO2lmKCF3KXJldHVybiFmJiZoO3ZhciB4PXQqZy93LE09LXQqYi93LEE9bmkoeSxtKSxTPWRyKHkseCksXz1kcihtLE0pO1BhKFMsXyk7dmFyIEU9QSx6PWZyKFMsRSksdj1mcihFLEUpLEM9eip6LXYqKGZyKFMsUyktMSk7aWYoIShDPDApKXt2YXIgUD1PZShDKSxGPWRyKEUsKC16LVApL3YpO2lmKFBhKEYsUyksRj11cihGKSwhZilyZXR1cm4gRjt2YXIgQj1oWzBdLEk9dVswXSxrPWhbMV0sRD11WzFdLFU7STxCJiYoVT1CLEI9SSxJPVUpO3ZhciBqPUktQixkdD10dChqLVgpPEssRHQ9ZHR8fGo8SztpZighZHQmJkQ8ayYmKFU9ayxrPUQsRD1VKSxEdD9kdD9rK0Q+MF5GWzFdPCh0dChGWzBdLUIpPEs/azpEKTprPD1GWzFdJiZGWzFdPD1EOmo+WF4oQjw9RlswXSYmRlswXTw9SSkpe3ZhciBHdD1kcihFLCgteitQKS92KTtyZXR1cm4gUGEoR3QsUyksW0YsdXIoR3QpXX19fWZ1bmN0aW9uIGwoaCx1KXt2YXIgZj1uP2k6WC1pLGQ9MDtyZXR1cm4gaDwtZj9kfD0xOmg+ZiYmKGR8PTIpLHU8LWY/ZHw9NDp1PmYmJihkfD04KSxkfXJldHVybiBQaChvLGEscixuP1swLC1pXTpbLVgsaS1YXSl9ZnVuY3Rpb24gQnAoaSx0LGUsbixzLHIpe3ZhciBvPWlbMF0sYT1pWzFdLGM9dFswXSxsPXRbMV0saD0wLHU9MSxmPWMtbyxkPWwtYSxwO2lmKHA9ZS1vLCEoIWYmJnA+MCkpe2lmKHAvPWYsZjwwKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9ZWxzZSBpZihmPjApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1pZihwPXMtbywhKCFmJiZwPDApKXtpZihwLz1mLGY8MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWVsc2UgaWYoZj4wKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9aWYocD1uLWEsISghZCYmcD4wKSl7aWYocC89ZCxkPDApe2lmKHA8aClyZXR1cm47cDx1JiYodT1wKX1lbHNlIGlmKGQ+MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWlmKHA9ci1hLCEoIWQmJnA8MCkpe2lmKHAvPWQsZDwwKXtpZihwPnUpcmV0dXJuO3A+aCYmKGg9cCl9ZWxzZSBpZihkPjApe2lmKHA8aClyZXR1cm47cDx1JiYodT1wKX1yZXR1cm4gaD4wJiYoaVswXT1vK2gqZixpWzFdPWEraCpkKSx1PDEmJih0WzBdPW8rdSpmLHRbMV09YSt1KmQpLCEwfX19fX12YXIgV2k9MWU5LF9yPS1XaTtmdW5jdGlvbiBGcChpLHQsZSxuKXtmdW5jdGlvbiBzKGwsaCl7cmV0dXJuIGk8PWwmJmw8PWUmJnQ8PWgmJmg8PW59ZnVuY3Rpb24gcihsLGgsdSxmKXt2YXIgZD0wLHA9MDtpZihsPT1udWxsfHwoZD1vKGwsdSkpIT09KHA9byhoLHUpKXx8YyhsLGgpPDBedT4wKWRvIGYucG9pbnQoZD09PTB8fGQ9PT0zP2k6ZSxkPjE/bjp0KTt3aGlsZSgoZD0oZCt1KzQpJTQpIT09cCk7ZWxzZSBmLnBvaW50KGhbMF0saFsxXSl9ZnVuY3Rpb24gbyhsLGgpe3JldHVybiB0dChsWzBdLWkpPEs/aD4wPzA6Mzp0dChsWzBdLWUpPEs/aD4wPzI6MTp0dChsWzFdLXQpPEs/aD4wPzE6MDpoPjA/MzoyfWZ1bmN0aW9uIGEobCxoKXtyZXR1cm4gYyhsLngsaC54KX1mdW5jdGlvbiBjKGwsaCl7dmFyIHU9byhsLDEpLGY9byhoLDEpO3JldHVybiB1IT09Zj91LWY6dT09PTA/aFsxXS1sWzFdOnU9PT0xP2xbMF0taFswXTp1PT09Mj9sWzFdLWhbMV06aFswXS1sWzBdfXJldHVybiBmdW5jdGlvbihsKXt2YXIgaD1sLHU9dmgoKSxmLGQscCx5LG0sZyxiLHcseCxNLEEsUz17cG9pbnQ6XyxsaW5lU3RhcnQ6QyxsaW5lRW5kOlAscG9seWdvblN0YXJ0OnoscG9seWdvbkVuZDp2fTtmdW5jdGlvbiBfKEIsSSl7cyhCLEkpJiZoLnBvaW50KEIsSSl9ZnVuY3Rpb24gRSgpe2Zvcih2YXIgQj0wLEk9MCxrPWQubGVuZ3RoO0k8azsrK0kpZm9yKHZhciBEPWRbSV0sVT0xLGo9RC5sZW5ndGgsZHQ9RFswXSxEdCxHdCxadD1kdFswXSxtZT1kdFsxXTtVPGo7KytVKUR0PVp0LEd0PW1lLGR0PURbVV0sWnQ9ZHRbMF0sbWU9ZHRbMV0sR3Q8PW4/bWU+biYmKFp0LUR0KSoobi1HdCk+KG1lLUd0KSooaS1EdCkmJisrQjptZTw9biYmKFp0LUR0KSoobi1HdCk8KG1lLUd0KSooaS1EdCkmJi0tQjtyZXR1cm4gQn1mdW5jdGlvbiB6KCl7aD11LGY9W10sZD1bXSxBPSEwfWZ1bmN0aW9uIHYoKXt2YXIgQj1FKCksST1BJiZCLGs9KGY9VmkoZikpLmxlbmd0aDsoSXx8aykmJihsLnBvbHlnb25TdGFydCgpLEkmJihsLmxpbmVTdGFydCgpLHIobnVsbCxudWxsLDEsbCksbC5saW5lRW5kKCkpLGsmJnpoKGYsYSxCLHIsbCksbC5wb2x5Z29uRW5kKCkpLGg9bCxmPWQ9cD1udWxsfWZ1bmN0aW9uIEMoKXtTLnBvaW50PUYsZCYmZC5wdXNoKHA9W10pLE09ITAseD0hMSxiPXc9TmFOfWZ1bmN0aW9uIFAoKXtmJiYoRih5LG0pLGcmJngmJnUucmVqb2luKCksZi5wdXNoKHUucmVzdWx0KCkpKSxTLnBvaW50PV8seCYmaC5saW5lRW5kKCl9ZnVuY3Rpb24gRihCLEkpe3ZhciBrPXMoQixJKTtpZihkJiZwLnB1c2goW0IsSV0pLE0peT1CLG09SSxnPWssTT0hMSxrJiYoaC5saW5lU3RhcnQoKSxoLnBvaW50KEIsSSkpO2Vsc2UgaWYoayYmeCloLnBvaW50KEIsSSk7ZWxzZXt2YXIgRD1bYj1NYXRoLm1heChfcixNYXRoLm1pbihXaSxiKSksdz1NYXRoLm1heChfcixNYXRoLm1pbihXaSx3KSldLFU9W0I9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksQikpLEk9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksSSkpXTtCcChELFUsaSx0LGUsbik/KHh8fChoLmxpbmVTdGFydCgpLGgucG9pbnQoRFswXSxEWzFdKSksaC5wb2ludChVWzBdLFVbMV0pLGt8fGgubGluZUVuZCgpLEE9ITEpOmsmJihoLmxpbmVTdGFydCgpLGgucG9pbnQoQixJKSxBPSExKX1iPUIsdz1JLHg9a31yZXR1cm4gU319dmFyIE9hLERhLHZyLHpyLHNpPXtzcGhlcmU6X3QscG9pbnQ6X3QsbGluZVN0YXJ0OklwLGxpbmVFbmQ6X3QscG9seWdvblN0YXJ0Ol90LHBvbHlnb25FbmQ6X3R9O2Z1bmN0aW9uIElwKCl7c2kucG9pbnQ9TnAsc2kubGluZUVuZD1rcH1mdW5jdGlvbiBrcCgpe3NpLnBvaW50PXNpLmxpbmVFbmQ9X3R9ZnVuY3Rpb24gTnAoaSx0KXtpKj1ILHQqPUgsRGE9aSx2cj1xKHQpLHpyPVcodCksc2kucG9pbnQ9UnB9ZnVuY3Rpb24gUnAoaSx0KXtpKj1ILHQqPUg7dmFyIGU9cSh0KSxuPVcodCkscz10dChpLURhKSxyPVcocyksbz1xKHMpLGE9bipvLGM9enIqZS12cipuKnIsbD12ciplK3pyKm4qcjtPYS5hZGQocmUoT2UoYSphK2MqYyksbCkpLERhPWksdnI9ZSx6cj1ufWZ1bmN0aW9uIExwKGkpe3JldHVybiBPYT1uZXcgTGUsbHIoaSxzaSksK09hfXZhciAkYT1bbnVsbCxudWxsXSxPcD17dHlwZToiTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6JGF9O2Z1bmN0aW9uIHJpKGksdCl7cmV0dXJuICRhWzBdPWksJGFbMV09dCxMcChPcCl9dmFyIEJoPXtGZWF0dXJlOmZ1bmN0aW9uKGksdCl7cmV0dXJuIFRyKGkuZ2VvbWV0cnksdCl9LEZlYXR1cmVDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZmVhdHVyZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihUcihlW25dLmdlb21ldHJ5LHQpKXJldHVybiEwO3JldHVybiExfX0sRmg9e1NwaGVyZTpmdW5jdGlvbigpe3JldHVybiEwfSxQb2ludDpmdW5jdGlvbihpLHQpe3JldHVybiBJaChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aVBvaW50OmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihJaChlW25dLHQpKXJldHVybiEwO3JldHVybiExfSxMaW5lU3RyaW5nOmZ1bmN0aW9uKGksdCl7cmV0dXJuIGtoKGkuY29vcmRpbmF0ZXMsdCl9LE11bHRpTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoa2goZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX0sUG9seWdvbjpmdW5jdGlvbihpLHQpe3JldHVybiBOaChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aVBvbHlnb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWlmKE5oKGVbbl0sdCkpcmV0dXJuITA7cmV0dXJuITF9LEdlb21ldHJ5Q29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmdlb21ldHJpZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihUcihlW25dLHQpKXJldHVybiEwO3JldHVybiExfX07ZnVuY3Rpb24gVHIoaSx0KXtyZXR1cm4gaSYmRmguaGFzT3duUHJvcGVydHkoaS50eXBlKT9GaFtpLnR5cGVdKGksdCk6ITF9ZnVuY3Rpb24gSWgoaSx0KXtyZXR1cm4gcmkoaSx0KT09PTB9ZnVuY3Rpb24ga2goaSx0KXtmb3IodmFyIGUsbixzLHI9MCxvPWkubGVuZ3RoO3I8bztyKyspe2lmKG49cmkoaVtyXSx0KSxuPT09MHx8cj4wJiYocz1yaShpW3JdLGlbci0xXSkscz4wJiZlPD1zJiZuPD1zJiYoZStuLXMpKigxLU1hdGgucG93KChlLW4pL3MsMikpPG9yKnMpKXJldHVybiEwO2U9bn1yZXR1cm4hMX1mdW5jdGlvbiBOaChpLHQpe3JldHVybiEhRWgoaS5tYXAoRHApLFJoKHQpKX1mdW5jdGlvbiBEcChpKXtyZXR1cm4gaT1pLm1hcChSaCksaS5wb3AoKSxpfWZ1bmN0aW9uIFJoKGkpe3JldHVybltpWzBdKkgsaVsxXSpIXX1mdW5jdGlvbiAkcChpLHQpe3JldHVybihpJiZCaC5oYXNPd25Qcm9wZXJ0eShpLnR5cGUpP0JoW2kudHlwZV06VHIpKGksdCl9ZnVuY3Rpb24gVnAoaSx0KXt2YXIgZT1pWzBdKkgsbj1pWzFdKkgscz10WzBdKkgscj10WzFdKkgsbz1XKG4pLGE9cShuKSxjPVcociksbD1xKHIpLGg9bypXKGUpLHU9bypxKGUpLGY9YypXKHMpLGQ9YypxKHMpLHA9MipEZShPZShqbChyLW4pK28qYypqbChzLWUpKSkseT1xKHApLG09cD9mdW5jdGlvbihnKXt2YXIgYj1xKGcqPXApL3ksdz1xKHAtZykveSx4PXcqaCtiKmYsTT13KnUrYipkLEE9dyphK2IqbDtyZXR1cm5bcmUoTSx4KSpodCxyZShBLE9lKHgqeCtNKk0pKSpodF19OmZ1bmN0aW9uKCl7cmV0dXJuW2UqaHQsbipodF19O3JldHVybiBtLmRpc3RhbmNlPXAsbX12YXIgTGg9aT0+aSxvaT0xLzAsRXI9b2ksR2k9LW9pLFByPUdpLE9oPXtwb2ludDpVcCxsaW5lU3RhcnQ6X3QsbGluZUVuZDpfdCxwb2x5Z29uU3RhcnQ6X3QscG9seWdvbkVuZDpfdCxyZXN1bHQ6ZnVuY3Rpb24oKXt2YXIgaT1bW29pLEVyXSxbR2ksUHJdXTtyZXR1cm4gR2k9UHI9LShFcj1vaT0xLzApLGl9fTtmdW5jdGlvbiBVcChpLHQpe2k8b2kmJihvaT1pKSxpPkdpJiYoR2k9aSksdDxFciYmKEVyPXQpLHQ+UHImJihQcj10KX1mdW5jdGlvbiBWYShpKXtyZXR1cm4gZnVuY3Rpb24odCl7dmFyIGU9bmV3IFVhO2Zvcih2YXIgbiBpbiBpKWVbbl09aVtuXTtyZXR1cm4gZS5zdHJlYW09dCxlfX1mdW5jdGlvbiBVYSgpe31VYS5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlVhLHBvaW50OmZ1bmN0aW9uKGksdCl7dGhpcy5zdHJlYW0ucG9pbnQoaSx0KX0sc3BoZXJlOmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0uc3BoZXJlKCl9LGxpbmVTdGFydDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLmxpbmVTdGFydCgpfSxsaW5lRW5kOmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0ubGluZUVuZCgpfSxwb2x5Z29uU3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5wb2x5Z29uU3RhcnQoKX0scG9seWdvbkVuZDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLnBvbHlnb25FbmQoKX19O2Z1bmN0aW9uIHFhKGksdCxlKXt2YXIgbj1pLmNsaXBFeHRlbnQmJmkuY2xpcEV4dGVudCgpO3JldHVybiBpLnNjYWxlKDE1MCkudHJhbnNsYXRlKFswLDBdKSxuIT1udWxsJiZpLmNsaXBFeHRlbnQobnVsbCksbHIoZSxpLnN0cmVhbShPaCkpLHQoT2gucmVzdWx0KCkpLG4hPW51bGwmJmkuY2xpcEV4dGVudChuKSxpfWZ1bmN0aW9uIERoKGksdCxlKXtyZXR1cm4gcWEoaSxmdW5jdGlvbihuKXt2YXIgcz10WzFdWzBdLXRbMF1bMF0scj10WzFdWzFdLXRbMF1bMV0sbz1NYXRoLm1pbihzLyhuWzFdWzBdLW5bMF1bMF0pLHIvKG5bMV1bMV0tblswXVsxXSkpLGE9K3RbMF1bMF0rKHMtbyooblsxXVswXStuWzBdWzBdKSkvMixjPSt0WzBdWzFdKyhyLW8qKG5bMV1bMV0rblswXVsxXSkpLzI7aS5zY2FsZSgxNTAqbykudHJhbnNsYXRlKFthLGNdKX0sZSl9ZnVuY3Rpb24gcXAoaSx0LGUpe3JldHVybiBEaChpLFtbMCwwXSx0XSxlKX1mdW5jdGlvbiBIcChpLHQsZSl7cmV0dXJuIHFhKGksZnVuY3Rpb24obil7dmFyIHM9K3Qscj1zLyhuWzFdWzBdLW5bMF1bMF0pLG89KHMtciooblsxXVswXStuWzBdWzBdKSkvMixhPS1yKm5bMF1bMV07aS5zY2FsZSgxNTAqcikudHJhbnNsYXRlKFtvLGFdKX0sZSl9ZnVuY3Rpb24gV3AoaSx0LGUpe3JldHVybiBxYShpLGZ1bmN0aW9uKG4pe3ZhciBzPSt0LHI9cy8oblsxXVsxXS1uWzBdWzFdKSxvPS1yKm5bMF1bMF0sYT0ocy1yKihuWzFdWzFdK25bMF1bMV0pKS8yO2kuc2NhbGUoMTUwKnIpLnRyYW5zbGF0ZShbbyxhXSl9LGUpfXZhciAkaD0xNixHcD1XKDMwKkgpO2Z1bmN0aW9uIFZoKGksdCl7cmV0dXJuK3Q/WHAoaSx0KTpacChpKX1mdW5jdGlvbiBacChpKXtyZXR1cm4gVmEoe3BvaW50OmZ1bmN0aW9uKHQsZSl7dD1pKHQsZSksdGhpcy5zdHJlYW0ucG9pbnQodFswXSx0WzFdKX19KX1mdW5jdGlvbiBYcChpLHQpe2Z1bmN0aW9uIGUobixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXt2YXIgZz1sLW4sYj1oLXMsdz1nKmcrYipiO2lmKHc+NCp0JiZ5LS0pe3ZhciB4PW8rZixNPWErZCxBPWMrcCxTPU9lKHgqeCtNKk0rQSpBKSxfPURlKEEvPVMpLEU9dHQodHQoQSktMSk8S3x8dHQoci11KTxLPyhyK3UpLzI6cmUoTSx4KSx6PWkoRSxfKSx2PXpbMF0sQz16WzFdLFA9di1uLEY9Qy1zLEI9YipQLWcqRjsoQipCL3c+dHx8dHQoKGcqUCtiKkYpL3ctLjUpPi4zfHxvKmYrYSpkK2MqcDxHcCkmJihlKG4scyxyLG8sYSxjLHYsQyxFLHgvPVMsTS89UyxBLHksbSksbS5wb2ludCh2LEMpLGUodixDLEUseCxNLEEsbCxoLHUsZixkLHAseSxtKSl9fXJldHVybiBmdW5jdGlvbihuKXt2YXIgcyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbT17cG9pbnQ6ZyxsaW5lU3RhcnQ6YixsaW5lRW5kOngscG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7bi5wb2x5Z29uU3RhcnQoKSxtLmxpbmVTdGFydD1NfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7bi5wb2x5Z29uRW5kKCksbS5saW5lU3RhcnQ9Yn19O2Z1bmN0aW9uIGcoXyxFKXtfPWkoXyxFKSxuLnBvaW50KF9bMF0sX1sxXSl9ZnVuY3Rpb24gYigpe3U9TmFOLG0ucG9pbnQ9dyxuLmxpbmVTdGFydCgpfWZ1bmN0aW9uIHcoXyxFKXt2YXIgej1TbihbXyxFXSksdj1pKF8sRSk7ZSh1LGYsaCxkLHAseSx1PXZbMF0sZj12WzFdLGg9XyxkPXpbMF0scD16WzFdLHk9elsyXSwkaCxuKSxuLnBvaW50KHUsZil9ZnVuY3Rpb24geCgpe20ucG9pbnQ9ZyxuLmxpbmVFbmQoKX1mdW5jdGlvbiBNKCl7YigpLG0ucG9pbnQ9QSxtLmxpbmVFbmQ9U31mdW5jdGlvbiBBKF8sRSl7dyhzPV8sRSkscj11LG89ZixhPWQsYz1wLGw9eSxtLnBvaW50PXd9ZnVuY3Rpb24gUygpe2UodSxmLGgsZCxwLHkscixvLHMsYSxjLGwsJGgsbiksbS5saW5lRW5kPXgseCgpfXJldHVybiBtfX12YXIgSnA9VmEoe3BvaW50OmZ1bmN0aW9uKGksdCl7dGhpcy5zdHJlYW0ucG9pbnQoaSpILHQqSCl9fSk7ZnVuY3Rpb24gWXAoaSl7cmV0dXJuIFZhKHtwb2ludDpmdW5jdGlvbih0LGUpe3ZhciBuPWkodCxlKTtyZXR1cm4gdGhpcy5zdHJlYW0ucG9pbnQoblswXSxuWzFdKX19KX1mdW5jdGlvbiBqcChpLHQsZSxuLHMpe2Z1bmN0aW9uIHIobyxhKXtyZXR1cm4gbyo9bixhKj1zLFt0K2kqbyxlLWkqYV19cmV0dXJuIHIuaW52ZXJ0PWZ1bmN0aW9uKG8sYSl7cmV0dXJuWyhvLXQpL2kqbiwoZS1hKS9pKnNdfSxyfWZ1bmN0aW9uIFVoKGksdCxlLG4scyxyKXtpZighcilyZXR1cm4ganAoaSx0LGUsbixzKTt2YXIgbz1XKHIpLGE9cShyKSxjPW8qaSxsPWEqaSxoPW8vaSx1PWEvaSxmPShhKmUtbyp0KS9pLGQ9KGEqdCtvKmUpL2k7ZnVuY3Rpb24gcCh5LG0pe3JldHVybiB5Kj1uLG0qPXMsW2MqeS1sKm0rdCxlLWwqeS1jKm1dfXJldHVybiBwLmludmVydD1mdW5jdGlvbih5LG0pe3JldHVybltuKihoKnktdSptK2YpLHMqKGQtdSp5LWgqbSldfSxwfWZ1bmN0aW9uIENyKGkpe3JldHVybiBRcChmdW5jdGlvbigpe3JldHVybiBpfSkoKX1mdW5jdGlvbiBRcChpKXt2YXIgdCxlPTE1MCxuPTQ4MCxzPTI1MCxyPTAsbz0wLGE9MCxjPTAsbD0wLGgsdT0wLGY9MSxkPTEscD1udWxsLHk9Q2gsbT1udWxsLGcsYix3LHg9TGgsTT0uNSxBLFMsXyxFLHo7ZnVuY3Rpb24gdihCKXtyZXR1cm4gXyhCWzBdKkgsQlsxXSpIKX1mdW5jdGlvbiBDKEIpe3JldHVybiBCPV8uaW52ZXJ0KEJbMF0sQlsxXSksQiYmW0JbMF0qaHQsQlsxXSpodF19di5zdHJlYW09ZnVuY3Rpb24oQil7cmV0dXJuIEUmJno9PT1CP0U6RT1KcChZcChoKSh5KEEoeCh6PUIpKSkpKX0sdi5wcmVjbGlwPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh5PUIscD12b2lkIDAsRigpKTp5fSx2LnBvc3RjbGlwPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh4PUIsbT1nPWI9dz1udWxsLEYoKSk6eH0sdi5jbGlwQW5nbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHk9K0I/Q3AocD1CKkgpOihwPW51bGwsQ2gpLEYoKSk6cCpodH0sdi5jbGlwRXh0ZW50PWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh4PUI9PW51bGw/KG09Zz1iPXc9bnVsbCxMaCk6RnAobT0rQlswXVswXSxnPStCWzBdWzFdLGI9K0JbMV1bMF0sdz0rQlsxXVsxXSksRigpKTptPT1udWxsP251bGw6W1ttLGddLFtiLHddXX0sdi5zY2FsZT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZT0rQixQKCkpOmV9LHYudHJhbnNsYXRlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhuPStCWzBdLHM9K0JbMV0sUCgpKTpbbixzXX0sdi5jZW50ZXI9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHI9QlswXSUzNjAqSCxvPUJbMV0lMzYwKkgsUCgpKTpbcipodCxvKmh0XX0sdi5yb3RhdGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGE9QlswXSUzNjAqSCxjPUJbMV0lMzYwKkgsbD1CLmxlbmd0aD4yP0JbMl0lMzYwKkg6MCxQKCkpOlthKmh0LGMqaHQsbCpodF19LHYuYW5nbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHU9QiUzNjAqSCxQKCkpOnUqaHR9LHYucmVmbGVjdFg9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGY9Qj8tMToxLFAoKSk6ZjwwfSx2LnJlZmxlY3RZPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhkPUI/LTE6MSxQKCkpOmQ8MH0sdi5wcmVjaXNpb249ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KEE9VmgoUyxNPUIqQiksRigpKTpPZShNKX0sdi5maXRFeHRlbnQ9ZnVuY3Rpb24oQixJKXtyZXR1cm4gRGgodixCLEkpfSx2LmZpdFNpemU9ZnVuY3Rpb24oQixJKXtyZXR1cm4gcXAodixCLEkpfSx2LmZpdFdpZHRoPWZ1bmN0aW9uKEIsSSl7cmV0dXJuIEhwKHYsQixJKX0sdi5maXRIZWlnaHQ9ZnVuY3Rpb24oQixJKXtyZXR1cm4gV3AodixCLEkpfTtmdW5jdGlvbiBQKCl7dmFyIEI9VWgoZSwwLDAsZixkLHUpLmFwcGx5KG51bGwsdChyLG8pKSxJPVVoKGUsbi1CWzBdLHMtQlsxXSxmLGQsdSk7cmV0dXJuIGg9d2goYSxjLGwpLFM9TmEodCxJKSxfPU5hKGgsUyksQT1WaChTLE0pLEYoKX1mdW5jdGlvbiBGKCl7cmV0dXJuIEU9ej1udWxsLHZ9cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHQ9aS5hcHBseSh0aGlzLGFyZ3VtZW50cyksdi5pbnZlcnQ9dC5pbnZlcnQmJkMsUCgpfX1mdW5jdGlvbiBLcChpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXt2YXIgbj1PZSh0KnQrZSplKSxzPWkobikscj1xKHMpLG89VyhzKTtyZXR1cm5bcmUodCpyLG4qbyksRGUobiYmZSpyL24pXX19ZnVuY3Rpb24gSGEoaSx0KXtyZXR1cm5baSxscCh1cCgoTnQrdCkvMikpXX1IYS5pbnZlcnQ9ZnVuY3Rpb24oaSx0KXtyZXR1cm5baSwyKlNhKGNwKHQpKS1OdF19O2Z1bmN0aW9uIHR5KCl7cmV0dXJuIGV5KEhhKS5zY2FsZSg5NjEvUnQpfWZ1bmN0aW9uIGV5KGkpe3ZhciB0PUNyKGkpLGU9dC5jZW50ZXIsbj10LnNjYWxlLHM9dC50cmFuc2xhdGUscj10LmNsaXBFeHRlbnQsbz1udWxsLGEsYyxsO3Quc2NhbGU9ZnVuY3Rpb24odSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KG4odSksaCgpKTpuKCl9LHQudHJhbnNsYXRlPWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhzKHUpLGgoKSk6cygpfSx0LmNlbnRlcj1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZSh1KSxoKCkpOmUoKX0sdC5jbGlwRXh0ZW50PWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh1PT1udWxsP289YT1jPWw9bnVsbDoobz0rdVswXVswXSxhPSt1WzBdWzFdLGM9K3VbMV1bMF0sbD0rdVsxXVsxXSksaCgpKTpvPT1udWxsP251bGw6W1tvLGFdLFtjLGxdXX07ZnVuY3Rpb24gaCgpe3ZhciB1PVgqbigpLGY9dChTaCh0LnJvdGF0ZSgpKS5pbnZlcnQoWzAsMF0pKTtyZXR1cm4gcihvPT1udWxsP1tbZlswXS11LGZbMV0tdV0sW2ZbMF0rdSxmWzFdK3VdXTppPT09SGE/W1tNYXRoLm1heChmWzBdLXUsbyksYV0sW01hdGgubWluKGZbMF0rdSxjKSxsXV06W1tvLE1hdGgubWF4KGZbMV0tdSxhKV0sW2MsTWF0aC5taW4oZlsxXSt1LGwpXV0pfXJldHVybiBoKCl9ZnVuY3Rpb24gV2EoaSx0KXtyZXR1cm5baSx0XX1XYS5pbnZlcnQ9V2E7ZnVuY3Rpb24gbnkoKXtyZXR1cm4gQ3IoV2EpLnNjYWxlKDE1Mi42Myl9ZnVuY3Rpb24gcWgoaSx0KXt2YXIgZT1XKHQpLG49MStXKGkpKmU7cmV0dXJuW2UqcShpKS9uLHEodCkvbl19cWguaW52ZXJ0PUtwKGZ1bmN0aW9uKGkpe3JldHVybiAyKlNhKGkpfSk7ZnVuY3Rpb24gaXkoKXtyZXR1cm4gQ3IocWgpLnNjYWxlKDI1MCkuY2xpcEFuZ2xlKDE0Mil9dmFyIEJyPU1hdGguYWJzLGFpPU1hdGguY29zLGJlPU1hdGguc2luLFppPTFlLTYsRnI9TWF0aC5QSSxHYT1Gci8yO2Z1bmN0aW9uIHN5KGkpe3JldHVybiBpP2kvTWF0aC5zaW4oaSk6MX1mdW5jdGlvbiBaYShpKXtyZXR1cm4gaT4xPzA6aTwtMT9GcjpNYXRoLmFjb3MoaSl9ZnVuY3Rpb24gSGgoaSl7cmV0dXJuIGk+MD9NYXRoLnNxcnQoaSk6MH1mdW5jdGlvbiBXaChpLHQpe3ZhciBlPWFpKHQpLG49c3koWmEoZSphaShpLz0yKSkpO3JldHVyblsyKmUqYmUoaSkqbixiZSh0KSpuXX1XaC5pbnZlcnQ9ZnVuY3Rpb24oaSx0KXtpZighKGkqaSs0KnQqdD5GcipGcitaaSkpe3ZhciBlPWksbj10LHM9MjU7ZG97dmFyIHI9YmUoZSksbz1iZShlLzIpLGE9YWkoZS8yKSxjPWJlKG4pLGw9YWkobiksaD1iZSgyKm4pLHU9YypjLGY9bCpsLGQ9bypvLHA9MS1mKmEqYSx5PXA/WmEobCphKSpIaChtPTEvcCk6bT0wLG0sZz0yKnkqbCpvLWksYj15KmMtdCx3PW0qKGYqZCt5KmwqYSp1KSx4PW0qKC41KnIqaC15KjIqYypvKSxNPW0qLjI1KihoKm8teSpjKmYqciksQT1tKih1KmEreSpkKmwpLFM9eCpNLUEqdztpZighUylicmVhazt2YXIgXz0oYip4LWcqQSkvUyxFPShnKk0tYip3KS9TO2UtPV8sbi09RX13aGlsZSgoQnIoXyk+Wml8fEJyKEUpPlppKSYmLS1zPjApO3JldHVybltlLG5dfX07ZnVuY3Rpb24gR2goaSx0KXt2YXIgZT1XaChpLHQpO3JldHVyblsoZVswXStpL0dhKS8yLChlWzFdK3QpLzJdfUdoLmludmVydD1mdW5jdGlvbihpLHQpe3ZhciBlPWksbj10LHM9MjU7ZG97dmFyIHI9YWkobiksbz1iZShuKSxhPWJlKDIqbiksYz1vKm8sbD1yKnIsaD1iZShlKSx1PWFpKGUvMiksZj1iZShlLzIpLGQ9ZipmLHA9MS1sKnUqdSx5PXA/WmEocip1KSpIaChtPTEvcCk6bT0wLG0sZz0uNSooMip5KnIqZitlL0dhKS1pLGI9LjUqKHkqbytuKS10LHc9LjUqbSoobCpkK3kqcip1KmMpKy41L0dhLHg9bSooaCphLzQteSpvKmYpLE09LjEyNSptKihhKmYteSpvKmwqaCksQT0uNSptKihjKnUreSpkKnIpKy41LFM9eCpNLUEqdyxfPShiKngtZypBKS9TLEU9KGcqTS1iKncpL1M7ZS09XyxuLT1FfXdoaWxlKChCcihfKT5aaXx8QnIoRSk+WmkpJiYtLXM+MCk7cmV0dXJuW2Usbl19O2Z1bmN0aW9uIHJ5KCl7cmV0dXJuIENyKEdoKS5zY2FsZSgxNTguODM3KX1jb25zdCBveT17bWVyY2F0b3I6dHksZXF1aXJlY3Rhbmd1bGFyOm55LHdpbmtlbDM6cnl9LFhhPXt9LFhpPWk9Pnt2YXIgbixzLHI7Y29uc3QgdD1KU09OLnN0cmluZ2lmeShpKTtpZihYYVt0XSlyZXR1cm4gWGFbdF07Y29uc3QgZT1veVsobj1pLnByb2plY3Rpb25UeXBlKSE9bnVsbD9uOiJtZXJjYXRvciJdKCkuY2VudGVyKGkuY2VudGVyKS5zY2FsZShpLnNjYWxlKS50cmFuc2xhdGUoKHM9aS50cmFuc2xhdGUpIT1udWxsP3M6WzAsMF0pLnByZWNpc2lvbigocj1pLnByZWNpc2lvbikhPW51bGw/cjouMSk7cmV0dXJuIGkucm90YXRlJiZlLnJvdGF0ZShpLnJvdGF0ZSksWGFbdF09ZSxlfSxJcj0oaSx0KT0+aS5tYXAoKFtlLG5dKT0+e2xldCBzO2lmKHQpe2NvbnN0W3Isb109dChbZSxuXSk7cz1uZXcgUihyLC1vKX1lbHNlIHM9bmV3IFIoZSxuKTtyZXR1cm4gc30pO3ZhciBKaT0oaSx0KT0+e2NvbnN0IGU9SmwoaSx0IT1udWxsP3Q6MCksbj17fSxzPVtdLHI9T2JqZWN0LmtleXMoZS5hdHRyaWJ1dGVzKTtyZXR1cm4gZS5pbmRleCYmci5wdXNoKCJpbmRleCIpLHIuZm9yRWFjaChvPT57Y29uc3QgYT1vPT09ImluZGV4Ij9lLmluZGV4OmUuYXR0cmlidXRlc1tvXTtuW29dPXthcnJheTphLmFycmF5LGl0ZW1TaXplOmEuaXRlbVNpemV9LHMucHVzaChhLmFycmF5LmJ1ZmZlcil9KSx0JiYobi5ncm91cHM9ZS5ncm91cHMpLGUuZGlzcG9zZSgpLGkuZm9yRWFjaChvPT57by5kaXNwb3NlKCl9KSx7bWVzc2FnZTpuLHRyYW5zZmVyOnN9fSxKYT0oaSx0PTMwMCk9Pntjb25zdCBlPVtdO3JldHVybiBpLmZvckVhY2gobj0+e2xldCBzPSExO2ZvcihsZXQgcj0xO3I8bi5sZW5ndGg7cisrKWlmKE1hdGguYWJzKG5bcl0ueC1uW3ItMV0ueCk+dCl7cz0hMDticmVha31pZihzKXtjb25zdCByPVtdLG89W107bi5mb3JFYWNoKGE9PnthLng8MD9yLnB1c2goYSk6by5wdXNoKGEpfSksZS5wdXNoKHIsbyl9ZWxzZSBlLnB1c2gobil9KSxlfTtmdW5jdGlvbiBheShpLHQsZT0wKXtjb25zdFtuLHMscixvXT1pO2xldCBhPTEvMCxjPTEvMCxsPS0xLzAsaD0tMS8wO2ZvcihsZXQgdT0wO3U8PWU7dSsrKXtjb25zdCBmPWUmJnUvZTtJcihbW24rZiooci1uKSxzXSxbbitmKihyLW4pLG9dLFtuLHMrZiooby1zKV0sW3IscytmKihvLXMpXV0sdCkuZm9yRWFjaChkPT57YT1NYXRoLm1pbihhLGQueCksYz1NYXRoLm1pbihjLGQueSksbD1NYXRoLm1heChsLGQueCksaD1NYXRoLm1heChoLGQueSl9KX1yZXR1cm5bW2EsY10sW2wsaF1dfWNvbnN0IGN5PSh7Y29vcmRpbmF0ZXNBcnI6aSxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxiYm94Om4sZGVwdGg6cyxwcm9qZWN0aW9uOnIsdXNlR3JvdXBzOm8saGFzVG9wOmEsaGFzQm90dG9tOmMsaGFzU2lkZTpsLHNwbGl0UG9seWdvbnM6aCx0b3BTZWdtZW50czp1fSk9Pntjb25zdCBmPXImJlhpKHIpO2xldCBkPWkubWFwKG09PklyKG0sZikpO2gmJihkPUphKGQsaCkpO2xldCBwO2lmKG4pe2NvbnN0W20sZ109YXkobixyIT1udWxsJiZyLnJvdGF0ZT9YaShaZShGdCh7fSxyKSx7cm90YXRlOnZvaWQgMH0pKTpmLChyPT1udWxsP3ZvaWQgMDpyLnByb2plY3Rpb25UeXBlKT09PSJ3aW5rZWwzIj8xMDowKTtwPW5ldyBndChuZXcgVChtWzBdLG1bMV0sMCksbmV3IFQoZ1swXSxnWzFdLDApKX1jb25zdCB5PWQubWFwKChtLGcpPT57dmFyIGI7cmV0dXJuIEowKHtwb2ludHM6bSxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxkZXB0aDooYj1zW2ddKSE9bnVsbD9iOnNbMF0saGFzVG9wOmEsaGFzQm90dG9tOmMsaGFzU2lkZTpsLGJveDM6cCx0b3BTZWdtZW50czp1fSl9KTtyZXR1cm4gSmkoeSxvKX07ZnVuY3Rpb24gWWEoaSx0LGUsbixzKXtsZXQgcjtpZihpPWkuc3ViYXJyYXl8fGkuc2xpY2U/aTppLmJ1ZmZlcixlPWUuc3ViYXJyYXl8fGUuc2xpY2U/ZTplLmJ1ZmZlcixpPXQ/aS5zdWJhcnJheT9pLnN1YmFycmF5KHQscyYmdCtzKTppLnNsaWNlKHQscyYmdCtzKTppLGUuc2V0KWUuc2V0KGksbik7ZWxzZSBmb3Iocj0wO3I8aS5sZW5ndGg7cisrKWVbcituXT1pW3JdO3JldHVybiBlfWZ1bmN0aW9uIGx5KGkpe3JldHVybiBpIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5P2k6aSBpbnN0YW5jZW9mIHVlP2kuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLmFycmF5OmkubWFwKHQ9Pntjb25zdCBlPUFycmF5LmlzQXJyYXkodCk7cmV0dXJuIHQgaW5zdGFuY2VvZiBUP1t0LngsdC55LHQuel06dCBpbnN0YW5jZW9mIFI/W3QueCx0LnksMF06ZSYmdC5sZW5ndGg9PT0zP1t0WzBdLHRbMV0sdFsyXV06ZSYmdC5sZW5ndGg9PT0yP1t0WzBdLHRbMV0sMF06dH0pLmZsYXQoKX1jbGFzcyBoeSBleHRlbmRzIHVle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9Ik1lc2hMaW5lIix0aGlzLmlzTWVzaExpbmU9ITAsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdLHRoaXMuY291bnRlcnM9W10sdGhpcy53aWR0aENhbGxiYWNrPW51bGwsdGhpcy5fcG9pbnRzPVtdLHRoaXMubWF0cml4V29ybGQ9bmV3IHN0LE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMse3BvaW50czp7ZW51bWVyYWJsZTohMCxnZXQoKXtyZXR1cm4gdGhpcy5fcG9pbnRzfSxzZXQodCl7dGhpcy5zZXRQb2ludHModCx0aGlzLndpZHRoQ2FsbGJhY2spfX19KX1zZXRNYXRyaXhXb3JsZCh0KXt0aGlzLm1hdHJpeFdvcmxkPXR9c2V0UG9pbnRzKHQsZSl7aWYodD1seSh0KSx0aGlzLl9wb2ludHM9dCx0aGlzLndpZHRoQ2FsbGJhY2s9ZSE9bnVsbD9lOm51bGwsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5jb3VudGVycz1bXSx0Lmxlbmd0aCYmdFswXWluc3RhbmNlb2YgVClmb3IobGV0IG49MDtuPHQubGVuZ3RoO24rKyl7Y29uc3Qgcz10W25dLHI9bi8odC5sZW5ndGgtMSk7dGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5jb3VudGVycy5wdXNoKHIpLHRoaXMuY291bnRlcnMucHVzaChyKX1lbHNlIGZvcihsZXQgbj0wO248dC5sZW5ndGg7bis9Myl7Y29uc3Qgcz1uLyh0Lmxlbmd0aC0xKTt0aGlzLnBvc2l0aW9ucy5wdXNoKHRbbl0sdFtuKzFdLHRbbisyXSksdGhpcy5wb3NpdGlvbnMucHVzaCh0W25dLHRbbisxXSx0W24rMl0pLHRoaXMuY291bnRlcnMucHVzaChzKSx0aGlzLmNvdW50ZXJzLnB1c2gocyl9dGhpcy5wcm9jZXNzKCl9Y29tcGFyZVYzKHQsZSl7Y29uc3Qgbj10KjYscz1lKjY7cmV0dXJuIHRoaXMucG9zaXRpb25zW25dPT09dGhpcy5wb3NpdGlvbnNbc10mJnRoaXMucG9zaXRpb25zW24rMV09PT10aGlzLnBvc2l0aW9uc1tzKzFdJiZ0aGlzLnBvc2l0aW9uc1tuKzJdPT09dGhpcy5wb3NpdGlvbnNbcysyXX1jb3B5VjModCl7Y29uc3QgZT10KjY7cmV0dXJuW3RoaXMucG9zaXRpb25zW2VdLHRoaXMucG9zaXRpb25zW2UrMV0sdGhpcy5wb3NpdGlvbnNbZSsyXV19cHJvY2Vzcygpe2NvbnN0IHQ9dGhpcy5wb3NpdGlvbnMubGVuZ3RoLzY7dGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdO2xldCBlLG47dGhpcy5jb21wYXJlVjMoMCx0LTEpP249dGhpcy5jb3B5VjModC0yKTpuPXRoaXMuY29weVYzKDApLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKTtmb3IobGV0IHM9MDtzPHQ7cysrKXtpZih0aGlzLnNpZGUucHVzaCgxKSx0aGlzLnNpZGUucHVzaCgtMSksdGhpcy53aWR0aENhbGxiYWNrP2U9dGhpcy53aWR0aENhbGxiYWNrKHMvKHQtMSkpOmU9MSx0aGlzLndpZHRoLnB1c2goZSksdGhpcy53aWR0aC5wdXNoKGUpLHRoaXMudXZzLnB1c2gocy8odC0xKSwwKSx0aGlzLnV2cy5wdXNoKHMvKHQtMSksMSksczx0LTEpe249dGhpcy5jb3B5VjMocyksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLnByZXZpb3VzLnB1c2goblswXSxuWzFdLG5bMl0pO2NvbnN0IHI9cyoyO3RoaXMuaW5kaWNlc19hcnJheS5wdXNoKHIscisxLHIrMiksdGhpcy5pbmRpY2VzX2FycmF5LnB1c2gocisyLHIrMSxyKzMpfXM+MCYmKG49dGhpcy5jb3B5VjMocyksdGhpcy5uZXh0LnB1c2goblswXSxuWzFdLG5bMl0pLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSl9dGhpcy5jb21wYXJlVjModC0xLDApP249dGhpcy5jb3B5VjMoMSk6bj10aGlzLmNvcHlWMyh0LTEpLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSksIXRoaXMuX2F0dHJpYnV0ZXN8fHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uY291bnQhPT10aGlzLmNvdW50ZXJzLmxlbmd0aD90aGlzLl9hdHRyaWJ1dGVzPXtwb3NpdGlvbjpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucyksMykscHJldmlvdXM6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wcmV2aW91cyksMyksbmV4dDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLm5leHQpLDMpLHNpZGU6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaWRlKSwxKSx3aWR0aDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSwxKSx1djpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnV2cyksMiksaW5kZXg6bmV3IHh0KG5ldyBVaW50MTZBcnJheSh0aGlzLmluZGljZXNfYXJyYXkpLDEpLGNvdW50ZXJzOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMuY291bnRlcnMpLDEpfToodGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucykpLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24ubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnByZXZpb3VzKSksdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLm5leHQuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5uZXh0KSksdGhpcy5fYXR0cmlidXRlcy5uZXh0Lm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMuc2lkZS5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnNpZGUpKSx0aGlzLl9hdHRyaWJ1dGVzLnNpZGUubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy53aWR0aC5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSksdGhpcy5fYXR0cmlidXRlcy53aWR0aC5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnV2LmNvcHlBcnJheShuZXcgRmxvYXQzMkFycmF5KHRoaXMudXZzKSksdGhpcy5fYXR0cmlidXRlcy51di5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLmluZGV4LmNvcHlBcnJheShuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzX2FycmF5KSksdGhpcy5fYXR0cmlidXRlcy5pbmRleC5uZWVkc1VwZGF0ZT0hMCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIix0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uKSx0aGlzLnNldEF0dHJpYnV0ZSgicHJldmlvdXMiLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMpLHRoaXMuc2V0QXR0cmlidXRlKCJuZXh0Iix0aGlzLl9hdHRyaWJ1dGVzLm5leHQpLHRoaXMuc2V0QXR0cmlidXRlKCJzaWRlIix0aGlzLl9hdHRyaWJ1dGVzLnNpZGUpLHRoaXMuc2V0QXR0cmlidXRlKCJ3aWR0aCIsdGhpcy5fYXR0cmlidXRlcy53aWR0aCksdGhpcy5zZXRBdHRyaWJ1dGUoInV2Iix0aGlzLl9hdHRyaWJ1dGVzLnV2KSx0aGlzLnNldEF0dHJpYnV0ZSgiY291bnRlcnMiLHRoaXMuX2F0dHJpYnV0ZXMuY291bnRlcnMpLHRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbiksdGhpcy5zZXRBdHRyaWJ1dGUoInByZXZpb3VzIix0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzKSx0aGlzLnNldEF0dHJpYnV0ZSgibmV4dCIsdGhpcy5fYXR0cmlidXRlcy5uZXh0KSx0aGlzLnNldEF0dHJpYnV0ZSgic2lkZSIsdGhpcy5fYXR0cmlidXRlcy5zaWRlKSx0aGlzLnNldEF0dHJpYnV0ZSgid2lkdGgiLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsdGhpcy5fYXR0cmlidXRlcy51diksdGhpcy5zZXRBdHRyaWJ1dGUoImNvdW50ZXJzIix0aGlzLl9hdHRyaWJ1dGVzLmNvdW50ZXJzKSx0aGlzLnNldEluZGV4KHRoaXMuX2F0dHJpYnV0ZXMuaW5kZXgpLHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCksdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKX1hZHZhbmNlKHt4OnQseTplLHo6bn0pe2NvbnN0IHM9dGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5hcnJheSxyPXRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMuYXJyYXksbz10aGlzLl9hdHRyaWJ1dGVzLm5leHQuYXJyYXksYT1zLmxlbmd0aDtZYShzLDAsciwwLGEpLFlhKHMsNixzLDAsYS02KSxzW2EtNl09dCxzW2EtNV09ZSxzW2EtNF09bixzW2EtM109dCxzW2EtMl09ZSxzW2EtMV09bixZYShzLDYsbywwLGEtNiksb1thLTZdPXQsb1thLTVdPWUsb1thLTRdPW4sb1thLTNdPXQsb1thLTJdPWUsb1thLTFdPW4sdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMubmV4dC5uZWVkc1VwZGF0ZT0hMH19dmFyIFpoPWk9Pntjb25zdHtzZXRQb2ludFdpZHRoOnQsbm9kZXM6ZX09aSxuPW5ldyBoeTtyZXR1cm4gbi5zZXRQb2ludHMoZSx0KSxufTtjb25zdCB1eT0oe2Nvb3JkaW5hdGVzQXJyOmkscHJvamVjdGlvbjp0LGxpbmVXaWR0aDplLHVzZUdyb3VwczpuLHNwbGl0UG9seWdvbnM6c30pPT57Y29uc3Qgcj10JiZYaSh0KTtsZXQgbz1pLm1hcChjPT5JcihjLHIpKTtzJiYobz1KYShvLHMpKTtjb25zdCBhPW8ubWFwKChjLGwpPT57dmFyIHU7Y29uc3QgaD0odT1lW2xdKSE9bnVsbD91OmVbMF07cmV0dXJuIFpoKHtub2RlczpjLHNldFBvaW50V2lkdGg6KCk9Pmh9KX0pO3JldHVybiBKaShhLG4pfTt2YXIgZnk9aT0+e2NvbnN0e3BvaW50czp0fT1pLGU9dC5yZWR1Y2UoKHMscixvKT0+KG88dC5sZW5ndGgtMSYmcy5wdXNoKHIsdFtvKzFdKSxzKSxbXSk7cmV0dXJuIG5ldyB1ZSgpLnNldEZyb21Qb2ludHMoZSl9O2NvbnN0IGR5PSh7Y29vcmRpbmF0ZXNBcnI6aSxwcm9qZWN0aW9uOnQsbGluZVdpZHRoOmUsdXNlR3JvdXBzOm4sc3BsaXRQb2x5Z29uczpzfSk9Pntjb25zdCByPXQmJlhpKHQpO2xldCBvPWkubWFwKGM9PklyKGMscikpO3MmJihvPUphKG8scykpO2NvbnN0IGE9by5tYXAoKGMsbCk9PmZ5KHtwb2ludHM6Yy5tYXAoaD0+bmV3IFQoaC54LGgueSwwKSl9KSk7cmV0dXJuIEppKGEsbil9O2Z1bmN0aW9uIHB5KGksdCxlPTIpe2NvbnN0IG49dCYmdC5sZW5ndGgscz1uP3RbMF0qZTppLmxlbmd0aDtsZXQgcj1YaChpLDAscyxlLCEwKTtjb25zdCBvPVtdO2lmKCFyfHxyLm5leHQ9PT1yLnByZXYpcmV0dXJuIG87bGV0IGEsYyxsO2lmKG4mJihyPXd5KGksdCxyLGUpKSxpLmxlbmd0aD44MCplKXthPTEvMCxjPTEvMDtsZXQgaD0tMS8wLHU9LTEvMDtmb3IobGV0IGY9ZTtmPHM7Zis9ZSl7Y29uc3QgZD1pW2ZdLHA9aVtmKzFdO2Q8YSYmKGE9ZCkscDxjJiYoYz1wKSxkPmgmJihoPWQpLHA+dSYmKHU9cCl9bD1NYXRoLm1heChoLWEsdS1jKSxsPWwhPT0wPzMyNzY3L2w6MH1yZXR1cm4gWWkocixvLGUsYSxjLGwsMCksb31mdW5jdGlvbiBYaChpLHQsZSxuLHMpe2xldCByO2lmKHM9PT1DeShpLHQsZSxuKT4wKWZvcihsZXQgbz10O288ZTtvKz1uKXI9amgoby9ufDAsaVtvXSxpW28rMV0scik7ZWxzZSBmb3IobGV0IG89ZS1uO28+PXQ7by09bilyPWpoKG8vbnwwLGlbb10saVtvKzFdLHIpO3JldHVybiByJiZrcihyLHIubmV4dCkmJihRaShyKSxyPXIubmV4dCkscn1mdW5jdGlvbiB2bihpLHQpe2lmKCFpKXJldHVybiBpO3R8fCh0PWkpO2xldCBlPWksbjtkbyBpZihuPSExLCFlLnN0ZWluZXImJihrcihlLGUubmV4dCl8fGF0KGUucHJldixlLGUubmV4dCk9PT0wKSl7aWYoUWkoZSksZT10PWUucHJldixlPT09ZS5uZXh0KWJyZWFrO249ITB9ZWxzZSBlPWUubmV4dDt3aGlsZShufHxlIT09dCk7cmV0dXJuIHR9ZnVuY3Rpb24gWWkoaSx0LGUsbixzLHIsbyl7aWYoIWkpcmV0dXJuOyFvJiZyJiZfeShpLG4scyxyKTtsZXQgYT1pO2Zvcig7aS5wcmV2IT09aS5uZXh0Oyl7Y29uc3QgYz1pLnByZXYsbD1pLm5leHQ7aWYocj9teShpLG4scyxyKTp5eShpKSl7dC5wdXNoKGMuaSxpLmksbC5pKSxRaShpKSxpPWwubmV4dCxhPWwubmV4dDtjb250aW51ZX1pZihpPWwsaT09PWEpe28/bz09PTE/KGk9Z3kodm4oaSksdCksWWkoaSx0LGUsbixzLHIsMikpOm89PT0yJiZ4eShpLHQsZSxuLHMscik6WWkodm4oaSksdCxlLG4scyxyLDEpO2JyZWFrfX19ZnVuY3Rpb24geXkoaSl7Y29uc3QgdD1pLnByZXYsZT1pLG49aS5uZXh0O2lmKGF0KHQsZSxuKT49MClyZXR1cm4hMTtjb25zdCBzPXQueCxyPWUueCxvPW4ueCxhPXQueSxjPWUueSxsPW4ueSxoPXM8cj9zPG8/czpvOnI8bz9yOm8sdT1hPGM/YTxsP2E6bDpjPGw/YzpsLGY9cz5yP3M+bz9zOm86cj5vP3I6byxkPWE+Yz9hPmw/YTpsOmM+bD9jOmw7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJmNpKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZhdChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIG15KGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihhdChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1hPGM/YTxsP2E6bDpjPGw/YzpsLHA9aDx1P2g8Zj9oOmY6dTxmP3U6Zix5PWE+Yz9hPmw/YTpsOmM+bD9jOmwsbT1oPnU/aD5mP2g6Zjp1PmY/dTpmLGc9amEoZCxwLHQsZSxuKSxiPWphKHksbSx0LGUsbik7bGV0IHc9aS5wcmV2Wix4PWkubmV4dFo7Zm9yKDt3JiZ3Lno+PWcmJngmJnguejw9Yjspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZjaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MHx8KHc9dy5wcmV2Wix4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmY2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApKXJldHVybiExO3g9eC5uZXh0Wn1mb3IoO3cmJncuej49Zzspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZjaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MClyZXR1cm4hMTt3PXcucHJldlp9Zm9yKDt4JiZ4Lno8PWI7KXtpZih4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmY2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApcmV0dXJuITE7eD14Lm5leHRafXJldHVybiEwfWZ1bmN0aW9uIGd5KGksdCl7bGV0IGU9aTtkb3tjb25zdCBuPWUucHJldixzPWUubmV4dC5uZXh0OyFrcihuLHMpJiZKaChuLGUsZS5uZXh0LHMpJiZqaShuLHMpJiZqaShzLG4pJiYodC5wdXNoKG4uaSxlLmkscy5pKSxRaShlKSxRaShlLm5leHQpLGU9aT1zKSxlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuIHZuKGUpfWZ1bmN0aW9uIHh5KGksdCxlLG4scyxyKXtsZXQgbz1pO2Rve2xldCBhPW8ubmV4dC5uZXh0O2Zvcig7YSE9PW8ucHJldjspe2lmKG8uaSE9PWEuaSYmVHkobyxhKSl7bGV0IGM9WWgobyxhKTtvPXZuKG8sby5uZXh0KSxjPXZuKGMsYy5uZXh0KSxZaShvLHQsZSxuLHMsciwwKSxZaShjLHQsZSxuLHMsciwwKTtyZXR1cm59YT1hLm5leHR9bz1vLm5leHR9d2hpbGUobyE9PWkpfWZ1bmN0aW9uIHd5KGksdCxlLG4pe2NvbnN0IHM9W107Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXRbcl0qbixjPXI8by0xP3RbcisxXSpuOmkubGVuZ3RoLGw9WGgoaSxhLGMsbiwhMSk7bD09PWwubmV4dCYmKGwuc3RlaW5lcj0hMCkscy5wdXNoKHp5KGwpKX1zLnNvcnQoYnkpO2ZvcihsZXQgcj0wO3I8cy5sZW5ndGg7cisrKWU9TXkoc1tyXSxlKTtyZXR1cm4gZX1mdW5jdGlvbiBieShpLHQpe3JldHVybiBpLngtdC54fWZ1bmN0aW9uIE15KGksdCl7Y29uc3QgZT1BeShpLHQpO2lmKCFlKXJldHVybiB0O2NvbnN0IG49WWgoZSxpKTtyZXR1cm4gdm4obixuLm5leHQpLHZuKGUsZS5uZXh0KX1mdW5jdGlvbiBBeShpLHQpe2xldCBlPXQ7Y29uc3Qgbj1pLngscz1pLnk7bGV0IHI9LTEvMCxvO2Rve2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZjaShzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTtqaShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmU3kobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIFN5KGksdCl7cmV0dXJuIGF0KGkucHJldixpLHQucHJldik8MCYmYXQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIF95KGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1qYShzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwsdnkocyl9ZnVuY3Rpb24gdnkoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBqYShpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24genkoaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIGNpKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiBUeShpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFFeShpLHQpJiYoamkoaSx0KSYmamkodCxpKSYmUHkoaSx0KSYmKGF0KGkucHJldixpLHQucHJldil8fGF0KGksdC5wcmV2LHQpKXx8a3IoaSx0KSYmYXQoaS5wcmV2LGksaS5uZXh0KT4wJiZhdCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIGF0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24ga3IoaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gSmgoaSx0LGUsbil7Y29uc3Qgcz1ScihhdChpLHQsZSkpLHI9UnIoYXQoaSx0LG4pKSxvPVJyKGF0KGUsbixpKSksYT1ScihhdChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJk5yKGksZSx0KXx8cj09PTAmJk5yKGksbix0KXx8bz09PTAmJk5yKGUsaSxuKXx8YT09PTAmJk5yKGUsdCxuKSl9ZnVuY3Rpb24gTnIoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIFJyKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBFeShpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmSmgoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gamkoaSx0KXtyZXR1cm4gYXQoaS5wcmV2LGksaS5uZXh0KTwwP2F0KGksdCxpLm5leHQpPj0wJiZhdChpLGkucHJldix0KT49MDphdChpLHQsaS5wcmV2KTwwfHxhdChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIFB5KGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gWWgoaSx0KXtjb25zdCBlPVFhKGkuaSxpLngsaS55KSxuPVFhKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBqaChpLHQsZSxuKXtjb25zdCBzPVFhKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gUWkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBRYShpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gQ3koaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWZ1bmN0aW9uIFFoKGkpe2NvbnN0IHQ9W10sZT1bXSxuPWlbMF1bMF0ubGVuZ3RoO2xldCBzPTAscj0wO2Zvcihjb25zdCBvIG9mIGkpe2Zvcihjb25zdCBhIG9mIG8pZm9yKGxldCBjPTA7YzxuO2MrKyl0LnB1c2goYVtjXSk7ciYmKHMrPXIsZS5wdXNoKHMpKSxyPW8ubGVuZ3RofXJldHVybnt2ZXJ0aWNlczp0LGhvbGVzOmUsZGltZW5zaW9uczpufX1mdW5jdGlvbiBCeShpKXtpZighaSl0aHJvdyBuZXcgRXJyb3IoImNvb3JkIGlzIHJlcXVpcmVkIik7aWYoIUFycmF5LmlzQXJyYXkoaSkpe2lmKGkudHlwZT09PSJGZWF0dXJlIiYmaS5nZW9tZXRyeSE9PW51bGwmJmkuZ2VvbWV0cnkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuZ2VvbWV0cnkuY29vcmRpbmF0ZXNdO2lmKGkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuY29vcmRpbmF0ZXNdfWlmKEFycmF5LmlzQXJyYXkoaSkmJmkubGVuZ3RoPj0yJiYhQXJyYXkuaXNBcnJheShpWzBdKSYmIUFycmF5LmlzQXJyYXkoaVsxXSkpcmV0dXJuWy4uLmldO3Rocm93IG5ldyBFcnJvcigiY29vcmQgbXVzdCBiZSBHZW9KU09OIFBvaW50IG9yIGFuIEFycmF5IG9mIG51bWJlcnMiKX1mdW5jdGlvbiBGeShpKXtpZihBcnJheS5pc0FycmF5KGkpKXJldHVybiBpO2lmKGkudHlwZT09PSJGZWF0dXJlIil7aWYoaS5nZW9tZXRyeSE9PW51bGwpcmV0dXJuIGkuZ2VvbWV0cnkuY29vcmRpbmF0ZXN9ZWxzZSBpZihpLmNvb3JkaW5hdGVzKXJldHVybiBpLmNvb3JkaW5hdGVzO3Rocm93IG5ldyBFcnJvcigiY29vcmRzIG11c3QgYmUgR2VvSlNPTiBGZWF0dXJlLCBHZW9tZXRyeSBPYmplY3Qgb3IgYW4gQXJyYXkiKX1mdW5jdGlvbiBJeShpKXtyZXR1cm4gaS50eXBlPT09IkZlYXR1cmUiP2kuZ2VvbWV0cnk6aX1mdW5jdGlvbiBreShpKXtjb25zdCB0PUZ5KGkpO2xldCBlPTAsbj0xLHMscjtmb3IoO248dC5sZW5ndGg7KXM9cnx8dFswXSxyPXRbbl0sZSs9KHJbMF0tc1swXSkqKHJbMV0rc1sxXSksbisrO3JldHVybiBlPjB9dmFyIE55PWt5O2NvbnN0IHFlPTExMTAyMjMwMjQ2MjUxNTY1ZS0zMix2dD0xMzQyMTc3MjksUnk9KDMrOCpxZSkqcWU7ZnVuY3Rpb24gS2EoaSx0LGUsbixzKXtsZXQgcixvLGEsYyxsPXRbMF0saD1uWzBdLHU9MCxmPTA7aD5sPT1oPi1sPyhyPWwsbD10WysrdV0pOihyPWgsaD1uWysrZl0pO2xldCBkPTA7aWYodTxpJiZmPGUpZm9yKGg+bD09aD4tbD8obz1sK3IsYT1yLShvLWwpLGw9dFsrK3VdKToobz1oK3IsYT1yLShvLWgpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7dTxpJiZmPGU7KWg+bD09aD4tbD8obz1yK2wsYz1vLXIsYT1yLShvLWMpKyhsLWMpLGw9dFsrK3VdKToobz1yK2gsYz1vLXIsYT1yLShvLWMpKyhoLWMpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDt1PGk7KW89citsLGM9by1yLGE9ci0oby1jKSsobC1jKSxsPXRbKyt1XSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDtmPGU7KW89citoLGM9by1yLGE9ci0oby1jKSsoaC1jKSxoPW5bKytmXSxyPW8sYSE9PTAmJihzW2QrK109YSk7cmV0dXJuKHIhPT0wfHxkPT09MCkmJihzW2QrK109ciksZH1mdW5jdGlvbiBMeShpLHQpe2xldCBlPXRbMF07Zm9yKGxldCBuPTE7bjxpO24rKyllKz10W25dO3JldHVybiBlfWZ1bmN0aW9uIEtpKGkpe3JldHVybiBuZXcgRmxvYXQ2NEFycmF5KGkpfWNvbnN0IE95PSgzKzE2KnFlKSpxZSxEeT0oMisxMipxZSkqcWUsJHk9KDkrNjQqcWUpKnFlKnFlLGxpPUtpKDQpLEtoPUtpKDgpLHR1PUtpKDEyKSxldT1LaSgxNiksQnQ9S2koNCk7ZnVuY3Rpb24gVnkoaSx0LGUsbixzLHIsbyl7bGV0IGEsYyxsLGgsdSxmLGQscCx5LG0sZyxiLHcseCxNLEEsUyxfO2NvbnN0IEU9aS1zLHo9ZS1zLHY9dC1yLEM9bi1yO3g9RSpDLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpDLHk9Zi0oZi1DKSxtPUMteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KnosZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KnoseT1mLShmLXopLG09ei15LFM9cCptLShBLWQqeS1wKnktZCptKSxnPU0tUyx1PU0tZyxsaVswXT1NLShnK3UpKyh1LVMpLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxsaVsxXT13LShnK3UpKyh1LUEpLF89YitnLHU9Xy1iLGxpWzJdPWItKF8tdSkrKGctdSksbGlbM109XztsZXQgUD1MeSg0LGxpKSxGPUR5Km87aWYoUD49Rnx8LVA+PUZ8fCh1PWktRSxhPWktKEUrdSkrKHUtcyksdT1lLXosbD1lLSh6K3UpKyh1LXMpLHU9dC12LGM9dC0odit1KSsodS1yKSx1PW4tQyxoPW4tKEMrdSkrKHUtciksYT09PTAmJmM9PT0wJiZsPT09MCYmaD09PTApfHwoRj0keSpvK1J5Kk1hdGguYWJzKFApLFArPUUqaCtDKmEtKHYqbCt6KmMpLFA+PUZ8fC1QPj1GKSlyZXR1cm4gUDt4PWEqQyxmPXZ0KmEsZD1mLShmLWEpLHA9YS1kLGY9dnQqQyx5PWYtKGYtQyksbT1DLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9Yyp6LGY9dnQqYyxkPWYtKGYtYykscD1jLWQsZj12dCp6LHk9Zi0oZi16KSxtPXoteSxTPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLVMsdT1NLWcsQnRbMF09TS0oZyt1KSsodS1TKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsQnRbMV09dy0oZyt1KSsodS1BKSxfPWIrZyx1PV8tYixCdFsyXT1iLShfLXUpKyhnLXUpLEJ0WzNdPV87Y29uc3QgQj1LYSg0LGxpLDQsQnQsS2gpO3g9RSpoLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpoLHk9Zi0oZi1oKSxtPWgteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KmwsZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KmwseT1mLShmLWwpLG09bC15LFM9cCptLShBLWQqeS1wKnktZCptKSxnPU0tUyx1PU0tZyxCdFswXT1NLShnK3UpKyh1LVMpLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxCdFsxXT13LShnK3UpKyh1LUEpLF89YitnLHU9Xy1iLEJ0WzJdPWItKF8tdSkrKGctdSksQnRbM109Xztjb25zdCBJPUthKEIsS2gsNCxCdCx0dSk7eD1hKmgsZj12dCphLGQ9Zi0oZi1hKSxwPWEtZCxmPXZ0KmgseT1mLShmLWgpLG09aC15LE09cCptLSh4LWQqeS1wKnktZCptKSxBPWMqbCxmPXZ0KmMsZD1mLShmLWMpLHA9Yy1kLGY9dnQqbCx5PWYtKGYtbCksbT1sLXksUz1wKm0tKEEtZCp5LXAqeS1kKm0pLGc9TS1TLHU9TS1nLEJ0WzBdPU0tKGcrdSkrKHUtUyksYj14K2csdT1iLXgsdz14LShiLXUpKyhnLXUpLGc9dy1BLHU9dy1nLEJ0WzFdPXctKGcrdSkrKHUtQSksXz1iK2csdT1fLWIsQnRbMl09Yi0oXy11KSsoZy11KSxCdFszXT1fO2NvbnN0IGs9S2EoSSx0dSw0LEJ0LGV1KTtyZXR1cm4gZXVbay0xXX1mdW5jdGlvbiBMcihpLHQsZSxuLHMscil7Y29uc3Qgbz0odC1yKSooZS1zKSxhPShpLXMpKihuLXIpLGM9by1hO2lmKG89PT0wfHxhPT09MHx8bz4wIT1hPjApcmV0dXJuIGM7Y29uc3QgbD1NYXRoLmFicyhvK2EpO3JldHVybiBNYXRoLmFicyhjKT49T3kqbD9jOi1WeShpLHQsZSxuLHMscixsKX1jb25zdCBudT1NYXRoLnBvdygyLC01MiksT3I9bmV3IFVpbnQzMkFycmF5KDUxMik7Y2xhc3MgdHN7c3RhdGljIGZyb20odCxlPUd5LG49Wnkpe2NvbnN0IHM9dC5sZW5ndGgscj1uZXcgRmxvYXQ2NEFycmF5KHMqMik7Zm9yKGxldCBvPTA7bzxzO28rKyl7Y29uc3QgYT10W29dO3JbMipvXT1lKGEpLHJbMipvKzFdPW4oYSl9cmV0dXJuIG5ldyB0cyhyKX1jb25zdHJ1Y3Rvcih0KXtjb25zdCBlPXQubGVuZ3RoPj4xO2lmKGU+MCYmdHlwZW9mIHRbMF0hPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcigiRXhwZWN0ZWQgY29vcmRzIHRvIGNvbnRhaW4gbnVtYmVycy4iKTt0aGlzLmNvb3Jkcz10O2NvbnN0IG49TWF0aC5tYXgoMiplLTUsMCk7dGhpcy5fdHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheShuKjMpLHRoaXMuX2hhbGZlZGdlcz1uZXcgSW50MzJBcnJheShuKjMpLHRoaXMuX2hhc2hTaXplPU1hdGguY2VpbChNYXRoLnNxcnQoZSkpLHRoaXMuX2h1bGxQcmV2PW5ldyBVaW50MzJBcnJheShlKSx0aGlzLl9odWxsTmV4dD1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbFRyaT1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbEhhc2g9bmV3IEludDMyQXJyYXkodGhpcy5faGFzaFNpemUpLmZpbGwoLTEpLHRoaXMuX2lkcz1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5fZGlzdHM9bmV3IEZsb2F0NjRBcnJheShlKSx0aGlzLnVwZGF0ZSgpfXVwZGF0ZSgpe2NvbnN0e2Nvb3Jkczp0LF9odWxsUHJldjplLF9odWxsTmV4dDpuLF9odWxsVHJpOnMsX2h1bGxIYXNoOnJ9PXRoaXMsbz10Lmxlbmd0aD4+MTtsZXQgYT0xLzAsYz0xLzAsbD0tMS8wLGg9LTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtjb25zdCB2PXRbMip6XSxDPXRbMip6KzFdO3Y8YSYmKGE9diksQzxjJiYoYz1DKSx2PmwmJihsPXYpLEM+aCYmKGg9QyksdGhpcy5faWRzW3pdPXp9Y29uc3QgdT0oYStsKS8yLGY9KGMraCkvMjtsZXQgZD0xLzAscCx5LG07Zm9yKGxldCB6PTA7ejxvO3orKyl7Y29uc3Qgdj10Yyh1LGYsdFsyKnpdLHRbMip6KzFdKTt2PGQmJihwPXosZD12KX1jb25zdCBnPXRbMipwXSxiPXRbMipwKzFdO2Q9MS8wO2ZvcihsZXQgej0wO3o8bzt6Kyspe2lmKHo9PT1wKWNvbnRpbnVlO2NvbnN0IHY9dGMoZyxiLHRbMip6XSx0WzIqeisxXSk7djxkJiZ2PjAmJih5PXosZD12KX1sZXQgdz10WzIqeV0seD10WzIqeSsxXSxNPTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtpZih6PT09cHx8ej09PXkpY29udGludWU7Y29uc3Qgdj1IeShnLGIsdyx4LHRbMip6XSx0WzIqeisxXSk7djxNJiYobT16LE09dil9bGV0IEE9dFsyKm1dLFM9dFsyKm0rMV07aWYoTT09PTEvMCl7Zm9yKGxldCBDPTA7QzxvO0MrKyl0aGlzLl9kaXN0c1tDXT10WzIqQ10tdFswXXx8dFsyKkMrMV0tdFsxXTtoaSh0aGlzLl9pZHMsdGhpcy5fZGlzdHMsMCxvLTEpO2NvbnN0IHo9bmV3IFVpbnQzMkFycmF5KG8pO2xldCB2PTA7Zm9yKGxldCBDPTAsUD0tMS8wO0M8bztDKyspe2NvbnN0IEY9dGhpcy5faWRzW0NdO3RoaXMuX2Rpc3RzW0ZdPlAmJih6W3YrK109RixQPXRoaXMuX2Rpc3RzW0ZdKX10aGlzLmh1bGw9ei5zdWJhcnJheSgwLHYpLHRoaXMudHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheSgwKSx0aGlzLmhhbGZlZGdlcz1uZXcgVWludDMyQXJyYXkoMCk7cmV0dXJufWlmKExyKGcsYix3LHgsQSxTKTwwKXtjb25zdCB6PXksdj13LEM9eDt5PW0sdz1BLHg9UyxtPXosQT12LFM9Q31jb25zdCBfPVd5KGcsYix3LHgsQSxTKTt0aGlzLl9jeD1fLngsdGhpcy5fY3k9Xy55O2ZvcihsZXQgej0wO3o8bzt6KyspdGhpcy5fZGlzdHNbel09dGModFsyKnpdLHRbMip6KzFdLF8ueCxfLnkpO2hpKHRoaXMuX2lkcyx0aGlzLl9kaXN0cywwLG8tMSksdGhpcy5faHVsbFN0YXJ0PXA7bGV0IEU9MztuW3BdPWVbbV09eSxuW3ldPWVbcF09bSxuW21dPWVbeV09cCxzW3BdPTAsc1t5XT0xLHNbbV09MixyLmZpbGwoLTEpLHJbdGhpcy5faGFzaEtleShnLGIpXT1wLHJbdGhpcy5faGFzaEtleSh3LHgpXT15LHJbdGhpcy5faGFzaEtleShBLFMpXT1tLHRoaXMudHJpYW5nbGVzTGVuPTAsdGhpcy5fYWRkVHJpYW5nbGUocCx5LG0sLTEsLTEsLTEpO2ZvcihsZXQgej0wLHYsQzt6PHRoaXMuX2lkcy5sZW5ndGg7eisrKXtjb25zdCBQPXRoaXMuX2lkc1t6XSxGPXRbMipQXSxCPXRbMipQKzFdO2lmKHo+MCYmTWF0aC5hYnMoRi12KTw9bnUmJk1hdGguYWJzKEItQyk8PW51fHwodj1GLEM9QixQPT09cHx8UD09PXl8fFA9PT1tKSljb250aW51ZTtsZXQgST0wO2ZvcihsZXQgZHQ9MCxEdD10aGlzLl9oYXNoS2V5KEYsQik7ZHQ8dGhpcy5faGFzaFNpemUmJihJPXJbKER0K2R0KSV0aGlzLl9oYXNoU2l6ZV0sIShJIT09LTEmJkkhPT1uW0ldKSk7ZHQrKyk7ST1lW0ldO2xldCBrPUksRDtmb3IoO0Q9bltrXSxMcihGLEIsdFsyKmtdLHRbMiprKzFdLHRbMipEXSx0WzIqRCsxXSk+PTA7KWlmKGs9RCxrPT09SSl7az0tMTticmVha31pZihrPT09LTEpY29udGludWU7bGV0IFU9dGhpcy5fYWRkVHJpYW5nbGUoayxQLG5ba10sLTEsLTEsc1trXSk7c1tQXT10aGlzLl9sZWdhbGl6ZShVKzIpLHNba109VSxFKys7bGV0IGo9bltrXTtmb3IoO0Q9bltqXSxMcihGLEIsdFsyKmpdLHRbMipqKzFdLHRbMipEXSx0WzIqRCsxXSk8MDspVT10aGlzLl9hZGRUcmlhbmdsZShqLFAsRCxzW1BdLC0xLHNbal0pLHNbUF09dGhpcy5fbGVnYWxpemUoVSsyKSxuW2pdPWosRS0tLGo9RDtpZihrPT09SSlmb3IoO0Q9ZVtrXSxMcihGLEIsdFsyKkRdLHRbMipEKzFdLHRbMiprXSx0WzIqaysxXSk8MDspVT10aGlzLl9hZGRUcmlhbmdsZShELFAsaywtMSxzW2tdLHNbRF0pLHRoaXMuX2xlZ2FsaXplKFUrMiksc1tEXT1VLG5ba109ayxFLS0saz1EO3RoaXMuX2h1bGxTdGFydD1lW1BdPWssbltrXT1lW2pdPVAsbltQXT1qLHJbdGhpcy5faGFzaEtleShGLEIpXT1QLHJbdGhpcy5faGFzaEtleSh0WzIqa10sdFsyKmsrMV0pXT1rfXRoaXMuaHVsbD1uZXcgVWludDMyQXJyYXkoRSk7Zm9yKGxldCB6PTAsdj10aGlzLl9odWxsU3RhcnQ7ejxFO3orKyl0aGlzLmh1bGxbel09dix2PW5bdl07dGhpcy50cmlhbmdsZXM9dGhpcy5fdHJpYW5nbGVzLnN1YmFycmF5KDAsdGhpcy50cmlhbmdsZXNMZW4pLHRoaXMuaGFsZmVkZ2VzPXRoaXMuX2hhbGZlZGdlcy5zdWJhcnJheSgwLHRoaXMudHJpYW5nbGVzTGVuKX1faGFzaEtleSh0LGUpe3JldHVybiBNYXRoLmZsb29yKFV5KHQtdGhpcy5fY3gsZS10aGlzLl9jeSkqdGhpcy5faGFzaFNpemUpJXRoaXMuX2hhc2hTaXplfV9sZWdhbGl6ZSh0KXtjb25zdHtfdHJpYW5nbGVzOmUsX2hhbGZlZGdlczpuLGNvb3JkczpzfT10aGlzO2xldCByPTAsbz0wO2Zvcig7Oyl7Y29uc3QgYT1uW3RdLGM9dC10JTM7aWYobz1jKyh0KzIpJTMsYT09PS0xKXtpZihyPT09MClicmVhazt0PU9yWy0tcl07Y29udGludWV9Y29uc3QgbD1hLWElMyxoPWMrKHQrMSklMyx1PWwrKGErMiklMyxmPWVbb10sZD1lW3RdLHA9ZVtoXSx5PWVbdV07aWYocXkoc1syKmZdLHNbMipmKzFdLHNbMipkXSxzWzIqZCsxXSxzWzIqcF0sc1syKnArMV0sc1syKnldLHNbMip5KzFdKSl7ZVt0XT15LGVbYV09Zjtjb25zdCBnPW5bdV07aWYoZz09PS0xKXtsZXQgdz10aGlzLl9odWxsU3RhcnQ7ZG97aWYodGhpcy5faHVsbFRyaVt3XT09PXUpe3RoaXMuX2h1bGxUcmlbd109dDticmVha313PXRoaXMuX2h1bGxQcmV2W3ddfXdoaWxlKHchPT10aGlzLl9odWxsU3RhcnQpfXRoaXMuX2xpbmsodCxnKSx0aGlzLl9saW5rKGEsbltvXSksdGhpcy5fbGluayhvLHUpO2NvbnN0IGI9bCsoYSsxKSUzO3I8T3IubGVuZ3RoJiYoT3JbcisrXT1iKX1lbHNle2lmKHI9PT0wKWJyZWFrO3Q9T3JbLS1yXX19cmV0dXJuIG99X2xpbmsodCxlKXt0aGlzLl9oYWxmZWRnZXNbdF09ZSxlIT09LTEmJih0aGlzLl9oYWxmZWRnZXNbZV09dCl9X2FkZFRyaWFuZ2xlKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMudHJpYW5nbGVzTGVuO3JldHVybiB0aGlzLl90cmlhbmdsZXNbYV09dCx0aGlzLl90cmlhbmdsZXNbYSsxXT1lLHRoaXMuX3RyaWFuZ2xlc1thKzJdPW4sdGhpcy5fbGluayhhLHMpLHRoaXMuX2xpbmsoYSsxLHIpLHRoaXMuX2xpbmsoYSsyLG8pLHRoaXMudHJpYW5nbGVzTGVuKz0zLGF9fWZ1bmN0aW9uIFV5KGksdCl7Y29uc3QgZT1pLyhNYXRoLmFicyhpKStNYXRoLmFicyh0KSk7cmV0dXJuKHQ+MD8zLWU6MStlKS80fWZ1bmN0aW9uIHRjKGksdCxlLG4pe2NvbnN0IHM9aS1lLHI9dC1uO3JldHVybiBzKnMrcipyfWZ1bmN0aW9uIHF5KGksdCxlLG4scyxyLG8sYSl7Y29uc3QgYz1pLW8sbD10LWEsaD1lLW8sdT1uLWEsZj1zLW8sZD1yLWEscD1jKmMrbCpsLHk9aCpoK3UqdSxtPWYqZitkKmQ7cmV0dXJuIGMqKHUqbS15KmQpLWwqKGgqbS15KmYpK3AqKGgqZC11KmYpPDB9ZnVuY3Rpb24gSHkoaSx0LGUsbixzLHIpe2NvbnN0IG89ZS1pLGE9bi10LGM9cy1pLGw9ci10LGg9bypvK2EqYSx1PWMqYytsKmwsZj0uNS8obypsLWEqYyksZD0obCpoLWEqdSkqZixwPShvKnUtYypoKSpmO3JldHVybiBkKmQrcCpwfWZ1bmN0aW9uIFd5KGksdCxlLG4scyxyKXtjb25zdCBvPWUtaSxhPW4tdCxjPXMtaSxsPXItdCxoPW8qbythKmEsdT1jKmMrbCpsLGY9LjUvKG8qbC1hKmMpLGQ9aSsobCpoLWEqdSkqZixwPXQrKG8qdS1jKmgpKmY7cmV0dXJue3g6ZCx5OnB9fWZ1bmN0aW9uIGhpKGksdCxlLG4pe2lmKG4tZTw9MjApZm9yKGxldCBzPWUrMTtzPD1uO3MrKyl7Y29uc3Qgcj1pW3NdLG89dFtyXTtsZXQgYT1zLTE7Zm9yKDthPj1lJiZ0W2lbYV1dPm87KWlbYSsxXT1pW2EtLV07aVthKzFdPXJ9ZWxzZXtjb25zdCBzPWUrbj4+MTtsZXQgcj1lKzEsbz1uO2VzKGkscyxyKSx0W2lbZV1dPnRbaVtuXV0mJmVzKGksZSxuKSx0W2lbcl1dPnRbaVtuXV0mJmVzKGkscixuKSx0W2lbZV1dPnRbaVtyXV0mJmVzKGksZSxyKTtjb25zdCBhPWlbcl0sYz10W2FdO2Zvcig7Oyl7ZG8gcisrO3doaWxlKHRbaVtyXV08Yyk7ZG8gby0tO3doaWxlKHRbaVtvXV0+Yyk7aWYobzxyKWJyZWFrO2VzKGkscixvKX1pW2UrMV09aVtvXSxpW29dPWEsbi1yKzE+PW8tZT8oaGkoaSx0LHIsbiksaGkoaSx0LGUsby0xKSk6KGhpKGksdCxlLG8tMSksaGkoaSx0LHIsbikpfX1mdW5jdGlvbiBlcyhpLHQsZSl7Y29uc3Qgbj1pW3RdO2lbdF09aVtlXSxpW2VdPW59ZnVuY3Rpb24gR3koaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gWnkoaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gWHkoaSx0KXt2YXIgZT0wLG49MCxzPTAscj0wLG89MCxhPTAsYz0wLGw9MCxoPW51bGwsdT1udWxsLGY9aVswXSxkPWlbMV0scD10Lmxlbmd0aDtmb3IoZTtlPHA7ZSsrKXtuPTA7dmFyIHk9dFtlXS5sZW5ndGgtMSxtPXRbZV07aWYoaD1tWzBdLGhbMF0hPT1tW3ldWzBdJiZoWzFdIT09bVt5XVsxXSl0aHJvdyBuZXcgRXJyb3IoIkZpcnN0IGFuZCBsYXN0IGNvb3JkaW5hdGVzIGluIGEgcmluZyBtdXN0IGJlIHRoZSBzYW1lIik7Zm9yKG89aFswXS1mLGE9aFsxXS1kLG47bjx5O24rKyl7aWYodT1tW24rMV0sbD11WzFdLWQsYTwwJiZsPDB8fGE+MCYmbD4wKXtoPXUsYT1sLG89aFswXS1mO2NvbnRpbnVlfWlmKGM9dVswXS1pWzBdLGw+MCYmYTw9MCl7aWYocj1vKmwtYyphLHI+MClzPXMrMTtlbHNlIGlmKHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT4wJiZsPD0wKXtpZihyPW8qbC1jKmEscjwwKXM9cysxO2Vsc2UgaWYocj09PTApcmV0dXJuIDB9ZWxzZSBpZihsPT09MCYmYTwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbDwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbD09PTApe2lmKGM8PTAmJm8+PTApcmV0dXJuIDA7aWYobzw9MCYmYz49MClyZXR1cm4gMH1oPXUsYT1sLG89Y319cmV0dXJuIHMlMiE9PTB9ZnVuY3Rpb24gSnkoaSx0LGU9e30pe2lmKCFpKXRocm93IG5ldyBFcnJvcigicG9pbnQgaXMgcmVxdWlyZWQiKTtpZighdCl0aHJvdyBuZXcgRXJyb3IoInBvbHlnb24gaXMgcmVxdWlyZWQiKTtjb25zdCBuPUJ5KGkpLHM9SXkodCkscj1zLnR5cGUsbz10LmJib3g7bGV0IGE9cy5jb29yZGluYXRlcztpZihvJiZZeShuLG8pPT09ITEpcmV0dXJuITE7cj09PSJQb2x5Z29uIiYmKGE9W2FdKTtsZXQgYz0hMTtmb3IodmFyIGw9MDtsPGEubGVuZ3RoOysrbCl7Y29uc3QgaD1YeShuLGFbbF0pO2lmKGg9PT0wKXJldHVybiFlLmlnbm9yZUJvdW5kYXJ5O2gmJihjPSEwKX1yZXR1cm4gY31mdW5jdGlvbiBZeShpLHQpe3JldHVybiB0WzBdPD1pWzBdJiZ0WzFdPD1pWzFdJiZ0WzJdPj1pWzBdJiZ0WzNdPj1pWzFdfXZhciBqeT1KeTtjb25zdCBpdT0xZS02O2NsYXNzIHpue2NvbnN0cnVjdG9yKCl7dGhpcy5feDA9dGhpcy5feTA9dGhpcy5feDE9dGhpcy5feTE9bnVsbCx0aGlzLl89IiJ9bW92ZVRvKHQsZSl7dGhpcy5fKz1gTSR7dGhpcy5feDA9dGhpcy5feDE9K3R9LCR7dGhpcy5feTA9dGhpcy5feTE9K2V9YH1jbG9zZVBhdGgoKXt0aGlzLl94MSE9PW51bGwmJih0aGlzLl94MT10aGlzLl94MCx0aGlzLl95MT10aGlzLl95MCx0aGlzLl8rPSJaIil9bGluZVRvKHQsZSl7dGhpcy5fKz1gTCR7dGhpcy5feDE9K3R9LCR7dGhpcy5feTE9K2V9YH1hcmModCxlLG4pe3Q9K3QsZT0rZSxuPStuO2NvbnN0IHM9dCtuLHI9ZTtpZihuPDApdGhyb3cgbmV3IEVycm9yKCJuZWdhdGl2ZSByYWRpdXMiKTt0aGlzLl94MT09PW51bGw/dGhpcy5fKz1gTSR7c30sJHtyfWA6KE1hdGguYWJzKHRoaXMuX3gxLXMpPml1fHxNYXRoLmFicyh0aGlzLl95MS1yKT5pdSkmJih0aGlzLl8rPSJMIitzKyIsIityKSxuJiYodGhpcy5fKz1gQSR7bn0sJHtufSwwLDEsMSwke3Qtbn0sJHtlfUEke259LCR7bn0sMCwxLDEsJHt0aGlzLl94MT1zfSwke3RoaXMuX3kxPXJ9YCl9cmVjdCh0LGUsbixzKXt0aGlzLl8rPWBNJHt0aGlzLl94MD10aGlzLl94MT0rdH0sJHt0aGlzLl95MD10aGlzLl95MT0rZX1oJHsrbn12JHsrc31oJHstbn1aYH12YWx1ZSgpe3JldHVybiB0aGlzLl98fG51bGx9fWNsYXNzIGVje2NvbnN0cnVjdG9yKCl7dGhpcy5fPVtdfW1vdmVUbyh0LGUpe3RoaXMuXy5wdXNoKFt0LGVdKX1jbG9zZVBhdGgoKXt0aGlzLl8ucHVzaCh0aGlzLl9bMF0uc2xpY2UoKSl9bGluZVRvKHQsZSl7dGhpcy5fLnB1c2goW3QsZV0pfXZhbHVlKCl7cmV0dXJuIHRoaXMuXy5sZW5ndGg/dGhpcy5fOm51bGx9fWNsYXNzIFF5e2NvbnN0cnVjdG9yKHQsW2UsbixzLHJdPVswLDAsOTYwLDUwMF0pe2lmKCEoKHM9K3MpPj0oZT0rZSkpfHwhKChyPStyKT49KG49K24pKSl0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgYm91bmRzIik7dGhpcy5kZWxhdW5heT10LHRoaXMuX2NpcmN1bWNlbnRlcnM9bmV3IEZsb2F0NjRBcnJheSh0LnBvaW50cy5sZW5ndGgqMiksdGhpcy52ZWN0b3JzPW5ldyBGbG9hdDY0QXJyYXkodC5wb2ludHMubGVuZ3RoKjIpLHRoaXMueG1heD1zLHRoaXMueG1pbj1lLHRoaXMueW1heD1yLHRoaXMueW1pbj1uLHRoaXMuX2luaXQoKX11cGRhdGUoKXtyZXR1cm4gdGhpcy5kZWxhdW5heS51cGRhdGUoKSx0aGlzLl9pbml0KCksdGhpc31faW5pdCgpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dCxodWxsOmUsdHJpYW5nbGVzOm59LHZlY3RvcnM6c309dGhpcyxyPXRoaXMuY2lyY3VtY2VudGVycz10aGlzLl9jaXJjdW1jZW50ZXJzLnN1YmFycmF5KDAsbi5sZW5ndGgvMyoyKTtmb3IobGV0IGQ9MCxwPTAseT1uLmxlbmd0aCxtLGc7ZDx5O2QrPTMscCs9Mil7Y29uc3QgYj1uW2RdKjIsdz1uW2QrMV0qMix4PW5bZCsyXSoyLE09dFtiXSxBPXRbYisxXSxTPXRbd10sXz10W3crMV0sRT10W3hdLHo9dFt4KzFdLHY9Uy1NLEM9Xy1BLFA9RS1NLEY9ei1BLEI9KHYqRi1DKlApKjI7aWYoTWF0aC5hYnMoQik8MWUtOSl7bGV0IEk9MWU5O2NvbnN0IGs9blswXSoyO0kqPU1hdGguc2lnbigodFtrXS1NKSpGLSh0W2srMV0tQSkqUCksbT0oTStFKS8yLUkqRixnPShBK3opLzIrSSpQfWVsc2V7Y29uc3QgST0xL0Isaz12KnYrQypDLEQ9UCpQK0YqRjttPU0rKEYqay1DKkQpKkksZz1BKyh2KkQtUCprKSpJfXJbcF09bSxyW3ArMV09Z31sZXQgbz1lW2UubGVuZ3RoLTFdLGEsYz1vKjQsbCxoPXRbMipvXSx1LGY9dFsyKm8rMV07cy5maWxsKDApO2ZvcihsZXQgZD0wO2Q8ZS5sZW5ndGg7KytkKW89ZVtkXSxhPWMsbD1oLHU9ZixjPW8qNCxoPXRbMipvXSxmPXRbMipvKzFdLHNbYSsyXT1zW2NdPXUtZixzW2ErM109c1tjKzFdPWgtbH1yZW5kZXIodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7ZGVsYXVuYXk6e2hhbGZlZGdlczpuLGluZWRnZXM6cyxodWxsOnJ9LGNpcmN1bWNlbnRlcnM6byx2ZWN0b3JzOmF9PXRoaXM7aWYoci5sZW5ndGg8PTEpcmV0dXJuIG51bGw7Zm9yKGxldCBoPTAsdT1uLmxlbmd0aDtoPHU7KytoKXtjb25zdCBmPW5baF07aWYoZjxoKWNvbnRpbnVlO2NvbnN0IGQ9TWF0aC5mbG9vcihoLzMpKjIscD1NYXRoLmZsb29yKGYvMykqMix5PW9bZF0sbT1vW2QrMV0sZz1vW3BdLGI9b1twKzFdO3RoaXMuX3JlbmRlclNlZ21lbnQoeSxtLGcsYix0KX1sZXQgYyxsPXJbci5sZW5ndGgtMV07Zm9yKGxldCBoPTA7aDxyLmxlbmd0aDsrK2gpe2M9bCxsPXJbaF07Y29uc3QgdT1NYXRoLmZsb29yKHNbbF0vMykqMixmPW9bdV0sZD1vW3UrMV0scD1jKjQseT10aGlzLl9wcm9qZWN0KGYsZCxhW3ArMl0sYVtwKzNdKTt5JiZ0aGlzLl9yZW5kZXJTZWdtZW50KGYsZCx5WzBdLHlbMV0sdCl9cmV0dXJuIGUmJmUudmFsdWUoKX1yZW5kZXJCb3VuZHModCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMDtyZXR1cm4gdC5yZWN0KHRoaXMueG1pbix0aGlzLnltaW4sdGhpcy54bWF4LXRoaXMueG1pbix0aGlzLnltYXgtdGhpcy55bWluKSxlJiZlLnZhbHVlKCl9cmVuZGVyQ2VsbCh0LGUpe2NvbnN0IG49ZT09bnVsbD9lPW5ldyB6bjp2b2lkIDAscz10aGlzLl9jbGlwKHQpO2lmKHM9PT1udWxsfHwhcy5sZW5ndGgpcmV0dXJuO2UubW92ZVRvKHNbMF0sc1sxXSk7bGV0IHI9cy5sZW5ndGg7Zm9yKDtzWzBdPT09c1tyLTJdJiZzWzFdPT09c1tyLTFdJiZyPjE7KXItPTI7Zm9yKGxldCBvPTI7bzxyO28rPTIpKHNbb10hPT1zW28tMl18fHNbbysxXSE9PXNbby0xXSkmJmUubGluZVRvKHNbb10sc1tvKzFdKTtyZXR1cm4gZS5jbG9zZVBhdGgoKSxuJiZuLnZhbHVlKCl9KmNlbGxQb2x5Z29ucygpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dH19PXRoaXM7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aC8yO2U8bjsrK2Upe2NvbnN0IHM9dGhpcy5jZWxsUG9seWdvbihlKTtzJiYocy5pbmRleD1lLHlpZWxkIHMpfX1jZWxsUG9seWdvbih0KXtjb25zdCBlPW5ldyBlYztyZXR1cm4gdGhpcy5yZW5kZXJDZWxsKHQsZSksZS52YWx1ZSgpfV9yZW5kZXJTZWdtZW50KHQsZSxuLHMscil7bGV0IG87Y29uc3QgYT10aGlzLl9yZWdpb25jb2RlKHQsZSksYz10aGlzLl9yZWdpb25jb2RlKG4scyk7YT09PTAmJmM9PT0wPyhyLm1vdmVUbyh0LGUpLHIubGluZVRvKG4scykpOihvPXRoaXMuX2NsaXBTZWdtZW50KHQsZSxuLHMsYSxjKSkmJihyLm1vdmVUbyhvWzBdLG9bMV0pLHIubGluZVRvKG9bMl0sb1szXSkpfWNvbnRhaW5zKHQsZSxuKXtyZXR1cm4gZT0rZSxlIT09ZXx8KG49K24sbiE9PW4pPyExOnRoaXMuZGVsYXVuYXkuX3N0ZXAodCxlLG4pPT09dH0qbmVpZ2hib3JzKHQpe2NvbnN0IGU9dGhpcy5fY2xpcCh0KTtpZihlKWZvcihjb25zdCBuIG9mIHRoaXMuZGVsYXVuYXkubmVpZ2hib3JzKHQpKXtjb25zdCBzPXRoaXMuX2NsaXAobik7aWYocyl7dDpmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKz0yKWZvcihsZXQgYT0wLGM9cy5sZW5ndGg7YTxjO2ErPTIpaWYoZVtyXT09c1thXSYmZVtyKzFdPT1zW2ErMV0mJmVbKHIrMiklb109PXNbKGErYy0yKSVjXSYmZVsociszKSVvXT09c1soYStjLTEpJWNdKXt5aWVsZCBuO2JyZWFrIHR9fX19X2NlbGwodCl7Y29uc3R7Y2lyY3VtY2VudGVyczplLGRlbGF1bmF5OntpbmVkZ2VzOm4saGFsZmVkZ2VzOnMsdHJpYW5nbGVzOnJ9fT10aGlzLG89blt0XTtpZihvPT09LTEpcmV0dXJuIG51bGw7Y29uc3QgYT1bXTtsZXQgYz1vO2Rve2NvbnN0IGw9TWF0aC5mbG9vcihjLzMpO2lmKGEucHVzaChlW2wqMl0sZVtsKjIrMV0pLGM9YyUzPT09Mj9jLTI6YysxLHJbY10hPT10KWJyZWFrO2M9c1tjXX13aGlsZShjIT09byYmYyE9PS0xKTtyZXR1cm4gYX1fY2xpcCh0KXtpZih0PT09MCYmdGhpcy5kZWxhdW5heS5odWxsLmxlbmd0aD09PTEpcmV0dXJuW3RoaXMueG1heCx0aGlzLnltaW4sdGhpcy54bWF4LHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltaW5dO2NvbnN0IGU9dGhpcy5fY2VsbCh0KTtpZihlPT09bnVsbClyZXR1cm4gbnVsbDtjb25zdHt2ZWN0b3JzOm59PXRoaXMscz10KjQ7cmV0dXJuIG5bc118fG5bcysxXT90aGlzLl9jbGlwSW5maW5pdGUodCxlLG5bc10sbltzKzFdLG5bcysyXSxuW3MrM10pOnRoaXMuX2NsaXBGaW5pdGUodCxlKX1fY2xpcEZpbml0ZSh0LGUpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHM9bnVsbCxyLG8sYT1lW24tMl0sYz1lW24tMV0sbCxoPXRoaXMuX3JlZ2lvbmNvZGUoYSxjKSx1LGY9MDtmb3IobGV0IGQ9MDtkPG47ZCs9MilpZihyPWEsbz1jLGE9ZVtkXSxjPWVbZCsxXSxsPWgsaD10aGlzLl9yZWdpb25jb2RlKGEsYyksbD09PTAmJmg9PT0wKXU9ZixmPTAscz9zLnB1c2goYSxjKTpzPVthLGNdO2Vsc2V7bGV0IHAseSxtLGcsYjtpZihsPT09MCl7aWYoKHA9dGhpcy5fY2xpcFNlZ21lbnQocixvLGEsYyxsLGgpKT09PW51bGwpY29udGludWU7W3ksbSxnLGJdPXB9ZWxzZXtpZigocD10aGlzLl9jbGlwU2VnbWVudChhLGMscixvLGgsbCkpPT09bnVsbCljb250aW51ZTtbZyxiLHksbV09cCx1PWYsZj10aGlzLl9lZGdlY29kZSh5LG0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCkscz9zLnB1c2goeSxtKTpzPVt5LG1dfXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGcsYiksdSYmZiYmdGhpcy5fZWRnZSh0LHUsZixzLHMubGVuZ3RoKSxzP3MucHVzaChnLGIpOnM9W2csYl19aWYocyl1PWYsZj10aGlzLl9lZGdlY29kZShzWzBdLHNbMV0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCk7ZWxzZSBpZih0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpKXJldHVyblt0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWluXTtyZXR1cm4gc31fY2xpcFNlZ21lbnQodCxlLG4scyxyLG8pe2Zvcig7Oyl7aWYocj09PTAmJm89PT0wKXJldHVyblt0LGUsbixzXTtpZihyJm8pcmV0dXJuIG51bGw7bGV0IGEsYyxsPXJ8fG87bCY4PyhhPXQrKG4tdCkqKHRoaXMueW1heC1lKS8ocy1lKSxjPXRoaXMueW1heCk6bCY0PyhhPXQrKG4tdCkqKHRoaXMueW1pbi1lKS8ocy1lKSxjPXRoaXMueW1pbik6bCYyPyhjPWUrKHMtZSkqKHRoaXMueG1heC10KS8obi10KSxhPXRoaXMueG1heCk6KGM9ZSsocy1lKSoodGhpcy54bWluLXQpLyhuLXQpLGE9dGhpcy54bWluKSxyPyh0PWEsZT1jLHI9dGhpcy5fcmVnaW9uY29kZSh0LGUpKToobj1hLHM9YyxvPXRoaXMuX3JlZ2lvbmNvZGUobixzKSl9fV9jbGlwSW5maW5pdGUodCxlLG4scyxyLG8pe2xldCBhPUFycmF5LmZyb20oZSksYztpZigoYz10aGlzLl9wcm9qZWN0KGFbMF0sYVsxXSxuLHMpKSYmYS51bnNoaWZ0KGNbMF0sY1sxXSksKGM9dGhpcy5fcHJvamVjdChhW2EubGVuZ3RoLTJdLGFbYS5sZW5ndGgtMV0scixvKSkmJmEucHVzaChjWzBdLGNbMV0pLGE9dGhpcy5fY2xpcEZpbml0ZSh0LGEpKWZvcihsZXQgbD0wLGg9YS5sZW5ndGgsdSxmPXRoaXMuX2VkZ2Vjb2RlKGFbaC0yXSxhW2gtMV0pO2w8aDtsKz0yKXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGFbbF0sYVtsKzFdKSx1JiZmJiYobD10aGlzLl9lZGdlKHQsdSxmLGEsbCksaD1hLmxlbmd0aCk7ZWxzZSB0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpJiYoYT1bdGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heF0pO3JldHVybiBhfV9lZGdlKHQsZSxuLHMscil7Zm9yKDtlIT09bjspe2xldCBvLGE7c3dpdGNoKGUpe2Nhc2UgNTplPTQ7Y29udGludWU7Y2FzZSA0OmU9NixvPXRoaXMueG1heCxhPXRoaXMueW1pbjticmVhaztjYXNlIDY6ZT0yO2NvbnRpbnVlO2Nhc2UgMjplPTEwLG89dGhpcy54bWF4LGE9dGhpcy55bWF4O2JyZWFrO2Nhc2UgMTA6ZT04O2NvbnRpbnVlO2Nhc2UgODplPTksbz10aGlzLnhtaW4sYT10aGlzLnltYXg7YnJlYWs7Y2FzZSA5OmU9MTtjb250aW51ZTtjYXNlIDE6ZT01LG89dGhpcy54bWluLGE9dGhpcy55bWluO2JyZWFrfShzW3JdIT09b3x8c1tyKzFdIT09YSkmJnRoaXMuY29udGFpbnModCxvLGEpJiYocy5zcGxpY2UociwwLG8sYSkscis9Mil9aWYocy5sZW5ndGg+NClmb3IobGV0IG89MDtvPHMubGVuZ3RoO28rPTIpe2NvbnN0IGE9KG8rMiklcy5sZW5ndGgsYz0obys0KSVzLmxlbmd0aDsoc1tvXT09PXNbYV0mJnNbYV09PT1zW2NdfHxzW28rMV09PT1zW2ErMV0mJnNbYSsxXT09PXNbYysxXSkmJihzLnNwbGljZShhLDIpLG8tPTIpfXJldHVybiByfV9wcm9qZWN0KHQsZSxuLHMpe2xldCByPTEvMCxvLGEsYztpZihzPDApe2lmKGU8PXRoaXMueW1pbilyZXR1cm4gbnVsbDsobz0odGhpcy55bWluLWUpL3MpPHImJihjPXRoaXMueW1pbixhPXQrKHI9bykqbil9ZWxzZSBpZihzPjApe2lmKGU+PXRoaXMueW1heClyZXR1cm4gbnVsbDsobz0odGhpcy55bWF4LWUpL3MpPHImJihjPXRoaXMueW1heCxhPXQrKHI9bykqbil9aWYobj4wKXtpZih0Pj10aGlzLnhtYXgpcmV0dXJuIG51bGw7KG89KHRoaXMueG1heC10KS9uKTxyJiYoYT10aGlzLnhtYXgsYz1lKyhyPW8pKnMpfWVsc2UgaWYobjwwKXtpZih0PD10aGlzLnhtaW4pcmV0dXJuIG51bGw7KG89KHRoaXMueG1pbi10KS9uKTxyJiYoYT10aGlzLnhtaW4sYz1lKyhyPW8pKnMpfXJldHVyblthLGNdfV9lZGdlY29kZSh0LGUpe3JldHVybih0PT09dGhpcy54bWluPzE6dD09PXRoaXMueG1heD8yOjApfChlPT09dGhpcy55bWluPzQ6ZT09PXRoaXMueW1heD84OjApfV9yZWdpb25jb2RlKHQsZSl7cmV0dXJuKHQ8dGhpcy54bWluPzE6dD50aGlzLnhtYXg/MjowKXwoZTx0aGlzLnltaW4/NDplPnRoaXMueW1heD84OjApfX1jb25zdCBLeT0yKk1hdGguUEksdWk9TWF0aC5wb3c7ZnVuY3Rpb24gdG0oaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gZW0oaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gbm0oaSl7Y29uc3R7dHJpYW5nbGVzOnQsY29vcmRzOmV9PWk7Zm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKz0zKXtjb25zdCBzPTIqdFtuXSxyPTIqdFtuKzFdLG89Mip0W24rMl07aWYoKGVbb10tZVtzXSkqKGVbcisxXS1lW3MrMV0pLShlW3JdLWVbc10pKihlW28rMV0tZVtzKzFdKT4xZS0xMClyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBpbShpLHQsZSl7cmV0dXJuW2krTWF0aC5zaW4oaSt0KSplLHQrTWF0aC5jb3MoaS10KSplXX1jbGFzcyBuY3tzdGF0aWMgZnJvbSh0LGU9dG0sbj1lbSxzKXtyZXR1cm4gbmV3IG5jKCJsZW5ndGgiaW4gdD9zbSh0LGUsbixzKTpGbG9hdDY0QXJyYXkuZnJvbShybSh0LGUsbixzKSkpfWNvbnN0cnVjdG9yKHQpe3RoaXMuX2RlbGF1bmF0b3I9bmV3IHRzKHQpLHRoaXMuaW5lZGdlcz1uZXcgSW50MzJBcnJheSh0Lmxlbmd0aC8yKSx0aGlzLl9odWxsSW5kZXg9bmV3IEludDMyQXJyYXkodC5sZW5ndGgvMiksdGhpcy5wb2ludHM9dGhpcy5fZGVsYXVuYXRvci5jb29yZHMsdGhpcy5faW5pdCgpfXVwZGF0ZSgpe3JldHVybiB0aGlzLl9kZWxhdW5hdG9yLnVwZGF0ZSgpLHRoaXMuX2luaXQoKSx0aGlzfV9pbml0KCl7Y29uc3QgdD10aGlzLl9kZWxhdW5hdG9yLGU9dGhpcy5wb2ludHM7aWYodC5odWxsJiZ0Lmh1bGwubGVuZ3RoPjImJm5tKHQpKXt0aGlzLmNvbGxpbmVhcj1JbnQzMkFycmF5LmZyb20oe2xlbmd0aDplLmxlbmd0aC8yfSwoZixkKT0+ZCkuc29ydCgoZixkKT0+ZVsyKmZdLWVbMipkXXx8ZVsyKmYrMV0tZVsyKmQrMV0pO2NvbnN0IGM9dGhpcy5jb2xsaW5lYXJbMF0sbD10aGlzLmNvbGxpbmVhclt0aGlzLmNvbGxpbmVhci5sZW5ndGgtMV0saD1bZVsyKmNdLGVbMipjKzFdLGVbMipsXSxlWzIqbCsxXV0sdT0xZS04Kk1hdGguaHlwb3QoaFszXS1oWzFdLGhbMl0taFswXSk7Zm9yKGxldCBmPTAsZD1lLmxlbmd0aC8yO2Y8ZDsrK2Ype2NvbnN0IHA9aW0oZVsyKmZdLGVbMipmKzFdLHUpO2VbMipmXT1wWzBdLGVbMipmKzFdPXBbMV19dGhpcy5fZGVsYXVuYXRvcj1uZXcgdHMoZSl9ZWxzZSBkZWxldGUgdGhpcy5jb2xsaW5lYXI7Y29uc3Qgbj10aGlzLmhhbGZlZGdlcz10aGlzLl9kZWxhdW5hdG9yLmhhbGZlZGdlcyxzPXRoaXMuaHVsbD10aGlzLl9kZWxhdW5hdG9yLmh1bGwscj10aGlzLnRyaWFuZ2xlcz10aGlzLl9kZWxhdW5hdG9yLnRyaWFuZ2xlcyxvPXRoaXMuaW5lZGdlcy5maWxsKC0xKSxhPXRoaXMuX2h1bGxJbmRleC5maWxsKC0xKTtmb3IobGV0IGM9MCxsPW4ubGVuZ3RoO2M8bDsrK2Mpe2NvbnN0IGg9cltjJTM9PT0yP2MtMjpjKzFdOyhuW2NdPT09LTF8fG9baF09PT0tMSkmJihvW2hdPWMpfWZvcihsZXQgYz0wLGw9cy5sZW5ndGg7YzxsOysrYylhW3NbY11dPWM7cy5sZW5ndGg8PTImJnMubGVuZ3RoPjAmJih0aGlzLnRyaWFuZ2xlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLmhhbGZlZGdlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLnRyaWFuZ2xlc1swXT1zWzBdLG9bc1swXV09MSxzLmxlbmd0aD09PTImJihvW3NbMV1dPTAsdGhpcy50cmlhbmdsZXNbMV09c1sxXSx0aGlzLnRyaWFuZ2xlc1syXT1zWzFdKSl9dm9yb25vaSh0KXtyZXR1cm4gbmV3IFF5KHRoaXMsdCl9Km5laWdoYm9ycyh0KXtjb25zdHtpbmVkZ2VzOmUsaHVsbDpuLF9odWxsSW5kZXg6cyxoYWxmZWRnZXM6cix0cmlhbmdsZXM6byxjb2xsaW5lYXI6YX09dGhpcztpZihhKXtjb25zdCB1PWEuaW5kZXhPZih0KTt1PjAmJih5aWVsZCBhW3UtMV0pLHU8YS5sZW5ndGgtMSYmKHlpZWxkIGFbdSsxXSk7cmV0dXJufWNvbnN0IGM9ZVt0XTtpZihjPT09LTEpcmV0dXJuO2xldCBsPWMsaD0tMTtkb3tpZih5aWVsZCBoPW9bbF0sbD1sJTM9PT0yP2wtMjpsKzEsb1tsXSE9PXQpcmV0dXJuO2lmKGw9cltsXSxsPT09LTEpe2NvbnN0IHU9blsoc1t0XSsxKSVuLmxlbmd0aF07dSE9PWgmJih5aWVsZCB1KTtyZXR1cm59fXdoaWxlKGwhPT1jKX1maW5kKHQsZSxuPTApe2lmKHQ9K3QsdCE9PXR8fChlPStlLGUhPT1lKSlyZXR1cm4tMTtjb25zdCBzPW47bGV0IHI7Zm9yKDsocj10aGlzLl9zdGVwKG4sdCxlKSk+PTAmJnIhPT1uJiZyIT09czspbj1yO3JldHVybiByfV9zdGVwKHQsZSxuKXtjb25zdHtpbmVkZ2VzOnMsaHVsbDpyLF9odWxsSW5kZXg6byxoYWxmZWRnZXM6YSx0cmlhbmdsZXM6Yyxwb2ludHM6bH09dGhpcztpZihzW3RdPT09LTF8fCFsLmxlbmd0aClyZXR1cm4odCsxKSUobC5sZW5ndGg+PjEpO2xldCBoPXQsdT11aShlLWxbdCoyXSwyKSt1aShuLWxbdCoyKzFdLDIpO2NvbnN0IGY9c1t0XTtsZXQgZD1mO2Rve2xldCBwPWNbZF07Y29uc3QgeT11aShlLWxbcCoyXSwyKSt1aShuLWxbcCoyKzFdLDIpO2lmKHk8dSYmKHU9eSxoPXApLGQ9ZCUzPT09Mj9kLTI6ZCsxLGNbZF0hPT10KWJyZWFrO2lmKGQ9YVtkXSxkPT09LTEpe2lmKGQ9clsob1t0XSsxKSVyLmxlbmd0aF0sZCE9PXAmJnVpKGUtbFtkKjJdLDIpK3VpKG4tbFtkKjIrMV0sMik8dSlyZXR1cm4gZDticmVha319d2hpbGUoZCE9PWYpO3JldHVybiBofXJlbmRlcih0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgem46dm9pZCAwLHtwb2ludHM6bixoYWxmZWRnZXM6cyx0cmlhbmdsZXM6cn09dGhpcztmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTsrK28pe2NvbnN0IGM9c1tvXTtpZihjPG8pY29udGludWU7Y29uc3QgbD1yW29dKjIsaD1yW2NdKjI7dC5tb3ZlVG8obltsXSxuW2wrMV0pLHQubGluZVRvKG5baF0sbltoKzFdKX1yZXR1cm4gdGhpcy5yZW5kZXJIdWxsKHQpLGUmJmUudmFsdWUoKX1yZW5kZXJQb2ludHModCxlKXtlPT09dm9pZCAwJiYoIXR8fHR5cGVvZiB0Lm1vdmVUbyE9ImZ1bmN0aW9uIikmJihlPXQsdD1udWxsKSxlPWU9PW51bGw/MjorZTtjb25zdCBuPXQ9PW51bGw/dD1uZXcgem46dm9pZCAwLHtwb2ludHM6c309dGhpcztmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKz0yKXtjb25zdCBhPXNbcl0sYz1zW3IrMV07dC5tb3ZlVG8oYStlLGMpLHQuYXJjKGEsYyxlLDAsS3kpfXJldHVybiBuJiZuLnZhbHVlKCl9cmVuZGVySHVsbCh0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgem46dm9pZCAwLHtodWxsOm4scG9pbnRzOnN9PXRoaXMscj1uWzBdKjIsbz1uLmxlbmd0aDt0Lm1vdmVUbyhzW3JdLHNbcisxXSk7Zm9yKGxldCBhPTE7YTxvOysrYSl7Y29uc3QgYz0yKm5bYV07dC5saW5lVG8oc1tjXSxzW2MrMV0pfXJldHVybiB0LmNsb3NlUGF0aCgpLGUmJmUudmFsdWUoKX1odWxsUG9seWdvbigpe2NvbnN0IHQ9bmV3IGVjO3JldHVybiB0aGlzLnJlbmRlckh1bGwodCksdC52YWx1ZSgpfXJlbmRlclRyaWFuZ2xlKHQsZSl7Y29uc3Qgbj1lPT1udWxsP2U9bmV3IHpuOnZvaWQgMCx7cG9pbnRzOnMsdHJpYW5nbGVzOnJ9PXRoaXMsbz1yW3QqPTNdKjIsYT1yW3QrMV0qMixjPXJbdCsyXSoyO3JldHVybiBlLm1vdmVUbyhzW29dLHNbbysxXSksZS5saW5lVG8oc1thXSxzW2ErMV0pLGUubGluZVRvKHNbY10sc1tjKzFdKSxlLmNsb3NlUGF0aCgpLG4mJm4udmFsdWUoKX0qdHJpYW5nbGVQb2x5Z29ucygpe2NvbnN0e3RyaWFuZ2xlczp0fT10aGlzO2ZvcihsZXQgZT0wLG49dC5sZW5ndGgvMztlPG47KytlKXlpZWxkIHRoaXMudHJpYW5nbGVQb2x5Z29uKGUpfXRyaWFuZ2xlUG9seWdvbih0KXtjb25zdCBlPW5ldyBlYztyZXR1cm4gdGhpcy5yZW5kZXJUcmlhbmdsZSh0LGUpLGUudmFsdWUoKX19ZnVuY3Rpb24gc20oaSx0LGUsbil7Y29uc3Qgcz1pLmxlbmd0aCxyPW5ldyBGbG9hdDY0QXJyYXkocyoyKTtmb3IobGV0IG89MDtvPHM7KytvKXtjb25zdCBhPWlbb107cltvKjJdPXQuY2FsbChuLGEsbyxpKSxyW28qMisxXT1lLmNhbGwobixhLG8saSl9cmV0dXJuIHJ9ZnVuY3Rpb24qcm0oaSx0LGUsbil7bGV0IHM9MDtmb3IoY29uc3QgciBvZiBpKXlpZWxkIHQuY2FsbChuLHIscyxpKSx5aWVsZCBlLmNhbGwobixyLHMsaSksKytzfWNvbnN0IGljPU1hdGguUEksc3U9aWMvMixydT0xODAvaWMsb3U9aWMvMTgwLG9tPU1hdGguYXRhbjIsYXU9TWF0aC5jb3MsYW09TWF0aC5tYXgsY209TWF0aC5taW4sY3U9TWF0aC5zaW4sbG09TWF0aC5zaWdufHxmdW5jdGlvbihpKXtyZXR1cm4gaT4wPzE6aTwwPy0xOjB9LGx1PU1hdGguc3FydDtmdW5jdGlvbiBobShpKXtyZXR1cm4gaT4xP3N1Omk8LTE/LXN1Ok1hdGguYXNpbihpKX1mdW5jdGlvbiBodShpLHQpe3JldHVybiBpWzBdKnRbMF0raVsxXSp0WzFdK2lbMl0qdFsyXX1mdW5jdGlvbiBXdChpLHQpe3JldHVybltpWzFdKnRbMl0taVsyXSp0WzFdLGlbMl0qdFswXS1pWzBdKnRbMl0saVswXSp0WzFdLWlbMV0qdFswXV19ZnVuY3Rpb24gRHIoaSx0KXtyZXR1cm5baVswXSt0WzBdLGlbMV0rdFsxXSxpWzJdK3RbMl1dfWZ1bmN0aW9uICRyKGkpe3ZhciB0PWx1KGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtyZXR1cm5baVswXS90LGlbMV0vdCxpWzJdL3RdfWZ1bmN0aW9uIHNjKGkpe3JldHVybltvbShpWzFdLGlbMF0pKnJ1LGhtKGFtKC0xLGNtKDEsaVsyXSkpKSpydV19ZnVuY3Rpb24gTWUoaSl7Y29uc3QgdD1pWzBdKm91LGU9aVsxXSpvdSxuPWF1KGUpO3JldHVybltuKmF1KHQpLG4qY3UodCksY3UoZSldfWZ1bmN0aW9uIHJjKGkpe3JldHVybiBpPWkubWFwKHQ9Pk1lKHQpKSxodShpWzBdLFd0KGlbMl0saVsxXSkpfWZ1bmN0aW9uIHVtKGkpe2NvbnN0IHQ9ZG0oaSksZT15bSh0KSxuPXBtKGUsaSkscz1nbShlLGkubGVuZ3RoKSxyPWZtKHMsaSksbz1tbShlLGkpLHtwb2x5Z29uczphLGNlbnRlcnM6Y309eG0obyxlLGkpLGw9d20oYSksaD1NbShlLGkpLHU9Ym0obixlKTtyZXR1cm57ZGVsYXVuYXk6dCxlZGdlczpuLHRyaWFuZ2xlczplLGNlbnRlcnM6YyxuZWlnaGJvcnM6cyxwb2x5Z29uczphLG1lc2g6bCxodWxsOmgsdXJxdWhhcnQ6dSxmaW5kOnJ9fWZ1bmN0aW9uIGZtKGksdCl7ZnVuY3Rpb24gZShuLHMpe2xldCByPW5bMF0tc1swXSxvPW5bMV0tc1sxXSxhPW5bMl0tc1syXTtyZXR1cm4gcipyK28qbythKmF9cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtvPT09dm9pZCAwJiYobz0wKTtsZXQgYSxjLGw9bztjb25zdCBoPU1lKFtzLHJdKTtkbyBhPW8sbz1udWxsLGM9ZShoLE1lKHRbYV0pKSxpW2FdLmZvckVhY2godT0+e2xldCBmPWUoaCxNZSh0W3VdKSk7aWYoZjxjKXtjPWYsbz11LGw9dTtyZXR1cm59fSk7d2hpbGUobyE9PW51bGwpO3JldHVybiBsfX1mdW5jdGlvbiBkbShpKXtpZihpLmxlbmd0aDwyKXJldHVybnt9O2xldCB0PTA7Zm9yKDtpc05hTihpW3RdWzBdK2lbdF1bMV0pJiZ0Kys8aS5sZW5ndGg7KTtjb25zdCBlPVNoKGlbdF0pLG49aXkoKS50cmFuc2xhdGUoWzAsMF0pLnNjYWxlKDEpLnJvdGF0ZShlLmludmVydChbMTgwLDBdKSk7aT1pLm1hcChuKTtjb25zdCBzPVtdO2xldCByPTE7Zm9yKGxldCB1PTAsZj1pLmxlbmd0aDt1PGY7dSsrKXtsZXQgZD15aShpW3VdWzBdLDIpK3lpKGlbdV1bMV0sMik7IWlzRmluaXRlKGQpfHxkPjFlMzI/cy5wdXNoKHUpOmQ+ciYmKHI9ZCl9Y29uc3Qgbz0xZTYqbHUocik7cy5mb3JFYWNoKHU9PmlbdV09W28sMF0pLGkucHVzaChbMCxvXSksaS5wdXNoKFstbywwXSksaS5wdXNoKFswLC1vXSk7Y29uc3QgYT1uYy5mcm9tKGkpO2EucHJvamVjdGlvbj1uO2NvbnN0e3RyaWFuZ2xlczpjLGhhbGZlZGdlczpsLGluZWRnZXM6aH09YTtmb3IobGV0IHU9MCxmPWwubGVuZ3RoO3U8Zjt1KyspaWYobFt1XTwwKXtjb25zdCBkPXUlMz09Mj91LTI6dSsxLHA9dSUzPT0wP3UrMjp1LTEseT1sW2RdLG09bFtwXTtsW3ldPW0sbFttXT15LGxbZF09bFtwXT0tMSxjW3VdPWNbZF09Y1twXT10LGhbY1t5XV09eSUzPT0wP3krMjp5LTEsaFtjW21dXT1tJTM9PTA/bSsyOm0tMSx1Kz0yLXUlM31lbHNlIGNbdV0+aS5sZW5ndGgtMy0xJiYoY1t1XT10KTtyZXR1cm4gYX1mdW5jdGlvbiBwbShpLHQpe2NvbnN0IGU9bmV3IFNldDtyZXR1cm4gdC5sZW5ndGg9PT0yP1tbMCwxXV06KGkuZm9yRWFjaChuPT57aWYoblswXSE9PW5bMV0mJiEocmMobi5tYXAocz0+dFtzXSkpPDApKWZvcihsZXQgcz0wLHI7czwzO3MrKylyPShzKzEpJTMsZS5hZGQoc3IoW25bc10sbltyXV0pLmpvaW4oIi0iKSl9KSxBcnJheS5mcm9tKGUsbj0+bi5zcGxpdCgiLSIpLm1hcChOdW1iZXIpKSl9ZnVuY3Rpb24geW0oaSl7Y29uc3R7dHJpYW5nbGVzOnR9PWk7aWYoIXQpcmV0dXJuW107Y29uc3QgZT1bXTtmb3IobGV0IG49MCxzPXQubGVuZ3RoLzM7bjxzO24rKyl7Y29uc3Qgcj10WzMqbl0sbz10WzMqbisxXSxhPXRbMypuKzJdO3IhPT1vJiZvIT09YSYmZS5wdXNoKFtyLGEsb10pfXJldHVybiBlfWZ1bmN0aW9uIG1tKGksdCl7cmV0dXJuIGkubWFwKGU9Pntjb25zdCBuPWUubWFwKHI9PnRbcl0pLm1hcChNZSkscz1EcihEcihXdChuWzFdLG5bMF0pLFd0KG5bMl0sblsxXSkpLFd0KG5bMF0sblsyXSkpO3JldHVybiBzYygkcihzKSl9KX1mdW5jdGlvbiBnbShpLHQpe2NvbnN0IGU9W107cmV0dXJuIGkuZm9yRWFjaChuPT57Zm9yKGxldCBzPTA7czwzO3MrKyl7Y29uc3Qgcj1uW3NdLG89blsocysxKSUzXTtlW3JdPWVbcl18fFtdLGVbcl0ucHVzaChvKX19KSxpLmxlbmd0aD09PTAmJih0PT09Mj8oZVswXT1bMV0sZVsxXT1bMF0pOnQ9PT0xJiYoZVswXT1bXSkpLGV9ZnVuY3Rpb24geG0oaSx0LGUpe2NvbnN0IG49W10scz1pLnNsaWNlKCk7aWYodC5sZW5ndGg9PT0wKXtpZihlLmxlbmd0aDwyKXJldHVybntwb2x5Z29uczpuLGNlbnRlcnM6c307aWYoZS5sZW5ndGg9PT0yKXtjb25zdCBhPU1lKGVbMF0pLGM9TWUoZVsxXSksbD0kcihEcihhLGMpKSxoPSRyKFd0KGEsYykpLHU9V3QobCxoKSxmPVtsLFd0KGwsdSksV3QoV3QobCx1KSx1KSxXdChXdChXdChsLHUpLHUpLHUpXS5tYXAoc2MpLm1hcChvKTtyZXR1cm4gbi5wdXNoKGYpLG4ucHVzaChmLnNsaWNlKCkucmV2ZXJzZSgpKSx7cG9seWdvbnM6bixjZW50ZXJzOnN9fX10LmZvckVhY2goKGEsYyk9Pntmb3IobGV0IGw9MDtsPDM7bCsrKXtjb25zdCBoPWFbbF0sdT1hWyhsKzEpJTNdLGY9YVsobCsyKSUzXTtuW2hdPW5baF18fFtdLG5baF0ucHVzaChbdSxmLGMsW2gsdSxmXV0pfX0pO2NvbnN0IHI9bi5tYXAoYT0+e2NvbnN0IGM9W2FbMF1bMl1dO2xldCBsPWFbMF1bMV07Zm9yKGxldCBoPTE7aDxhLmxlbmd0aDtoKyspZm9yKGxldCB1PTA7dTxhLmxlbmd0aDt1KyspaWYoYVt1XVswXT09bCl7bD1hW3VdWzFdLGMucHVzaChhW3VdWzJdKTticmVha31pZihjLmxlbmd0aD4yKXJldHVybiBjO2lmKGMubGVuZ3RoPT0yKXtjb25zdCBoPXV1KGVbYVswXVszXVswXV0sZVthWzBdWzNdWzFdXSxzW2NbMF1dKSx1PXV1KGVbYVswXVszXVsyXV0sZVthWzBdWzNdWzBdXSxzW2NbMF1dKSxmPW8oaCksZD1vKHUpO3JldHVybltjWzBdLGQsY1sxXSxmXX19KTtmdW5jdGlvbiBvKGEpe2xldCBjPS0xO3JldHVybiBzLnNsaWNlKHQubGVuZ3RoLDEvMCkuZm9yRWFjaCgobCxoKT0+e2xbMF09PT1hWzBdJiZsWzFdPT09YVsxXSYmKGM9aCt0Lmxlbmd0aCl9KSxjPDAmJihjPXMubGVuZ3RoLHMucHVzaChhKSksY31yZXR1cm57cG9seWdvbnM6cixjZW50ZXJzOnN9fWZ1bmN0aW9uIHV1KGksdCxlKXtpPU1lKGkpLHQ9TWUodCksZT1NZShlKTtjb25zdCBuPWxtKGh1KFd0KHQsaSksZSkpO3JldHVybiBzYygkcihEcihpLHQpKS5tYXAocz0+bipzKSl9ZnVuY3Rpb24gd20oaSl7Y29uc3QgdD1bXTtyZXR1cm4gaS5mb3JFYWNoKGU9PntpZighZSlyZXR1cm47bGV0IG49ZVtlLmxlbmd0aC0xXTtmb3IobGV0IHMgb2YgZSlzPm4mJnQucHVzaChbbixzXSksbj1zfSksdH1mdW5jdGlvbiBibShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtjb25zdCBuPW5ldyBNYXAscz1uZXcgTWFwO3JldHVybiBpLmZvckVhY2goKHIsbyk9Pntjb25zdCBhPXIuam9pbigiLSIpO24uc2V0KGEsZVtvXSkscy5zZXQoYSwhMCl9KSx0LmZvckVhY2gocj0+e2xldCBvPTAsYT0tMTtmb3IobGV0IGM9MDtjPDM7YysrKXtsZXQgbD1zcihbcltjXSxyWyhjKzEpJTNdXSkuam9pbigiLSIpO24uZ2V0KGwpPm8mJihvPW4uZ2V0KGwpLGE9bCl9cy5zZXQoYSwhMSl9KSxpLm1hcChyPT5zLmdldChyLmpvaW4oIi0iKSkpfX1mdW5jdGlvbiBNbShpLHQpe2NvbnN0IGU9bmV3IFNldCxuPVtdO2kubWFwKGE9PntpZighKHJjKGEubWFwKGM9PnRbYz50Lmxlbmd0aD8wOmNdKSk+MWUtMTIpKWZvcihsZXQgYz0wO2M8MztjKyspe2xldCBsPVthW2NdLGFbKGMrMSklM11dLGg9YCR7bFswXX0tJHtsWzFdfWA7ZS5oYXMoaCk/ZS5kZWxldGUoaCk6ZS5hZGQoYCR7bFsxXX0tJHtsWzBdfWApfX0pO2NvbnN0IHM9bmV3IE1hcDtsZXQgcjtpZihlLmZvckVhY2goYT0+e2E9YS5zcGxpdCgiLSIpLm1hcChOdW1iZXIpLHMuc2V0KGFbMF0sYVsxXSkscj1hWzBdfSkscj09PXZvaWQgMClyZXR1cm4gbjtsZXQgbz1yO2Rve24ucHVzaChvKTtsZXQgYT1zLmdldChvKTtzLnNldChvLC0xKSxvPWF9d2hpbGUobz4tMSYmbyE9PXIpO3JldHVybiBufWZ1bmN0aW9uIEFtKGkpe2NvbnN0IHQ9ZnVuY3Rpb24oZSl7aWYodC5kZWxhdW5heT1udWxsLHQuX2RhdGE9ZSx0eXBlb2YgdC5fZGF0YT09Im9iamVjdCImJnQuX2RhdGEudHlwZT09PSJGZWF0dXJlQ29sbGVjdGlvbiImJih0Ll9kYXRhPXQuX2RhdGEuZmVhdHVyZXMpLHR5cGVvZiB0Ll9kYXRhPT0ib2JqZWN0Iil7Y29uc3Qgbj10Ll9kYXRhLm1hcChzPT5bdC5fdngocyksdC5fdnkocyksc10pLmZpbHRlcihzPT5pc0Zpbml0ZShzWzBdK3NbMV0pKTt0LnBvaW50cz1uLm1hcChzPT5bc1swXSxzWzFdXSksdC52YWxpZD1uLm1hcChzPT5zWzJdKSx0LmRlbGF1bmF5PXVtKHQucG9pbnRzKX1yZXR1cm4gdH07cmV0dXJuIHQuX3Z4PWZ1bmN0aW9uKGUpe2lmKHR5cGVvZiBlPT0ib2JqZWN0IiYmInR5cGUiaW4gZSlyZXR1cm4geGgoZSlbMF07aWYoMCBpbiBlKXJldHVybiBlWzBdfSx0Ll92eT1mdW5jdGlvbihlKXtpZih0eXBlb2YgZT09Im9iamVjdCImJiJ0eXBlImluIGUpcmV0dXJuIHhoKGUpWzFdO2lmKDEgaW4gZSlyZXR1cm4gZVsxXX0sdC54PWZ1bmN0aW9uKGUpe3JldHVybiBlPyh0Ll92eD1lLHQpOnQuX3Z4fSx0Lnk9ZnVuY3Rpb24oZSl7cmV0dXJuIGU/KHQuX3Z5PWUsdCk6dC5fdnl9LHQucG9seWdvbnM9ZnVuY3Rpb24oZSl7aWYoZSE9PXZvaWQgMCYmdChlKSwhdC5kZWxhdW5heSlyZXR1cm4hMTtjb25zdCBuPXt0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6W119O3JldHVybiB0LnZhbGlkLmxlbmd0aD09PTB8fCh0LmRlbGF1bmF5LnBvbHlnb25zLmZvckVhY2goKHMscik9Pm4uZmVhdHVyZXMucHVzaCh7dHlwZToiRmVhdHVyZSIsZ2VvbWV0cnk6cz97dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5zLHNbMF1dLm1hcChvPT50LmRlbGF1bmF5LmNlbnRlcnNbb10pXX06bnVsbCxwcm9wZXJ0aWVzOntzaXRlOnQudmFsaWRbcl0sc2l0ZWNvb3JkaW5hdGVzOnQucG9pbnRzW3JdLG5laWdoYm91cnM6dC5kZWxhdW5heS5uZWlnaGJvcnNbcl19fSkpLHQudmFsaWQubGVuZ3RoPT09MSYmbi5mZWF0dXJlcy5wdXNoKHt0eXBlOiJGZWF0dXJlIixnZW9tZXRyeTp7dHlwZToiU3BoZXJlIn0scHJvcGVydGllczp7c2l0ZTp0LnZhbGlkWzBdLHNpdGVjb29yZGluYXRlczp0LnBvaW50c1swXSxuZWlnaGJvdXJzOltdfX0pKSxufSx0LnRyaWFuZ2xlcz1mdW5jdGlvbihlKXtyZXR1cm4gZSE9PXZvaWQgMCYmdChlKSx0LmRlbGF1bmF5P3t0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6dC5kZWxhdW5heS50cmlhbmdsZXMubWFwKChuLHMpPT4obj1uLm1hcChyPT50LnBvaW50c1tyXSksbi5jZW50ZXI9dC5kZWxhdW5heS5jZW50ZXJzW3NdLG4pKS5maWx0ZXIobj0+cmMobik+MCkubWFwKG49Pih7dHlwZToiRmVhdHVyZSIscHJvcGVydGllczp7Y2lyY3VtY2VudGVyOm4uY2VudGVyfSxnZW9tZXRyeTp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLG5bMF1dXX19KSl9OiExfSx0LmxpbmtzPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3Qgbj10LmRlbGF1bmF5LmVkZ2VzLm1hcChyPT5yaSh0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXSkpLHM9dC5kZWxhdW5heS51cnF1aGFydChuKTtyZXR1cm57dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOnQuZGVsYXVuYXkuZWRnZXMubWFwKChyLG8pPT4oe3R5cGU6IkZlYXR1cmUiLHByb3BlcnRpZXM6e3NvdXJjZTp0LnZhbGlkW3JbMF1dLHRhcmdldDp0LnZhbGlkW3JbMV1dLGxlbmd0aDpuW29dLHVycXVoYXJ0OiEhc1tvXX0sZ2VvbWV0cnk6e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOlt0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXV19fSkpfX0sdC5tZXNoPWZ1bmN0aW9uKGUpe3JldHVybiBlIT09dm9pZCAwJiZ0KGUpLHQuZGVsYXVuYXk/e3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6dC5kZWxhdW5heS5lZGdlcy5tYXAobj0+W3QucG9pbnRzW25bMF1dLHQucG9pbnRzW25bMV1dXSl9OiExfSx0LmNlbGxNZXNoPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3R7Y2VudGVyczpuLHBvbHlnb25zOnN9PXQuZGVsYXVuYXkscj1bXTtmb3IoY29uc3QgbyBvZiBzKWlmKG8pZm9yKGxldCBhPW8ubGVuZ3RoLGM9b1thLTFdLGw9b1swXSxoPTA7aDxhO2M9bCxsPW9bKytoXSlsPmMmJnIucHVzaChbbltjXSxuW2xdXSk7cmV0dXJue3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6cn19LHQuX2ZvdW5kPXZvaWQgMCx0LmZpbmQ9ZnVuY3Rpb24oZSxuLHMpe2lmKHQuX2ZvdW5kPXQuZGVsYXVuYXkuZmluZChlLG4sdC5fZm91bmQpLCFzfHxyaShbZSxuXSx0LnBvaW50c1t0Ll9mb3VuZF0pPHMpcmV0dXJuIHQuX2ZvdW5kfSx0Lmh1bGw9ZnVuY3Rpb24oZSl7ZSE9PXZvaWQgMCYmdChlKTtjb25zdCBuPXQuZGVsYXVuYXkuaHVsbCxzPXQucG9pbnRzO3JldHVybiBuLmxlbmd0aD09PTA/bnVsbDp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLm1hcChyPT5zW3JdKSxzW25bMF1dXV19fSxpP3QoaSk6dH1mdW5jdGlvbiBTbShpLHQpe3N3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtjYXNlIDA6YnJlYWs7Y2FzZSAxOnRoaXMucmFuZ2UoaSk7YnJlYWs7ZGVmYXVsdDp0aGlzLnJhbmdlKHQpLmRvbWFpbihpKTticmVha31yZXR1cm4gdGhpc31mdW5jdGlvbiBvYyhpLHQsZSl7aS5wcm90b3R5cGU9dC5wcm90b3R5cGU9ZSxlLmNvbnN0cnVjdG9yPWl9ZnVuY3Rpb24gZnUoaSx0KXt2YXIgZT1PYmplY3QuY3JlYXRlKGkucHJvdG90eXBlKTtmb3IodmFyIG4gaW4gdCllW25dPXRbbl07cmV0dXJuIGV9ZnVuY3Rpb24gbnMoKXt9dmFyIGlzPS43LFZyPTEvaXMsZmk9IlxccyooWystXT9cXGQrKVxccyoiLHNzPSJcXHMqKFsrLV0/KD86XFxkKlxcLik/XFxkKyg/OltlRV1bKy1dP1xcZCspPylcXHMqIixBZT0iXFxzKihbKy1dPyg/OlxcZCpcXC4pP1xcZCsoPzpbZUVdWystXT9cXGQrKT8pJVxccyoiLF9tPS9eIyhbMC05YS1mXXszLDh9KSQvLHZtPW5ldyBSZWdFeHAoYF5yZ2JcXCgke2ZpfSwke2ZpfSwke2ZpfVxcKSRgKSx6bT1uZXcgUmVnRXhwKGBecmdiXFwoJHtBZX0sJHtBZX0sJHtBZX1cXCkkYCksVG09bmV3IFJlZ0V4cChgXnJnYmFcXCgke2ZpfSwke2ZpfSwke2ZpfSwke3NzfVxcKSRgKSxFbT1uZXcgUmVnRXhwKGBecmdiYVxcKCR7QWV9LCR7QWV9LCR7QWV9LCR7c3N9XFwpJGApLFBtPW5ldyBSZWdFeHAoYF5oc2xcXCgke3NzfSwke0FlfSwke0FlfVxcKSRgKSxDbT1uZXcgUmVnRXhwKGBeaHNsYVxcKCR7c3N9LCR7QWV9LCR7QWV9LCR7c3N9XFwpJGApLGR1PXthbGljZWJsdWU6MTU3OTIzODMsYW50aXF1ZXdoaXRlOjE2NDQ0Mzc1LGFxdWE6NjU1MzUsYXF1YW1hcmluZTo4Mzg4NTY0LGF6dXJlOjE1Nzk0MTc1LGJlaWdlOjE2MTE5MjYwLGJpc3F1ZToxNjc3MDI0NCxibGFjazowLGJsYW5jaGVkYWxtb25kOjE2NzcyMDQ1LGJsdWU6MjU1LGJsdWV2aW9sZXQ6OTA1NTIwMixicm93bjoxMDgyNDIzNCxidXJseXdvb2Q6MTQ1OTYyMzEsY2FkZXRibHVlOjYyNjY1MjgsY2hhcnRyZXVzZTo4Mzg4MzUyLGNob2NvbGF0ZToxMzc4OTQ3MCxjb3JhbDoxNjc0NDI3Mixjb3JuZmxvd2VyYmx1ZTo2NTkxOTgxLGNvcm5zaWxrOjE2Nzc1Mzg4LGNyaW1zb246MTQ0MjMxMDAsY3lhbjo2NTUzNSxkYXJrYmx1ZToxMzksZGFya2N5YW46MzU3MjMsZGFya2dvbGRlbnJvZDoxMjA5MjkzOSxkYXJrZ3JheToxMTExOTAxNyxkYXJrZ3JlZW46MjU2MDAsZGFya2dyZXk6MTExMTkwMTcsZGFya2toYWtpOjEyNDMzMjU5LGRhcmttYWdlbnRhOjkxMDk2NDMsZGFya29saXZlZ3JlZW46NTU5Nzk5OSxkYXJrb3JhbmdlOjE2NzQ3NTIwLGRhcmtvcmNoaWQ6MTAwNDAwMTIsZGFya3JlZDo5MTA5NTA0LGRhcmtzYWxtb246MTUzMDg0MTAsZGFya3NlYWdyZWVuOjk0MTk5MTksZGFya3NsYXRlYmx1ZTo0NzM0MzQ3LGRhcmtzbGF0ZWdyYXk6MzEwMDQ5NSxkYXJrc2xhdGVncmV5OjMxMDA0OTUsZGFya3R1cnF1b2lzZTo1Mjk0NSxkYXJrdmlvbGV0Ojk2OTk1MzksZGVlcHBpbms6MTY3MTY5NDcsZGVlcHNreWJsdWU6NDkxNTEsZGltZ3JheTo2OTA4MjY1LGRpbWdyZXk6NjkwODI2NSxkb2RnZXJibHVlOjIwMDMxOTksZmlyZWJyaWNrOjExNjc0MTQ2LGZsb3JhbHdoaXRlOjE2Nzc1OTIwLGZvcmVzdGdyZWVuOjIyNjM4NDIsZnVjaHNpYToxNjcxMTkzNSxnYWluc2Jvcm86MTQ0NzQ0NjAsZ2hvc3R3aGl0ZToxNjMxNjY3MSxnb2xkOjE2NzY2NzIwLGdvbGRlbnJvZDoxNDMyOTEyMCxncmF5Ojg0MjE1MDQsZ3JlZW46MzI3NjgsZ3JlZW55ZWxsb3c6MTE0MDMwNTUsZ3JleTo4NDIxNTA0LGhvbmV5ZGV3OjE1Nzk0MTYwLGhvdHBpbms6MTY3Mzg3NDAsaW5kaWFucmVkOjEzNDU4NTI0LGluZGlnbzo0OTE1MzMwLGl2b3J5OjE2Nzc3MjAwLGtoYWtpOjE1Nzg3NjYwLGxhdmVuZGVyOjE1MTMyNDEwLGxhdmVuZGVyYmx1c2g6MTY3NzMzNjUsbGF3bmdyZWVuOjgxOTA5NzYsbGVtb25jaGlmZm9uOjE2Nzc1ODg1LGxpZ2h0Ymx1ZToxMTM5MzI1NCxsaWdodGNvcmFsOjE1NzYxNTM2LGxpZ2h0Y3lhbjoxNDc0NTU5OSxsaWdodGdvbGRlbnJvZHllbGxvdzoxNjQ0ODIxMCxsaWdodGdyYXk6MTM4ODIzMjMsbGlnaHRncmVlbjo5NDk4MjU2LGxpZ2h0Z3JleToxMzg4MjMyMyxsaWdodHBpbms6MTY3NTg0NjUsbGlnaHRzYWxtb246MTY3NTI3NjIsbGlnaHRzZWFncmVlbjoyMTQyODkwLGxpZ2h0c2t5Ymx1ZTo4OTAwMzQ2LGxpZ2h0c2xhdGVncmF5Ojc4MzM3NTMsbGlnaHRzbGF0ZWdyZXk6NzgzMzc1MyxsaWdodHN0ZWVsYmx1ZToxMTU4NDczNCxsaWdodHllbGxvdzoxNjc3NzE4NCxsaW1lOjY1MjgwLGxpbWVncmVlbjozMzI5MzMwLGxpbmVuOjE2NDQ1NjcwLG1hZ2VudGE6MTY3MTE5MzUsbWFyb29uOjgzODg2MDgsbWVkaXVtYXF1YW1hcmluZTo2NzM3MzIyLG1lZGl1bWJsdWU6MjA1LG1lZGl1bW9yY2hpZDoxMjIxMTY2NyxtZWRpdW1wdXJwbGU6OTY2MjY4MyxtZWRpdW1zZWFncmVlbjozOTc4MDk3LG1lZGl1bXNsYXRlYmx1ZTo4MDg3NzkwLG1lZGl1bXNwcmluZ2dyZWVuOjY0MTU0LG1lZGl1bXR1cnF1b2lzZTo0NzcyMzAwLG1lZGl1bXZpb2xldHJlZDoxMzA0NzE3MyxtaWRuaWdodGJsdWU6MTY0NDkxMixtaW50Y3JlYW06MTYxMjE4NTAsbWlzdHlyb3NlOjE2NzcwMjczLG1vY2Nhc2luOjE2NzcwMjI5LG5hdmFqb3doaXRlOjE2NzY4Njg1LG5hdnk6MTI4LG9sZGxhY2U6MTY2NDM1NTgsb2xpdmU6ODQyMTM3NixvbGl2ZWRyYWI6NzA0ODczOSxvcmFuZ2U6MTY3NTM5MjAsb3JhbmdlcmVkOjE2NzI5MzQ0LG9yY2hpZDoxNDMxNTczNCxwYWxlZ29sZGVucm9kOjE1NjU3MTMwLHBhbGVncmVlbjoxMDAyNTg4MCxwYWxldHVycXVvaXNlOjExNTI5OTY2LHBhbGV2aW9sZXRyZWQ6MTQzODEyMDMscGFwYXlhd2hpcDoxNjc3MzA3NyxwZWFjaHB1ZmY6MTY3Njc2NzMscGVydToxMzQ2ODk5MSxwaW5rOjE2NzYxMDM1LHBsdW06MTQ1MjQ2MzcscG93ZGVyYmx1ZToxMTU5MTkxMCxwdXJwbGU6ODM4ODczNixyZWJlY2NhcHVycGxlOjY2OTc4ODEscmVkOjE2NzExNjgwLHJvc3licm93bjoxMjM1NzUxOSxyb3lhbGJsdWU6NDI4Njk0NSxzYWRkbGVicm93bjo5MTI3MTg3LHNhbG1vbjoxNjQxNjg4MixzYW5keWJyb3duOjE2MDMyODY0LHNlYWdyZWVuOjMwNTAzMjcsc2Vhc2hlbGw6MTY3NzQ2Mzgsc2llbm5hOjEwNTA2Nzk3LHNpbHZlcjoxMjYzMjI1Nixza3libHVlOjg5MDAzMzEsc2xhdGVibHVlOjY5NzAwNjEsc2xhdGVncmF5OjczNzI5NDQsc2xhdGVncmV5OjczNzI5NDQsc25vdzoxNjc3NTkzMCxzcHJpbmdncmVlbjo2NTQwNyxzdGVlbGJsdWU6NDYyMDk4MCx0YW46MTM4MDg3ODAsdGVhbDozMjg5Nix0aGlzdGxlOjE0MjA0ODg4LHRvbWF0bzoxNjczNzA5NSx0dXJxdW9pc2U6NDI1MTg1Nix2aW9sZXQ6MTU2MzEwODYsd2hlYXQ6MTYxMTMzMzEsd2hpdGU6MTY3NzcyMTUsd2hpdGVzbW9rZToxNjExOTI4NSx5ZWxsb3c6MTY3NzY5NjAseWVsbG93Z3JlZW46MTAxNDUwNzR9O29jKG5zLHJzLHtjb3B5KGkpe3JldHVybiBPYmplY3QuYXNzaWduKG5ldyB0aGlzLmNvbnN0cnVjdG9yLHRoaXMsaSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuIHRoaXMucmdiKCkuZGlzcGxheWFibGUoKX0saGV4OnB1LGZvcm1hdEhleDpwdSxmb3JtYXRIZXg4OkJtLGZvcm1hdEhzbDpGbSxmb3JtYXRSZ2I6eXUsdG9TdHJpbmc6eXV9KTtmdW5jdGlvbiBwdSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleCgpfWZ1bmN0aW9uIEJtKCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0SGV4OCgpfWZ1bmN0aW9uIEZtKCl7cmV0dXJuIGJ1KHRoaXMpLmZvcm1hdEhzbCgpfWZ1bmN0aW9uIHl1KCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0UmdiKCl9ZnVuY3Rpb24gcnMoaSl7dmFyIHQsZTtyZXR1cm4gaT0oaSsiIikudHJpbSgpLnRvTG93ZXJDYXNlKCksKHQ9X20uZXhlYyhpKSk/KGU9dFsxXS5sZW5ndGgsdD1wYXJzZUludCh0WzFdLDE2KSxlPT09Nj9tdSh0KTplPT09Mz9uZXcgT3QodD4+OCYxNXx0Pj40JjI0MCx0Pj40JjE1fHQmMjQwLCh0JjE1KTw8NHx0JjE1LDEpOmU9PT04P1VyKHQ+PjI0JjI1NSx0Pj4xNiYyNTUsdD4+OCYyNTUsKHQmMjU1KS8yNTUpOmU9PT00P1VyKHQ+PjEyJjE1fHQ+PjgmMjQwLHQ+PjgmMTV8dD4+NCYyNDAsdD4+NCYxNXx0JjI0MCwoKHQmMTUpPDw0fHQmMTUpLzI1NSk6bnVsbCk6KHQ9dm0uZXhlYyhpKSk/bmV3IE90KHRbMV0sdFsyXSx0WzNdLDEpOih0PXptLmV4ZWMoaSkpP25ldyBPdCh0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCwxKToodD1UbS5leGVjKGkpKT9Vcih0WzFdLHRbMl0sdFszXSx0WzRdKToodD1FbS5leGVjKGkpKT9Vcih0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCx0WzRdKToodD1QbS5leGVjKGkpKT93dSh0WzFdLHRbMl0vMTAwLHRbM10vMTAwLDEpOih0PUNtLmV4ZWMoaSkpP3d1KHRbMV0sdFsyXS8xMDAsdFszXS8xMDAsdFs0XSk6ZHUuaGFzT3duUHJvcGVydHkoaSk/bXUoZHVbaV0pOmk9PT0idHJhbnNwYXJlbnQiP25ldyBPdChOYU4sTmFOLE5hTiwwKTpudWxsfWZ1bmN0aW9uIG11KGkpe3JldHVybiBuZXcgT3QoaT4+MTYmMjU1LGk+PjgmMjU1LGkmMjU1LDEpfWZ1bmN0aW9uIFVyKGksdCxlLG4pe3JldHVybiBuPD0wJiYoaT10PWU9TmFOKSxuZXcgT3QoaSx0LGUsbil9ZnVuY3Rpb24gSW0oaSl7cmV0dXJuIGkgaW5zdGFuY2VvZiBuc3x8KGk9cnMoaSkpLGk/KGk9aS5yZ2IoKSxuZXcgT3QoaS5yLGkuZyxpLmIsaS5vcGFjaXR5KSk6bmV3IE90fWZ1bmN0aW9uIGFjKGksdCxlLG4pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT9JbShpKTpuZXcgT3QoaSx0LGUsbj09bnVsbD8xOm4pfWZ1bmN0aW9uIE90KGksdCxlLG4pe3RoaXMucj0raSx0aGlzLmc9K3QsdGhpcy5iPStlLHRoaXMub3BhY2l0eT0rbn1vYyhPdCxhYyxmdShucyx7YnJpZ2h0ZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9WcjpNYXRoLnBvdyhWcixpKSxuZXcgT3QodGhpcy5yKmksdGhpcy5nKmksdGhpcy5iKmksdGhpcy5vcGFjaXR5KX0sZGFya2VyKGkpe3JldHVybiBpPWk9PW51bGw/aXM6TWF0aC5wb3coaXMsaSksbmV3IE90KHRoaXMucippLHRoaXMuZyppLHRoaXMuYippLHRoaXMub3BhY2l0eSl9LHJnYigpe3JldHVybiB0aGlzfSxjbGFtcCgpe3JldHVybiBuZXcgT3QoVG4odGhpcy5yKSxUbih0aGlzLmcpLFRuKHRoaXMuYikscXIodGhpcy5vcGFjaXR5KSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuLS41PD10aGlzLnImJnRoaXMucjwyNTUuNSYmLS41PD10aGlzLmcmJnRoaXMuZzwyNTUuNSYmLS41PD10aGlzLmImJnRoaXMuYjwyNTUuNSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGhleDpndSxmb3JtYXRIZXg6Z3UsZm9ybWF0SGV4ODprbSxmb3JtYXRSZ2I6eHUsdG9TdHJpbmc6eHV9KSk7ZnVuY3Rpb24gZ3UoKXtyZXR1cm5gIyR7RW4odGhpcy5yKX0ke0VuKHRoaXMuZyl9JHtFbih0aGlzLmIpfWB9ZnVuY3Rpb24ga20oKXtyZXR1cm5gIyR7RW4odGhpcy5yKX0ke0VuKHRoaXMuZyl9JHtFbih0aGlzLmIpfSR7RW4oKGlzTmFOKHRoaXMub3BhY2l0eSk/MTp0aGlzLm9wYWNpdHkpKjI1NSl9YH1mdW5jdGlvbiB4dSgpe2NvbnN0IGk9cXIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8icmdiKCI6InJnYmEoIn0ke1RuKHRoaXMucil9LCAke1RuKHRoaXMuZyl9LCAke1RuKHRoaXMuYil9JHtpPT09MT8iKSI6YCwgJHtpfSlgfWB9ZnVuY3Rpb24gcXIoaSl7cmV0dXJuIGlzTmFOKGkpPzE6TWF0aC5tYXgoMCxNYXRoLm1pbigxLGkpKX1mdW5jdGlvbiBUbihpKXtyZXR1cm4gTWF0aC5tYXgoMCxNYXRoLm1pbigyNTUsTWF0aC5yb3VuZChpKXx8MCkpfWZ1bmN0aW9uIEVuKGkpe3JldHVybiBpPVRuKGkpLChpPDE2PyIwIjoiIikraS50b1N0cmluZygxNil9ZnVuY3Rpb24gd3UoaSx0LGUsbil7cmV0dXJuIG48PTA/aT10PWU9TmFOOmU8PTB8fGU+PTE/aT10PU5hTjp0PD0wJiYoaT1OYU4pLG5ldyB5ZShpLHQsZSxuKX1mdW5jdGlvbiBidShpKXtpZihpIGluc3RhbmNlb2YgeWUpcmV0dXJuIG5ldyB5ZShpLmgsaS5zLGkubCxpLm9wYWNpdHkpO2lmKGkgaW5zdGFuY2VvZiBuc3x8KGk9cnMoaSkpLCFpKXJldHVybiBuZXcgeWU7aWYoaSBpbnN0YW5jZW9mIHllKXJldHVybiBpO2k9aS5yZ2IoKTt2YXIgdD1pLnIvMjU1LGU9aS5nLzI1NSxuPWkuYi8yNTUscz1NYXRoLm1pbih0LGUsbikscj1NYXRoLm1heCh0LGUsbiksbz1OYU4sYT1yLXMsYz0ocitzKS8yO3JldHVybiBhPyh0PT09cj9vPShlLW4pL2ErKGU8bikqNjplPT09cj9vPShuLXQpL2ErMjpvPSh0LWUpL2ErNCxhLz1jPC41P3IrczoyLXItcyxvKj02MCk6YT1jPjAmJmM8MT8wOm8sbmV3IHllKG8sYSxjLGkub3BhY2l0eSl9ZnVuY3Rpb24gTm0oaSx0LGUsbil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg9PT0xP2J1KGkpOm5ldyB5ZShpLHQsZSxuPT1udWxsPzE6bil9ZnVuY3Rpb24geWUoaSx0LGUsbil7dGhpcy5oPStpLHRoaXMucz0rdCx0aGlzLmw9K2UsdGhpcy5vcGFjaXR5PStufW9jKHllLE5tLGZ1KG5zLHticmlnaHRlcihpKXtyZXR1cm4gaT1pPT1udWxsP1ZyOk1hdGgucG93KFZyLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LGRhcmtlcihpKXtyZXR1cm4gaT1pPT1udWxsP2lzOk1hdGgucG93KGlzLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LHJnYigpe3ZhciBpPXRoaXMuaCUzNjArKHRoaXMuaDwwKSozNjAsdD1pc05hTihpKXx8aXNOYU4odGhpcy5zKT8wOnRoaXMucyxlPXRoaXMubCxuPWUrKGU8LjU/ZToxLWUpKnQscz0yKmUtbjtyZXR1cm4gbmV3IE90KGNjKGk+PTI0MD9pLTI0MDppKzEyMCxzLG4pLGNjKGkscyxuKSxjYyhpPDEyMD9pKzI0MDppLTEyMCxzLG4pLHRoaXMub3BhY2l0eSl9LGNsYW1wKCl7cmV0dXJuIG5ldyB5ZShNdSh0aGlzLmgpLEhyKHRoaXMucyksSHIodGhpcy5sKSxxcih0aGlzLm9wYWNpdHkpKX0sZGlzcGxheWFibGUoKXtyZXR1cm4oMDw9dGhpcy5zJiZ0aGlzLnM8PTF8fGlzTmFOKHRoaXMucykpJiYwPD10aGlzLmwmJnRoaXMubDw9MSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGZvcm1hdEhzbCgpe2NvbnN0IGk9cXIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8iaHNsKCI6ImhzbGEoIn0ke011KHRoaXMuaCl9LCAke0hyKHRoaXMucykqMTAwfSUsICR7SHIodGhpcy5sKSoxMDB9JSR7aT09PTE/IikiOmAsICR7aX0pYH1gfX0pKTtmdW5jdGlvbiBNdShpKXtyZXR1cm4gaT0oaXx8MCklMzYwLGk8MD9pKzM2MDppfWZ1bmN0aW9uIEhyKGkpe3JldHVybiBNYXRoLm1heCgwLE1hdGgubWluKDEsaXx8MCkpfWZ1bmN0aW9uIGNjKGksdCxlKXtyZXR1cm4oaTw2MD90KyhlLXQpKmkvNjA6aTwxODA/ZTppPDI0MD90KyhlLXQpKigyNDAtaSkvNjA6dCkqMjU1fXZhciBsYz1pPT4oKT0+aTtmdW5jdGlvbiBSbShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gaStlKnR9fWZ1bmN0aW9uIExtKGksdCxlKXtyZXR1cm4gaT1NYXRoLnBvdyhpLGUpLHQ9TWF0aC5wb3codCxlKS1pLGU9MS9lLGZ1bmN0aW9uKG4pe3JldHVybiBNYXRoLnBvdyhpK24qdCxlKX19ZnVuY3Rpb24gT20oaSl7cmV0dXJuKGk9K2kpPT0xP0F1OmZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUtdD9MbSh0LGUsaSk6bGMoaXNOYU4odCk/ZTp0KX19ZnVuY3Rpb24gQXUoaSx0KXt2YXIgZT10LWk7cmV0dXJuIGU/Um0oaSxlKTpsYyhpc05hTihpKT90OmkpfXZhciBTdT1mdW5jdGlvbiBpKHQpe3ZhciBlPU9tKHQpO2Z1bmN0aW9uIG4ocyxyKXt2YXIgbz1lKChzPWFjKHMpKS5yLChyPWFjKHIpKS5yKSxhPWUocy5nLHIuZyksYz1lKHMuYixyLmIpLGw9QXUocy5vcGFjaXR5LHIub3BhY2l0eSk7cmV0dXJuIGZ1bmN0aW9uKGgpe3JldHVybiBzLnI9byhoKSxzLmc9YShoKSxzLmI9YyhoKSxzLm9wYWNpdHk9bChoKSxzKyIifX1yZXR1cm4gbi5nYW1tYT1pLG59KDEpO2Z1bmN0aW9uIERtKGksdCl7dHx8KHQ9W10pO3ZhciBlPWk/TWF0aC5taW4odC5sZW5ndGgsaS5sZW5ndGgpOjAsbj10LnNsaWNlKCkscztyZXR1cm4gZnVuY3Rpb24ocil7Zm9yKHM9MDtzPGU7KytzKW5bc109aVtzXSooMS1yKSt0W3NdKnI7cmV0dXJuIG59fWZ1bmN0aW9uICRtKGkpe3JldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoaSkmJiEoaSBpbnN0YW5jZW9mIERhdGFWaWV3KX1mdW5jdGlvbiBWbShpLHQpe3ZhciBlPXQ/dC5sZW5ndGg6MCxuPWk/TWF0aC5taW4oZSxpLmxlbmd0aCk6MCxzPW5ldyBBcnJheShuKSxyPW5ldyBBcnJheShlKSxvO2ZvcihvPTA7bzxuOysrbylzW29dPWZjKGlbb10sdFtvXSk7Zm9yKDtvPGU7KytvKXJbb109dFtvXTtyZXR1cm4gZnVuY3Rpb24oYSl7Zm9yKG89MDtvPG47KytvKXJbb109c1tvXShhKTtyZXR1cm4gcn19ZnVuY3Rpb24gVW0oaSx0KXt2YXIgZT1uZXcgRGF0ZTtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKG4pe3JldHVybiBlLnNldFRpbWUoaSooMS1uKSt0Km4pLGV9fWZ1bmN0aW9uIFdyKGksdCl7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihlKXtyZXR1cm4gaSooMS1lKSt0KmV9fWZ1bmN0aW9uIHFtKGksdCl7dmFyIGU9e30sbj17fSxzOyhpPT09bnVsbHx8dHlwZW9mIGkhPSJvYmplY3QiKSYmKGk9e30pLCh0PT09bnVsbHx8dHlwZW9mIHQhPSJvYmplY3QiKSYmKHQ9e30pO2ZvcihzIGluIHQpcyBpbiBpP2Vbc109ZmMoaVtzXSx0W3NdKTpuW3NdPXRbc107cmV0dXJuIGZ1bmN0aW9uKHIpe2ZvcihzIGluIGUpbltzXT1lW3NdKHIpO3JldHVybiBufX12YXIgaGM9L1stK10/KD86XGQrXC4/XGQqfFwuP1xkKykoPzpbZUVdWy0rXT9cZCspPy9nLHVjPW5ldyBSZWdFeHAoaGMuc291cmNlLCJnIik7ZnVuY3Rpb24gSG0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIFdtKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gaSh0KSsiIn19ZnVuY3Rpb24gR20oaSx0KXt2YXIgZT1oYy5sYXN0SW5kZXg9dWMubGFzdEluZGV4PTAsbixzLHIsbz0tMSxhPVtdLGM9W107Zm9yKGk9aSsiIix0PXQrIiI7KG49aGMuZXhlYyhpKSkmJihzPXVjLmV4ZWModCkpOykocj1zLmluZGV4KT5lJiYocj10LnNsaWNlKGUsciksYVtvXT9hW29dKz1yOmFbKytvXT1yKSwobj1uWzBdKT09PShzPXNbMF0pP2Fbb10/YVtvXSs9czphWysrb109czooYVsrK29dPW51bGwsYy5wdXNoKHtpOm8seDpXcihuLHMpfSkpLGU9dWMubGFzdEluZGV4O3JldHVybiBlPHQubGVuZ3RoJiYocj10LnNsaWNlKGUpLGFbb10/YVtvXSs9cjphWysrb109ciksYS5sZW5ndGg8Mj9jWzBdP1dtKGNbMF0ueCk6SG0odCk6KHQ9Yy5sZW5ndGgsZnVuY3Rpb24obCl7Zm9yKHZhciBoPTAsdTtoPHQ7KytoKWFbKHU9Y1toXSkuaV09dS54KGwpO3JldHVybiBhLmpvaW4oIiIpfSl9ZnVuY3Rpb24gZmMoaSx0KXt2YXIgZT10eXBlb2YgdCxuO3JldHVybiB0PT1udWxsfHxlPT09ImJvb2xlYW4iP2xjKHQpOihlPT09Im51bWJlciI/V3I6ZT09PSJzdHJpbmciPyhuPXJzKHQpKT8odD1uLFN1KTpHbTp0IGluc3RhbmNlb2YgcnM/U3U6dCBpbnN0YW5jZW9mIERhdGU/VW06JG0odCk/RG06QXJyYXkuaXNBcnJheSh0KT9WbTp0eXBlb2YgdC52YWx1ZU9mIT0iZnVuY3Rpb24iJiZ0eXBlb2YgdC50b1N0cmluZyE9ImZ1bmN0aW9uInx8aXNOYU4odCk/cW06V3IpKGksdCl9ZnVuY3Rpb24gWm0oaSx0KXtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKGUpe3JldHVybiBNYXRoLnJvdW5kKGkqKDEtZSkrdCplKX19ZnVuY3Rpb24gWG0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIEptKGkpe3JldHVybitpfXZhciBfdT1bMCwxXTtmdW5jdGlvbiBkaShpKXtyZXR1cm4gaX1mdW5jdGlvbiBkYyhpLHQpe3JldHVybih0LT1pPStpKT9mdW5jdGlvbihlKXtyZXR1cm4oZS1pKS90fTpYbShpc05hTih0KT9OYU46LjUpfWZ1bmN0aW9uIFltKGksdCl7dmFyIGU7cmV0dXJuIGk+dCYmKGU9aSxpPXQsdD1lKSxmdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5tYXgoaSxNYXRoLm1pbih0LG4pKX19ZnVuY3Rpb24gam0oaSx0LGUpe3ZhciBuPWlbMF0scz1pWzFdLHI9dFswXSxvPXRbMV07cmV0dXJuIHM8bj8obj1kYyhzLG4pLHI9ZShvLHIpKToobj1kYyhuLHMpLHI9ZShyLG8pKSxmdW5jdGlvbihhKXtyZXR1cm4gcihuKGEpKX19ZnVuY3Rpb24gUW0oaSx0LGUpe3ZhciBuPU1hdGgubWluKGkubGVuZ3RoLHQubGVuZ3RoKS0xLHM9bmV3IEFycmF5KG4pLHI9bmV3IEFycmF5KG4pLG89LTE7Zm9yKGlbbl08aVswXSYmKGk9aS5zbGljZSgpLnJldmVyc2UoKSx0PXQuc2xpY2UoKS5yZXZlcnNlKCkpOysrbzxuOylzW29dPWRjKGlbb10saVtvKzFdKSxyW29dPWUodFtvXSx0W28rMV0pO3JldHVybiBmdW5jdGlvbihhKXt2YXIgYz10cChpLGEsMSxuKS0xO3JldHVybiByW2NdKHNbY10oYSkpfX1mdW5jdGlvbiBLbShpLHQpe3JldHVybiB0LmRvbWFpbihpLmRvbWFpbigpKS5yYW5nZShpLnJhbmdlKCkpLmludGVycG9sYXRlKGkuaW50ZXJwb2xhdGUoKSkuY2xhbXAoaS5jbGFtcCgpKS51bmtub3duKGkudW5rbm93bigpKX1mdW5jdGlvbiB0Zygpe3ZhciBpPV91LHQ9X3UsZT1mYyxuLHMscixvPWRpLGEsYyxsO2Z1bmN0aW9uIGgoKXt2YXIgZj1NYXRoLm1pbihpLmxlbmd0aCx0Lmxlbmd0aCk7cmV0dXJuIG8hPT1kaSYmKG89WW0oaVswXSxpW2YtMV0pKSxhPWY+Mj9RbTpqbSxjPWw9bnVsbCx1fWZ1bmN0aW9uIHUoZil7cmV0dXJuIGY9PW51bGx8fGlzTmFOKGY9K2YpP3I6KGN8fChjPWEoaS5tYXAobiksdCxlKSkpKG4obyhmKSkpfXJldHVybiB1LmludmVydD1mdW5jdGlvbihmKXtyZXR1cm4gbyhzKChsfHwobD1hKHQsaS5tYXAobiksV3IpKSkoZikpKX0sdS5kb21haW49ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGk9QXJyYXkuZnJvbShmLEptKSxoKCkpOmkuc2xpY2UoKX0sdS5yYW5nZT1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odD1BcnJheS5mcm9tKGYpLGgoKSk6dC5zbGljZSgpfSx1LnJhbmdlUm91bmQ9ZnVuY3Rpb24oZil7cmV0dXJuIHQ9QXJyYXkuZnJvbShmKSxlPVptLGgoKX0sdS5jbGFtcD1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obz1mPyEwOmRpLGgoKSk6byE9PWRpfSx1LmludGVycG9sYXRlPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhlPWYsaCgpKTplfSx1LnVua25vd249ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHI9Zix1KTpyfSxmdW5jdGlvbihmLGQpe3JldHVybiBuPWYscz1kLGgoKX19ZnVuY3Rpb24gZWcoKXtyZXR1cm4gdGcoKShkaSxkaSl9ZnVuY3Rpb24gbmcoaSl7cmV0dXJuIE1hdGguYWJzKGk9TWF0aC5yb3VuZChpKSk+PTFlMjE/aS50b0xvY2FsZVN0cmluZygiZW4iKS5yZXBsYWNlKC8sL2csIiIpOmkudG9TdHJpbmcoMTApfWZ1bmN0aW9uIEdyKGksdCl7aWYoKGU9KGk9dD9pLnRvRXhwb25lbnRpYWwodC0xKTppLnRvRXhwb25lbnRpYWwoKSkuaW5kZXhPZigiZSIpKTwwKXJldHVybiBudWxsO3ZhciBlLG49aS5zbGljZSgwLGUpO3JldHVybltuLmxlbmd0aD4xP25bMF0rbi5zbGljZSgyKTpuLCtpLnNsaWNlKGUrMSldfWZ1bmN0aW9uIHBpKGkpe3JldHVybiBpPUdyKE1hdGguYWJzKGkpKSxpP2lbMV06TmFOfWZ1bmN0aW9uIGlnKGksdCl7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Zm9yKHZhciBzPWUubGVuZ3RoLHI9W10sbz0wLGE9aVswXSxjPTA7cz4wJiZhPjAmJihjK2ErMT5uJiYoYT1NYXRoLm1heCgxLG4tYykpLHIucHVzaChlLnN1YnN0cmluZyhzLT1hLHMrYSkpLCEoKGMrPWErMSk+bikpOylhPWlbbz0obysxKSVpLmxlbmd0aF07cmV0dXJuIHIucmV2ZXJzZSgpLmpvaW4odCl9fWZ1bmN0aW9uIHNnKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdC5yZXBsYWNlKC9bMC05XS9nLGZ1bmN0aW9uKGUpe3JldHVybiBpWytlXX0pfX12YXIgcmc9L14oPzooLik/KFs8Pj1eXSkpPyhbK1wtKCBdKT8oWyQjXSk/KDApPyhcZCspPygsKT8oXC5cZCspPyh+KT8oW2EteiVdKT8kL2k7ZnVuY3Rpb24gWnIoaSl7aWYoISh0PXJnLmV4ZWMoaSkpKXRocm93IG5ldyBFcnJvcigiaW52YWxpZCBmb3JtYXQ6ICIraSk7dmFyIHQ7cmV0dXJuIG5ldyBwYyh7ZmlsbDp0WzFdLGFsaWduOnRbMl0sc2lnbjp0WzNdLHN5bWJvbDp0WzRdLHplcm86dFs1XSx3aWR0aDp0WzZdLGNvbW1hOnRbN10scHJlY2lzaW9uOnRbOF0mJnRbOF0uc2xpY2UoMSksdHJpbTp0WzldLHR5cGU6dFsxMF19KX1aci5wcm90b3R5cGU9cGMucHJvdG90eXBlO2Z1bmN0aW9uIHBjKGkpe3RoaXMuZmlsbD1pLmZpbGw9PT12b2lkIDA/IiAiOmkuZmlsbCsiIix0aGlzLmFsaWduPWkuYWxpZ249PT12b2lkIDA/Ij4iOmkuYWxpZ24rIiIsdGhpcy5zaWduPWkuc2lnbj09PXZvaWQgMD8iLSI6aS5zaWduKyIiLHRoaXMuc3ltYm9sPWkuc3ltYm9sPT09dm9pZCAwPyIiOmkuc3ltYm9sKyIiLHRoaXMuemVybz0hIWkuemVybyx0aGlzLndpZHRoPWkud2lkdGg9PT12b2lkIDA/dm9pZCAwOitpLndpZHRoLHRoaXMuY29tbWE9ISFpLmNvbW1hLHRoaXMucHJlY2lzaW9uPWkucHJlY2lzaW9uPT09dm9pZCAwP3ZvaWQgMDoraS5wcmVjaXNpb24sdGhpcy50cmltPSEhaS50cmltLHRoaXMudHlwZT1pLnR5cGU9PT12b2lkIDA/IiI6aS50eXBlKyIifXBjLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmZpbGwrdGhpcy5hbGlnbit0aGlzLnNpZ24rdGhpcy5zeW1ib2wrKHRoaXMuemVybz8iMCI6IiIpKyh0aGlzLndpZHRoPT09dm9pZCAwPyIiOk1hdGgubWF4KDEsdGhpcy53aWR0aHwwKSkrKHRoaXMuY29tbWE/IiwiOiIiKSsodGhpcy5wcmVjaXNpb249PT12b2lkIDA/IiI6Ii4iK01hdGgubWF4KDAsdGhpcy5wcmVjaXNpb258MCkpKyh0aGlzLnRyaW0/In4iOiIiKSt0aGlzLnR5cGV9O2Z1bmN0aW9uIG9nKGkpe3Q6Zm9yKHZhciB0PWkubGVuZ3RoLGU9MSxuPS0xLHM7ZTx0OysrZSlzd2l0Y2goaVtlXSl7Y2FzZSIuIjpuPXM9ZTticmVhaztjYXNlIjAiOm49PT0wJiYobj1lKSxzPWU7YnJlYWs7ZGVmYXVsdDppZighK2lbZV0pYnJlYWsgdDtuPjAmJihuPTApO2JyZWFrfXJldHVybiBuPjA/aS5zbGljZSgwLG4pK2kuc2xpY2UocysxKTppfXZhciB2dTtmdW5jdGlvbiBhZyhpLHQpe3ZhciBlPUdyKGksdCk7aWYoIWUpcmV0dXJuIGkrIiI7dmFyIG49ZVswXSxzPWVbMV0scj1zLSh2dT1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3Iocy8zKSkpKjMpKzEsbz1uLmxlbmd0aDtyZXR1cm4gcj09PW8/bjpyPm8/bituZXcgQXJyYXkoci1vKzEpLmpvaW4oIjAiKTpyPjA/bi5zbGljZSgwLHIpKyIuIituLnNsaWNlKHIpOiIwLiIrbmV3IEFycmF5KDEtcikuam9pbigiMCIpK0dyKGksTWF0aC5tYXgoMCx0K3ItMSkpWzBdfWZ1bmN0aW9uIHp1KGksdCl7dmFyIGU9R3IoaSx0KTtpZighZSlyZXR1cm4gaSsiIjt2YXIgbj1lWzBdLHM9ZVsxXTtyZXR1cm4gczwwPyIwLiIrbmV3IEFycmF5KC1zKS5qb2luKCIwIikrbjpuLmxlbmd0aD5zKzE/bi5zbGljZSgwLHMrMSkrIi4iK24uc2xpY2UocysxKTpuK25ldyBBcnJheShzLW4ubGVuZ3RoKzIpLmpvaW4oIjAiKX12YXIgVHU9eyIlIjooaSx0KT0+KGkqMTAwKS50b0ZpeGVkKHQpLGI6aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZygyKSxjOmk9PmkrIiIsZDpuZyxlOihpLHQpPT5pLnRvRXhwb25lbnRpYWwodCksZjooaSx0KT0+aS50b0ZpeGVkKHQpLGc6KGksdCk9PmkudG9QcmVjaXNpb24odCksbzppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDgpLHA6KGksdCk9Pnp1KGkqMTAwLHQpLHI6enUsczphZyxYOmk9Pk1hdGgucm91bmQoaSkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkseDppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDE2KX07ZnVuY3Rpb24gRXUoaSl7cmV0dXJuIGl9dmFyIFB1PUFycmF5LnByb3RvdHlwZS5tYXAsQ3U9WyJ5IiwieiIsImEiLCJmIiwicCIsIm4iLCLCtSIsIm0iLCIiLCJrIiwiTSIsIkciLCJUIiwiUCIsIkUiLCJaIiwiWSJdO2Z1bmN0aW9uIGNnKGkpe3ZhciB0PWkuZ3JvdXBpbmc9PT12b2lkIDB8fGkudGhvdXNhbmRzPT09dm9pZCAwP0V1OmlnKFB1LmNhbGwoaS5ncm91cGluZyxOdW1iZXIpLGkudGhvdXNhbmRzKyIiKSxlPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVswXSsiIixuPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVsxXSsiIixzPWkuZGVjaW1hbD09PXZvaWQgMD8iLiI6aS5kZWNpbWFsKyIiLHI9aS5udW1lcmFscz09PXZvaWQgMD9FdTpzZyhQdS5jYWxsKGkubnVtZXJhbHMsU3RyaW5nKSksbz1pLnBlcmNlbnQ9PT12b2lkIDA/IiUiOmkucGVyY2VudCsiIixhPWkubWludXM9PT12b2lkIDA/IuKIkiI6aS5taW51cysiIixjPWkubmFuPT09dm9pZCAwPyJOYU4iOmkubmFuKyIiO2Z1bmN0aW9uIGwodSl7dT1acih1KTt2YXIgZj11LmZpbGwsZD11LmFsaWduLHA9dS5zaWduLHk9dS5zeW1ib2wsbT11Lnplcm8sZz11LndpZHRoLGI9dS5jb21tYSx3PXUucHJlY2lzaW9uLHg9dS50cmltLE09dS50eXBlO009PT0ibiI/KGI9ITAsTT0iZyIpOlR1W01dfHwodz09PXZvaWQgMCYmKHc9MTIpLHg9ITAsTT0iZyIpLChtfHxmPT09IjAiJiZkPT09Ij0iKSYmKG09ITAsZj0iMCIsZD0iPSIpO3ZhciBBPXk9PT0iJCI/ZTp5PT09IiMiJiYvW2JveFhdLy50ZXN0KE0pPyIwIitNLnRvTG93ZXJDYXNlKCk6IiIsUz15PT09IiQiP246L1slcF0vLnRlc3QoTSk/bzoiIixfPVR1W01dLEU9L1tkZWZncHJzJV0vLnRlc3QoTSk7dz13PT09dm9pZCAwPzY6L1tncHJzXS8udGVzdChNKT9NYXRoLm1heCgxLE1hdGgubWluKDIxLHcpKTpNYXRoLm1heCgwLE1hdGgubWluKDIwLHcpKTtmdW5jdGlvbiB6KHYpe3ZhciBDPUEsUD1TLEYsQixJO2lmKE09PT0iYyIpUD1fKHYpK1Asdj0iIjtlbHNle3Y9K3Y7dmFyIGs9djwwfHwxL3Y8MDtpZih2PWlzTmFOKHYpP2M6XyhNYXRoLmFicyh2KSx3KSx4JiYodj1vZyh2KSksayYmK3Y9PTAmJnAhPT0iKyImJihrPSExKSxDPShrP3A9PT0iKCI/cDphOnA9PT0iLSJ8fHA9PT0iKCI/IiI6cCkrQyxQPShNPT09InMiP0N1WzgrdnUvM106IiIpK1ArKGsmJnA9PT0iKCI/IikiOiIiKSxFKXtmb3IoRj0tMSxCPXYubGVuZ3RoOysrRjxCOylpZihJPXYuY2hhckNvZGVBdChGKSw0OD5JfHxJPjU3KXtQPShJPT09NDY/cyt2LnNsaWNlKEYrMSk6di5zbGljZShGKSkrUCx2PXYuc2xpY2UoMCxGKTticmVha319fWImJiFtJiYodj10KHYsMS8wKSk7dmFyIEQ9Qy5sZW5ndGgrdi5sZW5ndGgrUC5sZW5ndGgsVT1EPGc/bmV3IEFycmF5KGctRCsxKS5qb2luKGYpOiIiO3N3aXRjaChiJiZtJiYodj10KFUrdixVLmxlbmd0aD9nLVAubGVuZ3RoOjEvMCksVT0iIiksZCl7Y2FzZSI8Ijp2PUMrditQK1U7YnJlYWs7Y2FzZSI9Ijp2PUMrVSt2K1A7YnJlYWs7Y2FzZSJeIjp2PVUuc2xpY2UoMCxEPVUubGVuZ3RoPj4xKStDK3YrUCtVLnNsaWNlKEQpO2JyZWFrO2RlZmF1bHQ6dj1VK0MrditQO2JyZWFrfXJldHVybiByKHYpfXJldHVybiB6LnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHUrIiJ9LHp9ZnVuY3Rpb24gaCh1LGYpe3ZhciBkPWwoKHU9WnIodSksdS50eXBlPSJmIix1KSkscD1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3IocGkoZikvMykpKSozLHk9TWF0aC5wb3coMTAsLXApLG09Q3VbOCtwLzNdO3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZCh5KmcpK219fXJldHVybntmb3JtYXQ6bCxmb3JtYXRQcmVmaXg6aH19dmFyIFhyLEJ1LEZ1O2xnKHt0aG91c2FuZHM6IiwiLGdyb3VwaW5nOlszXSxjdXJyZW5jeTpbIiQiLCIiXX0pO2Z1bmN0aW9uIGxnKGkpe3JldHVybiBYcj1jZyhpKSxCdT1Yci5mb3JtYXQsRnU9WHIuZm9ybWF0UHJlZml4LFhyfWZ1bmN0aW9uIGhnKGkpe3JldHVybiBNYXRoLm1heCgwLC1waShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIHVnKGksdCl7cmV0dXJuIE1hdGgubWF4KDAsTWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKHBpKHQpLzMpKSkqMy1waShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIGZnKGksdCl7cmV0dXJuIGk9TWF0aC5hYnMoaSksdD1NYXRoLmFicyh0KS1pLE1hdGgubWF4KDAscGkodCktcGkoaSkpKzF9ZnVuY3Rpb24gZGcoaSx0LGUsbil7dmFyIHM9cnAoaSx0LGUpLHI7c3dpdGNoKG49WnIobj09bnVsbD8iLGYiOm4pLG4udHlwZSl7Y2FzZSJzIjp7dmFyIG89TWF0aC5tYXgoTWF0aC5hYnMoaSksTWF0aC5hYnModCkpO3JldHVybiBuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9dWcocyxvKSkmJihuLnByZWNpc2lvbj1yKSxGdShuLG8pfWNhc2UiIjpjYXNlImUiOmNhc2UiZyI6Y2FzZSJwIjpjYXNlInIiOntuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9ZmcocyxNYXRoLm1heChNYXRoLmFicyhpKSxNYXRoLmFicyh0KSkpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSJlIikpO2JyZWFrfWNhc2UiZiI6Y2FzZSIlIjp7bi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPWhnKHMpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSIlIikqMik7YnJlYWt9fXJldHVybiBCdShuKX1mdW5jdGlvbiBwZyhpKXt2YXIgdD1pLmRvbWFpbjtyZXR1cm4gaS50aWNrcz1mdW5jdGlvbihlKXt2YXIgbj10KCk7cmV0dXJuIHNwKG5bMF0sbltuLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUpfSxpLnRpY2tGb3JtYXQ9ZnVuY3Rpb24oZSxuKXt2YXIgcz10KCk7cmV0dXJuIGRnKHNbMF0sc1tzLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUsbil9LGkubmljZT1mdW5jdGlvbihlKXtlPT1udWxsJiYoZT0xMCk7dmFyIG49dCgpLHM9MCxyPW4ubGVuZ3RoLTEsbz1uW3NdLGE9bltyXSxjLGwsaD0xMDtmb3IoYTxvJiYobD1vLG89YSxhPWwsbD1zLHM9cixyPWwpO2gtLSA+MDspe2lmKGw9QWEobyxhLGUpLGw9PT1jKXJldHVybiBuW3NdPW8sbltyXT1hLHQobik7aWYobD4wKW89TWF0aC5mbG9vcihvL2wpKmwsYT1NYXRoLmNlaWwoYS9sKSpsO2Vsc2UgaWYobDwwKW89TWF0aC5jZWlsKG8qbCkvbCxhPU1hdGguZmxvb3IoYSpsKS9sO2Vsc2UgYnJlYWs7Yz1sfXJldHVybiBpfSxpfWZ1bmN0aW9uIHljKCl7dmFyIGk9ZWcoKTtyZXR1cm4gaS5jb3B5PWZ1bmN0aW9uKCl7cmV0dXJuIEttKGkseWMoKSl9LFNtLmFwcGx5KGksYXJndW1lbnRzKSxwZyhpKX1mdW5jdGlvbiB5ZyhpLHQpe3JldHVybiBpLm1hcChlPT57Y29uc3Qgbj1bXTtsZXQgcztyZXR1cm4gZS5mb3JFYWNoKHI9PntpZihzKXtjb25zdCBvPXJpKHIscykqMTgwL01hdGguUEk7aWYobz50KXtjb25zdCBhPVZwKHMsciksYz0xL01hdGguY2VpbChvL3QpO2xldCBsPWM7Zm9yKDtsPDE7KW4ucHVzaChhKGwpKSxsKz1jfX1uLnB1c2gocz1yKX0pLG59KX1mdW5jdGlvbiBtZyhpLHttaW5Mbmc6dCxtYXhMbmc6ZSxtaW5MYXQ6bixtYXhMYXQ6c309e30pe2NvbnN0IHI9TWF0aC5yb3VuZCh5aSgzNjAvaSwyKS9NYXRoLlBJKSxvPSgxK01hdGguc3FydCg1KSkvMixhPWQ9PmQvbyozNjAlMzYwLTE4MCxjPWQ9Pk1hdGguYWNvcygyKmQvci0xKS9NYXRoLlBJKjE4MC05MCxsPWQ9PnIqKE1hdGguY29zKChkKzkwKSpNYXRoLlBJLzE4MCkrMSkvMixoPVtzIT09dm9pZCAwP01hdGguY2VpbChsKHMpKTowLG4hPT12b2lkIDA/TWF0aC5mbG9vcihsKG4pKTpyLTFdLHU9dD09PXZvaWQgMCYmZT09PXZvaWQgMD8oKT0+ITA6dD09PXZvaWQgMD9kPT5kPD1lOmU9PT12b2lkIDA/ZD0+ZD49dDplPj10P2Q9PmQ+PXQmJmQ8PWU6ZD0+ZD49dHx8ZDw9ZSxmPVtdO2ZvcihsZXQgZD1oWzBdO2Q8PWhbMV07ZCsrKXtjb25zdCBwPWEoZCk7dShwKSYmZi5wdXNoKFtwLGMoZCldKX1yZXR1cm4gZn1mdW5jdGlvbiBtYyhpLHQsZT0hMSl7cmV0dXJuIGU/JHAodCxpKTpqeShpLHQpfWZ1bmN0aW9uIGdnKGksdCl7Y29uc3QgZT17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tuLHNdLFtyLG9dXT1maChlKTtpZihNYXRoLm1pbihNYXRoLmFicyhyLW4pLE1hdGguYWJzKG8tcykpPHQpcmV0dXJuW107Y29uc3QgYT1uPnJ8fG8+PTg5fHxzPD0tODk7cmV0dXJuIG1nKHQse21pbkxuZzpuLG1heExuZzpyLG1pbkxhdDpzLG1heExhdDpvfSkuZmlsdGVyKGM9Pm1jKGMsZSxhKSl9ZnVuY3Rpb24geGcoaSx7cmVzb2x1dGlvbjp0PTEvMCxiYm94OmUscHJvamVjdGlvbjpufT17fSl7Y29uc3Qgcz15ZyhpLHQpLHI9Vmkocyksbz1nZyhpLHQpLGE9Wy4uLnIsLi4ub10sYz17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tsLGhdLFt1LGZdXT1maChjKSxkPWw+dXx8Zj49ODl8fGg8PS04OTtsZXQgcD1bXTtpZihkKXtjb25zdCBNPUFtKGEpLnRyaWFuZ2xlcygpLEE9bmV3IE1hcChhLm1hcCgoW1MsX10sRSk9PltgJHtTfS0ke199YCxFXSkpO00uZmVhdHVyZXMuZm9yRWFjaChTPT57Y29uc3QgXz1TLmdlb21ldHJ5LmNvb3JkaW5hdGVzWzBdLnNsaWNlKDAsMykucmV2ZXJzZSgpLEU9W107aWYoXy5mb3JFYWNoKChbeix2XSk9Pntjb25zdCBDPWAke3p9LSR7dn1gO0EuaGFzKEMpJiZFLnB1c2goQS5nZXQoQykpfSksRS5sZW5ndGg9PT0zKXtpZihFLnNvbWUoej0+ejxyLmxlbmd0aCkpe2NvbnN0IHo9Uy5wcm9wZXJ0aWVzLmNpcmN1bWNlbnRlcjtpZighbWMoeixjLGQpKXJldHVybn1wLnB1c2goLi4uRSl9fSl9ZWxzZSBpZihvLmxlbmd0aCl7Y29uc3QgTT10cy5mcm9tKGEpO2ZvcihsZXQgQT0wLFM9TS50cmlhbmdsZXMubGVuZ3RoO0E8UztBKz0zKXtjb25zdCBfPVsyLDEsMF0ubWFwKHo9Pk0udHJpYW5nbGVzW0Erel0pLEU9Xy5tYXAoej0+YVt6XSk7aWYoXy5zb21lKHo9Pno8ci5sZW5ndGgpKXtjb25zdCB6PVswLDFdLm1hcCh2PT5vcChFLEM9PkNbdl0pKTtpZighbWMoeixjLGQpKWNvbnRpbnVlfXAucHVzaCguLi5fKX19ZWxzZXtjb25zdHt2ZXJ0aWNlczpNLGhvbGVzOkE9W119PVFoKHMpO3A9cHkoTSxBLDIpfWxldCB5PWU/W2VbMF0sZVsyXV06c3IoYSxNPT5NWzBdKSxtPWU/W2VbMV0sZVszXV06c3IoYSxNPT5NWzFdKTtpZihuKXtjb25zdFtNLEFdPW4oW3lbMF0sbVswXV0pLFtTLF9dPW4oW3lbMV0sbVsxXV0pO3k9W00sU10sbT1bLUEsLV9dfWNvbnN0IGc9eWMoeSxbMCwxXSksYj15YyhtLFswLDFdKSx3PWEubWFwKChbTSxBXSk9PntpZihuKXtjb25zdFtTLF9dPW4oW00sQV0pO3JldHVybltnKFMpLGIoLV8pXX1lbHNlIHJldHVybltnKE0pLGIoQSldfSk7cmV0dXJue2NvbnRvdXI6cyx0cmlhbmdsZXM6e3BvaW50czphLGluZGljZXM6cCx1dnM6d319fWNvbnN0IEl1PW5ldyB1ZSgpLnNldEF0dHJpYnV0ZT8ic2V0QXR0cmlidXRlIjoiYWRkQXR0cmlidXRlIjtmdW5jdGlvbiBKcihpLHQsZSxuKXtjb25zdCBzPWkubWFwKHI9PnIubWFwKChbbyxhXSk9PntpZihuKXtjb25zdFtjLGxdPW4oW28sYV0pO3JldHVybltjLC1sLHRdfXJldHVybiBlP1kwKG8sYSx0KTpbbyxhLHRdfSkpO3JldHVybiBRaChzKX1mdW5jdGlvbiB3ZyhpLHQsZSxuLHMpe2NvbnN0e3ZlcnRpY2VzOnIsaG9sZXM6b309SnIoaSx0LG4scykse3ZlcnRpY2VzOmF9PUpyKGksZSxuLHMpLGM9VmkoW2Escl0pLGw9TWF0aC5yb3VuZChhLmxlbmd0aC8zKSxoPW5ldyBTZXQobyk7bGV0IHU9MDtjb25zdCBmPVtdO2ZvcihsZXQgcD0wO3A8bDtwKyspe2xldCB5PXArMTtpZih5PT09bCl5PXU7ZWxzZSBpZihoLmhhcyh5KSl7Y29uc3QgbT15O3k9dSx1PW19Zi5wdXNoKHAscCtsLHkrbCksZi5wdXNoKHkrbCx5LHApfWNvbnN0IGQ9W107Zm9yKGxldCBwPTE7cD49MDtwLS0pZm9yKGxldCB5PTA7eTxsO3krPTEpZC5wdXNoKHkvKGwtMSkscCk7cmV0dXJue2luZGljZXM6Zix2ZXJ0aWNlczpjLHV2czpkLHRvcFZlcnRzOmF9fWZ1bmN0aW9uIGt1KGksdCxlLG4scyxyKXtyZXR1cm57aW5kaWNlczpuP2kuaW5kaWNlczppLmluZGljZXMuc2xpY2UoKS5yZXZlcnNlKCksdmVydGljZXM6SnIoW2kucG9pbnRzXSx0LHMscikudmVydGljZXMsdXZzOmV9fWNvbnN0IE51PSh7cG9seWdvbkdlb0pzb246aSxzdGFydEhlaWdodDp0LGVuZEhlaWdodDplLGN1cnZhdHVyZVJlc29sdXRpb246bj0xLGNhcnRlc2lhbjpzPSEwLGhhc1NpZGU6cj0hMCxoYXNCb3R0b206bz0hMSxoYXNUb3A6YT0hMSxwcm9qZWN0aW9uOmMsYmJveDpsfSk9PntpLmZvckVhY2goZz0+e055KGcpfHxnLnJldmVyc2UoKX0pO2NvbnN0e2NvbnRvdXI6aCx0cmlhbmdsZXM6dX09eGcoaSx7cmVzb2x1dGlvbjpuLGJib3g6bCxwcm9qZWN0aW9uOmN9KTtsZXQgZj17fSxkO3ImJihmPXdnKGgsdCE9bnVsbD90OmUsZSE9bnVsbD9lOnQscyxjKSxkPWYudG9wVmVydHMpO2xldCBwPVtdOyhvfHxhKSYmKHA9VmkodS51dnMpKTtsZXQgeT17fTtvJiYoeT1rdSh1LHQscCwhMSxzLGMpKTtsZXQgbT17fTtyZXR1cm4gYSYmKG09a3UodSxlLHAsITAscyxjKSkse2NvbnRvdXI6aCx0cmlhbmdsZXM6dSxzaWRlVG9yc286Zixib3R0b21DYXA6eSx0b3BDYXA6bSx0b3BWZXJ0czpkfX07Y2xhc3MgYmcgZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0LGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJQb2x5Z29uQnVmZmVyR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz1GdCh7cG9seWdvbkdlb0pzb246dCxzdGFydEhlaWdodDowLGVuZEhlaWdodDoxLGhhc1RvcDohMCx0b3BGaXJzdDohMSxoYXNCb3R0b206ITAsaGFzU2lkZTohMCxjdXJ2YXR1cmVSZXNvbHV0aW9uOjEsY2FydGVzaWFuOiEwLHVzZXJEYXRhUnNvT2Zmc2V0OjB9LGUpO2NvbnN0e2VuZEhlaWdodDpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHVzZXJEYXRhUnNvT2Zmc2V0OmwscHJvamVjdGlvbjpofT10aGlzLnBhcmFtZXRlcnMse2NvbnRvdXI6dSxzaWRlVG9yc286Zix0b3BWZXJ0czpkLGJvdHRvbUNhcDpwLHRvcENhcDp5fT1OdShGdCh7fSx0aGlzLnBhcmFtZXRlcnMpKTtsZXQgbT1bXSxnPVtdLGI9W10sdz0wO2NvbnN0IHg9TT0+e2NvbnN0IEE9TWF0aC5yb3VuZChtLmxlbmd0aC8zKSxTPWIubGVuZ3RoO209bS5jb25jYXQoTS52ZXJ0aWNlcyksZz1nLmNvbmNhdChNLnV2cyksYj1iLmNvbmNhdChBP00uaW5kaWNlcy5tYXAoXz0+XytBKTpNLmluZGljZXMpLHRoaXMuYWRkR3JvdXAoUyxiLmxlbmd0aC1TLHcrKyl9O3MmJnImJngoeSksYSYmKHgoZiksdGhpcy51c2VyRGF0YS50b3BWZXJ0cz1sP0pyKHUsbitsLGMsaCkudmVydGljZXM6ZCksbyYmeChwKSxzJiYhciYmeCh5KSx0aGlzLnNldEluZGV4KGIpLHRoaXNbSXVdKCJwb3NpdGlvbiIsbmV3IEJlKG0sMykpLHRoaXNbSXVdKCJ1diIsbmV3IEJlKGcsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKX19dmFyIE1nPWk9Pntjb25zdCBhPWkse2Nvb3JkaW5hdGU6dCxzdGFydEhlaWdodDplLGhlaWdodDpufT1hLHM9SnUoYSxbImNvb3JkaW5hdGUiLCJzdGFydEhlaWdodCIsImhlaWdodCJdKTtsZXQgcj1lfHwwO3JldHVybiB0eXBlb2YgZSE9InVuZGVmaW5lZCImJnR5cGVvZiBuIT0idW5kZWZpbmVkIiYmKHI9ZStuKSxuZXcgYmcoW3RdLFplKEZ0KHt9LHMpLHtzdGFydEhlaWdodDplLGVuZEhlaWdodDpyfSkpfTtjb25zdCBBZz0oe2Nvb3JkaW5hdGVzQXJyOmksc3RhcnQ6dCxkZXB0aDplLHVzZUdyb3VwczpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHByb2plY3Rpb246bCxjdXJ2YXR1cmVSZXNvbHV0aW9uOmgsYmJveDp1fSk9Pntjb25zdCBmPWwmJlhpKGwpO2YmJihjPSExKSx0fHwodD1bMF0pO2NvbnN0IGQ9aS5tYXAoKHAseSk9Pnt2YXIgbSxnO3JldHVybiBNZyh7Y29vcmRpbmF0ZTpwLHByb2plY3Rpb246ZixzdGFydEhlaWdodDoobT10W3ldKSE9bnVsbD9tOnRbMF0saGVpZ2h0OihnPWVbeV0pIT1udWxsP2c6ZVswXSxoYXNUb3A6cyE9bnVsbD9zOiEwLHRvcEZpcnN0OnIhPW51bGw/cjohMSxoYXNCb3R0b206byE9bnVsbD9vOiEwLGhhc1NpZGU6YSE9bnVsbD9hOiEwLGNhcnRlc2lhbjpjIT1udWxsP2M6ITAsY3VydmF0dXJlUmVzb2x1dGlvbjpoIT1udWxsP2g6MSxiYm94OnV9KX0pO3JldHVybiBKaShkLG4pfSxTZz0oe2Nvb3JkaW5hdGVzQXJyOmksbGluZVdpZHRoOnQsc3RhcnQ6ZSx1c2VHcm91cHM6bn0pPT57Y29uc3Qgcj1pLm1hcCgobyxhKT0+e3ZhciBjO3JldHVybiBOdSh7cG9seWdvbkdlb0pzb246W29dLHN0YXJ0SGVpZ2h0OihjPWVbYV0pIT1udWxsP2M6ZVswXX0pLnRvcFZlcnRzfSkubWFwKChvLGEpPT57dmFyIGw7Y29uc3QgYz0obD10W2FdKSE9bnVsbD9sOnRbMF07cmV0dXJuIFpoKHtub2RlczpvLHNldFBvaW50V2lkdGg6KCk9PmN9KX0pO3JldHVybiBKaShyLG4pfTt2YXIgX2c9KGksdCxlKT0+bmV3IFByb21pc2UoKG4scyk9Pnt2YXIgcj1jPT57dHJ5e2EoZS5uZXh0KGMpKX1jYXRjaChsKXtzKGwpfX0sbz1jPT57dHJ5e2EoZS50aHJvdyhjKSl9Y2F0Y2gobCl7cyhsKX19LGE9Yz0+Yy5kb25lP24oYy52YWx1ZSk6UHJvbWlzZS5yZXNvbHZlKGMudmFsdWUpLnRoZW4ocixvKTthKChlPWUuYXBwbHkoaSx0KSkubmV4dCgpKX0pO2Z1bmN0aW9uIHZnKGkpe3JldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhpKS5yZWR1Y2UoZnVuY3Rpb24odCxlKXtyZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSx7dmFsdWU6aVtlXSxlbnVtZXJhYmxlOiEwfSl9LHt9KX0oaT0+e2NvbnN0IHQ9e3J1bihlLG4pe2NvbnN0IHM9bmV3IEZ1bmN0aW9uKCJyZXR1cm4gKCIrZSsiKS5hcHBseShudWxsLCBhcmd1bWVudHMpOyIpO3JldHVybiBzLmFwcGx5KHMsbil9LG1ldGhvZHMoKXtyZXR1cm4gT2JqZWN0LmtleXModCl9fTthZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIixlPT5fZyh2b2lkIDAsW2VdLGZ1bmN0aW9uKih7ZGF0YTpufSl7dHJ5e2NvbnN0IHM9dFtuLm1ldGhvZF07aWYocyl7Y29uc3Qgcj15aWVsZCBzLmFwcGx5KHMsbi5wYXJhbXMpO3IudHJhbnNmZXImJnIubWVzc2FnZT9wb3N0TWVzc2FnZSh7aWQ6bi5pZCxyZXN1bHQ6ci5tZXNzYWdlLGVycm9yOm51bGx9LHIudHJhbnNmZXIpOnBvc3RNZXNzYWdlKHtpZDpuLmlkLHJlc3VsdDpyLGVycm9yOm51bGx9KX1lbHNlIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXRob2QgIicrbi5tZXRob2QrJyInKX1jYXRjaChzKXtwb3N0TWVzc2FnZSh7aWQ6bi5pZCxyZXN1bHQ6bnVsbCxlcnJvcjp2ZyhzKX0pfX0pKSxPYmplY3Qua2V5cyhpKS5mb3JFYWNoKGU9Pnt0W2VdPWlbZV19KSxwb3N0TWVzc2FnZSgicmVhZHkiKX0pKHtleHRydWRlUG9seWdvbjpjeSxsaW5lOnV5LGxpbmUyOmR5LGNvbmljUG9seWdvbjpBZyxjb25pY0xpbmU6U2d9KX0pKCk7Cg==",J=g=>Uint8Array.from(atob(g),t=>t.charCodeAt(0)),z=typeof window!="undefined"&&window.Blob&&new Blob([J(o)],{type:"text/javascript;charset=utf-8"});function T(g){let t;try{if(t=z&&(window.URL||window.webkitURL).createObjectURL(z),!t)throw"";const r=new Worker(t,{name:g==null?void 0:g.name});return r.addEventListener("error",()=>{(window.URL||window.webkitURL).revokeObjectURL(t)}),r}catch(r){return new Worker("data:text/javascript;base64,"+o,{name:g==null?void 0:g.name})}finally{t&&(window.URL||window.webkitURL).revokeObjectURL(t)}}const R=g=>{const t=new BufferGeometry;return Object.keys(g).forEach(r=>{r==="groups"?g[r].forEach(m=>{t.addGroup(m.start,m.count,m.materialIndex)}):r==="index"?t.setIndex(new BufferAttribute(g[r].array,g[r].itemSize)):t.setAttribute(r,new BufferAttribute(g[r].array,g[r].itemSize))}),t};class Q{constructor(t){this.pluginName="worker",this.bufferGeometryLoader=new BufferGeometryLoader,this.cacheObj={},this._dispose=!1,this.options=W({dbName:"base",cacheVersion:"1"},t),this.store=createStore(this.options.dbName,"attributes")}install(t){this.pencil=t;const r=new esusLite.WorkerPool(T,{maxWorkers:this.options.maxWorkers});this.pool=r}geoGeometry(t,r){return V(this,null,function*(){const{mesaage:m,cacheKey:v,userData:C,cacheVersion:_,cb:w}=W(W({},this.options),r),I=this.pool,{err:O,res:Pe}=yield I.exec(t,[W({},m)],void 0,!0);if(O)throw O;const Ne=R(Pe);if(Object.assign(Ne.userData,W({},C)),w&&(yield w(Ne)),v){const{cacheObj:Fe}=this;Fe[v]||(Fe[v]={[_]:[]}),Fe[v][_].push(W({attributes:Pe},C))}return Ne})}getCachedGeometry(t){return V(this,null,function*(){const{cacheKey:r,cacheVersion:m}=t;if(r){const v=yield get(r,this.store),C=m||this.options.cacheVersion;return v!=null&&v[C]?v[C].map(_=>{const w=_,{attributes:I}=w,O=Y(w,["attributes"]),Pe=R(I);return Object.assign(Pe.userData,W({},O)),Pe}):[]}else return[]})}saveCache(){setMany(Object.entries(this.cacheObj),this.store)}dispose(){this.cacheObj={},this.pool.dispose(),this._dispose=!0}}class RoomEnvironment extends Scene{constructor(){super();const t=new BoxGeometry;t.deleteAttribute("uv");const r=new MeshStandardMaterial({side:BackSide}),m=new MeshStandardMaterial,v=new PointLight(16777215,900,28,2);v.position.set(.418,16.199,.3),this.add(v);const C=new Mesh(t,r);C.position.set(-.757,13.219,.717),C.scale.set(31.713,28.305,28.591),this.add(C);const _=new InstancedMesh(t,m,6),w=new Object3D;w.position.set(-10.906,2.009,1.846),w.rotation.set(0,-.195,0),w.scale.set(2.328,7.905,4.651),w.updateMatrix(),_.setMatrixAt(0,w.matrix),w.position.set(-5.607,-.754,-.758),w.rotation.set(0,.994,0),w.scale.set(1.97,1.534,3.955),w.updateMatrix(),_.setMatrixAt(1,w.matrix),w.position.set(6.167,.857,7.803),w.rotation.set(0,.561,0),w.scale.set(3.927,6.285,3.687),w.updateMatrix(),_.setMatrixAt(2,w.matrix),w.position.set(-2.017,.018,6.124),w.rotation.set(0,.333,0),w.scale.set(2.002,4.566,2.064),w.updateMatrix(),_.setMatrixAt(3,w.matrix),w.position.set(2.291,-.756,-2.621),w.rotation.set(0,-.286,0),w.scale.set(1.546,1.552,1.496),w.updateMatrix(),_.setMatrixAt(4,w.matrix),w.position.set(-2.193,-.369,-5.547),w.rotation.set(0,.516,0),w.scale.set(3.875,3.487,2.986),w.updateMatrix(),_.setMatrixAt(5,w.matrix),this.add(_);const I=new Mesh(t,createAreaLightMaterial(50));I.position.set(-16.116,14.37,8.208),I.scale.set(.1,2.428,2.739),this.add(I);const O=new Mesh(t,createAreaLightMaterial(50));O.position.set(-16.109,18.021,-8.207),O.scale.set(.1,2.425,2.751),this.add(O);const Pe=new Mesh(t,createAreaLightMaterial(17));Pe.position.set(14.904,12.198,-1.832),Pe.scale.set(.15,4.265,6.331),this.add(Pe);const Ne=new Mesh(t,createAreaLightMaterial(43));Ne.position.set(-.462,8.89,14.52),Ne.scale.set(4.38,5.441,.088),this.add(Ne);const Fe=new Mesh(t,createAreaLightMaterial(20));Fe.position.set(3.235,11.486,-12.541),Fe.scale.set(2.5,2,.1),this.add(Fe);const Ae=new Mesh(t,createAreaLightMaterial(100));Ae.position.set(0,20,0),Ae.scale.set(1,.1,1),this.add(Ae)}dispose(){const t=new Set;this.traverse(r=>{r.isMesh&&(t.add(r.geometry),t.add(r.material))});for(const r of t)r.dispose()}}function createAreaLightMaterial(g){const t=new MeshBasicMaterial;return t.color.setScalar(g),t}const BLOCKLISTED_GPUS=["geforce 320m","geforce 8600","geforce 8600m gt","geforce 8800 gs","geforce 8800 gt","geforce 9400","geforce 9400m g","geforce 9400m","geforce 9600m gt","geforce 9600m","geforce fx go5200","geforce gt 120","geforce gt 130","geforce gt 330m","geforce gtx 285","google swiftshader","intel g41","intel g45","intel gma 4500mhd","intel gma x3100","intel hd 3000","intel q45","legacy","mali-2","mali-3","mali-4","quadro fx 1500","quadro fx 4","quadro fx 5","radeon hd 2400","radeon hd 2600","radeon hd 4670","radeon hd 4850","radeon hd 4870","radeon hd 5670","radeon hd 5750","radeon hd 6290","radeon hd 6300","radeon hd 6310","radeon hd 6320","radeon hd 6490m","radeon hd 6630m","radeon hd 6750m","radeon hd 6770m","radeon hd 6970m","sgx 543","sgx543"],apple=[],amd=["2","3","4","6","12","15","25","48","455","535","555","575","600","610","625","630","640","694","699","740","880","900","2000","2270","2600","3200","3800","3900","4000","4150","4170","4190","4250","4800","5170","5400","5450","5470","5650","5670","5730","5750","5950","6150","6230","6250","6290","6300","6310","6320","6350","6370","6380","6410","6450","6460","6470","6480","6490","6510","6520","6530","6540","6550","6570","6620","6630","6670","6730","6760","6790","6980","7290","7310","7340","7400","7420","7450","7480","7500","7520","7540","7550","7610","7620","7640","7650","7670","7730","7820","8180","8210","8240","8250","8330","8350","8400","8410","8450","8490","8500","8510","8530","8600","8610","8690","8730","8760","8850","9171","9173","9874","10000","v","9999999999"],radeon=["2","3","4","6","25","48","455","535","555","575","610","625","630","640","740","880","1305","1605","2600","3200","4150","4250","5000","5400","5450","5470","5650","5670","5730","5750","5770","6230","6250","6290","6300","6310","6320","6350","6370","6380","6410","6450","6460","6470","6480","6490","6510","6520","6530","6540","6550","6570","6620","6630","6670","6730","6760","6790","7000","7290","7310","7340","7400","7420","7450","7480","7500","7520","7540","7550","7610","7620","7640","7650","7670","7730","8180","8210","8240","8250","8330","8350","8400","8410","8450","8490","8500","8510","8530","8600","8610","8690","8730","8850","9171","9173"],nvidia=["1","6","15","51","120","130","140","160","180","210","220","260","295","310","315","320","410","415","420","425","430","440","445","510","525","530","540","545","555","590","605","610","615","625","630","635","705","710","720","730","735","755","765","800","810","820","840","845","860","910","945","1010","1100","1800","2800","5010","5400","8400","8600","9300","9400","9600","9800","gpu","prexpe"],geforce=["10","120","130","210","240","280","295","320","410","415","420","425","430","440","445","510","520","525","530","540","545","555","590","605","610","615","620","625","630","635","705","710","720","730","735","755","765","800","810","820","840","845","860","910","945","1010","2075","8400","8600","9300","9400","9600","9800","gpu","prexpe"],adreno=["5","7","540","618","630","675","680","685"],tier0GPU={apple,amd,radeon,nvidia,geforce,adreno},types=["intel","apple","amd","radeon","nvidia","geforce","adreno"];class Benchmarks{constructor(t){C0(this,"renderer");this.renderer=t}query(){const t=this.renderer,r=this.getGpuType();if(!r)return this.queryFallback();if(r==="intel")return{tier:0,gpu:t};const m=tier0GPU[r],v=this.getGPUVersion();return m.includes(v)?{tier:0,renderer:t}:this.queryFallback()}getGpuType(){const t=this.renderer;for(const r of types)if(t.includes(r))return r}getGPUVersion(){var v;const r=this.renderer.replace(/\([^)]+\)/,""),m=r.match(/\d+/)||r.match(/(\W|^)([A-Za-z]{1,3})(\W|$)/g);return(v=m==null?void 0:m.join("").replace(/\W|amd/g,""))!=null?v:""}queryFallback(){const t=this.renderer,r=BLOCKLISTED_GPUS.find(m=>t.includes(m));return r?{tier:0,gpu:r}:{tier:3,gpu:t}}}class WebGL{constructor(){C0(this,"rawRenderer");C0(this,"renderer");const t=this.getRawRenderer();this.rawRenderer=t;const r=this.getRenderer();this.renderer=r}getRawRenderer(){try{const r=document.createElement("canvas").getContext("webgl"),m=r==null?void 0:r.getExtension("WEBGL_debug_renderer_info");return r&&m?r.getParameter(m.UNMASKED_RENDERER_WEBGL):""}catch(t){return""}}getRenderer(){const t=this.rawRenderer;return t?t.toLowerCase().replace(/.*angle ?\((.+)\)(?: on vulkan [0-9.]+)?$/i,"$1").replace(/\s(\d{1,2}gb|direct3d.+$)|\(r\)| \([^)]+\)$/g,"").replace(/(?:vulkan|opengl) \d+\.\d+(?:\.\d+)?(?: \((.*)\))?/,"$1"):""}query(){return{WebP:this.isWebPAvailable(),WebGL:this.isWebGLAvailable(),WebGL2:this.isWebGL2Available(),WebGL2RC:this.isWebGL2RenderingContextAvailable(),isGPUAcceleratorEnabled:this.isGPUAcceleratorAvailable()}}isWebGLAvailable(){try{const t=document.createElement("canvas");return!!(window.WebGLRenderingContext&&(t.getContext("webgl")||t.getContext("experimental-webgl")))}catch(t){return!1}}isWebGL2Available(){try{const t=document.createElement("canvas");return!!(window.WebGL2RenderingContext&&t.getContext("webgl2"))}catch(t){return!1}}isWebGL2RenderingContextAvailable(){return typeof window.WebGL2RenderingContext!="undefined"}isGPUAcceleratorAvailable(){const t=this.rawRenderer;return!/SwiftShader/gi.test(t)}isColorSpaceAvailable(t){try{const r=document.createElement("canvas"),m=window.WebGL2RenderingContext&&r.getContext("webgl2");return m?(m.drawingBufferColorSpace=t,m.drawingBufferColorSpace===t):!1}catch(r){return!1}}isWebPAvailable(){try{return document.createElement("canvas").toDataURL("image/webp").indexOf("data:image/webp")===0}catch(t){return!1}}}const detect=()=>{try{const g=new WebGL,t=new Benchmarks(g.renderer);return q0(q0({},g.query()),t.query())}catch(g){return console.error("vis-core: feature detection failed",g),{tier:0}}},isGzip=g=>!!(g.endsWith(".gzip")||g.endsWith(".gz")),jsonFetch=(g,t,r=isGzip)=>{const m=esusLite.makePromiseCreator(!0);return window.fetch(g).then(v=>{let C=v;if(C.ok)return r(g)&&C.headers.get("content-encoding")!=="gzip"?C.blob().then(_=>{const w=new DecompressionStream("gzip"),I=_.stream().pipeThrough(w);return new Response(I)}):C;throw new Error("Network response was not ok.")}).then(v=>v.json()).then(v=>{m.resolve(v)}).catch(v=>{m.reject(v)}),m.promise},compareVersion=(g,t)=>{if(!g&&!t)return 0;if(!g&&t)return-1;if(g&&!t)return 1;const r=g.split("."),m=t.split("."),v=Math.max(r.length,m.length);for(;r.length<v;)r.push("0");for(;m.length<v;)m.push("0");for(let C=0;C<v;C++){const _=parseInt(r[C]),w=parseInt(m[C]);if(_>w)return 1;if(_<w)return-1}return 0};class Config{constructor(t){C0(this,"editor");C0(this,"meta",{name:"",key:"",open:!1,jsonVersion:"0.0.0",sdkVersion:"0.0.0"});this.editor=t}setConfig(t,r){this.meta[t]=r,this.editor.emit("configChanged",q0({},this.meta))}fromJSON(t){Object.keys(t).forEach(r=>{const m=r==="version"?"jsonVersion":r;m in this.meta&&this.setConfig(m,t[r])})}compareVersion(){compareVersion(this.meta.jsonVersion,this.meta.sdkVersion)===1&&console.warn("vis-core 版本过低,可能会出现问题","json:"+this.meta.jsonVersion,"sdk:"+this.meta.sdkVersion)}toJSON(){return{version:this.meta.sdkVersion}}}function applyFixes(g,t){const r=[{version:"0.5.38",fix:()=>{var _;(_=t.v)!=null&&_.eo&&Object.keys(t.v.eo).forEach(w=>{["mouseLeft","mouseRight","mouseWheel","label","labelLite","shadowMap","autoRotate","equirectangular"].includes(w)&&(t.v.eo[w]=!!t.v.eo[w])}),t.h.u.forEach(w=>{w.type==="SetSetting"&&(w.attributeName==="阴影"&&(w.attributeName="shadowMap"),w.newValue=!!w.newValue,w.oldValue=!!w.oldValue)})}},{version:"0.7.14",fix:()=>{t.h.u.forEach(_=>{_.objectUuid&&(_.objectUuid=_.objectUuid.replace(_.objectUuid[0],_.objectUuid[0].toLowerCase()))})}},{version:"0.13.0",fix:()=>{if(t.h.u[0]&&t.h.u[0].visType==="city"&&(t.h.u[0].visOptions.jsonName||(t.h.u=[])),t.h.u[0]&&t.h.u[0].visType==="map"){if(t.h.u[0].visOptions.geojson){const{geojson:_,adcode:w,geojsonLite:I}=t.h.u[0].visOptions;t.h.u[0].visOptions=Ji(q0({},t.h.u[0].visOptions),{geojsonMap:{[w]:_},extrudeLineGeojsonMap:{[w]:I}}),delete t.h.u[0].visOptions.geojson,delete t.h.u[0].visOptions.geojsonLite}if(t.h.u[0].visOptions.bbox){const{bbox:_,bboxMap:w,adcode:I}=t.h.u[0].visOptions;t.h.u[0].visOptions=Ji(q0({},t.h.u[0].visOptions),{bboxMap:w||{[I]:_}}),delete t.h.u[0].visOptions.bbox}if(t.h.u[0].visOptions.worldBg){const{worldBg:_}=t.h.u[0].visOptions;t.h.u[0].visOptions=Ji(q0({},t.h.u[0].visOptions),{parentBg:_}),delete t.h.u[0].visOptions.worldBg}t.h.u[0].visOptions.adcode===0&&(t.h.u[0].visType="world")}t.h.u[0]&&t.h.u[0].visType==="world"&&(t.h.u[0].visType="map",t.h.u[0].visOptions={adcode:0,mapDepth:5,lineWidth:2,worldPacificCentre:!0,extrudeLine:!1})}},{version:"0.18.1",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="FJ"&&(t.h.u[0].visType="map2"),t.h.u[0]&&t.h.u[0].visType==="earth3"&&(t.h.u[0].visType="earth",t.h.u[0].visOptions.style="countryPlate")}},{version:"0.18.14",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u.forEach(_=>{if(_.type==="SetSetting"&&_.attributeName.startsWith("测试")&&typeof _.newValue=="string"&&_.newValue.includes(":::")){const w=_.newValue.split(":::")[1];_.attributeName+=":::"+w,_.newValue=_.newValue.split(":::")[0],_.oldValue&&typeof _.oldValue=="string"&&(_.oldValue=_.oldValue.split(":::")[0])}})}},{version:"0.18.16",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u.forEach(_=>{if(_.type==="SetSetting"&&_.attributeName.startsWith("测试")&&_.attributeName.includes(":::")&&!_.attributeName.includes("caId")){const w=_.attributeName.split(":::")[1];_.attributeName=_.attributeName.replace(w,`caId.${w}`)}})}},{version:"0.21.24",fix:()=>{var _,w;t.h.u[0]&&t.h.u[0].visType==="map"&&((w=(_=t.v)==null?void 0:_.eo)!=null&&w.parentBgCurvatureResolution)&&delete t.v.eo.parentBgCurvatureResolution}},{version:"0.23.1",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map2"&&!t.h.u[0].visOptions.cityOnMap&&(t.v.eo||(t.v.eo={}),t.v.eo.clickHandleDrillDown=!0)}},{version:"0.24.1",fix:()=>{var _,w;t.h.u[0]&&t.h.u[0].visType==="map"&&((w=(_=t.v)==null?void 0:_.eo)!=null&&w.drillDownTopMatTwo)&&(delete t.v.eo.drillDownTopMatTwo,t.v.eo.drillDownSecondLevelMats=!0)}},{version:"0.24.2",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map2"&&t.h.u.forEach(_=>{_.objectUuid==="plane#topMatOne"?(_.objectUuid="area",_.materialSlot=0):_.objectUuid==="plane#sideMat"?(_.objectUuid="area",_.materialSlot=1):_.objectUuid==="plane#lineMat"?_.objectUuid="line":_.objectUuid==="plane#extrudeLineMat"?_.objectUuid="extrudeLine":_.objectUuid==="plane#bgTopMatOne"?_.objectUuid="bgPlane#topMat":_.objectUuid==="plane#bgSideMat"?_.objectUuid="bgPlane#sideMat":_.objectUuid==="plane#bgLineMat"?_.objectUuid="bgPlane#lineMat":_.objectUuid==="plane#bgExtrudeLineMat"?_.objectUuid="bgPlane#extrudeLineMat":_.objectUuid==="parentPlane#topMat"?(_.objectUuid="100000area",_.materialSlot=0):_.objectUuid==="parentPlane#sideMat"?(_.objectUuid="100000area",_.materialSlot=1):_.objectUuid==="parentPlane#lineMat"?_.objectUuid="100000line":_.objectUuid==="worldPlane#topMat"?(_.objectUuid="worldarea",_.materialSlot=0):_.objectUuid==="worldPlane#sideMat"?(_.objectUuid="worldarea",_.materialSlot=1):_.objectUuid==="worldPlane#lineMat"?_.objectUuid="worldline":_.objectUuid==="continents#topMat"?(_.objectUuid="continentsArea",_.materialSlot=0):_.objectUuid==="continents#sideMat"?(_.objectUuid="continentsArea",_.materialSlot=1):_.objectUuid==="continents#lineMat"?_.objectUuid="continentsLine":_.objectUuid==="area#river"?_.objectUuid="geography#river":_.objectUuid==="area#grassland"?_.objectUuid="geography#grassland":_.objectUuid==="area-grey#river"?_.objectUuid="geography-grey#river":_.objectUuid==="area-grey#grassland"&&(_.objectUuid="geography-grey#grassland")})}},{version:"0.26.0",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map2"&&(t.v.eo||(t.v.eo={}),t.h.u[0].visType="map",t.h.u[0].visOptions.cityOnMap?(t.h.u[0].visOptions.style="map2CityOnMap",delete t.h.u[0].visOptions.cityOnMap):(t.h.u[0].visOptions.style="map2Base",t.v.eo.bottomPlane=!0))}},{version:"0.26.6",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="earth2"&&(t.h.u[0].visType="earth",t.h.u[0].visOptions.style="base")}},{version:"0.26.13",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&(t.h.u[0].visOptions.clickHandleDrillDown||t.v.eo.clickHandleDrillDown)&&t.v.eo.drillDownFirstLevelUseBgMats===void 0&&(t.v.eo.drillDownFirstLevelUseBgMats=!0)}},{version:"0.27.0",fix:()=>{if(t.h.u[0]&&t.h.u[0].visType==="map"){const _={};t.h.u.forEach((w,I)=>{var O,Pe,Ne;if(w.objectUuid==="area"&&w.materialSlot===0)w.objectUuid="plane#topMat",delete w.materialSlot;else if(w.objectUuid==="area"&&w.materialSlot===1)w.objectUuid="plane#sideMat",delete w.materialSlot;else if(w.objectUuid==="line")w.objectUuid="plane#lineMat";else if(w.objectUuid==="continentsArea"&&w.materialSlot===0)w.objectUuid="continents#topMat",delete w.materialSlot;else if(w.objectUuid==="continentsArea"&&w.materialSlot===1)w.objectUuid="continents#sideMat",delete w.materialSlot;else if(w.objectUuid==="continentsLine")w.objectUuid="continents#lineMat";else if(w.type==="SetSetting"&&((O=w.attributeName)!=null&&O.startsWith("测试"))&&w.attributeName.includes(":::caId.")){const Fe=w.attributeName.split(":::caId.")[1],Ae=t.h.u[0].visOptions.adcode;t.h.u[I]=[{id:w.id,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`extrudePolygon#${Ae}-${Fe}`,copyObjectUuid:`ExtrudePolygon#${Ae}-${Fe}_${w.id}`},{id:w.id+.1,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`line#${Ae}-${Fe}`,copyObjectUuid:`line#${Ae}-${Fe}_${w.id+.1}`}],_[Fe]=w.id}else if((Pe=w.objectUuid)!=null&&Pe.startsWith("planeCopyExtrudePolygon")){const Fe=w.objectUuid.split("CopyExtrudePolygon")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`extrudePolygon#${Ae}-${Fe}_${_[Fe]}`})}else if((Ne=w.objectUuid)!=null&&Ne.startsWith("planeCopyLine")){const Fe=w.objectUuid.split("CopyLine")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`line#${Ae}-${Fe}_${_[Fe]+.1}`})}}),t.h.u=t.h.u.flat()}}},{version:"0.27.8",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&(t.h.u[0].visOptions.mergeSide=!0,t.h.u.forEach(_=>{_.objectUuid==="extrudeLine"?_.objectUuid="plane#lineMat":_.objectUuid==="plane#lineMat"&&(_.objectUuid="extrudeLine")}))}},{version:"0.27.9",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&t.h.u.forEach(_=>{_.objectUuid==="plane#extrudeLineMat"&&(_.objectUuid="plane#lineMat")})}},{version:"0.27.14",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&t.h.u.forEach(_=>{_.objectUuid==="building"&&(_.objectUuid="building#group")})}},{version:"0.29.0",fix:()=>!1}];let m=0,v=r.length-1,C=r.length;for(;m<=v;){const _=Math.floor((m+v)/2);compareVersion(r[_].version,g)>0?(C=_,v=_-1):m=_+1}for(let _=C;_<r.length;_++)r[_].fix()!==!1&&(t.c.version=r[_].version)}const fixJSON=g=>{var t;return g.c||(g={h:{u:g.u},v:{eo:g.eo,bg:g.bg},c:{name:g.name,version:g.v}}),(t=g.c)!=null&&t.key&&delete g.c.key,applyFixes(g.c.version,g),g};class Command{constructor(t){C0(this,"id");C0(this,"updatable");C0(this,"type");C0(this,"name");C0(this,"editor");C0(this,"json",{});this.id=-1,this.updatable=!1,this.type="",this.name="",this.editor=t}toJSON(){const t={};return t.type=this.type,t.id=this.id,t.name=this.name,t.updatable=this.updatable,t}fromJSON(t){if(this.type=t.type,this.id=t.id,this.name=t.name,this.updatable=t.updatable,!this.editor.config.meta.jsonVersion&&t.objectUuid){const r=this.editor.objectByUuid(t.objectUuid);r&&(t.objectUuid=this.editor.uuidByObject(r));const m=this.editor.baseObjectByUuid(t.objectUuid);m&&(t.objectUuid=this.editor.uuidByBaseObject(m))}}fixJSON(){}}class SetColor extends Command{constructor(t,r,m,v){super(t),this.type="SetColor",this.name=`Set ${m}`,this.updatable=!0,this.object=r,this.attributeName=m,this.oldValue=r!==void 0?this.object[this.attributeName].getHex():void 0,this.newValue=v}execute(){this.object&&(this.object[this.attributeName].setHex(this.newValue),this.editor.emit("objectChanged",this.object))}undo(){this.object[this.attributeName].setHex(this.oldValue),this.editor.emit("objectChanged",this.object)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue}}class SetMaterialColor extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialColor",this.name=`Set Material.${m}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[m].getHex():void 0,this.newValue=v,this.attributeName=m}execute(){this.material[this.attributeName].setHex(this.newValue),this.editor.emit("materialChanged",this.material)}undo(){this.material[this.attributeName].setHex(this.oldValue),this.editor.emit("materialChanged",this.material)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetMaterial extends Command{constructor(t,r,m,v){super(t),this.type="SetMaterial",this.name="New Material",this.object=r,this.materialSlot=v,this.oldMaterial=this.editor.getObjectMaterial(r,v),this.newMaterial=m}execute(){this.editor.setObjectMaterial(this.object,this.materialSlot,this.newMaterial),this.editor.emit("materialChanged",this.newMaterial)}undo(){this.editor.setObjectMaterial(this.object,this.materialSlot,this.oldMaterial),this.editor.emit("materialChanged",this.oldMaterial)}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.newMaterial=this.newMaterial.toJSON(),t}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.materialSlot=t.materialSlot,this.oldMaterial=this.editor.getObjectMaterial(this.object,this.materialSlot),this.newMaterial=parseMaterial(t.newMaterial),((r=this.newMaterial.envMap)==null?void 0:r.name)==="PMREM.cubeUv"&&(this.newMaterial.envMap=this.editor.viewport.vis.getRoomEnvMap())}fixJSON(){const t=this.json;if(t&&t.oldMaterial&&delete t.oldMaterial,this.oldMaterial){const r=this.editor.pencil.mList.getKey(this.oldMaterial);r&&r!==t.objectUuid&&(console.warn("SetMaterial:fix:",t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}function parseMaterial(g){if(!g)return null;const t=new ObjectLoader,r=t.parseImages(g.images),m=t.parseTextures(g.textures,r);return t.parseMaterials([g],m)[g.uuid]}const TEXTURE_MAPPING={UVMapping,CubeReflectionMapping,CubeRefractionMapping,EquirectangularReflectionMapping,EquirectangularRefractionMapping,CubeUVReflectionMapping},TEXTURE_WRAPPING={RepeatWrapping,ClampToEdgeWrapping,MirroredRepeatWrapping},TEXTURE_FILTER={NearestFilter,NearestMipmapNearestFilter,NearestMipmapLinearFilter,LinearFilter,LinearMipmapNearestFilter,LinearMipmapLinearFilter};class SetMaterialMap extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialMap",this.name=`Set Material.${m}`,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldMap=r!==void 0?this.material[m]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=m}execute(){if(this.material.hasOwnProperty(this.mapName)){if(this.oldMap){const t=new se$1;t.track(this.oldMap),t.dispose()}this.newMap&&(this.newMap.name==="PMREM.cubeUv"&&(this.newMap=this.editor.viewport.vis.getRoomEnvMap()),this.newMap.anisotropy=this.editor.viewport.vis.tier0?1:this.editor.pencil.maxAnisotropy),this.material[this.mapName]=this.newMap,this.playVideo(this.newMap),this.material instanceof We$1&&(this.material.useMap=!!this.newMap,this.newMap&&this.newMap.wrapS!==RepeatWrapping&&(this.newMap.wrapS=RepeatWrapping,this.newMap.wrapT=RepeatWrapping,this.newMap.needsUpdate=!0)),(!this.oldMap&&this.newMap||this.oldMap&&!this.newMap)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material)}}undo(){this.material[this.mapName]=this.oldMap,this.playVideo(this.oldMap),this.material instanceof We$1&&(this.material.useMap=!!this.newMap),(!this.oldMap&&this.newMap||this.oldMap&&!this.newMap)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material)}playVideo(t){if(t&&t instanceof VideoTexture){const r=t.source.data;r&&r.play()}}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.mapName=this.mapName,t.newMap=serializeMap(this.newMap),t}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.mapName=t.mapName,this.oldMap=this.object&&this.material?this.material[this.mapName]:void 0,((r=t.newMap)==null?void 0:r.name)==="PMREM.cubeUv"?this.newMap=this.editor.viewport.vis.getRoomEnvMap():this.newMap=parseTexture(t.newMap)}fixJSON(){const t=this.json;if(t&&t.oldMap&&delete t.oldMap,this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}function parseTexture(g){let t=null;if(g){const r=new ObjectLoader;if(g.isVideoTexture){const m=document.createElement("video");m.src=g.images[0].url,m.muted=!0,m.loop=!0,m.preload="auto";const v={[g.images[0].uuid]:new VideoTexture(m)};t=parseVideoTextures([g],v)[g.uuid]}else{const m=r.parseImages(g.images);t=r.parseTextures([g],m)[g.uuid]}t.sourceFile=g.sourceFile}return t}const parseVideoTextures=(g,t)=>{function r(v,C){return typeof v=="number"?v:(console.warn("THREE.ObjectLoader.parseTexture: Constant should be in numeric form.",v),C[v])}const m={};if(g!==void 0)for(let v=0,C=g.length;v<C;v++){const _=g[v];let w=t[_.image];w.needsUpdate=!0,w.uuid=_.uuid,_.name!==void 0&&(w.name=_.name),_.mapping!==void 0&&(w.mapping=r(_.mapping,TEXTURE_MAPPING)),_.channel!==void 0&&(w.channel=_.channel),_.offset!==void 0&&w.offset.fromArray(_.offset),_.repeat!==void 0&&w.repeat.fromArray(_.repeat),_.center!==void 0&&w.center.fromArray(_.center),_.rotation!==void 0&&(w.rotation=_.rotation),_.wrap!==void 0&&(w.wrapS=r(_.wrap[0],TEXTURE_WRAPPING),w.wrapT=r(_.wrap[1],TEXTURE_WRAPPING)),_.format!==void 0&&(w.format=_.format),_.internalFormat!==void 0&&(w.internalFormat=_.internalFormat),_.type!==void 0&&(w.type=_.type),_.colorSpace!==void 0&&(w.colorSpace=_.colorSpace),_.encoding!==void 0&&(w.encoding=_.encoding),_.minFilter!==void 0&&(w.minFilter=r(_.minFilter,TEXTURE_FILTER)),_.magFilter!==void 0&&(w.magFilter=r(_.magFilter,TEXTURE_FILTER)),_.anisotropy!==void 0&&(w.anisotropy=_.anisotropy),_.flipY!==void 0&&(w.flipY=_.flipY),_.generateMipmaps!==void 0&&(w.generateMipmaps=_.generateMipmaps),_.premultiplyAlpha!==void 0&&(w.premultiplyAlpha=_.premultiplyAlpha),_.unpackAlignment!==void 0&&(w.unpackAlignment=_.unpackAlignment),_.compareFunction!==void 0&&(w.compareFunction=_.compareFunction),_.userData!==void 0&&(w.userData=_.userData),m[_.uuid]=w}return m};function serializeMap(g){if(g==null)return null;if(g.name==="PMREM.cubeUv")return{name:"PMREM.cubeUv"};const t={geometries:{},materials:{},textures:{},images:{}},r=g.toJSON(t),m=extractFromCache(t.images);return g instanceof VideoTexture&&(m[0].url=g.source.data.src,r.isVideoTexture=!0),m.length>0&&(r.images=m),r.sourceFile=g.sourceFile,r}function extractFromCache(g){const t=[];for(const r in g){const m=g[r];delete m.metadata,t.push(m)}return t}const needsUpdateAttributeName=["transparent","alphaTest","fog","vertexColors","vertexShader","fragmentShader","sizeAttenuation"];class SetMaterialValue extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialValue",this.name=`Set Material.${m}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[m]:void 0,this.newValue=v,this.attributeName=m}execute(){this.material!==void 0&&(this.material[this.attributeName]=this.newValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material),this.attributeName==="name"&&this.editor.emit("mListChange"))}undo(){this.material[this.attributeName]=this.oldValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("mListChange")})}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue,this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot)}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetMaterialVector extends Command{constructor(t,r,m,v,C){super(t),this.type="SetMaterialVector",this.name=`Set Material.${m}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[m].toArray():void 0,this.newValue=v,this.attributeName=m}execute(){this.material[this.attributeName].fromArray(this.newValue),this.editor.emit("materialChanged",this.material)}undo(){this.material[this.attributeName].fromArray(this.oldValue),this.editor.emit("materialChanged",this.material)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetMaterialMapVector extends Command{constructor(t,r,m,v,C,_="repeat"){var w,I,O,Pe;super(t),this.type="SetMaterialMapVector",this.attributeName2=_,this.name=`Set Material.${m}.${_}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.material instanceof We$1&&m==="map"&&_==="repeat"?this.oldValue=this.material.repeat.toArray():((I=(w=this.material)==null?void 0:w[m])==null?void 0:I[_])instanceof Vector2?this.oldValue=this.material[m][_].toArray():typeof((Pe=(O=this.material)==null?void 0:O[m])==null?void 0:Pe[_])!="undefined"&&(this.oldValue=this.material[m][_]),this.newValue=v,this.attributeName=m}execute(){var t,r,m,v,C;if((t=this.material)!=null&&t[this.attributeName]){const _=this.attributeName;this.material[_].wrapS!==RepeatWrapping&&(this.material[_].wrapS=RepeatWrapping,this.material[_].wrapT=RepeatWrapping,this.material[_].needsUpdate=!0)}this.material instanceof We$1&&this.attributeName==="map"&&this.attributeName2==="repeat"?this.material[this.attributeName2].fromArray(this.newValue):((m=(r=this.material)==null?void 0:r[this.attributeName])==null?void 0:m[this.attributeName2])instanceof Vector2?this.material[this.attributeName][this.attributeName2].fromArray(this.newValue):typeof((C=(v=this.material)==null?void 0:v[this.attributeName])==null?void 0:C[this.attributeName2])!="undefined"&&(this.material[this.attributeName][this.attributeName2]=this.newValue),this.editor.emit("materialChanged",this.material)}undo(){var t,r,m,v;this.material instanceof We$1&&this.attributeName==="map"&&this.attributeName2==="repeat"?this.material[this.attributeName2].fromArray(this.oldValue):((r=(t=this.material)==null?void 0:t[this.attributeName])==null?void 0:r[this.attributeName2])instanceof Vector2?this.material[this.attributeName][this.attributeName2].fromArray(this.oldValue):typeof((v=(m=this.material)==null?void 0:m[this.attributeName])==null?void 0:v[this.attributeName2])!="undefined"&&(this.material[this.attributeName][this.attributeName2]=this.oldValue),this.editor.emit("materialChanged",this.material)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByMaterialObject(this.object),t.materialSlot=this.materialSlot,t.attributeName=this.attributeName,t.attributeName2=this.attributeName2,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.materialObjectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.attributeName=t.attributeName,t.attributeName2&&(this.attributeName2=t.attributeName2),this.oldValue=t.oldValue,this.newValue=t.newValue,this.attributeName==="repeat"&&(this.attributeName="map")}fixJSON(){const t=this.json;if(this.material){const r=this.editor.pencil.mList.getKey(this.material);r&&r!==t.objectUuid&&(console.warn(`${this.type}:fix:`,t.objectUuid,r),t.objectUuid=r),r&&(t.materialSlot=0)}}}class SetPosition extends Command{constructor(t,r,m,v,C){super(t),this.type="SetPosition",this.name="Set Position",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&m!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=m.clone()),v!==void 0&&(this.oldPosition=v.clone())}execute(){this.cameraControls?this.cameraControls.setPosition(this.newPosition.x,this.newPosition.y,this.newPosition.z,!1):(this.object.position.copy(this.newPosition),this.object.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}undo(){this.cameraControls?this.cameraControls.setPosition(this.oldPosition.x,this.oldPosition.y,this.oldPosition.z,!1):(this.object.position.copy(this.oldPosition),this.object.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}update(t){this.newPosition.copy(t.newPosition)}toJSON(){var r;const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldPosition=(r=this.oldPosition)==null?void 0:r.toArray(),t.newPosition=this.newPosition.toArray(),t.cameraControls=!!this.cameraControls,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldPosition&&(this.oldPosition=new Vector3().fromArray(t.oldPosition)),this.newPosition=new Vector3().fromArray(t.newPosition),t.cameraControls&&(this.cameraControls=this.editor.pencil.controls)}}class SetRotation extends Command{constructor(t,r,m,v){super(t),this.type="SetRotation",this.name="Set Rotation",this.updatable=!0,this.object=r,r!==void 0&&m!==void 0&&(this.oldRotation=r.rotation.clone(),this.newRotation=m.clone()),v!==void 0&&(this.oldRotation=v.clone())}execute(){this.object.rotation.copy(this.newRotation),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}undo(){this.object.rotation.copy(this.oldRotation),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}update(t){this.newRotation.copy(t.newRotation)}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldRotation=this.oldRotation.toArray(),t.newRotation=this.newRotation.toArray(),t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldRotation&&(this.oldRotation=new Euler().fromArray(t.oldRotation)),this.newRotation=new Euler().fromArray(t.newRotation)}}class SetScale extends Command{constructor(t,r,m,v){super(t),this.type="SetScale",this.name="Set Scale",this.updatable=!0,this.object=r,r!==void 0&&m!==void 0&&(this.oldScale=r.scale.clone(),this.newScale=m.clone()),v!==void 0&&(this.oldScale=v.clone())}execute(){this.object.scale.copy(this.newScale),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}undo(){this.object.scale.copy(this.oldScale),this.object.updateMatrixWorld(!0),this.editor.emit("objectChanged",this.object)}update(t){this.newScale.copy(t.newScale)}toJSON(){var r;const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldScale=(r=this.oldScale)==null?void 0:r.toArray(),t.newScale=this.newScale.toArray(),t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldScale&&(this.oldScale=new Vector3().fromArray(t.oldScale)),this.newScale=new Vector3().fromArray(t.newScale)}}class SetValue extends Command{constructor(t,r,m,v,C){super(t),this.type="SetValue",this.name=`Set ${m}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=m;const _=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=_!==void 0?_[m]:void 0,this.newValue=v}execute(){const t=this.properties?this.object[this.properties]:this.object;t&&((t instanceof RectAreaLight||t instanceof AmbientLight)&&this.attributeName==="castShadow"||(t[this.attributeName]=this.newValue,this.fixObj(),this.editor.emit("objectChanged",this.object)))}fixObj(){const t=this.properties?this.object[this.properties]:this.object;if(t.isCamera&&["fov","left","right","top","bottom","near","far"].includes(this.attributeName)&&t.updateProjectionMatrix(),this.attributeName==="visible"){const r=this.editor.pencil.lead.objMap.get(this.object);r&&r[t[this.attributeName]?"show":"hide"]()}(this.attributeName==="name"||this.attributeName==="prefab"||this.attributeName==="visible"||this.attributeName==="keepCamera"||this.attributeName==="castShadow"&&this.object instanceof DirectionalLight)&&this.editor.emit("baseObjectListChange"),this.attributeName==="keepCamera"&&(this.editor.select(null),this.editor.emit("baseObjectListChange"))}undo(){const t=this.properties?this.object[this.properties]:this.object;t[this.attributeName]=this.oldValue,this.fixObj(),this.editor.emit("objectChanged",this.object)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.properties=this.properties,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue,this.object=this.editor.objectByUuid(t.objectUuid),this.properties=t.properties}}class SetVector extends Command{constructor(t,r,m,v,C){super(t),this.type="SetVector",this.name=`Set ${m}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=m;const _=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=_!==void 0?_[m].toArray():void 0,this.newValue=v}execute(){const t=this.properties?this.object[this.properties]:this.object;t&&(t[this.attributeName].fromArray(this.newValue),this.fixObj(),this.editor.emit("objectChanged",this.object))}fixObj(){this.editor.playing||this.attributeName==="mapSize"&&this.object[this.properties].map&&(this.object[this.properties].map.dispose(),this.object[this.properties].map=null)}undo(){(this.properties?this.object[this.properties]:this.object)[this.attributeName].fromArray(this.oldValue),this.fixObj(),this.editor.emit("objectChanged",this.object)}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.properties=this.properties,t.attributeName=this.attributeName,t.oldValue=this.oldValue,t.newValue=this.newValue,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.attributeName=t.attributeName,this.oldValue=t.oldValue,this.newValue=t.newValue,this.properties=t.properties}}class AddVis extends Command{constructor(r,m,v){super(r);C0(this,"visType");C0(this,"visOptions");this.type="AddVis",this.visType=m,this.visOptions=v,m!==void 0&&(this.name=`Add Vis: ${m}`)}execute(){return U0(this,null,function*(){yield this.editor.viewport.setVis(this.visType,this.visOptions),this.editor.select(null)})}undo(){const r=window.confirm("将删除所有记录,是否继续?");return r&&this.editor.viewport.dispose(),r}toJSON(){const r=super.toJSON();return r.visType=this.visType,r.visOptions=this.visOptions,r}fromJSON(r){super.fromJSON(r),this.visType=r.visType,this.visOptions=r.visOptions}}class AddObject extends Command{constructor(r,m,v){super(r);C0(this,"objectType");C0(this,"objectOptions");C0(this,"obj");C0(this,"addObjectUuid");this.type="AddObject",this.objectType=m,this.objectOptions=v,m!==void 0&&(this.name=`Add Object: ${m}`)}execute(){return U0(this,null,function*(){var m;const r=this.editor.viewport.vis;this.obj=yield r.lead.draw(this.objectType,Ji(q0({},this.objectOptions),{key:`${this.id}`})),this.obj.userData.updateKey!==!1&&r.lead.updateBaseObjectKey(this.obj,`$t:_${this.id}`),this.addObjectUuid=this.obj.key,this.editor.select(this.obj.key),(m=this.editor.viewport.vis)==null||m.initBaseObjectUserData(this.obj)})}undo(){this.obj.erase(),this.editor.select(null)}toJSON(){const r=super.toJSON();return r.objectType=this.objectType,r.objectOptions=this.objectOptions,r.addObjectUuid=this.addObjectUuid,r}fromJSON(r){super.fromJSON(r),this.objectType=r.objectType,this.objectOptions=r.objectOptions,this.addObjectUuid=r.addObjectUuid}fixJSON(){const r=this.json;r&&!r.addObjectUuid&&(r.addObjectUuid=this.addObjectUuid)}}class RemoveObject extends Command{constructor(r,m){super(r);C0(this,"object");C0(this,"objectUuid");this.type="RemoveObject",this.name="Remove Object",this.object=m,this.objectUuid=this.editor.uuidByBaseObject(m)}execute(){this.editor.playing?this.object.erase():(this.object.hide(),this.object.userData.selectHide=!0,this.object.mList.rmBaseObjectMap(this.object)),this.editor.emit("baseObjectListChange"),this.editor.select(null)}undo(){return U0(this,null,function*(){this.object.show(),this.object.mList.addBaseObjectMap(this.object),delete this.object.userData.selectHide,this.editor.emit("baseObjectListChange")})}toJSON(){const r=super.toJSON();return r.objectUuid=this.objectUuid,r}fromJSON(r){super.fromJSON(r),this.object=this.editor.baseObjectByUuid(r.objectUuid)}}class CopyObject extends Command{constructor(r,m){super(r);C0(this,"object");C0(this,"copyObject",null);C0(this,"copyObjectUuid");C0(this,"mListUuid",[]);this.type="CopyObject",this.name="Copy Object",this.object=m}execute(){return U0(this,null,function*(){var C;const r=this.editor.viewport.vis,m=this.object.key,v=yield this.object.instantiate({key:`${this.id}`});this.copyObject=v,v.userData.updateKey!==!1&&r.lead.updateBaseObjectKey(v,`${m}_${this.id}`),this.copyObjectUuid=v.key,this.editor.select(this.copyObjectUuid),(C=this.editor.viewport.vis)==null||C.initBaseObjectUserData(v)})}undo(){return U0(this,null,function*(){var r;(r=this.copyObject)==null||r.erase(),this.editor.select(null)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.editor.uuidByBaseObject(this.object),r.copyObjectUuid=this.copyObjectUuid,r.mListUuid=this.mListUuid,r}fromJSON(r){super.fromJSON(r),this.object=this.editor.baseObjectByUuid(r.objectUuid),this.copyObjectUuid=r.copyObjectUuid,this.mListUuid=r.mListUuid}fixJSON(){const r=this.json;if(r&&!r.copyObjectUuid&&(r.copyObjectUuid=this.copyObjectUuid),r){const m=this.object.object3d.material;if(m){const v=Array.isArray(m)?m:[m];r.mListUuid=v.map(C=>this.editor.pencil.mList.getKey(C)).filter(Boolean),r.mListUuid.length&&console.log("fixJSON CopyObject mListUuid",r.mListUuid)}}}}class AddMaterial extends Command{constructor(r,m){super(r);C0(this,"materialType");C0(this,"flag",!1);C0(this,"addObjectUuid");this.type="AddMaterial",this.name="Add Material",this.materialType=m}execute(){return U0(this,null,function*(){this.addObjectUuid=`material_${this.id}`;const r=this.editor.pencil.mList;let m;if(typeof this.materialType=="string")if(this.materialType.startsWith("k:")){const v=this.materialType.match(/k:([^|]+)\|s:([^|]+)/);if(v){const C=v[1],_=v[2],w=this.editor.pencil.lead.getObject(C);if(w){const I=w.object3d;m=Array.isArray(I.material)?I.material[+_]:I.material,this.flag=!0}else console.warn(`Base object with key ${C} not found.`),m=new MeshBasicMaterial}else console.warn(`Material type ${this.materialType} is not valid.`),m=new MeshBasicMaterial}else if(this.materialType.startsWith("t:")){const v=this.materialType.match(/t:([^|]+)\|s:([^|]+)/);if(v){const C=v[1],_=v[2],w=this.editor.pencil.lead.getObject(C);if(w){const I=w.object3d;m=Array.isArray(I.material)?I.material[+_]:I.material,this.flag=!0}else console.warn(`Base object with key ${C} not found.`),m=new MeshBasicMaterial}else console.warn(`Material type ${this.materialType} is not valid.`),m=new MeshBasicMaterial}else this.materialType==="MeshLineMaterial"?m=new We$1({color:new Color$1(16777215),lineWidth:1,sizeAttenuation:0}):m=new THREE[this.materialType];else m=parseMaterial(this.materialType);m.name=`材质_${this.id}`,r.add(this.addObjectUuid,m),this.flag&&this.editor.emit("materialChanged")})}undo(){return U0(this,null,function*(){this.editor.pencil.mList.remove(this.addObjectUuid),this.flag&&this.editor.emit("materialChanged")})}toJSON(){const r=super.toJSON();return r.materialType=this.materialType,r.addObjectUuid=this.addObjectUuid,r}fromJSON(r){super.fromJSON(r),this.materialType=r.materialType,this.addObjectUuid=r.addObjectUuid}}class CopyMaterial extends Command{constructor(r,m){super(r);C0(this,"objectUuid");C0(this,"copyObjectUuid");this.type="CopyMaterial",this.name="Copy Material",this.objectUuid=m}execute(){return U0(this,null,function*(){this.copyObjectUuid=`material_${this.id}`,this.editor.pencil.mList.copy(this.objectUuid,this.copyObjectUuid,{name:`材质_${this.id}`})})}undo(){return U0(this,null,function*(){this.editor.pencil.mList.remove(this.copyObjectUuid)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.objectUuid,r.copyObjectUuid=this.copyObjectUuid,r}fromJSON(r){super.fromJSON(r),this.objectUuid=r.objectUuid||r.materialKey||r.originKey,this.copyObjectUuid=r.copyObjectUuid||r.copyKey}fixJSON(){const r=this.json;r&&!r.objectUuid&&(r.objectUuid=r.objectUuid||r.materialKey||r.originKey),r&&!r.copyObjectUuid&&(r.copyObjectUuid=r.copyObjectUuid||r.copyKey)}}class RemoveMaterial extends Command{constructor(r,m){super(r);C0(this,"objectUuid");C0(this,"material");this.type="RemoveMaterial",this.name="Remove Material",this.objectUuid=m}execute(){return U0(this,null,function*(){const r=this.editor.pencil.mList;this.material=r.get(this.objectUuid),r.remove(this.objectUuid)})}undo(){return U0(this,null,function*(){const r=this.editor.pencil.mList;this.material&&r.add(this.objectUuid,this.material)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.objectUuid,r}fromJSON(r){super.fromJSON(r),this.objectUuid=r.objectUuid||r.materialKey}fixJSON(){const r=this.json;r&&!r.objectUuid&&(r.objectUuid=r.objectUuid||r.materialKey)}}class SetObjectMaterial extends Command{constructor(r,m,v,C){var w;super(r);C0(this,"object");C0(this,"oldValue");C0(this,"newValue");C0(this,"materialSlot");this.type="SetObjectMaterial",this.name="Set Object Material",this.object=m,this.materialSlot=v;const _=this.editor.getObjectMaterial(m,v);this.oldValue=(w=this.editor.pencil)==null?void 0:w.mList.getKey(_),this.newValue=C}execute(){return U0(this,null,function*(){const r=this.editor.pencil.mList;r.get(this.newValue)&&(this.editor.setObjectMaterial(this.object,this.materialSlot,r.get(this.newValue)),this.editor.emit("materialChanged",this.object))})}undo(){return U0(this,null,function*(){const r=this.editor.pencil.mList;this.editor.setObjectMaterial(this.object,this.materialSlot,r.get(this.oldValue)),this.editor.emit("materialChanged",this.object)})}toJSON(){const r=super.toJSON();return r.objectUuid=this.editor.uuidByObject(this.object),r.oldValue=this.oldValue,r.newValue=this.newValue,r.materialSlot=this.materialSlot,r}fromJSON(r){super.fromJSON(r),this.object=this.editor.objectByUuid(r.objectUuid),this.oldValue=r.oldValue,this.newValue=r.newValue,this.materialSlot=r.materialSlot}}class SetSetting extends Command{constructor(r,m,v){super(r);C0(this,"attributeName");C0(this,"newValue");C0(this,"oldValue");this.type="SetSetting",this.updatable=!0,this.name=`Set Setting.${m}`,this.attributeName=m,this.newValue=v,r.viewport.vis&&(this.oldValue=r.viewport.vis.settings[m])}execute(){return U0(this,null,function*(){const r=this.editor.viewport.vis;r.settings[this.attributeName]=this.newValue,yield r.settings[this.attributeName],this.editor.emit("settingsChanged")})}undo(){return U0(this,null,function*(){const r=this.editor.viewport.vis;r.settings[this.attributeName]=this.oldValue,yield r.settings[this.attributeName],this.editor.emit("settingsChanged")})}update(r){this.newValue=r.newValue}toJSON(){const r=super.toJSON();return r.name=this.name,r.attributeName=this.attributeName,r.newValue=this.newValue,r.oldValue=this.oldValue,r}fromJSON(r){super.fromJSON(r),this.name=r.name,this.attributeName=r.attributeName||r.name,this.newValue=r.newValue,this.oldValue=r.oldValue}}class SetTarget extends Command{constructor(t,r,m,v,C){super(t),this.type="SetTarget",this.name="Set Target",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&m!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=m.clone()),v!==void 0&&(this.oldPosition=v.clone())}execute(){this.cameraControls?this.cameraControls.setTarget(this.newPosition.x,this.newPosition.y,this.newPosition.z,!1):(this.object.target.copy(this.newPosition),this.object.target.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}undo(){this.cameraControls?this.cameraControls.setTarget(this.oldPosition.x,this.oldPosition.y,this.oldPosition.z,!1):(this.object.target.copy(this.oldPosition),this.object.target.updateMatrixWorld(!0)),this.editor.emit("objectChanged",this.object)}update(t){this.newPosition.copy(t.newPosition)}toJSON(){var r;const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.oldPosition=(r=this.oldPosition)==null?void 0:r.toArray(),t.newPosition=this.newPosition.toArray(),t.cameraControls=!!this.cameraControls,t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),t.oldPosition&&(this.oldPosition=new Vector3().fromArray(t.oldPosition)),this.newPosition=new Vector3().fromArray(t.newPosition),t.cameraControls&&(this.cameraControls=this.editor.pencil.controls)}}class SetSceenMap extends SetMaterialMap{constructor(t,r,m,v,C){super(t),this.type="SetSceenMap",this.name="Set Sceen.background",this.object=r,this.materialSlot=C,this.material=r!==void 0?r[C]:void 0,this.oldMap=r!==void 0?this.material[m]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=m}fromJSON(t){super.fromJSON(t),this.oldMap=this.object[this.materialSlot][this.mapName],this.material=this.object[this.materialSlot]}}class SetGeometry extends Command{constructor(t,r=null,m){super(t),this.type="SetGeometry",this.name="Set Geometry",this.updatable=!0,this.object=r,this.oldGeometry=r!==null?r.geometry:null,this.newGeometry=m||null}execute(){this.object.geometry.dispose(),this.object.geometry=this.newGeometry,this.object.geometry.computeBoundingSphere(),this.editor.emit("geometryChanged",this.object)}undo(){this.object.geometry.dispose(),this.object.geometry=this.oldGeometry,this.object.geometry.computeBoundingSphere(),this.editor.emit("geometryChanged",this.object)}update(t){this.newGeometry=t.newGeometry}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.newGeometry=this.geometryToJSON(this.newGeometry),t}geometryToJSON(t){return t?t.type==="MeshLine"?{type:"MeshLine",points:t.points,variableWidth:!!t.widthCallback}:t.toJSON():void 0}parseGeometry(t){if(!t)return;if(t.type==="MeshLine"){const v=new Be$1;return v.setPoints(t.points,t.variableWidth?C=>C:void 0),v}return new ObjectLoader().parseGeometries([t])[t.uuid]}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.oldGeometry=((r=this.object)==null?void 0:r.geometry)||null,this.newGeometry=this.parseGeometry(t.newGeometry)}}const Commands=Object.freeze(Object.defineProperty({__proto__:null,AddMaterial,AddObject,AddVis,CopyMaterial,CopyObject,RemoveMaterial,RemoveObject,SetColor,SetGeometry,SetMaterial,SetMaterialColor,SetMaterialMap,SetMaterialMapVector,SetMaterialValue,SetMaterialVector,SetObjectMaterial,SetPosition,SetRotation,SetScale,SetSceenMap,SetSetting,SetTarget,SetValue,SetVector},Symbol.toStringTag,{value:"Module"})),encodings="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function encodeArrayBufferToUrlSafeBase64(g){let t="";const r=new Uint8Array(g),m=r.byteLength,v=m%3,C=m-v;let _,w,I,O,Pe;for(let Ne=0;Ne<C;Ne=Ne+3)Pe=r[Ne]<<16|r[Ne+1]<<8|r[Ne+2],_=(Pe&16515072)>>18,w=(Pe&258048)>>12,I=(Pe&4032)>>6,O=Pe&63,t+=encodings[_]+encodings[w]+encodings[I]+encodings[O];return v===1?(Pe=r[C],_=(Pe&252)>>2,w=(Pe&3)<<4,t+=encodings[_]+encodings[w]):v===2&&(Pe=r[C]<<8|r[C+1],_=(Pe&64512)>>10,w=(Pe&1008)>>4,I=(Pe&15)<<2,t+=encodings[_]+encodings[w]+encodings[I]),t}function charCodeToNumber(g){if(g>=65&&g<=90)return g-65;if(g>=97&&g<=122)return g-71;if(g>=48&&g<=57)return g+4;if(g===45)return 62;if(g===95)return 63;throw new Error("Invalid char code in url safe base64: "+g)}function decodeUrlSafeBase64ToArrayBuffer(g){const t=g.length%4;let r=0,m=0,v=0;if(t===0)r=g.length/4*3,m=g.length;else{if(t===1)throw new Error("invalid url safe base64 encoded string: "+g);t===2?(r=(g.length-2)/4*3,m=g.length-2,v=1):(r=(g.length-3)/4*3,m=g.length-3,v=2)}let C;const _=new Uint8Array(r+v);let w,I,O,Pe;for(let Ne=0,Fe=0;Ne<m;Ne+=4,Fe+=3)w=charCodeToNumber(g.charCodeAt(Ne)),I=charCodeToNumber(g.charCodeAt(Ne+1)),O=charCodeToNumber(g.charCodeAt(Ne+2)),Pe=charCodeToNumber(g.charCodeAt(Ne+3)),C=(w<<18)+(I<<12)+(O<<6)+Pe,_.set([(C&16711680)>>16,(C&65280)>>8,C&255],Fe);return t===2?(w=charCodeToNumber(g.charCodeAt(m)),I=charCodeToNumber(g.charCodeAt(m+1)),C=(w<<2)+(I>>4),_.set([C&255],r)):t===3&&(w=charCodeToNumber(g.charCodeAt(m)),I=charCodeToNumber(g.charCodeAt(m+1)),O=charCodeToNumber(g.charCodeAt(m+2)),C=(w<<10)+(I<<4)+(O>>2),_.set([(C&65280)>>8,C&255],r)),_.buffer}class History{constructor(t){C0(this,"editor");C0(this,"undos");C0(this,"redos");C0(this,"lastCmdTime");C0(this,"idCounter");C0(this,"historyDisabled");this.editor=t,this.undos=[],this.redos=[],this.lastCmdTime=Date.now(),this.idCounter=0,this.historyDisabled=!1}execute(t,r){return U0(this,null,function*(){const m=this.undos[this.undos.length-1],v=Date.now()-this.lastCmdTime;m&&m.updatable&&t.updatable&&m.object===t.object&&m.objectUuid===t.objectUuid&&m.type===t.type&&m.attributeName===t.attributeName&&m.attributeName2===t.attributeName2&&m.name===t.name&&m.materialSlot===t.materialSlot&&v<500?(m.update(t),t=m):(this.undos.push(t),t.id=++this.idCounter),t.name=r!==void 0?r:t.name;try{yield t.execute()}catch(_){console.error(_,t)}t.json=t.toJSON(),this.lastCmdTime=Date.now(),this.redos=[],this.editor.emit("historyChanged",t)})}undo(){if(this.historyDisabled)return;let t;if(this.undos.length>0&&(t=this.undos.pop()),t!==void 0){if(!t.name){console.log("压缩配置,不支持 undo"),this.undos.push(t);return}t.undo(),this.redos.push(t),this.editor.emit("historyChanged",t)}return t}redo(){if(this.historyDisabled)return;let t;return this.redos.length>0&&(t=this.redos.pop()),t!==void 0&&(t.execute(),this.undos.push(t),this.editor.emit("historyChanged",t)),t}toJSON(){var r,m,v;const t={u:[],i:[]};for(let C=0;C<this.undos.length;C++)if(this.undos[C].hasOwnProperty("json")){const _=this.undos[C].json;if((r=_.newMap)!=null&&r.images||(m=_.newMaterial)!=null&&m.images){const w=(v=_.newMap)!=null&&v.images?"newMap":"newMaterial";t.u.push(Ji(q0({},_),{[w]:Ji(q0({},_[w]),{images:_[w].images.map(I=>{var Ne;if(typeof I.url!="string")if(((Ne=I.url)==null?void 0:Ne.type)==="Uint16Array"){const Fe=encodeArrayBufferToUrlSafeBase64(new Uint16Array(I.url.data).buffer);I._url=q0({},I.url),delete I._url.data,I.url=Fe}else return q0({},I);const O=t.i.findIndex(Fe=>Fe===I.url);let Pe=I.url;return O===-1?(t.i.push(I.url),Pe=`$rp-${t.i.length-1}`):Pe=`$rp-${O}`,Ji(q0({},I),{url:Pe})})})}))}else t.u.push(q0({},_))}return t}fromJSON(t){var v,C,_;if(t===void 0)return;let r=-1;const m=t.i;for(let w=0;w<t.u.length;w++){const I=t.u[w];if(m!=null&&m.length&&((v=I.newMap)!=null&&v.images||(C=I.newMaterial)!=null&&C.images)){const Pe=(_=I.newMap)!=null&&_.images?"newMap":"newMaterial";I[Pe].images.forEach(Ne=>{if(typeof Ne.url=="string"&&Ne.url.startsWith("$rp-")){const Fe=parseInt(Ne.url.replace("$rp-",""));Ne._url?(Ne.url=Ji(q0({},Ne._url),{data:decodeUrlSafeBase64ToArrayBuffer(m[Fe])}),delete Ne._url):Ne.url=m[Fe]}})}if(I.id<=r){console.error("历史记录id错误");continue}if(I.type==="SetOption"||!I.type)continue;I.type.endsWith("Command")&&(I.type=I.type.replace("Command",""));const O=new Commands[I.type](this.editor);O.json=I,O.id=I.id,O.name=I.name,this.undos.push(O),this.idCounter=I.id>this.idCounter?I.id:this.idCounter,r=I.id}this.editor.emit("historyChanged",this.undos[this.undos.length-1])}processUndos(t=1e3/60){return new Promise((r,m)=>{const v=[...this.undos],C=v.length;let _=0;const w=()=>U0(this,null,function*(){const I=performance.now();for(;v.length>0&&performance.now()-I<t;){if(this.editor._dispose){m("dispose");return}const O=v.shift(),Pe=this.editor.hooks.events.beforeExecuteUndo.length?this.editor.hooks.dispatch("beforeExecuteUndo",O):O;Pe&&(yield this.executeUndo(Pe)),this.editor.hooks.events.afterExecuteUndo.length&&this.editor.hooks.dispatch("afterExecuteUndo",O),_+=1}this.editor.emit("progress",{type:"还原场景",value:_/C*100|0}),v.length>0?requestAnimationFrame(w):r("")});requestAnimationFrame(w)})}executeUndo(t){return U0(this,null,function*(){t.fromJSON(t.json);try{!["AddObject","CopyMaterial","RemoveMaterial"].includes(t.json.type)&&t.json.objectUuid&&!t.object||(yield t.execute(),this.editor.playing||t.fixJSON())}catch(r){console.error(r,t)}})}clear(){this.undos.length=0,this.redos.length=0,this.idCounter=0,this.editor.emit("historyChanged",this.undos[this.undos.length-1])}}class Hooks{constructor(t){C0(this,"editor");C0(this,"events",{beforeSetVisOptions:[],beforeExecuteUndo:[],afterExecuteUndo:[],beforeShow:[],afterShow:[],beforeFromJSON:[],afterFromJSON:[],errorFromJSON:[]});C0(this,"source","");this.editor=t,this.addEvents({beforeFromJSON:()=>{window.postMessage({type:"vis-core.fromJSON.start"}),console.time("vis-core:time.fromJSON")},afterFromJSON:()=>{window.postMessage({type:"vis-core.fromJSON.end"}),console.timeEnd("vis-core:time.fromJSON")},errorFromJSON:()=>{window.postMessage({type:"vis-core.fromJSON.error"}),console.timeEnd("vis-core:time.fromJSON")}})}addEvents(t){var r;for(const m in t){const v=m;this.events[v]&&this.events[v].push(t[v].bind(t)),v==="afterShow"&&((r=this.editor.viewport.vis)==null?void 0:r.showState)===!0&&t[v](this.editor.viewport.vis)}}addStaticEvents(t){this.addEvents(t());const r=t.toString().replace(/\/\/.*?(?:\r\n|\n|\r|$)/g,"").replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s+/gm,"").replace(/(\r\n|\n|\r)/gm,"").trim();this.source!==r&&(this.source=r,this.editor.emit("scriptsChanged"))}fromJSON(t){if(!t)this.source="";else try{const r=new Function(`return ${t}()`)();this.addEvents(r),this.source=t}catch(r){console.error(r)}this.editor.emit("scriptsChanged")}toJSON(){return this.source}clear(){Object.keys(this.events).forEach(t=>{this.events[t]=[]})}dispatch(t,...r){let m;for(const v of this.events[t])if(t==="beforeSetVisOptions"?m=v(m!=null?m:r[0]):m=v(this.editor.viewport.vis,...r),m===!1)break;return m}}class Viewport{constructor(t,r){C0(this,"editor");C0(this,"vis");C0(this,"extendsOptions",{});C0(this,"cameraState",{});C0(this,"delLoadObj");C0(this,"options");C0(this,"copyObjKey");C0(this,"copyMListMaterialKey");this.options=r,this.editor=t}setSaveCamera(t){var r,m;this.vis.setSaveCamera(t),(r=this.vis.pencil.controls)==null||r.saveState(),this.cameraState=q0({},(m=this.vis)==null?void 0:m.cameraState),this.editor.emit("cameraStateChanged")}addVis(m){return U0(this,arguments,function*(t,r={}){this.replaceVis()&&(yield this.editor.execute(new AddVis(this.editor,t,r)))})}replaceVis(){if(this.vis){const t=window.confirm("将删除所有记录,是否继续?");return t&&this.dispose(),t}return!0}setVis(m){return U0(this,arguments,function*(t,r={}){if(!this.options.visFactories&&(this.editor.setViewportVis(t),!this.options.visFactories)){console.error("visFactories is not defined");return}if(this.vis=this.options.visFactories,this.vis.visName!==t)throw new Error(`visName is not match, import {${t}}`);let v=q0({},r);v=this.editor.hooks.events.beforeSetVisOptions.length?this.editor.hooks.dispatch("beforeSetVisOptions",v):v,this.vis.setOptions(q0(q0({},v),this.extendsOptions)),this.vis.cameraState=q0({},this.cameraState),this.delLoadObj&&(this.vis.delLoadArr=this.delLoadObj),this.vis.playing=this.editor.playing,this.vis._baseObjectByUuid=this.editor.baseObjectByUuid.bind(this.editor),this.vis._objectByUuid=this.editor.objectByUuid.bind(this.editor),this.vis.on("loaderProgress",(_,w)=>{this.editor.emit("progress",{type:"下载资源",value:_/w*100|0})}),this.vis.on("settingsChanged",()=>{this.editor.emit("settingsChanged")}),this.vis.on("show",()=>{this.editor.changeSelectOption(),this.editor.emit("visShow",!0)}),yield this.vis.init();const{pencil:C}=this.vis;C.userData.EditorEnv=!this.editor.playing,this.editor.pencil=C,this.editor.changeSelectOption(),this.editor.changeMListOptions(),this.editor.playing||(this.initEvent(),this.editor.emit("visChanged",this.vis)),this.editor.on("baseObjectListChange",()=>{this.editor.changeSelectOption()}),this.editor.on("mListChange",()=>{this.editor.changeMListOptions()}),C.event.on("lead.updateKey",()=>{this.editor.emit("baseObjectListChange")}),C.event.on("lead.draw",()=>{this.editor.emit("baseObjectListChange")}),C.event.on("lead.erase",()=>{this.editor.emit("baseObjectListChange")}),C.event.on("mList.add",()=>{this.editor.emit("mListChange")}),C.event.on("mList.remove",()=>{this.editor.emit("mListChange")}),C.event.on("mList.addBaseObjectMap",()=>{this.editor.emit("mListChange")}),C.event.on("mList.rmBaseObjectMap",()=>{this.editor.emit("mListChange")})})}setResetCameraUp(){var _,w,I;const r=((_=this.vis)==null?void 0:_.pencil.lead.group).getSize(),m=(r.max.x+r.min.x)/2,v=(r.max.y+r.min.y)/2,C=(w=this.vis)==null?void 0:w.pencil.cameraPositon.z;(I=this.vis)==null||I.pencil.controls.setLookAt(m,v,C,m,v,0,!0)}initEvent(){var r,m,v,C;const{pencil:t}=this.vis;t.controls.addEventListener("update",()=>{this.editor.emit("refreshSidebarObject3D",t.camera)}),(r=t.transformController)==null||r.event.on("change",_=>{this.editor.emit("refreshSidebarObject3D",_)}),(m=t.transformController)==null||m.event.on("translate",(_,w,I)=>{this.editor.execute(new SetPosition(this.editor,_,w,I))}),(v=t.transformController)==null||v.event.on("rotate",(_,w,I)=>{this.editor.execute(new SetRotation(this.editor,_,w,I))}),(C=t.transformController)==null||C.event.on("scale",(_,w,I)=>{this.editor.execute(new SetScale(this.editor,_,w,I))})}addObj(m){return U0(this,arguments,function*(t,r={}){const v=objs$3[t].getInitOptions;v&&Object.assign(r,v(this.vis.pencil,r)),yield this.editor.execute(new AddObject(this.editor,t,r))})}removeObj(t){return U0(this,null,function*(){const{vis:r}=this;if(!r||!t)return;const m=this.editor.findSelectItem(this.editor.selectOption,"key",t);if(m&&!m.disabledR){const v=this.editor.baseObjectByUuid(t);this.editor.execute(new RemoveObject(this.editor,v))}else console.warn(m?"Object is disabled for removal":"Object not found for removal")})}copyObj(t){if(this.vis&&(this.copyObjKey=void 0,t)){const r=this.editor.findSelectItem(this.editor.selectOption,"key",t);r&&!r.disabledC&&(this.copyObjKey=t)}}pasteObj(){return U0(this,null,function*(){const{vis:t}=this;if(!t||!this.copyObjKey)return;const r=this.editor.baseObjectByUuid(this.copyObjKey);this.editor.execute(new CopyObject(this.editor,r))})}copyMListMaterial(t){return U0(this,null,function*(){const{vis:r}=this;r&&(this.copyMListMaterialKey=t,t&&del("crossCopyMaterial"))})}pasteMListMaterial(){return U0(this,null,function*(){const{vis:t}=this;if(t){if(!this.copyMListMaterialKey){const r=yield get("crossCopyMaterial");r&&this.editor.execute(new AddMaterial(this.editor,r));return}this.editor.execute(new CopyMaterial(this.editor,this.copyMListMaterialKey))}})}addMListMaterial(t="MeshBasicMaterial"){return U0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new AddMaterial(this.editor,t))})}removeMListMaterial(t){return U0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new RemoveMaterial(this.editor,t))})}setExtendsOptions(t,r){this.extendsOptions[t]=r,this.vis.extendsOptions[t]=r,this.editor.emit("optionsChanged"),setTimeout(()=>{const m=this.editor.toJSON();this.dispose(),this.editor.fromJSON(m)})}toJSON(){var r;const t=(r=this.vis)==null?void 0:r.loader.getUnusedAssets();return{eo:this.extendsOptions,cs:this.cameraState,delLoadObj:t}}fromJSON(t){this.extendsOptions=t.eo||{},this.cameraState=t.cs||{},t.delLoadObj&&t.delLoadObj.length&&(this.delLoadObj=[...t.delLoadObj])}getLoadObj(){return this.vis?[...this.vis.loader.assets.keys()].filter(r=>this.vis.loader.delLoadArr.indexOf(r)===-1):[]}setTransformControlsModal(t){var m;const{pencil:r}=this.vis;(m=r.transformController)==null||m.controls.setMode(t),this.editor.emit("transformControlsModalChanged",t)}dispose(){var t;this.editor.emit("visShow",!1),(t=this.vis)==null||t.dispose(),this.options.visFactories=void 0,this.extendsOptions={},this.cameraState={},this.delLoadObj=void 0,this.vis=void 0,this.editor.history.clear()}}class Editor{constructor(t){C0(this,"selected",null);C0(this,"playing",!0);C0(this,"currentMaterialSlot",0);C0(this,"events",new events.EventEmitter);C0(this,"history");C0(this,"viewport");C0(this,"hooks");C0(this,"config");C0(this,"pencil");C0(this,"on",this.events.on.bind(this.events));C0(this,"emit",this.events.emit.bind(this.events));C0(this,"options");C0(this,"selectOption",[]);C0(this,"mListOptions",[]);C0(this,"_dispose",!1);this.options=q0({assetsPrefix:"",processUndosMaxFrameTime:Number.MAX_VALUE},t),this.events.setMaxListeners(9999999),this.viewport=new Viewport(this,{visFactories:t.visFactories}),this.history=new History(this),this.hooks=new Hooks(this),this.config=new Config(this),this.config.setConfig("sdkVersion",version)}getObjectMaterial(t,r){if(!t)return;let m=t.material;return Array.isArray(m)&&r!==void 0&&(m=m[r]),m}getMListFixBaseObjectByObject(t,r){var v;const m=this.getObjectMaterial(t,r);return m?((v=this.findMListSelectItem("material",m))==null?void 0:v.object)||t:null}materialObjectByUuid(t){const r=this.findMListSelectItem("key",t);return r?r.object:this.objectByUuid(t)}uuidByMaterialObject(t){const r=this.findMListSelectItem("object",t);return r?r.key:this.uuidByObject(t)}setObjectMaterial(t,r,m){let v=t.material;Array.isArray(t.material)&&r!==void 0?(v=t.material[r],t.material[r]=m):t.material=m,v!=null&&v.onBeforeCompile&&(m.onBeforeCompile=v.onBeforeCompile),v!=null&&v.name&&!m.name&&(m.name=v.name),m instanceof We$1&&(m.resolution=new Vector2(this.pencil.renderer.domElement.width,this.pencil.renderer.domElement.height))}uuidByObject(t){var r;return(r=this.findSelectItem(this.selectOption,"object",t))==null?void 0:r.key}objectByUuid(t){var r;return(r=this.findSelectItem(this.selectOption,"key",t))==null?void 0:r.object}uuidByBaseObject(t){var r;return(r=this.findSelectItem(this.selectOption,"baseObject",t))==null?void 0:r.key}baseObjectByUuid(t){var r;return(r=this.findSelectItem(this.selectOption,"key",t))==null?void 0:r.baseObject}findSelectItem(t,r,m){for(let v=0;v<t.length;v++){const C=t[v];if(C[r]===m)return C;if(C.children){const _=this.findSelectItem(C.children,r,m);if(_)return _}}}changeSelectOption(){const t=this.viewport.vis,r=m=>m.filter(v=>v.userData.selectHide!==!0).map(v=>{const C=[...v.children];if(v.key||console.warn("baseObject.key is empty, this may cause issues in the editor.",v),v.object3d.target){const De=v.options.type;C.unshift({key:v.key.replace(De,De+"Target"),object3d:v.object3d.target,userData:{disabledC:!0,disabledR:!0,disabledTC:v.userData.disabledTC},children:[]})}if(v.object3d.isDirectionalLight&&v.object3d.castShadow){const De=v.options.type;C.unshift({key:v.key.replace(De,De+"Shadow"),object3d:v.object3d.shadow.camera,userData:{disabledC:!0,disabledR:!0,disabledTC:!0},children:[]})}const w=C.length>0?r(C):[],I=v.object3d.isGroup,O=I||["@Scene","@Camera"].includes(v.key)||v.userData.disabledC||v.key.includes("__c__"),Pe=["@Scene","@Camera"].includes(v.key)||v.userData.disabledR||v.key.includes("__c__");if(w.length===0&&I)return null;const Ne=v.key.replace(v.key[0],v.key[0].toLowerCase()),Fe=["@Scene","@Camera"].includes(v.key)||v.userData.disabledTC,Ae=["@Scene","@Camera"].includes(v.key);return{key:Ne==="@Scene"?"scene":Ne==="@Camera"?"camera":Ne,name:v.object3d.name,object:v.object3d,visible:Ae?!0:v.object3d.visible,useMaterialType:v.useMaterialType,disabledC:O,disabledR:Pe,disabledTC:Fe,disabledVisible:Ae,baseObject:v,children:w}}).filter(v=>v!==null);this.selectOption=r([t.lead.scene]),this.emit("sceneGraphChanged")}findMListSelectItem(t,r){return this.mListOptions.find(m=>m[t]===r)}changeMListOptions(){if(!this.pencil)return[];this.mListOptions=Array.from(this.pencil.mList.fixBaseObjects.entries()).map(([t,r])=>{const m=this.pencil.mList.get(t);return{key:t,name:m.name,type:m.type,object:r.object3d,baseObject:r,material:m,use:this.pencil.mList.getBaseObjectMap(m).size}}),this.emit("mListGraphChanged")}execute(t,r){return U0(this,null,function*(){yield this.history.execute(t,r)})}fromJSON(t,r){return U0(this,null,function*(){var m,v,C,_;try{r&&!f$1(r)?console.warn("fromJSON 第二个参数已修改,{beforeSetVisOptions:(r)=>r} 替代"):r&&this.hooks.addEvents(r);let w;if(typeof t=="string"){const I=this.options.assetsPrefix+t;console.time("vis-core:time.json-fetch");const{res:O,err:Pe}=yield jsonFetch(I);if(console.timeEnd("vis-core:time.json-fetch"),Pe)throw new Error("fromJSON error:"+Pe);w=O}else w=t;if(this.hooks.dispatch("beforeFromJSON"),w=fixJSON(w),w.at&&(accessToken.token=w.at),!this.storage){if(!accessToken.token)throw new Error("设置 token 或平台重新下载 JSON 文件");const I=accessToken.getInfo();if(!I||!I.isValid)throw new Error("need accessToken")}if(this.config.fromJSON(w.c),this.history.fromJSON(w.h),this.viewport.fromJSON(w.v),this.hooks.fromJSON(w.s),this.config.compareVersion(),yield this.history.processUndos(this.options.processUndosMaxFrameTime),(m=w.v.bg)!=null&&m.texture&&this.viewport.vis){const I=parseTexture(w.v.bg.texture);I.colorSpace=SRGBColorSpace,this.viewport.vis.pencil.scene.background=I}return this.hooks.dispatch("beforeShow"),(v=this.viewport.vis)==null||v.show(),this.hooks.dispatch("afterShow"),(C=this.pencil.controls)==null||C.saveState(),this.select(null),(_=this.viewport.vis)!=null&&_.workerOnce&&this.playing&&window.requestIdleCallback(()=>{var I;(I=this.viewport.vis)==null||I.worker.dispose()}),this.hooks.dispatch("afterFromJSON"),w}catch(w){throw this.hooks.dispatch("errorFromJSON"),new Error("fromJSON error:"+w)}})}toJSON(){return{}}select(...t){}setViewportVis(...t){}getDataURL(){return this.pencil?(this.pencil.render(),this.pencil.renderer.domElement.toDataURL()):""}dispose(){this.events.removeAllListeners(),this.viewport.dispose(),this.history.clear(),this.hooks.clear(),this._dispose=!0}}const getScale=g=>{const r=window.getComputedStyle(g).transform;if(r&&r!=="none"){const m=new DOMMatrix(r);return Math.max(m.a,m.d)}};function observeScale(g,t){let r=g,m=1;for(;r;){const I=getScale(r);if(I!==void 0){m=I;break}if(r=r.parentElement,r===document.body){r=null;break}}if(!r)return null;const v=I=>{const O=getScale(r)||1;m!==O&&(m=O,t(O,I))},C=I=>{I.propertyName==="transform"&&v("transitionEnd")},_=new MutationObserver(I=>{for(const O of I)if(O.type==="attributes"&&O.attributeName==="style"){v("MutationObserver");return}});_.observe(r,{attributes:!0,attributeFilter:["style"]}),r.addEventListener("transitionend",C),t(m,"init");const w=_.disconnect;return _.disconnect=function(){w.call(_),r==null||r.removeEventListener("transitionend",C)},_}class Event{constructor(){C0(this,"event",new events.EventEmitter);C0(this,"eventHandlers",{});C0(this,"on",this.event.on.bind(this.event));C0(this,"emit",this.event.emit.bind(this.event))}addListener(t,r,m,v=!1){r in this.eventHandlers||(this.eventHandlers[r]=[]),this.eventHandlers[r].push({node:t,handler:m,capture:v}),t.addEventListener(r,m,v)}removeListener(t,r){this.eventHandlers[r].filter(({node:m})=>t?m===t:!0).forEach(({node:m,handler:v,capture:C})=>m.removeEventListener(r,v,C)),this.eventHandlers[r]=this.eventHandlers[r].filter(({node:m})=>t?m!==t:!1)}removeAllListeners(){Object.keys(this.eventHandlers).forEach(t=>{this.removeListener("",t)}),this.eventHandlers={}}dispose(){this.removeAllListeners(),this.event.removeAllListeners()}}class Camera extends Event{constructor(){super(...arguments);C0(this,"container");C0(this,"pencil");C0(this,"cameraState",{})}setSaveCamera(r){const m=this.pencil,v=m.cameraPositon,C=m.cameraTarget;this.cameraState[r]=[v.x,v.y,v.z,C.x,C.y,C.z]}useSaveCamera(r,m=!1){return U0(this,null,function*(){const v=this.cameraState[r];return v?(yield this.lookAt(v[0],v[1],v[2],v[3],v[4],v[5],m),!0):!1})}lookAt(r,m,v,C,_,w,I=!1,O=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=O/1e3,yield this.pencil.controls.setLookAt(r,m,v,C,_,w,I),this.pencil.controls.smoothTime=250/1e3})}truck(r,m,v=!1,C=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=C/1e3,this.pencil.controls.restThreshold=0,yield this.pencil.controls.truck(r,m,v),this.pencil.controls.restThreshold=.0025,this.pencil.controls.smoothTime=250/1e3})}dollyTo(r,m=!1,v=250){return U0(this,null,function*(){let C=r;if(typeof C=="string"){const[_,w]=C.split("=");_==="+"?C=this.pencil.controls.distance+ +w:_==="-"?C=this.pencil.controls.distance-+w:_==="*"?C=this.pencil.controls.distance*+w:_==="/"?C=this.pencil.controls.distance/+w:console.error("dollyTo distance error")}this.pencil.controls.smoothTime=v/1e3,yield this.pencil.controls.dollyTo(C,m),this.pencil.controls.smoothTime=250/1e3})}absoluteAngle(r,m){const v=Math.PI*2,C=r-m;return MathUtils.euclideanModulo(C+Math.PI,v)-Math.PI}lookAtTarget(r,m=!1,v=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=v/1e3;const C=this.pencil.controls.azimuthAngle,_=this.pencil.controls.polarAngle,w=this.pencil.controls.distance,I=this.pencil.cameraTarget.clone(),O=r.azimuthAngle||C,Pe=r.polarAngle||_,Ne=r.distance||w,Fe=r.target||I;yield Promise.all([this.pencil.controls.moveTo(Fe.x,Fe.y,Fe.z,m),this.pencil.controls.dollyTo(Ne,m),this.pencil.controls.rotateTo(C+this.absoluteAngle(O,C),_+this.absoluteAngle(Pe,_),m)]),this.pencil.controls.smoothTime=250/1e3})}paddingInCssPixel(r,m,v,C,_,w){const{camera:I,controls:O}=this.pencil,Pe=I.fov*MathUtils.DEG2RAD,Ne=this.pencil.getSize().height,{size:Fe}=r.getSize(),Ae=Fe.x,De=Fe.y,xt=Fe.z;let je=O.getDistanceToFitBox(Ae,De,xt),ke=0,at=0,ct=0,Gt=0;for(let Lt=0;Lt<10;Lt++){const Wt=je-xt*.5,Pt=2*Math.tan(Pe*.5)*Math.abs(Wt)/Ne;ke=m*Pt,at=C*Pt,ct=_*Pt,Gt=v*Pt,je=O.getDistanceToFitBox(Ae+ct+Gt,De+ke+at,xt)}return O.fitToBox(r.object3d,w,{paddingLeft:ct,paddingRight:Gt,paddingBottom:at,paddingTop:ke})}resetCamera(r=!1,m=250){return U0(this,null,function*(){this.pencil.controls.smoothTime=m/1e3,yield this.pencil.controls.reset(r),this.pencil.controls.smoothTime=250/1e3})}unproject(r,m=0){const v=new Vector3,C=new Vector3,{left:_,top:w,width:I,height:O}=this.container.getBoundingClientRect(),Pe=(r.clientX-_)/I*2-1,Ne=-((r.clientY-w)/O)*2+1,Fe=this.pencil.cameraPositon.clone();v.set(Pe,Ne,.5),v.unproject(this.pencil.camera),v.sub(Fe).normalize();const Ae=(m-Fe.z)/v.z;return C.copy(Fe).add(v.multiplyScalar(Ae)),C}dispose(){super.dispose(),this.cameraState={}}}const IS_DEV=!1;class Base extends Camera{constructor(r){var m;super();C0(this,"playing",!0);C0(this,"leftTruck",!0);C0(this,"options");C0(this,"showState",!1);C0(this,"settings",{});C0(this,"delLoadArr");C0(this,"extendsOptions",{});C0(this,"leadObjs",objs$3);C0(this,"lead");C0(this,"mList");C0(this,"workerOnce",!0);C0(this,"tier0",!1);C0(this,"pmremGenerator",null);C0(this,"re",null);C0(this,"roomEnvMap");C0(this,"visName");C0(this,"editor");C0(this,"publicDir",{});C0(this,"_baseObjectByUuid");C0(this,"_objectByUuid");C0(this,"observeScale",null);C0(this,"sceneActive",-1);C0(this,"initSettingsObj");C0(this,"mouseButtonsActiveStore",null);if(this.container=r.container,this.options=q0({assetsPrefix:"",editor:!0,logarithmicDepthBuffer:!0,observeParentScale:!0},r),!this.options.assetsPrefix){let v="/";v==="/"&&(v=""),this.options.assetsPrefix=v}this.options.workerOnce!==void 0&&(this.workerOnce=this.options.workerOnce);try{const v=window.location.search.match(/v_ldb=(\d+)/);if(v){const C=!!+v[1];this.options.logarithmicDepthBuffer=C}}catch(v){console.error(v)}if(this.options.editor){const v=detect();let C=(m=this.options.tier)!=null?m:v.tier;try{const _=window.location.search.match(/v_tier=(\d+)/);_&&(C=+_[1])}catch(_){console.error(_)}this.tier0=C!==3,this.editor=new Editor({assetsPrefix:this.options.assetsPrefix,visFactories:this}),console.info("vis-core:detect",version,JSON.stringify(Ji(q0({},v),{ldb:this.options.logarithmicDepthBuffer,tier0:this.tier0}),null,2))}this.visName=this.constructor.VisName}get loader(){return this.pencil.loader}get worker(){return this.pencil.installPlugins.get("worker")}setOptions(r){this.options=q0(q0({},this.options),r)}get fromJSON(){return this.editor.fromJSON.bind(this.editor)}get baseObjectByUuid(){var r;return((r=this.editor)==null?void 0:r.baseObjectByUuid.bind(this.editor))||this._baseObjectByUuid}get objectByUuid(){var r;return((r=this.editor)==null?void 0:r.objectByUuid.bind(this.editor))||this._objectByUuid}get getDataURL(){return this.editor.getDataURL.bind(this.editor)}loaderAdd(...r){}initMaterial(...r){return U0(this,null,function*(){})}initVis(...r){return U0(this,null,function*(){})}init(...r){return U0(this,null,function*(){yield this.initPencil(),this.loaderAdd(),console.time(`vis-core:time.${this.visName}-loader`),yield this.loader.loadAll(),console.timeEnd(`vis-core:time.${this.visName}-loader`),yield this.initMaterial(),yield this.initVis(),yield Promise.all(this.lead.objectsPromise)})}initPencil(){return U0(this,null,function*(){var v,C,_,w,I,O,Pe,Ne;if(this.pencil)return;const r=q0({},this.options.pencilConfig);if(this.options.css2DContainer&&(r.css2DRendererParams={container:this.options.css2DContainer}),this.options.pencil)this.pencil=this.options.pencil,this.pencil.stop(),this.sceneActive=this.pencil.addPage({cameraOptions:{fov:(C=(v=r.camera)==null?void 0:v.fov)!=null?C:45,near:(w=(_=r.camera)==null?void 0:_.near)!=null?w:.1,far:(O=(I=r.camera)==null?void 0:I.far)!=null?O:1e3,up:(Ne=(Pe=r.camera)==null?void 0:Pe.up)!=null?Ne:new Vector3(0,1,0)},sceneOptions:{background:new Color$1(0)}}),this.setSceneActive();else if(this.options.pencil2){this.pencil=this.options.pencil2,this.lead=this.pencil.lead.init(this.leadObjs),this.mList=this.pencil.mList,this.sceneActive=this.pencil.pageActiveIndex;return}else{const Fe=new ot(q0(Ji(q0({container:this.container,stats:!this.playing&&IS_DEV,helper:!this.playing,viewHelper:!this.playing,transformControls:!this.playing,css2DRenderer:!0},this.tier0?{composer:{multisampling:0}}:{}),{renderer:{alpha:!0,logarithmicDepthBuffer:this.options.logarithmicDepthBuffer},camera:{near:.1,far:1e3,fov:45,up:new Vector3(0,1,0)},bloom:!0,ssao:!0,ssaoParams:{minDistance:.001},scene:{background:new Color$1(0)},loader:q0({prefix:this.options.assetsPrefix,simpleTexture4deleted:!0},this.tier0?{anisotropy:1}:{})}),r));if(this.options.observeParentScale&&this.playing){const xt=()=>{this.observeScale||(this.observeScale=observeScale(this.container,(je,ke)=>{Fe.setDevicePixelRatio(window.devicePixelRatio*je)}))};xt(),Fe.event.on("resize",()=>{xt()})}if(this.tier0){const xt=new Map;Fe.event.on("beforeRender",()=>{Fe.scene.traverse(je=>{const ke=je;if(ke.material){const at=ke.material;(Array.isArray(at)?at:[at]).forEach(Gt=>{!xt.has(Gt)&&Gt.name&&(xt.set(Gt,Gt.name),Gt.name="")})}})}),Fe.event.on("render",()=>{[...xt.keys()].forEach(je=>{const ke=xt.get(je);ke&&(je.name=ke)}),xt.clear()})}this.pencil=Fe,this.sceneActive=1;const Ae=Fe.composerController.ssaoPass;Ae&&(Ae.enabled=!1);const De=new Q({dbName:this.visName,cacheVersion:version});Fe.use(De),this.playing||(window.vis=this,window.pencil=Fe)}const m=this.pencil;this.lead=m.lead.init(this.leadObjs),this.mList=m.mList,this.delLoadArr&&(m.loader.delLoadArr=this.delLoadArr),m.loader.on("progress",(...Fe)=>{this.showState!==!0&&this.emit("loaderProgress",...Fe)}),this.leftTruck&&(m.controls.mouseButtons.left=Gi.TRUCK,m.controls.mouseButtons.right=Gi.ROTATE),this.lead.group.hide(),this.lead.prefabGroup.hide(),this.initSceneUserData(),this.initCameraUserData(),this.initSettings()})}setSceneActive(){this.pencil.showPage(this.sceneActive)}initCameraUserData(){const r=this.pencil;r.camera.userData=new Proxy({up:r.camera.up.toArray().join(",")},{set:(m,v,C)=>{if(v==="up"){const _=C.split(",").map(w=>+w);r.camera.up.fromArray(_),r.controls.updateCameraUp()}return Reflect.set(m,v,C)}})}initSceneUserData(){var w,I,O,Pe,Ne,Fe;const r=this.pencil,m=r.scene.background,v=m instanceof Color$1?"Color":m instanceof Texture?"Texture":"None",C=v==="Texture"?m:null,_=v==="Color"?"#"+m.getHexString():"#000000";r.scene.userData=new Proxy({backgroundType:v,backgroundColor:_,backgroundTexture:C,shadowMapEnabled:this.pencil.renderer.shadowMap.enabled,shadowMapType:this.pencil.renderer.shadowMap.type,bloomThreshold:(I=(w=this.pencil.composerController)==null?void 0:w.bloomPass)==null?void 0:I.threshold,bloomRadius:(Pe=(O=this.pencil.composerController)==null?void 0:O.bloomPass)==null?void 0:Pe.radius,bloomStrength:(Fe=(Ne=this.pencil.composerController)==null?void 0:Ne.bloomPass)==null?void 0:Fe.strength},{set:(Ae,De,xt)=>(De==="shadowMapEnabled"||De==="shadowMapType"?(De==="shadowMapEnabled"?this.pencil.renderer.shadowMap.enabled=xt:De==="shadowMapType"&&(this.pencil.renderer.shadowMap.type=xt),this.pencil.scene.traverse(je=>{const ke=je;if(ke.receiveShadow&&ke.material){const at=ke.material;Array.isArray(at)?at.forEach(ct=>{ct.needsUpdate=!0}):at.needsUpdate=!0}})):De==="backgroundType"?xt==="None"?r.scene.background=null:r.scene.userData.backgroundColor?r.scene.background=new Color$1(r.scene.userData.backgroundColor):r.scene.userData.backgroundTexture&&(r.scene.background=r.scene.userData.backgroundTexture):De==="backgroundColor"?r.scene.background=new Color$1(xt):De==="backgroundTexture"?r.scene.background=xt:De==="bloomThreshold"?r.composerController.bloomPass&&(r.composerController.bloomPass.threshold=xt):De==="bloomRadius"?r.composerController.bloomPass&&(r.composerController.bloomPass.radius=xt):De==="bloomStrength"&&r.composerController.bloomPass&&(r.composerController.bloomPass.strength=xt),Reflect.set(Ae,De,xt))})}initBaseObjectUserData(r){const m=Ji(q0({},r.object3d.userData),{bloom:!1});if(r.objectType==="BaseObject#Light")return;const v=r.objectType==="BaseObject#Arc",C=r.objectType==="BaseObject#Line",_=r.object3d instanceof Group$1;v?m.animationDuration=2e3:C&&(m.animationDuration=0),prefabType.includes(r.objectType.split("#")[1])&&(m.prefab=r.prefab),r.object3d.userData=new Proxy(m,{set:(w,I,O)=>(I==="bloom"?O?r.enableBloom():r.disableBloom():I==="prefab"?(r.prefab=O,O?this.lead.prefabGroup.attach(r):this.lead.group.attach(r)):I==="animationDuration"&&v?r.animateIn({duration:O}):I==="animationDuration"&&(C||_)&&(C?[r]:r.children).forEach(Ne=>{Ne.material.userData.tween&&(Ne.material.userData.tween.stop(),remove(Ne.material.userData.tween),Ne.material.userData.tween=null),O&&(Ne.material.uniforms.offset.value.x=1,Ne.material.uniforms.offsetLoop.value=1,Ne.animate({duration:O,repeat:1/0,lineLoop:!0,startShow:!0}))}),Reflect.set(w,I,O))})}addCSS3DRenderer(){this.pencil&&this.pencil.cssRendererController.addRenderer("css3d",{container:this.pencil.cssRendererController.container,zIndex:"auto"})}initSettings(){const r={mouseLeft:this.pencil.controls.mouseButtons.left,mouseRight:this.pencil.controls.mouseButtons.right,mouseWheel:this.pencil.controls.mouseButtons.wheel};this.settings=new Proxy(Ji(q0(q0({},this.initSettingsObj),r),{mouseNone:!1,viewportPadding:[0,0,0,0]}),{set:(m,v,C)=>{if(!(v in m)&&!(v.replace(/(:::.+)\..*$/,"$1")in m))return Reflect.set({},v,C);v==="mouseWheel"?typeof C=="boolean"&&(C=C?r.mouseWheel:Gi.NONE):v==="mouseLeft"?typeof C=="boolean"&&(C=C?r.mouseLeft:Gi.NONE):v==="mouseRight"&&typeof C=="boolean"&&(C=C?r.mouseRight:Gi.NONE);const _=v.includes(":::");return Reflect.set(m,_?v.replace(/(:::.+)\..*$/,"$1"):v,this.handleSetting(v,C))},get:(m,v)=>{const _=v.includes(":::")?v.replace(/(:::.+)\..*$/,"$1"):v,w=Reflect.get(m,_);return w instanceof Promise?w.then(I=>(Reflect.set(m,_,I),I)):w}})}handleSetting(r,m){return U0(this,null,function*(){const{pencil:v}=this;if(r==="mouseWheel"||r==="mouseLeft"||r==="mouseRight"){const C=r.replace("mouse","").toLowerCase();(m||this.playing)&&(v.controls.mouseButtons[C]=m)}else r==="mouseNone"?m?(this.mouseButtonsActiveStore={mouseLeft:v.controls.mouseButtons.left,mouseRight:v.controls.mouseButtons.right,mouseWheel:v.controls.mouseButtons.wheel},v.controls.mouseButtons.left=Gi.NONE,v.controls.mouseButtons.right=Gi.NONE,v.controls.mouseButtons.wheel=Gi.NONE):this.mouseButtonsActiveStore&&(v.controls.mouseButtons.left=this.mouseButtonsActiveStore.mouseLeft,v.controls.mouseButtons.right=this.mouseButtonsActiveStore.mouseRight,v.controls.mouseButtons.wheel=this.mouseButtonsActiveStore.mouseWheel):r==="viewportPadding"&&v.setViewPadding(...m);return m})}show(){this.showState||(this.useSaveCamera("visShow"),this.options.disableInitShow||this.showAction())}showAction(){this.showState||(this.lead.group.show(),this.playing||this.lead.prefabGroup.show(),this.pencil.start(),this.showState=!0,this.emit("show"))}hide(){this.showState&&(this.lead.group.hide(),this.lead.prefabGroup.hide(),this.showState=!1,this.emit("hide"))}addCSS2D(v){return U0(this,arguments,function*(r,m={}){typeof m=="string"&&(m={display:m}),m.display&&(r.style.display=m.display);let C=0;typeof m.onTop!="undefined"&&(C=m.onTop);const _=yield this.lead.draw("Node",{onTop:C});return _.setChildren(r),_})}addCSS3D(v){return U0(this,arguments,function*(r,m={}){m.display&&(r.style.display=m.display);let C=0;typeof m.onTop!="undefined"&&(C=m.onTop);let _="3d";typeof m.type!="undefined"&&(_=m.type);const w=yield this.lead.draw("Node",{onTop:C,type:_});return w.setChildren(r),w})}getRoomEnvMap(){if(this.roomEnvMap)return this.roomEnvMap;const r=new PMREMGenerator(this.pencil.renderer);r.compileEquirectangularShader();const m=new RoomEnvironment,v=r.fromScene(m,.04).texture;return this.pmremGenerator=r,this.re=m,this.roomEnvMap=v,v}handlePick(r,m,v){console.warn("handlePick is deprecated, use BaseObject.onPointerEvent"),this.lead.handlePick(r,m,v)}getScreenPosition(r,m,v){const C=new Vector3(r,m,v);C.project(this.pencil.camera);const{width:_,height:w}=this.pencil.getSize(),I=(C.x*.5+.5)*_,O=(C.y*-.5+.5)*w;return{x:I,y:O}}dispose(){var r,m,v,C;super.dispose(),this.editor&&(this.editor.viewport.vis=void 0,this.editor.dispose()),this.publicDir={},this.options.pencil?this.pencil.removePage(this.sceneActive):this.options.pencil2||(r=this.pencil)==null||r.dispose(),(m=this.pmremGenerator)==null||m.dispose(),(v=this.re)==null||v.dispose(),(C=this.observeScale)==null||C.disconnect()}}C0(Base,"VisName","base");function clipGeojson(g,t){const r=turf.flatten(g).features,m=turf.flatten(t).features,v={type:"FeatureCollection",features:[]};for(let C=r.length-1;C>=0;C--){const _=r[C];for(let w=m.length-1;w>=0;w--){const I=m[w];if(contains(_,I))v.features.push(I);else if(contains(I,_))_.properties=I.properties,v.features.push(_);else{const O=turf.intersect(_,I);O&&(O.properties=I.properties,v.features.push(O))}}}return v}function contains(g,t){let r=!0;const m=turf.explode(t).features;for(let v=m.length-1;v>=0;v--)if(!turf.inside(m[v],g)){r=!1;break}return r}const getBoxMultiPoly=g=>{const t=g.features.map(r=>r.geometry.type==="Polygon"?[r.geometry.coordinates]:r.geometry.coordinates).flat();return Array.from({length:t.length},(r,m)=>turf.polygon(t[m]))};class Building extends ht{constructor(r){super();C0(this,"options");C0(this,"building",{});C0(this,"outJson",new Map);C0(this,"worldPositionZ",{value:0});this.options=q0({},r)}create(){return U0(this,null,function*(){const{json:r,projection:m,cacheKey:v,meters:C,grey:_,clip:w}=this.options,I=this.pencil.mList,O=this.pencil.getPlugin("worker"),Pe=this.pencil.lead,Ne=_?"-grey":"";this.createGroup();const Fe=I.getMultiple("building"+Ne);let Ae=v?yield O.getCachedGeometry({cacheKey:v}):[];if(Ae.length)w&&this.outJson.set(1,!0);else{let De;w&&(De=getBoxMultiPoly(w));const xt={};(r.features||r).forEach(ke=>{const at=typeof ke.properties.h=="string"?ke.properties.h.split(".")[1]:0,ct=Number(ke.properties.h)|0;xt[at]||(xt[at]={}),xt[at][ct]||(xt[at][ct]=[]),De?De.some(Lt=>{ke.geometry.coordinates[1]&&console.log(ke.geometry.coordinates[1]);const Wt=turf.polygon(ke.geometry.coordinates[0]);return turf.booleanContains(Lt,Wt)?(xt[at][ct].push(ke),!0):!1})||this.outJson.set(ke,!1):xt[at][ct].push(ke)});const je=Object.keys(xt).map(ke=>{const at=xt[ke];return Object.keys(at).map(ct=>{const Gt=at[ct];return{z:+ke,h:+ct,coordinatesArr:Gt.map(Lt=>Lt.geometry.type==="Polygon"?Lt.geometry.coordinates[0]:Lt.geometry.coordinates[0][0])}})}).flat().filter(ke=>ke.coordinatesArr.length);Ae=yield Promise.all(je.map(ke=>{const{h:at,z:ct,coordinatesArr:Gt}=ke,Lt=+at<=20?+at/18:+at<=60?+at/27:+at/12;return O.geoGeometry("extrudePolygon",{cacheKey:v,userData:{z:ct,h:at},mesaage:{coordinatesArr:Gt,projection:m,useGroups:2,depth:[Number(at)*(C||1)],hasBottom:!1,sideRepeat:Lt}})}))}yield Promise.all(Ae.map(De=>U0(this,null,function*(){const{h:xt,z:je}=De.userData,ke=xt+je,at=ke<=20?"20":ke<=60?"60":"max";let ct=this.options.material;ct||(ct=[Fe[at+"Top"],Fe[at+"Side"]]);const Gt=yield Pe.draw("ExtrudePolygon",{key:`$p:-${xt}-${je}`,geometry:De,material:ct},this);this.options.grey||(Gt.object3d.castShadow=!0),this.building[xt]||(this.building[xt]=[]),this.building[xt].push(Gt),Gt.position.z=Number(je)*(C||1)}))),this.options.sideGradient&&this.sideGradient(),this.object3d.name="建筑",_||this.lead.updateBaseObjectKey(this,`building${Ne?"-grey":""}#group`)})}sideGradient(r="#052438",m=.05/100){this.traverse(v=>{if(v instanceof is){const C=v.object3d.material;C[1].onBeforeCompile=_=>{_.uniforms.gradientColor={value:new Color$1(r)},_.uniforms.maxGradientHeight={value:m},_.uniforms.worldPositionZ=this.worldPositionZ,_.vertexShader=`
|
|
4856
4856
|
varying vec3 vPosition;
|
|
4857
4857
|
varying vec3 vWorldPosition;
|
|
4858
4858
|
${_.vertexShader}
|