vis-core 0.28.15 → 0.28.16
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 +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.module.js +61 -19
- 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 En=Object.defineProperty,In=Object.defineProperties;var zn=Object.getOwnPropertyDescriptors;var wn=Object.getOwnPropertySymbols,Nn=Object.getPrototypeOf,An=Object.prototype.hasOwnProperty,Kn=Object.prototype.propertyIsEnumerable,kn=Reflect.get;var Gn=(g,t)=>(t=Symbol[g])?t:Symbol.for("Symbol."+g),Fn=g=>{throw TypeError(g)},un=Math.pow,Zn=(g,t,r)=>t in g?En(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,Q0=(g,t)=>{for(var r in t||(t={}))An.call(t,r)&&Zn(g,r,t[r]);if(wn)for(var r of wn(t))Kn.call(t,r)&&Zn(g,r,t[r]);return g},Bi=(g,t)=>In(g,zn(t));var L0=(g,t,r)=>Zn(g,typeof t!="symbol"?t+"":t,r);var fn=(g,t,r)=>kn(Nn(g),r,t);var H0=(g,t,r)=>new Promise((m,v)=>{var C=E=>{try{w(r.next(E))}catch(O){v(O)}},_=E=>{try{w(r.throw(E))}catch(O){v(O)}},w=E=>E.done?m(E.value):Promise.resolve(E.value).then(C,_);w((r=r.apply(g,t)).next())}),Hn=function(g,t){this[0]=g,this[1]=t};var Vn=g=>{var t=g[Gn("asyncIterator")],r=!1,m,v={};return t==null?(t=g[Gn("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 Hn(new Promise(w=>{var E=t[C](_);E instanceof Object||Fn("Object expected"),w(E)}),1)}}),v[Gn("iterator")]=()=>v,m("next"),"throw"in t?m("throw"):v.throw=C=>{throw C},"return"in t&&m("return"),v},Wn=(g,t,r)=>(t=g[Gn("asyncIterator")])?t.call(g):(g=g[Gn("iterator")](),t={},r=(m,v)=>(v=g[m])&&(t[m]=C=>new Promise((_,w,E)=>(C=v.call(g,C),E=C.done,Promise.resolve(C.value).then(O=>_({value:O,done:E}),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)),E=jsrsasign.KJUR.crypto.Util.hashHex(v.toString(),"sha256"),O=m.verifyWithMessageHashPSS(E,jsrsasign.b64tohex(g),"sha256",32);if(!O)return this.token=void 0,"";const Pe=CryptoJS.AES.decrypt({ciphertext:w},C,{iv:_,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8),Ne=JSON.parse(Pe),Ae=Date.now();return!Ne.s||Ne.s>Ae?(this.token=void 0,""):Ne.e&&Ne.e<Ae?(this.token=void 0,""):(Ne.isValid=O,Ne)}},version="0.28.
|
|
2
|
+
"use strict";var En=Object.defineProperty,In=Object.defineProperties;var zn=Object.getOwnPropertyDescriptors;var wn=Object.getOwnPropertySymbols,Nn=Object.getPrototypeOf,An=Object.prototype.hasOwnProperty,Kn=Object.prototype.propertyIsEnumerable,kn=Reflect.get;var Gn=(g,t)=>(t=Symbol[g])?t:Symbol.for("Symbol."+g),Fn=g=>{throw TypeError(g)},un=Math.pow,Zn=(g,t,r)=>t in g?En(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,Q0=(g,t)=>{for(var r in t||(t={}))An.call(t,r)&&Zn(g,r,t[r]);if(wn)for(var r of wn(t))Kn.call(t,r)&&Zn(g,r,t[r]);return g},Bi=(g,t)=>In(g,zn(t));var L0=(g,t,r)=>Zn(g,typeof t!="symbol"?t+"":t,r);var fn=(g,t,r)=>kn(Nn(g),r,t);var H0=(g,t,r)=>new Promise((m,v)=>{var C=E=>{try{w(r.next(E))}catch(O){v(O)}},_=E=>{try{w(r.throw(E))}catch(O){v(O)}},w=E=>E.done?m(E.value):Promise.resolve(E.value).then(C,_);w((r=r.apply(g,t)).next())}),Hn=function(g,t){this[0]=g,this[1]=t};var Vn=g=>{var t=g[Gn("asyncIterator")],r=!1,m,v={};return t==null?(t=g[Gn("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 Hn(new Promise(w=>{var E=t[C](_);E instanceof Object||Fn("Object expected"),w(E)}),1)}}),v[Gn("iterator")]=()=>v,m("next"),"throw"in t?m("throw"):v.throw=C=>{throw C},"return"in t&&m("return"),v},Wn=(g,t,r)=>(t=g[Gn("asyncIterator")])?t.call(g):(g=g[Gn("iterator")](),t={},r=(m,v)=>(v=g[m])&&(t[m]=C=>new Promise((_,w,E)=>(C=v.call(g,C),E=C.done,Promise.resolve(C.value).then(O=>_({value:O,done:E}),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)),E=jsrsasign.KJUR.crypto.Util.hashHex(v.toString(),"sha256"),O=m.verifyWithMessageHashPSS(E,jsrsasign.b64tohex(g),"sha256",32);if(!O)return this.token=void 0,"";const Pe=CryptoJS.AES.decrypt({ciphertext:w},C,{iv:_,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8),Ne=JSON.parse(Pe),Ae=Date.now();return!Ne.s||Ne.s>Ae?(this.token=void 0,""):Ne.e&&Ne.e<Ae?(this.token=void 0,""):(Ne.isValid=O,Ne)}},version="0.28.16";/**
|
|
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},Gs=new MeshBasicMaterial({color:"black"}),Xs=new PointsMaterial({color:"black",sizeAttenuation:!1}),qs=new PointsMaterial({color:"black",sizeAttenuation:!0}),Qs=new SpriteMaterial({color:"black",sizeAttenuation:!0}),Js=new SpriteMaterial({color:"black",sizeAttenuation:!1}),ei=new Te$1({color:"black",sizeAttenuation:0,lineWidth:0}),ti={kernelRadius:8,minDistance:.005,maxDistance:.1},si={threshold:0,strength:.4,radius:.1,bloomAlphaType:0},ii={multisampling:4,premultiplieAlpha:!1};class ri{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:E}=_.capabilities,O=_.getDrawingBufferSize(new Vector2),ve=new WebGLRenderTarget(O.width,O.height,{samples:Math.min(w,E),type:HalfFloatType}),Pe=new EffectComposer(_,ve),Ne=this.getSize();Pe.setSize(Ne.width,Ne.height);const Ae=new RenderPass(m.scene,v.camera);Pe.addPass(Ae),this.scene=m.scene,this.camera=v.camera,this.finalComposer=Pe,this.renderPass=Ae,v.event.on("pageChange",Fe=>{this.changeCamera(Fe)}),m.event.on("pageChange",Fe=>{this.changeScene(Fe)})}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 Ks;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,E=new SSAOPass(r,m,_,w);E.kernelRadius=t.kernelRadius,E.minDistance=t.minDistance,E.maxDistance=t.maxDistance,this.ssaoPass=E,this.finalComposer.addPass(E)}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 E=new EffectComposer(r);E.renderToScreen=!1,E.addPass(this.renderPass),E.addPass(w),this.bloomComposer=E;const O=$s(E);O.uniforms.bloomAlphaType.value=_,this.bloomComposer=E,this.finalComposer.addPass(O),this.mixPass=O,this.bloomLayer.set(De)}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(De)):(this.bloomSelection.delete(m),v.layers.disable(De)))}),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,E=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=Qs:w.material=Js:_.material instanceof Te$1?_.material=ei:E.isPoints?E.material.sizeAttenuation?E.material=qs:E.material=Xs:_.material=Gs)})}),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 it 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,E=>{let O=E;const ve=t.split(".").pop(),Pe=this.options.type==="image"?`image/${ve||"png"}`:`video/${ve||"mp4"}`;O=O.slice(0,E.size,Pe);const Ne=()=>{_.removeEventListener("load",Ae,!1),_.removeEventListener("error",Fe,!1)},Ae=()=>{Ne(),C.needsUpdate=!0,r&&r(C)},Fe=Oe=>{Ne(),v&&v(Oe),this.manager.itemError(t),this.manager.itemEnd(t)};_.addEventListener("load",Ae,!1),_.addEventListener("error",Fe,!1);const ct=window.URL.createObjectURL(O);_.src=ct},m,v),C}}class oi 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=_,E=new DecompressionStream("gzip"),O=w.stream().pipeThrough(E);new Response(O).json().then(ve=>{r==null||r(ve)}).catch(ve=>{v==null||v(ve)})},m,v)}}const ni={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 ai{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(ni))if(C.includes(m))return v}getLoader(t,r){if(t==="images")return this.textureLoader||(this.textureLoader=new it(this.loadingManager),this.options.prefix&&this.textureLoader.setPath(this.options.prefix)),this.textureLoader;if(t==="media")return this.videoTextureLoader||(this.videoTextureLoader=new it(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 oi(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 E=this.getLoader(C,r);try{const O=yield E.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$1({texture:O});const ve=(v=r==null?void 0:r.anisotropy)!=null?v:this.options.anisotropy;O.anisotropy=ve}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(E=>{if(E){const O=this.getSrcByAsset(E,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 li={prefix:""};class hi extends ee{get loader(){return this.controller}constructor(t){super(),this.options=t}addLoader(t,r){const{loaderParams:m}=this.options,v=new ai(te(U({},m),{scene:t}));return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}function rt(g){let t=!1,r=[];return function(...m){r=m,t||(t=!0,requestAnimationFrame(()=>{t=!1,g(...r)}))}}class ci{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,E=[];if(this.pickFunctionsMap.forEach(Ae=>{w.has(Ae.type)&&E.push(te(U({},Ae),{objArr:Ae.objArr instanceof Function?Ae.objArr():Ae.objArr}))}),E.length===0)return;this.activeObjects.clear(),this.objCallbackMap.clear(),this.activeObject=null;const O=this.objCallbackMap;for(const Ae of E)for(const Fe of Ae.objArr){if(!Fe.object3d||!Fe.visibleWithAncestors)continue;O.has(Fe)||O.set(Fe,new Map);const ct=O.get(Fe);ct.has(Ae.type)||ct.set(Ae.type,[]),ct.get(Ae.type).push(Ae.cb)}if(O.size===0)return;const ve=[...O.keys()].map(Ae=>Ae.object3d),Pe=(_=this.pencil.pick(C,ve,!0))==null?void 0:_.intersects;if(!Pe||Pe.length===0)t==="down"?this.handleDownOutside(C):t==="move"&&this.handleLeaveEvents(C);else{const Ae=Pe[0];this.processIntersection(Ae,C,t)}const Ne=this.prevActiveObjects;this.prevActiveObjects=this.activeObjects,this.activeObjects=Ne,this.activeObjects.clear()};this.domElement.addEventListener(`pointer${t}`,rt(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 E=v.get(w);if(E)if(r==="move"){const O=E.get("enter");if(O&&!this.prevActiveObjects.has(w))for(const Pe of O)Pe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const ve=E.get("move");if(ve)for(const Pe of ve)Pe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m})}else{const O=E.get("down");if(O)for(const Pe of O)Pe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const ve=E.get("click");if(ve){const Pe=Ne=>{Ne.preventDefault();const Ae=5;if(!C&&Math.abs(Ne.clientX-t.clientX)<=Ae&&Math.abs(Ne.clientY-t.clientY)<=Ae)for(const Fe of ve)Fe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});this.domElement.removeEventListener("pointerup",Pe)};this.domElement.addEventListener("pointerup",Pe)}}}}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 E=w;E.element.style.pointerEvents="auto";const O=Pe=>{this.enabled&&(Pe.preventDefault(),m({baseObject:E,mouseEvent:Pe}))},ve=`pointer${r}`;E.element.addEventListener(ve,rt(O),!1),_.push({arr:E,type:ve,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 di extends ci{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),this.pencil.options.mList&&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 E=this.objectNamesToFactories.get(t);if(E){r||(r={}),r.target===void 0&&(r.target=m);const O=r.target,ve=(v=r.onTop)!=null?v:0,Pe=(C=r.prefab)!=null?C:!1,Ne=(_=r.create)!=null?_:!0,Ae=new E().create(r);let Fe;return O===null?Fe=null:typeof O=="string"?Fe=this.objects.get(O):(w=O==null?void 0:O.objectType)!=null&&w.startsWith("BaseObject")||O?Fe=O:Pe?Fe=this.prefabGroup:Fe=this.group,Ne===!1?Ae.create=()=>{}:Ne!==!0&&(Ae.create=()=>{Ne(Ae)}),Ae.pencil=this.pencil,Ae.lead=this,Ae.mList=this.mList,Ae.prefab=Pe,Ae.objectType=`BaseObject#${t}`,Ae.objectOptions=r,this.setBaseObjectKey(Ae,r.key?`$t:#${r.key}`:"$t:",Fe==null?void 0:Fe.key),this.objectsPm.set(Ae,this.addBaseObject(Ae,Fe,ve)),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,E]of this.objects.entries())if(E===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,E)=>{w.key.includes("__c__")&&this.updateBaseObjectKey(w,`${_}__c__${E}`)}),_}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.pencil.options.mList&&(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 mi extends ee{get lead(){return this.controller}constructor(t){super(),this.options=t}addLead(t,r,m){const{pencil:v}=this.options,C=new di(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 pi{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 E=v.material;return v.material=_,this.materials.set(t,_),this.disposeMaterial(E),this.syncChangeMaterial(E,_),!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),E=_.clone();m[w]=E;const O=`${r}#${w}`;this.add(O,E)}return m}disposeMaterial(t){if(!t)return;const r=new re$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:(E,O,ve)=>{if(typeof O=="string"&&!isNaN(Number(O))){const Pe=Number(O);if(Pe>=0&&Pe<E.length){const Ne=E[Pe];return this.rmBaseObjectMap(t,Ne),E[Pe]=ve,ve&&this.addBaseObjectMap(t),!0}}return E[O]=ve,!0}});return Object.defineProperty(w,"__isProxy",{value:!0,enumerable:!1}),w};t.materialList&&(t.materialList=new Proxy(t.materialList,{set:(_,w,E)=>{if(typeof w=="string"){const O=_[w];return this.rmBaseObjectMap(t,O),_[w]=E,E&&this.addBaseObjectMap(t),!0}return _[w]=E,!0},get:(_,w)=>{if(typeof w=="string"&&_[w]){const E=_[w];if(Array.isArray(E)){const O=m(E);return O!==E&&(_[w]=O),O}return E}return _[w]},deleteProperty:(_,w)=>{if(typeof w=="string"&&_[w]){const E=_[w];this.rmBaseObjectMap(t,E)}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 E=m(w);return E!==w&&(r[C]=E),E}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 E=v.materialList[w];if(Array.isArray(E)){const O=E.indexOf(t);O!==-1&&(E[O]=r)}else E===t&&(v.materialList[w]=r)})})}dispose(){const t=new re$1;t.track([...this.materials.values()]),t.dispose(),this.materials.clear(),this.fixBaseObjects.clear(),this.materialBaseObjectMap.clear()}}class fi extends ee{get mList(){return this.controller}constructor(t){super(),this.options=t}addMList(t,r){const{pencil:m}=this.options,v=new pi(m);return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}const _e=class Pn{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=rs(Pn.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:E}=this.options,{width:O,height:ve}=this.getSize(),Pe=m?new Ds({width:O,height:ve,renderer:m.WebGPURenderer,rendererParams:Rs}):new Ms({width:O,height:ve,rendererParams:te(U({},_),{antialias:!1})}),Ne=new zs({width:O,height:ve}),Ae=new Fs({}),Fe=new js({controlsParams:{domElement:(t=w==null?void 0:w.domElement)!=null?t:Pe.renderer.domElement}}),ct=new hi({loaderParams:U({anisotropy:Pe.renderer.capabilities.getMaxAnisotropy()},E)}),Oe=new fi({pencil:this}),ke=new mi({pencil:this});this.sceneController=Ae,this.cameraController=Ne,this.controlsController=Fe,this.rendererController=Pe,this.loaderController=ct,this.mListController=Oe,this.leadController=ke;const je=this.addPage({sceneOptions:this.options.scene,cameraOptions:this.options.camera});if(this.showPage(je),v){const at=new Ns({container:r,sceneController:Ae,cameraController:Ne});at.add(Ae.scene),this.helperController=at,C&&at.addViewHelper()}r.appendChild(Pe.renderer.domElement)}initComposer(){const{bloom:t,bloomParams:r,ssao:m,ssaoParams:v,composer:C}=this.options,_=new ri({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 Zs(t);r&&_.addRenderer("css2d",v),m&&_.addRenderer("css3d",C),this.cssRendererController=_}}initTransformControls(){const t=new Is({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:E}=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),E.setSize(t,r),this.installPlugins.forEach(ve=>{var Pe;(Pe=ve.setSize)==null||Pe.call(ve,t,r)}),this.viewPadding.some(ve=>ve!==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(E=>E!==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,E=_.getBoundingClientRect();if(w.x=(t.clientX-E.left)/(E.right-E.left)*2-1,w.y=-((t.clientY-E.top)/(E.bottom-E.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.timer.update(),update();const w=this.timer.getDelta(),E=this.timer.getElapsed();this.controlsController.update(w,E),this.leadController.update(w,E),this.installPlugins.forEach(O=>{var ve;(ve=O.update)==null||ve.call(O,w,E)}),(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:E})}start(){window.cancelAnimationFrame(this.TweenRaf),this.renderer.setAnimationLoop(this.render.bind(this)),this.event.emit("start")}stop(){this.tweenUpdateRaf(),this.renderer.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,E,O,ve,Pe,Ne,Ae,Fe;this.stop(),this.timer.dispose(),removeAll(),this.event.removeAllListeners(),(t=this.resizeObserver)==null||t.unobserve(this.options.container),this.installPlugins.forEach(ct=>{var Oe;(Oe=ct.dispose)==null||Oe.call(ct)}),(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(),(E=this.composerController)==null||E.dispose(),(O=this.rendererController)==null||O.dispose(),(ve=this.loaderController)==null||ve.dispose(),(Pe=this.leadController)==null||Pe.dispose(),(Ne=this.mListController)==null||Ne.dispose(),this.cssRendererController=void 0,this.installPlugins.clear(),(Ae=this.stats)==null||Ae.dom.remove(),(Fe=this.renderer)==null||Fe.domElement.remove()}};_e.options={stats:Le$1,helper:Le$1,viewHelper:Le$1,controls:!0,transformControls:Le$1,renderer:Ss,composer:ii,scene:ks,camera:wt,bloom:!1,bloomParams:si,ssao:!1,loader:li,ssaoParams:ti,css2DRenderer:!1,css2DRendererParams:U({},st),css3DRenderer:!1,css3DRendererParams:U({},st),mList:!0};let ot=_e;const Gi=J.ACTION,b$1=new Map,R$2=(g={})=>({generateTopUV(t,r,m,v,C){const _=r[m*3],w=r[m*3+1],E=r[v*3],O=r[v*3+1],ve=r[C*3],Pe=r[C*3+1];let Ne;if(b$1.has(t))Ne=b$1.get(t);else{let Oe=g.box3;if(!Oe){Oe=new Box3;const je=t.parameters.shapes.getPoints().map(at=>[at.x,at.y,0]).flat();Oe.setFromArray(je)}const ke=Oe.getSize(new Vector3);g.split&&(ke.y/=g.split),Ne={box:Oe,size:ke},b$1.set(t,Ne)}const{box:Ae,size:Fe}=Ne,ct=g.split?1-g.split:0;return[new Vector2((_-Ae.min.x)/Fe.x,(w-Ae.min.y)/Fe.y+ct),new Vector2((E-Ae.min.x)/Fe.x,(O-Ae.min.y)/Fe.y+ct),new Vector2((ve-Ae.min.x)/Fe.x,(Pe-Ae.min.y)/Fe.y+ct)]},generateSideWallUV(t,r,m,v,C,_){const w=r[m*3],E=r[m*3+1],O=r[m*3+2],ve=r[v*3],Pe=r[v*3+1],Ne=r[v*3+2],Ae=r[C*3],Fe=r[C*3+1],ct=r[C*3+2],Oe=r[_*3],ke=r[_*3+1],je=r[_*3+2];let at;if(b$1.has(r))at=b$1.get(r);else{const Lt=new Box3;Lt.setFromArray(r);const Wt=Lt.getSize(new Vector3);g.split&&(Wt.z/=1-g.split),g.sideRepeat&&(Wt.z/=g.sideRepeat),at={box:Lt,size:Wt},b$1.set(r,at)}const{box:xt,size:Gt}=at;return Math.abs(E-Pe)<Math.abs(w-ve)?[new Vector2((w-xt.min.x)/Gt.x,(O-xt.min.z)/Gt.z),new Vector2((ve-xt.min.x)/Gt.x,(Ne-xt.min.z)/Gt.z),new Vector2((Ae-xt.min.x)/Gt.x,(ct-xt.min.z)/Gt.z),new Vector2((Oe-xt.min.x)/Gt.x,(je-xt.min.z)/Gt.z)]:[new Vector2((E-xt.min.y)/Gt.y,(O-xt.min.z)/Gt.z),new Vector2((Pe-xt.min.y)/Gt.y,(Ne-xt.min.z)/Gt.z),new Vector2((Fe-xt.min.y)/Gt.y,(ct-xt.min.z)/Gt.z),new Vector2((ke-xt.min.y)/Gt.y,(je-xt.min.z)/Gt.z)]}}),P=()=>{b$1.clear()};var Jt=Object.defineProperty,Xt=Object.defineProperties,Qt=Object.getOwnPropertyDescriptors,lt=Object.getOwnPropertySymbols,Vt=Object.prototype.hasOwnProperty,Bt=Object.prototype.propertyIsEnumerable,It=(g,t,r)=>t in g?Jt(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,G=(g,t)=>{for(var r in t||(t={}))Vt.call(t,r)&&It(g,r,t[r]);if(lt)for(var r of lt(t))Bt.call(t,r)&&It(g,r,t[r]);return g},ut=(g,t)=>Xt(g,Qt(t)),gt=(g,t)=>{var r={};for(var m in g)Vt.call(g,m)&&t.indexOf(m)<0&&(r[m]=g[m]);if(g!=null&<)for(var m of lt(g))t.indexOf(m)<0&&Bt.call(g,m)&&(r[m]=g[m]);return r},nt=(g,t,r)=>new Promise((m,v)=>{var C=E=>{try{w(r.next(E))}catch(O){v(O)}},_=E=>{try{w(r.throw(E))}catch(O){v(O)}},w=E=>E.done?m(E.value):Promise.resolve(E.value).then(C,_);w((r=r.apply(g,t)).next())});class Xe extends ht{constructor(t){super(),this.objectType="BaseObject#Node",this.onNodePointerIndex=[],this.options=G({type:"2d"},t)}create(){const{position:t,children:r}=this.options,m=document.createElement("div");this.element=m,r&&m.appendChild(r),this.options.type==="3d"?this.createCSS3DObject(m):this.options.type==="3dSprite"?this.createCSS3DSprite(m):this.createCSS2DObject(m),t&&this.object3d.position.copy(t)}setChildren(t){this.options.children=t,this.element.innerHTML="",this.element.appendChild(t)}showAndEnsureVisible(){const t=this.options.children;t&&(t.style.visibility="hidden",this.show(),setTimeout(()=>{t.style.visibility="",this.ensureVisible()}))}moveElementToViewport(){const t=this.options.children;if(!t)return;const r=t.getBoundingClientRect(),m=window.innerWidth,v=window.innerHeight;let C=0,_=0;r.left<0?C=-r.left:r.right>m&&(C=m-r.right),r.top<0?_=-r.top:r.bottom>v&&(_=v-r.bottom),r.left+C<0&&(C=-r.left),r.top+_<0&&(_=-r.top),(C!==0||_!==0)&&(t.style.transform=`translate(${C}px, ${_}px)`)}ensureVisible(){const t=this.options.children;if(!t)return;t.style.transform&&(t.style.transform="");const r=new IntersectionObserver(m=>{m.forEach(v=>{v.isIntersecting&&(this.moveElementToViewport(),r.disconnect())})});r.observe(t)}onPointerEvent(t,r){const m=this.lead.handlePickNode([this],t,r);this.onNodePointerIndex.push(m)}dispose(){this.onNodePointerIndex.forEach(t=>{this.lead.removePickNode(t)}),super.dispose()}}class Qe extends ht{create(){this.createGroup()}}const Ue={ArcCurve,CatmullRomCurve3,CubicBezierCurve,CubicBezierCurve3,EllipseCurve,LineCurve,LineCurve3,QuadraticBezierCurve,QuadraticBezierCurve3,SplineCurve};class Z extends BufferGeometry{constructor(t=new Shape([new Vector2(.5,.5),new Vector2(-.5,.5),new Vector2(-.5,-.5),new Vector2(.5,-.5)]),r={}){super(),this.type="ExtrudeGeometry",this.parameters={shapes:t,options:r},t=Array.isArray(t)?t:[t];const m=this,v=[],C=[];for(let w=0,E=t.length;w<E;w++){const O=t[w];_(O)}this.setAttribute("position",new Float32BufferAttribute(v,3)),this.setAttribute("uv",new Float32BufferAttribute(C,2)),this.computeVertexNormals();function _(w){var E,O,ve;const Pe=[],Ne=r.curveSegments!==void 0?r.curveSegments:12,Ae=r.steps!==void 0?r.steps:1,Fe=r.depth!==void 0?r.depth:1;let ct=r.bevelEnabled!==void 0?r.bevelEnabled:!0,Oe=r.bevelThickness!==void 0?r.bevelThickness:.2,ke=r.bevelSize!==void 0?r.bevelSize:Oe-.1,je=r.bevelOffset!==void 0?r.bevelOffset:0,at=r.bevelSegments!==void 0?r.bevelSegments:3;const xt=r.extrudePath,Gt=r.UVGenerator!==void 0?r.UVGenerator:Ce,Lt=(E=r.hasTop)!=null?E:!0,Wt=(O=r.hasBottom)!=null?O:!0,Pt=(ve=r.hasSide)!=null?ve:!0;let zt,Nt=!1,Kt,t0,n0,o0;xt&&(zt=xt.getSpacedPoints(Ae),Nt=!0,ct=!1,Kt=xt.computeFrenetFrames(Ae,!1),t0=new Vector3,n0=new Vector3,o0=new Vector3),ct||(at=0,Oe=0,ke=0,je=0);const i0=w.extractPoints(Ne);let Yt=i0.shape;const qt=i0.holes;if(!ShapeUtils.isClockWise(Yt)){Yt=Yt.reverse();for(let P0=0,C0=qt.length;P0<C0;P0++){const E0=qt[P0];ShapeUtils.isClockWise(E0)&&(qt[P0]=E0.reverse())}}function kt(P0){const C0=10000000000000001e-36;let E0=P0[0];for(let q0=1;q0<=P0.length;q0++){const a0=q0%P0.length,s0=P0[a0],S0=s0.x-E0.x,R0=s0.y-E0.y,K0=S0*S0+R0*R0,V0=Math.max(Math.abs(s0.x),Math.abs(s0.y),Math.abs(E0.x),Math.abs(E0.y)),Ri=C0*V0*V0;if(K0<=Ri){P0.splice(a0,1),q0--;continue}E0=s0}}kt(Yt),qt.forEach(kt);const r0=qt.length,f0=Yt;for(let P0=0;P0<r0;P0++){const C0=qt[P0];Yt=Yt.concat(C0)}function m0(P0,C0,E0){return C0||console.error("THREE.ExtrudeGeometry: vec does not exist"),P0.clone().addScaledVector(C0,E0)}const w0=Yt.length;function $0(P0,C0,E0){let q0,a0,s0;const S0=P0.x-C0.x,R0=P0.y-C0.y,K0=E0.x-P0.x,V0=E0.y-P0.y,Ri=S0*S0+R0*R0,Ci=S0*V0-R0*K0;if(Math.abs(Ci)>Number.EPSILON){const _i=Math.sqrt(Ri),Pi=Math.sqrt(K0*K0+V0*V0),U0=C0.x-R0/_i,Zi=C0.y+S0/_i,Hi=E0.x-V0/Pi,Ni=E0.y+K0/Pi,Mi=((Hi-U0)*V0-(Ni-Zi)*K0)/(S0*V0-R0*K0);q0=U0+S0*Mi-P0.x,a0=Zi+R0*Mi-P0.y;const Vi=q0*q0+a0*a0;if(Vi<=2)return new Vector2(q0,a0);s0=Math.sqrt(Vi/2)}else{let _i=!1;S0>Number.EPSILON?K0>Number.EPSILON&&(_i=!0):S0<-Number.EPSILON?K0<-Number.EPSILON&&(_i=!0):Math.sign(R0)===Math.sign(V0)&&(_i=!0),_i?(q0=-R0,a0=S0,s0=Math.sqrt(Ri)):(q0=S0,a0=R0,s0=Math.sqrt(Ri/2))}return new Vector2(q0/s0,a0/s0)}const v0=[];for(let P0=0,C0=f0.length,E0=C0-1,q0=P0+1;P0<C0;P0++,E0++,q0++)E0===C0&&(E0=0),q0===C0&&(q0=0),v0[P0]=$0(f0[P0],f0[E0],f0[q0]);const I0=[];let A0,O0=v0.concat();for(let P0=0,C0=r0;P0<C0;P0++){const E0=qt[P0];A0=[];for(let q0=0,a0=E0.length,s0=a0-1,S0=q0+1;q0<a0;q0++,s0++,S0++)s0===a0&&(s0=0),S0===a0&&(S0=0),A0[q0]=$0(E0[q0],E0[s0],E0[S0]);I0.push(A0),O0=O0.concat(A0)}let xi;if(at===0)xi=ShapeUtils.triangulateShape(f0,qt);else{const P0=[],C0=[];for(let E0=0;E0<at;E0++){const q0=E0/at,a0=Oe*Math.cos(q0*Math.PI/2),s0=ke*Math.sin(q0*Math.PI/2)+je;for(let S0=0,R0=f0.length;S0<R0;S0++){const K0=m0(f0[S0],v0[S0],s0);l0(K0.x,K0.y,-a0),q0===0&&P0.push(K0)}for(let S0=0,R0=r0;S0<R0;S0++){const K0=qt[S0];A0=I0[S0];const V0=[];for(let Ri=0,Ci=K0.length;Ri<Ci;Ri++){const _i=m0(K0[Ri],A0[Ri],s0);l0(_i.x,_i.y,-a0),q0===0&&V0.push(_i)}q0===0&&C0.push(V0)}}xi=ShapeUtils.triangulateShape(P0,C0)}const wi=xi.length,Li=ke+je;for(let P0=0;P0<w0;P0++){const C0=ct?m0(Yt[P0],O0[P0],Li):Yt[P0];Nt?(n0.copy(Kt.normals[0]).multiplyScalar(C0.x),t0.copy(Kt.binormals[0]).multiplyScalar(C0.y),o0.copy(zt[0]).add(n0).add(t0),l0(o0.x,o0.y,o0.z)):l0(C0.x,C0.y,0)}for(let P0=1;P0<=Ae;P0++)for(let C0=0;C0<w0;C0++){const E0=ct?m0(Yt[C0],O0[C0],Li):Yt[C0];Nt?(n0.copy(Kt.normals[P0]).multiplyScalar(E0.x),t0.copy(Kt.binormals[P0]).multiplyScalar(E0.y),o0.copy(zt[P0]).add(n0).add(t0),l0(o0.x,o0.y,o0.z)):l0(E0.x,E0.y,Fe/Ae*P0)}for(let P0=at-1;P0>=0;P0--){const C0=P0/at,E0=Oe*Math.cos(C0*Math.PI/2),q0=ke*Math.sin(C0*Math.PI/2)+je;for(let a0=0,s0=f0.length;a0<s0;a0++){const S0=m0(f0[a0],v0[a0],q0);l0(S0.x,S0.y,Fe+E0)}for(let a0=0,s0=qt.length;a0<s0;a0++){const S0=qt[a0];A0=I0[a0];for(let R0=0,K0=S0.length;R0<K0;R0++){const V0=m0(S0[R0],A0[R0],q0);Nt?l0(V0.x,V0.y+zt[Ae-1].y,zt[Ae-1].x+E0):l0(V0.x,V0.y,Fe+E0)}}}ki(),Pt&&Ki();function ki(){const P0=v.length/3;if(ct){let C0=0,E0=w0*C0;if(Wt)for(let q0=0;q0<wi;q0++){const a0=xi[q0];Si(a0[2]+E0,a0[1]+E0,a0[0]+E0)}if(C0=Ae+at*2,E0=w0*C0,Lt)for(let q0=0;q0<wi;q0++){const a0=xi[q0];Si(a0[0]+E0,a0[1]+E0,a0[2]+E0)}}else{if(Wt)for(let C0=0;C0<wi;C0++){const E0=xi[C0];Si(E0[2],E0[1],E0[0])}if(Lt)for(let C0=0;C0<wi;C0++){const E0=xi[C0];Si(E0[0]+w0*Ae,E0[1]+w0*Ae,E0[2]+w0*Ae)}}m.addGroup(P0,v.length/3-P0,0)}function Ki(){const P0=v.length/3;let C0=0;B0(f0,C0),C0+=f0.length;for(let E0=0,q0=qt.length;E0<q0;E0++){const a0=qt[E0];B0(a0,C0),C0+=a0.length}m.addGroup(P0,v.length/3-P0,1)}function B0(P0,C0){let E0=P0.length;for(;--E0>=0;){const q0=E0;let a0=E0-1;a0<0&&(a0=P0.length-1);for(let s0=0,S0=Ae+at*2;s0<S0;s0++){const R0=w0*s0,K0=w0*(s0+1),V0=C0+q0+R0,Ri=C0+a0+R0,Ci=C0+a0+K0,_i=C0+q0+K0;j0(V0,Ri,Ci,_i)}}}function l0(P0,C0,E0){Pe.push(P0),Pe.push(C0),Pe.push(E0)}function Si(P0,C0,E0){gi(P0),gi(C0),gi(E0);const q0=v.length/3,a0=Gt.generateTopUV(m,v,q0-3,q0-2,q0-1);k0(a0[0]),k0(a0[1]),k0(a0[2])}function j0(P0,C0,E0,q0){gi(P0),gi(C0),gi(q0),gi(C0),gi(E0),gi(q0);const a0=v.length/3,s0=Gt.generateSideWallUV(m,v,a0-6,a0-3,a0-2,a0-1);k0(s0[0]),k0(s0[1]),k0(s0[3]),k0(s0[1]),k0(s0[2]),k0(s0[3])}function gi(P0){v.push(Pe[P0*3+0]),v.push(Pe[P0*3+1]),v.push(Pe[P0*3+2])}function k0(P0){C.push(P0.x),C.push(P0.y)}}}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}toJSON(){const t=super.toJSON(),r=this.parameters.shapes,m=this.parameters.options;return Ie(r,m,t)}static fromJSON(t,r){const m=[];for(let C=0,_=t.shapes.length;C<_;C++){const w=r[t.shapes[C]];m.push(w)}const v=t.options.extrudePath;return v!==void 0&&(t.options.extrudePath=new Ue[`${v.type}`]().fromJSON(v)),new Z(m,t.options)}}const Ce={generateTopUV:function(g,t,r,m,v){const C=t[r*3],_=t[r*3+1],w=t[m*3],E=t[m*3+1],O=t[v*3],ve=t[v*3+1];return[new Vector2(C,_),new Vector2(w,E),new Vector2(O,ve)]},generateSideWallUV:function(g,t,r,m,v,C){const _=t[r*3],w=t[r*3+1],E=t[r*3+2],O=t[m*3],ve=t[m*3+1],Pe=t[m*3+2],Ne=t[v*3],Ae=t[v*3+1],Fe=t[v*3+2],ct=t[C*3],Oe=t[C*3+1],ke=t[C*3+2];return Math.abs(w-ve)<Math.abs(_-O)?[new Vector2(_,1-E),new Vector2(O,1-Pe),new Vector2(Ne,1-Fe),new Vector2(ct,1-ke)]:[new Vector2(w,1-E),new Vector2(ve,1-Pe),new Vector2(Ae,1-Fe),new Vector2(Oe,1-ke)]}};function Ie(g,t,r){if(r.shapes=[],Array.isArray(g))for(let m=0,v=g.length;m<v;m++){const C=g[m];r.shapes.push(C.uuid)}else r.shapes.push(g.uuid);return r.options=Object.assign({},t),t.extrudePath!==void 0&&(r.options.extrudePath=t.extrudePath.toJSON()),r}class Ze extends ht{constructor(t){super(),this.rectAreaLightUniformsLibInit=!1,this.options=t}create(){var t,r,m,v,C,_,w,E,O,ve,Pe,Ne,Ae,Fe,ct,Oe,ke;const je=this.options;if(je.type==="AmbientLight"){const at=new AmbientLight(je.color);at.name="环境光",this.object3d=at}else if(je.type==="DirectionalLight"){const at=new DirectionalLight(je.color,je.intensity);at.name="平行光",at.target.position.set(0,0,0),this.object3d=at,at.target.name="平行光目标",at.shadow.camera.name="平行光阴影相机",at.shadow.camera.userData.directionalLightShadow=!0,this.directionalLight=at}else if(je.type==="PointLight"){const at=new PointLight((t=je.color)!=null?t:16777215,(r=je.intensity)!=null?r:1,(m=je.distance)!=null?m:0,(v=je.decay)!=null?v:2);at.name="点光源",this.object3d=at,this.pointLight=at}else if(je.type==="SpotLight"){const at=new SpotLight((C=je.color)!=null?C:16777215,(_=je.intensity)!=null?_:1,(w=je.distance)!=null?w:0,(E=je.angle)!=null?E:Math.PI/3,(O=je.penumbra)!=null?O:1,(ve=je.decay)!=null?ve:2);at.name="聚光灯",this.object3d=at,this.spotLight=at,at.target.name="聚光灯目标"}else if(je.type==="HemisphereLight"){const at=new HemisphereLight((Pe=je.color)!=null?Pe:16777215,(Ne=je.groundColor)!=null?Ne:16777215,(Ae=je.intensity)!=null?Ae:1);at.name="半球光",this.object3d=at,this.hemisphereLight=at}else if(je.type==="RectAreaLight"){this.rectAreaLightUniformsLibInit||(RectAreaLightUniformsLib.init(),this.rectAreaLightUniformsLibInit=!0);const at=new RectAreaLight((Fe=je.color)!=null?Fe:16777215,(ct=je.intensity)!=null?ct:1,(Oe=je.width)!=null?Oe:10,(ke=je.height)!=null?ke:10);at.name="矩形区域光",this.object3d=at,this.rectAreaLight=at}}render(){const t=this.object3d;t.target&&this.pencil.scene.add(t.target);const r=this.pencil.cameraTarget;if(this.spotLight||this.directionalLight){const m=this.spotLight||this.directionalLight;m.position.copy(r),m.target.position.copy(r)}else this.pointLight&&this.pointLight.position.copy(r)}dispose(){const t=this.object3d;t.target&&this.pencil.scene.remove(t.target),super.dispose()}}function R$1(g,t=0){const r=g[0].index!==null,m=new Set(Object.keys(g[0].attributes)),v=new Set(Object.keys(g[0].morphAttributes)),C={},_={},w=g[0].morphTargetsRelative,E=new BufferGeometry;let O=0;for(let ve=0;ve<g.length;++ve){const Pe=g[ve];let Ne=0;if(r!==(Pe.index!==null))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const Ae in Pe.attributes){if(!m.has(Ae))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+'. All geometries must have compatible attributes; make sure "'+Ae+'" attribute exists among all geometries, or in none of them.'),null;C[Ae]===void 0&&(C[Ae]=[]),C[Ae].push(Pe.attributes[Ae]),Ne++}if(Ne!==m.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". Make sure all geometries have the same number of attributes."),null;if(w!==Pe.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const Ae in Pe.morphAttributes){if(!v.has(Ae))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". .morphAttributes must be consistent throughout all geometries."),null;_[Ae]===void 0&&(_[Ae]=[]),_[Ae].push(Pe.morphAttributes[Ae])}if(t){let Ae;if(r)Ae=Pe.index.count;else if(Pe.attributes.position!==void 0)Ae=Pe.attributes.position.count;else return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". The geometry must have either an index or a position attribute"),null;if(t===1)E.addGroup(O,Ae,ve);else if(t===2&&Pe.groups.length>0)for(let Fe of Pe.groups){let ct=Fe.materialIndex;E.addGroup(O+Fe.start,Math.min(Fe.count,Ae),ct)}O+=Ae}}if(r){let ve=0;const Pe=[];for(let Ne=0;Ne<g.length;++Ne){const Ae=g[Ne].index;for(let Fe=0;Fe<Ae.count;++Fe)Pe.push(Ae.getX(Fe)+ve);ve+=g[Ne].attributes.position.count}E.setIndex(Pe)}for(const ve in C){const Pe=mergeAttributes(C[ve]);if(!Pe)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+ve+" attribute."),null;E.setAttribute(ve,Pe)}for(const ve in _){const Pe=_[ve][0].length;if(Pe===0)break;E.morphAttributes=E.morphAttributes||{},E.morphAttributes[ve]=[];for(let Ne=0;Ne<Pe;++Ne){const Ae=[];for(let ct=0;ct<_[ve].length;++ct)Ae.push(_[ve][ct][Ne]);const Fe=mergeAttributes(Ae);if(!Fe)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+ve+" morphAttribute."),null;E.morphAttributes[ve].push(Fe)}}return t===2?mergeGroups(E):E}const Dt=g=>{const{points:t}=g,r=t.reduce((m,v,C)=>(C<t.length-1&&m.push(v,t[C+1]),m),[]);return new BufferGeometry().setFromPoints(r)};let Ke=class extends ht{constructor(g={}){super(),this.options=G({},g)}get material(){var g;return(g=this.object3d)==null?void 0:g.material}create(){return nt(this,null,function*(){const{points:g,pointsArr:t,geometry:r,geometryArr:m,material:v,useGroups:C,setPointWidth:_,lineWidthArr:w,materialParameters:E,instanceCount:O}=this.options;let ve=v,Pe=r;!ve&&E&&(ve=this.getMaterial(E)),!Pe&&g?Pe=Dt({points:g}):!Pe&&t?Pe=R$1(t.map(Ae=>Dt({points:Ae})),C!=null?C:0):!Pe&&m&&m.length>1?Pe=R$1(m,C!=null?C:0):!Pe&&m&&m.length===1&&([Pe]=m);const Ne=new LineSegmentsGeometry().fromLineSegments(new LineSegments(Pe));if(this.pencil.options.WebGPUTHREE){O&&(Ne.instanceCount=O);const Ae=new _e$1(Ne,ve);Ae.computeLineDistances(),this.object3d=Ae}else{const Ae=new LineSegments2(Ne,ve);Ae.computeLineDistances(),this.object3d=Ae}})}getMaterial(g){return new LineMaterial(G({color:new Color$1("#ffffff")},g))}};function yt(g,t,r,m,v){let C;if(g=g.subarray||g.slice?g:g.buffer,r=r.subarray||r.slice?r:r.buffer,g=t?g.subarray?g.subarray(t,v&&t+v):g.slice(t,v&&t+v):g,r.set)r.set(g,m);else for(C=0;C<g.length;C++)r[C+m]=g[C];return r}function Ve(g){return g instanceof Float32Array?g:g instanceof BufferGeometry?g.getAttribute("position").array:g.map(t=>{const r=Array.isArray(t);return t instanceof Vector3?[t.x,t.y,t.z]:t instanceof Vector2?[t.x,t.y,0]:r&&t.length===3?[t[0],t[1],t[2]]:r&&t.length===2?[t[0],t[1],0]:t}).flat()}class Be extends BufferGeometry{constructor(){super(),this.type="MeshLine",this.isMeshLine=!0,this.positions=[],this.previous=[],this.next=[],this.side=[],this.width=[],this.indices_array=[],this.uvs=[],this.counters=[],this.widthCallback=null,this._points=[],this.matrixWorld=new Matrix4,Object.defineProperties(this,{points:{enumerable:!0,get(){return this._points},set(t){this.setPoints(t,this.widthCallback)}}})}setMatrixWorld(t){this.matrixWorld=t}setPoints(t,r){if(t=Ve(t),this._points=t,this.widthCallback=r!=null?r:null,this.positions=[],this.counters=[],t.length&&t[0]instanceof Vector3)for(let m=0;m<t.length;m++){const v=t[m],C=m/(t.length-1);this.positions.push(v.x,v.y,v.z),this.positions.push(v.x,v.y,v.z),this.counters.push(C),this.counters.push(C)}else for(let m=0;m<t.length;m+=3){const v=m/(t.length-1);this.positions.push(t[m],t[m+1],t[m+2]),this.positions.push(t[m],t[m+1],t[m+2]),this.counters.push(v),this.counters.push(v)}this.process()}compareV3(t,r){const m=t*6,v=r*6;return this.positions[m]===this.positions[v]&&this.positions[m+1]===this.positions[v+1]&&this.positions[m+2]===this.positions[v+2]}copyV3(t){const r=t*6;return[this.positions[r],this.positions[r+1],this.positions[r+2]]}process(){const t=this.positions.length/6;this.previous=[],this.next=[],this.side=[],this.width=[],this.indices_array=[],this.uvs=[];let r,m;this.compareV3(0,t-1)?m=this.copyV3(t-2):m=this.copyV3(0),this.previous.push(m[0],m[1],m[2]),this.previous.push(m[0],m[1],m[2]);for(let v=0;v<t;v++){if(this.side.push(1),this.side.push(-1),this.widthCallback?r=this.widthCallback(v/(t-1)):r=1,this.width.push(r),this.width.push(r),this.uvs.push(v/(t-1),0),this.uvs.push(v/(t-1),1),v<t-1){m=this.copyV3(v),this.previous.push(m[0],m[1],m[2]),this.previous.push(m[0],m[1],m[2]);const C=v*2;this.indices_array.push(C,C+1,C+2),this.indices_array.push(C+2,C+1,C+3)}v>0&&(m=this.copyV3(v),this.next.push(m[0],m[1],m[2]),this.next.push(m[0],m[1],m[2]))}this.compareV3(t-1,0)?m=this.copyV3(1):m=this.copyV3(t-1),this.next.push(m[0],m[1],m[2]),this.next.push(m[0],m[1],m[2]),!this._attributes||this._attributes.position.count!==this.counters.length?this._attributes={position:new BufferAttribute(new Float32Array(this.positions),3),previous:new BufferAttribute(new Float32Array(this.previous),3),next:new BufferAttribute(new Float32Array(this.next),3),side:new BufferAttribute(new Float32Array(this.side),1),width:new BufferAttribute(new Float32Array(this.width),1),uv:new BufferAttribute(new Float32Array(this.uvs),2),index:new BufferAttribute(new Uint16Array(this.indices_array),1),counters:new BufferAttribute(new Float32Array(this.counters),1)}:(this._attributes.position.copyArray(new Float32Array(this.positions)),this._attributes.position.needsUpdate=!0,this._attributes.previous.copyArray(new Float32Array(this.previous)),this._attributes.previous.needsUpdate=!0,this._attributes.next.copyArray(new Float32Array(this.next)),this._attributes.next.needsUpdate=!0,this._attributes.side.copyArray(new Float32Array(this.side)),this._attributes.side.needsUpdate=!0,this._attributes.width.copyArray(new Float32Array(this.width)),this._attributes.width.needsUpdate=!0,this._attributes.uv.copyArray(new Float32Array(this.uvs)),this._attributes.uv.needsUpdate=!0,this._attributes.index.copyArray(new Uint16Array(this.indices_array)),this._attributes.index.needsUpdate=!0),this.setAttribute("position",this._attributes.position),this.setAttribute("previous",this._attributes.previous),this.setAttribute("next",this._attributes.next),this.setAttribute("side",this._attributes.side),this.setAttribute("width",this._attributes.width),this.setAttribute("uv",this._attributes.uv),this.setAttribute("counters",this._attributes.counters),this.setAttribute("position",this._attributes.position),this.setAttribute("previous",this._attributes.previous),this.setAttribute("next",this._attributes.next),this.setAttribute("side",this._attributes.side),this.setAttribute("width",this._attributes.width),this.setAttribute("uv",this._attributes.uv),this.setAttribute("counters",this._attributes.counters),this.setIndex(this._attributes.index),this.computeBoundingSphere(),this.computeBoundingBox()}advance({x:t,y:r,z:m}){const v=this._attributes.position.array,C=this._attributes.previous.array,_=this._attributes.next.array,w=v.length;yt(v,0,C,0,w),yt(v,6,v,0,w-6),v[w-6]=t,v[w-5]=r,v[w-4]=m,v[w-3]=t,v[w-2]=r,v[w-1]=m,yt(v,6,_,0,w-6),_[w-6]=t,_[w-5]=r,_[w-4]=m,_[w-3]=t,_[w-2]=r,_[w-1]=m,this._attributes.position.needsUpdate=!0,this._attributes.previous.needsUpdate=!0,this._attributes.next.needsUpdate=!0}}const bt=g=>{const{setPointWidth:t,nodes:r}=g,m=new Be;return m.setPoints(r,t),m};class es extends ht{constructor(t={}){super(),this.options=G({},t)}get material(){var t;return(t=this.object3d)==null?void 0:t.material}create(){return nt(this,null,function*(){const{nodes:t,nodesArr:r,geometry:m,geometryArr:v,material:C,useGroups:_,setPointWidth:w,lineWidthArr:E,materialParameters:O}=this.options;let ve=C,Pe=m;!ve&&O&&(ve=this.getMaterial(O)),!Pe&&t?Pe=bt({nodes:t,setPointWidth:w}):!Pe&&r?Pe=R$1(r.map((Ne,Ae)=>{let Fe=w;return!Fe&&E&&(Fe=()=>{var ct;return(ct=E[Ae])!=null?ct:E[0]}),bt({nodes:Ne,setPointWidth:Fe})}),_!=null?_:0):!Pe&&v&&v.length>1?Pe=R$1(v,_!=null?_:0):!Pe&&v&&v.length===1&&([Pe]=v),this.createMesh(Pe,ve)})}setGeometry(t,r){const m=bt({nodes:t,setPointWidth:r}),v=this.object3d,C=v.geometry;v.geometry=m,C.dispose()}getMaterial(t){const{width:r,height:m}=this.pencil.getSize();return new Te$1(G({color:new Color$1("#ffffff"),resolution:new Vector2(r,m)},t))}addGeometries(t){const r=this.object3d,m=R$1([r.geometry,...t]);r.geometry=m}resize(t,r){var m,v;(v=(m=this.material)==null?void 0:m.uniforms)==null||v.resolution.value.set(t,r)}useMaterial(t){super.useMaterial(t);const{width:r,height:m}=this.pencil.getSize();this.resize(r,m)}animate({duration:t=1e3,delay:r=0,repeat:m=0,lineLoop:v,onRepeat:C,onUpdate:_,onComplete:w,startShow:E}={}){const{offset:O,offsetLoop:ve}=this.material.uniforms;if(this.material.userData.tween)return;const Pe=v!=null?v:!0;O.value.x=1,ve.value=Pe&&E?1:0;let Ne=0;const Ae=new Tween(O.value).to({x:-1},t).delay(r).repeat(m).onUpdate(({x:Fe})=>{Pe&&Fe<=0&&ve.value===0&&(ve.value=1),_&&_(Fe)}).onRepeat(()=>{Ne+=1,C&&C(Ne)}).onComplete(()=>{w&&w()}).start();this.material.userData.tween=Ae}render(){const{width:t,height:r}=this.pencil.getSize();this.resize(t,r)}dispose(){this.material.userData.tween&&(this.material.userData.tween.stop(),remove(this.material.userData.tween)),super.dispose()}}const Ot=g=>{const t=g,{coordinate:r,startHeight:m,height:v}=t,C=gt(t,["coordinate","startHeight","height"]);let _=m||0;return typeof m!="undefined"&&typeof v!="undefined"&&(_=m+v),new We$1([r],ut(G({},C),{startHeight:m,endHeight:_}))};class ss extends ht{constructor(t){super(),this.options=G({},t)}create(){const t=this.options,{geometry:r,coordinateArr:m,coordinate:v,material:C,useGroups:_}=t,w=gt(t,["geometry","coordinateArr","coordinate","material","useGroups"]);let E=r;if(!E&&v)E=Ot(G({coordinate:v},w));else if(!E&&m){const O=m.map(ve=>Ot(G({coordinate:ve},w)));E=R$1(O,_!=null?_:0)}this.createMesh(E,C)}}class ze extends Z{constructor(t,r){super(t,r);const m=new Brush(new Z(t,ut(G({},r),{hasTop:!0,hasSide:!0,hasBottom:!1})));m.updateMatrixWorld();const v=new Box3().setFromObject(m),C=new Vector3;v.getSize(C);const _=new Vector3(v.min.x+C.x/2,v.min.y+C.y/2,0);let w=r.topSegments,E=r.box3;if(E){E=E.union(v);const Oe=new Vector3;E.getSize(Oe);const ke=Math.max(C.x/Oe.x,C.y/Oe.y);w=Math.ceil(r.topSegments*ke)}if(w<4)return this;const O=new PlaneGeometry(C.x,C.y,w,w),ve=new Brush(O);ve.position.set(_.x,_.y,_.z),ve.updateMatrixWorld();const Pe=new Evaluator().evaluate(ve,m,INTERSECTION),Ne=Pe.geometry.getAttribute("position"),Ae=new Float32BufferAttribute(Ne.count*2,2);for(let Oe=0;Oe<Ne.count;Oe++){const ke=Ne.getZ(Oe);Ne.setZ(Oe,r.depth+ke)}if(E){const Oe=E.min,ke=E.max,je=new Vector3().subVectors(ke,Oe);for(let at=0;at<Ne.count;at++){const xt=Ne.getX(at),Gt=Ne.getY(at),Lt=(xt-Oe.x)/je.x,Wt=(Gt-Oe.y)/je.y;Ae.setXY(at,Lt,Wt)}Pe.geometry.setAttribute("uv",Ae)}Ne.needsUpdate=!0;const Fe=new Z(t,ut(G({},r),{hasTop:!1})),ct=R$1([Pe.geometry,Fe],2);this.copy(ct.toNonIndexed())}}const Ht=g=>{const{split:t,depth:r,points:m,box3:v,hasTop:C,hasBottom:_,hasSide:w,sideRepeat:E,topSegments:O}=g,ve=O?ze:Z,Pe=new ve(new Shape(m),{depth:r,bevelEnabled:!1,box3:v,UVGenerator:R$2({split:t,box3:v,sideRepeat:E}),hasTop:C,hasBottom:_,hasSide:w,topSegments:O});return P(),Pe};class is extends ht{constructor(t){super(),this.options=G({depth:1},t)}create(){return nt(this,null,function*(){const{points:t,pointsArr:r,useGroups:m,depth:v,geometry:C,geometryArr:_,material:w,box3:E,split:O,hasTop:ve,hasBottom:Pe,hasSide:Ne}=this.options,Ae=Array.isArray(v)?v:[v],Fe=Array.isArray(E)?E:[E],ct=w;let Oe=C;ct||console.log("material is null"),!Oe&&t?Oe=Ht({points:t,depth:Ae[0],box3:Fe[0],split:O,hasTop:ve,hasBottom:Pe,hasSide:Ne}):!Oe&&r?Oe=R$1(r.map((ke,je)=>{var at,xt;return Ht({points:ke,depth:(at=Ae[je])!=null?at:Ae[0],box3:(xt=Fe[je])!=null?xt:Fe[0],split:O,hasTop:ve,hasBottom:Pe,hasSide:Ne})}),m!=null?m:0):!Oe&&_&&_.length>1?Oe=R$1(_,m!=null?m:0):!Oe&&_&&_.length===1&&([Oe]=_),this.createMesh(Oe,ct)})}addGeometries(t){const r=this.object3d,m=R$1([r.geometry,...t]);r.geometry=m}setTextureAnisotropic(t,r){t.anisotropy=r||this.pencil.renderer.capabilities.getMaxAnisotropy()}}class Light extends Ze{update(t,r){var v;super.update(t,r);const m=this.object3d;(v=m.shadow)!=null&&v.camera&&(m.shadow.camera.near!==this.pencil.camera.near&&(m.shadow.camera.near=this.pencil.camera.near),m.shadow.camera.far!=this.pencil.camera.far&&(m.shadow.camera.far=this.pencil.camera.far))}render(){super.render();const t=this.object3d;t.userData=new Proxy({},{set:(w,E,O)=>(E==="keepCamera"&&(O?(this.pencil.render(),t.userData.parent=t.parent,this.pencil.camera.attach(t),t.target&&this.pencil.camera.attach(t.target)):!O&&t.userData.parent&&(this.pencil.render(),t.userData.parent.attach(t),t.target&&t.userData.parent.attach(t.target))),Reflect.set(w,E,O))});const{type:r,key:m}=this.options;m?(this.lead.updateBaseObjectKey(this,`${r}_${m}`),this.userData.updateKey=!1):this.lead.updateBaseObjectKey(this,`${r}`),t.target&&(t.target.userData.light=t);const v=this.object3d;v.isDirectionalLight&&(v.shadow.mapSize.width=1024,v.shadow.mapSize.height=1024);const C=this.object3d;C.isSpotLight&&C.shadow.mapSize.set(1024,1024);const _=this.object3d;_.isPointLight&&(_.shadow.mapSize.width=1024,_.shadow.mapSize.height=1024)}}class Point extends ht{constructor(r){super();L0(this,"options");L0(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 H0(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$2,equirectangular:s$1,winkel3:l},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*un(m,2):C=r/5*un(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,E=C*w;return t*g.renderer.getPixelRatio()/_.width/(1/E)};let map;class Arc extends ht{constructor(r){super();L0(this,"options");L0(this,"line");L0(this,"helperMesh");L0(this,"helperMeshPosition");L0(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 H0(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 E=v?createFlyPath(_,w,C):createFlyPath2(_,w,C),O=E.getPoints(1500),ve=this.pencil.lead,Pe=yield ve.draw("Line",{nodes:O,setPointWidth:Oe=>Oe*1,materialParameters:{color:r,map,useMap:1,transparent:!0,sizeAttenuation:0,lineWidth:m}},null);this.line=Pe,this.object3d=Pe.object3d;const[Ne,Ae,Fe,ct]=yield Promise.all([{key:"Arc_起点",position:E.v0},{key:"Arc_第一控制点",position:E.v1},{key:"Arc_第二控制点",position:E.v2},{key:"Arc_终点",position:E.v3}].map(je=>H0(this,[je],function*({key:Oe,position:ke}){const at=yield ve.draw("Group",{},this);return at.position.copy(ke),at.userData.disabledC=!0,at.userData.disabledR=!0,ve.updateBaseObjectKey(at,`${Oe}_${this.options.key}`),at})));this.helperMesh=[Ne,Ae,Fe,ct],this.helperMeshPosition=[Ne.position.clone(),Ae.position.clone(),Fe.position.clone(),ct.position.clone()]})}instantiate(){return H0(this,null,function*(){this.update();const r=yield this.line.instantiate({recursive:!1}),m=yield fn(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 E=(_?createFlyPath(r,m,v):createFlyPath2(r,m,v)).getPoints(1500);this.line.options.nodes=E,this.line.setGeometry(E,C),this.pickTube&&this.addPickTarget(this.pickTube.options.radius)}addPickTarget(r=1,m=!1){return H0(this,null,function*(){const v=this.pickTube,C=this.pencil.lead,_=this.line.options.nodes,w=new CurvePath;for(let ve=0;ve<_.length-1;ve++)w.add(new LineCurve3(_[ve],_[ve+1]));const E=yield C.draw("Tube",{path:w,radius:r,multiplyScalar:1},this),O=E.object3d;return O.material=new MeshBasicMaterial({color:16711680,transparent:!0,opacity:m?1:0}),v&&(v.userData._pe_&&E.onPointerEvent(...v.userData._pe_),v.erase()),this.pickTube=E,E})}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();L0(this,"options");this.options=Q0({},r)}create(){return H0(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 H0(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();L0(this,"options");this.options=Q0({},r)}create(){return H0(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);L0(this,"radius",100);L0(this,"material");L0(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),E=this.pencil.getSize().height*(1/(2*Math.tan(_/2))),O=t/E,{width:ve,height:Pe}=r.material.map.image;r.scale.set(ve/Pe*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();L0(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,Line:es,Line2:Ke,ExtrudePolygon:is,ConicPolygon:ss,Group:Qe,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(Bi(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,u=Object.getOwnPropertySymbols,Y=Object.prototype.hasOwnProperty,a=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={}))Y.call(t,r)&&s(g,r,t[r]);if(u)for(var r of u(t))a.call(t,r)&&s(g,r,t[r]);return g},x=(g,t)=>{var r={};for(var m in g)Y.call(g,m)&&t.indexOf(m)<0&&(r[m]=g[m]);if(g!=null&&u)for(var m of u(g))t.indexOf(m)<0&&a.call(g,m)&&(r[m]=g[m]);return r},V=(g,t,r)=>new Promise((m,v)=>{var C=E=>{try{w(r.next(E))}catch(O){v(O)}},_=E=>{try{w(r.throw(E))}catch(O){v(O)}},w=E=>E.done?m(E.value):Promise.resolve(E.value).then(C,_);w((r=r.apply(g,t)).next())});const o="dmFyIEJnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxGZz1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgSWc9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIFFyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIFp1PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksWHU9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgZ2M9KEosUSk9PihRPVN5bWJvbFtKXSk/UTpTeW1ib2wuZm9yKCJTeW1ib2wuIitKKSxrZz1KPT57dGhyb3cgVHlwZUVycm9yKEopfSx5aT1NYXRoLnBvdyxHdT0oSixRLG10KT0+USBpbiBKP0JnKEosUSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6bXR9KTpKW1FdPW10LEZ0PShKLFEpPT57Zm9yKHZhciBtdCBpbiBRfHwoUT17fSkpWnUuY2FsbChRLG10KSYmR3UoSixtdCxRW210XSk7aWYoUXIpZm9yKHZhciBtdCBvZiBRcihRKSlYdS5jYWxsKFEsbXQpJiZHdShKLG10LFFbbXRdKTtyZXR1cm4gSn0sWmU9KEosUSk9PkZnKEosSWcoUSkpO3ZhciBKdT0oSixRKT0+e3ZhciBtdD17fTtmb3IodmFyIE10IGluIEopWnUuY2FsbChKLE10KSYmUS5pbmRleE9mKE10KTwwJiYobXRbTXRdPUpbTXRdKTtpZihKIT1udWxsJiZRcilmb3IodmFyIE10IG9mIFFyKEopKVEuaW5kZXhPZihNdCk8MCYmWHUuY2FsbChKLE10KSYmKG10W010XT1KW010XSk7cmV0dXJuIG10fTt2YXIgTmc9ZnVuY3Rpb24oSixRKXt0aGlzWzBdPUosdGhpc1sxXT1RfTt2YXIgWXU9Sj0+e3ZhciBRPUpbZ2MoImFzeW5jSXRlcmF0b3IiKV0sbXQ9ITEsTXQsY249e307cmV0dXJuIFE9PW51bGw/KFE9SltnYygiaXRlcmF0b3IiKV0oKSxNdD1TZT0+Y25bU2VdPUJuPT5RW1NlXShCbikpOihRPVEuY2FsbChKKSxNdD1TZT0+Y25bU2VdPUJuPT57aWYobXQpe2lmKG10PSExLFNlPT09InRocm93Iil0aHJvdyBCbjtyZXR1cm4gQm59cmV0dXJuIG10PSEwLHtkb25lOiExLHZhbHVlOm5ldyBOZyhuZXcgUHJvbWlzZSh4Yz0+e3ZhciBLcj1RW1NlXShCbik7S3IgaW5zdGFuY2VvZiBPYmplY3R8fGtnKCJPYmplY3QgZXhwZWN0ZWQiKSx4YyhLcil9KSwxKX19KSxjbltnYygiaXRlcmF0b3IiKV09KCk9PmNuLE10KCJuZXh0IiksInRocm93ImluIFE/TXQoInRocm93Iik6Y24udGhyb3c9U2U9Pnt0aHJvdyBTZX0sInJldHVybiJpbiBRJiZNdCgicmV0dXJuIiksY259OyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTAtMjAyNSBUaHJlZS5qcyBBdXRob3JzCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKICovY29uc3QgSj0iMTc3Iix3Yz0iIixvZT0ic3JnYiIsYmM9InNyZ2ItbGluZWFyIixNYz0ibGluZWFyIix0bz0ic3JnYiI7Y2xhc3Mgb3N7YWRkRXZlbnRMaXN0ZW5lcih0LGUpe3RoaXMuX2xpc3RlbmVycz09PXZvaWQgMCYmKHRoaXMuX2xpc3RlbmVycz17fSk7Y29uc3Qgbj10aGlzLl9saXN0ZW5lcnM7blt0XT09PXZvaWQgMCYmKG5bdF09W10pLG5bdF0uaW5kZXhPZihlKT09PS0xJiZuW3RdLnB1c2goZSl9aGFzRXZlbnRMaXN0ZW5lcih0LGUpe2NvbnN0IG49dGhpcy5fbGlzdGVuZXJzO3JldHVybiBuPT09dm9pZCAwPyExOm5bdF0hPT12b2lkIDAmJm5bdF0uaW5kZXhPZihlKSE9PS0xfXJlbW92ZUV2ZW50TGlzdGVuZXIodCxlKXtjb25zdCBuPXRoaXMuX2xpc3RlbmVycztpZihuPT09dm9pZCAwKXJldHVybjtjb25zdCBzPW5bdF07aWYocyE9PXZvaWQgMCl7Y29uc3Qgcj1zLmluZGV4T2YoZSk7ciE9PS0xJiZzLnNwbGljZShyLDEpfX1kaXNwYXRjaEV2ZW50KHQpe2NvbnN0IGU9dGhpcy5fbGlzdGVuZXJzO2lmKGU9PT12b2lkIDApcmV0dXJuO2NvbnN0IG49ZVt0LnR5cGVdO2lmKG4hPT12b2lkIDApe3QudGFyZ2V0PXRoaXM7Y29uc3Qgcz1uLnNsaWNlKDApO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLmNhbGwodGhpcyx0KTt0LnRhcmdldD1udWxsfX19Y29uc3QgQXQ9WyIwMCIsIjAxIiwiMDIiLCIwMyIsIjA0IiwiMDUiLCIwNiIsIjA3IiwiMDgiLCIwOSIsIjBhIiwiMGIiLCIwYyIsIjBkIiwiMGUiLCIwZiIsIjEwIiwiMTEiLCIxMiIsIjEzIiwiMTQiLCIxNSIsIjE2IiwiMTciLCIxOCIsIjE5IiwiMWEiLCIxYiIsIjFjIiwiMWQiLCIxZSIsIjFmIiwiMjAiLCIyMSIsIjIyIiwiMjMiLCIyNCIsIjI1IiwiMjYiLCIyNyIsIjI4IiwiMjkiLCIyYSIsIjJiIiwiMmMiLCIyZCIsIjJlIiwiMmYiLCIzMCIsIjMxIiwiMzIiLCIzMyIsIjM0IiwiMzUiLCIzNiIsIjM3IiwiMzgiLCIzOSIsIjNhIiwiM2IiLCIzYyIsIjNkIiwiM2UiLCIzZiIsIjQwIiwiNDEiLCI0MiIsIjQzIiwiNDQiLCI0NSIsIjQ2IiwiNDciLCI0OCIsIjQ5IiwiNGEiLCI0YiIsIjRjIiwiNGQiLCI0ZSIsIjRmIiwiNTAiLCI1MSIsIjUyIiwiNTMiLCI1NCIsIjU1IiwiNTYiLCI1NyIsIjU4IiwiNTkiLCI1YSIsIjViIiwiNWMiLCI1ZCIsIjVlIiwiNWYiLCI2MCIsIjYxIiwiNjIiLCI2MyIsIjY0IiwiNjUiLCI2NiIsIjY3IiwiNjgiLCI2OSIsIjZhIiwiNmIiLCI2YyIsIjZkIiwiNmUiLCI2ZiIsIjcwIiwiNzEiLCI3MiIsIjczIiwiNzQiLCI3NSIsIjc2IiwiNzciLCI3OCIsIjc5IiwiN2EiLCI3YiIsIjdjIiwiN2QiLCI3ZSIsIjdmIiwiODAiLCI4MSIsIjgyIiwiODMiLCI4NCIsIjg1IiwiODYiLCI4NyIsIjg4IiwiODkiLCI4YSIsIjhiIiwiOGMiLCI4ZCIsIjhlIiwiOGYiLCI5MCIsIjkxIiwiOTIiLCI5MyIsIjk0IiwiOTUiLCI5NiIsIjk3IiwiOTgiLCI5OSIsIjlhIiwiOWIiLCI5YyIsIjlkIiwiOWUiLCI5ZiIsImEwIiwiYTEiLCJhMiIsImEzIiwiYTQiLCJhNSIsImE2IiwiYTciLCJhOCIsImE5IiwiYWEiLCJhYiIsImFjIiwiYWQiLCJhZSIsImFmIiwiYjAiLCJiMSIsImIyIiwiYjMiLCJiNCIsImI1IiwiYjYiLCJiNyIsImI4IiwiYjkiLCJiYSIsImJiIiwiYmMiLCJiZCIsImJlIiwiYmYiLCJjMCIsImMxIiwiYzIiLCJjMyIsImM0IiwiYzUiLCJjNiIsImM3IiwiYzgiLCJjOSIsImNhIiwiY2IiLCJjYyIsImNkIiwiY2UiLCJjZiIsImQwIiwiZDEiLCJkMiIsImQzIiwiZDQiLCJkNSIsImQ2IiwiZDciLCJkOCIsImQ5IiwiZGEiLCJkYiIsImRjIiwiZGQiLCJkZSIsImRmIiwiZTAiLCJlMSIsImUyIiwiZTMiLCJlNCIsImU1IiwiZTYiLCJlNyIsImU4IiwiZTkiLCJlYSIsImViIiwiZWMiLCJlZCIsImVlIiwiZWYiLCJmMCIsImYxIiwiZjIiLCJmMyIsImY0IiwiZjUiLCJmNiIsImY3IiwiZjgiLCJmOSIsImZhIiwiZmIiLCJmYyIsImZkIiwiZmUiLCJmZiJdO2Z1bmN0aW9uIEZuKCl7Y29uc3QgaT1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MCx0PU1hdGgucmFuZG9tKCkqNDI5NDk2NzI5NXwwLGU9TWF0aC5yYW5kb20oKSo0Mjk0OTY3Mjk1fDAsbj1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MDtyZXR1cm4oQXRbaSYyNTVdK0F0W2k+PjgmMjU1XStBdFtpPj4xNiYyNTVdK0F0W2k+PjI0JjI1NV0rIi0iK0F0W3QmMjU1XStBdFt0Pj44JjI1NV0rIi0iK0F0W3Q+PjE2JjE1fDY0XStBdFt0Pj4yNCYyNTVdKyItIitBdFtlJjYzfDEyOF0rQXRbZT4+OCYyNTVdKyItIitBdFtlPj4xNiYyNTVdK0F0W2U+PjI0JjI1NV0rQXRbbiYyNTVdK0F0W24+PjgmMjU1XStBdFtuPj4xNiYyNTVdK0F0W24+PjI0JjI1NV0pLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gWihpLHQsZSl7cmV0dXJuIE1hdGgubWF4KHQsTWF0aC5taW4oZSxpKSl9ZnVuY3Rpb24ganUoaSx0KXtyZXR1cm4oaSV0K3QpJXR9ZnVuY3Rpb24gZW8oaSx0LGUpe3JldHVybigxLWUpKmkrZSp0fWZ1bmN0aW9uIG1pKGksdCl7c3dpdGNoKHQuY29uc3RydWN0b3Ipe2Nhc2UgRmxvYXQzMkFycmF5OnJldHVybiBpO2Nhc2UgVWludDMyQXJyYXk6cmV0dXJuIGkvNDI5NDk2NzI5NTtjYXNlIFVpbnQxNkFycmF5OnJldHVybiBpLzY1NTM1O2Nhc2UgVWludDhBcnJheTpyZXR1cm4gaS8yNTU7Y2FzZSBJbnQzMkFycmF5OnJldHVybiBNYXRoLm1heChpLzIxNDc0ODM2NDcsLTEpO2Nhc2UgSW50MTZBcnJheTpyZXR1cm4gTWF0aC5tYXgoaS8zMjc2NywtMSk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgubWF4KGkvMTI3LC0xKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiSW52YWxpZCBjb21wb25lbnQgdHlwZS4iKX19ZnVuY3Rpb24gSXQoaSx0KXtzd2l0Y2godC5jb25zdHJ1Y3Rvcil7Y2FzZSBGbG9hdDMyQXJyYXk6cmV0dXJuIGk7Y2FzZSBVaW50MzJBcnJheTpyZXR1cm4gTWF0aC5yb3VuZChpKjQyOTQ5NjcyOTUpO2Nhc2UgVWludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSo2NTUzNSk7Y2FzZSBVaW50OEFycmF5OnJldHVybiBNYXRoLnJvdW5kKGkqMjU1KTtjYXNlIEludDMyQXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoyMTQ3NDgzNjQ3KTtjYXNlIEludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSozMjc2Nyk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoxMjcpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGNvbXBvbmVudCB0eXBlLiIpfX1jbGFzcyBSe2NvbnN0cnVjdG9yKHQ9MCxlPTApe1IucHJvdG90eXBlLmlzVmVjdG9yMj0hMCx0aGlzLng9dCx0aGlzLnk9ZX1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy54fXNldCB3aWR0aCh0KXt0aGlzLng9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMueX1zZXQgaGVpZ2h0KHQpe3RoaXMueT10fXNldCh0LGUpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Q29tcG9uZW50KHQsZSl7c3dpdGNoKHQpe2Nhc2UgMDp0aGlzLng9ZTticmVhaztjYXNlIDE6dGhpcy55PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnkpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PXNbMF0qZStzWzNdKm4rc1s2XSx0aGlzLnk9c1sxXSplK3NbNF0qbitzWzddLHRoaXN9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueX1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSl9bWFuaGF0dGFuTGVuZ3RoKCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueCkrTWF0aC5hYnModGhpcy55KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9YW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMigtdGhpcy55LC10aGlzLngpK01hdGguUEl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnk7cmV0dXJuIGUqZStuKm59bWFuaGF0dGFuRGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5hYnModGhpcy54LXQueCkrTWF0aC5hYnModGhpcy55LXQueSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXN9cm90YXRlQXJvdW5kKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9dGhpcy54LXQueCxvPXRoaXMueS10Lnk7cmV0dXJuIHRoaXMueD1yKm4tbypzK3QueCx0aGlzLnk9cipzK28qbit0LnksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55fX1jbGFzcyBnaXtjb25zdHJ1Y3Rvcih0PTAsZT0wLG49MCxzPTEpe3RoaXMuaXNRdWF0ZXJuaW9uPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9c31zdGF0aWMgc2xlcnBGbGF0KHQsZSxuLHMscixvLGEpe2xldCBjPW5bcyswXSxsPW5bcysxXSxoPW5bcysyXSx1PW5bcyszXTtjb25zdCBmPXJbbyswXSxkPXJbbysxXSxwPXJbbysyXSx5PXJbbyszXTtpZihhPT09MCl7dFtlKzBdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXU7cmV0dXJufWlmKGE9PT0xKXt0W2UrMF09Zix0W2UrMV09ZCx0W2UrMl09cCx0W2UrM109eTtyZXR1cm59aWYodSE9PXl8fGMhPT1mfHxsIT09ZHx8aCE9PXApe2xldCBtPTEtYTtjb25zdCBnPWMqZitsKmQraCpwK3UqeSxiPWc+PTA/MTotMSx3PTEtZypnO2lmKHc+TnVtYmVyLkVQU0lMT04pe2NvbnN0IE09TWF0aC5zcXJ0KHcpLEE9TWF0aC5hdGFuMihNLGcqYik7bT1NYXRoLnNpbihtKkEpL00sYT1NYXRoLnNpbihhKkEpL019Y29uc3QgeD1hKmI7aWYoYz1jKm0rZip4LGw9bCptK2QqeCxoPWgqbStwKngsdT11Km0reSp4LG09PT0xLWEpe2NvbnN0IE09MS9NYXRoLnNxcnQoYypjK2wqbCtoKmgrdSp1KTtjKj1NLGwqPU0saCo9TSx1Kj1NfX10W2VdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXV9c3RhdGljIG11bHRpcGx5UXVhdGVybmlvbnNGbGF0KHQsZSxuLHMscixvKXtjb25zdCBhPW5bc10sYz1uW3MrMV0sbD1uW3MrMl0saD1uW3MrM10sdT1yW29dLGY9cltvKzFdLGQ9cltvKzJdLHA9cltvKzNdO3JldHVybiB0W2VdPWEqcCtoKnUrYypkLWwqZix0W2UrMV09YypwK2gqZitsKnUtYSpkLHRbZSsyXT1sKnAraCpkK2EqZi1jKnUsdFtlKzNdPWgqcC1hKnUtYypmLWwqZCx0fWdldCB4KCl7cmV0dXJuIHRoaXMuX3h9c2V0IHgodCl7dGhpcy5feD10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeSgpe3JldHVybiB0aGlzLl95fXNldCB5KHQpe3RoaXMuX3k9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHooKXtyZXR1cm4gdGhpcy5fen1zZXQgeih0KXt0aGlzLl96PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB3KCl7cmV0dXJuIHRoaXMuX3d9c2V0IHcodCl7dGhpcy5fdz10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scyl7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9cyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl94LHRoaXMuX3ksdGhpcy5feix0aGlzLl93KX1jb3B5KHQpe3JldHVybiB0aGlzLl94PXQueCx0aGlzLl95PXQueSx0aGlzLl96PXQueix0aGlzLl93PXQudyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zZXRGcm9tRXVsZXIodCxlPSEwKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX29yZGVyLGE9TWF0aC5jb3MsYz1NYXRoLnNpbixsPWEobi8yKSxoPWEocy8yKSx1PWEoci8yKSxmPWMobi8yKSxkPWMocy8yKSxwPWMoci8yKTtzd2l0Y2gobyl7Y2FzZSJYWVoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJZWFoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJaWFkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJZWlgiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJYWlkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLlF1YXRlcm5pb246IC5zZXRGcm9tRXVsZXIoKSBlbmNvdW50ZXJlZCBhbiB1bmtub3duIG9yZGVyOiAiK28pfXJldHVybiBlPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21BeGlzQW5nbGUodCxlKXtjb25zdCBuPWUvMixzPU1hdGguc2luKG4pO3JldHVybiB0aGlzLl94PXQueCpzLHRoaXMuX3k9dC55KnMsdGhpcy5fej10Lnoqcyx0aGlzLl93PU1hdGguY29zKG4pLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0KXtjb25zdCBlPXQuZWxlbWVudHMsbj1lWzBdLHM9ZVs0XSxyPWVbOF0sbz1lWzFdLGE9ZVs1XSxjPWVbOV0sbD1lWzJdLGg9ZVs2XSx1PWVbMTBdLGY9bithK3U7aWYoZj4wKXtjb25zdCBkPS41L01hdGguc3FydChmKzEpO3RoaXMuX3c9LjI1L2QsdGhpcy5feD0oaC1jKSpkLHRoaXMuX3k9KHItbCkqZCx0aGlzLl96PShvLXMpKmR9ZWxzZSBpZihuPmEmJm4+dSl7Y29uc3QgZD0yKk1hdGguc3FydCgxK24tYS11KTt0aGlzLl93PShoLWMpL2QsdGhpcy5feD0uMjUqZCx0aGlzLl95PShzK28pL2QsdGhpcy5fej0ocitsKS9kfWVsc2UgaWYoYT51KXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErYS1uLXUpO3RoaXMuX3c9KHItbCkvZCx0aGlzLl94PShzK28pL2QsdGhpcy5feT0uMjUqZCx0aGlzLl96PShjK2gpL2R9ZWxzZXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErdS1uLWEpO3RoaXMuX3c9KG8tcykvZCx0aGlzLl94PShyK2wpL2QsdGhpcy5feT0oYytoKS9kLHRoaXMuX3o9LjI1KmR9cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Vbml0VmVjdG9ycyh0LGUpe2xldCBuPXQuZG90KGUpKzE7cmV0dXJuIG48TnVtYmVyLkVQU0lMT04/KG49MCxNYXRoLmFicyh0LngpPk1hdGguYWJzKHQueik/KHRoaXMuX3g9LXQueSx0aGlzLl95PXQueCx0aGlzLl96PTAsdGhpcy5fdz1uKToodGhpcy5feD0wLHRoaXMuX3k9LXQueix0aGlzLl96PXQueSx0aGlzLl93PW4pKToodGhpcy5feD10LnkqZS56LXQueiplLnksdGhpcy5feT10LnoqZS54LXQueCplLnosdGhpcy5fej10LngqZS55LXQueSplLngsdGhpcy5fdz1uKSx0aGlzLm5vcm1hbGl6ZSgpfWFuZ2xlVG8odCl7cmV0dXJuIDIqTWF0aC5hY29zKE1hdGguYWJzKFoodGhpcy5kb3QodCksLTEsMSkpKX1yb3RhdGVUb3dhcmRzKHQsZSl7Y29uc3Qgbj10aGlzLmFuZ2xlVG8odCk7aWYobj09PTApcmV0dXJuIHRoaXM7Y29uc3Qgcz1NYXRoLm1pbigxLGUvbik7cmV0dXJuIHRoaXMuc2xlcnAodCxzKSx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDAsMCwwLDEpfWludmVydCgpe3JldHVybiB0aGlzLmNvbmp1Z2F0ZSgpfWNvbmp1Z2F0ZSgpe3JldHVybiB0aGlzLl94Kj0tMSx0aGlzLl95Kj0tMSx0aGlzLl96Kj0tMSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMuX3gqdC5feCt0aGlzLl95KnQuX3krdGhpcy5feip0Ll96K3RoaXMuX3cqdC5fd31sZW5ndGhTcSgpe3JldHVybiB0aGlzLl94KnRoaXMuX3grdGhpcy5feSp0aGlzLl95K3RoaXMuX3oqdGhpcy5feit0aGlzLl93KnRoaXMuX3d9bGVuZ3RoKCl7cmV0dXJuIE1hdGguc3FydCh0aGlzLl94KnRoaXMuX3grdGhpcy5feSp0aGlzLl95K3RoaXMuX3oqdGhpcy5feit0aGlzLl93KnRoaXMuX3cpfW5vcm1hbGl6ZSgpe2xldCB0PXRoaXMubGVuZ3RoKCk7cmV0dXJuIHQ9PT0wPyh0aGlzLl94PTAsdGhpcy5feT0wLHRoaXMuX3o9MCx0aGlzLl93PTEpOih0PTEvdCx0aGlzLl94PXRoaXMuX3gqdCx0aGlzLl95PXRoaXMuX3kqdCx0aGlzLl96PXRoaXMuX3oqdCx0aGlzLl93PXRoaXMuX3cqdCksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlRdWF0ZXJuaW9ucyh0aGlzLHQpfXByZW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5UXVhdGVybmlvbnModCx0aGlzKX1tdWx0aXBseVF1YXRlcm5pb25zKHQsZSl7Y29uc3Qgbj10Ll94LHM9dC5feSxyPXQuX3osbz10Ll93LGE9ZS5feCxjPWUuX3ksbD1lLl96LGg9ZS5fdztyZXR1cm4gdGhpcy5feD1uKmgrbyphK3MqbC1yKmMsdGhpcy5feT1zKmgrbypjK3IqYS1uKmwsdGhpcy5fej1yKmgrbypsK24qYy1zKmEsdGhpcy5fdz1vKmgtbiphLXMqYy1yKmwsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2xlcnAodCxlKXtpZihlPT09MClyZXR1cm4gdGhpcztpZihlPT09MSlyZXR1cm4gdGhpcy5jb3B5KHQpO2NvbnN0IG49dGhpcy5feCxzPXRoaXMuX3kscj10aGlzLl96LG89dGhpcy5fdztsZXQgYT1vKnQuX3crbip0Ll94K3MqdC5feStyKnQuX3o7aWYoYTwwPyh0aGlzLl93PS10Ll93LHRoaXMuX3g9LXQuX3gsdGhpcy5feT0tdC5feSx0aGlzLl96PS10Ll96LGE9LWEpOnRoaXMuY29weSh0KSxhPj0xKXJldHVybiB0aGlzLl93PW8sdGhpcy5feD1uLHRoaXMuX3k9cyx0aGlzLl96PXIsdGhpcztjb25zdCBjPTEtYSphO2lmKGM8PU51bWJlci5FUFNJTE9OKXtjb25zdCBkPTEtZTtyZXR1cm4gdGhpcy5fdz1kKm8rZSp0aGlzLl93LHRoaXMuX3g9ZCpuK2UqdGhpcy5feCx0aGlzLl95PWQqcytlKnRoaXMuX3ksdGhpcy5fej1kKnIrZSp0aGlzLl96LHRoaXMubm9ybWFsaXplKCksdGhpc31jb25zdCBsPU1hdGguc3FydChjKSxoPU1hdGguYXRhbjIobCxhKSx1PU1hdGguc2luKCgxLWUpKmgpL2wsZj1NYXRoLnNpbihlKmgpL2w7cmV0dXJuIHRoaXMuX3c9byp1K3RoaXMuX3cqZix0aGlzLl94PW4qdSt0aGlzLl94KmYsdGhpcy5feT1zKnUrdGhpcy5feSpmLHRoaXMuX3o9cip1K3RoaXMuX3oqZix0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zbGVycFF1YXRlcm5pb25zKHQsZSxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLnNsZXJwKGUsbil9cmFuZG9tKCl7Y29uc3QgdD0yKk1hdGguUEkqTWF0aC5yYW5kb20oKSxlPTIqTWF0aC5QSSpNYXRoLnJhbmRvbSgpLG49TWF0aC5yYW5kb20oKSxzPU1hdGguc3FydCgxLW4pLHI9TWF0aC5zcXJ0KG4pO3JldHVybiB0aGlzLnNldChzKk1hdGguc2luKHQpLHMqTWF0aC5jb3ModCkscipNYXRoLnNpbihlKSxyKk1hdGguY29zKGUpKX1lcXVhbHModCl7cmV0dXJuIHQuX3g9PT10aGlzLl94JiZ0Ll95PT09dGhpcy5feSYmdC5fej09PXRoaXMuX3omJnQuX3c9PT10aGlzLl93fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMuX3g9dFtlXSx0aGlzLl95PXRbZSsxXSx0aGlzLl96PXRbZSsyXSx0aGlzLl93PXRbZSszXSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLl94LHRbZSsxXT10aGlzLl95LHRbZSsyXT10aGlzLl96LHRbZSszXT10aGlzLl93LHR9ZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLl94PXQuZ2V0WChlKSx0aGlzLl95PXQuZ2V0WShlKSx0aGlzLl96PXQuZ2V0WihlKSx0aGlzLl93PXQuZ2V0VyhlKSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc310b0pTT04oKXtyZXR1cm4gdGhpcy50b0FycmF5KCl9X29uQ2hhbmdlKHQpe3JldHVybiB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrPXQsdGhpc31fb25DaGFuZ2VDYWxsYmFjaygpe30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLl94LHlpZWxkIHRoaXMuX3kseWllbGQgdGhpcy5feix5aWVsZCB0aGlzLl93fX1jbGFzcyBUe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wKXtULnByb3RvdHlwZS5pc1ZlY3RvcjM9ITAsdGhpcy54PXQsdGhpcy55PWUsdGhpcy56PW59c2V0KHQsZSxuKXtyZXR1cm4gbj09PXZvaWQgMCYmKG49dGhpcy56KSx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpcy56PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Wih0KXtyZXR1cm4gdGhpcy56PXQsdGhpc31zZXRDb21wb25lbnQodCxlKXtzd2l0Y2godCl7Y2FzZSAwOnRoaXMueD1lO2JyZWFrO2Nhc2UgMTp0aGlzLnk9ZTticmVhaztjYXNlIDI6dGhpcy56PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2Nhc2UgMjpyZXR1cm4gdGhpcy56O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnksdGhpcy56KX1jb3B5KHQpe3JldHVybiB0aGlzLng9dC54LHRoaXMueT10LnksdGhpcy56PXQueix0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpcy56Kz10LnosdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpcy56Kz10LHRoaXN9YWRkVmVjdG9ycyh0LGUpe3JldHVybiB0aGlzLng9dC54K2UueCx0aGlzLnk9dC55K2UueSx0aGlzLno9dC56K2Uueix0aGlzfWFkZFNjYWxlZFZlY3Rvcih0LGUpe3JldHVybiB0aGlzLngrPXQueCplLHRoaXMueSs9dC55KmUsdGhpcy56Kz10LnoqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpcy56LT10LnosdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpcy56LT10LHRoaXN9c3ViVmVjdG9ycyh0LGUpe3JldHVybiB0aGlzLng9dC54LWUueCx0aGlzLnk9dC55LWUueSx0aGlzLno9dC56LWUueix0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLngqPXQueCx0aGlzLnkqPXQueSx0aGlzLnoqPXQueix0aGlzfW11bHRpcGx5U2NhbGFyKHQpe3JldHVybiB0aGlzLngqPXQsdGhpcy55Kj10LHRoaXMueio9dCx0aGlzfW11bHRpcGx5VmVjdG9ycyh0LGUpe3JldHVybiB0aGlzLng9dC54KmUueCx0aGlzLnk9dC55KmUueSx0aGlzLno9dC56KmUueix0aGlzfWFwcGx5RXVsZXIodCl7cmV0dXJuIHRoaXMuYXBwbHlRdWF0ZXJuaW9uKEFjLnNldEZyb21FdWxlcih0KSl9YXBwbHlBeGlzQW5nbGUodCxlKXtyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oQWMuc2V0RnJvbUF4aXNBbmdsZSh0LGUpKX1hcHBseU1hdHJpeDModCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9clswXSplK3JbM10qbityWzZdKnMsdGhpcy55PXJbMV0qZStyWzRdKm4rcls3XSpzLHRoaXMuej1yWzJdKmUrcls1XSpuK3JbOF0qcyx0aGlzfWFwcGx5Tm9ybWFsTWF0cml4KHQpe3JldHVybiB0aGlzLmFwcGx5TWF0cml4Myh0KS5ub3JtYWxpemUoKX1hcHBseU1hdHJpeDQodCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10LmVsZW1lbnRzLG89MS8oclszXSplK3JbN10qbityWzExXSpzK3JbMTVdKTtyZXR1cm4gdGhpcy54PShyWzBdKmUrcls0XSpuK3JbOF0qcytyWzEyXSkqbyx0aGlzLnk9KHJbMV0qZStyWzVdKm4rcls5XSpzK3JbMTNdKSpvLHRoaXMuej0oclsyXSplK3JbNl0qbityWzEwXSpzK3JbMTRdKSpvLHRoaXN9YXBwbHlRdWF0ZXJuaW9uKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dGhpcy56LHI9dC54LG89dC55LGE9dC56LGM9dC53LGw9MioobypzLWEqbiksaD0yKihhKmUtcipzKSx1PTIqKHIqbi1vKmUpO3JldHVybiB0aGlzLng9ZStjKmwrbyp1LWEqaCx0aGlzLnk9bitjKmgrYSpsLXIqdSx0aGlzLno9cytjKnUrcipoLW8qbCx0aGlzfXByb2plY3QodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGRJbnZlcnNlKS5hcHBseU1hdHJpeDQodC5wcm9qZWN0aW9uTWF0cml4KX11bnByb2plY3QodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXg0KHQucHJvamVjdGlvbk1hdHJpeEludmVyc2UpLmFwcGx5TWF0cml4NCh0Lm1hdHJpeFdvcmxkKX10cmFuc2Zvcm1EaXJlY3Rpb24odCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9clswXSplK3JbNF0qbityWzhdKnMsdGhpcy55PXJbMV0qZStyWzVdKm4rcls5XSpzLHRoaXMuej1yWzJdKmUrcls2XSpuK3JbMTBdKnMsdGhpcy5ub3JtYWxpemUoKX1kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXMuei89dC56LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1pbih0aGlzLnosdC56KSx0aGlzfW1heCh0KXtyZXR1cm4gdGhpcy54PU1hdGgubWF4KHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1heCh0aGlzLnksdC55KSx0aGlzLno9TWF0aC5tYXgodGhpcy56LHQueiksdGhpc31jbGFtcCh0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdC54LGUueCksdGhpcy55PVoodGhpcy55LHQueSxlLnkpLHRoaXMuej1aKHRoaXMueix0LnosZS56KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXMuej1aKHRoaXMueix0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpcy56PU1hdGguZmxvb3IodGhpcy56KSx0aGlzfWNlaWwoKXtyZXR1cm4gdGhpcy54PU1hdGguY2VpbCh0aGlzLngpLHRoaXMueT1NYXRoLmNlaWwodGhpcy55KSx0aGlzLno9TWF0aC5jZWlsKHRoaXMueiksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpcy56PU1hdGgucm91bmQodGhpcy56KSx0aGlzfXJvdW5kVG9aZXJvKCl7cmV0dXJuIHRoaXMueD1NYXRoLnRydW5jKHRoaXMueCksdGhpcy55PU1hdGgudHJ1bmModGhpcy55KSx0aGlzLno9TWF0aC50cnVuYyh0aGlzLnopLHRoaXN9bmVnYXRlKCl7cmV0dXJuIHRoaXMueD0tdGhpcy54LHRoaXMueT0tdGhpcy55LHRoaXMuej0tdGhpcy56LHRoaXN9ZG90KHQpe3JldHVybiB0aGlzLngqdC54K3RoaXMueSp0LnkrdGhpcy56KnQuen1sZW5ndGhTcSgpe3JldHVybiB0aGlzLngqdGhpcy54K3RoaXMueSp0aGlzLnkrdGhpcy56KnRoaXMuen1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56KX1tYW5oYXR0YW5MZW5ndGgoKXtyZXR1cm4gTWF0aC5hYnModGhpcy54KStNYXRoLmFicyh0aGlzLnkpK01hdGguYWJzKHRoaXMueil9bm9ybWFsaXplKCl7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKHRoaXMubGVuZ3RoKCl8fDEpfXNldExlbmd0aCh0KXtyZXR1cm4gdGhpcy5ub3JtYWxpemUoKS5tdWx0aXBseVNjYWxhcih0KX1sZXJwKHQsZSl7cmV0dXJuIHRoaXMueCs9KHQueC10aGlzLngpKmUsdGhpcy55Kz0odC55LXRoaXMueSkqZSx0aGlzLnorPSh0LnotdGhpcy56KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpcy56PXQueisoZS56LXQueikqbix0aGlzfWNyb3NzKHQpe3JldHVybiB0aGlzLmNyb3NzVmVjdG9ycyh0aGlzLHQpfWNyb3NzVmVjdG9ycyh0LGUpe2NvbnN0IG49dC54LHM9dC55LHI9dC56LG89ZS54LGE9ZS55LGM9ZS56O3JldHVybiB0aGlzLng9cypjLXIqYSx0aGlzLnk9cipvLW4qYyx0aGlzLno9biphLXMqbyx0aGlzfXByb2plY3RPblZlY3Rvcih0KXtjb25zdCBlPXQubGVuZ3RoU3EoKTtpZihlPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDApO2NvbnN0IG49dC5kb3QodGhpcykvZTtyZXR1cm4gdGhpcy5jb3B5KHQpLm11bHRpcGx5U2NhbGFyKG4pfXByb2plY3RPblBsYW5lKHQpe3JldHVybiBuby5jb3B5KHRoaXMpLnByb2plY3RPblZlY3Rvcih0KSx0aGlzLnN1Yihubyl9cmVmbGVjdCh0KXtyZXR1cm4gdGhpcy5zdWIobm8uY29weSh0KS5tdWx0aXBseVNjYWxhcigyKnRoaXMuZG90KHQpKSl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnkscz10aGlzLnotdC56O3JldHVybiBlKmUrbipuK3Mqc31tYW5oYXR0YW5EaXN0YW5jZVRvKHQpe3JldHVybiBNYXRoLmFicyh0aGlzLngtdC54KStNYXRoLmFicyh0aGlzLnktdC55KStNYXRoLmFicyh0aGlzLnotdC56KX1zZXRGcm9tU3BoZXJpY2FsKHQpe3JldHVybiB0aGlzLnNldEZyb21TcGhlcmljYWxDb29yZHModC5yYWRpdXMsdC5waGksdC50aGV0YSl9c2V0RnJvbVNwaGVyaWNhbENvb3Jkcyh0LGUsbil7Y29uc3Qgcz1NYXRoLnNpbihlKSp0O3JldHVybiB0aGlzLng9cypNYXRoLnNpbihuKSx0aGlzLnk9TWF0aC5jb3MoZSkqdCx0aGlzLno9cypNYXRoLmNvcyhuKSx0aGlzfXNldEZyb21DeWxpbmRyaWNhbCh0KXtyZXR1cm4gdGhpcy5zZXRGcm9tQ3lsaW5kcmljYWxDb29yZHModC5yYWRpdXMsdC50aGV0YSx0LnkpfXNldEZyb21DeWxpbmRyaWNhbENvb3Jkcyh0LGUsbil7cmV0dXJuIHRoaXMueD10Kk1hdGguc2luKGUpLHRoaXMueT1uLHRoaXMuej10Kk1hdGguY29zKGUpLHRoaXN9c2V0RnJvbU1hdHJpeFBvc2l0aW9uKHQpe2NvbnN0IGU9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PWVbMTJdLHRoaXMueT1lWzEzXSx0aGlzLno9ZVsxNF0sdGhpc31zZXRGcm9tTWF0cml4U2NhbGUodCl7Y29uc3QgZT10aGlzLnNldEZyb21NYXRyaXhDb2x1bW4odCwwKS5sZW5ndGgoKSxuPXRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbih0LDEpLmxlbmd0aCgpLHM9dGhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMikubGVuZ3RoKCk7cmV0dXJuIHRoaXMueD1lLHRoaXMueT1uLHRoaXMuej1zLHRoaXN9c2V0RnJvbU1hdHJpeENvbHVtbih0LGUpe3JldHVybiB0aGlzLmZyb21BcnJheSh0LmVsZW1lbnRzLGUqNCl9c2V0RnJvbU1hdHJpeDNDb2x1bW4odCxlKXtyZXR1cm4gdGhpcy5mcm9tQXJyYXkodC5lbGVtZW50cyxlKjMpfXNldEZyb21FdWxlcih0KXtyZXR1cm4gdGhpcy54PXQuX3gsdGhpcy55PXQuX3ksdGhpcy56PXQuX3osdGhpc31zZXRGcm9tQ29sb3IodCl7cmV0dXJuIHRoaXMueD10LnIsdGhpcy55PXQuZyx0aGlzLno9dC5iLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lng9PT10aGlzLngmJnQueT09PXRoaXMueSYmdC56PT09dGhpcy56fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpcy56PXRbZSsyXSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMueCx0W2UrMV09dGhpcy55LHRbZSsyXT10aGlzLnosdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMueD10LmdldFgoZSksdGhpcy55PXQuZ2V0WShlKSx0aGlzLno9dC5nZXRaKGUpLHRoaXN9cmFuZG9tKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJhbmRvbSgpLHRoaXMueT1NYXRoLnJhbmRvbSgpLHRoaXMuej1NYXRoLnJhbmRvbSgpLHRoaXN9cmFuZG9tRGlyZWN0aW9uKCl7Y29uc3QgdD1NYXRoLnJhbmRvbSgpKk1hdGguUEkqMixlPU1hdGgucmFuZG9tKCkqMi0xLG49TWF0aC5zcXJ0KDEtZSplKTtyZXR1cm4gdGhpcy54PW4qTWF0aC5jb3ModCksdGhpcy55PWUsdGhpcy56PW4qTWF0aC5zaW4odCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55LHlpZWxkIHRoaXMuen19Y29uc3Qgbm89bmV3IFQsQWM9bmV3IGdpO2NsYXNzIGdle2NvbnN0cnVjdG9yKHQsZSxuLHMscixvLGEsYyxsKXtnZS5wcm90b3R5cGUuaXNNYXRyaXgzPSEwLHRoaXMuZWxlbWVudHM9WzEsMCwwLDAsMSwwLDAsMCwxXSx0IT09dm9pZCAwJiZ0aGlzLnNldCh0LGUsbixzLHIsbyxhLGMsbCl9c2V0KHQsZSxuLHMscixvLGEsYyxsKXtjb25zdCBoPXRoaXMuZWxlbWVudHM7cmV0dXJuIGhbMF09dCxoWzFdPXMsaFsyXT1hLGhbM109ZSxoWzRdPXIsaFs1XT1jLGhbNl09bixoWzddPW8saFs4XT1sLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwxLDAsMCwwLDEpLHRoaXN9Y29weSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzO3JldHVybiBlWzBdPW5bMF0sZVsxXT1uWzFdLGVbMl09blsyXSxlWzNdPW5bM10sZVs0XT1uWzRdLGVbNV09bls1XSxlWzZdPW5bNl0sZVs3XT1uWzddLGVbOF09bls4XSx0aGlzfWV4dHJhY3RCYXNpcyh0LGUsbil7cmV0dXJuIHQuc2V0RnJvbU1hdHJpeDNDb2x1bW4odGhpcywwKSxlLnNldEZyb21NYXRyaXgzQ29sdW1uKHRoaXMsMSksbi5zZXRGcm9tTWF0cml4M0NvbHVtbih0aGlzLDIpLHRoaXN9c2V0RnJvbU1hdHJpeDQodCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLnNldChlWzBdLGVbNF0sZVs4XSxlWzFdLGVbNV0sZVs5XSxlWzJdLGVbNl0sZVsxMF0pLHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0aGlzLHQpfXByZW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXModCx0aGlzKX1tdWx0aXBseU1hdHJpY2VzKHQsZSl7Y29uc3Qgbj10LmVsZW1lbnRzLHM9ZS5lbGVtZW50cyxyPXRoaXMuZWxlbWVudHMsbz1uWzBdLGE9blszXSxjPW5bNl0sbD1uWzFdLGg9bls0XSx1PW5bN10sZj1uWzJdLGQ9bls1XSxwPW5bOF0seT1zWzBdLG09c1szXSxnPXNbNl0sYj1zWzFdLHc9c1s0XSx4PXNbN10sTT1zWzJdLEE9c1s1XSxTPXNbOF07cmV0dXJuIHJbMF09byp5K2EqYitjKk0sclszXT1vKm0rYSp3K2MqQSxyWzZdPW8qZythKngrYypTLHJbMV09bCp5K2gqYit1Kk0scls0XT1sKm0raCp3K3UqQSxyWzddPWwqZytoKngrdSpTLHJbMl09Zip5K2QqYitwKk0scls1XT1mKm0rZCp3K3AqQSxyWzhdPWYqZytkKngrcCpTLHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiBlWzBdKj10LGVbM10qPXQsZVs2XSo9dCxlWzFdKj10LGVbNF0qPXQsZVs3XSo9dCxlWzJdKj10LGVbNV0qPXQsZVs4XSo9dCx0aGlzfWRldGVybWluYW50KCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzLGU9dFswXSxuPXRbMV0scz10WzJdLHI9dFszXSxvPXRbNF0sYT10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdO3JldHVybiBlKm8qaC1lKmEqbC1uKnIqaCtuKmEqYytzKnIqbC1zKm8qY31pbnZlcnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFsxXSxzPXRbMl0scj10WzNdLG89dFs0XSxhPXRbNV0sYz10WzZdLGw9dFs3XSxoPXRbOF0sdT1oKm8tYSpsLGY9YSpjLWgqcixkPWwqci1vKmMscD1lKnUrbipmK3MqZDtpZihwPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMCwwLDAsMCwwLDApO2NvbnN0IHk9MS9wO3JldHVybiB0WzBdPXUqeSx0WzFdPShzKmwtaCpuKSp5LHRbMl09KGEqbi1zKm8pKnksdFszXT1mKnksdFs0XT0oaCplLXMqYykqeSx0WzVdPShzKnItYSplKSp5LHRbNl09ZCp5LHRbN109KG4qYy1sKmUpKnksdFs4XT0obyplLW4qcikqeSx0aGlzfXRyYW5zcG9zZSgpe2xldCB0O2NvbnN0IGU9dGhpcy5lbGVtZW50cztyZXR1cm4gdD1lWzFdLGVbMV09ZVszXSxlWzNdPXQsdD1lWzJdLGVbMl09ZVs2XSxlWzZdPXQsdD1lWzVdLGVbNV09ZVs3XSxlWzddPXQsdGhpc31nZXROb3JtYWxNYXRyaXgodCl7cmV0dXJuIHRoaXMuc2V0RnJvbU1hdHJpeDQodCkuaW52ZXJ0KCkudHJhbnNwb3NlKCl9dHJhbnNwb3NlSW50b0FycmF5KHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cztyZXR1cm4gdFswXT1lWzBdLHRbMV09ZVszXSx0WzJdPWVbNl0sdFszXT1lWzFdLHRbNF09ZVs0XSx0WzVdPWVbN10sdFs2XT1lWzJdLHRbN109ZVs1XSx0WzhdPWVbOF0sdGhpc31zZXRVdlRyYW5zZm9ybSh0LGUsbixzLHIsbyxhKXtjb25zdCBjPU1hdGguY29zKHIpLGw9TWF0aC5zaW4ocik7cmV0dXJuIHRoaXMuc2V0KG4qYyxuKmwsLW4qKGMqbytsKmEpK28rdCwtcypsLHMqYywtcyooLWwqbytjKmEpK2ErZSwwLDAsMSksdGhpc31zY2FsZSh0LGUpe3JldHVybiB0aGlzLnByZW11bHRpcGx5KGlvLm1ha2VTY2FsZSh0LGUpKSx0aGlzfXJvdGF0ZSh0KXtyZXR1cm4gdGhpcy5wcmVtdWx0aXBseShpby5tYWtlUm90YXRpb24oLXQpKSx0aGlzfXRyYW5zbGF0ZSh0LGUpe3JldHVybiB0aGlzLnByZW11bHRpcGx5KGlvLm1ha2VUcmFuc2xhdGlvbih0LGUpKSx0aGlzfW1ha2VUcmFuc2xhdGlvbih0LGUpe3JldHVybiB0LmlzVmVjdG9yMj90aGlzLnNldCgxLDAsdC54LDAsMSx0LnksMCwwLDEpOnRoaXMuc2V0KDEsMCx0LDAsMSxlLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbih0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsLW4sMCxuLGUsMCwwLDAsMSksdGhpc31tYWtlU2NhbGUodCxlKXtyZXR1cm4gdGhpcy5zZXQodCwwLDAsMCxlLDAsMCwwLDEpLHRoaXN9ZXF1YWxzKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7Zm9yKGxldCBzPTA7czw5O3MrKylpZihlW3NdIT09bltzXSlyZXR1cm4hMTtyZXR1cm4hMH1mcm9tQXJyYXkodCxlPTApe2ZvcihsZXQgbj0wO248OTtuKyspdGhpcy5lbGVtZW50c1tuXT10W24rZV07cmV0dXJuIHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7Y29uc3Qgbj10aGlzLmVsZW1lbnRzO3JldHVybiB0W2VdPW5bMF0sdFtlKzFdPW5bMV0sdFtlKzJdPW5bMl0sdFtlKzNdPW5bM10sdFtlKzRdPW5bNF0sdFtlKzVdPW5bNV0sdFtlKzZdPW5bNl0sdFtlKzddPW5bN10sdFtlKzhdPW5bOF0sdH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmZyb21BcnJheSh0aGlzLmVsZW1lbnRzKX19Y29uc3QgaW89bmV3IGdlO2Z1bmN0aW9uIFF1KGkpe2ZvcihsZXQgdD1pLmxlbmd0aC0xO3Q+PTA7LS10KWlmKGlbdF0+PTY1NTM1KXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uIFNjKGkpe3JldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiLGkpfWNvbnN0IF9jPXt9O2Z1bmN0aW9uIHZjKGkpe2kgaW4gX2N8fChfY1tpXT0hMCxjb25zb2xlLndhcm4oaSkpfWNvbnN0IHpjPW5ldyBnZSgpLnNldCguNDEyMzkwOCwuMzU3NTg0MywuMTgwNDgwOCwuMjEyNjM5LC43MTUxNjg3LC4wNzIxOTIzLC4wMTkzMzA4LC4xMTkxOTQ4LC45NTA1MzIyKSxUYz1uZXcgZ2UoKS5zZXQoMy4yNDA5Njk5LC0xLjUzNzM4MzIsLS40OTg2MTA4LC0uOTY5MjQzNiwxLjg3NTk2NzUsLjA0MTU1NTEsLjA1NTYzMDEsLS4yMDM5NzcsMS4wNTY5NzE1KTtmdW5jdGlvbiBLdSgpe2NvbnN0IGk9e2VuYWJsZWQ6ITAsd29ya2luZ0NvbG9yU3BhY2U6YmMsc3BhY2VzOnt9LGNvbnZlcnQ6ZnVuY3Rpb24ocyxyLG8pe3JldHVybiB0aGlzLmVuYWJsZWQ9PT0hMXx8cj09PW98fCFyfHwhb3x8KHRoaXMuc3BhY2VzW3JdLnRyYW5zZmVyPT09dG8mJihzLnI9X2Uocy5yKSxzLmc9X2Uocy5nKSxzLmI9X2Uocy5iKSksdGhpcy5zcGFjZXNbcl0ucHJpbWFyaWVzIT09dGhpcy5zcGFjZXNbb10ucHJpbWFyaWVzJiYocy5hcHBseU1hdHJpeDModGhpcy5zcGFjZXNbcl0udG9YWVopLHMuYXBwbHlNYXRyaXgzKHRoaXMuc3BhY2VzW29dLmZyb21YWVopKSx0aGlzLnNwYWNlc1tvXS50cmFuc2Zlcj09PXRvJiYocy5yPUluKHMucikscy5nPUluKHMuZykscy5iPUluKHMuYikpKSxzfSx3b3JraW5nVG9Db2xvclNwYWNlOmZ1bmN0aW9uKHMscil7cmV0dXJuIHRoaXMuY29udmVydChzLHRoaXMud29ya2luZ0NvbG9yU3BhY2Uscil9LGNvbG9yU3BhY2VUb1dvcmtpbmc6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdGhpcy5jb252ZXJ0KHMscix0aGlzLndvcmtpbmdDb2xvclNwYWNlKX0sZ2V0UHJpbWFyaWVzOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5wcmltYXJpZXN9LGdldFRyYW5zZmVyOmZ1bmN0aW9uKHMpe3JldHVybiBzPT09d2M/TWM6dGhpcy5zcGFjZXNbc10udHJhbnNmZXJ9LGdldEx1bWluYW5jZUNvZWZmaWNpZW50czpmdW5jdGlvbihzLHI9dGhpcy53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHMuZnJvbUFycmF5KHRoaXMuc3BhY2VzW3JdLmx1bWluYW5jZUNvZWZmaWNpZW50cyl9LGRlZmluZTpmdW5jdGlvbihzKXtPYmplY3QuYXNzaWduKHRoaXMuc3BhY2VzLHMpfSxfZ2V0TWF0cml4OmZ1bmN0aW9uKHMscixvKXtyZXR1cm4gcy5jb3B5KHRoaXMuc3BhY2VzW3JdLnRvWFlaKS5tdWx0aXBseSh0aGlzLnNwYWNlc1tvXS5mcm9tWFlaKX0sX2dldERyYXdpbmdCdWZmZXJDb2xvclNwYWNlOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5vdXRwdXRDb2xvclNwYWNlQ29uZmlnLmRyYXdpbmdCdWZmZXJDb2xvclNwYWNlfSxfZ2V0VW5wYWNrQ29sb3JTcGFjZTpmdW5jdGlvbihzPXRoaXMud29ya2luZ0NvbG9yU3BhY2Upe3JldHVybiB0aGlzLnNwYWNlc1tzXS53b3JraW5nQ29sb3JTcGFjZUNvbmZpZy51bnBhY2tDb2xvclNwYWNlfSxmcm9tV29ya2luZ0NvbG9yU3BhY2U6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdmMoIlRIUkVFLkNvbG9yTWFuYWdlbWVudDogLmZyb21Xb3JraW5nQ29sb3JTcGFjZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLndvcmtpbmdUb0NvbG9yU3BhY2UoKS4iKSxpLndvcmtpbmdUb0NvbG9yU3BhY2UocyxyKX0sdG9Xb3JraW5nQ29sb3JTcGFjZTpmdW5jdGlvbihzLHIpe3JldHVybiB2YygiVEhSRUUuQ29sb3JNYW5hZ2VtZW50OiAudG9Xb3JraW5nQ29sb3JTcGFjZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmNvbG9yU3BhY2VUb1dvcmtpbmcoKS4iKSxpLmNvbG9yU3BhY2VUb1dvcmtpbmcocyxyKX19LHQ9Wy42NCwuMzMsLjMsLjYsLjE1LC4wNl0sZT1bLjIxMjYsLjcxNTIsLjA3MjJdLG49Wy4zMTI3LC4zMjldO3JldHVybiBpLmRlZmluZSh7W2JjXTp7cHJpbWFyaWVzOnQsd2hpdGVQb2ludDpuLHRyYW5zZmVyOk1jLHRvWFlaOnpjLGZyb21YWVo6VGMsbHVtaW5hbmNlQ29lZmZpY2llbnRzOmUsd29ya2luZ0NvbG9yU3BhY2VDb25maWc6e3VucGFja0NvbG9yU3BhY2U6b2V9LG91dHB1dENvbG9yU3BhY2VDb25maWc6e2RyYXdpbmdCdWZmZXJDb2xvclNwYWNlOm9lfX0sW29lXTp7cHJpbWFyaWVzOnQsd2hpdGVQb2ludDpuLHRyYW5zZmVyOnRvLHRvWFlaOnpjLGZyb21YWVo6VGMsbHVtaW5hbmNlQ29lZmZpY2llbnRzOmUsb3V0cHV0Q29sb3JTcGFjZUNvbmZpZzp7ZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6b2V9fX0pLGl9Y29uc3QgYWU9S3UoKTtmdW5jdGlvbiBfZShpKXtyZXR1cm4gaTwuMDQwNDU/aSouMDc3Mzk5MzgwODpNYXRoLnBvdyhpKi45NDc4NjcyOTg2Ky4wNTIxMzI3MDE0LDIuNCl9ZnVuY3Rpb24gSW4oaSl7cmV0dXJuIGk8LjAwMzEzMDg/aSoxMi45MjoxLjA1NSpNYXRoLnBvdyhpLC40MTY2NiktLjA1NX1sZXQga247Y2xhc3MgdGZ7c3RhdGljIGdldERhdGFVUkwodCxlPSJpbWFnZS9wbmciKXtpZigvXmRhdGE6L2kudGVzdCh0LnNyYyl8fHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudD09InVuZGVmaW5lZCIpcmV0dXJuIHQuc3JjO2xldCBuO2lmKHQgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCluPXQ7ZWxzZXtrbj09PXZvaWQgMCYmKGtuPVNjKCJjYW52YXMiKSksa24ud2lkdGg9dC53aWR0aCxrbi5oZWlnaHQ9dC5oZWlnaHQ7Y29uc3Qgcz1rbi5nZXRDb250ZXh0KCIyZCIpO3QgaW5zdGFuY2VvZiBJbWFnZURhdGE/cy5wdXRJbWFnZURhdGEodCwwLDApOnMuZHJhd0ltYWdlKHQsMCwwLHQud2lkdGgsdC5oZWlnaHQpLG49a259cmV0dXJuIG4udG9EYXRhVVJMKGUpfXN0YXRpYyBzUkdCVG9MaW5lYXIodCl7aWYodHlwZW9mIEhUTUxJbWFnZUVsZW1lbnQhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudHx8dHlwZW9mIEhUTUxDYW52YXNFbGVtZW50IT0idW5kZWZpbmVkIiYmdCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50fHx0eXBlb2YgSW1hZ2VCaXRtYXAhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSW1hZ2VCaXRtYXApe2NvbnN0IGU9U2MoImNhbnZhcyIpO2Uud2lkdGg9dC53aWR0aCxlLmhlaWdodD10LmhlaWdodDtjb25zdCBuPWUuZ2V0Q29udGV4dCgiMmQiKTtuLmRyYXdJbWFnZSh0LDAsMCx0LndpZHRoLHQuaGVpZ2h0KTtjb25zdCBzPW4uZ2V0SW1hZ2VEYXRhKDAsMCx0LndpZHRoLHQuaGVpZ2h0KSxyPXMuZGF0YTtmb3IobGV0IG89MDtvPHIubGVuZ3RoO28rKylyW29dPV9lKHJbb10vMjU1KSoyNTU7cmV0dXJuIG4ucHV0SW1hZ2VEYXRhKHMsMCwwKSxlfWVsc2UgaWYodC5kYXRhKXtjb25zdCBlPXQuZGF0YS5zbGljZSgwKTtmb3IobGV0IG49MDtuPGUubGVuZ3RoO24rKyllIGluc3RhbmNlb2YgVWludDhBcnJheXx8ZSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5P2Vbbl09TWF0aC5mbG9vcihfZShlW25dLzI1NSkqMjU1KTplW25dPV9lKGVbbl0pO3JldHVybntkYXRhOmUsd2lkdGg6dC53aWR0aCxoZWlnaHQ6dC5oZWlnaHR9fWVsc2UgcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuSW1hZ2VVdGlscy5zUkdCVG9MaW5lYXIoKTogVW5zdXBwb3J0ZWQgaW1hZ2UgdHlwZS4gTm8gY29sb3Igc3BhY2UgY29udmVyc2lvbiBhcHBsaWVkLiIpLHR9fWxldCBlZj0wO2NsYXNzIG5me2NvbnN0cnVjdG9yKHQ9bnVsbCl7dGhpcy5pc1NvdXJjZT0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTplZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5kYXRhPXQsdGhpcy5kYXRhUmVhZHk9ITAsdGhpcy52ZXJzaW9uPTB9Z2V0U2l6ZSh0KXtjb25zdCBlPXRoaXMuZGF0YTtyZXR1cm4gZSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQ/dC5zZXQoZS52aWRlb1dpZHRoLGUudmlkZW9IZWlnaHQpOmUhPT1udWxsP3Quc2V0KGUud2lkdGgsZS5oZWlnaHQsZS5kZXB0aHx8MCk6dC5zZXQoMCwwLDApLHR9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy52ZXJzaW9uKyt9dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciO2lmKCFlJiZ0LmltYWdlc1t0aGlzLnV1aWRdIT09dm9pZCAwKXJldHVybiB0LmltYWdlc1t0aGlzLnV1aWRdO2NvbnN0IG49e3V1aWQ6dGhpcy51dWlkLHVybDoiIn0scz10aGlzLmRhdGE7aWYocyE9PW51bGwpe2xldCByO2lmKEFycmF5LmlzQXJyYXkocykpe3I9W107Zm9yKGxldCBvPTAsYT1zLmxlbmd0aDtvPGE7bysrKXNbb10uaXNEYXRhVGV4dHVyZT9yLnB1c2goc28oc1tvXS5pbWFnZSkpOnIucHVzaChzbyhzW29dKSl9ZWxzZSByPXNvKHMpO24udXJsPXJ9cmV0dXJuIGV8fCh0LmltYWdlc1t0aGlzLnV1aWRdPW4pLG59fWZ1bmN0aW9uIHNvKGkpe3JldHVybiB0eXBlb2YgSFRNTEltYWdlRWxlbWVudCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50fHx0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQhPSJ1bmRlZmluZWQiJiZpIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnR8fHR5cGVvZiBJbWFnZUJpdG1hcCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcD90Zi5nZXREYXRhVVJMKGkpOmkuZGF0YT97ZGF0YTpBcnJheS5mcm9tKGkuZGF0YSksd2lkdGg6aS53aWR0aCxoZWlnaHQ6aS5oZWlnaHQsdHlwZTppLmRhdGEuY29uc3RydWN0b3IubmFtZX06KGNvbnNvbGUud2FybigiVEhSRUUuVGV4dHVyZTogVW5hYmxlIHRvIHNlcmlhbGl6ZSBUZXh0dXJlLiIpLHt9KX1sZXQgc2Y9MDtjb25zdCBybz1uZXcgVDtjbGFzcyBsbiBleHRlbmRzIG9ze2NvbnN0cnVjdG9yKHQ9bG4uREVGQVVMVF9JTUFHRSxlPWxuLkRFRkFVTFRfTUFQUElORyxuPTEwMDEscz0xMDAxLHI9MTAwNixvPTEwMDgsYT0xMDIzLGM9MTAwOSxsPWxuLkRFRkFVTFRfQU5JU09UUk9QWSxoPXdjKXtzdXBlcigpLHRoaXMuaXNUZXh0dXJlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOnNmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy5zb3VyY2U9bmV3IG5mKHQpLHRoaXMubWlwbWFwcz1bXSx0aGlzLm1hcHBpbmc9ZSx0aGlzLmNoYW5uZWw9MCx0aGlzLndyYXBTPW4sdGhpcy53cmFwVD1zLHRoaXMubWFnRmlsdGVyPXIsdGhpcy5taW5GaWx0ZXI9byx0aGlzLmFuaXNvdHJvcHk9bCx0aGlzLmZvcm1hdD1hLHRoaXMuaW50ZXJuYWxGb3JtYXQ9bnVsbCx0aGlzLnR5cGU9Yyx0aGlzLm9mZnNldD1uZXcgUigwLDApLHRoaXMucmVwZWF0PW5ldyBSKDEsMSksdGhpcy5jZW50ZXI9bmV3IFIoMCwwKSx0aGlzLnJvdGF0aW9uPTAsdGhpcy5tYXRyaXhBdXRvVXBkYXRlPSEwLHRoaXMubWF0cml4PW5ldyBnZSx0aGlzLmdlbmVyYXRlTWlwbWFwcz0hMCx0aGlzLnByZW11bHRpcGx5QWxwaGE9ITEsdGhpcy5mbGlwWT0hMCx0aGlzLnVucGFja0FsaWdubWVudD00LHRoaXMuY29sb3JTcGFjZT1oLHRoaXMudXNlckRhdGE9e30sdGhpcy51cGRhdGVSYW5nZXM9W10sdGhpcy52ZXJzaW9uPTAsdGhpcy5vblVwZGF0ZT1udWxsLHRoaXMucmVuZGVyVGFyZ2V0PW51bGwsdGhpcy5pc1JlbmRlclRhcmdldFRleHR1cmU9ITEsdGhpcy5pc0FycmF5VGV4dHVyZT0hISh0JiZ0LmRlcHRoJiZ0LmRlcHRoPjEpLHRoaXMucG1yZW1WZXJzaW9uPTB9Z2V0IHdpZHRoKCl7cmV0dXJuIHRoaXMuc291cmNlLmdldFNpemUocm8pLnh9Z2V0IGhlaWdodCgpe3JldHVybiB0aGlzLnNvdXJjZS5nZXRTaXplKHJvKS55fWdldCBkZXB0aCgpe3JldHVybiB0aGlzLnNvdXJjZS5nZXRTaXplKHJvKS56fWdldCBpbWFnZSgpe3JldHVybiB0aGlzLnNvdXJjZS5kYXRhfXNldCBpbWFnZSh0PW51bGwpe3RoaXMuc291cmNlLmRhdGE9dH11cGRhdGVNYXRyaXgoKXt0aGlzLm1hdHJpeC5zZXRVdlRyYW5zZm9ybSh0aGlzLm9mZnNldC54LHRoaXMub2Zmc2V0LnksdGhpcy5yZXBlYXQueCx0aGlzLnJlcGVhdC55LHRoaXMucm90YXRpb24sdGhpcy5jZW50ZXIueCx0aGlzLmNlbnRlci55KX1hZGRVcGRhdGVSYW5nZSh0LGUpe3RoaXMudXBkYXRlUmFuZ2VzLnB1c2goe3N0YXJ0OnQsY291bnQ6ZX0pfWNsZWFyVXBkYXRlUmFuZ2VzKCl7dGhpcy51cGRhdGVSYW5nZXMubGVuZ3RoPTB9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7cmV0dXJuIHRoaXMubmFtZT10Lm5hbWUsdGhpcy5zb3VyY2U9dC5zb3VyY2UsdGhpcy5taXBtYXBzPXQubWlwbWFwcy5zbGljZSgwKSx0aGlzLm1hcHBpbmc9dC5tYXBwaW5nLHRoaXMuY2hhbm5lbD10LmNoYW5uZWwsdGhpcy53cmFwUz10LndyYXBTLHRoaXMud3JhcFQ9dC53cmFwVCx0aGlzLm1hZ0ZpbHRlcj10Lm1hZ0ZpbHRlcix0aGlzLm1pbkZpbHRlcj10Lm1pbkZpbHRlcix0aGlzLmFuaXNvdHJvcHk9dC5hbmlzb3Ryb3B5LHRoaXMuZm9ybWF0PXQuZm9ybWF0LHRoaXMuaW50ZXJuYWxGb3JtYXQ9dC5pbnRlcm5hbEZvcm1hdCx0aGlzLnR5cGU9dC50eXBlLHRoaXMub2Zmc2V0LmNvcHkodC5vZmZzZXQpLHRoaXMucmVwZWF0LmNvcHkodC5yZXBlYXQpLHRoaXMuY2VudGVyLmNvcHkodC5jZW50ZXIpLHRoaXMucm90YXRpb249dC5yb3RhdGlvbix0aGlzLm1hdHJpeEF1dG9VcGRhdGU9dC5tYXRyaXhBdXRvVXBkYXRlLHRoaXMubWF0cml4LmNvcHkodC5tYXRyaXgpLHRoaXMuZ2VuZXJhdGVNaXBtYXBzPXQuZ2VuZXJhdGVNaXBtYXBzLHRoaXMucHJlbXVsdGlwbHlBbHBoYT10LnByZW11bHRpcGx5QWxwaGEsdGhpcy5mbGlwWT10LmZsaXBZLHRoaXMudW5wYWNrQWxpZ25tZW50PXQudW5wYWNrQWxpZ25tZW50LHRoaXMuY29sb3JTcGFjZT10LmNvbG9yU3BhY2UsdGhpcy5yZW5kZXJUYXJnZXQ9dC5yZW5kZXJUYXJnZXQsdGhpcy5pc1JlbmRlclRhcmdldFRleHR1cmU9dC5pc1JlbmRlclRhcmdldFRleHR1cmUsdGhpcy5pc0FycmF5VGV4dHVyZT10LmlzQXJyYXlUZXh0dXJlLHRoaXMudXNlckRhdGE9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0LnVzZXJEYXRhKSksdGhpcy5uZWVkc1VwZGF0ZT0hMCx0aGlzfXNldFZhbHVlcyh0KXtmb3IoY29uc3QgZSBpbiB0KXtjb25zdCBuPXRbZV07aWYobj09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5UZXh0dXJlLnNldFZhbHVlcygpOiBwYXJhbWV0ZXIgJyR7ZX0nIGhhcyB2YWx1ZSBvZiB1bmRlZmluZWQuYCk7Y29udGludWV9Y29uc3Qgcz10aGlzW2VdO2lmKHM9PT12b2lkIDApe2NvbnNvbGUud2FybihgVEhSRUUuVGV4dHVyZS5zZXRWYWx1ZXMoKTogcHJvcGVydHkgJyR7ZX0nIGRvZXMgbm90IGV4aXN0LmApO2NvbnRpbnVlfXMmJm4mJnMuaXNWZWN0b3IyJiZuLmlzVmVjdG9yMnx8cyYmbiYmcy5pc1ZlY3RvcjMmJm4uaXNWZWN0b3IzfHxzJiZuJiZzLmlzTWF0cml4MyYmbi5pc01hdHJpeDM/cy5jb3B5KG4pOnRoaXNbZV09bn19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciO2lmKCFlJiZ0LnRleHR1cmVzW3RoaXMudXVpZF0hPT12b2lkIDApcmV0dXJuIHQudGV4dHVyZXNbdGhpcy51dWlkXTtjb25zdCBuPXttZXRhZGF0YTp7dmVyc2lvbjo0LjcsdHlwZToiVGV4dHVyZSIsZ2VuZXJhdG9yOiJUZXh0dXJlLnRvSlNPTiJ9LHV1aWQ6dGhpcy51dWlkLG5hbWU6dGhpcy5uYW1lLGltYWdlOnRoaXMuc291cmNlLnRvSlNPTih0KS51dWlkLG1hcHBpbmc6dGhpcy5tYXBwaW5nLGNoYW5uZWw6dGhpcy5jaGFubmVsLHJlcGVhdDpbdGhpcy5yZXBlYXQueCx0aGlzLnJlcGVhdC55XSxvZmZzZXQ6W3RoaXMub2Zmc2V0LngsdGhpcy5vZmZzZXQueV0sY2VudGVyOlt0aGlzLmNlbnRlci54LHRoaXMuY2VudGVyLnldLHJvdGF0aW9uOnRoaXMucm90YXRpb24sd3JhcDpbdGhpcy53cmFwUyx0aGlzLndyYXBUXSxmb3JtYXQ6dGhpcy5mb3JtYXQsaW50ZXJuYWxGb3JtYXQ6dGhpcy5pbnRlcm5hbEZvcm1hdCx0eXBlOnRoaXMudHlwZSxjb2xvclNwYWNlOnRoaXMuY29sb3JTcGFjZSxtaW5GaWx0ZXI6dGhpcy5taW5GaWx0ZXIsbWFnRmlsdGVyOnRoaXMubWFnRmlsdGVyLGFuaXNvdHJvcHk6dGhpcy5hbmlzb3Ryb3B5LGZsaXBZOnRoaXMuZmxpcFksZ2VuZXJhdGVNaXBtYXBzOnRoaXMuZ2VuZXJhdGVNaXBtYXBzLHByZW11bHRpcGx5QWxwaGE6dGhpcy5wcmVtdWx0aXBseUFscGhhLHVucGFja0FsaWdubWVudDp0aGlzLnVucGFja0FsaWdubWVudH07cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYobi51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSxlfHwodC50ZXh0dXJlc1t0aGlzLnV1aWRdPW4pLG59ZGlzcG9zZSgpe3RoaXMuZGlzcGF0Y2hFdmVudCh7dHlwZToiZGlzcG9zZSJ9KX10cmFuc2Zvcm1Vdih0KXtpZih0aGlzLm1hcHBpbmchPT0zMDApcmV0dXJuIHQ7aWYodC5hcHBseU1hdHJpeDModGhpcy5tYXRyaXgpLHQueDwwfHx0Lng+MSlzd2l0Y2godGhpcy53cmFwUyl7Y2FzZSAxZTM6dC54PXQueC1NYXRoLmZsb29yKHQueCk7YnJlYWs7Y2FzZSAxMDAxOnQueD10Lng8MD8wOjE7YnJlYWs7Y2FzZSAxMDAyOk1hdGguYWJzKE1hdGguZmxvb3IodC54KSUyKT09PTE/dC54PU1hdGguY2VpbCh0LngpLXQueDp0Lng9dC54LU1hdGguZmxvb3IodC54KTticmVha31pZih0Lnk8MHx8dC55PjEpc3dpdGNoKHRoaXMud3JhcFQpe2Nhc2UgMWUzOnQueT10LnktTWF0aC5mbG9vcih0LnkpO2JyZWFrO2Nhc2UgMTAwMTp0Lnk9dC55PDA/MDoxO2JyZWFrO2Nhc2UgMTAwMjpNYXRoLmFicyhNYXRoLmZsb29yKHQueSklMik9PT0xP3QueT1NYXRoLmNlaWwodC55KS10Lnk6dC55PXQueS1NYXRoLmZsb29yKHQueSk7YnJlYWt9cmV0dXJuIHRoaXMuZmxpcFkmJih0Lnk9MS10LnkpLHR9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmKHRoaXMudmVyc2lvbisrLHRoaXMuc291cmNlLm5lZWRzVXBkYXRlPSEwKX1zZXQgbmVlZHNQTVJFTVVwZGF0ZSh0KXt0PT09ITAmJnRoaXMucG1yZW1WZXJzaW9uKyt9fWxuLkRFRkFVTFRfSU1BR0U9bnVsbCxsbi5ERUZBVUxUX01BUFBJTkc9MzAwLGxuLkRFRkFVTFRfQU5JU09UUk9QWT0xO2NsYXNzIFl0e2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9MSl7WXQucHJvdG90eXBlLmlzVmVjdG9yND0hMCx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzLnc9c31nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy56fXNldCB3aWR0aCh0KXt0aGlzLno9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMud31zZXQgaGVpZ2h0KHQpe3RoaXMudz10fXNldCh0LGUsbixzKXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PWUsdGhpcy56PW4sdGhpcy53PXMsdGhpc31zZXRTY2FsYXIodCl7cmV0dXJuIHRoaXMueD10LHRoaXMueT10LHRoaXMuej10LHRoaXMudz10LHRoaXN9c2V0WCh0KXtyZXR1cm4gdGhpcy54PXQsdGhpc31zZXRZKHQpe3JldHVybiB0aGlzLnk9dCx0aGlzfXNldFoodCl7cmV0dXJuIHRoaXMuej10LHRoaXN9c2V0Vyh0KXtyZXR1cm4gdGhpcy53PXQsdGhpc31zZXRDb21wb25lbnQodCxlKXtzd2l0Y2godCl7Y2FzZSAwOnRoaXMueD1lO2JyZWFrO2Nhc2UgMTp0aGlzLnk9ZTticmVhaztjYXNlIDI6dGhpcy56PWU7YnJlYWs7Y2FzZSAzOnRoaXMudz1lO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9cmV0dXJuIHRoaXN9Z2V0Q29tcG9uZW50KHQpe3N3aXRjaCh0KXtjYXNlIDA6cmV0dXJuIHRoaXMueDtjYXNlIDE6cmV0dXJuIHRoaXMueTtjYXNlIDI6cmV0dXJuIHRoaXMuejtjYXNlIDM6cmV0dXJuIHRoaXMudztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAiK3QpfX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLngsdGhpcy55LHRoaXMueix0aGlzLncpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzLno9dC56LHRoaXMudz10LnchPT12b2lkIDA/dC53OjEsdGhpc31hZGQodCl7cmV0dXJuIHRoaXMueCs9dC54LHRoaXMueSs9dC55LHRoaXMueis9dC56LHRoaXMudys9dC53LHRoaXN9YWRkU2NhbGFyKHQpe3JldHVybiB0aGlzLngrPXQsdGhpcy55Kz10LHRoaXMueis9dCx0aGlzLncrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXMuej10LnorZS56LHRoaXMudz10LncrZS53LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzLnorPXQueiplLHRoaXMudys9dC53KmUsdGhpc31zdWIodCl7cmV0dXJuIHRoaXMueC09dC54LHRoaXMueS09dC55LHRoaXMuei09dC56LHRoaXMudy09dC53LHRoaXN9c3ViU2NhbGFyKHQpe3JldHVybiB0aGlzLngtPXQsdGhpcy55LT10LHRoaXMuei09dCx0aGlzLnctPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXMuej10LnotZS56LHRoaXMudz10LnctZS53LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXMueio9dC56LHRoaXMudyo9dC53LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpcy56Kj10LHRoaXMudyo9dCx0aGlzfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXRoaXMudyxvPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1vWzBdKmUrb1s0XSpuK29bOF0qcytvWzEyXSpyLHRoaXMueT1vWzFdKmUrb1s1XSpuK29bOV0qcytvWzEzXSpyLHRoaXMuej1vWzJdKmUrb1s2XSpuK29bMTBdKnMrb1sxNF0qcix0aGlzLnc9b1szXSplK29bN10qbitvWzExXSpzK29bMTVdKnIsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXMuei89dC56LHRoaXMudy89dC53LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9c2V0QXhpc0FuZ2xlRnJvbVF1YXRlcm5pb24odCl7dGhpcy53PTIqTWF0aC5hY29zKHQudyk7Y29uc3QgZT1NYXRoLnNxcnQoMS10LncqdC53KTtyZXR1cm4gZTwxZS00Pyh0aGlzLng9MSx0aGlzLnk9MCx0aGlzLno9MCk6KHRoaXMueD10LngvZSx0aGlzLnk9dC55L2UsdGhpcy56PXQuei9lKSx0aGlzfXNldEF4aXNBbmdsZUZyb21Sb3RhdGlvbk1hdHJpeCh0KXtsZXQgZSxuLHMscjtjb25zdCBjPXQuZWxlbWVudHMsbD1jWzBdLGg9Y1s0XSx1PWNbOF0sZj1jWzFdLGQ9Y1s1XSxwPWNbOV0seT1jWzJdLG09Y1s2XSxnPWNbMTBdO2lmKE1hdGguYWJzKGgtZik8LjAxJiZNYXRoLmFicyh1LXkpPC4wMSYmTWF0aC5hYnMocC1tKTwuMDEpe2lmKE1hdGguYWJzKGgrZik8LjEmJk1hdGguYWJzKHUreSk8LjEmJk1hdGguYWJzKHArbSk8LjEmJk1hdGguYWJzKGwrZCtnLTMpPC4xKXJldHVybiB0aGlzLnNldCgxLDAsMCwwKSx0aGlzO2U9TWF0aC5QSTtjb25zdCB3PShsKzEpLzIseD0oZCsxKS8yLE09KGcrMSkvMixBPShoK2YpLzQsUz0odSt5KS80LF89KHArbSkvNDtyZXR1cm4gdz54JiZ3Pk0/dzwuMDE/KG49MCxzPS43MDcxMDY3ODEscj0uNzA3MTA2NzgxKToobj1NYXRoLnNxcnQodykscz1BL24scj1TL24pOng+TT94PC4wMT8obj0uNzA3MTA2NzgxLHM9MCxyPS43MDcxMDY3ODEpOihzPU1hdGguc3FydCh4KSxuPUEvcyxyPV8vcyk6TTwuMDE/KG49LjcwNzEwNjc4MSxzPS43MDcxMDY3ODEscj0wKToocj1NYXRoLnNxcnQoTSksbj1TL3Iscz1fL3IpLHRoaXMuc2V0KG4scyxyLGUpLHRoaXN9bGV0IGI9TWF0aC5zcXJ0KChtLXApKihtLXApKyh1LXkpKih1LXkpKyhmLWgpKihmLWgpKTtyZXR1cm4gTWF0aC5hYnMoYik8LjAwMSYmKGI9MSksdGhpcy54PShtLXApL2IsdGhpcy55PSh1LXkpL2IsdGhpcy56PShmLWgpL2IsdGhpcy53PU1hdGguYWNvcygobCtkK2ctMSkvMiksdGhpc31zZXRGcm9tTWF0cml4UG9zaXRpb24odCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9ZVsxMl0sdGhpcy55PWVbMTNdLHRoaXMuej1lWzE0XSx0aGlzLnc9ZVsxNV0sdGhpc31taW4odCl7cmV0dXJuIHRoaXMueD1NYXRoLm1pbih0aGlzLngsdC54KSx0aGlzLnk9TWF0aC5taW4odGhpcy55LHQueSksdGhpcy56PU1hdGgubWluKHRoaXMueix0LnopLHRoaXMudz1NYXRoLm1pbih0aGlzLncsdC53KSx0aGlzfW1heCh0KXtyZXR1cm4gdGhpcy54PU1hdGgubWF4KHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1heCh0aGlzLnksdC55KSx0aGlzLno9TWF0aC5tYXgodGhpcy56LHQueiksdGhpcy53PU1hdGgubWF4KHRoaXMudyx0LncpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzLno9Wih0aGlzLnosdC56LGUueiksdGhpcy53PVoodGhpcy53LHQudyxlLncpLHRoaXN9Y2xhbXBTY2FsYXIodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQsZSksdGhpcy55PVoodGhpcy55LHQsZSksdGhpcy56PVoodGhpcy56LHQsZSksdGhpcy53PVoodGhpcy53LHQsZSksdGhpc31jbGFtcExlbmd0aCh0LGUpe2NvbnN0IG49dGhpcy5sZW5ndGgoKTtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIobnx8MSkubXVsdGlwbHlTY2FsYXIoWihuLHQsZSkpfWZsb29yKCl7cmV0dXJuIHRoaXMueD1NYXRoLmZsb29yKHRoaXMueCksdGhpcy55PU1hdGguZmxvb3IodGhpcy55KSx0aGlzLno9TWF0aC5mbG9vcih0aGlzLnopLHRoaXMudz1NYXRoLmZsb29yKHRoaXMudyksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpcy56PU1hdGguY2VpbCh0aGlzLnopLHRoaXMudz1NYXRoLmNlaWwodGhpcy53KSx0aGlzfXJvdW5kKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJvdW5kKHRoaXMueCksdGhpcy55PU1hdGgucm91bmQodGhpcy55KSx0aGlzLno9TWF0aC5yb3VuZCh0aGlzLnopLHRoaXMudz1NYXRoLnJvdW5kKHRoaXMudyksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpcy56PU1hdGgudHJ1bmModGhpcy56KSx0aGlzLnc9TWF0aC50cnVuYyh0aGlzLncpLHRoaXN9bmVnYXRlKCl7cmV0dXJuIHRoaXMueD0tdGhpcy54LHRoaXMueT0tdGhpcy55LHRoaXMuej0tdGhpcy56LHRoaXMudz0tdGhpcy53LHRoaXN9ZG90KHQpe3JldHVybiB0aGlzLngqdC54K3RoaXMueSp0LnkrdGhpcy56KnQueit0aGlzLncqdC53fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56K3RoaXMudyp0aGlzLnd9bGVuZ3RoKCl7cmV0dXJuIE1hdGguc3FydCh0aGlzLngqdGhpcy54K3RoaXMueSp0aGlzLnkrdGhpcy56KnRoaXMueit0aGlzLncqdGhpcy53KX1tYW5oYXR0YW5MZW5ndGgoKXtyZXR1cm4gTWF0aC5hYnModGhpcy54KStNYXRoLmFicyh0aGlzLnkpK01hdGguYWJzKHRoaXMueikrTWF0aC5hYnModGhpcy53KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXMueis9KHQuei10aGlzLnopKmUsdGhpcy53Kz0odC53LXRoaXMudykqZSx0aGlzfWxlcnBWZWN0b3JzKHQsZSxuKXtyZXR1cm4gdGhpcy54PXQueCsoZS54LXQueCkqbix0aGlzLnk9dC55KyhlLnktdC55KSpuLHRoaXMuej10LnorKGUuei10LnopKm4sdGhpcy53PXQudysoZS53LXQudykqbix0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC54PT09dGhpcy54JiZ0Lnk9PT10aGlzLnkmJnQuej09PXRoaXMueiYmdC53PT09dGhpcy53fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpcy56PXRbZSsyXSx0aGlzLnc9dFtlKzNdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy54LHRbZSsxXT10aGlzLnksdFtlKzJdPXRoaXMueix0W2UrM109dGhpcy53LHR9ZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLng9dC5nZXRYKGUpLHRoaXMueT10LmdldFkoZSksdGhpcy56PXQuZ2V0WihlKSx0aGlzLnc9dC5nZXRXKGUpLHRoaXN9cmFuZG9tKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJhbmRvbSgpLHRoaXMueT1NYXRoLnJhbmRvbSgpLHRoaXMuej1NYXRoLnJhbmRvbSgpLHRoaXMudz1NYXRoLnJhbmRvbSgpLHRoaXN9KltTeW1ib2wuaXRlcmF0b3JdKCl7eWllbGQgdGhpcy54LHlpZWxkIHRoaXMueSx5aWVsZCB0aGlzLnoseWllbGQgdGhpcy53fX1jbGFzcyBndHtjb25zdHJ1Y3Rvcih0PW5ldyBUKDEvMCwxLzAsMS8wKSxlPW5ldyBUKC0xLzAsLTEvMCwtMS8wKSl7dGhpcy5pc0JveDM9ITAsdGhpcy5taW49dCx0aGlzLm1heD1lfXNldCh0LGUpe3JldHVybiB0aGlzLm1pbi5jb3B5KHQpLHRoaXMubWF4LmNvcHkoZSksdGhpc31zZXRGcm9tQXJyYXkodCl7dGhpcy5tYWtlRW1wdHkoKTtmb3IobGV0IGU9MCxuPXQubGVuZ3RoO2U8bjtlKz0zKXRoaXMuZXhwYW5kQnlQb2ludChjZS5mcm9tQXJyYXkodCxlKSk7cmV0dXJuIHRoaXN9c2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSh0KXt0aGlzLm1ha2VFbXB0eSgpO2ZvcihsZXQgZT0wLG49dC5jb3VudDtlPG47ZSsrKXRoaXMuZXhwYW5kQnlQb2ludChjZS5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSkpO3JldHVybiB0aGlzfXNldEZyb21Qb2ludHModCl7dGhpcy5tYWtlRW1wdHkoKTtmb3IobGV0IGU9MCxuPXQubGVuZ3RoO2U8bjtlKyspdGhpcy5leHBhbmRCeVBvaW50KHRbZV0pO3JldHVybiB0aGlzfXNldEZyb21DZW50ZXJBbmRTaXplKHQsZSl7Y29uc3Qgbj1jZS5jb3B5KGUpLm11bHRpcGx5U2NhbGFyKC41KTtyZXR1cm4gdGhpcy5taW4uY29weSh0KS5zdWIobiksdGhpcy5tYXguY29weSh0KS5hZGQobiksdGhpc31zZXRGcm9tT2JqZWN0KHQsZT0hMSl7cmV0dXJuIHRoaXMubWFrZUVtcHR5KCksdGhpcy5leHBhbmRCeU9iamVjdCh0LGUpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLm1pbi5jb3B5KHQubWluKSx0aGlzLm1heC5jb3B5KHQubWF4KSx0aGlzfW1ha2VFbXB0eSgpe3JldHVybiB0aGlzLm1pbi54PXRoaXMubWluLnk9dGhpcy5taW4uej0xLzAsdGhpcy5tYXgueD10aGlzLm1heC55PXRoaXMubWF4Lno9LTEvMCx0aGlzfWlzRW1wdHkoKXtyZXR1cm4gdGhpcy5tYXgueDx0aGlzLm1pbi54fHx0aGlzLm1heC55PHRoaXMubWluLnl8fHRoaXMubWF4Lno8dGhpcy5taW4uen1nZXRDZW50ZXIodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3Quc2V0KDAsMCwwKTp0LmFkZFZlY3RvcnModGhpcy5taW4sdGhpcy5tYXgpLm11bHRpcGx5U2NhbGFyKC41KX1nZXRTaXplKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90LnNldCgwLDAsMCk6dC5zdWJWZWN0b3JzKHRoaXMubWF4LHRoaXMubWluKX1leHBhbmRCeVBvaW50KHQpe3JldHVybiB0aGlzLm1pbi5taW4odCksdGhpcy5tYXgubWF4KHQpLHRoaXN9ZXhwYW5kQnlWZWN0b3IodCl7cmV0dXJuIHRoaXMubWluLnN1Yih0KSx0aGlzLm1heC5hZGQodCksdGhpc31leHBhbmRCeVNjYWxhcih0KXtyZXR1cm4gdGhpcy5taW4uYWRkU2NhbGFyKC10KSx0aGlzLm1heC5hZGRTY2FsYXIodCksdGhpc31leHBhbmRCeU9iamVjdCh0LGU9ITEpe3QudXBkYXRlV29ybGRNYXRyaXgoITEsITEpO2NvbnN0IG49dC5nZW9tZXRyeTtpZihuIT09dm9pZCAwKXtjb25zdCByPW4uZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpO2lmKGU9PT0hMCYmciE9PXZvaWQgMCYmdC5pc0luc3RhbmNlZE1lc2ghPT0hMClmb3IobGV0IG89MCxhPXIuY291bnQ7bzxhO28rKyl0LmlzTWVzaD09PSEwP3QuZ2V0VmVydGV4UG9zaXRpb24obyxjZSk6Y2UuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLG8pLGNlLmFwcGx5TWF0cml4NCh0Lm1hdHJpeFdvcmxkKSx0aGlzLmV4cGFuZEJ5UG9pbnQoY2UpO2Vsc2UgdC5ib3VuZGluZ0JveCE9PXZvaWQgMD8odC5ib3VuZGluZ0JveD09PW51bGwmJnQuY29tcHV0ZUJvdW5kaW5nQm94KCksYXMuY29weSh0LmJvdW5kaW5nQm94KSk6KG4uYm91bmRpbmdCb3g9PT1udWxsJiZuLmNvbXB1dGVCb3VuZGluZ0JveCgpLGFzLmNvcHkobi5ib3VuZGluZ0JveCkpLGFzLmFwcGx5TWF0cml4NCh0Lm1hdHJpeFdvcmxkKSx0aGlzLnVuaW9uKGFzKX1jb25zdCBzPXQuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXRoaXMuZXhwYW5kQnlPYmplY3Qoc1tyXSxlKTtyZXR1cm4gdGhpc31jb250YWluc1BvaW50KHQpe3JldHVybiB0Lng+PXRoaXMubWluLngmJnQueDw9dGhpcy5tYXgueCYmdC55Pj10aGlzLm1pbi55JiZ0Lnk8PXRoaXMubWF4LnkmJnQuej49dGhpcy5taW4ueiYmdC56PD10aGlzLm1heC56fWNvbnRhaW5zQm94KHQpe3JldHVybiB0aGlzLm1pbi54PD10Lm1pbi54JiZ0Lm1heC54PD10aGlzLm1heC54JiZ0aGlzLm1pbi55PD10Lm1pbi55JiZ0Lm1heC55PD10aGlzLm1heC55JiZ0aGlzLm1pbi56PD10Lm1pbi56JiZ0Lm1heC56PD10aGlzLm1heC56fWdldFBhcmFtZXRlcih0LGUpe3JldHVybiBlLnNldCgodC54LXRoaXMubWluLngpLyh0aGlzLm1heC54LXRoaXMubWluLngpLCh0LnktdGhpcy5taW4ueSkvKHRoaXMubWF4LnktdGhpcy5taW4ueSksKHQuei10aGlzLm1pbi56KS8odGhpcy5tYXguei10aGlzLm1pbi56KSl9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdC5tYXgueD49dGhpcy5taW4ueCYmdC5taW4ueDw9dGhpcy5tYXgueCYmdC5tYXgueT49dGhpcy5taW4ueSYmdC5taW4ueTw9dGhpcy5tYXgueSYmdC5tYXguej49dGhpcy5taW4ueiYmdC5taW4uejw9dGhpcy5tYXguen1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0aGlzLmNsYW1wUG9pbnQodC5jZW50ZXIsY2UpLGNlLmRpc3RhbmNlVG9TcXVhcmVkKHQuY2VudGVyKTw9dC5yYWRpdXMqdC5yYWRpdXN9aW50ZXJzZWN0c1BsYW5lKHQpe2xldCBlLG47cmV0dXJuIHQubm9ybWFsLng+MD8oZT10Lm5vcm1hbC54KnRoaXMubWluLngsbj10Lm5vcm1hbC54KnRoaXMubWF4LngpOihlPXQubm9ybWFsLngqdGhpcy5tYXgueCxuPXQubm9ybWFsLngqdGhpcy5taW4ueCksdC5ub3JtYWwueT4wPyhlKz10Lm5vcm1hbC55KnRoaXMubWluLnksbis9dC5ub3JtYWwueSp0aGlzLm1heC55KTooZSs9dC5ub3JtYWwueSp0aGlzLm1heC55LG4rPXQubm9ybWFsLnkqdGhpcy5taW4ueSksdC5ub3JtYWwuej4wPyhlKz10Lm5vcm1hbC56KnRoaXMubWluLnosbis9dC5ub3JtYWwueip0aGlzLm1heC56KTooZSs9dC5ub3JtYWwueip0aGlzLm1heC56LG4rPXQubm9ybWFsLnoqdGhpcy5taW4ueiksZTw9LXQuY29uc3RhbnQmJm4+PS10LmNvbnN0YW50fWludGVyc2VjdHNUcmlhbmdsZSh0KXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4hMTt0aGlzLmdldENlbnRlcih4aSksY3Muc3ViVmVjdG9ycyh0aGlzLm1heCx4aSksTm4uc3ViVmVjdG9ycyh0LmEseGkpLFJuLnN1YlZlY3RvcnModC5iLHhpKSxMbi5zdWJWZWN0b3JzKHQuYyx4aSksWGUuc3ViVmVjdG9ycyhSbixObiksSmUuc3ViVmVjdG9ycyhMbixSbiksaG4uc3ViVmVjdG9ycyhObixMbik7bGV0IGU9WzAsLVhlLnosWGUueSwwLC1KZS56LEplLnksMCwtaG4ueixobi55LFhlLnosMCwtWGUueCxKZS56LDAsLUplLngsaG4ueiwwLC1obi54LC1YZS55LFhlLngsMCwtSmUueSxKZS54LDAsLWhuLnksaG4ueCwwXTtyZXR1cm4hb28oZSxObixSbixMbixjcyl8fChlPVsxLDAsMCwwLDEsMCwwLDAsMV0sIW9vKGUsTm4sUm4sTG4sY3MpKT8hMToobHMuY3Jvc3NWZWN0b3JzKFhlLEplKSxlPVtscy54LGxzLnksbHMuel0sb28oZSxObixSbixMbixjcykpfWNsYW1wUG9pbnQodCxlKXtyZXR1cm4gZS5jb3B5KHQpLmNsYW1wKHRoaXMubWluLHRoaXMubWF4KX1kaXN0YW5jZVRvUG9pbnQodCl7cmV0dXJuIHRoaXMuY2xhbXBQb2ludCh0LGNlKS5kaXN0YW5jZVRvKHQpfWdldEJvdW5kaW5nU3BoZXJlKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90Lm1ha2VFbXB0eSgpOih0aGlzLmdldENlbnRlcih0LmNlbnRlciksdC5yYWRpdXM9dGhpcy5nZXRTaXplKGNlKS5sZW5ndGgoKSouNSksdH1pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMubWluLm1heCh0Lm1pbiksdGhpcy5tYXgubWluKHQubWF4KSx0aGlzLmlzRW1wdHkoKSYmdGhpcy5tYWtlRW1wdHkoKSx0aGlzfXVuaW9uKHQpe3JldHVybiB0aGlzLm1pbi5taW4odC5taW4pLHRoaXMubWF4Lm1heCh0Lm1heCksdGhpc31hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3RoaXM6KHZlWzBdLnNldCh0aGlzLm1pbi54LHRoaXMubWluLnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzFdLnNldCh0aGlzLm1pbi54LHRoaXMubWluLnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHZlWzJdLnNldCh0aGlzLm1pbi54LHRoaXMubWF4LnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzNdLnNldCh0aGlzLm1pbi54LHRoaXMubWF4LnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHZlWzRdLnNldCh0aGlzLm1heC54LHRoaXMubWluLnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzVdLnNldCh0aGlzLm1heC54LHRoaXMubWluLnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHZlWzZdLnNldCh0aGlzLm1heC54LHRoaXMubWF4LnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzddLnNldCh0aGlzLm1heC54LHRoaXMubWF4LnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHRoaXMuc2V0RnJvbVBvaW50cyh2ZSksdGhpcyl9dHJhbnNsYXRlKHQpe3JldHVybiB0aGlzLm1pbi5hZGQodCksdGhpcy5tYXguYWRkKHQpLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lm1pbi5lcXVhbHModGhpcy5taW4pJiZ0Lm1heC5lcXVhbHModGhpcy5tYXgpfXRvSlNPTigpe3JldHVybnttaW46dGhpcy5taW4udG9BcnJheSgpLG1heDp0aGlzLm1heC50b0FycmF5KCl9fWZyb21KU09OKHQpe3JldHVybiB0aGlzLm1pbi5mcm9tQXJyYXkodC5taW4pLHRoaXMubWF4LmZyb21BcnJheSh0Lm1heCksdGhpc319Y29uc3QgdmU9W25ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBUXSxjZT1uZXcgVCxhcz1uZXcgZ3QsTm49bmV3IFQsUm49bmV3IFQsTG49bmV3IFQsWGU9bmV3IFQsSmU9bmV3IFQsaG49bmV3IFQseGk9bmV3IFQsY3M9bmV3IFQsbHM9bmV3IFQsdW49bmV3IFQ7ZnVuY3Rpb24gb28oaSx0LGUsbixzKXtmb3IobGV0IHI9MCxvPWkubGVuZ3RoLTM7cjw9bztyKz0zKXt1bi5mcm9tQXJyYXkoaSxyKTtjb25zdCBhPXMueCpNYXRoLmFicyh1bi54KStzLnkqTWF0aC5hYnModW4ueSkrcy56Kk1hdGguYWJzKHVuLnopLGM9dC5kb3QodW4pLGw9ZS5kb3QodW4pLGg9bi5kb3QodW4pO2lmKE1hdGgubWF4KC1NYXRoLm1heChjLGwsaCksTWF0aC5taW4oYyxsLGgpKT5hKXJldHVybiExfXJldHVybiEwfWNvbnN0IHJmPW5ldyBndCx3aT1uZXcgVCxhbz1uZXcgVDtjbGFzcyBjb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9LTEpe3RoaXMuaXNTcGhlcmU9ITAsdGhpcy5jZW50ZXI9dCx0aGlzLnJhZGl1cz1lfXNldCh0LGUpe3JldHVybiB0aGlzLmNlbnRlci5jb3B5KHQpLHRoaXMucmFkaXVzPWUsdGhpc31zZXRGcm9tUG9pbnRzKHQsZSl7Y29uc3Qgbj10aGlzLmNlbnRlcjtlIT09dm9pZCAwP24uY29weShlKTpyZi5zZXRGcm9tUG9pbnRzKHQpLmdldENlbnRlcihuKTtsZXQgcz0wO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKylzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZCh0W3JdKSk7cmV0dXJuIHRoaXMucmFkaXVzPU1hdGguc3FydChzKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuY2VudGVyLmNvcHkodC5jZW50ZXIpLHRoaXMucmFkaXVzPXQucmFkaXVzLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLnJhZGl1czwwfW1ha2VFbXB0eSgpe3JldHVybiB0aGlzLmNlbnRlci5zZXQoMCwwLDApLHRoaXMucmFkaXVzPS0xLHRoaXN9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmNlbnRlcik8PXRoaXMucmFkaXVzKnRoaXMucmFkaXVzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKS10aGlzLnJhZGl1c31pbnRlcnNlY3RzU3BoZXJlKHQpe2NvbnN0IGU9dGhpcy5yYWRpdXMrdC5yYWRpdXM7cmV0dXJuIHQuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuY2VudGVyKTw9ZSplfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1NwaGVyZSh0aGlzKX1pbnRlcnNlY3RzUGxhbmUodCl7cmV0dXJuIE1hdGguYWJzKHQuZGlzdGFuY2VUb1BvaW50KHRoaXMuY2VudGVyKSk8PXRoaXMucmFkaXVzfWNsYW1wUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHQpO3JldHVybiBlLmNvcHkodCksbj50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyYmKGUuc3ViKHRoaXMuY2VudGVyKS5ub3JtYWxpemUoKSxlLm11bHRpcGx5U2NhbGFyKHRoaXMucmFkaXVzKS5hZGQodGhpcy5jZW50ZXIpKSxlfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT8odC5tYWtlRW1wdHkoKSx0KToodC5zZXQodGhpcy5jZW50ZXIsdGhpcy5jZW50ZXIpLHQuZXhwYW5kQnlTY2FsYXIodGhpcy5yYWRpdXMpLHQpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYXBwbHlNYXRyaXg0KHQpLHRoaXMucmFkaXVzPXRoaXMucmFkaXVzKnQuZ2V0TWF4U2NhbGVPbkF4aXMoKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYWRkKHQpLHRoaXN9ZXhwYW5kQnlQb2ludCh0KXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4gdGhpcy5jZW50ZXIuY29weSh0KSx0aGlzLnJhZGl1cz0wLHRoaXM7d2kuc3ViVmVjdG9ycyh0LHRoaXMuY2VudGVyKTtjb25zdCBlPXdpLmxlbmd0aFNxKCk7aWYoZT50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyl7Y29uc3Qgbj1NYXRoLnNxcnQoZSkscz0obi10aGlzLnJhZGl1cykqLjU7dGhpcy5jZW50ZXIuYWRkU2NhbGVkVmVjdG9yKHdpLHMvbiksdGhpcy5yYWRpdXMrPXN9cmV0dXJuIHRoaXN9dW5pb24odCl7cmV0dXJuIHQuaXNFbXB0eSgpP3RoaXM6dGhpcy5pc0VtcHR5KCk/KHRoaXMuY29weSh0KSx0aGlzKToodGhpcy5jZW50ZXIuZXF1YWxzKHQuY2VudGVyKT09PSEwP3RoaXMucmFkaXVzPU1hdGgubWF4KHRoaXMucmFkaXVzLHQucmFkaXVzKTooYW8uc3ViVmVjdG9ycyh0LmNlbnRlcix0aGlzLmNlbnRlcikuc2V0TGVuZ3RoKHQucmFkaXVzKSx0aGlzLmV4cGFuZEJ5UG9pbnQod2kuY29weSh0LmNlbnRlcikuYWRkKGFvKSksdGhpcy5leHBhbmRCeVBvaW50KHdpLmNvcHkodC5jZW50ZXIpLnN1YihhbykpKSx0aGlzKX1lcXVhbHModCl7cmV0dXJuIHQuY2VudGVyLmVxdWFscyh0aGlzLmNlbnRlcikmJnQucmFkaXVzPT09dGhpcy5yYWRpdXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfXRvSlNPTigpe3JldHVybntyYWRpdXM6dGhpcy5yYWRpdXMsY2VudGVyOnRoaXMuY2VudGVyLnRvQXJyYXkoKX19ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMucmFkaXVzPXQucmFkaXVzLHRoaXMuY2VudGVyLmZyb21BcnJheSh0LmNlbnRlciksdGhpc319Y29uc3QgemU9bmV3IFQsbG89bmV3IFQsaHM9bmV3IFQsWWU9bmV3IFQsaG89bmV3IFQsdXM9bmV3IFQsdW89bmV3IFQ7Y2xhc3MgZm97Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBUKDAsMCwtMSkpe3RoaXMub3JpZ2luPXQsdGhpcy5kaXJlY3Rpb249ZX1zZXQodCxlKXtyZXR1cm4gdGhpcy5vcmlnaW4uY29weSh0KSx0aGlzLmRpcmVjdGlvbi5jb3B5KGUpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5vcmlnaW4uY29weSh0Lm9yaWdpbiksdGhpcy5kaXJlY3Rpb24uY29weSh0LmRpcmVjdGlvbiksdGhpc31hdCh0LGUpe3JldHVybiBlLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbix0KX1sb29rQXQodCl7cmV0dXJuIHRoaXMuZGlyZWN0aW9uLmNvcHkodCkuc3ViKHRoaXMub3JpZ2luKS5ub3JtYWxpemUoKSx0aGlzfXJlY2FzdCh0KXtyZXR1cm4gdGhpcy5vcmlnaW4uY29weSh0aGlzLmF0KHQsemUpKSx0aGlzfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlKXtlLnN1YlZlY3RvcnModCx0aGlzLm9yaWdpbik7Y29uc3Qgbj1lLmRvdCh0aGlzLmRpcmVjdGlvbik7cmV0dXJuIG48MD9lLmNvcHkodGhpcy5vcmlnaW4pOmUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLG4pfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VTcVRvUG9pbnQodCkpfWRpc3RhbmNlU3FUb1BvaW50KHQpe2NvbnN0IGU9emUuc3ViVmVjdG9ycyh0LHRoaXMub3JpZ2luKS5kb3QodGhpcy5kaXJlY3Rpb24pO3JldHVybiBlPDA/dGhpcy5vcmlnaW4uZGlzdGFuY2VUb1NxdWFyZWQodCk6KHplLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbixlKSx6ZS5kaXN0YW5jZVRvU3F1YXJlZCh0KSl9ZGlzdGFuY2VTcVRvU2VnbWVudCh0LGUsbixzKXtsby5jb3B5KHQpLmFkZChlKS5tdWx0aXBseVNjYWxhciguNSksaHMuY29weShlKS5zdWIodCkubm9ybWFsaXplKCksWWUuY29weSh0aGlzLm9yaWdpbikuc3ViKGxvKTtjb25zdCByPXQuZGlzdGFuY2VUbyhlKSouNSxvPS10aGlzLmRpcmVjdGlvbi5kb3QoaHMpLGE9WWUuZG90KHRoaXMuZGlyZWN0aW9uKSxjPS1ZZS5kb3QoaHMpLGw9WWUubGVuZ3RoU3EoKSxoPU1hdGguYWJzKDEtbypvKTtsZXQgdSxmLGQscDtpZihoPjApaWYodT1vKmMtYSxmPW8qYS1jLHA9cipoLHU+PTApaWYoZj49LXApaWYoZjw9cCl7Y29uc3QgeT0xL2g7dSo9eSxmKj15LGQ9dSoodStvKmYrMiphKStmKihvKnUrZisyKmMpK2x9ZWxzZSBmPXIsdT1NYXRoLm1heCgwLC0obypmK2EpKSxkPS11KnUrZiooZisyKmMpK2w7ZWxzZSBmPS1yLHU9TWF0aC5tYXgoMCwtKG8qZithKSksZD0tdSp1K2YqKGYrMipjKStsO2Vsc2UgZjw9LXA/KHU9TWF0aC5tYXgoMCwtKC1vKnIrYSkpLGY9dT4wPy1yOk1hdGgubWluKE1hdGgubWF4KC1yLC1jKSxyKSxkPS11KnUrZiooZisyKmMpK2wpOmY8PXA/KHU9MCxmPU1hdGgubWluKE1hdGgubWF4KC1yLC1jKSxyKSxkPWYqKGYrMipjKStsKToodT1NYXRoLm1heCgwLC0obypyK2EpKSxmPXU+MD9yOk1hdGgubWluKE1hdGgubWF4KC1yLC1jKSxyKSxkPS11KnUrZiooZisyKmMpK2wpO2Vsc2UgZj1vPjA/LXI6cix1PU1hdGgubWF4KDAsLShvKmYrYSkpLGQ9LXUqdStmKihmKzIqYykrbDtyZXR1cm4gbiYmbi5jb3B5KHRoaXMub3JpZ2luKS5hZGRTY2FsZWRWZWN0b3IodGhpcy5kaXJlY3Rpb24sdSkscyYmcy5jb3B5KGxvKS5hZGRTY2FsZWRWZWN0b3IoaHMsZiksZH1pbnRlcnNlY3RTcGhlcmUodCxlKXt6ZS5zdWJWZWN0b3JzKHQuY2VudGVyLHRoaXMub3JpZ2luKTtjb25zdCBuPXplLmRvdCh0aGlzLmRpcmVjdGlvbikscz16ZS5kb3QoemUpLW4qbixyPXQucmFkaXVzKnQucmFkaXVzO2lmKHM+cilyZXR1cm4gbnVsbDtjb25zdCBvPU1hdGguc3FydChyLXMpLGE9bi1vLGM9bitvO3JldHVybiBjPDA/bnVsbDphPDA/dGhpcy5hdChjLGUpOnRoaXMuYXQoYSxlKX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0LnJhZGl1czwwPyExOnRoaXMuZGlzdGFuY2VTcVRvUG9pbnQodC5jZW50ZXIpPD10LnJhZGl1cyp0LnJhZGl1c31kaXN0YW5jZVRvUGxhbmUodCl7Y29uc3QgZT10Lm5vcm1hbC5kb3QodGhpcy5kaXJlY3Rpb24pO2lmKGU9PT0wKXJldHVybiB0LmRpc3RhbmNlVG9Qb2ludCh0aGlzLm9yaWdpbik9PT0wPzA6bnVsbDtjb25zdCBuPS0odGhpcy5vcmlnaW4uZG90KHQubm9ybWFsKSt0LmNvbnN0YW50KS9lO3JldHVybiBuPj0wP246bnVsbH1pbnRlcnNlY3RQbGFuZSh0LGUpe2NvbnN0IG49dGhpcy5kaXN0YW5jZVRvUGxhbmUodCk7cmV0dXJuIG49PT1udWxsP251bGw6dGhpcy5hdChuLGUpfWludGVyc2VjdHNQbGFuZSh0KXtjb25zdCBlPXQuZGlzdGFuY2VUb1BvaW50KHRoaXMub3JpZ2luKTtyZXR1cm4gZT09PTB8fHQubm9ybWFsLmRvdCh0aGlzLmRpcmVjdGlvbikqZTwwfWludGVyc2VjdEJveCh0LGUpe2xldCBuLHMscixvLGEsYztjb25zdCBsPTEvdGhpcy5kaXJlY3Rpb24ueCxoPTEvdGhpcy5kaXJlY3Rpb24ueSx1PTEvdGhpcy5kaXJlY3Rpb24ueixmPXRoaXMub3JpZ2luO3JldHVybiBsPj0wPyhuPSh0Lm1pbi54LWYueCkqbCxzPSh0Lm1heC54LWYueCkqbCk6KG49KHQubWF4LngtZi54KSpsLHM9KHQubWluLngtZi54KSpsKSxoPj0wPyhyPSh0Lm1pbi55LWYueSkqaCxvPSh0Lm1heC55LWYueSkqaCk6KHI9KHQubWF4LnktZi55KSpoLG89KHQubWluLnktZi55KSpoKSxuPm98fHI+c3x8KChyPm58fGlzTmFOKG4pKSYmKG49ciksKG88c3x8aXNOYU4ocykpJiYocz1vKSx1Pj0wPyhhPSh0Lm1pbi56LWYueikqdSxjPSh0Lm1heC56LWYueikqdSk6KGE9KHQubWF4LnotZi56KSp1LGM9KHQubWluLnotZi56KSp1KSxuPmN8fGE+cyl8fCgoYT5ufHxuIT09bikmJihuPWEpLChjPHN8fHMhPT1zKSYmKHM9YyksczwwKT9udWxsOnRoaXMuYXQobj49MD9uOnMsZSl9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdGhpcy5pbnRlcnNlY3RCb3godCx6ZSkhPT1udWxsfWludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHMscil7aG8uc3ViVmVjdG9ycyhlLHQpLHVzLnN1YlZlY3RvcnMobix0KSx1by5jcm9zc1ZlY3RvcnMoaG8sdXMpO2xldCBvPXRoaXMuZGlyZWN0aW9uLmRvdCh1byksYTtpZihvPjApe2lmKHMpcmV0dXJuIG51bGw7YT0xfWVsc2UgaWYobzwwKWE9LTEsbz0tbztlbHNlIHJldHVybiBudWxsO1llLnN1YlZlY3RvcnModGhpcy5vcmlnaW4sdCk7Y29uc3QgYz1hKnRoaXMuZGlyZWN0aW9uLmRvdCh1cy5jcm9zc1ZlY3RvcnMoWWUsdXMpKTtpZihjPDApcmV0dXJuIG51bGw7Y29uc3QgbD1hKnRoaXMuZGlyZWN0aW9uLmRvdChoby5jcm9zcyhZZSkpO2lmKGw8MHx8YytsPm8pcmV0dXJuIG51bGw7Y29uc3QgaD0tYSpZZS5kb3QodW8pO3JldHVybiBoPDA/bnVsbDp0aGlzLmF0KGgvbyxyKX1hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMub3JpZ2luLmFwcGx5TWF0cml4NCh0KSx0aGlzLmRpcmVjdGlvbi50cmFuc2Zvcm1EaXJlY3Rpb24odCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQub3JpZ2luLmVxdWFscyh0aGlzLm9yaWdpbikmJnQuZGlyZWN0aW9uLmVxdWFscyh0aGlzLmRpcmVjdGlvbil9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX1jbGFzcyBzdHtjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtzdC5wcm90b3R5cGUuaXNNYXRyaXg0PSEwLHRoaXMuZWxlbWVudHM9WzEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDFdLHQhPT12b2lkIDAmJnRoaXMuc2V0KHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pfXNldCh0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtjb25zdCBnPXRoaXMuZWxlbWVudHM7cmV0dXJuIGdbMF09dCxnWzRdPWUsZ1s4XT1uLGdbMTJdPXMsZ1sxXT1yLGdbNV09byxnWzldPWEsZ1sxM109YyxnWzJdPWwsZ1s2XT1oLGdbMTBdPXUsZ1sxNF09ZixnWzNdPWQsZ1s3XT1wLGdbMTFdPXksZ1sxNV09bSx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDEpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHN0KCkuZnJvbUFycmF5KHRoaXMuZWxlbWVudHMpfWNvcHkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVswXT1uWzBdLGVbMV09blsxXSxlWzJdPW5bMl0sZVszXT1uWzNdLGVbNF09bls0XSxlWzVdPW5bNV0sZVs2XT1uWzZdLGVbN109bls3XSxlWzhdPW5bOF0sZVs5XT1uWzldLGVbMTBdPW5bMTBdLGVbMTFdPW5bMTFdLGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLGVbMTVdPW5bMTVdLHRoaXN9Y29weVBvc2l0aW9uKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7cmV0dXJuIGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLHRoaXN9c2V0RnJvbU1hdHJpeDModCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLnNldChlWzBdLGVbM10sZVs2XSwwLGVbMV0sZVs0XSxlWzddLDAsZVsyXSxlWzVdLGVbOF0sMCwwLDAsMCwxKSx0aGlzfWV4dHJhY3RCYXNpcyh0LGUsbil7cmV0dXJuIHQuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDApLGUuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDEpLG4uc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDIpLHRoaXN9bWFrZUJhc2lzKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodC54LGUueCxuLngsMCx0LnksZS55LG4ueSwwLHQueixlLnosbi56LDAsMCwwLDAsMSksdGhpc31leHRyYWN0Um90YXRpb24odCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cyxzPTEvT24uc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLHI9MS9Pbi5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCksbz0xL09uLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gZVswXT1uWzBdKnMsZVsxXT1uWzFdKnMsZVsyXT1uWzJdKnMsZVszXT0wLGVbNF09bls0XSpyLGVbNV09bls1XSpyLGVbNl09bls2XSpyLGVbN109MCxlWzhdPW5bOF0qbyxlWzldPW5bOV0qbyxlWzEwXT1uWzEwXSpvLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21FdWxlcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10Lngscz10Lnkscj10Lnosbz1NYXRoLmNvcyhuKSxhPU1hdGguc2luKG4pLGM9TWF0aC5jb3MocyksbD1NYXRoLnNpbihzKSxoPU1hdGguY29zKHIpLHU9TWF0aC5zaW4ocik7aWYodC5vcmRlcj09PSJYWVoiKXtjb25zdCBmPW8qaCxkPW8qdSxwPWEqaCx5PWEqdTtlWzBdPWMqaCxlWzRdPS1jKnUsZVs4XT1sLGVbMV09ZCtwKmwsZVs1XT1mLXkqbCxlWzldPS1hKmMsZVsyXT15LWYqbCxlWzZdPXArZCpsLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWVhaIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mK3kqYSxlWzRdPXAqYS1kLGVbOF09bypsLGVbMV09byp1LGVbNV09bypoLGVbOV09LWEsZVsyXT1kKmEtcCxlWzZdPXkrZiphLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWlhZIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mLXkqYSxlWzRdPS1vKnUsZVs4XT1wK2QqYSxlWzFdPWQrcCphLGVbNV09bypoLGVbOV09eS1mKmEsZVsyXT0tbypsLGVbNl09YSxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IlpZWCIpe2NvbnN0IGY9bypoLGQ9byp1LHA9YSpoLHk9YSp1O2VbMF09YypoLGVbNF09cCpsLWQsZVs4XT1mKmwreSxlWzFdPWMqdSxlWzVdPXkqbCtmLGVbOV09ZCpsLXAsZVsyXT0tbCxlWzZdPWEqYyxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IllaWCIpe2NvbnN0IGY9bypjLGQ9bypsLHA9YSpjLHk9YSpsO2VbMF09YypoLGVbNF09eS1mKnUsZVs4XT1wKnUrZCxlWzFdPXUsZVs1XT1vKmgsZVs5XT0tYSpoLGVbMl09LWwqaCxlWzZdPWQqdStwLGVbMTBdPWYteSp1fWVsc2UgaWYodC5vcmRlcj09PSJYWlkiKXtjb25zdCBmPW8qYyxkPW8qbCxwPWEqYyx5PWEqbDtlWzBdPWMqaCxlWzRdPS11LGVbOF09bCpoLGVbMV09Zip1K3ksZVs1XT1vKmgsZVs5XT1kKnUtcCxlWzJdPXAqdS1kLGVbNl09YSpoLGVbMTBdPXkqdStmfXJldHVybiBlWzNdPTAsZVs3XT0wLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLmNvbXBvc2Uob2YsdCxhZil9bG9va0F0KHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuICR0LnN1YlZlY3RvcnModCxlKSwkdC5sZW5ndGhTcSgpPT09MCYmKCR0Lno9MSksJHQubm9ybWFsaXplKCksamUuY3Jvc3NWZWN0b3JzKG4sJHQpLGplLmxlbmd0aFNxKCk9PT0wJiYoTWF0aC5hYnMobi56KT09PTE/JHQueCs9MWUtNDokdC56Kz0xZS00LCR0Lm5vcm1hbGl6ZSgpLGplLmNyb3NzVmVjdG9ycyhuLCR0KSksamUubm9ybWFsaXplKCksZnMuY3Jvc3NWZWN0b3JzKCR0LGplKSxzWzBdPWplLngsc1s0XT1mcy54LHNbOF09JHQueCxzWzFdPWplLnksc1s1XT1mcy55LHNbOV09JHQueSxzWzJdPWplLnosc1s2XT1mcy56LHNbMTBdPSR0LnosdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0LHRoaXMpfW11bHRpcGx5TWF0cmljZXModCxlKXtjb25zdCBuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzLHI9dGhpcy5lbGVtZW50cyxvPW5bMF0sYT1uWzRdLGM9bls4XSxsPW5bMTJdLGg9blsxXSx1PW5bNV0sZj1uWzldLGQ9blsxM10scD1uWzJdLHk9bls2XSxtPW5bMTBdLGc9blsxNF0sYj1uWzNdLHc9bls3XSx4PW5bMTFdLE09blsxNV0sQT1zWzBdLFM9c1s0XSxfPXNbOF0sRT1zWzEyXSx6PXNbMV0sdj1zWzVdLEM9c1s5XSxQPXNbMTNdLEY9c1syXSxCPXNbNl0sST1zWzEwXSxrPXNbMTRdLEQ9c1szXSxVPXNbN10saj1zWzExXSxkdD1zWzE1XTtyZXR1cm4gclswXT1vKkErYSp6K2MqRitsKkQscls0XT1vKlMrYSp2K2MqQitsKlUscls4XT1vKl8rYSpDK2MqSStsKmosclsxMl09bypFK2EqUCtjKmsrbCpkdCxyWzFdPWgqQSt1KnorZipGK2QqRCxyWzVdPWgqUyt1KnYrZipCK2QqVSxyWzldPWgqXyt1KkMrZipJK2QqaixyWzEzXT1oKkUrdSpQK2YqaytkKmR0LHJbMl09cCpBK3kqeittKkYrZypELHJbNl09cCpTK3kqdittKkIrZypVLHJbMTBdPXAqXyt5KkMrbSpJK2cqaixyWzE0XT1wKkUreSpQK20qaytnKmR0LHJbM109YipBK3cqeit4KkYrTSpELHJbN109YipTK3cqdit4KkIrTSpVLHJbMTFdPWIqXyt3KkMreCpJK00qaixyWzE1XT1iKkUrdypQK3gqaytNKmR0LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiBlWzBdKj10LGVbNF0qPXQsZVs4XSo9dCxlWzEyXSo9dCxlWzFdKj10LGVbNV0qPXQsZVs5XSo9dCxlWzEzXSo9dCxlWzJdKj10LGVbNl0qPXQsZVsxMF0qPXQsZVsxNF0qPXQsZVszXSo9dCxlWzddKj10LGVbMTFdKj10LGVbMTVdKj10LHRoaXN9ZGV0ZXJtaW5hbnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFs0XSxzPXRbOF0scj10WzEyXSxvPXRbMV0sYT10WzVdLGM9dFs5XSxsPXRbMTNdLGg9dFsyXSx1PXRbNl0sZj10WzEwXSxkPXRbMTRdLHA9dFszXSx5PXRbN10sbT10WzExXSxnPXRbMTVdO3JldHVybiBwKigrcipjKnUtcypsKnUtciphKmYrbipsKmYrcyphKmQtbipjKmQpK3kqKCtlKmMqZC1lKmwqZityKm8qZi1zKm8qZCtzKmwqaC1yKmMqaCkrbSooK2UqbCp1LWUqYSpkLXIqbyp1K24qbypkK3IqYSpoLW4qbCpoKStnKigtcyphKmgtZSpjKnUrZSphKmYrcypvKnUtbipvKmYrbipjKmgpfXRyYW5zcG9zZSgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cztsZXQgZTtyZXR1cm4gZT10WzFdLHRbMV09dFs0XSx0WzRdPWUsZT10WzJdLHRbMl09dFs4XSx0WzhdPWUsZT10WzZdLHRbNl09dFs5XSx0WzldPWUsZT10WzNdLHRbM109dFsxMl0sdFsxMl09ZSxlPXRbN10sdFs3XT10WzEzXSx0WzEzXT1lLGU9dFsxMV0sdFsxMV09dFsxNF0sdFsxNF09ZSx0aGlzfXNldFBvc2l0aW9uKHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuIHQuaXNWZWN0b3IzPyhzWzEyXT10Lngsc1sxM109dC55LHNbMTRdPXQueik6KHNbMTJdPXQsc1sxM109ZSxzWzE0XT1uKSx0aGlzfWludmVydCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSx1PXRbOV0sZj10WzEwXSxkPXRbMTFdLHA9dFsxMl0seT10WzEzXSxtPXRbMTRdLGc9dFsxNV0sYj11Km0qbC15KmYqbCt5KmMqZC1hKm0qZC11KmMqZythKmYqZyx3PXAqZipsLWgqbSpsLXAqYypkK28qbSpkK2gqYypnLW8qZipnLHg9aCp5KmwtcCp1KmwrcCphKmQtbyp5KmQtaCphKmcrbyp1KmcsTT1wKnUqYy1oKnkqYy1wKmEqZitvKnkqZitoKmEqbS1vKnUqbSxBPWUqYituKncrcyp4K3IqTTtpZihBPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCk7Y29uc3QgUz0xL0E7cmV0dXJuIHRbMF09YipTLHRbMV09KHkqZipyLXUqbSpyLXkqcypkK24qbSpkK3UqcypnLW4qZipnKSpTLHRbMl09KGEqbSpyLXkqYypyK3kqcypsLW4qbSpsLWEqcypnK24qYypnKSpTLHRbM109KHUqYypyLWEqZipyLXUqcypsK24qZipsK2EqcypkLW4qYypkKSpTLHRbNF09dypTLHRbNV09KGgqbSpyLXAqZipyK3AqcypkLWUqbSpkLWgqcypnK2UqZipnKSpTLHRbNl09KHAqYypyLW8qbSpyLXAqcypsK2UqbSpsK28qcypnLWUqYypnKSpTLHRbN109KG8qZipyLWgqYypyK2gqcypsLWUqZipsLW8qcypkK2UqYypkKSpTLHRbOF09eCpTLHRbOV09KHAqdSpyLWgqeSpyLXAqbipkK2UqeSpkK2gqbipnLWUqdSpnKSpTLHRbMTBdPShvKnkqci1wKmEqcitwKm4qbC1lKnkqbC1vKm4qZytlKmEqZykqUyx0WzExXT0oaCphKnItbyp1KnItaCpuKmwrZSp1KmwrbypuKmQtZSphKmQpKlMsdFsxMl09TSpTLHRbMTNdPShoKnkqcy1wKnUqcytwKm4qZi1lKnkqZi1oKm4qbStlKnUqbSkqUyx0WzE0XT0ocCphKnMtbyp5KnMtcCpuKmMrZSp5KmMrbypuKm0tZSphKm0pKlMsdFsxNV09KG8qdSpzLWgqYSpzK2gqbipjLWUqdSpjLW8qbipmK2UqYSpmKSpTLHRoaXN9c2NhbGUodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC54LHM9dC55LHI9dC56O3JldHVybiBlWzBdKj1uLGVbNF0qPXMsZVs4XSo9cixlWzFdKj1uLGVbNV0qPXMsZVs5XSo9cixlWzJdKj1uLGVbNl0qPXMsZVsxMF0qPXIsZVszXSo9bixlWzddKj1zLGVbMTFdKj1yLHRoaXN9Z2V0TWF4U2NhbGVPbkF4aXMoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdKnRbMF0rdFsxXSp0WzFdK3RbMl0qdFsyXSxuPXRbNF0qdFs0XSt0WzVdKnRbNV0rdFs2XSp0WzZdLHM9dFs4XSp0WzhdK3RbOV0qdFs5XSt0WzEwXSp0WzEwXTtyZXR1cm4gTWF0aC5zcXJ0KE1hdGgubWF4KGUsbixzKSl9bWFrZVRyYW5zbGF0aW9uKHQsZSxuKXtyZXR1cm4gdC5pc1ZlY3RvcjM/dGhpcy5zZXQoMSwwLDAsdC54LDAsMSwwLHQueSwwLDAsMSx0LnosMCwwLDAsMSk6dGhpcy5zZXQoMSwwLDAsdCwwLDEsMCxlLDAsMCwxLG4sMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25YKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwwLGUsLW4sMCwwLG4sZSwwLDAsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uWSh0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsMCxuLDAsMCwxLDAsMCwtbiwwLGUsMCwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbloodCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldChlLC1uLDAsMCxuLGUsMCwwLDAsMCwxLDAsMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25BeGlzKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9MS1uLG89dC54LGE9dC55LGM9dC56LGw9cipvLGg9ciphO3JldHVybiB0aGlzLnNldChsKm8rbixsKmEtcypjLGwqYytzKmEsMCxsKmErcypjLGgqYStuLGgqYy1zKm8sMCxsKmMtcyphLGgqYytzKm8scipjKmMrbiwwLDAsMCwwLDEpLHRoaXN9bWFrZVNjYWxlKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodCwwLDAsMCwwLGUsMCwwLDAsMCxuLDAsMCwwLDAsMSksdGhpc31tYWtlU2hlYXIodCxlLG4scyxyLG8pe3JldHVybiB0aGlzLnNldCgxLG4sciwwLHQsMSxvLDAsZSxzLDEsMCwwLDAsMCwxKSx0aGlzfWNvbXBvc2UodCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cyxyPWUuX3gsbz1lLl95LGE9ZS5feixjPWUuX3csbD1yK3IsaD1vK28sdT1hK2EsZj1yKmwsZD1yKmgscD1yKnUseT1vKmgsbT1vKnUsZz1hKnUsYj1jKmwsdz1jKmgseD1jKnUsTT1uLngsQT1uLnksUz1uLno7cmV0dXJuIHNbMF09KDEtKHkrZykpKk0sc1sxXT0oZCt4KSpNLHNbMl09KHAtdykqTSxzWzNdPTAsc1s0XT0oZC14KSpBLHNbNV09KDEtKGYrZykpKkEsc1s2XT0obStiKSpBLHNbN109MCxzWzhdPShwK3cpKlMsc1s5XT0obS1iKSpTLHNbMTBdPSgxLShmK3kpKSpTLHNbMTFdPTAsc1sxMl09dC54LHNbMTNdPXQueSxzWzE0XT10Lnosc1sxNV09MSx0aGlzfWRlY29tcG9zZSh0LGUsbil7Y29uc3Qgcz10aGlzLmVsZW1lbnRzO2xldCByPU9uLnNldChzWzBdLHNbMV0sc1syXSkubGVuZ3RoKCk7Y29uc3Qgbz1Pbi5zZXQoc1s0XSxzWzVdLHNbNl0pLmxlbmd0aCgpLGE9T24uc2V0KHNbOF0sc1s5XSxzWzEwXSkubGVuZ3RoKCk7dGhpcy5kZXRlcm1pbmFudCgpPDAmJihyPS1yKSx0Lng9c1sxMl0sdC55PXNbMTNdLHQuej1zWzE0XSxsZS5jb3B5KHRoaXMpO2NvbnN0IGw9MS9yLGg9MS9vLHU9MS9hO3JldHVybiBsZS5lbGVtZW50c1swXSo9bCxsZS5lbGVtZW50c1sxXSo9bCxsZS5lbGVtZW50c1syXSo9bCxsZS5lbGVtZW50c1s0XSo9aCxsZS5lbGVtZW50c1s1XSo9aCxsZS5lbGVtZW50c1s2XSo9aCxsZS5lbGVtZW50c1s4XSo9dSxsZS5lbGVtZW50c1s5XSo9dSxsZS5lbGVtZW50c1sxMF0qPXUsZS5zZXRGcm9tUm90YXRpb25NYXRyaXgobGUpLG4ueD1yLG4ueT1vLG4uej1hLHRoaXN9bWFrZVBlcnNwZWN0aXZlKHQsZSxuLHMscixvLGE9MmUzKXtjb25zdCBjPXRoaXMuZWxlbWVudHMsbD0yKnIvKGUtdCksaD0yKnIvKG4tcyksdT0oZSt0KS8oZS10KSxmPShuK3MpLyhuLXMpO2xldCBkLHA7aWYoYT09PTJlMylkPS0obytyKS8oby1yKSxwPS0yKm8qci8oby1yKTtlbHNlIGlmKGE9PT0yMDAxKWQ9LW8vKG8tcikscD0tbypyLyhvLXIpO2Vsc2UgdGhyb3cgbmV3IEVycm9yKCJUSFJFRS5NYXRyaXg0Lm1ha2VQZXJzcGVjdGl2ZSgpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPWwsY1s0XT0wLGNbOF09dSxjWzEyXT0wLGNbMV09MCxjWzVdPWgsY1s5XT1mLGNbMTNdPTAsY1syXT0wLGNbNl09MCxjWzEwXT1kLGNbMTRdPXAsY1szXT0wLGNbN109MCxjWzExXT0tMSxjWzE1XT0wLHRoaXN9bWFrZU9ydGhvZ3JhcGhpYyh0LGUsbixzLHIsbyxhPTJlMyl7Y29uc3QgYz10aGlzLmVsZW1lbnRzLGw9MS8oZS10KSxoPTEvKG4tcyksdT0xLyhvLXIpLGY9KGUrdCkqbCxkPShuK3MpKmg7bGV0IHAseTtpZihhPT09MmUzKXA9KG8rcikqdSx5PS0yKnU7ZWxzZSBpZihhPT09MjAwMSlwPXIqdSx5PS0xKnU7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIlRIUkVFLk1hdHJpeDQubWFrZU9ydGhvZ3JhcGhpYygpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPTIqbCxjWzRdPTAsY1s4XT0wLGNbMTJdPS1mLGNbMV09MCxjWzVdPTIqaCxjWzldPTAsY1sxM109LWQsY1syXT0wLGNbNl09MCxjWzEwXT15LGNbMTRdPS1wLGNbM109MCxjWzddPTAsY1sxMV09MCxjWzE1XT0xLHRoaXN9ZXF1YWxzKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7Zm9yKGxldCBzPTA7czwxNjtzKyspaWYoZVtzXSE9PW5bc10pcmV0dXJuITE7cmV0dXJuITB9ZnJvbUFycmF5KHQsZT0wKXtmb3IobGV0IG49MDtuPDE2O24rKyl0aGlzLmVsZW1lbnRzW25dPXRbbitlXTtyZXR1cm4gdGhpc310b0FycmF5KHQ9W10sZT0wKXtjb25zdCBuPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbZV09blswXSx0W2UrMV09blsxXSx0W2UrMl09blsyXSx0W2UrM109blszXSx0W2UrNF09bls0XSx0W2UrNV09bls1XSx0W2UrNl09bls2XSx0W2UrN109bls3XSx0W2UrOF09bls4XSx0W2UrOV09bls5XSx0W2UrMTBdPW5bMTBdLHRbZSsxMV09blsxMV0sdFtlKzEyXT1uWzEyXSx0W2UrMTNdPW5bMTNdLHRbZSsxNF09blsxNF0sdFtlKzE1XT1uWzE1XSx0fX1jb25zdCBPbj1uZXcgVCxsZT1uZXcgc3Qsb2Y9bmV3IFQoMCwwLDApLGFmPW5ldyBUKDEsMSwxKSxqZT1uZXcgVCxmcz1uZXcgVCwkdD1uZXcgVCxFYz1uZXcgc3QsUGM9bmV3IGdpO2NsYXNzIGJpe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9YmkuREVGQVVMVF9PUkRFUil7dGhpcy5pc0V1bGVyPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXN9Z2V0IHgoKXtyZXR1cm4gdGhpcy5feH1zZXQgeCh0KXt0aGlzLl94PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB5KCl7cmV0dXJuIHRoaXMuX3l9c2V0IHkodCl7dGhpcy5feT10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeigpe3JldHVybiB0aGlzLl96fXNldCB6KHQpe3RoaXMuX3o9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IG9yZGVyKCl7cmV0dXJuIHRoaXMuX29yZGVyfXNldCBvcmRlcih0KXt0aGlzLl9vcmRlcj10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scz10aGlzLl9vcmRlcil7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXMsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5feCx0aGlzLl95LHRoaXMuX3osdGhpcy5fb3JkZXIpfWNvcHkodCl7cmV0dXJuIHRoaXMuX3g9dC5feCx0aGlzLl95PXQuX3ksdGhpcy5fej10Ll96LHRoaXMuX29yZGVyPXQuX29yZGVyLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0LGU9dGhpcy5fb3JkZXIsbj0hMCl7Y29uc3Qgcz10LmVsZW1lbnRzLHI9c1swXSxvPXNbNF0sYT1zWzhdLGM9c1sxXSxsPXNbNV0saD1zWzldLHU9c1syXSxmPXNbNl0sZD1zWzEwXTtzd2l0Y2goZSl7Y2FzZSJYWVoiOnRoaXMuX3k9TWF0aC5hc2luKFooYSwtMSwxKSksTWF0aC5hYnMoYSk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMigtaCxkKSx0aGlzLl96PU1hdGguYXRhbjIoLW8scikpOih0aGlzLl94PU1hdGguYXRhbjIoZixsKSx0aGlzLl96PTApO2JyZWFrO2Nhc2UiWVhaIjp0aGlzLl94PU1hdGguYXNpbigtWihoLC0xLDEpKSxNYXRoLmFicyhoKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKGEsZCksdGhpcy5fej1NYXRoLmF0YW4yKGMsbCkpOih0aGlzLl95PU1hdGguYXRhbjIoLXUsciksdGhpcy5fej0wKTticmVhaztjYXNlIlpYWSI6dGhpcy5feD1NYXRoLmFzaW4oWihmLC0xLDEpKSxNYXRoLmFicyhmKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKC11LGQpLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxsKSk6KHRoaXMuX3k9MCx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3k9TWF0aC5hc2luKC1aKHUsLTEsMSkpLE1hdGguYWJzKHUpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoZixkKSx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk6KHRoaXMuX3g9MCx0aGlzLl96PU1hdGguYXRhbjIoLW8sbCkpO2JyZWFrO2Nhc2UiWVpYIjp0aGlzLl96PU1hdGguYXNpbihaKGMsLTEsMSkpLE1hdGguYWJzKGMpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoLWgsbCksdGhpcy5feT1NYXRoLmF0YW4yKC11LHIpKToodGhpcy5feD0wLHRoaXMuX3k9TWF0aC5hdGFuMihhLGQpKTticmVhaztjYXNlIlhaWSI6dGhpcy5fej1NYXRoLmFzaW4oLVoobywtMSwxKSksTWF0aC5hYnMobyk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMihmLGwpLHRoaXMuX3k9TWF0aC5hdGFuMihhLHIpKToodGhpcy5feD1NYXRoLmF0YW4yKC1oLGQpLHRoaXMuX3k9MCk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkV1bGVyOiAuc2V0RnJvbVJvdGF0aW9uTWF0cml4KCkgZW5jb3VudGVyZWQgYW4gdW5rbm93biBvcmRlcjogIitlKX1yZXR1cm4gdGhpcy5fb3JkZXI9ZSxuPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21RdWF0ZXJuaW9uKHQsZSxuKXtyZXR1cm4gRWMubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCksdGhpcy5zZXRGcm9tUm90YXRpb25NYXRyaXgoRWMsZSxuKX1zZXRGcm9tVmVjdG9yMyh0LGU9dGhpcy5fb3JkZXIpe3JldHVybiB0aGlzLnNldCh0LngsdC55LHQueixlKX1yZW9yZGVyKHQpe3JldHVybiBQYy5zZXRGcm9tRXVsZXIodGhpcyksdGhpcy5zZXRGcm9tUXVhdGVybmlvbihQYyx0KX1lcXVhbHModCl7cmV0dXJuIHQuX3g9PT10aGlzLl94JiZ0Ll95PT09dGhpcy5feSYmdC5fej09PXRoaXMuX3omJnQuX29yZGVyPT09dGhpcy5fb3JkZXJ9ZnJvbUFycmF5KHQpe3JldHVybiB0aGlzLl94PXRbMF0sdGhpcy5feT10WzFdLHRoaXMuX3o9dFsyXSx0WzNdIT09dm9pZCAwJiYodGhpcy5fb3JkZXI9dFszXSksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy5feCx0W2UrMV09dGhpcy5feSx0W2UrMl09dGhpcy5feix0W2UrM109dGhpcy5fb3JkZXIsdH1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX29yZGVyfX1iaS5ERUZBVUxUX09SREVSPSJYWVoiO2NsYXNzIGNme2NvbnN0cnVjdG9yKCl7dGhpcy5tYXNrPTF9c2V0KHQpe3RoaXMubWFzaz0oMTw8dHwwKT4+PjB9ZW5hYmxlKHQpe3RoaXMubWFza3w9MTw8dHwwfWVuYWJsZUFsbCgpe3RoaXMubWFzaz0tMX10b2dnbGUodCl7dGhpcy5tYXNrXj0xPDx0fDB9ZGlzYWJsZSh0KXt0aGlzLm1hc2smPX4oMTw8dHwwKX1kaXNhYmxlQWxsKCl7dGhpcy5tYXNrPTB9dGVzdCh0KXtyZXR1cm4odGhpcy5tYXNrJnQubWFzaykhPT0wfWlzRW5hYmxlZCh0KXtyZXR1cm4odGhpcy5tYXNrJigxPDx0fDApKSE9PTB9fWxldCBsZj0wO2NvbnN0IENjPW5ldyBULERuPW5ldyBnaSxUZT1uZXcgc3QsZHM9bmV3IFQsTWk9bmV3IFQsaGY9bmV3IFQsdWY9bmV3IGdpLEJjPW5ldyBUKDEsMCwwKSxGYz1uZXcgVCgwLDEsMCksSWM9bmV3IFQoMCwwLDEpLGtjPXt0eXBlOiJhZGRlZCJ9LGZmPXt0eXBlOiJyZW1vdmVkIn0sJG49e3R5cGU6ImNoaWxkYWRkZWQiLGNoaWxkOm51bGx9LHBvPXt0eXBlOiJjaGlsZHJlbW92ZWQiLGNoaWxkOm51bGx9O2NsYXNzIEVlIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNPYmplY3QzRD0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpsZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iT2JqZWN0M0QiLHRoaXMucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbj1bXSx0aGlzLnVwPUVlLkRFRkFVTFRfVVAuY2xvbmUoKTtjb25zdCB0PW5ldyBULGU9bmV3IGJpLG49bmV3IGdpLHM9bmV3IFQoMSwxLDEpO2Z1bmN0aW9uIHIoKXtuLnNldEZyb21FdWxlcihlLCExKX1mdW5jdGlvbiBvKCl7ZS5zZXRGcm9tUXVhdGVybmlvbihuLHZvaWQgMCwhMSl9ZS5fb25DaGFuZ2Uociksbi5fb25DaGFuZ2UobyksT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcyx7cG9zaXRpb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOnR9LHJvdGF0aW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTplfSxxdWF0ZXJuaW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTpufSxzY2FsZTp7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITAsdmFsdWU6c30sbW9kZWxWaWV3TWF0cml4Ont2YWx1ZTpuZXcgc3R9LG5vcm1hbE1hdHJpeDp7dmFsdWU6bmV3IGdlfX0pLHRoaXMubWF0cml4PW5ldyBzdCx0aGlzLm1hdHJpeFdvcmxkPW5ldyBzdCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9RWUuREVGQVVMVF9NQVRSSVhfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9RWUuREVGQVVMVF9NQVRSSVhfV09STERfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSExLHRoaXMubGF5ZXJzPW5ldyBjZix0aGlzLnZpc2libGU9ITAsdGhpcy5jYXN0U2hhZG93PSExLHRoaXMucmVjZWl2ZVNoYWRvdz0hMSx0aGlzLmZydXN0dW1DdWxsZWQ9ITAsdGhpcy5yZW5kZXJPcmRlcj0wLHRoaXMuYW5pbWF0aW9ucz1bXSx0aGlzLmN1c3RvbURlcHRoTWF0ZXJpYWw9dm9pZCAwLHRoaXMuY3VzdG9tRGlzdGFuY2VNYXRlcmlhbD12b2lkIDAsdGhpcy51c2VyRGF0YT17fX1vbkJlZm9yZVNoYWRvdygpe31vbkFmdGVyU2hhZG93KCl7fW9uQmVmb3JlUmVuZGVyKCl7fW9uQWZ0ZXJSZW5kZXIoKXt9YXBwbHlNYXRyaXg0KHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSx0aGlzLm1hdHJpeC5wcmVtdWx0aXBseSh0KSx0aGlzLm1hdHJpeC5kZWNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSl9YXBwbHlRdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkodCksdGhpc31zZXRSb3RhdGlvbkZyb21BeGlzQW5nbGUodCxlKXt0aGlzLnF1YXRlcm5pb24uc2V0RnJvbUF4aXNBbmdsZSh0LGUpfXNldFJvdGF0aW9uRnJvbUV1bGVyKHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tRXVsZXIodCwhMCl9c2V0Um90YXRpb25Gcm9tTWF0cml4KHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgodCl9c2V0Um90YXRpb25Gcm9tUXVhdGVybmlvbih0KXt0aGlzLnF1YXRlcm5pb24uY29weSh0KX1yb3RhdGVPbkF4aXModCxlKXtyZXR1cm4gRG4uc2V0RnJvbUF4aXNBbmdsZSh0LGUpLHRoaXMucXVhdGVybmlvbi5tdWx0aXBseShEbiksdGhpc31yb3RhdGVPbldvcmxkQXhpcyh0LGUpe3JldHVybiBEbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KERuKSx0aGlzfXJvdGF0ZVgodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEJjLHQpfXJvdGF0ZVkodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEZjLHQpfXJvdGF0ZVoodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEljLHQpfXRyYW5zbGF0ZU9uQXhpcyh0LGUpe3JldHVybiBDYy5jb3B5KHQpLmFwcGx5UXVhdGVybmlvbih0aGlzLnF1YXRlcm5pb24pLHRoaXMucG9zaXRpb24uYWRkKENjLm11bHRpcGx5U2NhbGFyKGUpKSx0aGlzfXRyYW5zbGF0ZVgodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEJjLHQpfXRyYW5zbGF0ZVkodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEZjLHQpfXRyYW5zbGF0ZVoodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEljLHQpfWxvY2FsVG9Xb3JsZCh0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdC5hcHBseU1hdHJpeDQodGhpcy5tYXRyaXhXb3JsZCl9d29ybGRUb0xvY2FsKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0LmFwcGx5TWF0cml4NChUZS5jb3B5KHRoaXMubWF0cml4V29ybGQpLmludmVydCgpKX1sb29rQXQodCxlLG4pe3QuaXNWZWN0b3IzP2RzLmNvcHkodCk6ZHMuc2V0KHQsZSxuKTtjb25zdCBzPXRoaXMucGFyZW50O3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLE1pLnNldEZyb21NYXRyaXhQb3NpdGlvbih0aGlzLm1hdHJpeFdvcmxkKSx0aGlzLmlzQ2FtZXJhfHx0aGlzLmlzTGlnaHQ/VGUubG9va0F0KE1pLGRzLHRoaXMudXApOlRlLmxvb2tBdChkcyxNaSx0aGlzLnVwKSx0aGlzLnF1YXRlcm5pb24uc2V0RnJvbVJvdGF0aW9uTWF0cml4KFRlKSxzJiYoVGUuZXh0cmFjdFJvdGF0aW9uKHMubWF0cml4V29ybGQpLERuLnNldEZyb21Sb3RhdGlvbk1hdHJpeChUZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KERuLmludmVydCgpKSl9YWRkKHQpe2lmKGFyZ3VtZW50cy5sZW5ndGg+MSl7Zm9yKGxldCBlPTA7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl0aGlzLmFkZChhcmd1bWVudHNbZV0pO3JldHVybiB0aGlzfXJldHVybiB0PT09dGhpcz8oY29uc29sZS5lcnJvcigiVEhSRUUuT2JqZWN0M0QuYWRkOiBvYmplY3QgY2FuJ3QgYmUgYWRkZWQgYXMgYSBjaGlsZCBvZiBpdHNlbGYuIix0KSx0aGlzKToodCYmdC5pc09iamVjdDNEPyh0LnJlbW92ZUZyb21QYXJlbnQoKSx0LnBhcmVudD10aGlzLHRoaXMuY2hpbGRyZW4ucHVzaCh0KSx0LmRpc3BhdGNoRXZlbnQoa2MpLCRuLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KCRuKSwkbi5jaGlsZD1udWxsKTpjb25zb2xlLmVycm9yKCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBub3QgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuT2JqZWN0M0QuIix0KSx0aGlzKX1yZW1vdmUodCl7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IobGV0IG49MDtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXRoaXMucmVtb3ZlKGFyZ3VtZW50c1tuXSk7cmV0dXJuIHRoaXN9Y29uc3QgZT10aGlzLmNoaWxkcmVuLmluZGV4T2YodCk7cmV0dXJuIGUhPT0tMSYmKHQucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbi5zcGxpY2UoZSwxKSx0LmRpc3BhdGNoRXZlbnQoZmYpLHBvLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KHBvKSxwby5jaGlsZD1udWxsKSx0aGlzfXJlbW92ZUZyb21QYXJlbnQoKXtjb25zdCB0PXRoaXMucGFyZW50O3JldHVybiB0IT09bnVsbCYmdC5yZW1vdmUodGhpcyksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLnJlbW92ZSguLi50aGlzLmNoaWxkcmVuKX1hdHRhY2godCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLFRlLmNvcHkodGhpcy5tYXRyaXhXb3JsZCkuaW52ZXJ0KCksdC5wYXJlbnQhPT1udWxsJiYodC5wYXJlbnQudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLFRlLm11bHRpcGx5KHQucGFyZW50Lm1hdHJpeFdvcmxkKSksdC5hcHBseU1hdHJpeDQoVGUpLHQucmVtb3ZlRnJvbVBhcmVudCgpLHQucGFyZW50PXRoaXMsdGhpcy5jaGlsZHJlbi5wdXNoKHQpLHQudXBkYXRlV29ybGRNYXRyaXgoITEsITApLHQuZGlzcGF0Y2hFdmVudChrYyksJG4uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQoJG4pLCRuLmNoaWxkPW51bGwsdGhpc31nZXRPYmplY3RCeUlkKHQpe3JldHVybiB0aGlzLmdldE9iamVjdEJ5UHJvcGVydHkoImlkIix0KX1nZXRPYmplY3RCeU5hbWUodCl7cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlQcm9wZXJ0eSgibmFtZSIsdCl9Z2V0T2JqZWN0QnlQcm9wZXJ0eSh0LGUpe2lmKHRoaXNbdF09PT1lKXJldHVybiB0aGlzO2ZvcihsZXQgbj0wLHM9dGhpcy5jaGlsZHJlbi5sZW5ndGg7bjxzO24rKyl7Y29uc3Qgbz10aGlzLmNoaWxkcmVuW25dLmdldE9iamVjdEJ5UHJvcGVydHkodCxlKTtpZihvIT09dm9pZCAwKXJldHVybiBvfX1nZXRPYmplY3RzQnlQcm9wZXJ0eSh0LGUsbj1bXSl7dGhpc1t0XT09PWUmJm4ucHVzaCh0aGlzKTtjb25zdCBzPXRoaXMuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXNbcl0uZ2V0T2JqZWN0c0J5UHJvcGVydHkodCxlLG4pO3JldHVybiBufWdldFdvcmxkUG9zaXRpb24odCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHQuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKHRoaXMubWF0cml4V29ybGQpfWdldFdvcmxkUXVhdGVybmlvbih0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdGhpcy5tYXRyaXhXb3JsZC5kZWNvbXBvc2UoTWksdCxoZiksdH1nZXRXb3JsZFNjYWxlKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZShNaSx1Zix0KSx0fWdldFdvcmxkRGlyZWN0aW9uKHQpe3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpO2NvbnN0IGU9dGhpcy5tYXRyaXhXb3JsZC5lbGVtZW50cztyZXR1cm4gdC5zZXQoZVs4XSxlWzldLGVbMTBdKS5ub3JtYWxpemUoKX1yYXljYXN0KCl7fXRyYXZlcnNlKHQpe3QodGhpcyk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnRyYXZlcnNlKHQpfXRyYXZlcnNlVmlzaWJsZSh0KXtpZih0aGlzLnZpc2libGU9PT0hMSlyZXR1cm47dCh0aGlzKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udHJhdmVyc2VWaXNpYmxlKHQpfXRyYXZlcnNlQW5jZXN0b3JzKHQpe2NvbnN0IGU9dGhpcy5wYXJlbnQ7ZSE9PW51bGwmJih0KGUpLGUudHJhdmVyc2VBbmNlc3RvcnModCkpfXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LmNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSksdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSEwfXVwZGF0ZU1hdHJpeFdvcmxkKHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSwodGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlfHx0KSYmKHRoaXMubWF0cml4V29ybGRBdXRvVXBkYXRlPT09ITAmJih0aGlzLnBhcmVudD09PW51bGw/dGhpcy5tYXRyaXhXb3JsZC5jb3B5KHRoaXMubWF0cml4KTp0aGlzLm1hdHJpeFdvcmxkLm11bHRpcGx5TWF0cmljZXModGhpcy5wYXJlbnQubWF0cml4V29ybGQsdGhpcy5tYXRyaXgpKSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITEsdD0hMCk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnVwZGF0ZU1hdHJpeFdvcmxkKHQpfXVwZGF0ZVdvcmxkTWF0cml4KHQsZSl7Y29uc3Qgbj10aGlzLnBhcmVudDtpZih0PT09ITAmJm4hPT1udWxsJiZuLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeEF1dG9VcGRhdGUmJnRoaXMudXBkYXRlTWF0cml4KCksdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9PT0hMCYmKHRoaXMucGFyZW50PT09bnVsbD90aGlzLm1hdHJpeFdvcmxkLmNvcHkodGhpcy5tYXRyaXgpOnRoaXMubWF0cml4V29ybGQubXVsdGlwbHlNYXRyaWNlcyh0aGlzLnBhcmVudC5tYXRyaXhXb3JsZCx0aGlzLm1hdHJpeCkpLGU9PT0hMCl7Y29uc3Qgcz10aGlzLmNoaWxkcmVuO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLnVwZGF0ZVdvcmxkTWF0cml4KCExLCEwKX19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciLG49e307ZSYmKHQ9e2dlb21ldHJpZXM6e30sbWF0ZXJpYWxzOnt9LHRleHR1cmVzOnt9LGltYWdlczp7fSxzaGFwZXM6e30sc2tlbGV0b25zOnt9LGFuaW1hdGlvbnM6e30sbm9kZXM6e319LG4ubWV0YWRhdGE9e3ZlcnNpb246NC43LHR5cGU6Ik9iamVjdCIsZ2VuZXJhdG9yOiJPYmplY3QzRC50b0pTT04ifSk7Y29uc3Qgcz17fTtzLnV1aWQ9dGhpcy51dWlkLHMudHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJihzLm5hbWU9dGhpcy5uYW1lKSx0aGlzLmNhc3RTaGFkb3c9PT0hMCYmKHMuY2FzdFNoYWRvdz0hMCksdGhpcy5yZWNlaXZlU2hhZG93PT09ITAmJihzLnJlY2VpdmVTaGFkb3c9ITApLHRoaXMudmlzaWJsZT09PSExJiYocy52aXNpYmxlPSExKSx0aGlzLmZydXN0dW1DdWxsZWQ9PT0hMSYmKHMuZnJ1c3R1bUN1bGxlZD0hMSksdGhpcy5yZW5kZXJPcmRlciE9PTAmJihzLnJlbmRlck9yZGVyPXRoaXMucmVuZGVyT3JkZXIpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYocy51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSxzLmxheWVycz10aGlzLmxheWVycy5tYXNrLHMubWF0cml4PXRoaXMubWF0cml4LnRvQXJyYXkoKSxzLnVwPXRoaXMudXAudG9BcnJheSgpLHRoaXMubWF0cml4QXV0b1VwZGF0ZT09PSExJiYocy5tYXRyaXhBdXRvVXBkYXRlPSExKSx0aGlzLmlzSW5zdGFuY2VkTWVzaCYmKHMudHlwZT0iSW5zdGFuY2VkTWVzaCIscy5jb3VudD10aGlzLmNvdW50LHMuaW5zdGFuY2VNYXRyaXg9dGhpcy5pbnN0YW5jZU1hdHJpeC50b0pTT04oKSx0aGlzLmluc3RhbmNlQ29sb3IhPT1udWxsJiYocy5pbnN0YW5jZUNvbG9yPXRoaXMuaW5zdGFuY2VDb2xvci50b0pTT04oKSkpLHRoaXMuaXNCYXRjaGVkTWVzaCYmKHMudHlwZT0iQmF0Y2hlZE1lc2giLHMucGVyT2JqZWN0RnJ1c3R1bUN1bGxlZD10aGlzLnBlck9iamVjdEZydXN0dW1DdWxsZWQscy5zb3J0T2JqZWN0cz10aGlzLnNvcnRPYmplY3RzLHMuZHJhd1Jhbmdlcz10aGlzLl9kcmF3UmFuZ2VzLHMucmVzZXJ2ZWRSYW5nZXM9dGhpcy5fcmVzZXJ2ZWRSYW5nZXMscy5nZW9tZXRyeUluZm89dGhpcy5fZ2VvbWV0cnlJbmZvLm1hcChhPT5aZShGdCh7fSxhKSx7Ym91bmRpbmdCb3g6YS5ib3VuZGluZ0JveD9hLmJvdW5kaW5nQm94LnRvSlNPTigpOnZvaWQgMCxib3VuZGluZ1NwaGVyZTphLmJvdW5kaW5nU3BoZXJlP2EuYm91bmRpbmdTcGhlcmUudG9KU09OKCk6dm9pZCAwfSkpLHMuaW5zdGFuY2VJbmZvPXRoaXMuX2luc3RhbmNlSW5mby5tYXAoYT0+RnQoe30sYSkpLHMuYXZhaWxhYmxlSW5zdGFuY2VJZHM9dGhpcy5fYXZhaWxhYmxlSW5zdGFuY2VJZHMuc2xpY2UoKSxzLmF2YWlsYWJsZUdlb21ldHJ5SWRzPXRoaXMuX2F2YWlsYWJsZUdlb21ldHJ5SWRzLnNsaWNlKCkscy5uZXh0SW5kZXhTdGFydD10aGlzLl9uZXh0SW5kZXhTdGFydCxzLm5leHRWZXJ0ZXhTdGFydD10aGlzLl9uZXh0VmVydGV4U3RhcnQscy5nZW9tZXRyeUNvdW50PXRoaXMuX2dlb21ldHJ5Q291bnQscy5tYXhJbnN0YW5jZUNvdW50PXRoaXMuX21heEluc3RhbmNlQ291bnQscy5tYXhWZXJ0ZXhDb3VudD10aGlzLl9tYXhWZXJ0ZXhDb3VudCxzLm1heEluZGV4Q291bnQ9dGhpcy5fbWF4SW5kZXhDb3VudCxzLmdlb21ldHJ5SW5pdGlhbGl6ZWQ9dGhpcy5fZ2VvbWV0cnlJbml0aWFsaXplZCxzLm1hdHJpY2VzVGV4dHVyZT10aGlzLl9tYXRyaWNlc1RleHR1cmUudG9KU09OKHQpLHMuaW5kaXJlY3RUZXh0dXJlPXRoaXMuX2luZGlyZWN0VGV4dHVyZS50b0pTT04odCksdGhpcy5fY29sb3JzVGV4dHVyZSE9PW51bGwmJihzLmNvbG9yc1RleHR1cmU9dGhpcy5fY29sb3JzVGV4dHVyZS50b0pTT04odCkpLHRoaXMuYm91bmRpbmdTcGhlcmUhPT1udWxsJiYocy5ib3VuZGluZ1NwaGVyZT10aGlzLmJvdW5kaW5nU3BoZXJlLnRvSlNPTigpKSx0aGlzLmJvdW5kaW5nQm94IT09bnVsbCYmKHMuYm91bmRpbmdCb3g9dGhpcy5ib3VuZGluZ0JveC50b0pTT04oKSkpO2Z1bmN0aW9uIHIoYSxjKXtyZXR1cm4gYVtjLnV1aWRdPT09dm9pZCAwJiYoYVtjLnV1aWRdPWMudG9KU09OKHQpKSxjLnV1aWR9aWYodGhpcy5pc1NjZW5lKXRoaXMuYmFja2dyb3VuZCYmKHRoaXMuYmFja2dyb3VuZC5pc0NvbG9yP3MuYmFja2dyb3VuZD10aGlzLmJhY2tncm91bmQudG9KU09OKCk6dGhpcy5iYWNrZ3JvdW5kLmlzVGV4dHVyZSYmKHMuYmFja2dyb3VuZD10aGlzLmJhY2tncm91bmQudG9KU09OKHQpLnV1aWQpKSx0aGlzLmVudmlyb25tZW50JiZ0aGlzLmVudmlyb25tZW50LmlzVGV4dHVyZSYmdGhpcy5lbnZpcm9ubWVudC5pc1JlbmRlclRhcmdldFRleHR1cmUhPT0hMCYmKHMuZW52aXJvbm1lbnQ9dGhpcy5lbnZpcm9ubWVudC50b0pTT04odCkudXVpZCk7ZWxzZSBpZih0aGlzLmlzTWVzaHx8dGhpcy5pc0xpbmV8fHRoaXMuaXNQb2ludHMpe3MuZ2VvbWV0cnk9cih0Lmdlb21ldHJpZXMsdGhpcy5nZW9tZXRyeSk7Y29uc3QgYT10aGlzLmdlb21ldHJ5LnBhcmFtZXRlcnM7aWYoYSE9PXZvaWQgMCYmYS5zaGFwZXMhPT12b2lkIDApe2NvbnN0IGM9YS5zaGFwZXM7aWYoQXJyYXkuaXNBcnJheShjKSlmb3IobGV0IGw9MCxoPWMubGVuZ3RoO2w8aDtsKyspe2NvbnN0IHU9Y1tsXTtyKHQuc2hhcGVzLHUpfWVsc2Ugcih0LnNoYXBlcyxjKX19aWYodGhpcy5pc1NraW5uZWRNZXNoJiYocy5iaW5kTW9kZT10aGlzLmJpbmRNb2RlLHMuYmluZE1hdHJpeD10aGlzLmJpbmRNYXRyaXgudG9BcnJheSgpLHRoaXMuc2tlbGV0b24hPT12b2lkIDAmJihyKHQuc2tlbGV0b25zLHRoaXMuc2tlbGV0b24pLHMuc2tlbGV0b249dGhpcy5za2VsZXRvbi51dWlkKSksdGhpcy5tYXRlcmlhbCE9PXZvaWQgMClpZihBcnJheS5pc0FycmF5KHRoaXMubWF0ZXJpYWwpKXtjb25zdCBhPVtdO2ZvcihsZXQgYz0wLGw9dGhpcy5tYXRlcmlhbC5sZW5ndGg7YzxsO2MrKylhLnB1c2gocih0Lm1hdGVyaWFscyx0aGlzLm1hdGVyaWFsW2NdKSk7cy5tYXRlcmlhbD1hfWVsc2Ugcy5tYXRlcmlhbD1yKHQubWF0ZXJpYWxzLHRoaXMubWF0ZXJpYWwpO2lmKHRoaXMuY2hpbGRyZW4ubGVuZ3RoPjApe3MuY2hpbGRyZW49W107Zm9yKGxldCBhPTA7YTx0aGlzLmNoaWxkcmVuLmxlbmd0aDthKyspcy5jaGlsZHJlbi5wdXNoKHRoaXMuY2hpbGRyZW5bYV0udG9KU09OKHQpLm9iamVjdCl9aWYodGhpcy5hbmltYXRpb25zLmxlbmd0aD4wKXtzLmFuaW1hdGlvbnM9W107Zm9yKGxldCBhPTA7YTx0aGlzLmFuaW1hdGlvbnMubGVuZ3RoO2ErKyl7Y29uc3QgYz10aGlzLmFuaW1hdGlvbnNbYV07cy5hbmltYXRpb25zLnB1c2gocih0LmFuaW1hdGlvbnMsYykpfX1pZihlKXtjb25zdCBhPW8odC5nZW9tZXRyaWVzKSxjPW8odC5tYXRlcmlhbHMpLGw9byh0LnRleHR1cmVzKSxoPW8odC5pbWFnZXMpLHU9byh0LnNoYXBlcyksZj1vKHQuc2tlbGV0b25zKSxkPW8odC5hbmltYXRpb25zKSxwPW8odC5ub2Rlcyk7YS5sZW5ndGg+MCYmKG4uZ2VvbWV0cmllcz1hKSxjLmxlbmd0aD4wJiYobi5tYXRlcmlhbHM9YyksbC5sZW5ndGg+MCYmKG4udGV4dHVyZXM9bCksaC5sZW5ndGg+MCYmKG4uaW1hZ2VzPWgpLHUubGVuZ3RoPjAmJihuLnNoYXBlcz11KSxmLmxlbmd0aD4wJiYobi5za2VsZXRvbnM9ZiksZC5sZW5ndGg+MCYmKG4uYW5pbWF0aW9ucz1kKSxwLmxlbmd0aD4wJiYobi5ub2Rlcz1wKX1yZXR1cm4gbi5vYmplY3Q9cyxuO2Z1bmN0aW9uIG8oYSl7Y29uc3QgYz1bXTtmb3IoY29uc3QgbCBpbiBhKXtjb25zdCBoPWFbbF07ZGVsZXRlIGgubWV0YWRhdGEsYy5wdXNoKGgpfXJldHVybiBjfX1jbG9uZSh0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMsdCl9Y29weSh0LGU9ITApe2lmKHRoaXMubmFtZT10Lm5hbWUsdGhpcy51cC5jb3B5KHQudXApLHRoaXMucG9zaXRpb24uY29weSh0LnBvc2l0aW9uKSx0aGlzLnJvdGF0aW9uLm9yZGVyPXQucm90YXRpb24ub3JkZXIsdGhpcy5xdWF0ZXJuaW9uLmNvcHkodC5xdWF0ZXJuaW9uKSx0aGlzLnNjYWxlLmNvcHkodC5zY2FsZSksdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5tYXRyaXhXb3JsZC5jb3B5KHQubWF0cml4V29ybGQpLHRoaXMubWF0cml4QXV0b1VwZGF0ZT10Lm1hdHJpeEF1dG9VcGRhdGUsdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9dC5tYXRyaXhXb3JsZEF1dG9VcGRhdGUsdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPXQubWF0cml4V29ybGROZWVkc1VwZGF0ZSx0aGlzLmxheWVycy5tYXNrPXQubGF5ZXJzLm1hc2ssdGhpcy52aXNpYmxlPXQudmlzaWJsZSx0aGlzLmNhc3RTaGFkb3c9dC5jYXN0U2hhZG93LHRoaXMucmVjZWl2ZVNoYWRvdz10LnJlY2VpdmVTaGFkb3csdGhpcy5mcnVzdHVtQ3VsbGVkPXQuZnJ1c3R1bUN1bGxlZCx0aGlzLnJlbmRlck9yZGVyPXQucmVuZGVyT3JkZXIsdGhpcy5hbmltYXRpb25zPXQuYW5pbWF0aW9ucy5zbGljZSgpLHRoaXMudXNlckRhdGE9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0LnVzZXJEYXRhKSksZT09PSEwKWZvcihsZXQgbj0wO248dC5jaGlsZHJlbi5sZW5ndGg7bisrKXtjb25zdCBzPXQuY2hpbGRyZW5bbl07dGhpcy5hZGQocy5jbG9uZSgpKX1yZXR1cm4gdGhpc319RWUuREVGQVVMVF9VUD1uZXcgVCgwLDEsMCksRWUuREVGQVVMVF9NQVRSSVhfQVVUT19VUERBVEU9ITAsRWUuREVGQVVMVF9NQVRSSVhfV09STERfQVVUT19VUERBVEU9ITA7Y29uc3QgaGU9bmV3IFQsUGU9bmV3IFQseW89bmV3IFQsQ2U9bmV3IFQsVm49bmV3IFQsVW49bmV3IFQsTmM9bmV3IFQsbW89bmV3IFQsZ289bmV3IFQseG89bmV3IFQsd289bmV3IFl0LGJvPW5ldyBZdCxNbz1uZXcgWXQ7Y2xhc3MgZXR7Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBULG49bmV3IFQpe3RoaXMuYT10LHRoaXMuYj1lLHRoaXMuYz1ufXN0YXRpYyBnZXROb3JtYWwodCxlLG4scyl7cy5zdWJWZWN0b3JzKG4sZSksaGUuc3ViVmVjdG9ycyh0LGUpLHMuY3Jvc3MoaGUpO2NvbnN0IHI9cy5sZW5ndGhTcSgpO3JldHVybiByPjA/cy5tdWx0aXBseVNjYWxhcigxL01hdGguc3FydChyKSk6cy5zZXQoMCwwLDApfXN0YXRpYyBnZXRCYXJ5Y29vcmQodCxlLG4scyxyKXtoZS5zdWJWZWN0b3JzKHMsZSksUGUuc3ViVmVjdG9ycyhuLGUpLHlvLnN1YlZlY3RvcnModCxlKTtjb25zdCBvPWhlLmRvdChoZSksYT1oZS5kb3QoUGUpLGM9aGUuZG90KHlvKSxsPVBlLmRvdChQZSksaD1QZS5kb3QoeW8pLHU9bypsLWEqYTtpZih1PT09MClyZXR1cm4gci5zZXQoMCwwLDApLG51bGw7Y29uc3QgZj0xL3UsZD0obCpjLWEqaCkqZixwPShvKmgtYSpjKSpmO3JldHVybiByLnNldCgxLWQtcCxwLGQpfXN0YXRpYyBjb250YWluc1BvaW50KHQsZSxuLHMpe3JldHVybiB0aGlzLmdldEJhcnljb29yZCh0LGUsbixzLENlKT09PW51bGw/ITE6Q2UueD49MCYmQ2UueT49MCYmQ2UueCtDZS55PD0xfXN0YXRpYyBnZXRJbnRlcnBvbGF0aW9uKHQsZSxuLHMscixvLGEsYyl7cmV0dXJuIHRoaXMuZ2V0QmFyeWNvb3JkKHQsZSxuLHMsQ2UpPT09bnVsbD8oYy54PTAsYy55PTAsInoiaW4gYyYmKGMuej0wKSwidyJpbiBjJiYoYy53PTApLG51bGwpOihjLnNldFNjYWxhcigwKSxjLmFkZFNjYWxlZFZlY3RvcihyLENlLngpLGMuYWRkU2NhbGVkVmVjdG9yKG8sQ2UueSksYy5hZGRTY2FsZWRWZWN0b3IoYSxDZS56KSxjKX1zdGF0aWMgZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKHQsZSxuLHMscixvKXtyZXR1cm4gd28uc2V0U2NhbGFyKDApLGJvLnNldFNjYWxhcigwKSxNby5zZXRTY2FsYXIoMCksd28uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLGJvLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxuKSxNby5mcm9tQnVmZmVyQXR0cmlidXRlKHQscyksby5zZXRTY2FsYXIoMCksby5hZGRTY2FsZWRWZWN0b3Iod28sci54KSxvLmFkZFNjYWxlZFZlY3RvcihibyxyLnkpLG8uYWRkU2NhbGVkVmVjdG9yKE1vLHIueiksb31zdGF0aWMgaXNGcm9udEZhY2luZyh0LGUsbixzKXtyZXR1cm4gaGUuc3ViVmVjdG9ycyhuLGUpLFBlLnN1YlZlY3RvcnModCxlKSxoZS5jcm9zcyhQZSkuZG90KHMpPDB9c2V0KHQsZSxuKXtyZXR1cm4gdGhpcy5hLmNvcHkodCksdGhpcy5iLmNvcHkoZSksdGhpcy5jLmNvcHkobiksdGhpc31zZXRGcm9tUG9pbnRzQW5kSW5kaWNlcyh0LGUsbixzKXtyZXR1cm4gdGhpcy5hLmNvcHkodFtlXSksdGhpcy5iLmNvcHkodFtuXSksdGhpcy5jLmNvcHkodFtzXSksdGhpc31zZXRGcm9tQXR0cmlidXRlQW5kSW5kaWNlcyh0LGUsbixzKXtyZXR1cm4gdGhpcy5hLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKSx0aGlzLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG4pLHRoaXMuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHQscyksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5hLmNvcHkodC5hKSx0aGlzLmIuY29weSh0LmIpLHRoaXMuYy5jb3B5KHQuYyksdGhpc31nZXRBcmVhKCl7cmV0dXJuIGhlLnN1YlZlY3RvcnModGhpcy5jLHRoaXMuYiksUGUuc3ViVmVjdG9ycyh0aGlzLmEsdGhpcy5iKSxoZS5jcm9zcyhQZSkubGVuZ3RoKCkqLjV9Z2V0TWlkcG9pbnQodCl7cmV0dXJuIHQuYWRkVmVjdG9ycyh0aGlzLmEsdGhpcy5iKS5hZGQodGhpcy5jKS5tdWx0aXBseVNjYWxhcigxLzMpfWdldE5vcm1hbCh0KXtyZXR1cm4gZXQuZ2V0Tm9ybWFsKHRoaXMuYSx0aGlzLmIsdGhpcy5jLHQpfWdldFBsYW5lKHQpe3JldHVybiB0LnNldEZyb21Db3BsYW5hclBvaW50cyh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9Z2V0QmFyeWNvb3JkKHQsZSl7cmV0dXJuIGV0LmdldEJhcnljb29yZCh0LHRoaXMuYSx0aGlzLmIsdGhpcy5jLGUpfWdldEludGVycG9sYXRpb24odCxlLG4scyxyKXtyZXR1cm4gZXQuZ2V0SW50ZXJwb2xhdGlvbih0LHRoaXMuYSx0aGlzLmIsdGhpcy5jLGUsbixzLHIpfWNvbnRhaW5zUG9pbnQodCl7cmV0dXJuIGV0LmNvbnRhaW5zUG9pbnQodCx0aGlzLmEsdGhpcy5iLHRoaXMuYyl9aXNGcm9udEZhY2luZyh0KXtyZXR1cm4gZXQuaXNGcm9udEZhY2luZyh0aGlzLmEsdGhpcy5iLHRoaXMuYyx0KX1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0LmludGVyc2VjdHNUcmlhbmdsZSh0aGlzKX1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZSl7Y29uc3Qgbj10aGlzLmEscz10aGlzLmIscj10aGlzLmM7bGV0IG8sYTtWbi5zdWJWZWN0b3JzKHMsbiksVW4uc3ViVmVjdG9ycyhyLG4pLG1vLnN1YlZlY3RvcnModCxuKTtjb25zdCBjPVZuLmRvdChtbyksbD1Vbi5kb3QobW8pO2lmKGM8PTAmJmw8PTApcmV0dXJuIGUuY29weShuKTtnby5zdWJWZWN0b3JzKHQscyk7Y29uc3QgaD1Wbi5kb3QoZ28pLHU9VW4uZG90KGdvKTtpZihoPj0wJiZ1PD1oKXJldHVybiBlLmNvcHkocyk7Y29uc3QgZj1jKnUtaCpsO2lmKGY8PTAmJmM+PTAmJmg8PTApcmV0dXJuIG89Yy8oYy1oKSxlLmNvcHkobikuYWRkU2NhbGVkVmVjdG9yKFZuLG8pO3hvLnN1YlZlY3RvcnModCxyKTtjb25zdCBkPVZuLmRvdCh4bykscD1Vbi5kb3QoeG8pO2lmKHA+PTAmJmQ8PXApcmV0dXJuIGUuY29weShyKTtjb25zdCB5PWQqbC1jKnA7aWYoeTw9MCYmbD49MCYmcDw9MClyZXR1cm4gYT1sLyhsLXApLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoVW4sYSk7Y29uc3QgbT1oKnAtZCp1O2lmKG08PTAmJnUtaD49MCYmZC1wPj0wKXJldHVybiBOYy5zdWJWZWN0b3JzKHIscyksYT0odS1oKS8odS1oKyhkLXApKSxlLmNvcHkocykuYWRkU2NhbGVkVmVjdG9yKE5jLGEpO2NvbnN0IGc9MS8obSt5K2YpO3JldHVybiBvPXkqZyxhPWYqZyxlLmNvcHkobikuYWRkU2NhbGVkVmVjdG9yKFZuLG8pLmFkZFNjYWxlZFZlY3RvcihVbixhKX1lcXVhbHModCl7cmV0dXJuIHQuYS5lcXVhbHModGhpcy5hKSYmdC5iLmVxdWFscyh0aGlzLmIpJiZ0LmMuZXF1YWxzKHRoaXMuYyl9fWNvbnN0IFJjPXthbGljZWJsdWU6MTU3OTIzODMsYW50aXF1ZXdoaXRlOjE2NDQ0Mzc1LGFxdWE6NjU1MzUsYXF1YW1hcmluZTo4Mzg4NTY0LGF6dXJlOjE1Nzk0MTc1LGJlaWdlOjE2MTE5MjYwLGJpc3F1ZToxNjc3MDI0NCxibGFjazowLGJsYW5jaGVkYWxtb25kOjE2NzcyMDQ1LGJsdWU6MjU1LGJsdWV2aW9sZXQ6OTA1NTIwMixicm93bjoxMDgyNDIzNCxidXJseXdvb2Q6MTQ1OTYyMzEsY2FkZXRibHVlOjYyNjY1MjgsY2hhcnRyZXVzZTo4Mzg4MzUyLGNob2NvbGF0ZToxMzc4OTQ3MCxjb3JhbDoxNjc0NDI3Mixjb3JuZmxvd2VyYmx1ZTo2NTkxOTgxLGNvcm5zaWxrOjE2Nzc1Mzg4LGNyaW1zb246MTQ0MjMxMDAsY3lhbjo2NTUzNSxkYXJrYmx1ZToxMzksZGFya2N5YW46MzU3MjMsZGFya2dvbGRlbnJvZDoxMjA5MjkzOSxkYXJrZ3JheToxMTExOTAxNyxkYXJrZ3JlZW46MjU2MDAsZGFya2dyZXk6MTExMTkwMTcsZGFya2toYWtpOjEyNDMzMjU5LGRhcmttYWdlbnRhOjkxMDk2NDMsZGFya29saXZlZ3JlZW46NTU5Nzk5OSxkYXJrb3JhbmdlOjE2NzQ3NTIwLGRhcmtvcmNoaWQ6MTAwNDAwMTIsZGFya3JlZDo5MTA5NTA0LGRhcmtzYWxtb246MTUzMDg0MTAsZGFya3NlYWdyZWVuOjk0MTk5MTksZGFya3NsYXRlYmx1ZTo0NzM0MzQ3LGRhcmtzbGF0ZWdyYXk6MzEwMDQ5NSxkYXJrc2xhdGVncmV5OjMxMDA0OTUsZGFya3R1cnF1b2lzZTo1Mjk0NSxkYXJrdmlvbGV0Ojk2OTk1MzksZGVlcHBpbms6MTY3MTY5NDcsZGVlcHNreWJsdWU6NDkxNTEsZGltZ3JheTo2OTA4MjY1LGRpbWdyZXk6NjkwODI2NSxkb2RnZXJibHVlOjIwMDMxOTksZmlyZWJyaWNrOjExNjc0MTQ2LGZsb3JhbHdoaXRlOjE2Nzc1OTIwLGZvcmVzdGdyZWVuOjIyNjM4NDIsZnVjaHNpYToxNjcxMTkzNSxnYWluc2Jvcm86MTQ0NzQ0NjAsZ2hvc3R3aGl0ZToxNjMxNjY3MSxnb2xkOjE2NzY2NzIwLGdvbGRlbnJvZDoxNDMyOTEyMCxncmF5Ojg0MjE1MDQsZ3JlZW46MzI3NjgsZ3JlZW55ZWxsb3c6MTE0MDMwNTUsZ3JleTo4NDIxNTA0LGhvbmV5ZGV3OjE1Nzk0MTYwLGhvdHBpbms6MTY3Mzg3NDAsaW5kaWFucmVkOjEzNDU4NTI0LGluZGlnbzo0OTE1MzMwLGl2b3J5OjE2Nzc3MjAwLGtoYWtpOjE1Nzg3NjYwLGxhdmVuZGVyOjE1MTMyNDEwLGxhdmVuZGVyYmx1c2g6MTY3NzMzNjUsbGF3bmdyZWVuOjgxOTA5NzYsbGVtb25jaGlmZm9uOjE2Nzc1ODg1LGxpZ2h0Ymx1ZToxMTM5MzI1NCxsaWdodGNvcmFsOjE1NzYxNTM2LGxpZ2h0Y3lhbjoxNDc0NTU5OSxsaWdodGdvbGRlbnJvZHllbGxvdzoxNjQ0ODIxMCxsaWdodGdyYXk6MTM4ODIzMjMsbGlnaHRncmVlbjo5NDk4MjU2LGxpZ2h0Z3JleToxMzg4MjMyMyxsaWdodHBpbms6MTY3NTg0NjUsbGlnaHRzYWxtb246MTY3NTI3NjIsbGlnaHRzZWFncmVlbjoyMTQyODkwLGxpZ2h0c2t5Ymx1ZTo4OTAwMzQ2LGxpZ2h0c2xhdGVncmF5Ojc4MzM3NTMsbGlnaHRzbGF0ZWdyZXk6NzgzMzc1MyxsaWdodHN0ZWVsYmx1ZToxMTU4NDczNCxsaWdodHllbGxvdzoxNjc3NzE4NCxsaW1lOjY1MjgwLGxpbWVncmVlbjozMzI5MzMwLGxpbmVuOjE2NDQ1NjcwLG1hZ2VudGE6MTY3MTE5MzUsbWFyb29uOjgzODg2MDgsbWVkaXVtYXF1YW1hcmluZTo2NzM3MzIyLG1lZGl1bWJsdWU6MjA1LG1lZGl1bW9yY2hpZDoxMjIxMTY2NyxtZWRpdW1wdXJwbGU6OTY2MjY4MyxtZWRpdW1zZWFncmVlbjozOTc4MDk3LG1lZGl1bXNsYXRlYmx1ZTo4MDg3NzkwLG1lZGl1bXNwcmluZ2dyZWVuOjY0MTU0LG1lZGl1bXR1cnF1b2lzZTo0NzcyMzAwLG1lZGl1bXZpb2xldHJlZDoxMzA0NzE3MyxtaWRuaWdodGJsdWU6MTY0NDkxMixtaW50Y3JlYW06MTYxMjE4NTAsbWlzdHlyb3NlOjE2NzcwMjczLG1vY2Nhc2luOjE2NzcwMjI5LG5hdmFqb3doaXRlOjE2NzY4Njg1LG5hdnk6MTI4LG9sZGxhY2U6MTY2NDM1NTgsb2xpdmU6ODQyMTM3NixvbGl2ZWRyYWI6NzA0ODczOSxvcmFuZ2U6MTY3NTM5MjAsb3JhbmdlcmVkOjE2NzI5MzQ0LG9yY2hpZDoxNDMxNTczNCxwYWxlZ29sZGVucm9kOjE1NjU3MTMwLHBhbGVncmVlbjoxMDAyNTg4MCxwYWxldHVycXVvaXNlOjExNTI5OTY2LHBhbGV2aW9sZXRyZWQ6MTQzODEyMDMscGFwYXlhd2hpcDoxNjc3MzA3NyxwZWFjaHB1ZmY6MTY3Njc2NzMscGVydToxMzQ2ODk5MSxwaW5rOjE2NzYxMDM1LHBsdW06MTQ1MjQ2MzcscG93ZGVyYmx1ZToxMTU5MTkxMCxwdXJwbGU6ODM4ODczNixyZWJlY2NhcHVycGxlOjY2OTc4ODEscmVkOjE2NzExNjgwLHJvc3licm93bjoxMjM1NzUxOSxyb3lhbGJsdWU6NDI4Njk0NSxzYWRkbGVicm93bjo5MTI3MTg3LHNhbG1vbjoxNjQxNjg4MixzYW5keWJyb3duOjE2MDMyODY0LHNlYWdyZWVuOjMwNTAzMjcsc2Vhc2hlbGw6MTY3NzQ2Mzgsc2llbm5hOjEwNTA2Nzk3LHNpbHZlcjoxMjYzMjI1Nixza3libHVlOjg5MDAzMzEsc2xhdGVibHVlOjY5NzAwNjEsc2xhdGVncmF5OjczNzI5NDQsc2xhdGVncmV5OjczNzI5NDQsc25vdzoxNjc3NTkzMCxzcHJpbmdncmVlbjo2NTQwNyxzdGVlbGJsdWU6NDYyMDk4MCx0YW46MTM4MDg3ODAsdGVhbDozMjg5Nix0aGlzdGxlOjE0MjA0ODg4LHRvbWF0bzoxNjczNzA5NSx0dXJxdW9pc2U6NDI1MTg1Nix2aW9sZXQ6MTU2MzEwODYsd2hlYXQ6MTYxMTMzMzEsd2hpdGU6MTY3NzcyMTUsd2hpdGVzbW9rZToxNjExOTI4NSx5ZWxsb3c6MTY3NzY5NjAseWVsbG93Z3JlZW46MTAxNDUwNzR9LFFlPXtoOjAsczowLGw6MH0scHM9e2g6MCxzOjAsbDowfTtmdW5jdGlvbiBBbyhpLHQsZSl7cmV0dXJuIGU8MCYmKGUrPTEpLGU+MSYmKGUtPTEpLGU8MS82P2krKHQtaSkqNiplOmU8MS8yP3Q6ZTwyLzM/aSsodC1pKSo2KigyLzMtZSk6aX1sZXQgeXM9Y2xhc3N7Y29uc3RydWN0b3IodCxlLG4pe3JldHVybiB0aGlzLmlzQ29sb3I9ITAsdGhpcy5yPTEsdGhpcy5nPTEsdGhpcy5iPTEsdGhpcy5zZXQodCxlLG4pfXNldCh0LGUsbil7aWYoZT09PXZvaWQgMCYmbj09PXZvaWQgMCl7Y29uc3Qgcz10O3MmJnMuaXNDb2xvcj90aGlzLmNvcHkocyk6dHlwZW9mIHM9PSJudW1iZXIiP3RoaXMuc2V0SGV4KHMpOnR5cGVvZiBzPT0ic3RyaW5nIiYmdGhpcy5zZXRTdHlsZShzKX1lbHNlIHRoaXMuc2V0UkdCKHQsZSxuKTtyZXR1cm4gdGhpc31zZXRTY2FsYXIodCl7cmV0dXJuIHRoaXMucj10LHRoaXMuZz10LHRoaXMuYj10LHRoaXN9c2V0SGV4KHQsZT1vZSl7cmV0dXJuIHQ9TWF0aC5mbG9vcih0KSx0aGlzLnI9KHQ+PjE2JjI1NSkvMjU1LHRoaXMuZz0odD4+OCYyNTUpLzI1NSx0aGlzLmI9KHQmMjU1KS8yNTUsYWUuY29sb3JTcGFjZVRvV29ya2luZyh0aGlzLGUpLHRoaXN9c2V0UkdCKHQsZSxuLHM9YWUud29ya2luZ0NvbG9yU3BhY2Upe3JldHVybiB0aGlzLnI9dCx0aGlzLmc9ZSx0aGlzLmI9bixhZS5jb2xvclNwYWNlVG9Xb3JraW5nKHRoaXMscyksdGhpc31zZXRIU0wodCxlLG4scz1hZS53b3JraW5nQ29sb3JTcGFjZSl7aWYodD1qdSh0LDEpLGU9WihlLDAsMSksbj1aKG4sMCwxKSxlPT09MCl0aGlzLnI9dGhpcy5nPXRoaXMuYj1uO2Vsc2V7Y29uc3Qgcj1uPD0uNT9uKigxK2UpOm4rZS1uKmUsbz0yKm4tcjt0aGlzLnI9QW8obyxyLHQrMS8zKSx0aGlzLmc9QW8obyxyLHQpLHRoaXMuYj1BbyhvLHIsdC0xLzMpfXJldHVybiBhZS5jb2xvclNwYWNlVG9Xb3JraW5nKHRoaXMscyksdGhpc31zZXRTdHlsZSh0LGU9b2Upe2Z1bmN0aW9uIG4ocil7ciE9PXZvaWQgMCYmcGFyc2VGbG9hdChyKTwxJiZjb25zb2xlLndhcm4oIlRIUkVFLkNvbG9yOiBBbHBoYSBjb21wb25lbnQgb2YgIit0KyIgd2lsbCBiZSBpZ25vcmVkLiIpfWxldCBzO2lmKHM9L14oXHcrKVwoKFteXCldKilcKS8uZXhlYyh0KSl7bGV0IHI7Y29uc3Qgbz1zWzFdLGE9c1syXTtzd2l0Y2gobyl7Y2FzZSJyZ2IiOmNhc2UicmdiYSI6aWYocj0vXlxzKihcZCspXHMqLFxzKihcZCspXHMqLFxzKihcZCspXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0UkdCKE1hdGgubWluKDI1NSxwYXJzZUludChyWzFdLDEwKSkvMjU1LE1hdGgubWluKDI1NSxwYXJzZUludChyWzJdLDEwKSkvMjU1LE1hdGgubWluKDI1NSxwYXJzZUludChyWzNdLDEwKSkvMjU1LGUpO2lmKHI9L15ccyooXGQrKVwlXHMqLFxzKihcZCspXCVccyosXHMqKFxkKylcJVxzKig/OixccyooXGQqXC4/XGQrKVxzKik/JC8uZXhlYyhhKSlyZXR1cm4gbihyWzRdKSx0aGlzLnNldFJHQihNYXRoLm1pbigxMDAscGFyc2VJbnQoclsxXSwxMCkpLzEwMCxNYXRoLm1pbigxMDAscGFyc2VJbnQoclsyXSwxMCkpLzEwMCxNYXRoLm1pbigxMDAscGFyc2VJbnQoclszXSwxMCkpLzEwMCxlKTticmVhaztjYXNlImhzbCI6Y2FzZSJoc2xhIjppZihyPS9eXHMqKFxkKlwuP1xkKylccyosXHMqKFxkKlwuP1xkKylcJVxzKixccyooXGQqXC4/XGQrKVwlXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0SFNMKHBhcnNlRmxvYXQoclsxXSkvMzYwLHBhcnNlRmxvYXQoclsyXSkvMTAwLHBhcnNlRmxvYXQoclszXSkvMTAwLGUpO2JyZWFrO2RlZmF1bHQ6Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogVW5rbm93biBjb2xvciBtb2RlbCAiK3QpfX1lbHNlIGlmKHM9L15cIyhbQS1GYS1mXGRdKykkLy5leGVjKHQpKXtjb25zdCByPXNbMV0sbz1yLmxlbmd0aDtpZihvPT09MylyZXR1cm4gdGhpcy5zZXRSR0IocGFyc2VJbnQoci5jaGFyQXQoMCksMTYpLzE1LHBhcnNlSW50KHIuY2hhckF0KDEpLDE2KS8xNSxwYXJzZUludChyLmNoYXJBdCgyKSwxNikvMTUsZSk7aWYobz09PTYpcmV0dXJuIHRoaXMuc2V0SGV4KHBhcnNlSW50KHIsMTYpLGUpO2NvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IEludmFsaWQgaGV4IGNvbG9yICIrdCl9ZWxzZSBpZih0JiZ0Lmxlbmd0aD4wKXJldHVybiB0aGlzLnNldENvbG9yTmFtZSh0LGUpO3JldHVybiB0aGlzfXNldENvbG9yTmFtZSh0LGU9b2Upe2NvbnN0IG49UmNbdC50b0xvd2VyQ2FzZSgpXTtyZXR1cm4gbiE9PXZvaWQgMD90aGlzLnNldEhleChuLGUpOmNvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IFVua25vd24gY29sb3IgIit0KSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMucix0aGlzLmcsdGhpcy5iKX1jb3B5KHQpe3JldHVybiB0aGlzLnI9dC5yLHRoaXMuZz10LmcsdGhpcy5iPXQuYix0aGlzfWNvcHlTUkdCVG9MaW5lYXIodCl7cmV0dXJuIHRoaXMucj1fZSh0LnIpLHRoaXMuZz1fZSh0LmcpLHRoaXMuYj1fZSh0LmIpLHRoaXN9Y29weUxpbmVhclRvU1JHQih0KXtyZXR1cm4gdGhpcy5yPUluKHQuciksdGhpcy5nPUluKHQuZyksdGhpcy5iPUluKHQuYiksdGhpc31jb252ZXJ0U1JHQlRvTGluZWFyKCl7cmV0dXJuIHRoaXMuY29weVNSR0JUb0xpbmVhcih0aGlzKSx0aGlzfWNvbnZlcnRMaW5lYXJUb1NSR0IoKXtyZXR1cm4gdGhpcy5jb3B5TGluZWFyVG9TUkdCKHRoaXMpLHRoaXN9Z2V0SGV4KHQ9b2Upe3JldHVybiBhZS53b3JraW5nVG9Db2xvclNwYWNlKFN0LmNvcHkodGhpcyksdCksTWF0aC5yb3VuZChaKFN0LnIqMjU1LDAsMjU1KSkqNjU1MzYrTWF0aC5yb3VuZChaKFN0LmcqMjU1LDAsMjU1KSkqMjU2K01hdGgucm91bmQoWihTdC5iKjI1NSwwLDI1NSkpfWdldEhleFN0cmluZyh0PW9lKXtyZXR1cm4oIjAwMDAwMCIrdGhpcy5nZXRIZXgodCkudG9TdHJpbmcoMTYpKS5zbGljZSgtNil9Z2V0SFNMKHQsZT1hZS53b3JraW5nQ29sb3JTcGFjZSl7YWUud29ya2luZ1RvQ29sb3JTcGFjZShTdC5jb3B5KHRoaXMpLGUpO2NvbnN0IG49U3QucixzPVN0Lmcscj1TdC5iLG89TWF0aC5tYXgobixzLHIpLGE9TWF0aC5taW4obixzLHIpO2xldCBjLGw7Y29uc3QgaD0oYStvKS8yO2lmKGE9PT1vKWM9MCxsPTA7ZWxzZXtjb25zdCB1PW8tYTtzd2l0Y2gobD1oPD0uNT91LyhvK2EpOnUvKDItby1hKSxvKXtjYXNlIG46Yz0ocy1yKS91KyhzPHI/NjowKTticmVhaztjYXNlIHM6Yz0oci1uKS91KzI7YnJlYWs7Y2FzZSByOmM9KG4tcykvdSs0O2JyZWFrfWMvPTZ9cmV0dXJuIHQuaD1jLHQucz1sLHQubD1oLHR9Z2V0UkdCKHQsZT1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIGFlLndvcmtpbmdUb0NvbG9yU3BhY2UoU3QuY29weSh0aGlzKSxlKSx0LnI9U3Qucix0Lmc9U3QuZyx0LmI9U3QuYix0fWdldFN0eWxlKHQ9b2Upe2FlLndvcmtpbmdUb0NvbG9yU3BhY2UoU3QuY29weSh0aGlzKSx0KTtjb25zdCBlPVN0LnIsbj1TdC5nLHM9U3QuYjtyZXR1cm4gdCE9PW9lP2Bjb2xvcigke3R9ICR7ZS50b0ZpeGVkKDMpfSAke24udG9GaXhlZCgzKX0gJHtzLnRvRml4ZWQoMyl9KWA6YHJnYigke01hdGgucm91bmQoZSoyNTUpfSwke01hdGgucm91bmQobioyNTUpfSwke01hdGgucm91bmQocyoyNTUpfSlgfW9mZnNldEhTTCh0LGUsbil7cmV0dXJuIHRoaXMuZ2V0SFNMKFFlKSx0aGlzLnNldEhTTChRZS5oK3QsUWUucytlLFFlLmwrbil9YWRkKHQpe3JldHVybiB0aGlzLnIrPXQucix0aGlzLmcrPXQuZyx0aGlzLmIrPXQuYix0aGlzfWFkZENvbG9ycyh0LGUpe3JldHVybiB0aGlzLnI9dC5yK2Uucix0aGlzLmc9dC5nK2UuZyx0aGlzLmI9dC5iK2UuYix0aGlzfWFkZFNjYWxhcih0KXtyZXR1cm4gdGhpcy5yKz10LHRoaXMuZys9dCx0aGlzLmIrPXQsdGhpc31zdWIodCl7cmV0dXJuIHRoaXMucj1NYXRoLm1heCgwLHRoaXMuci10LnIpLHRoaXMuZz1NYXRoLm1heCgwLHRoaXMuZy10LmcpLHRoaXMuYj1NYXRoLm1heCgwLHRoaXMuYi10LmIpLHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMucio9dC5yLHRoaXMuZyo9dC5nLHRoaXMuYio9dC5iLHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMucio9dCx0aGlzLmcqPXQsdGhpcy5iKj10LHRoaXN9bGVycCh0LGUpe3JldHVybiB0aGlzLnIrPSh0LnItdGhpcy5yKSplLHRoaXMuZys9KHQuZy10aGlzLmcpKmUsdGhpcy5iKz0odC5iLXRoaXMuYikqZSx0aGlzfWxlcnBDb2xvcnModCxlLG4pe3JldHVybiB0aGlzLnI9dC5yKyhlLnItdC5yKSpuLHRoaXMuZz10LmcrKGUuZy10LmcpKm4sdGhpcy5iPXQuYisoZS5iLXQuYikqbix0aGlzfWxlcnBIU0wodCxlKXt0aGlzLmdldEhTTChRZSksdC5nZXRIU0wocHMpO2NvbnN0IG49ZW8oUWUuaCxwcy5oLGUpLHM9ZW8oUWUucyxwcy5zLGUpLHI9ZW8oUWUubCxwcy5sLGUpO3JldHVybiB0aGlzLnNldEhTTChuLHMsciksdGhpc31zZXRGcm9tVmVjdG9yMyh0KXtyZXR1cm4gdGhpcy5yPXQueCx0aGlzLmc9dC55LHRoaXMuYj10LnosdGhpc31hcHBseU1hdHJpeDModCl7Y29uc3QgZT10aGlzLnIsbj10aGlzLmcscz10aGlzLmIscj10LmVsZW1lbnRzO3JldHVybiB0aGlzLnI9clswXSplK3JbM10qbityWzZdKnMsdGhpcy5nPXJbMV0qZStyWzRdKm4rcls3XSpzLHRoaXMuYj1yWzJdKmUrcls1XSpuK3JbOF0qcyx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5yPT09dGhpcy5yJiZ0Lmc9PT10aGlzLmcmJnQuYj09PXRoaXMuYn1mcm9tQXJyYXkodCxlPTApe3JldHVybiB0aGlzLnI9dFtlXSx0aGlzLmc9dFtlKzFdLHRoaXMuYj10W2UrMl0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLnIsdFtlKzFdPXRoaXMuZyx0W2UrMl09dGhpcy5iLHR9ZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLnI9dC5nZXRYKGUpLHRoaXMuZz10LmdldFkoZSksdGhpcy5iPXQuZ2V0WihlKSx0aGlzfXRvSlNPTigpe3JldHVybiB0aGlzLmdldEhleCgpfSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMucix5aWVsZCB0aGlzLmcseWllbGQgdGhpcy5ifX07Y29uc3QgU3Q9bmV3IHlzO3lzLk5BTUVTPVJjO2xldCBkZj0wO2NsYXNzIHBmIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNNYXRlcmlhbD0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpkZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iTWF0ZXJpYWwiLHRoaXMuYmxlbmRpbmc9MSx0aGlzLnNpZGU9MCx0aGlzLnZlcnRleENvbG9ycz0hMSx0aGlzLm9wYWNpdHk9MSx0aGlzLnRyYW5zcGFyZW50PSExLHRoaXMuYWxwaGFIYXNoPSExLHRoaXMuYmxlbmRTcmM9MjA0LHRoaXMuYmxlbmREc3Q9MjA1LHRoaXMuYmxlbmRFcXVhdGlvbj0xMDAsdGhpcy5ibGVuZFNyY0FscGhhPW51bGwsdGhpcy5ibGVuZERzdEFscGhhPW51bGwsdGhpcy5ibGVuZEVxdWF0aW9uQWxwaGE9bnVsbCx0aGlzLmJsZW5kQ29sb3I9bmV3IHlzKDAsMCwwKSx0aGlzLmJsZW5kQWxwaGE9MCx0aGlzLmRlcHRoRnVuYz0zLHRoaXMuZGVwdGhUZXN0PSEwLHRoaXMuZGVwdGhXcml0ZT0hMCx0aGlzLnN0ZW5jaWxXcml0ZU1hc2s9MjU1LHRoaXMuc3RlbmNpbEZ1bmM9NTE5LHRoaXMuc3RlbmNpbFJlZj0wLHRoaXMuc3RlbmNpbEZ1bmNNYXNrPTI1NSx0aGlzLnN0ZW5jaWxGYWlsPTc2ODAsdGhpcy5zdGVuY2lsWkZhaWw9NzY4MCx0aGlzLnN0ZW5jaWxaUGFzcz03NjgwLHRoaXMuc3RlbmNpbFdyaXRlPSExLHRoaXMuY2xpcHBpbmdQbGFuZXM9bnVsbCx0aGlzLmNsaXBJbnRlcnNlY3Rpb249ITEsdGhpcy5jbGlwU2hhZG93cz0hMSx0aGlzLnNoYWRvd1NpZGU9bnVsbCx0aGlzLmNvbG9yV3JpdGU9ITAsdGhpcy5wcmVjaXNpb249bnVsbCx0aGlzLnBvbHlnb25PZmZzZXQ9ITEsdGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yPTAsdGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHM9MCx0aGlzLmRpdGhlcmluZz0hMSx0aGlzLmFscGhhVG9Db3ZlcmFnZT0hMSx0aGlzLnByZW11bHRpcGxpZWRBbHBoYT0hMSx0aGlzLmZvcmNlU2luZ2xlUGFzcz0hMSx0aGlzLmFsbG93T3ZlcnJpZGU9ITAsdGhpcy52aXNpYmxlPSEwLHRoaXMudG9uZU1hcHBlZD0hMCx0aGlzLnVzZXJEYXRhPXt9LHRoaXMudmVyc2lvbj0wLHRoaXMuX2FscGhhVGVzdD0wfWdldCBhbHBoYVRlc3QoKXtyZXR1cm4gdGhpcy5fYWxwaGFUZXN0fXNldCBhbHBoYVRlc3QodCl7dGhpcy5fYWxwaGFUZXN0PjAhPXQ+MCYmdGhpcy52ZXJzaW9uKyssdGhpcy5fYWxwaGFUZXN0PXR9b25CZWZvcmVSZW5kZXIoKXt9b25CZWZvcmVDb21waWxlKCl7fWN1c3RvbVByb2dyYW1DYWNoZUtleSgpe3JldHVybiB0aGlzLm9uQmVmb3JlQ29tcGlsZS50b1N0cmluZygpfXNldFZhbHVlcyh0KXtpZih0IT09dm9pZCAwKWZvcihjb25zdCBlIGluIHQpe2NvbnN0IG49dFtlXTtpZihuPT09dm9pZCAwKXtjb25zb2xlLndhcm4oYFRIUkVFLk1hdGVyaWFsOiBwYXJhbWV0ZXIgJyR7ZX0nIGhhcyB2YWx1ZSBvZiB1bmRlZmluZWQuYCk7Y29udGludWV9Y29uc3Qgcz10aGlzW2VdO2lmKHM9PT12b2lkIDApe2NvbnNvbGUud2FybihgVEhSRUUuTWF0ZXJpYWw6ICcke2V9JyBpcyBub3QgYSBwcm9wZXJ0eSBvZiBUSFJFRS4ke3RoaXMudHlwZX0uYCk7Y29udGludWV9cyYmcy5pc0NvbG9yP3Muc2V0KG4pOnMmJnMuaXNWZWN0b3IzJiZuJiZuLmlzVmVjdG9yMz9zLmNvcHkobik6dGhpc1tlXT1ufX10b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7ZSYmKHQ9e3RleHR1cmVzOnt9LGltYWdlczp7fX0pO2NvbnN0IG49e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJNYXRlcmlhbCIsZ2VuZXJhdG9yOiJNYXRlcmlhbC50b0pTT04ifX07bi51dWlkPXRoaXMudXVpZCxuLnR5cGU9dGhpcy50eXBlLHRoaXMubmFtZSE9PSIiJiYobi5uYW1lPXRoaXMubmFtZSksdGhpcy5jb2xvciYmdGhpcy5jb2xvci5pc0NvbG9yJiYobi5jb2xvcj10aGlzLmNvbG9yLmdldEhleCgpKSx0aGlzLnJvdWdobmVzcyE9PXZvaWQgMCYmKG4ucm91Z2huZXNzPXRoaXMucm91Z2huZXNzKSx0aGlzLm1ldGFsbmVzcyE9PXZvaWQgMCYmKG4ubWV0YWxuZXNzPXRoaXMubWV0YWxuZXNzKSx0aGlzLnNoZWVuIT09dm9pZCAwJiYobi5zaGVlbj10aGlzLnNoZWVuKSx0aGlzLnNoZWVuQ29sb3ImJnRoaXMuc2hlZW5Db2xvci5pc0NvbG9yJiYobi5zaGVlbkNvbG9yPXRoaXMuc2hlZW5Db2xvci5nZXRIZXgoKSksdGhpcy5zaGVlblJvdWdobmVzcyE9PXZvaWQgMCYmKG4uc2hlZW5Sb3VnaG5lc3M9dGhpcy5zaGVlblJvdWdobmVzcyksdGhpcy5lbWlzc2l2ZSYmdGhpcy5lbWlzc2l2ZS5pc0NvbG9yJiYobi5lbWlzc2l2ZT10aGlzLmVtaXNzaXZlLmdldEhleCgpKSx0aGlzLmVtaXNzaXZlSW50ZW5zaXR5IT09dm9pZCAwJiZ0aGlzLmVtaXNzaXZlSW50ZW5zaXR5IT09MSYmKG4uZW1pc3NpdmVJbnRlbnNpdHk9dGhpcy5lbWlzc2l2ZUludGVuc2l0eSksdGhpcy5zcGVjdWxhciYmdGhpcy5zcGVjdWxhci5pc0NvbG9yJiYobi5zcGVjdWxhcj10aGlzLnNwZWN1bGFyLmdldEhleCgpKSx0aGlzLnNwZWN1bGFySW50ZW5zaXR5IT09dm9pZCAwJiYobi5zcGVjdWxhckludGVuc2l0eT10aGlzLnNwZWN1bGFySW50ZW5zaXR5KSx0aGlzLnNwZWN1bGFyQ29sb3ImJnRoaXMuc3BlY3VsYXJDb2xvci5pc0NvbG9yJiYobi5zcGVjdWxhckNvbG9yPXRoaXMuc3BlY3VsYXJDb2xvci5nZXRIZXgoKSksdGhpcy5zaGluaW5lc3MhPT12b2lkIDAmJihuLnNoaW5pbmVzcz10aGlzLnNoaW5pbmVzcyksdGhpcy5jbGVhcmNvYXQhPT12b2lkIDAmJihuLmNsZWFyY29hdD10aGlzLmNsZWFyY29hdCksdGhpcy5jbGVhcmNvYXRSb3VnaG5lc3MhPT12b2lkIDAmJihuLmNsZWFyY29hdFJvdWdobmVzcz10aGlzLmNsZWFyY29hdFJvdWdobmVzcyksdGhpcy5jbGVhcmNvYXRNYXAmJnRoaXMuY2xlYXJjb2F0TWFwLmlzVGV4dHVyZSYmKG4uY2xlYXJjb2F0TWFwPXRoaXMuY2xlYXJjb2F0TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmNsZWFyY29hdFJvdWdobmVzc01hcCYmdGhpcy5jbGVhcmNvYXRSb3VnaG5lc3NNYXAuaXNUZXh0dXJlJiYobi5jbGVhcmNvYXRSb3VnaG5lc3NNYXA9dGhpcy5jbGVhcmNvYXRSb3VnaG5lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuY2xlYXJjb2F0Tm9ybWFsTWFwJiZ0aGlzLmNsZWFyY29hdE5vcm1hbE1hcC5pc1RleHR1cmUmJihuLmNsZWFyY29hdE5vcm1hbE1hcD10aGlzLmNsZWFyY29hdE5vcm1hbE1hcC50b0pTT04odCkudXVpZCxuLmNsZWFyY29hdE5vcm1hbFNjYWxlPXRoaXMuY2xlYXJjb2F0Tm9ybWFsU2NhbGUudG9BcnJheSgpKSx0aGlzLmRpc3BlcnNpb24hPT12b2lkIDAmJihuLmRpc3BlcnNpb249dGhpcy5kaXNwZXJzaW9uKSx0aGlzLmlyaWRlc2NlbmNlIT09dm9pZCAwJiYobi5pcmlkZXNjZW5jZT10aGlzLmlyaWRlc2NlbmNlKSx0aGlzLmlyaWRlc2NlbmNlSU9SIT09dm9pZCAwJiYobi5pcmlkZXNjZW5jZUlPUj10aGlzLmlyaWRlc2NlbmNlSU9SKSx0aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzUmFuZ2UhPT12b2lkIDAmJihuLmlyaWRlc2NlbmNlVGhpY2tuZXNzUmFuZ2U9dGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc1JhbmdlKSx0aGlzLmlyaWRlc2NlbmNlTWFwJiZ0aGlzLmlyaWRlc2NlbmNlTWFwLmlzVGV4dHVyZSYmKG4uaXJpZGVzY2VuY2VNYXA9dGhpcy5pcmlkZXNjZW5jZU1hcC50b0pTT04odCkudXVpZCksdGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcCYmdGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcC5pc1RleHR1cmUmJihuLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwPXRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuYW5pc290cm9weSE9PXZvaWQgMCYmKG4uYW5pc290cm9weT10aGlzLmFuaXNvdHJvcHkpLHRoaXMuYW5pc290cm9weVJvdGF0aW9uIT09dm9pZCAwJiYobi5hbmlzb3Ryb3B5Um90YXRpb249dGhpcy5hbmlzb3Ryb3B5Um90YXRpb24pLHRoaXMuYW5pc290cm9weU1hcCYmdGhpcy5hbmlzb3Ryb3B5TWFwLmlzVGV4dHVyZSYmKG4uYW5pc290cm9weU1hcD10aGlzLmFuaXNvdHJvcHlNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubWFwJiZ0aGlzLm1hcC5pc1RleHR1cmUmJihuLm1hcD10aGlzLm1hcC50b0pTT04odCkudXVpZCksdGhpcy5tYXRjYXAmJnRoaXMubWF0Y2FwLmlzVGV4dHVyZSYmKG4ubWF0Y2FwPXRoaXMubWF0Y2FwLnRvSlNPTih0KS51dWlkKSx0aGlzLmFscGhhTWFwJiZ0aGlzLmFscGhhTWFwLmlzVGV4dHVyZSYmKG4uYWxwaGFNYXA9dGhpcy5hbHBoYU1hcC50b0pTT04odCkudXVpZCksdGhpcy5saWdodE1hcCYmdGhpcy5saWdodE1hcC5pc1RleHR1cmUmJihuLmxpZ2h0TWFwPXRoaXMubGlnaHRNYXAudG9KU09OKHQpLnV1aWQsbi5saWdodE1hcEludGVuc2l0eT10aGlzLmxpZ2h0TWFwSW50ZW5zaXR5KSx0aGlzLmFvTWFwJiZ0aGlzLmFvTWFwLmlzVGV4dHVyZSYmKG4uYW9NYXA9dGhpcy5hb01hcC50b0pTT04odCkudXVpZCxuLmFvTWFwSW50ZW5zaXR5PXRoaXMuYW9NYXBJbnRlbnNpdHkpLHRoaXMuYnVtcE1hcCYmdGhpcy5idW1wTWFwLmlzVGV4dHVyZSYmKG4uYnVtcE1hcD10aGlzLmJ1bXBNYXAudG9KU09OKHQpLnV1aWQsbi5idW1wU2NhbGU9dGhpcy5idW1wU2NhbGUpLHRoaXMubm9ybWFsTWFwJiZ0aGlzLm5vcm1hbE1hcC5pc1RleHR1cmUmJihuLm5vcm1hbE1hcD10aGlzLm5vcm1hbE1hcC50b0pTT04odCkudXVpZCxuLm5vcm1hbE1hcFR5cGU9dGhpcy5ub3JtYWxNYXBUeXBlLG4ubm9ybWFsU2NhbGU9dGhpcy5ub3JtYWxTY2FsZS50b0FycmF5KCkpLHRoaXMuZGlzcGxhY2VtZW50TWFwJiZ0aGlzLmRpc3BsYWNlbWVudE1hcC5pc1RleHR1cmUmJihuLmRpc3BsYWNlbWVudE1hcD10aGlzLmRpc3BsYWNlbWVudE1hcC50b0pTT04odCkudXVpZCxuLmRpc3BsYWNlbWVudFNjYWxlPXRoaXMuZGlzcGxhY2VtZW50U2NhbGUsbi5kaXNwbGFjZW1lbnRCaWFzPXRoaXMuZGlzcGxhY2VtZW50QmlhcyksdGhpcy5yb3VnaG5lc3NNYXAmJnRoaXMucm91Z2huZXNzTWFwLmlzVGV4dHVyZSYmKG4ucm91Z2huZXNzTWFwPXRoaXMucm91Z2huZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLm1ldGFsbmVzc01hcCYmdGhpcy5tZXRhbG5lc3NNYXAuaXNUZXh0dXJlJiYobi5tZXRhbG5lc3NNYXA9dGhpcy5tZXRhbG5lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuZW1pc3NpdmVNYXAmJnRoaXMuZW1pc3NpdmVNYXAuaXNUZXh0dXJlJiYobi5lbWlzc2l2ZU1hcD10aGlzLmVtaXNzaXZlTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnNwZWN1bGFyTWFwJiZ0aGlzLnNwZWN1bGFyTWFwLmlzVGV4dHVyZSYmKG4uc3BlY3VsYXJNYXA9dGhpcy5zcGVjdWxhck1hcC50b0pTT04odCkudXVpZCksdGhpcy5zcGVjdWxhckludGVuc2l0eU1hcCYmdGhpcy5zcGVjdWxhckludGVuc2l0eU1hcC5pc1RleHR1cmUmJihuLnNwZWN1bGFySW50ZW5zaXR5TWFwPXRoaXMuc3BlY3VsYXJJbnRlbnNpdHlNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuc3BlY3VsYXJDb2xvck1hcCYmdGhpcy5zcGVjdWxhckNvbG9yTWFwLmlzVGV4dHVyZSYmKG4uc3BlY3VsYXJDb2xvck1hcD10aGlzLnNwZWN1bGFyQ29sb3JNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuZW52TWFwJiZ0aGlzLmVudk1hcC5pc1RleHR1cmUmJihuLmVudk1hcD10aGlzLmVudk1hcC50b0pTT04odCkudXVpZCx0aGlzLmNvbWJpbmUhPT12b2lkIDAmJihuLmNvbWJpbmU9dGhpcy5jb21iaW5lKSksdGhpcy5lbnZNYXBSb3RhdGlvbiE9PXZvaWQgMCYmKG4uZW52TWFwUm90YXRpb249dGhpcy5lbnZNYXBSb3RhdGlvbi50b0FycmF5KCkpLHRoaXMuZW52TWFwSW50ZW5zaXR5IT09dm9pZCAwJiYobi5lbnZNYXBJbnRlbnNpdHk9dGhpcy5lbnZNYXBJbnRlbnNpdHkpLHRoaXMucmVmbGVjdGl2aXR5IT09dm9pZCAwJiYobi5yZWZsZWN0aXZpdHk9dGhpcy5yZWZsZWN0aXZpdHkpLHRoaXMucmVmcmFjdGlvblJhdGlvIT09dm9pZCAwJiYobi5yZWZyYWN0aW9uUmF0aW89dGhpcy5yZWZyYWN0aW9uUmF0aW8pLHRoaXMuZ3JhZGllbnRNYXAmJnRoaXMuZ3JhZGllbnRNYXAuaXNUZXh0dXJlJiYobi5ncmFkaWVudE1hcD10aGlzLmdyYWRpZW50TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnRyYW5zbWlzc2lvbiE9PXZvaWQgMCYmKG4udHJhbnNtaXNzaW9uPXRoaXMudHJhbnNtaXNzaW9uKSx0aGlzLnRyYW5zbWlzc2lvbk1hcCYmdGhpcy50cmFuc21pc3Npb25NYXAuaXNUZXh0dXJlJiYobi50cmFuc21pc3Npb25NYXA9dGhpcy50cmFuc21pc3Npb25NYXAudG9KU09OKHQpLnV1aWQpLHRoaXMudGhpY2tuZXNzIT09dm9pZCAwJiYobi50aGlja25lc3M9dGhpcy50aGlja25lc3MpLHRoaXMudGhpY2tuZXNzTWFwJiZ0aGlzLnRoaWNrbmVzc01hcC5pc1RleHR1cmUmJihuLnRoaWNrbmVzc01hcD10aGlzLnRoaWNrbmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5hdHRlbnVhdGlvbkRpc3RhbmNlIT09dm9pZCAwJiZ0aGlzLmF0dGVudWF0aW9uRGlzdGFuY2UhPT0xLzAmJihuLmF0dGVudWF0aW9uRGlzdGFuY2U9dGhpcy5hdHRlbnVhdGlvbkRpc3RhbmNlKSx0aGlzLmF0dGVudWF0aW9uQ29sb3IhPT12b2lkIDAmJihuLmF0dGVudWF0aW9uQ29sb3I9dGhpcy5hdHRlbnVhdGlvbkNvbG9yLmdldEhleCgpKSx0aGlzLnNpemUhPT12b2lkIDAmJihuLnNpemU9dGhpcy5zaXplKSx0aGlzLnNoYWRvd1NpZGUhPT1udWxsJiYobi5zaGFkb3dTaWRlPXRoaXMuc2hhZG93U2lkZSksdGhpcy5zaXplQXR0ZW51YXRpb24hPT12b2lkIDAmJihuLnNpemVBdHRlbnVhdGlvbj10aGlzLnNpemVBdHRlbnVhdGlvbiksdGhpcy5ibGVuZGluZyE9PTEmJihuLmJsZW5kaW5nPXRoaXMuYmxlbmRpbmcpLHRoaXMuc2lkZSE9PTAmJihuLnNpZGU9dGhpcy5zaWRlKSx0aGlzLnZlcnRleENvbG9ycz09PSEwJiYobi52ZXJ0ZXhDb2xvcnM9ITApLHRoaXMub3BhY2l0eTwxJiYobi5vcGFjaXR5PXRoaXMub3BhY2l0eSksdGhpcy50cmFuc3BhcmVudD09PSEwJiYobi50cmFuc3BhcmVudD0hMCksdGhpcy5ibGVuZFNyYyE9PTIwNCYmKG4uYmxlbmRTcmM9dGhpcy5ibGVuZFNyYyksdGhpcy5ibGVuZERzdCE9PTIwNSYmKG4uYmxlbmREc3Q9dGhpcy5ibGVuZERzdCksdGhpcy5ibGVuZEVxdWF0aW9uIT09MTAwJiYobi5ibGVuZEVxdWF0aW9uPXRoaXMuYmxlbmRFcXVhdGlvbiksdGhpcy5ibGVuZFNyY0FscGhhIT09bnVsbCYmKG4uYmxlbmRTcmNBbHBoYT10aGlzLmJsZW5kU3JjQWxwaGEpLHRoaXMuYmxlbmREc3RBbHBoYSE9PW51bGwmJihuLmJsZW5kRHN0QWxwaGE9dGhpcy5ibGVuZERzdEFscGhhKSx0aGlzLmJsZW5kRXF1YXRpb25BbHBoYSE9PW51bGwmJihuLmJsZW5kRXF1YXRpb25BbHBoYT10aGlzLmJsZW5kRXF1YXRpb25BbHBoYSksdGhpcy5ibGVuZENvbG9yJiZ0aGlzLmJsZW5kQ29sb3IuaXNDb2xvciYmKG4uYmxlbmRDb2xvcj10aGlzLmJsZW5kQ29sb3IuZ2V0SGV4KCkpLHRoaXMuYmxlbmRBbHBoYSE9PTAmJihuLmJsZW5kQWxwaGE9dGhpcy5ibGVuZEFscGhhKSx0aGlzLmRlcHRoRnVuYyE9PTMmJihuLmRlcHRoRnVuYz10aGlzLmRlcHRoRnVuYyksdGhpcy5kZXB0aFRlc3Q9PT0hMSYmKG4uZGVwdGhUZXN0PXRoaXMuZGVwdGhUZXN0KSx0aGlzLmRlcHRoV3JpdGU9PT0hMSYmKG4uZGVwdGhXcml0ZT10aGlzLmRlcHRoV3JpdGUpLHRoaXMuY29sb3JXcml0ZT09PSExJiYobi5jb2xvcldyaXRlPXRoaXMuY29sb3JXcml0ZSksdGhpcy5zdGVuY2lsV3JpdGVNYXNrIT09MjU1JiYobi5zdGVuY2lsV3JpdGVNYXNrPXRoaXMuc3RlbmNpbFdyaXRlTWFzayksdGhpcy5zdGVuY2lsRnVuYyE9PTUxOSYmKG4uc3RlbmNpbEZ1bmM9dGhpcy5zdGVuY2lsRnVuYyksdGhpcy5zdGVuY2lsUmVmIT09MCYmKG4uc3RlbmNpbFJlZj10aGlzLnN0ZW5jaWxSZWYpLHRoaXMuc3RlbmNpbEZ1bmNNYXNrIT09MjU1JiYobi5zdGVuY2lsRnVuY01hc2s9dGhpcy5zdGVuY2lsRnVuY01hc2spLHRoaXMuc3RlbmNpbEZhaWwhPT03NjgwJiYobi5zdGVuY2lsRmFpbD10aGlzLnN0ZW5jaWxGYWlsKSx0aGlzLnN0ZW5jaWxaRmFpbCE9PTc2ODAmJihuLnN0ZW5jaWxaRmFpbD10aGlzLnN0ZW5jaWxaRmFpbCksdGhpcy5zdGVuY2lsWlBhc3MhPT03NjgwJiYobi5zdGVuY2lsWlBhc3M9dGhpcy5zdGVuY2lsWlBhc3MpLHRoaXMuc3RlbmNpbFdyaXRlPT09ITAmJihuLnN0ZW5jaWxXcml0ZT10aGlzLnN0ZW5jaWxXcml0ZSksdGhpcy5yb3RhdGlvbiE9PXZvaWQgMCYmdGhpcy5yb3RhdGlvbiE9PTAmJihuLnJvdGF0aW9uPXRoaXMucm90YXRpb24pLHRoaXMucG9seWdvbk9mZnNldD09PSEwJiYobi5wb2x5Z29uT2Zmc2V0PSEwKSx0aGlzLnBvbHlnb25PZmZzZXRGYWN0b3IhPT0wJiYobi5wb2x5Z29uT2Zmc2V0RmFjdG9yPXRoaXMucG9seWdvbk9mZnNldEZhY3RvciksdGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHMhPT0wJiYobi5wb2x5Z29uT2Zmc2V0VW5pdHM9dGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHMpLHRoaXMubGluZXdpZHRoIT09dm9pZCAwJiZ0aGlzLmxpbmV3aWR0aCE9PTEmJihuLmxpbmV3aWR0aD10aGlzLmxpbmV3aWR0aCksdGhpcy5kYXNoU2l6ZSE9PXZvaWQgMCYmKG4uZGFzaFNpemU9dGhpcy5kYXNoU2l6ZSksdGhpcy5nYXBTaXplIT09dm9pZCAwJiYobi5nYXBTaXplPXRoaXMuZ2FwU2l6ZSksdGhpcy5zY2FsZSE9PXZvaWQgMCYmKG4uc2NhbGU9dGhpcy5zY2FsZSksdGhpcy5kaXRoZXJpbmc9PT0hMCYmKG4uZGl0aGVyaW5nPSEwKSx0aGlzLmFscGhhVGVzdD4wJiYobi5hbHBoYVRlc3Q9dGhpcy5hbHBoYVRlc3QpLHRoaXMuYWxwaGFIYXNoPT09ITAmJihuLmFscGhhSGFzaD0hMCksdGhpcy5hbHBoYVRvQ292ZXJhZ2U9PT0hMCYmKG4uYWxwaGFUb0NvdmVyYWdlPSEwKSx0aGlzLnByZW11bHRpcGxpZWRBbHBoYT09PSEwJiYobi5wcmVtdWx0aXBsaWVkQWxwaGE9ITApLHRoaXMuZm9yY2VTaW5nbGVQYXNzPT09ITAmJihuLmZvcmNlU2luZ2xlUGFzcz0hMCksdGhpcy53aXJlZnJhbWU9PT0hMCYmKG4ud2lyZWZyYW1lPSEwKSx0aGlzLndpcmVmcmFtZUxpbmV3aWR0aD4xJiYobi53aXJlZnJhbWVMaW5ld2lkdGg9dGhpcy53aXJlZnJhbWVMaW5ld2lkdGgpLHRoaXMud2lyZWZyYW1lTGluZWNhcCE9PSJyb3VuZCImJihuLndpcmVmcmFtZUxpbmVjYXA9dGhpcy53aXJlZnJhbWVMaW5lY2FwKSx0aGlzLndpcmVmcmFtZUxpbmVqb2luIT09InJvdW5kIiYmKG4ud2lyZWZyYW1lTGluZWpvaW49dGhpcy53aXJlZnJhbWVMaW5lam9pbiksdGhpcy5mbGF0U2hhZGluZz09PSEwJiYobi5mbGF0U2hhZGluZz0hMCksdGhpcy52aXNpYmxlPT09ITEmJihuLnZpc2libGU9ITEpLHRoaXMudG9uZU1hcHBlZD09PSExJiYobi50b25lTWFwcGVkPSExKSx0aGlzLmZvZz09PSExJiYobi5mb2c9ITEpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYobi51c2VyRGF0YT10aGlzLnVzZXJEYXRhKTtmdW5jdGlvbiBzKHIpe2NvbnN0IG89W107Zm9yKGNvbnN0IGEgaW4gcil7Y29uc3QgYz1yW2FdO2RlbGV0ZSBjLm1ldGFkYXRhLG8ucHVzaChjKX1yZXR1cm4gb31pZihlKXtjb25zdCByPXModC50ZXh0dXJlcyksbz1zKHQuaW1hZ2VzKTtyLmxlbmd0aD4wJiYobi50ZXh0dXJlcz1yKSxvLmxlbmd0aD4wJiYobi5pbWFnZXM9byl9cmV0dXJuIG59Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7dGhpcy5uYW1lPXQubmFtZSx0aGlzLmJsZW5kaW5nPXQuYmxlbmRpbmcsdGhpcy5zaWRlPXQuc2lkZSx0aGlzLnZlcnRleENvbG9ycz10LnZlcnRleENvbG9ycyx0aGlzLm9wYWNpdHk9dC5vcGFjaXR5LHRoaXMudHJhbnNwYXJlbnQ9dC50cmFuc3BhcmVudCx0aGlzLmJsZW5kU3JjPXQuYmxlbmRTcmMsdGhpcy5ibGVuZERzdD10LmJsZW5kRHN0LHRoaXMuYmxlbmRFcXVhdGlvbj10LmJsZW5kRXF1YXRpb24sdGhpcy5ibGVuZFNyY0FscGhhPXQuYmxlbmRTcmNBbHBoYSx0aGlzLmJsZW5kRHN0QWxwaGE9dC5ibGVuZERzdEFscGhhLHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhPXQuYmxlbmRFcXVhdGlvbkFscGhhLHRoaXMuYmxlbmRDb2xvci5jb3B5KHQuYmxlbmRDb2xvciksdGhpcy5ibGVuZEFscGhhPXQuYmxlbmRBbHBoYSx0aGlzLmRlcHRoRnVuYz10LmRlcHRoRnVuYyx0aGlzLmRlcHRoVGVzdD10LmRlcHRoVGVzdCx0aGlzLmRlcHRoV3JpdGU9dC5kZXB0aFdyaXRlLHRoaXMuc3RlbmNpbFdyaXRlTWFzaz10LnN0ZW5jaWxXcml0ZU1hc2ssdGhpcy5zdGVuY2lsRnVuYz10LnN0ZW5jaWxGdW5jLHRoaXMuc3RlbmNpbFJlZj10LnN0ZW5jaWxSZWYsdGhpcy5zdGVuY2lsRnVuY01hc2s9dC5zdGVuY2lsRnVuY01hc2ssdGhpcy5zdGVuY2lsRmFpbD10LnN0ZW5jaWxGYWlsLHRoaXMuc3RlbmNpbFpGYWlsPXQuc3RlbmNpbFpGYWlsLHRoaXMuc3RlbmNpbFpQYXNzPXQuc3RlbmNpbFpQYXNzLHRoaXMuc3RlbmNpbFdyaXRlPXQuc3RlbmNpbFdyaXRlO2NvbnN0IGU9dC5jbGlwcGluZ1BsYW5lcztsZXQgbj1udWxsO2lmKGUhPT1udWxsKXtjb25zdCBzPWUubGVuZ3RoO249bmV3IEFycmF5KHMpO2ZvcihsZXQgcj0wO3IhPT1zOysrciluW3JdPWVbcl0uY2xvbmUoKX1yZXR1cm4gdGhpcy5jbGlwcGluZ1BsYW5lcz1uLHRoaXMuY2xpcEludGVyc2VjdGlvbj10LmNsaXBJbnRlcnNlY3Rpb24sdGhpcy5jbGlwU2hhZG93cz10LmNsaXBTaGFkb3dzLHRoaXMuc2hhZG93U2lkZT10LnNoYWRvd1NpZGUsdGhpcy5jb2xvcldyaXRlPXQuY29sb3JXcml0ZSx0aGlzLnByZWNpc2lvbj10LnByZWNpc2lvbix0aGlzLnBvbHlnb25PZmZzZXQ9dC5wb2x5Z29uT2Zmc2V0LHRoaXMucG9seWdvbk9mZnNldEZhY3Rvcj10LnBvbHlnb25PZmZzZXRGYWN0b3IsdGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHM9dC5wb2x5Z29uT2Zmc2V0VW5pdHMsdGhpcy5kaXRoZXJpbmc9dC5kaXRoZXJpbmcsdGhpcy5hbHBoYVRlc3Q9dC5hbHBoYVRlc3QsdGhpcy5hbHBoYUhhc2g9dC5hbHBoYUhhc2gsdGhpcy5hbHBoYVRvQ292ZXJhZ2U9dC5hbHBoYVRvQ292ZXJhZ2UsdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE9dC5wcmVtdWx0aXBsaWVkQWxwaGEsdGhpcy5mb3JjZVNpbmdsZVBhc3M9dC5mb3JjZVNpbmdsZVBhc3MsdGhpcy52aXNpYmxlPXQudmlzaWJsZSx0aGlzLnRvbmVNYXBwZWQ9dC50b25lTWFwcGVkLHRoaXMudXNlckRhdGE9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0LnVzZXJEYXRhKSksdGhpc31kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfXNldCBuZWVkc1VwZGF0ZSh0KXt0PT09ITAmJnRoaXMudmVyc2lvbisrfX1jbGFzcyB5ZiBleHRlbmRzIHBme2NvbnN0cnVjdG9yKHQpe3N1cGVyKCksdGhpcy5pc01lc2hCYXNpY01hdGVyaWFsPSEwLHRoaXMudHlwZT0iTWVzaEJhc2ljTWF0ZXJpYWwiLHRoaXMuY29sb3I9bmV3IHlzKDE2Nzc3MjE1KSx0aGlzLm1hcD1udWxsLHRoaXMubGlnaHRNYXA9bnVsbCx0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5PTEsdGhpcy5hb01hcD1udWxsLHRoaXMuYW9NYXBJbnRlbnNpdHk9MSx0aGlzLnNwZWN1bGFyTWFwPW51bGwsdGhpcy5hbHBoYU1hcD1udWxsLHRoaXMuZW52TWFwPW51bGwsdGhpcy5lbnZNYXBSb3RhdGlvbj1uZXcgYmksdGhpcy5jb21iaW5lPTAsdGhpcy5yZWZsZWN0aXZpdHk9MSx0aGlzLnJlZnJhY3Rpb25SYXRpbz0uOTgsdGhpcy53aXJlZnJhbWU9ITEsdGhpcy53aXJlZnJhbWVMaW5ld2lkdGg9MSx0aGlzLndpcmVmcmFtZUxpbmVjYXA9InJvdW5kIix0aGlzLndpcmVmcmFtZUxpbmVqb2luPSJyb3VuZCIsdGhpcy5mb2c9ITAsdGhpcy5zZXRWYWx1ZXModCl9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLmNvbG9yLmNvcHkodC5jb2xvciksdGhpcy5tYXA9dC5tYXAsdGhpcy5saWdodE1hcD10LmxpZ2h0TWFwLHRoaXMubGlnaHRNYXBJbnRlbnNpdHk9dC5saWdodE1hcEludGVuc2l0eSx0aGlzLmFvTWFwPXQuYW9NYXAsdGhpcy5hb01hcEludGVuc2l0eT10LmFvTWFwSW50ZW5zaXR5LHRoaXMuc3BlY3VsYXJNYXA9dC5zcGVjdWxhck1hcCx0aGlzLmFscGhhTWFwPXQuYWxwaGFNYXAsdGhpcy5lbnZNYXA9dC5lbnZNYXAsdGhpcy5lbnZNYXBSb3RhdGlvbi5jb3B5KHQuZW52TWFwUm90YXRpb24pLHRoaXMuY29tYmluZT10LmNvbWJpbmUsdGhpcy5yZWZsZWN0aXZpdHk9dC5yZWZsZWN0aXZpdHksdGhpcy5yZWZyYWN0aW9uUmF0aW89dC5yZWZyYWN0aW9uUmF0aW8sdGhpcy53aXJlZnJhbWU9dC53aXJlZnJhbWUsdGhpcy53aXJlZnJhbWVMaW5ld2lkdGg9dC53aXJlZnJhbWVMaW5ld2lkdGgsdGhpcy53aXJlZnJhbWVMaW5lY2FwPXQud2lyZWZyYW1lTGluZWNhcCx0aGlzLndpcmVmcmFtZUxpbmVqb2luPXQud2lyZWZyYW1lTGluZWpvaW4sdGhpcy5mb2c9dC5mb2csdGhpc319Y29uc3QgcHQ9bmV3IFQsbXM9bmV3IFI7bGV0IG1mPTA7Y2xhc3MgeHR7Y29uc3RydWN0b3IodCxlLG49ITEpe2lmKEFycmF5LmlzQXJyYXkodCkpdGhyb3cgbmV3IFR5cGVFcnJvcigiVEhSRUUuQnVmZmVyQXR0cmlidXRlOiBhcnJheSBzaG91bGQgYmUgYSBUeXBlZCBBcnJheS4iKTt0aGlzLmlzQnVmZmVyQXR0cmlidXRlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOm1mKyt9KSx0aGlzLm5hbWU9IiIsdGhpcy5hcnJheT10LHRoaXMuaXRlbVNpemU9ZSx0aGlzLmNvdW50PXQhPT12b2lkIDA/dC5sZW5ndGgvZTowLHRoaXMubm9ybWFsaXplZD1uLHRoaXMudXNhZ2U9MzUwNDQsdGhpcy51cGRhdGVSYW5nZXM9W10sdGhpcy5ncHVUeXBlPTEwMTUsdGhpcy52ZXJzaW9uPTB9b25VcGxvYWRDYWxsYmFjaygpe31zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK31zZXRVc2FnZSh0KXtyZXR1cm4gdGhpcy51c2FnZT10LHRoaXN9YWRkVXBkYXRlUmFuZ2UodCxlKXt0aGlzLnVwZGF0ZVJhbmdlcy5wdXNoKHtzdGFydDp0LGNvdW50OmV9KX1jbGVhclVwZGF0ZVJhbmdlcygpe3RoaXMudXBkYXRlUmFuZ2VzLmxlbmd0aD0wfWNvcHkodCl7cmV0dXJuIHRoaXMubmFtZT10Lm5hbWUsdGhpcy5hcnJheT1uZXcgdC5hcnJheS5jb25zdHJ1Y3Rvcih0LmFycmF5KSx0aGlzLml0ZW1TaXplPXQuaXRlbVNpemUsdGhpcy5jb3VudD10LmNvdW50LHRoaXMubm9ybWFsaXplZD10Lm5vcm1hbGl6ZWQsdGhpcy51c2FnZT10LnVzYWdlLHRoaXMuZ3B1VHlwZT10LmdwdVR5cGUsdGhpc31jb3B5QXQodCxlLG4pe3QqPXRoaXMuaXRlbVNpemUsbio9ZS5pdGVtU2l6ZTtmb3IobGV0IHM9MCxyPXRoaXMuaXRlbVNpemU7czxyO3MrKyl0aGlzLmFycmF5W3Qrc109ZS5hcnJheVtuK3NdO3JldHVybiB0aGlzfWNvcHlBcnJheSh0KXtyZXR1cm4gdGhpcy5hcnJheS5zZXQodCksdGhpc31hcHBseU1hdHJpeDModCl7aWYodGhpcy5pdGVtU2l6ZT09PTIpZm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspbXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLG1zLmFwcGx5TWF0cml4Myh0KSx0aGlzLnNldFhZKGUsbXMueCxtcy55KTtlbHNlIGlmKHRoaXMuaXRlbVNpemU9PT0zKWZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC5hcHBseU1hdHJpeDModCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9YXBwbHlNYXRyaXg0KHQpe2ZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC5hcHBseU1hdHJpeDQodCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9YXBwbHlOb3JtYWxNYXRyaXgodCl7Zm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LmFwcGx5Tm9ybWFsTWF0cml4KHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfXRyYW5zZm9ybURpcmVjdGlvbih0KXtmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQudHJhbnNmb3JtRGlyZWN0aW9uKHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfXNldCh0LGU9MCl7cmV0dXJuIHRoaXMuYXJyYXkuc2V0KHQsZSksdGhpc31nZXRDb21wb25lbnQodCxlKXtsZXQgbj10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZStlXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYobj1taShuLHRoaXMuYXJyYXkpKSxufXNldENvbXBvbmVudCh0LGUsbil7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKG49SXQobix0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrZV09bix0aGlzfWdldFgodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemVdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0WCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplXT1lLHRoaXN9Z2V0WSh0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsxXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1taShlLHRoaXMuYXJyYXkpKSxlfXNldFkodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsxXT1lLHRoaXN9Z2V0Wih0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsyXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1taShlLHRoaXMuYXJyYXkpKSxlfXNldFoodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsyXT1lLHRoaXN9Z2V0Vyh0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSszXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1taShlLHRoaXMuYXJyYXkpKSxlfXNldFcodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSszXT1lLHRoaXN9c2V0WFkodCxlLG4pe3JldHVybiB0Kj10aGlzLml0ZW1TaXplLHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSxuPUl0KG4sdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCswXT1lLHRoaXMuYXJyYXlbdCsxXT1uLHRoaXN9c2V0WFlaKHQsZSxuLHMpe3JldHVybiB0Kj10aGlzLml0ZW1TaXplLHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSxuPUl0KG4sdGhpcy5hcnJheSkscz1JdChzLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QrMF09ZSx0aGlzLmFycmF5W3QrMV09bix0aGlzLmFycmF5W3QrMl09cyx0aGlzfXNldFhZWlcodCxlLG4scyxyKXtyZXR1cm4gdCo9dGhpcy5pdGVtU2l6ZSx0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSksbj1JdChuLHRoaXMuYXJyYXkpLHM9SXQocyx0aGlzLmFycmF5KSxyPUl0KHIsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCswXT1lLHRoaXMuYXJyYXlbdCsxXT1uLHRoaXMuYXJyYXlbdCsyXT1zLHRoaXMuYXJyYXlbdCszXT1yLHRoaXN9b25VcGxvYWQodCl7cmV0dXJuIHRoaXMub25VcGxvYWRDYWxsYmFjaz10LHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5hcnJheSx0aGlzLml0ZW1TaXplKS5jb3B5KHRoaXMpfXRvSlNPTigpe2NvbnN0IHQ9e2l0ZW1TaXplOnRoaXMuaXRlbVNpemUsdHlwZTp0aGlzLmFycmF5LmNvbnN0cnVjdG9yLm5hbWUsYXJyYXk6QXJyYXkuZnJvbSh0aGlzLmFycmF5KSxub3JtYWxpemVkOnRoaXMubm9ybWFsaXplZH07cmV0dXJuIHRoaXMubmFtZSE9PSIiJiYodC5uYW1lPXRoaXMubmFtZSksdGhpcy51c2FnZSE9PTM1MDQ0JiYodC51c2FnZT10aGlzLnVzYWdlKSx0fX1jbGFzcyBnZiBleHRlbmRzIHh0e2NvbnN0cnVjdG9yKHQsZSxuKXtzdXBlcihuZXcgVWludDE2QXJyYXkodCksZSxuKX19Y2xhc3MgeGYgZXh0ZW5kcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbil7c3VwZXIobmV3IFVpbnQzMkFycmF5KHQpLGUsbil9fWNsYXNzIEJlIGV4dGVuZHMgeHR7Y29uc3RydWN0b3IodCxlLG4pe3N1cGVyKG5ldyBGbG9hdDMyQXJyYXkodCksZSxuKX19bGV0IHdmPTA7Y29uc3QganQ9bmV3IHN0LFNvPW5ldyBFZSxxbj1uZXcgVCxWdD1uZXcgZ3QsQWk9bmV3IGd0LGJ0PW5ldyBUO2NsYXNzIHVlIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNCdWZmZXJHZW9tZXRyeT0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTp3ZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iQnVmZmVyR2VvbWV0cnkiLHRoaXMuaW5kZXg9bnVsbCx0aGlzLmluZGlyZWN0PW51bGwsdGhpcy5hdHRyaWJ1dGVzPXt9LHRoaXMubW9ycGhBdHRyaWJ1dGVzPXt9LHRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU9ITEsdGhpcy5ncm91cHM9W10sdGhpcy5ib3VuZGluZ0JveD1udWxsLHRoaXMuYm91bmRpbmdTcGhlcmU9bnVsbCx0aGlzLmRyYXdSYW5nZT17c3RhcnQ6MCxjb3VudDoxLzB9LHRoaXMudXNlckRhdGE9e319Z2V0SW5kZXgoKXtyZXR1cm4gdGhpcy5pbmRleH1zZXRJbmRleCh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90aGlzLmluZGV4PW5ldyhRdSh0KT94ZjpnZikodCwxKTp0aGlzLmluZGV4PXQsdGhpc31zZXRJbmRpcmVjdCh0KXtyZXR1cm4gdGhpcy5pbmRpcmVjdD10LHRoaXN9Z2V0SW5kaXJlY3QoKXtyZXR1cm4gdGhpcy5pbmRpcmVjdH1nZXRBdHRyaWJ1dGUodCl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XX1zZXRBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdPWUsdGhpc31kZWxldGVBdHRyaWJ1dGUodCl7cmV0dXJuIGRlbGV0ZSB0aGlzLmF0dHJpYnV0ZXNbdF0sdGhpc31oYXNBdHRyaWJ1dGUodCl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XSE9PXZvaWQgMH1hZGRHcm91cCh0LGUsbj0wKXt0aGlzLmdyb3Vwcy5wdXNoKHtzdGFydDp0LGNvdW50OmUsbWF0ZXJpYWxJbmRleDpufSl9Y2xlYXJHcm91cHMoKXt0aGlzLmdyb3Vwcz1bXX1zZXREcmF3UmFuZ2UodCxlKXt0aGlzLmRyYXdSYW5nZS5zdGFydD10LHRoaXMuZHJhd1JhbmdlLmNvdW50PWV9YXBwbHlNYXRyaXg0KHQpe2NvbnN0IGU9dGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uO2UhPT12b2lkIDAmJihlLmFwcGx5TWF0cml4NCh0KSxlLm5lZWRzVXBkYXRlPSEwKTtjb25zdCBuPXRoaXMuYXR0cmlidXRlcy5ub3JtYWw7aWYobiE9PXZvaWQgMCl7Y29uc3Qgcj1uZXcgZ2UoKS5nZXROb3JtYWxNYXRyaXgodCk7bi5hcHBseU5vcm1hbE1hdHJpeChyKSxuLm5lZWRzVXBkYXRlPSEwfWNvbnN0IHM9dGhpcy5hdHRyaWJ1dGVzLnRhbmdlbnQ7cmV0dXJuIHMhPT12b2lkIDAmJihzLnRyYW5zZm9ybURpcmVjdGlvbih0KSxzLm5lZWRzVXBkYXRlPSEwKSx0aGlzLmJvdW5kaW5nQm94IT09bnVsbCYmdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKSx0aGlzLmJvdW5kaW5nU3BoZXJlIT09bnVsbCYmdGhpcy5jb21wdXRlQm91bmRpbmdTcGhlcmUoKSx0aGlzfWFwcGx5UXVhdGVybmlvbih0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9cm90YXRlWCh0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uWCh0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31yb3RhdGVZKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25ZKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXJvdGF0ZVoodCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvbloodCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9dHJhbnNsYXRlKHQsZSxuKXtyZXR1cm4ganQubWFrZVRyYW5zbGF0aW9uKHQsZSxuKSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31zY2FsZSh0LGUsbil7cmV0dXJuIGp0Lm1ha2VTY2FsZSh0LGUsbiksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9bG9va0F0KHQpe3JldHVybiBTby5sb29rQXQodCksU28udXBkYXRlTWF0cml4KCksdGhpcy5hcHBseU1hdHJpeDQoU28ubWF0cml4KSx0aGlzfWNlbnRlcigpe3JldHVybiB0aGlzLmNvbXB1dGVCb3VuZGluZ0JveCgpLHRoaXMuYm91bmRpbmdCb3guZ2V0Q2VudGVyKHFuKS5uZWdhdGUoKSx0aGlzLnRyYW5zbGF0ZShxbi54LHFuLnkscW4ueiksdGhpc31zZXRGcm9tUG9pbnRzKHQpe2NvbnN0IGU9dGhpcy5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIik7aWYoZT09PXZvaWQgMCl7Y29uc3Qgbj1bXTtmb3IobGV0IHM9MCxyPXQubGVuZ3RoO3M8cjtzKyspe2NvbnN0IG89dFtzXTtuLnB1c2goby54LG8ueSxvLnp8fDApfXRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsbmV3IEJlKG4sMykpfWVsc2V7Y29uc3Qgbj1NYXRoLm1pbih0Lmxlbmd0aCxlLmNvdW50KTtmb3IobGV0IHM9MDtzPG47cysrKXtjb25zdCByPXRbc107ZS5zZXRYWVoocyxyLngsci55LHIuenx8MCl9dC5sZW5ndGg+ZS5jb3VudCYmY29uc29sZS53YXJuKCJUSFJFRS5CdWZmZXJHZW9tZXRyeTogQnVmZmVyIHNpemUgdG9vIHNtYWxsIGZvciBwb2ludHMgZGF0YS4gVXNlIC5kaXNwb3NlKCkgYW5kIGNyZWF0ZSBhIG5ldyBnZW9tZXRyeS4iKSxlLm5lZWRzVXBkYXRlPSEwfXJldHVybiB0aGlzfWNvbXB1dGVCb3VuZGluZ0JveCgpe3RoaXMuYm91bmRpbmdCb3g9PT1udWxsJiYodGhpcy5ib3VuZGluZ0JveD1uZXcgZ3QpO2NvbnN0IHQ9dGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uLGU9dGhpcy5tb3JwaEF0dHJpYnV0ZXMucG9zaXRpb247aWYodCYmdC5pc0dMQnVmZmVyQXR0cmlidXRlKXtjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTogR0xCdWZmZXJBdHRyaWJ1dGUgcmVxdWlyZXMgYSBtYW51YWwgYm91bmRpbmcgYm94LiIsdGhpcyksdGhpcy5ib3VuZGluZ0JveC5zZXQobmV3IFQoLTEvMCwtMS8wLC0xLzApLG5ldyBUKDEvMCwxLzAsMS8wKSk7cmV0dXJufWlmKHQhPT12b2lkIDApe2lmKHRoaXMuYm91bmRpbmdCb3guc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSh0KSxlKWZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyl7Y29uc3Qgcj1lW25dO1Z0LnNldEZyb21CdWZmZXJBdHRyaWJ1dGUociksdGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT8oYnQuYWRkVmVjdG9ycyh0aGlzLmJvdW5kaW5nQm94Lm1pbixWdC5taW4pLHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChidCksYnQuYWRkVmVjdG9ycyh0aGlzLmJvdW5kaW5nQm94Lm1heCxWdC5tYXgpLHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChidCkpOih0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoVnQubWluKSx0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoVnQubWF4KSl9fWVsc2UgdGhpcy5ib3VuZGluZ0JveC5tYWtlRW1wdHkoKTsoaXNOYU4odGhpcy5ib3VuZGluZ0JveC5taW4ueCl8fGlzTmFOKHRoaXMuYm91bmRpbmdCb3gubWluLnkpfHxpc05hTih0aGlzLmJvdW5kaW5nQm94Lm1pbi56KSkmJmNvbnNvbGUuZXJyb3IoJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ0JveCgpOiBDb21wdXRlZCBtaW4vbWF4IGhhdmUgTmFOIHZhbHVlcy4gVGhlICJwb3NpdGlvbiIgYXR0cmlidXRlIGlzIGxpa2VseSB0byBoYXZlIE5hTiB2YWx1ZXMuJyx0aGlzKX1jb21wdXRlQm91bmRpbmdTcGhlcmUoKXt0aGlzLmJvdW5kaW5nU3BoZXJlPT09bnVsbCYmKHRoaXMuYm91bmRpbmdTcGhlcmU9bmV3IGNvKTtjb25zdCB0PXRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbixlPXRoaXMubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uO2lmKHQmJnQuaXNHTEJ1ZmZlckF0dHJpYnV0ZSl7Y29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCk6IEdMQnVmZmVyQXR0cmlidXRlIHJlcXVpcmVzIGEgbWFudWFsIGJvdW5kaW5nIHNwaGVyZS4iLHRoaXMpLHRoaXMuYm91bmRpbmdTcGhlcmUuc2V0KG5ldyBULDEvMCk7cmV0dXJufWlmKHQpe2NvbnN0IG49dGhpcy5ib3VuZGluZ1NwaGVyZS5jZW50ZXI7aWYoVnQuc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSh0KSxlKWZvcihsZXQgcj0wLG89ZS5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1lW3JdO0FpLnNldEZyb21CdWZmZXJBdHRyaWJ1dGUoYSksdGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT8oYnQuYWRkVmVjdG9ycyhWdC5taW4sQWkubWluKSxWdC5leHBhbmRCeVBvaW50KGJ0KSxidC5hZGRWZWN0b3JzKFZ0Lm1heCxBaS5tYXgpLFZ0LmV4cGFuZEJ5UG9pbnQoYnQpKTooVnQuZXhwYW5kQnlQb2ludChBaS5taW4pLFZ0LmV4cGFuZEJ5UG9pbnQoQWkubWF4KSl9VnQuZ2V0Q2VudGVyKG4pO2xldCBzPTA7Zm9yKGxldCByPTAsbz10LmNvdW50O3I8bztyKyspYnQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LHIpLHM9TWF0aC5tYXgocyxuLmRpc3RhbmNlVG9TcXVhcmVkKGJ0KSk7aWYoZSlmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVtyXSxjPXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU7Zm9yKGxldCBsPTAsaD1hLmNvdW50O2w8aDtsKyspYnQuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGwpLGMmJihxbi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsbCksYnQuYWRkKHFuKSkscz1NYXRoLm1heChzLG4uZGlzdGFuY2VUb1NxdWFyZWQoYnQpKX10aGlzLmJvdW5kaW5nU3BoZXJlLnJhZGl1cz1NYXRoLnNxcnQocyksaXNOYU4odGhpcy5ib3VuZGluZ1NwaGVyZS5yYWRpdXMpJiZjb25zb2xlLmVycm9yKCdUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTogQ29tcHV0ZWQgcmFkaXVzIGlzIE5hTi4gVGhlICJwb3NpdGlvbiIgYXR0cmlidXRlIGlzIGxpa2VseSB0byBoYXZlIE5hTiB2YWx1ZXMuJyx0aGlzKX19Y29tcHV0ZVRhbmdlbnRzKCl7Y29uc3QgdD10aGlzLmluZGV4LGU9dGhpcy5hdHRyaWJ1dGVzO2lmKHQ9PT1udWxsfHxlLnBvc2l0aW9uPT09dm9pZCAwfHxlLm5vcm1hbD09PXZvaWQgMHx8ZS51dj09PXZvaWQgMCl7Y29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnk6IC5jb21wdXRlVGFuZ2VudHMoKSBmYWlsZWQuIE1pc3NpbmcgcmVxdWlyZWQgYXR0cmlidXRlcyAoaW5kZXgsIHBvc2l0aW9uLCBub3JtYWwgb3IgdXYpIik7cmV0dXJufWNvbnN0IG49ZS5wb3NpdGlvbixzPWUubm9ybWFsLHI9ZS51djt0aGlzLmhhc0F0dHJpYnV0ZSgidGFuZ2VudCIpPT09ITEmJnRoaXMuc2V0QXR0cmlidXRlKCJ0YW5nZW50IixuZXcgeHQobmV3IEZsb2F0MzJBcnJheSg0Km4uY291bnQpLDQpKTtjb25zdCBvPXRoaXMuZ2V0QXR0cmlidXRlKCJ0YW5nZW50IiksYT1bXSxjPVtdO2ZvcihsZXQgXz0wO188bi5jb3VudDtfKyspYVtfXT1uZXcgVCxjW19dPW5ldyBUO2NvbnN0IGw9bmV3IFQsaD1uZXcgVCx1PW5ldyBULGY9bmV3IFIsZD1uZXcgUixwPW5ldyBSLHk9bmV3IFQsbT1uZXcgVDtmdW5jdGlvbiBnKF8sRSx6KXtsLmZyb21CdWZmZXJBdHRyaWJ1dGUobixfKSxoLmZyb21CdWZmZXJBdHRyaWJ1dGUobixFKSx1LmZyb21CdWZmZXJBdHRyaWJ1dGUobix6KSxmLmZyb21CdWZmZXJBdHRyaWJ1dGUocixfKSxkLmZyb21CdWZmZXJBdHRyaWJ1dGUocixFKSxwLmZyb21CdWZmZXJBdHRyaWJ1dGUocix6KSxoLnN1YihsKSx1LnN1YihsKSxkLnN1YihmKSxwLnN1YihmKTtjb25zdCB2PTEvKGQueCpwLnktcC54KmQueSk7aXNGaW5pdGUodikmJih5LmNvcHkoaCkubXVsdGlwbHlTY2FsYXIocC55KS5hZGRTY2FsZWRWZWN0b3IodSwtZC55KS5tdWx0aXBseVNjYWxhcih2KSxtLmNvcHkodSkubXVsdGlwbHlTY2FsYXIoZC54KS5hZGRTY2FsZWRWZWN0b3IoaCwtcC54KS5tdWx0aXBseVNjYWxhcih2KSxhW19dLmFkZCh5KSxhW0VdLmFkZCh5KSxhW3pdLmFkZCh5KSxjW19dLmFkZChtKSxjW0VdLmFkZChtKSxjW3pdLmFkZChtKSl9bGV0IGI9dGhpcy5ncm91cHM7Yi5sZW5ndGg9PT0wJiYoYj1be3N0YXJ0OjAsY291bnQ6dC5jb3VudH1dKTtmb3IobGV0IF89MCxFPWIubGVuZ3RoO188RTsrK18pe2NvbnN0IHo9YltfXSx2PXouc3RhcnQsQz16LmNvdW50O2ZvcihsZXQgUD12LEY9ditDO1A8RjtQKz0zKWcodC5nZXRYKFArMCksdC5nZXRYKFArMSksdC5nZXRYKFArMikpfWNvbnN0IHc9bmV3IFQseD1uZXcgVCxNPW5ldyBULEE9bmV3IFQ7ZnVuY3Rpb24gUyhfKXtNLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxfKSxBLmNvcHkoTSk7Y29uc3QgRT1hW19dO3cuY29weShFKSx3LnN1YihNLm11bHRpcGx5U2NhbGFyKE0uZG90KEUpKSkubm9ybWFsaXplKCkseC5jcm9zc1ZlY3RvcnMoQSxFKTtjb25zdCB2PXguZG90KGNbX10pPDA/LTE6MTtvLnNldFhZWlcoXyx3Lngsdy55LHcueix2KX1mb3IobGV0IF89MCxFPWIubGVuZ3RoO188RTsrK18pe2NvbnN0IHo9YltfXSx2PXouc3RhcnQsQz16LmNvdW50O2ZvcihsZXQgUD12LEY9ditDO1A8RjtQKz0zKVModC5nZXRYKFArMCkpLFModC5nZXRYKFArMSkpLFModC5nZXRYKFArMikpfX1jb21wdXRlVmVydGV4Tm9ybWFscygpe2NvbnN0IHQ9dGhpcy5pbmRleCxlPXRoaXMuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpO2lmKGUhPT12b2lkIDApe2xldCBuPXRoaXMuZ2V0QXR0cmlidXRlKCJub3JtYWwiKTtpZihuPT09dm9pZCAwKW49bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkoZS5jb3VudCozKSwzKSx0aGlzLnNldEF0dHJpYnV0ZSgibm9ybWFsIixuKTtlbHNlIGZvcihsZXQgZj0wLGQ9bi5jb3VudDtmPGQ7ZisrKW4uc2V0WFlaKGYsMCwwLDApO2NvbnN0IHM9bmV3IFQscj1uZXcgVCxvPW5ldyBULGE9bmV3IFQsYz1uZXcgVCxsPW5ldyBULGg9bmV3IFQsdT1uZXcgVDtpZih0KWZvcihsZXQgZj0wLGQ9dC5jb3VudDtmPGQ7Zis9Myl7Y29uc3QgcD10LmdldFgoZiswKSx5PXQuZ2V0WChmKzEpLG09dC5nZXRYKGYrMik7cy5mcm9tQnVmZmVyQXR0cmlidXRlKGUscCksci5mcm9tQnVmZmVyQXR0cmlidXRlKGUseSksby5mcm9tQnVmZmVyQXR0cmlidXRlKGUsbSksaC5zdWJWZWN0b3JzKG8sciksdS5zdWJWZWN0b3JzKHMsciksaC5jcm9zcyh1KSxhLmZyb21CdWZmZXJBdHRyaWJ1dGUobixwKSxjLmZyb21CdWZmZXJBdHRyaWJ1dGUobix5KSxsLmZyb21CdWZmZXJBdHRyaWJ1dGUobixtKSxhLmFkZChoKSxjLmFkZChoKSxsLmFkZChoKSxuLnNldFhZWihwLGEueCxhLnksYS56KSxuLnNldFhZWih5LGMueCxjLnksYy56KSxuLnNldFhZWihtLGwueCxsLnksbC56KX1lbHNlIGZvcihsZXQgZj0wLGQ9ZS5jb3VudDtmPGQ7Zis9MylzLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxmKzApLHIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLGYrMSksby5mcm9tQnVmZmVyQXR0cmlidXRlKGUsZisyKSxoLnN1YlZlY3RvcnMobyxyKSx1LnN1YlZlY3RvcnMocyxyKSxoLmNyb3NzKHUpLG4uc2V0WFlaKGYrMCxoLngsaC55LGgueiksbi5zZXRYWVooZisxLGgueCxoLnksaC56KSxuLnNldFhZWihmKzIsaC54LGgueSxoLnopO3RoaXMubm9ybWFsaXplTm9ybWFscygpLG4ubmVlZHNVcGRhdGU9ITB9fW5vcm1hbGl6ZU5vcm1hbHMoKXtjb25zdCB0PXRoaXMuYXR0cmlidXRlcy5ub3JtYWw7Zm9yKGxldCBlPTAsbj10LmNvdW50O2U8bjtlKyspYnQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLGJ0Lm5vcm1hbGl6ZSgpLHQuc2V0WFlaKGUsYnQueCxidC55LGJ0LnopfXRvTm9uSW5kZXhlZCgpe2Z1bmN0aW9uIHQoYSxjKXtjb25zdCBsPWEuYXJyYXksaD1hLml0ZW1TaXplLHU9YS5ub3JtYWxpemVkLGY9bmV3IGwuY29uc3RydWN0b3IoYy5sZW5ndGgqaCk7bGV0IGQ9MCxwPTA7Zm9yKGxldCB5PTAsbT1jLmxlbmd0aDt5PG07eSsrKXthLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGU/ZD1jW3ldKmEuZGF0YS5zdHJpZGUrYS5vZmZzZXQ6ZD1jW3ldKmg7Zm9yKGxldCBnPTA7ZzxoO2crKylmW3ArK109bFtkKytdfXJldHVybiBuZXcgeHQoZixoLHUpfWlmKHRoaXMuaW5kZXg9PT1udWxsKXJldHVybiBjb25zb2xlLndhcm4oIlRIUkVFLkJ1ZmZlckdlb21ldHJ5LnRvTm9uSW5kZXhlZCgpOiBCdWZmZXJHZW9tZXRyeSBpcyBhbHJlYWR5IG5vbi1pbmRleGVkLiIpLHRoaXM7Y29uc3QgZT1uZXcgdWUsbj10aGlzLmluZGV4LmFycmF5LHM9dGhpcy5hdHRyaWJ1dGVzO2Zvcihjb25zdCBhIGluIHMpe2NvbnN0IGM9c1thXSxsPXQoYyxuKTtlLnNldEF0dHJpYnV0ZShhLGwpfWNvbnN0IHI9dGhpcy5tb3JwaEF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGEgaW4gcil7Y29uc3QgYz1bXSxsPXJbYV07Zm9yKGxldCBoPTAsdT1sLmxlbmd0aDtoPHU7aCsrKXtjb25zdCBmPWxbaF0sZD10KGYsbik7Yy5wdXNoKGQpfWUubW9ycGhBdHRyaWJ1dGVzW2FdPWN9ZS5tb3JwaFRhcmdldHNSZWxhdGl2ZT10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlO2NvbnN0IG89dGhpcy5ncm91cHM7Zm9yKGxldCBhPTAsYz1vLmxlbmd0aDthPGM7YSsrKXtjb25zdCBsPW9bYV07ZS5hZGRHcm91cChsLnN0YXJ0LGwuY291bnQsbC5tYXRlcmlhbEluZGV4KX1yZXR1cm4gZX10b0pTT04oKXtjb25zdCB0PXttZXRhZGF0YTp7dmVyc2lvbjo0LjcsdHlwZToiQnVmZmVyR2VvbWV0cnkiLGdlbmVyYXRvcjoiQnVmZmVyR2VvbWV0cnkudG9KU09OIn19O2lmKHQudXVpZD10aGlzLnV1aWQsdC50eXBlPXRoaXMudHlwZSx0aGlzLm5hbWUhPT0iIiYmKHQubmFtZT10aGlzLm5hbWUpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYodC51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSx0aGlzLnBhcmFtZXRlcnMhPT12b2lkIDApe2NvbnN0IGM9dGhpcy5wYXJhbWV0ZXJzO2Zvcihjb25zdCBsIGluIGMpY1tsXSE9PXZvaWQgMCYmKHRbbF09Y1tsXSk7cmV0dXJuIHR9dC5kYXRhPXthdHRyaWJ1dGVzOnt9fTtjb25zdCBlPXRoaXMuaW5kZXg7ZSE9PW51bGwmJih0LmRhdGEuaW5kZXg9e3R5cGU6ZS5hcnJheS5jb25zdHJ1Y3Rvci5uYW1lLGFycmF5OkFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGUuYXJyYXkpfSk7Y29uc3Qgbj10aGlzLmF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGMgaW4gbil7Y29uc3QgbD1uW2NdO3QuZGF0YS5hdHRyaWJ1dGVzW2NdPWwudG9KU09OKHQuZGF0YSl9Y29uc3Qgcz17fTtsZXQgcj0hMTtmb3IoY29uc3QgYyBpbiB0aGlzLm1vcnBoQXR0cmlidXRlcyl7Y29uc3QgbD10aGlzLm1vcnBoQXR0cmlidXRlc1tjXSxoPVtdO2ZvcihsZXQgdT0wLGY9bC5sZW5ndGg7dTxmO3UrKyl7Y29uc3QgZD1sW3VdO2gucHVzaChkLnRvSlNPTih0LmRhdGEpKX1oLmxlbmd0aD4wJiYoc1tjXT1oLHI9ITApfXImJih0LmRhdGEubW9ycGhBdHRyaWJ1dGVzPXMsdC5kYXRhLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmUpO2NvbnN0IG89dGhpcy5ncm91cHM7by5sZW5ndGg+MCYmKHQuZGF0YS5ncm91cHM9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvKSkpO2NvbnN0IGE9dGhpcy5ib3VuZGluZ1NwaGVyZTtyZXR1cm4gYSE9PW51bGwmJih0LmRhdGEuYm91bmRpbmdTcGhlcmU9YS50b0pTT04oKSksdH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXt0aGlzLmluZGV4PW51bGwsdGhpcy5hdHRyaWJ1dGVzPXt9LHRoaXMubW9ycGhBdHRyaWJ1dGVzPXt9LHRoaXMuZ3JvdXBzPVtdLHRoaXMuYm91bmRpbmdCb3g9bnVsbCx0aGlzLmJvdW5kaW5nU3BoZXJlPW51bGw7Y29uc3QgZT17fTt0aGlzLm5hbWU9dC5uYW1lO2NvbnN0IG49dC5pbmRleDtuIT09bnVsbCYmdGhpcy5zZXRJbmRleChuLmNsb25lKCkpO2NvbnN0IHM9dC5hdHRyaWJ1dGVzO2Zvcihjb25zdCBsIGluIHMpe2NvbnN0IGg9c1tsXTt0aGlzLnNldEF0dHJpYnV0ZShsLGguY2xvbmUoZSkpfWNvbnN0IHI9dC5tb3JwaEF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGwgaW4gcil7Y29uc3QgaD1bXSx1PXJbbF07Zm9yKGxldCBmPTAsZD11Lmxlbmd0aDtmPGQ7ZisrKWgucHVzaCh1W2ZdLmNsb25lKGUpKTt0aGlzLm1vcnBoQXR0cmlidXRlc1tsXT1ofXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU9dC5tb3JwaFRhcmdldHNSZWxhdGl2ZTtjb25zdCBvPXQuZ3JvdXBzO2ZvcihsZXQgbD0wLGg9by5sZW5ndGg7bDxoO2wrKyl7Y29uc3QgdT1vW2xdO3RoaXMuYWRkR3JvdXAodS5zdGFydCx1LmNvdW50LHUubWF0ZXJpYWxJbmRleCl9Y29uc3QgYT10LmJvdW5kaW5nQm94O2EhPT1udWxsJiYodGhpcy5ib3VuZGluZ0JveD1hLmNsb25lKCkpO2NvbnN0IGM9dC5ib3VuZGluZ1NwaGVyZTtyZXR1cm4gYyE9PW51bGwmJih0aGlzLmJvdW5kaW5nU3BoZXJlPWMuY2xvbmUoKSksdGhpcy5kcmF3UmFuZ2Uuc3RhcnQ9dC5kcmF3UmFuZ2Uuc3RhcnQsdGhpcy5kcmF3UmFuZ2UuY291bnQ9dC5kcmF3UmFuZ2UuY291bnQsdGhpcy51c2VyRGF0YT10LnVzZXJEYXRhLHRoaXN9ZGlzcG9zZSgpe3RoaXMuZGlzcGF0Y2hFdmVudCh7dHlwZToiZGlzcG9zZSJ9KX19Y29uc3QgTGM9bmV3IHN0LGZuPW5ldyBmbyxncz1uZXcgY28sT2M9bmV3IFQseHM9bmV3IFQsd3M9bmV3IFQsYnM9bmV3IFQsX289bmV3IFQsTXM9bmV3IFQsRGM9bmV3IFQsQXM9bmV3IFQ7Y2xhc3MgYmYgZXh0ZW5kcyBFZXtjb25zdHJ1Y3Rvcih0PW5ldyB1ZSxlPW5ldyB5Zil7c3VwZXIoKSx0aGlzLmlzTWVzaD0hMCx0aGlzLnR5cGU9Ik1lc2giLHRoaXMuZ2VvbWV0cnk9dCx0aGlzLm1hdGVyaWFsPWUsdGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9dm9pZCAwLHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPXZvaWQgMCx0aGlzLmNvdW50PTEsdGhpcy51cGRhdGVNb3JwaFRhcmdldHMoKX1jb3B5KHQsZSl7cmV0dXJuIHN1cGVyLmNvcHkodCxlKSx0Lm1vcnBoVGFyZ2V0SW5mbHVlbmNlcyE9PXZvaWQgMCYmKHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPXQubW9ycGhUYXJnZXRJbmZsdWVuY2VzLnNsaWNlKCkpLHQubW9ycGhUYXJnZXREaWN0aW9uYXJ5IT09dm9pZCAwJiYodGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9T2JqZWN0LmFzc2lnbih7fSx0Lm1vcnBoVGFyZ2V0RGljdGlvbmFyeSkpLHRoaXMubWF0ZXJpYWw9QXJyYXkuaXNBcnJheSh0Lm1hdGVyaWFsKT90Lm1hdGVyaWFsLnNsaWNlKCk6dC5tYXRlcmlhbCx0aGlzLmdlb21ldHJ5PXQuZ2VvbWV0cnksdGhpc311cGRhdGVNb3JwaFRhcmdldHMoKXtjb25zdCBlPXRoaXMuZ2VvbWV0cnkubW9ycGhBdHRyaWJ1dGVzLG49T2JqZWN0LmtleXMoZSk7aWYobi5sZW5ndGg+MCl7Y29uc3Qgcz1lW25bMF1dO2lmKHMhPT12b2lkIDApe3RoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPVtdLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5PXt9O2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1zW3JdLm5hbWV8fFN0cmluZyhyKTt0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcy5wdXNoKDApLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5W2FdPXJ9fX19Z2V0VmVydGV4UG9zaXRpb24odCxlKXtjb25zdCBuPXRoaXMuZ2VvbWV0cnkscz1uLmF0dHJpYnV0ZXMucG9zaXRpb24scj1uLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbixvPW4ubW9ycGhUYXJnZXRzUmVsYXRpdmU7ZS5mcm9tQnVmZmVyQXR0cmlidXRlKHMsdCk7Y29uc3QgYT10aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcztpZihyJiZhKXtNcy5zZXQoMCwwLDApO2ZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1hW2NdLHU9cltjXTtoIT09MCYmKF9vLmZyb21CdWZmZXJBdHRyaWJ1dGUodSx0KSxvP01zLmFkZFNjYWxlZFZlY3RvcihfbyxoKTpNcy5hZGRTY2FsZWRWZWN0b3IoX28uc3ViKGUpLGgpKX1lLmFkZChNcyl9cmV0dXJuIGV9cmF5Y2FzdCh0LGUpe2NvbnN0IG49dGhpcy5nZW9tZXRyeSxzPXRoaXMubWF0ZXJpYWwscj10aGlzLm1hdHJpeFdvcmxkO3MhPT12b2lkIDAmJihuLmJvdW5kaW5nU3BoZXJlPT09bnVsbCYmbi5jb21wdXRlQm91bmRpbmdTcGhlcmUoKSxncy5jb3B5KG4uYm91bmRpbmdTcGhlcmUpLGdzLmFwcGx5TWF0cml4NChyKSxmbi5jb3B5KHQucmF5KS5yZWNhc3QodC5uZWFyKSwhKGdzLmNvbnRhaW5zUG9pbnQoZm4ub3JpZ2luKT09PSExJiYoZm4uaW50ZXJzZWN0U3BoZXJlKGdzLE9jKT09PW51bGx8fGZuLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZChPYyk+eWkodC5mYXItdC5uZWFyLDIpKSkmJihMYy5jb3B5KHIpLmludmVydCgpLGZuLmNvcHkodC5yYXkpLmFwcGx5TWF0cml4NChMYyksIShuLmJvdW5kaW5nQm94IT09bnVsbCYmZm4uaW50ZXJzZWN0c0JveChuLmJvdW5kaW5nQm94KT09PSExKSYmdGhpcy5fY29tcHV0ZUludGVyc2VjdGlvbnModCxlLGZuKSkpfV9jb21wdXRlSW50ZXJzZWN0aW9ucyh0LGUsbil7bGV0IHM7Y29uc3Qgcj10aGlzLmdlb21ldHJ5LG89dGhpcy5tYXRlcmlhbCxhPXIuaW5kZXgsYz1yLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1yLmF0dHJpYnV0ZXMudXYsaD1yLmF0dHJpYnV0ZXMudXYxLHU9ci5hdHRyaWJ1dGVzLm5vcm1hbCxmPXIuZ3JvdXBzLGQ9ci5kcmF3UmFuZ2U7aWYoYSE9PW51bGwpaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihhLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9YS5nZXRYKHgpLFM9YS5nZXRYKHgrMSksXz1hLmdldFgoeCsyKTtzPVNzKHRoaXMsZyx0LG4sbCxoLHUsQSxTLF8pLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYS5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1hLmdldFgobSksdz1hLmdldFgobSsxKSx4PWEuZ2V0WChtKzIpO3M9U3ModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX1lbHNlIGlmKGMhPT12b2lkIDApaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihjLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9eCxTPXgrMSxfPXgrMjtzPVNzKHRoaXMsZyx0LG4sbCxoLHUsQSxTLF8pLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYy5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1tLHc9bSsxLHg9bSsyO3M9U3ModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX19fWZ1bmN0aW9uIE1mKGksdCxlLG4scyxyLG8sYSl7bGV0IGM7aWYodC5zaWRlPT09MT9jPW4uaW50ZXJzZWN0VHJpYW5nbGUobyxyLHMsITAsYSk6Yz1uLmludGVyc2VjdFRyaWFuZ2xlKHMscixvLHQuc2lkZT09PTAsYSksYz09PW51bGwpcmV0dXJuIG51bGw7QXMuY29weShhKSxBcy5hcHBseU1hdHJpeDQoaS5tYXRyaXhXb3JsZCk7Y29uc3QgbD1lLnJheS5vcmlnaW4uZGlzdGFuY2VUbyhBcyk7cmV0dXJuIGw8ZS5uZWFyfHxsPmUuZmFyP251bGw6e2Rpc3RhbmNlOmwscG9pbnQ6QXMuY2xvbmUoKSxvYmplY3Q6aX19ZnVuY3Rpb24gU3MoaSx0LGUsbixzLHIsbyxhLGMsbCl7aS5nZXRWZXJ0ZXhQb3NpdGlvbihhLHhzKSxpLmdldFZlcnRleFBvc2l0aW9uKGMsd3MpLGkuZ2V0VmVydGV4UG9zaXRpb24obCxicyk7Y29uc3QgaD1NZihpLHQsZSxuLHhzLHdzLGJzLERjKTtpZihoKXtjb25zdCB1PW5ldyBUO2V0LmdldEJhcnljb29yZChEYyx4cyx3cyxicyx1KSxzJiYoaC51dj1ldC5nZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUocyxhLGMsbCx1LG5ldyBSKSksciYmKGgudXYxPWV0LmdldEludGVycG9sYXRlZEF0dHJpYnV0ZShyLGEsYyxsLHUsbmV3IFIpKSxvJiYoaC5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKG8sYSxjLGwsdSxuZXcgVCksaC5ub3JtYWwuZG90KG4uZGlyZWN0aW9uKT4wJiZoLm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGY9e2EsYjpjLGM6bCxub3JtYWw6bmV3IFQsbWF0ZXJpYWxJbmRleDowfTtldC5nZXROb3JtYWwoeHMsd3MsYnMsZi5ub3JtYWwpLGguZmFjZT1mLGguYmFyeWNvb3JkPXV9cmV0dXJuIGh9Y29uc3Qgdm89bmV3IFQsQWY9bmV3IFQsU2Y9bmV3IGdlO2NsYXNzIHpve2NvbnN0cnVjdG9yKHQ9bmV3IFQoMSwwLDApLGU9MCl7dGhpcy5pc1BsYW5lPSEwLHRoaXMubm9ybWFsPXQsdGhpcy5jb25zdGFudD1lfXNldCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbC5jb3B5KHQpLHRoaXMuY29uc3RhbnQ9ZSx0aGlzfXNldENvbXBvbmVudHModCxlLG4scyl7cmV0dXJuIHRoaXMubm9ybWFsLnNldCh0LGUsbiksdGhpcy5jb25zdGFudD1zLHRoaXN9c2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWwuY29weSh0KSx0aGlzLmNvbnN0YW50PS1lLmRvdCh0aGlzLm5vcm1hbCksdGhpc31zZXRGcm9tQ29wbGFuYXJQb2ludHModCxlLG4pe2NvbnN0IHM9dm8uc3ViVmVjdG9ycyhuLGUpLmNyb3NzKEFmLnN1YlZlY3RvcnModCxlKSkubm9ybWFsaXplKCk7cmV0dXJuIHRoaXMuc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQocyx0KSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMubm9ybWFsLmNvcHkodC5ub3JtYWwpLHRoaXMuY29uc3RhbnQ9dC5jb25zdGFudCx0aGlzfW5vcm1hbGl6ZSgpe2NvbnN0IHQ9MS90aGlzLm5vcm1hbC5sZW5ndGgoKTtyZXR1cm4gdGhpcy5ub3JtYWwubXVsdGlwbHlTY2FsYXIodCksdGhpcy5jb25zdGFudCo9dCx0aGlzfW5lZ2F0ZSgpe3JldHVybiB0aGlzLmNvbnN0YW50Kj0tMSx0aGlzLm5vcm1hbC5uZWdhdGUoKSx0aGlzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdGhpcy5ub3JtYWwuZG90KHQpK3RoaXMuY29uc3RhbnR9ZGlzdGFuY2VUb1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQodC5jZW50ZXIpLXQucmFkaXVzfXByb2plY3RQb2ludCh0LGUpe3JldHVybiBlLmNvcHkodCkuYWRkU2NhbGVkVmVjdG9yKHRoaXMubm9ybWFsLC10aGlzLmRpc3RhbmNlVG9Qb2ludCh0KSl9aW50ZXJzZWN0TGluZSh0LGUpe2NvbnN0IG49dC5kZWx0YSh2bykscz10aGlzLm5vcm1hbC5kb3Qobik7aWYocz09PTApcmV0dXJuIHRoaXMuZGlzdGFuY2VUb1BvaW50KHQuc3RhcnQpPT09MD9lLmNvcHkodC5zdGFydCk6bnVsbDtjb25zdCByPS0odC5zdGFydC5kb3QodGhpcy5ub3JtYWwpK3RoaXMuY29uc3RhbnQpL3M7cmV0dXJuIHI8MHx8cj4xP251bGw6ZS5jb3B5KHQuc3RhcnQpLmFkZFNjYWxlZFZlY3RvcihuLHIpfWludGVyc2VjdHNMaW5lKHQpe2NvbnN0IGU9dGhpcy5kaXN0YW5jZVRvUG9pbnQodC5zdGFydCksbj10aGlzLmRpc3RhbmNlVG9Qb2ludCh0LmVuZCk7cmV0dXJuIGU8MCYmbj4wfHxuPDAmJmU+MH1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1jb3BsYW5hclBvaW50KHQpe3JldHVybiB0LmNvcHkodGhpcy5ub3JtYWwpLm11bHRpcGx5U2NhbGFyKC10aGlzLmNvbnN0YW50KX1hcHBseU1hdHJpeDQodCxlKXtjb25zdCBuPWV8fFNmLmdldE5vcm1hbE1hdHJpeCh0KSxzPXRoaXMuY29wbGFuYXJQb2ludCh2bykuYXBwbHlNYXRyaXg0KHQpLHI9dGhpcy5ub3JtYWwuYXBwbHlNYXRyaXgzKG4pLm5vcm1hbGl6ZSgpO3JldHVybiB0aGlzLmNvbnN0YW50PS1zLmRvdChyKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jb25zdGFudC09dC5kb3QodGhpcy5ub3JtYWwpLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lm5vcm1hbC5lcXVhbHModGhpcy5ub3JtYWwpJiZ0LmNvbnN0YW50PT09dGhpcy5jb25zdGFudH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9fWxldCB4ZT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMudHlwZT0iQ3VydmUiLHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPTIwMCx0aGlzLm5lZWRzVXBkYXRlPSExLHRoaXMuY2FjaGVBcmNMZW5ndGhzPW51bGx9Z2V0UG9pbnQoKXtjb25zb2xlLndhcm4oIlRIUkVFLkN1cnZlOiAuZ2V0UG9pbnQoKSBub3QgaW1wbGVtZW50ZWQuIil9Z2V0UG9pbnRBdCh0LGUpe2NvbnN0IG49dGhpcy5nZXRVdG9UbWFwcGluZyh0KTtyZXR1cm4gdGhpcy5nZXRQb2ludChuLGUpfWdldFBvaW50cyh0PTUpe2NvbnN0IGU9W107Zm9yKGxldCBuPTA7bjw9dDtuKyspZS5wdXNoKHRoaXMuZ2V0UG9pbnQobi90KSk7cmV0dXJuIGV9Z2V0U3BhY2VkUG9pbnRzKHQ9NSl7Y29uc3QgZT1bXTtmb3IobGV0IG49MDtuPD10O24rKyllLnB1c2godGhpcy5nZXRQb2ludEF0KG4vdCkpO3JldHVybiBlfWdldExlbmd0aCgpe2NvbnN0IHQ9dGhpcy5nZXRMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19Z2V0TGVuZ3Rocyh0PXRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zKXtpZih0aGlzLmNhY2hlQXJjTGVuZ3RocyYmdGhpcy5jYWNoZUFyY0xlbmd0aHMubGVuZ3RoPT09dCsxJiYhdGhpcy5uZWVkc1VwZGF0ZSlyZXR1cm4gdGhpcy5jYWNoZUFyY0xlbmd0aHM7dGhpcy5uZWVkc1VwZGF0ZT0hMTtjb25zdCBlPVtdO2xldCBuLHM9dGhpcy5nZXRQb2ludCgwKSxyPTA7ZS5wdXNoKDApO2ZvcihsZXQgbz0xO288PXQ7bysrKW49dGhpcy5nZXRQb2ludChvL3QpLHIrPW4uZGlzdGFuY2VUbyhzKSxlLnB1c2gocikscz1uO3JldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3Rocz1lLGV9dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5nZXRMZW5ndGhzKCl9Z2V0VXRvVG1hcHBpbmcodCxlPW51bGwpe2NvbnN0IG49dGhpcy5nZXRMZW5ndGhzKCk7bGV0IHM9MDtjb25zdCByPW4ubGVuZ3RoO2xldCBvO2U/bz1lOm89dCpuW3ItMV07bGV0IGE9MCxjPXItMSxsO2Zvcig7YTw9YzspaWYocz1NYXRoLmZsb29yKGErKGMtYSkvMiksbD1uW3NdLW8sbDwwKWE9cysxO2Vsc2UgaWYobD4wKWM9cy0xO2Vsc2V7Yz1zO2JyZWFrfWlmKHM9YyxuW3NdPT09bylyZXR1cm4gcy8oci0xKTtjb25zdCBoPW5bc10sZj1uW3MrMV0taCxkPShvLWgpL2Y7cmV0dXJuKHMrZCkvKHItMSl9Z2V0VGFuZ2VudCh0LGUpe2xldCBzPXQtMWUtNCxyPXQrMWUtNDtzPDAmJihzPTApLHI+MSYmKHI9MSk7Y29uc3Qgbz10aGlzLmdldFBvaW50KHMpLGE9dGhpcy5nZXRQb2ludChyKSxjPWV8fChvLmlzVmVjdG9yMj9uZXcgUjpuZXcgVCk7cmV0dXJuIGMuY29weShhKS5zdWIobykubm9ybWFsaXplKCksY31nZXRUYW5nZW50QXQodCxlKXtjb25zdCBuPXRoaXMuZ2V0VXRvVG1hcHBpbmcodCk7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudChuLGUpfWNvbXB1dGVGcmVuZXRGcmFtZXModCxlPSExKXtjb25zdCBuPW5ldyBULHM9W10scj1bXSxvPVtdLGE9bmV3IFQsYz1uZXcgc3Q7Zm9yKGxldCBkPTA7ZDw9dDtkKyspe2NvbnN0IHA9ZC90O3NbZF09dGhpcy5nZXRUYW5nZW50QXQocCxuZXcgVCl9clswXT1uZXcgVCxvWzBdPW5ldyBUO2xldCBsPU51bWJlci5NQVhfVkFMVUU7Y29uc3QgaD1NYXRoLmFicyhzWzBdLngpLHU9TWF0aC5hYnMoc1swXS55KSxmPU1hdGguYWJzKHNbMF0ueik7aDw9bCYmKGw9aCxuLnNldCgxLDAsMCkpLHU8PWwmJihsPXUsbi5zZXQoMCwxLDApKSxmPD1sJiZuLnNldCgwLDAsMSksYS5jcm9zc1ZlY3RvcnMoc1swXSxuKS5ub3JtYWxpemUoKSxyWzBdLmNyb3NzVmVjdG9ycyhzWzBdLGEpLG9bMF0uY3Jvc3NWZWN0b3JzKHNbMF0sclswXSk7Zm9yKGxldCBkPTE7ZDw9dDtkKyspe2lmKHJbZF09cltkLTFdLmNsb25lKCksb1tkXT1vW2QtMV0uY2xvbmUoKSxhLmNyb3NzVmVjdG9ycyhzW2QtMV0sc1tkXSksYS5sZW5ndGgoKT5OdW1iZXIuRVBTSUxPTil7YS5ub3JtYWxpemUoKTtjb25zdCBwPU1hdGguYWNvcyhaKHNbZC0xXS5kb3Qoc1tkXSksLTEsMSkpO3JbZF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhhLHApKX1vW2RdLmNyb3NzVmVjdG9ycyhzW2RdLHJbZF0pfWlmKGU9PT0hMCl7bGV0IGQ9TWF0aC5hY29zKFooclswXS5kb3Qoclt0XSksLTEsMSkpO2QvPXQsc1swXS5kb3QoYS5jcm9zc1ZlY3RvcnMoclswXSxyW3RdKSk+MCYmKGQ9LWQpO2ZvcihsZXQgcD0xO3A8PXQ7cCsrKXJbcF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhzW3BdLGQqcCkpLG9bcF0uY3Jvc3NWZWN0b3JzKHNbcF0scltwXSl9cmV0dXJue3RhbmdlbnRzOnMsbm9ybWFsczpyLGJpbm9ybWFsczpvfX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9dC5hcmNMZW5ndGhEaXZpc2lvbnMsdGhpc310b0pTT04oKXtjb25zdCB0PXttZXRhZGF0YTp7dmVyc2lvbjo0LjcsdHlwZToiQ3VydmUiLGdlbmVyYXRvcjoiQ3VydmUudG9KU09OIn19O3JldHVybiB0LmFyY0xlbmd0aERpdmlzaW9ucz10aGlzLmFyY0xlbmd0aERpdmlzaW9ucyx0LnR5cGU9dGhpcy50eXBlLHR9ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPXQuYXJjTGVuZ3RoRGl2aXNpb25zLHRoaXN9fTtjbGFzcyBfcyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0xLHM9MSxyPTAsbz1NYXRoLlBJKjIsYT0hMSxjPTApe3N1cGVyKCksdGhpcy5pc0VsbGlwc2VDdXJ2ZT0hMCx0aGlzLnR5cGU9IkVsbGlwc2VDdXJ2ZSIsdGhpcy5hWD10LHRoaXMuYVk9ZSx0aGlzLnhSYWRpdXM9bix0aGlzLnlSYWRpdXM9cyx0aGlzLmFTdGFydEFuZ2xlPXIsdGhpcy5hRW5kQW5nbGU9byx0aGlzLmFDbG9ja3dpc2U9YSx0aGlzLmFSb3RhdGlvbj1jfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9TWF0aC5QSSoyO2xldCByPXRoaXMuYUVuZEFuZ2xlLXRoaXMuYVN0YXJ0QW5nbGU7Y29uc3Qgbz1NYXRoLmFicyhyKTxOdW1iZXIuRVBTSUxPTjtmb3IoO3I8MDspcis9cztmb3IoO3I+czspci09cztyPE51bWJlci5FUFNJTE9OJiYobz9yPTA6cj1zKSx0aGlzLmFDbG9ja3dpc2U9PT0hMCYmIW8mJihyPT09cz9yPS1zOnI9ci1zKTtjb25zdCBhPXRoaXMuYVN0YXJ0QW5nbGUrdCpyO2xldCBjPXRoaXMuYVgrdGhpcy54UmFkaXVzKk1hdGguY29zKGEpLGw9dGhpcy5hWSt0aGlzLnlSYWRpdXMqTWF0aC5zaW4oYSk7aWYodGhpcy5hUm90YXRpb24hPT0wKXtjb25zdCBoPU1hdGguY29zKHRoaXMuYVJvdGF0aW9uKSx1PU1hdGguc2luKHRoaXMuYVJvdGF0aW9uKSxmPWMtdGhpcy5hWCxkPWwtdGhpcy5hWTtjPWYqaC1kKnUrdGhpcy5hWCxsPWYqdStkKmgrdGhpcy5hWX1yZXR1cm4gbi5zZXQoYyxsKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMuYVg9dC5hWCx0aGlzLmFZPXQuYVksdGhpcy54UmFkaXVzPXQueFJhZGl1cyx0aGlzLnlSYWRpdXM9dC55UmFkaXVzLHRoaXMuYVN0YXJ0QW5nbGU9dC5hU3RhcnRBbmdsZSx0aGlzLmFFbmRBbmdsZT10LmFFbmRBbmdsZSx0aGlzLmFDbG9ja3dpc2U9dC5hQ2xvY2t3aXNlLHRoaXMuYVJvdGF0aW9uPXQuYVJvdGF0aW9uLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC5hWD10aGlzLmFYLHQuYVk9dGhpcy5hWSx0LnhSYWRpdXM9dGhpcy54UmFkaXVzLHQueVJhZGl1cz10aGlzLnlSYWRpdXMsdC5hU3RhcnRBbmdsZT10aGlzLmFTdGFydEFuZ2xlLHQuYUVuZEFuZ2xlPXRoaXMuYUVuZEFuZ2xlLHQuYUNsb2Nrd2lzZT10aGlzLmFDbG9ja3dpc2UsdC5hUm90YXRpb249dGhpcy5hUm90YXRpb24sdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5hWD10LmFYLHRoaXMuYVk9dC5hWSx0aGlzLnhSYWRpdXM9dC54UmFkaXVzLHRoaXMueVJhZGl1cz10LnlSYWRpdXMsdGhpcy5hU3RhcnRBbmdsZT10LmFTdGFydEFuZ2xlLHRoaXMuYUVuZEFuZ2xlPXQuYUVuZEFuZ2xlLHRoaXMuYUNsb2Nrd2lzZT10LmFDbG9ja3dpc2UsdGhpcy5hUm90YXRpb249dC5hUm90YXRpb24sdGhpc319Y2xhc3MgJGMgZXh0ZW5kcyBfc3tjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyl7c3VwZXIodCxlLG4sbixzLHIsbyksdGhpcy5pc0FyY0N1cnZlPSEwLHRoaXMudHlwZT0iQXJjQ3VydmUifX1mdW5jdGlvbiBUbygpe2xldCBpPTAsdD0wLGU9MCxuPTA7ZnVuY3Rpb24gcyhyLG8sYSxjKXtpPXIsdD1hLGU9LTMqciszKm8tMiphLWMsbj0yKnItMipvK2ErY31yZXR1cm57aW5pdENhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsKXtzKG8sYSxsKihhLXIpLGwqKGMtbykpfSxpbml0Tm9udW5pZm9ybUNhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsLGgsdSl7bGV0IGY9KG8tcikvbC0oYS1yKS8obCtoKSsoYS1vKS9oLGQ9KGEtbykvaC0oYy1vKS8oaCt1KSsoYy1hKS91O2YqPWgsZCo9aCxzKG8sYSxmLGQpfSxjYWxjOmZ1bmN0aW9uKHIpe2NvbnN0IG89cipyLGE9bypyO3JldHVybiBpK3QqcitlKm8rbiphfX19Y29uc3QgdnM9bmV3IFQsRW89bmV3IFRvLFBvPW5ldyBUbyxDbz1uZXcgVG87Y2xhc3MgVmMgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdLGU9ITEsbj0iY2VudHJpcGV0YWwiLHM9LjUpe3N1cGVyKCksdGhpcy5pc0NhdG11bGxSb21DdXJ2ZTM9ITAsdGhpcy50eXBlPSJDYXRtdWxsUm9tQ3VydmUzIix0aGlzLnBvaW50cz10LHRoaXMuY2xvc2VkPWUsdGhpcy5jdXJ2ZVR5cGU9bix0aGlzLnRlbnNpb249c31nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZSxzPXRoaXMucG9pbnRzLHI9cy5sZW5ndGgsbz0oci0odGhpcy5jbG9zZWQ/MDoxKSkqdDtsZXQgYT1NYXRoLmZsb29yKG8pLGM9by1hO3RoaXMuY2xvc2VkP2ErPWE+MD8wOihNYXRoLmZsb29yKE1hdGguYWJzKGEpL3IpKzEpKnI6Yz09PTAmJmE9PT1yLTEmJihhPXItMixjPTEpO2xldCBsLGg7dGhpcy5jbG9zZWR8fGE+MD9sPXNbKGEtMSklcl06KHZzLnN1YlZlY3RvcnMoc1swXSxzWzFdKS5hZGQoc1swXSksbD12cyk7Y29uc3QgdT1zW2Elcl0sZj1zWyhhKzEpJXJdO2lmKHRoaXMuY2xvc2VkfHxhKzI8cj9oPXNbKGErMiklcl06KHZzLnN1YlZlY3RvcnMoc1tyLTFdLHNbci0yXSkuYWRkKHNbci0xXSksaD12cyksdGhpcy5jdXJ2ZVR5cGU9PT0iY2VudHJpcGV0YWwifHx0aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIil7Y29uc3QgZD10aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIj8uNTouMjU7bGV0IHA9TWF0aC5wb3cobC5kaXN0YW5jZVRvU3F1YXJlZCh1KSxkKSx5PU1hdGgucG93KHUuZGlzdGFuY2VUb1NxdWFyZWQoZiksZCksbT1NYXRoLnBvdyhmLmRpc3RhbmNlVG9TcXVhcmVkKGgpLGQpO3k8MWUtNCYmKHk9MSkscDwxZS00JiYocD15KSxtPDFlLTQmJihtPXkpLEVvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLngsdS54LGYueCxoLngscCx5LG0pLFBvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnksdS55LGYueSxoLnkscCx5LG0pLENvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnosdS56LGYueixoLnoscCx5LG0pfWVsc2UgdGhpcy5jdXJ2ZVR5cGU9PT0iY2F0bXVsbHJvbSImJihFby5pbml0Q2F0bXVsbFJvbShsLngsdS54LGYueCxoLngsdGhpcy50ZW5zaW9uKSxQby5pbml0Q2F0bXVsbFJvbShsLnksdS55LGYueSxoLnksdGhpcy50ZW5zaW9uKSxDby5pbml0Q2F0bXVsbFJvbShsLnosdS56LGYueixoLnosdGhpcy50ZW5zaW9uKSk7cmV0dXJuIG4uc2V0KEVvLmNhbGMoYyksUG8uY2FsYyhjKSxDby5jYWxjKGMpKSxufWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5jbG9zZWQ9dC5jbG9zZWQsdGhpcy5jdXJ2ZVR5cGU9dC5jdXJ2ZVR5cGUsdGhpcy50ZW5zaW9uPXQudGVuc2lvbix0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdC5jbG9zZWQ9dGhpcy5jbG9zZWQsdC5jdXJ2ZVR5cGU9dGhpcy5jdXJ2ZVR5cGUsdC50ZW5zaW9uPXRoaXMudGVuc2lvbix0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChuZXcgVCgpLmZyb21BcnJheShzKSl9cmV0dXJuIHRoaXMuY2xvc2VkPXQuY2xvc2VkLHRoaXMuY3VydmVUeXBlPXQuY3VydmVUeXBlLHRoaXMudGVuc2lvbj10LnRlbnNpb24sdGhpc319ZnVuY3Rpb24gVWMoaSx0LGUsbixzKXtjb25zdCByPShuLXQpKi41LG89KHMtZSkqLjUsYT1pKmksYz1pKmE7cmV0dXJuKDIqZS0yKm4rcitvKSpjKygtMyplKzMqbi0yKnItbykqYStyKmkrZX1mdW5jdGlvbiBfZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiBlKmUqdH1mdW5jdGlvbiB2ZihpLHQpe3JldHVybiAyKigxLWkpKmkqdH1mdW5jdGlvbiB6ZihpLHQpe3JldHVybiBpKmkqdH1mdW5jdGlvbiBTaShpLHQsZSxuKXtyZXR1cm4gX2YoaSx0KSt2ZihpLGUpK3pmKGksbil9ZnVuY3Rpb24gVGYoaSx0KXtjb25zdCBlPTEtaTtyZXR1cm4gZSplKmUqdH1mdW5jdGlvbiBFZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiAzKmUqZSppKnR9ZnVuY3Rpb24gUGYoaSx0KXtyZXR1cm4gMyooMS1pKSppKmkqdH1mdW5jdGlvbiBDZihpLHQpe3JldHVybiBpKmkqaSp0fWZ1bmN0aW9uIF9pKGksdCxlLG4scyl7cmV0dXJuIFRmKGksdCkrRWYoaSxlKStQZihpLG4pK0NmKGkscyl9Y2xhc3MgQm8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUixzPW5ldyBSKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlPSEwLHRoaXMudHlwZT0iQ3ViaWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW4sdGhpcy52Mz1zfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyLGE9dGhpcy52MztyZXR1cm4gbi5zZXQoX2kodCxzLngsci54LG8ueCxhLngpLF9pKHQscy55LHIueSxvLnksYS55KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3MgcWMgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCxzPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlMz0hMCx0aGlzLnR5cGU9IkN1YmljQmV6aWVyQ3VydmUzIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bix0aGlzLnYzPXN9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjIsYT10aGlzLnYzO3JldHVybiBuLnNldChfaSh0LHMueCxyLngsby54LGEueCksX2kodCxzLnksci55LG8ueSxhLnkpLF9pKHQscy56LHIueixvLnosYS56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3MgRm8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIpe3N1cGVyKCksdGhpcy5pc0xpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZSIsdGhpcy52MT10LHRoaXMudjI9ZX1nZXRQb2ludCh0LGU9bmV3IFIpe2NvbnN0IG49ZTtyZXR1cm4gdD09PTE/bi5jb3B5KHRoaXMudjIpOihuLmNvcHkodGhpcy52Mikuc3ViKHRoaXMudjEpLG4ubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMudjEpKSxufWdldFBvaW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRQb2ludCh0LGUpfWdldFRhbmdlbnQodCxlPW5ldyBSKXtyZXR1cm4gZS5zdWJWZWN0b3JzKHRoaXMudjIsdGhpcy52MSkubm9ybWFsaXplKCl9Z2V0VGFuZ2VudEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudCh0LGUpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBIYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCl7c3VwZXIoKSx0aGlzLmlzTGluZUN1cnZlMz0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZTMiLHRoaXMudjE9dCx0aGlzLnYyPWV9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWU7cmV0dXJuIHQ9PT0xP24uY29weSh0aGlzLnYyKToobi5jb3B5KHRoaXMudjIpLnN1Yih0aGlzLnYxKSxuLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnYxKSksbn1nZXRQb2ludEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0UG9pbnQodCxlKX1nZXRUYW5nZW50KHQsZT1uZXcgVCl7cmV0dXJuIGUuc3ViVmVjdG9ycyh0aGlzLnYyLHRoaXMudjEpLm5vcm1hbGl6ZSgpfWdldFRhbmdlbnRBdCh0LGUpe3JldHVybiB0aGlzLmdldFRhbmdlbnQodCxlKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3MgSW8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUil7c3VwZXIoKSx0aGlzLmlzUXVhZHJhdGljQmV6aWVyQ3VydmU9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW59Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjI7cmV0dXJuIG4uc2V0KFNpKHQscy54LHIueCxvLngpLFNpKHQscy55LHIueSxvLnkpKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYwPXRoaXMudjAudG9BcnJheSgpLHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBXYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCxuPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNRdWFkcmF0aWNCZXppZXJDdXJ2ZTM9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZTMiLHRoaXMudjA9dCx0aGlzLnYxPWUsdGhpcy52Mj1ufWdldFBvaW50KHQsZT1uZXcgVCl7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyO3JldHVybiBuLnNldChTaSh0LHMueCxyLngsby54KSxTaSh0LHMueSxyLnksby55KSxTaSh0LHMueixyLnosby56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3Mga28gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdKXtzdXBlcigpLHRoaXMuaXNTcGxpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IlNwbGluZUN1cnZlIix0aGlzLnBvaW50cz10fWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy5wb2ludHMscj0ocy5sZW5ndGgtMSkqdCxvPU1hdGguZmxvb3IociksYT1yLW8sYz1zW289PT0wP286by0xXSxsPXNbb10saD1zW28+cy5sZW5ndGgtMj9zLmxlbmd0aC0xOm8rMV0sdT1zW28+cy5sZW5ndGgtMz9zLmxlbmd0aC0xOm8rMl07cmV0dXJuIG4uc2V0KFVjKGEsYy54LGwueCxoLngsdS54KSxVYyhhLGMueSxsLnksaC55LHUueSkpLG59Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gobmV3IFIoKS5mcm9tQXJyYXkocykpfXJldHVybiB0aGlzfX12YXIgR2M9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQXJjQ3VydmU6JGMsQ2F0bXVsbFJvbUN1cnZlMzpWYyxDdWJpY0JlemllckN1cnZlOkJvLEN1YmljQmV6aWVyQ3VydmUzOnFjLEVsbGlwc2VDdXJ2ZTpfcyxMaW5lQ3VydmU6Rm8sTGluZUN1cnZlMzpIYyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTpJbyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTM6V2MsU3BsaW5lQ3VydmU6a299KTtjbGFzcyBCZiBleHRlbmRzIHhle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9IkN1cnZlUGF0aCIsdGhpcy5jdXJ2ZXM9W10sdGhpcy5hdXRvQ2xvc2U9ITF9YWRkKHQpe3RoaXMuY3VydmVzLnB1c2godCl9Y2xvc2VQYXRoKCl7Y29uc3QgdD10aGlzLmN1cnZlc1swXS5nZXRQb2ludCgwKSxlPXRoaXMuY3VydmVzW3RoaXMuY3VydmVzLmxlbmd0aC0xXS5nZXRQb2ludCgxKTtpZighdC5lcXVhbHMoZSkpe2NvbnN0IG49dC5pc1ZlY3RvcjI9PT0hMD8iTGluZUN1cnZlIjoiTGluZUN1cnZlMyI7dGhpcy5jdXJ2ZXMucHVzaChuZXcgR2Nbbl0oZSx0KSl9cmV0dXJuIHRoaXN9Z2V0UG9pbnQodCxlKXtjb25zdCBuPXQqdGhpcy5nZXRMZW5ndGgoKSxzPXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7bGV0IHI9MDtmb3IoO3I8cy5sZW5ndGg7KXtpZihzW3JdPj1uKXtjb25zdCBvPXNbcl0tbixhPXRoaXMuY3VydmVzW3JdLGM9YS5nZXRMZW5ndGgoKSxsPWM9PT0wPzA6MS1vL2M7cmV0dXJuIGEuZ2V0UG9pbnRBdChsLGUpfXIrK31yZXR1cm4gbnVsbH1nZXRMZW5ndGgoKXtjb25zdCB0PXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5jYWNoZUxlbmd0aHM9bnVsbCx0aGlzLmdldEN1cnZlTGVuZ3RocygpfWdldEN1cnZlTGVuZ3Rocygpe2lmKHRoaXMuY2FjaGVMZW5ndGhzJiZ0aGlzLmNhY2hlTGVuZ3Rocy5sZW5ndGg9PT10aGlzLmN1cnZlcy5sZW5ndGgpcmV0dXJuIHRoaXMuY2FjaGVMZW5ndGhzO2NvbnN0IHQ9W107bGV0IGU9MDtmb3IobGV0IG49MCxzPXRoaXMuY3VydmVzLmxlbmd0aDtuPHM7bisrKWUrPXRoaXMuY3VydmVzW25dLmdldExlbmd0aCgpLHQucHVzaChlKTtyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM9dCx0fWdldFNwYWNlZFBvaW50cyh0PTQwKXtjb25zdCBlPVtdO2ZvcihsZXQgbj0wO248PXQ7bisrKWUucHVzaCh0aGlzLmdldFBvaW50KG4vdCkpO3JldHVybiB0aGlzLmF1dG9DbG9zZSYmZS5wdXNoKGVbMF0pLGV9Z2V0UG9pbnRzKHQ9MTIpe2NvbnN0IGU9W107bGV0IG47Zm9yKGxldCBzPTAscj10aGlzLmN1cnZlcztzPHIubGVuZ3RoO3MrKyl7Y29uc3Qgbz1yW3NdLGE9by5pc0VsbGlwc2VDdXJ2ZT90KjI6by5pc0xpbmVDdXJ2ZXx8by5pc0xpbmVDdXJ2ZTM/MTpvLmlzU3BsaW5lQ3VydmU/dCpvLnBvaW50cy5sZW5ndGg6dCxjPW8uZ2V0UG9pbnRzKGEpO2ZvcihsZXQgbD0wO2w8Yy5sZW5ndGg7bCsrKXtjb25zdCBoPWNbbF07biYmbi5lcXVhbHMoaCl8fChlLnB1c2goaCksbj1oKX19cmV0dXJuIHRoaXMuYXV0b0Nsb3NlJiZlLmxlbmd0aD4xJiYhZVtlLmxlbmd0aC0xXS5lcXVhbHMoZVswXSkmJmUucHVzaChlWzBdKSxlfWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5hdXRvQ2xvc2U9dC5hdXRvQ2xvc2UsdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3QuYXV0b0Nsb3NlPXRoaXMuYXV0b0Nsb3NlLHQuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dGhpcy5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dGhpcy5jdXJ2ZXNbZV07dC5jdXJ2ZXMucHVzaChzLnRvSlNPTigpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLmF1dG9DbG9zZT10LmF1dG9DbG9zZSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gobmV3IEdjW3MudHlwZV0oKS5mcm9tSlNPTihzKSl9cmV0dXJuIHRoaXN9fWxldCBaYz1jbGFzcyBleHRlbmRzIEJme2NvbnN0cnVjdG9yKHQpe3N1cGVyKCksdGhpcy50eXBlPSJQYXRoIix0aGlzLmN1cnJlbnRQb2ludD1uZXcgUix0JiZ0aGlzLnNldEZyb21Qb2ludHModCl9c2V0RnJvbVBvaW50cyh0KXt0aGlzLm1vdmVUbyh0WzBdLngsdFswXS55KTtmb3IobGV0IGU9MSxuPXQubGVuZ3RoO2U8bjtlKyspdGhpcy5saW5lVG8odFtlXS54LHRbZV0ueSk7cmV0dXJuIHRoaXN9bW92ZVRvKHQsZSl7cmV0dXJuIHRoaXMuY3VycmVudFBvaW50LnNldCh0LGUpLHRoaXN9bGluZVRvKHQsZSl7Y29uc3Qgbj1uZXcgRm8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5zZXQodCxlKSx0aGlzfXF1YWRyYXRpY0N1cnZlVG8odCxlLG4scyl7Y29uc3Qgcj1uZXcgSW8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scykpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKHIpLHRoaXMuY3VycmVudFBvaW50LnNldChuLHMpLHRoaXN9YmV6aWVyQ3VydmVUbyh0LGUsbixzLHIsbyl7Y29uc3QgYT1uZXcgQm8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scyksbmV3IFIocixvKSk7cmV0dXJuIHRoaXMuY3VydmVzLnB1c2goYSksdGhpcy5jdXJyZW50UG9pbnQuc2V0KHIsbyksdGhpc31zcGxpbmVUaHJ1KHQpe2NvbnN0IGU9W3RoaXMuY3VycmVudFBvaW50LmNsb25lKCldLmNvbmNhdCh0KSxuPW5ldyBrbyhlKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5jb3B5KHRbdC5sZW5ndGgtMV0pLHRoaXN9YXJjKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMuY3VycmVudFBvaW50LngsYz10aGlzLmN1cnJlbnRQb2ludC55O3JldHVybiB0aGlzLmFic2FyYyh0K2EsZStjLG4scyxyLG8pLHRoaXN9YWJzYXJjKHQsZSxuLHMscixvKXtyZXR1cm4gdGhpcy5hYnNlbGxpcHNlKHQsZSxuLG4scyxyLG8pLHRoaXN9ZWxsaXBzZSh0LGUsbixzLHIsbyxhLGMpe2NvbnN0IGw9dGhpcy5jdXJyZW50UG9pbnQueCxoPXRoaXMuY3VycmVudFBvaW50Lnk7cmV0dXJuIHRoaXMuYWJzZWxsaXBzZSh0K2wsZStoLG4scyxyLG8sYSxjKSx0aGlzfWFic2VsbGlwc2UodCxlLG4scyxyLG8sYSxjKXtjb25zdCBsPW5ldyBfcyh0LGUsbixzLHIsbyxhLGMpO2lmKHRoaXMuY3VydmVzLmxlbmd0aD4wKXtjb25zdCB1PWwuZ2V0UG9pbnQoMCk7dS5lcXVhbHModGhpcy5jdXJyZW50UG9pbnQpfHx0aGlzLmxpbmVUbyh1LngsdS55KX10aGlzLmN1cnZlcy5wdXNoKGwpO2NvbnN0IGg9bC5nZXRQb2ludCgxKTtyZXR1cm4gdGhpcy5jdXJyZW50UG9pbnQuY29weShoKSx0aGlzfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5jdXJyZW50UG9pbnQuY29weSh0LmN1cnJlbnRQb2ludCksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LmN1cnJlbnRQb2ludD10aGlzLmN1cnJlbnRQb2ludC50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5jdXJyZW50UG9pbnQuZnJvbUFycmF5KHQuY3VycmVudFBvaW50KSx0aGlzfX07Y2xhc3MgWGMgZXh0ZW5kcyBaY3tjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLnR5cGU9IlNoYXBlIix0aGlzLmhvbGVzPVtdfWdldFBvaW50c0hvbGVzKHQpe2NvbnN0IGU9W107Zm9yKGxldCBuPTAscz10aGlzLmhvbGVzLmxlbmd0aDtuPHM7bisrKWVbbl09dGhpcy5ob2xlc1tuXS5nZXRQb2ludHModCk7cmV0dXJuIGV9ZXh0cmFjdFBvaW50cyh0KXtyZXR1cm57c2hhcGU6dGhpcy5nZXRQb2ludHModCksaG9sZXM6dGhpcy5nZXRQb2ludHNIb2xlcyh0KX19Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10LmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuaG9sZXNbZV07dGhpcy5ob2xlcy5wdXNoKHMuY2xvbmUoKSl9cmV0dXJuIHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnV1aWQ9dGhpcy51dWlkLHQuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10aGlzLmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMuaG9sZXNbZV07dC5ob2xlcy5wdXNoKHMudG9KU09OKCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMudXVpZD10LnV1aWQsdGhpcy5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXQuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5ob2xlc1tlXTt0aGlzLmhvbGVzLnB1c2gobmV3IFpjKCkuZnJvbUpTT04ocykpfXJldHVybiB0aGlzfX1mdW5jdGlvbiBGZihpLHQsZT0yKXtjb25zdCBuPXQmJnQubGVuZ3RoLHM9bj90WzBdKmU6aS5sZW5ndGg7bGV0IHI9SmMoaSwwLHMsZSwhMCk7Y29uc3Qgbz1bXTtpZighcnx8ci5uZXh0PT09ci5wcmV2KXJldHVybiBvO2xldCBhLGMsbDtpZihuJiYocj1MZihpLHQscixlKSksaS5sZW5ndGg+ODAqZSl7YT0xLzAsYz0xLzA7bGV0IGg9LTEvMCx1PS0xLzA7Zm9yKGxldCBmPWU7ZjxzO2YrPWUpe2NvbnN0IGQ9aVtmXSxwPWlbZisxXTtkPGEmJihhPWQpLHA8YyYmKGM9cCksZD5oJiYoaD1kKSxwPnUmJih1PXApfWw9TWF0aC5tYXgoaC1hLHUtYyksbD1sIT09MD8zMjc2Ny9sOjB9cmV0dXJuIHZpKHIsbyxlLGEsYyxsLDApLG99ZnVuY3Rpb24gSmMoaSx0LGUsbixzKXtsZXQgcjtpZihzPT09WGYoaSx0LGUsbik+MClmb3IobGV0IG89dDtvPGU7bys9bilyPUtjKG8vbnwwLGlbb10saVtvKzFdLHIpO2Vsc2UgZm9yKGxldCBvPWUtbjtvPj10O28tPW4pcj1LYyhvL258MCxpW29dLGlbbysxXSxyKTtyZXR1cm4gciYmSG4ocixyLm5leHQpJiYoRWkocikscj1yLm5leHQpLHJ9ZnVuY3Rpb24gZG4oaSx0KXtpZighaSlyZXR1cm4gaTt0fHwodD1pKTtsZXQgZT1pLG47ZG8gaWYobj0hMSwhZS5zdGVpbmVyJiYoSG4oZSxlLm5leHQpfHxydChlLnByZXYsZSxlLm5leHQpPT09MCkpe2lmKEVpKGUpLGU9dD1lLnByZXYsZT09PWUubmV4dClicmVhaztuPSEwfWVsc2UgZT1lLm5leHQ7d2hpbGUobnx8ZSE9PXQpO3JldHVybiB0fWZ1bmN0aW9uIHZpKGksdCxlLG4scyxyLG8pe2lmKCFpKXJldHVybjshbyYmciYmVWYoaSxuLHMscik7bGV0IGE9aTtmb3IoO2kucHJldiE9PWkubmV4dDspe2NvbnN0IGM9aS5wcmV2LGw9aS5uZXh0O2lmKHI/a2YoaSxuLHMscik6SWYoaSkpe3QucHVzaChjLmksaS5pLGwuaSksRWkoaSksaT1sLm5leHQsYT1sLm5leHQ7Y29udGludWV9aWYoaT1sLGk9PT1hKXtvP289PT0xPyhpPU5mKGRuKGkpLHQpLHZpKGksdCxlLG4scyxyLDIpKTpvPT09MiYmUmYoaSx0LGUsbixzLHIpOnZpKGRuKGkpLHQsZSxuLHMsciwxKTticmVha319fWZ1bmN0aW9uIElmKGkpe2NvbnN0IHQ9aS5wcmV2LGU9aSxuPWkubmV4dDtpZihydCh0LGUsbik+PTApcmV0dXJuITE7Y29uc3Qgcz10Lngscj1lLngsbz1uLngsYT10LnksYz1lLnksbD1uLnksaD1NYXRoLm1pbihzLHIsbyksdT1NYXRoLm1pbihhLGMsbCksZj1NYXRoLm1heChzLHIsbyksZD1NYXRoLm1heChhLGMsbCk7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJnppKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZydChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIGtmKGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihydChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1NYXRoLm1pbihhLGMsbCkscD1NYXRoLm1pbihoLHUsZikseT1NYXRoLm1heChhLGMsbCksbT1NYXRoLm1heChoLHUsZiksZz1ObyhkLHAsdCxlLG4pLGI9Tm8oeSxtLHQsZSxuKTtsZXQgdz1pLnByZXZaLHg9aS5uZXh0Wjtmb3IoO3cmJncuej49ZyYmeCYmeC56PD1iOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJnppKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wfHwodz13LnByZXZaLHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZ6aShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MCkpcmV0dXJuITE7eD14Lm5leHRafWZvcig7dyYmdy56Pj1nOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJnppKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wKXJldHVybiExO3c9dy5wcmV2Wn1mb3IoO3gmJnguejw9Yjspe2lmKHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZ6aShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MClyZXR1cm4hMTt4PXgubmV4dFp9cmV0dXJuITB9ZnVuY3Rpb24gTmYoaSx0KXtsZXQgZT1pO2Rve2NvbnN0IG49ZS5wcmV2LHM9ZS5uZXh0Lm5leHQ7IUhuKG4scykmJmpjKG4sZSxlLm5leHQscykmJlRpKG4scykmJlRpKHMsbikmJih0LnB1c2gobi5pLGUuaSxzLmkpLEVpKGUpLEVpKGUubmV4dCksZT1pPXMpLGU9ZS5uZXh0fXdoaWxlKGUhPT1pKTtyZXR1cm4gZG4oZSl9ZnVuY3Rpb24gUmYoaSx0LGUsbixzLHIpe2xldCBvPWk7ZG97bGV0IGE9by5uZXh0Lm5leHQ7Zm9yKDthIT09by5wcmV2Oyl7aWYoby5pIT09YS5pJiZXZihvLGEpKXtsZXQgYz1RYyhvLGEpO289ZG4obyxvLm5leHQpLGM9ZG4oYyxjLm5leHQpLHZpKG8sdCxlLG4scyxyLDApLHZpKGMsdCxlLG4scyxyLDApO3JldHVybn1hPWEubmV4dH1vPW8ubmV4dH13aGlsZShvIT09aSl9ZnVuY3Rpb24gTGYoaSx0LGUsbil7Y29uc3Qgcz1bXTtmb3IobGV0IHI9MCxvPXQubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9dFtyXSpuLGM9cjxvLTE/dFtyKzFdKm46aS5sZW5ndGgsbD1KYyhpLGEsYyxuLCExKTtsPT09bC5uZXh0JiYobC5zdGVpbmVyPSEwKSxzLnB1c2goSGYobCkpfXMuc29ydChPZik7Zm9yKGxldCByPTA7cjxzLmxlbmd0aDtyKyspZT1EZihzW3JdLGUpO3JldHVybiBlfWZ1bmN0aW9uIE9mKGksdCl7bGV0IGU9aS54LXQueDtpZihlPT09MCYmKGU9aS55LXQueSxlPT09MCkpe2NvbnN0IG49KGkubmV4dC55LWkueSkvKGkubmV4dC54LWkueCkscz0odC5uZXh0LnktdC55KS8odC5uZXh0LngtdC54KTtlPW4tc31yZXR1cm4gZX1mdW5jdGlvbiBEZihpLHQpe2NvbnN0IGU9JGYoaSx0KTtpZighZSlyZXR1cm4gdDtjb25zdCBuPVFjKGUsaSk7cmV0dXJuIGRuKG4sbi5uZXh0KSxkbihlLGUubmV4dCl9ZnVuY3Rpb24gJGYoaSx0KXtsZXQgZT10O2NvbnN0IG49aS54LHM9aS55O2xldCByPS0xLzAsbztpZihIbihpLGUpKXJldHVybiBlO2Rve2lmKEhuKGksZS5uZXh0KSlyZXR1cm4gZS5uZXh0O2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZZYyhzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTtUaShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmVmYobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIFZmKGksdCl7cmV0dXJuIHJ0KGkucHJldixpLHQucHJldik8MCYmcnQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIFVmKGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1ObyhzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwscWYocyl9ZnVuY3Rpb24gcWYoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBObyhpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24gSGYoaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIFljKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiB6aShpLHQsZSxuLHMscixvLGEpe3JldHVybiEoaT09PW8mJnQ9PT1hKSYmWWMoaSx0LGUsbixzLHIsbyxhKX1mdW5jdGlvbiBXZihpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFHZihpLHQpJiYoVGkoaSx0KSYmVGkodCxpKSYmWmYoaSx0KSYmKHJ0KGkucHJldixpLHQucHJldil8fHJ0KGksdC5wcmV2LHQpKXx8SG4oaSx0KSYmcnQoaS5wcmV2LGksaS5uZXh0KT4wJiZydCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIHJ0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24gSG4oaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gamMoaSx0LGUsbil7Y29uc3Qgcz1UcyhydChpLHQsZSkpLHI9VHMocnQoaSx0LG4pKSxvPVRzKHJ0KGUsbixpKSksYT1UcyhydChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJnpzKGksZSx0KXx8cj09PTAmJnpzKGksbix0KXx8bz09PTAmJnpzKGUsaSxuKXx8YT09PTAmJnpzKGUsdCxuKSl9ZnVuY3Rpb24genMoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIFRzKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBHZihpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmamMoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gVGkoaSx0KXtyZXR1cm4gcnQoaS5wcmV2LGksaS5uZXh0KTwwP3J0KGksdCxpLm5leHQpPj0wJiZydChpLGkucHJldix0KT49MDpydChpLHQsaS5wcmV2KTwwfHxydChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIFpmKGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gUWMoaSx0KXtjb25zdCBlPVJvKGkuaSxpLngsaS55KSxuPVJvKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBLYyhpLHQsZSxuKXtjb25zdCBzPVJvKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gRWkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBSbyhpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gWGYoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWNsYXNzIEpme3N0YXRpYyB0cmlhbmd1bGF0ZSh0LGUsbj0yKXtyZXR1cm4gRmYodCxlLG4pfX1jbGFzcyBXbntzdGF0aWMgYXJlYSh0KXtjb25zdCBlPXQubGVuZ3RoO2xldCBuPTA7Zm9yKGxldCBzPWUtMSxyPTA7cjxlO3M9cisrKW4rPXRbc10ueCp0W3JdLnktdFtyXS54KnRbc10ueTtyZXR1cm4gbiouNX1zdGF0aWMgaXNDbG9ja1dpc2UodCl7cmV0dXJuIFduLmFyZWEodCk8MH1zdGF0aWMgdHJpYW5ndWxhdGVTaGFwZSh0LGUpe2NvbnN0IG49W10scz1bXSxyPVtdO3RsKHQpLGVsKG4sdCk7bGV0IG89dC5sZW5ndGg7ZS5mb3JFYWNoKHRsKTtmb3IobGV0IGM9MDtjPGUubGVuZ3RoO2MrKylzLnB1c2gobyksbys9ZVtjXS5sZW5ndGgsZWwobixlW2NdKTtjb25zdCBhPUpmLnRyaWFuZ3VsYXRlKG4scyk7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKz0zKXIucHVzaChhLnNsaWNlKGMsYyszKSk7cmV0dXJuIHJ9fWZ1bmN0aW9uIHRsKGkpe2NvbnN0IHQ9aS5sZW5ndGg7dD4yJiZpW3QtMV0uZXF1YWxzKGlbMF0pJiZpLnBvcCgpfWZ1bmN0aW9uIGVsKGksdCl7Zm9yKGxldCBlPTA7ZTx0Lmxlbmd0aDtlKyspaS5wdXNoKHRbZV0ueCksaS5wdXNoKHRbZV0ueSl9Y2xhc3MgTG8gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PTEsZT0xLG49MSxzPTEpe3N1cGVyKCksdGhpcy50eXBlPSJQbGFuZUdlb21ldHJ5Iix0aGlzLnBhcmFtZXRlcnM9e3dpZHRoOnQsaGVpZ2h0OmUsd2lkdGhTZWdtZW50czpuLGhlaWdodFNlZ21lbnRzOnN9O2NvbnN0IHI9dC8yLG89ZS8yLGE9TWF0aC5mbG9vcihuKSxjPU1hdGguZmxvb3IocyksbD1hKzEsaD1jKzEsdT10L2EsZj1lL2MsZD1bXSxwPVtdLHk9W10sbT1bXTtmb3IobGV0IGc9MDtnPGg7ZysrKXtjb25zdCBiPWcqZi1vO2ZvcihsZXQgdz0wO3c8bDt3Kyspe2NvbnN0IHg9dyp1LXI7cC5wdXNoKHgsLWIsMCkseS5wdXNoKDAsMCwxKSxtLnB1c2gody9hKSxtLnB1c2goMS1nL2MpfX1mb3IobGV0IGc9MDtnPGM7ZysrKWZvcihsZXQgYj0wO2I8YTtiKyspe2NvbnN0IHc9YitsKmcseD1iK2wqKGcrMSksTT1iKzErbCooZysxKSxBPWIrMStsKmc7ZC5wdXNoKHcseCxBKSxkLnB1c2goeCxNLEEpfXRoaXMuc2V0SW5kZXgoZCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQmUocCwzKSksdGhpcy5zZXRBdHRyaWJ1dGUoIm5vcm1hbCIsbmV3IEJlKHksMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IEJlKG0sMikpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXN0YXRpYyBmcm9tSlNPTih0KXtyZXR1cm4gbmV3IExvKHQud2lkdGgsdC5oZWlnaHQsdC53aWR0aFNlZ21lbnRzLHQuaGVpZ2h0U2VnbWVudHMpfX1jb25zdCBubD1uZXcgVCxFcz1uZXcgVDtjbGFzcyBRdHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQpe3RoaXMuc3RhcnQ9dCx0aGlzLmVuZD1lfXNldCh0LGUpe3JldHVybiB0aGlzLnN0YXJ0LmNvcHkodCksdGhpcy5lbmQuY29weShlKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuc3RhcnQuY29weSh0LnN0YXJ0KSx0aGlzLmVuZC5jb3B5KHQuZW5kKSx0aGlzfWdldENlbnRlcih0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuc3RhcnQsdGhpcy5lbmQpLm11bHRpcGx5U2NhbGFyKC41KX1kZWx0YSh0KXtyZXR1cm4gdC5zdWJWZWN0b3JzKHRoaXMuZW5kLHRoaXMuc3RhcnQpfWRpc3RhbmNlU3EoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmVuZCl9ZGlzdGFuY2UoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvKHRoaXMuZW5kKX1hdCh0LGUpe3JldHVybiB0aGlzLmRlbHRhKGUpLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnN0YXJ0KX1jbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyKHQsZSl7bmwuc3ViVmVjdG9ycyh0LHRoaXMuc3RhcnQpLEVzLnN1YlZlY3RvcnModGhpcy5lbmQsdGhpcy5zdGFydCk7Y29uc3Qgbj1Fcy5kb3QoRXMpO2xldCByPUVzLmRvdChubCkvbjtyZXR1cm4gZSYmKHI9WihyLDAsMSkpLHJ9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUsbil7Y29uc3Qgcz10aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxlKTtyZXR1cm4gdGhpcy5kZWx0YShuKS5tdWx0aXBseVNjYWxhcihzKS5hZGQodGhpcy5zdGFydCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLnN0YXJ0LmFwcGx5TWF0cml4NCh0KSx0aGlzLmVuZC5hcHBseU1hdHJpeDQodCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQuc3RhcnQuZXF1YWxzKHRoaXMuc3RhcnQpJiZ0LmVuZC5lcXVhbHModGhpcy5lbmQpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX19dHlwZW9mIF9fVEhSRUVfREVWVE9PTFNfXyE9InVuZGVmaW5lZCImJl9fVEhSRUVfREVWVE9PTFNfXy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudCgicmVnaXN0ZXIiLHtkZXRhaWw6e3JldmlzaW9uOkp9fSkpLHR5cGVvZiB3aW5kb3chPSJ1bmRlZmluZWQiJiYod2luZG93Ll9fVEhSRUVfXz9jb25zb2xlLndhcm4oIldBUk5JTkc6IE11bHRpcGxlIGluc3RhbmNlcyBvZiBUaHJlZS5qcyBiZWluZyBpbXBvcnRlZC4iKTp3aW5kb3cuX19USFJFRV9fPUopO2NvbnN0IHBuPW5ldyBNYXAsWWY9KGk9e30pPT4oe2dlbmVyYXRlVG9wVVYodCxlLG4scyxyKXtjb25zdCBvPWVbbiozXSxhPWVbbiozKzFdLGM9ZVtzKjNdLGw9ZVtzKjMrMV0saD1lW3IqM10sdT1lW3IqMysxXTtsZXQgZjtpZihwbi5oYXModCkpZj1wbi5nZXQodCk7ZWxzZXtsZXQgbT1pLmJveDM7aWYoIW0pe209bmV3IGd0O2NvbnN0IHc9dC5wYXJhbWV0ZXJzLnNoYXBlcy5nZXRQb2ludHMoKS5tYXAoeD0+W3gueCx4LnksMF0pLmZsYXQoKTttLnNldEZyb21BcnJheSh3KX1jb25zdCBnPW0uZ2V0U2l6ZShuZXcgVCk7aS5zcGxpdCYmKGcueS89aS5zcGxpdCksZj17Ym94Om0sc2l6ZTpnfSxwbi5zZXQodCxmKX1jb25zdHtib3g6ZCxzaXplOnB9PWYseT1pLnNwbGl0PzEtaS5zcGxpdDowO3JldHVybltuZXcgUigoby1kLm1pbi54KS9wLngsKGEtZC5taW4ueSkvcC55K3kpLG5ldyBSKChjLWQubWluLngpL3AueCwobC1kLm1pbi55KS9wLnkreSksbmV3IFIoKGgtZC5taW4ueCkvcC54LCh1LWQubWluLnkpL3AueSt5KV19LGdlbmVyYXRlU2lkZVdhbGxVVih0LGUsbixzLHIsbyl7Y29uc3QgYT1lW24qM10sYz1lW24qMysxXSxsPWVbbiozKzJdLGg9ZVtzKjNdLHU9ZVtzKjMrMV0sZj1lW3MqMysyXSxkPWVbciozXSxwPWVbciozKzFdLHk9ZVtyKjMrMl0sbT1lW28qM10sZz1lW28qMysxXSxiPWVbbyozKzJdO2xldCB3O2lmKHBuLmhhcyhlKSl3PXBuLmdldChlKTtlbHNle2NvbnN0IEE9bmV3IGd0O0Euc2V0RnJvbUFycmF5KGUpO2NvbnN0IFM9QS5nZXRTaXplKG5ldyBUKTtpLnNwbGl0JiYoUy56Lz0xLWkuc3BsaXQpLGkuc2lkZVJlcGVhdCYmKFMuei89aS5zaWRlUmVwZWF0KSx3PXtib3g6QSxzaXplOlN9LHBuLnNldChlLHcpfWNvbnN0e2JveDp4LHNpemU6TX09dztyZXR1cm4gTWF0aC5hYnMoYy11KTxNYXRoLmFicyhhLWgpP1tuZXcgUigoYS14Lm1pbi54KS9NLngsKGwteC5taW4ueikvTS56KSxuZXcgUigoaC14Lm1pbi54KS9NLngsKGYteC5taW4ueikvTS56KSxuZXcgUigoZC14Lm1pbi54KS9NLngsKHkteC5taW4ueikvTS56KSxuZXcgUigobS14Lm1pbi54KS9NLngsKGIteC5taW4ueikvTS56KV06W25ldyBSKChjLXgubWluLnkpL00ueSwobC14Lm1pbi56KS9NLnopLG5ldyBSKCh1LXgubWluLnkpL00ueSwoZi14Lm1pbi56KS9NLnopLG5ldyBSKChwLXgubWluLnkpL00ueSwoeS14Lm1pbi56KS9NLnopLG5ldyBSKChnLXgubWluLnkpL00ueSwoYi14Lm1pbi56KS9NLnopXX19KSxqZj0oKT0+e3BuLmNsZWFyKCl9LFFmPXtBcmNDdXJ2ZTokYyxDYXRtdWxsUm9tQ3VydmUzOlZjLEN1YmljQmV6aWVyQ3VydmU6Qm8sQ3ViaWNCZXppZXJDdXJ2ZTM6cWMsRWxsaXBzZUN1cnZlOl9zLExpbmVDdXJ2ZTpGbyxMaW5lQ3VydmUzOkhjLFF1YWRyYXRpY0JlemllckN1cnZlOklvLFF1YWRyYXRpY0JlemllckN1cnZlMzpXYyxTcGxpbmVDdXJ2ZTprb307Y2xhc3MgR24gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PW5ldyBYYyhbbmV3IFIoLjUsLjUpLG5ldyBSKC0uNSwuNSksbmV3IFIoLS41LC0uNSksbmV3IFIoLjUsLS41KV0pLGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJFeHRydWRlR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz17c2hhcGVzOnQsb3B0aW9uczplfSx0PUFycmF5LmlzQXJyYXkodCk/dDpbdF07Y29uc3Qgbj10aGlzLHM9W10scj1bXTtmb3IobGV0IGE9MCxjPXQubGVuZ3RoO2E8YzthKyspe2NvbnN0IGw9dFthXTtvKGwpfXRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsbmV3IEJlKHMsMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IEJlKHIsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtmdW5jdGlvbiBvKGEpe3ZhciBPdSxEdSwkdTtjb25zdCBjPVtdLGw9ZS5jdXJ2ZVNlZ21lbnRzIT09dm9pZCAwP2UuY3VydmVTZWdtZW50czoxMixoPWUuc3RlcHMhPT12b2lkIDA/ZS5zdGVwczoxLHU9ZS5kZXB0aCE9PXZvaWQgMD9lLmRlcHRoOjE7bGV0IGY9ZS5iZXZlbEVuYWJsZWQhPT12b2lkIDA/ZS5iZXZlbEVuYWJsZWQ6ITAsZD1lLmJldmVsVGhpY2tuZXNzIT09dm9pZCAwP2UuYmV2ZWxUaGlja25lc3M6LjIscD1lLmJldmVsU2l6ZSE9PXZvaWQgMD9lLmJldmVsU2l6ZTpkLS4xLHk9ZS5iZXZlbE9mZnNldCE9PXZvaWQgMD9lLmJldmVsT2Zmc2V0OjAsbT1lLmJldmVsU2VnbWVudHMhPT12b2lkIDA/ZS5iZXZlbFNlZ21lbnRzOjM7Y29uc3QgZz1lLmV4dHJ1ZGVQYXRoLGI9ZS5VVkdlbmVyYXRvciE9PXZvaWQgMD9lLlVWR2VuZXJhdG9yOktmLHc9KE91PWUuaGFzVG9wKSE9bnVsbD9PdTohMCx4PShEdT1lLmhhc0JvdHRvbSkhPW51bGw/RHU6ITAsTT0oJHU9ZS5oYXNTaWRlKSE9bnVsbD8kdTohMDtsZXQgQSxTPSExLF8sRSx6LHY7ZyYmKEE9Zy5nZXRTcGFjZWRQb2ludHMoaCksUz0hMCxmPSExLF89Zy5jb21wdXRlRnJlbmV0RnJhbWVzKGgsITEpLEU9bmV3IFQsej1uZXcgVCx2PW5ldyBUKSxmfHwobT0wLGQ9MCxwPTAseT0wKTtjb25zdCBDPWEuZXh0cmFjdFBvaW50cyhsKTtsZXQgUD1DLnNoYXBlO2NvbnN0IEY9Qy5ob2xlcztpZighV24uaXNDbG9ja1dpc2UoUCkpe1A9UC5yZXZlcnNlKCk7Zm9yKGxldCBOPTAsTD1GLmxlbmd0aDtOPEw7TisrKXtjb25zdCBPPUZbTl07V24uaXNDbG9ja1dpc2UoTykmJihGW05dPU8ucmV2ZXJzZSgpKX19ZnVuY3Rpb24gSShOKXtjb25zdCBPPTEwMDAwMDAwMDAwMDAwMDAxZS0zNjtsZXQgVj1OWzBdO2ZvcihsZXQgJD0xOyQ8PU4ubGVuZ3RoOyQrKyl7Y29uc3QgWT0kJU4ubGVuZ3RoLEc9TltZXSxpdD1HLngtVi54LGN0PUcueS1WLnksd3Q9aXQqaXQrY3QqY3QsWHQ9TWF0aC5tYXgoTWF0aC5hYnMoRy54KSxNYXRoLmFicyhHLnkpLE1hdGguYWJzKFYueCksTWF0aC5hYnMoVi55KSksQ249TypYdCpYdDtpZih3dDw9Q24pe04uc3BsaWNlKFksMSksJC0tO2NvbnRpbnVlfVY9R319SShQKSxGLmZvckVhY2goSSk7Y29uc3Qgaz1GLmxlbmd0aCxEPVA7Zm9yKGxldCBOPTA7TjxrO04rKyl7Y29uc3QgTD1GW05dO1A9UC5jb25jYXQoTCl9ZnVuY3Rpb24gVShOLEwsTyl7cmV0dXJuIEx8fGNvbnNvbGUuZXJyb3IoIlRIUkVFLkV4dHJ1ZGVHZW9tZXRyeTogdmVjIGRvZXMgbm90IGV4aXN0IiksTi5jbG9uZSgpLmFkZFNjYWxlZFZlY3RvcihMLE8pfWNvbnN0IGo9UC5sZW5ndGg7ZnVuY3Rpb24gZHQoTixMLE8pe2xldCBWLCQsWTtjb25zdCBHPU4ueC1MLngsaXQ9Ti55LUwueSxjdD1PLngtTi54LHd0PU8ueS1OLnksWHQ9RypHK2l0Kml0LENuPUcqd3QtaXQqY3Q7aWYoTWF0aC5hYnMoQ24pPk51bWJlci5FUFNJTE9OKXtjb25zdCBKdD1NYXRoLnNxcnQoWHQpLFZ1PU1hdGguc3FydChjdCpjdCt3dCp3dCksVXU9TC54LWl0L0p0LHF1PUwueStHL0p0LFBnPU8ueC13dC9WdSxDZz1PLnkrY3QvVnUsSHU9KChQZy1VdSkqd3QtKENnLXF1KSpjdCkvKEcqd3QtaXQqY3QpO1Y9VXUrRypIdS1OLngsJD1xdStpdCpIdS1OLnk7Y29uc3QgV3U9VipWKyQqJDtpZihXdTw9MilyZXR1cm4gbmV3IFIoViwkKTtZPU1hdGguc3FydChXdS8yKX1lbHNle2xldCBKdD0hMTtHPk51bWJlci5FUFNJTE9OP2N0Pk51bWJlci5FUFNJTE9OJiYoSnQ9ITApOkc8LU51bWJlci5FUFNJTE9OP2N0PC1OdW1iZXIuRVBTSUxPTiYmKEp0PSEwKTpNYXRoLnNpZ24oaXQpPT09TWF0aC5zaWduKHd0KSYmKEp0PSEwKSxKdD8oVj0taXQsJD1HLFk9TWF0aC5zcXJ0KFh0KSk6KFY9RywkPWl0LFk9TWF0aC5zcXJ0KFh0LzIpKX1yZXR1cm4gbmV3IFIoVi9ZLCQvWSl9Y29uc3QgRHQ9W107Zm9yKGxldCBOPTAsTD1ELmxlbmd0aCxPPUwtMSxWPU4rMTtOPEw7TisrLE8rKyxWKyspTz09PUwmJihPPTApLFY9PT1MJiYoVj0wKSxEdFtOXT1kdChEW05dLERbT10sRFtWXSk7Y29uc3QgR3Q9W107bGV0IFp0LG1lPUR0LmNvbmNhdCgpO2ZvcihsZXQgTj0wLEw9aztOPEw7TisrKXtjb25zdCBPPUZbTl07WnQ9W107Zm9yKGxldCBWPTAsJD1PLmxlbmd0aCxZPSQtMSxHPVYrMTtWPCQ7VisrLFkrKyxHKyspWT09PSQmJihZPTApLEc9PT0kJiYoRz0wKSxadFtWXT1kdChPW1ZdLE9bWV0sT1tHXSk7R3QucHVzaChadCksbWU9bWUuY29uY2F0KFp0KX1sZXQgUG47aWYobT09PTApUG49V24udHJpYW5ndWxhdGVTaGFwZShELEYpO2Vsc2V7Y29uc3QgTj1bXSxMPVtdO2ZvcihsZXQgTz0wO088bTtPKyspe2NvbnN0IFY9Ty9tLCQ9ZCpNYXRoLmNvcyhWKk1hdGguUEkvMiksWT1wKk1hdGguc2luKFYqTWF0aC5QSS8yKSt5O2ZvcihsZXQgRz0wLGl0PUQubGVuZ3RoO0c8aXQ7RysrKXtjb25zdCBjdD1VKERbR10sRHRbR10sWSk7SGUoY3QueCxjdC55LC0kKSxWPT09MCYmTi5wdXNoKGN0KX1mb3IobGV0IEc9MCxpdD1rO0c8aXQ7RysrKXtjb25zdCBjdD1GW0ddO1p0PUd0W0ddO2NvbnN0IHd0PVtdO2ZvcihsZXQgWHQ9MCxDbj1jdC5sZW5ndGg7WHQ8Q247WHQrKyl7Y29uc3QgSnQ9VShjdFtYdF0sWnRbWHRdLFkpO0hlKEp0LngsSnQueSwtJCksVj09PTAmJnd0LnB1c2goSnQpfVY9PT0wJiZMLnB1c2god3QpfX1Qbj1Xbi50cmlhbmd1bGF0ZVNoYXBlKE4sTCl9Y29uc3QgWXI9UG4ubGVuZ3RoLFJ1PXAreTtmb3IobGV0IE49MDtOPGo7TisrKXtjb25zdCBMPWY/VShQW05dLG1lW05dLFJ1KTpQW05dO1M/KHouY29weShfLm5vcm1hbHNbMF0pLm11bHRpcGx5U2NhbGFyKEwueCksRS5jb3B5KF8uYmlub3JtYWxzWzBdKS5tdWx0aXBseVNjYWxhcihMLnkpLHYuY29weShBWzBdKS5hZGQoeikuYWRkKEUpLEhlKHYueCx2Lnksdi56KSk6SGUoTC54LEwueSwwKX1mb3IobGV0IE49MTtOPD1oO04rKylmb3IobGV0IEw9MDtMPGo7TCsrKXtjb25zdCBPPWY/VShQW0xdLG1lW0xdLFJ1KTpQW0xdO1M/KHouY29weShfLm5vcm1hbHNbTl0pLm11bHRpcGx5U2NhbGFyKE8ueCksRS5jb3B5KF8uYmlub3JtYWxzW05dKS5tdWx0aXBseVNjYWxhcihPLnkpLHYuY29weShBW05dKS5hZGQoeikuYWRkKEUpLEhlKHYueCx2Lnksdi56KSk6SGUoTy54LE8ueSx1L2gqTil9Zm9yKGxldCBOPW0tMTtOPj0wO04tLSl7Y29uc3QgTD1OL20sTz1kKk1hdGguY29zKEwqTWF0aC5QSS8yKSxWPXAqTWF0aC5zaW4oTCpNYXRoLlBJLzIpK3k7Zm9yKGxldCAkPTAsWT1ELmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPVUoRFskXSxEdFskXSxWKTtIZShHLngsRy55LHUrTyl9Zm9yKGxldCAkPTAsWT1GLmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPUZbJF07WnQ9R3RbJF07Zm9yKGxldCBpdD0wLGN0PUcubGVuZ3RoO2l0PGN0O2l0Kyspe2NvbnN0IHd0PVUoR1tpdF0sWnRbaXRdLFYpO1M/SGUod3QueCx3dC55K0FbaC0xXS55LEFbaC0xXS54K08pOkhlKHd0Lngsd3QueSx1K08pfX19emcoKSxNJiZUZygpO2Z1bmN0aW9uIHpnKCl7Y29uc3QgTj1zLmxlbmd0aC8zO2lmKGYpe2xldCBMPTAsTz1qKkw7aWYoeClmb3IobGV0IFY9MDtWPFlyO1YrKyl7Y29uc3QgJD1QbltWXTtqcigkWzJdK08sJFsxXStPLCRbMF0rTyl9aWYoTD1oK20qMixPPWoqTCx3KWZvcihsZXQgVj0wO1Y8WXI7VisrKXtjb25zdCAkPVBuW1ZdO2pyKCRbMF0rTywkWzFdK08sJFsyXStPKX19ZWxzZXtpZih4KWZvcihsZXQgTD0wO0w8WXI7TCsrKXtjb25zdCBPPVBuW0xdO2pyKE9bMl0sT1sxXSxPWzBdKX1pZih3KWZvcihsZXQgTD0wO0w8WXI7TCsrKXtjb25zdCBPPVBuW0xdO2pyKE9bMF0raipoLE9bMV0raipoLE9bMl0raipoKX19bi5hZGRHcm91cChOLHMubGVuZ3RoLzMtTiwwKX1mdW5jdGlvbiBUZygpe2NvbnN0IE49cy5sZW5ndGgvMztsZXQgTD0wO0x1KEQsTCksTCs9RC5sZW5ndGg7Zm9yKGxldCBPPTAsVj1GLmxlbmd0aDtPPFY7TysrKXtjb25zdCAkPUZbT107THUoJCxMKSxMKz0kLmxlbmd0aH1uLmFkZEdyb3VwKE4scy5sZW5ndGgvMy1OLDEpfWZ1bmN0aW9uIEx1KE4sTCl7bGV0IE89Ti5sZW5ndGg7Zm9yKDstLU8+PTA7KXtjb25zdCBWPU87bGV0ICQ9Ty0xOyQ8MCYmKCQ9Ti5sZW5ndGgtMSk7Zm9yKGxldCBZPTAsRz1oK20qMjtZPEc7WSsrKXtjb25zdCBpdD1qKlksY3Q9aiooWSsxKSx3dD1MK1YraXQsWHQ9TCskK2l0LENuPUwrJCtjdCxKdD1MK1YrY3Q7RWcod3QsWHQsQ24sSnQpfX19ZnVuY3Rpb24gSGUoTixMLE8pe2MucHVzaChOKSxjLnB1c2goTCksYy5wdXNoKE8pfWZ1bmN0aW9uIGpyKE4sTCxPKXtXZShOKSxXZShMKSxXZShPKTtjb25zdCBWPXMubGVuZ3RoLzMsJD1iLmdlbmVyYXRlVG9wVVYobixzLFYtMyxWLTIsVi0xKTtHZSgkWzBdKSxHZSgkWzFdKSxHZSgkWzJdKX1mdW5jdGlvbiBFZyhOLEwsTyxWKXtXZShOKSxXZShMKSxXZShWKSxXZShMKSxXZShPKSxXZShWKTtjb25zdCAkPXMubGVuZ3RoLzMsWT1iLmdlbmVyYXRlU2lkZVdhbGxVVihuLHMsJC02LCQtMywkLTIsJC0xKTtHZShZWzBdKSxHZShZWzFdKSxHZShZWzNdKSxHZShZWzFdKSxHZShZWzJdKSxHZShZWzNdKX1mdW5jdGlvbiBXZShOKXtzLnB1c2goY1tOKjMrMF0pLHMucHVzaChjW04qMysxXSkscy5wdXNoKGNbTiozKzJdKX1mdW5jdGlvbiBHZShOKXtyLnB1c2goTi54KSxyLnB1c2goTi55KX19fWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCksZT10aGlzLnBhcmFtZXRlcnMuc2hhcGVzLG49dGhpcy5wYXJhbWV0ZXJzLm9wdGlvbnM7cmV0dXJuIHRkKGUsbix0KX1zdGF0aWMgZnJvbUpTT04odCxlKXtjb25zdCBuPVtdO2ZvcihsZXQgcj0wLG89dC5zaGFwZXMubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVt0LnNoYXBlc1tyXV07bi5wdXNoKGEpfWNvbnN0IHM9dC5vcHRpb25zLmV4dHJ1ZGVQYXRoO3JldHVybiBzIT09dm9pZCAwJiYodC5vcHRpb25zLmV4dHJ1ZGVQYXRoPW5ldyBRZltgJHtzLnR5cGV9YF0oKS5mcm9tSlNPTihzKSksbmV3IEduKG4sdC5vcHRpb25zKX19Y29uc3QgS2Y9e2dlbmVyYXRlVG9wVVY6ZnVuY3Rpb24oaSx0LGUsbixzKXtjb25zdCByPXRbZSozXSxvPXRbZSozKzFdLGE9dFtuKjNdLGM9dFtuKjMrMV0sbD10W3MqM10saD10W3MqMysxXTtyZXR1cm5bbmV3IFIocixvKSxuZXcgUihhLGMpLG5ldyBSKGwsaCldfSxnZW5lcmF0ZVNpZGVXYWxsVVY6ZnVuY3Rpb24oaSx0LGUsbixzLHIpe2NvbnN0IG89dFtlKjNdLGE9dFtlKjMrMV0sYz10W2UqMysyXSxsPXRbbiozXSxoPXRbbiozKzFdLHU9dFtuKjMrMl0sZj10W3MqM10sZD10W3MqMysxXSxwPXRbcyozKzJdLHk9dFtyKjNdLG09dFtyKjMrMV0sZz10W3IqMysyXTtyZXR1cm4gTWF0aC5hYnMoYS1oKTxNYXRoLmFicyhvLWwpP1tuZXcgUihvLDEtYyksbmV3IFIobCwxLXUpLG5ldyBSKGYsMS1wKSxuZXcgUih5LDEtZyldOltuZXcgUihhLDEtYyksbmV3IFIoaCwxLXUpLG5ldyBSKGQsMS1wKSxuZXcgUihtLDEtZyldfX07ZnVuY3Rpb24gdGQoaSx0LGUpe2lmKGUuc2hhcGVzPVtdLEFycmF5LmlzQXJyYXkoaSkpZm9yKGxldCBuPTAscz1pLmxlbmd0aDtuPHM7bisrKXtjb25zdCByPWlbbl07ZS5zaGFwZXMucHVzaChyLnV1aWQpfWVsc2UgZS5zaGFwZXMucHVzaChpLnV1aWQpO3JldHVybiBlLm9wdGlvbnM9T2JqZWN0LmFzc2lnbih7fSx0KSx0LmV4dHJ1ZGVQYXRoIT09dm9pZCAwJiYoZS5vcHRpb25zLmV4dHJ1ZGVQYXRoPXQuZXh0cnVkZVBhdGgudG9KU09OKCkpLGV9Y29uc3QgaWw9MCxlZD0xLG5kPTIsc2w9MixPbz0xLjI1LHJsPTEsUGk9Nio0KzQrNCxQcz02NTUzNSxpZD1NYXRoLnBvdygyLC0yNCksRG89U3ltYm9sKCJTS0lQX0dFTkVSQVRJT04iKTtmdW5jdGlvbiBzZChpKXtyZXR1cm4gaS5pbmRleD9pLmluZGV4LmNvdW50OmkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudH1mdW5jdGlvbiBabihpKXtyZXR1cm4gc2QoaSkvM31mdW5jdGlvbiByZChpLHQ9QXJyYXlCdWZmZXIpe3JldHVybiBpPjY1NTM1P25ldyBVaW50MzJBcnJheShuZXcgdCg0KmkpKTpuZXcgVWludDE2QXJyYXkobmV3IHQoMippKSl9ZnVuY3Rpb24gb2QoaSx0KXtpZighaS5pbmRleCl7Y29uc3QgZT1pLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQsbj10LnVzZVNoYXJlZEFycmF5QnVmZmVyP1NoYXJlZEFycmF5QnVmZmVyOkFycmF5QnVmZmVyLHM9cmQoZSxuKTtpLnNldEluZGV4KG5ldyB4dChzLDEpKTtmb3IobGV0IHI9MDtyPGU7cisrKXNbcl09cn19ZnVuY3Rpb24gb2woaSx0KXtjb25zdCBlPVpuKGkpLG49dHx8aS5kcmF3UmFuZ2Uscz1uLnN0YXJ0LzMscj0obi5zdGFydCtuLmNvdW50KS8zLG89TWF0aC5tYXgoMCxzKSxhPU1hdGgubWluKGUsciktbztyZXR1cm5be29mZnNldDpNYXRoLmZsb29yKG8pLGNvdW50Ok1hdGguZmxvb3IoYSl9XX1mdW5jdGlvbiBhbChpLHQpe2lmKCFpLmdyb3Vwc3x8IWkuZ3JvdXBzLmxlbmd0aClyZXR1cm4gb2woaSx0KTtjb25zdCBlPVtdLG49bmV3IFNldCxzPXR8fGkuZHJhd1JhbmdlLHI9cy5zdGFydC8zLG89KHMuc3RhcnQrcy5jb3VudCkvMztmb3IoY29uc3QgYyBvZiBpLmdyb3Vwcyl7Y29uc3QgbD1jLnN0YXJ0LzMsaD0oYy5zdGFydCtjLmNvdW50KS8zO24uYWRkKE1hdGgubWF4KHIsbCkpLG4uYWRkKE1hdGgubWluKG8saCkpfWNvbnN0IGE9QXJyYXkuZnJvbShuLnZhbHVlcygpKS5zb3J0KChjLGwpPT5jLWwpO2ZvcihsZXQgYz0wO2M8YS5sZW5ndGgtMTtjKyspe2NvbnN0IGw9YVtjXSxoPWFbYysxXTtlLnB1c2goe29mZnNldDpNYXRoLmZsb29yKGwpLGNvdW50Ok1hdGguZmxvb3IoaC1sKX0pfXJldHVybiBlfWZ1bmN0aW9uIGFkKGksdCl7Y29uc3QgZT1abihpKSxuPWFsKGksdCkuc29ydCgobyxhKT0+by5vZmZzZXQtYS5vZmZzZXQpLHM9bltuLmxlbmd0aC0xXTtzLmNvdW50PU1hdGgubWluKGUtcy5vZmZzZXQscy5jb3VudCk7bGV0IHI9MDtyZXR1cm4gbi5mb3JFYWNoKCh7Y291bnQ6b30pPT5yKz1vKSxlIT09cn1mdW5jdGlvbiAkbyhpLHQsZSxuLHMpe2xldCByPTEvMCxvPTEvMCxhPTEvMCxjPS0xLzAsbD0tMS8wLGg9LTEvMCx1PTEvMCxmPTEvMCxkPTEvMCxwPS0xLzAseT0tMS8wLG09LTEvMDtmb3IobGV0IGc9dCo2LGI9KHQrZSkqNjtnPGI7Zys9Nil7Y29uc3Qgdz1pW2crMF0seD1pW2crMV0sTT13LXgsQT13K3g7TTxyJiYocj1NKSxBPmMmJihjPUEpLHc8dSYmKHU9dyksdz5wJiYocD13KTtjb25zdCBTPWlbZysyXSxfPWlbZyszXSxFPVMtXyx6PVMrXztFPG8mJihvPUUpLHo+bCYmKGw9eiksUzxmJiYoZj1TKSxTPnkmJih5PVMpO2NvbnN0IHY9aVtnKzRdLEM9aVtnKzVdLFA9di1DLEY9ditDO1A8YSYmKGE9UCksRj5oJiYoaD1GKSx2PGQmJihkPXYpLHY+bSYmKG09dil9blswXT1yLG5bMV09byxuWzJdPWEsblszXT1jLG5bNF09bCxuWzVdPWgsc1swXT11LHNbMV09ZixzWzJdPWQsc1szXT1wLHNbNF09eSxzWzVdPW19ZnVuY3Rpb24gY2QoaSx0PW51bGwsZT1udWxsLG49bnVsbCl7Y29uc3Qgcz1pLmF0dHJpYnV0ZXMucG9zaXRpb24scj1pLmluZGV4P2kuaW5kZXguYXJyYXk6bnVsbCxvPVpuKGkpLGE9cy5ub3JtYWxpemVkO2xldCBjO3Q9PT1udWxsPyhjPW5ldyBGbG9hdDMyQXJyYXkobyo2KSxlPTAsbj1vKTooYz10LGU9ZXx8MCxuPW58fG8pO2NvbnN0IGw9cy5hcnJheSxoPXMub2Zmc2V0fHwwO2xldCB1PTM7cy5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlJiYodT1zLmRhdGEuc3RyaWRlKTtjb25zdCBmPVsiZ2V0WCIsImdldFkiLCJnZXRaIl07Zm9yKGxldCBkPWU7ZDxlK247ZCsrKXtjb25zdCBwPWQqMyx5PWQqNjtsZXQgbT1wKzAsZz1wKzEsYj1wKzI7ciYmKG09clttXSxnPXJbZ10sYj1yW2JdKSxhfHwobT1tKnUraCxnPWcqdStoLGI9Yip1K2gpO2ZvcihsZXQgdz0wO3c8Mzt3Kyspe2xldCB4LE0sQTthPyh4PXNbZlt3XV0obSksTT1zW2Zbd11dKGcpLEE9c1tmW3ddXShiKSk6KHg9bFttK3ddLE09bFtnK3ddLEE9bFtiK3ddKTtsZXQgUz14O008UyYmKFM9TSksQTxTJiYoUz1BKTtsZXQgXz14O00+XyYmKF89TSksQT5fJiYoXz1BKTtjb25zdCBFPShfLVMpLzIsej13KjI7Y1t5K3orMF09UytFLGNbeSt6KzFdPUUrKE1hdGguYWJzKFMpK0UpKmlkfX1yZXR1cm4gY31mdW5jdGlvbiBsdChpLHQsZSl7cmV0dXJuIGUubWluLng9dFtpXSxlLm1pbi55PXRbaSsxXSxlLm1pbi56PXRbaSsyXSxlLm1heC54PXRbaSszXSxlLm1heC55PXRbaSs0XSxlLm1heC56PXRbaSs1XSxlfWZ1bmN0aW9uIGNsKGkpe2xldCB0PS0xLGU9LTEvMDtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPWlbbiszXS1pW25dO3M+ZSYmKGU9cyx0PW4pfXJldHVybiB0fWZ1bmN0aW9uIGxsKGksdCl7dC5zZXQoaSl9ZnVuY3Rpb24gaGwoaSx0LGUpe2xldCBuLHM7Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz1yKzM7bj1pW3JdLHM9dFtyXSxlW3JdPW48cz9uOnMsbj1pW29dLHM9dFtvXSxlW29dPW4+cz9uOnN9fWZ1bmN0aW9uIENzKGksdCxlKXtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPXRbaSsyKm5dLHI9dFtpKzIqbisxXSxvPXMtcixhPXMrcjtvPGVbbl0mJihlW25dPW8pLGE+ZVtuKzNdJiYoZVtuKzNdPWEpfX1mdW5jdGlvbiBDaShpKXtjb25zdCB0PWlbM10taVswXSxlPWlbNF0taVsxXSxuPWlbNV0taVsyXTtyZXR1cm4gMioodCplK2UqbituKnQpfWNvbnN0IEZlPTMyLGxkPShpLHQpPT5pLmNhbmRpZGF0ZS10LmNhbmRpZGF0ZSxLZT1uZXcgQXJyYXkoRmUpLmZpbGwoKS5tYXAoKCk9Pih7Y291bnQ6MCxib3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxyaWdodENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksbGVmdENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksY2FuZGlkYXRlOjB9KSksQnM9bmV3IEZsb2F0MzJBcnJheSg2KTtmdW5jdGlvbiBoZChpLHQsZSxuLHMscil7bGV0IG89LTEsYT0wO2lmKHI9PT1pbClvPWNsKHQpLG8hPT0tMSYmKGE9KHRbb10rdFtvKzNdKS8yKTtlbHNlIGlmKHI9PT1lZClvPWNsKGkpLG8hPT0tMSYmKGE9dWQoZSxuLHMsbykpO2Vsc2UgaWYocj09PW5kKXtjb25zdCBjPUNpKGkpO2xldCBsPU9vKnM7Y29uc3QgaD1uKjYsdT0obitzKSo2O2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9dFtmXSxtPSh0W2YrM10tZCkvRmU7aWYoczxGZS80KXtjb25zdCBnPVsuLi5LZV07Zy5sZW5ndGg9cztsZXQgYj0wO2ZvcihsZXQgeD1oO3g8dTt4Kz02LGIrKyl7Y29uc3QgTT1nW2JdO00uY2FuZGlkYXRlPWVbeCsyKmZdLE0uY291bnQ9MDtjb25zdHtib3VuZHM6QSxsZWZ0Q2FjaGVCb3VuZHM6UyxyaWdodENhY2hlQm91bmRzOl99PU07Zm9yKGxldCBFPTA7RTwzO0UrKylfW0VdPTEvMCxfW0UrM109LTEvMCxTW0VdPTEvMCxTW0UrM109LTEvMCxBW0VdPTEvMCxBW0UrM109LTEvMDtDcyh4LGUsQSl9Zy5zb3J0KGxkKTtsZXQgdz1zO2ZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XTtmb3IoO3grMTx3JiZnW3grMV0uY2FuZGlkYXRlPT09TS5jYW5kaWRhdGU7KWcuc3BsaWNlKHgrMSwxKSx3LS19Zm9yKGxldCB4PWg7eDx1O3grPTYpe2NvbnN0IE09ZVt4KzIqZl07Zm9yKGxldCBBPTA7QTx3O0ErKyl7Y29uc3QgUz1nW0FdO00+PVMuY2FuZGlkYXRlP0NzKHgsZSxTLnJpZ2h0Q2FjaGVCb3VuZHMpOihDcyh4LGUsUy5sZWZ0Q2FjaGVCb3VuZHMpLFMuY291bnQrKyl9fWZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XSxBPU0uY291bnQsUz1zLU0uY291bnQsXz1NLmxlZnRDYWNoZUJvdW5kcyxFPU0ucmlnaHRDYWNoZUJvdW5kcztsZXQgej0wO0EhPT0wJiYoej1DaShfKS9jKTtsZXQgdj0wO1MhPT0wJiYodj1DaShFKS9jKTtjb25zdCBDPXJsK09vKih6KkErdipTKTtDPGwmJihvPWYsbD1DLGE9TS5jYW5kaWRhdGUpfX1lbHNle2ZvcihsZXQgdz0wO3c8RmU7dysrKXtjb25zdCB4PUtlW3ddO3guY291bnQ9MCx4LmNhbmRpZGF0ZT1kK20rdyptO2NvbnN0IE09eC5ib3VuZHM7Zm9yKGxldCBBPTA7QTwzO0ErKylNW0FdPTEvMCxNW0ErM109LTEvMH1mb3IobGV0IHc9aDt3PHU7dys9Nil7bGV0IEE9fn4oKGVbdysyKmZdLWQpL20pO0E+PUZlJiYoQT1GZS0xKTtjb25zdCBTPUtlW0FdO1MuY291bnQrKyxDcyh3LGUsUy5ib3VuZHMpfWNvbnN0IGc9S2VbRmUtMV07bGwoZy5ib3VuZHMsZy5yaWdodENhY2hlQm91bmRzKTtmb3IobGV0IHc9RmUtMjt3Pj0wO3ctLSl7Y29uc3QgeD1LZVt3XSxNPUtlW3crMV07aGwoeC5ib3VuZHMsTS5yaWdodENhY2hlQm91bmRzLHgucmlnaHRDYWNoZUJvdW5kcyl9bGV0IGI9MDtmb3IobGV0IHc9MDt3PEZlLTE7dysrKXtjb25zdCB4PUtlW3ddLE09eC5jb3VudCxBPXguYm91bmRzLF89S2VbdysxXS5yaWdodENhY2hlQm91bmRzO00hPT0wJiYoYj09PTA/bGwoQSxCcyk6aGwoQSxCcyxCcykpLGIrPU07bGV0IEU9MCx6PTA7YiE9PTAmJihFPUNpKEJzKS9jKTtjb25zdCB2PXMtYjt2IT09MCYmKHo9Q2koXykvYyk7Y29uc3QgQz1ybCtPbyooRSpiK3oqdik7QzxsJiYobz1mLGw9QyxhPXguY2FuZGlkYXRlKX19fX1lbHNlIGNvbnNvbGUud2FybihgTWVzaEJWSDogSW52YWxpZCBidWlsZCBzdHJhdGVneSB2YWx1ZSAke3J9IHVzZWQuYCk7cmV0dXJue2F4aXM6byxwb3M6YX19ZnVuY3Rpb24gdWQoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPXQrZTtyPG87cisrKXMrPWlbcio2K24qMl07cmV0dXJuIHMvZX1jbGFzcyBWb3tjb25zdHJ1Y3Rvcigpe3RoaXMuYm91bmRpbmdEYXRhPW5ldyBGbG9hdDMyQXJyYXkoNil9fWZ1bmN0aW9uIGZkKGksdCxlLG4scyxyKXtsZXQgbz1uLGE9bitzLTE7Y29uc3QgYz1yLnBvcyxsPXIuYXhpcyoyO2Zvcig7Oyl7Zm9yKDtvPD1hJiZlW28qNitsXTxjOylvKys7Zm9yKDtvPD1hJiZlW2EqNitsXT49YzspYS0tO2lmKG88YSl7Zm9yKGxldCBoPTA7aDwzO2grKyl7bGV0IHU9dFtvKjMraF07dFtvKjMraF09dFthKjMraF0sdFthKjMraF09dX1mb3IobGV0IGg9MDtoPDY7aCsrKXtsZXQgdT1lW28qNitoXTtlW28qNitoXT1lW2EqNitoXSxlW2EqNitoXT11fW8rKyxhLS19ZWxzZSByZXR1cm4gb319ZnVuY3Rpb24gZGQoaSx0LGUsbixzLHIpe2xldCBvPW4sYT1uK3MtMTtjb25zdCBjPXIucG9zLGw9ci5heGlzKjI7Zm9yKDs7KXtmb3IoO288PWEmJmVbbyo2K2xdPGM7KW8rKztmb3IoO288PWEmJmVbYSo2K2xdPj1jOylhLS07aWYobzxhKXtsZXQgaD1pW29dO2lbb109aVthXSxpW2FdPWg7Zm9yKGxldCB1PTA7dTw2O3UrKyl7bGV0IGY9ZVtvKjYrdV07ZVtvKjYrdV09ZVthKjYrdV0sZVthKjYrdV09Zn1vKyssYS0tfWVsc2UgcmV0dXJuIG99fWZ1bmN0aW9uIGt0KGksdCl7cmV0dXJuIHRbaSsxNV09PT02NTUzNX1mdW5jdGlvbiBVdChpLHQpe3JldHVybiB0W2krNl19ZnVuY3Rpb24gS3QoaSx0KXtyZXR1cm4gdFtpKzE0XX1mdW5jdGlvbiB0ZShpKXtyZXR1cm4gaSs4fWZ1bmN0aW9uIGVlKGksdCl7cmV0dXJuIHRbaSs2XX1mdW5jdGlvbiB1bChpLHQpe3JldHVybiB0W2krN119ZnVuY3Rpb24gamcoaSl7cmV0dXJuIGl9bGV0IGZsLEJpLEZzLGRsO2NvbnN0IHBkPU1hdGgucG93KDIsMzIpO2Z1bmN0aW9uIFVvKGkpe3JldHVybiJjb3VudCJpbiBpPzE6MStVbyhpLmxlZnQpK1VvKGkucmlnaHQpfWZ1bmN0aW9uIHlkKGksdCxlKXtyZXR1cm4gZmw9bmV3IEZsb2F0MzJBcnJheShlKSxCaT1uZXcgVWludDMyQXJyYXkoZSksRnM9bmV3IFVpbnQxNkFycmF5KGUpLGRsPW5ldyBVaW50OEFycmF5KGUpLHFvKGksdCl9ZnVuY3Rpb24gcW8oaSx0KXtjb25zdCBlPWkvNCxuPWkvMixzPSJjb3VudCJpbiB0LHI9dC5ib3VuZGluZ0RhdGE7Zm9yKGxldCBvPTA7bzw2O28rKylmbFtlK29dPXJbb107aWYocylpZih0LmJ1ZmZlcil7Y29uc3Qgbz10LmJ1ZmZlcjtkbC5zZXQobmV3IFVpbnQ4QXJyYXkobyksaSk7Zm9yKGxldCBhPWksYz1pK28uYnl0ZUxlbmd0aDthPGM7YSs9UGkpe2NvbnN0IGw9YS8yO2t0KGwsRnMpfHwoQmlbYS80KzZdKz1lKX1yZXR1cm4gaStvLmJ5dGVMZW5ndGh9ZWxzZXtjb25zdCBvPXQub2Zmc2V0LGE9dC5jb3VudDtyZXR1cm4gQmlbZSs2XT1vLEZzW24rMTRdPWEsRnNbbisxNV09UHMsaStQaX1lbHNle2NvbnN0IG89dC5sZWZ0LGE9dC5yaWdodCxjPXQuc3BsaXRBeGlzO2xldCBsO2lmKGw9cW8oaStQaSxvKSxsLzQ+cGQpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBDYW5ub3Qgc3RvcmUgY2hpbGQgcG9pbnRlciBncmVhdGVyIHRoYW4gMzIgYml0cy4iKTtyZXR1cm4gQmlbZSs2XT1sLzQsbD1xbyhsLGEpLEJpW2UrN109YyxsfX1mdW5jdGlvbiBtZChpLHQpe2NvbnN0IGU9KGkuaW5kZXg/aS5pbmRleC5jb3VudDppLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQpLzMsbj1lPnlpKDIsMTYpLHM9bj80OjIscj10P25ldyBTaGFyZWRBcnJheUJ1ZmZlcihlKnMpOm5ldyBBcnJheUJ1ZmZlcihlKnMpLG89bj9uZXcgVWludDMyQXJyYXkocik6bmV3IFVpbnQxNkFycmF5KHIpO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKylvW2FdPWE7cmV0dXJuIG99ZnVuY3Rpb24gZ2QoaSx0LGUsbixzKXtjb25zdHttYXhEZXB0aDpyLHZlcmJvc2U6byxtYXhMZWFmVHJpczphLHN0cmF0ZWd5OmMsb25Qcm9ncmVzczpsLGluZGlyZWN0Omh9PXMsdT1pLl9pbmRpcmVjdEJ1ZmZlcixmPWkuZ2VvbWV0cnksZD1mLmluZGV4P2YuaW5kZXguYXJyYXk6bnVsbCxwPWg/ZGQ6ZmQseT1abihmKSxtPW5ldyBGbG9hdDMyQXJyYXkoNik7bGV0IGc9ITE7Y29uc3QgYj1uZXcgVm87cmV0dXJuICRvKHQsZSxuLGIuYm91bmRpbmdEYXRhLG0pLHgoYixlLG4sbSksYjtmdW5jdGlvbiB3KE0pe2wmJmwoTS95KX1mdW5jdGlvbiB4KE0sQSxTLF89bnVsbCxFPTApe2lmKCFnJiZFPj1yJiYoZz0hMCxvJiYoY29uc29sZS53YXJuKGBNZXNoQlZIOiBNYXggZGVwdGggb2YgJHtyfSByZWFjaGVkIHdoZW4gZ2VuZXJhdGluZyBCVkguIENvbnNpZGVyIGluY3JlYXNpbmcgbWF4RGVwdGguYCksY29uc29sZS53YXJuKGYpKSksUzw9YXx8RT49cilyZXR1cm4gdyhBK1MpLE0ub2Zmc2V0PUEsTS5jb3VudD1TLE07Y29uc3Qgej1oZChNLmJvdW5kaW5nRGF0YSxfLHQsQSxTLGMpO2lmKHouYXhpcz09PS0xKXJldHVybiB3KEErUyksTS5vZmZzZXQ9QSxNLmNvdW50PVMsTTtjb25zdCB2PXAodSxkLHQsQSxTLHopO2lmKHY9PT1BfHx2PT09QStTKXcoQStTKSxNLm9mZnNldD1BLE0uY291bnQ9UztlbHNle00uc3BsaXRBeGlzPXouYXhpcztjb25zdCBDPW5ldyBWbyxQPUEsRj12LUE7TS5sZWZ0PUMsJG8odCxQLEYsQy5ib3VuZGluZ0RhdGEsbSkseChDLFAsRixtLEUrMSk7Y29uc3QgQj1uZXcgVm8sST12LGs9Uy1GO00ucmlnaHQ9Qiwkbyh0LEksayxCLmJvdW5kaW5nRGF0YSxtKSx4KEIsSSxrLG0sRSsxKX1yZXR1cm4gTX19ZnVuY3Rpb24geGQoaSx0KXtjb25zdCBlPWkuZ2VvbWV0cnk7dC5pbmRpcmVjdCYmKGkuX2luZGlyZWN0QnVmZmVyPW1kKGUsdC51c2VTaGFyZWRBcnJheUJ1ZmZlciksYWQoZSx0LnJhbmdlKSYmIXQudmVyYm9zZSYmY29uc29sZS53YXJuKCdNZXNoQlZIOiBQcm92aWRlZCBnZW9tZXRyeSBjb250YWlucyBncm91cHMgb3IgYSByYW5nZSB0aGF0IGRvIG5vdCBmdWxseSBzcGFuIHRoZSB2ZXJ0ZXggY29udGVudHMgd2hpbGUgdXNpbmcgdGhlICJpbmRpcmVjdCIgb3B0aW9uLiBCVkggbWF5IGluY29ycmVjdGx5IHJlcG9ydCBpbnRlcnNlY3Rpb25zIG9uIHVucmVuZGVyZWQgcG9ydGlvbnMgb2YgdGhlIGdlb21ldHJ5LicpKSxpLl9pbmRpcmVjdEJ1ZmZlcnx8b2QoZSx0KTtjb25zdCBuPXQudXNlU2hhcmVkQXJyYXlCdWZmZXI/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1jZChlKSxyPXQuaW5kaXJlY3Q/b2woZSx0LnJhbmdlKTphbChlLHQucmFuZ2UpO2kuX3Jvb3RzPXIubWFwKG89Pntjb25zdCBhPWdkKGkscyxvLm9mZnNldCxvLmNvdW50LHQpLGM9VW8oYSksbD1uZXcgbihQaSpjKTtyZXR1cm4geWQoMCxhLGwpLGx9KX1jbGFzcyBJZXtjb25zdHJ1Y3Rvcigpe3RoaXMubWluPTEvMCx0aGlzLm1heD0tMS8wfXNldEZyb21Qb2ludHNGaWVsZCh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBjPXRbcl1bZV07bj1jPG4/YzpuLHM9Yz5zP2M6c310aGlzLm1pbj1uLHRoaXMubWF4PXN9c2V0RnJvbVBvaW50cyh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl0sYz10LmRvdChhKTtuPWM8bj9jOm4scz1jPnM/YzpzfXRoaXMubWluPW4sdGhpcy5tYXg9c31pc1NlcGFyYXRlZCh0KXtyZXR1cm4gdGhpcy5taW4+dC5tYXh8fHQubWluPnRoaXMubWF4fX1JZS5wcm90b3R5cGUuc2V0RnJvbUJveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Y29uc3Qgcz1uLm1pbixyPW4ubWF4O2xldCBvPTEvMCxhPS0xLzA7Zm9yKGxldCBjPTA7Yzw9MTtjKyspZm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspe2kueD1zLngqYytyLngqKDEtYyksaS55PXMueSpsK3IueSooMS1sKSxpLno9cy56Kmgrci56KigxLWgpO2NvbnN0IHU9ZS5kb3QoaSk7bz1NYXRoLm1pbih1LG8pLGE9TWF0aC5tYXgodSxhKX10aGlzLm1pbj1vLHRoaXMubWF4PWF9fSgpO2NvbnN0IHdkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtjb25zdCBhPXMuc3RhcnQsYz1pLGw9ci5zdGFydCxoPXQ7ZS5zdWJWZWN0b3JzKGEsbCksaS5zdWJWZWN0b3JzKHMuZW5kLHMuc3RhcnQpLHQuc3ViVmVjdG9ycyhyLmVuZCxyLnN0YXJ0KTtjb25zdCB1PWUuZG90KGgpLGY9aC5kb3QoYyksZD1oLmRvdChoKSxwPWUuZG90KGMpLG09Yy5kb3QoYykqZC1mKmY7bGV0IGcsYjttIT09MD9nPSh1KmYtcCpkKS9tOmc9MCxiPSh1K2cqZikvZCxvLng9ZyxvLnk9Yn19KCksSG89ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBSLHQ9bmV3IFQsZT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24ocyxyLG8sYSl7d2QocyxyLGkpO2xldCBjPWkueCxsPWkueTtpZihjPj0wJiZjPD0xJiZsPj0wJiZsPD0xKXtzLmF0KGMsbyksci5hdChsLGEpO3JldHVybn1lbHNlIGlmKGM+PTAmJmM8PTEpe2w8MD9yLmF0KDAsYSk6ci5hdCgxLGEpLHMuY2xvc2VzdFBvaW50VG9Qb2ludChhLCEwLG8pO3JldHVybn1lbHNlIGlmKGw+PTAmJmw8PTEpe2M8MD9zLmF0KDAsbyk6cy5hdCgxLG8pLHIuY2xvc2VzdFBvaW50VG9Qb2ludChvLCEwLGEpO3JldHVybn1lbHNle2xldCBoO2M8MD9oPXMuc3RhcnQ6aD1zLmVuZDtsZXQgdTtsPDA/dT1yLnN0YXJ0OnU9ci5lbmQ7Y29uc3QgZj10LGQ9ZTtpZihzLmNsb3Nlc3RQb2ludFRvUG9pbnQodSwhMCx0KSxyLmNsb3Nlc3RQb2ludFRvUG9pbnQoaCwhMCxlKSxmLmRpc3RhbmNlVG9TcXVhcmVkKHUpPD1kLmRpc3RhbmNlVG9TcXVhcmVkKGgpKXtvLmNvcHkoZiksYS5jb3B5KHUpO3JldHVybn1lbHNle28uY29weShoKSxhLmNvcHkoZCk7cmV0dXJufX19fSgpLGJkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IHpvLG49bmV3IFF0O3JldHVybiBmdW5jdGlvbihyLG8pe2NvbnN0e3JhZGl1czphLGNlbnRlcjpjfT1yLHthOmwsYjpoLGM6dX09bztpZihuLnN0YXJ0PWwsbi5lbmQ9aCxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hfHwobi5zdGFydD1sLG4uZW5kPXUsbi5jbG9zZXN0UG9pbnRUb1BvaW50KGMsITAsaSkuZGlzdGFuY2VUbyhjKTw9YSl8fChuLnN0YXJ0PWgsbi5lbmQ9dSxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hKSlyZXR1cm4hMDtjb25zdCB5PW8uZ2V0UGxhbmUoZSk7aWYoTWF0aC5hYnMoeS5kaXN0YW5jZVRvUG9pbnQoYykpPD1hKXtjb25zdCBnPXkucHJvamVjdFBvaW50KGMsdCk7aWYoby5jb250YWluc1BvaW50KGcpKXJldHVybiEwfXJldHVybiExfX0oKSxNZD0xZS0xNTtmdW5jdGlvbiBXbyhpKXtyZXR1cm4gTWF0aC5hYnMoaSk8TWR9Y2xhc3MgbmUgZXh0ZW5kcyBldHtjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzRXh0ZW5kZWRUcmlhbmdsZT0hMCx0aGlzLnNhdEF4ZXM9bmV3IEFycmF5KDQpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEJvdW5kcz1uZXcgQXJyYXkoNCkuZmlsbCgpLm1hcCgoKT0+bmV3IEllKSx0aGlzLnBvaW50cz1bdGhpcy5hLHRoaXMuYix0aGlzLmNdLHRoaXMuc3BoZXJlPW5ldyBjbyx0aGlzLnBsYW5lPW5ldyB6byx0aGlzLm5lZWRzVXBkYXRlPSEwfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIGJkKHQsdGhpcyl9dXBkYXRlKCl7Y29uc3QgdD10aGlzLmEsZT10aGlzLmIsbj10aGlzLmMscz10aGlzLnBvaW50cyxyPXRoaXMuc2F0QXhlcyxvPXRoaXMuc2F0Qm91bmRzLGE9clswXSxjPW9bMF07dGhpcy5nZXROb3JtYWwoYSksYy5zZXRGcm9tUG9pbnRzKGEscyk7Y29uc3QgbD1yWzFdLGg9b1sxXTtsLnN1YlZlY3RvcnModCxlKSxoLnNldEZyb21Qb2ludHMobCxzKTtjb25zdCB1PXJbMl0sZj1vWzJdO3Uuc3ViVmVjdG9ycyhlLG4pLGYuc2V0RnJvbVBvaW50cyh1LHMpO2NvbnN0IGQ9clszXSxwPW9bM107ZC5zdWJWZWN0b3JzKG4sdCkscC5zZXRGcm9tUG9pbnRzKGQscyksdGhpcy5zcGhlcmUuc2V0RnJvbVBvaW50cyh0aGlzLnBvaW50cyksdGhpcy5wbGFuZS5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChhLHQpLHRoaXMubmVlZHNVcGRhdGU9ITF9fW5lLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRUb1NlZ21lbnQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKHMscj1udWxsLG89bnVsbCl7Y29uc3R7c3RhcnQ6YSxlbmQ6Y309cyxsPXRoaXMucG9pbnRzO2xldCBoLHU9MS8wO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9KGYrMSklMztlLnN0YXJ0LmNvcHkobFtmXSksZS5lbmQuY29weShsW2RdKSxIbyhlLHMsaSx0KSxoPWkuZGlzdGFuY2VUb1NxdWFyZWQodCksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkodCkpfXJldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoYSxpKSxoPWEuZGlzdGFuY2VUb1NxdWFyZWQoaSksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkoYSkpLHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChjLGkpLGg9Yy5kaXN0YW5jZVRvU3F1YXJlZChpKSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weShjKSksTWF0aC5zcXJ0KHUpfX0oKSxuZS5wcm90b3R5cGUuaW50ZXJzZWN0c1RyaWFuZ2xlPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgbmUsdD1uZXcgQXJyYXkoMyksZT1uZXcgQXJyYXkoMyksbj1uZXcgSWUscz1uZXcgSWUscj1uZXcgVCxvPW5ldyBULGE9bmV3IFQsYz1uZXcgVCxsPW5ldyBULGg9bmV3IFF0LHU9bmV3IFF0LGY9bmV3IFF0LGQ9bmV3IFQ7ZnVuY3Rpb24gcCh5LG0sZyl7Y29uc3QgYj15LnBvaW50cztsZXQgdz0wLHg9LTE7Zm9yKGxldCBNPTA7TTwzO00rKyl7Y29uc3R7c3RhcnQ6QSxlbmQ6U309aDtBLmNvcHkoYltNXSksUy5jb3B5KGJbKE0rMSklM10pLGguZGVsdGEobyk7Y29uc3QgXz1XbyhtLmRpc3RhbmNlVG9Qb2ludChBKSk7aWYoV28obS5ub3JtYWwuZG90KG8pKSYmXyl7Zy5jb3B5KGgpLHc9MjticmVha31jb25zdCBFPW0uaW50ZXJzZWN0TGluZShoLGQpO2lmKCFFJiZfJiZkLmNvcHkoQSksKEV8fF8pJiYhV28oZC5kaXN0YW5jZVRvKFMpKSl7aWYodzw9MSkodz09PTE/Zy5zdGFydDpnLmVuZCkuY29weShkKSxfJiYoeD13KTtlbHNlIGlmKHc+PTIpeyh4PT09MT9nLnN0YXJ0OmcuZW5kKS5jb3B5KGQpLHc9MjticmVha31pZih3Kyssdz09PTImJng9PT0tMSlicmVha319cmV0dXJuIHd9cmV0dXJuIGZ1bmN0aW9uKG0sZz1udWxsLGI9ITEpe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksbS5pc0V4dGVuZGVkVHJpYW5nbGU/bS5uZWVkc1VwZGF0ZSYmbS51cGRhdGUoKTooaS5jb3B5KG0pLGkudXBkYXRlKCksbT1pKTtjb25zdCB3PXRoaXMucGxhbmUseD1tLnBsYW5lO2lmKE1hdGguYWJzKHcubm9ybWFsLmRvdCh4Lm5vcm1hbCkpPjEtMWUtMTApe2NvbnN0IE09dGhpcy5zYXRCb3VuZHMsQT10aGlzLnNhdEF4ZXM7ZVswXT1tLmEsZVsxXT1tLmIsZVsyXT1tLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1NW0VdLHY9QVtFXTtpZihuLnNldEZyb21Qb2ludHModixlKSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWNvbnN0IFM9bS5zYXRCb3VuZHMsXz1tLnNhdEF4ZXM7dFswXT10aGlzLmEsdFsxXT10aGlzLmIsdFsyXT10aGlzLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1TW0VdLHY9X1tFXTtpZihuLnNldEZyb21Qb2ludHModix0KSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWZvcihsZXQgRT0wO0U8NDtFKyspe2NvbnN0IHo9QVtFXTtmb3IobGV0IHY9MDt2PDQ7disrKXtjb25zdCBDPV9bdl07aWYoci5jcm9zc1ZlY3RvcnMoeixDKSxuLnNldEZyb21Qb2ludHMocix0KSxzLnNldEZyb21Qb2ludHMocixlKSxuLmlzU2VwYXJhdGVkKHMpKXJldHVybiExfX1yZXR1cm4gZyYmKGJ8fGNvbnNvbGUud2FybigiRXh0ZW5kZWRUcmlhbmdsZS5pbnRlcnNlY3RzVHJpYW5nbGU6IFRyaWFuZ2xlcyBhcmUgY29wbGFuYXIgd2hpY2ggZG9lcyBub3Qgc3VwcG9ydCBhbiBvdXRwdXQgZWRnZS4gU2V0dGluZyBlZGdlIHRvIDAsIDAsIDAuIiksZy5zdGFydC5zZXQoMCwwLDApLGcuZW5kLnNldCgwLDAsMCkpLCEwfWVsc2V7Y29uc3QgTT1wKHRoaXMseCx1KTtpZihNPT09MSYmbS5jb250YWluc1BvaW50KHUuZW5kKSlyZXR1cm4gZyYmKGcuc3RhcnQuY29weSh1LmVuZCksZy5lbmQuY29weSh1LmVuZCkpLCEwO2lmKE0hPT0yKXJldHVybiExO2NvbnN0IEE9cChtLHcsZik7aWYoQT09PTEmJnRoaXMuY29udGFpbnNQb2ludChmLmVuZCkpcmV0dXJuIGcmJihnLnN0YXJ0LmNvcHkoZi5lbmQpLGcuZW5kLmNvcHkoZi5lbmQpKSwhMDtpZihBIT09MilyZXR1cm4hMTtpZih1LmRlbHRhKGEpLGYuZGVsdGEoYyksYS5kb3QoYyk8MCl7bGV0IFA9Zi5zdGFydDtmLnN0YXJ0PWYuZW5kLGYuZW5kPVB9Y29uc3QgUz11LnN0YXJ0LmRvdChhKSxfPXUuZW5kLmRvdChhKSxFPWYuc3RhcnQuZG90KGEpLHo9Zi5lbmQuZG90KGEpLHY9XzxFLEM9Uzx6O3JldHVybiBTIT09eiYmRSE9PV8mJnY9PT1DPyExOihnJiYobC5zdWJWZWN0b3JzKHUuc3RhcnQsZi5zdGFydCksbC5kb3QoYSk+MD9nLnN0YXJ0LmNvcHkodS5zdGFydCk6Zy5zdGFydC5jb3B5KGYuc3RhcnQpLGwuc3ViVmVjdG9ycyh1LmVuZCxmLmVuZCksbC5kb3QoYSk8MD9nLmVuZC5jb3B5KHUuZW5kKTpnLmVuZC5jb3B5KGYuZW5kKSksITApfX19KCksbmUucHJvdG90eXBlLmRpc3RhbmNlVG9Qb2ludD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoZSxpKSxlLmRpc3RhbmNlVG8oaSl9fSgpLG5lLnByb3RvdHlwZS5kaXN0YW5jZVRvVHJpYW5nbGU9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1bImEiLCJiIiwiYyJdLG49bmV3IFF0LHM9bmV3IFF0O3JldHVybiBmdW5jdGlvbihvLGE9bnVsbCxjPW51bGwpe2NvbnN0IGw9YXx8Yz9uOm51bGw7aWYodGhpcy5pbnRlcnNlY3RzVHJpYW5nbGUobyxsKSlyZXR1cm4oYXx8YykmJihhJiZsLmdldENlbnRlcihhKSxjJiZsLmdldENlbnRlcihjKSksMDtsZXQgaD0xLzA7Zm9yKGxldCB1PTA7dTwzO3UrKyl7bGV0IGY7Y29uc3QgZD1lW3VdLHA9b1tkXTt0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocCxpKSxmPXAuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weShpKSxjJiZjLmNvcHkocCkpO2NvbnN0IHk9dGhpc1tkXTtvLmNsb3Nlc3RQb2ludFRvUG9pbnQoeSxpKSxmPXkuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weSh5KSxjJiZjLmNvcHkoaSkpfWZvcihsZXQgdT0wO3U8Mzt1Kyspe2NvbnN0IGY9ZVt1XSxkPWVbKHUrMSklM107bi5zZXQodGhpc1tmXSx0aGlzW2RdKTtmb3IobGV0IHA9MDtwPDM7cCsrKXtjb25zdCB5PWVbcF0sbT1lWyhwKzEpJTNdO3Muc2V0KG9beV0sb1ttXSksSG8obixzLGksdCk7Y29uc3QgZz1pLmRpc3RhbmNlVG9TcXVhcmVkKHQpO2c8aCYmKGg9ZyxhJiZhLmNvcHkoaSksYyYmYy5jb3B5KHQpKX19cmV0dXJuIE1hdGguc3FydChoKX19KCk7Y2xhc3MgenR7Y29uc3RydWN0b3IodCxlLG4pe3RoaXMuaXNPcmllbnRlZEJveD0hMCx0aGlzLm1pbj1uZXcgVCx0aGlzLm1heD1uZXcgVCx0aGlzLm1hdHJpeD1uZXcgc3QsdGhpcy5pbnZNYXRyaXg9bmV3IHN0LHRoaXMucG9pbnRzPW5ldyBBcnJheSg4KS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRBeGVzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRCb3VuZHM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBJZSksdGhpcy5hbGlnbmVkU2F0Qm91bmRzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgSWUpLHRoaXMubmVlZHNVcGRhdGU9ITEsdCYmdGhpcy5taW4uY29weSh0KSxlJiZ0aGlzLm1heC5jb3B5KGUpLG4mJnRoaXMubWF0cml4LmNvcHkobil9c2V0KHQsZSxuKXt0aGlzLm1pbi5jb3B5KHQpLHRoaXMubWF4LmNvcHkoZSksdGhpcy5tYXRyaXguY29weShuKSx0aGlzLm5lZWRzVXBkYXRlPSEwfWNvcHkodCl7dGhpcy5taW4uY29weSh0Lm1pbiksdGhpcy5tYXguY29weSh0Lm1heCksdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5uZWVkc1VwZGF0ZT0hMH19enQucHJvdG90eXBlLnVwZGF0ZT1mdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbigpe2NvbnN0IHQ9dGhpcy5tYXRyaXgsZT10aGlzLm1pbixuPXRoaXMubWF4LHM9dGhpcy5wb2ludHM7Zm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspZm9yKGxldCB1PTA7dTw9MTt1Kyspe2NvbnN0IGY9MSpsfDIqaHw0KnUsZD1zW2ZdO2QueD1sP24ueDplLngsZC55PWg/bi55OmUueSxkLno9dT9uLno6ZS56LGQuYXBwbHlNYXRyaXg0KHQpfWNvbnN0IHI9dGhpcy5zYXRCb3VuZHMsbz10aGlzLnNhdEF4ZXMsYT1zWzBdO2ZvcihsZXQgbD0wO2w8MztsKyspe2NvbnN0IGg9b1tsXSx1PXJbbF0sZj0xPDxsLGQ9c1tmXTtoLnN1YlZlY3RvcnMoYSxkKSx1LnNldEZyb21Qb2ludHMoaCxzKX1jb25zdCBjPXRoaXMuYWxpZ25lZFNhdEJvdW5kcztjWzBdLnNldEZyb21Qb2ludHNGaWVsZChzLCJ4IiksY1sxXS5zZXRGcm9tUG9pbnRzRmllbGQocywieSIpLGNbMl0uc2V0RnJvbVBvaW50c0ZpZWxkKHMsInoiKSx0aGlzLmludk1hdHJpeC5jb3B5KHRoaXMubWF0cml4KS5pbnZlcnQoKSx0aGlzLm5lZWRzVXBkYXRlPSExfX0oKSx6dC5wcm90b3R5cGUuaW50ZXJzZWN0c0JveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IEllO3JldHVybiBmdW5jdGlvbihlKXt0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpO2NvbnN0IG49ZS5taW4scz1lLm1heCxyPXRoaXMuc2F0Qm91bmRzLG89dGhpcy5zYXRBeGVzLGE9dGhpcy5hbGlnbmVkU2F0Qm91bmRzO2lmKGkubWluPW4ueCxpLm1heD1zLngsYVswXS5pc1NlcGFyYXRlZChpKXx8KGkubWluPW4ueSxpLm1heD1zLnksYVsxXS5pc1NlcGFyYXRlZChpKSl8fChpLm1pbj1uLnosaS5tYXg9cy56LGFbMl0uaXNTZXBhcmF0ZWQoaSkpKXJldHVybiExO2ZvcihsZXQgYz0wO2M8MztjKyspe2NvbnN0IGw9b1tjXSxoPXJbY107aWYoaS5zZXRGcm9tQm94KGwsZSksaC5pc1NlcGFyYXRlZChpKSlyZXR1cm4hMX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmludGVyc2VjdHNUcmlhbmdsZT1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IG5lLHQ9bmV3IEFycmF5KDMpLGU9bmV3IEllLG49bmV3IEllLHM9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKG8pe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksby5pc0V4dGVuZGVkVHJpYW5nbGU/by5uZWVkc1VwZGF0ZSYmby51cGRhdGUoKTooaS5jb3B5KG8pLGkudXBkYXRlKCksbz1pKTtjb25zdCBhPXRoaXMuc2F0Qm91bmRzLGM9dGhpcy5zYXRBeGVzO3RbMF09by5hLHRbMV09by5iLHRbMl09by5jO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9YVtmXSxwPWNbZl07aWYoZS5zZXRGcm9tUG9pbnRzKHAsdCksZC5pc1NlcGFyYXRlZChlKSlyZXR1cm4hMX1jb25zdCBsPW8uc2F0Qm91bmRzLGg9by5zYXRBeGVzLHU9dGhpcy5wb2ludHM7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1sW2ZdLHA9aFtmXTtpZihlLnNldEZyb21Qb2ludHMocCx1KSxkLmlzU2VwYXJhdGVkKGUpKXJldHVybiExfWZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9Y1tmXTtmb3IobGV0IHA9MDtwPDQ7cCsrKXtjb25zdCB5PWhbcF07aWYocy5jcm9zc1ZlY3RvcnMoZCx5KSxlLnNldEZyb21Qb2ludHMocyx0KSxuLnNldEZyb21Qb2ludHMocyx1KSxlLmlzU2VwYXJhdGVkKG4pKXJldHVybiExfX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFRvUG9pbnQ9ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxlLmNvcHkodCkuYXBwbHlNYXRyaXg0KHRoaXMuaW52TWF0cml4KS5jbGFtcCh0aGlzLm1pbix0aGlzLm1heCkuYXBwbHlNYXRyaXg0KHRoaXMubWF0cml4KSxlfX0oKSx6dC5wcm90b3R5cGUuZGlzdGFuY2VUb1BvaW50PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChlLGkpLGUuZGlzdGFuY2VUbyhpKX19KCksenQucHJvdG90eXBlLmRpc3RhbmNlVG9Cb3g9ZnVuY3Rpb24oKXtjb25zdCBpPVsieCIsInkiLCJ6Il0sdD1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksZT1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksbj1uZXcgVCxzPW5ldyBUO3JldHVybiBmdW5jdGlvbihvLGE9MCxjPW51bGwsbD1udWxsKXtpZih0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpLHRoaXMuaW50ZXJzZWN0c0JveChvKSlyZXR1cm4oY3x8bCkmJihvLmdldENlbnRlcihzKSx0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocyxuKSxvLmNsb3Nlc3RQb2ludFRvUG9pbnQobixzKSxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpKSwwO2NvbnN0IGg9YSphLHU9by5taW4sZj1vLm1heCxkPXRoaXMucG9pbnRzO2xldCBwPTEvMDtmb3IobGV0IG09MDttPDg7bSsrKXtjb25zdCBnPWRbbV07cy5jb3B5KGcpLmNsYW1wKHUsZik7Y29uc3QgYj1nLmRpc3RhbmNlVG9TcXVhcmVkKHMpO2lmKGI8cCYmKHA9YixjJiZjLmNvcHkoZyksbCYmbC5jb3B5KHMpLGI8aCkpcmV0dXJuIE1hdGguc3FydChiKX1sZXQgeT0wO2ZvcihsZXQgbT0wO208MzttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe2NvbnN0IHc9KG0rMSklMyx4PShtKzIpJTMsTT1nPDx3fGI8PHgsQT0xPDxtfGc8PHd8Yjw8eCxTPWRbTV0sXz1kW0FdO3RbeV0uc2V0KFMsXyk7Y29uc3Qgej1pW21dLHY9aVt3XSxDPWlbeF0sUD1lW3ldLEY9UC5zdGFydCxCPVAuZW5kO0Zbel09dVt6XSxGW3ZdPWc/dVt2XTpmW3ZdLEZbQ109Yj91W0NdOmZbdl0sQlt6XT1mW3pdLEJbdl09Zz91W3ZdOmZbdl0sQltDXT1iP3VbQ106Zlt2XSx5Kyt9Zm9yKGxldCBtPTA7bTw9MTttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe3MueD1tP2YueDp1Lngscy55PWc/Zi55OnUueSxzLno9Yj9mLno6dS56LHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChzLG4pO2NvbnN0IHc9cy5kaXN0YW5jZVRvU3F1YXJlZChuKTtpZih3PHAmJihwPXcsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx3PGgpKXJldHVybiBNYXRoLnNxcnQodyl9Zm9yKGxldCBtPTA7bTwxMjttKyspe2NvbnN0IGc9dFttXTtmb3IobGV0IGI9MDtiPDEyO2IrKyl7Y29uc3Qgdz1lW2JdO0hvKGcsdyxuLHMpO2NvbnN0IHg9bi5kaXN0YW5jZVRvU3F1YXJlZChzKTtpZih4PHAmJihwPXgsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx4PGgpKXJldHVybiBNYXRoLnNxcnQoeCl9fXJldHVybiBNYXRoLnNxcnQocCl9fSgpO2NsYXNzIEdve2NvbnN0cnVjdG9yKHQpe3RoaXMuX2dldE5ld1ByaW1pdGl2ZT10LHRoaXMuX3ByaW1pdGl2ZXM9W119Z2V0UHJpbWl0aXZlKCl7Y29uc3QgdD10aGlzLl9wcmltaXRpdmVzO3JldHVybiB0Lmxlbmd0aD09PTA/dGhpcy5fZ2V0TmV3UHJpbWl0aXZlKCk6dC5wb3AoKX1yZWxlYXNlUHJpbWl0aXZlKHQpe3RoaXMuX3ByaW1pdGl2ZXMucHVzaCh0KX19Y2xhc3MgQWQgZXh0ZW5kcyBHb3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCgpPT5uZXcgbmUpfX1jb25zdCBpZT1uZXcgQWQ7Y2xhc3MgU2R7Y29uc3RydWN0b3IoKXt0aGlzLmZsb2F0MzJBcnJheT1udWxsLHRoaXMudWludDE2QXJyYXk9bnVsbCx0aGlzLnVpbnQzMkFycmF5PW51bGw7Y29uc3QgdD1bXTtsZXQgZT1udWxsO3RoaXMuc2V0QnVmZmVyPW49PntlJiZ0LnB1c2goZSksZT1uLHRoaXMuZmxvYXQzMkFycmF5PW5ldyBGbG9hdDMyQXJyYXkobiksdGhpcy51aW50MTZBcnJheT1uZXcgVWludDE2QXJyYXkobiksdGhpcy51aW50MzJBcnJheT1uZXcgVWludDMyQXJyYXkobil9LHRoaXMuY2xlYXJCdWZmZXI9KCk9PntlPW51bGwsdGhpcy5mbG9hdDMyQXJyYXk9bnVsbCx0aGlzLnVpbnQxNkFycmF5PW51bGwsdGhpcy51aW50MzJBcnJheT1udWxsLHQubGVuZ3RoIT09MCYmdGhpcy5zZXRCdWZmZXIodC5wb3AoKSl9fX1jb25zdCBudD1uZXcgU2Q7bGV0IHRuLFhuO2NvbnN0IEpuPVtdLElzPW5ldyBHbygoKT0+bmV3IGd0KTtmdW5jdGlvbiBfZChpLHQsZSxuLHMscil7dG49SXMuZ2V0UHJpbWl0aXZlKCksWG49SXMuZ2V0UHJpbWl0aXZlKCksSm4ucHVzaCh0bixYbiksbnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPVpvKDAsaS5nZW9tZXRyeSxlLG4scyxyKTtudC5jbGVhckJ1ZmZlcigpLElzLnJlbGVhc2VQcmltaXRpdmUodG4pLElzLnJlbGVhc2VQcmltaXRpdmUoWG4pLEpuLnBvcCgpLEpuLnBvcCgpO2NvbnN0IGE9Sm4ubGVuZ3RoO3JldHVybiBhPjAmJihYbj1KblthLTFdLHRuPUpuW2EtMl0pLG99ZnVuY3Rpb24gWm8oaSx0LGUsbixzPW51bGwscj0wLG89MCl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udDtsZXQgaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1VdChpLGwpLGQ9S3QoaCxjKTtyZXR1cm4gbHQoaSxhLHRuKSxuKGYsZCwhMSxvLHIraSx0bil9ZWxzZXtsZXQgej1mdW5jdGlvbihDKXtjb25zdHt1aW50MTZBcnJheTpQLHVpbnQzMkFycmF5OkZ9PW50O2xldCBCPUMqMjtmb3IoOyFrdChCLFApOylDPXRlKEMpLEI9QyoyO3JldHVybiBVdChDLEYpfSx2PWZ1bmN0aW9uKEMpe2NvbnN0e3VpbnQxNkFycmF5OlAsdWludDMyQXJyYXk6Rn09bnQ7bGV0IEI9QyoyO2Zvcig7IWt0KEIsUCk7KUM9ZWUoQyxGKSxCPUMqMjtyZXR1cm4gVXQoQyxGKStLdChCLFApfTtjb25zdCBmPXRlKGkpLGQ9ZWUoaSxsKTtsZXQgcD1mLHk9ZCxtLGcsYix3O2lmKHMmJihiPXRuLHc9WG4sbHQocCxhLGIpLGx0KHksYSx3KSxtPXMoYiksZz1zKHcpLGc8bSkpe3A9ZCx5PWY7Y29uc3QgQz1tO209ZyxnPUMsYj13fWJ8fChiPXRuLGx0KHAsYSxiKSk7Y29uc3QgeD1rdChwKjIsYyksTT1lKGIseCxtLG8rMSxyK3ApO2xldCBBO2lmKE09PT1zbCl7Y29uc3QgQz16KHApLEY9dihwKS1DO0E9bihDLEYsITAsbysxLHIrcCxiKX1lbHNlIEE9TSYmWm8ocCx0LGUsbixzLHIsbysxKTtpZihBKXJldHVybiEwO3c9WG4sbHQoeSxhLHcpO2NvbnN0IFM9a3QoeSoyLGMpLF89ZSh3LFMsZyxvKzEscit5KTtsZXQgRTtpZihfPT09c2wpe2NvbnN0IEM9eih5KSxGPXYoeSktQztFPW4oQyxGLCEwLG8rMSxyK3ksdyl9ZWxzZSBFPV8mJlpvKHksdCxlLG4scyxyLG8rMSk7cmV0dXJuISFFfX1jb25zdCBGaT1uZXcgVCxYbz1uZXcgVDtmdW5jdGlvbiB2ZChpLHQsZT17fSxuPTAscz0xLzApe2NvbnN0IHI9bipuLG89cypzO2xldCBhPTEvMCxjPW51bGw7aWYoaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6aD0+KEZpLmNvcHkodCkuY2xhbXAoaC5taW4saC5tYXgpLEZpLmRpc3RhbmNlVG9TcXVhcmVkKHQpKSxpbnRlcnNlY3RzQm91bmRzOihoLHUsZik9PmY8YSYmZjxvLGludGVyc2VjdHNUcmlhbmdsZTooaCx1KT0+e2guY2xvc2VzdFBvaW50VG9Qb2ludCh0LEZpKTtjb25zdCBmPXQuZGlzdGFuY2VUb1NxdWFyZWQoRmkpO3JldHVybiBmPGEmJihYby5jb3B5KEZpKSxhPWYsYz11KSxmPHJ9fSksYT09PTEvMClyZXR1cm4gbnVsbDtjb25zdCBsPU1hdGguc3FydChhKTtyZXR1cm4gZS5wb2ludD9lLnBvaW50LmNvcHkoWG8pOmUucG9pbnQ9WG8uY2xvbmUoKSxlLmRpc3RhbmNlPWwsZS5mYWNlSW5kZXg9YyxlfWNvbnN0IHpkPXBhcnNlSW50KEopPj0xNjkseW49bmV3IFQsbW49bmV3IFQsZ249bmV3IFQsa3M9bmV3IFIsTnM9bmV3IFIsUnM9bmV3IFIscGw9bmV3IFQseWw9bmV3IFQsbWw9bmV3IFQsSWk9bmV3IFQ7ZnVuY3Rpb24gVGQoaSx0LGUsbixzLHIsbyxhKXtsZXQgYztpZihyPT09MT9jPWkuaW50ZXJzZWN0VHJpYW5nbGUobixlLHQsITAscyk6Yz1pLmludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHIhPT0yLHMpLGM9PT1udWxsKXJldHVybiBudWxsO2NvbnN0IGw9aS5vcmlnaW4uZGlzdGFuY2VUbyhzKTtyZXR1cm4gbDxvfHxsPmE/bnVsbDp7ZGlzdGFuY2U6bCxwb2ludDpzLmNsb25lKCl9fWZ1bmN0aW9uIEVkKGksdCxlLG4scyxyLG8sYSxjLGwsaCl7eW4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LHIpLG1uLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxvKSxnbi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsYSk7Y29uc3QgdT1UZChpLHluLG1uLGduLElpLGMsbCxoKTtpZih1KXtjb25zdCBmPW5ldyBUO2V0LmdldEJhcnljb29yZChJaSx5bixtbixnbixmKSxuJiYoa3MuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHIpLE5zLmZyb21CdWZmZXJBdHRyaWJ1dGUobixvKSxScy5mcm9tQnVmZmVyQXR0cmlidXRlKG4sYSksdS51dj1ldC5nZXRJbnRlcnBvbGF0aW9uKElpLHluLG1uLGduLGtzLE5zLFJzLG5ldyBSKSkscyYmKGtzLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxyKSxOcy5mcm9tQnVmZmVyQXR0cmlidXRlKHMsbyksUnMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLGEpLHUudXYxPWV0LmdldEludGVycG9sYXRpb24oSWkseW4sbW4sZ24sa3MsTnMsUnMsbmV3IFIpKSxlJiYocGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHIpLHlsLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxvKSxtbC5mcm9tQnVmZmVyQXR0cmlidXRlKGUsYSksdS5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGlvbihJaSx5bixtbixnbixwbCx5bCxtbCxuZXcgVCksdS5ub3JtYWwuZG90KGkuZGlyZWN0aW9uKT4wJiZ1Lm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGQ9e2E6cixiOm8sYzphLG5vcm1hbDpuZXcgVCxtYXRlcmlhbEluZGV4OjB9O2V0LmdldE5vcm1hbCh5bixtbixnbixkLm5vcm1hbCksdS5mYWNlPWQsdS5mYWNlSW5kZXg9cix6ZCYmKHUuYmFyeWNvb3JkPWYpfXJldHVybiB1fWZ1bmN0aW9uIExzKGksdCxlLG4scyxyLG8pe2NvbnN0IGE9biozO2xldCBjPWErMCxsPWErMSxoPWErMjtjb25zdCB1PWkuaW5kZXg7aS5pbmRleCYmKGM9dS5nZXRYKGMpLGw9dS5nZXRYKGwpLGg9dS5nZXRYKGgpKTtjb25zdHtwb3NpdGlvbjpmLG5vcm1hbDpkLHV2OnAsdXYxOnl9PWkuYXR0cmlidXRlcyxtPUVkKGUsZixkLHAseSxjLGwsaCx0LHIsbyk7cmV0dXJuIG0/KG0uZmFjZUluZGV4PW4scyYmcy5wdXNoKG0pLG0pOm51bGx9ZnVuY3Rpb24geXQoaSx0LGUsbil7Y29uc3Qgcz1pLmEscj1pLmIsbz1pLmM7bGV0IGE9dCxjPXQrMSxsPXQrMjtlJiYoYT1lLmdldFgoYSksYz1lLmdldFgoYyksbD1lLmdldFgobCkpLHMueD1uLmdldFgoYSkscy55PW4uZ2V0WShhKSxzLno9bi5nZXRaKGEpLHIueD1uLmdldFgoYyksci55PW4uZ2V0WShjKSxyLno9bi5nZXRaKGMpLG8ueD1uLmdldFgobCksby55PW4uZ2V0WShsKSxvLno9bi5nZXRaKGwpfWZ1bmN0aW9uIFBkKGksdCxlLG4scyxyLG8sYSl7Y29uc3R7Z2VvbWV0cnk6YyxfaW5kaXJlY3RCdWZmZXI6bH09aTtmb3IobGV0IGg9bix1PW4rcztoPHU7aCsrKUxzKGMsdCxlLGgscixvLGEpfWZ1bmN0aW9uIENkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmEsX2luZGlyZWN0QnVmZmVyOmN9PWk7bGV0IGw9MS8wLGg9bnVsbDtmb3IobGV0IHU9bixmPW4rczt1PGY7dSsrKXtsZXQgZDtkPUxzKGEsdCxlLHUsbnVsbCxyLG8pLGQmJmQuZGlzdGFuY2U8bCYmKGg9ZCxsPWQuZGlzdGFuY2UpfXJldHVybiBofWZ1bmN0aW9uIEJkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmF9PWUse2luZGV4OmN9PWEsbD1hLmF0dHJpYnV0ZXMucG9zaXRpb247Zm9yKGxldCBoPWksdT10K2k7aDx1O2grKyl7bGV0IGY7aWYoZj1oLHl0KG8sZiozLGMsbCksby5uZWVkc1VwZGF0ZT0hMCxuKG8sZixzLHIpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIEZkKGksdD1udWxsKXt0JiZBcnJheS5pc0FycmF5KHQpJiYodD1uZXcgU2V0KHQpKTtjb25zdCBlPWkuZ2VvbWV0cnksbj1lLmluZGV4P2UuaW5kZXguYXJyYXk6bnVsbCxzPWUuYXR0cmlidXRlcy5wb3NpdGlvbjtsZXQgcixvLGEsYyxsPTA7Y29uc3QgaD1pLl9yb290cztmb3IobGV0IGY9MCxkPWgubGVuZ3RoO2Y8ZDtmKyspcj1oW2ZdLG89bmV3IFVpbnQzMkFycmF5KHIpLGE9bmV3IFVpbnQxNkFycmF5KHIpLGM9bmV3IEZsb2F0MzJBcnJheShyKSx1KDAsbCksbCs9ci5ieXRlTGVuZ3RoO2Z1bmN0aW9uIHUoZixkLHA9ITEpe2NvbnN0IHk9ZioyO2lmKGFbeSsxNV09PT1Qcyl7Y29uc3QgZz1vW2YrNl0sYj1hW3krMTRdO2xldCB3PTEvMCx4PTEvMCxNPTEvMCxBPS0xLzAsUz0tMS8wLF89LTEvMDtmb3IobGV0IEU9MypnLHo9MyooZytiKTtFPHo7RSsrKXtsZXQgdj1uW0VdO2NvbnN0IEM9cy5nZXRYKHYpLFA9cy5nZXRZKHYpLEY9cy5nZXRaKHYpO0M8dyYmKHc9QyksQz5BJiYoQT1DKSxQPHgmJih4PVApLFA+UyYmKFM9UCksRjxNJiYoTT1GKSxGPl8mJihfPUYpfXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1TfHxjW2YrNV0hPT1fPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09UyxjW2YrNV09XywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsUz0hMTt0P018fChBPXQuaGFzKHcpLFM9dC5oYXMoeCksTT0hQSYmIVMpOihBPSEwLFM9ITApO2NvbnN0IF89TXx8QSxFPU18fFM7bGV0IHo9ITE7XyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFU9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+VT9rOlV9cmV0dXJuIEN9fX1mdW5jdGlvbiBlbihpLHQsZSxuLHMpe2xldCByLG8sYSxjLGwsaDtjb25zdCB1PTEvZS5kaXJlY3Rpb24ueCxmPTEvZS5kaXJlY3Rpb24ueSxkPTEvZS5kaXJlY3Rpb24ueixwPWUub3JpZ2luLngseT1lLm9yaWdpbi55LG09ZS5vcmlnaW4uejtsZXQgZz10W2ldLGI9dFtpKzNdLHc9dFtpKzFdLHg9dFtpKzMrMV0sTT10W2krMl0sQT10W2krMysyXTtyZXR1cm4gdT49MD8ocj0oZy1wKSp1LG89KGItcCkqdSk6KHI9KGItcCkqdSxvPShnLXApKnUpLGY+PTA/KGE9KHcteSkqZixjPSh4LXkpKmYpOihhPSh4LXkpKmYsYz0ody15KSpmKSxyPmN8fGE+b3x8KChhPnJ8fGlzTmFOKHIpKSYmKHI9YSksKGM8b3x8aXNOYU4obykpJiYobz1jKSxkPj0wPyhsPShNLW0pKmQsaD0oQS1tKSpkKToobD0oQS1tKSpkLGg9KE0tbSkqZCkscj5ofHxsPm8pPyExOigobD5yfHxyIT09cikmJihyPWwpLChoPG98fG8hPT1vKSYmKG89aCkscjw9cyYmbz49bil9ZnVuY3Rpb24gSWQoaSx0LGUsbixzLHIsbyxhKXtjb25zdHtnZW9tZXRyeTpjLF9pbmRpcmVjdEJ1ZmZlcjpsfT1pO2ZvcihsZXQgaD1uLHU9bitzO2g8dTtoKyspe2xldCBmPWw/bFtoXTpoO0xzKGMsdCxlLGYscixvLGEpfX1mdW5jdGlvbiBrZChpLHQsZSxuLHMscixvKXtjb25zdHtnZW9tZXRyeTphLF9pbmRpcmVjdEJ1ZmZlcjpjfT1pO2xldCBsPTEvMCxoPW51bGw7Zm9yKGxldCB1PW4sZj1uK3M7dTxmO3UrKyl7bGV0IGQ7ZD1McyhhLHQsZSxjP2NbdV06dSxudWxsLHIsbyksZCYmZC5kaXN0YW5jZTxsJiYoaD1kLGw9ZC5kaXN0YW5jZSl9cmV0dXJuIGh9ZnVuY3Rpb24gTmQoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YX09ZSx7aW5kZXg6Y309YSxsPWEuYXR0cmlidXRlcy5wb3NpdGlvbjtmb3IobGV0IGg9aSx1PXQraTtoPHU7aCsrKXtsZXQgZjtpZihmPWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoaCkseXQobyxmKjMsYyxsKSxvLm5lZWRzVXBkYXRlPSEwLG4obyxmLHMscikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gUmQoaSx0LGUsbixzLHIsbyl7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKSxKbygwLGksZSxuLHMscixvKSxudC5jbGVhckJ1ZmZlcigpfWZ1bmN0aW9uIEpvKGksdCxlLG4scyxyLG8pe2NvbnN0e2Zsb2F0MzJBcnJheTphLHVpbnQxNkFycmF5OmMsdWludDMyQXJyYXk6bH09bnQsaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1VdChpLGwpLGQ9S3QoaCxjKTtQZCh0LGUsbixmLGQscyxyLG8pfWVsc2V7Y29uc3QgZj10ZShpKTtlbihmLGEsbixyLG8pJiZKbyhmLHQsZSxuLHMscixvKTtjb25zdCBkPWVlKGksbCk7ZW4oZCxhLG4scixvKSYmSm8oZCx0LGUsbixzLHIsbyl9fWNvbnN0IExkPVsieCIsInkiLCJ6Il07ZnVuY3Rpb24gT2QoaSx0LGUsbixzLHIpe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSk7Y29uc3Qgbz1ZbygwLGksZSxuLHMscik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksb31mdW5jdGlvbiBZbyhpLHQsZSxuLHMscil7Y29uc3R7ZmxvYXQzMkFycmF5Om8sdWludDE2QXJyYXk6YSx1aW50MzJBcnJheTpjfT1udDtsZXQgbD1pKjI7aWYoa3QobCxhKSl7Y29uc3QgdT1VdChpLGMpLGY9S3QobCxhKTtyZXR1cm4gQ2QodCxlLG4sdSxmLHMscil9ZWxzZXtjb25zdCB1PXVsKGksYyksZj1MZFt1XSxwPW4uZGlyZWN0aW9uW2ZdPj0wO2xldCB5LG07cD8oeT10ZShpKSxtPWVlKGksYykpOih5PWVlKGksYyksbT10ZShpKSk7Y29uc3QgYj1lbih5LG8sbixzLHIpP1lvKHksdCxlLG4scyxyKTpudWxsO2lmKGIpe2NvbnN0IE09Yi5wb2ludFtmXTtpZihwP008PW9bbSt1XTpNPj1vW20rdSszXSlyZXR1cm4gYn1jb25zdCB4PWVuKG0sbyxuLHMscik/WW8obSx0LGUsbixzLHIpOm51bGw7cmV0dXJuIGImJng/Yi5kaXN0YW5jZTw9eC5kaXN0YW5jZT9iOng6Ynx8eHx8bnVsbH19Y29uc3QgT3M9bmV3IGd0LFluPW5ldyBuZSxqbj1uZXcgbmUsa2k9bmV3IHN0LGdsPW5ldyB6dCxEcz1uZXcgenQ7ZnVuY3Rpb24gRGQoaSx0LGUsbil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBzPWpvKDAsaSxlLG4pO3JldHVybiBudC5jbGVhckJ1ZmZlcigpLHN9ZnVuY3Rpb24gam8oaSx0LGUsbixzPW51bGwpe2NvbnN0e2Zsb2F0MzJBcnJheTpyLHVpbnQxNkFycmF5Om8sdWludDMyQXJyYXk6YX09bnQ7bGV0IGM9aSoyO2lmKHM9PT1udWxsJiYoZS5ib3VuZGluZ0JveHx8ZS5jb21wdXRlQm91bmRpbmdCb3goKSxnbC5zZXQoZS5ib3VuZGluZ0JveC5taW4sZS5ib3VuZGluZ0JveC5tYXgsbikscz1nbCksa3QoYyxvKSl7Y29uc3QgaD10Lmdlb21ldHJ5LHU9aC5pbmRleCxmPWguYXR0cmlidXRlcy5wb3NpdGlvbixkPWUuaW5kZXgscD1lLmF0dHJpYnV0ZXMucG9zaXRpb24seT1VdChpLGEpLG09S3QoYyxvKTtpZihraS5jb3B5KG4pLmludmVydCgpLGUuYm91bmRzVHJlZSlyZXR1cm4gbHQoaSxyLERzKSxEcy5tYXRyaXguY29weShraSksRHMubmVlZHNVcGRhdGU9ITAsZS5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpiPT5Ecy5pbnRlcnNlY3RzQm94KGIpLGludGVyc2VjdHNUcmlhbmdsZTpiPT57Yi5hLmFwcGx5TWF0cml4NChuKSxiLmIuYXBwbHlNYXRyaXg0KG4pLGIuYy5hcHBseU1hdHJpeDQobiksYi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHc9eSozLHg9KG0reSkqMzt3PHg7dys9MylpZih5dChqbix3LHUsZiksam4ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoam4pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15KjMsYj0obSt5KSozO2c8YjtnKz0zKXt5dChZbixnLHUsZiksWW4uYS5hcHBseU1hdHJpeDQoa2kpLFluLmIuYXBwbHlNYXRyaXg0KGtpKSxZbi5jLmFwcGx5TWF0cml4NChraSksWW4ubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB3PTAseD1kLmNvdW50O3c8eDt3Kz0zKWlmKHl0KGpuLHcsZCxwKSxqbi5uZWVkc1VwZGF0ZT0hMCxZbi5pbnRlcnNlY3RzVHJpYW5nbGUoam4pKXJldHVybiEwfX1lbHNle2NvbnN0IGg9aSs4LHU9YVtpKzZdO3JldHVybiBsdChoLHIsT3MpLCEhKHMuaW50ZXJzZWN0c0JveChPcykmJmpvKGgsdCxlLG4scyl8fChsdCh1LHIsT3MpLHMuaW50ZXJzZWN0c0JveChPcykmJmpvKHUsdCxlLG4scykpKX19Y29uc3QgJHM9bmV3IHN0LFFvPW5ldyB6dCxOaT1uZXcgenQsJGQ9bmV3IFQsVmQ9bmV3IFQsVWQ9bmV3IFQscWQ9bmV3IFQ7ZnVuY3Rpb24gSGQoaSx0LGUsbj17fSxzPXt9LHI9MCxvPTEvMCl7dC5ib3VuZGluZ0JveHx8dC5jb21wdXRlQm91bmRpbmdCb3goKSxRby5zZXQodC5ib3VuZGluZ0JveC5taW4sdC5ib3VuZGluZ0JveC5tYXgsZSksUW8ubmVlZHNVcGRhdGU9ITA7Y29uc3QgYT1pLmdlb21ldHJ5LGM9YS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9YS5pbmRleCxoPXQuYXR0cmlidXRlcy5wb3NpdGlvbix1PXQuaW5kZXgsZj1pZS5nZXRQcmltaXRpdmUoKSxkPWllLmdldFByaW1pdGl2ZSgpO2xldCBwPSRkLHk9VmQsbT1udWxsLGc9bnVsbDtzJiYobT1VZCxnPXFkKTtsZXQgYj0xLzAsdz1udWxsLHg9bnVsbDtyZXR1cm4gJHMuY29weShlKS5pbnZlcnQoKSxOaS5tYXRyaXguY29weSgkcyksaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6TT0+UW8uZGlzdGFuY2VUb0JveChNKSxpbnRlcnNlY3RzQm91bmRzOihNLEEsUyk9PlM8YiYmUzxvPyhBJiYoTmkubWluLmNvcHkoTS5taW4pLE5pLm1heC5jb3B5KE0ubWF4KSxOaS5uZWVkc1VwZGF0ZT0hMCksITApOiExLGludGVyc2VjdHNSYW5nZTooTSxBKT0+e2lmKHQuYm91bmRzVHJlZSlyZXR1cm4gdC5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpfPT5OaS5kaXN0YW5jZVRvQm94KF8pLGludGVyc2VjdHNCb3VuZHM6KF8sRSx6KT0+ejxiJiZ6PG8saW50ZXJzZWN0c1JhbmdlOihfLEUpPT57Zm9yKGxldCB6PV8sdj1fK0U7ejx2O3orKyl7eXQoZCwzKnosdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgQz1NLFA9TStBO0M8UDtDKyspe3l0KGYsMypDLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBGPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihGPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Rix3PUMseD16KSxGPHIpcmV0dXJuITB9fX19KTt7Y29uc3QgUz1abih0KTtmb3IobGV0IF89MCxFPVM7XzxFO18rKyl7eXQoZCwzKl8sdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgej1NLHY9TStBO3o8djt6Kyspe3l0KGYsMyp6LGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBDPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihDPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Qyx3PXoseD1fKSxDPHIpcmV0dXJuITB9fX19fSksaWUucmVsZWFzZVByaW1pdGl2ZShmKSxpZS5yZWxlYXNlUHJpbWl0aXZlKGQpLGI9PT0xLzA/bnVsbDoobi5wb2ludD9uLnBvaW50LmNvcHkoeSk6bi5wb2ludD15LmNsb25lKCksbi5kaXN0YW5jZT1iLG4uZmFjZUluZGV4PXcscyYmKHMucG9pbnQ/cy5wb2ludC5jb3B5KGcpOnMucG9pbnQ9Zy5jbG9uZSgpLHMucG9pbnQuYXBwbHlNYXRyaXg0KCRzKSx5LmFwcGx5TWF0cml4NCgkcykscy5kaXN0YW5jZT15LnN1YihzLnBvaW50KS5sZW5ndGgoKSxzLmZhY2VJbmRleD14KSxuKX1mdW5jdGlvbiBXZChpLHQ9bnVsbCl7dCYmQXJyYXkuaXNBcnJheSh0KSYmKHQ9bmV3IFNldCh0KSk7Y29uc3QgZT1pLmdlb21ldHJ5LG49ZS5pbmRleD9lLmluZGV4LmFycmF5Om51bGwscz1lLmF0dHJpYnV0ZXMucG9zaXRpb247bGV0IHIsbyxhLGMsbD0wO2NvbnN0IGg9aS5fcm9vdHM7Zm9yKGxldCBmPTAsZD1oLmxlbmd0aDtmPGQ7ZisrKXI9aFtmXSxvPW5ldyBVaW50MzJBcnJheShyKSxhPW5ldyBVaW50MTZBcnJheShyKSxjPW5ldyBGbG9hdDMyQXJyYXkociksdSgwLGwpLGwrPXIuYnl0ZUxlbmd0aDtmdW5jdGlvbiB1KGYsZCxwPSExKXtjb25zdCB5PWYqMjtpZihhW3krMTVdPT09UHMpe2NvbnN0IGc9b1tmKzZdLGI9YVt5KzE0XTtsZXQgdz0xLzAseD0xLzAsTT0xLzAsQT0tMS8wLFM9LTEvMCxfPS0xLzA7Zm9yKGxldCBFPWcsej1nK2I7RTx6O0UrKyl7Y29uc3Qgdj0zKmkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoRSk7Zm9yKGxldCBDPTA7QzwzO0MrKyl7bGV0IFA9ditDO1A9bj9uW1BdOlA7Y29uc3QgRj1zLmdldFgoUCksQj1zLmdldFkoUCksST1zLmdldFooUCk7Rjx3JiYodz1GKSxGPkEmJihBPUYpLEI8eCYmKHg9QiksQj5TJiYoUz1CKSxJPE0mJihNPUkpLEk+XyYmKF89SSl9fXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1TfHxjW2YrNV0hPT1fPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09UyxjW2YrNV09XywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsUz0hMTt0P018fChBPXQuaGFzKHcpLFM9dC5oYXMoeCksTT0hQSYmIVMpOihBPSEwLFM9ITApO2NvbnN0IF89TXx8QSxFPU18fFM7bGV0IHo9ITE7XyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFU9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+VT9rOlV9cmV0dXJuIEN9fX1mdW5jdGlvbiBHZChpLHQsZSxuLHMscixvKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pLEtvKDAsaSxlLG4scyxyLG8pLG50LmNsZWFyQnVmZmVyKCl9ZnVuY3Rpb24gS28oaSx0LGUsbixzLHIsbyl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udCxoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVV0KGksbCksZD1LdChoLGMpO0lkKHQsZSxuLGYsZCxzLHIsbyl9ZWxzZXtjb25zdCBmPXRlKGkpO2VuKGYsYSxuLHIsbykmJktvKGYsdCxlLG4scyxyLG8pO2NvbnN0IGQ9ZWUoaSxsKTtlbihkLGEsbixyLG8pJiZLbyhkLHQsZSxuLHMscixvKX19Y29uc3QgWmQ9WyJ4IiwieSIsInoiXTtmdW5jdGlvbiBYZChpLHQsZSxuLHMscil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPXRhKDAsaSxlLG4scyxyKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxvfWZ1bmN0aW9uIHRhKGksdCxlLG4scyxyKXtjb25zdHtmbG9hdDMyQXJyYXk6byx1aW50MTZBcnJheTphLHVpbnQzMkFycmF5OmN9PW50O2xldCBsPWkqMjtpZihrdChsLGEpKXtjb25zdCB1PVV0KGksYyksZj1LdChsLGEpO3JldHVybiBrZCh0LGUsbix1LGYscyxyKX1lbHNle2NvbnN0IHU9dWwoaSxjKSxmPVpkW3VdLHA9bi5kaXJlY3Rpb25bZl0+PTA7bGV0IHksbTtwPyh5PXRlKGkpLG09ZWUoaSxjKSk6KHk9ZWUoaSxjKSxtPXRlKGkpKTtjb25zdCBiPWVuKHksbyxuLHMscik/dGEoeSx0LGUsbixzLHIpOm51bGw7aWYoYil7Y29uc3QgTT1iLnBvaW50W2ZdO2lmKHA/TTw9b1ttK3VdOk0+PW9bbSt1KzNdKXJldHVybiBifWNvbnN0IHg9ZW4obSxvLG4scyxyKT90YShtLHQsZSxuLHMscik6bnVsbDtyZXR1cm4gYiYmeD9iLmRpc3RhbmNlPD14LmRpc3RhbmNlP2I6eDpifHx4fHxudWxsfX1jb25zdCBWcz1uZXcgZ3QsUW49bmV3IG5lLEtuPW5ldyBuZSxSaT1uZXcgc3QseGw9bmV3IHp0LFVzPW5ldyB6dDtmdW5jdGlvbiBKZChpLHQsZSxuKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IHM9ZWEoMCxpLGUsbik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksc31mdW5jdGlvbiBlYShpLHQsZSxuLHM9bnVsbCl7Y29uc3R7ZmxvYXQzMkFycmF5OnIsdWludDE2QXJyYXk6byx1aW50MzJBcnJheTphfT1udDtsZXQgYz1pKjI7aWYocz09PW51bGwmJihlLmJvdW5kaW5nQm94fHxlLmNvbXB1dGVCb3VuZGluZ0JveCgpLHhsLnNldChlLmJvdW5kaW5nQm94Lm1pbixlLmJvdW5kaW5nQm94Lm1heCxuKSxzPXhsKSxrdChjLG8pKXtjb25zdCBoPXQuZ2VvbWV0cnksdT1oLmluZGV4LGY9aC5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9ZS5pbmRleCxwPWUuYXR0cmlidXRlcy5wb3NpdGlvbix5PVV0KGksYSksbT1LdChjLG8pO2lmKFJpLmNvcHkobikuaW52ZXJ0KCksZS5ib3VuZHNUcmVlKXJldHVybiBsdChpLHIsVXMpLFVzLm1hdHJpeC5jb3B5KFJpKSxVcy5uZWVkc1VwZGF0ZT0hMCxlLmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmI9PlVzLmludGVyc2VjdHNCb3goYiksaW50ZXJzZWN0c1RyaWFuZ2xlOmI9PntiLmEuYXBwbHlNYXRyaXg0KG4pLGIuYi5hcHBseU1hdHJpeDQobiksYi5jLmFwcGx5TWF0cml4NChuKSxiLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgdz15LHg9bSt5O3c8eDt3KyspaWYoeXQoS24sMyp0LnJlc29sdmVUcmlhbmdsZUluZGV4KHcpLHUsZiksS24ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoS24pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15LGI9bSt5O2c8YjtnKyspe2NvbnN0IHc9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChnKTt5dChRbiwzKncsdSxmKSxRbi5hLmFwcGx5TWF0cml4NChSaSksUW4uYi5hcHBseU1hdHJpeDQoUmkpLFFuLmMuYXBwbHlNYXRyaXg0KFJpKSxRbi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHg9MCxNPWQuY291bnQ7eDxNO3grPTMpaWYoeXQoS24seCxkLHApLEtuLm5lZWRzVXBkYXRlPSEwLFFuLmludGVyc2VjdHNUcmlhbmdsZShLbikpcmV0dXJuITB9fWVsc2V7Y29uc3QgaD1pKzgsdT1hW2krNl07cmV0dXJuIGx0KGgscixWcyksISEocy5pbnRlcnNlY3RzQm94KFZzKSYmZWEoaCx0LGUsbixzKXx8KGx0KHUscixWcykscy5pbnRlcnNlY3RzQm94KFZzKSYmZWEodSx0LGUsbixzKSkpfX1jb25zdCBxcz1uZXcgc3QsbmE9bmV3IHp0LExpPW5ldyB6dCxZZD1uZXcgVCxqZD1uZXcgVCxRZD1uZXcgVCxLZD1uZXcgVDtmdW5jdGlvbiB0MChpLHQsZSxuPXt9LHM9e30scj0wLG89MS8wKXt0LmJvdW5kaW5nQm94fHx0LmNvbXB1dGVCb3VuZGluZ0JveCgpLG5hLnNldCh0LmJvdW5kaW5nQm94Lm1pbix0LmJvdW5kaW5nQm94Lm1heCxlKSxuYS5uZWVkc1VwZGF0ZT0hMDtjb25zdCBhPWkuZ2VvbWV0cnksYz1hLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1hLmluZGV4LGg9dC5hdHRyaWJ1dGVzLnBvc2l0aW9uLHU9dC5pbmRleCxmPWllLmdldFByaW1pdGl2ZSgpLGQ9aWUuZ2V0UHJpbWl0aXZlKCk7bGV0IHA9WWQseT1qZCxtPW51bGwsZz1udWxsO3MmJihtPVFkLGc9S2QpO2xldCBiPTEvMCx3PW51bGwseD1udWxsO3JldHVybiBxcy5jb3B5KGUpLmludmVydCgpLExpLm1hdHJpeC5jb3B5KHFzKSxpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpNPT5uYS5kaXN0YW5jZVRvQm94KE0pLGludGVyc2VjdHNCb3VuZHM6KE0sQSxTKT0+UzxiJiZTPG8/KEEmJihMaS5taW4uY29weShNLm1pbiksTGkubWF4LmNvcHkoTS5tYXgpLExpLm5lZWRzVXBkYXRlPSEwKSwhMCk6ITEsaW50ZXJzZWN0c1JhbmdlOihNLEEpPT57aWYodC5ib3VuZHNUcmVlKXtjb25zdCBTPXQuYm91bmRzVHJlZTtyZXR1cm4gUy5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6Xz0+TGkuZGlzdGFuY2VUb0JveChfKSxpbnRlcnNlY3RzQm91bmRzOihfLEUseik9Pno8YiYmejxvLGludGVyc2VjdHNSYW5nZTooXyxFKT0+e2ZvcihsZXQgej1fLHY9XytFO3o8djt6Kyspe2NvbnN0IEM9Uy5yZXNvbHZlVHJpYW5nbGVJbmRleCh6KTt5dChkLDMqQyx1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCBQPU0sRj1NK0E7UDxGO1ArKyl7Y29uc3QgQj1pLnJlc29sdmVUcmlhbmdsZUluZGV4KFApO3l0KGYsMypCLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBJPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihJPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9SSx3PVAseD16KSxJPHIpcmV0dXJuITB9fX19KX1lbHNle2NvbnN0IFM9Wm4odCk7Zm9yKGxldCBfPTAsRT1TO188RTtfKyspe3l0KGQsMypfLHUsaCksZC5hLmFwcGx5TWF0cml4NChlKSxkLmIuYXBwbHlNYXRyaXg0KGUpLGQuYy5hcHBseU1hdHJpeDQoZSksZC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHo9TSx2PU0rQTt6PHY7eisrKXtjb25zdCBDPWkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoeik7eXQoZiwzKkMsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IFA9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKFA8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1QLHc9eix4PV8pLFA8cilyZXR1cm4hMH19fX19KSxpZS5yZWxlYXNlUHJpbWl0aXZlKGYpLGllLnJlbGVhc2VQcmltaXRpdmUoZCksYj09PTEvMD9udWxsOihuLnBvaW50P24ucG9pbnQuY29weSh5KTpuLnBvaW50PXkuY2xvbmUoKSxuLmRpc3RhbmNlPWIsbi5mYWNlSW5kZXg9dyxzJiYocy5wb2ludD9zLnBvaW50LmNvcHkoZyk6cy5wb2ludD1nLmNsb25lKCkscy5wb2ludC5hcHBseU1hdHJpeDQocXMpLHkuYXBwbHlNYXRyaXg0KHFzKSxzLmRpc3RhbmNlPXkuc3ViKHMucG9pbnQpLmxlbmd0aCgpLHMuZmFjZUluZGV4PXgpLG4pfWZ1bmN0aW9uIGUwKCl7cmV0dXJuIHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciE9InVuZGVmaW5lZCJ9Y29uc3QgT2k9bmV3IG50LmNvbnN0cnVjdG9yLEhzPW5ldyBudC5jb25zdHJ1Y3Rvcixubj1uZXcgR28oKCk9Pm5ldyBndCksdGk9bmV3IGd0LGVpPW5ldyBndCxpYT1uZXcgZ3Qsc2E9bmV3IGd0O2xldCByYT0hMTtmdW5jdGlvbiBuMChpLHQsZSxuKXtpZihyYSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IFJlY3Vyc2l2ZSBjYWxscyB0byBidmhjYXN0IG5vdCBzdXBwb3J0ZWQuIik7cmE9ITA7Y29uc3Qgcz1pLl9yb290cyxyPXQuX3Jvb3RzO2xldCBvLGE9MCxjPTA7Y29uc3QgbD1uZXcgc3QoKS5jb3B5KGUpLmludmVydCgpO2ZvcihsZXQgaD0wLHU9cy5sZW5ndGg7aDx1O2grKyl7T2kuc2V0QnVmZmVyKHNbaF0pLGM9MDtjb25zdCBmPW5uLmdldFByaW1pdGl2ZSgpO2x0KDAsT2kuZmxvYXQzMkFycmF5LGYpLGYuYXBwbHlNYXRyaXg0KGwpO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwJiYoSHMuc2V0QnVmZmVyKHJbZF0pLG89ZmUoMCwwLGUsbCxuLGEsYywwLDAsZiksSHMuY2xlYXJCdWZmZXIoKSxjKz1yW2RdLmxlbmd0aCwhbyk7ZCsrKTtpZihubi5yZWxlYXNlUHJpbWl0aXZlKGYpLE9pLmNsZWFyQnVmZmVyKCksYSs9c1toXS5sZW5ndGgsbylicmVha31yZXR1cm4gcmE9ITEsb31mdW5jdGlvbiBmZShpLHQsZSxuLHMscj0wLG89MCxhPTAsYz0wLGw9bnVsbCxoPSExKXtsZXQgdSxmO2g/KHU9SHMsZj1PaSk6KHU9T2ksZj1Icyk7Y29uc3QgZD11LmZsb2F0MzJBcnJheSxwPXUudWludDMyQXJyYXkseT11LnVpbnQxNkFycmF5LG09Zi5mbG9hdDMyQXJyYXksZz1mLnVpbnQzMkFycmF5LGI9Zi51aW50MTZBcnJheSx3PWkqMix4PXQqMixNPWt0KHcseSksQT1rdCh4LGIpO2xldCBTPSExO2lmKEEmJk0paD9TPXMoVXQodCxnKSxLdCh0KjIsYiksVXQoaSxwKSxLdChpKjIseSksYyxvK3QsYSxyK2kpOlM9cyhVdChpLHApLEt0KGkqMix5KSxVdCh0LGcpLEt0KHQqMixiKSxhLHIraSxjLG8rdCk7ZWxzZSBpZihBKXtjb25zdCBfPW5uLmdldFByaW1pdGl2ZSgpO2x0KHQsbSxfKSxfLmFwcGx5TWF0cml4NChlKTtjb25zdCBFPXRlKGkpLHo9ZWUoaSxwKTtsdChFLGQsdGkpLGx0KHosZCxlaSk7Y29uc3Qgdj1fLmludGVyc2VjdHNCb3godGkpLEM9Xy5pbnRlcnNlY3RzQm94KGVpKTtTPXYmJmZlKHQsRSxuLGUscyxvLHIsYyxhKzEsXywhaCl8fEMmJmZlKHQseixuLGUscyxvLHIsYyxhKzEsXywhaCksbm4ucmVsZWFzZVByaW1pdGl2ZShfKX1lbHNle2NvbnN0IF89dGUodCksRT1lZSh0LGcpO2x0KF8sbSxpYSksbHQoRSxtLHNhKTtjb25zdCB6PWwuaW50ZXJzZWN0c0JveChpYSksdj1sLmludGVyc2VjdHNCb3goc2EpO2lmKHomJnYpUz1mZShpLF8sZSxuLHMscixvLGEsYysxLGwsaCl8fGZlKGksRSxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNlIGlmKHopaWYoTSlTPWZlKGksXyxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNle2NvbnN0IEM9bm4uZ2V0UHJpbWl0aXZlKCk7Qy5jb3B5KGlhKS5hcHBseU1hdHJpeDQoZSk7Y29uc3QgUD10ZShpKSxGPWVlKGkscCk7bHQoUCxkLHRpKSxsdChGLGQsZWkpO2NvbnN0IEI9Qy5pbnRlcnNlY3RzQm94KHRpKSxJPUMuaW50ZXJzZWN0c0JveChlaSk7Uz1CJiZmZShfLFAsbixlLHMsbyxyLGMsYSsxLEMsIWgpfHxJJiZmZShfLEYsbixlLHMsbyxyLGMsYSsxLEMsIWgpLG5uLnJlbGVhc2VQcmltaXRpdmUoQyl9ZWxzZSBpZih2KWlmKE0pUz1mZShpLEUsZSxuLHMscixvLGEsYysxLGwsaCk7ZWxzZXtjb25zdCBDPW5uLmdldFByaW1pdGl2ZSgpO0MuY29weShzYSkuYXBwbHlNYXRyaXg0KGUpO2NvbnN0IFA9dGUoaSksRj1lZShpLHApO2x0KFAsZCx0aSksbHQoRixkLGVpKTtjb25zdCBCPUMuaW50ZXJzZWN0c0JveCh0aSksST1DLmludGVyc2VjdHNCb3goZWkpO1M9QiYmZmUoRSxQLG4sZSxzLG8scixjLGErMSxDLCFoKXx8SSYmZmUoRSxGLG4sZSxzLG8scixjLGErMSxDLCFoKSxubi5yZWxlYXNlUHJpbWl0aXZlKEMpfX1yZXR1cm4gU31jb25zdCBXcz1uZXcgenQsd2w9bmV3IGd0LGkwPXtzdHJhdGVneTppbCxtYXhEZXB0aDo0MCxtYXhMZWFmVHJpczoxMCx1c2VTaGFyZWRBcnJheUJ1ZmZlcjohMSxzZXRCb3VuZGluZ0JveDohMCxvblByb2dyZXNzOm51bGwsaW5kaXJlY3Q6ITEsdmVyYm9zZTohMCxyYW5nZTpudWxsfTtjbGFzcyBvYXtzdGF0aWMgc2VyaWFsaXplKHQsZT17fSl7ZT1GdCh7Y2xvbmVCdWZmZXJzOiEwfSxlKTtjb25zdCBuPXQuZ2VvbWV0cnkscz10Ll9yb290cyxyPXQuX2luZGlyZWN0QnVmZmVyLG89bi5nZXRJbmRleCgpO2xldCBhO3JldHVybiBlLmNsb25lQnVmZmVycz9hPXtyb290czpzLm1hcChjPT5jLnNsaWNlKCkpLGluZGV4Om8/by5hcnJheS5zbGljZSgpOm51bGwsaW5kaXJlY3RCdWZmZXI6cj9yLnNsaWNlKCk6bnVsbH06YT17cm9vdHM6cyxpbmRleDpvP28uYXJyYXk6bnVsbCxpbmRpcmVjdEJ1ZmZlcjpyfSxhfXN0YXRpYyBkZXNlcmlhbGl6ZSh0LGUsbj17fSl7bj1GdCh7c2V0SW5kZXg6ITAsaW5kaXJlY3Q6ISF0LmluZGlyZWN0QnVmZmVyfSxuKTtjb25zdHtpbmRleDpzLHJvb3RzOnIsaW5kaXJlY3RCdWZmZXI6b309dCxhPW5ldyBvYShlLFplKEZ0KHt9LG4pLHtbRG9dOiEwfSkpO2lmKGEuX3Jvb3RzPXIsYS5faW5kaXJlY3RCdWZmZXI9b3x8bnVsbCxuLnNldEluZGV4KXtjb25zdCBjPWUuZ2V0SW5kZXgoKTtpZihjPT09bnVsbCl7Y29uc3QgbD1uZXcgeHQodC5pbmRleCwxLCExKTtlLnNldEluZGV4KGwpfWVsc2UgYy5hcnJheSE9PXMmJihjLmFycmF5LnNldChzKSxjLm5lZWRzVXBkYXRlPSEwKX1yZXR1cm4gYX1nZXQgaW5kaXJlY3QoKXtyZXR1cm4hIXRoaXMuX2luZGlyZWN0QnVmZmVyfWNvbnN0cnVjdG9yKHQsZT17fSl7aWYodC5pc0J1ZmZlckdlb21ldHJ5KXtpZih0LmluZGV4JiZ0LmluZGV4LmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGUgaW5kZXggYXR0cmlidXRlLiIpfWVsc2UgdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBPbmx5IEJ1ZmZlckdlb21ldHJpZXMgYXJlIHN1cHBvcnRlZC4iKTtpZihlPU9iamVjdC5hc3NpZ24oWmUoRnQoe30saTApLHtbRG9dOiExfSksZSksZS51c2VTaGFyZWRBcnJheUJ1ZmZlciYmIWUwKCkpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBTaGFyZWRBcnJheUJ1ZmZlciBpcyBub3QgYXZhaWxhYmxlLiIpO3RoaXMuZ2VvbWV0cnk9dCx0aGlzLl9yb290cz1udWxsLHRoaXMuX2luZGlyZWN0QnVmZmVyPW51bGwsZVtEb118fCh4ZCh0aGlzLGUpLCF0LmJvdW5kaW5nQm94JiZlLnNldEJvdW5kaW5nQm94JiYodC5ib3VuZGluZ0JveD10aGlzLmdldEJvdW5kaW5nQm94KG5ldyBndCkpKSx0aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4PWUuaW5kaXJlY3Q/bj0+dGhpcy5faW5kaXJlY3RCdWZmZXJbbl06bj0+bn1yZWZpdCh0PW51bGwpe3JldHVybih0aGlzLmluZGlyZWN0P1dkOkZkKSh0aGlzLHQpfXRyYXZlcnNlKHQsZT0wKXtjb25zdCBuPXRoaXMuX3Jvb3RzW2VdLHM9bmV3IFVpbnQzMkFycmF5KG4pLHI9bmV3IFVpbnQxNkFycmF5KG4pO28oMCk7ZnVuY3Rpb24gbyhhLGM9MCl7Y29uc3QgbD1hKjIsaD1yW2wrMTVdPT09UHM7aWYoaCl7Y29uc3QgdT1zW2ErNl0sZj1yW2wrMTRdO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksdSxmKX1lbHNle2NvbnN0IHU9YStQaS80LGY9c1thKzZdLGQ9c1thKzddO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksZCl8fChvKHUsYysxKSxvKGYsYysxKSl9fX1yYXljYXN0KHQsZT0wLG49MCxzPTEvMCl7Y29uc3Qgcj10aGlzLl9yb290cyxvPXRoaXMuZ2VvbWV0cnksYT1bXSxjPWUuaXNNYXRlcmlhbCxsPUFycmF5LmlzQXJyYXkoZSksaD1vLmdyb3Vwcyx1PWM/ZS5zaWRlOmUsZj10aGlzLmluZGlyZWN0P0dkOlJkO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwO2QrKyl7Y29uc3QgeT1sP2VbaFtkXS5tYXRlcmlhbEluZGV4XS5zaWRlOnUsbT1hLmxlbmd0aDtpZihmKHRoaXMsZCx5LHQsYSxuLHMpLGwpe2NvbnN0IGc9aFtkXS5tYXRlcmlhbEluZGV4O2ZvcihsZXQgYj1tLHc9YS5sZW5ndGg7Yjx3O2IrKylhW2JdLmZhY2UubWF0ZXJpYWxJbmRleD1nfX1yZXR1cm4gYX1yYXljYXN0Rmlyc3QodCxlPTAsbj0wLHM9MS8wKXtjb25zdCByPXRoaXMuX3Jvb3RzLG89dGhpcy5nZW9tZXRyeSxhPWUuaXNNYXRlcmlhbCxjPUFycmF5LmlzQXJyYXkoZSk7bGV0IGw9bnVsbDtjb25zdCBoPW8uZ3JvdXBzLHU9YT9lLnNpZGU6ZSxmPXRoaXMuaW5kaXJlY3Q/WGQ6T2Q7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHA7ZCsrKXtjb25zdCB5PWM/ZVtoW2RdLm1hdGVyaWFsSW5kZXhdLnNpZGU6dSxtPWYodGhpcyxkLHksdCxuLHMpO20hPW51bGwmJihsPT1udWxsfHxtLmRpc3RhbmNlPGwuZGlzdGFuY2UpJiYobD1tLGMmJihtLmZhY2UubWF0ZXJpYWxJbmRleD1oW2RdLm1hdGVyaWFsSW5kZXgpKX1yZXR1cm4gbH1pbnRlcnNlY3RzR2VvbWV0cnkodCxlKXtsZXQgbj0hMTtjb25zdCBzPXRoaXMuX3Jvb3RzLHI9dGhpcy5pbmRpcmVjdD9KZDpEZDtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YSYmKG49cih0aGlzLG8sdCxlKSwhbik7bysrKTtyZXR1cm4gbn1zaGFwZWNhc3QodCl7Y29uc3QgZT1pZS5nZXRQcmltaXRpdmUoKSxuPXRoaXMuaW5kaXJlY3Q/TmQ6QmQ7bGV0e2JvdW5kc1RyYXZlcnNlT3JkZXI6cyxpbnRlcnNlY3RzQm91bmRzOnIsaW50ZXJzZWN0c1JhbmdlOm8saW50ZXJzZWN0c1RyaWFuZ2xlOmF9PXQ7aWYobyYmYSl7Y29uc3QgdT1vO289KGYsZCxwLHksbSk9PnUoZixkLHAseSxtKT8hMDpuKGYsZCx0aGlzLGEscCx5LGUpfWVsc2Ugb3x8KGE/bz0odSxmLGQscCk9Pm4odSxmLHRoaXMsYSxkLHAsZSk6bz0odSxmLGQpPT5kKTtsZXQgYz0hMSxsPTA7Y29uc3QgaD10aGlzLl9yb290cztmb3IobGV0IHU9MCxmPWgubGVuZ3RoO3U8Zjt1Kyspe2NvbnN0IGQ9aFt1XTtpZihjPV9kKHRoaXMsdSxyLG8scyxsKSxjKWJyZWFrO2wrPWQuYnl0ZUxlbmd0aH1yZXR1cm4gaWUucmVsZWFzZVByaW1pdGl2ZShlKSxjfWJ2aGNhc3QodCxlLG4pe2xldHtpbnRlcnNlY3RzUmFuZ2VzOnMsaW50ZXJzZWN0c1RyaWFuZ2xlczpyfT1uO2NvbnN0IG89aWUuZ2V0UHJpbWl0aXZlKCksYT10aGlzLmdlb21ldHJ5LmluZGV4LGM9dGhpcy5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9dGhpcy5pbmRpcmVjdD9wPT57Y29uc3QgeT10aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4KHApO3l0KG8seSozLGEsYyl9OnA9Pnt5dChvLHAqMyxhLGMpfSxoPWllLmdldFByaW1pdGl2ZSgpLHU9dC5nZW9tZXRyeS5pbmRleCxmPXQuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixkPXQuaW5kaXJlY3Q/cD0+e2NvbnN0IHk9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChwKTt5dChoLHkqMyx1LGYpfTpwPT57eXQoaCxwKjMsdSxmKX07aWYocil7Y29uc3QgcD0oeSxtLGcsYix3LHgsTSxBKT0+e2ZvcihsZXQgUz1nLF89ZytiO1M8XztTKyspe2QoUyksaC5hLmFwcGx5TWF0cml4NChlKSxoLmIuYXBwbHlNYXRyaXg0KGUpLGguYy5hcHBseU1hdHJpeDQoZSksaC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IEU9eSx6PXkrbTtFPHo7RSsrKWlmKGwoRSksby5uZWVkc1VwZGF0ZT0hMCxyKG8saCxFLFMsdyx4LE0sQSkpcmV0dXJuITB9cmV0dXJuITF9O2lmKHMpe2NvbnN0IHk9cztzPWZ1bmN0aW9uKG0sZyxiLHcseCxNLEEsUyl7cmV0dXJuIHkobSxnLGIsdyx4LE0sQSxTKT8hMDpwKG0sZyxiLHcseCxNLEEsUyl9fWVsc2Ugcz1wfXJldHVybiBuMCh0aGlzLHQsZSxzKX1pbnRlcnNlY3RzQm94KHQsZSl7cmV0dXJuIFdzLnNldCh0Lm1pbix0Lm1heCxlKSxXcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpuPT5Xcy5pbnRlcnNlY3RzQm94KG4pLGludGVyc2VjdHNUcmlhbmdsZTpuPT5Xcy5pbnRlcnNlY3RzVHJpYW5nbGUobil9KX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczplPT50LmludGVyc2VjdHNCb3goZSksaW50ZXJzZWN0c1RyaWFuZ2xlOmU9PmUuaW50ZXJzZWN0c1NwaGVyZSh0KX0pfWNsb3Nlc3RQb2ludFRvR2VvbWV0cnkodCxlLG49e30scz17fSxyPTAsbz0xLzApe3JldHVybih0aGlzLmluZGlyZWN0P3QwOkhkKSh0aGlzLHQsZSxuLHMscixvKX1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZT17fSxuPTAscz0xLzApe3JldHVybiB2ZCh0aGlzLHQsZSxuLHMpfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0Lm1ha2VFbXB0eSgpLHRoaXMuX3Jvb3RzLmZvckVhY2gobj0+e2x0KDAsbmV3IEZsb2F0MzJBcnJheShuKSx3bCksdC51bmlvbih3bCl9KSx0fX1jb25zdCBibD0xZS02LHMwPWJsKi41LE1sPU1hdGgucG93KDEwLC1NYXRoLmxvZzEwKGJsKSkscjA9czAqTWw7ZnVuY3Rpb24gd2UoaSl7cmV0dXJufn4oaSpNbCtyMCl9ZnVuY3Rpb24gbzAoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfWB9ZnVuY3Rpb24gQWwoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfSwke3dlKGkueil9YH1mdW5jdGlvbiBhMChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9LCR7d2UoaS56KX0sJHt3ZShpLncpfWB9ZnVuY3Rpb24gYzAoaSx0LGUpe2UuZGlyZWN0aW9uLnN1YlZlY3RvcnModCxpKS5ub3JtYWxpemUoKTtjb25zdCBuPWkuZG90KGUuZGlyZWN0aW9uKTtyZXR1cm4gZS5vcmlnaW4uY29weShpKS5hZGRTY2FsZWRWZWN0b3IoZS5kaXJlY3Rpb24sLW4pLGV9ZnVuY3Rpb24gU2woKXtyZXR1cm4gdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIn1mdW5jdGlvbiBsMChpKXtpZihpLmJ1ZmZlciBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKXJldHVybiBpO2NvbnN0IHQ9aS5jb25zdHJ1Y3RvcixlPWkuYnVmZmVyLG49bmV3IFNoYXJlZEFycmF5QnVmZmVyKGUuYnl0ZUxlbmd0aCkscz1uZXcgVWludDhBcnJheShlKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobikuc2V0KHMsMCksbmV3IHQobil9ZnVuY3Rpb24gaDAoaSx0PUFycmF5QnVmZmVyKXtyZXR1cm4gaT42NTUzNT9uZXcgVWludDMyQXJyYXkobmV3IHQoNCppKSk6bmV3IFVpbnQxNkFycmF5KG5ldyB0KDIqaSkpfWZ1bmN0aW9uIHUwKGksdCl7aWYoIWkuaW5kZXgpe2NvbnN0IGU9aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50LG49dC51c2VTaGFyZWRBcnJheUJ1ZmZlcj9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPWgwKGUsbik7aS5zZXRJbmRleChuZXcgeHQocywxKSk7Zm9yKGxldCByPTA7cjxlO3IrKylzW3JdPXJ9fWZ1bmN0aW9uIGYwKGkpe3JldHVybiBpLmluZGV4P2kuaW5kZXguY291bnQ6aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWZ1bmN0aW9uIGFhKGkpe3JldHVybiBmMChpKS8zfWNvbnN0IGQwPTFlLTgscDA9bmV3IFQ7ZnVuY3Rpb24geTAoaSl7cmV0dXJufn4oaS8zKX1mdW5jdGlvbiBtMChpKXtyZXR1cm4gaSUzfWZ1bmN0aW9uIF9sKGksdCl7cmV0dXJuIGkuc3RhcnQtdC5zdGFydH1mdW5jdGlvbiB2bChpLHQpe3JldHVybiBwMC5zdWJWZWN0b3JzKHQsaS5vcmlnaW4pLmRvdChpLmRpcmVjdGlvbil9ZnVuY3Rpb24gZzAoaSx0LGUsbj1kMCl7aS5zb3J0KF9sKSx0LnNvcnQoX2wpO2ZvcihsZXQgYT0wO2E8aS5sZW5ndGg7YSsrKXtjb25zdCBjPWlbYV07Zm9yKGxldCBsPTA7bDx0Lmxlbmd0aDtsKyspe2NvbnN0IGg9dFtsXTtpZighKGguc3RhcnQ+Yy5lbmQpKXtpZihjLmVuZDxoLnN0YXJ0fHxoLmVuZDxjLnN0YXJ0KWNvbnRpbnVlO2lmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPj1oLmVuZClyKGguZW5kLGMuZW5kKXx8aS5zcGxpY2UoYSsxLDAse3N0YXJ0OmguZW5kLGVuZDpjLmVuZCxpbmRleDpjLmluZGV4fSksYy5lbmQ9aC5zdGFydCxoLnN0YXJ0PTAsaC5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPD1oLmVuZClyKGMuZW5kLGguZW5kKXx8dC5zcGxpY2UobCsxLDAse3N0YXJ0OmMuZW5kLGVuZDpoLmVuZCxpbmRleDpoLmluZGV4fSksaC5lbmQ9Yy5zdGFydCxjLnN0YXJ0PTAsYy5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPD1oLmVuZCl7Y29uc3QgdT1jLmVuZDtjLmVuZD1oLnN0YXJ0LGguc3RhcnQ9dX1lbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPj1oLmVuZCl7Y29uc3QgdT1oLmVuZDtoLmVuZD1jLnN0YXJ0LGMuc3RhcnQ9dX1lbHNlIHRocm93IG5ldyBFcnJvcn1pZihlLmhhcyhjLmluZGV4KXx8ZS5zZXQoYy5pbmRleCxbXSksZS5oYXMoaC5pbmRleCl8fGUuc2V0KGguaW5kZXgsW10pLGUuZ2V0KGMuaW5kZXgpLnB1c2goaC5pbmRleCksZS5nZXQoaC5pbmRleCkucHVzaChjLmluZGV4KSxvKGgpJiYodC5zcGxpY2UobCwxKSxsLS0pLG8oYykpe2kuc3BsaWNlKGEsMSksYS0tO2JyZWFrfX19cyhpKSxzKHQpO2Z1bmN0aW9uIHMoYSl7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKyspbyhhW2NdKSYmKGEuc3BsaWNlKGMsMSksYy0tKX1mdW5jdGlvbiByKGEsYyl7cmV0dXJuIE1hdGguYWJzKGMtYSk8bn1mdW5jdGlvbiBvKGEpe3JldHVybiBNYXRoLmFicyhhLmVuZC1hLnN0YXJ0KTxufX1jb25zdCB6bD0xZS01LFRsPTFlLTQ7Y2xhc3MgeDB7Y29uc3RydWN0b3IoKXt0aGlzLl9yYXlzPVtdfWFkZFJheSh0KXt0aGlzLl9yYXlzLnB1c2godCl9ZmluZENsb3Nlc3RSYXkodCl7Y29uc3QgZT10aGlzLl9yYXlzLG49dC5jbG9uZSgpO24uZGlyZWN0aW9uLm11bHRpcGx5U2NhbGFyKC0xKTtsZXQgcz0xLzAscj1udWxsO2ZvcihsZXQgYz0wLGw9ZS5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1lW2NdO2lmKG8oaCx0KSYmbyhoLG4pKWNvbnRpbnVlO2NvbnN0IHU9YShoLHQpLGY9YShoLG4pLGQ9TWF0aC5taW4odSxmKTtkPHMmJihzPWQscj1oKX1yZXR1cm4gcjtmdW5jdGlvbiBvKGMsbCl7Y29uc3QgaD1jLm9yaWdpbi5kaXN0YW5jZVRvKGwub3JpZ2luKT56bDtyZXR1cm4gYy5kaXJlY3Rpb24uYW5nbGVUbyhsLmRpcmVjdGlvbik+VGx8fGh9ZnVuY3Rpb24gYShjLGwpe2NvbnN0IGg9Yy5vcmlnaW4uZGlzdGFuY2VUbyhsLm9yaWdpbiksdT1jLmRpcmVjdGlvbi5hbmdsZVRvKGwuZGlyZWN0aW9uKTtyZXR1cm4gaC96bCt1L1RsfX19Y29uc3QgY2E9bmV3IFQsbGE9bmV3IFQsR3M9bmV3IGZvO2Z1bmN0aW9uIHcwKGksdCxlKXtjb25zdCBuPWkuYXR0cmlidXRlcyxzPWkuaW5kZXgscj1uLnBvc2l0aW9uLG89bmV3IE1hcCxhPW5ldyBNYXAsYz1BcnJheS5mcm9tKHQpLGw9bmV3IHgwO2ZvcihsZXQgaD0wLHU9Yy5sZW5ndGg7aDx1O2grKyl7Y29uc3QgZj1jW2hdLGQ9eTAoZikscD1tMChmKTtsZXQgeT0zKmQrcCxtPTMqZCsocCsxKSUzO3MmJih5PXMuZ2V0WCh5KSxtPXMuZ2V0WChtKSksY2EuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLHkpLGxhLmZyb21CdWZmZXJBdHRyaWJ1dGUocixtKSxjMChjYSxsYSxHcyk7bGV0IGcsYj1sLmZpbmRDbG9zZXN0UmF5KEdzKTtiPT09bnVsbCYmKGI9R3MuY2xvbmUoKSxsLmFkZFJheShiKSksYS5oYXMoYil8fGEuc2V0KGIse2ZvcndhcmQ6W10scmV2ZXJzZTpbXSxyYXk6Yn0pLGc9YS5nZXQoYik7bGV0IHc9dmwoYixjYSkseD12bChiLGxhKTt3PngmJihbdyx4XT1beCx3XSksR3MuZGlyZWN0aW9uLmRvdChiLmRpcmVjdGlvbik8MD9nLnJldmVyc2UucHVzaCh7c3RhcnQ6dyxlbmQ6eCxpbmRleDpmfSk6Zy5mb3J3YXJkLnB1c2goe3N0YXJ0OncsZW5kOngsaW5kZXg6Zn0pfXJldHVybiBhLmZvckVhY2goKHtmb3J3YXJkOmgscmV2ZXJzZTp1fSxmKT0+e2cwKGgsdSxvLGUpLGgubGVuZ3RoPT09MCYmdS5sZW5ndGg9PT0wJiZhLmRlbGV0ZShmKX0pLHtkaXNqb2ludENvbm5lY3Rpdml0eU1hcDpvLGZyYWdtZW50TWFwOmF9fWNvbnN0IGIwPW5ldyBSLGhhPW5ldyBULE0wPW5ldyBZdCx1YT1bIiIsIiIsIiJdO2NsYXNzIEEwe2NvbnN0cnVjdG9yKHQ9bnVsbCl7dGhpcy5kYXRhPW51bGwsdGhpcy5kaXNqb2ludENvbm5lY3Rpb25zPW51bGwsdGhpcy51bm1hdGNoZWREaXNqb2ludEVkZ2VzPW51bGwsdGhpcy51bm1hdGNoZWRFZGdlcz0tMSx0aGlzLm1hdGNoZWRFZGdlcz0tMSx0aGlzLnVzZURyYXdSYW5nZT0hMCx0aGlzLnVzZUFsbEF0dHJpYnV0ZXM9ITEsdGhpcy5tYXRjaERpc2pvaW50RWRnZXM9ITEsdGhpcy5kZWdlbmVyYXRlRXBzaWxvbj0xZS04LHQmJnRoaXMudXBkYXRlRnJvbSh0KX1nZXRTaWJsaW5nVHJpYW5nbGVJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOn5+KG4vMyl9Z2V0U2libGluZ0VkZ2VJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOm4lM31nZXREaXNqb2ludFNpYmxpbmdUcmlhbmdsZUluZGljZXModCxlKXtjb25zdCBuPXQqMytlLHM9dGhpcy5kaXNqb2ludENvbm5lY3Rpb25zLmdldChuKTtyZXR1cm4gcz9zLm1hcChyPT5+fihyLzMpKTpbXX1nZXREaXNqb2ludFNpYmxpbmdFZGdlSW5kaWNlcyh0LGUpe2NvbnN0IG49dCozK2Uscz10aGlzLmRpc2pvaW50Q29ubmVjdGlvbnMuZ2V0KG4pO3JldHVybiBzP3MubWFwKHI9PnIlMyk6W119aXNGdWxseUNvbm5lY3RlZCgpe3JldHVybiB0aGlzLnVubWF0Y2hlZEVkZ2VzPT09MH11cGRhdGVGcm9tKHQpe2NvbnN0e3VzZUFsbEF0dHJpYnV0ZXM6ZSx1c2VEcmF3UmFuZ2U6bixtYXRjaERpc2pvaW50RWRnZXM6cyxkZWdlbmVyYXRlRXBzaWxvbjpyfT10aGlzLG89ZT93OmIsYT1uZXcgTWFwLHthdHRyaWJ1dGVzOmN9PXQsbD1lP09iamVjdC5rZXlzKGMpOm51bGwsaD10LmluZGV4LHU9Yy5wb3NpdGlvbjtsZXQgZj1hYSh0KTtjb25zdCBkPWY7bGV0IHA9MDtuJiYocD10LmRyYXdSYW5nZS5zdGFydCx0LmRyYXdSYW5nZS5jb3VudCE9PTEvMCYmKGY9fn4odC5kcmF3UmFuZ2UuY291bnQvMykpKTtsZXQgeT10aGlzLmRhdGE7KCF5fHx5Lmxlbmd0aDwzKmQpJiYoeT1uZXcgSW50MzJBcnJheSgzKmQpKSx5LmZpbGwoLTEpO2xldCBtPTAsZz1uZXcgU2V0O2ZvcihsZXQgeD1wLE09ZiozK3A7eDxNO3grPTMpe2NvbnN0IEE9eDtmb3IobGV0IFM9MDtTPDM7UysrKXtsZXQgXz1BK1M7aCYmKF89aC5nZXRYKF8pKSx1YVtTXT1vKF8pfWZvcihsZXQgUz0wO1M8MztTKyspe2NvbnN0IF89KFMrMSklMyxFPXVhW1NdLHo9dWFbX10sdj1gJHt6fV8ke0V9YDtpZihhLmhhcyh2KSl7Y29uc3QgQz1BK1MsUD1hLmdldCh2KTt5W0NdPVAseVtQXT1DLGEuZGVsZXRlKHYpLG0rPTIsZy5kZWxldGUoUCl9ZWxzZXtjb25zdCBDPWAke0V9XyR7en1gLFA9QStTO2Euc2V0KEMsUCksZy5hZGQoUCl9fX1pZihzKXtjb25zdHtmcmFnbWVudE1hcDp4LGRpc2pvaW50Q29ubmVjdGl2aXR5TWFwOk19PXcwKHQsZyxyKTtnLmNsZWFyKCkseC5mb3JFYWNoKCh7Zm9yd2FyZDpBLHJldmVyc2U6U30pPT57QS5mb3JFYWNoKCh7aW5kZXg6X30pPT5nLmFkZChfKSksUy5mb3JFYWNoKCh7aW5kZXg6X30pPT5nLmFkZChfKSl9KSx0aGlzLnVubWF0Y2hlZERpc2pvaW50RWRnZXM9eCx0aGlzLmRpc2pvaW50Q29ubmVjdGlvbnM9TSxtPWYqMy1nLnNpemV9dGhpcy5tYXRjaGVkRWRnZXM9bSx0aGlzLnVubWF0Y2hlZEVkZ2VzPWcuc2l6ZSx0aGlzLmRhdGE9eTtmdW5jdGlvbiBiKHgpe3JldHVybiBoYS5mcm9tQnVmZmVyQXR0cmlidXRlKHUseCksQWwoaGEpfWZ1bmN0aW9uIHcoeCl7bGV0IE09IiI7Zm9yKGxldCBBPTAsUz1sLmxlbmd0aDtBPFM7QSsrKXtjb25zdCBfPWNbbFtBXV07bGV0IEU7c3dpdGNoKF8uaXRlbVNpemUpe2Nhc2UgMTpFPXdlKF8uZ2V0WCh4KSk7YnJlYWs7Y2FzZSAyOkU9bzAoYjAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShfLHgpKTticmVhaztjYXNlIDM6RT1BbChoYS5mcm9tQnVmZmVyQXR0cmlidXRlKF8seCkpO2JyZWFrO2Nhc2UgNDpFPWEwKE0wLmZyb21CdWZmZXJBdHRyaWJ1dGUoXyx4KSk7YnJlYWt9TSE9PSIiJiYoTSs9InwiKSxNKz1FfXJldHVybiBNfX19Y2xhc3MgWnMgZXh0ZW5kcyBiZntjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzQnJ1c2g9ITAsdGhpcy5fcHJldmlvdXNNYXRyaXg9bmV3IHN0LHRoaXMuX3ByZXZpb3VzTWF0cml4LmVsZW1lbnRzLmZpbGwoMCl9bWFya1VwZGF0ZWQoKXt0aGlzLl9wcmV2aW91c01hdHJpeC5jb3B5KHRoaXMubWF0cml4KX1pc0RpcnR5KCl7Y29uc3R7bWF0cml4OnQsX3ByZXZpb3VzTWF0cml4OmV9PXRoaXMsbj10LmVsZW1lbnRzLHM9ZS5lbGVtZW50cztmb3IobGV0IHI9MDtyPDE2O3IrKylpZihuW3JdIT09c1tyXSlyZXR1cm4hMDtyZXR1cm4hMX1wcmVwYXJlR2VvbWV0cnkoKXtjb25zdCB0PXRoaXMuZ2VvbWV0cnksZT10LmF0dHJpYnV0ZXMsbj1TbCgpO2lmKG4pZm9yKGNvbnN0IHMgaW4gZSl7Y29uc3Qgcj1lW3NdO2lmKHIuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl0aHJvdyBuZXcgRXJyb3IoIkJydXNoOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIik7ci5hcnJheT1sMChyLmFycmF5KX1pZih0LmJvdW5kc1RyZWV8fCh1MCh0LHt1c2VTaGFyZWRBcnJheUJ1ZmZlcjpufSksdC5ib3VuZHNUcmVlPW5ldyBvYSh0LHttYXhMZWFmVHJpczozLGluZGlyZWN0OiEwLHVzZVNoYXJlZEFycmF5QnVmZmVyOm59KSksdC5oYWxmRWRnZXN8fCh0LmhhbGZFZGdlcz1uZXcgQTAodCkpLCF0Lmdyb3VwSW5kaWNlcyl7Y29uc3Qgcz1hYSh0KSxyPW5ldyBVaW50MTZBcnJheShzKSxvPXQuZ3JvdXBzO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKyl7Y29uc3R7c3RhcnQ6bCxjb3VudDpofT1vW2FdO2ZvcihsZXQgdT1sLzMsZj0obCtoKS8zO3U8Zjt1Kyspclt1XT1hfXQuZ3JvdXBJbmRpY2VzPXJ9fWRpc3Bvc2VDYWNoZURhdGEoKXtjb25zdHtnZW9tZXRyeTp0fT10aGlzO3QuaGFsZkVkZ2VzPW51bGwsdC5ib3VuZHNUcmVlPW51bGwsdC5ncm91cEluZGljZXM9bnVsbH19Y29uc3QgUzA9MWUtMTQsZmE9bmV3IFQsRWw9bmV3IFQsUGw9bmV3IFQ7ZnVuY3Rpb24gc24oaSx0PVMwKXtmYS5zdWJWZWN0b3JzKGkuYixpLmEpLEVsLnN1YlZlY3RvcnMoaS5jLGkuYSksUGwuc3ViVmVjdG9ycyhpLmIsaS5jKTtjb25zdCBlPWZhLmFuZ2xlVG8oRWwpLG49ZmEuYW5nbGVUbyhQbCkscz1NYXRoLlBJLWUtbjtyZXR1cm4gTWF0aC5hYnMoZSk8dHx8TWF0aC5hYnMobik8dHx8TWF0aC5hYnMocyk8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYik8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dHx8aS5iLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dH1jb25zdCBkYT0xZS0xMCxEaT0xZS0xMCxfMD0xZS0xMCxrZT1uZXcgUXQsZnQ9bmV3IFF0LE5lPW5ldyBULHBhPW5ldyBULENsPW5ldyBULFhzPW5ldyB6byx5YT1uZXcgbmU7Y2xhc3MgdjB7Y29uc3RydWN0b3IoKXt0aGlzLl9wb29sPVtdLHRoaXMuX2luZGV4PTB9Z2V0VHJpYW5nbGUoKXtyZXR1cm4gdGhpcy5faW5kZXg+PXRoaXMuX3Bvb2wubGVuZ3RoJiZ0aGlzLl9wb29sLnB1c2gobmV3IGV0KSx0aGlzLl9wb29sW3RoaXMuX2luZGV4KytdfWNsZWFyKCl7dGhpcy5faW5kZXg9MH1yZXNldCgpe3RoaXMuX3Bvb2wubGVuZ3RoPTAsdGhpcy5faW5kZXg9MH19Y2xhc3MgejB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlUG9vbD1uZXcgdjAsdGhpcy50cmlhbmdsZXM9W10sdGhpcy5ub3JtYWw9bmV3IFQsdGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMX1pbml0aWFsaXplKHQpe3RoaXMucmVzZXQoKTtjb25zdHt0cmlhbmdsZXM6ZSx0cmlhbmdsZVBvb2w6bixub3JtYWw6c309dGhpcztpZihBcnJheS5pc0FycmF5KHQpKWZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdO2lmKHI9PT0wKWEuZ2V0Tm9ybWFsKHMpO2Vsc2UgaWYoTWF0aC5hYnMoMS1hLmdldE5vcm1hbChOZSkuZG90KHMpKT5kYSl0aHJvdyBuZXcgRXJyb3IoIlRyaWFuZ2xlIFNwbGl0dGVyOiBDYW5ub3QgaW5pdGlhbGl6ZSB3aXRoIHRyaWFuZ2xlcyB0aGF0IGhhdmUgZGlmZmVyZW50IG5vcm1hbHMuIik7Y29uc3QgYz1uLmdldFRyaWFuZ2xlKCk7Yy5jb3B5KGEpLGUucHVzaChjKX1lbHNle3QuZ2V0Tm9ybWFsKHMpO2NvbnN0IHI9bi5nZXRUcmlhbmdsZSgpO3IuY29weSh0KSxlLnB1c2gocil9fXNwbGl0QnlUcmlhbmdsZSh0KXtjb25zdHtub3JtYWw6ZSx0cmlhbmdsZXM6bn09dGhpcztpZih0LmdldE5vcm1hbChwYSkubm9ybWFsaXplKCksTWF0aC5hYnMoMS1NYXRoLmFicyhwYS5kb3QoZSkpKTxfMCl7dGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTthLmNvcGxhbmFyQ291bnQ9MH1jb25zdCBzPVt0LmEsdC5iLHQuY107Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz0ocisxKSUzLGE9c1tyXSxjPXNbb107TmUuc3ViVmVjdG9ycyhjLGEpLm5vcm1hbGl6ZSgpLENsLmNyb3NzVmVjdG9ycyhwYSxOZSksWHMuc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQoQ2wsYSksdGhpcy5zcGxpdEJ5UGxhbmUoWHMsdCl9fWVsc2UgdC5nZXRQbGFuZShYcyksdGhpcy5zcGxpdEJ5UGxhbmUoWHMsdCl9c3BsaXRCeVBsYW5lKHQsZSl7Y29uc3R7dHJpYW5nbGVzOm4sdHJpYW5nbGVQb29sOnN9PXRoaXM7eWEuY29weShlKSx5YS5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTtpZigheWEuaW50ZXJzZWN0c1RyaWFuZ2xlKGEsa2UsITApKWNvbnRpbnVlO2NvbnN0e2E6YyxiOmwsYzpofT1hO2xldCB1PTAsZj0tMSxkPSExLHA9W10seT1bXTtjb25zdCBtPVtjLGwsaF07Zm9yKGxldCBnPTA7ZzwzO2crKyl7Y29uc3QgYj0oZysxKSUzO2tlLnN0YXJ0LmNvcHkobVtnXSksa2UuZW5kLmNvcHkobVtiXSk7Y29uc3Qgdz10LmRpc3RhbmNlVG9Qb2ludChrZS5zdGFydCkseD10LmRpc3RhbmNlVG9Qb2ludChrZS5lbmQpO2lmKE1hdGguYWJzKHcpPERpJiZNYXRoLmFicyh4KTxEaSl7ZD0hMDticmVha31pZih3PjA/cC5wdXNoKGcpOnkucHVzaChnKSxNYXRoLmFicyh3KTxEaSljb250aW51ZTtsZXQgTT0hIXQuaW50ZXJzZWN0TGluZShrZSxOZSk7IU0mJk1hdGguYWJzKHgpPERpJiYoTmUuY29weShrZS5lbmQpLE09ITApLE0mJiEoTmUuZGlzdGFuY2VUbyhrZS5zdGFydCk8ZGEpJiYoTmUuZGlzdGFuY2VUbyhrZS5lbmQpPGRhJiYoZj1nKSx1PT09MD9mdC5zdGFydC5jb3B5KE5lKTpmdC5lbmQuY29weShOZSksdSsrKX1pZighZCYmdT09PTImJmZ0LmRpc3RhbmNlKCk+RGkpaWYoZiE9PS0xKXtmPShmKzEpJTM7bGV0IGc9MDtnPT09ZiYmKGc9KGcrMSklMyk7bGV0IGI9ZysxO2I9PT1mJiYoYj0oYisxKSUzKTtjb25zdCB3PXMuZ2V0VHJpYW5nbGUoKTt3LmEuY29weShtW2JdKSx3LmIuY29weShmdC5lbmQpLHcuYy5jb3B5KGZ0LnN0YXJ0KSxzbih3KXx8bi5wdXNoKHcpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LnN0YXJ0KSxhLmMuY29weShmdC5lbmQpLHNuKGEpJiYobi5zcGxpY2UociwxKSxyLS0sby0tKX1lbHNle2NvbnN0IGc9cC5sZW5ndGg+PTI/eVswXTpwWzBdO2lmKGc9PT0wKXtsZXQgQT1mdC5zdGFydDtmdC5zdGFydD1mdC5lbmQsZnQuZW5kPUF9Y29uc3QgYj0oZysxKSUzLHc9KGcrMiklMyx4PXMuZ2V0VHJpYW5nbGUoKSxNPXMuZ2V0VHJpYW5nbGUoKTttW2JdLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LnN0YXJ0KTxtW3ddLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LmVuZCk/KHguYS5jb3B5KG1bYl0pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LnN0YXJ0KSk6KHguYS5jb3B5KG1bd10pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LmVuZCkpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LmVuZCksYS5jLmNvcHkoZnQuc3RhcnQpLHNuKHgpfHxuLnB1c2goeCksc24oTSl8fG4ucHVzaChNKSxzbihhKSYmKG4uc3BsaWNlKHIsMSksci0tLG8tLSl9ZWxzZSB1PT09MyYmY29uc29sZS53YXJuKCJUcmlhbmdsZUNsaXBwZXI6IENvcGxhbmFyIGNsaXAgbm90IGhhbmRsZWQiKX19cmVzZXQoKXt0aGlzLnRyaWFuZ2xlcy5sZW5ndGg9MCx0aGlzLnRyaWFuZ2xlUG9vbC5jbGVhcigpLHRoaXMuY29wbGFuYXJUcmlhbmdsZVVzZWQ9ITF9fWZ1bmN0aW9uIFQwKGkpe3JldHVybiBpPX5+aSxpKzQtaSU0fWNsYXNzIEJse2NvbnN0cnVjdG9yKHQsZT01MDApe3RoaXMuZXhwYW5zaW9uRmFjdG9yPTEuNSx0aGlzLnR5cGU9dCx0aGlzLmxlbmd0aD0wLHRoaXMuYXJyYXk9bnVsbCx0aGlzLnNldFNpemUoZSl9c2V0VHlwZSh0KXtpZih0aGlzLmxlbmd0aCE9PTApdGhyb3cgbmV3IEVycm9yKCJUeXBlQmFja2VkQXJyYXk6IENhbm5vdCBjaGFuZ2UgdGhlIHR5cGUgd2hpbGUgdGhlcmUgaXMgdXNlZCBkYXRhIGluIHRoZSBidWZmZXIuIik7Y29uc3QgZT10aGlzLmFycmF5LmJ1ZmZlcjt0aGlzLmFycmF5PW5ldyB0KGUpLHRoaXMudHlwZT10fXNldFNpemUodCl7aWYodGhpcy5hcnJheSYmdD09PXRoaXMuYXJyYXkubGVuZ3RoKXJldHVybjtjb25zdCBlPXRoaXMudHlwZSxuPVNsKCk/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1uZXcgZShuZXcgbihUMCh0KmUuQllURVNfUEVSX0VMRU1FTlQpKSk7dGhpcy5hcnJheSYmcy5zZXQodGhpcy5hcnJheSwwKSx0aGlzLmFycmF5PXN9ZXhwYW5kKCl7Y29uc3R7YXJyYXk6dCxleHBhbnNpb25GYWN0b3I6ZX09dGhpczt0aGlzLnNldFNpemUodC5sZW5ndGgqZSl9cHVzaCguLi50KXtsZXR7YXJyYXk6ZSxsZW5ndGg6bn09dGhpcztuK3QubGVuZ3RoPmUubGVuZ3RoJiYodGhpcy5leHBhbmQoKSxlPXRoaXMuYXJyYXkpO2ZvcihsZXQgcz0wLHI9dC5sZW5ndGg7czxyO3MrKyllW24rc109dFtzXTt0aGlzLmxlbmd0aCs9dC5sZW5ndGh9Y2xlYXIoKXt0aGlzLmxlbmd0aD0wfX1jbGFzcyBFMHtjb25zdHJ1Y3Rvcigpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVt7fV0sdGhpcy5ncm91cENvdW50PTB9Z2V0VHlwZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0udHlwZX1nZXRJdGVtU2l6ZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0uaXRlbVNpemV9Z2V0Tm9ybWFsaXplZCh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0ubm9ybWFsaXplZH1nZXRDb3VudCh0KXtpZih0aGlzLmdyb3VwQ291bnQ8PXQpcmV0dXJuIDA7Y29uc3QgZT10aGlzLmdldEdyb3VwQXR0ckFycmF5KCJwb3NpdGlvbiIsdCk7cmV0dXJuIGUubGVuZ3RoL2UuaXRlbVNpemV9Z2V0VG90YWxMZW5ndGgodCl7Y29uc3R7Z3JvdXBDb3VudDplLGdyb3VwQXR0cmlidXRlczpufT10aGlzO2xldCBzPTA7Zm9yKGxldCByPTA7cjxlO3IrKyl7Y29uc3Qgbz1uW3JdO3MrPW9bdF0ubGVuZ3RofXJldHVybiBzfWdldEdyb3VwQXR0clNldCh0PTApe2NvbnN0e2dyb3VwQXR0cmlidXRlczplfT10aGlzO2lmKGVbdF0pcmV0dXJuIHRoaXMuZ3JvdXBDb3VudD1NYXRoLm1heCh0aGlzLmdyb3VwQ291bnQsdCsxKSxlW3RdO2NvbnN0IG49ZVswXTtmb3IodGhpcy5ncm91cENvdW50PU1hdGgubWF4KHRoaXMuZ3JvdXBDb3VudCx0KzEpO3Q+PWUubGVuZ3RoOyl7Y29uc3Qgcz17fTtlLnB1c2gocyk7Zm9yKGNvbnN0IHIgaW4gbil7Y29uc3Qgbz1uW3JdLGE9bmV3IEJsKG8udHlwZSk7YS5pdGVtU2l6ZT1vLml0ZW1TaXplLGEubm9ybWFsaXplZD1vLm5vcm1hbGl6ZWQsc1tyXT1hfX1yZXR1cm4gZVt0XX1nZXRHcm91cEF0dHJBcnJheSh0LGU9MCl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOm59PXRoaXM7aWYoIW5bMF1bdF0pdGhyb3cgbmV3IEVycm9yKGBUeXBlZEF0dHJpYnV0ZURhdGE6IEF0dHJpYnV0ZSB3aXRoICIke3R9IiBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRgKTtyZXR1cm4gdGhpcy5nZXRHcm91cEF0dHJTZXQoZSlbdF19aW5pdGlhbGl6ZUFycmF5KHQsZSxuLHMpe2NvbnN0e2dyb3VwQXR0cmlidXRlczpyfT10aGlzLGE9clswXVt0XTtpZihhKXtpZihhLnR5cGUhPT1lKWZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1yW2NdW3RdO2guc2V0VHlwZShlKSxoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXN9fWVsc2UgZm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPW5ldyBCbChlKTtoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXMscltjXVt0XT1ofX1jbGVhcigpe3RoaXMuZ3JvdXBDb3VudD0wO2NvbnN0e2dyb3VwQXR0cmlidXRlczp0fT10aGlzO3QuZm9yRWFjaChlPT57Zm9yKGNvbnN0IG4gaW4gZSllW25dLmNsZWFyKCl9KX1kZWxldGUodCl7dGhpcy5ncm91cEF0dHJpYnV0ZXMuZm9yRWFjaChlPT57ZGVsZXRlIGVbdF19KX1yZXNldCgpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVtdLHRoaXMuZ3JvdXBDb3VudD0wfX1jbGFzcyBGbHtjb25zdHJ1Y3Rvcigpe3RoaXMuaW50ZXJzZWN0aW9uU2V0PXt9LHRoaXMuaWRzPVtdfWFkZCh0LGUpe2NvbnN0e2ludGVyc2VjdGlvblNldDpuLGlkczpzfT10aGlzO25bdF18fChuW3RdPVtdLHMucHVzaCh0KSksblt0XS5wdXNoKGUpfX1jb25zdCBQMD0wLEMwPTEsQjA9MixJbD0zLEYwPTQsa2w9NSxObD02LHNlPW5ldyBmbyxSbD1uZXcgc3QsVHQ9bmV3IGV0LFJlPW5ldyBULExsPW5ldyBZdCxPbD1uZXcgWXQsRGw9bmV3IFl0LG1hPW5ldyBZdCxKcz1uZXcgWXQsWXM9bmV3IFl0LCRsPW5ldyBRdCxnYT1uZXcgVCx4YT0xZS04LEkwPTFlLTE1LHhuPS0xLHduPTEsanM9LTIsUXM9MiwkaT0wLGJuPTEsd2E9MixrMD0xZS0xNDtsZXQgS3M9bnVsbDtmdW5jdGlvbiBWbChpKXtLcz1pfWZ1bmN0aW9uIFVsKGksdCl7aS5nZXRNaWRwb2ludChzZS5vcmlnaW4pLGkuZ2V0Tm9ybWFsKHNlLmRpcmVjdGlvbik7Y29uc3QgZT10LnJheWNhc3RGaXJzdChzZSwyKTtyZXR1cm4hIShlJiZzZS5kaXJlY3Rpb24uZG90KGUuZmFjZS5ub3JtYWwpPjApP3huOndufWZ1bmN0aW9uIE4wKGksdCl7ZnVuY3Rpb24gZSgpe3JldHVybiBNYXRoLnJhbmRvbSgpLS41fWkuZ2V0Tm9ybWFsKGdhKSxzZS5kaXJlY3Rpb24uY29weShnYSksaS5nZXRNaWRwb2ludChzZS5vcmlnaW4pO2NvbnN0IG49MztsZXQgcz0wLHI9MS8wO2ZvcihsZXQgbz0wO288bjtvKyspe3NlLmRpcmVjdGlvbi54Kz1lKCkqeGEsc2UuZGlyZWN0aW9uLnkrPWUoKSp4YSxzZS5kaXJlY3Rpb24ueis9ZSgpKnhhLHNlLmRpcmVjdGlvbi5tdWx0aXBseVNjYWxhcigtMSk7Y29uc3QgYT10LnJheWNhc3RGaXJzdChzZSwyKTtpZighIShhJiZzZS5kaXJlY3Rpb24uZG90KGEuZmFjZS5ub3JtYWwpPjApJiZzKyssYSE9PW51bGwmJihyPU1hdGgubWluKHIsYS5kaXN0YW5jZSkpLHI8PUkwKXJldHVybiBhLmZhY2Uubm9ybWFsLmRvdChnYSk+MD9RczpqcztpZihzL24+LjV8fChvLXMrMSkvbj4uNSlicmVha31yZXR1cm4gcy9uPi41P3huOndufWZ1bmN0aW9uIFIwKGksdCl7Y29uc3QgZT1uZXcgRmwsbj1uZXcgRmw7cmV0dXJuIFJsLmNvcHkoaS5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkodC5tYXRyaXhXb3JsZCksaS5nZW9tZXRyeS5ib3VuZHNUcmVlLmJ2aGNhc3QodC5nZW9tZXRyeS5ib3VuZHNUcmVlLFJsLHtpbnRlcnNlY3RzVHJpYW5nbGVzKHMscixvLGEpe2lmKCFzbihzKSYmIXNuKHIpKXtsZXQgYz1zLmludGVyc2VjdHNUcmlhbmdsZShyLCRsLCEwKTtpZighYyl7Y29uc3QgbD1zLnBsYW5lLGg9ci5wbGFuZSx1PWwubm9ybWFsLGY9aC5ub3JtYWw7dS5kb3QoZik9PT0xJiZNYXRoLmFicyhsLmNvbnN0YW50LWguY29uc3RhbnQpPGswJiYoYz0hMCl9aWYoYyl7bGV0IGw9aS5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KG8pLGg9dC5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KGEpO2UuYWRkKGwsaCksbi5hZGQoaCxsKSxLcyYmKEtzLmFkZEVkZ2UoJGwpLEtzLmFkZEludGVyc2VjdGluZ1RyaWFuZ2xlcyhvLHMsYSxyKSl9fXJldHVybiExfX0pLHthSW50ZXJzZWN0aW9uczplLGJJbnRlcnNlY3Rpb25zOm59fWZ1bmN0aW9uIEwwKGksdCxlLG4scyxyLG89ITEpe2NvbnN0IGE9ZS5hdHRyaWJ1dGVzLGM9ZS5pbmRleCxsPWkqMyxoPWMuZ2V0WChsKzApLHU9Yy5nZXRYKGwrMSksZj1jLmdldFgobCsyKTtmb3IoY29uc3QgZCBpbiByKXtjb25zdCBwPWFbZF0seT1yW2RdO2lmKCEoZCBpbiBhKSl0aHJvdyBuZXcgRXJyb3IoYENTRyBPcGVyYXRpb25zOiBBdHRyaWJ1dGUgJHtkfSBub3QgYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IG09cC5pdGVtU2l6ZTtkPT09InBvc2l0aW9uIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlNYXRyaXg0KG4pLFR0LmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLHUpLmFwcGx5TWF0cml4NChuKSxUdC5jLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxmKS5hcHBseU1hdHJpeDQobiksYmEoVHQuYSxUdC5iLFR0LmMsdCwzLHksbykpOmQ9PT0ibm9ybWFsIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHAsZikuYXBwbHlOb3JtYWxNYXRyaXgocyksbyYmKFR0LmEubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmIubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmMubXVsdGlwbHlTY2FsYXIoLTEpKSxiYShUdC5hLFR0LmIsVHQuYyx0LDMseSxvLCEwKSk6KExsLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKSxPbC5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSksRGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGYpLGJhKExsLE9sLERsLHQsbSx5LG8pKX19ZnVuY3Rpb24gTzAoaSx0LGUsbixzLHIsbyxhPSExKXtNYShpLG4scyxyLG8sYSksTWEoYT9lOnQsbixzLHIsbyxhKSxNYShhP3Q6ZSxuLHMscixvLGEpfWZ1bmN0aW9uIHFsKGksdCxlPSExKXtzd2l0Y2goaSl7Y2FzZSBQMDppZih0PT09d258fHQ9PT1RcyYmIWUpcmV0dXJuIGJuO2JyZWFrO2Nhc2UgQzA6aWYoZSl7aWYodD09PXhuKXJldHVybiAkaX1lbHNlIGlmKHQ9PT13bnx8dD09PWpzKXJldHVybiBibjticmVhaztjYXNlIEIwOmlmKGUpe2lmKHQ9PT13bnx8dD09PWpzKXJldHVybiBibn1lbHNlIGlmKHQ9PT14bilyZXR1cm4gJGk7YnJlYWs7Y2FzZSBGMDppZih0PT09eG4pcmV0dXJuICRpO2lmKHQ9PT13bilyZXR1cm4gYm47YnJlYWs7Y2FzZSBJbDppZih0PT09eG58fHQ9PT1RcyYmIWUpcmV0dXJuIGJuO2JyZWFrO2Nhc2Uga2w6aWYoIWUmJih0PT09d258fHQ9PT1qcykpcmV0dXJuIGJuO2JyZWFrO2Nhc2UgTmw6aWYoIWUmJih0PT09eG58fHQ9PT1RcykpcmV0dXJuIGJuO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgQ1NHIG9wZXJhdGlvbiBlbnVtICIke2l9Ii5gKX1yZXR1cm4gd2F9ZnVuY3Rpb24gYmEoaSx0LGUsbixzLHIsbz0hMSxhPSExKXtjb25zdCBjPWw9PntyLnB1c2gobC54KSxzPjEmJnIucHVzaChsLnkpLHM+MiYmci5wdXNoKGwueikscz4zJiZyLnB1c2gobC53KX07bWEuc2V0KDAsMCwwLDApLmFkZFNjYWxlZFZlY3RvcihpLG4uYS54KS5hZGRTY2FsZWRWZWN0b3IodCxuLmEueSkuYWRkU2NhbGVkVmVjdG9yKGUsbi5hLnopLEpzLnNldCgwLDAsMCwwKS5hZGRTY2FsZWRWZWN0b3IoaSxuLmIueCkuYWRkU2NhbGVkVmVjdG9yKHQsbi5iLnkpLmFkZFNjYWxlZFZlY3RvcihlLG4uYi56KSxZcy5zZXQoMCwwLDAsMCkuYWRkU2NhbGVkVmVjdG9yKGksbi5jLngpLmFkZFNjYWxlZFZlY3Rvcih0LG4uYy55KS5hZGRTY2FsZWRWZWN0b3IoZSxuLmMueiksYSYmKG1hLm5vcm1hbGl6ZSgpLEpzLm5vcm1hbGl6ZSgpLFlzLm5vcm1hbGl6ZSgpKSxjKG1hKSxvPyhjKFlzKSxjKEpzKSk6KGMoSnMpLGMoWXMpKX1mdW5jdGlvbiBNYShpLHQsZSxuLHMscj0hMSl7Zm9yKGNvbnN0IG8gaW4gcyl7Y29uc3QgYT10W29dLGM9c1tvXTtpZighKG8gaW4gdCkpdGhyb3cgbmV3IEVycm9yKGBDU0cgT3BlcmF0aW9uczogQXR0cmlidXRlICR7b30gbm8gYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IGw9YS5pdGVtU2l6ZTtvPT09InBvc2l0aW9uIj8oUmUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGkpLmFwcGx5TWF0cml4NChlKSxjLnB1c2goUmUueCxSZS55LFJlLnopKTpvPT09Im5vcm1hbCI/KFJlLmZyb21CdWZmZXJBdHRyaWJ1dGUoYSxpKS5hcHBseU5vcm1hbE1hdHJpeChuKSxyJiZSZS5tdWx0aXBseVNjYWxhcigtMSksYy5wdXNoKFJlLngsUmUueSxSZS56KSk6KGMucHVzaChhLmdldFgoaSkpLGw+MSYmYy5wdXNoKGEuZ2V0WShpKSksbD4yJiZjLnB1c2goYS5nZXRaKGkpKSxsPjMmJmMucHVzaChhLmdldFcoaSkpKX19Y2xhc3MgRDB7Y29uc3RydWN0b3IodCl7dGhpcy50cmlhbmdsZT1uZXcgZXQoKS5jb3B5KHQpLHRoaXMuaW50ZXJzZWN0cz17fX1hZGRUcmlhbmdsZSh0LGUpe3RoaXMuaW50ZXJzZWN0c1t0XT1uZXcgZXQoKS5jb3B5KGUpfWdldEludGVyc2VjdEFycmF5KCl7Y29uc3QgdD1bXSx7aW50ZXJzZWN0czplfT10aGlzO2Zvcihjb25zdCBuIGluIGUpdC5wdXNoKGVbbl0pO3JldHVybiB0fX1jbGFzcyBIbHtjb25zdHJ1Y3Rvcigpe3RoaXMuZGF0YT17fX1hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKXtjb25zdHtkYXRhOnJ9PXRoaXM7clt0XXx8KHJbdF09bmV3IEQwKGUpKSxyW3RdLmFkZFRyaWFuZ2xlKG4scyl9Z2V0VHJpYW5nbGVzQXNBcnJheSh0PW51bGwpe2NvbnN0e2RhdGE6ZX09dGhpcyxuPVtdO2lmKHQhPT1udWxsKXQgaW4gZSYmbi5wdXNoKGVbdF0udHJpYW5nbGUpO2Vsc2UgZm9yKGNvbnN0IHMgaW4gZSluLnB1c2goZVtzXS50cmlhbmdsZSk7cmV0dXJuIG59Z2V0VHJpYW5nbGVJbmRpY2VzKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubWFwKHQ9PnBhcnNlSW50KHQpKX1nZXRJbnRlcnNlY3Rpb25JbmRpY2VzKHQpe2NvbnN0e2RhdGE6ZX09dGhpcztyZXR1cm4gZVt0XT9PYmplY3Qua2V5cyhlW3RdLmludGVyc2VjdHMpLm1hcChuPT5wYXJzZUludChuKSk6W119Z2V0SW50ZXJzZWN0aW9uc0FzQXJyYXkodD1udWxsLGU9bnVsbCl7Y29uc3R7ZGF0YTpufT10aGlzLHM9bmV3IFNldCxyPVtdLG89YT0+e2lmKG5bYV0paWYoZSE9PW51bGwpblthXS5pbnRlcnNlY3RzW2VdJiZyLnB1c2goblthXS5pbnRlcnNlY3RzW2VdKTtlbHNle2NvbnN0IGM9blthXS5pbnRlcnNlY3RzO2Zvcihjb25zdCBsIGluIGMpcy5oYXMobCl8fChzLmFkZChsKSxyLnB1c2goY1tsXSkpfX07aWYodCE9PW51bGwpbyh0KTtlbHNlIGZvcihjb25zdCBhIGluIG4pbyhhKTtyZXR1cm4gcn1yZXNldCgpe3RoaXMuZGF0YT17fX19Y2xhc3MgJDB7Y29uc3RydWN0b3IoKXt0aGlzLmVuYWJsZWQ9ITEsdGhpcy50cmlhbmdsZUludGVyc2VjdHNBPW5ldyBIbCx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0I9bmV3IEhsLHRoaXMuaW50ZXJzZWN0aW9uRWRnZXM9W119YWRkSW50ZXJzZWN0aW5nVHJpYW5nbGVzKHQsZSxuLHMpe2NvbnN0e3RyaWFuZ2xlSW50ZXJzZWN0c0E6cix0cmlhbmdsZUludGVyc2VjdHNCOm99PXRoaXM7ci5hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKSxvLmFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKG4scyx0LGUpfWFkZEVkZ2UodCl7dGhpcy5pbnRlcnNlY3Rpb25FZGdlcy5wdXNoKHQuY2xvbmUoKSl9cmVzZXQoKXt0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0EucmVzZXQoKSx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0IucmVzZXQoKSx0aGlzLmludGVyc2VjdGlvbkVkZ2VzPVtdfWluaXQoKXt0aGlzLmVuYWJsZWQmJih0aGlzLnJlc2V0KCksVmwodGhpcykpfWNvbXBsZXRlKCl7dGhpcy5lbmFibGVkJiZWbChudWxsKX19Y29uc3Qgcm49bmV3IHN0LHRyPW5ldyBnZSxNbj1uZXcgZXQsZXI9bmV3IGV0LG9uPW5ldyBldCxucj1uZXcgZXQsZGU9W10sQW49W107ZnVuY3Rpb24gVjAoaSl7Zm9yKGNvbnN0IHQgb2YgaSlyZXR1cm4gdH1mdW5jdGlvbiBVMChpLHQsZSxuLHMscj17fSl7Y29uc3R7dXNlR3JvdXBzOm89ITB9PXIse2FJbnRlcnNlY3Rpb25zOmEsYkludGVyc2VjdGlvbnM6Y309UjAoaSx0KSxsPVtdO2xldCBoPW51bGwsdTtyZXR1cm4gdT1vPzA6LTEsV2woaSx0LGEsZSwhMSxuLHMsdSksR2woaSx0LGEsZSwhMSxzLHUpLGUuZmluZEluZGV4KGQ9PmQhPT1ObCYmZCE9PWtsKSE9PS0xJiYodT1vP2kuZ2VvbWV0cnkuZ3JvdXBzLmxlbmd0aHx8MTotMSxXbCh0LGksYyxlLCEwLG4scyx1KSxHbCh0LGksYyxlLCEwLHMsdSkpLGRlLmxlbmd0aD0wLEFuLmxlbmd0aD0wLHtncm91cHM6bCxtYXRlcmlhbHM6aH19ZnVuY3Rpb24gV2woaSx0LGUsbixzLHIsbyxhPTApe2NvbnN0IGM9aS5tYXRyaXhXb3JsZC5kZXRlcm1pbmFudCgpPDA7cm4uY29weSh0Lm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseShpLm1hdHJpeFdvcmxkKSx0ci5nZXROb3JtYWxNYXRyaXgoaS5tYXRyaXhXb3JsZCkubXVsdGlwbHlTY2FsYXIoYz8tMToxKTtjb25zdCBsPWkuZ2VvbWV0cnkuZ3JvdXBJbmRpY2VzLGg9aS5nZW9tZXRyeS5pbmRleCx1PWkuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixmPXQuZ2VvbWV0cnkuYm91bmRzVHJlZSxkPXQuZ2VvbWV0cnkuaW5kZXgscD10Lmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb24seT1lLmlkcyxtPWUuaW50ZXJzZWN0aW9uU2V0O2ZvcihsZXQgZz0wLGI9eS5sZW5ndGg7ZzxiO2crKyl7Y29uc3Qgdz15W2ddLHg9YT09PS0xPzA6bFt3XSthLE09Myp3LEE9aC5nZXRYKE0rMCksUz1oLmdldFgoTSsxKSxfPWguZ2V0WChNKzIpO01uLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LEEpLmFwcGx5TWF0cml4NChybiksTW4uYi5mcm9tQnVmZmVyQXR0cmlidXRlKHUsUykuYXBwbHlNYXRyaXg0KHJuKSxNbi5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodSxfKS5hcHBseU1hdHJpeDQocm4pLHIucmVzZXQoKSxyLmluaXRpYWxpemUoTW4pO2NvbnN0IEU9bVt3XTtmb3IobGV0IHY9MCxDPUUubGVuZ3RoO3Y8Qzt2Kyspe2NvbnN0IFA9MypFW3ZdLEY9ZC5nZXRYKFArMCksQj1kLmdldFgoUCsxKSxJPWQuZ2V0WChQKzIpO2VyLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEYpLGVyLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEIpLGVyLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEkpLHIuc3BsaXRCeVRyaWFuZ2xlKGVyKX1jb25zdCB6PXIudHJpYW5nbGVzO2ZvcihsZXQgdj0wLEM9ei5sZW5ndGg7djxDO3YrKyl7Y29uc3QgUD16W3ZdLEY9ci5jb3BsYW5hclRyaWFuZ2xlVXNlZD9OMChQLGYpOlVsKFAsZik7ZGUubGVuZ3RoPTAsQW4ubGVuZ3RoPTA7Zm9yKGxldCBCPTAsST1uLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPXFsKG5bQl0sRixzKTtrIT09d2EmJihBbi5wdXNoKGspLGRlLnB1c2gob1tCXS5nZXRHcm91cEF0dHJTZXQoeCkpKX1pZihkZS5sZW5ndGghPT0wKXtNbi5nZXRCYXJ5Y29vcmQoUC5hLG5yLmEpLE1uLmdldEJhcnljb29yZChQLmIsbnIuYiksTW4uZ2V0QmFyeWNvb3JkKFAuYyxuci5jKTtmb3IobGV0IEI9MCxJPWRlLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPWRlW0JdLFU9QW5bQl09PT0kaTtMMCh3LG5yLGkuZ2VvbWV0cnksaS5tYXRyaXhXb3JsZCx0cixrLGMhPT1VKX19fX1yZXR1cm4geS5sZW5ndGh9ZnVuY3Rpb24gR2woaSx0LGUsbixzLHIsbz0wKXtjb25zdCBhPWkubWF0cml4V29ybGQuZGV0ZXJtaW5hbnQoKTwwO3JuLmNvcHkodC5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkoaS5tYXRyaXhXb3JsZCksdHIuZ2V0Tm9ybWFsTWF0cml4KGkubWF0cml4V29ybGQpLm11bHRpcGx5U2NhbGFyKGE/LTE6MSk7Y29uc3QgYz10Lmdlb21ldHJ5LmJvdW5kc1RyZWUsbD1pLmdlb21ldHJ5Lmdyb3VwSW5kaWNlcyxoPWkuZ2VvbWV0cnkuaW5kZXgsdT1pLmdlb21ldHJ5LmF0dHJpYnV0ZXMsZj11LnBvc2l0aW9uLGQ9W10scD1pLmdlb21ldHJ5LmhhbGZFZGdlcyx5PW5ldyBTZXQsbT1hYShpLmdlb21ldHJ5KTtmb3IobGV0IGc9MCxiPW07ZzxiO2crKylnIGluIGUuaW50ZXJzZWN0aW9uU2V0fHx5LmFkZChnKTtmb3IoO3kuc2l6ZT4wOyl7Y29uc3QgZz1WMCh5KTt5LmRlbGV0ZShnKSxkLnB1c2goZyk7Y29uc3QgYj0zKmcsdz1oLmdldFgoYiswKSx4PWguZ2V0WChiKzEpLE09aC5nZXRYKGIrMik7b24uYS5mcm9tQnVmZmVyQXR0cmlidXRlKGYsdykuYXBwbHlNYXRyaXg0KHJuKSxvbi5iLmZyb21CdWZmZXJBdHRyaWJ1dGUoZix4KS5hcHBseU1hdHJpeDQocm4pLG9uLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLE0pLmFwcGx5TWF0cml4NChybik7Y29uc3QgQT1VbChvbixjKTtBbi5sZW5ndGg9MCxkZS5sZW5ndGg9MDtmb3IobGV0IFM9MCxfPW4ubGVuZ3RoO1M8XztTKyspe2NvbnN0IEU9cWwobltTXSxBLHMpO0UhPT13YSYmKEFuLnB1c2goRSksZGUucHVzaChyW1NdKSl9Zm9yKDtkLmxlbmd0aD4wOyl7Y29uc3QgUz1kLnBvcCgpO2ZvcihsZXQgXz0wO188MztfKyspe2NvbnN0IEU9cC5nZXRTaWJsaW5nVHJpYW5nbGVJbmRleChTLF8pO0UhPT0tMSYmeS5oYXMoRSkmJihkLnB1c2goRSkseS5kZWxldGUoRSkpfWlmKGRlLmxlbmd0aCE9PTApe2NvbnN0IF89MypTLEU9aC5nZXRYKF8rMCksej1oLmdldFgoXysxKSx2PWguZ2V0WChfKzIpLEM9bz09PS0xPzA6bFtTXStvO2lmKG9uLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLEUpLG9uLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHopLG9uLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHYpLCFzbihvbikpZm9yKGxldCBQPTAsRj1kZS5sZW5ndGg7UDxGO1ArKyl7Y29uc3QgQj1BbltQXSxJPWRlW1BdLmdldEdyb3VwQXR0clNldChDKSxrPUI9PT0kaTtPMChFLHosdix1LGkubWF0cml4V29ybGQsdHIsSSxrIT09YSl9fX19fWZ1bmN0aW9uIHEwKGkpe2ZvcihsZXQgdD0wO3Q8aS5sZW5ndGgtMTt0Kyspe2NvbnN0IGU9aVt0XSxuPWlbdCsxXTtpZihlLm1hdGVyaWFsSW5kZXg9PT1uLm1hdGVyaWFsSW5kZXgpe2NvbnN0IHM9ZS5zdGFydCxyPW4uc3RhcnQrbi5jb3VudDtuLnN0YXJ0PXMsbi5jb3VudD1yLXMsaS5zcGxpY2UodCwxKSx0LS19fX1mdW5jdGlvbiBIMChpLHQsZSxuKXtlLmNsZWFyKCk7Y29uc3Qgcz1pLmF0dHJpYnV0ZXM7Zm9yKGxldCByPTAsbz1uLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPW5bcl0sYz1zW2FdO2UuaW5pdGlhbGl6ZUFycmF5KGEsYy5hcnJheS5jb25zdHJ1Y3RvcixjLml0ZW1TaXplLGMubm9ybWFsaXplZCl9Zm9yKGNvbnN0IHIgaW4gZS5hdHRyaWJ1dGVzKW4uaW5jbHVkZXMocil8fGUuZGVsZXRlKHIpO2Zvcihjb25zdCByIGluIHQuYXR0cmlidXRlcyluLmluY2x1ZGVzKHIpfHwodC5kZWxldGVBdHRyaWJ1dGUociksdC5kaXNwb3NlKCkpfWZ1bmN0aW9uIFcwKGksdCxlKXtsZXQgbj0hMSxzPS0xO2NvbnN0IHI9aS5hdHRyaWJ1dGVzLG89dC5ncm91cEF0dHJpYnV0ZXNbMF07Zm9yKGNvbnN0IGMgaW4gbyl7Y29uc3QgbD10LmdldFRvdGFsTGVuZ3RoKGMpLGg9dC5nZXRUeXBlKGMpLHU9dC5nZXRJdGVtU2l6ZShjKSxmPXQuZ2V0Tm9ybWFsaXplZChjKTtsZXQgZD1yW2NdOyghZHx8ZC5hcnJheS5sZW5ndGg8bCkmJihkPW5ldyB4dChuZXcgaChsKSx1LGYpLGkuc2V0QXR0cmlidXRlKGMsZCksbj0hMCk7bGV0IHA9MDtmb3IobGV0IHk9MCxtPU1hdGgubWluKGUubGVuZ3RoLHQuZ3JvdXBDb3VudCk7eTxtO3krKyl7Y29uc3QgZz1lW3ldLmluZGV4LHthcnJheTpiLHR5cGU6dyxsZW5ndGg6eH09dC5ncm91cEF0dHJpYnV0ZXNbZ11bY10sTT1uZXcgdyhiLmJ1ZmZlciwwLHgpO2QuYXJyYXkuc2V0KE0scCkscCs9TS5sZW5ndGh9ZC5uZWVkc1VwZGF0ZT0hMCxzPWwvZC5pdGVtU2l6ZX1pZihpLmluZGV4KXtjb25zdCBjPWkuaW5kZXguYXJyYXk7aWYoYy5sZW5ndGg8cylpLmluZGV4PW51bGwsbj0hMDtlbHNlIGZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyljW2xdPWx9bGV0IGE9MDtpLmNsZWFyR3JvdXBzKCk7Zm9yKGxldCBjPTAsbD1NYXRoLm1pbihlLmxlbmd0aCx0Lmdyb3VwQ291bnQpO2M8bDtjKyspe2NvbnN0e2luZGV4OmgsbWF0ZXJpYWxJbmRleDp1fT1lW2NdLGY9dC5nZXRDb3VudChoKTtmIT09MCYmKGkuYWRkR3JvdXAoYSxmLHUpLGErPWYpfWkuc2V0RHJhd1JhbmdlKDAscyksaS5ib3VuZHNUcmVlPW51bGwsbiYmaS5kaXNwb3NlKCl9ZnVuY3Rpb24gWmwoaSx0KXtsZXQgZT10O3JldHVybiBBcnJheS5pc0FycmF5KHQpfHwoZT1bXSxpLmZvckVhY2gobj0+e2Vbbi5tYXRlcmlhbEluZGV4XT10fSkpLGV9Y2xhc3MgRzB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlU3BsaXR0ZXI9bmV3IHowLHRoaXMuYXR0cmlidXRlRGF0YT1bXSx0aGlzLmF0dHJpYnV0ZXM9WyJwb3NpdGlvbiIsInV2Iiwibm9ybWFsIl0sdGhpcy51c2VHcm91cHM9ITAsdGhpcy5jb25zb2xpZGF0ZUdyb3Vwcz0hMCx0aGlzLmRlYnVnPW5ldyAkMH1nZXRHcm91cFJhbmdlcyh0KXtyZXR1cm4hdGhpcy51c2VHcm91cHN8fHQuZ3JvdXBzLmxlbmd0aD09PTA/W3tzdGFydDowLGNvdW50OjEvMCxtYXRlcmlhbEluZGV4OjB9XTp0Lmdyb3Vwcy5tYXAoZT0+RnQoe30sZSkpfWV2YWx1YXRlKHQsZSxuLHM9bmV3IFpzKXtsZXQgcj0hMDtpZihBcnJheS5pc0FycmF5KG4pfHwobj1bbl0pLEFycmF5LmlzQXJyYXkocyl8fChzPVtzXSxyPSExKSxzLmxlbmd0aCE9PW4ubGVuZ3RoKXRocm93IG5ldyBFcnJvcigiRXZhbHVhdG9yOiBvcGVyYXRpb25zIGFuZCB0YXJnZXQgYXJyYXkgcGFzc2VkIGFzIGRpZmZlcmVudCBzaXplcy4iKTt0LnByZXBhcmVHZW9tZXRyeSgpLGUucHJlcGFyZUdlb21ldHJ5KCk7Y29uc3R7dHJpYW5nbGVTcGxpdHRlcjpvLGF0dHJpYnV0ZURhdGE6YSxhdHRyaWJ1dGVzOmMsdXNlR3JvdXBzOmwsY29uc29saWRhdGVHcm91cHM6aCxkZWJ1Zzp1fT10aGlzO2Zvcig7YS5sZW5ndGg8cy5sZW5ndGg7KWEucHVzaChuZXcgRTApO3MuZm9yRWFjaCgoZyxiKT0+e0gwKHQuZ2VvbWV0cnksZy5nZW9tZXRyeSxhW2JdLGMpfSksdS5pbml0KCksVTAodCxlLG4sbyxhLHt1c2VHcm91cHM6bH0pLHUuY29tcGxldGUoKTtjb25zdCBmPXRoaXMuZ2V0R3JvdXBSYW5nZXModC5nZW9tZXRyeSksZD1abChmLHQubWF0ZXJpYWwpLHA9dGhpcy5nZXRHcm91cFJhbmdlcyhlLmdlb21ldHJ5KSx5PVpsKHAsZS5tYXRlcmlhbCk7cC5mb3JFYWNoKGc9PmcubWF0ZXJpYWxJbmRleCs9ZC5sZW5ndGgpO2xldCBtPVsuLi5mLC4uLnBdLm1hcCgoZyxiKT0+WmUoRnQoe30sZykse2luZGV4OmJ9KSk7aWYobCl7Y29uc3QgZz1bLi4uZCwuLi55XTtoJiYobT1tLm1hcCh3PT57Y29uc3QgeD1nW3cubWF0ZXJpYWxJbmRleF07cmV0dXJuIHcubWF0ZXJpYWxJbmRleD1nLmluZGV4T2YoeCksd30pLnNvcnQoKHcseCk9PncubWF0ZXJpYWxJbmRleC14Lm1hdGVyaWFsSW5kZXgpKTtjb25zdCBiPVtdO2ZvcihsZXQgdz0wLHg9Zy5sZW5ndGg7dzx4O3crKyl7bGV0IE09ITE7Zm9yKGxldCBBPTAsUz1tLmxlbmd0aDtBPFM7QSsrKXtjb25zdCBfPW1bQV07Xy5tYXRlcmlhbEluZGV4PT09dyYmKE09ITAsXy5tYXRlcmlhbEluZGV4PWIubGVuZ3RoKX1NJiZiLnB1c2goZ1t3XSl9cy5mb3JFYWNoKHc9Pnt3Lm1hdGVyaWFsPWJ9KX1lbHNlIG09W3tzdGFydDowLGNvdW50OjEvMCxpbmRleDowLG1hdGVyaWFsSW5kZXg6MH1dLHMuZm9yRWFjaChnPT57Zy5tYXRlcmlhbD1kWzBdfSk7cmV0dXJuIHMuZm9yRWFjaCgoZyxiKT0+e2NvbnN0IHc9Zy5nZW9tZXRyeTtXMCh3LGFbYl0sbSksaCYmcTAody5ncm91cHMpfSkscj9zOnNbMF19ZXZhbHVhdGVIaWVyYXJjaHkodCxlPW5ldyBacyl7dC51cGRhdGVNYXRyaXhXb3JsZCghMCk7Y29uc3Qgbj0ocixvKT0+e2NvbnN0IGE9ci5jaGlsZHJlbjtmb3IobGV0IGM9MCxsPWEubGVuZ3RoO2M8bDtjKyspe2NvbnN0IGg9YVtjXTtoLmlzT3BlcmF0aW9uR3JvdXA/bihoLG8pOm8oaCl9fSxzPXI9Pntjb25zdCBvPXIuY2hpbGRyZW47bGV0IGE9ITE7Zm9yKGxldCBsPTAsaD1vLmxlbmd0aDtsPGg7bCsrKXtjb25zdCB1PW9bbF07YT1zKHUpfHxhfWNvbnN0IGM9ci5pc0RpcnR5KCk7aWYoYyYmci5tYXJrVXBkYXRlZCgpLGEmJiFyLmlzT3BlcmF0aW9uR3JvdXApe2xldCBsO3JldHVybiBuKHIsaD0+e2w/bD10aGlzLmV2YWx1YXRlKGwsaCxoLm9wZXJhdGlvbik6bD10aGlzLmV2YWx1YXRlKHIsaCxoLm9wZXJhdGlvbil9KSxyLl9jYWNoZWRHZW9tZXRyeT1sLmdlb21ldHJ5LHIuX2NhY2hlZE1hdGVyaWFscz1sLm1hdGVyaWFsLCEwfWVsc2UgcmV0dXJuIGF8fGN9O3JldHVybiBzKHQpLGUuZ2VvbWV0cnk9dC5fY2FjaGVkR2VvbWV0cnksZS5tYXRlcmlhbD10Ll9jYWNoZWRNYXRlcmlhbHMsZX1yZXNldCgpe3RoaXMudHJpYW5nbGVTcGxpdHRlci5yZXNldCgpfX1mdW5jdGlvbiBYbChpKXtsZXQgdCxlLG4scz0tMSxyPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZih0PT09dm9pZCAwJiYodD1oLmFycmF5LmNvbnN0cnVjdG9yKSx0IT09aC5hcnJheS5jb25zdHJ1Y3RvcilyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmFycmF5IG11c3QgYmUgb2YgY29uc2lzdGVudCBhcnJheSB0eXBlcyBhY3Jvc3MgbWF0Y2hpbmcgYXR0cmlidXRlcy4iKSxudWxsO2lmKGU9PT12b2lkIDAmJihlPWguaXRlbVNpemUpLGUhPT1oLml0ZW1TaXplKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuaXRlbVNpemUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7aWYobj09PXZvaWQgMCYmKG49aC5ub3JtYWxpemVkKSxuIT09aC5ub3JtYWxpemVkKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUubm9ybWFsaXplZCBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihzPT09LTEmJihzPWguZ3B1VHlwZSkscyE9PWguZ3B1VHlwZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmdwdVR5cGUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7cis9aC5jb3VudCplfWNvbnN0IG89bmV3IHQociksYT1uZXcgeHQobyxlLG4pO2xldCBjPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZihoLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpe2NvbnN0IHU9Yy9lO2ZvcihsZXQgZj0wLGQ9aC5jb3VudDtmPGQ7ZisrKWZvcihsZXQgcD0wO3A8ZTtwKyspe2NvbnN0IHk9aC5nZXRDb21wb25lbnQoZixwKTthLnNldENvbXBvbmVudChmK3UscCx5KX19ZWxzZSBvLnNldChoLmFycmF5LGMpO2MrPWguY291bnQqZX1yZXR1cm4gcyE9PXZvaWQgMCYmKGEuZ3B1VHlwZT1zKSxhfWZ1bmN0aW9uIFowKGkpe2lmKGkuZ3JvdXBzLmxlbmd0aD09PTApcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlscy5tZXJnZUdyb3VwcygpOiBObyBncm91cHMgYXJlIGRlZmluZWQuIE5vdGhpbmcgdG8gbWVyZ2UuIiksaTtsZXQgdD1pLmdyb3VwcztpZih0PXQuc29ydCgobyxhKT0+by5tYXRlcmlhbEluZGV4IT09YS5tYXRlcmlhbEluZGV4P28ubWF0ZXJpYWxJbmRleC1hLm1hdGVyaWFsSW5kZXg6by5zdGFydC1hLnN0YXJ0KSxpLmdldEluZGV4KCk9PT1udWxsKXtjb25zdCBvPWkuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLGE9W107Zm9yKGxldCBjPTA7YzxvLmNvdW50O2MrPTMpYS5wdXNoKGMsYysxLGMrMik7aS5zZXRJbmRleChhKX1jb25zdCBlPWkuZ2V0SW5kZXgoKSxuPVtdO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb10sYz1hLnN0YXJ0LGw9YythLmNvdW50O2ZvcihsZXQgaD1jO2g8bDtoKyspbi5wdXNoKGUuZ2V0WChoKSl9aS5kaXNwb3NlKCksaS5zZXRJbmRleChuKTtsZXQgcz0wO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb107YS5zdGFydD1zLHMrPWEuY291bnR9bGV0IHI9dFswXTtpLmdyb3Vwcz1bcl07Zm9yKGxldCBvPTE7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXTtyLm1hdGVyaWFsSW5kZXg9PT1hLm1hdGVyaWFsSW5kZXg/ci5jb3VudCs9YS5jb3VudDoocj1hLGkuZ3JvdXBzLnB1c2gocikpfXJldHVybiBpfWZ1bmN0aW9uIEpsKGksdD0wKXtjb25zdCBlPWlbMF0uaW5kZXghPT1udWxsLG49bmV3IFNldChPYmplY3Qua2V5cyhpWzBdLmF0dHJpYnV0ZXMpKSxzPW5ldyBTZXQoT2JqZWN0LmtleXMoaVswXS5tb3JwaEF0dHJpYnV0ZXMpKSxyPXt9LG89e30sYT1pWzBdLm1vcnBoVGFyZ2V0c1JlbGF0aXZlLGM9bmV3IHVlO2xldCBsPTA7Zm9yKGxldCBoPTA7aDxpLmxlbmd0aDsrK2gpe2NvbnN0IHU9aVtoXTtsZXQgZj0wO2lmKGUhPT0odS5pbmRleCE9PW51bGwpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIEFsbCBnZW9tZXRyaWVzIG11c3QgaGF2ZSBjb21wYXRpYmxlIGF0dHJpYnV0ZXM7IG1ha2Ugc3VyZSBpbmRleCBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1LmF0dHJpYnV0ZXMpe2lmKCFuLmhhcyhkKSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsnLiBBbGwgZ2VvbWV0cmllcyBtdXN0IGhhdmUgY29tcGF0aWJsZSBhdHRyaWJ1dGVzOyBtYWtlIHN1cmUgIicrZCsnIiBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uJyksbnVsbDtyW2RdPT09dm9pZCAwJiYocltkXT1bXSkscltkXS5wdXNoKHUuYXR0cmlidXRlc1tkXSksZisrfWlmKGYhPT1uLnNpemUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gTWFrZSBzdXJlIGFsbCBnZW9tZXRyaWVzIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihhIT09dS5tb3JwaFRhcmdldHNSZWxhdGl2ZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiAubW9ycGhUYXJnZXRzUmVsYXRpdmUgbXVzdCBiZSBjb25zaXN0ZW50IHRocm91Z2hvdXQgYWxsIGdlb21ldHJpZXMuIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1Lm1vcnBoQXR0cmlidXRlcyl7aWYoIXMuaGFzKGQpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuICAubW9ycGhBdHRyaWJ1dGVzIG11c3QgYmUgY29uc2lzdGVudCB0aHJvdWdob3V0IGFsbCBnZW9tZXRyaWVzLiIpLG51bGw7b1tkXT09PXZvaWQgMCYmKG9bZF09W10pLG9bZF0ucHVzaCh1Lm1vcnBoQXR0cmlidXRlc1tkXSl9aWYodCl7bGV0IGQ7aWYoZSlkPXUuaW5kZXguY291bnQ7ZWxzZSBpZih1LmF0dHJpYnV0ZXMucG9zaXRpb24hPT12b2lkIDApZD11LmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQ7ZWxzZSByZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiBUaGUgZ2VvbWV0cnkgbXVzdCBoYXZlIGVpdGhlciBhbiBpbmRleCBvciBhIHBvc2l0aW9uIGF0dHJpYnV0ZSIpLG51bGw7aWYodD09PTEpYy5hZGRHcm91cChsLGQsaCk7ZWxzZSBpZih0PT09MiYmdS5ncm91cHMubGVuZ3RoPjApZm9yKGxldCBwIG9mIHUuZ3JvdXBzKXtsZXQgeT1wLm1hdGVyaWFsSW5kZXg7Yy5hZGRHcm91cChsK3Auc3RhcnQsTWF0aC5taW4ocC5jb3VudCxkKSx5KX1sKz1kfX1pZihlKXtsZXQgaD0wO2NvbnN0IHU9W107Zm9yKGxldCBmPTA7ZjxpLmxlbmd0aDsrK2Ype2NvbnN0IGQ9aVtmXS5pbmRleDtmb3IobGV0IHA9MDtwPGQuY291bnQ7KytwKXUucHVzaChkLmdldFgocCkraCk7aCs9aVtmXS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWMuc2V0SW5kZXgodSl9Zm9yKGNvbnN0IGggaW4gcil7Y29uc3QgdT1YbChyW2hdKTtpZighdSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIGF0dHJpYnV0ZS4iKSxudWxsO2Muc2V0QXR0cmlidXRlKGgsdSl9Zm9yKGNvbnN0IGggaW4gbyl7Y29uc3QgdT1vW2hdWzBdLmxlbmd0aDtpZih1PT09MClicmVhaztjLm1vcnBoQXR0cmlidXRlcz1jLm1vcnBoQXR0cmlidXRlc3x8e30sYy5tb3JwaEF0dHJpYnV0ZXNbaF09W107Zm9yKGxldCBmPTA7Zjx1OysrZil7Y29uc3QgZD1bXTtmb3IobGV0IHk9MDt5PG9baF0ubGVuZ3RoOysreSlkLnB1c2gob1toXVt5XVtmXSk7Y29uc3QgcD1YbChkKTtpZighcClyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIG1vcnBoQXR0cmlidXRlLiIpLG51bGw7Yy5tb3JwaEF0dHJpYnV0ZXNbaF0ucHVzaChwKX19cmV0dXJuIHQ9PT0yP1owKGMpOmN9Y2xhc3MgWDAgZXh0ZW5kcyBHbntjb25zdHJ1Y3Rvcih0LGUpe3N1cGVyKHQsZSk7Y29uc3Qgbj1uZXcgWnMobmV3IEduKHQsWmUoRnQoe30sZSkse2hhc1RvcDohMCxoYXNTaWRlOiEwLGhhc0JvdHRvbTohMX0pKSk7bi51cGRhdGVNYXRyaXhXb3JsZCgpO2NvbnN0IHM9bmV3IGd0KCkuc2V0RnJvbU9iamVjdChuKSxyPW5ldyBUO3MuZ2V0U2l6ZShyKTtjb25zdCBvPW5ldyBUKHMubWluLngrci54LzIscy5taW4ueStyLnkvMiwwKTtsZXQgYT1lLnRvcFNlZ21lbnRzLGM9ZS5ib3gzO2lmKGMpe2M9Yy51bmlvbihzKTtjb25zdCBnPW5ldyBUO2MuZ2V0U2l6ZShnKTtjb25zdCBiPU1hdGgubWF4KHIueC9nLngsci55L2cueSk7YT1NYXRoLmNlaWwoZS50b3BTZWdtZW50cypiKX1pZihhPDQpcmV0dXJuIHRoaXM7Y29uc3QgbD1uZXcgTG8oci54LHIueSxhLGEpLGg9bmV3IFpzKGwpO2gucG9zaXRpb24uc2V0KG8ueCxvLnksby56KSxoLnVwZGF0ZU1hdHJpeFdvcmxkKCk7Y29uc3QgZj1uZXcgRzAoKS5ldmFsdWF0ZShoLG4sSWwpLGQ9Zi5nZW9tZXRyeS5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIikscD1uZXcgQmUoZC5jb3VudCoyLDIpO2ZvcihsZXQgZz0wO2c8ZC5jb3VudDtnKyspe2NvbnN0IGI9ZC5nZXRaKGcpO2Quc2V0WihnLGUuZGVwdGgrYil9aWYoYyl7Y29uc3QgZz1jLm1pbixiPWMubWF4LHc9bmV3IFQoKS5zdWJWZWN0b3JzKGIsZyk7Zm9yKGxldCB4PTA7eDxkLmNvdW50O3grKyl7Y29uc3QgTT1kLmdldFgoeCksQT1kLmdldFkoeCksUz0oTS1nLngpL3cueCxfPShBLWcueSkvdy55O3Auc2V0WFkoeCxTLF8pfWYuZ2VvbWV0cnkuc2V0QXR0cmlidXRlKCJ1diIscCl9ZC5uZWVkc1VwZGF0ZT0hMDtjb25zdCB5PW5ldyBHbih0LFplKEZ0KHt9LGUpLHtoYXNUb3A6ITF9KSksbT1KbChbZi5nZW9tZXRyeSx5XSwyKTt0aGlzLmNvcHkobS50b05vbkluZGV4ZWQoKSl9fXZhciBKMD1pPT57Y29uc3R7c3BsaXQ6dCxkZXB0aDplLHBvaW50czpuLGJveDM6cyxoYXNUb3A6cixoYXNCb3R0b206byxoYXNTaWRlOmEsc2lkZVJlcGVhdDpjLHRvcFNlZ21lbnRzOmx9PWksaD1sP1gwOkduLHU9bmV3IGgobmV3IFhjKG4pLHtkZXB0aDplLGJldmVsRW5hYmxlZDohMSxib3gzOnMsVVZHZW5lcmF0b3I6WWYoe3NwbGl0OnQsYm94MzpzLHNpZGVSZXBlYXQ6Y30pLGhhc1RvcDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSx0b3BTZWdtZW50czpsfSk7cmV0dXJuIGpmKCksdX07ZnVuY3Rpb24gWTAoaSx0LGU9MCl7Y29uc3Qgbj0oOTAtdCkqTWF0aC5QSS8xODAscz0oOTAtaSkqTWF0aC5QSS8xODA7cmV0dXJuW2UqTWF0aC5zaW4obikqTWF0aC5jb3MocyksZSpNYXRoLmNvcyhuKSxlKk1hdGguc2luKG4pKk1hdGguc2luKHMpXX1mdW5jdGlvbiBpcihpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjppPHQ/LTE6aT50PzE6aT49dD8wOk5hTn1mdW5jdGlvbiBqMChpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjp0PGk/LTE6dD5pPzE6dD49aT8wOk5hTn1mdW5jdGlvbiBZbChpKXtsZXQgdCxlLG47aS5sZW5ndGghPT0yPyh0PWlyLGU9KGEsYyk9PmlyKGkoYSksYyksbj0oYSxjKT0+aShhKS1jKToodD1pPT09aXJ8fGk9PT1qMD9pOlEwLGU9aSxuPWkpO2Z1bmN0aW9uIHMoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTwwP2w9dSsxOmg9dX13aGlsZShsPGgpfXJldHVybiBsfWZ1bmN0aW9uIHIoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTw9MD9sPXUrMTpoPXV9d2hpbGUobDxoKX1yZXR1cm4gbH1mdW5jdGlvbiBvKGEsYyxsPTAsaD1hLmxlbmd0aCl7Y29uc3QgdT1zKGEsYyxsLGgtMSk7cmV0dXJuIHU+bCYmbihhW3UtMV0sYyk+LW4oYVt1XSxjKT91LTE6dX1yZXR1cm57bGVmdDpzLGNlbnRlcjpvLHJpZ2h0OnJ9fWZ1bmN0aW9uIFEwKCl7cmV0dXJuIDB9ZnVuY3Rpb24gSzAoaSl7cmV0dXJuIGk9PT1udWxsP05hTjoraX1jb25zdCB0cD1ZbChpcikucmlnaHQ7WWwoSzApLmNlbnRlcjtmdW5jdGlvbiBzcihpLHQpe2xldCBlLG47aWYodD09PXZvaWQgMClmb3IoY29uc3QgcyBvZiBpKXMhPW51bGwmJihlPT09dm9pZCAwP3M+PXMmJihlPW49cyk6KGU+cyYmKGU9cyksbjxzJiYobj1zKSkpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihlPT09dm9pZCAwP3I+PXImJihlPW49cik6KGU+ciYmKGU9ciksbjxyJiYobj1yKSkpfXJldHVybltlLG5dfWNsYXNzIExle2NvbnN0cnVjdG9yKCl7dGhpcy5fcGFydGlhbHM9bmV3IEZsb2F0NjRBcnJheSgzMiksdGhpcy5fbj0wfWFkZCh0KXtjb25zdCBlPXRoaXMuX3BhcnRpYWxzO2xldCBuPTA7Zm9yKGxldCBzPTA7czx0aGlzLl9uJiZzPDMyO3MrKyl7Y29uc3Qgcj1lW3NdLG89dCtyLGE9TWF0aC5hYnModCk8TWF0aC5hYnMocik/dC0oby1yKTpyLShvLXQpO2EmJihlW24rK109YSksdD1vfXJldHVybiBlW25dPXQsdGhpcy5fbj1uKzEsdGhpc312YWx1ZU9mKCl7Y29uc3QgdD10aGlzLl9wYXJ0aWFscztsZXQgZT10aGlzLl9uLG4scyxyLG89MDtpZihlPjApe2ZvcihvPXRbLS1lXTtlPjAmJihuPW8scz10Wy0tZV0sbz1uK3Mscj1zLShvLW4pLCFyKTspO2U+MCYmKHI8MCYmdFtlLTFdPDB8fHI+MCYmdFtlLTFdPjApJiYocz1yKjIsbj1vK3Mscz09bi1vJiYobz1uKSl9cmV0dXJuIG99fWNvbnN0IGVwPU1hdGguc3FydCg1MCksbnA9TWF0aC5zcXJ0KDEwKSxpcD1NYXRoLnNxcnQoMik7ZnVuY3Rpb24gcnIoaSx0LGUpe2NvbnN0IG49KHQtaSkvTWF0aC5tYXgoMCxlKSxzPU1hdGguZmxvb3IoTWF0aC5sb2cxMChuKSkscj1uL01hdGgucG93KDEwLHMpLG89cj49ZXA/MTA6cj49bnA/NTpyPj1pcD8yOjE7bGV0IGEsYyxsO3JldHVybiBzPDA/KGw9TWF0aC5wb3coMTAsLXMpL28sYT1NYXRoLnJvdW5kKGkqbCksYz1NYXRoLnJvdW5kKHQqbCksYS9sPGkmJisrYSxjL2w+dCYmLS1jLGw9LWwpOihsPU1hdGgucG93KDEwLHMpKm8sYT1NYXRoLnJvdW5kKGkvbCksYz1NYXRoLnJvdW5kKHQvbCksYSpsPGkmJisrYSxjKmw+dCYmLS1jKSxjPGEmJi41PD1lJiZlPDI/cnIoaSx0LGUqMik6W2EsYyxsXX1mdW5jdGlvbiBzcChpLHQsZSl7aWYodD0rdCxpPStpLGU9K2UsIShlPjApKXJldHVybltdO2lmKGk9PT10KXJldHVybltpXTtjb25zdCBuPXQ8aSxbcyxyLG9dPW4/cnIodCxpLGUpOnJyKGksdCxlKTtpZighKHI+PXMpKXJldHVybltdO2NvbnN0IGE9ci1zKzEsYz1uZXcgQXJyYXkoYSk7aWYobilpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpKm87ZWxzZSBpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpKm87cmV0dXJuIGN9ZnVuY3Rpb24gQWEoaSx0LGUpe3JldHVybiB0PSt0LGk9K2ksZT0rZSxycihpLHQsZSlbMl19ZnVuY3Rpb24gcnAoaSx0LGUpe3Q9K3QsaT0raSxlPStlO2NvbnN0IG49dDxpLHM9bj9BYSh0LGksZSk6QWEoaSx0LGUpO3JldHVybihuPy0xOjEpKihzPDA/MS8tczpzKX1mdW5jdGlvbiBvcChpLHQpe2xldCBlPTAsbj0wO2lmKHQ9PT12b2lkIDApZm9yKGxldCBzIG9mIGkpcyE9bnVsbCYmKHM9K3MpPj1zJiYoKytlLG4rPXMpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihyPStyKT49ciYmKCsrZSxuKz1yKX1pZihlKXJldHVybiBuL2V9ZnVuY3Rpb24qYXAoaSl7Zm9yKGNvbnN0IHQgb2YgaSl5aWVsZCpZdSh0KX1mdW5jdGlvbiBWaShpKXtyZXR1cm4gQXJyYXkuZnJvbShhcChpKSl9dmFyIEs9MWUtNixvcj0xZS0xMixYPU1hdGguUEksTnQ9WC8yLGFyPVgvNCxSdD1YKjIsaHQ9MTgwL1gsSD1YLzE4MCx0dD1NYXRoLmFicyxTYT1NYXRoLmF0YW4scmU9TWF0aC5hdGFuMixXPU1hdGguY29zLGNwPU1hdGguZXhwLF9hPU1hdGguaHlwb3QsbHA9TWF0aC5sb2cscT1NYXRoLnNpbixocD1NYXRoLnNpZ258fGZ1bmN0aW9uKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH0sT2U9TWF0aC5zcXJ0LHVwPU1hdGgudGFuO2Z1bmN0aW9uIGZwKGkpe3JldHVybiBpPjE/MDppPC0xP1g6TWF0aC5hY29zKGkpfWZ1bmN0aW9uIERlKGkpe3JldHVybiBpPjE/TnQ6aTwtMT8tTnQ6TWF0aC5hc2luKGkpfWZ1bmN0aW9uIGpsKGkpe3JldHVybihpPXEoaS8yKSkqaX1mdW5jdGlvbiBfdCgpe31mdW5jdGlvbiBjcihpLHQpe2kmJktsLmhhc093blByb3BlcnR5KGkudHlwZSkmJktsW2kudHlwZV0oaSx0KX12YXIgUWw9e0ZlYXR1cmU6ZnVuY3Rpb24oaSx0KXtjcihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspY3IoZVtuXS5nZW9tZXRyeSx0KX19LEtsPXtTcGhlcmU6ZnVuY3Rpb24oaSx0KXt0LnNwaGVyZSgpfSxQb2ludDpmdW5jdGlvbihpLHQpe2k9aS5jb29yZGluYXRlcyx0LnBvaW50KGlbMF0saVsxXSxpWzJdKX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaT1lW25dLHQucG9pbnQoaVswXSxpWzFdLGlbMl0pfSxMaW5lU3RyaW5nOmZ1bmN0aW9uKGksdCl7dmEoaS5jb29yZGluYXRlcyx0LDApfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KXZhKGVbbl0sdCwwKX0sUG9seWdvbjpmdW5jdGlvbihpLHQpe3RoKGkuY29vcmRpbmF0ZXMsdCl9LE11bHRpUG9seWdvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspdGgoZVtuXSx0KX0sR2VvbWV0cnlDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZ2VvbWV0cmllcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWNyKGVbbl0sdCl9fTtmdW5jdGlvbiB2YShpLHQsZSl7dmFyIG49LTEscz1pLmxlbmd0aC1lLHI7Zm9yKHQubGluZVN0YXJ0KCk7KytuPHM7KXI9aVtuXSx0LnBvaW50KHJbMF0sclsxXSxyWzJdKTt0LmxpbmVFbmQoKX1mdW5jdGlvbiB0aChpLHQpe3ZhciBlPS0xLG49aS5sZW5ndGg7Zm9yKHQucG9seWdvblN0YXJ0KCk7KytlPG47KXZhKGlbZV0sdCwxKTt0LnBvbHlnb25FbmQoKX1mdW5jdGlvbiBscihpLHQpe2kmJlFsLmhhc093blByb3BlcnR5KGkudHlwZSk/UWxbaS50eXBlXShpLHQpOmNyKGksdCl9dmFyIGhyPW5ldyBMZSxlaD1uZXcgTGUsbmgsaWgsemEsVGEsRWEsJGU9e3BvaW50Ol90LGxpbmVTdGFydDpfdCxsaW5lRW5kOl90LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2hyPW5ldyBMZSwkZS5saW5lU3RhcnQ9ZHAsJGUubGluZUVuZD1wcH0scG9seWdvbkVuZDpmdW5jdGlvbigpe3ZhciBpPStocjtlaC5hZGQoaTwwP1J0K2k6aSksdGhpcy5saW5lU3RhcnQ9dGhpcy5saW5lRW5kPXRoaXMucG9pbnQ9X3R9LHNwaGVyZTpmdW5jdGlvbigpe2VoLmFkZChSdCl9fTtmdW5jdGlvbiBkcCgpeyRlLnBvaW50PXlwfWZ1bmN0aW9uIHBwKCl7c2gobmgsaWgpfWZ1bmN0aW9uIHlwKGksdCl7JGUucG9pbnQ9c2gsbmg9aSxpaD10LGkqPUgsdCo9SCx6YT1pLFRhPVcodD10LzIrYXIpLEVhPXEodCl9ZnVuY3Rpb24gc2goaSx0KXtpKj1ILHQqPUgsdD10LzIrYXI7dmFyIGU9aS16YSxuPWU+PTA/MTotMSxzPW4qZSxyPVcodCksbz1xKHQpLGE9RWEqbyxjPVRhKnIrYSpXKHMpLGw9YSpuKnEocyk7aHIuYWRkKHJlKGwsYykpLHphPWksVGE9cixFYT1vfWZ1bmN0aW9uIHVyKGkpe3JldHVybltyZShpWzFdLGlbMF0pLERlKGlbMl0pXX1mdW5jdGlvbiBTbihpKXt2YXIgdD1pWzBdLGU9aVsxXSxuPVcoZSk7cmV0dXJuW24qVyh0KSxuKnEodCkscShlKV19ZnVuY3Rpb24gZnIoaSx0KXtyZXR1cm4gaVswXSp0WzBdK2lbMV0qdFsxXStpWzJdKnRbMl19ZnVuY3Rpb24gbmkoaSx0KXtyZXR1cm5baVsxXSp0WzJdLWlbMl0qdFsxXSxpWzJdKnRbMF0taVswXSp0WzJdLGlbMF0qdFsxXS1pWzFdKnRbMF1dfWZ1bmN0aW9uIFBhKGksdCl7aVswXSs9dFswXSxpWzFdKz10WzFdLGlbMl0rPXRbMl19ZnVuY3Rpb24gZHIoaSx0KXtyZXR1cm5baVswXSp0LGlbMV0qdCxpWzJdKnRdfWZ1bmN0aW9uIHByKGkpe3ZhciB0PU9lKGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtpWzBdLz10LGlbMV0vPXQsaVsyXS89dH12YXIgb3QsTHQsdXQscXQsX24scmgsb2gsaWksVWksYW4sVmUsVWU9e3BvaW50OkNhLGxpbmVTdGFydDpjaCxsaW5lRW5kOmxoLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe1VlLnBvaW50PWhoLFVlLmxpbmVTdGFydD1tcCxVZS5saW5lRW5kPWdwLFVpPW5ldyBMZSwkZS5wb2x5Z29uU3RhcnQoKX0scG9seWdvbkVuZDpmdW5jdGlvbigpeyRlLnBvbHlnb25FbmQoKSxVZS5wb2ludD1DYSxVZS5saW5lU3RhcnQ9Y2gsVWUubGluZUVuZD1saCxocjwwPyhvdD0tKHV0PTE4MCksTHQ9LShxdD05MCkpOlVpPks/cXQ9OTA6VWk8LUsmJihMdD0tOTApLFZlWzBdPW90LFZlWzFdPXV0fSxzcGhlcmU6ZnVuY3Rpb24oKXtvdD0tKHV0PTE4MCksTHQ9LShxdD05MCl9fTtmdW5jdGlvbiBDYShpLHQpe2FuLnB1c2goVmU9W290PWksdXQ9aV0pLHQ8THQmJihMdD10KSx0PnF0JiYocXQ9dCl9ZnVuY3Rpb24gYWgoaSx0KXt2YXIgZT1TbihbaSpILHQqSF0pO2lmKGlpKXt2YXIgbj1uaShpaSxlKSxzPVtuWzFdLC1uWzBdLDBdLHI9bmkocyxuKTtwcihyKSxyPXVyKHIpO3ZhciBvPWktX24sYT1vPjA/MTotMSxjPXJbMF0qaHQqYSxsLGg9dHQobyk+MTgwO2heKGEqX248YyYmYzxhKmkpPyhsPXJbMV0qaHQsbD5xdCYmKHF0PWwpKTooYz0oYyszNjApJTM2MC0xODAsaF4oYSpfbjxjJiZjPGEqaSk/KGw9LXJbMV0qaHQsbDxMdCYmKEx0PWwpKToodDxMdCYmKEx0PXQpLHQ+cXQmJihxdD10KSkpLGg/aTxfbj9IdChvdCxpKT5IdChvdCx1dCkmJih1dD1pKTpIdChpLHV0KT5IdChvdCx1dCkmJihvdD1pKTp1dD49b3Q/KGk8b3QmJihvdD1pKSxpPnV0JiYodXQ9aSkpOmk+X24/SHQob3QsaSk+SHQob3QsdXQpJiYodXQ9aSk6SHQoaSx1dCk+SHQob3QsdXQpJiYob3Q9aSl9ZWxzZSBhbi5wdXNoKFZlPVtvdD1pLHV0PWldKTt0PEx0JiYoTHQ9dCksdD5xdCYmKHF0PXQpLGlpPWUsX249aX1mdW5jdGlvbiBjaCgpe1VlLnBvaW50PWFofWZ1bmN0aW9uIGxoKCl7VmVbMF09b3QsVmVbMV09dXQsVWUucG9pbnQ9Q2EsaWk9bnVsbH1mdW5jdGlvbiBoaChpLHQpe2lmKGlpKXt2YXIgZT1pLV9uO1VpLmFkZCh0dChlKT4xODA/ZSsoZT4wPzM2MDotMzYwKTplKX1lbHNlIHJoPWksb2g9dDskZS5wb2ludChpLHQpLGFoKGksdCl9ZnVuY3Rpb24gbXAoKXskZS5saW5lU3RhcnQoKX1mdW5jdGlvbiBncCgpe2hoKHJoLG9oKSwkZS5saW5lRW5kKCksdHQoVWkpPksmJihvdD0tKHV0PTE4MCkpLFZlWzBdPW90LFZlWzFdPXV0LGlpPW51bGx9ZnVuY3Rpb24gSHQoaSx0KXtyZXR1cm4odC09aSk8MD90KzM2MDp0fWZ1bmN0aW9uIHhwKGksdCl7cmV0dXJuIGlbMF0tdFswXX1mdW5jdGlvbiB1aChpLHQpe3JldHVybiBpWzBdPD1pWzFdP2lbMF08PXQmJnQ8PWlbMV06dDxpWzBdfHxpWzFdPHR9ZnVuY3Rpb24gZmgoaSl7dmFyIHQsZSxuLHMscixvLGE7aWYocXQ9dXQ9LShvdD1MdD0xLzApLGFuPVtdLGxyKGksVWUpLGU9YW4ubGVuZ3RoKXtmb3IoYW4uc29ydCh4cCksdD0xLG49YW5bMF0scj1bbl07dDxlOysrdClzPWFuW3RdLHVoKG4sc1swXSl8fHVoKG4sc1sxXSk/KEh0KG5bMF0sc1sxXSk+SHQoblswXSxuWzFdKSYmKG5bMV09c1sxXSksSHQoc1swXSxuWzFdKT5IdChuWzBdLG5bMV0pJiYoblswXT1zWzBdKSk6ci5wdXNoKG49cyk7Zm9yKG89LTEvMCxlPXIubGVuZ3RoLTEsdD0wLG49cltlXTt0PD1lO249cywrK3Qpcz1yW3RdLChhPUh0KG5bMV0sc1swXSkpPm8mJihvPWEsb3Q9c1swXSx1dD1uWzFdKX1yZXR1cm4gYW49VmU9bnVsbCxvdD09PTEvMHx8THQ9PT0xLzA/W1tOYU4sTmFOXSxbTmFOLE5hTl1dOltbb3QsTHRdLFt1dCxxdF1dfXZhciBxaSx5cixtcixncix4cix3cixicixNcixCYSxGYSxJYSxkaCxwaCxFdCxQdCxDdCxwZT17c3BoZXJlOl90LHBvaW50OmthLGxpbmVTdGFydDp5aCxsaW5lRW5kOm1oLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe3BlLmxpbmVTdGFydD1NcCxwZS5saW5lRW5kPUFwfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7cGUubGluZVN0YXJ0PXloLHBlLmxpbmVFbmQ9bWh9fTtmdW5jdGlvbiBrYShpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO0hpKGUqVyhpKSxlKnEoaSkscSh0KSl9ZnVuY3Rpb24gSGkoaSx0LGUpeysrcWksbXIrPShpLW1yKS9xaSxncis9KHQtZ3IpL3FpLHhyKz0oZS14cikvcWl9ZnVuY3Rpb24geWgoKXtwZS5wb2ludD13cH1mdW5jdGlvbiB3cChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO0V0PWUqVyhpKSxQdD1lKnEoaSksQ3Q9cSh0KSxwZS5wb2ludD1icCxIaShFdCxQdCxDdCl9ZnVuY3Rpb24gYnAoaSx0KXtpKj1ILHQqPUg7dmFyIGU9Vyh0KSxuPWUqVyhpKSxzPWUqcShpKSxyPXEodCksbz1yZShPZSgobz1QdCpyLUN0KnMpKm8rKG89Q3Qqbi1FdCpyKSpvKyhvPUV0KnMtUHQqbikqbyksRXQqbitQdCpzK0N0KnIpO3lyKz1vLHdyKz1vKihFdCsoRXQ9bikpLGJyKz1vKihQdCsoUHQ9cykpLE1yKz1vKihDdCsoQ3Q9cikpLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiBtaCgpe3BlLnBvaW50PWthfWZ1bmN0aW9uIE1wKCl7cGUucG9pbnQ9U3B9ZnVuY3Rpb24gQXAoKXtnaChkaCxwaCkscGUucG9pbnQ9a2F9ZnVuY3Rpb24gU3AoaSx0KXtkaD1pLHBoPXQsaSo9SCx0Kj1ILHBlLnBvaW50PWdoO3ZhciBlPVcodCk7RXQ9ZSpXKGkpLFB0PWUqcShpKSxDdD1xKHQpLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiBnaChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpLG49ZSpXKGkpLHM9ZSpxKGkpLHI9cSh0KSxvPVB0KnItQ3QqcyxhPUN0Km4tRXQqcixjPUV0KnMtUHQqbixsPV9hKG8sYSxjKSxoPURlKGwpLHU9bCYmLWgvbDtCYS5hZGQodSpvKSxGYS5hZGQodSphKSxJYS5hZGQodSpjKSx5cis9aCx3cis9aCooRXQrKEV0PW4pKSxicis9aCooUHQrKFB0PXMpKSxNcis9aCooQ3QrKEN0PXIpKSxIaShFdCxQdCxDdCl9ZnVuY3Rpb24geGgoaSl7cWk9eXI9bXI9Z3I9eHI9d3I9YnI9TXI9MCxCYT1uZXcgTGUsRmE9bmV3IExlLElhPW5ldyBMZSxscihpLHBlKTt2YXIgdD0rQmEsZT0rRmEsbj0rSWEscz1fYSh0LGUsbik7cmV0dXJuIHM8b3ImJih0PXdyLGU9YnIsbj1Ncix5cjxLJiYodD1tcixlPWdyLG49eHIpLHM9X2EodCxlLG4pLHM8b3IpP1tOYU4sTmFOXTpbcmUoZSx0KSpodCxEZShuL3MpKmh0XX1mdW5jdGlvbiBOYShpLHQpe2Z1bmN0aW9uIGUobixzKXtyZXR1cm4gbj1pKG4scyksdChuWzBdLG5bMV0pfXJldHVybiBpLmludmVydCYmdC5pbnZlcnQmJihlLmludmVydD1mdW5jdGlvbihuLHMpe3JldHVybiBuPXQuaW52ZXJ0KG4scyksbiYmaS5pbnZlcnQoblswXSxuWzFdKX0pLGV9ZnVuY3Rpb24gUmEoaSx0KXtyZXR1cm4gdHQoaSk+WCYmKGktPU1hdGgucm91bmQoaS9SdCkqUnQpLFtpLHRdfVJhLmludmVydD1SYTtmdW5jdGlvbiB3aChpLHQsZSl7cmV0dXJuKGklPVJ0KT90fHxlP05hKE1oKGkpLEFoKHQsZSkpOk1oKGkpOnR8fGU/QWgodCxlKTpSYX1mdW5jdGlvbiBiaChpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdCs9aSx0dCh0KT5YJiYodC09TWF0aC5yb3VuZCh0L1J0KSpSdCksW3QsZV19fWZ1bmN0aW9uIE1oKGkpe3ZhciB0PWJoKGkpO3JldHVybiB0LmludmVydD1iaCgtaSksdH1mdW5jdGlvbiBBaChpLHQpe3ZhciBlPVcoaSksbj1xKGkpLHM9Vyh0KSxyPXEodCk7ZnVuY3Rpb24gbyhhLGMpe3ZhciBsPVcoYyksaD1XKGEpKmwsdT1xKGEpKmwsZj1xKGMpLGQ9ZiplK2gqbjtyZXR1cm5bcmUodSpzLWQqcixoKmUtZipuKSxEZShkKnMrdSpyKV19cmV0dXJuIG8uaW52ZXJ0PWZ1bmN0aW9uKGEsYyl7dmFyIGw9VyhjKSxoPVcoYSkqbCx1PXEoYSkqbCxmPXEoYyksZD1mKnMtdSpyO3JldHVybltyZSh1KnMrZipyLGgqZStkKm4pLERlKGQqZS1oKm4pXX0sb31mdW5jdGlvbiBTaChpKXtpPXdoKGlbMF0qSCxpWzFdKkgsaS5sZW5ndGg+Mj9pWzJdKkg6MCk7ZnVuY3Rpb24gdChlKXtyZXR1cm4gZT1pKGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9cmV0dXJuIHQuaW52ZXJ0PWZ1bmN0aW9uKGUpe3JldHVybiBlPWkuaW52ZXJ0KGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9LHR9ZnVuY3Rpb24gX3AoaSx0LGUsbixzLHIpe2lmKGUpe3ZhciBvPVcodCksYT1xKHQpLGM9biplO3M9PW51bGw/KHM9dCtuKlJ0LHI9dC1jLzIpOihzPV9oKG8scykscj1faChvLHIpLChuPjA/czxyOnM+cikmJihzKz1uKlJ0KSk7Zm9yKHZhciBsLGg9cztuPjA/aD5yOmg8cjtoLT1jKWw9dXIoW28sLWEqVyhoKSwtYSpxKGgpXSksaS5wb2ludChsWzBdLGxbMV0pfX1mdW5jdGlvbiBfaChpLHQpe3Q9U24odCksdFswXS09aSxwcih0KTt2YXIgZT1mcCgtdFsxXSk7cmV0dXJuKCgtdFsyXTwwPy1lOmUpK1J0LUspJVJ0fWZ1bmN0aW9uIHZoKCl7dmFyIGk9W10sdDtyZXR1cm57cG9pbnQ6ZnVuY3Rpb24oZSxuLHMpe3QucHVzaChbZSxuLHNdKX0sbGluZVN0YXJ0OmZ1bmN0aW9uKCl7aS5wdXNoKHQ9W10pfSxsaW5lRW5kOl90LHJlam9pbjpmdW5jdGlvbigpe2kubGVuZ3RoPjEmJmkucHVzaChpLnBvcCgpLmNvbmNhdChpLnNoaWZ0KCkpKX0scmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGU9aTtyZXR1cm4gaT1bXSx0PW51bGwsZX19fWZ1bmN0aW9uIEFyKGksdCl7cmV0dXJuIHR0KGlbMF0tdFswXSk8SyYmdHQoaVsxXS10WzFdKTxLfWZ1bmN0aW9uIFNyKGksdCxlLG4pe3RoaXMueD1pLHRoaXMuej10LHRoaXMubz1lLHRoaXMuZT1uLHRoaXMudj0hMSx0aGlzLm49dGhpcy5wPW51bGx9ZnVuY3Rpb24gemgoaSx0LGUsbixzKXt2YXIgcj1bXSxvPVtdLGEsYztpZihpLmZvckVhY2goZnVuY3Rpb24ocCl7aWYoISgoeT1wLmxlbmd0aC0xKTw9MCkpe3ZhciB5LG09cFswXSxnPXBbeV0sYjtpZihBcihtLGcpKXtpZighbVsyXSYmIWdbMl0pe2ZvcihzLmxpbmVTdGFydCgpLGE9MDthPHk7KythKXMucG9pbnQoKG09cFthXSlbMF0sbVsxXSk7cy5saW5lRW5kKCk7cmV0dXJufWdbMF0rPTIqS31yLnB1c2goYj1uZXcgU3IobSxwLG51bGwsITApKSxvLnB1c2goYi5vPW5ldyBTcihtLG51bGwsYiwhMSkpLHIucHVzaChiPW5ldyBTcihnLHAsbnVsbCwhMSkpLG8ucHVzaChiLm89bmV3IFNyKGcsbnVsbCxiLCEwKSl9fSksISFyLmxlbmd0aCl7Zm9yKG8uc29ydCh0KSxUaChyKSxUaChvKSxhPTAsYz1vLmxlbmd0aDthPGM7KythKW9bYV0uZT1lPSFlO2Zvcih2YXIgbD1yWzBdLGgsdTs7KXtmb3IodmFyIGY9bCxkPSEwO2YudjspaWYoKGY9Zi5uKT09PWwpcmV0dXJuO2g9Zi56LHMubGluZVN0YXJ0KCk7ZG97aWYoZi52PWYuby52PSEwLGYuZSl7aWYoZClmb3IoYT0wLGM9aC5sZW5ndGg7YTxjOysrYSlzLnBvaW50KCh1PWhbYV0pWzBdLHVbMV0pO2Vsc2UgbihmLngsZi5uLngsMSxzKTtmPWYubn1lbHNle2lmKGQpZm9yKGg9Zi5wLnosYT1oLmxlbmd0aC0xO2E+PTA7LS1hKXMucG9pbnQoKHU9aFthXSlbMF0sdVsxXSk7ZWxzZSBuKGYueCxmLnAueCwtMSxzKTtmPWYucH1mPWYubyxoPWYueixkPSFkfXdoaWxlKCFmLnYpO3MubGluZUVuZCgpfX19ZnVuY3Rpb24gVGgoaSl7aWYodD1pLmxlbmd0aCl7Zm9yKHZhciB0LGU9MCxuPWlbMF0sczsrK2U8dDspbi5uPXM9aVtlXSxzLnA9bixuPXM7bi5uPXM9aVswXSxzLnA9bn19ZnVuY3Rpb24gTGEoaSl7cmV0dXJuIHR0KGlbMF0pPD1YP2lbMF06aHAoaVswXSkqKCh0dChpWzBdKStYKSVSdC1YKX1mdW5jdGlvbiBFaChpLHQpe3ZhciBlPUxhKHQpLG49dFsxXSxzPXEobikscj1bcShlKSwtVyhlKSwwXSxvPTAsYT0wLGM9bmV3IExlO3M9PT0xP249TnQrSzpzPT09LTEmJihuPS1OdC1LKTtmb3IodmFyIGw9MCxoPWkubGVuZ3RoO2w8aDsrK2wpaWYoZj0odT1pW2xdKS5sZW5ndGgpZm9yKHZhciB1LGYsZD11W2YtMV0scD1MYShkKSx5PWRbMV0vMithcixtPXEoeSksZz1XKHkpLGI9MDtiPGY7KytiLHA9eCxtPUEsZz1TLGQ9dyl7dmFyIHc9dVtiXSx4PUxhKHcpLE09d1sxXS8yK2FyLEE9cShNKSxTPVcoTSksXz14LXAsRT1fPj0wPzE6LTEsej1FKl8sdj16PlgsQz1tKkE7aWYoYy5hZGQocmUoQypFKnEoeiksZypTK0MqVyh6KSkpLG8rPXY/XytFKlJ0Ol8sdl5wPj1lXng+PWUpe3ZhciBQPW5pKFNuKGQpLFNuKHcpKTtwcihQKTt2YXIgRj1uaShyLFApO3ByKEYpO3ZhciBCPSh2Xl8+PTA/LTE6MSkqRGUoRlsyXSk7KG4+Qnx8bj09PUImJihQWzBdfHxQWzFdKSkmJihhKz12Xl8+PTA/MTotMSl9fXJldHVybihvPC1LfHxvPEsmJmM8LW9yKV5hJjF9ZnVuY3Rpb24gUGgoaSx0LGUsbil7cmV0dXJuIGZ1bmN0aW9uKHMpe3ZhciByPXQocyksbz12aCgpLGE9dChvKSxjPSExLGwsaCx1LGY9e3BvaW50OmQsbGluZVN0YXJ0OnksbGluZUVuZDptLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2YucG9pbnQ9ZyxmLmxpbmVTdGFydD1iLGYubGluZUVuZD13LGg9W10sbD1bXX0scG9seWdvbkVuZDpmdW5jdGlvbigpe2YucG9pbnQ9ZCxmLmxpbmVTdGFydD15LGYubGluZUVuZD1tLGg9VmkoaCk7dmFyIHg9RWgobCxuKTtoLmxlbmd0aD8oY3x8KHMucG9seWdvblN0YXJ0KCksYz0hMCksemgoaCx6cCx4LGUscykpOngmJihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkpLGMmJihzLnBvbHlnb25FbmQoKSxjPSExKSxoPWw9bnVsbH0sc3BoZXJlOmZ1bmN0aW9uKCl7cy5wb2x5Z29uU3RhcnQoKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkscy5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBkKHgsTSl7aSh4LE0pJiZzLnBvaW50KHgsTSl9ZnVuY3Rpb24gcCh4LE0pe3IucG9pbnQoeCxNKX1mdW5jdGlvbiB5KCl7Zi5wb2ludD1wLHIubGluZVN0YXJ0KCl9ZnVuY3Rpb24gbSgpe2YucG9pbnQ9ZCxyLmxpbmVFbmQoKX1mdW5jdGlvbiBnKHgsTSl7dS5wdXNoKFt4LE1dKSxhLnBvaW50KHgsTSl9ZnVuY3Rpb24gYigpe2EubGluZVN0YXJ0KCksdT1bXX1mdW5jdGlvbiB3KCl7Zyh1WzBdWzBdLHVbMF1bMV0pLGEubGluZUVuZCgpO3ZhciB4PWEuY2xlYW4oKSxNPW8ucmVzdWx0KCksQSxTPU0ubGVuZ3RoLF8sRSx6O2lmKHUucG9wKCksbC5wdXNoKHUpLHU9bnVsbCwhIVMpe2lmKHgmMSl7aWYoRT1NWzBdLChfPUUubGVuZ3RoLTEpPjApe2ZvcihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLEE9MDtBPF87KytBKXMucG9pbnQoKHo9RVtBXSlbMF0selsxXSk7cy5saW5lRW5kKCl9cmV0dXJufVM+MSYmeCYyJiZNLnB1c2goTS5wb3AoKS5jb25jYXQoTS5zaGlmdCgpKSksaC5wdXNoKE0uZmlsdGVyKHZwKSl9fXJldHVybiBmfX1mdW5jdGlvbiB2cChpKXtyZXR1cm4gaS5sZW5ndGg+MX1mdW5jdGlvbiB6cChpLHQpe3JldHVybigoaT1pLngpWzBdPDA/aVsxXS1OdC1LOk50LWlbMV0pLSgodD10LngpWzBdPDA/dFsxXS1OdC1LOk50LXRbMV0pfXZhciBDaD1QaChmdW5jdGlvbigpe3JldHVybiEwfSxUcCxQcCxbLVgsLU50XSk7ZnVuY3Rpb24gVHAoaSl7dmFyIHQ9TmFOLGU9TmFOLG49TmFOLHM7cmV0dXJue2xpbmVTdGFydDpmdW5jdGlvbigpe2kubGluZVN0YXJ0KCkscz0xfSxwb2ludDpmdW5jdGlvbihyLG8pe3ZhciBhPXI+MD9YOi1YLGM9dHQoci10KTt0dChjLVgpPEs/KGkucG9pbnQodCxlPShlK28pLzI+MD9OdDotTnQpLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxpLnBvaW50KHIsZSkscz0wKTpuIT09YSYmYz49WCYmKHR0KHQtbik8SyYmKHQtPW4qSyksdHQoci1hKTxLJiYoci09YSpLKSxlPUVwKHQsZSxyLG8pLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxzPTApLGkucG9pbnQodD1yLGU9byksbj1hfSxsaW5lRW5kOmZ1bmN0aW9uKCl7aS5saW5lRW5kKCksdD1lPU5hTn0sY2xlYW46ZnVuY3Rpb24oKXtyZXR1cm4gMi1zfX19ZnVuY3Rpb24gRXAoaSx0LGUsbil7dmFyIHMscixvPXEoaS1lKTtyZXR1cm4gdHQobyk+Sz9TYSgocSh0KSoocj1XKG4pKSpxKGUpLXEobikqKHM9Vyh0KSkqcShpKSkvKHMqcipvKSk6KHQrbikvMn1mdW5jdGlvbiBQcChpLHQsZSxuKXt2YXIgcztpZihpPT1udWxsKXM9ZSpOdCxuLnBvaW50KC1YLHMpLG4ucG9pbnQoMCxzKSxuLnBvaW50KFgscyksbi5wb2ludChYLDApLG4ucG9pbnQoWCwtcyksbi5wb2ludCgwLC1zKSxuLnBvaW50KC1YLC1zKSxuLnBvaW50KC1YLDApLG4ucG9pbnQoLVgscyk7ZWxzZSBpZih0dChpWzBdLXRbMF0pPkspe3ZhciByPWlbMF08dFswXT9YOi1YO3M9ZSpyLzIsbi5wb2ludCgtcixzKSxuLnBvaW50KDAscyksbi5wb2ludChyLHMpfWVsc2Ugbi5wb2ludCh0WzBdLHRbMV0pfWZ1bmN0aW9uIENwKGkpe3ZhciB0PVcoaSksZT0yKkgsbj10PjAscz10dCh0KT5LO2Z1bmN0aW9uIHIoaCx1LGYsZCl7X3AoZCxpLGUsZixoLHUpfWZ1bmN0aW9uIG8oaCx1KXtyZXR1cm4gVyhoKSpXKHUpPnR9ZnVuY3Rpb24gYShoKXt2YXIgdSxmLGQscCx5O3JldHVybntsaW5lU3RhcnQ6ZnVuY3Rpb24oKXtwPWQ9ITEseT0xfSxwb2ludDpmdW5jdGlvbihtLGcpe3ZhciBiPVttLGddLHcseD1vKG0sZyksTT1uP3g/MDpsKG0sZyk6eD9sKG0rKG08MD9YOi1YKSxnKTowO2lmKCF1JiYocD1kPXgpJiZoLmxpbmVTdGFydCgpLHghPT1kJiYodz1jKHUsYiksKCF3fHxBcih1LHcpfHxBcihiLHcpKSYmKGJbMl09MSkpLHghPT1kKXk9MCx4PyhoLmxpbmVTdGFydCgpLHc9YyhiLHUpLGgucG9pbnQod1swXSx3WzFdKSk6KHc9Yyh1LGIpLGgucG9pbnQod1swXSx3WzFdLDIpLGgubGluZUVuZCgpKSx1PXc7ZWxzZSBpZihzJiZ1JiZuXngpe3ZhciBBOyEoTSZmKSYmKEE9YyhiLHUsITApKSYmKHk9MCxuPyhoLmxpbmVTdGFydCgpLGgucG9pbnQoQVswXVswXSxBWzBdWzFdKSxoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCkpOihoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCksaC5saW5lU3RhcnQoKSxoLnBvaW50KEFbMF1bMF0sQVswXVsxXSwzKSkpfXgmJighdXx8IUFyKHUsYikpJiZoLnBvaW50KGJbMF0sYlsxXSksdT1iLGQ9eCxmPU19LGxpbmVFbmQ6ZnVuY3Rpb24oKXtkJiZoLmxpbmVFbmQoKSx1PW51bGx9LGNsZWFuOmZ1bmN0aW9uKCl7cmV0dXJuIHl8KHAmJmQpPDwxfX19ZnVuY3Rpb24gYyhoLHUsZil7dmFyIGQ9U24oaCkscD1Tbih1KSx5PVsxLDAsMF0sbT1uaShkLHApLGc9ZnIobSxtKSxiPW1bMF0sdz1nLWIqYjtpZighdylyZXR1cm4hZiYmaDt2YXIgeD10KmcvdyxNPS10KmIvdyxBPW5pKHksbSksUz1kcih5LHgpLF89ZHIobSxNKTtQYShTLF8pO3ZhciBFPUEsej1mcihTLEUpLHY9ZnIoRSxFKSxDPXoqei12KihmcihTLFMpLTEpO2lmKCEoQzwwKSl7dmFyIFA9T2UoQyksRj1kcihFLCgtei1QKS92KTtpZihQYShGLFMpLEY9dXIoRiksIWYpcmV0dXJuIEY7dmFyIEI9aFswXSxJPXVbMF0saz1oWzFdLEQ9dVsxXSxVO0k8QiYmKFU9QixCPUksST1VKTt2YXIgaj1JLUIsZHQ9dHQoai1YKTxLLER0PWR0fHxqPEs7aWYoIWR0JiZEPGsmJihVPWssaz1ELEQ9VSksRHQ/ZHQ/aytEPjBeRlsxXTwodHQoRlswXS1CKTxLP2s6RCk6azw9RlsxXSYmRlsxXTw9RDpqPlheKEI8PUZbMF0mJkZbMF08PUkpKXt2YXIgR3Q9ZHIoRSwoLXorUCkvdik7cmV0dXJuIFBhKEd0LFMpLFtGLHVyKEd0KV19fX1mdW5jdGlvbiBsKGgsdSl7dmFyIGY9bj9pOlgtaSxkPTA7cmV0dXJuIGg8LWY/ZHw9MTpoPmYmJihkfD0yKSx1PC1mP2R8PTQ6dT5mJiYoZHw9OCksZH1yZXR1cm4gUGgobyxhLHIsbj9bMCwtaV06Wy1YLGktWF0pfWZ1bmN0aW9uIEJwKGksdCxlLG4scyxyKXt2YXIgbz1pWzBdLGE9aVsxXSxjPXRbMF0sbD10WzFdLGg9MCx1PTEsZj1jLW8sZD1sLWEscDtpZihwPWUtbywhKCFmJiZwPjApKXtpZihwLz1mLGY8MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWVsc2UgaWYoZj4wKXtpZihwPnUpcmV0dXJuO3A+aCYmKGg9cCl9aWYocD1zLW8sISghZiYmcDwwKSl7aWYocC89ZixmPDApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1lbHNlIGlmKGY+MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWlmKHA9bi1hLCEoIWQmJnA+MCkpe2lmKHAvPWQsZDwwKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9ZWxzZSBpZihkPjApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1pZihwPXItYSwhKCFkJiZwPDApKXtpZihwLz1kLGQ8MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWVsc2UgaWYoZD4wKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9cmV0dXJuIGg+MCYmKGlbMF09bytoKmYsaVsxXT1hK2gqZCksdTwxJiYodFswXT1vK3UqZix0WzFdPWErdSpkKSwhMH19fX19dmFyIFdpPTFlOSxfcj0tV2k7ZnVuY3Rpb24gRnAoaSx0LGUsbil7ZnVuY3Rpb24gcyhsLGgpe3JldHVybiBpPD1sJiZsPD1lJiZ0PD1oJiZoPD1ufWZ1bmN0aW9uIHIobCxoLHUsZil7dmFyIGQ9MCxwPTA7aWYobD09bnVsbHx8KGQ9byhsLHUpKSE9PShwPW8oaCx1KSl8fGMobCxoKTwwXnU+MClkbyBmLnBvaW50KGQ9PT0wfHxkPT09Mz9pOmUsZD4xP246dCk7d2hpbGUoKGQ9KGQrdSs0KSU0KSE9PXApO2Vsc2UgZi5wb2ludChoWzBdLGhbMV0pfWZ1bmN0aW9uIG8obCxoKXtyZXR1cm4gdHQobFswXS1pKTxLP2g+MD8wOjM6dHQobFswXS1lKTxLP2g+MD8yOjE6dHQobFsxXS10KTxLP2g+MD8xOjA6aD4wPzM6Mn1mdW5jdGlvbiBhKGwsaCl7cmV0dXJuIGMobC54LGgueCl9ZnVuY3Rpb24gYyhsLGgpe3ZhciB1PW8obCwxKSxmPW8oaCwxKTtyZXR1cm4gdSE9PWY/dS1mOnU9PT0wP2hbMV0tbFsxXTp1PT09MT9sWzBdLWhbMF06dT09PTI/bFsxXS1oWzFdOmhbMF0tbFswXX1yZXR1cm4gZnVuY3Rpb24obCl7dmFyIGg9bCx1PXZoKCksZixkLHAseSxtLGcsYix3LHgsTSxBLFM9e3BvaW50Ol8sbGluZVN0YXJ0OkMsbGluZUVuZDpQLHBvbHlnb25TdGFydDp6LHBvbHlnb25FbmQ6dn07ZnVuY3Rpb24gXyhCLEkpe3MoQixJKSYmaC5wb2ludChCLEkpfWZ1bmN0aW9uIEUoKXtmb3IodmFyIEI9MCxJPTAsaz1kLmxlbmd0aDtJPGs7KytJKWZvcih2YXIgRD1kW0ldLFU9MSxqPUQubGVuZ3RoLGR0PURbMF0sRHQsR3QsWnQ9ZHRbMF0sbWU9ZHRbMV07VTxqOysrVSlEdD1adCxHdD1tZSxkdD1EW1VdLFp0PWR0WzBdLG1lPWR0WzFdLEd0PD1uP21lPm4mJihadC1EdCkqKG4tR3QpPihtZS1HdCkqKGktRHQpJiYrK0I6bWU8PW4mJihadC1EdCkqKG4tR3QpPChtZS1HdCkqKGktRHQpJiYtLUI7cmV0dXJuIEJ9ZnVuY3Rpb24geigpe2g9dSxmPVtdLGQ9W10sQT0hMH1mdW5jdGlvbiB2KCl7dmFyIEI9RSgpLEk9QSYmQixrPShmPVZpKGYpKS5sZW5ndGg7KEl8fGspJiYobC5wb2x5Z29uU3RhcnQoKSxJJiYobC5saW5lU3RhcnQoKSxyKG51bGwsbnVsbCwxLGwpLGwubGluZUVuZCgpKSxrJiZ6aChmLGEsQixyLGwpLGwucG9seWdvbkVuZCgpKSxoPWwsZj1kPXA9bnVsbH1mdW5jdGlvbiBDKCl7Uy5wb2ludD1GLGQmJmQucHVzaChwPVtdKSxNPSEwLHg9ITEsYj13PU5hTn1mdW5jdGlvbiBQKCl7ZiYmKEYoeSxtKSxnJiZ4JiZ1LnJlam9pbigpLGYucHVzaCh1LnJlc3VsdCgpKSksUy5wb2ludD1fLHgmJmgubGluZUVuZCgpfWZ1bmN0aW9uIEYoQixJKXt2YXIgaz1zKEIsSSk7aWYoZCYmcC5wdXNoKFtCLEldKSxNKXk9QixtPUksZz1rLE09ITEsayYmKGgubGluZVN0YXJ0KCksaC5wb2ludChCLEkpKTtlbHNlIGlmKGsmJngpaC5wb2ludChCLEkpO2Vsc2V7dmFyIEQ9W2I9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksYikpLHc9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksdykpXSxVPVtCPU1hdGgubWF4KF9yLE1hdGgubWluKFdpLEIpKSxJPU1hdGgubWF4KF9yLE1hdGgubWluKFdpLEkpKV07QnAoRCxVLGksdCxlLG4pPyh4fHwoaC5saW5lU3RhcnQoKSxoLnBvaW50KERbMF0sRFsxXSkpLGgucG9pbnQoVVswXSxVWzFdKSxrfHxoLmxpbmVFbmQoKSxBPSExKTprJiYoaC5saW5lU3RhcnQoKSxoLnBvaW50KEIsSSksQT0hMSl9Yj1CLHc9SSx4PWt9cmV0dXJuIFN9fXZhciBPYSxEYSx2cix6cixzaT17c3BoZXJlOl90LHBvaW50Ol90LGxpbmVTdGFydDpJcCxsaW5lRW5kOl90LHBvbHlnb25TdGFydDpfdCxwb2x5Z29uRW5kOl90fTtmdW5jdGlvbiBJcCgpe3NpLnBvaW50PU5wLHNpLmxpbmVFbmQ9a3B9ZnVuY3Rpb24ga3AoKXtzaS5wb2ludD1zaS5saW5lRW5kPV90fWZ1bmN0aW9uIE5wKGksdCl7aSo9SCx0Kj1ILERhPWksdnI9cSh0KSx6cj1XKHQpLHNpLnBvaW50PVJwfWZ1bmN0aW9uIFJwKGksdCl7aSo9SCx0Kj1IO3ZhciBlPXEodCksbj1XKHQpLHM9dHQoaS1EYSkscj1XKHMpLG89cShzKSxhPW4qbyxjPXpyKmUtdnIqbipyLGw9dnIqZSt6cipuKnI7T2EuYWRkKHJlKE9lKGEqYStjKmMpLGwpKSxEYT1pLHZyPWUsenI9bn1mdW5jdGlvbiBMcChpKXtyZXR1cm4gT2E9bmV3IExlLGxyKGksc2kpLCtPYX12YXIgJGE9W251bGwsbnVsbF0sT3A9e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOiRhfTtmdW5jdGlvbiByaShpLHQpe3JldHVybiAkYVswXT1pLCRhWzFdPXQsTHAoT3ApfXZhciBCaD17RmVhdHVyZTpmdW5jdGlvbihpLHQpe3JldHVybiBUcihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoVHIoZVtuXS5nZW9tZXRyeSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19LEZoPXtTcGhlcmU6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sUG9pbnQ6ZnVuY3Rpb24oaSx0KXtyZXR1cm4gSWgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoSWgoZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX0sTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe3JldHVybiBraChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWlmKGtoKGVbbl0sdCkpcmV0dXJuITA7cmV0dXJuITF9LFBvbHlnb246ZnVuY3Rpb24oaSx0KXtyZXR1cm4gTmgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2x5Z29uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihOaChlW25dLHQpKXJldHVybiEwO3JldHVybiExfSxHZW9tZXRyeUNvbGxlY3Rpb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5nZW9tZXRyaWVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoVHIoZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19O2Z1bmN0aW9uIFRyKGksdCl7cmV0dXJuIGkmJkZoLmhhc093blByb3BlcnR5KGkudHlwZSk/RmhbaS50eXBlXShpLHQpOiExfWZ1bmN0aW9uIEloKGksdCl7cmV0dXJuIHJpKGksdCk9PT0wfWZ1bmN0aW9uIGtoKGksdCl7Zm9yKHZhciBlLG4scyxyPTAsbz1pLmxlbmd0aDtyPG87cisrKXtpZihuPXJpKGlbcl0sdCksbj09PTB8fHI+MCYmKHM9cmkoaVtyXSxpW3ItMV0pLHM+MCYmZTw9cyYmbjw9cyYmKGUrbi1zKSooMS1NYXRoLnBvdygoZS1uKS9zLDIpKTxvcipzKSlyZXR1cm4hMDtlPW59cmV0dXJuITF9ZnVuY3Rpb24gTmgoaSx0KXtyZXR1cm4hIUVoKGkubWFwKERwKSxSaCh0KSl9ZnVuY3Rpb24gRHAoaSl7cmV0dXJuIGk9aS5tYXAoUmgpLGkucG9wKCksaX1mdW5jdGlvbiBSaChpKXtyZXR1cm5baVswXSpILGlbMV0qSF19ZnVuY3Rpb24gJHAoaSx0KXtyZXR1cm4oaSYmQmguaGFzT3duUHJvcGVydHkoaS50eXBlKT9CaFtpLnR5cGVdOlRyKShpLHQpfWZ1bmN0aW9uIFZwKGksdCl7dmFyIGU9aVswXSpILG49aVsxXSpILHM9dFswXSpILHI9dFsxXSpILG89VyhuKSxhPXEobiksYz1XKHIpLGw9cShyKSxoPW8qVyhlKSx1PW8qcShlKSxmPWMqVyhzKSxkPWMqcShzKSxwPTIqRGUoT2Uoamwoci1uKStvKmMqamwocy1lKSkpLHk9cShwKSxtPXA/ZnVuY3Rpb24oZyl7dmFyIGI9cShnKj1wKS95LHc9cShwLWcpL3kseD13KmgrYipmLE09dyp1K2IqZCxBPXcqYStiKmw7cmV0dXJuW3JlKE0seCkqaHQscmUoQSxPZSh4KngrTSpNKSkqaHRdfTpmdW5jdGlvbigpe3JldHVybltlKmh0LG4qaHRdfTtyZXR1cm4gbS5kaXN0YW5jZT1wLG19dmFyIExoPWk9Pmksb2k9MS8wLEVyPW9pLEdpPS1vaSxQcj1HaSxPaD17cG9pbnQ6VXAsbGluZVN0YXJ0Ol90LGxpbmVFbmQ6X3QscG9seWdvblN0YXJ0Ol90LHBvbHlnb25FbmQ6X3QscmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGk9W1tvaSxFcl0sW0dpLFByXV07cmV0dXJuIEdpPVByPS0oRXI9b2k9MS8wKSxpfX07ZnVuY3Rpb24gVXAoaSx0KXtpPG9pJiYob2k9aSksaT5HaSYmKEdpPWkpLHQ8RXImJihFcj10KSx0PlByJiYoUHI9dCl9ZnVuY3Rpb24gVmEoaSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBVYTtmb3IodmFyIG4gaW4gaSllW25dPWlbbl07cmV0dXJuIGUuc3RyZWFtPXQsZX19ZnVuY3Rpb24gVWEoKXt9VWEucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpVYSxwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGksdCl9LHNwaGVyZTpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLnNwaGVyZSgpfSxsaW5lU3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5saW5lU3RhcnQoKX0sbGluZUVuZDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLmxpbmVFbmQoKX0scG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0ucG9seWdvblN0YXJ0KCl9LHBvbHlnb25FbmQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBxYShpLHQsZSl7dmFyIG49aS5jbGlwRXh0ZW50JiZpLmNsaXBFeHRlbnQoKTtyZXR1cm4gaS5zY2FsZSgxNTApLnRyYW5zbGF0ZShbMCwwXSksbiE9bnVsbCYmaS5jbGlwRXh0ZW50KG51bGwpLGxyKGUsaS5zdHJlYW0oT2gpKSx0KE9oLnJlc3VsdCgpKSxuIT1udWxsJiZpLmNsaXBFeHRlbnQobiksaX1mdW5jdGlvbiBEaChpLHQsZSl7cmV0dXJuIHFhKGksZnVuY3Rpb24obil7dmFyIHM9dFsxXVswXS10WzBdWzBdLHI9dFsxXVsxXS10WzBdWzFdLG89TWF0aC5taW4ocy8oblsxXVswXS1uWzBdWzBdKSxyLyhuWzFdWzFdLW5bMF1bMV0pKSxhPSt0WzBdWzBdKyhzLW8qKG5bMV1bMF0rblswXVswXSkpLzIsYz0rdFswXVsxXSsoci1vKihuWzFdWzFdK25bMF1bMV0pKS8yO2kuc2NhbGUoMTUwKm8pLnRyYW5zbGF0ZShbYSxjXSl9LGUpfWZ1bmN0aW9uIHFwKGksdCxlKXtyZXR1cm4gRGgoaSxbWzAsMF0sdF0sZSl9ZnVuY3Rpb24gSHAoaSx0LGUpe3JldHVybiBxYShpLGZ1bmN0aW9uKG4pe3ZhciBzPSt0LHI9cy8oblsxXVswXS1uWzBdWzBdKSxvPShzLXIqKG5bMV1bMF0rblswXVswXSkpLzIsYT0tcipuWzBdWzFdO2kuc2NhbGUoMTUwKnIpLnRyYW5zbGF0ZShbbyxhXSl9LGUpfWZ1bmN0aW9uIFdwKGksdCxlKXtyZXR1cm4gcWEoaSxmdW5jdGlvbihuKXt2YXIgcz0rdCxyPXMvKG5bMV1bMV0tblswXVsxXSksbz0tcipuWzBdWzBdLGE9KHMtciooblsxXVsxXStuWzBdWzFdKSkvMjtpLnNjYWxlKDE1MCpyKS50cmFuc2xhdGUoW28sYV0pfSxlKX12YXIgJGg9MTYsR3A9VygzMCpIKTtmdW5jdGlvbiBWaChpLHQpe3JldHVybit0P1hwKGksdCk6WnAoaSl9ZnVuY3Rpb24gWnAoaSl7cmV0dXJuIFZhKHtwb2ludDpmdW5jdGlvbih0LGUpe3Q9aSh0LGUpLHRoaXMuc3RyZWFtLnBvaW50KHRbMF0sdFsxXSl9fSl9ZnVuY3Rpb24gWHAoaSx0KXtmdW5jdGlvbiBlKG4scyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbSl7dmFyIGc9bC1uLGI9aC1zLHc9ZypnK2IqYjtpZih3PjQqdCYmeS0tKXt2YXIgeD1vK2YsTT1hK2QsQT1jK3AsUz1PZSh4KngrTSpNK0EqQSksXz1EZShBLz1TKSxFPXR0KHR0KEEpLTEpPEt8fHR0KHItdSk8Sz8ocit1KS8yOnJlKE0seCksej1pKEUsXyksdj16WzBdLEM9elsxXSxQPXYtbixGPUMtcyxCPWIqUC1nKkY7KEIqQi93PnR8fHR0KChnKlArYipGKS93LS41KT4uM3x8bypmK2EqZCtjKnA8R3ApJiYoZShuLHMscixvLGEsYyx2LEMsRSx4Lz1TLE0vPVMsQSx5LG0pLG0ucG9pbnQodixDKSxlKHYsQyxFLHgsTSxBLGwsaCx1LGYsZCxwLHksbSkpfX1yZXR1cm4gZnVuY3Rpb24obil7dmFyIHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG09e3BvaW50OmcsbGluZVN0YXJ0OmIsbGluZUVuZDp4LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe24ucG9seWdvblN0YXJ0KCksbS5saW5lU3RhcnQ9TX0scG9seWdvbkVuZDpmdW5jdGlvbigpe24ucG9seWdvbkVuZCgpLG0ubGluZVN0YXJ0PWJ9fTtmdW5jdGlvbiBnKF8sRSl7Xz1pKF8sRSksbi5wb2ludChfWzBdLF9bMV0pfWZ1bmN0aW9uIGIoKXt1PU5hTixtLnBvaW50PXcsbi5saW5lU3RhcnQoKX1mdW5jdGlvbiB3KF8sRSl7dmFyIHo9U24oW18sRV0pLHY9aShfLEUpO2UodSxmLGgsZCxwLHksdT12WzBdLGY9dlsxXSxoPV8sZD16WzBdLHA9elsxXSx5PXpbMl0sJGgsbiksbi5wb2ludCh1LGYpfWZ1bmN0aW9uIHgoKXttLnBvaW50PWcsbi5saW5lRW5kKCl9ZnVuY3Rpb24gTSgpe2IoKSxtLnBvaW50PUEsbS5saW5lRW5kPVN9ZnVuY3Rpb24gQShfLEUpe3cocz1fLEUpLHI9dSxvPWYsYT1kLGM9cCxsPXksbS5wb2ludD13fWZ1bmN0aW9uIFMoKXtlKHUsZixoLGQscCx5LHIsbyxzLGEsYyxsLCRoLG4pLG0ubGluZUVuZD14LHgoKX1yZXR1cm4gbX19dmFyIEpwPVZhKHtwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGkqSCx0KkgpfX0pO2Z1bmN0aW9uIFlwKGkpe3JldHVybiBWYSh7cG9pbnQ6ZnVuY3Rpb24odCxlKXt2YXIgbj1pKHQsZSk7cmV0dXJuIHRoaXMuc3RyZWFtLnBvaW50KG5bMF0sblsxXSl9fSl9ZnVuY3Rpb24ganAoaSx0LGUsbixzKXtmdW5jdGlvbiByKG8sYSl7cmV0dXJuIG8qPW4sYSo9cyxbdCtpKm8sZS1pKmFdfXJldHVybiByLmludmVydD1mdW5jdGlvbihvLGEpe3JldHVyblsoby10KS9pKm4sKGUtYSkvaSpzXX0scn1mdW5jdGlvbiBVaChpLHQsZSxuLHMscil7aWYoIXIpcmV0dXJuIGpwKGksdCxlLG4scyk7dmFyIG89VyhyKSxhPXEociksYz1vKmksbD1hKmksaD1vL2ksdT1hL2ksZj0oYSplLW8qdCkvaSxkPShhKnQrbyplKS9pO2Z1bmN0aW9uIHAoeSxtKXtyZXR1cm4geSo9bixtKj1zLFtjKnktbCptK3QsZS1sKnktYyptXX1yZXR1cm4gcC5pbnZlcnQ9ZnVuY3Rpb24oeSxtKXtyZXR1cm5bbiooaCp5LXUqbStmKSxzKihkLXUqeS1oKm0pXX0scH1mdW5jdGlvbiBDcihpKXtyZXR1cm4gUXAoZnVuY3Rpb24oKXtyZXR1cm4gaX0pKCl9ZnVuY3Rpb24gUXAoaSl7dmFyIHQsZT0xNTAsbj00ODAscz0yNTAscj0wLG89MCxhPTAsYz0wLGw9MCxoLHU9MCxmPTEsZD0xLHA9bnVsbCx5PUNoLG09bnVsbCxnLGIsdyx4PUxoLE09LjUsQSxTLF8sRSx6O2Z1bmN0aW9uIHYoQil7cmV0dXJuIF8oQlswXSpILEJbMV0qSCl9ZnVuY3Rpb24gQyhCKXtyZXR1cm4gQj1fLmludmVydChCWzBdLEJbMV0pLEImJltCWzBdKmh0LEJbMV0qaHRdfXYuc3RyZWFtPWZ1bmN0aW9uKEIpe3JldHVybiBFJiZ6PT09Qj9FOkU9SnAoWXAoaCkoeShBKHgoej1CKSkpKSl9LHYucHJlY2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeT1CLHA9dm9pZCAwLEYoKSk6eX0sdi5wb3N0Y2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CLG09Zz1iPXc9bnVsbCxGKCkpOnh9LHYuY2xpcEFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh5PStCP0NwKHA9QipIKToocD1udWxsLENoKSxGKCkpOnAqaHR9LHYuY2xpcEV4dGVudD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CPT1udWxsPyhtPWc9Yj13PW51bGwsTGgpOkZwKG09K0JbMF1bMF0sZz0rQlswXVsxXSxiPStCWzFdWzBdLHc9K0JbMV1bMV0pLEYoKSk6bT09bnVsbD9udWxsOltbbSxnXSxbYix3XV19LHYuc2NhbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGU9K0IsUCgpKTplfSx2LnRyYW5zbGF0ZT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obj0rQlswXSxzPStCWzFdLFAoKSk6W24sc119LHYuY2VudGVyPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhyPUJbMF0lMzYwKkgsbz1CWzFdJTM2MCpILFAoKSk6W3IqaHQsbypodF19LHYucm90YXRlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhhPUJbMF0lMzYwKkgsYz1CWzFdJTM2MCpILGw9Qi5sZW5ndGg+Mj9CWzJdJTM2MCpIOjAsUCgpKTpbYSpodCxjKmh0LGwqaHRdfSx2LmFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh1PUIlMzYwKkgsUCgpKTp1Kmh0fSx2LnJlZmxlY3RYPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhmPUI/LTE6MSxQKCkpOmY8MH0sdi5yZWZsZWN0WT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZD1CPy0xOjEsUCgpKTpkPDB9LHYucHJlY2lzaW9uPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhBPVZoKFMsTT1CKkIpLEYoKSk6T2UoTSl9LHYuZml0RXh0ZW50PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIERoKHYsQixJKX0sdi5maXRTaXplPWZ1bmN0aW9uKEIsSSl7cmV0dXJuIHFwKHYsQixJKX0sdi5maXRXaWR0aD1mdW5jdGlvbihCLEkpe3JldHVybiBIcCh2LEIsSSl9LHYuZml0SGVpZ2h0PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIFdwKHYsQixJKX07ZnVuY3Rpb24gUCgpe3ZhciBCPVVoKGUsMCwwLGYsZCx1KS5hcHBseShudWxsLHQocixvKSksST1VaChlLG4tQlswXSxzLUJbMV0sZixkLHUpO3JldHVybiBoPXdoKGEsYyxsKSxTPU5hKHQsSSksXz1OYShoLFMpLEE9VmgoUyxNKSxGKCl9ZnVuY3Rpb24gRigpe3JldHVybiBFPXo9bnVsbCx2fXJldHVybiBmdW5jdGlvbigpe3JldHVybiB0PWkuYXBwbHkodGhpcyxhcmd1bWVudHMpLHYuaW52ZXJ0PXQuaW52ZXJ0JiZDLFAoKX19ZnVuY3Rpb24gS3AoaSl7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7dmFyIG49T2UodCp0K2UqZSkscz1pKG4pLHI9cShzKSxvPVcocyk7cmV0dXJuW3JlKHQqcixuKm8pLERlKG4mJmUqci9uKV19fWZ1bmN0aW9uIEhhKGksdCl7cmV0dXJuW2ksbHAodXAoKE50K3QpLzIpKV19SGEuaW52ZXJ0PWZ1bmN0aW9uKGksdCl7cmV0dXJuW2ksMipTYShjcCh0KSktTnRdfTtmdW5jdGlvbiB0eSgpe3JldHVybiBleShIYSkuc2NhbGUoOTYxL1J0KX1mdW5jdGlvbiBleShpKXt2YXIgdD1DcihpKSxlPXQuY2VudGVyLG49dC5zY2FsZSxzPXQudHJhbnNsYXRlLHI9dC5jbGlwRXh0ZW50LG89bnVsbCxhLGMsbDt0LnNjYWxlPWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhuKHUpLGgoKSk6bigpfSx0LnRyYW5zbGF0ZT1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8ocyh1KSxoKCkpOnMoKX0sdC5jZW50ZXI9ZnVuY3Rpb24odSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGUodSksaCgpKTplKCl9LHQuY2xpcEV4dGVudD1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odT09bnVsbD9vPWE9Yz1sPW51bGw6KG89K3VbMF1bMF0sYT0rdVswXVsxXSxjPSt1WzFdWzBdLGw9K3VbMV1bMV0pLGgoKSk6bz09bnVsbD9udWxsOltbbyxhXSxbYyxsXV19O2Z1bmN0aW9uIGgoKXt2YXIgdT1YKm4oKSxmPXQoU2godC5yb3RhdGUoKSkuaW52ZXJ0KFswLDBdKSk7cmV0dXJuIHIobz09bnVsbD9bW2ZbMF0tdSxmWzFdLXVdLFtmWzBdK3UsZlsxXSt1XV06aT09PUhhP1tbTWF0aC5tYXgoZlswXS11LG8pLGFdLFtNYXRoLm1pbihmWzBdK3UsYyksbF1dOltbbyxNYXRoLm1heChmWzFdLXUsYSldLFtjLE1hdGgubWluKGZbMV0rdSxsKV1dKX1yZXR1cm4gaCgpfWZ1bmN0aW9uIFdhKGksdCl7cmV0dXJuW2ksdF19V2EuaW52ZXJ0PVdhO2Z1bmN0aW9uIG55KCl7cmV0dXJuIENyKFdhKS5zY2FsZSgxNTIuNjMpfWZ1bmN0aW9uIHFoKGksdCl7dmFyIGU9Vyh0KSxuPTErVyhpKSplO3JldHVybltlKnEoaSkvbixxKHQpL25dfXFoLmludmVydD1LcChmdW5jdGlvbihpKXtyZXR1cm4gMipTYShpKX0pO2Z1bmN0aW9uIGl5KCl7cmV0dXJuIENyKHFoKS5zY2FsZSgyNTApLmNsaXBBbmdsZSgxNDIpfXZhciBCcj1NYXRoLmFicyxhaT1NYXRoLmNvcyxiZT1NYXRoLnNpbixaaT0xZS02LEZyPU1hdGguUEksR2E9RnIvMjtmdW5jdGlvbiBzeShpKXtyZXR1cm4gaT9pL01hdGguc2luKGkpOjF9ZnVuY3Rpb24gWmEoaSl7cmV0dXJuIGk+MT8wOmk8LTE/RnI6TWF0aC5hY29zKGkpfWZ1bmN0aW9uIEhoKGkpe3JldHVybiBpPjA/TWF0aC5zcXJ0KGkpOjB9ZnVuY3Rpb24gV2goaSx0KXt2YXIgZT1haSh0KSxuPXN5KFphKGUqYWkoaS89MikpKTtyZXR1cm5bMiplKmJlKGkpKm4sYmUodCkqbl19V2guaW52ZXJ0PWZ1bmN0aW9uKGksdCl7aWYoIShpKmkrNCp0KnQ+RnIqRnIrWmkpKXt2YXIgZT1pLG49dCxzPTI1O2Rve3ZhciByPWJlKGUpLG89YmUoZS8yKSxhPWFpKGUvMiksYz1iZShuKSxsPWFpKG4pLGg9YmUoMipuKSx1PWMqYyxmPWwqbCxkPW8qbyxwPTEtZiphKmEseT1wP1phKGwqYSkqSGgobT0xL3ApOm09MCxtLGc9Mip5Kmwqby1pLGI9eSpjLXQsdz1tKihmKmQreSpsKmEqdSkseD1tKiguNSpyKmgteSoyKmMqbyksTT1tKi4yNSooaCpvLXkqYypmKnIpLEE9bSoodSphK3kqZCpsKSxTPXgqTS1BKnc7aWYoIVMpYnJlYWs7dmFyIF89KGIqeC1nKkEpL1MsRT0oZypNLWIqdykvUztlLT1fLG4tPUV9d2hpbGUoKEJyKF8pPlppfHxCcihFKT5aaSkmJi0tcz4wKTtyZXR1cm5bZSxuXX19O2Z1bmN0aW9uIEdoKGksdCl7dmFyIGU9V2goaSx0KTtyZXR1cm5bKGVbMF0raS9HYSkvMiwoZVsxXSt0KS8yXX1HaC5pbnZlcnQ9ZnVuY3Rpb24oaSx0KXt2YXIgZT1pLG49dCxzPTI1O2Rve3ZhciByPWFpKG4pLG89YmUobiksYT1iZSgyKm4pLGM9bypvLGw9cipyLGg9YmUoZSksdT1haShlLzIpLGY9YmUoZS8yKSxkPWYqZixwPTEtbCp1KnUseT1wP1phKHIqdSkqSGgobT0xL3ApOm09MCxtLGc9LjUqKDIqeSpyKmYrZS9HYSktaSxiPS41Kih5Km8rbiktdCx3PS41Km0qKGwqZCt5KnIqdSpjKSsuNS9HYSx4PW0qKGgqYS80LXkqbypmKSxNPS4xMjUqbSooYSpmLXkqbypsKmgpLEE9LjUqbSooYyp1K3kqZCpyKSsuNSxTPXgqTS1BKncsXz0oYip4LWcqQSkvUyxFPShnKk0tYip3KS9TO2UtPV8sbi09RX13aGlsZSgoQnIoXyk+Wml8fEJyKEUpPlppKSYmLS1zPjApO3JldHVybltlLG5dfTtmdW5jdGlvbiByeSgpe3JldHVybiBDcihHaCkuc2NhbGUoMTU4LjgzNyl9Y29uc3Qgb3k9e21lcmNhdG9yOnR5LGVxdWlyZWN0YW5ndWxhcjpueSx3aW5rZWwzOnJ5fSxYYT17fSxYaT1pPT57dmFyIG4scyxyO2NvbnN0IHQ9SlNPTi5zdHJpbmdpZnkoaSk7aWYoWGFbdF0pcmV0dXJuIFhhW3RdO2NvbnN0IGU9b3lbKG49aS5wcm9qZWN0aW9uVHlwZSkhPW51bGw/bjoibWVyY2F0b3IiXSgpLmNlbnRlcihpLmNlbnRlcikuc2NhbGUoaS5zY2FsZSkudHJhbnNsYXRlKChzPWkudHJhbnNsYXRlKSE9bnVsbD9zOlswLDBdKS5wcmVjaXNpb24oKHI9aS5wcmVjaXNpb24pIT1udWxsP3I6LjEpO3JldHVybiBpLnJvdGF0ZSYmZS5yb3RhdGUoaS5yb3RhdGUpLFhhW3RdPWUsZX0sSXI9KGksdCk9PmkubWFwKChbZSxuXSk9PntsZXQgcztpZih0KXtjb25zdFtyLG9dPXQoW2Usbl0pO3M9bmV3IFIociwtbyl9ZWxzZSBzPW5ldyBSKGUsbik7cmV0dXJuIHN9KTt2YXIgSmk9KGksdCk9Pntjb25zdCBlPUpsKGksdCE9bnVsbD90OjApLG49e30scz1bXSxyPU9iamVjdC5rZXlzKGUuYXR0cmlidXRlcyk7cmV0dXJuIGUuaW5kZXgmJnIucHVzaCgiaW5kZXgiKSxyLmZvckVhY2gobz0+e2NvbnN0IGE9bz09PSJpbmRleCI/ZS5pbmRleDplLmF0dHJpYnV0ZXNbb107bltvXT17YXJyYXk6YS5hcnJheSxpdGVtU2l6ZTphLml0ZW1TaXplfSxzLnB1c2goYS5hcnJheS5idWZmZXIpfSksdCYmKG4uZ3JvdXBzPWUuZ3JvdXBzKSxlLmRpc3Bvc2UoKSxpLmZvckVhY2gobz0+e28uZGlzcG9zZSgpfSkse21lc3NhZ2U6bix0cmFuc2ZlcjpzfX0sSmE9KGksdD0zMDApPT57Y29uc3QgZT1bXTtyZXR1cm4gaS5mb3JFYWNoKG49PntsZXQgcz0hMTtmb3IobGV0IHI9MTtyPG4ubGVuZ3RoO3IrKylpZihNYXRoLmFicyhuW3JdLngtbltyLTFdLngpPnQpe3M9ITA7YnJlYWt9aWYocyl7Y29uc3Qgcj1bXSxvPVtdO24uZm9yRWFjaChhPT57YS54PDA/ci5wdXNoKGEpOm8ucHVzaChhKX0pLGUucHVzaChyLG8pfWVsc2UgZS5wdXNoKG4pfSksZX07ZnVuY3Rpb24gYXkoaSx0LGU9MCl7Y29uc3RbbixzLHIsb109aTtsZXQgYT0xLzAsYz0xLzAsbD0tMS8wLGg9LTEvMDtmb3IobGV0IHU9MDt1PD1lO3UrKyl7Y29uc3QgZj1lJiZ1L2U7SXIoW1tuK2YqKHItbiksc10sW24rZiooci1uKSxvXSxbbixzK2YqKG8tcyldLFtyLHMrZiooby1zKV1dLHQpLmZvckVhY2goZD0+e2E9TWF0aC5taW4oYSxkLngpLGM9TWF0aC5taW4oYyxkLnkpLGw9TWF0aC5tYXgobCxkLngpLGg9TWF0aC5tYXgoaCxkLnkpfSl9cmV0dXJuW1thLGNdLFtsLGhdXX1jb25zdCBjeT0oe2Nvb3JkaW5hdGVzQXJyOmksc3BsaXQ6dCxzaWRlUmVwZWF0OmUsYmJveDpuLGRlcHRoOnMscHJvamVjdGlvbjpyLHVzZUdyb3VwczpvLGhhc1RvcDphLGhhc0JvdHRvbTpjLGhhc1NpZGU6bCxzcGxpdFBvbHlnb25zOmgsdG9wU2VnbWVudHM6dX0pPT57Y29uc3QgZj1yJiZYaShyKTtsZXQgZD1pLm1hcChtPT5JcihtLGYpKTtoJiYoZD1KYShkLGgpKTtsZXQgcDtpZihuKXtjb25zdFttLGddPWF5KG4sciE9bnVsbCYmci5yb3RhdGU/WGkoWmUoRnQoe30scikse3JvdGF0ZTp2b2lkIDB9KSk6Ziwocj09bnVsbD92b2lkIDA6ci5wcm9qZWN0aW9uVHlwZSk9PT0id2lua2VsMyI/MTA6MCk7cD1uZXcgZ3QobmV3IFQobVswXSxtWzFdLDApLG5ldyBUKGdbMF0sZ1sxXSwwKSl9Y29uc3QgeT1kLm1hcCgobSxnKT0+e3ZhciBiO3JldHVybiBKMCh7cG9pbnRzOm0sc3BsaXQ6dCxzaWRlUmVwZWF0OmUsZGVwdGg6KGI9c1tnXSkhPW51bGw/YjpzWzBdLGhhc1RvcDphLGhhc0JvdHRvbTpjLGhhc1NpZGU6bCxib3gzOnAsdG9wU2VnbWVudHM6dX0pfSk7cmV0dXJuIEppKHksbyl9O2Z1bmN0aW9uIFlhKGksdCxlLG4scyl7bGV0IHI7aWYoaT1pLnN1YmFycmF5fHxpLnNsaWNlP2k6aS5idWZmZXIsZT1lLnN1YmFycmF5fHxlLnNsaWNlP2U6ZS5idWZmZXIsaT10P2kuc3ViYXJyYXk/aS5zdWJhcnJheSh0LHMmJnQrcyk6aS5zbGljZSh0LHMmJnQrcyk6aSxlLnNldCllLnNldChpLG4pO2Vsc2UgZm9yKHI9MDtyPGkubGVuZ3RoO3IrKyllW3Irbl09aVtyXTtyZXR1cm4gZX1mdW5jdGlvbiBseShpKXtyZXR1cm4gaSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheT9pOmkgaW5zdGFuY2VvZiB1ZT9pLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKS5hcnJheTppLm1hcCh0PT57Y29uc3QgZT1BcnJheS5pc0FycmF5KHQpO3JldHVybiB0IGluc3RhbmNlb2YgVD9bdC54LHQueSx0LnpdOnQgaW5zdGFuY2VvZiBSP1t0LngsdC55LDBdOmUmJnQubGVuZ3RoPT09Mz9bdFswXSx0WzFdLHRbMl1dOmUmJnQubGVuZ3RoPT09Mj9bdFswXSx0WzFdLDBdOnR9KS5mbGF0KCl9Y2xhc3MgaHkgZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy50eXBlPSJNZXNoTGluZSIsdGhpcy5pc01lc2hMaW5lPSEwLHRoaXMucG9zaXRpb25zPVtdLHRoaXMucHJldmlvdXM9W10sdGhpcy5uZXh0PVtdLHRoaXMuc2lkZT1bXSx0aGlzLndpZHRoPVtdLHRoaXMuaW5kaWNlc19hcnJheT1bXSx0aGlzLnV2cz1bXSx0aGlzLmNvdW50ZXJzPVtdLHRoaXMud2lkdGhDYWxsYmFjaz1udWxsLHRoaXMuX3BvaW50cz1bXSx0aGlzLm1hdHJpeFdvcmxkPW5ldyBzdCxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLHtwb2ludHM6e2VudW1lcmFibGU6ITAsZ2V0KCl7cmV0dXJuIHRoaXMuX3BvaW50c30sc2V0KHQpe3RoaXMuc2V0UG9pbnRzKHQsdGhpcy53aWR0aENhbGxiYWNrKX19fSl9c2V0TWF0cml4V29ybGQodCl7dGhpcy5tYXRyaXhXb3JsZD10fXNldFBvaW50cyh0LGUpe2lmKHQ9bHkodCksdGhpcy5fcG9pbnRzPXQsdGhpcy53aWR0aENhbGxiYWNrPWUhPW51bGw/ZTpudWxsLHRoaXMucG9zaXRpb25zPVtdLHRoaXMuY291bnRlcnM9W10sdC5sZW5ndGgmJnRbMF1pbnN0YW5jZW9mIFQpZm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKyspe2NvbnN0IHM9dFtuXSxyPW4vKHQubGVuZ3RoLTEpO3RoaXMucG9zaXRpb25zLnB1c2gocy54LHMueSxzLnopLHRoaXMucG9zaXRpb25zLnB1c2gocy54LHMueSxzLnopLHRoaXMuY291bnRlcnMucHVzaChyKSx0aGlzLmNvdW50ZXJzLnB1c2gocil9ZWxzZSBmb3IobGV0IG49MDtuPHQubGVuZ3RoO24rPTMpe2NvbnN0IHM9bi8odC5sZW5ndGgtMSk7dGhpcy5wb3NpdGlvbnMucHVzaCh0W25dLHRbbisxXSx0W24rMl0pLHRoaXMucG9zaXRpb25zLnB1c2godFtuXSx0W24rMV0sdFtuKzJdKSx0aGlzLmNvdW50ZXJzLnB1c2gocyksdGhpcy5jb3VudGVycy5wdXNoKHMpfXRoaXMucHJvY2VzcygpfWNvbXBhcmVWMyh0LGUpe2NvbnN0IG49dCo2LHM9ZSo2O3JldHVybiB0aGlzLnBvc2l0aW9uc1tuXT09PXRoaXMucG9zaXRpb25zW3NdJiZ0aGlzLnBvc2l0aW9uc1tuKzFdPT09dGhpcy5wb3NpdGlvbnNbcysxXSYmdGhpcy5wb3NpdGlvbnNbbisyXT09PXRoaXMucG9zaXRpb25zW3MrMl19Y29weVYzKHQpe2NvbnN0IGU9dCo2O3JldHVyblt0aGlzLnBvc2l0aW9uc1tlXSx0aGlzLnBvc2l0aW9uc1tlKzFdLHRoaXMucG9zaXRpb25zW2UrMl1dfXByb2Nlc3MoKXtjb25zdCB0PXRoaXMucG9zaXRpb25zLmxlbmd0aC82O3RoaXMucHJldmlvdXM9W10sdGhpcy5uZXh0PVtdLHRoaXMuc2lkZT1bXSx0aGlzLndpZHRoPVtdLHRoaXMuaW5kaWNlc19hcnJheT1bXSx0aGlzLnV2cz1bXTtsZXQgZSxuO3RoaXMuY29tcGFyZVYzKDAsdC0xKT9uPXRoaXMuY29weVYzKHQtMik6bj10aGlzLmNvcHlWMygwKSx0aGlzLnByZXZpb3VzLnB1c2goblswXSxuWzFdLG5bMl0pLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSk7Zm9yKGxldCBzPTA7czx0O3MrKyl7aWYodGhpcy5zaWRlLnB1c2goMSksdGhpcy5zaWRlLnB1c2goLTEpLHRoaXMud2lkdGhDYWxsYmFjaz9lPXRoaXMud2lkdGhDYWxsYmFjayhzLyh0LTEpKTplPTEsdGhpcy53aWR0aC5wdXNoKGUpLHRoaXMud2lkdGgucHVzaChlKSx0aGlzLnV2cy5wdXNoKHMvKHQtMSksMCksdGhpcy51dnMucHVzaChzLyh0LTEpLDEpLHM8dC0xKXtuPXRoaXMuY29weVYzKHMpLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKTtjb25zdCByPXMqMjt0aGlzLmluZGljZXNfYXJyYXkucHVzaChyLHIrMSxyKzIpLHRoaXMuaW5kaWNlc19hcnJheS5wdXNoKHIrMixyKzEsciszKX1zPjAmJihuPXRoaXMuY29weVYzKHMpLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSkpfXRoaXMuY29tcGFyZVYzKHQtMSwwKT9uPXRoaXMuY29weVYzKDEpOm49dGhpcy5jb3B5VjModC0xKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5uZXh0LnB1c2goblswXSxuWzFdLG5bMl0pLCF0aGlzLl9hdHRyaWJ1dGVzfHx0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50IT09dGhpcy5jb3VudGVycy5sZW5ndGg/dGhpcy5fYXR0cmlidXRlcz17cG9zaXRpb246bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wb3NpdGlvbnMpLDMpLHByZXZpb3VzOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMucHJldmlvdXMpLDMpLG5leHQ6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5uZXh0KSwzKSxzaWRlOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMuc2lkZSksMSksd2lkdGg6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy53aWR0aCksMSksdXY6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy51dnMpLDIpLGluZGV4Om5ldyB4dChuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzX2FycmF5KSwxKSxjb3VudGVyczpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLmNvdW50ZXJzKSwxKX06KHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wb3NpdGlvbnMpKSx0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wcmV2aW91cykpLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5uZXh0LmNvcHlBcnJheShuZXcgRmxvYXQzMkFycmF5KHRoaXMubmV4dCkpLHRoaXMuX2F0dHJpYnV0ZXMubmV4dC5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnNpZGUuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaWRlKSksdGhpcy5fYXR0cmlidXRlcy5zaWRlLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGguY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy53aWR0aCkpLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy51di5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnV2cykpLHRoaXMuX2F0dHJpYnV0ZXMudXYubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5pbmRleC5jb3B5QXJyYXkobmV3IFVpbnQxNkFycmF5KHRoaXMuaW5kaWNlc19hcnJheSkpLHRoaXMuX2F0dHJpYnV0ZXMuaW5kZXgubmVlZHNVcGRhdGU9ITApLHRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbiksdGhpcy5zZXRBdHRyaWJ1dGUoInByZXZpb3VzIix0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzKSx0aGlzLnNldEF0dHJpYnV0ZSgibmV4dCIsdGhpcy5fYXR0cmlidXRlcy5uZXh0KSx0aGlzLnNldEF0dHJpYnV0ZSgic2lkZSIsdGhpcy5fYXR0cmlidXRlcy5zaWRlKSx0aGlzLnNldEF0dHJpYnV0ZSgid2lkdGgiLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsdGhpcy5fYXR0cmlidXRlcy51diksdGhpcy5zZXRBdHRyaWJ1dGUoImNvdW50ZXJzIix0aGlzLl9hdHRyaWJ1dGVzLmNvdW50ZXJzKSx0aGlzLnNldEF0dHJpYnV0ZSgicG9zaXRpb24iLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24pLHRoaXMuc2V0QXR0cmlidXRlKCJwcmV2aW91cyIsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cyksdGhpcy5zZXRBdHRyaWJ1dGUoIm5leHQiLHRoaXMuX2F0dHJpYnV0ZXMubmV4dCksdGhpcy5zZXRBdHRyaWJ1dGUoInNpZGUiLHRoaXMuX2F0dHJpYnV0ZXMuc2lkZSksdGhpcy5zZXRBdHRyaWJ1dGUoIndpZHRoIix0aGlzLl9hdHRyaWJ1dGVzLndpZHRoKSx0aGlzLnNldEF0dHJpYnV0ZSgidXYiLHRoaXMuX2F0dHJpYnV0ZXMudXYpLHRoaXMuc2V0QXR0cmlidXRlKCJjb3VudGVycyIsdGhpcy5fYXR0cmlidXRlcy5jb3VudGVycyksdGhpcy5zZXRJbmRleCh0aGlzLl9hdHRyaWJ1dGVzLmluZGV4KSx0aGlzLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpLHRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCl9YWR2YW5jZSh7eDp0LHk6ZSx6Om59KXtjb25zdCBzPXRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uYXJyYXkscj10aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzLmFycmF5LG89dGhpcy5fYXR0cmlidXRlcy5uZXh0LmFycmF5LGE9cy5sZW5ndGg7WWEocywwLHIsMCxhKSxZYShzLDYscywwLGEtNiksc1thLTZdPXQsc1thLTVdPWUsc1thLTRdPW4sc1thLTNdPXQsc1thLTJdPWUsc1thLTFdPW4sWWEocyw2LG8sMCxhLTYpLG9bYS02XT10LG9bYS01XT1lLG9bYS00XT1uLG9bYS0zXT10LG9bYS0yXT1lLG9bYS0xXT1uLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24ubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLm5leHQubmVlZHNVcGRhdGU9ITB9fXZhciBaaD1pPT57Y29uc3R7c2V0UG9pbnRXaWR0aDp0LG5vZGVzOmV9PWksbj1uZXcgaHk7cmV0dXJuIG4uc2V0UG9pbnRzKGUsdCksbn07Y29uc3QgdXk9KHtjb29yZGluYXRlc0FycjppLHByb2plY3Rpb246dCxsaW5lV2lkdGg6ZSx1c2VHcm91cHM6bixzcGxpdFBvbHlnb25zOnN9KT0+e2NvbnN0IHI9dCYmWGkodCk7bGV0IG89aS5tYXAoYz0+SXIoYyxyKSk7cyYmKG89SmEobyxzKSk7Y29uc3QgYT1vLm1hcCgoYyxsKT0+e3ZhciB1O2NvbnN0IGg9KHU9ZVtsXSkhPW51bGw/dTplWzBdO3JldHVybiBaaCh7bm9kZXM6YyxzZXRQb2ludFdpZHRoOigpPT5ofSl9KTtyZXR1cm4gSmkoYSxuKX07dmFyIGZ5PWk9Pntjb25zdHtwb2ludHM6dH09aSxlPXQucmVkdWNlKChzLHIsbyk9PihvPHQubGVuZ3RoLTEmJnMucHVzaChyLHRbbysxXSkscyksW10pO3JldHVybiBuZXcgdWUoKS5zZXRGcm9tUG9pbnRzKGUpfTtjb25zdCBkeT0oe2Nvb3JkaW5hdGVzQXJyOmkscHJvamVjdGlvbjp0LGxpbmVXaWR0aDplLHVzZUdyb3VwczpuLHNwbGl0UG9seWdvbnM6c30pPT57Y29uc3Qgcj10JiZYaSh0KTtsZXQgbz1pLm1hcChjPT5JcihjLHIpKTtzJiYobz1KYShvLHMpKTtjb25zdCBhPW8ubWFwKChjLGwpPT5meSh7cG9pbnRzOmMubWFwKGg9Pm5ldyBUKGgueCxoLnksMCkpfSkpO3JldHVybiBKaShhLG4pfTtmdW5jdGlvbiBweShpLHQsZT0yKXtjb25zdCBuPXQmJnQubGVuZ3RoLHM9bj90WzBdKmU6aS5sZW5ndGg7bGV0IHI9WGgoaSwwLHMsZSwhMCk7Y29uc3Qgbz1bXTtpZighcnx8ci5uZXh0PT09ci5wcmV2KXJldHVybiBvO2xldCBhLGMsbDtpZihuJiYocj13eShpLHQscixlKSksaS5sZW5ndGg+ODAqZSl7YT0xLzAsYz0xLzA7bGV0IGg9LTEvMCx1PS0xLzA7Zm9yKGxldCBmPWU7ZjxzO2YrPWUpe2NvbnN0IGQ9aVtmXSxwPWlbZisxXTtkPGEmJihhPWQpLHA8YyYmKGM9cCksZD5oJiYoaD1kKSxwPnUmJih1PXApfWw9TWF0aC5tYXgoaC1hLHUtYyksbD1sIT09MD8zMjc2Ny9sOjB9cmV0dXJuIFlpKHIsbyxlLGEsYyxsLDApLG99ZnVuY3Rpb24gWGgoaSx0LGUsbixzKXtsZXQgcjtpZihzPT09Q3koaSx0LGUsbik+MClmb3IobGV0IG89dDtvPGU7bys9bilyPWpoKG8vbnwwLGlbb10saVtvKzFdLHIpO2Vsc2UgZm9yKGxldCBvPWUtbjtvPj10O28tPW4pcj1qaChvL258MCxpW29dLGlbbysxXSxyKTtyZXR1cm4gciYma3IocixyLm5leHQpJiYoUWkocikscj1yLm5leHQpLHJ9ZnVuY3Rpb24gdm4oaSx0KXtpZighaSlyZXR1cm4gaTt0fHwodD1pKTtsZXQgZT1pLG47ZG8gaWYobj0hMSwhZS5zdGVpbmVyJiYoa3IoZSxlLm5leHQpfHxhdChlLnByZXYsZSxlLm5leHQpPT09MCkpe2lmKFFpKGUpLGU9dD1lLnByZXYsZT09PWUubmV4dClicmVhaztuPSEwfWVsc2UgZT1lLm5leHQ7d2hpbGUobnx8ZSE9PXQpO3JldHVybiB0fWZ1bmN0aW9uIFlpKGksdCxlLG4scyxyLG8pe2lmKCFpKXJldHVybjshbyYmciYmX3koaSxuLHMscik7bGV0IGE9aTtmb3IoO2kucHJldiE9PWkubmV4dDspe2NvbnN0IGM9aS5wcmV2LGw9aS5uZXh0O2lmKHI/bXkoaSxuLHMscik6eXkoaSkpe3QucHVzaChjLmksaS5pLGwuaSksUWkoaSksaT1sLm5leHQsYT1sLm5leHQ7Y29udGludWV9aWYoaT1sLGk9PT1hKXtvP289PT0xPyhpPWd5KHZuKGkpLHQpLFlpKGksdCxlLG4scyxyLDIpKTpvPT09MiYmeHkoaSx0LGUsbixzLHIpOllpKHZuKGkpLHQsZSxuLHMsciwxKTticmVha319fWZ1bmN0aW9uIHl5KGkpe2NvbnN0IHQ9aS5wcmV2LGU9aSxuPWkubmV4dDtpZihhdCh0LGUsbik+PTApcmV0dXJuITE7Y29uc3Qgcz10Lngscj1lLngsbz1uLngsYT10LnksYz1lLnksbD1uLnksaD1zPHI/czxvP3M6bzpyPG8/cjpvLHU9YTxjP2E8bD9hOmw6YzxsP2M6bCxmPXM+cj9zPm8/czpvOnI+bz9yOm8sZD1hPmM/YT5sP2E6bDpjPmw/YzpsO2xldCBwPW4ubmV4dDtmb3IoO3AhPT10Oyl7aWYocC54Pj1oJiZwLng8PWYmJnAueT49dSYmcC55PD1kJiZjaShzLGEscixjLG8sbCxwLngscC55KSYmYXQocC5wcmV2LHAscC5uZXh0KT49MClyZXR1cm4hMTtwPXAubmV4dH1yZXR1cm4hMH1mdW5jdGlvbiBteShpLHQsZSxuKXtjb25zdCBzPWkucHJldixyPWksbz1pLm5leHQ7aWYoYXQocyxyLG8pPj0wKXJldHVybiExO2NvbnN0IGE9cy54LGM9ci54LGw9by54LGg9cy55LHU9ci55LGY9by55LGQ9YTxjP2E8bD9hOmw6YzxsP2M6bCxwPWg8dT9oPGY/aDpmOnU8Zj91OmYseT1hPmM/YT5sP2E6bDpjPmw/YzpsLG09aD51P2g+Zj9oOmY6dT5mP3U6ZixnPWphKGQscCx0LGUsbiksYj1qYSh5LG0sdCxlLG4pO2xldCB3PWkucHJldloseD1pLm5leHRaO2Zvcig7dyYmdy56Pj1nJiZ4JiZ4Lno8PWI7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmY2koYSxoLGMsdSxsLGYsdy54LHcueSkmJmF0KHcucHJldix3LHcubmV4dCk+PTB8fCh3PXcucHJldloseC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJmNpKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZhdCh4LnByZXYseCx4Lm5leHQpPj0wKSlyZXR1cm4hMTt4PXgubmV4dFp9Zm9yKDt3JiZ3Lno+PWc7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmY2koYSxoLGMsdSxsLGYsdy54LHcueSkmJmF0KHcucHJldix3LHcubmV4dCk+PTApcmV0dXJuITE7dz13LnByZXZafWZvcig7eCYmeC56PD1iOyl7aWYoeC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJmNpKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZhdCh4LnByZXYseCx4Lm5leHQpPj0wKXJldHVybiExO3g9eC5uZXh0Wn1yZXR1cm4hMH1mdW5jdGlvbiBneShpLHQpe2xldCBlPWk7ZG97Y29uc3Qgbj1lLnByZXYscz1lLm5leHQubmV4dDsha3IobixzKSYmSmgobixlLGUubmV4dCxzKSYmamkobixzKSYmamkocyxuKSYmKHQucHVzaChuLmksZS5pLHMuaSksUWkoZSksUWkoZS5uZXh0KSxlPWk9cyksZT1lLm5leHR9d2hpbGUoZSE9PWkpO3JldHVybiB2bihlKX1mdW5jdGlvbiB4eShpLHQsZSxuLHMscil7bGV0IG89aTtkb3tsZXQgYT1vLm5leHQubmV4dDtmb3IoO2EhPT1vLnByZXY7KXtpZihvLmkhPT1hLmkmJlR5KG8sYSkpe2xldCBjPVloKG8sYSk7bz12bihvLG8ubmV4dCksYz12bihjLGMubmV4dCksWWkobyx0LGUsbixzLHIsMCksWWkoYyx0LGUsbixzLHIsMCk7cmV0dXJufWE9YS5uZXh0fW89by5uZXh0fXdoaWxlKG8hPT1pKX1mdW5jdGlvbiB3eShpLHQsZSxuKXtjb25zdCBzPVtdO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdKm4sYz1yPG8tMT90W3IrMV0qbjppLmxlbmd0aCxsPVhoKGksYSxjLG4sITEpO2w9PT1sLm5leHQmJihsLnN0ZWluZXI9ITApLHMucHVzaCh6eShsKSl9cy5zb3J0KGJ5KTtmb3IobGV0IHI9MDtyPHMubGVuZ3RoO3IrKyllPU15KHNbcl0sZSk7cmV0dXJuIGV9ZnVuY3Rpb24gYnkoaSx0KXtyZXR1cm4gaS54LXQueH1mdW5jdGlvbiBNeShpLHQpe2NvbnN0IGU9QXkoaSx0KTtpZighZSlyZXR1cm4gdDtjb25zdCBuPVloKGUsaSk7cmV0dXJuIHZuKG4sbi5uZXh0KSx2bihlLGUubmV4dCl9ZnVuY3Rpb24gQXkoaSx0KXtsZXQgZT10O2NvbnN0IG49aS54LHM9aS55O2xldCByPS0xLzAsbztkb3tpZihzPD1lLnkmJnM+PWUubmV4dC55JiZlLm5leHQueSE9PWUueSl7Y29uc3QgdT1lLngrKHMtZS55KSooZS5uZXh0LngtZS54KS8oZS5uZXh0LnktZS55KTtpZih1PD1uJiZ1PnImJihyPXUsbz1lLng8ZS5uZXh0Lng/ZTplLm5leHQsdT09PW4pKXJldHVybiBvfWU9ZS5uZXh0fXdoaWxlKGUhPT10KTtpZighbylyZXR1cm4gbnVsbDtjb25zdCBhPW8sYz1vLngsbD1vLnk7bGV0IGg9MS8wO2U9bztkb3tpZihuPj1lLngmJmUueD49YyYmbiE9PWUueCYmY2koczxsP246cixzLGMsbCxzPGw/cjpuLHMsZS54LGUueSkpe2NvbnN0IHU9TWF0aC5hYnMocy1lLnkpLyhuLWUueCk7amkoZSxpKSYmKHU8aHx8dT09PWgmJihlLng+by54fHxlLng9PT1vLngmJlN5KG8sZSkpKSYmKG89ZSxoPXUpfWU9ZS5uZXh0fXdoaWxlKGUhPT1hKTtyZXR1cm4gb31mdW5jdGlvbiBTeShpLHQpe3JldHVybiBhdChpLnByZXYsaSx0LnByZXYpPDAmJmF0KHQubmV4dCxpLGkubmV4dCk8MH1mdW5jdGlvbiBfeShpLHQsZSxuKXtsZXQgcz1pO2RvIHMuej09PTAmJihzLno9amEocy54LHMueSx0LGUsbikpLHMucHJldlo9cy5wcmV2LHMubmV4dFo9cy5uZXh0LHM9cy5uZXh0O3doaWxlKHMhPT1pKTtzLnByZXZaLm5leHRaPW51bGwscy5wcmV2Wj1udWxsLHZ5KHMpfWZ1bmN0aW9uIHZ5KGkpe2xldCB0LGU9MTtkb3tsZXQgbj1pLHM7aT1udWxsO2xldCByPW51bGw7Zm9yKHQ9MDtuOyl7dCsrO2xldCBvPW4sYT0wO2ZvcihsZXQgbD0wO2w8ZSYmKGErKyxvPW8ubmV4dFosISFvKTtsKyspO2xldCBjPWU7Zm9yKDthPjB8fGM+MCYmbzspYSE9PTAmJihjPT09MHx8IW98fG4uejw9by56KT8ocz1uLG49bi5uZXh0WixhLS0pOihzPW8sbz1vLm5leHRaLGMtLSkscj9yLm5leHRaPXM6aT1zLHMucHJldlo9cixyPXM7bj1vfXIubmV4dFo9bnVsbCxlKj0yfXdoaWxlKHQ+MSk7cmV0dXJuIGl9ZnVuY3Rpb24gamEoaSx0LGUsbixzKXtyZXR1cm4gaT0oaS1lKSpzfDAsdD0odC1uKSpzfDAsaT0oaXxpPDw4KSYxNjcxMTkzNSxpPShpfGk8PDQpJjI1MjY0NTEzNSxpPShpfGk8PDIpJjg1ODk5MzQ1OSxpPShpfGk8PDEpJjE0MzE2NTU3NjUsdD0odHx0PDw4KSYxNjcxMTkzNSx0PSh0fHQ8PDQpJjI1MjY0NTEzNSx0PSh0fHQ8PDIpJjg1ODk5MzQ1OSx0PSh0fHQ8PDEpJjE0MzE2NTU3NjUsaXx0PDwxfWZ1bmN0aW9uIHp5KGkpe2xldCB0PWksZT1pO2RvKHQueDxlLnh8fHQueD09PWUueCYmdC55PGUueSkmJihlPXQpLHQ9dC5uZXh0O3doaWxlKHQhPT1pKTtyZXR1cm4gZX1mdW5jdGlvbiBjaShpLHQsZSxuLHMscixvLGEpe3JldHVybihzLW8pKih0LWEpPj0oaS1vKSooci1hKSYmKGktbykqKG4tYSk+PShlLW8pKih0LWEpJiYoZS1vKSooci1hKT49KHMtbykqKG4tYSl9ZnVuY3Rpb24gVHkoaSx0KXtyZXR1cm4gaS5uZXh0LmkhPT10LmkmJmkucHJldi5pIT09dC5pJiYhRXkoaSx0KSYmKGppKGksdCkmJmppKHQsaSkmJlB5KGksdCkmJihhdChpLnByZXYsaSx0LnByZXYpfHxhdChpLHQucHJldix0KSl8fGtyKGksdCkmJmF0KGkucHJldixpLGkubmV4dCk+MCYmYXQodC5wcmV2LHQsdC5uZXh0KT4wKX1mdW5jdGlvbiBhdChpLHQsZSl7cmV0dXJuKHQueS1pLnkpKihlLngtdC54KS0odC54LWkueCkqKGUueS10LnkpfWZ1bmN0aW9uIGtyKGksdCl7cmV0dXJuIGkueD09PXQueCYmaS55PT09dC55fWZ1bmN0aW9uIEpoKGksdCxlLG4pe2NvbnN0IHM9UnIoYXQoaSx0LGUpKSxyPVJyKGF0KGksdCxuKSksbz1ScihhdChlLG4saSkpLGE9UnIoYXQoZSxuLHQpKTtyZXR1cm4hIShzIT09ciYmbyE9PWF8fHM9PT0wJiZOcihpLGUsdCl8fHI9PT0wJiZOcihpLG4sdCl8fG89PT0wJiZOcihlLGksbil8fGE9PT0wJiZOcihlLHQsbikpfWZ1bmN0aW9uIE5yKGksdCxlKXtyZXR1cm4gdC54PD1NYXRoLm1heChpLngsZS54KSYmdC54Pj1NYXRoLm1pbihpLngsZS54KSYmdC55PD1NYXRoLm1heChpLnksZS55KSYmdC55Pj1NYXRoLm1pbihpLnksZS55KX1mdW5jdGlvbiBScihpKXtyZXR1cm4gaT4wPzE6aTwwPy0xOjB9ZnVuY3Rpb24gRXkoaSx0KXtsZXQgZT1pO2Rve2lmKGUuaSE9PWkuaSYmZS5uZXh0LmkhPT1pLmkmJmUuaSE9PXQuaSYmZS5uZXh0LmkhPT10LmkmJkpoKGUsZS5uZXh0LGksdCkpcmV0dXJuITA7ZT1lLm5leHR9d2hpbGUoZSE9PWkpO3JldHVybiExfWZ1bmN0aW9uIGppKGksdCl7cmV0dXJuIGF0KGkucHJldixpLGkubmV4dCk8MD9hdChpLHQsaS5uZXh0KT49MCYmYXQoaSxpLnByZXYsdCk+PTA6YXQoaSx0LGkucHJldik8MHx8YXQoaSxpLm5leHQsdCk8MH1mdW5jdGlvbiBQeShpLHQpe2xldCBlPWksbj0hMTtjb25zdCBzPShpLngrdC54KS8yLHI9KGkueSt0LnkpLzI7ZG8gZS55PnIhPWUubmV4dC55PnImJmUubmV4dC55IT09ZS55JiZzPChlLm5leHQueC1lLngpKihyLWUueSkvKGUubmV4dC55LWUueSkrZS54JiYobj0hbiksZT1lLm5leHQ7d2hpbGUoZSE9PWkpO3JldHVybiBufWZ1bmN0aW9uIFloKGksdCl7Y29uc3QgZT1RYShpLmksaS54LGkueSksbj1RYSh0LmksdC54LHQueSkscz1pLm5leHQscj10LnByZXY7cmV0dXJuIGkubmV4dD10LHQucHJldj1pLGUubmV4dD1zLHMucHJldj1lLG4ubmV4dD1lLGUucHJldj1uLHIubmV4dD1uLG4ucHJldj1yLG59ZnVuY3Rpb24gamgoaSx0LGUsbil7Y29uc3Qgcz1RYShpLHQsZSk7cmV0dXJuIG4/KHMubmV4dD1uLm5leHQscy5wcmV2PW4sbi5uZXh0LnByZXY9cyxuLm5leHQ9cyk6KHMucHJldj1zLHMubmV4dD1zKSxzfWZ1bmN0aW9uIFFpKGkpe2kubmV4dC5wcmV2PWkucHJldixpLnByZXYubmV4dD1pLm5leHQsaS5wcmV2WiYmKGkucHJldloubmV4dFo9aS5uZXh0WiksaS5uZXh0WiYmKGkubmV4dFoucHJldlo9aS5wcmV2Wil9ZnVuY3Rpb24gUWEoaSx0LGUpe3JldHVybntpLHg6dCx5OmUscHJldjpudWxsLG5leHQ6bnVsbCx6OjAscHJldlo6bnVsbCxuZXh0WjpudWxsLHN0ZWluZXI6ITF9fWZ1bmN0aW9uIEN5KGksdCxlLG4pe2xldCBzPTA7Zm9yKGxldCByPXQsbz1lLW47cjxlO3IrPW4pcys9KGlbb10taVtyXSkqKGlbcisxXStpW28rMV0pLG89cjtyZXR1cm4gc31mdW5jdGlvbiBRaChpKXtjb25zdCB0PVtdLGU9W10sbj1pWzBdWzBdLmxlbmd0aDtsZXQgcz0wLHI9MDtmb3IoY29uc3QgbyBvZiBpKXtmb3IoY29uc3QgYSBvZiBvKWZvcihsZXQgYz0wO2M8bjtjKyspdC5wdXNoKGFbY10pO3ImJihzKz1yLGUucHVzaChzKSkscj1vLmxlbmd0aH1yZXR1cm57dmVydGljZXM6dCxob2xlczplLGRpbWVuc2lvbnM6bn19ZnVuY3Rpb24gQnkoaSl7aWYoIWkpdGhyb3cgbmV3IEVycm9yKCJjb29yZCBpcyByZXF1aXJlZCIpO2lmKCFBcnJheS5pc0FycmF5KGkpKXtpZihpLnR5cGU9PT0iRmVhdHVyZSImJmkuZ2VvbWV0cnkhPT1udWxsJiZpLmdlb21ldHJ5LnR5cGU9PT0iUG9pbnQiKXJldHVyblsuLi5pLmdlb21ldHJ5LmNvb3JkaW5hdGVzXTtpZihpLnR5cGU9PT0iUG9pbnQiKXJldHVyblsuLi5pLmNvb3JkaW5hdGVzXX1pZihBcnJheS5pc0FycmF5KGkpJiZpLmxlbmd0aD49MiYmIUFycmF5LmlzQXJyYXkoaVswXSkmJiFBcnJheS5pc0FycmF5KGlbMV0pKXJldHVyblsuLi5pXTt0aHJvdyBuZXcgRXJyb3IoImNvb3JkIG11c3QgYmUgR2VvSlNPTiBQb2ludCBvciBhbiBBcnJheSBvZiBudW1iZXJzIil9ZnVuY3Rpb24gRnkoaSl7aWYoQXJyYXkuaXNBcnJheShpKSlyZXR1cm4gaTtpZihpLnR5cGU9PT0iRmVhdHVyZSIpe2lmKGkuZ2VvbWV0cnkhPT1udWxsKXJldHVybiBpLmdlb21ldHJ5LmNvb3JkaW5hdGVzfWVsc2UgaWYoaS5jb29yZGluYXRlcylyZXR1cm4gaS5jb29yZGluYXRlczt0aHJvdyBuZXcgRXJyb3IoImNvb3JkcyBtdXN0IGJlIEdlb0pTT04gRmVhdHVyZSwgR2VvbWV0cnkgT2JqZWN0IG9yIGFuIEFycmF5Iil9ZnVuY3Rpb24gSXkoaSl7cmV0dXJuIGkudHlwZT09PSJGZWF0dXJlIj9pLmdlb21ldHJ5Oml9ZnVuY3Rpb24ga3koaSl7Y29uc3QgdD1GeShpKTtsZXQgZT0wLG49MSxzLHI7Zm9yKDtuPHQubGVuZ3RoOylzPXJ8fHRbMF0scj10W25dLGUrPShyWzBdLXNbMF0pKihyWzFdK3NbMV0pLG4rKztyZXR1cm4gZT4wfXZhciBOeT1reTtjb25zdCBxZT0xMTEwMjIzMDI0NjI1MTU2NWUtMzIsdnQ9MTM0MjE3NzI5LFJ5PSgzKzgqcWUpKnFlO2Z1bmN0aW9uIEthKGksdCxlLG4scyl7bGV0IHIsbyxhLGMsbD10WzBdLGg9blswXSx1PTAsZj0wO2g+bD09aD4tbD8ocj1sLGw9dFsrK3VdKToocj1oLGg9blsrK2ZdKTtsZXQgZD0wO2lmKHU8aSYmZjxlKWZvcihoPmw9PWg+LWw/KG89bCtyLGE9ci0oby1sKSxsPXRbKyt1XSk6KG89aCtyLGE9ci0oby1oKSxoPW5bKytmXSkscj1vLGEhPT0wJiYoc1tkKytdPWEpO3U8aSYmZjxlOyloPmw9PWg+LWw/KG89citsLGM9by1yLGE9ci0oby1jKSsobC1jKSxsPXRbKyt1XSk6KG89citoLGM9by1yLGE9ci0oby1jKSsoaC1jKSxoPW5bKytmXSkscj1vLGEhPT0wJiYoc1tkKytdPWEpO2Zvcig7dTxpOylvPXIrbCxjPW8tcixhPXItKG8tYykrKGwtYyksbD10WysrdV0scj1vLGEhPT0wJiYoc1tkKytdPWEpO2Zvcig7ZjxlOylvPXIraCxjPW8tcixhPXItKG8tYykrKGgtYyksaD1uWysrZl0scj1vLGEhPT0wJiYoc1tkKytdPWEpO3JldHVybihyIT09MHx8ZD09PTApJiYoc1tkKytdPXIpLGR9ZnVuY3Rpb24gTHkoaSx0KXtsZXQgZT10WzBdO2ZvcihsZXQgbj0xO248aTtuKyspZSs9dFtuXTtyZXR1cm4gZX1mdW5jdGlvbiBLaShpKXtyZXR1cm4gbmV3IEZsb2F0NjRBcnJheShpKX1jb25zdCBPeT0oMysxNipxZSkqcWUsRHk9KDIrMTIqcWUpKnFlLCR5PSg5KzY0KnFlKSpxZSpxZSxsaT1LaSg0KSxLaD1LaSg4KSx0dT1LaSgxMiksZXU9S2koMTYpLEJ0PUtpKDQpO2Z1bmN0aW9uIFZ5KGksdCxlLG4scyxyLG8pe2xldCBhLGMsbCxoLHUsZixkLHAseSxtLGcsYix3LHgsTSxBLFMsXztjb25zdCBFPWktcyx6PWUtcyx2PXQtcixDPW4tcjt4PUUqQyxmPXZ0KkUsZD1mLShmLUUpLHA9RS1kLGY9dnQqQyx5PWYtKGYtQyksbT1DLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9dip6LGY9dnQqdixkPWYtKGYtdikscD12LWQsZj12dCp6LHk9Zi0oZi16KSxtPXoteSxTPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLVMsdT1NLWcsbGlbMF09TS0oZyt1KSsodS1TKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsbGlbMV09dy0oZyt1KSsodS1BKSxfPWIrZyx1PV8tYixsaVsyXT1iLShfLXUpKyhnLXUpLGxpWzNdPV87bGV0IFA9THkoNCxsaSksRj1EeSpvO2lmKFA+PUZ8fC1QPj1GfHwodT1pLUUsYT1pLShFK3UpKyh1LXMpLHU9ZS16LGw9ZS0oeit1KSsodS1zKSx1PXQtdixjPXQtKHYrdSkrKHUtciksdT1uLUMsaD1uLShDK3UpKyh1LXIpLGE9PT0wJiZjPT09MCYmbD09PTAmJmg9PT0wKXx8KEY9JHkqbytSeSpNYXRoLmFicyhQKSxQKz1FKmgrQyphLSh2KmwreipjKSxQPj1GfHwtUD49RikpcmV0dXJuIFA7eD1hKkMsZj12dCphLGQ9Zi0oZi1hKSxwPWEtZCxmPXZ0KkMseT1mLShmLUMpLG09Qy15LE09cCptLSh4LWQqeS1wKnktZCptKSxBPWMqeixmPXZ0KmMsZD1mLShmLWMpLHA9Yy1kLGY9dnQqeix5PWYtKGYteiksbT16LXksUz1wKm0tKEEtZCp5LXAqeS1kKm0pLGc9TS1TLHU9TS1nLEJ0WzBdPU0tKGcrdSkrKHUtUyksYj14K2csdT1iLXgsdz14LShiLXUpKyhnLXUpLGc9dy1BLHU9dy1nLEJ0WzFdPXctKGcrdSkrKHUtQSksXz1iK2csdT1fLWIsQnRbMl09Yi0oXy11KSsoZy11KSxCdFszXT1fO2NvbnN0IEI9S2EoNCxsaSw0LEJ0LEtoKTt4PUUqaCxmPXZ0KkUsZD1mLShmLUUpLHA9RS1kLGY9dnQqaCx5PWYtKGYtaCksbT1oLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9dipsLGY9dnQqdixkPWYtKGYtdikscD12LWQsZj12dCpsLHk9Zi0oZi1sKSxtPWwteSxTPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLVMsdT1NLWcsQnRbMF09TS0oZyt1KSsodS1TKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsQnRbMV09dy0oZyt1KSsodS1BKSxfPWIrZyx1PV8tYixCdFsyXT1iLShfLXUpKyhnLXUpLEJ0WzNdPV87Y29uc3QgST1LYShCLEtoLDQsQnQsdHUpO3g9YSpoLGY9dnQqYSxkPWYtKGYtYSkscD1hLWQsZj12dCpoLHk9Zi0oZi1oKSxtPWgteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT1jKmwsZj12dCpjLGQ9Zi0oZi1jKSxwPWMtZCxmPXZ0KmwseT1mLShmLWwpLG09bC15LFM9cCptLShBLWQqeS1wKnktZCptKSxnPU0tUyx1PU0tZyxCdFswXT1NLShnK3UpKyh1LVMpLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxCdFsxXT13LShnK3UpKyh1LUEpLF89YitnLHU9Xy1iLEJ0WzJdPWItKF8tdSkrKGctdSksQnRbM109Xztjb25zdCBrPUthKEksdHUsNCxCdCxldSk7cmV0dXJuIGV1W2stMV19ZnVuY3Rpb24gTHIoaSx0LGUsbixzLHIpe2NvbnN0IG89KHQtcikqKGUtcyksYT0oaS1zKSoobi1yKSxjPW8tYTtpZihvPT09MHx8YT09PTB8fG8+MCE9YT4wKXJldHVybiBjO2NvbnN0IGw9TWF0aC5hYnMobythKTtyZXR1cm4gTWF0aC5hYnMoYyk+PU95Kmw/YzotVnkoaSx0LGUsbixzLHIsbCl9Y29uc3QgbnU9TWF0aC5wb3coMiwtNTIpLE9yPW5ldyBVaW50MzJBcnJheSg1MTIpO2NsYXNzIHRze3N0YXRpYyBmcm9tKHQsZT1HeSxuPVp5KXtjb25zdCBzPXQubGVuZ3RoLHI9bmV3IEZsb2F0NjRBcnJheShzKjIpO2ZvcihsZXQgbz0wO288cztvKyspe2NvbnN0IGE9dFtvXTtyWzIqb109ZShhKSxyWzIqbysxXT1uKGEpfXJldHVybiBuZXcgdHMocil9Y29uc3RydWN0b3IodCl7Y29uc3QgZT10Lmxlbmd0aD4+MTtpZihlPjAmJnR5cGVvZiB0WzBdIT0ibnVtYmVyIil0aHJvdyBuZXcgRXJyb3IoIkV4cGVjdGVkIGNvb3JkcyB0byBjb250YWluIG51bWJlcnMuIik7dGhpcy5jb29yZHM9dDtjb25zdCBuPU1hdGgubWF4KDIqZS01LDApO3RoaXMuX3RyaWFuZ2xlcz1uZXcgVWludDMyQXJyYXkobiozKSx0aGlzLl9oYWxmZWRnZXM9bmV3IEludDMyQXJyYXkobiozKSx0aGlzLl9oYXNoU2l6ZT1NYXRoLmNlaWwoTWF0aC5zcXJ0KGUpKSx0aGlzLl9odWxsUHJldj1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbE5leHQ9bmV3IFVpbnQzMkFycmF5KGUpLHRoaXMuX2h1bGxUcmk9bmV3IFVpbnQzMkFycmF5KGUpLHRoaXMuX2h1bGxIYXNoPW5ldyBJbnQzMkFycmF5KHRoaXMuX2hhc2hTaXplKS5maWxsKC0xKSx0aGlzLl9pZHM9bmV3IFVpbnQzMkFycmF5KGUpLHRoaXMuX2Rpc3RzPW5ldyBGbG9hdDY0QXJyYXkoZSksdGhpcy51cGRhdGUoKX11cGRhdGUoKXtjb25zdHtjb29yZHM6dCxfaHVsbFByZXY6ZSxfaHVsbE5leHQ6bixfaHVsbFRyaTpzLF9odWxsSGFzaDpyfT10aGlzLG89dC5sZW5ndGg+PjE7bGV0IGE9MS8wLGM9MS8wLGw9LTEvMCxoPS0xLzA7Zm9yKGxldCB6PTA7ejxvO3orKyl7Y29uc3Qgdj10WzIqel0sQz10WzIqeisxXTt2PGEmJihhPXYpLEM8YyYmKGM9Qyksdj5sJiYobD12KSxDPmgmJihoPUMpLHRoaXMuX2lkc1t6XT16fWNvbnN0IHU9KGErbCkvMixmPShjK2gpLzI7bGV0IGQ9MS8wLHAseSxtO2ZvcihsZXQgej0wO3o8bzt6Kyspe2NvbnN0IHY9dGModSxmLHRbMip6XSx0WzIqeisxXSk7djxkJiYocD16LGQ9dil9Y29uc3QgZz10WzIqcF0sYj10WzIqcCsxXTtkPTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtpZih6PT09cCljb250aW51ZTtjb25zdCB2PXRjKGcsYix0WzIqel0sdFsyKnorMV0pO3Y8ZCYmdj4wJiYoeT16LGQ9dil9bGV0IHc9dFsyKnldLHg9dFsyKnkrMV0sTT0xLzA7Zm9yKGxldCB6PTA7ejxvO3orKyl7aWYoej09PXB8fHo9PT15KWNvbnRpbnVlO2NvbnN0IHY9SHkoZyxiLHcseCx0WzIqel0sdFsyKnorMV0pO3Y8TSYmKG09eixNPXYpfWxldCBBPXRbMiptXSxTPXRbMiptKzFdO2lmKE09PT0xLzApe2ZvcihsZXQgQz0wO0M8bztDKyspdGhpcy5fZGlzdHNbQ109dFsyKkNdLXRbMF18fHRbMipDKzFdLXRbMV07aGkodGhpcy5faWRzLHRoaXMuX2Rpc3RzLDAsby0xKTtjb25zdCB6PW5ldyBVaW50MzJBcnJheShvKTtsZXQgdj0wO2ZvcihsZXQgQz0wLFA9LTEvMDtDPG87QysrKXtjb25zdCBGPXRoaXMuX2lkc1tDXTt0aGlzLl9kaXN0c1tGXT5QJiYoelt2KytdPUYsUD10aGlzLl9kaXN0c1tGXSl9dGhpcy5odWxsPXouc3ViYXJyYXkoMCx2KSx0aGlzLnRyaWFuZ2xlcz1uZXcgVWludDMyQXJyYXkoMCksdGhpcy5oYWxmZWRnZXM9bmV3IFVpbnQzMkFycmF5KDApO3JldHVybn1pZihMcihnLGIsdyx4LEEsUyk8MCl7Y29uc3Qgej15LHY9dyxDPXg7eT1tLHc9QSx4PVMsbT16LEE9dixTPUN9Y29uc3QgXz1XeShnLGIsdyx4LEEsUyk7dGhpcy5fY3g9Xy54LHRoaXMuX2N5PV8ueTtmb3IobGV0IHo9MDt6PG87eisrKXRoaXMuX2Rpc3RzW3pdPXRjKHRbMip6XSx0WzIqeisxXSxfLngsXy55KTtoaSh0aGlzLl9pZHMsdGhpcy5fZGlzdHMsMCxvLTEpLHRoaXMuX2h1bGxTdGFydD1wO2xldCBFPTM7bltwXT1lW21dPXksblt5XT1lW3BdPW0sblttXT1lW3ldPXAsc1twXT0wLHNbeV09MSxzW21dPTIsci5maWxsKC0xKSxyW3RoaXMuX2hhc2hLZXkoZyxiKV09cCxyW3RoaXMuX2hhc2hLZXkodyx4KV09eSxyW3RoaXMuX2hhc2hLZXkoQSxTKV09bSx0aGlzLnRyaWFuZ2xlc0xlbj0wLHRoaXMuX2FkZFRyaWFuZ2xlKHAseSxtLC0xLC0xLC0xKTtmb3IobGV0IHo9MCx2LEM7ejx0aGlzLl9pZHMubGVuZ3RoO3orKyl7Y29uc3QgUD10aGlzLl9pZHNbel0sRj10WzIqUF0sQj10WzIqUCsxXTtpZih6PjAmJk1hdGguYWJzKEYtdik8PW51JiZNYXRoLmFicyhCLUMpPD1udXx8KHY9RixDPUIsUD09PXB8fFA9PT15fHxQPT09bSkpY29udGludWU7bGV0IEk9MDtmb3IobGV0IGR0PTAsRHQ9dGhpcy5faGFzaEtleShGLEIpO2R0PHRoaXMuX2hhc2hTaXplJiYoST1yWyhEdCtkdCkldGhpcy5faGFzaFNpemVdLCEoSSE9PS0xJiZJIT09bltJXSkpO2R0KyspO0k9ZVtJXTtsZXQgaz1JLEQ7Zm9yKDtEPW5ba10sTHIoRixCLHRbMiprXSx0WzIqaysxXSx0WzIqRF0sdFsyKkQrMV0pPj0wOylpZihrPUQsaz09PUkpe2s9LTE7YnJlYWt9aWYoaz09PS0xKWNvbnRpbnVlO2xldCBVPXRoaXMuX2FkZFRyaWFuZ2xlKGssUCxuW2tdLC0xLC0xLHNba10pO3NbUF09dGhpcy5fbGVnYWxpemUoVSsyKSxzW2tdPVUsRSsrO2xldCBqPW5ba107Zm9yKDtEPW5bal0sTHIoRixCLHRbMipqXSx0WzIqaisxXSx0WzIqRF0sdFsyKkQrMV0pPDA7KVU9dGhpcy5fYWRkVHJpYW5nbGUoaixQLEQsc1tQXSwtMSxzW2pdKSxzW1BdPXRoaXMuX2xlZ2FsaXplKFUrMiksbltqXT1qLEUtLSxqPUQ7aWYoaz09PUkpZm9yKDtEPWVba10sTHIoRixCLHRbMipEXSx0WzIqRCsxXSx0WzIqa10sdFsyKmsrMV0pPDA7KVU9dGhpcy5fYWRkVHJpYW5nbGUoRCxQLGssLTEsc1trXSxzW0RdKSx0aGlzLl9sZWdhbGl6ZShVKzIpLHNbRF09VSxuW2tdPWssRS0tLGs9RDt0aGlzLl9odWxsU3RhcnQ9ZVtQXT1rLG5ba109ZVtqXT1QLG5bUF09aixyW3RoaXMuX2hhc2hLZXkoRixCKV09UCxyW3RoaXMuX2hhc2hLZXkodFsyKmtdLHRbMiprKzFdKV09a310aGlzLmh1bGw9bmV3IFVpbnQzMkFycmF5KEUpO2ZvcihsZXQgej0wLHY9dGhpcy5faHVsbFN0YXJ0O3o8RTt6KyspdGhpcy5odWxsW3pdPXYsdj1uW3ZdO3RoaXMudHJpYW5nbGVzPXRoaXMuX3RyaWFuZ2xlcy5zdWJhcnJheSgwLHRoaXMudHJpYW5nbGVzTGVuKSx0aGlzLmhhbGZlZGdlcz10aGlzLl9oYWxmZWRnZXMuc3ViYXJyYXkoMCx0aGlzLnRyaWFuZ2xlc0xlbil9X2hhc2hLZXkodCxlKXtyZXR1cm4gTWF0aC5mbG9vcihVeSh0LXRoaXMuX2N4LGUtdGhpcy5fY3kpKnRoaXMuX2hhc2hTaXplKSV0aGlzLl9oYXNoU2l6ZX1fbGVnYWxpemUodCl7Y29uc3R7X3RyaWFuZ2xlczplLF9oYWxmZWRnZXM6bixjb29yZHM6c309dGhpcztsZXQgcj0wLG89MDtmb3IoOzspe2NvbnN0IGE9blt0XSxjPXQtdCUzO2lmKG89YysodCsyKSUzLGE9PT0tMSl7aWYocj09PTApYnJlYWs7dD1PclstLXJdO2NvbnRpbnVlfWNvbnN0IGw9YS1hJTMsaD1jKyh0KzEpJTMsdT1sKyhhKzIpJTMsZj1lW29dLGQ9ZVt0XSxwPWVbaF0seT1lW3VdO2lmKHF5KHNbMipmXSxzWzIqZisxXSxzWzIqZF0sc1syKmQrMV0sc1syKnBdLHNbMipwKzFdLHNbMip5XSxzWzIqeSsxXSkpe2VbdF09eSxlW2FdPWY7Y29uc3QgZz1uW3VdO2lmKGc9PT0tMSl7bGV0IHc9dGhpcy5faHVsbFN0YXJ0O2Rve2lmKHRoaXMuX2h1bGxUcmlbd109PT11KXt0aGlzLl9odWxsVHJpW3ddPXQ7YnJlYWt9dz10aGlzLl9odWxsUHJldlt3XX13aGlsZSh3IT09dGhpcy5faHVsbFN0YXJ0KX10aGlzLl9saW5rKHQsZyksdGhpcy5fbGluayhhLG5bb10pLHRoaXMuX2xpbmsobyx1KTtjb25zdCBiPWwrKGErMSklMztyPE9yLmxlbmd0aCYmKE9yW3IrK109Yil9ZWxzZXtpZihyPT09MClicmVhazt0PU9yWy0tcl19fXJldHVybiBvfV9saW5rKHQsZSl7dGhpcy5faGFsZmVkZ2VzW3RdPWUsZSE9PS0xJiYodGhpcy5faGFsZmVkZ2VzW2VdPXQpfV9hZGRUcmlhbmdsZSh0LGUsbixzLHIsbyl7Y29uc3QgYT10aGlzLnRyaWFuZ2xlc0xlbjtyZXR1cm4gdGhpcy5fdHJpYW5nbGVzW2FdPXQsdGhpcy5fdHJpYW5nbGVzW2ErMV09ZSx0aGlzLl90cmlhbmdsZXNbYSsyXT1uLHRoaXMuX2xpbmsoYSxzKSx0aGlzLl9saW5rKGErMSxyKSx0aGlzLl9saW5rKGErMixvKSx0aGlzLnRyaWFuZ2xlc0xlbis9MyxhfX1mdW5jdGlvbiBVeShpLHQpe2NvbnN0IGU9aS8oTWF0aC5hYnMoaSkrTWF0aC5hYnModCkpO3JldHVybih0PjA/My1lOjErZSkvNH1mdW5jdGlvbiB0YyhpLHQsZSxuKXtjb25zdCBzPWktZSxyPXQtbjtyZXR1cm4gcypzK3Iqcn1mdW5jdGlvbiBxeShpLHQsZSxuLHMscixvLGEpe2NvbnN0IGM9aS1vLGw9dC1hLGg9ZS1vLHU9bi1hLGY9cy1vLGQ9ci1hLHA9YypjK2wqbCx5PWgqaCt1KnUsbT1mKmYrZCpkO3JldHVybiBjKih1Km0teSpkKS1sKihoKm0teSpmKStwKihoKmQtdSpmKTwwfWZ1bmN0aW9uIEh5KGksdCxlLG4scyxyKXtjb25zdCBvPWUtaSxhPW4tdCxjPXMtaSxsPXItdCxoPW8qbythKmEsdT1jKmMrbCpsLGY9LjUvKG8qbC1hKmMpLGQ9KGwqaC1hKnUpKmYscD0obyp1LWMqaCkqZjtyZXR1cm4gZCpkK3AqcH1mdW5jdGlvbiBXeShpLHQsZSxuLHMscil7Y29uc3Qgbz1lLWksYT1uLXQsYz1zLWksbD1yLXQsaD1vKm8rYSphLHU9YypjK2wqbCxmPS41LyhvKmwtYSpjKSxkPWkrKGwqaC1hKnUpKmYscD10KyhvKnUtYypoKSpmO3JldHVybnt4OmQseTpwfX1mdW5jdGlvbiBoaShpLHQsZSxuKXtpZihuLWU8PTIwKWZvcihsZXQgcz1lKzE7czw9bjtzKyspe2NvbnN0IHI9aVtzXSxvPXRbcl07bGV0IGE9cy0xO2Zvcig7YT49ZSYmdFtpW2FdXT5vOylpW2ErMV09aVthLS1dO2lbYSsxXT1yfWVsc2V7Y29uc3Qgcz1lK24+PjE7bGV0IHI9ZSsxLG89bjtlcyhpLHMsciksdFtpW2VdXT50W2lbbl1dJiZlcyhpLGUsbiksdFtpW3JdXT50W2lbbl1dJiZlcyhpLHIsbiksdFtpW2VdXT50W2lbcl1dJiZlcyhpLGUscik7Y29uc3QgYT1pW3JdLGM9dFthXTtmb3IoOzspe2RvIHIrKzt3aGlsZSh0W2lbcl1dPGMpO2RvIG8tLTt3aGlsZSh0W2lbb11dPmMpO2lmKG88cilicmVhaztlcyhpLHIsbyl9aVtlKzFdPWlbb10saVtvXT1hLG4tcisxPj1vLWU/KGhpKGksdCxyLG4pLGhpKGksdCxlLG8tMSkpOihoaShpLHQsZSxvLTEpLGhpKGksdCxyLG4pKX19ZnVuY3Rpb24gZXMoaSx0LGUpe2NvbnN0IG49aVt0XTtpW3RdPWlbZV0saVtlXT1ufWZ1bmN0aW9uIEd5KGkpe3JldHVybiBpWzBdfWZ1bmN0aW9uIFp5KGkpe3JldHVybiBpWzFdfWZ1bmN0aW9uIFh5KGksdCl7dmFyIGU9MCxuPTAscz0wLHI9MCxvPTAsYT0wLGM9MCxsPTAsaD1udWxsLHU9bnVsbCxmPWlbMF0sZD1pWzFdLHA9dC5sZW5ndGg7Zm9yKGU7ZTxwO2UrKyl7bj0wO3ZhciB5PXRbZV0ubGVuZ3RoLTEsbT10W2VdO2lmKGg9bVswXSxoWzBdIT09bVt5XVswXSYmaFsxXSE9PW1beV1bMV0pdGhyb3cgbmV3IEVycm9yKCJGaXJzdCBhbmQgbGFzdCBjb29yZGluYXRlcyBpbiBhIHJpbmcgbXVzdCBiZSB0aGUgc2FtZSIpO2ZvcihvPWhbMF0tZixhPWhbMV0tZCxuO248eTtuKyspe2lmKHU9bVtuKzFdLGw9dVsxXS1kLGE8MCYmbDwwfHxhPjAmJmw+MCl7aD11LGE9bCxvPWhbMF0tZjtjb250aW51ZX1pZihjPXVbMF0taVswXSxsPjAmJmE8PTApe2lmKHI9bypsLWMqYSxyPjApcz1zKzE7ZWxzZSBpZihyPT09MClyZXR1cm4gMH1lbHNlIGlmKGE+MCYmbDw9MCl7aWYocj1vKmwtYyphLHI8MClzPXMrMTtlbHNlIGlmKHI9PT0wKXJldHVybiAwfWVsc2UgaWYobD09PTAmJmE8MCl7aWYocj1vKmwtYyphLHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT09PTAmJmw8MCl7aWYocj1vKmwtYyphLHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT09PTAmJmw9PT0wKXtpZihjPD0wJiZvPj0wKXJldHVybiAwO2lmKG88PTAmJmM+PTApcmV0dXJuIDB9aD11LGE9bCxvPWN9fXJldHVybiBzJTIhPT0wfWZ1bmN0aW9uIEp5KGksdCxlPXt9KXtpZighaSl0aHJvdyBuZXcgRXJyb3IoInBvaW50IGlzIHJlcXVpcmVkIik7aWYoIXQpdGhyb3cgbmV3IEVycm9yKCJwb2x5Z29uIGlzIHJlcXVpcmVkIik7Y29uc3Qgbj1CeShpKSxzPUl5KHQpLHI9cy50eXBlLG89dC5iYm94O2xldCBhPXMuY29vcmRpbmF0ZXM7aWYobyYmWXkobixvKT09PSExKXJldHVybiExO3I9PT0iUG9seWdvbiImJihhPVthXSk7bGV0IGM9ITE7Zm9yKHZhciBsPTA7bDxhLmxlbmd0aDsrK2wpe2NvbnN0IGg9WHkobixhW2xdKTtpZihoPT09MClyZXR1cm4hZS5pZ25vcmVCb3VuZGFyeTtoJiYoYz0hMCl9cmV0dXJuIGN9ZnVuY3Rpb24gWXkoaSx0KXtyZXR1cm4gdFswXTw9aVswXSYmdFsxXTw9aVsxXSYmdFsyXT49aVswXSYmdFszXT49aVsxXX12YXIgank9Snk7Y29uc3QgaXU9MWUtNjtjbGFzcyB6bntjb25zdHJ1Y3Rvcigpe3RoaXMuX3gwPXRoaXMuX3kwPXRoaXMuX3gxPXRoaXMuX3kxPW51bGwsdGhpcy5fPSIifW1vdmVUbyh0LGUpe3RoaXMuXys9YE0ke3RoaXMuX3gwPXRoaXMuX3gxPSt0fSwke3RoaXMuX3kwPXRoaXMuX3kxPStlfWB9Y2xvc2VQYXRoKCl7dGhpcy5feDEhPT1udWxsJiYodGhpcy5feDE9dGhpcy5feDAsdGhpcy5feTE9dGhpcy5feTAsdGhpcy5fKz0iWiIpfWxpbmVUbyh0LGUpe3RoaXMuXys9YEwke3RoaXMuX3gxPSt0fSwke3RoaXMuX3kxPStlfWB9YXJjKHQsZSxuKXt0PSt0LGU9K2Usbj0rbjtjb25zdCBzPXQrbixyPWU7aWYobjwwKXRocm93IG5ldyBFcnJvcigibmVnYXRpdmUgcmFkaXVzIik7dGhpcy5feDE9PT1udWxsP3RoaXMuXys9YE0ke3N9LCR7cn1gOihNYXRoLmFicyh0aGlzLl94MS1zKT5pdXx8TWF0aC5hYnModGhpcy5feTEtcik+aXUpJiYodGhpcy5fKz0iTCIrcysiLCIrciksbiYmKHRoaXMuXys9YEEke259LCR7bn0sMCwxLDEsJHt0LW59LCR7ZX1BJHtufSwke259LDAsMSwxLCR7dGhpcy5feDE9c30sJHt0aGlzLl95MT1yfWApfXJlY3QodCxlLG4scyl7dGhpcy5fKz1gTSR7dGhpcy5feDA9dGhpcy5feDE9K3R9LCR7dGhpcy5feTA9dGhpcy5feTE9K2V9aCR7K259diR7K3N9aCR7LW59WmB9dmFsdWUoKXtyZXR1cm4gdGhpcy5ffHxudWxsfX1jbGFzcyBlY3tjb25zdHJ1Y3Rvcigpe3RoaXMuXz1bXX1tb3ZlVG8odCxlKXt0aGlzLl8ucHVzaChbdCxlXSl9Y2xvc2VQYXRoKCl7dGhpcy5fLnB1c2godGhpcy5fWzBdLnNsaWNlKCkpfWxpbmVUbyh0LGUpe3RoaXMuXy5wdXNoKFt0LGVdKX12YWx1ZSgpe3JldHVybiB0aGlzLl8ubGVuZ3RoP3RoaXMuXzpudWxsfX1jbGFzcyBReXtjb25zdHJ1Y3Rvcih0LFtlLG4scyxyXT1bMCwwLDk2MCw1MDBdKXtpZighKChzPStzKT49KGU9K2UpKXx8ISgocj0rcik+PShuPStuKSkpdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIGJvdW5kcyIpO3RoaXMuZGVsYXVuYXk9dCx0aGlzLl9jaXJjdW1jZW50ZXJzPW5ldyBGbG9hdDY0QXJyYXkodC5wb2ludHMubGVuZ3RoKjIpLHRoaXMudmVjdG9ycz1uZXcgRmxvYXQ2NEFycmF5KHQucG9pbnRzLmxlbmd0aCoyKSx0aGlzLnhtYXg9cyx0aGlzLnhtaW49ZSx0aGlzLnltYXg9cix0aGlzLnltaW49bix0aGlzLl9pbml0KCl9dXBkYXRlKCl7cmV0dXJuIHRoaXMuZGVsYXVuYXkudXBkYXRlKCksdGhpcy5faW5pdCgpLHRoaXN9X2luaXQoKXtjb25zdHtkZWxhdW5heTp7cG9pbnRzOnQsaHVsbDplLHRyaWFuZ2xlczpufSx2ZWN0b3JzOnN9PXRoaXMscj10aGlzLmNpcmN1bWNlbnRlcnM9dGhpcy5fY2lyY3VtY2VudGVycy5zdWJhcnJheSgwLG4ubGVuZ3RoLzMqMik7Zm9yKGxldCBkPTAscD0wLHk9bi5sZW5ndGgsbSxnO2Q8eTtkKz0zLHArPTIpe2NvbnN0IGI9bltkXSoyLHc9bltkKzFdKjIseD1uW2QrMl0qMixNPXRbYl0sQT10W2IrMV0sUz10W3ddLF89dFt3KzFdLEU9dFt4XSx6PXRbeCsxXSx2PVMtTSxDPV8tQSxQPUUtTSxGPXotQSxCPSh2KkYtQypQKSoyO2lmKE1hdGguYWJzKEIpPDFlLTkpe2xldCBJPTFlOTtjb25zdCBrPW5bMF0qMjtJKj1NYXRoLnNpZ24oKHRba10tTSkqRi0odFtrKzFdLUEpKlApLG09KE0rRSkvMi1JKkYsZz0oQSt6KS8yK0kqUH1lbHNle2NvbnN0IEk9MS9CLGs9dip2K0MqQyxEPVAqUCtGKkY7bT1NKyhGKmstQypEKSpJLGc9QSsodipELVAqaykqSX1yW3BdPW0scltwKzFdPWd9bGV0IG89ZVtlLmxlbmd0aC0xXSxhLGM9byo0LGwsaD10WzIqb10sdSxmPXRbMipvKzFdO3MuZmlsbCgwKTtmb3IobGV0IGQ9MDtkPGUubGVuZ3RoOysrZClvPWVbZF0sYT1jLGw9aCx1PWYsYz1vKjQsaD10WzIqb10sZj10WzIqbysxXSxzW2ErMl09c1tjXT11LWYsc1thKzNdPXNbYysxXT1oLWx9cmVuZGVyKHQpe2NvbnN0IGU9dD09bnVsbD90PW5ldyB6bjp2b2lkIDAse2RlbGF1bmF5OntoYWxmZWRnZXM6bixpbmVkZ2VzOnMsaHVsbDpyfSxjaXJjdW1jZW50ZXJzOm8sdmVjdG9yczphfT10aGlzO2lmKHIubGVuZ3RoPD0xKXJldHVybiBudWxsO2ZvcihsZXQgaD0wLHU9bi5sZW5ndGg7aDx1OysraCl7Y29uc3QgZj1uW2hdO2lmKGY8aCljb250aW51ZTtjb25zdCBkPU1hdGguZmxvb3IoaC8zKSoyLHA9TWF0aC5mbG9vcihmLzMpKjIseT1vW2RdLG09b1tkKzFdLGc9b1twXSxiPW9bcCsxXTt0aGlzLl9yZW5kZXJTZWdtZW50KHksbSxnLGIsdCl9bGV0IGMsbD1yW3IubGVuZ3RoLTFdO2ZvcihsZXQgaD0wO2g8ci5sZW5ndGg7KytoKXtjPWwsbD1yW2hdO2NvbnN0IHU9TWF0aC5mbG9vcihzW2xdLzMpKjIsZj1vW3VdLGQ9b1t1KzFdLHA9Yyo0LHk9dGhpcy5fcHJvamVjdChmLGQsYVtwKzJdLGFbcCszXSk7eSYmdGhpcy5fcmVuZGVyU2VnbWVudChmLGQseVswXSx5WzFdLHQpfXJldHVybiBlJiZlLnZhbHVlKCl9cmVuZGVyQm91bmRzKHQpe2NvbnN0IGU9dD09bnVsbD90PW5ldyB6bjp2b2lkIDA7cmV0dXJuIHQucmVjdCh0aGlzLnhtaW4sdGhpcy55bWluLHRoaXMueG1heC10aGlzLnhtaW4sdGhpcy55bWF4LXRoaXMueW1pbiksZSYmZS52YWx1ZSgpfXJlbmRlckNlbGwodCxlKXtjb25zdCBuPWU9PW51bGw/ZT1uZXcgem46dm9pZCAwLHM9dGhpcy5fY2xpcCh0KTtpZihzPT09bnVsbHx8IXMubGVuZ3RoKXJldHVybjtlLm1vdmVUbyhzWzBdLHNbMV0pO2xldCByPXMubGVuZ3RoO2Zvcig7c1swXT09PXNbci0yXSYmc1sxXT09PXNbci0xXSYmcj4xOylyLT0yO2ZvcihsZXQgbz0yO288cjtvKz0yKShzW29dIT09c1tvLTJdfHxzW28rMV0hPT1zW28tMV0pJiZlLmxpbmVUbyhzW29dLHNbbysxXSk7cmV0dXJuIGUuY2xvc2VQYXRoKCksbiYmbi52YWx1ZSgpfSpjZWxsUG9seWdvbnMoKXtjb25zdHtkZWxhdW5heTp7cG9pbnRzOnR9fT10aGlzO2ZvcihsZXQgZT0wLG49dC5sZW5ndGgvMjtlPG47KytlKXtjb25zdCBzPXRoaXMuY2VsbFBvbHlnb24oZSk7cyYmKHMuaW5kZXg9ZSx5aWVsZCBzKX19Y2VsbFBvbHlnb24odCl7Y29uc3QgZT1uZXcgZWM7cmV0dXJuIHRoaXMucmVuZGVyQ2VsbCh0LGUpLGUudmFsdWUoKX1fcmVuZGVyU2VnbWVudCh0LGUsbixzLHIpe2xldCBvO2NvbnN0IGE9dGhpcy5fcmVnaW9uY29kZSh0LGUpLGM9dGhpcy5fcmVnaW9uY29kZShuLHMpO2E9PT0wJiZjPT09MD8oci5tb3ZlVG8odCxlKSxyLmxpbmVUbyhuLHMpKToobz10aGlzLl9jbGlwU2VnbWVudCh0LGUsbixzLGEsYykpJiYoci5tb3ZlVG8ob1swXSxvWzFdKSxyLmxpbmVUbyhvWzJdLG9bM10pKX1jb250YWlucyh0LGUsbil7cmV0dXJuIGU9K2UsZSE9PWV8fChuPStuLG4hPT1uKT8hMTp0aGlzLmRlbGF1bmF5Ll9zdGVwKHQsZSxuKT09PXR9Km5laWdoYm9ycyh0KXtjb25zdCBlPXRoaXMuX2NsaXAodCk7aWYoZSlmb3IoY29uc3QgbiBvZiB0aGlzLmRlbGF1bmF5Lm5laWdoYm9ycyh0KSl7Y29uc3Qgcz10aGlzLl9jbGlwKG4pO2lmKHMpe3Q6Zm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cis9Milmb3IobGV0IGE9MCxjPXMubGVuZ3RoO2E8YzthKz0yKWlmKGVbcl09PXNbYV0mJmVbcisxXT09c1thKzFdJiZlWyhyKzIpJW9dPT1zWyhhK2MtMiklY10mJmVbKHIrMyklb109PXNbKGErYy0xKSVjXSl7eWllbGQgbjticmVhayB0fX19fV9jZWxsKHQpe2NvbnN0e2NpcmN1bWNlbnRlcnM6ZSxkZWxhdW5heTp7aW5lZGdlczpuLGhhbGZlZGdlczpzLHRyaWFuZ2xlczpyfX09dGhpcyxvPW5bdF07aWYobz09PS0xKXJldHVybiBudWxsO2NvbnN0IGE9W107bGV0IGM9bztkb3tjb25zdCBsPU1hdGguZmxvb3IoYy8zKTtpZihhLnB1c2goZVtsKjJdLGVbbCoyKzFdKSxjPWMlMz09PTI/Yy0yOmMrMSxyW2NdIT09dClicmVhaztjPXNbY119d2hpbGUoYyE9PW8mJmMhPT0tMSk7cmV0dXJuIGF9X2NsaXAodCl7aWYodD09PTAmJnRoaXMuZGVsYXVuYXkuaHVsbC5sZW5ndGg9PT0xKXJldHVyblt0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWluXTtjb25zdCBlPXRoaXMuX2NlbGwodCk7aWYoZT09PW51bGwpcmV0dXJuIG51bGw7Y29uc3R7dmVjdG9yczpufT10aGlzLHM9dCo0O3JldHVybiBuW3NdfHxuW3MrMV0/dGhpcy5fY2xpcEluZmluaXRlKHQsZSxuW3NdLG5bcysxXSxuW3MrMl0sbltzKzNdKTp0aGlzLl9jbGlwRmluaXRlKHQsZSl9X2NsaXBGaW5pdGUodCxlKXtjb25zdCBuPWUubGVuZ3RoO2xldCBzPW51bGwscixvLGE9ZVtuLTJdLGM9ZVtuLTFdLGwsaD10aGlzLl9yZWdpb25jb2RlKGEsYyksdSxmPTA7Zm9yKGxldCBkPTA7ZDxuO2QrPTIpaWYocj1hLG89YyxhPWVbZF0sYz1lW2QrMV0sbD1oLGg9dGhpcy5fcmVnaW9uY29kZShhLGMpLGw9PT0wJiZoPT09MCl1PWYsZj0wLHM/cy5wdXNoKGEsYyk6cz1bYSxjXTtlbHNle2xldCBwLHksbSxnLGI7aWYobD09PTApe2lmKChwPXRoaXMuX2NsaXBTZWdtZW50KHIsbyxhLGMsbCxoKSk9PT1udWxsKWNvbnRpbnVlO1t5LG0sZyxiXT1wfWVsc2V7aWYoKHA9dGhpcy5fY2xpcFNlZ21lbnQoYSxjLHIsbyxoLGwpKT09PW51bGwpY29udGludWU7W2csYix5LG1dPXAsdT1mLGY9dGhpcy5fZWRnZWNvZGUoeSxtKSx1JiZmJiZ0aGlzLl9lZGdlKHQsdSxmLHMscy5sZW5ndGgpLHM/cy5wdXNoKHksbSk6cz1beSxtXX11PWYsZj10aGlzLl9lZGdlY29kZShnLGIpLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCkscz9zLnB1c2goZyxiKTpzPVtnLGJdfWlmKHMpdT1mLGY9dGhpcy5fZWRnZWNvZGUoc1swXSxzWzFdKSx1JiZmJiZ0aGlzLl9lZGdlKHQsdSxmLHMscy5sZW5ndGgpO2Vsc2UgaWYodGhpcy5jb250YWlucyh0LCh0aGlzLnhtaW4rdGhpcy54bWF4KS8yLCh0aGlzLnltaW4rdGhpcy55bWF4KS8yKSlyZXR1cm5bdGhpcy54bWF4LHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1pbl07cmV0dXJuIHN9X2NsaXBTZWdtZW50KHQsZSxuLHMscixvKXtmb3IoOzspe2lmKHI9PT0wJiZvPT09MClyZXR1cm5bdCxlLG4sc107aWYociZvKXJldHVybiBudWxsO2xldCBhLGMsbD1yfHxvO2wmOD8oYT10KyhuLXQpKih0aGlzLnltYXgtZSkvKHMtZSksYz10aGlzLnltYXgpOmwmND8oYT10KyhuLXQpKih0aGlzLnltaW4tZSkvKHMtZSksYz10aGlzLnltaW4pOmwmMj8oYz1lKyhzLWUpKih0aGlzLnhtYXgtdCkvKG4tdCksYT10aGlzLnhtYXgpOihjPWUrKHMtZSkqKHRoaXMueG1pbi10KS8obi10KSxhPXRoaXMueG1pbikscj8odD1hLGU9YyxyPXRoaXMuX3JlZ2lvbmNvZGUodCxlKSk6KG49YSxzPWMsbz10aGlzLl9yZWdpb25jb2RlKG4scykpfX1fY2xpcEluZmluaXRlKHQsZSxuLHMscixvKXtsZXQgYT1BcnJheS5mcm9tKGUpLGM7aWYoKGM9dGhpcy5fcHJvamVjdChhWzBdLGFbMV0sbixzKSkmJmEudW5zaGlmdChjWzBdLGNbMV0pLChjPXRoaXMuX3Byb2plY3QoYVthLmxlbmd0aC0yXSxhW2EubGVuZ3RoLTFdLHIsbykpJiZhLnB1c2goY1swXSxjWzFdKSxhPXRoaXMuX2NsaXBGaW5pdGUodCxhKSlmb3IobGV0IGw9MCxoPWEubGVuZ3RoLHUsZj10aGlzLl9lZGdlY29kZShhW2gtMl0sYVtoLTFdKTtsPGg7bCs9Mil1PWYsZj10aGlzLl9lZGdlY29kZShhW2xdLGFbbCsxXSksdSYmZiYmKGw9dGhpcy5fZWRnZSh0LHUsZixhLGwpLGg9YS5sZW5ndGgpO2Vsc2UgdGhpcy5jb250YWlucyh0LCh0aGlzLnhtaW4rdGhpcy54bWF4KS8yLCh0aGlzLnltaW4rdGhpcy55bWF4KS8yKSYmKGE9W3RoaXMueG1pbix0aGlzLnltaW4sdGhpcy54bWF4LHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltYXhdKTtyZXR1cm4gYX1fZWRnZSh0LGUsbixzLHIpe2Zvcig7ZSE9PW47KXtsZXQgbyxhO3N3aXRjaChlKXtjYXNlIDU6ZT00O2NvbnRpbnVlO2Nhc2UgNDplPTYsbz10aGlzLnhtYXgsYT10aGlzLnltaW47YnJlYWs7Y2FzZSA2OmU9Mjtjb250aW51ZTtjYXNlIDI6ZT0xMCxvPXRoaXMueG1heCxhPXRoaXMueW1heDticmVhaztjYXNlIDEwOmU9ODtjb250aW51ZTtjYXNlIDg6ZT05LG89dGhpcy54bWluLGE9dGhpcy55bWF4O2JyZWFrO2Nhc2UgOTplPTE7Y29udGludWU7Y2FzZSAxOmU9NSxvPXRoaXMueG1pbixhPXRoaXMueW1pbjticmVha30oc1tyXSE9PW98fHNbcisxXSE9PWEpJiZ0aGlzLmNvbnRhaW5zKHQsbyxhKSYmKHMuc3BsaWNlKHIsMCxvLGEpLHIrPTIpfWlmKHMubGVuZ3RoPjQpZm9yKGxldCBvPTA7bzxzLmxlbmd0aDtvKz0yKXtjb25zdCBhPShvKzIpJXMubGVuZ3RoLGM9KG8rNCklcy5sZW5ndGg7KHNbb109PT1zW2FdJiZzW2FdPT09c1tjXXx8c1tvKzFdPT09c1thKzFdJiZzW2ErMV09PT1zW2MrMV0pJiYocy5zcGxpY2UoYSwyKSxvLT0yKX1yZXR1cm4gcn1fcHJvamVjdCh0LGUsbixzKXtsZXQgcj0xLzAsbyxhLGM7aWYoczwwKXtpZihlPD10aGlzLnltaW4pcmV0dXJuIG51bGw7KG89KHRoaXMueW1pbi1lKS9zKTxyJiYoYz10aGlzLnltaW4sYT10KyhyPW8pKm4pfWVsc2UgaWYocz4wKXtpZihlPj10aGlzLnltYXgpcmV0dXJuIG51bGw7KG89KHRoaXMueW1heC1lKS9zKTxyJiYoYz10aGlzLnltYXgsYT10KyhyPW8pKm4pfWlmKG4+MCl7aWYodD49dGhpcy54bWF4KXJldHVybiBudWxsOyhvPSh0aGlzLnhtYXgtdCkvbik8ciYmKGE9dGhpcy54bWF4LGM9ZSsocj1vKSpzKX1lbHNlIGlmKG48MCl7aWYodDw9dGhpcy54bWluKXJldHVybiBudWxsOyhvPSh0aGlzLnhtaW4tdCkvbik8ciYmKGE9dGhpcy54bWluLGM9ZSsocj1vKSpzKX1yZXR1cm5bYSxjXX1fZWRnZWNvZGUodCxlKXtyZXR1cm4odD09PXRoaXMueG1pbj8xOnQ9PT10aGlzLnhtYXg/MjowKXwoZT09PXRoaXMueW1pbj80OmU9PT10aGlzLnltYXg/ODowKX1fcmVnaW9uY29kZSh0LGUpe3JldHVybih0PHRoaXMueG1pbj8xOnQ+dGhpcy54bWF4PzI6MCl8KGU8dGhpcy55bWluPzQ6ZT50aGlzLnltYXg/ODowKX19Y29uc3QgS3k9MipNYXRoLlBJLHVpPU1hdGgucG93O2Z1bmN0aW9uIHRtKGkpe3JldHVybiBpWzBdfWZ1bmN0aW9uIGVtKGkpe3JldHVybiBpWzFdfWZ1bmN0aW9uIG5tKGkpe2NvbnN0e3RyaWFuZ2xlczp0LGNvb3JkczplfT1pO2ZvcihsZXQgbj0wO248dC5sZW5ndGg7bis9Myl7Y29uc3Qgcz0yKnRbbl0scj0yKnRbbisxXSxvPTIqdFtuKzJdO2lmKChlW29dLWVbc10pKihlW3IrMV0tZVtzKzFdKS0oZVtyXS1lW3NdKSooZVtvKzFdLWVbcysxXSk+MWUtMTApcmV0dXJuITF9cmV0dXJuITB9ZnVuY3Rpb24gaW0oaSx0LGUpe3JldHVybltpK01hdGguc2luKGkrdCkqZSx0K01hdGguY29zKGktdCkqZV19Y2xhc3MgbmN7c3RhdGljIGZyb20odCxlPXRtLG49ZW0scyl7cmV0dXJuIG5ldyBuYygibGVuZ3RoImluIHQ/c20odCxlLG4scyk6RmxvYXQ2NEFycmF5LmZyb20ocm0odCxlLG4scykpKX1jb25zdHJ1Y3Rvcih0KXt0aGlzLl9kZWxhdW5hdG9yPW5ldyB0cyh0KSx0aGlzLmluZWRnZXM9bmV3IEludDMyQXJyYXkodC5sZW5ndGgvMiksdGhpcy5faHVsbEluZGV4PW5ldyBJbnQzMkFycmF5KHQubGVuZ3RoLzIpLHRoaXMucG9pbnRzPXRoaXMuX2RlbGF1bmF0b3IuY29vcmRzLHRoaXMuX2luaXQoKX11cGRhdGUoKXtyZXR1cm4gdGhpcy5fZGVsYXVuYXRvci51cGRhdGUoKSx0aGlzLl9pbml0KCksdGhpc31faW5pdCgpe2NvbnN0IHQ9dGhpcy5fZGVsYXVuYXRvcixlPXRoaXMucG9pbnRzO2lmKHQuaHVsbCYmdC5odWxsLmxlbmd0aD4yJiZubSh0KSl7dGhpcy5jb2xsaW5lYXI9SW50MzJBcnJheS5mcm9tKHtsZW5ndGg6ZS5sZW5ndGgvMn0sKGYsZCk9PmQpLnNvcnQoKGYsZCk9PmVbMipmXS1lWzIqZF18fGVbMipmKzFdLWVbMipkKzFdKTtjb25zdCBjPXRoaXMuY29sbGluZWFyWzBdLGw9dGhpcy5jb2xsaW5lYXJbdGhpcy5jb2xsaW5lYXIubGVuZ3RoLTFdLGg9W2VbMipjXSxlWzIqYysxXSxlWzIqbF0sZVsyKmwrMV1dLHU9MWUtOCpNYXRoLmh5cG90KGhbM10taFsxXSxoWzJdLWhbMF0pO2ZvcihsZXQgZj0wLGQ9ZS5sZW5ndGgvMjtmPGQ7KytmKXtjb25zdCBwPWltKGVbMipmXSxlWzIqZisxXSx1KTtlWzIqZl09cFswXSxlWzIqZisxXT1wWzFdfXRoaXMuX2RlbGF1bmF0b3I9bmV3IHRzKGUpfWVsc2UgZGVsZXRlIHRoaXMuY29sbGluZWFyO2NvbnN0IG49dGhpcy5oYWxmZWRnZXM9dGhpcy5fZGVsYXVuYXRvci5oYWxmZWRnZXMscz10aGlzLmh1bGw9dGhpcy5fZGVsYXVuYXRvci5odWxsLHI9dGhpcy50cmlhbmdsZXM9dGhpcy5fZGVsYXVuYXRvci50cmlhbmdsZXMsbz10aGlzLmluZWRnZXMuZmlsbCgtMSksYT10aGlzLl9odWxsSW5kZXguZmlsbCgtMSk7Zm9yKGxldCBjPTAsbD1uLmxlbmd0aDtjPGw7KytjKXtjb25zdCBoPXJbYyUzPT09Mj9jLTI6YysxXTsobltjXT09PS0xfHxvW2hdPT09LTEpJiYob1toXT1jKX1mb3IobGV0IGM9MCxsPXMubGVuZ3RoO2M8bDsrK2MpYVtzW2NdXT1jO3MubGVuZ3RoPD0yJiZzLmxlbmd0aD4wJiYodGhpcy50cmlhbmdsZXM9bmV3IEludDMyQXJyYXkoMykuZmlsbCgtMSksdGhpcy5oYWxmZWRnZXM9bmV3IEludDMyQXJyYXkoMykuZmlsbCgtMSksdGhpcy50cmlhbmdsZXNbMF09c1swXSxvW3NbMF1dPTEscy5sZW5ndGg9PT0yJiYob1tzWzFdXT0wLHRoaXMudHJpYW5nbGVzWzFdPXNbMV0sdGhpcy50cmlhbmdsZXNbMl09c1sxXSkpfXZvcm9ub2kodCl7cmV0dXJuIG5ldyBReSh0aGlzLHQpfSpuZWlnaGJvcnModCl7Y29uc3R7aW5lZGdlczplLGh1bGw6bixfaHVsbEluZGV4OnMsaGFsZmVkZ2VzOnIsdHJpYW5nbGVzOm8sY29sbGluZWFyOmF9PXRoaXM7aWYoYSl7Y29uc3QgdT1hLmluZGV4T2YodCk7dT4wJiYoeWllbGQgYVt1LTFdKSx1PGEubGVuZ3RoLTEmJih5aWVsZCBhW3UrMV0pO3JldHVybn1jb25zdCBjPWVbdF07aWYoYz09PS0xKXJldHVybjtsZXQgbD1jLGg9LTE7ZG97aWYoeWllbGQgaD1vW2xdLGw9bCUzPT09Mj9sLTI6bCsxLG9bbF0hPT10KXJldHVybjtpZihsPXJbbF0sbD09PS0xKXtjb25zdCB1PW5bKHNbdF0rMSklbi5sZW5ndGhdO3UhPT1oJiYoeWllbGQgdSk7cmV0dXJufX13aGlsZShsIT09Yyl9ZmluZCh0LGUsbj0wKXtpZih0PSt0LHQhPT10fHwoZT0rZSxlIT09ZSkpcmV0dXJuLTE7Y29uc3Qgcz1uO2xldCByO2Zvcig7KHI9dGhpcy5fc3RlcChuLHQsZSkpPj0wJiZyIT09biYmciE9PXM7KW49cjtyZXR1cm4gcn1fc3RlcCh0LGUsbil7Y29uc3R7aW5lZGdlczpzLGh1bGw6cixfaHVsbEluZGV4Om8saGFsZmVkZ2VzOmEsdHJpYW5nbGVzOmMscG9pbnRzOmx9PXRoaXM7aWYoc1t0XT09PS0xfHwhbC5sZW5ndGgpcmV0dXJuKHQrMSklKGwubGVuZ3RoPj4xKTtsZXQgaD10LHU9dWkoZS1sW3QqMl0sMikrdWkobi1sW3QqMisxXSwyKTtjb25zdCBmPXNbdF07bGV0IGQ9Zjtkb3tsZXQgcD1jW2RdO2NvbnN0IHk9dWkoZS1sW3AqMl0sMikrdWkobi1sW3AqMisxXSwyKTtpZih5PHUmJih1PXksaD1wKSxkPWQlMz09PTI/ZC0yOmQrMSxjW2RdIT09dClicmVhaztpZihkPWFbZF0sZD09PS0xKXtpZihkPXJbKG9bdF0rMSklci5sZW5ndGhdLGQhPT1wJiZ1aShlLWxbZCoyXSwyKSt1aShuLWxbZCoyKzFdLDIpPHUpcmV0dXJuIGQ7YnJlYWt9fXdoaWxlKGQhPT1mKTtyZXR1cm4gaH1yZW5kZXIodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7cG9pbnRzOm4saGFsZmVkZ2VzOnMsdHJpYW5nbGVzOnJ9PXRoaXM7Zm9yKGxldCBvPTAsYT1zLmxlbmd0aDtvPGE7KytvKXtjb25zdCBjPXNbb107aWYoYzxvKWNvbnRpbnVlO2NvbnN0IGw9cltvXSoyLGg9cltjXSoyO3QubW92ZVRvKG5bbF0sbltsKzFdKSx0LmxpbmVUbyhuW2hdLG5baCsxXSl9cmV0dXJuIHRoaXMucmVuZGVySHVsbCh0KSxlJiZlLnZhbHVlKCl9cmVuZGVyUG9pbnRzKHQsZSl7ZT09PXZvaWQgMCYmKCF0fHx0eXBlb2YgdC5tb3ZlVG8hPSJmdW5jdGlvbiIpJiYoZT10LHQ9bnVsbCksZT1lPT1udWxsPzI6K2U7Y29uc3Qgbj10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7cG9pbnRzOnN9PXRoaXM7Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cis9Mil7Y29uc3QgYT1zW3JdLGM9c1tyKzFdO3QubW92ZVRvKGErZSxjKSx0LmFyYyhhLGMsZSwwLEt5KX1yZXR1cm4gbiYmbi52YWx1ZSgpfXJlbmRlckh1bGwodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7aHVsbDpuLHBvaW50czpzfT10aGlzLHI9blswXSoyLG89bi5sZW5ndGg7dC5tb3ZlVG8oc1tyXSxzW3IrMV0pO2ZvcihsZXQgYT0xO2E8bzsrK2Epe2NvbnN0IGM9MipuW2FdO3QubGluZVRvKHNbY10sc1tjKzFdKX1yZXR1cm4gdC5jbG9zZVBhdGgoKSxlJiZlLnZhbHVlKCl9aHVsbFBvbHlnb24oKXtjb25zdCB0PW5ldyBlYztyZXR1cm4gdGhpcy5yZW5kZXJIdWxsKHQpLHQudmFsdWUoKX1yZW5kZXJUcmlhbmdsZSh0LGUpe2NvbnN0IG49ZT09bnVsbD9lPW5ldyB6bjp2b2lkIDAse3BvaW50czpzLHRyaWFuZ2xlczpyfT10aGlzLG89clt0Kj0zXSoyLGE9clt0KzFdKjIsYz1yW3QrMl0qMjtyZXR1cm4gZS5tb3ZlVG8oc1tvXSxzW28rMV0pLGUubGluZVRvKHNbYV0sc1thKzFdKSxlLmxpbmVUbyhzW2NdLHNbYysxXSksZS5jbG9zZVBhdGgoKSxuJiZuLnZhbHVlKCl9KnRyaWFuZ2xlUG9seWdvbnMoKXtjb25zdHt0cmlhbmdsZXM6dH09dGhpcztmb3IobGV0IGU9MCxuPXQubGVuZ3RoLzM7ZTxuOysrZSl5aWVsZCB0aGlzLnRyaWFuZ2xlUG9seWdvbihlKX10cmlhbmdsZVBvbHlnb24odCl7Y29uc3QgZT1uZXcgZWM7cmV0dXJuIHRoaXMucmVuZGVyVHJpYW5nbGUodCxlKSxlLnZhbHVlKCl9fWZ1bmN0aW9uIHNtKGksdCxlLG4pe2NvbnN0IHM9aS5sZW5ndGgscj1uZXcgRmxvYXQ2NEFycmF5KHMqMik7Zm9yKGxldCBvPTA7bzxzOysrbyl7Y29uc3QgYT1pW29dO3JbbyoyXT10LmNhbGwobixhLG8saSkscltvKjIrMV09ZS5jYWxsKG4sYSxvLGkpfXJldHVybiByfWZ1bmN0aW9uKnJtKGksdCxlLG4pe2xldCBzPTA7Zm9yKGNvbnN0IHIgb2YgaSl5aWVsZCB0LmNhbGwobixyLHMsaSkseWllbGQgZS5jYWxsKG4scixzLGkpLCsrc31jb25zdCBpYz1NYXRoLlBJLHN1PWljLzIscnU9MTgwL2ljLG91PWljLzE4MCxvbT1NYXRoLmF0YW4yLGF1PU1hdGguY29zLGFtPU1hdGgubWF4LGNtPU1hdGgubWluLGN1PU1hdGguc2luLGxtPU1hdGguc2lnbnx8ZnVuY3Rpb24oaSl7cmV0dXJuIGk+MD8xOmk8MD8tMTowfSxsdT1NYXRoLnNxcnQ7ZnVuY3Rpb24gaG0oaSl7cmV0dXJuIGk+MT9zdTppPC0xPy1zdTpNYXRoLmFzaW4oaSl9ZnVuY3Rpb24gaHUoaSx0KXtyZXR1cm4gaVswXSp0WzBdK2lbMV0qdFsxXStpWzJdKnRbMl19ZnVuY3Rpb24gV3QoaSx0KXtyZXR1cm5baVsxXSp0WzJdLWlbMl0qdFsxXSxpWzJdKnRbMF0taVswXSp0WzJdLGlbMF0qdFsxXS1pWzFdKnRbMF1dfWZ1bmN0aW9uIERyKGksdCl7cmV0dXJuW2lbMF0rdFswXSxpWzFdK3RbMV0saVsyXSt0WzJdXX1mdW5jdGlvbiAkcihpKXt2YXIgdD1sdShpWzBdKmlbMF0raVsxXSppWzFdK2lbMl0qaVsyXSk7cmV0dXJuW2lbMF0vdCxpWzFdL3QsaVsyXS90XX1mdW5jdGlvbiBzYyhpKXtyZXR1cm5bb20oaVsxXSxpWzBdKSpydSxobShhbSgtMSxjbSgxLGlbMl0pKSkqcnVdfWZ1bmN0aW9uIE1lKGkpe2NvbnN0IHQ9aVswXSpvdSxlPWlbMV0qb3Usbj1hdShlKTtyZXR1cm5bbiphdSh0KSxuKmN1KHQpLGN1KGUpXX1mdW5jdGlvbiByYyhpKXtyZXR1cm4gaT1pLm1hcCh0PT5NZSh0KSksaHUoaVswXSxXdChpWzJdLGlbMV0pKX1mdW5jdGlvbiB1bShpKXtjb25zdCB0PWRtKGkpLGU9eW0odCksbj1wbShlLGkpLHM9Z20oZSxpLmxlbmd0aCkscj1mbShzLGkpLG89bW0oZSxpKSx7cG9seWdvbnM6YSxjZW50ZXJzOmN9PXhtKG8sZSxpKSxsPXdtKGEpLGg9TW0oZSxpKSx1PWJtKG4sZSk7cmV0dXJue2RlbGF1bmF5OnQsZWRnZXM6bix0cmlhbmdsZXM6ZSxjZW50ZXJzOmMsbmVpZ2hib3JzOnMscG9seWdvbnM6YSxtZXNoOmwsaHVsbDpoLHVycXVoYXJ0OnUsZmluZDpyfX1mdW5jdGlvbiBmbShpLHQpe2Z1bmN0aW9uIGUobixzKXtsZXQgcj1uWzBdLXNbMF0sbz1uWzFdLXNbMV0sYT1uWzJdLXNbMl07cmV0dXJuIHIqcitvKm8rYSphfXJldHVybiBmdW5jdGlvbihzLHIsbyl7bz09PXZvaWQgMCYmKG89MCk7bGV0IGEsYyxsPW87Y29uc3QgaD1NZShbcyxyXSk7ZG8gYT1vLG89bnVsbCxjPWUoaCxNZSh0W2FdKSksaVthXS5mb3JFYWNoKHU9PntsZXQgZj1lKGgsTWUodFt1XSkpO2lmKGY8Yyl7Yz1mLG89dSxsPXU7cmV0dXJufX0pO3doaWxlKG8hPT1udWxsKTtyZXR1cm4gbH19ZnVuY3Rpb24gZG0oaSl7aWYoaS5sZW5ndGg8MilyZXR1cm57fTtsZXQgdD0wO2Zvcig7aXNOYU4oaVt0XVswXStpW3RdWzFdKSYmdCsrPGkubGVuZ3RoOyk7Y29uc3QgZT1TaChpW3RdKSxuPWl5KCkudHJhbnNsYXRlKFswLDBdKS5zY2FsZSgxKS5yb3RhdGUoZS5pbnZlcnQoWzE4MCwwXSkpO2k9aS5tYXAobik7Y29uc3Qgcz1bXTtsZXQgcj0xO2ZvcihsZXQgdT0wLGY9aS5sZW5ndGg7dTxmO3UrKyl7bGV0IGQ9eWkoaVt1XVswXSwyKSt5aShpW3VdWzFdLDIpOyFpc0Zpbml0ZShkKXx8ZD4xZTMyP3MucHVzaCh1KTpkPnImJihyPWQpfWNvbnN0IG89MWU2Kmx1KHIpO3MuZm9yRWFjaCh1PT5pW3VdPVtvLDBdKSxpLnB1c2goWzAsb10pLGkucHVzaChbLW8sMF0pLGkucHVzaChbMCwtb10pO2NvbnN0IGE9bmMuZnJvbShpKTthLnByb2plY3Rpb249bjtjb25zdHt0cmlhbmdsZXM6YyxoYWxmZWRnZXM6bCxpbmVkZ2VzOmh9PWE7Zm9yKGxldCB1PTAsZj1sLmxlbmd0aDt1PGY7dSsrKWlmKGxbdV08MCl7Y29uc3QgZD11JTM9PTI/dS0yOnUrMSxwPXUlMz09MD91KzI6dS0xLHk9bFtkXSxtPWxbcF07bFt5XT1tLGxbbV09eSxsW2RdPWxbcF09LTEsY1t1XT1jW2RdPWNbcF09dCxoW2NbeV1dPXklMz09MD95KzI6eS0xLGhbY1ttXV09bSUzPT0wP20rMjptLTEsdSs9Mi11JTN9ZWxzZSBjW3VdPmkubGVuZ3RoLTMtMSYmKGNbdV09dCk7cmV0dXJuIGF9ZnVuY3Rpb24gcG0oaSx0KXtjb25zdCBlPW5ldyBTZXQ7cmV0dXJuIHQubGVuZ3RoPT09Mj9bWzAsMV1dOihpLmZvckVhY2gobj0+e2lmKG5bMF0hPT1uWzFdJiYhKHJjKG4ubWFwKHM9PnRbc10pKTwwKSlmb3IobGV0IHM9MCxyO3M8MztzKyspcj0ocysxKSUzLGUuYWRkKHNyKFtuW3NdLG5bcl1dKS5qb2luKCItIikpfSksQXJyYXkuZnJvbShlLG49Pm4uc3BsaXQoIi0iKS5tYXAoTnVtYmVyKSkpfWZ1bmN0aW9uIHltKGkpe2NvbnN0e3RyaWFuZ2xlczp0fT1pO2lmKCF0KXJldHVybltdO2NvbnN0IGU9W107Zm9yKGxldCBuPTAscz10Lmxlbmd0aC8zO248cztuKyspe2NvbnN0IHI9dFszKm5dLG89dFszKm4rMV0sYT10WzMqbisyXTtyIT09byYmbyE9PWEmJmUucHVzaChbcixhLG9dKX1yZXR1cm4gZX1mdW5jdGlvbiBtbShpLHQpe3JldHVybiBpLm1hcChlPT57Y29uc3Qgbj1lLm1hcChyPT50W3JdKS5tYXAoTWUpLHM9RHIoRHIoV3QoblsxXSxuWzBdKSxXdChuWzJdLG5bMV0pKSxXdChuWzBdLG5bMl0pKTtyZXR1cm4gc2MoJHIocykpfSl9ZnVuY3Rpb24gZ20oaSx0KXtjb25zdCBlPVtdO3JldHVybiBpLmZvckVhY2gobj0+e2ZvcihsZXQgcz0wO3M8MztzKyspe2NvbnN0IHI9bltzXSxvPW5bKHMrMSklM107ZVtyXT1lW3JdfHxbXSxlW3JdLnB1c2gobyl9fSksaS5sZW5ndGg9PT0wJiYodD09PTI/KGVbMF09WzFdLGVbMV09WzBdKTp0PT09MSYmKGVbMF09W10pKSxlfWZ1bmN0aW9uIHhtKGksdCxlKXtjb25zdCBuPVtdLHM9aS5zbGljZSgpO2lmKHQubGVuZ3RoPT09MCl7aWYoZS5sZW5ndGg8MilyZXR1cm57cG9seWdvbnM6bixjZW50ZXJzOnN9O2lmKGUubGVuZ3RoPT09Mil7Y29uc3QgYT1NZShlWzBdKSxjPU1lKGVbMV0pLGw9JHIoRHIoYSxjKSksaD0kcihXdChhLGMpKSx1PVd0KGwsaCksZj1bbCxXdChsLHUpLFd0KFd0KGwsdSksdSksV3QoV3QoV3QobCx1KSx1KSx1KV0ubWFwKHNjKS5tYXAobyk7cmV0dXJuIG4ucHVzaChmKSxuLnB1c2goZi5zbGljZSgpLnJldmVyc2UoKSkse3BvbHlnb25zOm4sY2VudGVyczpzfX19dC5mb3JFYWNoKChhLGMpPT57Zm9yKGxldCBsPTA7bDwzO2wrKyl7Y29uc3QgaD1hW2xdLHU9YVsobCsxKSUzXSxmPWFbKGwrMiklM107bltoXT1uW2hdfHxbXSxuW2hdLnB1c2goW3UsZixjLFtoLHUsZl1dKX19KTtjb25zdCByPW4ubWFwKGE9Pntjb25zdCBjPVthWzBdWzJdXTtsZXQgbD1hWzBdWzFdO2ZvcihsZXQgaD0xO2g8YS5sZW5ndGg7aCsrKWZvcihsZXQgdT0wO3U8YS5sZW5ndGg7dSsrKWlmKGFbdV1bMF09PWwpe2w9YVt1XVsxXSxjLnB1c2goYVt1XVsyXSk7YnJlYWt9aWYoYy5sZW5ndGg+MilyZXR1cm4gYztpZihjLmxlbmd0aD09Mil7Y29uc3QgaD11dShlW2FbMF1bM11bMF1dLGVbYVswXVszXVsxXV0sc1tjWzBdXSksdT11dShlW2FbMF1bM11bMl1dLGVbYVswXVszXVswXV0sc1tjWzBdXSksZj1vKGgpLGQ9byh1KTtyZXR1cm5bY1swXSxkLGNbMV0sZl19fSk7ZnVuY3Rpb24gbyhhKXtsZXQgYz0tMTtyZXR1cm4gcy5zbGljZSh0Lmxlbmd0aCwxLzApLmZvckVhY2goKGwsaCk9PntsWzBdPT09YVswXSYmbFsxXT09PWFbMV0mJihjPWgrdC5sZW5ndGgpfSksYzwwJiYoYz1zLmxlbmd0aCxzLnB1c2goYSkpLGN9cmV0dXJue3BvbHlnb25zOnIsY2VudGVyczpzfX1mdW5jdGlvbiB1dShpLHQsZSl7aT1NZShpKSx0PU1lKHQpLGU9TWUoZSk7Y29uc3Qgbj1sbShodShXdCh0LGkpLGUpKTtyZXR1cm4gc2MoJHIoRHIoaSx0KSkubWFwKHM9Pm4qcykpfWZ1bmN0aW9uIHdtKGkpe2NvbnN0IHQ9W107cmV0dXJuIGkuZm9yRWFjaChlPT57aWYoIWUpcmV0dXJuO2xldCBuPWVbZS5sZW5ndGgtMV07Zm9yKGxldCBzIG9mIGUpcz5uJiZ0LnB1c2goW24sc10pLG49c30pLHR9ZnVuY3Rpb24gYm0oaSx0KXtyZXR1cm4gZnVuY3Rpb24oZSl7Y29uc3Qgbj1uZXcgTWFwLHM9bmV3IE1hcDtyZXR1cm4gaS5mb3JFYWNoKChyLG8pPT57Y29uc3QgYT1yLmpvaW4oIi0iKTtuLnNldChhLGVbb10pLHMuc2V0KGEsITApfSksdC5mb3JFYWNoKHI9PntsZXQgbz0wLGE9LTE7Zm9yKGxldCBjPTA7YzwzO2MrKyl7bGV0IGw9c3IoW3JbY10sclsoYysxKSUzXV0pLmpvaW4oIi0iKTtuLmdldChsKT5vJiYobz1uLmdldChsKSxhPWwpfXMuc2V0KGEsITEpfSksaS5tYXAocj0+cy5nZXQoci5qb2luKCItIikpKX19ZnVuY3Rpb24gTW0oaSx0KXtjb25zdCBlPW5ldyBTZXQsbj1bXTtpLm1hcChhPT57aWYoIShyYyhhLm1hcChjPT50W2M+dC5sZW5ndGg/MDpjXSkpPjFlLTEyKSlmb3IobGV0IGM9MDtjPDM7YysrKXtsZXQgbD1bYVtjXSxhWyhjKzEpJTNdXSxoPWAke2xbMF19LSR7bFsxXX1gO2UuaGFzKGgpP2UuZGVsZXRlKGgpOmUuYWRkKGAke2xbMV19LSR7bFswXX1gKX19KTtjb25zdCBzPW5ldyBNYXA7bGV0IHI7aWYoZS5mb3JFYWNoKGE9PnthPWEuc3BsaXQoIi0iKS5tYXAoTnVtYmVyKSxzLnNldChhWzBdLGFbMV0pLHI9YVswXX0pLHI9PT12b2lkIDApcmV0dXJuIG47bGV0IG89cjtkb3tuLnB1c2gobyk7bGV0IGE9cy5nZXQobyk7cy5zZXQobywtMSksbz1hfXdoaWxlKG8+LTEmJm8hPT1yKTtyZXR1cm4gbn1mdW5jdGlvbiBBbShpKXtjb25zdCB0PWZ1bmN0aW9uKGUpe2lmKHQuZGVsYXVuYXk9bnVsbCx0Ll9kYXRhPWUsdHlwZW9mIHQuX2RhdGE9PSJvYmplY3QiJiZ0Ll9kYXRhLnR5cGU9PT0iRmVhdHVyZUNvbGxlY3Rpb24iJiYodC5fZGF0YT10Ll9kYXRhLmZlYXR1cmVzKSx0eXBlb2YgdC5fZGF0YT09Im9iamVjdCIpe2NvbnN0IG49dC5fZGF0YS5tYXAocz0+W3QuX3Z4KHMpLHQuX3Z5KHMpLHNdKS5maWx0ZXIocz0+aXNGaW5pdGUoc1swXStzWzFdKSk7dC5wb2ludHM9bi5tYXAocz0+W3NbMF0sc1sxXV0pLHQudmFsaWQ9bi5tYXAocz0+c1syXSksdC5kZWxhdW5heT11bSh0LnBvaW50cyl9cmV0dXJuIHR9O3JldHVybiB0Ll92eD1mdW5jdGlvbihlKXtpZih0eXBlb2YgZT09Im9iamVjdCImJiJ0eXBlImluIGUpcmV0dXJuIHhoKGUpWzBdO2lmKDAgaW4gZSlyZXR1cm4gZVswXX0sdC5fdnk9ZnVuY3Rpb24oZSl7aWYodHlwZW9mIGU9PSJvYmplY3QiJiYidHlwZSJpbiBlKXJldHVybiB4aChlKVsxXTtpZigxIGluIGUpcmV0dXJuIGVbMV19LHQueD1mdW5jdGlvbihlKXtyZXR1cm4gZT8odC5fdng9ZSx0KTp0Ll92eH0sdC55PWZ1bmN0aW9uKGUpe3JldHVybiBlPyh0Ll92eT1lLHQpOnQuX3Z5fSx0LnBvbHlnb25zPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3Qgbj17dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOltdfTtyZXR1cm4gdC52YWxpZC5sZW5ndGg9PT0wfHwodC5kZWxhdW5heS5wb2x5Z29ucy5mb3JFYWNoKChzLHIpPT5uLmZlYXR1cmVzLnB1c2goe3R5cGU6IkZlYXR1cmUiLGdlb21ldHJ5OnM/e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOltbLi4ucyxzWzBdXS5tYXAobz0+dC5kZWxhdW5heS5jZW50ZXJzW29dKV19Om51bGwscHJvcGVydGllczp7c2l0ZTp0LnZhbGlkW3JdLHNpdGVjb29yZGluYXRlczp0LnBvaW50c1tyXSxuZWlnaGJvdXJzOnQuZGVsYXVuYXkubmVpZ2hib3JzW3JdfX0pKSx0LnZhbGlkLmxlbmd0aD09PTEmJm4uZmVhdHVyZXMucHVzaCh7dHlwZToiRmVhdHVyZSIsZ2VvbWV0cnk6e3R5cGU6IlNwaGVyZSJ9LHByb3BlcnRpZXM6e3NpdGU6dC52YWxpZFswXSxzaXRlY29vcmRpbmF0ZXM6dC5wb2ludHNbMF0sbmVpZ2hib3VyczpbXX19KSksbn0sdC50cmlhbmdsZXM9ZnVuY3Rpb24oZSl7cmV0dXJuIGUhPT12b2lkIDAmJnQoZSksdC5kZWxhdW5heT97dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOnQuZGVsYXVuYXkudHJpYW5nbGVzLm1hcCgobixzKT0+KG49bi5tYXAocj0+dC5wb2ludHNbcl0pLG4uY2VudGVyPXQuZGVsYXVuYXkuY2VudGVyc1tzXSxuKSkuZmlsdGVyKG49PnJjKG4pPjApLm1hcChuPT4oe3R5cGU6IkZlYXR1cmUiLHByb3BlcnRpZXM6e2NpcmN1bWNlbnRlcjpuLmNlbnRlcn0sZ2VvbWV0cnk6e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOltbLi4ubixuWzBdXV19fSkpfTohMX0sdC5saW5rcz1mdW5jdGlvbihlKXtpZihlIT09dm9pZCAwJiZ0KGUpLCF0LmRlbGF1bmF5KXJldHVybiExO2NvbnN0IG49dC5kZWxhdW5heS5lZGdlcy5tYXAocj0+cmkodC5wb2ludHNbclswXV0sdC5wb2ludHNbclsxXV0pKSxzPXQuZGVsYXVuYXkudXJxdWhhcnQobik7cmV0dXJue3R5cGU6IkZlYXR1cmVDb2xsZWN0aW9uIixmZWF0dXJlczp0LmRlbGF1bmF5LmVkZ2VzLm1hcCgocixvKT0+KHt0eXBlOiJGZWF0dXJlIixwcm9wZXJ0aWVzOntzb3VyY2U6dC52YWxpZFtyWzBdXSx0YXJnZXQ6dC52YWxpZFtyWzFdXSxsZW5ndGg6bltvXSx1cnF1aGFydDohIXNbb119LGdlb21ldHJ5Ont0eXBlOiJMaW5lU3RyaW5nIixjb29yZGluYXRlczpbdC5wb2ludHNbclswXV0sdC5wb2ludHNbclsxXV1dfX0pKX19LHQubWVzaD1mdW5jdGlvbihlKXtyZXR1cm4gZSE9PXZvaWQgMCYmdChlKSx0LmRlbGF1bmF5P3t0eXBlOiJNdWx0aUxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOnQuZGVsYXVuYXkuZWRnZXMubWFwKG49Plt0LnBvaW50c1tuWzBdXSx0LnBvaW50c1tuWzFdXV0pfTohMX0sdC5jZWxsTWVzaD1mdW5jdGlvbihlKXtpZihlIT09dm9pZCAwJiZ0KGUpLCF0LmRlbGF1bmF5KXJldHVybiExO2NvbnN0e2NlbnRlcnM6bixwb2x5Z29uczpzfT10LmRlbGF1bmF5LHI9W107Zm9yKGNvbnN0IG8gb2YgcylpZihvKWZvcihsZXQgYT1vLmxlbmd0aCxjPW9bYS0xXSxsPW9bMF0saD0wO2g8YTtjPWwsbD1vWysraF0pbD5jJiZyLnB1c2goW25bY10sbltsXV0pO3JldHVybnt0eXBlOiJNdWx0aUxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOnJ9fSx0Ll9mb3VuZD12b2lkIDAsdC5maW5kPWZ1bmN0aW9uKGUsbixzKXtpZih0Ll9mb3VuZD10LmRlbGF1bmF5LmZpbmQoZSxuLHQuX2ZvdW5kKSwhc3x8cmkoW2Usbl0sdC5wb2ludHNbdC5fZm91bmRdKTxzKXJldHVybiB0Ll9mb3VuZH0sdC5odWxsPWZ1bmN0aW9uKGUpe2UhPT12b2lkIDAmJnQoZSk7Y29uc3Qgbj10LmRlbGF1bmF5Lmh1bGwscz10LnBvaW50cztyZXR1cm4gbi5sZW5ndGg9PT0wP251bGw6e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOltbLi4ubi5tYXAocj0+c1tyXSksc1tuWzBdXV1dfX0saT90KGkpOnR9ZnVuY3Rpb24gU20oaSx0KXtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAwOmJyZWFrO2Nhc2UgMTp0aGlzLnJhbmdlKGkpO2JyZWFrO2RlZmF1bHQ6dGhpcy5yYW5nZSh0KS5kb21haW4oaSk7YnJlYWt9cmV0dXJuIHRoaXN9ZnVuY3Rpb24gb2MoaSx0LGUpe2kucHJvdG90eXBlPXQucHJvdG90eXBlPWUsZS5jb25zdHJ1Y3Rvcj1pfWZ1bmN0aW9uIGZ1KGksdCl7dmFyIGU9T2JqZWN0LmNyZWF0ZShpLnByb3RvdHlwZSk7Zm9yKHZhciBuIGluIHQpZVtuXT10W25dO3JldHVybiBlfWZ1bmN0aW9uIG5zKCl7fXZhciBpcz0uNyxWcj0xL2lzLGZpPSJcXHMqKFsrLV0/XFxkKylcXHMqIixzcz0iXFxzKihbKy1dPyg/OlxcZCpcXC4pP1xcZCsoPzpbZUVdWystXT9cXGQrKT8pXFxzKiIsQWU9IlxccyooWystXT8oPzpcXGQqXFwuKT9cXGQrKD86W2VFXVsrLV0/XFxkKyk/KSVcXHMqIixfbT0vXiMoWzAtOWEtZl17Myw4fSkkLyx2bT1uZXcgUmVnRXhwKGBecmdiXFwoJHtmaX0sJHtmaX0sJHtmaX1cXCkkYCksem09bmV3IFJlZ0V4cChgXnJnYlxcKCR7QWV9LCR7QWV9LCR7QWV9XFwpJGApLFRtPW5ldyBSZWdFeHAoYF5yZ2JhXFwoJHtmaX0sJHtmaX0sJHtmaX0sJHtzc31cXCkkYCksRW09bmV3IFJlZ0V4cChgXnJnYmFcXCgke0FlfSwke0FlfSwke0FlfSwke3NzfVxcKSRgKSxQbT1uZXcgUmVnRXhwKGBeaHNsXFwoJHtzc30sJHtBZX0sJHtBZX1cXCkkYCksQ209bmV3IFJlZ0V4cChgXmhzbGFcXCgke3NzfSwke0FlfSwke0FlfSwke3NzfVxcKSRgKSxkdT17YWxpY2VibHVlOjE1NzkyMzgzLGFudGlxdWV3aGl0ZToxNjQ0NDM3NSxhcXVhOjY1NTM1LGFxdWFtYXJpbmU6ODM4ODU2NCxhenVyZToxNTc5NDE3NSxiZWlnZToxNjExOTI2MCxiaXNxdWU6MTY3NzAyNDQsYmxhY2s6MCxibGFuY2hlZGFsbW9uZDoxNjc3MjA0NSxibHVlOjI1NSxibHVldmlvbGV0OjkwNTUyMDIsYnJvd246MTA4MjQyMzQsYnVybHl3b29kOjE0NTk2MjMxLGNhZGV0Ymx1ZTo2MjY2NTI4LGNoYXJ0cmV1c2U6ODM4ODM1MixjaG9jb2xhdGU6MTM3ODk0NzAsY29yYWw6MTY3NDQyNzIsY29ybmZsb3dlcmJsdWU6NjU5MTk4MSxjb3Juc2lsazoxNjc3NTM4OCxjcmltc29uOjE0NDIzMTAwLGN5YW46NjU1MzUsZGFya2JsdWU6MTM5LGRhcmtjeWFuOjM1NzIzLGRhcmtnb2xkZW5yb2Q6MTIwOTI5MzksZGFya2dyYXk6MTExMTkwMTcsZGFya2dyZWVuOjI1NjAwLGRhcmtncmV5OjExMTE5MDE3LGRhcmtraGFraToxMjQzMzI1OSxkYXJrbWFnZW50YTo5MTA5NjQzLGRhcmtvbGl2ZWdyZWVuOjU1OTc5OTksZGFya29yYW5nZToxNjc0NzUyMCxkYXJrb3JjaGlkOjEwMDQwMDEyLGRhcmtyZWQ6OTEwOTUwNCxkYXJrc2FsbW9uOjE1MzA4NDEwLGRhcmtzZWFncmVlbjo5NDE5OTE5LGRhcmtzbGF0ZWJsdWU6NDczNDM0NyxkYXJrc2xhdGVncmF5OjMxMDA0OTUsZGFya3NsYXRlZ3JleTozMTAwNDk1LGRhcmt0dXJxdW9pc2U6NTI5NDUsZGFya3Zpb2xldDo5Njk5NTM5LGRlZXBwaW5rOjE2NzE2OTQ3LGRlZXBza3libHVlOjQ5MTUxLGRpbWdyYXk6NjkwODI2NSxkaW1ncmV5OjY5MDgyNjUsZG9kZ2VyYmx1ZToyMDAzMTk5LGZpcmVicmljazoxMTY3NDE0NixmbG9yYWx3aGl0ZToxNjc3NTkyMCxmb3Jlc3RncmVlbjoyMjYzODQyLGZ1Y2hzaWE6MTY3MTE5MzUsZ2FpbnNib3JvOjE0NDc0NDYwLGdob3N0d2hpdGU6MTYzMTY2NzEsZ29sZDoxNjc2NjcyMCxnb2xkZW5yb2Q6MTQzMjkxMjAsZ3JheTo4NDIxNTA0LGdyZWVuOjMyNzY4LGdyZWVueWVsbG93OjExNDAzMDU1LGdyZXk6ODQyMTUwNCxob25leWRldzoxNTc5NDE2MCxob3RwaW5rOjE2NzM4NzQwLGluZGlhbnJlZDoxMzQ1ODUyNCxpbmRpZ286NDkxNTMzMCxpdm9yeToxNjc3NzIwMCxraGFraToxNTc4NzY2MCxsYXZlbmRlcjoxNTEzMjQxMCxsYXZlbmRlcmJsdXNoOjE2NzczMzY1LGxhd25ncmVlbjo4MTkwOTc2LGxlbW9uY2hpZmZvbjoxNjc3NTg4NSxsaWdodGJsdWU6MTEzOTMyNTQsbGlnaHRjb3JhbDoxNTc2MTUzNixsaWdodGN5YW46MTQ3NDU1OTksbGlnaHRnb2xkZW5yb2R5ZWxsb3c6MTY0NDgyMTAsbGlnaHRncmF5OjEzODgyMzIzLGxpZ2h0Z3JlZW46OTQ5ODI1NixsaWdodGdyZXk6MTM4ODIzMjMsbGlnaHRwaW5rOjE2NzU4NDY1LGxpZ2h0c2FsbW9uOjE2NzUyNzYyLGxpZ2h0c2VhZ3JlZW46MjE0Mjg5MCxsaWdodHNreWJsdWU6ODkwMDM0NixsaWdodHNsYXRlZ3JheTo3ODMzNzUzLGxpZ2h0c2xhdGVncmV5Ojc4MzM3NTMsbGlnaHRzdGVlbGJsdWU6MTE1ODQ3MzQsbGlnaHR5ZWxsb3c6MTY3NzcxODQsbGltZTo2NTI4MCxsaW1lZ3JlZW46MzMyOTMzMCxsaW5lbjoxNjQ0NTY3MCxtYWdlbnRhOjE2NzExOTM1LG1hcm9vbjo4Mzg4NjA4LG1lZGl1bWFxdWFtYXJpbmU6NjczNzMyMixtZWRpdW1ibHVlOjIwNSxtZWRpdW1vcmNoaWQ6MTIyMTE2NjcsbWVkaXVtcHVycGxlOjk2NjI2ODMsbWVkaXVtc2VhZ3JlZW46Mzk3ODA5NyxtZWRpdW1zbGF0ZWJsdWU6ODA4Nzc5MCxtZWRpdW1zcHJpbmdncmVlbjo2NDE1NCxtZWRpdW10dXJxdW9pc2U6NDc3MjMwMCxtZWRpdW12aW9sZXRyZWQ6MTMwNDcxNzMsbWlkbmlnaHRibHVlOjE2NDQ5MTIsbWludGNyZWFtOjE2MTIxODUwLG1pc3R5cm9zZToxNjc3MDI3Myxtb2NjYXNpbjoxNjc3MDIyOSxuYXZham93aGl0ZToxNjc2ODY4NSxuYXZ5OjEyOCxvbGRsYWNlOjE2NjQzNTU4LG9saXZlOjg0MjEzNzYsb2xpdmVkcmFiOjcwNDg3Mzksb3JhbmdlOjE2NzUzOTIwLG9yYW5nZXJlZDoxNjcyOTM0NCxvcmNoaWQ6MTQzMTU3MzQscGFsZWdvbGRlbnJvZDoxNTY1NzEzMCxwYWxlZ3JlZW46MTAwMjU4ODAscGFsZXR1cnF1b2lzZToxMTUyOTk2NixwYWxldmlvbGV0cmVkOjE0MzgxMjAzLHBhcGF5YXdoaXA6MTY3NzMwNzcscGVhY2hwdWZmOjE2NzY3NjczLHBlcnU6MTM0Njg5OTEscGluazoxNjc2MTAzNSxwbHVtOjE0NTI0NjM3LHBvd2RlcmJsdWU6MTE1OTE5MTAscHVycGxlOjgzODg3MzYscmViZWNjYXB1cnBsZTo2Njk3ODgxLHJlZDoxNjcxMTY4MCxyb3N5YnJvd246MTIzNTc1MTkscm95YWxibHVlOjQyODY5NDUsc2FkZGxlYnJvd246OTEyNzE4NyxzYWxtb246MTY0MTY4ODIsc2FuZHlicm93bjoxNjAzMjg2NCxzZWFncmVlbjozMDUwMzI3LHNlYXNoZWxsOjE2Nzc0NjM4LHNpZW5uYToxMDUwNjc5NyxzaWx2ZXI6MTI2MzIyNTYsc2t5Ymx1ZTo4OTAwMzMxLHNsYXRlYmx1ZTo2OTcwMDYxLHNsYXRlZ3JheTo3MzcyOTQ0LHNsYXRlZ3JleTo3MzcyOTQ0LHNub3c6MTY3NzU5MzAsc3ByaW5nZ3JlZW46NjU0MDcsc3RlZWxibHVlOjQ2MjA5ODAsdGFuOjEzODA4NzgwLHRlYWw6MzI4OTYsdGhpc3RsZToxNDIwNDg4OCx0b21hdG86MTY3MzcwOTUsdHVycXVvaXNlOjQyNTE4NTYsdmlvbGV0OjE1NjMxMDg2LHdoZWF0OjE2MTEzMzMxLHdoaXRlOjE2Nzc3MjE1LHdoaXRlc21va2U6MTYxMTkyODUseWVsbG93OjE2Nzc2OTYwLHllbGxvd2dyZWVuOjEwMTQ1MDc0fTtvYyhucyxycyx7Y29weShpKXtyZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgdGhpcy5jb25zdHJ1Y3Rvcix0aGlzLGkpfSxkaXNwbGF5YWJsZSgpe3JldHVybiB0aGlzLnJnYigpLmRpc3BsYXlhYmxlKCl9LGhleDpwdSxmb3JtYXRIZXg6cHUsZm9ybWF0SGV4ODpCbSxmb3JtYXRIc2w6Rm0sZm9ybWF0UmdiOnl1LHRvU3RyaW5nOnl1fSk7ZnVuY3Rpb24gcHUoKXtyZXR1cm4gdGhpcy5yZ2IoKS5mb3JtYXRIZXgoKX1mdW5jdGlvbiBCbSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleDgoKX1mdW5jdGlvbiBGbSgpe3JldHVybiBidSh0aGlzKS5mb3JtYXRIc2woKX1mdW5jdGlvbiB5dSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdFJnYigpfWZ1bmN0aW9uIHJzKGkpe3ZhciB0LGU7cmV0dXJuIGk9KGkrIiIpLnRyaW0oKS50b0xvd2VyQ2FzZSgpLCh0PV9tLmV4ZWMoaSkpPyhlPXRbMV0ubGVuZ3RoLHQ9cGFyc2VJbnQodFsxXSwxNiksZT09PTY/bXUodCk6ZT09PTM/bmV3IE90KHQ+PjgmMTV8dD4+NCYyNDAsdD4+NCYxNXx0JjI0MCwodCYxNSk8PDR8dCYxNSwxKTplPT09OD9Vcih0Pj4yNCYyNTUsdD4+MTYmMjU1LHQ+PjgmMjU1LCh0JjI1NSkvMjU1KTplPT09ND9Vcih0Pj4xMiYxNXx0Pj44JjI0MCx0Pj44JjE1fHQ+PjQmMjQwLHQ+PjQmMTV8dCYyNDAsKCh0JjE1KTw8NHx0JjE1KS8yNTUpOm51bGwpOih0PXZtLmV4ZWMoaSkpP25ldyBPdCh0WzFdLHRbMl0sdFszXSwxKToodD16bS5leGVjKGkpKT9uZXcgT3QodFsxXSoyNTUvMTAwLHRbMl0qMjU1LzEwMCx0WzNdKjI1NS8xMDAsMSk6KHQ9VG0uZXhlYyhpKSk/VXIodFsxXSx0WzJdLHRbM10sdFs0XSk6KHQ9RW0uZXhlYyhpKSk/VXIodFsxXSoyNTUvMTAwLHRbMl0qMjU1LzEwMCx0WzNdKjI1NS8xMDAsdFs0XSk6KHQ9UG0uZXhlYyhpKSk/d3UodFsxXSx0WzJdLzEwMCx0WzNdLzEwMCwxKToodD1DbS5leGVjKGkpKT93dSh0WzFdLHRbMl0vMTAwLHRbM10vMTAwLHRbNF0pOmR1Lmhhc093blByb3BlcnR5KGkpP211KGR1W2ldKTppPT09InRyYW5zcGFyZW50Ij9uZXcgT3QoTmFOLE5hTixOYU4sMCk6bnVsbH1mdW5jdGlvbiBtdShpKXtyZXR1cm4gbmV3IE90KGk+PjE2JjI1NSxpPj44JjI1NSxpJjI1NSwxKX1mdW5jdGlvbiBVcihpLHQsZSxuKXtyZXR1cm4gbjw9MCYmKGk9dD1lPU5hTiksbmV3IE90KGksdCxlLG4pfWZ1bmN0aW9uIEltKGkpe3JldHVybiBpIGluc3RhbmNlb2YgbnN8fChpPXJzKGkpKSxpPyhpPWkucmdiKCksbmV3IE90KGkucixpLmcsaS5iLGkub3BhY2l0eSkpOm5ldyBPdH1mdW5jdGlvbiBhYyhpLHQsZSxuKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD09PTE/SW0oaSk6bmV3IE90KGksdCxlLG49PW51bGw/MTpuKX1mdW5jdGlvbiBPdChpLHQsZSxuKXt0aGlzLnI9K2ksdGhpcy5nPSt0LHRoaXMuYj0rZSx0aGlzLm9wYWNpdHk9K259b2MoT3QsYWMsZnUobnMse2JyaWdodGVyKGkpe3JldHVybiBpPWk9PW51bGw/VnI6TWF0aC5wb3coVnIsaSksbmV3IE90KHRoaXMucippLHRoaXMuZyppLHRoaXMuYippLHRoaXMub3BhY2l0eSl9LGRhcmtlcihpKXtyZXR1cm4gaT1pPT1udWxsP2lzOk1hdGgucG93KGlzLGkpLG5ldyBPdCh0aGlzLnIqaSx0aGlzLmcqaSx0aGlzLmIqaSx0aGlzLm9wYWNpdHkpfSxyZ2IoKXtyZXR1cm4gdGhpc30sY2xhbXAoKXtyZXR1cm4gbmV3IE90KFRuKHRoaXMuciksVG4odGhpcy5nKSxUbih0aGlzLmIpLHFyKHRoaXMub3BhY2l0eSkpfSxkaXNwbGF5YWJsZSgpe3JldHVybi0uNTw9dGhpcy5yJiZ0aGlzLnI8MjU1LjUmJi0uNTw9dGhpcy5nJiZ0aGlzLmc8MjU1LjUmJi0uNTw9dGhpcy5iJiZ0aGlzLmI8MjU1LjUmJjA8PXRoaXMub3BhY2l0eSYmdGhpcy5vcGFjaXR5PD0xfSxoZXg6Z3UsZm9ybWF0SGV4Omd1LGZvcm1hdEhleDg6a20sZm9ybWF0UmdiOnh1LHRvU3RyaW5nOnh1fSkpO2Z1bmN0aW9uIGd1KCl7cmV0dXJuYCMke0VuKHRoaXMucil9JHtFbih0aGlzLmcpfSR7RW4odGhpcy5iKX1gfWZ1bmN0aW9uIGttKCl7cmV0dXJuYCMke0VuKHRoaXMucil9JHtFbih0aGlzLmcpfSR7RW4odGhpcy5iKX0ke0VuKChpc05hTih0aGlzLm9wYWNpdHkpPzE6dGhpcy5vcGFjaXR5KSoyNTUpfWB9ZnVuY3Rpb24geHUoKXtjb25zdCBpPXFyKHRoaXMub3BhY2l0eSk7cmV0dXJuYCR7aT09PTE/InJnYigiOiJyZ2JhKCJ9JHtUbih0aGlzLnIpfSwgJHtUbih0aGlzLmcpfSwgJHtUbih0aGlzLmIpfSR7aT09PTE/IikiOmAsICR7aX0pYH1gfWZ1bmN0aW9uIHFyKGkpe3JldHVybiBpc05hTihpKT8xOk1hdGgubWF4KDAsTWF0aC5taW4oMSxpKSl9ZnVuY3Rpb24gVG4oaSl7cmV0dXJuIE1hdGgubWF4KDAsTWF0aC5taW4oMjU1LE1hdGgucm91bmQoaSl8fDApKX1mdW5jdGlvbiBFbihpKXtyZXR1cm4gaT1UbihpKSwoaTwxNj8iMCI6IiIpK2kudG9TdHJpbmcoMTYpfWZ1bmN0aW9uIHd1KGksdCxlLG4pe3JldHVybiBuPD0wP2k9dD1lPU5hTjplPD0wfHxlPj0xP2k9dD1OYU46dDw9MCYmKGk9TmFOKSxuZXcgeWUoaSx0LGUsbil9ZnVuY3Rpb24gYnUoaSl7aWYoaSBpbnN0YW5jZW9mIHllKXJldHVybiBuZXcgeWUoaS5oLGkucyxpLmwsaS5vcGFjaXR5KTtpZihpIGluc3RhbmNlb2YgbnN8fChpPXJzKGkpKSwhaSlyZXR1cm4gbmV3IHllO2lmKGkgaW5zdGFuY2VvZiB5ZSlyZXR1cm4gaTtpPWkucmdiKCk7dmFyIHQ9aS5yLzI1NSxlPWkuZy8yNTUsbj1pLmIvMjU1LHM9TWF0aC5taW4odCxlLG4pLHI9TWF0aC5tYXgodCxlLG4pLG89TmFOLGE9ci1zLGM9KHIrcykvMjtyZXR1cm4gYT8odD09PXI/bz0oZS1uKS9hKyhlPG4pKjY6ZT09PXI/bz0obi10KS9hKzI6bz0odC1lKS9hKzQsYS89YzwuNT9yK3M6Mi1yLXMsbyo9NjApOmE9Yz4wJiZjPDE/MDpvLG5ldyB5ZShvLGEsYyxpLm9wYWNpdHkpfWZ1bmN0aW9uIE5tKGksdCxlLG4pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT9idShpKTpuZXcgeWUoaSx0LGUsbj09bnVsbD8xOm4pfWZ1bmN0aW9uIHllKGksdCxlLG4pe3RoaXMuaD0raSx0aGlzLnM9K3QsdGhpcy5sPStlLHRoaXMub3BhY2l0eT0rbn1vYyh5ZSxObSxmdShucyx7YnJpZ2h0ZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9WcjpNYXRoLnBvdyhWcixpKSxuZXcgeWUodGhpcy5oLHRoaXMucyx0aGlzLmwqaSx0aGlzLm9wYWNpdHkpfSxkYXJrZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9pczpNYXRoLnBvdyhpcyxpKSxuZXcgeWUodGhpcy5oLHRoaXMucyx0aGlzLmwqaSx0aGlzLm9wYWNpdHkpfSxyZ2IoKXt2YXIgaT10aGlzLmglMzYwKyh0aGlzLmg8MCkqMzYwLHQ9aXNOYU4oaSl8fGlzTmFOKHRoaXMucyk/MDp0aGlzLnMsZT10aGlzLmwsbj1lKyhlPC41P2U6MS1lKSp0LHM9MiplLW47cmV0dXJuIG5ldyBPdChjYyhpPj0yNDA/aS0yNDA6aSsxMjAscyxuKSxjYyhpLHMsbiksY2MoaTwxMjA/aSsyNDA6aS0xMjAscyxuKSx0aGlzLm9wYWNpdHkpfSxjbGFtcCgpe3JldHVybiBuZXcgeWUoTXUodGhpcy5oKSxIcih0aGlzLnMpLEhyKHRoaXMubCkscXIodGhpcy5vcGFjaXR5KSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuKDA8PXRoaXMucyYmdGhpcy5zPD0xfHxpc05hTih0aGlzLnMpKSYmMDw9dGhpcy5sJiZ0aGlzLmw8PTEmJjA8PXRoaXMub3BhY2l0eSYmdGhpcy5vcGFjaXR5PD0xfSxmb3JtYXRIc2woKXtjb25zdCBpPXFyKHRoaXMub3BhY2l0eSk7cmV0dXJuYCR7aT09PTE/ImhzbCgiOiJoc2xhKCJ9JHtNdSh0aGlzLmgpfSwgJHtIcih0aGlzLnMpKjEwMH0lLCAke0hyKHRoaXMubCkqMTAwfSUke2k9PT0xPyIpIjpgLCAke2l9KWB9YH19KSk7ZnVuY3Rpb24gTXUoaSl7cmV0dXJuIGk9KGl8fDApJTM2MCxpPDA/aSszNjA6aX1mdW5jdGlvbiBIcihpKXtyZXR1cm4gTWF0aC5tYXgoMCxNYXRoLm1pbigxLGl8fDApKX1mdW5jdGlvbiBjYyhpLHQsZSl7cmV0dXJuKGk8NjA/dCsoZS10KSppLzYwOmk8MTgwP2U6aTwyNDA/dCsoZS10KSooMjQwLWkpLzYwOnQpKjI1NX12YXIgbGM9aT0+KCk9Pmk7ZnVuY3Rpb24gUm0oaSx0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIGkrZSp0fX1mdW5jdGlvbiBMbShpLHQsZSl7cmV0dXJuIGk9TWF0aC5wb3coaSxlKSx0PU1hdGgucG93KHQsZSktaSxlPTEvZSxmdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5wb3coaStuKnQsZSl9fWZ1bmN0aW9uIE9tKGkpe3JldHVybihpPStpKT09MT9BdTpmdW5jdGlvbih0LGUpe3JldHVybiBlLXQ/TG0odCxlLGkpOmxjKGlzTmFOKHQpP2U6dCl9fWZ1bmN0aW9uIEF1KGksdCl7dmFyIGU9dC1pO3JldHVybiBlP1JtKGksZSk6bGMoaXNOYU4oaSk/dDppKX12YXIgU3U9ZnVuY3Rpb24gaSh0KXt2YXIgZT1PbSh0KTtmdW5jdGlvbiBuKHMscil7dmFyIG89ZSgocz1hYyhzKSkuciwocj1hYyhyKSkuciksYT1lKHMuZyxyLmcpLGM9ZShzLmIsci5iKSxsPUF1KHMub3BhY2l0eSxyLm9wYWNpdHkpO3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gcy5yPW8oaCkscy5nPWEoaCkscy5iPWMoaCkscy5vcGFjaXR5PWwoaCkscysiIn19cmV0dXJuIG4uZ2FtbWE9aSxufSgxKTtmdW5jdGlvbiBEbShpLHQpe3R8fCh0PVtdKTt2YXIgZT1pP01hdGgubWluKHQubGVuZ3RoLGkubGVuZ3RoKTowLG49dC5zbGljZSgpLHM7cmV0dXJuIGZ1bmN0aW9uKHIpe2ZvcihzPTA7czxlOysrcyluW3NdPWlbc10qKDEtcikrdFtzXSpyO3JldHVybiBufX1mdW5jdGlvbiAkbShpKXtyZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KGkpJiYhKGkgaW5zdGFuY2VvZiBEYXRhVmlldyl9ZnVuY3Rpb24gVm0oaSx0KXt2YXIgZT10P3QubGVuZ3RoOjAsbj1pP01hdGgubWluKGUsaS5sZW5ndGgpOjAscz1uZXcgQXJyYXkobikscj1uZXcgQXJyYXkoZSksbztmb3Iobz0wO288bjsrK28pc1tvXT1mYyhpW29dLHRbb10pO2Zvcig7bzxlOysrbylyW29dPXRbb107cmV0dXJuIGZ1bmN0aW9uKGEpe2ZvcihvPTA7bzxuOysrbylyW29dPXNbb10oYSk7cmV0dXJuIHJ9fWZ1bmN0aW9uIFVtKGksdCl7dmFyIGU9bmV3IERhdGU7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihuKXtyZXR1cm4gZS5zZXRUaW1lKGkqKDEtbikrdCpuKSxlfX1mdW5jdGlvbiBXcihpLHQpe3JldHVybiBpPStpLHQ9K3QsZnVuY3Rpb24oZSl7cmV0dXJuIGkqKDEtZSkrdCplfX1mdW5jdGlvbiBxbShpLHQpe3ZhciBlPXt9LG49e30sczsoaT09PW51bGx8fHR5cGVvZiBpIT0ib2JqZWN0IikmJihpPXt9KSwodD09PW51bGx8fHR5cGVvZiB0IT0ib2JqZWN0IikmJih0PXt9KTtmb3IocyBpbiB0KXMgaW4gaT9lW3NdPWZjKGlbc10sdFtzXSk6bltzXT10W3NdO3JldHVybiBmdW5jdGlvbihyKXtmb3IocyBpbiBlKW5bc109ZVtzXShyKTtyZXR1cm4gbn19dmFyIGhjPS9bLStdPyg/OlxkK1wuP1xkKnxcLj9cZCspKD86W2VFXVstK10/XGQrKT8vZyx1Yz1uZXcgUmVnRXhwKGhjLnNvdXJjZSwiZyIpO2Z1bmN0aW9uIEhtKGkpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBpfX1mdW5jdGlvbiBXbShpKXtyZXR1cm4gZnVuY3Rpb24odCl7cmV0dXJuIGkodCkrIiJ9fWZ1bmN0aW9uIEdtKGksdCl7dmFyIGU9aGMubGFzdEluZGV4PXVjLmxhc3RJbmRleD0wLG4scyxyLG89LTEsYT1bXSxjPVtdO2ZvcihpPWkrIiIsdD10KyIiOyhuPWhjLmV4ZWMoaSkpJiYocz11Yy5leGVjKHQpKTspKHI9cy5pbmRleCk+ZSYmKHI9dC5zbGljZShlLHIpLGFbb10/YVtvXSs9cjphWysrb109ciksKG49blswXSk9PT0ocz1zWzBdKT9hW29dP2Fbb10rPXM6YVsrK29dPXM6KGFbKytvXT1udWxsLGMucHVzaCh7aTpvLHg6V3IobixzKX0pKSxlPXVjLmxhc3RJbmRleDtyZXR1cm4gZTx0Lmxlbmd0aCYmKHI9dC5zbGljZShlKSxhW29dP2Fbb10rPXI6YVsrK29dPXIpLGEubGVuZ3RoPDI/Y1swXT9XbShjWzBdLngpOkhtKHQpOih0PWMubGVuZ3RoLGZ1bmN0aW9uKGwpe2Zvcih2YXIgaD0wLHU7aDx0OysraClhWyh1PWNbaF0pLmldPXUueChsKTtyZXR1cm4gYS5qb2luKCIiKX0pfWZ1bmN0aW9uIGZjKGksdCl7dmFyIGU9dHlwZW9mIHQsbjtyZXR1cm4gdD09bnVsbHx8ZT09PSJib29sZWFuIj9sYyh0KTooZT09PSJudW1iZXIiP1dyOmU9PT0ic3RyaW5nIj8obj1ycyh0KSk/KHQ9bixTdSk6R206dCBpbnN0YW5jZW9mIHJzP1N1OnQgaW5zdGFuY2VvZiBEYXRlP1VtOiRtKHQpP0RtOkFycmF5LmlzQXJyYXkodCk/Vm06dHlwZW9mIHQudmFsdWVPZiE9ImZ1bmN0aW9uIiYmdHlwZW9mIHQudG9TdHJpbmchPSJmdW5jdGlvbiJ8fGlzTmFOKHQpP3FtOldyKShpLHQpfWZ1bmN0aW9uIFptKGksdCl7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihlKXtyZXR1cm4gTWF0aC5yb3VuZChpKigxLWUpK3QqZSl9fWZ1bmN0aW9uIFhtKGkpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBpfX1mdW5jdGlvbiBKbShpKXtyZXR1cm4raX12YXIgX3U9WzAsMV07ZnVuY3Rpb24gZGkoaSl7cmV0dXJuIGl9ZnVuY3Rpb24gZGMoaSx0KXtyZXR1cm4odC09aT0raSk/ZnVuY3Rpb24oZSl7cmV0dXJuKGUtaSkvdH06WG0oaXNOYU4odCk/TmFOOi41KX1mdW5jdGlvbiBZbShpLHQpe3ZhciBlO3JldHVybiBpPnQmJihlPWksaT10LHQ9ZSksZnVuY3Rpb24obil7cmV0dXJuIE1hdGgubWF4KGksTWF0aC5taW4odCxuKSl9fWZ1bmN0aW9uIGptKGksdCxlKXt2YXIgbj1pWzBdLHM9aVsxXSxyPXRbMF0sbz10WzFdO3JldHVybiBzPG4/KG49ZGMocyxuKSxyPWUobyxyKSk6KG49ZGMobixzKSxyPWUocixvKSksZnVuY3Rpb24oYSl7cmV0dXJuIHIobihhKSl9fWZ1bmN0aW9uIFFtKGksdCxlKXt2YXIgbj1NYXRoLm1pbihpLmxlbmd0aCx0Lmxlbmd0aCktMSxzPW5ldyBBcnJheShuKSxyPW5ldyBBcnJheShuKSxvPS0xO2ZvcihpW25dPGlbMF0mJihpPWkuc2xpY2UoKS5yZXZlcnNlKCksdD10LnNsaWNlKCkucmV2ZXJzZSgpKTsrK288bjspc1tvXT1kYyhpW29dLGlbbysxXSkscltvXT1lKHRbb10sdFtvKzFdKTtyZXR1cm4gZnVuY3Rpb24oYSl7dmFyIGM9dHAoaSxhLDEsbiktMTtyZXR1cm4gcltjXShzW2NdKGEpKX19ZnVuY3Rpb24gS20oaSx0KXtyZXR1cm4gdC5kb21haW4oaS5kb21haW4oKSkucmFuZ2UoaS5yYW5nZSgpKS5pbnRlcnBvbGF0ZShpLmludGVycG9sYXRlKCkpLmNsYW1wKGkuY2xhbXAoKSkudW5rbm93bihpLnVua25vd24oKSl9ZnVuY3Rpb24gdGcoKXt2YXIgaT1fdSx0PV91LGU9ZmMsbixzLHIsbz1kaSxhLGMsbDtmdW5jdGlvbiBoKCl7dmFyIGY9TWF0aC5taW4oaS5sZW5ndGgsdC5sZW5ndGgpO3JldHVybiBvIT09ZGkmJihvPVltKGlbMF0saVtmLTFdKSksYT1mPjI/UW06am0sYz1sPW51bGwsdX1mdW5jdGlvbiB1KGYpe3JldHVybiBmPT1udWxsfHxpc05hTihmPStmKT9yOihjfHwoYz1hKGkubWFwKG4pLHQsZSkpKShuKG8oZikpKX1yZXR1cm4gdS5pbnZlcnQ9ZnVuY3Rpb24oZil7cmV0dXJuIG8ocygobHx8KGw9YSh0LGkubWFwKG4pLFdyKSkpKGYpKSl9LHUuZG9tYWluPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhpPUFycmF5LmZyb20oZixKbSksaCgpKTppLnNsaWNlKCl9LHUucmFuZ2U9ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHQ9QXJyYXkuZnJvbShmKSxoKCkpOnQuc2xpY2UoKX0sdS5yYW5nZVJvdW5kPWZ1bmN0aW9uKGYpe3JldHVybiB0PUFycmF5LmZyb20oZiksZT1abSxoKCl9LHUuY2xhbXA9ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KG89Zj8hMDpkaSxoKCkpOm8hPT1kaX0sdS5pbnRlcnBvbGF0ZT1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZT1mLGgoKSk6ZX0sdS51bmtub3duPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhyPWYsdSk6cn0sZnVuY3Rpb24oZixkKXtyZXR1cm4gbj1mLHM9ZCxoKCl9fWZ1bmN0aW9uIGVnKCl7cmV0dXJuIHRnKCkoZGksZGkpfWZ1bmN0aW9uIG5nKGkpe3JldHVybiBNYXRoLmFicyhpPU1hdGgucm91bmQoaSkpPj0xZTIxP2kudG9Mb2NhbGVTdHJpbmcoImVuIikucmVwbGFjZSgvLC9nLCIiKTppLnRvU3RyaW5nKDEwKX1mdW5jdGlvbiBHcihpLHQpe2lmKChlPShpPXQ/aS50b0V4cG9uZW50aWFsKHQtMSk6aS50b0V4cG9uZW50aWFsKCkpLmluZGV4T2YoImUiKSk8MClyZXR1cm4gbnVsbDt2YXIgZSxuPWkuc2xpY2UoMCxlKTtyZXR1cm5bbi5sZW5ndGg+MT9uWzBdK24uc2xpY2UoMik6biwraS5zbGljZShlKzEpXX1mdW5jdGlvbiBwaShpKXtyZXR1cm4gaT1HcihNYXRoLmFicyhpKSksaT9pWzFdOk5hTn1mdW5jdGlvbiBpZyhpLHQpe3JldHVybiBmdW5jdGlvbihlLG4pe2Zvcih2YXIgcz1lLmxlbmd0aCxyPVtdLG89MCxhPWlbMF0sYz0wO3M+MCYmYT4wJiYoYythKzE+biYmKGE9TWF0aC5tYXgoMSxuLWMpKSxyLnB1c2goZS5zdWJzdHJpbmcocy09YSxzK2EpKSwhKChjKz1hKzEpPm4pKTspYT1pW289KG8rMSklaS5sZW5ndGhdO3JldHVybiByLnJldmVyc2UoKS5qb2luKHQpfX1mdW5jdGlvbiBzZyhpKXtyZXR1cm4gZnVuY3Rpb24odCl7cmV0dXJuIHQucmVwbGFjZSgvWzAtOV0vZyxmdW5jdGlvbihlKXtyZXR1cm4gaVsrZV19KX19dmFyIHJnPS9eKD86KC4pPyhbPD49Xl0pKT8oWytcLSggXSk/KFskI10pPygwKT8oXGQrKT8oLCk/KFwuXGQrKT8ofik/KFthLXolXSk/JC9pO2Z1bmN0aW9uIFpyKGkpe2lmKCEodD1yZy5leGVjKGkpKSl0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgZm9ybWF0OiAiK2kpO3ZhciB0O3JldHVybiBuZXcgcGMoe2ZpbGw6dFsxXSxhbGlnbjp0WzJdLHNpZ246dFszXSxzeW1ib2w6dFs0XSx6ZXJvOnRbNV0sd2lkdGg6dFs2XSxjb21tYTp0WzddLHByZWNpc2lvbjp0WzhdJiZ0WzhdLnNsaWNlKDEpLHRyaW06dFs5XSx0eXBlOnRbMTBdfSl9WnIucHJvdG90eXBlPXBjLnByb3RvdHlwZTtmdW5jdGlvbiBwYyhpKXt0aGlzLmZpbGw9aS5maWxsPT09dm9pZCAwPyIgIjppLmZpbGwrIiIsdGhpcy5hbGlnbj1pLmFsaWduPT09dm9pZCAwPyI+IjppLmFsaWduKyIiLHRoaXMuc2lnbj1pLnNpZ249PT12b2lkIDA/Ii0iOmkuc2lnbisiIix0aGlzLnN5bWJvbD1pLnN5bWJvbD09PXZvaWQgMD8iIjppLnN5bWJvbCsiIix0aGlzLnplcm89ISFpLnplcm8sdGhpcy53aWR0aD1pLndpZHRoPT09dm9pZCAwP3ZvaWQgMDoraS53aWR0aCx0aGlzLmNvbW1hPSEhaS5jb21tYSx0aGlzLnByZWNpc2lvbj1pLnByZWNpc2lvbj09PXZvaWQgMD92b2lkIDA6K2kucHJlY2lzaW9uLHRoaXMudHJpbT0hIWkudHJpbSx0aGlzLnR5cGU9aS50eXBlPT09dm9pZCAwPyIiOmkudHlwZSsiIn1wYy5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5maWxsK3RoaXMuYWxpZ24rdGhpcy5zaWduK3RoaXMuc3ltYm9sKyh0aGlzLnplcm8/IjAiOiIiKSsodGhpcy53aWR0aD09PXZvaWQgMD8iIjpNYXRoLm1heCgxLHRoaXMud2lkdGh8MCkpKyh0aGlzLmNvbW1hPyIsIjoiIikrKHRoaXMucHJlY2lzaW9uPT09dm9pZCAwPyIiOiIuIitNYXRoLm1heCgwLHRoaXMucHJlY2lzaW9ufDApKSsodGhpcy50cmltPyJ+IjoiIikrdGhpcy50eXBlfTtmdW5jdGlvbiBvZyhpKXt0OmZvcih2YXIgdD1pLmxlbmd0aCxlPTEsbj0tMSxzO2U8dDsrK2Upc3dpdGNoKGlbZV0pe2Nhc2UiLiI6bj1zPWU7YnJlYWs7Y2FzZSIwIjpuPT09MCYmKG49ZSkscz1lO2JyZWFrO2RlZmF1bHQ6aWYoIStpW2VdKWJyZWFrIHQ7bj4wJiYobj0wKTticmVha31yZXR1cm4gbj4wP2kuc2xpY2UoMCxuKStpLnNsaWNlKHMrMSk6aX12YXIgdnU7ZnVuY3Rpb24gYWcoaSx0KXt2YXIgZT1HcihpLHQpO2lmKCFlKXJldHVybiBpKyIiO3ZhciBuPWVbMF0scz1lWzFdLHI9cy0odnU9TWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKHMvMykpKSozKSsxLG89bi5sZW5ndGg7cmV0dXJuIHI9PT1vP246cj5vP24rbmV3IEFycmF5KHItbysxKS5qb2luKCIwIik6cj4wP24uc2xpY2UoMCxyKSsiLiIrbi5zbGljZShyKToiMC4iK25ldyBBcnJheSgxLXIpLmpvaW4oIjAiKStHcihpLE1hdGgubWF4KDAsdCtyLTEpKVswXX1mdW5jdGlvbiB6dShpLHQpe3ZhciBlPUdyKGksdCk7aWYoIWUpcmV0dXJuIGkrIiI7dmFyIG49ZVswXSxzPWVbMV07cmV0dXJuIHM8MD8iMC4iK25ldyBBcnJheSgtcykuam9pbigiMCIpK246bi5sZW5ndGg+cysxP24uc2xpY2UoMCxzKzEpKyIuIituLnNsaWNlKHMrMSk6bituZXcgQXJyYXkocy1uLmxlbmd0aCsyKS5qb2luKCIwIil9dmFyIFR1PXsiJSI6KGksdCk9PihpKjEwMCkudG9GaXhlZCh0KSxiOmk9Pk1hdGgucm91bmQoaSkudG9TdHJpbmcoMiksYzppPT5pKyIiLGQ6bmcsZTooaSx0KT0+aS50b0V4cG9uZW50aWFsKHQpLGY6KGksdCk9PmkudG9GaXhlZCh0KSxnOihpLHQpPT5pLnRvUHJlY2lzaW9uKHQpLG86aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZyg4KSxwOihpLHQpPT56dShpKjEwMCx0KSxyOnp1LHM6YWcsWDppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpLHg6aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZygxNil9O2Z1bmN0aW9uIEV1KGkpe3JldHVybiBpfXZhciBQdT1BcnJheS5wcm90b3R5cGUubWFwLEN1PVsieSIsInoiLCJhIiwiZiIsInAiLCJuIiwiwrUiLCJtIiwiIiwiayIsIk0iLCJHIiwiVCIsIlAiLCJFIiwiWiIsIlkiXTtmdW5jdGlvbiBjZyhpKXt2YXIgdD1pLmdyb3VwaW5nPT09dm9pZCAwfHxpLnRob3VzYW5kcz09PXZvaWQgMD9FdTppZyhQdS5jYWxsKGkuZ3JvdXBpbmcsTnVtYmVyKSxpLnRob3VzYW5kcysiIiksZT1pLmN1cnJlbmN5PT09dm9pZCAwPyIiOmkuY3VycmVuY3lbMF0rIiIsbj1pLmN1cnJlbmN5PT09dm9pZCAwPyIiOmkuY3VycmVuY3lbMV0rIiIscz1pLmRlY2ltYWw9PT12b2lkIDA/Ii4iOmkuZGVjaW1hbCsiIixyPWkubnVtZXJhbHM9PT12b2lkIDA/RXU6c2coUHUuY2FsbChpLm51bWVyYWxzLFN0cmluZykpLG89aS5wZXJjZW50PT09dm9pZCAwPyIlIjppLnBlcmNlbnQrIiIsYT1pLm1pbnVzPT09dm9pZCAwPyLiiJIiOmkubWludXMrIiIsYz1pLm5hbj09PXZvaWQgMD8iTmFOIjppLm5hbisiIjtmdW5jdGlvbiBsKHUpe3U9WnIodSk7dmFyIGY9dS5maWxsLGQ9dS5hbGlnbixwPXUuc2lnbix5PXUuc3ltYm9sLG09dS56ZXJvLGc9dS53aWR0aCxiPXUuY29tbWEsdz11LnByZWNpc2lvbix4PXUudHJpbSxNPXUudHlwZTtNPT09Im4iPyhiPSEwLE09ImciKTpUdVtNXXx8KHc9PT12b2lkIDAmJih3PTEyKSx4PSEwLE09ImciKSwobXx8Zj09PSIwIiYmZD09PSI9IikmJihtPSEwLGY9IjAiLGQ9Ij0iKTt2YXIgQT15PT09IiQiP2U6eT09PSIjIiYmL1tib3hYXS8udGVzdChNKT8iMCIrTS50b0xvd2VyQ2FzZSgpOiIiLFM9eT09PSIkIj9uOi9bJXBdLy50ZXN0KE0pP286IiIsXz1UdVtNXSxFPS9bZGVmZ3BycyVdLy50ZXN0KE0pO3c9dz09PXZvaWQgMD82Oi9bZ3Byc10vLnRlc3QoTSk/TWF0aC5tYXgoMSxNYXRoLm1pbigyMSx3KSk6TWF0aC5tYXgoMCxNYXRoLm1pbigyMCx3KSk7ZnVuY3Rpb24geih2KXt2YXIgQz1BLFA9UyxGLEIsSTtpZihNPT09ImMiKVA9Xyh2KStQLHY9IiI7ZWxzZXt2PSt2O3ZhciBrPXY8MHx8MS92PDA7aWYodj1pc05hTih2KT9jOl8oTWF0aC5hYnModiksdykseCYmKHY9b2codikpLGsmJit2PT0wJiZwIT09IisiJiYoaz0hMSksQz0oaz9wPT09IigiP3A6YTpwPT09Ii0ifHxwPT09IigiPyIiOnApK0MsUD0oTT09PSJzIj9DdVs4K3Z1LzNdOiIiKStQKyhrJiZwPT09IigiPyIpIjoiIiksRSl7Zm9yKEY9LTEsQj12Lmxlbmd0aDsrK0Y8QjspaWYoST12LmNoYXJDb2RlQXQoRiksNDg+SXx8ST41Nyl7UD0oST09PTQ2P3Mrdi5zbGljZShGKzEpOnYuc2xpY2UoRikpK1Asdj12LnNsaWNlKDAsRik7YnJlYWt9fX1iJiYhbSYmKHY9dCh2LDEvMCkpO3ZhciBEPUMubGVuZ3RoK3YubGVuZ3RoK1AubGVuZ3RoLFU9RDxnP25ldyBBcnJheShnLUQrMSkuam9pbihmKToiIjtzd2l0Y2goYiYmbSYmKHY9dChVK3YsVS5sZW5ndGg/Zy1QLmxlbmd0aDoxLzApLFU9IiIpLGQpe2Nhc2UiPCI6dj1DK3YrUCtVO2JyZWFrO2Nhc2UiPSI6dj1DK1UrditQO2JyZWFrO2Nhc2UiXiI6dj1VLnNsaWNlKDAsRD1VLmxlbmd0aD4+MSkrQyt2K1ArVS5zbGljZShEKTticmVhaztkZWZhdWx0OnY9VStDK3YrUDticmVha31yZXR1cm4gcih2KX1yZXR1cm4gei50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB1KyIifSx6fWZ1bmN0aW9uIGgodSxmKXt2YXIgZD1sKCh1PVpyKHUpLHUudHlwZT0iZiIsdSkpLHA9TWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKHBpKGYpLzMpKSkqMyx5PU1hdGgucG93KDEwLC1wKSxtPUN1WzgrcC8zXTtyZXR1cm4gZnVuY3Rpb24oZyl7cmV0dXJuIGQoeSpnKSttfX1yZXR1cm57Zm9ybWF0OmwsZm9ybWF0UHJlZml4Omh9fXZhciBYcixCdSxGdTtsZyh7dGhvdXNhbmRzOiIsIixncm91cGluZzpbM10sY3VycmVuY3k6WyIkIiwiIl19KTtmdW5jdGlvbiBsZyhpKXtyZXR1cm4gWHI9Y2coaSksQnU9WHIuZm9ybWF0LEZ1PVhyLmZvcm1hdFByZWZpeCxYcn1mdW5jdGlvbiBoZyhpKXtyZXR1cm4gTWF0aC5tYXgoMCwtcGkoTWF0aC5hYnMoaSkpKX1mdW5jdGlvbiB1ZyhpLHQpe3JldHVybiBNYXRoLm1heCgwLE1hdGgubWF4KC04LE1hdGgubWluKDgsTWF0aC5mbG9vcihwaSh0KS8zKSkpKjMtcGkoTWF0aC5hYnMoaSkpKX1mdW5jdGlvbiBmZyhpLHQpe3JldHVybiBpPU1hdGguYWJzKGkpLHQ9TWF0aC5hYnModCktaSxNYXRoLm1heCgwLHBpKHQpLXBpKGkpKSsxfWZ1bmN0aW9uIGRnKGksdCxlLG4pe3ZhciBzPXJwKGksdCxlKSxyO3N3aXRjaChuPVpyKG49PW51bGw/IixmIjpuKSxuLnR5cGUpe2Nhc2UicyI6e3ZhciBvPU1hdGgubWF4KE1hdGguYWJzKGkpLE1hdGguYWJzKHQpKTtyZXR1cm4gbi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPXVnKHMsbykpJiYobi5wcmVjaXNpb249ciksRnUobixvKX1jYXNlIiI6Y2FzZSJlIjpjYXNlImciOmNhc2UicCI6Y2FzZSJyIjp7bi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPWZnKHMsTWF0aC5tYXgoTWF0aC5hYnMoaSksTWF0aC5hYnModCkpKSkmJihuLnByZWNpc2lvbj1yLShuLnR5cGU9PT0iZSIpKTticmVha31jYXNlImYiOmNhc2UiJSI6e24ucHJlY2lzaW9uPT1udWxsJiYhaXNOYU4ocj1oZyhzKSkmJihuLnByZWNpc2lvbj1yLShuLnR5cGU9PT0iJSIpKjIpO2JyZWFrfX1yZXR1cm4gQnUobil9ZnVuY3Rpb24gcGcoaSl7dmFyIHQ9aS5kb21haW47cmV0dXJuIGkudGlja3M9ZnVuY3Rpb24oZSl7dmFyIG49dCgpO3JldHVybiBzcChuWzBdLG5bbi5sZW5ndGgtMV0sZT09bnVsbD8xMDplKX0saS50aWNrRm9ybWF0PWZ1bmN0aW9uKGUsbil7dmFyIHM9dCgpO3JldHVybiBkZyhzWzBdLHNbcy5sZW5ndGgtMV0sZT09bnVsbD8xMDplLG4pfSxpLm5pY2U9ZnVuY3Rpb24oZSl7ZT09bnVsbCYmKGU9MTApO3ZhciBuPXQoKSxzPTAscj1uLmxlbmd0aC0xLG89bltzXSxhPW5bcl0sYyxsLGg9MTA7Zm9yKGE8byYmKGw9byxvPWEsYT1sLGw9cyxzPXIscj1sKTtoLS0gPjA7KXtpZihsPUFhKG8sYSxlKSxsPT09YylyZXR1cm4gbltzXT1vLG5bcl09YSx0KG4pO2lmKGw+MClvPU1hdGguZmxvb3Ioby9sKSpsLGE9TWF0aC5jZWlsKGEvbCkqbDtlbHNlIGlmKGw8MClvPU1hdGguY2VpbChvKmwpL2wsYT1NYXRoLmZsb29yKGEqbCkvbDtlbHNlIGJyZWFrO2M9bH1yZXR1cm4gaX0saX1mdW5jdGlvbiB5Yygpe3ZhciBpPWVnKCk7cmV0dXJuIGkuY29weT1mdW5jdGlvbigpe3JldHVybiBLbShpLHljKCkpfSxTbS5hcHBseShpLGFyZ3VtZW50cykscGcoaSl9ZnVuY3Rpb24geWcoaSx0KXtyZXR1cm4gaS5tYXAoZT0+e2NvbnN0IG49W107bGV0IHM7cmV0dXJuIGUuZm9yRWFjaChyPT57aWYocyl7Y29uc3Qgbz1yaShyLHMpKjE4MC9NYXRoLlBJO2lmKG8+dCl7Y29uc3QgYT1WcChzLHIpLGM9MS9NYXRoLmNlaWwoby90KTtsZXQgbD1jO2Zvcig7bDwxOyluLnB1c2goYShsKSksbCs9Y319bi5wdXNoKHM9cil9KSxufSl9ZnVuY3Rpb24gbWcoaSx7bWluTG5nOnQsbWF4TG5nOmUsbWluTGF0Om4sbWF4TGF0OnN9PXt9KXtjb25zdCByPU1hdGgucm91bmQoeWkoMzYwL2ksMikvTWF0aC5QSSksbz0oMStNYXRoLnNxcnQoNSkpLzIsYT1kPT5kL28qMzYwJTM2MC0xODAsYz1kPT5NYXRoLmFjb3MoMipkL3ItMSkvTWF0aC5QSSoxODAtOTAsbD1kPT5yKihNYXRoLmNvcygoZCs5MCkqTWF0aC5QSS8xODApKzEpLzIsaD1bcyE9PXZvaWQgMD9NYXRoLmNlaWwobChzKSk6MCxuIT09dm9pZCAwP01hdGguZmxvb3IobChuKSk6ci0xXSx1PXQ9PT12b2lkIDAmJmU9PT12b2lkIDA/KCk9PiEwOnQ9PT12b2lkIDA/ZD0+ZDw9ZTplPT09dm9pZCAwP2Q9PmQ+PXQ6ZT49dD9kPT5kPj10JiZkPD1lOmQ9PmQ+PXR8fGQ8PWUsZj1bXTtmb3IobGV0IGQ9aFswXTtkPD1oWzFdO2QrKyl7Y29uc3QgcD1hKGQpO3UocCkmJmYucHVzaChbcCxjKGQpXSl9cmV0dXJuIGZ9ZnVuY3Rpb24gbWMoaSx0LGU9ITEpe3JldHVybiBlPyRwKHQsaSk6ankoaSx0KX1mdW5jdGlvbiBnZyhpLHQpe2NvbnN0IGU9e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOml9LFtbbixzXSxbcixvXV09ZmgoZSk7aWYoTWF0aC5taW4oTWF0aC5hYnMoci1uKSxNYXRoLmFicyhvLXMpKTx0KXJldHVybltdO2NvbnN0IGE9bj5yfHxvPj04OXx8czw9LTg5O3JldHVybiBtZyh0LHttaW5Mbmc6bixtYXhMbmc6cixtaW5MYXQ6cyxtYXhMYXQ6b30pLmZpbHRlcihjPT5tYyhjLGUsYSkpfWZ1bmN0aW9uIHhnKGkse3Jlc29sdXRpb246dD0xLzAsYmJveDplLHByb2plY3Rpb246bn09e30pe2NvbnN0IHM9eWcoaSx0KSxyPVZpKHMpLG89Z2coaSx0KSxhPVsuLi5yLC4uLm9dLGM9e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOml9LFtbbCxoXSxbdSxmXV09ZmgoYyksZD1sPnV8fGY+PTg5fHxoPD0tODk7bGV0IHA9W107aWYoZCl7Y29uc3QgTT1BbShhKS50cmlhbmdsZXMoKSxBPW5ldyBNYXAoYS5tYXAoKFtTLF9dLEUpPT5bYCR7U30tJHtffWAsRV0pKTtNLmZlYXR1cmVzLmZvckVhY2goUz0+e2NvbnN0IF89Uy5nZW9tZXRyeS5jb29yZGluYXRlc1swXS5zbGljZSgwLDMpLnJldmVyc2UoKSxFPVtdO2lmKF8uZm9yRWFjaCgoW3osdl0pPT57Y29uc3QgQz1gJHt6fS0ke3Z9YDtBLmhhcyhDKSYmRS5wdXNoKEEuZ2V0KEMpKX0pLEUubGVuZ3RoPT09Myl7aWYoRS5zb21lKHo9Pno8ci5sZW5ndGgpKXtjb25zdCB6PVMucHJvcGVydGllcy5jaXJjdW1jZW50ZXI7aWYoIW1jKHosYyxkKSlyZXR1cm59cC5wdXNoKC4uLkUpfX0pfWVsc2UgaWYoby5sZW5ndGgpe2NvbnN0IE09dHMuZnJvbShhKTtmb3IobGV0IEE9MCxTPU0udHJpYW5nbGVzLmxlbmd0aDtBPFM7QSs9Myl7Y29uc3QgXz1bMiwxLDBdLm1hcCh6PT5NLnRyaWFuZ2xlc1tBK3pdKSxFPV8ubWFwKHo9PmFbel0pO2lmKF8uc29tZSh6PT56PHIubGVuZ3RoKSl7Y29uc3Qgej1bMCwxXS5tYXAodj0+b3AoRSxDPT5DW3ZdKSk7aWYoIW1jKHosYyxkKSljb250aW51ZX1wLnB1c2goLi4uXyl9fWVsc2V7Y29uc3R7dmVydGljZXM6TSxob2xlczpBPVtdfT1RaChzKTtwPXB5KE0sQSwyKX1sZXQgeT1lP1tlWzBdLGVbMl1dOnNyKGEsTT0+TVswXSksbT1lP1tlWzFdLGVbM11dOnNyKGEsTT0+TVsxXSk7aWYobil7Y29uc3RbTSxBXT1uKFt5WzBdLG1bMF1dKSxbUyxfXT1uKFt5WzFdLG1bMV1dKTt5PVtNLFNdLG09Wy1BLC1fXX1jb25zdCBnPXljKHksWzAsMV0pLGI9eWMobSxbMCwxXSksdz1hLm1hcCgoW00sQV0pPT57aWYobil7Y29uc3RbUyxfXT1uKFtNLEFdKTtyZXR1cm5bZyhTKSxiKC1fKV19ZWxzZSByZXR1cm5bZyhNKSxiKEEpXX0pO3JldHVybntjb250b3VyOnMsdHJpYW5nbGVzOntwb2ludHM6YSxpbmRpY2VzOnAsdXZzOnd9fX1jb25zdCBJdT1uZXcgdWUoKS5zZXRBdHRyaWJ1dGU/InNldEF0dHJpYnV0ZSI6ImFkZEF0dHJpYnV0ZSI7ZnVuY3Rpb24gSnIoaSx0LGUsbil7Y29uc3Qgcz1pLm1hcChyPT5yLm1hcCgoW28sYV0pPT57aWYobil7Y29uc3RbYyxsXT1uKFtvLGFdKTtyZXR1cm5bYywtbCx0XX1yZXR1cm4gZT9ZMChvLGEsdCk6W28sYSx0XX0pKTtyZXR1cm4gUWgocyl9ZnVuY3Rpb24gd2coaSx0LGUsbixzKXtjb25zdHt2ZXJ0aWNlczpyLGhvbGVzOm99PUpyKGksdCxuLHMpLHt2ZXJ0aWNlczphfT1KcihpLGUsbixzKSxjPVZpKFthLHJdKSxsPU1hdGgucm91bmQoYS5sZW5ndGgvMyksaD1uZXcgU2V0KG8pO2xldCB1PTA7Y29uc3QgZj1bXTtmb3IobGV0IHA9MDtwPGw7cCsrKXtsZXQgeT1wKzE7aWYoeT09PWwpeT11O2Vsc2UgaWYoaC5oYXMoeSkpe2NvbnN0IG09eTt5PXUsdT1tfWYucHVzaChwLHArbCx5K2wpLGYucHVzaCh5K2wseSxwKX1jb25zdCBkPVtdO2ZvcihsZXQgcD0xO3A+PTA7cC0tKWZvcihsZXQgeT0wO3k8bDt5Kz0xKWQucHVzaCh5LyhsLTEpLHApO3JldHVybntpbmRpY2VzOmYsdmVydGljZXM6Yyx1dnM6ZCx0b3BWZXJ0czphfX1mdW5jdGlvbiBrdShpLHQsZSxuLHMscil7cmV0dXJue2luZGljZXM6bj9pLmluZGljZXM6aS5pbmRpY2VzLnNsaWNlKCkucmV2ZXJzZSgpLHZlcnRpY2VzOkpyKFtpLnBvaW50c10sdCxzLHIpLnZlcnRpY2VzLHV2czplfX1jb25zdCBOdT0oe3BvbHlnb25HZW9Kc29uOmksc3RhcnRIZWlnaHQ6dCxlbmRIZWlnaHQ6ZSxjdXJ2YXR1cmVSZXNvbHV0aW9uOm49MSxjYXJ0ZXNpYW46cz0hMCxoYXNTaWRlOnI9ITAsaGFzQm90dG9tOm89ITEsaGFzVG9wOmE9ITEscHJvamVjdGlvbjpjLGJib3g6bH0pPT57aS5mb3JFYWNoKGc9PntOeShnKXx8Zy5yZXZlcnNlKCl9KTtjb25zdHtjb250b3VyOmgsdHJpYW5nbGVzOnV9PXhnKGkse3Jlc29sdXRpb246bixiYm94OmwscHJvamVjdGlvbjpjfSk7bGV0IGY9e30sZDtyJiYoZj13ZyhoLHQhPW51bGw/dDplLGUhPW51bGw/ZTp0LHMsYyksZD1mLnRvcFZlcnRzKTtsZXQgcD1bXTsob3x8YSkmJihwPVZpKHUudXZzKSk7bGV0IHk9e307byYmKHk9a3UodSx0LHAsITEscyxjKSk7bGV0IG09e307cmV0dXJuIGEmJihtPWt1KHUsZSxwLCEwLHMsYykpLHtjb250b3VyOmgsdHJpYW5nbGVzOnUsc2lkZVRvcnNvOmYsYm90dG9tQ2FwOnksdG9wQ2FwOm0sdG9wVmVydHM6ZH19O2NsYXNzIGJnIGV4dGVuZHMgdWV7Y29uc3RydWN0b3IodCxlPXt9KXtzdXBlcigpLHRoaXMudHlwZT0iUG9seWdvbkJ1ZmZlckdlb21ldHJ5Iix0aGlzLnBhcmFtZXRlcnM9RnQoe3BvbHlnb25HZW9Kc29uOnQsc3RhcnRIZWlnaHQ6MCxlbmRIZWlnaHQ6MSxoYXNUb3A6ITAsdG9wRmlyc3Q6ITEsaGFzQm90dG9tOiEwLGhhc1NpZGU6ITAsY3VydmF0dXJlUmVzb2x1dGlvbjoxLGNhcnRlc2lhbjohMCx1c2VyRGF0YVJzb09mZnNldDowfSxlKTtjb25zdHtlbmRIZWlnaHQ6bixoYXNUb3A6cyx0b3BGaXJzdDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSxjYXJ0ZXNpYW46Yyx1c2VyRGF0YVJzb09mZnNldDpsLHByb2plY3Rpb246aH09dGhpcy5wYXJhbWV0ZXJzLHtjb250b3VyOnUsc2lkZVRvcnNvOmYsdG9wVmVydHM6ZCxib3R0b21DYXA6cCx0b3BDYXA6eX09TnUoRnQoe30sdGhpcy5wYXJhbWV0ZXJzKSk7bGV0IG09W10sZz1bXSxiPVtdLHc9MDtjb25zdCB4PU09Pntjb25zdCBBPU1hdGgucm91bmQobS5sZW5ndGgvMyksUz1iLmxlbmd0aDttPW0uY29uY2F0KE0udmVydGljZXMpLGc9Zy5jb25jYXQoTS51dnMpLGI9Yi5jb25jYXQoQT9NLmluZGljZXMubWFwKF89Pl8rQSk6TS5pbmRpY2VzKSx0aGlzLmFkZEdyb3VwKFMsYi5sZW5ndGgtUyx3KyspfTtzJiZyJiZ4KHkpLGEmJih4KGYpLHRoaXMudXNlckRhdGEudG9wVmVydHM9bD9Kcih1LG4rbCxjLGgpLnZlcnRpY2VzOmQpLG8mJngocCkscyYmIXImJngoeSksdGhpcy5zZXRJbmRleChiKSx0aGlzW0l1XSgicG9zaXRpb24iLG5ldyBCZShtLDMpKSx0aGlzW0l1XSgidXYiLG5ldyBCZShnLDIpKSx0aGlzLmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCl9fXZhciBNZz1pPT57Y29uc3QgYT1pLHtjb29yZGluYXRlOnQsc3RhcnRIZWlnaHQ6ZSxoZWlnaHQ6bn09YSxzPUp1KGEsWyJjb29yZGluYXRlIiwic3RhcnRIZWlnaHQiLCJoZWlnaHQiXSk7bGV0IHI9ZXx8MDtyZXR1cm4gdHlwZW9mIGUhPSJ1bmRlZmluZWQiJiZ0eXBlb2YgbiE9InVuZGVmaW5lZCImJihyPWUrbiksbmV3IGJnKFt0XSxaZShGdCh7fSxzKSx7c3RhcnRIZWlnaHQ6ZSxlbmRIZWlnaHQ6cn0pKX07Y29uc3QgQWc9KHtjb29yZGluYXRlc0FycjppLHN0YXJ0OnQsZGVwdGg6ZSx1c2VHcm91cHM6bixoYXNUb3A6cyx0b3BGaXJzdDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSxjYXJ0ZXNpYW46Yyxwcm9qZWN0aW9uOmwsY3VydmF0dXJlUmVzb2x1dGlvbjpoLGJib3g6dX0pPT57Y29uc3QgZj1sJiZYaShsKTtmJiYoYz0hMSksdHx8KHQ9WzBdKTtjb25zdCBkPWkubWFwKChwLHkpPT57dmFyIG0sZztyZXR1cm4gTWcoe2Nvb3JkaW5hdGU6cCxwcm9qZWN0aW9uOmYsc3RhcnRIZWlnaHQ6KG09dFt5XSkhPW51bGw/bTp0WzBdLGhlaWdodDooZz1lW3ldKSE9bnVsbD9nOmVbMF0saGFzVG9wOnMhPW51bGw/czohMCx0b3BGaXJzdDpyIT1udWxsP3I6ITEsaGFzQm90dG9tOm8hPW51bGw/bzohMCxoYXNTaWRlOmEhPW51bGw/YTohMCxjYXJ0ZXNpYW46YyE9bnVsbD9jOiEwLGN1cnZhdHVyZVJlc29sdXRpb246aCE9bnVsbD9oOjEsYmJveDp1fSl9KTtyZXR1cm4gSmkoZCxuKX0sU2c9KHtjb29yZGluYXRlc0FycjppLGxpbmVXaWR0aDp0LHN0YXJ0OmUsdXNlR3JvdXBzOm59KT0+e2NvbnN0IHI9aS5tYXAoKG8sYSk9Pnt2YXIgYztyZXR1cm4gTnUoe3BvbHlnb25HZW9Kc29uOltvXSxzdGFydEhlaWdodDooYz1lW2FdKSE9bnVsbD9jOmVbMF19KS50b3BWZXJ0c30pLm1hcCgobyxhKT0+e3ZhciBsO2NvbnN0IGM9KGw9dFthXSkhPW51bGw/bDp0WzBdO3JldHVybiBaaCh7bm9kZXM6byxzZXRQb2ludFdpZHRoOigpPT5jfSl9KTtyZXR1cm4gSmkocixuKX07dmFyIF9nPShpLHQsZSk9Pm5ldyBQcm9taXNlKChuLHMpPT57dmFyIHI9Yz0+e3RyeXthKGUubmV4dChjKSl9Y2F0Y2gobCl7cyhsKX19LG89Yz0+e3RyeXthKGUudGhyb3coYykpfWNhdGNoKGwpe3MobCl9fSxhPWM9PmMuZG9uZT9uKGMudmFsdWUpOlByb21pc2UucmVzb2x2ZShjLnZhbHVlKS50aGVuKHIsbyk7YSgoZT1lLmFwcGx5KGksdCkpLm5leHQoKSl9KTtmdW5jdGlvbiB2ZyhpKXtyZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoaSkucmVkdWNlKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LGUse3ZhbHVlOmlbZV0sZW51bWVyYWJsZTohMH0pfSx7fSl9KGk9Pntjb25zdCB0PXtydW4oZSxuKXtjb25zdCBzPW5ldyBGdW5jdGlvbigicmV0dXJuICgiK2UrIikuYXBwbHkobnVsbCwgYXJndW1lbnRzKTsiKTtyZXR1cm4gcy5hcHBseShzLG4pfSxtZXRob2RzKCl7cmV0dXJuIE9iamVjdC5rZXlzKHQpfX07YWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZT0+X2codm9pZCAwLFtlXSxmdW5jdGlvbiooe2RhdGE6bn0pe3RyeXtjb25zdCBzPXRbbi5tZXRob2RdO2lmKHMpe2NvbnN0IHI9eWllbGQgcy5hcHBseShzLG4ucGFyYW1zKTtyLnRyYW5zZmVyJiZyLm1lc3NhZ2U/cG9zdE1lc3NhZ2Uoe2lkOm4uaWQscmVzdWx0OnIubWVzc2FnZSxlcnJvcjpudWxsfSxyLnRyYW5zZmVyKTpwb3N0TWVzc2FnZSh7aWQ6bi5pZCxyZXN1bHQ6cixlcnJvcjpudWxsfSl9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbWV0aG9kICInK24ubWV0aG9kKyciJyl9Y2F0Y2gocyl7cG9zdE1lc3NhZ2Uoe2lkOm4uaWQscmVzdWx0Om51bGwsZXJyb3I6dmcocyl9KX19KSksT2JqZWN0LmtleXMoaSkuZm9yRWFjaChlPT57dFtlXT1pW2VdfSkscG9zdE1lc3NhZ2UoInJlYWR5Iil9KSh7ZXh0cnVkZVBvbHlnb246Y3ksbGluZTp1eSxsaW5lMjpkeSxjb25pY1BvbHlnb246QWcsY29uaWNMaW5lOlNnfSl9KSgpOwo=",N=g=>Uint8Array.from(atob(g),t=>t.charCodeAt(0)),R=typeof window!="undefined"&&window.Blob&&new Blob([N(o)],{type:"text/javascript;charset=utf-8"});function T(g){let t;try{if(t=R&&(window.URL||window.webkitURL).createObjectURL(R),!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 z=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 I{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),E=this.pool,{err:O,res:ve}=yield E.exec(t,[W({},m)],void 0,!0);if(O)throw O;const Pe=z(ve);if(Object.assign(Pe.userData,W({},C)),w&&(yield w(Pe)),v){const{cacheObj:Ne}=this;Ne[v]||(Ne[v]={[_]:[]}),Ne[v][_].push(W({attributes:ve},C))}return Pe})}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:E}=w,O=x(w,["attributes"]),ve=z(E);return Object.assign(ve.userData,W({},O)),ve}):[]}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 E=new Mesh(t,createAreaLightMaterial(50));E.position.set(-16.116,14.37,8.208),E.scale.set(.1,2.428,2.739),this.add(E);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 ve=new Mesh(t,createAreaLightMaterial(17));ve.position.set(14.904,12.198,-1.832),ve.scale.set(.15,4.265,6.331),this.add(ve);const Pe=new Mesh(t,createAreaLightMaterial(43));Pe.position.set(-.462,8.89,14.52),Pe.scale.set(4.38,5.441,.088),this.add(Pe);const Ne=new Mesh(t,createAreaLightMaterial(20));Ne.position.set(3.235,11.486,-12.541),Ne.scale.set(2.5,2,.1),this.add(Ne);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}class Event{constructor(){L0(this,"event",new events.EventEmitter);L0(this,"eventHandlers",{});L0(this,"on",this.event.on.bind(this.event));L0(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);L0(this,"container");L0(this,"pencil");L0(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 H0(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,E=!1,O=250){return H0(this,null,function*(){this.pencil.controls.smoothTime=O/1e3,yield this.pencil.controls.setLookAt(r,m,v,C,_,w,E),this.pencil.controls.smoothTime=250/1e3})}truck(r,m,v=!1,C=250){return H0(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 H0(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 H0(this,null,function*(){this.pencil.controls.smoothTime=v/1e3;const C=this.pencil.controls.azimuthAngle,_=this.pencil.controls.polarAngle,w=this.pencil.controls.distance,E=this.pencil.cameraTarget.clone(),O=r.azimuthAngle||C,ve=r.polarAngle||_,Pe=r.distance||w,Ne=r.target||E;yield Promise.all([this.pencil.controls.moveTo(Ne.x,Ne.y,Ne.z,m),this.pencil.controls.dollyTo(Pe,m),this.pencil.controls.rotateTo(C+this.absoluteAngle(O,C),_+this.absoluteAngle(ve,_),m)]),this.pencil.controls.smoothTime=250/1e3})}paddingInCssPixel(r,m,v,C,_,w){const{camera:E,controls:O}=this.pencil,ve=E.fov*MathUtils.DEG2RAD,Pe=this.pencil.getSize().height,{size:Ne}=r.getSize(),Ae=Ne.x,Fe=Ne.y,ct=Ne.z;let Oe=O.getDistanceToFitBox(Ae,Fe,ct),ke=0,je=0,at=0,xt=0;for(let Gt=0;Gt<10;Gt++){const Lt=Oe-ct*.5,Wt=2*Math.tan(ve*.5)*Math.abs(Lt)/Pe;ke=m*Wt,je=C*Wt,at=_*Wt,xt=v*Wt,Oe=O.getDistanceToFitBox(Ae+at+xt,Fe+ke+je,ct)}return O.fitToBox(r.object3d,w,{paddingLeft:at,paddingRight:xt,paddingBottom:je,paddingTop:ke})}resetCamera(r=!1,m=250){return H0(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:E,height:O}=this.container.getBoundingClientRect(),ve=(r.clientX-_)/E*2-1,Pe=-((r.clientY-w)/O)*2+1,Ne=this.pencil.cameraPositon.clone();v.set(ve,Pe,.5),v.unproject(this.pencil.camera),v.sub(Ne).normalize();const Ae=(m-Ne.z)/v.z;return C.copy(Ne).add(v.multiplyScalar(Ae)),C}dispose(){super.dispose(),this.cameraState={}}}class Command{constructor(t){L0(this,"id");L0(this,"updatable");L0(this,"type");L0(this,"name");L0(this,"editor");L0(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}}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)}}}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 re$1;t.track(this.oldMap),t.dispose()}this.newMap&&(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 Te$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 Te$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){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,this.newMap=parseTexture(t.newMap)}fixJSON(){const t=this.json;t&&t.oldMap&&delete t.oldMap}}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;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),setTimeout(()=>{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)}}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}}class SetMaterialMapVector extends Command{constructor(t,r,m,v,C,_="repeat"){var w,E,O,ve;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 Te$1&&m==="map"&&_==="repeat"?this.oldValue=this.material.repeat.toArray():((E=(w=this.material)==null?void 0:w[m])==null?void 0:E[_])instanceof Vector2?this.oldValue=this.material[m][_].toArray():typeof((ve=(O=this.material)==null?void 0:O[m])==null?void 0:ve[_])!="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 Te$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 Te$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")}}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;t.isCamera&&["fov","left","right","top","bottom","near","far"].includes(this.attributeName)&&t.updateProjectionMatrix(),setTimeout(()=>{(this.attributeName==="name"||this.attributeName==="prefab"||this.attributeName==="visible"||this.attributeName==="keepCamera")&&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);L0(this,"visType");L0(this,"visOptions");this.type="AddVis",this.visType=m,this.visOptions=v,m!==void 0&&(this.name=`Add Vis: ${m}`)}execute(){return H0(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);L0(this,"objectType");L0(this,"objectOptions");L0(this,"obj");L0(this,"addObjectUuid");this.type="AddObject",this.objectType=m,this.objectOptions=v,m!==void 0&&(this.name=`Add Object: ${m}`)}execute(){return H0(this,null,function*(){var m;const r=this.editor.viewport.vis;this.obj=yield r.lead.draw(this.objectType,Bi(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);L0(this,"object");L0(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 H0(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);L0(this,"object");L0(this,"copyObject",null);L0(this,"copyObjectUuid");this.type="CopyObject",this.name="Copy Object",this.object=m}execute(){return H0(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 H0(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}fromJSON(r){super.fromJSON(r),this.object=this.editor.baseObjectByUuid(r.objectUuid),this.copyObjectUuid=r.copyObjectUuid}fixJSON(){const r=this.json;r&&!r.copyObjectUuid&&(r.copyObjectUuid=this.copyObjectUuid)}}class AddMaterial extends Command{constructor(r,m){super(r);L0(this,"materialType");L0(this,"addObjectUuid");this.type="AddMaterial",this.name="Add Material",this.materialType=m}execute(){return H0(this,null,function*(){this.addObjectUuid=`material_${this.id}`;const r=this.editor.pencil.mList,m=this.materialType==="MeshLineMaterial"?new Te$1({color:new Color$1(16777215),lineWidth:1,sizeAttenuation:0}):new THREE[this.materialType];m.name=`材质_${this.id}`,r.add(this.addObjectUuid,m)})}undo(){return H0(this,null,function*(){this.editor.pencil.mList.remove(this.addObjectUuid)})}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);L0(this,"objectUuid");L0(this,"copyObjectUuid");this.type="CopyMaterial",this.name="Copy Material",this.objectUuid=m}execute(){return H0(this,null,function*(){this.copyObjectUuid=`material_${this.id}`,this.editor.pencil.mList.copy(this.objectUuid,this.copyObjectUuid,{name:`材质_${this.id}`})})}undo(){return H0(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);L0(this,"objectUuid");L0(this,"material");this.type="RemoveMaterial",this.name="Remove Material",this.objectUuid=m}execute(){return H0(this,null,function*(){const r=this.editor.pencil.mList;this.material=r.get(this.objectUuid),r.remove(this.objectUuid)})}undo(){return H0(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);L0(this,"object");L0(this,"oldValue");L0(this,"newValue");L0(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 H0(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 H0(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);L0(this,"attributeName");L0(this,"newValue");L0(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 H0(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 H0(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;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,E,O,ve;for(let Pe=0;Pe<C;Pe=Pe+3)ve=r[Pe]<<16|r[Pe+1]<<8|r[Pe+2],_=(ve&16515072)>>18,w=(ve&258048)>>12,E=(ve&4032)>>6,O=ve&63,t+=encodings[_]+encodings[w]+encodings[E]+encodings[O];return v===1?(ve=r[C],_=(ve&252)>>2,w=(ve&3)<<4,t+=encodings[_]+encodings[w]):v===2&&(ve=r[C]<<8|r[C+1],_=(ve&64512)>>10,w=(ve&1008)>>4,E=(ve&15)<<2,t+=encodings[_]+encodings[w]+encodings[E]),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,E,O,ve;for(let Pe=0,Ne=0;Pe<m;Pe+=4,Ne+=3)w=charCodeToNumber(g.charCodeAt(Pe)),E=charCodeToNumber(g.charCodeAt(Pe+1)),O=charCodeToNumber(g.charCodeAt(Pe+2)),ve=charCodeToNumber(g.charCodeAt(Pe+3)),C=(w<<18)+(E<<12)+(O<<6)+ve,_.set([(C&16711680)>>16,(C&65280)>>8,C&255],Ne);return t===2?(w=charCodeToNumber(g.charCodeAt(m)),E=charCodeToNumber(g.charCodeAt(m+1)),C=(w<<2)+(E>>4),_.set([C&255],r)):t===3&&(w=charCodeToNumber(g.charCodeAt(m)),E=charCodeToNumber(g.charCodeAt(m+1)),O=charCodeToNumber(g.charCodeAt(m+2)),C=(w<<10)+(E<<4)+(O>>2),_.set([(C&65280)>>8,C&255],r)),_.buffer}class History{constructor(t){L0(this,"editor");L0(this,"undos");L0(this,"redos");L0(this,"lastCmdTime");L0(this,"idCounter");L0(this,"historyDisabled");this.editor=t,this.undos=[],this.redos=[],this.lastCmdTime=Date.now(),this.idCounter=0,this.historyDisabled=!1}execute(t,r){return H0(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(Bi(Q0({},_),{[w]:Bi(Q0({},_[w]),{images:_[w].images.map(E=>{var Pe;if(typeof E.url!="string")if(((Pe=E.url)==null?void 0:Pe.type)==="Uint16Array"){const Ne=encodeArrayBufferToUrlSafeBase64(new Uint16Array(E.url.data).buffer);E._url=Q0({},E.url),delete E._url.data,E.url=Ne}else return Q0({},E);const O=t.i.findIndex(Ne=>Ne===E.url);let ve=E.url;return O===-1?(t.i.push(E.url),ve=`$rp-${t.i.length-1}`):ve=`$rp-${O}`,Bi(Q0({},E),{url:ve})})})}))}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 E=t.u[w];if(m!=null&&m.length&&((v=E.newMap)!=null&&v.images||(C=E.newMaterial)!=null&&C.images)){const ve=(_=E.newMap)!=null&&_.images?"newMap":"newMaterial";E[ve].images.forEach(Pe=>{if(typeof Pe.url=="string"&&Pe.url.startsWith("$rp-")){const Ne=parseInt(Pe.url.replace("$rp-",""));Pe._url?(Pe.url=Bi(Q0({},Pe._url),{data:decodeUrlSafeBase64ToArrayBuffer(m[Ne])}),delete Pe._url):Pe.url=m[Ne],this.editor.playing||console.log("$rp-",Ne,E)}})}if(E.id<=r){console.error("历史记录id错误");continue}if(E.type==="SetOption"||!E.type)continue;E.type.endsWith("Command")&&(E.type=E.type.replace("Command",""));const O=new Commands[E.type](this.editor);O.json=E,O.id=E.id,O.name=E.name,this.undos.push(O),this.idCounter=E.id>this.idCounter?E.id:this.idCounter,r=E.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=()=>H0(this,null,function*(){const E=performance.now();for(;v.length>0&&performance.now()-E<t;){if(this.editor._dispose){m("dispose");return}const O=v.shift(),ve=this.editor.hooks.events.beforeExecuteUndo.length?this.editor.hooks.dispatch("beforeExecuteUndo",O):O;ve&&(yield this.executeUndo(ve)),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 H0(this,null,function*(){t.fromJSON(t.json);try{!["AddObject","CopyMaterial","RemoveMaterial"].includes(t.json.type)&&t.json.objectUuid&&!t.object||(yield t.execute(),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 Viewport{constructor(t,r){L0(this,"editor");L0(this,"vis");L0(this,"extendsOptions",{});L0(this,"cameraState",{});L0(this,"delLoadObj");L0(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 H0(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 H0(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,E;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;(E=this.vis)==null||E.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,E)=>{this.editor.execute(new SetPosition(this.editor,_,w,E))}),(v=t.transformController)==null||v.event.on("rotate",(_,w,E)=>{this.editor.execute(new SetRotation(this.editor,_,w,E))}),(C=t.transformController)==null||C.event.on("scale",(_,w,E)=>{this.editor.execute(new SetScale(this.editor,_,w,E))})}addObj(m){return H0(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 H0(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 H0(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 H0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new AddMaterial(this.editor,t))})}removeMListMaterial(t){return H0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new RemoveMaterial(this.editor,t))})}copyMListMaterial(t){return H0(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()}}const 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};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:E}=t.h.u[0].visOptions;t.h.u[0].visOptions=Bi(Q0({},t.h.u[0].visOptions),{geojsonMap:{[w]:_},extrudeLineGeojsonMap:{[w]:E}}),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:E}=t.h.u[0].visOptions;t.h.u[0].visOptions=Bi(Q0({},t.h.u[0].visOptions),{bboxMap:w||{[E]:_}}),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=Bi(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,t.v.eo.parentBgTopSegments=400)}},{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,E)=>{var O,ve,Pe;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 Ne=w.attributeName.split(":::caId.")[1],Ae=t.h.u[0].visOptions.adcode;t.h.u[E]=[{id:w.id,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`extrudePolygon#${Ae}-${Ne}`,copyObjectUuid:`ExtrudePolygon#${Ae}-${Ne}_${w.id}`},{id:w.id+.1,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`line#${Ae}-${Ne}`,copyObjectUuid:`line#${Ae}-${Ne}_${w.id+.1}`}],_[Ne]=w.id}else if((ve=w.objectUuid)!=null&&ve.startsWith("planeCopyExtrudePolygon")){const Ne=w.objectUuid.split("CopyExtrudePolygon")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`extrudePolygon#${Ae}-${Ne}_${_[Ne]}`})}else if((Pe=w.objectUuid)!=null&&Pe.startsWith("planeCopyLine")){const Ne=w.objectUuid.split("CopyLine")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`line#${Ae}-${Ne}_${_[Ne]+.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 Hooks{constructor(t){L0(this,"editor");L0(this,"events",{beforeSetVisOptions:[],beforeExecuteUndo:[],afterExecuteUndo:[],beforeShow:[],afterShow:[],beforeFromJSON:[],afterFromJSON:[],errorFromJSON:[]});L0(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 Config{constructor(t){L0(this,"editor");L0(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}}}const 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"),E=_.stream().pipeThrough(w);return new Response(E)}):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};class Editor{constructor(t){L0(this,"selected",null);L0(this,"playing",!0);L0(this,"currentMaterialSlot",0);L0(this,"events",new events.EventEmitter);L0(this,"history");L0(this,"viewport");L0(this,"hooks");L0(this,"config");L0(this,"pencil");L0(this,"on",this.events.on.bind(this.events));L0(this,"emit",this.events.emit.bind(this.events));L0(this,"options");L0(this,"selectOption",[]);L0(this,"mListOptions",[]);L0(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 Te$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 Fe=v.options.type;C.unshift({key:v.key.replace(Fe,Fe+"Target"),object3d:v.object3d.target,userData:{disabledC:!0,disabledR:!0},children:[]})}if(v.object3d.isDirectionalLight){const Fe=v.options.type;C.unshift({key:v.key.replace(Fe,Fe+"Shadow"),object3d:v.object3d.shadow.camera,userData:{disabledC:!0,disabledR:!0},children:[]})}const w=C.length>0?r(C):[],E=v.object3d.isGroup,O=E||["@Scene","@Camera"].includes(v.key)||v.userData.disabledC||v.key.includes("__c__"),ve=["@Scene","@Camera"].includes(v.key)||v.userData.disabledR||v.key.includes("__c__");if(w.length===0&&E)return null;const Pe=v.key.replace(v.key[0],v.key[0].toLowerCase()),Ne=["@Scene","@Camera"].includes(v.key)||v.userData.disabledTC,Ae=["@Scene","@Camera"].includes(v.key);return{key:Pe==="@Scene"?"scene":Pe==="@Camera"?"camera":Pe,name:v.object3d.name,object:v.object3d,visible:Ae?!0:v.object3d.visible,useMaterialType:v.useMaterialType,disabledC:O,disabledR:ve,disabledTC:Ne,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 H0(this,null,function*(){yield this.history.execute(t,r)})}fromJSON(t,r){return H0(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 E=this.options.assetsPrefix+t;console.time("vis-core:time.json-fetch");const{res:O,err:ve}=yield jsonFetch(E);if(console.timeEnd("vis-core:time.json-fetch"),ve)throw new Error("fromJSON error:"+ve);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 E=accessToken.getInfo();if(!E||!E.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 E=parseTexture(w.v.bg.texture);E.colorSpace=SRGBColorSpace,this.viewport.vis.pencil.scene.background=E}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 E;(E=this.viewport.vis)==null||E.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 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){L0(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(){L0(this,"rawRenderer");L0(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}}},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 E=getScale(r);if(E!==void 0){m=E;break}if(r=r.parentElement,r===document.body){r=null;break}}if(!r)return null;const v=E=>{const O=getScale(r)||1;m!==O&&(m=O,t(O,E))},C=E=>{E.propertyName==="transform"&&v("transitionEnd")},_=new MutationObserver(E=>{for(const O of E)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)},_}const IS_DEV=!1;class Base extends Camera{constructor(r){var m;super();L0(this,"playing",!0);L0(this,"leftTruck",!0);L0(this,"options");L0(this,"showState",!1);L0(this,"settings",{});L0(this,"delLoadArr");L0(this,"extendsOptions",{});L0(this,"leadObjs",objs$3);L0(this,"lead");L0(this,"mList");L0(this,"workerOnce",!0);L0(this,"tier0",!1);L0(this,"pmremGenerator",null);L0(this,"re",null);L0(this,"roomEnvMap");L0(this,"visName");L0(this,"editor");L0(this,"publicDir",{});L0(this,"_baseObjectByUuid");L0(this,"_objectByUuid");L0(this,"observeScale",null);L0(this,"sceneActive",-1);L0(this,"initSettingsObj");L0(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(Bi(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 H0(this,null,function*(){})}initVis(...r){return H0(this,null,function*(){})}init(...r){return H0(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 H0(this,null,function*(){var v,C,_,w,E,O,ve,Pe;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=(E=r.camera)==null?void 0:E.far)!=null?O:1e3,up:(Pe=(ve=r.camera)==null?void 0:ve.up)!=null?Pe: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 Ne=new ot(Q0(Bi(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 ct=()=>{this.observeScale||(this.observeScale=observeScale(this.container,(Oe,ke)=>{Ne.setDevicePixelRatio(window.devicePixelRatio*Oe)}))};ct(),Ne.event.on("resize",()=>{ct()})}this.pencil=Ne,this.sceneActive=1;const Ae=Ne.composerController.ssaoPass;Ae&&(Ae.enabled=!1);const Fe=new I({dbName:this.visName,cacheVersion:version});Ne.use(Fe),this.playing||(window.vis=this,window.pencil=Ne)}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",(...Ne)=>{this.showState!==!0&&this.emit("loaderProgress",...Ne)}),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,E,O,ve,Pe,Ne;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:(E=(w=this.pencil.composerController)==null?void 0:w.bloomPass)==null?void 0:E.threshold,bloomRadius:(ve=(O=this.pencil.composerController)==null?void 0:O.bloomPass)==null?void 0:ve.radius,bloomStrength:(Ne=(Pe=this.pencil.composerController)==null?void 0:Pe.bloomPass)==null?void 0:Ne.strength},{set:(Ae,Fe,ct)=>(Fe==="shadowMapEnabled"||Fe==="shadowMapType"?(Fe==="shadowMapEnabled"?this.pencil.renderer.shadowMap.enabled=ct:Fe==="shadowMapType"&&(this.pencil.renderer.shadowMap.type=ct),this.pencil.scene.traverse(Oe=>{const ke=Oe;if(ke.receiveShadow&&ke.material){const je=ke.material;Array.isArray(je)?je.forEach(at=>{at.needsUpdate=!0}):je.needsUpdate=!0}})):Fe==="backgroundType"?ct==="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):Fe==="backgroundColor"?r.scene.background=new Color$1(ct):Fe==="backgroundTexture"?r.scene.background=ct:Fe==="bloomThreshold"?r.composerController.bloomPass&&(r.composerController.bloomPass.threshold=ct):Fe==="bloomRadius"?r.composerController.bloomPass&&(r.composerController.bloomPass.radius=ct):Fe==="bloomStrength"&&r.composerController.bloomPass&&(r.composerController.bloomPass.strength=ct),Reflect.set(Ae,Fe,ct))})}initBaseObjectUserData(r){const m=Bi(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,E,O)=>(E==="bloom"?O?r.enableBloom():r.disableBloom():E==="prefab"?(r.prefab=O,O?this.lead.prefabGroup.attach(r):this.lead.group.attach(r)):E==="animationDuration"&&v?r.animateIn({duration:O}):E==="animationDuration"&&(C||_)&&(C?[r]:r.children).forEach(Pe=>{Pe.material.userData.tween&&(Pe.material.userData.tween.stop(),remove(Pe.material.userData.tween),Pe.material.userData.tween=null),O&&(Pe.material.uniforms.offset.value.x=1,Pe.material.uniforms.offsetLoop.value=1,Pe.animate({duration:O,repeat:1/0,lineLoop:!0,startShow:!0}))}),Reflect.set(w,E,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(Bi(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(E=>(Reflect.set(m,_,E),E)):w}})}handleSetting(r,m){return H0(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 H0(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 H0(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(),E=(C.x*.5+.5)*_,O=(C.y*-.5+.5)*w;return{x:E,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()}}L0(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 E=m[w];if(contains(_,E))v.features.push(E);else if(contains(E,_))_.properties=E.properties,v.features.push(_);else{const O=turf.intersect(_,E);O&&(O.properties=E.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();L0(this,"options");L0(this,"building",{});L0(this,"outJson",new Map);L0(this,"worldPositionZ",{value:0});this.options=Q0({},r)}create(){return H0(this,null,function*(){const{json:r,projection:m,cacheKey:v,meters:C,grey:_,clip:w}=this.options,E=this.pencil.mList,O=this.pencil.getPlugin("worker"),ve=this.pencil.lead,Pe=_?"-grey":"";this.createGroup();const Ne=E.getMultiple("building"+Pe);let Ae=v?yield O.getCachedGeometry({cacheKey:v}):[];if(Ae.length)w&&this.outJson.set(1,!0);else{let Fe;w&&(Fe=getBoxMultiPoly(w));const ct={};(r.features||r).forEach(ke=>{const je=typeof ke.properties.h=="string"?ke.properties.h.split(".")[1]:0,at=Number(ke.properties.h)|0;ct[je]||(ct[je]={}),ct[je][at]||(ct[je][at]=[]),Fe?Fe.some(Gt=>{ke.geometry.coordinates[1]&&console.log(ke.geometry.coordinates[1]);const Lt=turf.polygon(ke.geometry.coordinates[0]);return turf.booleanContains(Gt,Lt)?(ct[je][at].push(ke),!0):!1})||this.outJson.set(ke,!1):ct[je][at].push(ke)});const Oe=Object.keys(ct).map(ke=>{const je=ct[ke];return Object.keys(je).map(at=>{const xt=je[at];return{z:+ke,h:+at,coordinatesArr:xt.map(Gt=>Gt.geometry.type==="Polygon"?Gt.geometry.coordinates[0]:Gt.geometry.coordinates[0][0])}})}).flat().filter(ke=>ke.coordinatesArr.length);Ae=yield Promise.all(Oe.map(ke=>{const{h:je,z:at,coordinatesArr:xt}=ke,Gt=+je<=20?+je/18:+je<=60?+je/27:+je/12;return O.geoGeometry("extrudePolygon",{cacheKey:v,userData:{z:at,h:je},mesaage:{coordinatesArr:xt,projection:m,useGroups:2,depth:[Number(je)*(C||1)],hasBottom:!1,sideRepeat:Gt}})}))}yield Promise.all(Ae.map(Fe=>H0(this,null,function*(){const{h:ct,z:Oe}=Fe.userData,ke=ct+Oe,je=ke<=20?"20":ke<=60?"60":"max";let at=this.options.material;at||(at=[Ne[je+"Top"],Ne[je+"Side"]]);const xt=yield ve.draw("ExtrudePolygon",{key:`$p:-${ct}-${Oe}`,geometry:Fe,material:at},this);this.options.grey||(xt.object3d.castShadow=!0),this.building[ct]||(this.building[ct]=[]),this.building[ct].push(xt),xt.position.z=Number(Oe)*(C||1)}))),this.options.sideGradient&&this.sideGradient(),this.object3d.name="建筑",_||this.lead.updateBaseObjectKey(this,`building${Pe?"-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},Gs=new MeshBasicMaterial({color:"black"}),Xs=new PointsMaterial({color:"black",sizeAttenuation:!1}),qs=new PointsMaterial({color:"black",sizeAttenuation:!0}),Qs=new SpriteMaterial({color:"black",sizeAttenuation:!0}),Js=new SpriteMaterial({color:"black",sizeAttenuation:!1}),ei=new Te$1({color:"black",sizeAttenuation:0,lineWidth:0}),ti={kernelRadius:8,minDistance:.005,maxDistance:.1},si={threshold:0,strength:.4,radius:.1,bloomAlphaType:0},ii={multisampling:4,premultiplieAlpha:!1};class ri{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:E}=_.capabilities,O=_.getDrawingBufferSize(new Vector2),ve=new WebGLRenderTarget(O.width,O.height,{samples:Math.min(w,E),type:HalfFloatType}),Pe=new EffectComposer(_,ve),Ne=this.getSize();Pe.setSize(Ne.width,Ne.height);const Ae=new RenderPass(m.scene,v.camera);Pe.addPass(Ae),this.scene=m.scene,this.camera=v.camera,this.finalComposer=Pe,this.renderPass=Ae,v.event.on("pageChange",Fe=>{this.changeCamera(Fe)}),m.event.on("pageChange",Fe=>{this.changeScene(Fe)})}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 Ks;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,E=new SSAOPass(r,m,_,w);E.kernelRadius=t.kernelRadius,E.minDistance=t.minDistance,E.maxDistance=t.maxDistance,this.ssaoPass=E,this.finalComposer.addPass(E)}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 E=new EffectComposer(r);E.renderToScreen=!1,E.addPass(this.renderPass),E.addPass(w),this.bloomComposer=E;const O=$s(E);O.uniforms.bloomAlphaType.value=_,this.bloomComposer=E,this.finalComposer.addPass(O),this.mixPass=O,this.bloomLayer.set(De)}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(De)):(this.bloomSelection.delete(m),v.layers.disable(De)))}),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,E=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=Qs:w.material=Js:_.material instanceof Te$1?_.material=ei:E.isPoints?E.material.sizeAttenuation?E.material=qs:E.material=Xs:_.material=Gs)})}),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 it 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,E=>{let O=E;const ve=t.split(".").pop(),Pe=this.options.type==="image"?`image/${ve||"png"}`:`video/${ve||"mp4"}`;O=O.slice(0,E.size,Pe);const Ne=()=>{_.removeEventListener("load",Ae,!1),_.removeEventListener("error",Fe,!1)},Ae=()=>{Ne(),C.needsUpdate=!0,r&&r(C)},Fe=Oe=>{Ne(),v&&v(Oe),this.manager.itemError(t),this.manager.itemEnd(t)};_.addEventListener("load",Ae,!1),_.addEventListener("error",Fe,!1);const ct=window.URL.createObjectURL(O);_.src=ct},m,v),C}}class oi 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=_,E=new DecompressionStream("gzip"),O=w.stream().pipeThrough(E);new Response(O).json().then(ve=>{r==null||r(ve)}).catch(ve=>{v==null||v(ve)})},m,v)}}const ni={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 ai{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(ni))if(C.includes(m))return v}getLoader(t,r){if(t==="images")return this.textureLoader||(this.textureLoader=new it(this.loadingManager),this.options.prefix&&this.textureLoader.setPath(this.options.prefix)),this.textureLoader;if(t==="media")return this.videoTextureLoader||(this.videoTextureLoader=new it(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 oi(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 E=this.getLoader(C,r);try{const O=yield E.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$1({texture:O});const ve=(v=r==null?void 0:r.anisotropy)!=null?v:this.options.anisotropy;O.anisotropy=ve}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(E=>{if(E){const O=this.getSrcByAsset(E,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 li={prefix:""};class hi extends ee{get loader(){return this.controller}constructor(t){super(),this.options=t}addLoader(t,r){const{loaderParams:m}=this.options,v=new ai(te(U({},m),{scene:t}));return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}function rt(g){let t=!1,r=[];return function(...m){r=m,t||(t=!0,requestAnimationFrame(()=>{t=!1,g(...r)}))}}class ci{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,E=[];if(this.pickFunctionsMap.forEach(Ae=>{w.has(Ae.type)&&E.push(te(U({},Ae),{objArr:Ae.objArr instanceof Function?Ae.objArr():Ae.objArr}))}),E.length===0)return;this.activeObjects.clear(),this.objCallbackMap.clear(),this.activeObject=null;const O=this.objCallbackMap;for(const Ae of E)for(const Fe of Ae.objArr){if(!Fe.object3d||!Fe.visibleWithAncestors)continue;O.has(Fe)||O.set(Fe,new Map);const ct=O.get(Fe);ct.has(Ae.type)||ct.set(Ae.type,[]),ct.get(Ae.type).push(Ae.cb)}if(O.size===0)return;const ve=[...O.keys()].map(Ae=>Ae.object3d),Pe=(_=this.pencil.pick(C,ve,!0))==null?void 0:_.intersects;if(!Pe||Pe.length===0)t==="down"?this.handleDownOutside(C):t==="move"&&this.handleLeaveEvents(C);else{const Ae=Pe[0];this.processIntersection(Ae,C,t)}const Ne=this.prevActiveObjects;this.prevActiveObjects=this.activeObjects,this.activeObjects=Ne,this.activeObjects.clear()};this.domElement.addEventListener(`pointer${t}`,rt(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 E=v.get(w);if(E)if(r==="move"){const O=E.get("enter");if(O&&!this.prevActiveObjects.has(w))for(const Pe of O)Pe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const ve=E.get("move");if(ve)for(const Pe of ve)Pe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m})}else{const O=E.get("down");if(O)for(const Pe of O)Pe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});const ve=E.get("click");if(ve){const Pe=Ne=>{Ne.preventDefault();const Ae=5;if(!C&&Math.abs(Ne.clientX-t.clientX)<=Ae&&Math.abs(Ne.clientY-t.clientY)<=Ae)for(const Fe of ve)Fe({baseObject:w,realBaseObject:this.activeObject,mouseEvent:t,sp:_,intersectionIndex:m});this.domElement.removeEventListener("pointerup",Pe)};this.domElement.addEventListener("pointerup",Pe)}}}}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 E=w;E.element.style.pointerEvents="auto";const O=Pe=>{this.enabled&&(Pe.preventDefault(),m({baseObject:E,mouseEvent:Pe}))},ve=`pointer${r}`;E.element.addEventListener(ve,rt(O),!1),_.push({arr:E,type:ve,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 di extends ci{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),this.pencil.options.mList&&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 E=this.objectNamesToFactories.get(t);if(E){r||(r={}),r.target===void 0&&(r.target=m);const O=r.target,ve=(v=r.onTop)!=null?v:0,Pe=(C=r.prefab)!=null?C:!1,Ne=(_=r.create)!=null?_:!0,Ae=new E().create(r);let Fe;return O===null?Fe=null:typeof O=="string"?Fe=this.objects.get(O):(w=O==null?void 0:O.objectType)!=null&&w.startsWith("BaseObject")||O?Fe=O:Pe?Fe=this.prefabGroup:Fe=this.group,Ne===!1?Ae.create=()=>{}:Ne!==!0&&(Ae.create=()=>{Ne(Ae)}),Ae.pencil=this.pencil,Ae.lead=this,Ae.mList=this.mList,Ae.prefab=Pe,Ae.objectType=`BaseObject#${t}`,Ae.objectOptions=r,this.setBaseObjectKey(Ae,r.key?`$t:#${r.key}`:"$t:",Fe==null?void 0:Fe.key),this.objectsPm.set(Ae,this.addBaseObject(Ae,Fe,ve)),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,E]of this.objects.entries())if(E===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,E)=>{w.key.includes("__c__")&&this.updateBaseObjectKey(w,`${_}__c__${E}`)}),_}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.pencil.options.mList&&(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 mi extends ee{get lead(){return this.controller}constructor(t){super(),this.options=t}addLead(t,r,m){const{pencil:v}=this.options,C=new di(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 pi{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 E=v.material;return v.material=_,this.materials.set(t,_),this.disposeMaterial(E),this.syncChangeMaterial(E,_),!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),E=_.clone();m[w]=E;const O=`${r}#${w}`;this.add(O,E)}return m}disposeMaterial(t){if(!t)return;const r=new re$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:(E,O,ve)=>{if(typeof O=="string"&&!isNaN(Number(O))){const Pe=Number(O);if(Pe>=0&&Pe<E.length){const Ne=E[Pe];return this.rmBaseObjectMap(t,Ne),E[Pe]=ve,ve&&this.addBaseObjectMap(t),!0}}return E[O]=ve,!0}});return Object.defineProperty(w,"__isProxy",{value:!0,enumerable:!1}),w};t.materialList&&(t.materialList=new Proxy(t.materialList,{set:(_,w,E)=>{if(typeof w=="string"){const O=_[w];return this.rmBaseObjectMap(t,O),_[w]=E,E&&this.addBaseObjectMap(t),!0}return _[w]=E,!0},get:(_,w)=>{if(typeof w=="string"&&_[w]){const E=_[w];if(Array.isArray(E)){const O=m(E);return O!==E&&(_[w]=O),O}return E}return _[w]},deleteProperty:(_,w)=>{if(typeof w=="string"&&_[w]){const E=_[w];this.rmBaseObjectMap(t,E)}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 E=m(w);return E!==w&&(r[C]=E),E}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 E=v.materialList[w];if(Array.isArray(E)){const O=E.indexOf(t);O!==-1&&(E[O]=r)}else E===t&&(v.materialList[w]=r)})})}dispose(){const t=new re$1;t.track([...this.materials.values()]),t.dispose(),this.materials.clear(),this.fixBaseObjects.clear(),this.materialBaseObjectMap.clear()}}class fi extends ee{get mList(){return this.controller}constructor(t){super(),this.options=t}addMList(t,r){const{pencil:m}=this.options,v=new pi(m);return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}const _e=class Pn{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=rs(Pn.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:E}=this.options,{width:O,height:ve}=this.getSize(),Pe=m?new Ds({width:O,height:ve,renderer:m.WebGPURenderer,rendererParams:Rs}):new Ms({width:O,height:ve,rendererParams:te(U({},_),{antialias:!1})}),Ne=new zs({width:O,height:ve}),Ae=new Fs({}),Fe=new js({controlsParams:{domElement:(t=w==null?void 0:w.domElement)!=null?t:Pe.renderer.domElement}}),ct=new hi({loaderParams:U({anisotropy:Pe.renderer.capabilities.getMaxAnisotropy()},E)}),Oe=new fi({pencil:this}),ke=new mi({pencil:this});this.sceneController=Ae,this.cameraController=Ne,this.controlsController=Fe,this.rendererController=Pe,this.loaderController=ct,this.mListController=Oe,this.leadController=ke;const je=this.addPage({sceneOptions:this.options.scene,cameraOptions:this.options.camera});if(this.showPage(je),v){const at=new Ns({container:r,sceneController:Ae,cameraController:Ne});at.add(Ae.scene),this.helperController=at,C&&at.addViewHelper()}r.appendChild(Pe.renderer.domElement)}initComposer(){const{bloom:t,bloomParams:r,ssao:m,ssaoParams:v,composer:C}=this.options,_=new ri({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 Zs(t);r&&_.addRenderer("css2d",v),m&&_.addRenderer("css3d",C),this.cssRendererController=_}}initTransformControls(){const t=new Is({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:E}=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),E.setSize(t,r),this.installPlugins.forEach(ve=>{var Pe;(Pe=ve.setSize)==null||Pe.call(ve,t,r)}),this.viewPadding.some(ve=>ve!==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(E=>E!==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,E=_.getBoundingClientRect();if(w.x=(t.clientX-E.left)/(E.right-E.left)*2-1,w.y=-((t.clientY-E.top)/(E.bottom-E.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.timer.update(),update();const w=this.timer.getDelta(),E=this.timer.getElapsed();this.controlsController.update(w,E),this.leadController.update(w,E),this.installPlugins.forEach(O=>{var ve;(ve=O.update)==null||ve.call(O,w,E)}),(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:E})}start(){window.cancelAnimationFrame(this.TweenRaf),this.renderer.setAnimationLoop(this.render.bind(this)),this.event.emit("start")}stop(){this.tweenUpdateRaf(),this.renderer.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,E,O,ve,Pe,Ne,Ae,Fe;this.stop(),this.timer.dispose(),removeAll(),this.event.removeAllListeners(),(t=this.resizeObserver)==null||t.unobserve(this.options.container),this.installPlugins.forEach(ct=>{var Oe;(Oe=ct.dispose)==null||Oe.call(ct)}),(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(),(E=this.composerController)==null||E.dispose(),(O=this.rendererController)==null||O.dispose(),(ve=this.loaderController)==null||ve.dispose(),(Pe=this.leadController)==null||Pe.dispose(),(Ne=this.mListController)==null||Ne.dispose(),this.cssRendererController=void 0,this.installPlugins.clear(),(Ae=this.stats)==null||Ae.dom.remove(),(Fe=this.renderer)==null||Fe.domElement.remove()}};_e.options={stats:Le$1,helper:Le$1,viewHelper:Le$1,controls:!0,transformControls:Le$1,renderer:Ss,composer:ii,scene:ks,camera:wt,bloom:!1,bloomParams:si,ssao:!1,loader:li,ssaoParams:ti,css2DRenderer:!1,css2DRendererParams:U({},st),css3DRenderer:!1,css3DRendererParams:U({},st),mList:!0};let ot=_e;const Gi=J.ACTION,b$1=new Map,R$2=(g={})=>({generateTopUV(t,r,m,v,C){const _=r[m*3],w=r[m*3+1],E=r[v*3],O=r[v*3+1],ve=r[C*3],Pe=r[C*3+1];let Ne;if(b$1.has(t))Ne=b$1.get(t);else{let Oe=g.box3;if(!Oe){Oe=new Box3;const je=t.parameters.shapes.getPoints().map(at=>[at.x,at.y,0]).flat();Oe.setFromArray(je)}const ke=Oe.getSize(new Vector3);g.split&&(ke.y/=g.split),Ne={box:Oe,size:ke},b$1.set(t,Ne)}const{box:Ae,size:Fe}=Ne,ct=g.split?1-g.split:0;return[new Vector2((_-Ae.min.x)/Fe.x,(w-Ae.min.y)/Fe.y+ct),new Vector2((E-Ae.min.x)/Fe.x,(O-Ae.min.y)/Fe.y+ct),new Vector2((ve-Ae.min.x)/Fe.x,(Pe-Ae.min.y)/Fe.y+ct)]},generateSideWallUV(t,r,m,v,C,_){const w=r[m*3],E=r[m*3+1],O=r[m*3+2],ve=r[v*3],Pe=r[v*3+1],Ne=r[v*3+2],Ae=r[C*3],Fe=r[C*3+1],ct=r[C*3+2],Oe=r[_*3],ke=r[_*3+1],je=r[_*3+2];let at;if(b$1.has(r))at=b$1.get(r);else{const Lt=new Box3;Lt.setFromArray(r);const Wt=Lt.getSize(new Vector3);g.split&&(Wt.z/=1-g.split),g.sideRepeat&&(Wt.z/=g.sideRepeat),at={box:Lt,size:Wt},b$1.set(r,at)}const{box:xt,size:Gt}=at;return Math.abs(E-Pe)<Math.abs(w-ve)?[new Vector2((w-xt.min.x)/Gt.x,(O-xt.min.z)/Gt.z),new Vector2((ve-xt.min.x)/Gt.x,(Ne-xt.min.z)/Gt.z),new Vector2((Ae-xt.min.x)/Gt.x,(ct-xt.min.z)/Gt.z),new Vector2((Oe-xt.min.x)/Gt.x,(je-xt.min.z)/Gt.z)]:[new Vector2((E-xt.min.y)/Gt.y,(O-xt.min.z)/Gt.z),new Vector2((Pe-xt.min.y)/Gt.y,(Ne-xt.min.z)/Gt.z),new Vector2((Fe-xt.min.y)/Gt.y,(ct-xt.min.z)/Gt.z),new Vector2((ke-xt.min.y)/Gt.y,(je-xt.min.z)/Gt.z)]}}),P=()=>{b$1.clear()};var Jt=Object.defineProperty,Xt=Object.defineProperties,Qt=Object.getOwnPropertyDescriptors,lt=Object.getOwnPropertySymbols,Vt=Object.prototype.hasOwnProperty,Bt=Object.prototype.propertyIsEnumerable,It=(g,t,r)=>t in g?Jt(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,G=(g,t)=>{for(var r in t||(t={}))Vt.call(t,r)&&It(g,r,t[r]);if(lt)for(var r of lt(t))Bt.call(t,r)&&It(g,r,t[r]);return g},ut=(g,t)=>Xt(g,Qt(t)),gt=(g,t)=>{var r={};for(var m in g)Vt.call(g,m)&&t.indexOf(m)<0&&(r[m]=g[m]);if(g!=null&<)for(var m of lt(g))t.indexOf(m)<0&&Bt.call(g,m)&&(r[m]=g[m]);return r},nt=(g,t,r)=>new Promise((m,v)=>{var C=E=>{try{w(r.next(E))}catch(O){v(O)}},_=E=>{try{w(r.throw(E))}catch(O){v(O)}},w=E=>E.done?m(E.value):Promise.resolve(E.value).then(C,_);w((r=r.apply(g,t)).next())});class Xe extends ht{constructor(t){super(),this.objectType="BaseObject#Node",this.onNodePointerIndex=[],this.options=G({type:"2d"},t)}create(){const{position:t,children:r}=this.options,m=document.createElement("div");this.element=m,r&&m.appendChild(r),this.options.type==="3d"?this.createCSS3DObject(m):this.options.type==="3dSprite"?this.createCSS3DSprite(m):this.createCSS2DObject(m),t&&this.object3d.position.copy(t)}setChildren(t){this.options.children=t,this.element.innerHTML="",this.element.appendChild(t)}showAndEnsureVisible(){const t=this.options.children;t&&(t.style.visibility="hidden",this.show(),setTimeout(()=>{t.style.visibility="",this.ensureVisible()}))}moveElementToViewport(){const t=this.options.children;if(!t)return;const r=t.getBoundingClientRect(),m=window.innerWidth,v=window.innerHeight;let C=0,_=0;r.left<0?C=-r.left:r.right>m&&(C=m-r.right),r.top<0?_=-r.top:r.bottom>v&&(_=v-r.bottom),r.left+C<0&&(C=-r.left),r.top+_<0&&(_=-r.top),(C!==0||_!==0)&&(t.style.transform=`translate(${C}px, ${_}px)`)}ensureVisible(){const t=this.options.children;if(!t)return;t.style.transform&&(t.style.transform="");const r=new IntersectionObserver(m=>{m.forEach(v=>{v.isIntersecting&&(this.moveElementToViewport(),r.disconnect())})});r.observe(t)}onPointerEvent(t,r){const m=this.lead.handlePickNode([this],t,r);this.onNodePointerIndex.push(m)}dispose(){this.onNodePointerIndex.forEach(t=>{this.lead.removePickNode(t)}),super.dispose()}}class Qe extends ht{create(){this.createGroup()}}const Ue={ArcCurve,CatmullRomCurve3,CubicBezierCurve,CubicBezierCurve3,EllipseCurve,LineCurve,LineCurve3,QuadraticBezierCurve,QuadraticBezierCurve3,SplineCurve};class Z extends BufferGeometry{constructor(t=new Shape([new Vector2(.5,.5),new Vector2(-.5,.5),new Vector2(-.5,-.5),new Vector2(.5,-.5)]),r={}){super(),this.type="ExtrudeGeometry",this.parameters={shapes:t,options:r},t=Array.isArray(t)?t:[t];const m=this,v=[],C=[];for(let w=0,E=t.length;w<E;w++){const O=t[w];_(O)}this.setAttribute("position",new Float32BufferAttribute(v,3)),this.setAttribute("uv",new Float32BufferAttribute(C,2)),this.computeVertexNormals();function _(w){var E,O,ve;const Pe=[],Ne=r.curveSegments!==void 0?r.curveSegments:12,Ae=r.steps!==void 0?r.steps:1,Fe=r.depth!==void 0?r.depth:1;let ct=r.bevelEnabled!==void 0?r.bevelEnabled:!0,Oe=r.bevelThickness!==void 0?r.bevelThickness:.2,ke=r.bevelSize!==void 0?r.bevelSize:Oe-.1,je=r.bevelOffset!==void 0?r.bevelOffset:0,at=r.bevelSegments!==void 0?r.bevelSegments:3;const xt=r.extrudePath,Gt=r.UVGenerator!==void 0?r.UVGenerator:Ce,Lt=(E=r.hasTop)!=null?E:!0,Wt=(O=r.hasBottom)!=null?O:!0,Pt=(ve=r.hasSide)!=null?ve:!0;let zt,Nt=!1,Kt,t0,n0,o0;xt&&(zt=xt.getSpacedPoints(Ae),Nt=!0,ct=!1,Kt=xt.computeFrenetFrames(Ae,!1),t0=new Vector3,n0=new Vector3,o0=new Vector3),ct||(at=0,Oe=0,ke=0,je=0);const i0=w.extractPoints(Ne);let Yt=i0.shape;const qt=i0.holes;if(!ShapeUtils.isClockWise(Yt)){Yt=Yt.reverse();for(let P0=0,C0=qt.length;P0<C0;P0++){const E0=qt[P0];ShapeUtils.isClockWise(E0)&&(qt[P0]=E0.reverse())}}function kt(P0){const C0=10000000000000001e-36;let E0=P0[0];for(let q0=1;q0<=P0.length;q0++){const a0=q0%P0.length,s0=P0[a0],S0=s0.x-E0.x,R0=s0.y-E0.y,K0=S0*S0+R0*R0,V0=Math.max(Math.abs(s0.x),Math.abs(s0.y),Math.abs(E0.x),Math.abs(E0.y)),Ri=C0*V0*V0;if(K0<=Ri){P0.splice(a0,1),q0--;continue}E0=s0}}kt(Yt),qt.forEach(kt);const r0=qt.length,f0=Yt;for(let P0=0;P0<r0;P0++){const C0=qt[P0];Yt=Yt.concat(C0)}function m0(P0,C0,E0){return C0||console.error("THREE.ExtrudeGeometry: vec does not exist"),P0.clone().addScaledVector(C0,E0)}const w0=Yt.length;function $0(P0,C0,E0){let q0,a0,s0;const S0=P0.x-C0.x,R0=P0.y-C0.y,K0=E0.x-P0.x,V0=E0.y-P0.y,Ri=S0*S0+R0*R0,Ci=S0*V0-R0*K0;if(Math.abs(Ci)>Number.EPSILON){const _i=Math.sqrt(Ri),Pi=Math.sqrt(K0*K0+V0*V0),U0=C0.x-R0/_i,Zi=C0.y+S0/_i,Hi=E0.x-V0/Pi,Ni=E0.y+K0/Pi,Mi=((Hi-U0)*V0-(Ni-Zi)*K0)/(S0*V0-R0*K0);q0=U0+S0*Mi-P0.x,a0=Zi+R0*Mi-P0.y;const Vi=q0*q0+a0*a0;if(Vi<=2)return new Vector2(q0,a0);s0=Math.sqrt(Vi/2)}else{let _i=!1;S0>Number.EPSILON?K0>Number.EPSILON&&(_i=!0):S0<-Number.EPSILON?K0<-Number.EPSILON&&(_i=!0):Math.sign(R0)===Math.sign(V0)&&(_i=!0),_i?(q0=-R0,a0=S0,s0=Math.sqrt(Ri)):(q0=S0,a0=R0,s0=Math.sqrt(Ri/2))}return new Vector2(q0/s0,a0/s0)}const v0=[];for(let P0=0,C0=f0.length,E0=C0-1,q0=P0+1;P0<C0;P0++,E0++,q0++)E0===C0&&(E0=0),q0===C0&&(q0=0),v0[P0]=$0(f0[P0],f0[E0],f0[q0]);const I0=[];let A0,O0=v0.concat();for(let P0=0,C0=r0;P0<C0;P0++){const E0=qt[P0];A0=[];for(let q0=0,a0=E0.length,s0=a0-1,S0=q0+1;q0<a0;q0++,s0++,S0++)s0===a0&&(s0=0),S0===a0&&(S0=0),A0[q0]=$0(E0[q0],E0[s0],E0[S0]);I0.push(A0),O0=O0.concat(A0)}let xi;if(at===0)xi=ShapeUtils.triangulateShape(f0,qt);else{const P0=[],C0=[];for(let E0=0;E0<at;E0++){const q0=E0/at,a0=Oe*Math.cos(q0*Math.PI/2),s0=ke*Math.sin(q0*Math.PI/2)+je;for(let S0=0,R0=f0.length;S0<R0;S0++){const K0=m0(f0[S0],v0[S0],s0);l0(K0.x,K0.y,-a0),q0===0&&P0.push(K0)}for(let S0=0,R0=r0;S0<R0;S0++){const K0=qt[S0];A0=I0[S0];const V0=[];for(let Ri=0,Ci=K0.length;Ri<Ci;Ri++){const _i=m0(K0[Ri],A0[Ri],s0);l0(_i.x,_i.y,-a0),q0===0&&V0.push(_i)}q0===0&&C0.push(V0)}}xi=ShapeUtils.triangulateShape(P0,C0)}const wi=xi.length,Li=ke+je;for(let P0=0;P0<w0;P0++){const C0=ct?m0(Yt[P0],O0[P0],Li):Yt[P0];Nt?(n0.copy(Kt.normals[0]).multiplyScalar(C0.x),t0.copy(Kt.binormals[0]).multiplyScalar(C0.y),o0.copy(zt[0]).add(n0).add(t0),l0(o0.x,o0.y,o0.z)):l0(C0.x,C0.y,0)}for(let P0=1;P0<=Ae;P0++)for(let C0=0;C0<w0;C0++){const E0=ct?m0(Yt[C0],O0[C0],Li):Yt[C0];Nt?(n0.copy(Kt.normals[P0]).multiplyScalar(E0.x),t0.copy(Kt.binormals[P0]).multiplyScalar(E0.y),o0.copy(zt[P0]).add(n0).add(t0),l0(o0.x,o0.y,o0.z)):l0(E0.x,E0.y,Fe/Ae*P0)}for(let P0=at-1;P0>=0;P0--){const C0=P0/at,E0=Oe*Math.cos(C0*Math.PI/2),q0=ke*Math.sin(C0*Math.PI/2)+je;for(let a0=0,s0=f0.length;a0<s0;a0++){const S0=m0(f0[a0],v0[a0],q0);l0(S0.x,S0.y,Fe+E0)}for(let a0=0,s0=qt.length;a0<s0;a0++){const S0=qt[a0];A0=I0[a0];for(let R0=0,K0=S0.length;R0<K0;R0++){const V0=m0(S0[R0],A0[R0],q0);Nt?l0(V0.x,V0.y+zt[Ae-1].y,zt[Ae-1].x+E0):l0(V0.x,V0.y,Fe+E0)}}}ki(),Pt&&Ki();function ki(){const P0=v.length/3;if(ct){let C0=0,E0=w0*C0;if(Wt)for(let q0=0;q0<wi;q0++){const a0=xi[q0];Si(a0[2]+E0,a0[1]+E0,a0[0]+E0)}if(C0=Ae+at*2,E0=w0*C0,Lt)for(let q0=0;q0<wi;q0++){const a0=xi[q0];Si(a0[0]+E0,a0[1]+E0,a0[2]+E0)}}else{if(Wt)for(let C0=0;C0<wi;C0++){const E0=xi[C0];Si(E0[2],E0[1],E0[0])}if(Lt)for(let C0=0;C0<wi;C0++){const E0=xi[C0];Si(E0[0]+w0*Ae,E0[1]+w0*Ae,E0[2]+w0*Ae)}}m.addGroup(P0,v.length/3-P0,0)}function Ki(){const P0=v.length/3;let C0=0;B0(f0,C0),C0+=f0.length;for(let E0=0,q0=qt.length;E0<q0;E0++){const a0=qt[E0];B0(a0,C0),C0+=a0.length}m.addGroup(P0,v.length/3-P0,1)}function B0(P0,C0){let E0=P0.length;for(;--E0>=0;){const q0=E0;let a0=E0-1;a0<0&&(a0=P0.length-1);for(let s0=0,S0=Ae+at*2;s0<S0;s0++){const R0=w0*s0,K0=w0*(s0+1),V0=C0+q0+R0,Ri=C0+a0+R0,Ci=C0+a0+K0,_i=C0+q0+K0;j0(V0,Ri,Ci,_i)}}}function l0(P0,C0,E0){Pe.push(P0),Pe.push(C0),Pe.push(E0)}function Si(P0,C0,E0){gi(P0),gi(C0),gi(E0);const q0=v.length/3,a0=Gt.generateTopUV(m,v,q0-3,q0-2,q0-1);k0(a0[0]),k0(a0[1]),k0(a0[2])}function j0(P0,C0,E0,q0){gi(P0),gi(C0),gi(q0),gi(C0),gi(E0),gi(q0);const a0=v.length/3,s0=Gt.generateSideWallUV(m,v,a0-6,a0-3,a0-2,a0-1);k0(s0[0]),k0(s0[1]),k0(s0[3]),k0(s0[1]),k0(s0[2]),k0(s0[3])}function gi(P0){v.push(Pe[P0*3+0]),v.push(Pe[P0*3+1]),v.push(Pe[P0*3+2])}function k0(P0){C.push(P0.x),C.push(P0.y)}}}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}toJSON(){const t=super.toJSON(),r=this.parameters.shapes,m=this.parameters.options;return Ie(r,m,t)}static fromJSON(t,r){const m=[];for(let C=0,_=t.shapes.length;C<_;C++){const w=r[t.shapes[C]];m.push(w)}const v=t.options.extrudePath;return v!==void 0&&(t.options.extrudePath=new Ue[`${v.type}`]().fromJSON(v)),new Z(m,t.options)}}const Ce={generateTopUV:function(g,t,r,m,v){const C=t[r*3],_=t[r*3+1],w=t[m*3],E=t[m*3+1],O=t[v*3],ve=t[v*3+1];return[new Vector2(C,_),new Vector2(w,E),new Vector2(O,ve)]},generateSideWallUV:function(g,t,r,m,v,C){const _=t[r*3],w=t[r*3+1],E=t[r*3+2],O=t[m*3],ve=t[m*3+1],Pe=t[m*3+2],Ne=t[v*3],Ae=t[v*3+1],Fe=t[v*3+2],ct=t[C*3],Oe=t[C*3+1],ke=t[C*3+2];return Math.abs(w-ve)<Math.abs(_-O)?[new Vector2(_,1-E),new Vector2(O,1-Pe),new Vector2(Ne,1-Fe),new Vector2(ct,1-ke)]:[new Vector2(w,1-E),new Vector2(ve,1-Pe),new Vector2(Ae,1-Fe),new Vector2(Oe,1-ke)]}};function Ie(g,t,r){if(r.shapes=[],Array.isArray(g))for(let m=0,v=g.length;m<v;m++){const C=g[m];r.shapes.push(C.uuid)}else r.shapes.push(g.uuid);return r.options=Object.assign({},t),t.extrudePath!==void 0&&(r.options.extrudePath=t.extrudePath.toJSON()),r}class Ze extends ht{constructor(t){super(),this.rectAreaLightUniformsLibInit=!1,this.options=t}create(){var t,r,m,v,C,_,w,E,O,ve,Pe,Ne,Ae,Fe,ct,Oe,ke;const je=this.options;if(je.type==="AmbientLight"){const at=new AmbientLight(je.color);at.name="环境光",this.object3d=at}else if(je.type==="DirectionalLight"){const at=new DirectionalLight(je.color,je.intensity);at.name="平行光",at.target.position.set(0,0,0),this.object3d=at,at.target.name="平行光目标",at.shadow.camera.name="平行光阴影相机",at.shadow.camera.userData.directionalLightShadow=!0,this.directionalLight=at}else if(je.type==="PointLight"){const at=new PointLight((t=je.color)!=null?t:16777215,(r=je.intensity)!=null?r:1,(m=je.distance)!=null?m:0,(v=je.decay)!=null?v:2);at.name="点光源",this.object3d=at,this.pointLight=at}else if(je.type==="SpotLight"){const at=new SpotLight((C=je.color)!=null?C:16777215,(_=je.intensity)!=null?_:1,(w=je.distance)!=null?w:0,(E=je.angle)!=null?E:Math.PI/3,(O=je.penumbra)!=null?O:1,(ve=je.decay)!=null?ve:2);at.name="聚光灯",this.object3d=at,this.spotLight=at,at.target.name="聚光灯目标"}else if(je.type==="HemisphereLight"){const at=new HemisphereLight((Pe=je.color)!=null?Pe:16777215,(Ne=je.groundColor)!=null?Ne:16777215,(Ae=je.intensity)!=null?Ae:1);at.name="半球光",this.object3d=at,this.hemisphereLight=at}else if(je.type==="RectAreaLight"){this.rectAreaLightUniformsLibInit||(RectAreaLightUniformsLib.init(),this.rectAreaLightUniformsLibInit=!0);const at=new RectAreaLight((Fe=je.color)!=null?Fe:16777215,(ct=je.intensity)!=null?ct:1,(Oe=je.width)!=null?Oe:10,(ke=je.height)!=null?ke:10);at.name="矩形区域光",this.object3d=at,this.rectAreaLight=at}}render(){const t=this.object3d;t.target&&this.pencil.scene.add(t.target);const r=this.pencil.cameraTarget;if(this.spotLight||this.directionalLight){const m=this.spotLight||this.directionalLight;m.position.copy(r),m.target.position.copy(r)}else this.pointLight&&this.pointLight.position.copy(r)}dispose(){const t=this.object3d;t.target&&this.pencil.scene.remove(t.target),super.dispose()}}function R$1(g,t=0){const r=g[0].index!==null,m=new Set(Object.keys(g[0].attributes)),v=new Set(Object.keys(g[0].morphAttributes)),C={},_={},w=g[0].morphTargetsRelative,E=new BufferGeometry;let O=0;for(let ve=0;ve<g.length;++ve){const Pe=g[ve];let Ne=0;if(r!==(Pe.index!==null))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const Ae in Pe.attributes){if(!m.has(Ae))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+'. All geometries must have compatible attributes; make sure "'+Ae+'" attribute exists among all geometries, or in none of them.'),null;C[Ae]===void 0&&(C[Ae]=[]),C[Ae].push(Pe.attributes[Ae]),Ne++}if(Ne!==m.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". Make sure all geometries have the same number of attributes."),null;if(w!==Pe.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const Ae in Pe.morphAttributes){if(!v.has(Ae))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". .morphAttributes must be consistent throughout all geometries."),null;_[Ae]===void 0&&(_[Ae]=[]),_[Ae].push(Pe.morphAttributes[Ae])}if(t){let Ae;if(r)Ae=Pe.index.count;else if(Pe.attributes.position!==void 0)Ae=Pe.attributes.position.count;else return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+ve+". The geometry must have either an index or a position attribute"),null;if(t===1)E.addGroup(O,Ae,ve);else if(t===2&&Pe.groups.length>0)for(let Fe of Pe.groups){let ct=Fe.materialIndex;E.addGroup(O+Fe.start,Math.min(Fe.count,Ae),ct)}O+=Ae}}if(r){let ve=0;const Pe=[];for(let Ne=0;Ne<g.length;++Ne){const Ae=g[Ne].index;for(let Fe=0;Fe<Ae.count;++Fe)Pe.push(Ae.getX(Fe)+ve);ve+=g[Ne].attributes.position.count}E.setIndex(Pe)}for(const ve in C){const Pe=mergeAttributes(C[ve]);if(!Pe)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+ve+" attribute."),null;E.setAttribute(ve,Pe)}for(const ve in _){const Pe=_[ve][0].length;if(Pe===0)break;E.morphAttributes=E.morphAttributes||{},E.morphAttributes[ve]=[];for(let Ne=0;Ne<Pe;++Ne){const Ae=[];for(let ct=0;ct<_[ve].length;++ct)Ae.push(_[ve][ct][Ne]);const Fe=mergeAttributes(Ae);if(!Fe)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+ve+" morphAttribute."),null;E.morphAttributes[ve].push(Fe)}}return t===2?mergeGroups(E):E}const Dt=g=>{const{points:t}=g,r=t.reduce((m,v,C)=>(C<t.length-1&&m.push(v,t[C+1]),m),[]);return new BufferGeometry().setFromPoints(r)};let Ke=class extends ht{constructor(g={}){super(),this.options=G({},g)}get material(){var g;return(g=this.object3d)==null?void 0:g.material}create(){return nt(this,null,function*(){const{points:g,pointsArr:t,geometry:r,geometryArr:m,material:v,useGroups:C,setPointWidth:_,lineWidthArr:w,materialParameters:E,instanceCount:O}=this.options;let ve=v,Pe=r;!ve&&E&&(ve=this.getMaterial(E)),!Pe&&g?Pe=Dt({points:g}):!Pe&&t?Pe=R$1(t.map(Ae=>Dt({points:Ae})),C!=null?C:0):!Pe&&m&&m.length>1?Pe=R$1(m,C!=null?C:0):!Pe&&m&&m.length===1&&([Pe]=m);const Ne=new LineSegmentsGeometry().fromLineSegments(new LineSegments(Pe));if(this.pencil.options.WebGPUTHREE){O&&(Ne.instanceCount=O);const Ae=new _e$1(Ne,ve);Ae.computeLineDistances(),this.object3d=Ae}else{const Ae=new LineSegments2(Ne,ve);Ae.computeLineDistances(),this.object3d=Ae}})}getMaterial(g){return new LineMaterial(G({color:new Color$1("#ffffff")},g))}};function yt(g,t,r,m,v){let C;if(g=g.subarray||g.slice?g:g.buffer,r=r.subarray||r.slice?r:r.buffer,g=t?g.subarray?g.subarray(t,v&&t+v):g.slice(t,v&&t+v):g,r.set)r.set(g,m);else for(C=0;C<g.length;C++)r[C+m]=g[C];return r}function Ve(g){return g instanceof Float32Array?g:g instanceof BufferGeometry?g.getAttribute("position").array:g.map(t=>{const r=Array.isArray(t);return t instanceof Vector3?[t.x,t.y,t.z]:t instanceof Vector2?[t.x,t.y,0]:r&&t.length===3?[t[0],t[1],t[2]]:r&&t.length===2?[t[0],t[1],0]:t}).flat()}class Be extends BufferGeometry{constructor(){super(),this.type="MeshLine",this.isMeshLine=!0,this.positions=[],this.previous=[],this.next=[],this.side=[],this.width=[],this.indices_array=[],this.uvs=[],this.counters=[],this.widthCallback=null,this._points=[],this.matrixWorld=new Matrix4,Object.defineProperties(this,{points:{enumerable:!0,get(){return this._points},set(t){this.setPoints(t,this.widthCallback)}}})}setMatrixWorld(t){this.matrixWorld=t}setPoints(t,r){if(t=Ve(t),this._points=t,this.widthCallback=r!=null?r:null,this.positions=[],this.counters=[],t.length&&t[0]instanceof Vector3)for(let m=0;m<t.length;m++){const v=t[m],C=m/(t.length-1);this.positions.push(v.x,v.y,v.z),this.positions.push(v.x,v.y,v.z),this.counters.push(C),this.counters.push(C)}else for(let m=0;m<t.length;m+=3){const v=m/(t.length-1);this.positions.push(t[m],t[m+1],t[m+2]),this.positions.push(t[m],t[m+1],t[m+2]),this.counters.push(v),this.counters.push(v)}this.process()}compareV3(t,r){const m=t*6,v=r*6;return this.positions[m]===this.positions[v]&&this.positions[m+1]===this.positions[v+1]&&this.positions[m+2]===this.positions[v+2]}copyV3(t){const r=t*6;return[this.positions[r],this.positions[r+1],this.positions[r+2]]}process(){const t=this.positions.length/6;this.previous=[],this.next=[],this.side=[],this.width=[],this.indices_array=[],this.uvs=[];let r,m;this.compareV3(0,t-1)?m=this.copyV3(t-2):m=this.copyV3(0),this.previous.push(m[0],m[1],m[2]),this.previous.push(m[0],m[1],m[2]);for(let v=0;v<t;v++){if(this.side.push(1),this.side.push(-1),this.widthCallback?r=this.widthCallback(v/(t-1)):r=1,this.width.push(r),this.width.push(r),this.uvs.push(v/(t-1),0),this.uvs.push(v/(t-1),1),v<t-1){m=this.copyV3(v),this.previous.push(m[0],m[1],m[2]),this.previous.push(m[0],m[1],m[2]);const C=v*2;this.indices_array.push(C,C+1,C+2),this.indices_array.push(C+2,C+1,C+3)}v>0&&(m=this.copyV3(v),this.next.push(m[0],m[1],m[2]),this.next.push(m[0],m[1],m[2]))}this.compareV3(t-1,0)?m=this.copyV3(1):m=this.copyV3(t-1),this.next.push(m[0],m[1],m[2]),this.next.push(m[0],m[1],m[2]),!this._attributes||this._attributes.position.count!==this.counters.length?this._attributes={position:new BufferAttribute(new Float32Array(this.positions),3),previous:new BufferAttribute(new Float32Array(this.previous),3),next:new BufferAttribute(new Float32Array(this.next),3),side:new BufferAttribute(new Float32Array(this.side),1),width:new BufferAttribute(new Float32Array(this.width),1),uv:new BufferAttribute(new Float32Array(this.uvs),2),index:new BufferAttribute(new Uint16Array(this.indices_array),1),counters:new BufferAttribute(new Float32Array(this.counters),1)}:(this._attributes.position.copyArray(new Float32Array(this.positions)),this._attributes.position.needsUpdate=!0,this._attributes.previous.copyArray(new Float32Array(this.previous)),this._attributes.previous.needsUpdate=!0,this._attributes.next.copyArray(new Float32Array(this.next)),this._attributes.next.needsUpdate=!0,this._attributes.side.copyArray(new Float32Array(this.side)),this._attributes.side.needsUpdate=!0,this._attributes.width.copyArray(new Float32Array(this.width)),this._attributes.width.needsUpdate=!0,this._attributes.uv.copyArray(new Float32Array(this.uvs)),this._attributes.uv.needsUpdate=!0,this._attributes.index.copyArray(new Uint16Array(this.indices_array)),this._attributes.index.needsUpdate=!0),this.setAttribute("position",this._attributes.position),this.setAttribute("previous",this._attributes.previous),this.setAttribute("next",this._attributes.next),this.setAttribute("side",this._attributes.side),this.setAttribute("width",this._attributes.width),this.setAttribute("uv",this._attributes.uv),this.setAttribute("counters",this._attributes.counters),this.setAttribute("position",this._attributes.position),this.setAttribute("previous",this._attributes.previous),this.setAttribute("next",this._attributes.next),this.setAttribute("side",this._attributes.side),this.setAttribute("width",this._attributes.width),this.setAttribute("uv",this._attributes.uv),this.setAttribute("counters",this._attributes.counters),this.setIndex(this._attributes.index),this.computeBoundingSphere(),this.computeBoundingBox()}advance({x:t,y:r,z:m}){const v=this._attributes.position.array,C=this._attributes.previous.array,_=this._attributes.next.array,w=v.length;yt(v,0,C,0,w),yt(v,6,v,0,w-6),v[w-6]=t,v[w-5]=r,v[w-4]=m,v[w-3]=t,v[w-2]=r,v[w-1]=m,yt(v,6,_,0,w-6),_[w-6]=t,_[w-5]=r,_[w-4]=m,_[w-3]=t,_[w-2]=r,_[w-1]=m,this._attributes.position.needsUpdate=!0,this._attributes.previous.needsUpdate=!0,this._attributes.next.needsUpdate=!0}}const bt=g=>{const{setPointWidth:t,nodes:r}=g,m=new Be;return m.setPoints(r,t),m};class es extends ht{constructor(t={}){super(),this.options=G({},t)}get material(){var t;return(t=this.object3d)==null?void 0:t.material}create(){return nt(this,null,function*(){const{nodes:t,nodesArr:r,geometry:m,geometryArr:v,material:C,useGroups:_,setPointWidth:w,lineWidthArr:E,materialParameters:O}=this.options;let ve=C,Pe=m;!ve&&O&&(ve=this.getMaterial(O)),!Pe&&t?Pe=bt({nodes:t,setPointWidth:w}):!Pe&&r?Pe=R$1(r.map((Ne,Ae)=>{let Fe=w;return!Fe&&E&&(Fe=()=>{var ct;return(ct=E[Ae])!=null?ct:E[0]}),bt({nodes:Ne,setPointWidth:Fe})}),_!=null?_:0):!Pe&&v&&v.length>1?Pe=R$1(v,_!=null?_:0):!Pe&&v&&v.length===1&&([Pe]=v),this.createMesh(Pe,ve)})}setGeometry(t,r){const m=bt({nodes:t,setPointWidth:r}),v=this.object3d,C=v.geometry;v.geometry=m,C.dispose()}getMaterial(t){const{width:r,height:m}=this.pencil.getSize();return new Te$1(G({color:new Color$1("#ffffff"),resolution:new Vector2(r,m)},t))}addGeometries(t){const r=this.object3d,m=R$1([r.geometry,...t]);r.geometry=m}resize(t,r){var m,v;(v=(m=this.material)==null?void 0:m.uniforms)==null||v.resolution.value.set(t,r)}useMaterial(t){super.useMaterial(t);const{width:r,height:m}=this.pencil.getSize();this.resize(r,m)}animate({duration:t=1e3,delay:r=0,repeat:m=0,lineLoop:v,onRepeat:C,onUpdate:_,onComplete:w,startShow:E}={}){const{offset:O,offsetLoop:ve}=this.material.uniforms;if(this.material.userData.tween)return;const Pe=v!=null?v:!0;O.value.x=1,ve.value=Pe&&E?1:0;let Ne=0;const Ae=new Tween(O.value).to({x:-1},t).delay(r).repeat(m).onUpdate(({x:Fe})=>{Pe&&Fe<=0&&ve.value===0&&(ve.value=1),_&&_(Fe)}).onRepeat(()=>{Ne+=1,C&&C(Ne)}).onComplete(()=>{w&&w()}).start();this.material.userData.tween=Ae}render(){const{width:t,height:r}=this.pencil.getSize();this.resize(t,r)}dispose(){this.material.userData.tween&&(this.material.userData.tween.stop(),remove(this.material.userData.tween)),super.dispose()}}const Ot=g=>{const t=g,{coordinate:r,startHeight:m,height:v}=t,C=gt(t,["coordinate","startHeight","height"]);let _=m||0;return typeof m!="undefined"&&typeof v!="undefined"&&(_=m+v),new We$1([r],ut(G({},C),{startHeight:m,endHeight:_}))};class ss extends ht{constructor(t){super(),this.options=G({},t)}create(){const t=this.options,{geometry:r,coordinateArr:m,coordinate:v,material:C,useGroups:_}=t,w=gt(t,["geometry","coordinateArr","coordinate","material","useGroups"]);let E=r;if(!E&&v)E=Ot(G({coordinate:v},w));else if(!E&&m){const O=m.map(ve=>Ot(G({coordinate:ve},w)));E=R$1(O,_!=null?_:0)}this.createMesh(E,C)}}class ze extends Z{constructor(t,r){super(t,r);const m=new Brush(new Z(t,ut(G({},r),{hasTop:!0,hasSide:!0,hasBottom:!1})));m.updateMatrixWorld();const v=new Box3().setFromObject(m),C=new Vector3;v.getSize(C);const _=new Vector3(v.min.x+C.x/2,v.min.y+C.y/2,0);let w=r.topSegments,E=r.box3;if(E){E=E.union(v);const Oe=new Vector3;E.getSize(Oe);const ke=Math.max(C.x/Oe.x,C.y/Oe.y);w=Math.ceil(r.topSegments*ke)}if(w<4)return this;const O=new PlaneGeometry(C.x,C.y,w,w),ve=new Brush(O);ve.position.set(_.x,_.y,_.z),ve.updateMatrixWorld();const Pe=new Evaluator().evaluate(ve,m,INTERSECTION),Ne=Pe.geometry.getAttribute("position"),Ae=new Float32BufferAttribute(Ne.count*2,2);for(let Oe=0;Oe<Ne.count;Oe++){const ke=Ne.getZ(Oe);Ne.setZ(Oe,r.depth+ke)}if(E){const Oe=E.min,ke=E.max,je=new Vector3().subVectors(ke,Oe);for(let at=0;at<Ne.count;at++){const xt=Ne.getX(at),Gt=Ne.getY(at),Lt=(xt-Oe.x)/je.x,Wt=(Gt-Oe.y)/je.y;Ae.setXY(at,Lt,Wt)}Pe.geometry.setAttribute("uv",Ae)}Ne.needsUpdate=!0;const Fe=new Z(t,ut(G({},r),{hasTop:!1})),ct=R$1([Pe.geometry,Fe],2);this.copy(ct.toNonIndexed())}}const Ht=g=>{const{split:t,depth:r,points:m,box3:v,hasTop:C,hasBottom:_,hasSide:w,sideRepeat:E,topSegments:O}=g,ve=O?ze:Z,Pe=new ve(new Shape(m),{depth:r,bevelEnabled:!1,box3:v,UVGenerator:R$2({split:t,box3:v,sideRepeat:E}),hasTop:C,hasBottom:_,hasSide:w,topSegments:O});return P(),Pe};class is extends ht{constructor(t){super(),this.options=G({depth:1},t)}create(){return nt(this,null,function*(){const{points:t,pointsArr:r,useGroups:m,depth:v,geometry:C,geometryArr:_,material:w,box3:E,split:O,hasTop:ve,hasBottom:Pe,hasSide:Ne}=this.options,Ae=Array.isArray(v)?v:[v],Fe=Array.isArray(E)?E:[E],ct=w;let Oe=C;ct||console.log("material is null"),!Oe&&t?Oe=Ht({points:t,depth:Ae[0],box3:Fe[0],split:O,hasTop:ve,hasBottom:Pe,hasSide:Ne}):!Oe&&r?Oe=R$1(r.map((ke,je)=>{var at,xt;return Ht({points:ke,depth:(at=Ae[je])!=null?at:Ae[0],box3:(xt=Fe[je])!=null?xt:Fe[0],split:O,hasTop:ve,hasBottom:Pe,hasSide:Ne})}),m!=null?m:0):!Oe&&_&&_.length>1?Oe=R$1(_,m!=null?m:0):!Oe&&_&&_.length===1&&([Oe]=_),this.createMesh(Oe,ct)})}addGeometries(t){const r=this.object3d,m=R$1([r.geometry,...t]);r.geometry=m}setTextureAnisotropic(t,r){t.anisotropy=r||this.pencil.renderer.capabilities.getMaxAnisotropy()}}class Light extends Ze{update(t,r){var v;super.update(t,r);const m=this.object3d;(v=m.shadow)!=null&&v.camera&&(m.shadow.camera.near!==this.pencil.camera.near&&(m.shadow.camera.near=this.pencil.camera.near),m.shadow.camera.far!=this.pencil.camera.far&&(m.shadow.camera.far=this.pencil.camera.far))}render(){super.render();const t=this.object3d;t.userData=new Proxy({},{set:(w,E,O)=>(E==="keepCamera"&&(O?(this.pencil.render(),t.userData.parent=t.parent,this.pencil.camera.attach(t),t.target&&this.pencil.camera.attach(t.target)):!O&&t.userData.parent&&(this.pencil.render(),t.userData.parent.attach(t),t.target&&t.userData.parent.attach(t.target))),Reflect.set(w,E,O))});const{type:r,key:m}=this.options;m?(this.lead.updateBaseObjectKey(this,`${r}_${m}`),this.userData.updateKey=!1):this.lead.updateBaseObjectKey(this,`${r}`),t.target&&(t.target.userData.light=t);const v=this.object3d;v.isDirectionalLight&&(v.shadow.mapSize.width=1024,v.shadow.mapSize.height=1024);const C=this.object3d;C.isSpotLight&&C.shadow.mapSize.set(1024,1024);const _=this.object3d;_.isPointLight&&(_.shadow.mapSize.width=1024,_.shadow.mapSize.height=1024)}}class Point extends ht{constructor(r){super();L0(this,"options");L0(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 H0(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$2,equirectangular:s$1,winkel3:l},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*un(m,2):C=r/5*un(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,E=C*w;return t*g.renderer.getPixelRatio()/_.width/(1/E)};let map;class Arc extends ht{constructor(r){super();L0(this,"options");L0(this,"line");L0(this,"helperMesh");L0(this,"helperMeshPosition");L0(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 H0(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 E=v?createFlyPath(_,w,C):createFlyPath2(_,w,C),O=E.getPoints(1500),ve=this.pencil.lead,Pe=yield ve.draw("Line",{nodes:O,setPointWidth:Oe=>Oe*1,materialParameters:{color:r,map,useMap:1,transparent:!0,sizeAttenuation:0,lineWidth:m}},null);this.line=Pe,this.object3d=Pe.object3d;const[Ne,Ae,Fe,ct]=yield Promise.all([{key:"Arc_起点",position:E.v0},{key:"Arc_第一控制点",position:E.v1},{key:"Arc_第二控制点",position:E.v2},{key:"Arc_终点",position:E.v3}].map(je=>H0(this,[je],function*({key:Oe,position:ke}){const at=yield ve.draw("Group",{},this);return at.position.copy(ke),at.userData.disabledC=!0,at.userData.disabledR=!0,ve.updateBaseObjectKey(at,`${Oe}_${this.options.key}`),at})));this.helperMesh=[Ne,Ae,Fe,ct],this.helperMeshPosition=[Ne.position.clone(),Ae.position.clone(),Fe.position.clone(),ct.position.clone()]})}instantiate(){return H0(this,null,function*(){this.update();const r=yield this.line.instantiate({recursive:!1}),m=yield fn(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 E=(_?createFlyPath(r,m,v):createFlyPath2(r,m,v)).getPoints(1500);this.line.options.nodes=E,this.line.setGeometry(E,C),this.pickTube&&this.addPickTarget(this.pickTube.options.radius)}addPickTarget(r=1,m=!1){return H0(this,null,function*(){const v=this.pickTube,C=this.pencil.lead,_=this.line.options.nodes,w=new CurvePath;for(let ve=0;ve<_.length-1;ve++)w.add(new LineCurve3(_[ve],_[ve+1]));const E=yield C.draw("Tube",{path:w,radius:r,multiplyScalar:1},this),O=E.object3d;return O.material=new MeshBasicMaterial({color:16711680,transparent:!0,opacity:m?1:0}),v&&(v.userData._pe_&&E.onPointerEvent(...v.userData._pe_),v.erase()),this.pickTube=E,E})}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();L0(this,"options");this.options=Q0({},r)}create(){return H0(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 H0(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();L0(this,"options");this.options=Q0({},r)}create(){return H0(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);L0(this,"radius",100);L0(this,"material");L0(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),E=this.pencil.getSize().height*(1/(2*Math.tan(_/2))),O=t/E,{width:ve,height:Pe}=r.material.map.image;r.scale.set(ve/Pe*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();L0(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,Line:es,Line2:Ke,ExtrudePolygon:is,ConicPolygon:ss,Group:Qe,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(Bi(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,u=Object.getOwnPropertySymbols,Y=Object.prototype.hasOwnProperty,a=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={}))Y.call(t,r)&&s(g,r,t[r]);if(u)for(var r of u(t))a.call(t,r)&&s(g,r,t[r]);return g},x=(g,t)=>{var r={};for(var m in g)Y.call(g,m)&&t.indexOf(m)<0&&(r[m]=g[m]);if(g!=null&&u)for(var m of u(g))t.indexOf(m)<0&&a.call(g,m)&&(r[m]=g[m]);return r},V=(g,t,r)=>new Promise((m,v)=>{var C=E=>{try{w(r.next(E))}catch(O){v(O)}},_=E=>{try{w(r.throw(E))}catch(O){v(O)}},w=E=>E.done?m(E.value):Promise.resolve(E.value).then(C,_);w((r=r.apply(g,t)).next())});const o="dmFyIEJnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxGZz1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgSWc9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIFFyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIFp1PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksWHU9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgZ2M9KEosUSk9PihRPVN5bWJvbFtKXSk/UTpTeW1ib2wuZm9yKCJTeW1ib2wuIitKKSxrZz1KPT57dGhyb3cgVHlwZUVycm9yKEopfSx5aT1NYXRoLnBvdyxHdT0oSixRLG10KT0+USBpbiBKP0JnKEosUSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6bXR9KTpKW1FdPW10LEZ0PShKLFEpPT57Zm9yKHZhciBtdCBpbiBRfHwoUT17fSkpWnUuY2FsbChRLG10KSYmR3UoSixtdCxRW210XSk7aWYoUXIpZm9yKHZhciBtdCBvZiBRcihRKSlYdS5jYWxsKFEsbXQpJiZHdShKLG10LFFbbXRdKTtyZXR1cm4gSn0sWmU9KEosUSk9PkZnKEosSWcoUSkpO3ZhciBKdT0oSixRKT0+e3ZhciBtdD17fTtmb3IodmFyIE10IGluIEopWnUuY2FsbChKLE10KSYmUS5pbmRleE9mKE10KTwwJiYobXRbTXRdPUpbTXRdKTtpZihKIT1udWxsJiZRcilmb3IodmFyIE10IG9mIFFyKEopKVEuaW5kZXhPZihNdCk8MCYmWHUuY2FsbChKLE10KSYmKG10W010XT1KW010XSk7cmV0dXJuIG10fTt2YXIgTmc9ZnVuY3Rpb24oSixRKXt0aGlzWzBdPUosdGhpc1sxXT1RfTt2YXIgWXU9Sj0+e3ZhciBRPUpbZ2MoImFzeW5jSXRlcmF0b3IiKV0sbXQ9ITEsTXQsY249e307cmV0dXJuIFE9PW51bGw/KFE9SltnYygiaXRlcmF0b3IiKV0oKSxNdD1TZT0+Y25bU2VdPUJuPT5RW1NlXShCbikpOihRPVEuY2FsbChKKSxNdD1TZT0+Y25bU2VdPUJuPT57aWYobXQpe2lmKG10PSExLFNlPT09InRocm93Iil0aHJvdyBCbjtyZXR1cm4gQm59cmV0dXJuIG10PSEwLHtkb25lOiExLHZhbHVlOm5ldyBOZyhuZXcgUHJvbWlzZSh4Yz0+e3ZhciBLcj1RW1NlXShCbik7S3IgaW5zdGFuY2VvZiBPYmplY3R8fGtnKCJPYmplY3QgZXhwZWN0ZWQiKSx4YyhLcil9KSwxKX19KSxjbltnYygiaXRlcmF0b3IiKV09KCk9PmNuLE10KCJuZXh0IiksInRocm93ImluIFE/TXQoInRocm93Iik6Y24udGhyb3c9U2U9Pnt0aHJvdyBTZX0sInJldHVybiJpbiBRJiZNdCgicmV0dXJuIiksY259OyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTAtMjAyNSBUaHJlZS5qcyBBdXRob3JzCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKICovY29uc3QgSj0iMTc3Iix3Yz0iIixvZT0ic3JnYiIsYmM9InNyZ2ItbGluZWFyIixNYz0ibGluZWFyIix0bz0ic3JnYiI7Y2xhc3Mgb3N7YWRkRXZlbnRMaXN0ZW5lcih0LGUpe3RoaXMuX2xpc3RlbmVycz09PXZvaWQgMCYmKHRoaXMuX2xpc3RlbmVycz17fSk7Y29uc3Qgbj10aGlzLl9saXN0ZW5lcnM7blt0XT09PXZvaWQgMCYmKG5bdF09W10pLG5bdF0uaW5kZXhPZihlKT09PS0xJiZuW3RdLnB1c2goZSl9aGFzRXZlbnRMaXN0ZW5lcih0LGUpe2NvbnN0IG49dGhpcy5fbGlzdGVuZXJzO3JldHVybiBuPT09dm9pZCAwPyExOm5bdF0hPT12b2lkIDAmJm5bdF0uaW5kZXhPZihlKSE9PS0xfXJlbW92ZUV2ZW50TGlzdGVuZXIodCxlKXtjb25zdCBuPXRoaXMuX2xpc3RlbmVycztpZihuPT09dm9pZCAwKXJldHVybjtjb25zdCBzPW5bdF07aWYocyE9PXZvaWQgMCl7Y29uc3Qgcj1zLmluZGV4T2YoZSk7ciE9PS0xJiZzLnNwbGljZShyLDEpfX1kaXNwYXRjaEV2ZW50KHQpe2NvbnN0IGU9dGhpcy5fbGlzdGVuZXJzO2lmKGU9PT12b2lkIDApcmV0dXJuO2NvbnN0IG49ZVt0LnR5cGVdO2lmKG4hPT12b2lkIDApe3QudGFyZ2V0PXRoaXM7Y29uc3Qgcz1uLnNsaWNlKDApO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLmNhbGwodGhpcyx0KTt0LnRhcmdldD1udWxsfX19Y29uc3QgQXQ9WyIwMCIsIjAxIiwiMDIiLCIwMyIsIjA0IiwiMDUiLCIwNiIsIjA3IiwiMDgiLCIwOSIsIjBhIiwiMGIiLCIwYyIsIjBkIiwiMGUiLCIwZiIsIjEwIiwiMTEiLCIxMiIsIjEzIiwiMTQiLCIxNSIsIjE2IiwiMTciLCIxOCIsIjE5IiwiMWEiLCIxYiIsIjFjIiwiMWQiLCIxZSIsIjFmIiwiMjAiLCIyMSIsIjIyIiwiMjMiLCIyNCIsIjI1IiwiMjYiLCIyNyIsIjI4IiwiMjkiLCIyYSIsIjJiIiwiMmMiLCIyZCIsIjJlIiwiMmYiLCIzMCIsIjMxIiwiMzIiLCIzMyIsIjM0IiwiMzUiLCIzNiIsIjM3IiwiMzgiLCIzOSIsIjNhIiwiM2IiLCIzYyIsIjNkIiwiM2UiLCIzZiIsIjQwIiwiNDEiLCI0MiIsIjQzIiwiNDQiLCI0NSIsIjQ2IiwiNDciLCI0OCIsIjQ5IiwiNGEiLCI0YiIsIjRjIiwiNGQiLCI0ZSIsIjRmIiwiNTAiLCI1MSIsIjUyIiwiNTMiLCI1NCIsIjU1IiwiNTYiLCI1NyIsIjU4IiwiNTkiLCI1YSIsIjViIiwiNWMiLCI1ZCIsIjVlIiwiNWYiLCI2MCIsIjYxIiwiNjIiLCI2MyIsIjY0IiwiNjUiLCI2NiIsIjY3IiwiNjgiLCI2OSIsIjZhIiwiNmIiLCI2YyIsIjZkIiwiNmUiLCI2ZiIsIjcwIiwiNzEiLCI3MiIsIjczIiwiNzQiLCI3NSIsIjc2IiwiNzciLCI3OCIsIjc5IiwiN2EiLCI3YiIsIjdjIiwiN2QiLCI3ZSIsIjdmIiwiODAiLCI4MSIsIjgyIiwiODMiLCI4NCIsIjg1IiwiODYiLCI4NyIsIjg4IiwiODkiLCI4YSIsIjhiIiwiOGMiLCI4ZCIsIjhlIiwiOGYiLCI5MCIsIjkxIiwiOTIiLCI5MyIsIjk0IiwiOTUiLCI5NiIsIjk3IiwiOTgiLCI5OSIsIjlhIiwiOWIiLCI5YyIsIjlkIiwiOWUiLCI5ZiIsImEwIiwiYTEiLCJhMiIsImEzIiwiYTQiLCJhNSIsImE2IiwiYTciLCJhOCIsImE5IiwiYWEiLCJhYiIsImFjIiwiYWQiLCJhZSIsImFmIiwiYjAiLCJiMSIsImIyIiwiYjMiLCJiNCIsImI1IiwiYjYiLCJiNyIsImI4IiwiYjkiLCJiYSIsImJiIiwiYmMiLCJiZCIsImJlIiwiYmYiLCJjMCIsImMxIiwiYzIiLCJjMyIsImM0IiwiYzUiLCJjNiIsImM3IiwiYzgiLCJjOSIsImNhIiwiY2IiLCJjYyIsImNkIiwiY2UiLCJjZiIsImQwIiwiZDEiLCJkMiIsImQzIiwiZDQiLCJkNSIsImQ2IiwiZDciLCJkOCIsImQ5IiwiZGEiLCJkYiIsImRjIiwiZGQiLCJkZSIsImRmIiwiZTAiLCJlMSIsImUyIiwiZTMiLCJlNCIsImU1IiwiZTYiLCJlNyIsImU4IiwiZTkiLCJlYSIsImViIiwiZWMiLCJlZCIsImVlIiwiZWYiLCJmMCIsImYxIiwiZjIiLCJmMyIsImY0IiwiZjUiLCJmNiIsImY3IiwiZjgiLCJmOSIsImZhIiwiZmIiLCJmYyIsImZkIiwiZmUiLCJmZiJdO2Z1bmN0aW9uIEZuKCl7Y29uc3QgaT1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MCx0PU1hdGgucmFuZG9tKCkqNDI5NDk2NzI5NXwwLGU9TWF0aC5yYW5kb20oKSo0Mjk0OTY3Mjk1fDAsbj1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MDtyZXR1cm4oQXRbaSYyNTVdK0F0W2k+PjgmMjU1XStBdFtpPj4xNiYyNTVdK0F0W2k+PjI0JjI1NV0rIi0iK0F0W3QmMjU1XStBdFt0Pj44JjI1NV0rIi0iK0F0W3Q+PjE2JjE1fDY0XStBdFt0Pj4yNCYyNTVdKyItIitBdFtlJjYzfDEyOF0rQXRbZT4+OCYyNTVdKyItIitBdFtlPj4xNiYyNTVdK0F0W2U+PjI0JjI1NV0rQXRbbiYyNTVdK0F0W24+PjgmMjU1XStBdFtuPj4xNiYyNTVdK0F0W24+PjI0JjI1NV0pLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gWihpLHQsZSl7cmV0dXJuIE1hdGgubWF4KHQsTWF0aC5taW4oZSxpKSl9ZnVuY3Rpb24ganUoaSx0KXtyZXR1cm4oaSV0K3QpJXR9ZnVuY3Rpb24gZW8oaSx0LGUpe3JldHVybigxLWUpKmkrZSp0fWZ1bmN0aW9uIG1pKGksdCl7c3dpdGNoKHQuY29uc3RydWN0b3Ipe2Nhc2UgRmxvYXQzMkFycmF5OnJldHVybiBpO2Nhc2UgVWludDMyQXJyYXk6cmV0dXJuIGkvNDI5NDk2NzI5NTtjYXNlIFVpbnQxNkFycmF5OnJldHVybiBpLzY1NTM1O2Nhc2UgVWludDhBcnJheTpyZXR1cm4gaS8yNTU7Y2FzZSBJbnQzMkFycmF5OnJldHVybiBNYXRoLm1heChpLzIxNDc0ODM2NDcsLTEpO2Nhc2UgSW50MTZBcnJheTpyZXR1cm4gTWF0aC5tYXgoaS8zMjc2NywtMSk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgubWF4KGkvMTI3LC0xKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiSW52YWxpZCBjb21wb25lbnQgdHlwZS4iKX19ZnVuY3Rpb24gSXQoaSx0KXtzd2l0Y2godC5jb25zdHJ1Y3Rvcil7Y2FzZSBGbG9hdDMyQXJyYXk6cmV0dXJuIGk7Y2FzZSBVaW50MzJBcnJheTpyZXR1cm4gTWF0aC5yb3VuZChpKjQyOTQ5NjcyOTUpO2Nhc2UgVWludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSo2NTUzNSk7Y2FzZSBVaW50OEFycmF5OnJldHVybiBNYXRoLnJvdW5kKGkqMjU1KTtjYXNlIEludDMyQXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoyMTQ3NDgzNjQ3KTtjYXNlIEludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSozMjc2Nyk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoxMjcpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGNvbXBvbmVudCB0eXBlLiIpfX1jbGFzcyBSe2NvbnN0cnVjdG9yKHQ9MCxlPTApe1IucHJvdG90eXBlLmlzVmVjdG9yMj0hMCx0aGlzLng9dCx0aGlzLnk9ZX1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy54fXNldCB3aWR0aCh0KXt0aGlzLng9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMueX1zZXQgaGVpZ2h0KHQpe3RoaXMueT10fXNldCh0LGUpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Q29tcG9uZW50KHQsZSl7c3dpdGNoKHQpe2Nhc2UgMDp0aGlzLng9ZTticmVhaztjYXNlIDE6dGhpcy55PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnkpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PXNbMF0qZStzWzNdKm4rc1s2XSx0aGlzLnk9c1sxXSplK3NbNF0qbitzWzddLHRoaXN9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueX1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSl9bWFuaGF0dGFuTGVuZ3RoKCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueCkrTWF0aC5hYnModGhpcy55KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9YW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMigtdGhpcy55LC10aGlzLngpK01hdGguUEl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnk7cmV0dXJuIGUqZStuKm59bWFuaGF0dGFuRGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5hYnModGhpcy54LXQueCkrTWF0aC5hYnModGhpcy55LXQueSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXN9cm90YXRlQXJvdW5kKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9dGhpcy54LXQueCxvPXRoaXMueS10Lnk7cmV0dXJuIHRoaXMueD1yKm4tbypzK3QueCx0aGlzLnk9cipzK28qbit0LnksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55fX1jbGFzcyBnaXtjb25zdHJ1Y3Rvcih0PTAsZT0wLG49MCxzPTEpe3RoaXMuaXNRdWF0ZXJuaW9uPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9c31zdGF0aWMgc2xlcnBGbGF0KHQsZSxuLHMscixvLGEpe2xldCBjPW5bcyswXSxsPW5bcysxXSxoPW5bcysyXSx1PW5bcyszXTtjb25zdCBmPXJbbyswXSxkPXJbbysxXSxwPXJbbysyXSx5PXJbbyszXTtpZihhPT09MCl7dFtlKzBdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXU7cmV0dXJufWlmKGE9PT0xKXt0W2UrMF09Zix0W2UrMV09ZCx0W2UrMl09cCx0W2UrM109eTtyZXR1cm59aWYodSE9PXl8fGMhPT1mfHxsIT09ZHx8aCE9PXApe2xldCBtPTEtYTtjb25zdCBnPWMqZitsKmQraCpwK3UqeSxiPWc+PTA/MTotMSx3PTEtZypnO2lmKHc+TnVtYmVyLkVQU0lMT04pe2NvbnN0IE09TWF0aC5zcXJ0KHcpLEE9TWF0aC5hdGFuMihNLGcqYik7bT1NYXRoLnNpbihtKkEpL00sYT1NYXRoLnNpbihhKkEpL019Y29uc3QgeD1hKmI7aWYoYz1jKm0rZip4LGw9bCptK2QqeCxoPWgqbStwKngsdT11Km0reSp4LG09PT0xLWEpe2NvbnN0IE09MS9NYXRoLnNxcnQoYypjK2wqbCtoKmgrdSp1KTtjKj1NLGwqPU0saCo9TSx1Kj1NfX10W2VdPWMsdFtlKzFdPWwsdFtlKzJdPWgsdFtlKzNdPXV9c3RhdGljIG11bHRpcGx5UXVhdGVybmlvbnNGbGF0KHQsZSxuLHMscixvKXtjb25zdCBhPW5bc10sYz1uW3MrMV0sbD1uW3MrMl0saD1uW3MrM10sdT1yW29dLGY9cltvKzFdLGQ9cltvKzJdLHA9cltvKzNdO3JldHVybiB0W2VdPWEqcCtoKnUrYypkLWwqZix0W2UrMV09YypwK2gqZitsKnUtYSpkLHRbZSsyXT1sKnAraCpkK2EqZi1jKnUsdFtlKzNdPWgqcC1hKnUtYypmLWwqZCx0fWdldCB4KCl7cmV0dXJuIHRoaXMuX3h9c2V0IHgodCl7dGhpcy5feD10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeSgpe3JldHVybiB0aGlzLl95fXNldCB5KHQpe3RoaXMuX3k9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHooKXtyZXR1cm4gdGhpcy5fen1zZXQgeih0KXt0aGlzLl96PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB3KCl7cmV0dXJuIHRoaXMuX3d9c2V0IHcodCl7dGhpcy5fdz10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scyl7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX3c9cyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl94LHRoaXMuX3ksdGhpcy5feix0aGlzLl93KX1jb3B5KHQpe3JldHVybiB0aGlzLl94PXQueCx0aGlzLl95PXQueSx0aGlzLl96PXQueix0aGlzLl93PXQudyx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zZXRGcm9tRXVsZXIodCxlPSEwKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX29yZGVyLGE9TWF0aC5jb3MsYz1NYXRoLnNpbixsPWEobi8yKSxoPWEocy8yKSx1PWEoci8yKSxmPWMobi8yKSxkPWMocy8yKSxwPWMoci8yKTtzd2l0Y2gobyl7Y2FzZSJYWVoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJZWFoiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJaWFkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7Y2FzZSJZWlgiOnRoaXMuX3g9ZipoKnUrbCpkKnAsdGhpcy5feT1sKmQqdStmKmgqcCx0aGlzLl96PWwqaCpwLWYqZCp1LHRoaXMuX3c9bCpoKnUtZipkKnA7YnJlYWs7Y2FzZSJYWlkiOnRoaXMuX3g9ZipoKnUtbCpkKnAsdGhpcy5feT1sKmQqdS1mKmgqcCx0aGlzLl96PWwqaCpwK2YqZCp1LHRoaXMuX3c9bCpoKnUrZipkKnA7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLlF1YXRlcm5pb246IC5zZXRGcm9tRXVsZXIoKSBlbmNvdW50ZXJlZCBhbiB1bmtub3duIG9yZGVyOiAiK28pfXJldHVybiBlPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21BeGlzQW5nbGUodCxlKXtjb25zdCBuPWUvMixzPU1hdGguc2luKG4pO3JldHVybiB0aGlzLl94PXQueCpzLHRoaXMuX3k9dC55KnMsdGhpcy5fej10Lnoqcyx0aGlzLl93PU1hdGguY29zKG4pLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0KXtjb25zdCBlPXQuZWxlbWVudHMsbj1lWzBdLHM9ZVs0XSxyPWVbOF0sbz1lWzFdLGE9ZVs1XSxjPWVbOV0sbD1lWzJdLGg9ZVs2XSx1PWVbMTBdLGY9bithK3U7aWYoZj4wKXtjb25zdCBkPS41L01hdGguc3FydChmKzEpO3RoaXMuX3c9LjI1L2QsdGhpcy5feD0oaC1jKSpkLHRoaXMuX3k9KHItbCkqZCx0aGlzLl96PShvLXMpKmR9ZWxzZSBpZihuPmEmJm4+dSl7Y29uc3QgZD0yKk1hdGguc3FydCgxK24tYS11KTt0aGlzLl93PShoLWMpL2QsdGhpcy5feD0uMjUqZCx0aGlzLl95PShzK28pL2QsdGhpcy5fej0ocitsKS9kfWVsc2UgaWYoYT51KXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErYS1uLXUpO3RoaXMuX3c9KHItbCkvZCx0aGlzLl94PShzK28pL2QsdGhpcy5feT0uMjUqZCx0aGlzLl96PShjK2gpL2R9ZWxzZXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErdS1uLWEpO3RoaXMuX3c9KG8tcykvZCx0aGlzLl94PShyK2wpL2QsdGhpcy5feT0oYytoKS9kLHRoaXMuX3o9LjI1KmR9cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Vbml0VmVjdG9ycyh0LGUpe2xldCBuPXQuZG90KGUpKzE7cmV0dXJuIG48TnVtYmVyLkVQU0lMT04/KG49MCxNYXRoLmFicyh0LngpPk1hdGguYWJzKHQueik/KHRoaXMuX3g9LXQueSx0aGlzLl95PXQueCx0aGlzLl96PTAsdGhpcy5fdz1uKToodGhpcy5feD0wLHRoaXMuX3k9LXQueix0aGlzLl96PXQueSx0aGlzLl93PW4pKToodGhpcy5feD10LnkqZS56LXQueiplLnksdGhpcy5feT10LnoqZS54LXQueCplLnosdGhpcy5fej10LngqZS55LXQueSplLngsdGhpcy5fdz1uKSx0aGlzLm5vcm1hbGl6ZSgpfWFuZ2xlVG8odCl7cmV0dXJuIDIqTWF0aC5hY29zKE1hdGguYWJzKFoodGhpcy5kb3QodCksLTEsMSkpKX1yb3RhdGVUb3dhcmRzKHQsZSl7Y29uc3Qgbj10aGlzLmFuZ2xlVG8odCk7aWYobj09PTApcmV0dXJuIHRoaXM7Y29uc3Qgcz1NYXRoLm1pbigxLGUvbik7cmV0dXJuIHRoaXMuc2xlcnAodCxzKSx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDAsMCwwLDEpfWludmVydCgpe3JldHVybiB0aGlzLmNvbmp1Z2F0ZSgpfWNvbmp1Z2F0ZSgpe3JldHVybiB0aGlzLl94Kj0tMSx0aGlzLl95Kj0tMSx0aGlzLl96Kj0tMSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMuX3gqdC5feCt0aGlzLl95KnQuX3krdGhpcy5feip0Ll96K3RoaXMuX3cqdC5fd31sZW5ndGhTcSgpe3JldHVybiB0aGlzLl94KnRoaXMuX3grdGhpcy5feSp0aGlzLl95K3RoaXMuX3oqdGhpcy5feit0aGlzLl93KnRoaXMuX3d9bGVuZ3RoKCl7cmV0dXJuIE1hdGguc3FydCh0aGlzLl94KnRoaXMuX3grdGhpcy5feSp0aGlzLl95K3RoaXMuX3oqdGhpcy5feit0aGlzLl93KnRoaXMuX3cpfW5vcm1hbGl6ZSgpe2xldCB0PXRoaXMubGVuZ3RoKCk7cmV0dXJuIHQ9PT0wPyh0aGlzLl94PTAsdGhpcy5feT0wLHRoaXMuX3o9MCx0aGlzLl93PTEpOih0PTEvdCx0aGlzLl94PXRoaXMuX3gqdCx0aGlzLl95PXRoaXMuX3kqdCx0aGlzLl96PXRoaXMuX3oqdCx0aGlzLl93PXRoaXMuX3cqdCksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlRdWF0ZXJuaW9ucyh0aGlzLHQpfXByZW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5UXVhdGVybmlvbnModCx0aGlzKX1tdWx0aXBseVF1YXRlcm5pb25zKHQsZSl7Y29uc3Qgbj10Ll94LHM9dC5feSxyPXQuX3osbz10Ll93LGE9ZS5feCxjPWUuX3ksbD1lLl96LGg9ZS5fdztyZXR1cm4gdGhpcy5feD1uKmgrbyphK3MqbC1yKmMsdGhpcy5feT1zKmgrbypjK3IqYS1uKmwsdGhpcy5fej1yKmgrbypsK24qYy1zKmEsdGhpcy5fdz1vKmgtbiphLXMqYy1yKmwsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2xlcnAodCxlKXtpZihlPT09MClyZXR1cm4gdGhpcztpZihlPT09MSlyZXR1cm4gdGhpcy5jb3B5KHQpO2NvbnN0IG49dGhpcy5feCxzPXRoaXMuX3kscj10aGlzLl96LG89dGhpcy5fdztsZXQgYT1vKnQuX3crbip0Ll94K3MqdC5feStyKnQuX3o7aWYoYTwwPyh0aGlzLl93PS10Ll93LHRoaXMuX3g9LXQuX3gsdGhpcy5feT0tdC5feSx0aGlzLl96PS10Ll96LGE9LWEpOnRoaXMuY29weSh0KSxhPj0xKXJldHVybiB0aGlzLl93PW8sdGhpcy5feD1uLHRoaXMuX3k9cyx0aGlzLl96PXIsdGhpcztjb25zdCBjPTEtYSphO2lmKGM8PU51bWJlci5FUFNJTE9OKXtjb25zdCBkPTEtZTtyZXR1cm4gdGhpcy5fdz1kKm8rZSp0aGlzLl93LHRoaXMuX3g9ZCpuK2UqdGhpcy5feCx0aGlzLl95PWQqcytlKnRoaXMuX3ksdGhpcy5fej1kKnIrZSp0aGlzLl96LHRoaXMubm9ybWFsaXplKCksdGhpc31jb25zdCBsPU1hdGguc3FydChjKSxoPU1hdGguYXRhbjIobCxhKSx1PU1hdGguc2luKCgxLWUpKmgpL2wsZj1NYXRoLnNpbihlKmgpL2w7cmV0dXJuIHRoaXMuX3c9byp1K3RoaXMuX3cqZix0aGlzLl94PW4qdSt0aGlzLl94KmYsdGhpcy5feT1zKnUrdGhpcy5feSpmLHRoaXMuX3o9cip1K3RoaXMuX3oqZix0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zbGVycFF1YXRlcm5pb25zKHQsZSxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLnNsZXJwKGUsbil9cmFuZG9tKCl7Y29uc3QgdD0yKk1hdGguUEkqTWF0aC5yYW5kb20oKSxlPTIqTWF0aC5QSSpNYXRoLnJhbmRvbSgpLG49TWF0aC5yYW5kb20oKSxzPU1hdGguc3FydCgxLW4pLHI9TWF0aC5zcXJ0KG4pO3JldHVybiB0aGlzLnNldChzKk1hdGguc2luKHQpLHMqTWF0aC5jb3ModCkscipNYXRoLnNpbihlKSxyKk1hdGguY29zKGUpKX1lcXVhbHModCl7cmV0dXJuIHQuX3g9PT10aGlzLl94JiZ0Ll95PT09dGhpcy5feSYmdC5fej09PXRoaXMuX3omJnQuX3c9PT10aGlzLl93fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMuX3g9dFtlXSx0aGlzLl95PXRbZSsxXSx0aGlzLl96PXRbZSsyXSx0aGlzLl93PXRbZSszXSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLl94LHRbZSsxXT10aGlzLl95LHRbZSsyXT10aGlzLl96LHRbZSszXT10aGlzLl93LHR9ZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLl94PXQuZ2V0WChlKSx0aGlzLl95PXQuZ2V0WShlKSx0aGlzLl96PXQuZ2V0WihlKSx0aGlzLl93PXQuZ2V0VyhlKSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc310b0pTT04oKXtyZXR1cm4gdGhpcy50b0FycmF5KCl9X29uQ2hhbmdlKHQpe3JldHVybiB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrPXQsdGhpc31fb25DaGFuZ2VDYWxsYmFjaygpe30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLl94LHlpZWxkIHRoaXMuX3kseWllbGQgdGhpcy5feix5aWVsZCB0aGlzLl93fX1jbGFzcyBUe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wKXtULnByb3RvdHlwZS5pc1ZlY3RvcjM9ITAsdGhpcy54PXQsdGhpcy55PWUsdGhpcy56PW59c2V0KHQsZSxuKXtyZXR1cm4gbj09PXZvaWQgMCYmKG49dGhpcy56KSx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpcy56PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Wih0KXtyZXR1cm4gdGhpcy56PXQsdGhpc31zZXRDb21wb25lbnQodCxlKXtzd2l0Y2godCl7Y2FzZSAwOnRoaXMueD1lO2JyZWFrO2Nhc2UgMTp0aGlzLnk9ZTticmVhaztjYXNlIDI6dGhpcy56PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2Nhc2UgMjpyZXR1cm4gdGhpcy56O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnksdGhpcy56KX1jb3B5KHQpe3JldHVybiB0aGlzLng9dC54LHRoaXMueT10LnksdGhpcy56PXQueix0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpcy56Kz10LnosdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpcy56Kz10LHRoaXN9YWRkVmVjdG9ycyh0LGUpe3JldHVybiB0aGlzLng9dC54K2UueCx0aGlzLnk9dC55K2UueSx0aGlzLno9dC56K2Uueix0aGlzfWFkZFNjYWxlZFZlY3Rvcih0LGUpe3JldHVybiB0aGlzLngrPXQueCplLHRoaXMueSs9dC55KmUsdGhpcy56Kz10LnoqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpcy56LT10LnosdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpcy56LT10LHRoaXN9c3ViVmVjdG9ycyh0LGUpe3JldHVybiB0aGlzLng9dC54LWUueCx0aGlzLnk9dC55LWUueSx0aGlzLno9dC56LWUueix0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLngqPXQueCx0aGlzLnkqPXQueSx0aGlzLnoqPXQueix0aGlzfW11bHRpcGx5U2NhbGFyKHQpe3JldHVybiB0aGlzLngqPXQsdGhpcy55Kj10LHRoaXMueio9dCx0aGlzfW11bHRpcGx5VmVjdG9ycyh0LGUpe3JldHVybiB0aGlzLng9dC54KmUueCx0aGlzLnk9dC55KmUueSx0aGlzLno9dC56KmUueix0aGlzfWFwcGx5RXVsZXIodCl7cmV0dXJuIHRoaXMuYXBwbHlRdWF0ZXJuaW9uKEFjLnNldEZyb21FdWxlcih0KSl9YXBwbHlBeGlzQW5nbGUodCxlKXtyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oQWMuc2V0RnJvbUF4aXNBbmdsZSh0LGUpKX1hcHBseU1hdHJpeDModCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9clswXSplK3JbM10qbityWzZdKnMsdGhpcy55PXJbMV0qZStyWzRdKm4rcls3XSpzLHRoaXMuej1yWzJdKmUrcls1XSpuK3JbOF0qcyx0aGlzfWFwcGx5Tm9ybWFsTWF0cml4KHQpe3JldHVybiB0aGlzLmFwcGx5TWF0cml4Myh0KS5ub3JtYWxpemUoKX1hcHBseU1hdHJpeDQodCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10LmVsZW1lbnRzLG89MS8oclszXSplK3JbN10qbityWzExXSpzK3JbMTVdKTtyZXR1cm4gdGhpcy54PShyWzBdKmUrcls0XSpuK3JbOF0qcytyWzEyXSkqbyx0aGlzLnk9KHJbMV0qZStyWzVdKm4rcls5XSpzK3JbMTNdKSpvLHRoaXMuej0oclsyXSplK3JbNl0qbityWzEwXSpzK3JbMTRdKSpvLHRoaXN9YXBwbHlRdWF0ZXJuaW9uKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dGhpcy56LHI9dC54LG89dC55LGE9dC56LGM9dC53LGw9MioobypzLWEqbiksaD0yKihhKmUtcipzKSx1PTIqKHIqbi1vKmUpO3JldHVybiB0aGlzLng9ZStjKmwrbyp1LWEqaCx0aGlzLnk9bitjKmgrYSpsLXIqdSx0aGlzLno9cytjKnUrcipoLW8qbCx0aGlzfXByb2plY3QodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGRJbnZlcnNlKS5hcHBseU1hdHJpeDQodC5wcm9qZWN0aW9uTWF0cml4KX11bnByb2plY3QodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXg0KHQucHJvamVjdGlvbk1hdHJpeEludmVyc2UpLmFwcGx5TWF0cml4NCh0Lm1hdHJpeFdvcmxkKX10cmFuc2Zvcm1EaXJlY3Rpb24odCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9clswXSplK3JbNF0qbityWzhdKnMsdGhpcy55PXJbMV0qZStyWzVdKm4rcls5XSpzLHRoaXMuej1yWzJdKmUrcls2XSpuK3JbMTBdKnMsdGhpcy5ub3JtYWxpemUoKX1kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXMuei89dC56LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1pbih0aGlzLnosdC56KSx0aGlzfW1heCh0KXtyZXR1cm4gdGhpcy54PU1hdGgubWF4KHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1heCh0aGlzLnksdC55KSx0aGlzLno9TWF0aC5tYXgodGhpcy56LHQueiksdGhpc31jbGFtcCh0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdC54LGUueCksdGhpcy55PVoodGhpcy55LHQueSxlLnkpLHRoaXMuej1aKHRoaXMueix0LnosZS56KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXMuej1aKHRoaXMueix0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpcy56PU1hdGguZmxvb3IodGhpcy56KSx0aGlzfWNlaWwoKXtyZXR1cm4gdGhpcy54PU1hdGguY2VpbCh0aGlzLngpLHRoaXMueT1NYXRoLmNlaWwodGhpcy55KSx0aGlzLno9TWF0aC5jZWlsKHRoaXMueiksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpcy56PU1hdGgucm91bmQodGhpcy56KSx0aGlzfXJvdW5kVG9aZXJvKCl7cmV0dXJuIHRoaXMueD1NYXRoLnRydW5jKHRoaXMueCksdGhpcy55PU1hdGgudHJ1bmModGhpcy55KSx0aGlzLno9TWF0aC50cnVuYyh0aGlzLnopLHRoaXN9bmVnYXRlKCl7cmV0dXJuIHRoaXMueD0tdGhpcy54LHRoaXMueT0tdGhpcy55LHRoaXMuej0tdGhpcy56LHRoaXN9ZG90KHQpe3JldHVybiB0aGlzLngqdC54K3RoaXMueSp0LnkrdGhpcy56KnQuen1sZW5ndGhTcSgpe3JldHVybiB0aGlzLngqdGhpcy54K3RoaXMueSp0aGlzLnkrdGhpcy56KnRoaXMuen1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56KX1tYW5oYXR0YW5MZW5ndGgoKXtyZXR1cm4gTWF0aC5hYnModGhpcy54KStNYXRoLmFicyh0aGlzLnkpK01hdGguYWJzKHRoaXMueil9bm9ybWFsaXplKCl7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKHRoaXMubGVuZ3RoKCl8fDEpfXNldExlbmd0aCh0KXtyZXR1cm4gdGhpcy5ub3JtYWxpemUoKS5tdWx0aXBseVNjYWxhcih0KX1sZXJwKHQsZSl7cmV0dXJuIHRoaXMueCs9KHQueC10aGlzLngpKmUsdGhpcy55Kz0odC55LXRoaXMueSkqZSx0aGlzLnorPSh0LnotdGhpcy56KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpcy56PXQueisoZS56LXQueikqbix0aGlzfWNyb3NzKHQpe3JldHVybiB0aGlzLmNyb3NzVmVjdG9ycyh0aGlzLHQpfWNyb3NzVmVjdG9ycyh0LGUpe2NvbnN0IG49dC54LHM9dC55LHI9dC56LG89ZS54LGE9ZS55LGM9ZS56O3JldHVybiB0aGlzLng9cypjLXIqYSx0aGlzLnk9cipvLW4qYyx0aGlzLno9biphLXMqbyx0aGlzfXByb2plY3RPblZlY3Rvcih0KXtjb25zdCBlPXQubGVuZ3RoU3EoKTtpZihlPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDApO2NvbnN0IG49dC5kb3QodGhpcykvZTtyZXR1cm4gdGhpcy5jb3B5KHQpLm11bHRpcGx5U2NhbGFyKG4pfXByb2plY3RPblBsYW5lKHQpe3JldHVybiBuby5jb3B5KHRoaXMpLnByb2plY3RPblZlY3Rvcih0KSx0aGlzLnN1Yihubyl9cmVmbGVjdCh0KXtyZXR1cm4gdGhpcy5zdWIobm8uY29weSh0KS5tdWx0aXBseVNjYWxhcigyKnRoaXMuZG90KHQpKSl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnkscz10aGlzLnotdC56O3JldHVybiBlKmUrbipuK3Mqc31tYW5oYXR0YW5EaXN0YW5jZVRvKHQpe3JldHVybiBNYXRoLmFicyh0aGlzLngtdC54KStNYXRoLmFicyh0aGlzLnktdC55KStNYXRoLmFicyh0aGlzLnotdC56KX1zZXRGcm9tU3BoZXJpY2FsKHQpe3JldHVybiB0aGlzLnNldEZyb21TcGhlcmljYWxDb29yZHModC5yYWRpdXMsdC5waGksdC50aGV0YSl9c2V0RnJvbVNwaGVyaWNhbENvb3Jkcyh0LGUsbil7Y29uc3Qgcz1NYXRoLnNpbihlKSp0O3JldHVybiB0aGlzLng9cypNYXRoLnNpbihuKSx0aGlzLnk9TWF0aC5jb3MoZSkqdCx0aGlzLno9cypNYXRoLmNvcyhuKSx0aGlzfXNldEZyb21DeWxpbmRyaWNhbCh0KXtyZXR1cm4gdGhpcy5zZXRGcm9tQ3lsaW5kcmljYWxDb29yZHModC5yYWRpdXMsdC50aGV0YSx0LnkpfXNldEZyb21DeWxpbmRyaWNhbENvb3Jkcyh0LGUsbil7cmV0dXJuIHRoaXMueD10Kk1hdGguc2luKGUpLHRoaXMueT1uLHRoaXMuej10Kk1hdGguY29zKGUpLHRoaXN9c2V0RnJvbU1hdHJpeFBvc2l0aW9uKHQpe2NvbnN0IGU9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PWVbMTJdLHRoaXMueT1lWzEzXSx0aGlzLno9ZVsxNF0sdGhpc31zZXRGcm9tTWF0cml4U2NhbGUodCl7Y29uc3QgZT10aGlzLnNldEZyb21NYXRyaXhDb2x1bW4odCwwKS5sZW5ndGgoKSxuPXRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbih0LDEpLmxlbmd0aCgpLHM9dGhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMikubGVuZ3RoKCk7cmV0dXJuIHRoaXMueD1lLHRoaXMueT1uLHRoaXMuej1zLHRoaXN9c2V0RnJvbU1hdHJpeENvbHVtbih0LGUpe3JldHVybiB0aGlzLmZyb21BcnJheSh0LmVsZW1lbnRzLGUqNCl9c2V0RnJvbU1hdHJpeDNDb2x1bW4odCxlKXtyZXR1cm4gdGhpcy5mcm9tQXJyYXkodC5lbGVtZW50cyxlKjMpfXNldEZyb21FdWxlcih0KXtyZXR1cm4gdGhpcy54PXQuX3gsdGhpcy55PXQuX3ksdGhpcy56PXQuX3osdGhpc31zZXRGcm9tQ29sb3IodCl7cmV0dXJuIHRoaXMueD10LnIsdGhpcy55PXQuZyx0aGlzLno9dC5iLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lng9PT10aGlzLngmJnQueT09PXRoaXMueSYmdC56PT09dGhpcy56fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpcy56PXRbZSsyXSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMueCx0W2UrMV09dGhpcy55LHRbZSsyXT10aGlzLnosdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMueD10LmdldFgoZSksdGhpcy55PXQuZ2V0WShlKSx0aGlzLno9dC5nZXRaKGUpLHRoaXN9cmFuZG9tKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJhbmRvbSgpLHRoaXMueT1NYXRoLnJhbmRvbSgpLHRoaXMuej1NYXRoLnJhbmRvbSgpLHRoaXN9cmFuZG9tRGlyZWN0aW9uKCl7Y29uc3QgdD1NYXRoLnJhbmRvbSgpKk1hdGguUEkqMixlPU1hdGgucmFuZG9tKCkqMi0xLG49TWF0aC5zcXJ0KDEtZSplKTtyZXR1cm4gdGhpcy54PW4qTWF0aC5jb3ModCksdGhpcy55PWUsdGhpcy56PW4qTWF0aC5zaW4odCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55LHlpZWxkIHRoaXMuen19Y29uc3Qgbm89bmV3IFQsQWM9bmV3IGdpO2NsYXNzIGdle2NvbnN0cnVjdG9yKHQsZSxuLHMscixvLGEsYyxsKXtnZS5wcm90b3R5cGUuaXNNYXRyaXgzPSEwLHRoaXMuZWxlbWVudHM9WzEsMCwwLDAsMSwwLDAsMCwxXSx0IT09dm9pZCAwJiZ0aGlzLnNldCh0LGUsbixzLHIsbyxhLGMsbCl9c2V0KHQsZSxuLHMscixvLGEsYyxsKXtjb25zdCBoPXRoaXMuZWxlbWVudHM7cmV0dXJuIGhbMF09dCxoWzFdPXMsaFsyXT1hLGhbM109ZSxoWzRdPXIsaFs1XT1jLGhbNl09bixoWzddPW8saFs4XT1sLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwxLDAsMCwwLDEpLHRoaXN9Y29weSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzO3JldHVybiBlWzBdPW5bMF0sZVsxXT1uWzFdLGVbMl09blsyXSxlWzNdPW5bM10sZVs0XT1uWzRdLGVbNV09bls1XSxlWzZdPW5bNl0sZVs3XT1uWzddLGVbOF09bls4XSx0aGlzfWV4dHJhY3RCYXNpcyh0LGUsbil7cmV0dXJuIHQuc2V0RnJvbU1hdHJpeDNDb2x1bW4odGhpcywwKSxlLnNldEZyb21NYXRyaXgzQ29sdW1uKHRoaXMsMSksbi5zZXRGcm9tTWF0cml4M0NvbHVtbih0aGlzLDIpLHRoaXN9c2V0RnJvbU1hdHJpeDQodCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLnNldChlWzBdLGVbNF0sZVs4XSxlWzFdLGVbNV0sZVs5XSxlWzJdLGVbNl0sZVsxMF0pLHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0aGlzLHQpfXByZW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXModCx0aGlzKX1tdWx0aXBseU1hdHJpY2VzKHQsZSl7Y29uc3Qgbj10LmVsZW1lbnRzLHM9ZS5lbGVtZW50cyxyPXRoaXMuZWxlbWVudHMsbz1uWzBdLGE9blszXSxjPW5bNl0sbD1uWzFdLGg9bls0XSx1PW5bN10sZj1uWzJdLGQ9bls1XSxwPW5bOF0seT1zWzBdLG09c1szXSxnPXNbNl0sYj1zWzFdLHc9c1s0XSx4PXNbN10sTT1zWzJdLEE9c1s1XSxTPXNbOF07cmV0dXJuIHJbMF09byp5K2EqYitjKk0sclszXT1vKm0rYSp3K2MqQSxyWzZdPW8qZythKngrYypTLHJbMV09bCp5K2gqYit1Kk0scls0XT1sKm0raCp3K3UqQSxyWzddPWwqZytoKngrdSpTLHJbMl09Zip5K2QqYitwKk0scls1XT1mKm0rZCp3K3AqQSxyWzhdPWYqZytkKngrcCpTLHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiBlWzBdKj10LGVbM10qPXQsZVs2XSo9dCxlWzFdKj10LGVbNF0qPXQsZVs3XSo9dCxlWzJdKj10LGVbNV0qPXQsZVs4XSo9dCx0aGlzfWRldGVybWluYW50KCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzLGU9dFswXSxuPXRbMV0scz10WzJdLHI9dFszXSxvPXRbNF0sYT10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdO3JldHVybiBlKm8qaC1lKmEqbC1uKnIqaCtuKmEqYytzKnIqbC1zKm8qY31pbnZlcnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFsxXSxzPXRbMl0scj10WzNdLG89dFs0XSxhPXRbNV0sYz10WzZdLGw9dFs3XSxoPXRbOF0sdT1oKm8tYSpsLGY9YSpjLWgqcixkPWwqci1vKmMscD1lKnUrbipmK3MqZDtpZihwPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMCwwLDAsMCwwLDApO2NvbnN0IHk9MS9wO3JldHVybiB0WzBdPXUqeSx0WzFdPShzKmwtaCpuKSp5LHRbMl09KGEqbi1zKm8pKnksdFszXT1mKnksdFs0XT0oaCplLXMqYykqeSx0WzVdPShzKnItYSplKSp5LHRbNl09ZCp5LHRbN109KG4qYy1sKmUpKnksdFs4XT0obyplLW4qcikqeSx0aGlzfXRyYW5zcG9zZSgpe2xldCB0O2NvbnN0IGU9dGhpcy5lbGVtZW50cztyZXR1cm4gdD1lWzFdLGVbMV09ZVszXSxlWzNdPXQsdD1lWzJdLGVbMl09ZVs2XSxlWzZdPXQsdD1lWzVdLGVbNV09ZVs3XSxlWzddPXQsdGhpc31nZXROb3JtYWxNYXRyaXgodCl7cmV0dXJuIHRoaXMuc2V0RnJvbU1hdHJpeDQodCkuaW52ZXJ0KCkudHJhbnNwb3NlKCl9dHJhbnNwb3NlSW50b0FycmF5KHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cztyZXR1cm4gdFswXT1lWzBdLHRbMV09ZVszXSx0WzJdPWVbNl0sdFszXT1lWzFdLHRbNF09ZVs0XSx0WzVdPWVbN10sdFs2XT1lWzJdLHRbN109ZVs1XSx0WzhdPWVbOF0sdGhpc31zZXRVdlRyYW5zZm9ybSh0LGUsbixzLHIsbyxhKXtjb25zdCBjPU1hdGguY29zKHIpLGw9TWF0aC5zaW4ocik7cmV0dXJuIHRoaXMuc2V0KG4qYyxuKmwsLW4qKGMqbytsKmEpK28rdCwtcypsLHMqYywtcyooLWwqbytjKmEpK2ErZSwwLDAsMSksdGhpc31zY2FsZSh0LGUpe3JldHVybiB0aGlzLnByZW11bHRpcGx5KGlvLm1ha2VTY2FsZSh0LGUpKSx0aGlzfXJvdGF0ZSh0KXtyZXR1cm4gdGhpcy5wcmVtdWx0aXBseShpby5tYWtlUm90YXRpb24oLXQpKSx0aGlzfXRyYW5zbGF0ZSh0LGUpe3JldHVybiB0aGlzLnByZW11bHRpcGx5KGlvLm1ha2VUcmFuc2xhdGlvbih0LGUpKSx0aGlzfW1ha2VUcmFuc2xhdGlvbih0LGUpe3JldHVybiB0LmlzVmVjdG9yMj90aGlzLnNldCgxLDAsdC54LDAsMSx0LnksMCwwLDEpOnRoaXMuc2V0KDEsMCx0LDAsMSxlLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbih0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsLW4sMCxuLGUsMCwwLDAsMSksdGhpc31tYWtlU2NhbGUodCxlKXtyZXR1cm4gdGhpcy5zZXQodCwwLDAsMCxlLDAsMCwwLDEpLHRoaXN9ZXF1YWxzKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7Zm9yKGxldCBzPTA7czw5O3MrKylpZihlW3NdIT09bltzXSlyZXR1cm4hMTtyZXR1cm4hMH1mcm9tQXJyYXkodCxlPTApe2ZvcihsZXQgbj0wO248OTtuKyspdGhpcy5lbGVtZW50c1tuXT10W24rZV07cmV0dXJuIHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7Y29uc3Qgbj10aGlzLmVsZW1lbnRzO3JldHVybiB0W2VdPW5bMF0sdFtlKzFdPW5bMV0sdFtlKzJdPW5bMl0sdFtlKzNdPW5bM10sdFtlKzRdPW5bNF0sdFtlKzVdPW5bNV0sdFtlKzZdPW5bNl0sdFtlKzddPW5bN10sdFtlKzhdPW5bOF0sdH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmZyb21BcnJheSh0aGlzLmVsZW1lbnRzKX19Y29uc3QgaW89bmV3IGdlO2Z1bmN0aW9uIFF1KGkpe2ZvcihsZXQgdD1pLmxlbmd0aC0xO3Q+PTA7LS10KWlmKGlbdF0+PTY1NTM1KXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uIFNjKGkpe3JldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiLGkpfWNvbnN0IF9jPXt9O2Z1bmN0aW9uIHZjKGkpe2kgaW4gX2N8fChfY1tpXT0hMCxjb25zb2xlLndhcm4oaSkpfWNvbnN0IHpjPW5ldyBnZSgpLnNldCguNDEyMzkwOCwuMzU3NTg0MywuMTgwNDgwOCwuMjEyNjM5LC43MTUxNjg3LC4wNzIxOTIzLC4wMTkzMzA4LC4xMTkxOTQ4LC45NTA1MzIyKSxUYz1uZXcgZ2UoKS5zZXQoMy4yNDA5Njk5LC0xLjUzNzM4MzIsLS40OTg2MTA4LC0uOTY5MjQzNiwxLjg3NTk2NzUsLjA0MTU1NTEsLjA1NTYzMDEsLS4yMDM5NzcsMS4wNTY5NzE1KTtmdW5jdGlvbiBLdSgpe2NvbnN0IGk9e2VuYWJsZWQ6ITAsd29ya2luZ0NvbG9yU3BhY2U6YmMsc3BhY2VzOnt9LGNvbnZlcnQ6ZnVuY3Rpb24ocyxyLG8pe3JldHVybiB0aGlzLmVuYWJsZWQ9PT0hMXx8cj09PW98fCFyfHwhb3x8KHRoaXMuc3BhY2VzW3JdLnRyYW5zZmVyPT09dG8mJihzLnI9X2Uocy5yKSxzLmc9X2Uocy5nKSxzLmI9X2Uocy5iKSksdGhpcy5zcGFjZXNbcl0ucHJpbWFyaWVzIT09dGhpcy5zcGFjZXNbb10ucHJpbWFyaWVzJiYocy5hcHBseU1hdHJpeDModGhpcy5zcGFjZXNbcl0udG9YWVopLHMuYXBwbHlNYXRyaXgzKHRoaXMuc3BhY2VzW29dLmZyb21YWVopKSx0aGlzLnNwYWNlc1tvXS50cmFuc2Zlcj09PXRvJiYocy5yPUluKHMucikscy5nPUluKHMuZykscy5iPUluKHMuYikpKSxzfSx3b3JraW5nVG9Db2xvclNwYWNlOmZ1bmN0aW9uKHMscil7cmV0dXJuIHRoaXMuY29udmVydChzLHRoaXMud29ya2luZ0NvbG9yU3BhY2Uscil9LGNvbG9yU3BhY2VUb1dvcmtpbmc6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdGhpcy5jb252ZXJ0KHMscix0aGlzLndvcmtpbmdDb2xvclNwYWNlKX0sZ2V0UHJpbWFyaWVzOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5wcmltYXJpZXN9LGdldFRyYW5zZmVyOmZ1bmN0aW9uKHMpe3JldHVybiBzPT09d2M/TWM6dGhpcy5zcGFjZXNbc10udHJhbnNmZXJ9LGdldEx1bWluYW5jZUNvZWZmaWNpZW50czpmdW5jdGlvbihzLHI9dGhpcy53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHMuZnJvbUFycmF5KHRoaXMuc3BhY2VzW3JdLmx1bWluYW5jZUNvZWZmaWNpZW50cyl9LGRlZmluZTpmdW5jdGlvbihzKXtPYmplY3QuYXNzaWduKHRoaXMuc3BhY2VzLHMpfSxfZ2V0TWF0cml4OmZ1bmN0aW9uKHMscixvKXtyZXR1cm4gcy5jb3B5KHRoaXMuc3BhY2VzW3JdLnRvWFlaKS5tdWx0aXBseSh0aGlzLnNwYWNlc1tvXS5mcm9tWFlaKX0sX2dldERyYXdpbmdCdWZmZXJDb2xvclNwYWNlOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5vdXRwdXRDb2xvclNwYWNlQ29uZmlnLmRyYXdpbmdCdWZmZXJDb2xvclNwYWNlfSxfZ2V0VW5wYWNrQ29sb3JTcGFjZTpmdW5jdGlvbihzPXRoaXMud29ya2luZ0NvbG9yU3BhY2Upe3JldHVybiB0aGlzLnNwYWNlc1tzXS53b3JraW5nQ29sb3JTcGFjZUNvbmZpZy51bnBhY2tDb2xvclNwYWNlfSxmcm9tV29ya2luZ0NvbG9yU3BhY2U6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdmMoIlRIUkVFLkNvbG9yTWFuYWdlbWVudDogLmZyb21Xb3JraW5nQ29sb3JTcGFjZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLndvcmtpbmdUb0NvbG9yU3BhY2UoKS4iKSxpLndvcmtpbmdUb0NvbG9yU3BhY2UocyxyKX0sdG9Xb3JraW5nQ29sb3JTcGFjZTpmdW5jdGlvbihzLHIpe3JldHVybiB2YygiVEhSRUUuQ29sb3JNYW5hZ2VtZW50OiAudG9Xb3JraW5nQ29sb3JTcGFjZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmNvbG9yU3BhY2VUb1dvcmtpbmcoKS4iKSxpLmNvbG9yU3BhY2VUb1dvcmtpbmcocyxyKX19LHQ9Wy42NCwuMzMsLjMsLjYsLjE1LC4wNl0sZT1bLjIxMjYsLjcxNTIsLjA3MjJdLG49Wy4zMTI3LC4zMjldO3JldHVybiBpLmRlZmluZSh7W2JjXTp7cHJpbWFyaWVzOnQsd2hpdGVQb2ludDpuLHRyYW5zZmVyOk1jLHRvWFlaOnpjLGZyb21YWVo6VGMsbHVtaW5hbmNlQ29lZmZpY2llbnRzOmUsd29ya2luZ0NvbG9yU3BhY2VDb25maWc6e3VucGFja0NvbG9yU3BhY2U6b2V9LG91dHB1dENvbG9yU3BhY2VDb25maWc6e2RyYXdpbmdCdWZmZXJDb2xvclNwYWNlOm9lfX0sW29lXTp7cHJpbWFyaWVzOnQsd2hpdGVQb2ludDpuLHRyYW5zZmVyOnRvLHRvWFlaOnpjLGZyb21YWVo6VGMsbHVtaW5hbmNlQ29lZmZpY2llbnRzOmUsb3V0cHV0Q29sb3JTcGFjZUNvbmZpZzp7ZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6b2V9fX0pLGl9Y29uc3QgYWU9S3UoKTtmdW5jdGlvbiBfZShpKXtyZXR1cm4gaTwuMDQwNDU/aSouMDc3Mzk5MzgwODpNYXRoLnBvdyhpKi45NDc4NjcyOTg2Ky4wNTIxMzI3MDE0LDIuNCl9ZnVuY3Rpb24gSW4oaSl7cmV0dXJuIGk8LjAwMzEzMDg/aSoxMi45MjoxLjA1NSpNYXRoLnBvdyhpLC40MTY2NiktLjA1NX1sZXQga247Y2xhc3MgdGZ7c3RhdGljIGdldERhdGFVUkwodCxlPSJpbWFnZS9wbmciKXtpZigvXmRhdGE6L2kudGVzdCh0LnNyYyl8fHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudD09InVuZGVmaW5lZCIpcmV0dXJuIHQuc3JjO2xldCBuO2lmKHQgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCluPXQ7ZWxzZXtrbj09PXZvaWQgMCYmKGtuPVNjKCJjYW52YXMiKSksa24ud2lkdGg9dC53aWR0aCxrbi5oZWlnaHQ9dC5oZWlnaHQ7Y29uc3Qgcz1rbi5nZXRDb250ZXh0KCIyZCIpO3QgaW5zdGFuY2VvZiBJbWFnZURhdGE/cy5wdXRJbWFnZURhdGEodCwwLDApOnMuZHJhd0ltYWdlKHQsMCwwLHQud2lkdGgsdC5oZWlnaHQpLG49a259cmV0dXJuIG4udG9EYXRhVVJMKGUpfXN0YXRpYyBzUkdCVG9MaW5lYXIodCl7aWYodHlwZW9mIEhUTUxJbWFnZUVsZW1lbnQhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudHx8dHlwZW9mIEhUTUxDYW52YXNFbGVtZW50IT0idW5kZWZpbmVkIiYmdCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50fHx0eXBlb2YgSW1hZ2VCaXRtYXAhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSW1hZ2VCaXRtYXApe2NvbnN0IGU9U2MoImNhbnZhcyIpO2Uud2lkdGg9dC53aWR0aCxlLmhlaWdodD10LmhlaWdodDtjb25zdCBuPWUuZ2V0Q29udGV4dCgiMmQiKTtuLmRyYXdJbWFnZSh0LDAsMCx0LndpZHRoLHQuaGVpZ2h0KTtjb25zdCBzPW4uZ2V0SW1hZ2VEYXRhKDAsMCx0LndpZHRoLHQuaGVpZ2h0KSxyPXMuZGF0YTtmb3IobGV0IG89MDtvPHIubGVuZ3RoO28rKylyW29dPV9lKHJbb10vMjU1KSoyNTU7cmV0dXJuIG4ucHV0SW1hZ2VEYXRhKHMsMCwwKSxlfWVsc2UgaWYodC5kYXRhKXtjb25zdCBlPXQuZGF0YS5zbGljZSgwKTtmb3IobGV0IG49MDtuPGUubGVuZ3RoO24rKyllIGluc3RhbmNlb2YgVWludDhBcnJheXx8ZSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5P2Vbbl09TWF0aC5mbG9vcihfZShlW25dLzI1NSkqMjU1KTplW25dPV9lKGVbbl0pO3JldHVybntkYXRhOmUsd2lkdGg6dC53aWR0aCxoZWlnaHQ6dC5oZWlnaHR9fWVsc2UgcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuSW1hZ2VVdGlscy5zUkdCVG9MaW5lYXIoKTogVW5zdXBwb3J0ZWQgaW1hZ2UgdHlwZS4gTm8gY29sb3Igc3BhY2UgY29udmVyc2lvbiBhcHBsaWVkLiIpLHR9fWxldCBlZj0wO2NsYXNzIG5me2NvbnN0cnVjdG9yKHQ9bnVsbCl7dGhpcy5pc1NvdXJjZT0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTplZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5kYXRhPXQsdGhpcy5kYXRhUmVhZHk9ITAsdGhpcy52ZXJzaW9uPTB9Z2V0U2l6ZSh0KXtjb25zdCBlPXRoaXMuZGF0YTtyZXR1cm4gZSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQ/dC5zZXQoZS52aWRlb1dpZHRoLGUudmlkZW9IZWlnaHQpOmUhPT1udWxsP3Quc2V0KGUud2lkdGgsZS5oZWlnaHQsZS5kZXB0aHx8MCk6dC5zZXQoMCwwLDApLHR9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy52ZXJzaW9uKyt9dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciO2lmKCFlJiZ0LmltYWdlc1t0aGlzLnV1aWRdIT09dm9pZCAwKXJldHVybiB0LmltYWdlc1t0aGlzLnV1aWRdO2NvbnN0IG49e3V1aWQ6dGhpcy51dWlkLHVybDoiIn0scz10aGlzLmRhdGE7aWYocyE9PW51bGwpe2xldCByO2lmKEFycmF5LmlzQXJyYXkocykpe3I9W107Zm9yKGxldCBvPTAsYT1zLmxlbmd0aDtvPGE7bysrKXNbb10uaXNEYXRhVGV4dHVyZT9yLnB1c2goc28oc1tvXS5pbWFnZSkpOnIucHVzaChzbyhzW29dKSl9ZWxzZSByPXNvKHMpO24udXJsPXJ9cmV0dXJuIGV8fCh0LmltYWdlc1t0aGlzLnV1aWRdPW4pLG59fWZ1bmN0aW9uIHNvKGkpe3JldHVybiB0eXBlb2YgSFRNTEltYWdlRWxlbWVudCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50fHx0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQhPSJ1bmRlZmluZWQiJiZpIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnR8fHR5cGVvZiBJbWFnZUJpdG1hcCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcD90Zi5nZXREYXRhVVJMKGkpOmkuZGF0YT97ZGF0YTpBcnJheS5mcm9tKGkuZGF0YSksd2lkdGg6aS53aWR0aCxoZWlnaHQ6aS5oZWlnaHQsdHlwZTppLmRhdGEuY29uc3RydWN0b3IubmFtZX06KGNvbnNvbGUud2FybigiVEhSRUUuVGV4dHVyZTogVW5hYmxlIHRvIHNlcmlhbGl6ZSBUZXh0dXJlLiIpLHt9KX1sZXQgc2Y9MDtjb25zdCBybz1uZXcgVDtjbGFzcyBsbiBleHRlbmRzIG9ze2NvbnN0cnVjdG9yKHQ9bG4uREVGQVVMVF9JTUFHRSxlPWxuLkRFRkFVTFRfTUFQUElORyxuPTEwMDEscz0xMDAxLHI9MTAwNixvPTEwMDgsYT0xMDIzLGM9MTAwOSxsPWxuLkRFRkFVTFRfQU5JU09UUk9QWSxoPXdjKXtzdXBlcigpLHRoaXMuaXNUZXh0dXJlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOnNmKyt9KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLm5hbWU9IiIsdGhpcy5zb3VyY2U9bmV3IG5mKHQpLHRoaXMubWlwbWFwcz1bXSx0aGlzLm1hcHBpbmc9ZSx0aGlzLmNoYW5uZWw9MCx0aGlzLndyYXBTPW4sdGhpcy53cmFwVD1zLHRoaXMubWFnRmlsdGVyPXIsdGhpcy5taW5GaWx0ZXI9byx0aGlzLmFuaXNvdHJvcHk9bCx0aGlzLmZvcm1hdD1hLHRoaXMuaW50ZXJuYWxGb3JtYXQ9bnVsbCx0aGlzLnR5cGU9Yyx0aGlzLm9mZnNldD1uZXcgUigwLDApLHRoaXMucmVwZWF0PW5ldyBSKDEsMSksdGhpcy5jZW50ZXI9bmV3IFIoMCwwKSx0aGlzLnJvdGF0aW9uPTAsdGhpcy5tYXRyaXhBdXRvVXBkYXRlPSEwLHRoaXMubWF0cml4PW5ldyBnZSx0aGlzLmdlbmVyYXRlTWlwbWFwcz0hMCx0aGlzLnByZW11bHRpcGx5QWxwaGE9ITEsdGhpcy5mbGlwWT0hMCx0aGlzLnVucGFja0FsaWdubWVudD00LHRoaXMuY29sb3JTcGFjZT1oLHRoaXMudXNlckRhdGE9e30sdGhpcy51cGRhdGVSYW5nZXM9W10sdGhpcy52ZXJzaW9uPTAsdGhpcy5vblVwZGF0ZT1udWxsLHRoaXMucmVuZGVyVGFyZ2V0PW51bGwsdGhpcy5pc1JlbmRlclRhcmdldFRleHR1cmU9ITEsdGhpcy5pc0FycmF5VGV4dHVyZT0hISh0JiZ0LmRlcHRoJiZ0LmRlcHRoPjEpLHRoaXMucG1yZW1WZXJzaW9uPTB9Z2V0IHdpZHRoKCl7cmV0dXJuIHRoaXMuc291cmNlLmdldFNpemUocm8pLnh9Z2V0IGhlaWdodCgpe3JldHVybiB0aGlzLnNvdXJjZS5nZXRTaXplKHJvKS55fWdldCBkZXB0aCgpe3JldHVybiB0aGlzLnNvdXJjZS5nZXRTaXplKHJvKS56fWdldCBpbWFnZSgpe3JldHVybiB0aGlzLnNvdXJjZS5kYXRhfXNldCBpbWFnZSh0PW51bGwpe3RoaXMuc291cmNlLmRhdGE9dH11cGRhdGVNYXRyaXgoKXt0aGlzLm1hdHJpeC5zZXRVdlRyYW5zZm9ybSh0aGlzLm9mZnNldC54LHRoaXMub2Zmc2V0LnksdGhpcy5yZXBlYXQueCx0aGlzLnJlcGVhdC55LHRoaXMucm90YXRpb24sdGhpcy5jZW50ZXIueCx0aGlzLmNlbnRlci55KX1hZGRVcGRhdGVSYW5nZSh0LGUpe3RoaXMudXBkYXRlUmFuZ2VzLnB1c2goe3N0YXJ0OnQsY291bnQ6ZX0pfWNsZWFyVXBkYXRlUmFuZ2VzKCl7dGhpcy51cGRhdGVSYW5nZXMubGVuZ3RoPTB9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7cmV0dXJuIHRoaXMubmFtZT10Lm5hbWUsdGhpcy5zb3VyY2U9dC5zb3VyY2UsdGhpcy5taXBtYXBzPXQubWlwbWFwcy5zbGljZSgwKSx0aGlzLm1hcHBpbmc9dC5tYXBwaW5nLHRoaXMuY2hhbm5lbD10LmNoYW5uZWwsdGhpcy53cmFwUz10LndyYXBTLHRoaXMud3JhcFQ9dC53cmFwVCx0aGlzLm1hZ0ZpbHRlcj10Lm1hZ0ZpbHRlcix0aGlzLm1pbkZpbHRlcj10Lm1pbkZpbHRlcix0aGlzLmFuaXNvdHJvcHk9dC5hbmlzb3Ryb3B5LHRoaXMuZm9ybWF0PXQuZm9ybWF0LHRoaXMuaW50ZXJuYWxGb3JtYXQ9dC5pbnRlcm5hbEZvcm1hdCx0aGlzLnR5cGU9dC50eXBlLHRoaXMub2Zmc2V0LmNvcHkodC5vZmZzZXQpLHRoaXMucmVwZWF0LmNvcHkodC5yZXBlYXQpLHRoaXMuY2VudGVyLmNvcHkodC5jZW50ZXIpLHRoaXMucm90YXRpb249dC5yb3RhdGlvbix0aGlzLm1hdHJpeEF1dG9VcGRhdGU9dC5tYXRyaXhBdXRvVXBkYXRlLHRoaXMubWF0cml4LmNvcHkodC5tYXRyaXgpLHRoaXMuZ2VuZXJhdGVNaXBtYXBzPXQuZ2VuZXJhdGVNaXBtYXBzLHRoaXMucHJlbXVsdGlwbHlBbHBoYT10LnByZW11bHRpcGx5QWxwaGEsdGhpcy5mbGlwWT10LmZsaXBZLHRoaXMudW5wYWNrQWxpZ25tZW50PXQudW5wYWNrQWxpZ25tZW50LHRoaXMuY29sb3JTcGFjZT10LmNvbG9yU3BhY2UsdGhpcy5yZW5kZXJUYXJnZXQ9dC5yZW5kZXJUYXJnZXQsdGhpcy5pc1JlbmRlclRhcmdldFRleHR1cmU9dC5pc1JlbmRlclRhcmdldFRleHR1cmUsdGhpcy5pc0FycmF5VGV4dHVyZT10LmlzQXJyYXlUZXh0dXJlLHRoaXMudXNlckRhdGE9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0LnVzZXJEYXRhKSksdGhpcy5uZWVkc1VwZGF0ZT0hMCx0aGlzfXNldFZhbHVlcyh0KXtmb3IoY29uc3QgZSBpbiB0KXtjb25zdCBuPXRbZV07aWYobj09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5UZXh0dXJlLnNldFZhbHVlcygpOiBwYXJhbWV0ZXIgJyR7ZX0nIGhhcyB2YWx1ZSBvZiB1bmRlZmluZWQuYCk7Y29udGludWV9Y29uc3Qgcz10aGlzW2VdO2lmKHM9PT12b2lkIDApe2NvbnNvbGUud2FybihgVEhSRUUuVGV4dHVyZS5zZXRWYWx1ZXMoKTogcHJvcGVydHkgJyR7ZX0nIGRvZXMgbm90IGV4aXN0LmApO2NvbnRpbnVlfXMmJm4mJnMuaXNWZWN0b3IyJiZuLmlzVmVjdG9yMnx8cyYmbiYmcy5pc1ZlY3RvcjMmJm4uaXNWZWN0b3IzfHxzJiZuJiZzLmlzTWF0cml4MyYmbi5pc01hdHJpeDM/cy5jb3B5KG4pOnRoaXNbZV09bn19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciO2lmKCFlJiZ0LnRleHR1cmVzW3RoaXMudXVpZF0hPT12b2lkIDApcmV0dXJuIHQudGV4dHVyZXNbdGhpcy51dWlkXTtjb25zdCBuPXttZXRhZGF0YTp7dmVyc2lvbjo0LjcsdHlwZToiVGV4dHVyZSIsZ2VuZXJhdG9yOiJUZXh0dXJlLnRvSlNPTiJ9LHV1aWQ6dGhpcy51dWlkLG5hbWU6dGhpcy5uYW1lLGltYWdlOnRoaXMuc291cmNlLnRvSlNPTih0KS51dWlkLG1hcHBpbmc6dGhpcy5tYXBwaW5nLGNoYW5uZWw6dGhpcy5jaGFubmVsLHJlcGVhdDpbdGhpcy5yZXBlYXQueCx0aGlzLnJlcGVhdC55XSxvZmZzZXQ6W3RoaXMub2Zmc2V0LngsdGhpcy5vZmZzZXQueV0sY2VudGVyOlt0aGlzLmNlbnRlci54LHRoaXMuY2VudGVyLnldLHJvdGF0aW9uOnRoaXMucm90YXRpb24sd3JhcDpbdGhpcy53cmFwUyx0aGlzLndyYXBUXSxmb3JtYXQ6dGhpcy5mb3JtYXQsaW50ZXJuYWxGb3JtYXQ6dGhpcy5pbnRlcm5hbEZvcm1hdCx0eXBlOnRoaXMudHlwZSxjb2xvclNwYWNlOnRoaXMuY29sb3JTcGFjZSxtaW5GaWx0ZXI6dGhpcy5taW5GaWx0ZXIsbWFnRmlsdGVyOnRoaXMubWFnRmlsdGVyLGFuaXNvdHJvcHk6dGhpcy5hbmlzb3Ryb3B5LGZsaXBZOnRoaXMuZmxpcFksZ2VuZXJhdGVNaXBtYXBzOnRoaXMuZ2VuZXJhdGVNaXBtYXBzLHByZW11bHRpcGx5QWxwaGE6dGhpcy5wcmVtdWx0aXBseUFscGhhLHVucGFja0FsaWdubWVudDp0aGlzLnVucGFja0FsaWdubWVudH07cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYobi51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSxlfHwodC50ZXh0dXJlc1t0aGlzLnV1aWRdPW4pLG59ZGlzcG9zZSgpe3RoaXMuZGlzcGF0Y2hFdmVudCh7dHlwZToiZGlzcG9zZSJ9KX10cmFuc2Zvcm1Vdih0KXtpZih0aGlzLm1hcHBpbmchPT0zMDApcmV0dXJuIHQ7aWYodC5hcHBseU1hdHJpeDModGhpcy5tYXRyaXgpLHQueDwwfHx0Lng+MSlzd2l0Y2godGhpcy53cmFwUyl7Y2FzZSAxZTM6dC54PXQueC1NYXRoLmZsb29yKHQueCk7YnJlYWs7Y2FzZSAxMDAxOnQueD10Lng8MD8wOjE7YnJlYWs7Y2FzZSAxMDAyOk1hdGguYWJzKE1hdGguZmxvb3IodC54KSUyKT09PTE/dC54PU1hdGguY2VpbCh0LngpLXQueDp0Lng9dC54LU1hdGguZmxvb3IodC54KTticmVha31pZih0Lnk8MHx8dC55PjEpc3dpdGNoKHRoaXMud3JhcFQpe2Nhc2UgMWUzOnQueT10LnktTWF0aC5mbG9vcih0LnkpO2JyZWFrO2Nhc2UgMTAwMTp0Lnk9dC55PDA/MDoxO2JyZWFrO2Nhc2UgMTAwMjpNYXRoLmFicyhNYXRoLmZsb29yKHQueSklMik9PT0xP3QueT1NYXRoLmNlaWwodC55KS10Lnk6dC55PXQueS1NYXRoLmZsb29yKHQueSk7YnJlYWt9cmV0dXJuIHRoaXMuZmxpcFkmJih0Lnk9MS10LnkpLHR9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmKHRoaXMudmVyc2lvbisrLHRoaXMuc291cmNlLm5lZWRzVXBkYXRlPSEwKX1zZXQgbmVlZHNQTVJFTVVwZGF0ZSh0KXt0PT09ITAmJnRoaXMucG1yZW1WZXJzaW9uKyt9fWxuLkRFRkFVTFRfSU1BR0U9bnVsbCxsbi5ERUZBVUxUX01BUFBJTkc9MzAwLGxuLkRFRkFVTFRfQU5JU09UUk9QWT0xO2NsYXNzIFl0e2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9MSl7WXQucHJvdG90eXBlLmlzVmVjdG9yND0hMCx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzLnc9c31nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy56fXNldCB3aWR0aCh0KXt0aGlzLno9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMud31zZXQgaGVpZ2h0KHQpe3RoaXMudz10fXNldCh0LGUsbixzKXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PWUsdGhpcy56PW4sdGhpcy53PXMsdGhpc31zZXRTY2FsYXIodCl7cmV0dXJuIHRoaXMueD10LHRoaXMueT10LHRoaXMuej10LHRoaXMudz10LHRoaXN9c2V0WCh0KXtyZXR1cm4gdGhpcy54PXQsdGhpc31zZXRZKHQpe3JldHVybiB0aGlzLnk9dCx0aGlzfXNldFoodCl7cmV0dXJuIHRoaXMuej10LHRoaXN9c2V0Vyh0KXtyZXR1cm4gdGhpcy53PXQsdGhpc31zZXRDb21wb25lbnQodCxlKXtzd2l0Y2godCl7Y2FzZSAwOnRoaXMueD1lO2JyZWFrO2Nhc2UgMTp0aGlzLnk9ZTticmVhaztjYXNlIDI6dGhpcy56PWU7YnJlYWs7Y2FzZSAzOnRoaXMudz1lO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9cmV0dXJuIHRoaXN9Z2V0Q29tcG9uZW50KHQpe3N3aXRjaCh0KXtjYXNlIDA6cmV0dXJuIHRoaXMueDtjYXNlIDE6cmV0dXJuIHRoaXMueTtjYXNlIDI6cmV0dXJuIHRoaXMuejtjYXNlIDM6cmV0dXJuIHRoaXMudztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAiK3QpfX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLngsdGhpcy55LHRoaXMueix0aGlzLncpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzLno9dC56LHRoaXMudz10LnchPT12b2lkIDA/dC53OjEsdGhpc31hZGQodCl7cmV0dXJuIHRoaXMueCs9dC54LHRoaXMueSs9dC55LHRoaXMueis9dC56LHRoaXMudys9dC53LHRoaXN9YWRkU2NhbGFyKHQpe3JldHVybiB0aGlzLngrPXQsdGhpcy55Kz10LHRoaXMueis9dCx0aGlzLncrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXMuej10LnorZS56LHRoaXMudz10LncrZS53LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzLnorPXQueiplLHRoaXMudys9dC53KmUsdGhpc31zdWIodCl7cmV0dXJuIHRoaXMueC09dC54LHRoaXMueS09dC55LHRoaXMuei09dC56LHRoaXMudy09dC53LHRoaXN9c3ViU2NhbGFyKHQpe3JldHVybiB0aGlzLngtPXQsdGhpcy55LT10LHRoaXMuei09dCx0aGlzLnctPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXMuej10LnotZS56LHRoaXMudz10LnctZS53LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXMueio9dC56LHRoaXMudyo9dC53LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpcy56Kj10LHRoaXMudyo9dCx0aGlzfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXRoaXMudyxvPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1vWzBdKmUrb1s0XSpuK29bOF0qcytvWzEyXSpyLHRoaXMueT1vWzFdKmUrb1s1XSpuK29bOV0qcytvWzEzXSpyLHRoaXMuej1vWzJdKmUrb1s2XSpuK29bMTBdKnMrb1sxNF0qcix0aGlzLnc9b1szXSplK29bN10qbitvWzExXSpzK29bMTVdKnIsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXMuei89dC56LHRoaXMudy89dC53LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9c2V0QXhpc0FuZ2xlRnJvbVF1YXRlcm5pb24odCl7dGhpcy53PTIqTWF0aC5hY29zKHQudyk7Y29uc3QgZT1NYXRoLnNxcnQoMS10LncqdC53KTtyZXR1cm4gZTwxZS00Pyh0aGlzLng9MSx0aGlzLnk9MCx0aGlzLno9MCk6KHRoaXMueD10LngvZSx0aGlzLnk9dC55L2UsdGhpcy56PXQuei9lKSx0aGlzfXNldEF4aXNBbmdsZUZyb21Sb3RhdGlvbk1hdHJpeCh0KXtsZXQgZSxuLHMscjtjb25zdCBjPXQuZWxlbWVudHMsbD1jWzBdLGg9Y1s0XSx1PWNbOF0sZj1jWzFdLGQ9Y1s1XSxwPWNbOV0seT1jWzJdLG09Y1s2XSxnPWNbMTBdO2lmKE1hdGguYWJzKGgtZik8LjAxJiZNYXRoLmFicyh1LXkpPC4wMSYmTWF0aC5hYnMocC1tKTwuMDEpe2lmKE1hdGguYWJzKGgrZik8LjEmJk1hdGguYWJzKHUreSk8LjEmJk1hdGguYWJzKHArbSk8LjEmJk1hdGguYWJzKGwrZCtnLTMpPC4xKXJldHVybiB0aGlzLnNldCgxLDAsMCwwKSx0aGlzO2U9TWF0aC5QSTtjb25zdCB3PShsKzEpLzIseD0oZCsxKS8yLE09KGcrMSkvMixBPShoK2YpLzQsUz0odSt5KS80LF89KHArbSkvNDtyZXR1cm4gdz54JiZ3Pk0/dzwuMDE/KG49MCxzPS43MDcxMDY3ODEscj0uNzA3MTA2NzgxKToobj1NYXRoLnNxcnQodykscz1BL24scj1TL24pOng+TT94PC4wMT8obj0uNzA3MTA2NzgxLHM9MCxyPS43MDcxMDY3ODEpOihzPU1hdGguc3FydCh4KSxuPUEvcyxyPV8vcyk6TTwuMDE/KG49LjcwNzEwNjc4MSxzPS43MDcxMDY3ODEscj0wKToocj1NYXRoLnNxcnQoTSksbj1TL3Iscz1fL3IpLHRoaXMuc2V0KG4scyxyLGUpLHRoaXN9bGV0IGI9TWF0aC5zcXJ0KChtLXApKihtLXApKyh1LXkpKih1LXkpKyhmLWgpKihmLWgpKTtyZXR1cm4gTWF0aC5hYnMoYik8LjAwMSYmKGI9MSksdGhpcy54PShtLXApL2IsdGhpcy55PSh1LXkpL2IsdGhpcy56PShmLWgpL2IsdGhpcy53PU1hdGguYWNvcygobCtkK2ctMSkvMiksdGhpc31zZXRGcm9tTWF0cml4UG9zaXRpb24odCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9ZVsxMl0sdGhpcy55PWVbMTNdLHRoaXMuej1lWzE0XSx0aGlzLnc9ZVsxNV0sdGhpc31taW4odCl7cmV0dXJuIHRoaXMueD1NYXRoLm1pbih0aGlzLngsdC54KSx0aGlzLnk9TWF0aC5taW4odGhpcy55LHQueSksdGhpcy56PU1hdGgubWluKHRoaXMueix0LnopLHRoaXMudz1NYXRoLm1pbih0aGlzLncsdC53KSx0aGlzfW1heCh0KXtyZXR1cm4gdGhpcy54PU1hdGgubWF4KHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1heCh0aGlzLnksdC55KSx0aGlzLno9TWF0aC5tYXgodGhpcy56LHQueiksdGhpcy53PU1hdGgubWF4KHRoaXMudyx0LncpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzLno9Wih0aGlzLnosdC56LGUueiksdGhpcy53PVoodGhpcy53LHQudyxlLncpLHRoaXN9Y2xhbXBTY2FsYXIodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQsZSksdGhpcy55PVoodGhpcy55LHQsZSksdGhpcy56PVoodGhpcy56LHQsZSksdGhpcy53PVoodGhpcy53LHQsZSksdGhpc31jbGFtcExlbmd0aCh0LGUpe2NvbnN0IG49dGhpcy5sZW5ndGgoKTtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIobnx8MSkubXVsdGlwbHlTY2FsYXIoWihuLHQsZSkpfWZsb29yKCl7cmV0dXJuIHRoaXMueD1NYXRoLmZsb29yKHRoaXMueCksdGhpcy55PU1hdGguZmxvb3IodGhpcy55KSx0aGlzLno9TWF0aC5mbG9vcih0aGlzLnopLHRoaXMudz1NYXRoLmZsb29yKHRoaXMudyksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpcy56PU1hdGguY2VpbCh0aGlzLnopLHRoaXMudz1NYXRoLmNlaWwodGhpcy53KSx0aGlzfXJvdW5kKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJvdW5kKHRoaXMueCksdGhpcy55PU1hdGgucm91bmQodGhpcy55KSx0aGlzLno9TWF0aC5yb3VuZCh0aGlzLnopLHRoaXMudz1NYXRoLnJvdW5kKHRoaXMudyksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpcy56PU1hdGgudHJ1bmModGhpcy56KSx0aGlzLnc9TWF0aC50cnVuYyh0aGlzLncpLHRoaXN9bmVnYXRlKCl7cmV0dXJuIHRoaXMueD0tdGhpcy54LHRoaXMueT0tdGhpcy55LHRoaXMuej0tdGhpcy56LHRoaXMudz0tdGhpcy53LHRoaXN9ZG90KHQpe3JldHVybiB0aGlzLngqdC54K3RoaXMueSp0LnkrdGhpcy56KnQueit0aGlzLncqdC53fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56K3RoaXMudyp0aGlzLnd9bGVuZ3RoKCl7cmV0dXJuIE1hdGguc3FydCh0aGlzLngqdGhpcy54K3RoaXMueSp0aGlzLnkrdGhpcy56KnRoaXMueit0aGlzLncqdGhpcy53KX1tYW5oYXR0YW5MZW5ndGgoKXtyZXR1cm4gTWF0aC5hYnModGhpcy54KStNYXRoLmFicyh0aGlzLnkpK01hdGguYWJzKHRoaXMueikrTWF0aC5hYnModGhpcy53KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXMueis9KHQuei10aGlzLnopKmUsdGhpcy53Kz0odC53LXRoaXMudykqZSx0aGlzfWxlcnBWZWN0b3JzKHQsZSxuKXtyZXR1cm4gdGhpcy54PXQueCsoZS54LXQueCkqbix0aGlzLnk9dC55KyhlLnktdC55KSpuLHRoaXMuej10LnorKGUuei10LnopKm4sdGhpcy53PXQudysoZS53LXQudykqbix0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC54PT09dGhpcy54JiZ0Lnk9PT10aGlzLnkmJnQuej09PXRoaXMueiYmdC53PT09dGhpcy53fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpcy56PXRbZSsyXSx0aGlzLnc9dFtlKzNdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy54LHRbZSsxXT10aGlzLnksdFtlKzJdPXRoaXMueix0W2UrM109dGhpcy53LHR9ZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLng9dC5nZXRYKGUpLHRoaXMueT10LmdldFkoZSksdGhpcy56PXQuZ2V0WihlKSx0aGlzLnc9dC5nZXRXKGUpLHRoaXN9cmFuZG9tKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJhbmRvbSgpLHRoaXMueT1NYXRoLnJhbmRvbSgpLHRoaXMuej1NYXRoLnJhbmRvbSgpLHRoaXMudz1NYXRoLnJhbmRvbSgpLHRoaXN9KltTeW1ib2wuaXRlcmF0b3JdKCl7eWllbGQgdGhpcy54LHlpZWxkIHRoaXMueSx5aWVsZCB0aGlzLnoseWllbGQgdGhpcy53fX1jbGFzcyBndHtjb25zdHJ1Y3Rvcih0PW5ldyBUKDEvMCwxLzAsMS8wKSxlPW5ldyBUKC0xLzAsLTEvMCwtMS8wKSl7dGhpcy5pc0JveDM9ITAsdGhpcy5taW49dCx0aGlzLm1heD1lfXNldCh0LGUpe3JldHVybiB0aGlzLm1pbi5jb3B5KHQpLHRoaXMubWF4LmNvcHkoZSksdGhpc31zZXRGcm9tQXJyYXkodCl7dGhpcy5tYWtlRW1wdHkoKTtmb3IobGV0IGU9MCxuPXQubGVuZ3RoO2U8bjtlKz0zKXRoaXMuZXhwYW5kQnlQb2ludChjZS5mcm9tQXJyYXkodCxlKSk7cmV0dXJuIHRoaXN9c2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSh0KXt0aGlzLm1ha2VFbXB0eSgpO2ZvcihsZXQgZT0wLG49dC5jb3VudDtlPG47ZSsrKXRoaXMuZXhwYW5kQnlQb2ludChjZS5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSkpO3JldHVybiB0aGlzfXNldEZyb21Qb2ludHModCl7dGhpcy5tYWtlRW1wdHkoKTtmb3IobGV0IGU9MCxuPXQubGVuZ3RoO2U8bjtlKyspdGhpcy5leHBhbmRCeVBvaW50KHRbZV0pO3JldHVybiB0aGlzfXNldEZyb21DZW50ZXJBbmRTaXplKHQsZSl7Y29uc3Qgbj1jZS5jb3B5KGUpLm11bHRpcGx5U2NhbGFyKC41KTtyZXR1cm4gdGhpcy5taW4uY29weSh0KS5zdWIobiksdGhpcy5tYXguY29weSh0KS5hZGQobiksdGhpc31zZXRGcm9tT2JqZWN0KHQsZT0hMSl7cmV0dXJuIHRoaXMubWFrZUVtcHR5KCksdGhpcy5leHBhbmRCeU9iamVjdCh0LGUpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLm1pbi5jb3B5KHQubWluKSx0aGlzLm1heC5jb3B5KHQubWF4KSx0aGlzfW1ha2VFbXB0eSgpe3JldHVybiB0aGlzLm1pbi54PXRoaXMubWluLnk9dGhpcy5taW4uej0xLzAsdGhpcy5tYXgueD10aGlzLm1heC55PXRoaXMubWF4Lno9LTEvMCx0aGlzfWlzRW1wdHkoKXtyZXR1cm4gdGhpcy5tYXgueDx0aGlzLm1pbi54fHx0aGlzLm1heC55PHRoaXMubWluLnl8fHRoaXMubWF4Lno8dGhpcy5taW4uen1nZXRDZW50ZXIodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3Quc2V0KDAsMCwwKTp0LmFkZFZlY3RvcnModGhpcy5taW4sdGhpcy5tYXgpLm11bHRpcGx5U2NhbGFyKC41KX1nZXRTaXplKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90LnNldCgwLDAsMCk6dC5zdWJWZWN0b3JzKHRoaXMubWF4LHRoaXMubWluKX1leHBhbmRCeVBvaW50KHQpe3JldHVybiB0aGlzLm1pbi5taW4odCksdGhpcy5tYXgubWF4KHQpLHRoaXN9ZXhwYW5kQnlWZWN0b3IodCl7cmV0dXJuIHRoaXMubWluLnN1Yih0KSx0aGlzLm1heC5hZGQodCksdGhpc31leHBhbmRCeVNjYWxhcih0KXtyZXR1cm4gdGhpcy5taW4uYWRkU2NhbGFyKC10KSx0aGlzLm1heC5hZGRTY2FsYXIodCksdGhpc31leHBhbmRCeU9iamVjdCh0LGU9ITEpe3QudXBkYXRlV29ybGRNYXRyaXgoITEsITEpO2NvbnN0IG49dC5nZW9tZXRyeTtpZihuIT09dm9pZCAwKXtjb25zdCByPW4uZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpO2lmKGU9PT0hMCYmciE9PXZvaWQgMCYmdC5pc0luc3RhbmNlZE1lc2ghPT0hMClmb3IobGV0IG89MCxhPXIuY291bnQ7bzxhO28rKyl0LmlzTWVzaD09PSEwP3QuZ2V0VmVydGV4UG9zaXRpb24obyxjZSk6Y2UuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLG8pLGNlLmFwcGx5TWF0cml4NCh0Lm1hdHJpeFdvcmxkKSx0aGlzLmV4cGFuZEJ5UG9pbnQoY2UpO2Vsc2UgdC5ib3VuZGluZ0JveCE9PXZvaWQgMD8odC5ib3VuZGluZ0JveD09PW51bGwmJnQuY29tcHV0ZUJvdW5kaW5nQm94KCksYXMuY29weSh0LmJvdW5kaW5nQm94KSk6KG4uYm91bmRpbmdCb3g9PT1udWxsJiZuLmNvbXB1dGVCb3VuZGluZ0JveCgpLGFzLmNvcHkobi5ib3VuZGluZ0JveCkpLGFzLmFwcGx5TWF0cml4NCh0Lm1hdHJpeFdvcmxkKSx0aGlzLnVuaW9uKGFzKX1jb25zdCBzPXQuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXRoaXMuZXhwYW5kQnlPYmplY3Qoc1tyXSxlKTtyZXR1cm4gdGhpc31jb250YWluc1BvaW50KHQpe3JldHVybiB0Lng+PXRoaXMubWluLngmJnQueDw9dGhpcy5tYXgueCYmdC55Pj10aGlzLm1pbi55JiZ0Lnk8PXRoaXMubWF4LnkmJnQuej49dGhpcy5taW4ueiYmdC56PD10aGlzLm1heC56fWNvbnRhaW5zQm94KHQpe3JldHVybiB0aGlzLm1pbi54PD10Lm1pbi54JiZ0Lm1heC54PD10aGlzLm1heC54JiZ0aGlzLm1pbi55PD10Lm1pbi55JiZ0Lm1heC55PD10aGlzLm1heC55JiZ0aGlzLm1pbi56PD10Lm1pbi56JiZ0Lm1heC56PD10aGlzLm1heC56fWdldFBhcmFtZXRlcih0LGUpe3JldHVybiBlLnNldCgodC54LXRoaXMubWluLngpLyh0aGlzLm1heC54LXRoaXMubWluLngpLCh0LnktdGhpcy5taW4ueSkvKHRoaXMubWF4LnktdGhpcy5taW4ueSksKHQuei10aGlzLm1pbi56KS8odGhpcy5tYXguei10aGlzLm1pbi56KSl9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdC5tYXgueD49dGhpcy5taW4ueCYmdC5taW4ueDw9dGhpcy5tYXgueCYmdC5tYXgueT49dGhpcy5taW4ueSYmdC5taW4ueTw9dGhpcy5tYXgueSYmdC5tYXguej49dGhpcy5taW4ueiYmdC5taW4uejw9dGhpcy5tYXguen1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0aGlzLmNsYW1wUG9pbnQodC5jZW50ZXIsY2UpLGNlLmRpc3RhbmNlVG9TcXVhcmVkKHQuY2VudGVyKTw9dC5yYWRpdXMqdC5yYWRpdXN9aW50ZXJzZWN0c1BsYW5lKHQpe2xldCBlLG47cmV0dXJuIHQubm9ybWFsLng+MD8oZT10Lm5vcm1hbC54KnRoaXMubWluLngsbj10Lm5vcm1hbC54KnRoaXMubWF4LngpOihlPXQubm9ybWFsLngqdGhpcy5tYXgueCxuPXQubm9ybWFsLngqdGhpcy5taW4ueCksdC5ub3JtYWwueT4wPyhlKz10Lm5vcm1hbC55KnRoaXMubWluLnksbis9dC5ub3JtYWwueSp0aGlzLm1heC55KTooZSs9dC5ub3JtYWwueSp0aGlzLm1heC55LG4rPXQubm9ybWFsLnkqdGhpcy5taW4ueSksdC5ub3JtYWwuej4wPyhlKz10Lm5vcm1hbC56KnRoaXMubWluLnosbis9dC5ub3JtYWwueip0aGlzLm1heC56KTooZSs9dC5ub3JtYWwueip0aGlzLm1heC56LG4rPXQubm9ybWFsLnoqdGhpcy5taW4ueiksZTw9LXQuY29uc3RhbnQmJm4+PS10LmNvbnN0YW50fWludGVyc2VjdHNUcmlhbmdsZSh0KXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4hMTt0aGlzLmdldENlbnRlcih4aSksY3Muc3ViVmVjdG9ycyh0aGlzLm1heCx4aSksTm4uc3ViVmVjdG9ycyh0LmEseGkpLFJuLnN1YlZlY3RvcnModC5iLHhpKSxMbi5zdWJWZWN0b3JzKHQuYyx4aSksWGUuc3ViVmVjdG9ycyhSbixObiksSmUuc3ViVmVjdG9ycyhMbixSbiksaG4uc3ViVmVjdG9ycyhObixMbik7bGV0IGU9WzAsLVhlLnosWGUueSwwLC1KZS56LEplLnksMCwtaG4ueixobi55LFhlLnosMCwtWGUueCxKZS56LDAsLUplLngsaG4ueiwwLC1obi54LC1YZS55LFhlLngsMCwtSmUueSxKZS54LDAsLWhuLnksaG4ueCwwXTtyZXR1cm4hb28oZSxObixSbixMbixjcyl8fChlPVsxLDAsMCwwLDEsMCwwLDAsMV0sIW9vKGUsTm4sUm4sTG4sY3MpKT8hMToobHMuY3Jvc3NWZWN0b3JzKFhlLEplKSxlPVtscy54LGxzLnksbHMuel0sb28oZSxObixSbixMbixjcykpfWNsYW1wUG9pbnQodCxlKXtyZXR1cm4gZS5jb3B5KHQpLmNsYW1wKHRoaXMubWluLHRoaXMubWF4KX1kaXN0YW5jZVRvUG9pbnQodCl7cmV0dXJuIHRoaXMuY2xhbXBQb2ludCh0LGNlKS5kaXN0YW5jZVRvKHQpfWdldEJvdW5kaW5nU3BoZXJlKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90Lm1ha2VFbXB0eSgpOih0aGlzLmdldENlbnRlcih0LmNlbnRlciksdC5yYWRpdXM9dGhpcy5nZXRTaXplKGNlKS5sZW5ndGgoKSouNSksdH1pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMubWluLm1heCh0Lm1pbiksdGhpcy5tYXgubWluKHQubWF4KSx0aGlzLmlzRW1wdHkoKSYmdGhpcy5tYWtlRW1wdHkoKSx0aGlzfXVuaW9uKHQpe3JldHVybiB0aGlzLm1pbi5taW4odC5taW4pLHRoaXMubWF4Lm1heCh0Lm1heCksdGhpc31hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMuaXNFbXB0eSgpP3RoaXM6KHZlWzBdLnNldCh0aGlzLm1pbi54LHRoaXMubWluLnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzFdLnNldCh0aGlzLm1pbi54LHRoaXMubWluLnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHZlWzJdLnNldCh0aGlzLm1pbi54LHRoaXMubWF4LnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzNdLnNldCh0aGlzLm1pbi54LHRoaXMubWF4LnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHZlWzRdLnNldCh0aGlzLm1heC54LHRoaXMubWluLnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzVdLnNldCh0aGlzLm1heC54LHRoaXMubWluLnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHZlWzZdLnNldCh0aGlzLm1heC54LHRoaXMubWF4LnksdGhpcy5taW4ueikuYXBwbHlNYXRyaXg0KHQpLHZlWzddLnNldCh0aGlzLm1heC54LHRoaXMubWF4LnksdGhpcy5tYXgueikuYXBwbHlNYXRyaXg0KHQpLHRoaXMuc2V0RnJvbVBvaW50cyh2ZSksdGhpcyl9dHJhbnNsYXRlKHQpe3JldHVybiB0aGlzLm1pbi5hZGQodCksdGhpcy5tYXguYWRkKHQpLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lm1pbi5lcXVhbHModGhpcy5taW4pJiZ0Lm1heC5lcXVhbHModGhpcy5tYXgpfXRvSlNPTigpe3JldHVybnttaW46dGhpcy5taW4udG9BcnJheSgpLG1heDp0aGlzLm1heC50b0FycmF5KCl9fWZyb21KU09OKHQpe3JldHVybiB0aGlzLm1pbi5mcm9tQXJyYXkodC5taW4pLHRoaXMubWF4LmZyb21BcnJheSh0Lm1heCksdGhpc319Y29uc3QgdmU9W25ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBUXSxjZT1uZXcgVCxhcz1uZXcgZ3QsTm49bmV3IFQsUm49bmV3IFQsTG49bmV3IFQsWGU9bmV3IFQsSmU9bmV3IFQsaG49bmV3IFQseGk9bmV3IFQsY3M9bmV3IFQsbHM9bmV3IFQsdW49bmV3IFQ7ZnVuY3Rpb24gb28oaSx0LGUsbixzKXtmb3IobGV0IHI9MCxvPWkubGVuZ3RoLTM7cjw9bztyKz0zKXt1bi5mcm9tQXJyYXkoaSxyKTtjb25zdCBhPXMueCpNYXRoLmFicyh1bi54KStzLnkqTWF0aC5hYnModW4ueSkrcy56Kk1hdGguYWJzKHVuLnopLGM9dC5kb3QodW4pLGw9ZS5kb3QodW4pLGg9bi5kb3QodW4pO2lmKE1hdGgubWF4KC1NYXRoLm1heChjLGwsaCksTWF0aC5taW4oYyxsLGgpKT5hKXJldHVybiExfXJldHVybiEwfWNvbnN0IHJmPW5ldyBndCx3aT1uZXcgVCxhbz1uZXcgVDtjbGFzcyBjb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9LTEpe3RoaXMuaXNTcGhlcmU9ITAsdGhpcy5jZW50ZXI9dCx0aGlzLnJhZGl1cz1lfXNldCh0LGUpe3JldHVybiB0aGlzLmNlbnRlci5jb3B5KHQpLHRoaXMucmFkaXVzPWUsdGhpc31zZXRGcm9tUG9pbnRzKHQsZSl7Y29uc3Qgbj10aGlzLmNlbnRlcjtlIT09dm9pZCAwP24uY29weShlKTpyZi5zZXRGcm9tUG9pbnRzKHQpLmdldENlbnRlcihuKTtsZXQgcz0wO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKylzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZCh0W3JdKSk7cmV0dXJuIHRoaXMucmFkaXVzPU1hdGguc3FydChzKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuY2VudGVyLmNvcHkodC5jZW50ZXIpLHRoaXMucmFkaXVzPXQucmFkaXVzLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLnJhZGl1czwwfW1ha2VFbXB0eSgpe3JldHVybiB0aGlzLmNlbnRlci5zZXQoMCwwLDApLHRoaXMucmFkaXVzPS0xLHRoaXN9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmNlbnRlcik8PXRoaXMucmFkaXVzKnRoaXMucmFkaXVzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKS10aGlzLnJhZGl1c31pbnRlcnNlY3RzU3BoZXJlKHQpe2NvbnN0IGU9dGhpcy5yYWRpdXMrdC5yYWRpdXM7cmV0dXJuIHQuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuY2VudGVyKTw9ZSplfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1NwaGVyZSh0aGlzKX1pbnRlcnNlY3RzUGxhbmUodCl7cmV0dXJuIE1hdGguYWJzKHQuZGlzdGFuY2VUb1BvaW50KHRoaXMuY2VudGVyKSk8PXRoaXMucmFkaXVzfWNsYW1wUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHQpO3JldHVybiBlLmNvcHkodCksbj50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyYmKGUuc3ViKHRoaXMuY2VudGVyKS5ub3JtYWxpemUoKSxlLm11bHRpcGx5U2NhbGFyKHRoaXMucmFkaXVzKS5hZGQodGhpcy5jZW50ZXIpKSxlfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT8odC5tYWtlRW1wdHkoKSx0KToodC5zZXQodGhpcy5jZW50ZXIsdGhpcy5jZW50ZXIpLHQuZXhwYW5kQnlTY2FsYXIodGhpcy5yYWRpdXMpLHQpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYXBwbHlNYXRyaXg0KHQpLHRoaXMucmFkaXVzPXRoaXMucmFkaXVzKnQuZ2V0TWF4U2NhbGVPbkF4aXMoKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYWRkKHQpLHRoaXN9ZXhwYW5kQnlQb2ludCh0KXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4gdGhpcy5jZW50ZXIuY29weSh0KSx0aGlzLnJhZGl1cz0wLHRoaXM7d2kuc3ViVmVjdG9ycyh0LHRoaXMuY2VudGVyKTtjb25zdCBlPXdpLmxlbmd0aFNxKCk7aWYoZT50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyl7Y29uc3Qgbj1NYXRoLnNxcnQoZSkscz0obi10aGlzLnJhZGl1cykqLjU7dGhpcy5jZW50ZXIuYWRkU2NhbGVkVmVjdG9yKHdpLHMvbiksdGhpcy5yYWRpdXMrPXN9cmV0dXJuIHRoaXN9dW5pb24odCl7cmV0dXJuIHQuaXNFbXB0eSgpP3RoaXM6dGhpcy5pc0VtcHR5KCk/KHRoaXMuY29weSh0KSx0aGlzKToodGhpcy5jZW50ZXIuZXF1YWxzKHQuY2VudGVyKT09PSEwP3RoaXMucmFkaXVzPU1hdGgubWF4KHRoaXMucmFkaXVzLHQucmFkaXVzKTooYW8uc3ViVmVjdG9ycyh0LmNlbnRlcix0aGlzLmNlbnRlcikuc2V0TGVuZ3RoKHQucmFkaXVzKSx0aGlzLmV4cGFuZEJ5UG9pbnQod2kuY29weSh0LmNlbnRlcikuYWRkKGFvKSksdGhpcy5leHBhbmRCeVBvaW50KHdpLmNvcHkodC5jZW50ZXIpLnN1YihhbykpKSx0aGlzKX1lcXVhbHModCl7cmV0dXJuIHQuY2VudGVyLmVxdWFscyh0aGlzLmNlbnRlcikmJnQucmFkaXVzPT09dGhpcy5yYWRpdXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfXRvSlNPTigpe3JldHVybntyYWRpdXM6dGhpcy5yYWRpdXMsY2VudGVyOnRoaXMuY2VudGVyLnRvQXJyYXkoKX19ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMucmFkaXVzPXQucmFkaXVzLHRoaXMuY2VudGVyLmZyb21BcnJheSh0LmNlbnRlciksdGhpc319Y29uc3QgemU9bmV3IFQsbG89bmV3IFQsaHM9bmV3IFQsWWU9bmV3IFQsaG89bmV3IFQsdXM9bmV3IFQsdW89bmV3IFQ7Y2xhc3MgZm97Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBUKDAsMCwtMSkpe3RoaXMub3JpZ2luPXQsdGhpcy5kaXJlY3Rpb249ZX1zZXQodCxlKXtyZXR1cm4gdGhpcy5vcmlnaW4uY29weSh0KSx0aGlzLmRpcmVjdGlvbi5jb3B5KGUpLHRoaXN9Y29weSh0KXtyZXR1cm4gdGhpcy5vcmlnaW4uY29weSh0Lm9yaWdpbiksdGhpcy5kaXJlY3Rpb24uY29weSh0LmRpcmVjdGlvbiksdGhpc31hdCh0LGUpe3JldHVybiBlLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbix0KX1sb29rQXQodCl7cmV0dXJuIHRoaXMuZGlyZWN0aW9uLmNvcHkodCkuc3ViKHRoaXMub3JpZ2luKS5ub3JtYWxpemUoKSx0aGlzfXJlY2FzdCh0KXtyZXR1cm4gdGhpcy5vcmlnaW4uY29weSh0aGlzLmF0KHQsemUpKSx0aGlzfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlKXtlLnN1YlZlY3RvcnModCx0aGlzLm9yaWdpbik7Y29uc3Qgbj1lLmRvdCh0aGlzLmRpcmVjdGlvbik7cmV0dXJuIG48MD9lLmNvcHkodGhpcy5vcmlnaW4pOmUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLG4pfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VTcVRvUG9pbnQodCkpfWRpc3RhbmNlU3FUb1BvaW50KHQpe2NvbnN0IGU9emUuc3ViVmVjdG9ycyh0LHRoaXMub3JpZ2luKS5kb3QodGhpcy5kaXJlY3Rpb24pO3JldHVybiBlPDA/dGhpcy5vcmlnaW4uZGlzdGFuY2VUb1NxdWFyZWQodCk6KHplLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbixlKSx6ZS5kaXN0YW5jZVRvU3F1YXJlZCh0KSl9ZGlzdGFuY2VTcVRvU2VnbWVudCh0LGUsbixzKXtsby5jb3B5KHQpLmFkZChlKS5tdWx0aXBseVNjYWxhciguNSksaHMuY29weShlKS5zdWIodCkubm9ybWFsaXplKCksWWUuY29weSh0aGlzLm9yaWdpbikuc3ViKGxvKTtjb25zdCByPXQuZGlzdGFuY2VUbyhlKSouNSxvPS10aGlzLmRpcmVjdGlvbi5kb3QoaHMpLGE9WWUuZG90KHRoaXMuZGlyZWN0aW9uKSxjPS1ZZS5kb3QoaHMpLGw9WWUubGVuZ3RoU3EoKSxoPU1hdGguYWJzKDEtbypvKTtsZXQgdSxmLGQscDtpZihoPjApaWYodT1vKmMtYSxmPW8qYS1jLHA9cipoLHU+PTApaWYoZj49LXApaWYoZjw9cCl7Y29uc3QgeT0xL2g7dSo9eSxmKj15LGQ9dSoodStvKmYrMiphKStmKihvKnUrZisyKmMpK2x9ZWxzZSBmPXIsdT1NYXRoLm1heCgwLC0obypmK2EpKSxkPS11KnUrZiooZisyKmMpK2w7ZWxzZSBmPS1yLHU9TWF0aC5tYXgoMCwtKG8qZithKSksZD0tdSp1K2YqKGYrMipjKStsO2Vsc2UgZjw9LXA/KHU9TWF0aC5tYXgoMCwtKC1vKnIrYSkpLGY9dT4wPy1yOk1hdGgubWluKE1hdGgubWF4KC1yLC1jKSxyKSxkPS11KnUrZiooZisyKmMpK2wpOmY8PXA/KHU9MCxmPU1hdGgubWluKE1hdGgubWF4KC1yLC1jKSxyKSxkPWYqKGYrMipjKStsKToodT1NYXRoLm1heCgwLC0obypyK2EpKSxmPXU+MD9yOk1hdGgubWluKE1hdGgubWF4KC1yLC1jKSxyKSxkPS11KnUrZiooZisyKmMpK2wpO2Vsc2UgZj1vPjA/LXI6cix1PU1hdGgubWF4KDAsLShvKmYrYSkpLGQ9LXUqdStmKihmKzIqYykrbDtyZXR1cm4gbiYmbi5jb3B5KHRoaXMub3JpZ2luKS5hZGRTY2FsZWRWZWN0b3IodGhpcy5kaXJlY3Rpb24sdSkscyYmcy5jb3B5KGxvKS5hZGRTY2FsZWRWZWN0b3IoaHMsZiksZH1pbnRlcnNlY3RTcGhlcmUodCxlKXt6ZS5zdWJWZWN0b3JzKHQuY2VudGVyLHRoaXMub3JpZ2luKTtjb25zdCBuPXplLmRvdCh0aGlzLmRpcmVjdGlvbikscz16ZS5kb3QoemUpLW4qbixyPXQucmFkaXVzKnQucmFkaXVzO2lmKHM+cilyZXR1cm4gbnVsbDtjb25zdCBvPU1hdGguc3FydChyLXMpLGE9bi1vLGM9bitvO3JldHVybiBjPDA/bnVsbDphPDA/dGhpcy5hdChjLGUpOnRoaXMuYXQoYSxlKX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0LnJhZGl1czwwPyExOnRoaXMuZGlzdGFuY2VTcVRvUG9pbnQodC5jZW50ZXIpPD10LnJhZGl1cyp0LnJhZGl1c31kaXN0YW5jZVRvUGxhbmUodCl7Y29uc3QgZT10Lm5vcm1hbC5kb3QodGhpcy5kaXJlY3Rpb24pO2lmKGU9PT0wKXJldHVybiB0LmRpc3RhbmNlVG9Qb2ludCh0aGlzLm9yaWdpbik9PT0wPzA6bnVsbDtjb25zdCBuPS0odGhpcy5vcmlnaW4uZG90KHQubm9ybWFsKSt0LmNvbnN0YW50KS9lO3JldHVybiBuPj0wP246bnVsbH1pbnRlcnNlY3RQbGFuZSh0LGUpe2NvbnN0IG49dGhpcy5kaXN0YW5jZVRvUGxhbmUodCk7cmV0dXJuIG49PT1udWxsP251bGw6dGhpcy5hdChuLGUpfWludGVyc2VjdHNQbGFuZSh0KXtjb25zdCBlPXQuZGlzdGFuY2VUb1BvaW50KHRoaXMub3JpZ2luKTtyZXR1cm4gZT09PTB8fHQubm9ybWFsLmRvdCh0aGlzLmRpcmVjdGlvbikqZTwwfWludGVyc2VjdEJveCh0LGUpe2xldCBuLHMscixvLGEsYztjb25zdCBsPTEvdGhpcy5kaXJlY3Rpb24ueCxoPTEvdGhpcy5kaXJlY3Rpb24ueSx1PTEvdGhpcy5kaXJlY3Rpb24ueixmPXRoaXMub3JpZ2luO3JldHVybiBsPj0wPyhuPSh0Lm1pbi54LWYueCkqbCxzPSh0Lm1heC54LWYueCkqbCk6KG49KHQubWF4LngtZi54KSpsLHM9KHQubWluLngtZi54KSpsKSxoPj0wPyhyPSh0Lm1pbi55LWYueSkqaCxvPSh0Lm1heC55LWYueSkqaCk6KHI9KHQubWF4LnktZi55KSpoLG89KHQubWluLnktZi55KSpoKSxuPm98fHI+c3x8KChyPm58fGlzTmFOKG4pKSYmKG49ciksKG88c3x8aXNOYU4ocykpJiYocz1vKSx1Pj0wPyhhPSh0Lm1pbi56LWYueikqdSxjPSh0Lm1heC56LWYueikqdSk6KGE9KHQubWF4LnotZi56KSp1LGM9KHQubWluLnotZi56KSp1KSxuPmN8fGE+cyl8fCgoYT5ufHxuIT09bikmJihuPWEpLChjPHN8fHMhPT1zKSYmKHM9YyksczwwKT9udWxsOnRoaXMuYXQobj49MD9uOnMsZSl9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdGhpcy5pbnRlcnNlY3RCb3godCx6ZSkhPT1udWxsfWludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHMscil7aG8uc3ViVmVjdG9ycyhlLHQpLHVzLnN1YlZlY3RvcnMobix0KSx1by5jcm9zc1ZlY3RvcnMoaG8sdXMpO2xldCBvPXRoaXMuZGlyZWN0aW9uLmRvdCh1byksYTtpZihvPjApe2lmKHMpcmV0dXJuIG51bGw7YT0xfWVsc2UgaWYobzwwKWE9LTEsbz0tbztlbHNlIHJldHVybiBudWxsO1llLnN1YlZlY3RvcnModGhpcy5vcmlnaW4sdCk7Y29uc3QgYz1hKnRoaXMuZGlyZWN0aW9uLmRvdCh1cy5jcm9zc1ZlY3RvcnMoWWUsdXMpKTtpZihjPDApcmV0dXJuIG51bGw7Y29uc3QgbD1hKnRoaXMuZGlyZWN0aW9uLmRvdChoby5jcm9zcyhZZSkpO2lmKGw8MHx8YytsPm8pcmV0dXJuIG51bGw7Y29uc3QgaD0tYSpZZS5kb3QodW8pO3JldHVybiBoPDA/bnVsbDp0aGlzLmF0KGgvbyxyKX1hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMub3JpZ2luLmFwcGx5TWF0cml4NCh0KSx0aGlzLmRpcmVjdGlvbi50cmFuc2Zvcm1EaXJlY3Rpb24odCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQub3JpZ2luLmVxdWFscyh0aGlzLm9yaWdpbikmJnQuZGlyZWN0aW9uLmVxdWFscyh0aGlzLmRpcmVjdGlvbil9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX1jbGFzcyBzdHtjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtzdC5wcm90b3R5cGUuaXNNYXRyaXg0PSEwLHRoaXMuZWxlbWVudHM9WzEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDFdLHQhPT12b2lkIDAmJnRoaXMuc2V0KHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pfXNldCh0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtjb25zdCBnPXRoaXMuZWxlbWVudHM7cmV0dXJuIGdbMF09dCxnWzRdPWUsZ1s4XT1uLGdbMTJdPXMsZ1sxXT1yLGdbNV09byxnWzldPWEsZ1sxM109YyxnWzJdPWwsZ1s2XT1oLGdbMTBdPXUsZ1sxNF09ZixnWzNdPWQsZ1s3XT1wLGdbMTFdPXksZ1sxNV09bSx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDEpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHN0KCkuZnJvbUFycmF5KHRoaXMuZWxlbWVudHMpfWNvcHkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVswXT1uWzBdLGVbMV09blsxXSxlWzJdPW5bMl0sZVszXT1uWzNdLGVbNF09bls0XSxlWzVdPW5bNV0sZVs2XT1uWzZdLGVbN109bls3XSxlWzhdPW5bOF0sZVs5XT1uWzldLGVbMTBdPW5bMTBdLGVbMTFdPW5bMTFdLGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLGVbMTVdPW5bMTVdLHRoaXN9Y29weVBvc2l0aW9uKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7cmV0dXJuIGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLHRoaXN9c2V0RnJvbU1hdHJpeDModCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLnNldChlWzBdLGVbM10sZVs2XSwwLGVbMV0sZVs0XSxlWzddLDAsZVsyXSxlWzVdLGVbOF0sMCwwLDAsMCwxKSx0aGlzfWV4dHJhY3RCYXNpcyh0LGUsbil7cmV0dXJuIHQuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDApLGUuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDEpLG4uc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDIpLHRoaXN9bWFrZUJhc2lzKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodC54LGUueCxuLngsMCx0LnksZS55LG4ueSwwLHQueixlLnosbi56LDAsMCwwLDAsMSksdGhpc31leHRyYWN0Um90YXRpb24odCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cyxzPTEvT24uc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLHI9MS9Pbi5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCksbz0xL09uLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gZVswXT1uWzBdKnMsZVsxXT1uWzFdKnMsZVsyXT1uWzJdKnMsZVszXT0wLGVbNF09bls0XSpyLGVbNV09bls1XSpyLGVbNl09bls2XSpyLGVbN109MCxlWzhdPW5bOF0qbyxlWzldPW5bOV0qbyxlWzEwXT1uWzEwXSpvLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21FdWxlcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10Lngscz10Lnkscj10Lnosbz1NYXRoLmNvcyhuKSxhPU1hdGguc2luKG4pLGM9TWF0aC5jb3MocyksbD1NYXRoLnNpbihzKSxoPU1hdGguY29zKHIpLHU9TWF0aC5zaW4ocik7aWYodC5vcmRlcj09PSJYWVoiKXtjb25zdCBmPW8qaCxkPW8qdSxwPWEqaCx5PWEqdTtlWzBdPWMqaCxlWzRdPS1jKnUsZVs4XT1sLGVbMV09ZCtwKmwsZVs1XT1mLXkqbCxlWzldPS1hKmMsZVsyXT15LWYqbCxlWzZdPXArZCpsLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWVhaIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mK3kqYSxlWzRdPXAqYS1kLGVbOF09bypsLGVbMV09byp1LGVbNV09bypoLGVbOV09LWEsZVsyXT1kKmEtcCxlWzZdPXkrZiphLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWlhZIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mLXkqYSxlWzRdPS1vKnUsZVs4XT1wK2QqYSxlWzFdPWQrcCphLGVbNV09bypoLGVbOV09eS1mKmEsZVsyXT0tbypsLGVbNl09YSxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IlpZWCIpe2NvbnN0IGY9bypoLGQ9byp1LHA9YSpoLHk9YSp1O2VbMF09YypoLGVbNF09cCpsLWQsZVs4XT1mKmwreSxlWzFdPWMqdSxlWzVdPXkqbCtmLGVbOV09ZCpsLXAsZVsyXT0tbCxlWzZdPWEqYyxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IllaWCIpe2NvbnN0IGY9bypjLGQ9bypsLHA9YSpjLHk9YSpsO2VbMF09YypoLGVbNF09eS1mKnUsZVs4XT1wKnUrZCxlWzFdPXUsZVs1XT1vKmgsZVs5XT0tYSpoLGVbMl09LWwqaCxlWzZdPWQqdStwLGVbMTBdPWYteSp1fWVsc2UgaWYodC5vcmRlcj09PSJYWlkiKXtjb25zdCBmPW8qYyxkPW8qbCxwPWEqYyx5PWEqbDtlWzBdPWMqaCxlWzRdPS11LGVbOF09bCpoLGVbMV09Zip1K3ksZVs1XT1vKmgsZVs5XT1kKnUtcCxlWzJdPXAqdS1kLGVbNl09YSpoLGVbMTBdPXkqdStmfXJldHVybiBlWzNdPTAsZVs3XT0wLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLmNvbXBvc2Uob2YsdCxhZil9bG9va0F0KHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuICR0LnN1YlZlY3RvcnModCxlKSwkdC5sZW5ndGhTcSgpPT09MCYmKCR0Lno9MSksJHQubm9ybWFsaXplKCksamUuY3Jvc3NWZWN0b3JzKG4sJHQpLGplLmxlbmd0aFNxKCk9PT0wJiYoTWF0aC5hYnMobi56KT09PTE/JHQueCs9MWUtNDokdC56Kz0xZS00LCR0Lm5vcm1hbGl6ZSgpLGplLmNyb3NzVmVjdG9ycyhuLCR0KSksamUubm9ybWFsaXplKCksZnMuY3Jvc3NWZWN0b3JzKCR0LGplKSxzWzBdPWplLngsc1s0XT1mcy54LHNbOF09JHQueCxzWzFdPWplLnksc1s1XT1mcy55LHNbOV09JHQueSxzWzJdPWplLnosc1s2XT1mcy56LHNbMTBdPSR0LnosdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0LHRoaXMpfW11bHRpcGx5TWF0cmljZXModCxlKXtjb25zdCBuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzLHI9dGhpcy5lbGVtZW50cyxvPW5bMF0sYT1uWzRdLGM9bls4XSxsPW5bMTJdLGg9blsxXSx1PW5bNV0sZj1uWzldLGQ9blsxM10scD1uWzJdLHk9bls2XSxtPW5bMTBdLGc9blsxNF0sYj1uWzNdLHc9bls3XSx4PW5bMTFdLE09blsxNV0sQT1zWzBdLFM9c1s0XSxfPXNbOF0sRT1zWzEyXSx6PXNbMV0sdj1zWzVdLEM9c1s5XSxQPXNbMTNdLEY9c1syXSxCPXNbNl0sST1zWzEwXSxrPXNbMTRdLEQ9c1szXSxVPXNbN10saj1zWzExXSxkdD1zWzE1XTtyZXR1cm4gclswXT1vKkErYSp6K2MqRitsKkQscls0XT1vKlMrYSp2K2MqQitsKlUscls4XT1vKl8rYSpDK2MqSStsKmosclsxMl09bypFK2EqUCtjKmsrbCpkdCxyWzFdPWgqQSt1KnorZipGK2QqRCxyWzVdPWgqUyt1KnYrZipCK2QqVSxyWzldPWgqXyt1KkMrZipJK2QqaixyWzEzXT1oKkUrdSpQK2YqaytkKmR0LHJbMl09cCpBK3kqeittKkYrZypELHJbNl09cCpTK3kqdittKkIrZypVLHJbMTBdPXAqXyt5KkMrbSpJK2cqaixyWzE0XT1wKkUreSpQK20qaytnKmR0LHJbM109YipBK3cqeit4KkYrTSpELHJbN109YipTK3cqdit4KkIrTSpVLHJbMTFdPWIqXyt3KkMreCpJK00qaixyWzE1XT1iKkUrdypQK3gqaytNKmR0LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiBlWzBdKj10LGVbNF0qPXQsZVs4XSo9dCxlWzEyXSo9dCxlWzFdKj10LGVbNV0qPXQsZVs5XSo9dCxlWzEzXSo9dCxlWzJdKj10LGVbNl0qPXQsZVsxMF0qPXQsZVsxNF0qPXQsZVszXSo9dCxlWzddKj10LGVbMTFdKj10LGVbMTVdKj10LHRoaXN9ZGV0ZXJtaW5hbnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFs0XSxzPXRbOF0scj10WzEyXSxvPXRbMV0sYT10WzVdLGM9dFs5XSxsPXRbMTNdLGg9dFsyXSx1PXRbNl0sZj10WzEwXSxkPXRbMTRdLHA9dFszXSx5PXRbN10sbT10WzExXSxnPXRbMTVdO3JldHVybiBwKigrcipjKnUtcypsKnUtciphKmYrbipsKmYrcyphKmQtbipjKmQpK3kqKCtlKmMqZC1lKmwqZityKm8qZi1zKm8qZCtzKmwqaC1yKmMqaCkrbSooK2UqbCp1LWUqYSpkLXIqbyp1K24qbypkK3IqYSpoLW4qbCpoKStnKigtcyphKmgtZSpjKnUrZSphKmYrcypvKnUtbipvKmYrbipjKmgpfXRyYW5zcG9zZSgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cztsZXQgZTtyZXR1cm4gZT10WzFdLHRbMV09dFs0XSx0WzRdPWUsZT10WzJdLHRbMl09dFs4XSx0WzhdPWUsZT10WzZdLHRbNl09dFs5XSx0WzldPWUsZT10WzNdLHRbM109dFsxMl0sdFsxMl09ZSxlPXRbN10sdFs3XT10WzEzXSx0WzEzXT1lLGU9dFsxMV0sdFsxMV09dFsxNF0sdFsxNF09ZSx0aGlzfXNldFBvc2l0aW9uKHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuIHQuaXNWZWN0b3IzPyhzWzEyXT10Lngsc1sxM109dC55LHNbMTRdPXQueik6KHNbMTJdPXQsc1sxM109ZSxzWzE0XT1uKSx0aGlzfWludmVydCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSx1PXRbOV0sZj10WzEwXSxkPXRbMTFdLHA9dFsxMl0seT10WzEzXSxtPXRbMTRdLGc9dFsxNV0sYj11Km0qbC15KmYqbCt5KmMqZC1hKm0qZC11KmMqZythKmYqZyx3PXAqZipsLWgqbSpsLXAqYypkK28qbSpkK2gqYypnLW8qZipnLHg9aCp5KmwtcCp1KmwrcCphKmQtbyp5KmQtaCphKmcrbyp1KmcsTT1wKnUqYy1oKnkqYy1wKmEqZitvKnkqZitoKmEqbS1vKnUqbSxBPWUqYituKncrcyp4K3IqTTtpZihBPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCk7Y29uc3QgUz0xL0E7cmV0dXJuIHRbMF09YipTLHRbMV09KHkqZipyLXUqbSpyLXkqcypkK24qbSpkK3UqcypnLW4qZipnKSpTLHRbMl09KGEqbSpyLXkqYypyK3kqcypsLW4qbSpsLWEqcypnK24qYypnKSpTLHRbM109KHUqYypyLWEqZipyLXUqcypsK24qZipsK2EqcypkLW4qYypkKSpTLHRbNF09dypTLHRbNV09KGgqbSpyLXAqZipyK3AqcypkLWUqbSpkLWgqcypnK2UqZipnKSpTLHRbNl09KHAqYypyLW8qbSpyLXAqcypsK2UqbSpsK28qcypnLWUqYypnKSpTLHRbN109KG8qZipyLWgqYypyK2gqcypsLWUqZipsLW8qcypkK2UqYypkKSpTLHRbOF09eCpTLHRbOV09KHAqdSpyLWgqeSpyLXAqbipkK2UqeSpkK2gqbipnLWUqdSpnKSpTLHRbMTBdPShvKnkqci1wKmEqcitwKm4qbC1lKnkqbC1vKm4qZytlKmEqZykqUyx0WzExXT0oaCphKnItbyp1KnItaCpuKmwrZSp1KmwrbypuKmQtZSphKmQpKlMsdFsxMl09TSpTLHRbMTNdPShoKnkqcy1wKnUqcytwKm4qZi1lKnkqZi1oKm4qbStlKnUqbSkqUyx0WzE0XT0ocCphKnMtbyp5KnMtcCpuKmMrZSp5KmMrbypuKm0tZSphKm0pKlMsdFsxNV09KG8qdSpzLWgqYSpzK2gqbipjLWUqdSpjLW8qbipmK2UqYSpmKSpTLHRoaXN9c2NhbGUodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC54LHM9dC55LHI9dC56O3JldHVybiBlWzBdKj1uLGVbNF0qPXMsZVs4XSo9cixlWzFdKj1uLGVbNV0qPXMsZVs5XSo9cixlWzJdKj1uLGVbNl0qPXMsZVsxMF0qPXIsZVszXSo9bixlWzddKj1zLGVbMTFdKj1yLHRoaXN9Z2V0TWF4U2NhbGVPbkF4aXMoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdKnRbMF0rdFsxXSp0WzFdK3RbMl0qdFsyXSxuPXRbNF0qdFs0XSt0WzVdKnRbNV0rdFs2XSp0WzZdLHM9dFs4XSp0WzhdK3RbOV0qdFs5XSt0WzEwXSp0WzEwXTtyZXR1cm4gTWF0aC5zcXJ0KE1hdGgubWF4KGUsbixzKSl9bWFrZVRyYW5zbGF0aW9uKHQsZSxuKXtyZXR1cm4gdC5pc1ZlY3RvcjM/dGhpcy5zZXQoMSwwLDAsdC54LDAsMSwwLHQueSwwLDAsMSx0LnosMCwwLDAsMSk6dGhpcy5zZXQoMSwwLDAsdCwwLDEsMCxlLDAsMCwxLG4sMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25YKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwwLGUsLW4sMCwwLG4sZSwwLDAsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uWSh0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsMCxuLDAsMCwxLDAsMCwtbiwwLGUsMCwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbloodCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldChlLC1uLDAsMCxuLGUsMCwwLDAsMCwxLDAsMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25BeGlzKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9MS1uLG89dC54LGE9dC55LGM9dC56LGw9cipvLGg9ciphO3JldHVybiB0aGlzLnNldChsKm8rbixsKmEtcypjLGwqYytzKmEsMCxsKmErcypjLGgqYStuLGgqYy1zKm8sMCxsKmMtcyphLGgqYytzKm8scipjKmMrbiwwLDAsMCwwLDEpLHRoaXN9bWFrZVNjYWxlKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodCwwLDAsMCwwLGUsMCwwLDAsMCxuLDAsMCwwLDAsMSksdGhpc31tYWtlU2hlYXIodCxlLG4scyxyLG8pe3JldHVybiB0aGlzLnNldCgxLG4sciwwLHQsMSxvLDAsZSxzLDEsMCwwLDAsMCwxKSx0aGlzfWNvbXBvc2UodCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cyxyPWUuX3gsbz1lLl95LGE9ZS5feixjPWUuX3csbD1yK3IsaD1vK28sdT1hK2EsZj1yKmwsZD1yKmgscD1yKnUseT1vKmgsbT1vKnUsZz1hKnUsYj1jKmwsdz1jKmgseD1jKnUsTT1uLngsQT1uLnksUz1uLno7cmV0dXJuIHNbMF09KDEtKHkrZykpKk0sc1sxXT0oZCt4KSpNLHNbMl09KHAtdykqTSxzWzNdPTAsc1s0XT0oZC14KSpBLHNbNV09KDEtKGYrZykpKkEsc1s2XT0obStiKSpBLHNbN109MCxzWzhdPShwK3cpKlMsc1s5XT0obS1iKSpTLHNbMTBdPSgxLShmK3kpKSpTLHNbMTFdPTAsc1sxMl09dC54LHNbMTNdPXQueSxzWzE0XT10Lnosc1sxNV09MSx0aGlzfWRlY29tcG9zZSh0LGUsbil7Y29uc3Qgcz10aGlzLmVsZW1lbnRzO2xldCByPU9uLnNldChzWzBdLHNbMV0sc1syXSkubGVuZ3RoKCk7Y29uc3Qgbz1Pbi5zZXQoc1s0XSxzWzVdLHNbNl0pLmxlbmd0aCgpLGE9T24uc2V0KHNbOF0sc1s5XSxzWzEwXSkubGVuZ3RoKCk7dGhpcy5kZXRlcm1pbmFudCgpPDAmJihyPS1yKSx0Lng9c1sxMl0sdC55PXNbMTNdLHQuej1zWzE0XSxsZS5jb3B5KHRoaXMpO2NvbnN0IGw9MS9yLGg9MS9vLHU9MS9hO3JldHVybiBsZS5lbGVtZW50c1swXSo9bCxsZS5lbGVtZW50c1sxXSo9bCxsZS5lbGVtZW50c1syXSo9bCxsZS5lbGVtZW50c1s0XSo9aCxsZS5lbGVtZW50c1s1XSo9aCxsZS5lbGVtZW50c1s2XSo9aCxsZS5lbGVtZW50c1s4XSo9dSxsZS5lbGVtZW50c1s5XSo9dSxsZS5lbGVtZW50c1sxMF0qPXUsZS5zZXRGcm9tUm90YXRpb25NYXRyaXgobGUpLG4ueD1yLG4ueT1vLG4uej1hLHRoaXN9bWFrZVBlcnNwZWN0aXZlKHQsZSxuLHMscixvLGE9MmUzKXtjb25zdCBjPXRoaXMuZWxlbWVudHMsbD0yKnIvKGUtdCksaD0yKnIvKG4tcyksdT0oZSt0KS8oZS10KSxmPShuK3MpLyhuLXMpO2xldCBkLHA7aWYoYT09PTJlMylkPS0obytyKS8oby1yKSxwPS0yKm8qci8oby1yKTtlbHNlIGlmKGE9PT0yMDAxKWQ9LW8vKG8tcikscD0tbypyLyhvLXIpO2Vsc2UgdGhyb3cgbmV3IEVycm9yKCJUSFJFRS5NYXRyaXg0Lm1ha2VQZXJzcGVjdGl2ZSgpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPWwsY1s0XT0wLGNbOF09dSxjWzEyXT0wLGNbMV09MCxjWzVdPWgsY1s5XT1mLGNbMTNdPTAsY1syXT0wLGNbNl09MCxjWzEwXT1kLGNbMTRdPXAsY1szXT0wLGNbN109MCxjWzExXT0tMSxjWzE1XT0wLHRoaXN9bWFrZU9ydGhvZ3JhcGhpYyh0LGUsbixzLHIsbyxhPTJlMyl7Y29uc3QgYz10aGlzLmVsZW1lbnRzLGw9MS8oZS10KSxoPTEvKG4tcyksdT0xLyhvLXIpLGY9KGUrdCkqbCxkPShuK3MpKmg7bGV0IHAseTtpZihhPT09MmUzKXA9KG8rcikqdSx5PS0yKnU7ZWxzZSBpZihhPT09MjAwMSlwPXIqdSx5PS0xKnU7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIlRIUkVFLk1hdHJpeDQubWFrZU9ydGhvZ3JhcGhpYygpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPTIqbCxjWzRdPTAsY1s4XT0wLGNbMTJdPS1mLGNbMV09MCxjWzVdPTIqaCxjWzldPTAsY1sxM109LWQsY1syXT0wLGNbNl09MCxjWzEwXT15LGNbMTRdPS1wLGNbM109MCxjWzddPTAsY1sxMV09MCxjWzE1XT0xLHRoaXN9ZXF1YWxzKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7Zm9yKGxldCBzPTA7czwxNjtzKyspaWYoZVtzXSE9PW5bc10pcmV0dXJuITE7cmV0dXJuITB9ZnJvbUFycmF5KHQsZT0wKXtmb3IobGV0IG49MDtuPDE2O24rKyl0aGlzLmVsZW1lbnRzW25dPXRbbitlXTtyZXR1cm4gdGhpc310b0FycmF5KHQ9W10sZT0wKXtjb25zdCBuPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbZV09blswXSx0W2UrMV09blsxXSx0W2UrMl09blsyXSx0W2UrM109blszXSx0W2UrNF09bls0XSx0W2UrNV09bls1XSx0W2UrNl09bls2XSx0W2UrN109bls3XSx0W2UrOF09bls4XSx0W2UrOV09bls5XSx0W2UrMTBdPW5bMTBdLHRbZSsxMV09blsxMV0sdFtlKzEyXT1uWzEyXSx0W2UrMTNdPW5bMTNdLHRbZSsxNF09blsxNF0sdFtlKzE1XT1uWzE1XSx0fX1jb25zdCBPbj1uZXcgVCxsZT1uZXcgc3Qsb2Y9bmV3IFQoMCwwLDApLGFmPW5ldyBUKDEsMSwxKSxqZT1uZXcgVCxmcz1uZXcgVCwkdD1uZXcgVCxFYz1uZXcgc3QsUGM9bmV3IGdpO2NsYXNzIGJpe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9YmkuREVGQVVMVF9PUkRFUil7dGhpcy5pc0V1bGVyPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXN9Z2V0IHgoKXtyZXR1cm4gdGhpcy5feH1zZXQgeCh0KXt0aGlzLl94PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB5KCl7cmV0dXJuIHRoaXMuX3l9c2V0IHkodCl7dGhpcy5feT10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeigpe3JldHVybiB0aGlzLl96fXNldCB6KHQpe3RoaXMuX3o9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IG9yZGVyKCl7cmV0dXJuIHRoaXMuX29yZGVyfXNldCBvcmRlcih0KXt0aGlzLl9vcmRlcj10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scz10aGlzLl9vcmRlcil7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXMsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5feCx0aGlzLl95LHRoaXMuX3osdGhpcy5fb3JkZXIpfWNvcHkodCl7cmV0dXJuIHRoaXMuX3g9dC5feCx0aGlzLl95PXQuX3ksdGhpcy5fej10Ll96LHRoaXMuX29yZGVyPXQuX29yZGVyLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0LGU9dGhpcy5fb3JkZXIsbj0hMCl7Y29uc3Qgcz10LmVsZW1lbnRzLHI9c1swXSxvPXNbNF0sYT1zWzhdLGM9c1sxXSxsPXNbNV0saD1zWzldLHU9c1syXSxmPXNbNl0sZD1zWzEwXTtzd2l0Y2goZSl7Y2FzZSJYWVoiOnRoaXMuX3k9TWF0aC5hc2luKFooYSwtMSwxKSksTWF0aC5hYnMoYSk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMigtaCxkKSx0aGlzLl96PU1hdGguYXRhbjIoLW8scikpOih0aGlzLl94PU1hdGguYXRhbjIoZixsKSx0aGlzLl96PTApO2JyZWFrO2Nhc2UiWVhaIjp0aGlzLl94PU1hdGguYXNpbigtWihoLC0xLDEpKSxNYXRoLmFicyhoKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKGEsZCksdGhpcy5fej1NYXRoLmF0YW4yKGMsbCkpOih0aGlzLl95PU1hdGguYXRhbjIoLXUsciksdGhpcy5fej0wKTticmVhaztjYXNlIlpYWSI6dGhpcy5feD1NYXRoLmFzaW4oWihmLC0xLDEpKSxNYXRoLmFicyhmKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKC11LGQpLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxsKSk6KHRoaXMuX3k9MCx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3k9TWF0aC5hc2luKC1aKHUsLTEsMSkpLE1hdGguYWJzKHUpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoZixkKSx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk6KHRoaXMuX3g9MCx0aGlzLl96PU1hdGguYXRhbjIoLW8sbCkpO2JyZWFrO2Nhc2UiWVpYIjp0aGlzLl96PU1hdGguYXNpbihaKGMsLTEsMSkpLE1hdGguYWJzKGMpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoLWgsbCksdGhpcy5feT1NYXRoLmF0YW4yKC11LHIpKToodGhpcy5feD0wLHRoaXMuX3k9TWF0aC5hdGFuMihhLGQpKTticmVhaztjYXNlIlhaWSI6dGhpcy5fej1NYXRoLmFzaW4oLVoobywtMSwxKSksTWF0aC5hYnMobyk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMihmLGwpLHRoaXMuX3k9TWF0aC5hdGFuMihhLHIpKToodGhpcy5feD1NYXRoLmF0YW4yKC1oLGQpLHRoaXMuX3k9MCk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkV1bGVyOiAuc2V0RnJvbVJvdGF0aW9uTWF0cml4KCkgZW5jb3VudGVyZWQgYW4gdW5rbm93biBvcmRlcjogIitlKX1yZXR1cm4gdGhpcy5fb3JkZXI9ZSxuPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21RdWF0ZXJuaW9uKHQsZSxuKXtyZXR1cm4gRWMubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCksdGhpcy5zZXRGcm9tUm90YXRpb25NYXRyaXgoRWMsZSxuKX1zZXRGcm9tVmVjdG9yMyh0LGU9dGhpcy5fb3JkZXIpe3JldHVybiB0aGlzLnNldCh0LngsdC55LHQueixlKX1yZW9yZGVyKHQpe3JldHVybiBQYy5zZXRGcm9tRXVsZXIodGhpcyksdGhpcy5zZXRGcm9tUXVhdGVybmlvbihQYyx0KX1lcXVhbHModCl7cmV0dXJuIHQuX3g9PT10aGlzLl94JiZ0Ll95PT09dGhpcy5feSYmdC5fej09PXRoaXMuX3omJnQuX29yZGVyPT09dGhpcy5fb3JkZXJ9ZnJvbUFycmF5KHQpe3JldHVybiB0aGlzLl94PXRbMF0sdGhpcy5feT10WzFdLHRoaXMuX3o9dFsyXSx0WzNdIT09dm9pZCAwJiYodGhpcy5fb3JkZXI9dFszXSksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy5feCx0W2UrMV09dGhpcy5feSx0W2UrMl09dGhpcy5feix0W2UrM109dGhpcy5fb3JkZXIsdH1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX29yZGVyfX1iaS5ERUZBVUxUX09SREVSPSJYWVoiO2NsYXNzIGNme2NvbnN0cnVjdG9yKCl7dGhpcy5tYXNrPTF9c2V0KHQpe3RoaXMubWFzaz0oMTw8dHwwKT4+PjB9ZW5hYmxlKHQpe3RoaXMubWFza3w9MTw8dHwwfWVuYWJsZUFsbCgpe3RoaXMubWFzaz0tMX10b2dnbGUodCl7dGhpcy5tYXNrXj0xPDx0fDB9ZGlzYWJsZSh0KXt0aGlzLm1hc2smPX4oMTw8dHwwKX1kaXNhYmxlQWxsKCl7dGhpcy5tYXNrPTB9dGVzdCh0KXtyZXR1cm4odGhpcy5tYXNrJnQubWFzaykhPT0wfWlzRW5hYmxlZCh0KXtyZXR1cm4odGhpcy5tYXNrJigxPDx0fDApKSE9PTB9fWxldCBsZj0wO2NvbnN0IENjPW5ldyBULERuPW5ldyBnaSxUZT1uZXcgc3QsZHM9bmV3IFQsTWk9bmV3IFQsaGY9bmV3IFQsdWY9bmV3IGdpLEJjPW5ldyBUKDEsMCwwKSxGYz1uZXcgVCgwLDEsMCksSWM9bmV3IFQoMCwwLDEpLGtjPXt0eXBlOiJhZGRlZCJ9LGZmPXt0eXBlOiJyZW1vdmVkIn0sJG49e3R5cGU6ImNoaWxkYWRkZWQiLGNoaWxkOm51bGx9LHBvPXt0eXBlOiJjaGlsZHJlbW92ZWQiLGNoaWxkOm51bGx9O2NsYXNzIEVlIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNPYmplY3QzRD0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpsZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iT2JqZWN0M0QiLHRoaXMucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbj1bXSx0aGlzLnVwPUVlLkRFRkFVTFRfVVAuY2xvbmUoKTtjb25zdCB0PW5ldyBULGU9bmV3IGJpLG49bmV3IGdpLHM9bmV3IFQoMSwxLDEpO2Z1bmN0aW9uIHIoKXtuLnNldEZyb21FdWxlcihlLCExKX1mdW5jdGlvbiBvKCl7ZS5zZXRGcm9tUXVhdGVybmlvbihuLHZvaWQgMCwhMSl9ZS5fb25DaGFuZ2Uociksbi5fb25DaGFuZ2UobyksT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcyx7cG9zaXRpb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOnR9LHJvdGF0aW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTplfSxxdWF0ZXJuaW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTpufSxzY2FsZTp7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITAsdmFsdWU6c30sbW9kZWxWaWV3TWF0cml4Ont2YWx1ZTpuZXcgc3R9LG5vcm1hbE1hdHJpeDp7dmFsdWU6bmV3IGdlfX0pLHRoaXMubWF0cml4PW5ldyBzdCx0aGlzLm1hdHJpeFdvcmxkPW5ldyBzdCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9RWUuREVGQVVMVF9NQVRSSVhfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9RWUuREVGQVVMVF9NQVRSSVhfV09STERfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSExLHRoaXMubGF5ZXJzPW5ldyBjZix0aGlzLnZpc2libGU9ITAsdGhpcy5jYXN0U2hhZG93PSExLHRoaXMucmVjZWl2ZVNoYWRvdz0hMSx0aGlzLmZydXN0dW1DdWxsZWQ9ITAsdGhpcy5yZW5kZXJPcmRlcj0wLHRoaXMuYW5pbWF0aW9ucz1bXSx0aGlzLmN1c3RvbURlcHRoTWF0ZXJpYWw9dm9pZCAwLHRoaXMuY3VzdG9tRGlzdGFuY2VNYXRlcmlhbD12b2lkIDAsdGhpcy51c2VyRGF0YT17fX1vbkJlZm9yZVNoYWRvdygpe31vbkFmdGVyU2hhZG93KCl7fW9uQmVmb3JlUmVuZGVyKCl7fW9uQWZ0ZXJSZW5kZXIoKXt9YXBwbHlNYXRyaXg0KHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSx0aGlzLm1hdHJpeC5wcmVtdWx0aXBseSh0KSx0aGlzLm1hdHJpeC5kZWNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSl9YXBwbHlRdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkodCksdGhpc31zZXRSb3RhdGlvbkZyb21BeGlzQW5nbGUodCxlKXt0aGlzLnF1YXRlcm5pb24uc2V0RnJvbUF4aXNBbmdsZSh0LGUpfXNldFJvdGF0aW9uRnJvbUV1bGVyKHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tRXVsZXIodCwhMCl9c2V0Um90YXRpb25Gcm9tTWF0cml4KHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgodCl9c2V0Um90YXRpb25Gcm9tUXVhdGVybmlvbih0KXt0aGlzLnF1YXRlcm5pb24uY29weSh0KX1yb3RhdGVPbkF4aXModCxlKXtyZXR1cm4gRG4uc2V0RnJvbUF4aXNBbmdsZSh0LGUpLHRoaXMucXVhdGVybmlvbi5tdWx0aXBseShEbiksdGhpc31yb3RhdGVPbldvcmxkQXhpcyh0LGUpe3JldHVybiBEbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KERuKSx0aGlzfXJvdGF0ZVgodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEJjLHQpfXJvdGF0ZVkodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEZjLHQpfXJvdGF0ZVoodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEljLHQpfXRyYW5zbGF0ZU9uQXhpcyh0LGUpe3JldHVybiBDYy5jb3B5KHQpLmFwcGx5UXVhdGVybmlvbih0aGlzLnF1YXRlcm5pb24pLHRoaXMucG9zaXRpb24uYWRkKENjLm11bHRpcGx5U2NhbGFyKGUpKSx0aGlzfXRyYW5zbGF0ZVgodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEJjLHQpfXRyYW5zbGF0ZVkodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEZjLHQpfXRyYW5zbGF0ZVoodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEljLHQpfWxvY2FsVG9Xb3JsZCh0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdC5hcHBseU1hdHJpeDQodGhpcy5tYXRyaXhXb3JsZCl9d29ybGRUb0xvY2FsKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0LmFwcGx5TWF0cml4NChUZS5jb3B5KHRoaXMubWF0cml4V29ybGQpLmludmVydCgpKX1sb29rQXQodCxlLG4pe3QuaXNWZWN0b3IzP2RzLmNvcHkodCk6ZHMuc2V0KHQsZSxuKTtjb25zdCBzPXRoaXMucGFyZW50O3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLE1pLnNldEZyb21NYXRyaXhQb3NpdGlvbih0aGlzLm1hdHJpeFdvcmxkKSx0aGlzLmlzQ2FtZXJhfHx0aGlzLmlzTGlnaHQ/VGUubG9va0F0KE1pLGRzLHRoaXMudXApOlRlLmxvb2tBdChkcyxNaSx0aGlzLnVwKSx0aGlzLnF1YXRlcm5pb24uc2V0RnJvbVJvdGF0aW9uTWF0cml4KFRlKSxzJiYoVGUuZXh0cmFjdFJvdGF0aW9uKHMubWF0cml4V29ybGQpLERuLnNldEZyb21Sb3RhdGlvbk1hdHJpeChUZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KERuLmludmVydCgpKSl9YWRkKHQpe2lmKGFyZ3VtZW50cy5sZW5ndGg+MSl7Zm9yKGxldCBlPTA7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl0aGlzLmFkZChhcmd1bWVudHNbZV0pO3JldHVybiB0aGlzfXJldHVybiB0PT09dGhpcz8oY29uc29sZS5lcnJvcigiVEhSRUUuT2JqZWN0M0QuYWRkOiBvYmplY3QgY2FuJ3QgYmUgYWRkZWQgYXMgYSBjaGlsZCBvZiBpdHNlbGYuIix0KSx0aGlzKToodCYmdC5pc09iamVjdDNEPyh0LnJlbW92ZUZyb21QYXJlbnQoKSx0LnBhcmVudD10aGlzLHRoaXMuY2hpbGRyZW4ucHVzaCh0KSx0LmRpc3BhdGNoRXZlbnQoa2MpLCRuLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KCRuKSwkbi5jaGlsZD1udWxsKTpjb25zb2xlLmVycm9yKCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBub3QgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuT2JqZWN0M0QuIix0KSx0aGlzKX1yZW1vdmUodCl7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IobGV0IG49MDtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXRoaXMucmVtb3ZlKGFyZ3VtZW50c1tuXSk7cmV0dXJuIHRoaXN9Y29uc3QgZT10aGlzLmNoaWxkcmVuLmluZGV4T2YodCk7cmV0dXJuIGUhPT0tMSYmKHQucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbi5zcGxpY2UoZSwxKSx0LmRpc3BhdGNoRXZlbnQoZmYpLHBvLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KHBvKSxwby5jaGlsZD1udWxsKSx0aGlzfXJlbW92ZUZyb21QYXJlbnQoKXtjb25zdCB0PXRoaXMucGFyZW50O3JldHVybiB0IT09bnVsbCYmdC5yZW1vdmUodGhpcyksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLnJlbW92ZSguLi50aGlzLmNoaWxkcmVuKX1hdHRhY2godCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLFRlLmNvcHkodGhpcy5tYXRyaXhXb3JsZCkuaW52ZXJ0KCksdC5wYXJlbnQhPT1udWxsJiYodC5wYXJlbnQudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLFRlLm11bHRpcGx5KHQucGFyZW50Lm1hdHJpeFdvcmxkKSksdC5hcHBseU1hdHJpeDQoVGUpLHQucmVtb3ZlRnJvbVBhcmVudCgpLHQucGFyZW50PXRoaXMsdGhpcy5jaGlsZHJlbi5wdXNoKHQpLHQudXBkYXRlV29ybGRNYXRyaXgoITEsITApLHQuZGlzcGF0Y2hFdmVudChrYyksJG4uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQoJG4pLCRuLmNoaWxkPW51bGwsdGhpc31nZXRPYmplY3RCeUlkKHQpe3JldHVybiB0aGlzLmdldE9iamVjdEJ5UHJvcGVydHkoImlkIix0KX1nZXRPYmplY3RCeU5hbWUodCl7cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlQcm9wZXJ0eSgibmFtZSIsdCl9Z2V0T2JqZWN0QnlQcm9wZXJ0eSh0LGUpe2lmKHRoaXNbdF09PT1lKXJldHVybiB0aGlzO2ZvcihsZXQgbj0wLHM9dGhpcy5jaGlsZHJlbi5sZW5ndGg7bjxzO24rKyl7Y29uc3Qgbz10aGlzLmNoaWxkcmVuW25dLmdldE9iamVjdEJ5UHJvcGVydHkodCxlKTtpZihvIT09dm9pZCAwKXJldHVybiBvfX1nZXRPYmplY3RzQnlQcm9wZXJ0eSh0LGUsbj1bXSl7dGhpc1t0XT09PWUmJm4ucHVzaCh0aGlzKTtjb25zdCBzPXRoaXMuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXNbcl0uZ2V0T2JqZWN0c0J5UHJvcGVydHkodCxlLG4pO3JldHVybiBufWdldFdvcmxkUG9zaXRpb24odCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHQuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKHRoaXMubWF0cml4V29ybGQpfWdldFdvcmxkUXVhdGVybmlvbih0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdGhpcy5tYXRyaXhXb3JsZC5kZWNvbXBvc2UoTWksdCxoZiksdH1nZXRXb3JsZFNjYWxlKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZShNaSx1Zix0KSx0fWdldFdvcmxkRGlyZWN0aW9uKHQpe3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpO2NvbnN0IGU9dGhpcy5tYXRyaXhXb3JsZC5lbGVtZW50cztyZXR1cm4gdC5zZXQoZVs4XSxlWzldLGVbMTBdKS5ub3JtYWxpemUoKX1yYXljYXN0KCl7fXRyYXZlcnNlKHQpe3QodGhpcyk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnRyYXZlcnNlKHQpfXRyYXZlcnNlVmlzaWJsZSh0KXtpZih0aGlzLnZpc2libGU9PT0hMSlyZXR1cm47dCh0aGlzKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udHJhdmVyc2VWaXNpYmxlKHQpfXRyYXZlcnNlQW5jZXN0b3JzKHQpe2NvbnN0IGU9dGhpcy5wYXJlbnQ7ZSE9PW51bGwmJih0KGUpLGUudHJhdmVyc2VBbmNlc3RvcnModCkpfXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LmNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSksdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSEwfXVwZGF0ZU1hdHJpeFdvcmxkKHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSwodGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlfHx0KSYmKHRoaXMubWF0cml4V29ybGRBdXRvVXBkYXRlPT09ITAmJih0aGlzLnBhcmVudD09PW51bGw/dGhpcy5tYXRyaXhXb3JsZC5jb3B5KHRoaXMubWF0cml4KTp0aGlzLm1hdHJpeFdvcmxkLm11bHRpcGx5TWF0cmljZXModGhpcy5wYXJlbnQubWF0cml4V29ybGQsdGhpcy5tYXRyaXgpKSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITEsdD0hMCk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnVwZGF0ZU1hdHJpeFdvcmxkKHQpfXVwZGF0ZVdvcmxkTWF0cml4KHQsZSl7Y29uc3Qgbj10aGlzLnBhcmVudDtpZih0PT09ITAmJm4hPT1udWxsJiZuLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeEF1dG9VcGRhdGUmJnRoaXMudXBkYXRlTWF0cml4KCksdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9PT0hMCYmKHRoaXMucGFyZW50PT09bnVsbD90aGlzLm1hdHJpeFdvcmxkLmNvcHkodGhpcy5tYXRyaXgpOnRoaXMubWF0cml4V29ybGQubXVsdGlwbHlNYXRyaWNlcyh0aGlzLnBhcmVudC5tYXRyaXhXb3JsZCx0aGlzLm1hdHJpeCkpLGU9PT0hMCl7Y29uc3Qgcz10aGlzLmNoaWxkcmVuO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLnVwZGF0ZVdvcmxkTWF0cml4KCExLCEwKX19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciLG49e307ZSYmKHQ9e2dlb21ldHJpZXM6e30sbWF0ZXJpYWxzOnt9LHRleHR1cmVzOnt9LGltYWdlczp7fSxzaGFwZXM6e30sc2tlbGV0b25zOnt9LGFuaW1hdGlvbnM6e30sbm9kZXM6e319LG4ubWV0YWRhdGE9e3ZlcnNpb246NC43LHR5cGU6Ik9iamVjdCIsZ2VuZXJhdG9yOiJPYmplY3QzRC50b0pTT04ifSk7Y29uc3Qgcz17fTtzLnV1aWQ9dGhpcy51dWlkLHMudHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJihzLm5hbWU9dGhpcy5uYW1lKSx0aGlzLmNhc3RTaGFkb3c9PT0hMCYmKHMuY2FzdFNoYWRvdz0hMCksdGhpcy5yZWNlaXZlU2hhZG93PT09ITAmJihzLnJlY2VpdmVTaGFkb3c9ITApLHRoaXMudmlzaWJsZT09PSExJiYocy52aXNpYmxlPSExKSx0aGlzLmZydXN0dW1DdWxsZWQ9PT0hMSYmKHMuZnJ1c3R1bUN1bGxlZD0hMSksdGhpcy5yZW5kZXJPcmRlciE9PTAmJihzLnJlbmRlck9yZGVyPXRoaXMucmVuZGVyT3JkZXIpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYocy51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSxzLmxheWVycz10aGlzLmxheWVycy5tYXNrLHMubWF0cml4PXRoaXMubWF0cml4LnRvQXJyYXkoKSxzLnVwPXRoaXMudXAudG9BcnJheSgpLHRoaXMubWF0cml4QXV0b1VwZGF0ZT09PSExJiYocy5tYXRyaXhBdXRvVXBkYXRlPSExKSx0aGlzLmlzSW5zdGFuY2VkTWVzaCYmKHMudHlwZT0iSW5zdGFuY2VkTWVzaCIscy5jb3VudD10aGlzLmNvdW50LHMuaW5zdGFuY2VNYXRyaXg9dGhpcy5pbnN0YW5jZU1hdHJpeC50b0pTT04oKSx0aGlzLmluc3RhbmNlQ29sb3IhPT1udWxsJiYocy5pbnN0YW5jZUNvbG9yPXRoaXMuaW5zdGFuY2VDb2xvci50b0pTT04oKSkpLHRoaXMuaXNCYXRjaGVkTWVzaCYmKHMudHlwZT0iQmF0Y2hlZE1lc2giLHMucGVyT2JqZWN0RnJ1c3R1bUN1bGxlZD10aGlzLnBlck9iamVjdEZydXN0dW1DdWxsZWQscy5zb3J0T2JqZWN0cz10aGlzLnNvcnRPYmplY3RzLHMuZHJhd1Jhbmdlcz10aGlzLl9kcmF3UmFuZ2VzLHMucmVzZXJ2ZWRSYW5nZXM9dGhpcy5fcmVzZXJ2ZWRSYW5nZXMscy5nZW9tZXRyeUluZm89dGhpcy5fZ2VvbWV0cnlJbmZvLm1hcChhPT5aZShGdCh7fSxhKSx7Ym91bmRpbmdCb3g6YS5ib3VuZGluZ0JveD9hLmJvdW5kaW5nQm94LnRvSlNPTigpOnZvaWQgMCxib3VuZGluZ1NwaGVyZTphLmJvdW5kaW5nU3BoZXJlP2EuYm91bmRpbmdTcGhlcmUudG9KU09OKCk6dm9pZCAwfSkpLHMuaW5zdGFuY2VJbmZvPXRoaXMuX2luc3RhbmNlSW5mby5tYXAoYT0+RnQoe30sYSkpLHMuYXZhaWxhYmxlSW5zdGFuY2VJZHM9dGhpcy5fYXZhaWxhYmxlSW5zdGFuY2VJZHMuc2xpY2UoKSxzLmF2YWlsYWJsZUdlb21ldHJ5SWRzPXRoaXMuX2F2YWlsYWJsZUdlb21ldHJ5SWRzLnNsaWNlKCkscy5uZXh0SW5kZXhTdGFydD10aGlzLl9uZXh0SW5kZXhTdGFydCxzLm5leHRWZXJ0ZXhTdGFydD10aGlzLl9uZXh0VmVydGV4U3RhcnQscy5nZW9tZXRyeUNvdW50PXRoaXMuX2dlb21ldHJ5Q291bnQscy5tYXhJbnN0YW5jZUNvdW50PXRoaXMuX21heEluc3RhbmNlQ291bnQscy5tYXhWZXJ0ZXhDb3VudD10aGlzLl9tYXhWZXJ0ZXhDb3VudCxzLm1heEluZGV4Q291bnQ9dGhpcy5fbWF4SW5kZXhDb3VudCxzLmdlb21ldHJ5SW5pdGlhbGl6ZWQ9dGhpcy5fZ2VvbWV0cnlJbml0aWFsaXplZCxzLm1hdHJpY2VzVGV4dHVyZT10aGlzLl9tYXRyaWNlc1RleHR1cmUudG9KU09OKHQpLHMuaW5kaXJlY3RUZXh0dXJlPXRoaXMuX2luZGlyZWN0VGV4dHVyZS50b0pTT04odCksdGhpcy5fY29sb3JzVGV4dHVyZSE9PW51bGwmJihzLmNvbG9yc1RleHR1cmU9dGhpcy5fY29sb3JzVGV4dHVyZS50b0pTT04odCkpLHRoaXMuYm91bmRpbmdTcGhlcmUhPT1udWxsJiYocy5ib3VuZGluZ1NwaGVyZT10aGlzLmJvdW5kaW5nU3BoZXJlLnRvSlNPTigpKSx0aGlzLmJvdW5kaW5nQm94IT09bnVsbCYmKHMuYm91bmRpbmdCb3g9dGhpcy5ib3VuZGluZ0JveC50b0pTT04oKSkpO2Z1bmN0aW9uIHIoYSxjKXtyZXR1cm4gYVtjLnV1aWRdPT09dm9pZCAwJiYoYVtjLnV1aWRdPWMudG9KU09OKHQpKSxjLnV1aWR9aWYodGhpcy5pc1NjZW5lKXRoaXMuYmFja2dyb3VuZCYmKHRoaXMuYmFja2dyb3VuZC5pc0NvbG9yP3MuYmFja2dyb3VuZD10aGlzLmJhY2tncm91bmQudG9KU09OKCk6dGhpcy5iYWNrZ3JvdW5kLmlzVGV4dHVyZSYmKHMuYmFja2dyb3VuZD10aGlzLmJhY2tncm91bmQudG9KU09OKHQpLnV1aWQpKSx0aGlzLmVudmlyb25tZW50JiZ0aGlzLmVudmlyb25tZW50LmlzVGV4dHVyZSYmdGhpcy5lbnZpcm9ubWVudC5pc1JlbmRlclRhcmdldFRleHR1cmUhPT0hMCYmKHMuZW52aXJvbm1lbnQ9dGhpcy5lbnZpcm9ubWVudC50b0pTT04odCkudXVpZCk7ZWxzZSBpZih0aGlzLmlzTWVzaHx8dGhpcy5pc0xpbmV8fHRoaXMuaXNQb2ludHMpe3MuZ2VvbWV0cnk9cih0Lmdlb21ldHJpZXMsdGhpcy5nZW9tZXRyeSk7Y29uc3QgYT10aGlzLmdlb21ldHJ5LnBhcmFtZXRlcnM7aWYoYSE9PXZvaWQgMCYmYS5zaGFwZXMhPT12b2lkIDApe2NvbnN0IGM9YS5zaGFwZXM7aWYoQXJyYXkuaXNBcnJheShjKSlmb3IobGV0IGw9MCxoPWMubGVuZ3RoO2w8aDtsKyspe2NvbnN0IHU9Y1tsXTtyKHQuc2hhcGVzLHUpfWVsc2Ugcih0LnNoYXBlcyxjKX19aWYodGhpcy5pc1NraW5uZWRNZXNoJiYocy5iaW5kTW9kZT10aGlzLmJpbmRNb2RlLHMuYmluZE1hdHJpeD10aGlzLmJpbmRNYXRyaXgudG9BcnJheSgpLHRoaXMuc2tlbGV0b24hPT12b2lkIDAmJihyKHQuc2tlbGV0b25zLHRoaXMuc2tlbGV0b24pLHMuc2tlbGV0b249dGhpcy5za2VsZXRvbi51dWlkKSksdGhpcy5tYXRlcmlhbCE9PXZvaWQgMClpZihBcnJheS5pc0FycmF5KHRoaXMubWF0ZXJpYWwpKXtjb25zdCBhPVtdO2ZvcihsZXQgYz0wLGw9dGhpcy5tYXRlcmlhbC5sZW5ndGg7YzxsO2MrKylhLnB1c2gocih0Lm1hdGVyaWFscyx0aGlzLm1hdGVyaWFsW2NdKSk7cy5tYXRlcmlhbD1hfWVsc2Ugcy5tYXRlcmlhbD1yKHQubWF0ZXJpYWxzLHRoaXMubWF0ZXJpYWwpO2lmKHRoaXMuY2hpbGRyZW4ubGVuZ3RoPjApe3MuY2hpbGRyZW49W107Zm9yKGxldCBhPTA7YTx0aGlzLmNoaWxkcmVuLmxlbmd0aDthKyspcy5jaGlsZHJlbi5wdXNoKHRoaXMuY2hpbGRyZW5bYV0udG9KU09OKHQpLm9iamVjdCl9aWYodGhpcy5hbmltYXRpb25zLmxlbmd0aD4wKXtzLmFuaW1hdGlvbnM9W107Zm9yKGxldCBhPTA7YTx0aGlzLmFuaW1hdGlvbnMubGVuZ3RoO2ErKyl7Y29uc3QgYz10aGlzLmFuaW1hdGlvbnNbYV07cy5hbmltYXRpb25zLnB1c2gocih0LmFuaW1hdGlvbnMsYykpfX1pZihlKXtjb25zdCBhPW8odC5nZW9tZXRyaWVzKSxjPW8odC5tYXRlcmlhbHMpLGw9byh0LnRleHR1cmVzKSxoPW8odC5pbWFnZXMpLHU9byh0LnNoYXBlcyksZj1vKHQuc2tlbGV0b25zKSxkPW8odC5hbmltYXRpb25zKSxwPW8odC5ub2Rlcyk7YS5sZW5ndGg+MCYmKG4uZ2VvbWV0cmllcz1hKSxjLmxlbmd0aD4wJiYobi5tYXRlcmlhbHM9YyksbC5sZW5ndGg+MCYmKG4udGV4dHVyZXM9bCksaC5sZW5ndGg+MCYmKG4uaW1hZ2VzPWgpLHUubGVuZ3RoPjAmJihuLnNoYXBlcz11KSxmLmxlbmd0aD4wJiYobi5za2VsZXRvbnM9ZiksZC5sZW5ndGg+MCYmKG4uYW5pbWF0aW9ucz1kKSxwLmxlbmd0aD4wJiYobi5ub2Rlcz1wKX1yZXR1cm4gbi5vYmplY3Q9cyxuO2Z1bmN0aW9uIG8oYSl7Y29uc3QgYz1bXTtmb3IoY29uc3QgbCBpbiBhKXtjb25zdCBoPWFbbF07ZGVsZXRlIGgubWV0YWRhdGEsYy5wdXNoKGgpfXJldHVybiBjfX1jbG9uZSh0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMsdCl9Y29weSh0LGU9ITApe2lmKHRoaXMubmFtZT10Lm5hbWUsdGhpcy51cC5jb3B5KHQudXApLHRoaXMucG9zaXRpb24uY29weSh0LnBvc2l0aW9uKSx0aGlzLnJvdGF0aW9uLm9yZGVyPXQucm90YXRpb24ub3JkZXIsdGhpcy5xdWF0ZXJuaW9uLmNvcHkodC5xdWF0ZXJuaW9uKSx0aGlzLnNjYWxlLmNvcHkodC5zY2FsZSksdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5tYXRyaXhXb3JsZC5jb3B5KHQubWF0cml4V29ybGQpLHRoaXMubWF0cml4QXV0b1VwZGF0ZT10Lm1hdHJpeEF1dG9VcGRhdGUsdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9dC5tYXRyaXhXb3JsZEF1dG9VcGRhdGUsdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPXQubWF0cml4V29ybGROZWVkc1VwZGF0ZSx0aGlzLmxheWVycy5tYXNrPXQubGF5ZXJzLm1hc2ssdGhpcy52aXNpYmxlPXQudmlzaWJsZSx0aGlzLmNhc3RTaGFkb3c9dC5jYXN0U2hhZG93LHRoaXMucmVjZWl2ZVNoYWRvdz10LnJlY2VpdmVTaGFkb3csdGhpcy5mcnVzdHVtQ3VsbGVkPXQuZnJ1c3R1bUN1bGxlZCx0aGlzLnJlbmRlck9yZGVyPXQucmVuZGVyT3JkZXIsdGhpcy5hbmltYXRpb25zPXQuYW5pbWF0aW9ucy5zbGljZSgpLHRoaXMudXNlckRhdGE9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0LnVzZXJEYXRhKSksZT09PSEwKWZvcihsZXQgbj0wO248dC5jaGlsZHJlbi5sZW5ndGg7bisrKXtjb25zdCBzPXQuY2hpbGRyZW5bbl07dGhpcy5hZGQocy5jbG9uZSgpKX1yZXR1cm4gdGhpc319RWUuREVGQVVMVF9VUD1uZXcgVCgwLDEsMCksRWUuREVGQVVMVF9NQVRSSVhfQVVUT19VUERBVEU9ITAsRWUuREVGQVVMVF9NQVRSSVhfV09STERfQVVUT19VUERBVEU9ITA7Y29uc3QgaGU9bmV3IFQsUGU9bmV3IFQseW89bmV3IFQsQ2U9bmV3IFQsVm49bmV3IFQsVW49bmV3IFQsTmM9bmV3IFQsbW89bmV3IFQsZ289bmV3IFQseG89bmV3IFQsd289bmV3IFl0LGJvPW5ldyBZdCxNbz1uZXcgWXQ7Y2xhc3MgZXR7Y29uc3RydWN0b3IodD1uZXcgVCxlPW5ldyBULG49bmV3IFQpe3RoaXMuYT10LHRoaXMuYj1lLHRoaXMuYz1ufXN0YXRpYyBnZXROb3JtYWwodCxlLG4scyl7cy5zdWJWZWN0b3JzKG4sZSksaGUuc3ViVmVjdG9ycyh0LGUpLHMuY3Jvc3MoaGUpO2NvbnN0IHI9cy5sZW5ndGhTcSgpO3JldHVybiByPjA/cy5tdWx0aXBseVNjYWxhcigxL01hdGguc3FydChyKSk6cy5zZXQoMCwwLDApfXN0YXRpYyBnZXRCYXJ5Y29vcmQodCxlLG4scyxyKXtoZS5zdWJWZWN0b3JzKHMsZSksUGUuc3ViVmVjdG9ycyhuLGUpLHlvLnN1YlZlY3RvcnModCxlKTtjb25zdCBvPWhlLmRvdChoZSksYT1oZS5kb3QoUGUpLGM9aGUuZG90KHlvKSxsPVBlLmRvdChQZSksaD1QZS5kb3QoeW8pLHU9bypsLWEqYTtpZih1PT09MClyZXR1cm4gci5zZXQoMCwwLDApLG51bGw7Y29uc3QgZj0xL3UsZD0obCpjLWEqaCkqZixwPShvKmgtYSpjKSpmO3JldHVybiByLnNldCgxLWQtcCxwLGQpfXN0YXRpYyBjb250YWluc1BvaW50KHQsZSxuLHMpe3JldHVybiB0aGlzLmdldEJhcnljb29yZCh0LGUsbixzLENlKT09PW51bGw/ITE6Q2UueD49MCYmQ2UueT49MCYmQ2UueCtDZS55PD0xfXN0YXRpYyBnZXRJbnRlcnBvbGF0aW9uKHQsZSxuLHMscixvLGEsYyl7cmV0dXJuIHRoaXMuZ2V0QmFyeWNvb3JkKHQsZSxuLHMsQ2UpPT09bnVsbD8oYy54PTAsYy55PTAsInoiaW4gYyYmKGMuej0wKSwidyJpbiBjJiYoYy53PTApLG51bGwpOihjLnNldFNjYWxhcigwKSxjLmFkZFNjYWxlZFZlY3RvcihyLENlLngpLGMuYWRkU2NhbGVkVmVjdG9yKG8sQ2UueSksYy5hZGRTY2FsZWRWZWN0b3IoYSxDZS56KSxjKX1zdGF0aWMgZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKHQsZSxuLHMscixvKXtyZXR1cm4gd28uc2V0U2NhbGFyKDApLGJvLnNldFNjYWxhcigwKSxNby5zZXRTY2FsYXIoMCksd28uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLGJvLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxuKSxNby5mcm9tQnVmZmVyQXR0cmlidXRlKHQscyksby5zZXRTY2FsYXIoMCksby5hZGRTY2FsZWRWZWN0b3Iod28sci54KSxvLmFkZFNjYWxlZFZlY3RvcihibyxyLnkpLG8uYWRkU2NhbGVkVmVjdG9yKE1vLHIueiksb31zdGF0aWMgaXNGcm9udEZhY2luZyh0LGUsbixzKXtyZXR1cm4gaGUuc3ViVmVjdG9ycyhuLGUpLFBlLnN1YlZlY3RvcnModCxlKSxoZS5jcm9zcyhQZSkuZG90KHMpPDB9c2V0KHQsZSxuKXtyZXR1cm4gdGhpcy5hLmNvcHkodCksdGhpcy5iLmNvcHkoZSksdGhpcy5jLmNvcHkobiksdGhpc31zZXRGcm9tUG9pbnRzQW5kSW5kaWNlcyh0LGUsbixzKXtyZXR1cm4gdGhpcy5hLmNvcHkodFtlXSksdGhpcy5iLmNvcHkodFtuXSksdGhpcy5jLmNvcHkodFtzXSksdGhpc31zZXRGcm9tQXR0cmlidXRlQW5kSW5kaWNlcyh0LGUsbixzKXtyZXR1cm4gdGhpcy5hLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKSx0aGlzLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG4pLHRoaXMuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHQscyksdGhpc31jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5hLmNvcHkodC5hKSx0aGlzLmIuY29weSh0LmIpLHRoaXMuYy5jb3B5KHQuYyksdGhpc31nZXRBcmVhKCl7cmV0dXJuIGhlLnN1YlZlY3RvcnModGhpcy5jLHRoaXMuYiksUGUuc3ViVmVjdG9ycyh0aGlzLmEsdGhpcy5iKSxoZS5jcm9zcyhQZSkubGVuZ3RoKCkqLjV9Z2V0TWlkcG9pbnQodCl7cmV0dXJuIHQuYWRkVmVjdG9ycyh0aGlzLmEsdGhpcy5iKS5hZGQodGhpcy5jKS5tdWx0aXBseVNjYWxhcigxLzMpfWdldE5vcm1hbCh0KXtyZXR1cm4gZXQuZ2V0Tm9ybWFsKHRoaXMuYSx0aGlzLmIsdGhpcy5jLHQpfWdldFBsYW5lKHQpe3JldHVybiB0LnNldEZyb21Db3BsYW5hclBvaW50cyh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9Z2V0QmFyeWNvb3JkKHQsZSl7cmV0dXJuIGV0LmdldEJhcnljb29yZCh0LHRoaXMuYSx0aGlzLmIsdGhpcy5jLGUpfWdldEludGVycG9sYXRpb24odCxlLG4scyxyKXtyZXR1cm4gZXQuZ2V0SW50ZXJwb2xhdGlvbih0LHRoaXMuYSx0aGlzLmIsdGhpcy5jLGUsbixzLHIpfWNvbnRhaW5zUG9pbnQodCl7cmV0dXJuIGV0LmNvbnRhaW5zUG9pbnQodCx0aGlzLmEsdGhpcy5iLHRoaXMuYyl9aXNGcm9udEZhY2luZyh0KXtyZXR1cm4gZXQuaXNGcm9udEZhY2luZyh0aGlzLmEsdGhpcy5iLHRoaXMuYyx0KX1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0LmludGVyc2VjdHNUcmlhbmdsZSh0aGlzKX1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZSl7Y29uc3Qgbj10aGlzLmEscz10aGlzLmIscj10aGlzLmM7bGV0IG8sYTtWbi5zdWJWZWN0b3JzKHMsbiksVW4uc3ViVmVjdG9ycyhyLG4pLG1vLnN1YlZlY3RvcnModCxuKTtjb25zdCBjPVZuLmRvdChtbyksbD1Vbi5kb3QobW8pO2lmKGM8PTAmJmw8PTApcmV0dXJuIGUuY29weShuKTtnby5zdWJWZWN0b3JzKHQscyk7Y29uc3QgaD1Wbi5kb3QoZ28pLHU9VW4uZG90KGdvKTtpZihoPj0wJiZ1PD1oKXJldHVybiBlLmNvcHkocyk7Y29uc3QgZj1jKnUtaCpsO2lmKGY8PTAmJmM+PTAmJmg8PTApcmV0dXJuIG89Yy8oYy1oKSxlLmNvcHkobikuYWRkU2NhbGVkVmVjdG9yKFZuLG8pO3hvLnN1YlZlY3RvcnModCxyKTtjb25zdCBkPVZuLmRvdCh4bykscD1Vbi5kb3QoeG8pO2lmKHA+PTAmJmQ8PXApcmV0dXJuIGUuY29weShyKTtjb25zdCB5PWQqbC1jKnA7aWYoeTw9MCYmbD49MCYmcDw9MClyZXR1cm4gYT1sLyhsLXApLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoVW4sYSk7Y29uc3QgbT1oKnAtZCp1O2lmKG08PTAmJnUtaD49MCYmZC1wPj0wKXJldHVybiBOYy5zdWJWZWN0b3JzKHIscyksYT0odS1oKS8odS1oKyhkLXApKSxlLmNvcHkocykuYWRkU2NhbGVkVmVjdG9yKE5jLGEpO2NvbnN0IGc9MS8obSt5K2YpO3JldHVybiBvPXkqZyxhPWYqZyxlLmNvcHkobikuYWRkU2NhbGVkVmVjdG9yKFZuLG8pLmFkZFNjYWxlZFZlY3RvcihVbixhKX1lcXVhbHModCl7cmV0dXJuIHQuYS5lcXVhbHModGhpcy5hKSYmdC5iLmVxdWFscyh0aGlzLmIpJiZ0LmMuZXF1YWxzKHRoaXMuYyl9fWNvbnN0IFJjPXthbGljZWJsdWU6MTU3OTIzODMsYW50aXF1ZXdoaXRlOjE2NDQ0Mzc1LGFxdWE6NjU1MzUsYXF1YW1hcmluZTo4Mzg4NTY0LGF6dXJlOjE1Nzk0MTc1LGJlaWdlOjE2MTE5MjYwLGJpc3F1ZToxNjc3MDI0NCxibGFjazowLGJsYW5jaGVkYWxtb25kOjE2NzcyMDQ1LGJsdWU6MjU1LGJsdWV2aW9sZXQ6OTA1NTIwMixicm93bjoxMDgyNDIzNCxidXJseXdvb2Q6MTQ1OTYyMzEsY2FkZXRibHVlOjYyNjY1MjgsY2hhcnRyZXVzZTo4Mzg4MzUyLGNob2NvbGF0ZToxMzc4OTQ3MCxjb3JhbDoxNjc0NDI3Mixjb3JuZmxvd2VyYmx1ZTo2NTkxOTgxLGNvcm5zaWxrOjE2Nzc1Mzg4LGNyaW1zb246MTQ0MjMxMDAsY3lhbjo2NTUzNSxkYXJrYmx1ZToxMzksZGFya2N5YW46MzU3MjMsZGFya2dvbGRlbnJvZDoxMjA5MjkzOSxkYXJrZ3JheToxMTExOTAxNyxkYXJrZ3JlZW46MjU2MDAsZGFya2dyZXk6MTExMTkwMTcsZGFya2toYWtpOjEyNDMzMjU5LGRhcmttYWdlbnRhOjkxMDk2NDMsZGFya29saXZlZ3JlZW46NTU5Nzk5OSxkYXJrb3JhbmdlOjE2NzQ3NTIwLGRhcmtvcmNoaWQ6MTAwNDAwMTIsZGFya3JlZDo5MTA5NTA0LGRhcmtzYWxtb246MTUzMDg0MTAsZGFya3NlYWdyZWVuOjk0MTk5MTksZGFya3NsYXRlYmx1ZTo0NzM0MzQ3LGRhcmtzbGF0ZWdyYXk6MzEwMDQ5NSxkYXJrc2xhdGVncmV5OjMxMDA0OTUsZGFya3R1cnF1b2lzZTo1Mjk0NSxkYXJrdmlvbGV0Ojk2OTk1MzksZGVlcHBpbms6MTY3MTY5NDcsZGVlcHNreWJsdWU6NDkxNTEsZGltZ3JheTo2OTA4MjY1LGRpbWdyZXk6NjkwODI2NSxkb2RnZXJibHVlOjIwMDMxOTksZmlyZWJyaWNrOjExNjc0MTQ2LGZsb3JhbHdoaXRlOjE2Nzc1OTIwLGZvcmVzdGdyZWVuOjIyNjM4NDIsZnVjaHNpYToxNjcxMTkzNSxnYWluc2Jvcm86MTQ0NzQ0NjAsZ2hvc3R3aGl0ZToxNjMxNjY3MSxnb2xkOjE2NzY2NzIwLGdvbGRlbnJvZDoxNDMyOTEyMCxncmF5Ojg0MjE1MDQsZ3JlZW46MzI3NjgsZ3JlZW55ZWxsb3c6MTE0MDMwNTUsZ3JleTo4NDIxNTA0LGhvbmV5ZGV3OjE1Nzk0MTYwLGhvdHBpbms6MTY3Mzg3NDAsaW5kaWFucmVkOjEzNDU4NTI0LGluZGlnbzo0OTE1MzMwLGl2b3J5OjE2Nzc3MjAwLGtoYWtpOjE1Nzg3NjYwLGxhdmVuZGVyOjE1MTMyNDEwLGxhdmVuZGVyYmx1c2g6MTY3NzMzNjUsbGF3bmdyZWVuOjgxOTA5NzYsbGVtb25jaGlmZm9uOjE2Nzc1ODg1LGxpZ2h0Ymx1ZToxMTM5MzI1NCxsaWdodGNvcmFsOjE1NzYxNTM2LGxpZ2h0Y3lhbjoxNDc0NTU5OSxsaWdodGdvbGRlbnJvZHllbGxvdzoxNjQ0ODIxMCxsaWdodGdyYXk6MTM4ODIzMjMsbGlnaHRncmVlbjo5NDk4MjU2LGxpZ2h0Z3JleToxMzg4MjMyMyxsaWdodHBpbms6MTY3NTg0NjUsbGlnaHRzYWxtb246MTY3NTI3NjIsbGlnaHRzZWFncmVlbjoyMTQyODkwLGxpZ2h0c2t5Ymx1ZTo4OTAwMzQ2LGxpZ2h0c2xhdGVncmF5Ojc4MzM3NTMsbGlnaHRzbGF0ZWdyZXk6NzgzMzc1MyxsaWdodHN0ZWVsYmx1ZToxMTU4NDczNCxsaWdodHllbGxvdzoxNjc3NzE4NCxsaW1lOjY1MjgwLGxpbWVncmVlbjozMzI5MzMwLGxpbmVuOjE2NDQ1NjcwLG1hZ2VudGE6MTY3MTE5MzUsbWFyb29uOjgzODg2MDgsbWVkaXVtYXF1YW1hcmluZTo2NzM3MzIyLG1lZGl1bWJsdWU6MjA1LG1lZGl1bW9yY2hpZDoxMjIxMTY2NyxtZWRpdW1wdXJwbGU6OTY2MjY4MyxtZWRpdW1zZWFncmVlbjozOTc4MDk3LG1lZGl1bXNsYXRlYmx1ZTo4MDg3NzkwLG1lZGl1bXNwcmluZ2dyZWVuOjY0MTU0LG1lZGl1bXR1cnF1b2lzZTo0NzcyMzAwLG1lZGl1bXZpb2xldHJlZDoxMzA0NzE3MyxtaWRuaWdodGJsdWU6MTY0NDkxMixtaW50Y3JlYW06MTYxMjE4NTAsbWlzdHlyb3NlOjE2NzcwMjczLG1vY2Nhc2luOjE2NzcwMjI5LG5hdmFqb3doaXRlOjE2NzY4Njg1LG5hdnk6MTI4LG9sZGxhY2U6MTY2NDM1NTgsb2xpdmU6ODQyMTM3NixvbGl2ZWRyYWI6NzA0ODczOSxvcmFuZ2U6MTY3NTM5MjAsb3JhbmdlcmVkOjE2NzI5MzQ0LG9yY2hpZDoxNDMxNTczNCxwYWxlZ29sZGVucm9kOjE1NjU3MTMwLHBhbGVncmVlbjoxMDAyNTg4MCxwYWxldHVycXVvaXNlOjExNTI5OTY2LHBhbGV2aW9sZXRyZWQ6MTQzODEyMDMscGFwYXlhd2hpcDoxNjc3MzA3NyxwZWFjaHB1ZmY6MTY3Njc2NzMscGVydToxMzQ2ODk5MSxwaW5rOjE2NzYxMDM1LHBsdW06MTQ1MjQ2MzcscG93ZGVyYmx1ZToxMTU5MTkxMCxwdXJwbGU6ODM4ODczNixyZWJlY2NhcHVycGxlOjY2OTc4ODEscmVkOjE2NzExNjgwLHJvc3licm93bjoxMjM1NzUxOSxyb3lhbGJsdWU6NDI4Njk0NSxzYWRkbGVicm93bjo5MTI3MTg3LHNhbG1vbjoxNjQxNjg4MixzYW5keWJyb3duOjE2MDMyODY0LHNlYWdyZWVuOjMwNTAzMjcsc2Vhc2hlbGw6MTY3NzQ2Mzgsc2llbm5hOjEwNTA2Nzk3LHNpbHZlcjoxMjYzMjI1Nixza3libHVlOjg5MDAzMzEsc2xhdGVibHVlOjY5NzAwNjEsc2xhdGVncmF5OjczNzI5NDQsc2xhdGVncmV5OjczNzI5NDQsc25vdzoxNjc3NTkzMCxzcHJpbmdncmVlbjo2NTQwNyxzdGVlbGJsdWU6NDYyMDk4MCx0YW46MTM4MDg3ODAsdGVhbDozMjg5Nix0aGlzdGxlOjE0MjA0ODg4LHRvbWF0bzoxNjczNzA5NSx0dXJxdW9pc2U6NDI1MTg1Nix2aW9sZXQ6MTU2MzEwODYsd2hlYXQ6MTYxMTMzMzEsd2hpdGU6MTY3NzcyMTUsd2hpdGVzbW9rZToxNjExOTI4NSx5ZWxsb3c6MTY3NzY5NjAseWVsbG93Z3JlZW46MTAxNDUwNzR9LFFlPXtoOjAsczowLGw6MH0scHM9e2g6MCxzOjAsbDowfTtmdW5jdGlvbiBBbyhpLHQsZSl7cmV0dXJuIGU8MCYmKGUrPTEpLGU+MSYmKGUtPTEpLGU8MS82P2krKHQtaSkqNiplOmU8MS8yP3Q6ZTwyLzM/aSsodC1pKSo2KigyLzMtZSk6aX1sZXQgeXM9Y2xhc3N7Y29uc3RydWN0b3IodCxlLG4pe3JldHVybiB0aGlzLmlzQ29sb3I9ITAsdGhpcy5yPTEsdGhpcy5nPTEsdGhpcy5iPTEsdGhpcy5zZXQodCxlLG4pfXNldCh0LGUsbil7aWYoZT09PXZvaWQgMCYmbj09PXZvaWQgMCl7Y29uc3Qgcz10O3MmJnMuaXNDb2xvcj90aGlzLmNvcHkocyk6dHlwZW9mIHM9PSJudW1iZXIiP3RoaXMuc2V0SGV4KHMpOnR5cGVvZiBzPT0ic3RyaW5nIiYmdGhpcy5zZXRTdHlsZShzKX1lbHNlIHRoaXMuc2V0UkdCKHQsZSxuKTtyZXR1cm4gdGhpc31zZXRTY2FsYXIodCl7cmV0dXJuIHRoaXMucj10LHRoaXMuZz10LHRoaXMuYj10LHRoaXN9c2V0SGV4KHQsZT1vZSl7cmV0dXJuIHQ9TWF0aC5mbG9vcih0KSx0aGlzLnI9KHQ+PjE2JjI1NSkvMjU1LHRoaXMuZz0odD4+OCYyNTUpLzI1NSx0aGlzLmI9KHQmMjU1KS8yNTUsYWUuY29sb3JTcGFjZVRvV29ya2luZyh0aGlzLGUpLHRoaXN9c2V0UkdCKHQsZSxuLHM9YWUud29ya2luZ0NvbG9yU3BhY2Upe3JldHVybiB0aGlzLnI9dCx0aGlzLmc9ZSx0aGlzLmI9bixhZS5jb2xvclNwYWNlVG9Xb3JraW5nKHRoaXMscyksdGhpc31zZXRIU0wodCxlLG4scz1hZS53b3JraW5nQ29sb3JTcGFjZSl7aWYodD1qdSh0LDEpLGU9WihlLDAsMSksbj1aKG4sMCwxKSxlPT09MCl0aGlzLnI9dGhpcy5nPXRoaXMuYj1uO2Vsc2V7Y29uc3Qgcj1uPD0uNT9uKigxK2UpOm4rZS1uKmUsbz0yKm4tcjt0aGlzLnI9QW8obyxyLHQrMS8zKSx0aGlzLmc9QW8obyxyLHQpLHRoaXMuYj1BbyhvLHIsdC0xLzMpfXJldHVybiBhZS5jb2xvclNwYWNlVG9Xb3JraW5nKHRoaXMscyksdGhpc31zZXRTdHlsZSh0LGU9b2Upe2Z1bmN0aW9uIG4ocil7ciE9PXZvaWQgMCYmcGFyc2VGbG9hdChyKTwxJiZjb25zb2xlLndhcm4oIlRIUkVFLkNvbG9yOiBBbHBoYSBjb21wb25lbnQgb2YgIit0KyIgd2lsbCBiZSBpZ25vcmVkLiIpfWxldCBzO2lmKHM9L14oXHcrKVwoKFteXCldKilcKS8uZXhlYyh0KSl7bGV0IHI7Y29uc3Qgbz1zWzFdLGE9c1syXTtzd2l0Y2gobyl7Y2FzZSJyZ2IiOmNhc2UicmdiYSI6aWYocj0vXlxzKihcZCspXHMqLFxzKihcZCspXHMqLFxzKihcZCspXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0UkdCKE1hdGgubWluKDI1NSxwYXJzZUludChyWzFdLDEwKSkvMjU1LE1hdGgubWluKDI1NSxwYXJzZUludChyWzJdLDEwKSkvMjU1LE1hdGgubWluKDI1NSxwYXJzZUludChyWzNdLDEwKSkvMjU1LGUpO2lmKHI9L15ccyooXGQrKVwlXHMqLFxzKihcZCspXCVccyosXHMqKFxkKylcJVxzKig/OixccyooXGQqXC4/XGQrKVxzKik/JC8uZXhlYyhhKSlyZXR1cm4gbihyWzRdKSx0aGlzLnNldFJHQihNYXRoLm1pbigxMDAscGFyc2VJbnQoclsxXSwxMCkpLzEwMCxNYXRoLm1pbigxMDAscGFyc2VJbnQoclsyXSwxMCkpLzEwMCxNYXRoLm1pbigxMDAscGFyc2VJbnQoclszXSwxMCkpLzEwMCxlKTticmVhaztjYXNlImhzbCI6Y2FzZSJoc2xhIjppZihyPS9eXHMqKFxkKlwuP1xkKylccyosXHMqKFxkKlwuP1xkKylcJVxzKixccyooXGQqXC4/XGQrKVwlXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0SFNMKHBhcnNlRmxvYXQoclsxXSkvMzYwLHBhcnNlRmxvYXQoclsyXSkvMTAwLHBhcnNlRmxvYXQoclszXSkvMTAwLGUpO2JyZWFrO2RlZmF1bHQ6Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogVW5rbm93biBjb2xvciBtb2RlbCAiK3QpfX1lbHNlIGlmKHM9L15cIyhbQS1GYS1mXGRdKykkLy5leGVjKHQpKXtjb25zdCByPXNbMV0sbz1yLmxlbmd0aDtpZihvPT09MylyZXR1cm4gdGhpcy5zZXRSR0IocGFyc2VJbnQoci5jaGFyQXQoMCksMTYpLzE1LHBhcnNlSW50KHIuY2hhckF0KDEpLDE2KS8xNSxwYXJzZUludChyLmNoYXJBdCgyKSwxNikvMTUsZSk7aWYobz09PTYpcmV0dXJuIHRoaXMuc2V0SGV4KHBhcnNlSW50KHIsMTYpLGUpO2NvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IEludmFsaWQgaGV4IGNvbG9yICIrdCl9ZWxzZSBpZih0JiZ0Lmxlbmd0aD4wKXJldHVybiB0aGlzLnNldENvbG9yTmFtZSh0LGUpO3JldHVybiB0aGlzfXNldENvbG9yTmFtZSh0LGU9b2Upe2NvbnN0IG49UmNbdC50b0xvd2VyQ2FzZSgpXTtyZXR1cm4gbiE9PXZvaWQgMD90aGlzLnNldEhleChuLGUpOmNvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IFVua25vd24gY29sb3IgIit0KSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMucix0aGlzLmcsdGhpcy5iKX1jb3B5KHQpe3JldHVybiB0aGlzLnI9dC5yLHRoaXMuZz10LmcsdGhpcy5iPXQuYix0aGlzfWNvcHlTUkdCVG9MaW5lYXIodCl7cmV0dXJuIHRoaXMucj1fZSh0LnIpLHRoaXMuZz1fZSh0LmcpLHRoaXMuYj1fZSh0LmIpLHRoaXN9Y29weUxpbmVhclRvU1JHQih0KXtyZXR1cm4gdGhpcy5yPUluKHQuciksdGhpcy5nPUluKHQuZyksdGhpcy5iPUluKHQuYiksdGhpc31jb252ZXJ0U1JHQlRvTGluZWFyKCl7cmV0dXJuIHRoaXMuY29weVNSR0JUb0xpbmVhcih0aGlzKSx0aGlzfWNvbnZlcnRMaW5lYXJUb1NSR0IoKXtyZXR1cm4gdGhpcy5jb3B5TGluZWFyVG9TUkdCKHRoaXMpLHRoaXN9Z2V0SGV4KHQ9b2Upe3JldHVybiBhZS53b3JraW5nVG9Db2xvclNwYWNlKFN0LmNvcHkodGhpcyksdCksTWF0aC5yb3VuZChaKFN0LnIqMjU1LDAsMjU1KSkqNjU1MzYrTWF0aC5yb3VuZChaKFN0LmcqMjU1LDAsMjU1KSkqMjU2K01hdGgucm91bmQoWihTdC5iKjI1NSwwLDI1NSkpfWdldEhleFN0cmluZyh0PW9lKXtyZXR1cm4oIjAwMDAwMCIrdGhpcy5nZXRIZXgodCkudG9TdHJpbmcoMTYpKS5zbGljZSgtNil9Z2V0SFNMKHQsZT1hZS53b3JraW5nQ29sb3JTcGFjZSl7YWUud29ya2luZ1RvQ29sb3JTcGFjZShTdC5jb3B5KHRoaXMpLGUpO2NvbnN0IG49U3QucixzPVN0Lmcscj1TdC5iLG89TWF0aC5tYXgobixzLHIpLGE9TWF0aC5taW4obixzLHIpO2xldCBjLGw7Y29uc3QgaD0oYStvKS8yO2lmKGE9PT1vKWM9MCxsPTA7ZWxzZXtjb25zdCB1PW8tYTtzd2l0Y2gobD1oPD0uNT91LyhvK2EpOnUvKDItby1hKSxvKXtjYXNlIG46Yz0ocy1yKS91KyhzPHI/NjowKTticmVhaztjYXNlIHM6Yz0oci1uKS91KzI7YnJlYWs7Y2FzZSByOmM9KG4tcykvdSs0O2JyZWFrfWMvPTZ9cmV0dXJuIHQuaD1jLHQucz1sLHQubD1oLHR9Z2V0UkdCKHQsZT1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIGFlLndvcmtpbmdUb0NvbG9yU3BhY2UoU3QuY29weSh0aGlzKSxlKSx0LnI9U3Qucix0Lmc9U3QuZyx0LmI9U3QuYix0fWdldFN0eWxlKHQ9b2Upe2FlLndvcmtpbmdUb0NvbG9yU3BhY2UoU3QuY29weSh0aGlzKSx0KTtjb25zdCBlPVN0LnIsbj1TdC5nLHM9U3QuYjtyZXR1cm4gdCE9PW9lP2Bjb2xvcigke3R9ICR7ZS50b0ZpeGVkKDMpfSAke24udG9GaXhlZCgzKX0gJHtzLnRvRml4ZWQoMyl9KWA6YHJnYigke01hdGgucm91bmQoZSoyNTUpfSwke01hdGgucm91bmQobioyNTUpfSwke01hdGgucm91bmQocyoyNTUpfSlgfW9mZnNldEhTTCh0LGUsbil7cmV0dXJuIHRoaXMuZ2V0SFNMKFFlKSx0aGlzLnNldEhTTChRZS5oK3QsUWUucytlLFFlLmwrbil9YWRkKHQpe3JldHVybiB0aGlzLnIrPXQucix0aGlzLmcrPXQuZyx0aGlzLmIrPXQuYix0aGlzfWFkZENvbG9ycyh0LGUpe3JldHVybiB0aGlzLnI9dC5yK2Uucix0aGlzLmc9dC5nK2UuZyx0aGlzLmI9dC5iK2UuYix0aGlzfWFkZFNjYWxhcih0KXtyZXR1cm4gdGhpcy5yKz10LHRoaXMuZys9dCx0aGlzLmIrPXQsdGhpc31zdWIodCl7cmV0dXJuIHRoaXMucj1NYXRoLm1heCgwLHRoaXMuci10LnIpLHRoaXMuZz1NYXRoLm1heCgwLHRoaXMuZy10LmcpLHRoaXMuYj1NYXRoLm1heCgwLHRoaXMuYi10LmIpLHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMucio9dC5yLHRoaXMuZyo9dC5nLHRoaXMuYio9dC5iLHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMucio9dCx0aGlzLmcqPXQsdGhpcy5iKj10LHRoaXN9bGVycCh0LGUpe3JldHVybiB0aGlzLnIrPSh0LnItdGhpcy5yKSplLHRoaXMuZys9KHQuZy10aGlzLmcpKmUsdGhpcy5iKz0odC5iLXRoaXMuYikqZSx0aGlzfWxlcnBDb2xvcnModCxlLG4pe3JldHVybiB0aGlzLnI9dC5yKyhlLnItdC5yKSpuLHRoaXMuZz10LmcrKGUuZy10LmcpKm4sdGhpcy5iPXQuYisoZS5iLXQuYikqbix0aGlzfWxlcnBIU0wodCxlKXt0aGlzLmdldEhTTChRZSksdC5nZXRIU0wocHMpO2NvbnN0IG49ZW8oUWUuaCxwcy5oLGUpLHM9ZW8oUWUucyxwcy5zLGUpLHI9ZW8oUWUubCxwcy5sLGUpO3JldHVybiB0aGlzLnNldEhTTChuLHMsciksdGhpc31zZXRGcm9tVmVjdG9yMyh0KXtyZXR1cm4gdGhpcy5yPXQueCx0aGlzLmc9dC55LHRoaXMuYj10LnosdGhpc31hcHBseU1hdHJpeDModCl7Y29uc3QgZT10aGlzLnIsbj10aGlzLmcscz10aGlzLmIscj10LmVsZW1lbnRzO3JldHVybiB0aGlzLnI9clswXSplK3JbM10qbityWzZdKnMsdGhpcy5nPXJbMV0qZStyWzRdKm4rcls3XSpzLHRoaXMuYj1yWzJdKmUrcls1XSpuK3JbOF0qcyx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5yPT09dGhpcy5yJiZ0Lmc9PT10aGlzLmcmJnQuYj09PXRoaXMuYn1mcm9tQXJyYXkodCxlPTApe3JldHVybiB0aGlzLnI9dFtlXSx0aGlzLmc9dFtlKzFdLHRoaXMuYj10W2UrMl0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLnIsdFtlKzFdPXRoaXMuZyx0W2UrMl09dGhpcy5iLHR9ZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpe3JldHVybiB0aGlzLnI9dC5nZXRYKGUpLHRoaXMuZz10LmdldFkoZSksdGhpcy5iPXQuZ2V0WihlKSx0aGlzfXRvSlNPTigpe3JldHVybiB0aGlzLmdldEhleCgpfSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMucix5aWVsZCB0aGlzLmcseWllbGQgdGhpcy5ifX07Y29uc3QgU3Q9bmV3IHlzO3lzLk5BTUVTPVJjO2xldCBkZj0wO2NsYXNzIHBmIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNNYXRlcmlhbD0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpkZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iTWF0ZXJpYWwiLHRoaXMuYmxlbmRpbmc9MSx0aGlzLnNpZGU9MCx0aGlzLnZlcnRleENvbG9ycz0hMSx0aGlzLm9wYWNpdHk9MSx0aGlzLnRyYW5zcGFyZW50PSExLHRoaXMuYWxwaGFIYXNoPSExLHRoaXMuYmxlbmRTcmM9MjA0LHRoaXMuYmxlbmREc3Q9MjA1LHRoaXMuYmxlbmRFcXVhdGlvbj0xMDAsdGhpcy5ibGVuZFNyY0FscGhhPW51bGwsdGhpcy5ibGVuZERzdEFscGhhPW51bGwsdGhpcy5ibGVuZEVxdWF0aW9uQWxwaGE9bnVsbCx0aGlzLmJsZW5kQ29sb3I9bmV3IHlzKDAsMCwwKSx0aGlzLmJsZW5kQWxwaGE9MCx0aGlzLmRlcHRoRnVuYz0zLHRoaXMuZGVwdGhUZXN0PSEwLHRoaXMuZGVwdGhXcml0ZT0hMCx0aGlzLnN0ZW5jaWxXcml0ZU1hc2s9MjU1LHRoaXMuc3RlbmNpbEZ1bmM9NTE5LHRoaXMuc3RlbmNpbFJlZj0wLHRoaXMuc3RlbmNpbEZ1bmNNYXNrPTI1NSx0aGlzLnN0ZW5jaWxGYWlsPTc2ODAsdGhpcy5zdGVuY2lsWkZhaWw9NzY4MCx0aGlzLnN0ZW5jaWxaUGFzcz03NjgwLHRoaXMuc3RlbmNpbFdyaXRlPSExLHRoaXMuY2xpcHBpbmdQbGFuZXM9bnVsbCx0aGlzLmNsaXBJbnRlcnNlY3Rpb249ITEsdGhpcy5jbGlwU2hhZG93cz0hMSx0aGlzLnNoYWRvd1NpZGU9bnVsbCx0aGlzLmNvbG9yV3JpdGU9ITAsdGhpcy5wcmVjaXNpb249bnVsbCx0aGlzLnBvbHlnb25PZmZzZXQ9ITEsdGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yPTAsdGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHM9MCx0aGlzLmRpdGhlcmluZz0hMSx0aGlzLmFscGhhVG9Db3ZlcmFnZT0hMSx0aGlzLnByZW11bHRpcGxpZWRBbHBoYT0hMSx0aGlzLmZvcmNlU2luZ2xlUGFzcz0hMSx0aGlzLmFsbG93T3ZlcnJpZGU9ITAsdGhpcy52aXNpYmxlPSEwLHRoaXMudG9uZU1hcHBlZD0hMCx0aGlzLnVzZXJEYXRhPXt9LHRoaXMudmVyc2lvbj0wLHRoaXMuX2FscGhhVGVzdD0wfWdldCBhbHBoYVRlc3QoKXtyZXR1cm4gdGhpcy5fYWxwaGFUZXN0fXNldCBhbHBoYVRlc3QodCl7dGhpcy5fYWxwaGFUZXN0PjAhPXQ+MCYmdGhpcy52ZXJzaW9uKyssdGhpcy5fYWxwaGFUZXN0PXR9b25CZWZvcmVSZW5kZXIoKXt9b25CZWZvcmVDb21waWxlKCl7fWN1c3RvbVByb2dyYW1DYWNoZUtleSgpe3JldHVybiB0aGlzLm9uQmVmb3JlQ29tcGlsZS50b1N0cmluZygpfXNldFZhbHVlcyh0KXtpZih0IT09dm9pZCAwKWZvcihjb25zdCBlIGluIHQpe2NvbnN0IG49dFtlXTtpZihuPT09dm9pZCAwKXtjb25zb2xlLndhcm4oYFRIUkVFLk1hdGVyaWFsOiBwYXJhbWV0ZXIgJyR7ZX0nIGhhcyB2YWx1ZSBvZiB1bmRlZmluZWQuYCk7Y29udGludWV9Y29uc3Qgcz10aGlzW2VdO2lmKHM9PT12b2lkIDApe2NvbnNvbGUud2FybihgVEhSRUUuTWF0ZXJpYWw6ICcke2V9JyBpcyBub3QgYSBwcm9wZXJ0eSBvZiBUSFJFRS4ke3RoaXMudHlwZX0uYCk7Y29udGludWV9cyYmcy5pc0NvbG9yP3Muc2V0KG4pOnMmJnMuaXNWZWN0b3IzJiZuJiZuLmlzVmVjdG9yMz9zLmNvcHkobik6dGhpc1tlXT1ufX10b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7ZSYmKHQ9e3RleHR1cmVzOnt9LGltYWdlczp7fX0pO2NvbnN0IG49e21ldGFkYXRhOnt2ZXJzaW9uOjQuNyx0eXBlOiJNYXRlcmlhbCIsZ2VuZXJhdG9yOiJNYXRlcmlhbC50b0pTT04ifX07bi51dWlkPXRoaXMudXVpZCxuLnR5cGU9dGhpcy50eXBlLHRoaXMubmFtZSE9PSIiJiYobi5uYW1lPXRoaXMubmFtZSksdGhpcy5jb2xvciYmdGhpcy5jb2xvci5pc0NvbG9yJiYobi5jb2xvcj10aGlzLmNvbG9yLmdldEhleCgpKSx0aGlzLnJvdWdobmVzcyE9PXZvaWQgMCYmKG4ucm91Z2huZXNzPXRoaXMucm91Z2huZXNzKSx0aGlzLm1ldGFsbmVzcyE9PXZvaWQgMCYmKG4ubWV0YWxuZXNzPXRoaXMubWV0YWxuZXNzKSx0aGlzLnNoZWVuIT09dm9pZCAwJiYobi5zaGVlbj10aGlzLnNoZWVuKSx0aGlzLnNoZWVuQ29sb3ImJnRoaXMuc2hlZW5Db2xvci5pc0NvbG9yJiYobi5zaGVlbkNvbG9yPXRoaXMuc2hlZW5Db2xvci5nZXRIZXgoKSksdGhpcy5zaGVlblJvdWdobmVzcyE9PXZvaWQgMCYmKG4uc2hlZW5Sb3VnaG5lc3M9dGhpcy5zaGVlblJvdWdobmVzcyksdGhpcy5lbWlzc2l2ZSYmdGhpcy5lbWlzc2l2ZS5pc0NvbG9yJiYobi5lbWlzc2l2ZT10aGlzLmVtaXNzaXZlLmdldEhleCgpKSx0aGlzLmVtaXNzaXZlSW50ZW5zaXR5IT09dm9pZCAwJiZ0aGlzLmVtaXNzaXZlSW50ZW5zaXR5IT09MSYmKG4uZW1pc3NpdmVJbnRlbnNpdHk9dGhpcy5lbWlzc2l2ZUludGVuc2l0eSksdGhpcy5zcGVjdWxhciYmdGhpcy5zcGVjdWxhci5pc0NvbG9yJiYobi5zcGVjdWxhcj10aGlzLnNwZWN1bGFyLmdldEhleCgpKSx0aGlzLnNwZWN1bGFySW50ZW5zaXR5IT09dm9pZCAwJiYobi5zcGVjdWxhckludGVuc2l0eT10aGlzLnNwZWN1bGFySW50ZW5zaXR5KSx0aGlzLnNwZWN1bGFyQ29sb3ImJnRoaXMuc3BlY3VsYXJDb2xvci5pc0NvbG9yJiYobi5zcGVjdWxhckNvbG9yPXRoaXMuc3BlY3VsYXJDb2xvci5nZXRIZXgoKSksdGhpcy5zaGluaW5lc3MhPT12b2lkIDAmJihuLnNoaW5pbmVzcz10aGlzLnNoaW5pbmVzcyksdGhpcy5jbGVhcmNvYXQhPT12b2lkIDAmJihuLmNsZWFyY29hdD10aGlzLmNsZWFyY29hdCksdGhpcy5jbGVhcmNvYXRSb3VnaG5lc3MhPT12b2lkIDAmJihuLmNsZWFyY29hdFJvdWdobmVzcz10aGlzLmNsZWFyY29hdFJvdWdobmVzcyksdGhpcy5jbGVhcmNvYXRNYXAmJnRoaXMuY2xlYXJjb2F0TWFwLmlzVGV4dHVyZSYmKG4uY2xlYXJjb2F0TWFwPXRoaXMuY2xlYXJjb2F0TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmNsZWFyY29hdFJvdWdobmVzc01hcCYmdGhpcy5jbGVhcmNvYXRSb3VnaG5lc3NNYXAuaXNUZXh0dXJlJiYobi5jbGVhcmNvYXRSb3VnaG5lc3NNYXA9dGhpcy5jbGVhcmNvYXRSb3VnaG5lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuY2xlYXJjb2F0Tm9ybWFsTWFwJiZ0aGlzLmNsZWFyY29hdE5vcm1hbE1hcC5pc1RleHR1cmUmJihuLmNsZWFyY29hdE5vcm1hbE1hcD10aGlzLmNsZWFyY29hdE5vcm1hbE1hcC50b0pTT04odCkudXVpZCxuLmNsZWFyY29hdE5vcm1hbFNjYWxlPXRoaXMuY2xlYXJjb2F0Tm9ybWFsU2NhbGUudG9BcnJheSgpKSx0aGlzLmRpc3BlcnNpb24hPT12b2lkIDAmJihuLmRpc3BlcnNpb249dGhpcy5kaXNwZXJzaW9uKSx0aGlzLmlyaWRlc2NlbmNlIT09dm9pZCAwJiYobi5pcmlkZXNjZW5jZT10aGlzLmlyaWRlc2NlbmNlKSx0aGlzLmlyaWRlc2NlbmNlSU9SIT09dm9pZCAwJiYobi5pcmlkZXNjZW5jZUlPUj10aGlzLmlyaWRlc2NlbmNlSU9SKSx0aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzUmFuZ2UhPT12b2lkIDAmJihuLmlyaWRlc2NlbmNlVGhpY2tuZXNzUmFuZ2U9dGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc1JhbmdlKSx0aGlzLmlyaWRlc2NlbmNlTWFwJiZ0aGlzLmlyaWRlc2NlbmNlTWFwLmlzVGV4dHVyZSYmKG4uaXJpZGVzY2VuY2VNYXA9dGhpcy5pcmlkZXNjZW5jZU1hcC50b0pTT04odCkudXVpZCksdGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcCYmdGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcC5pc1RleHR1cmUmJihuLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwPXRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuYW5pc290cm9weSE9PXZvaWQgMCYmKG4uYW5pc290cm9weT10aGlzLmFuaXNvdHJvcHkpLHRoaXMuYW5pc290cm9weVJvdGF0aW9uIT09dm9pZCAwJiYobi5hbmlzb3Ryb3B5Um90YXRpb249dGhpcy5hbmlzb3Ryb3B5Um90YXRpb24pLHRoaXMuYW5pc290cm9weU1hcCYmdGhpcy5hbmlzb3Ryb3B5TWFwLmlzVGV4dHVyZSYmKG4uYW5pc290cm9weU1hcD10aGlzLmFuaXNvdHJvcHlNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubWFwJiZ0aGlzLm1hcC5pc1RleHR1cmUmJihuLm1hcD10aGlzLm1hcC50b0pTT04odCkudXVpZCksdGhpcy5tYXRjYXAmJnRoaXMubWF0Y2FwLmlzVGV4dHVyZSYmKG4ubWF0Y2FwPXRoaXMubWF0Y2FwLnRvSlNPTih0KS51dWlkKSx0aGlzLmFscGhhTWFwJiZ0aGlzLmFscGhhTWFwLmlzVGV4dHVyZSYmKG4uYWxwaGFNYXA9dGhpcy5hbHBoYU1hcC50b0pTT04odCkudXVpZCksdGhpcy5saWdodE1hcCYmdGhpcy5saWdodE1hcC5pc1RleHR1cmUmJihuLmxpZ2h0TWFwPXRoaXMubGlnaHRNYXAudG9KU09OKHQpLnV1aWQsbi5saWdodE1hcEludGVuc2l0eT10aGlzLmxpZ2h0TWFwSW50ZW5zaXR5KSx0aGlzLmFvTWFwJiZ0aGlzLmFvTWFwLmlzVGV4dHVyZSYmKG4uYW9NYXA9dGhpcy5hb01hcC50b0pTT04odCkudXVpZCxuLmFvTWFwSW50ZW5zaXR5PXRoaXMuYW9NYXBJbnRlbnNpdHkpLHRoaXMuYnVtcE1hcCYmdGhpcy5idW1wTWFwLmlzVGV4dHVyZSYmKG4uYnVtcE1hcD10aGlzLmJ1bXBNYXAudG9KU09OKHQpLnV1aWQsbi5idW1wU2NhbGU9dGhpcy5idW1wU2NhbGUpLHRoaXMubm9ybWFsTWFwJiZ0aGlzLm5vcm1hbE1hcC5pc1RleHR1cmUmJihuLm5vcm1hbE1hcD10aGlzLm5vcm1hbE1hcC50b0pTT04odCkudXVpZCxuLm5vcm1hbE1hcFR5cGU9dGhpcy5ub3JtYWxNYXBUeXBlLG4ubm9ybWFsU2NhbGU9dGhpcy5ub3JtYWxTY2FsZS50b0FycmF5KCkpLHRoaXMuZGlzcGxhY2VtZW50TWFwJiZ0aGlzLmRpc3BsYWNlbWVudE1hcC5pc1RleHR1cmUmJihuLmRpc3BsYWNlbWVudE1hcD10aGlzLmRpc3BsYWNlbWVudE1hcC50b0pTT04odCkudXVpZCxuLmRpc3BsYWNlbWVudFNjYWxlPXRoaXMuZGlzcGxhY2VtZW50U2NhbGUsbi5kaXNwbGFjZW1lbnRCaWFzPXRoaXMuZGlzcGxhY2VtZW50QmlhcyksdGhpcy5yb3VnaG5lc3NNYXAmJnRoaXMucm91Z2huZXNzTWFwLmlzVGV4dHVyZSYmKG4ucm91Z2huZXNzTWFwPXRoaXMucm91Z2huZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLm1ldGFsbmVzc01hcCYmdGhpcy5tZXRhbG5lc3NNYXAuaXNUZXh0dXJlJiYobi5tZXRhbG5lc3NNYXA9dGhpcy5tZXRhbG5lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuZW1pc3NpdmVNYXAmJnRoaXMuZW1pc3NpdmVNYXAuaXNUZXh0dXJlJiYobi5lbWlzc2l2ZU1hcD10aGlzLmVtaXNzaXZlTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnNwZWN1bGFyTWFwJiZ0aGlzLnNwZWN1bGFyTWFwLmlzVGV4dHVyZSYmKG4uc3BlY3VsYXJNYXA9dGhpcy5zcGVjdWxhck1hcC50b0pTT04odCkudXVpZCksdGhpcy5zcGVjdWxhckludGVuc2l0eU1hcCYmdGhpcy5zcGVjdWxhckludGVuc2l0eU1hcC5pc1RleHR1cmUmJihuLnNwZWN1bGFySW50ZW5zaXR5TWFwPXRoaXMuc3BlY3VsYXJJbnRlbnNpdHlNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuc3BlY3VsYXJDb2xvck1hcCYmdGhpcy5zcGVjdWxhckNvbG9yTWFwLmlzVGV4dHVyZSYmKG4uc3BlY3VsYXJDb2xvck1hcD10aGlzLnNwZWN1bGFyQ29sb3JNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuZW52TWFwJiZ0aGlzLmVudk1hcC5pc1RleHR1cmUmJihuLmVudk1hcD10aGlzLmVudk1hcC50b0pTT04odCkudXVpZCx0aGlzLmNvbWJpbmUhPT12b2lkIDAmJihuLmNvbWJpbmU9dGhpcy5jb21iaW5lKSksdGhpcy5lbnZNYXBSb3RhdGlvbiE9PXZvaWQgMCYmKG4uZW52TWFwUm90YXRpb249dGhpcy5lbnZNYXBSb3RhdGlvbi50b0FycmF5KCkpLHRoaXMuZW52TWFwSW50ZW5zaXR5IT09dm9pZCAwJiYobi5lbnZNYXBJbnRlbnNpdHk9dGhpcy5lbnZNYXBJbnRlbnNpdHkpLHRoaXMucmVmbGVjdGl2aXR5IT09dm9pZCAwJiYobi5yZWZsZWN0aXZpdHk9dGhpcy5yZWZsZWN0aXZpdHkpLHRoaXMucmVmcmFjdGlvblJhdGlvIT09dm9pZCAwJiYobi5yZWZyYWN0aW9uUmF0aW89dGhpcy5yZWZyYWN0aW9uUmF0aW8pLHRoaXMuZ3JhZGllbnRNYXAmJnRoaXMuZ3JhZGllbnRNYXAuaXNUZXh0dXJlJiYobi5ncmFkaWVudE1hcD10aGlzLmdyYWRpZW50TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnRyYW5zbWlzc2lvbiE9PXZvaWQgMCYmKG4udHJhbnNtaXNzaW9uPXRoaXMudHJhbnNtaXNzaW9uKSx0aGlzLnRyYW5zbWlzc2lvbk1hcCYmdGhpcy50cmFuc21pc3Npb25NYXAuaXNUZXh0dXJlJiYobi50cmFuc21pc3Npb25NYXA9dGhpcy50cmFuc21pc3Npb25NYXAudG9KU09OKHQpLnV1aWQpLHRoaXMudGhpY2tuZXNzIT09dm9pZCAwJiYobi50aGlja25lc3M9dGhpcy50aGlja25lc3MpLHRoaXMudGhpY2tuZXNzTWFwJiZ0aGlzLnRoaWNrbmVzc01hcC5pc1RleHR1cmUmJihuLnRoaWNrbmVzc01hcD10aGlzLnRoaWNrbmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5hdHRlbnVhdGlvbkRpc3RhbmNlIT09dm9pZCAwJiZ0aGlzLmF0dGVudWF0aW9uRGlzdGFuY2UhPT0xLzAmJihuLmF0dGVudWF0aW9uRGlzdGFuY2U9dGhpcy5hdHRlbnVhdGlvbkRpc3RhbmNlKSx0aGlzLmF0dGVudWF0aW9uQ29sb3IhPT12b2lkIDAmJihuLmF0dGVudWF0aW9uQ29sb3I9dGhpcy5hdHRlbnVhdGlvbkNvbG9yLmdldEhleCgpKSx0aGlzLnNpemUhPT12b2lkIDAmJihuLnNpemU9dGhpcy5zaXplKSx0aGlzLnNoYWRvd1NpZGUhPT1udWxsJiYobi5zaGFkb3dTaWRlPXRoaXMuc2hhZG93U2lkZSksdGhpcy5zaXplQXR0ZW51YXRpb24hPT12b2lkIDAmJihuLnNpemVBdHRlbnVhdGlvbj10aGlzLnNpemVBdHRlbnVhdGlvbiksdGhpcy5ibGVuZGluZyE9PTEmJihuLmJsZW5kaW5nPXRoaXMuYmxlbmRpbmcpLHRoaXMuc2lkZSE9PTAmJihuLnNpZGU9dGhpcy5zaWRlKSx0aGlzLnZlcnRleENvbG9ycz09PSEwJiYobi52ZXJ0ZXhDb2xvcnM9ITApLHRoaXMub3BhY2l0eTwxJiYobi5vcGFjaXR5PXRoaXMub3BhY2l0eSksdGhpcy50cmFuc3BhcmVudD09PSEwJiYobi50cmFuc3BhcmVudD0hMCksdGhpcy5ibGVuZFNyYyE9PTIwNCYmKG4uYmxlbmRTcmM9dGhpcy5ibGVuZFNyYyksdGhpcy5ibGVuZERzdCE9PTIwNSYmKG4uYmxlbmREc3Q9dGhpcy5ibGVuZERzdCksdGhpcy5ibGVuZEVxdWF0aW9uIT09MTAwJiYobi5ibGVuZEVxdWF0aW9uPXRoaXMuYmxlbmRFcXVhdGlvbiksdGhpcy5ibGVuZFNyY0FscGhhIT09bnVsbCYmKG4uYmxlbmRTcmNBbHBoYT10aGlzLmJsZW5kU3JjQWxwaGEpLHRoaXMuYmxlbmREc3RBbHBoYSE9PW51bGwmJihuLmJsZW5kRHN0QWxwaGE9dGhpcy5ibGVuZERzdEFscGhhKSx0aGlzLmJsZW5kRXF1YXRpb25BbHBoYSE9PW51bGwmJihuLmJsZW5kRXF1YXRpb25BbHBoYT10aGlzLmJsZW5kRXF1YXRpb25BbHBoYSksdGhpcy5ibGVuZENvbG9yJiZ0aGlzLmJsZW5kQ29sb3IuaXNDb2xvciYmKG4uYmxlbmRDb2xvcj10aGlzLmJsZW5kQ29sb3IuZ2V0SGV4KCkpLHRoaXMuYmxlbmRBbHBoYSE9PTAmJihuLmJsZW5kQWxwaGE9dGhpcy5ibGVuZEFscGhhKSx0aGlzLmRlcHRoRnVuYyE9PTMmJihuLmRlcHRoRnVuYz10aGlzLmRlcHRoRnVuYyksdGhpcy5kZXB0aFRlc3Q9PT0hMSYmKG4uZGVwdGhUZXN0PXRoaXMuZGVwdGhUZXN0KSx0aGlzLmRlcHRoV3JpdGU9PT0hMSYmKG4uZGVwdGhXcml0ZT10aGlzLmRlcHRoV3JpdGUpLHRoaXMuY29sb3JXcml0ZT09PSExJiYobi5jb2xvcldyaXRlPXRoaXMuY29sb3JXcml0ZSksdGhpcy5zdGVuY2lsV3JpdGVNYXNrIT09MjU1JiYobi5zdGVuY2lsV3JpdGVNYXNrPXRoaXMuc3RlbmNpbFdyaXRlTWFzayksdGhpcy5zdGVuY2lsRnVuYyE9PTUxOSYmKG4uc3RlbmNpbEZ1bmM9dGhpcy5zdGVuY2lsRnVuYyksdGhpcy5zdGVuY2lsUmVmIT09MCYmKG4uc3RlbmNpbFJlZj10aGlzLnN0ZW5jaWxSZWYpLHRoaXMuc3RlbmNpbEZ1bmNNYXNrIT09MjU1JiYobi5zdGVuY2lsRnVuY01hc2s9dGhpcy5zdGVuY2lsRnVuY01hc2spLHRoaXMuc3RlbmNpbEZhaWwhPT03NjgwJiYobi5zdGVuY2lsRmFpbD10aGlzLnN0ZW5jaWxGYWlsKSx0aGlzLnN0ZW5jaWxaRmFpbCE9PTc2ODAmJihuLnN0ZW5jaWxaRmFpbD10aGlzLnN0ZW5jaWxaRmFpbCksdGhpcy5zdGVuY2lsWlBhc3MhPT03NjgwJiYobi5zdGVuY2lsWlBhc3M9dGhpcy5zdGVuY2lsWlBhc3MpLHRoaXMuc3RlbmNpbFdyaXRlPT09ITAmJihuLnN0ZW5jaWxXcml0ZT10aGlzLnN0ZW5jaWxXcml0ZSksdGhpcy5yb3RhdGlvbiE9PXZvaWQgMCYmdGhpcy5yb3RhdGlvbiE9PTAmJihuLnJvdGF0aW9uPXRoaXMucm90YXRpb24pLHRoaXMucG9seWdvbk9mZnNldD09PSEwJiYobi5wb2x5Z29uT2Zmc2V0PSEwKSx0aGlzLnBvbHlnb25PZmZzZXRGYWN0b3IhPT0wJiYobi5wb2x5Z29uT2Zmc2V0RmFjdG9yPXRoaXMucG9seWdvbk9mZnNldEZhY3RvciksdGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHMhPT0wJiYobi5wb2x5Z29uT2Zmc2V0VW5pdHM9dGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHMpLHRoaXMubGluZXdpZHRoIT09dm9pZCAwJiZ0aGlzLmxpbmV3aWR0aCE9PTEmJihuLmxpbmV3aWR0aD10aGlzLmxpbmV3aWR0aCksdGhpcy5kYXNoU2l6ZSE9PXZvaWQgMCYmKG4uZGFzaFNpemU9dGhpcy5kYXNoU2l6ZSksdGhpcy5nYXBTaXplIT09dm9pZCAwJiYobi5nYXBTaXplPXRoaXMuZ2FwU2l6ZSksdGhpcy5zY2FsZSE9PXZvaWQgMCYmKG4uc2NhbGU9dGhpcy5zY2FsZSksdGhpcy5kaXRoZXJpbmc9PT0hMCYmKG4uZGl0aGVyaW5nPSEwKSx0aGlzLmFscGhhVGVzdD4wJiYobi5hbHBoYVRlc3Q9dGhpcy5hbHBoYVRlc3QpLHRoaXMuYWxwaGFIYXNoPT09ITAmJihuLmFscGhhSGFzaD0hMCksdGhpcy5hbHBoYVRvQ292ZXJhZ2U9PT0hMCYmKG4uYWxwaGFUb0NvdmVyYWdlPSEwKSx0aGlzLnByZW11bHRpcGxpZWRBbHBoYT09PSEwJiYobi5wcmVtdWx0aXBsaWVkQWxwaGE9ITApLHRoaXMuZm9yY2VTaW5nbGVQYXNzPT09ITAmJihuLmZvcmNlU2luZ2xlUGFzcz0hMCksdGhpcy53aXJlZnJhbWU9PT0hMCYmKG4ud2lyZWZyYW1lPSEwKSx0aGlzLndpcmVmcmFtZUxpbmV3aWR0aD4xJiYobi53aXJlZnJhbWVMaW5ld2lkdGg9dGhpcy53aXJlZnJhbWVMaW5ld2lkdGgpLHRoaXMud2lyZWZyYW1lTGluZWNhcCE9PSJyb3VuZCImJihuLndpcmVmcmFtZUxpbmVjYXA9dGhpcy53aXJlZnJhbWVMaW5lY2FwKSx0aGlzLndpcmVmcmFtZUxpbmVqb2luIT09InJvdW5kIiYmKG4ud2lyZWZyYW1lTGluZWpvaW49dGhpcy53aXJlZnJhbWVMaW5lam9pbiksdGhpcy5mbGF0U2hhZGluZz09PSEwJiYobi5mbGF0U2hhZGluZz0hMCksdGhpcy52aXNpYmxlPT09ITEmJihuLnZpc2libGU9ITEpLHRoaXMudG9uZU1hcHBlZD09PSExJiYobi50b25lTWFwcGVkPSExKSx0aGlzLmZvZz09PSExJiYobi5mb2c9ITEpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYobi51c2VyRGF0YT10aGlzLnVzZXJEYXRhKTtmdW5jdGlvbiBzKHIpe2NvbnN0IG89W107Zm9yKGNvbnN0IGEgaW4gcil7Y29uc3QgYz1yW2FdO2RlbGV0ZSBjLm1ldGFkYXRhLG8ucHVzaChjKX1yZXR1cm4gb31pZihlKXtjb25zdCByPXModC50ZXh0dXJlcyksbz1zKHQuaW1hZ2VzKTtyLmxlbmd0aD4wJiYobi50ZXh0dXJlcz1yKSxvLmxlbmd0aD4wJiYobi5pbWFnZXM9byl9cmV0dXJuIG59Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7dGhpcy5uYW1lPXQubmFtZSx0aGlzLmJsZW5kaW5nPXQuYmxlbmRpbmcsdGhpcy5zaWRlPXQuc2lkZSx0aGlzLnZlcnRleENvbG9ycz10LnZlcnRleENvbG9ycyx0aGlzLm9wYWNpdHk9dC5vcGFjaXR5LHRoaXMudHJhbnNwYXJlbnQ9dC50cmFuc3BhcmVudCx0aGlzLmJsZW5kU3JjPXQuYmxlbmRTcmMsdGhpcy5ibGVuZERzdD10LmJsZW5kRHN0LHRoaXMuYmxlbmRFcXVhdGlvbj10LmJsZW5kRXF1YXRpb24sdGhpcy5ibGVuZFNyY0FscGhhPXQuYmxlbmRTcmNBbHBoYSx0aGlzLmJsZW5kRHN0QWxwaGE9dC5ibGVuZERzdEFscGhhLHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhPXQuYmxlbmRFcXVhdGlvbkFscGhhLHRoaXMuYmxlbmRDb2xvci5jb3B5KHQuYmxlbmRDb2xvciksdGhpcy5ibGVuZEFscGhhPXQuYmxlbmRBbHBoYSx0aGlzLmRlcHRoRnVuYz10LmRlcHRoRnVuYyx0aGlzLmRlcHRoVGVzdD10LmRlcHRoVGVzdCx0aGlzLmRlcHRoV3JpdGU9dC5kZXB0aFdyaXRlLHRoaXMuc3RlbmNpbFdyaXRlTWFzaz10LnN0ZW5jaWxXcml0ZU1hc2ssdGhpcy5zdGVuY2lsRnVuYz10LnN0ZW5jaWxGdW5jLHRoaXMuc3RlbmNpbFJlZj10LnN0ZW5jaWxSZWYsdGhpcy5zdGVuY2lsRnVuY01hc2s9dC5zdGVuY2lsRnVuY01hc2ssdGhpcy5zdGVuY2lsRmFpbD10LnN0ZW5jaWxGYWlsLHRoaXMuc3RlbmNpbFpGYWlsPXQuc3RlbmNpbFpGYWlsLHRoaXMuc3RlbmNpbFpQYXNzPXQuc3RlbmNpbFpQYXNzLHRoaXMuc3RlbmNpbFdyaXRlPXQuc3RlbmNpbFdyaXRlO2NvbnN0IGU9dC5jbGlwcGluZ1BsYW5lcztsZXQgbj1udWxsO2lmKGUhPT1udWxsKXtjb25zdCBzPWUubGVuZ3RoO249bmV3IEFycmF5KHMpO2ZvcihsZXQgcj0wO3IhPT1zOysrciluW3JdPWVbcl0uY2xvbmUoKX1yZXR1cm4gdGhpcy5jbGlwcGluZ1BsYW5lcz1uLHRoaXMuY2xpcEludGVyc2VjdGlvbj10LmNsaXBJbnRlcnNlY3Rpb24sdGhpcy5jbGlwU2hhZG93cz10LmNsaXBTaGFkb3dzLHRoaXMuc2hhZG93U2lkZT10LnNoYWRvd1NpZGUsdGhpcy5jb2xvcldyaXRlPXQuY29sb3JXcml0ZSx0aGlzLnByZWNpc2lvbj10LnByZWNpc2lvbix0aGlzLnBvbHlnb25PZmZzZXQ9dC5wb2x5Z29uT2Zmc2V0LHRoaXMucG9seWdvbk9mZnNldEZhY3Rvcj10LnBvbHlnb25PZmZzZXRGYWN0b3IsdGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHM9dC5wb2x5Z29uT2Zmc2V0VW5pdHMsdGhpcy5kaXRoZXJpbmc9dC5kaXRoZXJpbmcsdGhpcy5hbHBoYVRlc3Q9dC5hbHBoYVRlc3QsdGhpcy5hbHBoYUhhc2g9dC5hbHBoYUhhc2gsdGhpcy5hbHBoYVRvQ292ZXJhZ2U9dC5hbHBoYVRvQ292ZXJhZ2UsdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE9dC5wcmVtdWx0aXBsaWVkQWxwaGEsdGhpcy5mb3JjZVNpbmdsZVBhc3M9dC5mb3JjZVNpbmdsZVBhc3MsdGhpcy52aXNpYmxlPXQudmlzaWJsZSx0aGlzLnRvbmVNYXBwZWQ9dC50b25lTWFwcGVkLHRoaXMudXNlckRhdGE9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0LnVzZXJEYXRhKSksdGhpc31kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfXNldCBuZWVkc1VwZGF0ZSh0KXt0PT09ITAmJnRoaXMudmVyc2lvbisrfX1jbGFzcyB5ZiBleHRlbmRzIHBme2NvbnN0cnVjdG9yKHQpe3N1cGVyKCksdGhpcy5pc01lc2hCYXNpY01hdGVyaWFsPSEwLHRoaXMudHlwZT0iTWVzaEJhc2ljTWF0ZXJpYWwiLHRoaXMuY29sb3I9bmV3IHlzKDE2Nzc3MjE1KSx0aGlzLm1hcD1udWxsLHRoaXMubGlnaHRNYXA9bnVsbCx0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5PTEsdGhpcy5hb01hcD1udWxsLHRoaXMuYW9NYXBJbnRlbnNpdHk9MSx0aGlzLnNwZWN1bGFyTWFwPW51bGwsdGhpcy5hbHBoYU1hcD1udWxsLHRoaXMuZW52TWFwPW51bGwsdGhpcy5lbnZNYXBSb3RhdGlvbj1uZXcgYmksdGhpcy5jb21iaW5lPTAsdGhpcy5yZWZsZWN0aXZpdHk9MSx0aGlzLnJlZnJhY3Rpb25SYXRpbz0uOTgsdGhpcy53aXJlZnJhbWU9ITEsdGhpcy53aXJlZnJhbWVMaW5ld2lkdGg9MSx0aGlzLndpcmVmcmFtZUxpbmVjYXA9InJvdW5kIix0aGlzLndpcmVmcmFtZUxpbmVqb2luPSJyb3VuZCIsdGhpcy5mb2c9ITAsdGhpcy5zZXRWYWx1ZXModCl9Y29weSh0KXtyZXR1cm4gc3VwZXIuY29weSh0KSx0aGlzLmNvbG9yLmNvcHkodC5jb2xvciksdGhpcy5tYXA9dC5tYXAsdGhpcy5saWdodE1hcD10LmxpZ2h0TWFwLHRoaXMubGlnaHRNYXBJbnRlbnNpdHk9dC5saWdodE1hcEludGVuc2l0eSx0aGlzLmFvTWFwPXQuYW9NYXAsdGhpcy5hb01hcEludGVuc2l0eT10LmFvTWFwSW50ZW5zaXR5LHRoaXMuc3BlY3VsYXJNYXA9dC5zcGVjdWxhck1hcCx0aGlzLmFscGhhTWFwPXQuYWxwaGFNYXAsdGhpcy5lbnZNYXA9dC5lbnZNYXAsdGhpcy5lbnZNYXBSb3RhdGlvbi5jb3B5KHQuZW52TWFwUm90YXRpb24pLHRoaXMuY29tYmluZT10LmNvbWJpbmUsdGhpcy5yZWZsZWN0aXZpdHk9dC5yZWZsZWN0aXZpdHksdGhpcy5yZWZyYWN0aW9uUmF0aW89dC5yZWZyYWN0aW9uUmF0aW8sdGhpcy53aXJlZnJhbWU9dC53aXJlZnJhbWUsdGhpcy53aXJlZnJhbWVMaW5ld2lkdGg9dC53aXJlZnJhbWVMaW5ld2lkdGgsdGhpcy53aXJlZnJhbWVMaW5lY2FwPXQud2lyZWZyYW1lTGluZWNhcCx0aGlzLndpcmVmcmFtZUxpbmVqb2luPXQud2lyZWZyYW1lTGluZWpvaW4sdGhpcy5mb2c9dC5mb2csdGhpc319Y29uc3QgcHQ9bmV3IFQsbXM9bmV3IFI7bGV0IG1mPTA7Y2xhc3MgeHR7Y29uc3RydWN0b3IodCxlLG49ITEpe2lmKEFycmF5LmlzQXJyYXkodCkpdGhyb3cgbmV3IFR5cGVFcnJvcigiVEhSRUUuQnVmZmVyQXR0cmlidXRlOiBhcnJheSBzaG91bGQgYmUgYSBUeXBlZCBBcnJheS4iKTt0aGlzLmlzQnVmZmVyQXR0cmlidXRlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOm1mKyt9KSx0aGlzLm5hbWU9IiIsdGhpcy5hcnJheT10LHRoaXMuaXRlbVNpemU9ZSx0aGlzLmNvdW50PXQhPT12b2lkIDA/dC5sZW5ndGgvZTowLHRoaXMubm9ybWFsaXplZD1uLHRoaXMudXNhZ2U9MzUwNDQsdGhpcy51cGRhdGVSYW5nZXM9W10sdGhpcy5ncHVUeXBlPTEwMTUsdGhpcy52ZXJzaW9uPTB9b25VcGxvYWRDYWxsYmFjaygpe31zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK31zZXRVc2FnZSh0KXtyZXR1cm4gdGhpcy51c2FnZT10LHRoaXN9YWRkVXBkYXRlUmFuZ2UodCxlKXt0aGlzLnVwZGF0ZVJhbmdlcy5wdXNoKHtzdGFydDp0LGNvdW50OmV9KX1jbGVhclVwZGF0ZVJhbmdlcygpe3RoaXMudXBkYXRlUmFuZ2VzLmxlbmd0aD0wfWNvcHkodCl7cmV0dXJuIHRoaXMubmFtZT10Lm5hbWUsdGhpcy5hcnJheT1uZXcgdC5hcnJheS5jb25zdHJ1Y3Rvcih0LmFycmF5KSx0aGlzLml0ZW1TaXplPXQuaXRlbVNpemUsdGhpcy5jb3VudD10LmNvdW50LHRoaXMubm9ybWFsaXplZD10Lm5vcm1hbGl6ZWQsdGhpcy51c2FnZT10LnVzYWdlLHRoaXMuZ3B1VHlwZT10LmdwdVR5cGUsdGhpc31jb3B5QXQodCxlLG4pe3QqPXRoaXMuaXRlbVNpemUsbio9ZS5pdGVtU2l6ZTtmb3IobGV0IHM9MCxyPXRoaXMuaXRlbVNpemU7czxyO3MrKyl0aGlzLmFycmF5W3Qrc109ZS5hcnJheVtuK3NdO3JldHVybiB0aGlzfWNvcHlBcnJheSh0KXtyZXR1cm4gdGhpcy5hcnJheS5zZXQodCksdGhpc31hcHBseU1hdHJpeDModCl7aWYodGhpcy5pdGVtU2l6ZT09PTIpZm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspbXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLG1zLmFwcGx5TWF0cml4Myh0KSx0aGlzLnNldFhZKGUsbXMueCxtcy55KTtlbHNlIGlmKHRoaXMuaXRlbVNpemU9PT0zKWZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC5hcHBseU1hdHJpeDModCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9YXBwbHlNYXRyaXg0KHQpe2ZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC5hcHBseU1hdHJpeDQodCksdGhpcy5zZXRYWVooZSxwdC54LHB0LnkscHQueik7cmV0dXJuIHRoaXN9YXBwbHlOb3JtYWxNYXRyaXgodCl7Zm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LmFwcGx5Tm9ybWFsTWF0cml4KHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfXRyYW5zZm9ybURpcmVjdGlvbih0KXtmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQudHJhbnNmb3JtRGlyZWN0aW9uKHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfXNldCh0LGU9MCl7cmV0dXJuIHRoaXMuYXJyYXkuc2V0KHQsZSksdGhpc31nZXRDb21wb25lbnQodCxlKXtsZXQgbj10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZStlXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYobj1taShuLHRoaXMuYXJyYXkpKSxufXNldENvbXBvbmVudCh0LGUsbil7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKG49SXQobix0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrZV09bix0aGlzfWdldFgodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemVdO3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPW1pKGUsdGhpcy5hcnJheSkpLGV9c2V0WCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplXT1lLHRoaXN9Z2V0WSh0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsxXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1taShlLHRoaXMuYXJyYXkpKSxlfXNldFkodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsxXT1lLHRoaXN9Z2V0Wih0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsyXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1taShlLHRoaXMuYXJyYXkpKSxlfXNldFoodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSsyXT1lLHRoaXN9Z2V0Vyh0KXtsZXQgZT10aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSszXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1taShlLHRoaXMuYXJyYXkpKSxlfXNldFcodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZSszXT1lLHRoaXN9c2V0WFkodCxlLG4pe3JldHVybiB0Kj10aGlzLml0ZW1TaXplLHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSxuPUl0KG4sdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCswXT1lLHRoaXMuYXJyYXlbdCsxXT1uLHRoaXN9c2V0WFlaKHQsZSxuLHMpe3JldHVybiB0Kj10aGlzLml0ZW1TaXplLHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSxuPUl0KG4sdGhpcy5hcnJheSkscz1JdChzLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QrMF09ZSx0aGlzLmFycmF5W3QrMV09bix0aGlzLmFycmF5W3QrMl09cyx0aGlzfXNldFhZWlcodCxlLG4scyxyKXtyZXR1cm4gdCo9dGhpcy5pdGVtU2l6ZSx0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSksbj1JdChuLHRoaXMuYXJyYXkpLHM9SXQocyx0aGlzLmFycmF5KSxyPUl0KHIsdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCswXT1lLHRoaXMuYXJyYXlbdCsxXT1uLHRoaXMuYXJyYXlbdCsyXT1zLHRoaXMuYXJyYXlbdCszXT1yLHRoaXN9b25VcGxvYWQodCl7cmV0dXJuIHRoaXMub25VcGxvYWRDYWxsYmFjaz10LHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5hcnJheSx0aGlzLml0ZW1TaXplKS5jb3B5KHRoaXMpfXRvSlNPTigpe2NvbnN0IHQ9e2l0ZW1TaXplOnRoaXMuaXRlbVNpemUsdHlwZTp0aGlzLmFycmF5LmNvbnN0cnVjdG9yLm5hbWUsYXJyYXk6QXJyYXkuZnJvbSh0aGlzLmFycmF5KSxub3JtYWxpemVkOnRoaXMubm9ybWFsaXplZH07cmV0dXJuIHRoaXMubmFtZSE9PSIiJiYodC5uYW1lPXRoaXMubmFtZSksdGhpcy51c2FnZSE9PTM1MDQ0JiYodC51c2FnZT10aGlzLnVzYWdlKSx0fX1jbGFzcyBnZiBleHRlbmRzIHh0e2NvbnN0cnVjdG9yKHQsZSxuKXtzdXBlcihuZXcgVWludDE2QXJyYXkodCksZSxuKX19Y2xhc3MgeGYgZXh0ZW5kcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbil7c3VwZXIobmV3IFVpbnQzMkFycmF5KHQpLGUsbil9fWNsYXNzIEJlIGV4dGVuZHMgeHR7Y29uc3RydWN0b3IodCxlLG4pe3N1cGVyKG5ldyBGbG9hdDMyQXJyYXkodCksZSxuKX19bGV0IHdmPTA7Y29uc3QganQ9bmV3IHN0LFNvPW5ldyBFZSxxbj1uZXcgVCxWdD1uZXcgZ3QsQWk9bmV3IGd0LGJ0PW5ldyBUO2NsYXNzIHVlIGV4dGVuZHMgb3N7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNCdWZmZXJHZW9tZXRyeT0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTp3ZisrfSksdGhpcy51dWlkPUZuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iQnVmZmVyR2VvbWV0cnkiLHRoaXMuaW5kZXg9bnVsbCx0aGlzLmluZGlyZWN0PW51bGwsdGhpcy5hdHRyaWJ1dGVzPXt9LHRoaXMubW9ycGhBdHRyaWJ1dGVzPXt9LHRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU9ITEsdGhpcy5ncm91cHM9W10sdGhpcy5ib3VuZGluZ0JveD1udWxsLHRoaXMuYm91bmRpbmdTcGhlcmU9bnVsbCx0aGlzLmRyYXdSYW5nZT17c3RhcnQ6MCxjb3VudDoxLzB9LHRoaXMudXNlckRhdGE9e319Z2V0SW5kZXgoKXtyZXR1cm4gdGhpcy5pbmRleH1zZXRJbmRleCh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90aGlzLmluZGV4PW5ldyhRdSh0KT94ZjpnZikodCwxKTp0aGlzLmluZGV4PXQsdGhpc31zZXRJbmRpcmVjdCh0KXtyZXR1cm4gdGhpcy5pbmRpcmVjdD10LHRoaXN9Z2V0SW5kaXJlY3QoKXtyZXR1cm4gdGhpcy5pbmRpcmVjdH1nZXRBdHRyaWJ1dGUodCl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XX1zZXRBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdPWUsdGhpc31kZWxldGVBdHRyaWJ1dGUodCl7cmV0dXJuIGRlbGV0ZSB0aGlzLmF0dHJpYnV0ZXNbdF0sdGhpc31oYXNBdHRyaWJ1dGUodCl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XSE9PXZvaWQgMH1hZGRHcm91cCh0LGUsbj0wKXt0aGlzLmdyb3Vwcy5wdXNoKHtzdGFydDp0LGNvdW50OmUsbWF0ZXJpYWxJbmRleDpufSl9Y2xlYXJHcm91cHMoKXt0aGlzLmdyb3Vwcz1bXX1zZXREcmF3UmFuZ2UodCxlKXt0aGlzLmRyYXdSYW5nZS5zdGFydD10LHRoaXMuZHJhd1JhbmdlLmNvdW50PWV9YXBwbHlNYXRyaXg0KHQpe2NvbnN0IGU9dGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uO2UhPT12b2lkIDAmJihlLmFwcGx5TWF0cml4NCh0KSxlLm5lZWRzVXBkYXRlPSEwKTtjb25zdCBuPXRoaXMuYXR0cmlidXRlcy5ub3JtYWw7aWYobiE9PXZvaWQgMCl7Y29uc3Qgcj1uZXcgZ2UoKS5nZXROb3JtYWxNYXRyaXgodCk7bi5hcHBseU5vcm1hbE1hdHJpeChyKSxuLm5lZWRzVXBkYXRlPSEwfWNvbnN0IHM9dGhpcy5hdHRyaWJ1dGVzLnRhbmdlbnQ7cmV0dXJuIHMhPT12b2lkIDAmJihzLnRyYW5zZm9ybURpcmVjdGlvbih0KSxzLm5lZWRzVXBkYXRlPSEwKSx0aGlzLmJvdW5kaW5nQm94IT09bnVsbCYmdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKSx0aGlzLmJvdW5kaW5nU3BoZXJlIT09bnVsbCYmdGhpcy5jb21wdXRlQm91bmRpbmdTcGhlcmUoKSx0aGlzfWFwcGx5UXVhdGVybmlvbih0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9cm90YXRlWCh0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uWCh0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31yb3RhdGVZKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25ZKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXJvdGF0ZVoodCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvbloodCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9dHJhbnNsYXRlKHQsZSxuKXtyZXR1cm4ganQubWFrZVRyYW5zbGF0aW9uKHQsZSxuKSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31zY2FsZSh0LGUsbil7cmV0dXJuIGp0Lm1ha2VTY2FsZSh0LGUsbiksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9bG9va0F0KHQpe3JldHVybiBTby5sb29rQXQodCksU28udXBkYXRlTWF0cml4KCksdGhpcy5hcHBseU1hdHJpeDQoU28ubWF0cml4KSx0aGlzfWNlbnRlcigpe3JldHVybiB0aGlzLmNvbXB1dGVCb3VuZGluZ0JveCgpLHRoaXMuYm91bmRpbmdCb3guZ2V0Q2VudGVyKHFuKS5uZWdhdGUoKSx0aGlzLnRyYW5zbGF0ZShxbi54LHFuLnkscW4ueiksdGhpc31zZXRGcm9tUG9pbnRzKHQpe2NvbnN0IGU9dGhpcy5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIik7aWYoZT09PXZvaWQgMCl7Y29uc3Qgbj1bXTtmb3IobGV0IHM9MCxyPXQubGVuZ3RoO3M8cjtzKyspe2NvbnN0IG89dFtzXTtuLnB1c2goby54LG8ueSxvLnp8fDApfXRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsbmV3IEJlKG4sMykpfWVsc2V7Y29uc3Qgbj1NYXRoLm1pbih0Lmxlbmd0aCxlLmNvdW50KTtmb3IobGV0IHM9MDtzPG47cysrKXtjb25zdCByPXRbc107ZS5zZXRYWVoocyxyLngsci55LHIuenx8MCl9dC5sZW5ndGg+ZS5jb3VudCYmY29uc29sZS53YXJuKCJUSFJFRS5CdWZmZXJHZW9tZXRyeTogQnVmZmVyIHNpemUgdG9vIHNtYWxsIGZvciBwb2ludHMgZGF0YS4gVXNlIC5kaXNwb3NlKCkgYW5kIGNyZWF0ZSBhIG5ldyBnZW9tZXRyeS4iKSxlLm5lZWRzVXBkYXRlPSEwfXJldHVybiB0aGlzfWNvbXB1dGVCb3VuZGluZ0JveCgpe3RoaXMuYm91bmRpbmdCb3g9PT1udWxsJiYodGhpcy5ib3VuZGluZ0JveD1uZXcgZ3QpO2NvbnN0IHQ9dGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uLGU9dGhpcy5tb3JwaEF0dHJpYnV0ZXMucG9zaXRpb247aWYodCYmdC5pc0dMQnVmZmVyQXR0cmlidXRlKXtjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTogR0xCdWZmZXJBdHRyaWJ1dGUgcmVxdWlyZXMgYSBtYW51YWwgYm91bmRpbmcgYm94LiIsdGhpcyksdGhpcy5ib3VuZGluZ0JveC5zZXQobmV3IFQoLTEvMCwtMS8wLC0xLzApLG5ldyBUKDEvMCwxLzAsMS8wKSk7cmV0dXJufWlmKHQhPT12b2lkIDApe2lmKHRoaXMuYm91bmRpbmdCb3guc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSh0KSxlKWZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyl7Y29uc3Qgcj1lW25dO1Z0LnNldEZyb21CdWZmZXJBdHRyaWJ1dGUociksdGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT8oYnQuYWRkVmVjdG9ycyh0aGlzLmJvdW5kaW5nQm94Lm1pbixWdC5taW4pLHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChidCksYnQuYWRkVmVjdG9ycyh0aGlzLmJvdW5kaW5nQm94Lm1heCxWdC5tYXgpLHRoaXMuYm91bmRpbmdCb3guZXhwYW5kQnlQb2ludChidCkpOih0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoVnQubWluKSx0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoVnQubWF4KSl9fWVsc2UgdGhpcy5ib3VuZGluZ0JveC5tYWtlRW1wdHkoKTsoaXNOYU4odGhpcy5ib3VuZGluZ0JveC5taW4ueCl8fGlzTmFOKHRoaXMuYm91bmRpbmdCb3gubWluLnkpfHxpc05hTih0aGlzLmJvdW5kaW5nQm94Lm1pbi56KSkmJmNvbnNvbGUuZXJyb3IoJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ0JveCgpOiBDb21wdXRlZCBtaW4vbWF4IGhhdmUgTmFOIHZhbHVlcy4gVGhlICJwb3NpdGlvbiIgYXR0cmlidXRlIGlzIGxpa2VseSB0byBoYXZlIE5hTiB2YWx1ZXMuJyx0aGlzKX1jb21wdXRlQm91bmRpbmdTcGhlcmUoKXt0aGlzLmJvdW5kaW5nU3BoZXJlPT09bnVsbCYmKHRoaXMuYm91bmRpbmdTcGhlcmU9bmV3IGNvKTtjb25zdCB0PXRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbixlPXRoaXMubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uO2lmKHQmJnQuaXNHTEJ1ZmZlckF0dHJpYnV0ZSl7Y29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCk6IEdMQnVmZmVyQXR0cmlidXRlIHJlcXVpcmVzIGEgbWFudWFsIGJvdW5kaW5nIHNwaGVyZS4iLHRoaXMpLHRoaXMuYm91bmRpbmdTcGhlcmUuc2V0KG5ldyBULDEvMCk7cmV0dXJufWlmKHQpe2NvbnN0IG49dGhpcy5ib3VuZGluZ1NwaGVyZS5jZW50ZXI7aWYoVnQuc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSh0KSxlKWZvcihsZXQgcj0wLG89ZS5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1lW3JdO0FpLnNldEZyb21CdWZmZXJBdHRyaWJ1dGUoYSksdGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZT8oYnQuYWRkVmVjdG9ycyhWdC5taW4sQWkubWluKSxWdC5leHBhbmRCeVBvaW50KGJ0KSxidC5hZGRWZWN0b3JzKFZ0Lm1heCxBaS5tYXgpLFZ0LmV4cGFuZEJ5UG9pbnQoYnQpKTooVnQuZXhwYW5kQnlQb2ludChBaS5taW4pLFZ0LmV4cGFuZEJ5UG9pbnQoQWkubWF4KSl9VnQuZ2V0Q2VudGVyKG4pO2xldCBzPTA7Zm9yKGxldCByPTAsbz10LmNvdW50O3I8bztyKyspYnQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LHIpLHM9TWF0aC5tYXgocyxuLmRpc3RhbmNlVG9TcXVhcmVkKGJ0KSk7aWYoZSlmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVtyXSxjPXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU7Zm9yKGxldCBsPTAsaD1hLmNvdW50O2w8aDtsKyspYnQuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGwpLGMmJihxbi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsbCksYnQuYWRkKHFuKSkscz1NYXRoLm1heChzLG4uZGlzdGFuY2VUb1NxdWFyZWQoYnQpKX10aGlzLmJvdW5kaW5nU3BoZXJlLnJhZGl1cz1NYXRoLnNxcnQocyksaXNOYU4odGhpcy5ib3VuZGluZ1NwaGVyZS5yYWRpdXMpJiZjb25zb2xlLmVycm9yKCdUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTogQ29tcHV0ZWQgcmFkaXVzIGlzIE5hTi4gVGhlICJwb3NpdGlvbiIgYXR0cmlidXRlIGlzIGxpa2VseSB0byBoYXZlIE5hTiB2YWx1ZXMuJyx0aGlzKX19Y29tcHV0ZVRhbmdlbnRzKCl7Y29uc3QgdD10aGlzLmluZGV4LGU9dGhpcy5hdHRyaWJ1dGVzO2lmKHQ9PT1udWxsfHxlLnBvc2l0aW9uPT09dm9pZCAwfHxlLm5vcm1hbD09PXZvaWQgMHx8ZS51dj09PXZvaWQgMCl7Y29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnk6IC5jb21wdXRlVGFuZ2VudHMoKSBmYWlsZWQuIE1pc3NpbmcgcmVxdWlyZWQgYXR0cmlidXRlcyAoaW5kZXgsIHBvc2l0aW9uLCBub3JtYWwgb3IgdXYpIik7cmV0dXJufWNvbnN0IG49ZS5wb3NpdGlvbixzPWUubm9ybWFsLHI9ZS51djt0aGlzLmhhc0F0dHJpYnV0ZSgidGFuZ2VudCIpPT09ITEmJnRoaXMuc2V0QXR0cmlidXRlKCJ0YW5nZW50IixuZXcgeHQobmV3IEZsb2F0MzJBcnJheSg0Km4uY291bnQpLDQpKTtjb25zdCBvPXRoaXMuZ2V0QXR0cmlidXRlKCJ0YW5nZW50IiksYT1bXSxjPVtdO2ZvcihsZXQgXz0wO188bi5jb3VudDtfKyspYVtfXT1uZXcgVCxjW19dPW5ldyBUO2NvbnN0IGw9bmV3IFQsaD1uZXcgVCx1PW5ldyBULGY9bmV3IFIsZD1uZXcgUixwPW5ldyBSLHk9bmV3IFQsbT1uZXcgVDtmdW5jdGlvbiBnKF8sRSx6KXtsLmZyb21CdWZmZXJBdHRyaWJ1dGUobixfKSxoLmZyb21CdWZmZXJBdHRyaWJ1dGUobixFKSx1LmZyb21CdWZmZXJBdHRyaWJ1dGUobix6KSxmLmZyb21CdWZmZXJBdHRyaWJ1dGUocixfKSxkLmZyb21CdWZmZXJBdHRyaWJ1dGUocixFKSxwLmZyb21CdWZmZXJBdHRyaWJ1dGUocix6KSxoLnN1YihsKSx1LnN1YihsKSxkLnN1YihmKSxwLnN1YihmKTtjb25zdCB2PTEvKGQueCpwLnktcC54KmQueSk7aXNGaW5pdGUodikmJih5LmNvcHkoaCkubXVsdGlwbHlTY2FsYXIocC55KS5hZGRTY2FsZWRWZWN0b3IodSwtZC55KS5tdWx0aXBseVNjYWxhcih2KSxtLmNvcHkodSkubXVsdGlwbHlTY2FsYXIoZC54KS5hZGRTY2FsZWRWZWN0b3IoaCwtcC54KS5tdWx0aXBseVNjYWxhcih2KSxhW19dLmFkZCh5KSxhW0VdLmFkZCh5KSxhW3pdLmFkZCh5KSxjW19dLmFkZChtKSxjW0VdLmFkZChtKSxjW3pdLmFkZChtKSl9bGV0IGI9dGhpcy5ncm91cHM7Yi5sZW5ndGg9PT0wJiYoYj1be3N0YXJ0OjAsY291bnQ6dC5jb3VudH1dKTtmb3IobGV0IF89MCxFPWIubGVuZ3RoO188RTsrK18pe2NvbnN0IHo9YltfXSx2PXouc3RhcnQsQz16LmNvdW50O2ZvcihsZXQgUD12LEY9ditDO1A8RjtQKz0zKWcodC5nZXRYKFArMCksdC5nZXRYKFArMSksdC5nZXRYKFArMikpfWNvbnN0IHc9bmV3IFQseD1uZXcgVCxNPW5ldyBULEE9bmV3IFQ7ZnVuY3Rpb24gUyhfKXtNLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxfKSxBLmNvcHkoTSk7Y29uc3QgRT1hW19dO3cuY29weShFKSx3LnN1YihNLm11bHRpcGx5U2NhbGFyKE0uZG90KEUpKSkubm9ybWFsaXplKCkseC5jcm9zc1ZlY3RvcnMoQSxFKTtjb25zdCB2PXguZG90KGNbX10pPDA/LTE6MTtvLnNldFhZWlcoXyx3Lngsdy55LHcueix2KX1mb3IobGV0IF89MCxFPWIubGVuZ3RoO188RTsrK18pe2NvbnN0IHo9YltfXSx2PXouc3RhcnQsQz16LmNvdW50O2ZvcihsZXQgUD12LEY9ditDO1A8RjtQKz0zKVModC5nZXRYKFArMCkpLFModC5nZXRYKFArMSkpLFModC5nZXRYKFArMikpfX1jb21wdXRlVmVydGV4Tm9ybWFscygpe2NvbnN0IHQ9dGhpcy5pbmRleCxlPXRoaXMuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpO2lmKGUhPT12b2lkIDApe2xldCBuPXRoaXMuZ2V0QXR0cmlidXRlKCJub3JtYWwiKTtpZihuPT09dm9pZCAwKW49bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkoZS5jb3VudCozKSwzKSx0aGlzLnNldEF0dHJpYnV0ZSgibm9ybWFsIixuKTtlbHNlIGZvcihsZXQgZj0wLGQ9bi5jb3VudDtmPGQ7ZisrKW4uc2V0WFlaKGYsMCwwLDApO2NvbnN0IHM9bmV3IFQscj1uZXcgVCxvPW5ldyBULGE9bmV3IFQsYz1uZXcgVCxsPW5ldyBULGg9bmV3IFQsdT1uZXcgVDtpZih0KWZvcihsZXQgZj0wLGQ9dC5jb3VudDtmPGQ7Zis9Myl7Y29uc3QgcD10LmdldFgoZiswKSx5PXQuZ2V0WChmKzEpLG09dC5nZXRYKGYrMik7cy5mcm9tQnVmZmVyQXR0cmlidXRlKGUscCksci5mcm9tQnVmZmVyQXR0cmlidXRlKGUseSksby5mcm9tQnVmZmVyQXR0cmlidXRlKGUsbSksaC5zdWJWZWN0b3JzKG8sciksdS5zdWJWZWN0b3JzKHMsciksaC5jcm9zcyh1KSxhLmZyb21CdWZmZXJBdHRyaWJ1dGUobixwKSxjLmZyb21CdWZmZXJBdHRyaWJ1dGUobix5KSxsLmZyb21CdWZmZXJBdHRyaWJ1dGUobixtKSxhLmFkZChoKSxjLmFkZChoKSxsLmFkZChoKSxuLnNldFhZWihwLGEueCxhLnksYS56KSxuLnNldFhZWih5LGMueCxjLnksYy56KSxuLnNldFhZWihtLGwueCxsLnksbC56KX1lbHNlIGZvcihsZXQgZj0wLGQ9ZS5jb3VudDtmPGQ7Zis9MylzLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxmKzApLHIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLGYrMSksby5mcm9tQnVmZmVyQXR0cmlidXRlKGUsZisyKSxoLnN1YlZlY3RvcnMobyxyKSx1LnN1YlZlY3RvcnMocyxyKSxoLmNyb3NzKHUpLG4uc2V0WFlaKGYrMCxoLngsaC55LGgueiksbi5zZXRYWVooZisxLGgueCxoLnksaC56KSxuLnNldFhZWihmKzIsaC54LGgueSxoLnopO3RoaXMubm9ybWFsaXplTm9ybWFscygpLG4ubmVlZHNVcGRhdGU9ITB9fW5vcm1hbGl6ZU5vcm1hbHMoKXtjb25zdCB0PXRoaXMuYXR0cmlidXRlcy5ub3JtYWw7Zm9yKGxldCBlPTAsbj10LmNvdW50O2U8bjtlKyspYnQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLGJ0Lm5vcm1hbGl6ZSgpLHQuc2V0WFlaKGUsYnQueCxidC55LGJ0LnopfXRvTm9uSW5kZXhlZCgpe2Z1bmN0aW9uIHQoYSxjKXtjb25zdCBsPWEuYXJyYXksaD1hLml0ZW1TaXplLHU9YS5ub3JtYWxpemVkLGY9bmV3IGwuY29uc3RydWN0b3IoYy5sZW5ndGgqaCk7bGV0IGQ9MCxwPTA7Zm9yKGxldCB5PTAsbT1jLmxlbmd0aDt5PG07eSsrKXthLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGU/ZD1jW3ldKmEuZGF0YS5zdHJpZGUrYS5vZmZzZXQ6ZD1jW3ldKmg7Zm9yKGxldCBnPTA7ZzxoO2crKylmW3ArK109bFtkKytdfXJldHVybiBuZXcgeHQoZixoLHUpfWlmKHRoaXMuaW5kZXg9PT1udWxsKXJldHVybiBjb25zb2xlLndhcm4oIlRIUkVFLkJ1ZmZlckdlb21ldHJ5LnRvTm9uSW5kZXhlZCgpOiBCdWZmZXJHZW9tZXRyeSBpcyBhbHJlYWR5IG5vbi1pbmRleGVkLiIpLHRoaXM7Y29uc3QgZT1uZXcgdWUsbj10aGlzLmluZGV4LmFycmF5LHM9dGhpcy5hdHRyaWJ1dGVzO2Zvcihjb25zdCBhIGluIHMpe2NvbnN0IGM9c1thXSxsPXQoYyxuKTtlLnNldEF0dHJpYnV0ZShhLGwpfWNvbnN0IHI9dGhpcy5tb3JwaEF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGEgaW4gcil7Y29uc3QgYz1bXSxsPXJbYV07Zm9yKGxldCBoPTAsdT1sLmxlbmd0aDtoPHU7aCsrKXtjb25zdCBmPWxbaF0sZD10KGYsbik7Yy5wdXNoKGQpfWUubW9ycGhBdHRyaWJ1dGVzW2FdPWN9ZS5tb3JwaFRhcmdldHNSZWxhdGl2ZT10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlO2NvbnN0IG89dGhpcy5ncm91cHM7Zm9yKGxldCBhPTAsYz1vLmxlbmd0aDthPGM7YSsrKXtjb25zdCBsPW9bYV07ZS5hZGRHcm91cChsLnN0YXJ0LGwuY291bnQsbC5tYXRlcmlhbEluZGV4KX1yZXR1cm4gZX10b0pTT04oKXtjb25zdCB0PXttZXRhZGF0YTp7dmVyc2lvbjo0LjcsdHlwZToiQnVmZmVyR2VvbWV0cnkiLGdlbmVyYXRvcjoiQnVmZmVyR2VvbWV0cnkudG9KU09OIn19O2lmKHQudXVpZD10aGlzLnV1aWQsdC50eXBlPXRoaXMudHlwZSx0aGlzLm5hbWUhPT0iIiYmKHQubmFtZT10aGlzLm5hbWUpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYodC51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSx0aGlzLnBhcmFtZXRlcnMhPT12b2lkIDApe2NvbnN0IGM9dGhpcy5wYXJhbWV0ZXJzO2Zvcihjb25zdCBsIGluIGMpY1tsXSE9PXZvaWQgMCYmKHRbbF09Y1tsXSk7cmV0dXJuIHR9dC5kYXRhPXthdHRyaWJ1dGVzOnt9fTtjb25zdCBlPXRoaXMuaW5kZXg7ZSE9PW51bGwmJih0LmRhdGEuaW5kZXg9e3R5cGU6ZS5hcnJheS5jb25zdHJ1Y3Rvci5uYW1lLGFycmF5OkFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGUuYXJyYXkpfSk7Y29uc3Qgbj10aGlzLmF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGMgaW4gbil7Y29uc3QgbD1uW2NdO3QuZGF0YS5hdHRyaWJ1dGVzW2NdPWwudG9KU09OKHQuZGF0YSl9Y29uc3Qgcz17fTtsZXQgcj0hMTtmb3IoY29uc3QgYyBpbiB0aGlzLm1vcnBoQXR0cmlidXRlcyl7Y29uc3QgbD10aGlzLm1vcnBoQXR0cmlidXRlc1tjXSxoPVtdO2ZvcihsZXQgdT0wLGY9bC5sZW5ndGg7dTxmO3UrKyl7Y29uc3QgZD1sW3VdO2gucHVzaChkLnRvSlNPTih0LmRhdGEpKX1oLmxlbmd0aD4wJiYoc1tjXT1oLHI9ITApfXImJih0LmRhdGEubW9ycGhBdHRyaWJ1dGVzPXMsdC5kYXRhLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmUpO2NvbnN0IG89dGhpcy5ncm91cHM7by5sZW5ndGg+MCYmKHQuZGF0YS5ncm91cHM9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvKSkpO2NvbnN0IGE9dGhpcy5ib3VuZGluZ1NwaGVyZTtyZXR1cm4gYSE9PW51bGwmJih0LmRhdGEuYm91bmRpbmdTcGhlcmU9YS50b0pTT04oKSksdH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXt0aGlzLmluZGV4PW51bGwsdGhpcy5hdHRyaWJ1dGVzPXt9LHRoaXMubW9ycGhBdHRyaWJ1dGVzPXt9LHRoaXMuZ3JvdXBzPVtdLHRoaXMuYm91bmRpbmdCb3g9bnVsbCx0aGlzLmJvdW5kaW5nU3BoZXJlPW51bGw7Y29uc3QgZT17fTt0aGlzLm5hbWU9dC5uYW1lO2NvbnN0IG49dC5pbmRleDtuIT09bnVsbCYmdGhpcy5zZXRJbmRleChuLmNsb25lKCkpO2NvbnN0IHM9dC5hdHRyaWJ1dGVzO2Zvcihjb25zdCBsIGluIHMpe2NvbnN0IGg9c1tsXTt0aGlzLnNldEF0dHJpYnV0ZShsLGguY2xvbmUoZSkpfWNvbnN0IHI9dC5tb3JwaEF0dHJpYnV0ZXM7Zm9yKGNvbnN0IGwgaW4gcil7Y29uc3QgaD1bXSx1PXJbbF07Zm9yKGxldCBmPTAsZD11Lmxlbmd0aDtmPGQ7ZisrKWgucHVzaCh1W2ZdLmNsb25lKGUpKTt0aGlzLm1vcnBoQXR0cmlidXRlc1tsXT1ofXRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU9dC5tb3JwaFRhcmdldHNSZWxhdGl2ZTtjb25zdCBvPXQuZ3JvdXBzO2ZvcihsZXQgbD0wLGg9by5sZW5ndGg7bDxoO2wrKyl7Y29uc3QgdT1vW2xdO3RoaXMuYWRkR3JvdXAodS5zdGFydCx1LmNvdW50LHUubWF0ZXJpYWxJbmRleCl9Y29uc3QgYT10LmJvdW5kaW5nQm94O2EhPT1udWxsJiYodGhpcy5ib3VuZGluZ0JveD1hLmNsb25lKCkpO2NvbnN0IGM9dC5ib3VuZGluZ1NwaGVyZTtyZXR1cm4gYyE9PW51bGwmJih0aGlzLmJvdW5kaW5nU3BoZXJlPWMuY2xvbmUoKSksdGhpcy5kcmF3UmFuZ2Uuc3RhcnQ9dC5kcmF3UmFuZ2Uuc3RhcnQsdGhpcy5kcmF3UmFuZ2UuY291bnQ9dC5kcmF3UmFuZ2UuY291bnQsdGhpcy51c2VyRGF0YT10LnVzZXJEYXRhLHRoaXN9ZGlzcG9zZSgpe3RoaXMuZGlzcGF0Y2hFdmVudCh7dHlwZToiZGlzcG9zZSJ9KX19Y29uc3QgTGM9bmV3IHN0LGZuPW5ldyBmbyxncz1uZXcgY28sT2M9bmV3IFQseHM9bmV3IFQsd3M9bmV3IFQsYnM9bmV3IFQsX289bmV3IFQsTXM9bmV3IFQsRGM9bmV3IFQsQXM9bmV3IFQ7Y2xhc3MgYmYgZXh0ZW5kcyBFZXtjb25zdHJ1Y3Rvcih0PW5ldyB1ZSxlPW5ldyB5Zil7c3VwZXIoKSx0aGlzLmlzTWVzaD0hMCx0aGlzLnR5cGU9Ik1lc2giLHRoaXMuZ2VvbWV0cnk9dCx0aGlzLm1hdGVyaWFsPWUsdGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9dm9pZCAwLHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPXZvaWQgMCx0aGlzLmNvdW50PTEsdGhpcy51cGRhdGVNb3JwaFRhcmdldHMoKX1jb3B5KHQsZSl7cmV0dXJuIHN1cGVyLmNvcHkodCxlKSx0Lm1vcnBoVGFyZ2V0SW5mbHVlbmNlcyE9PXZvaWQgMCYmKHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPXQubW9ycGhUYXJnZXRJbmZsdWVuY2VzLnNsaWNlKCkpLHQubW9ycGhUYXJnZXREaWN0aW9uYXJ5IT09dm9pZCAwJiYodGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9T2JqZWN0LmFzc2lnbih7fSx0Lm1vcnBoVGFyZ2V0RGljdGlvbmFyeSkpLHRoaXMubWF0ZXJpYWw9QXJyYXkuaXNBcnJheSh0Lm1hdGVyaWFsKT90Lm1hdGVyaWFsLnNsaWNlKCk6dC5tYXRlcmlhbCx0aGlzLmdlb21ldHJ5PXQuZ2VvbWV0cnksdGhpc311cGRhdGVNb3JwaFRhcmdldHMoKXtjb25zdCBlPXRoaXMuZ2VvbWV0cnkubW9ycGhBdHRyaWJ1dGVzLG49T2JqZWN0LmtleXMoZSk7aWYobi5sZW5ndGg+MCl7Y29uc3Qgcz1lW25bMF1dO2lmKHMhPT12b2lkIDApe3RoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPVtdLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5PXt9O2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1zW3JdLm5hbWV8fFN0cmluZyhyKTt0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcy5wdXNoKDApLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5W2FdPXJ9fX19Z2V0VmVydGV4UG9zaXRpb24odCxlKXtjb25zdCBuPXRoaXMuZ2VvbWV0cnkscz1uLmF0dHJpYnV0ZXMucG9zaXRpb24scj1uLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbixvPW4ubW9ycGhUYXJnZXRzUmVsYXRpdmU7ZS5mcm9tQnVmZmVyQXR0cmlidXRlKHMsdCk7Y29uc3QgYT10aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcztpZihyJiZhKXtNcy5zZXQoMCwwLDApO2ZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1hW2NdLHU9cltjXTtoIT09MCYmKF9vLmZyb21CdWZmZXJBdHRyaWJ1dGUodSx0KSxvP01zLmFkZFNjYWxlZFZlY3RvcihfbyxoKTpNcy5hZGRTY2FsZWRWZWN0b3IoX28uc3ViKGUpLGgpKX1lLmFkZChNcyl9cmV0dXJuIGV9cmF5Y2FzdCh0LGUpe2NvbnN0IG49dGhpcy5nZW9tZXRyeSxzPXRoaXMubWF0ZXJpYWwscj10aGlzLm1hdHJpeFdvcmxkO3MhPT12b2lkIDAmJihuLmJvdW5kaW5nU3BoZXJlPT09bnVsbCYmbi5jb21wdXRlQm91bmRpbmdTcGhlcmUoKSxncy5jb3B5KG4uYm91bmRpbmdTcGhlcmUpLGdzLmFwcGx5TWF0cml4NChyKSxmbi5jb3B5KHQucmF5KS5yZWNhc3QodC5uZWFyKSwhKGdzLmNvbnRhaW5zUG9pbnQoZm4ub3JpZ2luKT09PSExJiYoZm4uaW50ZXJzZWN0U3BoZXJlKGdzLE9jKT09PW51bGx8fGZuLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZChPYyk+eWkodC5mYXItdC5uZWFyLDIpKSkmJihMYy5jb3B5KHIpLmludmVydCgpLGZuLmNvcHkodC5yYXkpLmFwcGx5TWF0cml4NChMYyksIShuLmJvdW5kaW5nQm94IT09bnVsbCYmZm4uaW50ZXJzZWN0c0JveChuLmJvdW5kaW5nQm94KT09PSExKSYmdGhpcy5fY29tcHV0ZUludGVyc2VjdGlvbnModCxlLGZuKSkpfV9jb21wdXRlSW50ZXJzZWN0aW9ucyh0LGUsbil7bGV0IHM7Y29uc3Qgcj10aGlzLmdlb21ldHJ5LG89dGhpcy5tYXRlcmlhbCxhPXIuaW5kZXgsYz1yLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1yLmF0dHJpYnV0ZXMudXYsaD1yLmF0dHJpYnV0ZXMudXYxLHU9ci5hdHRyaWJ1dGVzLm5vcm1hbCxmPXIuZ3JvdXBzLGQ9ci5kcmF3UmFuZ2U7aWYoYSE9PW51bGwpaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihhLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9YS5nZXRYKHgpLFM9YS5nZXRYKHgrMSksXz1hLmdldFgoeCsyKTtzPVNzKHRoaXMsZyx0LG4sbCxoLHUsQSxTLF8pLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYS5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1hLmdldFgobSksdz1hLmdldFgobSsxKSx4PWEuZ2V0WChtKzIpO3M9U3ModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX1lbHNlIGlmKGMhPT12b2lkIDApaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihjLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9eCxTPXgrMSxfPXgrMjtzPVNzKHRoaXMsZyx0LG4sbCxoLHUsQSxTLF8pLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYy5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1tLHc9bSsxLHg9bSsyO3M9U3ModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX19fWZ1bmN0aW9uIE1mKGksdCxlLG4scyxyLG8sYSl7bGV0IGM7aWYodC5zaWRlPT09MT9jPW4uaW50ZXJzZWN0VHJpYW5nbGUobyxyLHMsITAsYSk6Yz1uLmludGVyc2VjdFRyaWFuZ2xlKHMscixvLHQuc2lkZT09PTAsYSksYz09PW51bGwpcmV0dXJuIG51bGw7QXMuY29weShhKSxBcy5hcHBseU1hdHJpeDQoaS5tYXRyaXhXb3JsZCk7Y29uc3QgbD1lLnJheS5vcmlnaW4uZGlzdGFuY2VUbyhBcyk7cmV0dXJuIGw8ZS5uZWFyfHxsPmUuZmFyP251bGw6e2Rpc3RhbmNlOmwscG9pbnQ6QXMuY2xvbmUoKSxvYmplY3Q6aX19ZnVuY3Rpb24gU3MoaSx0LGUsbixzLHIsbyxhLGMsbCl7aS5nZXRWZXJ0ZXhQb3NpdGlvbihhLHhzKSxpLmdldFZlcnRleFBvc2l0aW9uKGMsd3MpLGkuZ2V0VmVydGV4UG9zaXRpb24obCxicyk7Y29uc3QgaD1NZihpLHQsZSxuLHhzLHdzLGJzLERjKTtpZihoKXtjb25zdCB1PW5ldyBUO2V0LmdldEJhcnljb29yZChEYyx4cyx3cyxicyx1KSxzJiYoaC51dj1ldC5nZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUocyxhLGMsbCx1LG5ldyBSKSksciYmKGgudXYxPWV0LmdldEludGVycG9sYXRlZEF0dHJpYnV0ZShyLGEsYyxsLHUsbmV3IFIpKSxvJiYoaC5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKG8sYSxjLGwsdSxuZXcgVCksaC5ub3JtYWwuZG90KG4uZGlyZWN0aW9uKT4wJiZoLm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGY9e2EsYjpjLGM6bCxub3JtYWw6bmV3IFQsbWF0ZXJpYWxJbmRleDowfTtldC5nZXROb3JtYWwoeHMsd3MsYnMsZi5ub3JtYWwpLGguZmFjZT1mLGguYmFyeWNvb3JkPXV9cmV0dXJuIGh9Y29uc3Qgdm89bmV3IFQsQWY9bmV3IFQsU2Y9bmV3IGdlO2NsYXNzIHpve2NvbnN0cnVjdG9yKHQ9bmV3IFQoMSwwLDApLGU9MCl7dGhpcy5pc1BsYW5lPSEwLHRoaXMubm9ybWFsPXQsdGhpcy5jb25zdGFudD1lfXNldCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbC5jb3B5KHQpLHRoaXMuY29uc3RhbnQ9ZSx0aGlzfXNldENvbXBvbmVudHModCxlLG4scyl7cmV0dXJuIHRoaXMubm9ybWFsLnNldCh0LGUsbiksdGhpcy5jb25zdGFudD1zLHRoaXN9c2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWwuY29weSh0KSx0aGlzLmNvbnN0YW50PS1lLmRvdCh0aGlzLm5vcm1hbCksdGhpc31zZXRGcm9tQ29wbGFuYXJQb2ludHModCxlLG4pe2NvbnN0IHM9dm8uc3ViVmVjdG9ycyhuLGUpLmNyb3NzKEFmLnN1YlZlY3RvcnModCxlKSkubm9ybWFsaXplKCk7cmV0dXJuIHRoaXMuc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQocyx0KSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMubm9ybWFsLmNvcHkodC5ub3JtYWwpLHRoaXMuY29uc3RhbnQ9dC5jb25zdGFudCx0aGlzfW5vcm1hbGl6ZSgpe2NvbnN0IHQ9MS90aGlzLm5vcm1hbC5sZW5ndGgoKTtyZXR1cm4gdGhpcy5ub3JtYWwubXVsdGlwbHlTY2FsYXIodCksdGhpcy5jb25zdGFudCo9dCx0aGlzfW5lZ2F0ZSgpe3JldHVybiB0aGlzLmNvbnN0YW50Kj0tMSx0aGlzLm5vcm1hbC5uZWdhdGUoKSx0aGlzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdGhpcy5ub3JtYWwuZG90KHQpK3RoaXMuY29uc3RhbnR9ZGlzdGFuY2VUb1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQodC5jZW50ZXIpLXQucmFkaXVzfXByb2plY3RQb2ludCh0LGUpe3JldHVybiBlLmNvcHkodCkuYWRkU2NhbGVkVmVjdG9yKHRoaXMubm9ybWFsLC10aGlzLmRpc3RhbmNlVG9Qb2ludCh0KSl9aW50ZXJzZWN0TGluZSh0LGUpe2NvbnN0IG49dC5kZWx0YSh2bykscz10aGlzLm5vcm1hbC5kb3Qobik7aWYocz09PTApcmV0dXJuIHRoaXMuZGlzdGFuY2VUb1BvaW50KHQuc3RhcnQpPT09MD9lLmNvcHkodC5zdGFydCk6bnVsbDtjb25zdCByPS0odC5zdGFydC5kb3QodGhpcy5ub3JtYWwpK3RoaXMuY29uc3RhbnQpL3M7cmV0dXJuIHI8MHx8cj4xP251bGw6ZS5jb3B5KHQuc3RhcnQpLmFkZFNjYWxlZFZlY3RvcihuLHIpfWludGVyc2VjdHNMaW5lKHQpe2NvbnN0IGU9dGhpcy5kaXN0YW5jZVRvUG9pbnQodC5zdGFydCksbj10aGlzLmRpc3RhbmNlVG9Qb2ludCh0LmVuZCk7cmV0dXJuIGU8MCYmbj4wfHxuPDAmJmU+MH1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1jb3BsYW5hclBvaW50KHQpe3JldHVybiB0LmNvcHkodGhpcy5ub3JtYWwpLm11bHRpcGx5U2NhbGFyKC10aGlzLmNvbnN0YW50KX1hcHBseU1hdHJpeDQodCxlKXtjb25zdCBuPWV8fFNmLmdldE5vcm1hbE1hdHJpeCh0KSxzPXRoaXMuY29wbGFuYXJQb2ludCh2bykuYXBwbHlNYXRyaXg0KHQpLHI9dGhpcy5ub3JtYWwuYXBwbHlNYXRyaXgzKG4pLm5vcm1hbGl6ZSgpO3JldHVybiB0aGlzLmNvbnN0YW50PS1zLmRvdChyKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jb25zdGFudC09dC5kb3QodGhpcy5ub3JtYWwpLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lm5vcm1hbC5lcXVhbHModGhpcy5ub3JtYWwpJiZ0LmNvbnN0YW50PT09dGhpcy5jb25zdGFudH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9fWxldCB4ZT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMudHlwZT0iQ3VydmUiLHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPTIwMCx0aGlzLm5lZWRzVXBkYXRlPSExLHRoaXMuY2FjaGVBcmNMZW5ndGhzPW51bGx9Z2V0UG9pbnQoKXtjb25zb2xlLndhcm4oIlRIUkVFLkN1cnZlOiAuZ2V0UG9pbnQoKSBub3QgaW1wbGVtZW50ZWQuIil9Z2V0UG9pbnRBdCh0LGUpe2NvbnN0IG49dGhpcy5nZXRVdG9UbWFwcGluZyh0KTtyZXR1cm4gdGhpcy5nZXRQb2ludChuLGUpfWdldFBvaW50cyh0PTUpe2NvbnN0IGU9W107Zm9yKGxldCBuPTA7bjw9dDtuKyspZS5wdXNoKHRoaXMuZ2V0UG9pbnQobi90KSk7cmV0dXJuIGV9Z2V0U3BhY2VkUG9pbnRzKHQ9NSl7Y29uc3QgZT1bXTtmb3IobGV0IG49MDtuPD10O24rKyllLnB1c2godGhpcy5nZXRQb2ludEF0KG4vdCkpO3JldHVybiBlfWdldExlbmd0aCgpe2NvbnN0IHQ9dGhpcy5nZXRMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19Z2V0TGVuZ3Rocyh0PXRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zKXtpZih0aGlzLmNhY2hlQXJjTGVuZ3RocyYmdGhpcy5jYWNoZUFyY0xlbmd0aHMubGVuZ3RoPT09dCsxJiYhdGhpcy5uZWVkc1VwZGF0ZSlyZXR1cm4gdGhpcy5jYWNoZUFyY0xlbmd0aHM7dGhpcy5uZWVkc1VwZGF0ZT0hMTtjb25zdCBlPVtdO2xldCBuLHM9dGhpcy5nZXRQb2ludCgwKSxyPTA7ZS5wdXNoKDApO2ZvcihsZXQgbz0xO288PXQ7bysrKW49dGhpcy5nZXRQb2ludChvL3QpLHIrPW4uZGlzdGFuY2VUbyhzKSxlLnB1c2gocikscz1uO3JldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3Rocz1lLGV9dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5nZXRMZW5ndGhzKCl9Z2V0VXRvVG1hcHBpbmcodCxlPW51bGwpe2NvbnN0IG49dGhpcy5nZXRMZW5ndGhzKCk7bGV0IHM9MDtjb25zdCByPW4ubGVuZ3RoO2xldCBvO2U/bz1lOm89dCpuW3ItMV07bGV0IGE9MCxjPXItMSxsO2Zvcig7YTw9YzspaWYocz1NYXRoLmZsb29yKGErKGMtYSkvMiksbD1uW3NdLW8sbDwwKWE9cysxO2Vsc2UgaWYobD4wKWM9cy0xO2Vsc2V7Yz1zO2JyZWFrfWlmKHM9YyxuW3NdPT09bylyZXR1cm4gcy8oci0xKTtjb25zdCBoPW5bc10sZj1uW3MrMV0taCxkPShvLWgpL2Y7cmV0dXJuKHMrZCkvKHItMSl9Z2V0VGFuZ2VudCh0LGUpe2xldCBzPXQtMWUtNCxyPXQrMWUtNDtzPDAmJihzPTApLHI+MSYmKHI9MSk7Y29uc3Qgbz10aGlzLmdldFBvaW50KHMpLGE9dGhpcy5nZXRQb2ludChyKSxjPWV8fChvLmlzVmVjdG9yMj9uZXcgUjpuZXcgVCk7cmV0dXJuIGMuY29weShhKS5zdWIobykubm9ybWFsaXplKCksY31nZXRUYW5nZW50QXQodCxlKXtjb25zdCBuPXRoaXMuZ2V0VXRvVG1hcHBpbmcodCk7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudChuLGUpfWNvbXB1dGVGcmVuZXRGcmFtZXModCxlPSExKXtjb25zdCBuPW5ldyBULHM9W10scj1bXSxvPVtdLGE9bmV3IFQsYz1uZXcgc3Q7Zm9yKGxldCBkPTA7ZDw9dDtkKyspe2NvbnN0IHA9ZC90O3NbZF09dGhpcy5nZXRUYW5nZW50QXQocCxuZXcgVCl9clswXT1uZXcgVCxvWzBdPW5ldyBUO2xldCBsPU51bWJlci5NQVhfVkFMVUU7Y29uc3QgaD1NYXRoLmFicyhzWzBdLngpLHU9TWF0aC5hYnMoc1swXS55KSxmPU1hdGguYWJzKHNbMF0ueik7aDw9bCYmKGw9aCxuLnNldCgxLDAsMCkpLHU8PWwmJihsPXUsbi5zZXQoMCwxLDApKSxmPD1sJiZuLnNldCgwLDAsMSksYS5jcm9zc1ZlY3RvcnMoc1swXSxuKS5ub3JtYWxpemUoKSxyWzBdLmNyb3NzVmVjdG9ycyhzWzBdLGEpLG9bMF0uY3Jvc3NWZWN0b3JzKHNbMF0sclswXSk7Zm9yKGxldCBkPTE7ZDw9dDtkKyspe2lmKHJbZF09cltkLTFdLmNsb25lKCksb1tkXT1vW2QtMV0uY2xvbmUoKSxhLmNyb3NzVmVjdG9ycyhzW2QtMV0sc1tkXSksYS5sZW5ndGgoKT5OdW1iZXIuRVBTSUxPTil7YS5ub3JtYWxpemUoKTtjb25zdCBwPU1hdGguYWNvcyhaKHNbZC0xXS5kb3Qoc1tkXSksLTEsMSkpO3JbZF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhhLHApKX1vW2RdLmNyb3NzVmVjdG9ycyhzW2RdLHJbZF0pfWlmKGU9PT0hMCl7bGV0IGQ9TWF0aC5hY29zKFooclswXS5kb3Qoclt0XSksLTEsMSkpO2QvPXQsc1swXS5kb3QoYS5jcm9zc1ZlY3RvcnMoclswXSxyW3RdKSk+MCYmKGQ9LWQpO2ZvcihsZXQgcD0xO3A8PXQ7cCsrKXJbcF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhzW3BdLGQqcCkpLG9bcF0uY3Jvc3NWZWN0b3JzKHNbcF0scltwXSl9cmV0dXJue3RhbmdlbnRzOnMsbm9ybWFsczpyLGJpbm9ybWFsczpvfX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9dC5hcmNMZW5ndGhEaXZpc2lvbnMsdGhpc310b0pTT04oKXtjb25zdCB0PXttZXRhZGF0YTp7dmVyc2lvbjo0LjcsdHlwZToiQ3VydmUiLGdlbmVyYXRvcjoiQ3VydmUudG9KU09OIn19O3JldHVybiB0LmFyY0xlbmd0aERpdmlzaW9ucz10aGlzLmFyY0xlbmd0aERpdmlzaW9ucyx0LnR5cGU9dGhpcy50eXBlLHR9ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPXQuYXJjTGVuZ3RoRGl2aXNpb25zLHRoaXN9fTtjbGFzcyBfcyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0xLHM9MSxyPTAsbz1NYXRoLlBJKjIsYT0hMSxjPTApe3N1cGVyKCksdGhpcy5pc0VsbGlwc2VDdXJ2ZT0hMCx0aGlzLnR5cGU9IkVsbGlwc2VDdXJ2ZSIsdGhpcy5hWD10LHRoaXMuYVk9ZSx0aGlzLnhSYWRpdXM9bix0aGlzLnlSYWRpdXM9cyx0aGlzLmFTdGFydEFuZ2xlPXIsdGhpcy5hRW5kQW5nbGU9byx0aGlzLmFDbG9ja3dpc2U9YSx0aGlzLmFSb3RhdGlvbj1jfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9TWF0aC5QSSoyO2xldCByPXRoaXMuYUVuZEFuZ2xlLXRoaXMuYVN0YXJ0QW5nbGU7Y29uc3Qgbz1NYXRoLmFicyhyKTxOdW1iZXIuRVBTSUxPTjtmb3IoO3I8MDspcis9cztmb3IoO3I+czspci09cztyPE51bWJlci5FUFNJTE9OJiYobz9yPTA6cj1zKSx0aGlzLmFDbG9ja3dpc2U9PT0hMCYmIW8mJihyPT09cz9yPS1zOnI9ci1zKTtjb25zdCBhPXRoaXMuYVN0YXJ0QW5nbGUrdCpyO2xldCBjPXRoaXMuYVgrdGhpcy54UmFkaXVzKk1hdGguY29zKGEpLGw9dGhpcy5hWSt0aGlzLnlSYWRpdXMqTWF0aC5zaW4oYSk7aWYodGhpcy5hUm90YXRpb24hPT0wKXtjb25zdCBoPU1hdGguY29zKHRoaXMuYVJvdGF0aW9uKSx1PU1hdGguc2luKHRoaXMuYVJvdGF0aW9uKSxmPWMtdGhpcy5hWCxkPWwtdGhpcy5hWTtjPWYqaC1kKnUrdGhpcy5hWCxsPWYqdStkKmgrdGhpcy5hWX1yZXR1cm4gbi5zZXQoYyxsKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMuYVg9dC5hWCx0aGlzLmFZPXQuYVksdGhpcy54UmFkaXVzPXQueFJhZGl1cyx0aGlzLnlSYWRpdXM9dC55UmFkaXVzLHRoaXMuYVN0YXJ0QW5nbGU9dC5hU3RhcnRBbmdsZSx0aGlzLmFFbmRBbmdsZT10LmFFbmRBbmdsZSx0aGlzLmFDbG9ja3dpc2U9dC5hQ2xvY2t3aXNlLHRoaXMuYVJvdGF0aW9uPXQuYVJvdGF0aW9uLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC5hWD10aGlzLmFYLHQuYVk9dGhpcy5hWSx0LnhSYWRpdXM9dGhpcy54UmFkaXVzLHQueVJhZGl1cz10aGlzLnlSYWRpdXMsdC5hU3RhcnRBbmdsZT10aGlzLmFTdGFydEFuZ2xlLHQuYUVuZEFuZ2xlPXRoaXMuYUVuZEFuZ2xlLHQuYUNsb2Nrd2lzZT10aGlzLmFDbG9ja3dpc2UsdC5hUm90YXRpb249dGhpcy5hUm90YXRpb24sdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5hWD10LmFYLHRoaXMuYVk9dC5hWSx0aGlzLnhSYWRpdXM9dC54UmFkaXVzLHRoaXMueVJhZGl1cz10LnlSYWRpdXMsdGhpcy5hU3RhcnRBbmdsZT10LmFTdGFydEFuZ2xlLHRoaXMuYUVuZEFuZ2xlPXQuYUVuZEFuZ2xlLHRoaXMuYUNsb2Nrd2lzZT10LmFDbG9ja3dpc2UsdGhpcy5hUm90YXRpb249dC5hUm90YXRpb24sdGhpc319Y2xhc3MgJGMgZXh0ZW5kcyBfc3tjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyl7c3VwZXIodCxlLG4sbixzLHIsbyksdGhpcy5pc0FyY0N1cnZlPSEwLHRoaXMudHlwZT0iQXJjQ3VydmUifX1mdW5jdGlvbiBUbygpe2xldCBpPTAsdD0wLGU9MCxuPTA7ZnVuY3Rpb24gcyhyLG8sYSxjKXtpPXIsdD1hLGU9LTMqciszKm8tMiphLWMsbj0yKnItMipvK2ErY31yZXR1cm57aW5pdENhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsKXtzKG8sYSxsKihhLXIpLGwqKGMtbykpfSxpbml0Tm9udW5pZm9ybUNhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsLGgsdSl7bGV0IGY9KG8tcikvbC0oYS1yKS8obCtoKSsoYS1vKS9oLGQ9KGEtbykvaC0oYy1vKS8oaCt1KSsoYy1hKS91O2YqPWgsZCo9aCxzKG8sYSxmLGQpfSxjYWxjOmZ1bmN0aW9uKHIpe2NvbnN0IG89cipyLGE9bypyO3JldHVybiBpK3QqcitlKm8rbiphfX19Y29uc3QgdnM9bmV3IFQsRW89bmV3IFRvLFBvPW5ldyBUbyxDbz1uZXcgVG87Y2xhc3MgVmMgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdLGU9ITEsbj0iY2VudHJpcGV0YWwiLHM9LjUpe3N1cGVyKCksdGhpcy5pc0NhdG11bGxSb21DdXJ2ZTM9ITAsdGhpcy50eXBlPSJDYXRtdWxsUm9tQ3VydmUzIix0aGlzLnBvaW50cz10LHRoaXMuY2xvc2VkPWUsdGhpcy5jdXJ2ZVR5cGU9bix0aGlzLnRlbnNpb249c31nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZSxzPXRoaXMucG9pbnRzLHI9cy5sZW5ndGgsbz0oci0odGhpcy5jbG9zZWQ/MDoxKSkqdDtsZXQgYT1NYXRoLmZsb29yKG8pLGM9by1hO3RoaXMuY2xvc2VkP2ErPWE+MD8wOihNYXRoLmZsb29yKE1hdGguYWJzKGEpL3IpKzEpKnI6Yz09PTAmJmE9PT1yLTEmJihhPXItMixjPTEpO2xldCBsLGg7dGhpcy5jbG9zZWR8fGE+MD9sPXNbKGEtMSklcl06KHZzLnN1YlZlY3RvcnMoc1swXSxzWzFdKS5hZGQoc1swXSksbD12cyk7Y29uc3QgdT1zW2Elcl0sZj1zWyhhKzEpJXJdO2lmKHRoaXMuY2xvc2VkfHxhKzI8cj9oPXNbKGErMiklcl06KHZzLnN1YlZlY3RvcnMoc1tyLTFdLHNbci0yXSkuYWRkKHNbci0xXSksaD12cyksdGhpcy5jdXJ2ZVR5cGU9PT0iY2VudHJpcGV0YWwifHx0aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIil7Y29uc3QgZD10aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIj8uNTouMjU7bGV0IHA9TWF0aC5wb3cobC5kaXN0YW5jZVRvU3F1YXJlZCh1KSxkKSx5PU1hdGgucG93KHUuZGlzdGFuY2VUb1NxdWFyZWQoZiksZCksbT1NYXRoLnBvdyhmLmRpc3RhbmNlVG9TcXVhcmVkKGgpLGQpO3k8MWUtNCYmKHk9MSkscDwxZS00JiYocD15KSxtPDFlLTQmJihtPXkpLEVvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLngsdS54LGYueCxoLngscCx5LG0pLFBvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnksdS55LGYueSxoLnkscCx5LG0pLENvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnosdS56LGYueixoLnoscCx5LG0pfWVsc2UgdGhpcy5jdXJ2ZVR5cGU9PT0iY2F0bXVsbHJvbSImJihFby5pbml0Q2F0bXVsbFJvbShsLngsdS54LGYueCxoLngsdGhpcy50ZW5zaW9uKSxQby5pbml0Q2F0bXVsbFJvbShsLnksdS55LGYueSxoLnksdGhpcy50ZW5zaW9uKSxDby5pbml0Q2F0bXVsbFJvbShsLnosdS56LGYueixoLnosdGhpcy50ZW5zaW9uKSk7cmV0dXJuIG4uc2V0KEVvLmNhbGMoYyksUG8uY2FsYyhjKSxDby5jYWxjKGMpKSxufWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5jbG9zZWQ9dC5jbG9zZWQsdGhpcy5jdXJ2ZVR5cGU9dC5jdXJ2ZVR5cGUsdGhpcy50ZW5zaW9uPXQudGVuc2lvbix0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdC5jbG9zZWQ9dGhpcy5jbG9zZWQsdC5jdXJ2ZVR5cGU9dGhpcy5jdXJ2ZVR5cGUsdC50ZW5zaW9uPXRoaXMudGVuc2lvbix0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChuZXcgVCgpLmZyb21BcnJheShzKSl9cmV0dXJuIHRoaXMuY2xvc2VkPXQuY2xvc2VkLHRoaXMuY3VydmVUeXBlPXQuY3VydmVUeXBlLHRoaXMudGVuc2lvbj10LnRlbnNpb24sdGhpc319ZnVuY3Rpb24gVWMoaSx0LGUsbixzKXtjb25zdCByPShuLXQpKi41LG89KHMtZSkqLjUsYT1pKmksYz1pKmE7cmV0dXJuKDIqZS0yKm4rcitvKSpjKygtMyplKzMqbi0yKnItbykqYStyKmkrZX1mdW5jdGlvbiBfZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiBlKmUqdH1mdW5jdGlvbiB2ZihpLHQpe3JldHVybiAyKigxLWkpKmkqdH1mdW5jdGlvbiB6ZihpLHQpe3JldHVybiBpKmkqdH1mdW5jdGlvbiBTaShpLHQsZSxuKXtyZXR1cm4gX2YoaSx0KSt2ZihpLGUpK3pmKGksbil9ZnVuY3Rpb24gVGYoaSx0KXtjb25zdCBlPTEtaTtyZXR1cm4gZSplKmUqdH1mdW5jdGlvbiBFZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiAzKmUqZSppKnR9ZnVuY3Rpb24gUGYoaSx0KXtyZXR1cm4gMyooMS1pKSppKmkqdH1mdW5jdGlvbiBDZihpLHQpe3JldHVybiBpKmkqaSp0fWZ1bmN0aW9uIF9pKGksdCxlLG4scyl7cmV0dXJuIFRmKGksdCkrRWYoaSxlKStQZihpLG4pK0NmKGkscyl9Y2xhc3MgQm8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUixzPW5ldyBSKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlPSEwLHRoaXMudHlwZT0iQ3ViaWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW4sdGhpcy52Mz1zfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyLGE9dGhpcy52MztyZXR1cm4gbi5zZXQoX2kodCxzLngsci54LG8ueCxhLngpLF9pKHQscy55LHIueSxvLnksYS55KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3MgcWMgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCxzPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlMz0hMCx0aGlzLnR5cGU9IkN1YmljQmV6aWVyQ3VydmUzIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bix0aGlzLnYzPXN9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjIsYT10aGlzLnYzO3JldHVybiBuLnNldChfaSh0LHMueCxyLngsby54LGEueCksX2kodCxzLnksci55LG8ueSxhLnkpLF9pKHQscy56LHIueixvLnosYS56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3MgRm8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIpe3N1cGVyKCksdGhpcy5pc0xpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZSIsdGhpcy52MT10LHRoaXMudjI9ZX1nZXRQb2ludCh0LGU9bmV3IFIpe2NvbnN0IG49ZTtyZXR1cm4gdD09PTE/bi5jb3B5KHRoaXMudjIpOihuLmNvcHkodGhpcy52Mikuc3ViKHRoaXMudjEpLG4ubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMudjEpKSxufWdldFBvaW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRQb2ludCh0LGUpfWdldFRhbmdlbnQodCxlPW5ldyBSKXtyZXR1cm4gZS5zdWJWZWN0b3JzKHRoaXMudjIsdGhpcy52MSkubm9ybWFsaXplKCl9Z2V0VGFuZ2VudEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudCh0LGUpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBIYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCl7c3VwZXIoKSx0aGlzLmlzTGluZUN1cnZlMz0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZTMiLHRoaXMudjE9dCx0aGlzLnYyPWV9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWU7cmV0dXJuIHQ9PT0xP24uY29weSh0aGlzLnYyKToobi5jb3B5KHRoaXMudjIpLnN1Yih0aGlzLnYxKSxuLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnYxKSksbn1nZXRQb2ludEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0UG9pbnQodCxlKX1nZXRUYW5nZW50KHQsZT1uZXcgVCl7cmV0dXJuIGUuc3ViVmVjdG9ycyh0aGlzLnYyLHRoaXMudjEpLm5vcm1hbGl6ZSgpfWdldFRhbmdlbnRBdCh0LGUpe3JldHVybiB0aGlzLmdldFRhbmdlbnQodCxlKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3MgSW8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUil7c3VwZXIoKSx0aGlzLmlzUXVhZHJhdGljQmV6aWVyQ3VydmU9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW59Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjI7cmV0dXJuIG4uc2V0KFNpKHQscy54LHIueCxvLngpLFNpKHQscy55LHIueSxvLnkpKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYwPXRoaXMudjAudG9BcnJheSgpLHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBXYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCxuPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNRdWFkcmF0aWNCZXppZXJDdXJ2ZTM9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZTMiLHRoaXMudjA9dCx0aGlzLnYxPWUsdGhpcy52Mj1ufWdldFBvaW50KHQsZT1uZXcgVCl7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyO3JldHVybiBuLnNldChTaSh0LHMueCxyLngsby54KSxTaSh0LHMueSxyLnksby55KSxTaSh0LHMueixyLnosby56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3Mga28gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdKXtzdXBlcigpLHRoaXMuaXNTcGxpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IlNwbGluZUN1cnZlIix0aGlzLnBvaW50cz10fWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy5wb2ludHMscj0ocy5sZW5ndGgtMSkqdCxvPU1hdGguZmxvb3IociksYT1yLW8sYz1zW289PT0wP286by0xXSxsPXNbb10saD1zW28+cy5sZW5ndGgtMj9zLmxlbmd0aC0xOm8rMV0sdT1zW28+cy5sZW5ndGgtMz9zLmxlbmd0aC0xOm8rMl07cmV0dXJuIG4uc2V0KFVjKGEsYy54LGwueCxoLngsdS54KSxVYyhhLGMueSxsLnksaC55LHUueSkpLG59Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gobmV3IFIoKS5mcm9tQXJyYXkocykpfXJldHVybiB0aGlzfX12YXIgR2M9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQXJjQ3VydmU6JGMsQ2F0bXVsbFJvbUN1cnZlMzpWYyxDdWJpY0JlemllckN1cnZlOkJvLEN1YmljQmV6aWVyQ3VydmUzOnFjLEVsbGlwc2VDdXJ2ZTpfcyxMaW5lQ3VydmU6Rm8sTGluZUN1cnZlMzpIYyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTpJbyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTM6V2MsU3BsaW5lQ3VydmU6a299KTtjbGFzcyBCZiBleHRlbmRzIHhle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9IkN1cnZlUGF0aCIsdGhpcy5jdXJ2ZXM9W10sdGhpcy5hdXRvQ2xvc2U9ITF9YWRkKHQpe3RoaXMuY3VydmVzLnB1c2godCl9Y2xvc2VQYXRoKCl7Y29uc3QgdD10aGlzLmN1cnZlc1swXS5nZXRQb2ludCgwKSxlPXRoaXMuY3VydmVzW3RoaXMuY3VydmVzLmxlbmd0aC0xXS5nZXRQb2ludCgxKTtpZighdC5lcXVhbHMoZSkpe2NvbnN0IG49dC5pc1ZlY3RvcjI9PT0hMD8iTGluZUN1cnZlIjoiTGluZUN1cnZlMyI7dGhpcy5jdXJ2ZXMucHVzaChuZXcgR2Nbbl0oZSx0KSl9cmV0dXJuIHRoaXN9Z2V0UG9pbnQodCxlKXtjb25zdCBuPXQqdGhpcy5nZXRMZW5ndGgoKSxzPXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7bGV0IHI9MDtmb3IoO3I8cy5sZW5ndGg7KXtpZihzW3JdPj1uKXtjb25zdCBvPXNbcl0tbixhPXRoaXMuY3VydmVzW3JdLGM9YS5nZXRMZW5ndGgoKSxsPWM9PT0wPzA6MS1vL2M7cmV0dXJuIGEuZ2V0UG9pbnRBdChsLGUpfXIrK31yZXR1cm4gbnVsbH1nZXRMZW5ndGgoKXtjb25zdCB0PXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5jYWNoZUxlbmd0aHM9bnVsbCx0aGlzLmdldEN1cnZlTGVuZ3RocygpfWdldEN1cnZlTGVuZ3Rocygpe2lmKHRoaXMuY2FjaGVMZW5ndGhzJiZ0aGlzLmNhY2hlTGVuZ3Rocy5sZW5ndGg9PT10aGlzLmN1cnZlcy5sZW5ndGgpcmV0dXJuIHRoaXMuY2FjaGVMZW5ndGhzO2NvbnN0IHQ9W107bGV0IGU9MDtmb3IobGV0IG49MCxzPXRoaXMuY3VydmVzLmxlbmd0aDtuPHM7bisrKWUrPXRoaXMuY3VydmVzW25dLmdldExlbmd0aCgpLHQucHVzaChlKTtyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM9dCx0fWdldFNwYWNlZFBvaW50cyh0PTQwKXtjb25zdCBlPVtdO2ZvcihsZXQgbj0wO248PXQ7bisrKWUucHVzaCh0aGlzLmdldFBvaW50KG4vdCkpO3JldHVybiB0aGlzLmF1dG9DbG9zZSYmZS5wdXNoKGVbMF0pLGV9Z2V0UG9pbnRzKHQ9MTIpe2NvbnN0IGU9W107bGV0IG47Zm9yKGxldCBzPTAscj10aGlzLmN1cnZlcztzPHIubGVuZ3RoO3MrKyl7Y29uc3Qgbz1yW3NdLGE9by5pc0VsbGlwc2VDdXJ2ZT90KjI6by5pc0xpbmVDdXJ2ZXx8by5pc0xpbmVDdXJ2ZTM/MTpvLmlzU3BsaW5lQ3VydmU/dCpvLnBvaW50cy5sZW5ndGg6dCxjPW8uZ2V0UG9pbnRzKGEpO2ZvcihsZXQgbD0wO2w8Yy5sZW5ndGg7bCsrKXtjb25zdCBoPWNbbF07biYmbi5lcXVhbHMoaCl8fChlLnB1c2goaCksbj1oKX19cmV0dXJuIHRoaXMuYXV0b0Nsb3NlJiZlLmxlbmd0aD4xJiYhZVtlLmxlbmd0aC0xXS5lcXVhbHMoZVswXSkmJmUucHVzaChlWzBdKSxlfWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5hdXRvQ2xvc2U9dC5hdXRvQ2xvc2UsdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3QuYXV0b0Nsb3NlPXRoaXMuYXV0b0Nsb3NlLHQuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dGhpcy5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dGhpcy5jdXJ2ZXNbZV07dC5jdXJ2ZXMucHVzaChzLnRvSlNPTigpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLmF1dG9DbG9zZT10LmF1dG9DbG9zZSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gobmV3IEdjW3MudHlwZV0oKS5mcm9tSlNPTihzKSl9cmV0dXJuIHRoaXN9fWxldCBaYz1jbGFzcyBleHRlbmRzIEJme2NvbnN0cnVjdG9yKHQpe3N1cGVyKCksdGhpcy50eXBlPSJQYXRoIix0aGlzLmN1cnJlbnRQb2ludD1uZXcgUix0JiZ0aGlzLnNldEZyb21Qb2ludHModCl9c2V0RnJvbVBvaW50cyh0KXt0aGlzLm1vdmVUbyh0WzBdLngsdFswXS55KTtmb3IobGV0IGU9MSxuPXQubGVuZ3RoO2U8bjtlKyspdGhpcy5saW5lVG8odFtlXS54LHRbZV0ueSk7cmV0dXJuIHRoaXN9bW92ZVRvKHQsZSl7cmV0dXJuIHRoaXMuY3VycmVudFBvaW50LnNldCh0LGUpLHRoaXN9bGluZVRvKHQsZSl7Y29uc3Qgbj1uZXcgRm8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5zZXQodCxlKSx0aGlzfXF1YWRyYXRpY0N1cnZlVG8odCxlLG4scyl7Y29uc3Qgcj1uZXcgSW8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scykpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKHIpLHRoaXMuY3VycmVudFBvaW50LnNldChuLHMpLHRoaXN9YmV6aWVyQ3VydmVUbyh0LGUsbixzLHIsbyl7Y29uc3QgYT1uZXcgQm8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scyksbmV3IFIocixvKSk7cmV0dXJuIHRoaXMuY3VydmVzLnB1c2goYSksdGhpcy5jdXJyZW50UG9pbnQuc2V0KHIsbyksdGhpc31zcGxpbmVUaHJ1KHQpe2NvbnN0IGU9W3RoaXMuY3VycmVudFBvaW50LmNsb25lKCldLmNvbmNhdCh0KSxuPW5ldyBrbyhlKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5jb3B5KHRbdC5sZW5ndGgtMV0pLHRoaXN9YXJjKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMuY3VycmVudFBvaW50LngsYz10aGlzLmN1cnJlbnRQb2ludC55O3JldHVybiB0aGlzLmFic2FyYyh0K2EsZStjLG4scyxyLG8pLHRoaXN9YWJzYXJjKHQsZSxuLHMscixvKXtyZXR1cm4gdGhpcy5hYnNlbGxpcHNlKHQsZSxuLG4scyxyLG8pLHRoaXN9ZWxsaXBzZSh0LGUsbixzLHIsbyxhLGMpe2NvbnN0IGw9dGhpcy5jdXJyZW50UG9pbnQueCxoPXRoaXMuY3VycmVudFBvaW50Lnk7cmV0dXJuIHRoaXMuYWJzZWxsaXBzZSh0K2wsZStoLG4scyxyLG8sYSxjKSx0aGlzfWFic2VsbGlwc2UodCxlLG4scyxyLG8sYSxjKXtjb25zdCBsPW5ldyBfcyh0LGUsbixzLHIsbyxhLGMpO2lmKHRoaXMuY3VydmVzLmxlbmd0aD4wKXtjb25zdCB1PWwuZ2V0UG9pbnQoMCk7dS5lcXVhbHModGhpcy5jdXJyZW50UG9pbnQpfHx0aGlzLmxpbmVUbyh1LngsdS55KX10aGlzLmN1cnZlcy5wdXNoKGwpO2NvbnN0IGg9bC5nZXRQb2ludCgxKTtyZXR1cm4gdGhpcy5jdXJyZW50UG9pbnQuY29weShoKSx0aGlzfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5jdXJyZW50UG9pbnQuY29weSh0LmN1cnJlbnRQb2ludCksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LmN1cnJlbnRQb2ludD10aGlzLmN1cnJlbnRQb2ludC50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5jdXJyZW50UG9pbnQuZnJvbUFycmF5KHQuY3VycmVudFBvaW50KSx0aGlzfX07Y2xhc3MgWGMgZXh0ZW5kcyBaY3tjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLnV1aWQ9Rm4oKSx0aGlzLnR5cGU9IlNoYXBlIix0aGlzLmhvbGVzPVtdfWdldFBvaW50c0hvbGVzKHQpe2NvbnN0IGU9W107Zm9yKGxldCBuPTAscz10aGlzLmhvbGVzLmxlbmd0aDtuPHM7bisrKWVbbl09dGhpcy5ob2xlc1tuXS5nZXRQb2ludHModCk7cmV0dXJuIGV9ZXh0cmFjdFBvaW50cyh0KXtyZXR1cm57c2hhcGU6dGhpcy5nZXRQb2ludHModCksaG9sZXM6dGhpcy5nZXRQb2ludHNIb2xlcyh0KX19Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10LmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuaG9sZXNbZV07dGhpcy5ob2xlcy5wdXNoKHMuY2xvbmUoKSl9cmV0dXJuIHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnV1aWQ9dGhpcy51dWlkLHQuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10aGlzLmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMuaG9sZXNbZV07dC5ob2xlcy5wdXNoKHMudG9KU09OKCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMudXVpZD10LnV1aWQsdGhpcy5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXQuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5ob2xlc1tlXTt0aGlzLmhvbGVzLnB1c2gobmV3IFpjKCkuZnJvbUpTT04ocykpfXJldHVybiB0aGlzfX1mdW5jdGlvbiBGZihpLHQsZT0yKXtjb25zdCBuPXQmJnQubGVuZ3RoLHM9bj90WzBdKmU6aS5sZW5ndGg7bGV0IHI9SmMoaSwwLHMsZSwhMCk7Y29uc3Qgbz1bXTtpZighcnx8ci5uZXh0PT09ci5wcmV2KXJldHVybiBvO2xldCBhLGMsbDtpZihuJiYocj1MZihpLHQscixlKSksaS5sZW5ndGg+ODAqZSl7YT0xLzAsYz0xLzA7bGV0IGg9LTEvMCx1PS0xLzA7Zm9yKGxldCBmPWU7ZjxzO2YrPWUpe2NvbnN0IGQ9aVtmXSxwPWlbZisxXTtkPGEmJihhPWQpLHA8YyYmKGM9cCksZD5oJiYoaD1kKSxwPnUmJih1PXApfWw9TWF0aC5tYXgoaC1hLHUtYyksbD1sIT09MD8zMjc2Ny9sOjB9cmV0dXJuIHZpKHIsbyxlLGEsYyxsLDApLG99ZnVuY3Rpb24gSmMoaSx0LGUsbixzKXtsZXQgcjtpZihzPT09WGYoaSx0LGUsbik+MClmb3IobGV0IG89dDtvPGU7bys9bilyPUtjKG8vbnwwLGlbb10saVtvKzFdLHIpO2Vsc2UgZm9yKGxldCBvPWUtbjtvPj10O28tPW4pcj1LYyhvL258MCxpW29dLGlbbysxXSxyKTtyZXR1cm4gciYmSG4ocixyLm5leHQpJiYoRWkocikscj1yLm5leHQpLHJ9ZnVuY3Rpb24gZG4oaSx0KXtpZighaSlyZXR1cm4gaTt0fHwodD1pKTtsZXQgZT1pLG47ZG8gaWYobj0hMSwhZS5zdGVpbmVyJiYoSG4oZSxlLm5leHQpfHxydChlLnByZXYsZSxlLm5leHQpPT09MCkpe2lmKEVpKGUpLGU9dD1lLnByZXYsZT09PWUubmV4dClicmVhaztuPSEwfWVsc2UgZT1lLm5leHQ7d2hpbGUobnx8ZSE9PXQpO3JldHVybiB0fWZ1bmN0aW9uIHZpKGksdCxlLG4scyxyLG8pe2lmKCFpKXJldHVybjshbyYmciYmVWYoaSxuLHMscik7bGV0IGE9aTtmb3IoO2kucHJldiE9PWkubmV4dDspe2NvbnN0IGM9aS5wcmV2LGw9aS5uZXh0O2lmKHI/a2YoaSxuLHMscik6SWYoaSkpe3QucHVzaChjLmksaS5pLGwuaSksRWkoaSksaT1sLm5leHQsYT1sLm5leHQ7Y29udGludWV9aWYoaT1sLGk9PT1hKXtvP289PT0xPyhpPU5mKGRuKGkpLHQpLHZpKGksdCxlLG4scyxyLDIpKTpvPT09MiYmUmYoaSx0LGUsbixzLHIpOnZpKGRuKGkpLHQsZSxuLHMsciwxKTticmVha319fWZ1bmN0aW9uIElmKGkpe2NvbnN0IHQ9aS5wcmV2LGU9aSxuPWkubmV4dDtpZihydCh0LGUsbik+PTApcmV0dXJuITE7Y29uc3Qgcz10Lngscj1lLngsbz1uLngsYT10LnksYz1lLnksbD1uLnksaD1NYXRoLm1pbihzLHIsbyksdT1NYXRoLm1pbihhLGMsbCksZj1NYXRoLm1heChzLHIsbyksZD1NYXRoLm1heChhLGMsbCk7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJnppKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZydChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIGtmKGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihydChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1NYXRoLm1pbihhLGMsbCkscD1NYXRoLm1pbihoLHUsZikseT1NYXRoLm1heChhLGMsbCksbT1NYXRoLm1heChoLHUsZiksZz1ObyhkLHAsdCxlLG4pLGI9Tm8oeSxtLHQsZSxuKTtsZXQgdz1pLnByZXZaLHg9aS5uZXh0Wjtmb3IoO3cmJncuej49ZyYmeCYmeC56PD1iOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJnppKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wfHwodz13LnByZXZaLHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZ6aShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MCkpcmV0dXJuITE7eD14Lm5leHRafWZvcig7dyYmdy56Pj1nOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJnppKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wKXJldHVybiExO3c9dy5wcmV2Wn1mb3IoO3gmJnguejw9Yjspe2lmKHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZ6aShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MClyZXR1cm4hMTt4PXgubmV4dFp9cmV0dXJuITB9ZnVuY3Rpb24gTmYoaSx0KXtsZXQgZT1pO2Rve2NvbnN0IG49ZS5wcmV2LHM9ZS5uZXh0Lm5leHQ7IUhuKG4scykmJmpjKG4sZSxlLm5leHQscykmJlRpKG4scykmJlRpKHMsbikmJih0LnB1c2gobi5pLGUuaSxzLmkpLEVpKGUpLEVpKGUubmV4dCksZT1pPXMpLGU9ZS5uZXh0fXdoaWxlKGUhPT1pKTtyZXR1cm4gZG4oZSl9ZnVuY3Rpb24gUmYoaSx0LGUsbixzLHIpe2xldCBvPWk7ZG97bGV0IGE9by5uZXh0Lm5leHQ7Zm9yKDthIT09by5wcmV2Oyl7aWYoby5pIT09YS5pJiZXZihvLGEpKXtsZXQgYz1RYyhvLGEpO289ZG4obyxvLm5leHQpLGM9ZG4oYyxjLm5leHQpLHZpKG8sdCxlLG4scyxyLDApLHZpKGMsdCxlLG4scyxyLDApO3JldHVybn1hPWEubmV4dH1vPW8ubmV4dH13aGlsZShvIT09aSl9ZnVuY3Rpb24gTGYoaSx0LGUsbil7Y29uc3Qgcz1bXTtmb3IobGV0IHI9MCxvPXQubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9dFtyXSpuLGM9cjxvLTE/dFtyKzFdKm46aS5sZW5ndGgsbD1KYyhpLGEsYyxuLCExKTtsPT09bC5uZXh0JiYobC5zdGVpbmVyPSEwKSxzLnB1c2goSGYobCkpfXMuc29ydChPZik7Zm9yKGxldCByPTA7cjxzLmxlbmd0aDtyKyspZT1EZihzW3JdLGUpO3JldHVybiBlfWZ1bmN0aW9uIE9mKGksdCl7bGV0IGU9aS54LXQueDtpZihlPT09MCYmKGU9aS55LXQueSxlPT09MCkpe2NvbnN0IG49KGkubmV4dC55LWkueSkvKGkubmV4dC54LWkueCkscz0odC5uZXh0LnktdC55KS8odC5uZXh0LngtdC54KTtlPW4tc31yZXR1cm4gZX1mdW5jdGlvbiBEZihpLHQpe2NvbnN0IGU9JGYoaSx0KTtpZighZSlyZXR1cm4gdDtjb25zdCBuPVFjKGUsaSk7cmV0dXJuIGRuKG4sbi5uZXh0KSxkbihlLGUubmV4dCl9ZnVuY3Rpb24gJGYoaSx0KXtsZXQgZT10O2NvbnN0IG49aS54LHM9aS55O2xldCByPS0xLzAsbztpZihIbihpLGUpKXJldHVybiBlO2Rve2lmKEhuKGksZS5uZXh0KSlyZXR1cm4gZS5uZXh0O2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZZYyhzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTtUaShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmVmYobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIFZmKGksdCl7cmV0dXJuIHJ0KGkucHJldixpLHQucHJldik8MCYmcnQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIFVmKGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1ObyhzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwscWYocyl9ZnVuY3Rpb24gcWYoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBObyhpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24gSGYoaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIFljKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiB6aShpLHQsZSxuLHMscixvLGEpe3JldHVybiEoaT09PW8mJnQ9PT1hKSYmWWMoaSx0LGUsbixzLHIsbyxhKX1mdW5jdGlvbiBXZihpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFHZihpLHQpJiYoVGkoaSx0KSYmVGkodCxpKSYmWmYoaSx0KSYmKHJ0KGkucHJldixpLHQucHJldil8fHJ0KGksdC5wcmV2LHQpKXx8SG4oaSx0KSYmcnQoaS5wcmV2LGksaS5uZXh0KT4wJiZydCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIHJ0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24gSG4oaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gamMoaSx0LGUsbil7Y29uc3Qgcz1UcyhydChpLHQsZSkpLHI9VHMocnQoaSx0LG4pKSxvPVRzKHJ0KGUsbixpKSksYT1UcyhydChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJnpzKGksZSx0KXx8cj09PTAmJnpzKGksbix0KXx8bz09PTAmJnpzKGUsaSxuKXx8YT09PTAmJnpzKGUsdCxuKSl9ZnVuY3Rpb24genMoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIFRzKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBHZihpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmamMoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gVGkoaSx0KXtyZXR1cm4gcnQoaS5wcmV2LGksaS5uZXh0KTwwP3J0KGksdCxpLm5leHQpPj0wJiZydChpLGkucHJldix0KT49MDpydChpLHQsaS5wcmV2KTwwfHxydChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIFpmKGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gUWMoaSx0KXtjb25zdCBlPVJvKGkuaSxpLngsaS55KSxuPVJvKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBLYyhpLHQsZSxuKXtjb25zdCBzPVJvKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gRWkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBSbyhpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gWGYoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWNsYXNzIEpme3N0YXRpYyB0cmlhbmd1bGF0ZSh0LGUsbj0yKXtyZXR1cm4gRmYodCxlLG4pfX1jbGFzcyBXbntzdGF0aWMgYXJlYSh0KXtjb25zdCBlPXQubGVuZ3RoO2xldCBuPTA7Zm9yKGxldCBzPWUtMSxyPTA7cjxlO3M9cisrKW4rPXRbc10ueCp0W3JdLnktdFtyXS54KnRbc10ueTtyZXR1cm4gbiouNX1zdGF0aWMgaXNDbG9ja1dpc2UodCl7cmV0dXJuIFduLmFyZWEodCk8MH1zdGF0aWMgdHJpYW5ndWxhdGVTaGFwZSh0LGUpe2NvbnN0IG49W10scz1bXSxyPVtdO3RsKHQpLGVsKG4sdCk7bGV0IG89dC5sZW5ndGg7ZS5mb3JFYWNoKHRsKTtmb3IobGV0IGM9MDtjPGUubGVuZ3RoO2MrKylzLnB1c2gobyksbys9ZVtjXS5sZW5ndGgsZWwobixlW2NdKTtjb25zdCBhPUpmLnRyaWFuZ3VsYXRlKG4scyk7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKz0zKXIucHVzaChhLnNsaWNlKGMsYyszKSk7cmV0dXJuIHJ9fWZ1bmN0aW9uIHRsKGkpe2NvbnN0IHQ9aS5sZW5ndGg7dD4yJiZpW3QtMV0uZXF1YWxzKGlbMF0pJiZpLnBvcCgpfWZ1bmN0aW9uIGVsKGksdCl7Zm9yKGxldCBlPTA7ZTx0Lmxlbmd0aDtlKyspaS5wdXNoKHRbZV0ueCksaS5wdXNoKHRbZV0ueSl9Y2xhc3MgTG8gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PTEsZT0xLG49MSxzPTEpe3N1cGVyKCksdGhpcy50eXBlPSJQbGFuZUdlb21ldHJ5Iix0aGlzLnBhcmFtZXRlcnM9e3dpZHRoOnQsaGVpZ2h0OmUsd2lkdGhTZWdtZW50czpuLGhlaWdodFNlZ21lbnRzOnN9O2NvbnN0IHI9dC8yLG89ZS8yLGE9TWF0aC5mbG9vcihuKSxjPU1hdGguZmxvb3IocyksbD1hKzEsaD1jKzEsdT10L2EsZj1lL2MsZD1bXSxwPVtdLHk9W10sbT1bXTtmb3IobGV0IGc9MDtnPGg7ZysrKXtjb25zdCBiPWcqZi1vO2ZvcihsZXQgdz0wO3c8bDt3Kyspe2NvbnN0IHg9dyp1LXI7cC5wdXNoKHgsLWIsMCkseS5wdXNoKDAsMCwxKSxtLnB1c2gody9hKSxtLnB1c2goMS1nL2MpfX1mb3IobGV0IGc9MDtnPGM7ZysrKWZvcihsZXQgYj0wO2I8YTtiKyspe2NvbnN0IHc9YitsKmcseD1iK2wqKGcrMSksTT1iKzErbCooZysxKSxBPWIrMStsKmc7ZC5wdXNoKHcseCxBKSxkLnB1c2goeCxNLEEpfXRoaXMuc2V0SW5kZXgoZCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQmUocCwzKSksdGhpcy5zZXRBdHRyaWJ1dGUoIm5vcm1hbCIsbmV3IEJlKHksMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IEJlKG0sMikpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXN0YXRpYyBmcm9tSlNPTih0KXtyZXR1cm4gbmV3IExvKHQud2lkdGgsdC5oZWlnaHQsdC53aWR0aFNlZ21lbnRzLHQuaGVpZ2h0U2VnbWVudHMpfX1jb25zdCBubD1uZXcgVCxFcz1uZXcgVDtjbGFzcyBRdHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQpe3RoaXMuc3RhcnQ9dCx0aGlzLmVuZD1lfXNldCh0LGUpe3JldHVybiB0aGlzLnN0YXJ0LmNvcHkodCksdGhpcy5lbmQuY29weShlKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuc3RhcnQuY29weSh0LnN0YXJ0KSx0aGlzLmVuZC5jb3B5KHQuZW5kKSx0aGlzfWdldENlbnRlcih0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuc3RhcnQsdGhpcy5lbmQpLm11bHRpcGx5U2NhbGFyKC41KX1kZWx0YSh0KXtyZXR1cm4gdC5zdWJWZWN0b3JzKHRoaXMuZW5kLHRoaXMuc3RhcnQpfWRpc3RhbmNlU3EoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmVuZCl9ZGlzdGFuY2UoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvKHRoaXMuZW5kKX1hdCh0LGUpe3JldHVybiB0aGlzLmRlbHRhKGUpLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnN0YXJ0KX1jbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyKHQsZSl7bmwuc3ViVmVjdG9ycyh0LHRoaXMuc3RhcnQpLEVzLnN1YlZlY3RvcnModGhpcy5lbmQsdGhpcy5zdGFydCk7Y29uc3Qgbj1Fcy5kb3QoRXMpO2xldCByPUVzLmRvdChubCkvbjtyZXR1cm4gZSYmKHI9WihyLDAsMSkpLHJ9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUsbil7Y29uc3Qgcz10aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxlKTtyZXR1cm4gdGhpcy5kZWx0YShuKS5tdWx0aXBseVNjYWxhcihzKS5hZGQodGhpcy5zdGFydCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLnN0YXJ0LmFwcGx5TWF0cml4NCh0KSx0aGlzLmVuZC5hcHBseU1hdHJpeDQodCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQuc3RhcnQuZXF1YWxzKHRoaXMuc3RhcnQpJiZ0LmVuZC5lcXVhbHModGhpcy5lbmQpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX19dHlwZW9mIF9fVEhSRUVfREVWVE9PTFNfXyE9InVuZGVmaW5lZCImJl9fVEhSRUVfREVWVE9PTFNfXy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudCgicmVnaXN0ZXIiLHtkZXRhaWw6e3JldmlzaW9uOkp9fSkpLHR5cGVvZiB3aW5kb3chPSJ1bmRlZmluZWQiJiYod2luZG93Ll9fVEhSRUVfXz9jb25zb2xlLndhcm4oIldBUk5JTkc6IE11bHRpcGxlIGluc3RhbmNlcyBvZiBUaHJlZS5qcyBiZWluZyBpbXBvcnRlZC4iKTp3aW5kb3cuX19USFJFRV9fPUopO2NvbnN0IHBuPW5ldyBNYXAsWWY9KGk9e30pPT4oe2dlbmVyYXRlVG9wVVYodCxlLG4scyxyKXtjb25zdCBvPWVbbiozXSxhPWVbbiozKzFdLGM9ZVtzKjNdLGw9ZVtzKjMrMV0saD1lW3IqM10sdT1lW3IqMysxXTtsZXQgZjtpZihwbi5oYXModCkpZj1wbi5nZXQodCk7ZWxzZXtsZXQgbT1pLmJveDM7aWYoIW0pe209bmV3IGd0O2NvbnN0IHc9dC5wYXJhbWV0ZXJzLnNoYXBlcy5nZXRQb2ludHMoKS5tYXAoeD0+W3gueCx4LnksMF0pLmZsYXQoKTttLnNldEZyb21BcnJheSh3KX1jb25zdCBnPW0uZ2V0U2l6ZShuZXcgVCk7aS5zcGxpdCYmKGcueS89aS5zcGxpdCksZj17Ym94Om0sc2l6ZTpnfSxwbi5zZXQodCxmKX1jb25zdHtib3g6ZCxzaXplOnB9PWYseT1pLnNwbGl0PzEtaS5zcGxpdDowO3JldHVybltuZXcgUigoby1kLm1pbi54KS9wLngsKGEtZC5taW4ueSkvcC55K3kpLG5ldyBSKChjLWQubWluLngpL3AueCwobC1kLm1pbi55KS9wLnkreSksbmV3IFIoKGgtZC5taW4ueCkvcC54LCh1LWQubWluLnkpL3AueSt5KV19LGdlbmVyYXRlU2lkZVdhbGxVVih0LGUsbixzLHIsbyl7Y29uc3QgYT1lW24qM10sYz1lW24qMysxXSxsPWVbbiozKzJdLGg9ZVtzKjNdLHU9ZVtzKjMrMV0sZj1lW3MqMysyXSxkPWVbciozXSxwPWVbciozKzFdLHk9ZVtyKjMrMl0sbT1lW28qM10sZz1lW28qMysxXSxiPWVbbyozKzJdO2xldCB3O2lmKHBuLmhhcyhlKSl3PXBuLmdldChlKTtlbHNle2NvbnN0IEE9bmV3IGd0O0Euc2V0RnJvbUFycmF5KGUpO2NvbnN0IFM9QS5nZXRTaXplKG5ldyBUKTtpLnNwbGl0JiYoUy56Lz0xLWkuc3BsaXQpLGkuc2lkZVJlcGVhdCYmKFMuei89aS5zaWRlUmVwZWF0KSx3PXtib3g6QSxzaXplOlN9LHBuLnNldChlLHcpfWNvbnN0e2JveDp4LHNpemU6TX09dztyZXR1cm4gTWF0aC5hYnMoYy11KTxNYXRoLmFicyhhLWgpP1tuZXcgUigoYS14Lm1pbi54KS9NLngsKGwteC5taW4ueikvTS56KSxuZXcgUigoaC14Lm1pbi54KS9NLngsKGYteC5taW4ueikvTS56KSxuZXcgUigoZC14Lm1pbi54KS9NLngsKHkteC5taW4ueikvTS56KSxuZXcgUigobS14Lm1pbi54KS9NLngsKGIteC5taW4ueikvTS56KV06W25ldyBSKChjLXgubWluLnkpL00ueSwobC14Lm1pbi56KS9NLnopLG5ldyBSKCh1LXgubWluLnkpL00ueSwoZi14Lm1pbi56KS9NLnopLG5ldyBSKChwLXgubWluLnkpL00ueSwoeS14Lm1pbi56KS9NLnopLG5ldyBSKChnLXgubWluLnkpL00ueSwoYi14Lm1pbi56KS9NLnopXX19KSxqZj0oKT0+e3BuLmNsZWFyKCl9LFFmPXtBcmNDdXJ2ZTokYyxDYXRtdWxsUm9tQ3VydmUzOlZjLEN1YmljQmV6aWVyQ3VydmU6Qm8sQ3ViaWNCZXppZXJDdXJ2ZTM6cWMsRWxsaXBzZUN1cnZlOl9zLExpbmVDdXJ2ZTpGbyxMaW5lQ3VydmUzOkhjLFF1YWRyYXRpY0JlemllckN1cnZlOklvLFF1YWRyYXRpY0JlemllckN1cnZlMzpXYyxTcGxpbmVDdXJ2ZTprb307Y2xhc3MgR24gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PW5ldyBYYyhbbmV3IFIoLjUsLjUpLG5ldyBSKC0uNSwuNSksbmV3IFIoLS41LC0uNSksbmV3IFIoLjUsLS41KV0pLGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJFeHRydWRlR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz17c2hhcGVzOnQsb3B0aW9uczplfSx0PUFycmF5LmlzQXJyYXkodCk/dDpbdF07Y29uc3Qgbj10aGlzLHM9W10scj1bXTtmb3IobGV0IGE9MCxjPXQubGVuZ3RoO2E8YzthKyspe2NvbnN0IGw9dFthXTtvKGwpfXRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsbmV3IEJlKHMsMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IEJlKHIsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtmdW5jdGlvbiBvKGEpe3ZhciBPdSxEdSwkdTtjb25zdCBjPVtdLGw9ZS5jdXJ2ZVNlZ21lbnRzIT09dm9pZCAwP2UuY3VydmVTZWdtZW50czoxMixoPWUuc3RlcHMhPT12b2lkIDA/ZS5zdGVwczoxLHU9ZS5kZXB0aCE9PXZvaWQgMD9lLmRlcHRoOjE7bGV0IGY9ZS5iZXZlbEVuYWJsZWQhPT12b2lkIDA/ZS5iZXZlbEVuYWJsZWQ6ITAsZD1lLmJldmVsVGhpY2tuZXNzIT09dm9pZCAwP2UuYmV2ZWxUaGlja25lc3M6LjIscD1lLmJldmVsU2l6ZSE9PXZvaWQgMD9lLmJldmVsU2l6ZTpkLS4xLHk9ZS5iZXZlbE9mZnNldCE9PXZvaWQgMD9lLmJldmVsT2Zmc2V0OjAsbT1lLmJldmVsU2VnbWVudHMhPT12b2lkIDA/ZS5iZXZlbFNlZ21lbnRzOjM7Y29uc3QgZz1lLmV4dHJ1ZGVQYXRoLGI9ZS5VVkdlbmVyYXRvciE9PXZvaWQgMD9lLlVWR2VuZXJhdG9yOktmLHc9KE91PWUuaGFzVG9wKSE9bnVsbD9PdTohMCx4PShEdT1lLmhhc0JvdHRvbSkhPW51bGw/RHU6ITAsTT0oJHU9ZS5oYXNTaWRlKSE9bnVsbD8kdTohMDtsZXQgQSxTPSExLF8sRSx6LHY7ZyYmKEE9Zy5nZXRTcGFjZWRQb2ludHMoaCksUz0hMCxmPSExLF89Zy5jb21wdXRlRnJlbmV0RnJhbWVzKGgsITEpLEU9bmV3IFQsej1uZXcgVCx2PW5ldyBUKSxmfHwobT0wLGQ9MCxwPTAseT0wKTtjb25zdCBDPWEuZXh0cmFjdFBvaW50cyhsKTtsZXQgUD1DLnNoYXBlO2NvbnN0IEY9Qy5ob2xlcztpZighV24uaXNDbG9ja1dpc2UoUCkpe1A9UC5yZXZlcnNlKCk7Zm9yKGxldCBOPTAsTD1GLmxlbmd0aDtOPEw7TisrKXtjb25zdCBPPUZbTl07V24uaXNDbG9ja1dpc2UoTykmJihGW05dPU8ucmV2ZXJzZSgpKX19ZnVuY3Rpb24gSShOKXtjb25zdCBPPTEwMDAwMDAwMDAwMDAwMDAxZS0zNjtsZXQgVj1OWzBdO2ZvcihsZXQgJD0xOyQ8PU4ubGVuZ3RoOyQrKyl7Y29uc3QgWT0kJU4ubGVuZ3RoLEc9TltZXSxpdD1HLngtVi54LGN0PUcueS1WLnksd3Q9aXQqaXQrY3QqY3QsWHQ9TWF0aC5tYXgoTWF0aC5hYnMoRy54KSxNYXRoLmFicyhHLnkpLE1hdGguYWJzKFYueCksTWF0aC5hYnMoVi55KSksQ249TypYdCpYdDtpZih3dDw9Q24pe04uc3BsaWNlKFksMSksJC0tO2NvbnRpbnVlfVY9R319SShQKSxGLmZvckVhY2goSSk7Y29uc3Qgaz1GLmxlbmd0aCxEPVA7Zm9yKGxldCBOPTA7TjxrO04rKyl7Y29uc3QgTD1GW05dO1A9UC5jb25jYXQoTCl9ZnVuY3Rpb24gVShOLEwsTyl7cmV0dXJuIEx8fGNvbnNvbGUuZXJyb3IoIlRIUkVFLkV4dHJ1ZGVHZW9tZXRyeTogdmVjIGRvZXMgbm90IGV4aXN0IiksTi5jbG9uZSgpLmFkZFNjYWxlZFZlY3RvcihMLE8pfWNvbnN0IGo9UC5sZW5ndGg7ZnVuY3Rpb24gZHQoTixMLE8pe2xldCBWLCQsWTtjb25zdCBHPU4ueC1MLngsaXQ9Ti55LUwueSxjdD1PLngtTi54LHd0PU8ueS1OLnksWHQ9RypHK2l0Kml0LENuPUcqd3QtaXQqY3Q7aWYoTWF0aC5hYnMoQ24pPk51bWJlci5FUFNJTE9OKXtjb25zdCBKdD1NYXRoLnNxcnQoWHQpLFZ1PU1hdGguc3FydChjdCpjdCt3dCp3dCksVXU9TC54LWl0L0p0LHF1PUwueStHL0p0LFBnPU8ueC13dC9WdSxDZz1PLnkrY3QvVnUsSHU9KChQZy1VdSkqd3QtKENnLXF1KSpjdCkvKEcqd3QtaXQqY3QpO1Y9VXUrRypIdS1OLngsJD1xdStpdCpIdS1OLnk7Y29uc3QgV3U9VipWKyQqJDtpZihXdTw9MilyZXR1cm4gbmV3IFIoViwkKTtZPU1hdGguc3FydChXdS8yKX1lbHNle2xldCBKdD0hMTtHPk51bWJlci5FUFNJTE9OP2N0Pk51bWJlci5FUFNJTE9OJiYoSnQ9ITApOkc8LU51bWJlci5FUFNJTE9OP2N0PC1OdW1iZXIuRVBTSUxPTiYmKEp0PSEwKTpNYXRoLnNpZ24oaXQpPT09TWF0aC5zaWduKHd0KSYmKEp0PSEwKSxKdD8oVj0taXQsJD1HLFk9TWF0aC5zcXJ0KFh0KSk6KFY9RywkPWl0LFk9TWF0aC5zcXJ0KFh0LzIpKX1yZXR1cm4gbmV3IFIoVi9ZLCQvWSl9Y29uc3QgRHQ9W107Zm9yKGxldCBOPTAsTD1ELmxlbmd0aCxPPUwtMSxWPU4rMTtOPEw7TisrLE8rKyxWKyspTz09PUwmJihPPTApLFY9PT1MJiYoVj0wKSxEdFtOXT1kdChEW05dLERbT10sRFtWXSk7Y29uc3QgR3Q9W107bGV0IFp0LG1lPUR0LmNvbmNhdCgpO2ZvcihsZXQgTj0wLEw9aztOPEw7TisrKXtjb25zdCBPPUZbTl07WnQ9W107Zm9yKGxldCBWPTAsJD1PLmxlbmd0aCxZPSQtMSxHPVYrMTtWPCQ7VisrLFkrKyxHKyspWT09PSQmJihZPTApLEc9PT0kJiYoRz0wKSxadFtWXT1kdChPW1ZdLE9bWV0sT1tHXSk7R3QucHVzaChadCksbWU9bWUuY29uY2F0KFp0KX1sZXQgUG47aWYobT09PTApUG49V24udHJpYW5ndWxhdGVTaGFwZShELEYpO2Vsc2V7Y29uc3QgTj1bXSxMPVtdO2ZvcihsZXQgTz0wO088bTtPKyspe2NvbnN0IFY9Ty9tLCQ9ZCpNYXRoLmNvcyhWKk1hdGguUEkvMiksWT1wKk1hdGguc2luKFYqTWF0aC5QSS8yKSt5O2ZvcihsZXQgRz0wLGl0PUQubGVuZ3RoO0c8aXQ7RysrKXtjb25zdCBjdD1VKERbR10sRHRbR10sWSk7SGUoY3QueCxjdC55LC0kKSxWPT09MCYmTi5wdXNoKGN0KX1mb3IobGV0IEc9MCxpdD1rO0c8aXQ7RysrKXtjb25zdCBjdD1GW0ddO1p0PUd0W0ddO2NvbnN0IHd0PVtdO2ZvcihsZXQgWHQ9MCxDbj1jdC5sZW5ndGg7WHQ8Q247WHQrKyl7Y29uc3QgSnQ9VShjdFtYdF0sWnRbWHRdLFkpO0hlKEp0LngsSnQueSwtJCksVj09PTAmJnd0LnB1c2goSnQpfVY9PT0wJiZMLnB1c2god3QpfX1Qbj1Xbi50cmlhbmd1bGF0ZVNoYXBlKE4sTCl9Y29uc3QgWXI9UG4ubGVuZ3RoLFJ1PXAreTtmb3IobGV0IE49MDtOPGo7TisrKXtjb25zdCBMPWY/VShQW05dLG1lW05dLFJ1KTpQW05dO1M/KHouY29weShfLm5vcm1hbHNbMF0pLm11bHRpcGx5U2NhbGFyKEwueCksRS5jb3B5KF8uYmlub3JtYWxzWzBdKS5tdWx0aXBseVNjYWxhcihMLnkpLHYuY29weShBWzBdKS5hZGQoeikuYWRkKEUpLEhlKHYueCx2Lnksdi56KSk6SGUoTC54LEwueSwwKX1mb3IobGV0IE49MTtOPD1oO04rKylmb3IobGV0IEw9MDtMPGo7TCsrKXtjb25zdCBPPWY/VShQW0xdLG1lW0xdLFJ1KTpQW0xdO1M/KHouY29weShfLm5vcm1hbHNbTl0pLm11bHRpcGx5U2NhbGFyKE8ueCksRS5jb3B5KF8uYmlub3JtYWxzW05dKS5tdWx0aXBseVNjYWxhcihPLnkpLHYuY29weShBW05dKS5hZGQoeikuYWRkKEUpLEhlKHYueCx2Lnksdi56KSk6SGUoTy54LE8ueSx1L2gqTil9Zm9yKGxldCBOPW0tMTtOPj0wO04tLSl7Y29uc3QgTD1OL20sTz1kKk1hdGguY29zKEwqTWF0aC5QSS8yKSxWPXAqTWF0aC5zaW4oTCpNYXRoLlBJLzIpK3k7Zm9yKGxldCAkPTAsWT1ELmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPVUoRFskXSxEdFskXSxWKTtIZShHLngsRy55LHUrTyl9Zm9yKGxldCAkPTAsWT1GLmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPUZbJF07WnQ9R3RbJF07Zm9yKGxldCBpdD0wLGN0PUcubGVuZ3RoO2l0PGN0O2l0Kyspe2NvbnN0IHd0PVUoR1tpdF0sWnRbaXRdLFYpO1M/SGUod3QueCx3dC55K0FbaC0xXS55LEFbaC0xXS54K08pOkhlKHd0Lngsd3QueSx1K08pfX19emcoKSxNJiZUZygpO2Z1bmN0aW9uIHpnKCl7Y29uc3QgTj1zLmxlbmd0aC8zO2lmKGYpe2xldCBMPTAsTz1qKkw7aWYoeClmb3IobGV0IFY9MDtWPFlyO1YrKyl7Y29uc3QgJD1QbltWXTtqcigkWzJdK08sJFsxXStPLCRbMF0rTyl9aWYoTD1oK20qMixPPWoqTCx3KWZvcihsZXQgVj0wO1Y8WXI7VisrKXtjb25zdCAkPVBuW1ZdO2pyKCRbMF0rTywkWzFdK08sJFsyXStPKX19ZWxzZXtpZih4KWZvcihsZXQgTD0wO0w8WXI7TCsrKXtjb25zdCBPPVBuW0xdO2pyKE9bMl0sT1sxXSxPWzBdKX1pZih3KWZvcihsZXQgTD0wO0w8WXI7TCsrKXtjb25zdCBPPVBuW0xdO2pyKE9bMF0raipoLE9bMV0raipoLE9bMl0raipoKX19bi5hZGRHcm91cChOLHMubGVuZ3RoLzMtTiwwKX1mdW5jdGlvbiBUZygpe2NvbnN0IE49cy5sZW5ndGgvMztsZXQgTD0wO0x1KEQsTCksTCs9RC5sZW5ndGg7Zm9yKGxldCBPPTAsVj1GLmxlbmd0aDtPPFY7TysrKXtjb25zdCAkPUZbT107THUoJCxMKSxMKz0kLmxlbmd0aH1uLmFkZEdyb3VwKE4scy5sZW5ndGgvMy1OLDEpfWZ1bmN0aW9uIEx1KE4sTCl7bGV0IE89Ti5sZW5ndGg7Zm9yKDstLU8+PTA7KXtjb25zdCBWPU87bGV0ICQ9Ty0xOyQ8MCYmKCQ9Ti5sZW5ndGgtMSk7Zm9yKGxldCBZPTAsRz1oK20qMjtZPEc7WSsrKXtjb25zdCBpdD1qKlksY3Q9aiooWSsxKSx3dD1MK1YraXQsWHQ9TCskK2l0LENuPUwrJCtjdCxKdD1MK1YrY3Q7RWcod3QsWHQsQ24sSnQpfX19ZnVuY3Rpb24gSGUoTixMLE8pe2MucHVzaChOKSxjLnB1c2goTCksYy5wdXNoKE8pfWZ1bmN0aW9uIGpyKE4sTCxPKXtXZShOKSxXZShMKSxXZShPKTtjb25zdCBWPXMubGVuZ3RoLzMsJD1iLmdlbmVyYXRlVG9wVVYobixzLFYtMyxWLTIsVi0xKTtHZSgkWzBdKSxHZSgkWzFdKSxHZSgkWzJdKX1mdW5jdGlvbiBFZyhOLEwsTyxWKXtXZShOKSxXZShMKSxXZShWKSxXZShMKSxXZShPKSxXZShWKTtjb25zdCAkPXMubGVuZ3RoLzMsWT1iLmdlbmVyYXRlU2lkZVdhbGxVVihuLHMsJC02LCQtMywkLTIsJC0xKTtHZShZWzBdKSxHZShZWzFdKSxHZShZWzNdKSxHZShZWzFdKSxHZShZWzJdKSxHZShZWzNdKX1mdW5jdGlvbiBXZShOKXtzLnB1c2goY1tOKjMrMF0pLHMucHVzaChjW04qMysxXSkscy5wdXNoKGNbTiozKzJdKX1mdW5jdGlvbiBHZShOKXtyLnB1c2goTi54KSxyLnB1c2goTi55KX19fWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCksZT10aGlzLnBhcmFtZXRlcnMuc2hhcGVzLG49dGhpcy5wYXJhbWV0ZXJzLm9wdGlvbnM7cmV0dXJuIHRkKGUsbix0KX1zdGF0aWMgZnJvbUpTT04odCxlKXtjb25zdCBuPVtdO2ZvcihsZXQgcj0wLG89dC5zaGFwZXMubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVt0LnNoYXBlc1tyXV07bi5wdXNoKGEpfWNvbnN0IHM9dC5vcHRpb25zLmV4dHJ1ZGVQYXRoO3JldHVybiBzIT09dm9pZCAwJiYodC5vcHRpb25zLmV4dHJ1ZGVQYXRoPW5ldyBRZltgJHtzLnR5cGV9YF0oKS5mcm9tSlNPTihzKSksbmV3IEduKG4sdC5vcHRpb25zKX19Y29uc3QgS2Y9e2dlbmVyYXRlVG9wVVY6ZnVuY3Rpb24oaSx0LGUsbixzKXtjb25zdCByPXRbZSozXSxvPXRbZSozKzFdLGE9dFtuKjNdLGM9dFtuKjMrMV0sbD10W3MqM10saD10W3MqMysxXTtyZXR1cm5bbmV3IFIocixvKSxuZXcgUihhLGMpLG5ldyBSKGwsaCldfSxnZW5lcmF0ZVNpZGVXYWxsVVY6ZnVuY3Rpb24oaSx0LGUsbixzLHIpe2NvbnN0IG89dFtlKjNdLGE9dFtlKjMrMV0sYz10W2UqMysyXSxsPXRbbiozXSxoPXRbbiozKzFdLHU9dFtuKjMrMl0sZj10W3MqM10sZD10W3MqMysxXSxwPXRbcyozKzJdLHk9dFtyKjNdLG09dFtyKjMrMV0sZz10W3IqMysyXTtyZXR1cm4gTWF0aC5hYnMoYS1oKTxNYXRoLmFicyhvLWwpP1tuZXcgUihvLDEtYyksbmV3IFIobCwxLXUpLG5ldyBSKGYsMS1wKSxuZXcgUih5LDEtZyldOltuZXcgUihhLDEtYyksbmV3IFIoaCwxLXUpLG5ldyBSKGQsMS1wKSxuZXcgUihtLDEtZyldfX07ZnVuY3Rpb24gdGQoaSx0LGUpe2lmKGUuc2hhcGVzPVtdLEFycmF5LmlzQXJyYXkoaSkpZm9yKGxldCBuPTAscz1pLmxlbmd0aDtuPHM7bisrKXtjb25zdCByPWlbbl07ZS5zaGFwZXMucHVzaChyLnV1aWQpfWVsc2UgZS5zaGFwZXMucHVzaChpLnV1aWQpO3JldHVybiBlLm9wdGlvbnM9T2JqZWN0LmFzc2lnbih7fSx0KSx0LmV4dHJ1ZGVQYXRoIT09dm9pZCAwJiYoZS5vcHRpb25zLmV4dHJ1ZGVQYXRoPXQuZXh0cnVkZVBhdGgudG9KU09OKCkpLGV9Y29uc3QgaWw9MCxlZD0xLG5kPTIsc2w9MixPbz0xLjI1LHJsPTEsUGk9Nio0KzQrNCxQcz02NTUzNSxpZD1NYXRoLnBvdygyLC0yNCksRG89U3ltYm9sKCJTS0lQX0dFTkVSQVRJT04iKTtmdW5jdGlvbiBzZChpKXtyZXR1cm4gaS5pbmRleD9pLmluZGV4LmNvdW50OmkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudH1mdW5jdGlvbiBabihpKXtyZXR1cm4gc2QoaSkvM31mdW5jdGlvbiByZChpLHQ9QXJyYXlCdWZmZXIpe3JldHVybiBpPjY1NTM1P25ldyBVaW50MzJBcnJheShuZXcgdCg0KmkpKTpuZXcgVWludDE2QXJyYXkobmV3IHQoMippKSl9ZnVuY3Rpb24gb2QoaSx0KXtpZighaS5pbmRleCl7Y29uc3QgZT1pLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQsbj10LnVzZVNoYXJlZEFycmF5QnVmZmVyP1NoYXJlZEFycmF5QnVmZmVyOkFycmF5QnVmZmVyLHM9cmQoZSxuKTtpLnNldEluZGV4KG5ldyB4dChzLDEpKTtmb3IobGV0IHI9MDtyPGU7cisrKXNbcl09cn19ZnVuY3Rpb24gb2woaSx0KXtjb25zdCBlPVpuKGkpLG49dHx8aS5kcmF3UmFuZ2Uscz1uLnN0YXJ0LzMscj0obi5zdGFydCtuLmNvdW50KS8zLG89TWF0aC5tYXgoMCxzKSxhPU1hdGgubWluKGUsciktbztyZXR1cm5be29mZnNldDpNYXRoLmZsb29yKG8pLGNvdW50Ok1hdGguZmxvb3IoYSl9XX1mdW5jdGlvbiBhbChpLHQpe2lmKCFpLmdyb3Vwc3x8IWkuZ3JvdXBzLmxlbmd0aClyZXR1cm4gb2woaSx0KTtjb25zdCBlPVtdLG49bmV3IFNldCxzPXR8fGkuZHJhd1JhbmdlLHI9cy5zdGFydC8zLG89KHMuc3RhcnQrcy5jb3VudCkvMztmb3IoY29uc3QgYyBvZiBpLmdyb3Vwcyl7Y29uc3QgbD1jLnN0YXJ0LzMsaD0oYy5zdGFydCtjLmNvdW50KS8zO24uYWRkKE1hdGgubWF4KHIsbCkpLG4uYWRkKE1hdGgubWluKG8saCkpfWNvbnN0IGE9QXJyYXkuZnJvbShuLnZhbHVlcygpKS5zb3J0KChjLGwpPT5jLWwpO2ZvcihsZXQgYz0wO2M8YS5sZW5ndGgtMTtjKyspe2NvbnN0IGw9YVtjXSxoPWFbYysxXTtlLnB1c2goe29mZnNldDpNYXRoLmZsb29yKGwpLGNvdW50Ok1hdGguZmxvb3IoaC1sKX0pfXJldHVybiBlfWZ1bmN0aW9uIGFkKGksdCl7Y29uc3QgZT1abihpKSxuPWFsKGksdCkuc29ydCgobyxhKT0+by5vZmZzZXQtYS5vZmZzZXQpLHM9bltuLmxlbmd0aC0xXTtzLmNvdW50PU1hdGgubWluKGUtcy5vZmZzZXQscy5jb3VudCk7bGV0IHI9MDtyZXR1cm4gbi5mb3JFYWNoKCh7Y291bnQ6b30pPT5yKz1vKSxlIT09cn1mdW5jdGlvbiAkbyhpLHQsZSxuLHMpe2xldCByPTEvMCxvPTEvMCxhPTEvMCxjPS0xLzAsbD0tMS8wLGg9LTEvMCx1PTEvMCxmPTEvMCxkPTEvMCxwPS0xLzAseT0tMS8wLG09LTEvMDtmb3IobGV0IGc9dCo2LGI9KHQrZSkqNjtnPGI7Zys9Nil7Y29uc3Qgdz1pW2crMF0seD1pW2crMV0sTT13LXgsQT13K3g7TTxyJiYocj1NKSxBPmMmJihjPUEpLHc8dSYmKHU9dyksdz5wJiYocD13KTtjb25zdCBTPWlbZysyXSxfPWlbZyszXSxFPVMtXyx6PVMrXztFPG8mJihvPUUpLHo+bCYmKGw9eiksUzxmJiYoZj1TKSxTPnkmJih5PVMpO2NvbnN0IHY9aVtnKzRdLEM9aVtnKzVdLFA9di1DLEY9ditDO1A8YSYmKGE9UCksRj5oJiYoaD1GKSx2PGQmJihkPXYpLHY+bSYmKG09dil9blswXT1yLG5bMV09byxuWzJdPWEsblszXT1jLG5bNF09bCxuWzVdPWgsc1swXT11LHNbMV09ZixzWzJdPWQsc1szXT1wLHNbNF09eSxzWzVdPW19ZnVuY3Rpb24gY2QoaSx0PW51bGwsZT1udWxsLG49bnVsbCl7Y29uc3Qgcz1pLmF0dHJpYnV0ZXMucG9zaXRpb24scj1pLmluZGV4P2kuaW5kZXguYXJyYXk6bnVsbCxvPVpuKGkpLGE9cy5ub3JtYWxpemVkO2xldCBjO3Q9PT1udWxsPyhjPW5ldyBGbG9hdDMyQXJyYXkobyo2KSxlPTAsbj1vKTooYz10LGU9ZXx8MCxuPW58fG8pO2NvbnN0IGw9cy5hcnJheSxoPXMub2Zmc2V0fHwwO2xldCB1PTM7cy5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlJiYodT1zLmRhdGEuc3RyaWRlKTtjb25zdCBmPVsiZ2V0WCIsImdldFkiLCJnZXRaIl07Zm9yKGxldCBkPWU7ZDxlK247ZCsrKXtjb25zdCBwPWQqMyx5PWQqNjtsZXQgbT1wKzAsZz1wKzEsYj1wKzI7ciYmKG09clttXSxnPXJbZ10sYj1yW2JdKSxhfHwobT1tKnUraCxnPWcqdStoLGI9Yip1K2gpO2ZvcihsZXQgdz0wO3c8Mzt3Kyspe2xldCB4LE0sQTthPyh4PXNbZlt3XV0obSksTT1zW2Zbd11dKGcpLEE9c1tmW3ddXShiKSk6KHg9bFttK3ddLE09bFtnK3ddLEE9bFtiK3ddKTtsZXQgUz14O008UyYmKFM9TSksQTxTJiYoUz1BKTtsZXQgXz14O00+XyYmKF89TSksQT5fJiYoXz1BKTtjb25zdCBFPShfLVMpLzIsej13KjI7Y1t5K3orMF09UytFLGNbeSt6KzFdPUUrKE1hdGguYWJzKFMpK0UpKmlkfX1yZXR1cm4gY31mdW5jdGlvbiBsdChpLHQsZSl7cmV0dXJuIGUubWluLng9dFtpXSxlLm1pbi55PXRbaSsxXSxlLm1pbi56PXRbaSsyXSxlLm1heC54PXRbaSszXSxlLm1heC55PXRbaSs0XSxlLm1heC56PXRbaSs1XSxlfWZ1bmN0aW9uIGNsKGkpe2xldCB0PS0xLGU9LTEvMDtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPWlbbiszXS1pW25dO3M+ZSYmKGU9cyx0PW4pfXJldHVybiB0fWZ1bmN0aW9uIGxsKGksdCl7dC5zZXQoaSl9ZnVuY3Rpb24gaGwoaSx0LGUpe2xldCBuLHM7Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz1yKzM7bj1pW3JdLHM9dFtyXSxlW3JdPW48cz9uOnMsbj1pW29dLHM9dFtvXSxlW29dPW4+cz9uOnN9fWZ1bmN0aW9uIENzKGksdCxlKXtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPXRbaSsyKm5dLHI9dFtpKzIqbisxXSxvPXMtcixhPXMrcjtvPGVbbl0mJihlW25dPW8pLGE+ZVtuKzNdJiYoZVtuKzNdPWEpfX1mdW5jdGlvbiBDaShpKXtjb25zdCB0PWlbM10taVswXSxlPWlbNF0taVsxXSxuPWlbNV0taVsyXTtyZXR1cm4gMioodCplK2UqbituKnQpfWNvbnN0IEZlPTMyLGxkPShpLHQpPT5pLmNhbmRpZGF0ZS10LmNhbmRpZGF0ZSxLZT1uZXcgQXJyYXkoRmUpLmZpbGwoKS5tYXAoKCk9Pih7Y291bnQ6MCxib3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxyaWdodENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksbGVmdENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksY2FuZGlkYXRlOjB9KSksQnM9bmV3IEZsb2F0MzJBcnJheSg2KTtmdW5jdGlvbiBoZChpLHQsZSxuLHMscil7bGV0IG89LTEsYT0wO2lmKHI9PT1pbClvPWNsKHQpLG8hPT0tMSYmKGE9KHRbb10rdFtvKzNdKS8yKTtlbHNlIGlmKHI9PT1lZClvPWNsKGkpLG8hPT0tMSYmKGE9dWQoZSxuLHMsbykpO2Vsc2UgaWYocj09PW5kKXtjb25zdCBjPUNpKGkpO2xldCBsPU9vKnM7Y29uc3QgaD1uKjYsdT0obitzKSo2O2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9dFtmXSxtPSh0W2YrM10tZCkvRmU7aWYoczxGZS80KXtjb25zdCBnPVsuLi5LZV07Zy5sZW5ndGg9cztsZXQgYj0wO2ZvcihsZXQgeD1oO3g8dTt4Kz02LGIrKyl7Y29uc3QgTT1nW2JdO00uY2FuZGlkYXRlPWVbeCsyKmZdLE0uY291bnQ9MDtjb25zdHtib3VuZHM6QSxsZWZ0Q2FjaGVCb3VuZHM6UyxyaWdodENhY2hlQm91bmRzOl99PU07Zm9yKGxldCBFPTA7RTwzO0UrKylfW0VdPTEvMCxfW0UrM109LTEvMCxTW0VdPTEvMCxTW0UrM109LTEvMCxBW0VdPTEvMCxBW0UrM109LTEvMDtDcyh4LGUsQSl9Zy5zb3J0KGxkKTtsZXQgdz1zO2ZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XTtmb3IoO3grMTx3JiZnW3grMV0uY2FuZGlkYXRlPT09TS5jYW5kaWRhdGU7KWcuc3BsaWNlKHgrMSwxKSx3LS19Zm9yKGxldCB4PWg7eDx1O3grPTYpe2NvbnN0IE09ZVt4KzIqZl07Zm9yKGxldCBBPTA7QTx3O0ErKyl7Y29uc3QgUz1nW0FdO00+PVMuY2FuZGlkYXRlP0NzKHgsZSxTLnJpZ2h0Q2FjaGVCb3VuZHMpOihDcyh4LGUsUy5sZWZ0Q2FjaGVCb3VuZHMpLFMuY291bnQrKyl9fWZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XSxBPU0uY291bnQsUz1zLU0uY291bnQsXz1NLmxlZnRDYWNoZUJvdW5kcyxFPU0ucmlnaHRDYWNoZUJvdW5kcztsZXQgej0wO0EhPT0wJiYoej1DaShfKS9jKTtsZXQgdj0wO1MhPT0wJiYodj1DaShFKS9jKTtjb25zdCBDPXJsK09vKih6KkErdipTKTtDPGwmJihvPWYsbD1DLGE9TS5jYW5kaWRhdGUpfX1lbHNle2ZvcihsZXQgdz0wO3c8RmU7dysrKXtjb25zdCB4PUtlW3ddO3guY291bnQ9MCx4LmNhbmRpZGF0ZT1kK20rdyptO2NvbnN0IE09eC5ib3VuZHM7Zm9yKGxldCBBPTA7QTwzO0ErKylNW0FdPTEvMCxNW0ErM109LTEvMH1mb3IobGV0IHc9aDt3PHU7dys9Nil7bGV0IEE9fn4oKGVbdysyKmZdLWQpL20pO0E+PUZlJiYoQT1GZS0xKTtjb25zdCBTPUtlW0FdO1MuY291bnQrKyxDcyh3LGUsUy5ib3VuZHMpfWNvbnN0IGc9S2VbRmUtMV07bGwoZy5ib3VuZHMsZy5yaWdodENhY2hlQm91bmRzKTtmb3IobGV0IHc9RmUtMjt3Pj0wO3ctLSl7Y29uc3QgeD1LZVt3XSxNPUtlW3crMV07aGwoeC5ib3VuZHMsTS5yaWdodENhY2hlQm91bmRzLHgucmlnaHRDYWNoZUJvdW5kcyl9bGV0IGI9MDtmb3IobGV0IHc9MDt3PEZlLTE7dysrKXtjb25zdCB4PUtlW3ddLE09eC5jb3VudCxBPXguYm91bmRzLF89S2VbdysxXS5yaWdodENhY2hlQm91bmRzO00hPT0wJiYoYj09PTA/bGwoQSxCcyk6aGwoQSxCcyxCcykpLGIrPU07bGV0IEU9MCx6PTA7YiE9PTAmJihFPUNpKEJzKS9jKTtjb25zdCB2PXMtYjt2IT09MCYmKHo9Q2koXykvYyk7Y29uc3QgQz1ybCtPbyooRSpiK3oqdik7QzxsJiYobz1mLGw9QyxhPXguY2FuZGlkYXRlKX19fX1lbHNlIGNvbnNvbGUud2FybihgTWVzaEJWSDogSW52YWxpZCBidWlsZCBzdHJhdGVneSB2YWx1ZSAke3J9IHVzZWQuYCk7cmV0dXJue2F4aXM6byxwb3M6YX19ZnVuY3Rpb24gdWQoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPXQrZTtyPG87cisrKXMrPWlbcio2K24qMl07cmV0dXJuIHMvZX1jbGFzcyBWb3tjb25zdHJ1Y3Rvcigpe3RoaXMuYm91bmRpbmdEYXRhPW5ldyBGbG9hdDMyQXJyYXkoNil9fWZ1bmN0aW9uIGZkKGksdCxlLG4scyxyKXtsZXQgbz1uLGE9bitzLTE7Y29uc3QgYz1yLnBvcyxsPXIuYXhpcyoyO2Zvcig7Oyl7Zm9yKDtvPD1hJiZlW28qNitsXTxjOylvKys7Zm9yKDtvPD1hJiZlW2EqNitsXT49YzspYS0tO2lmKG88YSl7Zm9yKGxldCBoPTA7aDwzO2grKyl7bGV0IHU9dFtvKjMraF07dFtvKjMraF09dFthKjMraF0sdFthKjMraF09dX1mb3IobGV0IGg9MDtoPDY7aCsrKXtsZXQgdT1lW28qNitoXTtlW28qNitoXT1lW2EqNitoXSxlW2EqNitoXT11fW8rKyxhLS19ZWxzZSByZXR1cm4gb319ZnVuY3Rpb24gZGQoaSx0LGUsbixzLHIpe2xldCBvPW4sYT1uK3MtMTtjb25zdCBjPXIucG9zLGw9ci5heGlzKjI7Zm9yKDs7KXtmb3IoO288PWEmJmVbbyo2K2xdPGM7KW8rKztmb3IoO288PWEmJmVbYSo2K2xdPj1jOylhLS07aWYobzxhKXtsZXQgaD1pW29dO2lbb109aVthXSxpW2FdPWg7Zm9yKGxldCB1PTA7dTw2O3UrKyl7bGV0IGY9ZVtvKjYrdV07ZVtvKjYrdV09ZVthKjYrdV0sZVthKjYrdV09Zn1vKyssYS0tfWVsc2UgcmV0dXJuIG99fWZ1bmN0aW9uIGt0KGksdCl7cmV0dXJuIHRbaSsxNV09PT02NTUzNX1mdW5jdGlvbiBVdChpLHQpe3JldHVybiB0W2krNl19ZnVuY3Rpb24gS3QoaSx0KXtyZXR1cm4gdFtpKzE0XX1mdW5jdGlvbiB0ZShpKXtyZXR1cm4gaSs4fWZ1bmN0aW9uIGVlKGksdCl7cmV0dXJuIHRbaSs2XX1mdW5jdGlvbiB1bChpLHQpe3JldHVybiB0W2krN119ZnVuY3Rpb24gamcoaSl7cmV0dXJuIGl9bGV0IGZsLEJpLEZzLGRsO2NvbnN0IHBkPU1hdGgucG93KDIsMzIpO2Z1bmN0aW9uIFVvKGkpe3JldHVybiJjb3VudCJpbiBpPzE6MStVbyhpLmxlZnQpK1VvKGkucmlnaHQpfWZ1bmN0aW9uIHlkKGksdCxlKXtyZXR1cm4gZmw9bmV3IEZsb2F0MzJBcnJheShlKSxCaT1uZXcgVWludDMyQXJyYXkoZSksRnM9bmV3IFVpbnQxNkFycmF5KGUpLGRsPW5ldyBVaW50OEFycmF5KGUpLHFvKGksdCl9ZnVuY3Rpb24gcW8oaSx0KXtjb25zdCBlPWkvNCxuPWkvMixzPSJjb3VudCJpbiB0LHI9dC5ib3VuZGluZ0RhdGE7Zm9yKGxldCBvPTA7bzw2O28rKylmbFtlK29dPXJbb107aWYocylpZih0LmJ1ZmZlcil7Y29uc3Qgbz10LmJ1ZmZlcjtkbC5zZXQobmV3IFVpbnQ4QXJyYXkobyksaSk7Zm9yKGxldCBhPWksYz1pK28uYnl0ZUxlbmd0aDthPGM7YSs9UGkpe2NvbnN0IGw9YS8yO2t0KGwsRnMpfHwoQmlbYS80KzZdKz1lKX1yZXR1cm4gaStvLmJ5dGVMZW5ndGh9ZWxzZXtjb25zdCBvPXQub2Zmc2V0LGE9dC5jb3VudDtyZXR1cm4gQmlbZSs2XT1vLEZzW24rMTRdPWEsRnNbbisxNV09UHMsaStQaX1lbHNle2NvbnN0IG89dC5sZWZ0LGE9dC5yaWdodCxjPXQuc3BsaXRBeGlzO2xldCBsO2lmKGw9cW8oaStQaSxvKSxsLzQ+cGQpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBDYW5ub3Qgc3RvcmUgY2hpbGQgcG9pbnRlciBncmVhdGVyIHRoYW4gMzIgYml0cy4iKTtyZXR1cm4gQmlbZSs2XT1sLzQsbD1xbyhsLGEpLEJpW2UrN109YyxsfX1mdW5jdGlvbiBtZChpLHQpe2NvbnN0IGU9KGkuaW5kZXg/aS5pbmRleC5jb3VudDppLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQpLzMsbj1lPnlpKDIsMTYpLHM9bj80OjIscj10P25ldyBTaGFyZWRBcnJheUJ1ZmZlcihlKnMpOm5ldyBBcnJheUJ1ZmZlcihlKnMpLG89bj9uZXcgVWludDMyQXJyYXkocik6bmV3IFVpbnQxNkFycmF5KHIpO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKylvW2FdPWE7cmV0dXJuIG99ZnVuY3Rpb24gZ2QoaSx0LGUsbixzKXtjb25zdHttYXhEZXB0aDpyLHZlcmJvc2U6byxtYXhMZWFmVHJpczphLHN0cmF0ZWd5OmMsb25Qcm9ncmVzczpsLGluZGlyZWN0Omh9PXMsdT1pLl9pbmRpcmVjdEJ1ZmZlcixmPWkuZ2VvbWV0cnksZD1mLmluZGV4P2YuaW5kZXguYXJyYXk6bnVsbCxwPWg/ZGQ6ZmQseT1abihmKSxtPW5ldyBGbG9hdDMyQXJyYXkoNik7bGV0IGc9ITE7Y29uc3QgYj1uZXcgVm87cmV0dXJuICRvKHQsZSxuLGIuYm91bmRpbmdEYXRhLG0pLHgoYixlLG4sbSksYjtmdW5jdGlvbiB3KE0pe2wmJmwoTS95KX1mdW5jdGlvbiB4KE0sQSxTLF89bnVsbCxFPTApe2lmKCFnJiZFPj1yJiYoZz0hMCxvJiYoY29uc29sZS53YXJuKGBNZXNoQlZIOiBNYXggZGVwdGggb2YgJHtyfSByZWFjaGVkIHdoZW4gZ2VuZXJhdGluZyBCVkguIENvbnNpZGVyIGluY3JlYXNpbmcgbWF4RGVwdGguYCksY29uc29sZS53YXJuKGYpKSksUzw9YXx8RT49cilyZXR1cm4gdyhBK1MpLE0ub2Zmc2V0PUEsTS5jb3VudD1TLE07Y29uc3Qgej1oZChNLmJvdW5kaW5nRGF0YSxfLHQsQSxTLGMpO2lmKHouYXhpcz09PS0xKXJldHVybiB3KEErUyksTS5vZmZzZXQ9QSxNLmNvdW50PVMsTTtjb25zdCB2PXAodSxkLHQsQSxTLHopO2lmKHY9PT1BfHx2PT09QStTKXcoQStTKSxNLm9mZnNldD1BLE0uY291bnQ9UztlbHNle00uc3BsaXRBeGlzPXouYXhpcztjb25zdCBDPW5ldyBWbyxQPUEsRj12LUE7TS5sZWZ0PUMsJG8odCxQLEYsQy5ib3VuZGluZ0RhdGEsbSkseChDLFAsRixtLEUrMSk7Y29uc3QgQj1uZXcgVm8sST12LGs9Uy1GO00ucmlnaHQ9Qiwkbyh0LEksayxCLmJvdW5kaW5nRGF0YSxtKSx4KEIsSSxrLG0sRSsxKX1yZXR1cm4gTX19ZnVuY3Rpb24geGQoaSx0KXtjb25zdCBlPWkuZ2VvbWV0cnk7dC5pbmRpcmVjdCYmKGkuX2luZGlyZWN0QnVmZmVyPW1kKGUsdC51c2VTaGFyZWRBcnJheUJ1ZmZlciksYWQoZSx0LnJhbmdlKSYmIXQudmVyYm9zZSYmY29uc29sZS53YXJuKCdNZXNoQlZIOiBQcm92aWRlZCBnZW9tZXRyeSBjb250YWlucyBncm91cHMgb3IgYSByYW5nZSB0aGF0IGRvIG5vdCBmdWxseSBzcGFuIHRoZSB2ZXJ0ZXggY29udGVudHMgd2hpbGUgdXNpbmcgdGhlICJpbmRpcmVjdCIgb3B0aW9uLiBCVkggbWF5IGluY29ycmVjdGx5IHJlcG9ydCBpbnRlcnNlY3Rpb25zIG9uIHVucmVuZGVyZWQgcG9ydGlvbnMgb2YgdGhlIGdlb21ldHJ5LicpKSxpLl9pbmRpcmVjdEJ1ZmZlcnx8b2QoZSx0KTtjb25zdCBuPXQudXNlU2hhcmVkQXJyYXlCdWZmZXI/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1jZChlKSxyPXQuaW5kaXJlY3Q/b2woZSx0LnJhbmdlKTphbChlLHQucmFuZ2UpO2kuX3Jvb3RzPXIubWFwKG89Pntjb25zdCBhPWdkKGkscyxvLm9mZnNldCxvLmNvdW50LHQpLGM9VW8oYSksbD1uZXcgbihQaSpjKTtyZXR1cm4geWQoMCxhLGwpLGx9KX1jbGFzcyBJZXtjb25zdHJ1Y3Rvcigpe3RoaXMubWluPTEvMCx0aGlzLm1heD0tMS8wfXNldEZyb21Qb2ludHNGaWVsZCh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBjPXRbcl1bZV07bj1jPG4/YzpuLHM9Yz5zP2M6c310aGlzLm1pbj1uLHRoaXMubWF4PXN9c2V0RnJvbVBvaW50cyh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl0sYz10LmRvdChhKTtuPWM8bj9jOm4scz1jPnM/YzpzfXRoaXMubWluPW4sdGhpcy5tYXg9c31pc1NlcGFyYXRlZCh0KXtyZXR1cm4gdGhpcy5taW4+dC5tYXh8fHQubWluPnRoaXMubWF4fX1JZS5wcm90b3R5cGUuc2V0RnJvbUJveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Y29uc3Qgcz1uLm1pbixyPW4ubWF4O2xldCBvPTEvMCxhPS0xLzA7Zm9yKGxldCBjPTA7Yzw9MTtjKyspZm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspe2kueD1zLngqYytyLngqKDEtYyksaS55PXMueSpsK3IueSooMS1sKSxpLno9cy56Kmgrci56KigxLWgpO2NvbnN0IHU9ZS5kb3QoaSk7bz1NYXRoLm1pbih1LG8pLGE9TWF0aC5tYXgodSxhKX10aGlzLm1pbj1vLHRoaXMubWF4PWF9fSgpO2NvbnN0IHdkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtjb25zdCBhPXMuc3RhcnQsYz1pLGw9ci5zdGFydCxoPXQ7ZS5zdWJWZWN0b3JzKGEsbCksaS5zdWJWZWN0b3JzKHMuZW5kLHMuc3RhcnQpLHQuc3ViVmVjdG9ycyhyLmVuZCxyLnN0YXJ0KTtjb25zdCB1PWUuZG90KGgpLGY9aC5kb3QoYyksZD1oLmRvdChoKSxwPWUuZG90KGMpLG09Yy5kb3QoYykqZC1mKmY7bGV0IGcsYjttIT09MD9nPSh1KmYtcCpkKS9tOmc9MCxiPSh1K2cqZikvZCxvLng9ZyxvLnk9Yn19KCksSG89ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBSLHQ9bmV3IFQsZT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24ocyxyLG8sYSl7d2QocyxyLGkpO2xldCBjPWkueCxsPWkueTtpZihjPj0wJiZjPD0xJiZsPj0wJiZsPD0xKXtzLmF0KGMsbyksci5hdChsLGEpO3JldHVybn1lbHNlIGlmKGM+PTAmJmM8PTEpe2w8MD9yLmF0KDAsYSk6ci5hdCgxLGEpLHMuY2xvc2VzdFBvaW50VG9Qb2ludChhLCEwLG8pO3JldHVybn1lbHNlIGlmKGw+PTAmJmw8PTEpe2M8MD9zLmF0KDAsbyk6cy5hdCgxLG8pLHIuY2xvc2VzdFBvaW50VG9Qb2ludChvLCEwLGEpO3JldHVybn1lbHNle2xldCBoO2M8MD9oPXMuc3RhcnQ6aD1zLmVuZDtsZXQgdTtsPDA/dT1yLnN0YXJ0OnU9ci5lbmQ7Y29uc3QgZj10LGQ9ZTtpZihzLmNsb3Nlc3RQb2ludFRvUG9pbnQodSwhMCx0KSxyLmNsb3Nlc3RQb2ludFRvUG9pbnQoaCwhMCxlKSxmLmRpc3RhbmNlVG9TcXVhcmVkKHUpPD1kLmRpc3RhbmNlVG9TcXVhcmVkKGgpKXtvLmNvcHkoZiksYS5jb3B5KHUpO3JldHVybn1lbHNle28uY29weShoKSxhLmNvcHkoZCk7cmV0dXJufX19fSgpLGJkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IHpvLG49bmV3IFF0O3JldHVybiBmdW5jdGlvbihyLG8pe2NvbnN0e3JhZGl1czphLGNlbnRlcjpjfT1yLHthOmwsYjpoLGM6dX09bztpZihuLnN0YXJ0PWwsbi5lbmQ9aCxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hfHwobi5zdGFydD1sLG4uZW5kPXUsbi5jbG9zZXN0UG9pbnRUb1BvaW50KGMsITAsaSkuZGlzdGFuY2VUbyhjKTw9YSl8fChuLnN0YXJ0PWgsbi5lbmQ9dSxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hKSlyZXR1cm4hMDtjb25zdCB5PW8uZ2V0UGxhbmUoZSk7aWYoTWF0aC5hYnMoeS5kaXN0YW5jZVRvUG9pbnQoYykpPD1hKXtjb25zdCBnPXkucHJvamVjdFBvaW50KGMsdCk7aWYoby5jb250YWluc1BvaW50KGcpKXJldHVybiEwfXJldHVybiExfX0oKSxNZD0xZS0xNTtmdW5jdGlvbiBXbyhpKXtyZXR1cm4gTWF0aC5hYnMoaSk8TWR9Y2xhc3MgbmUgZXh0ZW5kcyBldHtjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzRXh0ZW5kZWRUcmlhbmdsZT0hMCx0aGlzLnNhdEF4ZXM9bmV3IEFycmF5KDQpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEJvdW5kcz1uZXcgQXJyYXkoNCkuZmlsbCgpLm1hcCgoKT0+bmV3IEllKSx0aGlzLnBvaW50cz1bdGhpcy5hLHRoaXMuYix0aGlzLmNdLHRoaXMuc3BoZXJlPW5ldyBjbyx0aGlzLnBsYW5lPW5ldyB6byx0aGlzLm5lZWRzVXBkYXRlPSEwfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIGJkKHQsdGhpcyl9dXBkYXRlKCl7Y29uc3QgdD10aGlzLmEsZT10aGlzLmIsbj10aGlzLmMscz10aGlzLnBvaW50cyxyPXRoaXMuc2F0QXhlcyxvPXRoaXMuc2F0Qm91bmRzLGE9clswXSxjPW9bMF07dGhpcy5nZXROb3JtYWwoYSksYy5zZXRGcm9tUG9pbnRzKGEscyk7Y29uc3QgbD1yWzFdLGg9b1sxXTtsLnN1YlZlY3RvcnModCxlKSxoLnNldEZyb21Qb2ludHMobCxzKTtjb25zdCB1PXJbMl0sZj1vWzJdO3Uuc3ViVmVjdG9ycyhlLG4pLGYuc2V0RnJvbVBvaW50cyh1LHMpO2NvbnN0IGQ9clszXSxwPW9bM107ZC5zdWJWZWN0b3JzKG4sdCkscC5zZXRGcm9tUG9pbnRzKGQscyksdGhpcy5zcGhlcmUuc2V0RnJvbVBvaW50cyh0aGlzLnBvaW50cyksdGhpcy5wbGFuZS5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChhLHQpLHRoaXMubmVlZHNVcGRhdGU9ITF9fW5lLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRUb1NlZ21lbnQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKHMscj1udWxsLG89bnVsbCl7Y29uc3R7c3RhcnQ6YSxlbmQ6Y309cyxsPXRoaXMucG9pbnRzO2xldCBoLHU9MS8wO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9KGYrMSklMztlLnN0YXJ0LmNvcHkobFtmXSksZS5lbmQuY29weShsW2RdKSxIbyhlLHMsaSx0KSxoPWkuZGlzdGFuY2VUb1NxdWFyZWQodCksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkodCkpfXJldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoYSxpKSxoPWEuZGlzdGFuY2VUb1NxdWFyZWQoaSksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkoYSkpLHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChjLGkpLGg9Yy5kaXN0YW5jZVRvU3F1YXJlZChpKSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weShjKSksTWF0aC5zcXJ0KHUpfX0oKSxuZS5wcm90b3R5cGUuaW50ZXJzZWN0c1RyaWFuZ2xlPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgbmUsdD1uZXcgQXJyYXkoMyksZT1uZXcgQXJyYXkoMyksbj1uZXcgSWUscz1uZXcgSWUscj1uZXcgVCxvPW5ldyBULGE9bmV3IFQsYz1uZXcgVCxsPW5ldyBULGg9bmV3IFF0LHU9bmV3IFF0LGY9bmV3IFF0LGQ9bmV3IFQ7ZnVuY3Rpb24gcCh5LG0sZyl7Y29uc3QgYj15LnBvaW50cztsZXQgdz0wLHg9LTE7Zm9yKGxldCBNPTA7TTwzO00rKyl7Y29uc3R7c3RhcnQ6QSxlbmQ6U309aDtBLmNvcHkoYltNXSksUy5jb3B5KGJbKE0rMSklM10pLGguZGVsdGEobyk7Y29uc3QgXz1XbyhtLmRpc3RhbmNlVG9Qb2ludChBKSk7aWYoV28obS5ub3JtYWwuZG90KG8pKSYmXyl7Zy5jb3B5KGgpLHc9MjticmVha31jb25zdCBFPW0uaW50ZXJzZWN0TGluZShoLGQpO2lmKCFFJiZfJiZkLmNvcHkoQSksKEV8fF8pJiYhV28oZC5kaXN0YW5jZVRvKFMpKSl7aWYodzw9MSkodz09PTE/Zy5zdGFydDpnLmVuZCkuY29weShkKSxfJiYoeD13KTtlbHNlIGlmKHc+PTIpeyh4PT09MT9nLnN0YXJ0OmcuZW5kKS5jb3B5KGQpLHc9MjticmVha31pZih3Kyssdz09PTImJng9PT0tMSlicmVha319cmV0dXJuIHd9cmV0dXJuIGZ1bmN0aW9uKG0sZz1udWxsLGI9ITEpe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksbS5pc0V4dGVuZGVkVHJpYW5nbGU/bS5uZWVkc1VwZGF0ZSYmbS51cGRhdGUoKTooaS5jb3B5KG0pLGkudXBkYXRlKCksbT1pKTtjb25zdCB3PXRoaXMucGxhbmUseD1tLnBsYW5lO2lmKE1hdGguYWJzKHcubm9ybWFsLmRvdCh4Lm5vcm1hbCkpPjEtMWUtMTApe2NvbnN0IE09dGhpcy5zYXRCb3VuZHMsQT10aGlzLnNhdEF4ZXM7ZVswXT1tLmEsZVsxXT1tLmIsZVsyXT1tLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1NW0VdLHY9QVtFXTtpZihuLnNldEZyb21Qb2ludHModixlKSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWNvbnN0IFM9bS5zYXRCb3VuZHMsXz1tLnNhdEF4ZXM7dFswXT10aGlzLmEsdFsxXT10aGlzLmIsdFsyXT10aGlzLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1TW0VdLHY9X1tFXTtpZihuLnNldEZyb21Qb2ludHModix0KSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWZvcihsZXQgRT0wO0U8NDtFKyspe2NvbnN0IHo9QVtFXTtmb3IobGV0IHY9MDt2PDQ7disrKXtjb25zdCBDPV9bdl07aWYoci5jcm9zc1ZlY3RvcnMoeixDKSxuLnNldEZyb21Qb2ludHMocix0KSxzLnNldEZyb21Qb2ludHMocixlKSxuLmlzU2VwYXJhdGVkKHMpKXJldHVybiExfX1yZXR1cm4gZyYmKGJ8fGNvbnNvbGUud2FybigiRXh0ZW5kZWRUcmlhbmdsZS5pbnRlcnNlY3RzVHJpYW5nbGU6IFRyaWFuZ2xlcyBhcmUgY29wbGFuYXIgd2hpY2ggZG9lcyBub3Qgc3VwcG9ydCBhbiBvdXRwdXQgZWRnZS4gU2V0dGluZyBlZGdlIHRvIDAsIDAsIDAuIiksZy5zdGFydC5zZXQoMCwwLDApLGcuZW5kLnNldCgwLDAsMCkpLCEwfWVsc2V7Y29uc3QgTT1wKHRoaXMseCx1KTtpZihNPT09MSYmbS5jb250YWluc1BvaW50KHUuZW5kKSlyZXR1cm4gZyYmKGcuc3RhcnQuY29weSh1LmVuZCksZy5lbmQuY29weSh1LmVuZCkpLCEwO2lmKE0hPT0yKXJldHVybiExO2NvbnN0IEE9cChtLHcsZik7aWYoQT09PTEmJnRoaXMuY29udGFpbnNQb2ludChmLmVuZCkpcmV0dXJuIGcmJihnLnN0YXJ0LmNvcHkoZi5lbmQpLGcuZW5kLmNvcHkoZi5lbmQpKSwhMDtpZihBIT09MilyZXR1cm4hMTtpZih1LmRlbHRhKGEpLGYuZGVsdGEoYyksYS5kb3QoYyk8MCl7bGV0IFA9Zi5zdGFydDtmLnN0YXJ0PWYuZW5kLGYuZW5kPVB9Y29uc3QgUz11LnN0YXJ0LmRvdChhKSxfPXUuZW5kLmRvdChhKSxFPWYuc3RhcnQuZG90KGEpLHo9Zi5lbmQuZG90KGEpLHY9XzxFLEM9Uzx6O3JldHVybiBTIT09eiYmRSE9PV8mJnY9PT1DPyExOihnJiYobC5zdWJWZWN0b3JzKHUuc3RhcnQsZi5zdGFydCksbC5kb3QoYSk+MD9nLnN0YXJ0LmNvcHkodS5zdGFydCk6Zy5zdGFydC5jb3B5KGYuc3RhcnQpLGwuc3ViVmVjdG9ycyh1LmVuZCxmLmVuZCksbC5kb3QoYSk8MD9nLmVuZC5jb3B5KHUuZW5kKTpnLmVuZC5jb3B5KGYuZW5kKSksITApfX19KCksbmUucHJvdG90eXBlLmRpc3RhbmNlVG9Qb2ludD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoZSxpKSxlLmRpc3RhbmNlVG8oaSl9fSgpLG5lLnByb3RvdHlwZS5kaXN0YW5jZVRvVHJpYW5nbGU9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1bImEiLCJiIiwiYyJdLG49bmV3IFF0LHM9bmV3IFF0O3JldHVybiBmdW5jdGlvbihvLGE9bnVsbCxjPW51bGwpe2NvbnN0IGw9YXx8Yz9uOm51bGw7aWYodGhpcy5pbnRlcnNlY3RzVHJpYW5nbGUobyxsKSlyZXR1cm4oYXx8YykmJihhJiZsLmdldENlbnRlcihhKSxjJiZsLmdldENlbnRlcihjKSksMDtsZXQgaD0xLzA7Zm9yKGxldCB1PTA7dTwzO3UrKyl7bGV0IGY7Y29uc3QgZD1lW3VdLHA9b1tkXTt0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocCxpKSxmPXAuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weShpKSxjJiZjLmNvcHkocCkpO2NvbnN0IHk9dGhpc1tkXTtvLmNsb3Nlc3RQb2ludFRvUG9pbnQoeSxpKSxmPXkuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weSh5KSxjJiZjLmNvcHkoaSkpfWZvcihsZXQgdT0wO3U8Mzt1Kyspe2NvbnN0IGY9ZVt1XSxkPWVbKHUrMSklM107bi5zZXQodGhpc1tmXSx0aGlzW2RdKTtmb3IobGV0IHA9MDtwPDM7cCsrKXtjb25zdCB5PWVbcF0sbT1lWyhwKzEpJTNdO3Muc2V0KG9beV0sb1ttXSksSG8obixzLGksdCk7Y29uc3QgZz1pLmRpc3RhbmNlVG9TcXVhcmVkKHQpO2c8aCYmKGg9ZyxhJiZhLmNvcHkoaSksYyYmYy5jb3B5KHQpKX19cmV0dXJuIE1hdGguc3FydChoKX19KCk7Y2xhc3MgenR7Y29uc3RydWN0b3IodCxlLG4pe3RoaXMuaXNPcmllbnRlZEJveD0hMCx0aGlzLm1pbj1uZXcgVCx0aGlzLm1heD1uZXcgVCx0aGlzLm1hdHJpeD1uZXcgc3QsdGhpcy5pbnZNYXRyaXg9bmV3IHN0LHRoaXMucG9pbnRzPW5ldyBBcnJheSg4KS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRBeGVzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRCb3VuZHM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBJZSksdGhpcy5hbGlnbmVkU2F0Qm91bmRzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgSWUpLHRoaXMubmVlZHNVcGRhdGU9ITEsdCYmdGhpcy5taW4uY29weSh0KSxlJiZ0aGlzLm1heC5jb3B5KGUpLG4mJnRoaXMubWF0cml4LmNvcHkobil9c2V0KHQsZSxuKXt0aGlzLm1pbi5jb3B5KHQpLHRoaXMubWF4LmNvcHkoZSksdGhpcy5tYXRyaXguY29weShuKSx0aGlzLm5lZWRzVXBkYXRlPSEwfWNvcHkodCl7dGhpcy5taW4uY29weSh0Lm1pbiksdGhpcy5tYXguY29weSh0Lm1heCksdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5uZWVkc1VwZGF0ZT0hMH19enQucHJvdG90eXBlLnVwZGF0ZT1mdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbigpe2NvbnN0IHQ9dGhpcy5tYXRyaXgsZT10aGlzLm1pbixuPXRoaXMubWF4LHM9dGhpcy5wb2ludHM7Zm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspZm9yKGxldCB1PTA7dTw9MTt1Kyspe2NvbnN0IGY9MSpsfDIqaHw0KnUsZD1zW2ZdO2QueD1sP24ueDplLngsZC55PWg/bi55OmUueSxkLno9dT9uLno6ZS56LGQuYXBwbHlNYXRyaXg0KHQpfWNvbnN0IHI9dGhpcy5zYXRCb3VuZHMsbz10aGlzLnNhdEF4ZXMsYT1zWzBdO2ZvcihsZXQgbD0wO2w8MztsKyspe2NvbnN0IGg9b1tsXSx1PXJbbF0sZj0xPDxsLGQ9c1tmXTtoLnN1YlZlY3RvcnMoYSxkKSx1LnNldEZyb21Qb2ludHMoaCxzKX1jb25zdCBjPXRoaXMuYWxpZ25lZFNhdEJvdW5kcztjWzBdLnNldEZyb21Qb2ludHNGaWVsZChzLCJ4IiksY1sxXS5zZXRGcm9tUG9pbnRzRmllbGQocywieSIpLGNbMl0uc2V0RnJvbVBvaW50c0ZpZWxkKHMsInoiKSx0aGlzLmludk1hdHJpeC5jb3B5KHRoaXMubWF0cml4KS5pbnZlcnQoKSx0aGlzLm5lZWRzVXBkYXRlPSExfX0oKSx6dC5wcm90b3R5cGUuaW50ZXJzZWN0c0JveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IEllO3JldHVybiBmdW5jdGlvbihlKXt0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpO2NvbnN0IG49ZS5taW4scz1lLm1heCxyPXRoaXMuc2F0Qm91bmRzLG89dGhpcy5zYXRBeGVzLGE9dGhpcy5hbGlnbmVkU2F0Qm91bmRzO2lmKGkubWluPW4ueCxpLm1heD1zLngsYVswXS5pc1NlcGFyYXRlZChpKXx8KGkubWluPW4ueSxpLm1heD1zLnksYVsxXS5pc1NlcGFyYXRlZChpKSl8fChpLm1pbj1uLnosaS5tYXg9cy56LGFbMl0uaXNTZXBhcmF0ZWQoaSkpKXJldHVybiExO2ZvcihsZXQgYz0wO2M8MztjKyspe2NvbnN0IGw9b1tjXSxoPXJbY107aWYoaS5zZXRGcm9tQm94KGwsZSksaC5pc1NlcGFyYXRlZChpKSlyZXR1cm4hMX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmludGVyc2VjdHNUcmlhbmdsZT1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IG5lLHQ9bmV3IEFycmF5KDMpLGU9bmV3IEllLG49bmV3IEllLHM9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKG8pe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksby5pc0V4dGVuZGVkVHJpYW5nbGU/by5uZWVkc1VwZGF0ZSYmby51cGRhdGUoKTooaS5jb3B5KG8pLGkudXBkYXRlKCksbz1pKTtjb25zdCBhPXRoaXMuc2F0Qm91bmRzLGM9dGhpcy5zYXRBeGVzO3RbMF09by5hLHRbMV09by5iLHRbMl09by5jO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9YVtmXSxwPWNbZl07aWYoZS5zZXRGcm9tUG9pbnRzKHAsdCksZC5pc1NlcGFyYXRlZChlKSlyZXR1cm4hMX1jb25zdCBsPW8uc2F0Qm91bmRzLGg9by5zYXRBeGVzLHU9dGhpcy5wb2ludHM7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1sW2ZdLHA9aFtmXTtpZihlLnNldEZyb21Qb2ludHMocCx1KSxkLmlzU2VwYXJhdGVkKGUpKXJldHVybiExfWZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9Y1tmXTtmb3IobGV0IHA9MDtwPDQ7cCsrKXtjb25zdCB5PWhbcF07aWYocy5jcm9zc1ZlY3RvcnMoZCx5KSxlLnNldEZyb21Qb2ludHMocyx0KSxuLnNldEZyb21Qb2ludHMocyx1KSxlLmlzU2VwYXJhdGVkKG4pKXJldHVybiExfX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFRvUG9pbnQ9ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxlLmNvcHkodCkuYXBwbHlNYXRyaXg0KHRoaXMuaW52TWF0cml4KS5jbGFtcCh0aGlzLm1pbix0aGlzLm1heCkuYXBwbHlNYXRyaXg0KHRoaXMubWF0cml4KSxlfX0oKSx6dC5wcm90b3R5cGUuZGlzdGFuY2VUb1BvaW50PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChlLGkpLGUuZGlzdGFuY2VUbyhpKX19KCksenQucHJvdG90eXBlLmRpc3RhbmNlVG9Cb3g9ZnVuY3Rpb24oKXtjb25zdCBpPVsieCIsInkiLCJ6Il0sdD1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksZT1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksbj1uZXcgVCxzPW5ldyBUO3JldHVybiBmdW5jdGlvbihvLGE9MCxjPW51bGwsbD1udWxsKXtpZih0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpLHRoaXMuaW50ZXJzZWN0c0JveChvKSlyZXR1cm4oY3x8bCkmJihvLmdldENlbnRlcihzKSx0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocyxuKSxvLmNsb3Nlc3RQb2ludFRvUG9pbnQobixzKSxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpKSwwO2NvbnN0IGg9YSphLHU9by5taW4sZj1vLm1heCxkPXRoaXMucG9pbnRzO2xldCBwPTEvMDtmb3IobGV0IG09MDttPDg7bSsrKXtjb25zdCBnPWRbbV07cy5jb3B5KGcpLmNsYW1wKHUsZik7Y29uc3QgYj1nLmRpc3RhbmNlVG9TcXVhcmVkKHMpO2lmKGI8cCYmKHA9YixjJiZjLmNvcHkoZyksbCYmbC5jb3B5KHMpLGI8aCkpcmV0dXJuIE1hdGguc3FydChiKX1sZXQgeT0wO2ZvcihsZXQgbT0wO208MzttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe2NvbnN0IHc9KG0rMSklMyx4PShtKzIpJTMsTT1nPDx3fGI8PHgsQT0xPDxtfGc8PHd8Yjw8eCxTPWRbTV0sXz1kW0FdO3RbeV0uc2V0KFMsXyk7Y29uc3Qgej1pW21dLHY9aVt3XSxDPWlbeF0sUD1lW3ldLEY9UC5zdGFydCxCPVAuZW5kO0Zbel09dVt6XSxGW3ZdPWc/dVt2XTpmW3ZdLEZbQ109Yj91W0NdOmZbdl0sQlt6XT1mW3pdLEJbdl09Zz91W3ZdOmZbdl0sQltDXT1iP3VbQ106Zlt2XSx5Kyt9Zm9yKGxldCBtPTA7bTw9MTttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe3MueD1tP2YueDp1Lngscy55PWc/Zi55OnUueSxzLno9Yj9mLno6dS56LHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChzLG4pO2NvbnN0IHc9cy5kaXN0YW5jZVRvU3F1YXJlZChuKTtpZih3PHAmJihwPXcsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx3PGgpKXJldHVybiBNYXRoLnNxcnQodyl9Zm9yKGxldCBtPTA7bTwxMjttKyspe2NvbnN0IGc9dFttXTtmb3IobGV0IGI9MDtiPDEyO2IrKyl7Y29uc3Qgdz1lW2JdO0hvKGcsdyxuLHMpO2NvbnN0IHg9bi5kaXN0YW5jZVRvU3F1YXJlZChzKTtpZih4PHAmJihwPXgsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx4PGgpKXJldHVybiBNYXRoLnNxcnQoeCl9fXJldHVybiBNYXRoLnNxcnQocCl9fSgpO2NsYXNzIEdve2NvbnN0cnVjdG9yKHQpe3RoaXMuX2dldE5ld1ByaW1pdGl2ZT10LHRoaXMuX3ByaW1pdGl2ZXM9W119Z2V0UHJpbWl0aXZlKCl7Y29uc3QgdD10aGlzLl9wcmltaXRpdmVzO3JldHVybiB0Lmxlbmd0aD09PTA/dGhpcy5fZ2V0TmV3UHJpbWl0aXZlKCk6dC5wb3AoKX1yZWxlYXNlUHJpbWl0aXZlKHQpe3RoaXMuX3ByaW1pdGl2ZXMucHVzaCh0KX19Y2xhc3MgQWQgZXh0ZW5kcyBHb3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCgpPT5uZXcgbmUpfX1jb25zdCBpZT1uZXcgQWQ7Y2xhc3MgU2R7Y29uc3RydWN0b3IoKXt0aGlzLmZsb2F0MzJBcnJheT1udWxsLHRoaXMudWludDE2QXJyYXk9bnVsbCx0aGlzLnVpbnQzMkFycmF5PW51bGw7Y29uc3QgdD1bXTtsZXQgZT1udWxsO3RoaXMuc2V0QnVmZmVyPW49PntlJiZ0LnB1c2goZSksZT1uLHRoaXMuZmxvYXQzMkFycmF5PW5ldyBGbG9hdDMyQXJyYXkobiksdGhpcy51aW50MTZBcnJheT1uZXcgVWludDE2QXJyYXkobiksdGhpcy51aW50MzJBcnJheT1uZXcgVWludDMyQXJyYXkobil9LHRoaXMuY2xlYXJCdWZmZXI9KCk9PntlPW51bGwsdGhpcy5mbG9hdDMyQXJyYXk9bnVsbCx0aGlzLnVpbnQxNkFycmF5PW51bGwsdGhpcy51aW50MzJBcnJheT1udWxsLHQubGVuZ3RoIT09MCYmdGhpcy5zZXRCdWZmZXIodC5wb3AoKSl9fX1jb25zdCBudD1uZXcgU2Q7bGV0IHRuLFhuO2NvbnN0IEpuPVtdLElzPW5ldyBHbygoKT0+bmV3IGd0KTtmdW5jdGlvbiBfZChpLHQsZSxuLHMscil7dG49SXMuZ2V0UHJpbWl0aXZlKCksWG49SXMuZ2V0UHJpbWl0aXZlKCksSm4ucHVzaCh0bixYbiksbnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPVpvKDAsaS5nZW9tZXRyeSxlLG4scyxyKTtudC5jbGVhckJ1ZmZlcigpLElzLnJlbGVhc2VQcmltaXRpdmUodG4pLElzLnJlbGVhc2VQcmltaXRpdmUoWG4pLEpuLnBvcCgpLEpuLnBvcCgpO2NvbnN0IGE9Sm4ubGVuZ3RoO3JldHVybiBhPjAmJihYbj1KblthLTFdLHRuPUpuW2EtMl0pLG99ZnVuY3Rpb24gWm8oaSx0LGUsbixzPW51bGwscj0wLG89MCl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udDtsZXQgaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1VdChpLGwpLGQ9S3QoaCxjKTtyZXR1cm4gbHQoaSxhLHRuKSxuKGYsZCwhMSxvLHIraSx0bil9ZWxzZXtsZXQgej1mdW5jdGlvbihDKXtjb25zdHt1aW50MTZBcnJheTpQLHVpbnQzMkFycmF5OkZ9PW50O2xldCBCPUMqMjtmb3IoOyFrdChCLFApOylDPXRlKEMpLEI9QyoyO3JldHVybiBVdChDLEYpfSx2PWZ1bmN0aW9uKEMpe2NvbnN0e3VpbnQxNkFycmF5OlAsdWludDMyQXJyYXk6Rn09bnQ7bGV0IEI9QyoyO2Zvcig7IWt0KEIsUCk7KUM9ZWUoQyxGKSxCPUMqMjtyZXR1cm4gVXQoQyxGKStLdChCLFApfTtjb25zdCBmPXRlKGkpLGQ9ZWUoaSxsKTtsZXQgcD1mLHk9ZCxtLGcsYix3O2lmKHMmJihiPXRuLHc9WG4sbHQocCxhLGIpLGx0KHksYSx3KSxtPXMoYiksZz1zKHcpLGc8bSkpe3A9ZCx5PWY7Y29uc3QgQz1tO209ZyxnPUMsYj13fWJ8fChiPXRuLGx0KHAsYSxiKSk7Y29uc3QgeD1rdChwKjIsYyksTT1lKGIseCxtLG8rMSxyK3ApO2xldCBBO2lmKE09PT1zbCl7Y29uc3QgQz16KHApLEY9dihwKS1DO0E9bihDLEYsITAsbysxLHIrcCxiKX1lbHNlIEE9TSYmWm8ocCx0LGUsbixzLHIsbysxKTtpZihBKXJldHVybiEwO3c9WG4sbHQoeSxhLHcpO2NvbnN0IFM9a3QoeSoyLGMpLF89ZSh3LFMsZyxvKzEscit5KTtsZXQgRTtpZihfPT09c2wpe2NvbnN0IEM9eih5KSxGPXYoeSktQztFPW4oQyxGLCEwLG8rMSxyK3ksdyl9ZWxzZSBFPV8mJlpvKHksdCxlLG4scyxyLG8rMSk7cmV0dXJuISFFfX1jb25zdCBGaT1uZXcgVCxYbz1uZXcgVDtmdW5jdGlvbiB2ZChpLHQsZT17fSxuPTAscz0xLzApe2NvbnN0IHI9bipuLG89cypzO2xldCBhPTEvMCxjPW51bGw7aWYoaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6aD0+KEZpLmNvcHkodCkuY2xhbXAoaC5taW4saC5tYXgpLEZpLmRpc3RhbmNlVG9TcXVhcmVkKHQpKSxpbnRlcnNlY3RzQm91bmRzOihoLHUsZik9PmY8YSYmZjxvLGludGVyc2VjdHNUcmlhbmdsZTooaCx1KT0+e2guY2xvc2VzdFBvaW50VG9Qb2ludCh0LEZpKTtjb25zdCBmPXQuZGlzdGFuY2VUb1NxdWFyZWQoRmkpO3JldHVybiBmPGEmJihYby5jb3B5KEZpKSxhPWYsYz11KSxmPHJ9fSksYT09PTEvMClyZXR1cm4gbnVsbDtjb25zdCBsPU1hdGguc3FydChhKTtyZXR1cm4gZS5wb2ludD9lLnBvaW50LmNvcHkoWG8pOmUucG9pbnQ9WG8uY2xvbmUoKSxlLmRpc3RhbmNlPWwsZS5mYWNlSW5kZXg9YyxlfWNvbnN0IHpkPXBhcnNlSW50KEopPj0xNjkseW49bmV3IFQsbW49bmV3IFQsZ249bmV3IFQsa3M9bmV3IFIsTnM9bmV3IFIsUnM9bmV3IFIscGw9bmV3IFQseWw9bmV3IFQsbWw9bmV3IFQsSWk9bmV3IFQ7ZnVuY3Rpb24gVGQoaSx0LGUsbixzLHIsbyxhKXtsZXQgYztpZihyPT09MT9jPWkuaW50ZXJzZWN0VHJpYW5nbGUobixlLHQsITAscyk6Yz1pLmludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHIhPT0yLHMpLGM9PT1udWxsKXJldHVybiBudWxsO2NvbnN0IGw9aS5vcmlnaW4uZGlzdGFuY2VUbyhzKTtyZXR1cm4gbDxvfHxsPmE/bnVsbDp7ZGlzdGFuY2U6bCxwb2ludDpzLmNsb25lKCl9fWZ1bmN0aW9uIEVkKGksdCxlLG4scyxyLG8sYSxjLGwsaCl7eW4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LHIpLG1uLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxvKSxnbi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsYSk7Y29uc3QgdT1UZChpLHluLG1uLGduLElpLGMsbCxoKTtpZih1KXtjb25zdCBmPW5ldyBUO2V0LmdldEJhcnljb29yZChJaSx5bixtbixnbixmKSxuJiYoa3MuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHIpLE5zLmZyb21CdWZmZXJBdHRyaWJ1dGUobixvKSxScy5mcm9tQnVmZmVyQXR0cmlidXRlKG4sYSksdS51dj1ldC5nZXRJbnRlcnBvbGF0aW9uKElpLHluLG1uLGduLGtzLE5zLFJzLG5ldyBSKSkscyYmKGtzLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxyKSxOcy5mcm9tQnVmZmVyQXR0cmlidXRlKHMsbyksUnMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLGEpLHUudXYxPWV0LmdldEludGVycG9sYXRpb24oSWkseW4sbW4sZ24sa3MsTnMsUnMsbmV3IFIpKSxlJiYocGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHIpLHlsLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxvKSxtbC5mcm9tQnVmZmVyQXR0cmlidXRlKGUsYSksdS5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGlvbihJaSx5bixtbixnbixwbCx5bCxtbCxuZXcgVCksdS5ub3JtYWwuZG90KGkuZGlyZWN0aW9uKT4wJiZ1Lm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGQ9e2E6cixiOm8sYzphLG5vcm1hbDpuZXcgVCxtYXRlcmlhbEluZGV4OjB9O2V0LmdldE5vcm1hbCh5bixtbixnbixkLm5vcm1hbCksdS5mYWNlPWQsdS5mYWNlSW5kZXg9cix6ZCYmKHUuYmFyeWNvb3JkPWYpfXJldHVybiB1fWZ1bmN0aW9uIExzKGksdCxlLG4scyxyLG8pe2NvbnN0IGE9biozO2xldCBjPWErMCxsPWErMSxoPWErMjtjb25zdCB1PWkuaW5kZXg7aS5pbmRleCYmKGM9dS5nZXRYKGMpLGw9dS5nZXRYKGwpLGg9dS5nZXRYKGgpKTtjb25zdHtwb3NpdGlvbjpmLG5vcm1hbDpkLHV2OnAsdXYxOnl9PWkuYXR0cmlidXRlcyxtPUVkKGUsZixkLHAseSxjLGwsaCx0LHIsbyk7cmV0dXJuIG0/KG0uZmFjZUluZGV4PW4scyYmcy5wdXNoKG0pLG0pOm51bGx9ZnVuY3Rpb24geXQoaSx0LGUsbil7Y29uc3Qgcz1pLmEscj1pLmIsbz1pLmM7bGV0IGE9dCxjPXQrMSxsPXQrMjtlJiYoYT1lLmdldFgoYSksYz1lLmdldFgoYyksbD1lLmdldFgobCkpLHMueD1uLmdldFgoYSkscy55PW4uZ2V0WShhKSxzLno9bi5nZXRaKGEpLHIueD1uLmdldFgoYyksci55PW4uZ2V0WShjKSxyLno9bi5nZXRaKGMpLG8ueD1uLmdldFgobCksby55PW4uZ2V0WShsKSxvLno9bi5nZXRaKGwpfWZ1bmN0aW9uIFBkKGksdCxlLG4scyxyLG8sYSl7Y29uc3R7Z2VvbWV0cnk6YyxfaW5kaXJlY3RCdWZmZXI6bH09aTtmb3IobGV0IGg9bix1PW4rcztoPHU7aCsrKUxzKGMsdCxlLGgscixvLGEpfWZ1bmN0aW9uIENkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmEsX2luZGlyZWN0QnVmZmVyOmN9PWk7bGV0IGw9MS8wLGg9bnVsbDtmb3IobGV0IHU9bixmPW4rczt1PGY7dSsrKXtsZXQgZDtkPUxzKGEsdCxlLHUsbnVsbCxyLG8pLGQmJmQuZGlzdGFuY2U8bCYmKGg9ZCxsPWQuZGlzdGFuY2UpfXJldHVybiBofWZ1bmN0aW9uIEJkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmF9PWUse2luZGV4OmN9PWEsbD1hLmF0dHJpYnV0ZXMucG9zaXRpb247Zm9yKGxldCBoPWksdT10K2k7aDx1O2grKyl7bGV0IGY7aWYoZj1oLHl0KG8sZiozLGMsbCksby5uZWVkc1VwZGF0ZT0hMCxuKG8sZixzLHIpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIEZkKGksdD1udWxsKXt0JiZBcnJheS5pc0FycmF5KHQpJiYodD1uZXcgU2V0KHQpKTtjb25zdCBlPWkuZ2VvbWV0cnksbj1lLmluZGV4P2UuaW5kZXguYXJyYXk6bnVsbCxzPWUuYXR0cmlidXRlcy5wb3NpdGlvbjtsZXQgcixvLGEsYyxsPTA7Y29uc3QgaD1pLl9yb290cztmb3IobGV0IGY9MCxkPWgubGVuZ3RoO2Y8ZDtmKyspcj1oW2ZdLG89bmV3IFVpbnQzMkFycmF5KHIpLGE9bmV3IFVpbnQxNkFycmF5KHIpLGM9bmV3IEZsb2F0MzJBcnJheShyKSx1KDAsbCksbCs9ci5ieXRlTGVuZ3RoO2Z1bmN0aW9uIHUoZixkLHA9ITEpe2NvbnN0IHk9ZioyO2lmKGFbeSsxNV09PT1Qcyl7Y29uc3QgZz1vW2YrNl0sYj1hW3krMTRdO2xldCB3PTEvMCx4PTEvMCxNPTEvMCxBPS0xLzAsUz0tMS8wLF89LTEvMDtmb3IobGV0IEU9MypnLHo9MyooZytiKTtFPHo7RSsrKXtsZXQgdj1uW0VdO2NvbnN0IEM9cy5nZXRYKHYpLFA9cy5nZXRZKHYpLEY9cy5nZXRaKHYpO0M8dyYmKHc9QyksQz5BJiYoQT1DKSxQPHgmJih4PVApLFA+UyYmKFM9UCksRjxNJiYoTT1GKSxGPl8mJihfPUYpfXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1TfHxjW2YrNV0hPT1fPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09UyxjW2YrNV09XywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsUz0hMTt0P018fChBPXQuaGFzKHcpLFM9dC5oYXMoeCksTT0hQSYmIVMpOihBPSEwLFM9ITApO2NvbnN0IF89TXx8QSxFPU18fFM7bGV0IHo9ITE7XyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFU9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+VT9rOlV9cmV0dXJuIEN9fX1mdW5jdGlvbiBlbihpLHQsZSxuLHMpe2xldCByLG8sYSxjLGwsaDtjb25zdCB1PTEvZS5kaXJlY3Rpb24ueCxmPTEvZS5kaXJlY3Rpb24ueSxkPTEvZS5kaXJlY3Rpb24ueixwPWUub3JpZ2luLngseT1lLm9yaWdpbi55LG09ZS5vcmlnaW4uejtsZXQgZz10W2ldLGI9dFtpKzNdLHc9dFtpKzFdLHg9dFtpKzMrMV0sTT10W2krMl0sQT10W2krMysyXTtyZXR1cm4gdT49MD8ocj0oZy1wKSp1LG89KGItcCkqdSk6KHI9KGItcCkqdSxvPShnLXApKnUpLGY+PTA/KGE9KHcteSkqZixjPSh4LXkpKmYpOihhPSh4LXkpKmYsYz0ody15KSpmKSxyPmN8fGE+b3x8KChhPnJ8fGlzTmFOKHIpKSYmKHI9YSksKGM8b3x8aXNOYU4obykpJiYobz1jKSxkPj0wPyhsPShNLW0pKmQsaD0oQS1tKSpkKToobD0oQS1tKSpkLGg9KE0tbSkqZCkscj5ofHxsPm8pPyExOigobD5yfHxyIT09cikmJihyPWwpLChoPG98fG8hPT1vKSYmKG89aCkscjw9cyYmbz49bil9ZnVuY3Rpb24gSWQoaSx0LGUsbixzLHIsbyxhKXtjb25zdHtnZW9tZXRyeTpjLF9pbmRpcmVjdEJ1ZmZlcjpsfT1pO2ZvcihsZXQgaD1uLHU9bitzO2g8dTtoKyspe2xldCBmPWw/bFtoXTpoO0xzKGMsdCxlLGYscixvLGEpfX1mdW5jdGlvbiBrZChpLHQsZSxuLHMscixvKXtjb25zdHtnZW9tZXRyeTphLF9pbmRpcmVjdEJ1ZmZlcjpjfT1pO2xldCBsPTEvMCxoPW51bGw7Zm9yKGxldCB1PW4sZj1uK3M7dTxmO3UrKyl7bGV0IGQ7ZD1McyhhLHQsZSxjP2NbdV06dSxudWxsLHIsbyksZCYmZC5kaXN0YW5jZTxsJiYoaD1kLGw9ZC5kaXN0YW5jZSl9cmV0dXJuIGh9ZnVuY3Rpb24gTmQoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YX09ZSx7aW5kZXg6Y309YSxsPWEuYXR0cmlidXRlcy5wb3NpdGlvbjtmb3IobGV0IGg9aSx1PXQraTtoPHU7aCsrKXtsZXQgZjtpZihmPWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoaCkseXQobyxmKjMsYyxsKSxvLm5lZWRzVXBkYXRlPSEwLG4obyxmLHMscikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gUmQoaSx0LGUsbixzLHIsbyl7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKSxKbygwLGksZSxuLHMscixvKSxudC5jbGVhckJ1ZmZlcigpfWZ1bmN0aW9uIEpvKGksdCxlLG4scyxyLG8pe2NvbnN0e2Zsb2F0MzJBcnJheTphLHVpbnQxNkFycmF5OmMsdWludDMyQXJyYXk6bH09bnQsaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1VdChpLGwpLGQ9S3QoaCxjKTtQZCh0LGUsbixmLGQscyxyLG8pfWVsc2V7Y29uc3QgZj10ZShpKTtlbihmLGEsbixyLG8pJiZKbyhmLHQsZSxuLHMscixvKTtjb25zdCBkPWVlKGksbCk7ZW4oZCxhLG4scixvKSYmSm8oZCx0LGUsbixzLHIsbyl9fWNvbnN0IExkPVsieCIsInkiLCJ6Il07ZnVuY3Rpb24gT2QoaSx0LGUsbixzLHIpe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSk7Y29uc3Qgbz1ZbygwLGksZSxuLHMscik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksb31mdW5jdGlvbiBZbyhpLHQsZSxuLHMscil7Y29uc3R7ZmxvYXQzMkFycmF5Om8sdWludDE2QXJyYXk6YSx1aW50MzJBcnJheTpjfT1udDtsZXQgbD1pKjI7aWYoa3QobCxhKSl7Y29uc3QgdT1VdChpLGMpLGY9S3QobCxhKTtyZXR1cm4gQ2QodCxlLG4sdSxmLHMscil9ZWxzZXtjb25zdCB1PXVsKGksYyksZj1MZFt1XSxwPW4uZGlyZWN0aW9uW2ZdPj0wO2xldCB5LG07cD8oeT10ZShpKSxtPWVlKGksYykpOih5PWVlKGksYyksbT10ZShpKSk7Y29uc3QgYj1lbih5LG8sbixzLHIpP1lvKHksdCxlLG4scyxyKTpudWxsO2lmKGIpe2NvbnN0IE09Yi5wb2ludFtmXTtpZihwP008PW9bbSt1XTpNPj1vW20rdSszXSlyZXR1cm4gYn1jb25zdCB4PWVuKG0sbyxuLHMscik/WW8obSx0LGUsbixzLHIpOm51bGw7cmV0dXJuIGImJng/Yi5kaXN0YW5jZTw9eC5kaXN0YW5jZT9iOng6Ynx8eHx8bnVsbH19Y29uc3QgT3M9bmV3IGd0LFluPW5ldyBuZSxqbj1uZXcgbmUsa2k9bmV3IHN0LGdsPW5ldyB6dCxEcz1uZXcgenQ7ZnVuY3Rpb24gRGQoaSx0LGUsbil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBzPWpvKDAsaSxlLG4pO3JldHVybiBudC5jbGVhckJ1ZmZlcigpLHN9ZnVuY3Rpb24gam8oaSx0LGUsbixzPW51bGwpe2NvbnN0e2Zsb2F0MzJBcnJheTpyLHVpbnQxNkFycmF5Om8sdWludDMyQXJyYXk6YX09bnQ7bGV0IGM9aSoyO2lmKHM9PT1udWxsJiYoZS5ib3VuZGluZ0JveHx8ZS5jb21wdXRlQm91bmRpbmdCb3goKSxnbC5zZXQoZS5ib3VuZGluZ0JveC5taW4sZS5ib3VuZGluZ0JveC5tYXgsbikscz1nbCksa3QoYyxvKSl7Y29uc3QgaD10Lmdlb21ldHJ5LHU9aC5pbmRleCxmPWguYXR0cmlidXRlcy5wb3NpdGlvbixkPWUuaW5kZXgscD1lLmF0dHJpYnV0ZXMucG9zaXRpb24seT1VdChpLGEpLG09S3QoYyxvKTtpZihraS5jb3B5KG4pLmludmVydCgpLGUuYm91bmRzVHJlZSlyZXR1cm4gbHQoaSxyLERzKSxEcy5tYXRyaXguY29weShraSksRHMubmVlZHNVcGRhdGU9ITAsZS5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpiPT5Ecy5pbnRlcnNlY3RzQm94KGIpLGludGVyc2VjdHNUcmlhbmdsZTpiPT57Yi5hLmFwcGx5TWF0cml4NChuKSxiLmIuYXBwbHlNYXRyaXg0KG4pLGIuYy5hcHBseU1hdHJpeDQobiksYi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHc9eSozLHg9KG0reSkqMzt3PHg7dys9MylpZih5dChqbix3LHUsZiksam4ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoam4pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15KjMsYj0obSt5KSozO2c8YjtnKz0zKXt5dChZbixnLHUsZiksWW4uYS5hcHBseU1hdHJpeDQoa2kpLFluLmIuYXBwbHlNYXRyaXg0KGtpKSxZbi5jLmFwcGx5TWF0cml4NChraSksWW4ubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB3PTAseD1kLmNvdW50O3c8eDt3Kz0zKWlmKHl0KGpuLHcsZCxwKSxqbi5uZWVkc1VwZGF0ZT0hMCxZbi5pbnRlcnNlY3RzVHJpYW5nbGUoam4pKXJldHVybiEwfX1lbHNle2NvbnN0IGg9aSs4LHU9YVtpKzZdO3JldHVybiBsdChoLHIsT3MpLCEhKHMuaW50ZXJzZWN0c0JveChPcykmJmpvKGgsdCxlLG4scyl8fChsdCh1LHIsT3MpLHMuaW50ZXJzZWN0c0JveChPcykmJmpvKHUsdCxlLG4scykpKX19Y29uc3QgJHM9bmV3IHN0LFFvPW5ldyB6dCxOaT1uZXcgenQsJGQ9bmV3IFQsVmQ9bmV3IFQsVWQ9bmV3IFQscWQ9bmV3IFQ7ZnVuY3Rpb24gSGQoaSx0LGUsbj17fSxzPXt9LHI9MCxvPTEvMCl7dC5ib3VuZGluZ0JveHx8dC5jb21wdXRlQm91bmRpbmdCb3goKSxRby5zZXQodC5ib3VuZGluZ0JveC5taW4sdC5ib3VuZGluZ0JveC5tYXgsZSksUW8ubmVlZHNVcGRhdGU9ITA7Y29uc3QgYT1pLmdlb21ldHJ5LGM9YS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9YS5pbmRleCxoPXQuYXR0cmlidXRlcy5wb3NpdGlvbix1PXQuaW5kZXgsZj1pZS5nZXRQcmltaXRpdmUoKSxkPWllLmdldFByaW1pdGl2ZSgpO2xldCBwPSRkLHk9VmQsbT1udWxsLGc9bnVsbDtzJiYobT1VZCxnPXFkKTtsZXQgYj0xLzAsdz1udWxsLHg9bnVsbDtyZXR1cm4gJHMuY29weShlKS5pbnZlcnQoKSxOaS5tYXRyaXguY29weSgkcyksaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6TT0+UW8uZGlzdGFuY2VUb0JveChNKSxpbnRlcnNlY3RzQm91bmRzOihNLEEsUyk9PlM8YiYmUzxvPyhBJiYoTmkubWluLmNvcHkoTS5taW4pLE5pLm1heC5jb3B5KE0ubWF4KSxOaS5uZWVkc1VwZGF0ZT0hMCksITApOiExLGludGVyc2VjdHNSYW5nZTooTSxBKT0+e2lmKHQuYm91bmRzVHJlZSlyZXR1cm4gdC5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpfPT5OaS5kaXN0YW5jZVRvQm94KF8pLGludGVyc2VjdHNCb3VuZHM6KF8sRSx6KT0+ejxiJiZ6PG8saW50ZXJzZWN0c1JhbmdlOihfLEUpPT57Zm9yKGxldCB6PV8sdj1fK0U7ejx2O3orKyl7eXQoZCwzKnosdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgQz1NLFA9TStBO0M8UDtDKyspe3l0KGYsMypDLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBGPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihGPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Rix3PUMseD16KSxGPHIpcmV0dXJuITB9fX19KTt7Y29uc3QgUz1abih0KTtmb3IobGV0IF89MCxFPVM7XzxFO18rKyl7eXQoZCwzKl8sdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgej1NLHY9TStBO3o8djt6Kyspe3l0KGYsMyp6LGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBDPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihDPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Qyx3PXoseD1fKSxDPHIpcmV0dXJuITB9fX19fSksaWUucmVsZWFzZVByaW1pdGl2ZShmKSxpZS5yZWxlYXNlUHJpbWl0aXZlKGQpLGI9PT0xLzA/bnVsbDoobi5wb2ludD9uLnBvaW50LmNvcHkoeSk6bi5wb2ludD15LmNsb25lKCksbi5kaXN0YW5jZT1iLG4uZmFjZUluZGV4PXcscyYmKHMucG9pbnQ/cy5wb2ludC5jb3B5KGcpOnMucG9pbnQ9Zy5jbG9uZSgpLHMucG9pbnQuYXBwbHlNYXRyaXg0KCRzKSx5LmFwcGx5TWF0cml4NCgkcykscy5kaXN0YW5jZT15LnN1YihzLnBvaW50KS5sZW5ndGgoKSxzLmZhY2VJbmRleD14KSxuKX1mdW5jdGlvbiBXZChpLHQ9bnVsbCl7dCYmQXJyYXkuaXNBcnJheSh0KSYmKHQ9bmV3IFNldCh0KSk7Y29uc3QgZT1pLmdlb21ldHJ5LG49ZS5pbmRleD9lLmluZGV4LmFycmF5Om51bGwscz1lLmF0dHJpYnV0ZXMucG9zaXRpb247bGV0IHIsbyxhLGMsbD0wO2NvbnN0IGg9aS5fcm9vdHM7Zm9yKGxldCBmPTAsZD1oLmxlbmd0aDtmPGQ7ZisrKXI9aFtmXSxvPW5ldyBVaW50MzJBcnJheShyKSxhPW5ldyBVaW50MTZBcnJheShyKSxjPW5ldyBGbG9hdDMyQXJyYXkociksdSgwLGwpLGwrPXIuYnl0ZUxlbmd0aDtmdW5jdGlvbiB1KGYsZCxwPSExKXtjb25zdCB5PWYqMjtpZihhW3krMTVdPT09UHMpe2NvbnN0IGc9b1tmKzZdLGI9YVt5KzE0XTtsZXQgdz0xLzAseD0xLzAsTT0xLzAsQT0tMS8wLFM9LTEvMCxfPS0xLzA7Zm9yKGxldCBFPWcsej1nK2I7RTx6O0UrKyl7Y29uc3Qgdj0zKmkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoRSk7Zm9yKGxldCBDPTA7QzwzO0MrKyl7bGV0IFA9ditDO1A9bj9uW1BdOlA7Y29uc3QgRj1zLmdldFgoUCksQj1zLmdldFkoUCksST1zLmdldFooUCk7Rjx3JiYodz1GKSxGPkEmJihBPUYpLEI8eCYmKHg9QiksQj5TJiYoUz1CKSxJPE0mJihNPUkpLEk+XyYmKF89SSl9fXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1TfHxjW2YrNV0hPT1fPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09UyxjW2YrNV09XywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsUz0hMTt0P018fChBPXQuaGFzKHcpLFM9dC5oYXMoeCksTT0hQSYmIVMpOihBPSEwLFM9ITApO2NvbnN0IF89TXx8QSxFPU18fFM7bGV0IHo9ITE7XyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFU9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+VT9rOlV9cmV0dXJuIEN9fX1mdW5jdGlvbiBHZChpLHQsZSxuLHMscixvKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pLEtvKDAsaSxlLG4scyxyLG8pLG50LmNsZWFyQnVmZmVyKCl9ZnVuY3Rpb24gS28oaSx0LGUsbixzLHIsbyl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udCxoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVV0KGksbCksZD1LdChoLGMpO0lkKHQsZSxuLGYsZCxzLHIsbyl9ZWxzZXtjb25zdCBmPXRlKGkpO2VuKGYsYSxuLHIsbykmJktvKGYsdCxlLG4scyxyLG8pO2NvbnN0IGQ9ZWUoaSxsKTtlbihkLGEsbixyLG8pJiZLbyhkLHQsZSxuLHMscixvKX19Y29uc3QgWmQ9WyJ4IiwieSIsInoiXTtmdW5jdGlvbiBYZChpLHQsZSxuLHMscil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPXRhKDAsaSxlLG4scyxyKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxvfWZ1bmN0aW9uIHRhKGksdCxlLG4scyxyKXtjb25zdHtmbG9hdDMyQXJyYXk6byx1aW50MTZBcnJheTphLHVpbnQzMkFycmF5OmN9PW50O2xldCBsPWkqMjtpZihrdChsLGEpKXtjb25zdCB1PVV0KGksYyksZj1LdChsLGEpO3JldHVybiBrZCh0LGUsbix1LGYscyxyKX1lbHNle2NvbnN0IHU9dWwoaSxjKSxmPVpkW3VdLHA9bi5kaXJlY3Rpb25bZl0+PTA7bGV0IHksbTtwPyh5PXRlKGkpLG09ZWUoaSxjKSk6KHk9ZWUoaSxjKSxtPXRlKGkpKTtjb25zdCBiPWVuKHksbyxuLHMscik/dGEoeSx0LGUsbixzLHIpOm51bGw7aWYoYil7Y29uc3QgTT1iLnBvaW50W2ZdO2lmKHA/TTw9b1ttK3VdOk0+PW9bbSt1KzNdKXJldHVybiBifWNvbnN0IHg9ZW4obSxvLG4scyxyKT90YShtLHQsZSxuLHMscik6bnVsbDtyZXR1cm4gYiYmeD9iLmRpc3RhbmNlPD14LmRpc3RhbmNlP2I6eDpifHx4fHxudWxsfX1jb25zdCBWcz1uZXcgZ3QsUW49bmV3IG5lLEtuPW5ldyBuZSxSaT1uZXcgc3QseGw9bmV3IHp0LFVzPW5ldyB6dDtmdW5jdGlvbiBKZChpLHQsZSxuKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IHM9ZWEoMCxpLGUsbik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksc31mdW5jdGlvbiBlYShpLHQsZSxuLHM9bnVsbCl7Y29uc3R7ZmxvYXQzMkFycmF5OnIsdWludDE2QXJyYXk6byx1aW50MzJBcnJheTphfT1udDtsZXQgYz1pKjI7aWYocz09PW51bGwmJihlLmJvdW5kaW5nQm94fHxlLmNvbXB1dGVCb3VuZGluZ0JveCgpLHhsLnNldChlLmJvdW5kaW5nQm94Lm1pbixlLmJvdW5kaW5nQm94Lm1heCxuKSxzPXhsKSxrdChjLG8pKXtjb25zdCBoPXQuZ2VvbWV0cnksdT1oLmluZGV4LGY9aC5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9ZS5pbmRleCxwPWUuYXR0cmlidXRlcy5wb3NpdGlvbix5PVV0KGksYSksbT1LdChjLG8pO2lmKFJpLmNvcHkobikuaW52ZXJ0KCksZS5ib3VuZHNUcmVlKXJldHVybiBsdChpLHIsVXMpLFVzLm1hdHJpeC5jb3B5KFJpKSxVcy5uZWVkc1VwZGF0ZT0hMCxlLmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmI9PlVzLmludGVyc2VjdHNCb3goYiksaW50ZXJzZWN0c1RyaWFuZ2xlOmI9PntiLmEuYXBwbHlNYXRyaXg0KG4pLGIuYi5hcHBseU1hdHJpeDQobiksYi5jLmFwcGx5TWF0cml4NChuKSxiLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgdz15LHg9bSt5O3c8eDt3KyspaWYoeXQoS24sMyp0LnJlc29sdmVUcmlhbmdsZUluZGV4KHcpLHUsZiksS24ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoS24pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15LGI9bSt5O2c8YjtnKyspe2NvbnN0IHc9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChnKTt5dChRbiwzKncsdSxmKSxRbi5hLmFwcGx5TWF0cml4NChSaSksUW4uYi5hcHBseU1hdHJpeDQoUmkpLFFuLmMuYXBwbHlNYXRyaXg0KFJpKSxRbi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHg9MCxNPWQuY291bnQ7eDxNO3grPTMpaWYoeXQoS24seCxkLHApLEtuLm5lZWRzVXBkYXRlPSEwLFFuLmludGVyc2VjdHNUcmlhbmdsZShLbikpcmV0dXJuITB9fWVsc2V7Y29uc3QgaD1pKzgsdT1hW2krNl07cmV0dXJuIGx0KGgscixWcyksISEocy5pbnRlcnNlY3RzQm94KFZzKSYmZWEoaCx0LGUsbixzKXx8KGx0KHUscixWcykscy5pbnRlcnNlY3RzQm94KFZzKSYmZWEodSx0LGUsbixzKSkpfX1jb25zdCBxcz1uZXcgc3QsbmE9bmV3IHp0LExpPW5ldyB6dCxZZD1uZXcgVCxqZD1uZXcgVCxRZD1uZXcgVCxLZD1uZXcgVDtmdW5jdGlvbiB0MChpLHQsZSxuPXt9LHM9e30scj0wLG89MS8wKXt0LmJvdW5kaW5nQm94fHx0LmNvbXB1dGVCb3VuZGluZ0JveCgpLG5hLnNldCh0LmJvdW5kaW5nQm94Lm1pbix0LmJvdW5kaW5nQm94Lm1heCxlKSxuYS5uZWVkc1VwZGF0ZT0hMDtjb25zdCBhPWkuZ2VvbWV0cnksYz1hLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1hLmluZGV4LGg9dC5hdHRyaWJ1dGVzLnBvc2l0aW9uLHU9dC5pbmRleCxmPWllLmdldFByaW1pdGl2ZSgpLGQ9aWUuZ2V0UHJpbWl0aXZlKCk7bGV0IHA9WWQseT1qZCxtPW51bGwsZz1udWxsO3MmJihtPVFkLGc9S2QpO2xldCBiPTEvMCx3PW51bGwseD1udWxsO3JldHVybiBxcy5jb3B5KGUpLmludmVydCgpLExpLm1hdHJpeC5jb3B5KHFzKSxpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpNPT5uYS5kaXN0YW5jZVRvQm94KE0pLGludGVyc2VjdHNCb3VuZHM6KE0sQSxTKT0+UzxiJiZTPG8/KEEmJihMaS5taW4uY29weShNLm1pbiksTGkubWF4LmNvcHkoTS5tYXgpLExpLm5lZWRzVXBkYXRlPSEwKSwhMCk6ITEsaW50ZXJzZWN0c1JhbmdlOihNLEEpPT57aWYodC5ib3VuZHNUcmVlKXtjb25zdCBTPXQuYm91bmRzVHJlZTtyZXR1cm4gUy5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6Xz0+TGkuZGlzdGFuY2VUb0JveChfKSxpbnRlcnNlY3RzQm91bmRzOihfLEUseik9Pno8YiYmejxvLGludGVyc2VjdHNSYW5nZTooXyxFKT0+e2ZvcihsZXQgej1fLHY9XytFO3o8djt6Kyspe2NvbnN0IEM9Uy5yZXNvbHZlVHJpYW5nbGVJbmRleCh6KTt5dChkLDMqQyx1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCBQPU0sRj1NK0E7UDxGO1ArKyl7Y29uc3QgQj1pLnJlc29sdmVUcmlhbmdsZUluZGV4KFApO3l0KGYsMypCLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBJPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihJPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9SSx3PVAseD16KSxJPHIpcmV0dXJuITB9fX19KX1lbHNle2NvbnN0IFM9Wm4odCk7Zm9yKGxldCBfPTAsRT1TO188RTtfKyspe3l0KGQsMypfLHUsaCksZC5hLmFwcGx5TWF0cml4NChlKSxkLmIuYXBwbHlNYXRyaXg0KGUpLGQuYy5hcHBseU1hdHJpeDQoZSksZC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHo9TSx2PU0rQTt6PHY7eisrKXtjb25zdCBDPWkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoeik7eXQoZiwzKkMsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IFA9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKFA8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1QLHc9eix4PV8pLFA8cilyZXR1cm4hMH19fX19KSxpZS5yZWxlYXNlUHJpbWl0aXZlKGYpLGllLnJlbGVhc2VQcmltaXRpdmUoZCksYj09PTEvMD9udWxsOihuLnBvaW50P24ucG9pbnQuY29weSh5KTpuLnBvaW50PXkuY2xvbmUoKSxuLmRpc3RhbmNlPWIsbi5mYWNlSW5kZXg9dyxzJiYocy5wb2ludD9zLnBvaW50LmNvcHkoZyk6cy5wb2ludD1nLmNsb25lKCkscy5wb2ludC5hcHBseU1hdHJpeDQocXMpLHkuYXBwbHlNYXRyaXg0KHFzKSxzLmRpc3RhbmNlPXkuc3ViKHMucG9pbnQpLmxlbmd0aCgpLHMuZmFjZUluZGV4PXgpLG4pfWZ1bmN0aW9uIGUwKCl7cmV0dXJuIHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciE9InVuZGVmaW5lZCJ9Y29uc3QgT2k9bmV3IG50LmNvbnN0cnVjdG9yLEhzPW5ldyBudC5jb25zdHJ1Y3Rvcixubj1uZXcgR28oKCk9Pm5ldyBndCksdGk9bmV3IGd0LGVpPW5ldyBndCxpYT1uZXcgZ3Qsc2E9bmV3IGd0O2xldCByYT0hMTtmdW5jdGlvbiBuMChpLHQsZSxuKXtpZihyYSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IFJlY3Vyc2l2ZSBjYWxscyB0byBidmhjYXN0IG5vdCBzdXBwb3J0ZWQuIik7cmE9ITA7Y29uc3Qgcz1pLl9yb290cyxyPXQuX3Jvb3RzO2xldCBvLGE9MCxjPTA7Y29uc3QgbD1uZXcgc3QoKS5jb3B5KGUpLmludmVydCgpO2ZvcihsZXQgaD0wLHU9cy5sZW5ndGg7aDx1O2grKyl7T2kuc2V0QnVmZmVyKHNbaF0pLGM9MDtjb25zdCBmPW5uLmdldFByaW1pdGl2ZSgpO2x0KDAsT2kuZmxvYXQzMkFycmF5LGYpLGYuYXBwbHlNYXRyaXg0KGwpO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwJiYoSHMuc2V0QnVmZmVyKHJbZF0pLG89ZmUoMCwwLGUsbCxuLGEsYywwLDAsZiksSHMuY2xlYXJCdWZmZXIoKSxjKz1yW2RdLmxlbmd0aCwhbyk7ZCsrKTtpZihubi5yZWxlYXNlUHJpbWl0aXZlKGYpLE9pLmNsZWFyQnVmZmVyKCksYSs9c1toXS5sZW5ndGgsbylicmVha31yZXR1cm4gcmE9ITEsb31mdW5jdGlvbiBmZShpLHQsZSxuLHMscj0wLG89MCxhPTAsYz0wLGw9bnVsbCxoPSExKXtsZXQgdSxmO2g/KHU9SHMsZj1PaSk6KHU9T2ksZj1Icyk7Y29uc3QgZD11LmZsb2F0MzJBcnJheSxwPXUudWludDMyQXJyYXkseT11LnVpbnQxNkFycmF5LG09Zi5mbG9hdDMyQXJyYXksZz1mLnVpbnQzMkFycmF5LGI9Zi51aW50MTZBcnJheSx3PWkqMix4PXQqMixNPWt0KHcseSksQT1rdCh4LGIpO2xldCBTPSExO2lmKEEmJk0paD9TPXMoVXQodCxnKSxLdCh0KjIsYiksVXQoaSxwKSxLdChpKjIseSksYyxvK3QsYSxyK2kpOlM9cyhVdChpLHApLEt0KGkqMix5KSxVdCh0LGcpLEt0KHQqMixiKSxhLHIraSxjLG8rdCk7ZWxzZSBpZihBKXtjb25zdCBfPW5uLmdldFByaW1pdGl2ZSgpO2x0KHQsbSxfKSxfLmFwcGx5TWF0cml4NChlKTtjb25zdCBFPXRlKGkpLHo9ZWUoaSxwKTtsdChFLGQsdGkpLGx0KHosZCxlaSk7Y29uc3Qgdj1fLmludGVyc2VjdHNCb3godGkpLEM9Xy5pbnRlcnNlY3RzQm94KGVpKTtTPXYmJmZlKHQsRSxuLGUscyxvLHIsYyxhKzEsXywhaCl8fEMmJmZlKHQseixuLGUscyxvLHIsYyxhKzEsXywhaCksbm4ucmVsZWFzZVByaW1pdGl2ZShfKX1lbHNle2NvbnN0IF89dGUodCksRT1lZSh0LGcpO2x0KF8sbSxpYSksbHQoRSxtLHNhKTtjb25zdCB6PWwuaW50ZXJzZWN0c0JveChpYSksdj1sLmludGVyc2VjdHNCb3goc2EpO2lmKHomJnYpUz1mZShpLF8sZSxuLHMscixvLGEsYysxLGwsaCl8fGZlKGksRSxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNlIGlmKHopaWYoTSlTPWZlKGksXyxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNle2NvbnN0IEM9bm4uZ2V0UHJpbWl0aXZlKCk7Qy5jb3B5KGlhKS5hcHBseU1hdHJpeDQoZSk7Y29uc3QgUD10ZShpKSxGPWVlKGkscCk7bHQoUCxkLHRpKSxsdChGLGQsZWkpO2NvbnN0IEI9Qy5pbnRlcnNlY3RzQm94KHRpKSxJPUMuaW50ZXJzZWN0c0JveChlaSk7Uz1CJiZmZShfLFAsbixlLHMsbyxyLGMsYSsxLEMsIWgpfHxJJiZmZShfLEYsbixlLHMsbyxyLGMsYSsxLEMsIWgpLG5uLnJlbGVhc2VQcmltaXRpdmUoQyl9ZWxzZSBpZih2KWlmKE0pUz1mZShpLEUsZSxuLHMscixvLGEsYysxLGwsaCk7ZWxzZXtjb25zdCBDPW5uLmdldFByaW1pdGl2ZSgpO0MuY29weShzYSkuYXBwbHlNYXRyaXg0KGUpO2NvbnN0IFA9dGUoaSksRj1lZShpLHApO2x0KFAsZCx0aSksbHQoRixkLGVpKTtjb25zdCBCPUMuaW50ZXJzZWN0c0JveCh0aSksST1DLmludGVyc2VjdHNCb3goZWkpO1M9QiYmZmUoRSxQLG4sZSxzLG8scixjLGErMSxDLCFoKXx8SSYmZmUoRSxGLG4sZSxzLG8scixjLGErMSxDLCFoKSxubi5yZWxlYXNlUHJpbWl0aXZlKEMpfX1yZXR1cm4gU31jb25zdCBXcz1uZXcgenQsd2w9bmV3IGd0LGkwPXtzdHJhdGVneTppbCxtYXhEZXB0aDo0MCxtYXhMZWFmVHJpczoxMCx1c2VTaGFyZWRBcnJheUJ1ZmZlcjohMSxzZXRCb3VuZGluZ0JveDohMCxvblByb2dyZXNzOm51bGwsaW5kaXJlY3Q6ITEsdmVyYm9zZTohMCxyYW5nZTpudWxsfTtjbGFzcyBvYXtzdGF0aWMgc2VyaWFsaXplKHQsZT17fSl7ZT1GdCh7Y2xvbmVCdWZmZXJzOiEwfSxlKTtjb25zdCBuPXQuZ2VvbWV0cnkscz10Ll9yb290cyxyPXQuX2luZGlyZWN0QnVmZmVyLG89bi5nZXRJbmRleCgpO2xldCBhO3JldHVybiBlLmNsb25lQnVmZmVycz9hPXtyb290czpzLm1hcChjPT5jLnNsaWNlKCkpLGluZGV4Om8/by5hcnJheS5zbGljZSgpOm51bGwsaW5kaXJlY3RCdWZmZXI6cj9yLnNsaWNlKCk6bnVsbH06YT17cm9vdHM6cyxpbmRleDpvP28uYXJyYXk6bnVsbCxpbmRpcmVjdEJ1ZmZlcjpyfSxhfXN0YXRpYyBkZXNlcmlhbGl6ZSh0LGUsbj17fSl7bj1GdCh7c2V0SW5kZXg6ITAsaW5kaXJlY3Q6ISF0LmluZGlyZWN0QnVmZmVyfSxuKTtjb25zdHtpbmRleDpzLHJvb3RzOnIsaW5kaXJlY3RCdWZmZXI6b309dCxhPW5ldyBvYShlLFplKEZ0KHt9LG4pLHtbRG9dOiEwfSkpO2lmKGEuX3Jvb3RzPXIsYS5faW5kaXJlY3RCdWZmZXI9b3x8bnVsbCxuLnNldEluZGV4KXtjb25zdCBjPWUuZ2V0SW5kZXgoKTtpZihjPT09bnVsbCl7Y29uc3QgbD1uZXcgeHQodC5pbmRleCwxLCExKTtlLnNldEluZGV4KGwpfWVsc2UgYy5hcnJheSE9PXMmJihjLmFycmF5LnNldChzKSxjLm5lZWRzVXBkYXRlPSEwKX1yZXR1cm4gYX1nZXQgaW5kaXJlY3QoKXtyZXR1cm4hIXRoaXMuX2luZGlyZWN0QnVmZmVyfWNvbnN0cnVjdG9yKHQsZT17fSl7aWYodC5pc0J1ZmZlckdlb21ldHJ5KXtpZih0LmluZGV4JiZ0LmluZGV4LmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGUgaW5kZXggYXR0cmlidXRlLiIpfWVsc2UgdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBPbmx5IEJ1ZmZlckdlb21ldHJpZXMgYXJlIHN1cHBvcnRlZC4iKTtpZihlPU9iamVjdC5hc3NpZ24oWmUoRnQoe30saTApLHtbRG9dOiExfSksZSksZS51c2VTaGFyZWRBcnJheUJ1ZmZlciYmIWUwKCkpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBTaGFyZWRBcnJheUJ1ZmZlciBpcyBub3QgYXZhaWxhYmxlLiIpO3RoaXMuZ2VvbWV0cnk9dCx0aGlzLl9yb290cz1udWxsLHRoaXMuX2luZGlyZWN0QnVmZmVyPW51bGwsZVtEb118fCh4ZCh0aGlzLGUpLCF0LmJvdW5kaW5nQm94JiZlLnNldEJvdW5kaW5nQm94JiYodC5ib3VuZGluZ0JveD10aGlzLmdldEJvdW5kaW5nQm94KG5ldyBndCkpKSx0aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4PWUuaW5kaXJlY3Q/bj0+dGhpcy5faW5kaXJlY3RCdWZmZXJbbl06bj0+bn1yZWZpdCh0PW51bGwpe3JldHVybih0aGlzLmluZGlyZWN0P1dkOkZkKSh0aGlzLHQpfXRyYXZlcnNlKHQsZT0wKXtjb25zdCBuPXRoaXMuX3Jvb3RzW2VdLHM9bmV3IFVpbnQzMkFycmF5KG4pLHI9bmV3IFVpbnQxNkFycmF5KG4pO28oMCk7ZnVuY3Rpb24gbyhhLGM9MCl7Y29uc3QgbD1hKjIsaD1yW2wrMTVdPT09UHM7aWYoaCl7Y29uc3QgdT1zW2ErNl0sZj1yW2wrMTRdO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksdSxmKX1lbHNle2NvbnN0IHU9YStQaS80LGY9c1thKzZdLGQ9c1thKzddO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksZCl8fChvKHUsYysxKSxvKGYsYysxKSl9fX1yYXljYXN0KHQsZT0wLG49MCxzPTEvMCl7Y29uc3Qgcj10aGlzLl9yb290cyxvPXRoaXMuZ2VvbWV0cnksYT1bXSxjPWUuaXNNYXRlcmlhbCxsPUFycmF5LmlzQXJyYXkoZSksaD1vLmdyb3Vwcyx1PWM/ZS5zaWRlOmUsZj10aGlzLmluZGlyZWN0P0dkOlJkO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwO2QrKyl7Y29uc3QgeT1sP2VbaFtkXS5tYXRlcmlhbEluZGV4XS5zaWRlOnUsbT1hLmxlbmd0aDtpZihmKHRoaXMsZCx5LHQsYSxuLHMpLGwpe2NvbnN0IGc9aFtkXS5tYXRlcmlhbEluZGV4O2ZvcihsZXQgYj1tLHc9YS5sZW5ndGg7Yjx3O2IrKylhW2JdLmZhY2UubWF0ZXJpYWxJbmRleD1nfX1yZXR1cm4gYX1yYXljYXN0Rmlyc3QodCxlPTAsbj0wLHM9MS8wKXtjb25zdCByPXRoaXMuX3Jvb3RzLG89dGhpcy5nZW9tZXRyeSxhPWUuaXNNYXRlcmlhbCxjPUFycmF5LmlzQXJyYXkoZSk7bGV0IGw9bnVsbDtjb25zdCBoPW8uZ3JvdXBzLHU9YT9lLnNpZGU6ZSxmPXRoaXMuaW5kaXJlY3Q/WGQ6T2Q7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHA7ZCsrKXtjb25zdCB5PWM/ZVtoW2RdLm1hdGVyaWFsSW5kZXhdLnNpZGU6dSxtPWYodGhpcyxkLHksdCxuLHMpO20hPW51bGwmJihsPT1udWxsfHxtLmRpc3RhbmNlPGwuZGlzdGFuY2UpJiYobD1tLGMmJihtLmZhY2UubWF0ZXJpYWxJbmRleD1oW2RdLm1hdGVyaWFsSW5kZXgpKX1yZXR1cm4gbH1pbnRlcnNlY3RzR2VvbWV0cnkodCxlKXtsZXQgbj0hMTtjb25zdCBzPXRoaXMuX3Jvb3RzLHI9dGhpcy5pbmRpcmVjdD9KZDpEZDtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YSYmKG49cih0aGlzLG8sdCxlKSwhbik7bysrKTtyZXR1cm4gbn1zaGFwZWNhc3QodCl7Y29uc3QgZT1pZS5nZXRQcmltaXRpdmUoKSxuPXRoaXMuaW5kaXJlY3Q/TmQ6QmQ7bGV0e2JvdW5kc1RyYXZlcnNlT3JkZXI6cyxpbnRlcnNlY3RzQm91bmRzOnIsaW50ZXJzZWN0c1JhbmdlOm8saW50ZXJzZWN0c1RyaWFuZ2xlOmF9PXQ7aWYobyYmYSl7Y29uc3QgdT1vO289KGYsZCxwLHksbSk9PnUoZixkLHAseSxtKT8hMDpuKGYsZCx0aGlzLGEscCx5LGUpfWVsc2Ugb3x8KGE/bz0odSxmLGQscCk9Pm4odSxmLHRoaXMsYSxkLHAsZSk6bz0odSxmLGQpPT5kKTtsZXQgYz0hMSxsPTA7Y29uc3QgaD10aGlzLl9yb290cztmb3IobGV0IHU9MCxmPWgubGVuZ3RoO3U8Zjt1Kyspe2NvbnN0IGQ9aFt1XTtpZihjPV9kKHRoaXMsdSxyLG8scyxsKSxjKWJyZWFrO2wrPWQuYnl0ZUxlbmd0aH1yZXR1cm4gaWUucmVsZWFzZVByaW1pdGl2ZShlKSxjfWJ2aGNhc3QodCxlLG4pe2xldHtpbnRlcnNlY3RzUmFuZ2VzOnMsaW50ZXJzZWN0c1RyaWFuZ2xlczpyfT1uO2NvbnN0IG89aWUuZ2V0UHJpbWl0aXZlKCksYT10aGlzLmdlb21ldHJ5LmluZGV4LGM9dGhpcy5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9dGhpcy5pbmRpcmVjdD9wPT57Y29uc3QgeT10aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4KHApO3l0KG8seSozLGEsYyl9OnA9Pnt5dChvLHAqMyxhLGMpfSxoPWllLmdldFByaW1pdGl2ZSgpLHU9dC5nZW9tZXRyeS5pbmRleCxmPXQuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixkPXQuaW5kaXJlY3Q/cD0+e2NvbnN0IHk9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChwKTt5dChoLHkqMyx1LGYpfTpwPT57eXQoaCxwKjMsdSxmKX07aWYocil7Y29uc3QgcD0oeSxtLGcsYix3LHgsTSxBKT0+e2ZvcihsZXQgUz1nLF89ZytiO1M8XztTKyspe2QoUyksaC5hLmFwcGx5TWF0cml4NChlKSxoLmIuYXBwbHlNYXRyaXg0KGUpLGguYy5hcHBseU1hdHJpeDQoZSksaC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IEU9eSx6PXkrbTtFPHo7RSsrKWlmKGwoRSksby5uZWVkc1VwZGF0ZT0hMCxyKG8saCxFLFMsdyx4LE0sQSkpcmV0dXJuITB9cmV0dXJuITF9O2lmKHMpe2NvbnN0IHk9cztzPWZ1bmN0aW9uKG0sZyxiLHcseCxNLEEsUyl7cmV0dXJuIHkobSxnLGIsdyx4LE0sQSxTKT8hMDpwKG0sZyxiLHcseCxNLEEsUyl9fWVsc2Ugcz1wfXJldHVybiBuMCh0aGlzLHQsZSxzKX1pbnRlcnNlY3RzQm94KHQsZSl7cmV0dXJuIFdzLnNldCh0Lm1pbix0Lm1heCxlKSxXcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpuPT5Xcy5pbnRlcnNlY3RzQm94KG4pLGludGVyc2VjdHNUcmlhbmdsZTpuPT5Xcy5pbnRlcnNlY3RzVHJpYW5nbGUobil9KX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczplPT50LmludGVyc2VjdHNCb3goZSksaW50ZXJzZWN0c1RyaWFuZ2xlOmU9PmUuaW50ZXJzZWN0c1NwaGVyZSh0KX0pfWNsb3Nlc3RQb2ludFRvR2VvbWV0cnkodCxlLG49e30scz17fSxyPTAsbz0xLzApe3JldHVybih0aGlzLmluZGlyZWN0P3QwOkhkKSh0aGlzLHQsZSxuLHMscixvKX1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZT17fSxuPTAscz0xLzApe3JldHVybiB2ZCh0aGlzLHQsZSxuLHMpfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0Lm1ha2VFbXB0eSgpLHRoaXMuX3Jvb3RzLmZvckVhY2gobj0+e2x0KDAsbmV3IEZsb2F0MzJBcnJheShuKSx3bCksdC51bmlvbih3bCl9KSx0fX1jb25zdCBibD0xZS02LHMwPWJsKi41LE1sPU1hdGgucG93KDEwLC1NYXRoLmxvZzEwKGJsKSkscjA9czAqTWw7ZnVuY3Rpb24gd2UoaSl7cmV0dXJufn4oaSpNbCtyMCl9ZnVuY3Rpb24gbzAoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfWB9ZnVuY3Rpb24gQWwoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfSwke3dlKGkueil9YH1mdW5jdGlvbiBhMChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9LCR7d2UoaS56KX0sJHt3ZShpLncpfWB9ZnVuY3Rpb24gYzAoaSx0LGUpe2UuZGlyZWN0aW9uLnN1YlZlY3RvcnModCxpKS5ub3JtYWxpemUoKTtjb25zdCBuPWkuZG90KGUuZGlyZWN0aW9uKTtyZXR1cm4gZS5vcmlnaW4uY29weShpKS5hZGRTY2FsZWRWZWN0b3IoZS5kaXJlY3Rpb24sLW4pLGV9ZnVuY3Rpb24gU2woKXtyZXR1cm4gdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIn1mdW5jdGlvbiBsMChpKXtpZihpLmJ1ZmZlciBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKXJldHVybiBpO2NvbnN0IHQ9aS5jb25zdHJ1Y3RvcixlPWkuYnVmZmVyLG49bmV3IFNoYXJlZEFycmF5QnVmZmVyKGUuYnl0ZUxlbmd0aCkscz1uZXcgVWludDhBcnJheShlKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobikuc2V0KHMsMCksbmV3IHQobil9ZnVuY3Rpb24gaDAoaSx0PUFycmF5QnVmZmVyKXtyZXR1cm4gaT42NTUzNT9uZXcgVWludDMyQXJyYXkobmV3IHQoNCppKSk6bmV3IFVpbnQxNkFycmF5KG5ldyB0KDIqaSkpfWZ1bmN0aW9uIHUwKGksdCl7aWYoIWkuaW5kZXgpe2NvbnN0IGU9aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50LG49dC51c2VTaGFyZWRBcnJheUJ1ZmZlcj9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPWgwKGUsbik7aS5zZXRJbmRleChuZXcgeHQocywxKSk7Zm9yKGxldCByPTA7cjxlO3IrKylzW3JdPXJ9fWZ1bmN0aW9uIGYwKGkpe3JldHVybiBpLmluZGV4P2kuaW5kZXguY291bnQ6aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWZ1bmN0aW9uIGFhKGkpe3JldHVybiBmMChpKS8zfWNvbnN0IGQwPTFlLTgscDA9bmV3IFQ7ZnVuY3Rpb24geTAoaSl7cmV0dXJufn4oaS8zKX1mdW5jdGlvbiBtMChpKXtyZXR1cm4gaSUzfWZ1bmN0aW9uIF9sKGksdCl7cmV0dXJuIGkuc3RhcnQtdC5zdGFydH1mdW5jdGlvbiB2bChpLHQpe3JldHVybiBwMC5zdWJWZWN0b3JzKHQsaS5vcmlnaW4pLmRvdChpLmRpcmVjdGlvbil9ZnVuY3Rpb24gZzAoaSx0LGUsbj1kMCl7aS5zb3J0KF9sKSx0LnNvcnQoX2wpO2ZvcihsZXQgYT0wO2E8aS5sZW5ndGg7YSsrKXtjb25zdCBjPWlbYV07Zm9yKGxldCBsPTA7bDx0Lmxlbmd0aDtsKyspe2NvbnN0IGg9dFtsXTtpZighKGguc3RhcnQ+Yy5lbmQpKXtpZihjLmVuZDxoLnN0YXJ0fHxoLmVuZDxjLnN0YXJ0KWNvbnRpbnVlO2lmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPj1oLmVuZClyKGguZW5kLGMuZW5kKXx8aS5zcGxpY2UoYSsxLDAse3N0YXJ0OmguZW5kLGVuZDpjLmVuZCxpbmRleDpjLmluZGV4fSksYy5lbmQ9aC5zdGFydCxoLnN0YXJ0PTAsaC5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPD1oLmVuZClyKGMuZW5kLGguZW5kKXx8dC5zcGxpY2UobCsxLDAse3N0YXJ0OmMuZW5kLGVuZDpoLmVuZCxpbmRleDpoLmluZGV4fSksaC5lbmQ9Yy5zdGFydCxjLnN0YXJ0PTAsYy5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPD1oLmVuZCl7Y29uc3QgdT1jLmVuZDtjLmVuZD1oLnN0YXJ0LGguc3RhcnQ9dX1lbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPj1oLmVuZCl7Y29uc3QgdT1oLmVuZDtoLmVuZD1jLnN0YXJ0LGMuc3RhcnQ9dX1lbHNlIHRocm93IG5ldyBFcnJvcn1pZihlLmhhcyhjLmluZGV4KXx8ZS5zZXQoYy5pbmRleCxbXSksZS5oYXMoaC5pbmRleCl8fGUuc2V0KGguaW5kZXgsW10pLGUuZ2V0KGMuaW5kZXgpLnB1c2goaC5pbmRleCksZS5nZXQoaC5pbmRleCkucHVzaChjLmluZGV4KSxvKGgpJiYodC5zcGxpY2UobCwxKSxsLS0pLG8oYykpe2kuc3BsaWNlKGEsMSksYS0tO2JyZWFrfX19cyhpKSxzKHQpO2Z1bmN0aW9uIHMoYSl7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKyspbyhhW2NdKSYmKGEuc3BsaWNlKGMsMSksYy0tKX1mdW5jdGlvbiByKGEsYyl7cmV0dXJuIE1hdGguYWJzKGMtYSk8bn1mdW5jdGlvbiBvKGEpe3JldHVybiBNYXRoLmFicyhhLmVuZC1hLnN0YXJ0KTxufX1jb25zdCB6bD0xZS01LFRsPTFlLTQ7Y2xhc3MgeDB7Y29uc3RydWN0b3IoKXt0aGlzLl9yYXlzPVtdfWFkZFJheSh0KXt0aGlzLl9yYXlzLnB1c2godCl9ZmluZENsb3Nlc3RSYXkodCl7Y29uc3QgZT10aGlzLl9yYXlzLG49dC5jbG9uZSgpO24uZGlyZWN0aW9uLm11bHRpcGx5U2NhbGFyKC0xKTtsZXQgcz0xLzAscj1udWxsO2ZvcihsZXQgYz0wLGw9ZS5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1lW2NdO2lmKG8oaCx0KSYmbyhoLG4pKWNvbnRpbnVlO2NvbnN0IHU9YShoLHQpLGY9YShoLG4pLGQ9TWF0aC5taW4odSxmKTtkPHMmJihzPWQscj1oKX1yZXR1cm4gcjtmdW5jdGlvbiBvKGMsbCl7Y29uc3QgaD1jLm9yaWdpbi5kaXN0YW5jZVRvKGwub3JpZ2luKT56bDtyZXR1cm4gYy5kaXJlY3Rpb24uYW5nbGVUbyhsLmRpcmVjdGlvbik+VGx8fGh9ZnVuY3Rpb24gYShjLGwpe2NvbnN0IGg9Yy5vcmlnaW4uZGlzdGFuY2VUbyhsLm9yaWdpbiksdT1jLmRpcmVjdGlvbi5hbmdsZVRvKGwuZGlyZWN0aW9uKTtyZXR1cm4gaC96bCt1L1RsfX19Y29uc3QgY2E9bmV3IFQsbGE9bmV3IFQsR3M9bmV3IGZvO2Z1bmN0aW9uIHcwKGksdCxlKXtjb25zdCBuPWkuYXR0cmlidXRlcyxzPWkuaW5kZXgscj1uLnBvc2l0aW9uLG89bmV3IE1hcCxhPW5ldyBNYXAsYz1BcnJheS5mcm9tKHQpLGw9bmV3IHgwO2ZvcihsZXQgaD0wLHU9Yy5sZW5ndGg7aDx1O2grKyl7Y29uc3QgZj1jW2hdLGQ9eTAoZikscD1tMChmKTtsZXQgeT0zKmQrcCxtPTMqZCsocCsxKSUzO3MmJih5PXMuZ2V0WCh5KSxtPXMuZ2V0WChtKSksY2EuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLHkpLGxhLmZyb21CdWZmZXJBdHRyaWJ1dGUocixtKSxjMChjYSxsYSxHcyk7bGV0IGcsYj1sLmZpbmRDbG9zZXN0UmF5KEdzKTtiPT09bnVsbCYmKGI9R3MuY2xvbmUoKSxsLmFkZFJheShiKSksYS5oYXMoYil8fGEuc2V0KGIse2ZvcndhcmQ6W10scmV2ZXJzZTpbXSxyYXk6Yn0pLGc9YS5nZXQoYik7bGV0IHc9dmwoYixjYSkseD12bChiLGxhKTt3PngmJihbdyx4XT1beCx3XSksR3MuZGlyZWN0aW9uLmRvdChiLmRpcmVjdGlvbik8MD9nLnJldmVyc2UucHVzaCh7c3RhcnQ6dyxlbmQ6eCxpbmRleDpmfSk6Zy5mb3J3YXJkLnB1c2goe3N0YXJ0OncsZW5kOngsaW5kZXg6Zn0pfXJldHVybiBhLmZvckVhY2goKHtmb3J3YXJkOmgscmV2ZXJzZTp1fSxmKT0+e2cwKGgsdSxvLGUpLGgubGVuZ3RoPT09MCYmdS5sZW5ndGg9PT0wJiZhLmRlbGV0ZShmKX0pLHtkaXNqb2ludENvbm5lY3Rpdml0eU1hcDpvLGZyYWdtZW50TWFwOmF9fWNvbnN0IGIwPW5ldyBSLGhhPW5ldyBULE0wPW5ldyBZdCx1YT1bIiIsIiIsIiJdO2NsYXNzIEEwe2NvbnN0cnVjdG9yKHQ9bnVsbCl7dGhpcy5kYXRhPW51bGwsdGhpcy5kaXNqb2ludENvbm5lY3Rpb25zPW51bGwsdGhpcy51bm1hdGNoZWREaXNqb2ludEVkZ2VzPW51bGwsdGhpcy51bm1hdGNoZWRFZGdlcz0tMSx0aGlzLm1hdGNoZWRFZGdlcz0tMSx0aGlzLnVzZURyYXdSYW5nZT0hMCx0aGlzLnVzZUFsbEF0dHJpYnV0ZXM9ITEsdGhpcy5tYXRjaERpc2pvaW50RWRnZXM9ITEsdGhpcy5kZWdlbmVyYXRlRXBzaWxvbj0xZS04LHQmJnRoaXMudXBkYXRlRnJvbSh0KX1nZXRTaWJsaW5nVHJpYW5nbGVJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOn5+KG4vMyl9Z2V0U2libGluZ0VkZ2VJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOm4lM31nZXREaXNqb2ludFNpYmxpbmdUcmlhbmdsZUluZGljZXModCxlKXtjb25zdCBuPXQqMytlLHM9dGhpcy5kaXNqb2ludENvbm5lY3Rpb25zLmdldChuKTtyZXR1cm4gcz9zLm1hcChyPT5+fihyLzMpKTpbXX1nZXREaXNqb2ludFNpYmxpbmdFZGdlSW5kaWNlcyh0LGUpe2NvbnN0IG49dCozK2Uscz10aGlzLmRpc2pvaW50Q29ubmVjdGlvbnMuZ2V0KG4pO3JldHVybiBzP3MubWFwKHI9PnIlMyk6W119aXNGdWxseUNvbm5lY3RlZCgpe3JldHVybiB0aGlzLnVubWF0Y2hlZEVkZ2VzPT09MH11cGRhdGVGcm9tKHQpe2NvbnN0e3VzZUFsbEF0dHJpYnV0ZXM6ZSx1c2VEcmF3UmFuZ2U6bixtYXRjaERpc2pvaW50RWRnZXM6cyxkZWdlbmVyYXRlRXBzaWxvbjpyfT10aGlzLG89ZT93OmIsYT1uZXcgTWFwLHthdHRyaWJ1dGVzOmN9PXQsbD1lP09iamVjdC5rZXlzKGMpOm51bGwsaD10LmluZGV4LHU9Yy5wb3NpdGlvbjtsZXQgZj1hYSh0KTtjb25zdCBkPWY7bGV0IHA9MDtuJiYocD10LmRyYXdSYW5nZS5zdGFydCx0LmRyYXdSYW5nZS5jb3VudCE9PTEvMCYmKGY9fn4odC5kcmF3UmFuZ2UuY291bnQvMykpKTtsZXQgeT10aGlzLmRhdGE7KCF5fHx5Lmxlbmd0aDwzKmQpJiYoeT1uZXcgSW50MzJBcnJheSgzKmQpKSx5LmZpbGwoLTEpO2xldCBtPTAsZz1uZXcgU2V0O2ZvcihsZXQgeD1wLE09ZiozK3A7eDxNO3grPTMpe2NvbnN0IEE9eDtmb3IobGV0IFM9MDtTPDM7UysrKXtsZXQgXz1BK1M7aCYmKF89aC5nZXRYKF8pKSx1YVtTXT1vKF8pfWZvcihsZXQgUz0wO1M8MztTKyspe2NvbnN0IF89KFMrMSklMyxFPXVhW1NdLHo9dWFbX10sdj1gJHt6fV8ke0V9YDtpZihhLmhhcyh2KSl7Y29uc3QgQz1BK1MsUD1hLmdldCh2KTt5W0NdPVAseVtQXT1DLGEuZGVsZXRlKHYpLG0rPTIsZy5kZWxldGUoUCl9ZWxzZXtjb25zdCBDPWAke0V9XyR7en1gLFA9QStTO2Euc2V0KEMsUCksZy5hZGQoUCl9fX1pZihzKXtjb25zdHtmcmFnbWVudE1hcDp4LGRpc2pvaW50Q29ubmVjdGl2aXR5TWFwOk19PXcwKHQsZyxyKTtnLmNsZWFyKCkseC5mb3JFYWNoKCh7Zm9yd2FyZDpBLHJldmVyc2U6U30pPT57QS5mb3JFYWNoKCh7aW5kZXg6X30pPT5nLmFkZChfKSksUy5mb3JFYWNoKCh7aW5kZXg6X30pPT5nLmFkZChfKSl9KSx0aGlzLnVubWF0Y2hlZERpc2pvaW50RWRnZXM9eCx0aGlzLmRpc2pvaW50Q29ubmVjdGlvbnM9TSxtPWYqMy1nLnNpemV9dGhpcy5tYXRjaGVkRWRnZXM9bSx0aGlzLnVubWF0Y2hlZEVkZ2VzPWcuc2l6ZSx0aGlzLmRhdGE9eTtmdW5jdGlvbiBiKHgpe3JldHVybiBoYS5mcm9tQnVmZmVyQXR0cmlidXRlKHUseCksQWwoaGEpfWZ1bmN0aW9uIHcoeCl7bGV0IE09IiI7Zm9yKGxldCBBPTAsUz1sLmxlbmd0aDtBPFM7QSsrKXtjb25zdCBfPWNbbFtBXV07bGV0IEU7c3dpdGNoKF8uaXRlbVNpemUpe2Nhc2UgMTpFPXdlKF8uZ2V0WCh4KSk7YnJlYWs7Y2FzZSAyOkU9bzAoYjAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShfLHgpKTticmVhaztjYXNlIDM6RT1BbChoYS5mcm9tQnVmZmVyQXR0cmlidXRlKF8seCkpO2JyZWFrO2Nhc2UgNDpFPWEwKE0wLmZyb21CdWZmZXJBdHRyaWJ1dGUoXyx4KSk7YnJlYWt9TSE9PSIiJiYoTSs9InwiKSxNKz1FfXJldHVybiBNfX19Y2xhc3MgWnMgZXh0ZW5kcyBiZntjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzQnJ1c2g9ITAsdGhpcy5fcHJldmlvdXNNYXRyaXg9bmV3IHN0LHRoaXMuX3ByZXZpb3VzTWF0cml4LmVsZW1lbnRzLmZpbGwoMCl9bWFya1VwZGF0ZWQoKXt0aGlzLl9wcmV2aW91c01hdHJpeC5jb3B5KHRoaXMubWF0cml4KX1pc0RpcnR5KCl7Y29uc3R7bWF0cml4OnQsX3ByZXZpb3VzTWF0cml4OmV9PXRoaXMsbj10LmVsZW1lbnRzLHM9ZS5lbGVtZW50cztmb3IobGV0IHI9MDtyPDE2O3IrKylpZihuW3JdIT09c1tyXSlyZXR1cm4hMDtyZXR1cm4hMX1wcmVwYXJlR2VvbWV0cnkoKXtjb25zdCB0PXRoaXMuZ2VvbWV0cnksZT10LmF0dHJpYnV0ZXMsbj1TbCgpO2lmKG4pZm9yKGNvbnN0IHMgaW4gZSl7Y29uc3Qgcj1lW3NdO2lmKHIuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl0aHJvdyBuZXcgRXJyb3IoIkJydXNoOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIik7ci5hcnJheT1sMChyLmFycmF5KX1pZih0LmJvdW5kc1RyZWV8fCh1MCh0LHt1c2VTaGFyZWRBcnJheUJ1ZmZlcjpufSksdC5ib3VuZHNUcmVlPW5ldyBvYSh0LHttYXhMZWFmVHJpczozLGluZGlyZWN0OiEwLHVzZVNoYXJlZEFycmF5QnVmZmVyOm59KSksdC5oYWxmRWRnZXN8fCh0LmhhbGZFZGdlcz1uZXcgQTAodCkpLCF0Lmdyb3VwSW5kaWNlcyl7Y29uc3Qgcz1hYSh0KSxyPW5ldyBVaW50MTZBcnJheShzKSxvPXQuZ3JvdXBzO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKyl7Y29uc3R7c3RhcnQ6bCxjb3VudDpofT1vW2FdO2ZvcihsZXQgdT1sLzMsZj0obCtoKS8zO3U8Zjt1Kyspclt1XT1hfXQuZ3JvdXBJbmRpY2VzPXJ9fWRpc3Bvc2VDYWNoZURhdGEoKXtjb25zdHtnZW9tZXRyeTp0fT10aGlzO3QuaGFsZkVkZ2VzPW51bGwsdC5ib3VuZHNUcmVlPW51bGwsdC5ncm91cEluZGljZXM9bnVsbH19Y29uc3QgUzA9MWUtMTQsZmE9bmV3IFQsRWw9bmV3IFQsUGw9bmV3IFQ7ZnVuY3Rpb24gc24oaSx0PVMwKXtmYS5zdWJWZWN0b3JzKGkuYixpLmEpLEVsLnN1YlZlY3RvcnMoaS5jLGkuYSksUGwuc3ViVmVjdG9ycyhpLmIsaS5jKTtjb25zdCBlPWZhLmFuZ2xlVG8oRWwpLG49ZmEuYW5nbGVUbyhQbCkscz1NYXRoLlBJLWUtbjtyZXR1cm4gTWF0aC5hYnMoZSk8dHx8TWF0aC5hYnMobik8dHx8TWF0aC5hYnMocyk8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYik8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dHx8aS5iLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dH1jb25zdCBkYT0xZS0xMCxEaT0xZS0xMCxfMD0xZS0xMCxrZT1uZXcgUXQsZnQ9bmV3IFF0LE5lPW5ldyBULHBhPW5ldyBULENsPW5ldyBULFhzPW5ldyB6byx5YT1uZXcgbmU7Y2xhc3MgdjB7Y29uc3RydWN0b3IoKXt0aGlzLl9wb29sPVtdLHRoaXMuX2luZGV4PTB9Z2V0VHJpYW5nbGUoKXtyZXR1cm4gdGhpcy5faW5kZXg+PXRoaXMuX3Bvb2wubGVuZ3RoJiZ0aGlzLl9wb29sLnB1c2gobmV3IGV0KSx0aGlzLl9wb29sW3RoaXMuX2luZGV4KytdfWNsZWFyKCl7dGhpcy5faW5kZXg9MH1yZXNldCgpe3RoaXMuX3Bvb2wubGVuZ3RoPTAsdGhpcy5faW5kZXg9MH19Y2xhc3MgejB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlUG9vbD1uZXcgdjAsdGhpcy50cmlhbmdsZXM9W10sdGhpcy5ub3JtYWw9bmV3IFQsdGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMX1pbml0aWFsaXplKHQpe3RoaXMucmVzZXQoKTtjb25zdHt0cmlhbmdsZXM6ZSx0cmlhbmdsZVBvb2w6bixub3JtYWw6c309dGhpcztpZihBcnJheS5pc0FycmF5KHQpKWZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdO2lmKHI9PT0wKWEuZ2V0Tm9ybWFsKHMpO2Vsc2UgaWYoTWF0aC5hYnMoMS1hLmdldE5vcm1hbChOZSkuZG90KHMpKT5kYSl0aHJvdyBuZXcgRXJyb3IoIlRyaWFuZ2xlIFNwbGl0dGVyOiBDYW5ub3QgaW5pdGlhbGl6ZSB3aXRoIHRyaWFuZ2xlcyB0aGF0IGhhdmUgZGlmZmVyZW50IG5vcm1hbHMuIik7Y29uc3QgYz1uLmdldFRyaWFuZ2xlKCk7Yy5jb3B5KGEpLGUucHVzaChjKX1lbHNle3QuZ2V0Tm9ybWFsKHMpO2NvbnN0IHI9bi5nZXRUcmlhbmdsZSgpO3IuY29weSh0KSxlLnB1c2gocil9fXNwbGl0QnlUcmlhbmdsZSh0KXtjb25zdHtub3JtYWw6ZSx0cmlhbmdsZXM6bn09dGhpcztpZih0LmdldE5vcm1hbChwYSkubm9ybWFsaXplKCksTWF0aC5hYnMoMS1NYXRoLmFicyhwYS5kb3QoZSkpKTxfMCl7dGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTthLmNvcGxhbmFyQ291bnQ9MH1jb25zdCBzPVt0LmEsdC5iLHQuY107Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz0ocisxKSUzLGE9c1tyXSxjPXNbb107TmUuc3ViVmVjdG9ycyhjLGEpLm5vcm1hbGl6ZSgpLENsLmNyb3NzVmVjdG9ycyhwYSxOZSksWHMuc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQoQ2wsYSksdGhpcy5zcGxpdEJ5UGxhbmUoWHMsdCl9fWVsc2UgdC5nZXRQbGFuZShYcyksdGhpcy5zcGxpdEJ5UGxhbmUoWHMsdCl9c3BsaXRCeVBsYW5lKHQsZSl7Y29uc3R7dHJpYW5nbGVzOm4sdHJpYW5nbGVQb29sOnN9PXRoaXM7eWEuY29weShlKSx5YS5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTtpZigheWEuaW50ZXJzZWN0c1RyaWFuZ2xlKGEsa2UsITApKWNvbnRpbnVlO2NvbnN0e2E6YyxiOmwsYzpofT1hO2xldCB1PTAsZj0tMSxkPSExLHA9W10seT1bXTtjb25zdCBtPVtjLGwsaF07Zm9yKGxldCBnPTA7ZzwzO2crKyl7Y29uc3QgYj0oZysxKSUzO2tlLnN0YXJ0LmNvcHkobVtnXSksa2UuZW5kLmNvcHkobVtiXSk7Y29uc3Qgdz10LmRpc3RhbmNlVG9Qb2ludChrZS5zdGFydCkseD10LmRpc3RhbmNlVG9Qb2ludChrZS5lbmQpO2lmKE1hdGguYWJzKHcpPERpJiZNYXRoLmFicyh4KTxEaSl7ZD0hMDticmVha31pZih3PjA/cC5wdXNoKGcpOnkucHVzaChnKSxNYXRoLmFicyh3KTxEaSljb250aW51ZTtsZXQgTT0hIXQuaW50ZXJzZWN0TGluZShrZSxOZSk7IU0mJk1hdGguYWJzKHgpPERpJiYoTmUuY29weShrZS5lbmQpLE09ITApLE0mJiEoTmUuZGlzdGFuY2VUbyhrZS5zdGFydCk8ZGEpJiYoTmUuZGlzdGFuY2VUbyhrZS5lbmQpPGRhJiYoZj1nKSx1PT09MD9mdC5zdGFydC5jb3B5KE5lKTpmdC5lbmQuY29weShOZSksdSsrKX1pZighZCYmdT09PTImJmZ0LmRpc3RhbmNlKCk+RGkpaWYoZiE9PS0xKXtmPShmKzEpJTM7bGV0IGc9MDtnPT09ZiYmKGc9KGcrMSklMyk7bGV0IGI9ZysxO2I9PT1mJiYoYj0oYisxKSUzKTtjb25zdCB3PXMuZ2V0VHJpYW5nbGUoKTt3LmEuY29weShtW2JdKSx3LmIuY29weShmdC5lbmQpLHcuYy5jb3B5KGZ0LnN0YXJ0KSxzbih3KXx8bi5wdXNoKHcpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LnN0YXJ0KSxhLmMuY29weShmdC5lbmQpLHNuKGEpJiYobi5zcGxpY2UociwxKSxyLS0sby0tKX1lbHNle2NvbnN0IGc9cC5sZW5ndGg+PTI/eVswXTpwWzBdO2lmKGc9PT0wKXtsZXQgQT1mdC5zdGFydDtmdC5zdGFydD1mdC5lbmQsZnQuZW5kPUF9Y29uc3QgYj0oZysxKSUzLHc9KGcrMiklMyx4PXMuZ2V0VHJpYW5nbGUoKSxNPXMuZ2V0VHJpYW5nbGUoKTttW2JdLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LnN0YXJ0KTxtW3ddLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LmVuZCk/KHguYS5jb3B5KG1bYl0pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LnN0YXJ0KSk6KHguYS5jb3B5KG1bd10pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LmVuZCkpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LmVuZCksYS5jLmNvcHkoZnQuc3RhcnQpLHNuKHgpfHxuLnB1c2goeCksc24oTSl8fG4ucHVzaChNKSxzbihhKSYmKG4uc3BsaWNlKHIsMSksci0tLG8tLSl9ZWxzZSB1PT09MyYmY29uc29sZS53YXJuKCJUcmlhbmdsZUNsaXBwZXI6IENvcGxhbmFyIGNsaXAgbm90IGhhbmRsZWQiKX19cmVzZXQoKXt0aGlzLnRyaWFuZ2xlcy5sZW5ndGg9MCx0aGlzLnRyaWFuZ2xlUG9vbC5jbGVhcigpLHRoaXMuY29wbGFuYXJUcmlhbmdsZVVzZWQ9ITF9fWZ1bmN0aW9uIFQwKGkpe3JldHVybiBpPX5+aSxpKzQtaSU0fWNsYXNzIEJse2NvbnN0cnVjdG9yKHQsZT01MDApe3RoaXMuZXhwYW5zaW9uRmFjdG9yPTEuNSx0aGlzLnR5cGU9dCx0aGlzLmxlbmd0aD0wLHRoaXMuYXJyYXk9bnVsbCx0aGlzLnNldFNpemUoZSl9c2V0VHlwZSh0KXtpZih0aGlzLmxlbmd0aCE9PTApdGhyb3cgbmV3IEVycm9yKCJUeXBlQmFja2VkQXJyYXk6IENhbm5vdCBjaGFuZ2UgdGhlIHR5cGUgd2hpbGUgdGhlcmUgaXMgdXNlZCBkYXRhIGluIHRoZSBidWZmZXIuIik7Y29uc3QgZT10aGlzLmFycmF5LmJ1ZmZlcjt0aGlzLmFycmF5PW5ldyB0KGUpLHRoaXMudHlwZT10fXNldFNpemUodCl7aWYodGhpcy5hcnJheSYmdD09PXRoaXMuYXJyYXkubGVuZ3RoKXJldHVybjtjb25zdCBlPXRoaXMudHlwZSxuPVNsKCk/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1uZXcgZShuZXcgbihUMCh0KmUuQllURVNfUEVSX0VMRU1FTlQpKSk7dGhpcy5hcnJheSYmcy5zZXQodGhpcy5hcnJheSwwKSx0aGlzLmFycmF5PXN9ZXhwYW5kKCl7Y29uc3R7YXJyYXk6dCxleHBhbnNpb25GYWN0b3I6ZX09dGhpczt0aGlzLnNldFNpemUodC5sZW5ndGgqZSl9cHVzaCguLi50KXtsZXR7YXJyYXk6ZSxsZW5ndGg6bn09dGhpcztuK3QubGVuZ3RoPmUubGVuZ3RoJiYodGhpcy5leHBhbmQoKSxlPXRoaXMuYXJyYXkpO2ZvcihsZXQgcz0wLHI9dC5sZW5ndGg7czxyO3MrKyllW24rc109dFtzXTt0aGlzLmxlbmd0aCs9dC5sZW5ndGh9Y2xlYXIoKXt0aGlzLmxlbmd0aD0wfX1jbGFzcyBFMHtjb25zdHJ1Y3Rvcigpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVt7fV0sdGhpcy5ncm91cENvdW50PTB9Z2V0VHlwZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0udHlwZX1nZXRJdGVtU2l6ZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0uaXRlbVNpemV9Z2V0Tm9ybWFsaXplZCh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0ubm9ybWFsaXplZH1nZXRDb3VudCh0KXtpZih0aGlzLmdyb3VwQ291bnQ8PXQpcmV0dXJuIDA7Y29uc3QgZT10aGlzLmdldEdyb3VwQXR0ckFycmF5KCJwb3NpdGlvbiIsdCk7cmV0dXJuIGUubGVuZ3RoL2UuaXRlbVNpemV9Z2V0VG90YWxMZW5ndGgodCl7Y29uc3R7Z3JvdXBDb3VudDplLGdyb3VwQXR0cmlidXRlczpufT10aGlzO2xldCBzPTA7Zm9yKGxldCByPTA7cjxlO3IrKyl7Y29uc3Qgbz1uW3JdO3MrPW9bdF0ubGVuZ3RofXJldHVybiBzfWdldEdyb3VwQXR0clNldCh0PTApe2NvbnN0e2dyb3VwQXR0cmlidXRlczplfT10aGlzO2lmKGVbdF0pcmV0dXJuIHRoaXMuZ3JvdXBDb3VudD1NYXRoLm1heCh0aGlzLmdyb3VwQ291bnQsdCsxKSxlW3RdO2NvbnN0IG49ZVswXTtmb3IodGhpcy5ncm91cENvdW50PU1hdGgubWF4KHRoaXMuZ3JvdXBDb3VudCx0KzEpO3Q+PWUubGVuZ3RoOyl7Y29uc3Qgcz17fTtlLnB1c2gocyk7Zm9yKGNvbnN0IHIgaW4gbil7Y29uc3Qgbz1uW3JdLGE9bmV3IEJsKG8udHlwZSk7YS5pdGVtU2l6ZT1vLml0ZW1TaXplLGEubm9ybWFsaXplZD1vLm5vcm1hbGl6ZWQsc1tyXT1hfX1yZXR1cm4gZVt0XX1nZXRHcm91cEF0dHJBcnJheSh0LGU9MCl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOm59PXRoaXM7aWYoIW5bMF1bdF0pdGhyb3cgbmV3IEVycm9yKGBUeXBlZEF0dHJpYnV0ZURhdGE6IEF0dHJpYnV0ZSB3aXRoICIke3R9IiBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRgKTtyZXR1cm4gdGhpcy5nZXRHcm91cEF0dHJTZXQoZSlbdF19aW5pdGlhbGl6ZUFycmF5KHQsZSxuLHMpe2NvbnN0e2dyb3VwQXR0cmlidXRlczpyfT10aGlzLGE9clswXVt0XTtpZihhKXtpZihhLnR5cGUhPT1lKWZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1yW2NdW3RdO2guc2V0VHlwZShlKSxoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXN9fWVsc2UgZm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPW5ldyBCbChlKTtoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXMscltjXVt0XT1ofX1jbGVhcigpe3RoaXMuZ3JvdXBDb3VudD0wO2NvbnN0e2dyb3VwQXR0cmlidXRlczp0fT10aGlzO3QuZm9yRWFjaChlPT57Zm9yKGNvbnN0IG4gaW4gZSllW25dLmNsZWFyKCl9KX1kZWxldGUodCl7dGhpcy5ncm91cEF0dHJpYnV0ZXMuZm9yRWFjaChlPT57ZGVsZXRlIGVbdF19KX1yZXNldCgpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVtdLHRoaXMuZ3JvdXBDb3VudD0wfX1jbGFzcyBGbHtjb25zdHJ1Y3Rvcigpe3RoaXMuaW50ZXJzZWN0aW9uU2V0PXt9LHRoaXMuaWRzPVtdfWFkZCh0LGUpe2NvbnN0e2ludGVyc2VjdGlvblNldDpuLGlkczpzfT10aGlzO25bdF18fChuW3RdPVtdLHMucHVzaCh0KSksblt0XS5wdXNoKGUpfX1jb25zdCBQMD0wLEMwPTEsQjA9MixJbD0zLEYwPTQsa2w9NSxObD02LHNlPW5ldyBmbyxSbD1uZXcgc3QsVHQ9bmV3IGV0LFJlPW5ldyBULExsPW5ldyBZdCxPbD1uZXcgWXQsRGw9bmV3IFl0LG1hPW5ldyBZdCxKcz1uZXcgWXQsWXM9bmV3IFl0LCRsPW5ldyBRdCxnYT1uZXcgVCx4YT0xZS04LEkwPTFlLTE1LHhuPS0xLHduPTEsanM9LTIsUXM9MiwkaT0wLGJuPTEsd2E9MixrMD0xZS0xNDtsZXQgS3M9bnVsbDtmdW5jdGlvbiBWbChpKXtLcz1pfWZ1bmN0aW9uIFVsKGksdCl7aS5nZXRNaWRwb2ludChzZS5vcmlnaW4pLGkuZ2V0Tm9ybWFsKHNlLmRpcmVjdGlvbik7Y29uc3QgZT10LnJheWNhc3RGaXJzdChzZSwyKTtyZXR1cm4hIShlJiZzZS5kaXJlY3Rpb24uZG90KGUuZmFjZS5ub3JtYWwpPjApP3huOndufWZ1bmN0aW9uIE4wKGksdCl7ZnVuY3Rpb24gZSgpe3JldHVybiBNYXRoLnJhbmRvbSgpLS41fWkuZ2V0Tm9ybWFsKGdhKSxzZS5kaXJlY3Rpb24uY29weShnYSksaS5nZXRNaWRwb2ludChzZS5vcmlnaW4pO2NvbnN0IG49MztsZXQgcz0wLHI9MS8wO2ZvcihsZXQgbz0wO288bjtvKyspe3NlLmRpcmVjdGlvbi54Kz1lKCkqeGEsc2UuZGlyZWN0aW9uLnkrPWUoKSp4YSxzZS5kaXJlY3Rpb24ueis9ZSgpKnhhLHNlLmRpcmVjdGlvbi5tdWx0aXBseVNjYWxhcigtMSk7Y29uc3QgYT10LnJheWNhc3RGaXJzdChzZSwyKTtpZighIShhJiZzZS5kaXJlY3Rpb24uZG90KGEuZmFjZS5ub3JtYWwpPjApJiZzKyssYSE9PW51bGwmJihyPU1hdGgubWluKHIsYS5kaXN0YW5jZSkpLHI8PUkwKXJldHVybiBhLmZhY2Uubm9ybWFsLmRvdChnYSk+MD9RczpqcztpZihzL24+LjV8fChvLXMrMSkvbj4uNSlicmVha31yZXR1cm4gcy9uPi41P3huOndufWZ1bmN0aW9uIFIwKGksdCl7Y29uc3QgZT1uZXcgRmwsbj1uZXcgRmw7cmV0dXJuIFJsLmNvcHkoaS5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkodC5tYXRyaXhXb3JsZCksaS5nZW9tZXRyeS5ib3VuZHNUcmVlLmJ2aGNhc3QodC5nZW9tZXRyeS5ib3VuZHNUcmVlLFJsLHtpbnRlcnNlY3RzVHJpYW5nbGVzKHMscixvLGEpe2lmKCFzbihzKSYmIXNuKHIpKXtsZXQgYz1zLmludGVyc2VjdHNUcmlhbmdsZShyLCRsLCEwKTtpZighYyl7Y29uc3QgbD1zLnBsYW5lLGg9ci5wbGFuZSx1PWwubm9ybWFsLGY9aC5ub3JtYWw7dS5kb3QoZik9PT0xJiZNYXRoLmFicyhsLmNvbnN0YW50LWguY29uc3RhbnQpPGswJiYoYz0hMCl9aWYoYyl7bGV0IGw9aS5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KG8pLGg9dC5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KGEpO2UuYWRkKGwsaCksbi5hZGQoaCxsKSxLcyYmKEtzLmFkZEVkZ2UoJGwpLEtzLmFkZEludGVyc2VjdGluZ1RyaWFuZ2xlcyhvLHMsYSxyKSl9fXJldHVybiExfX0pLHthSW50ZXJzZWN0aW9uczplLGJJbnRlcnNlY3Rpb25zOm59fWZ1bmN0aW9uIEwwKGksdCxlLG4scyxyLG89ITEpe2NvbnN0IGE9ZS5hdHRyaWJ1dGVzLGM9ZS5pbmRleCxsPWkqMyxoPWMuZ2V0WChsKzApLHU9Yy5nZXRYKGwrMSksZj1jLmdldFgobCsyKTtmb3IoY29uc3QgZCBpbiByKXtjb25zdCBwPWFbZF0seT1yW2RdO2lmKCEoZCBpbiBhKSl0aHJvdyBuZXcgRXJyb3IoYENTRyBPcGVyYXRpb25zOiBBdHRyaWJ1dGUgJHtkfSBub3QgYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IG09cC5pdGVtU2l6ZTtkPT09InBvc2l0aW9uIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlNYXRyaXg0KG4pLFR0LmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLHUpLmFwcGx5TWF0cml4NChuKSxUdC5jLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxmKS5hcHBseU1hdHJpeDQobiksYmEoVHQuYSxUdC5iLFR0LmMsdCwzLHksbykpOmQ9PT0ibm9ybWFsIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHAsZikuYXBwbHlOb3JtYWxNYXRyaXgocyksbyYmKFR0LmEubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmIubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmMubXVsdGlwbHlTY2FsYXIoLTEpKSxiYShUdC5hLFR0LmIsVHQuYyx0LDMseSxvLCEwKSk6KExsLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKSxPbC5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSksRGwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGYpLGJhKExsLE9sLERsLHQsbSx5LG8pKX19ZnVuY3Rpb24gTzAoaSx0LGUsbixzLHIsbyxhPSExKXtNYShpLG4scyxyLG8sYSksTWEoYT9lOnQsbixzLHIsbyxhKSxNYShhP3Q6ZSxuLHMscixvLGEpfWZ1bmN0aW9uIHFsKGksdCxlPSExKXtzd2l0Y2goaSl7Y2FzZSBQMDppZih0PT09d258fHQ9PT1RcyYmIWUpcmV0dXJuIGJuO2JyZWFrO2Nhc2UgQzA6aWYoZSl7aWYodD09PXhuKXJldHVybiAkaX1lbHNlIGlmKHQ9PT13bnx8dD09PWpzKXJldHVybiBibjticmVhaztjYXNlIEIwOmlmKGUpe2lmKHQ9PT13bnx8dD09PWpzKXJldHVybiBibn1lbHNlIGlmKHQ9PT14bilyZXR1cm4gJGk7YnJlYWs7Y2FzZSBGMDppZih0PT09eG4pcmV0dXJuICRpO2lmKHQ9PT13bilyZXR1cm4gYm47YnJlYWs7Y2FzZSBJbDppZih0PT09eG58fHQ9PT1RcyYmIWUpcmV0dXJuIGJuO2JyZWFrO2Nhc2Uga2w6aWYoIWUmJih0PT09d258fHQ9PT1qcykpcmV0dXJuIGJuO2JyZWFrO2Nhc2UgTmw6aWYoIWUmJih0PT09eG58fHQ9PT1RcykpcmV0dXJuIGJuO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgQ1NHIG9wZXJhdGlvbiBlbnVtICIke2l9Ii5gKX1yZXR1cm4gd2F9ZnVuY3Rpb24gYmEoaSx0LGUsbixzLHIsbz0hMSxhPSExKXtjb25zdCBjPWw9PntyLnB1c2gobC54KSxzPjEmJnIucHVzaChsLnkpLHM+MiYmci5wdXNoKGwueikscz4zJiZyLnB1c2gobC53KX07bWEuc2V0KDAsMCwwLDApLmFkZFNjYWxlZFZlY3RvcihpLG4uYS54KS5hZGRTY2FsZWRWZWN0b3IodCxuLmEueSkuYWRkU2NhbGVkVmVjdG9yKGUsbi5hLnopLEpzLnNldCgwLDAsMCwwKS5hZGRTY2FsZWRWZWN0b3IoaSxuLmIueCkuYWRkU2NhbGVkVmVjdG9yKHQsbi5iLnkpLmFkZFNjYWxlZFZlY3RvcihlLG4uYi56KSxZcy5zZXQoMCwwLDAsMCkuYWRkU2NhbGVkVmVjdG9yKGksbi5jLngpLmFkZFNjYWxlZFZlY3Rvcih0LG4uYy55KS5hZGRTY2FsZWRWZWN0b3IoZSxuLmMueiksYSYmKG1hLm5vcm1hbGl6ZSgpLEpzLm5vcm1hbGl6ZSgpLFlzLm5vcm1hbGl6ZSgpKSxjKG1hKSxvPyhjKFlzKSxjKEpzKSk6KGMoSnMpLGMoWXMpKX1mdW5jdGlvbiBNYShpLHQsZSxuLHMscj0hMSl7Zm9yKGNvbnN0IG8gaW4gcyl7Y29uc3QgYT10W29dLGM9c1tvXTtpZighKG8gaW4gdCkpdGhyb3cgbmV3IEVycm9yKGBDU0cgT3BlcmF0aW9uczogQXR0cmlidXRlICR7b30gbm8gYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IGw9YS5pdGVtU2l6ZTtvPT09InBvc2l0aW9uIj8oUmUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGkpLmFwcGx5TWF0cml4NChlKSxjLnB1c2goUmUueCxSZS55LFJlLnopKTpvPT09Im5vcm1hbCI/KFJlLmZyb21CdWZmZXJBdHRyaWJ1dGUoYSxpKS5hcHBseU5vcm1hbE1hdHJpeChuKSxyJiZSZS5tdWx0aXBseVNjYWxhcigtMSksYy5wdXNoKFJlLngsUmUueSxSZS56KSk6KGMucHVzaChhLmdldFgoaSkpLGw+MSYmYy5wdXNoKGEuZ2V0WShpKSksbD4yJiZjLnB1c2goYS5nZXRaKGkpKSxsPjMmJmMucHVzaChhLmdldFcoaSkpKX19Y2xhc3MgRDB7Y29uc3RydWN0b3IodCl7dGhpcy50cmlhbmdsZT1uZXcgZXQoKS5jb3B5KHQpLHRoaXMuaW50ZXJzZWN0cz17fX1hZGRUcmlhbmdsZSh0LGUpe3RoaXMuaW50ZXJzZWN0c1t0XT1uZXcgZXQoKS5jb3B5KGUpfWdldEludGVyc2VjdEFycmF5KCl7Y29uc3QgdD1bXSx7aW50ZXJzZWN0czplfT10aGlzO2Zvcihjb25zdCBuIGluIGUpdC5wdXNoKGVbbl0pO3JldHVybiB0fX1jbGFzcyBIbHtjb25zdHJ1Y3Rvcigpe3RoaXMuZGF0YT17fX1hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKXtjb25zdHtkYXRhOnJ9PXRoaXM7clt0XXx8KHJbdF09bmV3IEQwKGUpKSxyW3RdLmFkZFRyaWFuZ2xlKG4scyl9Z2V0VHJpYW5nbGVzQXNBcnJheSh0PW51bGwpe2NvbnN0e2RhdGE6ZX09dGhpcyxuPVtdO2lmKHQhPT1udWxsKXQgaW4gZSYmbi5wdXNoKGVbdF0udHJpYW5nbGUpO2Vsc2UgZm9yKGNvbnN0IHMgaW4gZSluLnB1c2goZVtzXS50cmlhbmdsZSk7cmV0dXJuIG59Z2V0VHJpYW5nbGVJbmRpY2VzKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubWFwKHQ9PnBhcnNlSW50KHQpKX1nZXRJbnRlcnNlY3Rpb25JbmRpY2VzKHQpe2NvbnN0e2RhdGE6ZX09dGhpcztyZXR1cm4gZVt0XT9PYmplY3Qua2V5cyhlW3RdLmludGVyc2VjdHMpLm1hcChuPT5wYXJzZUludChuKSk6W119Z2V0SW50ZXJzZWN0aW9uc0FzQXJyYXkodD1udWxsLGU9bnVsbCl7Y29uc3R7ZGF0YTpufT10aGlzLHM9bmV3IFNldCxyPVtdLG89YT0+e2lmKG5bYV0paWYoZSE9PW51bGwpblthXS5pbnRlcnNlY3RzW2VdJiZyLnB1c2goblthXS5pbnRlcnNlY3RzW2VdKTtlbHNle2NvbnN0IGM9blthXS5pbnRlcnNlY3RzO2Zvcihjb25zdCBsIGluIGMpcy5oYXMobCl8fChzLmFkZChsKSxyLnB1c2goY1tsXSkpfX07aWYodCE9PW51bGwpbyh0KTtlbHNlIGZvcihjb25zdCBhIGluIG4pbyhhKTtyZXR1cm4gcn1yZXNldCgpe3RoaXMuZGF0YT17fX19Y2xhc3MgJDB7Y29uc3RydWN0b3IoKXt0aGlzLmVuYWJsZWQ9ITEsdGhpcy50cmlhbmdsZUludGVyc2VjdHNBPW5ldyBIbCx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0I9bmV3IEhsLHRoaXMuaW50ZXJzZWN0aW9uRWRnZXM9W119YWRkSW50ZXJzZWN0aW5nVHJpYW5nbGVzKHQsZSxuLHMpe2NvbnN0e3RyaWFuZ2xlSW50ZXJzZWN0c0E6cix0cmlhbmdsZUludGVyc2VjdHNCOm99PXRoaXM7ci5hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKSxvLmFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKG4scyx0LGUpfWFkZEVkZ2UodCl7dGhpcy5pbnRlcnNlY3Rpb25FZGdlcy5wdXNoKHQuY2xvbmUoKSl9cmVzZXQoKXt0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0EucmVzZXQoKSx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0IucmVzZXQoKSx0aGlzLmludGVyc2VjdGlvbkVkZ2VzPVtdfWluaXQoKXt0aGlzLmVuYWJsZWQmJih0aGlzLnJlc2V0KCksVmwodGhpcykpfWNvbXBsZXRlKCl7dGhpcy5lbmFibGVkJiZWbChudWxsKX19Y29uc3Qgcm49bmV3IHN0LHRyPW5ldyBnZSxNbj1uZXcgZXQsZXI9bmV3IGV0LG9uPW5ldyBldCxucj1uZXcgZXQsZGU9W10sQW49W107ZnVuY3Rpb24gVjAoaSl7Zm9yKGNvbnN0IHQgb2YgaSlyZXR1cm4gdH1mdW5jdGlvbiBVMChpLHQsZSxuLHMscj17fSl7Y29uc3R7dXNlR3JvdXBzOm89ITB9PXIse2FJbnRlcnNlY3Rpb25zOmEsYkludGVyc2VjdGlvbnM6Y309UjAoaSx0KSxsPVtdO2xldCBoPW51bGwsdTtyZXR1cm4gdT1vPzA6LTEsV2woaSx0LGEsZSwhMSxuLHMsdSksR2woaSx0LGEsZSwhMSxzLHUpLGUuZmluZEluZGV4KGQ9PmQhPT1ObCYmZCE9PWtsKSE9PS0xJiYodT1vP2kuZ2VvbWV0cnkuZ3JvdXBzLmxlbmd0aHx8MTotMSxXbCh0LGksYyxlLCEwLG4scyx1KSxHbCh0LGksYyxlLCEwLHMsdSkpLGRlLmxlbmd0aD0wLEFuLmxlbmd0aD0wLHtncm91cHM6bCxtYXRlcmlhbHM6aH19ZnVuY3Rpb24gV2woaSx0LGUsbixzLHIsbyxhPTApe2NvbnN0IGM9aS5tYXRyaXhXb3JsZC5kZXRlcm1pbmFudCgpPDA7cm4uY29weSh0Lm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseShpLm1hdHJpeFdvcmxkKSx0ci5nZXROb3JtYWxNYXRyaXgoaS5tYXRyaXhXb3JsZCkubXVsdGlwbHlTY2FsYXIoYz8tMToxKTtjb25zdCBsPWkuZ2VvbWV0cnkuZ3JvdXBJbmRpY2VzLGg9aS5nZW9tZXRyeS5pbmRleCx1PWkuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixmPXQuZ2VvbWV0cnkuYm91bmRzVHJlZSxkPXQuZ2VvbWV0cnkuaW5kZXgscD10Lmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb24seT1lLmlkcyxtPWUuaW50ZXJzZWN0aW9uU2V0O2ZvcihsZXQgZz0wLGI9eS5sZW5ndGg7ZzxiO2crKyl7Y29uc3Qgdz15W2ddLHg9YT09PS0xPzA6bFt3XSthLE09Myp3LEE9aC5nZXRYKE0rMCksUz1oLmdldFgoTSsxKSxfPWguZ2V0WChNKzIpO01uLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LEEpLmFwcGx5TWF0cml4NChybiksTW4uYi5mcm9tQnVmZmVyQXR0cmlidXRlKHUsUykuYXBwbHlNYXRyaXg0KHJuKSxNbi5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodSxfKS5hcHBseU1hdHJpeDQocm4pLHIucmVzZXQoKSxyLmluaXRpYWxpemUoTW4pO2NvbnN0IEU9bVt3XTtmb3IobGV0IHY9MCxDPUUubGVuZ3RoO3Y8Qzt2Kyspe2NvbnN0IFA9MypFW3ZdLEY9ZC5nZXRYKFArMCksQj1kLmdldFgoUCsxKSxJPWQuZ2V0WChQKzIpO2VyLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEYpLGVyLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEIpLGVyLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEkpLHIuc3BsaXRCeVRyaWFuZ2xlKGVyKX1jb25zdCB6PXIudHJpYW5nbGVzO2ZvcihsZXQgdj0wLEM9ei5sZW5ndGg7djxDO3YrKyl7Y29uc3QgUD16W3ZdLEY9ci5jb3BsYW5hclRyaWFuZ2xlVXNlZD9OMChQLGYpOlVsKFAsZik7ZGUubGVuZ3RoPTAsQW4ubGVuZ3RoPTA7Zm9yKGxldCBCPTAsST1uLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPXFsKG5bQl0sRixzKTtrIT09d2EmJihBbi5wdXNoKGspLGRlLnB1c2gob1tCXS5nZXRHcm91cEF0dHJTZXQoeCkpKX1pZihkZS5sZW5ndGghPT0wKXtNbi5nZXRCYXJ5Y29vcmQoUC5hLG5yLmEpLE1uLmdldEJhcnljb29yZChQLmIsbnIuYiksTW4uZ2V0QmFyeWNvb3JkKFAuYyxuci5jKTtmb3IobGV0IEI9MCxJPWRlLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPWRlW0JdLFU9QW5bQl09PT0kaTtMMCh3LG5yLGkuZ2VvbWV0cnksaS5tYXRyaXhXb3JsZCx0cixrLGMhPT1VKX19fX1yZXR1cm4geS5sZW5ndGh9ZnVuY3Rpb24gR2woaSx0LGUsbixzLHIsbz0wKXtjb25zdCBhPWkubWF0cml4V29ybGQuZGV0ZXJtaW5hbnQoKTwwO3JuLmNvcHkodC5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkoaS5tYXRyaXhXb3JsZCksdHIuZ2V0Tm9ybWFsTWF0cml4KGkubWF0cml4V29ybGQpLm11bHRpcGx5U2NhbGFyKGE/LTE6MSk7Y29uc3QgYz10Lmdlb21ldHJ5LmJvdW5kc1RyZWUsbD1pLmdlb21ldHJ5Lmdyb3VwSW5kaWNlcyxoPWkuZ2VvbWV0cnkuaW5kZXgsdT1pLmdlb21ldHJ5LmF0dHJpYnV0ZXMsZj11LnBvc2l0aW9uLGQ9W10scD1pLmdlb21ldHJ5LmhhbGZFZGdlcyx5PW5ldyBTZXQsbT1hYShpLmdlb21ldHJ5KTtmb3IobGV0IGc9MCxiPW07ZzxiO2crKylnIGluIGUuaW50ZXJzZWN0aW9uU2V0fHx5LmFkZChnKTtmb3IoO3kuc2l6ZT4wOyl7Y29uc3QgZz1WMCh5KTt5LmRlbGV0ZShnKSxkLnB1c2goZyk7Y29uc3QgYj0zKmcsdz1oLmdldFgoYiswKSx4PWguZ2V0WChiKzEpLE09aC5nZXRYKGIrMik7b24uYS5mcm9tQnVmZmVyQXR0cmlidXRlKGYsdykuYXBwbHlNYXRyaXg0KHJuKSxvbi5iLmZyb21CdWZmZXJBdHRyaWJ1dGUoZix4KS5hcHBseU1hdHJpeDQocm4pLG9uLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLE0pLmFwcGx5TWF0cml4NChybik7Y29uc3QgQT1VbChvbixjKTtBbi5sZW5ndGg9MCxkZS5sZW5ndGg9MDtmb3IobGV0IFM9MCxfPW4ubGVuZ3RoO1M8XztTKyspe2NvbnN0IEU9cWwobltTXSxBLHMpO0UhPT13YSYmKEFuLnB1c2goRSksZGUucHVzaChyW1NdKSl9Zm9yKDtkLmxlbmd0aD4wOyl7Y29uc3QgUz1kLnBvcCgpO2ZvcihsZXQgXz0wO188MztfKyspe2NvbnN0IEU9cC5nZXRTaWJsaW5nVHJpYW5nbGVJbmRleChTLF8pO0UhPT0tMSYmeS5oYXMoRSkmJihkLnB1c2goRSkseS5kZWxldGUoRSkpfWlmKGRlLmxlbmd0aCE9PTApe2NvbnN0IF89MypTLEU9aC5nZXRYKF8rMCksej1oLmdldFgoXysxKSx2PWguZ2V0WChfKzIpLEM9bz09PS0xPzA6bFtTXStvO2lmKG9uLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLEUpLG9uLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHopLG9uLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHYpLCFzbihvbikpZm9yKGxldCBQPTAsRj1kZS5sZW5ndGg7UDxGO1ArKyl7Y29uc3QgQj1BbltQXSxJPWRlW1BdLmdldEdyb3VwQXR0clNldChDKSxrPUI9PT0kaTtPMChFLHosdix1LGkubWF0cml4V29ybGQsdHIsSSxrIT09YSl9fX19fWZ1bmN0aW9uIHEwKGkpe2ZvcihsZXQgdD0wO3Q8aS5sZW5ndGgtMTt0Kyspe2NvbnN0IGU9aVt0XSxuPWlbdCsxXTtpZihlLm1hdGVyaWFsSW5kZXg9PT1uLm1hdGVyaWFsSW5kZXgpe2NvbnN0IHM9ZS5zdGFydCxyPW4uc3RhcnQrbi5jb3VudDtuLnN0YXJ0PXMsbi5jb3VudD1yLXMsaS5zcGxpY2UodCwxKSx0LS19fX1mdW5jdGlvbiBIMChpLHQsZSxuKXtlLmNsZWFyKCk7Y29uc3Qgcz1pLmF0dHJpYnV0ZXM7Zm9yKGxldCByPTAsbz1uLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPW5bcl0sYz1zW2FdO2UuaW5pdGlhbGl6ZUFycmF5KGEsYy5hcnJheS5jb25zdHJ1Y3RvcixjLml0ZW1TaXplLGMubm9ybWFsaXplZCl9Zm9yKGNvbnN0IHIgaW4gZS5hdHRyaWJ1dGVzKW4uaW5jbHVkZXMocil8fGUuZGVsZXRlKHIpO2Zvcihjb25zdCByIGluIHQuYXR0cmlidXRlcyluLmluY2x1ZGVzKHIpfHwodC5kZWxldGVBdHRyaWJ1dGUociksdC5kaXNwb3NlKCkpfWZ1bmN0aW9uIFcwKGksdCxlKXtsZXQgbj0hMSxzPS0xO2NvbnN0IHI9aS5hdHRyaWJ1dGVzLG89dC5ncm91cEF0dHJpYnV0ZXNbMF07Zm9yKGNvbnN0IGMgaW4gbyl7Y29uc3QgbD10LmdldFRvdGFsTGVuZ3RoKGMpLGg9dC5nZXRUeXBlKGMpLHU9dC5nZXRJdGVtU2l6ZShjKSxmPXQuZ2V0Tm9ybWFsaXplZChjKTtsZXQgZD1yW2NdOyghZHx8ZC5hcnJheS5sZW5ndGg8bCkmJihkPW5ldyB4dChuZXcgaChsKSx1LGYpLGkuc2V0QXR0cmlidXRlKGMsZCksbj0hMCk7bGV0IHA9MDtmb3IobGV0IHk9MCxtPU1hdGgubWluKGUubGVuZ3RoLHQuZ3JvdXBDb3VudCk7eTxtO3krKyl7Y29uc3QgZz1lW3ldLmluZGV4LHthcnJheTpiLHR5cGU6dyxsZW5ndGg6eH09dC5ncm91cEF0dHJpYnV0ZXNbZ11bY10sTT1uZXcgdyhiLmJ1ZmZlciwwLHgpO2QuYXJyYXkuc2V0KE0scCkscCs9TS5sZW5ndGh9ZC5uZWVkc1VwZGF0ZT0hMCxzPWwvZC5pdGVtU2l6ZX1pZihpLmluZGV4KXtjb25zdCBjPWkuaW5kZXguYXJyYXk7aWYoYy5sZW5ndGg8cylpLmluZGV4PW51bGwsbj0hMDtlbHNlIGZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyljW2xdPWx9bGV0IGE9MDtpLmNsZWFyR3JvdXBzKCk7Zm9yKGxldCBjPTAsbD1NYXRoLm1pbihlLmxlbmd0aCx0Lmdyb3VwQ291bnQpO2M8bDtjKyspe2NvbnN0e2luZGV4OmgsbWF0ZXJpYWxJbmRleDp1fT1lW2NdLGY9dC5nZXRDb3VudChoKTtmIT09MCYmKGkuYWRkR3JvdXAoYSxmLHUpLGErPWYpfWkuc2V0RHJhd1JhbmdlKDAscyksaS5ib3VuZHNUcmVlPW51bGwsbiYmaS5kaXNwb3NlKCl9ZnVuY3Rpb24gWmwoaSx0KXtsZXQgZT10O3JldHVybiBBcnJheS5pc0FycmF5KHQpfHwoZT1bXSxpLmZvckVhY2gobj0+e2Vbbi5tYXRlcmlhbEluZGV4XT10fSkpLGV9Y2xhc3MgRzB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlU3BsaXR0ZXI9bmV3IHowLHRoaXMuYXR0cmlidXRlRGF0YT1bXSx0aGlzLmF0dHJpYnV0ZXM9WyJwb3NpdGlvbiIsInV2Iiwibm9ybWFsIl0sdGhpcy51c2VHcm91cHM9ITAsdGhpcy5jb25zb2xpZGF0ZUdyb3Vwcz0hMCx0aGlzLmRlYnVnPW5ldyAkMH1nZXRHcm91cFJhbmdlcyh0KXtyZXR1cm4hdGhpcy51c2VHcm91cHN8fHQuZ3JvdXBzLmxlbmd0aD09PTA/W3tzdGFydDowLGNvdW50OjEvMCxtYXRlcmlhbEluZGV4OjB9XTp0Lmdyb3Vwcy5tYXAoZT0+RnQoe30sZSkpfWV2YWx1YXRlKHQsZSxuLHM9bmV3IFpzKXtsZXQgcj0hMDtpZihBcnJheS5pc0FycmF5KG4pfHwobj1bbl0pLEFycmF5LmlzQXJyYXkocyl8fChzPVtzXSxyPSExKSxzLmxlbmd0aCE9PW4ubGVuZ3RoKXRocm93IG5ldyBFcnJvcigiRXZhbHVhdG9yOiBvcGVyYXRpb25zIGFuZCB0YXJnZXQgYXJyYXkgcGFzc2VkIGFzIGRpZmZlcmVudCBzaXplcy4iKTt0LnByZXBhcmVHZW9tZXRyeSgpLGUucHJlcGFyZUdlb21ldHJ5KCk7Y29uc3R7dHJpYW5nbGVTcGxpdHRlcjpvLGF0dHJpYnV0ZURhdGE6YSxhdHRyaWJ1dGVzOmMsdXNlR3JvdXBzOmwsY29uc29saWRhdGVHcm91cHM6aCxkZWJ1Zzp1fT10aGlzO2Zvcig7YS5sZW5ndGg8cy5sZW5ndGg7KWEucHVzaChuZXcgRTApO3MuZm9yRWFjaCgoZyxiKT0+e0gwKHQuZ2VvbWV0cnksZy5nZW9tZXRyeSxhW2JdLGMpfSksdS5pbml0KCksVTAodCxlLG4sbyxhLHt1c2VHcm91cHM6bH0pLHUuY29tcGxldGUoKTtjb25zdCBmPXRoaXMuZ2V0R3JvdXBSYW5nZXModC5nZW9tZXRyeSksZD1abChmLHQubWF0ZXJpYWwpLHA9dGhpcy5nZXRHcm91cFJhbmdlcyhlLmdlb21ldHJ5KSx5PVpsKHAsZS5tYXRlcmlhbCk7cC5mb3JFYWNoKGc9PmcubWF0ZXJpYWxJbmRleCs9ZC5sZW5ndGgpO2xldCBtPVsuLi5mLC4uLnBdLm1hcCgoZyxiKT0+WmUoRnQoe30sZykse2luZGV4OmJ9KSk7aWYobCl7Y29uc3QgZz1bLi4uZCwuLi55XTtoJiYobT1tLm1hcCh3PT57Y29uc3QgeD1nW3cubWF0ZXJpYWxJbmRleF07cmV0dXJuIHcubWF0ZXJpYWxJbmRleD1nLmluZGV4T2YoeCksd30pLnNvcnQoKHcseCk9PncubWF0ZXJpYWxJbmRleC14Lm1hdGVyaWFsSW5kZXgpKTtjb25zdCBiPVtdO2ZvcihsZXQgdz0wLHg9Zy5sZW5ndGg7dzx4O3crKyl7bGV0IE09ITE7Zm9yKGxldCBBPTAsUz1tLmxlbmd0aDtBPFM7QSsrKXtjb25zdCBfPW1bQV07Xy5tYXRlcmlhbEluZGV4PT09dyYmKE09ITAsXy5tYXRlcmlhbEluZGV4PWIubGVuZ3RoKX1NJiZiLnB1c2goZ1t3XSl9cy5mb3JFYWNoKHc9Pnt3Lm1hdGVyaWFsPWJ9KX1lbHNlIG09W3tzdGFydDowLGNvdW50OjEvMCxpbmRleDowLG1hdGVyaWFsSW5kZXg6MH1dLHMuZm9yRWFjaChnPT57Zy5tYXRlcmlhbD1kWzBdfSk7cmV0dXJuIHMuZm9yRWFjaCgoZyxiKT0+e2NvbnN0IHc9Zy5nZW9tZXRyeTtXMCh3LGFbYl0sbSksaCYmcTAody5ncm91cHMpfSkscj9zOnNbMF19ZXZhbHVhdGVIaWVyYXJjaHkodCxlPW5ldyBacyl7dC51cGRhdGVNYXRyaXhXb3JsZCghMCk7Y29uc3Qgbj0ocixvKT0+e2NvbnN0IGE9ci5jaGlsZHJlbjtmb3IobGV0IGM9MCxsPWEubGVuZ3RoO2M8bDtjKyspe2NvbnN0IGg9YVtjXTtoLmlzT3BlcmF0aW9uR3JvdXA/bihoLG8pOm8oaCl9fSxzPXI9Pntjb25zdCBvPXIuY2hpbGRyZW47bGV0IGE9ITE7Zm9yKGxldCBsPTAsaD1vLmxlbmd0aDtsPGg7bCsrKXtjb25zdCB1PW9bbF07YT1zKHUpfHxhfWNvbnN0IGM9ci5pc0RpcnR5KCk7aWYoYyYmci5tYXJrVXBkYXRlZCgpLGEmJiFyLmlzT3BlcmF0aW9uR3JvdXApe2xldCBsO3JldHVybiBuKHIsaD0+e2w/bD10aGlzLmV2YWx1YXRlKGwsaCxoLm9wZXJhdGlvbik6bD10aGlzLmV2YWx1YXRlKHIsaCxoLm9wZXJhdGlvbil9KSxyLl9jYWNoZWRHZW9tZXRyeT1sLmdlb21ldHJ5LHIuX2NhY2hlZE1hdGVyaWFscz1sLm1hdGVyaWFsLCEwfWVsc2UgcmV0dXJuIGF8fGN9O3JldHVybiBzKHQpLGUuZ2VvbWV0cnk9dC5fY2FjaGVkR2VvbWV0cnksZS5tYXRlcmlhbD10Ll9jYWNoZWRNYXRlcmlhbHMsZX1yZXNldCgpe3RoaXMudHJpYW5nbGVTcGxpdHRlci5yZXNldCgpfX1mdW5jdGlvbiBYbChpKXtsZXQgdCxlLG4scz0tMSxyPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZih0PT09dm9pZCAwJiYodD1oLmFycmF5LmNvbnN0cnVjdG9yKSx0IT09aC5hcnJheS5jb25zdHJ1Y3RvcilyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmFycmF5IG11c3QgYmUgb2YgY29uc2lzdGVudCBhcnJheSB0eXBlcyBhY3Jvc3MgbWF0Y2hpbmcgYXR0cmlidXRlcy4iKSxudWxsO2lmKGU9PT12b2lkIDAmJihlPWguaXRlbVNpemUpLGUhPT1oLml0ZW1TaXplKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuaXRlbVNpemUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7aWYobj09PXZvaWQgMCYmKG49aC5ub3JtYWxpemVkKSxuIT09aC5ub3JtYWxpemVkKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUubm9ybWFsaXplZCBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihzPT09LTEmJihzPWguZ3B1VHlwZSkscyE9PWguZ3B1VHlwZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmdwdVR5cGUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7cis9aC5jb3VudCplfWNvbnN0IG89bmV3IHQociksYT1uZXcgeHQobyxlLG4pO2xldCBjPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZihoLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpe2NvbnN0IHU9Yy9lO2ZvcihsZXQgZj0wLGQ9aC5jb3VudDtmPGQ7ZisrKWZvcihsZXQgcD0wO3A8ZTtwKyspe2NvbnN0IHk9aC5nZXRDb21wb25lbnQoZixwKTthLnNldENvbXBvbmVudChmK3UscCx5KX19ZWxzZSBvLnNldChoLmFycmF5LGMpO2MrPWguY291bnQqZX1yZXR1cm4gcyE9PXZvaWQgMCYmKGEuZ3B1VHlwZT1zKSxhfWZ1bmN0aW9uIFowKGkpe2lmKGkuZ3JvdXBzLmxlbmd0aD09PTApcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlscy5tZXJnZUdyb3VwcygpOiBObyBncm91cHMgYXJlIGRlZmluZWQuIE5vdGhpbmcgdG8gbWVyZ2UuIiksaTtsZXQgdD1pLmdyb3VwcztpZih0PXQuc29ydCgobyxhKT0+by5tYXRlcmlhbEluZGV4IT09YS5tYXRlcmlhbEluZGV4P28ubWF0ZXJpYWxJbmRleC1hLm1hdGVyaWFsSW5kZXg6by5zdGFydC1hLnN0YXJ0KSxpLmdldEluZGV4KCk9PT1udWxsKXtjb25zdCBvPWkuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLGE9W107Zm9yKGxldCBjPTA7YzxvLmNvdW50O2MrPTMpYS5wdXNoKGMsYysxLGMrMik7aS5zZXRJbmRleChhKX1jb25zdCBlPWkuZ2V0SW5kZXgoKSxuPVtdO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb10sYz1hLnN0YXJ0LGw9YythLmNvdW50O2ZvcihsZXQgaD1jO2g8bDtoKyspbi5wdXNoKGUuZ2V0WChoKSl9aS5kaXNwb3NlKCksaS5zZXRJbmRleChuKTtsZXQgcz0wO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb107YS5zdGFydD1zLHMrPWEuY291bnR9bGV0IHI9dFswXTtpLmdyb3Vwcz1bcl07Zm9yKGxldCBvPTE7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXTtyLm1hdGVyaWFsSW5kZXg9PT1hLm1hdGVyaWFsSW5kZXg/ci5jb3VudCs9YS5jb3VudDoocj1hLGkuZ3JvdXBzLnB1c2gocikpfXJldHVybiBpfWZ1bmN0aW9uIEpsKGksdD0wKXtjb25zdCBlPWlbMF0uaW5kZXghPT1udWxsLG49bmV3IFNldChPYmplY3Qua2V5cyhpWzBdLmF0dHJpYnV0ZXMpKSxzPW5ldyBTZXQoT2JqZWN0LmtleXMoaVswXS5tb3JwaEF0dHJpYnV0ZXMpKSxyPXt9LG89e30sYT1pWzBdLm1vcnBoVGFyZ2V0c1JlbGF0aXZlLGM9bmV3IHVlO2xldCBsPTA7Zm9yKGxldCBoPTA7aDxpLmxlbmd0aDsrK2gpe2NvbnN0IHU9aVtoXTtsZXQgZj0wO2lmKGUhPT0odS5pbmRleCE9PW51bGwpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIEFsbCBnZW9tZXRyaWVzIG11c3QgaGF2ZSBjb21wYXRpYmxlIGF0dHJpYnV0ZXM7IG1ha2Ugc3VyZSBpbmRleCBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1LmF0dHJpYnV0ZXMpe2lmKCFuLmhhcyhkKSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsnLiBBbGwgZ2VvbWV0cmllcyBtdXN0IGhhdmUgY29tcGF0aWJsZSBhdHRyaWJ1dGVzOyBtYWtlIHN1cmUgIicrZCsnIiBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uJyksbnVsbDtyW2RdPT09dm9pZCAwJiYocltkXT1bXSkscltkXS5wdXNoKHUuYXR0cmlidXRlc1tkXSksZisrfWlmKGYhPT1uLnNpemUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gTWFrZSBzdXJlIGFsbCBnZW9tZXRyaWVzIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihhIT09dS5tb3JwaFRhcmdldHNSZWxhdGl2ZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiAubW9ycGhUYXJnZXRzUmVsYXRpdmUgbXVzdCBiZSBjb25zaXN0ZW50IHRocm91Z2hvdXQgYWxsIGdlb21ldHJpZXMuIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1Lm1vcnBoQXR0cmlidXRlcyl7aWYoIXMuaGFzKGQpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuICAubW9ycGhBdHRyaWJ1dGVzIG11c3QgYmUgY29uc2lzdGVudCB0aHJvdWdob3V0IGFsbCBnZW9tZXRyaWVzLiIpLG51bGw7b1tkXT09PXZvaWQgMCYmKG9bZF09W10pLG9bZF0ucHVzaCh1Lm1vcnBoQXR0cmlidXRlc1tkXSl9aWYodCl7bGV0IGQ7aWYoZSlkPXUuaW5kZXguY291bnQ7ZWxzZSBpZih1LmF0dHJpYnV0ZXMucG9zaXRpb24hPT12b2lkIDApZD11LmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQ7ZWxzZSByZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiBUaGUgZ2VvbWV0cnkgbXVzdCBoYXZlIGVpdGhlciBhbiBpbmRleCBvciBhIHBvc2l0aW9uIGF0dHJpYnV0ZSIpLG51bGw7aWYodD09PTEpYy5hZGRHcm91cChsLGQsaCk7ZWxzZSBpZih0PT09MiYmdS5ncm91cHMubGVuZ3RoPjApZm9yKGxldCBwIG9mIHUuZ3JvdXBzKXtsZXQgeT1wLm1hdGVyaWFsSW5kZXg7Yy5hZGRHcm91cChsK3Auc3RhcnQsTWF0aC5taW4ocC5jb3VudCxkKSx5KX1sKz1kfX1pZihlKXtsZXQgaD0wO2NvbnN0IHU9W107Zm9yKGxldCBmPTA7ZjxpLmxlbmd0aDsrK2Ype2NvbnN0IGQ9aVtmXS5pbmRleDtmb3IobGV0IHA9MDtwPGQuY291bnQ7KytwKXUucHVzaChkLmdldFgocCkraCk7aCs9aVtmXS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWMuc2V0SW5kZXgodSl9Zm9yKGNvbnN0IGggaW4gcil7Y29uc3QgdT1YbChyW2hdKTtpZighdSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIGF0dHJpYnV0ZS4iKSxudWxsO2Muc2V0QXR0cmlidXRlKGgsdSl9Zm9yKGNvbnN0IGggaW4gbyl7Y29uc3QgdT1vW2hdWzBdLmxlbmd0aDtpZih1PT09MClicmVhaztjLm1vcnBoQXR0cmlidXRlcz1jLm1vcnBoQXR0cmlidXRlc3x8e30sYy5tb3JwaEF0dHJpYnV0ZXNbaF09W107Zm9yKGxldCBmPTA7Zjx1OysrZil7Y29uc3QgZD1bXTtmb3IobGV0IHk9MDt5PG9baF0ubGVuZ3RoOysreSlkLnB1c2gob1toXVt5XVtmXSk7Y29uc3QgcD1YbChkKTtpZighcClyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIG1vcnBoQXR0cmlidXRlLiIpLG51bGw7Yy5tb3JwaEF0dHJpYnV0ZXNbaF0ucHVzaChwKX19cmV0dXJuIHQ9PT0yP1owKGMpOmN9Y2xhc3MgWDAgZXh0ZW5kcyBHbntjb25zdHJ1Y3Rvcih0LGUpe3N1cGVyKHQsZSk7Y29uc3Qgbj1uZXcgWnMobmV3IEduKHQsWmUoRnQoe30sZSkse2hhc1RvcDohMCxoYXNTaWRlOiEwLGhhc0JvdHRvbTohMX0pKSk7bi51cGRhdGVNYXRyaXhXb3JsZCgpO2NvbnN0IHM9bmV3IGd0KCkuc2V0RnJvbU9iamVjdChuKSxyPW5ldyBUO3MuZ2V0U2l6ZShyKTtjb25zdCBvPW5ldyBUKHMubWluLngrci54LzIscy5taW4ueStyLnkvMiwwKTtsZXQgYT1lLnRvcFNlZ21lbnRzLGM9ZS5ib3gzO2lmKGMpe2M9Yy51bmlvbihzKTtjb25zdCBnPW5ldyBUO2MuZ2V0U2l6ZShnKTtjb25zdCBiPU1hdGgubWF4KHIueC9nLngsci55L2cueSk7YT1NYXRoLmNlaWwoZS50b3BTZWdtZW50cypiKX1pZihhPDQpcmV0dXJuIHRoaXM7Y29uc3QgbD1uZXcgTG8oci54LHIueSxhLGEpLGg9bmV3IFpzKGwpO2gucG9zaXRpb24uc2V0KG8ueCxvLnksby56KSxoLnVwZGF0ZU1hdHJpeFdvcmxkKCk7Y29uc3QgZj1uZXcgRzAoKS5ldmFsdWF0ZShoLG4sSWwpLGQ9Zi5nZW9tZXRyeS5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIikscD1uZXcgQmUoZC5jb3VudCoyLDIpO2ZvcihsZXQgZz0wO2c8ZC5jb3VudDtnKyspe2NvbnN0IGI9ZC5nZXRaKGcpO2Quc2V0WihnLGUuZGVwdGgrYil9aWYoYyl7Y29uc3QgZz1jLm1pbixiPWMubWF4LHc9bmV3IFQoKS5zdWJWZWN0b3JzKGIsZyk7Zm9yKGxldCB4PTA7eDxkLmNvdW50O3grKyl7Y29uc3QgTT1kLmdldFgoeCksQT1kLmdldFkoeCksUz0oTS1nLngpL3cueCxfPShBLWcueSkvdy55O3Auc2V0WFkoeCxTLF8pfWYuZ2VvbWV0cnkuc2V0QXR0cmlidXRlKCJ1diIscCl9ZC5uZWVkc1VwZGF0ZT0hMDtjb25zdCB5PW5ldyBHbih0LFplKEZ0KHt9LGUpLHtoYXNUb3A6ITF9KSksbT1KbChbZi5nZW9tZXRyeSx5XSwyKTt0aGlzLmNvcHkobS50b05vbkluZGV4ZWQoKSl9fXZhciBKMD1pPT57Y29uc3R7c3BsaXQ6dCxkZXB0aDplLHBvaW50czpuLGJveDM6cyxoYXNUb3A6cixoYXNCb3R0b206byxoYXNTaWRlOmEsc2lkZVJlcGVhdDpjLHRvcFNlZ21lbnRzOmx9PWksaD1sP1gwOkduLHU9bmV3IGgobmV3IFhjKG4pLHtkZXB0aDplLGJldmVsRW5hYmxlZDohMSxib3gzOnMsVVZHZW5lcmF0b3I6WWYoe3NwbGl0OnQsYm94MzpzLHNpZGVSZXBlYXQ6Y30pLGhhc1RvcDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSx0b3BTZWdtZW50czpsfSk7cmV0dXJuIGpmKCksdX07ZnVuY3Rpb24gWTAoaSx0LGU9MCl7Y29uc3Qgbj0oOTAtdCkqTWF0aC5QSS8xODAscz0oOTAtaSkqTWF0aC5QSS8xODA7cmV0dXJuW2UqTWF0aC5zaW4obikqTWF0aC5jb3MocyksZSpNYXRoLmNvcyhuKSxlKk1hdGguc2luKG4pKk1hdGguc2luKHMpXX1mdW5jdGlvbiBpcihpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjppPHQ/LTE6aT50PzE6aT49dD8wOk5hTn1mdW5jdGlvbiBqMChpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjp0PGk/LTE6dD5pPzE6dD49aT8wOk5hTn1mdW5jdGlvbiBZbChpKXtsZXQgdCxlLG47aS5sZW5ndGghPT0yPyh0PWlyLGU9KGEsYyk9PmlyKGkoYSksYyksbj0oYSxjKT0+aShhKS1jKToodD1pPT09aXJ8fGk9PT1qMD9pOlEwLGU9aSxuPWkpO2Z1bmN0aW9uIHMoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTwwP2w9dSsxOmg9dX13aGlsZShsPGgpfXJldHVybiBsfWZ1bmN0aW9uIHIoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTw9MD9sPXUrMTpoPXV9d2hpbGUobDxoKX1yZXR1cm4gbH1mdW5jdGlvbiBvKGEsYyxsPTAsaD1hLmxlbmd0aCl7Y29uc3QgdT1zKGEsYyxsLGgtMSk7cmV0dXJuIHU+bCYmbihhW3UtMV0sYyk+LW4oYVt1XSxjKT91LTE6dX1yZXR1cm57bGVmdDpzLGNlbnRlcjpvLHJpZ2h0OnJ9fWZ1bmN0aW9uIFEwKCl7cmV0dXJuIDB9ZnVuY3Rpb24gSzAoaSl7cmV0dXJuIGk9PT1udWxsP05hTjoraX1jb25zdCB0cD1ZbChpcikucmlnaHQ7WWwoSzApLmNlbnRlcjtmdW5jdGlvbiBzcihpLHQpe2xldCBlLG47aWYodD09PXZvaWQgMClmb3IoY29uc3QgcyBvZiBpKXMhPW51bGwmJihlPT09dm9pZCAwP3M+PXMmJihlPW49cyk6KGU+cyYmKGU9cyksbjxzJiYobj1zKSkpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihlPT09dm9pZCAwP3I+PXImJihlPW49cik6KGU+ciYmKGU9ciksbjxyJiYobj1yKSkpfXJldHVybltlLG5dfWNsYXNzIExle2NvbnN0cnVjdG9yKCl7dGhpcy5fcGFydGlhbHM9bmV3IEZsb2F0NjRBcnJheSgzMiksdGhpcy5fbj0wfWFkZCh0KXtjb25zdCBlPXRoaXMuX3BhcnRpYWxzO2xldCBuPTA7Zm9yKGxldCBzPTA7czx0aGlzLl9uJiZzPDMyO3MrKyl7Y29uc3Qgcj1lW3NdLG89dCtyLGE9TWF0aC5hYnModCk8TWF0aC5hYnMocik/dC0oby1yKTpyLShvLXQpO2EmJihlW24rK109YSksdD1vfXJldHVybiBlW25dPXQsdGhpcy5fbj1uKzEsdGhpc312YWx1ZU9mKCl7Y29uc3QgdD10aGlzLl9wYXJ0aWFscztsZXQgZT10aGlzLl9uLG4scyxyLG89MDtpZihlPjApe2ZvcihvPXRbLS1lXTtlPjAmJihuPW8scz10Wy0tZV0sbz1uK3Mscj1zLShvLW4pLCFyKTspO2U+MCYmKHI8MCYmdFtlLTFdPDB8fHI+MCYmdFtlLTFdPjApJiYocz1yKjIsbj1vK3Mscz09bi1vJiYobz1uKSl9cmV0dXJuIG99fWNvbnN0IGVwPU1hdGguc3FydCg1MCksbnA9TWF0aC5zcXJ0KDEwKSxpcD1NYXRoLnNxcnQoMik7ZnVuY3Rpb24gcnIoaSx0LGUpe2NvbnN0IG49KHQtaSkvTWF0aC5tYXgoMCxlKSxzPU1hdGguZmxvb3IoTWF0aC5sb2cxMChuKSkscj1uL01hdGgucG93KDEwLHMpLG89cj49ZXA/MTA6cj49bnA/NTpyPj1pcD8yOjE7bGV0IGEsYyxsO3JldHVybiBzPDA/KGw9TWF0aC5wb3coMTAsLXMpL28sYT1NYXRoLnJvdW5kKGkqbCksYz1NYXRoLnJvdW5kKHQqbCksYS9sPGkmJisrYSxjL2w+dCYmLS1jLGw9LWwpOihsPU1hdGgucG93KDEwLHMpKm8sYT1NYXRoLnJvdW5kKGkvbCksYz1NYXRoLnJvdW5kKHQvbCksYSpsPGkmJisrYSxjKmw+dCYmLS1jKSxjPGEmJi41PD1lJiZlPDI/cnIoaSx0LGUqMik6W2EsYyxsXX1mdW5jdGlvbiBzcChpLHQsZSl7aWYodD0rdCxpPStpLGU9K2UsIShlPjApKXJldHVybltdO2lmKGk9PT10KXJldHVybltpXTtjb25zdCBuPXQ8aSxbcyxyLG9dPW4/cnIodCxpLGUpOnJyKGksdCxlKTtpZighKHI+PXMpKXJldHVybltdO2NvbnN0IGE9ci1zKzEsYz1uZXcgQXJyYXkoYSk7aWYobilpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpKm87ZWxzZSBpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpKm87cmV0dXJuIGN9ZnVuY3Rpb24gQWEoaSx0LGUpe3JldHVybiB0PSt0LGk9K2ksZT0rZSxycihpLHQsZSlbMl19ZnVuY3Rpb24gcnAoaSx0LGUpe3Q9K3QsaT0raSxlPStlO2NvbnN0IG49dDxpLHM9bj9BYSh0LGksZSk6QWEoaSx0LGUpO3JldHVybihuPy0xOjEpKihzPDA/MS8tczpzKX1mdW5jdGlvbiBvcChpLHQpe2xldCBlPTAsbj0wO2lmKHQ9PT12b2lkIDApZm9yKGxldCBzIG9mIGkpcyE9bnVsbCYmKHM9K3MpPj1zJiYoKytlLG4rPXMpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihyPStyKT49ciYmKCsrZSxuKz1yKX1pZihlKXJldHVybiBuL2V9ZnVuY3Rpb24qYXAoaSl7Zm9yKGNvbnN0IHQgb2YgaSl5aWVsZCpZdSh0KX1mdW5jdGlvbiBWaShpKXtyZXR1cm4gQXJyYXkuZnJvbShhcChpKSl9dmFyIEs9MWUtNixvcj0xZS0xMixYPU1hdGguUEksTnQ9WC8yLGFyPVgvNCxSdD1YKjIsaHQ9MTgwL1gsSD1YLzE4MCx0dD1NYXRoLmFicyxTYT1NYXRoLmF0YW4scmU9TWF0aC5hdGFuMixXPU1hdGguY29zLGNwPU1hdGguZXhwLF9hPU1hdGguaHlwb3QsbHA9TWF0aC5sb2cscT1NYXRoLnNpbixocD1NYXRoLnNpZ258fGZ1bmN0aW9uKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH0sT2U9TWF0aC5zcXJ0LHVwPU1hdGgudGFuO2Z1bmN0aW9uIGZwKGkpe3JldHVybiBpPjE/MDppPC0xP1g6TWF0aC5hY29zKGkpfWZ1bmN0aW9uIERlKGkpe3JldHVybiBpPjE/TnQ6aTwtMT8tTnQ6TWF0aC5hc2luKGkpfWZ1bmN0aW9uIGpsKGkpe3JldHVybihpPXEoaS8yKSkqaX1mdW5jdGlvbiBfdCgpe31mdW5jdGlvbiBjcihpLHQpe2kmJktsLmhhc093blByb3BlcnR5KGkudHlwZSkmJktsW2kudHlwZV0oaSx0KX12YXIgUWw9e0ZlYXR1cmU6ZnVuY3Rpb24oaSx0KXtjcihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspY3IoZVtuXS5nZW9tZXRyeSx0KX19LEtsPXtTcGhlcmU6ZnVuY3Rpb24oaSx0KXt0LnNwaGVyZSgpfSxQb2ludDpmdW5jdGlvbihpLHQpe2k9aS5jb29yZGluYXRlcyx0LnBvaW50KGlbMF0saVsxXSxpWzJdKX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaT1lW25dLHQucG9pbnQoaVswXSxpWzFdLGlbMl0pfSxMaW5lU3RyaW5nOmZ1bmN0aW9uKGksdCl7dmEoaS5jb29yZGluYXRlcyx0LDApfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KXZhKGVbbl0sdCwwKX0sUG9seWdvbjpmdW5jdGlvbihpLHQpe3RoKGkuY29vcmRpbmF0ZXMsdCl9LE11bHRpUG9seWdvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspdGgoZVtuXSx0KX0sR2VvbWV0cnlDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZ2VvbWV0cmllcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWNyKGVbbl0sdCl9fTtmdW5jdGlvbiB2YShpLHQsZSl7dmFyIG49LTEscz1pLmxlbmd0aC1lLHI7Zm9yKHQubGluZVN0YXJ0KCk7KytuPHM7KXI9aVtuXSx0LnBvaW50KHJbMF0sclsxXSxyWzJdKTt0LmxpbmVFbmQoKX1mdW5jdGlvbiB0aChpLHQpe3ZhciBlPS0xLG49aS5sZW5ndGg7Zm9yKHQucG9seWdvblN0YXJ0KCk7KytlPG47KXZhKGlbZV0sdCwxKTt0LnBvbHlnb25FbmQoKX1mdW5jdGlvbiBscihpLHQpe2kmJlFsLmhhc093blByb3BlcnR5KGkudHlwZSk/UWxbaS50eXBlXShpLHQpOmNyKGksdCl9dmFyIGhyPW5ldyBMZSxlaD1uZXcgTGUsbmgsaWgsemEsVGEsRWEsJGU9e3BvaW50Ol90LGxpbmVTdGFydDpfdCxsaW5lRW5kOl90LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2hyPW5ldyBMZSwkZS5saW5lU3RhcnQ9ZHAsJGUubGluZUVuZD1wcH0scG9seWdvbkVuZDpmdW5jdGlvbigpe3ZhciBpPStocjtlaC5hZGQoaTwwP1J0K2k6aSksdGhpcy5saW5lU3RhcnQ9dGhpcy5saW5lRW5kPXRoaXMucG9pbnQ9X3R9LHNwaGVyZTpmdW5jdGlvbigpe2VoLmFkZChSdCl9fTtmdW5jdGlvbiBkcCgpeyRlLnBvaW50PXlwfWZ1bmN0aW9uIHBwKCl7c2gobmgsaWgpfWZ1bmN0aW9uIHlwKGksdCl7JGUucG9pbnQ9c2gsbmg9aSxpaD10LGkqPUgsdCo9SCx6YT1pLFRhPVcodD10LzIrYXIpLEVhPXEodCl9ZnVuY3Rpb24gc2goaSx0KXtpKj1ILHQqPUgsdD10LzIrYXI7dmFyIGU9aS16YSxuPWU+PTA/MTotMSxzPW4qZSxyPVcodCksbz1xKHQpLGE9RWEqbyxjPVRhKnIrYSpXKHMpLGw9YSpuKnEocyk7aHIuYWRkKHJlKGwsYykpLHphPWksVGE9cixFYT1vfWZ1bmN0aW9uIHVyKGkpe3JldHVybltyZShpWzFdLGlbMF0pLERlKGlbMl0pXX1mdW5jdGlvbiBTbihpKXt2YXIgdD1pWzBdLGU9aVsxXSxuPVcoZSk7cmV0dXJuW24qVyh0KSxuKnEodCkscShlKV19ZnVuY3Rpb24gZnIoaSx0KXtyZXR1cm4gaVswXSp0WzBdK2lbMV0qdFsxXStpWzJdKnRbMl19ZnVuY3Rpb24gbmkoaSx0KXtyZXR1cm5baVsxXSp0WzJdLWlbMl0qdFsxXSxpWzJdKnRbMF0taVswXSp0WzJdLGlbMF0qdFsxXS1pWzFdKnRbMF1dfWZ1bmN0aW9uIFBhKGksdCl7aVswXSs9dFswXSxpWzFdKz10WzFdLGlbMl0rPXRbMl19ZnVuY3Rpb24gZHIoaSx0KXtyZXR1cm5baVswXSp0LGlbMV0qdCxpWzJdKnRdfWZ1bmN0aW9uIHByKGkpe3ZhciB0PU9lKGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtpWzBdLz10LGlbMV0vPXQsaVsyXS89dH12YXIgb3QsTHQsdXQscXQsX24scmgsb2gsaWksVWksYW4sVmUsVWU9e3BvaW50OkNhLGxpbmVTdGFydDpjaCxsaW5lRW5kOmxoLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe1VlLnBvaW50PWhoLFVlLmxpbmVTdGFydD1tcCxVZS5saW5lRW5kPWdwLFVpPW5ldyBMZSwkZS5wb2x5Z29uU3RhcnQoKX0scG9seWdvbkVuZDpmdW5jdGlvbigpeyRlLnBvbHlnb25FbmQoKSxVZS5wb2ludD1DYSxVZS5saW5lU3RhcnQ9Y2gsVWUubGluZUVuZD1saCxocjwwPyhvdD0tKHV0PTE4MCksTHQ9LShxdD05MCkpOlVpPks/cXQ9OTA6VWk8LUsmJihMdD0tOTApLFZlWzBdPW90LFZlWzFdPXV0fSxzcGhlcmU6ZnVuY3Rpb24oKXtvdD0tKHV0PTE4MCksTHQ9LShxdD05MCl9fTtmdW5jdGlvbiBDYShpLHQpe2FuLnB1c2goVmU9W290PWksdXQ9aV0pLHQ8THQmJihMdD10KSx0PnF0JiYocXQ9dCl9ZnVuY3Rpb24gYWgoaSx0KXt2YXIgZT1TbihbaSpILHQqSF0pO2lmKGlpKXt2YXIgbj1uaShpaSxlKSxzPVtuWzFdLC1uWzBdLDBdLHI9bmkocyxuKTtwcihyKSxyPXVyKHIpO3ZhciBvPWktX24sYT1vPjA/MTotMSxjPXJbMF0qaHQqYSxsLGg9dHQobyk+MTgwO2heKGEqX248YyYmYzxhKmkpPyhsPXJbMV0qaHQsbD5xdCYmKHF0PWwpKTooYz0oYyszNjApJTM2MC0xODAsaF4oYSpfbjxjJiZjPGEqaSk/KGw9LXJbMV0qaHQsbDxMdCYmKEx0PWwpKToodDxMdCYmKEx0PXQpLHQ+cXQmJihxdD10KSkpLGg/aTxfbj9IdChvdCxpKT5IdChvdCx1dCkmJih1dD1pKTpIdChpLHV0KT5IdChvdCx1dCkmJihvdD1pKTp1dD49b3Q/KGk8b3QmJihvdD1pKSxpPnV0JiYodXQ9aSkpOmk+X24/SHQob3QsaSk+SHQob3QsdXQpJiYodXQ9aSk6SHQoaSx1dCk+SHQob3QsdXQpJiYob3Q9aSl9ZWxzZSBhbi5wdXNoKFZlPVtvdD1pLHV0PWldKTt0PEx0JiYoTHQ9dCksdD5xdCYmKHF0PXQpLGlpPWUsX249aX1mdW5jdGlvbiBjaCgpe1VlLnBvaW50PWFofWZ1bmN0aW9uIGxoKCl7VmVbMF09b3QsVmVbMV09dXQsVWUucG9pbnQ9Q2EsaWk9bnVsbH1mdW5jdGlvbiBoaChpLHQpe2lmKGlpKXt2YXIgZT1pLV9uO1VpLmFkZCh0dChlKT4xODA/ZSsoZT4wPzM2MDotMzYwKTplKX1lbHNlIHJoPWksb2g9dDskZS5wb2ludChpLHQpLGFoKGksdCl9ZnVuY3Rpb24gbXAoKXskZS5saW5lU3RhcnQoKX1mdW5jdGlvbiBncCgpe2hoKHJoLG9oKSwkZS5saW5lRW5kKCksdHQoVWkpPksmJihvdD0tKHV0PTE4MCkpLFZlWzBdPW90LFZlWzFdPXV0LGlpPW51bGx9ZnVuY3Rpb24gSHQoaSx0KXtyZXR1cm4odC09aSk8MD90KzM2MDp0fWZ1bmN0aW9uIHhwKGksdCl7cmV0dXJuIGlbMF0tdFswXX1mdW5jdGlvbiB1aChpLHQpe3JldHVybiBpWzBdPD1pWzFdP2lbMF08PXQmJnQ8PWlbMV06dDxpWzBdfHxpWzFdPHR9ZnVuY3Rpb24gZmgoaSl7dmFyIHQsZSxuLHMscixvLGE7aWYocXQ9dXQ9LShvdD1MdD0xLzApLGFuPVtdLGxyKGksVWUpLGU9YW4ubGVuZ3RoKXtmb3IoYW4uc29ydCh4cCksdD0xLG49YW5bMF0scj1bbl07dDxlOysrdClzPWFuW3RdLHVoKG4sc1swXSl8fHVoKG4sc1sxXSk/KEh0KG5bMF0sc1sxXSk+SHQoblswXSxuWzFdKSYmKG5bMV09c1sxXSksSHQoc1swXSxuWzFdKT5IdChuWzBdLG5bMV0pJiYoblswXT1zWzBdKSk6ci5wdXNoKG49cyk7Zm9yKG89LTEvMCxlPXIubGVuZ3RoLTEsdD0wLG49cltlXTt0PD1lO249cywrK3Qpcz1yW3RdLChhPUh0KG5bMV0sc1swXSkpPm8mJihvPWEsb3Q9c1swXSx1dD1uWzFdKX1yZXR1cm4gYW49VmU9bnVsbCxvdD09PTEvMHx8THQ9PT0xLzA/W1tOYU4sTmFOXSxbTmFOLE5hTl1dOltbb3QsTHRdLFt1dCxxdF1dfXZhciBxaSx5cixtcixncix4cix3cixicixNcixCYSxGYSxJYSxkaCxwaCxFdCxQdCxDdCxwZT17c3BoZXJlOl90LHBvaW50OmthLGxpbmVTdGFydDp5aCxsaW5lRW5kOm1oLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe3BlLmxpbmVTdGFydD1NcCxwZS5saW5lRW5kPUFwfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7cGUubGluZVN0YXJ0PXloLHBlLmxpbmVFbmQ9bWh9fTtmdW5jdGlvbiBrYShpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO0hpKGUqVyhpKSxlKnEoaSkscSh0KSl9ZnVuY3Rpb24gSGkoaSx0LGUpeysrcWksbXIrPShpLW1yKS9xaSxncis9KHQtZ3IpL3FpLHhyKz0oZS14cikvcWl9ZnVuY3Rpb24geWgoKXtwZS5wb2ludD13cH1mdW5jdGlvbiB3cChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO0V0PWUqVyhpKSxQdD1lKnEoaSksQ3Q9cSh0KSxwZS5wb2ludD1icCxIaShFdCxQdCxDdCl9ZnVuY3Rpb24gYnAoaSx0KXtpKj1ILHQqPUg7dmFyIGU9Vyh0KSxuPWUqVyhpKSxzPWUqcShpKSxyPXEodCksbz1yZShPZSgobz1QdCpyLUN0KnMpKm8rKG89Q3Qqbi1FdCpyKSpvKyhvPUV0KnMtUHQqbikqbyksRXQqbitQdCpzK0N0KnIpO3lyKz1vLHdyKz1vKihFdCsoRXQ9bikpLGJyKz1vKihQdCsoUHQ9cykpLE1yKz1vKihDdCsoQ3Q9cikpLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiBtaCgpe3BlLnBvaW50PWthfWZ1bmN0aW9uIE1wKCl7cGUucG9pbnQ9U3B9ZnVuY3Rpb24gQXAoKXtnaChkaCxwaCkscGUucG9pbnQ9a2F9ZnVuY3Rpb24gU3AoaSx0KXtkaD1pLHBoPXQsaSo9SCx0Kj1ILHBlLnBvaW50PWdoO3ZhciBlPVcodCk7RXQ9ZSpXKGkpLFB0PWUqcShpKSxDdD1xKHQpLEhpKEV0LFB0LEN0KX1mdW5jdGlvbiBnaChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpLG49ZSpXKGkpLHM9ZSpxKGkpLHI9cSh0KSxvPVB0KnItQ3QqcyxhPUN0Km4tRXQqcixjPUV0KnMtUHQqbixsPV9hKG8sYSxjKSxoPURlKGwpLHU9bCYmLWgvbDtCYS5hZGQodSpvKSxGYS5hZGQodSphKSxJYS5hZGQodSpjKSx5cis9aCx3cis9aCooRXQrKEV0PW4pKSxicis9aCooUHQrKFB0PXMpKSxNcis9aCooQ3QrKEN0PXIpKSxIaShFdCxQdCxDdCl9ZnVuY3Rpb24geGgoaSl7cWk9eXI9bXI9Z3I9eHI9d3I9YnI9TXI9MCxCYT1uZXcgTGUsRmE9bmV3IExlLElhPW5ldyBMZSxscihpLHBlKTt2YXIgdD0rQmEsZT0rRmEsbj0rSWEscz1fYSh0LGUsbik7cmV0dXJuIHM8b3ImJih0PXdyLGU9YnIsbj1Ncix5cjxLJiYodD1tcixlPWdyLG49eHIpLHM9X2EodCxlLG4pLHM8b3IpP1tOYU4sTmFOXTpbcmUoZSx0KSpodCxEZShuL3MpKmh0XX1mdW5jdGlvbiBOYShpLHQpe2Z1bmN0aW9uIGUobixzKXtyZXR1cm4gbj1pKG4scyksdChuWzBdLG5bMV0pfXJldHVybiBpLmludmVydCYmdC5pbnZlcnQmJihlLmludmVydD1mdW5jdGlvbihuLHMpe3JldHVybiBuPXQuaW52ZXJ0KG4scyksbiYmaS5pbnZlcnQoblswXSxuWzFdKX0pLGV9ZnVuY3Rpb24gUmEoaSx0KXtyZXR1cm4gdHQoaSk+WCYmKGktPU1hdGgucm91bmQoaS9SdCkqUnQpLFtpLHRdfVJhLmludmVydD1SYTtmdW5jdGlvbiB3aChpLHQsZSl7cmV0dXJuKGklPVJ0KT90fHxlP05hKE1oKGkpLEFoKHQsZSkpOk1oKGkpOnR8fGU/QWgodCxlKTpSYX1mdW5jdGlvbiBiaChpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdCs9aSx0dCh0KT5YJiYodC09TWF0aC5yb3VuZCh0L1J0KSpSdCksW3QsZV19fWZ1bmN0aW9uIE1oKGkpe3ZhciB0PWJoKGkpO3JldHVybiB0LmludmVydD1iaCgtaSksdH1mdW5jdGlvbiBBaChpLHQpe3ZhciBlPVcoaSksbj1xKGkpLHM9Vyh0KSxyPXEodCk7ZnVuY3Rpb24gbyhhLGMpe3ZhciBsPVcoYyksaD1XKGEpKmwsdT1xKGEpKmwsZj1xKGMpLGQ9ZiplK2gqbjtyZXR1cm5bcmUodSpzLWQqcixoKmUtZipuKSxEZShkKnMrdSpyKV19cmV0dXJuIG8uaW52ZXJ0PWZ1bmN0aW9uKGEsYyl7dmFyIGw9VyhjKSxoPVcoYSkqbCx1PXEoYSkqbCxmPXEoYyksZD1mKnMtdSpyO3JldHVybltyZSh1KnMrZipyLGgqZStkKm4pLERlKGQqZS1oKm4pXX0sb31mdW5jdGlvbiBTaChpKXtpPXdoKGlbMF0qSCxpWzFdKkgsaS5sZW5ndGg+Mj9pWzJdKkg6MCk7ZnVuY3Rpb24gdChlKXtyZXR1cm4gZT1pKGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9cmV0dXJuIHQuaW52ZXJ0PWZ1bmN0aW9uKGUpe3JldHVybiBlPWkuaW52ZXJ0KGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9LHR9ZnVuY3Rpb24gX3AoaSx0LGUsbixzLHIpe2lmKGUpe3ZhciBvPVcodCksYT1xKHQpLGM9biplO3M9PW51bGw/KHM9dCtuKlJ0LHI9dC1jLzIpOihzPV9oKG8scykscj1faChvLHIpLChuPjA/czxyOnM+cikmJihzKz1uKlJ0KSk7Zm9yKHZhciBsLGg9cztuPjA/aD5yOmg8cjtoLT1jKWw9dXIoW28sLWEqVyhoKSwtYSpxKGgpXSksaS5wb2ludChsWzBdLGxbMV0pfX1mdW5jdGlvbiBfaChpLHQpe3Q9U24odCksdFswXS09aSxwcih0KTt2YXIgZT1mcCgtdFsxXSk7cmV0dXJuKCgtdFsyXTwwPy1lOmUpK1J0LUspJVJ0fWZ1bmN0aW9uIHZoKCl7dmFyIGk9W10sdDtyZXR1cm57cG9pbnQ6ZnVuY3Rpb24oZSxuLHMpe3QucHVzaChbZSxuLHNdKX0sbGluZVN0YXJ0OmZ1bmN0aW9uKCl7aS5wdXNoKHQ9W10pfSxsaW5lRW5kOl90LHJlam9pbjpmdW5jdGlvbigpe2kubGVuZ3RoPjEmJmkucHVzaChpLnBvcCgpLmNvbmNhdChpLnNoaWZ0KCkpKX0scmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGU9aTtyZXR1cm4gaT1bXSx0PW51bGwsZX19fWZ1bmN0aW9uIEFyKGksdCl7cmV0dXJuIHR0KGlbMF0tdFswXSk8SyYmdHQoaVsxXS10WzFdKTxLfWZ1bmN0aW9uIFNyKGksdCxlLG4pe3RoaXMueD1pLHRoaXMuej10LHRoaXMubz1lLHRoaXMuZT1uLHRoaXMudj0hMSx0aGlzLm49dGhpcy5wPW51bGx9ZnVuY3Rpb24gemgoaSx0LGUsbixzKXt2YXIgcj1bXSxvPVtdLGEsYztpZihpLmZvckVhY2goZnVuY3Rpb24ocCl7aWYoISgoeT1wLmxlbmd0aC0xKTw9MCkpe3ZhciB5LG09cFswXSxnPXBbeV0sYjtpZihBcihtLGcpKXtpZighbVsyXSYmIWdbMl0pe2ZvcihzLmxpbmVTdGFydCgpLGE9MDthPHk7KythKXMucG9pbnQoKG09cFthXSlbMF0sbVsxXSk7cy5saW5lRW5kKCk7cmV0dXJufWdbMF0rPTIqS31yLnB1c2goYj1uZXcgU3IobSxwLG51bGwsITApKSxvLnB1c2goYi5vPW5ldyBTcihtLG51bGwsYiwhMSkpLHIucHVzaChiPW5ldyBTcihnLHAsbnVsbCwhMSkpLG8ucHVzaChiLm89bmV3IFNyKGcsbnVsbCxiLCEwKSl9fSksISFyLmxlbmd0aCl7Zm9yKG8uc29ydCh0KSxUaChyKSxUaChvKSxhPTAsYz1vLmxlbmd0aDthPGM7KythKW9bYV0uZT1lPSFlO2Zvcih2YXIgbD1yWzBdLGgsdTs7KXtmb3IodmFyIGY9bCxkPSEwO2YudjspaWYoKGY9Zi5uKT09PWwpcmV0dXJuO2g9Zi56LHMubGluZVN0YXJ0KCk7ZG97aWYoZi52PWYuby52PSEwLGYuZSl7aWYoZClmb3IoYT0wLGM9aC5sZW5ndGg7YTxjOysrYSlzLnBvaW50KCh1PWhbYV0pWzBdLHVbMV0pO2Vsc2UgbihmLngsZi5uLngsMSxzKTtmPWYubn1lbHNle2lmKGQpZm9yKGg9Zi5wLnosYT1oLmxlbmd0aC0xO2E+PTA7LS1hKXMucG9pbnQoKHU9aFthXSlbMF0sdVsxXSk7ZWxzZSBuKGYueCxmLnAueCwtMSxzKTtmPWYucH1mPWYubyxoPWYueixkPSFkfXdoaWxlKCFmLnYpO3MubGluZUVuZCgpfX19ZnVuY3Rpb24gVGgoaSl7aWYodD1pLmxlbmd0aCl7Zm9yKHZhciB0LGU9MCxuPWlbMF0sczsrK2U8dDspbi5uPXM9aVtlXSxzLnA9bixuPXM7bi5uPXM9aVswXSxzLnA9bn19ZnVuY3Rpb24gTGEoaSl7cmV0dXJuIHR0KGlbMF0pPD1YP2lbMF06aHAoaVswXSkqKCh0dChpWzBdKStYKSVSdC1YKX1mdW5jdGlvbiBFaChpLHQpe3ZhciBlPUxhKHQpLG49dFsxXSxzPXEobikscj1bcShlKSwtVyhlKSwwXSxvPTAsYT0wLGM9bmV3IExlO3M9PT0xP249TnQrSzpzPT09LTEmJihuPS1OdC1LKTtmb3IodmFyIGw9MCxoPWkubGVuZ3RoO2w8aDsrK2wpaWYoZj0odT1pW2xdKS5sZW5ndGgpZm9yKHZhciB1LGYsZD11W2YtMV0scD1MYShkKSx5PWRbMV0vMithcixtPXEoeSksZz1XKHkpLGI9MDtiPGY7KytiLHA9eCxtPUEsZz1TLGQ9dyl7dmFyIHc9dVtiXSx4PUxhKHcpLE09d1sxXS8yK2FyLEE9cShNKSxTPVcoTSksXz14LXAsRT1fPj0wPzE6LTEsej1FKl8sdj16PlgsQz1tKkE7aWYoYy5hZGQocmUoQypFKnEoeiksZypTK0MqVyh6KSkpLG8rPXY/XytFKlJ0Ol8sdl5wPj1lXng+PWUpe3ZhciBQPW5pKFNuKGQpLFNuKHcpKTtwcihQKTt2YXIgRj1uaShyLFApO3ByKEYpO3ZhciBCPSh2Xl8+PTA/LTE6MSkqRGUoRlsyXSk7KG4+Qnx8bj09PUImJihQWzBdfHxQWzFdKSkmJihhKz12Xl8+PTA/MTotMSl9fXJldHVybihvPC1LfHxvPEsmJmM8LW9yKV5hJjF9ZnVuY3Rpb24gUGgoaSx0LGUsbil7cmV0dXJuIGZ1bmN0aW9uKHMpe3ZhciByPXQocyksbz12aCgpLGE9dChvKSxjPSExLGwsaCx1LGY9e3BvaW50OmQsbGluZVN0YXJ0OnksbGluZUVuZDptLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2YucG9pbnQ9ZyxmLmxpbmVTdGFydD1iLGYubGluZUVuZD13LGg9W10sbD1bXX0scG9seWdvbkVuZDpmdW5jdGlvbigpe2YucG9pbnQ9ZCxmLmxpbmVTdGFydD15LGYubGluZUVuZD1tLGg9VmkoaCk7dmFyIHg9RWgobCxuKTtoLmxlbmd0aD8oY3x8KHMucG9seWdvblN0YXJ0KCksYz0hMCksemgoaCx6cCx4LGUscykpOngmJihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkpLGMmJihzLnBvbHlnb25FbmQoKSxjPSExKSxoPWw9bnVsbH0sc3BoZXJlOmZ1bmN0aW9uKCl7cy5wb2x5Z29uU3RhcnQoKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkscy5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBkKHgsTSl7aSh4LE0pJiZzLnBvaW50KHgsTSl9ZnVuY3Rpb24gcCh4LE0pe3IucG9pbnQoeCxNKX1mdW5jdGlvbiB5KCl7Zi5wb2ludD1wLHIubGluZVN0YXJ0KCl9ZnVuY3Rpb24gbSgpe2YucG9pbnQ9ZCxyLmxpbmVFbmQoKX1mdW5jdGlvbiBnKHgsTSl7dS5wdXNoKFt4LE1dKSxhLnBvaW50KHgsTSl9ZnVuY3Rpb24gYigpe2EubGluZVN0YXJ0KCksdT1bXX1mdW5jdGlvbiB3KCl7Zyh1WzBdWzBdLHVbMF1bMV0pLGEubGluZUVuZCgpO3ZhciB4PWEuY2xlYW4oKSxNPW8ucmVzdWx0KCksQSxTPU0ubGVuZ3RoLF8sRSx6O2lmKHUucG9wKCksbC5wdXNoKHUpLHU9bnVsbCwhIVMpe2lmKHgmMSl7aWYoRT1NWzBdLChfPUUubGVuZ3RoLTEpPjApe2ZvcihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLEE9MDtBPF87KytBKXMucG9pbnQoKHo9RVtBXSlbMF0selsxXSk7cy5saW5lRW5kKCl9cmV0dXJufVM+MSYmeCYyJiZNLnB1c2goTS5wb3AoKS5jb25jYXQoTS5zaGlmdCgpKSksaC5wdXNoKE0uZmlsdGVyKHZwKSl9fXJldHVybiBmfX1mdW5jdGlvbiB2cChpKXtyZXR1cm4gaS5sZW5ndGg+MX1mdW5jdGlvbiB6cChpLHQpe3JldHVybigoaT1pLngpWzBdPDA/aVsxXS1OdC1LOk50LWlbMV0pLSgodD10LngpWzBdPDA/dFsxXS1OdC1LOk50LXRbMV0pfXZhciBDaD1QaChmdW5jdGlvbigpe3JldHVybiEwfSxUcCxQcCxbLVgsLU50XSk7ZnVuY3Rpb24gVHAoaSl7dmFyIHQ9TmFOLGU9TmFOLG49TmFOLHM7cmV0dXJue2xpbmVTdGFydDpmdW5jdGlvbigpe2kubGluZVN0YXJ0KCkscz0xfSxwb2ludDpmdW5jdGlvbihyLG8pe3ZhciBhPXI+MD9YOi1YLGM9dHQoci10KTt0dChjLVgpPEs/KGkucG9pbnQodCxlPShlK28pLzI+MD9OdDotTnQpLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxpLnBvaW50KHIsZSkscz0wKTpuIT09YSYmYz49WCYmKHR0KHQtbik8SyYmKHQtPW4qSyksdHQoci1hKTxLJiYoci09YSpLKSxlPUVwKHQsZSxyLG8pLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxzPTApLGkucG9pbnQodD1yLGU9byksbj1hfSxsaW5lRW5kOmZ1bmN0aW9uKCl7aS5saW5lRW5kKCksdD1lPU5hTn0sY2xlYW46ZnVuY3Rpb24oKXtyZXR1cm4gMi1zfX19ZnVuY3Rpb24gRXAoaSx0LGUsbil7dmFyIHMscixvPXEoaS1lKTtyZXR1cm4gdHQobyk+Sz9TYSgocSh0KSoocj1XKG4pKSpxKGUpLXEobikqKHM9Vyh0KSkqcShpKSkvKHMqcipvKSk6KHQrbikvMn1mdW5jdGlvbiBQcChpLHQsZSxuKXt2YXIgcztpZihpPT1udWxsKXM9ZSpOdCxuLnBvaW50KC1YLHMpLG4ucG9pbnQoMCxzKSxuLnBvaW50KFgscyksbi5wb2ludChYLDApLG4ucG9pbnQoWCwtcyksbi5wb2ludCgwLC1zKSxuLnBvaW50KC1YLC1zKSxuLnBvaW50KC1YLDApLG4ucG9pbnQoLVgscyk7ZWxzZSBpZih0dChpWzBdLXRbMF0pPkspe3ZhciByPWlbMF08dFswXT9YOi1YO3M9ZSpyLzIsbi5wb2ludCgtcixzKSxuLnBvaW50KDAscyksbi5wb2ludChyLHMpfWVsc2Ugbi5wb2ludCh0WzBdLHRbMV0pfWZ1bmN0aW9uIENwKGkpe3ZhciB0PVcoaSksZT0yKkgsbj10PjAscz10dCh0KT5LO2Z1bmN0aW9uIHIoaCx1LGYsZCl7X3AoZCxpLGUsZixoLHUpfWZ1bmN0aW9uIG8oaCx1KXtyZXR1cm4gVyhoKSpXKHUpPnR9ZnVuY3Rpb24gYShoKXt2YXIgdSxmLGQscCx5O3JldHVybntsaW5lU3RhcnQ6ZnVuY3Rpb24oKXtwPWQ9ITEseT0xfSxwb2ludDpmdW5jdGlvbihtLGcpe3ZhciBiPVttLGddLHcseD1vKG0sZyksTT1uP3g/MDpsKG0sZyk6eD9sKG0rKG08MD9YOi1YKSxnKTowO2lmKCF1JiYocD1kPXgpJiZoLmxpbmVTdGFydCgpLHghPT1kJiYodz1jKHUsYiksKCF3fHxBcih1LHcpfHxBcihiLHcpKSYmKGJbMl09MSkpLHghPT1kKXk9MCx4PyhoLmxpbmVTdGFydCgpLHc9YyhiLHUpLGgucG9pbnQod1swXSx3WzFdKSk6KHc9Yyh1LGIpLGgucG9pbnQod1swXSx3WzFdLDIpLGgubGluZUVuZCgpKSx1PXc7ZWxzZSBpZihzJiZ1JiZuXngpe3ZhciBBOyEoTSZmKSYmKEE9YyhiLHUsITApKSYmKHk9MCxuPyhoLmxpbmVTdGFydCgpLGgucG9pbnQoQVswXVswXSxBWzBdWzFdKSxoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCkpOihoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCksaC5saW5lU3RhcnQoKSxoLnBvaW50KEFbMF1bMF0sQVswXVsxXSwzKSkpfXgmJighdXx8IUFyKHUsYikpJiZoLnBvaW50KGJbMF0sYlsxXSksdT1iLGQ9eCxmPU19LGxpbmVFbmQ6ZnVuY3Rpb24oKXtkJiZoLmxpbmVFbmQoKSx1PW51bGx9LGNsZWFuOmZ1bmN0aW9uKCl7cmV0dXJuIHl8KHAmJmQpPDwxfX19ZnVuY3Rpb24gYyhoLHUsZil7dmFyIGQ9U24oaCkscD1Tbih1KSx5PVsxLDAsMF0sbT1uaShkLHApLGc9ZnIobSxtKSxiPW1bMF0sdz1nLWIqYjtpZighdylyZXR1cm4hZiYmaDt2YXIgeD10KmcvdyxNPS10KmIvdyxBPW5pKHksbSksUz1kcih5LHgpLF89ZHIobSxNKTtQYShTLF8pO3ZhciBFPUEsej1mcihTLEUpLHY9ZnIoRSxFKSxDPXoqei12KihmcihTLFMpLTEpO2lmKCEoQzwwKSl7dmFyIFA9T2UoQyksRj1kcihFLCgtei1QKS92KTtpZihQYShGLFMpLEY9dXIoRiksIWYpcmV0dXJuIEY7dmFyIEI9aFswXSxJPXVbMF0saz1oWzFdLEQ9dVsxXSxVO0k8QiYmKFU9QixCPUksST1VKTt2YXIgaj1JLUIsZHQ9dHQoai1YKTxLLER0PWR0fHxqPEs7aWYoIWR0JiZEPGsmJihVPWssaz1ELEQ9VSksRHQ/ZHQ/aytEPjBeRlsxXTwodHQoRlswXS1CKTxLP2s6RCk6azw9RlsxXSYmRlsxXTw9RDpqPlheKEI8PUZbMF0mJkZbMF08PUkpKXt2YXIgR3Q9ZHIoRSwoLXorUCkvdik7cmV0dXJuIFBhKEd0LFMpLFtGLHVyKEd0KV19fX1mdW5jdGlvbiBsKGgsdSl7dmFyIGY9bj9pOlgtaSxkPTA7cmV0dXJuIGg8LWY/ZHw9MTpoPmYmJihkfD0yKSx1PC1mP2R8PTQ6dT5mJiYoZHw9OCksZH1yZXR1cm4gUGgobyxhLHIsbj9bMCwtaV06Wy1YLGktWF0pfWZ1bmN0aW9uIEJwKGksdCxlLG4scyxyKXt2YXIgbz1pWzBdLGE9aVsxXSxjPXRbMF0sbD10WzFdLGg9MCx1PTEsZj1jLW8sZD1sLWEscDtpZihwPWUtbywhKCFmJiZwPjApKXtpZihwLz1mLGY8MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWVsc2UgaWYoZj4wKXtpZihwPnUpcmV0dXJuO3A+aCYmKGg9cCl9aWYocD1zLW8sISghZiYmcDwwKSl7aWYocC89ZixmPDApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1lbHNlIGlmKGY+MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWlmKHA9bi1hLCEoIWQmJnA+MCkpe2lmKHAvPWQsZDwwKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9ZWxzZSBpZihkPjApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1pZihwPXItYSwhKCFkJiZwPDApKXtpZihwLz1kLGQ8MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWVsc2UgaWYoZD4wKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9cmV0dXJuIGg+MCYmKGlbMF09bytoKmYsaVsxXT1hK2gqZCksdTwxJiYodFswXT1vK3UqZix0WzFdPWErdSpkKSwhMH19fX19dmFyIFdpPTFlOSxfcj0tV2k7ZnVuY3Rpb24gRnAoaSx0LGUsbil7ZnVuY3Rpb24gcyhsLGgpe3JldHVybiBpPD1sJiZsPD1lJiZ0PD1oJiZoPD1ufWZ1bmN0aW9uIHIobCxoLHUsZil7dmFyIGQ9MCxwPTA7aWYobD09bnVsbHx8KGQ9byhsLHUpKSE9PShwPW8oaCx1KSl8fGMobCxoKTwwXnU+MClkbyBmLnBvaW50KGQ9PT0wfHxkPT09Mz9pOmUsZD4xP246dCk7d2hpbGUoKGQ9KGQrdSs0KSU0KSE9PXApO2Vsc2UgZi5wb2ludChoWzBdLGhbMV0pfWZ1bmN0aW9uIG8obCxoKXtyZXR1cm4gdHQobFswXS1pKTxLP2g+MD8wOjM6dHQobFswXS1lKTxLP2g+MD8yOjE6dHQobFsxXS10KTxLP2g+MD8xOjA6aD4wPzM6Mn1mdW5jdGlvbiBhKGwsaCl7cmV0dXJuIGMobC54LGgueCl9ZnVuY3Rpb24gYyhsLGgpe3ZhciB1PW8obCwxKSxmPW8oaCwxKTtyZXR1cm4gdSE9PWY/dS1mOnU9PT0wP2hbMV0tbFsxXTp1PT09MT9sWzBdLWhbMF06dT09PTI/bFsxXS1oWzFdOmhbMF0tbFswXX1yZXR1cm4gZnVuY3Rpb24obCl7dmFyIGg9bCx1PXZoKCksZixkLHAseSxtLGcsYix3LHgsTSxBLFM9e3BvaW50Ol8sbGluZVN0YXJ0OkMsbGluZUVuZDpQLHBvbHlnb25TdGFydDp6LHBvbHlnb25FbmQ6dn07ZnVuY3Rpb24gXyhCLEkpe3MoQixJKSYmaC5wb2ludChCLEkpfWZ1bmN0aW9uIEUoKXtmb3IodmFyIEI9MCxJPTAsaz1kLmxlbmd0aDtJPGs7KytJKWZvcih2YXIgRD1kW0ldLFU9MSxqPUQubGVuZ3RoLGR0PURbMF0sRHQsR3QsWnQ9ZHRbMF0sbWU9ZHRbMV07VTxqOysrVSlEdD1adCxHdD1tZSxkdD1EW1VdLFp0PWR0WzBdLG1lPWR0WzFdLEd0PD1uP21lPm4mJihadC1EdCkqKG4tR3QpPihtZS1HdCkqKGktRHQpJiYrK0I6bWU8PW4mJihadC1EdCkqKG4tR3QpPChtZS1HdCkqKGktRHQpJiYtLUI7cmV0dXJuIEJ9ZnVuY3Rpb24geigpe2g9dSxmPVtdLGQ9W10sQT0hMH1mdW5jdGlvbiB2KCl7dmFyIEI9RSgpLEk9QSYmQixrPShmPVZpKGYpKS5sZW5ndGg7KEl8fGspJiYobC5wb2x5Z29uU3RhcnQoKSxJJiYobC5saW5lU3RhcnQoKSxyKG51bGwsbnVsbCwxLGwpLGwubGluZUVuZCgpKSxrJiZ6aChmLGEsQixyLGwpLGwucG9seWdvbkVuZCgpKSxoPWwsZj1kPXA9bnVsbH1mdW5jdGlvbiBDKCl7Uy5wb2ludD1GLGQmJmQucHVzaChwPVtdKSxNPSEwLHg9ITEsYj13PU5hTn1mdW5jdGlvbiBQKCl7ZiYmKEYoeSxtKSxnJiZ4JiZ1LnJlam9pbigpLGYucHVzaCh1LnJlc3VsdCgpKSksUy5wb2ludD1fLHgmJmgubGluZUVuZCgpfWZ1bmN0aW9uIEYoQixJKXt2YXIgaz1zKEIsSSk7aWYoZCYmcC5wdXNoKFtCLEldKSxNKXk9QixtPUksZz1rLE09ITEsayYmKGgubGluZVN0YXJ0KCksaC5wb2ludChCLEkpKTtlbHNlIGlmKGsmJngpaC5wb2ludChCLEkpO2Vsc2V7dmFyIEQ9W2I9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksYikpLHc9TWF0aC5tYXgoX3IsTWF0aC5taW4oV2ksdykpXSxVPVtCPU1hdGgubWF4KF9yLE1hdGgubWluKFdpLEIpKSxJPU1hdGgubWF4KF9yLE1hdGgubWluKFdpLEkpKV07QnAoRCxVLGksdCxlLG4pPyh4fHwoaC5saW5lU3RhcnQoKSxoLnBvaW50KERbMF0sRFsxXSkpLGgucG9pbnQoVVswXSxVWzFdKSxrfHxoLmxpbmVFbmQoKSxBPSExKTprJiYoaC5saW5lU3RhcnQoKSxoLnBvaW50KEIsSSksQT0hMSl9Yj1CLHc9SSx4PWt9cmV0dXJuIFN9fXZhciBPYSxEYSx2cix6cixzaT17c3BoZXJlOl90LHBvaW50Ol90LGxpbmVTdGFydDpJcCxsaW5lRW5kOl90LHBvbHlnb25TdGFydDpfdCxwb2x5Z29uRW5kOl90fTtmdW5jdGlvbiBJcCgpe3NpLnBvaW50PU5wLHNpLmxpbmVFbmQ9a3B9ZnVuY3Rpb24ga3AoKXtzaS5wb2ludD1zaS5saW5lRW5kPV90fWZ1bmN0aW9uIE5wKGksdCl7aSo9SCx0Kj1ILERhPWksdnI9cSh0KSx6cj1XKHQpLHNpLnBvaW50PVJwfWZ1bmN0aW9uIFJwKGksdCl7aSo9SCx0Kj1IO3ZhciBlPXEodCksbj1XKHQpLHM9dHQoaS1EYSkscj1XKHMpLG89cShzKSxhPW4qbyxjPXpyKmUtdnIqbipyLGw9dnIqZSt6cipuKnI7T2EuYWRkKHJlKE9lKGEqYStjKmMpLGwpKSxEYT1pLHZyPWUsenI9bn1mdW5jdGlvbiBMcChpKXtyZXR1cm4gT2E9bmV3IExlLGxyKGksc2kpLCtPYX12YXIgJGE9W251bGwsbnVsbF0sT3A9e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOiRhfTtmdW5jdGlvbiByaShpLHQpe3JldHVybiAkYVswXT1pLCRhWzFdPXQsTHAoT3ApfXZhciBCaD17RmVhdHVyZTpmdW5jdGlvbihpLHQpe3JldHVybiBUcihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoVHIoZVtuXS5nZW9tZXRyeSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19LEZoPXtTcGhlcmU6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sUG9pbnQ6ZnVuY3Rpb24oaSx0KXtyZXR1cm4gSWgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoSWgoZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX0sTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe3JldHVybiBraChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWlmKGtoKGVbbl0sdCkpcmV0dXJuITA7cmV0dXJuITF9LFBvbHlnb246ZnVuY3Rpb24oaSx0KXtyZXR1cm4gTmgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2x5Z29uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZihOaChlW25dLHQpKXJldHVybiEwO3JldHVybiExfSxHZW9tZXRyeUNvbGxlY3Rpb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5nZW9tZXRyaWVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoVHIoZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19O2Z1bmN0aW9uIFRyKGksdCl7cmV0dXJuIGkmJkZoLmhhc093blByb3BlcnR5KGkudHlwZSk/RmhbaS50eXBlXShpLHQpOiExfWZ1bmN0aW9uIEloKGksdCl7cmV0dXJuIHJpKGksdCk9PT0wfWZ1bmN0aW9uIGtoKGksdCl7Zm9yKHZhciBlLG4scyxyPTAsbz1pLmxlbmd0aDtyPG87cisrKXtpZihuPXJpKGlbcl0sdCksbj09PTB8fHI+MCYmKHM9cmkoaVtyXSxpW3ItMV0pLHM+MCYmZTw9cyYmbjw9cyYmKGUrbi1zKSooMS1NYXRoLnBvdygoZS1uKS9zLDIpKTxvcipzKSlyZXR1cm4hMDtlPW59cmV0dXJuITF9ZnVuY3Rpb24gTmgoaSx0KXtyZXR1cm4hIUVoKGkubWFwKERwKSxSaCh0KSl9ZnVuY3Rpb24gRHAoaSl7cmV0dXJuIGk9aS5tYXAoUmgpLGkucG9wKCksaX1mdW5jdGlvbiBSaChpKXtyZXR1cm5baVswXSpILGlbMV0qSF19ZnVuY3Rpb24gJHAoaSx0KXtyZXR1cm4oaSYmQmguaGFzT3duUHJvcGVydHkoaS50eXBlKT9CaFtpLnR5cGVdOlRyKShpLHQpfWZ1bmN0aW9uIFZwKGksdCl7dmFyIGU9aVswXSpILG49aVsxXSpILHM9dFswXSpILHI9dFsxXSpILG89VyhuKSxhPXEobiksYz1XKHIpLGw9cShyKSxoPW8qVyhlKSx1PW8qcShlKSxmPWMqVyhzKSxkPWMqcShzKSxwPTIqRGUoT2Uoamwoci1uKStvKmMqamwocy1lKSkpLHk9cShwKSxtPXA/ZnVuY3Rpb24oZyl7dmFyIGI9cShnKj1wKS95LHc9cShwLWcpL3kseD13KmgrYipmLE09dyp1K2IqZCxBPXcqYStiKmw7cmV0dXJuW3JlKE0seCkqaHQscmUoQSxPZSh4KngrTSpNKSkqaHRdfTpmdW5jdGlvbigpe3JldHVybltlKmh0LG4qaHRdfTtyZXR1cm4gbS5kaXN0YW5jZT1wLG19dmFyIExoPWk9Pmksb2k9MS8wLEVyPW9pLEdpPS1vaSxQcj1HaSxPaD17cG9pbnQ6VXAsbGluZVN0YXJ0Ol90LGxpbmVFbmQ6X3QscG9seWdvblN0YXJ0Ol90LHBvbHlnb25FbmQ6X3QscmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGk9W1tvaSxFcl0sW0dpLFByXV07cmV0dXJuIEdpPVByPS0oRXI9b2k9MS8wKSxpfX07ZnVuY3Rpb24gVXAoaSx0KXtpPG9pJiYob2k9aSksaT5HaSYmKEdpPWkpLHQ8RXImJihFcj10KSx0PlByJiYoUHI9dCl9ZnVuY3Rpb24gVmEoaSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBVYTtmb3IodmFyIG4gaW4gaSllW25dPWlbbl07cmV0dXJuIGUuc3RyZWFtPXQsZX19ZnVuY3Rpb24gVWEoKXt9VWEucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpVYSxwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGksdCl9LHNwaGVyZTpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLnNwaGVyZSgpfSxsaW5lU3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5saW5lU3RhcnQoKX0sbGluZUVuZDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLmxpbmVFbmQoKX0scG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0ucG9seWdvblN0YXJ0KCl9LHBvbHlnb25FbmQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBxYShpLHQsZSl7dmFyIG49aS5jbGlwRXh0ZW50JiZpLmNsaXBFeHRlbnQoKTtyZXR1cm4gaS5zY2FsZSgxNTApLnRyYW5zbGF0ZShbMCwwXSksbiE9bnVsbCYmaS5jbGlwRXh0ZW50KG51bGwpLGxyKGUsaS5zdHJlYW0oT2gpKSx0KE9oLnJlc3VsdCgpKSxuIT1udWxsJiZpLmNsaXBFeHRlbnQobiksaX1mdW5jdGlvbiBEaChpLHQsZSl7cmV0dXJuIHFhKGksZnVuY3Rpb24obil7dmFyIHM9dFsxXVswXS10WzBdWzBdLHI9dFsxXVsxXS10WzBdWzFdLG89TWF0aC5taW4ocy8oblsxXVswXS1uWzBdWzBdKSxyLyhuWzFdWzFdLW5bMF1bMV0pKSxhPSt0WzBdWzBdKyhzLW8qKG5bMV1bMF0rblswXVswXSkpLzIsYz0rdFswXVsxXSsoci1vKihuWzFdWzFdK25bMF1bMV0pKS8yO2kuc2NhbGUoMTUwKm8pLnRyYW5zbGF0ZShbYSxjXSl9LGUpfWZ1bmN0aW9uIHFwKGksdCxlKXtyZXR1cm4gRGgoaSxbWzAsMF0sdF0sZSl9ZnVuY3Rpb24gSHAoaSx0LGUpe3JldHVybiBxYShpLGZ1bmN0aW9uKG4pe3ZhciBzPSt0LHI9cy8oblsxXVswXS1uWzBdWzBdKSxvPShzLXIqKG5bMV1bMF0rblswXVswXSkpLzIsYT0tcipuWzBdWzFdO2kuc2NhbGUoMTUwKnIpLnRyYW5zbGF0ZShbbyxhXSl9LGUpfWZ1bmN0aW9uIFdwKGksdCxlKXtyZXR1cm4gcWEoaSxmdW5jdGlvbihuKXt2YXIgcz0rdCxyPXMvKG5bMV1bMV0tblswXVsxXSksbz0tcipuWzBdWzBdLGE9KHMtciooblsxXVsxXStuWzBdWzFdKSkvMjtpLnNjYWxlKDE1MCpyKS50cmFuc2xhdGUoW28sYV0pfSxlKX12YXIgJGg9MTYsR3A9VygzMCpIKTtmdW5jdGlvbiBWaChpLHQpe3JldHVybit0P1hwKGksdCk6WnAoaSl9ZnVuY3Rpb24gWnAoaSl7cmV0dXJuIFZhKHtwb2ludDpmdW5jdGlvbih0LGUpe3Q9aSh0LGUpLHRoaXMuc3RyZWFtLnBvaW50KHRbMF0sdFsxXSl9fSl9ZnVuY3Rpb24gWHAoaSx0KXtmdW5jdGlvbiBlKG4scyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbSl7dmFyIGc9bC1uLGI9aC1zLHc9ZypnK2IqYjtpZih3PjQqdCYmeS0tKXt2YXIgeD1vK2YsTT1hK2QsQT1jK3AsUz1PZSh4KngrTSpNK0EqQSksXz1EZShBLz1TKSxFPXR0KHR0KEEpLTEpPEt8fHR0KHItdSk8Sz8ocit1KS8yOnJlKE0seCksej1pKEUsXyksdj16WzBdLEM9elsxXSxQPXYtbixGPUMtcyxCPWIqUC1nKkY7KEIqQi93PnR8fHR0KChnKlArYipGKS93LS41KT4uM3x8bypmK2EqZCtjKnA8R3ApJiYoZShuLHMscixvLGEsYyx2LEMsRSx4Lz1TLE0vPVMsQSx5LG0pLG0ucG9pbnQodixDKSxlKHYsQyxFLHgsTSxBLGwsaCx1LGYsZCxwLHksbSkpfX1yZXR1cm4gZnVuY3Rpb24obil7dmFyIHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG09e3BvaW50OmcsbGluZVN0YXJ0OmIsbGluZUVuZDp4LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe24ucG9seWdvblN0YXJ0KCksbS5saW5lU3RhcnQ9TX0scG9seWdvbkVuZDpmdW5jdGlvbigpe24ucG9seWdvbkVuZCgpLG0ubGluZVN0YXJ0PWJ9fTtmdW5jdGlvbiBnKF8sRSl7Xz1pKF8sRSksbi5wb2ludChfWzBdLF9bMV0pfWZ1bmN0aW9uIGIoKXt1PU5hTixtLnBvaW50PXcsbi5saW5lU3RhcnQoKX1mdW5jdGlvbiB3KF8sRSl7dmFyIHo9U24oW18sRV0pLHY9aShfLEUpO2UodSxmLGgsZCxwLHksdT12WzBdLGY9dlsxXSxoPV8sZD16WzBdLHA9elsxXSx5PXpbMl0sJGgsbiksbi5wb2ludCh1LGYpfWZ1bmN0aW9uIHgoKXttLnBvaW50PWcsbi5saW5lRW5kKCl9ZnVuY3Rpb24gTSgpe2IoKSxtLnBvaW50PUEsbS5saW5lRW5kPVN9ZnVuY3Rpb24gQShfLEUpe3cocz1fLEUpLHI9dSxvPWYsYT1kLGM9cCxsPXksbS5wb2ludD13fWZ1bmN0aW9uIFMoKXtlKHUsZixoLGQscCx5LHIsbyxzLGEsYyxsLCRoLG4pLG0ubGluZUVuZD14LHgoKX1yZXR1cm4gbX19dmFyIEpwPVZhKHtwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGkqSCx0KkgpfX0pO2Z1bmN0aW9uIFlwKGkpe3JldHVybiBWYSh7cG9pbnQ6ZnVuY3Rpb24odCxlKXt2YXIgbj1pKHQsZSk7cmV0dXJuIHRoaXMuc3RyZWFtLnBvaW50KG5bMF0sblsxXSl9fSl9ZnVuY3Rpb24ganAoaSx0LGUsbixzKXtmdW5jdGlvbiByKG8sYSl7cmV0dXJuIG8qPW4sYSo9cyxbdCtpKm8sZS1pKmFdfXJldHVybiByLmludmVydD1mdW5jdGlvbihvLGEpe3JldHVyblsoby10KS9pKm4sKGUtYSkvaSpzXX0scn1mdW5jdGlvbiBVaChpLHQsZSxuLHMscil7aWYoIXIpcmV0dXJuIGpwKGksdCxlLG4scyk7dmFyIG89VyhyKSxhPXEociksYz1vKmksbD1hKmksaD1vL2ksdT1hL2ksZj0oYSplLW8qdCkvaSxkPShhKnQrbyplKS9pO2Z1bmN0aW9uIHAoeSxtKXtyZXR1cm4geSo9bixtKj1zLFtjKnktbCptK3QsZS1sKnktYyptXX1yZXR1cm4gcC5pbnZlcnQ9ZnVuY3Rpb24oeSxtKXtyZXR1cm5bbiooaCp5LXUqbStmKSxzKihkLXUqeS1oKm0pXX0scH1mdW5jdGlvbiBDcihpKXtyZXR1cm4gUXAoZnVuY3Rpb24oKXtyZXR1cm4gaX0pKCl9ZnVuY3Rpb24gUXAoaSl7dmFyIHQsZT0xNTAsbj00ODAscz0yNTAscj0wLG89MCxhPTAsYz0wLGw9MCxoLHU9MCxmPTEsZD0xLHA9bnVsbCx5PUNoLG09bnVsbCxnLGIsdyx4PUxoLE09LjUsQSxTLF8sRSx6O2Z1bmN0aW9uIHYoQil7cmV0dXJuIF8oQlswXSpILEJbMV0qSCl9ZnVuY3Rpb24gQyhCKXtyZXR1cm4gQj1fLmludmVydChCWzBdLEJbMV0pLEImJltCWzBdKmh0LEJbMV0qaHRdfXYuc3RyZWFtPWZ1bmN0aW9uKEIpe3JldHVybiBFJiZ6PT09Qj9FOkU9SnAoWXAoaCkoeShBKHgoej1CKSkpKSl9LHYucHJlY2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeT1CLHA9dm9pZCAwLEYoKSk6eX0sdi5wb3N0Y2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CLG09Zz1iPXc9bnVsbCxGKCkpOnh9LHYuY2xpcEFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh5PStCP0NwKHA9QipIKToocD1udWxsLENoKSxGKCkpOnAqaHR9LHYuY2xpcEV4dGVudD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CPT1udWxsPyhtPWc9Yj13PW51bGwsTGgpOkZwKG09K0JbMF1bMF0sZz0rQlswXVsxXSxiPStCWzFdWzBdLHc9K0JbMV1bMV0pLEYoKSk6bT09bnVsbD9udWxsOltbbSxnXSxbYix3XV19LHYuc2NhbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGU9K0IsUCgpKTplfSx2LnRyYW5zbGF0ZT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obj0rQlswXSxzPStCWzFdLFAoKSk6W24sc119LHYuY2VudGVyPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhyPUJbMF0lMzYwKkgsbz1CWzFdJTM2MCpILFAoKSk6W3IqaHQsbypodF19LHYucm90YXRlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhhPUJbMF0lMzYwKkgsYz1CWzFdJTM2MCpILGw9Qi5sZW5ndGg+Mj9CWzJdJTM2MCpIOjAsUCgpKTpbYSpodCxjKmh0LGwqaHRdfSx2LmFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh1PUIlMzYwKkgsUCgpKTp1Kmh0fSx2LnJlZmxlY3RYPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhmPUI/LTE6MSxQKCkpOmY8MH0sdi5yZWZsZWN0WT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZD1CPy0xOjEsUCgpKTpkPDB9LHYucHJlY2lzaW9uPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhBPVZoKFMsTT1CKkIpLEYoKSk6T2UoTSl9LHYuZml0RXh0ZW50PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIERoKHYsQixJKX0sdi5maXRTaXplPWZ1bmN0aW9uKEIsSSl7cmV0dXJuIHFwKHYsQixJKX0sdi5maXRXaWR0aD1mdW5jdGlvbihCLEkpe3JldHVybiBIcCh2LEIsSSl9LHYuZml0SGVpZ2h0PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIFdwKHYsQixJKX07ZnVuY3Rpb24gUCgpe3ZhciBCPVVoKGUsMCwwLGYsZCx1KS5hcHBseShudWxsLHQocixvKSksST1VaChlLG4tQlswXSxzLUJbMV0sZixkLHUpO3JldHVybiBoPXdoKGEsYyxsKSxTPU5hKHQsSSksXz1OYShoLFMpLEE9VmgoUyxNKSxGKCl9ZnVuY3Rpb24gRigpe3JldHVybiBFPXo9bnVsbCx2fXJldHVybiBmdW5jdGlvbigpe3JldHVybiB0PWkuYXBwbHkodGhpcyxhcmd1bWVudHMpLHYuaW52ZXJ0PXQuaW52ZXJ0JiZDLFAoKX19ZnVuY3Rpb24gS3AoaSl7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7dmFyIG49T2UodCp0K2UqZSkscz1pKG4pLHI9cShzKSxvPVcocyk7cmV0dXJuW3JlKHQqcixuKm8pLERlKG4mJmUqci9uKV19fWZ1bmN0aW9uIEhhKGksdCl7cmV0dXJuW2ksbHAodXAoKE50K3QpLzIpKV19SGEuaW52ZXJ0PWZ1bmN0aW9uKGksdCl7cmV0dXJuW2ksMipTYShjcCh0KSktTnRdfTtmdW5jdGlvbiB0eSgpe3JldHVybiBleShIYSkuc2NhbGUoOTYxL1J0KX1mdW5jdGlvbiBleShpKXt2YXIgdD1DcihpKSxlPXQuY2VudGVyLG49dC5zY2FsZSxzPXQudHJhbnNsYXRlLHI9dC5jbGlwRXh0ZW50LG89bnVsbCxhLGMsbDt0LnNjYWxlPWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhuKHUpLGgoKSk6bigpfSx0LnRyYW5zbGF0ZT1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8ocyh1KSxoKCkpOnMoKX0sdC5jZW50ZXI9ZnVuY3Rpb24odSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGUodSksaCgpKTplKCl9LHQuY2xpcEV4dGVudD1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odT09bnVsbD9vPWE9Yz1sPW51bGw6KG89K3VbMF1bMF0sYT0rdVswXVsxXSxjPSt1WzFdWzBdLGw9K3VbMV1bMV0pLGgoKSk6bz09bnVsbD9udWxsOltbbyxhXSxbYyxsXV19O2Z1bmN0aW9uIGgoKXt2YXIgdT1YKm4oKSxmPXQoU2godC5yb3RhdGUoKSkuaW52ZXJ0KFswLDBdKSk7cmV0dXJuIHIobz09bnVsbD9bW2ZbMF0tdSxmWzFdLXVdLFtmWzBdK3UsZlsxXSt1XV06aT09PUhhP1tbTWF0aC5tYXgoZlswXS11LG8pLGFdLFtNYXRoLm1pbihmWzBdK3UsYyksbF1dOltbbyxNYXRoLm1heChmWzFdLXUsYSldLFtjLE1hdGgubWluKGZbMV0rdSxsKV1dKX1yZXR1cm4gaCgpfWZ1bmN0aW9uIFdhKGksdCl7cmV0dXJuW2ksdF19V2EuaW52ZXJ0PVdhO2Z1bmN0aW9uIG55KCl7cmV0dXJuIENyKFdhKS5zY2FsZSgxNTIuNjMpfWZ1bmN0aW9uIHFoKGksdCl7dmFyIGU9Vyh0KSxuPTErVyhpKSplO3JldHVybltlKnEoaSkvbixxKHQpL25dfXFoLmludmVydD1LcChmdW5jdGlvbihpKXtyZXR1cm4gMipTYShpKX0pO2Z1bmN0aW9uIGl5KCl7cmV0dXJuIENyKHFoKS5zY2FsZSgyNTApLmNsaXBBbmdsZSgxNDIpfXZhciBCcj1NYXRoLmFicyxhaT1NYXRoLmNvcyxiZT1NYXRoLnNpbixaaT0xZS02LEZyPU1hdGguUEksR2E9RnIvMjtmdW5jdGlvbiBzeShpKXtyZXR1cm4gaT9pL01hdGguc2luKGkpOjF9ZnVuY3Rpb24gWmEoaSl7cmV0dXJuIGk+MT8wOmk8LTE/RnI6TWF0aC5hY29zKGkpfWZ1bmN0aW9uIEhoKGkpe3JldHVybiBpPjA/TWF0aC5zcXJ0KGkpOjB9ZnVuY3Rpb24gV2goaSx0KXt2YXIgZT1haSh0KSxuPXN5KFphKGUqYWkoaS89MikpKTtyZXR1cm5bMiplKmJlKGkpKm4sYmUodCkqbl19V2guaW52ZXJ0PWZ1bmN0aW9uKGksdCl7aWYoIShpKmkrNCp0KnQ+RnIqRnIrWmkpKXt2YXIgZT1pLG49dCxzPTI1O2Rve3ZhciByPWJlKGUpLG89YmUoZS8yKSxhPWFpKGUvMiksYz1iZShuKSxsPWFpKG4pLGg9YmUoMipuKSx1PWMqYyxmPWwqbCxkPW8qbyxwPTEtZiphKmEseT1wP1phKGwqYSkqSGgobT0xL3ApOm09MCxtLGc9Mip5Kmwqby1pLGI9eSpjLXQsdz1tKihmKmQreSpsKmEqdSkseD1tKiguNSpyKmgteSoyKmMqbyksTT1tKi4yNSooaCpvLXkqYypmKnIpLEE9bSoodSphK3kqZCpsKSxTPXgqTS1BKnc7aWYoIVMpYnJlYWs7dmFyIF89KGIqeC1nKkEpL1MsRT0oZypNLWIqdykvUztlLT1fLG4tPUV9d2hpbGUoKEJyKF8pPlppfHxCcihFKT5aaSkmJi0tcz4wKTtyZXR1cm5bZSxuXX19O2Z1bmN0aW9uIEdoKGksdCl7dmFyIGU9V2goaSx0KTtyZXR1cm5bKGVbMF0raS9HYSkvMiwoZVsxXSt0KS8yXX1HaC5pbnZlcnQ9ZnVuY3Rpb24oaSx0KXt2YXIgZT1pLG49dCxzPTI1O2Rve3ZhciByPWFpKG4pLG89YmUobiksYT1iZSgyKm4pLGM9bypvLGw9cipyLGg9YmUoZSksdT1haShlLzIpLGY9YmUoZS8yKSxkPWYqZixwPTEtbCp1KnUseT1wP1phKHIqdSkqSGgobT0xL3ApOm09MCxtLGc9LjUqKDIqeSpyKmYrZS9HYSktaSxiPS41Kih5Km8rbiktdCx3PS41Km0qKGwqZCt5KnIqdSpjKSsuNS9HYSx4PW0qKGgqYS80LXkqbypmKSxNPS4xMjUqbSooYSpmLXkqbypsKmgpLEE9LjUqbSooYyp1K3kqZCpyKSsuNSxTPXgqTS1BKncsXz0oYip4LWcqQSkvUyxFPShnKk0tYip3KS9TO2UtPV8sbi09RX13aGlsZSgoQnIoXyk+Wml8fEJyKEUpPlppKSYmLS1zPjApO3JldHVybltlLG5dfTtmdW5jdGlvbiByeSgpe3JldHVybiBDcihHaCkuc2NhbGUoMTU4LjgzNyl9Y29uc3Qgb3k9e21lcmNhdG9yOnR5LGVxdWlyZWN0YW5ndWxhcjpueSx3aW5rZWwzOnJ5fSxYYT17fSxYaT1pPT57dmFyIG4scyxyO2NvbnN0IHQ9SlNPTi5zdHJpbmdpZnkoaSk7aWYoWGFbdF0pcmV0dXJuIFhhW3RdO2NvbnN0IGU9b3lbKG49aS5wcm9qZWN0aW9uVHlwZSkhPW51bGw/bjoibWVyY2F0b3IiXSgpLmNlbnRlcihpLmNlbnRlcikuc2NhbGUoaS5zY2FsZSkudHJhbnNsYXRlKChzPWkudHJhbnNsYXRlKSE9bnVsbD9zOlswLDBdKS5wcmVjaXNpb24oKHI9aS5wcmVjaXNpb24pIT1udWxsP3I6LjEpO3JldHVybiBpLnJvdGF0ZSYmZS5yb3RhdGUoaS5yb3RhdGUpLFhhW3RdPWUsZX0sSXI9KGksdCk9PmkubWFwKChbZSxuXSk9PntsZXQgcztpZih0KXtjb25zdFtyLG9dPXQoW2Usbl0pO3M9bmV3IFIociwtbyl9ZWxzZSBzPW5ldyBSKGUsbik7cmV0dXJuIHN9KTt2YXIgSmk9KGksdCk9Pntjb25zdCBlPUpsKGksdCE9bnVsbD90OjApLG49e30scz1bXSxyPU9iamVjdC5rZXlzKGUuYXR0cmlidXRlcyk7cmV0dXJuIGUuaW5kZXgmJnIucHVzaCgiaW5kZXgiKSxyLmZvckVhY2gobz0+e2NvbnN0IGE9bz09PSJpbmRleCI/ZS5pbmRleDplLmF0dHJpYnV0ZXNbb107bltvXT17YXJyYXk6YS5hcnJheSxpdGVtU2l6ZTphLml0ZW1TaXplfSxzLnB1c2goYS5hcnJheS5idWZmZXIpfSksdCYmKG4uZ3JvdXBzPWUuZ3JvdXBzKSxlLmRpc3Bvc2UoKSxpLmZvckVhY2gobz0+e28uZGlzcG9zZSgpfSkse21lc3NhZ2U6bix0cmFuc2ZlcjpzfX0sSmE9KGksdD0zMDApPT57Y29uc3QgZT1bXTtyZXR1cm4gaS5mb3JFYWNoKG49PntsZXQgcz0hMTtmb3IobGV0IHI9MTtyPG4ubGVuZ3RoO3IrKylpZihNYXRoLmFicyhuW3JdLngtbltyLTFdLngpPnQpe3M9ITA7YnJlYWt9aWYocyl7Y29uc3Qgcj1bXSxvPVtdO24uZm9yRWFjaChhPT57YS54PDA/ci5wdXNoKGEpOm8ucHVzaChhKX0pLGUucHVzaChyLG8pfWVsc2UgZS5wdXNoKG4pfSksZX07ZnVuY3Rpb24gYXkoaSx0LGU9MCl7Y29uc3RbbixzLHIsb109aTtsZXQgYT0xLzAsYz0xLzAsbD0tMS8wLGg9LTEvMDtmb3IobGV0IHU9MDt1PD1lO3UrKyl7Y29uc3QgZj1lJiZ1L2U7SXIoW1tuK2YqKHItbiksc10sW24rZiooci1uKSxvXSxbbixzK2YqKG8tcyldLFtyLHMrZiooby1zKV1dLHQpLmZvckVhY2goZD0+e2E9TWF0aC5taW4oYSxkLngpLGM9TWF0aC5taW4oYyxkLnkpLGw9TWF0aC5tYXgobCxkLngpLGg9TWF0aC5tYXgoaCxkLnkpfSl9cmV0dXJuW1thLGNdLFtsLGhdXX1jb25zdCBjeT0oe2Nvb3JkaW5hdGVzQXJyOmksc3BsaXQ6dCxzaWRlUmVwZWF0OmUsYmJveDpuLGRlcHRoOnMscHJvamVjdGlvbjpyLHVzZUdyb3VwczpvLGhhc1RvcDphLGhhc0JvdHRvbTpjLGhhc1NpZGU6bCxzcGxpdFBvbHlnb25zOmgsdG9wU2VnbWVudHM6dX0pPT57Y29uc3QgZj1yJiZYaShyKTtsZXQgZD1pLm1hcChtPT5JcihtLGYpKTtoJiYoZD1KYShkLGgpKTtsZXQgcDtpZihuKXtjb25zdFttLGddPWF5KG4sciE9bnVsbCYmci5yb3RhdGU/WGkoWmUoRnQoe30scikse3JvdGF0ZTp2b2lkIDB9KSk6Ziwocj09bnVsbD92b2lkIDA6ci5wcm9qZWN0aW9uVHlwZSk9PT0id2lua2VsMyI/MTA6MCk7cD1uZXcgZ3QobmV3IFQobVswXSxtWzFdLDApLG5ldyBUKGdbMF0sZ1sxXSwwKSl9Y29uc3QgeT1kLm1hcCgobSxnKT0+e3ZhciBiO3JldHVybiBKMCh7cG9pbnRzOm0sc3BsaXQ6dCxzaWRlUmVwZWF0OmUsZGVwdGg6KGI9c1tnXSkhPW51bGw/YjpzWzBdLGhhc1RvcDphLGhhc0JvdHRvbTpjLGhhc1NpZGU6bCxib3gzOnAsdG9wU2VnbWVudHM6dX0pfSk7cmV0dXJuIEppKHksbyl9O2Z1bmN0aW9uIFlhKGksdCxlLG4scyl7bGV0IHI7aWYoaT1pLnN1YmFycmF5fHxpLnNsaWNlP2k6aS5idWZmZXIsZT1lLnN1YmFycmF5fHxlLnNsaWNlP2U6ZS5idWZmZXIsaT10P2kuc3ViYXJyYXk/aS5zdWJhcnJheSh0LHMmJnQrcyk6aS5zbGljZSh0LHMmJnQrcyk6aSxlLnNldCllLnNldChpLG4pO2Vsc2UgZm9yKHI9MDtyPGkubGVuZ3RoO3IrKyllW3Irbl09aVtyXTtyZXR1cm4gZX1mdW5jdGlvbiBseShpKXtyZXR1cm4gaSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheT9pOmkgaW5zdGFuY2VvZiB1ZT9pLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKS5hcnJheTppLm1hcCh0PT57Y29uc3QgZT1BcnJheS5pc0FycmF5KHQpO3JldHVybiB0IGluc3RhbmNlb2YgVD9bdC54LHQueSx0LnpdOnQgaW5zdGFuY2VvZiBSP1t0LngsdC55LDBdOmUmJnQubGVuZ3RoPT09Mz9bdFswXSx0WzFdLHRbMl1dOmUmJnQubGVuZ3RoPT09Mj9bdFswXSx0WzFdLDBdOnR9KS5mbGF0KCl9Y2xhc3MgaHkgZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcigpe3N1cGVyKCksdGhpcy50eXBlPSJNZXNoTGluZSIsdGhpcy5pc01lc2hMaW5lPSEwLHRoaXMucG9zaXRpb25zPVtdLHRoaXMucHJldmlvdXM9W10sdGhpcy5uZXh0PVtdLHRoaXMuc2lkZT1bXSx0aGlzLndpZHRoPVtdLHRoaXMuaW5kaWNlc19hcnJheT1bXSx0aGlzLnV2cz1bXSx0aGlzLmNvdW50ZXJzPVtdLHRoaXMud2lkdGhDYWxsYmFjaz1udWxsLHRoaXMuX3BvaW50cz1bXSx0aGlzLm1hdHJpeFdvcmxkPW5ldyBzdCxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLHtwb2ludHM6e2VudW1lcmFibGU6ITAsZ2V0KCl7cmV0dXJuIHRoaXMuX3BvaW50c30sc2V0KHQpe3RoaXMuc2V0UG9pbnRzKHQsdGhpcy53aWR0aENhbGxiYWNrKX19fSl9c2V0TWF0cml4V29ybGQodCl7dGhpcy5tYXRyaXhXb3JsZD10fXNldFBvaW50cyh0LGUpe2lmKHQ9bHkodCksdGhpcy5fcG9pbnRzPXQsdGhpcy53aWR0aENhbGxiYWNrPWUhPW51bGw/ZTpudWxsLHRoaXMucG9zaXRpb25zPVtdLHRoaXMuY291bnRlcnM9W10sdC5sZW5ndGgmJnRbMF1pbnN0YW5jZW9mIFQpZm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKyspe2NvbnN0IHM9dFtuXSxyPW4vKHQubGVuZ3RoLTEpO3RoaXMucG9zaXRpb25zLnB1c2gocy54LHMueSxzLnopLHRoaXMucG9zaXRpb25zLnB1c2gocy54LHMueSxzLnopLHRoaXMuY291bnRlcnMucHVzaChyKSx0aGlzLmNvdW50ZXJzLnB1c2gocil9ZWxzZSBmb3IobGV0IG49MDtuPHQubGVuZ3RoO24rPTMpe2NvbnN0IHM9bi8odC5sZW5ndGgtMSk7dGhpcy5wb3NpdGlvbnMucHVzaCh0W25dLHRbbisxXSx0W24rMl0pLHRoaXMucG9zaXRpb25zLnB1c2godFtuXSx0W24rMV0sdFtuKzJdKSx0aGlzLmNvdW50ZXJzLnB1c2gocyksdGhpcy5jb3VudGVycy5wdXNoKHMpfXRoaXMucHJvY2VzcygpfWNvbXBhcmVWMyh0LGUpe2NvbnN0IG49dCo2LHM9ZSo2O3JldHVybiB0aGlzLnBvc2l0aW9uc1tuXT09PXRoaXMucG9zaXRpb25zW3NdJiZ0aGlzLnBvc2l0aW9uc1tuKzFdPT09dGhpcy5wb3NpdGlvbnNbcysxXSYmdGhpcy5wb3NpdGlvbnNbbisyXT09PXRoaXMucG9zaXRpb25zW3MrMl19Y29weVYzKHQpe2NvbnN0IGU9dCo2O3JldHVyblt0aGlzLnBvc2l0aW9uc1tlXSx0aGlzLnBvc2l0aW9uc1tlKzFdLHRoaXMucG9zaXRpb25zW2UrMl1dfXByb2Nlc3MoKXtjb25zdCB0PXRoaXMucG9zaXRpb25zLmxlbmd0aC82O3RoaXMucHJldmlvdXM9W10sdGhpcy5uZXh0PVtdLHRoaXMuc2lkZT1bXSx0aGlzLndpZHRoPVtdLHRoaXMuaW5kaWNlc19hcnJheT1bXSx0aGlzLnV2cz1bXTtsZXQgZSxuO3RoaXMuY29tcGFyZVYzKDAsdC0xKT9uPXRoaXMuY29weVYzKHQtMik6bj10aGlzLmNvcHlWMygwKSx0aGlzLnByZXZpb3VzLnB1c2goblswXSxuWzFdLG5bMl0pLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSk7Zm9yKGxldCBzPTA7czx0O3MrKyl7aWYodGhpcy5zaWRlLnB1c2goMSksdGhpcy5zaWRlLnB1c2goLTEpLHRoaXMud2lkdGhDYWxsYmFjaz9lPXRoaXMud2lkdGhDYWxsYmFjayhzLyh0LTEpKTplPTEsdGhpcy53aWR0aC5wdXNoKGUpLHRoaXMud2lkdGgucHVzaChlKSx0aGlzLnV2cy5wdXNoKHMvKHQtMSksMCksdGhpcy51dnMucHVzaChzLyh0LTEpLDEpLHM8dC0xKXtuPXRoaXMuY29weVYzKHMpLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKTtjb25zdCByPXMqMjt0aGlzLmluZGljZXNfYXJyYXkucHVzaChyLHIrMSxyKzIpLHRoaXMuaW5kaWNlc19hcnJheS5wdXNoKHIrMixyKzEsciszKX1zPjAmJihuPXRoaXMuY29weVYzKHMpLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSkpfXRoaXMuY29tcGFyZVYzKHQtMSwwKT9uPXRoaXMuY29weVYzKDEpOm49dGhpcy5jb3B5VjModC0xKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5uZXh0LnB1c2goblswXSxuWzFdLG5bMl0pLCF0aGlzLl9hdHRyaWJ1dGVzfHx0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50IT09dGhpcy5jb3VudGVycy5sZW5ndGg/dGhpcy5fYXR0cmlidXRlcz17cG9zaXRpb246bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wb3NpdGlvbnMpLDMpLHByZXZpb3VzOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMucHJldmlvdXMpLDMpLG5leHQ6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5uZXh0KSwzKSxzaWRlOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMuc2lkZSksMSksd2lkdGg6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy53aWR0aCksMSksdXY6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy51dnMpLDIpLGluZGV4Om5ldyB4dChuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzX2FycmF5KSwxKSxjb3VudGVyczpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLmNvdW50ZXJzKSwxKX06KHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wb3NpdGlvbnMpKSx0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wcmV2aW91cykpLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5uZXh0LmNvcHlBcnJheShuZXcgRmxvYXQzMkFycmF5KHRoaXMubmV4dCkpLHRoaXMuX2F0dHJpYnV0ZXMubmV4dC5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnNpZGUuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaWRlKSksdGhpcy5fYXR0cmlidXRlcy5zaWRlLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGguY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy53aWR0aCkpLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy51di5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnV2cykpLHRoaXMuX2F0dHJpYnV0ZXMudXYubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5pbmRleC5jb3B5QXJyYXkobmV3IFVpbnQxNkFycmF5KHRoaXMuaW5kaWNlc19hcnJheSkpLHRoaXMuX2F0dHJpYnV0ZXMuaW5kZXgubmVlZHNVcGRhdGU9ITApLHRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbiksdGhpcy5zZXRBdHRyaWJ1dGUoInByZXZpb3VzIix0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzKSx0aGlzLnNldEF0dHJpYnV0ZSgibmV4dCIsdGhpcy5fYXR0cmlidXRlcy5uZXh0KSx0aGlzLnNldEF0dHJpYnV0ZSgic2lkZSIsdGhpcy5fYXR0cmlidXRlcy5zaWRlKSx0aGlzLnNldEF0dHJpYnV0ZSgid2lkdGgiLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsdGhpcy5fYXR0cmlidXRlcy51diksdGhpcy5zZXRBdHRyaWJ1dGUoImNvdW50ZXJzIix0aGlzLl9hdHRyaWJ1dGVzLmNvdW50ZXJzKSx0aGlzLnNldEF0dHJpYnV0ZSgicG9zaXRpb24iLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24pLHRoaXMuc2V0QXR0cmlidXRlKCJwcmV2aW91cyIsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cyksdGhpcy5zZXRBdHRyaWJ1dGUoIm5leHQiLHRoaXMuX2F0dHJpYnV0ZXMubmV4dCksdGhpcy5zZXRBdHRyaWJ1dGUoInNpZGUiLHRoaXMuX2F0dHJpYnV0ZXMuc2lkZSksdGhpcy5zZXRBdHRyaWJ1dGUoIndpZHRoIix0aGlzLl9hdHRyaWJ1dGVzLndpZHRoKSx0aGlzLnNldEF0dHJpYnV0ZSgidXYiLHRoaXMuX2F0dHJpYnV0ZXMudXYpLHRoaXMuc2V0QXR0cmlidXRlKCJjb3VudGVycyIsdGhpcy5fYXR0cmlidXRlcy5jb3VudGVycyksdGhpcy5zZXRJbmRleCh0aGlzLl9hdHRyaWJ1dGVzLmluZGV4KSx0aGlzLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpLHRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCl9YWR2YW5jZSh7eDp0LHk6ZSx6Om59KXtjb25zdCBzPXRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uYXJyYXkscj10aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzLmFycmF5LG89dGhpcy5fYXR0cmlidXRlcy5uZXh0LmFycmF5LGE9cy5sZW5ndGg7WWEocywwLHIsMCxhKSxZYShzLDYscywwLGEtNiksc1thLTZdPXQsc1thLTVdPWUsc1thLTRdPW4sc1thLTNdPXQsc1thLTJdPWUsc1thLTFdPW4sWWEocyw2LG8sMCxhLTYpLG9bYS02XT10LG9bYS01XT1lLG9bYS00XT1uLG9bYS0zXT10LG9bYS0yXT1lLG9bYS0xXT1uLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24ubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLm5leHQubmVlZHNVcGRhdGU9ITB9fXZhciBaaD1pPT57Y29uc3R7c2V0UG9pbnRXaWR0aDp0LG5vZGVzOmV9PWksbj1uZXcgaHk7cmV0dXJuIG4uc2V0UG9pbnRzKGUsdCksbn07Y29uc3QgdXk9KHtjb29yZGluYXRlc0FycjppLHByb2plY3Rpb246dCxsaW5lV2lkdGg6ZSx1c2VHcm91cHM6bixzcGxpdFBvbHlnb25zOnN9KT0+e2NvbnN0IHI9dCYmWGkodCk7bGV0IG89aS5tYXAoYz0+SXIoYyxyKSk7cyYmKG89SmEobyxzKSk7Y29uc3QgYT1vLm1hcCgoYyxsKT0+e3ZhciB1O2NvbnN0IGg9KHU9ZVtsXSkhPW51bGw/dTplWzBdO3JldHVybiBaaCh7bm9kZXM6YyxzZXRQb2ludFdpZHRoOigpPT5ofSl9KTtyZXR1cm4gSmkoYSxuKX07dmFyIGZ5PWk9Pntjb25zdHtwb2ludHM6dH09aSxlPXQucmVkdWNlKChzLHIsbyk9PihvPHQubGVuZ3RoLTEmJnMucHVzaChyLHRbbysxXSkscyksW10pO3JldHVybiBuZXcgdWUoKS5zZXRGcm9tUG9pbnRzKGUpfTtjb25zdCBkeT0oe2Nvb3JkaW5hdGVzQXJyOmkscHJvamVjdGlvbjp0LGxpbmVXaWR0aDplLHVzZUdyb3VwczpuLHNwbGl0UG9seWdvbnM6c30pPT57Y29uc3Qgcj10JiZYaSh0KTtsZXQgbz1pLm1hcChjPT5JcihjLHIpKTtzJiYobz1KYShvLHMpKTtjb25zdCBhPW8ubWFwKChjLGwpPT5meSh7cG9pbnRzOmMubWFwKGg9Pm5ldyBUKGgueCxoLnksMCkpfSkpO3JldHVybiBKaShhLG4pfTtmdW5jdGlvbiBweShpLHQsZT0yKXtjb25zdCBuPXQmJnQubGVuZ3RoLHM9bj90WzBdKmU6aS5sZW5ndGg7bGV0IHI9WGgoaSwwLHMsZSwhMCk7Y29uc3Qgbz1bXTtpZighcnx8ci5uZXh0PT09ci5wcmV2KXJldHVybiBvO2xldCBhLGMsbDtpZihuJiYocj13eShpLHQscixlKSksaS5sZW5ndGg+ODAqZSl7YT0xLzAsYz0xLzA7bGV0IGg9LTEvMCx1PS0xLzA7Zm9yKGxldCBmPWU7ZjxzO2YrPWUpe2NvbnN0IGQ9aVtmXSxwPWlbZisxXTtkPGEmJihhPWQpLHA8YyYmKGM9cCksZD5oJiYoaD1kKSxwPnUmJih1PXApfWw9TWF0aC5tYXgoaC1hLHUtYyksbD1sIT09MD8zMjc2Ny9sOjB9cmV0dXJuIFlpKHIsbyxlLGEsYyxsLDApLG99ZnVuY3Rpb24gWGgoaSx0LGUsbixzKXtsZXQgcjtpZihzPT09Q3koaSx0LGUsbik+MClmb3IobGV0IG89dDtvPGU7bys9bilyPWpoKG8vbnwwLGlbb10saVtvKzFdLHIpO2Vsc2UgZm9yKGxldCBvPWUtbjtvPj10O28tPW4pcj1qaChvL258MCxpW29dLGlbbysxXSxyKTtyZXR1cm4gciYma3IocixyLm5leHQpJiYoUWkocikscj1yLm5leHQpLHJ9ZnVuY3Rpb24gdm4oaSx0KXtpZighaSlyZXR1cm4gaTt0fHwodD1pKTtsZXQgZT1pLG47ZG8gaWYobj0hMSwhZS5zdGVpbmVyJiYoa3IoZSxlLm5leHQpfHxhdChlLnByZXYsZSxlLm5leHQpPT09MCkpe2lmKFFpKGUpLGU9dD1lLnByZXYsZT09PWUubmV4dClicmVhaztuPSEwfWVsc2UgZT1lLm5leHQ7d2hpbGUobnx8ZSE9PXQpO3JldHVybiB0fWZ1bmN0aW9uIFlpKGksdCxlLG4scyxyLG8pe2lmKCFpKXJldHVybjshbyYmciYmX3koaSxuLHMscik7bGV0IGE9aTtmb3IoO2kucHJldiE9PWkubmV4dDspe2NvbnN0IGM9aS5wcmV2LGw9aS5uZXh0O2lmKHI/bXkoaSxuLHMscik6eXkoaSkpe3QucHVzaChjLmksaS5pLGwuaSksUWkoaSksaT1sLm5leHQsYT1sLm5leHQ7Y29udGludWV9aWYoaT1sLGk9PT1hKXtvP289PT0xPyhpPWd5KHZuKGkpLHQpLFlpKGksdCxlLG4scyxyLDIpKTpvPT09MiYmeHkoaSx0LGUsbixzLHIpOllpKHZuKGkpLHQsZSxuLHMsciwxKTticmVha319fWZ1bmN0aW9uIHl5KGkpe2NvbnN0IHQ9aS5wcmV2LGU9aSxuPWkubmV4dDtpZihhdCh0LGUsbik+PTApcmV0dXJuITE7Y29uc3Qgcz10Lngscj1lLngsbz1uLngsYT10LnksYz1lLnksbD1uLnksaD1zPHI/czxvP3M6bzpyPG8/cjpvLHU9YTxjP2E8bD9hOmw6YzxsP2M6bCxmPXM+cj9zPm8/czpvOnI+bz9yOm8sZD1hPmM/YT5sP2E6bDpjPmw/YzpsO2xldCBwPW4ubmV4dDtmb3IoO3AhPT10Oyl7aWYocC54Pj1oJiZwLng8PWYmJnAueT49dSYmcC55PD1kJiZjaShzLGEscixjLG8sbCxwLngscC55KSYmYXQocC5wcmV2LHAscC5uZXh0KT49MClyZXR1cm4hMTtwPXAubmV4dH1yZXR1cm4hMH1mdW5jdGlvbiBteShpLHQsZSxuKXtjb25zdCBzPWkucHJldixyPWksbz1pLm5leHQ7aWYoYXQocyxyLG8pPj0wKXJldHVybiExO2NvbnN0IGE9cy54LGM9ci54LGw9by54LGg9cy55LHU9ci55LGY9by55LGQ9YTxjP2E8bD9hOmw6YzxsP2M6bCxwPWg8dT9oPGY/aDpmOnU8Zj91OmYseT1hPmM/YT5sP2E6bDpjPmw/YzpsLG09aD51P2g+Zj9oOmY6dT5mP3U6ZixnPWphKGQscCx0LGUsbiksYj1qYSh5LG0sdCxlLG4pO2xldCB3PWkucHJldloseD1pLm5leHRaO2Zvcig7dyYmdy56Pj1nJiZ4JiZ4Lno8PWI7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmY2koYSxoLGMsdSxsLGYsdy54LHcueSkmJmF0KHcucHJldix3LHcubmV4dCk+PTB8fCh3PXcucHJldloseC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJmNpKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZhdCh4LnByZXYseCx4Lm5leHQpPj0wKSlyZXR1cm4hMTt4PXgubmV4dFp9Zm9yKDt3JiZ3Lno+PWc7KXtpZih3Lng+PWQmJncueDw9eSYmdy55Pj1wJiZ3Lnk8PW0mJnchPT1zJiZ3IT09byYmY2koYSxoLGMsdSxsLGYsdy54LHcueSkmJmF0KHcucHJldix3LHcubmV4dCk+PTApcmV0dXJuITE7dz13LnByZXZafWZvcig7eCYmeC56PD1iOyl7aWYoeC54Pj1kJiZ4Lng8PXkmJngueT49cCYmeC55PD1tJiZ4IT09cyYmeCE9PW8mJmNpKGEsaCxjLHUsbCxmLHgueCx4LnkpJiZhdCh4LnByZXYseCx4Lm5leHQpPj0wKXJldHVybiExO3g9eC5uZXh0Wn1yZXR1cm4hMH1mdW5jdGlvbiBneShpLHQpe2xldCBlPWk7ZG97Y29uc3Qgbj1lLnByZXYscz1lLm5leHQubmV4dDsha3IobixzKSYmSmgobixlLGUubmV4dCxzKSYmamkobixzKSYmamkocyxuKSYmKHQucHVzaChuLmksZS5pLHMuaSksUWkoZSksUWkoZS5uZXh0KSxlPWk9cyksZT1lLm5leHR9d2hpbGUoZSE9PWkpO3JldHVybiB2bihlKX1mdW5jdGlvbiB4eShpLHQsZSxuLHMscil7bGV0IG89aTtkb3tsZXQgYT1vLm5leHQubmV4dDtmb3IoO2EhPT1vLnByZXY7KXtpZihvLmkhPT1hLmkmJlR5KG8sYSkpe2xldCBjPVloKG8sYSk7bz12bihvLG8ubmV4dCksYz12bihjLGMubmV4dCksWWkobyx0LGUsbixzLHIsMCksWWkoYyx0LGUsbixzLHIsMCk7cmV0dXJufWE9YS5uZXh0fW89by5uZXh0fXdoaWxlKG8hPT1pKX1mdW5jdGlvbiB3eShpLHQsZSxuKXtjb25zdCBzPVtdO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdKm4sYz1yPG8tMT90W3IrMV0qbjppLmxlbmd0aCxsPVhoKGksYSxjLG4sITEpO2w9PT1sLm5leHQmJihsLnN0ZWluZXI9ITApLHMucHVzaCh6eShsKSl9cy5zb3J0KGJ5KTtmb3IobGV0IHI9MDtyPHMubGVuZ3RoO3IrKyllPU15KHNbcl0sZSk7cmV0dXJuIGV9ZnVuY3Rpb24gYnkoaSx0KXtyZXR1cm4gaS54LXQueH1mdW5jdGlvbiBNeShpLHQpe2NvbnN0IGU9QXkoaSx0KTtpZighZSlyZXR1cm4gdDtjb25zdCBuPVloKGUsaSk7cmV0dXJuIHZuKG4sbi5uZXh0KSx2bihlLGUubmV4dCl9ZnVuY3Rpb24gQXkoaSx0KXtsZXQgZT10O2NvbnN0IG49aS54LHM9aS55O2xldCByPS0xLzAsbztkb3tpZihzPD1lLnkmJnM+PWUubmV4dC55JiZlLm5leHQueSE9PWUueSl7Y29uc3QgdT1lLngrKHMtZS55KSooZS5uZXh0LngtZS54KS8oZS5uZXh0LnktZS55KTtpZih1PD1uJiZ1PnImJihyPXUsbz1lLng8ZS5uZXh0Lng/ZTplLm5leHQsdT09PW4pKXJldHVybiBvfWU9ZS5uZXh0fXdoaWxlKGUhPT10KTtpZighbylyZXR1cm4gbnVsbDtjb25zdCBhPW8sYz1vLngsbD1vLnk7bGV0IGg9MS8wO2U9bztkb3tpZihuPj1lLngmJmUueD49YyYmbiE9PWUueCYmY2koczxsP246cixzLGMsbCxzPGw/cjpuLHMsZS54LGUueSkpe2NvbnN0IHU9TWF0aC5hYnMocy1lLnkpLyhuLWUueCk7amkoZSxpKSYmKHU8aHx8dT09PWgmJihlLng+by54fHxlLng9PT1vLngmJlN5KG8sZSkpKSYmKG89ZSxoPXUpfWU9ZS5uZXh0fXdoaWxlKGUhPT1hKTtyZXR1cm4gb31mdW5jdGlvbiBTeShpLHQpe3JldHVybiBhdChpLnByZXYsaSx0LnByZXYpPDAmJmF0KHQubmV4dCxpLGkubmV4dCk8MH1mdW5jdGlvbiBfeShpLHQsZSxuKXtsZXQgcz1pO2RvIHMuej09PTAmJihzLno9amEocy54LHMueSx0LGUsbikpLHMucHJldlo9cy5wcmV2LHMubmV4dFo9cy5uZXh0LHM9cy5uZXh0O3doaWxlKHMhPT1pKTtzLnByZXZaLm5leHRaPW51bGwscy5wcmV2Wj1udWxsLHZ5KHMpfWZ1bmN0aW9uIHZ5KGkpe2xldCB0LGU9MTtkb3tsZXQgbj1pLHM7aT1udWxsO2xldCByPW51bGw7Zm9yKHQ9MDtuOyl7dCsrO2xldCBvPW4sYT0wO2ZvcihsZXQgbD0wO2w8ZSYmKGErKyxvPW8ubmV4dFosISFvKTtsKyspO2xldCBjPWU7Zm9yKDthPjB8fGM+MCYmbzspYSE9PTAmJihjPT09MHx8IW98fG4uejw9by56KT8ocz1uLG49bi5uZXh0WixhLS0pOihzPW8sbz1vLm5leHRaLGMtLSkscj9yLm5leHRaPXM6aT1zLHMucHJldlo9cixyPXM7bj1vfXIubmV4dFo9bnVsbCxlKj0yfXdoaWxlKHQ+MSk7cmV0dXJuIGl9ZnVuY3Rpb24gamEoaSx0LGUsbixzKXtyZXR1cm4gaT0oaS1lKSpzfDAsdD0odC1uKSpzfDAsaT0oaXxpPDw4KSYxNjcxMTkzNSxpPShpfGk8PDQpJjI1MjY0NTEzNSxpPShpfGk8PDIpJjg1ODk5MzQ1OSxpPShpfGk8PDEpJjE0MzE2NTU3NjUsdD0odHx0PDw4KSYxNjcxMTkzNSx0PSh0fHQ8PDQpJjI1MjY0NTEzNSx0PSh0fHQ8PDIpJjg1ODk5MzQ1OSx0PSh0fHQ8PDEpJjE0MzE2NTU3NjUsaXx0PDwxfWZ1bmN0aW9uIHp5KGkpe2xldCB0PWksZT1pO2RvKHQueDxlLnh8fHQueD09PWUueCYmdC55PGUueSkmJihlPXQpLHQ9dC5uZXh0O3doaWxlKHQhPT1pKTtyZXR1cm4gZX1mdW5jdGlvbiBjaShpLHQsZSxuLHMscixvLGEpe3JldHVybihzLW8pKih0LWEpPj0oaS1vKSooci1hKSYmKGktbykqKG4tYSk+PShlLW8pKih0LWEpJiYoZS1vKSooci1hKT49KHMtbykqKG4tYSl9ZnVuY3Rpb24gVHkoaSx0KXtyZXR1cm4gaS5uZXh0LmkhPT10LmkmJmkucHJldi5pIT09dC5pJiYhRXkoaSx0KSYmKGppKGksdCkmJmppKHQsaSkmJlB5KGksdCkmJihhdChpLnByZXYsaSx0LnByZXYpfHxhdChpLHQucHJldix0KSl8fGtyKGksdCkmJmF0KGkucHJldixpLGkubmV4dCk+MCYmYXQodC5wcmV2LHQsdC5uZXh0KT4wKX1mdW5jdGlvbiBhdChpLHQsZSl7cmV0dXJuKHQueS1pLnkpKihlLngtdC54KS0odC54LWkueCkqKGUueS10LnkpfWZ1bmN0aW9uIGtyKGksdCl7cmV0dXJuIGkueD09PXQueCYmaS55PT09dC55fWZ1bmN0aW9uIEpoKGksdCxlLG4pe2NvbnN0IHM9UnIoYXQoaSx0LGUpKSxyPVJyKGF0KGksdCxuKSksbz1ScihhdChlLG4saSkpLGE9UnIoYXQoZSxuLHQpKTtyZXR1cm4hIShzIT09ciYmbyE9PWF8fHM9PT0wJiZOcihpLGUsdCl8fHI9PT0wJiZOcihpLG4sdCl8fG89PT0wJiZOcihlLGksbil8fGE9PT0wJiZOcihlLHQsbikpfWZ1bmN0aW9uIE5yKGksdCxlKXtyZXR1cm4gdC54PD1NYXRoLm1heChpLngsZS54KSYmdC54Pj1NYXRoLm1pbihpLngsZS54KSYmdC55PD1NYXRoLm1heChpLnksZS55KSYmdC55Pj1NYXRoLm1pbihpLnksZS55KX1mdW5jdGlvbiBScihpKXtyZXR1cm4gaT4wPzE6aTwwPy0xOjB9ZnVuY3Rpb24gRXkoaSx0KXtsZXQgZT1pO2Rve2lmKGUuaSE9PWkuaSYmZS5uZXh0LmkhPT1pLmkmJmUuaSE9PXQuaSYmZS5uZXh0LmkhPT10LmkmJkpoKGUsZS5uZXh0LGksdCkpcmV0dXJuITA7ZT1lLm5leHR9d2hpbGUoZSE9PWkpO3JldHVybiExfWZ1bmN0aW9uIGppKGksdCl7cmV0dXJuIGF0KGkucHJldixpLGkubmV4dCk8MD9hdChpLHQsaS5uZXh0KT49MCYmYXQoaSxpLnByZXYsdCk+PTA6YXQoaSx0LGkucHJldik8MHx8YXQoaSxpLm5leHQsdCk8MH1mdW5jdGlvbiBQeShpLHQpe2xldCBlPWksbj0hMTtjb25zdCBzPShpLngrdC54KS8yLHI9KGkueSt0LnkpLzI7ZG8gZS55PnIhPWUubmV4dC55PnImJmUubmV4dC55IT09ZS55JiZzPChlLm5leHQueC1lLngpKihyLWUueSkvKGUubmV4dC55LWUueSkrZS54JiYobj0hbiksZT1lLm5leHQ7d2hpbGUoZSE9PWkpO3JldHVybiBufWZ1bmN0aW9uIFloKGksdCl7Y29uc3QgZT1RYShpLmksaS54LGkueSksbj1RYSh0LmksdC54LHQueSkscz1pLm5leHQscj10LnByZXY7cmV0dXJuIGkubmV4dD10LHQucHJldj1pLGUubmV4dD1zLHMucHJldj1lLG4ubmV4dD1lLGUucHJldj1uLHIubmV4dD1uLG4ucHJldj1yLG59ZnVuY3Rpb24gamgoaSx0LGUsbil7Y29uc3Qgcz1RYShpLHQsZSk7cmV0dXJuIG4/KHMubmV4dD1uLm5leHQscy5wcmV2PW4sbi5uZXh0LnByZXY9cyxuLm5leHQ9cyk6KHMucHJldj1zLHMubmV4dD1zKSxzfWZ1bmN0aW9uIFFpKGkpe2kubmV4dC5wcmV2PWkucHJldixpLnByZXYubmV4dD1pLm5leHQsaS5wcmV2WiYmKGkucHJldloubmV4dFo9aS5uZXh0WiksaS5uZXh0WiYmKGkubmV4dFoucHJldlo9aS5wcmV2Wil9ZnVuY3Rpb24gUWEoaSx0LGUpe3JldHVybntpLHg6dCx5OmUscHJldjpudWxsLG5leHQ6bnVsbCx6OjAscHJldlo6bnVsbCxuZXh0WjpudWxsLHN0ZWluZXI6ITF9fWZ1bmN0aW9uIEN5KGksdCxlLG4pe2xldCBzPTA7Zm9yKGxldCByPXQsbz1lLW47cjxlO3IrPW4pcys9KGlbb10taVtyXSkqKGlbcisxXStpW28rMV0pLG89cjtyZXR1cm4gc31mdW5jdGlvbiBRaChpKXtjb25zdCB0PVtdLGU9W10sbj1pWzBdWzBdLmxlbmd0aDtsZXQgcz0wLHI9MDtmb3IoY29uc3QgbyBvZiBpKXtmb3IoY29uc3QgYSBvZiBvKWZvcihsZXQgYz0wO2M8bjtjKyspdC5wdXNoKGFbY10pO3ImJihzKz1yLGUucHVzaChzKSkscj1vLmxlbmd0aH1yZXR1cm57dmVydGljZXM6dCxob2xlczplLGRpbWVuc2lvbnM6bn19ZnVuY3Rpb24gQnkoaSl7aWYoIWkpdGhyb3cgbmV3IEVycm9yKCJjb29yZCBpcyByZXF1aXJlZCIpO2lmKCFBcnJheS5pc0FycmF5KGkpKXtpZihpLnR5cGU9PT0iRmVhdHVyZSImJmkuZ2VvbWV0cnkhPT1udWxsJiZpLmdlb21ldHJ5LnR5cGU9PT0iUG9pbnQiKXJldHVyblsuLi5pLmdlb21ldHJ5LmNvb3JkaW5hdGVzXTtpZihpLnR5cGU9PT0iUG9pbnQiKXJldHVyblsuLi5pLmNvb3JkaW5hdGVzXX1pZihBcnJheS5pc0FycmF5KGkpJiZpLmxlbmd0aD49MiYmIUFycmF5LmlzQXJyYXkoaVswXSkmJiFBcnJheS5pc0FycmF5KGlbMV0pKXJldHVyblsuLi5pXTt0aHJvdyBuZXcgRXJyb3IoImNvb3JkIG11c3QgYmUgR2VvSlNPTiBQb2ludCBvciBhbiBBcnJheSBvZiBudW1iZXJzIil9ZnVuY3Rpb24gRnkoaSl7aWYoQXJyYXkuaXNBcnJheShpKSlyZXR1cm4gaTtpZihpLnR5cGU9PT0iRmVhdHVyZSIpe2lmKGkuZ2VvbWV0cnkhPT1udWxsKXJldHVybiBpLmdlb21ldHJ5LmNvb3JkaW5hdGVzfWVsc2UgaWYoaS5jb29yZGluYXRlcylyZXR1cm4gaS5jb29yZGluYXRlczt0aHJvdyBuZXcgRXJyb3IoImNvb3JkcyBtdXN0IGJlIEdlb0pTT04gRmVhdHVyZSwgR2VvbWV0cnkgT2JqZWN0IG9yIGFuIEFycmF5Iil9ZnVuY3Rpb24gSXkoaSl7cmV0dXJuIGkudHlwZT09PSJGZWF0dXJlIj9pLmdlb21ldHJ5Oml9ZnVuY3Rpb24ga3koaSl7Y29uc3QgdD1GeShpKTtsZXQgZT0wLG49MSxzLHI7Zm9yKDtuPHQubGVuZ3RoOylzPXJ8fHRbMF0scj10W25dLGUrPShyWzBdLXNbMF0pKihyWzFdK3NbMV0pLG4rKztyZXR1cm4gZT4wfXZhciBOeT1reTtjb25zdCBxZT0xMTEwMjIzMDI0NjI1MTU2NWUtMzIsdnQ9MTM0MjE3NzI5LFJ5PSgzKzgqcWUpKnFlO2Z1bmN0aW9uIEthKGksdCxlLG4scyl7bGV0IHIsbyxhLGMsbD10WzBdLGg9blswXSx1PTAsZj0wO2g+bD09aD4tbD8ocj1sLGw9dFsrK3VdKToocj1oLGg9blsrK2ZdKTtsZXQgZD0wO2lmKHU8aSYmZjxlKWZvcihoPmw9PWg+LWw/KG89bCtyLGE9ci0oby1sKSxsPXRbKyt1XSk6KG89aCtyLGE9ci0oby1oKSxoPW5bKytmXSkscj1vLGEhPT0wJiYoc1tkKytdPWEpO3U8aSYmZjxlOyloPmw9PWg+LWw/KG89citsLGM9by1yLGE9ci0oby1jKSsobC1jKSxsPXRbKyt1XSk6KG89citoLGM9by1yLGE9ci0oby1jKSsoaC1jKSxoPW5bKytmXSkscj1vLGEhPT0wJiYoc1tkKytdPWEpO2Zvcig7dTxpOylvPXIrbCxjPW8tcixhPXItKG8tYykrKGwtYyksbD10WysrdV0scj1vLGEhPT0wJiYoc1tkKytdPWEpO2Zvcig7ZjxlOylvPXIraCxjPW8tcixhPXItKG8tYykrKGgtYyksaD1uWysrZl0scj1vLGEhPT0wJiYoc1tkKytdPWEpO3JldHVybihyIT09MHx8ZD09PTApJiYoc1tkKytdPXIpLGR9ZnVuY3Rpb24gTHkoaSx0KXtsZXQgZT10WzBdO2ZvcihsZXQgbj0xO248aTtuKyspZSs9dFtuXTtyZXR1cm4gZX1mdW5jdGlvbiBLaShpKXtyZXR1cm4gbmV3IEZsb2F0NjRBcnJheShpKX1jb25zdCBPeT0oMysxNipxZSkqcWUsRHk9KDIrMTIqcWUpKnFlLCR5PSg5KzY0KnFlKSpxZSpxZSxsaT1LaSg0KSxLaD1LaSg4KSx0dT1LaSgxMiksZXU9S2koMTYpLEJ0PUtpKDQpO2Z1bmN0aW9uIFZ5KGksdCxlLG4scyxyLG8pe2xldCBhLGMsbCxoLHUsZixkLHAseSxtLGcsYix3LHgsTSxBLFMsXztjb25zdCBFPWktcyx6PWUtcyx2PXQtcixDPW4tcjt4PUUqQyxmPXZ0KkUsZD1mLShmLUUpLHA9RS1kLGY9dnQqQyx5PWYtKGYtQyksbT1DLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9dip6LGY9dnQqdixkPWYtKGYtdikscD12LWQsZj12dCp6LHk9Zi0oZi16KSxtPXoteSxTPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLVMsdT1NLWcsbGlbMF09TS0oZyt1KSsodS1TKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsbGlbMV09dy0oZyt1KSsodS1BKSxfPWIrZyx1PV8tYixsaVsyXT1iLShfLXUpKyhnLXUpLGxpWzNdPV87bGV0IFA9THkoNCxsaSksRj1EeSpvO2lmKFA+PUZ8fC1QPj1GfHwodT1pLUUsYT1pLShFK3UpKyh1LXMpLHU9ZS16LGw9ZS0oeit1KSsodS1zKSx1PXQtdixjPXQtKHYrdSkrKHUtciksdT1uLUMsaD1uLShDK3UpKyh1LXIpLGE9PT0wJiZjPT09MCYmbD09PTAmJmg9PT0wKXx8KEY9JHkqbytSeSpNYXRoLmFicyhQKSxQKz1FKmgrQyphLSh2KmwreipjKSxQPj1GfHwtUD49RikpcmV0dXJuIFA7eD1hKkMsZj12dCphLGQ9Zi0oZi1hKSxwPWEtZCxmPXZ0KkMseT1mLShmLUMpLG09Qy15LE09cCptLSh4LWQqeS1wKnktZCptKSxBPWMqeixmPXZ0KmMsZD1mLShmLWMpLHA9Yy1kLGY9dnQqeix5PWYtKGYteiksbT16LXksUz1wKm0tKEEtZCp5LXAqeS1kKm0pLGc9TS1TLHU9TS1nLEJ0WzBdPU0tKGcrdSkrKHUtUyksYj14K2csdT1iLXgsdz14LShiLXUpKyhnLXUpLGc9dy1BLHU9dy1nLEJ0WzFdPXctKGcrdSkrKHUtQSksXz1iK2csdT1fLWIsQnRbMl09Yi0oXy11KSsoZy11KSxCdFszXT1fO2NvbnN0IEI9S2EoNCxsaSw0LEJ0LEtoKTt4PUUqaCxmPXZ0KkUsZD1mLShmLUUpLHA9RS1kLGY9dnQqaCx5PWYtKGYtaCksbT1oLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9dipsLGY9dnQqdixkPWYtKGYtdikscD12LWQsZj12dCpsLHk9Zi0oZi1sKSxtPWwteSxTPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLVMsdT1NLWcsQnRbMF09TS0oZyt1KSsodS1TKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsQnRbMV09dy0oZyt1KSsodS1BKSxfPWIrZyx1PV8tYixCdFsyXT1iLShfLXUpKyhnLXUpLEJ0WzNdPV87Y29uc3QgST1LYShCLEtoLDQsQnQsdHUpO3g9YSpoLGY9dnQqYSxkPWYtKGYtYSkscD1hLWQsZj12dCpoLHk9Zi0oZi1oKSxtPWgteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT1jKmwsZj12dCpjLGQ9Zi0oZi1jKSxwPWMtZCxmPXZ0KmwseT1mLShmLWwpLG09bC15LFM9cCptLShBLWQqeS1wKnktZCptKSxnPU0tUyx1PU0tZyxCdFswXT1NLShnK3UpKyh1LVMpLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxCdFsxXT13LShnK3UpKyh1LUEpLF89YitnLHU9Xy1iLEJ0WzJdPWItKF8tdSkrKGctdSksQnRbM109Xztjb25zdCBrPUthKEksdHUsNCxCdCxldSk7cmV0dXJuIGV1W2stMV19ZnVuY3Rpb24gTHIoaSx0LGUsbixzLHIpe2NvbnN0IG89KHQtcikqKGUtcyksYT0oaS1zKSoobi1yKSxjPW8tYTtpZihvPT09MHx8YT09PTB8fG8+MCE9YT4wKXJldHVybiBjO2NvbnN0IGw9TWF0aC5hYnMobythKTtyZXR1cm4gTWF0aC5hYnMoYyk+PU95Kmw/YzotVnkoaSx0LGUsbixzLHIsbCl9Y29uc3QgbnU9TWF0aC5wb3coMiwtNTIpLE9yPW5ldyBVaW50MzJBcnJheSg1MTIpO2NsYXNzIHRze3N0YXRpYyBmcm9tKHQsZT1HeSxuPVp5KXtjb25zdCBzPXQubGVuZ3RoLHI9bmV3IEZsb2F0NjRBcnJheShzKjIpO2ZvcihsZXQgbz0wO288cztvKyspe2NvbnN0IGE9dFtvXTtyWzIqb109ZShhKSxyWzIqbysxXT1uKGEpfXJldHVybiBuZXcgdHMocil9Y29uc3RydWN0b3IodCl7Y29uc3QgZT10Lmxlbmd0aD4+MTtpZihlPjAmJnR5cGVvZiB0WzBdIT0ibnVtYmVyIil0aHJvdyBuZXcgRXJyb3IoIkV4cGVjdGVkIGNvb3JkcyB0byBjb250YWluIG51bWJlcnMuIik7dGhpcy5jb29yZHM9dDtjb25zdCBuPU1hdGgubWF4KDIqZS01LDApO3RoaXMuX3RyaWFuZ2xlcz1uZXcgVWludDMyQXJyYXkobiozKSx0aGlzLl9oYWxmZWRnZXM9bmV3IEludDMyQXJyYXkobiozKSx0aGlzLl9oYXNoU2l6ZT1NYXRoLmNlaWwoTWF0aC5zcXJ0KGUpKSx0aGlzLl9odWxsUHJldj1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbE5leHQ9bmV3IFVpbnQzMkFycmF5KGUpLHRoaXMuX2h1bGxUcmk9bmV3IFVpbnQzMkFycmF5KGUpLHRoaXMuX2h1bGxIYXNoPW5ldyBJbnQzMkFycmF5KHRoaXMuX2hhc2hTaXplKS5maWxsKC0xKSx0aGlzLl9pZHM9bmV3IFVpbnQzMkFycmF5KGUpLHRoaXMuX2Rpc3RzPW5ldyBGbG9hdDY0QXJyYXkoZSksdGhpcy51cGRhdGUoKX11cGRhdGUoKXtjb25zdHtjb29yZHM6dCxfaHVsbFByZXY6ZSxfaHVsbE5leHQ6bixfaHVsbFRyaTpzLF9odWxsSGFzaDpyfT10aGlzLG89dC5sZW5ndGg+PjE7bGV0IGE9MS8wLGM9MS8wLGw9LTEvMCxoPS0xLzA7Zm9yKGxldCB6PTA7ejxvO3orKyl7Y29uc3Qgdj10WzIqel0sQz10WzIqeisxXTt2PGEmJihhPXYpLEM8YyYmKGM9Qyksdj5sJiYobD12KSxDPmgmJihoPUMpLHRoaXMuX2lkc1t6XT16fWNvbnN0IHU9KGErbCkvMixmPShjK2gpLzI7bGV0IGQ9MS8wLHAseSxtO2ZvcihsZXQgej0wO3o8bzt6Kyspe2NvbnN0IHY9dGModSxmLHRbMip6XSx0WzIqeisxXSk7djxkJiYocD16LGQ9dil9Y29uc3QgZz10WzIqcF0sYj10WzIqcCsxXTtkPTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtpZih6PT09cCljb250aW51ZTtjb25zdCB2PXRjKGcsYix0WzIqel0sdFsyKnorMV0pO3Y8ZCYmdj4wJiYoeT16LGQ9dil9bGV0IHc9dFsyKnldLHg9dFsyKnkrMV0sTT0xLzA7Zm9yKGxldCB6PTA7ejxvO3orKyl7aWYoej09PXB8fHo9PT15KWNvbnRpbnVlO2NvbnN0IHY9SHkoZyxiLHcseCx0WzIqel0sdFsyKnorMV0pO3Y8TSYmKG09eixNPXYpfWxldCBBPXRbMiptXSxTPXRbMiptKzFdO2lmKE09PT0xLzApe2ZvcihsZXQgQz0wO0M8bztDKyspdGhpcy5fZGlzdHNbQ109dFsyKkNdLXRbMF18fHRbMipDKzFdLXRbMV07aGkodGhpcy5faWRzLHRoaXMuX2Rpc3RzLDAsby0xKTtjb25zdCB6PW5ldyBVaW50MzJBcnJheShvKTtsZXQgdj0wO2ZvcihsZXQgQz0wLFA9LTEvMDtDPG87QysrKXtjb25zdCBGPXRoaXMuX2lkc1tDXTt0aGlzLl9kaXN0c1tGXT5QJiYoelt2KytdPUYsUD10aGlzLl9kaXN0c1tGXSl9dGhpcy5odWxsPXouc3ViYXJyYXkoMCx2KSx0aGlzLnRyaWFuZ2xlcz1uZXcgVWludDMyQXJyYXkoMCksdGhpcy5oYWxmZWRnZXM9bmV3IFVpbnQzMkFycmF5KDApO3JldHVybn1pZihMcihnLGIsdyx4LEEsUyk8MCl7Y29uc3Qgej15LHY9dyxDPXg7eT1tLHc9QSx4PVMsbT16LEE9dixTPUN9Y29uc3QgXz1XeShnLGIsdyx4LEEsUyk7dGhpcy5fY3g9Xy54LHRoaXMuX2N5PV8ueTtmb3IobGV0IHo9MDt6PG87eisrKXRoaXMuX2Rpc3RzW3pdPXRjKHRbMip6XSx0WzIqeisxXSxfLngsXy55KTtoaSh0aGlzLl9pZHMsdGhpcy5fZGlzdHMsMCxvLTEpLHRoaXMuX2h1bGxTdGFydD1wO2xldCBFPTM7bltwXT1lW21dPXksblt5XT1lW3BdPW0sblttXT1lW3ldPXAsc1twXT0wLHNbeV09MSxzW21dPTIsci5maWxsKC0xKSxyW3RoaXMuX2hhc2hLZXkoZyxiKV09cCxyW3RoaXMuX2hhc2hLZXkodyx4KV09eSxyW3RoaXMuX2hhc2hLZXkoQSxTKV09bSx0aGlzLnRyaWFuZ2xlc0xlbj0wLHRoaXMuX2FkZFRyaWFuZ2xlKHAseSxtLC0xLC0xLC0xKTtmb3IobGV0IHo9MCx2LEM7ejx0aGlzLl9pZHMubGVuZ3RoO3orKyl7Y29uc3QgUD10aGlzLl9pZHNbel0sRj10WzIqUF0sQj10WzIqUCsxXTtpZih6PjAmJk1hdGguYWJzKEYtdik8PW51JiZNYXRoLmFicyhCLUMpPD1udXx8KHY9RixDPUIsUD09PXB8fFA9PT15fHxQPT09bSkpY29udGludWU7bGV0IEk9MDtmb3IobGV0IGR0PTAsRHQ9dGhpcy5faGFzaEtleShGLEIpO2R0PHRoaXMuX2hhc2hTaXplJiYoST1yWyhEdCtkdCkldGhpcy5faGFzaFNpemVdLCEoSSE9PS0xJiZJIT09bltJXSkpO2R0KyspO0k9ZVtJXTtsZXQgaz1JLEQ7Zm9yKDtEPW5ba10sTHIoRixCLHRbMiprXSx0WzIqaysxXSx0WzIqRF0sdFsyKkQrMV0pPj0wOylpZihrPUQsaz09PUkpe2s9LTE7YnJlYWt9aWYoaz09PS0xKWNvbnRpbnVlO2xldCBVPXRoaXMuX2FkZFRyaWFuZ2xlKGssUCxuW2tdLC0xLC0xLHNba10pO3NbUF09dGhpcy5fbGVnYWxpemUoVSsyKSxzW2tdPVUsRSsrO2xldCBqPW5ba107Zm9yKDtEPW5bal0sTHIoRixCLHRbMipqXSx0WzIqaisxXSx0WzIqRF0sdFsyKkQrMV0pPDA7KVU9dGhpcy5fYWRkVHJpYW5nbGUoaixQLEQsc1tQXSwtMSxzW2pdKSxzW1BdPXRoaXMuX2xlZ2FsaXplKFUrMiksbltqXT1qLEUtLSxqPUQ7aWYoaz09PUkpZm9yKDtEPWVba10sTHIoRixCLHRbMipEXSx0WzIqRCsxXSx0WzIqa10sdFsyKmsrMV0pPDA7KVU9dGhpcy5fYWRkVHJpYW5nbGUoRCxQLGssLTEsc1trXSxzW0RdKSx0aGlzLl9sZWdhbGl6ZShVKzIpLHNbRF09VSxuW2tdPWssRS0tLGs9RDt0aGlzLl9odWxsU3RhcnQ9ZVtQXT1rLG5ba109ZVtqXT1QLG5bUF09aixyW3RoaXMuX2hhc2hLZXkoRixCKV09UCxyW3RoaXMuX2hhc2hLZXkodFsyKmtdLHRbMiprKzFdKV09a310aGlzLmh1bGw9bmV3IFVpbnQzMkFycmF5KEUpO2ZvcihsZXQgej0wLHY9dGhpcy5faHVsbFN0YXJ0O3o8RTt6KyspdGhpcy5odWxsW3pdPXYsdj1uW3ZdO3RoaXMudHJpYW5nbGVzPXRoaXMuX3RyaWFuZ2xlcy5zdWJhcnJheSgwLHRoaXMudHJpYW5nbGVzTGVuKSx0aGlzLmhhbGZlZGdlcz10aGlzLl9oYWxmZWRnZXMuc3ViYXJyYXkoMCx0aGlzLnRyaWFuZ2xlc0xlbil9X2hhc2hLZXkodCxlKXtyZXR1cm4gTWF0aC5mbG9vcihVeSh0LXRoaXMuX2N4LGUtdGhpcy5fY3kpKnRoaXMuX2hhc2hTaXplKSV0aGlzLl9oYXNoU2l6ZX1fbGVnYWxpemUodCl7Y29uc3R7X3RyaWFuZ2xlczplLF9oYWxmZWRnZXM6bixjb29yZHM6c309dGhpcztsZXQgcj0wLG89MDtmb3IoOzspe2NvbnN0IGE9blt0XSxjPXQtdCUzO2lmKG89YysodCsyKSUzLGE9PT0tMSl7aWYocj09PTApYnJlYWs7dD1PclstLXJdO2NvbnRpbnVlfWNvbnN0IGw9YS1hJTMsaD1jKyh0KzEpJTMsdT1sKyhhKzIpJTMsZj1lW29dLGQ9ZVt0XSxwPWVbaF0seT1lW3VdO2lmKHF5KHNbMipmXSxzWzIqZisxXSxzWzIqZF0sc1syKmQrMV0sc1syKnBdLHNbMipwKzFdLHNbMip5XSxzWzIqeSsxXSkpe2VbdF09eSxlW2FdPWY7Y29uc3QgZz1uW3VdO2lmKGc9PT0tMSl7bGV0IHc9dGhpcy5faHVsbFN0YXJ0O2Rve2lmKHRoaXMuX2h1bGxUcmlbd109PT11KXt0aGlzLl9odWxsVHJpW3ddPXQ7YnJlYWt9dz10aGlzLl9odWxsUHJldlt3XX13aGlsZSh3IT09dGhpcy5faHVsbFN0YXJ0KX10aGlzLl9saW5rKHQsZyksdGhpcy5fbGluayhhLG5bb10pLHRoaXMuX2xpbmsobyx1KTtjb25zdCBiPWwrKGErMSklMztyPE9yLmxlbmd0aCYmKE9yW3IrK109Yil9ZWxzZXtpZihyPT09MClicmVhazt0PU9yWy0tcl19fXJldHVybiBvfV9saW5rKHQsZSl7dGhpcy5faGFsZmVkZ2VzW3RdPWUsZSE9PS0xJiYodGhpcy5faGFsZmVkZ2VzW2VdPXQpfV9hZGRUcmlhbmdsZSh0LGUsbixzLHIsbyl7Y29uc3QgYT10aGlzLnRyaWFuZ2xlc0xlbjtyZXR1cm4gdGhpcy5fdHJpYW5nbGVzW2FdPXQsdGhpcy5fdHJpYW5nbGVzW2ErMV09ZSx0aGlzLl90cmlhbmdsZXNbYSsyXT1uLHRoaXMuX2xpbmsoYSxzKSx0aGlzLl9saW5rKGErMSxyKSx0aGlzLl9saW5rKGErMixvKSx0aGlzLnRyaWFuZ2xlc0xlbis9MyxhfX1mdW5jdGlvbiBVeShpLHQpe2NvbnN0IGU9aS8oTWF0aC5hYnMoaSkrTWF0aC5hYnModCkpO3JldHVybih0PjA/My1lOjErZSkvNH1mdW5jdGlvbiB0YyhpLHQsZSxuKXtjb25zdCBzPWktZSxyPXQtbjtyZXR1cm4gcypzK3Iqcn1mdW5jdGlvbiBxeShpLHQsZSxuLHMscixvLGEpe2NvbnN0IGM9aS1vLGw9dC1hLGg9ZS1vLHU9bi1hLGY9cy1vLGQ9ci1hLHA9YypjK2wqbCx5PWgqaCt1KnUsbT1mKmYrZCpkO3JldHVybiBjKih1Km0teSpkKS1sKihoKm0teSpmKStwKihoKmQtdSpmKTwwfWZ1bmN0aW9uIEh5KGksdCxlLG4scyxyKXtjb25zdCBvPWUtaSxhPW4tdCxjPXMtaSxsPXItdCxoPW8qbythKmEsdT1jKmMrbCpsLGY9LjUvKG8qbC1hKmMpLGQ9KGwqaC1hKnUpKmYscD0obyp1LWMqaCkqZjtyZXR1cm4gZCpkK3AqcH1mdW5jdGlvbiBXeShpLHQsZSxuLHMscil7Y29uc3Qgbz1lLWksYT1uLXQsYz1zLWksbD1yLXQsaD1vKm8rYSphLHU9YypjK2wqbCxmPS41LyhvKmwtYSpjKSxkPWkrKGwqaC1hKnUpKmYscD10KyhvKnUtYypoKSpmO3JldHVybnt4OmQseTpwfX1mdW5jdGlvbiBoaShpLHQsZSxuKXtpZihuLWU8PTIwKWZvcihsZXQgcz1lKzE7czw9bjtzKyspe2NvbnN0IHI9aVtzXSxvPXRbcl07bGV0IGE9cy0xO2Zvcig7YT49ZSYmdFtpW2FdXT5vOylpW2ErMV09aVthLS1dO2lbYSsxXT1yfWVsc2V7Y29uc3Qgcz1lK24+PjE7bGV0IHI9ZSsxLG89bjtlcyhpLHMsciksdFtpW2VdXT50W2lbbl1dJiZlcyhpLGUsbiksdFtpW3JdXT50W2lbbl1dJiZlcyhpLHIsbiksdFtpW2VdXT50W2lbcl1dJiZlcyhpLGUscik7Y29uc3QgYT1pW3JdLGM9dFthXTtmb3IoOzspe2RvIHIrKzt3aGlsZSh0W2lbcl1dPGMpO2RvIG8tLTt3aGlsZSh0W2lbb11dPmMpO2lmKG88cilicmVhaztlcyhpLHIsbyl9aVtlKzFdPWlbb10saVtvXT1hLG4tcisxPj1vLWU/KGhpKGksdCxyLG4pLGhpKGksdCxlLG8tMSkpOihoaShpLHQsZSxvLTEpLGhpKGksdCxyLG4pKX19ZnVuY3Rpb24gZXMoaSx0LGUpe2NvbnN0IG49aVt0XTtpW3RdPWlbZV0saVtlXT1ufWZ1bmN0aW9uIEd5KGkpe3JldHVybiBpWzBdfWZ1bmN0aW9uIFp5KGkpe3JldHVybiBpWzFdfWZ1bmN0aW9uIFh5KGksdCl7dmFyIGU9MCxuPTAscz0wLHI9MCxvPTAsYT0wLGM9MCxsPTAsaD1udWxsLHU9bnVsbCxmPWlbMF0sZD1pWzFdLHA9dC5sZW5ndGg7Zm9yKGU7ZTxwO2UrKyl7bj0wO3ZhciB5PXRbZV0ubGVuZ3RoLTEsbT10W2VdO2lmKGg9bVswXSxoWzBdIT09bVt5XVswXSYmaFsxXSE9PW1beV1bMV0pdGhyb3cgbmV3IEVycm9yKCJGaXJzdCBhbmQgbGFzdCBjb29yZGluYXRlcyBpbiBhIHJpbmcgbXVzdCBiZSB0aGUgc2FtZSIpO2ZvcihvPWhbMF0tZixhPWhbMV0tZCxuO248eTtuKyspe2lmKHU9bVtuKzFdLGw9dVsxXS1kLGE8MCYmbDwwfHxhPjAmJmw+MCl7aD11LGE9bCxvPWhbMF0tZjtjb250aW51ZX1pZihjPXVbMF0taVswXSxsPjAmJmE8PTApe2lmKHI9bypsLWMqYSxyPjApcz1zKzE7ZWxzZSBpZihyPT09MClyZXR1cm4gMH1lbHNlIGlmKGE+MCYmbDw9MCl7aWYocj1vKmwtYyphLHI8MClzPXMrMTtlbHNlIGlmKHI9PT0wKXJldHVybiAwfWVsc2UgaWYobD09PTAmJmE8MCl7aWYocj1vKmwtYyphLHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT09PTAmJmw8MCl7aWYocj1vKmwtYyphLHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT09PTAmJmw9PT0wKXtpZihjPD0wJiZvPj0wKXJldHVybiAwO2lmKG88PTAmJmM+PTApcmV0dXJuIDB9aD11LGE9bCxvPWN9fXJldHVybiBzJTIhPT0wfWZ1bmN0aW9uIEp5KGksdCxlPXt9KXtpZighaSl0aHJvdyBuZXcgRXJyb3IoInBvaW50IGlzIHJlcXVpcmVkIik7aWYoIXQpdGhyb3cgbmV3IEVycm9yKCJwb2x5Z29uIGlzIHJlcXVpcmVkIik7Y29uc3Qgbj1CeShpKSxzPUl5KHQpLHI9cy50eXBlLG89dC5iYm94O2xldCBhPXMuY29vcmRpbmF0ZXM7aWYobyYmWXkobixvKT09PSExKXJldHVybiExO3I9PT0iUG9seWdvbiImJihhPVthXSk7bGV0IGM9ITE7Zm9yKHZhciBsPTA7bDxhLmxlbmd0aDsrK2wpe2NvbnN0IGg9WHkobixhW2xdKTtpZihoPT09MClyZXR1cm4hZS5pZ25vcmVCb3VuZGFyeTtoJiYoYz0hMCl9cmV0dXJuIGN9ZnVuY3Rpb24gWXkoaSx0KXtyZXR1cm4gdFswXTw9aVswXSYmdFsxXTw9aVsxXSYmdFsyXT49aVswXSYmdFszXT49aVsxXX12YXIgank9Snk7Y29uc3QgaXU9MWUtNjtjbGFzcyB6bntjb25zdHJ1Y3Rvcigpe3RoaXMuX3gwPXRoaXMuX3kwPXRoaXMuX3gxPXRoaXMuX3kxPW51bGwsdGhpcy5fPSIifW1vdmVUbyh0LGUpe3RoaXMuXys9YE0ke3RoaXMuX3gwPXRoaXMuX3gxPSt0fSwke3RoaXMuX3kwPXRoaXMuX3kxPStlfWB9Y2xvc2VQYXRoKCl7dGhpcy5feDEhPT1udWxsJiYodGhpcy5feDE9dGhpcy5feDAsdGhpcy5feTE9dGhpcy5feTAsdGhpcy5fKz0iWiIpfWxpbmVUbyh0LGUpe3RoaXMuXys9YEwke3RoaXMuX3gxPSt0fSwke3RoaXMuX3kxPStlfWB9YXJjKHQsZSxuKXt0PSt0LGU9K2Usbj0rbjtjb25zdCBzPXQrbixyPWU7aWYobjwwKXRocm93IG5ldyBFcnJvcigibmVnYXRpdmUgcmFkaXVzIik7dGhpcy5feDE9PT1udWxsP3RoaXMuXys9YE0ke3N9LCR7cn1gOihNYXRoLmFicyh0aGlzLl94MS1zKT5pdXx8TWF0aC5hYnModGhpcy5feTEtcik+aXUpJiYodGhpcy5fKz0iTCIrcysiLCIrciksbiYmKHRoaXMuXys9YEEke259LCR7bn0sMCwxLDEsJHt0LW59LCR7ZX1BJHtufSwke259LDAsMSwxLCR7dGhpcy5feDE9c30sJHt0aGlzLl95MT1yfWApfXJlY3QodCxlLG4scyl7dGhpcy5fKz1gTSR7dGhpcy5feDA9dGhpcy5feDE9K3R9LCR7dGhpcy5feTA9dGhpcy5feTE9K2V9aCR7K259diR7K3N9aCR7LW59WmB9dmFsdWUoKXtyZXR1cm4gdGhpcy5ffHxudWxsfX1jbGFzcyBlY3tjb25zdHJ1Y3Rvcigpe3RoaXMuXz1bXX1tb3ZlVG8odCxlKXt0aGlzLl8ucHVzaChbdCxlXSl9Y2xvc2VQYXRoKCl7dGhpcy5fLnB1c2godGhpcy5fWzBdLnNsaWNlKCkpfWxpbmVUbyh0LGUpe3RoaXMuXy5wdXNoKFt0LGVdKX12YWx1ZSgpe3JldHVybiB0aGlzLl8ubGVuZ3RoP3RoaXMuXzpudWxsfX1jbGFzcyBReXtjb25zdHJ1Y3Rvcih0LFtlLG4scyxyXT1bMCwwLDk2MCw1MDBdKXtpZighKChzPStzKT49KGU9K2UpKXx8ISgocj0rcik+PShuPStuKSkpdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIGJvdW5kcyIpO3RoaXMuZGVsYXVuYXk9dCx0aGlzLl9jaXJjdW1jZW50ZXJzPW5ldyBGbG9hdDY0QXJyYXkodC5wb2ludHMubGVuZ3RoKjIpLHRoaXMudmVjdG9ycz1uZXcgRmxvYXQ2NEFycmF5KHQucG9pbnRzLmxlbmd0aCoyKSx0aGlzLnhtYXg9cyx0aGlzLnhtaW49ZSx0aGlzLnltYXg9cix0aGlzLnltaW49bix0aGlzLl9pbml0KCl9dXBkYXRlKCl7cmV0dXJuIHRoaXMuZGVsYXVuYXkudXBkYXRlKCksdGhpcy5faW5pdCgpLHRoaXN9X2luaXQoKXtjb25zdHtkZWxhdW5heTp7cG9pbnRzOnQsaHVsbDplLHRyaWFuZ2xlczpufSx2ZWN0b3JzOnN9PXRoaXMscj10aGlzLmNpcmN1bWNlbnRlcnM9dGhpcy5fY2lyY3VtY2VudGVycy5zdWJhcnJheSgwLG4ubGVuZ3RoLzMqMik7Zm9yKGxldCBkPTAscD0wLHk9bi5sZW5ndGgsbSxnO2Q8eTtkKz0zLHArPTIpe2NvbnN0IGI9bltkXSoyLHc9bltkKzFdKjIseD1uW2QrMl0qMixNPXRbYl0sQT10W2IrMV0sUz10W3ddLF89dFt3KzFdLEU9dFt4XSx6PXRbeCsxXSx2PVMtTSxDPV8tQSxQPUUtTSxGPXotQSxCPSh2KkYtQypQKSoyO2lmKE1hdGguYWJzKEIpPDFlLTkpe2xldCBJPTFlOTtjb25zdCBrPW5bMF0qMjtJKj1NYXRoLnNpZ24oKHRba10tTSkqRi0odFtrKzFdLUEpKlApLG09KE0rRSkvMi1JKkYsZz0oQSt6KS8yK0kqUH1lbHNle2NvbnN0IEk9MS9CLGs9dip2K0MqQyxEPVAqUCtGKkY7bT1NKyhGKmstQypEKSpJLGc9QSsodipELVAqaykqSX1yW3BdPW0scltwKzFdPWd9bGV0IG89ZVtlLmxlbmd0aC0xXSxhLGM9byo0LGwsaD10WzIqb10sdSxmPXRbMipvKzFdO3MuZmlsbCgwKTtmb3IobGV0IGQ9MDtkPGUubGVuZ3RoOysrZClvPWVbZF0sYT1jLGw9aCx1PWYsYz1vKjQsaD10WzIqb10sZj10WzIqbysxXSxzW2ErMl09c1tjXT11LWYsc1thKzNdPXNbYysxXT1oLWx9cmVuZGVyKHQpe2NvbnN0IGU9dD09bnVsbD90PW5ldyB6bjp2b2lkIDAse2RlbGF1bmF5OntoYWxmZWRnZXM6bixpbmVkZ2VzOnMsaHVsbDpyfSxjaXJjdW1jZW50ZXJzOm8sdmVjdG9yczphfT10aGlzO2lmKHIubGVuZ3RoPD0xKXJldHVybiBudWxsO2ZvcihsZXQgaD0wLHU9bi5sZW5ndGg7aDx1OysraCl7Y29uc3QgZj1uW2hdO2lmKGY8aCljb250aW51ZTtjb25zdCBkPU1hdGguZmxvb3IoaC8zKSoyLHA9TWF0aC5mbG9vcihmLzMpKjIseT1vW2RdLG09b1tkKzFdLGc9b1twXSxiPW9bcCsxXTt0aGlzLl9yZW5kZXJTZWdtZW50KHksbSxnLGIsdCl9bGV0IGMsbD1yW3IubGVuZ3RoLTFdO2ZvcihsZXQgaD0wO2g8ci5sZW5ndGg7KytoKXtjPWwsbD1yW2hdO2NvbnN0IHU9TWF0aC5mbG9vcihzW2xdLzMpKjIsZj1vW3VdLGQ9b1t1KzFdLHA9Yyo0LHk9dGhpcy5fcHJvamVjdChmLGQsYVtwKzJdLGFbcCszXSk7eSYmdGhpcy5fcmVuZGVyU2VnbWVudChmLGQseVswXSx5WzFdLHQpfXJldHVybiBlJiZlLnZhbHVlKCl9cmVuZGVyQm91bmRzKHQpe2NvbnN0IGU9dD09bnVsbD90PW5ldyB6bjp2b2lkIDA7cmV0dXJuIHQucmVjdCh0aGlzLnhtaW4sdGhpcy55bWluLHRoaXMueG1heC10aGlzLnhtaW4sdGhpcy55bWF4LXRoaXMueW1pbiksZSYmZS52YWx1ZSgpfXJlbmRlckNlbGwodCxlKXtjb25zdCBuPWU9PW51bGw/ZT1uZXcgem46dm9pZCAwLHM9dGhpcy5fY2xpcCh0KTtpZihzPT09bnVsbHx8IXMubGVuZ3RoKXJldHVybjtlLm1vdmVUbyhzWzBdLHNbMV0pO2xldCByPXMubGVuZ3RoO2Zvcig7c1swXT09PXNbci0yXSYmc1sxXT09PXNbci0xXSYmcj4xOylyLT0yO2ZvcihsZXQgbz0yO288cjtvKz0yKShzW29dIT09c1tvLTJdfHxzW28rMV0hPT1zW28tMV0pJiZlLmxpbmVUbyhzW29dLHNbbysxXSk7cmV0dXJuIGUuY2xvc2VQYXRoKCksbiYmbi52YWx1ZSgpfSpjZWxsUG9seWdvbnMoKXtjb25zdHtkZWxhdW5heTp7cG9pbnRzOnR9fT10aGlzO2ZvcihsZXQgZT0wLG49dC5sZW5ndGgvMjtlPG47KytlKXtjb25zdCBzPXRoaXMuY2VsbFBvbHlnb24oZSk7cyYmKHMuaW5kZXg9ZSx5aWVsZCBzKX19Y2VsbFBvbHlnb24odCl7Y29uc3QgZT1uZXcgZWM7cmV0dXJuIHRoaXMucmVuZGVyQ2VsbCh0LGUpLGUudmFsdWUoKX1fcmVuZGVyU2VnbWVudCh0LGUsbixzLHIpe2xldCBvO2NvbnN0IGE9dGhpcy5fcmVnaW9uY29kZSh0LGUpLGM9dGhpcy5fcmVnaW9uY29kZShuLHMpO2E9PT0wJiZjPT09MD8oci5tb3ZlVG8odCxlKSxyLmxpbmVUbyhuLHMpKToobz10aGlzLl9jbGlwU2VnbWVudCh0LGUsbixzLGEsYykpJiYoci5tb3ZlVG8ob1swXSxvWzFdKSxyLmxpbmVUbyhvWzJdLG9bM10pKX1jb250YWlucyh0LGUsbil7cmV0dXJuIGU9K2UsZSE9PWV8fChuPStuLG4hPT1uKT8hMTp0aGlzLmRlbGF1bmF5Ll9zdGVwKHQsZSxuKT09PXR9Km5laWdoYm9ycyh0KXtjb25zdCBlPXRoaXMuX2NsaXAodCk7aWYoZSlmb3IoY29uc3QgbiBvZiB0aGlzLmRlbGF1bmF5Lm5laWdoYm9ycyh0KSl7Y29uc3Qgcz10aGlzLl9jbGlwKG4pO2lmKHMpe3Q6Zm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cis9Milmb3IobGV0IGE9MCxjPXMubGVuZ3RoO2E8YzthKz0yKWlmKGVbcl09PXNbYV0mJmVbcisxXT09c1thKzFdJiZlWyhyKzIpJW9dPT1zWyhhK2MtMiklY10mJmVbKHIrMyklb109PXNbKGErYy0xKSVjXSl7eWllbGQgbjticmVhayB0fX19fV9jZWxsKHQpe2NvbnN0e2NpcmN1bWNlbnRlcnM6ZSxkZWxhdW5heTp7aW5lZGdlczpuLGhhbGZlZGdlczpzLHRyaWFuZ2xlczpyfX09dGhpcyxvPW5bdF07aWYobz09PS0xKXJldHVybiBudWxsO2NvbnN0IGE9W107bGV0IGM9bztkb3tjb25zdCBsPU1hdGguZmxvb3IoYy8zKTtpZihhLnB1c2goZVtsKjJdLGVbbCoyKzFdKSxjPWMlMz09PTI/Yy0yOmMrMSxyW2NdIT09dClicmVhaztjPXNbY119d2hpbGUoYyE9PW8mJmMhPT0tMSk7cmV0dXJuIGF9X2NsaXAodCl7aWYodD09PTAmJnRoaXMuZGVsYXVuYXkuaHVsbC5sZW5ndGg9PT0xKXJldHVyblt0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWluXTtjb25zdCBlPXRoaXMuX2NlbGwodCk7aWYoZT09PW51bGwpcmV0dXJuIG51bGw7Y29uc3R7dmVjdG9yczpufT10aGlzLHM9dCo0O3JldHVybiBuW3NdfHxuW3MrMV0/dGhpcy5fY2xpcEluZmluaXRlKHQsZSxuW3NdLG5bcysxXSxuW3MrMl0sbltzKzNdKTp0aGlzLl9jbGlwRmluaXRlKHQsZSl9X2NsaXBGaW5pdGUodCxlKXtjb25zdCBuPWUubGVuZ3RoO2xldCBzPW51bGwscixvLGE9ZVtuLTJdLGM9ZVtuLTFdLGwsaD10aGlzLl9yZWdpb25jb2RlKGEsYyksdSxmPTA7Zm9yKGxldCBkPTA7ZDxuO2QrPTIpaWYocj1hLG89YyxhPWVbZF0sYz1lW2QrMV0sbD1oLGg9dGhpcy5fcmVnaW9uY29kZShhLGMpLGw9PT0wJiZoPT09MCl1PWYsZj0wLHM/cy5wdXNoKGEsYyk6cz1bYSxjXTtlbHNle2xldCBwLHksbSxnLGI7aWYobD09PTApe2lmKChwPXRoaXMuX2NsaXBTZWdtZW50KHIsbyxhLGMsbCxoKSk9PT1udWxsKWNvbnRpbnVlO1t5LG0sZyxiXT1wfWVsc2V7aWYoKHA9dGhpcy5fY2xpcFNlZ21lbnQoYSxjLHIsbyxoLGwpKT09PW51bGwpY29udGludWU7W2csYix5LG1dPXAsdT1mLGY9dGhpcy5fZWRnZWNvZGUoeSxtKSx1JiZmJiZ0aGlzLl9lZGdlKHQsdSxmLHMscy5sZW5ndGgpLHM/cy5wdXNoKHksbSk6cz1beSxtXX11PWYsZj10aGlzLl9lZGdlY29kZShnLGIpLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCkscz9zLnB1c2goZyxiKTpzPVtnLGJdfWlmKHMpdT1mLGY9dGhpcy5fZWRnZWNvZGUoc1swXSxzWzFdKSx1JiZmJiZ0aGlzLl9lZGdlKHQsdSxmLHMscy5sZW5ndGgpO2Vsc2UgaWYodGhpcy5jb250YWlucyh0LCh0aGlzLnhtaW4rdGhpcy54bWF4KS8yLCh0aGlzLnltaW4rdGhpcy55bWF4KS8yKSlyZXR1cm5bdGhpcy54bWF4LHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1pbl07cmV0dXJuIHN9X2NsaXBTZWdtZW50KHQsZSxuLHMscixvKXtmb3IoOzspe2lmKHI9PT0wJiZvPT09MClyZXR1cm5bdCxlLG4sc107aWYociZvKXJldHVybiBudWxsO2xldCBhLGMsbD1yfHxvO2wmOD8oYT10KyhuLXQpKih0aGlzLnltYXgtZSkvKHMtZSksYz10aGlzLnltYXgpOmwmND8oYT10KyhuLXQpKih0aGlzLnltaW4tZSkvKHMtZSksYz10aGlzLnltaW4pOmwmMj8oYz1lKyhzLWUpKih0aGlzLnhtYXgtdCkvKG4tdCksYT10aGlzLnhtYXgpOihjPWUrKHMtZSkqKHRoaXMueG1pbi10KS8obi10KSxhPXRoaXMueG1pbikscj8odD1hLGU9YyxyPXRoaXMuX3JlZ2lvbmNvZGUodCxlKSk6KG49YSxzPWMsbz10aGlzLl9yZWdpb25jb2RlKG4scykpfX1fY2xpcEluZmluaXRlKHQsZSxuLHMscixvKXtsZXQgYT1BcnJheS5mcm9tKGUpLGM7aWYoKGM9dGhpcy5fcHJvamVjdChhWzBdLGFbMV0sbixzKSkmJmEudW5zaGlmdChjWzBdLGNbMV0pLChjPXRoaXMuX3Byb2plY3QoYVthLmxlbmd0aC0yXSxhW2EubGVuZ3RoLTFdLHIsbykpJiZhLnB1c2goY1swXSxjWzFdKSxhPXRoaXMuX2NsaXBGaW5pdGUodCxhKSlmb3IobGV0IGw9MCxoPWEubGVuZ3RoLHUsZj10aGlzLl9lZGdlY29kZShhW2gtMl0sYVtoLTFdKTtsPGg7bCs9Mil1PWYsZj10aGlzLl9lZGdlY29kZShhW2xdLGFbbCsxXSksdSYmZiYmKGw9dGhpcy5fZWRnZSh0LHUsZixhLGwpLGg9YS5sZW5ndGgpO2Vsc2UgdGhpcy5jb250YWlucyh0LCh0aGlzLnhtaW4rdGhpcy54bWF4KS8yLCh0aGlzLnltaW4rdGhpcy55bWF4KS8yKSYmKGE9W3RoaXMueG1pbix0aGlzLnltaW4sdGhpcy54bWF4LHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltYXhdKTtyZXR1cm4gYX1fZWRnZSh0LGUsbixzLHIpe2Zvcig7ZSE9PW47KXtsZXQgbyxhO3N3aXRjaChlKXtjYXNlIDU6ZT00O2NvbnRpbnVlO2Nhc2UgNDplPTYsbz10aGlzLnhtYXgsYT10aGlzLnltaW47YnJlYWs7Y2FzZSA2OmU9Mjtjb250aW51ZTtjYXNlIDI6ZT0xMCxvPXRoaXMueG1heCxhPXRoaXMueW1heDticmVhaztjYXNlIDEwOmU9ODtjb250aW51ZTtjYXNlIDg6ZT05LG89dGhpcy54bWluLGE9dGhpcy55bWF4O2JyZWFrO2Nhc2UgOTplPTE7Y29udGludWU7Y2FzZSAxOmU9NSxvPXRoaXMueG1pbixhPXRoaXMueW1pbjticmVha30oc1tyXSE9PW98fHNbcisxXSE9PWEpJiZ0aGlzLmNvbnRhaW5zKHQsbyxhKSYmKHMuc3BsaWNlKHIsMCxvLGEpLHIrPTIpfWlmKHMubGVuZ3RoPjQpZm9yKGxldCBvPTA7bzxzLmxlbmd0aDtvKz0yKXtjb25zdCBhPShvKzIpJXMubGVuZ3RoLGM9KG8rNCklcy5sZW5ndGg7KHNbb109PT1zW2FdJiZzW2FdPT09c1tjXXx8c1tvKzFdPT09c1thKzFdJiZzW2ErMV09PT1zW2MrMV0pJiYocy5zcGxpY2UoYSwyKSxvLT0yKX1yZXR1cm4gcn1fcHJvamVjdCh0LGUsbixzKXtsZXQgcj0xLzAsbyxhLGM7aWYoczwwKXtpZihlPD10aGlzLnltaW4pcmV0dXJuIG51bGw7KG89KHRoaXMueW1pbi1lKS9zKTxyJiYoYz10aGlzLnltaW4sYT10KyhyPW8pKm4pfWVsc2UgaWYocz4wKXtpZihlPj10aGlzLnltYXgpcmV0dXJuIG51bGw7KG89KHRoaXMueW1heC1lKS9zKTxyJiYoYz10aGlzLnltYXgsYT10KyhyPW8pKm4pfWlmKG4+MCl7aWYodD49dGhpcy54bWF4KXJldHVybiBudWxsOyhvPSh0aGlzLnhtYXgtdCkvbik8ciYmKGE9dGhpcy54bWF4LGM9ZSsocj1vKSpzKX1lbHNlIGlmKG48MCl7aWYodDw9dGhpcy54bWluKXJldHVybiBudWxsOyhvPSh0aGlzLnhtaW4tdCkvbik8ciYmKGE9dGhpcy54bWluLGM9ZSsocj1vKSpzKX1yZXR1cm5bYSxjXX1fZWRnZWNvZGUodCxlKXtyZXR1cm4odD09PXRoaXMueG1pbj8xOnQ9PT10aGlzLnhtYXg/MjowKXwoZT09PXRoaXMueW1pbj80OmU9PT10aGlzLnltYXg/ODowKX1fcmVnaW9uY29kZSh0LGUpe3JldHVybih0PHRoaXMueG1pbj8xOnQ+dGhpcy54bWF4PzI6MCl8KGU8dGhpcy55bWluPzQ6ZT50aGlzLnltYXg/ODowKX19Y29uc3QgS3k9MipNYXRoLlBJLHVpPU1hdGgucG93O2Z1bmN0aW9uIHRtKGkpe3JldHVybiBpWzBdfWZ1bmN0aW9uIGVtKGkpe3JldHVybiBpWzFdfWZ1bmN0aW9uIG5tKGkpe2NvbnN0e3RyaWFuZ2xlczp0LGNvb3JkczplfT1pO2ZvcihsZXQgbj0wO248dC5sZW5ndGg7bis9Myl7Y29uc3Qgcz0yKnRbbl0scj0yKnRbbisxXSxvPTIqdFtuKzJdO2lmKChlW29dLWVbc10pKihlW3IrMV0tZVtzKzFdKS0oZVtyXS1lW3NdKSooZVtvKzFdLWVbcysxXSk+MWUtMTApcmV0dXJuITF9cmV0dXJuITB9ZnVuY3Rpb24gaW0oaSx0LGUpe3JldHVybltpK01hdGguc2luKGkrdCkqZSx0K01hdGguY29zKGktdCkqZV19Y2xhc3MgbmN7c3RhdGljIGZyb20odCxlPXRtLG49ZW0scyl7cmV0dXJuIG5ldyBuYygibGVuZ3RoImluIHQ/c20odCxlLG4scyk6RmxvYXQ2NEFycmF5LmZyb20ocm0odCxlLG4scykpKX1jb25zdHJ1Y3Rvcih0KXt0aGlzLl9kZWxhdW5hdG9yPW5ldyB0cyh0KSx0aGlzLmluZWRnZXM9bmV3IEludDMyQXJyYXkodC5sZW5ndGgvMiksdGhpcy5faHVsbEluZGV4PW5ldyBJbnQzMkFycmF5KHQubGVuZ3RoLzIpLHRoaXMucG9pbnRzPXRoaXMuX2RlbGF1bmF0b3IuY29vcmRzLHRoaXMuX2luaXQoKX11cGRhdGUoKXtyZXR1cm4gdGhpcy5fZGVsYXVuYXRvci51cGRhdGUoKSx0aGlzLl9pbml0KCksdGhpc31faW5pdCgpe2NvbnN0IHQ9dGhpcy5fZGVsYXVuYXRvcixlPXRoaXMucG9pbnRzO2lmKHQuaHVsbCYmdC5odWxsLmxlbmd0aD4yJiZubSh0KSl7dGhpcy5jb2xsaW5lYXI9SW50MzJBcnJheS5mcm9tKHtsZW5ndGg6ZS5sZW5ndGgvMn0sKGYsZCk9PmQpLnNvcnQoKGYsZCk9PmVbMipmXS1lWzIqZF18fGVbMipmKzFdLWVbMipkKzFdKTtjb25zdCBjPXRoaXMuY29sbGluZWFyWzBdLGw9dGhpcy5jb2xsaW5lYXJbdGhpcy5jb2xsaW5lYXIubGVuZ3RoLTFdLGg9W2VbMipjXSxlWzIqYysxXSxlWzIqbF0sZVsyKmwrMV1dLHU9MWUtOCpNYXRoLmh5cG90KGhbM10taFsxXSxoWzJdLWhbMF0pO2ZvcihsZXQgZj0wLGQ9ZS5sZW5ndGgvMjtmPGQ7KytmKXtjb25zdCBwPWltKGVbMipmXSxlWzIqZisxXSx1KTtlWzIqZl09cFswXSxlWzIqZisxXT1wWzFdfXRoaXMuX2RlbGF1bmF0b3I9bmV3IHRzKGUpfWVsc2UgZGVsZXRlIHRoaXMuY29sbGluZWFyO2NvbnN0IG49dGhpcy5oYWxmZWRnZXM9dGhpcy5fZGVsYXVuYXRvci5oYWxmZWRnZXMscz10aGlzLmh1bGw9dGhpcy5fZGVsYXVuYXRvci5odWxsLHI9dGhpcy50cmlhbmdsZXM9dGhpcy5fZGVsYXVuYXRvci50cmlhbmdsZXMsbz10aGlzLmluZWRnZXMuZmlsbCgtMSksYT10aGlzLl9odWxsSW5kZXguZmlsbCgtMSk7Zm9yKGxldCBjPTAsbD1uLmxlbmd0aDtjPGw7KytjKXtjb25zdCBoPXJbYyUzPT09Mj9jLTI6YysxXTsobltjXT09PS0xfHxvW2hdPT09LTEpJiYob1toXT1jKX1mb3IobGV0IGM9MCxsPXMubGVuZ3RoO2M8bDsrK2MpYVtzW2NdXT1jO3MubGVuZ3RoPD0yJiZzLmxlbmd0aD4wJiYodGhpcy50cmlhbmdsZXM9bmV3IEludDMyQXJyYXkoMykuZmlsbCgtMSksdGhpcy5oYWxmZWRnZXM9bmV3IEludDMyQXJyYXkoMykuZmlsbCgtMSksdGhpcy50cmlhbmdsZXNbMF09c1swXSxvW3NbMF1dPTEscy5sZW5ndGg9PT0yJiYob1tzWzFdXT0wLHRoaXMudHJpYW5nbGVzWzFdPXNbMV0sdGhpcy50cmlhbmdsZXNbMl09c1sxXSkpfXZvcm9ub2kodCl7cmV0dXJuIG5ldyBReSh0aGlzLHQpfSpuZWlnaGJvcnModCl7Y29uc3R7aW5lZGdlczplLGh1bGw6bixfaHVsbEluZGV4OnMsaGFsZmVkZ2VzOnIsdHJpYW5nbGVzOm8sY29sbGluZWFyOmF9PXRoaXM7aWYoYSl7Y29uc3QgdT1hLmluZGV4T2YodCk7dT4wJiYoeWllbGQgYVt1LTFdKSx1PGEubGVuZ3RoLTEmJih5aWVsZCBhW3UrMV0pO3JldHVybn1jb25zdCBjPWVbdF07aWYoYz09PS0xKXJldHVybjtsZXQgbD1jLGg9LTE7ZG97aWYoeWllbGQgaD1vW2xdLGw9bCUzPT09Mj9sLTI6bCsxLG9bbF0hPT10KXJldHVybjtpZihsPXJbbF0sbD09PS0xKXtjb25zdCB1PW5bKHNbdF0rMSklbi5sZW5ndGhdO3UhPT1oJiYoeWllbGQgdSk7cmV0dXJufX13aGlsZShsIT09Yyl9ZmluZCh0LGUsbj0wKXtpZih0PSt0LHQhPT10fHwoZT0rZSxlIT09ZSkpcmV0dXJuLTE7Y29uc3Qgcz1uO2xldCByO2Zvcig7KHI9dGhpcy5fc3RlcChuLHQsZSkpPj0wJiZyIT09biYmciE9PXM7KW49cjtyZXR1cm4gcn1fc3RlcCh0LGUsbil7Y29uc3R7aW5lZGdlczpzLGh1bGw6cixfaHVsbEluZGV4Om8saGFsZmVkZ2VzOmEsdHJpYW5nbGVzOmMscG9pbnRzOmx9PXRoaXM7aWYoc1t0XT09PS0xfHwhbC5sZW5ndGgpcmV0dXJuKHQrMSklKGwubGVuZ3RoPj4xKTtsZXQgaD10LHU9dWkoZS1sW3QqMl0sMikrdWkobi1sW3QqMisxXSwyKTtjb25zdCBmPXNbdF07bGV0IGQ9Zjtkb3tsZXQgcD1jW2RdO2NvbnN0IHk9dWkoZS1sW3AqMl0sMikrdWkobi1sW3AqMisxXSwyKTtpZih5PHUmJih1PXksaD1wKSxkPWQlMz09PTI/ZC0yOmQrMSxjW2RdIT09dClicmVhaztpZihkPWFbZF0sZD09PS0xKXtpZihkPXJbKG9bdF0rMSklci5sZW5ndGhdLGQhPT1wJiZ1aShlLWxbZCoyXSwyKSt1aShuLWxbZCoyKzFdLDIpPHUpcmV0dXJuIGQ7YnJlYWt9fXdoaWxlKGQhPT1mKTtyZXR1cm4gaH1yZW5kZXIodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7cG9pbnRzOm4saGFsZmVkZ2VzOnMsdHJpYW5nbGVzOnJ9PXRoaXM7Zm9yKGxldCBvPTAsYT1zLmxlbmd0aDtvPGE7KytvKXtjb25zdCBjPXNbb107aWYoYzxvKWNvbnRpbnVlO2NvbnN0IGw9cltvXSoyLGg9cltjXSoyO3QubW92ZVRvKG5bbF0sbltsKzFdKSx0LmxpbmVUbyhuW2hdLG5baCsxXSl9cmV0dXJuIHRoaXMucmVuZGVySHVsbCh0KSxlJiZlLnZhbHVlKCl9cmVuZGVyUG9pbnRzKHQsZSl7ZT09PXZvaWQgMCYmKCF0fHx0eXBlb2YgdC5tb3ZlVG8hPSJmdW5jdGlvbiIpJiYoZT10LHQ9bnVsbCksZT1lPT1udWxsPzI6K2U7Y29uc3Qgbj10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7cG9pbnRzOnN9PXRoaXM7Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cis9Mil7Y29uc3QgYT1zW3JdLGM9c1tyKzFdO3QubW92ZVRvKGErZSxjKSx0LmFyYyhhLGMsZSwwLEt5KX1yZXR1cm4gbiYmbi52YWx1ZSgpfXJlbmRlckh1bGwodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHpuOnZvaWQgMCx7aHVsbDpuLHBvaW50czpzfT10aGlzLHI9blswXSoyLG89bi5sZW5ndGg7dC5tb3ZlVG8oc1tyXSxzW3IrMV0pO2ZvcihsZXQgYT0xO2E8bzsrK2Epe2NvbnN0IGM9MipuW2FdO3QubGluZVRvKHNbY10sc1tjKzFdKX1yZXR1cm4gdC5jbG9zZVBhdGgoKSxlJiZlLnZhbHVlKCl9aHVsbFBvbHlnb24oKXtjb25zdCB0PW5ldyBlYztyZXR1cm4gdGhpcy5yZW5kZXJIdWxsKHQpLHQudmFsdWUoKX1yZW5kZXJUcmlhbmdsZSh0LGUpe2NvbnN0IG49ZT09bnVsbD9lPW5ldyB6bjp2b2lkIDAse3BvaW50czpzLHRyaWFuZ2xlczpyfT10aGlzLG89clt0Kj0zXSoyLGE9clt0KzFdKjIsYz1yW3QrMl0qMjtyZXR1cm4gZS5tb3ZlVG8oc1tvXSxzW28rMV0pLGUubGluZVRvKHNbYV0sc1thKzFdKSxlLmxpbmVUbyhzW2NdLHNbYysxXSksZS5jbG9zZVBhdGgoKSxuJiZuLnZhbHVlKCl9KnRyaWFuZ2xlUG9seWdvbnMoKXtjb25zdHt0cmlhbmdsZXM6dH09dGhpcztmb3IobGV0IGU9MCxuPXQubGVuZ3RoLzM7ZTxuOysrZSl5aWVsZCB0aGlzLnRyaWFuZ2xlUG9seWdvbihlKX10cmlhbmdsZVBvbHlnb24odCl7Y29uc3QgZT1uZXcgZWM7cmV0dXJuIHRoaXMucmVuZGVyVHJpYW5nbGUodCxlKSxlLnZhbHVlKCl9fWZ1bmN0aW9uIHNtKGksdCxlLG4pe2NvbnN0IHM9aS5sZW5ndGgscj1uZXcgRmxvYXQ2NEFycmF5KHMqMik7Zm9yKGxldCBvPTA7bzxzOysrbyl7Y29uc3QgYT1pW29dO3JbbyoyXT10LmNhbGwobixhLG8saSkscltvKjIrMV09ZS5jYWxsKG4sYSxvLGkpfXJldHVybiByfWZ1bmN0aW9uKnJtKGksdCxlLG4pe2xldCBzPTA7Zm9yKGNvbnN0IHIgb2YgaSl5aWVsZCB0LmNhbGwobixyLHMsaSkseWllbGQgZS5jYWxsKG4scixzLGkpLCsrc31jb25zdCBpYz1NYXRoLlBJLHN1PWljLzIscnU9MTgwL2ljLG91PWljLzE4MCxvbT1NYXRoLmF0YW4yLGF1PU1hdGguY29zLGFtPU1hdGgubWF4LGNtPU1hdGgubWluLGN1PU1hdGguc2luLGxtPU1hdGguc2lnbnx8ZnVuY3Rpb24oaSl7cmV0dXJuIGk+MD8xOmk8MD8tMTowfSxsdT1NYXRoLnNxcnQ7ZnVuY3Rpb24gaG0oaSl7cmV0dXJuIGk+MT9zdTppPC0xPy1zdTpNYXRoLmFzaW4oaSl9ZnVuY3Rpb24gaHUoaSx0KXtyZXR1cm4gaVswXSp0WzBdK2lbMV0qdFsxXStpWzJdKnRbMl19ZnVuY3Rpb24gV3QoaSx0KXtyZXR1cm5baVsxXSp0WzJdLWlbMl0qdFsxXSxpWzJdKnRbMF0taVswXSp0WzJdLGlbMF0qdFsxXS1pWzFdKnRbMF1dfWZ1bmN0aW9uIERyKGksdCl7cmV0dXJuW2lbMF0rdFswXSxpWzFdK3RbMV0saVsyXSt0WzJdXX1mdW5jdGlvbiAkcihpKXt2YXIgdD1sdShpWzBdKmlbMF0raVsxXSppWzFdK2lbMl0qaVsyXSk7cmV0dXJuW2lbMF0vdCxpWzFdL3QsaVsyXS90XX1mdW5jdGlvbiBzYyhpKXtyZXR1cm5bb20oaVsxXSxpWzBdKSpydSxobShhbSgtMSxjbSgxLGlbMl0pKSkqcnVdfWZ1bmN0aW9uIE1lKGkpe2NvbnN0IHQ9aVswXSpvdSxlPWlbMV0qb3Usbj1hdShlKTtyZXR1cm5bbiphdSh0KSxuKmN1KHQpLGN1KGUpXX1mdW5jdGlvbiByYyhpKXtyZXR1cm4gaT1pLm1hcCh0PT5NZSh0KSksaHUoaVswXSxXdChpWzJdLGlbMV0pKX1mdW5jdGlvbiB1bShpKXtjb25zdCB0PWRtKGkpLGU9eW0odCksbj1wbShlLGkpLHM9Z20oZSxpLmxlbmd0aCkscj1mbShzLGkpLG89bW0oZSxpKSx7cG9seWdvbnM6YSxjZW50ZXJzOmN9PXhtKG8sZSxpKSxsPXdtKGEpLGg9TW0oZSxpKSx1PWJtKG4sZSk7cmV0dXJue2RlbGF1bmF5OnQsZWRnZXM6bix0cmlhbmdsZXM6ZSxjZW50ZXJzOmMsbmVpZ2hib3JzOnMscG9seWdvbnM6YSxtZXNoOmwsaHVsbDpoLHVycXVoYXJ0OnUsZmluZDpyfX1mdW5jdGlvbiBmbShpLHQpe2Z1bmN0aW9uIGUobixzKXtsZXQgcj1uWzBdLXNbMF0sbz1uWzFdLXNbMV0sYT1uWzJdLXNbMl07cmV0dXJuIHIqcitvKm8rYSphfXJldHVybiBmdW5jdGlvbihzLHIsbyl7bz09PXZvaWQgMCYmKG89MCk7bGV0IGEsYyxsPW87Y29uc3QgaD1NZShbcyxyXSk7ZG8gYT1vLG89bnVsbCxjPWUoaCxNZSh0W2FdKSksaVthXS5mb3JFYWNoKHU9PntsZXQgZj1lKGgsTWUodFt1XSkpO2lmKGY8Yyl7Yz1mLG89dSxsPXU7cmV0dXJufX0pO3doaWxlKG8hPT1udWxsKTtyZXR1cm4gbH19ZnVuY3Rpb24gZG0oaSl7aWYoaS5sZW5ndGg8MilyZXR1cm57fTtsZXQgdD0wO2Zvcig7aXNOYU4oaVt0XVswXStpW3RdWzFdKSYmdCsrPGkubGVuZ3RoOyk7Y29uc3QgZT1TaChpW3RdKSxuPWl5KCkudHJhbnNsYXRlKFswLDBdKS5zY2FsZSgxKS5yb3RhdGUoZS5pbnZlcnQoWzE4MCwwXSkpO2k9aS5tYXAobik7Y29uc3Qgcz1bXTtsZXQgcj0xO2ZvcihsZXQgdT0wLGY9aS5sZW5ndGg7dTxmO3UrKyl7bGV0IGQ9eWkoaVt1XVswXSwyKSt5aShpW3VdWzFdLDIpOyFpc0Zpbml0ZShkKXx8ZD4xZTMyP3MucHVzaCh1KTpkPnImJihyPWQpfWNvbnN0IG89MWU2Kmx1KHIpO3MuZm9yRWFjaCh1PT5pW3VdPVtvLDBdKSxpLnB1c2goWzAsb10pLGkucHVzaChbLW8sMF0pLGkucHVzaChbMCwtb10pO2NvbnN0IGE9bmMuZnJvbShpKTthLnByb2plY3Rpb249bjtjb25zdHt0cmlhbmdsZXM6YyxoYWxmZWRnZXM6bCxpbmVkZ2VzOmh9PWE7Zm9yKGxldCB1PTAsZj1sLmxlbmd0aDt1PGY7dSsrKWlmKGxbdV08MCl7Y29uc3QgZD11JTM9PTI/dS0yOnUrMSxwPXUlMz09MD91KzI6dS0xLHk9bFtkXSxtPWxbcF07bFt5XT1tLGxbbV09eSxsW2RdPWxbcF09LTEsY1t1XT1jW2RdPWNbcF09dCxoW2NbeV1dPXklMz09MD95KzI6eS0xLGhbY1ttXV09bSUzPT0wP20rMjptLTEsdSs9Mi11JTN9ZWxzZSBjW3VdPmkubGVuZ3RoLTMtMSYmKGNbdV09dCk7cmV0dXJuIGF9ZnVuY3Rpb24gcG0oaSx0KXtjb25zdCBlPW5ldyBTZXQ7cmV0dXJuIHQubGVuZ3RoPT09Mj9bWzAsMV1dOihpLmZvckVhY2gobj0+e2lmKG5bMF0hPT1uWzFdJiYhKHJjKG4ubWFwKHM9PnRbc10pKTwwKSlmb3IobGV0IHM9MCxyO3M8MztzKyspcj0ocysxKSUzLGUuYWRkKHNyKFtuW3NdLG5bcl1dKS5qb2luKCItIikpfSksQXJyYXkuZnJvbShlLG49Pm4uc3BsaXQoIi0iKS5tYXAoTnVtYmVyKSkpfWZ1bmN0aW9uIHltKGkpe2NvbnN0e3RyaWFuZ2xlczp0fT1pO2lmKCF0KXJldHVybltdO2NvbnN0IGU9W107Zm9yKGxldCBuPTAscz10Lmxlbmd0aC8zO248cztuKyspe2NvbnN0IHI9dFszKm5dLG89dFszKm4rMV0sYT10WzMqbisyXTtyIT09byYmbyE9PWEmJmUucHVzaChbcixhLG9dKX1yZXR1cm4gZX1mdW5jdGlvbiBtbShpLHQpe3JldHVybiBpLm1hcChlPT57Y29uc3Qgbj1lLm1hcChyPT50W3JdKS5tYXAoTWUpLHM9RHIoRHIoV3QoblsxXSxuWzBdKSxXdChuWzJdLG5bMV0pKSxXdChuWzBdLG5bMl0pKTtyZXR1cm4gc2MoJHIocykpfSl9ZnVuY3Rpb24gZ20oaSx0KXtjb25zdCBlPVtdO3JldHVybiBpLmZvckVhY2gobj0+e2ZvcihsZXQgcz0wO3M8MztzKyspe2NvbnN0IHI9bltzXSxvPW5bKHMrMSklM107ZVtyXT1lW3JdfHxbXSxlW3JdLnB1c2gobyl9fSksaS5sZW5ndGg9PT0wJiYodD09PTI/KGVbMF09WzFdLGVbMV09WzBdKTp0PT09MSYmKGVbMF09W10pKSxlfWZ1bmN0aW9uIHhtKGksdCxlKXtjb25zdCBuPVtdLHM9aS5zbGljZSgpO2lmKHQubGVuZ3RoPT09MCl7aWYoZS5sZW5ndGg8MilyZXR1cm57cG9seWdvbnM6bixjZW50ZXJzOnN9O2lmKGUubGVuZ3RoPT09Mil7Y29uc3QgYT1NZShlWzBdKSxjPU1lKGVbMV0pLGw9JHIoRHIoYSxjKSksaD0kcihXdChhLGMpKSx1PVd0KGwsaCksZj1bbCxXdChsLHUpLFd0KFd0KGwsdSksdSksV3QoV3QoV3QobCx1KSx1KSx1KV0ubWFwKHNjKS5tYXAobyk7cmV0dXJuIG4ucHVzaChmKSxuLnB1c2goZi5zbGljZSgpLnJldmVyc2UoKSkse3BvbHlnb25zOm4sY2VudGVyczpzfX19dC5mb3JFYWNoKChhLGMpPT57Zm9yKGxldCBsPTA7bDwzO2wrKyl7Y29uc3QgaD1hW2xdLHU9YVsobCsxKSUzXSxmPWFbKGwrMiklM107bltoXT1uW2hdfHxbXSxuW2hdLnB1c2goW3UsZixjLFtoLHUsZl1dKX19KTtjb25zdCByPW4ubWFwKGE9Pntjb25zdCBjPVthWzBdWzJdXTtsZXQgbD1hWzBdWzFdO2ZvcihsZXQgaD0xO2g8YS5sZW5ndGg7aCsrKWZvcihsZXQgdT0wO3U8YS5sZW5ndGg7dSsrKWlmKGFbdV1bMF09PWwpe2w9YVt1XVsxXSxjLnB1c2goYVt1XVsyXSk7YnJlYWt9aWYoYy5sZW5ndGg+MilyZXR1cm4gYztpZihjLmxlbmd0aD09Mil7Y29uc3QgaD11dShlW2FbMF1bM11bMF1dLGVbYVswXVszXVsxXV0sc1tjWzBdXSksdT11dShlW2FbMF1bM11bMl1dLGVbYVswXVszXVswXV0sc1tjWzBdXSksZj1vKGgpLGQ9byh1KTtyZXR1cm5bY1swXSxkLGNbMV0sZl19fSk7ZnVuY3Rpb24gbyhhKXtsZXQgYz0tMTtyZXR1cm4gcy5zbGljZSh0Lmxlbmd0aCwxLzApLmZvckVhY2goKGwsaCk9PntsWzBdPT09YVswXSYmbFsxXT09PWFbMV0mJihjPWgrdC5sZW5ndGgpfSksYzwwJiYoYz1zLmxlbmd0aCxzLnB1c2goYSkpLGN9cmV0dXJue3BvbHlnb25zOnIsY2VudGVyczpzfX1mdW5jdGlvbiB1dShpLHQsZSl7aT1NZShpKSx0PU1lKHQpLGU9TWUoZSk7Y29uc3Qgbj1sbShodShXdCh0LGkpLGUpKTtyZXR1cm4gc2MoJHIoRHIoaSx0KSkubWFwKHM9Pm4qcykpfWZ1bmN0aW9uIHdtKGkpe2NvbnN0IHQ9W107cmV0dXJuIGkuZm9yRWFjaChlPT57aWYoIWUpcmV0dXJuO2xldCBuPWVbZS5sZW5ndGgtMV07Zm9yKGxldCBzIG9mIGUpcz5uJiZ0LnB1c2goW24sc10pLG49c30pLHR9ZnVuY3Rpb24gYm0oaSx0KXtyZXR1cm4gZnVuY3Rpb24oZSl7Y29uc3Qgbj1uZXcgTWFwLHM9bmV3IE1hcDtyZXR1cm4gaS5mb3JFYWNoKChyLG8pPT57Y29uc3QgYT1yLmpvaW4oIi0iKTtuLnNldChhLGVbb10pLHMuc2V0KGEsITApfSksdC5mb3JFYWNoKHI9PntsZXQgbz0wLGE9LTE7Zm9yKGxldCBjPTA7YzwzO2MrKyl7bGV0IGw9c3IoW3JbY10sclsoYysxKSUzXV0pLmpvaW4oIi0iKTtuLmdldChsKT5vJiYobz1uLmdldChsKSxhPWwpfXMuc2V0KGEsITEpfSksaS5tYXAocj0+cy5nZXQoci5qb2luKCItIikpKX19ZnVuY3Rpb24gTW0oaSx0KXtjb25zdCBlPW5ldyBTZXQsbj1bXTtpLm1hcChhPT57aWYoIShyYyhhLm1hcChjPT50W2M+dC5sZW5ndGg/MDpjXSkpPjFlLTEyKSlmb3IobGV0IGM9MDtjPDM7YysrKXtsZXQgbD1bYVtjXSxhWyhjKzEpJTNdXSxoPWAke2xbMF19LSR7bFsxXX1gO2UuaGFzKGgpP2UuZGVsZXRlKGgpOmUuYWRkKGAke2xbMV19LSR7bFswXX1gKX19KTtjb25zdCBzPW5ldyBNYXA7bGV0IHI7aWYoZS5mb3JFYWNoKGE9PnthPWEuc3BsaXQoIi0iKS5tYXAoTnVtYmVyKSxzLnNldChhWzBdLGFbMV0pLHI9YVswXX0pLHI9PT12b2lkIDApcmV0dXJuIG47bGV0IG89cjtkb3tuLnB1c2gobyk7bGV0IGE9cy5nZXQobyk7cy5zZXQobywtMSksbz1hfXdoaWxlKG8+LTEmJm8hPT1yKTtyZXR1cm4gbn1mdW5jdGlvbiBBbShpKXtjb25zdCB0PWZ1bmN0aW9uKGUpe2lmKHQuZGVsYXVuYXk9bnVsbCx0Ll9kYXRhPWUsdHlwZW9mIHQuX2RhdGE9PSJvYmplY3QiJiZ0Ll9kYXRhLnR5cGU9PT0iRmVhdHVyZUNvbGxlY3Rpb24iJiYodC5fZGF0YT10Ll9kYXRhLmZlYXR1cmVzKSx0eXBlb2YgdC5fZGF0YT09Im9iamVjdCIpe2NvbnN0IG49dC5fZGF0YS5tYXAocz0+W3QuX3Z4KHMpLHQuX3Z5KHMpLHNdKS5maWx0ZXIocz0+aXNGaW5pdGUoc1swXStzWzFdKSk7dC5wb2ludHM9bi5tYXAocz0+W3NbMF0sc1sxXV0pLHQudmFsaWQ9bi5tYXAocz0+c1syXSksdC5kZWxhdW5heT11bSh0LnBvaW50cyl9cmV0dXJuIHR9O3JldHVybiB0Ll92eD1mdW5jdGlvbihlKXtpZih0eXBlb2YgZT09Im9iamVjdCImJiJ0eXBlImluIGUpcmV0dXJuIHhoKGUpWzBdO2lmKDAgaW4gZSlyZXR1cm4gZVswXX0sdC5fdnk9ZnVuY3Rpb24oZSl7aWYodHlwZW9mIGU9PSJvYmplY3QiJiYidHlwZSJpbiBlKXJldHVybiB4aChlKVsxXTtpZigxIGluIGUpcmV0dXJuIGVbMV19LHQueD1mdW5jdGlvbihlKXtyZXR1cm4gZT8odC5fdng9ZSx0KTp0Ll92eH0sdC55PWZ1bmN0aW9uKGUpe3JldHVybiBlPyh0Ll92eT1lLHQpOnQuX3Z5fSx0LnBvbHlnb25zPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3Qgbj17dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOltdfTtyZXR1cm4gdC52YWxpZC5sZW5ndGg9PT0wfHwodC5kZWxhdW5heS5wb2x5Z29ucy5mb3JFYWNoKChzLHIpPT5uLmZlYXR1cmVzLnB1c2goe3R5cGU6IkZlYXR1cmUiLGdlb21ldHJ5OnM/e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOltbLi4ucyxzWzBdXS5tYXAobz0+dC5kZWxhdW5heS5jZW50ZXJzW29dKV19Om51bGwscHJvcGVydGllczp7c2l0ZTp0LnZhbGlkW3JdLHNpdGVjb29yZGluYXRlczp0LnBvaW50c1tyXSxuZWlnaGJvdXJzOnQuZGVsYXVuYXkubmVpZ2hib3JzW3JdfX0pKSx0LnZhbGlkLmxlbmd0aD09PTEmJm4uZmVhdHVyZXMucHVzaCh7dHlwZToiRmVhdHVyZSIsZ2VvbWV0cnk6e3R5cGU6IlNwaGVyZSJ9LHByb3BlcnRpZXM6e3NpdGU6dC52YWxpZFswXSxzaXRlY29vcmRpbmF0ZXM6dC5wb2ludHNbMF0sbmVpZ2hib3VyczpbXX19KSksbn0sdC50cmlhbmdsZXM9ZnVuY3Rpb24oZSl7cmV0dXJuIGUhPT12b2lkIDAmJnQoZSksdC5kZWxhdW5heT97dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOnQuZGVsYXVuYXkudHJpYW5nbGVzLm1hcCgobixzKT0+KG49bi5tYXAocj0+dC5wb2ludHNbcl0pLG4uY2VudGVyPXQuZGVsYXVuYXkuY2VudGVyc1tzXSxuKSkuZmlsdGVyKG49PnJjKG4pPjApLm1hcChuPT4oe3R5cGU6IkZlYXR1cmUiLHByb3BlcnRpZXM6e2NpcmN1bWNlbnRlcjpuLmNlbnRlcn0sZ2VvbWV0cnk6e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOltbLi4ubixuWzBdXV19fSkpfTohMX0sdC5saW5rcz1mdW5jdGlvbihlKXtpZihlIT09dm9pZCAwJiZ0KGUpLCF0LmRlbGF1bmF5KXJldHVybiExO2NvbnN0IG49dC5kZWxhdW5heS5lZGdlcy5tYXAocj0+cmkodC5wb2ludHNbclswXV0sdC5wb2ludHNbclsxXV0pKSxzPXQuZGVsYXVuYXkudXJxdWhhcnQobik7cmV0dXJue3R5cGU6IkZlYXR1cmVDb2xsZWN0aW9uIixmZWF0dXJlczp0LmRlbGF1bmF5LmVkZ2VzLm1hcCgocixvKT0+KHt0eXBlOiJGZWF0dXJlIixwcm9wZXJ0aWVzOntzb3VyY2U6dC52YWxpZFtyWzBdXSx0YXJnZXQ6dC52YWxpZFtyWzFdXSxsZW5ndGg6bltvXSx1cnF1aGFydDohIXNbb119LGdlb21ldHJ5Ont0eXBlOiJMaW5lU3RyaW5nIixjb29yZGluYXRlczpbdC5wb2ludHNbclswXV0sdC5wb2ludHNbclsxXV1dfX0pKX19LHQubWVzaD1mdW5jdGlvbihlKXtyZXR1cm4gZSE9PXZvaWQgMCYmdChlKSx0LmRlbGF1bmF5P3t0eXBlOiJNdWx0aUxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOnQuZGVsYXVuYXkuZWRnZXMubWFwKG49Plt0LnBvaW50c1tuWzBdXSx0LnBvaW50c1tuWzFdXV0pfTohMX0sdC5jZWxsTWVzaD1mdW5jdGlvbihlKXtpZihlIT09dm9pZCAwJiZ0KGUpLCF0LmRlbGF1bmF5KXJldHVybiExO2NvbnN0e2NlbnRlcnM6bixwb2x5Z29uczpzfT10LmRlbGF1bmF5LHI9W107Zm9yKGNvbnN0IG8gb2YgcylpZihvKWZvcihsZXQgYT1vLmxlbmd0aCxjPW9bYS0xXSxsPW9bMF0saD0wO2g8YTtjPWwsbD1vWysraF0pbD5jJiZyLnB1c2goW25bY10sbltsXV0pO3JldHVybnt0eXBlOiJNdWx0aUxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOnJ9fSx0Ll9mb3VuZD12b2lkIDAsdC5maW5kPWZ1bmN0aW9uKGUsbixzKXtpZih0Ll9mb3VuZD10LmRlbGF1bmF5LmZpbmQoZSxuLHQuX2ZvdW5kKSwhc3x8cmkoW2Usbl0sdC5wb2ludHNbdC5fZm91bmRdKTxzKXJldHVybiB0Ll9mb3VuZH0sdC5odWxsPWZ1bmN0aW9uKGUpe2UhPT12b2lkIDAmJnQoZSk7Y29uc3Qgbj10LmRlbGF1bmF5Lmh1bGwscz10LnBvaW50cztyZXR1cm4gbi5sZW5ndGg9PT0wP251bGw6e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOltbLi4ubi5tYXAocj0+c1tyXSksc1tuWzBdXV1dfX0saT90KGkpOnR9ZnVuY3Rpb24gU20oaSx0KXtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAwOmJyZWFrO2Nhc2UgMTp0aGlzLnJhbmdlKGkpO2JyZWFrO2RlZmF1bHQ6dGhpcy5yYW5nZSh0KS5kb21haW4oaSk7YnJlYWt9cmV0dXJuIHRoaXN9ZnVuY3Rpb24gb2MoaSx0LGUpe2kucHJvdG90eXBlPXQucHJvdG90eXBlPWUsZS5jb25zdHJ1Y3Rvcj1pfWZ1bmN0aW9uIGZ1KGksdCl7dmFyIGU9T2JqZWN0LmNyZWF0ZShpLnByb3RvdHlwZSk7Zm9yKHZhciBuIGluIHQpZVtuXT10W25dO3JldHVybiBlfWZ1bmN0aW9uIG5zKCl7fXZhciBpcz0uNyxWcj0xL2lzLGZpPSJcXHMqKFsrLV0/XFxkKylcXHMqIixzcz0iXFxzKihbKy1dPyg/OlxcZCpcXC4pP1xcZCsoPzpbZUVdWystXT9cXGQrKT8pXFxzKiIsQWU9IlxccyooWystXT8oPzpcXGQqXFwuKT9cXGQrKD86W2VFXVsrLV0/XFxkKyk/KSVcXHMqIixfbT0vXiMoWzAtOWEtZl17Myw4fSkkLyx2bT1uZXcgUmVnRXhwKGBecmdiXFwoJHtmaX0sJHtmaX0sJHtmaX1cXCkkYCksem09bmV3IFJlZ0V4cChgXnJnYlxcKCR7QWV9LCR7QWV9LCR7QWV9XFwpJGApLFRtPW5ldyBSZWdFeHAoYF5yZ2JhXFwoJHtmaX0sJHtmaX0sJHtmaX0sJHtzc31cXCkkYCksRW09bmV3IFJlZ0V4cChgXnJnYmFcXCgke0FlfSwke0FlfSwke0FlfSwke3NzfVxcKSRgKSxQbT1uZXcgUmVnRXhwKGBeaHNsXFwoJHtzc30sJHtBZX0sJHtBZX1cXCkkYCksQ209bmV3IFJlZ0V4cChgXmhzbGFcXCgke3NzfSwke0FlfSwke0FlfSwke3NzfVxcKSRgKSxkdT17YWxpY2VibHVlOjE1NzkyMzgzLGFudGlxdWV3aGl0ZToxNjQ0NDM3NSxhcXVhOjY1NTM1LGFxdWFtYXJpbmU6ODM4ODU2NCxhenVyZToxNTc5NDE3NSxiZWlnZToxNjExOTI2MCxiaXNxdWU6MTY3NzAyNDQsYmxhY2s6MCxibGFuY2hlZGFsbW9uZDoxNjc3MjA0NSxibHVlOjI1NSxibHVldmlvbGV0OjkwNTUyMDIsYnJvd246MTA4MjQyMzQsYnVybHl3b29kOjE0NTk2MjMxLGNhZGV0Ymx1ZTo2MjY2NTI4LGNoYXJ0cmV1c2U6ODM4ODM1MixjaG9jb2xhdGU6MTM3ODk0NzAsY29yYWw6MTY3NDQyNzIsY29ybmZsb3dlcmJsdWU6NjU5MTk4MSxjb3Juc2lsazoxNjc3NTM4OCxjcmltc29uOjE0NDIzMTAwLGN5YW46NjU1MzUsZGFya2JsdWU6MTM5LGRhcmtjeWFuOjM1NzIzLGRhcmtnb2xkZW5yb2Q6MTIwOTI5MzksZGFya2dyYXk6MTExMTkwMTcsZGFya2dyZWVuOjI1NjAwLGRhcmtncmV5OjExMTE5MDE3LGRhcmtraGFraToxMjQzMzI1OSxkYXJrbWFnZW50YTo5MTA5NjQzLGRhcmtvbGl2ZWdyZWVuOjU1OTc5OTksZGFya29yYW5nZToxNjc0NzUyMCxkYXJrb3JjaGlkOjEwMDQwMDEyLGRhcmtyZWQ6OTEwOTUwNCxkYXJrc2FsbW9uOjE1MzA4NDEwLGRhcmtzZWFncmVlbjo5NDE5OTE5LGRhcmtzbGF0ZWJsdWU6NDczNDM0NyxkYXJrc2xhdGVncmF5OjMxMDA0OTUsZGFya3NsYXRlZ3JleTozMTAwNDk1LGRhcmt0dXJxdW9pc2U6NTI5NDUsZGFya3Zpb2xldDo5Njk5NTM5LGRlZXBwaW5rOjE2NzE2OTQ3LGRlZXBza3libHVlOjQ5MTUxLGRpbWdyYXk6NjkwODI2NSxkaW1ncmV5OjY5MDgyNjUsZG9kZ2VyYmx1ZToyMDAzMTk5LGZpcmVicmljazoxMTY3NDE0NixmbG9yYWx3aGl0ZToxNjc3NTkyMCxmb3Jlc3RncmVlbjoyMjYzODQyLGZ1Y2hzaWE6MTY3MTE5MzUsZ2FpbnNib3JvOjE0NDc0NDYwLGdob3N0d2hpdGU6MTYzMTY2NzEsZ29sZDoxNjc2NjcyMCxnb2xkZW5yb2Q6MTQzMjkxMjAsZ3JheTo4NDIxNTA0LGdyZWVuOjMyNzY4LGdyZWVueWVsbG93OjExNDAzMDU1LGdyZXk6ODQyMTUwNCxob25leWRldzoxNTc5NDE2MCxob3RwaW5rOjE2NzM4NzQwLGluZGlhbnJlZDoxMzQ1ODUyNCxpbmRpZ286NDkxNTMzMCxpdm9yeToxNjc3NzIwMCxraGFraToxNTc4NzY2MCxsYXZlbmRlcjoxNTEzMjQxMCxsYXZlbmRlcmJsdXNoOjE2NzczMzY1LGxhd25ncmVlbjo4MTkwOTc2LGxlbW9uY2hpZmZvbjoxNjc3NTg4NSxsaWdodGJsdWU6MTEzOTMyNTQsbGlnaHRjb3JhbDoxNTc2MTUzNixsaWdodGN5YW46MTQ3NDU1OTksbGlnaHRnb2xkZW5yb2R5ZWxsb3c6MTY0NDgyMTAsbGlnaHRncmF5OjEzODgyMzIzLGxpZ2h0Z3JlZW46OTQ5ODI1NixsaWdodGdyZXk6MTM4ODIzMjMsbGlnaHRwaW5rOjE2NzU4NDY1LGxpZ2h0c2FsbW9uOjE2NzUyNzYyLGxpZ2h0c2VhZ3JlZW46MjE0Mjg5MCxsaWdodHNreWJsdWU6ODkwMDM0NixsaWdodHNsYXRlZ3JheTo3ODMzNzUzLGxpZ2h0c2xhdGVncmV5Ojc4MzM3NTMsbGlnaHRzdGVlbGJsdWU6MTE1ODQ3MzQsbGlnaHR5ZWxsb3c6MTY3NzcxODQsbGltZTo2NTI4MCxsaW1lZ3JlZW46MzMyOTMzMCxsaW5lbjoxNjQ0NTY3MCxtYWdlbnRhOjE2NzExOTM1LG1hcm9vbjo4Mzg4NjA4LG1lZGl1bWFxdWFtYXJpbmU6NjczNzMyMixtZWRpdW1ibHVlOjIwNSxtZWRpdW1vcmNoaWQ6MTIyMTE2NjcsbWVkaXVtcHVycGxlOjk2NjI2ODMsbWVkaXVtc2VhZ3JlZW46Mzk3ODA5NyxtZWRpdW1zbGF0ZWJsdWU6ODA4Nzc5MCxtZWRpdW1zcHJpbmdncmVlbjo2NDE1NCxtZWRpdW10dXJxdW9pc2U6NDc3MjMwMCxtZWRpdW12aW9sZXRyZWQ6MTMwNDcxNzMsbWlkbmlnaHRibHVlOjE2NDQ5MTIsbWludGNyZWFtOjE2MTIxODUwLG1pc3R5cm9zZToxNjc3MDI3Myxtb2NjYXNpbjoxNjc3MDIyOSxuYXZham93aGl0ZToxNjc2ODY4NSxuYXZ5OjEyOCxvbGRsYWNlOjE2NjQzNTU4LG9saXZlOjg0MjEzNzYsb2xpdmVkcmFiOjcwNDg3Mzksb3JhbmdlOjE2NzUzOTIwLG9yYW5nZXJlZDoxNjcyOTM0NCxvcmNoaWQ6MTQzMTU3MzQscGFsZWdvbGRlbnJvZDoxNTY1NzEzMCxwYWxlZ3JlZW46MTAwMjU4ODAscGFsZXR1cnF1b2lzZToxMTUyOTk2NixwYWxldmlvbGV0cmVkOjE0MzgxMjAzLHBhcGF5YXdoaXA6MTY3NzMwNzcscGVhY2hwdWZmOjE2NzY3NjczLHBlcnU6MTM0Njg5OTEscGluazoxNjc2MTAzNSxwbHVtOjE0NTI0NjM3LHBvd2RlcmJsdWU6MTE1OTE5MTAscHVycGxlOjgzODg3MzYscmViZWNjYXB1cnBsZTo2Njk3ODgxLHJlZDoxNjcxMTY4MCxyb3N5YnJvd246MTIzNTc1MTkscm95YWxibHVlOjQyODY5NDUsc2FkZGxlYnJvd246OTEyNzE4NyxzYWxtb246MTY0MTY4ODIsc2FuZHlicm93bjoxNjAzMjg2NCxzZWFncmVlbjozMDUwMzI3LHNlYXNoZWxsOjE2Nzc0NjM4LHNpZW5uYToxMDUwNjc5NyxzaWx2ZXI6MTI2MzIyNTYsc2t5Ymx1ZTo4OTAwMzMxLHNsYXRlYmx1ZTo2OTcwMDYxLHNsYXRlZ3JheTo3MzcyOTQ0LHNsYXRlZ3JleTo3MzcyOTQ0LHNub3c6MTY3NzU5MzAsc3ByaW5nZ3JlZW46NjU0MDcsc3RlZWxibHVlOjQ2MjA5ODAsdGFuOjEzODA4NzgwLHRlYWw6MzI4OTYsdGhpc3RsZToxNDIwNDg4OCx0b21hdG86MTY3MzcwOTUsdHVycXVvaXNlOjQyNTE4NTYsdmlvbGV0OjE1NjMxMDg2LHdoZWF0OjE2MTEzMzMxLHdoaXRlOjE2Nzc3MjE1LHdoaXRlc21va2U6MTYxMTkyODUseWVsbG93OjE2Nzc2OTYwLHllbGxvd2dyZWVuOjEwMTQ1MDc0fTtvYyhucyxycyx7Y29weShpKXtyZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgdGhpcy5jb25zdHJ1Y3Rvcix0aGlzLGkpfSxkaXNwbGF5YWJsZSgpe3JldHVybiB0aGlzLnJnYigpLmRpc3BsYXlhYmxlKCl9LGhleDpwdSxmb3JtYXRIZXg6cHUsZm9ybWF0SGV4ODpCbSxmb3JtYXRIc2w6Rm0sZm9ybWF0UmdiOnl1LHRvU3RyaW5nOnl1fSk7ZnVuY3Rpb24gcHUoKXtyZXR1cm4gdGhpcy5yZ2IoKS5mb3JtYXRIZXgoKX1mdW5jdGlvbiBCbSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleDgoKX1mdW5jdGlvbiBGbSgpe3JldHVybiBidSh0aGlzKS5mb3JtYXRIc2woKX1mdW5jdGlvbiB5dSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdFJnYigpfWZ1bmN0aW9uIHJzKGkpe3ZhciB0LGU7cmV0dXJuIGk9KGkrIiIpLnRyaW0oKS50b0xvd2VyQ2FzZSgpLCh0PV9tLmV4ZWMoaSkpPyhlPXRbMV0ubGVuZ3RoLHQ9cGFyc2VJbnQodFsxXSwxNiksZT09PTY/bXUodCk6ZT09PTM/bmV3IE90KHQ+PjgmMTV8dD4+NCYyNDAsdD4+NCYxNXx0JjI0MCwodCYxNSk8PDR8dCYxNSwxKTplPT09OD9Vcih0Pj4yNCYyNTUsdD4+MTYmMjU1LHQ+PjgmMjU1LCh0JjI1NSkvMjU1KTplPT09ND9Vcih0Pj4xMiYxNXx0Pj44JjI0MCx0Pj44JjE1fHQ+PjQmMjQwLHQ+PjQmMTV8dCYyNDAsKCh0JjE1KTw8NHx0JjE1KS8yNTUpOm51bGwpOih0PXZtLmV4ZWMoaSkpP25ldyBPdCh0WzFdLHRbMl0sdFszXSwxKToodD16bS5leGVjKGkpKT9uZXcgT3QodFsxXSoyNTUvMTAwLHRbMl0qMjU1LzEwMCx0WzNdKjI1NS8xMDAsMSk6KHQ9VG0uZXhlYyhpKSk/VXIodFsxXSx0WzJdLHRbM10sdFs0XSk6KHQ9RW0uZXhlYyhpKSk/VXIodFsxXSoyNTUvMTAwLHRbMl0qMjU1LzEwMCx0WzNdKjI1NS8xMDAsdFs0XSk6KHQ9UG0uZXhlYyhpKSk/d3UodFsxXSx0WzJdLzEwMCx0WzNdLzEwMCwxKToodD1DbS5leGVjKGkpKT93dSh0WzFdLHRbMl0vMTAwLHRbM10vMTAwLHRbNF0pOmR1Lmhhc093blByb3BlcnR5KGkpP211KGR1W2ldKTppPT09InRyYW5zcGFyZW50Ij9uZXcgT3QoTmFOLE5hTixOYU4sMCk6bnVsbH1mdW5jdGlvbiBtdShpKXtyZXR1cm4gbmV3IE90KGk+PjE2JjI1NSxpPj44JjI1NSxpJjI1NSwxKX1mdW5jdGlvbiBVcihpLHQsZSxuKXtyZXR1cm4gbjw9MCYmKGk9dD1lPU5hTiksbmV3IE90KGksdCxlLG4pfWZ1bmN0aW9uIEltKGkpe3JldHVybiBpIGluc3RhbmNlb2YgbnN8fChpPXJzKGkpKSxpPyhpPWkucmdiKCksbmV3IE90KGkucixpLmcsaS5iLGkub3BhY2l0eSkpOm5ldyBPdH1mdW5jdGlvbiBhYyhpLHQsZSxuKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD09PTE/SW0oaSk6bmV3IE90KGksdCxlLG49PW51bGw/MTpuKX1mdW5jdGlvbiBPdChpLHQsZSxuKXt0aGlzLnI9K2ksdGhpcy5nPSt0LHRoaXMuYj0rZSx0aGlzLm9wYWNpdHk9K259b2MoT3QsYWMsZnUobnMse2JyaWdodGVyKGkpe3JldHVybiBpPWk9PW51bGw/VnI6TWF0aC5wb3coVnIsaSksbmV3IE90KHRoaXMucippLHRoaXMuZyppLHRoaXMuYippLHRoaXMub3BhY2l0eSl9LGRhcmtlcihpKXtyZXR1cm4gaT1pPT1udWxsP2lzOk1hdGgucG93KGlzLGkpLG5ldyBPdCh0aGlzLnIqaSx0aGlzLmcqaSx0aGlzLmIqaSx0aGlzLm9wYWNpdHkpfSxyZ2IoKXtyZXR1cm4gdGhpc30sY2xhbXAoKXtyZXR1cm4gbmV3IE90KFRuKHRoaXMuciksVG4odGhpcy5nKSxUbih0aGlzLmIpLHFyKHRoaXMub3BhY2l0eSkpfSxkaXNwbGF5YWJsZSgpe3JldHVybi0uNTw9dGhpcy5yJiZ0aGlzLnI8MjU1LjUmJi0uNTw9dGhpcy5nJiZ0aGlzLmc8MjU1LjUmJi0uNTw9dGhpcy5iJiZ0aGlzLmI8MjU1LjUmJjA8PXRoaXMub3BhY2l0eSYmdGhpcy5vcGFjaXR5PD0xfSxoZXg6Z3UsZm9ybWF0SGV4Omd1LGZvcm1hdEhleDg6a20sZm9ybWF0UmdiOnh1LHRvU3RyaW5nOnh1fSkpO2Z1bmN0aW9uIGd1KCl7cmV0dXJuYCMke0VuKHRoaXMucil9JHtFbih0aGlzLmcpfSR7RW4odGhpcy5iKX1gfWZ1bmN0aW9uIGttKCl7cmV0dXJuYCMke0VuKHRoaXMucil9JHtFbih0aGlzLmcpfSR7RW4odGhpcy5iKX0ke0VuKChpc05hTih0aGlzLm9wYWNpdHkpPzE6dGhpcy5vcGFjaXR5KSoyNTUpfWB9ZnVuY3Rpb24geHUoKXtjb25zdCBpPXFyKHRoaXMub3BhY2l0eSk7cmV0dXJuYCR7aT09PTE/InJnYigiOiJyZ2JhKCJ9JHtUbih0aGlzLnIpfSwgJHtUbih0aGlzLmcpfSwgJHtUbih0aGlzLmIpfSR7aT09PTE/IikiOmAsICR7aX0pYH1gfWZ1bmN0aW9uIHFyKGkpe3JldHVybiBpc05hTihpKT8xOk1hdGgubWF4KDAsTWF0aC5taW4oMSxpKSl9ZnVuY3Rpb24gVG4oaSl7cmV0dXJuIE1hdGgubWF4KDAsTWF0aC5taW4oMjU1LE1hdGgucm91bmQoaSl8fDApKX1mdW5jdGlvbiBFbihpKXtyZXR1cm4gaT1UbihpKSwoaTwxNj8iMCI6IiIpK2kudG9TdHJpbmcoMTYpfWZ1bmN0aW9uIHd1KGksdCxlLG4pe3JldHVybiBuPD0wP2k9dD1lPU5hTjplPD0wfHxlPj0xP2k9dD1OYU46dDw9MCYmKGk9TmFOKSxuZXcgeWUoaSx0LGUsbil9ZnVuY3Rpb24gYnUoaSl7aWYoaSBpbnN0YW5jZW9mIHllKXJldHVybiBuZXcgeWUoaS5oLGkucyxpLmwsaS5vcGFjaXR5KTtpZihpIGluc3RhbmNlb2YgbnN8fChpPXJzKGkpKSwhaSlyZXR1cm4gbmV3IHllO2lmKGkgaW5zdGFuY2VvZiB5ZSlyZXR1cm4gaTtpPWkucmdiKCk7dmFyIHQ9aS5yLzI1NSxlPWkuZy8yNTUsbj1pLmIvMjU1LHM9TWF0aC5taW4odCxlLG4pLHI9TWF0aC5tYXgodCxlLG4pLG89TmFOLGE9ci1zLGM9KHIrcykvMjtyZXR1cm4gYT8odD09PXI/bz0oZS1uKS9hKyhlPG4pKjY6ZT09PXI/bz0obi10KS9hKzI6bz0odC1lKS9hKzQsYS89YzwuNT9yK3M6Mi1yLXMsbyo9NjApOmE9Yz4wJiZjPDE/MDpvLG5ldyB5ZShvLGEsYyxpLm9wYWNpdHkpfWZ1bmN0aW9uIE5tKGksdCxlLG4pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT9idShpKTpuZXcgeWUoaSx0LGUsbj09bnVsbD8xOm4pfWZ1bmN0aW9uIHllKGksdCxlLG4pe3RoaXMuaD0raSx0aGlzLnM9K3QsdGhpcy5sPStlLHRoaXMub3BhY2l0eT0rbn1vYyh5ZSxObSxmdShucyx7YnJpZ2h0ZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9WcjpNYXRoLnBvdyhWcixpKSxuZXcgeWUodGhpcy5oLHRoaXMucyx0aGlzLmwqaSx0aGlzLm9wYWNpdHkpfSxkYXJrZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9pczpNYXRoLnBvdyhpcyxpKSxuZXcgeWUodGhpcy5oLHRoaXMucyx0aGlzLmwqaSx0aGlzLm9wYWNpdHkpfSxyZ2IoKXt2YXIgaT10aGlzLmglMzYwKyh0aGlzLmg8MCkqMzYwLHQ9aXNOYU4oaSl8fGlzTmFOKHRoaXMucyk/MDp0aGlzLnMsZT10aGlzLmwsbj1lKyhlPC41P2U6MS1lKSp0LHM9MiplLW47cmV0dXJuIG5ldyBPdChjYyhpPj0yNDA/aS0yNDA6aSsxMjAscyxuKSxjYyhpLHMsbiksY2MoaTwxMjA/aSsyNDA6aS0xMjAscyxuKSx0aGlzLm9wYWNpdHkpfSxjbGFtcCgpe3JldHVybiBuZXcgeWUoTXUodGhpcy5oKSxIcih0aGlzLnMpLEhyKHRoaXMubCkscXIodGhpcy5vcGFjaXR5KSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuKDA8PXRoaXMucyYmdGhpcy5zPD0xfHxpc05hTih0aGlzLnMpKSYmMDw9dGhpcy5sJiZ0aGlzLmw8PTEmJjA8PXRoaXMub3BhY2l0eSYmdGhpcy5vcGFjaXR5PD0xfSxmb3JtYXRIc2woKXtjb25zdCBpPXFyKHRoaXMub3BhY2l0eSk7cmV0dXJuYCR7aT09PTE/ImhzbCgiOiJoc2xhKCJ9JHtNdSh0aGlzLmgpfSwgJHtIcih0aGlzLnMpKjEwMH0lLCAke0hyKHRoaXMubCkqMTAwfSUke2k9PT0xPyIpIjpgLCAke2l9KWB9YH19KSk7ZnVuY3Rpb24gTXUoaSl7cmV0dXJuIGk9KGl8fDApJTM2MCxpPDA/aSszNjA6aX1mdW5jdGlvbiBIcihpKXtyZXR1cm4gTWF0aC5tYXgoMCxNYXRoLm1pbigxLGl8fDApKX1mdW5jdGlvbiBjYyhpLHQsZSl7cmV0dXJuKGk8NjA/dCsoZS10KSppLzYwOmk8MTgwP2U6aTwyNDA/dCsoZS10KSooMjQwLWkpLzYwOnQpKjI1NX12YXIgbGM9aT0+KCk9Pmk7ZnVuY3Rpb24gUm0oaSx0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIGkrZSp0fX1mdW5jdGlvbiBMbShpLHQsZSl7cmV0dXJuIGk9TWF0aC5wb3coaSxlKSx0PU1hdGgucG93KHQsZSktaSxlPTEvZSxmdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5wb3coaStuKnQsZSl9fWZ1bmN0aW9uIE9tKGkpe3JldHVybihpPStpKT09MT9BdTpmdW5jdGlvbih0LGUpe3JldHVybiBlLXQ/TG0odCxlLGkpOmxjKGlzTmFOKHQpP2U6dCl9fWZ1bmN0aW9uIEF1KGksdCl7dmFyIGU9dC1pO3JldHVybiBlP1JtKGksZSk6bGMoaXNOYU4oaSk/dDppKX12YXIgU3U9ZnVuY3Rpb24gaSh0KXt2YXIgZT1PbSh0KTtmdW5jdGlvbiBuKHMscil7dmFyIG89ZSgocz1hYyhzKSkuciwocj1hYyhyKSkuciksYT1lKHMuZyxyLmcpLGM9ZShzLmIsci5iKSxsPUF1KHMub3BhY2l0eSxyLm9wYWNpdHkpO3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gcy5yPW8oaCkscy5nPWEoaCkscy5iPWMoaCkscy5vcGFjaXR5PWwoaCkscysiIn19cmV0dXJuIG4uZ2FtbWE9aSxufSgxKTtmdW5jdGlvbiBEbShpLHQpe3R8fCh0PVtdKTt2YXIgZT1pP01hdGgubWluKHQubGVuZ3RoLGkubGVuZ3RoKTowLG49dC5zbGljZSgpLHM7cmV0dXJuIGZ1bmN0aW9uKHIpe2ZvcihzPTA7czxlOysrcyluW3NdPWlbc10qKDEtcikrdFtzXSpyO3JldHVybiBufX1mdW5jdGlvbiAkbShpKXtyZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KGkpJiYhKGkgaW5zdGFuY2VvZiBEYXRhVmlldyl9ZnVuY3Rpb24gVm0oaSx0KXt2YXIgZT10P3QubGVuZ3RoOjAsbj1pP01hdGgubWluKGUsaS5sZW5ndGgpOjAscz1uZXcgQXJyYXkobikscj1uZXcgQXJyYXkoZSksbztmb3Iobz0wO288bjsrK28pc1tvXT1mYyhpW29dLHRbb10pO2Zvcig7bzxlOysrbylyW29dPXRbb107cmV0dXJuIGZ1bmN0aW9uKGEpe2ZvcihvPTA7bzxuOysrbylyW29dPXNbb10oYSk7cmV0dXJuIHJ9fWZ1bmN0aW9uIFVtKGksdCl7dmFyIGU9bmV3IERhdGU7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihuKXtyZXR1cm4gZS5zZXRUaW1lKGkqKDEtbikrdCpuKSxlfX1mdW5jdGlvbiBXcihpLHQpe3JldHVybiBpPStpLHQ9K3QsZnVuY3Rpb24oZSl7cmV0dXJuIGkqKDEtZSkrdCplfX1mdW5jdGlvbiBxbShpLHQpe3ZhciBlPXt9LG49e30sczsoaT09PW51bGx8fHR5cGVvZiBpIT0ib2JqZWN0IikmJihpPXt9KSwodD09PW51bGx8fHR5cGVvZiB0IT0ib2JqZWN0IikmJih0PXt9KTtmb3IocyBpbiB0KXMgaW4gaT9lW3NdPWZjKGlbc10sdFtzXSk6bltzXT10W3NdO3JldHVybiBmdW5jdGlvbihyKXtmb3IocyBpbiBlKW5bc109ZVtzXShyKTtyZXR1cm4gbn19dmFyIGhjPS9bLStdPyg/OlxkK1wuP1xkKnxcLj9cZCspKD86W2VFXVstK10/XGQrKT8vZyx1Yz1uZXcgUmVnRXhwKGhjLnNvdXJjZSwiZyIpO2Z1bmN0aW9uIEhtKGkpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBpfX1mdW5jdGlvbiBXbShpKXtyZXR1cm4gZnVuY3Rpb24odCl7cmV0dXJuIGkodCkrIiJ9fWZ1bmN0aW9uIEdtKGksdCl7dmFyIGU9aGMubGFzdEluZGV4PXVjLmxhc3RJbmRleD0wLG4scyxyLG89LTEsYT1bXSxjPVtdO2ZvcihpPWkrIiIsdD10KyIiOyhuPWhjLmV4ZWMoaSkpJiYocz11Yy5leGVjKHQpKTspKHI9cy5pbmRleCk+ZSYmKHI9dC5zbGljZShlLHIpLGFbb10/YVtvXSs9cjphWysrb109ciksKG49blswXSk9PT0ocz1zWzBdKT9hW29dP2Fbb10rPXM6YVsrK29dPXM6KGFbKytvXT1udWxsLGMucHVzaCh7aTpvLHg6V3IobixzKX0pKSxlPXVjLmxhc3RJbmRleDtyZXR1cm4gZTx0Lmxlbmd0aCYmKHI9dC5zbGljZShlKSxhW29dP2Fbb10rPXI6YVsrK29dPXIpLGEubGVuZ3RoPDI/Y1swXT9XbShjWzBdLngpOkhtKHQpOih0PWMubGVuZ3RoLGZ1bmN0aW9uKGwpe2Zvcih2YXIgaD0wLHU7aDx0OysraClhWyh1PWNbaF0pLmldPXUueChsKTtyZXR1cm4gYS5qb2luKCIiKX0pfWZ1bmN0aW9uIGZjKGksdCl7dmFyIGU9dHlwZW9mIHQsbjtyZXR1cm4gdD09bnVsbHx8ZT09PSJib29sZWFuIj9sYyh0KTooZT09PSJudW1iZXIiP1dyOmU9PT0ic3RyaW5nIj8obj1ycyh0KSk/KHQ9bixTdSk6R206dCBpbnN0YW5jZW9mIHJzP1N1OnQgaW5zdGFuY2VvZiBEYXRlP1VtOiRtKHQpP0RtOkFycmF5LmlzQXJyYXkodCk/Vm06dHlwZW9mIHQudmFsdWVPZiE9ImZ1bmN0aW9uIiYmdHlwZW9mIHQudG9TdHJpbmchPSJmdW5jdGlvbiJ8fGlzTmFOKHQpP3FtOldyKShpLHQpfWZ1bmN0aW9uIFptKGksdCl7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihlKXtyZXR1cm4gTWF0aC5yb3VuZChpKigxLWUpK3QqZSl9fWZ1bmN0aW9uIFhtKGkpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBpfX1mdW5jdGlvbiBKbShpKXtyZXR1cm4raX12YXIgX3U9WzAsMV07ZnVuY3Rpb24gZGkoaSl7cmV0dXJuIGl9ZnVuY3Rpb24gZGMoaSx0KXtyZXR1cm4odC09aT0raSk/ZnVuY3Rpb24oZSl7cmV0dXJuKGUtaSkvdH06WG0oaXNOYU4odCk/TmFOOi41KX1mdW5jdGlvbiBZbShpLHQpe3ZhciBlO3JldHVybiBpPnQmJihlPWksaT10LHQ9ZSksZnVuY3Rpb24obil7cmV0dXJuIE1hdGgubWF4KGksTWF0aC5taW4odCxuKSl9fWZ1bmN0aW9uIGptKGksdCxlKXt2YXIgbj1pWzBdLHM9aVsxXSxyPXRbMF0sbz10WzFdO3JldHVybiBzPG4/KG49ZGMocyxuKSxyPWUobyxyKSk6KG49ZGMobixzKSxyPWUocixvKSksZnVuY3Rpb24oYSl7cmV0dXJuIHIobihhKSl9fWZ1bmN0aW9uIFFtKGksdCxlKXt2YXIgbj1NYXRoLm1pbihpLmxlbmd0aCx0Lmxlbmd0aCktMSxzPW5ldyBBcnJheShuKSxyPW5ldyBBcnJheShuKSxvPS0xO2ZvcihpW25dPGlbMF0mJihpPWkuc2xpY2UoKS5yZXZlcnNlKCksdD10LnNsaWNlKCkucmV2ZXJzZSgpKTsrK288bjspc1tvXT1kYyhpW29dLGlbbysxXSkscltvXT1lKHRbb10sdFtvKzFdKTtyZXR1cm4gZnVuY3Rpb24oYSl7dmFyIGM9dHAoaSxhLDEsbiktMTtyZXR1cm4gcltjXShzW2NdKGEpKX19ZnVuY3Rpb24gS20oaSx0KXtyZXR1cm4gdC5kb21haW4oaS5kb21haW4oKSkucmFuZ2UoaS5yYW5nZSgpKS5pbnRlcnBvbGF0ZShpLmludGVycG9sYXRlKCkpLmNsYW1wKGkuY2xhbXAoKSkudW5rbm93bihpLnVua25vd24oKSl9ZnVuY3Rpb24gdGcoKXt2YXIgaT1fdSx0PV91LGU9ZmMsbixzLHIsbz1kaSxhLGMsbDtmdW5jdGlvbiBoKCl7dmFyIGY9TWF0aC5taW4oaS5sZW5ndGgsdC5sZW5ndGgpO3JldHVybiBvIT09ZGkmJihvPVltKGlbMF0saVtmLTFdKSksYT1mPjI/UW06am0sYz1sPW51bGwsdX1mdW5jdGlvbiB1KGYpe3JldHVybiBmPT1udWxsfHxpc05hTihmPStmKT9yOihjfHwoYz1hKGkubWFwKG4pLHQsZSkpKShuKG8oZikpKX1yZXR1cm4gdS5pbnZlcnQ9ZnVuY3Rpb24oZil7cmV0dXJuIG8ocygobHx8KGw9YSh0LGkubWFwKG4pLFdyKSkpKGYpKSl9LHUuZG9tYWluPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhpPUFycmF5LmZyb20oZixKbSksaCgpKTppLnNsaWNlKCl9LHUucmFuZ2U9ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHQ9QXJyYXkuZnJvbShmKSxoKCkpOnQuc2xpY2UoKX0sdS5yYW5nZVJvdW5kPWZ1bmN0aW9uKGYpe3JldHVybiB0PUFycmF5LmZyb20oZiksZT1abSxoKCl9LHUuY2xhbXA9ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KG89Zj8hMDpkaSxoKCkpOm8hPT1kaX0sdS5pbnRlcnBvbGF0ZT1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZT1mLGgoKSk6ZX0sdS51bmtub3duPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhyPWYsdSk6cn0sZnVuY3Rpb24oZixkKXtyZXR1cm4gbj1mLHM9ZCxoKCl9fWZ1bmN0aW9uIGVnKCl7cmV0dXJuIHRnKCkoZGksZGkpfWZ1bmN0aW9uIG5nKGkpe3JldHVybiBNYXRoLmFicyhpPU1hdGgucm91bmQoaSkpPj0xZTIxP2kudG9Mb2NhbGVTdHJpbmcoImVuIikucmVwbGFjZSgvLC9nLCIiKTppLnRvU3RyaW5nKDEwKX1mdW5jdGlvbiBHcihpLHQpe2lmKChlPShpPXQ/aS50b0V4cG9uZW50aWFsKHQtMSk6aS50b0V4cG9uZW50aWFsKCkpLmluZGV4T2YoImUiKSk8MClyZXR1cm4gbnVsbDt2YXIgZSxuPWkuc2xpY2UoMCxlKTtyZXR1cm5bbi5sZW5ndGg+MT9uWzBdK24uc2xpY2UoMik6biwraS5zbGljZShlKzEpXX1mdW5jdGlvbiBwaShpKXtyZXR1cm4gaT1HcihNYXRoLmFicyhpKSksaT9pWzFdOk5hTn1mdW5jdGlvbiBpZyhpLHQpe3JldHVybiBmdW5jdGlvbihlLG4pe2Zvcih2YXIgcz1lLmxlbmd0aCxyPVtdLG89MCxhPWlbMF0sYz0wO3M+MCYmYT4wJiYoYythKzE+biYmKGE9TWF0aC5tYXgoMSxuLWMpKSxyLnB1c2goZS5zdWJzdHJpbmcocy09YSxzK2EpKSwhKChjKz1hKzEpPm4pKTspYT1pW289KG8rMSklaS5sZW5ndGhdO3JldHVybiByLnJldmVyc2UoKS5qb2luKHQpfX1mdW5jdGlvbiBzZyhpKXtyZXR1cm4gZnVuY3Rpb24odCl7cmV0dXJuIHQucmVwbGFjZSgvWzAtOV0vZyxmdW5jdGlvbihlKXtyZXR1cm4gaVsrZV19KX19dmFyIHJnPS9eKD86KC4pPyhbPD49Xl0pKT8oWytcLSggXSk/KFskI10pPygwKT8oXGQrKT8oLCk/KFwuXGQrKT8ofik/KFthLXolXSk/JC9pO2Z1bmN0aW9uIFpyKGkpe2lmKCEodD1yZy5leGVjKGkpKSl0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgZm9ybWF0OiAiK2kpO3ZhciB0O3JldHVybiBuZXcgcGMoe2ZpbGw6dFsxXSxhbGlnbjp0WzJdLHNpZ246dFszXSxzeW1ib2w6dFs0XSx6ZXJvOnRbNV0sd2lkdGg6dFs2XSxjb21tYTp0WzddLHByZWNpc2lvbjp0WzhdJiZ0WzhdLnNsaWNlKDEpLHRyaW06dFs5XSx0eXBlOnRbMTBdfSl9WnIucHJvdG90eXBlPXBjLnByb3RvdHlwZTtmdW5jdGlvbiBwYyhpKXt0aGlzLmZpbGw9aS5maWxsPT09dm9pZCAwPyIgIjppLmZpbGwrIiIsdGhpcy5hbGlnbj1pLmFsaWduPT09dm9pZCAwPyI+IjppLmFsaWduKyIiLHRoaXMuc2lnbj1pLnNpZ249PT12b2lkIDA/Ii0iOmkuc2lnbisiIix0aGlzLnN5bWJvbD1pLnN5bWJvbD09PXZvaWQgMD8iIjppLnN5bWJvbCsiIix0aGlzLnplcm89ISFpLnplcm8sdGhpcy53aWR0aD1pLndpZHRoPT09dm9pZCAwP3ZvaWQgMDoraS53aWR0aCx0aGlzLmNvbW1hPSEhaS5jb21tYSx0aGlzLnByZWNpc2lvbj1pLnByZWNpc2lvbj09PXZvaWQgMD92b2lkIDA6K2kucHJlY2lzaW9uLHRoaXMudHJpbT0hIWkudHJpbSx0aGlzLnR5cGU9aS50eXBlPT09dm9pZCAwPyIiOmkudHlwZSsiIn1wYy5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5maWxsK3RoaXMuYWxpZ24rdGhpcy5zaWduK3RoaXMuc3ltYm9sKyh0aGlzLnplcm8/IjAiOiIiKSsodGhpcy53aWR0aD09PXZvaWQgMD8iIjpNYXRoLm1heCgxLHRoaXMud2lkdGh8MCkpKyh0aGlzLmNvbW1hPyIsIjoiIikrKHRoaXMucHJlY2lzaW9uPT09dm9pZCAwPyIiOiIuIitNYXRoLm1heCgwLHRoaXMucHJlY2lzaW9ufDApKSsodGhpcy50cmltPyJ+IjoiIikrdGhpcy50eXBlfTtmdW5jdGlvbiBvZyhpKXt0OmZvcih2YXIgdD1pLmxlbmd0aCxlPTEsbj0tMSxzO2U8dDsrK2Upc3dpdGNoKGlbZV0pe2Nhc2UiLiI6bj1zPWU7YnJlYWs7Y2FzZSIwIjpuPT09MCYmKG49ZSkscz1lO2JyZWFrO2RlZmF1bHQ6aWYoIStpW2VdKWJyZWFrIHQ7bj4wJiYobj0wKTticmVha31yZXR1cm4gbj4wP2kuc2xpY2UoMCxuKStpLnNsaWNlKHMrMSk6aX12YXIgdnU7ZnVuY3Rpb24gYWcoaSx0KXt2YXIgZT1HcihpLHQpO2lmKCFlKXJldHVybiBpKyIiO3ZhciBuPWVbMF0scz1lWzFdLHI9cy0odnU9TWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKHMvMykpKSozKSsxLG89bi5sZW5ndGg7cmV0dXJuIHI9PT1vP246cj5vP24rbmV3IEFycmF5KHItbysxKS5qb2luKCIwIik6cj4wP24uc2xpY2UoMCxyKSsiLiIrbi5zbGljZShyKToiMC4iK25ldyBBcnJheSgxLXIpLmpvaW4oIjAiKStHcihpLE1hdGgubWF4KDAsdCtyLTEpKVswXX1mdW5jdGlvbiB6dShpLHQpe3ZhciBlPUdyKGksdCk7aWYoIWUpcmV0dXJuIGkrIiI7dmFyIG49ZVswXSxzPWVbMV07cmV0dXJuIHM8MD8iMC4iK25ldyBBcnJheSgtcykuam9pbigiMCIpK246bi5sZW5ndGg+cysxP24uc2xpY2UoMCxzKzEpKyIuIituLnNsaWNlKHMrMSk6bituZXcgQXJyYXkocy1uLmxlbmd0aCsyKS5qb2luKCIwIil9dmFyIFR1PXsiJSI6KGksdCk9PihpKjEwMCkudG9GaXhlZCh0KSxiOmk9Pk1hdGgucm91bmQoaSkudG9TdHJpbmcoMiksYzppPT5pKyIiLGQ6bmcsZTooaSx0KT0+aS50b0V4cG9uZW50aWFsKHQpLGY6KGksdCk9PmkudG9GaXhlZCh0KSxnOihpLHQpPT5pLnRvUHJlY2lzaW9uKHQpLG86aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZyg4KSxwOihpLHQpPT56dShpKjEwMCx0KSxyOnp1LHM6YWcsWDppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpLHg6aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZygxNil9O2Z1bmN0aW9uIEV1KGkpe3JldHVybiBpfXZhciBQdT1BcnJheS5wcm90b3R5cGUubWFwLEN1PVsieSIsInoiLCJhIiwiZiIsInAiLCJuIiwiwrUiLCJtIiwiIiwiayIsIk0iLCJHIiwiVCIsIlAiLCJFIiwiWiIsIlkiXTtmdW5jdGlvbiBjZyhpKXt2YXIgdD1pLmdyb3VwaW5nPT09dm9pZCAwfHxpLnRob3VzYW5kcz09PXZvaWQgMD9FdTppZyhQdS5jYWxsKGkuZ3JvdXBpbmcsTnVtYmVyKSxpLnRob3VzYW5kcysiIiksZT1pLmN1cnJlbmN5PT09dm9pZCAwPyIiOmkuY3VycmVuY3lbMF0rIiIsbj1pLmN1cnJlbmN5PT09dm9pZCAwPyIiOmkuY3VycmVuY3lbMV0rIiIscz1pLmRlY2ltYWw9PT12b2lkIDA/Ii4iOmkuZGVjaW1hbCsiIixyPWkubnVtZXJhbHM9PT12b2lkIDA/RXU6c2coUHUuY2FsbChpLm51bWVyYWxzLFN0cmluZykpLG89aS5wZXJjZW50PT09dm9pZCAwPyIlIjppLnBlcmNlbnQrIiIsYT1pLm1pbnVzPT09dm9pZCAwPyLiiJIiOmkubWludXMrIiIsYz1pLm5hbj09PXZvaWQgMD8iTmFOIjppLm5hbisiIjtmdW5jdGlvbiBsKHUpe3U9WnIodSk7dmFyIGY9dS5maWxsLGQ9dS5hbGlnbixwPXUuc2lnbix5PXUuc3ltYm9sLG09dS56ZXJvLGc9dS53aWR0aCxiPXUuY29tbWEsdz11LnByZWNpc2lvbix4PXUudHJpbSxNPXUudHlwZTtNPT09Im4iPyhiPSEwLE09ImciKTpUdVtNXXx8KHc9PT12b2lkIDAmJih3PTEyKSx4PSEwLE09ImciKSwobXx8Zj09PSIwIiYmZD09PSI9IikmJihtPSEwLGY9IjAiLGQ9Ij0iKTt2YXIgQT15PT09IiQiP2U6eT09PSIjIiYmL1tib3hYXS8udGVzdChNKT8iMCIrTS50b0xvd2VyQ2FzZSgpOiIiLFM9eT09PSIkIj9uOi9bJXBdLy50ZXN0KE0pP286IiIsXz1UdVtNXSxFPS9bZGVmZ3BycyVdLy50ZXN0KE0pO3c9dz09PXZvaWQgMD82Oi9bZ3Byc10vLnRlc3QoTSk/TWF0aC5tYXgoMSxNYXRoLm1pbigyMSx3KSk6TWF0aC5tYXgoMCxNYXRoLm1pbigyMCx3KSk7ZnVuY3Rpb24geih2KXt2YXIgQz1BLFA9UyxGLEIsSTtpZihNPT09ImMiKVA9Xyh2KStQLHY9IiI7ZWxzZXt2PSt2O3ZhciBrPXY8MHx8MS92PDA7aWYodj1pc05hTih2KT9jOl8oTWF0aC5hYnModiksdykseCYmKHY9b2codikpLGsmJit2PT0wJiZwIT09IisiJiYoaz0hMSksQz0oaz9wPT09IigiP3A6YTpwPT09Ii0ifHxwPT09IigiPyIiOnApK0MsUD0oTT09PSJzIj9DdVs4K3Z1LzNdOiIiKStQKyhrJiZwPT09IigiPyIpIjoiIiksRSl7Zm9yKEY9LTEsQj12Lmxlbmd0aDsrK0Y8QjspaWYoST12LmNoYXJDb2RlQXQoRiksNDg+SXx8ST41Nyl7UD0oST09PTQ2P3Mrdi5zbGljZShGKzEpOnYuc2xpY2UoRikpK1Asdj12LnNsaWNlKDAsRik7YnJlYWt9fX1iJiYhbSYmKHY9dCh2LDEvMCkpO3ZhciBEPUMubGVuZ3RoK3YubGVuZ3RoK1AubGVuZ3RoLFU9RDxnP25ldyBBcnJheShnLUQrMSkuam9pbihmKToiIjtzd2l0Y2goYiYmbSYmKHY9dChVK3YsVS5sZW5ndGg/Zy1QLmxlbmd0aDoxLzApLFU9IiIpLGQpe2Nhc2UiPCI6dj1DK3YrUCtVO2JyZWFrO2Nhc2UiPSI6dj1DK1UrditQO2JyZWFrO2Nhc2UiXiI6dj1VLnNsaWNlKDAsRD1VLmxlbmd0aD4+MSkrQyt2K1ArVS5zbGljZShEKTticmVhaztkZWZhdWx0OnY9VStDK3YrUDticmVha31yZXR1cm4gcih2KX1yZXR1cm4gei50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB1KyIifSx6fWZ1bmN0aW9uIGgodSxmKXt2YXIgZD1sKCh1PVpyKHUpLHUudHlwZT0iZiIsdSkpLHA9TWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKHBpKGYpLzMpKSkqMyx5PU1hdGgucG93KDEwLC1wKSxtPUN1WzgrcC8zXTtyZXR1cm4gZnVuY3Rpb24oZyl7cmV0dXJuIGQoeSpnKSttfX1yZXR1cm57Zm9ybWF0OmwsZm9ybWF0UHJlZml4Omh9fXZhciBYcixCdSxGdTtsZyh7dGhvdXNhbmRzOiIsIixncm91cGluZzpbM10sY3VycmVuY3k6WyIkIiwiIl19KTtmdW5jdGlvbiBsZyhpKXtyZXR1cm4gWHI9Y2coaSksQnU9WHIuZm9ybWF0LEZ1PVhyLmZvcm1hdFByZWZpeCxYcn1mdW5jdGlvbiBoZyhpKXtyZXR1cm4gTWF0aC5tYXgoMCwtcGkoTWF0aC5hYnMoaSkpKX1mdW5jdGlvbiB1ZyhpLHQpe3JldHVybiBNYXRoLm1heCgwLE1hdGgubWF4KC04LE1hdGgubWluKDgsTWF0aC5mbG9vcihwaSh0KS8zKSkpKjMtcGkoTWF0aC5hYnMoaSkpKX1mdW5jdGlvbiBmZyhpLHQpe3JldHVybiBpPU1hdGguYWJzKGkpLHQ9TWF0aC5hYnModCktaSxNYXRoLm1heCgwLHBpKHQpLXBpKGkpKSsxfWZ1bmN0aW9uIGRnKGksdCxlLG4pe3ZhciBzPXJwKGksdCxlKSxyO3N3aXRjaChuPVpyKG49PW51bGw/IixmIjpuKSxuLnR5cGUpe2Nhc2UicyI6e3ZhciBvPU1hdGgubWF4KE1hdGguYWJzKGkpLE1hdGguYWJzKHQpKTtyZXR1cm4gbi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPXVnKHMsbykpJiYobi5wcmVjaXNpb249ciksRnUobixvKX1jYXNlIiI6Y2FzZSJlIjpjYXNlImciOmNhc2UicCI6Y2FzZSJyIjp7bi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPWZnKHMsTWF0aC5tYXgoTWF0aC5hYnMoaSksTWF0aC5hYnModCkpKSkmJihuLnByZWNpc2lvbj1yLShuLnR5cGU9PT0iZSIpKTticmVha31jYXNlImYiOmNhc2UiJSI6e24ucHJlY2lzaW9uPT1udWxsJiYhaXNOYU4ocj1oZyhzKSkmJihuLnByZWNpc2lvbj1yLShuLnR5cGU9PT0iJSIpKjIpO2JyZWFrfX1yZXR1cm4gQnUobil9ZnVuY3Rpb24gcGcoaSl7dmFyIHQ9aS5kb21haW47cmV0dXJuIGkudGlja3M9ZnVuY3Rpb24oZSl7dmFyIG49dCgpO3JldHVybiBzcChuWzBdLG5bbi5sZW5ndGgtMV0sZT09bnVsbD8xMDplKX0saS50aWNrRm9ybWF0PWZ1bmN0aW9uKGUsbil7dmFyIHM9dCgpO3JldHVybiBkZyhzWzBdLHNbcy5sZW5ndGgtMV0sZT09bnVsbD8xMDplLG4pfSxpLm5pY2U9ZnVuY3Rpb24oZSl7ZT09bnVsbCYmKGU9MTApO3ZhciBuPXQoKSxzPTAscj1uLmxlbmd0aC0xLG89bltzXSxhPW5bcl0sYyxsLGg9MTA7Zm9yKGE8byYmKGw9byxvPWEsYT1sLGw9cyxzPXIscj1sKTtoLS0gPjA7KXtpZihsPUFhKG8sYSxlKSxsPT09YylyZXR1cm4gbltzXT1vLG5bcl09YSx0KG4pO2lmKGw+MClvPU1hdGguZmxvb3Ioby9sKSpsLGE9TWF0aC5jZWlsKGEvbCkqbDtlbHNlIGlmKGw8MClvPU1hdGguY2VpbChvKmwpL2wsYT1NYXRoLmZsb29yKGEqbCkvbDtlbHNlIGJyZWFrO2M9bH1yZXR1cm4gaX0saX1mdW5jdGlvbiB5Yygpe3ZhciBpPWVnKCk7cmV0dXJuIGkuY29weT1mdW5jdGlvbigpe3JldHVybiBLbShpLHljKCkpfSxTbS5hcHBseShpLGFyZ3VtZW50cykscGcoaSl9ZnVuY3Rpb24geWcoaSx0KXtyZXR1cm4gaS5tYXAoZT0+e2NvbnN0IG49W107bGV0IHM7cmV0dXJuIGUuZm9yRWFjaChyPT57aWYocyl7Y29uc3Qgbz1yaShyLHMpKjE4MC9NYXRoLlBJO2lmKG8+dCl7Y29uc3QgYT1WcChzLHIpLGM9MS9NYXRoLmNlaWwoby90KTtsZXQgbD1jO2Zvcig7bDwxOyluLnB1c2goYShsKSksbCs9Y319bi5wdXNoKHM9cil9KSxufSl9ZnVuY3Rpb24gbWcoaSx7bWluTG5nOnQsbWF4TG5nOmUsbWluTGF0Om4sbWF4TGF0OnN9PXt9KXtjb25zdCByPU1hdGgucm91bmQoeWkoMzYwL2ksMikvTWF0aC5QSSksbz0oMStNYXRoLnNxcnQoNSkpLzIsYT1kPT5kL28qMzYwJTM2MC0xODAsYz1kPT5NYXRoLmFjb3MoMipkL3ItMSkvTWF0aC5QSSoxODAtOTAsbD1kPT5yKihNYXRoLmNvcygoZCs5MCkqTWF0aC5QSS8xODApKzEpLzIsaD1bcyE9PXZvaWQgMD9NYXRoLmNlaWwobChzKSk6MCxuIT09dm9pZCAwP01hdGguZmxvb3IobChuKSk6ci0xXSx1PXQ9PT12b2lkIDAmJmU9PT12b2lkIDA/KCk9PiEwOnQ9PT12b2lkIDA/ZD0+ZDw9ZTplPT09dm9pZCAwP2Q9PmQ+PXQ6ZT49dD9kPT5kPj10JiZkPD1lOmQ9PmQ+PXR8fGQ8PWUsZj1bXTtmb3IobGV0IGQ9aFswXTtkPD1oWzFdO2QrKyl7Y29uc3QgcD1hKGQpO3UocCkmJmYucHVzaChbcCxjKGQpXSl9cmV0dXJuIGZ9ZnVuY3Rpb24gbWMoaSx0LGU9ITEpe3JldHVybiBlPyRwKHQsaSk6ankoaSx0KX1mdW5jdGlvbiBnZyhpLHQpe2NvbnN0IGU9e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOml9LFtbbixzXSxbcixvXV09ZmgoZSk7aWYoTWF0aC5taW4oTWF0aC5hYnMoci1uKSxNYXRoLmFicyhvLXMpKTx0KXJldHVybltdO2NvbnN0IGE9bj5yfHxvPj04OXx8czw9LTg5O3JldHVybiBtZyh0LHttaW5Mbmc6bixtYXhMbmc6cixtaW5MYXQ6cyxtYXhMYXQ6b30pLmZpbHRlcihjPT5tYyhjLGUsYSkpfWZ1bmN0aW9uIHhnKGkse3Jlc29sdXRpb246dD0xLzAsYmJveDplLHByb2plY3Rpb246bn09e30pe2NvbnN0IHM9eWcoaSx0KSxyPVZpKHMpLG89Z2coaSx0KSxhPVsuLi5yLC4uLm9dLGM9e3R5cGU6IlBvbHlnb24iLGNvb3JkaW5hdGVzOml9LFtbbCxoXSxbdSxmXV09ZmgoYyksZD1sPnV8fGY+PTg5fHxoPD0tODk7bGV0IHA9W107aWYoZCl7Y29uc3QgTT1BbShhKS50cmlhbmdsZXMoKSxBPW5ldyBNYXAoYS5tYXAoKFtTLF9dLEUpPT5bYCR7U30tJHtffWAsRV0pKTtNLmZlYXR1cmVzLmZvckVhY2goUz0+e2NvbnN0IF89Uy5nZW9tZXRyeS5jb29yZGluYXRlc1swXS5zbGljZSgwLDMpLnJldmVyc2UoKSxFPVtdO2lmKF8uZm9yRWFjaCgoW3osdl0pPT57Y29uc3QgQz1gJHt6fS0ke3Z9YDtBLmhhcyhDKSYmRS5wdXNoKEEuZ2V0KEMpKX0pLEUubGVuZ3RoPT09Myl7aWYoRS5zb21lKHo9Pno8ci5sZW5ndGgpKXtjb25zdCB6PVMucHJvcGVydGllcy5jaXJjdW1jZW50ZXI7aWYoIW1jKHosYyxkKSlyZXR1cm59cC5wdXNoKC4uLkUpfX0pfWVsc2UgaWYoby5sZW5ndGgpe2NvbnN0IE09dHMuZnJvbShhKTtmb3IobGV0IEE9MCxTPU0udHJpYW5nbGVzLmxlbmd0aDtBPFM7QSs9Myl7Y29uc3QgXz1bMiwxLDBdLm1hcCh6PT5NLnRyaWFuZ2xlc1tBK3pdKSxFPV8ubWFwKHo9PmFbel0pO2lmKF8uc29tZSh6PT56PHIubGVuZ3RoKSl7Y29uc3Qgej1bMCwxXS5tYXAodj0+b3AoRSxDPT5DW3ZdKSk7aWYoIW1jKHosYyxkKSljb250aW51ZX1wLnB1c2goLi4uXyl9fWVsc2V7Y29uc3R7dmVydGljZXM6TSxob2xlczpBPVtdfT1RaChzKTtwPXB5KE0sQSwyKX1sZXQgeT1lP1tlWzBdLGVbMl1dOnNyKGEsTT0+TVswXSksbT1lP1tlWzFdLGVbM11dOnNyKGEsTT0+TVsxXSk7aWYobil7Y29uc3RbTSxBXT1uKFt5WzBdLG1bMF1dKSxbUyxfXT1uKFt5WzFdLG1bMV1dKTt5PVtNLFNdLG09Wy1BLC1fXX1jb25zdCBnPXljKHksWzAsMV0pLGI9eWMobSxbMCwxXSksdz1hLm1hcCgoW00sQV0pPT57aWYobil7Y29uc3RbUyxfXT1uKFtNLEFdKTtyZXR1cm5bZyhTKSxiKC1fKV19ZWxzZSByZXR1cm5bZyhNKSxiKEEpXX0pO3JldHVybntjb250b3VyOnMsdHJpYW5nbGVzOntwb2ludHM6YSxpbmRpY2VzOnAsdXZzOnd9fX1jb25zdCBJdT1uZXcgdWUoKS5zZXRBdHRyaWJ1dGU/InNldEF0dHJpYnV0ZSI6ImFkZEF0dHJpYnV0ZSI7ZnVuY3Rpb24gSnIoaSx0LGUsbil7Y29uc3Qgcz1pLm1hcChyPT5yLm1hcCgoW28sYV0pPT57aWYobil7Y29uc3RbYyxsXT1uKFtvLGFdKTtyZXR1cm5bYywtbCx0XX1yZXR1cm4gZT9ZMChvLGEsdCk6W28sYSx0XX0pKTtyZXR1cm4gUWgocyl9ZnVuY3Rpb24gd2coaSx0LGUsbixzKXtjb25zdHt2ZXJ0aWNlczpyLGhvbGVzOm99PUpyKGksdCxuLHMpLHt2ZXJ0aWNlczphfT1KcihpLGUsbixzKSxjPVZpKFthLHJdKSxsPU1hdGgucm91bmQoYS5sZW5ndGgvMyksaD1uZXcgU2V0KG8pO2xldCB1PTA7Y29uc3QgZj1bXTtmb3IobGV0IHA9MDtwPGw7cCsrKXtsZXQgeT1wKzE7aWYoeT09PWwpeT11O2Vsc2UgaWYoaC5oYXMoeSkpe2NvbnN0IG09eTt5PXUsdT1tfWYucHVzaChwLHArbCx5K2wpLGYucHVzaCh5K2wseSxwKX1jb25zdCBkPVtdO2ZvcihsZXQgcD0xO3A+PTA7cC0tKWZvcihsZXQgeT0wO3k8bDt5Kz0xKWQucHVzaCh5LyhsLTEpLHApO3JldHVybntpbmRpY2VzOmYsdmVydGljZXM6Yyx1dnM6ZCx0b3BWZXJ0czphfX1mdW5jdGlvbiBrdShpLHQsZSxuLHMscil7cmV0dXJue2luZGljZXM6bj9pLmluZGljZXM6aS5pbmRpY2VzLnNsaWNlKCkucmV2ZXJzZSgpLHZlcnRpY2VzOkpyKFtpLnBvaW50c10sdCxzLHIpLnZlcnRpY2VzLHV2czplfX1jb25zdCBOdT0oe3BvbHlnb25HZW9Kc29uOmksc3RhcnRIZWlnaHQ6dCxlbmRIZWlnaHQ6ZSxjdXJ2YXR1cmVSZXNvbHV0aW9uOm49MSxjYXJ0ZXNpYW46cz0hMCxoYXNTaWRlOnI9ITAsaGFzQm90dG9tOm89ITEsaGFzVG9wOmE9ITEscHJvamVjdGlvbjpjLGJib3g6bH0pPT57aS5mb3JFYWNoKGc9PntOeShnKXx8Zy5yZXZlcnNlKCl9KTtjb25zdHtjb250b3VyOmgsdHJpYW5nbGVzOnV9PXhnKGkse3Jlc29sdXRpb246bixiYm94OmwscHJvamVjdGlvbjpjfSk7bGV0IGY9e30sZDtyJiYoZj13ZyhoLHQhPW51bGw/dDplLGUhPW51bGw/ZTp0LHMsYyksZD1mLnRvcFZlcnRzKTtsZXQgcD1bXTsob3x8YSkmJihwPVZpKHUudXZzKSk7bGV0IHk9e307byYmKHk9a3UodSx0LHAsITEscyxjKSk7bGV0IG09e307cmV0dXJuIGEmJihtPWt1KHUsZSxwLCEwLHMsYykpLHtjb250b3VyOmgsdHJpYW5nbGVzOnUsc2lkZVRvcnNvOmYsYm90dG9tQ2FwOnksdG9wQ2FwOm0sdG9wVmVydHM6ZH19O2NsYXNzIGJnIGV4dGVuZHMgdWV7Y29uc3RydWN0b3IodCxlPXt9KXtzdXBlcigpLHRoaXMudHlwZT0iUG9seWdvbkJ1ZmZlckdlb21ldHJ5Iix0aGlzLnBhcmFtZXRlcnM9RnQoe3BvbHlnb25HZW9Kc29uOnQsc3RhcnRIZWlnaHQ6MCxlbmRIZWlnaHQ6MSxoYXNUb3A6ITAsdG9wRmlyc3Q6ITEsaGFzQm90dG9tOiEwLGhhc1NpZGU6ITAsY3VydmF0dXJlUmVzb2x1dGlvbjoxLGNhcnRlc2lhbjohMCx1c2VyRGF0YVJzb09mZnNldDowfSxlKTtjb25zdHtlbmRIZWlnaHQ6bixoYXNUb3A6cyx0b3BGaXJzdDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSxjYXJ0ZXNpYW46Yyx1c2VyRGF0YVJzb09mZnNldDpsLHByb2plY3Rpb246aH09dGhpcy5wYXJhbWV0ZXJzLHtjb250b3VyOnUsc2lkZVRvcnNvOmYsdG9wVmVydHM6ZCxib3R0b21DYXA6cCx0b3BDYXA6eX09TnUoRnQoe30sdGhpcy5wYXJhbWV0ZXJzKSk7bGV0IG09W10sZz1bXSxiPVtdLHc9MDtjb25zdCB4PU09Pntjb25zdCBBPU1hdGgucm91bmQobS5sZW5ndGgvMyksUz1iLmxlbmd0aDttPW0uY29uY2F0KE0udmVydGljZXMpLGc9Zy5jb25jYXQoTS51dnMpLGI9Yi5jb25jYXQoQT9NLmluZGljZXMubWFwKF89Pl8rQSk6TS5pbmRpY2VzKSx0aGlzLmFkZEdyb3VwKFMsYi5sZW5ndGgtUyx3KyspfTtzJiZyJiZ4KHkpLGEmJih4KGYpLHRoaXMudXNlckRhdGEudG9wVmVydHM9bD9Kcih1LG4rbCxjLGgpLnZlcnRpY2VzOmQpLG8mJngocCkscyYmIXImJngoeSksdGhpcy5zZXRJbmRleChiKSx0aGlzW0l1XSgicG9zaXRpb24iLG5ldyBCZShtLDMpKSx0aGlzW0l1XSgidXYiLG5ldyBCZShnLDIpKSx0aGlzLmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCl9fXZhciBNZz1pPT57Y29uc3QgYT1pLHtjb29yZGluYXRlOnQsc3RhcnRIZWlnaHQ6ZSxoZWlnaHQ6bn09YSxzPUp1KGEsWyJjb29yZGluYXRlIiwic3RhcnRIZWlnaHQiLCJoZWlnaHQiXSk7bGV0IHI9ZXx8MDtyZXR1cm4gdHlwZW9mIGUhPSJ1bmRlZmluZWQiJiZ0eXBlb2YgbiE9InVuZGVmaW5lZCImJihyPWUrbiksbmV3IGJnKFt0XSxaZShGdCh7fSxzKSx7c3RhcnRIZWlnaHQ6ZSxlbmRIZWlnaHQ6cn0pKX07Y29uc3QgQWc9KHtjb29yZGluYXRlc0FycjppLHN0YXJ0OnQsZGVwdGg6ZSx1c2VHcm91cHM6bixoYXNUb3A6cyx0b3BGaXJzdDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSxjYXJ0ZXNpYW46Yyxwcm9qZWN0aW9uOmwsY3VydmF0dXJlUmVzb2x1dGlvbjpoLGJib3g6dX0pPT57Y29uc3QgZj1sJiZYaShsKTtmJiYoYz0hMSksdHx8KHQ9WzBdKTtjb25zdCBkPWkubWFwKChwLHkpPT57dmFyIG0sZztyZXR1cm4gTWcoe2Nvb3JkaW5hdGU6cCxwcm9qZWN0aW9uOmYsc3RhcnRIZWlnaHQ6KG09dFt5XSkhPW51bGw/bTp0WzBdLGhlaWdodDooZz1lW3ldKSE9bnVsbD9nOmVbMF0saGFzVG9wOnMhPW51bGw/czohMCx0b3BGaXJzdDpyIT1udWxsP3I6ITEsaGFzQm90dG9tOm8hPW51bGw/bzohMCxoYXNTaWRlOmEhPW51bGw/YTohMCxjYXJ0ZXNpYW46YyE9bnVsbD9jOiEwLGN1cnZhdHVyZVJlc29sdXRpb246aCE9bnVsbD9oOjEsYmJveDp1fSl9KTtyZXR1cm4gSmkoZCxuKX0sU2c9KHtjb29yZGluYXRlc0FycjppLGxpbmVXaWR0aDp0LHN0YXJ0OmUsdXNlR3JvdXBzOm59KT0+e2NvbnN0IHI9aS5tYXAoKG8sYSk9Pnt2YXIgYztyZXR1cm4gTnUoe3BvbHlnb25HZW9Kc29uOltvXSxzdGFydEhlaWdodDooYz1lW2FdKSE9bnVsbD9jOmVbMF19KS50b3BWZXJ0c30pLm1hcCgobyxhKT0+e3ZhciBsO2NvbnN0IGM9KGw9dFthXSkhPW51bGw/bDp0WzBdO3JldHVybiBaaCh7bm9kZXM6byxzZXRQb2ludFdpZHRoOigpPT5jfSl9KTtyZXR1cm4gSmkocixuKX07dmFyIF9nPShpLHQsZSk9Pm5ldyBQcm9taXNlKChuLHMpPT57dmFyIHI9Yz0+e3RyeXthKGUubmV4dChjKSl9Y2F0Y2gobCl7cyhsKX19LG89Yz0+e3RyeXthKGUudGhyb3coYykpfWNhdGNoKGwpe3MobCl9fSxhPWM9PmMuZG9uZT9uKGMudmFsdWUpOlByb21pc2UucmVzb2x2ZShjLnZhbHVlKS50aGVuKHIsbyk7YSgoZT1lLmFwcGx5KGksdCkpLm5leHQoKSl9KTtmdW5jdGlvbiB2ZyhpKXtyZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoaSkucmVkdWNlKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LGUse3ZhbHVlOmlbZV0sZW51bWVyYWJsZTohMH0pfSx7fSl9KGk9Pntjb25zdCB0PXtydW4oZSxuKXtjb25zdCBzPW5ldyBGdW5jdGlvbigicmV0dXJuICgiK2UrIikuYXBwbHkobnVsbCwgYXJndW1lbnRzKTsiKTtyZXR1cm4gcy5hcHBseShzLG4pfSxtZXRob2RzKCl7cmV0dXJuIE9iamVjdC5rZXlzKHQpfX07YWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZT0+X2codm9pZCAwLFtlXSxmdW5jdGlvbiooe2RhdGE6bn0pe3RyeXtjb25zdCBzPXRbbi5tZXRob2RdO2lmKHMpe2NvbnN0IHI9eWllbGQgcy5hcHBseShzLG4ucGFyYW1zKTtyLnRyYW5zZmVyJiZyLm1lc3NhZ2U/cG9zdE1lc3NhZ2Uoe2lkOm4uaWQscmVzdWx0OnIubWVzc2FnZSxlcnJvcjpudWxsfSxyLnRyYW5zZmVyKTpwb3N0TWVzc2FnZSh7aWQ6bi5pZCxyZXN1bHQ6cixlcnJvcjpudWxsfSl9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbWV0aG9kICInK24ubWV0aG9kKyciJyl9Y2F0Y2gocyl7cG9zdE1lc3NhZ2Uoe2lkOm4uaWQscmVzdWx0Om51bGwsZXJyb3I6dmcocyl9KX19KSksT2JqZWN0LmtleXMoaSkuZm9yRWFjaChlPT57dFtlXT1pW2VdfSkscG9zdE1lc3NhZ2UoInJlYWR5Iil9KSh7ZXh0cnVkZVBvbHlnb246Y3ksbGluZTp1eSxsaW5lMjpkeSxjb25pY1BvbHlnb246QWcsY29uaWNMaW5lOlNnfSl9KSgpOwo=",N=g=>Uint8Array.from(atob(g),t=>t.charCodeAt(0)),R=typeof window!="undefined"&&window.Blob&&new Blob([N(o)],{type:"text/javascript;charset=utf-8"});function T(g){let t;try{if(t=R&&(window.URL||window.webkitURL).createObjectURL(R),!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 z=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 I{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),E=this.pool,{err:O,res:ve}=yield E.exec(t,[W({},m)],void 0,!0);if(O)throw O;const Pe=z(ve);if(Object.assign(Pe.userData,W({},C)),w&&(yield w(Pe)),v){const{cacheObj:Ne}=this;Ne[v]||(Ne[v]={[_]:[]}),Ne[v][_].push(W({attributes:ve},C))}return Pe})}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:E}=w,O=x(w,["attributes"]),ve=z(E);return Object.assign(ve.userData,W({},O)),ve}):[]}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 E=new Mesh(t,createAreaLightMaterial(50));E.position.set(-16.116,14.37,8.208),E.scale.set(.1,2.428,2.739),this.add(E);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 ve=new Mesh(t,createAreaLightMaterial(17));ve.position.set(14.904,12.198,-1.832),ve.scale.set(.15,4.265,6.331),this.add(ve);const Pe=new Mesh(t,createAreaLightMaterial(43));Pe.position.set(-.462,8.89,14.52),Pe.scale.set(4.38,5.441,.088),this.add(Pe);const Ne=new Mesh(t,createAreaLightMaterial(20));Ne.position.set(3.235,11.486,-12.541),Ne.scale.set(2.5,2,.1),this.add(Ne);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}class Event{constructor(){L0(this,"event",new events.EventEmitter);L0(this,"eventHandlers",{});L0(this,"on",this.event.on.bind(this.event));L0(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);L0(this,"container");L0(this,"pencil");L0(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 H0(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,E=!1,O=250){return H0(this,null,function*(){this.pencil.controls.smoothTime=O/1e3,yield this.pencil.controls.setLookAt(r,m,v,C,_,w,E),this.pencil.controls.smoothTime=250/1e3})}truck(r,m,v=!1,C=250){return H0(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 H0(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 H0(this,null,function*(){this.pencil.controls.smoothTime=v/1e3;const C=this.pencil.controls.azimuthAngle,_=this.pencil.controls.polarAngle,w=this.pencil.controls.distance,E=this.pencil.cameraTarget.clone(),O=r.azimuthAngle||C,ve=r.polarAngle||_,Pe=r.distance||w,Ne=r.target||E;yield Promise.all([this.pencil.controls.moveTo(Ne.x,Ne.y,Ne.z,m),this.pencil.controls.dollyTo(Pe,m),this.pencil.controls.rotateTo(C+this.absoluteAngle(O,C),_+this.absoluteAngle(ve,_),m)]),this.pencil.controls.smoothTime=250/1e3})}paddingInCssPixel(r,m,v,C,_,w){const{camera:E,controls:O}=this.pencil,ve=E.fov*MathUtils.DEG2RAD,Pe=this.pencil.getSize().height,{size:Ne}=r.getSize(),Ae=Ne.x,Fe=Ne.y,ct=Ne.z;let Oe=O.getDistanceToFitBox(Ae,Fe,ct),ke=0,je=0,at=0,xt=0;for(let Gt=0;Gt<10;Gt++){const Lt=Oe-ct*.5,Wt=2*Math.tan(ve*.5)*Math.abs(Lt)/Pe;ke=m*Wt,je=C*Wt,at=_*Wt,xt=v*Wt,Oe=O.getDistanceToFitBox(Ae+at+xt,Fe+ke+je,ct)}return O.fitToBox(r.object3d,w,{paddingLeft:at,paddingRight:xt,paddingBottom:je,paddingTop:ke})}resetCamera(r=!1,m=250){return H0(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:E,height:O}=this.container.getBoundingClientRect(),ve=(r.clientX-_)/E*2-1,Pe=-((r.clientY-w)/O)*2+1,Ne=this.pencil.cameraPositon.clone();v.set(ve,Pe,.5),v.unproject(this.pencil.camera),v.sub(Ne).normalize();const Ae=(m-Ne.z)/v.z;return C.copy(Ne).add(v.multiplyScalar(Ae)),C}dispose(){super.dispose(),this.cameraState={}}}class Command{constructor(t){L0(this,"id");L0(this,"updatable");L0(this,"type");L0(this,"name");L0(this,"editor");L0(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 re$1;t.track(this.oldMap),t.dispose()}this.newMap&&(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 Te$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 Te$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){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,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;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,E,O,ve;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 Te$1&&m==="map"&&_==="repeat"?this.oldValue=this.material.repeat.toArray():((E=(w=this.material)==null?void 0:w[m])==null?void 0:E[_])instanceof Vector2?this.oldValue=this.material[m][_].toArray():typeof((ve=(O=this.material)==null?void 0:O[m])==null?void 0:ve[_])!="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 Te$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 Te$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.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);L0(this,"visType");L0(this,"visOptions");this.type="AddVis",this.visType=m,this.visOptions=v,m!==void 0&&(this.name=`Add Vis: ${m}`)}execute(){return H0(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);L0(this,"objectType");L0(this,"objectOptions");L0(this,"obj");L0(this,"addObjectUuid");this.type="AddObject",this.objectType=m,this.objectOptions=v,m!==void 0&&(this.name=`Add Object: ${m}`)}execute(){return H0(this,null,function*(){var m;const r=this.editor.viewport.vis;this.obj=yield r.lead.draw(this.objectType,Bi(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);L0(this,"object");L0(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 H0(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);L0(this,"object");L0(this,"copyObject",null);L0(this,"copyObjectUuid");this.type="CopyObject",this.name="Copy Object",this.object=m}execute(){return H0(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 H0(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}fromJSON(r){super.fromJSON(r),this.object=this.editor.baseObjectByUuid(r.objectUuid),this.copyObjectUuid=r.copyObjectUuid}fixJSON(){const r=this.json;r&&!r.copyObjectUuid&&(r.copyObjectUuid=this.copyObjectUuid)}}class AddMaterial extends Command{constructor(r,m){super(r);L0(this,"materialType");L0(this,"flag",!1);L0(this,"addObjectUuid");this.type="AddMaterial",this.name="Add Material",this.materialType=m}execute(){return H0(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 E=w.object3d;m=Array.isArray(E.material)?E.material[+_]:E.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 Te$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 H0(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);L0(this,"objectUuid");L0(this,"copyObjectUuid");this.type="CopyMaterial",this.name="Copy Material",this.objectUuid=m}execute(){return H0(this,null,function*(){this.copyObjectUuid=`material_${this.id}`,this.editor.pencil.mList.copy(this.objectUuid,this.copyObjectUuid,{name:`材质_${this.id}`})})}undo(){return H0(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);L0(this,"objectUuid");L0(this,"material");this.type="RemoveMaterial",this.name="Remove Material",this.objectUuid=m}execute(){return H0(this,null,function*(){const r=this.editor.pencil.mList;this.material=r.get(this.objectUuid),r.remove(this.objectUuid)})}undo(){return H0(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);L0(this,"object");L0(this,"oldValue");L0(this,"newValue");L0(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 H0(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 H0(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);L0(this,"attributeName");L0(this,"newValue");L0(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 H0(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 H0(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;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,E,O,ve;for(let Pe=0;Pe<C;Pe=Pe+3)ve=r[Pe]<<16|r[Pe+1]<<8|r[Pe+2],_=(ve&16515072)>>18,w=(ve&258048)>>12,E=(ve&4032)>>6,O=ve&63,t+=encodings[_]+encodings[w]+encodings[E]+encodings[O];return v===1?(ve=r[C],_=(ve&252)>>2,w=(ve&3)<<4,t+=encodings[_]+encodings[w]):v===2&&(ve=r[C]<<8|r[C+1],_=(ve&64512)>>10,w=(ve&1008)>>4,E=(ve&15)<<2,t+=encodings[_]+encodings[w]+encodings[E]),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,E,O,ve;for(let Pe=0,Ne=0;Pe<m;Pe+=4,Ne+=3)w=charCodeToNumber(g.charCodeAt(Pe)),E=charCodeToNumber(g.charCodeAt(Pe+1)),O=charCodeToNumber(g.charCodeAt(Pe+2)),ve=charCodeToNumber(g.charCodeAt(Pe+3)),C=(w<<18)+(E<<12)+(O<<6)+ve,_.set([(C&16711680)>>16,(C&65280)>>8,C&255],Ne);return t===2?(w=charCodeToNumber(g.charCodeAt(m)),E=charCodeToNumber(g.charCodeAt(m+1)),C=(w<<2)+(E>>4),_.set([C&255],r)):t===3&&(w=charCodeToNumber(g.charCodeAt(m)),E=charCodeToNumber(g.charCodeAt(m+1)),O=charCodeToNumber(g.charCodeAt(m+2)),C=(w<<10)+(E<<4)+(O>>2),_.set([(C&65280)>>8,C&255],r)),_.buffer}class History{constructor(t){L0(this,"editor");L0(this,"undos");L0(this,"redos");L0(this,"lastCmdTime");L0(this,"idCounter");L0(this,"historyDisabled");this.editor=t,this.undos=[],this.redos=[],this.lastCmdTime=Date.now(),this.idCounter=0,this.historyDisabled=!1}execute(t,r){return H0(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(Bi(Q0({},_),{[w]:Bi(Q0({},_[w]),{images:_[w].images.map(E=>{var Pe;if(typeof E.url!="string")if(((Pe=E.url)==null?void 0:Pe.type)==="Uint16Array"){const Ne=encodeArrayBufferToUrlSafeBase64(new Uint16Array(E.url.data).buffer);E._url=Q0({},E.url),delete E._url.data,E.url=Ne}else return Q0({},E);const O=t.i.findIndex(Ne=>Ne===E.url);let ve=E.url;return O===-1?(t.i.push(E.url),ve=`$rp-${t.i.length-1}`):ve=`$rp-${O}`,Bi(Q0({},E),{url:ve})})})}))}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 E=t.u[w];if(m!=null&&m.length&&((v=E.newMap)!=null&&v.images||(C=E.newMaterial)!=null&&C.images)){const ve=(_=E.newMap)!=null&&_.images?"newMap":"newMaterial";E[ve].images.forEach(Pe=>{if(typeof Pe.url=="string"&&Pe.url.startsWith("$rp-")){const Ne=parseInt(Pe.url.replace("$rp-",""));Pe._url?(Pe.url=Bi(Q0({},Pe._url),{data:decodeUrlSafeBase64ToArrayBuffer(m[Ne])}),delete Pe._url):Pe.url=m[Ne]}})}if(E.id<=r){console.error("历史记录id错误");continue}if(E.type==="SetOption"||!E.type)continue;E.type.endsWith("Command")&&(E.type=E.type.replace("Command",""));const O=new Commands[E.type](this.editor);O.json=E,O.id=E.id,O.name=E.name,this.undos.push(O),this.idCounter=E.id>this.idCounter?E.id:this.idCounter,r=E.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=()=>H0(this,null,function*(){const E=performance.now();for(;v.length>0&&performance.now()-E<t;){if(this.editor._dispose){m("dispose");return}const O=v.shift(),ve=this.editor.hooks.events.beforeExecuteUndo.length?this.editor.hooks.dispatch("beforeExecuteUndo",O):O;ve&&(yield this.executeUndo(ve)),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 H0(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 Viewport{constructor(t,r){L0(this,"editor");L0(this,"vis");L0(this,"extendsOptions",{});L0(this,"cameraState",{});L0(this,"delLoadObj");L0(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 H0(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 H0(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,E;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;(E=this.vis)==null||E.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,E)=>{this.editor.execute(new SetPosition(this.editor,_,w,E))}),(v=t.transformController)==null||v.event.on("rotate",(_,w,E)=>{this.editor.execute(new SetRotation(this.editor,_,w,E))}),(C=t.transformController)==null||C.event.on("scale",(_,w,E)=>{this.editor.execute(new SetScale(this.editor,_,w,E))})}addObj(m){return H0(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 H0(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 H0(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 H0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new AddMaterial(this.editor,t))})}removeMListMaterial(t){return H0(this,null,function*(){const{vis:r}=this;r&&this.editor.execute(new RemoveMaterial(this.editor,t))})}copyMListMaterial(t){return H0(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()}}const 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};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:E}=t.h.u[0].visOptions;t.h.u[0].visOptions=Bi(Q0({},t.h.u[0].visOptions),{geojsonMap:{[w]:_},extrudeLineGeojsonMap:{[w]:E}}),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:E}=t.h.u[0].visOptions;t.h.u[0].visOptions=Bi(Q0({},t.h.u[0].visOptions),{bboxMap:w||{[E]:_}}),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=Bi(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,t.v.eo.parentBgTopSegments=400)}},{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,E)=>{var O,ve,Pe;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 Ne=w.attributeName.split(":::caId.")[1],Ae=t.h.u[0].visOptions.adcode;t.h.u[E]=[{id:w.id,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`extrudePolygon#${Ae}-${Ne}`,copyObjectUuid:`ExtrudePolygon#${Ae}-${Ne}_${w.id}`},{id:w.id+.1,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`line#${Ae}-${Ne}`,copyObjectUuid:`line#${Ae}-${Ne}_${w.id+.1}`}],_[Ne]=w.id}else if((ve=w.objectUuid)!=null&&ve.startsWith("planeCopyExtrudePolygon")){const Ne=w.objectUuid.split("CopyExtrudePolygon")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`extrudePolygon#${Ae}-${Ne}_${_[Ne]}`})}else if((Pe=w.objectUuid)!=null&&Pe.startsWith("planeCopyLine")){const Ne=w.objectUuid.split("CopyLine")[1],Ae=t.h.u[0].visOptions.adcode;Object.assign(w,{objectUuid:`line#${Ae}-${Ne}_${_[Ne]+.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 Hooks{constructor(t){L0(this,"editor");L0(this,"events",{beforeSetVisOptions:[],beforeExecuteUndo:[],afterExecuteUndo:[],beforeShow:[],afterShow:[],beforeFromJSON:[],afterFromJSON:[],errorFromJSON:[]});L0(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 Config{constructor(t){L0(this,"editor");L0(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}}}const 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"),E=_.stream().pipeThrough(w);return new Response(E)}):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};class Editor{constructor(t){L0(this,"selected",null);L0(this,"playing",!0);L0(this,"currentMaterialSlot",0);L0(this,"events",new events.EventEmitter);L0(this,"history");L0(this,"viewport");L0(this,"hooks");L0(this,"config");L0(this,"pencil");L0(this,"on",this.events.on.bind(this.events));L0(this,"emit",this.events.emit.bind(this.events));L0(this,"options");L0(this,"selectOption",[]);L0(this,"mListOptions",[]);L0(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 Te$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 Fe=v.options.type;C.unshift({key:v.key.replace(Fe,Fe+"Target"),object3d:v.object3d.target,userData:{disabledC:!0,disabledR:!0},children:[]})}if(v.object3d.isDirectionalLight){const Fe=v.options.type;C.unshift({key:v.key.replace(Fe,Fe+"Shadow"),object3d:v.object3d.shadow.camera,userData:{disabledC:!0,disabledR:!0},children:[]})}const w=C.length>0?r(C):[],E=v.object3d.isGroup,O=E||["@Scene","@Camera"].includes(v.key)||v.userData.disabledC||v.key.includes("__c__"),ve=["@Scene","@Camera"].includes(v.key)||v.userData.disabledR||v.key.includes("__c__");if(w.length===0&&E)return null;const Pe=v.key.replace(v.key[0],v.key[0].toLowerCase()),Ne=["@Scene","@Camera"].includes(v.key)||v.userData.disabledTC,Ae=["@Scene","@Camera"].includes(v.key);return{key:Pe==="@Scene"?"scene":Pe==="@Camera"?"camera":Pe,name:v.object3d.name,object:v.object3d,visible:Ae?!0:v.object3d.visible,useMaterialType:v.useMaterialType,disabledC:O,disabledR:ve,disabledTC:Ne,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 H0(this,null,function*(){yield this.history.execute(t,r)})}fromJSON(t,r){return H0(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 E=this.options.assetsPrefix+t;console.time("vis-core:time.json-fetch");const{res:O,err:ve}=yield jsonFetch(E);if(console.timeEnd("vis-core:time.json-fetch"),ve)throw new Error("fromJSON error:"+ve);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 E=accessToken.getInfo();if(!E||!E.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 E=parseTexture(w.v.bg.texture);E.colorSpace=SRGBColorSpace,this.viewport.vis.pencil.scene.background=E}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 E;(E=this.viewport.vis)==null||E.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 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){L0(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(){L0(this,"rawRenderer");L0(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}}},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 E=getScale(r);if(E!==void 0){m=E;break}if(r=r.parentElement,r===document.body){r=null;break}}if(!r)return null;const v=E=>{const O=getScale(r)||1;m!==O&&(m=O,t(O,E))},C=E=>{E.propertyName==="transform"&&v("transitionEnd")},_=new MutationObserver(E=>{for(const O of E)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)},_}const IS_DEV=!1;class Base extends Camera{constructor(r){var m;super();L0(this,"playing",!0);L0(this,"leftTruck",!0);L0(this,"options");L0(this,"showState",!1);L0(this,"settings",{});L0(this,"delLoadArr");L0(this,"extendsOptions",{});L0(this,"leadObjs",objs$3);L0(this,"lead");L0(this,"mList");L0(this,"workerOnce",!0);L0(this,"tier0",!1);L0(this,"pmremGenerator",null);L0(this,"re",null);L0(this,"roomEnvMap");L0(this,"visName");L0(this,"editor");L0(this,"publicDir",{});L0(this,"_baseObjectByUuid");L0(this,"_objectByUuid");L0(this,"observeScale",null);L0(this,"sceneActive",-1);L0(this,"initSettingsObj");L0(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(Bi(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 H0(this,null,function*(){})}initVis(...r){return H0(this,null,function*(){})}init(...r){return H0(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 H0(this,null,function*(){var v,C,_,w,E,O,ve,Pe;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=(E=r.camera)==null?void 0:E.far)!=null?O:1e3,up:(Pe=(ve=r.camera)==null?void 0:ve.up)!=null?Pe: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 Ne=new ot(Q0(Bi(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 ct=()=>{this.observeScale||(this.observeScale=observeScale(this.container,(Oe,ke)=>{Ne.setDevicePixelRatio(window.devicePixelRatio*Oe)}))};ct(),Ne.event.on("resize",()=>{ct()})}this.pencil=Ne,this.sceneActive=1;const Ae=Ne.composerController.ssaoPass;Ae&&(Ae.enabled=!1);const Fe=new I({dbName:this.visName,cacheVersion:version});Ne.use(Fe),this.playing||(window.vis=this,window.pencil=Ne)}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",(...Ne)=>{this.showState!==!0&&this.emit("loaderProgress",...Ne)}),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,E,O,ve,Pe,Ne;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:(E=(w=this.pencil.composerController)==null?void 0:w.bloomPass)==null?void 0:E.threshold,bloomRadius:(ve=(O=this.pencil.composerController)==null?void 0:O.bloomPass)==null?void 0:ve.radius,bloomStrength:(Ne=(Pe=this.pencil.composerController)==null?void 0:Pe.bloomPass)==null?void 0:Ne.strength},{set:(Ae,Fe,ct)=>(Fe==="shadowMapEnabled"||Fe==="shadowMapType"?(Fe==="shadowMapEnabled"?this.pencil.renderer.shadowMap.enabled=ct:Fe==="shadowMapType"&&(this.pencil.renderer.shadowMap.type=ct),this.pencil.scene.traverse(Oe=>{const ke=Oe;if(ke.receiveShadow&&ke.material){const je=ke.material;Array.isArray(je)?je.forEach(at=>{at.needsUpdate=!0}):je.needsUpdate=!0}})):Fe==="backgroundType"?ct==="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):Fe==="backgroundColor"?r.scene.background=new Color$1(ct):Fe==="backgroundTexture"?r.scene.background=ct:Fe==="bloomThreshold"?r.composerController.bloomPass&&(r.composerController.bloomPass.threshold=ct):Fe==="bloomRadius"?r.composerController.bloomPass&&(r.composerController.bloomPass.radius=ct):Fe==="bloomStrength"&&r.composerController.bloomPass&&(r.composerController.bloomPass.strength=ct),Reflect.set(Ae,Fe,ct))})}initBaseObjectUserData(r){const m=Bi(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,E,O)=>(E==="bloom"?O?r.enableBloom():r.disableBloom():E==="prefab"?(r.prefab=O,O?this.lead.prefabGroup.attach(r):this.lead.group.attach(r)):E==="animationDuration"&&v?r.animateIn({duration:O}):E==="animationDuration"&&(C||_)&&(C?[r]:r.children).forEach(Pe=>{Pe.material.userData.tween&&(Pe.material.userData.tween.stop(),remove(Pe.material.userData.tween),Pe.material.userData.tween=null),O&&(Pe.material.uniforms.offset.value.x=1,Pe.material.uniforms.offsetLoop.value=1,Pe.animate({duration:O,repeat:1/0,lineLoop:!0,startShow:!0}))}),Reflect.set(w,E,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(Bi(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(E=>(Reflect.set(m,_,E),E)):w}})}handleSetting(r,m){return H0(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 H0(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 H0(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(),E=(C.x*.5+.5)*_,O=(C.y*-.5+.5)*w;return{x:E,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()}}L0(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 E=m[w];if(contains(_,E))v.features.push(E);else if(contains(E,_))_.properties=E.properties,v.features.push(_);else{const O=turf.intersect(_,E);O&&(O.properties=E.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();L0(this,"options");L0(this,"building",{});L0(this,"outJson",new Map);L0(this,"worldPositionZ",{value:0});this.options=Q0({},r)}create(){return H0(this,null,function*(){const{json:r,projection:m,cacheKey:v,meters:C,grey:_,clip:w}=this.options,E=this.pencil.mList,O=this.pencil.getPlugin("worker"),ve=this.pencil.lead,Pe=_?"-grey":"";this.createGroup();const Ne=E.getMultiple("building"+Pe);let Ae=v?yield O.getCachedGeometry({cacheKey:v}):[];if(Ae.length)w&&this.outJson.set(1,!0);else{let Fe;w&&(Fe=getBoxMultiPoly(w));const ct={};(r.features||r).forEach(ke=>{const je=typeof ke.properties.h=="string"?ke.properties.h.split(".")[1]:0,at=Number(ke.properties.h)|0;ct[je]||(ct[je]={}),ct[je][at]||(ct[je][at]=[]),Fe?Fe.some(Gt=>{ke.geometry.coordinates[1]&&console.log(ke.geometry.coordinates[1]);const Lt=turf.polygon(ke.geometry.coordinates[0]);return turf.booleanContains(Gt,Lt)?(ct[je][at].push(ke),!0):!1})||this.outJson.set(ke,!1):ct[je][at].push(ke)});const Oe=Object.keys(ct).map(ke=>{const je=ct[ke];return Object.keys(je).map(at=>{const xt=je[at];return{z:+ke,h:+at,coordinatesArr:xt.map(Gt=>Gt.geometry.type==="Polygon"?Gt.geometry.coordinates[0]:Gt.geometry.coordinates[0][0])}})}).flat().filter(ke=>ke.coordinatesArr.length);Ae=yield Promise.all(Oe.map(ke=>{const{h:je,z:at,coordinatesArr:xt}=ke,Gt=+je<=20?+je/18:+je<=60?+je/27:+je/12;return O.geoGeometry("extrudePolygon",{cacheKey:v,userData:{z:at,h:je},mesaage:{coordinatesArr:xt,projection:m,useGroups:2,depth:[Number(je)*(C||1)],hasBottom:!1,sideRepeat:Gt}})}))}yield Promise.all(Ae.map(Fe=>H0(this,null,function*(){const{h:ct,z:Oe}=Fe.userData,ke=ct+Oe,je=ke<=20?"20":ke<=60?"60":"max";let at=this.options.material;at||(at=[Ne[je+"Top"],Ne[je+"Side"]]);const xt=yield ve.draw("ExtrudePolygon",{key:`$p:-${ct}-${Oe}`,geometry:Fe,material:at},this);this.options.grey||(xt.object3d.castShadow=!0),this.building[ct]||(this.building[ct]=[]),this.building[ct].push(xt),xt.position.z=Number(Oe)*(C||1)}))),this.options.sideGradient&&this.sideGradient(),this.object3d.name="建筑",_||this.lead.updateBaseObjectKey(this,`building${Pe?"-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}
|