vis-core 0.27.10 → 0.27.11

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/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 Nn=Object.defineProperty,Kn=Object.defineProperties;var Fn=Object.getOwnPropertyDescriptors;var Wn=Object.getOwnPropertySymbols,An=Object.getPrototypeOf,kn=Object.prototype.hasOwnProperty,Hn=Object.prototype.propertyIsEnumerable,Yn=Reflect.get;var Ln=(g,t)=>(t=Symbol[g])?t:Symbol.for("Symbol."+g),Un=g=>{throw TypeError(g)},mn=Math.pow,Vn=(g,t,r)=>t in g?Nn(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,bi=(g,t)=>{for(var r in t||(t={}))kn.call(t,r)&&Vn(g,r,t[r]);if(Wn)for(var r of Wn(t))Hn.call(t,r)&&Vn(g,r,t[r]);return g},Di=(g,t)=>Kn(g,Fn(t));var _0=(g,t,r)=>Vn(g,typeof t!="symbol"?t+"":t,r);var yn=(g,t,r)=>Yn(An(g),r,t);var D0=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())}),Bn=function(g,t){this[0]=g,this[1]=t};var Pn=g=>{var t=g[Ln("asyncIterator")],r=!1,d,v={};return t==null?(t=g[Ln("iterator")](),d=C=>v[C]=w=>t[C](w)):(t=t.call(g),d=C=>v[C]=w=>{if(r){if(r=!1,C==="throw")throw w;return w}return r=!0,{done:!1,value:new Bn(new Promise(E=>{var ye=t[C](w);ye instanceof Object||Un("Object expected"),E(ye)}),1)}}),v[Ln("iterator")]=()=>v,d("next"),"throw"in t?d("throw"):v.throw=C=>{throw C},"return"in t&&d("return"),v},En=(g,t,r)=>(t=g[Ln("asyncIterator")])?t.call(g):(g=g[Ln("iterator")](),t={},r=(d,v)=>(v=g[d])&&(t[d]=C=>new Promise((w,E,ye)=>(C=v.call(g,C),ye=C.done,Promise.resolve(C.value).then(Le=>w({value:Le,done:ye}),E)))),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(":::"),d=jsrsasign.KEYUTIL.getKey(atob(publicKeyPEM)),v=CryptoJS.enc.Base64.parse(t),C=CryptoJS.enc.Base64.parse(r),w=CryptoJS.lib.WordArray.create(v.words.slice(0,4)),E=CryptoJS.lib.WordArray.create(v.words.slice(4)),ye=jsrsasign.KJUR.crypto.Util.hashHex(v.toString(),"sha256"),Le=d.verifyWithMessageHashPSS(ye,jsrsasign.b64tohex(g),"sha256",32);if(!Le)return this.token=void 0,"";const Ne=CryptoJS.AES.decrypt({ciphertext:E},C,{iv:w,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8),Fe=JSON.parse(Ne),at=Date.now();return!Fe.s||Fe.s>at?(this.token=void 0,""):Fe.e&&Fe.e<at?(this.token=void 0,""):(Fe.isValid=Le,Fe)}},version="0.27.10";/**
2
+ "use strict";var Nn=Object.defineProperty,Kn=Object.defineProperties;var Fn=Object.getOwnPropertyDescriptors;var Wn=Object.getOwnPropertySymbols,An=Object.getPrototypeOf,kn=Object.prototype.hasOwnProperty,Hn=Object.prototype.propertyIsEnumerable,Yn=Reflect.get;var Ln=(g,t)=>(t=Symbol[g])?t:Symbol.for("Symbol."+g),Un=g=>{throw TypeError(g)},mn=Math.pow,Vn=(g,t,r)=>t in g?Nn(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,bi=(g,t)=>{for(var r in t||(t={}))kn.call(t,r)&&Vn(g,r,t[r]);if(Wn)for(var r of Wn(t))Hn.call(t,r)&&Vn(g,r,t[r]);return g},Di=(g,t)=>Kn(g,Fn(t));var _0=(g,t,r)=>Vn(g,typeof t!="symbol"?t+"":t,r);var yn=(g,t,r)=>Yn(An(g),r,t);var D0=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())}),Bn=function(g,t){this[0]=g,this[1]=t};var Pn=g=>{var t=g[Ln("asyncIterator")],r=!1,d,v={};return t==null?(t=g[Ln("iterator")](),d=C=>v[C]=w=>t[C](w)):(t=t.call(g),d=C=>v[C]=w=>{if(r){if(r=!1,C==="throw")throw w;return w}return r=!0,{done:!1,value:new Bn(new Promise(E=>{var ye=t[C](w);ye instanceof Object||Un("Object expected"),E(ye)}),1)}}),v[Ln("iterator")]=()=>v,d("next"),"throw"in t?d("throw"):v.throw=C=>{throw C},"return"in t&&d("return"),v},En=(g,t,r)=>(t=g[Ln("asyncIterator")])?t.call(g):(g=g[Ln("iterator")](),t={},r=(d,v)=>(v=g[d])&&(t[d]=C=>new Promise((w,E,ye)=>(C=v.call(g,C),ye=C.done,Promise.resolve(C.value).then(Le=>w({value:Le,done:ye}),E)))),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(":::"),d=jsrsasign.KEYUTIL.getKey(atob(publicKeyPEM)),v=CryptoJS.enc.Base64.parse(t),C=CryptoJS.enc.Base64.parse(r),w=CryptoJS.lib.WordArray.create(v.words.slice(0,4)),E=CryptoJS.lib.WordArray.create(v.words.slice(4)),ye=jsrsasign.KJUR.crypto.Util.hashHex(v.toString(),"sha256"),Le=d.verifyWithMessageHashPSS(ye,jsrsasign.b64tohex(g),"sha256",32);if(!Le)return this.token=void 0,"";const Ne=CryptoJS.AES.decrypt({ciphertext:E},C,{iv:w,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8),Fe=JSON.parse(Ne),at=Date.now();return!Fe.s||Fe.s>at?(this.token=void 0,""):Fe.e&&Fe.e<at?(this.token=void 0,""):(Fe.isValid=Le,Fe)}},version="0.27.11";/**
3
3
  * @license
4
4
  * Copyright 2010-2025 Three.js Authors
5
5
  * SPDX-License-Identifier: MIT
@@ -3840,7 +3840,7 @@ void main() {
3840
3840
  opacity: 0.9;
3841
3841
  z-index: 10000;
3842
3842
  ${this.minimal?"cursor: pointer;":""}
3843
- `}setupEventListeners(){this.minimal?(this.dom.addEventListener("click",this.handleClick),this.showPanel(this.mode)):window.addEventListener("resize",this.handleResize)}init(t){return D0(this,null,function*(){if(!t){console.error('Stats: The "canvas" parameter is undefined.');return}if(!this.handleThreeRenderer(t)&&!(yield this.handleWebGPURenderer(t)))if(this.initializeWebGL(t)){this.trackGPU&&this.initializeGPUTracking();return}else console.error("Stats-gl: Failed to initialize WebGL context")})}handleThreeRenderer(t){return t.isWebGLRenderer&&!this.threeRendererPatched?(this.patchThreeRenderer(t),this.gl=t.getContext(),this.trackGPU&&this.initializeGPUTracking(),!0):!1}handleWebGPURenderer(t){return D0(this,null,function*(){return t.isWebGPURenderer?((this.trackGPU||this.trackCPT)&&(t.backend.trackTimestamp=!0,(yield t.hasFeatureAsync("timestamp-query"))&&this.initializeWebGPUPanels()),this.info=t.info,this.patchThreeWebGPU(t),!0):!1})}initializeWebGPUPanels(){this.trackGPU&&(this.gpuPanel=this.addPanel(new gn.Panel("GPU","#ff0","#220"))),this.trackCPT&&(this.gpuPanelCompute=this.addPanel(new gn.Panel("CPT","#e1e1e1","#212121")))}initializeWebGL(t){if(t instanceof WebGL2RenderingContext)this.gl=t;else if(t instanceof HTMLCanvasElement||t instanceof OffscreenCanvas){if(this.gl=t.getContext("webgl2"),!this.gl)return console.error("Stats: Unable to obtain WebGL2 context."),!1}else return console.error("Stats: Invalid input type. Expected WebGL2RenderingContext, HTMLCanvasElement, or OffscreenCanvas."),!1;return!0}initializeGPUTracking(){this.gl&&(this.ext=this.gl.getExtension("EXT_disjoint_timer_query_webgl2"),this.ext&&(this.gpuPanel=this.addPanel(new gn.Panel("GPU","#ff0","#220"))))}begin(){this.beginProfiling("cpu-started"),!(!this.gl||!this.ext)&&(this.activeQuery&&this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.activeQuery=this.gl.createQuery(),this.activeQuery&&this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT,this.activeQuery))}end(){this.renderCount++,this.gl&&this.ext&&this.activeQuery&&(this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.gpuQueries.push({query:this.activeQuery}),this.activeQuery=null),this.endProfiling("cpu-started","cpu-finished","cpu-duration")}update(){this.endProfiling("cpu-started","cpu-finished","cpu-duration"),this.info?this.processWebGPUTimestamps():this.processGpuQueries(),this.updateAverages(),this.resetCounters()}processWebGPUTimestamps(){this.totalGpuDuration=this.info.render.timestamp,this.totalGpuDurationCompute=this.info.compute.timestamp}resetCounters(){this.renderCount=0,this.totalCpuDuration=0,this.beginTime=this.endInternal()}resizePanel(t){t.canvas.style.position="absolute",this.minimal?t.canvas.style.display="none":(t.canvas.style.display="block",this.horizontal?(t.canvas.style.top="0px",t.canvas.style.left=t.id*t.WIDTH/t.PR+"px"):(t.canvas.style.left="0px",t.canvas.style.top=t.id*t.HEIGHT/t.PR+"px"))}addPanel(t){return t.canvas&&(this.dom.appendChild(t.canvas),t.id=this._panelId,this.resizePanel(t),this._panelId++),t}showPanel(t){for(let r=0;r<this.dom.children.length;r++){const d=this.dom.children[r];d.style.display=r===t?"block":"none"}this.mode=t}processGpuQueries(){!this.gl||!this.ext||(this.totalGpuDuration=0,this.gpuQueries.forEach((t,r)=>{if(this.gl){const d=this.gl.getQueryParameter(t.query,this.gl.QUERY_RESULT_AVAILABLE),v=this.gl.getParameter(this.ext.GPU_DISJOINT_EXT);if(d&&!v){const w=this.gl.getQueryParameter(t.query,this.gl.QUERY_RESULT)*1e-6;this.totalGpuDuration+=w,this.gl.deleteQuery(t.query),this.gpuQueries.splice(r,1)}}}))}detectVSync(t){if(this.lastFrameTime===0){this.lastFrameTime=t;return}const r=t-this.lastFrameTime;if(this.lastFrameTime=t,this.frameTimeHistory.push(r),this.frameTimeHistory.length>this.HISTORY_SIZE&&this.frameTimeHistory.shift(),this.frameTimeHistory.length<60)return;const d=this.frameTimeHistory.reduce((ye,Le)=>ye+Le)/this.frameTimeHistory.length,v=this.frameTimeHistory.reduce((ye,Le)=>ye+Math.pow(Le-d,2),0)/this.frameTimeHistory.length;if(Math.sqrt(v)>2){this.detectedVSync=null;return}let w=null,E=1/0;for(const ye of this.VSYNC_RATES){const Le=Math.abs(d-ye.frameTime);Le<E&&(E=Le,w=ye)}w&&E/w.frameTime<=this.VSYNC_THRESHOLD?this.detectedVSync=w:this.detectedVSync=null}endInternal(){var t;const r=performance.now();for(this.frameTimes.push(r);this.frameTimes.length>0&&this.frameTimes[0]<=r-1e3;)this.frameTimes.shift();const d=Math.round(this.frameTimes.length);this.addToAverage(d,this.averageFps);const v=r>=this.prevTextTime+1e3/this.logsPerSecond,C=r>=this.prevGraphTime+1e3/this.graphsPerSecond;if(this.updatePanelComponents(this.fpsPanel,this.averageFps,0,v,C),this.updatePanelComponents(this.msPanel,this.averageCpu,this.precision,v,C),this.gpuPanel&&this.updatePanelComponents(this.gpuPanel,this.averageGpu,this.precision,v,C),this.trackCPT&&this.gpuPanelCompute&&this.updatePanelComponents(this.gpuPanelCompute,this.averageGpuCompute,this.precision,v,C),v&&(this.prevTextTime=r),C&&(this.prevGraphTime=r),this.vsyncPanel!==null){this.detectVSync(r);const w=((t=this.detectedVSync)==null?void 0:t.refreshRate)||0;v&&w>0&&this.vsyncPanel.update(w,w)}return r}updatePanelComponents(t,r,d,v,C){if(!t||r.logs.length===0)return;t.name in this.lastMin||(this.lastMin[t.name]=1/0,this.lastMax[t.name]=0,this.lastValue[t.name]=0);const w=r.logs[r.logs.length-1];this.lastMax[t.name]=Math.max(...r.logs),this.lastMin[t.name]=Math.min(this.lastMin[t.name],w),this.lastValue[t.name]=this.lastValue[t.name]*.7+w*.3;const E=Math.max(Math.max(...r.logs),...r.graph.slice(-this.samplesGraph));this.updateCounter++,v&&t.update(this.lastValue[t.name],this.lastMax[t.name],d),C&&t.updateGraph(w,E)}beginProfiling(t){if(window.performance)try{window.performance.clearMarks(t),window.performance.mark(t)}catch(r){console.debug("Stats: Performance marking failed:",r)}}endProfiling(t,r,d){if(!(!window.performance||!r||!t))try{window.performance.getEntriesByName(t,"mark").length===0&&this.beginProfiling(t),window.performance.clearMarks(r),window.performance.mark(r),window.performance.clearMeasures(d);const C=performance.measure(d,t,r);this.totalCpuDuration+=C.duration,window.performance.clearMarks(t),window.performance.clearMarks(r),window.performance.clearMeasures(d)}catch(v){console.debug("Stats: Performance measurement failed:",v)}}updatePanel(t,r,d=2){if(!t||r.logs.length===0)return;const v=performance.now();t.name in this.lastMin||(this.lastMin[t.name]=1/0,this.lastMax[t.name]=0,this.lastValue[t.name]=0);const C=r.logs[r.logs.length-1],w=Math.max(...r.logs.slice(-30));this.lastMin[t.name]=Math.min(this.lastMin[t.name],C),this.lastMax[t.name]=Math.max(this.lastMax[t.name],C),this.lastValue[t.name]=this.lastValue[t.name]*.7+C*.3;const E=Math.max(w,...r.graph.slice(-this.samplesGraph));this.updateCounter++,this.updateCounter%(this.logsPerSecond*2)===0&&(this.lastMax[t.name]=w,this.lastMin[t.name]=C),t.update&&(v>=this.prevCpuTime+1e3/this.logsPerSecond&&t.update(this.lastValue[t.name],C,this.lastMax[t.name],E,d),v>=this.prevGraphTime+1e3/this.graphsPerSecond&&(t.updateGraph(C,E),this.prevGraphTime=v))}updateAverages(){this.addToAverage(this.totalCpuDuration,this.averageCpu),this.addToAverage(this.totalGpuDuration,this.averageGpu),this.info&&this.totalGpuDurationCompute!==void 0&&this.addToAverage(this.totalGpuDurationCompute,this.averageGpuCompute)}addToAverage(t,r){r.logs.push(t),r.logs.length>this.samplesLog&&(r.logs=r.logs.slice(-this.samplesLog)),r.graph.push(t),r.graph.length>this.samplesGraph&&(r.graph=r.graph.slice(-this.samplesGraph))}get domElement(){return this.dom}patchThreeWebGPU(t){const r=t.info.reset,d=this;t.info.reset=function(){d.beginProfiling("cpu-started"),r.call(this)}}patchThreeRenderer(t){const r=t.render,d=this;t.render=function(v,C){d.begin(),r.call(this,v,C),d.end()},this.threeRendererPatched=!0}};_Stats.Panel=Panel;let Stats=_Stats;const e={linearSRGB:"srgb-linear",sRGB:"srgb"},a$2={map:e.sRGB,sheenColorMap:e.sRGB,specularColorMap:e.sRGB,emissiveMap:e.sRGB,envMap:e.sRGB};function l$1({node:g,material:t,texture:r}){i$3({node:g,material:t,texture:r}).forEach(n)}function i$3({node:g,material:t,texture:r}){return r?[{map:r}]:t?Array.isArray(t)?t:[t]:g!=null&&g.material?Array.isArray(g.material)?g.material:[g.material]:[]}function n(g){Object.keys(a$2).forEach(t=>{const r=g;r[t]&&(r[t].colorSpace=a$2[t])})}function c$1(g){return Object.prototype.toString.call(g)==="[object Object]"}function f(g){if(c$1(g)===!1)return!1;const t=g.constructor;if(t===void 0)return!0;const r=t.prototype;return!(c$1(r)===!1||r.hasOwnProperty("isPrototypeOf")===!1)}class CSS2DObject extends Object3D{constructor(t=document.createElement("div")){super(),this.isCSS2DObject=!0,this.element=t,this.element.style.position="absolute",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.center=new Vector2(.5,.5),this.addEventListener("removed",function(){this.traverse(function(r){r.element instanceof r.element.ownerDocument.defaultView.Element&&r.element.parentNode!==null&&r.element.remove()})})}copy(t,r){return super.copy(t,r),this.element=t.element.cloneNode(!0),this.center=t.center,this}}new Vector3;new Matrix4;new Matrix4;new Vector3;new Vector3;new Vector3;new Vector3;class CSS3DObject extends Object3D{constructor(t=document.createElement("div")){super(),this.isCSS3DObject=!0,this.element=t,this.element.style.position="absolute",this.element.style.pointerEvents="auto",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.addEventListener("removed",function(){this.traverse(function(r){r.element instanceof r.element.ownerDocument.defaultView.Element&&r.element.parentNode!==null&&r.element.remove()})})}copy(t,r){return super.copy(t,r),this.element=t.element.cloneNode(!0),this}}class CSS3DSprite extends CSS3DObject{constructor(t){super(t),this.isCSS3DSprite=!0,this.rotation2D=0}copy(t,r){return super.copy(t,r),this.rotation2D=t.rotation2D,this}}new Matrix4;new Matrix4;function ascending(g,t){return g==null||t==null?NaN:g<t?-1:g>t?1:g>=t?0:NaN}function descending(g,t){return g==null||t==null?NaN:t<g?-1:t>g?1:t>=g?0:NaN}function bisector(g){let t,r,d;g.length!==2?(t=ascending,r=(E,ye)=>ascending(g(E),ye),d=(E,ye)=>g(E)-ye):(t=g===ascending||g===descending?g:zero$1,r=g,d=g);function v(E,ye,Le=0,Re=E.length){if(Le<Re){if(t(ye,ye)!==0)return Re;do{const Ne=Le+Re>>>1;r(E[Ne],ye)<0?Le=Ne+1:Re=Ne}while(Le<Re)}return Le}function C(E,ye,Le=0,Re=E.length){if(Le<Re){if(t(ye,ye)!==0)return Re;do{const Ne=Le+Re>>>1;r(E[Ne],ye)<=0?Le=Ne+1:Re=Ne}while(Le<Re)}return Le}function w(E,ye,Le=0,Re=E.length){const Ne=v(E,ye,Le,Re-1);return Ne>Le&&d(E[Ne-1],ye)>-d(E[Ne],ye)?Ne-1:Ne}return{left:v,center:w,right:C}}function zero$1(){return 0}function number$1(g){return g===null?NaN:+g}const ascendingBisect=bisector(ascending),bisectRight=ascendingBisect.right;bisector(number$1).center;function extent(g,t){let r,d;if(t===void 0)for(const v of g)v!=null&&(r===void 0?v>=v&&(r=d=v):(r>v&&(r=v),d<v&&(d=v)));else{let v=-1;for(let C of g)(C=t(C,++v,g))!=null&&(r===void 0?C>=C&&(r=d=C):(r>C&&(r=C),d<C&&(d=C)))}return[r,d]}class Adder{constructor(){this._partials=new Float64Array(32),this._n=0}add(t){const r=this._partials;let d=0;for(let v=0;v<this._n&&v<32;v++){const C=r[v],w=t+C,E=Math.abs(t)<Math.abs(C)?t-(w-C):C-(w-t);E&&(r[d++]=E),t=w}return r[d]=t,this._n=d+1,this}valueOf(){const t=this._partials;let r=this._n,d,v,C,w=0;if(r>0){for(w=t[--r];r>0&&(d=w,v=t[--r],w=d+v,C=v-(w-d),!C););r>0&&(C<0&&t[r-1]<0||C>0&&t[r-1]>0)&&(v=C*2,d=w+v,v==d-w&&(w=d))}return w}}const e10=Math.sqrt(50),e5=Math.sqrt(10),e2=Math.sqrt(2);function tickSpec(g,t,r){const d=(t-g)/Math.max(0,r),v=Math.floor(Math.log10(d)),C=d/Math.pow(10,v),w=C>=e10?10:C>=e5?5:C>=e2?2:1;let E,ye,Le;return v<0?(Le=Math.pow(10,-v)/w,E=Math.round(g*Le),ye=Math.round(t*Le),E/Le<g&&++E,ye/Le>t&&--ye,Le=-Le):(Le=Math.pow(10,v)*w,E=Math.round(g/Le),ye=Math.round(t/Le),E*Le<g&&++E,ye*Le>t&&--ye),ye<E&&.5<=r&&r<2?tickSpec(g,t,r*2):[E,ye,Le]}function ticks(g,t,r){if(t=+t,g=+g,r=+r,!(r>0))return[];if(g===t)return[g];const d=t<g,[v,C,w]=d?tickSpec(t,g,r):tickSpec(g,t,r);if(!(C>=v))return[];const E=C-v+1,ye=new Array(E);if(d)if(w<0)for(let Le=0;Le<E;++Le)ye[Le]=(C-Le)/-w;else for(let Le=0;Le<E;++Le)ye[Le]=(C-Le)*w;else if(w<0)for(let Le=0;Le<E;++Le)ye[Le]=(v+Le)/-w;else for(let Le=0;Le<E;++Le)ye[Le]=(v+Le)*w;return ye}function tickIncrement(g,t,r){return t=+t,g=+g,r=+r,tickSpec(g,t,r)[2]}function tickStep(g,t,r){t=+t,g=+g,r=+r;const d=t<g,v=d?tickIncrement(t,g,r):tickIncrement(g,t,r);return(d?-1:1)*(v<0?1/-v:v)}function mean(g,t){let r=0,d=0;if(t===void 0)for(let v of g)v!=null&&(v=+v)>=v&&(++r,d+=v);else{let v=-1;for(let C of g)(C=t(C,++v,g))!=null&&(C=+C)>=C&&(++r,d+=C)}if(r)return d/r}function*flatten$1(g){for(const t of g)yield*Pn(t)}function merge(g){return Array.from(flatten$1(g))}var epsilon$2=1e-6,epsilon2=1e-12,pi$3=Math.PI,halfPi$1=pi$3/2,quarterPi=pi$3/4,tau$1=pi$3*2,degrees$1=180/pi$3,radians$2=pi$3/180,abs=Math.abs,atan$1=Math.atan,atan2$1=Math.atan2,cos$2=Math.cos,exp=Math.exp,hypot=Math.hypot,log=Math.log,sin$1=Math.sin,sign$2=Math.sign||function(g){return g>0?1:g<0?-1:0},sqrt$2=Math.sqrt,tan$1=Math.tan;function acos(g){return g>1?0:g<-1?pi$3:Math.acos(g)}function asin$1(g){return g>1?halfPi$1:g<-1?-halfPi$1:Math.asin(g)}function haversin(g){return(g=sin$1(g/2))*g}function noop(){}function streamGeometry(g,t){g&&streamGeometryType.hasOwnProperty(g.type)&&streamGeometryType[g.type](g,t)}var streamObjectType={Feature:function(g,t){streamGeometry(g.geometry,t)},FeatureCollection:function(g,t){for(var r=g.features,d=-1,v=r.length;++d<v;)streamGeometry(r[d].geometry,t)}},streamGeometryType={Sphere:function(g,t){t.sphere()},Point:function(g,t){g=g.coordinates,t.point(g[0],g[1],g[2])},MultiPoint:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)g=r[d],t.point(g[0],g[1],g[2])},LineString:function(g,t){streamLine(g.coordinates,t,0)},MultiLineString:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)streamLine(r[d],t,0)},Polygon:function(g,t){streamPolygon(g.coordinates,t)},MultiPolygon:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)streamPolygon(r[d],t)},GeometryCollection:function(g,t){for(var r=g.geometries,d=-1,v=r.length;++d<v;)streamGeometry(r[d],t)}};function streamLine(g,t,r){var d=-1,v=g.length-r,C;for(t.lineStart();++d<v;)C=g[d],t.point(C[0],C[1],C[2]);t.lineEnd()}function streamPolygon(g,t){var r=-1,d=g.length;for(t.polygonStart();++r<d;)streamLine(g[r],t,1);t.polygonEnd()}function geoStream(g,t){g&&streamObjectType.hasOwnProperty(g.type)?streamObjectType[g.type](g,t):streamGeometry(g,t)}var areaRingSum=new Adder,areaSum=new Adder,lambda00$2,phi00$2,lambda0$2,cosPhi0$1,sinPhi0$1,areaStream={point:noop,lineStart:noop,lineEnd:noop,polygonStart:function(){areaRingSum=new Adder,areaStream.lineStart=areaRingStart,areaStream.lineEnd=areaRingEnd},polygonEnd:function(){var g=+areaRingSum;areaSum.add(g<0?tau$1+g:g),this.lineStart=this.lineEnd=this.point=noop},sphere:function(){areaSum.add(tau$1)}};function areaRingStart(){areaStream.point=areaPointFirst}function areaRingEnd(){areaPoint(lambda00$2,phi00$2)}function areaPointFirst(g,t){areaStream.point=areaPoint,lambda00$2=g,phi00$2=t,g*=radians$2,t*=radians$2,lambda0$2=g,cosPhi0$1=cos$2(t=t/2+quarterPi),sinPhi0$1=sin$1(t)}function areaPoint(g,t){g*=radians$2,t*=radians$2,t=t/2+quarterPi;var r=g-lambda0$2,d=r>=0?1:-1,v=d*r,C=cos$2(t),w=sin$1(t),E=sinPhi0$1*w,ye=cosPhi0$1*C+E*cos$2(v),Le=E*d*sin$1(v);areaRingSum.add(atan2$1(Le,ye)),lambda0$2=g,cosPhi0$1=C,sinPhi0$1=w}function spherical$1(g){return[atan2$1(g[1],g[0]),asin$1(g[2])]}function cartesian$1(g){var t=g[0],r=g[1],d=cos$2(r);return[d*cos$2(t),d*sin$1(t),sin$1(r)]}function cartesianDot$1(g,t){return g[0]*t[0]+g[1]*t[1]+g[2]*t[2]}function cartesianCross$1(g,t){return[g[1]*t[2]-g[2]*t[1],g[2]*t[0]-g[0]*t[2],g[0]*t[1]-g[1]*t[0]]}function cartesianAddInPlace(g,t){g[0]+=t[0],g[1]+=t[1],g[2]+=t[2]}function cartesianScale(g,t){return[g[0]*t,g[1]*t,g[2]*t]}function cartesianNormalizeInPlace(g){var t=sqrt$2(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]);g[0]/=t,g[1]/=t,g[2]/=t}var lambda0$1,phi0,lambda1,phi1,lambda2,lambda00$1,phi00$1,p0,deltaSum,ranges,range,boundsStream$1={point:boundsPoint$1,lineStart:boundsLineStart,lineEnd:boundsLineEnd,polygonStart:function(){boundsStream$1.point=boundsRingPoint,boundsStream$1.lineStart=boundsRingStart,boundsStream$1.lineEnd=boundsRingEnd,deltaSum=new Adder,areaStream.polygonStart()},polygonEnd:function(){areaStream.polygonEnd(),boundsStream$1.point=boundsPoint$1,boundsStream$1.lineStart=boundsLineStart,boundsStream$1.lineEnd=boundsLineEnd,areaRingSum<0?(lambda0$1=-(lambda1=180),phi0=-(phi1=90)):deltaSum>epsilon$2?phi1=90:deltaSum<-epsilon$2&&(phi0=-90),range[0]=lambda0$1,range[1]=lambda1},sphere:function(){lambda0$1=-(lambda1=180),phi0=-(phi1=90)}};function boundsPoint$1(g,t){ranges.push(range=[lambda0$1=g,lambda1=g]),t<phi0&&(phi0=t),t>phi1&&(phi1=t)}function linePoint(g,t){var r=cartesian$1([g*radians$2,t*radians$2]);if(p0){var d=cartesianCross$1(p0,r),v=[d[1],-d[0],0],C=cartesianCross$1(v,d);cartesianNormalizeInPlace(C),C=spherical$1(C);var w=g-lambda2,E=w>0?1:-1,ye=C[0]*degrees$1*E,Le,Re=abs(w)>180;Re^(E*lambda2<ye&&ye<E*g)?(Le=C[1]*degrees$1,Le>phi1&&(phi1=Le)):(ye=(ye+360)%360-180,Re^(E*lambda2<ye&&ye<E*g)?(Le=-C[1]*degrees$1,Le<phi0&&(phi0=Le)):(t<phi0&&(phi0=t),t>phi1&&(phi1=t))),Re?g<lambda2?angle(lambda0$1,g)>angle(lambda0$1,lambda1)&&(lambda1=g):angle(g,lambda1)>angle(lambda0$1,lambda1)&&(lambda0$1=g):lambda1>=lambda0$1?(g<lambda0$1&&(lambda0$1=g),g>lambda1&&(lambda1=g)):g>lambda2?angle(lambda0$1,g)>angle(lambda0$1,lambda1)&&(lambda1=g):angle(g,lambda1)>angle(lambda0$1,lambda1)&&(lambda0$1=g)}else ranges.push(range=[lambda0$1=g,lambda1=g]);t<phi0&&(phi0=t),t>phi1&&(phi1=t),p0=r,lambda2=g}function boundsLineStart(){boundsStream$1.point=linePoint}function boundsLineEnd(){range[0]=lambda0$1,range[1]=lambda1,boundsStream$1.point=boundsPoint$1,p0=null}function boundsRingPoint(g,t){if(p0){var r=g-lambda2;deltaSum.add(abs(r)>180?r+(r>0?360:-360):r)}else lambda00$1=g,phi00$1=t;areaStream.point(g,t),linePoint(g,t)}function boundsRingStart(){areaStream.lineStart()}function boundsRingEnd(){boundsRingPoint(lambda00$1,phi00$1),areaStream.lineEnd(),abs(deltaSum)>epsilon$2&&(lambda0$1=-(lambda1=180)),range[0]=lambda0$1,range[1]=lambda1,p0=null}function angle(g,t){return(t-=g)<0?t+360:t}function rangeCompare(g,t){return g[0]-t[0]}function rangeContains(g,t){return g[0]<=g[1]?g[0]<=t&&t<=g[1]:t<g[0]||g[1]<t}function wt(g){var t,r,d,v,C,w,E;if(phi1=lambda1=-(lambda0$1=phi0=1/0),ranges=[],geoStream(g,boundsStream$1),r=ranges.length){for(ranges.sort(rangeCompare),t=1,d=ranges[0],C=[d];t<r;++t)v=ranges[t],rangeContains(d,v[0])||rangeContains(d,v[1])?(angle(d[0],v[1])>angle(d[0],d[1])&&(d[1]=v[1]),angle(v[0],d[1])>angle(d[0],d[1])&&(d[0]=v[0])):C.push(d=v);for(w=-1/0,r=C.length-1,t=0,d=C[r];t<=r;d=v,++t)v=C[t],(E=angle(d[1],v[0]))>w&&(w=E,lambda0$1=v[0],lambda1=d[1])}return ranges=range=null,lambda0$1===1/0||phi0===1/0?[[NaN,NaN],[NaN,NaN]]:[[lambda0$1,phi0],[lambda1,phi1]]}var W0,W1,X0,Y0,Z0,X1,Y1,Z1,X2,Y2,Z2,lambda00,phi00,x0$1,y0$1,z0,centroidStream={sphere:noop,point:centroidPoint,lineStart:centroidLineStart,lineEnd:centroidLineEnd,polygonStart:function(){centroidStream.lineStart=centroidRingStart,centroidStream.lineEnd=centroidRingEnd},polygonEnd:function(){centroidStream.lineStart=centroidLineStart,centroidStream.lineEnd=centroidLineEnd}};function centroidPoint(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t);centroidPointCartesian(r*cos$2(g),r*sin$1(g),sin$1(t))}function centroidPointCartesian(g,t,r){++W0,X0+=(g-X0)/W0,Y0+=(t-Y0)/W0,Z0+=(r-Z0)/W0}function centroidLineStart(){centroidStream.point=centroidLinePointFirst}function centroidLinePointFirst(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t);x0$1=r*cos$2(g),y0$1=r*sin$1(g),z0=sin$1(t),centroidStream.point=centroidLinePoint,centroidPointCartesian(x0$1,y0$1,z0)}function centroidLinePoint(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t),d=r*cos$2(g),v=r*sin$1(g),C=sin$1(t),w=atan2$1(sqrt$2((w=y0$1*C-z0*v)*w+(w=z0*d-x0$1*C)*w+(w=x0$1*v-y0$1*d)*w),x0$1*d+y0$1*v+z0*C);W1+=w,X1+=w*(x0$1+(x0$1=d)),Y1+=w*(y0$1+(y0$1=v)),Z1+=w*(z0+(z0=C)),centroidPointCartesian(x0$1,y0$1,z0)}function centroidLineEnd(){centroidStream.point=centroidPoint}function centroidRingStart(){centroidStream.point=centroidRingPointFirst}function centroidRingEnd(){centroidRingPoint(lambda00,phi00),centroidStream.point=centroidPoint}function centroidRingPointFirst(g,t){lambda00=g,phi00=t,g*=radians$2,t*=radians$2,centroidStream.point=centroidRingPoint;var r=cos$2(t);x0$1=r*cos$2(g),y0$1=r*sin$1(g),z0=sin$1(t),centroidPointCartesian(x0$1,y0$1,z0)}function centroidRingPoint(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t),d=r*cos$2(g),v=r*sin$1(g),C=sin$1(t),w=y0$1*C-z0*v,E=z0*d-x0$1*C,ye=x0$1*v-y0$1*d,Le=hypot(w,E,ye),Re=asin$1(Le),Ne=Le&&-Re/Le;X2.add(Ne*w),Y2.add(Ne*E),Z2.add(Ne*ye),W1+=Re,X1+=Re*(x0$1+(x0$1=d)),Y1+=Re*(y0$1+(y0$1=v)),Z1+=Re*(z0+(z0=C)),centroidPointCartesian(x0$1,y0$1,z0)}function geoCentroid(g){W0=W1=X0=Y0=Z0=X1=Y1=Z1=0,X2=new Adder,Y2=new Adder,Z2=new Adder,geoStream(g,centroidStream);var t=+X2,r=+Y2,d=+Z2,v=hypot(t,r,d);return v<epsilon2&&(t=X1,r=Y1,d=Z1,W1<epsilon$2&&(t=X0,r=Y0,d=Z0),v=hypot(t,r,d),v<epsilon2)?[NaN,NaN]:[atan2$1(r,t)*degrees$1,asin$1(d/v)*degrees$1]}function compose(g,t){function r(d,v){return d=g(d,v),t(d[0],d[1])}return g.invert&&t.invert&&(r.invert=function(d,v){return d=t.invert(d,v),d&&g.invert(d[0],d[1])}),r}function rotationIdentity(g,t){return abs(g)>pi$3&&(g-=Math.round(g/tau$1)*tau$1),[g,t]}rotationIdentity.invert=rotationIdentity;function rotateRadians(g,t,r){return(g%=tau$1)?t||r?compose(rotationLambda(g),rotationPhiGamma(t,r)):rotationLambda(g):t||r?rotationPhiGamma(t,r):rotationIdentity}function forwardRotationLambda(g){return function(t,r){return t+=g,abs(t)>pi$3&&(t-=Math.round(t/tau$1)*tau$1),[t,r]}}function rotationLambda(g){var t=forwardRotationLambda(g);return t.invert=forwardRotationLambda(-g),t}function rotationPhiGamma(g,t){var r=cos$2(g),d=sin$1(g),v=cos$2(t),C=sin$1(t);function w(E,ye){var Le=cos$2(ye),Re=cos$2(E)*Le,Ne=sin$1(E)*Le,Fe=sin$1(ye),at=Fe*r+Re*d;return[atan2$1(Ne*v-at*C,Re*r-Fe*d),asin$1(at*v+Ne*C)]}return w.invert=function(E,ye){var Le=cos$2(ye),Re=cos$2(E)*Le,Ne=sin$1(E)*Le,Fe=sin$1(ye),at=Fe*v-Ne*C;return[atan2$1(Ne*v+Fe*C,Re*r+at*d),asin$1(at*r-Re*d)]},w}function geoRotation(g){g=rotateRadians(g[0]*radians$2,g[1]*radians$2,g.length>2?g[2]*radians$2:0);function t(r){return r=g(r[0]*radians$2,r[1]*radians$2),r[0]*=degrees$1,r[1]*=degrees$1,r}return t.invert=function(r){return r=g.invert(r[0]*radians$2,r[1]*radians$2),r[0]*=degrees$1,r[1]*=degrees$1,r},t}function circleStream(g,t,r,d,v,C){if(r){var w=cos$2(t),E=sin$1(t),ye=d*r;v==null?(v=t+d*tau$1,C=t-ye/2):(v=circleRadius(w,v),C=circleRadius(w,C),(d>0?v<C:v>C)&&(v+=d*tau$1));for(var Le,Re=v;d>0?Re>C:Re<C;Re-=ye)Le=spherical$1([w,-E*cos$2(Re),-E*sin$1(Re)]),g.point(Le[0],Le[1])}}function circleRadius(g,t){t=cartesian$1(t),t[0]-=g,cartesianNormalizeInPlace(t);var r=acos(-t[1]);return((-t[2]<0?-r:r)+tau$1-epsilon$2)%tau$1}function clipBuffer(){var g=[],t;return{point:function(r,d,v){t.push([r,d,v])},lineStart:function(){g.push(t=[])},lineEnd:noop,rejoin:function(){g.length>1&&g.push(g.pop().concat(g.shift()))},result:function(){var r=g;return g=[],t=null,r}}}function pointEqual(g,t){return abs(g[0]-t[0])<epsilon$2&&abs(g[1]-t[1])<epsilon$2}function Intersection(g,t,r,d){this.x=g,this.z=t,this.o=r,this.e=d,this.v=!1,this.n=this.p=null}function clipRejoin(g,t,r,d,v){var C=[],w=[],E,ye;if(g.forEach(function(ot){if(!((Gt=ot.length-1)<=0)){var Gt,ht=ot[0],ke=ot[Gt],ct;if(pointEqual(ht,ke)){if(!ht[2]&&!ke[2]){for(v.lineStart(),E=0;E<Gt;++E)v.point((ht=ot[E])[0],ht[1]);v.lineEnd();return}ke[0]+=2*epsilon$2}C.push(ct=new Intersection(ht,ot,null,!0)),w.push(ct.o=new Intersection(ht,null,ct,!1)),C.push(ct=new Intersection(ke,ot,null,!1)),w.push(ct.o=new Intersection(ke,null,ct,!0))}}),!!C.length){for(w.sort(t),link(C),link(w),E=0,ye=w.length;E<ye;++E)w[E].e=r=!r;for(var Le=C[0],Re,Ne;;){for(var Fe=Le,at=!0;Fe.v;)if((Fe=Fe.n)===Le)return;Re=Fe.z,v.lineStart();do{if(Fe.v=Fe.o.v=!0,Fe.e){if(at)for(E=0,ye=Re.length;E<ye;++E)v.point((Ne=Re[E])[0],Ne[1]);else d(Fe.x,Fe.n.x,1,v);Fe=Fe.n}else{if(at)for(Re=Fe.p.z,E=Re.length-1;E>=0;--E)v.point((Ne=Re[E])[0],Ne[1]);else d(Fe.x,Fe.p.x,-1,v);Fe=Fe.p}Fe=Fe.o,Re=Fe.z,at=!at}while(!Fe.v);v.lineEnd()}}}function link(g){if(t=g.length){for(var t,r=0,d=g[0],v;++r<t;)d.n=v=g[r],v.p=d,d=v;d.n=v=g[0],v.p=d}}function longitude(g){return abs(g[0])<=pi$3?g[0]:sign$2(g[0])*((abs(g[0])+pi$3)%tau$1-pi$3)}function polygonContains(g,t){var r=longitude(t),d=t[1],v=sin$1(d),C=[sin$1(r),-cos$2(r),0],w=0,E=0,ye=new Adder;v===1?d=halfPi$1+epsilon$2:v===-1&&(d=-halfPi$1-epsilon$2);for(var Le=0,Re=g.length;Le<Re;++Le)if(Fe=(Ne=g[Le]).length)for(var Ne,Fe,at=Ne[Fe-1],ot=longitude(at),Gt=at[1]/2+quarterPi,ht=sin$1(Gt),ke=cos$2(Gt),ct=0;ct<Fe;++ct,ot=Rt,ht=Pt,ke=Nt,at=xt){var xt=Ne[ct],Rt=longitude(xt),Wt=xt[1]/2+quarterPi,Pt=sin$1(Wt),Nt=cos$2(Wt),Kt=Rt-ot,Ft=Kt>=0?1:-1,kt=Ft*Kt,Yt=kt>pi$3,s0=ht*Pt;if(ye.add(atan2$1(s0*Ft*sin$1(kt),ke*Nt+s0*cos$2(kt))),w+=Yt?Kt+Ft*tau$1:Kt,Yt^ot>=r^Rt>=r){var o0=cartesianCross$1(cartesian$1(at),cartesian$1(xt));cartesianNormalizeInPlace(o0);var h0=cartesianCross$1(C,o0);cartesianNormalizeInPlace(h0);var r0=(Yt^Kt>=0?-1:1)*asin$1(h0[2]);(d>r0||d===r0&&(o0[0]||o0[1]))&&(E+=Yt^Kt>=0?1:-1)}}return(w<-epsilon$2||w<epsilon$2&&ye<-epsilon2)^E&1}function clip(g,t,r,d){return function(v){var C=t(v),w=clipBuffer(),E=t(w),ye=!1,Le,Re,Ne,Fe={point:at,lineStart:Gt,lineEnd:ht,polygonStart:function(){Fe.point=ke,Fe.lineStart=ct,Fe.lineEnd=xt,Re=[],Le=[]},polygonEnd:function(){Fe.point=at,Fe.lineStart=Gt,Fe.lineEnd=ht,Re=merge(Re);var Rt=polygonContains(Le,d);Re.length?(ye||(v.polygonStart(),ye=!0),clipRejoin(Re,compareIntersection,Rt,r,v)):Rt&&(ye||(v.polygonStart(),ye=!0),v.lineStart(),r(null,null,1,v),v.lineEnd()),ye&&(v.polygonEnd(),ye=!1),Re=Le=null},sphere:function(){v.polygonStart(),v.lineStart(),r(null,null,1,v),v.lineEnd(),v.polygonEnd()}};function at(Rt,Wt){g(Rt,Wt)&&v.point(Rt,Wt)}function ot(Rt,Wt){C.point(Rt,Wt)}function Gt(){Fe.point=ot,C.lineStart()}function ht(){Fe.point=at,C.lineEnd()}function ke(Rt,Wt){Ne.push([Rt,Wt]),E.point(Rt,Wt)}function ct(){E.lineStart(),Ne=[]}function xt(){ke(Ne[0][0],Ne[0][1]),E.lineEnd();var Rt=E.clean(),Wt=w.result(),Pt,Nt=Wt.length,Kt,Ft,kt;if(Ne.pop(),Le.push(Ne),Ne=null,!!Nt){if(Rt&1){if(Ft=Wt[0],(Kt=Ft.length-1)>0){for(ye||(v.polygonStart(),ye=!0),v.lineStart(),Pt=0;Pt<Kt;++Pt)v.point((kt=Ft[Pt])[0],kt[1]);v.lineEnd()}return}Nt>1&&Rt&2&&Wt.push(Wt.pop().concat(Wt.shift())),Re.push(Wt.filter(validSegment))}}return Fe}}function validSegment(g){return g.length>1}function compareIntersection(g,t){return((g=g.x)[0]<0?g[1]-halfPi$1-epsilon$2:halfPi$1-g[1])-((t=t.x)[0]<0?t[1]-halfPi$1-epsilon$2:halfPi$1-t[1])}const clipAntimeridian=clip(function(){return!0},clipAntimeridianLine,clipAntimeridianInterpolate,[-pi$3,-halfPi$1]);function clipAntimeridianLine(g){var t=NaN,r=NaN,d=NaN,v;return{lineStart:function(){g.lineStart(),v=1},point:function(C,w){var E=C>0?pi$3:-pi$3,ye=abs(C-t);abs(ye-pi$3)<epsilon$2?(g.point(t,r=(r+w)/2>0?halfPi$1:-halfPi$1),g.point(d,r),g.lineEnd(),g.lineStart(),g.point(E,r),g.point(C,r),v=0):d!==E&&ye>=pi$3&&(abs(t-d)<epsilon$2&&(t-=d*epsilon$2),abs(C-E)<epsilon$2&&(C-=E*epsilon$2),r=clipAntimeridianIntersect(t,r,C,w),g.point(d,r),g.lineEnd(),g.lineStart(),g.point(E,r),v=0),g.point(t=C,r=w),d=E},lineEnd:function(){g.lineEnd(),t=r=NaN},clean:function(){return 2-v}}}function clipAntimeridianIntersect(g,t,r,d){var v,C,w=sin$1(g-r);return abs(w)>epsilon$2?atan$1((sin$1(t)*(C=cos$2(d))*sin$1(r)-sin$1(d)*(v=cos$2(t))*sin$1(g))/(v*C*w)):(t+d)/2}function clipAntimeridianInterpolate(g,t,r,d){var v;if(g==null)v=r*halfPi$1,d.point(-pi$3,v),d.point(0,v),d.point(pi$3,v),d.point(pi$3,0),d.point(pi$3,-v),d.point(0,-v),d.point(-pi$3,-v),d.point(-pi$3,0),d.point(-pi$3,v);else if(abs(g[0]-t[0])>epsilon$2){var C=g[0]<t[0]?pi$3:-pi$3;v=r*C/2,d.point(-C,v),d.point(0,v),d.point(C,v)}else d.point(t[0],t[1])}function clipCircle(g){var t=cos$2(g),r=2*radians$2,d=t>0,v=abs(t)>epsilon$2;function C(Re,Ne,Fe,at){circleStream(at,g,r,Fe,Re,Ne)}function w(Re,Ne){return cos$2(Re)*cos$2(Ne)>t}function E(Re){var Ne,Fe,at,ot,Gt;return{lineStart:function(){ot=at=!1,Gt=1},point:function(ht,ke){var ct=[ht,ke],xt,Rt=w(ht,ke),Wt=d?Rt?0:Le(ht,ke):Rt?Le(ht+(ht<0?pi$3:-pi$3),ke):0;if(!Ne&&(ot=at=Rt)&&Re.lineStart(),Rt!==at&&(xt=ye(Ne,ct),(!xt||pointEqual(Ne,xt)||pointEqual(ct,xt))&&(ct[2]=1)),Rt!==at)Gt=0,Rt?(Re.lineStart(),xt=ye(ct,Ne),Re.point(xt[0],xt[1])):(xt=ye(Ne,ct),Re.point(xt[0],xt[1],2),Re.lineEnd()),Ne=xt;else if(v&&Ne&&d^Rt){var Pt;!(Wt&Fe)&&(Pt=ye(ct,Ne,!0))&&(Gt=0,d?(Re.lineStart(),Re.point(Pt[0][0],Pt[0][1]),Re.point(Pt[1][0],Pt[1][1]),Re.lineEnd()):(Re.point(Pt[1][0],Pt[1][1]),Re.lineEnd(),Re.lineStart(),Re.point(Pt[0][0],Pt[0][1],3)))}Rt&&(!Ne||!pointEqual(Ne,ct))&&Re.point(ct[0],ct[1]),Ne=ct,at=Rt,Fe=Wt},lineEnd:function(){at&&Re.lineEnd(),Ne=null},clean:function(){return Gt|(ot&&at)<<1}}}function ye(Re,Ne,Fe){var at=cartesian$1(Re),ot=cartesian$1(Ne),Gt=[1,0,0],ht=cartesianCross$1(at,ot),ke=cartesianDot$1(ht,ht),ct=ht[0],xt=ke-ct*ct;if(!xt)return!Fe&&Re;var Rt=t*ke/xt,Wt=-t*ct/xt,Pt=cartesianCross$1(Gt,ht),Nt=cartesianScale(Gt,Rt),Kt=cartesianScale(ht,Wt);cartesianAddInPlace(Nt,Kt);var Ft=Pt,kt=cartesianDot$1(Nt,Ft),Yt=cartesianDot$1(Ft,Ft),s0=kt*kt-Yt*(cartesianDot$1(Nt,Nt)-1);if(!(s0<0)){var o0=sqrt$2(s0),h0=cartesianScale(Ft,(-kt-o0)/Yt);if(cartesianAddInPlace(h0,Nt),h0=spherical$1(h0),!Fe)return h0;var r0=Re[0],e0=Ne[0],i0=Re[1],Ut=Ne[1],l0;e0<r0&&(l0=r0,r0=e0,e0=l0);var S0=e0-r0,g0=abs(S0-pi$3)<epsilon$2,I0=g0||S0<epsilon$2;if(!g0&&Ut<i0&&(l0=i0,i0=Ut,Ut=l0),I0?g0?i0+Ut>0^h0[1]<(abs(h0[0]-r0)<epsilon$2?i0:Ut):i0<=h0[1]&&h0[1]<=Ut:S0>pi$3^(r0<=h0[0]&&h0[0]<=e0)){var fi=cartesianScale(Ft,(-kt+o0)/Yt);return cartesianAddInPlace(fi,Nt),[h0,spherical$1(fi)]}}}function Le(Re,Ne){var Fe=d?g:pi$3-g,at=0;return Re<-Fe?at|=1:Re>Fe&&(at|=2),Ne<-Fe?at|=4:Ne>Fe&&(at|=8),at}return clip(w,E,C,d?[0,-g]:[-pi$3,g-pi$3])}function clipLine(g,t,r,d,v,C){var w=g[0],E=g[1],ye=t[0],Le=t[1],Re=0,Ne=1,Fe=ye-w,at=Le-E,ot;if(ot=r-w,!(!Fe&&ot>0)){if(ot/=Fe,Fe<0){if(ot<Re)return;ot<Ne&&(Ne=ot)}else if(Fe>0){if(ot>Ne)return;ot>Re&&(Re=ot)}if(ot=v-w,!(!Fe&&ot<0)){if(ot/=Fe,Fe<0){if(ot>Ne)return;ot>Re&&(Re=ot)}else if(Fe>0){if(ot<Re)return;ot<Ne&&(Ne=ot)}if(ot=d-E,!(!at&&ot>0)){if(ot/=at,at<0){if(ot<Re)return;ot<Ne&&(Ne=ot)}else if(at>0){if(ot>Ne)return;ot>Re&&(Re=ot)}if(ot=C-E,!(!at&&ot<0)){if(ot/=at,at<0){if(ot>Ne)return;ot>Re&&(Re=ot)}else if(at>0){if(ot<Re)return;ot<Ne&&(Ne=ot)}return Re>0&&(g[0]=w+Re*Fe,g[1]=E+Re*at),Ne<1&&(t[0]=w+Ne*Fe,t[1]=E+Ne*at),!0}}}}}var clipMax=1e9,clipMin=-clipMax;function clipRectangle(g,t,r,d){function v(Le,Re){return g<=Le&&Le<=r&&t<=Re&&Re<=d}function C(Le,Re,Ne,Fe){var at=0,ot=0;if(Le==null||(at=w(Le,Ne))!==(ot=w(Re,Ne))||ye(Le,Re)<0^Ne>0)do Fe.point(at===0||at===3?g:r,at>1?d:t);while((at=(at+Ne+4)%4)!==ot);else Fe.point(Re[0],Re[1])}function w(Le,Re){return abs(Le[0]-g)<epsilon$2?Re>0?0:3:abs(Le[0]-r)<epsilon$2?Re>0?2:1:abs(Le[1]-t)<epsilon$2?Re>0?1:0:Re>0?3:2}function E(Le,Re){return ye(Le.x,Re.x)}function ye(Le,Re){var Ne=w(Le,1),Fe=w(Re,1);return Ne!==Fe?Ne-Fe:Ne===0?Re[1]-Le[1]:Ne===1?Le[0]-Re[0]:Ne===2?Le[1]-Re[1]:Re[0]-Le[0]}return function(Le){var Re=Le,Ne=clipBuffer(),Fe,at,ot,Gt,ht,ke,ct,xt,Rt,Wt,Pt,Nt={point:Kt,lineStart:s0,lineEnd:o0,polygonStart:kt,polygonEnd:Yt};function Kt(r0,e0){v(r0,e0)&&Re.point(r0,e0)}function Ft(){for(var r0=0,e0=0,i0=at.length;e0<i0;++e0)for(var Ut=at[e0],l0=1,S0=Ut.length,g0=Ut[0],I0,fi,L0=g0[0],K0=g0[1];l0<S0;++l0)I0=L0,fi=K0,g0=Ut[l0],L0=g0[0],K0=g0[1],fi<=d?K0>d&&(L0-I0)*(d-fi)>(K0-fi)*(g-I0)&&++r0:K0<=d&&(L0-I0)*(d-fi)<(K0-fi)*(g-I0)&&--r0;return r0}function kt(){Re=Ne,Fe=[],at=[],Pt=!0}function Yt(){var r0=Ft(),e0=Pt&&r0,i0=(Fe=merge(Fe)).length;(e0||i0)&&(Le.polygonStart(),e0&&(Le.lineStart(),C(null,null,1,Le),Le.lineEnd()),i0&&clipRejoin(Fe,E,r0,C,Le),Le.polygonEnd()),Re=Le,Fe=at=ot=null}function s0(){Nt.point=h0,at&&at.push(ot=[]),Wt=!0,Rt=!1,ct=xt=NaN}function o0(){Fe&&(h0(Gt,ht),ke&&Rt&&Ne.rejoin(),Fe.push(Ne.result())),Nt.point=Kt,Rt&&Re.lineEnd()}function h0(r0,e0){var i0=v(r0,e0);if(at&&ot.push([r0,e0]),Wt)Gt=r0,ht=e0,ke=i0,Wt=!1,i0&&(Re.lineStart(),Re.point(r0,e0));else if(i0&&Rt)Re.point(r0,e0);else{var Ut=[ct=Math.max(clipMin,Math.min(clipMax,ct)),xt=Math.max(clipMin,Math.min(clipMax,xt))],l0=[r0=Math.max(clipMin,Math.min(clipMax,r0)),e0=Math.max(clipMin,Math.min(clipMax,e0))];clipLine(Ut,l0,g,t,r,d)?(Rt||(Re.lineStart(),Re.point(Ut[0],Ut[1])),Re.point(l0[0],l0[1]),i0||Re.lineEnd(),Pt=!1):i0&&(Re.lineStart(),Re.point(r0,e0),Pt=!1)}ct=r0,xt=e0,Rt=i0}return Nt}}var lengthSum,lambda0,sinPhi0,cosPhi0,lengthStream={sphere:noop,point:noop,lineStart:lengthLineStart,lineEnd:noop,polygonStart:noop,polygonEnd:noop};function lengthLineStart(){lengthStream.point=lengthPointFirst,lengthStream.lineEnd=lengthLineEnd}function lengthLineEnd(){lengthStream.point=lengthStream.lineEnd=noop}function lengthPointFirst(g,t){g*=radians$2,t*=radians$2,lambda0=g,sinPhi0=sin$1(t),cosPhi0=cos$2(t),lengthStream.point=lengthPoint}function lengthPoint(g,t){g*=radians$2,t*=radians$2;var r=sin$1(t),d=cos$2(t),v=abs(g-lambda0),C=cos$2(v),w=sin$1(v),E=d*w,ye=cosPhi0*r-sinPhi0*d*C,Le=sinPhi0*r+cosPhi0*d*C;lengthSum.add(atan2$1(sqrt$2(E*E+ye*ye),Le)),lambda0=g,sinPhi0=r,cosPhi0=d}function length(g){return lengthSum=new Adder,geoStream(g,lengthStream),+lengthSum}var coordinates=[null,null],object$1={type:"LineString",coordinates};function $t(g,t){return coordinates[0]=g,coordinates[1]=t,length(object$1)}var containsObjectType={Feature:function(g,t){return containsGeometry(g.geometry,t)},FeatureCollection:function(g,t){for(var r=g.features,d=-1,v=r.length;++d<v;)if(containsGeometry(r[d].geometry,t))return!0;return!1}},containsGeometryType={Sphere:function(){return!0},Point:function(g,t){return containsPoint(g.coordinates,t)},MultiPoint:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)if(containsPoint(r[d],t))return!0;return!1},LineString:function(g,t){return containsLine(g.coordinates,t)},MultiLineString:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)if(containsLine(r[d],t))return!0;return!1},Polygon:function(g,t){return containsPolygon(g.coordinates,t)},MultiPolygon:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)if(containsPolygon(r[d],t))return!0;return!1},GeometryCollection:function(g,t){for(var r=g.geometries,d=-1,v=r.length;++d<v;)if(containsGeometry(r[d],t))return!0;return!1}};function containsGeometry(g,t){return g&&containsGeometryType.hasOwnProperty(g.type)?containsGeometryType[g.type](g,t):!1}function containsPoint(g,t){return $t(g,t)===0}function containsLine(g,t){for(var r,d,v,C=0,w=g.length;C<w;C++){if(d=$t(g[C],t),d===0||C>0&&(v=$t(g[C],g[C-1]),v>0&&r<=v&&d<=v&&(r+d-v)*(1-Math.pow((r-d)/v,2))<epsilon2*v))return!0;r=d}return!1}function containsPolygon(g,t){return!!polygonContains(g.map(ringRadians),pointRadians(t))}function ringRadians(g){return g=g.map(pointRadians),g.pop(),g}function pointRadians(g){return[g[0]*radians$2,g[1]*radians$2]}function Zt(g,t){return(g&&containsObjectType.hasOwnProperty(g.type)?containsObjectType[g.type]:containsGeometry)(g,t)}function qt(g,t){var r=g[0]*radians$2,d=g[1]*radians$2,v=t[0]*radians$2,C=t[1]*radians$2,w=cos$2(d),E=sin$1(d),ye=cos$2(C),Le=sin$1(C),Re=w*cos$2(r),Ne=w*sin$1(r),Fe=ye*cos$2(v),at=ye*sin$1(v),ot=2*asin$1(sqrt$2(haversin(C-d)+w*ye*haversin(v-r))),Gt=sin$1(ot),ht=ot?function(ke){var ct=sin$1(ke*=ot)/Gt,xt=sin$1(ot-ke)/Gt,Rt=xt*Re+ct*Fe,Wt=xt*Ne+ct*at,Pt=xt*E+ct*Le;return[atan2$1(Wt,Rt)*degrees$1,atan2$1(Pt,sqrt$2(Rt*Rt+Wt*Wt))*degrees$1]}:function(){return[r*degrees$1,d*degrees$1]};return ht.distance=ot,ht}const identity$2=g=>g;var x0=1/0,y0=x0,x1=-x0,y1=x1,boundsStream={point:boundsPoint,lineStart:noop,lineEnd:noop,polygonStart:noop,polygonEnd:noop,result:function(){var g=[[x0,y0],[x1,y1]];return x1=y1=-(y0=x0=1/0),g}};function boundsPoint(g,t){g<x0&&(x0=g),g>x1&&(x1=g),t<y0&&(y0=t),t>y1&&(y1=t)}function transformer$1(g){return function(t){var r=new TransformStream;for(var d in g)r[d]=g[d];return r.stream=t,r}}function TransformStream(){}TransformStream.prototype={constructor:TransformStream,point:function(g,t){this.stream.point(g,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function fit(g,t,r){var d=g.clipExtent&&g.clipExtent();return g.scale(150).translate([0,0]),d!=null&&g.clipExtent(null),geoStream(r,g.stream(boundsStream)),t(boundsStream.result()),d!=null&&g.clipExtent(d),g}function fitExtent(g,t,r){return fit(g,function(d){var v=t[1][0]-t[0][0],C=t[1][1]-t[0][1],w=Math.min(v/(d[1][0]-d[0][0]),C/(d[1][1]-d[0][1])),E=+t[0][0]+(v-w*(d[1][0]+d[0][0]))/2,ye=+t[0][1]+(C-w*(d[1][1]+d[0][1]))/2;g.scale(150*w).translate([E,ye])},r)}function fitSize(g,t,r){return fitExtent(g,[[0,0],t],r)}function fitWidth(g,t,r){return fit(g,function(d){var v=+t,C=v/(d[1][0]-d[0][0]),w=(v-C*(d[1][0]+d[0][0]))/2,E=-C*d[0][1];g.scale(150*C).translate([w,E])},r)}function fitHeight(g,t,r){return fit(g,function(d){var v=+t,C=v/(d[1][1]-d[0][1]),w=-C*d[0][0],E=(v-C*(d[1][1]+d[0][1]))/2;g.scale(150*C).translate([w,E])},r)}var maxDepth=16,cosMinDistance=cos$2(30*radians$2);function resample(g,t){return+t?resample$1(g,t):resampleNone(g)}function resampleNone(g){return transformer$1({point:function(t,r){t=g(t,r),this.stream.point(t[0],t[1])}})}function resample$1(g,t){function r(d,v,C,w,E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht){var ke=Le-d,ct=Re-v,xt=ke*ke+ct*ct;if(xt>4*t&&Gt--){var Rt=w+Fe,Wt=E+at,Pt=ye+ot,Nt=sqrt$2(Rt*Rt+Wt*Wt+Pt*Pt),Kt=asin$1(Pt/=Nt),Ft=abs(abs(Pt)-1)<epsilon$2||abs(C-Ne)<epsilon$2?(C+Ne)/2:atan2$1(Wt,Rt),kt=g(Ft,Kt),Yt=kt[0],s0=kt[1],o0=Yt-d,h0=s0-v,r0=ct*o0-ke*h0;(r0*r0/xt>t||abs((ke*o0+ct*h0)/xt-.5)>.3||w*Fe+E*at+ye*ot<cosMinDistance)&&(r(d,v,C,w,E,ye,Yt,s0,Ft,Rt/=Nt,Wt/=Nt,Pt,Gt,ht),ht.point(Yt,s0),r(Yt,s0,Ft,Rt,Wt,Pt,Le,Re,Ne,Fe,at,ot,Gt,ht))}}return function(d){var v,C,w,E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht={point:ke,lineStart:ct,lineEnd:Rt,polygonStart:function(){d.polygonStart(),ht.lineStart=Wt},polygonEnd:function(){d.polygonEnd(),ht.lineStart=ct}};function ke(Kt,Ft){Kt=g(Kt,Ft),d.point(Kt[0],Kt[1])}function ct(){Ne=NaN,ht.point=xt,d.lineStart()}function xt(Kt,Ft){var kt=cartesian$1([Kt,Ft]),Yt=g(Kt,Ft);r(Ne,Fe,Re,at,ot,Gt,Ne=Yt[0],Fe=Yt[1],Re=Kt,at=kt[0],ot=kt[1],Gt=kt[2],maxDepth,d),d.point(Ne,Fe)}function Rt(){ht.point=ke,d.lineEnd()}function Wt(){ct(),ht.point=Pt,ht.lineEnd=Nt}function Pt(Kt,Ft){xt(v=Kt,Ft),C=Ne,w=Fe,E=at,ye=ot,Le=Gt,ht.point=xt}function Nt(){r(Ne,Fe,Re,at,ot,Gt,C,w,v,E,ye,Le,maxDepth,d),ht.lineEnd=Rt,Rt()}return ht}}var transformRadians=transformer$1({point:function(g,t){this.stream.point(g*radians$2,t*radians$2)}});function transformRotate(g){return transformer$1({point:function(t,r){var d=g(t,r);return this.stream.point(d[0],d[1])}})}function scaleTranslate(g,t,r,d,v){function C(w,E){return w*=d,E*=v,[t+g*w,r-g*E]}return C.invert=function(w,E){return[(w-t)/g*d,(r-E)/g*v]},C}function scaleTranslateRotate(g,t,r,d,v,C){if(!C)return scaleTranslate(g,t,r,d,v);var w=cos$2(C),E=sin$1(C),ye=w*g,Le=E*g,Re=w/g,Ne=E/g,Fe=(E*r-w*t)/g,at=(E*t+w*r)/g;function ot(Gt,ht){return Gt*=d,ht*=v,[ye*Gt-Le*ht+t,r-Le*Gt-ye*ht]}return ot.invert=function(Gt,ht){return[d*(Re*Gt-Ne*ht+Fe),v*(at-Ne*Gt-Re*ht)]},ot}function projection(g){return projectionMutator(function(){return g})()}function projectionMutator(g){var t,r=150,d=480,v=250,C=0,w=0,E=0,ye=0,Le=0,Re,Ne=0,Fe=1,at=1,ot=null,Gt=clipAntimeridian,ht=null,ke,ct,xt,Rt=identity$2,Wt=.5,Pt,Nt,Kt,Ft,kt;function Yt(r0){return Kt(r0[0]*radians$2,r0[1]*radians$2)}function s0(r0){return r0=Kt.invert(r0[0],r0[1]),r0&&[r0[0]*degrees$1,r0[1]*degrees$1]}Yt.stream=function(r0){return Ft&&kt===r0?Ft:Ft=transformRadians(transformRotate(Re)(Gt(Pt(Rt(kt=r0)))))},Yt.preclip=function(r0){return arguments.length?(Gt=r0,ot=void 0,h0()):Gt},Yt.postclip=function(r0){return arguments.length?(Rt=r0,ht=ke=ct=xt=null,h0()):Rt},Yt.clipAngle=function(r0){return arguments.length?(Gt=+r0?clipCircle(ot=r0*radians$2):(ot=null,clipAntimeridian),h0()):ot*degrees$1},Yt.clipExtent=function(r0){return arguments.length?(Rt=r0==null?(ht=ke=ct=xt=null,identity$2):clipRectangle(ht=+r0[0][0],ke=+r0[0][1],ct=+r0[1][0],xt=+r0[1][1]),h0()):ht==null?null:[[ht,ke],[ct,xt]]},Yt.scale=function(r0){return arguments.length?(r=+r0,o0()):r},Yt.translate=function(r0){return arguments.length?(d=+r0[0],v=+r0[1],o0()):[d,v]},Yt.center=function(r0){return arguments.length?(C=r0[0]%360*radians$2,w=r0[1]%360*radians$2,o0()):[C*degrees$1,w*degrees$1]},Yt.rotate=function(r0){return arguments.length?(E=r0[0]%360*radians$2,ye=r0[1]%360*radians$2,Le=r0.length>2?r0[2]%360*radians$2:0,o0()):[E*degrees$1,ye*degrees$1,Le*degrees$1]},Yt.angle=function(r0){return arguments.length?(Ne=r0%360*radians$2,o0()):Ne*degrees$1},Yt.reflectX=function(r0){return arguments.length?(Fe=r0?-1:1,o0()):Fe<0},Yt.reflectY=function(r0){return arguments.length?(at=r0?-1:1,o0()):at<0},Yt.precision=function(r0){return arguments.length?(Pt=resample(Nt,Wt=r0*r0),h0()):sqrt$2(Wt)},Yt.fitExtent=function(r0,e0){return fitExtent(Yt,r0,e0)},Yt.fitSize=function(r0,e0){return fitSize(Yt,r0,e0)},Yt.fitWidth=function(r0,e0){return fitWidth(Yt,r0,e0)},Yt.fitHeight=function(r0,e0){return fitHeight(Yt,r0,e0)};function o0(){var r0=scaleTranslateRotate(r,0,0,Fe,at,Ne).apply(null,t(C,w)),e0=scaleTranslateRotate(r,d-r0[0],v-r0[1],Fe,at,Ne);return Re=rotateRadians(E,ye,Le),Nt=compose(t,e0),Kt=compose(Re,Nt),Pt=resample(Nt,Wt),h0()}function h0(){return Ft=kt=null,Yt}return function(){return t=g.apply(this,arguments),Yt.invert=t.invert&&s0,o0()}}function azimuthalInvert(g){return function(t,r){var d=sqrt$2(t*t+r*r),v=g(d),C=sin$1(v),w=cos$2(v);return[atan2$1(t*C,d*w),asin$1(d&&r*C/d)]}}function mercatorRaw(g,t){return[g,log(tan$1((halfPi$1+t)/2))]}mercatorRaw.invert=function(g,t){return[g,2*atan$1(exp(t))-halfPi$1]};function s$1(){return mercatorProjection(mercatorRaw).scale(961/tau$1)}function mercatorProjection(g){var t=projection(g),r=t.center,d=t.scale,v=t.translate,C=t.clipExtent,w=null,E,ye,Le;t.scale=function(Ne){return arguments.length?(d(Ne),Re()):d()},t.translate=function(Ne){return arguments.length?(v(Ne),Re()):v()},t.center=function(Ne){return arguments.length?(r(Ne),Re()):r()},t.clipExtent=function(Ne){return arguments.length?(Ne==null?w=E=ye=Le=null:(w=+Ne[0][0],E=+Ne[0][1],ye=+Ne[1][0],Le=+Ne[1][1]),Re()):w==null?null:[[w,E],[ye,Le]]};function Re(){var Ne=pi$3*d(),Fe=t(geoRotation(t.rotate()).invert([0,0]));return C(w==null?[[Fe[0]-Ne,Fe[1]-Ne],[Fe[0]+Ne,Fe[1]+Ne]]:g===mercatorRaw?[[Math.max(Fe[0]-Ne,w),E],[Math.min(Fe[0]+Ne,ye),Le]]:[[w,Math.max(Fe[1]-Ne,E)],[ye,Math.min(Fe[1]+Ne,Le)]])}return Re()}function equirectangularRaw(g,t){return[g,t]}equirectangularRaw.invert=equirectangularRaw;function i$2(){return projection(equirectangularRaw).scale(152.63)}function stereographicRaw(g,t){var r=cos$2(t),d=1+cos$2(g)*r;return[r*sin$1(g)/d,sin$1(t)/d]}stereographicRaw.invert=azimuthalInvert(function(g){return 2*atan$1(g)});function geoStereographic(){return projection(stereographicRaw).scale(250).clipAngle(142)}var atan=Math.atan,cos$1=Math.cos,tan=Math.tan,pi$2=Math.PI,radians$1=pi$2/180;function sqrt$1(g){return g>0?Math.sqrt(g):0}var faheyK=cos$1(35*radians$1);function faheyRaw(g,t){var r=tan(t/2);return[g*faheyK*sqrt$1(1-r*r),(1+faheyK)*r]}faheyRaw.invert=function(g,t){var r=t/(1+faheyK);return[g&&g/(faheyK*sqrt$1(1-r*r)),2*atan(r)]};function p(){return projection(faheyRaw).scale(137.152)}function i$1(g,t,r=0){const d=(90-t)*Math.PI/180,v=(90-g)*Math.PI/180;return[r*Math.sin(d)*Math.cos(v),r*Math.cos(d),r*Math.sin(d)*Math.sin(v)]}const h=g=>g instanceof Vector3?g:new Vector3(...g),_box$1=new Box3,_vector=new Vector3;class LineSegmentsGeometry extends InstancedBufferGeometry{constructor(){super(),this.isLineSegmentsGeometry=!0,this.type="LineSegmentsGeometry";const t=[-1,2,0,1,2,0,-1,1,0,1,1,0,-1,0,0,1,0,0,-1,-1,0,1,-1,0],r=[-1,2,1,2,-1,1,1,1,-1,-1,1,-1,-1,-2,1,-2],d=[0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5];this.setIndex(d),this.setAttribute("position",new Float32BufferAttribute(t,3)),this.setAttribute("uv",new Float32BufferAttribute(r,2))}applyMatrix4(t){const r=this.attributes.instanceStart,d=this.attributes.instanceEnd;return r!==void 0&&(r.applyMatrix4(t),d.applyMatrix4(t),r.needsUpdate=!0),this.boundingBox!==null&&this.computeBoundingBox(),this.boundingSphere!==null&&this.computeBoundingSphere(),this}setPositions(t){let r;t instanceof Float32Array?r=t:Array.isArray(t)&&(r=new Float32Array(t));const d=new InstancedInterleavedBuffer(r,6,1);return this.setAttribute("instanceStart",new InterleavedBufferAttribute(d,3,0)),this.setAttribute("instanceEnd",new InterleavedBufferAttribute(d,3,3)),this.instanceCount=this.attributes.instanceStart.count,this.computeBoundingBox(),this.computeBoundingSphere(),this}setColors(t){let r;t instanceof Float32Array?r=t:Array.isArray(t)&&(r=new Float32Array(t));const d=new InstancedInterleavedBuffer(r,6,1);return this.setAttribute("instanceColorStart",new InterleavedBufferAttribute(d,3,0)),this.setAttribute("instanceColorEnd",new InterleavedBufferAttribute(d,3,3)),this}fromWireframeGeometry(t){return this.setPositions(t.attributes.position.array),this}fromEdgesGeometry(t){return this.setPositions(t.attributes.position.array),this}fromMesh(t){return this.fromWireframeGeometry(new WireframeGeometry(t.geometry)),this}fromLineSegments(t){const r=t.geometry;return this.setPositions(r.attributes.position.array),this}computeBoundingBox(){this.boundingBox===null&&(this.boundingBox=new Box3);const t=this.attributes.instanceStart,r=this.attributes.instanceEnd;t!==void 0&&r!==void 0&&(this.boundingBox.setFromBufferAttribute(t),_box$1.setFromBufferAttribute(r),this.boundingBox.union(_box$1))}computeBoundingSphere(){this.boundingSphere===null&&(this.boundingSphere=new Sphere$1),this.boundingBox===null&&this.computeBoundingBox();const t=this.attributes.instanceStart,r=this.attributes.instanceEnd;if(t!==void 0&&r!==void 0){const d=this.boundingSphere.center;this.boundingBox.getCenter(d);let v=0;for(let C=0,w=t.count;C<w;C++)_vector.fromBufferAttribute(t,C),v=Math.max(v,d.distanceToSquared(_vector)),_vector.fromBufferAttribute(r,C),v=Math.max(v,d.distanceToSquared(_vector));this.boundingSphere.radius=Math.sqrt(v),isNaN(this.boundingSphere.radius)&&console.error("THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.",this)}}toJSON(){}}function earcut(g,t,r=2){const d=t&&t.length,v=d?t[0]*r:g.length;let C=linkedList(g,0,v,r,!0);const w=[];if(!C||C.next===C.prev)return w;let E,ye,Le;if(d&&(C=eliminateHoles(g,t,C,r)),g.length>80*r){E=1/0,ye=1/0;let Re=-1/0,Ne=-1/0;for(let Fe=r;Fe<v;Fe+=r){const at=g[Fe],ot=g[Fe+1];at<E&&(E=at),ot<ye&&(ye=ot),at>Re&&(Re=at),ot>Ne&&(Ne=ot)}Le=Math.max(Re-E,Ne-ye),Le=Le!==0?32767/Le:0}return earcutLinked(C,w,r,E,ye,Le,0),w}function linkedList(g,t,r,d,v){let C;if(v===signedArea(g,t,r,d)>0)for(let w=t;w<r;w+=d)C=insertNode(w/d|0,g[w],g[w+1],C);else for(let w=r-d;w>=t;w-=d)C=insertNode(w/d|0,g[w],g[w+1],C);return C&&equals(C,C.next)&&(removeNode(C),C=C.next),C}function filterPoints(g,t){if(!g)return g;t||(t=g);let r=g,d;do if(d=!1,!r.steiner&&(equals(r,r.next)||area(r.prev,r,r.next)===0)){if(removeNode(r),r=t=r.prev,r===r.next)break;d=!0}else r=r.next;while(d||r!==t);return t}function earcutLinked(g,t,r,d,v,C,w){if(!g)return;!w&&C&&indexCurve(g,d,v,C);let E=g;for(;g.prev!==g.next;){const ye=g.prev,Le=g.next;if(C?isEarHashed(g,d,v,C):isEar(g)){t.push(ye.i,g.i,Le.i),removeNode(g),g=Le.next,E=Le.next;continue}if(g=Le,g===E){w?w===1?(g=cureLocalIntersections(filterPoints(g),t),earcutLinked(g,t,r,d,v,C,2)):w===2&&splitEarcut(g,t,r,d,v,C):earcutLinked(filterPoints(g),t,r,d,v,C,1);break}}}function isEar(g){const t=g.prev,r=g,d=g.next;if(area(t,r,d)>=0)return!1;const v=t.x,C=r.x,w=d.x,E=t.y,ye=r.y,Le=d.y,Re=v<C?v<w?v:w:C<w?C:w,Ne=E<ye?E<Le?E:Le:ye<Le?ye:Le,Fe=v>C?v>w?v:w:C>w?C:w,at=E>ye?E>Le?E:Le:ye>Le?ye:Le;let ot=d.next;for(;ot!==t;){if(ot.x>=Re&&ot.x<=Fe&&ot.y>=Ne&&ot.y<=at&&pointInTriangle(v,E,C,ye,w,Le,ot.x,ot.y)&&area(ot.prev,ot,ot.next)>=0)return!1;ot=ot.next}return!0}function isEarHashed(g,t,r,d){const v=g.prev,C=g,w=g.next;if(area(v,C,w)>=0)return!1;const E=v.x,ye=C.x,Le=w.x,Re=v.y,Ne=C.y,Fe=w.y,at=E<ye?E<Le?E:Le:ye<Le?ye:Le,ot=Re<Ne?Re<Fe?Re:Fe:Ne<Fe?Ne:Fe,Gt=E>ye?E>Le?E:Le:ye>Le?ye:Le,ht=Re>Ne?Re>Fe?Re:Fe:Ne>Fe?Ne:Fe,ke=zOrder(at,ot,t,r,d),ct=zOrder(Gt,ht,t,r,d);let xt=g.prevZ,Rt=g.nextZ;for(;xt&&xt.z>=ke&&Rt&&Rt.z<=ct;){if(xt.x>=at&&xt.x<=Gt&&xt.y>=ot&&xt.y<=ht&&xt!==v&&xt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,xt.x,xt.y)&&area(xt.prev,xt,xt.next)>=0||(xt=xt.prevZ,Rt.x>=at&&Rt.x<=Gt&&Rt.y>=ot&&Rt.y<=ht&&Rt!==v&&Rt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,Rt.x,Rt.y)&&area(Rt.prev,Rt,Rt.next)>=0))return!1;Rt=Rt.nextZ}for(;xt&&xt.z>=ke;){if(xt.x>=at&&xt.x<=Gt&&xt.y>=ot&&xt.y<=ht&&xt!==v&&xt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,xt.x,xt.y)&&area(xt.prev,xt,xt.next)>=0)return!1;xt=xt.prevZ}for(;Rt&&Rt.z<=ct;){if(Rt.x>=at&&Rt.x<=Gt&&Rt.y>=ot&&Rt.y<=ht&&Rt!==v&&Rt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,Rt.x,Rt.y)&&area(Rt.prev,Rt,Rt.next)>=0)return!1;Rt=Rt.nextZ}return!0}function cureLocalIntersections(g,t){let r=g;do{const d=r.prev,v=r.next.next;!equals(d,v)&&intersects(d,r,r.next,v)&&locallyInside(d,v)&&locallyInside(v,d)&&(t.push(d.i,r.i,v.i),removeNode(r),removeNode(r.next),r=g=v),r=r.next}while(r!==g);return filterPoints(r)}function splitEarcut(g,t,r,d,v,C){let w=g;do{let E=w.next.next;for(;E!==w.prev;){if(w.i!==E.i&&isValidDiagonal(w,E)){let ye=splitPolygon(w,E);w=filterPoints(w,w.next),ye=filterPoints(ye,ye.next),earcutLinked(w,t,r,d,v,C,0),earcutLinked(ye,t,r,d,v,C,0);return}E=E.next}w=w.next}while(w!==g)}function eliminateHoles(g,t,r,d){const v=[];for(let C=0,w=t.length;C<w;C++){const E=t[C]*d,ye=C<w-1?t[C+1]*d:g.length,Le=linkedList(g,E,ye,d,!1);Le===Le.next&&(Le.steiner=!0),v.push(getLeftmost(Le))}v.sort(compareX);for(let C=0;C<v.length;C++)r=eliminateHole(v[C],r);return r}function compareX(g,t){return g.x-t.x}function eliminateHole(g,t){const r=findHoleBridge(g,t);if(!r)return t;const d=splitPolygon(r,g);return filterPoints(d,d.next),filterPoints(r,r.next)}function findHoleBridge(g,t){let r=t;const d=g.x,v=g.y;let C=-1/0,w;do{if(v<=r.y&&v>=r.next.y&&r.next.y!==r.y){const Ne=r.x+(v-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(Ne<=d&&Ne>C&&(C=Ne,w=r.x<r.next.x?r:r.next,Ne===d))return w}r=r.next}while(r!==t);if(!w)return null;const E=w,ye=w.x,Le=w.y;let Re=1/0;r=w;do{if(d>=r.x&&r.x>=ye&&d!==r.x&&pointInTriangle(v<Le?d:C,v,ye,Le,v<Le?C:d,v,r.x,r.y)){const Ne=Math.abs(v-r.y)/(d-r.x);locallyInside(r,g)&&(Ne<Re||Ne===Re&&(r.x>w.x||r.x===w.x&&sectorContainsSector(w,r)))&&(w=r,Re=Ne)}r=r.next}while(r!==E);return w}function sectorContainsSector(g,t){return area(g.prev,g,t.prev)<0&&area(t.next,g,g.next)<0}function indexCurve(g,t,r,d){let v=g;do v.z===0&&(v.z=zOrder(v.x,v.y,t,r,d)),v.prevZ=v.prev,v.nextZ=v.next,v=v.next;while(v!==g);v.prevZ.nextZ=null,v.prevZ=null,sortLinked(v)}function sortLinked(g){let t,r=1;do{let d=g,v;g=null;let C=null;for(t=0;d;){t++;let w=d,E=0;for(let Le=0;Le<r&&(E++,w=w.nextZ,!!w);Le++);let ye=r;for(;E>0||ye>0&&w;)E!==0&&(ye===0||!w||d.z<=w.z)?(v=d,d=d.nextZ,E--):(v=w,w=w.nextZ,ye--),C?C.nextZ=v:g=v,v.prevZ=C,C=v;d=w}C.nextZ=null,r*=2}while(t>1);return g}function zOrder(g,t,r,d,v){return g=(g-r)*v|0,t=(t-d)*v|0,g=(g|g<<8)&16711935,g=(g|g<<4)&252645135,g=(g|g<<2)&858993459,g=(g|g<<1)&1431655765,t=(t|t<<8)&16711935,t=(t|t<<4)&252645135,t=(t|t<<2)&858993459,t=(t|t<<1)&1431655765,g|t<<1}function getLeftmost(g){let t=g,r=g;do(t.x<r.x||t.x===r.x&&t.y<r.y)&&(r=t),t=t.next;while(t!==g);return r}function pointInTriangle(g,t,r,d,v,C,w,E){return(v-w)*(t-E)>=(g-w)*(C-E)&&(g-w)*(d-E)>=(r-w)*(t-E)&&(r-w)*(C-E)>=(v-w)*(d-E)}function isValidDiagonal(g,t){return g.next.i!==t.i&&g.prev.i!==t.i&&!intersectsPolygon(g,t)&&(locallyInside(g,t)&&locallyInside(t,g)&&middleInside(g,t)&&(area(g.prev,g,t.prev)||area(g,t.prev,t))||equals(g,t)&&area(g.prev,g,g.next)>0&&area(t.prev,t,t.next)>0)}function area(g,t,r){return(t.y-g.y)*(r.x-t.x)-(t.x-g.x)*(r.y-t.y)}function equals(g,t){return g.x===t.x&&g.y===t.y}function intersects(g,t,r,d){const v=sign$1(area(g,t,r)),C=sign$1(area(g,t,d)),w=sign$1(area(r,d,g)),E=sign$1(area(r,d,t));return!!(v!==C&&w!==E||v===0&&onSegment(g,r,t)||C===0&&onSegment(g,d,t)||w===0&&onSegment(r,g,d)||E===0&&onSegment(r,t,d))}function onSegment(g,t,r){return t.x<=Math.max(g.x,r.x)&&t.x>=Math.min(g.x,r.x)&&t.y<=Math.max(g.y,r.y)&&t.y>=Math.min(g.y,r.y)}function sign$1(g){return g>0?1:g<0?-1:0}function intersectsPolygon(g,t){let r=g;do{if(r.i!==g.i&&r.next.i!==g.i&&r.i!==t.i&&r.next.i!==t.i&&intersects(r,r.next,g,t))return!0;r=r.next}while(r!==g);return!1}function locallyInside(g,t){return area(g.prev,g,g.next)<0?area(g,t,g.next)>=0&&area(g,g.prev,t)>=0:area(g,t,g.prev)<0||area(g,g.next,t)<0}function middleInside(g,t){let r=g,d=!1;const v=(g.x+t.x)/2,C=(g.y+t.y)/2;do r.y>C!=r.next.y>C&&r.next.y!==r.y&&v<(r.next.x-r.x)*(C-r.y)/(r.next.y-r.y)+r.x&&(d=!d),r=r.next;while(r!==g);return d}function splitPolygon(g,t){const r=createNode(g.i,g.x,g.y),d=createNode(t.i,t.x,t.y),v=g.next,C=t.prev;return g.next=t,t.prev=g,r.next=v,v.prev=r,d.next=r,r.prev=d,C.next=d,d.prev=C,d}function insertNode(g,t,r,d){const v=createNode(g,t,r);return d?(v.next=d.next,v.prev=d,d.next.prev=v,d.next=v):(v.prev=v,v.next=v),v}function removeNode(g){g.next.prev=g.prev,g.prev.next=g.next,g.prevZ&&(g.prevZ.nextZ=g.nextZ),g.nextZ&&(g.nextZ.prevZ=g.prevZ)}function createNode(g,t,r){return{i:g,x:t,y:r,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function signedArea(g,t,r,d){let v=0;for(let C=t,w=r-d;C<r;C+=d)v+=(g[w]-g[C])*(g[C+1]+g[w+1]),w=C;return v}function flatten(g){const t=[],r=[],d=g[0][0].length;let v=0,C=0;for(const w of g){for(const E of w)for(let ye=0;ye<d;ye++)t.push(E[ye]);C&&(v+=C,r.push(v)),C=w.length}return{vertices:t,holes:r,dimensions:d}}function getCoord(g){if(!g)throw new Error("coord is required");if(!Array.isArray(g)){if(g.type==="Feature"&&g.geometry!==null&&g.geometry.type==="Point")return[...g.geometry.coordinates];if(g.type==="Point")return[...g.coordinates]}if(Array.isArray(g)&&g.length>=2&&!Array.isArray(g[0])&&!Array.isArray(g[1]))return[...g];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function getCoords(g){if(Array.isArray(g))return g;if(g.type==="Feature"){if(g.geometry!==null)return g.geometry.coordinates}else if(g.coordinates)return g.coordinates;throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array")}function getGeom(g){return g.type==="Feature"?g.geometry:g}function booleanClockwise(g){const t=getCoords(g);let r=0,d=1,v,C;for(;d<t.length;)v=C||t[0],C=t[d],r+=(C[0]-v[0])*(C[1]+v[1]),d++;return r>0}var turf_boolean_clockwise_default=booleanClockwise;const epsilon$1=11102230246251565e-32,splitter=134217729,resulterrbound=(3+8*epsilon$1)*epsilon$1;function sum(g,t,r,d,v){let C,w,E,ye,Le=t[0],Re=d[0],Ne=0,Fe=0;Re>Le==Re>-Le?(C=Le,Le=t[++Ne]):(C=Re,Re=d[++Fe]);let at=0;if(Ne<g&&Fe<r)for(Re>Le==Re>-Le?(w=Le+C,E=C-(w-Le),Le=t[++Ne]):(w=Re+C,E=C-(w-Re),Re=d[++Fe]),C=w,E!==0&&(v[at++]=E);Ne<g&&Fe<r;)Re>Le==Re>-Le?(w=C+Le,ye=w-C,E=C-(w-ye)+(Le-ye),Le=t[++Ne]):(w=C+Re,ye=w-C,E=C-(w-ye)+(Re-ye),Re=d[++Fe]),C=w,E!==0&&(v[at++]=E);for(;Ne<g;)w=C+Le,ye=w-C,E=C-(w-ye)+(Le-ye),Le=t[++Ne],C=w,E!==0&&(v[at++]=E);for(;Fe<r;)w=C+Re,ye=w-C,E=C-(w-ye)+(Re-ye),Re=d[++Fe],C=w,E!==0&&(v[at++]=E);return(C!==0||at===0)&&(v[at++]=C),at}function estimate(g,t){let r=t[0];for(let d=1;d<g;d++)r+=t[d];return r}function vec(g){return new Float64Array(g)}const ccwerrboundA=(3+16*epsilon$1)*epsilon$1,ccwerrboundB=(2+12*epsilon$1)*epsilon$1,ccwerrboundC=(9+64*epsilon$1)*epsilon$1*epsilon$1,B=vec(4),C1=vec(8),C2=vec(12),D=vec(16),u$1=vec(4);function orient2dadapt(g,t,r,d,v,C,w){let E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht,ke,ct,xt,Rt,Wt,Pt,Nt,Kt;const Ft=g-v,kt=r-v,Yt=t-C,s0=d-C;Rt=Ft*s0,Fe=splitter*Ft,at=Fe-(Fe-Ft),ot=Ft-at,Fe=splitter*s0,Gt=Fe-(Fe-s0),ht=s0-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=Yt*kt,Fe=splitter*Yt,at=Fe-(Fe-Yt),ot=Yt-at,Fe=splitter*kt,Gt=Fe-(Fe-kt),ht=kt-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,B[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,B[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,B[2]=ct-(Kt-Ne)+(ke-Ne),B[3]=Kt;let o0=estimate(4,B),h0=ccwerrboundB*w;if(o0>=h0||-o0>=h0||(Ne=g-Ft,E=g-(Ft+Ne)+(Ne-v),Ne=r-kt,Le=r-(kt+Ne)+(Ne-v),Ne=t-Yt,ye=t-(Yt+Ne)+(Ne-C),Ne=d-s0,Re=d-(s0+Ne)+(Ne-C),E===0&&ye===0&&Le===0&&Re===0)||(h0=ccwerrboundC*w+resulterrbound*Math.abs(o0),o0+=Ft*Re+s0*E-(Yt*Le+kt*ye),o0>=h0||-o0>=h0))return o0;Rt=E*s0,Fe=splitter*E,at=Fe-(Fe-E),ot=E-at,Fe=splitter*s0,Gt=Fe-(Fe-s0),ht=s0-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=ye*kt,Fe=splitter*ye,at=Fe-(Fe-ye),ot=ye-at,Fe=splitter*kt,Gt=Fe-(Fe-kt),ht=kt-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,u$1[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,u$1[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,u$1[2]=ct-(Kt-Ne)+(ke-Ne),u$1[3]=Kt;const r0=sum(4,B,4,u$1,C1);Rt=Ft*Re,Fe=splitter*Ft,at=Fe-(Fe-Ft),ot=Ft-at,Fe=splitter*Re,Gt=Fe-(Fe-Re),ht=Re-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=Yt*Le,Fe=splitter*Yt,at=Fe-(Fe-Yt),ot=Yt-at,Fe=splitter*Le,Gt=Fe-(Fe-Le),ht=Le-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,u$1[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,u$1[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,u$1[2]=ct-(Kt-Ne)+(ke-Ne),u$1[3]=Kt;const e0=sum(r0,C1,4,u$1,C2);Rt=E*Re,Fe=splitter*E,at=Fe-(Fe-E),ot=E-at,Fe=splitter*Re,Gt=Fe-(Fe-Re),ht=Re-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=ye*Le,Fe=splitter*ye,at=Fe-(Fe-ye),ot=ye-at,Fe=splitter*Le,Gt=Fe-(Fe-Le),ht=Le-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,u$1[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,u$1[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,u$1[2]=ct-(Kt-Ne)+(ke-Ne),u$1[3]=Kt;const i0=sum(e0,C2,4,u$1,D);return D[i0-1]}function orient2d(g,t,r,d,v,C){const w=(t-C)*(r-v),E=(g-v)*(d-C),ye=w-E,Le=Math.abs(w+E);return Math.abs(ye)>=ccwerrboundA*Le?ye:-orient2dadapt(g,t,r,d,v,C,Le)}const EPSILON$2=Math.pow(2,-52),EDGE_STACK=new Uint32Array(512);class Delaunator{static from(t,r=defaultGetX,d=defaultGetY){const v=t.length,C=new Float64Array(v*2);for(let w=0;w<v;w++){const E=t[w];C[2*w]=r(E),C[2*w+1]=d(E)}return new Delaunator(C)}constructor(t){const r=t.length>>1;if(r>0&&typeof t[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=t;const d=Math.max(2*r-5,0);this._triangles=new Uint32Array(d*3),this._halfedges=new Int32Array(d*3),this._hashSize=Math.ceil(Math.sqrt(r)),this._hullPrev=new Uint32Array(r),this._hullNext=new Uint32Array(r),this._hullTri=new Uint32Array(r),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(r),this._dists=new Float64Array(r),this.update()}update(){const{coords:t,_hullPrev:r,_hullNext:d,_hullTri:v,_hullHash:C}=this,w=t.length>>1;let E=1/0,ye=1/0,Le=-1/0,Re=-1/0;for(let kt=0;kt<w;kt++){const Yt=t[2*kt],s0=t[2*kt+1];Yt<E&&(E=Yt),s0<ye&&(ye=s0),Yt>Le&&(Le=Yt),s0>Re&&(Re=s0),this._ids[kt]=kt}const Ne=(E+Le)/2,Fe=(ye+Re)/2;let at=1/0,ot,Gt,ht;for(let kt=0;kt<w;kt++){const Yt=dist(Ne,Fe,t[2*kt],t[2*kt+1]);Yt<at&&(ot=kt,at=Yt)}const ke=t[2*ot],ct=t[2*ot+1];at=1/0;for(let kt=0;kt<w;kt++){if(kt===ot)continue;const Yt=dist(ke,ct,t[2*kt],t[2*kt+1]);Yt<at&&Yt>0&&(Gt=kt,at=Yt)}let xt=t[2*Gt],Rt=t[2*Gt+1],Wt=1/0;for(let kt=0;kt<w;kt++){if(kt===ot||kt===Gt)continue;const Yt=circumradius(ke,ct,xt,Rt,t[2*kt],t[2*kt+1]);Yt<Wt&&(ht=kt,Wt=Yt)}let Pt=t[2*ht],Nt=t[2*ht+1];if(Wt===1/0){for(let s0=0;s0<w;s0++)this._dists[s0]=t[2*s0]-t[0]||t[2*s0+1]-t[1];quicksort(this._ids,this._dists,0,w-1);const kt=new Uint32Array(w);let Yt=0;for(let s0=0,o0=-1/0;s0<w;s0++){const h0=this._ids[s0];this._dists[h0]>o0&&(kt[Yt++]=h0,o0=this._dists[h0])}this.hull=kt.subarray(0,Yt),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(orient2d(ke,ct,xt,Rt,Pt,Nt)<0){const kt=Gt,Yt=xt,s0=Rt;Gt=ht,xt=Pt,Rt=Nt,ht=kt,Pt=Yt,Nt=s0}const Kt=circumcenter(ke,ct,xt,Rt,Pt,Nt);this._cx=Kt.x,this._cy=Kt.y;for(let kt=0;kt<w;kt++)this._dists[kt]=dist(t[2*kt],t[2*kt+1],Kt.x,Kt.y);quicksort(this._ids,this._dists,0,w-1),this._hullStart=ot;let Ft=3;d[ot]=r[ht]=Gt,d[Gt]=r[ot]=ht,d[ht]=r[Gt]=ot,v[ot]=0,v[Gt]=1,v[ht]=2,C.fill(-1),C[this._hashKey(ke,ct)]=ot,C[this._hashKey(xt,Rt)]=Gt,C[this._hashKey(Pt,Nt)]=ht,this.trianglesLen=0,this._addTriangle(ot,Gt,ht,-1,-1,-1);for(let kt=0,Yt,s0;kt<this._ids.length;kt++){const o0=this._ids[kt],h0=t[2*o0],r0=t[2*o0+1];if(kt>0&&Math.abs(h0-Yt)<=EPSILON$2&&Math.abs(r0-s0)<=EPSILON$2||(Yt=h0,s0=r0,o0===ot||o0===Gt||o0===ht))continue;let e0=0;for(let g0=0,I0=this._hashKey(h0,r0);g0<this._hashSize&&(e0=C[(I0+g0)%this._hashSize],!(e0!==-1&&e0!==d[e0]));g0++);e0=r[e0];let i0=e0,Ut;for(;Ut=d[i0],orient2d(h0,r0,t[2*i0],t[2*i0+1],t[2*Ut],t[2*Ut+1])>=0;)if(i0=Ut,i0===e0){i0=-1;break}if(i0===-1)continue;let l0=this._addTriangle(i0,o0,d[i0],-1,-1,v[i0]);v[o0]=this._legalize(l0+2),v[i0]=l0,Ft++;let S0=d[i0];for(;Ut=d[S0],orient2d(h0,r0,t[2*S0],t[2*S0+1],t[2*Ut],t[2*Ut+1])<0;)l0=this._addTriangle(S0,o0,Ut,v[o0],-1,v[S0]),v[o0]=this._legalize(l0+2),d[S0]=S0,Ft--,S0=Ut;if(i0===e0)for(;Ut=r[i0],orient2d(h0,r0,t[2*Ut],t[2*Ut+1],t[2*i0],t[2*i0+1])<0;)l0=this._addTriangle(Ut,o0,i0,-1,v[i0],v[Ut]),this._legalize(l0+2),v[Ut]=l0,d[i0]=i0,Ft--,i0=Ut;this._hullStart=r[o0]=i0,d[i0]=r[S0]=o0,d[o0]=S0,C[this._hashKey(h0,r0)]=o0,C[this._hashKey(t[2*i0],t[2*i0+1])]=i0}this.hull=new Uint32Array(Ft);for(let kt=0,Yt=this._hullStart;kt<Ft;kt++)this.hull[kt]=Yt,Yt=d[Yt];this.triangles=this._triangles.subarray(0,this.trianglesLen),this.halfedges=this._halfedges.subarray(0,this.trianglesLen)}_hashKey(t,r){return Math.floor(pseudoAngle(t-this._cx,r-this._cy)*this._hashSize)%this._hashSize}_legalize(t){const{_triangles:r,_halfedges:d,coords:v}=this;let C=0,w=0;for(;;){const E=d[t],ye=t-t%3;if(w=ye+(t+2)%3,E===-1){if(C===0)break;t=EDGE_STACK[--C];continue}const Le=E-E%3,Re=ye+(t+1)%3,Ne=Le+(E+2)%3,Fe=r[w],at=r[t],ot=r[Re],Gt=r[Ne];if(inCircle(v[2*Fe],v[2*Fe+1],v[2*at],v[2*at+1],v[2*ot],v[2*ot+1],v[2*Gt],v[2*Gt+1])){r[t]=Gt,r[E]=Fe;const ke=d[Ne];if(ke===-1){let xt=this._hullStart;do{if(this._hullTri[xt]===Ne){this._hullTri[xt]=t;break}xt=this._hullPrev[xt]}while(xt!==this._hullStart)}this._link(t,ke),this._link(E,d[w]),this._link(w,Ne);const ct=Le+(E+1)%3;C<EDGE_STACK.length&&(EDGE_STACK[C++]=ct)}else{if(C===0)break;t=EDGE_STACK[--C]}}return w}_link(t,r){this._halfedges[t]=r,r!==-1&&(this._halfedges[r]=t)}_addTriangle(t,r,d,v,C,w){const E=this.trianglesLen;return this._triangles[E]=t,this._triangles[E+1]=r,this._triangles[E+2]=d,this._link(E,v),this._link(E+1,C),this._link(E+2,w),this.trianglesLen+=3,E}}function pseudoAngle(g,t){const r=g/(Math.abs(g)+Math.abs(t));return(t>0?3-r:1+r)/4}function dist(g,t,r,d){const v=g-r,C=t-d;return v*v+C*C}function inCircle(g,t,r,d,v,C,w,E){const ye=g-w,Le=t-E,Re=r-w,Ne=d-E,Fe=v-w,at=C-E,ot=ye*ye+Le*Le,Gt=Re*Re+Ne*Ne,ht=Fe*Fe+at*at;return ye*(Ne*ht-Gt*at)-Le*(Re*ht-Gt*Fe)+ot*(Re*at-Ne*Fe)<0}function circumradius(g,t,r,d,v,C){const w=r-g,E=d-t,ye=v-g,Le=C-t,Re=w*w+E*E,Ne=ye*ye+Le*Le,Fe=.5/(w*Le-E*ye),at=(Le*Re-E*Ne)*Fe,ot=(w*Ne-ye*Re)*Fe;return at*at+ot*ot}function circumcenter(g,t,r,d,v,C){const w=r-g,E=d-t,ye=v-g,Le=C-t,Re=w*w+E*E,Ne=ye*ye+Le*Le,Fe=.5/(w*Le-E*ye),at=g+(Le*Re-E*Ne)*Fe,ot=t+(w*Ne-ye*Re)*Fe;return{x:at,y:ot}}function quicksort(g,t,r,d){if(d-r<=20)for(let v=r+1;v<=d;v++){const C=g[v],w=t[C];let E=v-1;for(;E>=r&&t[g[E]]>w;)g[E+1]=g[E--];g[E+1]=C}else{const v=r+d>>1;let C=r+1,w=d;swap(g,v,C),t[g[r]]>t[g[d]]&&swap(g,r,d),t[g[C]]>t[g[d]]&&swap(g,C,d),t[g[r]]>t[g[C]]&&swap(g,r,C);const E=g[C],ye=t[E];for(;;){do C++;while(t[g[C]]<ye);do w--;while(t[g[w]]>ye);if(w<C)break;swap(g,C,w)}g[r+1]=g[w],g[w]=E,d-C+1>=w-r?(quicksort(g,t,C,d),quicksort(g,t,r,w-1)):(quicksort(g,t,r,w-1),quicksort(g,t,C,d))}}function swap(g,t,r){const d=g[t];g[t]=g[r],g[r]=d}function defaultGetX(g){return g[0]}function defaultGetY(g){return g[1]}function pointInPolygon(g,t){var r=0,d=0,v=0,C=0,w=0,E=0,ye=0,Le=0,Re=null,Ne=null,Fe=g[0],at=g[1],ot=t.length;for(r;r<ot;r++){d=0;var Gt=t[r].length-1,ht=t[r];if(Re=ht[0],Re[0]!==ht[Gt][0]&&Re[1]!==ht[Gt][1])throw new Error("First and last coordinates in a ring must be the same");for(w=Re[0]-Fe,E=Re[1]-at,d;d<Gt;d++){if(Ne=ht[d+1],Le=Ne[1]-at,E<0&&Le<0||E>0&&Le>0){Re=Ne,E=Le,w=Re[0]-Fe;continue}if(ye=Ne[0]-g[0],Le>0&&E<=0){if(C=w*Le-ye*E,C>0)v=v+1;else if(C===0)return 0}else if(E>0&&Le<=0){if(C=w*Le-ye*E,C<0)v=v+1;else if(C===0)return 0}else if(Le===0&&E<0){if(C=w*Le-ye*E,C===0)return 0}else if(E===0&&Le<0){if(C=w*Le-ye*E,C===0)return 0}else if(E===0&&Le===0){if(ye<=0&&w>=0)return 0;if(w<=0&&ye>=0)return 0}Re=Ne,E=Le,w=ye}}return v%2!==0}function booleanPointInPolygon(g,t,r={}){if(!g)throw new Error("point is required");if(!t)throw new Error("polygon is required");const d=getCoord(g),v=getGeom(t),C=v.type,w=t.bbox;let E=v.coordinates;if(w&&inBBox(d,w)===!1)return!1;C==="Polygon"&&(E=[E]);let ye=!1;for(var Le=0;Le<E.length;++Le){const Re=pointInPolygon(d,E[Le]);if(Re===0)return!r.ignoreBoundary;Re&&(ye=!0)}return ye}function inBBox(g,t){return t[0]<=g[0]&&t[1]<=g[1]&&t[2]>=g[0]&&t[3]>=g[1]}var turf_boolean_point_in_polygon_default=booleanPointInPolygon;const epsilon=1e-6;class Path{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._=""}moveTo(t,r){this._+=`M${this._x0=this._x1=+t},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")}lineTo(t,r){this._+=`L${this._x1=+t},${this._y1=+r}`}arc(t,r,d){t=+t,r=+r,d=+d;const v=t+d,C=r;if(d<0)throw new Error("negative radius");this._x1===null?this._+=`M${v},${C}`:(Math.abs(this._x1-v)>epsilon||Math.abs(this._y1-C)>epsilon)&&(this._+="L"+v+","+C),d&&(this._+=`A${d},${d},0,1,1,${t-d},${r}A${d},${d},0,1,1,${this._x1=v},${this._y1=C}`)}rect(t,r,d,v){this._+=`M${this._x0=this._x1=+t},${this._y0=this._y1=+r}h${+d}v${+v}h${-d}Z`}value(){return this._||null}}class Polygon{constructor(){this._=[]}moveTo(t,r){this._.push([t,r])}closePath(){this._.push(this._[0].slice())}lineTo(t,r){this._.push([t,r])}value(){return this._.length?this._:null}}class Voronoi{constructor(t,[r,d,v,C]=[0,0,960,500]){if(!((v=+v)>=(r=+r))||!((C=+C)>=(d=+d)))throw new Error("invalid bounds");this.delaunay=t,this._circumcenters=new Float64Array(t.points.length*2),this.vectors=new Float64Array(t.points.length*2),this.xmax=v,this.xmin=r,this.ymax=C,this.ymin=d,this._init()}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:t,hull:r,triangles:d},vectors:v}=this;let C,w;const E=this.circumcenters=this._circumcenters.subarray(0,d.length/3*2);for(let Gt=0,ht=0,ke=d.length,ct,xt;Gt<ke;Gt+=3,ht+=2){const Rt=d[Gt]*2,Wt=d[Gt+1]*2,Pt=d[Gt+2]*2,Nt=t[Rt],Kt=t[Rt+1],Ft=t[Wt],kt=t[Wt+1],Yt=t[Pt],s0=t[Pt+1],o0=Ft-Nt,h0=kt-Kt,r0=Yt-Nt,e0=s0-Kt,i0=(o0*e0-h0*r0)*2;if(Math.abs(i0)<1e-9){if(C===void 0){C=w=0;for(const l0 of r)C+=t[l0*2],w+=t[l0*2+1];C/=r.length,w/=r.length}const Ut=1e9*Math.sign((C-Nt)*e0-(w-Kt)*r0);ct=(Nt+Yt)/2-Ut*e0,xt=(Kt+s0)/2+Ut*r0}else{const Ut=1/i0,l0=o0*o0+h0*h0,S0=r0*r0+e0*e0;ct=Nt+(e0*l0-h0*S0)*Ut,xt=Kt+(o0*S0-r0*l0)*Ut}E[ht]=ct,E[ht+1]=xt}let ye=r[r.length-1],Le,Re=ye*4,Ne,Fe=t[2*ye],at,ot=t[2*ye+1];v.fill(0);for(let Gt=0;Gt<r.length;++Gt)ye=r[Gt],Le=Re,Ne=Fe,at=ot,Re=ye*4,Fe=t[2*ye],ot=t[2*ye+1],v[Le+2]=v[Re]=at-ot,v[Le+3]=v[Re+1]=Fe-Ne}render(t){const r=t==null?t=new Path:void 0,{delaunay:{halfedges:d,inedges:v,hull:C},circumcenters:w,vectors:E}=this;if(C.length<=1)return null;for(let Re=0,Ne=d.length;Re<Ne;++Re){const Fe=d[Re];if(Fe<Re)continue;const at=Math.floor(Re/3)*2,ot=Math.floor(Fe/3)*2,Gt=w[at],ht=w[at+1],ke=w[ot],ct=w[ot+1];this._renderSegment(Gt,ht,ke,ct,t)}let ye,Le=C[C.length-1];for(let Re=0;Re<C.length;++Re){ye=Le,Le=C[Re];const Ne=Math.floor(v[Le]/3)*2,Fe=w[Ne],at=w[Ne+1],ot=ye*4,Gt=this._project(Fe,at,E[ot+2],E[ot+3]);Gt&&this._renderSegment(Fe,at,Gt[0],Gt[1],t)}return r&&r.value()}renderBounds(t){const r=t==null?t=new Path:void 0;return t.rect(this.xmin,this.ymin,this.xmax-this.xmin,this.ymax-this.ymin),r&&r.value()}renderCell(t,r){const d=r==null?r=new Path:void 0,v=this._clip(t);if(v===null||!v.length)return;r.moveTo(v[0],v[1]);let C=v.length;for(;v[0]===v[C-2]&&v[1]===v[C-1]&&C>1;)C-=2;for(let w=2;w<C;w+=2)(v[w]!==v[w-2]||v[w+1]!==v[w-1])&&r.lineTo(v[w],v[w+1]);return r.closePath(),d&&d.value()}*cellPolygons(){const{delaunay:{points:t}}=this;for(let r=0,d=t.length/2;r<d;++r){const v=this.cellPolygon(r);v&&(v.index=r,yield v)}}cellPolygon(t){const r=new Polygon;return this.renderCell(t,r),r.value()}_renderSegment(t,r,d,v,C){let w;const E=this._regioncode(t,r),ye=this._regioncode(d,v);E===0&&ye===0?(C.moveTo(t,r),C.lineTo(d,v)):(w=this._clipSegment(t,r,d,v,E,ye))&&(C.moveTo(w[0],w[1]),C.lineTo(w[2],w[3]))}contains(t,r,d){return r=+r,r!==r||(d=+d,d!==d)?!1:this.delaunay._step(t,r,d)===t}*neighbors(t){const r=this._clip(t);if(r)for(const d of this.delaunay.neighbors(t)){const v=this._clip(d);if(v){e:for(let C=0,w=r.length;C<w;C+=2)for(let E=0,ye=v.length;E<ye;E+=2)if(r[C]===v[E]&&r[C+1]===v[E+1]&&r[(C+2)%w]===v[(E+ye-2)%ye]&&r[(C+3)%w]===v[(E+ye-1)%ye]){yield d;break e}}}}_cell(t){const{circumcenters:r,delaunay:{inedges:d,halfedges:v,triangles:C}}=this,w=d[t];if(w===-1)return null;const E=[];let ye=w;do{const Le=Math.floor(ye/3);if(E.push(r[Le*2],r[Le*2+1]),ye=ye%3===2?ye-2:ye+1,C[ye]!==t)break;ye=v[ye]}while(ye!==w&&ye!==-1);return E}_clip(t){if(t===0&&this.delaunay.hull.length===1)return[this.xmax,this.ymin,this.xmax,this.ymax,this.xmin,this.ymax,this.xmin,this.ymin];const r=this._cell(t);if(r===null)return null;const{vectors:d}=this,v=t*4;return this._simplify(d[v]||d[v+1]?this._clipInfinite(t,r,d[v],d[v+1],d[v+2],d[v+3]):this._clipFinite(t,r))}_clipFinite(t,r){const d=r.length;let v=null,C,w,E=r[d-2],ye=r[d-1],Le,Re=this._regioncode(E,ye),Ne,Fe=0;for(let at=0;at<d;at+=2)if(C=E,w=ye,E=r[at],ye=r[at+1],Le=Re,Re=this._regioncode(E,ye),Le===0&&Re===0)Ne=Fe,Fe=0,v?v.push(E,ye):v=[E,ye];else{let ot,Gt,ht,ke,ct;if(Le===0){if((ot=this._clipSegment(C,w,E,ye,Le,Re))===null)continue;[Gt,ht,ke,ct]=ot}else{if((ot=this._clipSegment(E,ye,C,w,Re,Le))===null)continue;[ke,ct,Gt,ht]=ot,Ne=Fe,Fe=this._edgecode(Gt,ht),Ne&&Fe&&this._edge(t,Ne,Fe,v,v.length),v?v.push(Gt,ht):v=[Gt,ht]}Ne=Fe,Fe=this._edgecode(ke,ct),Ne&&Fe&&this._edge(t,Ne,Fe,v,v.length),v?v.push(ke,ct):v=[ke,ct]}if(v)Ne=Fe,Fe=this._edgecode(v[0],v[1]),Ne&&Fe&&this._edge(t,Ne,Fe,v,v.length);else if(this.contains(t,(this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2))return[this.xmax,this.ymin,this.xmax,this.ymax,this.xmin,this.ymax,this.xmin,this.ymin];return v}_clipSegment(t,r,d,v,C,w){const E=C<w;for(E&&([t,r,d,v,C,w]=[d,v,t,r,w,C]);;){if(C===0&&w===0)return E?[d,v,t,r]:[t,r,d,v];if(C&w)return null;let ye,Le,Re=C||w;Re&8?(ye=t+(d-t)*(this.ymax-r)/(v-r),Le=this.ymax):Re&4?(ye=t+(d-t)*(this.ymin-r)/(v-r),Le=this.ymin):Re&2?(Le=r+(v-r)*(this.xmax-t)/(d-t),ye=this.xmax):(Le=r+(v-r)*(this.xmin-t)/(d-t),ye=this.xmin),C?(t=ye,r=Le,C=this._regioncode(t,r)):(d=ye,v=Le,w=this._regioncode(d,v))}}_clipInfinite(t,r,d,v,C,w){let E=Array.from(r),ye;if((ye=this._project(E[0],E[1],d,v))&&E.unshift(ye[0],ye[1]),(ye=this._project(E[E.length-2],E[E.length-1],C,w))&&E.push(ye[0],ye[1]),E=this._clipFinite(t,E))for(let Le=0,Re=E.length,Ne,Fe=this._edgecode(E[Re-2],E[Re-1]);Le<Re;Le+=2)Ne=Fe,Fe=this._edgecode(E[Le],E[Le+1]),Ne&&Fe&&(Le=this._edge(t,Ne,Fe,E,Le),Re=E.length);else this.contains(t,(this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)&&(E=[this.xmin,this.ymin,this.xmax,this.ymin,this.xmax,this.ymax,this.xmin,this.ymax]);return E}_edge(t,r,d,v,C){for(;r!==d;){let w,E;switch(r){case 5:r=4;continue;case 4:r=6,w=this.xmax,E=this.ymin;break;case 6:r=2;continue;case 2:r=10,w=this.xmax,E=this.ymax;break;case 10:r=8;continue;case 8:r=9,w=this.xmin,E=this.ymax;break;case 9:r=1;continue;case 1:r=5,w=this.xmin,E=this.ymin;break}(v[C]!==w||v[C+1]!==E)&&this.contains(t,w,E)&&(v.splice(C,0,w,E),C+=2)}return C}_project(t,r,d,v){let C=1/0,w,E,ye;if(v<0){if(r<=this.ymin)return null;(w=(this.ymin-r)/v)<C&&(ye=this.ymin,E=t+(C=w)*d)}else if(v>0){if(r>=this.ymax)return null;(w=(this.ymax-r)/v)<C&&(ye=this.ymax,E=t+(C=w)*d)}if(d>0){if(t>=this.xmax)return null;(w=(this.xmax-t)/d)<C&&(E=this.xmax,ye=r+(C=w)*v)}else if(d<0){if(t<=this.xmin)return null;(w=(this.xmin-t)/d)<C&&(E=this.xmin,ye=r+(C=w)*v)}return[E,ye]}_edgecode(t,r){return(t===this.xmin?1:t===this.xmax?2:0)|(r===this.ymin?4:r===this.ymax?8:0)}_regioncode(t,r){return(t<this.xmin?1:t>this.xmax?2:0)|(r<this.ymin?4:r>this.ymax?8:0)}_simplify(t){if(t&&t.length>4){for(let r=0;r<t.length;r+=2){const d=(r+2)%t.length,v=(r+4)%t.length;(t[r]===t[d]&&t[d]===t[v]||t[r+1]===t[d+1]&&t[d+1]===t[v+1])&&(t.splice(d,2),r-=2)}t.length||(t=null)}return t}}const tau=2*Math.PI,pow=Math.pow;function pointX(g){return g[0]}function pointY(g){return g[1]}function collinear(g){const{triangles:t,coords:r}=g;for(let d=0;d<t.length;d+=3){const v=2*t[d],C=2*t[d+1],w=2*t[d+2];if((r[w]-r[v])*(r[C+1]-r[v+1])-(r[C]-r[v])*(r[w+1]-r[v+1])>1e-10)return!1}return!0}function jitter(g,t,r){return[g+Math.sin(g+t)*r,t+Math.cos(g-t)*r]}class Delaunay{static from(t,r=pointX,d=pointY,v){return new Delaunay("length"in t?flatArray(t,r,d,v):Float64Array.from(flatIterable(t,r,d,v)))}constructor(t){this._delaunator=new Delaunator(t),this.inedges=new Int32Array(t.length/2),this._hullIndex=new Int32Array(t.length/2),this.points=this._delaunator.coords,this._init()}update(){return this._delaunator.update(),this._init(),this}_init(){const t=this._delaunator,r=this.points;if(t.hull&&t.hull.length>2&&collinear(t)){this.collinear=Int32Array.from({length:r.length/2},(Fe,at)=>at).sort((Fe,at)=>r[2*Fe]-r[2*at]||r[2*Fe+1]-r[2*at+1]);const ye=this.collinear[0],Le=this.collinear[this.collinear.length-1],Re=[r[2*ye],r[2*ye+1],r[2*Le],r[2*Le+1]],Ne=1e-8*Math.hypot(Re[3]-Re[1],Re[2]-Re[0]);for(let Fe=0,at=r.length/2;Fe<at;++Fe){const ot=jitter(r[2*Fe],r[2*Fe+1],Ne);r[2*Fe]=ot[0],r[2*Fe+1]=ot[1]}this._delaunator=new Delaunator(r)}else delete this.collinear;const d=this.halfedges=this._delaunator.halfedges,v=this.hull=this._delaunator.hull,C=this.triangles=this._delaunator.triangles,w=this.inedges.fill(-1),E=this._hullIndex.fill(-1);for(let ye=0,Le=d.length;ye<Le;++ye){const Re=C[ye%3===2?ye-2:ye+1];(d[ye]===-1||w[Re]===-1)&&(w[Re]=ye)}for(let ye=0,Le=v.length;ye<Le;++ye)E[v[ye]]=ye;v.length<=2&&v.length>0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=v[0],w[v[0]]=1,v.length===2&&(w[v[1]]=0,this.triangles[1]=v[1],this.triangles[2]=v[1]))}voronoi(t){return new Voronoi(this,t)}*neighbors(t){const{inedges:r,hull:d,_hullIndex:v,halfedges:C,triangles:w,collinear:E}=this;if(E){const Ne=E.indexOf(t);Ne>0&&(yield E[Ne-1]),Ne<E.length-1&&(yield E[Ne+1]);return}const ye=r[t];if(ye===-1)return;let Le=ye,Re=-1;do{if(yield Re=w[Le],Le=Le%3===2?Le-2:Le+1,w[Le]!==t)return;if(Le=C[Le],Le===-1){const Ne=d[(v[t]+1)%d.length];Ne!==Re&&(yield Ne);return}}while(Le!==ye)}find(t,r,d=0){if(t=+t,t!==t||(r=+r,r!==r))return-1;const v=d;let C;for(;(C=this._step(d,t,r))>=0&&C!==d&&C!==v;)d=C;return C}_step(t,r,d){const{inedges:v,hull:C,_hullIndex:w,halfedges:E,triangles:ye,points:Le}=this;if(v[t]===-1||!Le.length)return(t+1)%(Le.length>>1);let Re=t,Ne=pow(r-Le[t*2],2)+pow(d-Le[t*2+1],2);const Fe=v[t];let at=Fe;do{let ot=ye[at];const Gt=pow(r-Le[ot*2],2)+pow(d-Le[ot*2+1],2);if(Gt<Ne&&(Ne=Gt,Re=ot),at=at%3===2?at-2:at+1,ye[at]!==t)break;if(at=E[at],at===-1){if(at=C[(w[t]+1)%C.length],at!==ot&&pow(r-Le[at*2],2)+pow(d-Le[at*2+1],2)<Ne)return at;break}}while(at!==Fe);return Re}render(t){const r=t==null?t=new Path:void 0,{points:d,halfedges:v,triangles:C}=this;for(let w=0,E=v.length;w<E;++w){const ye=v[w];if(ye<w)continue;const Le=C[w]*2,Re=C[ye]*2;t.moveTo(d[Le],d[Le+1]),t.lineTo(d[Re],d[Re+1])}return this.renderHull(t),r&&r.value()}renderPoints(t,r){r===void 0&&(!t||typeof t.moveTo!="function")&&(r=t,t=null),r=r==null?2:+r;const d=t==null?t=new Path:void 0,{points:v}=this;for(let C=0,w=v.length;C<w;C+=2){const E=v[C],ye=v[C+1];t.moveTo(E+r,ye),t.arc(E,ye,r,0,tau)}return d&&d.value()}renderHull(t){const r=t==null?t=new Path:void 0,{hull:d,points:v}=this,C=d[0]*2,w=d.length;t.moveTo(v[C],v[C+1]);for(let E=1;E<w;++E){const ye=2*d[E];t.lineTo(v[ye],v[ye+1])}return t.closePath(),r&&r.value()}hullPolygon(){const t=new Polygon;return this.renderHull(t),t.value()}renderTriangle(t,r){const d=r==null?r=new Path:void 0,{points:v,triangles:C}=this,w=C[t*=3]*2,E=C[t+1]*2,ye=C[t+2]*2;return r.moveTo(v[w],v[w+1]),r.lineTo(v[E],v[E+1]),r.lineTo(v[ye],v[ye+1]),r.closePath(),d&&d.value()}*trianglePolygons(){const{triangles:t}=this;for(let r=0,d=t.length/3;r<d;++r)yield this.trianglePolygon(r)}trianglePolygon(t){const r=new Polygon;return this.renderTriangle(t,r),r.value()}}function flatArray(g,t,r,d){const v=g.length,C=new Float64Array(v*2);for(let w=0;w<v;++w){const E=g[w];C[w*2]=t.call(d,E,w,g),C[w*2+1]=r.call(d,E,w,g)}return C}function*flatIterable(g,t,r,d){let v=0;for(const C of g)yield t.call(d,C,v,g),yield r.call(d,C,v,g),++v}const pi$1=Math.PI,halfPi=pi$1/2,degrees=180/pi$1,radians=pi$1/180,atan2=Math.atan2,cos=Math.cos,max$1=Math.max,min=Math.min,sin=Math.sin,sign=Math.sign||function(g){return g>0?1:g<0?-1:0},sqrt=Math.sqrt;function asin(g){return g>1?halfPi:g<-1?-halfPi:Math.asin(g)}function cartesianDot(g,t){return g[0]*t[0]+g[1]*t[1]+g[2]*t[2]}function cartesianCross(g,t){return[g[1]*t[2]-g[2]*t[1],g[2]*t[0]-g[0]*t[2],g[0]*t[1]-g[1]*t[0]]}function cartesianAdd(g,t){return[g[0]+t[0],g[1]+t[1],g[2]+t[2]]}function cartesianNormalize(g){var t=sqrt(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]);return[g[0]/t,g[1]/t,g[2]/t]}function spherical(g){return[atan2(g[1],g[0])*degrees,asin(max$1(-1,min(1,g[2])))*degrees]}function cartesian(g){const t=g[0]*radians,r=g[1]*radians,d=cos(r);return[d*cos(t),d*sin(t),sin(r)]}function excess(g){return g=g.map(t=>cartesian(t)),cartesianDot(g[0],cartesianCross(g[2],g[1]))}function geoDelaunay(g){const t=geo_delaunay_from(g),r=geo_triangles(t),d=geo_edges(r,g),v=geo_neighbors(r,g.length),C=geo_find(v,g),w=geo_circumcenters(r,g),{polygons:E,centers:ye}=geo_polygons(w,r,g),Le=geo_mesh(E),Re=geo_hull(r,g),Ne=geo_urquhart(d,r);return{delaunay:t,edges:d,triangles:r,centers:ye,neighbors:v,polygons:E,mesh:Le,hull:Re,urquhart:Ne,find:C}}function geo_find(g,t){function r(d,v){let C=d[0]-v[0],w=d[1]-v[1],E=d[2]-v[2];return C*C+w*w+E*E}return function(v,C,w){w===void 0&&(w=0);let E,ye,Le=w;const Re=cartesian([v,C]);do E=w,w=null,ye=r(Re,cartesian(t[E])),g[E].forEach(Ne=>{let Fe=r(Re,cartesian(t[Ne]));if(Fe<ye){ye=Fe,w=Ne,Le=Ne;return}});while(w!==null);return Le}}function geo_delaunay_from(g){if(g.length<2)return{};let t=0;for(;isNaN(g[t][0]+g[t][1])&&t++<g.length;);const r=geoRotation(g[t]),d=geoStereographic().translate([0,0]).scale(1).rotate(r.invert([180,0]));g=g.map(d);const v=[];let C=1;for(let Ne=0,Fe=g.length;Ne<Fe;Ne++){let at=mn(g[Ne][0],2)+mn(g[Ne][1],2);!isFinite(at)||at>1e32?v.push(Ne):at>C&&(C=at)}const w=1e6*sqrt(C);v.forEach(Ne=>g[Ne]=[w,0]),g.push([0,w]),g.push([-w,0]),g.push([0,-w]);const E=Delaunay.from(g);E.projection=d;const{triangles:ye,halfedges:Le,inedges:Re}=E;for(let Ne=0,Fe=Le.length;Ne<Fe;Ne++)if(Le[Ne]<0){const at=Ne%3==2?Ne-2:Ne+1,ot=Ne%3==0?Ne+2:Ne-1,Gt=Le[at],ht=Le[ot];Le[Gt]=ht,Le[ht]=Gt,Le[at]=Le[ot]=-1,ye[Ne]=ye[at]=ye[ot]=t,Re[ye[Gt]]=Gt%3==0?Gt+2:Gt-1,Re[ye[ht]]=ht%3==0?ht+2:ht-1,Ne+=2-Ne%3}else ye[Ne]>g.length-3-1&&(ye[Ne]=t);return E}function geo_edges(g,t){const r=new Set;return t.length===2?[[0,1]]:(g.forEach(d=>{if(d[0]!==d[1]&&!(excess(d.map(v=>t[v]))<0))for(let v=0,C;v<3;v++)C=(v+1)%3,r.add(extent([d[v],d[C]]).join("-"))}),Array.from(r,d=>d.split("-").map(Number)))}function geo_triangles(g){const{triangles:t}=g;if(!t)return[];const r=[];for(let d=0,v=t.length/3;d<v;d++){const C=t[3*d],w=t[3*d+1],E=t[3*d+2];C!==w&&w!==E&&r.push([C,E,w])}return r}function geo_circumcenters(g,t){return g.map(r=>{const d=r.map(C=>t[C]).map(cartesian),v=cartesianAdd(cartesianAdd(cartesianCross(d[1],d[0]),cartesianCross(d[2],d[1])),cartesianCross(d[0],d[2]));return spherical(cartesianNormalize(v))})}function geo_neighbors(g,t){const r=[];return g.forEach(d=>{for(let v=0;v<3;v++){const C=d[v],w=d[(v+1)%3];r[C]=r[C]||[],r[C].push(w)}}),g.length===0&&(t===2?(r[0]=[1],r[1]=[0]):t===1&&(r[0]=[])),r}function geo_polygons(g,t,r){const d=[],v=g.slice();if(t.length===0){if(r.length<2)return{polygons:d,centers:v};if(r.length===2){const E=cartesian(r[0]),ye=cartesian(r[1]),Le=cartesianNormalize(cartesianAdd(E,ye)),Re=cartesianNormalize(cartesianCross(E,ye)),Ne=cartesianCross(Le,Re),Fe=[Le,cartesianCross(Le,Ne),cartesianCross(cartesianCross(Le,Ne),Ne),cartesianCross(cartesianCross(cartesianCross(Le,Ne),Ne),Ne)].map(spherical).map(w);return d.push(Fe),d.push(Fe.slice().reverse()),{polygons:d,centers:v}}}t.forEach((E,ye)=>{for(let Le=0;Le<3;Le++){const Re=E[Le],Ne=E[(Le+1)%3],Fe=E[(Le+2)%3];d[Re]=d[Re]||[],d[Re].push([Ne,Fe,ye,[Re,Ne,Fe]])}});const C=d.map(E=>{const ye=[E[0][2]];let Le=E[0][1];for(let Re=1;Re<E.length;Re++)for(let Ne=0;Ne<E.length;Ne++)if(E[Ne][0]==Le){Le=E[Ne][1],ye.push(E[Ne][2]);break}if(ye.length>2)return ye;if(ye.length==2){const Re=o_midpoint(r[E[0][3][0]],r[E[0][3][1]],v[ye[0]]),Ne=o_midpoint(r[E[0][3][2]],r[E[0][3][0]],v[ye[0]]),Fe=w(Re),at=w(Ne);return[ye[0],at,ye[1],Fe]}});function w(E){let ye=-1;return v.slice(t.length,1/0).forEach((Le,Re)=>{Le[0]===E[0]&&Le[1]===E[1]&&(ye=Re+t.length)}),ye<0&&(ye=v.length,v.push(E)),ye}return{polygons:C,centers:v}}function o_midpoint(g,t,r){g=cartesian(g),t=cartesian(t),r=cartesian(r);const d=sign(cartesianDot(cartesianCross(t,g),r));return spherical(cartesianNormalize(cartesianAdd(g,t)).map(v=>d*v))}function geo_mesh(g){const t=[];return g.forEach(r=>{if(!r)return;let d=r[r.length-1];for(let v of r)v>d&&t.push([d,v]),d=v}),t}function geo_urquhart(g,t){return function(r){const d=new Map,v=new Map;return g.forEach((C,w)=>{const E=C.join("-");d.set(E,r[w]),v.set(E,!0)}),t.forEach(C=>{let w=0,E=-1;for(let ye=0;ye<3;ye++){let Le=extent([C[ye],C[(ye+1)%3]]).join("-");d.get(Le)>w&&(w=d.get(Le),E=Le)}v.set(E,!1)}),g.map(C=>v.get(C.join("-")))}}function geo_hull(g,t){const r=new Set,d=[];g.map(E=>{if(!(excess(E.map(ye=>t[ye>t.length?0:ye]))>1e-12))for(let ye=0;ye<3;ye++){let Le=[E[ye],E[(ye+1)%3]],Re=`${Le[0]}-${Le[1]}`;r.has(Re)?r.delete(Re):r.add(`${Le[1]}-${Le[0]}`)}});const v=new Map;let C;if(r.forEach(E=>{E=E.split("-").map(Number),v.set(E[0],E[1]),C=E[0]}),C===void 0)return d;let w=C;do{d.push(w);let E=v.get(w);v.set(w,-1),w=E}while(w>-1&&w!==C);return d}function geoVoronoi(g){const t=function(r){if(t.delaunay=null,t._data=r,typeof t._data=="object"&&t._data.type==="FeatureCollection"&&(t._data=t._data.features),typeof t._data=="object"){const d=t._data.map(v=>[t._vx(v),t._vy(v),v]).filter(v=>isFinite(v[0]+v[1]));t.points=d.map(v=>[v[0],v[1]]),t.valid=d.map(v=>v[2]),t.delaunay=geoDelaunay(t.points)}return t};return t._vx=function(r){if(typeof r=="object"&&"type"in r)return geoCentroid(r)[0];if(0 in r)return r[0]},t._vy=function(r){if(typeof r=="object"&&"type"in r)return geoCentroid(r)[1];if(1 in r)return r[1]},t.x=function(r){return r?(t._vx=r,t):t._vx},t.y=function(r){return r?(t._vy=r,t):t._vy},t.polygons=function(r){if(r!==void 0&&t(r),!t.delaunay)return!1;const d={type:"FeatureCollection",features:[]};return t.valid.length===0||(t.delaunay.polygons.forEach((v,C)=>d.features.push({type:"Feature",geometry:v?{type:"Polygon",coordinates:[[...v,v[0]].map(w=>t.delaunay.centers[w])]}:null,properties:{site:t.valid[C],sitecoordinates:t.points[C],neighbours:t.delaunay.neighbors[C]}})),t.valid.length===1&&d.features.push({type:"Feature",geometry:{type:"Sphere"},properties:{site:t.valid[0],sitecoordinates:t.points[0],neighbours:[]}})),d},t.triangles=function(r){return r!==void 0&&t(r),t.delaunay?{type:"FeatureCollection",features:t.delaunay.triangles.map((d,v)=>(d=d.map(C=>t.points[C]),d.center=t.delaunay.centers[v],d)).filter(d=>excess(d)>0).map(d=>({type:"Feature",properties:{circumcenter:d.center},geometry:{type:"Polygon",coordinates:[[...d,d[0]]]}}))}:!1},t.links=function(r){if(r!==void 0&&t(r),!t.delaunay)return!1;const d=t.delaunay.edges.map(C=>$t(t.points[C[0]],t.points[C[1]])),v=t.delaunay.urquhart(d);return{type:"FeatureCollection",features:t.delaunay.edges.map((C,w)=>({type:"Feature",properties:{source:t.valid[C[0]],target:t.valid[C[1]],length:d[w],urquhart:!!v[w]},geometry:{type:"LineString",coordinates:[t.points[C[0]],t.points[C[1]]]}}))}},t.mesh=function(r){return r!==void 0&&t(r),t.delaunay?{type:"MultiLineString",coordinates:t.delaunay.edges.map(d=>[t.points[d[0]],t.points[d[1]]])}:!1},t.cellMesh=function(r){if(r!==void 0&&t(r),!t.delaunay)return!1;const{centers:d,polygons:v}=t.delaunay,C=[];for(const w of v)if(w)for(let E=w.length,ye=w[E-1],Le=w[0],Re=0;Re<E;ye=Le,Le=w[++Re])Le>ye&&C.push([d[ye],d[Le]]);return{type:"MultiLineString",coordinates:C}},t._found=void 0,t.find=function(r,d,v){if(t._found=t.delaunay.find(r,d,t._found),!v||$t([r,d],t.points[t._found])<v)return t._found},t.hull=function(r){r!==void 0&&t(r);const d=t.delaunay.hull,v=t.points;return d.length===0?null:{type:"Polygon",coordinates:[[...d.map(C=>v[C]),v[d[0]]]]}},g?t(g):t}function initRange(g,t){switch(arguments.length){case 0:break;case 1:this.range(g);break;default:this.range(t).domain(g);break}return this}function define$1(g,t,r){g.prototype=t.prototype=r,r.constructor=g}function extend(g,t){var r=Object.create(g.prototype);for(var d in t)r[d]=t[d];return r}function Color(){}var darker=.7,brighter=1/darker,reI="\\s*([+-]?\\d+)\\s*",reN="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",reP="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",reHex=/^#([0-9a-f]{3,8})$/,reRgbInteger=new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`),reRgbPercent=new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`),reRgbaInteger=new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`),reRgbaPercent=new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`),reHslPercent=new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`),reHslaPercent=new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`),named={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};define$1(Color,color,{copy(g){return Object.assign(new this.constructor,this,g)},displayable(){return this.rgb().displayable()},hex:color_formatHex,formatHex:color_formatHex,formatHex8:color_formatHex8,formatHsl:color_formatHsl,formatRgb:color_formatRgb,toString:color_formatRgb});function color_formatHex(){return this.rgb().formatHex()}function color_formatHex8(){return this.rgb().formatHex8()}function color_formatHsl(){return hslConvert(this).formatHsl()}function color_formatRgb(){return this.rgb().formatRgb()}function color(g){var t,r;return g=(g+"").trim().toLowerCase(),(t=reHex.exec(g))?(r=t[1].length,t=parseInt(t[1],16),r===6?rgbn(t):r===3?new Rgb(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):r===8?rgba(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):r===4?rgba(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=reRgbInteger.exec(g))?new Rgb(t[1],t[2],t[3],1):(t=reRgbPercent.exec(g))?new Rgb(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=reRgbaInteger.exec(g))?rgba(t[1],t[2],t[3],t[4]):(t=reRgbaPercent.exec(g))?rgba(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=reHslPercent.exec(g))?hsla(t[1],t[2]/100,t[3]/100,1):(t=reHslaPercent.exec(g))?hsla(t[1],t[2]/100,t[3]/100,t[4]):named.hasOwnProperty(g)?rgbn(named[g]):g==="transparent"?new Rgb(NaN,NaN,NaN,0):null}function rgbn(g){return new Rgb(g>>16&255,g>>8&255,g&255,1)}function rgba(g,t,r,d){return d<=0&&(g=t=r=NaN),new Rgb(g,t,r,d)}function rgbConvert(g){return g instanceof Color||(g=color(g)),g?(g=g.rgb(),new Rgb(g.r,g.g,g.b,g.opacity)):new Rgb}function rgb$1(g,t,r,d){return arguments.length===1?rgbConvert(g):new Rgb(g,t,r,d==null?1:d)}function Rgb(g,t,r,d){this.r=+g,this.g=+t,this.b=+r,this.opacity=+d}define$1(Rgb,rgb$1,extend(Color,{brighter(g){return g=g==null?brighter:Math.pow(brighter,g),new Rgb(this.r*g,this.g*g,this.b*g,this.opacity)},darker(g){return g=g==null?darker:Math.pow(darker,g),new Rgb(this.r*g,this.g*g,this.b*g,this.opacity)},rgb(){return this},clamp(){return new Rgb(clampi(this.r),clampi(this.g),clampi(this.b),clampa(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:rgb_formatHex,formatHex:rgb_formatHex,formatHex8:rgb_formatHex8,formatRgb:rgb_formatRgb,toString:rgb_formatRgb}));function rgb_formatHex(){return`#${hex(this.r)}${hex(this.g)}${hex(this.b)}`}function rgb_formatHex8(){return`#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity)?1:this.opacity)*255)}`}function rgb_formatRgb(){const g=clampa(this.opacity);return`${g===1?"rgb(":"rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${g===1?")":`, ${g})`}`}function clampa(g){return isNaN(g)?1:Math.max(0,Math.min(1,g))}function clampi(g){return Math.max(0,Math.min(255,Math.round(g)||0))}function hex(g){return g=clampi(g),(g<16?"0":"")+g.toString(16)}function hsla(g,t,r,d){return d<=0?g=t=r=NaN:r<=0||r>=1?g=t=NaN:t<=0&&(g=NaN),new Hsl(g,t,r,d)}function hslConvert(g){if(g instanceof Hsl)return new Hsl(g.h,g.s,g.l,g.opacity);if(g instanceof Color||(g=color(g)),!g)return new Hsl;if(g instanceof Hsl)return g;g=g.rgb();var t=g.r/255,r=g.g/255,d=g.b/255,v=Math.min(t,r,d),C=Math.max(t,r,d),w=NaN,E=C-v,ye=(C+v)/2;return E?(t===C?w=(r-d)/E+(r<d)*6:r===C?w=(d-t)/E+2:w=(t-r)/E+4,E/=ye<.5?C+v:2-C-v,w*=60):E=ye>0&&ye<1?0:w,new Hsl(w,E,ye,g.opacity)}function hsl(g,t,r,d){return arguments.length===1?hslConvert(g):new Hsl(g,t,r,d==null?1:d)}function Hsl(g,t,r,d){this.h=+g,this.s=+t,this.l=+r,this.opacity=+d}define$1(Hsl,hsl,extend(Color,{brighter(g){return g=g==null?brighter:Math.pow(brighter,g),new Hsl(this.h,this.s,this.l*g,this.opacity)},darker(g){return g=g==null?darker:Math.pow(darker,g),new Hsl(this.h,this.s,this.l*g,this.opacity)},rgb(){var g=this.h%360+(this.h<0)*360,t=isNaN(g)||isNaN(this.s)?0:this.s,r=this.l,d=r+(r<.5?r:1-r)*t,v=2*r-d;return new Rgb(hsl2rgb(g>=240?g-240:g+120,v,d),hsl2rgb(g,v,d),hsl2rgb(g<120?g+240:g-120,v,d),this.opacity)},clamp(){return new Hsl(clamph(this.h),clampt(this.s),clampt(this.l),clampa(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const g=clampa(this.opacity);return`${g===1?"hsl(":"hsla("}${clamph(this.h)}, ${clampt(this.s)*100}%, ${clampt(this.l)*100}%${g===1?")":`, ${g})`}`}}));function clamph(g){return g=(g||0)%360,g<0?g+360:g}function clampt(g){return Math.max(0,Math.min(1,g||0))}function hsl2rgb(g,t,r){return(g<60?t+(r-t)*g/60:g<180?r:g<240?t+(r-t)*(240-g)/60:t)*255}const constant=g=>()=>g;function linear$1(g,t){return function(r){return g+r*t}}function exponential(g,t,r){return g=Math.pow(g,r),t=Math.pow(t,r)-g,r=1/r,function(d){return Math.pow(g+d*t,r)}}function gamma(g){return(g=+g)==1?nogamma:function(t,r){return r-t?exponential(t,r,g):constant(isNaN(t)?r:t)}}function nogamma(g,t){var r=t-g;return r?linear$1(g,r):constant(isNaN(g)?t:g)}const rgb=function g(t){var r=gamma(t);function d(v,C){var w=r((v=rgb$1(v)).r,(C=rgb$1(C)).r),E=r(v.g,C.g),ye=r(v.b,C.b),Le=nogamma(v.opacity,C.opacity);return function(Re){return v.r=w(Re),v.g=E(Re),v.b=ye(Re),v.opacity=Le(Re),v+""}}return d.gamma=g,d}(1);function numberArray(g,t){t||(t=[]);var r=g?Math.min(t.length,g.length):0,d=t.slice(),v;return function(C){for(v=0;v<r;++v)d[v]=g[v]*(1-C)+t[v]*C;return d}}function isNumberArray(g){return ArrayBuffer.isView(g)&&!(g instanceof DataView)}function genericArray(g,t){var r=t?t.length:0,d=g?Math.min(r,g.length):0,v=new Array(d),C=new Array(r),w;for(w=0;w<d;++w)v[w]=interpolate(g[w],t[w]);for(;w<r;++w)C[w]=t[w];return function(E){for(w=0;w<d;++w)C[w]=v[w](E);return C}}function date(g,t){var r=new Date;return g=+g,t=+t,function(d){return r.setTime(g*(1-d)+t*d),r}}function interpolateNumber(g,t){return g=+g,t=+t,function(r){return g*(1-r)+t*r}}function object(g,t){var r={},d={},v;(g===null||typeof g!="object")&&(g={}),(t===null||typeof t!="object")&&(t={});for(v in t)v in g?r[v]=interpolate(g[v],t[v]):d[v]=t[v];return function(C){for(v in r)d[v]=r[v](C);return d}}var reA=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,reB=new RegExp(reA.source,"g");function zero(g){return function(){return g}}function one(g){return function(t){return g(t)+""}}function string(g,t){var r=reA.lastIndex=reB.lastIndex=0,d,v,C,w=-1,E=[],ye=[];for(g=g+"",t=t+"";(d=reA.exec(g))&&(v=reB.exec(t));)(C=v.index)>r&&(C=t.slice(r,C),E[w]?E[w]+=C:E[++w]=C),(d=d[0])===(v=v[0])?E[w]?E[w]+=v:E[++w]=v:(E[++w]=null,ye.push({i:w,x:interpolateNumber(d,v)})),r=reB.lastIndex;return r<t.length&&(C=t.slice(r),E[w]?E[w]+=C:E[++w]=C),E.length<2?ye[0]?one(ye[0].x):zero(t):(t=ye.length,function(Le){for(var Re=0,Ne;Re<t;++Re)E[(Ne=ye[Re]).i]=Ne.x(Le);return E.join("")})}function interpolate(g,t){var r=typeof t,d;return t==null||r==="boolean"?constant(t):(r==="number"?interpolateNumber:r==="string"?(d=color(t))?(t=d,rgb):string:t instanceof color?rgb:t instanceof Date?date:isNumberArray(t)?numberArray:Array.isArray(t)?genericArray:typeof t.valueOf!="function"&&typeof t.toString!="function"||isNaN(t)?object:interpolateNumber)(g,t)}function interpolateRound(g,t){return g=+g,t=+t,function(r){return Math.round(g*(1-r)+t*r)}}function constants(g){return function(){return g}}function number(g){return+g}var unit=[0,1];function identity$1(g){return g}function normalize(g,t){return(t-=g=+g)?function(r){return(r-g)/t}:constants(isNaN(t)?NaN:.5)}function clamper(g,t){var r;return g>t&&(r=g,g=t,t=r),function(d){return Math.max(g,Math.min(t,d))}}function bimap(g,t,r){var d=g[0],v=g[1],C=t[0],w=t[1];return v<d?(d=normalize(v,d),C=r(w,C)):(d=normalize(d,v),C=r(C,w)),function(E){return C(d(E))}}function polymap(g,t,r){var d=Math.min(g.length,t.length)-1,v=new Array(d),C=new Array(d),w=-1;for(g[d]<g[0]&&(g=g.slice().reverse(),t=t.slice().reverse());++w<d;)v[w]=normalize(g[w],g[w+1]),C[w]=r(t[w],t[w+1]);return function(E){var ye=bisectRight(g,E,1,d)-1;return C[ye](v[ye](E))}}function copy(g,t){return t.domain(g.domain()).range(g.range()).interpolate(g.interpolate()).clamp(g.clamp()).unknown(g.unknown())}function transformer(){var g=unit,t=unit,r=interpolate,d,v,C,w=identity$1,E,ye,Le;function Re(){var Fe=Math.min(g.length,t.length);return w!==identity$1&&(w=clamper(g[0],g[Fe-1])),E=Fe>2?polymap:bimap,ye=Le=null,Ne}function Ne(Fe){return Fe==null||isNaN(Fe=+Fe)?C:(ye||(ye=E(g.map(d),t,r)))(d(w(Fe)))}return Ne.invert=function(Fe){return w(v((Le||(Le=E(t,g.map(d),interpolateNumber)))(Fe)))},Ne.domain=function(Fe){return arguments.length?(g=Array.from(Fe,number),Re()):g.slice()},Ne.range=function(Fe){return arguments.length?(t=Array.from(Fe),Re()):t.slice()},Ne.rangeRound=function(Fe){return t=Array.from(Fe),r=interpolateRound,Re()},Ne.clamp=function(Fe){return arguments.length?(w=Fe?!0:identity$1,Re()):w!==identity$1},Ne.interpolate=function(Fe){return arguments.length?(r=Fe,Re()):r},Ne.unknown=function(Fe){return arguments.length?(C=Fe,Ne):C},function(Fe,at){return d=Fe,v=at,Re()}}function continuous(){return transformer()(identity$1,identity$1)}function formatDecimal(g){return Math.abs(g=Math.round(g))>=1e21?g.toLocaleString("en").replace(/,/g,""):g.toString(10)}function formatDecimalParts(g,t){if((r=(g=t?g.toExponential(t-1):g.toExponential()).indexOf("e"))<0)return null;var r,d=g.slice(0,r);return[d.length>1?d[0]+d.slice(2):d,+g.slice(r+1)]}function exponent(g){return g=formatDecimalParts(Math.abs(g)),g?g[1]:NaN}function formatGroup(g,t){return function(r,d){for(var v=r.length,C=[],w=0,E=g[0],ye=0;v>0&&E>0&&(ye+E+1>d&&(E=Math.max(1,d-ye)),C.push(r.substring(v-=E,v+E)),!((ye+=E+1)>d));)E=g[w=(w+1)%g.length];return C.reverse().join(t)}}function formatNumerals(g){return function(t){return t.replace(/[0-9]/g,function(r){return g[+r]})}}var re$2=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function formatSpecifier(g){if(!(t=re$2.exec(g)))throw new Error("invalid format: "+g);var t;return new FormatSpecifier({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}formatSpecifier.prototype=FormatSpecifier.prototype;function FormatSpecifier(g){this.fill=g.fill===void 0?" ":g.fill+"",this.align=g.align===void 0?">":g.align+"",this.sign=g.sign===void 0?"-":g.sign+"",this.symbol=g.symbol===void 0?"":g.symbol+"",this.zero=!!g.zero,this.width=g.width===void 0?void 0:+g.width,this.comma=!!g.comma,this.precision=g.precision===void 0?void 0:+g.precision,this.trim=!!g.trim,this.type=g.type===void 0?"":g.type+""}FormatSpecifier.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function formatTrim(g){e:for(var t=g.length,r=1,d=-1,v;r<t;++r)switch(g[r]){case".":d=v=r;break;case"0":d===0&&(d=r),v=r;break;default:if(!+g[r])break e;d>0&&(d=0);break}return d>0?g.slice(0,d)+g.slice(v+1):g}var prefixExponent;function formatPrefixAuto(g,t){var r=formatDecimalParts(g,t);if(!r)return g+"";var d=r[0],v=r[1],C=v-(prefixExponent=Math.max(-8,Math.min(8,Math.floor(v/3)))*3)+1,w=d.length;return C===w?d:C>w?d+new Array(C-w+1).join("0"):C>0?d.slice(0,C)+"."+d.slice(C):"0."+new Array(1-C).join("0")+formatDecimalParts(g,Math.max(0,t+C-1))[0]}function formatRounded(g,t){var r=formatDecimalParts(g,t);if(!r)return g+"";var d=r[0],v=r[1];return v<0?"0."+new Array(-v).join("0")+d:d.length>v+1?d.slice(0,v+1)+"."+d.slice(v+1):d+new Array(v-d.length+2).join("0")}const formatTypes={"%":(g,t)=>(g*100).toFixed(t),b:g=>Math.round(g).toString(2),c:g=>g+"",d:formatDecimal,e:(g,t)=>g.toExponential(t),f:(g,t)=>g.toFixed(t),g:(g,t)=>g.toPrecision(t),o:g=>Math.round(g).toString(8),p:(g,t)=>formatRounded(g*100,t),r:formatRounded,s:formatPrefixAuto,X:g=>Math.round(g).toString(16).toUpperCase(),x:g=>Math.round(g).toString(16)};function identity(g){return g}var map$1=Array.prototype.map,prefixes=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function formatLocale(g){var t=g.grouping===void 0||g.thousands===void 0?identity:formatGroup(map$1.call(g.grouping,Number),g.thousands+""),r=g.currency===void 0?"":g.currency[0]+"",d=g.currency===void 0?"":g.currency[1]+"",v=g.decimal===void 0?".":g.decimal+"",C=g.numerals===void 0?identity:formatNumerals(map$1.call(g.numerals,String)),w=g.percent===void 0?"%":g.percent+"",E=g.minus===void 0?"−":g.minus+"",ye=g.nan===void 0?"NaN":g.nan+"";function Le(Ne){Ne=formatSpecifier(Ne);var Fe=Ne.fill,at=Ne.align,ot=Ne.sign,Gt=Ne.symbol,ht=Ne.zero,ke=Ne.width,ct=Ne.comma,xt=Ne.precision,Rt=Ne.trim,Wt=Ne.type;Wt==="n"?(ct=!0,Wt="g"):formatTypes[Wt]||(xt===void 0&&(xt=12),Rt=!0,Wt="g"),(ht||Fe==="0"&&at==="=")&&(ht=!0,Fe="0",at="=");var Pt=Gt==="$"?r:Gt==="#"&&/[boxX]/.test(Wt)?"0"+Wt.toLowerCase():"",Nt=Gt==="$"?d:/[%p]/.test(Wt)?w:"",Kt=formatTypes[Wt],Ft=/[defgprs%]/.test(Wt);xt=xt===void 0?6:/[gprs]/.test(Wt)?Math.max(1,Math.min(21,xt)):Math.max(0,Math.min(20,xt));function kt(Yt){var s0=Pt,o0=Nt,h0,r0,e0;if(Wt==="c")o0=Kt(Yt)+o0,Yt="";else{Yt=+Yt;var i0=Yt<0||1/Yt<0;if(Yt=isNaN(Yt)?ye:Kt(Math.abs(Yt),xt),Rt&&(Yt=formatTrim(Yt)),i0&&+Yt==0&&ot!=="+"&&(i0=!1),s0=(i0?ot==="("?ot:E:ot==="-"||ot==="("?"":ot)+s0,o0=(Wt==="s"?prefixes[8+prefixExponent/3]:"")+o0+(i0&&ot==="("?")":""),Ft){for(h0=-1,r0=Yt.length;++h0<r0;)if(e0=Yt.charCodeAt(h0),48>e0||e0>57){o0=(e0===46?v+Yt.slice(h0+1):Yt.slice(h0))+o0,Yt=Yt.slice(0,h0);break}}}ct&&!ht&&(Yt=t(Yt,1/0));var Ut=s0.length+Yt.length+o0.length,l0=Ut<ke?new Array(ke-Ut+1).join(Fe):"";switch(ct&&ht&&(Yt=t(l0+Yt,l0.length?ke-o0.length:1/0),l0=""),at){case"<":Yt=s0+Yt+o0+l0;break;case"=":Yt=s0+l0+Yt+o0;break;case"^":Yt=l0.slice(0,Ut=l0.length>>1)+s0+Yt+o0+l0.slice(Ut);break;default:Yt=l0+s0+Yt+o0;break}return C(Yt)}return kt.toString=function(){return Ne+""},kt}function Re(Ne,Fe){var at=Le((Ne=formatSpecifier(Ne),Ne.type="f",Ne)),ot=Math.max(-8,Math.min(8,Math.floor(exponent(Fe)/3)))*3,Gt=Math.pow(10,-ot),ht=prefixes[8+ot/3];return function(ke){return at(Gt*ke)+ht}}return{format:Le,formatPrefix:Re}}var locale,format,formatPrefix;defaultLocale({thousands:",",grouping:[3],currency:["$",""]});function defaultLocale(g){return locale=formatLocale(g),format=locale.format,formatPrefix=locale.formatPrefix,locale}function precisionFixed(g){return Math.max(0,-exponent(Math.abs(g)))}function precisionPrefix(g,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(exponent(t)/3)))*3-exponent(Math.abs(g)))}function precisionRound(g,t){return g=Math.abs(g),t=Math.abs(t)-g,Math.max(0,exponent(t)-exponent(g))+1}function tickFormat(g,t,r,d){var v=tickStep(g,t,r),C;switch(d=formatSpecifier(d==null?",f":d),d.type){case"s":{var w=Math.max(Math.abs(g),Math.abs(t));return d.precision==null&&!isNaN(C=precisionPrefix(v,w))&&(d.precision=C),formatPrefix(d,w)}case"":case"e":case"g":case"p":case"r":{d.precision==null&&!isNaN(C=precisionRound(v,Math.max(Math.abs(g),Math.abs(t))))&&(d.precision=C-(d.type==="e"));break}case"f":case"%":{d.precision==null&&!isNaN(C=precisionFixed(v))&&(d.precision=C-(d.type==="%")*2);break}}return format(d)}function linearish(g){var t=g.domain;return g.ticks=function(r){var d=t();return ticks(d[0],d[d.length-1],r==null?10:r)},g.tickFormat=function(r,d){var v=t();return tickFormat(v[0],v[v.length-1],r==null?10:r,d)},g.nice=function(r){r==null&&(r=10);var d=t(),v=0,C=d.length-1,w=d[v],E=d[C],ye,Le,Re=10;for(E<w&&(Le=w,w=E,E=Le,Le=v,v=C,C=Le);Re-- >0;){if(Le=tickIncrement(w,E,r),Le===ye)return d[v]=w,d[C]=E,t(d);if(Le>0)w=Math.floor(w/Le)*Le,E=Math.ceil(E/Le)*Le;else if(Le<0)w=Math.ceil(w*Le)/Le,E=Math.floor(E*Le)/Le;else break;ye=Le}return g},g}function linear(){var g=continuous();return g.copy=function(){return copy(g,linear())},initRange.apply(g,arguments),linearish(g)}var At$1=Object.defineProperty,jt=Object.defineProperties,St$1=Object.getOwnPropertyDescriptors,tt$1=Object.getOwnPropertySymbols,Ct$1=Object.prototype.hasOwnProperty,zt=Object.prototype.propertyIsEnumerable,it$1=Math.pow,et$2=(g,t,r)=>t in g?At$1(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,L$1=(g,t)=>{for(var r in t||(t={}))Ct$1.call(t,r)&&et$2(g,r,t[r]);if(tt$1)for(var r of tt$1(t))zt.call(t,r)&&et$2(g,r,t[r]);return g},q$1=(g,t)=>jt(g,St$1(t)),st$1=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())});class O{constructor(){this.resources=new Set,this.disposeWithMaterial=!0,this.materialList={},this.disposeTrack=!0}track(t){if(!t||this.disposeTrack===!1)return t;if(Array.isArray(t))return t.forEach(r=>this.track(r)),t;if(!this.disposeWithMaterial&&t instanceof Material)return t;if(t instanceof O?(t===this&&t.object3d?this.track(t.object3d):(t.disposeTrack=!1,this.resources.add(t)),Object.values(t.materialList).map(r=>this.track(r))):(t instanceof Object3D||Reflect.has(t,"dispose"))&&this.resources.add(t),t instanceof O)this.track(t.children);else if(t instanceof Object3D){const r=t;this.track(r.geometry),this.track(r.material),this.track(r.children)}else if(t instanceof Material){for(const d of Object.values(t))d instanceof Texture&&this.track(d);const r=t;if(r.uniforms){for(const d of Object.values(r.uniforms))if(d){const v=d.value;(v instanceof Texture||Array.isArray(v))&&this.track(v)}}}else t instanceof VideoTexture&&t.source.data&&this.resources.add(t.source.data);return t}dispose(){const t=[];for(const r of this.resources)r instanceof Object3D?t.push(r):r instanceof HTMLVideoElement&&(r.pause(),r.src="",r.remove()),Reflect.has(r,"dispose")&&r.dispose();t.forEach(r=>{r.removeFromParent()}),t.length=0,this.resources.clear()}}const ee$1=(g,t=1)=>{const r=new BufferGeometry;r.setAttribute("position",new Float32BufferAttribute(new Array(t*3).fill(0),3)),r.setAttribute("scaleAtt",new Float32BufferAttribute(new Array(t).fill(1),1));const d=g.material,v=new PointsMaterial({size:10,map:d.map,alphaMap:d.alphaMap,color:d.color,blending:d.blending,depthTest:d.depthTest,depthWrite:!1,opacity:d.opacity,transparent:!0,alphaTest:d.alphaTest,sizeAttenuation:!1});return v.onBeforeCompile=C=>{C.vertexShader=`
3843
+ `}setupEventListeners(){this.minimal?(this.dom.addEventListener("click",this.handleClick),this.showPanel(this.mode)):window.addEventListener("resize",this.handleResize)}init(t){return D0(this,null,function*(){if(!t){console.error('Stats: The "canvas" parameter is undefined.');return}if(!this.handleThreeRenderer(t)&&!(yield this.handleWebGPURenderer(t)))if(this.initializeWebGL(t)){this.trackGPU&&this.initializeGPUTracking();return}else console.error("Stats-gl: Failed to initialize WebGL context")})}handleThreeRenderer(t){return t.isWebGLRenderer&&!this.threeRendererPatched?(this.patchThreeRenderer(t),this.gl=t.getContext(),this.trackGPU&&this.initializeGPUTracking(),!0):!1}handleWebGPURenderer(t){return D0(this,null,function*(){return t.isWebGPURenderer?((this.trackGPU||this.trackCPT)&&(t.backend.trackTimestamp=!0,(yield t.hasFeatureAsync("timestamp-query"))&&this.initializeWebGPUPanels()),this.info=t.info,this.patchThreeWebGPU(t),!0):!1})}initializeWebGPUPanels(){this.trackGPU&&(this.gpuPanel=this.addPanel(new gn.Panel("GPU","#ff0","#220"))),this.trackCPT&&(this.gpuPanelCompute=this.addPanel(new gn.Panel("CPT","#e1e1e1","#212121")))}initializeWebGL(t){if(t instanceof WebGL2RenderingContext)this.gl=t;else if(t instanceof HTMLCanvasElement||t instanceof OffscreenCanvas){if(this.gl=t.getContext("webgl2"),!this.gl)return console.error("Stats: Unable to obtain WebGL2 context."),!1}else return console.error("Stats: Invalid input type. Expected WebGL2RenderingContext, HTMLCanvasElement, or OffscreenCanvas."),!1;return!0}initializeGPUTracking(){this.gl&&(this.ext=this.gl.getExtension("EXT_disjoint_timer_query_webgl2"),this.ext&&(this.gpuPanel=this.addPanel(new gn.Panel("GPU","#ff0","#220"))))}begin(){this.beginProfiling("cpu-started"),!(!this.gl||!this.ext)&&(this.activeQuery&&this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.activeQuery=this.gl.createQuery(),this.activeQuery&&this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT,this.activeQuery))}end(){this.renderCount++,this.gl&&this.ext&&this.activeQuery&&(this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.gpuQueries.push({query:this.activeQuery}),this.activeQuery=null),this.endProfiling("cpu-started","cpu-finished","cpu-duration")}update(){this.endProfiling("cpu-started","cpu-finished","cpu-duration"),this.info?this.processWebGPUTimestamps():this.processGpuQueries(),this.updateAverages(),this.resetCounters()}processWebGPUTimestamps(){this.totalGpuDuration=this.info.render.timestamp,this.totalGpuDurationCompute=this.info.compute.timestamp}resetCounters(){this.renderCount=0,this.totalCpuDuration=0,this.beginTime=this.endInternal()}resizePanel(t){t.canvas.style.position="absolute",this.minimal?t.canvas.style.display="none":(t.canvas.style.display="block",this.horizontal?(t.canvas.style.top="0px",t.canvas.style.left=t.id*t.WIDTH/t.PR+"px"):(t.canvas.style.left="0px",t.canvas.style.top=t.id*t.HEIGHT/t.PR+"px"))}addPanel(t){return t.canvas&&(this.dom.appendChild(t.canvas),t.id=this._panelId,this.resizePanel(t),this._panelId++),t}showPanel(t){for(let r=0;r<this.dom.children.length;r++){const d=this.dom.children[r];d.style.display=r===t?"block":"none"}this.mode=t}processGpuQueries(){!this.gl||!this.ext||(this.totalGpuDuration=0,this.gpuQueries.forEach((t,r)=>{if(this.gl){const d=this.gl.getQueryParameter(t.query,this.gl.QUERY_RESULT_AVAILABLE),v=this.gl.getParameter(this.ext.GPU_DISJOINT_EXT);if(d&&!v){const w=this.gl.getQueryParameter(t.query,this.gl.QUERY_RESULT)*1e-6;this.totalGpuDuration+=w,this.gl.deleteQuery(t.query),this.gpuQueries.splice(r,1)}}}))}detectVSync(t){if(this.lastFrameTime===0){this.lastFrameTime=t;return}const r=t-this.lastFrameTime;if(this.lastFrameTime=t,this.frameTimeHistory.push(r),this.frameTimeHistory.length>this.HISTORY_SIZE&&this.frameTimeHistory.shift(),this.frameTimeHistory.length<60)return;const d=this.frameTimeHistory.reduce((ye,Le)=>ye+Le)/this.frameTimeHistory.length,v=this.frameTimeHistory.reduce((ye,Le)=>ye+Math.pow(Le-d,2),0)/this.frameTimeHistory.length;if(Math.sqrt(v)>2){this.detectedVSync=null;return}let w=null,E=1/0;for(const ye of this.VSYNC_RATES){const Le=Math.abs(d-ye.frameTime);Le<E&&(E=Le,w=ye)}w&&E/w.frameTime<=this.VSYNC_THRESHOLD?this.detectedVSync=w:this.detectedVSync=null}endInternal(){var t;const r=performance.now();for(this.frameTimes.push(r);this.frameTimes.length>0&&this.frameTimes[0]<=r-1e3;)this.frameTimes.shift();const d=Math.round(this.frameTimes.length);this.addToAverage(d,this.averageFps);const v=r>=this.prevTextTime+1e3/this.logsPerSecond,C=r>=this.prevGraphTime+1e3/this.graphsPerSecond;if(this.updatePanelComponents(this.fpsPanel,this.averageFps,0,v,C),this.updatePanelComponents(this.msPanel,this.averageCpu,this.precision,v,C),this.gpuPanel&&this.updatePanelComponents(this.gpuPanel,this.averageGpu,this.precision,v,C),this.trackCPT&&this.gpuPanelCompute&&this.updatePanelComponents(this.gpuPanelCompute,this.averageGpuCompute,this.precision,v,C),v&&(this.prevTextTime=r),C&&(this.prevGraphTime=r),this.vsyncPanel!==null){this.detectVSync(r);const w=((t=this.detectedVSync)==null?void 0:t.refreshRate)||0;v&&w>0&&this.vsyncPanel.update(w,w)}return r}updatePanelComponents(t,r,d,v,C){if(!t||r.logs.length===0)return;t.name in this.lastMin||(this.lastMin[t.name]=1/0,this.lastMax[t.name]=0,this.lastValue[t.name]=0);const w=r.logs[r.logs.length-1];this.lastMax[t.name]=Math.max(...r.logs),this.lastMin[t.name]=Math.min(this.lastMin[t.name],w),this.lastValue[t.name]=this.lastValue[t.name]*.7+w*.3;const E=Math.max(Math.max(...r.logs),...r.graph.slice(-this.samplesGraph));this.updateCounter++,v&&t.update(this.lastValue[t.name],this.lastMax[t.name],d),C&&t.updateGraph(w,E)}beginProfiling(t){if(window.performance)try{window.performance.clearMarks(t),window.performance.mark(t)}catch(r){console.debug("Stats: Performance marking failed:",r)}}endProfiling(t,r,d){if(!(!window.performance||!r||!t))try{window.performance.getEntriesByName(t,"mark").length===0&&this.beginProfiling(t),window.performance.clearMarks(r),window.performance.mark(r),window.performance.clearMeasures(d);const C=performance.measure(d,t,r);this.totalCpuDuration+=C.duration,window.performance.clearMarks(t),window.performance.clearMarks(r),window.performance.clearMeasures(d)}catch(v){console.debug("Stats: Performance measurement failed:",v)}}updatePanel(t,r,d=2){if(!t||r.logs.length===0)return;const v=performance.now();t.name in this.lastMin||(this.lastMin[t.name]=1/0,this.lastMax[t.name]=0,this.lastValue[t.name]=0);const C=r.logs[r.logs.length-1],w=Math.max(...r.logs.slice(-30));this.lastMin[t.name]=Math.min(this.lastMin[t.name],C),this.lastMax[t.name]=Math.max(this.lastMax[t.name],C),this.lastValue[t.name]=this.lastValue[t.name]*.7+C*.3;const E=Math.max(w,...r.graph.slice(-this.samplesGraph));this.updateCounter++,this.updateCounter%(this.logsPerSecond*2)===0&&(this.lastMax[t.name]=w,this.lastMin[t.name]=C),t.update&&(v>=this.prevCpuTime+1e3/this.logsPerSecond&&t.update(this.lastValue[t.name],C,this.lastMax[t.name],E,d),v>=this.prevGraphTime+1e3/this.graphsPerSecond&&(t.updateGraph(C,E),this.prevGraphTime=v))}updateAverages(){this.addToAverage(this.totalCpuDuration,this.averageCpu),this.addToAverage(this.totalGpuDuration,this.averageGpu),this.info&&this.totalGpuDurationCompute!==void 0&&this.addToAverage(this.totalGpuDurationCompute,this.averageGpuCompute)}addToAverage(t,r){r.logs.push(t),r.logs.length>this.samplesLog&&(r.logs=r.logs.slice(-this.samplesLog)),r.graph.push(t),r.graph.length>this.samplesGraph&&(r.graph=r.graph.slice(-this.samplesGraph))}get domElement(){return this.dom}patchThreeWebGPU(t){const r=t.info.reset,d=this;t.info.reset=function(){d.beginProfiling("cpu-started"),r.call(this)}}patchThreeRenderer(t){const r=t.render,d=this;t.render=function(v,C){d.begin(),r.call(this,v,C),d.end()},this.threeRendererPatched=!0}};_Stats.Panel=Panel;let Stats=_Stats;const e={linearSRGB:"srgb-linear",sRGB:"srgb"},a$2={map:e.sRGB,sheenColorMap:e.sRGB,specularColorMap:e.sRGB,emissiveMap:e.sRGB,envMap:e.sRGB};function l$1({node:g,material:t,texture:r}){i$3({node:g,material:t,texture:r}).forEach(n)}function i$3({node:g,material:t,texture:r}){return r?[{map:r}]:t?Array.isArray(t)?t:[t]:g!=null&&g.material?Array.isArray(g.material)?g.material:[g.material]:[]}function n(g){Object.keys(a$2).forEach(t=>{const r=g;r[t]&&(r[t].colorSpace=a$2[t])})}function c$1(g){return Object.prototype.toString.call(g)==="[object Object]"}function f(g){if(c$1(g)===!1)return!1;const t=g.constructor;if(t===void 0)return!0;const r=t.prototype;return!(c$1(r)===!1||r.hasOwnProperty("isPrototypeOf")===!1)}class CSS2DObject extends Object3D{constructor(t=document.createElement("div")){super(),this.isCSS2DObject=!0,this.element=t,this.element.style.position="absolute",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.center=new Vector2(.5,.5),this.addEventListener("removed",function(){this.traverse(function(r){r.element instanceof r.element.ownerDocument.defaultView.Element&&r.element.parentNode!==null&&r.element.remove()})})}copy(t,r){return super.copy(t,r),this.element=t.element.cloneNode(!0),this.center=t.center,this}}new Vector3;new Matrix4;new Matrix4;new Vector3;new Vector3;new Vector3;new Vector3;class CSS3DObject extends Object3D{constructor(t=document.createElement("div")){super(),this.isCSS3DObject=!0,this.element=t,this.element.style.position="absolute",this.element.style.pointerEvents="auto",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.addEventListener("removed",function(){this.traverse(function(r){r.element instanceof r.element.ownerDocument.defaultView.Element&&r.element.parentNode!==null&&r.element.remove()})})}copy(t,r){return super.copy(t,r),this.element=t.element.cloneNode(!0),this}}class CSS3DSprite extends CSS3DObject{constructor(t){super(t),this.isCSS3DSprite=!0,this.rotation2D=0}copy(t,r){return super.copy(t,r),this.rotation2D=t.rotation2D,this}}new Matrix4;new Matrix4;function ascending(g,t){return g==null||t==null?NaN:g<t?-1:g>t?1:g>=t?0:NaN}function descending(g,t){return g==null||t==null?NaN:t<g?-1:t>g?1:t>=g?0:NaN}function bisector(g){let t,r,d;g.length!==2?(t=ascending,r=(E,ye)=>ascending(g(E),ye),d=(E,ye)=>g(E)-ye):(t=g===ascending||g===descending?g:zero$1,r=g,d=g);function v(E,ye,Le=0,Re=E.length){if(Le<Re){if(t(ye,ye)!==0)return Re;do{const Ne=Le+Re>>>1;r(E[Ne],ye)<0?Le=Ne+1:Re=Ne}while(Le<Re)}return Le}function C(E,ye,Le=0,Re=E.length){if(Le<Re){if(t(ye,ye)!==0)return Re;do{const Ne=Le+Re>>>1;r(E[Ne],ye)<=0?Le=Ne+1:Re=Ne}while(Le<Re)}return Le}function w(E,ye,Le=0,Re=E.length){const Ne=v(E,ye,Le,Re-1);return Ne>Le&&d(E[Ne-1],ye)>-d(E[Ne],ye)?Ne-1:Ne}return{left:v,center:w,right:C}}function zero$1(){return 0}function number$1(g){return g===null?NaN:+g}const ascendingBisect=bisector(ascending),bisectRight=ascendingBisect.right;bisector(number$1).center;function extent(g,t){let r,d;if(t===void 0)for(const v of g)v!=null&&(r===void 0?v>=v&&(r=d=v):(r>v&&(r=v),d<v&&(d=v)));else{let v=-1;for(let C of g)(C=t(C,++v,g))!=null&&(r===void 0?C>=C&&(r=d=C):(r>C&&(r=C),d<C&&(d=C)))}return[r,d]}class Adder{constructor(){this._partials=new Float64Array(32),this._n=0}add(t){const r=this._partials;let d=0;for(let v=0;v<this._n&&v<32;v++){const C=r[v],w=t+C,E=Math.abs(t)<Math.abs(C)?t-(w-C):C-(w-t);E&&(r[d++]=E),t=w}return r[d]=t,this._n=d+1,this}valueOf(){const t=this._partials;let r=this._n,d,v,C,w=0;if(r>0){for(w=t[--r];r>0&&(d=w,v=t[--r],w=d+v,C=v-(w-d),!C););r>0&&(C<0&&t[r-1]<0||C>0&&t[r-1]>0)&&(v=C*2,d=w+v,v==d-w&&(w=d))}return w}}const e10=Math.sqrt(50),e5=Math.sqrt(10),e2=Math.sqrt(2);function tickSpec(g,t,r){const d=(t-g)/Math.max(0,r),v=Math.floor(Math.log10(d)),C=d/Math.pow(10,v),w=C>=e10?10:C>=e5?5:C>=e2?2:1;let E,ye,Le;return v<0?(Le=Math.pow(10,-v)/w,E=Math.round(g*Le),ye=Math.round(t*Le),E/Le<g&&++E,ye/Le>t&&--ye,Le=-Le):(Le=Math.pow(10,v)*w,E=Math.round(g/Le),ye=Math.round(t/Le),E*Le<g&&++E,ye*Le>t&&--ye),ye<E&&.5<=r&&r<2?tickSpec(g,t,r*2):[E,ye,Le]}function ticks(g,t,r){if(t=+t,g=+g,r=+r,!(r>0))return[];if(g===t)return[g];const d=t<g,[v,C,w]=d?tickSpec(t,g,r):tickSpec(g,t,r);if(!(C>=v))return[];const E=C-v+1,ye=new Array(E);if(d)if(w<0)for(let Le=0;Le<E;++Le)ye[Le]=(C-Le)/-w;else for(let Le=0;Le<E;++Le)ye[Le]=(C-Le)*w;else if(w<0)for(let Le=0;Le<E;++Le)ye[Le]=(v+Le)/-w;else for(let Le=0;Le<E;++Le)ye[Le]=(v+Le)*w;return ye}function tickIncrement(g,t,r){return t=+t,g=+g,r=+r,tickSpec(g,t,r)[2]}function tickStep(g,t,r){t=+t,g=+g,r=+r;const d=t<g,v=d?tickIncrement(t,g,r):tickIncrement(g,t,r);return(d?-1:1)*(v<0?1/-v:v)}function mean(g,t){let r=0,d=0;if(t===void 0)for(let v of g)v!=null&&(v=+v)>=v&&(++r,d+=v);else{let v=-1;for(let C of g)(C=t(C,++v,g))!=null&&(C=+C)>=C&&(++r,d+=C)}if(r)return d/r}function*flatten$1(g){for(const t of g)yield*Pn(t)}function merge(g){return Array.from(flatten$1(g))}var epsilon$2=1e-6,epsilon2=1e-12,pi$3=Math.PI,halfPi$1=pi$3/2,quarterPi=pi$3/4,tau$1=pi$3*2,degrees$1=180/pi$3,radians$2=pi$3/180,abs=Math.abs,atan$1=Math.atan,atan2$1=Math.atan2,cos$2=Math.cos,exp=Math.exp,hypot=Math.hypot,log=Math.log,sin$1=Math.sin,sign$2=Math.sign||function(g){return g>0?1:g<0?-1:0},sqrt$2=Math.sqrt,tan$1=Math.tan;function acos(g){return g>1?0:g<-1?pi$3:Math.acos(g)}function asin$1(g){return g>1?halfPi$1:g<-1?-halfPi$1:Math.asin(g)}function haversin(g){return(g=sin$1(g/2))*g}function noop(){}function streamGeometry(g,t){g&&streamGeometryType.hasOwnProperty(g.type)&&streamGeometryType[g.type](g,t)}var streamObjectType={Feature:function(g,t){streamGeometry(g.geometry,t)},FeatureCollection:function(g,t){for(var r=g.features,d=-1,v=r.length;++d<v;)streamGeometry(r[d].geometry,t)}},streamGeometryType={Sphere:function(g,t){t.sphere()},Point:function(g,t){g=g.coordinates,t.point(g[0],g[1],g[2])},MultiPoint:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)g=r[d],t.point(g[0],g[1],g[2])},LineString:function(g,t){streamLine(g.coordinates,t,0)},MultiLineString:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)streamLine(r[d],t,0)},Polygon:function(g,t){streamPolygon(g.coordinates,t)},MultiPolygon:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)streamPolygon(r[d],t)},GeometryCollection:function(g,t){for(var r=g.geometries,d=-1,v=r.length;++d<v;)streamGeometry(r[d],t)}};function streamLine(g,t,r){var d=-1,v=g.length-r,C;for(t.lineStart();++d<v;)C=g[d],t.point(C[0],C[1],C[2]);t.lineEnd()}function streamPolygon(g,t){var r=-1,d=g.length;for(t.polygonStart();++r<d;)streamLine(g[r],t,1);t.polygonEnd()}function geoStream(g,t){g&&streamObjectType.hasOwnProperty(g.type)?streamObjectType[g.type](g,t):streamGeometry(g,t)}var areaRingSum=new Adder,areaSum=new Adder,lambda00$2,phi00$2,lambda0$2,cosPhi0$1,sinPhi0$1,areaStream={point:noop,lineStart:noop,lineEnd:noop,polygonStart:function(){areaRingSum=new Adder,areaStream.lineStart=areaRingStart,areaStream.lineEnd=areaRingEnd},polygonEnd:function(){var g=+areaRingSum;areaSum.add(g<0?tau$1+g:g),this.lineStart=this.lineEnd=this.point=noop},sphere:function(){areaSum.add(tau$1)}};function areaRingStart(){areaStream.point=areaPointFirst}function areaRingEnd(){areaPoint(lambda00$2,phi00$2)}function areaPointFirst(g,t){areaStream.point=areaPoint,lambda00$2=g,phi00$2=t,g*=radians$2,t*=radians$2,lambda0$2=g,cosPhi0$1=cos$2(t=t/2+quarterPi),sinPhi0$1=sin$1(t)}function areaPoint(g,t){g*=radians$2,t*=radians$2,t=t/2+quarterPi;var r=g-lambda0$2,d=r>=0?1:-1,v=d*r,C=cos$2(t),w=sin$1(t),E=sinPhi0$1*w,ye=cosPhi0$1*C+E*cos$2(v),Le=E*d*sin$1(v);areaRingSum.add(atan2$1(Le,ye)),lambda0$2=g,cosPhi0$1=C,sinPhi0$1=w}function spherical$1(g){return[atan2$1(g[1],g[0]),asin$1(g[2])]}function cartesian$1(g){var t=g[0],r=g[1],d=cos$2(r);return[d*cos$2(t),d*sin$1(t),sin$1(r)]}function cartesianDot$1(g,t){return g[0]*t[0]+g[1]*t[1]+g[2]*t[2]}function cartesianCross$1(g,t){return[g[1]*t[2]-g[2]*t[1],g[2]*t[0]-g[0]*t[2],g[0]*t[1]-g[1]*t[0]]}function cartesianAddInPlace(g,t){g[0]+=t[0],g[1]+=t[1],g[2]+=t[2]}function cartesianScale(g,t){return[g[0]*t,g[1]*t,g[2]*t]}function cartesianNormalizeInPlace(g){var t=sqrt$2(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]);g[0]/=t,g[1]/=t,g[2]/=t}var lambda0$1,phi0,lambda1,phi1,lambda2,lambda00$1,phi00$1,p0,deltaSum,ranges,range,boundsStream$1={point:boundsPoint$1,lineStart:boundsLineStart,lineEnd:boundsLineEnd,polygonStart:function(){boundsStream$1.point=boundsRingPoint,boundsStream$1.lineStart=boundsRingStart,boundsStream$1.lineEnd=boundsRingEnd,deltaSum=new Adder,areaStream.polygonStart()},polygonEnd:function(){areaStream.polygonEnd(),boundsStream$1.point=boundsPoint$1,boundsStream$1.lineStart=boundsLineStart,boundsStream$1.lineEnd=boundsLineEnd,areaRingSum<0?(lambda0$1=-(lambda1=180),phi0=-(phi1=90)):deltaSum>epsilon$2?phi1=90:deltaSum<-epsilon$2&&(phi0=-90),range[0]=lambda0$1,range[1]=lambda1},sphere:function(){lambda0$1=-(lambda1=180),phi0=-(phi1=90)}};function boundsPoint$1(g,t){ranges.push(range=[lambda0$1=g,lambda1=g]),t<phi0&&(phi0=t),t>phi1&&(phi1=t)}function linePoint(g,t){var r=cartesian$1([g*radians$2,t*radians$2]);if(p0){var d=cartesianCross$1(p0,r),v=[d[1],-d[0],0],C=cartesianCross$1(v,d);cartesianNormalizeInPlace(C),C=spherical$1(C);var w=g-lambda2,E=w>0?1:-1,ye=C[0]*degrees$1*E,Le,Re=abs(w)>180;Re^(E*lambda2<ye&&ye<E*g)?(Le=C[1]*degrees$1,Le>phi1&&(phi1=Le)):(ye=(ye+360)%360-180,Re^(E*lambda2<ye&&ye<E*g)?(Le=-C[1]*degrees$1,Le<phi0&&(phi0=Le)):(t<phi0&&(phi0=t),t>phi1&&(phi1=t))),Re?g<lambda2?angle(lambda0$1,g)>angle(lambda0$1,lambda1)&&(lambda1=g):angle(g,lambda1)>angle(lambda0$1,lambda1)&&(lambda0$1=g):lambda1>=lambda0$1?(g<lambda0$1&&(lambda0$1=g),g>lambda1&&(lambda1=g)):g>lambda2?angle(lambda0$1,g)>angle(lambda0$1,lambda1)&&(lambda1=g):angle(g,lambda1)>angle(lambda0$1,lambda1)&&(lambda0$1=g)}else ranges.push(range=[lambda0$1=g,lambda1=g]);t<phi0&&(phi0=t),t>phi1&&(phi1=t),p0=r,lambda2=g}function boundsLineStart(){boundsStream$1.point=linePoint}function boundsLineEnd(){range[0]=lambda0$1,range[1]=lambda1,boundsStream$1.point=boundsPoint$1,p0=null}function boundsRingPoint(g,t){if(p0){var r=g-lambda2;deltaSum.add(abs(r)>180?r+(r>0?360:-360):r)}else lambda00$1=g,phi00$1=t;areaStream.point(g,t),linePoint(g,t)}function boundsRingStart(){areaStream.lineStart()}function boundsRingEnd(){boundsRingPoint(lambda00$1,phi00$1),areaStream.lineEnd(),abs(deltaSum)>epsilon$2&&(lambda0$1=-(lambda1=180)),range[0]=lambda0$1,range[1]=lambda1,p0=null}function angle(g,t){return(t-=g)<0?t+360:t}function rangeCompare(g,t){return g[0]-t[0]}function rangeContains(g,t){return g[0]<=g[1]?g[0]<=t&&t<=g[1]:t<g[0]||g[1]<t}function wt(g){var t,r,d,v,C,w,E;if(phi1=lambda1=-(lambda0$1=phi0=1/0),ranges=[],geoStream(g,boundsStream$1),r=ranges.length){for(ranges.sort(rangeCompare),t=1,d=ranges[0],C=[d];t<r;++t)v=ranges[t],rangeContains(d,v[0])||rangeContains(d,v[1])?(angle(d[0],v[1])>angle(d[0],d[1])&&(d[1]=v[1]),angle(v[0],d[1])>angle(d[0],d[1])&&(d[0]=v[0])):C.push(d=v);for(w=-1/0,r=C.length-1,t=0,d=C[r];t<=r;d=v,++t)v=C[t],(E=angle(d[1],v[0]))>w&&(w=E,lambda0$1=v[0],lambda1=d[1])}return ranges=range=null,lambda0$1===1/0||phi0===1/0?[[NaN,NaN],[NaN,NaN]]:[[lambda0$1,phi0],[lambda1,phi1]]}var W0,W1,X0,Y0,Z0,X1,Y1,Z1,X2,Y2,Z2,lambda00,phi00,x0$1,y0$1,z0,centroidStream={sphere:noop,point:centroidPoint,lineStart:centroidLineStart,lineEnd:centroidLineEnd,polygonStart:function(){centroidStream.lineStart=centroidRingStart,centroidStream.lineEnd=centroidRingEnd},polygonEnd:function(){centroidStream.lineStart=centroidLineStart,centroidStream.lineEnd=centroidLineEnd}};function centroidPoint(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t);centroidPointCartesian(r*cos$2(g),r*sin$1(g),sin$1(t))}function centroidPointCartesian(g,t,r){++W0,X0+=(g-X0)/W0,Y0+=(t-Y0)/W0,Z0+=(r-Z0)/W0}function centroidLineStart(){centroidStream.point=centroidLinePointFirst}function centroidLinePointFirst(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t);x0$1=r*cos$2(g),y0$1=r*sin$1(g),z0=sin$1(t),centroidStream.point=centroidLinePoint,centroidPointCartesian(x0$1,y0$1,z0)}function centroidLinePoint(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t),d=r*cos$2(g),v=r*sin$1(g),C=sin$1(t),w=atan2$1(sqrt$2((w=y0$1*C-z0*v)*w+(w=z0*d-x0$1*C)*w+(w=x0$1*v-y0$1*d)*w),x0$1*d+y0$1*v+z0*C);W1+=w,X1+=w*(x0$1+(x0$1=d)),Y1+=w*(y0$1+(y0$1=v)),Z1+=w*(z0+(z0=C)),centroidPointCartesian(x0$1,y0$1,z0)}function centroidLineEnd(){centroidStream.point=centroidPoint}function centroidRingStart(){centroidStream.point=centroidRingPointFirst}function centroidRingEnd(){centroidRingPoint(lambda00,phi00),centroidStream.point=centroidPoint}function centroidRingPointFirst(g,t){lambda00=g,phi00=t,g*=radians$2,t*=radians$2,centroidStream.point=centroidRingPoint;var r=cos$2(t);x0$1=r*cos$2(g),y0$1=r*sin$1(g),z0=sin$1(t),centroidPointCartesian(x0$1,y0$1,z0)}function centroidRingPoint(g,t){g*=radians$2,t*=radians$2;var r=cos$2(t),d=r*cos$2(g),v=r*sin$1(g),C=sin$1(t),w=y0$1*C-z0*v,E=z0*d-x0$1*C,ye=x0$1*v-y0$1*d,Le=hypot(w,E,ye),Re=asin$1(Le),Ne=Le&&-Re/Le;X2.add(Ne*w),Y2.add(Ne*E),Z2.add(Ne*ye),W1+=Re,X1+=Re*(x0$1+(x0$1=d)),Y1+=Re*(y0$1+(y0$1=v)),Z1+=Re*(z0+(z0=C)),centroidPointCartesian(x0$1,y0$1,z0)}function geoCentroid(g){W0=W1=X0=Y0=Z0=X1=Y1=Z1=0,X2=new Adder,Y2=new Adder,Z2=new Adder,geoStream(g,centroidStream);var t=+X2,r=+Y2,d=+Z2,v=hypot(t,r,d);return v<epsilon2&&(t=X1,r=Y1,d=Z1,W1<epsilon$2&&(t=X0,r=Y0,d=Z0),v=hypot(t,r,d),v<epsilon2)?[NaN,NaN]:[atan2$1(r,t)*degrees$1,asin$1(d/v)*degrees$1]}function compose(g,t){function r(d,v){return d=g(d,v),t(d[0],d[1])}return g.invert&&t.invert&&(r.invert=function(d,v){return d=t.invert(d,v),d&&g.invert(d[0],d[1])}),r}function rotationIdentity(g,t){return abs(g)>pi$3&&(g-=Math.round(g/tau$1)*tau$1),[g,t]}rotationIdentity.invert=rotationIdentity;function rotateRadians(g,t,r){return(g%=tau$1)?t||r?compose(rotationLambda(g),rotationPhiGamma(t,r)):rotationLambda(g):t||r?rotationPhiGamma(t,r):rotationIdentity}function forwardRotationLambda(g){return function(t,r){return t+=g,abs(t)>pi$3&&(t-=Math.round(t/tau$1)*tau$1),[t,r]}}function rotationLambda(g){var t=forwardRotationLambda(g);return t.invert=forwardRotationLambda(-g),t}function rotationPhiGamma(g,t){var r=cos$2(g),d=sin$1(g),v=cos$2(t),C=sin$1(t);function w(E,ye){var Le=cos$2(ye),Re=cos$2(E)*Le,Ne=sin$1(E)*Le,Fe=sin$1(ye),at=Fe*r+Re*d;return[atan2$1(Ne*v-at*C,Re*r-Fe*d),asin$1(at*v+Ne*C)]}return w.invert=function(E,ye){var Le=cos$2(ye),Re=cos$2(E)*Le,Ne=sin$1(E)*Le,Fe=sin$1(ye),at=Fe*v-Ne*C;return[atan2$1(Ne*v+Fe*C,Re*r+at*d),asin$1(at*r-Re*d)]},w}function geoRotation(g){g=rotateRadians(g[0]*radians$2,g[1]*radians$2,g.length>2?g[2]*radians$2:0);function t(r){return r=g(r[0]*radians$2,r[1]*radians$2),r[0]*=degrees$1,r[1]*=degrees$1,r}return t.invert=function(r){return r=g.invert(r[0]*radians$2,r[1]*radians$2),r[0]*=degrees$1,r[1]*=degrees$1,r},t}function circleStream(g,t,r,d,v,C){if(r){var w=cos$2(t),E=sin$1(t),ye=d*r;v==null?(v=t+d*tau$1,C=t-ye/2):(v=circleRadius(w,v),C=circleRadius(w,C),(d>0?v<C:v>C)&&(v+=d*tau$1));for(var Le,Re=v;d>0?Re>C:Re<C;Re-=ye)Le=spherical$1([w,-E*cos$2(Re),-E*sin$1(Re)]),g.point(Le[0],Le[1])}}function circleRadius(g,t){t=cartesian$1(t),t[0]-=g,cartesianNormalizeInPlace(t);var r=acos(-t[1]);return((-t[2]<0?-r:r)+tau$1-epsilon$2)%tau$1}function clipBuffer(){var g=[],t;return{point:function(r,d,v){t.push([r,d,v])},lineStart:function(){g.push(t=[])},lineEnd:noop,rejoin:function(){g.length>1&&g.push(g.pop().concat(g.shift()))},result:function(){var r=g;return g=[],t=null,r}}}function pointEqual(g,t){return abs(g[0]-t[0])<epsilon$2&&abs(g[1]-t[1])<epsilon$2}function Intersection(g,t,r,d){this.x=g,this.z=t,this.o=r,this.e=d,this.v=!1,this.n=this.p=null}function clipRejoin(g,t,r,d,v){var C=[],w=[],E,ye;if(g.forEach(function(ot){if(!((Gt=ot.length-1)<=0)){var Gt,ht=ot[0],ke=ot[Gt],ct;if(pointEqual(ht,ke)){if(!ht[2]&&!ke[2]){for(v.lineStart(),E=0;E<Gt;++E)v.point((ht=ot[E])[0],ht[1]);v.lineEnd();return}ke[0]+=2*epsilon$2}C.push(ct=new Intersection(ht,ot,null,!0)),w.push(ct.o=new Intersection(ht,null,ct,!1)),C.push(ct=new Intersection(ke,ot,null,!1)),w.push(ct.o=new Intersection(ke,null,ct,!0))}}),!!C.length){for(w.sort(t),link(C),link(w),E=0,ye=w.length;E<ye;++E)w[E].e=r=!r;for(var Le=C[0],Re,Ne;;){for(var Fe=Le,at=!0;Fe.v;)if((Fe=Fe.n)===Le)return;Re=Fe.z,v.lineStart();do{if(Fe.v=Fe.o.v=!0,Fe.e){if(at)for(E=0,ye=Re.length;E<ye;++E)v.point((Ne=Re[E])[0],Ne[1]);else d(Fe.x,Fe.n.x,1,v);Fe=Fe.n}else{if(at)for(Re=Fe.p.z,E=Re.length-1;E>=0;--E)v.point((Ne=Re[E])[0],Ne[1]);else d(Fe.x,Fe.p.x,-1,v);Fe=Fe.p}Fe=Fe.o,Re=Fe.z,at=!at}while(!Fe.v);v.lineEnd()}}}function link(g){if(t=g.length){for(var t,r=0,d=g[0],v;++r<t;)d.n=v=g[r],v.p=d,d=v;d.n=v=g[0],v.p=d}}function longitude(g){return abs(g[0])<=pi$3?g[0]:sign$2(g[0])*((abs(g[0])+pi$3)%tau$1-pi$3)}function polygonContains(g,t){var r=longitude(t),d=t[1],v=sin$1(d),C=[sin$1(r),-cos$2(r),0],w=0,E=0,ye=new Adder;v===1?d=halfPi$1+epsilon$2:v===-1&&(d=-halfPi$1-epsilon$2);for(var Le=0,Re=g.length;Le<Re;++Le)if(Fe=(Ne=g[Le]).length)for(var Ne,Fe,at=Ne[Fe-1],ot=longitude(at),Gt=at[1]/2+quarterPi,ht=sin$1(Gt),ke=cos$2(Gt),ct=0;ct<Fe;++ct,ot=Rt,ht=Pt,ke=Nt,at=xt){var xt=Ne[ct],Rt=longitude(xt),Wt=xt[1]/2+quarterPi,Pt=sin$1(Wt),Nt=cos$2(Wt),Kt=Rt-ot,Ft=Kt>=0?1:-1,kt=Ft*Kt,Yt=kt>pi$3,s0=ht*Pt;if(ye.add(atan2$1(s0*Ft*sin$1(kt),ke*Nt+s0*cos$2(kt))),w+=Yt?Kt+Ft*tau$1:Kt,Yt^ot>=r^Rt>=r){var o0=cartesianCross$1(cartesian$1(at),cartesian$1(xt));cartesianNormalizeInPlace(o0);var h0=cartesianCross$1(C,o0);cartesianNormalizeInPlace(h0);var r0=(Yt^Kt>=0?-1:1)*asin$1(h0[2]);(d>r0||d===r0&&(o0[0]||o0[1]))&&(E+=Yt^Kt>=0?1:-1)}}return(w<-epsilon$2||w<epsilon$2&&ye<-epsilon2)^E&1}function clip(g,t,r,d){return function(v){var C=t(v),w=clipBuffer(),E=t(w),ye=!1,Le,Re,Ne,Fe={point:at,lineStart:Gt,lineEnd:ht,polygonStart:function(){Fe.point=ke,Fe.lineStart=ct,Fe.lineEnd=xt,Re=[],Le=[]},polygonEnd:function(){Fe.point=at,Fe.lineStart=Gt,Fe.lineEnd=ht,Re=merge(Re);var Rt=polygonContains(Le,d);Re.length?(ye||(v.polygonStart(),ye=!0),clipRejoin(Re,compareIntersection,Rt,r,v)):Rt&&(ye||(v.polygonStart(),ye=!0),v.lineStart(),r(null,null,1,v),v.lineEnd()),ye&&(v.polygonEnd(),ye=!1),Re=Le=null},sphere:function(){v.polygonStart(),v.lineStart(),r(null,null,1,v),v.lineEnd(),v.polygonEnd()}};function at(Rt,Wt){g(Rt,Wt)&&v.point(Rt,Wt)}function ot(Rt,Wt){C.point(Rt,Wt)}function Gt(){Fe.point=ot,C.lineStart()}function ht(){Fe.point=at,C.lineEnd()}function ke(Rt,Wt){Ne.push([Rt,Wt]),E.point(Rt,Wt)}function ct(){E.lineStart(),Ne=[]}function xt(){ke(Ne[0][0],Ne[0][1]),E.lineEnd();var Rt=E.clean(),Wt=w.result(),Pt,Nt=Wt.length,Kt,Ft,kt;if(Ne.pop(),Le.push(Ne),Ne=null,!!Nt){if(Rt&1){if(Ft=Wt[0],(Kt=Ft.length-1)>0){for(ye||(v.polygonStart(),ye=!0),v.lineStart(),Pt=0;Pt<Kt;++Pt)v.point((kt=Ft[Pt])[0],kt[1]);v.lineEnd()}return}Nt>1&&Rt&2&&Wt.push(Wt.pop().concat(Wt.shift())),Re.push(Wt.filter(validSegment))}}return Fe}}function validSegment(g){return g.length>1}function compareIntersection(g,t){return((g=g.x)[0]<0?g[1]-halfPi$1-epsilon$2:halfPi$1-g[1])-((t=t.x)[0]<0?t[1]-halfPi$1-epsilon$2:halfPi$1-t[1])}const clipAntimeridian=clip(function(){return!0},clipAntimeridianLine,clipAntimeridianInterpolate,[-pi$3,-halfPi$1]);function clipAntimeridianLine(g){var t=NaN,r=NaN,d=NaN,v;return{lineStart:function(){g.lineStart(),v=1},point:function(C,w){var E=C>0?pi$3:-pi$3,ye=abs(C-t);abs(ye-pi$3)<epsilon$2?(g.point(t,r=(r+w)/2>0?halfPi$1:-halfPi$1),g.point(d,r),g.lineEnd(),g.lineStart(),g.point(E,r),g.point(C,r),v=0):d!==E&&ye>=pi$3&&(abs(t-d)<epsilon$2&&(t-=d*epsilon$2),abs(C-E)<epsilon$2&&(C-=E*epsilon$2),r=clipAntimeridianIntersect(t,r,C,w),g.point(d,r),g.lineEnd(),g.lineStart(),g.point(E,r),v=0),g.point(t=C,r=w),d=E},lineEnd:function(){g.lineEnd(),t=r=NaN},clean:function(){return 2-v}}}function clipAntimeridianIntersect(g,t,r,d){var v,C,w=sin$1(g-r);return abs(w)>epsilon$2?atan$1((sin$1(t)*(C=cos$2(d))*sin$1(r)-sin$1(d)*(v=cos$2(t))*sin$1(g))/(v*C*w)):(t+d)/2}function clipAntimeridianInterpolate(g,t,r,d){var v;if(g==null)v=r*halfPi$1,d.point(-pi$3,v),d.point(0,v),d.point(pi$3,v),d.point(pi$3,0),d.point(pi$3,-v),d.point(0,-v),d.point(-pi$3,-v),d.point(-pi$3,0),d.point(-pi$3,v);else if(abs(g[0]-t[0])>epsilon$2){var C=g[0]<t[0]?pi$3:-pi$3;v=r*C/2,d.point(-C,v),d.point(0,v),d.point(C,v)}else d.point(t[0],t[1])}function clipCircle(g){var t=cos$2(g),r=2*radians$2,d=t>0,v=abs(t)>epsilon$2;function C(Re,Ne,Fe,at){circleStream(at,g,r,Fe,Re,Ne)}function w(Re,Ne){return cos$2(Re)*cos$2(Ne)>t}function E(Re){var Ne,Fe,at,ot,Gt;return{lineStart:function(){ot=at=!1,Gt=1},point:function(ht,ke){var ct=[ht,ke],xt,Rt=w(ht,ke),Wt=d?Rt?0:Le(ht,ke):Rt?Le(ht+(ht<0?pi$3:-pi$3),ke):0;if(!Ne&&(ot=at=Rt)&&Re.lineStart(),Rt!==at&&(xt=ye(Ne,ct),(!xt||pointEqual(Ne,xt)||pointEqual(ct,xt))&&(ct[2]=1)),Rt!==at)Gt=0,Rt?(Re.lineStart(),xt=ye(ct,Ne),Re.point(xt[0],xt[1])):(xt=ye(Ne,ct),Re.point(xt[0],xt[1],2),Re.lineEnd()),Ne=xt;else if(v&&Ne&&d^Rt){var Pt;!(Wt&Fe)&&(Pt=ye(ct,Ne,!0))&&(Gt=0,d?(Re.lineStart(),Re.point(Pt[0][0],Pt[0][1]),Re.point(Pt[1][0],Pt[1][1]),Re.lineEnd()):(Re.point(Pt[1][0],Pt[1][1]),Re.lineEnd(),Re.lineStart(),Re.point(Pt[0][0],Pt[0][1],3)))}Rt&&(!Ne||!pointEqual(Ne,ct))&&Re.point(ct[0],ct[1]),Ne=ct,at=Rt,Fe=Wt},lineEnd:function(){at&&Re.lineEnd(),Ne=null},clean:function(){return Gt|(ot&&at)<<1}}}function ye(Re,Ne,Fe){var at=cartesian$1(Re),ot=cartesian$1(Ne),Gt=[1,0,0],ht=cartesianCross$1(at,ot),ke=cartesianDot$1(ht,ht),ct=ht[0],xt=ke-ct*ct;if(!xt)return!Fe&&Re;var Rt=t*ke/xt,Wt=-t*ct/xt,Pt=cartesianCross$1(Gt,ht),Nt=cartesianScale(Gt,Rt),Kt=cartesianScale(ht,Wt);cartesianAddInPlace(Nt,Kt);var Ft=Pt,kt=cartesianDot$1(Nt,Ft),Yt=cartesianDot$1(Ft,Ft),s0=kt*kt-Yt*(cartesianDot$1(Nt,Nt)-1);if(!(s0<0)){var o0=sqrt$2(s0),h0=cartesianScale(Ft,(-kt-o0)/Yt);if(cartesianAddInPlace(h0,Nt),h0=spherical$1(h0),!Fe)return h0;var r0=Re[0],e0=Ne[0],i0=Re[1],Ut=Ne[1],l0;e0<r0&&(l0=r0,r0=e0,e0=l0);var S0=e0-r0,g0=abs(S0-pi$3)<epsilon$2,I0=g0||S0<epsilon$2;if(!g0&&Ut<i0&&(l0=i0,i0=Ut,Ut=l0),I0?g0?i0+Ut>0^h0[1]<(abs(h0[0]-r0)<epsilon$2?i0:Ut):i0<=h0[1]&&h0[1]<=Ut:S0>pi$3^(r0<=h0[0]&&h0[0]<=e0)){var fi=cartesianScale(Ft,(-kt+o0)/Yt);return cartesianAddInPlace(fi,Nt),[h0,spherical$1(fi)]}}}function Le(Re,Ne){var Fe=d?g:pi$3-g,at=0;return Re<-Fe?at|=1:Re>Fe&&(at|=2),Ne<-Fe?at|=4:Ne>Fe&&(at|=8),at}return clip(w,E,C,d?[0,-g]:[-pi$3,g-pi$3])}function clipLine(g,t,r,d,v,C){var w=g[0],E=g[1],ye=t[0],Le=t[1],Re=0,Ne=1,Fe=ye-w,at=Le-E,ot;if(ot=r-w,!(!Fe&&ot>0)){if(ot/=Fe,Fe<0){if(ot<Re)return;ot<Ne&&(Ne=ot)}else if(Fe>0){if(ot>Ne)return;ot>Re&&(Re=ot)}if(ot=v-w,!(!Fe&&ot<0)){if(ot/=Fe,Fe<0){if(ot>Ne)return;ot>Re&&(Re=ot)}else if(Fe>0){if(ot<Re)return;ot<Ne&&(Ne=ot)}if(ot=d-E,!(!at&&ot>0)){if(ot/=at,at<0){if(ot<Re)return;ot<Ne&&(Ne=ot)}else if(at>0){if(ot>Ne)return;ot>Re&&(Re=ot)}if(ot=C-E,!(!at&&ot<0)){if(ot/=at,at<0){if(ot>Ne)return;ot>Re&&(Re=ot)}else if(at>0){if(ot<Re)return;ot<Ne&&(Ne=ot)}return Re>0&&(g[0]=w+Re*Fe,g[1]=E+Re*at),Ne<1&&(t[0]=w+Ne*Fe,t[1]=E+Ne*at),!0}}}}}var clipMax=1e9,clipMin=-clipMax;function clipRectangle(g,t,r,d){function v(Le,Re){return g<=Le&&Le<=r&&t<=Re&&Re<=d}function C(Le,Re,Ne,Fe){var at=0,ot=0;if(Le==null||(at=w(Le,Ne))!==(ot=w(Re,Ne))||ye(Le,Re)<0^Ne>0)do Fe.point(at===0||at===3?g:r,at>1?d:t);while((at=(at+Ne+4)%4)!==ot);else Fe.point(Re[0],Re[1])}function w(Le,Re){return abs(Le[0]-g)<epsilon$2?Re>0?0:3:abs(Le[0]-r)<epsilon$2?Re>0?2:1:abs(Le[1]-t)<epsilon$2?Re>0?1:0:Re>0?3:2}function E(Le,Re){return ye(Le.x,Re.x)}function ye(Le,Re){var Ne=w(Le,1),Fe=w(Re,1);return Ne!==Fe?Ne-Fe:Ne===0?Re[1]-Le[1]:Ne===1?Le[0]-Re[0]:Ne===2?Le[1]-Re[1]:Re[0]-Le[0]}return function(Le){var Re=Le,Ne=clipBuffer(),Fe,at,ot,Gt,ht,ke,ct,xt,Rt,Wt,Pt,Nt={point:Kt,lineStart:s0,lineEnd:o0,polygonStart:kt,polygonEnd:Yt};function Kt(r0,e0){v(r0,e0)&&Re.point(r0,e0)}function Ft(){for(var r0=0,e0=0,i0=at.length;e0<i0;++e0)for(var Ut=at[e0],l0=1,S0=Ut.length,g0=Ut[0],I0,fi,L0=g0[0],K0=g0[1];l0<S0;++l0)I0=L0,fi=K0,g0=Ut[l0],L0=g0[0],K0=g0[1],fi<=d?K0>d&&(L0-I0)*(d-fi)>(K0-fi)*(g-I0)&&++r0:K0<=d&&(L0-I0)*(d-fi)<(K0-fi)*(g-I0)&&--r0;return r0}function kt(){Re=Ne,Fe=[],at=[],Pt=!0}function Yt(){var r0=Ft(),e0=Pt&&r0,i0=(Fe=merge(Fe)).length;(e0||i0)&&(Le.polygonStart(),e0&&(Le.lineStart(),C(null,null,1,Le),Le.lineEnd()),i0&&clipRejoin(Fe,E,r0,C,Le),Le.polygonEnd()),Re=Le,Fe=at=ot=null}function s0(){Nt.point=h0,at&&at.push(ot=[]),Wt=!0,Rt=!1,ct=xt=NaN}function o0(){Fe&&(h0(Gt,ht),ke&&Rt&&Ne.rejoin(),Fe.push(Ne.result())),Nt.point=Kt,Rt&&Re.lineEnd()}function h0(r0,e0){var i0=v(r0,e0);if(at&&ot.push([r0,e0]),Wt)Gt=r0,ht=e0,ke=i0,Wt=!1,i0&&(Re.lineStart(),Re.point(r0,e0));else if(i0&&Rt)Re.point(r0,e0);else{var Ut=[ct=Math.max(clipMin,Math.min(clipMax,ct)),xt=Math.max(clipMin,Math.min(clipMax,xt))],l0=[r0=Math.max(clipMin,Math.min(clipMax,r0)),e0=Math.max(clipMin,Math.min(clipMax,e0))];clipLine(Ut,l0,g,t,r,d)?(Rt||(Re.lineStart(),Re.point(Ut[0],Ut[1])),Re.point(l0[0],l0[1]),i0||Re.lineEnd(),Pt=!1):i0&&(Re.lineStart(),Re.point(r0,e0),Pt=!1)}ct=r0,xt=e0,Rt=i0}return Nt}}var lengthSum,lambda0,sinPhi0,cosPhi0,lengthStream={sphere:noop,point:noop,lineStart:lengthLineStart,lineEnd:noop,polygonStart:noop,polygonEnd:noop};function lengthLineStart(){lengthStream.point=lengthPointFirst,lengthStream.lineEnd=lengthLineEnd}function lengthLineEnd(){lengthStream.point=lengthStream.lineEnd=noop}function lengthPointFirst(g,t){g*=radians$2,t*=radians$2,lambda0=g,sinPhi0=sin$1(t),cosPhi0=cos$2(t),lengthStream.point=lengthPoint}function lengthPoint(g,t){g*=radians$2,t*=radians$2;var r=sin$1(t),d=cos$2(t),v=abs(g-lambda0),C=cos$2(v),w=sin$1(v),E=d*w,ye=cosPhi0*r-sinPhi0*d*C,Le=sinPhi0*r+cosPhi0*d*C;lengthSum.add(atan2$1(sqrt$2(E*E+ye*ye),Le)),lambda0=g,sinPhi0=r,cosPhi0=d}function length(g){return lengthSum=new Adder,geoStream(g,lengthStream),+lengthSum}var coordinates=[null,null],object$1={type:"LineString",coordinates};function $t(g,t){return coordinates[0]=g,coordinates[1]=t,length(object$1)}var containsObjectType={Feature:function(g,t){return containsGeometry(g.geometry,t)},FeatureCollection:function(g,t){for(var r=g.features,d=-1,v=r.length;++d<v;)if(containsGeometry(r[d].geometry,t))return!0;return!1}},containsGeometryType={Sphere:function(){return!0},Point:function(g,t){return containsPoint(g.coordinates,t)},MultiPoint:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)if(containsPoint(r[d],t))return!0;return!1},LineString:function(g,t){return containsLine(g.coordinates,t)},MultiLineString:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)if(containsLine(r[d],t))return!0;return!1},Polygon:function(g,t){return containsPolygon(g.coordinates,t)},MultiPolygon:function(g,t){for(var r=g.coordinates,d=-1,v=r.length;++d<v;)if(containsPolygon(r[d],t))return!0;return!1},GeometryCollection:function(g,t){for(var r=g.geometries,d=-1,v=r.length;++d<v;)if(containsGeometry(r[d],t))return!0;return!1}};function containsGeometry(g,t){return g&&containsGeometryType.hasOwnProperty(g.type)?containsGeometryType[g.type](g,t):!1}function containsPoint(g,t){return $t(g,t)===0}function containsLine(g,t){for(var r,d,v,C=0,w=g.length;C<w;C++){if(d=$t(g[C],t),d===0||C>0&&(v=$t(g[C],g[C-1]),v>0&&r<=v&&d<=v&&(r+d-v)*(1-Math.pow((r-d)/v,2))<epsilon2*v))return!0;r=d}return!1}function containsPolygon(g,t){return!!polygonContains(g.map(ringRadians),pointRadians(t))}function ringRadians(g){return g=g.map(pointRadians),g.pop(),g}function pointRadians(g){return[g[0]*radians$2,g[1]*radians$2]}function Zt(g,t){return(g&&containsObjectType.hasOwnProperty(g.type)?containsObjectType[g.type]:containsGeometry)(g,t)}function qt(g,t){var r=g[0]*radians$2,d=g[1]*radians$2,v=t[0]*radians$2,C=t[1]*radians$2,w=cos$2(d),E=sin$1(d),ye=cos$2(C),Le=sin$1(C),Re=w*cos$2(r),Ne=w*sin$1(r),Fe=ye*cos$2(v),at=ye*sin$1(v),ot=2*asin$1(sqrt$2(haversin(C-d)+w*ye*haversin(v-r))),Gt=sin$1(ot),ht=ot?function(ke){var ct=sin$1(ke*=ot)/Gt,xt=sin$1(ot-ke)/Gt,Rt=xt*Re+ct*Fe,Wt=xt*Ne+ct*at,Pt=xt*E+ct*Le;return[atan2$1(Wt,Rt)*degrees$1,atan2$1(Pt,sqrt$2(Rt*Rt+Wt*Wt))*degrees$1]}:function(){return[r*degrees$1,d*degrees$1]};return ht.distance=ot,ht}const identity$2=g=>g;var x0=1/0,y0=x0,x1=-x0,y1=x1,boundsStream={point:boundsPoint,lineStart:noop,lineEnd:noop,polygonStart:noop,polygonEnd:noop,result:function(){var g=[[x0,y0],[x1,y1]];return x1=y1=-(y0=x0=1/0),g}};function boundsPoint(g,t){g<x0&&(x0=g),g>x1&&(x1=g),t<y0&&(y0=t),t>y1&&(y1=t)}function transformer$1(g){return function(t){var r=new TransformStream;for(var d in g)r[d]=g[d];return r.stream=t,r}}function TransformStream(){}TransformStream.prototype={constructor:TransformStream,point:function(g,t){this.stream.point(g,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function fit(g,t,r){var d=g.clipExtent&&g.clipExtent();return g.scale(150).translate([0,0]),d!=null&&g.clipExtent(null),geoStream(r,g.stream(boundsStream)),t(boundsStream.result()),d!=null&&g.clipExtent(d),g}function fitExtent(g,t,r){return fit(g,function(d){var v=t[1][0]-t[0][0],C=t[1][1]-t[0][1],w=Math.min(v/(d[1][0]-d[0][0]),C/(d[1][1]-d[0][1])),E=+t[0][0]+(v-w*(d[1][0]+d[0][0]))/2,ye=+t[0][1]+(C-w*(d[1][1]+d[0][1]))/2;g.scale(150*w).translate([E,ye])},r)}function fitSize(g,t,r){return fitExtent(g,[[0,0],t],r)}function fitWidth(g,t,r){return fit(g,function(d){var v=+t,C=v/(d[1][0]-d[0][0]),w=(v-C*(d[1][0]+d[0][0]))/2,E=-C*d[0][1];g.scale(150*C).translate([w,E])},r)}function fitHeight(g,t,r){return fit(g,function(d){var v=+t,C=v/(d[1][1]-d[0][1]),w=-C*d[0][0],E=(v-C*(d[1][1]+d[0][1]))/2;g.scale(150*C).translate([w,E])},r)}var maxDepth=16,cosMinDistance=cos$2(30*radians$2);function resample(g,t){return+t?resample$1(g,t):resampleNone(g)}function resampleNone(g){return transformer$1({point:function(t,r){t=g(t,r),this.stream.point(t[0],t[1])}})}function resample$1(g,t){function r(d,v,C,w,E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht){var ke=Le-d,ct=Re-v,xt=ke*ke+ct*ct;if(xt>4*t&&Gt--){var Rt=w+Fe,Wt=E+at,Pt=ye+ot,Nt=sqrt$2(Rt*Rt+Wt*Wt+Pt*Pt),Kt=asin$1(Pt/=Nt),Ft=abs(abs(Pt)-1)<epsilon$2||abs(C-Ne)<epsilon$2?(C+Ne)/2:atan2$1(Wt,Rt),kt=g(Ft,Kt),Yt=kt[0],s0=kt[1],o0=Yt-d,h0=s0-v,r0=ct*o0-ke*h0;(r0*r0/xt>t||abs((ke*o0+ct*h0)/xt-.5)>.3||w*Fe+E*at+ye*ot<cosMinDistance)&&(r(d,v,C,w,E,ye,Yt,s0,Ft,Rt/=Nt,Wt/=Nt,Pt,Gt,ht),ht.point(Yt,s0),r(Yt,s0,Ft,Rt,Wt,Pt,Le,Re,Ne,Fe,at,ot,Gt,ht))}}return function(d){var v,C,w,E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht={point:ke,lineStart:ct,lineEnd:Rt,polygonStart:function(){d.polygonStart(),ht.lineStart=Wt},polygonEnd:function(){d.polygonEnd(),ht.lineStart=ct}};function ke(Kt,Ft){Kt=g(Kt,Ft),d.point(Kt[0],Kt[1])}function ct(){Ne=NaN,ht.point=xt,d.lineStart()}function xt(Kt,Ft){var kt=cartesian$1([Kt,Ft]),Yt=g(Kt,Ft);r(Ne,Fe,Re,at,ot,Gt,Ne=Yt[0],Fe=Yt[1],Re=Kt,at=kt[0],ot=kt[1],Gt=kt[2],maxDepth,d),d.point(Ne,Fe)}function Rt(){ht.point=ke,d.lineEnd()}function Wt(){ct(),ht.point=Pt,ht.lineEnd=Nt}function Pt(Kt,Ft){xt(v=Kt,Ft),C=Ne,w=Fe,E=at,ye=ot,Le=Gt,ht.point=xt}function Nt(){r(Ne,Fe,Re,at,ot,Gt,C,w,v,E,ye,Le,maxDepth,d),ht.lineEnd=Rt,Rt()}return ht}}var transformRadians=transformer$1({point:function(g,t){this.stream.point(g*radians$2,t*radians$2)}});function transformRotate(g){return transformer$1({point:function(t,r){var d=g(t,r);return this.stream.point(d[0],d[1])}})}function scaleTranslate(g,t,r,d,v){function C(w,E){return w*=d,E*=v,[t+g*w,r-g*E]}return C.invert=function(w,E){return[(w-t)/g*d,(r-E)/g*v]},C}function scaleTranslateRotate(g,t,r,d,v,C){if(!C)return scaleTranslate(g,t,r,d,v);var w=cos$2(C),E=sin$1(C),ye=w*g,Le=E*g,Re=w/g,Ne=E/g,Fe=(E*r-w*t)/g,at=(E*t+w*r)/g;function ot(Gt,ht){return Gt*=d,ht*=v,[ye*Gt-Le*ht+t,r-Le*Gt-ye*ht]}return ot.invert=function(Gt,ht){return[d*(Re*Gt-Ne*ht+Fe),v*(at-Ne*Gt-Re*ht)]},ot}function projection(g){return projectionMutator(function(){return g})()}function projectionMutator(g){var t,r=150,d=480,v=250,C=0,w=0,E=0,ye=0,Le=0,Re,Ne=0,Fe=1,at=1,ot=null,Gt=clipAntimeridian,ht=null,ke,ct,xt,Rt=identity$2,Wt=.5,Pt,Nt,Kt,Ft,kt;function Yt(r0){return Kt(r0[0]*radians$2,r0[1]*radians$2)}function s0(r0){return r0=Kt.invert(r0[0],r0[1]),r0&&[r0[0]*degrees$1,r0[1]*degrees$1]}Yt.stream=function(r0){return Ft&&kt===r0?Ft:Ft=transformRadians(transformRotate(Re)(Gt(Pt(Rt(kt=r0)))))},Yt.preclip=function(r0){return arguments.length?(Gt=r0,ot=void 0,h0()):Gt},Yt.postclip=function(r0){return arguments.length?(Rt=r0,ht=ke=ct=xt=null,h0()):Rt},Yt.clipAngle=function(r0){return arguments.length?(Gt=+r0?clipCircle(ot=r0*radians$2):(ot=null,clipAntimeridian),h0()):ot*degrees$1},Yt.clipExtent=function(r0){return arguments.length?(Rt=r0==null?(ht=ke=ct=xt=null,identity$2):clipRectangle(ht=+r0[0][0],ke=+r0[0][1],ct=+r0[1][0],xt=+r0[1][1]),h0()):ht==null?null:[[ht,ke],[ct,xt]]},Yt.scale=function(r0){return arguments.length?(r=+r0,o0()):r},Yt.translate=function(r0){return arguments.length?(d=+r0[0],v=+r0[1],o0()):[d,v]},Yt.center=function(r0){return arguments.length?(C=r0[0]%360*radians$2,w=r0[1]%360*radians$2,o0()):[C*degrees$1,w*degrees$1]},Yt.rotate=function(r0){return arguments.length?(E=r0[0]%360*radians$2,ye=r0[1]%360*radians$2,Le=r0.length>2?r0[2]%360*radians$2:0,o0()):[E*degrees$1,ye*degrees$1,Le*degrees$1]},Yt.angle=function(r0){return arguments.length?(Ne=r0%360*radians$2,o0()):Ne*degrees$1},Yt.reflectX=function(r0){return arguments.length?(Fe=r0?-1:1,o0()):Fe<0},Yt.reflectY=function(r0){return arguments.length?(at=r0?-1:1,o0()):at<0},Yt.precision=function(r0){return arguments.length?(Pt=resample(Nt,Wt=r0*r0),h0()):sqrt$2(Wt)},Yt.fitExtent=function(r0,e0){return fitExtent(Yt,r0,e0)},Yt.fitSize=function(r0,e0){return fitSize(Yt,r0,e0)},Yt.fitWidth=function(r0,e0){return fitWidth(Yt,r0,e0)},Yt.fitHeight=function(r0,e0){return fitHeight(Yt,r0,e0)};function o0(){var r0=scaleTranslateRotate(r,0,0,Fe,at,Ne).apply(null,t(C,w)),e0=scaleTranslateRotate(r,d-r0[0],v-r0[1],Fe,at,Ne);return Re=rotateRadians(E,ye,Le),Nt=compose(t,e0),Kt=compose(Re,Nt),Pt=resample(Nt,Wt),h0()}function h0(){return Ft=kt=null,Yt}return function(){return t=g.apply(this,arguments),Yt.invert=t.invert&&s0,o0()}}function azimuthalInvert(g){return function(t,r){var d=sqrt$2(t*t+r*r),v=g(d),C=sin$1(v),w=cos$2(v);return[atan2$1(t*C,d*w),asin$1(d&&r*C/d)]}}function mercatorRaw(g,t){return[g,log(tan$1((halfPi$1+t)/2))]}mercatorRaw.invert=function(g,t){return[g,2*atan$1(exp(t))-halfPi$1]};function s$1(){return mercatorProjection(mercatorRaw).scale(961/tau$1)}function mercatorProjection(g){var t=projection(g),r=t.center,d=t.scale,v=t.translate,C=t.clipExtent,w=null,E,ye,Le;t.scale=function(Ne){return arguments.length?(d(Ne),Re()):d()},t.translate=function(Ne){return arguments.length?(v(Ne),Re()):v()},t.center=function(Ne){return arguments.length?(r(Ne),Re()):r()},t.clipExtent=function(Ne){return arguments.length?(Ne==null?w=E=ye=Le=null:(w=+Ne[0][0],E=+Ne[0][1],ye=+Ne[1][0],Le=+Ne[1][1]),Re()):w==null?null:[[w,E],[ye,Le]]};function Re(){var Ne=pi$3*d(),Fe=t(geoRotation(t.rotate()).invert([0,0]));return C(w==null?[[Fe[0]-Ne,Fe[1]-Ne],[Fe[0]+Ne,Fe[1]+Ne]]:g===mercatorRaw?[[Math.max(Fe[0]-Ne,w),E],[Math.min(Fe[0]+Ne,ye),Le]]:[[w,Math.max(Fe[1]-Ne,E)],[ye,Math.min(Fe[1]+Ne,Le)]])}return Re()}function equirectangularRaw(g,t){return[g,t]}equirectangularRaw.invert=equirectangularRaw;function i$2(){return projection(equirectangularRaw).scale(152.63)}function stereographicRaw(g,t){var r=cos$2(t),d=1+cos$2(g)*r;return[r*sin$1(g)/d,sin$1(t)/d]}stereographicRaw.invert=azimuthalInvert(function(g){return 2*atan$1(g)});function geoStereographic(){return projection(stereographicRaw).scale(250).clipAngle(142)}var atan=Math.atan,cos$1=Math.cos,tan=Math.tan,pi$2=Math.PI,radians$1=pi$2/180;function sqrt$1(g){return g>0?Math.sqrt(g):0}var faheyK=cos$1(35*radians$1);function faheyRaw(g,t){var r=tan(t/2);return[g*faheyK*sqrt$1(1-r*r),(1+faheyK)*r]}faheyRaw.invert=function(g,t){var r=t/(1+faheyK);return[g&&g/(faheyK*sqrt$1(1-r*r)),2*atan(r)]};function p(){return projection(faheyRaw).scale(137.152)}function i$1(g,t,r=0){const d=(90-t)*Math.PI/180,v=(90-g)*Math.PI/180;return[r*Math.sin(d)*Math.cos(v),r*Math.cos(d),r*Math.sin(d)*Math.sin(v)]}const h=g=>g instanceof Vector3?g:new Vector3(...g),_box$1=new Box3,_vector=new Vector3;class LineSegmentsGeometry extends InstancedBufferGeometry{constructor(){super(),this.isLineSegmentsGeometry=!0,this.type="LineSegmentsGeometry";const t=[-1,2,0,1,2,0,-1,1,0,1,1,0,-1,0,0,1,0,0,-1,-1,0,1,-1,0],r=[-1,2,1,2,-1,1,1,1,-1,-1,1,-1,-1,-2,1,-2],d=[0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5];this.setIndex(d),this.setAttribute("position",new Float32BufferAttribute(t,3)),this.setAttribute("uv",new Float32BufferAttribute(r,2))}applyMatrix4(t){const r=this.attributes.instanceStart,d=this.attributes.instanceEnd;return r!==void 0&&(r.applyMatrix4(t),d.applyMatrix4(t),r.needsUpdate=!0),this.boundingBox!==null&&this.computeBoundingBox(),this.boundingSphere!==null&&this.computeBoundingSphere(),this}setPositions(t){let r;t instanceof Float32Array?r=t:Array.isArray(t)&&(r=new Float32Array(t));const d=new InstancedInterleavedBuffer(r,6,1);return this.setAttribute("instanceStart",new InterleavedBufferAttribute(d,3,0)),this.setAttribute("instanceEnd",new InterleavedBufferAttribute(d,3,3)),this.instanceCount=this.attributes.instanceStart.count,this.computeBoundingBox(),this.computeBoundingSphere(),this}setColors(t){let r;t instanceof Float32Array?r=t:Array.isArray(t)&&(r=new Float32Array(t));const d=new InstancedInterleavedBuffer(r,6,1);return this.setAttribute("instanceColorStart",new InterleavedBufferAttribute(d,3,0)),this.setAttribute("instanceColorEnd",new InterleavedBufferAttribute(d,3,3)),this}fromWireframeGeometry(t){return this.setPositions(t.attributes.position.array),this}fromEdgesGeometry(t){return this.setPositions(t.attributes.position.array),this}fromMesh(t){return this.fromWireframeGeometry(new WireframeGeometry(t.geometry)),this}fromLineSegments(t){const r=t.geometry;return this.setPositions(r.attributes.position.array),this}computeBoundingBox(){this.boundingBox===null&&(this.boundingBox=new Box3);const t=this.attributes.instanceStart,r=this.attributes.instanceEnd;t!==void 0&&r!==void 0&&(this.boundingBox.setFromBufferAttribute(t),_box$1.setFromBufferAttribute(r),this.boundingBox.union(_box$1))}computeBoundingSphere(){this.boundingSphere===null&&(this.boundingSphere=new Sphere$1),this.boundingBox===null&&this.computeBoundingBox();const t=this.attributes.instanceStart,r=this.attributes.instanceEnd;if(t!==void 0&&r!==void 0){const d=this.boundingSphere.center;this.boundingBox.getCenter(d);let v=0;for(let C=0,w=t.count;C<w;C++)_vector.fromBufferAttribute(t,C),v=Math.max(v,d.distanceToSquared(_vector)),_vector.fromBufferAttribute(r,C),v=Math.max(v,d.distanceToSquared(_vector));this.boundingSphere.radius=Math.sqrt(v),isNaN(this.boundingSphere.radius)&&console.error("THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.",this)}}toJSON(){}}function earcut(g,t,r=2){const d=t&&t.length,v=d?t[0]*r:g.length;let C=linkedList(g,0,v,r,!0);const w=[];if(!C||C.next===C.prev)return w;let E,ye,Le;if(d&&(C=eliminateHoles(g,t,C,r)),g.length>80*r){E=1/0,ye=1/0;let Re=-1/0,Ne=-1/0;for(let Fe=r;Fe<v;Fe+=r){const at=g[Fe],ot=g[Fe+1];at<E&&(E=at),ot<ye&&(ye=ot),at>Re&&(Re=at),ot>Ne&&(Ne=ot)}Le=Math.max(Re-E,Ne-ye),Le=Le!==0?32767/Le:0}return earcutLinked(C,w,r,E,ye,Le,0),w}function linkedList(g,t,r,d,v){let C;if(v===signedArea(g,t,r,d)>0)for(let w=t;w<r;w+=d)C=insertNode(w/d|0,g[w],g[w+1],C);else for(let w=r-d;w>=t;w-=d)C=insertNode(w/d|0,g[w],g[w+1],C);return C&&equals(C,C.next)&&(removeNode(C),C=C.next),C}function filterPoints(g,t){if(!g)return g;t||(t=g);let r=g,d;do if(d=!1,!r.steiner&&(equals(r,r.next)||area(r.prev,r,r.next)===0)){if(removeNode(r),r=t=r.prev,r===r.next)break;d=!0}else r=r.next;while(d||r!==t);return t}function earcutLinked(g,t,r,d,v,C,w){if(!g)return;!w&&C&&indexCurve(g,d,v,C);let E=g;for(;g.prev!==g.next;){const ye=g.prev,Le=g.next;if(C?isEarHashed(g,d,v,C):isEar(g)){t.push(ye.i,g.i,Le.i),removeNode(g),g=Le.next,E=Le.next;continue}if(g=Le,g===E){w?w===1?(g=cureLocalIntersections(filterPoints(g),t),earcutLinked(g,t,r,d,v,C,2)):w===2&&splitEarcut(g,t,r,d,v,C):earcutLinked(filterPoints(g),t,r,d,v,C,1);break}}}function isEar(g){const t=g.prev,r=g,d=g.next;if(area(t,r,d)>=0)return!1;const v=t.x,C=r.x,w=d.x,E=t.y,ye=r.y,Le=d.y,Re=v<C?v<w?v:w:C<w?C:w,Ne=E<ye?E<Le?E:Le:ye<Le?ye:Le,Fe=v>C?v>w?v:w:C>w?C:w,at=E>ye?E>Le?E:Le:ye>Le?ye:Le;let ot=d.next;for(;ot!==t;){if(ot.x>=Re&&ot.x<=Fe&&ot.y>=Ne&&ot.y<=at&&pointInTriangle(v,E,C,ye,w,Le,ot.x,ot.y)&&area(ot.prev,ot,ot.next)>=0)return!1;ot=ot.next}return!0}function isEarHashed(g,t,r,d){const v=g.prev,C=g,w=g.next;if(area(v,C,w)>=0)return!1;const E=v.x,ye=C.x,Le=w.x,Re=v.y,Ne=C.y,Fe=w.y,at=E<ye?E<Le?E:Le:ye<Le?ye:Le,ot=Re<Ne?Re<Fe?Re:Fe:Ne<Fe?Ne:Fe,Gt=E>ye?E>Le?E:Le:ye>Le?ye:Le,ht=Re>Ne?Re>Fe?Re:Fe:Ne>Fe?Ne:Fe,ke=zOrder(at,ot,t,r,d),ct=zOrder(Gt,ht,t,r,d);let xt=g.prevZ,Rt=g.nextZ;for(;xt&&xt.z>=ke&&Rt&&Rt.z<=ct;){if(xt.x>=at&&xt.x<=Gt&&xt.y>=ot&&xt.y<=ht&&xt!==v&&xt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,xt.x,xt.y)&&area(xt.prev,xt,xt.next)>=0||(xt=xt.prevZ,Rt.x>=at&&Rt.x<=Gt&&Rt.y>=ot&&Rt.y<=ht&&Rt!==v&&Rt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,Rt.x,Rt.y)&&area(Rt.prev,Rt,Rt.next)>=0))return!1;Rt=Rt.nextZ}for(;xt&&xt.z>=ke;){if(xt.x>=at&&xt.x<=Gt&&xt.y>=ot&&xt.y<=ht&&xt!==v&&xt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,xt.x,xt.y)&&area(xt.prev,xt,xt.next)>=0)return!1;xt=xt.prevZ}for(;Rt&&Rt.z<=ct;){if(Rt.x>=at&&Rt.x<=Gt&&Rt.y>=ot&&Rt.y<=ht&&Rt!==v&&Rt!==w&&pointInTriangle(E,Re,ye,Ne,Le,Fe,Rt.x,Rt.y)&&area(Rt.prev,Rt,Rt.next)>=0)return!1;Rt=Rt.nextZ}return!0}function cureLocalIntersections(g,t){let r=g;do{const d=r.prev,v=r.next.next;!equals(d,v)&&intersects(d,r,r.next,v)&&locallyInside(d,v)&&locallyInside(v,d)&&(t.push(d.i,r.i,v.i),removeNode(r),removeNode(r.next),r=g=v),r=r.next}while(r!==g);return filterPoints(r)}function splitEarcut(g,t,r,d,v,C){let w=g;do{let E=w.next.next;for(;E!==w.prev;){if(w.i!==E.i&&isValidDiagonal(w,E)){let ye=splitPolygon(w,E);w=filterPoints(w,w.next),ye=filterPoints(ye,ye.next),earcutLinked(w,t,r,d,v,C,0),earcutLinked(ye,t,r,d,v,C,0);return}E=E.next}w=w.next}while(w!==g)}function eliminateHoles(g,t,r,d){const v=[];for(let C=0,w=t.length;C<w;C++){const E=t[C]*d,ye=C<w-1?t[C+1]*d:g.length,Le=linkedList(g,E,ye,d,!1);Le===Le.next&&(Le.steiner=!0),v.push(getLeftmost(Le))}v.sort(compareX);for(let C=0;C<v.length;C++)r=eliminateHole(v[C],r);return r}function compareX(g,t){return g.x-t.x}function eliminateHole(g,t){const r=findHoleBridge(g,t);if(!r)return t;const d=splitPolygon(r,g);return filterPoints(d,d.next),filterPoints(r,r.next)}function findHoleBridge(g,t){let r=t;const d=g.x,v=g.y;let C=-1/0,w;do{if(v<=r.y&&v>=r.next.y&&r.next.y!==r.y){const Ne=r.x+(v-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(Ne<=d&&Ne>C&&(C=Ne,w=r.x<r.next.x?r:r.next,Ne===d))return w}r=r.next}while(r!==t);if(!w)return null;const E=w,ye=w.x,Le=w.y;let Re=1/0;r=w;do{if(d>=r.x&&r.x>=ye&&d!==r.x&&pointInTriangle(v<Le?d:C,v,ye,Le,v<Le?C:d,v,r.x,r.y)){const Ne=Math.abs(v-r.y)/(d-r.x);locallyInside(r,g)&&(Ne<Re||Ne===Re&&(r.x>w.x||r.x===w.x&&sectorContainsSector(w,r)))&&(w=r,Re=Ne)}r=r.next}while(r!==E);return w}function sectorContainsSector(g,t){return area(g.prev,g,t.prev)<0&&area(t.next,g,g.next)<0}function indexCurve(g,t,r,d){let v=g;do v.z===0&&(v.z=zOrder(v.x,v.y,t,r,d)),v.prevZ=v.prev,v.nextZ=v.next,v=v.next;while(v!==g);v.prevZ.nextZ=null,v.prevZ=null,sortLinked(v)}function sortLinked(g){let t,r=1;do{let d=g,v;g=null;let C=null;for(t=0;d;){t++;let w=d,E=0;for(let Le=0;Le<r&&(E++,w=w.nextZ,!!w);Le++);let ye=r;for(;E>0||ye>0&&w;)E!==0&&(ye===0||!w||d.z<=w.z)?(v=d,d=d.nextZ,E--):(v=w,w=w.nextZ,ye--),C?C.nextZ=v:g=v,v.prevZ=C,C=v;d=w}C.nextZ=null,r*=2}while(t>1);return g}function zOrder(g,t,r,d,v){return g=(g-r)*v|0,t=(t-d)*v|0,g=(g|g<<8)&16711935,g=(g|g<<4)&252645135,g=(g|g<<2)&858993459,g=(g|g<<1)&1431655765,t=(t|t<<8)&16711935,t=(t|t<<4)&252645135,t=(t|t<<2)&858993459,t=(t|t<<1)&1431655765,g|t<<1}function getLeftmost(g){let t=g,r=g;do(t.x<r.x||t.x===r.x&&t.y<r.y)&&(r=t),t=t.next;while(t!==g);return r}function pointInTriangle(g,t,r,d,v,C,w,E){return(v-w)*(t-E)>=(g-w)*(C-E)&&(g-w)*(d-E)>=(r-w)*(t-E)&&(r-w)*(C-E)>=(v-w)*(d-E)}function isValidDiagonal(g,t){return g.next.i!==t.i&&g.prev.i!==t.i&&!intersectsPolygon(g,t)&&(locallyInside(g,t)&&locallyInside(t,g)&&middleInside(g,t)&&(area(g.prev,g,t.prev)||area(g,t.prev,t))||equals(g,t)&&area(g.prev,g,g.next)>0&&area(t.prev,t,t.next)>0)}function area(g,t,r){return(t.y-g.y)*(r.x-t.x)-(t.x-g.x)*(r.y-t.y)}function equals(g,t){return g.x===t.x&&g.y===t.y}function intersects(g,t,r,d){const v=sign$1(area(g,t,r)),C=sign$1(area(g,t,d)),w=sign$1(area(r,d,g)),E=sign$1(area(r,d,t));return!!(v!==C&&w!==E||v===0&&onSegment(g,r,t)||C===0&&onSegment(g,d,t)||w===0&&onSegment(r,g,d)||E===0&&onSegment(r,t,d))}function onSegment(g,t,r){return t.x<=Math.max(g.x,r.x)&&t.x>=Math.min(g.x,r.x)&&t.y<=Math.max(g.y,r.y)&&t.y>=Math.min(g.y,r.y)}function sign$1(g){return g>0?1:g<0?-1:0}function intersectsPolygon(g,t){let r=g;do{if(r.i!==g.i&&r.next.i!==g.i&&r.i!==t.i&&r.next.i!==t.i&&intersects(r,r.next,g,t))return!0;r=r.next}while(r!==g);return!1}function locallyInside(g,t){return area(g.prev,g,g.next)<0?area(g,t,g.next)>=0&&area(g,g.prev,t)>=0:area(g,t,g.prev)<0||area(g,g.next,t)<0}function middleInside(g,t){let r=g,d=!1;const v=(g.x+t.x)/2,C=(g.y+t.y)/2;do r.y>C!=r.next.y>C&&r.next.y!==r.y&&v<(r.next.x-r.x)*(C-r.y)/(r.next.y-r.y)+r.x&&(d=!d),r=r.next;while(r!==g);return d}function splitPolygon(g,t){const r=createNode(g.i,g.x,g.y),d=createNode(t.i,t.x,t.y),v=g.next,C=t.prev;return g.next=t,t.prev=g,r.next=v,v.prev=r,d.next=r,r.prev=d,C.next=d,d.prev=C,d}function insertNode(g,t,r,d){const v=createNode(g,t,r);return d?(v.next=d.next,v.prev=d,d.next.prev=v,d.next=v):(v.prev=v,v.next=v),v}function removeNode(g){g.next.prev=g.prev,g.prev.next=g.next,g.prevZ&&(g.prevZ.nextZ=g.nextZ),g.nextZ&&(g.nextZ.prevZ=g.prevZ)}function createNode(g,t,r){return{i:g,x:t,y:r,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function signedArea(g,t,r,d){let v=0;for(let C=t,w=r-d;C<r;C+=d)v+=(g[w]-g[C])*(g[C+1]+g[w+1]),w=C;return v}function flatten(g){const t=[],r=[],d=g[0][0].length;let v=0,C=0;for(const w of g){for(const E of w)for(let ye=0;ye<d;ye++)t.push(E[ye]);C&&(v+=C,r.push(v)),C=w.length}return{vertices:t,holes:r,dimensions:d}}function getCoord(g){if(!g)throw new Error("coord is required");if(!Array.isArray(g)){if(g.type==="Feature"&&g.geometry!==null&&g.geometry.type==="Point")return[...g.geometry.coordinates];if(g.type==="Point")return[...g.coordinates]}if(Array.isArray(g)&&g.length>=2&&!Array.isArray(g[0])&&!Array.isArray(g[1]))return[...g];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function getCoords(g){if(Array.isArray(g))return g;if(g.type==="Feature"){if(g.geometry!==null)return g.geometry.coordinates}else if(g.coordinates)return g.coordinates;throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array")}function getGeom(g){return g.type==="Feature"?g.geometry:g}function booleanClockwise(g){const t=getCoords(g);let r=0,d=1,v,C;for(;d<t.length;)v=C||t[0],C=t[d],r+=(C[0]-v[0])*(C[1]+v[1]),d++;return r>0}var turf_boolean_clockwise_default=booleanClockwise;const epsilon$1=11102230246251565e-32,splitter=134217729,resulterrbound=(3+8*epsilon$1)*epsilon$1;function sum(g,t,r,d,v){let C,w,E,ye,Le=t[0],Re=d[0],Ne=0,Fe=0;Re>Le==Re>-Le?(C=Le,Le=t[++Ne]):(C=Re,Re=d[++Fe]);let at=0;if(Ne<g&&Fe<r)for(Re>Le==Re>-Le?(w=Le+C,E=C-(w-Le),Le=t[++Ne]):(w=Re+C,E=C-(w-Re),Re=d[++Fe]),C=w,E!==0&&(v[at++]=E);Ne<g&&Fe<r;)Re>Le==Re>-Le?(w=C+Le,ye=w-C,E=C-(w-ye)+(Le-ye),Le=t[++Ne]):(w=C+Re,ye=w-C,E=C-(w-ye)+(Re-ye),Re=d[++Fe]),C=w,E!==0&&(v[at++]=E);for(;Ne<g;)w=C+Le,ye=w-C,E=C-(w-ye)+(Le-ye),Le=t[++Ne],C=w,E!==0&&(v[at++]=E);for(;Fe<r;)w=C+Re,ye=w-C,E=C-(w-ye)+(Re-ye),Re=d[++Fe],C=w,E!==0&&(v[at++]=E);return(C!==0||at===0)&&(v[at++]=C),at}function estimate(g,t){let r=t[0];for(let d=1;d<g;d++)r+=t[d];return r}function vec(g){return new Float64Array(g)}const ccwerrboundA=(3+16*epsilon$1)*epsilon$1,ccwerrboundB=(2+12*epsilon$1)*epsilon$1,ccwerrboundC=(9+64*epsilon$1)*epsilon$1*epsilon$1,B=vec(4),C1=vec(8),C2=vec(12),D=vec(16),u$1=vec(4);function orient2dadapt(g,t,r,d,v,C,w){let E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht,ke,ct,xt,Rt,Wt,Pt,Nt,Kt;const Ft=g-v,kt=r-v,Yt=t-C,s0=d-C;Rt=Ft*s0,Fe=splitter*Ft,at=Fe-(Fe-Ft),ot=Ft-at,Fe=splitter*s0,Gt=Fe-(Fe-s0),ht=s0-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=Yt*kt,Fe=splitter*Yt,at=Fe-(Fe-Yt),ot=Yt-at,Fe=splitter*kt,Gt=Fe-(Fe-kt),ht=kt-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,B[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,B[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,B[2]=ct-(Kt-Ne)+(ke-Ne),B[3]=Kt;let o0=estimate(4,B),h0=ccwerrboundB*w;if(o0>=h0||-o0>=h0||(Ne=g-Ft,E=g-(Ft+Ne)+(Ne-v),Ne=r-kt,Le=r-(kt+Ne)+(Ne-v),Ne=t-Yt,ye=t-(Yt+Ne)+(Ne-C),Ne=d-s0,Re=d-(s0+Ne)+(Ne-C),E===0&&ye===0&&Le===0&&Re===0)||(h0=ccwerrboundC*w+resulterrbound*Math.abs(o0),o0+=Ft*Re+s0*E-(Yt*Le+kt*ye),o0>=h0||-o0>=h0))return o0;Rt=E*s0,Fe=splitter*E,at=Fe-(Fe-E),ot=E-at,Fe=splitter*s0,Gt=Fe-(Fe-s0),ht=s0-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=ye*kt,Fe=splitter*ye,at=Fe-(Fe-ye),ot=ye-at,Fe=splitter*kt,Gt=Fe-(Fe-kt),ht=kt-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,u$1[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,u$1[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,u$1[2]=ct-(Kt-Ne)+(ke-Ne),u$1[3]=Kt;const r0=sum(4,B,4,u$1,C1);Rt=Ft*Re,Fe=splitter*Ft,at=Fe-(Fe-Ft),ot=Ft-at,Fe=splitter*Re,Gt=Fe-(Fe-Re),ht=Re-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=Yt*Le,Fe=splitter*Yt,at=Fe-(Fe-Yt),ot=Yt-at,Fe=splitter*Le,Gt=Fe-(Fe-Le),ht=Le-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,u$1[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,u$1[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,u$1[2]=ct-(Kt-Ne)+(ke-Ne),u$1[3]=Kt;const e0=sum(r0,C1,4,u$1,C2);Rt=E*Re,Fe=splitter*E,at=Fe-(Fe-E),ot=E-at,Fe=splitter*Re,Gt=Fe-(Fe-Re),ht=Re-Gt,Wt=ot*ht-(Rt-at*Gt-ot*Gt-at*ht),Pt=ye*Le,Fe=splitter*ye,at=Fe-(Fe-ye),ot=ye-at,Fe=splitter*Le,Gt=Fe-(Fe-Le),ht=Le-Gt,Nt=ot*ht-(Pt-at*Gt-ot*Gt-at*ht),ke=Wt-Nt,Ne=Wt-ke,u$1[0]=Wt-(ke+Ne)+(Ne-Nt),ct=Rt+ke,Ne=ct-Rt,xt=Rt-(ct-Ne)+(ke-Ne),ke=xt-Pt,Ne=xt-ke,u$1[1]=xt-(ke+Ne)+(Ne-Pt),Kt=ct+ke,Ne=Kt-ct,u$1[2]=ct-(Kt-Ne)+(ke-Ne),u$1[3]=Kt;const i0=sum(e0,C2,4,u$1,D);return D[i0-1]}function orient2d(g,t,r,d,v,C){const w=(t-C)*(r-v),E=(g-v)*(d-C),ye=w-E,Le=Math.abs(w+E);return Math.abs(ye)>=ccwerrboundA*Le?ye:-orient2dadapt(g,t,r,d,v,C,Le)}const EPSILON$2=Math.pow(2,-52),EDGE_STACK=new Uint32Array(512);class Delaunator{static from(t,r=defaultGetX,d=defaultGetY){const v=t.length,C=new Float64Array(v*2);for(let w=0;w<v;w++){const E=t[w];C[2*w]=r(E),C[2*w+1]=d(E)}return new Delaunator(C)}constructor(t){const r=t.length>>1;if(r>0&&typeof t[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=t;const d=Math.max(2*r-5,0);this._triangles=new Uint32Array(d*3),this._halfedges=new Int32Array(d*3),this._hashSize=Math.ceil(Math.sqrt(r)),this._hullPrev=new Uint32Array(r),this._hullNext=new Uint32Array(r),this._hullTri=new Uint32Array(r),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(r),this._dists=new Float64Array(r),this.update()}update(){const{coords:t,_hullPrev:r,_hullNext:d,_hullTri:v,_hullHash:C}=this,w=t.length>>1;let E=1/0,ye=1/0,Le=-1/0,Re=-1/0;for(let kt=0;kt<w;kt++){const Yt=t[2*kt],s0=t[2*kt+1];Yt<E&&(E=Yt),s0<ye&&(ye=s0),Yt>Le&&(Le=Yt),s0>Re&&(Re=s0),this._ids[kt]=kt}const Ne=(E+Le)/2,Fe=(ye+Re)/2;let at=1/0,ot,Gt,ht;for(let kt=0;kt<w;kt++){const Yt=dist(Ne,Fe,t[2*kt],t[2*kt+1]);Yt<at&&(ot=kt,at=Yt)}const ke=t[2*ot],ct=t[2*ot+1];at=1/0;for(let kt=0;kt<w;kt++){if(kt===ot)continue;const Yt=dist(ke,ct,t[2*kt],t[2*kt+1]);Yt<at&&Yt>0&&(Gt=kt,at=Yt)}let xt=t[2*Gt],Rt=t[2*Gt+1],Wt=1/0;for(let kt=0;kt<w;kt++){if(kt===ot||kt===Gt)continue;const Yt=circumradius(ke,ct,xt,Rt,t[2*kt],t[2*kt+1]);Yt<Wt&&(ht=kt,Wt=Yt)}let Pt=t[2*ht],Nt=t[2*ht+1];if(Wt===1/0){for(let s0=0;s0<w;s0++)this._dists[s0]=t[2*s0]-t[0]||t[2*s0+1]-t[1];quicksort(this._ids,this._dists,0,w-1);const kt=new Uint32Array(w);let Yt=0;for(let s0=0,o0=-1/0;s0<w;s0++){const h0=this._ids[s0];this._dists[h0]>o0&&(kt[Yt++]=h0,o0=this._dists[h0])}this.hull=kt.subarray(0,Yt),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(orient2d(ke,ct,xt,Rt,Pt,Nt)<0){const kt=Gt,Yt=xt,s0=Rt;Gt=ht,xt=Pt,Rt=Nt,ht=kt,Pt=Yt,Nt=s0}const Kt=circumcenter(ke,ct,xt,Rt,Pt,Nt);this._cx=Kt.x,this._cy=Kt.y;for(let kt=0;kt<w;kt++)this._dists[kt]=dist(t[2*kt],t[2*kt+1],Kt.x,Kt.y);quicksort(this._ids,this._dists,0,w-1),this._hullStart=ot;let Ft=3;d[ot]=r[ht]=Gt,d[Gt]=r[ot]=ht,d[ht]=r[Gt]=ot,v[ot]=0,v[Gt]=1,v[ht]=2,C.fill(-1),C[this._hashKey(ke,ct)]=ot,C[this._hashKey(xt,Rt)]=Gt,C[this._hashKey(Pt,Nt)]=ht,this.trianglesLen=0,this._addTriangle(ot,Gt,ht,-1,-1,-1);for(let kt=0,Yt,s0;kt<this._ids.length;kt++){const o0=this._ids[kt],h0=t[2*o0],r0=t[2*o0+1];if(kt>0&&Math.abs(h0-Yt)<=EPSILON$2&&Math.abs(r0-s0)<=EPSILON$2||(Yt=h0,s0=r0,o0===ot||o0===Gt||o0===ht))continue;let e0=0;for(let g0=0,I0=this._hashKey(h0,r0);g0<this._hashSize&&(e0=C[(I0+g0)%this._hashSize],!(e0!==-1&&e0!==d[e0]));g0++);e0=r[e0];let i0=e0,Ut;for(;Ut=d[i0],orient2d(h0,r0,t[2*i0],t[2*i0+1],t[2*Ut],t[2*Ut+1])>=0;)if(i0=Ut,i0===e0){i0=-1;break}if(i0===-1)continue;let l0=this._addTriangle(i0,o0,d[i0],-1,-1,v[i0]);v[o0]=this._legalize(l0+2),v[i0]=l0,Ft++;let S0=d[i0];for(;Ut=d[S0],orient2d(h0,r0,t[2*S0],t[2*S0+1],t[2*Ut],t[2*Ut+1])<0;)l0=this._addTriangle(S0,o0,Ut,v[o0],-1,v[S0]),v[o0]=this._legalize(l0+2),d[S0]=S0,Ft--,S0=Ut;if(i0===e0)for(;Ut=r[i0],orient2d(h0,r0,t[2*Ut],t[2*Ut+1],t[2*i0],t[2*i0+1])<0;)l0=this._addTriangle(Ut,o0,i0,-1,v[i0],v[Ut]),this._legalize(l0+2),v[Ut]=l0,d[i0]=i0,Ft--,i0=Ut;this._hullStart=r[o0]=i0,d[i0]=r[S0]=o0,d[o0]=S0,C[this._hashKey(h0,r0)]=o0,C[this._hashKey(t[2*i0],t[2*i0+1])]=i0}this.hull=new Uint32Array(Ft);for(let kt=0,Yt=this._hullStart;kt<Ft;kt++)this.hull[kt]=Yt,Yt=d[Yt];this.triangles=this._triangles.subarray(0,this.trianglesLen),this.halfedges=this._halfedges.subarray(0,this.trianglesLen)}_hashKey(t,r){return Math.floor(pseudoAngle(t-this._cx,r-this._cy)*this._hashSize)%this._hashSize}_legalize(t){const{_triangles:r,_halfedges:d,coords:v}=this;let C=0,w=0;for(;;){const E=d[t],ye=t-t%3;if(w=ye+(t+2)%3,E===-1){if(C===0)break;t=EDGE_STACK[--C];continue}const Le=E-E%3,Re=ye+(t+1)%3,Ne=Le+(E+2)%3,Fe=r[w],at=r[t],ot=r[Re],Gt=r[Ne];if(inCircle(v[2*Fe],v[2*Fe+1],v[2*at],v[2*at+1],v[2*ot],v[2*ot+1],v[2*Gt],v[2*Gt+1])){r[t]=Gt,r[E]=Fe;const ke=d[Ne];if(ke===-1){let xt=this._hullStart;do{if(this._hullTri[xt]===Ne){this._hullTri[xt]=t;break}xt=this._hullPrev[xt]}while(xt!==this._hullStart)}this._link(t,ke),this._link(E,d[w]),this._link(w,Ne);const ct=Le+(E+1)%3;C<EDGE_STACK.length&&(EDGE_STACK[C++]=ct)}else{if(C===0)break;t=EDGE_STACK[--C]}}return w}_link(t,r){this._halfedges[t]=r,r!==-1&&(this._halfedges[r]=t)}_addTriangle(t,r,d,v,C,w){const E=this.trianglesLen;return this._triangles[E]=t,this._triangles[E+1]=r,this._triangles[E+2]=d,this._link(E,v),this._link(E+1,C),this._link(E+2,w),this.trianglesLen+=3,E}}function pseudoAngle(g,t){const r=g/(Math.abs(g)+Math.abs(t));return(t>0?3-r:1+r)/4}function dist(g,t,r,d){const v=g-r,C=t-d;return v*v+C*C}function inCircle(g,t,r,d,v,C,w,E){const ye=g-w,Le=t-E,Re=r-w,Ne=d-E,Fe=v-w,at=C-E,ot=ye*ye+Le*Le,Gt=Re*Re+Ne*Ne,ht=Fe*Fe+at*at;return ye*(Ne*ht-Gt*at)-Le*(Re*ht-Gt*Fe)+ot*(Re*at-Ne*Fe)<0}function circumradius(g,t,r,d,v,C){const w=r-g,E=d-t,ye=v-g,Le=C-t,Re=w*w+E*E,Ne=ye*ye+Le*Le,Fe=.5/(w*Le-E*ye),at=(Le*Re-E*Ne)*Fe,ot=(w*Ne-ye*Re)*Fe;return at*at+ot*ot}function circumcenter(g,t,r,d,v,C){const w=r-g,E=d-t,ye=v-g,Le=C-t,Re=w*w+E*E,Ne=ye*ye+Le*Le,Fe=.5/(w*Le-E*ye),at=g+(Le*Re-E*Ne)*Fe,ot=t+(w*Ne-ye*Re)*Fe;return{x:at,y:ot}}function quicksort(g,t,r,d){if(d-r<=20)for(let v=r+1;v<=d;v++){const C=g[v],w=t[C];let E=v-1;for(;E>=r&&t[g[E]]>w;)g[E+1]=g[E--];g[E+1]=C}else{const v=r+d>>1;let C=r+1,w=d;swap(g,v,C),t[g[r]]>t[g[d]]&&swap(g,r,d),t[g[C]]>t[g[d]]&&swap(g,C,d),t[g[r]]>t[g[C]]&&swap(g,r,C);const E=g[C],ye=t[E];for(;;){do C++;while(t[g[C]]<ye);do w--;while(t[g[w]]>ye);if(w<C)break;swap(g,C,w)}g[r+1]=g[w],g[w]=E,d-C+1>=w-r?(quicksort(g,t,C,d),quicksort(g,t,r,w-1)):(quicksort(g,t,r,w-1),quicksort(g,t,C,d))}}function swap(g,t,r){const d=g[t];g[t]=g[r],g[r]=d}function defaultGetX(g){return g[0]}function defaultGetY(g){return g[1]}function pointInPolygon(g,t){var r=0,d=0,v=0,C=0,w=0,E=0,ye=0,Le=0,Re=null,Ne=null,Fe=g[0],at=g[1],ot=t.length;for(r;r<ot;r++){d=0;var Gt=t[r].length-1,ht=t[r];if(Re=ht[0],Re[0]!==ht[Gt][0]&&Re[1]!==ht[Gt][1])throw new Error("First and last coordinates in a ring must be the same");for(w=Re[0]-Fe,E=Re[1]-at,d;d<Gt;d++){if(Ne=ht[d+1],Le=Ne[1]-at,E<0&&Le<0||E>0&&Le>0){Re=Ne,E=Le,w=Re[0]-Fe;continue}if(ye=Ne[0]-g[0],Le>0&&E<=0){if(C=w*Le-ye*E,C>0)v=v+1;else if(C===0)return 0}else if(E>0&&Le<=0){if(C=w*Le-ye*E,C<0)v=v+1;else if(C===0)return 0}else if(Le===0&&E<0){if(C=w*Le-ye*E,C===0)return 0}else if(E===0&&Le<0){if(C=w*Le-ye*E,C===0)return 0}else if(E===0&&Le===0){if(ye<=0&&w>=0)return 0;if(w<=0&&ye>=0)return 0}Re=Ne,E=Le,w=ye}}return v%2!==0}function booleanPointInPolygon(g,t,r={}){if(!g)throw new Error("point is required");if(!t)throw new Error("polygon is required");const d=getCoord(g),v=getGeom(t),C=v.type,w=t.bbox;let E=v.coordinates;if(w&&inBBox(d,w)===!1)return!1;C==="Polygon"&&(E=[E]);let ye=!1;for(var Le=0;Le<E.length;++Le){const Re=pointInPolygon(d,E[Le]);if(Re===0)return!r.ignoreBoundary;Re&&(ye=!0)}return ye}function inBBox(g,t){return t[0]<=g[0]&&t[1]<=g[1]&&t[2]>=g[0]&&t[3]>=g[1]}var turf_boolean_point_in_polygon_default=booleanPointInPolygon;const epsilon=1e-6;class Path{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._=""}moveTo(t,r){this._+=`M${this._x0=this._x1=+t},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")}lineTo(t,r){this._+=`L${this._x1=+t},${this._y1=+r}`}arc(t,r,d){t=+t,r=+r,d=+d;const v=t+d,C=r;if(d<0)throw new Error("negative radius");this._x1===null?this._+=`M${v},${C}`:(Math.abs(this._x1-v)>epsilon||Math.abs(this._y1-C)>epsilon)&&(this._+="L"+v+","+C),d&&(this._+=`A${d},${d},0,1,1,${t-d},${r}A${d},${d},0,1,1,${this._x1=v},${this._y1=C}`)}rect(t,r,d,v){this._+=`M${this._x0=this._x1=+t},${this._y0=this._y1=+r}h${+d}v${+v}h${-d}Z`}value(){return this._||null}}class Polygon{constructor(){this._=[]}moveTo(t,r){this._.push([t,r])}closePath(){this._.push(this._[0].slice())}lineTo(t,r){this._.push([t,r])}value(){return this._.length?this._:null}}class Voronoi{constructor(t,[r,d,v,C]=[0,0,960,500]){if(!((v=+v)>=(r=+r))||!((C=+C)>=(d=+d)))throw new Error("invalid bounds");this.delaunay=t,this._circumcenters=new Float64Array(t.points.length*2),this.vectors=new Float64Array(t.points.length*2),this.xmax=v,this.xmin=r,this.ymax=C,this.ymin=d,this._init()}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:t,hull:r,triangles:d},vectors:v}=this;let C,w;const E=this.circumcenters=this._circumcenters.subarray(0,d.length/3*2);for(let Gt=0,ht=0,ke=d.length,ct,xt;Gt<ke;Gt+=3,ht+=2){const Rt=d[Gt]*2,Wt=d[Gt+1]*2,Pt=d[Gt+2]*2,Nt=t[Rt],Kt=t[Rt+1],Ft=t[Wt],kt=t[Wt+1],Yt=t[Pt],s0=t[Pt+1],o0=Ft-Nt,h0=kt-Kt,r0=Yt-Nt,e0=s0-Kt,i0=(o0*e0-h0*r0)*2;if(Math.abs(i0)<1e-9){if(C===void 0){C=w=0;for(const l0 of r)C+=t[l0*2],w+=t[l0*2+1];C/=r.length,w/=r.length}const Ut=1e9*Math.sign((C-Nt)*e0-(w-Kt)*r0);ct=(Nt+Yt)/2-Ut*e0,xt=(Kt+s0)/2+Ut*r0}else{const Ut=1/i0,l0=o0*o0+h0*h0,S0=r0*r0+e0*e0;ct=Nt+(e0*l0-h0*S0)*Ut,xt=Kt+(o0*S0-r0*l0)*Ut}E[ht]=ct,E[ht+1]=xt}let ye=r[r.length-1],Le,Re=ye*4,Ne,Fe=t[2*ye],at,ot=t[2*ye+1];v.fill(0);for(let Gt=0;Gt<r.length;++Gt)ye=r[Gt],Le=Re,Ne=Fe,at=ot,Re=ye*4,Fe=t[2*ye],ot=t[2*ye+1],v[Le+2]=v[Re]=at-ot,v[Le+3]=v[Re+1]=Fe-Ne}render(t){const r=t==null?t=new Path:void 0,{delaunay:{halfedges:d,inedges:v,hull:C},circumcenters:w,vectors:E}=this;if(C.length<=1)return null;for(let Re=0,Ne=d.length;Re<Ne;++Re){const Fe=d[Re];if(Fe<Re)continue;const at=Math.floor(Re/3)*2,ot=Math.floor(Fe/3)*2,Gt=w[at],ht=w[at+1],ke=w[ot],ct=w[ot+1];this._renderSegment(Gt,ht,ke,ct,t)}let ye,Le=C[C.length-1];for(let Re=0;Re<C.length;++Re){ye=Le,Le=C[Re];const Ne=Math.floor(v[Le]/3)*2,Fe=w[Ne],at=w[Ne+1],ot=ye*4,Gt=this._project(Fe,at,E[ot+2],E[ot+3]);Gt&&this._renderSegment(Fe,at,Gt[0],Gt[1],t)}return r&&r.value()}renderBounds(t){const r=t==null?t=new Path:void 0;return t.rect(this.xmin,this.ymin,this.xmax-this.xmin,this.ymax-this.ymin),r&&r.value()}renderCell(t,r){const d=r==null?r=new Path:void 0,v=this._clip(t);if(v===null||!v.length)return;r.moveTo(v[0],v[1]);let C=v.length;for(;v[0]===v[C-2]&&v[1]===v[C-1]&&C>1;)C-=2;for(let w=2;w<C;w+=2)(v[w]!==v[w-2]||v[w+1]!==v[w-1])&&r.lineTo(v[w],v[w+1]);return r.closePath(),d&&d.value()}*cellPolygons(){const{delaunay:{points:t}}=this;for(let r=0,d=t.length/2;r<d;++r){const v=this.cellPolygon(r);v&&(v.index=r,yield v)}}cellPolygon(t){const r=new Polygon;return this.renderCell(t,r),r.value()}_renderSegment(t,r,d,v,C){let w;const E=this._regioncode(t,r),ye=this._regioncode(d,v);E===0&&ye===0?(C.moveTo(t,r),C.lineTo(d,v)):(w=this._clipSegment(t,r,d,v,E,ye))&&(C.moveTo(w[0],w[1]),C.lineTo(w[2],w[3]))}contains(t,r,d){return r=+r,r!==r||(d=+d,d!==d)?!1:this.delaunay._step(t,r,d)===t}*neighbors(t){const r=this._clip(t);if(r)for(const d of this.delaunay.neighbors(t)){const v=this._clip(d);if(v){e:for(let C=0,w=r.length;C<w;C+=2)for(let E=0,ye=v.length;E<ye;E+=2)if(r[C]===v[E]&&r[C+1]===v[E+1]&&r[(C+2)%w]===v[(E+ye-2)%ye]&&r[(C+3)%w]===v[(E+ye-1)%ye]){yield d;break e}}}}_cell(t){const{circumcenters:r,delaunay:{inedges:d,halfedges:v,triangles:C}}=this,w=d[t];if(w===-1)return null;const E=[];let ye=w;do{const Le=Math.floor(ye/3);if(E.push(r[Le*2],r[Le*2+1]),ye=ye%3===2?ye-2:ye+1,C[ye]!==t)break;ye=v[ye]}while(ye!==w&&ye!==-1);return E}_clip(t){if(t===0&&this.delaunay.hull.length===1)return[this.xmax,this.ymin,this.xmax,this.ymax,this.xmin,this.ymax,this.xmin,this.ymin];const r=this._cell(t);if(r===null)return null;const{vectors:d}=this,v=t*4;return this._simplify(d[v]||d[v+1]?this._clipInfinite(t,r,d[v],d[v+1],d[v+2],d[v+3]):this._clipFinite(t,r))}_clipFinite(t,r){const d=r.length;let v=null,C,w,E=r[d-2],ye=r[d-1],Le,Re=this._regioncode(E,ye),Ne,Fe=0;for(let at=0;at<d;at+=2)if(C=E,w=ye,E=r[at],ye=r[at+1],Le=Re,Re=this._regioncode(E,ye),Le===0&&Re===0)Ne=Fe,Fe=0,v?v.push(E,ye):v=[E,ye];else{let ot,Gt,ht,ke,ct;if(Le===0){if((ot=this._clipSegment(C,w,E,ye,Le,Re))===null)continue;[Gt,ht,ke,ct]=ot}else{if((ot=this._clipSegment(E,ye,C,w,Re,Le))===null)continue;[ke,ct,Gt,ht]=ot,Ne=Fe,Fe=this._edgecode(Gt,ht),Ne&&Fe&&this._edge(t,Ne,Fe,v,v.length),v?v.push(Gt,ht):v=[Gt,ht]}Ne=Fe,Fe=this._edgecode(ke,ct),Ne&&Fe&&this._edge(t,Ne,Fe,v,v.length),v?v.push(ke,ct):v=[ke,ct]}if(v)Ne=Fe,Fe=this._edgecode(v[0],v[1]),Ne&&Fe&&this._edge(t,Ne,Fe,v,v.length);else if(this.contains(t,(this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2))return[this.xmax,this.ymin,this.xmax,this.ymax,this.xmin,this.ymax,this.xmin,this.ymin];return v}_clipSegment(t,r,d,v,C,w){const E=C<w;for(E&&([t,r,d,v,C,w]=[d,v,t,r,w,C]);;){if(C===0&&w===0)return E?[d,v,t,r]:[t,r,d,v];if(C&w)return null;let ye,Le,Re=C||w;Re&8?(ye=t+(d-t)*(this.ymax-r)/(v-r),Le=this.ymax):Re&4?(ye=t+(d-t)*(this.ymin-r)/(v-r),Le=this.ymin):Re&2?(Le=r+(v-r)*(this.xmax-t)/(d-t),ye=this.xmax):(Le=r+(v-r)*(this.xmin-t)/(d-t),ye=this.xmin),C?(t=ye,r=Le,C=this._regioncode(t,r)):(d=ye,v=Le,w=this._regioncode(d,v))}}_clipInfinite(t,r,d,v,C,w){let E=Array.from(r),ye;if((ye=this._project(E[0],E[1],d,v))&&E.unshift(ye[0],ye[1]),(ye=this._project(E[E.length-2],E[E.length-1],C,w))&&E.push(ye[0],ye[1]),E=this._clipFinite(t,E))for(let Le=0,Re=E.length,Ne,Fe=this._edgecode(E[Re-2],E[Re-1]);Le<Re;Le+=2)Ne=Fe,Fe=this._edgecode(E[Le],E[Le+1]),Ne&&Fe&&(Le=this._edge(t,Ne,Fe,E,Le),Re=E.length);else this.contains(t,(this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)&&(E=[this.xmin,this.ymin,this.xmax,this.ymin,this.xmax,this.ymax,this.xmin,this.ymax]);return E}_edge(t,r,d,v,C){for(;r!==d;){let w,E;switch(r){case 5:r=4;continue;case 4:r=6,w=this.xmax,E=this.ymin;break;case 6:r=2;continue;case 2:r=10,w=this.xmax,E=this.ymax;break;case 10:r=8;continue;case 8:r=9,w=this.xmin,E=this.ymax;break;case 9:r=1;continue;case 1:r=5,w=this.xmin,E=this.ymin;break}(v[C]!==w||v[C+1]!==E)&&this.contains(t,w,E)&&(v.splice(C,0,w,E),C+=2)}return C}_project(t,r,d,v){let C=1/0,w,E,ye;if(v<0){if(r<=this.ymin)return null;(w=(this.ymin-r)/v)<C&&(ye=this.ymin,E=t+(C=w)*d)}else if(v>0){if(r>=this.ymax)return null;(w=(this.ymax-r)/v)<C&&(ye=this.ymax,E=t+(C=w)*d)}if(d>0){if(t>=this.xmax)return null;(w=(this.xmax-t)/d)<C&&(E=this.xmax,ye=r+(C=w)*v)}else if(d<0){if(t<=this.xmin)return null;(w=(this.xmin-t)/d)<C&&(E=this.xmin,ye=r+(C=w)*v)}return[E,ye]}_edgecode(t,r){return(t===this.xmin?1:t===this.xmax?2:0)|(r===this.ymin?4:r===this.ymax?8:0)}_regioncode(t,r){return(t<this.xmin?1:t>this.xmax?2:0)|(r<this.ymin?4:r>this.ymax?8:0)}_simplify(t){if(t&&t.length>4){for(let r=0;r<t.length;r+=2){const d=(r+2)%t.length,v=(r+4)%t.length;(t[r]===t[d]&&t[d]===t[v]||t[r+1]===t[d+1]&&t[d+1]===t[v+1])&&(t.splice(d,2),r-=2)}t.length||(t=null)}return t}}const tau=2*Math.PI,pow=Math.pow;function pointX(g){return g[0]}function pointY(g){return g[1]}function collinear(g){const{triangles:t,coords:r}=g;for(let d=0;d<t.length;d+=3){const v=2*t[d],C=2*t[d+1],w=2*t[d+2];if((r[w]-r[v])*(r[C+1]-r[v+1])-(r[C]-r[v])*(r[w+1]-r[v+1])>1e-10)return!1}return!0}function jitter(g,t,r){return[g+Math.sin(g+t)*r,t+Math.cos(g-t)*r]}class Delaunay{static from(t,r=pointX,d=pointY,v){return new Delaunay("length"in t?flatArray(t,r,d,v):Float64Array.from(flatIterable(t,r,d,v)))}constructor(t){this._delaunator=new Delaunator(t),this.inedges=new Int32Array(t.length/2),this._hullIndex=new Int32Array(t.length/2),this.points=this._delaunator.coords,this._init()}update(){return this._delaunator.update(),this._init(),this}_init(){const t=this._delaunator,r=this.points;if(t.hull&&t.hull.length>2&&collinear(t)){this.collinear=Int32Array.from({length:r.length/2},(Fe,at)=>at).sort((Fe,at)=>r[2*Fe]-r[2*at]||r[2*Fe+1]-r[2*at+1]);const ye=this.collinear[0],Le=this.collinear[this.collinear.length-1],Re=[r[2*ye],r[2*ye+1],r[2*Le],r[2*Le+1]],Ne=1e-8*Math.hypot(Re[3]-Re[1],Re[2]-Re[0]);for(let Fe=0,at=r.length/2;Fe<at;++Fe){const ot=jitter(r[2*Fe],r[2*Fe+1],Ne);r[2*Fe]=ot[0],r[2*Fe+1]=ot[1]}this._delaunator=new Delaunator(r)}else delete this.collinear;const d=this.halfedges=this._delaunator.halfedges,v=this.hull=this._delaunator.hull,C=this.triangles=this._delaunator.triangles,w=this.inedges.fill(-1),E=this._hullIndex.fill(-1);for(let ye=0,Le=d.length;ye<Le;++ye){const Re=C[ye%3===2?ye-2:ye+1];(d[ye]===-1||w[Re]===-1)&&(w[Re]=ye)}for(let ye=0,Le=v.length;ye<Le;++ye)E[v[ye]]=ye;v.length<=2&&v.length>0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=v[0],w[v[0]]=1,v.length===2&&(w[v[1]]=0,this.triangles[1]=v[1],this.triangles[2]=v[1]))}voronoi(t){return new Voronoi(this,t)}*neighbors(t){const{inedges:r,hull:d,_hullIndex:v,halfedges:C,triangles:w,collinear:E}=this;if(E){const Ne=E.indexOf(t);Ne>0&&(yield E[Ne-1]),Ne<E.length-1&&(yield E[Ne+1]);return}const ye=r[t];if(ye===-1)return;let Le=ye,Re=-1;do{if(yield Re=w[Le],Le=Le%3===2?Le-2:Le+1,w[Le]!==t)return;if(Le=C[Le],Le===-1){const Ne=d[(v[t]+1)%d.length];Ne!==Re&&(yield Ne);return}}while(Le!==ye)}find(t,r,d=0){if(t=+t,t!==t||(r=+r,r!==r))return-1;const v=d;let C;for(;(C=this._step(d,t,r))>=0&&C!==d&&C!==v;)d=C;return C}_step(t,r,d){const{inedges:v,hull:C,_hullIndex:w,halfedges:E,triangles:ye,points:Le}=this;if(v[t]===-1||!Le.length)return(t+1)%(Le.length>>1);let Re=t,Ne=pow(r-Le[t*2],2)+pow(d-Le[t*2+1],2);const Fe=v[t];let at=Fe;do{let ot=ye[at];const Gt=pow(r-Le[ot*2],2)+pow(d-Le[ot*2+1],2);if(Gt<Ne&&(Ne=Gt,Re=ot),at=at%3===2?at-2:at+1,ye[at]!==t)break;if(at=E[at],at===-1){if(at=C[(w[t]+1)%C.length],at!==ot&&pow(r-Le[at*2],2)+pow(d-Le[at*2+1],2)<Ne)return at;break}}while(at!==Fe);return Re}render(t){const r=t==null?t=new Path:void 0,{points:d,halfedges:v,triangles:C}=this;for(let w=0,E=v.length;w<E;++w){const ye=v[w];if(ye<w)continue;const Le=C[w]*2,Re=C[ye]*2;t.moveTo(d[Le],d[Le+1]),t.lineTo(d[Re],d[Re+1])}return this.renderHull(t),r&&r.value()}renderPoints(t,r){r===void 0&&(!t||typeof t.moveTo!="function")&&(r=t,t=null),r=r==null?2:+r;const d=t==null?t=new Path:void 0,{points:v}=this;for(let C=0,w=v.length;C<w;C+=2){const E=v[C],ye=v[C+1];t.moveTo(E+r,ye),t.arc(E,ye,r,0,tau)}return d&&d.value()}renderHull(t){const r=t==null?t=new Path:void 0,{hull:d,points:v}=this,C=d[0]*2,w=d.length;t.moveTo(v[C],v[C+1]);for(let E=1;E<w;++E){const ye=2*d[E];t.lineTo(v[ye],v[ye+1])}return t.closePath(),r&&r.value()}hullPolygon(){const t=new Polygon;return this.renderHull(t),t.value()}renderTriangle(t,r){const d=r==null?r=new Path:void 0,{points:v,triangles:C}=this,w=C[t*=3]*2,E=C[t+1]*2,ye=C[t+2]*2;return r.moveTo(v[w],v[w+1]),r.lineTo(v[E],v[E+1]),r.lineTo(v[ye],v[ye+1]),r.closePath(),d&&d.value()}*trianglePolygons(){const{triangles:t}=this;for(let r=0,d=t.length/3;r<d;++r)yield this.trianglePolygon(r)}trianglePolygon(t){const r=new Polygon;return this.renderTriangle(t,r),r.value()}}function flatArray(g,t,r,d){const v=g.length,C=new Float64Array(v*2);for(let w=0;w<v;++w){const E=g[w];C[w*2]=t.call(d,E,w,g),C[w*2+1]=r.call(d,E,w,g)}return C}function*flatIterable(g,t,r,d){let v=0;for(const C of g)yield t.call(d,C,v,g),yield r.call(d,C,v,g),++v}const pi$1=Math.PI,halfPi=pi$1/2,degrees=180/pi$1,radians=pi$1/180,atan2=Math.atan2,cos=Math.cos,max$1=Math.max,min=Math.min,sin=Math.sin,sign=Math.sign||function(g){return g>0?1:g<0?-1:0},sqrt=Math.sqrt;function asin(g){return g>1?halfPi:g<-1?-halfPi:Math.asin(g)}function cartesianDot(g,t){return g[0]*t[0]+g[1]*t[1]+g[2]*t[2]}function cartesianCross(g,t){return[g[1]*t[2]-g[2]*t[1],g[2]*t[0]-g[0]*t[2],g[0]*t[1]-g[1]*t[0]]}function cartesianAdd(g,t){return[g[0]+t[0],g[1]+t[1],g[2]+t[2]]}function cartesianNormalize(g){var t=sqrt(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]);return[g[0]/t,g[1]/t,g[2]/t]}function spherical(g){return[atan2(g[1],g[0])*degrees,asin(max$1(-1,min(1,g[2])))*degrees]}function cartesian(g){const t=g[0]*radians,r=g[1]*radians,d=cos(r);return[d*cos(t),d*sin(t),sin(r)]}function excess(g){return g=g.map(t=>cartesian(t)),cartesianDot(g[0],cartesianCross(g[2],g[1]))}function geoDelaunay(g){const t=geo_delaunay_from(g),r=geo_triangles(t),d=geo_edges(r,g),v=geo_neighbors(r,g.length),C=geo_find(v,g),w=geo_circumcenters(r,g),{polygons:E,centers:ye}=geo_polygons(w,r,g),Le=geo_mesh(E),Re=geo_hull(r,g),Ne=geo_urquhart(d,r);return{delaunay:t,edges:d,triangles:r,centers:ye,neighbors:v,polygons:E,mesh:Le,hull:Re,urquhart:Ne,find:C}}function geo_find(g,t){function r(d,v){let C=d[0]-v[0],w=d[1]-v[1],E=d[2]-v[2];return C*C+w*w+E*E}return function(v,C,w){w===void 0&&(w=0);let E,ye,Le=w;const Re=cartesian([v,C]);do E=w,w=null,ye=r(Re,cartesian(t[E])),g[E].forEach(Ne=>{let Fe=r(Re,cartesian(t[Ne]));if(Fe<ye){ye=Fe,w=Ne,Le=Ne;return}});while(w!==null);return Le}}function geo_delaunay_from(g){if(g.length<2)return{};let t=0;for(;isNaN(g[t][0]+g[t][1])&&t++<g.length;);const r=geoRotation(g[t]),d=geoStereographic().translate([0,0]).scale(1).rotate(r.invert([180,0]));g=g.map(d);const v=[];let C=1;for(let Ne=0,Fe=g.length;Ne<Fe;Ne++){let at=mn(g[Ne][0],2)+mn(g[Ne][1],2);!isFinite(at)||at>1e32?v.push(Ne):at>C&&(C=at)}const w=1e6*sqrt(C);v.forEach(Ne=>g[Ne]=[w,0]),g.push([0,w]),g.push([-w,0]),g.push([0,-w]);const E=Delaunay.from(g);E.projection=d;const{triangles:ye,halfedges:Le,inedges:Re}=E;for(let Ne=0,Fe=Le.length;Ne<Fe;Ne++)if(Le[Ne]<0){const at=Ne%3==2?Ne-2:Ne+1,ot=Ne%3==0?Ne+2:Ne-1,Gt=Le[at],ht=Le[ot];Le[Gt]=ht,Le[ht]=Gt,Le[at]=Le[ot]=-1,ye[Ne]=ye[at]=ye[ot]=t,Re[ye[Gt]]=Gt%3==0?Gt+2:Gt-1,Re[ye[ht]]=ht%3==0?ht+2:ht-1,Ne+=2-Ne%3}else ye[Ne]>g.length-3-1&&(ye[Ne]=t);return E}function geo_edges(g,t){const r=new Set;return t.length===2?[[0,1]]:(g.forEach(d=>{if(d[0]!==d[1]&&!(excess(d.map(v=>t[v]))<0))for(let v=0,C;v<3;v++)C=(v+1)%3,r.add(extent([d[v],d[C]]).join("-"))}),Array.from(r,d=>d.split("-").map(Number)))}function geo_triangles(g){const{triangles:t}=g;if(!t)return[];const r=[];for(let d=0,v=t.length/3;d<v;d++){const C=t[3*d],w=t[3*d+1],E=t[3*d+2];C!==w&&w!==E&&r.push([C,E,w])}return r}function geo_circumcenters(g,t){return g.map(r=>{const d=r.map(C=>t[C]).map(cartesian),v=cartesianAdd(cartesianAdd(cartesianCross(d[1],d[0]),cartesianCross(d[2],d[1])),cartesianCross(d[0],d[2]));return spherical(cartesianNormalize(v))})}function geo_neighbors(g,t){const r=[];return g.forEach(d=>{for(let v=0;v<3;v++){const C=d[v],w=d[(v+1)%3];r[C]=r[C]||[],r[C].push(w)}}),g.length===0&&(t===2?(r[0]=[1],r[1]=[0]):t===1&&(r[0]=[])),r}function geo_polygons(g,t,r){const d=[],v=g.slice();if(t.length===0){if(r.length<2)return{polygons:d,centers:v};if(r.length===2){const E=cartesian(r[0]),ye=cartesian(r[1]),Le=cartesianNormalize(cartesianAdd(E,ye)),Re=cartesianNormalize(cartesianCross(E,ye)),Ne=cartesianCross(Le,Re),Fe=[Le,cartesianCross(Le,Ne),cartesianCross(cartesianCross(Le,Ne),Ne),cartesianCross(cartesianCross(cartesianCross(Le,Ne),Ne),Ne)].map(spherical).map(w);return d.push(Fe),d.push(Fe.slice().reverse()),{polygons:d,centers:v}}}t.forEach((E,ye)=>{for(let Le=0;Le<3;Le++){const Re=E[Le],Ne=E[(Le+1)%3],Fe=E[(Le+2)%3];d[Re]=d[Re]||[],d[Re].push([Ne,Fe,ye,[Re,Ne,Fe]])}});const C=d.map(E=>{const ye=[E[0][2]];let Le=E[0][1];for(let Re=1;Re<E.length;Re++)for(let Ne=0;Ne<E.length;Ne++)if(E[Ne][0]==Le){Le=E[Ne][1],ye.push(E[Ne][2]);break}if(ye.length>2)return ye;if(ye.length==2){const Re=o_midpoint(r[E[0][3][0]],r[E[0][3][1]],v[ye[0]]),Ne=o_midpoint(r[E[0][3][2]],r[E[0][3][0]],v[ye[0]]),Fe=w(Re),at=w(Ne);return[ye[0],at,ye[1],Fe]}});function w(E){let ye=-1;return v.slice(t.length,1/0).forEach((Le,Re)=>{Le[0]===E[0]&&Le[1]===E[1]&&(ye=Re+t.length)}),ye<0&&(ye=v.length,v.push(E)),ye}return{polygons:C,centers:v}}function o_midpoint(g,t,r){g=cartesian(g),t=cartesian(t),r=cartesian(r);const d=sign(cartesianDot(cartesianCross(t,g),r));return spherical(cartesianNormalize(cartesianAdd(g,t)).map(v=>d*v))}function geo_mesh(g){const t=[];return g.forEach(r=>{if(!r)return;let d=r[r.length-1];for(let v of r)v>d&&t.push([d,v]),d=v}),t}function geo_urquhart(g,t){return function(r){const d=new Map,v=new Map;return g.forEach((C,w)=>{const E=C.join("-");d.set(E,r[w]),v.set(E,!0)}),t.forEach(C=>{let w=0,E=-1;for(let ye=0;ye<3;ye++){let Le=extent([C[ye],C[(ye+1)%3]]).join("-");d.get(Le)>w&&(w=d.get(Le),E=Le)}v.set(E,!1)}),g.map(C=>v.get(C.join("-")))}}function geo_hull(g,t){const r=new Set,d=[];g.map(E=>{if(!(excess(E.map(ye=>t[ye>t.length?0:ye]))>1e-12))for(let ye=0;ye<3;ye++){let Le=[E[ye],E[(ye+1)%3]],Re=`${Le[0]}-${Le[1]}`;r.has(Re)?r.delete(Re):r.add(`${Le[1]}-${Le[0]}`)}});const v=new Map;let C;if(r.forEach(E=>{E=E.split("-").map(Number),v.set(E[0],E[1]),C=E[0]}),C===void 0)return d;let w=C;do{d.push(w);let E=v.get(w);v.set(w,-1),w=E}while(w>-1&&w!==C);return d}function geoVoronoi(g){const t=function(r){if(t.delaunay=null,t._data=r,typeof t._data=="object"&&t._data.type==="FeatureCollection"&&(t._data=t._data.features),typeof t._data=="object"){const d=t._data.map(v=>[t._vx(v),t._vy(v),v]).filter(v=>isFinite(v[0]+v[1]));t.points=d.map(v=>[v[0],v[1]]),t.valid=d.map(v=>v[2]),t.delaunay=geoDelaunay(t.points)}return t};return t._vx=function(r){if(typeof r=="object"&&"type"in r)return geoCentroid(r)[0];if(0 in r)return r[0]},t._vy=function(r){if(typeof r=="object"&&"type"in r)return geoCentroid(r)[1];if(1 in r)return r[1]},t.x=function(r){return r?(t._vx=r,t):t._vx},t.y=function(r){return r?(t._vy=r,t):t._vy},t.polygons=function(r){if(r!==void 0&&t(r),!t.delaunay)return!1;const d={type:"FeatureCollection",features:[]};return t.valid.length===0||(t.delaunay.polygons.forEach((v,C)=>d.features.push({type:"Feature",geometry:v?{type:"Polygon",coordinates:[[...v,v[0]].map(w=>t.delaunay.centers[w])]}:null,properties:{site:t.valid[C],sitecoordinates:t.points[C],neighbours:t.delaunay.neighbors[C]}})),t.valid.length===1&&d.features.push({type:"Feature",geometry:{type:"Sphere"},properties:{site:t.valid[0],sitecoordinates:t.points[0],neighbours:[]}})),d},t.triangles=function(r){return r!==void 0&&t(r),t.delaunay?{type:"FeatureCollection",features:t.delaunay.triangles.map((d,v)=>(d=d.map(C=>t.points[C]),d.center=t.delaunay.centers[v],d)).filter(d=>excess(d)>0).map(d=>({type:"Feature",properties:{circumcenter:d.center},geometry:{type:"Polygon",coordinates:[[...d,d[0]]]}}))}:!1},t.links=function(r){if(r!==void 0&&t(r),!t.delaunay)return!1;const d=t.delaunay.edges.map(C=>$t(t.points[C[0]],t.points[C[1]])),v=t.delaunay.urquhart(d);return{type:"FeatureCollection",features:t.delaunay.edges.map((C,w)=>({type:"Feature",properties:{source:t.valid[C[0]],target:t.valid[C[1]],length:d[w],urquhart:!!v[w]},geometry:{type:"LineString",coordinates:[t.points[C[0]],t.points[C[1]]]}}))}},t.mesh=function(r){return r!==void 0&&t(r),t.delaunay?{type:"MultiLineString",coordinates:t.delaunay.edges.map(d=>[t.points[d[0]],t.points[d[1]]])}:!1},t.cellMesh=function(r){if(r!==void 0&&t(r),!t.delaunay)return!1;const{centers:d,polygons:v}=t.delaunay,C=[];for(const w of v)if(w)for(let E=w.length,ye=w[E-1],Le=w[0],Re=0;Re<E;ye=Le,Le=w[++Re])Le>ye&&C.push([d[ye],d[Le]]);return{type:"MultiLineString",coordinates:C}},t._found=void 0,t.find=function(r,d,v){if(t._found=t.delaunay.find(r,d,t._found),!v||$t([r,d],t.points[t._found])<v)return t._found},t.hull=function(r){r!==void 0&&t(r);const d=t.delaunay.hull,v=t.points;return d.length===0?null:{type:"Polygon",coordinates:[[...d.map(C=>v[C]),v[d[0]]]]}},g?t(g):t}function initRange(g,t){switch(arguments.length){case 0:break;case 1:this.range(g);break;default:this.range(t).domain(g);break}return this}function define$1(g,t,r){g.prototype=t.prototype=r,r.constructor=g}function extend(g,t){var r=Object.create(g.prototype);for(var d in t)r[d]=t[d];return r}function Color(){}var darker=.7,brighter=1/darker,reI="\\s*([+-]?\\d+)\\s*",reN="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",reP="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",reHex=/^#([0-9a-f]{3,8})$/,reRgbInteger=new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`),reRgbPercent=new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`),reRgbaInteger=new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`),reRgbaPercent=new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`),reHslPercent=new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`),reHslaPercent=new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`),named={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};define$1(Color,color,{copy(g){return Object.assign(new this.constructor,this,g)},displayable(){return this.rgb().displayable()},hex:color_formatHex,formatHex:color_formatHex,formatHex8:color_formatHex8,formatHsl:color_formatHsl,formatRgb:color_formatRgb,toString:color_formatRgb});function color_formatHex(){return this.rgb().formatHex()}function color_formatHex8(){return this.rgb().formatHex8()}function color_formatHsl(){return hslConvert(this).formatHsl()}function color_formatRgb(){return this.rgb().formatRgb()}function color(g){var t,r;return g=(g+"").trim().toLowerCase(),(t=reHex.exec(g))?(r=t[1].length,t=parseInt(t[1],16),r===6?rgbn(t):r===3?new Rgb(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):r===8?rgba(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):r===4?rgba(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=reRgbInteger.exec(g))?new Rgb(t[1],t[2],t[3],1):(t=reRgbPercent.exec(g))?new Rgb(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=reRgbaInteger.exec(g))?rgba(t[1],t[2],t[3],t[4]):(t=reRgbaPercent.exec(g))?rgba(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=reHslPercent.exec(g))?hsla(t[1],t[2]/100,t[3]/100,1):(t=reHslaPercent.exec(g))?hsla(t[1],t[2]/100,t[3]/100,t[4]):named.hasOwnProperty(g)?rgbn(named[g]):g==="transparent"?new Rgb(NaN,NaN,NaN,0):null}function rgbn(g){return new Rgb(g>>16&255,g>>8&255,g&255,1)}function rgba(g,t,r,d){return d<=0&&(g=t=r=NaN),new Rgb(g,t,r,d)}function rgbConvert(g){return g instanceof Color||(g=color(g)),g?(g=g.rgb(),new Rgb(g.r,g.g,g.b,g.opacity)):new Rgb}function rgb$1(g,t,r,d){return arguments.length===1?rgbConvert(g):new Rgb(g,t,r,d==null?1:d)}function Rgb(g,t,r,d){this.r=+g,this.g=+t,this.b=+r,this.opacity=+d}define$1(Rgb,rgb$1,extend(Color,{brighter(g){return g=g==null?brighter:Math.pow(brighter,g),new Rgb(this.r*g,this.g*g,this.b*g,this.opacity)},darker(g){return g=g==null?darker:Math.pow(darker,g),new Rgb(this.r*g,this.g*g,this.b*g,this.opacity)},rgb(){return this},clamp(){return new Rgb(clampi(this.r),clampi(this.g),clampi(this.b),clampa(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:rgb_formatHex,formatHex:rgb_formatHex,formatHex8:rgb_formatHex8,formatRgb:rgb_formatRgb,toString:rgb_formatRgb}));function rgb_formatHex(){return`#${hex(this.r)}${hex(this.g)}${hex(this.b)}`}function rgb_formatHex8(){return`#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity)?1:this.opacity)*255)}`}function rgb_formatRgb(){const g=clampa(this.opacity);return`${g===1?"rgb(":"rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${g===1?")":`, ${g})`}`}function clampa(g){return isNaN(g)?1:Math.max(0,Math.min(1,g))}function clampi(g){return Math.max(0,Math.min(255,Math.round(g)||0))}function hex(g){return g=clampi(g),(g<16?"0":"")+g.toString(16)}function hsla(g,t,r,d){return d<=0?g=t=r=NaN:r<=0||r>=1?g=t=NaN:t<=0&&(g=NaN),new Hsl(g,t,r,d)}function hslConvert(g){if(g instanceof Hsl)return new Hsl(g.h,g.s,g.l,g.opacity);if(g instanceof Color||(g=color(g)),!g)return new Hsl;if(g instanceof Hsl)return g;g=g.rgb();var t=g.r/255,r=g.g/255,d=g.b/255,v=Math.min(t,r,d),C=Math.max(t,r,d),w=NaN,E=C-v,ye=(C+v)/2;return E?(t===C?w=(r-d)/E+(r<d)*6:r===C?w=(d-t)/E+2:w=(t-r)/E+4,E/=ye<.5?C+v:2-C-v,w*=60):E=ye>0&&ye<1?0:w,new Hsl(w,E,ye,g.opacity)}function hsl(g,t,r,d){return arguments.length===1?hslConvert(g):new Hsl(g,t,r,d==null?1:d)}function Hsl(g,t,r,d){this.h=+g,this.s=+t,this.l=+r,this.opacity=+d}define$1(Hsl,hsl,extend(Color,{brighter(g){return g=g==null?brighter:Math.pow(brighter,g),new Hsl(this.h,this.s,this.l*g,this.opacity)},darker(g){return g=g==null?darker:Math.pow(darker,g),new Hsl(this.h,this.s,this.l*g,this.opacity)},rgb(){var g=this.h%360+(this.h<0)*360,t=isNaN(g)||isNaN(this.s)?0:this.s,r=this.l,d=r+(r<.5?r:1-r)*t,v=2*r-d;return new Rgb(hsl2rgb(g>=240?g-240:g+120,v,d),hsl2rgb(g,v,d),hsl2rgb(g<120?g+240:g-120,v,d),this.opacity)},clamp(){return new Hsl(clamph(this.h),clampt(this.s),clampt(this.l),clampa(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const g=clampa(this.opacity);return`${g===1?"hsl(":"hsla("}${clamph(this.h)}, ${clampt(this.s)*100}%, ${clampt(this.l)*100}%${g===1?")":`, ${g})`}`}}));function clamph(g){return g=(g||0)%360,g<0?g+360:g}function clampt(g){return Math.max(0,Math.min(1,g||0))}function hsl2rgb(g,t,r){return(g<60?t+(r-t)*g/60:g<180?r:g<240?t+(r-t)*(240-g)/60:t)*255}const constant=g=>()=>g;function linear$1(g,t){return function(r){return g+r*t}}function exponential(g,t,r){return g=Math.pow(g,r),t=Math.pow(t,r)-g,r=1/r,function(d){return Math.pow(g+d*t,r)}}function gamma(g){return(g=+g)==1?nogamma:function(t,r){return r-t?exponential(t,r,g):constant(isNaN(t)?r:t)}}function nogamma(g,t){var r=t-g;return r?linear$1(g,r):constant(isNaN(g)?t:g)}const rgb=function g(t){var r=gamma(t);function d(v,C){var w=r((v=rgb$1(v)).r,(C=rgb$1(C)).r),E=r(v.g,C.g),ye=r(v.b,C.b),Le=nogamma(v.opacity,C.opacity);return function(Re){return v.r=w(Re),v.g=E(Re),v.b=ye(Re),v.opacity=Le(Re),v+""}}return d.gamma=g,d}(1);function numberArray(g,t){t||(t=[]);var r=g?Math.min(t.length,g.length):0,d=t.slice(),v;return function(C){for(v=0;v<r;++v)d[v]=g[v]*(1-C)+t[v]*C;return d}}function isNumberArray(g){return ArrayBuffer.isView(g)&&!(g instanceof DataView)}function genericArray(g,t){var r=t?t.length:0,d=g?Math.min(r,g.length):0,v=new Array(d),C=new Array(r),w;for(w=0;w<d;++w)v[w]=interpolate(g[w],t[w]);for(;w<r;++w)C[w]=t[w];return function(E){for(w=0;w<d;++w)C[w]=v[w](E);return C}}function date(g,t){var r=new Date;return g=+g,t=+t,function(d){return r.setTime(g*(1-d)+t*d),r}}function interpolateNumber(g,t){return g=+g,t=+t,function(r){return g*(1-r)+t*r}}function object(g,t){var r={},d={},v;(g===null||typeof g!="object")&&(g={}),(t===null||typeof t!="object")&&(t={});for(v in t)v in g?r[v]=interpolate(g[v],t[v]):d[v]=t[v];return function(C){for(v in r)d[v]=r[v](C);return d}}var reA=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,reB=new RegExp(reA.source,"g");function zero(g){return function(){return g}}function one(g){return function(t){return g(t)+""}}function string(g,t){var r=reA.lastIndex=reB.lastIndex=0,d,v,C,w=-1,E=[],ye=[];for(g=g+"",t=t+"";(d=reA.exec(g))&&(v=reB.exec(t));)(C=v.index)>r&&(C=t.slice(r,C),E[w]?E[w]+=C:E[++w]=C),(d=d[0])===(v=v[0])?E[w]?E[w]+=v:E[++w]=v:(E[++w]=null,ye.push({i:w,x:interpolateNumber(d,v)})),r=reB.lastIndex;return r<t.length&&(C=t.slice(r),E[w]?E[w]+=C:E[++w]=C),E.length<2?ye[0]?one(ye[0].x):zero(t):(t=ye.length,function(Le){for(var Re=0,Ne;Re<t;++Re)E[(Ne=ye[Re]).i]=Ne.x(Le);return E.join("")})}function interpolate(g,t){var r=typeof t,d;return t==null||r==="boolean"?constant(t):(r==="number"?interpolateNumber:r==="string"?(d=color(t))?(t=d,rgb):string:t instanceof color?rgb:t instanceof Date?date:isNumberArray(t)?numberArray:Array.isArray(t)?genericArray:typeof t.valueOf!="function"&&typeof t.toString!="function"||isNaN(t)?object:interpolateNumber)(g,t)}function interpolateRound(g,t){return g=+g,t=+t,function(r){return Math.round(g*(1-r)+t*r)}}function constants(g){return function(){return g}}function number(g){return+g}var unit=[0,1];function identity$1(g){return g}function normalize(g,t){return(t-=g=+g)?function(r){return(r-g)/t}:constants(isNaN(t)?NaN:.5)}function clamper(g,t){var r;return g>t&&(r=g,g=t,t=r),function(d){return Math.max(g,Math.min(t,d))}}function bimap(g,t,r){var d=g[0],v=g[1],C=t[0],w=t[1];return v<d?(d=normalize(v,d),C=r(w,C)):(d=normalize(d,v),C=r(C,w)),function(E){return C(d(E))}}function polymap(g,t,r){var d=Math.min(g.length,t.length)-1,v=new Array(d),C=new Array(d),w=-1;for(g[d]<g[0]&&(g=g.slice().reverse(),t=t.slice().reverse());++w<d;)v[w]=normalize(g[w],g[w+1]),C[w]=r(t[w],t[w+1]);return function(E){var ye=bisectRight(g,E,1,d)-1;return C[ye](v[ye](E))}}function copy(g,t){return t.domain(g.domain()).range(g.range()).interpolate(g.interpolate()).clamp(g.clamp()).unknown(g.unknown())}function transformer(){var g=unit,t=unit,r=interpolate,d,v,C,w=identity$1,E,ye,Le;function Re(){var Fe=Math.min(g.length,t.length);return w!==identity$1&&(w=clamper(g[0],g[Fe-1])),E=Fe>2?polymap:bimap,ye=Le=null,Ne}function Ne(Fe){return Fe==null||isNaN(Fe=+Fe)?C:(ye||(ye=E(g.map(d),t,r)))(d(w(Fe)))}return Ne.invert=function(Fe){return w(v((Le||(Le=E(t,g.map(d),interpolateNumber)))(Fe)))},Ne.domain=function(Fe){return arguments.length?(g=Array.from(Fe,number),Re()):g.slice()},Ne.range=function(Fe){return arguments.length?(t=Array.from(Fe),Re()):t.slice()},Ne.rangeRound=function(Fe){return t=Array.from(Fe),r=interpolateRound,Re()},Ne.clamp=function(Fe){return arguments.length?(w=Fe?!0:identity$1,Re()):w!==identity$1},Ne.interpolate=function(Fe){return arguments.length?(r=Fe,Re()):r},Ne.unknown=function(Fe){return arguments.length?(C=Fe,Ne):C},function(Fe,at){return d=Fe,v=at,Re()}}function continuous(){return transformer()(identity$1,identity$1)}function formatDecimal(g){return Math.abs(g=Math.round(g))>=1e21?g.toLocaleString("en").replace(/,/g,""):g.toString(10)}function formatDecimalParts(g,t){if((r=(g=t?g.toExponential(t-1):g.toExponential()).indexOf("e"))<0)return null;var r,d=g.slice(0,r);return[d.length>1?d[0]+d.slice(2):d,+g.slice(r+1)]}function exponent(g){return g=formatDecimalParts(Math.abs(g)),g?g[1]:NaN}function formatGroup(g,t){return function(r,d){for(var v=r.length,C=[],w=0,E=g[0],ye=0;v>0&&E>0&&(ye+E+1>d&&(E=Math.max(1,d-ye)),C.push(r.substring(v-=E,v+E)),!((ye+=E+1)>d));)E=g[w=(w+1)%g.length];return C.reverse().join(t)}}function formatNumerals(g){return function(t){return t.replace(/[0-9]/g,function(r){return g[+r]})}}var re$2=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function formatSpecifier(g){if(!(t=re$2.exec(g)))throw new Error("invalid format: "+g);var t;return new FormatSpecifier({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}formatSpecifier.prototype=FormatSpecifier.prototype;function FormatSpecifier(g){this.fill=g.fill===void 0?" ":g.fill+"",this.align=g.align===void 0?">":g.align+"",this.sign=g.sign===void 0?"-":g.sign+"",this.symbol=g.symbol===void 0?"":g.symbol+"",this.zero=!!g.zero,this.width=g.width===void 0?void 0:+g.width,this.comma=!!g.comma,this.precision=g.precision===void 0?void 0:+g.precision,this.trim=!!g.trim,this.type=g.type===void 0?"":g.type+""}FormatSpecifier.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function formatTrim(g){e:for(var t=g.length,r=1,d=-1,v;r<t;++r)switch(g[r]){case".":d=v=r;break;case"0":d===0&&(d=r),v=r;break;default:if(!+g[r])break e;d>0&&(d=0);break}return d>0?g.slice(0,d)+g.slice(v+1):g}var prefixExponent;function formatPrefixAuto(g,t){var r=formatDecimalParts(g,t);if(!r)return g+"";var d=r[0],v=r[1],C=v-(prefixExponent=Math.max(-8,Math.min(8,Math.floor(v/3)))*3)+1,w=d.length;return C===w?d:C>w?d+new Array(C-w+1).join("0"):C>0?d.slice(0,C)+"."+d.slice(C):"0."+new Array(1-C).join("0")+formatDecimalParts(g,Math.max(0,t+C-1))[0]}function formatRounded(g,t){var r=formatDecimalParts(g,t);if(!r)return g+"";var d=r[0],v=r[1];return v<0?"0."+new Array(-v).join("0")+d:d.length>v+1?d.slice(0,v+1)+"."+d.slice(v+1):d+new Array(v-d.length+2).join("0")}const formatTypes={"%":(g,t)=>(g*100).toFixed(t),b:g=>Math.round(g).toString(2),c:g=>g+"",d:formatDecimal,e:(g,t)=>g.toExponential(t),f:(g,t)=>g.toFixed(t),g:(g,t)=>g.toPrecision(t),o:g=>Math.round(g).toString(8),p:(g,t)=>formatRounded(g*100,t),r:formatRounded,s:formatPrefixAuto,X:g=>Math.round(g).toString(16).toUpperCase(),x:g=>Math.round(g).toString(16)};function identity(g){return g}var map$1=Array.prototype.map,prefixes=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function formatLocale(g){var t=g.grouping===void 0||g.thousands===void 0?identity:formatGroup(map$1.call(g.grouping,Number),g.thousands+""),r=g.currency===void 0?"":g.currency[0]+"",d=g.currency===void 0?"":g.currency[1]+"",v=g.decimal===void 0?".":g.decimal+"",C=g.numerals===void 0?identity:formatNumerals(map$1.call(g.numerals,String)),w=g.percent===void 0?"%":g.percent+"",E=g.minus===void 0?"−":g.minus+"",ye=g.nan===void 0?"NaN":g.nan+"";function Le(Ne){Ne=formatSpecifier(Ne);var Fe=Ne.fill,at=Ne.align,ot=Ne.sign,Gt=Ne.symbol,ht=Ne.zero,ke=Ne.width,ct=Ne.comma,xt=Ne.precision,Rt=Ne.trim,Wt=Ne.type;Wt==="n"?(ct=!0,Wt="g"):formatTypes[Wt]||(xt===void 0&&(xt=12),Rt=!0,Wt="g"),(ht||Fe==="0"&&at==="=")&&(ht=!0,Fe="0",at="=");var Pt=Gt==="$"?r:Gt==="#"&&/[boxX]/.test(Wt)?"0"+Wt.toLowerCase():"",Nt=Gt==="$"?d:/[%p]/.test(Wt)?w:"",Kt=formatTypes[Wt],Ft=/[defgprs%]/.test(Wt);xt=xt===void 0?6:/[gprs]/.test(Wt)?Math.max(1,Math.min(21,xt)):Math.max(0,Math.min(20,xt));function kt(Yt){var s0=Pt,o0=Nt,h0,r0,e0;if(Wt==="c")o0=Kt(Yt)+o0,Yt="";else{Yt=+Yt;var i0=Yt<0||1/Yt<0;if(Yt=isNaN(Yt)?ye:Kt(Math.abs(Yt),xt),Rt&&(Yt=formatTrim(Yt)),i0&&+Yt==0&&ot!=="+"&&(i0=!1),s0=(i0?ot==="("?ot:E:ot==="-"||ot==="("?"":ot)+s0,o0=(Wt==="s"?prefixes[8+prefixExponent/3]:"")+o0+(i0&&ot==="("?")":""),Ft){for(h0=-1,r0=Yt.length;++h0<r0;)if(e0=Yt.charCodeAt(h0),48>e0||e0>57){o0=(e0===46?v+Yt.slice(h0+1):Yt.slice(h0))+o0,Yt=Yt.slice(0,h0);break}}}ct&&!ht&&(Yt=t(Yt,1/0));var Ut=s0.length+Yt.length+o0.length,l0=Ut<ke?new Array(ke-Ut+1).join(Fe):"";switch(ct&&ht&&(Yt=t(l0+Yt,l0.length?ke-o0.length:1/0),l0=""),at){case"<":Yt=s0+Yt+o0+l0;break;case"=":Yt=s0+l0+Yt+o0;break;case"^":Yt=l0.slice(0,Ut=l0.length>>1)+s0+Yt+o0+l0.slice(Ut);break;default:Yt=l0+s0+Yt+o0;break}return C(Yt)}return kt.toString=function(){return Ne+""},kt}function Re(Ne,Fe){var at=Le((Ne=formatSpecifier(Ne),Ne.type="f",Ne)),ot=Math.max(-8,Math.min(8,Math.floor(exponent(Fe)/3)))*3,Gt=Math.pow(10,-ot),ht=prefixes[8+ot/3];return function(ke){return at(Gt*ke)+ht}}return{format:Le,formatPrefix:Re}}var locale,format,formatPrefix;defaultLocale({thousands:",",grouping:[3],currency:["$",""]});function defaultLocale(g){return locale=formatLocale(g),format=locale.format,formatPrefix=locale.formatPrefix,locale}function precisionFixed(g){return Math.max(0,-exponent(Math.abs(g)))}function precisionPrefix(g,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(exponent(t)/3)))*3-exponent(Math.abs(g)))}function precisionRound(g,t){return g=Math.abs(g),t=Math.abs(t)-g,Math.max(0,exponent(t)-exponent(g))+1}function tickFormat(g,t,r,d){var v=tickStep(g,t,r),C;switch(d=formatSpecifier(d==null?",f":d),d.type){case"s":{var w=Math.max(Math.abs(g),Math.abs(t));return d.precision==null&&!isNaN(C=precisionPrefix(v,w))&&(d.precision=C),formatPrefix(d,w)}case"":case"e":case"g":case"p":case"r":{d.precision==null&&!isNaN(C=precisionRound(v,Math.max(Math.abs(g),Math.abs(t))))&&(d.precision=C-(d.type==="e"));break}case"f":case"%":{d.precision==null&&!isNaN(C=precisionFixed(v))&&(d.precision=C-(d.type==="%")*2);break}}return format(d)}function linearish(g){var t=g.domain;return g.ticks=function(r){var d=t();return ticks(d[0],d[d.length-1],r==null?10:r)},g.tickFormat=function(r,d){var v=t();return tickFormat(v[0],v[v.length-1],r==null?10:r,d)},g.nice=function(r){r==null&&(r=10);var d=t(),v=0,C=d.length-1,w=d[v],E=d[C],ye,Le,Re=10;for(E<w&&(Le=w,w=E,E=Le,Le=v,v=C,C=Le);Re-- >0;){if(Le=tickIncrement(w,E,r),Le===ye)return d[v]=w,d[C]=E,t(d);if(Le>0)w=Math.floor(w/Le)*Le,E=Math.ceil(E/Le)*Le;else if(Le<0)w=Math.ceil(w*Le)/Le,E=Math.floor(E*Le)/Le;else break;ye=Le}return g},g}function linear(){var g=continuous();return g.copy=function(){return copy(g,linear())},initRange.apply(g,arguments),linearish(g)}var At$1=Object.defineProperty,jt=Object.defineProperties,St$1=Object.getOwnPropertyDescriptors,tt$1=Object.getOwnPropertySymbols,Ct$1=Object.prototype.hasOwnProperty,zt=Object.prototype.propertyIsEnumerable,it$1=Math.pow,et$2=(g,t,r)=>t in g?At$1(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,L$1=(g,t)=>{for(var r in t||(t={}))Ct$1.call(t,r)&&et$2(g,r,t[r]);if(tt$1)for(var r of tt$1(t))zt.call(t,r)&&et$2(g,r,t[r]);return g},q$1=(g,t)=>jt(g,St$1(t)),st$1=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())});class O{constructor(){this.resources=new Set,this.disposeWithMaterial=!0,this.disposeVideo=!0,this.materialList={},this.disposeTrack=!0}track(t){if(!t||this.disposeTrack===!1)return t;if(Array.isArray(t))return t.forEach(r=>this.track(r)),t;if(!this.disposeWithMaterial&&t instanceof Material)return t;if(t instanceof O?(t===this&&t.object3d?this.track(t.object3d):(t.disposeTrack=!1,this.resources.add(t)),Object.values(t.materialList).map(r=>this.track(r))):(t instanceof Object3D||Reflect.has(t,"dispose"))&&this.resources.add(t),t instanceof O)this.track(t.children);else if(t instanceof Object3D){const r=t;this.track(r.geometry),this.track(r.material),this.track(r.children)}else if(t instanceof Material){for(const d of Object.values(t))d instanceof Texture&&this.track(d);const r=t;if(r.uniforms){for(const d of Object.values(r.uniforms))if(d){const v=d.value;(v instanceof Texture||Array.isArray(v))&&this.track(v)}}}else this.disposeVideo&&t instanceof VideoTexture&&t.source.data&&this.resources.add(t.source.data);return t}dispose(){const t=[];for(const r of this.resources)r instanceof Object3D?t.push(r):r instanceof HTMLVideoElement&&r.pause(),Reflect.has(r,"dispose")&&r.dispose();t.forEach(r=>{r.removeFromParent()}),t.length=0,this.resources.clear()}}const ee$1=(g,t=1)=>{const r=new BufferGeometry;r.setAttribute("position",new Float32BufferAttribute(new Array(t*3).fill(0),3)),r.setAttribute("scaleAtt",new Float32BufferAttribute(new Array(t).fill(1),1));const d=g.material,v=new PointsMaterial({size:10,map:d.map,alphaMap:d.alphaMap,color:d.color,blending:d.blending,depthTest:d.depthTest,depthWrite:!1,opacity:d.opacity,transparent:!0,alphaTest:d.alphaTest,sizeAttenuation:!1});return v.onBeforeCompile=C=>{C.vertexShader=`
3844
3844
  attribute float scaleAtt;
3845
3845
  ${C.vertexShader.replace("gl_PointSize = size;","gl_PointSize = size * scaleAtt;")}
3846
3846
  `},new Points(r,v)};let ie$1=class extends O{constructor(){super(...arguments),this.objectType="BaseObject",this.userData={},this.prefab=!1,this.isInstantiate=!1,this.isBloom=!1,this.materialList={},this.useMaterialType="origin",this.onPointerIndex=[]}get parent(){const t=this.object3d.parent;return t&&this.lead.objMap.get(t)||null}get children(){return this.object3d.children.map(t=>this.lead.objMap.get(t)).filter(t=>!!t)}get position(){return this.object3d.position}get rotation(){return this.object3d.rotation}get scale(){return this.object3d.scale}get add(){return this.object3d.add.bind(this.object3d)}get remove(){return this.object3d.remove.bind(this.object3d)}get visible(){return this.object3d.visible}get visibleWithAncestors(){if(this.visible){let t=this.parent;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}else return!1}create(){this.createGroup()}render(){}update(t,r){}resize(t,r){}show(){return this.object3d.visible=!0,this}hide(){return this.object3d.visible=!1,this}createMesh(...t){return this.object3d=new Mesh(...t),this}createGroup(){return this.object3d=new Group$1,this}createPoints(...t){return this.object3d=new Points(...t),this}createCSS2DObject(t){return this.object3d=new CSS2DObject(t),this}createCSS3DObject(t){return this.object3d=new CSS3DObject(t),this}createCSS3DSprite(t){return this.object3d=new CSS3DSprite(t),this}createSprite(t){return this.object3d=new Sprite$1(t),this}attach(...t){return[...t].forEach(r=>{this.object3d.attach(r.object3d)}),this}getSize(){const t=new Box3().setFromObject(this.object3d);return{min:t.min,max:t.max,size:t.getSize(new Vector3),center:t.getCenter(new Vector3)}}traverse(t){t(this),this.children.forEach(r=>{r.traverse(t)})}clone(){return this.instantiate()}instantiate(t,r){return st$1(this,null,function*(){var d;const v=t&&t.length>0,C=(d=r==null?void 0:r.recursive)!=null?d:!0,{objectType:w,objectOptions:E}=this,[,ye]=w.split("#");let Le=r==null?void 0:r.create;Le===void 0&&(Le=Ne=>{if(this.object3d){if(v){const Fe=t.length;if(this.object3d instanceof Sprite$1)Ne.object3d=ee$1(this.object3d,Fe);else{const ot=this.object3d;Ne.object3d=new InstancedMesh(ot.geometry,ot.material,Fe),Ne.setMaterialList("instantiate","clone"),Ne.useMaterial("instantiate")}const at=new Object3D;t.forEach((ot,Gt)=>{const ht=h(ot.position),ke=h(ot.scale||[1,1,1]);at.position.copy(ht),at.scale.copy(ke),at.updateMatrix(),Ne.setInstancedMatrix(Gt,at.matrix.clone())})}else Ne.object3d=this.object3d.clone(!1),Ne.setMaterialList("instantiate","clone"),Ne.useMaterial("instantiate");Ne.object3d.userData.prefab&&delete Ne.object3d.userData.prefab}});const Re=yield this.lead.draw(ye,q$1(L$1({},E||{}),{create:Le,prefab:!1,key:(r==null?void 0:r.key)||(E==null?void 0:E.key),target:(r==null?void 0:r.target)||(E==null?void 0:E.target)}));return this.isBloom&&Re.enableBloom(),C&&(yield Promise.all(this.children.map(Ne=>Ne.instantiate(void 0,{target:Re})))),Re.isInstantiate=!0,Re})}setInstancedMatrix(t,r){if(this.object3d instanceof InstancedMesh||this.object3d.isInstantiate)this.object3d.setMatrixAt(t,r);else if(this.object3d instanceof Points||this.object3d.type==="Points"){const d=this.object3d.geometry,v=d.attributes.position.array,C=d.attributes.scaleAtt.array,w=new Vector3,E=new Vector3,ye=new Quaternion,Le=t*3,Re=t*1;r.decompose(w,ye,E),v[Le]=w.x,v[Le+1]=w.y,v[Le+2]=w.z,C[Re]=Math.max(E.x,E.y,E.z),d.attributes.position.needsUpdate=!0,d.attributes.scaleAtt.needsUpdate=!0}}erase(){this.lead.erase(this)}cloneMaterial(){const t=this.object3d;if(!t||!t.material)return;const r=t.material;if(Array.isArray(r))return r.map(d=>{const v=d.userData;d.userData={};const C=d.clone();return d.userData=v,C});{const d=r.userData;r.userData={};const v=r.clone();return r.userData=d,v}}setMaterialList(t,r,d=!0){const v=this.object3d;if(!v||!v.material)return;if(this.materialList.origin||(this.materialList.origin=v.material),this.materialList[t])if(d){const w=this.materialList[t],E=new O;E.track(w),E.dispose()}else return this.materialList[t];const C=r==="clone"?this.cloneMaterial():r;return this.materialList[t]=C,C}useMaterial(t){const r=this.object3d;!r||!r.material||this.useMaterialType===t||!this.materialList[t]||(this.useMaterialType=t,r.material=this.materialList[t])}setTop(t){this.object3d&&(this.object3d.renderOrder=t)}onPointerEvent(t,r){const d=this.lead.handlePick([this],t,r);this.onPointerIndex.push(d)}enableBloom(){var t;(t=this.pencil.composerController)==null||t.setBloomSelection(this,!0),this.isBloom=!0}disableBloom(){var t;(t=this.pencil.composerController)==null||t.setBloomSelection(this,!1),this.isBloom=!1}dispose(){var t;this.onPointerIndex.forEach(r=>{this.lead.removePick(r)}),(t=this.pencil.composerController)==null||t.bloomSelection.delete(this),this.lead&&(this.lead.objects.delete(this.key),this.object3d&&this.lead.objMap.delete(this.object3d)),this.track(this),super.dispose()}disposeWithOutMaterial(){this.disposeWithMaterial=!1,this.dispose()}},ze$1=class extends ie$1{create(){this.createGroup()}};const N$2=new Vector4,dt=new Vector3,pt=new Vector3,b$2=new Vector4,y=new Vector4,I=new Vector4,Q$2=new Vector3,K$1=new Matrix4,x$3=new Line3,mt=new Vector3,U$1=new Box3,R$4=new Sphere$1,T$2=new Vector4;let W$1,_;function vt$1(g,t,r){return T$2.set(0,0,-t,1).applyMatrix4(g.projectionMatrix),T$2.multiplyScalar(1/T$2.w),T$2.x=_/r.width,T$2.y=_/r.height,T$2.applyMatrix4(g.projectionMatrixInverse),T$2.multiplyScalar(1/T$2.w),Math.abs(Math.max(T$2.x,T$2.y))}function se$1(g,t){const r=g.matrixWorld,d=g.geometry,v=d.attributes.instanceStart,C=d.attributes.instanceEnd,w=Math.min(d.instanceCount,v.count);for(let E=0,ye=w;E<ye;E++){x$3.start.fromBufferAttribute(v,E),x$3.end.fromBufferAttribute(C,E),x$3.applyMatrix4(r);const Le=new Vector3,Re=new Vector3;W$1.distanceSqToSegment(x$3.start,x$3.end,Re,Le),Re.distanceTo(Le)<_*.5&&t.push({point:Re,pointOnLine:Le,distance:W$1.origin.distanceTo(Re),object:g,face:null,faceIndex:E,uv:null,uv1:null})}}function ne$1(g,t,r){const d=t.projectionMatrix,v=g.material.resolution,C=g.matrixWorld,w=g.geometry,E=w.attributes.instanceStart,ye=w.attributes.instanceEnd,Le=Math.min(w.instanceCount,E.count),Re=-t.near;W$1.at(1,I),I.w=1,I.applyMatrix4(t.matrixWorldInverse),I.applyMatrix4(d),I.multiplyScalar(1/I.w),I.x*=v.x/2,I.y*=v.y/2,I.z=0,Q$2.copy(I),K$1.multiplyMatrices(t.matrixWorldInverse,C);for(let Ne=0,Fe=Le;Ne<Fe;Ne++){if(b$2.fromBufferAttribute(E,Ne),y.fromBufferAttribute(ye,Ne),b$2.w=1,y.w=1,b$2.applyMatrix4(K$1),y.applyMatrix4(K$1),b$2.z>Re&&y.z>Re)continue;if(b$2.z>Re){const ke=b$2.z-y.z,ct=(b$2.z-Re)/ke;b$2.lerp(y,ct)}else if(y.z>Re){const ke=y.z-b$2.z,ct=(y.z-Re)/ke;y.lerp(b$2,ct)}b$2.applyMatrix4(d),y.applyMatrix4(d),b$2.multiplyScalar(1/b$2.w),y.multiplyScalar(1/y.w),b$2.x*=v.x/2,b$2.y*=v.y/2,y.x*=v.x/2,y.y*=v.y/2,x$3.start.copy(b$2),x$3.start.z=0,x$3.end.copy(y),x$3.end.z=0;const at=x$3.closestPointToPointParameter(Q$2,!0);x$3.at(at,mt);const ot=MathUtils.lerp(b$2.z,y.z,at),Gt=ot>=-1&&ot<=1,ht=Q$2.distanceTo(mt)<_*.5;if(Gt&&ht){x$3.start.fromBufferAttribute(E,Ne),x$3.end.fromBufferAttribute(ye,Ne),x$3.start.applyMatrix4(C),x$3.end.applyMatrix4(C);const ke=new Vector3,ct=new Vector3;W$1.distanceSqToSegment(x$3.start,x$3.end,ct,ke),r.push({point:ct,pointOnLine:ke,distance:W$1.origin.distanceTo(ct),object:g,face:null,faceIndex:Ne,uv:null,uv1:null})}}}class De extends Mesh{constructor(t=new LineSegmentsGeometry,r){super(t,r),this.isLineSegments2=!0,this.type="LineSegments2"}computeLineDistances(){const t=this.geometry,r=t.attributes.instanceStart,d=t.attributes.instanceEnd,v=new Float32Array(2*r.count);for(let w=0,E=0,ye=r.count;w<ye;w++,E+=2)dt.fromBufferAttribute(r,w),pt.fromBufferAttribute(d,w),v[E]=E===0?0:v[E-1],v[E+1]=v[E]+dt.distanceTo(pt);const C=new InstancedInterleavedBuffer(v,2,1);return t.setAttribute("instanceDistanceStart",new InterleavedBufferAttribute(C,1,0)),t.setAttribute("instanceDistanceEnd",new InterleavedBufferAttribute(C,1,1)),this}raycast(t,r){const d=this.material.worldUnits,v=t.camera;v===null&&!d&&console.error('LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.');const C=t.params.Line2!==void 0&&t.params.Line2.threshold||0;W$1=t.ray;const w=this.matrixWorld,E=this.geometry,ye=this.material;_=ye.linewidth+C,E.boundingSphere===null&&E.computeBoundingSphere(),R$4.copy(E.boundingSphere).applyMatrix4(w);let Le;if(d)Le=_*.5;else{const Ne=Math.max(v.near,R$4.distanceToPoint(W$1.origin));Le=vt$1(v,Ne,ye.resolution)}if(R$4.radius+=Le,W$1.intersectsSphere(R$4)===!1)return;E.boundingBox===null&&E.computeBoundingBox(),U$1.copy(E.boundingBox).applyMatrix4(w);let Re;if(d)Re=_*.5;else{const Ne=Math.max(v.near,U$1.distanceToPoint(W$1.origin));Re=vt$1(v,Ne,ye.resolution)}U$1.expandByScalar(Re),W$1.intersectsBox(U$1)!==!1&&(d?se$1(this,r):ne$1(this,v,r))}onBeforeRender(t){const r=this.material.uniforms;r&&r.resolution&&(t.getViewport(N$2),this.material.uniforms.resolution.value.set(N$2.z,N$2.w))}}const gt$2=["encodings_fragment","colorspace_fragment"],re$1=`
@@ -4853,7 +4853,7 @@ version 0.8.2
4853
4853
  gl_FragColor = ( base_color + vec4( 1.0 ) * bloom_color );
4854
4854
  }
4855
4855
  }
4856
- `,defines:{}}),"baseTexture");return t.needsSwap=!0,t},Pe=1,me=!1,Xs=new MeshBasicMaterial({color:"black"}),qs=new PointsMaterial({color:"black",sizeAttenuation:!1}),$s=new PointsMaterial({color:"black",sizeAttenuation:!0}),Qs=new SpriteMaterial({color:"black",sizeAttenuation:!0}),Js=new SpriteMaterial({color:"black",sizeAttenuation:!1}),ei=new Ie$2({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.pipViewportState=null,this.options=t;const{rendererController:r,sceneController:d,cameraController:v,composerParams:C}=t,{renderer:w}=r;this.renderer=w;const{multisampling:E}=C,{maxSamples:ye}=w.capabilities,Le=w.getDrawingBufferSize(new Vector2),Re=new WebGLRenderTarget(Le.width,Le.height,{samples:Math.min(E,ye),type:HalfFloatType}),Ne=new EffectComposer(w,Re),Fe=this.getSize();Ne.setSize(Fe.width,Fe.height);const at=new RenderPass(d.scene,v.camera);Ne.addPass(at),this.scene=d.scene,this.camera=v.camera,this.finalComposer=Ne,this.renderPass=at,v.event.on("pageChange",ot=>{this.changeCamera(ot)}),d.event.on("pageChange",ot=>{this.changeScene(ot)})}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 Gs;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:d,renderer:v}=this,C=v.getSize(new Vector2),w=C.width,E=C.height,ye=new SSAOPass(r,d,w,E);ye.kernelRadius=t.kernelRadius,ye.minDistance=t.minDistance,ye.maxDistance=t.maxDistance,this.ssaoPass=ye,this.finalComposer.addPass(ye)}addBloomPass(t){const{renderer:r}=this,{threshold:d,strength:v,radius:C,bloomAlphaType:w}=t,E=new UnrealBloomPass(new Vector2(window.innerWidth,window.innerHeight),v,C,d);this.bloomPass=E;const ye=new EffectComposer(r);ye.renderToScreen=!1,ye.addPass(this.renderPass),ye.addPass(E),this.bloomComposer=ye;const Le=Ks(ye);Le.uniforms.bloomAlphaType.value=w,this.bloomComposer=ye,this.finalComposer.addPass(Le),this.mixPass=Le,this.bloomLayer.set(Pe)}setBloomSelection(t,r){if(!this.bloomComposer){console.warn("err:pencil.options.bloom");return}t.traverse(d=>{const{object3d:v}=d;v&&(r?(this.bloomSelection.add(d),v.layers.enable(Pe)):(this.bloomSelection.delete(d),v.layers.disable(Pe)))}),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 d;(d=this.bloomComposer)==null||d.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(d=>{d.isTransformControls||d.isTransformControlsRoot||d.type==="RectAreaLightHelper"?t.push(d):r.push(d)}),r.forEach(d=>{d.traverse(v=>{var C;const w=v,E=v,ye=v;(C=w.material)!=null&&C.isShadowMaterial?t.push(w):w.material&&this.bloomLayer.test(w.layers)===!1&&(this.bloomMaterials[w.uuid]=w.material,E.isSprite?E.material.sizeAttenuation?E.material=Qs:E.material=Js:w.material instanceof Ie$2?w.material=ei:ye.isPoints?ye.material.sizeAttenuation?ye.material=$s:ye.material=qs:w.material=Xs)})}),t.forEach(d=>{this.bloomVisible[d.uuid]=d.visible,d.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.mixPass.enabled=!0,this.darkenNonBloomed(),this.bloomComposer.render(),this.restoreNonBloomed()):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:d}=this.options;if(this.finalComposerRender(),this.pipViewportState){t.setPageActive(31),t.setAspect(this.pipViewportState.width/this.pipViewportState.height),r.setViewport(ee(U({},this.pipViewportState),{scissor:!0,scissorTest:!0})),this.finalComposerRender(),t.setPageActive(d.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 st extends Loader{constructor(t){super(t),this.options={type:"image"}}setOptions(t){return this.options=t,this}load(t,r,d,v){let C,w;this.options.type==="image"?(w=document.createElement("img"),C=new Texture(w)):this.options.type==="video"?(w=document.createElement("video"),w.preload="auto",w.autoplay=!1,w.loop=!1,w.muted=!0,w.setAttribute("webkit-playsinline","webkit-playsinline"),w.setAttribute("playsinline",""),C=new VideoTexture(w)):C=new Texture;const E=new FileLoader(this.manager);return E.setResponseType("blob"),E.setRequestHeader(this.requestHeader),E.setPath(this.path),E.setWithCredentials(this.withCredentials),E.load(t,ye=>{let Le=ye;const Re=t.split(".").pop(),Ne=this.options.type==="image"?`image/${Re||"png"}`:`video/${Re||"mp4"}`;Le=Le.slice(0,ye.size,Ne);const Fe=()=>{w.removeEventListener("load",at,!1),w.removeEventListener("error",ot,!1)},at=()=>{Fe(),C.needsUpdate=!0,r&&r(C)},ot=ht=>{Fe(),v&&v(ht),this.manager.itemError(t),this.manager.itemEnd(t)};w.addEventListener("load",at,!1),w.addEventListener("error",ot,!1);const Gt=window.URL.createObjectURL(Le);w.src=Gt},d,v),C}}class oi extends Loader{constructor(t){super(t)}load(t,r,d,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,w=>{const E=w,ye=new DecompressionStream("gzip"),Le=E.stream().pipeThrough(ye);new Response(Le).json().then(Re=>{r==null||r(Re)}).catch(Re=>{v==null||v(Re)})},d,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 ve.EventEmitter,this.options=U({simpleTexture4deleted:!1,prefix:""},t),this.loadingManager=new LoadingManager(()=>{},(r,d,v)=>{this.emit("progress",d,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 d=this.assets.get(t);if(!d){if((r==="images"||r==="media"||r==="exr")&&this.options.simpleTexture4deleted&&this.delLoadArr.includes(t))return new Texture;console.warn(`Asset ${t} not found`)}return d}getAssetType(t){var r;const d=(r=t.split(".").pop())==null?void 0:r.toLowerCase();if(d){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(d))return v}getLoader(t,r){if(t==="images")return this.textureLoader||(this.textureLoader=new st(this.loadingManager),this.options.prefix&&this.textureLoader.setPath(this.options.prefix)),this.textureLoader;if(t==="media")return this.videoTextureLoader||(this.videoTextureLoader=new st(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(d=>{const v=U({src:d},r);this.loadObj.push(v)})}getSrcByAsset(t,r=this.assets){let d;return r.forEach((v,C)=>{v===t&&(d=C)}),d}get textureAssets(){const t=new Map;return this.assets.forEach((r,d)=>{(r instanceof Texture||r instanceof DataTexture||r instanceof VideoTexture)&&t.set(d,r)}),t}loadAll(){return te(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 te(this,null,function*(){var d,v;const C=(d=r==null?void 0:r.type)!=null?d:this.getAssetType(t);if(!C)return;const w=(r==null?void 0:r.cache)!==!1,E=esusLite.makePromiseCreator();if(w){if(this.assets.has(t))return this.assets.get(t);this.assets.set(t,E.promise)}const ye=this.getLoader(C,r);try{const Le=yield ye.loadAsync(t);if(this.assets.set(t,Le),E.resolve(Le),C==="images"||C==="media"||C==="exr"||C==="lottie"){(r==null?void 0:r.colorCorrection)!==!1&&l$1({texture:Le});const Re=(v=r==null?void 0:r.anisotropy)!=null?v:this.options.anisotropy;Le.anisotropy=Re}return Le}catch(Le){E.reject(`Failed to load ${t}`);return}})}getUnusedAssets(){const{scene:t}=this.options;if(!t)return[...this.delLoadArr];const r=new Set,d=this.textureAssets;t.traverse(C=>{const w=C;w.material&&(Array.isArray(w.material)?w.material:[w.material]).forEach(E=>{[E.map,E.emissiveMap,E.normalMap,E.roughnessMap,E.metalnessMap,E.aoMap].forEach(ye=>{if(ye){const Le=this.getSrcByAsset(ye,d);Le&&r.add(Le)}})})});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 hi={prefix:""};class li extends ae{get loader(){return this.controller}constructor(t){super(),this.options=t}addLoader(t,r){const{loaderParams:d}=this.options,v=new ai(ee(U({},d),{scene:t}));return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}class ci extends ie$1{constructor(t){super(),this.options=U({},t)}create(){var t;this.object3d=(t=this.options.scene)!=null?t:new Scene}}function it(g){let t=!1,r=[];return function(...d){r=d,t||(t=!0,requestAnimationFrame(()=>{t=!1,g(...r)}))}}class di{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.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"]),d=new Set(["down","downOutside","click"]),v=C=>{var w;if(!this.enabled)return;C.preventDefault();const E=t==="move"?r:d,ye=[];if(this.pickFunctionsMap.forEach(ot=>{E.has(ot.type)&&ye.push(ee(U({},ot),{objArr:ot.objArr instanceof Function?ot.objArr():ot.objArr}))}),ye.length===0)return;this.activeObjects.clear(),this.objCallbackMap.clear();const Le=this.objCallbackMap,Re=[];for(const ot of ye)for(const Gt of ot.objArr){if(!Gt.object3d||!Gt.visibleWithAncestors)continue;Le.has(Gt)||(Le.set(Gt,new Map),Re.push(Gt));const ht=Le.get(Gt);ht.has(ot.type)||ht.set(ot.type,[]),ht.get(ot.type).push(ot.cb)}if(Re.length===0)return;const Ne=Re.map(ot=>ot.object3d);Ne.forEach(ot=>{ot.isGroup&&ot.traverse(Gt=>{Gt instanceof Mesh&&Ne.push(Gt)})});const Fe=(w=this.pencil.pick(C,Ne,!1))==null?void 0:w.intersects;if(!Fe||Fe.length===0)t==="down"?this.handleDownOutside(C):t==="move"&&this.handleLeaveEvents(C);else{this.sortIntersections(Fe);const ot=Fe[0];this.processIntersection(ot,C,t)}const at=this.prevActiveObjects;this.prevActiveObjects=this.activeObjects,this.activeObjects=at,this.activeObjects.clear()};this.domElement.addEventListener(`pointer${t}`,it(v),{passive:!1})}sortIntersections(t){t.sort((r,d)=>r.distance===d.distance?r.object.getObjectById(d.object.id)?1:d.object.getObjectById(r.object.id)?-1:0:r.distance-d.distance)}processIntersection(t,r,d){const v=this.objCallbackMap,C=t.index||-1;let w=t.object;for(;w;){const E=this.pencil.lead.objMap.get(w);E&&v.has(E)&&this.activeObjects.add(E),w=w.parent}d==="move"?this.handleLeaveEvents(r):d==="down"&&this.handleDownOutside(r),this.processObjectHierarchy(r,d,C)}processObjectHierarchy(t,r,d){const v=this.objCallbackMap;let C=!1;const w=()=>{C=!0};for(const E of this.activeObjects){if(C)break;const ye=v.get(E);if(ye)if(r==="move"){const Le=ye.get("enter");if(Le&&!this.prevActiveObjects.has(E))for(const Ne of Le)Ne({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d});const Re=ye.get("move");if(Re)for(const Ne of Re)Ne({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d})}else{const Le=ye.get("down");if(Le)for(const Ne of Le)Ne({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d});const Re=ye.get("click");if(Re){const Ne=Fe=>{Fe.preventDefault();const at=5;if(!C&&Math.abs(Fe.clientX-t.clientX)<=at&&Math.abs(Fe.clientY-t.clientY)<=at)for(const ot of Re)ot({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d});this.domElement.removeEventListener("pointerup",Ne)};this.domElement.addEventListener("pointerup",Ne)}}}}handleLeaveEvents(t){this.objCallbackMap.forEach((r,d)=>{const v=r.get("leave");if(v&&this.prevActiveObjects.has(d)&&!this.activeObjects.has(d))for(const C of v)C({baseObject:d,mouseEvent:t})})}handleDownOutside(t){this.objCallbackMap.forEach((r,d)=>{const v=r.get("downOutside");if(v&&!this.activeObjects.has(d))for(const C of v)C({baseObject:d,mouseEvent:t})})}handlePick(t,r,d){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:d}),this.pickListener.move||Array.from(this.pickFunctionsMap.values()).some(w=>["move","enter","leave"].includes(w.type))&&(this.pickListener.move=!0,this.addPickListener("move")),this.pickListener.down||Array.from(this.pickFunctionsMap.values()).some(w=>["down","downOutside","click"].includes(w.type))&&(this.pickListener.down=!0,this.addPickListener("down")),C}removePick(t){this.pickFunctionsMap.delete(t)}handlePickNode(t,r,d){if(r==="downOutside")return console.warn("handlePickNode:err:不支持 downOutside"),-1;this.pickNodeFunctionsMapIndex+=1;const v=this.pickNodeFunctionsMapIndex,C=t instanceof Function?t():t,w=[];for(const E of C){const ye=E;ye.element.style.pointerEvents="auto";const Le=Ne=>{this.enabled&&(Ne.preventDefault(),d({baseObject:ye,mouseEvent:Ne}))},Re=`pointer${r}`;ye.element.addEventListener(Re,it(Le),!1),w.push({arr:ye,type:Re,listener:Le})}return this.pickNodeFunctionsMap.set(v,w),v}removePickNode(t){const r=this.pickNodeFunctionsMap.get(t);if(r){for(const d of r)d.arr.element.style.pointerEvents="none",d.arr.element.removeEventListener(d.type,d.listener,!1);this.pickNodeFunctionsMap.delete(t)}}dispose(){this.pickFunctionsMap.clear(),this.pickNodeFunctionsMap.clear(),this.activeObjects.clear(),this.prevActiveObjects.clear(),this.objCallbackMap.clear()}}class pi extends di{constructor(t,r){super(t),this.objMap=new Map,this.objects=new Map,this.objectsPm=new Map,this.objectNamesToFactories=new Map,this.scene=new ci({scene:r.scene}),this.scene.create(),this.scene.lead=this,this.scene.pencil=t,this.scene.key="Scene",this.scene.object3d.name="场景",this.group=new ze$1,this.group.create(),this.group.lead=this,this.group.pencil=t,this.group.key="@Group",this.group.object3d.name="物体组",this.prefabGroup=new ze$1,this.prefabGroup.create(),this.prefabGroup.lead=this,this.prefabGroup.pencil=t,this.prefabGroup.key="@PrefabGroup",this.prefabGroup.object3d.name="预制组",this.scene.add(this.group.object3d,this.prefabGroup.object3d),this.objects.set("@Scene",this.scene),this.objects.set("@Group",this.group),this.objects.set("@PrefabGroup",this.prefabGroup),this.objMap.set(this.scene.object3d,this.scene),this.objMap.set(this.group.object3d,this.group),this.objMap.set(this.prefabGroup.object3d,this.prefabGroup)}get objectsPromise(){return this.objectsPm.values()}init(t){return Object.keys(t).forEach(r=>{const d=class{create(v={}){return new t[r](v)}};this.objectNamesToFactories.set(r,d)}),this}getObject(t,r){t.includes("#")&&console.warn("getObject:err:不支持 #",t);const{key:d}=r||{},v=`${t}${d?`#${d}`:""}`;return this.objects.get(v)}getAllObject(t,r){t.includes("#")&&console.warn("getAllObject:err:不支持 #",t);const{key:d}=r||{},v=`${t}${d?`#${d}`:""}`,C=[];return this.objects.forEach((w,E)=>{(E.startsWith(d?v:`${v}#`)||E===v)&&C.push(w)}),C}draw(t,r,d){return te(this,null,function*(){var v,C,w,E;const ye=this.objectNamesToFactories.get(t);if(ye){r||(r={}),r.target===void 0&&(r.target=d);const Le=r.target,Re=(v=r.onTop)!=null?v:0,Ne=(C=r.prefab)!=null?C:!1,Fe=(w=r.create)!=null?w:!0,at=new ye().create(r);let ot;return Le===null?ot=null:typeof Le=="string"?ot=this.objects.get(Le):(E=Le==null?void 0:Le.objectType)!=null&&E.startsWith("BaseObject")||Le?ot=Le:Ne?ot=this.prefabGroup:ot=this.group,Fe===!1?at.create=()=>{}:Fe!==!0&&(at.create=()=>{Fe(at)}),at.pencil=this.pencil,at.lead=this,at.prefab=Ne,at.objectType=`BaseObject#${t}`,at.objectOptions=r,this.setBaseObjectKey(at,r.key?`$t:#${r.key}`:"$t:",ot==null?void 0:ot.key),this.objectsPm.set(at.key,this.addBaseObject(at,ot,Re)),yield this.objectsPm.get(at.key),this.objectsPm.delete(at.key),at}throw new Error(`Unrecognized:${t}`)})}setBaseObjectKey(t,r,d){const v=t.objectType,[,C]=v.split("#");let w=r.replace("$t:",C);if(d){const[,E]=d.split("#");w=w.replace("$p:",E)}return this.objects.has(w)&&(w.includes("#")?w+=`-${esusLite.generateUUID()}`:w+=`#${esusLite.generateUUID()}`),t.key=w,this.objects.set(w,t),w}updateBaseObjectKey(t,r){var d;let v;for(const[E,ye]of this.objects.entries())if(ye===t){v=E;break}const C=(d=t.parent)==null?void 0:d.key;if(!v)return this.setBaseObjectKey(t,r,C);this.objects.delete(v);const w=this.setBaseObjectKey(t,r,C);return this.pencil.event.emit("updateKey",t,w,v),w}addBaseObject(t,r,d){return te(this,null,function*(){yield t.create(),t.object3d&&(d&&t.setTop(d),r!==null&&(r.add(t.object3d),this.objMap.set(t.object3d,t))),t.render(),this.pencil.event.emit("draw",t)})}erase(...t){this.handleErase(!0,...t),this.pencil.event.emit("erase",...t)}eraseWithoutMaterial(...t){this.handleErase(!1,...t)}handleErase(t,...r){[...r].forEach(d=>{const v=[];if(typeof d=="string"){const[C,w]=d.split("#");v.push(...this.getAllObject(C,{key:w}))}else v.push(d);v.forEach(C=>{t?C.dispose():C.disposeWithOutMaterial()})})}update(t,r){this.objects.forEach(d=>{d.update(t,r)})}setSize(t,r){this.objects.forEach(d=>{d.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.objectNamesToFactories.clear()}}class mi extends ae{get lead(){return this.controller}constructor(t){super(),this.options=t}addLead(t,r){const{pencil:d}=this.options,v=new pi(d,{scene:t});return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}setPageActive(t){super.setPageActive(t,(r,d)=>{r.enabled=d})}setSize(t,r){this.controllerMap.forEach((d,v)=>{v.setSize(t,r)})}}const _e=class In{constructor(t){var r,d;this.raycaster=new Raycaster,this.maxBackufferArea=5760*5760,this.installPlugins=new Map,this._cameraPositon=new Vector3,this._cameraTarget=new Vector3,this.event=new ve.EventEmitter,this.timer=new Timer,this.userData={},this.pageActiveIndex=0,this.pageCountIndex=0,this.userSetDprCache=1,this.event.setMaxListeners(1/0),(d=(r=this.timer).connect)==null||d.call(r,document),this.options=is(In.options,t,{isMergeableObject:f}),this.userSetDprCache=this.options.renderer.devicePixelRatio;const{container:v,stats:C,transformControls:w}=this.options;if(this.init(),this.options.WebGPUTHREE||this.initComposer(),this.initCSSRenderer(),w&&this.initTransformControls(),C){const E=new Stats({horizontal:!1});E.dom.style.position="absolute",E.init(this.renderer),v.appendChild(E.dom),this.stats=E}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}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 d=this.pageCountIndex+1,v=this.cameraController.addPerspectiveCamera(r,d),C=this.sceneController.addScene(t,d);return C.add(v),this.controlsController.addCameraControls(v,d),this.loaderController.addLoader(C,d),this.leadController.addLead(C,d),this.pageCountIndex=d,d}removePage(t){this.cameraController.removePage(t),this.sceneController.removePage(t),this.controlsController.removePage(t),this.loaderController.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 d=this.scene;this.sceneController.setPageActive(t),d&&((r=this.cssRendererController)==null||r.render(d,this.camera)),this.cameraController.setPageActive(t),this.controlsController.setPageActive(t),this.loaderController.setPageActive(t),this.leadController.setPageActive(t),this.pageActiveIndex=t}init(){var t;const{container:r,WebGPUTHREE:d,helper:v,viewHelper:C,renderer:w,controls:E,loader:ye}=this.options,{width:Le,height:Re}=this.getSize(),Ne=d?new Rs({width:Le,height:Re,renderer:d.WebGPURenderer,rendererParams:Ds}):new Ms({width:Le,height:Re,rendererParams:ee(U({},w),{antialias:!1})}),Fe=new zs({width:Le,height:Re}),at=new Fs({}),ot=new Hs({controlsParams:{domElement:(t=E==null?void 0:E.domElement)!=null?t:Ne.renderer.domElement}}),Gt=new li({loaderParams:U({anisotropy:Ne.renderer.capabilities.getMaxAnisotropy()},ye)}),ht=new mi({pencil:this});this.sceneController=at,this.cameraController=Fe,this.controlsController=ot,this.rendererController=Ne,this.loaderController=Gt,this.leadController=ht;const ke=this.addPage({sceneOptions:this.options.scene,cameraOptions:this.options.camera});if(this.showPage(ke),v){const ct=new Ns({container:r,sceneController:at,cameraController:Fe});ct.add(at.scene),this.helperController=ct,C&&ct.addViewHelper()}r.appendChild(Ne.renderer.domElement)}initComposer(){const{bloom:t,bloomParams:r,ssao:d,ssaoParams:v,composer:C}=this.options,w=new ri({rendererController:this.rendererController,sceneController:this.sceneController,cameraController:this.cameraController,composerParams:C});this.composerController=w,t&&w.addBloomPass(U({},r)),d&&w.addSSAOPass(U({},v)),w.addOutputPass()}initCSSRenderer(){const{container:t,css2DRenderer:r,css3DRenderer:d,css2DRendererParams:v,css3DRendererParams:C}=this.options;if(r||d){const w=new Zs(t);r&&w.addRenderer("css2d",v),d&&w.addRenderer("css3d",C),this.cssRendererController=w}}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(d=>{for(const v of d){const C=v.contentRect;this.handeleResize(C.width,C.height),this.setDevicePixelRatio(this.userSetDprCache)}});r.observe(t),this.resizeObserver=r}handeleResize(t,r,d=!0){const{rendererController:v,cameraController:C,composerController:w,cssRendererController:E,leadController:ye}=this,Le=this.renderer.getSize(new Vector2);Le.x===t&&Le.y===r||(C.setSize(t,r),v.setSize(t,r),w==null||w.setSize(t,r),E==null||E.setSize(t,r),ye.setSize(t,r),this.installPlugins.forEach(Re=>{var Ne;(Ne=Re.setSize)==null||Ne.call(Re,t,r)}),this.render(),d&&this.event.emit("resize",{width:t,height:r}))}setDevicePixelRatio(t){var r;this.userSetDprCache=t;const{width:d,height:v}=this.getSize();let C=Math.sqrt(this.maxBackufferArea/(d*v));C=(C*100|0)/100;const w=Math.min(t,C);w!==t&&console.warn("maxBackufferArea:",this.maxBackufferArea," the pixel ratio is set to",w);const E=this.renderer.getPixelRatio();w!==E&&(this.rendererController.setPixelRatio(w),(r=this.composerController)==null||r.setPixelRatio(w))}pick(t,r,d=!0){const{raycaster:v,options:C}=this,{container:w}=C,E=new Vector2,ye=w.getBoundingClientRect();if(E.x=(t.clientX-ye.left)/(ye.right-ye.left)*2-1,E.y=-((t.clientY-ye.top)/(ye.bottom-ye.top))*2+1,this.camera&&this.scene){v.setFromCamera(E,this.camera);const Le=v.intersectObjects(r||this.scene.children,d);if(Le.length)return{object:Le[0].object,index:Le[0].index,intersects:Le}}}render(){var t,r,d,v,C,w;if(!this.camera||!this.scene)return;this.timer.update(),update();const E=this.timer.getDelta(),ye=this.timer.getElapsed();this.controlsController.update(E,ye),this.leadController.update(E,ye),this.installPlugins.forEach(Le=>{var Re;(Re=Le.update)==null||Re.call(Le,E,ye)}),(t=this.helperController)==null||t.update(E,this.controlsController,this.cameraTarget),(r=this.composerController)!=null&&r.active?this.composerController.render():(d=this.rendererController)==null||d.render(this.scene,this.camera),(v=this.helperController)==null||v.renderViewHelper(this.renderer),(C=this.cssRendererController)==null||C.render(this.scene,this.camera),(w=this.stats)==null||w.update(),this.event.emit("render",{delta:E,elapsed:ye})}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:d,height:v}=this.getSize(),C=new DOMRect(t.x/d,(v-t.y-t.height)/v,t.width/d,t.height/v);if(r)r.enabled=!0,r.camera.position.copy(this.camera.position);else{const w=this.cameraController.cloneCamera(31);w.aspect=t.width/t.height,w.updateProjectionMatrix(),r=this.controlsController.addCameraControls(w,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,d,v,C,w,E,ye,Le,Re,Ne,Fe,at;this.stop(),this.timer.dispose(),removeAll(),this.event.removeAllListeners(),(t=this.resizeObserver)==null||t.unobserve(this.options.container),this.installPlugins.forEach(ot=>{var Gt;(Gt=ot.dispose)==null||Gt.call(ot)}),(r=this.controlsController)==null||r.dispose(),(d=this.transformController)==null||d.dispose(),(v=this.cssRendererController)==null||v.dispose(),(C=this.sceneController)==null||C.dispose(),(w=this.cameraController)==null||w.dispose(),(E=this.helperController)==null||E.dispose(),(ye=this.composerController)==null||ye.dispose(),(Le=this.rendererController)==null||Le.dispose(),(Re=this.loaderController)==null||Re.dispose(),(Ne=this.leadController)==null||Ne.dispose(),this.cssRendererController=void 0,this.installPlugins.clear(),(Fe=this.stats)==null||Fe.dom.remove(),(at=this.renderer)==null||at.domElement.remove()}};_e.options={stats:me,helper:me,viewHelper:me,controls:!0,transformControls:me,renderer:As,composer:ii,scene:ks,camera:Tt,bloom:!1,bloomParams:si,ssao:!1,loader:hi,ssaoParams:ti,css2DRenderer:!1,css2DRendererParams:U({},tt),css3DRenderer:!1,css3DRendererParams:U({},tt)};let rt=_e;const Ki=J.ACTION,b$1=new Map,R$2=(g={})=>({generateTopUV(t,r,d,v,C){const w=r[d*3],E=r[d*3+1],ye=r[v*3],Le=r[v*3+1],Re=r[C*3],Ne=r[C*3+1];let Fe;if(b$1.has(t))Fe=b$1.get(t);else{let ht=g.box3;if(!ht){ht=new Box3;const ct=t.parameters.shapes.getPoints().map(xt=>[xt.x,xt.y,0]).flat();ht.setFromArray(ct)}const ke=ht.getSize(new Vector3);g.split&&(ke.y/=g.split),Fe={box:ht,size:ke},b$1.set(t,Fe)}const{box:at,size:ot}=Fe,Gt=g.split?1-g.split:0;return[new Vector2((w-at.min.x)/ot.x,(E-at.min.y)/ot.y+Gt),new Vector2((ye-at.min.x)/ot.x,(Le-at.min.y)/ot.y+Gt),new Vector2((Re-at.min.x)/ot.x,(Ne-at.min.y)/ot.y+Gt)]},generateSideWallUV(t,r,d,v,C,w){const E=r[d*3],ye=r[d*3+1],Le=r[d*3+2],Re=r[v*3],Ne=r[v*3+1],Fe=r[v*3+2],at=r[C*3],ot=r[C*3+1],Gt=r[C*3+2],ht=r[w*3],ke=r[w*3+1],ct=r[w*3+2];let xt;if(b$1.has(r))xt=b$1.get(r);else{const Pt=new Box3;Pt.setFromArray(r);const Nt=Pt.getSize(new Vector3);g.split&&(Nt.z/=1-g.split),g.sideRepeat&&(Nt.z/=g.sideRepeat),xt={box:Pt,size:Nt},b$1.set(r,xt)}const{box:Rt,size:Wt}=xt;return Math.abs(ye-Ne)<Math.abs(E-Re)?[new Vector2((E-Rt.min.x)/Wt.x,(Le-Rt.min.z)/Wt.z),new Vector2((Re-Rt.min.x)/Wt.x,(Fe-Rt.min.z)/Wt.z),new Vector2((at-Rt.min.x)/Wt.x,(Gt-Rt.min.z)/Wt.z),new Vector2((ht-Rt.min.x)/Wt.x,(ct-Rt.min.z)/Wt.z)]:[new Vector2((ye-Rt.min.y)/Wt.y,(Le-Rt.min.z)/Wt.z),new Vector2((Ne-Rt.min.y)/Wt.y,(Fe-Rt.min.z)/Wt.z),new Vector2((ot-Rt.min.y)/Wt.y,(Gt-Rt.min.z)/Wt.z),new Vector2((ke-Rt.min.y)/Wt.y,(ct-Rt.min.z)/Wt.z)]}}),P=()=>{b$1.clear()};var Jt=Object.defineProperty,Xt=Object.defineProperties,Qt=Object.getOwnPropertyDescriptors,lt=Object.getOwnPropertySymbols,Bt=Object.prototype.hasOwnProperty,Vt=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={}))Bt.call(t,r)&&It(g,r,t[r]);if(lt)for(var r of lt(t))Vt.call(t,r)&&It(g,r,t[r]);return g},ut=(g,t)=>Xt(g,Qt(t)),gt=(g,t)=>{var r={};for(var d in g)Bt.call(g,d)&&t.indexOf(d)<0&&(r[d]=g[d]);if(g!=null&&lt)for(var d of lt(g))t.indexOf(d)<0&&Vt.call(g,d)&&(r[d]=g[d]);return r},nt=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())});class Xe extends ie$1{constructor(t){super(),this.objectType="BaseObject#Node",this.onNodePointerIndex=[],this.options=G({type:"2d"},t)}create(){const{position:t,children:r}=this.options,d=document.createElement("div");this.element=d,r&&d.appendChild(r),this.options.type==="3d"?this.createCSS3DObject(d):this.options.type==="3dSprite"?this.createCSS3DSprite(d):this.createCSS2DObject(d),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(),d=window.innerWidth,v=window.innerHeight;let C=0,w=0;r.left<0?C=-r.left:r.right>d&&(C=d-r.right),r.top<0?w=-r.top:r.bottom>v&&(w=v-r.bottom),r.left+C<0&&(C=-r.left),r.top+w<0&&(w=-r.top),(C!==0||w!==0)&&(t.style.transform=`translate(${C}px, ${w}px)`)}ensureVisible(){const t=this.options.children;if(!t)return;t.style.transform&&(t.style.transform="");const r=new IntersectionObserver(d=>{d.forEach(v=>{v.isIntersecting&&(this.moveElementToViewport(),r.disconnect())})});r.observe(t)}onPointerEvent(t,r){const d=this.lead.handlePickNode([this],t,r);this.onNodePointerIndex.push(d)}dispose(){this.onNodePointerIndex.forEach(t=>{this.lead.removePickNode(t)}),super.dispose()}}const Ue={ArcCurve,CatmullRomCurve3,CubicBezierCurve,CubicBezierCurve3,EllipseCurve,LineCurve,LineCurve3,QuadraticBezierCurve,QuadraticBezierCurve3,SplineCurve};let Y$1=class zn 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 d=this,v=[],C=[];for(let E=0,ye=t.length;E<ye;E++){const Le=t[E];w(Le)}this.setAttribute("position",new Float32BufferAttribute(v,3)),this.setAttribute("uv",new Float32BufferAttribute(C,2)),this.computeVertexNormals();function w(E){var ye,Le,Re;const Ne=[],Fe=r.curveSegments!==void 0?r.curveSegments:12,at=r.steps!==void 0?r.steps:1,ot=r.depth!==void 0?r.depth:1;let Gt=r.bevelEnabled!==void 0?r.bevelEnabled:!0,ht=r.bevelThickness!==void 0?r.bevelThickness:.2,ke=r.bevelSize!==void 0?r.bevelSize:ht-.1,ct=r.bevelOffset!==void 0?r.bevelOffset:0,xt=r.bevelSegments!==void 0?r.bevelSegments:3;const Rt=r.extrudePath,Wt=r.UVGenerator!==void 0?r.UVGenerator:Ce,Pt=(ye=r.hasTop)!=null?ye:!0,Nt=(Le=r.hasBottom)!=null?Le:!0,Kt=(Re=r.hasSide)!=null?Re:!0;let Ft,kt=!1,Yt,s0,o0,h0;Rt&&(Ft=Rt.getSpacedPoints(at),kt=!0,Gt=!1,Yt=Rt.computeFrenetFrames(at,!1),s0=new Vector3,o0=new Vector3,h0=new Vector3),Gt||(xt=0,ht=0,ke=0,ct=0);const r0=E.extractPoints(Fe);let e0=r0.shape;const i0=r0.holes;if(!ShapeUtils.isClockWise(e0)){e0=e0.reverse();for(let F0=0,w0=i0.length;F0<w0;F0++){const c0=i0[F0];ShapeUtils.isClockWise(c0)&&(i0[F0]=c0.reverse())}}function Ut(F0){const w0=10000000000000001e-36;let c0=F0[0];for(let a0=1;a0<=F0.length;a0++){const M0=a0%F0.length,R0=F0[M0],N0=R0.x-c0.x,P0=R0.y-c0.y,Mi=N0*N0+P0*P0,yi=Math.max(Math.abs(R0.x),Math.abs(R0.y),Math.abs(c0.x),Math.abs(c0.y)),Xi=w0*yi*yi;if(Mi<=Xi){F0.splice(M0,1),a0--;continue}c0=R0}}Ut(e0),i0.forEach(Ut);const l0=i0.length,S0=e0;for(let F0=0;F0<l0;F0++){const w0=i0[F0];e0=e0.concat(w0)}function g0(F0,w0,c0){return w0||console.error("THREE.ExtrudeGeometry: vec does not exist"),F0.clone().addScaledVector(w0,c0)}const I0=e0.length;function fi(F0,w0,c0){let a0,M0,R0;const N0=F0.x-w0.x,P0=F0.y-w0.y,Mi=c0.x-F0.x,yi=c0.y-F0.y,Xi=N0*N0+P0*P0,Ii=N0*yi-P0*Mi;if(Math.abs(Ii)>Number.EPSILON){const $0=Math.sqrt(Xi),_i=Math.sqrt(Mi*Mi+yi*yi),Vi=w0.x-P0/$0,zi=w0.y+N0/$0,wi=c0.x-yi/_i,Bi=c0.y+Mi/_i,Ni=((wi-Vi)*yi-(Bi-zi)*Mi)/(N0*yi-P0*Mi);a0=Vi+N0*Ni-F0.x,M0=zi+P0*Ni-F0.y;const Hi=a0*a0+M0*M0;if(Hi<=2)return new Vector2(a0,M0);R0=Math.sqrt(Hi/2)}else{let $0=!1;N0>Number.EPSILON?Mi>Number.EPSILON&&($0=!0):N0<-Number.EPSILON?Mi<-Number.EPSILON&&($0=!0):Math.sign(P0)===Math.sign(yi)&&($0=!0),$0?(a0=-P0,M0=N0,R0=Math.sqrt(Xi)):(a0=N0,M0=P0,R0=Math.sqrt(Xi/2))}return new Vector2(a0/R0,M0/R0)}const L0=[];for(let F0=0,w0=S0.length,c0=w0-1,a0=F0+1;F0<w0;F0++,c0++,a0++)c0===w0&&(c0=0),a0===w0&&(a0=0),L0[F0]=fi(S0[F0],S0[c0],S0[a0]);const K0=[];let A0,J0=L0.concat();for(let F0=0,w0=l0;F0<w0;F0++){const c0=i0[F0];A0=[];for(let a0=0,M0=c0.length,R0=M0-1,N0=a0+1;a0<M0;a0++,R0++,N0++)R0===M0&&(R0=0),N0===M0&&(N0=0),A0[a0]=fi(c0[a0],c0[R0],c0[N0]);K0.push(A0),J0=J0.concat(A0)}let Gi;if(xt===0)Gi=ShapeUtils.triangulateShape(S0,i0);else{const F0=[],w0=[];for(let c0=0;c0<xt;c0++){const a0=c0/xt,M0=ht*Math.cos(a0*Math.PI/2),R0=ke*Math.sin(a0*Math.PI/2)+ct;for(let N0=0,P0=S0.length;N0<P0;N0++){const Mi=g0(S0[N0],L0[N0],R0);u0(Mi.x,Mi.y,-M0),a0===0&&F0.push(Mi)}for(let N0=0,P0=l0;N0<P0;N0++){const Mi=i0[N0];A0=K0[N0];const yi=[];for(let Xi=0,Ii=Mi.length;Xi<Ii;Xi++){const $0=g0(Mi[Xi],A0[Xi],R0);u0($0.x,$0.y,-M0),a0===0&&yi.push($0)}a0===0&&w0.push(yi)}}Gi=ShapeUtils.triangulateShape(F0,w0)}const Ci=Gi.length,Li=ke+ct;for(let F0=0;F0<I0;F0++){const w0=Gt?g0(e0[F0],J0[F0],Li):e0[F0];kt?(o0.copy(Yt.normals[0]).multiplyScalar(w0.x),s0.copy(Yt.binormals[0]).multiplyScalar(w0.y),h0.copy(Ft[0]).add(o0).add(s0),u0(h0.x,h0.y,h0.z)):u0(w0.x,w0.y,0)}for(let F0=1;F0<=at;F0++)for(let w0=0;w0<I0;w0++){const c0=Gt?g0(e0[w0],J0[w0],Li):e0[w0];kt?(o0.copy(Yt.normals[F0]).multiplyScalar(c0.x),s0.copy(Yt.binormals[F0]).multiplyScalar(c0.y),h0.copy(Ft[F0]).add(o0).add(s0),u0(h0.x,h0.y,h0.z)):u0(c0.x,c0.y,ot/at*F0)}for(let F0=xt-1;F0>=0;F0--){const w0=F0/xt,c0=ht*Math.cos(w0*Math.PI/2),a0=ke*Math.sin(w0*Math.PI/2)+ct;for(let M0=0,R0=S0.length;M0<R0;M0++){const N0=g0(S0[M0],L0[M0],a0);u0(N0.x,N0.y,ot+c0)}for(let M0=0,R0=i0.length;M0<R0;M0++){const N0=i0[M0];A0=K0[M0];for(let P0=0,Mi=N0.length;P0<Mi;P0++){const yi=g0(N0[P0],A0[P0],a0);kt?u0(yi.x,yi.y+Ft[at-1].y,Ft[at-1].x+c0):u0(yi.x,yi.y,ot+c0)}}}Ai(),Kt&&Fi();function Ai(){const F0=v.length/3;if(Gt){let w0=0,c0=I0*w0;if(Nt)for(let a0=0;a0<Ci;a0++){const M0=Gi[a0];vi(M0[2]+c0,M0[1]+c0,M0[0]+c0)}if(w0=at+xt*2,c0=I0*w0,Pt)for(let a0=0;a0<Ci;a0++){const M0=Gi[a0];vi(M0[0]+c0,M0[1]+c0,M0[2]+c0)}}else{if(Nt)for(let w0=0;w0<Ci;w0++){const c0=Gi[w0];vi(c0[2],c0[1],c0[0])}if(Pt)for(let w0=0;w0<Ci;w0++){const c0=Gi[w0];vi(c0[0]+I0*at,c0[1]+I0*at,c0[2]+I0*at)}}d.addGroup(F0,v.length/3-F0,0)}function Fi(){const F0=v.length/3;let w0=0;O0(S0,w0),w0+=S0.length;for(let c0=0,a0=i0.length;c0<a0;c0++){const M0=i0[c0];O0(M0,w0),w0+=M0.length}d.addGroup(F0,v.length/3-F0,1)}function O0(F0,w0){let c0=F0.length;for(;--c0>=0;){const a0=c0;let M0=c0-1;M0<0&&(M0=F0.length-1);for(let R0=0,N0=at+xt*2;R0<N0;R0++){const P0=I0*R0,Mi=I0*(R0+1),yi=w0+a0+P0,Xi=w0+M0+P0,Ii=w0+M0+Mi,$0=w0+a0+Mi;j0(yi,Xi,Ii,$0)}}}function u0(F0,w0,c0){Ne.push(F0),Ne.push(w0),Ne.push(c0)}function vi(F0,w0,c0){Q0(F0),Q0(w0),Q0(c0);const a0=v.length/3,M0=Wt.generateTopUV(d,v,a0-3,a0-2,a0-1);U0(M0[0]),U0(M0[1]),U0(M0[2])}function j0(F0,w0,c0,a0){Q0(F0),Q0(w0),Q0(a0),Q0(w0),Q0(c0),Q0(a0);const M0=v.length/3,R0=Wt.generateSideWallUV(d,v,M0-6,M0-3,M0-2,M0-1);U0(R0[0]),U0(R0[1]),U0(R0[3]),U0(R0[1]),U0(R0[2]),U0(R0[3])}function Q0(F0){v.push(Ne[F0*3+0]),v.push(Ne[F0*3+1]),v.push(Ne[F0*3+2])}function U0(F0){C.push(F0.x),C.push(F0.y)}}}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}toJSON(){const t=super.toJSON(),r=this.parameters.shapes,d=this.parameters.options;return Ie(r,d,t)}static fromJSON(t,r){const d=[];for(let C=0,w=t.shapes.length;C<w;C++){const E=r[t.shapes[C]];d.push(E)}const v=t.options.extrudePath;return v!==void 0&&(t.options.extrudePath=new Ue[`${v.type}`]().fromJSON(v)),new zn(d,t.options)}};const Ce={generateTopUV:function(g,t,r,d,v){const C=t[r*3],w=t[r*3+1],E=t[d*3],ye=t[d*3+1],Le=t[v*3],Re=t[v*3+1];return[new Vector2(C,w),new Vector2(E,ye),new Vector2(Le,Re)]},generateSideWallUV:function(g,t,r,d,v,C){const w=t[r*3],E=t[r*3+1],ye=t[r*3+2],Le=t[d*3],Re=t[d*3+1],Ne=t[d*3+2],Fe=t[v*3],at=t[v*3+1],ot=t[v*3+2],Gt=t[C*3],ht=t[C*3+1],ke=t[C*3+2];return Math.abs(E-Re)<Math.abs(w-Le)?[new Vector2(w,1-ye),new Vector2(Le,1-Ne),new Vector2(Fe,1-ot),new Vector2(Gt,1-ke)]:[new Vector2(E,1-ye),new Vector2(Re,1-Ne),new Vector2(at,1-ot),new Vector2(ht,1-ke)]}};function Ie(g,t,r){if(r.shapes=[],Array.isArray(g))for(let d=0,v=g.length;d<v;d++){const C=g[d];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 Ye extends ie$1{constructor(t){super(),this.rectAreaLightUniformsLibInit=!1,this.options=t}create(){var t,r,d,v,C,w,E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht,ke;const ct=this.options;if(ct.type==="AmbientLight"){const xt=new AmbientLight(ct.color);xt.name="环境光",this.object3d=xt}else if(ct.type==="DirectionalLight"){const xt=new DirectionalLight(ct.color,ct.intensity);xt.name="平行光",xt.target.position.set(0,0,0),this.object3d=xt,xt.target.name="平行光目标",xt.shadow.camera.name="平行光阴影相机",xt.shadow.camera.userData.directionalLightShadow=!0,this.directionalLight=xt}else if(ct.type==="PointLight"){const xt=new PointLight((t=ct.color)!=null?t:16777215,(r=ct.intensity)!=null?r:1,(d=ct.distance)!=null?d:0,(v=ct.decay)!=null?v:2);xt.name="点光源",this.object3d=xt,this.pointLight=xt}else if(ct.type==="SpotLight"){const xt=new SpotLight((C=ct.color)!=null?C:16777215,(w=ct.intensity)!=null?w:1,(E=ct.distance)!=null?E:0,(ye=ct.angle)!=null?ye:Math.PI/3,(Le=ct.penumbra)!=null?Le:1,(Re=ct.decay)!=null?Re:2);xt.name="聚光灯",this.object3d=xt,this.spotLight=xt,xt.target.name="聚光灯目标"}else if(ct.type==="HemisphereLight"){const xt=new HemisphereLight((Ne=ct.color)!=null?Ne:16777215,(Fe=ct.groundColor)!=null?Fe:16777215,(at=ct.intensity)!=null?at:1);xt.name="半球光",this.object3d=xt,this.hemisphereLight=xt}else if(ct.type==="RectAreaLight"){this.rectAreaLightUniformsLibInit||(RectAreaLightUniformsLib.init(),this.rectAreaLightUniformsLibInit=!0);const xt=new RectAreaLight((ot=ct.color)!=null?ot:16777215,(Gt=ct.intensity)!=null?Gt:1,(ht=ct.width)!=null?ht:10,(ke=ct.height)!=null?ke:10);xt.name="矩形区域光",this.object3d=xt,this.rectAreaLight=xt}}render(){const t=this.object3d;t.target&&this.pencil.scene.add(t.target);const r=this.pencil.cameraTarget;if(this.spotLight||this.directionalLight){const d=this.spotLight||this.directionalLight;d.position.copy(r),d.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,d=new Set(Object.keys(g[0].attributes)),v=new Set(Object.keys(g[0].morphAttributes)),C={},w={},E=g[0].morphTargetsRelative,ye=new BufferGeometry;let Le=0;for(let Re=0;Re<g.length;++Re){const Ne=g[Re];let Fe=0;if(r!==(Ne.index!==null))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const at in Ne.attributes){if(!d.has(at))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+'. All geometries must have compatible attributes; make sure "'+at+'" attribute exists among all geometries, or in none of them.'),null;C[at]===void 0&&(C[at]=[]),C[at].push(Ne.attributes[at]),Fe++}if(Fe!==d.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". Make sure all geometries have the same number of attributes."),null;if(E!==Ne.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const at in Ne.morphAttributes){if(!v.has(at))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". .morphAttributes must be consistent throughout all geometries."),null;w[at]===void 0&&(w[at]=[]),w[at].push(Ne.morphAttributes[at])}if(t){let at;if(r)at=Ne.index.count;else if(Ne.attributes.position!==void 0)at=Ne.attributes.position.count;else return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". The geometry must have either an index or a position attribute"),null;if(t===1)ye.addGroup(Le,at,Re);else if(t===2&&Ne.groups.length>0)for(let ot of Ne.groups){let Gt=ot.materialIndex;ye.addGroup(Le+ot.start,Math.min(ot.count,at),Gt)}Le+=at}}if(r){let Re=0;const Ne=[];for(let Fe=0;Fe<g.length;++Fe){const at=g[Fe].index;for(let ot=0;ot<at.count;++ot)Ne.push(at.getX(ot)+Re);Re+=g[Fe].attributes.position.count}ye.setIndex(Ne)}for(const Re in C){const Ne=mergeAttributes(C[Re]);if(!Ne)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+Re+" attribute."),null;ye.setAttribute(Re,Ne)}for(const Re in w){const Ne=w[Re][0].length;if(Ne===0)break;ye.morphAttributes=ye.morphAttributes||{},ye.morphAttributes[Re]=[];for(let Fe=0;Fe<Ne;++Fe){const at=[];for(let Gt=0;Gt<w[Re].length;++Gt)at.push(w[Re][Gt][Fe]);const ot=mergeAttributes(at);if(!ot)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+Re+" morphAttribute."),null;ye.morphAttributes[Re].push(ot)}}return t===2?mergeGroups(ye):ye}const Dt=g=>{const{points:t}=g,r=t.reduce((d,v,C)=>(C<t.length-1&&d.push(v,t[C+1]),d),[]);return new BufferGeometry().setFromPoints(r)};let Ze=class extends ie$1{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:d,material:v,useGroups:C,setPointWidth:w,lineWidthArr:E,materialParameters:ye,instanceCount:Le}=this.options;let Re=v,Ne=r;!Re&&ye&&(Re=this.getMaterial(ye)),!Ne&&g?Ne=Dt({points:g}):!Ne&&t?Ne=R$1(t.map(at=>Dt({points:at})),C!=null?C:0):!Ne&&d&&d.length>1?Ne=R$1(d,C!=null?C:0):!Ne&&d&&d.length===1&&([Ne]=d);const Fe=new LineSegmentsGeometry().fromLineSegments(new LineSegments(Ne));if(this.pencil.options.WebGPUTHREE){Le&&(Fe.instanceCount=Le);const at=new De(Fe,Re);at.computeLineDistances(),this.object3d=at}else{const at=new LineSegments2(Fe,Re);at.computeLineDistances(),this.object3d=at}})}getMaterial(g){return new LineMaterial(G({color:new Color$1("#ffffff")},g))}};function yt(g,t,r,d,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,d);else for(C=0;C<g.length;C++)r[C+d]=g[C];return r}function Be(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 Ve 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=Be(t),this._points=t,this.widthCallback=r!=null?r:null,this.positions=[],this.counters=[],t.length&&t[0]instanceof Vector3)for(let d=0;d<t.length;d++){const v=t[d],C=d/(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 d=0;d<t.length;d+=3){const v=d/(t.length-1);this.positions.push(t[d],t[d+1],t[d+2]),this.positions.push(t[d],t[d+1],t[d+2]),this.counters.push(v),this.counters.push(v)}this.process()}compareV3(t,r){const d=t*6,v=r*6;return this.positions[d]===this.positions[v]&&this.positions[d+1]===this.positions[v+1]&&this.positions[d+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,d;this.compareV3(0,t-1)?d=this.copyV3(t-2):d=this.copyV3(0),this.previous.push(d[0],d[1],d[2]),this.previous.push(d[0],d[1],d[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){d=this.copyV3(v),this.previous.push(d[0],d[1],d[2]),this.previous.push(d[0],d[1],d[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&&(d=this.copyV3(v),this.next.push(d[0],d[1],d[2]),this.next.push(d[0],d[1],d[2]))}this.compareV3(t-1,0)?d=this.copyV3(1):d=this.copyV3(t-1),this.next.push(d[0],d[1],d[2]),this.next.push(d[0],d[1],d[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:d}){const v=this._attributes.position.array,C=this._attributes.previous.array,w=this._attributes.next.array,E=v.length;yt(v,0,C,0,E),yt(v,6,v,0,E-6),v[E-6]=t,v[E-5]=r,v[E-4]=d,v[E-3]=t,v[E-2]=r,v[E-1]=d,yt(v,6,w,0,E-6),w[E-6]=t,w[E-5]=r,w[E-4]=d,w[E-3]=t,w[E-2]=r,w[E-1]=d,this._attributes.position.needsUpdate=!0,this._attributes.previous.needsUpdate=!0,this._attributes.next.needsUpdate=!0}}const bt=g=>{const{setPointWidth:t,nodes:r}=g,d=new Ve;return d.setPoints(r,t),d};class ts extends ie$1{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:d,geometryArr:v,material:C,useGroups:w,setPointWidth:E,lineWidthArr:ye,materialParameters:Le}=this.options;let Re=C,Ne=d;!Re&&Le&&(Re=this.getMaterial(Le)),!Ne&&t?Ne=bt({nodes:t,setPointWidth:E}):!Ne&&r?Ne=R$1(r.map((Fe,at)=>{let ot=E;return!ot&&ye&&(ot=()=>{var Gt;return(Gt=ye[at])!=null?Gt:ye[0]}),bt({nodes:Fe,setPointWidth:ot})}),w!=null?w:0):!Ne&&v&&v.length>1?Ne=R$1(v,w!=null?w:0):!Ne&&v&&v.length===1&&([Ne]=v),this.createMesh(Ne,Re)})}setGeometry(t,r){const d=bt({nodes:t,setPointWidth:r}),v=this.object3d,C=v.geometry;v.geometry=d,C.dispose()}getMaterial(t){const{width:r,height:d}=this.pencil.getSize();return new Ie$2(G({color:new Color$1("#ffffff"),resolution:new Vector2(r,d)},t))}addGeometries(t){const r=this.object3d,d=R$1([r.geometry,...t]);r.geometry=d}resize(t,r){var d,v;(v=(d=this.material)==null?void 0:d.uniforms)==null||v.resolution.value.set(t,r)}useMaterial(t){super.useMaterial(t);const{width:r,height:d}=this.pencil.getSize();this.resize(r,d)}animate({duration:t=1e3,delay:r=0,repeat:d=0,lineLoop:v,onRepeat:C,onUpdate:w,onComplete:E,startShow:ye}={}){const{offset:Le,offsetLoop:Re}=this.material.uniforms;if(this.material.userData.tween)return;const Ne=v!=null?v:!0;Le.value.x=1,Re.value=Ne&&ye?1:0;let Fe=0;const at=new Tween(Le.value).to({x:-1},t).delay(r).repeat(d).onUpdate(({x:ot})=>{Ne&&ot<=0&&Re.value===0&&(Re.value=1),w&&w(ot)}).onRepeat(()=>{Fe+=1,C&&C(Fe)}).onComplete(()=>{E&&E()}).start();this.material.userData.tween=at}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:d,height:v}=t,C=gt(t,["coordinate","startHeight","height"]);let w=d||0;return typeof d!="undefined"&&typeof v!="undefined"&&(w=d+v),new Te$1([r],ut(G({},C),{startHeight:d,endHeight:w}))};class es extends ie$1{constructor(t){super(),this.options=G({},t)}create(){const t=this.options,{geometry:r,coordinateArr:d,coordinate:v,material:C,useGroups:w}=t,E=gt(t,["geometry","coordinateArr","coordinate","material","useGroups"]);let ye=r;if(!ye&&v)ye=Ot(G({coordinate:v},E));else if(!ye&&d){const Le=d.map(Re=>Ot(G({coordinate:Re},E)));ye=R$1(Le,w!=null?w:0)}this.createMesh(ye,C)}}class ze extends Y$1{constructor(t,r){super(t,r);const d=new Brush(new Y$1(t,ut(G({},r),{hasTop:!0,hasSide:!0,hasBottom:!1})));d.updateMatrixWorld();const v=new Box3().setFromObject(d),C=new Vector3;v.getSize(C);const w=new Vector3(v.min.x+C.x/2,v.min.y+C.y/2,0);let E=r.topSegments,ye=r.box3;if(ye){ye=ye.union(v);const ht=new Vector3;ye.getSize(ht);const ke=Math.max(C.x/ht.x,C.y/ht.y);E=Math.ceil(r.topSegments*ke)}if(E<4)return this;const Le=new PlaneGeometry(C.x,C.y,E,E),Re=new Brush(Le);Re.position.set(w.x,w.y,w.z),Re.updateMatrixWorld();const Ne=new Evaluator().evaluate(Re,d,INTERSECTION),Fe=Ne.geometry.getAttribute("position"),at=new Float32BufferAttribute(Fe.count*2,2);for(let ht=0;ht<Fe.count;ht++){const ke=Fe.getZ(ht);Fe.setZ(ht,r.depth+ke)}if(ye){const ht=ye.min,ke=ye.max,ct=new Vector3().subVectors(ke,ht);for(let xt=0;xt<Fe.count;xt++){const Rt=Fe.getX(xt),Wt=Fe.getY(xt),Pt=(Rt-ht.x)/ct.x,Nt=(Wt-ht.y)/ct.y;at.setXY(xt,Pt,Nt)}Ne.geometry.setAttribute("uv",at)}Fe.needsUpdate=!0;const ot=new Y$1(t,ut(G({},r),{hasTop:!1})),Gt=R$1([Ne.geometry,ot],2);this.copy(Gt.toNonIndexed())}}const Ht=g=>{const{split:t,depth:r,points:d,box3:v,hasTop:C,hasBottom:w,hasSide:E,sideRepeat:ye,topSegments:Le}=g,Re=Le?ze:Y$1,Ne=new Re(new Shape(d),{depth:r,bevelEnabled:!1,box3:v,UVGenerator:R$2({split:t,box3:v,sideRepeat:ye}),hasTop:C,hasBottom:w,hasSide:E,topSegments:Le});return P(),Ne};class ss extends ie$1{constructor(t){super(),this.options=G({depth:1},t)}create(){return nt(this,null,function*(){const{points:t,pointsArr:r,useGroups:d,depth:v,geometry:C,geometryArr:w,material:E,box3:ye,split:Le,hasTop:Re,hasBottom:Ne,hasSide:Fe}=this.options,at=Array.isArray(v)?v:[v],ot=Array.isArray(ye)?ye:[ye],Gt=E;let ht=C;Gt||console.log("material is null"),!ht&&t?ht=Ht({points:t,depth:at[0],box3:ot[0],split:Le,hasTop:Re,hasBottom:Ne,hasSide:Fe}):!ht&&r?ht=R$1(r.map((ke,ct)=>{var xt,Rt;return Ht({points:ke,depth:(xt=at[ct])!=null?xt:at[0],box3:(Rt=ot[ct])!=null?Rt:ot[0],split:Le,hasTop:Re,hasBottom:Ne,hasSide:Fe})}),d!=null?d:0):!ht&&w&&w.length>1?ht=R$1(w,d!=null?d:0):!ht&&w&&w.length===1&&([ht]=w),this.createMesh(ht,Gt)})}addGeometries(t){const r=this.object3d,d=R$1([r.geometry,...t]);r.geometry=d}setTextureAnisotropic(t,r){t.anisotropy=r||this.pencil.renderer.capabilities.getMaxAnisotropy()}}class Light extends Ye{update(t,r){var v;super.update(t,r);const d=this.object3d;(v=d.shadow)!=null&&v.camera&&(d.shadow.camera.near!==this.pencil.camera.near&&(d.shadow.camera.near=this.pencil.camera.near),d.shadow.camera.far!=this.pencil.camera.far&&(d.shadow.camera.far=this.pencil.camera.far))}render(){super.render();const t=this.object3d;t.userData=new Proxy({},{set:(E,ye,Le)=>(ye==="keepCamera"&&(Le?(this.pencil.render(),t.userData.parent=t.parent,this.pencil.camera.attach(t),t.target&&this.pencil.camera.attach(t.target)):!Le&&t.userData.parent&&(this.pencil.render(),t.userData.parent.attach(t),t.target&&t.userData.parent.attach(t.target))),Reflect.set(E,ye,Le))});const{type:r,key:d}=this.options;d?(this.lead.updateBaseObjectKey(this,`${r}_${d}`),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 w=this.object3d;w.isPointLight&&(w.shadow.mapSize.width=1024,w.shadow.mapSize.height=1024)}}class Point extends ie$1{constructor(r){super();_0(this,"options");_0(this,"scaleValue",1);this.options=bi({sprite:!0},r)}get material(){var r;return(r=this.object3d)==null?void 0:r.material}getMaterial(){const{sprite:r}=this.options,d=document.createElement("canvas");d.width=100,d.height=100;const v=d.getContext("2d");v.beginPath(),v.arc(50,50,50,0,2*Math.PI),v.fillStyle="#ffffff",v.fill(),v.closePath();const C=new CanvasTexture(d);return r?new SpriteMaterial({transparent:!0,map:C}):new MeshBasicMaterial({color:16777215,transparent:!0,map:C})}create(){return D0(this,null,function*(){const{sprite:r}=this.options,d=this.getMaterial();r?this.createSprite(d):this.createMesh(new PlaneGeometry(1,1),d),this.setScale(1),this.object3d.scale.multiplyScalar(.1)})}setScale(r){this.scaleValue=r;const d=this.material.map;d!=null&&d.image?this.object3d.scale.set(d.image.width*r,d.image.height*r,1):this.object3d.scale.set(r,r,1)}}const l={mercator:s$1,equirectangular:i$2,fahey:p},a$1={},m=g=>{var t,r,d;const v=JSON.stringify(g);if(a$1[v])return a$1[v];const C=l[(t=g.projectionType)!=null?t:"mercator"]().center(g.center).scale(g.scale).translate((r=g.translate)!=null?r:[0,0]).precision((d=g.precision)!=null?d:.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 d=document.createElement("canvas");d.width=256,d.height=1;const v=d.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 w=new CanvasTexture(d);return w.wrapS=RepeatWrapping,w.wrapT=RepeatWrapping,w.needsUpdate=!0,w},createFlyPath=(g,t,r=40)=>{const d=g.angleTo(t);let v=g.clone().add(t);v=v.normalize().multiplyScalar(r);let C;d<=1?C=r/5*d:d>1&&d<2?C=r/5*mn(d,2):C=r/5*mn(d,1.5);const w=g.clone().add(v).normalize().multiplyScalar(r+C),E=t.clone().add(v).normalize().multiplyScalar(r+C);return new CubicBezierCurve3(g,w,E,t)},createFlyPath2=(g,t,r=40)=>{const d=new Vector3().lerpVectors(g,t,.25),v=new Vector3().lerpVectors(g,t,.75);return d.z+=r,v.z+=r,new CubicBezierCurve3(g,d,v,t)},pixel2unit=(g,t)=>{const d=g.camera.fov*Math.PI/180,v=g.controls.getPosition(new Vector3,!1),C=2*Math.tan(d/2)*v.z,w=g.getSize(),E=w.width/w.width,ye=C*E;return t*g.renderer.getPixelRatio()/w.width/(1/ye)};let map;class Arc extends ie$1{constructor(r){super();_0(this,"options");_0(this,"line");_0(this,"helperMesh");_0(this,"helperMeshPosition");_0(this,"pickTube",null);this.options=bi({color:"#ffffff",lineWidth:6,globe:!1,offsetLoop:!0},r),this.options.repeat&&this.options.repeat[0]===.5&&(this.options.offsetLoop=!1)}static getInitOptions(r,d){const v=pixel2unit(r,200),C=d.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)),w=d.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:w.toArray()}}create(){return D0(this,null,function*(){map||(map=getLineTexture(.5));const{color:r,lineWidth:d,globe:v}=this.options;let{radius:C}=this.options;const w=h(this.options.from||[0,0,0]),E=h(this.options.to||[0,0,0]);C=C!=null?C:w.distanceTo(E);const ye=v?createFlyPath(w,E,C):createFlyPath2(w,E,C),Le=ye.getPoints(1500),Re=this.pencil.lead,Ne=yield Re.draw("Line",{nodes:Le,setPointWidth:ht=>ht*1,materialParameters:{color:r,map,useMap:1,transparent:!0,sizeAttenuation:0,lineWidth:d}},null);this.line=Ne,this.object3d=Ne.object3d;const[Fe,at,ot,Gt]=yield Promise.all([{key:"Arc_起点",position:ye.v0},{key:"Arc_第一控制点",position:ye.v1},{key:"Arc_第二控制点",position:ye.v2},{key:"Arc_终点",position:ye.v3}].map(ct=>D0(this,[ct],function*({key:ht,position:ke}){const xt=yield Re.draw("Group",{},this);return xt.position.copy(ke),xt.userData.disabledCR=!0,xt.userData.disabledTC=!1,Re.updateBaseObjectKey(xt,`${ht}_${this.options.key}`),xt})));this.helperMesh=[Fe,at,ot,Gt],this.helperMeshPosition=[Fe.position.clone(),at.position.clone(),ot.position.clone(),Gt.position.clone()]})}instantiate(){return D0(this,null,function*(){this.update();const r=yield this.line.instantiate(void 0,{recursive:!1}),d=yield yn(Arc.prototype,this,"instantiate").call(this,void 0,{create:v=>{v.line=r,v.object3d=r.object3d}});return d.position.set(0,0,0),d.rotation.set(0,0,0),d.scale.set(1,1,1),d})}setPath(r,d,v,C=w=>w*1){const{globe:w}=this.options;r=h(r),d=h(d);const ye=(w?createFlyPath(r,d,v):createFlyPath2(r,d,v)).getPoints(1500);this.line.options.nodes=ye,this.line.setGeometry(ye,C),this.pickTube&&this.addPickTarget(this.pickTube.options.radius)}addPickTarget(r=1,d=!1){return D0(this,null,function*(){const v=this.pickTube,C=this.pencil.lead,w=this.line.options.nodes,E=new CurvePath;for(let Re=0;Re<w.length-1;Re++)E.add(new LineCurve3(w[Re],w[Re+1]));const ye=yield C.draw("Tube",{path:E,radius:r,multiplyScalar:1},this),Le=ye.object3d;return Le.material=new MeshBasicMaterial({color:16711680,transparent:!0,opacity:d?1:0}),v&&(v.userData._pe_&&ye.onPointerEvent(...v.userData._pe_),v.erase()),this.pickTube=ye,ye})}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:d=0,repeat:v=1/0,onComplete:C,onRepeat:w}={}){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:d,lineLoop:this.options.offsetLoop,onRepeat:w,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,E)=>{this.helperMeshPosition[E].copy(w.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.track(this.line),setTimeout(()=>{!this.pencil.userData.EditorEnv&&this.prefab||this.line.material.userData.tween||this.animateIn()})}}class CrossPlane extends ie$1{constructor(r){super();_0(this,"options");this.options=bi({},r)}create(){return D0(this,null,function*(){const v=new PlaneGeometry(.5,5,2,2);this.createGroup();const C=this.options.material||new MeshBasicMaterial({color:"#ffffff",side:DoubleSide});C.depthWrite=!1;const w=new Mesh(v,C),E=w.clone();w.rotation.x=-Math.PI*.5,E.rotation.x=-Math.PI*.5,E.rotation.y=-Math.PI*.5,w.translateY(5/2),E.translateY(5/2),this.add(w,E),this.userData.material=C,this.userData.disabledTC=!1})}}class PlaneShadow extends ie$1{create(){return D0(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 ie$1{constructor(r){super();_0(this,"options");this.options=bi({},r)}create(){return D0(this,null,function*(){const r=this.pencil.loader,d=this.options.src;if(!d)throw new Error("src is required");let v=r.getAsset(d);v||(v=yield r.load(d)),this.object3d=v.scene,this.scale.multiplyScalar(20)})}}class Box extends ie$1{create(){const t=new BoxGeometry(1,1,1,1,1,1);this.createMesh(t),this.scale.multiplyScalar(20)}}class Capsule extends ie$1{create(){const t=new CapsuleGeometry(1,1,4,8);this.createMesh(t),this.scale.multiplyScalar(20)}}class Circle extends ie$1{create(){const t=new CircleGeometry(1,32,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Cylinder extends ie$1{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 ie$1{create(){const t=new DodecahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Icosahedron extends ie$1{create(){const t=new IcosahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Lathe extends ie$1{create(){const t=new LatheGeometry;this.createMesh(t,new MeshStandardMaterial({side:DoubleSide})),this.scale.multiplyScalar(20)}}class Octahedron extends ie$1{create(){const t=new OctahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Plane extends ie$1{create(){const t=new PlaneGeometry(1,1,2,2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Ring extends ie$1{create(){const t=new RingGeometry(.5,1,32,1,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Sphere extends ie$1{constructor(){super(...arguments);_0(this,"radius",100);_0(this,"material");_0(this,"options")}create(){var d;(d=this.options)!=null&&d.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 ie$1{create(){this.createSprite(new SpriteMaterial),this.scale.multiplyScalar(20)}setDesiredPixelSize(t){var d;const r=this.object3d;if((d=r.material.map)!=null&&d.image){const v=this.pencil.camera,C=new Vector3;v.matrixWorld.decompose(C,new Quaternion,new Vector3);const w=MathUtils.degToRad(v.fov),ye=this.pencil.getSize().height*(1/(2*Math.tan(w/2))),Le=t/ye,{width:Re,height:Ne}=r.material.map.image;r.scale.set(Re/Ne*Le,Le,1)}}}class Tetrahedron extends ie$1{create(){const t=new TetrahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Torus extends ie$1{create(){const t=new TorusGeometry(1,.4,12,48,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class TorusKnot extends ie$1{create(){const t=new TorusKnotGeometry(1,.4,64,8,2,3);this.createMesh(t),this.scale.multiplyScalar(20)}}class Tube extends ie$1{constructor(r){super();_0(this,"options");this.options=r}create(){var w,E;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)]),d=(w=this.options.radius)!=null?w:1,v=(E=this.options.multiplyScalar)!=null?E:20,C=new TubeGeometry(r,64,d,8,!1);this.createMesh(C),this.scale.multiplyScalar(v)}}const baseObjs={Node:Xe,Line:ts,Line2:Ze,ExtrudePolygon:ss,ConicPolygon:es,Group:ze$1,Light,Point,Arc,Model},expObjs={Plane,CrossPlane,PlaneShadow,Ring,Sphere,Sprite,Tetrahedron,Torus,TorusKnot,Tube,Box,Capsule,Circle,Cylinder,Dodecahedron,Icosahedron,Lathe,Octahedron},prefabType=Object.keys(Di(bi({},expObjs),{Arc,Model})).map(g=>g),objs$3=bi(bi({},baseObjs),expObjs);class MaterialList{constructor(){_0(this,"pluginName","materialList");_0(this,"pencil");_0(this,"materials",new Map);_0(this,"baseObjects",new Map);_0(this,"fixBufferGeometry",new BufferGeometry);_0(this,"wrapObject")}install(t){this.pencil=t,this.wrapObject=this.makeBaseObject({key:"MaterialList",name:"材质列表",isGroup:!0,childrenGetter:()=>this.buildMaterialObjectHierarchy()})}buildMaterialObjectHierarchy(){const t=[],r={};return this.baseObjects.forEach((d,v)=>{if(v.includes("#")){const[C]=v.split("#");r[C]||(r[C]=this.makeBaseObject({key:C,name:C,isGroup:!0}),t.push(r[C])),r[C].children.push(d)}else t.push(d)}),t}makeBaseObject({key:t,name:r,isGroup:d=!1,childrenGetter:v,object3d:C}){const w={key:t,userData:{},children:v?[]:[]};return C?(w.object3d=C,r&&(w.object3d.name=r)):w.object3d={isGroup:d,name:r||t,userData:{fixBufferGeometry:!0}},v&&Object.defineProperty(w,"children",{get:v,enumerable:!0}),w}setUserData(t,r){const d=this.baseObjects.get(t);d&&(d.userData=bi(bi({},d.userData),r),this.emitObject3dChange())}add(t,r){this.materials.set(t,r);const d=new Proxy(new Mesh(this.fixBufferGeometry,r),{set:(C,w,E)=>w==="material"?(C.material=E,this.materials.set(t,E),!0):Reflect.set(C,w,E)});d.userData.fixBufferGeometry=!0;const v=this.makeBaseObject({name:r.name,key:t,object3d:d});this.baseObjects.set(t,v),this.emitObject3dChange()}addMultiple(t,r){for(const[d,v]of Object.entries(r)){const C=`${t}#${d}`;v&&this.add(C,v)}}get(t){const r=this.materials.get(t);return r||console.warn(`Material with key "${t}" not found.`),r}getBaseObjectByMaterial(t){for(const[r,d]of this.materials.entries())if(d===t)return this.baseObjects.get(r);return null}getMultiple(t){const r={},d=`${t}#`;let v=!1;for(const[C,w]of this.materials.entries())if(C.startsWith(d)){const E=C.substring(d.length);r[E]=w,v=!0}return v?r:null}copyMultiple(t,r){const d={},v=`${t}#`;for(const[C,w]of this.materials.entries())if(C.startsWith(v)){const E=C.substring(v.length),ye=w.clone();d[E]=ye;const Le=`${r}#${E}`;this.add(Le,ye)}return d}remove(t){this.materials.delete(t),this.baseObjects.delete(t),this.emitObject3dChange()}clear(){this.materials.clear(),this.baseObjects.clear(),this.emitObject3dChange()}getKeys(){return Array.from(this.materials.keys())}emitObject3dChange(){var t;(t=this.pencil)==null||t.event.emit("baseObjectListChange")}dispose(){const t=new O;t.track([...this.materials.values()]),t.dispose(),this.fixBufferGeometry.dispose(),this.materials.clear(),this.baseObjects.clear()}}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 d=promisifyRequest(r);return(v,C)=>d.then(w=>C(w.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(d=>r.put(d[1],d[0])),promisifyRequest(r.transaction)))}var H=Object.defineProperty,u=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable,s=(g,t,r)=>t in g?H(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,W=(g,t)=>{for(var r in t||(t={}))a.call(t,r)&&s(g,r,t[r]);if(u)for(var r of u(t))Y.call(t,r)&&s(g,r,t[r]);return g},x=(g,t)=>{var r={};for(var d in g)a.call(g,d)&&t.indexOf(d)<0&&(r[d]=g[d]);if(g!=null&&u)for(var d of u(g))t.indexOf(d)<0&&Y.call(g,d)&&(r[d]=g[d]);return r},V=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())});const o="dmFyIFNnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSx2Zz1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgemc9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIFhyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIEx1PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksT3U9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgaGM9KEosUSk9PihRPVN5bWJvbFtKXSk/UTpTeW1ib2wuZm9yKCJTeW1ib2wuIitKKSxUZz1KPT57dGhyb3cgVHlwZUVycm9yKEopfSxkaT1NYXRoLnBvdyxSdT0oSixRLG10KT0+USBpbiBKP1NnKEosUSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6bXR9KTpKW1FdPW10LEZ0PShKLFEpPT57Zm9yKHZhciBtdCBpbiBRfHwoUT17fSkpTHUuY2FsbChRLG10KSYmUnUoSixtdCxRW210XSk7aWYoWHIpZm9yKHZhciBtdCBvZiBYcihRKSlPdS5jYWxsKFEsbXQpJiZSdShKLG10LFFbbXRdKTtyZXR1cm4gSn0sR2U9KEosUSk9PnZnKEosemcoUSkpO3ZhciBEdT0oSixRKT0+e3ZhciBtdD17fTtmb3IodmFyIE10IGluIEopTHUuY2FsbChKLE10KSYmUS5pbmRleE9mKE10KTwwJiYobXRbTXRdPUpbTXRdKTtpZihKIT1udWxsJiZYcilmb3IodmFyIE10IG9mIFhyKEopKVEuaW5kZXhPZihNdCk8MCYmT3UuY2FsbChKLE10KSYmKG10W010XT1KW010XSk7cmV0dXJuIG10fTt2YXIgRWc9ZnVuY3Rpb24oSixRKXt0aGlzWzBdPUosdGhpc1sxXT1RfTt2YXIgJHU9Sj0+e3ZhciBRPUpbaGMoImFzeW5jSXRlcmF0b3IiKV0sbXQ9ITEsTXQsYW49e307cmV0dXJuIFE9PW51bGw/KFE9SltoYygiaXRlcmF0b3IiKV0oKSxNdD1BZT0+YW5bQWVdPUNuPT5RW0FlXShDbikpOihRPVEuY2FsbChKKSxNdD1BZT0+YW5bQWVdPUNuPT57aWYobXQpe2lmKG10PSExLEFlPT09InRocm93Iil0aHJvdyBDbjtyZXR1cm4gQ259cmV0dXJuIG10PSEwLHtkb25lOiExLHZhbHVlOm5ldyBFZyhuZXcgUHJvbWlzZSh1Yz0+e3ZhciBKcj1RW0FlXShDbik7SnIgaW5zdGFuY2VvZiBPYmplY3R8fFRnKCJPYmplY3QgZXhwZWN0ZWQiKSx1YyhKcil9KSwxKX19KSxhbltoYygiaXRlcmF0b3IiKV09KCk9PmFuLE10KCJuZXh0IiksInRocm93ImluIFE/TXQoInRocm93Iik6YW4udGhyb3c9QWU9Pnt0aHJvdyBBZX0sInJldHVybiJpbiBRJiZNdCgicmV0dXJuIiksYW59OyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTAtMjAyNSBUaHJlZS5qcyBBdXRob3JzCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKICovY29uc3QgSj0iMTc2IixmYz0iIixvZT0ic3JnYiIsZGM9InNyZ2ItbGluZWFyIixwYz0ibGluZWFyIixZcj0ic3JnYiI7Y2xhc3MgaXN7YWRkRXZlbnRMaXN0ZW5lcih0LGUpe3RoaXMuX2xpc3RlbmVycz09PXZvaWQgMCYmKHRoaXMuX2xpc3RlbmVycz17fSk7Y29uc3Qgbj10aGlzLl9saXN0ZW5lcnM7blt0XT09PXZvaWQgMCYmKG5bdF09W10pLG5bdF0uaW5kZXhPZihlKT09PS0xJiZuW3RdLnB1c2goZSl9aGFzRXZlbnRMaXN0ZW5lcih0LGUpe2NvbnN0IG49dGhpcy5fbGlzdGVuZXJzO3JldHVybiBuPT09dm9pZCAwPyExOm5bdF0hPT12b2lkIDAmJm5bdF0uaW5kZXhPZihlKSE9PS0xfXJlbW92ZUV2ZW50TGlzdGVuZXIodCxlKXtjb25zdCBuPXRoaXMuX2xpc3RlbmVycztpZihuPT09dm9pZCAwKXJldHVybjtjb25zdCBzPW5bdF07aWYocyE9PXZvaWQgMCl7Y29uc3Qgcj1zLmluZGV4T2YoZSk7ciE9PS0xJiZzLnNwbGljZShyLDEpfX1kaXNwYXRjaEV2ZW50KHQpe2NvbnN0IGU9dGhpcy5fbGlzdGVuZXJzO2lmKGU9PT12b2lkIDApcmV0dXJuO2NvbnN0IG49ZVt0LnR5cGVdO2lmKG4hPT12b2lkIDApe3QudGFyZ2V0PXRoaXM7Y29uc3Qgcz1uLnNsaWNlKDApO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLmNhbGwodGhpcyx0KTt0LnRhcmdldD1udWxsfX19Y29uc3QgQXQ9WyIwMCIsIjAxIiwiMDIiLCIwMyIsIjA0IiwiMDUiLCIwNiIsIjA3IiwiMDgiLCIwOSIsIjBhIiwiMGIiLCIwYyIsIjBkIiwiMGUiLCIwZiIsIjEwIiwiMTEiLCIxMiIsIjEzIiwiMTQiLCIxNSIsIjE2IiwiMTciLCIxOCIsIjE5IiwiMWEiLCIxYiIsIjFjIiwiMWQiLCIxZSIsIjFmIiwiMjAiLCIyMSIsIjIyIiwiMjMiLCIyNCIsIjI1IiwiMjYiLCIyNyIsIjI4IiwiMjkiLCIyYSIsIjJiIiwiMmMiLCIyZCIsIjJlIiwiMmYiLCIzMCIsIjMxIiwiMzIiLCIzMyIsIjM0IiwiMzUiLCIzNiIsIjM3IiwiMzgiLCIzOSIsIjNhIiwiM2IiLCIzYyIsIjNkIiwiM2UiLCIzZiIsIjQwIiwiNDEiLCI0MiIsIjQzIiwiNDQiLCI0NSIsIjQ2IiwiNDciLCI0OCIsIjQ5IiwiNGEiLCI0YiIsIjRjIiwiNGQiLCI0ZSIsIjRmIiwiNTAiLCI1MSIsIjUyIiwiNTMiLCI1NCIsIjU1IiwiNTYiLCI1NyIsIjU4IiwiNTkiLCI1YSIsIjViIiwiNWMiLCI1ZCIsIjVlIiwiNWYiLCI2MCIsIjYxIiwiNjIiLCI2MyIsIjY0IiwiNjUiLCI2NiIsIjY3IiwiNjgiLCI2OSIsIjZhIiwiNmIiLCI2YyIsIjZkIiwiNmUiLCI2ZiIsIjcwIiwiNzEiLCI3MiIsIjczIiwiNzQiLCI3NSIsIjc2IiwiNzciLCI3OCIsIjc5IiwiN2EiLCI3YiIsIjdjIiwiN2QiLCI3ZSIsIjdmIiwiODAiLCI4MSIsIjgyIiwiODMiLCI4NCIsIjg1IiwiODYiLCI4NyIsIjg4IiwiODkiLCI4YSIsIjhiIiwiOGMiLCI4ZCIsIjhlIiwiOGYiLCI5MCIsIjkxIiwiOTIiLCI5MyIsIjk0IiwiOTUiLCI5NiIsIjk3IiwiOTgiLCI5OSIsIjlhIiwiOWIiLCI5YyIsIjlkIiwiOWUiLCI5ZiIsImEwIiwiYTEiLCJhMiIsImEzIiwiYTQiLCJhNSIsImE2IiwiYTciLCJhOCIsImE5IiwiYWEiLCJhYiIsImFjIiwiYWQiLCJhZSIsImFmIiwiYjAiLCJiMSIsImIyIiwiYjMiLCJiNCIsImI1IiwiYjYiLCJiNyIsImI4IiwiYjkiLCJiYSIsImJiIiwiYmMiLCJiZCIsImJlIiwiYmYiLCJjMCIsImMxIiwiYzIiLCJjMyIsImM0IiwiYzUiLCJjNiIsImM3IiwiYzgiLCJjOSIsImNhIiwiY2IiLCJjYyIsImNkIiwiY2UiLCJjZiIsImQwIiwiZDEiLCJkMiIsImQzIiwiZDQiLCJkNSIsImQ2IiwiZDciLCJkOCIsImQ5IiwiZGEiLCJkYiIsImRjIiwiZGQiLCJkZSIsImRmIiwiZTAiLCJlMSIsImUyIiwiZTMiLCJlNCIsImU1IiwiZTYiLCJlNyIsImU4IiwiZTkiLCJlYSIsImViIiwiZWMiLCJlZCIsImVlIiwiZWYiLCJmMCIsImYxIiwiZjIiLCJmMyIsImY0IiwiZjUiLCJmNiIsImY3IiwiZjgiLCJmOSIsImZhIiwiZmIiLCJmYyIsImZkIiwiZmUiLCJmZiJdO2Z1bmN0aW9uIEJuKCl7Y29uc3QgaT1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MCx0PU1hdGgucmFuZG9tKCkqNDI5NDk2NzI5NXwwLGU9TWF0aC5yYW5kb20oKSo0Mjk0OTY3Mjk1fDAsbj1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MDtyZXR1cm4oQXRbaSYyNTVdK0F0W2k+PjgmMjU1XStBdFtpPj4xNiYyNTVdK0F0W2k+PjI0JjI1NV0rIi0iK0F0W3QmMjU1XStBdFt0Pj44JjI1NV0rIi0iK0F0W3Q+PjE2JjE1fDY0XStBdFt0Pj4yNCYyNTVdKyItIitBdFtlJjYzfDEyOF0rQXRbZT4+OCYyNTVdKyItIitBdFtlPj4xNiYyNTVdK0F0W2U+PjI0JjI1NV0rQXRbbiYyNTVdK0F0W24+PjgmMjU1XStBdFtuPj4xNiYyNTVdK0F0W24+PjI0JjI1NV0pLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gWihpLHQsZSl7cmV0dXJuIE1hdGgubWF4KHQsTWF0aC5taW4oZSxpKSl9ZnVuY3Rpb24gVXUoaSx0KXtyZXR1cm4oaSV0K3QpJXR9ZnVuY3Rpb24ganIoaSx0LGUpe3JldHVybigxLWUpKmkrZSp0fWZ1bmN0aW9uIHBpKGksdCl7c3dpdGNoKHQuY29uc3RydWN0b3Ipe2Nhc2UgRmxvYXQzMkFycmF5OnJldHVybiBpO2Nhc2UgVWludDMyQXJyYXk6cmV0dXJuIGkvNDI5NDk2NzI5NTtjYXNlIFVpbnQxNkFycmF5OnJldHVybiBpLzY1NTM1O2Nhc2UgVWludDhBcnJheTpyZXR1cm4gaS8yNTU7Y2FzZSBJbnQzMkFycmF5OnJldHVybiBNYXRoLm1heChpLzIxNDc0ODM2NDcsLTEpO2Nhc2UgSW50MTZBcnJheTpyZXR1cm4gTWF0aC5tYXgoaS8zMjc2NywtMSk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgubWF4KGkvMTI3LC0xKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiSW52YWxpZCBjb21wb25lbnQgdHlwZS4iKX19ZnVuY3Rpb24gSXQoaSx0KXtzd2l0Y2godC5jb25zdHJ1Y3Rvcil7Y2FzZSBGbG9hdDMyQXJyYXk6cmV0dXJuIGk7Y2FzZSBVaW50MzJBcnJheTpyZXR1cm4gTWF0aC5yb3VuZChpKjQyOTQ5NjcyOTUpO2Nhc2UgVWludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSo2NTUzNSk7Y2FzZSBVaW50OEFycmF5OnJldHVybiBNYXRoLnJvdW5kKGkqMjU1KTtjYXNlIEludDMyQXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoyMTQ3NDgzNjQ3KTtjYXNlIEludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSozMjc2Nyk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoxMjcpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGNvbXBvbmVudCB0eXBlLiIpfX1jbGFzcyBSe2NvbnN0cnVjdG9yKHQ9MCxlPTApe1IucHJvdG90eXBlLmlzVmVjdG9yMj0hMCx0aGlzLng9dCx0aGlzLnk9ZX1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy54fXNldCB3aWR0aCh0KXt0aGlzLng9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMueX1zZXQgaGVpZ2h0KHQpe3RoaXMueT10fXNldCh0LGUpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Q29tcG9uZW50KHQsZSl7c3dpdGNoKHQpe2Nhc2UgMDp0aGlzLng9ZTticmVhaztjYXNlIDE6dGhpcy55PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnkpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PXNbMF0qZStzWzNdKm4rc1s2XSx0aGlzLnk9c1sxXSplK3NbNF0qbitzWzddLHRoaXN9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueX1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSl9bWFuaGF0dGFuTGVuZ3RoKCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueCkrTWF0aC5hYnModGhpcy55KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9YW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMigtdGhpcy55LC10aGlzLngpK01hdGguUEl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnk7cmV0dXJuIGUqZStuKm59bWFuaGF0dGFuRGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5hYnModGhpcy54LXQueCkrTWF0aC5hYnModGhpcy55LXQueSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXN9cm90YXRlQXJvdW5kKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9dGhpcy54LXQueCxvPXRoaXMueS10Lnk7cmV0dXJuIHRoaXMueD1yKm4tbypzK3QueCx0aGlzLnk9cipzK28qbit0LnksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55fX1jbGFzcyBnZXtjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyxhLGMsbCl7Z2UucHJvdG90eXBlLmlzTWF0cml4Mz0hMCx0aGlzLmVsZW1lbnRzPVsxLDAsMCwwLDEsMCwwLDAsMV0sdCE9PXZvaWQgMCYmdGhpcy5zZXQodCxlLG4scyxyLG8sYSxjLGwpfXNldCh0LGUsbixzLHIsbyxhLGMsbCl7Y29uc3QgaD10aGlzLmVsZW1lbnRzO3JldHVybiBoWzBdPXQsaFsxXT1zLGhbMl09YSxoWzNdPWUsaFs0XT1yLGhbNV09YyxoWzZdPW4saFs3XT1vLGhbOF09bCx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDEsMCwwLDAsMSwwLDAsMCwxKSx0aGlzfWNvcHkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVswXT1uWzBdLGVbMV09blsxXSxlWzJdPW5bMl0sZVszXT1uWzNdLGVbNF09bls0XSxlWzVdPW5bNV0sZVs2XT1uWzZdLGVbN109bls3XSxlWzhdPW5bOF0sdGhpc31leHRyYWN0QmFzaXModCxlLG4pe3JldHVybiB0LnNldEZyb21NYXRyaXgzQ29sdW1uKHRoaXMsMCksZS5zZXRGcm9tTWF0cml4M0NvbHVtbih0aGlzLDEpLG4uc2V0RnJvbU1hdHJpeDNDb2x1bW4odGhpcywyKSx0aGlzfXNldEZyb21NYXRyaXg0KHQpe2NvbnN0IGU9dC5lbGVtZW50cztyZXR1cm4gdGhpcy5zZXQoZVswXSxlWzRdLGVbOF0sZVsxXSxlWzVdLGVbOV0sZVsyXSxlWzZdLGVbMTBdKSx0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXModGhpcyx0KX1wcmVtdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHQsdGhpcyl9bXVsdGlwbHlNYXRyaWNlcyh0LGUpe2NvbnN0IG49dC5lbGVtZW50cyxzPWUuZWxlbWVudHMscj10aGlzLmVsZW1lbnRzLG89blswXSxhPW5bM10sYz1uWzZdLGw9blsxXSxoPW5bNF0sdT1uWzddLGY9blsyXSxkPW5bNV0scD1uWzhdLHk9c1swXSxtPXNbM10sZz1zWzZdLGI9c1sxXSx3PXNbNF0seD1zWzddLE09c1syXSxBPXNbNV0sXz1zWzhdO3JldHVybiByWzBdPW8qeSthKmIrYypNLHJbM109byptK2EqdytjKkEscls2XT1vKmcrYSp4K2MqXyxyWzFdPWwqeStoKmIrdSpNLHJbNF09bCptK2gqdyt1KkEscls3XT1sKmcraCp4K3UqXyxyWzJdPWYqeStkKmIrcCpNLHJbNV09ZiptK2QqdytwKkEscls4XT1mKmcrZCp4K3AqXyx0aGlzfW11bHRpcGx5U2NhbGFyKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cztyZXR1cm4gZVswXSo9dCxlWzNdKj10LGVbNl0qPXQsZVsxXSo9dCxlWzRdKj10LGVbN10qPXQsZVsyXSo9dCxlWzVdKj10LGVbOF0qPXQsdGhpc31kZXRlcm1pbmFudCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XTtyZXR1cm4gZSpvKmgtZSphKmwtbipyKmgrbiphKmMrcypyKmwtcypvKmN9aW52ZXJ0KCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzLGU9dFswXSxuPXRbMV0scz10WzJdLHI9dFszXSxvPXRbNF0sYT10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdLHU9aCpvLWEqbCxmPWEqYy1oKnIsZD1sKnItbypjLHA9ZSp1K24qZitzKmQ7aWYocD09PTApcmV0dXJuIHRoaXMuc2V0KDAsMCwwLDAsMCwwLDAsMCwwKTtjb25zdCB5PTEvcDtyZXR1cm4gdFswXT11KnksdFsxXT0ocypsLWgqbikqeSx0WzJdPShhKm4tcypvKSp5LHRbM109Zip5LHRbNF09KGgqZS1zKmMpKnksdFs1XT0ocypyLWEqZSkqeSx0WzZdPWQqeSx0WzddPShuKmMtbCplKSp5LHRbOF09KG8qZS1uKnIpKnksdGhpc310cmFuc3Bvc2UoKXtsZXQgdDtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIHQ9ZVsxXSxlWzFdPWVbM10sZVszXT10LHQ9ZVsyXSxlWzJdPWVbNl0sZVs2XT10LHQ9ZVs1XSxlWzVdPWVbN10sZVs3XT10LHRoaXN9Z2V0Tm9ybWFsTWF0cml4KHQpe3JldHVybiB0aGlzLnNldEZyb21NYXRyaXg0KHQpLmludmVydCgpLnRyYW5zcG9zZSgpfXRyYW5zcG9zZUludG9BcnJheSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbM10sdFsyXT1lWzZdLHRbM109ZVsxXSx0WzRdPWVbNF0sdFs1XT1lWzddLHRbNl09ZVsyXSx0WzddPWVbNV0sdFs4XT1lWzhdLHRoaXN9c2V0VXZUcmFuc2Zvcm0odCxlLG4scyxyLG8sYSl7Y29uc3QgYz1NYXRoLmNvcyhyKSxsPU1hdGguc2luKHIpO3JldHVybiB0aGlzLnNldChuKmMsbipsLC1uKihjKm8rbCphKStvK3QsLXMqbCxzKmMsLXMqKC1sKm8rYyphKSthK2UsMCwwLDEpLHRoaXN9c2NhbGUodCxlKXtyZXR1cm4gdGhpcy5wcmVtdWx0aXBseShRci5tYWtlU2NhbGUodCxlKSksdGhpc31yb3RhdGUodCl7cmV0dXJuIHRoaXMucHJlbXVsdGlwbHkoUXIubWFrZVJvdGF0aW9uKC10KSksdGhpc310cmFuc2xhdGUodCxlKXtyZXR1cm4gdGhpcy5wcmVtdWx0aXBseShRci5tYWtlVHJhbnNsYXRpb24odCxlKSksdGhpc31tYWtlVHJhbnNsYXRpb24odCxlKXtyZXR1cm4gdC5pc1ZlY3RvcjI/dGhpcy5zZXQoMSwwLHQueCwwLDEsdC55LDAsMCwxKTp0aGlzLnNldCgxLDAsdCwwLDEsZSwwLDAsMSksdGhpc31tYWtlUm90YXRpb24odCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldChlLC1uLDAsbixlLDAsMCwwLDEpLHRoaXN9bWFrZVNjYWxlKHQsZSl7cmV0dXJuIHRoaXMuc2V0KHQsMCwwLDAsZSwwLDAsMCwxKSx0aGlzfWVxdWFscyh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzO2ZvcihsZXQgcz0wO3M8OTtzKyspaWYoZVtzXSE9PW5bc10pcmV0dXJuITE7cmV0dXJuITB9ZnJvbUFycmF5KHQsZT0wKXtmb3IobGV0IG49MDtuPDk7bisrKXRoaXMuZWxlbWVudHNbbl09dFtuK2VdO3JldHVybiB0aGlzfXRvQXJyYXkodD1bXSxlPTApe2NvbnN0IG49dGhpcy5lbGVtZW50cztyZXR1cm4gdFtlXT1uWzBdLHRbZSsxXT1uWzFdLHRbZSsyXT1uWzJdLHRbZSszXT1uWzNdLHRbZSs0XT1uWzRdLHRbZSs1XT1uWzVdLHRbZSs2XT1uWzZdLHRbZSs3XT1uWzddLHRbZSs4XT1uWzhdLHR9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5mcm9tQXJyYXkodGhpcy5lbGVtZW50cyl9fWNvbnN0IFFyPW5ldyBnZTtmdW5jdGlvbiBWdShpKXtmb3IobGV0IHQ9aS5sZW5ndGgtMTt0Pj0wOy0tdClpZihpW3RdPj02NTUzNSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiB5YyhpKXtyZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIixpKX1jb25zdCBtYz1uZXcgZ2UoKS5zZXQoLjQxMjM5MDgsLjM1NzU4NDMsLjE4MDQ4MDgsLjIxMjYzOSwuNzE1MTY4NywuMDcyMTkyMywuMDE5MzMwOCwuMTE5MTk0OCwuOTUwNTMyMiksZ2M9bmV3IGdlKCkuc2V0KDMuMjQwOTY5OSwtMS41MzczODMyLC0uNDk4NjEwOCwtLjk2OTI0MzYsMS44NzU5Njc1LC4wNDE1NTUxLC4wNTU2MzAxLC0uMjAzOTc3LDEuMDU2OTcxNSk7ZnVuY3Rpb24gcXUoKXtjb25zdCBpPXtlbmFibGVkOiEwLHdvcmtpbmdDb2xvclNwYWNlOmRjLHNwYWNlczp7fSxjb252ZXJ0OmZ1bmN0aW9uKHMscixvKXtyZXR1cm4gdGhpcy5lbmFibGVkPT09ITF8fHI9PT1vfHwhcnx8IW98fCh0aGlzLnNwYWNlc1tyXS50cmFuc2Zlcj09PVlyJiYocy5yPV9lKHMucikscy5nPV9lKHMuZykscy5iPV9lKHMuYikpLHRoaXMuc3BhY2VzW3JdLnByaW1hcmllcyE9PXRoaXMuc3BhY2VzW29dLnByaW1hcmllcyYmKHMuYXBwbHlNYXRyaXgzKHRoaXMuc3BhY2VzW3JdLnRvWFlaKSxzLmFwcGx5TWF0cml4Myh0aGlzLnNwYWNlc1tvXS5mcm9tWFlaKSksdGhpcy5zcGFjZXNbb10udHJhbnNmZXI9PT1ZciYmKHMucj1GbihzLnIpLHMuZz1GbihzLmcpLHMuYj1GbihzLmIpKSksc30sZnJvbVdvcmtpbmdDb2xvclNwYWNlOmZ1bmN0aW9uKHMscil7cmV0dXJuIHRoaXMuY29udmVydChzLHRoaXMud29ya2luZ0NvbG9yU3BhY2Uscil9LHRvV29ya2luZ0NvbG9yU3BhY2U6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdGhpcy5jb252ZXJ0KHMscix0aGlzLndvcmtpbmdDb2xvclNwYWNlKX0sZ2V0UHJpbWFyaWVzOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5wcmltYXJpZXN9LGdldFRyYW5zZmVyOmZ1bmN0aW9uKHMpe3JldHVybiBzPT09ZmM/cGM6dGhpcy5zcGFjZXNbc10udHJhbnNmZXJ9LGdldEx1bWluYW5jZUNvZWZmaWNpZW50czpmdW5jdGlvbihzLHI9dGhpcy53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHMuZnJvbUFycmF5KHRoaXMuc3BhY2VzW3JdLmx1bWluYW5jZUNvZWZmaWNpZW50cyl9LGRlZmluZTpmdW5jdGlvbihzKXtPYmplY3QuYXNzaWduKHRoaXMuc3BhY2VzLHMpfSxfZ2V0TWF0cml4OmZ1bmN0aW9uKHMscixvKXtyZXR1cm4gcy5jb3B5KHRoaXMuc3BhY2VzW3JdLnRvWFlaKS5tdWx0aXBseSh0aGlzLnNwYWNlc1tvXS5mcm9tWFlaKX0sX2dldERyYXdpbmdCdWZmZXJDb2xvclNwYWNlOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5vdXRwdXRDb2xvclNwYWNlQ29uZmlnLmRyYXdpbmdCdWZmZXJDb2xvclNwYWNlfSxfZ2V0VW5wYWNrQ29sb3JTcGFjZTpmdW5jdGlvbihzPXRoaXMud29ya2luZ0NvbG9yU3BhY2Upe3JldHVybiB0aGlzLnNwYWNlc1tzXS53b3JraW5nQ29sb3JTcGFjZUNvbmZpZy51bnBhY2tDb2xvclNwYWNlfX0sdD1bLjY0LC4zMywuMywuNiwuMTUsLjA2XSxlPVsuMjEyNiwuNzE1MiwuMDcyMl0sbj1bLjMxMjcsLjMyOV07cmV0dXJuIGkuZGVmaW5lKHtbZGNdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6cGMsdG9YWVo6bWMsZnJvbVhZWjpnYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSx3b3JraW5nQ29sb3JTcGFjZUNvbmZpZzp7dW5wYWNrQ29sb3JTcGFjZTpvZX0sb3V0cHV0Q29sb3JTcGFjZUNvbmZpZzp7ZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6b2V9fSxbb2VdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6WXIsdG9YWVo6bWMsZnJvbVhZWjpnYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSxvdXRwdXRDb2xvclNwYWNlQ29uZmlnOntkcmF3aW5nQnVmZmVyQ29sb3JTcGFjZTpvZX19fSksaX1jb25zdCBhZT1xdSgpO2Z1bmN0aW9uIF9lKGkpe3JldHVybiBpPC4wNDA0NT9pKi4wNzczOTkzODA4Ok1hdGgucG93KGkqLjk0Nzg2NzI5ODYrLjA1MjEzMjcwMTQsMi40KX1mdW5jdGlvbiBGbihpKXtyZXR1cm4gaTwuMDAzMTMwOD9pKjEyLjkyOjEuMDU1Kk1hdGgucG93KGksLjQxNjY2KS0uMDU1fWxldCBJbjtjbGFzcyBIdXtzdGF0aWMgZ2V0RGF0YVVSTCh0LGU9ImltYWdlL3BuZyIpe2lmKC9eZGF0YTovaS50ZXN0KHQuc3JjKXx8dHlwZW9mIEhUTUxDYW52YXNFbGVtZW50PT0idW5kZWZpbmVkIilyZXR1cm4gdC5zcmM7bGV0IG47aWYodCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KW49dDtlbHNle0luPT09dm9pZCAwJiYoSW49eWMoImNhbnZhcyIpKSxJbi53aWR0aD10LndpZHRoLEluLmhlaWdodD10LmhlaWdodDtjb25zdCBzPUluLmdldENvbnRleHQoIjJkIik7dCBpbnN0YW5jZW9mIEltYWdlRGF0YT9zLnB1dEltYWdlRGF0YSh0LDAsMCk6cy5kcmF3SW1hZ2UodCwwLDAsdC53aWR0aCx0LmhlaWdodCksbj1Jbn1yZXR1cm4gbi50b0RhdGFVUkwoZSl9c3RhdGljIHNSR0JUb0xpbmVhcih0KXtpZih0eXBlb2YgSFRNTEltYWdlRWxlbWVudCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50fHx0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnR8fHR5cGVvZiBJbWFnZUJpdG1hcCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcCl7Y29uc3QgZT15YygiY2FudmFzIik7ZS53aWR0aD10LndpZHRoLGUuaGVpZ2h0PXQuaGVpZ2h0O2NvbnN0IG49ZS5nZXRDb250ZXh0KCIyZCIpO24uZHJhd0ltYWdlKHQsMCwwLHQud2lkdGgsdC5oZWlnaHQpO2NvbnN0IHM9bi5nZXRJbWFnZURhdGEoMCwwLHQud2lkdGgsdC5oZWlnaHQpLHI9cy5kYXRhO2ZvcihsZXQgbz0wO288ci5sZW5ndGg7bysrKXJbb109X2UocltvXS8yNTUpKjI1NTtyZXR1cm4gbi5wdXRJbWFnZURhdGEocywwLDApLGV9ZWxzZSBpZih0LmRhdGEpe2NvbnN0IGU9dC5kYXRhLnNsaWNlKDApO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxlIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXk/ZVtuXT1NYXRoLmZsb29yKF9lKGVbbl0vMjU1KSoyNTUpOmVbbl09X2UoZVtuXSk7cmV0dXJue2RhdGE6ZSx3aWR0aDp0LndpZHRoLGhlaWdodDp0LmhlaWdodH19ZWxzZSByZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5JbWFnZVV0aWxzLnNSR0JUb0xpbmVhcigpOiBVbnN1cHBvcnRlZCBpbWFnZSB0eXBlLiBObyBjb2xvciBzcGFjZSBjb252ZXJzaW9uIGFwcGxpZWQuIiksdH19bGV0IFd1PTA7Y2xhc3MgR3V7Y29uc3RydWN0b3IodD1udWxsKXt0aGlzLmlzU291cmNlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOld1Kyt9KSx0aGlzLnV1aWQ9Qm4oKSx0aGlzLmRhdGE9dCx0aGlzLmRhdGFSZWFkeT0hMCx0aGlzLnZlcnNpb249MH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK310b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQuaW1hZ2VzW3RoaXMudXVpZF0hPT12b2lkIDApcmV0dXJuIHQuaW1hZ2VzW3RoaXMudXVpZF07Y29uc3Qgbj17dXVpZDp0aGlzLnV1aWQsdXJsOiIifSxzPXRoaXMuZGF0YTtpZihzIT09bnVsbCl7bGV0IHI7aWYoQXJyYXkuaXNBcnJheShzKSl7cj1bXTtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTtvKyspc1tvXS5pc0RhdGFUZXh0dXJlP3IucHVzaChLcihzW29dLmltYWdlKSk6ci5wdXNoKEtyKHNbb10pKX1lbHNlIHI9S3Iocyk7bi51cmw9cn1yZXR1cm4gZXx8KHQuaW1hZ2VzW3RoaXMudXVpZF09biksbn19ZnVuY3Rpb24gS3IoaSl7cmV0dXJuIHR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50IT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnR8fHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudHx8dHlwZW9mIEltYWdlQml0bWFwIT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEltYWdlQml0bWFwP0h1LmdldERhdGFVUkwoaSk6aS5kYXRhP3tkYXRhOkFycmF5LmZyb20oaS5kYXRhKSx3aWR0aDppLndpZHRoLGhlaWdodDppLmhlaWdodCx0eXBlOmkuZGF0YS5jb25zdHJ1Y3Rvci5uYW1lfTooY29uc29sZS53YXJuKCJUSFJFRS5UZXh0dXJlOiBVbmFibGUgdG8gc2VyaWFsaXplIFRleHR1cmUuIikse30pfWxldCBadT0wO2NsYXNzIGNuIGV4dGVuZHMgaXN7Y29uc3RydWN0b3IodD1jbi5ERUZBVUxUX0lNQUdFLGU9Y24uREVGQVVMVF9NQVBQSU5HLG49MTAwMSxzPTEwMDEscj0xMDA2LG89MTAwOCxhPTEwMjMsYz0xMDA5LGw9Y24uREVGQVVMVF9BTklTT1RST1BZLGg9ZmMpe3N1cGVyKCksdGhpcy5pc1RleHR1cmU9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6WnUrK30pLHRoaXMudXVpZD1CbigpLHRoaXMubmFtZT0iIix0aGlzLnNvdXJjZT1uZXcgR3UodCksdGhpcy5taXBtYXBzPVtdLHRoaXMubWFwcGluZz1lLHRoaXMuY2hhbm5lbD0wLHRoaXMud3JhcFM9bix0aGlzLndyYXBUPXMsdGhpcy5tYWdGaWx0ZXI9cix0aGlzLm1pbkZpbHRlcj1vLHRoaXMuYW5pc290cm9weT1sLHRoaXMuZm9ybWF0PWEsdGhpcy5pbnRlcm5hbEZvcm1hdD1udWxsLHRoaXMudHlwZT1jLHRoaXMub2Zmc2V0PW5ldyBSKDAsMCksdGhpcy5yZXBlYXQ9bmV3IFIoMSwxKSx0aGlzLmNlbnRlcj1uZXcgUigwLDApLHRoaXMucm90YXRpb249MCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9ITAsdGhpcy5tYXRyaXg9bmV3IGdlLHRoaXMuZ2VuZXJhdGVNaXBtYXBzPSEwLHRoaXMucHJlbXVsdGlwbHlBbHBoYT0hMSx0aGlzLmZsaXBZPSEwLHRoaXMudW5wYWNrQWxpZ25tZW50PTQsdGhpcy5jb2xvclNwYWNlPWgsdGhpcy51c2VyRGF0YT17fSx0aGlzLnZlcnNpb249MCx0aGlzLm9uVXBkYXRlPW51bGwsdGhpcy5yZW5kZXJUYXJnZXQ9bnVsbCx0aGlzLmlzUmVuZGVyVGFyZ2V0VGV4dHVyZT0hMSx0aGlzLmlzVGV4dHVyZUFycmF5PSExLHRoaXMucG1yZW1WZXJzaW9uPTB9Z2V0IGltYWdlKCl7cmV0dXJuIHRoaXMuc291cmNlLmRhdGF9c2V0IGltYWdlKHQ9bnVsbCl7dGhpcy5zb3VyY2UuZGF0YT10fXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LnNldFV2VHJhbnNmb3JtKHRoaXMub2Zmc2V0LngsdGhpcy5vZmZzZXQueSx0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnksdGhpcy5yb3RhdGlvbix0aGlzLmNlbnRlci54LHRoaXMuY2VudGVyLnkpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLm5hbWU9dC5uYW1lLHRoaXMuc291cmNlPXQuc291cmNlLHRoaXMubWlwbWFwcz10Lm1pcG1hcHMuc2xpY2UoMCksdGhpcy5tYXBwaW5nPXQubWFwcGluZyx0aGlzLmNoYW5uZWw9dC5jaGFubmVsLHRoaXMud3JhcFM9dC53cmFwUyx0aGlzLndyYXBUPXQud3JhcFQsdGhpcy5tYWdGaWx0ZXI9dC5tYWdGaWx0ZXIsdGhpcy5taW5GaWx0ZXI9dC5taW5GaWx0ZXIsdGhpcy5hbmlzb3Ryb3B5PXQuYW5pc290cm9weSx0aGlzLmZvcm1hdD10LmZvcm1hdCx0aGlzLmludGVybmFsRm9ybWF0PXQuaW50ZXJuYWxGb3JtYXQsdGhpcy50eXBlPXQudHlwZSx0aGlzLm9mZnNldC5jb3B5KHQub2Zmc2V0KSx0aGlzLnJlcGVhdC5jb3B5KHQucmVwZWF0KSx0aGlzLmNlbnRlci5jb3B5KHQuY2VudGVyKSx0aGlzLnJvdGF0aW9uPXQucm90YXRpb24sdGhpcy5tYXRyaXhBdXRvVXBkYXRlPXQubWF0cml4QXV0b1VwZGF0ZSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLmdlbmVyYXRlTWlwbWFwcz10LmdlbmVyYXRlTWlwbWFwcyx0aGlzLnByZW11bHRpcGx5QWxwaGE9dC5wcmVtdWx0aXBseUFscGhhLHRoaXMuZmxpcFk9dC5mbGlwWSx0aGlzLnVucGFja0FsaWdubWVudD10LnVucGFja0FsaWdubWVudCx0aGlzLmNvbG9yU3BhY2U9dC5jb2xvclNwYWNlLHRoaXMucmVuZGVyVGFyZ2V0PXQucmVuZGVyVGFyZ2V0LHRoaXMuaXNSZW5kZXJUYXJnZXRUZXh0dXJlPXQuaXNSZW5kZXJUYXJnZXRUZXh0dXJlLHRoaXMuaXNUZXh0dXJlQXJyYXk9dC5pc1RleHR1cmVBcnJheSx0aGlzLnVzZXJEYXRhPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodC51c2VyRGF0YSkpLHRoaXMubmVlZHNVcGRhdGU9ITAsdGhpc310b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQudGV4dHVyZXNbdGhpcy51dWlkXSE9PXZvaWQgMClyZXR1cm4gdC50ZXh0dXJlc1t0aGlzLnV1aWRdO2NvbnN0IG49e21ldGFkYXRhOnt2ZXJzaW9uOjQuNix0eXBlOiJUZXh0dXJlIixnZW5lcmF0b3I6IlRleHR1cmUudG9KU09OIn0sdXVpZDp0aGlzLnV1aWQsbmFtZTp0aGlzLm5hbWUsaW1hZ2U6dGhpcy5zb3VyY2UudG9KU09OKHQpLnV1aWQsbWFwcGluZzp0aGlzLm1hcHBpbmcsY2hhbm5lbDp0aGlzLmNoYW5uZWwscmVwZWF0Olt0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnldLG9mZnNldDpbdGhpcy5vZmZzZXQueCx0aGlzLm9mZnNldC55XSxjZW50ZXI6W3RoaXMuY2VudGVyLngsdGhpcy5jZW50ZXIueV0scm90YXRpb246dGhpcy5yb3RhdGlvbix3cmFwOlt0aGlzLndyYXBTLHRoaXMud3JhcFRdLGZvcm1hdDp0aGlzLmZvcm1hdCxpbnRlcm5hbEZvcm1hdDp0aGlzLmludGVybmFsRm9ybWF0LHR5cGU6dGhpcy50eXBlLGNvbG9yU3BhY2U6dGhpcy5jb2xvclNwYWNlLG1pbkZpbHRlcjp0aGlzLm1pbkZpbHRlcixtYWdGaWx0ZXI6dGhpcy5tYWdGaWx0ZXIsYW5pc290cm9weTp0aGlzLmFuaXNvdHJvcHksZmxpcFk6dGhpcy5mbGlwWSxnZW5lcmF0ZU1pcG1hcHM6dGhpcy5nZW5lcmF0ZU1pcG1hcHMscHJlbXVsdGlwbHlBbHBoYTp0aGlzLnByZW11bHRpcGx5QWxwaGEsdW5wYWNrQWxpZ25tZW50OnRoaXMudW5wYWNrQWxpZ25tZW50fTtyZXR1cm4gT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihuLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLGV8fCh0LnRleHR1cmVzW3RoaXMudXVpZF09biksbn1kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfXRyYW5zZm9ybVV2KHQpe2lmKHRoaXMubWFwcGluZyE9PTMwMClyZXR1cm4gdDtpZih0LmFwcGx5TWF0cml4Myh0aGlzLm1hdHJpeCksdC54PDB8fHQueD4xKXN3aXRjaCh0aGlzLndyYXBTKXtjYXNlIDFlMzp0Lng9dC54LU1hdGguZmxvb3IodC54KTticmVhaztjYXNlIDEwMDE6dC54PXQueDwwPzA6MTticmVhaztjYXNlIDEwMDI6TWF0aC5hYnMoTWF0aC5mbG9vcih0LngpJTIpPT09MT90Lng9TWF0aC5jZWlsKHQueCktdC54OnQueD10LngtTWF0aC5mbG9vcih0LngpO2JyZWFrfWlmKHQueTwwfHx0Lnk+MSlzd2l0Y2godGhpcy53cmFwVCl7Y2FzZSAxZTM6dC55PXQueS1NYXRoLmZsb29yKHQueSk7YnJlYWs7Y2FzZSAxMDAxOnQueT10Lnk8MD8wOjE7YnJlYWs7Y2FzZSAxMDAyOk1hdGguYWJzKE1hdGguZmxvb3IodC55KSUyKT09PTE/dC55PU1hdGguY2VpbCh0LnkpLXQueTp0Lnk9dC55LU1hdGguZmxvb3IodC55KTticmVha31yZXR1cm4gdGhpcy5mbGlwWSYmKHQueT0xLXQueSksdH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiYodGhpcy52ZXJzaW9uKyssdGhpcy5zb3VyY2UubmVlZHNVcGRhdGU9ITApfXNldCBuZWVkc1BNUkVNVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy5wbXJlbVZlcnNpb24rK319Y24uREVGQVVMVF9JTUFHRT1udWxsLGNuLkRFRkFVTFRfTUFQUElORz0zMDAsY24uREVGQVVMVF9BTklTT1RST1BZPTE7Y2xhc3MgWXR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTAscz0xKXtZdC5wcm90b3R5cGUuaXNWZWN0b3I0PSEwLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXMudz1zfWdldCB3aWR0aCgpe3JldHVybiB0aGlzLnp9c2V0IHdpZHRoKHQpe3RoaXMuej10fWdldCBoZWlnaHQoKXtyZXR1cm4gdGhpcy53fXNldCBoZWlnaHQodCl7dGhpcy53PXR9c2V0KHQsZSxuLHMpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzLnc9cyx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpcy56PXQsdGhpcy53PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Wih0KXtyZXR1cm4gdGhpcy56PXQsdGhpc31zZXRXKHQpe3JldHVybiB0aGlzLnc9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztjYXNlIDM6dGhpcy53PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2Nhc2UgMjpyZXR1cm4gdGhpcy56O2Nhc2UgMzpyZXR1cm4gdGhpcy53O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnksdGhpcy56LHRoaXMudyl9Y29weSh0KXtyZXR1cm4gdGhpcy54PXQueCx0aGlzLnk9dC55LHRoaXMuej10LnosdGhpcy53PXQudyE9PXZvaWQgMD90Lnc6MSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpcy56Kz10LnosdGhpcy53Kz10LncsdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpcy56Kz10LHRoaXMudys9dCx0aGlzfWFkZFZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueCtlLngsdGhpcy55PXQueStlLnksdGhpcy56PXQueitlLnosdGhpcy53PXQudytlLncsdGhpc31hZGRTY2FsZWRWZWN0b3IodCxlKXtyZXR1cm4gdGhpcy54Kz10LngqZSx0aGlzLnkrPXQueSplLHRoaXMueis9dC56KmUsdGhpcy53Kz10LncqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpcy56LT10LnosdGhpcy53LT10LncsdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpcy56LT10LHRoaXMudy09dCx0aGlzfXN1YlZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueC1lLngsdGhpcy55PXQueS1lLnksdGhpcy56PXQuei1lLnosdGhpcy53PXQudy1lLncsdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy54Kj10LngsdGhpcy55Kj10LnksdGhpcy56Kj10LnosdGhpcy53Kj10LncsdGhpc31tdWx0aXBseVNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kj10LHRoaXMueSo9dCx0aGlzLnoqPXQsdGhpcy53Kj10LHRoaXN9YXBwbHlNYXRyaXg0KHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dGhpcy56LHI9dGhpcy53LG89dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PW9bMF0qZStvWzRdKm4rb1s4XSpzK29bMTJdKnIsdGhpcy55PW9bMV0qZStvWzVdKm4rb1s5XSpzK29bMTNdKnIsdGhpcy56PW9bMl0qZStvWzZdKm4rb1sxMF0qcytvWzE0XSpyLHRoaXMudz1vWzNdKmUrb1s3XSpuK29bMTFdKnMrb1sxNV0qcix0aGlzfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpcy53Lz10LncsdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1zZXRBeGlzQW5nbGVGcm9tUXVhdGVybmlvbih0KXt0aGlzLnc9MipNYXRoLmFjb3ModC53KTtjb25zdCBlPU1hdGguc3FydCgxLXQudyp0LncpO3JldHVybiBlPDFlLTQ/KHRoaXMueD0xLHRoaXMueT0wLHRoaXMuej0wKToodGhpcy54PXQueC9lLHRoaXMueT10LnkvZSx0aGlzLno9dC56L2UpLHRoaXN9c2V0QXhpc0FuZ2xlRnJvbVJvdGF0aW9uTWF0cml4KHQpe2xldCBlLG4scyxyO2NvbnN0IGM9dC5lbGVtZW50cyxsPWNbMF0saD1jWzRdLHU9Y1s4XSxmPWNbMV0sZD1jWzVdLHA9Y1s5XSx5PWNbMl0sbT1jWzZdLGc9Y1sxMF07aWYoTWF0aC5hYnMoaC1mKTwuMDEmJk1hdGguYWJzKHUteSk8LjAxJiZNYXRoLmFicyhwLW0pPC4wMSl7aWYoTWF0aC5hYnMoaCtmKTwuMSYmTWF0aC5hYnModSt5KTwuMSYmTWF0aC5hYnMocCttKTwuMSYmTWF0aC5hYnMobCtkK2ctMyk8LjEpcmV0dXJuIHRoaXMuc2V0KDEsMCwwLDApLHRoaXM7ZT1NYXRoLlBJO2NvbnN0IHc9KGwrMSkvMix4PShkKzEpLzIsTT0oZysxKS8yLEE9KGgrZikvNCxfPSh1K3kpLzQsUz0ocCttKS80O3JldHVybiB3PngmJnc+TT93PC4wMT8obj0wLHM9LjcwNzEwNjc4MSxyPS43MDcxMDY3ODEpOihuPU1hdGguc3FydCh3KSxzPUEvbixyPV8vbik6eD5NP3g8LjAxPyhuPS43MDcxMDY3ODEscz0wLHI9LjcwNzEwNjc4MSk6KHM9TWF0aC5zcXJ0KHgpLG49QS9zLHI9Uy9zKTpNPC4wMT8obj0uNzA3MTA2NzgxLHM9LjcwNzEwNjc4MSxyPTApOihyPU1hdGguc3FydChNKSxuPV8vcixzPVMvciksdGhpcy5zZXQobixzLHIsZSksdGhpc31sZXQgYj1NYXRoLnNxcnQoKG0tcCkqKG0tcCkrKHUteSkqKHUteSkrKGYtaCkqKGYtaCkpO3JldHVybiBNYXRoLmFicyhiKTwuMDAxJiYoYj0xKSx0aGlzLng9KG0tcCkvYix0aGlzLnk9KHUteSkvYix0aGlzLno9KGYtaCkvYix0aGlzLnc9TWF0aC5hY29zKChsK2QrZy0xKS8yKSx0aGlzfXNldEZyb21NYXRyaXhQb3NpdGlvbih0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1lWzEyXSx0aGlzLnk9ZVsxM10sdGhpcy56PWVbMTRdLHRoaXMudz1lWzE1XSx0aGlzfW1pbih0KXtyZXR1cm4gdGhpcy54PU1hdGgubWluKHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1pbih0aGlzLnksdC55KSx0aGlzLno9TWF0aC5taW4odGhpcy56LHQueiksdGhpcy53PU1hdGgubWluKHRoaXMudyx0LncpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzLnc9TWF0aC5tYXgodGhpcy53LHQudyksdGhpc31jbGFtcCh0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdC54LGUueCksdGhpcy55PVoodGhpcy55LHQueSxlLnkpLHRoaXMuej1aKHRoaXMueix0LnosZS56KSx0aGlzLnc9Wih0aGlzLncsdC53LGUudyksdGhpc31jbGFtcFNjYWxhcih0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdCxlKSx0aGlzLnk9Wih0aGlzLnksdCxlKSx0aGlzLno9Wih0aGlzLnosdCxlKSx0aGlzLnc9Wih0aGlzLncsdCxlKSx0aGlzfWNsYW1wTGVuZ3RoKHQsZSl7Y29uc3Qgbj10aGlzLmxlbmd0aCgpO3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcihufHwxKS5tdWx0aXBseVNjYWxhcihaKG4sdCxlKSl9Zmxvb3IoKXtyZXR1cm4gdGhpcy54PU1hdGguZmxvb3IodGhpcy54KSx0aGlzLnk9TWF0aC5mbG9vcih0aGlzLnkpLHRoaXMuej1NYXRoLmZsb29yKHRoaXMueiksdGhpcy53PU1hdGguZmxvb3IodGhpcy53KSx0aGlzfWNlaWwoKXtyZXR1cm4gdGhpcy54PU1hdGguY2VpbCh0aGlzLngpLHRoaXMueT1NYXRoLmNlaWwodGhpcy55KSx0aGlzLno9TWF0aC5jZWlsKHRoaXMueiksdGhpcy53PU1hdGguY2VpbCh0aGlzLncpLHRoaXN9cm91bmQoKXtyZXR1cm4gdGhpcy54PU1hdGgucm91bmQodGhpcy54KSx0aGlzLnk9TWF0aC5yb3VuZCh0aGlzLnkpLHRoaXMuej1NYXRoLnJvdW5kKHRoaXMueiksdGhpcy53PU1hdGgucm91bmQodGhpcy53KSx0aGlzfXJvdW5kVG9aZXJvKCl7cmV0dXJuIHRoaXMueD1NYXRoLnRydW5jKHRoaXMueCksdGhpcy55PU1hdGgudHJ1bmModGhpcy55KSx0aGlzLno9TWF0aC50cnVuYyh0aGlzLnopLHRoaXMudz1NYXRoLnRydW5jKHRoaXMudyksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpcy53PS10aGlzLncsdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56K3RoaXMudyp0Lnd9bGVuZ3RoU3EoKXtyZXR1cm4gdGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnordGhpcy53KnRoaXMud31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56K3RoaXMudyp0aGlzLncpfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KStNYXRoLmFicyh0aGlzLncpfW5vcm1hbGl6ZSgpe3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcih0aGlzLmxlbmd0aCgpfHwxKX1zZXRMZW5ndGgodCl7cmV0dXJuIHRoaXMubm9ybWFsaXplKCkubXVsdGlwbHlTY2FsYXIodCl9bGVycCh0LGUpe3JldHVybiB0aGlzLngrPSh0LngtdGhpcy54KSplLHRoaXMueSs9KHQueS10aGlzLnkpKmUsdGhpcy56Kz0odC56LXRoaXMueikqZSx0aGlzLncrPSh0LnctdGhpcy53KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpcy56PXQueisoZS56LXQueikqbix0aGlzLnc9dC53KyhlLnctdC53KSpuLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lng9PT10aGlzLngmJnQueT09PXRoaXMueSYmdC56PT09dGhpcy56JiZ0Lnc9PT10aGlzLnd9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXMudz10W2UrM10sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0W2UrMl09dGhpcy56LHRbZSszXT10aGlzLncsdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMueD10LmdldFgoZSksdGhpcy55PXQuZ2V0WShlKSx0aGlzLno9dC5nZXRaKGUpLHRoaXMudz10LmdldFcoZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpcy53PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55LHlpZWxkIHRoaXMueix5aWVsZCB0aGlzLnd9fWNsYXNzIHlpe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9MSl7dGhpcy5pc1F1YXRlcm5pb249ITAsdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fdz1zfXN0YXRpYyBzbGVycEZsYXQodCxlLG4scyxyLG8sYSl7bGV0IGM9bltzKzBdLGw9bltzKzFdLGg9bltzKzJdLHU9bltzKzNdO2NvbnN0IGY9cltvKzBdLGQ9cltvKzFdLHA9cltvKzJdLHk9cltvKzNdO2lmKGE9PT0wKXt0W2UrMF09Yyx0W2UrMV09bCx0W2UrMl09aCx0W2UrM109dTtyZXR1cm59aWYoYT09PTEpe3RbZSswXT1mLHRbZSsxXT1kLHRbZSsyXT1wLHRbZSszXT15O3JldHVybn1pZih1IT09eXx8YyE9PWZ8fGwhPT1kfHxoIT09cCl7bGV0IG09MS1hO2NvbnN0IGc9YypmK2wqZCtoKnArdSp5LGI9Zz49MD8xOi0xLHc9MS1nKmc7aWYodz5OdW1iZXIuRVBTSUxPTil7Y29uc3QgTT1NYXRoLnNxcnQodyksQT1NYXRoLmF0YW4yKE0sZypiKTttPU1hdGguc2luKG0qQSkvTSxhPU1hdGguc2luKGEqQSkvTX1jb25zdCB4PWEqYjtpZihjPWMqbStmKngsbD1sKm0rZCp4LGg9aCptK3AqeCx1PXUqbSt5KngsbT09PTEtYSl7Y29uc3QgTT0xL01hdGguc3FydChjKmMrbCpsK2gqaCt1KnUpO2MqPU0sbCo9TSxoKj1NLHUqPU19fXRbZV09Yyx0W2UrMV09bCx0W2UrMl09aCx0W2UrM109dX1zdGF0aWMgbXVsdGlwbHlRdWF0ZXJuaW9uc0ZsYXQodCxlLG4scyxyLG8pe2NvbnN0IGE9bltzXSxjPW5bcysxXSxsPW5bcysyXSxoPW5bcyszXSx1PXJbb10sZj1yW28rMV0sZD1yW28rMl0scD1yW28rM107cmV0dXJuIHRbZV09YSpwK2gqdStjKmQtbCpmLHRbZSsxXT1jKnAraCpmK2wqdS1hKmQsdFtlKzJdPWwqcCtoKmQrYSpmLWMqdSx0W2UrM109aCpwLWEqdS1jKmYtbCpkLHR9Z2V0IHgoKXtyZXR1cm4gdGhpcy5feH1zZXQgeCh0KXt0aGlzLl94PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB5KCl7cmV0dXJuIHRoaXMuX3l9c2V0IHkodCl7dGhpcy5feT10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeigpe3JldHVybiB0aGlzLl96fXNldCB6KHQpe3RoaXMuX3o9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHcoKXtyZXR1cm4gdGhpcy5fd31zZXQgdyh0KXt0aGlzLl93PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfXNldCh0LGUsbixzKXtyZXR1cm4gdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fdz1zLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuX3gsdGhpcy5feSx0aGlzLl96LHRoaXMuX3cpfWNvcHkodCl7cmV0dXJuIHRoaXMuX3g9dC54LHRoaXMuX3k9dC55LHRoaXMuX3o9dC56LHRoaXMuX3c9dC53LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21FdWxlcih0LGU9ITApe2NvbnN0IG49dC5feCxzPXQuX3kscj10Ll96LG89dC5fb3JkZXIsYT1NYXRoLmNvcyxjPU1hdGguc2luLGw9YShuLzIpLGg9YShzLzIpLHU9YShyLzIpLGY9YyhuLzIpLGQ9YyhzLzIpLHA9YyhyLzIpO3N3aXRjaChvKXtjYXNlIlhZWiI6dGhpcy5feD1mKmgqdStsKmQqcCx0aGlzLl95PWwqZCp1LWYqaCpwLHRoaXMuX3o9bCpoKnArZipkKnUsdGhpcy5fdz1sKmgqdS1mKmQqcDticmVhaztjYXNlIllYWiI6dGhpcy5feD1mKmgqdStsKmQqcCx0aGlzLl95PWwqZCp1LWYqaCpwLHRoaXMuX3o9bCpoKnAtZipkKnUsdGhpcy5fdz1sKmgqdStmKmQqcDticmVhaztjYXNlIlpYWSI6dGhpcy5feD1mKmgqdS1sKmQqcCx0aGlzLl95PWwqZCp1K2YqaCpwLHRoaXMuX3o9bCpoKnArZipkKnUsdGhpcy5fdz1sKmgqdS1mKmQqcDticmVhaztjYXNlIlpZWCI6dGhpcy5feD1mKmgqdS1sKmQqcCx0aGlzLl95PWwqZCp1K2YqaCpwLHRoaXMuX3o9bCpoKnAtZipkKnUsdGhpcy5fdz1sKmgqdStmKmQqcDticmVhaztjYXNlIllaWCI6dGhpcy5feD1mKmgqdStsKmQqcCx0aGlzLl95PWwqZCp1K2YqaCpwLHRoaXMuX3o9bCpoKnAtZipkKnUsdGhpcy5fdz1sKmgqdS1mKmQqcDticmVhaztjYXNlIlhaWSI6dGhpcy5feD1mKmgqdS1sKmQqcCx0aGlzLl95PWwqZCp1LWYqaCpwLHRoaXMuX3o9bCpoKnArZipkKnUsdGhpcy5fdz1sKmgqdStmKmQqcDticmVhaztkZWZhdWx0OmNvbnNvbGUud2FybigiVEhSRUUuUXVhdGVybmlvbjogLnNldEZyb21FdWxlcigpIGVuY291bnRlcmVkIGFuIHVua25vd24gb3JkZXI6ICIrbyl9cmV0dXJuIGU9PT0hMCYmdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbUF4aXNBbmdsZSh0LGUpe2NvbnN0IG49ZS8yLHM9TWF0aC5zaW4obik7cmV0dXJuIHRoaXMuX3g9dC54KnMsdGhpcy5feT10Lnkqcyx0aGlzLl96PXQueipzLHRoaXMuX3c9TWF0aC5jb3MobiksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVJvdGF0aW9uTWF0cml4KHQpe2NvbnN0IGU9dC5lbGVtZW50cyxuPWVbMF0scz1lWzRdLHI9ZVs4XSxvPWVbMV0sYT1lWzVdLGM9ZVs5XSxsPWVbMl0saD1lWzZdLHU9ZVsxMF0sZj1uK2ErdTtpZihmPjApe2NvbnN0IGQ9LjUvTWF0aC5zcXJ0KGYrMSk7dGhpcy5fdz0uMjUvZCx0aGlzLl94PShoLWMpKmQsdGhpcy5feT0oci1sKSpkLHRoaXMuX3o9KG8tcykqZH1lbHNlIGlmKG4+YSYmbj51KXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErbi1hLXUpO3RoaXMuX3c9KGgtYykvZCx0aGlzLl94PS4yNSpkLHRoaXMuX3k9KHMrbykvZCx0aGlzLl96PShyK2wpL2R9ZWxzZSBpZihhPnUpe2NvbnN0IGQ9MipNYXRoLnNxcnQoMSthLW4tdSk7dGhpcy5fdz0oci1sKS9kLHRoaXMuX3g9KHMrbykvZCx0aGlzLl95PS4yNSpkLHRoaXMuX3o9KGMraCkvZH1lbHNle2NvbnN0IGQ9MipNYXRoLnNxcnQoMSt1LW4tYSk7dGhpcy5fdz0oby1zKS9kLHRoaXMuX3g9KHIrbCkvZCx0aGlzLl95PShjK2gpL2QsdGhpcy5fej0uMjUqZH1yZXR1cm4gdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVVuaXRWZWN0b3JzKHQsZSl7bGV0IG49dC5kb3QoZSkrMTtyZXR1cm4gbjxOdW1iZXIuRVBTSUxPTj8obj0wLE1hdGguYWJzKHQueCk+TWF0aC5hYnModC56KT8odGhpcy5feD0tdC55LHRoaXMuX3k9dC54LHRoaXMuX3o9MCx0aGlzLl93PW4pOih0aGlzLl94PTAsdGhpcy5feT0tdC56LHRoaXMuX3o9dC55LHRoaXMuX3c9bikpOih0aGlzLl94PXQueSplLnotdC56KmUueSx0aGlzLl95PXQueiplLngtdC54KmUueix0aGlzLl96PXQueCplLnktdC55KmUueCx0aGlzLl93PW4pLHRoaXMubm9ybWFsaXplKCl9YW5nbGVUbyh0KXtyZXR1cm4gMipNYXRoLmFjb3MoTWF0aC5hYnMoWih0aGlzLmRvdCh0KSwtMSwxKSkpfXJvdGF0ZVRvd2FyZHModCxlKXtjb25zdCBuPXRoaXMuYW5nbGVUbyh0KTtpZihuPT09MClyZXR1cm4gdGhpcztjb25zdCBzPU1hdGgubWluKDEsZS9uKTtyZXR1cm4gdGhpcy5zbGVycCh0LHMpLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMSl9aW52ZXJ0KCl7cmV0dXJuIHRoaXMuY29uanVnYXRlKCl9Y29uanVnYXRlKCl7cmV0dXJuIHRoaXMuX3gqPS0xLHRoaXMuX3kqPS0xLHRoaXMuX3oqPS0xLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfWRvdCh0KXtyZXR1cm4gdGhpcy5feCp0Ll94K3RoaXMuX3kqdC5feSt0aGlzLl96KnQuX3ordGhpcy5fdyp0Ll93fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fd31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fdyl9bm9ybWFsaXplKCl7bGV0IHQ9dGhpcy5sZW5ndGgoKTtyZXR1cm4gdD09PTA/KHRoaXMuX3g9MCx0aGlzLl95PTAsdGhpcy5fej0wLHRoaXMuX3c9MSk6KHQ9MS90LHRoaXMuX3g9dGhpcy5feCp0LHRoaXMuX3k9dGhpcy5feSp0LHRoaXMuX3o9dGhpcy5feip0LHRoaXMuX3c9dGhpcy5fdyp0KSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseVF1YXRlcm5pb25zKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlRdWF0ZXJuaW9ucyh0LHRoaXMpfW11bHRpcGx5UXVhdGVybmlvbnModCxlKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX3csYT1lLl94LGM9ZS5feSxsPWUuX3osaD1lLl93O3JldHVybiB0aGlzLl94PW4qaCtvKmErcypsLXIqYyx0aGlzLl95PXMqaCtvKmMrciphLW4qbCx0aGlzLl96PXIqaCtvKmwrbipjLXMqYSx0aGlzLl93PW8qaC1uKmEtcypjLXIqbCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zbGVycCh0LGUpe2lmKGU9PT0wKXJldHVybiB0aGlzO2lmKGU9PT0xKXJldHVybiB0aGlzLmNvcHkodCk7Y29uc3Qgbj10aGlzLl94LHM9dGhpcy5feSxyPXRoaXMuX3osbz10aGlzLl93O2xldCBhPW8qdC5fdytuKnQuX3grcyp0Ll95K3IqdC5fejtpZihhPDA/KHRoaXMuX3c9LXQuX3csdGhpcy5feD0tdC5feCx0aGlzLl95PS10Ll95LHRoaXMuX3o9LXQuX3osYT0tYSk6dGhpcy5jb3B5KHQpLGE+PTEpcmV0dXJuIHRoaXMuX3c9byx0aGlzLl94PW4sdGhpcy5feT1zLHRoaXMuX3o9cix0aGlzO2NvbnN0IGM9MS1hKmE7aWYoYzw9TnVtYmVyLkVQU0lMT04pe2NvbnN0IGQ9MS1lO3JldHVybiB0aGlzLl93PWQqbytlKnRoaXMuX3csdGhpcy5feD1kKm4rZSp0aGlzLl94LHRoaXMuX3k9ZCpzK2UqdGhpcy5feSx0aGlzLl96PWQqcitlKnRoaXMuX3osdGhpcy5ub3JtYWxpemUoKSx0aGlzfWNvbnN0IGw9TWF0aC5zcXJ0KGMpLGg9TWF0aC5hdGFuMihsLGEpLHU9TWF0aC5zaW4oKDEtZSkqaCkvbCxmPU1hdGguc2luKGUqaCkvbDtyZXR1cm4gdGhpcy5fdz1vKnUrdGhpcy5fdypmLHRoaXMuX3g9bip1K3RoaXMuX3gqZix0aGlzLl95PXMqdSt0aGlzLl95KmYsdGhpcy5fej1yKnUrdGhpcy5feipmLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNsZXJwUXVhdGVybmlvbnModCxlLG4pe3JldHVybiB0aGlzLmNvcHkodCkuc2xlcnAoZSxuKX1yYW5kb20oKXtjb25zdCB0PTIqTWF0aC5QSSpNYXRoLnJhbmRvbSgpLGU9MipNYXRoLlBJKk1hdGgucmFuZG9tKCksbj1NYXRoLnJhbmRvbSgpLHM9TWF0aC5zcXJ0KDEtbikscj1NYXRoLnNxcnQobik7cmV0dXJuIHRoaXMuc2V0KHMqTWF0aC5zaW4odCkscypNYXRoLmNvcyh0KSxyKk1hdGguc2luKGUpLHIqTWF0aC5jb3MoZSkpfWVxdWFscyh0KXtyZXR1cm4gdC5feD09PXRoaXMuX3gmJnQuX3k9PT10aGlzLl95JiZ0Ll96PT09dGhpcy5feiYmdC5fdz09PXRoaXMuX3d9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy5feD10W2VdLHRoaXMuX3k9dFtlKzFdLHRoaXMuX3o9dFtlKzJdLHRoaXMuX3c9dFtlKzNdLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMuX3gsdFtlKzFdPXRoaXMuX3ksdFtlKzJdPXRoaXMuX3osdFtlKzNdPXRoaXMuX3csdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMuX3g9dC5nZXRYKGUpLHRoaXMuX3k9dC5nZXRZKGUpLHRoaXMuX3o9dC5nZXRaKGUpLHRoaXMuX3c9dC5nZXRXKGUpLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvSlNPTigpe3JldHVybiB0aGlzLnRvQXJyYXkoKX1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX3d9fWNsYXNzIFR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTApe1QucHJvdG90eXBlLmlzVmVjdG9yMz0hMCx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bn1zZXQodCxlLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj10aGlzLnopLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXN9c2V0U2NhbGFyKHQpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9dCx0aGlzLno9dCx0aGlzfXNldFgodCl7cmV0dXJuIHRoaXMueD10LHRoaXN9c2V0WSh0KXtyZXR1cm4gdGhpcy55PXQsdGhpc31zZXRaKHQpe3JldHVybiB0aGlzLno9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAiK3QpfXJldHVybiB0aGlzfWdldENvbXBvbmVudCh0KXtzd2l0Y2godCl7Y2FzZSAwOnJldHVybiB0aGlzLng7Y2FzZSAxOnJldHVybiB0aGlzLnk7Y2FzZSAyOnJldHVybiB0aGlzLno7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX19Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy54LHRoaXMueSx0aGlzLnopfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzLno9dC56LHRoaXN9YWRkKHQpe3JldHVybiB0aGlzLngrPXQueCx0aGlzLnkrPXQueSx0aGlzLnorPXQueix0aGlzfWFkZFNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kz10LHRoaXMueSs9dCx0aGlzLnorPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXMuej10LnorZS56LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzLnorPXQueiplLHRoaXN9c3ViKHQpe3JldHVybiB0aGlzLngtPXQueCx0aGlzLnktPXQueSx0aGlzLnotPXQueix0aGlzfXN1YlNjYWxhcih0KXtyZXR1cm4gdGhpcy54LT10LHRoaXMueS09dCx0aGlzLnotPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXMuej10LnotZS56LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXMueio9dC56LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpcy56Kj10LHRoaXN9bXVsdGlwbHlWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngqZS54LHRoaXMueT10LnkqZS55LHRoaXMuej10LnoqZS56LHRoaXN9YXBwbHlFdWxlcih0KXtyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oeGMuc2V0RnJvbUV1bGVyKHQpKX1hcHBseUF4aXNBbmdsZSh0LGUpe3JldHVybiB0aGlzLmFwcGx5UXVhdGVybmlvbih4Yy5zZXRGcm9tQXhpc0FuZ2xlKHQsZSkpfWFwcGx5TWF0cml4Myh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrclszXSpuK3JbNl0qcyx0aGlzLnk9clsxXSplK3JbNF0qbityWzddKnMsdGhpcy56PXJbMl0qZStyWzVdKm4rcls4XSpzLHRoaXN9YXBwbHlOb3JtYWxNYXRyaXgodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXgzKHQpLm5vcm1hbGl6ZSgpfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHMsbz0xLyhyWzNdKmUrcls3XSpuK3JbMTFdKnMrclsxNV0pO3JldHVybiB0aGlzLng9KHJbMF0qZStyWzRdKm4rcls4XSpzK3JbMTJdKSpvLHRoaXMueT0oclsxXSplK3JbNV0qbityWzldKnMrclsxM10pKm8sdGhpcy56PShyWzJdKmUrcls2XSpuK3JbMTBdKnMrclsxNF0pKm8sdGhpc31hcHBseVF1YXRlcm5pb24odCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10Lngsbz10LnksYT10LnosYz10LncsbD0yKihvKnMtYSpuKSxoPTIqKGEqZS1yKnMpLHU9MioocipuLW8qZSk7cmV0dXJuIHRoaXMueD1lK2MqbCtvKnUtYSpoLHRoaXMueT1uK2MqaCthKmwtcip1LHRoaXMuej1zK2MqdStyKmgtbypsLHRoaXN9cHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZEludmVyc2UpLmFwcGx5TWF0cml4NCh0LnByb2plY3Rpb25NYXRyaXgpfXVucHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5wcm9qZWN0aW9uTWF0cml4SW52ZXJzZSkuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpfXRyYW5zZm9ybURpcmVjdGlvbih0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrcls0XSpuK3JbOF0qcyx0aGlzLnk9clsxXSplK3JbNV0qbityWzldKnMsdGhpcy56PXJbMl0qZStyWzZdKm4rclsxMF0qcyx0aGlzLm5vcm1hbGl6ZSgpfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1taW4odCl7cmV0dXJuIHRoaXMueD1NYXRoLm1pbih0aGlzLngsdC54KSx0aGlzLnk9TWF0aC5taW4odGhpcy55LHQueSksdGhpcy56PU1hdGgubWluKHRoaXMueix0LnopLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzfWNsYW1wKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LngsZS54KSx0aGlzLnk9Wih0aGlzLnksdC55LGUueSksdGhpcy56PVoodGhpcy56LHQueixlLnopLHRoaXN9Y2xhbXBTY2FsYXIodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQsZSksdGhpcy55PVoodGhpcy55LHQsZSksdGhpcy56PVoodGhpcy56LHQsZSksdGhpc31jbGFtcExlbmd0aCh0LGUpe2NvbnN0IG49dGhpcy5sZW5ndGgoKTtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIobnx8MSkubXVsdGlwbHlTY2FsYXIoWihuLHQsZSkpfWZsb29yKCl7cmV0dXJuIHRoaXMueD1NYXRoLmZsb29yKHRoaXMueCksdGhpcy55PU1hdGguZmxvb3IodGhpcy55KSx0aGlzLno9TWF0aC5mbG9vcih0aGlzLnopLHRoaXN9Y2VpbCgpe3JldHVybiB0aGlzLng9TWF0aC5jZWlsKHRoaXMueCksdGhpcy55PU1hdGguY2VpbCh0aGlzLnkpLHRoaXMuej1NYXRoLmNlaWwodGhpcy56KSx0aGlzfXJvdW5kKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJvdW5kKHRoaXMueCksdGhpcy55PU1hdGgucm91bmQodGhpcy55KSx0aGlzLno9TWF0aC5yb3VuZCh0aGlzLnopLHRoaXN9cm91bmRUb1plcm8oKXtyZXR1cm4gdGhpcy54PU1hdGgudHJ1bmModGhpcy54KSx0aGlzLnk9TWF0aC50cnVuYyh0aGlzLnkpLHRoaXMuej1NYXRoLnRydW5jKHRoaXMueiksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56fWxlbmd0aCgpe3JldHVybiBNYXRoLnNxcnQodGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnopfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXMueis9KHQuei10aGlzLnopKmUsdGhpc31sZXJwVmVjdG9ycyh0LGUsbil7cmV0dXJuIHRoaXMueD10LngrKGUueC10LngpKm4sdGhpcy55PXQueSsoZS55LXQueSkqbix0aGlzLno9dC56KyhlLnotdC56KSpuLHRoaXN9Y3Jvc3ModCl7cmV0dXJuIHRoaXMuY3Jvc3NWZWN0b3JzKHRoaXMsdCl9Y3Jvc3NWZWN0b3JzKHQsZSl7Y29uc3Qgbj10Lngscz10Lnkscj10Lnosbz1lLngsYT1lLnksYz1lLno7cmV0dXJuIHRoaXMueD1zKmMtciphLHRoaXMueT1yKm8tbipjLHRoaXMuej1uKmEtcypvLHRoaXN9cHJvamVjdE9uVmVjdG9yKHQpe2NvbnN0IGU9dC5sZW5ndGhTcSgpO2lmKGU9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCk7Y29uc3Qgbj10LmRvdCh0aGlzKS9lO3JldHVybiB0aGlzLmNvcHkodCkubXVsdGlwbHlTY2FsYXIobil9cHJvamVjdE9uUGxhbmUodCl7cmV0dXJuIHRvLmNvcHkodGhpcykucHJvamVjdE9uVmVjdG9yKHQpLHRoaXMuc3ViKHRvKX1yZWZsZWN0KHQpe3JldHVybiB0aGlzLnN1Yih0by5jb3B5KHQpLm11bHRpcGx5U2NhbGFyKDIqdGhpcy5kb3QodCkpKX1hbmdsZVRvKHQpe2NvbnN0IGU9TWF0aC5zcXJ0KHRoaXMubGVuZ3RoU3EoKSp0Lmxlbmd0aFNxKCkpO2lmKGU9PT0wKXJldHVybiBNYXRoLlBJLzI7Y29uc3Qgbj10aGlzLmRvdCh0KS9lO3JldHVybiBNYXRoLmFjb3MoWihuLC0xLDEpKX1kaXN0YW5jZVRvKHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVRvU3F1YXJlZCh0KSl9ZGlzdGFuY2VUb1NxdWFyZWQodCl7Y29uc3QgZT10aGlzLngtdC54LG49dGhpcy55LXQueSxzPXRoaXMuei10Lno7cmV0dXJuIGUqZStuKm4rcypzfW1hbmhhdHRhbkRpc3RhbmNlVG8odCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueC10LngpK01hdGguYWJzKHRoaXMueS10LnkpK01hdGguYWJzKHRoaXMuei10LnopfXNldEZyb21TcGhlcmljYWwodCl7cmV0dXJuIHRoaXMuc2V0RnJvbVNwaGVyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnBoaSx0LnRoZXRhKX1zZXRGcm9tU3BoZXJpY2FsQ29vcmRzKHQsZSxuKXtjb25zdCBzPU1hdGguc2luKGUpKnQ7cmV0dXJuIHRoaXMueD1zKk1hdGguc2luKG4pLHRoaXMueT1NYXRoLmNvcyhlKSp0LHRoaXMuej1zKk1hdGguY29zKG4pLHRoaXN9c2V0RnJvbUN5bGluZHJpY2FsKHQpe3JldHVybiB0aGlzLnNldEZyb21DeWxpbmRyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnRoZXRhLHQueSl9c2V0RnJvbUN5bGluZHJpY2FsQ29vcmRzKHQsZSxuKXtyZXR1cm4gdGhpcy54PXQqTWF0aC5zaW4oZSksdGhpcy55PW4sdGhpcy56PXQqTWF0aC5jb3MoZSksdGhpc31zZXRGcm9tTWF0cml4UG9zaXRpb24odCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9ZVsxMl0sdGhpcy55PWVbMTNdLHRoaXMuej1lWzE0XSx0aGlzfXNldEZyb21NYXRyaXhTY2FsZSh0KXtjb25zdCBlPXRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLG49dGhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCkscz10aGlzLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gdGhpcy54PWUsdGhpcy55PW4sdGhpcy56PXMsdGhpc31zZXRGcm9tTWF0cml4Q29sdW1uKHQsZSl7cmV0dXJuIHRoaXMuZnJvbUFycmF5KHQuZWxlbWVudHMsZSo0KX1zZXRGcm9tTWF0cml4M0NvbHVtbih0LGUpe3JldHVybiB0aGlzLmZyb21BcnJheSh0LmVsZW1lbnRzLGUqMyl9c2V0RnJvbUV1bGVyKHQpe3JldHVybiB0aGlzLng9dC5feCx0aGlzLnk9dC5feSx0aGlzLno9dC5feix0aGlzfXNldEZyb21Db2xvcih0KXtyZXR1cm4gdGhpcy54PXQucix0aGlzLnk9dC5nLHRoaXMuej10LmIsdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55JiZ0Lno9PT10aGlzLnp9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy54LHRbZSsxXT10aGlzLnksdFtlKzJdPXRoaXMueix0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXMuej10LmdldFooZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpc31yYW5kb21EaXJlY3Rpb24oKXtjb25zdCB0PU1hdGgucmFuZG9tKCkqTWF0aC5QSSoyLGU9TWF0aC5yYW5kb20oKSoyLTEsbj1NYXRoLnNxcnQoMS1lKmUpO3JldHVybiB0aGlzLng9bipNYXRoLmNvcyh0KSx0aGlzLnk9ZSx0aGlzLno9bipNYXRoLnNpbih0KSx0aGlzfSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMueCx5aWVsZCB0aGlzLnkseWllbGQgdGhpcy56fX1jb25zdCB0bz1uZXcgVCx4Yz1uZXcgeWk7Y2xhc3MgZ3R7Y29uc3RydWN0b3IodD1uZXcgVCgxLzAsMS8wLDEvMCksZT1uZXcgVCgtMS8wLC0xLzAsLTEvMCkpe3RoaXMuaXNCb3gzPSEwLHRoaXMubWluPXQsdGhpcy5tYXg9ZX1zZXQodCxlKXtyZXR1cm4gdGhpcy5taW4uY29weSh0KSx0aGlzLm1heC5jb3B5KGUpLHRoaXN9c2V0RnJvbUFycmF5KHQpe3RoaXMubWFrZUVtcHR5KCk7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aDtlPG47ZSs9Myl0aGlzLmV4cGFuZEJ5UG9pbnQoY2UuZnJvbUFycmF5KHQsZSkpO3JldHVybiB0aGlzfXNldEZyb21CdWZmZXJBdHRyaWJ1dGUodCl7dGhpcy5tYWtlRW1wdHkoKTtmb3IobGV0IGU9MCxuPXQuY291bnQ7ZTxuO2UrKyl0aGlzLmV4cGFuZEJ5UG9pbnQoY2UuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpKTtyZXR1cm4gdGhpc31zZXRGcm9tUG9pbnRzKHQpe3RoaXMubWFrZUVtcHR5KCk7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aDtlPG47ZSsrKXRoaXMuZXhwYW5kQnlQb2ludCh0W2VdKTtyZXR1cm4gdGhpc31zZXRGcm9tQ2VudGVyQW5kU2l6ZSh0LGUpe2NvbnN0IG49Y2UuY29weShlKS5tdWx0aXBseVNjYWxhciguNSk7cmV0dXJuIHRoaXMubWluLmNvcHkodCkuc3ViKG4pLHRoaXMubWF4LmNvcHkodCkuYWRkKG4pLHRoaXN9c2V0RnJvbU9iamVjdCh0LGU9ITEpe3JldHVybiB0aGlzLm1ha2VFbXB0eSgpLHRoaXMuZXhwYW5kQnlPYmplY3QodCxlKX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5taW4uY29weSh0Lm1pbiksdGhpcy5tYXguY29weSh0Lm1heCksdGhpc31tYWtlRW1wdHkoKXtyZXR1cm4gdGhpcy5taW4ueD10aGlzLm1pbi55PXRoaXMubWluLno9MS8wLHRoaXMubWF4Lng9dGhpcy5tYXgueT10aGlzLm1heC56PS0xLzAsdGhpc31pc0VtcHR5KCl7cmV0dXJuIHRoaXMubWF4Lng8dGhpcy5taW4ueHx8dGhpcy5tYXgueTx0aGlzLm1pbi55fHx0aGlzLm1heC56PHRoaXMubWluLnp9Z2V0Q2VudGVyKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90LnNldCgwLDAsMCk6dC5hZGRWZWN0b3JzKHRoaXMubWluLHRoaXMubWF4KS5tdWx0aXBseVNjYWxhciguNSl9Z2V0U2l6ZSh0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dC5zZXQoMCwwLDApOnQuc3ViVmVjdG9ycyh0aGlzLm1heCx0aGlzLm1pbil9ZXhwYW5kQnlQb2ludCh0KXtyZXR1cm4gdGhpcy5taW4ubWluKHQpLHRoaXMubWF4Lm1heCh0KSx0aGlzfWV4cGFuZEJ5VmVjdG9yKHQpe3JldHVybiB0aGlzLm1pbi5zdWIodCksdGhpcy5tYXguYWRkKHQpLHRoaXN9ZXhwYW5kQnlTY2FsYXIodCl7cmV0dXJuIHRoaXMubWluLmFkZFNjYWxhcigtdCksdGhpcy5tYXguYWRkU2NhbGFyKHQpLHRoaXN9ZXhwYW5kQnlPYmplY3QodCxlPSExKXt0LnVwZGF0ZVdvcmxkTWF0cml4KCExLCExKTtjb25zdCBuPXQuZ2VvbWV0cnk7aWYobiE9PXZvaWQgMCl7Y29uc3Qgcj1uLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKTtpZihlPT09ITAmJnIhPT12b2lkIDAmJnQuaXNJbnN0YW5jZWRNZXNoIT09ITApZm9yKGxldCBvPTAsYT1yLmNvdW50O288YTtvKyspdC5pc01lc2g9PT0hMD90LmdldFZlcnRleFBvc2l0aW9uKG8sY2UpOmNlLmZyb21CdWZmZXJBdHRyaWJ1dGUocixvKSxjZS5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZCksdGhpcy5leHBhbmRCeVBvaW50KGNlKTtlbHNlIHQuYm91bmRpbmdCb3ghPT12b2lkIDA/KHQuYm91bmRpbmdCb3g9PT1udWxsJiZ0LmNvbXB1dGVCb3VuZGluZ0JveCgpLHNzLmNvcHkodC5ib3VuZGluZ0JveCkpOihuLmJvdW5kaW5nQm94PT09bnVsbCYmbi5jb21wdXRlQm91bmRpbmdCb3goKSxzcy5jb3B5KG4uYm91bmRpbmdCb3gpKSxzcy5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZCksdGhpcy51bmlvbihzcyl9Y29uc3Qgcz10LmNoaWxkcmVuO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKyl0aGlzLmV4cGFuZEJ5T2JqZWN0KHNbcl0sZSk7cmV0dXJuIHRoaXN9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gdC54Pj10aGlzLm1pbi54JiZ0Lng8PXRoaXMubWF4LngmJnQueT49dGhpcy5taW4ueSYmdC55PD10aGlzLm1heC55JiZ0Lno+PXRoaXMubWluLnomJnQuejw9dGhpcy5tYXguen1jb250YWluc0JveCh0KXtyZXR1cm4gdGhpcy5taW4ueDw9dC5taW4ueCYmdC5tYXgueDw9dGhpcy5tYXgueCYmdGhpcy5taW4ueTw9dC5taW4ueSYmdC5tYXgueTw9dGhpcy5tYXgueSYmdGhpcy5taW4uejw9dC5taW4ueiYmdC5tYXguejw9dGhpcy5tYXguen1nZXRQYXJhbWV0ZXIodCxlKXtyZXR1cm4gZS5zZXQoKHQueC10aGlzLm1pbi54KS8odGhpcy5tYXgueC10aGlzLm1pbi54KSwodC55LXRoaXMubWluLnkpLyh0aGlzLm1heC55LXRoaXMubWluLnkpLCh0LnotdGhpcy5taW4ueikvKHRoaXMubWF4LnotdGhpcy5taW4ueikpfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQubWF4Lng+PXRoaXMubWluLngmJnQubWluLng8PXRoaXMubWF4LngmJnQubWF4Lnk+PXRoaXMubWluLnkmJnQubWluLnk8PXRoaXMubWF4LnkmJnQubWF4Lno+PXRoaXMubWluLnomJnQubWluLno8PXRoaXMubWF4Lnp9aW50ZXJzZWN0c1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5jbGFtcFBvaW50KHQuY2VudGVyLGNlKSxjZS5kaXN0YW5jZVRvU3F1YXJlZCh0LmNlbnRlcik8PXQucmFkaXVzKnQucmFkaXVzfWludGVyc2VjdHNQbGFuZSh0KXtsZXQgZSxuO3JldHVybiB0Lm5vcm1hbC54PjA/KGU9dC5ub3JtYWwueCp0aGlzLm1pbi54LG49dC5ub3JtYWwueCp0aGlzLm1heC54KTooZT10Lm5vcm1hbC54KnRoaXMubWF4Lngsbj10Lm5vcm1hbC54KnRoaXMubWluLngpLHQubm9ybWFsLnk+MD8oZSs9dC5ub3JtYWwueSp0aGlzLm1pbi55LG4rPXQubm9ybWFsLnkqdGhpcy5tYXgueSk6KGUrPXQubm9ybWFsLnkqdGhpcy5tYXgueSxuKz10Lm5vcm1hbC55KnRoaXMubWluLnkpLHQubm9ybWFsLno+MD8oZSs9dC5ub3JtYWwueip0aGlzLm1pbi56LG4rPXQubm9ybWFsLnoqdGhpcy5tYXgueik6KGUrPXQubm9ybWFsLnoqdGhpcy5tYXgueixuKz10Lm5vcm1hbC56KnRoaXMubWluLnopLGU8PS10LmNvbnN0YW50JiZuPj0tdC5jb25zdGFudH1pbnRlcnNlY3RzVHJpYW5nbGUodCl7aWYodGhpcy5pc0VtcHR5KCkpcmV0dXJuITE7dGhpcy5nZXRDZW50ZXIobWkpLHJzLnN1YlZlY3RvcnModGhpcy5tYXgsbWkpLGtuLnN1YlZlY3RvcnModC5hLG1pKSxObi5zdWJWZWN0b3JzKHQuYixtaSksUm4uc3ViVmVjdG9ycyh0LmMsbWkpLFplLnN1YlZlY3RvcnMoTm4sa24pLFhlLnN1YlZlY3RvcnMoUm4sTm4pLGxuLnN1YlZlY3RvcnMoa24sUm4pO2xldCBlPVswLC1aZS56LFplLnksMCwtWGUueixYZS55LDAsLWxuLnosbG4ueSxaZS56LDAsLVplLngsWGUueiwwLC1YZS54LGxuLnosMCwtbG4ueCwtWmUueSxaZS54LDAsLVhlLnksWGUueCwwLC1sbi55LGxuLngsMF07cmV0dXJuIWVvKGUsa24sTm4sUm4scnMpfHwoZT1bMSwwLDAsMCwxLDAsMCwwLDFdLCFlbyhlLGtuLE5uLFJuLHJzKSk/ITE6KG9zLmNyb3NzVmVjdG9ycyhaZSxYZSksZT1bb3MueCxvcy55LG9zLnpdLGVvKGUsa24sTm4sUm4scnMpKX1jbGFtcFBvaW50KHQsZSl7cmV0dXJuIGUuY29weSh0KS5jbGFtcCh0aGlzLm1pbix0aGlzLm1heCl9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiB0aGlzLmNsYW1wUG9pbnQodCxjZSkuZGlzdGFuY2VUbyh0KX1nZXRCb3VuZGluZ1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dC5tYWtlRW1wdHkoKToodGhpcy5nZXRDZW50ZXIodC5jZW50ZXIpLHQucmFkaXVzPXRoaXMuZ2V0U2l6ZShjZSkubGVuZ3RoKCkqLjUpLHR9aW50ZXJzZWN0KHQpe3JldHVybiB0aGlzLm1pbi5tYXgodC5taW4pLHRoaXMubWF4Lm1pbih0Lm1heCksdGhpcy5pc0VtcHR5KCkmJnRoaXMubWFrZUVtcHR5KCksdGhpc311bmlvbih0KXtyZXR1cm4gdGhpcy5taW4ubWluKHQubWluKSx0aGlzLm1heC5tYXgodC5tYXgpLHRoaXN9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90aGlzOihTZVswXS5zZXQodGhpcy5taW4ueCx0aGlzLm1pbi55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVsxXS5zZXQodGhpcy5taW4ueCx0aGlzLm1pbi55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSxTZVsyXS5zZXQodGhpcy5taW4ueCx0aGlzLm1heC55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVszXS5zZXQodGhpcy5taW4ueCx0aGlzLm1heC55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSxTZVs0XS5zZXQodGhpcy5tYXgueCx0aGlzLm1pbi55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVs1XS5zZXQodGhpcy5tYXgueCx0aGlzLm1pbi55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSxTZVs2XS5zZXQodGhpcy5tYXgueCx0aGlzLm1heC55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVs3XS5zZXQodGhpcy5tYXgueCx0aGlzLm1heC55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSx0aGlzLnNldEZyb21Qb2ludHMoU2UpLHRoaXMpfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5taW4uYWRkKHQpLHRoaXMubWF4LmFkZCh0KSx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5taW4uZXF1YWxzKHRoaXMubWluKSYmdC5tYXguZXF1YWxzKHRoaXMubWF4KX19Y29uc3QgU2U9W25ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBUXSxjZT1uZXcgVCxzcz1uZXcgZ3Qsa249bmV3IFQsTm49bmV3IFQsUm49bmV3IFQsWmU9bmV3IFQsWGU9bmV3IFQsbG49bmV3IFQsbWk9bmV3IFQscnM9bmV3IFQsb3M9bmV3IFQsaG49bmV3IFQ7ZnVuY3Rpb24gZW8oaSx0LGUsbixzKXtmb3IobGV0IHI9MCxvPWkubGVuZ3RoLTM7cjw9bztyKz0zKXtobi5mcm9tQXJyYXkoaSxyKTtjb25zdCBhPXMueCpNYXRoLmFicyhobi54KStzLnkqTWF0aC5hYnMoaG4ueSkrcy56Kk1hdGguYWJzKGhuLnopLGM9dC5kb3QoaG4pLGw9ZS5kb3QoaG4pLGg9bi5kb3QoaG4pO2lmKE1hdGgubWF4KC1NYXRoLm1heChjLGwsaCksTWF0aC5taW4oYyxsLGgpKT5hKXJldHVybiExfXJldHVybiEwfWNvbnN0IFh1PW5ldyBndCxnaT1uZXcgVCxubz1uZXcgVDtjbGFzcyBpb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9LTEpe3RoaXMuaXNTcGhlcmU9ITAsdGhpcy5jZW50ZXI9dCx0aGlzLnJhZGl1cz1lfXNldCh0LGUpe3JldHVybiB0aGlzLmNlbnRlci5jb3B5KHQpLHRoaXMucmFkaXVzPWUsdGhpc31zZXRGcm9tUG9pbnRzKHQsZSl7Y29uc3Qgbj10aGlzLmNlbnRlcjtlIT09dm9pZCAwP24uY29weShlKTpYdS5zZXRGcm9tUG9pbnRzKHQpLmdldENlbnRlcihuKTtsZXQgcz0wO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKylzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZCh0W3JdKSk7cmV0dXJuIHRoaXMucmFkaXVzPU1hdGguc3FydChzKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuY2VudGVyLmNvcHkodC5jZW50ZXIpLHRoaXMucmFkaXVzPXQucmFkaXVzLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLnJhZGl1czwwfW1ha2VFbXB0eSgpe3JldHVybiB0aGlzLmNlbnRlci5zZXQoMCwwLDApLHRoaXMucmFkaXVzPS0xLHRoaXN9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmNlbnRlcik8PXRoaXMucmFkaXVzKnRoaXMucmFkaXVzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKS10aGlzLnJhZGl1c31pbnRlcnNlY3RzU3BoZXJlKHQpe2NvbnN0IGU9dGhpcy5yYWRpdXMrdC5yYWRpdXM7cmV0dXJuIHQuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuY2VudGVyKTw9ZSplfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1NwaGVyZSh0aGlzKX1pbnRlcnNlY3RzUGxhbmUodCl7cmV0dXJuIE1hdGguYWJzKHQuZGlzdGFuY2VUb1BvaW50KHRoaXMuY2VudGVyKSk8PXRoaXMucmFkaXVzfWNsYW1wUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHQpO3JldHVybiBlLmNvcHkodCksbj50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyYmKGUuc3ViKHRoaXMuY2VudGVyKS5ub3JtYWxpemUoKSxlLm11bHRpcGx5U2NhbGFyKHRoaXMucmFkaXVzKS5hZGQodGhpcy5jZW50ZXIpKSxlfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT8odC5tYWtlRW1wdHkoKSx0KToodC5zZXQodGhpcy5jZW50ZXIsdGhpcy5jZW50ZXIpLHQuZXhwYW5kQnlTY2FsYXIodGhpcy5yYWRpdXMpLHQpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYXBwbHlNYXRyaXg0KHQpLHRoaXMucmFkaXVzPXRoaXMucmFkaXVzKnQuZ2V0TWF4U2NhbGVPbkF4aXMoKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYWRkKHQpLHRoaXN9ZXhwYW5kQnlQb2ludCh0KXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4gdGhpcy5jZW50ZXIuY29weSh0KSx0aGlzLnJhZGl1cz0wLHRoaXM7Z2kuc3ViVmVjdG9ycyh0LHRoaXMuY2VudGVyKTtjb25zdCBlPWdpLmxlbmd0aFNxKCk7aWYoZT50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyl7Y29uc3Qgbj1NYXRoLnNxcnQoZSkscz0obi10aGlzLnJhZGl1cykqLjU7dGhpcy5jZW50ZXIuYWRkU2NhbGVkVmVjdG9yKGdpLHMvbiksdGhpcy5yYWRpdXMrPXN9cmV0dXJuIHRoaXN9dW5pb24odCl7cmV0dXJuIHQuaXNFbXB0eSgpP3RoaXM6dGhpcy5pc0VtcHR5KCk/KHRoaXMuY29weSh0KSx0aGlzKToodGhpcy5jZW50ZXIuZXF1YWxzKHQuY2VudGVyKT09PSEwP3RoaXMucmFkaXVzPU1hdGgubWF4KHRoaXMucmFkaXVzLHQucmFkaXVzKToobm8uc3ViVmVjdG9ycyh0LmNlbnRlcix0aGlzLmNlbnRlcikuc2V0TGVuZ3RoKHQucmFkaXVzKSx0aGlzLmV4cGFuZEJ5UG9pbnQoZ2kuY29weSh0LmNlbnRlcikuYWRkKG5vKSksdGhpcy5leHBhbmRCeVBvaW50KGdpLmNvcHkodC5jZW50ZXIpLnN1YihubykpKSx0aGlzKX1lcXVhbHModCl7cmV0dXJuIHQuY2VudGVyLmVxdWFscyh0aGlzLmNlbnRlcikmJnQucmFkaXVzPT09dGhpcy5yYWRpdXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX1jb25zdCB2ZT1uZXcgVCxzbz1uZXcgVCxhcz1uZXcgVCxKZT1uZXcgVCxybz1uZXcgVCxjcz1uZXcgVCxvbz1uZXcgVDtjbGFzcyBhb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQoMCwwLC0xKSl7dGhpcy5vcmlnaW49dCx0aGlzLmRpcmVjdGlvbj1lfXNldCh0LGUpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQpLHRoaXMuZGlyZWN0aW9uLmNvcHkoZSksdGhpc31jb3B5KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQub3JpZ2luKSx0aGlzLmRpcmVjdGlvbi5jb3B5KHQuZGlyZWN0aW9uKSx0aGlzfWF0KHQsZSl7cmV0dXJuIGUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLHQpfWxvb2tBdCh0KXtyZXR1cm4gdGhpcy5kaXJlY3Rpb24uY29weSh0KS5zdWIodGhpcy5vcmlnaW4pLm5vcm1hbGl6ZSgpLHRoaXN9cmVjYXN0KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHRoaXMuYXQodCx2ZSkpLHRoaXN9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUpe2Uuc3ViVmVjdG9ycyh0LHRoaXMub3JpZ2luKTtjb25zdCBuPWUuZG90KHRoaXMuZGlyZWN0aW9uKTtyZXR1cm4gbjwwP2UuY29weSh0aGlzLm9yaWdpbik6ZS5jb3B5KHRoaXMub3JpZ2luKS5hZGRTY2FsZWRWZWN0b3IodGhpcy5kaXJlY3Rpb24sbil9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVNxVG9Qb2ludCh0KSl9ZGlzdGFuY2VTcVRvUG9pbnQodCl7Y29uc3QgZT12ZS5zdWJWZWN0b3JzKHQsdGhpcy5vcmlnaW4pLmRvdCh0aGlzLmRpcmVjdGlvbik7cmV0dXJuIGU8MD90aGlzLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZCh0KToodmUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLGUpLHZlLmRpc3RhbmNlVG9TcXVhcmVkKHQpKX1kaXN0YW5jZVNxVG9TZWdtZW50KHQsZSxuLHMpe3NvLmNvcHkodCkuYWRkKGUpLm11bHRpcGx5U2NhbGFyKC41KSxhcy5jb3B5KGUpLnN1Yih0KS5ub3JtYWxpemUoKSxKZS5jb3B5KHRoaXMub3JpZ2luKS5zdWIoc28pO2NvbnN0IHI9dC5kaXN0YW5jZVRvKGUpKi41LG89LXRoaXMuZGlyZWN0aW9uLmRvdChhcyksYT1KZS5kb3QodGhpcy5kaXJlY3Rpb24pLGM9LUplLmRvdChhcyksbD1KZS5sZW5ndGhTcSgpLGg9TWF0aC5hYnMoMS1vKm8pO2xldCB1LGYsZCxwO2lmKGg+MClpZih1PW8qYy1hLGY9byphLWMscD1yKmgsdT49MClpZihmPj0tcClpZihmPD1wKXtjb25zdCB5PTEvaDt1Kj15LGYqPXksZD11Kih1K28qZisyKmEpK2YqKG8qdStmKzIqYykrbH1lbHNlIGY9cix1PU1hdGgubWF4KDAsLShvKmYrYSkpLGQ9LXUqdStmKihmKzIqYykrbDtlbHNlIGY9LXIsdT1NYXRoLm1heCgwLC0obypmK2EpKSxkPS11KnUrZiooZisyKmMpK2w7ZWxzZSBmPD0tcD8odT1NYXRoLm1heCgwLC0oLW8qcithKSksZj11PjA/LXI6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk6Zjw9cD8odT0wLGY9TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9ZiooZisyKmMpK2wpOih1PU1hdGgubWF4KDAsLShvKnIrYSkpLGY9dT4wP3I6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk7ZWxzZSBmPW8+MD8tcjpyLHU9TWF0aC5tYXgoMCwtKG8qZithKSksZD0tdSp1K2YqKGYrMipjKStsO3JldHVybiBuJiZuLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbix1KSxzJiZzLmNvcHkoc28pLmFkZFNjYWxlZFZlY3RvcihhcyxmKSxkfWludGVyc2VjdFNwaGVyZSh0LGUpe3ZlLnN1YlZlY3RvcnModC5jZW50ZXIsdGhpcy5vcmlnaW4pO2NvbnN0IG49dmUuZG90KHRoaXMuZGlyZWN0aW9uKSxzPXZlLmRvdCh2ZSktbipuLHI9dC5yYWRpdXMqdC5yYWRpdXM7aWYocz5yKXJldHVybiBudWxsO2NvbnN0IG89TWF0aC5zcXJ0KHItcyksYT1uLW8sYz1uK287cmV0dXJuIGM8MD9udWxsOmE8MD90aGlzLmF0KGMsZSk6dGhpcy5hdChhLGUpfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHRoaXMuZGlzdGFuY2VTcVRvUG9pbnQodC5jZW50ZXIpPD10LnJhZGl1cyp0LnJhZGl1c31kaXN0YW5jZVRvUGxhbmUodCl7Y29uc3QgZT10Lm5vcm1hbC5kb3QodGhpcy5kaXJlY3Rpb24pO2lmKGU9PT0wKXJldHVybiB0LmRpc3RhbmNlVG9Qb2ludCh0aGlzLm9yaWdpbik9PT0wPzA6bnVsbDtjb25zdCBuPS0odGhpcy5vcmlnaW4uZG90KHQubm9ybWFsKSt0LmNvbnN0YW50KS9lO3JldHVybiBuPj0wP246bnVsbH1pbnRlcnNlY3RQbGFuZSh0LGUpe2NvbnN0IG49dGhpcy5kaXN0YW5jZVRvUGxhbmUodCk7cmV0dXJuIG49PT1udWxsP251bGw6dGhpcy5hdChuLGUpfWludGVyc2VjdHNQbGFuZSh0KXtjb25zdCBlPXQuZGlzdGFuY2VUb1BvaW50KHRoaXMub3JpZ2luKTtyZXR1cm4gZT09PTB8fHQubm9ybWFsLmRvdCh0aGlzLmRpcmVjdGlvbikqZTwwfWludGVyc2VjdEJveCh0LGUpe2xldCBuLHMscixvLGEsYztjb25zdCBsPTEvdGhpcy5kaXJlY3Rpb24ueCxoPTEvdGhpcy5kaXJlY3Rpb24ueSx1PTEvdGhpcy5kaXJlY3Rpb24ueixmPXRoaXMub3JpZ2luO3JldHVybiBsPj0wPyhuPSh0Lm1pbi54LWYueCkqbCxzPSh0Lm1heC54LWYueCkqbCk6KG49KHQubWF4LngtZi54KSpsLHM9KHQubWluLngtZi54KSpsKSxoPj0wPyhyPSh0Lm1pbi55LWYueSkqaCxvPSh0Lm1heC55LWYueSkqaCk6KHI9KHQubWF4LnktZi55KSpoLG89KHQubWluLnktZi55KSpoKSxuPm98fHI+c3x8KChyPm58fGlzTmFOKG4pKSYmKG49ciksKG88c3x8aXNOYU4ocykpJiYocz1vKSx1Pj0wPyhhPSh0Lm1pbi56LWYueikqdSxjPSh0Lm1heC56LWYueikqdSk6KGE9KHQubWF4LnotZi56KSp1LGM9KHQubWluLnotZi56KSp1KSxuPmN8fGE+cyl8fCgoYT5ufHxuIT09bikmJihuPWEpLChjPHN8fHMhPT1zKSYmKHM9YyksczwwKT9udWxsOnRoaXMuYXQobj49MD9uOnMsZSl9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdGhpcy5pbnRlcnNlY3RCb3godCx2ZSkhPT1udWxsfWludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHMscil7cm8uc3ViVmVjdG9ycyhlLHQpLGNzLnN1YlZlY3RvcnMobix0KSxvby5jcm9zc1ZlY3RvcnMocm8sY3MpO2xldCBvPXRoaXMuZGlyZWN0aW9uLmRvdChvbyksYTtpZihvPjApe2lmKHMpcmV0dXJuIG51bGw7YT0xfWVsc2UgaWYobzwwKWE9LTEsbz0tbztlbHNlIHJldHVybiBudWxsO0plLnN1YlZlY3RvcnModGhpcy5vcmlnaW4sdCk7Y29uc3QgYz1hKnRoaXMuZGlyZWN0aW9uLmRvdChjcy5jcm9zc1ZlY3RvcnMoSmUsY3MpKTtpZihjPDApcmV0dXJuIG51bGw7Y29uc3QgbD1hKnRoaXMuZGlyZWN0aW9uLmRvdChyby5jcm9zcyhKZSkpO2lmKGw8MHx8YytsPm8pcmV0dXJuIG51bGw7Y29uc3QgaD0tYSpKZS5kb3Qob28pO3JldHVybiBoPDA/bnVsbDp0aGlzLmF0KGgvbyxyKX1hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMub3JpZ2luLmFwcGx5TWF0cml4NCh0KSx0aGlzLmRpcmVjdGlvbi50cmFuc2Zvcm1EaXJlY3Rpb24odCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQub3JpZ2luLmVxdWFscyh0aGlzLm9yaWdpbikmJnQuZGlyZWN0aW9uLmVxdWFscyh0aGlzLmRpcmVjdGlvbil9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX1jbGFzcyBzdHtjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtzdC5wcm90b3R5cGUuaXNNYXRyaXg0PSEwLHRoaXMuZWxlbWVudHM9WzEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDFdLHQhPT12b2lkIDAmJnRoaXMuc2V0KHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pfXNldCh0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtjb25zdCBnPXRoaXMuZWxlbWVudHM7cmV0dXJuIGdbMF09dCxnWzRdPWUsZ1s4XT1uLGdbMTJdPXMsZ1sxXT1yLGdbNV09byxnWzldPWEsZ1sxM109YyxnWzJdPWwsZ1s2XT1oLGdbMTBdPXUsZ1sxNF09ZixnWzNdPWQsZ1s3XT1wLGdbMTFdPXksZ1sxNV09bSx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDEpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHN0KCkuZnJvbUFycmF5KHRoaXMuZWxlbWVudHMpfWNvcHkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVswXT1uWzBdLGVbMV09blsxXSxlWzJdPW5bMl0sZVszXT1uWzNdLGVbNF09bls0XSxlWzVdPW5bNV0sZVs2XT1uWzZdLGVbN109bls3XSxlWzhdPW5bOF0sZVs5XT1uWzldLGVbMTBdPW5bMTBdLGVbMTFdPW5bMTFdLGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLGVbMTVdPW5bMTVdLHRoaXN9Y29weVBvc2l0aW9uKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7cmV0dXJuIGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLHRoaXN9c2V0RnJvbU1hdHJpeDModCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLnNldChlWzBdLGVbM10sZVs2XSwwLGVbMV0sZVs0XSxlWzddLDAsZVsyXSxlWzVdLGVbOF0sMCwwLDAsMCwxKSx0aGlzfWV4dHJhY3RCYXNpcyh0LGUsbil7cmV0dXJuIHQuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDApLGUuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDEpLG4uc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDIpLHRoaXN9bWFrZUJhc2lzKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodC54LGUueCxuLngsMCx0LnksZS55LG4ueSwwLHQueixlLnosbi56LDAsMCwwLDAsMSksdGhpc31leHRyYWN0Um90YXRpb24odCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cyxzPTEvTG4uc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLHI9MS9Mbi5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCksbz0xL0xuLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gZVswXT1uWzBdKnMsZVsxXT1uWzFdKnMsZVsyXT1uWzJdKnMsZVszXT0wLGVbNF09bls0XSpyLGVbNV09bls1XSpyLGVbNl09bls2XSpyLGVbN109MCxlWzhdPW5bOF0qbyxlWzldPW5bOV0qbyxlWzEwXT1uWzEwXSpvLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21FdWxlcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10Lngscz10Lnkscj10Lnosbz1NYXRoLmNvcyhuKSxhPU1hdGguc2luKG4pLGM9TWF0aC5jb3MocyksbD1NYXRoLnNpbihzKSxoPU1hdGguY29zKHIpLHU9TWF0aC5zaW4ocik7aWYodC5vcmRlcj09PSJYWVoiKXtjb25zdCBmPW8qaCxkPW8qdSxwPWEqaCx5PWEqdTtlWzBdPWMqaCxlWzRdPS1jKnUsZVs4XT1sLGVbMV09ZCtwKmwsZVs1XT1mLXkqbCxlWzldPS1hKmMsZVsyXT15LWYqbCxlWzZdPXArZCpsLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWVhaIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mK3kqYSxlWzRdPXAqYS1kLGVbOF09bypsLGVbMV09byp1LGVbNV09bypoLGVbOV09LWEsZVsyXT1kKmEtcCxlWzZdPXkrZiphLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWlhZIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mLXkqYSxlWzRdPS1vKnUsZVs4XT1wK2QqYSxlWzFdPWQrcCphLGVbNV09bypoLGVbOV09eS1mKmEsZVsyXT0tbypsLGVbNl09YSxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IlpZWCIpe2NvbnN0IGY9bypoLGQ9byp1LHA9YSpoLHk9YSp1O2VbMF09YypoLGVbNF09cCpsLWQsZVs4XT1mKmwreSxlWzFdPWMqdSxlWzVdPXkqbCtmLGVbOV09ZCpsLXAsZVsyXT0tbCxlWzZdPWEqYyxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IllaWCIpe2NvbnN0IGY9bypjLGQ9bypsLHA9YSpjLHk9YSpsO2VbMF09YypoLGVbNF09eS1mKnUsZVs4XT1wKnUrZCxlWzFdPXUsZVs1XT1vKmgsZVs5XT0tYSpoLGVbMl09LWwqaCxlWzZdPWQqdStwLGVbMTBdPWYteSp1fWVsc2UgaWYodC5vcmRlcj09PSJYWlkiKXtjb25zdCBmPW8qYyxkPW8qbCxwPWEqYyx5PWEqbDtlWzBdPWMqaCxlWzRdPS11LGVbOF09bCpoLGVbMV09Zip1K3ksZVs1XT1vKmgsZVs5XT1kKnUtcCxlWzJdPXAqdS1kLGVbNl09YSpoLGVbMTBdPXkqdStmfXJldHVybiBlWzNdPTAsZVs3XT0wLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLmNvbXBvc2UoSnUsdCxZdSl9bG9va0F0KHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuICR0LnN1YlZlY3RvcnModCxlKSwkdC5sZW5ndGhTcSgpPT09MCYmKCR0Lno9MSksJHQubm9ybWFsaXplKCksWWUuY3Jvc3NWZWN0b3JzKG4sJHQpLFllLmxlbmd0aFNxKCk9PT0wJiYoTWF0aC5hYnMobi56KT09PTE/JHQueCs9MWUtNDokdC56Kz0xZS00LCR0Lm5vcm1hbGl6ZSgpLFllLmNyb3NzVmVjdG9ycyhuLCR0KSksWWUubm9ybWFsaXplKCksbHMuY3Jvc3NWZWN0b3JzKCR0LFllKSxzWzBdPVllLngsc1s0XT1scy54LHNbOF09JHQueCxzWzFdPVllLnksc1s1XT1scy55LHNbOV09JHQueSxzWzJdPVllLnosc1s2XT1scy56LHNbMTBdPSR0LnosdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0LHRoaXMpfW11bHRpcGx5TWF0cmljZXModCxlKXtjb25zdCBuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzLHI9dGhpcy5lbGVtZW50cyxvPW5bMF0sYT1uWzRdLGM9bls4XSxsPW5bMTJdLGg9blsxXSx1PW5bNV0sZj1uWzldLGQ9blsxM10scD1uWzJdLHk9bls2XSxtPW5bMTBdLGc9blsxNF0sYj1uWzNdLHc9bls3XSx4PW5bMTFdLE09blsxNV0sQT1zWzBdLF89c1s0XSxTPXNbOF0sRT1zWzEyXSx6PXNbMV0sdj1zWzVdLEM9c1s5XSxQPXNbMTNdLEY9c1syXSxCPXNbNl0sST1zWzEwXSxrPXNbMTRdLEQ9c1szXSxWPXNbN10saj1zWzExXSxkdD1zWzE1XTtyZXR1cm4gclswXT1vKkErYSp6K2MqRitsKkQscls0XT1vKl8rYSp2K2MqQitsKlYscls4XT1vKlMrYSpDK2MqSStsKmosclsxMl09bypFK2EqUCtjKmsrbCpkdCxyWzFdPWgqQSt1KnorZipGK2QqRCxyWzVdPWgqXyt1KnYrZipCK2QqVixyWzldPWgqUyt1KkMrZipJK2QqaixyWzEzXT1oKkUrdSpQK2YqaytkKmR0LHJbMl09cCpBK3kqeittKkYrZypELHJbNl09cCpfK3kqdittKkIrZypWLHJbMTBdPXAqUyt5KkMrbSpJK2cqaixyWzE0XT1wKkUreSpQK20qaytnKmR0LHJbM109YipBK3cqeit4KkYrTSpELHJbN109YipfK3cqdit4KkIrTSpWLHJbMTFdPWIqUyt3KkMreCpJK00qaixyWzE1XT1iKkUrdypQK3gqaytNKmR0LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiBlWzBdKj10LGVbNF0qPXQsZVs4XSo9dCxlWzEyXSo9dCxlWzFdKj10LGVbNV0qPXQsZVs5XSo9dCxlWzEzXSo9dCxlWzJdKj10LGVbNl0qPXQsZVsxMF0qPXQsZVsxNF0qPXQsZVszXSo9dCxlWzddKj10LGVbMTFdKj10LGVbMTVdKj10LHRoaXN9ZGV0ZXJtaW5hbnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFs0XSxzPXRbOF0scj10WzEyXSxvPXRbMV0sYT10WzVdLGM9dFs5XSxsPXRbMTNdLGg9dFsyXSx1PXRbNl0sZj10WzEwXSxkPXRbMTRdLHA9dFszXSx5PXRbN10sbT10WzExXSxnPXRbMTVdO3JldHVybiBwKigrcipjKnUtcypsKnUtciphKmYrbipsKmYrcyphKmQtbipjKmQpK3kqKCtlKmMqZC1lKmwqZityKm8qZi1zKm8qZCtzKmwqaC1yKmMqaCkrbSooK2UqbCp1LWUqYSpkLXIqbyp1K24qbypkK3IqYSpoLW4qbCpoKStnKigtcyphKmgtZSpjKnUrZSphKmYrcypvKnUtbipvKmYrbipjKmgpfXRyYW5zcG9zZSgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cztsZXQgZTtyZXR1cm4gZT10WzFdLHRbMV09dFs0XSx0WzRdPWUsZT10WzJdLHRbMl09dFs4XSx0WzhdPWUsZT10WzZdLHRbNl09dFs5XSx0WzldPWUsZT10WzNdLHRbM109dFsxMl0sdFsxMl09ZSxlPXRbN10sdFs3XT10WzEzXSx0WzEzXT1lLGU9dFsxMV0sdFsxMV09dFsxNF0sdFsxNF09ZSx0aGlzfXNldFBvc2l0aW9uKHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuIHQuaXNWZWN0b3IzPyhzWzEyXT10Lngsc1sxM109dC55LHNbMTRdPXQueik6KHNbMTJdPXQsc1sxM109ZSxzWzE0XT1uKSx0aGlzfWludmVydCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSx1PXRbOV0sZj10WzEwXSxkPXRbMTFdLHA9dFsxMl0seT10WzEzXSxtPXRbMTRdLGc9dFsxNV0sYj11Km0qbC15KmYqbCt5KmMqZC1hKm0qZC11KmMqZythKmYqZyx3PXAqZipsLWgqbSpsLXAqYypkK28qbSpkK2gqYypnLW8qZipnLHg9aCp5KmwtcCp1KmwrcCphKmQtbyp5KmQtaCphKmcrbyp1KmcsTT1wKnUqYy1oKnkqYy1wKmEqZitvKnkqZitoKmEqbS1vKnUqbSxBPWUqYituKncrcyp4K3IqTTtpZihBPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCk7Y29uc3QgXz0xL0E7cmV0dXJuIHRbMF09YipfLHRbMV09KHkqZipyLXUqbSpyLXkqcypkK24qbSpkK3UqcypnLW4qZipnKSpfLHRbMl09KGEqbSpyLXkqYypyK3kqcypsLW4qbSpsLWEqcypnK24qYypnKSpfLHRbM109KHUqYypyLWEqZipyLXUqcypsK24qZipsK2EqcypkLW4qYypkKSpfLHRbNF09dypfLHRbNV09KGgqbSpyLXAqZipyK3AqcypkLWUqbSpkLWgqcypnK2UqZipnKSpfLHRbNl09KHAqYypyLW8qbSpyLXAqcypsK2UqbSpsK28qcypnLWUqYypnKSpfLHRbN109KG8qZipyLWgqYypyK2gqcypsLWUqZipsLW8qcypkK2UqYypkKSpfLHRbOF09eCpfLHRbOV09KHAqdSpyLWgqeSpyLXAqbipkK2UqeSpkK2gqbipnLWUqdSpnKSpfLHRbMTBdPShvKnkqci1wKmEqcitwKm4qbC1lKnkqbC1vKm4qZytlKmEqZykqXyx0WzExXT0oaCphKnItbyp1KnItaCpuKmwrZSp1KmwrbypuKmQtZSphKmQpKl8sdFsxMl09TSpfLHRbMTNdPShoKnkqcy1wKnUqcytwKm4qZi1lKnkqZi1oKm4qbStlKnUqbSkqXyx0WzE0XT0ocCphKnMtbyp5KnMtcCpuKmMrZSp5KmMrbypuKm0tZSphKm0pKl8sdFsxNV09KG8qdSpzLWgqYSpzK2gqbipjLWUqdSpjLW8qbipmK2UqYSpmKSpfLHRoaXN9c2NhbGUodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC54LHM9dC55LHI9dC56O3JldHVybiBlWzBdKj1uLGVbNF0qPXMsZVs4XSo9cixlWzFdKj1uLGVbNV0qPXMsZVs5XSo9cixlWzJdKj1uLGVbNl0qPXMsZVsxMF0qPXIsZVszXSo9bixlWzddKj1zLGVbMTFdKj1yLHRoaXN9Z2V0TWF4U2NhbGVPbkF4aXMoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdKnRbMF0rdFsxXSp0WzFdK3RbMl0qdFsyXSxuPXRbNF0qdFs0XSt0WzVdKnRbNV0rdFs2XSp0WzZdLHM9dFs4XSp0WzhdK3RbOV0qdFs5XSt0WzEwXSp0WzEwXTtyZXR1cm4gTWF0aC5zcXJ0KE1hdGgubWF4KGUsbixzKSl9bWFrZVRyYW5zbGF0aW9uKHQsZSxuKXtyZXR1cm4gdC5pc1ZlY3RvcjM/dGhpcy5zZXQoMSwwLDAsdC54LDAsMSwwLHQueSwwLDAsMSx0LnosMCwwLDAsMSk6dGhpcy5zZXQoMSwwLDAsdCwwLDEsMCxlLDAsMCwxLG4sMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25YKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwwLGUsLW4sMCwwLG4sZSwwLDAsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uWSh0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsMCxuLDAsMCwxLDAsMCwtbiwwLGUsMCwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbloodCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldChlLC1uLDAsMCxuLGUsMCwwLDAsMCwxLDAsMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25BeGlzKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9MS1uLG89dC54LGE9dC55LGM9dC56LGw9cipvLGg9ciphO3JldHVybiB0aGlzLnNldChsKm8rbixsKmEtcypjLGwqYytzKmEsMCxsKmErcypjLGgqYStuLGgqYy1zKm8sMCxsKmMtcyphLGgqYytzKm8scipjKmMrbiwwLDAsMCwwLDEpLHRoaXN9bWFrZVNjYWxlKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodCwwLDAsMCwwLGUsMCwwLDAsMCxuLDAsMCwwLDAsMSksdGhpc31tYWtlU2hlYXIodCxlLG4scyxyLG8pe3JldHVybiB0aGlzLnNldCgxLG4sciwwLHQsMSxvLDAsZSxzLDEsMCwwLDAsMCwxKSx0aGlzfWNvbXBvc2UodCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cyxyPWUuX3gsbz1lLl95LGE9ZS5feixjPWUuX3csbD1yK3IsaD1vK28sdT1hK2EsZj1yKmwsZD1yKmgscD1yKnUseT1vKmgsbT1vKnUsZz1hKnUsYj1jKmwsdz1jKmgseD1jKnUsTT1uLngsQT1uLnksXz1uLno7cmV0dXJuIHNbMF09KDEtKHkrZykpKk0sc1sxXT0oZCt4KSpNLHNbMl09KHAtdykqTSxzWzNdPTAsc1s0XT0oZC14KSpBLHNbNV09KDEtKGYrZykpKkEsc1s2XT0obStiKSpBLHNbN109MCxzWzhdPShwK3cpKl8sc1s5XT0obS1iKSpfLHNbMTBdPSgxLShmK3kpKSpfLHNbMTFdPTAsc1sxMl09dC54LHNbMTNdPXQueSxzWzE0XT10Lnosc1sxNV09MSx0aGlzfWRlY29tcG9zZSh0LGUsbil7Y29uc3Qgcz10aGlzLmVsZW1lbnRzO2xldCByPUxuLnNldChzWzBdLHNbMV0sc1syXSkubGVuZ3RoKCk7Y29uc3Qgbz1Mbi5zZXQoc1s0XSxzWzVdLHNbNl0pLmxlbmd0aCgpLGE9TG4uc2V0KHNbOF0sc1s5XSxzWzEwXSkubGVuZ3RoKCk7dGhpcy5kZXRlcm1pbmFudCgpPDAmJihyPS1yKSx0Lng9c1sxMl0sdC55PXNbMTNdLHQuej1zWzE0XSxsZS5jb3B5KHRoaXMpO2NvbnN0IGw9MS9yLGg9MS9vLHU9MS9hO3JldHVybiBsZS5lbGVtZW50c1swXSo9bCxsZS5lbGVtZW50c1sxXSo9bCxsZS5lbGVtZW50c1syXSo9bCxsZS5lbGVtZW50c1s0XSo9aCxsZS5lbGVtZW50c1s1XSo9aCxsZS5lbGVtZW50c1s2XSo9aCxsZS5lbGVtZW50c1s4XSo9dSxsZS5lbGVtZW50c1s5XSo9dSxsZS5lbGVtZW50c1sxMF0qPXUsZS5zZXRGcm9tUm90YXRpb25NYXRyaXgobGUpLG4ueD1yLG4ueT1vLG4uej1hLHRoaXN9bWFrZVBlcnNwZWN0aXZlKHQsZSxuLHMscixvLGE9MmUzKXtjb25zdCBjPXRoaXMuZWxlbWVudHMsbD0yKnIvKGUtdCksaD0yKnIvKG4tcyksdT0oZSt0KS8oZS10KSxmPShuK3MpLyhuLXMpO2xldCBkLHA7aWYoYT09PTJlMylkPS0obytyKS8oby1yKSxwPS0yKm8qci8oby1yKTtlbHNlIGlmKGE9PT0yMDAxKWQ9LW8vKG8tcikscD0tbypyLyhvLXIpO2Vsc2UgdGhyb3cgbmV3IEVycm9yKCJUSFJFRS5NYXRyaXg0Lm1ha2VQZXJzcGVjdGl2ZSgpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPWwsY1s0XT0wLGNbOF09dSxjWzEyXT0wLGNbMV09MCxjWzVdPWgsY1s5XT1mLGNbMTNdPTAsY1syXT0wLGNbNl09MCxjWzEwXT1kLGNbMTRdPXAsY1szXT0wLGNbN109MCxjWzExXT0tMSxjWzE1XT0wLHRoaXN9bWFrZU9ydGhvZ3JhcGhpYyh0LGUsbixzLHIsbyxhPTJlMyl7Y29uc3QgYz10aGlzLmVsZW1lbnRzLGw9MS8oZS10KSxoPTEvKG4tcyksdT0xLyhvLXIpLGY9KGUrdCkqbCxkPShuK3MpKmg7bGV0IHAseTtpZihhPT09MmUzKXA9KG8rcikqdSx5PS0yKnU7ZWxzZSBpZihhPT09MjAwMSlwPXIqdSx5PS0xKnU7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIlRIUkVFLk1hdHJpeDQubWFrZU9ydGhvZ3JhcGhpYygpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPTIqbCxjWzRdPTAsY1s4XT0wLGNbMTJdPS1mLGNbMV09MCxjWzVdPTIqaCxjWzldPTAsY1sxM109LWQsY1syXT0wLGNbNl09MCxjWzEwXT15LGNbMTRdPS1wLGNbM109MCxjWzddPTAsY1sxMV09MCxjWzE1XT0xLHRoaXN9ZXF1YWxzKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7Zm9yKGxldCBzPTA7czwxNjtzKyspaWYoZVtzXSE9PW5bc10pcmV0dXJuITE7cmV0dXJuITB9ZnJvbUFycmF5KHQsZT0wKXtmb3IobGV0IG49MDtuPDE2O24rKyl0aGlzLmVsZW1lbnRzW25dPXRbbitlXTtyZXR1cm4gdGhpc310b0FycmF5KHQ9W10sZT0wKXtjb25zdCBuPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbZV09blswXSx0W2UrMV09blsxXSx0W2UrMl09blsyXSx0W2UrM109blszXSx0W2UrNF09bls0XSx0W2UrNV09bls1XSx0W2UrNl09bls2XSx0W2UrN109bls3XSx0W2UrOF09bls4XSx0W2UrOV09bls5XSx0W2UrMTBdPW5bMTBdLHRbZSsxMV09blsxMV0sdFtlKzEyXT1uWzEyXSx0W2UrMTNdPW5bMTNdLHRbZSsxNF09blsxNF0sdFtlKzE1XT1uWzE1XSx0fX1jb25zdCBMbj1uZXcgVCxsZT1uZXcgc3QsSnU9bmV3IFQoMCwwLDApLFl1PW5ldyBUKDEsMSwxKSxZZT1uZXcgVCxscz1uZXcgVCwkdD1uZXcgVCx3Yz1uZXcgc3QsYmM9bmV3IHlpO2NsYXNzIHhpe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9eGkuREVGQVVMVF9PUkRFUil7dGhpcy5pc0V1bGVyPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXN9Z2V0IHgoKXtyZXR1cm4gdGhpcy5feH1zZXQgeCh0KXt0aGlzLl94PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB5KCl7cmV0dXJuIHRoaXMuX3l9c2V0IHkodCl7dGhpcy5feT10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeigpe3JldHVybiB0aGlzLl96fXNldCB6KHQpe3RoaXMuX3o9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IG9yZGVyKCl7cmV0dXJuIHRoaXMuX29yZGVyfXNldCBvcmRlcih0KXt0aGlzLl9vcmRlcj10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scz10aGlzLl9vcmRlcil7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXMsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5feCx0aGlzLl95LHRoaXMuX3osdGhpcy5fb3JkZXIpfWNvcHkodCl7cmV0dXJuIHRoaXMuX3g9dC5feCx0aGlzLl95PXQuX3ksdGhpcy5fej10Ll96LHRoaXMuX29yZGVyPXQuX29yZGVyLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0LGU9dGhpcy5fb3JkZXIsbj0hMCl7Y29uc3Qgcz10LmVsZW1lbnRzLHI9c1swXSxvPXNbNF0sYT1zWzhdLGM9c1sxXSxsPXNbNV0saD1zWzldLHU9c1syXSxmPXNbNl0sZD1zWzEwXTtzd2l0Y2goZSl7Y2FzZSJYWVoiOnRoaXMuX3k9TWF0aC5hc2luKFooYSwtMSwxKSksTWF0aC5hYnMoYSk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMigtaCxkKSx0aGlzLl96PU1hdGguYXRhbjIoLW8scikpOih0aGlzLl94PU1hdGguYXRhbjIoZixsKSx0aGlzLl96PTApO2JyZWFrO2Nhc2UiWVhaIjp0aGlzLl94PU1hdGguYXNpbigtWihoLC0xLDEpKSxNYXRoLmFicyhoKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKGEsZCksdGhpcy5fej1NYXRoLmF0YW4yKGMsbCkpOih0aGlzLl95PU1hdGguYXRhbjIoLXUsciksdGhpcy5fej0wKTticmVhaztjYXNlIlpYWSI6dGhpcy5feD1NYXRoLmFzaW4oWihmLC0xLDEpKSxNYXRoLmFicyhmKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKC11LGQpLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxsKSk6KHRoaXMuX3k9MCx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3k9TWF0aC5hc2luKC1aKHUsLTEsMSkpLE1hdGguYWJzKHUpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoZixkKSx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk6KHRoaXMuX3g9MCx0aGlzLl96PU1hdGguYXRhbjIoLW8sbCkpO2JyZWFrO2Nhc2UiWVpYIjp0aGlzLl96PU1hdGguYXNpbihaKGMsLTEsMSkpLE1hdGguYWJzKGMpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoLWgsbCksdGhpcy5feT1NYXRoLmF0YW4yKC11LHIpKToodGhpcy5feD0wLHRoaXMuX3k9TWF0aC5hdGFuMihhLGQpKTticmVhaztjYXNlIlhaWSI6dGhpcy5fej1NYXRoLmFzaW4oLVoobywtMSwxKSksTWF0aC5hYnMobyk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMihmLGwpLHRoaXMuX3k9TWF0aC5hdGFuMihhLHIpKToodGhpcy5feD1NYXRoLmF0YW4yKC1oLGQpLHRoaXMuX3k9MCk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkV1bGVyOiAuc2V0RnJvbVJvdGF0aW9uTWF0cml4KCkgZW5jb3VudGVyZWQgYW4gdW5rbm93biBvcmRlcjogIitlKX1yZXR1cm4gdGhpcy5fb3JkZXI9ZSxuPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21RdWF0ZXJuaW9uKHQsZSxuKXtyZXR1cm4gd2MubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCksdGhpcy5zZXRGcm9tUm90YXRpb25NYXRyaXgod2MsZSxuKX1zZXRGcm9tVmVjdG9yMyh0LGU9dGhpcy5fb3JkZXIpe3JldHVybiB0aGlzLnNldCh0LngsdC55LHQueixlKX1yZW9yZGVyKHQpe3JldHVybiBiYy5zZXRGcm9tRXVsZXIodGhpcyksdGhpcy5zZXRGcm9tUXVhdGVybmlvbihiYyx0KX1lcXVhbHModCl7cmV0dXJuIHQuX3g9PT10aGlzLl94JiZ0Ll95PT09dGhpcy5feSYmdC5fej09PXRoaXMuX3omJnQuX29yZGVyPT09dGhpcy5fb3JkZXJ9ZnJvbUFycmF5KHQpe3JldHVybiB0aGlzLl94PXRbMF0sdGhpcy5feT10WzFdLHRoaXMuX3o9dFsyXSx0WzNdIT09dm9pZCAwJiYodGhpcy5fb3JkZXI9dFszXSksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy5feCx0W2UrMV09dGhpcy5feSx0W2UrMl09dGhpcy5feix0W2UrM109dGhpcy5fb3JkZXIsdH1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX29yZGVyfX14aS5ERUZBVUxUX09SREVSPSJYWVoiO2NsYXNzIGp1e2NvbnN0cnVjdG9yKCl7dGhpcy5tYXNrPTF9c2V0KHQpe3RoaXMubWFzaz0oMTw8dHwwKT4+PjB9ZW5hYmxlKHQpe3RoaXMubWFza3w9MTw8dHwwfWVuYWJsZUFsbCgpe3RoaXMubWFzaz0tMX10b2dnbGUodCl7dGhpcy5tYXNrXj0xPDx0fDB9ZGlzYWJsZSh0KXt0aGlzLm1hc2smPX4oMTw8dHwwKX1kaXNhYmxlQWxsKCl7dGhpcy5tYXNrPTB9dGVzdCh0KXtyZXR1cm4odGhpcy5tYXNrJnQubWFzaykhPT0wfWlzRW5hYmxlZCh0KXtyZXR1cm4odGhpcy5tYXNrJigxPDx0fDApKSE9PTB9fWxldCBRdT0wO2NvbnN0IE1jPW5ldyBULE9uPW5ldyB5aSx6ZT1uZXcgc3QsaHM9bmV3IFQsd2k9bmV3IFQsS3U9bmV3IFQsdGY9bmV3IHlpLEFjPW5ldyBUKDEsMCwwKSxfYz1uZXcgVCgwLDEsMCksU2M9bmV3IFQoMCwwLDEpLHZjPXt0eXBlOiJhZGRlZCJ9LGVmPXt0eXBlOiJyZW1vdmVkIn0sRG49e3R5cGU6ImNoaWxkYWRkZWQiLGNoaWxkOm51bGx9LGNvPXt0eXBlOiJjaGlsZHJlbW92ZWQiLGNoaWxkOm51bGx9O2NsYXNzIFRlIGV4dGVuZHMgaXN7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNPYmplY3QzRD0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpRdSsrfSksdGhpcy51dWlkPUJuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iT2JqZWN0M0QiLHRoaXMucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbj1bXSx0aGlzLnVwPVRlLkRFRkFVTFRfVVAuY2xvbmUoKTtjb25zdCB0PW5ldyBULGU9bmV3IHhpLG49bmV3IHlpLHM9bmV3IFQoMSwxLDEpO2Z1bmN0aW9uIHIoKXtuLnNldEZyb21FdWxlcihlLCExKX1mdW5jdGlvbiBvKCl7ZS5zZXRGcm9tUXVhdGVybmlvbihuLHZvaWQgMCwhMSl9ZS5fb25DaGFuZ2Uociksbi5fb25DaGFuZ2UobyksT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcyx7cG9zaXRpb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOnR9LHJvdGF0aW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTplfSxxdWF0ZXJuaW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTpufSxzY2FsZTp7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITAsdmFsdWU6c30sbW9kZWxWaWV3TWF0cml4Ont2YWx1ZTpuZXcgc3R9LG5vcm1hbE1hdHJpeDp7dmFsdWU6bmV3IGdlfX0pLHRoaXMubWF0cml4PW5ldyBzdCx0aGlzLm1hdHJpeFdvcmxkPW5ldyBzdCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9VGUuREVGQVVMVF9NQVRSSVhfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9VGUuREVGQVVMVF9NQVRSSVhfV09STERfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSExLHRoaXMubGF5ZXJzPW5ldyBqdSx0aGlzLnZpc2libGU9ITAsdGhpcy5jYXN0U2hhZG93PSExLHRoaXMucmVjZWl2ZVNoYWRvdz0hMSx0aGlzLmZydXN0dW1DdWxsZWQ9ITAsdGhpcy5yZW5kZXJPcmRlcj0wLHRoaXMuYW5pbWF0aW9ucz1bXSx0aGlzLmN1c3RvbURlcHRoTWF0ZXJpYWw9dm9pZCAwLHRoaXMuY3VzdG9tRGlzdGFuY2VNYXRlcmlhbD12b2lkIDAsdGhpcy51c2VyRGF0YT17fX1vbkJlZm9yZVNoYWRvdygpe31vbkFmdGVyU2hhZG93KCl7fW9uQmVmb3JlUmVuZGVyKCl7fW9uQWZ0ZXJSZW5kZXIoKXt9YXBwbHlNYXRyaXg0KHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSx0aGlzLm1hdHJpeC5wcmVtdWx0aXBseSh0KSx0aGlzLm1hdHJpeC5kZWNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSl9YXBwbHlRdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkodCksdGhpc31zZXRSb3RhdGlvbkZyb21BeGlzQW5nbGUodCxlKXt0aGlzLnF1YXRlcm5pb24uc2V0RnJvbUF4aXNBbmdsZSh0LGUpfXNldFJvdGF0aW9uRnJvbUV1bGVyKHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tRXVsZXIodCwhMCl9c2V0Um90YXRpb25Gcm9tTWF0cml4KHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgodCl9c2V0Um90YXRpb25Gcm9tUXVhdGVybmlvbih0KXt0aGlzLnF1YXRlcm5pb24uY29weSh0KX1yb3RhdGVPbkF4aXModCxlKXtyZXR1cm4gT24uc2V0RnJvbUF4aXNBbmdsZSh0LGUpLHRoaXMucXVhdGVybmlvbi5tdWx0aXBseShPbiksdGhpc31yb3RhdGVPbldvcmxkQXhpcyh0LGUpe3JldHVybiBPbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KE9uKSx0aGlzfXJvdGF0ZVgodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEFjLHQpfXJvdGF0ZVkodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKF9jLHQpfXJvdGF0ZVoodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKFNjLHQpfXRyYW5zbGF0ZU9uQXhpcyh0LGUpe3JldHVybiBNYy5jb3B5KHQpLmFwcGx5UXVhdGVybmlvbih0aGlzLnF1YXRlcm5pb24pLHRoaXMucG9zaXRpb24uYWRkKE1jLm11bHRpcGx5U2NhbGFyKGUpKSx0aGlzfXRyYW5zbGF0ZVgodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEFjLHQpfXRyYW5zbGF0ZVkodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKF9jLHQpfXRyYW5zbGF0ZVoodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKFNjLHQpfWxvY2FsVG9Xb3JsZCh0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdC5hcHBseU1hdHJpeDQodGhpcy5tYXRyaXhXb3JsZCl9d29ybGRUb0xvY2FsKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0LmFwcGx5TWF0cml4NCh6ZS5jb3B5KHRoaXMubWF0cml4V29ybGQpLmludmVydCgpKX1sb29rQXQodCxlLG4pe3QuaXNWZWN0b3IzP2hzLmNvcHkodCk6aHMuc2V0KHQsZSxuKTtjb25zdCBzPXRoaXMucGFyZW50O3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHdpLnNldEZyb21NYXRyaXhQb3NpdGlvbih0aGlzLm1hdHJpeFdvcmxkKSx0aGlzLmlzQ2FtZXJhfHx0aGlzLmlzTGlnaHQ/emUubG9va0F0KHdpLGhzLHRoaXMudXApOnplLmxvb2tBdChocyx3aSx0aGlzLnVwKSx0aGlzLnF1YXRlcm5pb24uc2V0RnJvbVJvdGF0aW9uTWF0cml4KHplKSxzJiYoemUuZXh0cmFjdFJvdGF0aW9uKHMubWF0cml4V29ybGQpLE9uLnNldEZyb21Sb3RhdGlvbk1hdHJpeCh6ZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KE9uLmludmVydCgpKSl9YWRkKHQpe2lmKGFyZ3VtZW50cy5sZW5ndGg+MSl7Zm9yKGxldCBlPTA7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl0aGlzLmFkZChhcmd1bWVudHNbZV0pO3JldHVybiB0aGlzfXJldHVybiB0PT09dGhpcz8oY29uc29sZS5lcnJvcigiVEhSRUUuT2JqZWN0M0QuYWRkOiBvYmplY3QgY2FuJ3QgYmUgYWRkZWQgYXMgYSBjaGlsZCBvZiBpdHNlbGYuIix0KSx0aGlzKToodCYmdC5pc09iamVjdDNEPyh0LnJlbW92ZUZyb21QYXJlbnQoKSx0LnBhcmVudD10aGlzLHRoaXMuY2hpbGRyZW4ucHVzaCh0KSx0LmRpc3BhdGNoRXZlbnQodmMpLERuLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KERuKSxEbi5jaGlsZD1udWxsKTpjb25zb2xlLmVycm9yKCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBub3QgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuT2JqZWN0M0QuIix0KSx0aGlzKX1yZW1vdmUodCl7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IobGV0IG49MDtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXRoaXMucmVtb3ZlKGFyZ3VtZW50c1tuXSk7cmV0dXJuIHRoaXN9Y29uc3QgZT10aGlzLmNoaWxkcmVuLmluZGV4T2YodCk7cmV0dXJuIGUhPT0tMSYmKHQucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbi5zcGxpY2UoZSwxKSx0LmRpc3BhdGNoRXZlbnQoZWYpLGNvLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KGNvKSxjby5jaGlsZD1udWxsKSx0aGlzfXJlbW92ZUZyb21QYXJlbnQoKXtjb25zdCB0PXRoaXMucGFyZW50O3JldHVybiB0IT09bnVsbCYmdC5yZW1vdmUodGhpcyksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLnJlbW92ZSguLi50aGlzLmNoaWxkcmVuKX1hdHRhY2godCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHplLmNvcHkodGhpcy5tYXRyaXhXb3JsZCkuaW52ZXJ0KCksdC5wYXJlbnQhPT1udWxsJiYodC5wYXJlbnQudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHplLm11bHRpcGx5KHQucGFyZW50Lm1hdHJpeFdvcmxkKSksdC5hcHBseU1hdHJpeDQoemUpLHQucmVtb3ZlRnJvbVBhcmVudCgpLHQucGFyZW50PXRoaXMsdGhpcy5jaGlsZHJlbi5wdXNoKHQpLHQudXBkYXRlV29ybGRNYXRyaXgoITEsITApLHQuZGlzcGF0Y2hFdmVudCh2YyksRG4uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQoRG4pLERuLmNoaWxkPW51bGwsdGhpc31nZXRPYmplY3RCeUlkKHQpe3JldHVybiB0aGlzLmdldE9iamVjdEJ5UHJvcGVydHkoImlkIix0KX1nZXRPYmplY3RCeU5hbWUodCl7cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlQcm9wZXJ0eSgibmFtZSIsdCl9Z2V0T2JqZWN0QnlQcm9wZXJ0eSh0LGUpe2lmKHRoaXNbdF09PT1lKXJldHVybiB0aGlzO2ZvcihsZXQgbj0wLHM9dGhpcy5jaGlsZHJlbi5sZW5ndGg7bjxzO24rKyl7Y29uc3Qgbz10aGlzLmNoaWxkcmVuW25dLmdldE9iamVjdEJ5UHJvcGVydHkodCxlKTtpZihvIT09dm9pZCAwKXJldHVybiBvfX1nZXRPYmplY3RzQnlQcm9wZXJ0eSh0LGUsbj1bXSl7dGhpc1t0XT09PWUmJm4ucHVzaCh0aGlzKTtjb25zdCBzPXRoaXMuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXNbcl0uZ2V0T2JqZWN0c0J5UHJvcGVydHkodCxlLG4pO3JldHVybiBufWdldFdvcmxkUG9zaXRpb24odCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHQuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKHRoaXMubWF0cml4V29ybGQpfWdldFdvcmxkUXVhdGVybmlvbih0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdGhpcy5tYXRyaXhXb3JsZC5kZWNvbXBvc2Uod2ksdCxLdSksdH1nZXRXb3JsZFNjYWxlKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZSh3aSx0Zix0KSx0fWdldFdvcmxkRGlyZWN0aW9uKHQpe3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpO2NvbnN0IGU9dGhpcy5tYXRyaXhXb3JsZC5lbGVtZW50cztyZXR1cm4gdC5zZXQoZVs4XSxlWzldLGVbMTBdKS5ub3JtYWxpemUoKX1yYXljYXN0KCl7fXRyYXZlcnNlKHQpe3QodGhpcyk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnRyYXZlcnNlKHQpfXRyYXZlcnNlVmlzaWJsZSh0KXtpZih0aGlzLnZpc2libGU9PT0hMSlyZXR1cm47dCh0aGlzKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udHJhdmVyc2VWaXNpYmxlKHQpfXRyYXZlcnNlQW5jZXN0b3JzKHQpe2NvbnN0IGU9dGhpcy5wYXJlbnQ7ZSE9PW51bGwmJih0KGUpLGUudHJhdmVyc2VBbmNlc3RvcnModCkpfXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LmNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSksdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSEwfXVwZGF0ZU1hdHJpeFdvcmxkKHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSwodGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlfHx0KSYmKHRoaXMubWF0cml4V29ybGRBdXRvVXBkYXRlPT09ITAmJih0aGlzLnBhcmVudD09PW51bGw/dGhpcy5tYXRyaXhXb3JsZC5jb3B5KHRoaXMubWF0cml4KTp0aGlzLm1hdHJpeFdvcmxkLm11bHRpcGx5TWF0cmljZXModGhpcy5wYXJlbnQubWF0cml4V29ybGQsdGhpcy5tYXRyaXgpKSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITEsdD0hMCk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnVwZGF0ZU1hdHJpeFdvcmxkKHQpfXVwZGF0ZVdvcmxkTWF0cml4KHQsZSl7Y29uc3Qgbj10aGlzLnBhcmVudDtpZih0PT09ITAmJm4hPT1udWxsJiZuLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeEF1dG9VcGRhdGUmJnRoaXMudXBkYXRlTWF0cml4KCksdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9PT0hMCYmKHRoaXMucGFyZW50PT09bnVsbD90aGlzLm1hdHJpeFdvcmxkLmNvcHkodGhpcy5tYXRyaXgpOnRoaXMubWF0cml4V29ybGQubXVsdGlwbHlNYXRyaWNlcyh0aGlzLnBhcmVudC5tYXRyaXhXb3JsZCx0aGlzLm1hdHJpeCkpLGU9PT0hMCl7Y29uc3Qgcz10aGlzLmNoaWxkcmVuO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLnVwZGF0ZVdvcmxkTWF0cml4KCExLCEwKX19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciLG49e307ZSYmKHQ9e2dlb21ldHJpZXM6e30sbWF0ZXJpYWxzOnt9LHRleHR1cmVzOnt9LGltYWdlczp7fSxzaGFwZXM6e30sc2tlbGV0b25zOnt9LGFuaW1hdGlvbnM6e30sbm9kZXM6e319LG4ubWV0YWRhdGE9e3ZlcnNpb246NC42LHR5cGU6Ik9iamVjdCIsZ2VuZXJhdG9yOiJPYmplY3QzRC50b0pTT04ifSk7Y29uc3Qgcz17fTtzLnV1aWQ9dGhpcy51dWlkLHMudHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJihzLm5hbWU9dGhpcy5uYW1lKSx0aGlzLmNhc3RTaGFkb3c9PT0hMCYmKHMuY2FzdFNoYWRvdz0hMCksdGhpcy5yZWNlaXZlU2hhZG93PT09ITAmJihzLnJlY2VpdmVTaGFkb3c9ITApLHRoaXMudmlzaWJsZT09PSExJiYocy52aXNpYmxlPSExKSx0aGlzLmZydXN0dW1DdWxsZWQ9PT0hMSYmKHMuZnJ1c3R1bUN1bGxlZD0hMSksdGhpcy5yZW5kZXJPcmRlciE9PTAmJihzLnJlbmRlck9yZGVyPXRoaXMucmVuZGVyT3JkZXIpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYocy51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSxzLmxheWVycz10aGlzLmxheWVycy5tYXNrLHMubWF0cml4PXRoaXMubWF0cml4LnRvQXJyYXkoKSxzLnVwPXRoaXMudXAudG9BcnJheSgpLHRoaXMubWF0cml4QXV0b1VwZGF0ZT09PSExJiYocy5tYXRyaXhBdXRvVXBkYXRlPSExKSx0aGlzLmlzSW5zdGFuY2VkTWVzaCYmKHMudHlwZT0iSW5zdGFuY2VkTWVzaCIscy5jb3VudD10aGlzLmNvdW50LHMuaW5zdGFuY2VNYXRyaXg9dGhpcy5pbnN0YW5jZU1hdHJpeC50b0pTT04oKSx0aGlzLmluc3RhbmNlQ29sb3IhPT1udWxsJiYocy5pbnN0YW5jZUNvbG9yPXRoaXMuaW5zdGFuY2VDb2xvci50b0pTT04oKSkpLHRoaXMuaXNCYXRjaGVkTWVzaCYmKHMudHlwZT0iQmF0Y2hlZE1lc2giLHMucGVyT2JqZWN0RnJ1c3R1bUN1bGxlZD10aGlzLnBlck9iamVjdEZydXN0dW1DdWxsZWQscy5zb3J0T2JqZWN0cz10aGlzLnNvcnRPYmplY3RzLHMuZHJhd1Jhbmdlcz10aGlzLl9kcmF3UmFuZ2VzLHMucmVzZXJ2ZWRSYW5nZXM9dGhpcy5fcmVzZXJ2ZWRSYW5nZXMscy5nZW9tZXRyeUluZm89dGhpcy5fZ2VvbWV0cnlJbmZvLm1hcChhPT5HZShGdCh7fSxhKSx7Ym91bmRpbmdCb3g6YS5ib3VuZGluZ0JveD97bWluOmEuYm91bmRpbmdCb3gubWluLnRvQXJyYXkoKSxtYXg6YS5ib3VuZGluZ0JveC5tYXgudG9BcnJheSgpfTp2b2lkIDAsYm91bmRpbmdTcGhlcmU6YS5ib3VuZGluZ1NwaGVyZT97cmFkaXVzOmEuYm91bmRpbmdTcGhlcmUucmFkaXVzLGNlbnRlcjphLmJvdW5kaW5nU3BoZXJlLmNlbnRlci50b0FycmF5KCl9OnZvaWQgMH0pKSxzLmluc3RhbmNlSW5mbz10aGlzLl9pbnN0YW5jZUluZm8ubWFwKGE9PkZ0KHt9LGEpKSxzLmF2YWlsYWJsZUluc3RhbmNlSWRzPXRoaXMuX2F2YWlsYWJsZUluc3RhbmNlSWRzLnNsaWNlKCkscy5hdmFpbGFibGVHZW9tZXRyeUlkcz10aGlzLl9hdmFpbGFibGVHZW9tZXRyeUlkcy5zbGljZSgpLHMubmV4dEluZGV4U3RhcnQ9dGhpcy5fbmV4dEluZGV4U3RhcnQscy5uZXh0VmVydGV4U3RhcnQ9dGhpcy5fbmV4dFZlcnRleFN0YXJ0LHMuZ2VvbWV0cnlDb3VudD10aGlzLl9nZW9tZXRyeUNvdW50LHMubWF4SW5zdGFuY2VDb3VudD10aGlzLl9tYXhJbnN0YW5jZUNvdW50LHMubWF4VmVydGV4Q291bnQ9dGhpcy5fbWF4VmVydGV4Q291bnQscy5tYXhJbmRleENvdW50PXRoaXMuX21heEluZGV4Q291bnQscy5nZW9tZXRyeUluaXRpYWxpemVkPXRoaXMuX2dlb21ldHJ5SW5pdGlhbGl6ZWQscy5tYXRyaWNlc1RleHR1cmU9dGhpcy5fbWF0cmljZXNUZXh0dXJlLnRvSlNPTih0KSxzLmluZGlyZWN0VGV4dHVyZT10aGlzLl9pbmRpcmVjdFRleHR1cmUudG9KU09OKHQpLHRoaXMuX2NvbG9yc1RleHR1cmUhPT1udWxsJiYocy5jb2xvcnNUZXh0dXJlPXRoaXMuX2NvbG9yc1RleHR1cmUudG9KU09OKHQpKSx0aGlzLmJvdW5kaW5nU3BoZXJlIT09bnVsbCYmKHMuYm91bmRpbmdTcGhlcmU9e2NlbnRlcjp0aGlzLmJvdW5kaW5nU3BoZXJlLmNlbnRlci50b0FycmF5KCkscmFkaXVzOnRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzfSksdGhpcy5ib3VuZGluZ0JveCE9PW51bGwmJihzLmJvdW5kaW5nQm94PXttaW46dGhpcy5ib3VuZGluZ0JveC5taW4udG9BcnJheSgpLG1heDp0aGlzLmJvdW5kaW5nQm94Lm1heC50b0FycmF5KCl9KSk7ZnVuY3Rpb24gcihhLGMpe3JldHVybiBhW2MudXVpZF09PT12b2lkIDAmJihhW2MudXVpZF09Yy50b0pTT04odCkpLGMudXVpZH1pZih0aGlzLmlzU2NlbmUpdGhpcy5iYWNrZ3JvdW5kJiYodGhpcy5iYWNrZ3JvdW5kLmlzQ29sb3I/cy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04oKTp0aGlzLmJhY2tncm91bmQuaXNUZXh0dXJlJiYocy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04odCkudXVpZCkpLHRoaXMuZW52aXJvbm1lbnQmJnRoaXMuZW52aXJvbm1lbnQuaXNUZXh0dXJlJiZ0aGlzLmVudmlyb25tZW50LmlzUmVuZGVyVGFyZ2V0VGV4dHVyZSE9PSEwJiYocy5lbnZpcm9ubWVudD10aGlzLmVudmlyb25tZW50LnRvSlNPTih0KS51dWlkKTtlbHNlIGlmKHRoaXMuaXNNZXNofHx0aGlzLmlzTGluZXx8dGhpcy5pc1BvaW50cyl7cy5nZW9tZXRyeT1yKHQuZ2VvbWV0cmllcyx0aGlzLmdlb21ldHJ5KTtjb25zdCBhPXRoaXMuZ2VvbWV0cnkucGFyYW1ldGVycztpZihhIT09dm9pZCAwJiZhLnNoYXBlcyE9PXZvaWQgMCl7Y29uc3QgYz1hLnNoYXBlcztpZihBcnJheS5pc0FycmF5KGMpKWZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyl7Y29uc3QgdT1jW2xdO3IodC5zaGFwZXMsdSl9ZWxzZSByKHQuc2hhcGVzLGMpfX1pZih0aGlzLmlzU2tpbm5lZE1lc2gmJihzLmJpbmRNb2RlPXRoaXMuYmluZE1vZGUscy5iaW5kTWF0cml4PXRoaXMuYmluZE1hdHJpeC50b0FycmF5KCksdGhpcy5za2VsZXRvbiE9PXZvaWQgMCYmKHIodC5za2VsZXRvbnMsdGhpcy5za2VsZXRvbikscy5za2VsZXRvbj10aGlzLnNrZWxldG9uLnV1aWQpKSx0aGlzLm1hdGVyaWFsIT09dm9pZCAwKWlmKEFycmF5LmlzQXJyYXkodGhpcy5tYXRlcmlhbCkpe2NvbnN0IGE9W107Zm9yKGxldCBjPTAsbD10aGlzLm1hdGVyaWFsLmxlbmd0aDtjPGw7YysrKWEucHVzaChyKHQubWF0ZXJpYWxzLHRoaXMubWF0ZXJpYWxbY10pKTtzLm1hdGVyaWFsPWF9ZWxzZSBzLm1hdGVyaWFsPXIodC5tYXRlcmlhbHMsdGhpcy5tYXRlcmlhbCk7aWYodGhpcy5jaGlsZHJlbi5sZW5ndGg+MCl7cy5jaGlsZHJlbj1bXTtmb3IobGV0IGE9MDthPHRoaXMuY2hpbGRyZW4ubGVuZ3RoO2ErKylzLmNoaWxkcmVuLnB1c2godGhpcy5jaGlsZHJlblthXS50b0pTT04odCkub2JqZWN0KX1pZih0aGlzLmFuaW1hdGlvbnMubGVuZ3RoPjApe3MuYW5pbWF0aW9ucz1bXTtmb3IobGV0IGE9MDthPHRoaXMuYW5pbWF0aW9ucy5sZW5ndGg7YSsrKXtjb25zdCBjPXRoaXMuYW5pbWF0aW9uc1thXTtzLmFuaW1hdGlvbnMucHVzaChyKHQuYW5pbWF0aW9ucyxjKSl9fWlmKGUpe2NvbnN0IGE9byh0Lmdlb21ldHJpZXMpLGM9byh0Lm1hdGVyaWFscyksbD1vKHQudGV4dHVyZXMpLGg9byh0LmltYWdlcyksdT1vKHQuc2hhcGVzKSxmPW8odC5za2VsZXRvbnMpLGQ9byh0LmFuaW1hdGlvbnMpLHA9byh0Lm5vZGVzKTthLmxlbmd0aD4wJiYobi5nZW9tZXRyaWVzPWEpLGMubGVuZ3RoPjAmJihuLm1hdGVyaWFscz1jKSxsLmxlbmd0aD4wJiYobi50ZXh0dXJlcz1sKSxoLmxlbmd0aD4wJiYobi5pbWFnZXM9aCksdS5sZW5ndGg+MCYmKG4uc2hhcGVzPXUpLGYubGVuZ3RoPjAmJihuLnNrZWxldG9ucz1mKSxkLmxlbmd0aD4wJiYobi5hbmltYXRpb25zPWQpLHAubGVuZ3RoPjAmJihuLm5vZGVzPXApfXJldHVybiBuLm9iamVjdD1zLG47ZnVuY3Rpb24gbyhhKXtjb25zdCBjPVtdO2Zvcihjb25zdCBsIGluIGEpe2NvbnN0IGg9YVtsXTtkZWxldGUgaC5tZXRhZGF0YSxjLnB1c2goaCl9cmV0dXJuIGN9fWNsb25lKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyx0KX1jb3B5KHQsZT0hMCl7aWYodGhpcy5uYW1lPXQubmFtZSx0aGlzLnVwLmNvcHkodC51cCksdGhpcy5wb3NpdGlvbi5jb3B5KHQucG9zaXRpb24pLHRoaXMucm90YXRpb24ub3JkZXI9dC5yb3RhdGlvbi5vcmRlcix0aGlzLnF1YXRlcm5pb24uY29weSh0LnF1YXRlcm5pb24pLHRoaXMuc2NhbGUuY29weSh0LnNjYWxlKSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLm1hdHJpeFdvcmxkLmNvcHkodC5tYXRyaXhXb3JsZCksdGhpcy5tYXRyaXhBdXRvVXBkYXRlPXQubWF0cml4QXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT10Lm1hdHJpeFdvcmxkQXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9dC5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlLHRoaXMubGF5ZXJzLm1hc2s9dC5sYXllcnMubWFzayx0aGlzLnZpc2libGU9dC52aXNpYmxlLHRoaXMuY2FzdFNoYWRvdz10LmNhc3RTaGFkb3csdGhpcy5yZWNlaXZlU2hhZG93PXQucmVjZWl2ZVNoYWRvdyx0aGlzLmZydXN0dW1DdWxsZWQ9dC5mcnVzdHVtQ3VsbGVkLHRoaXMucmVuZGVyT3JkZXI9dC5yZW5kZXJPcmRlcix0aGlzLmFuaW1hdGlvbnM9dC5hbmltYXRpb25zLnNsaWNlKCksdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSxlPT09ITApZm9yKGxldCBuPTA7bjx0LmNoaWxkcmVuLmxlbmd0aDtuKyspe2NvbnN0IHM9dC5jaGlsZHJlbltuXTt0aGlzLmFkZChzLmNsb25lKCkpfXJldHVybiB0aGlzfX1UZS5ERUZBVUxUX1VQPW5ldyBUKDAsMSwwKSxUZS5ERUZBVUxUX01BVFJJWF9BVVRPX1VQREFURT0hMCxUZS5ERUZBVUxUX01BVFJJWF9XT1JMRF9BVVRPX1VQREFURT0hMDtjb25zdCBoZT1uZXcgVCxFZT1uZXcgVCxsbz1uZXcgVCxQZT1uZXcgVCwkbj1uZXcgVCxVbj1uZXcgVCx6Yz1uZXcgVCxobz1uZXcgVCx1bz1uZXcgVCxmbz1uZXcgVCxwbz1uZXcgWXQseW89bmV3IFl0LG1vPW5ldyBZdDtjbGFzcyBldHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCl7dGhpcy5hPXQsdGhpcy5iPWUsdGhpcy5jPW59c3RhdGljIGdldE5vcm1hbCh0LGUsbixzKXtzLnN1YlZlY3RvcnMobixlKSxoZS5zdWJWZWN0b3JzKHQsZSkscy5jcm9zcyhoZSk7Y29uc3Qgcj1zLmxlbmd0aFNxKCk7cmV0dXJuIHI+MD9zLm11bHRpcGx5U2NhbGFyKDEvTWF0aC5zcXJ0KHIpKTpzLnNldCgwLDAsMCl9c3RhdGljIGdldEJhcnljb29yZCh0LGUsbixzLHIpe2hlLnN1YlZlY3RvcnMocyxlKSxFZS5zdWJWZWN0b3JzKG4sZSksbG8uc3ViVmVjdG9ycyh0LGUpO2NvbnN0IG89aGUuZG90KGhlKSxhPWhlLmRvdChFZSksYz1oZS5kb3QobG8pLGw9RWUuZG90KEVlKSxoPUVlLmRvdChsbyksdT1vKmwtYSphO2lmKHU9PT0wKXJldHVybiByLnNldCgwLDAsMCksbnVsbDtjb25zdCBmPTEvdSxkPShsKmMtYSpoKSpmLHA9KG8qaC1hKmMpKmY7cmV0dXJuIHIuc2V0KDEtZC1wLHAsZCl9c3RhdGljIGNvbnRhaW5zUG9pbnQodCxlLG4scyl7cmV0dXJuIHRoaXMuZ2V0QmFyeWNvb3JkKHQsZSxuLHMsUGUpPT09bnVsbD8hMTpQZS54Pj0wJiZQZS55Pj0wJiZQZS54K1BlLnk8PTF9c3RhdGljIGdldEludGVycG9sYXRpb24odCxlLG4scyxyLG8sYSxjKXtyZXR1cm4gdGhpcy5nZXRCYXJ5Y29vcmQodCxlLG4scyxQZSk9PT1udWxsPyhjLng9MCxjLnk9MCwieiJpbiBjJiYoYy56PTApLCJ3ImluIGMmJihjLnc9MCksbnVsbCk6KGMuc2V0U2NhbGFyKDApLGMuYWRkU2NhbGVkVmVjdG9yKHIsUGUueCksYy5hZGRTY2FsZWRWZWN0b3IobyxQZS55KSxjLmFkZFNjYWxlZFZlY3RvcihhLFBlLnopLGMpfXN0YXRpYyBnZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUodCxlLG4scyxyLG8pe3JldHVybiBwby5zZXRTY2FsYXIoMCkseW8uc2V0U2NhbGFyKDApLG1vLnNldFNjYWxhcigwKSxwby5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSkseW8uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG4pLG1vLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSxvLnNldFNjYWxhcigwKSxvLmFkZFNjYWxlZFZlY3RvcihwbyxyLngpLG8uYWRkU2NhbGVkVmVjdG9yKHlvLHIueSksby5hZGRTY2FsZWRWZWN0b3IobW8sci56KSxvfXN0YXRpYyBpc0Zyb250RmFjaW5nKHQsZSxuLHMpe3JldHVybiBoZS5zdWJWZWN0b3JzKG4sZSksRWUuc3ViVmVjdG9ycyh0LGUpLGhlLmNyb3NzKEVlKS5kb3Qocyk8MH1zZXQodCxlLG4pe3JldHVybiB0aGlzLmEuY29weSh0KSx0aGlzLmIuY29weShlKSx0aGlzLmMuY29weShuKSx0aGlzfXNldEZyb21Qb2ludHNBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuY29weSh0W2VdKSx0aGlzLmIuY29weSh0W25dKSx0aGlzLmMuY29weSh0W3NdKSx0aGlzfXNldEZyb21BdHRyaWJ1dGVBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLHRoaXMuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsbiksdGhpcy5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLmEuY29weSh0LmEpLHRoaXMuYi5jb3B5KHQuYiksdGhpcy5jLmNvcHkodC5jKSx0aGlzfWdldEFyZWEoKXtyZXR1cm4gaGUuc3ViVmVjdG9ycyh0aGlzLmMsdGhpcy5iKSxFZS5zdWJWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLGhlLmNyb3NzKEVlKS5sZW5ndGgoKSouNX1nZXRNaWRwb2ludCh0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLmFkZCh0aGlzLmMpLm11bHRpcGx5U2NhbGFyKDEvMyl9Z2V0Tm9ybWFsKHQpe3JldHVybiBldC5nZXROb3JtYWwodGhpcy5hLHRoaXMuYix0aGlzLmMsdCl9Z2V0UGxhbmUodCl7cmV0dXJuIHQuc2V0RnJvbUNvcGxhbmFyUG9pbnRzKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1nZXRCYXJ5Y29vcmQodCxlKXtyZXR1cm4gZXQuZ2V0QmFyeWNvb3JkKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSl9Z2V0SW50ZXJwb2xhdGlvbih0LGUsbixzLHIpe3JldHVybiBldC5nZXRJbnRlcnBvbGF0aW9uKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSxuLHMscil9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gZXQuY29udGFpbnNQb2ludCh0LHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1pc0Zyb250RmFjaW5nKHQpe3JldHVybiBldC5pc0Zyb250RmFjaW5nKHRoaXMuYSx0aGlzLmIsdGhpcy5jLHQpfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1RyaWFuZ2xlKHRoaXMpfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuYSxzPXRoaXMuYixyPXRoaXMuYztsZXQgbyxhOyRuLnN1YlZlY3RvcnMocyxuKSxVbi5zdWJWZWN0b3JzKHIsbiksaG8uc3ViVmVjdG9ycyh0LG4pO2NvbnN0IGM9JG4uZG90KGhvKSxsPVVuLmRvdChobyk7aWYoYzw9MCYmbDw9MClyZXR1cm4gZS5jb3B5KG4pO3VvLnN1YlZlY3RvcnModCxzKTtjb25zdCBoPSRuLmRvdCh1byksdT1Vbi5kb3QodW8pO2lmKGg+PTAmJnU8PWgpcmV0dXJuIGUuY29weShzKTtjb25zdCBmPWMqdS1oKmw7aWYoZjw9MCYmYz49MCYmaDw9MClyZXR1cm4gbz1jLyhjLWgpLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoJG4sbyk7Zm8uc3ViVmVjdG9ycyh0LHIpO2NvbnN0IGQ9JG4uZG90KGZvKSxwPVVuLmRvdChmbyk7aWYocD49MCYmZDw9cClyZXR1cm4gZS5jb3B5KHIpO2NvbnN0IHk9ZCpsLWMqcDtpZih5PD0wJiZsPj0wJiZwPD0wKXJldHVybiBhPWwvKGwtcCksZS5jb3B5KG4pLmFkZFNjYWxlZFZlY3RvcihVbixhKTtjb25zdCBtPWgqcC1kKnU7aWYobTw9MCYmdS1oPj0wJiZkLXA+PTApcmV0dXJuIHpjLnN1YlZlY3RvcnMocixzKSxhPSh1LWgpLyh1LWgrKGQtcCkpLGUuY29weShzKS5hZGRTY2FsZWRWZWN0b3IoemMsYSk7Y29uc3QgZz0xLyhtK3krZik7cmV0dXJuIG89eSpnLGE9ZipnLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoJG4sbykuYWRkU2NhbGVkVmVjdG9yKFVuLGEpfWVxdWFscyh0KXtyZXR1cm4gdC5hLmVxdWFscyh0aGlzLmEpJiZ0LmIuZXF1YWxzKHRoaXMuYikmJnQuYy5lcXVhbHModGhpcy5jKX19Y29uc3QgVGM9e2FsaWNlYmx1ZToxNTc5MjM4MyxhbnRpcXVld2hpdGU6MTY0NDQzNzUsYXF1YTo2NTUzNSxhcXVhbWFyaW5lOjgzODg1NjQsYXp1cmU6MTU3OTQxNzUsYmVpZ2U6MTYxMTkyNjAsYmlzcXVlOjE2NzcwMjQ0LGJsYWNrOjAsYmxhbmNoZWRhbG1vbmQ6MTY3NzIwNDUsYmx1ZToyNTUsYmx1ZXZpb2xldDo5MDU1MjAyLGJyb3duOjEwODI0MjM0LGJ1cmx5d29vZDoxNDU5NjIzMSxjYWRldGJsdWU6NjI2NjUyOCxjaGFydHJldXNlOjgzODgzNTIsY2hvY29sYXRlOjEzNzg5NDcwLGNvcmFsOjE2NzQ0MjcyLGNvcm5mbG93ZXJibHVlOjY1OTE5ODEsY29ybnNpbGs6MTY3NzUzODgsY3JpbXNvbjoxNDQyMzEwMCxjeWFuOjY1NTM1LGRhcmtibHVlOjEzOSxkYXJrY3lhbjozNTcyMyxkYXJrZ29sZGVucm9kOjEyMDkyOTM5LGRhcmtncmF5OjExMTE5MDE3LGRhcmtncmVlbjoyNTYwMCxkYXJrZ3JleToxMTExOTAxNyxkYXJra2hha2k6MTI0MzMyNTksZGFya21hZ2VudGE6OTEwOTY0MyxkYXJrb2xpdmVncmVlbjo1NTk3OTk5LGRhcmtvcmFuZ2U6MTY3NDc1MjAsZGFya29yY2hpZDoxMDA0MDAxMixkYXJrcmVkOjkxMDk1MDQsZGFya3NhbG1vbjoxNTMwODQxMCxkYXJrc2VhZ3JlZW46OTQxOTkxOSxkYXJrc2xhdGVibHVlOjQ3MzQzNDcsZGFya3NsYXRlZ3JheTozMTAwNDk1LGRhcmtzbGF0ZWdyZXk6MzEwMDQ5NSxkYXJrdHVycXVvaXNlOjUyOTQ1LGRhcmt2aW9sZXQ6OTY5OTUzOSxkZWVwcGluazoxNjcxNjk0NyxkZWVwc2t5Ymx1ZTo0OTE1MSxkaW1ncmF5OjY5MDgyNjUsZGltZ3JleTo2OTA4MjY1LGRvZGdlcmJsdWU6MjAwMzE5OSxmaXJlYnJpY2s6MTE2NzQxNDYsZmxvcmFsd2hpdGU6MTY3NzU5MjAsZm9yZXN0Z3JlZW46MjI2Mzg0MixmdWNoc2lhOjE2NzExOTM1LGdhaW5zYm9ybzoxNDQ3NDQ2MCxnaG9zdHdoaXRlOjE2MzE2NjcxLGdvbGQ6MTY3NjY3MjAsZ29sZGVucm9kOjE0MzI5MTIwLGdyYXk6ODQyMTUwNCxncmVlbjozMjc2OCxncmVlbnllbGxvdzoxMTQwMzA1NSxncmV5Ojg0MjE1MDQsaG9uZXlkZXc6MTU3OTQxNjAsaG90cGluazoxNjczODc0MCxpbmRpYW5yZWQ6MTM0NTg1MjQsaW5kaWdvOjQ5MTUzMzAsaXZvcnk6MTY3NzcyMDAsa2hha2k6MTU3ODc2NjAsbGF2ZW5kZXI6MTUxMzI0MTAsbGF2ZW5kZXJibHVzaDoxNjc3MzM2NSxsYXduZ3JlZW46ODE5MDk3NixsZW1vbmNoaWZmb246MTY3NzU4ODUsbGlnaHRibHVlOjExMzkzMjU0LGxpZ2h0Y29yYWw6MTU3NjE1MzYsbGlnaHRjeWFuOjE0NzQ1NTk5LGxpZ2h0Z29sZGVucm9keWVsbG93OjE2NDQ4MjEwLGxpZ2h0Z3JheToxMzg4MjMyMyxsaWdodGdyZWVuOjk0OTgyNTYsbGlnaHRncmV5OjEzODgyMzIzLGxpZ2h0cGluazoxNjc1ODQ2NSxsaWdodHNhbG1vbjoxNjc1Mjc2MixsaWdodHNlYWdyZWVuOjIxNDI4OTAsbGlnaHRza3libHVlOjg5MDAzNDYsbGlnaHRzbGF0ZWdyYXk6NzgzMzc1MyxsaWdodHNsYXRlZ3JleTo3ODMzNzUzLGxpZ2h0c3RlZWxibHVlOjExNTg0NzM0LGxpZ2h0eWVsbG93OjE2Nzc3MTg0LGxpbWU6NjUyODAsbGltZWdyZWVuOjMzMjkzMzAsbGluZW46MTY0NDU2NzAsbWFnZW50YToxNjcxMTkzNSxtYXJvb246ODM4ODYwOCxtZWRpdW1hcXVhbWFyaW5lOjY3MzczMjIsbWVkaXVtYmx1ZToyMDUsbWVkaXVtb3JjaGlkOjEyMjExNjY3LG1lZGl1bXB1cnBsZTo5NjYyNjgzLG1lZGl1bXNlYWdyZWVuOjM5NzgwOTcsbWVkaXVtc2xhdGVibHVlOjgwODc3OTAsbWVkaXVtc3ByaW5nZ3JlZW46NjQxNTQsbWVkaXVtdHVycXVvaXNlOjQ3NzIzMDAsbWVkaXVtdmlvbGV0cmVkOjEzMDQ3MTczLG1pZG5pZ2h0Ymx1ZToxNjQ0OTEyLG1pbnRjcmVhbToxNjEyMTg1MCxtaXN0eXJvc2U6MTY3NzAyNzMsbW9jY2FzaW46MTY3NzAyMjksbmF2YWpvd2hpdGU6MTY3Njg2ODUsbmF2eToxMjgsb2xkbGFjZToxNjY0MzU1OCxvbGl2ZTo4NDIxMzc2LG9saXZlZHJhYjo3MDQ4NzM5LG9yYW5nZToxNjc1MzkyMCxvcmFuZ2VyZWQ6MTY3MjkzNDQsb3JjaGlkOjE0MzE1NzM0LHBhbGVnb2xkZW5yb2Q6MTU2NTcxMzAscGFsZWdyZWVuOjEwMDI1ODgwLHBhbGV0dXJxdW9pc2U6MTE1Mjk5NjYscGFsZXZpb2xldHJlZDoxNDM4MTIwMyxwYXBheWF3aGlwOjE2NzczMDc3LHBlYWNocHVmZjoxNjc2NzY3MyxwZXJ1OjEzNDY4OTkxLHBpbms6MTY3NjEwMzUscGx1bToxNDUyNDYzNyxwb3dkZXJibHVlOjExNTkxOTEwLHB1cnBsZTo4Mzg4NzM2LHJlYmVjY2FwdXJwbGU6NjY5Nzg4MSxyZWQ6MTY3MTE2ODAscm9zeWJyb3duOjEyMzU3NTE5LHJveWFsYmx1ZTo0Mjg2OTQ1LHNhZGRsZWJyb3duOjkxMjcxODcsc2FsbW9uOjE2NDE2ODgyLHNhbmR5YnJvd246MTYwMzI4NjQsc2VhZ3JlZW46MzA1MDMyNyxzZWFzaGVsbDoxNjc3NDYzOCxzaWVubmE6MTA1MDY3OTcsc2lsdmVyOjEyNjMyMjU2LHNreWJsdWU6ODkwMDMzMSxzbGF0ZWJsdWU6Njk3MDA2MSxzbGF0ZWdyYXk6NzM3Mjk0NCxzbGF0ZWdyZXk6NzM3Mjk0NCxzbm93OjE2Nzc1OTMwLHNwcmluZ2dyZWVuOjY1NDA3LHN0ZWVsYmx1ZTo0NjIwOTgwLHRhbjoxMzgwODc4MCx0ZWFsOjMyODk2LHRoaXN0bGU6MTQyMDQ4ODgsdG9tYXRvOjE2NzM3MDk1LHR1cnF1b2lzZTo0MjUxODU2LHZpb2xldDoxNTYzMTA4Nix3aGVhdDoxNjExMzMzMSx3aGl0ZToxNjc3NzIxNSx3aGl0ZXNtb2tlOjE2MTE5Mjg1LHllbGxvdzoxNjc3Njk2MCx5ZWxsb3dncmVlbjoxMDE0NTA3NH0samU9e2g6MCxzOjAsbDowfSx1cz17aDowLHM6MCxsOjB9O2Z1bmN0aW9uIGdvKGksdCxlKXtyZXR1cm4gZTwwJiYoZSs9MSksZT4xJiYoZS09MSksZTwxLzY/aSsodC1pKSo2KmU6ZTwxLzI/dDplPDIvMz9pKyh0LWkpKjYqKDIvMy1lKTppfWxldCBmcz1jbGFzc3tjb25zdHJ1Y3Rvcih0LGUsbil7cmV0dXJuIHRoaXMuaXNDb2xvcj0hMCx0aGlzLnI9MSx0aGlzLmc9MSx0aGlzLmI9MSx0aGlzLnNldCh0LGUsbil9c2V0KHQsZSxuKXtpZihlPT09dm9pZCAwJiZuPT09dm9pZCAwKXtjb25zdCBzPXQ7cyYmcy5pc0NvbG9yP3RoaXMuY29weShzKTp0eXBlb2Ygcz09Im51bWJlciI/dGhpcy5zZXRIZXgocyk6dHlwZW9mIHM9PSJzdHJpbmciJiZ0aGlzLnNldFN0eWxlKHMpfWVsc2UgdGhpcy5zZXRSR0IodCxlLG4pO3JldHVybiB0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy5yPXQsdGhpcy5nPXQsdGhpcy5iPXQsdGhpc31zZXRIZXgodCxlPW9lKXtyZXR1cm4gdD1NYXRoLmZsb29yKHQpLHRoaXMucj0odD4+MTYmMjU1KS8yNTUsdGhpcy5nPSh0Pj44JjI1NSkvMjU1LHRoaXMuYj0odCYyNTUpLzI1NSxhZS50b1dvcmtpbmdDb2xvclNwYWNlKHRoaXMsZSksdGhpc31zZXRSR0IodCxlLG4scz1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHRoaXMucj10LHRoaXMuZz1lLHRoaXMuYj1uLGFlLnRvV29ya2luZ0NvbG9yU3BhY2UodGhpcyxzKSx0aGlzfXNldEhTTCh0LGUsbixzPWFlLndvcmtpbmdDb2xvclNwYWNlKXtpZih0PVV1KHQsMSksZT1aKGUsMCwxKSxuPVoobiwwLDEpLGU9PT0wKXRoaXMucj10aGlzLmc9dGhpcy5iPW47ZWxzZXtjb25zdCByPW48PS41P24qKDErZSk6bitlLW4qZSxvPTIqbi1yO3RoaXMucj1nbyhvLHIsdCsxLzMpLHRoaXMuZz1nbyhvLHIsdCksdGhpcy5iPWdvKG8scix0LTEvMyl9cmV0dXJuIGFlLnRvV29ya2luZ0NvbG9yU3BhY2UodGhpcyxzKSx0aGlzfXNldFN0eWxlKHQsZT1vZSl7ZnVuY3Rpb24gbihyKXtyIT09dm9pZCAwJiZwYXJzZUZsb2F0KHIpPDEmJmNvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IEFscGhhIGNvbXBvbmVudCBvZiAiK3QrIiB3aWxsIGJlIGlnbm9yZWQuIil9bGV0IHM7aWYocz0vXihcdyspXCgoW15cKV0qKVwpLy5leGVjKHQpKXtsZXQgcjtjb25zdCBvPXNbMV0sYT1zWzJdO3N3aXRjaChvKXtjYXNlInJnYiI6Y2FzZSJyZ2JhIjppZihyPS9eXHMqKFxkKylccyosXHMqKFxkKylccyosXHMqKFxkKylccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRSR0IoTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMV0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMl0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbM10sMTApKS8yNTUsZSk7aWYocj0vXlxzKihcZCspXCVccyosXHMqKFxkKylcJVxzKixccyooXGQrKVwlXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0UkdCKE1hdGgubWluKDEwMCxwYXJzZUludChyWzFdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzJdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzNdLDEwKSkvMTAwLGUpO2JyZWFrO2Nhc2UiaHNsIjpjYXNlImhzbGEiOmlmKHI9L15ccyooXGQqXC4/XGQrKVxzKixccyooXGQqXC4/XGQrKVwlXHMqLFxzKihcZCpcLj9cZCspXCVccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRIU0wocGFyc2VGbG9hdChyWzFdKS8zNjAscGFyc2VGbG9hdChyWzJdKS8xMDAscGFyc2VGbG9hdChyWzNdKS8xMDAsZSk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkNvbG9yOiBVbmtub3duIGNvbG9yIG1vZGVsICIrdCl9fWVsc2UgaWYocz0vXlwjKFtBLUZhLWZcZF0rKSQvLmV4ZWModCkpe2NvbnN0IHI9c1sxXSxvPXIubGVuZ3RoO2lmKG89PT0zKXJldHVybiB0aGlzLnNldFJHQihwYXJzZUludChyLmNoYXJBdCgwKSwxNikvMTUscGFyc2VJbnQoci5jaGFyQXQoMSksMTYpLzE1LHBhcnNlSW50KHIuY2hhckF0KDIpLDE2KS8xNSxlKTtpZihvPT09NilyZXR1cm4gdGhpcy5zZXRIZXgocGFyc2VJbnQociwxNiksZSk7Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogSW52YWxpZCBoZXggY29sb3IgIit0KX1lbHNlIGlmKHQmJnQubGVuZ3RoPjApcmV0dXJuIHRoaXMuc2V0Q29sb3JOYW1lKHQsZSk7cmV0dXJuIHRoaXN9c2V0Q29sb3JOYW1lKHQsZT1vZSl7Y29uc3Qgbj1UY1t0LnRvTG93ZXJDYXNlKCldO3JldHVybiBuIT09dm9pZCAwP3RoaXMuc2V0SGV4KG4sZSk6Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogVW5rbm93biBjb2xvciAiK3QpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5yLHRoaXMuZyx0aGlzLmIpfWNvcHkodCl7cmV0dXJuIHRoaXMucj10LnIsdGhpcy5nPXQuZyx0aGlzLmI9dC5iLHRoaXN9Y29weVNSR0JUb0xpbmVhcih0KXtyZXR1cm4gdGhpcy5yPV9lKHQuciksdGhpcy5nPV9lKHQuZyksdGhpcy5iPV9lKHQuYiksdGhpc31jb3B5TGluZWFyVG9TUkdCKHQpe3JldHVybiB0aGlzLnI9Rm4odC5yKSx0aGlzLmc9Rm4odC5nKSx0aGlzLmI9Rm4odC5iKSx0aGlzfWNvbnZlcnRTUkdCVG9MaW5lYXIoKXtyZXR1cm4gdGhpcy5jb3B5U1JHQlRvTGluZWFyKHRoaXMpLHRoaXN9Y29udmVydExpbmVhclRvU1JHQigpe3JldHVybiB0aGlzLmNvcHlMaW5lYXJUb1NSR0IodGhpcyksdGhpc31nZXRIZXgodD1vZSl7cmV0dXJuIGFlLmZyb21Xb3JraW5nQ29sb3JTcGFjZShfdC5jb3B5KHRoaXMpLHQpLE1hdGgucm91bmQoWihfdC5yKjI1NSwwLDI1NSkpKjY1NTM2K01hdGgucm91bmQoWihfdC5nKjI1NSwwLDI1NSkpKjI1NitNYXRoLnJvdW5kKFooX3QuYioyNTUsMCwyNTUpKX1nZXRIZXhTdHJpbmcodD1vZSl7cmV0dXJuKCIwMDAwMDAiK3RoaXMuZ2V0SGV4KHQpLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTYpfWdldEhTTCh0LGU9YWUud29ya2luZ0NvbG9yU3BhY2Upe2FlLmZyb21Xb3JraW5nQ29sb3JTcGFjZShfdC5jb3B5KHRoaXMpLGUpO2NvbnN0IG49X3QucixzPV90Lmcscj1fdC5iLG89TWF0aC5tYXgobixzLHIpLGE9TWF0aC5taW4obixzLHIpO2xldCBjLGw7Y29uc3QgaD0oYStvKS8yO2lmKGE9PT1vKWM9MCxsPTA7ZWxzZXtjb25zdCB1PW8tYTtzd2l0Y2gobD1oPD0uNT91LyhvK2EpOnUvKDItby1hKSxvKXtjYXNlIG46Yz0ocy1yKS91KyhzPHI/NjowKTticmVhaztjYXNlIHM6Yz0oci1uKS91KzI7YnJlYWs7Y2FzZSByOmM9KG4tcykvdSs0O2JyZWFrfWMvPTZ9cmV0dXJuIHQuaD1jLHQucz1sLHQubD1oLHR9Z2V0UkdCKHQsZT1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIGFlLmZyb21Xb3JraW5nQ29sb3JTcGFjZShfdC5jb3B5KHRoaXMpLGUpLHQucj1fdC5yLHQuZz1fdC5nLHQuYj1fdC5iLHR9Z2V0U3R5bGUodD1vZSl7YWUuZnJvbVdvcmtpbmdDb2xvclNwYWNlKF90LmNvcHkodGhpcyksdCk7Y29uc3QgZT1fdC5yLG49X3QuZyxzPV90LmI7cmV0dXJuIHQhPT1vZT9gY29sb3IoJHt0fSAke2UudG9GaXhlZCgzKX0gJHtuLnRvRml4ZWQoMyl9ICR7cy50b0ZpeGVkKDMpfSlgOmByZ2IoJHtNYXRoLnJvdW5kKGUqMjU1KX0sJHtNYXRoLnJvdW5kKG4qMjU1KX0sJHtNYXRoLnJvdW5kKHMqMjU1KX0pYH1vZmZzZXRIU0wodCxlLG4pe3JldHVybiB0aGlzLmdldEhTTChqZSksdGhpcy5zZXRIU0woamUuaCt0LGplLnMrZSxqZS5sK24pfWFkZCh0KXtyZXR1cm4gdGhpcy5yKz10LnIsdGhpcy5nKz10LmcsdGhpcy5iKz10LmIsdGhpc31hZGRDb2xvcnModCxlKXtyZXR1cm4gdGhpcy5yPXQucitlLnIsdGhpcy5nPXQuZytlLmcsdGhpcy5iPXQuYitlLmIsdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMucis9dCx0aGlzLmcrPXQsdGhpcy5iKz10LHRoaXN9c3ViKHQpe3JldHVybiB0aGlzLnI9TWF0aC5tYXgoMCx0aGlzLnItdC5yKSx0aGlzLmc9TWF0aC5tYXgoMCx0aGlzLmctdC5nKSx0aGlzLmI9TWF0aC5tYXgoMCx0aGlzLmItdC5iKSx0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLnIqPXQucix0aGlzLmcqPXQuZyx0aGlzLmIqPXQuYix0aGlzfW11bHRpcGx5U2NhbGFyKHQpe3JldHVybiB0aGlzLnIqPXQsdGhpcy5nKj10LHRoaXMuYio9dCx0aGlzfWxlcnAodCxlKXtyZXR1cm4gdGhpcy5yKz0odC5yLXRoaXMucikqZSx0aGlzLmcrPSh0LmctdGhpcy5nKSplLHRoaXMuYis9KHQuYi10aGlzLmIpKmUsdGhpc31sZXJwQ29sb3JzKHQsZSxuKXtyZXR1cm4gdGhpcy5yPXQucisoZS5yLXQucikqbix0aGlzLmc9dC5nKyhlLmctdC5nKSpuLHRoaXMuYj10LmIrKGUuYi10LmIpKm4sdGhpc31sZXJwSFNMKHQsZSl7dGhpcy5nZXRIU0woamUpLHQuZ2V0SFNMKHVzKTtjb25zdCBuPWpyKGplLmgsdXMuaCxlKSxzPWpyKGplLnMsdXMucyxlKSxyPWpyKGplLmwsdXMubCxlKTtyZXR1cm4gdGhpcy5zZXRIU0wobixzLHIpLHRoaXN9c2V0RnJvbVZlY3RvcjModCl7cmV0dXJuIHRoaXMucj10LngsdGhpcy5nPXQueSx0aGlzLmI9dC56LHRoaXN9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy5yLG49dGhpcy5nLHM9dGhpcy5iLHI9dC5lbGVtZW50cztyZXR1cm4gdGhpcy5yPXJbMF0qZStyWzNdKm4rcls2XSpzLHRoaXMuZz1yWzFdKmUrcls0XSpuK3JbN10qcyx0aGlzLmI9clsyXSplK3JbNV0qbityWzhdKnMsdGhpc31lcXVhbHModCl7cmV0dXJuIHQucj09PXRoaXMuciYmdC5nPT09dGhpcy5nJiZ0LmI9PT10aGlzLmJ9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy5yPXRbZV0sdGhpcy5nPXRbZSsxXSx0aGlzLmI9dFtlKzJdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy5yLHRbZSsxXT10aGlzLmcsdFtlKzJdPXRoaXMuYix0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy5yPXQuZ2V0WChlKSx0aGlzLmc9dC5nZXRZKGUpLHRoaXMuYj10LmdldFooZSksdGhpc310b0pTT04oKXtyZXR1cm4gdGhpcy5nZXRIZXgoKX0qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLnIseWllbGQgdGhpcy5nLHlpZWxkIHRoaXMuYn19O2NvbnN0IF90PW5ldyBmcztmcy5OQU1FUz1UYztsZXQgbmY9MDtjbGFzcyBzZiBleHRlbmRzIGlze2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLmlzTWF0ZXJpYWw9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6bmYrK30pLHRoaXMudXVpZD1CbigpLHRoaXMubmFtZT0iIix0aGlzLnR5cGU9Ik1hdGVyaWFsIix0aGlzLmJsZW5kaW5nPTEsdGhpcy5zaWRlPTAsdGhpcy52ZXJ0ZXhDb2xvcnM9ITEsdGhpcy5vcGFjaXR5PTEsdGhpcy50cmFuc3BhcmVudD0hMSx0aGlzLmFscGhhSGFzaD0hMSx0aGlzLmJsZW5kU3JjPTIwNCx0aGlzLmJsZW5kRHN0PTIwNSx0aGlzLmJsZW5kRXF1YXRpb249MTAwLHRoaXMuYmxlbmRTcmNBbHBoYT1udWxsLHRoaXMuYmxlbmREc3RBbHBoYT1udWxsLHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhPW51bGwsdGhpcy5ibGVuZENvbG9yPW5ldyBmcygwLDAsMCksdGhpcy5ibGVuZEFscGhhPTAsdGhpcy5kZXB0aEZ1bmM9Myx0aGlzLmRlcHRoVGVzdD0hMCx0aGlzLmRlcHRoV3JpdGU9ITAsdGhpcy5zdGVuY2lsV3JpdGVNYXNrPTI1NSx0aGlzLnN0ZW5jaWxGdW5jPTUxOSx0aGlzLnN0ZW5jaWxSZWY9MCx0aGlzLnN0ZW5jaWxGdW5jTWFzaz0yNTUsdGhpcy5zdGVuY2lsRmFpbD03NjgwLHRoaXMuc3RlbmNpbFpGYWlsPTc2ODAsdGhpcy5zdGVuY2lsWlBhc3M9NzY4MCx0aGlzLnN0ZW5jaWxXcml0ZT0hMSx0aGlzLmNsaXBwaW5nUGxhbmVzPW51bGwsdGhpcy5jbGlwSW50ZXJzZWN0aW9uPSExLHRoaXMuY2xpcFNoYWRvd3M9ITEsdGhpcy5zaGFkb3dTaWRlPW51bGwsdGhpcy5jb2xvcldyaXRlPSEwLHRoaXMucHJlY2lzaW9uPW51bGwsdGhpcy5wb2x5Z29uT2Zmc2V0PSExLHRoaXMucG9seWdvbk9mZnNldEZhY3Rvcj0wLHRoaXMucG9seWdvbk9mZnNldFVuaXRzPTAsdGhpcy5kaXRoZXJpbmc9ITEsdGhpcy5hbHBoYVRvQ292ZXJhZ2U9ITEsdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE9ITEsdGhpcy5mb3JjZVNpbmdsZVBhc3M9ITEsdGhpcy5hbGxvd092ZXJyaWRlPSEwLHRoaXMudmlzaWJsZT0hMCx0aGlzLnRvbmVNYXBwZWQ9ITAsdGhpcy51c2VyRGF0YT17fSx0aGlzLnZlcnNpb249MCx0aGlzLl9hbHBoYVRlc3Q9MH1nZXQgYWxwaGFUZXN0KCl7cmV0dXJuIHRoaXMuX2FscGhhVGVzdH1zZXQgYWxwaGFUZXN0KHQpe3RoaXMuX2FscGhhVGVzdD4wIT10PjAmJnRoaXMudmVyc2lvbisrLHRoaXMuX2FscGhhVGVzdD10fW9uQmVmb3JlUmVuZGVyKCl7fW9uQmVmb3JlQ29tcGlsZSgpe31jdXN0b21Qcm9ncmFtQ2FjaGVLZXkoKXtyZXR1cm4gdGhpcy5vbkJlZm9yZUNvbXBpbGUudG9TdHJpbmcoKX1zZXRWYWx1ZXModCl7aWYodCE9PXZvaWQgMClmb3IoY29uc3QgZSBpbiB0KXtjb25zdCBuPXRbZV07aWYobj09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5NYXRlcmlhbDogcGFyYW1ldGVyICcke2V9JyBoYXMgdmFsdWUgb2YgdW5kZWZpbmVkLmApO2NvbnRpbnVlfWNvbnN0IHM9dGhpc1tlXTtpZihzPT09dm9pZCAwKXtjb25zb2xlLndhcm4oYFRIUkVFLk1hdGVyaWFsOiAnJHtlfScgaXMgbm90IGEgcHJvcGVydHkgb2YgVEhSRUUuJHt0aGlzLnR5cGV9LmApO2NvbnRpbnVlfXMmJnMuaXNDb2xvcj9zLnNldChuKTpzJiZzLmlzVmVjdG9yMyYmbiYmbi5pc1ZlY3RvcjM/cy5jb3B5KG4pOnRoaXNbZV09bn19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciO2UmJih0PXt0ZXh0dXJlczp7fSxpbWFnZXM6e319KTtjb25zdCBuPXttZXRhZGF0YTp7dmVyc2lvbjo0LjYsdHlwZToiTWF0ZXJpYWwiLGdlbmVyYXRvcjoiTWF0ZXJpYWwudG9KU09OIn19O24udXVpZD10aGlzLnV1aWQsbi50eXBlPXRoaXMudHlwZSx0aGlzLm5hbWUhPT0iIiYmKG4ubmFtZT10aGlzLm5hbWUpLHRoaXMuY29sb3ImJnRoaXMuY29sb3IuaXNDb2xvciYmKG4uY29sb3I9dGhpcy5jb2xvci5nZXRIZXgoKSksdGhpcy5yb3VnaG5lc3MhPT12b2lkIDAmJihuLnJvdWdobmVzcz10aGlzLnJvdWdobmVzcyksdGhpcy5tZXRhbG5lc3MhPT12b2lkIDAmJihuLm1ldGFsbmVzcz10aGlzLm1ldGFsbmVzcyksdGhpcy5zaGVlbiE9PXZvaWQgMCYmKG4uc2hlZW49dGhpcy5zaGVlbiksdGhpcy5zaGVlbkNvbG9yJiZ0aGlzLnNoZWVuQ29sb3IuaXNDb2xvciYmKG4uc2hlZW5Db2xvcj10aGlzLnNoZWVuQ29sb3IuZ2V0SGV4KCkpLHRoaXMuc2hlZW5Sb3VnaG5lc3MhPT12b2lkIDAmJihuLnNoZWVuUm91Z2huZXNzPXRoaXMuc2hlZW5Sb3VnaG5lc3MpLHRoaXMuZW1pc3NpdmUmJnRoaXMuZW1pc3NpdmUuaXNDb2xvciYmKG4uZW1pc3NpdmU9dGhpcy5lbWlzc2l2ZS5nZXRIZXgoKSksdGhpcy5lbWlzc2l2ZUludGVuc2l0eSE9PXZvaWQgMCYmdGhpcy5lbWlzc2l2ZUludGVuc2l0eSE9PTEmJihuLmVtaXNzaXZlSW50ZW5zaXR5PXRoaXMuZW1pc3NpdmVJbnRlbnNpdHkpLHRoaXMuc3BlY3VsYXImJnRoaXMuc3BlY3VsYXIuaXNDb2xvciYmKG4uc3BlY3VsYXI9dGhpcy5zcGVjdWxhci5nZXRIZXgoKSksdGhpcy5zcGVjdWxhckludGVuc2l0eSE9PXZvaWQgMCYmKG4uc3BlY3VsYXJJbnRlbnNpdHk9dGhpcy5zcGVjdWxhckludGVuc2l0eSksdGhpcy5zcGVjdWxhckNvbG9yJiZ0aGlzLnNwZWN1bGFyQ29sb3IuaXNDb2xvciYmKG4uc3BlY3VsYXJDb2xvcj10aGlzLnNwZWN1bGFyQ29sb3IuZ2V0SGV4KCkpLHRoaXMuc2hpbmluZXNzIT09dm9pZCAwJiYobi5zaGluaW5lc3M9dGhpcy5zaGluaW5lc3MpLHRoaXMuY2xlYXJjb2F0IT09dm9pZCAwJiYobi5jbGVhcmNvYXQ9dGhpcy5jbGVhcmNvYXQpLHRoaXMuY2xlYXJjb2F0Um91Z2huZXNzIT09dm9pZCAwJiYobi5jbGVhcmNvYXRSb3VnaG5lc3M9dGhpcy5jbGVhcmNvYXRSb3VnaG5lc3MpLHRoaXMuY2xlYXJjb2F0TWFwJiZ0aGlzLmNsZWFyY29hdE1hcC5pc1RleHR1cmUmJihuLmNsZWFyY29hdE1hcD10aGlzLmNsZWFyY29hdE1hcC50b0pTT04odCkudXVpZCksdGhpcy5jbGVhcmNvYXRSb3VnaG5lc3NNYXAmJnRoaXMuY2xlYXJjb2F0Um91Z2huZXNzTWFwLmlzVGV4dHVyZSYmKG4uY2xlYXJjb2F0Um91Z2huZXNzTWFwPXRoaXMuY2xlYXJjb2F0Um91Z2huZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmNsZWFyY29hdE5vcm1hbE1hcCYmdGhpcy5jbGVhcmNvYXROb3JtYWxNYXAuaXNUZXh0dXJlJiYobi5jbGVhcmNvYXROb3JtYWxNYXA9dGhpcy5jbGVhcmNvYXROb3JtYWxNYXAudG9KU09OKHQpLnV1aWQsbi5jbGVhcmNvYXROb3JtYWxTY2FsZT10aGlzLmNsZWFyY29hdE5vcm1hbFNjYWxlLnRvQXJyYXkoKSksdGhpcy5kaXNwZXJzaW9uIT09dm9pZCAwJiYobi5kaXNwZXJzaW9uPXRoaXMuZGlzcGVyc2lvbiksdGhpcy5pcmlkZXNjZW5jZSE9PXZvaWQgMCYmKG4uaXJpZGVzY2VuY2U9dGhpcy5pcmlkZXNjZW5jZSksdGhpcy5pcmlkZXNjZW5jZUlPUiE9PXZvaWQgMCYmKG4uaXJpZGVzY2VuY2VJT1I9dGhpcy5pcmlkZXNjZW5jZUlPUiksdGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc1JhbmdlIT09dm9pZCAwJiYobi5pcmlkZXNjZW5jZVRoaWNrbmVzc1JhbmdlPXRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NSYW5nZSksdGhpcy5pcmlkZXNjZW5jZU1hcCYmdGhpcy5pcmlkZXNjZW5jZU1hcC5pc1RleHR1cmUmJihuLmlyaWRlc2NlbmNlTWFwPXRoaXMuaXJpZGVzY2VuY2VNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXAmJnRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXAuaXNUZXh0dXJlJiYobi5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcD10aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmFuaXNvdHJvcHkhPT12b2lkIDAmJihuLmFuaXNvdHJvcHk9dGhpcy5hbmlzb3Ryb3B5KSx0aGlzLmFuaXNvdHJvcHlSb3RhdGlvbiE9PXZvaWQgMCYmKG4uYW5pc290cm9weVJvdGF0aW9uPXRoaXMuYW5pc290cm9weVJvdGF0aW9uKSx0aGlzLmFuaXNvdHJvcHlNYXAmJnRoaXMuYW5pc290cm9weU1hcC5pc1RleHR1cmUmJihuLmFuaXNvdHJvcHlNYXA9dGhpcy5hbmlzb3Ryb3B5TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLm1hcCYmdGhpcy5tYXAuaXNUZXh0dXJlJiYobi5tYXA9dGhpcy5tYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubWF0Y2FwJiZ0aGlzLm1hdGNhcC5pc1RleHR1cmUmJihuLm1hdGNhcD10aGlzLm1hdGNhcC50b0pTT04odCkudXVpZCksdGhpcy5hbHBoYU1hcCYmdGhpcy5hbHBoYU1hcC5pc1RleHR1cmUmJihuLmFscGhhTWFwPXRoaXMuYWxwaGFNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubGlnaHRNYXAmJnRoaXMubGlnaHRNYXAuaXNUZXh0dXJlJiYobi5saWdodE1hcD10aGlzLmxpZ2h0TWFwLnRvSlNPTih0KS51dWlkLG4ubGlnaHRNYXBJbnRlbnNpdHk9dGhpcy5saWdodE1hcEludGVuc2l0eSksdGhpcy5hb01hcCYmdGhpcy5hb01hcC5pc1RleHR1cmUmJihuLmFvTWFwPXRoaXMuYW9NYXAudG9KU09OKHQpLnV1aWQsbi5hb01hcEludGVuc2l0eT10aGlzLmFvTWFwSW50ZW5zaXR5KSx0aGlzLmJ1bXBNYXAmJnRoaXMuYnVtcE1hcC5pc1RleHR1cmUmJihuLmJ1bXBNYXA9dGhpcy5idW1wTWFwLnRvSlNPTih0KS51dWlkLG4uYnVtcFNjYWxlPXRoaXMuYnVtcFNjYWxlKSx0aGlzLm5vcm1hbE1hcCYmdGhpcy5ub3JtYWxNYXAuaXNUZXh0dXJlJiYobi5ub3JtYWxNYXA9dGhpcy5ub3JtYWxNYXAudG9KU09OKHQpLnV1aWQsbi5ub3JtYWxNYXBUeXBlPXRoaXMubm9ybWFsTWFwVHlwZSxuLm5vcm1hbFNjYWxlPXRoaXMubm9ybWFsU2NhbGUudG9BcnJheSgpKSx0aGlzLmRpc3BsYWNlbWVudE1hcCYmdGhpcy5kaXNwbGFjZW1lbnRNYXAuaXNUZXh0dXJlJiYobi5kaXNwbGFjZW1lbnRNYXA9dGhpcy5kaXNwbGFjZW1lbnRNYXAudG9KU09OKHQpLnV1aWQsbi5kaXNwbGFjZW1lbnRTY2FsZT10aGlzLmRpc3BsYWNlbWVudFNjYWxlLG4uZGlzcGxhY2VtZW50Qmlhcz10aGlzLmRpc3BsYWNlbWVudEJpYXMpLHRoaXMucm91Z2huZXNzTWFwJiZ0aGlzLnJvdWdobmVzc01hcC5pc1RleHR1cmUmJihuLnJvdWdobmVzc01hcD10aGlzLnJvdWdobmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5tZXRhbG5lc3NNYXAmJnRoaXMubWV0YWxuZXNzTWFwLmlzVGV4dHVyZSYmKG4ubWV0YWxuZXNzTWFwPXRoaXMubWV0YWxuZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmVtaXNzaXZlTWFwJiZ0aGlzLmVtaXNzaXZlTWFwLmlzVGV4dHVyZSYmKG4uZW1pc3NpdmVNYXA9dGhpcy5lbWlzc2l2ZU1hcC50b0pTT04odCkudXVpZCksdGhpcy5zcGVjdWxhck1hcCYmdGhpcy5zcGVjdWxhck1hcC5pc1RleHR1cmUmJihuLnNwZWN1bGFyTWFwPXRoaXMuc3BlY3VsYXJNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuc3BlY3VsYXJJbnRlbnNpdHlNYXAmJnRoaXMuc3BlY3VsYXJJbnRlbnNpdHlNYXAuaXNUZXh0dXJlJiYobi5zcGVjdWxhckludGVuc2l0eU1hcD10aGlzLnNwZWN1bGFySW50ZW5zaXR5TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnNwZWN1bGFyQ29sb3JNYXAmJnRoaXMuc3BlY3VsYXJDb2xvck1hcC5pc1RleHR1cmUmJihuLnNwZWN1bGFyQ29sb3JNYXA9dGhpcy5zcGVjdWxhckNvbG9yTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmVudk1hcCYmdGhpcy5lbnZNYXAuaXNUZXh0dXJlJiYobi5lbnZNYXA9dGhpcy5lbnZNYXAudG9KU09OKHQpLnV1aWQsdGhpcy5jb21iaW5lIT09dm9pZCAwJiYobi5jb21iaW5lPXRoaXMuY29tYmluZSkpLHRoaXMuZW52TWFwUm90YXRpb24hPT12b2lkIDAmJihuLmVudk1hcFJvdGF0aW9uPXRoaXMuZW52TWFwUm90YXRpb24udG9BcnJheSgpKSx0aGlzLmVudk1hcEludGVuc2l0eSE9PXZvaWQgMCYmKG4uZW52TWFwSW50ZW5zaXR5PXRoaXMuZW52TWFwSW50ZW5zaXR5KSx0aGlzLnJlZmxlY3Rpdml0eSE9PXZvaWQgMCYmKG4ucmVmbGVjdGl2aXR5PXRoaXMucmVmbGVjdGl2aXR5KSx0aGlzLnJlZnJhY3Rpb25SYXRpbyE9PXZvaWQgMCYmKG4ucmVmcmFjdGlvblJhdGlvPXRoaXMucmVmcmFjdGlvblJhdGlvKSx0aGlzLmdyYWRpZW50TWFwJiZ0aGlzLmdyYWRpZW50TWFwLmlzVGV4dHVyZSYmKG4uZ3JhZGllbnRNYXA9dGhpcy5ncmFkaWVudE1hcC50b0pTT04odCkudXVpZCksdGhpcy50cmFuc21pc3Npb24hPT12b2lkIDAmJihuLnRyYW5zbWlzc2lvbj10aGlzLnRyYW5zbWlzc2lvbiksdGhpcy50cmFuc21pc3Npb25NYXAmJnRoaXMudHJhbnNtaXNzaW9uTWFwLmlzVGV4dHVyZSYmKG4udHJhbnNtaXNzaW9uTWFwPXRoaXMudHJhbnNtaXNzaW9uTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnRoaWNrbmVzcyE9PXZvaWQgMCYmKG4udGhpY2tuZXNzPXRoaXMudGhpY2tuZXNzKSx0aGlzLnRoaWNrbmVzc01hcCYmdGhpcy50aGlja25lc3NNYXAuaXNUZXh0dXJlJiYobi50aGlja25lc3NNYXA9dGhpcy50aGlja25lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuYXR0ZW51YXRpb25EaXN0YW5jZSE9PXZvaWQgMCYmdGhpcy5hdHRlbnVhdGlvbkRpc3RhbmNlIT09MS8wJiYobi5hdHRlbnVhdGlvbkRpc3RhbmNlPXRoaXMuYXR0ZW51YXRpb25EaXN0YW5jZSksdGhpcy5hdHRlbnVhdGlvbkNvbG9yIT09dm9pZCAwJiYobi5hdHRlbnVhdGlvbkNvbG9yPXRoaXMuYXR0ZW51YXRpb25Db2xvci5nZXRIZXgoKSksdGhpcy5zaXplIT09dm9pZCAwJiYobi5zaXplPXRoaXMuc2l6ZSksdGhpcy5zaGFkb3dTaWRlIT09bnVsbCYmKG4uc2hhZG93U2lkZT10aGlzLnNoYWRvd1NpZGUpLHRoaXMuc2l6ZUF0dGVudWF0aW9uIT09dm9pZCAwJiYobi5zaXplQXR0ZW51YXRpb249dGhpcy5zaXplQXR0ZW51YXRpb24pLHRoaXMuYmxlbmRpbmchPT0xJiYobi5ibGVuZGluZz10aGlzLmJsZW5kaW5nKSx0aGlzLnNpZGUhPT0wJiYobi5zaWRlPXRoaXMuc2lkZSksdGhpcy52ZXJ0ZXhDb2xvcnM9PT0hMCYmKG4udmVydGV4Q29sb3JzPSEwKSx0aGlzLm9wYWNpdHk8MSYmKG4ub3BhY2l0eT10aGlzLm9wYWNpdHkpLHRoaXMudHJhbnNwYXJlbnQ9PT0hMCYmKG4udHJhbnNwYXJlbnQ9ITApLHRoaXMuYmxlbmRTcmMhPT0yMDQmJihuLmJsZW5kU3JjPXRoaXMuYmxlbmRTcmMpLHRoaXMuYmxlbmREc3QhPT0yMDUmJihuLmJsZW5kRHN0PXRoaXMuYmxlbmREc3QpLHRoaXMuYmxlbmRFcXVhdGlvbiE9PTEwMCYmKG4uYmxlbmRFcXVhdGlvbj10aGlzLmJsZW5kRXF1YXRpb24pLHRoaXMuYmxlbmRTcmNBbHBoYSE9PW51bGwmJihuLmJsZW5kU3JjQWxwaGE9dGhpcy5ibGVuZFNyY0FscGhhKSx0aGlzLmJsZW5kRHN0QWxwaGEhPT1udWxsJiYobi5ibGVuZERzdEFscGhhPXRoaXMuYmxlbmREc3RBbHBoYSksdGhpcy5ibGVuZEVxdWF0aW9uQWxwaGEhPT1udWxsJiYobi5ibGVuZEVxdWF0aW9uQWxwaGE9dGhpcy5ibGVuZEVxdWF0aW9uQWxwaGEpLHRoaXMuYmxlbmRDb2xvciYmdGhpcy5ibGVuZENvbG9yLmlzQ29sb3ImJihuLmJsZW5kQ29sb3I9dGhpcy5ibGVuZENvbG9yLmdldEhleCgpKSx0aGlzLmJsZW5kQWxwaGEhPT0wJiYobi5ibGVuZEFscGhhPXRoaXMuYmxlbmRBbHBoYSksdGhpcy5kZXB0aEZ1bmMhPT0zJiYobi5kZXB0aEZ1bmM9dGhpcy5kZXB0aEZ1bmMpLHRoaXMuZGVwdGhUZXN0PT09ITEmJihuLmRlcHRoVGVzdD10aGlzLmRlcHRoVGVzdCksdGhpcy5kZXB0aFdyaXRlPT09ITEmJihuLmRlcHRoV3JpdGU9dGhpcy5kZXB0aFdyaXRlKSx0aGlzLmNvbG9yV3JpdGU9PT0hMSYmKG4uY29sb3JXcml0ZT10aGlzLmNvbG9yV3JpdGUpLHRoaXMuc3RlbmNpbFdyaXRlTWFzayE9PTI1NSYmKG4uc3RlbmNpbFdyaXRlTWFzaz10aGlzLnN0ZW5jaWxXcml0ZU1hc2spLHRoaXMuc3RlbmNpbEZ1bmMhPT01MTkmJihuLnN0ZW5jaWxGdW5jPXRoaXMuc3RlbmNpbEZ1bmMpLHRoaXMuc3RlbmNpbFJlZiE9PTAmJihuLnN0ZW5jaWxSZWY9dGhpcy5zdGVuY2lsUmVmKSx0aGlzLnN0ZW5jaWxGdW5jTWFzayE9PTI1NSYmKG4uc3RlbmNpbEZ1bmNNYXNrPXRoaXMuc3RlbmNpbEZ1bmNNYXNrKSx0aGlzLnN0ZW5jaWxGYWlsIT09NzY4MCYmKG4uc3RlbmNpbEZhaWw9dGhpcy5zdGVuY2lsRmFpbCksdGhpcy5zdGVuY2lsWkZhaWwhPT03NjgwJiYobi5zdGVuY2lsWkZhaWw9dGhpcy5zdGVuY2lsWkZhaWwpLHRoaXMuc3RlbmNpbFpQYXNzIT09NzY4MCYmKG4uc3RlbmNpbFpQYXNzPXRoaXMuc3RlbmNpbFpQYXNzKSx0aGlzLnN0ZW5jaWxXcml0ZT09PSEwJiYobi5zdGVuY2lsV3JpdGU9dGhpcy5zdGVuY2lsV3JpdGUpLHRoaXMucm90YXRpb24hPT12b2lkIDAmJnRoaXMucm90YXRpb24hPT0wJiYobi5yb3RhdGlvbj10aGlzLnJvdGF0aW9uKSx0aGlzLnBvbHlnb25PZmZzZXQ9PT0hMCYmKG4ucG9seWdvbk9mZnNldD0hMCksdGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yIT09MCYmKG4ucG9seWdvbk9mZnNldEZhY3Rvcj10aGlzLnBvbHlnb25PZmZzZXRGYWN0b3IpLHRoaXMucG9seWdvbk9mZnNldFVuaXRzIT09MCYmKG4ucG9seWdvbk9mZnNldFVuaXRzPXRoaXMucG9seWdvbk9mZnNldFVuaXRzKSx0aGlzLmxpbmV3aWR0aCE9PXZvaWQgMCYmdGhpcy5saW5ld2lkdGghPT0xJiYobi5saW5ld2lkdGg9dGhpcy5saW5ld2lkdGgpLHRoaXMuZGFzaFNpemUhPT12b2lkIDAmJihuLmRhc2hTaXplPXRoaXMuZGFzaFNpemUpLHRoaXMuZ2FwU2l6ZSE9PXZvaWQgMCYmKG4uZ2FwU2l6ZT10aGlzLmdhcFNpemUpLHRoaXMuc2NhbGUhPT12b2lkIDAmJihuLnNjYWxlPXRoaXMuc2NhbGUpLHRoaXMuZGl0aGVyaW5nPT09ITAmJihuLmRpdGhlcmluZz0hMCksdGhpcy5hbHBoYVRlc3Q+MCYmKG4uYWxwaGFUZXN0PXRoaXMuYWxwaGFUZXN0KSx0aGlzLmFscGhhSGFzaD09PSEwJiYobi5hbHBoYUhhc2g9ITApLHRoaXMuYWxwaGFUb0NvdmVyYWdlPT09ITAmJihuLmFscGhhVG9Db3ZlcmFnZT0hMCksdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE9PT0hMCYmKG4ucHJlbXVsdGlwbGllZEFscGhhPSEwKSx0aGlzLmZvcmNlU2luZ2xlUGFzcz09PSEwJiYobi5mb3JjZVNpbmdsZVBhc3M9ITApLHRoaXMud2lyZWZyYW1lPT09ITAmJihuLndpcmVmcmFtZT0hMCksdGhpcy53aXJlZnJhbWVMaW5ld2lkdGg+MSYmKG4ud2lyZWZyYW1lTGluZXdpZHRoPXRoaXMud2lyZWZyYW1lTGluZXdpZHRoKSx0aGlzLndpcmVmcmFtZUxpbmVjYXAhPT0icm91bmQiJiYobi53aXJlZnJhbWVMaW5lY2FwPXRoaXMud2lyZWZyYW1lTGluZWNhcCksdGhpcy53aXJlZnJhbWVMaW5lam9pbiE9PSJyb3VuZCImJihuLndpcmVmcmFtZUxpbmVqb2luPXRoaXMud2lyZWZyYW1lTGluZWpvaW4pLHRoaXMuZmxhdFNoYWRpbmc9PT0hMCYmKG4uZmxhdFNoYWRpbmc9ITApLHRoaXMudmlzaWJsZT09PSExJiYobi52aXNpYmxlPSExKSx0aGlzLnRvbmVNYXBwZWQ9PT0hMSYmKG4udG9uZU1hcHBlZD0hMSksdGhpcy5mb2c9PT0hMSYmKG4uZm9nPSExKSxPYmplY3Qua2V5cyh0aGlzLnVzZXJEYXRhKS5sZW5ndGg+MCYmKG4udXNlckRhdGE9dGhpcy51c2VyRGF0YSk7ZnVuY3Rpb24gcyhyKXtjb25zdCBvPVtdO2Zvcihjb25zdCBhIGluIHIpe2NvbnN0IGM9clthXTtkZWxldGUgYy5tZXRhZGF0YSxvLnB1c2goYyl9cmV0dXJuIG99aWYoZSl7Y29uc3Qgcj1zKHQudGV4dHVyZXMpLG89cyh0LmltYWdlcyk7ci5sZW5ndGg+MCYmKG4udGV4dHVyZXM9ciksby5sZW5ndGg+MCYmKG4uaW1hZ2VzPW8pfXJldHVybiBufWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3RoaXMubmFtZT10Lm5hbWUsdGhpcy5ibGVuZGluZz10LmJsZW5kaW5nLHRoaXMuc2lkZT10LnNpZGUsdGhpcy52ZXJ0ZXhDb2xvcnM9dC52ZXJ0ZXhDb2xvcnMsdGhpcy5vcGFjaXR5PXQub3BhY2l0eSx0aGlzLnRyYW5zcGFyZW50PXQudHJhbnNwYXJlbnQsdGhpcy5ibGVuZFNyYz10LmJsZW5kU3JjLHRoaXMuYmxlbmREc3Q9dC5ibGVuZERzdCx0aGlzLmJsZW5kRXF1YXRpb249dC5ibGVuZEVxdWF0aW9uLHRoaXMuYmxlbmRTcmNBbHBoYT10LmJsZW5kU3JjQWxwaGEsdGhpcy5ibGVuZERzdEFscGhhPXQuYmxlbmREc3RBbHBoYSx0aGlzLmJsZW5kRXF1YXRpb25BbHBoYT10LmJsZW5kRXF1YXRpb25BbHBoYSx0aGlzLmJsZW5kQ29sb3IuY29weSh0LmJsZW5kQ29sb3IpLHRoaXMuYmxlbmRBbHBoYT10LmJsZW5kQWxwaGEsdGhpcy5kZXB0aEZ1bmM9dC5kZXB0aEZ1bmMsdGhpcy5kZXB0aFRlc3Q9dC5kZXB0aFRlc3QsdGhpcy5kZXB0aFdyaXRlPXQuZGVwdGhXcml0ZSx0aGlzLnN0ZW5jaWxXcml0ZU1hc2s9dC5zdGVuY2lsV3JpdGVNYXNrLHRoaXMuc3RlbmNpbEZ1bmM9dC5zdGVuY2lsRnVuYyx0aGlzLnN0ZW5jaWxSZWY9dC5zdGVuY2lsUmVmLHRoaXMuc3RlbmNpbEZ1bmNNYXNrPXQuc3RlbmNpbEZ1bmNNYXNrLHRoaXMuc3RlbmNpbEZhaWw9dC5zdGVuY2lsRmFpbCx0aGlzLnN0ZW5jaWxaRmFpbD10LnN0ZW5jaWxaRmFpbCx0aGlzLnN0ZW5jaWxaUGFzcz10LnN0ZW5jaWxaUGFzcyx0aGlzLnN0ZW5jaWxXcml0ZT10LnN0ZW5jaWxXcml0ZTtjb25zdCBlPXQuY2xpcHBpbmdQbGFuZXM7bGV0IG49bnVsbDtpZihlIT09bnVsbCl7Y29uc3Qgcz1lLmxlbmd0aDtuPW5ldyBBcnJheShzKTtmb3IobGV0IHI9MDtyIT09czsrK3IpbltyXT1lW3JdLmNsb25lKCl9cmV0dXJuIHRoaXMuY2xpcHBpbmdQbGFuZXM9bix0aGlzLmNsaXBJbnRlcnNlY3Rpb249dC5jbGlwSW50ZXJzZWN0aW9uLHRoaXMuY2xpcFNoYWRvd3M9dC5jbGlwU2hhZG93cyx0aGlzLnNoYWRvd1NpZGU9dC5zaGFkb3dTaWRlLHRoaXMuY29sb3JXcml0ZT10LmNvbG9yV3JpdGUsdGhpcy5wcmVjaXNpb249dC5wcmVjaXNpb24sdGhpcy5wb2x5Z29uT2Zmc2V0PXQucG9seWdvbk9mZnNldCx0aGlzLnBvbHlnb25PZmZzZXRGYWN0b3I9dC5wb2x5Z29uT2Zmc2V0RmFjdG9yLHRoaXMucG9seWdvbk9mZnNldFVuaXRzPXQucG9seWdvbk9mZnNldFVuaXRzLHRoaXMuZGl0aGVyaW5nPXQuZGl0aGVyaW5nLHRoaXMuYWxwaGFUZXN0PXQuYWxwaGFUZXN0LHRoaXMuYWxwaGFIYXNoPXQuYWxwaGFIYXNoLHRoaXMuYWxwaGFUb0NvdmVyYWdlPXQuYWxwaGFUb0NvdmVyYWdlLHRoaXMucHJlbXVsdGlwbGllZEFscGhhPXQucHJlbXVsdGlwbGllZEFscGhhLHRoaXMuZm9yY2VTaW5nbGVQYXNzPXQuZm9yY2VTaW5nbGVQYXNzLHRoaXMudmlzaWJsZT10LnZpc2libGUsdGhpcy50b25lTWFwcGVkPXQudG9uZU1hcHBlZCx0aGlzLnVzZXJEYXRhPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodC51c2VyRGF0YSkpLHRoaXN9ZGlzcG9zZSgpe3RoaXMuZGlzcGF0Y2hFdmVudCh7dHlwZToiZGlzcG9zZSJ9KX1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK319Y2xhc3MgcmYgZXh0ZW5kcyBzZntjb25zdHJ1Y3Rvcih0KXtzdXBlcigpLHRoaXMuaXNNZXNoQmFzaWNNYXRlcmlhbD0hMCx0aGlzLnR5cGU9Ik1lc2hCYXNpY01hdGVyaWFsIix0aGlzLmNvbG9yPW5ldyBmcygxNjc3NzIxNSksdGhpcy5tYXA9bnVsbCx0aGlzLmxpZ2h0TWFwPW51bGwsdGhpcy5saWdodE1hcEludGVuc2l0eT0xLHRoaXMuYW9NYXA9bnVsbCx0aGlzLmFvTWFwSW50ZW5zaXR5PTEsdGhpcy5zcGVjdWxhck1hcD1udWxsLHRoaXMuYWxwaGFNYXA9bnVsbCx0aGlzLmVudk1hcD1udWxsLHRoaXMuZW52TWFwUm90YXRpb249bmV3IHhpLHRoaXMuY29tYmluZT0wLHRoaXMucmVmbGVjdGl2aXR5PTEsdGhpcy5yZWZyYWN0aW9uUmF0aW89Ljk4LHRoaXMud2lyZWZyYW1lPSExLHRoaXMud2lyZWZyYW1lTGluZXdpZHRoPTEsdGhpcy53aXJlZnJhbWVMaW5lY2FwPSJyb3VuZCIsdGhpcy53aXJlZnJhbWVMaW5lam9pbj0icm91bmQiLHRoaXMuZm9nPSEwLHRoaXMuc2V0VmFsdWVzKHQpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5jb2xvci5jb3B5KHQuY29sb3IpLHRoaXMubWFwPXQubWFwLHRoaXMubGlnaHRNYXA9dC5saWdodE1hcCx0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5PXQubGlnaHRNYXBJbnRlbnNpdHksdGhpcy5hb01hcD10LmFvTWFwLHRoaXMuYW9NYXBJbnRlbnNpdHk9dC5hb01hcEludGVuc2l0eSx0aGlzLnNwZWN1bGFyTWFwPXQuc3BlY3VsYXJNYXAsdGhpcy5hbHBoYU1hcD10LmFscGhhTWFwLHRoaXMuZW52TWFwPXQuZW52TWFwLHRoaXMuZW52TWFwUm90YXRpb24uY29weSh0LmVudk1hcFJvdGF0aW9uKSx0aGlzLmNvbWJpbmU9dC5jb21iaW5lLHRoaXMucmVmbGVjdGl2aXR5PXQucmVmbGVjdGl2aXR5LHRoaXMucmVmcmFjdGlvblJhdGlvPXQucmVmcmFjdGlvblJhdGlvLHRoaXMud2lyZWZyYW1lPXQud2lyZWZyYW1lLHRoaXMud2lyZWZyYW1lTGluZXdpZHRoPXQud2lyZWZyYW1lTGluZXdpZHRoLHRoaXMud2lyZWZyYW1lTGluZWNhcD10LndpcmVmcmFtZUxpbmVjYXAsdGhpcy53aXJlZnJhbWVMaW5lam9pbj10LndpcmVmcmFtZUxpbmVqb2luLHRoaXMuZm9nPXQuZm9nLHRoaXN9fWNvbnN0IHB0PW5ldyBULGRzPW5ldyBSO2xldCBvZj0wO2NsYXNzIHh0e2NvbnN0cnVjdG9yKHQsZSxuPSExKXtpZihBcnJheS5pc0FycmF5KHQpKXRocm93IG5ldyBUeXBlRXJyb3IoIlRIUkVFLkJ1ZmZlckF0dHJpYnV0ZTogYXJyYXkgc2hvdWxkIGJlIGEgVHlwZWQgQXJyYXkuIik7dGhpcy5pc0J1ZmZlckF0dHJpYnV0ZT0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpvZisrfSksdGhpcy5uYW1lPSIiLHRoaXMuYXJyYXk9dCx0aGlzLml0ZW1TaXplPWUsdGhpcy5jb3VudD10IT09dm9pZCAwP3QubGVuZ3RoL2U6MCx0aGlzLm5vcm1hbGl6ZWQ9bix0aGlzLnVzYWdlPTM1MDQ0LHRoaXMudXBkYXRlUmFuZ2VzPVtdLHRoaXMuZ3B1VHlwZT0xMDE1LHRoaXMudmVyc2lvbj0wfW9uVXBsb2FkQ2FsbGJhY2soKXt9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy52ZXJzaW9uKyt9c2V0VXNhZ2UodCl7cmV0dXJuIHRoaXMudXNhZ2U9dCx0aGlzfWFkZFVwZGF0ZVJhbmdlKHQsZSl7dGhpcy51cGRhdGVSYW5nZXMucHVzaCh7c3RhcnQ6dCxjb3VudDplfSl9Y2xlYXJVcGRhdGVSYW5nZXMoKXt0aGlzLnVwZGF0ZVJhbmdlcy5sZW5ndGg9MH1jb3B5KHQpe3JldHVybiB0aGlzLm5hbWU9dC5uYW1lLHRoaXMuYXJyYXk9bmV3IHQuYXJyYXkuY29uc3RydWN0b3IodC5hcnJheSksdGhpcy5pdGVtU2l6ZT10Lml0ZW1TaXplLHRoaXMuY291bnQ9dC5jb3VudCx0aGlzLm5vcm1hbGl6ZWQ9dC5ub3JtYWxpemVkLHRoaXMudXNhZ2U9dC51c2FnZSx0aGlzLmdwdVR5cGU9dC5ncHVUeXBlLHRoaXN9Y29weUF0KHQsZSxuKXt0Kj10aGlzLml0ZW1TaXplLG4qPWUuaXRlbVNpemU7Zm9yKGxldCBzPTAscj10aGlzLml0ZW1TaXplO3M8cjtzKyspdGhpcy5hcnJheVt0K3NdPWUuYXJyYXlbbitzXTtyZXR1cm4gdGhpc31jb3B5QXJyYXkodCl7cmV0dXJuIHRoaXMuYXJyYXkuc2V0KHQpLHRoaXN9YXBwbHlNYXRyaXgzKHQpe2lmKHRoaXMuaXRlbVNpemU9PT0yKWZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKWRzLmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxkcy5hcHBseU1hdHJpeDModCksdGhpcy5zZXRYWShlLGRzLngsZHMueSk7ZWxzZSBpZih0aGlzLml0ZW1TaXplPT09Mylmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQuYXBwbHlNYXRyaXgzKHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfWFwcGx5TWF0cml4NCh0KXtmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQuYXBwbHlNYXRyaXg0KHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfWFwcGx5Tm9ybWFsTWF0cml4KHQpe2ZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC5hcHBseU5vcm1hbE1hdHJpeCh0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc310cmFuc2Zvcm1EaXJlY3Rpb24odCl7Zm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LnRyYW5zZm9ybURpcmVjdGlvbih0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc31zZXQodCxlPTApe3JldHVybiB0aGlzLmFycmF5LnNldCh0LGUpLHRoaXN9Z2V0Q29tcG9uZW50KHQsZSl7bGV0IG49dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrZV07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKG49cGkobix0aGlzLmFycmF5KSksbn1zZXRDb21wb25lbnQodCxlLG4pe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihuPUl0KG4sdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplK2VdPW4sdGhpc31nZXRYKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1waShlLHRoaXMuYXJyYXkpKSxlfXNldFgodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZV09ZSx0aGlzfWdldFkodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMV07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9cGkoZSx0aGlzLmFycmF5KSksZX1zZXRZKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMV09ZSx0aGlzfWdldFoodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMl07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9cGkoZSx0aGlzLmFycmF5KSksZX1zZXRaKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMl09ZSx0aGlzfWdldFcodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrM107cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9cGkoZSx0aGlzLmFycmF5KSksZX1zZXRXKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrM109ZSx0aGlzfXNldFhZKHQsZSxuKXtyZXR1cm4gdCo9dGhpcy5pdGVtU2l6ZSx0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSksbj1JdChuLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QrMF09ZSx0aGlzLmFycmF5W3QrMV09bix0aGlzfXNldFhZWih0LGUsbixzKXtyZXR1cm4gdCo9dGhpcy5pdGVtU2l6ZSx0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSksbj1JdChuLHRoaXMuYXJyYXkpLHM9SXQocyx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KzBdPWUsdGhpcy5hcnJheVt0KzFdPW4sdGhpcy5hcnJheVt0KzJdPXMsdGhpc31zZXRYWVpXKHQsZSxuLHMscil7cmV0dXJuIHQqPXRoaXMuaXRlbVNpemUsdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpLG49SXQobix0aGlzLmFycmF5KSxzPUl0KHMsdGhpcy5hcnJheSkscj1JdChyLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QrMF09ZSx0aGlzLmFycmF5W3QrMV09bix0aGlzLmFycmF5W3QrMl09cyx0aGlzLmFycmF5W3QrM109cix0aGlzfW9uVXBsb2FkKHQpe3JldHVybiB0aGlzLm9uVXBsb2FkQ2FsbGJhY2s9dCx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuYXJyYXksdGhpcy5pdGVtU2l6ZSkuY29weSh0aGlzKX10b0pTT04oKXtjb25zdCB0PXtpdGVtU2l6ZTp0aGlzLml0ZW1TaXplLHR5cGU6dGhpcy5hcnJheS5jb25zdHJ1Y3Rvci5uYW1lLGFycmF5OkFycmF5LmZyb20odGhpcy5hcnJheSksbm9ybWFsaXplZDp0aGlzLm5vcm1hbGl6ZWR9O3JldHVybiB0aGlzLm5hbWUhPT0iIiYmKHQubmFtZT10aGlzLm5hbWUpLHRoaXMudXNhZ2UhPT0zNTA0NCYmKHQudXNhZ2U9dGhpcy51c2FnZSksdH19Y2xhc3MgYWYgZXh0ZW5kcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbil7c3VwZXIobmV3IFVpbnQxNkFycmF5KHQpLGUsbil9fWNsYXNzIGNmIGV4dGVuZHMgeHR7Y29uc3RydWN0b3IodCxlLG4pe3N1cGVyKG5ldyBVaW50MzJBcnJheSh0KSxlLG4pfX1jbGFzcyBDZSBleHRlbmRzIHh0e2NvbnN0cnVjdG9yKHQsZSxuKXtzdXBlcihuZXcgRmxvYXQzMkFycmF5KHQpLGUsbil9fWxldCBsZj0wO2NvbnN0IGp0PW5ldyBzdCx4bz1uZXcgVGUsVm49bmV3IFQsVXQ9bmV3IGd0LGJpPW5ldyBndCxidD1uZXcgVDtjbGFzcyB1ZSBleHRlbmRzIGlze2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLmlzQnVmZmVyR2VvbWV0cnk9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6bGYrK30pLHRoaXMudXVpZD1CbigpLHRoaXMubmFtZT0iIix0aGlzLnR5cGU9IkJ1ZmZlckdlb21ldHJ5Iix0aGlzLmluZGV4PW51bGwsdGhpcy5pbmRpcmVjdD1udWxsLHRoaXMuYXR0cmlidXRlcz17fSx0aGlzLm1vcnBoQXR0cmlidXRlcz17fSx0aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPSExLHRoaXMuZ3JvdXBzPVtdLHRoaXMuYm91bmRpbmdCb3g9bnVsbCx0aGlzLmJvdW5kaW5nU3BoZXJlPW51bGwsdGhpcy5kcmF3UmFuZ2U9e3N0YXJ0OjAsY291bnQ6MS8wfSx0aGlzLnVzZXJEYXRhPXt9fWdldEluZGV4KCl7cmV0dXJuIHRoaXMuaW5kZXh9c2V0SW5kZXgodCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/dGhpcy5pbmRleD1uZXcoVnUodCk/Y2Y6YWYpKHQsMSk6dGhpcy5pbmRleD10LHRoaXN9c2V0SW5kaXJlY3QodCl7cmV0dXJuIHRoaXMuaW5kaXJlY3Q9dCx0aGlzfWdldEluZGlyZWN0KCl7cmV0dXJuIHRoaXMuaW5kaXJlY3R9Z2V0QXR0cmlidXRlKHQpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF19c2V0QXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XT1lLHRoaXN9ZGVsZXRlQXR0cmlidXRlKHQpe3JldHVybiBkZWxldGUgdGhpcy5hdHRyaWJ1dGVzW3RdLHRoaXN9aGFzQXR0cmlidXRlKHQpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF0hPT12b2lkIDB9YWRkR3JvdXAodCxlLG49MCl7dGhpcy5ncm91cHMucHVzaCh7c3RhcnQ6dCxjb3VudDplLG1hdGVyaWFsSW5kZXg6bn0pfWNsZWFyR3JvdXBzKCl7dGhpcy5ncm91cHM9W119c2V0RHJhd1JhbmdlKHQsZSl7dGhpcy5kcmF3UmFuZ2Uuc3RhcnQ9dCx0aGlzLmRyYXdSYW5nZS5jb3VudD1lfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbjtlIT09dm9pZCAwJiYoZS5hcHBseU1hdHJpeDQodCksZS5uZWVkc1VwZGF0ZT0hMCk7Y29uc3Qgbj10aGlzLmF0dHJpYnV0ZXMubm9ybWFsO2lmKG4hPT12b2lkIDApe2NvbnN0IHI9bmV3IGdlKCkuZ2V0Tm9ybWFsTWF0cml4KHQpO24uYXBwbHlOb3JtYWxNYXRyaXgociksbi5uZWVkc1VwZGF0ZT0hMH1jb25zdCBzPXRoaXMuYXR0cmlidXRlcy50YW5nZW50O3JldHVybiBzIT09dm9pZCAwJiYocy50cmFuc2Zvcm1EaXJlY3Rpb24odCkscy5uZWVkc1VwZGF0ZT0hMCksdGhpcy5ib3VuZGluZ0JveCE9PW51bGwmJnRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCksdGhpcy5ib3VuZGluZ1NwaGVyZSE9PW51bGwmJnRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCksdGhpc31hcHBseVF1YXRlcm5pb24odCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXJvdGF0ZVgodCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvblgodCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9cm90YXRlWSh0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uWSh0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31yb3RhdGVaKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25aKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXRyYW5zbGF0ZSh0LGUsbil7cmV0dXJuIGp0Lm1ha2VUcmFuc2xhdGlvbih0LGUsbiksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9c2NhbGUodCxlLG4pe3JldHVybiBqdC5tYWtlU2NhbGUodCxlLG4pLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfWxvb2tBdCh0KXtyZXR1cm4geG8ubG9va0F0KHQpLHhvLnVwZGF0ZU1hdHJpeCgpLHRoaXMuYXBwbHlNYXRyaXg0KHhvLm1hdHJpeCksdGhpc31jZW50ZXIoKXtyZXR1cm4gdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKSx0aGlzLmJvdW5kaW5nQm94LmdldENlbnRlcihWbikubmVnYXRlKCksdGhpcy50cmFuc2xhdGUoVm4ueCxWbi55LFZuLnopLHRoaXN9c2V0RnJvbVBvaW50cyh0KXtjb25zdCBlPXRoaXMuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpO2lmKGU9PT12b2lkIDApe2NvbnN0IG49W107Zm9yKGxldCBzPTAscj10Lmxlbmd0aDtzPHI7cysrKXtjb25zdCBvPXRbc107bi5wdXNoKG8ueCxvLnksby56fHwwKX10aGlzLnNldEF0dHJpYnV0ZSgicG9zaXRpb24iLG5ldyBDZShuLDMpKX1lbHNle2NvbnN0IG49TWF0aC5taW4odC5sZW5ndGgsZS5jb3VudCk7Zm9yKGxldCBzPTA7czxuO3MrKyl7Y29uc3Qgcj10W3NdO2Uuc2V0WFlaKHMsci54LHIueSxyLnp8fDApfXQubGVuZ3RoPmUuY291bnQmJmNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnk6IEJ1ZmZlciBzaXplIHRvbyBzbWFsbCBmb3IgcG9pbnRzIGRhdGEuIFVzZSAuZGlzcG9zZSgpIGFuZCBjcmVhdGUgYSBuZXcgZ2VvbWV0cnkuIiksZS5uZWVkc1VwZGF0ZT0hMH1yZXR1cm4gdGhpc31jb21wdXRlQm91bmRpbmdCb3goKXt0aGlzLmJvdW5kaW5nQm94PT09bnVsbCYmKHRoaXMuYm91bmRpbmdCb3g9bmV3IGd0KTtjb25zdCB0PXRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbixlPXRoaXMubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uO2lmKHQmJnQuaXNHTEJ1ZmZlckF0dHJpYnV0ZSl7Y29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94KCk6IEdMQnVmZmVyQXR0cmlidXRlIHJlcXVpcmVzIGEgbWFudWFsIGJvdW5kaW5nIGJveC4iLHRoaXMpLHRoaXMuYm91bmRpbmdCb3guc2V0KG5ldyBUKC0xLzAsLTEvMCwtMS8wKSxuZXcgVCgxLzAsMS8wLDEvMCkpO3JldHVybn1pZih0IT09dm9pZCAwKXtpZih0aGlzLmJvdW5kaW5nQm94LnNldEZyb21CdWZmZXJBdHRyaWJ1dGUodCksZSlmb3IobGV0IG49MCxzPWUubGVuZ3RoO248cztuKyspe2NvbnN0IHI9ZVtuXTtVdC5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHIpLHRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU/KGJ0LmFkZFZlY3RvcnModGhpcy5ib3VuZGluZ0JveC5taW4sVXQubWluKSx0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoYnQpLGJ0LmFkZFZlY3RvcnModGhpcy5ib3VuZGluZ0JveC5tYXgsVXQubWF4KSx0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoYnQpKToodGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KFV0Lm1pbiksdGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KFV0Lm1heCkpfX1lbHNlIHRoaXMuYm91bmRpbmdCb3gubWFrZUVtcHR5KCk7KGlzTmFOKHRoaXMuYm91bmRpbmdCb3gubWluLngpfHxpc05hTih0aGlzLmJvdW5kaW5nQm94Lm1pbi55KXx8aXNOYU4odGhpcy5ib3VuZGluZ0JveC5taW4ueikpJiZjb25zb2xlLmVycm9yKCdUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTogQ29tcHV0ZWQgbWluL21heCBoYXZlIE5hTiB2YWx1ZXMuIFRoZSAicG9zaXRpb24iIGF0dHJpYnV0ZSBpcyBsaWtlbHkgdG8gaGF2ZSBOYU4gdmFsdWVzLicsdGhpcyl9Y29tcHV0ZUJvdW5kaW5nU3BoZXJlKCl7dGhpcy5ib3VuZGluZ1NwaGVyZT09PW51bGwmJih0aGlzLmJvdW5kaW5nU3BoZXJlPW5ldyBpbyk7Y29uc3QgdD10aGlzLmF0dHJpYnV0ZXMucG9zaXRpb24sZT10aGlzLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbjtpZih0JiZ0LmlzR0xCdWZmZXJBdHRyaWJ1dGUpe2NvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpOiBHTEJ1ZmZlckF0dHJpYnV0ZSByZXF1aXJlcyBhIG1hbnVhbCBib3VuZGluZyBzcGhlcmUuIix0aGlzKSx0aGlzLmJvdW5kaW5nU3BoZXJlLnNldChuZXcgVCwxLzApO3JldHVybn1pZih0KXtjb25zdCBuPXRoaXMuYm91bmRpbmdTcGhlcmUuY2VudGVyO2lmKFV0LnNldEZyb21CdWZmZXJBdHRyaWJ1dGUodCksZSlmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVtyXTtiaS5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKGEpLHRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU/KGJ0LmFkZFZlY3RvcnMoVXQubWluLGJpLm1pbiksVXQuZXhwYW5kQnlQb2ludChidCksYnQuYWRkVmVjdG9ycyhVdC5tYXgsYmkubWF4KSxVdC5leHBhbmRCeVBvaW50KGJ0KSk6KFV0LmV4cGFuZEJ5UG9pbnQoYmkubWluKSxVdC5leHBhbmRCeVBvaW50KGJpLm1heCkpfVV0LmdldENlbnRlcihuKTtsZXQgcz0wO2ZvcihsZXQgcj0wLG89dC5jb3VudDtyPG87cisrKWJ0LmZyb21CdWZmZXJBdHRyaWJ1dGUodCxyKSxzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZChidCkpO2lmKGUpZm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl0sYz10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlO2ZvcihsZXQgbD0wLGg9YS5jb3VudDtsPGg7bCsrKWJ0LmZyb21CdWZmZXJBdHRyaWJ1dGUoYSxsKSxjJiYoVm4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGwpLGJ0LmFkZChWbikpLHM9TWF0aC5tYXgocyxuLmRpc3RhbmNlVG9TcXVhcmVkKGJ0KSl9dGhpcy5ib3VuZGluZ1NwaGVyZS5yYWRpdXM9TWF0aC5zcXJ0KHMpLGlzTmFOKHRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzKSYmY29uc29sZS5lcnJvcignVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCk6IENvbXB1dGVkIHJhZGl1cyBpcyBOYU4uIFRoZSAicG9zaXRpb24iIGF0dHJpYnV0ZSBpcyBsaWtlbHkgdG8gaGF2ZSBOYU4gdmFsdWVzLicsdGhpcyl9fWNvbXB1dGVUYW5nZW50cygpe2NvbnN0IHQ9dGhpcy5pbmRleCxlPXRoaXMuYXR0cmlidXRlcztpZih0PT09bnVsbHx8ZS5wb3NpdGlvbj09PXZvaWQgMHx8ZS5ub3JtYWw9PT12b2lkIDB8fGUudXY9PT12b2lkIDApe2NvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5OiAuY29tcHV0ZVRhbmdlbnRzKCkgZmFpbGVkLiBNaXNzaW5nIHJlcXVpcmVkIGF0dHJpYnV0ZXMgKGluZGV4LCBwb3NpdGlvbiwgbm9ybWFsIG9yIHV2KSIpO3JldHVybn1jb25zdCBuPWUucG9zaXRpb24scz1lLm5vcm1hbCxyPWUudXY7dGhpcy5oYXNBdHRyaWJ1dGUoInRhbmdlbnQiKT09PSExJiZ0aGlzLnNldEF0dHJpYnV0ZSgidGFuZ2VudCIsbmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkoNCpuLmNvdW50KSw0KSk7Y29uc3Qgbz10aGlzLmdldEF0dHJpYnV0ZSgidGFuZ2VudCIpLGE9W10sYz1bXTtmb3IobGV0IFM9MDtTPG4uY291bnQ7UysrKWFbU109bmV3IFQsY1tTXT1uZXcgVDtjb25zdCBsPW5ldyBULGg9bmV3IFQsdT1uZXcgVCxmPW5ldyBSLGQ9bmV3IFIscD1uZXcgUix5PW5ldyBULG09bmV3IFQ7ZnVuY3Rpb24gZyhTLEUseil7bC5mcm9tQnVmZmVyQXR0cmlidXRlKG4sUyksaC5mcm9tQnVmZmVyQXR0cmlidXRlKG4sRSksdS5mcm9tQnVmZmVyQXR0cmlidXRlKG4seiksZi5mcm9tQnVmZmVyQXR0cmlidXRlKHIsUyksZC5mcm9tQnVmZmVyQXR0cmlidXRlKHIsRSkscC5mcm9tQnVmZmVyQXR0cmlidXRlKHIseiksaC5zdWIobCksdS5zdWIobCksZC5zdWIoZikscC5zdWIoZik7Y29uc3Qgdj0xLyhkLngqcC55LXAueCpkLnkpO2lzRmluaXRlKHYpJiYoeS5jb3B5KGgpLm11bHRpcGx5U2NhbGFyKHAueSkuYWRkU2NhbGVkVmVjdG9yKHUsLWQueSkubXVsdGlwbHlTY2FsYXIodiksbS5jb3B5KHUpLm11bHRpcGx5U2NhbGFyKGQueCkuYWRkU2NhbGVkVmVjdG9yKGgsLXAueCkubXVsdGlwbHlTY2FsYXIodiksYVtTXS5hZGQoeSksYVtFXS5hZGQoeSksYVt6XS5hZGQoeSksY1tTXS5hZGQobSksY1tFXS5hZGQobSksY1t6XS5hZGQobSkpfWxldCBiPXRoaXMuZ3JvdXBzO2IubGVuZ3RoPT09MCYmKGI9W3tzdGFydDowLGNvdW50OnQuY291bnR9XSk7Zm9yKGxldCBTPTAsRT1iLmxlbmd0aDtTPEU7KytTKXtjb25zdCB6PWJbU10sdj16LnN0YXJ0LEM9ei5jb3VudDtmb3IobGV0IFA9dixGPXYrQztQPEY7UCs9MylnKHQuZ2V0WChQKzApLHQuZ2V0WChQKzEpLHQuZ2V0WChQKzIpKX1jb25zdCB3PW5ldyBULHg9bmV3IFQsTT1uZXcgVCxBPW5ldyBUO2Z1bmN0aW9uIF8oUyl7TS5mcm9tQnVmZmVyQXR0cmlidXRlKHMsUyksQS5jb3B5KE0pO2NvbnN0IEU9YVtTXTt3LmNvcHkoRSksdy5zdWIoTS5tdWx0aXBseVNjYWxhcihNLmRvdChFKSkpLm5vcm1hbGl6ZSgpLHguY3Jvc3NWZWN0b3JzKEEsRSk7Y29uc3Qgdj14LmRvdChjW1NdKTwwPy0xOjE7by5zZXRYWVpXKFMsdy54LHcueSx3Lnosdil9Zm9yKGxldCBTPTAsRT1iLmxlbmd0aDtTPEU7KytTKXtjb25zdCB6PWJbU10sdj16LnN0YXJ0LEM9ei5jb3VudDtmb3IobGV0IFA9dixGPXYrQztQPEY7UCs9MylfKHQuZ2V0WChQKzApKSxfKHQuZ2V0WChQKzEpKSxfKHQuZ2V0WChQKzIpKX19Y29tcHV0ZVZlcnRleE5vcm1hbHMoKXtjb25zdCB0PXRoaXMuaW5kZXgsZT10aGlzLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKTtpZihlIT09dm9pZCAwKXtsZXQgbj10aGlzLmdldEF0dHJpYnV0ZSgibm9ybWFsIik7aWYobj09PXZvaWQgMCluPW5ldyB4dChuZXcgRmxvYXQzMkFycmF5KGUuY291bnQqMyksMyksdGhpcy5zZXRBdHRyaWJ1dGUoIm5vcm1hbCIsbik7ZWxzZSBmb3IobGV0IGY9MCxkPW4uY291bnQ7ZjxkO2YrKyluLnNldFhZWihmLDAsMCwwKTtjb25zdCBzPW5ldyBULHI9bmV3IFQsbz1uZXcgVCxhPW5ldyBULGM9bmV3IFQsbD1uZXcgVCxoPW5ldyBULHU9bmV3IFQ7aWYodClmb3IobGV0IGY9MCxkPXQuY291bnQ7ZjxkO2YrPTMpe2NvbnN0IHA9dC5nZXRYKGYrMCkseT10LmdldFgoZisxKSxtPXQuZ2V0WChmKzIpO3MuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHApLHIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHkpLG8uZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLG0pLGguc3ViVmVjdG9ycyhvLHIpLHUuc3ViVmVjdG9ycyhzLHIpLGguY3Jvc3ModSksYS5mcm9tQnVmZmVyQXR0cmlidXRlKG4scCksYy5mcm9tQnVmZmVyQXR0cmlidXRlKG4seSksbC5mcm9tQnVmZmVyQXR0cmlidXRlKG4sbSksYS5hZGQoaCksYy5hZGQoaCksbC5hZGQoaCksbi5zZXRYWVoocCxhLngsYS55LGEueiksbi5zZXRYWVooeSxjLngsYy55LGMueiksbi5zZXRYWVoobSxsLngsbC55LGwueil9ZWxzZSBmb3IobGV0IGY9MCxkPWUuY291bnQ7ZjxkO2YrPTMpcy5mcm9tQnVmZmVyQXR0cmlidXRlKGUsZiswKSxyLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxmKzEpLG8uZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLGYrMiksaC5zdWJWZWN0b3JzKG8sciksdS5zdWJWZWN0b3JzKHMsciksaC5jcm9zcyh1KSxuLnNldFhZWihmKzAsaC54LGgueSxoLnopLG4uc2V0WFlaKGYrMSxoLngsaC55LGgueiksbi5zZXRYWVooZisyLGgueCxoLnksaC56KTt0aGlzLm5vcm1hbGl6ZU5vcm1hbHMoKSxuLm5lZWRzVXBkYXRlPSEwfX1ub3JtYWxpemVOb3JtYWxzKCl7Y29uc3QgdD10aGlzLmF0dHJpYnV0ZXMubm9ybWFsO2ZvcihsZXQgZT0wLG49dC5jb3VudDtlPG47ZSsrKWJ0LmZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKSxidC5ub3JtYWxpemUoKSx0LnNldFhZWihlLGJ0LngsYnQueSxidC56KX10b05vbkluZGV4ZWQoKXtmdW5jdGlvbiB0KGEsYyl7Y29uc3QgbD1hLmFycmF5LGg9YS5pdGVtU2l6ZSx1PWEubm9ybWFsaXplZCxmPW5ldyBsLmNvbnN0cnVjdG9yKGMubGVuZ3RoKmgpO2xldCBkPTAscD0wO2ZvcihsZXQgeT0wLG09Yy5sZW5ndGg7eTxtO3krKyl7YS5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlP2Q9Y1t5XSphLmRhdGEuc3RyaWRlK2Eub2Zmc2V0OmQ9Y1t5XSpoO2ZvcihsZXQgZz0wO2c8aDtnKyspZltwKytdPWxbZCsrXX1yZXR1cm4gbmV3IHh0KGYsaCx1KX1pZih0aGlzLmluZGV4PT09bnVsbClyZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5CdWZmZXJHZW9tZXRyeS50b05vbkluZGV4ZWQoKTogQnVmZmVyR2VvbWV0cnkgaXMgYWxyZWFkeSBub24taW5kZXhlZC4iKSx0aGlzO2NvbnN0IGU9bmV3IHVlLG49dGhpcy5pbmRleC5hcnJheSxzPXRoaXMuYXR0cmlidXRlcztmb3IoY29uc3QgYSBpbiBzKXtjb25zdCBjPXNbYV0sbD10KGMsbik7ZS5zZXRBdHRyaWJ1dGUoYSxsKX1jb25zdCByPXRoaXMubW9ycGhBdHRyaWJ1dGVzO2Zvcihjb25zdCBhIGluIHIpe2NvbnN0IGM9W10sbD1yW2FdO2ZvcihsZXQgaD0wLHU9bC5sZW5ndGg7aDx1O2grKyl7Y29uc3QgZj1sW2hdLGQ9dChmLG4pO2MucHVzaChkKX1lLm1vcnBoQXR0cmlidXRlc1thXT1jfWUubW9ycGhUYXJnZXRzUmVsYXRpdmU9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZTtjb25zdCBvPXRoaXMuZ3JvdXBzO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKyl7Y29uc3QgbD1vW2FdO2UuYWRkR3JvdXAobC5zdGFydCxsLmNvdW50LGwubWF0ZXJpYWxJbmRleCl9cmV0dXJuIGV9dG9KU09OKCl7Y29uc3QgdD17bWV0YWRhdGE6e3ZlcnNpb246NC42LHR5cGU6IkJ1ZmZlckdlb21ldHJ5IixnZW5lcmF0b3I6IkJ1ZmZlckdlb21ldHJ5LnRvSlNPTiJ9fTtpZih0LnV1aWQ9dGhpcy51dWlkLHQudHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJih0Lm5hbWU9dGhpcy5uYW1lKSxPYmplY3Qua2V5cyh0aGlzLnVzZXJEYXRhKS5sZW5ndGg+MCYmKHQudXNlckRhdGE9dGhpcy51c2VyRGF0YSksdGhpcy5wYXJhbWV0ZXJzIT09dm9pZCAwKXtjb25zdCBjPXRoaXMucGFyYW1ldGVycztmb3IoY29uc3QgbCBpbiBjKWNbbF0hPT12b2lkIDAmJih0W2xdPWNbbF0pO3JldHVybiB0fXQuZGF0YT17YXR0cmlidXRlczp7fX07Y29uc3QgZT10aGlzLmluZGV4O2UhPT1udWxsJiYodC5kYXRhLmluZGV4PXt0eXBlOmUuYXJyYXkuY29uc3RydWN0b3IubmFtZSxhcnJheTpBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChlLmFycmF5KX0pO2NvbnN0IG49dGhpcy5hdHRyaWJ1dGVzO2Zvcihjb25zdCBjIGluIG4pe2NvbnN0IGw9bltjXTt0LmRhdGEuYXR0cmlidXRlc1tjXT1sLnRvSlNPTih0LmRhdGEpfWNvbnN0IHM9e307bGV0IHI9ITE7Zm9yKGNvbnN0IGMgaW4gdGhpcy5tb3JwaEF0dHJpYnV0ZXMpe2NvbnN0IGw9dGhpcy5tb3JwaEF0dHJpYnV0ZXNbY10saD1bXTtmb3IobGV0IHU9MCxmPWwubGVuZ3RoO3U8Zjt1Kyspe2NvbnN0IGQ9bFt1XTtoLnB1c2goZC50b0pTT04odC5kYXRhKSl9aC5sZW5ndGg+MCYmKHNbY109aCxyPSEwKX1yJiYodC5kYXRhLm1vcnBoQXR0cmlidXRlcz1zLHQuZGF0YS5tb3JwaFRhcmdldHNSZWxhdGl2ZT10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlKTtjb25zdCBvPXRoaXMuZ3JvdXBzO28ubGVuZ3RoPjAmJih0LmRhdGEuZ3JvdXBzPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobykpKTtjb25zdCBhPXRoaXMuYm91bmRpbmdTcGhlcmU7cmV0dXJuIGEhPT1udWxsJiYodC5kYXRhLmJvdW5kaW5nU3BoZXJlPXtjZW50ZXI6YS5jZW50ZXIudG9BcnJheSgpLHJhZGl1czphLnJhZGl1c30pLHR9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7dGhpcy5pbmRleD1udWxsLHRoaXMuYXR0cmlidXRlcz17fSx0aGlzLm1vcnBoQXR0cmlidXRlcz17fSx0aGlzLmdyb3Vwcz1bXSx0aGlzLmJvdW5kaW5nQm94PW51bGwsdGhpcy5ib3VuZGluZ1NwaGVyZT1udWxsO2NvbnN0IGU9e307dGhpcy5uYW1lPXQubmFtZTtjb25zdCBuPXQuaW5kZXg7biE9PW51bGwmJnRoaXMuc2V0SW5kZXgobi5jbG9uZSgpKTtjb25zdCBzPXQuYXR0cmlidXRlcztmb3IoY29uc3QgbCBpbiBzKXtjb25zdCBoPXNbbF07dGhpcy5zZXRBdHRyaWJ1dGUobCxoLmNsb25lKGUpKX1jb25zdCByPXQubW9ycGhBdHRyaWJ1dGVzO2Zvcihjb25zdCBsIGluIHIpe2NvbnN0IGg9W10sdT1yW2xdO2ZvcihsZXQgZj0wLGQ9dS5sZW5ndGg7ZjxkO2YrKyloLnB1c2godVtmXS5jbG9uZShlKSk7dGhpcy5tb3JwaEF0dHJpYnV0ZXNbbF09aH10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPXQubW9ycGhUYXJnZXRzUmVsYXRpdmU7Y29uc3Qgbz10Lmdyb3Vwcztmb3IobGV0IGw9MCxoPW8ubGVuZ3RoO2w8aDtsKyspe2NvbnN0IHU9b1tsXTt0aGlzLmFkZEdyb3VwKHUuc3RhcnQsdS5jb3VudCx1Lm1hdGVyaWFsSW5kZXgpfWNvbnN0IGE9dC5ib3VuZGluZ0JveDthIT09bnVsbCYmKHRoaXMuYm91bmRpbmdCb3g9YS5jbG9uZSgpKTtjb25zdCBjPXQuYm91bmRpbmdTcGhlcmU7cmV0dXJuIGMhPT1udWxsJiYodGhpcy5ib3VuZGluZ1NwaGVyZT1jLmNsb25lKCkpLHRoaXMuZHJhd1JhbmdlLnN0YXJ0PXQuZHJhd1JhbmdlLnN0YXJ0LHRoaXMuZHJhd1JhbmdlLmNvdW50PXQuZHJhd1JhbmdlLmNvdW50LHRoaXMudXNlckRhdGE9dC51c2VyRGF0YSx0aGlzfWRpc3Bvc2UoKXt0aGlzLmRpc3BhdGNoRXZlbnQoe3R5cGU6ImRpc3Bvc2UifSl9fWNvbnN0IEVjPW5ldyBzdCx1bj1uZXcgYW8scHM9bmV3IGlvLFBjPW5ldyBULHlzPW5ldyBULG1zPW5ldyBULGdzPW5ldyBULHdvPW5ldyBULHhzPW5ldyBULENjPW5ldyBULHdzPW5ldyBUO2NsYXNzIGhmIGV4dGVuZHMgVGV7Y29uc3RydWN0b3IodD1uZXcgdWUsZT1uZXcgcmYpe3N1cGVyKCksdGhpcy5pc01lc2g9ITAsdGhpcy50eXBlPSJNZXNoIix0aGlzLmdlb21ldHJ5PXQsdGhpcy5tYXRlcmlhbD1lLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5PXZvaWQgMCx0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcz12b2lkIDAsdGhpcy51cGRhdGVNb3JwaFRhcmdldHMoKX1jb3B5KHQsZSl7cmV0dXJuIHN1cGVyLmNvcHkodCxlKSx0Lm1vcnBoVGFyZ2V0SW5mbHVlbmNlcyE9PXZvaWQgMCYmKHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPXQubW9ycGhUYXJnZXRJbmZsdWVuY2VzLnNsaWNlKCkpLHQubW9ycGhUYXJnZXREaWN0aW9uYXJ5IT09dm9pZCAwJiYodGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9T2JqZWN0LmFzc2lnbih7fSx0Lm1vcnBoVGFyZ2V0RGljdGlvbmFyeSkpLHRoaXMubWF0ZXJpYWw9QXJyYXkuaXNBcnJheSh0Lm1hdGVyaWFsKT90Lm1hdGVyaWFsLnNsaWNlKCk6dC5tYXRlcmlhbCx0aGlzLmdlb21ldHJ5PXQuZ2VvbWV0cnksdGhpc311cGRhdGVNb3JwaFRhcmdldHMoKXtjb25zdCBlPXRoaXMuZ2VvbWV0cnkubW9ycGhBdHRyaWJ1dGVzLG49T2JqZWN0LmtleXMoZSk7aWYobi5sZW5ndGg+MCl7Y29uc3Qgcz1lW25bMF1dO2lmKHMhPT12b2lkIDApe3RoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPVtdLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5PXt9O2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1zW3JdLm5hbWV8fFN0cmluZyhyKTt0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcy5wdXNoKDApLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5W2FdPXJ9fX19Z2V0VmVydGV4UG9zaXRpb24odCxlKXtjb25zdCBuPXRoaXMuZ2VvbWV0cnkscz1uLmF0dHJpYnV0ZXMucG9zaXRpb24scj1uLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbixvPW4ubW9ycGhUYXJnZXRzUmVsYXRpdmU7ZS5mcm9tQnVmZmVyQXR0cmlidXRlKHMsdCk7Y29uc3QgYT10aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcztpZihyJiZhKXt4cy5zZXQoMCwwLDApO2ZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1hW2NdLHU9cltjXTtoIT09MCYmKHdvLmZyb21CdWZmZXJBdHRyaWJ1dGUodSx0KSxvP3hzLmFkZFNjYWxlZFZlY3Rvcih3byxoKTp4cy5hZGRTY2FsZWRWZWN0b3Iod28uc3ViKGUpLGgpKX1lLmFkZCh4cyl9cmV0dXJuIGV9cmF5Y2FzdCh0LGUpe2NvbnN0IG49dGhpcy5nZW9tZXRyeSxzPXRoaXMubWF0ZXJpYWwscj10aGlzLm1hdHJpeFdvcmxkO3MhPT12b2lkIDAmJihuLmJvdW5kaW5nU3BoZXJlPT09bnVsbCYmbi5jb21wdXRlQm91bmRpbmdTcGhlcmUoKSxwcy5jb3B5KG4uYm91bmRpbmdTcGhlcmUpLHBzLmFwcGx5TWF0cml4NChyKSx1bi5jb3B5KHQucmF5KS5yZWNhc3QodC5uZWFyKSwhKHBzLmNvbnRhaW5zUG9pbnQodW4ub3JpZ2luKT09PSExJiYodW4uaW50ZXJzZWN0U3BoZXJlKHBzLFBjKT09PW51bGx8fHVuLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZChQYyk+ZGkodC5mYXItdC5uZWFyLDIpKSkmJihFYy5jb3B5KHIpLmludmVydCgpLHVuLmNvcHkodC5yYXkpLmFwcGx5TWF0cml4NChFYyksIShuLmJvdW5kaW5nQm94IT09bnVsbCYmdW4uaW50ZXJzZWN0c0JveChuLmJvdW5kaW5nQm94KT09PSExKSYmdGhpcy5fY29tcHV0ZUludGVyc2VjdGlvbnModCxlLHVuKSkpfV9jb21wdXRlSW50ZXJzZWN0aW9ucyh0LGUsbil7bGV0IHM7Y29uc3Qgcj10aGlzLmdlb21ldHJ5LG89dGhpcy5tYXRlcmlhbCxhPXIuaW5kZXgsYz1yLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1yLmF0dHJpYnV0ZXMudXYsaD1yLmF0dHJpYnV0ZXMudXYxLHU9ci5hdHRyaWJ1dGVzLm5vcm1hbCxmPXIuZ3JvdXBzLGQ9ci5kcmF3UmFuZ2U7aWYoYSE9PW51bGwpaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihhLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9YS5nZXRYKHgpLF89YS5nZXRYKHgrMSksUz1hLmdldFgoeCsyKTtzPWJzKHRoaXMsZyx0LG4sbCxoLHUsQSxfLFMpLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYS5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1hLmdldFgobSksdz1hLmdldFgobSsxKSx4PWEuZ2V0WChtKzIpO3M9YnModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX1lbHNlIGlmKGMhPT12b2lkIDApaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihjLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9eCxfPXgrMSxTPXgrMjtzPWJzKHRoaXMsZyx0LG4sbCxoLHUsQSxfLFMpLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYy5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1tLHc9bSsxLHg9bSsyO3M9YnModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX19fWZ1bmN0aW9uIHVmKGksdCxlLG4scyxyLG8sYSl7bGV0IGM7aWYodC5zaWRlPT09MT9jPW4uaW50ZXJzZWN0VHJpYW5nbGUobyxyLHMsITAsYSk6Yz1uLmludGVyc2VjdFRyaWFuZ2xlKHMscixvLHQuc2lkZT09PTAsYSksYz09PW51bGwpcmV0dXJuIG51bGw7d3MuY29weShhKSx3cy5hcHBseU1hdHJpeDQoaS5tYXRyaXhXb3JsZCk7Y29uc3QgbD1lLnJheS5vcmlnaW4uZGlzdGFuY2VUbyh3cyk7cmV0dXJuIGw8ZS5uZWFyfHxsPmUuZmFyP251bGw6e2Rpc3RhbmNlOmwscG9pbnQ6d3MuY2xvbmUoKSxvYmplY3Q6aX19ZnVuY3Rpb24gYnMoaSx0LGUsbixzLHIsbyxhLGMsbCl7aS5nZXRWZXJ0ZXhQb3NpdGlvbihhLHlzKSxpLmdldFZlcnRleFBvc2l0aW9uKGMsbXMpLGkuZ2V0VmVydGV4UG9zaXRpb24obCxncyk7Y29uc3QgaD11ZihpLHQsZSxuLHlzLG1zLGdzLENjKTtpZihoKXtjb25zdCB1PW5ldyBUO2V0LmdldEJhcnljb29yZChDYyx5cyxtcyxncyx1KSxzJiYoaC51dj1ldC5nZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUocyxhLGMsbCx1LG5ldyBSKSksciYmKGgudXYxPWV0LmdldEludGVycG9sYXRlZEF0dHJpYnV0ZShyLGEsYyxsLHUsbmV3IFIpKSxvJiYoaC5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKG8sYSxjLGwsdSxuZXcgVCksaC5ub3JtYWwuZG90KG4uZGlyZWN0aW9uKT4wJiZoLm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGY9e2EsYjpjLGM6bCxub3JtYWw6bmV3IFQsbWF0ZXJpYWxJbmRleDowfTtldC5nZXROb3JtYWwoeXMsbXMsZ3MsZi5ub3JtYWwpLGguZmFjZT1mLGguYmFyeWNvb3JkPXV9cmV0dXJuIGh9Y29uc3QgYm89bmV3IFQsZmY9bmV3IFQsZGY9bmV3IGdlO2NsYXNzIE1ve2NvbnN0cnVjdG9yKHQ9bmV3IFQoMSwwLDApLGU9MCl7dGhpcy5pc1BsYW5lPSEwLHRoaXMubm9ybWFsPXQsdGhpcy5jb25zdGFudD1lfXNldCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbC5jb3B5KHQpLHRoaXMuY29uc3RhbnQ9ZSx0aGlzfXNldENvbXBvbmVudHModCxlLG4scyl7cmV0dXJuIHRoaXMubm9ybWFsLnNldCh0LGUsbiksdGhpcy5jb25zdGFudD1zLHRoaXN9c2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWwuY29weSh0KSx0aGlzLmNvbnN0YW50PS1lLmRvdCh0aGlzLm5vcm1hbCksdGhpc31zZXRGcm9tQ29wbGFuYXJQb2ludHModCxlLG4pe2NvbnN0IHM9Ym8uc3ViVmVjdG9ycyhuLGUpLmNyb3NzKGZmLnN1YlZlY3RvcnModCxlKSkubm9ybWFsaXplKCk7cmV0dXJuIHRoaXMuc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQocyx0KSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMubm9ybWFsLmNvcHkodC5ub3JtYWwpLHRoaXMuY29uc3RhbnQ9dC5jb25zdGFudCx0aGlzfW5vcm1hbGl6ZSgpe2NvbnN0IHQ9MS90aGlzLm5vcm1hbC5sZW5ndGgoKTtyZXR1cm4gdGhpcy5ub3JtYWwubXVsdGlwbHlTY2FsYXIodCksdGhpcy5jb25zdGFudCo9dCx0aGlzfW5lZ2F0ZSgpe3JldHVybiB0aGlzLmNvbnN0YW50Kj0tMSx0aGlzLm5vcm1hbC5uZWdhdGUoKSx0aGlzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdGhpcy5ub3JtYWwuZG90KHQpK3RoaXMuY29uc3RhbnR9ZGlzdGFuY2VUb1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQodC5jZW50ZXIpLXQucmFkaXVzfXByb2plY3RQb2ludCh0LGUpe3JldHVybiBlLmNvcHkodCkuYWRkU2NhbGVkVmVjdG9yKHRoaXMubm9ybWFsLC10aGlzLmRpc3RhbmNlVG9Qb2ludCh0KSl9aW50ZXJzZWN0TGluZSh0LGUpe2NvbnN0IG49dC5kZWx0YShibykscz10aGlzLm5vcm1hbC5kb3Qobik7aWYocz09PTApcmV0dXJuIHRoaXMuZGlzdGFuY2VUb1BvaW50KHQuc3RhcnQpPT09MD9lLmNvcHkodC5zdGFydCk6bnVsbDtjb25zdCByPS0odC5zdGFydC5kb3QodGhpcy5ub3JtYWwpK3RoaXMuY29uc3RhbnQpL3M7cmV0dXJuIHI8MHx8cj4xP251bGw6ZS5jb3B5KHQuc3RhcnQpLmFkZFNjYWxlZFZlY3RvcihuLHIpfWludGVyc2VjdHNMaW5lKHQpe2NvbnN0IGU9dGhpcy5kaXN0YW5jZVRvUG9pbnQodC5zdGFydCksbj10aGlzLmRpc3RhbmNlVG9Qb2ludCh0LmVuZCk7cmV0dXJuIGU8MCYmbj4wfHxuPDAmJmU+MH1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1jb3BsYW5hclBvaW50KHQpe3JldHVybiB0LmNvcHkodGhpcy5ub3JtYWwpLm11bHRpcGx5U2NhbGFyKC10aGlzLmNvbnN0YW50KX1hcHBseU1hdHJpeDQodCxlKXtjb25zdCBuPWV8fGRmLmdldE5vcm1hbE1hdHJpeCh0KSxzPXRoaXMuY29wbGFuYXJQb2ludChibykuYXBwbHlNYXRyaXg0KHQpLHI9dGhpcy5ub3JtYWwuYXBwbHlNYXRyaXgzKG4pLm5vcm1hbGl6ZSgpO3JldHVybiB0aGlzLmNvbnN0YW50PS1zLmRvdChyKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jb25zdGFudC09dC5kb3QodGhpcy5ub3JtYWwpLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lm5vcm1hbC5lcXVhbHModGhpcy5ub3JtYWwpJiZ0LmNvbnN0YW50PT09dGhpcy5jb25zdGFudH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9fWxldCB4ZT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMudHlwZT0iQ3VydmUiLHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPTIwMCx0aGlzLm5lZWRzVXBkYXRlPSExLHRoaXMuY2FjaGVBcmNMZW5ndGhzPW51bGx9Z2V0UG9pbnQoKXtjb25zb2xlLndhcm4oIlRIUkVFLkN1cnZlOiAuZ2V0UG9pbnQoKSBub3QgaW1wbGVtZW50ZWQuIil9Z2V0UG9pbnRBdCh0LGUpe2NvbnN0IG49dGhpcy5nZXRVdG9UbWFwcGluZyh0KTtyZXR1cm4gdGhpcy5nZXRQb2ludChuLGUpfWdldFBvaW50cyh0PTUpe2NvbnN0IGU9W107Zm9yKGxldCBuPTA7bjw9dDtuKyspZS5wdXNoKHRoaXMuZ2V0UG9pbnQobi90KSk7cmV0dXJuIGV9Z2V0U3BhY2VkUG9pbnRzKHQ9NSl7Y29uc3QgZT1bXTtmb3IobGV0IG49MDtuPD10O24rKyllLnB1c2godGhpcy5nZXRQb2ludEF0KG4vdCkpO3JldHVybiBlfWdldExlbmd0aCgpe2NvbnN0IHQ9dGhpcy5nZXRMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19Z2V0TGVuZ3Rocyh0PXRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zKXtpZih0aGlzLmNhY2hlQXJjTGVuZ3RocyYmdGhpcy5jYWNoZUFyY0xlbmd0aHMubGVuZ3RoPT09dCsxJiYhdGhpcy5uZWVkc1VwZGF0ZSlyZXR1cm4gdGhpcy5jYWNoZUFyY0xlbmd0aHM7dGhpcy5uZWVkc1VwZGF0ZT0hMTtjb25zdCBlPVtdO2xldCBuLHM9dGhpcy5nZXRQb2ludCgwKSxyPTA7ZS5wdXNoKDApO2ZvcihsZXQgbz0xO288PXQ7bysrKW49dGhpcy5nZXRQb2ludChvL3QpLHIrPW4uZGlzdGFuY2VUbyhzKSxlLnB1c2gocikscz1uO3JldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3Rocz1lLGV9dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5nZXRMZW5ndGhzKCl9Z2V0VXRvVG1hcHBpbmcodCxlPW51bGwpe2NvbnN0IG49dGhpcy5nZXRMZW5ndGhzKCk7bGV0IHM9MDtjb25zdCByPW4ubGVuZ3RoO2xldCBvO2U/bz1lOm89dCpuW3ItMV07bGV0IGE9MCxjPXItMSxsO2Zvcig7YTw9YzspaWYocz1NYXRoLmZsb29yKGErKGMtYSkvMiksbD1uW3NdLW8sbDwwKWE9cysxO2Vsc2UgaWYobD4wKWM9cy0xO2Vsc2V7Yz1zO2JyZWFrfWlmKHM9YyxuW3NdPT09bylyZXR1cm4gcy8oci0xKTtjb25zdCBoPW5bc10sZj1uW3MrMV0taCxkPShvLWgpL2Y7cmV0dXJuKHMrZCkvKHItMSl9Z2V0VGFuZ2VudCh0LGUpe2xldCBzPXQtMWUtNCxyPXQrMWUtNDtzPDAmJihzPTApLHI+MSYmKHI9MSk7Y29uc3Qgbz10aGlzLmdldFBvaW50KHMpLGE9dGhpcy5nZXRQb2ludChyKSxjPWV8fChvLmlzVmVjdG9yMj9uZXcgUjpuZXcgVCk7cmV0dXJuIGMuY29weShhKS5zdWIobykubm9ybWFsaXplKCksY31nZXRUYW5nZW50QXQodCxlKXtjb25zdCBuPXRoaXMuZ2V0VXRvVG1hcHBpbmcodCk7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudChuLGUpfWNvbXB1dGVGcmVuZXRGcmFtZXModCxlPSExKXtjb25zdCBuPW5ldyBULHM9W10scj1bXSxvPVtdLGE9bmV3IFQsYz1uZXcgc3Q7Zm9yKGxldCBkPTA7ZDw9dDtkKyspe2NvbnN0IHA9ZC90O3NbZF09dGhpcy5nZXRUYW5nZW50QXQocCxuZXcgVCl9clswXT1uZXcgVCxvWzBdPW5ldyBUO2xldCBsPU51bWJlci5NQVhfVkFMVUU7Y29uc3QgaD1NYXRoLmFicyhzWzBdLngpLHU9TWF0aC5hYnMoc1swXS55KSxmPU1hdGguYWJzKHNbMF0ueik7aDw9bCYmKGw9aCxuLnNldCgxLDAsMCkpLHU8PWwmJihsPXUsbi5zZXQoMCwxLDApKSxmPD1sJiZuLnNldCgwLDAsMSksYS5jcm9zc1ZlY3RvcnMoc1swXSxuKS5ub3JtYWxpemUoKSxyWzBdLmNyb3NzVmVjdG9ycyhzWzBdLGEpLG9bMF0uY3Jvc3NWZWN0b3JzKHNbMF0sclswXSk7Zm9yKGxldCBkPTE7ZDw9dDtkKyspe2lmKHJbZF09cltkLTFdLmNsb25lKCksb1tkXT1vW2QtMV0uY2xvbmUoKSxhLmNyb3NzVmVjdG9ycyhzW2QtMV0sc1tkXSksYS5sZW5ndGgoKT5OdW1iZXIuRVBTSUxPTil7YS5ub3JtYWxpemUoKTtjb25zdCBwPU1hdGguYWNvcyhaKHNbZC0xXS5kb3Qoc1tkXSksLTEsMSkpO3JbZF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhhLHApKX1vW2RdLmNyb3NzVmVjdG9ycyhzW2RdLHJbZF0pfWlmKGU9PT0hMCl7bGV0IGQ9TWF0aC5hY29zKFooclswXS5kb3Qoclt0XSksLTEsMSkpO2QvPXQsc1swXS5kb3QoYS5jcm9zc1ZlY3RvcnMoclswXSxyW3RdKSk+MCYmKGQ9LWQpO2ZvcihsZXQgcD0xO3A8PXQ7cCsrKXJbcF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhzW3BdLGQqcCkpLG9bcF0uY3Jvc3NWZWN0b3JzKHNbcF0scltwXSl9cmV0dXJue3RhbmdlbnRzOnMsbm9ybWFsczpyLGJpbm9ybWFsczpvfX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9dC5hcmNMZW5ndGhEaXZpc2lvbnMsdGhpc310b0pTT04oKXtjb25zdCB0PXttZXRhZGF0YTp7dmVyc2lvbjo0LjYsdHlwZToiQ3VydmUiLGdlbmVyYXRvcjoiQ3VydmUudG9KU09OIn19O3JldHVybiB0LmFyY0xlbmd0aERpdmlzaW9ucz10aGlzLmFyY0xlbmd0aERpdmlzaW9ucyx0LnR5cGU9dGhpcy50eXBlLHR9ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPXQuYXJjTGVuZ3RoRGl2aXNpb25zLHRoaXN9fTtjbGFzcyBNcyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0xLHM9MSxyPTAsbz1NYXRoLlBJKjIsYT0hMSxjPTApe3N1cGVyKCksdGhpcy5pc0VsbGlwc2VDdXJ2ZT0hMCx0aGlzLnR5cGU9IkVsbGlwc2VDdXJ2ZSIsdGhpcy5hWD10LHRoaXMuYVk9ZSx0aGlzLnhSYWRpdXM9bix0aGlzLnlSYWRpdXM9cyx0aGlzLmFTdGFydEFuZ2xlPXIsdGhpcy5hRW5kQW5nbGU9byx0aGlzLmFDbG9ja3dpc2U9YSx0aGlzLmFSb3RhdGlvbj1jfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9TWF0aC5QSSoyO2xldCByPXRoaXMuYUVuZEFuZ2xlLXRoaXMuYVN0YXJ0QW5nbGU7Y29uc3Qgbz1NYXRoLmFicyhyKTxOdW1iZXIuRVBTSUxPTjtmb3IoO3I8MDspcis9cztmb3IoO3I+czspci09cztyPE51bWJlci5FUFNJTE9OJiYobz9yPTA6cj1zKSx0aGlzLmFDbG9ja3dpc2U9PT0hMCYmIW8mJihyPT09cz9yPS1zOnI9ci1zKTtjb25zdCBhPXRoaXMuYVN0YXJ0QW5nbGUrdCpyO2xldCBjPXRoaXMuYVgrdGhpcy54UmFkaXVzKk1hdGguY29zKGEpLGw9dGhpcy5hWSt0aGlzLnlSYWRpdXMqTWF0aC5zaW4oYSk7aWYodGhpcy5hUm90YXRpb24hPT0wKXtjb25zdCBoPU1hdGguY29zKHRoaXMuYVJvdGF0aW9uKSx1PU1hdGguc2luKHRoaXMuYVJvdGF0aW9uKSxmPWMtdGhpcy5hWCxkPWwtdGhpcy5hWTtjPWYqaC1kKnUrdGhpcy5hWCxsPWYqdStkKmgrdGhpcy5hWX1yZXR1cm4gbi5zZXQoYyxsKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMuYVg9dC5hWCx0aGlzLmFZPXQuYVksdGhpcy54UmFkaXVzPXQueFJhZGl1cyx0aGlzLnlSYWRpdXM9dC55UmFkaXVzLHRoaXMuYVN0YXJ0QW5nbGU9dC5hU3RhcnRBbmdsZSx0aGlzLmFFbmRBbmdsZT10LmFFbmRBbmdsZSx0aGlzLmFDbG9ja3dpc2U9dC5hQ2xvY2t3aXNlLHRoaXMuYVJvdGF0aW9uPXQuYVJvdGF0aW9uLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC5hWD10aGlzLmFYLHQuYVk9dGhpcy5hWSx0LnhSYWRpdXM9dGhpcy54UmFkaXVzLHQueVJhZGl1cz10aGlzLnlSYWRpdXMsdC5hU3RhcnRBbmdsZT10aGlzLmFTdGFydEFuZ2xlLHQuYUVuZEFuZ2xlPXRoaXMuYUVuZEFuZ2xlLHQuYUNsb2Nrd2lzZT10aGlzLmFDbG9ja3dpc2UsdC5hUm90YXRpb249dGhpcy5hUm90YXRpb24sdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5hWD10LmFYLHRoaXMuYVk9dC5hWSx0aGlzLnhSYWRpdXM9dC54UmFkaXVzLHRoaXMueVJhZGl1cz10LnlSYWRpdXMsdGhpcy5hU3RhcnRBbmdsZT10LmFTdGFydEFuZ2xlLHRoaXMuYUVuZEFuZ2xlPXQuYUVuZEFuZ2xlLHRoaXMuYUNsb2Nrd2lzZT10LmFDbG9ja3dpc2UsdGhpcy5hUm90YXRpb249dC5hUm90YXRpb24sdGhpc319Y2xhc3MgQmMgZXh0ZW5kcyBNc3tjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyl7c3VwZXIodCxlLG4sbixzLHIsbyksdGhpcy5pc0FyY0N1cnZlPSEwLHRoaXMudHlwZT0iQXJjQ3VydmUifX1mdW5jdGlvbiBBbygpe2xldCBpPTAsdD0wLGU9MCxuPTA7ZnVuY3Rpb24gcyhyLG8sYSxjKXtpPXIsdD1hLGU9LTMqciszKm8tMiphLWMsbj0yKnItMipvK2ErY31yZXR1cm57aW5pdENhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsKXtzKG8sYSxsKihhLXIpLGwqKGMtbykpfSxpbml0Tm9udW5pZm9ybUNhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsLGgsdSl7bGV0IGY9KG8tcikvbC0oYS1yKS8obCtoKSsoYS1vKS9oLGQ9KGEtbykvaC0oYy1vKS8oaCt1KSsoYy1hKS91O2YqPWgsZCo9aCxzKG8sYSxmLGQpfSxjYWxjOmZ1bmN0aW9uKHIpe2NvbnN0IG89cipyLGE9bypyO3JldHVybiBpK3QqcitlKm8rbiphfX19Y29uc3QgQXM9bmV3IFQsX289bmV3IEFvLFNvPW5ldyBBbyx2bz1uZXcgQW87Y2xhc3MgRmMgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdLGU9ITEsbj0iY2VudHJpcGV0YWwiLHM9LjUpe3N1cGVyKCksdGhpcy5pc0NhdG11bGxSb21DdXJ2ZTM9ITAsdGhpcy50eXBlPSJDYXRtdWxsUm9tQ3VydmUzIix0aGlzLnBvaW50cz10LHRoaXMuY2xvc2VkPWUsdGhpcy5jdXJ2ZVR5cGU9bix0aGlzLnRlbnNpb249c31nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZSxzPXRoaXMucG9pbnRzLHI9cy5sZW5ndGgsbz0oci0odGhpcy5jbG9zZWQ/MDoxKSkqdDtsZXQgYT1NYXRoLmZsb29yKG8pLGM9by1hO3RoaXMuY2xvc2VkP2ErPWE+MD8wOihNYXRoLmZsb29yKE1hdGguYWJzKGEpL3IpKzEpKnI6Yz09PTAmJmE9PT1yLTEmJihhPXItMixjPTEpO2xldCBsLGg7dGhpcy5jbG9zZWR8fGE+MD9sPXNbKGEtMSklcl06KEFzLnN1YlZlY3RvcnMoc1swXSxzWzFdKS5hZGQoc1swXSksbD1Bcyk7Y29uc3QgdT1zW2Elcl0sZj1zWyhhKzEpJXJdO2lmKHRoaXMuY2xvc2VkfHxhKzI8cj9oPXNbKGErMiklcl06KEFzLnN1YlZlY3RvcnMoc1tyLTFdLHNbci0yXSkuYWRkKHNbci0xXSksaD1BcyksdGhpcy5jdXJ2ZVR5cGU9PT0iY2VudHJpcGV0YWwifHx0aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIil7Y29uc3QgZD10aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIj8uNTouMjU7bGV0IHA9TWF0aC5wb3cobC5kaXN0YW5jZVRvU3F1YXJlZCh1KSxkKSx5PU1hdGgucG93KHUuZGlzdGFuY2VUb1NxdWFyZWQoZiksZCksbT1NYXRoLnBvdyhmLmRpc3RhbmNlVG9TcXVhcmVkKGgpLGQpO3k8MWUtNCYmKHk9MSkscDwxZS00JiYocD15KSxtPDFlLTQmJihtPXkpLF9vLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLngsdS54LGYueCxoLngscCx5LG0pLFNvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnksdS55LGYueSxoLnkscCx5LG0pLHZvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnosdS56LGYueixoLnoscCx5LG0pfWVsc2UgdGhpcy5jdXJ2ZVR5cGU9PT0iY2F0bXVsbHJvbSImJihfby5pbml0Q2F0bXVsbFJvbShsLngsdS54LGYueCxoLngsdGhpcy50ZW5zaW9uKSxTby5pbml0Q2F0bXVsbFJvbShsLnksdS55LGYueSxoLnksdGhpcy50ZW5zaW9uKSx2by5pbml0Q2F0bXVsbFJvbShsLnosdS56LGYueixoLnosdGhpcy50ZW5zaW9uKSk7cmV0dXJuIG4uc2V0KF9vLmNhbGMoYyksU28uY2FsYyhjKSx2by5jYWxjKGMpKSxufWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5jbG9zZWQ9dC5jbG9zZWQsdGhpcy5jdXJ2ZVR5cGU9dC5jdXJ2ZVR5cGUsdGhpcy50ZW5zaW9uPXQudGVuc2lvbix0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdC5jbG9zZWQ9dGhpcy5jbG9zZWQsdC5jdXJ2ZVR5cGU9dGhpcy5jdXJ2ZVR5cGUsdC50ZW5zaW9uPXRoaXMudGVuc2lvbix0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChuZXcgVCgpLmZyb21BcnJheShzKSl9cmV0dXJuIHRoaXMuY2xvc2VkPXQuY2xvc2VkLHRoaXMuY3VydmVUeXBlPXQuY3VydmVUeXBlLHRoaXMudGVuc2lvbj10LnRlbnNpb24sdGhpc319ZnVuY3Rpb24gSWMoaSx0LGUsbixzKXtjb25zdCByPShuLXQpKi41LG89KHMtZSkqLjUsYT1pKmksYz1pKmE7cmV0dXJuKDIqZS0yKm4rcitvKSpjKygtMyplKzMqbi0yKnItbykqYStyKmkrZX1mdW5jdGlvbiBwZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiBlKmUqdH1mdW5jdGlvbiB5ZihpLHQpe3JldHVybiAyKigxLWkpKmkqdH1mdW5jdGlvbiBtZihpLHQpe3JldHVybiBpKmkqdH1mdW5jdGlvbiBNaShpLHQsZSxuKXtyZXR1cm4gcGYoaSx0KSt5ZihpLGUpK21mKGksbil9ZnVuY3Rpb24gZ2YoaSx0KXtjb25zdCBlPTEtaTtyZXR1cm4gZSplKmUqdH1mdW5jdGlvbiB4ZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiAzKmUqZSppKnR9ZnVuY3Rpb24gd2YoaSx0KXtyZXR1cm4gMyooMS1pKSppKmkqdH1mdW5jdGlvbiBiZihpLHQpe3JldHVybiBpKmkqaSp0fWZ1bmN0aW9uIEFpKGksdCxlLG4scyl7cmV0dXJuIGdmKGksdCkreGYoaSxlKSt3ZihpLG4pK2JmKGkscyl9Y2xhc3Mgem8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUixzPW5ldyBSKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlPSEwLHRoaXMudHlwZT0iQ3ViaWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW4sdGhpcy52Mz1zfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyLGE9dGhpcy52MztyZXR1cm4gbi5zZXQoQWkodCxzLngsci54LG8ueCxhLngpLEFpKHQscy55LHIueSxvLnksYS55KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3Mga2MgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCxzPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlMz0hMCx0aGlzLnR5cGU9IkN1YmljQmV6aWVyQ3VydmUzIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bix0aGlzLnYzPXN9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjIsYT10aGlzLnYzO3JldHVybiBuLnNldChBaSh0LHMueCxyLngsby54LGEueCksQWkodCxzLnksci55LG8ueSxhLnkpLEFpKHQscy56LHIueixvLnosYS56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3MgVG8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIpe3N1cGVyKCksdGhpcy5pc0xpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZSIsdGhpcy52MT10LHRoaXMudjI9ZX1nZXRQb2ludCh0LGU9bmV3IFIpe2NvbnN0IG49ZTtyZXR1cm4gdD09PTE/bi5jb3B5KHRoaXMudjIpOihuLmNvcHkodGhpcy52Mikuc3ViKHRoaXMudjEpLG4ubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMudjEpKSxufWdldFBvaW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRQb2ludCh0LGUpfWdldFRhbmdlbnQodCxlPW5ldyBSKXtyZXR1cm4gZS5zdWJWZWN0b3JzKHRoaXMudjIsdGhpcy52MSkubm9ybWFsaXplKCl9Z2V0VGFuZ2VudEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudCh0LGUpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBOYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCl7c3VwZXIoKSx0aGlzLmlzTGluZUN1cnZlMz0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZTMiLHRoaXMudjE9dCx0aGlzLnYyPWV9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWU7cmV0dXJuIHQ9PT0xP24uY29weSh0aGlzLnYyKToobi5jb3B5KHRoaXMudjIpLnN1Yih0aGlzLnYxKSxuLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnYxKSksbn1nZXRQb2ludEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0UG9pbnQodCxlKX1nZXRUYW5nZW50KHQsZT1uZXcgVCl7cmV0dXJuIGUuc3ViVmVjdG9ycyh0aGlzLnYyLHRoaXMudjEpLm5vcm1hbGl6ZSgpfWdldFRhbmdlbnRBdCh0LGUpe3JldHVybiB0aGlzLmdldFRhbmdlbnQodCxlKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3MgRW8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUil7c3VwZXIoKSx0aGlzLmlzUXVhZHJhdGljQmV6aWVyQ3VydmU9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW59Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjI7cmV0dXJuIG4uc2V0KE1pKHQscy54LHIueCxvLngpLE1pKHQscy55LHIueSxvLnkpKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYwPXRoaXMudjAudG9BcnJheSgpLHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBSYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCxuPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNRdWFkcmF0aWNCZXppZXJDdXJ2ZTM9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZTMiLHRoaXMudjA9dCx0aGlzLnYxPWUsdGhpcy52Mj1ufWdldFBvaW50KHQsZT1uZXcgVCl7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyO3JldHVybiBuLnNldChNaSh0LHMueCxyLngsby54KSxNaSh0LHMueSxyLnksby55KSxNaSh0LHMueixyLnosby56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3MgUG8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdKXtzdXBlcigpLHRoaXMuaXNTcGxpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IlNwbGluZUN1cnZlIix0aGlzLnBvaW50cz10fWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy5wb2ludHMscj0ocy5sZW5ndGgtMSkqdCxvPU1hdGguZmxvb3IociksYT1yLW8sYz1zW289PT0wP286by0xXSxsPXNbb10saD1zW28+cy5sZW5ndGgtMj9zLmxlbmd0aC0xOm8rMV0sdT1zW28+cy5sZW5ndGgtMz9zLmxlbmd0aC0xOm8rMl07cmV0dXJuIG4uc2V0KEljKGEsYy54LGwueCxoLngsdS54KSxJYyhhLGMueSxsLnksaC55LHUueSkpLG59Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gobmV3IFIoKS5mcm9tQXJyYXkocykpfXJldHVybiB0aGlzfX12YXIgTGM9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQXJjQ3VydmU6QmMsQ2F0bXVsbFJvbUN1cnZlMzpGYyxDdWJpY0JlemllckN1cnZlOnpvLEN1YmljQmV6aWVyQ3VydmUzOmtjLEVsbGlwc2VDdXJ2ZTpNcyxMaW5lQ3VydmU6VG8sTGluZUN1cnZlMzpOYyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTpFbyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTM6UmMsU3BsaW5lQ3VydmU6UG99KTtjbGFzcyBNZiBleHRlbmRzIHhle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9IkN1cnZlUGF0aCIsdGhpcy5jdXJ2ZXM9W10sdGhpcy5hdXRvQ2xvc2U9ITF9YWRkKHQpe3RoaXMuY3VydmVzLnB1c2godCl9Y2xvc2VQYXRoKCl7Y29uc3QgdD10aGlzLmN1cnZlc1swXS5nZXRQb2ludCgwKSxlPXRoaXMuY3VydmVzW3RoaXMuY3VydmVzLmxlbmd0aC0xXS5nZXRQb2ludCgxKTtpZighdC5lcXVhbHMoZSkpe2NvbnN0IG49dC5pc1ZlY3RvcjI9PT0hMD8iTGluZUN1cnZlIjoiTGluZUN1cnZlMyI7dGhpcy5jdXJ2ZXMucHVzaChuZXcgTGNbbl0oZSx0KSl9cmV0dXJuIHRoaXN9Z2V0UG9pbnQodCxlKXtjb25zdCBuPXQqdGhpcy5nZXRMZW5ndGgoKSxzPXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7bGV0IHI9MDtmb3IoO3I8cy5sZW5ndGg7KXtpZihzW3JdPj1uKXtjb25zdCBvPXNbcl0tbixhPXRoaXMuY3VydmVzW3JdLGM9YS5nZXRMZW5ndGgoKSxsPWM9PT0wPzA6MS1vL2M7cmV0dXJuIGEuZ2V0UG9pbnRBdChsLGUpfXIrK31yZXR1cm4gbnVsbH1nZXRMZW5ndGgoKXtjb25zdCB0PXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5jYWNoZUxlbmd0aHM9bnVsbCx0aGlzLmdldEN1cnZlTGVuZ3RocygpfWdldEN1cnZlTGVuZ3Rocygpe2lmKHRoaXMuY2FjaGVMZW5ndGhzJiZ0aGlzLmNhY2hlTGVuZ3Rocy5sZW5ndGg9PT10aGlzLmN1cnZlcy5sZW5ndGgpcmV0dXJuIHRoaXMuY2FjaGVMZW5ndGhzO2NvbnN0IHQ9W107bGV0IGU9MDtmb3IobGV0IG49MCxzPXRoaXMuY3VydmVzLmxlbmd0aDtuPHM7bisrKWUrPXRoaXMuY3VydmVzW25dLmdldExlbmd0aCgpLHQucHVzaChlKTtyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM9dCx0fWdldFNwYWNlZFBvaW50cyh0PTQwKXtjb25zdCBlPVtdO2ZvcihsZXQgbj0wO248PXQ7bisrKWUucHVzaCh0aGlzLmdldFBvaW50KG4vdCkpO3JldHVybiB0aGlzLmF1dG9DbG9zZSYmZS5wdXNoKGVbMF0pLGV9Z2V0UG9pbnRzKHQ9MTIpe2NvbnN0IGU9W107bGV0IG47Zm9yKGxldCBzPTAscj10aGlzLmN1cnZlcztzPHIubGVuZ3RoO3MrKyl7Y29uc3Qgbz1yW3NdLGE9by5pc0VsbGlwc2VDdXJ2ZT90KjI6by5pc0xpbmVDdXJ2ZXx8by5pc0xpbmVDdXJ2ZTM/MTpvLmlzU3BsaW5lQ3VydmU/dCpvLnBvaW50cy5sZW5ndGg6dCxjPW8uZ2V0UG9pbnRzKGEpO2ZvcihsZXQgbD0wO2w8Yy5sZW5ndGg7bCsrKXtjb25zdCBoPWNbbF07biYmbi5lcXVhbHMoaCl8fChlLnB1c2goaCksbj1oKX19cmV0dXJuIHRoaXMuYXV0b0Nsb3NlJiZlLmxlbmd0aD4xJiYhZVtlLmxlbmd0aC0xXS5lcXVhbHMoZVswXSkmJmUucHVzaChlWzBdKSxlfWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5hdXRvQ2xvc2U9dC5hdXRvQ2xvc2UsdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3QuYXV0b0Nsb3NlPXRoaXMuYXV0b0Nsb3NlLHQuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dGhpcy5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dGhpcy5jdXJ2ZXNbZV07dC5jdXJ2ZXMucHVzaChzLnRvSlNPTigpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLmF1dG9DbG9zZT10LmF1dG9DbG9zZSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gobmV3IExjW3MudHlwZV0oKS5mcm9tSlNPTihzKSl9cmV0dXJuIHRoaXN9fWxldCBPYz1jbGFzcyBleHRlbmRzIE1me2NvbnN0cnVjdG9yKHQpe3N1cGVyKCksdGhpcy50eXBlPSJQYXRoIix0aGlzLmN1cnJlbnRQb2ludD1uZXcgUix0JiZ0aGlzLnNldEZyb21Qb2ludHModCl9c2V0RnJvbVBvaW50cyh0KXt0aGlzLm1vdmVUbyh0WzBdLngsdFswXS55KTtmb3IobGV0IGU9MSxuPXQubGVuZ3RoO2U8bjtlKyspdGhpcy5saW5lVG8odFtlXS54LHRbZV0ueSk7cmV0dXJuIHRoaXN9bW92ZVRvKHQsZSl7cmV0dXJuIHRoaXMuY3VycmVudFBvaW50LnNldCh0LGUpLHRoaXN9bGluZVRvKHQsZSl7Y29uc3Qgbj1uZXcgVG8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5zZXQodCxlKSx0aGlzfXF1YWRyYXRpY0N1cnZlVG8odCxlLG4scyl7Y29uc3Qgcj1uZXcgRW8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scykpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKHIpLHRoaXMuY3VycmVudFBvaW50LnNldChuLHMpLHRoaXN9YmV6aWVyQ3VydmVUbyh0LGUsbixzLHIsbyl7Y29uc3QgYT1uZXcgem8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scyksbmV3IFIocixvKSk7cmV0dXJuIHRoaXMuY3VydmVzLnB1c2goYSksdGhpcy5jdXJyZW50UG9pbnQuc2V0KHIsbyksdGhpc31zcGxpbmVUaHJ1KHQpe2NvbnN0IGU9W3RoaXMuY3VycmVudFBvaW50LmNsb25lKCldLmNvbmNhdCh0KSxuPW5ldyBQbyhlKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5jb3B5KHRbdC5sZW5ndGgtMV0pLHRoaXN9YXJjKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMuY3VycmVudFBvaW50LngsYz10aGlzLmN1cnJlbnRQb2ludC55O3JldHVybiB0aGlzLmFic2FyYyh0K2EsZStjLG4scyxyLG8pLHRoaXN9YWJzYXJjKHQsZSxuLHMscixvKXtyZXR1cm4gdGhpcy5hYnNlbGxpcHNlKHQsZSxuLG4scyxyLG8pLHRoaXN9ZWxsaXBzZSh0LGUsbixzLHIsbyxhLGMpe2NvbnN0IGw9dGhpcy5jdXJyZW50UG9pbnQueCxoPXRoaXMuY3VycmVudFBvaW50Lnk7cmV0dXJuIHRoaXMuYWJzZWxsaXBzZSh0K2wsZStoLG4scyxyLG8sYSxjKSx0aGlzfWFic2VsbGlwc2UodCxlLG4scyxyLG8sYSxjKXtjb25zdCBsPW5ldyBNcyh0LGUsbixzLHIsbyxhLGMpO2lmKHRoaXMuY3VydmVzLmxlbmd0aD4wKXtjb25zdCB1PWwuZ2V0UG9pbnQoMCk7dS5lcXVhbHModGhpcy5jdXJyZW50UG9pbnQpfHx0aGlzLmxpbmVUbyh1LngsdS55KX10aGlzLmN1cnZlcy5wdXNoKGwpO2NvbnN0IGg9bC5nZXRQb2ludCgxKTtyZXR1cm4gdGhpcy5jdXJyZW50UG9pbnQuY29weShoKSx0aGlzfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5jdXJyZW50UG9pbnQuY29weSh0LmN1cnJlbnRQb2ludCksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LmN1cnJlbnRQb2ludD10aGlzLmN1cnJlbnRQb2ludC50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5jdXJyZW50UG9pbnQuZnJvbUFycmF5KHQuY3VycmVudFBvaW50KSx0aGlzfX07Y2xhc3MgRGMgZXh0ZW5kcyBPY3tjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLnV1aWQ9Qm4oKSx0aGlzLnR5cGU9IlNoYXBlIix0aGlzLmhvbGVzPVtdfWdldFBvaW50c0hvbGVzKHQpe2NvbnN0IGU9W107Zm9yKGxldCBuPTAscz10aGlzLmhvbGVzLmxlbmd0aDtuPHM7bisrKWVbbl09dGhpcy5ob2xlc1tuXS5nZXRQb2ludHModCk7cmV0dXJuIGV9ZXh0cmFjdFBvaW50cyh0KXtyZXR1cm57c2hhcGU6dGhpcy5nZXRQb2ludHModCksaG9sZXM6dGhpcy5nZXRQb2ludHNIb2xlcyh0KX19Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10LmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuaG9sZXNbZV07dGhpcy5ob2xlcy5wdXNoKHMuY2xvbmUoKSl9cmV0dXJuIHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnV1aWQ9dGhpcy51dWlkLHQuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10aGlzLmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMuaG9sZXNbZV07dC5ob2xlcy5wdXNoKHMudG9KU09OKCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMudXVpZD10LnV1aWQsdGhpcy5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXQuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5ob2xlc1tlXTt0aGlzLmhvbGVzLnB1c2gobmV3IE9jKCkuZnJvbUpTT04ocykpfXJldHVybiB0aGlzfX1mdW5jdGlvbiBBZihpLHQsZT0yKXtjb25zdCBuPXQmJnQubGVuZ3RoLHM9bj90WzBdKmU6aS5sZW5ndGg7bGV0IHI9JGMoaSwwLHMsZSwhMCk7Y29uc3Qgbz1bXTtpZighcnx8ci5uZXh0PT09ci5wcmV2KXJldHVybiBvO2xldCBhLGMsbDtpZihuJiYocj1UZihpLHQscixlKSksaS5sZW5ndGg+ODAqZSl7YT0xLzAsYz0xLzA7bGV0IGg9LTEvMCx1PS0xLzA7Zm9yKGxldCBmPWU7ZjxzO2YrPWUpe2NvbnN0IGQ9aVtmXSxwPWlbZisxXTtkPGEmJihhPWQpLHA8YyYmKGM9cCksZD5oJiYoaD1kKSxwPnUmJih1PXApfWw9TWF0aC5tYXgoaC1hLHUtYyksbD1sIT09MD8zMjc2Ny9sOjB9cmV0dXJuIF9pKHIsbyxlLGEsYyxsLDApLG99ZnVuY3Rpb24gJGMoaSx0LGUsbixzKXtsZXQgcjtpZihzPT09T2YoaSx0LGUsbik+MClmb3IobGV0IG89dDtvPGU7bys9bilyPUhjKG8vbnwwLGlbb10saVtvKzFdLHIpO2Vsc2UgZm9yKGxldCBvPWUtbjtvPj10O28tPW4pcj1IYyhvL258MCxpW29dLGlbbysxXSxyKTtyZXR1cm4gciYmcW4ocixyLm5leHQpJiYoemkocikscj1yLm5leHQpLHJ9ZnVuY3Rpb24gZm4oaSx0KXtpZighaSlyZXR1cm4gaTt0fHwodD1pKTtsZXQgZT1pLG47ZG8gaWYobj0hMSwhZS5zdGVpbmVyJiYocW4oZSxlLm5leHQpfHxydChlLnByZXYsZSxlLm5leHQpPT09MCkpe2lmKHppKGUpLGU9dD1lLnByZXYsZT09PWUubmV4dClicmVhaztuPSEwfWVsc2UgZT1lLm5leHQ7d2hpbGUobnx8ZSE9PXQpO3JldHVybiB0fWZ1bmN0aW9uIF9pKGksdCxlLG4scyxyLG8pe2lmKCFpKXJldHVybjshbyYmciYmRmYoaSxuLHMscik7bGV0IGE9aTtmb3IoO2kucHJldiE9PWkubmV4dDspe2NvbnN0IGM9aS5wcmV2LGw9aS5uZXh0O2lmKHI/U2YoaSxuLHMscik6X2YoaSkpe3QucHVzaChjLmksaS5pLGwuaSksemkoaSksaT1sLm5leHQsYT1sLm5leHQ7Y29udGludWV9aWYoaT1sLGk9PT1hKXtvP289PT0xPyhpPXZmKGZuKGkpLHQpLF9pKGksdCxlLG4scyxyLDIpKTpvPT09MiYmemYoaSx0LGUsbixzLHIpOl9pKGZuKGkpLHQsZSxuLHMsciwxKTticmVha319fWZ1bmN0aW9uIF9mKGkpe2NvbnN0IHQ9aS5wcmV2LGU9aSxuPWkubmV4dDtpZihydCh0LGUsbik+PTApcmV0dXJuITE7Y29uc3Qgcz10Lngscj1lLngsbz1uLngsYT10LnksYz1lLnksbD1uLnksaD1NYXRoLm1pbihzLHIsbyksdT1NYXRoLm1pbihhLGMsbCksZj1NYXRoLm1heChzLHIsbyksZD1NYXRoLm1heChhLGMsbCk7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJlNpKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZydChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIFNmKGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihydChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1NYXRoLm1pbihhLGMsbCkscD1NYXRoLm1pbihoLHUsZikseT1NYXRoLm1heChhLGMsbCksbT1NYXRoLm1heChoLHUsZiksZz1DbyhkLHAsdCxlLG4pLGI9Q28oeSxtLHQsZSxuKTtsZXQgdz1pLnByZXZaLHg9aS5uZXh0Wjtmb3IoO3cmJncuej49ZyYmeCYmeC56PD1iOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJlNpKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wfHwodz13LnByZXZaLHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZTaShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MCkpcmV0dXJuITE7eD14Lm5leHRafWZvcig7dyYmdy56Pj1nOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJlNpKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wKXJldHVybiExO3c9dy5wcmV2Wn1mb3IoO3gmJnguejw9Yjspe2lmKHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZTaShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MClyZXR1cm4hMTt4PXgubmV4dFp9cmV0dXJuITB9ZnVuY3Rpb24gdmYoaSx0KXtsZXQgZT1pO2Rve2NvbnN0IG49ZS5wcmV2LHM9ZS5uZXh0Lm5leHQ7IXFuKG4scykmJlZjKG4sZSxlLm5leHQscykmJnZpKG4scykmJnZpKHMsbikmJih0LnB1c2gobi5pLGUuaSxzLmkpLHppKGUpLHppKGUubmV4dCksZT1pPXMpLGU9ZS5uZXh0fXdoaWxlKGUhPT1pKTtyZXR1cm4gZm4oZSl9ZnVuY3Rpb24gemYoaSx0LGUsbixzLHIpe2xldCBvPWk7ZG97bGV0IGE9by5uZXh0Lm5leHQ7Zm9yKDthIT09by5wcmV2Oyl7aWYoby5pIT09YS5pJiZOZihvLGEpKXtsZXQgYz1xYyhvLGEpO289Zm4obyxvLm5leHQpLGM9Zm4oYyxjLm5leHQpLF9pKG8sdCxlLG4scyxyLDApLF9pKGMsdCxlLG4scyxyLDApO3JldHVybn1hPWEubmV4dH1vPW8ubmV4dH13aGlsZShvIT09aSl9ZnVuY3Rpb24gVGYoaSx0LGUsbil7Y29uc3Qgcz1bXTtmb3IobGV0IHI9MCxvPXQubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9dFtyXSpuLGM9cjxvLTE/dFtyKzFdKm46aS5sZW5ndGgsbD0kYyhpLGEsYyxuLCExKTtsPT09bC5uZXh0JiYobC5zdGVpbmVyPSEwKSxzLnB1c2goa2YobCkpfXMuc29ydChFZik7Zm9yKGxldCByPTA7cjxzLmxlbmd0aDtyKyspZT1QZihzW3JdLGUpO3JldHVybiBlfWZ1bmN0aW9uIEVmKGksdCl7bGV0IGU9aS54LXQueDtpZihlPT09MCYmKGU9aS55LXQueSxlPT09MCkpe2NvbnN0IG49KGkubmV4dC55LWkueSkvKGkubmV4dC54LWkueCkscz0odC5uZXh0LnktdC55KS8odC5uZXh0LngtdC54KTtlPW4tc31yZXR1cm4gZX1mdW5jdGlvbiBQZihpLHQpe2NvbnN0IGU9Q2YoaSx0KTtpZighZSlyZXR1cm4gdDtjb25zdCBuPXFjKGUsaSk7cmV0dXJuIGZuKG4sbi5uZXh0KSxmbihlLGUubmV4dCl9ZnVuY3Rpb24gQ2YoaSx0KXtsZXQgZT10O2NvbnN0IG49aS54LHM9aS55O2xldCByPS0xLzAsbztpZihxbihpLGUpKXJldHVybiBlO2Rve2lmKHFuKGksZS5uZXh0KSlyZXR1cm4gZS5uZXh0O2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZVYyhzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTt2aShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmQmYobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIEJmKGksdCl7cmV0dXJuIHJ0KGkucHJldixpLHQucHJldik8MCYmcnQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIEZmKGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1DbyhzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwsSWYocyl9ZnVuY3Rpb24gSWYoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBDbyhpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24ga2YoaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIFVjKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiBTaShpLHQsZSxuLHMscixvLGEpe3JldHVybiEoaT09PW8mJnQ9PT1hKSYmVWMoaSx0LGUsbixzLHIsbyxhKX1mdW5jdGlvbiBOZihpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFSZihpLHQpJiYodmkoaSx0KSYmdmkodCxpKSYmTGYoaSx0KSYmKHJ0KGkucHJldixpLHQucHJldil8fHJ0KGksdC5wcmV2LHQpKXx8cW4oaSx0KSYmcnQoaS5wcmV2LGksaS5uZXh0KT4wJiZydCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIHJ0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24gcW4oaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gVmMoaSx0LGUsbil7Y29uc3Qgcz1TcyhydChpLHQsZSkpLHI9U3MocnQoaSx0LG4pKSxvPVNzKHJ0KGUsbixpKSksYT1TcyhydChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJl9zKGksZSx0KXx8cj09PTAmJl9zKGksbix0KXx8bz09PTAmJl9zKGUsaSxuKXx8YT09PTAmJl9zKGUsdCxuKSl9ZnVuY3Rpb24gX3MoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIFNzKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBSZihpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmVmMoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gdmkoaSx0KXtyZXR1cm4gcnQoaS5wcmV2LGksaS5uZXh0KTwwP3J0KGksdCxpLm5leHQpPj0wJiZydChpLGkucHJldix0KT49MDpydChpLHQsaS5wcmV2KTwwfHxydChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIExmKGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gcWMoaSx0KXtjb25zdCBlPUJvKGkuaSxpLngsaS55KSxuPUJvKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBIYyhpLHQsZSxuKXtjb25zdCBzPUJvKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gemkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBCbyhpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gT2YoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWNsYXNzIERme3N0YXRpYyB0cmlhbmd1bGF0ZSh0LGUsbj0yKXtyZXR1cm4gQWYodCxlLG4pfX1jbGFzcyBIbntzdGF0aWMgYXJlYSh0KXtjb25zdCBlPXQubGVuZ3RoO2xldCBuPTA7Zm9yKGxldCBzPWUtMSxyPTA7cjxlO3M9cisrKW4rPXRbc10ueCp0W3JdLnktdFtyXS54KnRbc10ueTtyZXR1cm4gbiouNX1zdGF0aWMgaXNDbG9ja1dpc2UodCl7cmV0dXJuIEhuLmFyZWEodCk8MH1zdGF0aWMgdHJpYW5ndWxhdGVTaGFwZSh0LGUpe2NvbnN0IG49W10scz1bXSxyPVtdO1djKHQpLEdjKG4sdCk7bGV0IG89dC5sZW5ndGg7ZS5mb3JFYWNoKFdjKTtmb3IobGV0IGM9MDtjPGUubGVuZ3RoO2MrKylzLnB1c2gobyksbys9ZVtjXS5sZW5ndGgsR2MobixlW2NdKTtjb25zdCBhPURmLnRyaWFuZ3VsYXRlKG4scyk7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKz0zKXIucHVzaChhLnNsaWNlKGMsYyszKSk7cmV0dXJuIHJ9fWZ1bmN0aW9uIFdjKGkpe2NvbnN0IHQ9aS5sZW5ndGg7dD4yJiZpW3QtMV0uZXF1YWxzKGlbMF0pJiZpLnBvcCgpfWZ1bmN0aW9uIEdjKGksdCl7Zm9yKGxldCBlPTA7ZTx0Lmxlbmd0aDtlKyspaS5wdXNoKHRbZV0ueCksaS5wdXNoKHRbZV0ueSl9Y2xhc3MgRm8gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PTEsZT0xLG49MSxzPTEpe3N1cGVyKCksdGhpcy50eXBlPSJQbGFuZUdlb21ldHJ5Iix0aGlzLnBhcmFtZXRlcnM9e3dpZHRoOnQsaGVpZ2h0OmUsd2lkdGhTZWdtZW50czpuLGhlaWdodFNlZ21lbnRzOnN9O2NvbnN0IHI9dC8yLG89ZS8yLGE9TWF0aC5mbG9vcihuKSxjPU1hdGguZmxvb3IocyksbD1hKzEsaD1jKzEsdT10L2EsZj1lL2MsZD1bXSxwPVtdLHk9W10sbT1bXTtmb3IobGV0IGc9MDtnPGg7ZysrKXtjb25zdCBiPWcqZi1vO2ZvcihsZXQgdz0wO3c8bDt3Kyspe2NvbnN0IHg9dyp1LXI7cC5wdXNoKHgsLWIsMCkseS5wdXNoKDAsMCwxKSxtLnB1c2gody9hKSxtLnB1c2goMS1nL2MpfX1mb3IobGV0IGc9MDtnPGM7ZysrKWZvcihsZXQgYj0wO2I8YTtiKyspe2NvbnN0IHc9YitsKmcseD1iK2wqKGcrMSksTT1iKzErbCooZysxKSxBPWIrMStsKmc7ZC5wdXNoKHcseCxBKSxkLnB1c2goeCxNLEEpfXRoaXMuc2V0SW5kZXgoZCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQ2UocCwzKSksdGhpcy5zZXRBdHRyaWJ1dGUoIm5vcm1hbCIsbmV3IENlKHksMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IENlKG0sMikpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXN0YXRpYyBmcm9tSlNPTih0KXtyZXR1cm4gbmV3IEZvKHQud2lkdGgsdC5oZWlnaHQsdC53aWR0aFNlZ21lbnRzLHQuaGVpZ2h0U2VnbWVudHMpfX1jb25zdCBaYz1uZXcgVCx2cz1uZXcgVDtjbGFzcyBRdHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQpe3RoaXMuc3RhcnQ9dCx0aGlzLmVuZD1lfXNldCh0LGUpe3JldHVybiB0aGlzLnN0YXJ0LmNvcHkodCksdGhpcy5lbmQuY29weShlKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuc3RhcnQuY29weSh0LnN0YXJ0KSx0aGlzLmVuZC5jb3B5KHQuZW5kKSx0aGlzfWdldENlbnRlcih0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuc3RhcnQsdGhpcy5lbmQpLm11bHRpcGx5U2NhbGFyKC41KX1kZWx0YSh0KXtyZXR1cm4gdC5zdWJWZWN0b3JzKHRoaXMuZW5kLHRoaXMuc3RhcnQpfWRpc3RhbmNlU3EoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmVuZCl9ZGlzdGFuY2UoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvKHRoaXMuZW5kKX1hdCh0LGUpe3JldHVybiB0aGlzLmRlbHRhKGUpLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnN0YXJ0KX1jbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyKHQsZSl7WmMuc3ViVmVjdG9ycyh0LHRoaXMuc3RhcnQpLHZzLnN1YlZlY3RvcnModGhpcy5lbmQsdGhpcy5zdGFydCk7Y29uc3Qgbj12cy5kb3QodnMpO2xldCByPXZzLmRvdChaYykvbjtyZXR1cm4gZSYmKHI9WihyLDAsMSkpLHJ9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUsbil7Y29uc3Qgcz10aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxlKTtyZXR1cm4gdGhpcy5kZWx0YShuKS5tdWx0aXBseVNjYWxhcihzKS5hZGQodGhpcy5zdGFydCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLnN0YXJ0LmFwcGx5TWF0cml4NCh0KSx0aGlzLmVuZC5hcHBseU1hdHJpeDQodCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQuc3RhcnQuZXF1YWxzKHRoaXMuc3RhcnQpJiZ0LmVuZC5lcXVhbHModGhpcy5lbmQpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX19dHlwZW9mIF9fVEhSRUVfREVWVE9PTFNfXyE9InVuZGVmaW5lZCImJl9fVEhSRUVfREVWVE9PTFNfXy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudCgicmVnaXN0ZXIiLHtkZXRhaWw6e3JldmlzaW9uOkp9fSkpLHR5cGVvZiB3aW5kb3chPSJ1bmRlZmluZWQiJiYod2luZG93Ll9fVEhSRUVfXz9jb25zb2xlLndhcm4oIldBUk5JTkc6IE11bHRpcGxlIGluc3RhbmNlcyBvZiBUaHJlZS5qcyBiZWluZyBpbXBvcnRlZC4iKTp3aW5kb3cuX19USFJFRV9fPUopO2NvbnN0IGRuPW5ldyBNYXAsJGY9KGk9e30pPT4oe2dlbmVyYXRlVG9wVVYodCxlLG4scyxyKXtjb25zdCBvPWVbbiozXSxhPWVbbiozKzFdLGM9ZVtzKjNdLGw9ZVtzKjMrMV0saD1lW3IqM10sdT1lW3IqMysxXTtsZXQgZjtpZihkbi5oYXModCkpZj1kbi5nZXQodCk7ZWxzZXtsZXQgbT1pLmJveDM7aWYoIW0pe209bmV3IGd0O2NvbnN0IHc9dC5wYXJhbWV0ZXJzLnNoYXBlcy5nZXRQb2ludHMoKS5tYXAoeD0+W3gueCx4LnksMF0pLmZsYXQoKTttLnNldEZyb21BcnJheSh3KX1jb25zdCBnPW0uZ2V0U2l6ZShuZXcgVCk7aS5zcGxpdCYmKGcueS89aS5zcGxpdCksZj17Ym94Om0sc2l6ZTpnfSxkbi5zZXQodCxmKX1jb25zdHtib3g6ZCxzaXplOnB9PWYseT1pLnNwbGl0PzEtaS5zcGxpdDowO3JldHVybltuZXcgUigoby1kLm1pbi54KS9wLngsKGEtZC5taW4ueSkvcC55K3kpLG5ldyBSKChjLWQubWluLngpL3AueCwobC1kLm1pbi55KS9wLnkreSksbmV3IFIoKGgtZC5taW4ueCkvcC54LCh1LWQubWluLnkpL3AueSt5KV19LGdlbmVyYXRlU2lkZVdhbGxVVih0LGUsbixzLHIsbyl7Y29uc3QgYT1lW24qM10sYz1lW24qMysxXSxsPWVbbiozKzJdLGg9ZVtzKjNdLHU9ZVtzKjMrMV0sZj1lW3MqMysyXSxkPWVbciozXSxwPWVbciozKzFdLHk9ZVtyKjMrMl0sbT1lW28qM10sZz1lW28qMysxXSxiPWVbbyozKzJdO2xldCB3O2lmKGRuLmhhcyhlKSl3PWRuLmdldChlKTtlbHNle2NvbnN0IEE9bmV3IGd0O0Euc2V0RnJvbUFycmF5KGUpO2NvbnN0IF89QS5nZXRTaXplKG5ldyBUKTtpLnNwbGl0JiYoXy56Lz0xLWkuc3BsaXQpLGkuc2lkZVJlcGVhdCYmKF8uei89aS5zaWRlUmVwZWF0KSx3PXtib3g6QSxzaXplOl99LGRuLnNldChlLHcpfWNvbnN0e2JveDp4LHNpemU6TX09dztyZXR1cm4gTWF0aC5hYnMoYy11KTxNYXRoLmFicyhhLWgpP1tuZXcgUigoYS14Lm1pbi54KS9NLngsKGwteC5taW4ueikvTS56KSxuZXcgUigoaC14Lm1pbi54KS9NLngsKGYteC5taW4ueikvTS56KSxuZXcgUigoZC14Lm1pbi54KS9NLngsKHkteC5taW4ueikvTS56KSxuZXcgUigobS14Lm1pbi54KS9NLngsKGIteC5taW4ueikvTS56KV06W25ldyBSKChjLXgubWluLnkpL00ueSwobC14Lm1pbi56KS9NLnopLG5ldyBSKCh1LXgubWluLnkpL00ueSwoZi14Lm1pbi56KS9NLnopLG5ldyBSKChwLXgubWluLnkpL00ueSwoeS14Lm1pbi56KS9NLnopLG5ldyBSKChnLXgubWluLnkpL00ueSwoYi14Lm1pbi56KS9NLnopXX19KSxVZj0oKT0+e2RuLmNsZWFyKCl9LFZmPXtBcmNDdXJ2ZTpCYyxDYXRtdWxsUm9tQ3VydmUzOkZjLEN1YmljQmV6aWVyQ3VydmU6em8sQ3ViaWNCZXppZXJDdXJ2ZTM6a2MsRWxsaXBzZUN1cnZlOk1zLExpbmVDdXJ2ZTpUbyxMaW5lQ3VydmUzOk5jLFF1YWRyYXRpY0JlemllckN1cnZlOkVvLFF1YWRyYXRpY0JlemllckN1cnZlMzpSYyxTcGxpbmVDdXJ2ZTpQb307Y2xhc3MgV24gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PW5ldyBEYyhbbmV3IFIoLjUsLjUpLG5ldyBSKC0uNSwuNSksbmV3IFIoLS41LC0uNSksbmV3IFIoLjUsLS41KV0pLGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJFeHRydWRlR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz17c2hhcGVzOnQsb3B0aW9uczplfSx0PUFycmF5LmlzQXJyYXkodCk/dDpbdF07Y29uc3Qgbj10aGlzLHM9W10scj1bXTtmb3IobGV0IGE9MCxjPXQubGVuZ3RoO2E8YzthKyspe2NvbnN0IGw9dFthXTtvKGwpfXRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsbmV3IENlKHMsMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IENlKHIsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtmdW5jdGlvbiBvKGEpe3ZhciBFdSxQdSxDdTtjb25zdCBjPVtdLGw9ZS5jdXJ2ZVNlZ21lbnRzIT09dm9pZCAwP2UuY3VydmVTZWdtZW50czoxMixoPWUuc3RlcHMhPT12b2lkIDA/ZS5zdGVwczoxLHU9ZS5kZXB0aCE9PXZvaWQgMD9lLmRlcHRoOjE7bGV0IGY9ZS5iZXZlbEVuYWJsZWQhPT12b2lkIDA/ZS5iZXZlbEVuYWJsZWQ6ITAsZD1lLmJldmVsVGhpY2tuZXNzIT09dm9pZCAwP2UuYmV2ZWxUaGlja25lc3M6LjIscD1lLmJldmVsU2l6ZSE9PXZvaWQgMD9lLmJldmVsU2l6ZTpkLS4xLHk9ZS5iZXZlbE9mZnNldCE9PXZvaWQgMD9lLmJldmVsT2Zmc2V0OjAsbT1lLmJldmVsU2VnbWVudHMhPT12b2lkIDA/ZS5iZXZlbFNlZ21lbnRzOjM7Y29uc3QgZz1lLmV4dHJ1ZGVQYXRoLGI9ZS5VVkdlbmVyYXRvciE9PXZvaWQgMD9lLlVWR2VuZXJhdG9yOnFmLHc9KEV1PWUuaGFzVG9wKSE9bnVsbD9FdTohMCx4PShQdT1lLmhhc0JvdHRvbSkhPW51bGw/UHU6ITAsTT0oQ3U9ZS5oYXNTaWRlKSE9bnVsbD9DdTohMDtsZXQgQSxfPSExLFMsRSx6LHY7ZyYmKEE9Zy5nZXRTcGFjZWRQb2ludHMoaCksXz0hMCxmPSExLFM9Zy5jb21wdXRlRnJlbmV0RnJhbWVzKGgsITEpLEU9bmV3IFQsej1uZXcgVCx2PW5ldyBUKSxmfHwobT0wLGQ9MCxwPTAseT0wKTtjb25zdCBDPWEuZXh0cmFjdFBvaW50cyhsKTtsZXQgUD1DLnNoYXBlO2NvbnN0IEY9Qy5ob2xlcztpZighSG4uaXNDbG9ja1dpc2UoUCkpe1A9UC5yZXZlcnNlKCk7Zm9yKGxldCBOPTAsTD1GLmxlbmd0aDtOPEw7TisrKXtjb25zdCBPPUZbTl07SG4uaXNDbG9ja1dpc2UoTykmJihGW05dPU8ucmV2ZXJzZSgpKX19ZnVuY3Rpb24gSShOKXtjb25zdCBPPTEwMDAwMDAwMDAwMDAwMDAxZS0zNjtsZXQgVT1OWzBdO2ZvcihsZXQgJD0xOyQ8PU4ubGVuZ3RoOyQrKyl7Y29uc3QgWT0kJU4ubGVuZ3RoLEc9TltZXSxpdD1HLngtVS54LGN0PUcueS1VLnksd3Q9aXQqaXQrY3QqY3QsWHQ9TWF0aC5tYXgoTWF0aC5hYnMoRy54KSxNYXRoLmFicyhHLnkpLE1hdGguYWJzKFUueCksTWF0aC5hYnMoVS55KSksUG49TypYdCpYdDtpZih3dDw9UG4pe04uc3BsaWNlKFksMSksJC0tO2NvbnRpbnVlfVU9R319SShQKSxGLmZvckVhY2goSSk7Y29uc3Qgaz1GLmxlbmd0aCxEPVA7Zm9yKGxldCBOPTA7TjxrO04rKyl7Y29uc3QgTD1GW05dO1A9UC5jb25jYXQoTCl9ZnVuY3Rpb24gVihOLEwsTyl7cmV0dXJuIEx8fGNvbnNvbGUuZXJyb3IoIlRIUkVFLkV4dHJ1ZGVHZW9tZXRyeTogdmVjIGRvZXMgbm90IGV4aXN0IiksTi5jbG9uZSgpLmFkZFNjYWxlZFZlY3RvcihMLE8pfWNvbnN0IGo9UC5sZW5ndGg7ZnVuY3Rpb24gZHQoTixMLE8pe2xldCBVLCQsWTtjb25zdCBHPU4ueC1MLngsaXQ9Ti55LUwueSxjdD1PLngtTi54LHd0PU8ueS1OLnksWHQ9RypHK2l0Kml0LFBuPUcqd3QtaXQqY3Q7aWYoTWF0aC5hYnMoUG4pPk51bWJlci5FUFNJTE9OKXtjb25zdCBKdD1NYXRoLnNxcnQoWHQpLEJ1PU1hdGguc3FydChjdCpjdCt3dCp3dCksRnU9TC54LWl0L0p0LEl1PUwueStHL0p0LEFnPU8ueC13dC9CdSxfZz1PLnkrY3QvQnUsa3U9KChBZy1GdSkqd3QtKF9nLUl1KSpjdCkvKEcqd3QtaXQqY3QpO1U9RnUrRyprdS1OLngsJD1JdStpdCprdS1OLnk7Y29uc3QgTnU9VSpVKyQqJDtpZihOdTw9MilyZXR1cm4gbmV3IFIoVSwkKTtZPU1hdGguc3FydChOdS8yKX1lbHNle2xldCBKdD0hMTtHPk51bWJlci5FUFNJTE9OP2N0Pk51bWJlci5FUFNJTE9OJiYoSnQ9ITApOkc8LU51bWJlci5FUFNJTE9OP2N0PC1OdW1iZXIuRVBTSUxPTiYmKEp0PSEwKTpNYXRoLnNpZ24oaXQpPT09TWF0aC5zaWduKHd0KSYmKEp0PSEwKSxKdD8oVT0taXQsJD1HLFk9TWF0aC5zcXJ0KFh0KSk6KFU9RywkPWl0LFk9TWF0aC5zcXJ0KFh0LzIpKX1yZXR1cm4gbmV3IFIoVS9ZLCQvWSl9Y29uc3QgRHQ9W107Zm9yKGxldCBOPTAsTD1ELmxlbmd0aCxPPUwtMSxVPU4rMTtOPEw7TisrLE8rKyxVKyspTz09PUwmJihPPTApLFU9PT1MJiYoVT0wKSxEdFtOXT1kdChEW05dLERbT10sRFtVXSk7Y29uc3QgR3Q9W107bGV0IFp0LG1lPUR0LmNvbmNhdCgpO2ZvcihsZXQgTj0wLEw9aztOPEw7TisrKXtjb25zdCBPPUZbTl07WnQ9W107Zm9yKGxldCBVPTAsJD1PLmxlbmd0aCxZPSQtMSxHPVUrMTtVPCQ7VSsrLFkrKyxHKyspWT09PSQmJihZPTApLEc9PT0kJiYoRz0wKSxadFtVXT1kdChPW1VdLE9bWV0sT1tHXSk7R3QucHVzaChadCksbWU9bWUuY29uY2F0KFp0KX1sZXQgRW47aWYobT09PTApRW49SG4udHJpYW5ndWxhdGVTaGFwZShELEYpO2Vsc2V7Y29uc3QgTj1bXSxMPVtdO2ZvcihsZXQgTz0wO088bTtPKyspe2NvbnN0IFU9Ty9tLCQ9ZCpNYXRoLmNvcyhVKk1hdGguUEkvMiksWT1wKk1hdGguc2luKFUqTWF0aC5QSS8yKSt5O2ZvcihsZXQgRz0wLGl0PUQubGVuZ3RoO0c8aXQ7RysrKXtjb25zdCBjdD1WKERbR10sRHRbR10sWSk7cWUoY3QueCxjdC55LC0kKSxVPT09MCYmTi5wdXNoKGN0KX1mb3IobGV0IEc9MCxpdD1rO0c8aXQ7RysrKXtjb25zdCBjdD1GW0ddO1p0PUd0W0ddO2NvbnN0IHd0PVtdO2ZvcihsZXQgWHQ9MCxQbj1jdC5sZW5ndGg7WHQ8UG47WHQrKyl7Y29uc3QgSnQ9VihjdFtYdF0sWnRbWHRdLFkpO3FlKEp0LngsSnQueSwtJCksVT09PTAmJnd0LnB1c2goSnQpfVU9PT0wJiZMLnB1c2god3QpfX1Fbj1Ibi50cmlhbmd1bGF0ZVNoYXBlKE4sTCl9Y29uc3QgR3I9RW4ubGVuZ3RoLHp1PXAreTtmb3IobGV0IE49MDtOPGo7TisrKXtjb25zdCBMPWY/VihQW05dLG1lW05dLHp1KTpQW05dO18/KHouY29weShTLm5vcm1hbHNbMF0pLm11bHRpcGx5U2NhbGFyKEwueCksRS5jb3B5KFMuYmlub3JtYWxzWzBdKS5tdWx0aXBseVNjYWxhcihMLnkpLHYuY29weShBWzBdKS5hZGQoeikuYWRkKEUpLHFlKHYueCx2Lnksdi56KSk6cWUoTC54LEwueSwwKX1mb3IobGV0IE49MTtOPD1oO04rKylmb3IobGV0IEw9MDtMPGo7TCsrKXtjb25zdCBPPWY/VihQW0xdLG1lW0xdLHp1KTpQW0xdO18/KHouY29weShTLm5vcm1hbHNbTl0pLm11bHRpcGx5U2NhbGFyKE8ueCksRS5jb3B5KFMuYmlub3JtYWxzW05dKS5tdWx0aXBseVNjYWxhcihPLnkpLHYuY29weShBW05dKS5hZGQoeikuYWRkKEUpLHFlKHYueCx2Lnksdi56KSk6cWUoTy54LE8ueSx1L2gqTil9Zm9yKGxldCBOPW0tMTtOPj0wO04tLSl7Y29uc3QgTD1OL20sTz1kKk1hdGguY29zKEwqTWF0aC5QSS8yKSxVPXAqTWF0aC5zaW4oTCpNYXRoLlBJLzIpK3k7Zm9yKGxldCAkPTAsWT1ELmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPVYoRFskXSxEdFskXSxVKTtxZShHLngsRy55LHUrTyl9Zm9yKGxldCAkPTAsWT1GLmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPUZbJF07WnQ9R3RbJF07Zm9yKGxldCBpdD0wLGN0PUcubGVuZ3RoO2l0PGN0O2l0Kyspe2NvbnN0IHd0PVYoR1tpdF0sWnRbaXRdLFUpO18/cWUod3QueCx3dC55K0FbaC0xXS55LEFbaC0xXS54K08pOnFlKHd0Lngsd3QueSx1K08pfX19d2coKSxNJiZiZygpO2Z1bmN0aW9uIHdnKCl7Y29uc3QgTj1zLmxlbmd0aC8zO2lmKGYpe2xldCBMPTAsTz1qKkw7aWYoeClmb3IobGV0IFU9MDtVPEdyO1UrKyl7Y29uc3QgJD1FbltVXTtacigkWzJdK08sJFsxXStPLCRbMF0rTyl9aWYoTD1oK20qMixPPWoqTCx3KWZvcihsZXQgVT0wO1U8R3I7VSsrKXtjb25zdCAkPUVuW1VdO1pyKCRbMF0rTywkWzFdK08sJFsyXStPKX19ZWxzZXtpZih4KWZvcihsZXQgTD0wO0w8R3I7TCsrKXtjb25zdCBPPUVuW0xdO1pyKE9bMl0sT1sxXSxPWzBdKX1pZih3KWZvcihsZXQgTD0wO0w8R3I7TCsrKXtjb25zdCBPPUVuW0xdO1pyKE9bMF0raipoLE9bMV0raipoLE9bMl0raipoKX19bi5hZGRHcm91cChOLHMubGVuZ3RoLzMtTiwwKX1mdW5jdGlvbiBiZygpe2NvbnN0IE49cy5sZW5ndGgvMztsZXQgTD0wO1R1KEQsTCksTCs9RC5sZW5ndGg7Zm9yKGxldCBPPTAsVT1GLmxlbmd0aDtPPFU7TysrKXtjb25zdCAkPUZbT107VHUoJCxMKSxMKz0kLmxlbmd0aH1uLmFkZEdyb3VwKE4scy5sZW5ndGgvMy1OLDEpfWZ1bmN0aW9uIFR1KE4sTCl7bGV0IE89Ti5sZW5ndGg7Zm9yKDstLU8+PTA7KXtjb25zdCBVPU87bGV0ICQ9Ty0xOyQ8MCYmKCQ9Ti5sZW5ndGgtMSk7Zm9yKGxldCBZPTAsRz1oK20qMjtZPEc7WSsrKXtjb25zdCBpdD1qKlksY3Q9aiooWSsxKSx3dD1MK1UraXQsWHQ9TCskK2l0LFBuPUwrJCtjdCxKdD1MK1UrY3Q7TWcod3QsWHQsUG4sSnQpfX19ZnVuY3Rpb24gcWUoTixMLE8pe2MucHVzaChOKSxjLnB1c2goTCksYy5wdXNoKE8pfWZ1bmN0aW9uIFpyKE4sTCxPKXtIZShOKSxIZShMKSxIZShPKTtjb25zdCBVPXMubGVuZ3RoLzMsJD1iLmdlbmVyYXRlVG9wVVYobixzLFUtMyxVLTIsVS0xKTtXZSgkWzBdKSxXZSgkWzFdKSxXZSgkWzJdKX1mdW5jdGlvbiBNZyhOLEwsTyxVKXtIZShOKSxIZShMKSxIZShVKSxIZShMKSxIZShPKSxIZShVKTtjb25zdCAkPXMubGVuZ3RoLzMsWT1iLmdlbmVyYXRlU2lkZVdhbGxVVihuLHMsJC02LCQtMywkLTIsJC0xKTtXZShZWzBdKSxXZShZWzFdKSxXZShZWzNdKSxXZShZWzFdKSxXZShZWzJdKSxXZShZWzNdKX1mdW5jdGlvbiBIZShOKXtzLnB1c2goY1tOKjMrMF0pLHMucHVzaChjW04qMysxXSkscy5wdXNoKGNbTiozKzJdKX1mdW5jdGlvbiBXZShOKXtyLnB1c2goTi54KSxyLnB1c2goTi55KX19fWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCksZT10aGlzLnBhcmFtZXRlcnMuc2hhcGVzLG49dGhpcy5wYXJhbWV0ZXJzLm9wdGlvbnM7cmV0dXJuIEhmKGUsbix0KX1zdGF0aWMgZnJvbUpTT04odCxlKXtjb25zdCBuPVtdO2ZvcihsZXQgcj0wLG89dC5zaGFwZXMubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVt0LnNoYXBlc1tyXV07bi5wdXNoKGEpfWNvbnN0IHM9dC5vcHRpb25zLmV4dHJ1ZGVQYXRoO3JldHVybiBzIT09dm9pZCAwJiYodC5vcHRpb25zLmV4dHJ1ZGVQYXRoPW5ldyBWZltgJHtzLnR5cGV9YF0oKS5mcm9tSlNPTihzKSksbmV3IFduKG4sdC5vcHRpb25zKX19Y29uc3QgcWY9e2dlbmVyYXRlVG9wVVY6ZnVuY3Rpb24oaSx0LGUsbixzKXtjb25zdCByPXRbZSozXSxvPXRbZSozKzFdLGE9dFtuKjNdLGM9dFtuKjMrMV0sbD10W3MqM10saD10W3MqMysxXTtyZXR1cm5bbmV3IFIocixvKSxuZXcgUihhLGMpLG5ldyBSKGwsaCldfSxnZW5lcmF0ZVNpZGVXYWxsVVY6ZnVuY3Rpb24oaSx0LGUsbixzLHIpe2NvbnN0IG89dFtlKjNdLGE9dFtlKjMrMV0sYz10W2UqMysyXSxsPXRbbiozXSxoPXRbbiozKzFdLHU9dFtuKjMrMl0sZj10W3MqM10sZD10W3MqMysxXSxwPXRbcyozKzJdLHk9dFtyKjNdLG09dFtyKjMrMV0sZz10W3IqMysyXTtyZXR1cm4gTWF0aC5hYnMoYS1oKTxNYXRoLmFicyhvLWwpP1tuZXcgUihvLDEtYyksbmV3IFIobCwxLXUpLG5ldyBSKGYsMS1wKSxuZXcgUih5LDEtZyldOltuZXcgUihhLDEtYyksbmV3IFIoaCwxLXUpLG5ldyBSKGQsMS1wKSxuZXcgUihtLDEtZyldfX07ZnVuY3Rpb24gSGYoaSx0LGUpe2lmKGUuc2hhcGVzPVtdLEFycmF5LmlzQXJyYXkoaSkpZm9yKGxldCBuPTAscz1pLmxlbmd0aDtuPHM7bisrKXtjb25zdCByPWlbbl07ZS5zaGFwZXMucHVzaChyLnV1aWQpfWVsc2UgZS5zaGFwZXMucHVzaChpLnV1aWQpO3JldHVybiBlLm9wdGlvbnM9T2JqZWN0LmFzc2lnbih7fSx0KSx0LmV4dHJ1ZGVQYXRoIT09dm9pZCAwJiYoZS5vcHRpb25zLmV4dHJ1ZGVQYXRoPXQuZXh0cnVkZVBhdGgudG9KU09OKCkpLGV9Y29uc3QgWGM9MCxXZj0xLEdmPTIsSmM9MixJbz0xLjI1LFljPTEsVGk9Nio0KzQrNCx6cz02NTUzNSxaZj1NYXRoLnBvdygyLC0yNCksa289U3ltYm9sKCJTS0lQX0dFTkVSQVRJT04iKTtmdW5jdGlvbiBYZihpKXtyZXR1cm4gaS5pbmRleD9pLmluZGV4LmNvdW50OmkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudH1mdW5jdGlvbiBHbihpKXtyZXR1cm4gWGYoaSkvM31mdW5jdGlvbiBKZihpLHQ9QXJyYXlCdWZmZXIpe3JldHVybiBpPjY1NTM1P25ldyBVaW50MzJBcnJheShuZXcgdCg0KmkpKTpuZXcgVWludDE2QXJyYXkobmV3IHQoMippKSl9ZnVuY3Rpb24gWWYoaSx0KXtpZighaS5pbmRleCl7Y29uc3QgZT1pLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQsbj10LnVzZVNoYXJlZEFycmF5QnVmZmVyP1NoYXJlZEFycmF5QnVmZmVyOkFycmF5QnVmZmVyLHM9SmYoZSxuKTtpLnNldEluZGV4KG5ldyB4dChzLDEpKTtmb3IobGV0IHI9MDtyPGU7cisrKXNbcl09cn19ZnVuY3Rpb24gamMoaSx0KXtjb25zdCBlPUduKGkpLG49dHx8aS5kcmF3UmFuZ2Uscz1uLnN0YXJ0LzMscj0obi5zdGFydCtuLmNvdW50KS8zLG89TWF0aC5tYXgoMCxzKSxhPU1hdGgubWluKGUsciktbztyZXR1cm5be29mZnNldDpNYXRoLmZsb29yKG8pLGNvdW50Ok1hdGguZmxvb3IoYSl9XX1mdW5jdGlvbiBRYyhpLHQpe2lmKCFpLmdyb3Vwc3x8IWkuZ3JvdXBzLmxlbmd0aClyZXR1cm4gamMoaSx0KTtjb25zdCBlPVtdLG49bmV3IFNldCxzPXR8fGkuZHJhd1JhbmdlLHI9cy5zdGFydC8zLG89KHMuc3RhcnQrcy5jb3VudCkvMztmb3IoY29uc3QgYyBvZiBpLmdyb3Vwcyl7Y29uc3QgbD1jLnN0YXJ0LzMsaD0oYy5zdGFydCtjLmNvdW50KS8zO24uYWRkKE1hdGgubWF4KHIsbCkpLG4uYWRkKE1hdGgubWluKG8saCkpfWNvbnN0IGE9QXJyYXkuZnJvbShuLnZhbHVlcygpKS5zb3J0KChjLGwpPT5jLWwpO2ZvcihsZXQgYz0wO2M8YS5sZW5ndGgtMTtjKyspe2NvbnN0IGw9YVtjXSxoPWFbYysxXTtlLnB1c2goe29mZnNldDpNYXRoLmZsb29yKGwpLGNvdW50Ok1hdGguZmxvb3IoaC1sKX0pfXJldHVybiBlfWZ1bmN0aW9uIGpmKGksdCl7Y29uc3QgZT1HbihpKSxuPVFjKGksdCkuc29ydCgobyxhKT0+by5vZmZzZXQtYS5vZmZzZXQpLHM9bltuLmxlbmd0aC0xXTtzLmNvdW50PU1hdGgubWluKGUtcy5vZmZzZXQscy5jb3VudCk7bGV0IHI9MDtyZXR1cm4gbi5mb3JFYWNoKCh7Y291bnQ6b30pPT5yKz1vKSxlIT09cn1mdW5jdGlvbiBObyhpLHQsZSxuLHMpe2xldCByPTEvMCxvPTEvMCxhPTEvMCxjPS0xLzAsbD0tMS8wLGg9LTEvMCx1PTEvMCxmPTEvMCxkPTEvMCxwPS0xLzAseT0tMS8wLG09LTEvMDtmb3IobGV0IGc9dCo2LGI9KHQrZSkqNjtnPGI7Zys9Nil7Y29uc3Qgdz1pW2crMF0seD1pW2crMV0sTT13LXgsQT13K3g7TTxyJiYocj1NKSxBPmMmJihjPUEpLHc8dSYmKHU9dyksdz5wJiYocD13KTtjb25zdCBfPWlbZysyXSxTPWlbZyszXSxFPV8tUyx6PV8rUztFPG8mJihvPUUpLHo+bCYmKGw9eiksXzxmJiYoZj1fKSxfPnkmJih5PV8pO2NvbnN0IHY9aVtnKzRdLEM9aVtnKzVdLFA9di1DLEY9ditDO1A8YSYmKGE9UCksRj5oJiYoaD1GKSx2PGQmJihkPXYpLHY+bSYmKG09dil9blswXT1yLG5bMV09byxuWzJdPWEsblszXT1jLG5bNF09bCxuWzVdPWgsc1swXT11LHNbMV09ZixzWzJdPWQsc1szXT1wLHNbNF09eSxzWzVdPW19ZnVuY3Rpb24gUWYoaSx0PW51bGwsZT1udWxsLG49bnVsbCl7Y29uc3Qgcz1pLmF0dHJpYnV0ZXMucG9zaXRpb24scj1pLmluZGV4P2kuaW5kZXguYXJyYXk6bnVsbCxvPUduKGkpLGE9cy5ub3JtYWxpemVkO2xldCBjO3Q9PT1udWxsPyhjPW5ldyBGbG9hdDMyQXJyYXkobyo2KSxlPTAsbj1vKTooYz10LGU9ZXx8MCxuPW58fG8pO2NvbnN0IGw9cy5hcnJheSxoPXMub2Zmc2V0fHwwO2xldCB1PTM7cy5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlJiYodT1zLmRhdGEuc3RyaWRlKTtjb25zdCBmPVsiZ2V0WCIsImdldFkiLCJnZXRaIl07Zm9yKGxldCBkPWU7ZDxlK247ZCsrKXtjb25zdCBwPWQqMyx5PWQqNjtsZXQgbT1wKzAsZz1wKzEsYj1wKzI7ciYmKG09clttXSxnPXJbZ10sYj1yW2JdKSxhfHwobT1tKnUraCxnPWcqdStoLGI9Yip1K2gpO2ZvcihsZXQgdz0wO3c8Mzt3Kyspe2xldCB4LE0sQTthPyh4PXNbZlt3XV0obSksTT1zW2Zbd11dKGcpLEE9c1tmW3ddXShiKSk6KHg9bFttK3ddLE09bFtnK3ddLEE9bFtiK3ddKTtsZXQgXz14O008XyYmKF89TSksQTxfJiYoXz1BKTtsZXQgUz14O00+UyYmKFM9TSksQT5TJiYoUz1BKTtjb25zdCBFPShTLV8pLzIsej13KjI7Y1t5K3orMF09XytFLGNbeSt6KzFdPUUrKE1hdGguYWJzKF8pK0UpKlpmfX1yZXR1cm4gY31mdW5jdGlvbiBsdChpLHQsZSl7cmV0dXJuIGUubWluLng9dFtpXSxlLm1pbi55PXRbaSsxXSxlLm1pbi56PXRbaSsyXSxlLm1heC54PXRbaSszXSxlLm1heC55PXRbaSs0XSxlLm1heC56PXRbaSs1XSxlfWZ1bmN0aW9uIEtjKGkpe2xldCB0PS0xLGU9LTEvMDtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPWlbbiszXS1pW25dO3M+ZSYmKGU9cyx0PW4pfXJldHVybiB0fWZ1bmN0aW9uIHRsKGksdCl7dC5zZXQoaSl9ZnVuY3Rpb24gZWwoaSx0LGUpe2xldCBuLHM7Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz1yKzM7bj1pW3JdLHM9dFtyXSxlW3JdPW48cz9uOnMsbj1pW29dLHM9dFtvXSxlW29dPW4+cz9uOnN9fWZ1bmN0aW9uIFRzKGksdCxlKXtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPXRbaSsyKm5dLHI9dFtpKzIqbisxXSxvPXMtcixhPXMrcjtvPGVbbl0mJihlW25dPW8pLGE+ZVtuKzNdJiYoZVtuKzNdPWEpfX1mdW5jdGlvbiBFaShpKXtjb25zdCB0PWlbM10taVswXSxlPWlbNF0taVsxXSxuPWlbNV0taVsyXTtyZXR1cm4gMioodCplK2UqbituKnQpfWNvbnN0IEJlPTMyLEtmPShpLHQpPT5pLmNhbmRpZGF0ZS10LmNhbmRpZGF0ZSxRZT1uZXcgQXJyYXkoQmUpLmZpbGwoKS5tYXAoKCk9Pih7Y291bnQ6MCxib3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxyaWdodENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksbGVmdENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksY2FuZGlkYXRlOjB9KSksRXM9bmV3IEZsb2F0MzJBcnJheSg2KTtmdW5jdGlvbiB0ZChpLHQsZSxuLHMscil7bGV0IG89LTEsYT0wO2lmKHI9PT1YYylvPUtjKHQpLG8hPT0tMSYmKGE9KHRbb10rdFtvKzNdKS8yKTtlbHNlIGlmKHI9PT1XZilvPUtjKGkpLG8hPT0tMSYmKGE9ZWQoZSxuLHMsbykpO2Vsc2UgaWYocj09PUdmKXtjb25zdCBjPUVpKGkpO2xldCBsPUlvKnM7Y29uc3QgaD1uKjYsdT0obitzKSo2O2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9dFtmXSxtPSh0W2YrM10tZCkvQmU7aWYoczxCZS80KXtjb25zdCBnPVsuLi5RZV07Zy5sZW5ndGg9cztsZXQgYj0wO2ZvcihsZXQgeD1oO3g8dTt4Kz02LGIrKyl7Y29uc3QgTT1nW2JdO00uY2FuZGlkYXRlPWVbeCsyKmZdLE0uY291bnQ9MDtjb25zdHtib3VuZHM6QSxsZWZ0Q2FjaGVCb3VuZHM6XyxyaWdodENhY2hlQm91bmRzOlN9PU07Zm9yKGxldCBFPTA7RTwzO0UrKylTW0VdPTEvMCxTW0UrM109LTEvMCxfW0VdPTEvMCxfW0UrM109LTEvMCxBW0VdPTEvMCxBW0UrM109LTEvMDtUcyh4LGUsQSl9Zy5zb3J0KEtmKTtsZXQgdz1zO2ZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XTtmb3IoO3grMTx3JiZnW3grMV0uY2FuZGlkYXRlPT09TS5jYW5kaWRhdGU7KWcuc3BsaWNlKHgrMSwxKSx3LS19Zm9yKGxldCB4PWg7eDx1O3grPTYpe2NvbnN0IE09ZVt4KzIqZl07Zm9yKGxldCBBPTA7QTx3O0ErKyl7Y29uc3QgXz1nW0FdO00+PV8uY2FuZGlkYXRlP1RzKHgsZSxfLnJpZ2h0Q2FjaGVCb3VuZHMpOihUcyh4LGUsXy5sZWZ0Q2FjaGVCb3VuZHMpLF8uY291bnQrKyl9fWZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XSxBPU0uY291bnQsXz1zLU0uY291bnQsUz1NLmxlZnRDYWNoZUJvdW5kcyxFPU0ucmlnaHRDYWNoZUJvdW5kcztsZXQgej0wO0EhPT0wJiYoej1FaShTKS9jKTtsZXQgdj0wO18hPT0wJiYodj1FaShFKS9jKTtjb25zdCBDPVljK0lvKih6KkErdipfKTtDPGwmJihvPWYsbD1DLGE9TS5jYW5kaWRhdGUpfX1lbHNle2ZvcihsZXQgdz0wO3c8QmU7dysrKXtjb25zdCB4PVFlW3ddO3guY291bnQ9MCx4LmNhbmRpZGF0ZT1kK20rdyptO2NvbnN0IE09eC5ib3VuZHM7Zm9yKGxldCBBPTA7QTwzO0ErKylNW0FdPTEvMCxNW0ErM109LTEvMH1mb3IobGV0IHc9aDt3PHU7dys9Nil7bGV0IEE9fn4oKGVbdysyKmZdLWQpL20pO0E+PUJlJiYoQT1CZS0xKTtjb25zdCBfPVFlW0FdO18uY291bnQrKyxUcyh3LGUsXy5ib3VuZHMpfWNvbnN0IGc9UWVbQmUtMV07dGwoZy5ib3VuZHMsZy5yaWdodENhY2hlQm91bmRzKTtmb3IobGV0IHc9QmUtMjt3Pj0wO3ctLSl7Y29uc3QgeD1RZVt3XSxNPVFlW3crMV07ZWwoeC5ib3VuZHMsTS5yaWdodENhY2hlQm91bmRzLHgucmlnaHRDYWNoZUJvdW5kcyl9bGV0IGI9MDtmb3IobGV0IHc9MDt3PEJlLTE7dysrKXtjb25zdCB4PVFlW3ddLE09eC5jb3VudCxBPXguYm91bmRzLFM9UWVbdysxXS5yaWdodENhY2hlQm91bmRzO00hPT0wJiYoYj09PTA/dGwoQSxFcyk6ZWwoQSxFcyxFcykpLGIrPU07bGV0IEU9MCx6PTA7YiE9PTAmJihFPUVpKEVzKS9jKTtjb25zdCB2PXMtYjt2IT09MCYmKHo9RWkoUykvYyk7Y29uc3QgQz1ZYytJbyooRSpiK3oqdik7QzxsJiYobz1mLGw9QyxhPXguY2FuZGlkYXRlKX19fX1lbHNlIGNvbnNvbGUud2FybihgTWVzaEJWSDogSW52YWxpZCBidWlsZCBzdHJhdGVneSB2YWx1ZSAke3J9IHVzZWQuYCk7cmV0dXJue2F4aXM6byxwb3M6YX19ZnVuY3Rpb24gZWQoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPXQrZTtyPG87cisrKXMrPWlbcio2K24qMl07cmV0dXJuIHMvZX1jbGFzcyBSb3tjb25zdHJ1Y3Rvcigpe3RoaXMuYm91bmRpbmdEYXRhPW5ldyBGbG9hdDMyQXJyYXkoNil9fWZ1bmN0aW9uIG5kKGksdCxlLG4scyxyKXtsZXQgbz1uLGE9bitzLTE7Y29uc3QgYz1yLnBvcyxsPXIuYXhpcyoyO2Zvcig7Oyl7Zm9yKDtvPD1hJiZlW28qNitsXTxjOylvKys7Zm9yKDtvPD1hJiZlW2EqNitsXT49YzspYS0tO2lmKG88YSl7Zm9yKGxldCBoPTA7aDwzO2grKyl7bGV0IHU9dFtvKjMraF07dFtvKjMraF09dFthKjMraF0sdFthKjMraF09dX1mb3IobGV0IGg9MDtoPDY7aCsrKXtsZXQgdT1lW28qNitoXTtlW28qNitoXT1lW2EqNitoXSxlW2EqNitoXT11fW8rKyxhLS19ZWxzZSByZXR1cm4gb319ZnVuY3Rpb24gaWQoaSx0LGUsbixzLHIpe2xldCBvPW4sYT1uK3MtMTtjb25zdCBjPXIucG9zLGw9ci5heGlzKjI7Zm9yKDs7KXtmb3IoO288PWEmJmVbbyo2K2xdPGM7KW8rKztmb3IoO288PWEmJmVbYSo2K2xdPj1jOylhLS07aWYobzxhKXtsZXQgaD1pW29dO2lbb109aVthXSxpW2FdPWg7Zm9yKGxldCB1PTA7dTw2O3UrKyl7bGV0IGY9ZVtvKjYrdV07ZVtvKjYrdV09ZVthKjYrdV0sZVthKjYrdV09Zn1vKyssYS0tfWVsc2UgcmV0dXJuIG99fWZ1bmN0aW9uIGt0KGksdCl7cmV0dXJuIHRbaSsxNV09PT02NTUzNX1mdW5jdGlvbiBWdChpLHQpe3JldHVybiB0W2krNl19ZnVuY3Rpb24gS3QoaSx0KXtyZXR1cm4gdFtpKzE0XX1mdW5jdGlvbiB0ZShpKXtyZXR1cm4gaSs4fWZ1bmN0aW9uIGVlKGksdCl7cmV0dXJuIHRbaSs2XX1mdW5jdGlvbiBubChpLHQpe3JldHVybiB0W2krN119ZnVuY3Rpb24gSGcoaSl7cmV0dXJuIGl9bGV0IGlsLFBpLFBzLHNsO2NvbnN0IHNkPU1hdGgucG93KDIsMzIpO2Z1bmN0aW9uIExvKGkpe3JldHVybiJjb3VudCJpbiBpPzE6MStMbyhpLmxlZnQpK0xvKGkucmlnaHQpfWZ1bmN0aW9uIHJkKGksdCxlKXtyZXR1cm4gaWw9bmV3IEZsb2F0MzJBcnJheShlKSxQaT1uZXcgVWludDMyQXJyYXkoZSksUHM9bmV3IFVpbnQxNkFycmF5KGUpLHNsPW5ldyBVaW50OEFycmF5KGUpLE9vKGksdCl9ZnVuY3Rpb24gT28oaSx0KXtjb25zdCBlPWkvNCxuPWkvMixzPSJjb3VudCJpbiB0LHI9dC5ib3VuZGluZ0RhdGE7Zm9yKGxldCBvPTA7bzw2O28rKylpbFtlK29dPXJbb107aWYocylpZih0LmJ1ZmZlcil7Y29uc3Qgbz10LmJ1ZmZlcjtzbC5zZXQobmV3IFVpbnQ4QXJyYXkobyksaSk7Zm9yKGxldCBhPWksYz1pK28uYnl0ZUxlbmd0aDthPGM7YSs9VGkpe2NvbnN0IGw9YS8yO2t0KGwsUHMpfHwoUGlbYS80KzZdKz1lKX1yZXR1cm4gaStvLmJ5dGVMZW5ndGh9ZWxzZXtjb25zdCBvPXQub2Zmc2V0LGE9dC5jb3VudDtyZXR1cm4gUGlbZSs2XT1vLFBzW24rMTRdPWEsUHNbbisxNV09enMsaStUaX1lbHNle2NvbnN0IG89dC5sZWZ0LGE9dC5yaWdodCxjPXQuc3BsaXRBeGlzO2xldCBsO2lmKGw9T28oaStUaSxvKSxsLzQ+c2QpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBDYW5ub3Qgc3RvcmUgY2hpbGQgcG9pbnRlciBncmVhdGVyIHRoYW4gMzIgYml0cy4iKTtyZXR1cm4gUGlbZSs2XT1sLzQsbD1PbyhsLGEpLFBpW2UrN109YyxsfX1mdW5jdGlvbiBvZChpLHQpe2NvbnN0IGU9KGkuaW5kZXg/aS5pbmRleC5jb3VudDppLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQpLzMsbj1lPmRpKDIsMTYpLHM9bj80OjIscj10P25ldyBTaGFyZWRBcnJheUJ1ZmZlcihlKnMpOm5ldyBBcnJheUJ1ZmZlcihlKnMpLG89bj9uZXcgVWludDMyQXJyYXkocik6bmV3IFVpbnQxNkFycmF5KHIpO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKylvW2FdPWE7cmV0dXJuIG99ZnVuY3Rpb24gYWQoaSx0LGUsbixzKXtjb25zdHttYXhEZXB0aDpyLHZlcmJvc2U6byxtYXhMZWFmVHJpczphLHN0cmF0ZWd5OmMsb25Qcm9ncmVzczpsLGluZGlyZWN0Omh9PXMsdT1pLl9pbmRpcmVjdEJ1ZmZlcixmPWkuZ2VvbWV0cnksZD1mLmluZGV4P2YuaW5kZXguYXJyYXk6bnVsbCxwPWg/aWQ6bmQseT1HbihmKSxtPW5ldyBGbG9hdDMyQXJyYXkoNik7bGV0IGc9ITE7Y29uc3QgYj1uZXcgUm87cmV0dXJuIE5vKHQsZSxuLGIuYm91bmRpbmdEYXRhLG0pLHgoYixlLG4sbSksYjtmdW5jdGlvbiB3KE0pe2wmJmwoTS95KX1mdW5jdGlvbiB4KE0sQSxfLFM9bnVsbCxFPTApe2lmKCFnJiZFPj1yJiYoZz0hMCxvJiYoY29uc29sZS53YXJuKGBNZXNoQlZIOiBNYXggZGVwdGggb2YgJHtyfSByZWFjaGVkIHdoZW4gZ2VuZXJhdGluZyBCVkguIENvbnNpZGVyIGluY3JlYXNpbmcgbWF4RGVwdGguYCksY29uc29sZS53YXJuKGYpKSksXzw9YXx8RT49cilyZXR1cm4gdyhBK18pLE0ub2Zmc2V0PUEsTS5jb3VudD1fLE07Y29uc3Qgej10ZChNLmJvdW5kaW5nRGF0YSxTLHQsQSxfLGMpO2lmKHouYXhpcz09PS0xKXJldHVybiB3KEErXyksTS5vZmZzZXQ9QSxNLmNvdW50PV8sTTtjb25zdCB2PXAodSxkLHQsQSxfLHopO2lmKHY9PT1BfHx2PT09QStfKXcoQStfKSxNLm9mZnNldD1BLE0uY291bnQ9XztlbHNle00uc3BsaXRBeGlzPXouYXhpcztjb25zdCBDPW5ldyBSbyxQPUEsRj12LUE7TS5sZWZ0PUMsTm8odCxQLEYsQy5ib3VuZGluZ0RhdGEsbSkseChDLFAsRixtLEUrMSk7Y29uc3QgQj1uZXcgUm8sST12LGs9Xy1GO00ucmlnaHQ9QixObyh0LEksayxCLmJvdW5kaW5nRGF0YSxtKSx4KEIsSSxrLG0sRSsxKX1yZXR1cm4gTX19ZnVuY3Rpb24gY2QoaSx0KXtjb25zdCBlPWkuZ2VvbWV0cnk7dC5pbmRpcmVjdCYmKGkuX2luZGlyZWN0QnVmZmVyPW9kKGUsdC51c2VTaGFyZWRBcnJheUJ1ZmZlciksamYoZSx0LnJhbmdlKSYmIXQudmVyYm9zZSYmY29uc29sZS53YXJuKCdNZXNoQlZIOiBQcm92aWRlZCBnZW9tZXRyeSBjb250YWlucyBncm91cHMgb3IgYSByYW5nZSB0aGF0IGRvIG5vdCBmdWxseSBzcGFuIHRoZSB2ZXJ0ZXggY29udGVudHMgd2hpbGUgdXNpbmcgdGhlICJpbmRpcmVjdCIgb3B0aW9uLiBCVkggbWF5IGluY29ycmVjdGx5IHJlcG9ydCBpbnRlcnNlY3Rpb25zIG9uIHVucmVuZGVyZWQgcG9ydGlvbnMgb2YgdGhlIGdlb21ldHJ5LicpKSxpLl9pbmRpcmVjdEJ1ZmZlcnx8WWYoZSx0KTtjb25zdCBuPXQudXNlU2hhcmVkQXJyYXlCdWZmZXI/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1RZihlKSxyPXQuaW5kaXJlY3Q/amMoZSx0LnJhbmdlKTpRYyhlLHQucmFuZ2UpO2kuX3Jvb3RzPXIubWFwKG89Pntjb25zdCBhPWFkKGkscyxvLm9mZnNldCxvLmNvdW50LHQpLGM9TG8oYSksbD1uZXcgbihUaSpjKTtyZXR1cm4gcmQoMCxhLGwpLGx9KX1jbGFzcyBGZXtjb25zdHJ1Y3Rvcigpe3RoaXMubWluPTEvMCx0aGlzLm1heD0tMS8wfXNldEZyb21Qb2ludHNGaWVsZCh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBjPXRbcl1bZV07bj1jPG4/YzpuLHM9Yz5zP2M6c310aGlzLm1pbj1uLHRoaXMubWF4PXN9c2V0RnJvbVBvaW50cyh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl0sYz10LmRvdChhKTtuPWM8bj9jOm4scz1jPnM/YzpzfXRoaXMubWluPW4sdGhpcy5tYXg9c31pc1NlcGFyYXRlZCh0KXtyZXR1cm4gdGhpcy5taW4+dC5tYXh8fHQubWluPnRoaXMubWF4fX1GZS5wcm90b3R5cGUuc2V0RnJvbUJveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Y29uc3Qgcz1uLm1pbixyPW4ubWF4O2xldCBvPTEvMCxhPS0xLzA7Zm9yKGxldCBjPTA7Yzw9MTtjKyspZm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspe2kueD1zLngqYytyLngqKDEtYyksaS55PXMueSpsK3IueSooMS1sKSxpLno9cy56Kmgrci56KigxLWgpO2NvbnN0IHU9ZS5kb3QoaSk7bz1NYXRoLm1pbih1LG8pLGE9TWF0aC5tYXgodSxhKX10aGlzLm1pbj1vLHRoaXMubWF4PWF9fSgpO2NvbnN0IGxkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtjb25zdCBhPXMuc3RhcnQsYz1pLGw9ci5zdGFydCxoPXQ7ZS5zdWJWZWN0b3JzKGEsbCksaS5zdWJWZWN0b3JzKHMuZW5kLHMuc3RhcnQpLHQuc3ViVmVjdG9ycyhyLmVuZCxyLnN0YXJ0KTtjb25zdCB1PWUuZG90KGgpLGY9aC5kb3QoYyksZD1oLmRvdChoKSxwPWUuZG90KGMpLG09Yy5kb3QoYykqZC1mKmY7bGV0IGcsYjttIT09MD9nPSh1KmYtcCpkKS9tOmc9MCxiPSh1K2cqZikvZCxvLng9ZyxvLnk9Yn19KCksRG89ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBSLHQ9bmV3IFQsZT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24ocyxyLG8sYSl7bGQocyxyLGkpO2xldCBjPWkueCxsPWkueTtpZihjPj0wJiZjPD0xJiZsPj0wJiZsPD0xKXtzLmF0KGMsbyksci5hdChsLGEpO3JldHVybn1lbHNlIGlmKGM+PTAmJmM8PTEpe2w8MD9yLmF0KDAsYSk6ci5hdCgxLGEpLHMuY2xvc2VzdFBvaW50VG9Qb2ludChhLCEwLG8pO3JldHVybn1lbHNlIGlmKGw+PTAmJmw8PTEpe2M8MD9zLmF0KDAsbyk6cy5hdCgxLG8pLHIuY2xvc2VzdFBvaW50VG9Qb2ludChvLCEwLGEpO3JldHVybn1lbHNle2xldCBoO2M8MD9oPXMuc3RhcnQ6aD1zLmVuZDtsZXQgdTtsPDA/dT1yLnN0YXJ0OnU9ci5lbmQ7Y29uc3QgZj10LGQ9ZTtpZihzLmNsb3Nlc3RQb2ludFRvUG9pbnQodSwhMCx0KSxyLmNsb3Nlc3RQb2ludFRvUG9pbnQoaCwhMCxlKSxmLmRpc3RhbmNlVG9TcXVhcmVkKHUpPD1kLmRpc3RhbmNlVG9TcXVhcmVkKGgpKXtvLmNvcHkoZiksYS5jb3B5KHUpO3JldHVybn1lbHNle28uY29weShoKSxhLmNvcHkoZCk7cmV0dXJufX19fSgpLGhkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IE1vLG49bmV3IFF0O3JldHVybiBmdW5jdGlvbihyLG8pe2NvbnN0e3JhZGl1czphLGNlbnRlcjpjfT1yLHthOmwsYjpoLGM6dX09bztpZihuLnN0YXJ0PWwsbi5lbmQ9aCxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hfHwobi5zdGFydD1sLG4uZW5kPXUsbi5jbG9zZXN0UG9pbnRUb1BvaW50KGMsITAsaSkuZGlzdGFuY2VUbyhjKTw9YSl8fChuLnN0YXJ0PWgsbi5lbmQ9dSxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hKSlyZXR1cm4hMDtjb25zdCB5PW8uZ2V0UGxhbmUoZSk7aWYoTWF0aC5hYnMoeS5kaXN0YW5jZVRvUG9pbnQoYykpPD1hKXtjb25zdCBnPXkucHJvamVjdFBvaW50KGMsdCk7aWYoby5jb250YWluc1BvaW50KGcpKXJldHVybiEwfXJldHVybiExfX0oKSx1ZD0xZS0xNTtmdW5jdGlvbiAkbyhpKXtyZXR1cm4gTWF0aC5hYnMoaSk8dWR9Y2xhc3MgbmUgZXh0ZW5kcyBldHtjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzRXh0ZW5kZWRUcmlhbmdsZT0hMCx0aGlzLnNhdEF4ZXM9bmV3IEFycmF5KDQpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEJvdW5kcz1uZXcgQXJyYXkoNCkuZmlsbCgpLm1hcCgoKT0+bmV3IEZlKSx0aGlzLnBvaW50cz1bdGhpcy5hLHRoaXMuYix0aGlzLmNdLHRoaXMuc3BoZXJlPW5ldyBpbyx0aGlzLnBsYW5lPW5ldyBNbyx0aGlzLm5lZWRzVXBkYXRlPSEwfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIGhkKHQsdGhpcyl9dXBkYXRlKCl7Y29uc3QgdD10aGlzLmEsZT10aGlzLmIsbj10aGlzLmMscz10aGlzLnBvaW50cyxyPXRoaXMuc2F0QXhlcyxvPXRoaXMuc2F0Qm91bmRzLGE9clswXSxjPW9bMF07dGhpcy5nZXROb3JtYWwoYSksYy5zZXRGcm9tUG9pbnRzKGEscyk7Y29uc3QgbD1yWzFdLGg9b1sxXTtsLnN1YlZlY3RvcnModCxlKSxoLnNldEZyb21Qb2ludHMobCxzKTtjb25zdCB1PXJbMl0sZj1vWzJdO3Uuc3ViVmVjdG9ycyhlLG4pLGYuc2V0RnJvbVBvaW50cyh1LHMpO2NvbnN0IGQ9clszXSxwPW9bM107ZC5zdWJWZWN0b3JzKG4sdCkscC5zZXRGcm9tUG9pbnRzKGQscyksdGhpcy5zcGhlcmUuc2V0RnJvbVBvaW50cyh0aGlzLnBvaW50cyksdGhpcy5wbGFuZS5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChhLHQpLHRoaXMubmVlZHNVcGRhdGU9ITF9fW5lLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRUb1NlZ21lbnQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKHMscj1udWxsLG89bnVsbCl7Y29uc3R7c3RhcnQ6YSxlbmQ6Y309cyxsPXRoaXMucG9pbnRzO2xldCBoLHU9MS8wO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9KGYrMSklMztlLnN0YXJ0LmNvcHkobFtmXSksZS5lbmQuY29weShsW2RdKSxEbyhlLHMsaSx0KSxoPWkuZGlzdGFuY2VUb1NxdWFyZWQodCksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkodCkpfXJldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoYSxpKSxoPWEuZGlzdGFuY2VUb1NxdWFyZWQoaSksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkoYSkpLHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChjLGkpLGg9Yy5kaXN0YW5jZVRvU3F1YXJlZChpKSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weShjKSksTWF0aC5zcXJ0KHUpfX0oKSxuZS5wcm90b3R5cGUuaW50ZXJzZWN0c1RyaWFuZ2xlPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgbmUsdD1uZXcgQXJyYXkoMyksZT1uZXcgQXJyYXkoMyksbj1uZXcgRmUscz1uZXcgRmUscj1uZXcgVCxvPW5ldyBULGE9bmV3IFQsYz1uZXcgVCxsPW5ldyBULGg9bmV3IFF0LHU9bmV3IFF0LGY9bmV3IFF0LGQ9bmV3IFQ7ZnVuY3Rpb24gcCh5LG0sZyl7Y29uc3QgYj15LnBvaW50cztsZXQgdz0wLHg9LTE7Zm9yKGxldCBNPTA7TTwzO00rKyl7Y29uc3R7c3RhcnQ6QSxlbmQ6X309aDtBLmNvcHkoYltNXSksXy5jb3B5KGJbKE0rMSklM10pLGguZGVsdGEobyk7Y29uc3QgUz0kbyhtLmRpc3RhbmNlVG9Qb2ludChBKSk7aWYoJG8obS5ub3JtYWwuZG90KG8pKSYmUyl7Zy5jb3B5KGgpLHc9MjticmVha31jb25zdCBFPW0uaW50ZXJzZWN0TGluZShoLGQpO2lmKCFFJiZTJiZkLmNvcHkoQSksKEV8fFMpJiYhJG8oZC5kaXN0YW5jZVRvKF8pKSl7aWYodzw9MSkodz09PTE/Zy5zdGFydDpnLmVuZCkuY29weShkKSxTJiYoeD13KTtlbHNlIGlmKHc+PTIpeyh4PT09MT9nLnN0YXJ0OmcuZW5kKS5jb3B5KGQpLHc9MjticmVha31pZih3Kyssdz09PTImJng9PT0tMSlicmVha319cmV0dXJuIHd9cmV0dXJuIGZ1bmN0aW9uKG0sZz1udWxsLGI9ITEpe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksbS5pc0V4dGVuZGVkVHJpYW5nbGU/bS5uZWVkc1VwZGF0ZSYmbS51cGRhdGUoKTooaS5jb3B5KG0pLGkudXBkYXRlKCksbT1pKTtjb25zdCB3PXRoaXMucGxhbmUseD1tLnBsYW5lO2lmKE1hdGguYWJzKHcubm9ybWFsLmRvdCh4Lm5vcm1hbCkpPjEtMWUtMTApe2NvbnN0IE09dGhpcy5zYXRCb3VuZHMsQT10aGlzLnNhdEF4ZXM7ZVswXT1tLmEsZVsxXT1tLmIsZVsyXT1tLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1NW0VdLHY9QVtFXTtpZihuLnNldEZyb21Qb2ludHModixlKSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWNvbnN0IF89bS5zYXRCb3VuZHMsUz1tLnNhdEF4ZXM7dFswXT10aGlzLmEsdFsxXT10aGlzLmIsdFsyXT10aGlzLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1fW0VdLHY9U1tFXTtpZihuLnNldEZyb21Qb2ludHModix0KSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWZvcihsZXQgRT0wO0U8NDtFKyspe2NvbnN0IHo9QVtFXTtmb3IobGV0IHY9MDt2PDQ7disrKXtjb25zdCBDPVNbdl07aWYoci5jcm9zc1ZlY3RvcnMoeixDKSxuLnNldEZyb21Qb2ludHMocix0KSxzLnNldEZyb21Qb2ludHMocixlKSxuLmlzU2VwYXJhdGVkKHMpKXJldHVybiExfX1yZXR1cm4gZyYmKGJ8fGNvbnNvbGUud2FybigiRXh0ZW5kZWRUcmlhbmdsZS5pbnRlcnNlY3RzVHJpYW5nbGU6IFRyaWFuZ2xlcyBhcmUgY29wbGFuYXIgd2hpY2ggZG9lcyBub3Qgc3VwcG9ydCBhbiBvdXRwdXQgZWRnZS4gU2V0dGluZyBlZGdlIHRvIDAsIDAsIDAuIiksZy5zdGFydC5zZXQoMCwwLDApLGcuZW5kLnNldCgwLDAsMCkpLCEwfWVsc2V7Y29uc3QgTT1wKHRoaXMseCx1KTtpZihNPT09MSYmbS5jb250YWluc1BvaW50KHUuZW5kKSlyZXR1cm4gZyYmKGcuc3RhcnQuY29weSh1LmVuZCksZy5lbmQuY29weSh1LmVuZCkpLCEwO2lmKE0hPT0yKXJldHVybiExO2NvbnN0IEE9cChtLHcsZik7aWYoQT09PTEmJnRoaXMuY29udGFpbnNQb2ludChmLmVuZCkpcmV0dXJuIGcmJihnLnN0YXJ0LmNvcHkoZi5lbmQpLGcuZW5kLmNvcHkoZi5lbmQpKSwhMDtpZihBIT09MilyZXR1cm4hMTtpZih1LmRlbHRhKGEpLGYuZGVsdGEoYyksYS5kb3QoYyk8MCl7bGV0IFA9Zi5zdGFydDtmLnN0YXJ0PWYuZW5kLGYuZW5kPVB9Y29uc3QgXz11LnN0YXJ0LmRvdChhKSxTPXUuZW5kLmRvdChhKSxFPWYuc3RhcnQuZG90KGEpLHo9Zi5lbmQuZG90KGEpLHY9UzxFLEM9Xzx6O3JldHVybiBfIT09eiYmRSE9PVMmJnY9PT1DPyExOihnJiYobC5zdWJWZWN0b3JzKHUuc3RhcnQsZi5zdGFydCksbC5kb3QoYSk+MD9nLnN0YXJ0LmNvcHkodS5zdGFydCk6Zy5zdGFydC5jb3B5KGYuc3RhcnQpLGwuc3ViVmVjdG9ycyh1LmVuZCxmLmVuZCksbC5kb3QoYSk8MD9nLmVuZC5jb3B5KHUuZW5kKTpnLmVuZC5jb3B5KGYuZW5kKSksITApfX19KCksbmUucHJvdG90eXBlLmRpc3RhbmNlVG9Qb2ludD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoZSxpKSxlLmRpc3RhbmNlVG8oaSl9fSgpLG5lLnByb3RvdHlwZS5kaXN0YW5jZVRvVHJpYW5nbGU9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1bImEiLCJiIiwiYyJdLG49bmV3IFF0LHM9bmV3IFF0O3JldHVybiBmdW5jdGlvbihvLGE9bnVsbCxjPW51bGwpe2NvbnN0IGw9YXx8Yz9uOm51bGw7aWYodGhpcy5pbnRlcnNlY3RzVHJpYW5nbGUobyxsKSlyZXR1cm4oYXx8YykmJihhJiZsLmdldENlbnRlcihhKSxjJiZsLmdldENlbnRlcihjKSksMDtsZXQgaD0xLzA7Zm9yKGxldCB1PTA7dTwzO3UrKyl7bGV0IGY7Y29uc3QgZD1lW3VdLHA9b1tkXTt0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocCxpKSxmPXAuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weShpKSxjJiZjLmNvcHkocCkpO2NvbnN0IHk9dGhpc1tkXTtvLmNsb3Nlc3RQb2ludFRvUG9pbnQoeSxpKSxmPXkuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weSh5KSxjJiZjLmNvcHkoaSkpfWZvcihsZXQgdT0wO3U8Mzt1Kyspe2NvbnN0IGY9ZVt1XSxkPWVbKHUrMSklM107bi5zZXQodGhpc1tmXSx0aGlzW2RdKTtmb3IobGV0IHA9MDtwPDM7cCsrKXtjb25zdCB5PWVbcF0sbT1lWyhwKzEpJTNdO3Muc2V0KG9beV0sb1ttXSksRG8obixzLGksdCk7Y29uc3QgZz1pLmRpc3RhbmNlVG9TcXVhcmVkKHQpO2c8aCYmKGg9ZyxhJiZhLmNvcHkoaSksYyYmYy5jb3B5KHQpKX19cmV0dXJuIE1hdGguc3FydChoKX19KCk7Y2xhc3MgenR7Y29uc3RydWN0b3IodCxlLG4pe3RoaXMuaXNPcmllbnRlZEJveD0hMCx0aGlzLm1pbj1uZXcgVCx0aGlzLm1heD1uZXcgVCx0aGlzLm1hdHJpeD1uZXcgc3QsdGhpcy5pbnZNYXRyaXg9bmV3IHN0LHRoaXMucG9pbnRzPW5ldyBBcnJheSg4KS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRBeGVzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRCb3VuZHM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBGZSksdGhpcy5hbGlnbmVkU2F0Qm91bmRzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgRmUpLHRoaXMubmVlZHNVcGRhdGU9ITEsdCYmdGhpcy5taW4uY29weSh0KSxlJiZ0aGlzLm1heC5jb3B5KGUpLG4mJnRoaXMubWF0cml4LmNvcHkobil9c2V0KHQsZSxuKXt0aGlzLm1pbi5jb3B5KHQpLHRoaXMubWF4LmNvcHkoZSksdGhpcy5tYXRyaXguY29weShuKSx0aGlzLm5lZWRzVXBkYXRlPSEwfWNvcHkodCl7dGhpcy5taW4uY29weSh0Lm1pbiksdGhpcy5tYXguY29weSh0Lm1heCksdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5uZWVkc1VwZGF0ZT0hMH19enQucHJvdG90eXBlLnVwZGF0ZT1mdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbigpe2NvbnN0IHQ9dGhpcy5tYXRyaXgsZT10aGlzLm1pbixuPXRoaXMubWF4LHM9dGhpcy5wb2ludHM7Zm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspZm9yKGxldCB1PTA7dTw9MTt1Kyspe2NvbnN0IGY9MSpsfDIqaHw0KnUsZD1zW2ZdO2QueD1sP24ueDplLngsZC55PWg/bi55OmUueSxkLno9dT9uLno6ZS56LGQuYXBwbHlNYXRyaXg0KHQpfWNvbnN0IHI9dGhpcy5zYXRCb3VuZHMsbz10aGlzLnNhdEF4ZXMsYT1zWzBdO2ZvcihsZXQgbD0wO2w8MztsKyspe2NvbnN0IGg9b1tsXSx1PXJbbF0sZj0xPDxsLGQ9c1tmXTtoLnN1YlZlY3RvcnMoYSxkKSx1LnNldEZyb21Qb2ludHMoaCxzKX1jb25zdCBjPXRoaXMuYWxpZ25lZFNhdEJvdW5kcztjWzBdLnNldEZyb21Qb2ludHNGaWVsZChzLCJ4IiksY1sxXS5zZXRGcm9tUG9pbnRzRmllbGQocywieSIpLGNbMl0uc2V0RnJvbVBvaW50c0ZpZWxkKHMsInoiKSx0aGlzLmludk1hdHJpeC5jb3B5KHRoaXMubWF0cml4KS5pbnZlcnQoKSx0aGlzLm5lZWRzVXBkYXRlPSExfX0oKSx6dC5wcm90b3R5cGUuaW50ZXJzZWN0c0JveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IEZlO3JldHVybiBmdW5jdGlvbihlKXt0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpO2NvbnN0IG49ZS5taW4scz1lLm1heCxyPXRoaXMuc2F0Qm91bmRzLG89dGhpcy5zYXRBeGVzLGE9dGhpcy5hbGlnbmVkU2F0Qm91bmRzO2lmKGkubWluPW4ueCxpLm1heD1zLngsYVswXS5pc1NlcGFyYXRlZChpKXx8KGkubWluPW4ueSxpLm1heD1zLnksYVsxXS5pc1NlcGFyYXRlZChpKSl8fChpLm1pbj1uLnosaS5tYXg9cy56LGFbMl0uaXNTZXBhcmF0ZWQoaSkpKXJldHVybiExO2ZvcihsZXQgYz0wO2M8MztjKyspe2NvbnN0IGw9b1tjXSxoPXJbY107aWYoaS5zZXRGcm9tQm94KGwsZSksaC5pc1NlcGFyYXRlZChpKSlyZXR1cm4hMX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmludGVyc2VjdHNUcmlhbmdsZT1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IG5lLHQ9bmV3IEFycmF5KDMpLGU9bmV3IEZlLG49bmV3IEZlLHM9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKG8pe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksby5pc0V4dGVuZGVkVHJpYW5nbGU/by5uZWVkc1VwZGF0ZSYmby51cGRhdGUoKTooaS5jb3B5KG8pLGkudXBkYXRlKCksbz1pKTtjb25zdCBhPXRoaXMuc2F0Qm91bmRzLGM9dGhpcy5zYXRBeGVzO3RbMF09by5hLHRbMV09by5iLHRbMl09by5jO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9YVtmXSxwPWNbZl07aWYoZS5zZXRGcm9tUG9pbnRzKHAsdCksZC5pc1NlcGFyYXRlZChlKSlyZXR1cm4hMX1jb25zdCBsPW8uc2F0Qm91bmRzLGg9by5zYXRBeGVzLHU9dGhpcy5wb2ludHM7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1sW2ZdLHA9aFtmXTtpZihlLnNldEZyb21Qb2ludHMocCx1KSxkLmlzU2VwYXJhdGVkKGUpKXJldHVybiExfWZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9Y1tmXTtmb3IobGV0IHA9MDtwPDQ7cCsrKXtjb25zdCB5PWhbcF07aWYocy5jcm9zc1ZlY3RvcnMoZCx5KSxlLnNldEZyb21Qb2ludHMocyx0KSxuLnNldEZyb21Qb2ludHMocyx1KSxlLmlzU2VwYXJhdGVkKG4pKXJldHVybiExfX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFRvUG9pbnQ9ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxlLmNvcHkodCkuYXBwbHlNYXRyaXg0KHRoaXMuaW52TWF0cml4KS5jbGFtcCh0aGlzLm1pbix0aGlzLm1heCkuYXBwbHlNYXRyaXg0KHRoaXMubWF0cml4KSxlfX0oKSx6dC5wcm90b3R5cGUuZGlzdGFuY2VUb1BvaW50PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChlLGkpLGUuZGlzdGFuY2VUbyhpKX19KCksenQucHJvdG90eXBlLmRpc3RhbmNlVG9Cb3g9ZnVuY3Rpb24oKXtjb25zdCBpPVsieCIsInkiLCJ6Il0sdD1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksZT1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksbj1uZXcgVCxzPW5ldyBUO3JldHVybiBmdW5jdGlvbihvLGE9MCxjPW51bGwsbD1udWxsKXtpZih0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpLHRoaXMuaW50ZXJzZWN0c0JveChvKSlyZXR1cm4oY3x8bCkmJihvLmdldENlbnRlcihzKSx0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocyxuKSxvLmNsb3Nlc3RQb2ludFRvUG9pbnQobixzKSxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpKSwwO2NvbnN0IGg9YSphLHU9by5taW4sZj1vLm1heCxkPXRoaXMucG9pbnRzO2xldCBwPTEvMDtmb3IobGV0IG09MDttPDg7bSsrKXtjb25zdCBnPWRbbV07cy5jb3B5KGcpLmNsYW1wKHUsZik7Y29uc3QgYj1nLmRpc3RhbmNlVG9TcXVhcmVkKHMpO2lmKGI8cCYmKHA9YixjJiZjLmNvcHkoZyksbCYmbC5jb3B5KHMpLGI8aCkpcmV0dXJuIE1hdGguc3FydChiKX1sZXQgeT0wO2ZvcihsZXQgbT0wO208MzttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe2NvbnN0IHc9KG0rMSklMyx4PShtKzIpJTMsTT1nPDx3fGI8PHgsQT0xPDxtfGc8PHd8Yjw8eCxfPWRbTV0sUz1kW0FdO3RbeV0uc2V0KF8sUyk7Y29uc3Qgej1pW21dLHY9aVt3XSxDPWlbeF0sUD1lW3ldLEY9UC5zdGFydCxCPVAuZW5kO0Zbel09dVt6XSxGW3ZdPWc/dVt2XTpmW3ZdLEZbQ109Yj91W0NdOmZbdl0sQlt6XT1mW3pdLEJbdl09Zz91W3ZdOmZbdl0sQltDXT1iP3VbQ106Zlt2XSx5Kyt9Zm9yKGxldCBtPTA7bTw9MTttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe3MueD1tP2YueDp1Lngscy55PWc/Zi55OnUueSxzLno9Yj9mLno6dS56LHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChzLG4pO2NvbnN0IHc9cy5kaXN0YW5jZVRvU3F1YXJlZChuKTtpZih3PHAmJihwPXcsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx3PGgpKXJldHVybiBNYXRoLnNxcnQodyl9Zm9yKGxldCBtPTA7bTwxMjttKyspe2NvbnN0IGc9dFttXTtmb3IobGV0IGI9MDtiPDEyO2IrKyl7Y29uc3Qgdz1lW2JdO0RvKGcsdyxuLHMpO2NvbnN0IHg9bi5kaXN0YW5jZVRvU3F1YXJlZChzKTtpZih4PHAmJihwPXgsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx4PGgpKXJldHVybiBNYXRoLnNxcnQoeCl9fXJldHVybiBNYXRoLnNxcnQocCl9fSgpO2NsYXNzIFVve2NvbnN0cnVjdG9yKHQpe3RoaXMuX2dldE5ld1ByaW1pdGl2ZT10LHRoaXMuX3ByaW1pdGl2ZXM9W119Z2V0UHJpbWl0aXZlKCl7Y29uc3QgdD10aGlzLl9wcmltaXRpdmVzO3JldHVybiB0Lmxlbmd0aD09PTA/dGhpcy5fZ2V0TmV3UHJpbWl0aXZlKCk6dC5wb3AoKX1yZWxlYXNlUHJpbWl0aXZlKHQpe3RoaXMuX3ByaW1pdGl2ZXMucHVzaCh0KX19Y2xhc3MgZmQgZXh0ZW5kcyBVb3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCgpPT5uZXcgbmUpfX1jb25zdCBpZT1uZXcgZmQ7Y2xhc3MgZGR7Y29uc3RydWN0b3IoKXt0aGlzLmZsb2F0MzJBcnJheT1udWxsLHRoaXMudWludDE2QXJyYXk9bnVsbCx0aGlzLnVpbnQzMkFycmF5PW51bGw7Y29uc3QgdD1bXTtsZXQgZT1udWxsO3RoaXMuc2V0QnVmZmVyPW49PntlJiZ0LnB1c2goZSksZT1uLHRoaXMuZmxvYXQzMkFycmF5PW5ldyBGbG9hdDMyQXJyYXkobiksdGhpcy51aW50MTZBcnJheT1uZXcgVWludDE2QXJyYXkobiksdGhpcy51aW50MzJBcnJheT1uZXcgVWludDMyQXJyYXkobil9LHRoaXMuY2xlYXJCdWZmZXI9KCk9PntlPW51bGwsdGhpcy5mbG9hdDMyQXJyYXk9bnVsbCx0aGlzLnVpbnQxNkFycmF5PW51bGwsdGhpcy51aW50MzJBcnJheT1udWxsLHQubGVuZ3RoIT09MCYmdGhpcy5zZXRCdWZmZXIodC5wb3AoKSl9fX1jb25zdCBudD1uZXcgZGQ7bGV0IEtlLFpuO2NvbnN0IFhuPVtdLENzPW5ldyBVbygoKT0+bmV3IGd0KTtmdW5jdGlvbiBwZChpLHQsZSxuLHMscil7S2U9Q3MuZ2V0UHJpbWl0aXZlKCksWm49Q3MuZ2V0UHJpbWl0aXZlKCksWG4ucHVzaChLZSxabiksbnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPVZvKDAsaS5nZW9tZXRyeSxlLG4scyxyKTtudC5jbGVhckJ1ZmZlcigpLENzLnJlbGVhc2VQcmltaXRpdmUoS2UpLENzLnJlbGVhc2VQcmltaXRpdmUoWm4pLFhuLnBvcCgpLFhuLnBvcCgpO2NvbnN0IGE9WG4ubGVuZ3RoO3JldHVybiBhPjAmJihabj1YblthLTFdLEtlPVhuW2EtMl0pLG99ZnVuY3Rpb24gVm8oaSx0LGUsbixzPW51bGwscj0wLG89MCl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udDtsZXQgaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1WdChpLGwpLGQ9S3QoaCxjKTtyZXR1cm4gbHQoaSxhLEtlKSxuKGYsZCwhMSxvLHIraSxLZSl9ZWxzZXtsZXQgej1mdW5jdGlvbihDKXtjb25zdHt1aW50MTZBcnJheTpQLHVpbnQzMkFycmF5OkZ9PW50O2xldCBCPUMqMjtmb3IoOyFrdChCLFApOylDPXRlKEMpLEI9QyoyO3JldHVybiBWdChDLEYpfSx2PWZ1bmN0aW9uKEMpe2NvbnN0e3VpbnQxNkFycmF5OlAsdWludDMyQXJyYXk6Rn09bnQ7bGV0IEI9QyoyO2Zvcig7IWt0KEIsUCk7KUM9ZWUoQyxGKSxCPUMqMjtyZXR1cm4gVnQoQyxGKStLdChCLFApfTtjb25zdCBmPXRlKGkpLGQ9ZWUoaSxsKTtsZXQgcD1mLHk9ZCxtLGcsYix3O2lmKHMmJihiPUtlLHc9Wm4sbHQocCxhLGIpLGx0KHksYSx3KSxtPXMoYiksZz1zKHcpLGc8bSkpe3A9ZCx5PWY7Y29uc3QgQz1tO209ZyxnPUMsYj13fWJ8fChiPUtlLGx0KHAsYSxiKSk7Y29uc3QgeD1rdChwKjIsYyksTT1lKGIseCxtLG8rMSxyK3ApO2xldCBBO2lmKE09PT1KYyl7Y29uc3QgQz16KHApLEY9dihwKS1DO0E9bihDLEYsITAsbysxLHIrcCxiKX1lbHNlIEE9TSYmVm8ocCx0LGUsbixzLHIsbysxKTtpZihBKXJldHVybiEwO3c9Wm4sbHQoeSxhLHcpO2NvbnN0IF89a3QoeSoyLGMpLFM9ZSh3LF8sZyxvKzEscit5KTtsZXQgRTtpZihTPT09SmMpe2NvbnN0IEM9eih5KSxGPXYoeSktQztFPW4oQyxGLCEwLG8rMSxyK3ksdyl9ZWxzZSBFPVMmJlZvKHksdCxlLG4scyxyLG8rMSk7cmV0dXJuISFFfX1jb25zdCBDaT1uZXcgVCxxbz1uZXcgVDtmdW5jdGlvbiB5ZChpLHQsZT17fSxuPTAscz0xLzApe2NvbnN0IHI9bipuLG89cypzO2xldCBhPTEvMCxjPW51bGw7aWYoaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6aD0+KENpLmNvcHkodCkuY2xhbXAoaC5taW4saC5tYXgpLENpLmRpc3RhbmNlVG9TcXVhcmVkKHQpKSxpbnRlcnNlY3RzQm91bmRzOihoLHUsZik9PmY8YSYmZjxvLGludGVyc2VjdHNUcmlhbmdsZTooaCx1KT0+e2guY2xvc2VzdFBvaW50VG9Qb2ludCh0LENpKTtjb25zdCBmPXQuZGlzdGFuY2VUb1NxdWFyZWQoQ2kpO3JldHVybiBmPGEmJihxby5jb3B5KENpKSxhPWYsYz11KSxmPHJ9fSksYT09PTEvMClyZXR1cm4gbnVsbDtjb25zdCBsPU1hdGguc3FydChhKTtyZXR1cm4gZS5wb2ludD9lLnBvaW50LmNvcHkocW8pOmUucG9pbnQ9cW8uY2xvbmUoKSxlLmRpc3RhbmNlPWwsZS5mYWNlSW5kZXg9YyxlfWNvbnN0IG1kPXBhcnNlSW50KEopPj0xNjkscG49bmV3IFQseW49bmV3IFQsbW49bmV3IFQsQnM9bmV3IFIsRnM9bmV3IFIsSXM9bmV3IFIscmw9bmV3IFQsb2w9bmV3IFQsYWw9bmV3IFQsQmk9bmV3IFQ7ZnVuY3Rpb24gZ2QoaSx0LGUsbixzLHIsbyxhKXtsZXQgYztpZihyPT09MT9jPWkuaW50ZXJzZWN0VHJpYW5nbGUobixlLHQsITAscyk6Yz1pLmludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHIhPT0yLHMpLGM9PT1udWxsKXJldHVybiBudWxsO2NvbnN0IGw9aS5vcmlnaW4uZGlzdGFuY2VUbyhzKTtyZXR1cm4gbDxvfHxsPmE/bnVsbDp7ZGlzdGFuY2U6bCxwb2ludDpzLmNsb25lKCl9fWZ1bmN0aW9uIHhkKGksdCxlLG4scyxyLG8sYSxjLGwsaCl7cG4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LHIpLHluLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxvKSxtbi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsYSk7Y29uc3QgdT1nZChpLHBuLHluLG1uLEJpLGMsbCxoKTtpZih1KXtjb25zdCBmPW5ldyBUO2V0LmdldEJhcnljb29yZChCaSxwbix5bixtbixmKSxuJiYoQnMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHIpLEZzLmZyb21CdWZmZXJBdHRyaWJ1dGUobixvKSxJcy5mcm9tQnVmZmVyQXR0cmlidXRlKG4sYSksdS51dj1ldC5nZXRJbnRlcnBvbGF0aW9uKEJpLHBuLHluLG1uLEJzLEZzLElzLG5ldyBSKSkscyYmKEJzLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxyKSxGcy5mcm9tQnVmZmVyQXR0cmlidXRlKHMsbyksSXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLGEpLHUudXYxPWV0LmdldEludGVycG9sYXRpb24oQmkscG4seW4sbW4sQnMsRnMsSXMsbmV3IFIpKSxlJiYocmwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHIpLG9sLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxvKSxhbC5mcm9tQnVmZmVyQXR0cmlidXRlKGUsYSksdS5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGlvbihCaSxwbix5bixtbixybCxvbCxhbCxuZXcgVCksdS5ub3JtYWwuZG90KGkuZGlyZWN0aW9uKT4wJiZ1Lm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGQ9e2E6cixiOm8sYzphLG5vcm1hbDpuZXcgVCxtYXRlcmlhbEluZGV4OjB9O2V0LmdldE5vcm1hbChwbix5bixtbixkLm5vcm1hbCksdS5mYWNlPWQsdS5mYWNlSW5kZXg9cixtZCYmKHUuYmFyeWNvb3JkPWYpfXJldHVybiB1fWZ1bmN0aW9uIGtzKGksdCxlLG4scyxyLG8pe2NvbnN0IGE9biozO2xldCBjPWErMCxsPWErMSxoPWErMjtjb25zdCB1PWkuaW5kZXg7aS5pbmRleCYmKGM9dS5nZXRYKGMpLGw9dS5nZXRYKGwpLGg9dS5nZXRYKGgpKTtjb25zdHtwb3NpdGlvbjpmLG5vcm1hbDpkLHV2OnAsdXYxOnl9PWkuYXR0cmlidXRlcyxtPXhkKGUsZixkLHAseSxjLGwsaCx0LHIsbyk7cmV0dXJuIG0/KG0uZmFjZUluZGV4PW4scyYmcy5wdXNoKG0pLG0pOm51bGx9ZnVuY3Rpb24geXQoaSx0LGUsbil7Y29uc3Qgcz1pLmEscj1pLmIsbz1pLmM7bGV0IGE9dCxjPXQrMSxsPXQrMjtlJiYoYT1lLmdldFgoYSksYz1lLmdldFgoYyksbD1lLmdldFgobCkpLHMueD1uLmdldFgoYSkscy55PW4uZ2V0WShhKSxzLno9bi5nZXRaKGEpLHIueD1uLmdldFgoYyksci55PW4uZ2V0WShjKSxyLno9bi5nZXRaKGMpLG8ueD1uLmdldFgobCksby55PW4uZ2V0WShsKSxvLno9bi5nZXRaKGwpfWZ1bmN0aW9uIHdkKGksdCxlLG4scyxyLG8sYSl7Y29uc3R7Z2VvbWV0cnk6YyxfaW5kaXJlY3RCdWZmZXI6bH09aTtmb3IobGV0IGg9bix1PW4rcztoPHU7aCsrKWtzKGMsdCxlLGgscixvLGEpfWZ1bmN0aW9uIGJkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmEsX2luZGlyZWN0QnVmZmVyOmN9PWk7bGV0IGw9MS8wLGg9bnVsbDtmb3IobGV0IHU9bixmPW4rczt1PGY7dSsrKXtsZXQgZDtkPWtzKGEsdCxlLHUsbnVsbCxyLG8pLGQmJmQuZGlzdGFuY2U8bCYmKGg9ZCxsPWQuZGlzdGFuY2UpfXJldHVybiBofWZ1bmN0aW9uIE1kKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmF9PWUse2luZGV4OmN9PWEsbD1hLmF0dHJpYnV0ZXMucG9zaXRpb247Zm9yKGxldCBoPWksdT10K2k7aDx1O2grKyl7bGV0IGY7aWYoZj1oLHl0KG8sZiozLGMsbCksby5uZWVkc1VwZGF0ZT0hMCxuKG8sZixzLHIpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIEFkKGksdD1udWxsKXt0JiZBcnJheS5pc0FycmF5KHQpJiYodD1uZXcgU2V0KHQpKTtjb25zdCBlPWkuZ2VvbWV0cnksbj1lLmluZGV4P2UuaW5kZXguYXJyYXk6bnVsbCxzPWUuYXR0cmlidXRlcy5wb3NpdGlvbjtsZXQgcixvLGEsYyxsPTA7Y29uc3QgaD1pLl9yb290cztmb3IobGV0IGY9MCxkPWgubGVuZ3RoO2Y8ZDtmKyspcj1oW2ZdLG89bmV3IFVpbnQzMkFycmF5KHIpLGE9bmV3IFVpbnQxNkFycmF5KHIpLGM9bmV3IEZsb2F0MzJBcnJheShyKSx1KDAsbCksbCs9ci5ieXRlTGVuZ3RoO2Z1bmN0aW9uIHUoZixkLHA9ITEpe2NvbnN0IHk9ZioyO2lmKGFbeSsxNV09PT16cyl7Y29uc3QgZz1vW2YrNl0sYj1hW3krMTRdO2xldCB3PTEvMCx4PTEvMCxNPTEvMCxBPS0xLzAsXz0tMS8wLFM9LTEvMDtmb3IobGV0IEU9MypnLHo9MyooZytiKTtFPHo7RSsrKXtsZXQgdj1uW0VdO2NvbnN0IEM9cy5nZXRYKHYpLFA9cy5nZXRZKHYpLEY9cy5nZXRaKHYpO0M8dyYmKHc9QyksQz5BJiYoQT1DKSxQPHgmJih4PVApLFA+XyYmKF89UCksRjxNJiYoTT1GKSxGPlMmJihTPUYpfXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1ffHxjW2YrNV0hPT1TPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09XyxjW2YrNV09UywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsXz0hMTt0P018fChBPXQuaGFzKHcpLF89dC5oYXMoeCksTT0hQSYmIV8pOihBPSEwLF89ITApO2NvbnN0IFM9TXx8QSxFPU18fF87bGV0IHo9ITE7UyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFY9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+Vj9rOlZ9cmV0dXJuIEN9fX1mdW5jdGlvbiB0bihpLHQsZSxuLHMpe2xldCByLG8sYSxjLGwsaDtjb25zdCB1PTEvZS5kaXJlY3Rpb24ueCxmPTEvZS5kaXJlY3Rpb24ueSxkPTEvZS5kaXJlY3Rpb24ueixwPWUub3JpZ2luLngseT1lLm9yaWdpbi55LG09ZS5vcmlnaW4uejtsZXQgZz10W2ldLGI9dFtpKzNdLHc9dFtpKzFdLHg9dFtpKzMrMV0sTT10W2krMl0sQT10W2krMysyXTtyZXR1cm4gdT49MD8ocj0oZy1wKSp1LG89KGItcCkqdSk6KHI9KGItcCkqdSxvPShnLXApKnUpLGY+PTA/KGE9KHcteSkqZixjPSh4LXkpKmYpOihhPSh4LXkpKmYsYz0ody15KSpmKSxyPmN8fGE+b3x8KChhPnJ8fGlzTmFOKHIpKSYmKHI9YSksKGM8b3x8aXNOYU4obykpJiYobz1jKSxkPj0wPyhsPShNLW0pKmQsaD0oQS1tKSpkKToobD0oQS1tKSpkLGg9KE0tbSkqZCkscj5ofHxsPm8pPyExOigobD5yfHxyIT09cikmJihyPWwpLChoPG98fG8hPT1vKSYmKG89aCkscjw9cyYmbz49bil9ZnVuY3Rpb24gX2QoaSx0LGUsbixzLHIsbyxhKXtjb25zdHtnZW9tZXRyeTpjLF9pbmRpcmVjdEJ1ZmZlcjpsfT1pO2ZvcihsZXQgaD1uLHU9bitzO2g8dTtoKyspe2xldCBmPWw/bFtoXTpoO2tzKGMsdCxlLGYscixvLGEpfX1mdW5jdGlvbiBTZChpLHQsZSxuLHMscixvKXtjb25zdHtnZW9tZXRyeTphLF9pbmRpcmVjdEJ1ZmZlcjpjfT1pO2xldCBsPTEvMCxoPW51bGw7Zm9yKGxldCB1PW4sZj1uK3M7dTxmO3UrKyl7bGV0IGQ7ZD1rcyhhLHQsZSxjP2NbdV06dSxudWxsLHIsbyksZCYmZC5kaXN0YW5jZTxsJiYoaD1kLGw9ZC5kaXN0YW5jZSl9cmV0dXJuIGh9ZnVuY3Rpb24gdmQoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YX09ZSx7aW5kZXg6Y309YSxsPWEuYXR0cmlidXRlcy5wb3NpdGlvbjtmb3IobGV0IGg9aSx1PXQraTtoPHU7aCsrKXtsZXQgZjtpZihmPWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoaCkseXQobyxmKjMsYyxsKSxvLm5lZWRzVXBkYXRlPSEwLG4obyxmLHMscikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gemQoaSx0LGUsbixzLHIsbyl7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKSxIbygwLGksZSxuLHMscixvKSxudC5jbGVhckJ1ZmZlcigpfWZ1bmN0aW9uIEhvKGksdCxlLG4scyxyLG8pe2NvbnN0e2Zsb2F0MzJBcnJheTphLHVpbnQxNkFycmF5OmMsdWludDMyQXJyYXk6bH09bnQsaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1WdChpLGwpLGQ9S3QoaCxjKTt3ZCh0LGUsbixmLGQscyxyLG8pfWVsc2V7Y29uc3QgZj10ZShpKTt0bihmLGEsbixyLG8pJiZIbyhmLHQsZSxuLHMscixvKTtjb25zdCBkPWVlKGksbCk7dG4oZCxhLG4scixvKSYmSG8oZCx0LGUsbixzLHIsbyl9fWNvbnN0IFRkPVsieCIsInkiLCJ6Il07ZnVuY3Rpb24gRWQoaSx0LGUsbixzLHIpe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSk7Y29uc3Qgbz1XbygwLGksZSxuLHMscik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksb31mdW5jdGlvbiBXbyhpLHQsZSxuLHMscil7Y29uc3R7ZmxvYXQzMkFycmF5Om8sdWludDE2QXJyYXk6YSx1aW50MzJBcnJheTpjfT1udDtsZXQgbD1pKjI7aWYoa3QobCxhKSl7Y29uc3QgdT1WdChpLGMpLGY9S3QobCxhKTtyZXR1cm4gYmQodCxlLG4sdSxmLHMscil9ZWxzZXtjb25zdCB1PW5sKGksYyksZj1UZFt1XSxwPW4uZGlyZWN0aW9uW2ZdPj0wO2xldCB5LG07cD8oeT10ZShpKSxtPWVlKGksYykpOih5PWVlKGksYyksbT10ZShpKSk7Y29uc3QgYj10bih5LG8sbixzLHIpP1dvKHksdCxlLG4scyxyKTpudWxsO2lmKGIpe2NvbnN0IE09Yi5wb2ludFtmXTtpZihwP008PW9bbSt1XTpNPj1vW20rdSszXSlyZXR1cm4gYn1jb25zdCB4PXRuKG0sbyxuLHMscik/V28obSx0LGUsbixzLHIpOm51bGw7cmV0dXJuIGImJng/Yi5kaXN0YW5jZTw9eC5kaXN0YW5jZT9iOng6Ynx8eHx8bnVsbH19Y29uc3QgTnM9bmV3IGd0LEpuPW5ldyBuZSxZbj1uZXcgbmUsRmk9bmV3IHN0LGNsPW5ldyB6dCxScz1uZXcgenQ7ZnVuY3Rpb24gUGQoaSx0LGUsbil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBzPUdvKDAsaSxlLG4pO3JldHVybiBudC5jbGVhckJ1ZmZlcigpLHN9ZnVuY3Rpb24gR28oaSx0LGUsbixzPW51bGwpe2NvbnN0e2Zsb2F0MzJBcnJheTpyLHVpbnQxNkFycmF5Om8sdWludDMyQXJyYXk6YX09bnQ7bGV0IGM9aSoyO2lmKHM9PT1udWxsJiYoZS5ib3VuZGluZ0JveHx8ZS5jb21wdXRlQm91bmRpbmdCb3goKSxjbC5zZXQoZS5ib3VuZGluZ0JveC5taW4sZS5ib3VuZGluZ0JveC5tYXgsbikscz1jbCksa3QoYyxvKSl7Y29uc3QgaD10Lmdlb21ldHJ5LHU9aC5pbmRleCxmPWguYXR0cmlidXRlcy5wb3NpdGlvbixkPWUuaW5kZXgscD1lLmF0dHJpYnV0ZXMucG9zaXRpb24seT1WdChpLGEpLG09S3QoYyxvKTtpZihGaS5jb3B5KG4pLmludmVydCgpLGUuYm91bmRzVHJlZSlyZXR1cm4gbHQoaSxyLFJzKSxScy5tYXRyaXguY29weShGaSksUnMubmVlZHNVcGRhdGU9ITAsZS5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpiPT5Scy5pbnRlcnNlY3RzQm94KGIpLGludGVyc2VjdHNUcmlhbmdsZTpiPT57Yi5hLmFwcGx5TWF0cml4NChuKSxiLmIuYXBwbHlNYXRyaXg0KG4pLGIuYy5hcHBseU1hdHJpeDQobiksYi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHc9eSozLHg9KG0reSkqMzt3PHg7dys9MylpZih5dChZbix3LHUsZiksWW4ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoWW4pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15KjMsYj0obSt5KSozO2c8YjtnKz0zKXt5dChKbixnLHUsZiksSm4uYS5hcHBseU1hdHJpeDQoRmkpLEpuLmIuYXBwbHlNYXRyaXg0KEZpKSxKbi5jLmFwcGx5TWF0cml4NChGaSksSm4ubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB3PTAseD1kLmNvdW50O3c8eDt3Kz0zKWlmKHl0KFluLHcsZCxwKSxZbi5uZWVkc1VwZGF0ZT0hMCxKbi5pbnRlcnNlY3RzVHJpYW5nbGUoWW4pKXJldHVybiEwfX1lbHNle2NvbnN0IGg9aSs4LHU9YVtpKzZdO3JldHVybiBsdChoLHIsTnMpLCEhKHMuaW50ZXJzZWN0c0JveChOcykmJkdvKGgsdCxlLG4scyl8fChsdCh1LHIsTnMpLHMuaW50ZXJzZWN0c0JveChOcykmJkdvKHUsdCxlLG4scykpKX19Y29uc3QgTHM9bmV3IHN0LFpvPW5ldyB6dCxJaT1uZXcgenQsQ2Q9bmV3IFQsQmQ9bmV3IFQsRmQ9bmV3IFQsSWQ9bmV3IFQ7ZnVuY3Rpb24ga2QoaSx0LGUsbj17fSxzPXt9LHI9MCxvPTEvMCl7dC5ib3VuZGluZ0JveHx8dC5jb21wdXRlQm91bmRpbmdCb3goKSxaby5zZXQodC5ib3VuZGluZ0JveC5taW4sdC5ib3VuZGluZ0JveC5tYXgsZSksWm8ubmVlZHNVcGRhdGU9ITA7Y29uc3QgYT1pLmdlb21ldHJ5LGM9YS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9YS5pbmRleCxoPXQuYXR0cmlidXRlcy5wb3NpdGlvbix1PXQuaW5kZXgsZj1pZS5nZXRQcmltaXRpdmUoKSxkPWllLmdldFByaW1pdGl2ZSgpO2xldCBwPUNkLHk9QmQsbT1udWxsLGc9bnVsbDtzJiYobT1GZCxnPUlkKTtsZXQgYj0xLzAsdz1udWxsLHg9bnVsbDtyZXR1cm4gTHMuY29weShlKS5pbnZlcnQoKSxJaS5tYXRyaXguY29weShMcyksaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6TT0+Wm8uZGlzdGFuY2VUb0JveChNKSxpbnRlcnNlY3RzQm91bmRzOihNLEEsXyk9Pl88YiYmXzxvPyhBJiYoSWkubWluLmNvcHkoTS5taW4pLElpLm1heC5jb3B5KE0ubWF4KSxJaS5uZWVkc1VwZGF0ZT0hMCksITApOiExLGludGVyc2VjdHNSYW5nZTooTSxBKT0+e2lmKHQuYm91bmRzVHJlZSlyZXR1cm4gdC5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpTPT5JaS5kaXN0YW5jZVRvQm94KFMpLGludGVyc2VjdHNCb3VuZHM6KFMsRSx6KT0+ejxiJiZ6PG8saW50ZXJzZWN0c1JhbmdlOihTLEUpPT57Zm9yKGxldCB6PVMsdj1TK0U7ejx2O3orKyl7eXQoZCwzKnosdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgQz1NLFA9TStBO0M8UDtDKyspe3l0KGYsMypDLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBGPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihGPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Rix3PUMseD16KSxGPHIpcmV0dXJuITB9fX19KTt7Y29uc3QgXz1Hbih0KTtmb3IobGV0IFM9MCxFPV87UzxFO1MrKyl7eXQoZCwzKlMsdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgej1NLHY9TStBO3o8djt6Kyspe3l0KGYsMyp6LGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBDPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihDPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Qyx3PXoseD1TKSxDPHIpcmV0dXJuITB9fX19fSksaWUucmVsZWFzZVByaW1pdGl2ZShmKSxpZS5yZWxlYXNlUHJpbWl0aXZlKGQpLGI9PT0xLzA/bnVsbDoobi5wb2ludD9uLnBvaW50LmNvcHkoeSk6bi5wb2ludD15LmNsb25lKCksbi5kaXN0YW5jZT1iLG4uZmFjZUluZGV4PXcscyYmKHMucG9pbnQ/cy5wb2ludC5jb3B5KGcpOnMucG9pbnQ9Zy5jbG9uZSgpLHMucG9pbnQuYXBwbHlNYXRyaXg0KExzKSx5LmFwcGx5TWF0cml4NChMcykscy5kaXN0YW5jZT15LnN1YihzLnBvaW50KS5sZW5ndGgoKSxzLmZhY2VJbmRleD14KSxuKX1mdW5jdGlvbiBOZChpLHQ9bnVsbCl7dCYmQXJyYXkuaXNBcnJheSh0KSYmKHQ9bmV3IFNldCh0KSk7Y29uc3QgZT1pLmdlb21ldHJ5LG49ZS5pbmRleD9lLmluZGV4LmFycmF5Om51bGwscz1lLmF0dHJpYnV0ZXMucG9zaXRpb247bGV0IHIsbyxhLGMsbD0wO2NvbnN0IGg9aS5fcm9vdHM7Zm9yKGxldCBmPTAsZD1oLmxlbmd0aDtmPGQ7ZisrKXI9aFtmXSxvPW5ldyBVaW50MzJBcnJheShyKSxhPW5ldyBVaW50MTZBcnJheShyKSxjPW5ldyBGbG9hdDMyQXJyYXkociksdSgwLGwpLGwrPXIuYnl0ZUxlbmd0aDtmdW5jdGlvbiB1KGYsZCxwPSExKXtjb25zdCB5PWYqMjtpZihhW3krMTVdPT09enMpe2NvbnN0IGc9b1tmKzZdLGI9YVt5KzE0XTtsZXQgdz0xLzAseD0xLzAsTT0xLzAsQT0tMS8wLF89LTEvMCxTPS0xLzA7Zm9yKGxldCBFPWcsej1nK2I7RTx6O0UrKyl7Y29uc3Qgdj0zKmkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoRSk7Zm9yKGxldCBDPTA7QzwzO0MrKyl7bGV0IFA9ditDO1A9bj9uW1BdOlA7Y29uc3QgRj1zLmdldFgoUCksQj1zLmdldFkoUCksST1zLmdldFooUCk7Rjx3JiYodz1GKSxGPkEmJihBPUYpLEI8eCYmKHg9QiksQj5fJiYoXz1CKSxJPE0mJihNPUkpLEk+UyYmKFM9SSl9fXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1ffHxjW2YrNV0hPT1TPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09XyxjW2YrNV09UywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsXz0hMTt0P018fChBPXQuaGFzKHcpLF89dC5oYXMoeCksTT0hQSYmIV8pOihBPSEwLF89ITApO2NvbnN0IFM9TXx8QSxFPU18fF87bGV0IHo9ITE7UyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFY9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+Vj9rOlZ9cmV0dXJuIEN9fX1mdW5jdGlvbiBSZChpLHQsZSxuLHMscixvKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pLFhvKDAsaSxlLG4scyxyLG8pLG50LmNsZWFyQnVmZmVyKCl9ZnVuY3Rpb24gWG8oaSx0LGUsbixzLHIsbyl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udCxoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVZ0KGksbCksZD1LdChoLGMpO19kKHQsZSxuLGYsZCxzLHIsbyl9ZWxzZXtjb25zdCBmPXRlKGkpO3RuKGYsYSxuLHIsbykmJlhvKGYsdCxlLG4scyxyLG8pO2NvbnN0IGQ9ZWUoaSxsKTt0bihkLGEsbixyLG8pJiZYbyhkLHQsZSxuLHMscixvKX19Y29uc3QgTGQ9WyJ4IiwieSIsInoiXTtmdW5jdGlvbiBPZChpLHQsZSxuLHMscil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPUpvKDAsaSxlLG4scyxyKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxvfWZ1bmN0aW9uIEpvKGksdCxlLG4scyxyKXtjb25zdHtmbG9hdDMyQXJyYXk6byx1aW50MTZBcnJheTphLHVpbnQzMkFycmF5OmN9PW50O2xldCBsPWkqMjtpZihrdChsLGEpKXtjb25zdCB1PVZ0KGksYyksZj1LdChsLGEpO3JldHVybiBTZCh0LGUsbix1LGYscyxyKX1lbHNle2NvbnN0IHU9bmwoaSxjKSxmPUxkW3VdLHA9bi5kaXJlY3Rpb25bZl0+PTA7bGV0IHksbTtwPyh5PXRlKGkpLG09ZWUoaSxjKSk6KHk9ZWUoaSxjKSxtPXRlKGkpKTtjb25zdCBiPXRuKHksbyxuLHMscik/Sm8oeSx0LGUsbixzLHIpOm51bGw7aWYoYil7Y29uc3QgTT1iLnBvaW50W2ZdO2lmKHA/TTw9b1ttK3VdOk0+PW9bbSt1KzNdKXJldHVybiBifWNvbnN0IHg9dG4obSxvLG4scyxyKT9KbyhtLHQsZSxuLHMscik6bnVsbDtyZXR1cm4gYiYmeD9iLmRpc3RhbmNlPD14LmRpc3RhbmNlP2I6eDpifHx4fHxudWxsfX1jb25zdCBPcz1uZXcgZ3Qsam49bmV3IG5lLFFuPW5ldyBuZSxraT1uZXcgc3QsbGw9bmV3IHp0LERzPW5ldyB6dDtmdW5jdGlvbiBEZChpLHQsZSxuKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IHM9WW8oMCxpLGUsbik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksc31mdW5jdGlvbiBZbyhpLHQsZSxuLHM9bnVsbCl7Y29uc3R7ZmxvYXQzMkFycmF5OnIsdWludDE2QXJyYXk6byx1aW50MzJBcnJheTphfT1udDtsZXQgYz1pKjI7aWYocz09PW51bGwmJihlLmJvdW5kaW5nQm94fHxlLmNvbXB1dGVCb3VuZGluZ0JveCgpLGxsLnNldChlLmJvdW5kaW5nQm94Lm1pbixlLmJvdW5kaW5nQm94Lm1heCxuKSxzPWxsKSxrdChjLG8pKXtjb25zdCBoPXQuZ2VvbWV0cnksdT1oLmluZGV4LGY9aC5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9ZS5pbmRleCxwPWUuYXR0cmlidXRlcy5wb3NpdGlvbix5PVZ0KGksYSksbT1LdChjLG8pO2lmKGtpLmNvcHkobikuaW52ZXJ0KCksZS5ib3VuZHNUcmVlKXJldHVybiBsdChpLHIsRHMpLERzLm1hdHJpeC5jb3B5KGtpKSxEcy5uZWVkc1VwZGF0ZT0hMCxlLmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmI9PkRzLmludGVyc2VjdHNCb3goYiksaW50ZXJzZWN0c1RyaWFuZ2xlOmI9PntiLmEuYXBwbHlNYXRyaXg0KG4pLGIuYi5hcHBseU1hdHJpeDQobiksYi5jLmFwcGx5TWF0cml4NChuKSxiLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgdz15LHg9bSt5O3c8eDt3KyspaWYoeXQoUW4sMyp0LnJlc29sdmVUcmlhbmdsZUluZGV4KHcpLHUsZiksUW4ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoUW4pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15LGI9bSt5O2c8YjtnKyspe2NvbnN0IHc9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChnKTt5dChqbiwzKncsdSxmKSxqbi5hLmFwcGx5TWF0cml4NChraSksam4uYi5hcHBseU1hdHJpeDQoa2kpLGpuLmMuYXBwbHlNYXRyaXg0KGtpKSxqbi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHg9MCxNPWQuY291bnQ7eDxNO3grPTMpaWYoeXQoUW4seCxkLHApLFFuLm5lZWRzVXBkYXRlPSEwLGpuLmludGVyc2VjdHNUcmlhbmdsZShRbikpcmV0dXJuITB9fWVsc2V7Y29uc3QgaD1pKzgsdT1hW2krNl07cmV0dXJuIGx0KGgscixPcyksISEocy5pbnRlcnNlY3RzQm94KE9zKSYmWW8oaCx0LGUsbixzKXx8KGx0KHUscixPcykscy5pbnRlcnNlY3RzQm94KE9zKSYmWW8odSx0LGUsbixzKSkpfX1jb25zdCAkcz1uZXcgc3Qsam89bmV3IHp0LE5pPW5ldyB6dCwkZD1uZXcgVCxVZD1uZXcgVCxWZD1uZXcgVCxxZD1uZXcgVDtmdW5jdGlvbiBIZChpLHQsZSxuPXt9LHM9e30scj0wLG89MS8wKXt0LmJvdW5kaW5nQm94fHx0LmNvbXB1dGVCb3VuZGluZ0JveCgpLGpvLnNldCh0LmJvdW5kaW5nQm94Lm1pbix0LmJvdW5kaW5nQm94Lm1heCxlKSxqby5uZWVkc1VwZGF0ZT0hMDtjb25zdCBhPWkuZ2VvbWV0cnksYz1hLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1hLmluZGV4LGg9dC5hdHRyaWJ1dGVzLnBvc2l0aW9uLHU9dC5pbmRleCxmPWllLmdldFByaW1pdGl2ZSgpLGQ9aWUuZ2V0UHJpbWl0aXZlKCk7bGV0IHA9JGQseT1VZCxtPW51bGwsZz1udWxsO3MmJihtPVZkLGc9cWQpO2xldCBiPTEvMCx3PW51bGwseD1udWxsO3JldHVybiAkcy5jb3B5KGUpLmludmVydCgpLE5pLm1hdHJpeC5jb3B5KCRzKSxpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpNPT5qby5kaXN0YW5jZVRvQm94KE0pLGludGVyc2VjdHNCb3VuZHM6KE0sQSxfKT0+XzxiJiZfPG8/KEEmJihOaS5taW4uY29weShNLm1pbiksTmkubWF4LmNvcHkoTS5tYXgpLE5pLm5lZWRzVXBkYXRlPSEwKSwhMCk6ITEsaW50ZXJzZWN0c1JhbmdlOihNLEEpPT57aWYodC5ib3VuZHNUcmVlKXtjb25zdCBfPXQuYm91bmRzVHJlZTtyZXR1cm4gXy5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6Uz0+TmkuZGlzdGFuY2VUb0JveChTKSxpbnRlcnNlY3RzQm91bmRzOihTLEUseik9Pno8YiYmejxvLGludGVyc2VjdHNSYW5nZTooUyxFKT0+e2ZvcihsZXQgej1TLHY9UytFO3o8djt6Kyspe2NvbnN0IEM9Xy5yZXNvbHZlVHJpYW5nbGVJbmRleCh6KTt5dChkLDMqQyx1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCBQPU0sRj1NK0E7UDxGO1ArKyl7Y29uc3QgQj1pLnJlc29sdmVUcmlhbmdsZUluZGV4KFApO3l0KGYsMypCLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBJPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihJPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9SSx3PVAseD16KSxJPHIpcmV0dXJuITB9fX19KX1lbHNle2NvbnN0IF89R24odCk7Zm9yKGxldCBTPTAsRT1fO1M8RTtTKyspe3l0KGQsMypTLHUsaCksZC5hLmFwcGx5TWF0cml4NChlKSxkLmIuYXBwbHlNYXRyaXg0KGUpLGQuYy5hcHBseU1hdHJpeDQoZSksZC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHo9TSx2PU0rQTt6PHY7eisrKXtjb25zdCBDPWkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoeik7eXQoZiwzKkMsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IFA9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKFA8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1QLHc9eix4PVMpLFA8cilyZXR1cm4hMH19fX19KSxpZS5yZWxlYXNlUHJpbWl0aXZlKGYpLGllLnJlbGVhc2VQcmltaXRpdmUoZCksYj09PTEvMD9udWxsOihuLnBvaW50P24ucG9pbnQuY29weSh5KTpuLnBvaW50PXkuY2xvbmUoKSxuLmRpc3RhbmNlPWIsbi5mYWNlSW5kZXg9dyxzJiYocy5wb2ludD9zLnBvaW50LmNvcHkoZyk6cy5wb2ludD1nLmNsb25lKCkscy5wb2ludC5hcHBseU1hdHJpeDQoJHMpLHkuYXBwbHlNYXRyaXg0KCRzKSxzLmRpc3RhbmNlPXkuc3ViKHMucG9pbnQpLmxlbmd0aCgpLHMuZmFjZUluZGV4PXgpLG4pfWZ1bmN0aW9uIFdkKCl7cmV0dXJuIHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciE9InVuZGVmaW5lZCJ9Y29uc3QgUmk9bmV3IG50LmNvbnN0cnVjdG9yLFVzPW5ldyBudC5jb25zdHJ1Y3Rvcixlbj1uZXcgVW8oKCk9Pm5ldyBndCksS249bmV3IGd0LHRpPW5ldyBndCxRbz1uZXcgZ3QsS289bmV3IGd0O2xldCB0YT0hMTtmdW5jdGlvbiBHZChpLHQsZSxuKXtpZih0YSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IFJlY3Vyc2l2ZSBjYWxscyB0byBidmhjYXN0IG5vdCBzdXBwb3J0ZWQuIik7dGE9ITA7Y29uc3Qgcz1pLl9yb290cyxyPXQuX3Jvb3RzO2xldCBvLGE9MCxjPTA7Y29uc3QgbD1uZXcgc3QoKS5jb3B5KGUpLmludmVydCgpO2ZvcihsZXQgaD0wLHU9cy5sZW5ndGg7aDx1O2grKyl7Umkuc2V0QnVmZmVyKHNbaF0pLGM9MDtjb25zdCBmPWVuLmdldFByaW1pdGl2ZSgpO2x0KDAsUmkuZmxvYXQzMkFycmF5LGYpLGYuYXBwbHlNYXRyaXg0KGwpO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwJiYoVXMuc2V0QnVmZmVyKHJbZF0pLG89ZmUoMCwwLGUsbCxuLGEsYywwLDAsZiksVXMuY2xlYXJCdWZmZXIoKSxjKz1yW2RdLmxlbmd0aCwhbyk7ZCsrKTtpZihlbi5yZWxlYXNlUHJpbWl0aXZlKGYpLFJpLmNsZWFyQnVmZmVyKCksYSs9c1toXS5sZW5ndGgsbylicmVha31yZXR1cm4gdGE9ITEsb31mdW5jdGlvbiBmZShpLHQsZSxuLHMscj0wLG89MCxhPTAsYz0wLGw9bnVsbCxoPSExKXtsZXQgdSxmO2g/KHU9VXMsZj1SaSk6KHU9UmksZj1Vcyk7Y29uc3QgZD11LmZsb2F0MzJBcnJheSxwPXUudWludDMyQXJyYXkseT11LnVpbnQxNkFycmF5LG09Zi5mbG9hdDMyQXJyYXksZz1mLnVpbnQzMkFycmF5LGI9Zi51aW50MTZBcnJheSx3PWkqMix4PXQqMixNPWt0KHcseSksQT1rdCh4LGIpO2xldCBfPSExO2lmKEEmJk0paD9fPXMoVnQodCxnKSxLdCh0KjIsYiksVnQoaSxwKSxLdChpKjIseSksYyxvK3QsYSxyK2kpOl89cyhWdChpLHApLEt0KGkqMix5KSxWdCh0LGcpLEt0KHQqMixiKSxhLHIraSxjLG8rdCk7ZWxzZSBpZihBKXtjb25zdCBTPWVuLmdldFByaW1pdGl2ZSgpO2x0KHQsbSxTKSxTLmFwcGx5TWF0cml4NChlKTtjb25zdCBFPXRlKGkpLHo9ZWUoaSxwKTtsdChFLGQsS24pLGx0KHosZCx0aSk7Y29uc3Qgdj1TLmludGVyc2VjdHNCb3goS24pLEM9Uy5pbnRlcnNlY3RzQm94KHRpKTtfPXYmJmZlKHQsRSxuLGUscyxvLHIsYyxhKzEsUywhaCl8fEMmJmZlKHQseixuLGUscyxvLHIsYyxhKzEsUywhaCksZW4ucmVsZWFzZVByaW1pdGl2ZShTKX1lbHNle2NvbnN0IFM9dGUodCksRT1lZSh0LGcpO2x0KFMsbSxRbyksbHQoRSxtLEtvKTtjb25zdCB6PWwuaW50ZXJzZWN0c0JveChRbyksdj1sLmludGVyc2VjdHNCb3goS28pO2lmKHomJnYpXz1mZShpLFMsZSxuLHMscixvLGEsYysxLGwsaCl8fGZlKGksRSxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNlIGlmKHopaWYoTSlfPWZlKGksUyxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNle2NvbnN0IEM9ZW4uZ2V0UHJpbWl0aXZlKCk7Qy5jb3B5KFFvKS5hcHBseU1hdHJpeDQoZSk7Y29uc3QgUD10ZShpKSxGPWVlKGkscCk7bHQoUCxkLEtuKSxsdChGLGQsdGkpO2NvbnN0IEI9Qy5pbnRlcnNlY3RzQm94KEtuKSxJPUMuaW50ZXJzZWN0c0JveCh0aSk7Xz1CJiZmZShTLFAsbixlLHMsbyxyLGMsYSsxLEMsIWgpfHxJJiZmZShTLEYsbixlLHMsbyxyLGMsYSsxLEMsIWgpLGVuLnJlbGVhc2VQcmltaXRpdmUoQyl9ZWxzZSBpZih2KWlmKE0pXz1mZShpLEUsZSxuLHMscixvLGEsYysxLGwsaCk7ZWxzZXtjb25zdCBDPWVuLmdldFByaW1pdGl2ZSgpO0MuY29weShLbykuYXBwbHlNYXRyaXg0KGUpO2NvbnN0IFA9dGUoaSksRj1lZShpLHApO2x0KFAsZCxLbiksbHQoRixkLHRpKTtjb25zdCBCPUMuaW50ZXJzZWN0c0JveChLbiksST1DLmludGVyc2VjdHNCb3godGkpO189QiYmZmUoRSxQLG4sZSxzLG8scixjLGErMSxDLCFoKXx8SSYmZmUoRSxGLG4sZSxzLG8scixjLGErMSxDLCFoKSxlbi5yZWxlYXNlUHJpbWl0aXZlKEMpfX1yZXR1cm4gX31jb25zdCBWcz1uZXcgenQsaGw9bmV3IGd0LFpkPXtzdHJhdGVneTpYYyxtYXhEZXB0aDo0MCxtYXhMZWFmVHJpczoxMCx1c2VTaGFyZWRBcnJheUJ1ZmZlcjohMSxzZXRCb3VuZGluZ0JveDohMCxvblByb2dyZXNzOm51bGwsaW5kaXJlY3Q6ITEsdmVyYm9zZTohMCxyYW5nZTpudWxsfTtjbGFzcyBlYXtzdGF0aWMgc2VyaWFsaXplKHQsZT17fSl7ZT1GdCh7Y2xvbmVCdWZmZXJzOiEwfSxlKTtjb25zdCBuPXQuZ2VvbWV0cnkscz10Ll9yb290cyxyPXQuX2luZGlyZWN0QnVmZmVyLG89bi5nZXRJbmRleCgpO2xldCBhO3JldHVybiBlLmNsb25lQnVmZmVycz9hPXtyb290czpzLm1hcChjPT5jLnNsaWNlKCkpLGluZGV4Om8/by5hcnJheS5zbGljZSgpOm51bGwsaW5kaXJlY3RCdWZmZXI6cj9yLnNsaWNlKCk6bnVsbH06YT17cm9vdHM6cyxpbmRleDpvP28uYXJyYXk6bnVsbCxpbmRpcmVjdEJ1ZmZlcjpyfSxhfXN0YXRpYyBkZXNlcmlhbGl6ZSh0LGUsbj17fSl7bj1GdCh7c2V0SW5kZXg6ITAsaW5kaXJlY3Q6ISF0LmluZGlyZWN0QnVmZmVyfSxuKTtjb25zdHtpbmRleDpzLHJvb3RzOnIsaW5kaXJlY3RCdWZmZXI6b309dCxhPW5ldyBlYShlLEdlKEZ0KHt9LG4pLHtba29dOiEwfSkpO2lmKGEuX3Jvb3RzPXIsYS5faW5kaXJlY3RCdWZmZXI9b3x8bnVsbCxuLnNldEluZGV4KXtjb25zdCBjPWUuZ2V0SW5kZXgoKTtpZihjPT09bnVsbCl7Y29uc3QgbD1uZXcgeHQodC5pbmRleCwxLCExKTtlLnNldEluZGV4KGwpfWVsc2UgYy5hcnJheSE9PXMmJihjLmFycmF5LnNldChzKSxjLm5lZWRzVXBkYXRlPSEwKX1yZXR1cm4gYX1nZXQgaW5kaXJlY3QoKXtyZXR1cm4hIXRoaXMuX2luZGlyZWN0QnVmZmVyfWNvbnN0cnVjdG9yKHQsZT17fSl7aWYodC5pc0J1ZmZlckdlb21ldHJ5KXtpZih0LmluZGV4JiZ0LmluZGV4LmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGUgaW5kZXggYXR0cmlidXRlLiIpfWVsc2UgdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBPbmx5IEJ1ZmZlckdlb21ldHJpZXMgYXJlIHN1cHBvcnRlZC4iKTtpZihlPU9iamVjdC5hc3NpZ24oR2UoRnQoe30sWmQpLHtba29dOiExfSksZSksZS51c2VTaGFyZWRBcnJheUJ1ZmZlciYmIVdkKCkpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBTaGFyZWRBcnJheUJ1ZmZlciBpcyBub3QgYXZhaWxhYmxlLiIpO3RoaXMuZ2VvbWV0cnk9dCx0aGlzLl9yb290cz1udWxsLHRoaXMuX2luZGlyZWN0QnVmZmVyPW51bGwsZVtrb118fChjZCh0aGlzLGUpLCF0LmJvdW5kaW5nQm94JiZlLnNldEJvdW5kaW5nQm94JiYodC5ib3VuZGluZ0JveD10aGlzLmdldEJvdW5kaW5nQm94KG5ldyBndCkpKSx0aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4PWUuaW5kaXJlY3Q/bj0+dGhpcy5faW5kaXJlY3RCdWZmZXJbbl06bj0+bn1yZWZpdCh0PW51bGwpe3JldHVybih0aGlzLmluZGlyZWN0P05kOkFkKSh0aGlzLHQpfXRyYXZlcnNlKHQsZT0wKXtjb25zdCBuPXRoaXMuX3Jvb3RzW2VdLHM9bmV3IFVpbnQzMkFycmF5KG4pLHI9bmV3IFVpbnQxNkFycmF5KG4pO28oMCk7ZnVuY3Rpb24gbyhhLGM9MCl7Y29uc3QgbD1hKjIsaD1yW2wrMTVdPT09enM7aWYoaCl7Y29uc3QgdT1zW2ErNl0sZj1yW2wrMTRdO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksdSxmKX1lbHNle2NvbnN0IHU9YStUaS80LGY9c1thKzZdLGQ9c1thKzddO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksZCl8fChvKHUsYysxKSxvKGYsYysxKSl9fX1yYXljYXN0KHQsZT0wLG49MCxzPTEvMCl7Y29uc3Qgcj10aGlzLl9yb290cyxvPXRoaXMuZ2VvbWV0cnksYT1bXSxjPWUuaXNNYXRlcmlhbCxsPUFycmF5LmlzQXJyYXkoZSksaD1vLmdyb3Vwcyx1PWM/ZS5zaWRlOmUsZj10aGlzLmluZGlyZWN0P1JkOnpkO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwO2QrKyl7Y29uc3QgeT1sP2VbaFtkXS5tYXRlcmlhbEluZGV4XS5zaWRlOnUsbT1hLmxlbmd0aDtpZihmKHRoaXMsZCx5LHQsYSxuLHMpLGwpe2NvbnN0IGc9aFtkXS5tYXRlcmlhbEluZGV4O2ZvcihsZXQgYj1tLHc9YS5sZW5ndGg7Yjx3O2IrKylhW2JdLmZhY2UubWF0ZXJpYWxJbmRleD1nfX1yZXR1cm4gYX1yYXljYXN0Rmlyc3QodCxlPTAsbj0wLHM9MS8wKXtjb25zdCByPXRoaXMuX3Jvb3RzLG89dGhpcy5nZW9tZXRyeSxhPWUuaXNNYXRlcmlhbCxjPUFycmF5LmlzQXJyYXkoZSk7bGV0IGw9bnVsbDtjb25zdCBoPW8uZ3JvdXBzLHU9YT9lLnNpZGU6ZSxmPXRoaXMuaW5kaXJlY3Q/T2Q6RWQ7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHA7ZCsrKXtjb25zdCB5PWM/ZVtoW2RdLm1hdGVyaWFsSW5kZXhdLnNpZGU6dSxtPWYodGhpcyxkLHksdCxuLHMpO20hPW51bGwmJihsPT1udWxsfHxtLmRpc3RhbmNlPGwuZGlzdGFuY2UpJiYobD1tLGMmJihtLmZhY2UubWF0ZXJpYWxJbmRleD1oW2RdLm1hdGVyaWFsSW5kZXgpKX1yZXR1cm4gbH1pbnRlcnNlY3RzR2VvbWV0cnkodCxlKXtsZXQgbj0hMTtjb25zdCBzPXRoaXMuX3Jvb3RzLHI9dGhpcy5pbmRpcmVjdD9EZDpQZDtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YSYmKG49cih0aGlzLG8sdCxlKSwhbik7bysrKTtyZXR1cm4gbn1zaGFwZWNhc3QodCl7Y29uc3QgZT1pZS5nZXRQcmltaXRpdmUoKSxuPXRoaXMuaW5kaXJlY3Q/dmQ6TWQ7bGV0e2JvdW5kc1RyYXZlcnNlT3JkZXI6cyxpbnRlcnNlY3RzQm91bmRzOnIsaW50ZXJzZWN0c1JhbmdlOm8saW50ZXJzZWN0c1RyaWFuZ2xlOmF9PXQ7aWYobyYmYSl7Y29uc3QgdT1vO289KGYsZCxwLHksbSk9PnUoZixkLHAseSxtKT8hMDpuKGYsZCx0aGlzLGEscCx5LGUpfWVsc2Ugb3x8KGE/bz0odSxmLGQscCk9Pm4odSxmLHRoaXMsYSxkLHAsZSk6bz0odSxmLGQpPT5kKTtsZXQgYz0hMSxsPTA7Y29uc3QgaD10aGlzLl9yb290cztmb3IobGV0IHU9MCxmPWgubGVuZ3RoO3U8Zjt1Kyspe2NvbnN0IGQ9aFt1XTtpZihjPXBkKHRoaXMsdSxyLG8scyxsKSxjKWJyZWFrO2wrPWQuYnl0ZUxlbmd0aH1yZXR1cm4gaWUucmVsZWFzZVByaW1pdGl2ZShlKSxjfWJ2aGNhc3QodCxlLG4pe2xldHtpbnRlcnNlY3RzUmFuZ2VzOnMsaW50ZXJzZWN0c1RyaWFuZ2xlczpyfT1uO2NvbnN0IG89aWUuZ2V0UHJpbWl0aXZlKCksYT10aGlzLmdlb21ldHJ5LmluZGV4LGM9dGhpcy5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9dGhpcy5pbmRpcmVjdD9wPT57Y29uc3QgeT10aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4KHApO3l0KG8seSozLGEsYyl9OnA9Pnt5dChvLHAqMyxhLGMpfSxoPWllLmdldFByaW1pdGl2ZSgpLHU9dC5nZW9tZXRyeS5pbmRleCxmPXQuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixkPXQuaW5kaXJlY3Q/cD0+e2NvbnN0IHk9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChwKTt5dChoLHkqMyx1LGYpfTpwPT57eXQoaCxwKjMsdSxmKX07aWYocil7Y29uc3QgcD0oeSxtLGcsYix3LHgsTSxBKT0+e2ZvcihsZXQgXz1nLFM9ZytiO188UztfKyspe2QoXyksaC5hLmFwcGx5TWF0cml4NChlKSxoLmIuYXBwbHlNYXRyaXg0KGUpLGguYy5hcHBseU1hdHJpeDQoZSksaC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IEU9eSx6PXkrbTtFPHo7RSsrKWlmKGwoRSksby5uZWVkc1VwZGF0ZT0hMCxyKG8saCxFLF8sdyx4LE0sQSkpcmV0dXJuITB9cmV0dXJuITF9O2lmKHMpe2NvbnN0IHk9cztzPWZ1bmN0aW9uKG0sZyxiLHcseCxNLEEsXyl7cmV0dXJuIHkobSxnLGIsdyx4LE0sQSxfKT8hMDpwKG0sZyxiLHcseCxNLEEsXyl9fWVsc2Ugcz1wfXJldHVybiBHZCh0aGlzLHQsZSxzKX1pbnRlcnNlY3RzQm94KHQsZSl7cmV0dXJuIFZzLnNldCh0Lm1pbix0Lm1heCxlKSxWcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpuPT5Wcy5pbnRlcnNlY3RzQm94KG4pLGludGVyc2VjdHNUcmlhbmdsZTpuPT5Wcy5pbnRlcnNlY3RzVHJpYW5nbGUobil9KX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczplPT50LmludGVyc2VjdHNCb3goZSksaW50ZXJzZWN0c1RyaWFuZ2xlOmU9PmUuaW50ZXJzZWN0c1NwaGVyZSh0KX0pfWNsb3Nlc3RQb2ludFRvR2VvbWV0cnkodCxlLG49e30scz17fSxyPTAsbz0xLzApe3JldHVybih0aGlzLmluZGlyZWN0P0hkOmtkKSh0aGlzLHQsZSxuLHMscixvKX1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZT17fSxuPTAscz0xLzApe3JldHVybiB5ZCh0aGlzLHQsZSxuLHMpfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0Lm1ha2VFbXB0eSgpLHRoaXMuX3Jvb3RzLmZvckVhY2gobj0+e2x0KDAsbmV3IEZsb2F0MzJBcnJheShuKSxobCksdC51bmlvbihobCl9KSx0fX1jb25zdCB1bD0xZS02LFhkPXVsKi41LGZsPU1hdGgucG93KDEwLC1NYXRoLmxvZzEwKHVsKSksSmQ9WGQqZmw7ZnVuY3Rpb24gd2UoaSl7cmV0dXJufn4oaSpmbCtKZCl9ZnVuY3Rpb24gWWQoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfWB9ZnVuY3Rpb24gZGwoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfSwke3dlKGkueil9YH1mdW5jdGlvbiBqZChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9LCR7d2UoaS56KX0sJHt3ZShpLncpfWB9ZnVuY3Rpb24gUWQoaSx0LGUpe2UuZGlyZWN0aW9uLnN1YlZlY3RvcnModCxpKS5ub3JtYWxpemUoKTtjb25zdCBuPWkuZG90KGUuZGlyZWN0aW9uKTtyZXR1cm4gZS5vcmlnaW4uY29weShpKS5hZGRTY2FsZWRWZWN0b3IoZS5kaXJlY3Rpb24sLW4pLGV9ZnVuY3Rpb24gcGwoKXtyZXR1cm4gdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIn1mdW5jdGlvbiBLZChpKXtpZihpLmJ1ZmZlciBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKXJldHVybiBpO2NvbnN0IHQ9aS5jb25zdHJ1Y3RvcixlPWkuYnVmZmVyLG49bmV3IFNoYXJlZEFycmF5QnVmZmVyKGUuYnl0ZUxlbmd0aCkscz1uZXcgVWludDhBcnJheShlKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobikuc2V0KHMsMCksbmV3IHQobil9ZnVuY3Rpb24gdDAoaSx0PUFycmF5QnVmZmVyKXtyZXR1cm4gaT42NTUzNT9uZXcgVWludDMyQXJyYXkobmV3IHQoNCppKSk6bmV3IFVpbnQxNkFycmF5KG5ldyB0KDIqaSkpfWZ1bmN0aW9uIGUwKGksdCl7aWYoIWkuaW5kZXgpe2NvbnN0IGU9aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50LG49dC51c2VTaGFyZWRBcnJheUJ1ZmZlcj9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPXQwKGUsbik7aS5zZXRJbmRleChuZXcgeHQocywxKSk7Zm9yKGxldCByPTA7cjxlO3IrKylzW3JdPXJ9fWZ1bmN0aW9uIG4wKGkpe3JldHVybiBpLmluZGV4P2kuaW5kZXguY291bnQ6aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWZ1bmN0aW9uIG5hKGkpe3JldHVybiBuMChpKS8zfWNvbnN0IGkwPTFlLTgsczA9bmV3IFQ7ZnVuY3Rpb24gcjAoaSl7cmV0dXJufn4oaS8zKX1mdW5jdGlvbiBvMChpKXtyZXR1cm4gaSUzfWZ1bmN0aW9uIHlsKGksdCl7cmV0dXJuIGkuc3RhcnQtdC5zdGFydH1mdW5jdGlvbiBtbChpLHQpe3JldHVybiBzMC5zdWJWZWN0b3JzKHQsaS5vcmlnaW4pLmRvdChpLmRpcmVjdGlvbil9ZnVuY3Rpb24gYTAoaSx0LGUsbj1pMCl7aS5zb3J0KHlsKSx0LnNvcnQoeWwpO2ZvcihsZXQgYT0wO2E8aS5sZW5ndGg7YSsrKXtjb25zdCBjPWlbYV07Zm9yKGxldCBsPTA7bDx0Lmxlbmd0aDtsKyspe2NvbnN0IGg9dFtsXTtpZighKGguc3RhcnQ+Yy5lbmQpKXtpZihjLmVuZDxoLnN0YXJ0fHxoLmVuZDxjLnN0YXJ0KWNvbnRpbnVlO2lmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPj1oLmVuZClyKGguZW5kLGMuZW5kKXx8aS5zcGxpY2UoYSsxLDAse3N0YXJ0OmguZW5kLGVuZDpjLmVuZCxpbmRleDpjLmluZGV4fSksYy5lbmQ9aC5zdGFydCxoLnN0YXJ0PTAsaC5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPD1oLmVuZClyKGMuZW5kLGguZW5kKXx8dC5zcGxpY2UobCsxLDAse3N0YXJ0OmMuZW5kLGVuZDpoLmVuZCxpbmRleDpoLmluZGV4fSksaC5lbmQ9Yy5zdGFydCxjLnN0YXJ0PTAsYy5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPD1oLmVuZCl7Y29uc3QgdT1jLmVuZDtjLmVuZD1oLnN0YXJ0LGguc3RhcnQ9dX1lbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPj1oLmVuZCl7Y29uc3QgdT1oLmVuZDtoLmVuZD1jLnN0YXJ0LGMuc3RhcnQ9dX1lbHNlIHRocm93IG5ldyBFcnJvcn1pZihlLmhhcyhjLmluZGV4KXx8ZS5zZXQoYy5pbmRleCxbXSksZS5oYXMoaC5pbmRleCl8fGUuc2V0KGguaW5kZXgsW10pLGUuZ2V0KGMuaW5kZXgpLnB1c2goaC5pbmRleCksZS5nZXQoaC5pbmRleCkucHVzaChjLmluZGV4KSxvKGgpJiYodC5zcGxpY2UobCwxKSxsLS0pLG8oYykpe2kuc3BsaWNlKGEsMSksYS0tO2JyZWFrfX19cyhpKSxzKHQpO2Z1bmN0aW9uIHMoYSl7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKyspbyhhW2NdKSYmKGEuc3BsaWNlKGMsMSksYy0tKX1mdW5jdGlvbiByKGEsYyl7cmV0dXJuIE1hdGguYWJzKGMtYSk8bn1mdW5jdGlvbiBvKGEpe3JldHVybiBNYXRoLmFicyhhLmVuZC1hLnN0YXJ0KTxufX1jb25zdCBnbD0xZS01LHhsPTFlLTQ7Y2xhc3MgYzB7Y29uc3RydWN0b3IoKXt0aGlzLl9yYXlzPVtdfWFkZFJheSh0KXt0aGlzLl9yYXlzLnB1c2godCl9ZmluZENsb3Nlc3RSYXkodCl7Y29uc3QgZT10aGlzLl9yYXlzLG49dC5jbG9uZSgpO24uZGlyZWN0aW9uLm11bHRpcGx5U2NhbGFyKC0xKTtsZXQgcz0xLzAscj1udWxsO2ZvcihsZXQgYz0wLGw9ZS5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1lW2NdO2lmKG8oaCx0KSYmbyhoLG4pKWNvbnRpbnVlO2NvbnN0IHU9YShoLHQpLGY9YShoLG4pLGQ9TWF0aC5taW4odSxmKTtkPHMmJihzPWQscj1oKX1yZXR1cm4gcjtmdW5jdGlvbiBvKGMsbCl7Y29uc3QgaD1jLm9yaWdpbi5kaXN0YW5jZVRvKGwub3JpZ2luKT5nbDtyZXR1cm4gYy5kaXJlY3Rpb24uYW5nbGVUbyhsLmRpcmVjdGlvbik+eGx8fGh9ZnVuY3Rpb24gYShjLGwpe2NvbnN0IGg9Yy5vcmlnaW4uZGlzdGFuY2VUbyhsLm9yaWdpbiksdT1jLmRpcmVjdGlvbi5hbmdsZVRvKGwuZGlyZWN0aW9uKTtyZXR1cm4gaC9nbCt1L3hsfX19Y29uc3QgaWE9bmV3IFQsc2E9bmV3IFQscXM9bmV3IGFvO2Z1bmN0aW9uIGwwKGksdCxlKXtjb25zdCBuPWkuYXR0cmlidXRlcyxzPWkuaW5kZXgscj1uLnBvc2l0aW9uLG89bmV3IE1hcCxhPW5ldyBNYXAsYz1BcnJheS5mcm9tKHQpLGw9bmV3IGMwO2ZvcihsZXQgaD0wLHU9Yy5sZW5ndGg7aDx1O2grKyl7Y29uc3QgZj1jW2hdLGQ9cjAoZikscD1vMChmKTtsZXQgeT0zKmQrcCxtPTMqZCsocCsxKSUzO3MmJih5PXMuZ2V0WCh5KSxtPXMuZ2V0WChtKSksaWEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLHkpLHNhLmZyb21CdWZmZXJBdHRyaWJ1dGUocixtKSxRZChpYSxzYSxxcyk7bGV0IGcsYj1sLmZpbmRDbG9zZXN0UmF5KHFzKTtiPT09bnVsbCYmKGI9cXMuY2xvbmUoKSxsLmFkZFJheShiKSksYS5oYXMoYil8fGEuc2V0KGIse2ZvcndhcmQ6W10scmV2ZXJzZTpbXSxyYXk6Yn0pLGc9YS5nZXQoYik7bGV0IHc9bWwoYixpYSkseD1tbChiLHNhKTt3PngmJihbdyx4XT1beCx3XSkscXMuZGlyZWN0aW9uLmRvdChiLmRpcmVjdGlvbik8MD9nLnJldmVyc2UucHVzaCh7c3RhcnQ6dyxlbmQ6eCxpbmRleDpmfSk6Zy5mb3J3YXJkLnB1c2goe3N0YXJ0OncsZW5kOngsaW5kZXg6Zn0pfXJldHVybiBhLmZvckVhY2goKHtmb3J3YXJkOmgscmV2ZXJzZTp1fSxmKT0+e2EwKGgsdSxvLGUpLGgubGVuZ3RoPT09MCYmdS5sZW5ndGg9PT0wJiZhLmRlbGV0ZShmKX0pLHtkaXNqb2ludENvbm5lY3Rpdml0eU1hcDpvLGZyYWdtZW50TWFwOmF9fWNvbnN0IGgwPW5ldyBSLHJhPW5ldyBULHUwPW5ldyBZdCxvYT1bIiIsIiIsIiJdO2NsYXNzIGYwe2NvbnN0cnVjdG9yKHQ9bnVsbCl7dGhpcy5kYXRhPW51bGwsdGhpcy5kaXNqb2ludENvbm5lY3Rpb25zPW51bGwsdGhpcy51bm1hdGNoZWREaXNqb2ludEVkZ2VzPW51bGwsdGhpcy51bm1hdGNoZWRFZGdlcz0tMSx0aGlzLm1hdGNoZWRFZGdlcz0tMSx0aGlzLnVzZURyYXdSYW5nZT0hMCx0aGlzLnVzZUFsbEF0dHJpYnV0ZXM9ITEsdGhpcy5tYXRjaERpc2pvaW50RWRnZXM9ITEsdGhpcy5kZWdlbmVyYXRlRXBzaWxvbj0xZS04LHQmJnRoaXMudXBkYXRlRnJvbSh0KX1nZXRTaWJsaW5nVHJpYW5nbGVJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOn5+KG4vMyl9Z2V0U2libGluZ0VkZ2VJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOm4lM31nZXREaXNqb2ludFNpYmxpbmdUcmlhbmdsZUluZGljZXModCxlKXtjb25zdCBuPXQqMytlLHM9dGhpcy5kaXNqb2ludENvbm5lY3Rpb25zLmdldChuKTtyZXR1cm4gcz9zLm1hcChyPT5+fihyLzMpKTpbXX1nZXREaXNqb2ludFNpYmxpbmdFZGdlSW5kaWNlcyh0LGUpe2NvbnN0IG49dCozK2Uscz10aGlzLmRpc2pvaW50Q29ubmVjdGlvbnMuZ2V0KG4pO3JldHVybiBzP3MubWFwKHI9PnIlMyk6W119aXNGdWxseUNvbm5lY3RlZCgpe3JldHVybiB0aGlzLnVubWF0Y2hlZEVkZ2VzPT09MH11cGRhdGVGcm9tKHQpe2NvbnN0e3VzZUFsbEF0dHJpYnV0ZXM6ZSx1c2VEcmF3UmFuZ2U6bixtYXRjaERpc2pvaW50RWRnZXM6cyxkZWdlbmVyYXRlRXBzaWxvbjpyfT10aGlzLG89ZT93OmIsYT1uZXcgTWFwLHthdHRyaWJ1dGVzOmN9PXQsbD1lP09iamVjdC5rZXlzKGMpOm51bGwsaD10LmluZGV4LHU9Yy5wb3NpdGlvbjtsZXQgZj1uYSh0KTtjb25zdCBkPWY7bGV0IHA9MDtuJiYocD10LmRyYXdSYW5nZS5zdGFydCx0LmRyYXdSYW5nZS5jb3VudCE9PTEvMCYmKGY9fn4odC5kcmF3UmFuZ2UuY291bnQvMykpKTtsZXQgeT10aGlzLmRhdGE7KCF5fHx5Lmxlbmd0aDwzKmQpJiYoeT1uZXcgSW50MzJBcnJheSgzKmQpKSx5LmZpbGwoLTEpO2xldCBtPTAsZz1uZXcgU2V0O2ZvcihsZXQgeD1wLE09ZiozK3A7eDxNO3grPTMpe2NvbnN0IEE9eDtmb3IobGV0IF89MDtfPDM7XysrKXtsZXQgUz1BK187aCYmKFM9aC5nZXRYKFMpKSxvYVtfXT1vKFMpfWZvcihsZXQgXz0wO188MztfKyspe2NvbnN0IFM9KF8rMSklMyxFPW9hW19dLHo9b2FbU10sdj1gJHt6fV8ke0V9YDtpZihhLmhhcyh2KSl7Y29uc3QgQz1BK18sUD1hLmdldCh2KTt5W0NdPVAseVtQXT1DLGEuZGVsZXRlKHYpLG0rPTIsZy5kZWxldGUoUCl9ZWxzZXtjb25zdCBDPWAke0V9XyR7en1gLFA9QStfO2Euc2V0KEMsUCksZy5hZGQoUCl9fX1pZihzKXtjb25zdHtmcmFnbWVudE1hcDp4LGRpc2pvaW50Q29ubmVjdGl2aXR5TWFwOk19PWwwKHQsZyxyKTtnLmNsZWFyKCkseC5mb3JFYWNoKCh7Zm9yd2FyZDpBLHJldmVyc2U6X30pPT57QS5mb3JFYWNoKCh7aW5kZXg6U30pPT5nLmFkZChTKSksXy5mb3JFYWNoKCh7aW5kZXg6U30pPT5nLmFkZChTKSl9KSx0aGlzLnVubWF0Y2hlZERpc2pvaW50RWRnZXM9eCx0aGlzLmRpc2pvaW50Q29ubmVjdGlvbnM9TSxtPWYqMy1nLnNpemV9dGhpcy5tYXRjaGVkRWRnZXM9bSx0aGlzLnVubWF0Y2hlZEVkZ2VzPWcuc2l6ZSx0aGlzLmRhdGE9eTtmdW5jdGlvbiBiKHgpe3JldHVybiByYS5mcm9tQnVmZmVyQXR0cmlidXRlKHUseCksZGwocmEpfWZ1bmN0aW9uIHcoeCl7bGV0IE09IiI7Zm9yKGxldCBBPTAsXz1sLmxlbmd0aDtBPF87QSsrKXtjb25zdCBTPWNbbFtBXV07bGV0IEU7c3dpdGNoKFMuaXRlbVNpemUpe2Nhc2UgMTpFPXdlKFMuZ2V0WCh4KSk7YnJlYWs7Y2FzZSAyOkU9WWQoaDAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShTLHgpKTticmVhaztjYXNlIDM6RT1kbChyYS5mcm9tQnVmZmVyQXR0cmlidXRlKFMseCkpO2JyZWFrO2Nhc2UgNDpFPWpkKHUwLmZyb21CdWZmZXJBdHRyaWJ1dGUoUyx4KSk7YnJlYWt9TSE9PSIiJiYoTSs9InwiKSxNKz1FfXJldHVybiBNfX19Y2xhc3MgSHMgZXh0ZW5kcyBoZntjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzQnJ1c2g9ITAsdGhpcy5fcHJldmlvdXNNYXRyaXg9bmV3IHN0LHRoaXMuX3ByZXZpb3VzTWF0cml4LmVsZW1lbnRzLmZpbGwoMCl9bWFya1VwZGF0ZWQoKXt0aGlzLl9wcmV2aW91c01hdHJpeC5jb3B5KHRoaXMubWF0cml4KX1pc0RpcnR5KCl7Y29uc3R7bWF0cml4OnQsX3ByZXZpb3VzTWF0cml4OmV9PXRoaXMsbj10LmVsZW1lbnRzLHM9ZS5lbGVtZW50cztmb3IobGV0IHI9MDtyPDE2O3IrKylpZihuW3JdIT09c1tyXSlyZXR1cm4hMDtyZXR1cm4hMX1wcmVwYXJlR2VvbWV0cnkoKXtjb25zdCB0PXRoaXMuZ2VvbWV0cnksZT10LmF0dHJpYnV0ZXMsbj1wbCgpO2lmKG4pZm9yKGNvbnN0IHMgaW4gZSl7Y29uc3Qgcj1lW3NdO2lmKHIuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl0aHJvdyBuZXcgRXJyb3IoIkJydXNoOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIik7ci5hcnJheT1LZChyLmFycmF5KX1pZih0LmJvdW5kc1RyZWV8fChlMCh0LHt1c2VTaGFyZWRBcnJheUJ1ZmZlcjpufSksdC5ib3VuZHNUcmVlPW5ldyBlYSh0LHttYXhMZWFmVHJpczozLGluZGlyZWN0OiEwLHVzZVNoYXJlZEFycmF5QnVmZmVyOm59KSksdC5oYWxmRWRnZXN8fCh0LmhhbGZFZGdlcz1uZXcgZjAodCkpLCF0Lmdyb3VwSW5kaWNlcyl7Y29uc3Qgcz1uYSh0KSxyPW5ldyBVaW50MTZBcnJheShzKSxvPXQuZ3JvdXBzO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKyl7Y29uc3R7c3RhcnQ6bCxjb3VudDpofT1vW2FdO2ZvcihsZXQgdT1sLzMsZj0obCtoKS8zO3U8Zjt1Kyspclt1XT1hfXQuZ3JvdXBJbmRpY2VzPXJ9fWRpc3Bvc2VDYWNoZURhdGEoKXtjb25zdHtnZW9tZXRyeTp0fT10aGlzO3QuaGFsZkVkZ2VzPW51bGwsdC5ib3VuZHNUcmVlPW51bGwsdC5ncm91cEluZGljZXM9bnVsbH19Y29uc3QgZDA9MWUtMTQsYWE9bmV3IFQsd2w9bmV3IFQsYmw9bmV3IFQ7ZnVuY3Rpb24gbm4oaSx0PWQwKXthYS5zdWJWZWN0b3JzKGkuYixpLmEpLHdsLnN1YlZlY3RvcnMoaS5jLGkuYSksYmwuc3ViVmVjdG9ycyhpLmIsaS5jKTtjb25zdCBlPWFhLmFuZ2xlVG8od2wpLG49YWEuYW5nbGVUbyhibCkscz1NYXRoLlBJLWUtbjtyZXR1cm4gTWF0aC5hYnMoZSk8dHx8TWF0aC5hYnMobik8dHx8TWF0aC5hYnMocyk8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYik8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dHx8aS5iLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dH1jb25zdCBjYT0xZS0xMCxMaT0xZS0xMCxwMD0xZS0xMCxJZT1uZXcgUXQsZnQ9bmV3IFF0LGtlPW5ldyBULGxhPW5ldyBULE1sPW5ldyBULFdzPW5ldyBNbyxoYT1uZXcgbmU7Y2xhc3MgeTB7Y29uc3RydWN0b3IoKXt0aGlzLl9wb29sPVtdLHRoaXMuX2luZGV4PTB9Z2V0VHJpYW5nbGUoKXtyZXR1cm4gdGhpcy5faW5kZXg+PXRoaXMuX3Bvb2wubGVuZ3RoJiZ0aGlzLl9wb29sLnB1c2gobmV3IGV0KSx0aGlzLl9wb29sW3RoaXMuX2luZGV4KytdfWNsZWFyKCl7dGhpcy5faW5kZXg9MH1yZXNldCgpe3RoaXMuX3Bvb2wubGVuZ3RoPTAsdGhpcy5faW5kZXg9MH19Y2xhc3MgbTB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlUG9vbD1uZXcgeTAsdGhpcy50cmlhbmdsZXM9W10sdGhpcy5ub3JtYWw9bmV3IFQsdGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMX1pbml0aWFsaXplKHQpe3RoaXMucmVzZXQoKTtjb25zdHt0cmlhbmdsZXM6ZSx0cmlhbmdsZVBvb2w6bixub3JtYWw6c309dGhpcztpZihBcnJheS5pc0FycmF5KHQpKWZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdO2lmKHI9PT0wKWEuZ2V0Tm9ybWFsKHMpO2Vsc2UgaWYoTWF0aC5hYnMoMS1hLmdldE5vcm1hbChrZSkuZG90KHMpKT5jYSl0aHJvdyBuZXcgRXJyb3IoIlRyaWFuZ2xlIFNwbGl0dGVyOiBDYW5ub3QgaW5pdGlhbGl6ZSB3aXRoIHRyaWFuZ2xlcyB0aGF0IGhhdmUgZGlmZmVyZW50IG5vcm1hbHMuIik7Y29uc3QgYz1uLmdldFRyaWFuZ2xlKCk7Yy5jb3B5KGEpLGUucHVzaChjKX1lbHNle3QuZ2V0Tm9ybWFsKHMpO2NvbnN0IHI9bi5nZXRUcmlhbmdsZSgpO3IuY29weSh0KSxlLnB1c2gocil9fXNwbGl0QnlUcmlhbmdsZSh0KXtjb25zdHtub3JtYWw6ZSx0cmlhbmdsZXM6bn09dGhpcztpZih0LmdldE5vcm1hbChsYSkubm9ybWFsaXplKCksTWF0aC5hYnMoMS1NYXRoLmFicyhsYS5kb3QoZSkpKTxwMCl7dGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTthLmNvcGxhbmFyQ291bnQ9MH1jb25zdCBzPVt0LmEsdC5iLHQuY107Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz0ocisxKSUzLGE9c1tyXSxjPXNbb107a2Uuc3ViVmVjdG9ycyhjLGEpLm5vcm1hbGl6ZSgpLE1sLmNyb3NzVmVjdG9ycyhsYSxrZSksV3Muc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQoTWwsYSksdGhpcy5zcGxpdEJ5UGxhbmUoV3MsdCl9fWVsc2UgdC5nZXRQbGFuZShXcyksdGhpcy5zcGxpdEJ5UGxhbmUoV3MsdCl9c3BsaXRCeVBsYW5lKHQsZSl7Y29uc3R7dHJpYW5nbGVzOm4sdHJpYW5nbGVQb29sOnN9PXRoaXM7aGEuY29weShlKSxoYS5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTtpZighaGEuaW50ZXJzZWN0c1RyaWFuZ2xlKGEsSWUsITApKWNvbnRpbnVlO2NvbnN0e2E6YyxiOmwsYzpofT1hO2xldCB1PTAsZj0tMSxkPSExLHA9W10seT1bXTtjb25zdCBtPVtjLGwsaF07Zm9yKGxldCBnPTA7ZzwzO2crKyl7Y29uc3QgYj0oZysxKSUzO0llLnN0YXJ0LmNvcHkobVtnXSksSWUuZW5kLmNvcHkobVtiXSk7Y29uc3Qgdz10LmRpc3RhbmNlVG9Qb2ludChJZS5zdGFydCkseD10LmRpc3RhbmNlVG9Qb2ludChJZS5lbmQpO2lmKE1hdGguYWJzKHcpPExpJiZNYXRoLmFicyh4KTxMaSl7ZD0hMDticmVha31pZih3PjA/cC5wdXNoKGcpOnkucHVzaChnKSxNYXRoLmFicyh3KTxMaSljb250aW51ZTtsZXQgTT0hIXQuaW50ZXJzZWN0TGluZShJZSxrZSk7IU0mJk1hdGguYWJzKHgpPExpJiYoa2UuY29weShJZS5lbmQpLE09ITApLE0mJiEoa2UuZGlzdGFuY2VUbyhJZS5zdGFydCk8Y2EpJiYoa2UuZGlzdGFuY2VUbyhJZS5lbmQpPGNhJiYoZj1nKSx1PT09MD9mdC5zdGFydC5jb3B5KGtlKTpmdC5lbmQuY29weShrZSksdSsrKX1pZighZCYmdT09PTImJmZ0LmRpc3RhbmNlKCk+TGkpaWYoZiE9PS0xKXtmPShmKzEpJTM7bGV0IGc9MDtnPT09ZiYmKGc9KGcrMSklMyk7bGV0IGI9ZysxO2I9PT1mJiYoYj0oYisxKSUzKTtjb25zdCB3PXMuZ2V0VHJpYW5nbGUoKTt3LmEuY29weShtW2JdKSx3LmIuY29weShmdC5lbmQpLHcuYy5jb3B5KGZ0LnN0YXJ0KSxubih3KXx8bi5wdXNoKHcpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LnN0YXJ0KSxhLmMuY29weShmdC5lbmQpLG5uKGEpJiYobi5zcGxpY2UociwxKSxyLS0sby0tKX1lbHNle2NvbnN0IGc9cC5sZW5ndGg+PTI/eVswXTpwWzBdO2lmKGc9PT0wKXtsZXQgQT1mdC5zdGFydDtmdC5zdGFydD1mdC5lbmQsZnQuZW5kPUF9Y29uc3QgYj0oZysxKSUzLHc9KGcrMiklMyx4PXMuZ2V0VHJpYW5nbGUoKSxNPXMuZ2V0VHJpYW5nbGUoKTttW2JdLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LnN0YXJ0KTxtW3ddLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LmVuZCk/KHguYS5jb3B5KG1bYl0pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LnN0YXJ0KSk6KHguYS5jb3B5KG1bd10pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LmVuZCkpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LmVuZCksYS5jLmNvcHkoZnQuc3RhcnQpLG5uKHgpfHxuLnB1c2goeCksbm4oTSl8fG4ucHVzaChNKSxubihhKSYmKG4uc3BsaWNlKHIsMSksci0tLG8tLSl9ZWxzZSB1PT09MyYmY29uc29sZS53YXJuKCJUcmlhbmdsZUNsaXBwZXI6IENvcGxhbmFyIGNsaXAgbm90IGhhbmRsZWQiKX19cmVzZXQoKXt0aGlzLnRyaWFuZ2xlcy5sZW5ndGg9MCx0aGlzLnRyaWFuZ2xlUG9vbC5jbGVhcigpLHRoaXMuY29wbGFuYXJUcmlhbmdsZVVzZWQ9ITF9fWZ1bmN0aW9uIGcwKGkpe3JldHVybiBpPX5+aSxpKzQtaSU0fWNsYXNzIEFse2NvbnN0cnVjdG9yKHQsZT01MDApe3RoaXMuZXhwYW5zaW9uRmFjdG9yPTEuNSx0aGlzLnR5cGU9dCx0aGlzLmxlbmd0aD0wLHRoaXMuYXJyYXk9bnVsbCx0aGlzLnNldFNpemUoZSl9c2V0VHlwZSh0KXtpZih0aGlzLmxlbmd0aCE9PTApdGhyb3cgbmV3IEVycm9yKCJUeXBlQmFja2VkQXJyYXk6IENhbm5vdCBjaGFuZ2UgdGhlIHR5cGUgd2hpbGUgdGhlcmUgaXMgdXNlZCBkYXRhIGluIHRoZSBidWZmZXIuIik7Y29uc3QgZT10aGlzLmFycmF5LmJ1ZmZlcjt0aGlzLmFycmF5PW5ldyB0KGUpLHRoaXMudHlwZT10fXNldFNpemUodCl7aWYodGhpcy5hcnJheSYmdD09PXRoaXMuYXJyYXkubGVuZ3RoKXJldHVybjtjb25zdCBlPXRoaXMudHlwZSxuPXBsKCk/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1uZXcgZShuZXcgbihnMCh0KmUuQllURVNfUEVSX0VMRU1FTlQpKSk7dGhpcy5hcnJheSYmcy5zZXQodGhpcy5hcnJheSwwKSx0aGlzLmFycmF5PXN9ZXhwYW5kKCl7Y29uc3R7YXJyYXk6dCxleHBhbnNpb25GYWN0b3I6ZX09dGhpczt0aGlzLnNldFNpemUodC5sZW5ndGgqZSl9cHVzaCguLi50KXtsZXR7YXJyYXk6ZSxsZW5ndGg6bn09dGhpcztuK3QubGVuZ3RoPmUubGVuZ3RoJiYodGhpcy5leHBhbmQoKSxlPXRoaXMuYXJyYXkpO2ZvcihsZXQgcz0wLHI9dC5sZW5ndGg7czxyO3MrKyllW24rc109dFtzXTt0aGlzLmxlbmd0aCs9dC5sZW5ndGh9Y2xlYXIoKXt0aGlzLmxlbmd0aD0wfX1jbGFzcyB4MHtjb25zdHJ1Y3Rvcigpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVt7fV0sdGhpcy5ncm91cENvdW50PTB9Z2V0VHlwZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0udHlwZX1nZXRJdGVtU2l6ZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0uaXRlbVNpemV9Z2V0Tm9ybWFsaXplZCh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0ubm9ybWFsaXplZH1nZXRDb3VudCh0KXtpZih0aGlzLmdyb3VwQ291bnQ8PXQpcmV0dXJuIDA7Y29uc3QgZT10aGlzLmdldEdyb3VwQXR0ckFycmF5KCJwb3NpdGlvbiIsdCk7cmV0dXJuIGUubGVuZ3RoL2UuaXRlbVNpemV9Z2V0VG90YWxMZW5ndGgodCl7Y29uc3R7Z3JvdXBDb3VudDplLGdyb3VwQXR0cmlidXRlczpufT10aGlzO2xldCBzPTA7Zm9yKGxldCByPTA7cjxlO3IrKyl7Y29uc3Qgbz1uW3JdO3MrPW9bdF0ubGVuZ3RofXJldHVybiBzfWdldEdyb3VwQXR0clNldCh0PTApe2NvbnN0e2dyb3VwQXR0cmlidXRlczplfT10aGlzO2lmKGVbdF0pcmV0dXJuIHRoaXMuZ3JvdXBDb3VudD1NYXRoLm1heCh0aGlzLmdyb3VwQ291bnQsdCsxKSxlW3RdO2NvbnN0IG49ZVswXTtmb3IodGhpcy5ncm91cENvdW50PU1hdGgubWF4KHRoaXMuZ3JvdXBDb3VudCx0KzEpO3Q+PWUubGVuZ3RoOyl7Y29uc3Qgcz17fTtlLnB1c2gocyk7Zm9yKGNvbnN0IHIgaW4gbil7Y29uc3Qgbz1uW3JdLGE9bmV3IEFsKG8udHlwZSk7YS5pdGVtU2l6ZT1vLml0ZW1TaXplLGEubm9ybWFsaXplZD1vLm5vcm1hbGl6ZWQsc1tyXT1hfX1yZXR1cm4gZVt0XX1nZXRHcm91cEF0dHJBcnJheSh0LGU9MCl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOm59PXRoaXM7aWYoIW5bMF1bdF0pdGhyb3cgbmV3IEVycm9yKGBUeXBlZEF0dHJpYnV0ZURhdGE6IEF0dHJpYnV0ZSB3aXRoICIke3R9IiBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRgKTtyZXR1cm4gdGhpcy5nZXRHcm91cEF0dHJTZXQoZSlbdF19aW5pdGlhbGl6ZUFycmF5KHQsZSxuLHMpe2NvbnN0e2dyb3VwQXR0cmlidXRlczpyfT10aGlzLGE9clswXVt0XTtpZihhKXtpZihhLnR5cGUhPT1lKWZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1yW2NdW3RdO2guc2V0VHlwZShlKSxoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXN9fWVsc2UgZm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPW5ldyBBbChlKTtoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXMscltjXVt0XT1ofX1jbGVhcigpe3RoaXMuZ3JvdXBDb3VudD0wO2NvbnN0e2dyb3VwQXR0cmlidXRlczp0fT10aGlzO3QuZm9yRWFjaChlPT57Zm9yKGNvbnN0IG4gaW4gZSllW25dLmNsZWFyKCl9KX1kZWxldGUodCl7dGhpcy5ncm91cEF0dHJpYnV0ZXMuZm9yRWFjaChlPT57ZGVsZXRlIGVbdF19KX1yZXNldCgpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVtdLHRoaXMuZ3JvdXBDb3VudD0wfX1jbGFzcyBfbHtjb25zdHJ1Y3Rvcigpe3RoaXMuaW50ZXJzZWN0aW9uU2V0PXt9LHRoaXMuaWRzPVtdfWFkZCh0LGUpe2NvbnN0e2ludGVyc2VjdGlvblNldDpuLGlkczpzfT10aGlzO25bdF18fChuW3RdPVtdLHMucHVzaCh0KSksblt0XS5wdXNoKGUpfX1jb25zdCB3MD0wLGIwPTEsTTA9MixTbD0zLEEwPTQsdmw9NSx6bD02LHNlPW5ldyBhbyxUbD1uZXcgc3QsVHQ9bmV3IGV0LE5lPW5ldyBULEVsPW5ldyBZdCxQbD1uZXcgWXQsQ2w9bmV3IFl0LHVhPW5ldyBZdCxHcz1uZXcgWXQsWnM9bmV3IFl0LEJsPW5ldyBRdCxmYT1uZXcgVCxkYT0xZS04LF8wPTFlLTE1LGduPS0xLHhuPTEsWHM9LTIsSnM9MixPaT0wLHduPTEscGE9MixTMD0xZS0xNDtsZXQgWXM9bnVsbDtmdW5jdGlvbiBGbChpKXtZcz1pfWZ1bmN0aW9uIElsKGksdCl7aS5nZXRNaWRwb2ludChzZS5vcmlnaW4pLGkuZ2V0Tm9ybWFsKHNlLmRpcmVjdGlvbik7Y29uc3QgZT10LnJheWNhc3RGaXJzdChzZSwyKTtyZXR1cm4hIShlJiZzZS5kaXJlY3Rpb24uZG90KGUuZmFjZS5ub3JtYWwpPjApP2duOnhufWZ1bmN0aW9uIHYwKGksdCl7ZnVuY3Rpb24gZSgpe3JldHVybiBNYXRoLnJhbmRvbSgpLS41fWkuZ2V0Tm9ybWFsKGZhKSxzZS5kaXJlY3Rpb24uY29weShmYSksaS5nZXRNaWRwb2ludChzZS5vcmlnaW4pO2NvbnN0IG49MztsZXQgcz0wLHI9MS8wO2ZvcihsZXQgbz0wO288bjtvKyspe3NlLmRpcmVjdGlvbi54Kz1lKCkqZGEsc2UuZGlyZWN0aW9uLnkrPWUoKSpkYSxzZS5kaXJlY3Rpb24ueis9ZSgpKmRhLHNlLmRpcmVjdGlvbi5tdWx0aXBseVNjYWxhcigtMSk7Y29uc3QgYT10LnJheWNhc3RGaXJzdChzZSwyKTtpZighIShhJiZzZS5kaXJlY3Rpb24uZG90KGEuZmFjZS5ub3JtYWwpPjApJiZzKyssYSE9PW51bGwmJihyPU1hdGgubWluKHIsYS5kaXN0YW5jZSkpLHI8PV8wKXJldHVybiBhLmZhY2Uubm9ybWFsLmRvdChmYSk+MD9KczpYcztpZihzL24+LjV8fChvLXMrMSkvbj4uNSlicmVha31yZXR1cm4gcy9uPi41P2duOnhufWZ1bmN0aW9uIHowKGksdCl7Y29uc3QgZT1uZXcgX2wsbj1uZXcgX2w7cmV0dXJuIFRsLmNvcHkoaS5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkodC5tYXRyaXhXb3JsZCksaS5nZW9tZXRyeS5ib3VuZHNUcmVlLmJ2aGNhc3QodC5nZW9tZXRyeS5ib3VuZHNUcmVlLFRsLHtpbnRlcnNlY3RzVHJpYW5nbGVzKHMscixvLGEpe2lmKCFubihzKSYmIW5uKHIpKXtsZXQgYz1zLmludGVyc2VjdHNUcmlhbmdsZShyLEJsLCEwKTtpZighYyl7Y29uc3QgbD1zLnBsYW5lLGg9ci5wbGFuZSx1PWwubm9ybWFsLGY9aC5ub3JtYWw7dS5kb3QoZik9PT0xJiZNYXRoLmFicyhsLmNvbnN0YW50LWguY29uc3RhbnQpPFMwJiYoYz0hMCl9aWYoYyl7bGV0IGw9aS5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KG8pLGg9dC5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KGEpO2UuYWRkKGwsaCksbi5hZGQoaCxsKSxZcyYmKFlzLmFkZEVkZ2UoQmwpLFlzLmFkZEludGVyc2VjdGluZ1RyaWFuZ2xlcyhvLHMsYSxyKSl9fXJldHVybiExfX0pLHthSW50ZXJzZWN0aW9uczplLGJJbnRlcnNlY3Rpb25zOm59fWZ1bmN0aW9uIFQwKGksdCxlLG4scyxyLG89ITEpe2NvbnN0IGE9ZS5hdHRyaWJ1dGVzLGM9ZS5pbmRleCxsPWkqMyxoPWMuZ2V0WChsKzApLHU9Yy5nZXRYKGwrMSksZj1jLmdldFgobCsyKTtmb3IoY29uc3QgZCBpbiByKXtjb25zdCBwPWFbZF0seT1yW2RdO2lmKCEoZCBpbiBhKSl0aHJvdyBuZXcgRXJyb3IoYENTRyBPcGVyYXRpb25zOiBBdHRyaWJ1dGUgJHtkfSBub3QgYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IG09cC5pdGVtU2l6ZTtkPT09InBvc2l0aW9uIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlNYXRyaXg0KG4pLFR0LmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLHUpLmFwcGx5TWF0cml4NChuKSxUdC5jLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxmKS5hcHBseU1hdHJpeDQobikseWEoVHQuYSxUdC5iLFR0LmMsdCwzLHksbykpOmQ9PT0ibm9ybWFsIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHAsZikuYXBwbHlOb3JtYWxNYXRyaXgocyksbyYmKFR0LmEubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmIubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmMubXVsdGlwbHlTY2FsYXIoLTEpKSx5YShUdC5hLFR0LmIsVHQuYyx0LDMseSxvLCEwKSk6KEVsLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKSxQbC5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSksQ2wuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGYpLHlhKEVsLFBsLENsLHQsbSx5LG8pKX19ZnVuY3Rpb24gRTAoaSx0LGUsbixzLHIsbyxhPSExKXttYShpLG4scyxyLG8sYSksbWEoYT9lOnQsbixzLHIsbyxhKSxtYShhP3Q6ZSxuLHMscixvLGEpfWZ1bmN0aW9uIGtsKGksdCxlPSExKXtzd2l0Y2goaSl7Y2FzZSB3MDppZih0PT09eG58fHQ9PT1KcyYmIWUpcmV0dXJuIHduO2JyZWFrO2Nhc2UgYjA6aWYoZSl7aWYodD09PWduKXJldHVybiBPaX1lbHNlIGlmKHQ9PT14bnx8dD09PVhzKXJldHVybiB3bjticmVhaztjYXNlIE0wOmlmKGUpe2lmKHQ9PT14bnx8dD09PVhzKXJldHVybiB3bn1lbHNlIGlmKHQ9PT1nbilyZXR1cm4gT2k7YnJlYWs7Y2FzZSBBMDppZih0PT09Z24pcmV0dXJuIE9pO2lmKHQ9PT14bilyZXR1cm4gd247YnJlYWs7Y2FzZSBTbDppZih0PT09Z258fHQ9PT1KcyYmIWUpcmV0dXJuIHduO2JyZWFrO2Nhc2Ugdmw6aWYoIWUmJih0PT09eG58fHQ9PT1YcykpcmV0dXJuIHduO2JyZWFrO2Nhc2Ugemw6aWYoIWUmJih0PT09Z258fHQ9PT1KcykpcmV0dXJuIHduO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgQ1NHIG9wZXJhdGlvbiBlbnVtICIke2l9Ii5gKX1yZXR1cm4gcGF9ZnVuY3Rpb24geWEoaSx0LGUsbixzLHIsbz0hMSxhPSExKXtjb25zdCBjPWw9PntyLnB1c2gobC54KSxzPjEmJnIucHVzaChsLnkpLHM+MiYmci5wdXNoKGwueikscz4zJiZyLnB1c2gobC53KX07dWEuc2V0KDAsMCwwLDApLmFkZFNjYWxlZFZlY3RvcihpLG4uYS54KS5hZGRTY2FsZWRWZWN0b3IodCxuLmEueSkuYWRkU2NhbGVkVmVjdG9yKGUsbi5hLnopLEdzLnNldCgwLDAsMCwwKS5hZGRTY2FsZWRWZWN0b3IoaSxuLmIueCkuYWRkU2NhbGVkVmVjdG9yKHQsbi5iLnkpLmFkZFNjYWxlZFZlY3RvcihlLG4uYi56KSxacy5zZXQoMCwwLDAsMCkuYWRkU2NhbGVkVmVjdG9yKGksbi5jLngpLmFkZFNjYWxlZFZlY3Rvcih0LG4uYy55KS5hZGRTY2FsZWRWZWN0b3IoZSxuLmMueiksYSYmKHVhLm5vcm1hbGl6ZSgpLEdzLm5vcm1hbGl6ZSgpLFpzLm5vcm1hbGl6ZSgpKSxjKHVhKSxvPyhjKFpzKSxjKEdzKSk6KGMoR3MpLGMoWnMpKX1mdW5jdGlvbiBtYShpLHQsZSxuLHMscj0hMSl7Zm9yKGNvbnN0IG8gaW4gcyl7Y29uc3QgYT10W29dLGM9c1tvXTtpZighKG8gaW4gdCkpdGhyb3cgbmV3IEVycm9yKGBDU0cgT3BlcmF0aW9uczogQXR0cmlidXRlICR7b30gbm8gYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IGw9YS5pdGVtU2l6ZTtvPT09InBvc2l0aW9uIj8oTmUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGkpLmFwcGx5TWF0cml4NChlKSxjLnB1c2goTmUueCxOZS55LE5lLnopKTpvPT09Im5vcm1hbCI/KE5lLmZyb21CdWZmZXJBdHRyaWJ1dGUoYSxpKS5hcHBseU5vcm1hbE1hdHJpeChuKSxyJiZOZS5tdWx0aXBseVNjYWxhcigtMSksYy5wdXNoKE5lLngsTmUueSxOZS56KSk6KGMucHVzaChhLmdldFgoaSkpLGw+MSYmYy5wdXNoKGEuZ2V0WShpKSksbD4yJiZjLnB1c2goYS5nZXRaKGkpKSxsPjMmJmMucHVzaChhLmdldFcoaSkpKX19Y2xhc3MgUDB7Y29uc3RydWN0b3IodCl7dGhpcy50cmlhbmdsZT1uZXcgZXQoKS5jb3B5KHQpLHRoaXMuaW50ZXJzZWN0cz17fX1hZGRUcmlhbmdsZSh0LGUpe3RoaXMuaW50ZXJzZWN0c1t0XT1uZXcgZXQoKS5jb3B5KGUpfWdldEludGVyc2VjdEFycmF5KCl7Y29uc3QgdD1bXSx7aW50ZXJzZWN0czplfT10aGlzO2Zvcihjb25zdCBuIGluIGUpdC5wdXNoKGVbbl0pO3JldHVybiB0fX1jbGFzcyBObHtjb25zdHJ1Y3Rvcigpe3RoaXMuZGF0YT17fX1hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKXtjb25zdHtkYXRhOnJ9PXRoaXM7clt0XXx8KHJbdF09bmV3IFAwKGUpKSxyW3RdLmFkZFRyaWFuZ2xlKG4scyl9Z2V0VHJpYW5nbGVzQXNBcnJheSh0PW51bGwpe2NvbnN0e2RhdGE6ZX09dGhpcyxuPVtdO2lmKHQhPT1udWxsKXQgaW4gZSYmbi5wdXNoKGVbdF0udHJpYW5nbGUpO2Vsc2UgZm9yKGNvbnN0IHMgaW4gZSluLnB1c2goZVtzXS50cmlhbmdsZSk7cmV0dXJuIG59Z2V0VHJpYW5nbGVJbmRpY2VzKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubWFwKHQ9PnBhcnNlSW50KHQpKX1nZXRJbnRlcnNlY3Rpb25JbmRpY2VzKHQpe2NvbnN0e2RhdGE6ZX09dGhpcztyZXR1cm4gZVt0XT9PYmplY3Qua2V5cyhlW3RdLmludGVyc2VjdHMpLm1hcChuPT5wYXJzZUludChuKSk6W119Z2V0SW50ZXJzZWN0aW9uc0FzQXJyYXkodD1udWxsLGU9bnVsbCl7Y29uc3R7ZGF0YTpufT10aGlzLHM9bmV3IFNldCxyPVtdLG89YT0+e2lmKG5bYV0paWYoZSE9PW51bGwpblthXS5pbnRlcnNlY3RzW2VdJiZyLnB1c2goblthXS5pbnRlcnNlY3RzW2VdKTtlbHNle2NvbnN0IGM9blthXS5pbnRlcnNlY3RzO2Zvcihjb25zdCBsIGluIGMpcy5oYXMobCl8fChzLmFkZChsKSxyLnB1c2goY1tsXSkpfX07aWYodCE9PW51bGwpbyh0KTtlbHNlIGZvcihjb25zdCBhIGluIG4pbyhhKTtyZXR1cm4gcn1yZXNldCgpe3RoaXMuZGF0YT17fX19Y2xhc3MgQzB7Y29uc3RydWN0b3IoKXt0aGlzLmVuYWJsZWQ9ITEsdGhpcy50cmlhbmdsZUludGVyc2VjdHNBPW5ldyBObCx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0I9bmV3IE5sLHRoaXMuaW50ZXJzZWN0aW9uRWRnZXM9W119YWRkSW50ZXJzZWN0aW5nVHJpYW5nbGVzKHQsZSxuLHMpe2NvbnN0e3RyaWFuZ2xlSW50ZXJzZWN0c0E6cix0cmlhbmdsZUludGVyc2VjdHNCOm99PXRoaXM7ci5hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKSxvLmFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKG4scyx0LGUpfWFkZEVkZ2UodCl7dGhpcy5pbnRlcnNlY3Rpb25FZGdlcy5wdXNoKHQuY2xvbmUoKSl9cmVzZXQoKXt0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0EucmVzZXQoKSx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0IucmVzZXQoKSx0aGlzLmludGVyc2VjdGlvbkVkZ2VzPVtdfWluaXQoKXt0aGlzLmVuYWJsZWQmJih0aGlzLnJlc2V0KCksRmwodGhpcykpfWNvbXBsZXRlKCl7dGhpcy5lbmFibGVkJiZGbChudWxsKX19Y29uc3Qgc249bmV3IHN0LGpzPW5ldyBnZSxibj1uZXcgZXQsUXM9bmV3IGV0LHJuPW5ldyBldCxLcz1uZXcgZXQsZGU9W10sTW49W107ZnVuY3Rpb24gQjAoaSl7Zm9yKGNvbnN0IHQgb2YgaSlyZXR1cm4gdH1mdW5jdGlvbiBGMChpLHQsZSxuLHMscj17fSl7Y29uc3R7dXNlR3JvdXBzOm89ITB9PXIse2FJbnRlcnNlY3Rpb25zOmEsYkludGVyc2VjdGlvbnM6Y309ejAoaSx0KSxsPVtdO2xldCBoPW51bGwsdTtyZXR1cm4gdT1vPzA6LTEsUmwoaSx0LGEsZSwhMSxuLHMsdSksTGwoaSx0LGEsZSwhMSxzLHUpLGUuZmluZEluZGV4KGQ9PmQhPT16bCYmZCE9PXZsKSE9PS0xJiYodT1vP2kuZ2VvbWV0cnkuZ3JvdXBzLmxlbmd0aHx8MTotMSxSbCh0LGksYyxlLCEwLG4scyx1KSxMbCh0LGksYyxlLCEwLHMsdSkpLGRlLmxlbmd0aD0wLE1uLmxlbmd0aD0wLHtncm91cHM6bCxtYXRlcmlhbHM6aH19ZnVuY3Rpb24gUmwoaSx0LGUsbixzLHIsbyxhPTApe2NvbnN0IGM9aS5tYXRyaXhXb3JsZC5kZXRlcm1pbmFudCgpPDA7c24uY29weSh0Lm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseShpLm1hdHJpeFdvcmxkKSxqcy5nZXROb3JtYWxNYXRyaXgoaS5tYXRyaXhXb3JsZCkubXVsdGlwbHlTY2FsYXIoYz8tMToxKTtjb25zdCBsPWkuZ2VvbWV0cnkuZ3JvdXBJbmRpY2VzLGg9aS5nZW9tZXRyeS5pbmRleCx1PWkuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixmPXQuZ2VvbWV0cnkuYm91bmRzVHJlZSxkPXQuZ2VvbWV0cnkuaW5kZXgscD10Lmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb24seT1lLmlkcyxtPWUuaW50ZXJzZWN0aW9uU2V0O2ZvcihsZXQgZz0wLGI9eS5sZW5ndGg7ZzxiO2crKyl7Y29uc3Qgdz15W2ddLHg9YT09PS0xPzA6bFt3XSthLE09Myp3LEE9aC5nZXRYKE0rMCksXz1oLmdldFgoTSsxKSxTPWguZ2V0WChNKzIpO2JuLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LEEpLmFwcGx5TWF0cml4NChzbiksYm4uYi5mcm9tQnVmZmVyQXR0cmlidXRlKHUsXykuYXBwbHlNYXRyaXg0KHNuKSxibi5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodSxTKS5hcHBseU1hdHJpeDQoc24pLHIucmVzZXQoKSxyLmluaXRpYWxpemUoYm4pO2NvbnN0IEU9bVt3XTtmb3IobGV0IHY9MCxDPUUubGVuZ3RoO3Y8Qzt2Kyspe2NvbnN0IFA9MypFW3ZdLEY9ZC5nZXRYKFArMCksQj1kLmdldFgoUCsxKSxJPWQuZ2V0WChQKzIpO1FzLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEYpLFFzLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEIpLFFzLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEkpLHIuc3BsaXRCeVRyaWFuZ2xlKFFzKX1jb25zdCB6PXIudHJpYW5nbGVzO2ZvcihsZXQgdj0wLEM9ei5sZW5ndGg7djxDO3YrKyl7Y29uc3QgUD16W3ZdLEY9ci5jb3BsYW5hclRyaWFuZ2xlVXNlZD92MChQLGYpOklsKFAsZik7ZGUubGVuZ3RoPTAsTW4ubGVuZ3RoPTA7Zm9yKGxldCBCPTAsST1uLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPWtsKG5bQl0sRixzKTtrIT09cGEmJihNbi5wdXNoKGspLGRlLnB1c2gob1tCXS5nZXRHcm91cEF0dHJTZXQoeCkpKX1pZihkZS5sZW5ndGghPT0wKXtibi5nZXRCYXJ5Y29vcmQoUC5hLEtzLmEpLGJuLmdldEJhcnljb29yZChQLmIsS3MuYiksYm4uZ2V0QmFyeWNvb3JkKFAuYyxLcy5jKTtmb3IobGV0IEI9MCxJPWRlLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPWRlW0JdLFY9TW5bQl09PT1PaTtUMCh3LEtzLGkuZ2VvbWV0cnksaS5tYXRyaXhXb3JsZCxqcyxrLGMhPT1WKX19fX1yZXR1cm4geS5sZW5ndGh9ZnVuY3Rpb24gTGwoaSx0LGUsbixzLHIsbz0wKXtjb25zdCBhPWkubWF0cml4V29ybGQuZGV0ZXJtaW5hbnQoKTwwO3NuLmNvcHkodC5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkoaS5tYXRyaXhXb3JsZCksanMuZ2V0Tm9ybWFsTWF0cml4KGkubWF0cml4V29ybGQpLm11bHRpcGx5U2NhbGFyKGE/LTE6MSk7Y29uc3QgYz10Lmdlb21ldHJ5LmJvdW5kc1RyZWUsbD1pLmdlb21ldHJ5Lmdyb3VwSW5kaWNlcyxoPWkuZ2VvbWV0cnkuaW5kZXgsdT1pLmdlb21ldHJ5LmF0dHJpYnV0ZXMsZj11LnBvc2l0aW9uLGQ9W10scD1pLmdlb21ldHJ5LmhhbGZFZGdlcyx5PW5ldyBTZXQsbT1uYShpLmdlb21ldHJ5KTtmb3IobGV0IGc9MCxiPW07ZzxiO2crKylnIGluIGUuaW50ZXJzZWN0aW9uU2V0fHx5LmFkZChnKTtmb3IoO3kuc2l6ZT4wOyl7Y29uc3QgZz1CMCh5KTt5LmRlbGV0ZShnKSxkLnB1c2goZyk7Y29uc3QgYj0zKmcsdz1oLmdldFgoYiswKSx4PWguZ2V0WChiKzEpLE09aC5nZXRYKGIrMik7cm4uYS5mcm9tQnVmZmVyQXR0cmlidXRlKGYsdykuYXBwbHlNYXRyaXg0KHNuKSxybi5iLmZyb21CdWZmZXJBdHRyaWJ1dGUoZix4KS5hcHBseU1hdHJpeDQoc24pLHJuLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLE0pLmFwcGx5TWF0cml4NChzbik7Y29uc3QgQT1JbChybixjKTtNbi5sZW5ndGg9MCxkZS5sZW5ndGg9MDtmb3IobGV0IF89MCxTPW4ubGVuZ3RoO188UztfKyspe2NvbnN0IEU9a2wobltfXSxBLHMpO0UhPT1wYSYmKE1uLnB1c2goRSksZGUucHVzaChyW19dKSl9Zm9yKDtkLmxlbmd0aD4wOyl7Y29uc3QgXz1kLnBvcCgpO2ZvcihsZXQgUz0wO1M8MztTKyspe2NvbnN0IEU9cC5nZXRTaWJsaW5nVHJpYW5nbGVJbmRleChfLFMpO0UhPT0tMSYmeS5oYXMoRSkmJihkLnB1c2goRSkseS5kZWxldGUoRSkpfWlmKGRlLmxlbmd0aCE9PTApe2NvbnN0IFM9MypfLEU9aC5nZXRYKFMrMCksej1oLmdldFgoUysxKSx2PWguZ2V0WChTKzIpLEM9bz09PS0xPzA6bFtfXStvO2lmKHJuLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLEUpLHJuLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHopLHJuLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHYpLCFubihybikpZm9yKGxldCBQPTAsRj1kZS5sZW5ndGg7UDxGO1ArKyl7Y29uc3QgQj1NbltQXSxJPWRlW1BdLmdldEdyb3VwQXR0clNldChDKSxrPUI9PT1PaTtFMChFLHosdix1LGkubWF0cml4V29ybGQsanMsSSxrIT09YSl9fX19fWZ1bmN0aW9uIEkwKGkpe2ZvcihsZXQgdD0wO3Q8aS5sZW5ndGgtMTt0Kyspe2NvbnN0IGU9aVt0XSxuPWlbdCsxXTtpZihlLm1hdGVyaWFsSW5kZXg9PT1uLm1hdGVyaWFsSW5kZXgpe2NvbnN0IHM9ZS5zdGFydCxyPW4uc3RhcnQrbi5jb3VudDtuLnN0YXJ0PXMsbi5jb3VudD1yLXMsaS5zcGxpY2UodCwxKSx0LS19fX1mdW5jdGlvbiBrMChpLHQsZSxuKXtlLmNsZWFyKCk7Y29uc3Qgcz1pLmF0dHJpYnV0ZXM7Zm9yKGxldCByPTAsbz1uLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPW5bcl0sYz1zW2FdO2UuaW5pdGlhbGl6ZUFycmF5KGEsYy5hcnJheS5jb25zdHJ1Y3RvcixjLml0ZW1TaXplLGMubm9ybWFsaXplZCl9Zm9yKGNvbnN0IHIgaW4gZS5hdHRyaWJ1dGVzKW4uaW5jbHVkZXMocil8fGUuZGVsZXRlKHIpO2Zvcihjb25zdCByIGluIHQuYXR0cmlidXRlcyluLmluY2x1ZGVzKHIpfHwodC5kZWxldGVBdHRyaWJ1dGUociksdC5kaXNwb3NlKCkpfWZ1bmN0aW9uIE4wKGksdCxlKXtsZXQgbj0hMSxzPS0xO2NvbnN0IHI9aS5hdHRyaWJ1dGVzLG89dC5ncm91cEF0dHJpYnV0ZXNbMF07Zm9yKGNvbnN0IGMgaW4gbyl7Y29uc3QgbD10LmdldFRvdGFsTGVuZ3RoKGMpLGg9dC5nZXRUeXBlKGMpLHU9dC5nZXRJdGVtU2l6ZShjKSxmPXQuZ2V0Tm9ybWFsaXplZChjKTtsZXQgZD1yW2NdOyghZHx8ZC5hcnJheS5sZW5ndGg8bCkmJihkPW5ldyB4dChuZXcgaChsKSx1LGYpLGkuc2V0QXR0cmlidXRlKGMsZCksbj0hMCk7bGV0IHA9MDtmb3IobGV0IHk9MCxtPU1hdGgubWluKGUubGVuZ3RoLHQuZ3JvdXBDb3VudCk7eTxtO3krKyl7Y29uc3QgZz1lW3ldLmluZGV4LHthcnJheTpiLHR5cGU6dyxsZW5ndGg6eH09dC5ncm91cEF0dHJpYnV0ZXNbZ11bY10sTT1uZXcgdyhiLmJ1ZmZlciwwLHgpO2QuYXJyYXkuc2V0KE0scCkscCs9TS5sZW5ndGh9ZC5uZWVkc1VwZGF0ZT0hMCxzPWwvZC5pdGVtU2l6ZX1pZihpLmluZGV4KXtjb25zdCBjPWkuaW5kZXguYXJyYXk7aWYoYy5sZW5ndGg8cylpLmluZGV4PW51bGwsbj0hMDtlbHNlIGZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyljW2xdPWx9bGV0IGE9MDtpLmNsZWFyR3JvdXBzKCk7Zm9yKGxldCBjPTAsbD1NYXRoLm1pbihlLmxlbmd0aCx0Lmdyb3VwQ291bnQpO2M8bDtjKyspe2NvbnN0e2luZGV4OmgsbWF0ZXJpYWxJbmRleDp1fT1lW2NdLGY9dC5nZXRDb3VudChoKTtmIT09MCYmKGkuYWRkR3JvdXAoYSxmLHUpLGErPWYpfWkuc2V0RHJhd1JhbmdlKDAscyksaS5ib3VuZHNUcmVlPW51bGwsbiYmaS5kaXNwb3NlKCl9ZnVuY3Rpb24gT2woaSx0KXtsZXQgZT10O3JldHVybiBBcnJheS5pc0FycmF5KHQpfHwoZT1bXSxpLmZvckVhY2gobj0+e2Vbbi5tYXRlcmlhbEluZGV4XT10fSkpLGV9Y2xhc3MgUjB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlU3BsaXR0ZXI9bmV3IG0wLHRoaXMuYXR0cmlidXRlRGF0YT1bXSx0aGlzLmF0dHJpYnV0ZXM9WyJwb3NpdGlvbiIsInV2Iiwibm9ybWFsIl0sdGhpcy51c2VHcm91cHM9ITAsdGhpcy5jb25zb2xpZGF0ZUdyb3Vwcz0hMCx0aGlzLmRlYnVnPW5ldyBDMH1nZXRHcm91cFJhbmdlcyh0KXtyZXR1cm4hdGhpcy51c2VHcm91cHN8fHQuZ3JvdXBzLmxlbmd0aD09PTA/W3tzdGFydDowLGNvdW50OjEvMCxtYXRlcmlhbEluZGV4OjB9XTp0Lmdyb3Vwcy5tYXAoZT0+RnQoe30sZSkpfWV2YWx1YXRlKHQsZSxuLHM9bmV3IEhzKXtsZXQgcj0hMDtpZihBcnJheS5pc0FycmF5KG4pfHwobj1bbl0pLEFycmF5LmlzQXJyYXkocyl8fChzPVtzXSxyPSExKSxzLmxlbmd0aCE9PW4ubGVuZ3RoKXRocm93IG5ldyBFcnJvcigiRXZhbHVhdG9yOiBvcGVyYXRpb25zIGFuZCB0YXJnZXQgYXJyYXkgcGFzc2VkIGFzIGRpZmZlcmVudCBzaXplcy4iKTt0LnByZXBhcmVHZW9tZXRyeSgpLGUucHJlcGFyZUdlb21ldHJ5KCk7Y29uc3R7dHJpYW5nbGVTcGxpdHRlcjpvLGF0dHJpYnV0ZURhdGE6YSxhdHRyaWJ1dGVzOmMsdXNlR3JvdXBzOmwsY29uc29saWRhdGVHcm91cHM6aCxkZWJ1Zzp1fT10aGlzO2Zvcig7YS5sZW5ndGg8cy5sZW5ndGg7KWEucHVzaChuZXcgeDApO3MuZm9yRWFjaCgoZyxiKT0+e2swKHQuZ2VvbWV0cnksZy5nZW9tZXRyeSxhW2JdLGMpfSksdS5pbml0KCksRjAodCxlLG4sbyxhLHt1c2VHcm91cHM6bH0pLHUuY29tcGxldGUoKTtjb25zdCBmPXRoaXMuZ2V0R3JvdXBSYW5nZXModC5nZW9tZXRyeSksZD1PbChmLHQubWF0ZXJpYWwpLHA9dGhpcy5nZXRHcm91cFJhbmdlcyhlLmdlb21ldHJ5KSx5PU9sKHAsZS5tYXRlcmlhbCk7cC5mb3JFYWNoKGc9PmcubWF0ZXJpYWxJbmRleCs9ZC5sZW5ndGgpO2xldCBtPVsuLi5mLC4uLnBdLm1hcCgoZyxiKT0+R2UoRnQoe30sZykse2luZGV4OmJ9KSk7aWYobCl7Y29uc3QgZz1bLi4uZCwuLi55XTtoJiYobT1tLm1hcCh3PT57Y29uc3QgeD1nW3cubWF0ZXJpYWxJbmRleF07cmV0dXJuIHcubWF0ZXJpYWxJbmRleD1nLmluZGV4T2YoeCksd30pLnNvcnQoKHcseCk9PncubWF0ZXJpYWxJbmRleC14Lm1hdGVyaWFsSW5kZXgpKTtjb25zdCBiPVtdO2ZvcihsZXQgdz0wLHg9Zy5sZW5ndGg7dzx4O3crKyl7bGV0IE09ITE7Zm9yKGxldCBBPTAsXz1tLmxlbmd0aDtBPF87QSsrKXtjb25zdCBTPW1bQV07Uy5tYXRlcmlhbEluZGV4PT09dyYmKE09ITAsUy5tYXRlcmlhbEluZGV4PWIubGVuZ3RoKX1NJiZiLnB1c2goZ1t3XSl9cy5mb3JFYWNoKHc9Pnt3Lm1hdGVyaWFsPWJ9KX1lbHNlIG09W3tzdGFydDowLGNvdW50OjEvMCxpbmRleDowLG1hdGVyaWFsSW5kZXg6MH1dLHMuZm9yRWFjaChnPT57Zy5tYXRlcmlhbD1kWzBdfSk7cmV0dXJuIHMuZm9yRWFjaCgoZyxiKT0+e2NvbnN0IHc9Zy5nZW9tZXRyeTtOMCh3LGFbYl0sbSksaCYmSTAody5ncm91cHMpfSkscj9zOnNbMF19ZXZhbHVhdGVIaWVyYXJjaHkodCxlPW5ldyBIcyl7dC51cGRhdGVNYXRyaXhXb3JsZCghMCk7Y29uc3Qgbj0ocixvKT0+e2NvbnN0IGE9ci5jaGlsZHJlbjtmb3IobGV0IGM9MCxsPWEubGVuZ3RoO2M8bDtjKyspe2NvbnN0IGg9YVtjXTtoLmlzT3BlcmF0aW9uR3JvdXA/bihoLG8pOm8oaCl9fSxzPXI9Pntjb25zdCBvPXIuY2hpbGRyZW47bGV0IGE9ITE7Zm9yKGxldCBsPTAsaD1vLmxlbmd0aDtsPGg7bCsrKXtjb25zdCB1PW9bbF07YT1zKHUpfHxhfWNvbnN0IGM9ci5pc0RpcnR5KCk7aWYoYyYmci5tYXJrVXBkYXRlZCgpLGEmJiFyLmlzT3BlcmF0aW9uR3JvdXApe2xldCBsO3JldHVybiBuKHIsaD0+e2w/bD10aGlzLmV2YWx1YXRlKGwsaCxoLm9wZXJhdGlvbik6bD10aGlzLmV2YWx1YXRlKHIsaCxoLm9wZXJhdGlvbil9KSxyLl9jYWNoZWRHZW9tZXRyeT1sLmdlb21ldHJ5LHIuX2NhY2hlZE1hdGVyaWFscz1sLm1hdGVyaWFsLCEwfWVsc2UgcmV0dXJuIGF8fGN9O3JldHVybiBzKHQpLGUuZ2VvbWV0cnk9dC5fY2FjaGVkR2VvbWV0cnksZS5tYXRlcmlhbD10Ll9jYWNoZWRNYXRlcmlhbHMsZX1yZXNldCgpe3RoaXMudHJpYW5nbGVTcGxpdHRlci5yZXNldCgpfX1mdW5jdGlvbiBEbChpKXtsZXQgdCxlLG4scz0tMSxyPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZih0PT09dm9pZCAwJiYodD1oLmFycmF5LmNvbnN0cnVjdG9yKSx0IT09aC5hcnJheS5jb25zdHJ1Y3RvcilyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmFycmF5IG11c3QgYmUgb2YgY29uc2lzdGVudCBhcnJheSB0eXBlcyBhY3Jvc3MgbWF0Y2hpbmcgYXR0cmlidXRlcy4iKSxudWxsO2lmKGU9PT12b2lkIDAmJihlPWguaXRlbVNpemUpLGUhPT1oLml0ZW1TaXplKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuaXRlbVNpemUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7aWYobj09PXZvaWQgMCYmKG49aC5ub3JtYWxpemVkKSxuIT09aC5ub3JtYWxpemVkKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUubm9ybWFsaXplZCBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihzPT09LTEmJihzPWguZ3B1VHlwZSkscyE9PWguZ3B1VHlwZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmdwdVR5cGUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7cis9aC5jb3VudCplfWNvbnN0IG89bmV3IHQociksYT1uZXcgeHQobyxlLG4pO2xldCBjPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZihoLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpe2NvbnN0IHU9Yy9lO2ZvcihsZXQgZj0wLGQ9aC5jb3VudDtmPGQ7ZisrKWZvcihsZXQgcD0wO3A8ZTtwKyspe2NvbnN0IHk9aC5nZXRDb21wb25lbnQoZixwKTthLnNldENvbXBvbmVudChmK3UscCx5KX19ZWxzZSBvLnNldChoLmFycmF5LGMpO2MrPWguY291bnQqZX1yZXR1cm4gcyE9PXZvaWQgMCYmKGEuZ3B1VHlwZT1zKSxhfWZ1bmN0aW9uIEwwKGkpe2lmKGkuZ3JvdXBzLmxlbmd0aD09PTApcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlscy5tZXJnZUdyb3VwcygpOiBObyBncm91cHMgYXJlIGRlZmluZWQuIE5vdGhpbmcgdG8gbWVyZ2UuIiksaTtsZXQgdD1pLmdyb3VwcztpZih0PXQuc29ydCgobyxhKT0+by5tYXRlcmlhbEluZGV4IT09YS5tYXRlcmlhbEluZGV4P28ubWF0ZXJpYWxJbmRleC1hLm1hdGVyaWFsSW5kZXg6by5zdGFydC1hLnN0YXJ0KSxpLmdldEluZGV4KCk9PT1udWxsKXtjb25zdCBvPWkuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLGE9W107Zm9yKGxldCBjPTA7YzxvLmNvdW50O2MrPTMpYS5wdXNoKGMsYysxLGMrMik7aS5zZXRJbmRleChhKX1jb25zdCBlPWkuZ2V0SW5kZXgoKSxuPVtdO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb10sYz1hLnN0YXJ0LGw9YythLmNvdW50O2ZvcihsZXQgaD1jO2g8bDtoKyspbi5wdXNoKGUuZ2V0WChoKSl9aS5kaXNwb3NlKCksaS5zZXRJbmRleChuKTtsZXQgcz0wO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb107YS5zdGFydD1zLHMrPWEuY291bnR9bGV0IHI9dFswXTtpLmdyb3Vwcz1bcl07Zm9yKGxldCBvPTE7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXTtyLm1hdGVyaWFsSW5kZXg9PT1hLm1hdGVyaWFsSW5kZXg/ci5jb3VudCs9YS5jb3VudDoocj1hLGkuZ3JvdXBzLnB1c2gocikpfXJldHVybiBpfWZ1bmN0aW9uICRsKGksdD0wKXtjb25zdCBlPWlbMF0uaW5kZXghPT1udWxsLG49bmV3IFNldChPYmplY3Qua2V5cyhpWzBdLmF0dHJpYnV0ZXMpKSxzPW5ldyBTZXQoT2JqZWN0LmtleXMoaVswXS5tb3JwaEF0dHJpYnV0ZXMpKSxyPXt9LG89e30sYT1pWzBdLm1vcnBoVGFyZ2V0c1JlbGF0aXZlLGM9bmV3IHVlO2xldCBsPTA7Zm9yKGxldCBoPTA7aDxpLmxlbmd0aDsrK2gpe2NvbnN0IHU9aVtoXTtsZXQgZj0wO2lmKGUhPT0odS5pbmRleCE9PW51bGwpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIEFsbCBnZW9tZXRyaWVzIG11c3QgaGF2ZSBjb21wYXRpYmxlIGF0dHJpYnV0ZXM7IG1ha2Ugc3VyZSBpbmRleCBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1LmF0dHJpYnV0ZXMpe2lmKCFuLmhhcyhkKSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsnLiBBbGwgZ2VvbWV0cmllcyBtdXN0IGhhdmUgY29tcGF0aWJsZSBhdHRyaWJ1dGVzOyBtYWtlIHN1cmUgIicrZCsnIiBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uJyksbnVsbDtyW2RdPT09dm9pZCAwJiYocltkXT1bXSkscltkXS5wdXNoKHUuYXR0cmlidXRlc1tkXSksZisrfWlmKGYhPT1uLnNpemUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gTWFrZSBzdXJlIGFsbCBnZW9tZXRyaWVzIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihhIT09dS5tb3JwaFRhcmdldHNSZWxhdGl2ZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiAubW9ycGhUYXJnZXRzUmVsYXRpdmUgbXVzdCBiZSBjb25zaXN0ZW50IHRocm91Z2hvdXQgYWxsIGdlb21ldHJpZXMuIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1Lm1vcnBoQXR0cmlidXRlcyl7aWYoIXMuaGFzKGQpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuICAubW9ycGhBdHRyaWJ1dGVzIG11c3QgYmUgY29uc2lzdGVudCB0aHJvdWdob3V0IGFsbCBnZW9tZXRyaWVzLiIpLG51bGw7b1tkXT09PXZvaWQgMCYmKG9bZF09W10pLG9bZF0ucHVzaCh1Lm1vcnBoQXR0cmlidXRlc1tkXSl9aWYodCl7bGV0IGQ7aWYoZSlkPXUuaW5kZXguY291bnQ7ZWxzZSBpZih1LmF0dHJpYnV0ZXMucG9zaXRpb24hPT12b2lkIDApZD11LmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQ7ZWxzZSByZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiBUaGUgZ2VvbWV0cnkgbXVzdCBoYXZlIGVpdGhlciBhbiBpbmRleCBvciBhIHBvc2l0aW9uIGF0dHJpYnV0ZSIpLG51bGw7aWYodD09PTEpYy5hZGRHcm91cChsLGQsaCk7ZWxzZSBpZih0PT09MiYmdS5ncm91cHMubGVuZ3RoPjApZm9yKGxldCBwIG9mIHUuZ3JvdXBzKXtsZXQgeT1wLm1hdGVyaWFsSW5kZXg7Yy5hZGRHcm91cChsK3Auc3RhcnQsTWF0aC5taW4ocC5jb3VudCxkKSx5KX1sKz1kfX1pZihlKXtsZXQgaD0wO2NvbnN0IHU9W107Zm9yKGxldCBmPTA7ZjxpLmxlbmd0aDsrK2Ype2NvbnN0IGQ9aVtmXS5pbmRleDtmb3IobGV0IHA9MDtwPGQuY291bnQ7KytwKXUucHVzaChkLmdldFgocCkraCk7aCs9aVtmXS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWMuc2V0SW5kZXgodSl9Zm9yKGNvbnN0IGggaW4gcil7Y29uc3QgdT1EbChyW2hdKTtpZighdSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIGF0dHJpYnV0ZS4iKSxudWxsO2Muc2V0QXR0cmlidXRlKGgsdSl9Zm9yKGNvbnN0IGggaW4gbyl7Y29uc3QgdT1vW2hdWzBdLmxlbmd0aDtpZih1PT09MClicmVhaztjLm1vcnBoQXR0cmlidXRlcz1jLm1vcnBoQXR0cmlidXRlc3x8e30sYy5tb3JwaEF0dHJpYnV0ZXNbaF09W107Zm9yKGxldCBmPTA7Zjx1OysrZil7Y29uc3QgZD1bXTtmb3IobGV0IHk9MDt5PG9baF0ubGVuZ3RoOysreSlkLnB1c2gob1toXVt5XVtmXSk7Y29uc3QgcD1EbChkKTtpZighcClyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIG1vcnBoQXR0cmlidXRlLiIpLG51bGw7Yy5tb3JwaEF0dHJpYnV0ZXNbaF0ucHVzaChwKX19cmV0dXJuIHQ9PT0yP0wwKGMpOmN9Y2xhc3MgTzAgZXh0ZW5kcyBXbntjb25zdHJ1Y3Rvcih0LGUpe3N1cGVyKHQsZSk7Y29uc3Qgbj1uZXcgSHMobmV3IFduKHQsR2UoRnQoe30sZSkse2hhc1RvcDohMCxoYXNTaWRlOiEwLGhhc0JvdHRvbTohMX0pKSk7bi51cGRhdGVNYXRyaXhXb3JsZCgpO2NvbnN0IHM9bmV3IGd0KCkuc2V0RnJvbU9iamVjdChuKSxyPW5ldyBUO3MuZ2V0U2l6ZShyKTtjb25zdCBvPW5ldyBUKHMubWluLngrci54LzIscy5taW4ueStyLnkvMiwwKTtsZXQgYT1lLnRvcFNlZ21lbnRzLGM9ZS5ib3gzO2lmKGMpe2M9Yy51bmlvbihzKTtjb25zdCBnPW5ldyBUO2MuZ2V0U2l6ZShnKTtjb25zdCBiPU1hdGgubWF4KHIueC9nLngsci55L2cueSk7YT1NYXRoLmNlaWwoZS50b3BTZWdtZW50cypiKX1pZihhPDQpcmV0dXJuIHRoaXM7Y29uc3QgbD1uZXcgRm8oci54LHIueSxhLGEpLGg9bmV3IEhzKGwpO2gucG9zaXRpb24uc2V0KG8ueCxvLnksby56KSxoLnVwZGF0ZU1hdHJpeFdvcmxkKCk7Y29uc3QgZj1uZXcgUjAoKS5ldmFsdWF0ZShoLG4sU2wpLGQ9Zi5nZW9tZXRyeS5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIikscD1uZXcgQ2UoZC5jb3VudCoyLDIpO2ZvcihsZXQgZz0wO2c8ZC5jb3VudDtnKyspe2NvbnN0IGI9ZC5nZXRaKGcpO2Quc2V0WihnLGUuZGVwdGgrYil9aWYoYyl7Y29uc3QgZz1jLm1pbixiPWMubWF4LHc9bmV3IFQoKS5zdWJWZWN0b3JzKGIsZyk7Zm9yKGxldCB4PTA7eDxkLmNvdW50O3grKyl7Y29uc3QgTT1kLmdldFgoeCksQT1kLmdldFkoeCksXz0oTS1nLngpL3cueCxTPShBLWcueSkvdy55O3Auc2V0WFkoeCxfLFMpfWYuZ2VvbWV0cnkuc2V0QXR0cmlidXRlKCJ1diIscCl9ZC5uZWVkc1VwZGF0ZT0hMDtjb25zdCB5PW5ldyBXbih0LEdlKEZ0KHt9LGUpLHtoYXNUb3A6ITF9KSksbT0kbChbZi5nZW9tZXRyeSx5XSwyKTt0aGlzLmNvcHkobS50b05vbkluZGV4ZWQoKSl9fXZhciBEMD1pPT57Y29uc3R7c3BsaXQ6dCxkZXB0aDplLHBvaW50czpuLGJveDM6cyxoYXNUb3A6cixoYXNCb3R0b206byxoYXNTaWRlOmEsc2lkZVJlcGVhdDpjLHRvcFNlZ21lbnRzOmx9PWksaD1sP08wOlduLHU9bmV3IGgobmV3IERjKG4pLHtkZXB0aDplLGJldmVsRW5hYmxlZDohMSxib3gzOnMsVVZHZW5lcmF0b3I6JGYoe3NwbGl0OnQsYm94MzpzLHNpZGVSZXBlYXQ6Y30pLGhhc1RvcDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSx0b3BTZWdtZW50czpsfSk7cmV0dXJuIFVmKCksdX07ZnVuY3Rpb24gJDAoaSx0LGU9MCl7Y29uc3Qgbj0oOTAtdCkqTWF0aC5QSS8xODAscz0oOTAtaSkqTWF0aC5QSS8xODA7cmV0dXJuW2UqTWF0aC5zaW4obikqTWF0aC5jb3MocyksZSpNYXRoLmNvcyhuKSxlKk1hdGguc2luKG4pKk1hdGguc2luKHMpXX1mdW5jdGlvbiB0cihpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjppPHQ/LTE6aT50PzE6aT49dD8wOk5hTn1mdW5jdGlvbiBVMChpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjp0PGk/LTE6dD5pPzE6dD49aT8wOk5hTn1mdW5jdGlvbiBVbChpKXtsZXQgdCxlLG47aS5sZW5ndGghPT0yPyh0PXRyLGU9KGEsYyk9PnRyKGkoYSksYyksbj0oYSxjKT0+aShhKS1jKToodD1pPT09dHJ8fGk9PT1VMD9pOlYwLGU9aSxuPWkpO2Z1bmN0aW9uIHMoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTwwP2w9dSsxOmg9dX13aGlsZShsPGgpfXJldHVybiBsfWZ1bmN0aW9uIHIoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTw9MD9sPXUrMTpoPXV9d2hpbGUobDxoKX1yZXR1cm4gbH1mdW5jdGlvbiBvKGEsYyxsPTAsaD1hLmxlbmd0aCl7Y29uc3QgdT1zKGEsYyxsLGgtMSk7cmV0dXJuIHU+bCYmbihhW3UtMV0sYyk+LW4oYVt1XSxjKT91LTE6dX1yZXR1cm57bGVmdDpzLGNlbnRlcjpvLHJpZ2h0OnJ9fWZ1bmN0aW9uIFYwKCl7cmV0dXJuIDB9ZnVuY3Rpb24gcTAoaSl7cmV0dXJuIGk9PT1udWxsP05hTjoraX1jb25zdCBIMD1VbCh0cikucmlnaHQ7VWwocTApLmNlbnRlcjtmdW5jdGlvbiBlcihpLHQpe2xldCBlLG47aWYodD09PXZvaWQgMClmb3IoY29uc3QgcyBvZiBpKXMhPW51bGwmJihlPT09dm9pZCAwP3M+PXMmJihlPW49cyk6KGU+cyYmKGU9cyksbjxzJiYobj1zKSkpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihlPT09dm9pZCAwP3I+PXImJihlPW49cik6KGU+ciYmKGU9ciksbjxyJiYobj1yKSkpfXJldHVybltlLG5dfWNsYXNzIFJle2NvbnN0cnVjdG9yKCl7dGhpcy5fcGFydGlhbHM9bmV3IEZsb2F0NjRBcnJheSgzMiksdGhpcy5fbj0wfWFkZCh0KXtjb25zdCBlPXRoaXMuX3BhcnRpYWxzO2xldCBuPTA7Zm9yKGxldCBzPTA7czx0aGlzLl9uJiZzPDMyO3MrKyl7Y29uc3Qgcj1lW3NdLG89dCtyLGE9TWF0aC5hYnModCk8TWF0aC5hYnMocik/dC0oby1yKTpyLShvLXQpO2EmJihlW24rK109YSksdD1vfXJldHVybiBlW25dPXQsdGhpcy5fbj1uKzEsdGhpc312YWx1ZU9mKCl7Y29uc3QgdD10aGlzLl9wYXJ0aWFscztsZXQgZT10aGlzLl9uLG4scyxyLG89MDtpZihlPjApe2ZvcihvPXRbLS1lXTtlPjAmJihuPW8scz10Wy0tZV0sbz1uK3Mscj1zLShvLW4pLCFyKTspO2U+MCYmKHI8MCYmdFtlLTFdPDB8fHI+MCYmdFtlLTFdPjApJiYocz1yKjIsbj1vK3Mscz09bi1vJiYobz1uKSl9cmV0dXJuIG99fWNvbnN0IFcwPU1hdGguc3FydCg1MCksRzA9TWF0aC5zcXJ0KDEwKSxaMD1NYXRoLnNxcnQoMik7ZnVuY3Rpb24gbnIoaSx0LGUpe2NvbnN0IG49KHQtaSkvTWF0aC5tYXgoMCxlKSxzPU1hdGguZmxvb3IoTWF0aC5sb2cxMChuKSkscj1uL01hdGgucG93KDEwLHMpLG89cj49VzA/MTA6cj49RzA/NTpyPj1aMD8yOjE7bGV0IGEsYyxsO3JldHVybiBzPDA/KGw9TWF0aC5wb3coMTAsLXMpL28sYT1NYXRoLnJvdW5kKGkqbCksYz1NYXRoLnJvdW5kKHQqbCksYS9sPGkmJisrYSxjL2w+dCYmLS1jLGw9LWwpOihsPU1hdGgucG93KDEwLHMpKm8sYT1NYXRoLnJvdW5kKGkvbCksYz1NYXRoLnJvdW5kKHQvbCksYSpsPGkmJisrYSxjKmw+dCYmLS1jKSxjPGEmJi41PD1lJiZlPDI/bnIoaSx0LGUqMik6W2EsYyxsXX1mdW5jdGlvbiBYMChpLHQsZSl7aWYodD0rdCxpPStpLGU9K2UsIShlPjApKXJldHVybltdO2lmKGk9PT10KXJldHVybltpXTtjb25zdCBuPXQ8aSxbcyxyLG9dPW4/bnIodCxpLGUpOm5yKGksdCxlKTtpZighKHI+PXMpKXJldHVybltdO2NvbnN0IGE9ci1zKzEsYz1uZXcgQXJyYXkoYSk7aWYobilpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpKm87ZWxzZSBpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpKm87cmV0dXJuIGN9ZnVuY3Rpb24gZ2EoaSx0LGUpe3JldHVybiB0PSt0LGk9K2ksZT0rZSxucihpLHQsZSlbMl19ZnVuY3Rpb24gSjAoaSx0LGUpe3Q9K3QsaT0raSxlPStlO2NvbnN0IG49dDxpLHM9bj9nYSh0LGksZSk6Z2EoaSx0LGUpO3JldHVybihuPy0xOjEpKihzPDA/MS8tczpzKX1mdW5jdGlvbiBZMChpLHQpe2xldCBlPTAsbj0wO2lmKHQ9PT12b2lkIDApZm9yKGxldCBzIG9mIGkpcyE9bnVsbCYmKHM9K3MpPj1zJiYoKytlLG4rPXMpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihyPStyKT49ciYmKCsrZSxuKz1yKX1pZihlKXJldHVybiBuL2V9ZnVuY3Rpb24qajAoaSl7Zm9yKGNvbnN0IHQgb2YgaSl5aWVsZCokdSh0KX1mdW5jdGlvbiBEaShpKXtyZXR1cm4gQXJyYXkuZnJvbShqMChpKSl9dmFyIEs9MWUtNixpcj0xZS0xMixYPU1hdGguUEksTnQ9WC8yLHNyPVgvNCxSdD1YKjIsaHQ9MTgwL1gsSD1YLzE4MCx0dD1NYXRoLmFicyx4YT1NYXRoLmF0YW4scmU9TWF0aC5hdGFuMixXPU1hdGguY29zLFEwPU1hdGguZXhwLHdhPU1hdGguaHlwb3QsSzA9TWF0aC5sb2cscT1NYXRoLnNpbix0cD1NYXRoLnNpZ258fGZ1bmN0aW9uKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH0sTGU9TWF0aC5zcXJ0LGVwPU1hdGgudGFuO2Z1bmN0aW9uIG5wKGkpe3JldHVybiBpPjE/MDppPC0xP1g6TWF0aC5hY29zKGkpfWZ1bmN0aW9uIE9lKGkpe3JldHVybiBpPjE/TnQ6aTwtMT8tTnQ6TWF0aC5hc2luKGkpfWZ1bmN0aW9uIFZsKGkpe3JldHVybihpPXEoaS8yKSkqaX1mdW5jdGlvbiBTdCgpe31mdW5jdGlvbiBycihpLHQpe2kmJkhsLmhhc093blByb3BlcnR5KGkudHlwZSkmJkhsW2kudHlwZV0oaSx0KX12YXIgcWw9e0ZlYXR1cmU6ZnVuY3Rpb24oaSx0KXtycihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspcnIoZVtuXS5nZW9tZXRyeSx0KX19LEhsPXtTcGhlcmU6ZnVuY3Rpb24oaSx0KXt0LnNwaGVyZSgpfSxQb2ludDpmdW5jdGlvbihpLHQpe2k9aS5jb29yZGluYXRlcyx0LnBvaW50KGlbMF0saVsxXSxpWzJdKX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaT1lW25dLHQucG9pbnQoaVswXSxpWzFdLGlbMl0pfSxMaW5lU3RyaW5nOmZ1bmN0aW9uKGksdCl7YmEoaS5jb29yZGluYXRlcyx0LDApfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWJhKGVbbl0sdCwwKX0sUG9seWdvbjpmdW5jdGlvbihpLHQpe1dsKGkuY29vcmRpbmF0ZXMsdCl9LE11bHRpUG9seWdvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspV2woZVtuXSx0KX0sR2VvbWV0cnlDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZ2VvbWV0cmllcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KXJyKGVbbl0sdCl9fTtmdW5jdGlvbiBiYShpLHQsZSl7dmFyIG49LTEscz1pLmxlbmd0aC1lLHI7Zm9yKHQubGluZVN0YXJ0KCk7KytuPHM7KXI9aVtuXSx0LnBvaW50KHJbMF0sclsxXSxyWzJdKTt0LmxpbmVFbmQoKX1mdW5jdGlvbiBXbChpLHQpe3ZhciBlPS0xLG49aS5sZW5ndGg7Zm9yKHQucG9seWdvblN0YXJ0KCk7KytlPG47KWJhKGlbZV0sdCwxKTt0LnBvbHlnb25FbmQoKX1mdW5jdGlvbiBvcihpLHQpe2kmJnFsLmhhc093blByb3BlcnR5KGkudHlwZSk/cWxbaS50eXBlXShpLHQpOnJyKGksdCl9dmFyIGFyPW5ldyBSZSxHbD1uZXcgUmUsWmwsWGwsTWEsQWEsX2EsRGU9e3BvaW50OlN0LGxpbmVTdGFydDpTdCxsaW5lRW5kOlN0LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2FyPW5ldyBSZSxEZS5saW5lU3RhcnQ9aXAsRGUubGluZUVuZD1zcH0scG9seWdvbkVuZDpmdW5jdGlvbigpe3ZhciBpPSthcjtHbC5hZGQoaTwwP1J0K2k6aSksdGhpcy5saW5lU3RhcnQ9dGhpcy5saW5lRW5kPXRoaXMucG9pbnQ9U3R9LHNwaGVyZTpmdW5jdGlvbigpe0dsLmFkZChSdCl9fTtmdW5jdGlvbiBpcCgpe0RlLnBvaW50PXJwfWZ1bmN0aW9uIHNwKCl7SmwoWmwsWGwpfWZ1bmN0aW9uIHJwKGksdCl7RGUucG9pbnQ9SmwsWmw9aSxYbD10LGkqPUgsdCo9SCxNYT1pLEFhPVcodD10LzIrc3IpLF9hPXEodCl9ZnVuY3Rpb24gSmwoaSx0KXtpKj1ILHQqPUgsdD10LzIrc3I7dmFyIGU9aS1NYSxuPWU+PTA/MTotMSxzPW4qZSxyPVcodCksbz1xKHQpLGE9X2EqbyxjPUFhKnIrYSpXKHMpLGw9YSpuKnEocyk7YXIuYWRkKHJlKGwsYykpLE1hPWksQWE9cixfYT1vfWZ1bmN0aW9uIGNyKGkpe3JldHVybltyZShpWzFdLGlbMF0pLE9lKGlbMl0pXX1mdW5jdGlvbiBBbihpKXt2YXIgdD1pWzBdLGU9aVsxXSxuPVcoZSk7cmV0dXJuW24qVyh0KSxuKnEodCkscShlKV19ZnVuY3Rpb24gbHIoaSx0KXtyZXR1cm4gaVswXSp0WzBdK2lbMV0qdFsxXStpWzJdKnRbMl19ZnVuY3Rpb24gZWkoaSx0KXtyZXR1cm5baVsxXSp0WzJdLWlbMl0qdFsxXSxpWzJdKnRbMF0taVswXSp0WzJdLGlbMF0qdFsxXS1pWzFdKnRbMF1dfWZ1bmN0aW9uIFNhKGksdCl7aVswXSs9dFswXSxpWzFdKz10WzFdLGlbMl0rPXRbMl19ZnVuY3Rpb24gaHIoaSx0KXtyZXR1cm5baVswXSp0LGlbMV0qdCxpWzJdKnRdfWZ1bmN0aW9uIHVyKGkpe3ZhciB0PUxlKGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtpWzBdLz10LGlbMV0vPXQsaVsyXS89dH12YXIgb3QsTHQsdXQscXQsX24sWWwsamwsbmksJGksb24sJGUsVWU9e3BvaW50OnZhLGxpbmVTdGFydDpLbCxsaW5lRW5kOnRoLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe1VlLnBvaW50PWVoLFVlLmxpbmVTdGFydD1vcCxVZS5saW5lRW5kPWFwLCRpPW5ldyBSZSxEZS5wb2x5Z29uU3RhcnQoKX0scG9seWdvbkVuZDpmdW5jdGlvbigpe0RlLnBvbHlnb25FbmQoKSxVZS5wb2ludD12YSxVZS5saW5lU3RhcnQ9S2wsVWUubGluZUVuZD10aCxhcjwwPyhvdD0tKHV0PTE4MCksTHQ9LShxdD05MCkpOiRpPks/cXQ9OTA6JGk8LUsmJihMdD0tOTApLCRlWzBdPW90LCRlWzFdPXV0fSxzcGhlcmU6ZnVuY3Rpb24oKXtvdD0tKHV0PTE4MCksTHQ9LShxdD05MCl9fTtmdW5jdGlvbiB2YShpLHQpe29uLnB1c2goJGU9W290PWksdXQ9aV0pLHQ8THQmJihMdD10KSx0PnF0JiYocXQ9dCl9ZnVuY3Rpb24gUWwoaSx0KXt2YXIgZT1BbihbaSpILHQqSF0pO2lmKG5pKXt2YXIgbj1laShuaSxlKSxzPVtuWzFdLC1uWzBdLDBdLHI9ZWkocyxuKTt1cihyKSxyPWNyKHIpO3ZhciBvPWktX24sYT1vPjA/MTotMSxjPXJbMF0qaHQqYSxsLGg9dHQobyk+MTgwO2heKGEqX248YyYmYzxhKmkpPyhsPXJbMV0qaHQsbD5xdCYmKHF0PWwpKTooYz0oYyszNjApJTM2MC0xODAsaF4oYSpfbjxjJiZjPGEqaSk/KGw9LXJbMV0qaHQsbDxMdCYmKEx0PWwpKToodDxMdCYmKEx0PXQpLHQ+cXQmJihxdD10KSkpLGg/aTxfbj9IdChvdCxpKT5IdChvdCx1dCkmJih1dD1pKTpIdChpLHV0KT5IdChvdCx1dCkmJihvdD1pKTp1dD49b3Q/KGk8b3QmJihvdD1pKSxpPnV0JiYodXQ9aSkpOmk+X24/SHQob3QsaSk+SHQob3QsdXQpJiYodXQ9aSk6SHQoaSx1dCk+SHQob3QsdXQpJiYob3Q9aSl9ZWxzZSBvbi5wdXNoKCRlPVtvdD1pLHV0PWldKTt0PEx0JiYoTHQ9dCksdD5xdCYmKHF0PXQpLG5pPWUsX249aX1mdW5jdGlvbiBLbCgpe1VlLnBvaW50PVFsfWZ1bmN0aW9uIHRoKCl7JGVbMF09b3QsJGVbMV09dXQsVWUucG9pbnQ9dmEsbmk9bnVsbH1mdW5jdGlvbiBlaChpLHQpe2lmKG5pKXt2YXIgZT1pLV9uOyRpLmFkZCh0dChlKT4xODA/ZSsoZT4wPzM2MDotMzYwKTplKX1lbHNlIFlsPWksamw9dDtEZS5wb2ludChpLHQpLFFsKGksdCl9ZnVuY3Rpb24gb3AoKXtEZS5saW5lU3RhcnQoKX1mdW5jdGlvbiBhcCgpe2VoKFlsLGpsKSxEZS5saW5lRW5kKCksdHQoJGkpPksmJihvdD0tKHV0PTE4MCkpLCRlWzBdPW90LCRlWzFdPXV0LG5pPW51bGx9ZnVuY3Rpb24gSHQoaSx0KXtyZXR1cm4odC09aSk8MD90KzM2MDp0fWZ1bmN0aW9uIGNwKGksdCl7cmV0dXJuIGlbMF0tdFswXX1mdW5jdGlvbiBuaChpLHQpe3JldHVybiBpWzBdPD1pWzFdP2lbMF08PXQmJnQ8PWlbMV06dDxpWzBdfHxpWzFdPHR9ZnVuY3Rpb24gaWgoaSl7dmFyIHQsZSxuLHMscixvLGE7aWYocXQ9dXQ9LShvdD1MdD0xLzApLG9uPVtdLG9yKGksVWUpLGU9b24ubGVuZ3RoKXtmb3Iob24uc29ydChjcCksdD0xLG49b25bMF0scj1bbl07dDxlOysrdClzPW9uW3RdLG5oKG4sc1swXSl8fG5oKG4sc1sxXSk/KEh0KG5bMF0sc1sxXSk+SHQoblswXSxuWzFdKSYmKG5bMV09c1sxXSksSHQoc1swXSxuWzFdKT5IdChuWzBdLG5bMV0pJiYoblswXT1zWzBdKSk6ci5wdXNoKG49cyk7Zm9yKG89LTEvMCxlPXIubGVuZ3RoLTEsdD0wLG49cltlXTt0PD1lO249cywrK3Qpcz1yW3RdLChhPUh0KG5bMV0sc1swXSkpPm8mJihvPWEsb3Q9c1swXSx1dD1uWzFdKX1yZXR1cm4gb249JGU9bnVsbCxvdD09PTEvMHx8THQ9PT0xLzA/W1tOYU4sTmFOXSxbTmFOLE5hTl1dOltbb3QsTHRdLFt1dCxxdF1dfXZhciBVaSxmcixkcixwcix5cixtcixncix4cix6YSxUYSxFYSxzaCxyaCxFdCxQdCxDdCxwZT17c3BoZXJlOlN0LHBvaW50OlBhLGxpbmVTdGFydDpvaCxsaW5lRW5kOmFoLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe3BlLmxpbmVTdGFydD11cCxwZS5saW5lRW5kPWZwfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7cGUubGluZVN0YXJ0PW9oLHBlLmxpbmVFbmQ9YWh9fTtmdW5jdGlvbiBQYShpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO1ZpKGUqVyhpKSxlKnEoaSkscSh0KSl9ZnVuY3Rpb24gVmkoaSx0LGUpeysrVWksZHIrPShpLWRyKS9VaSxwcis9KHQtcHIpL1VpLHlyKz0oZS15cikvVWl9ZnVuY3Rpb24gb2goKXtwZS5wb2ludD1scH1mdW5jdGlvbiBscChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO0V0PWUqVyhpKSxQdD1lKnEoaSksQ3Q9cSh0KSxwZS5wb2ludD1ocCxWaShFdCxQdCxDdCl9ZnVuY3Rpb24gaHAoaSx0KXtpKj1ILHQqPUg7dmFyIGU9Vyh0KSxuPWUqVyhpKSxzPWUqcShpKSxyPXEodCksbz1yZShMZSgobz1QdCpyLUN0KnMpKm8rKG89Q3Qqbi1FdCpyKSpvKyhvPUV0KnMtUHQqbikqbyksRXQqbitQdCpzK0N0KnIpO2ZyKz1vLG1yKz1vKihFdCsoRXQ9bikpLGdyKz1vKihQdCsoUHQ9cykpLHhyKz1vKihDdCsoQ3Q9cikpLFZpKEV0LFB0LEN0KX1mdW5jdGlvbiBhaCgpe3BlLnBvaW50PVBhfWZ1bmN0aW9uIHVwKCl7cGUucG9pbnQ9ZHB9ZnVuY3Rpb24gZnAoKXtjaChzaCxyaCkscGUucG9pbnQ9UGF9ZnVuY3Rpb24gZHAoaSx0KXtzaD1pLHJoPXQsaSo9SCx0Kj1ILHBlLnBvaW50PWNoO3ZhciBlPVcodCk7RXQ9ZSpXKGkpLFB0PWUqcShpKSxDdD1xKHQpLFZpKEV0LFB0LEN0KX1mdW5jdGlvbiBjaChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpLG49ZSpXKGkpLHM9ZSpxKGkpLHI9cSh0KSxvPVB0KnItQ3QqcyxhPUN0Km4tRXQqcixjPUV0KnMtUHQqbixsPXdhKG8sYSxjKSxoPU9lKGwpLHU9bCYmLWgvbDt6YS5hZGQodSpvKSxUYS5hZGQodSphKSxFYS5hZGQodSpjKSxmcis9aCxtcis9aCooRXQrKEV0PW4pKSxncis9aCooUHQrKFB0PXMpKSx4cis9aCooQ3QrKEN0PXIpKSxWaShFdCxQdCxDdCl9ZnVuY3Rpb24gbGgoaSl7VWk9ZnI9ZHI9cHI9eXI9bXI9Z3I9eHI9MCx6YT1uZXcgUmUsVGE9bmV3IFJlLEVhPW5ldyBSZSxvcihpLHBlKTt2YXIgdD0remEsZT0rVGEsbj0rRWEscz13YSh0LGUsbik7cmV0dXJuIHM8aXImJih0PW1yLGU9Z3Isbj14cixmcjxLJiYodD1kcixlPXByLG49eXIpLHM9d2EodCxlLG4pLHM8aXIpP1tOYU4sTmFOXTpbcmUoZSx0KSpodCxPZShuL3MpKmh0XX1mdW5jdGlvbiBDYShpLHQpe2Z1bmN0aW9uIGUobixzKXtyZXR1cm4gbj1pKG4scyksdChuWzBdLG5bMV0pfXJldHVybiBpLmludmVydCYmdC5pbnZlcnQmJihlLmludmVydD1mdW5jdGlvbihuLHMpe3JldHVybiBuPXQuaW52ZXJ0KG4scyksbiYmaS5pbnZlcnQoblswXSxuWzFdKX0pLGV9ZnVuY3Rpb24gQmEoaSx0KXtyZXR1cm4gdHQoaSk+WCYmKGktPU1hdGgucm91bmQoaS9SdCkqUnQpLFtpLHRdfUJhLmludmVydD1CYTtmdW5jdGlvbiBoaChpLHQsZSl7cmV0dXJuKGklPVJ0KT90fHxlP0NhKGZoKGkpLGRoKHQsZSkpOmZoKGkpOnR8fGU/ZGgodCxlKTpCYX1mdW5jdGlvbiB1aChpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdCs9aSx0dCh0KT5YJiYodC09TWF0aC5yb3VuZCh0L1J0KSpSdCksW3QsZV19fWZ1bmN0aW9uIGZoKGkpe3ZhciB0PXVoKGkpO3JldHVybiB0LmludmVydD11aCgtaSksdH1mdW5jdGlvbiBkaChpLHQpe3ZhciBlPVcoaSksbj1xKGkpLHM9Vyh0KSxyPXEodCk7ZnVuY3Rpb24gbyhhLGMpe3ZhciBsPVcoYyksaD1XKGEpKmwsdT1xKGEpKmwsZj1xKGMpLGQ9ZiplK2gqbjtyZXR1cm5bcmUodSpzLWQqcixoKmUtZipuKSxPZShkKnMrdSpyKV19cmV0dXJuIG8uaW52ZXJ0PWZ1bmN0aW9uKGEsYyl7dmFyIGw9VyhjKSxoPVcoYSkqbCx1PXEoYSkqbCxmPXEoYyksZD1mKnMtdSpyO3JldHVybltyZSh1KnMrZipyLGgqZStkKm4pLE9lKGQqZS1oKm4pXX0sb31mdW5jdGlvbiBwaChpKXtpPWhoKGlbMF0qSCxpWzFdKkgsaS5sZW5ndGg+Mj9pWzJdKkg6MCk7ZnVuY3Rpb24gdChlKXtyZXR1cm4gZT1pKGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9cmV0dXJuIHQuaW52ZXJ0PWZ1bmN0aW9uKGUpe3JldHVybiBlPWkuaW52ZXJ0KGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9LHR9ZnVuY3Rpb24gcHAoaSx0LGUsbixzLHIpe2lmKGUpe3ZhciBvPVcodCksYT1xKHQpLGM9biplO3M9PW51bGw/KHM9dCtuKlJ0LHI9dC1jLzIpOihzPXloKG8scykscj15aChvLHIpLChuPjA/czxyOnM+cikmJihzKz1uKlJ0KSk7Zm9yKHZhciBsLGg9cztuPjA/aD5yOmg8cjtoLT1jKWw9Y3IoW28sLWEqVyhoKSwtYSpxKGgpXSksaS5wb2ludChsWzBdLGxbMV0pfX1mdW5jdGlvbiB5aChpLHQpe3Q9QW4odCksdFswXS09aSx1cih0KTt2YXIgZT1ucCgtdFsxXSk7cmV0dXJuKCgtdFsyXTwwPy1lOmUpK1J0LUspJVJ0fWZ1bmN0aW9uIG1oKCl7dmFyIGk9W10sdDtyZXR1cm57cG9pbnQ6ZnVuY3Rpb24oZSxuLHMpe3QucHVzaChbZSxuLHNdKX0sbGluZVN0YXJ0OmZ1bmN0aW9uKCl7aS5wdXNoKHQ9W10pfSxsaW5lRW5kOlN0LHJlam9pbjpmdW5jdGlvbigpe2kubGVuZ3RoPjEmJmkucHVzaChpLnBvcCgpLmNvbmNhdChpLnNoaWZ0KCkpKX0scmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGU9aTtyZXR1cm4gaT1bXSx0PW51bGwsZX19fWZ1bmN0aW9uIHdyKGksdCl7cmV0dXJuIHR0KGlbMF0tdFswXSk8SyYmdHQoaVsxXS10WzFdKTxLfWZ1bmN0aW9uIGJyKGksdCxlLG4pe3RoaXMueD1pLHRoaXMuej10LHRoaXMubz1lLHRoaXMuZT1uLHRoaXMudj0hMSx0aGlzLm49dGhpcy5wPW51bGx9ZnVuY3Rpb24gZ2goaSx0LGUsbixzKXt2YXIgcj1bXSxvPVtdLGEsYztpZihpLmZvckVhY2goZnVuY3Rpb24ocCl7aWYoISgoeT1wLmxlbmd0aC0xKTw9MCkpe3ZhciB5LG09cFswXSxnPXBbeV0sYjtpZih3cihtLGcpKXtpZighbVsyXSYmIWdbMl0pe2ZvcihzLmxpbmVTdGFydCgpLGE9MDthPHk7KythKXMucG9pbnQoKG09cFthXSlbMF0sbVsxXSk7cy5saW5lRW5kKCk7cmV0dXJufWdbMF0rPTIqS31yLnB1c2goYj1uZXcgYnIobSxwLG51bGwsITApKSxvLnB1c2goYi5vPW5ldyBicihtLG51bGwsYiwhMSkpLHIucHVzaChiPW5ldyBicihnLHAsbnVsbCwhMSkpLG8ucHVzaChiLm89bmV3IGJyKGcsbnVsbCxiLCEwKSl9fSksISFyLmxlbmd0aCl7Zm9yKG8uc29ydCh0KSx4aChyKSx4aChvKSxhPTAsYz1vLmxlbmd0aDthPGM7KythKW9bYV0uZT1lPSFlO2Zvcih2YXIgbD1yWzBdLGgsdTs7KXtmb3IodmFyIGY9bCxkPSEwO2YudjspaWYoKGY9Zi5uKT09PWwpcmV0dXJuO2g9Zi56LHMubGluZVN0YXJ0KCk7ZG97aWYoZi52PWYuby52PSEwLGYuZSl7aWYoZClmb3IoYT0wLGM9aC5sZW5ndGg7YTxjOysrYSlzLnBvaW50KCh1PWhbYV0pWzBdLHVbMV0pO2Vsc2UgbihmLngsZi5uLngsMSxzKTtmPWYubn1lbHNle2lmKGQpZm9yKGg9Zi5wLnosYT1oLmxlbmd0aC0xO2E+PTA7LS1hKXMucG9pbnQoKHU9aFthXSlbMF0sdVsxXSk7ZWxzZSBuKGYueCxmLnAueCwtMSxzKTtmPWYucH1mPWYubyxoPWYueixkPSFkfXdoaWxlKCFmLnYpO3MubGluZUVuZCgpfX19ZnVuY3Rpb24geGgoaSl7aWYodD1pLmxlbmd0aCl7Zm9yKHZhciB0LGU9MCxuPWlbMF0sczsrK2U8dDspbi5uPXM9aVtlXSxzLnA9bixuPXM7bi5uPXM9aVswXSxzLnA9bn19ZnVuY3Rpb24gRmEoaSl7cmV0dXJuIHR0KGlbMF0pPD1YP2lbMF06dHAoaVswXSkqKCh0dChpWzBdKStYKSVSdC1YKX1mdW5jdGlvbiB3aChpLHQpe3ZhciBlPUZhKHQpLG49dFsxXSxzPXEobikscj1bcShlKSwtVyhlKSwwXSxvPTAsYT0wLGM9bmV3IFJlO3M9PT0xP249TnQrSzpzPT09LTEmJihuPS1OdC1LKTtmb3IodmFyIGw9MCxoPWkubGVuZ3RoO2w8aDsrK2wpaWYoZj0odT1pW2xdKS5sZW5ndGgpZm9yKHZhciB1LGYsZD11W2YtMV0scD1GYShkKSx5PWRbMV0vMitzcixtPXEoeSksZz1XKHkpLGI9MDtiPGY7KytiLHA9eCxtPUEsZz1fLGQ9dyl7dmFyIHc9dVtiXSx4PUZhKHcpLE09d1sxXS8yK3NyLEE9cShNKSxfPVcoTSksUz14LXAsRT1TPj0wPzE6LTEsej1FKlMsdj16PlgsQz1tKkE7aWYoYy5hZGQocmUoQypFKnEoeiksZypfK0MqVyh6KSkpLG8rPXY/UytFKlJ0OlMsdl5wPj1lXng+PWUpe3ZhciBQPWVpKEFuKGQpLEFuKHcpKTt1cihQKTt2YXIgRj1laShyLFApO3VyKEYpO3ZhciBCPSh2XlM+PTA/LTE6MSkqT2UoRlsyXSk7KG4+Qnx8bj09PUImJihQWzBdfHxQWzFdKSkmJihhKz12XlM+PTA/MTotMSl9fXJldHVybihvPC1LfHxvPEsmJmM8LWlyKV5hJjF9ZnVuY3Rpb24gYmgoaSx0LGUsbil7cmV0dXJuIGZ1bmN0aW9uKHMpe3ZhciByPXQocyksbz1taCgpLGE9dChvKSxjPSExLGwsaCx1LGY9e3BvaW50OmQsbGluZVN0YXJ0OnksbGluZUVuZDptLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2YucG9pbnQ9ZyxmLmxpbmVTdGFydD1iLGYubGluZUVuZD13LGg9W10sbD1bXX0scG9seWdvbkVuZDpmdW5jdGlvbigpe2YucG9pbnQ9ZCxmLmxpbmVTdGFydD15LGYubGluZUVuZD1tLGg9RGkoaCk7dmFyIHg9d2gobCxuKTtoLmxlbmd0aD8oY3x8KHMucG9seWdvblN0YXJ0KCksYz0hMCksZ2goaCxtcCx4LGUscykpOngmJihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkpLGMmJihzLnBvbHlnb25FbmQoKSxjPSExKSxoPWw9bnVsbH0sc3BoZXJlOmZ1bmN0aW9uKCl7cy5wb2x5Z29uU3RhcnQoKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkscy5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBkKHgsTSl7aSh4LE0pJiZzLnBvaW50KHgsTSl9ZnVuY3Rpb24gcCh4LE0pe3IucG9pbnQoeCxNKX1mdW5jdGlvbiB5KCl7Zi5wb2ludD1wLHIubGluZVN0YXJ0KCl9ZnVuY3Rpb24gbSgpe2YucG9pbnQ9ZCxyLmxpbmVFbmQoKX1mdW5jdGlvbiBnKHgsTSl7dS5wdXNoKFt4LE1dKSxhLnBvaW50KHgsTSl9ZnVuY3Rpb24gYigpe2EubGluZVN0YXJ0KCksdT1bXX1mdW5jdGlvbiB3KCl7Zyh1WzBdWzBdLHVbMF1bMV0pLGEubGluZUVuZCgpO3ZhciB4PWEuY2xlYW4oKSxNPW8ucmVzdWx0KCksQSxfPU0ubGVuZ3RoLFMsRSx6O2lmKHUucG9wKCksbC5wdXNoKHUpLHU9bnVsbCwhIV8pe2lmKHgmMSl7aWYoRT1NWzBdLChTPUUubGVuZ3RoLTEpPjApe2ZvcihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLEE9MDtBPFM7KytBKXMucG9pbnQoKHo9RVtBXSlbMF0selsxXSk7cy5saW5lRW5kKCl9cmV0dXJufV8+MSYmeCYyJiZNLnB1c2goTS5wb3AoKS5jb25jYXQoTS5zaGlmdCgpKSksaC5wdXNoKE0uZmlsdGVyKHlwKSl9fXJldHVybiBmfX1mdW5jdGlvbiB5cChpKXtyZXR1cm4gaS5sZW5ndGg+MX1mdW5jdGlvbiBtcChpLHQpe3JldHVybigoaT1pLngpWzBdPDA/aVsxXS1OdC1LOk50LWlbMV0pLSgodD10LngpWzBdPDA/dFsxXS1OdC1LOk50LXRbMV0pfXZhciBNaD1iaChmdW5jdGlvbigpe3JldHVybiEwfSxncCx3cCxbLVgsLU50XSk7ZnVuY3Rpb24gZ3AoaSl7dmFyIHQ9TmFOLGU9TmFOLG49TmFOLHM7cmV0dXJue2xpbmVTdGFydDpmdW5jdGlvbigpe2kubGluZVN0YXJ0KCkscz0xfSxwb2ludDpmdW5jdGlvbihyLG8pe3ZhciBhPXI+MD9YOi1YLGM9dHQoci10KTt0dChjLVgpPEs/KGkucG9pbnQodCxlPShlK28pLzI+MD9OdDotTnQpLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxpLnBvaW50KHIsZSkscz0wKTpuIT09YSYmYz49WCYmKHR0KHQtbik8SyYmKHQtPW4qSyksdHQoci1hKTxLJiYoci09YSpLKSxlPXhwKHQsZSxyLG8pLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxzPTApLGkucG9pbnQodD1yLGU9byksbj1hfSxsaW5lRW5kOmZ1bmN0aW9uKCl7aS5saW5lRW5kKCksdD1lPU5hTn0sY2xlYW46ZnVuY3Rpb24oKXtyZXR1cm4gMi1zfX19ZnVuY3Rpb24geHAoaSx0LGUsbil7dmFyIHMscixvPXEoaS1lKTtyZXR1cm4gdHQobyk+Sz94YSgocSh0KSoocj1XKG4pKSpxKGUpLXEobikqKHM9Vyh0KSkqcShpKSkvKHMqcipvKSk6KHQrbikvMn1mdW5jdGlvbiB3cChpLHQsZSxuKXt2YXIgcztpZihpPT1udWxsKXM9ZSpOdCxuLnBvaW50KC1YLHMpLG4ucG9pbnQoMCxzKSxuLnBvaW50KFgscyksbi5wb2ludChYLDApLG4ucG9pbnQoWCwtcyksbi5wb2ludCgwLC1zKSxuLnBvaW50KC1YLC1zKSxuLnBvaW50KC1YLDApLG4ucG9pbnQoLVgscyk7ZWxzZSBpZih0dChpWzBdLXRbMF0pPkspe3ZhciByPWlbMF08dFswXT9YOi1YO3M9ZSpyLzIsbi5wb2ludCgtcixzKSxuLnBvaW50KDAscyksbi5wb2ludChyLHMpfWVsc2Ugbi5wb2ludCh0WzBdLHRbMV0pfWZ1bmN0aW9uIGJwKGkpe3ZhciB0PVcoaSksZT0yKkgsbj10PjAscz10dCh0KT5LO2Z1bmN0aW9uIHIoaCx1LGYsZCl7cHAoZCxpLGUsZixoLHUpfWZ1bmN0aW9uIG8oaCx1KXtyZXR1cm4gVyhoKSpXKHUpPnR9ZnVuY3Rpb24gYShoKXt2YXIgdSxmLGQscCx5O3JldHVybntsaW5lU3RhcnQ6ZnVuY3Rpb24oKXtwPWQ9ITEseT0xfSxwb2ludDpmdW5jdGlvbihtLGcpe3ZhciBiPVttLGddLHcseD1vKG0sZyksTT1uP3g/MDpsKG0sZyk6eD9sKG0rKG08MD9YOi1YKSxnKTowO2lmKCF1JiYocD1kPXgpJiZoLmxpbmVTdGFydCgpLHghPT1kJiYodz1jKHUsYiksKCF3fHx3cih1LHcpfHx3cihiLHcpKSYmKGJbMl09MSkpLHghPT1kKXk9MCx4PyhoLmxpbmVTdGFydCgpLHc9YyhiLHUpLGgucG9pbnQod1swXSx3WzFdKSk6KHc9Yyh1LGIpLGgucG9pbnQod1swXSx3WzFdLDIpLGgubGluZUVuZCgpKSx1PXc7ZWxzZSBpZihzJiZ1JiZuXngpe3ZhciBBOyEoTSZmKSYmKEE9YyhiLHUsITApKSYmKHk9MCxuPyhoLmxpbmVTdGFydCgpLGgucG9pbnQoQVswXVswXSxBWzBdWzFdKSxoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCkpOihoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCksaC5saW5lU3RhcnQoKSxoLnBvaW50KEFbMF1bMF0sQVswXVsxXSwzKSkpfXgmJighdXx8IXdyKHUsYikpJiZoLnBvaW50KGJbMF0sYlsxXSksdT1iLGQ9eCxmPU19LGxpbmVFbmQ6ZnVuY3Rpb24oKXtkJiZoLmxpbmVFbmQoKSx1PW51bGx9LGNsZWFuOmZ1bmN0aW9uKCl7cmV0dXJuIHl8KHAmJmQpPDwxfX19ZnVuY3Rpb24gYyhoLHUsZil7dmFyIGQ9QW4oaCkscD1Bbih1KSx5PVsxLDAsMF0sbT1laShkLHApLGc9bHIobSxtKSxiPW1bMF0sdz1nLWIqYjtpZighdylyZXR1cm4hZiYmaDt2YXIgeD10KmcvdyxNPS10KmIvdyxBPWVpKHksbSksXz1ocih5LHgpLFM9aHIobSxNKTtTYShfLFMpO3ZhciBFPUEsej1scihfLEUpLHY9bHIoRSxFKSxDPXoqei12KihscihfLF8pLTEpO2lmKCEoQzwwKSl7dmFyIFA9TGUoQyksRj1ocihFLCgtei1QKS92KTtpZihTYShGLF8pLEY9Y3IoRiksIWYpcmV0dXJuIEY7dmFyIEI9aFswXSxJPXVbMF0saz1oWzFdLEQ9dVsxXSxWO0k8QiYmKFY9QixCPUksST1WKTt2YXIgaj1JLUIsZHQ9dHQoai1YKTxLLER0PWR0fHxqPEs7aWYoIWR0JiZEPGsmJihWPWssaz1ELEQ9ViksRHQ/ZHQ/aytEPjBeRlsxXTwodHQoRlswXS1CKTxLP2s6RCk6azw9RlsxXSYmRlsxXTw9RDpqPlheKEI8PUZbMF0mJkZbMF08PUkpKXt2YXIgR3Q9aHIoRSwoLXorUCkvdik7cmV0dXJuIFNhKEd0LF8pLFtGLGNyKEd0KV19fX1mdW5jdGlvbiBsKGgsdSl7dmFyIGY9bj9pOlgtaSxkPTA7cmV0dXJuIGg8LWY/ZHw9MTpoPmYmJihkfD0yKSx1PC1mP2R8PTQ6dT5mJiYoZHw9OCksZH1yZXR1cm4gYmgobyxhLHIsbj9bMCwtaV06Wy1YLGktWF0pfWZ1bmN0aW9uIE1wKGksdCxlLG4scyxyKXt2YXIgbz1pWzBdLGE9aVsxXSxjPXRbMF0sbD10WzFdLGg9MCx1PTEsZj1jLW8sZD1sLWEscDtpZihwPWUtbywhKCFmJiZwPjApKXtpZihwLz1mLGY8MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWVsc2UgaWYoZj4wKXtpZihwPnUpcmV0dXJuO3A+aCYmKGg9cCl9aWYocD1zLW8sISghZiYmcDwwKSl7aWYocC89ZixmPDApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1lbHNlIGlmKGY+MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWlmKHA9bi1hLCEoIWQmJnA+MCkpe2lmKHAvPWQsZDwwKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9ZWxzZSBpZihkPjApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1pZihwPXItYSwhKCFkJiZwPDApKXtpZihwLz1kLGQ8MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWVsc2UgaWYoZD4wKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9cmV0dXJuIGg+MCYmKGlbMF09bytoKmYsaVsxXT1hK2gqZCksdTwxJiYodFswXT1vK3UqZix0WzFdPWErdSpkKSwhMH19fX19dmFyIHFpPTFlOSxNcj0tcWk7ZnVuY3Rpb24gQXAoaSx0LGUsbil7ZnVuY3Rpb24gcyhsLGgpe3JldHVybiBpPD1sJiZsPD1lJiZ0PD1oJiZoPD1ufWZ1bmN0aW9uIHIobCxoLHUsZil7dmFyIGQ9MCxwPTA7aWYobD09bnVsbHx8KGQ9byhsLHUpKSE9PShwPW8oaCx1KSl8fGMobCxoKTwwXnU+MClkbyBmLnBvaW50KGQ9PT0wfHxkPT09Mz9pOmUsZD4xP246dCk7d2hpbGUoKGQ9KGQrdSs0KSU0KSE9PXApO2Vsc2UgZi5wb2ludChoWzBdLGhbMV0pfWZ1bmN0aW9uIG8obCxoKXtyZXR1cm4gdHQobFswXS1pKTxLP2g+MD8wOjM6dHQobFswXS1lKTxLP2g+MD8yOjE6dHQobFsxXS10KTxLP2g+MD8xOjA6aD4wPzM6Mn1mdW5jdGlvbiBhKGwsaCl7cmV0dXJuIGMobC54LGgueCl9ZnVuY3Rpb24gYyhsLGgpe3ZhciB1PW8obCwxKSxmPW8oaCwxKTtyZXR1cm4gdSE9PWY/dS1mOnU9PT0wP2hbMV0tbFsxXTp1PT09MT9sWzBdLWhbMF06dT09PTI/bFsxXS1oWzFdOmhbMF0tbFswXX1yZXR1cm4gZnVuY3Rpb24obCl7dmFyIGg9bCx1PW1oKCksZixkLHAseSxtLGcsYix3LHgsTSxBLF89e3BvaW50OlMsbGluZVN0YXJ0OkMsbGluZUVuZDpQLHBvbHlnb25TdGFydDp6LHBvbHlnb25FbmQ6dn07ZnVuY3Rpb24gUyhCLEkpe3MoQixJKSYmaC5wb2ludChCLEkpfWZ1bmN0aW9uIEUoKXtmb3IodmFyIEI9MCxJPTAsaz1kLmxlbmd0aDtJPGs7KytJKWZvcih2YXIgRD1kW0ldLFY9MSxqPUQubGVuZ3RoLGR0PURbMF0sRHQsR3QsWnQ9ZHRbMF0sbWU9ZHRbMV07VjxqOysrVilEdD1adCxHdD1tZSxkdD1EW1ZdLFp0PWR0WzBdLG1lPWR0WzFdLEd0PD1uP21lPm4mJihadC1EdCkqKG4tR3QpPihtZS1HdCkqKGktRHQpJiYrK0I6bWU8PW4mJihadC1EdCkqKG4tR3QpPChtZS1HdCkqKGktRHQpJiYtLUI7cmV0dXJuIEJ9ZnVuY3Rpb24geigpe2g9dSxmPVtdLGQ9W10sQT0hMH1mdW5jdGlvbiB2KCl7dmFyIEI9RSgpLEk9QSYmQixrPShmPURpKGYpKS5sZW5ndGg7KEl8fGspJiYobC5wb2x5Z29uU3RhcnQoKSxJJiYobC5saW5lU3RhcnQoKSxyKG51bGwsbnVsbCwxLGwpLGwubGluZUVuZCgpKSxrJiZnaChmLGEsQixyLGwpLGwucG9seWdvbkVuZCgpKSxoPWwsZj1kPXA9bnVsbH1mdW5jdGlvbiBDKCl7Xy5wb2ludD1GLGQmJmQucHVzaChwPVtdKSxNPSEwLHg9ITEsYj13PU5hTn1mdW5jdGlvbiBQKCl7ZiYmKEYoeSxtKSxnJiZ4JiZ1LnJlam9pbigpLGYucHVzaCh1LnJlc3VsdCgpKSksXy5wb2ludD1TLHgmJmgubGluZUVuZCgpfWZ1bmN0aW9uIEYoQixJKXt2YXIgaz1zKEIsSSk7aWYoZCYmcC5wdXNoKFtCLEldKSxNKXk9QixtPUksZz1rLE09ITEsayYmKGgubGluZVN0YXJ0KCksaC5wb2ludChCLEkpKTtlbHNlIGlmKGsmJngpaC5wb2ludChCLEkpO2Vsc2V7dmFyIEQ9W2I9TWF0aC5tYXgoTXIsTWF0aC5taW4ocWksYikpLHc9TWF0aC5tYXgoTXIsTWF0aC5taW4ocWksdykpXSxWPVtCPU1hdGgubWF4KE1yLE1hdGgubWluKHFpLEIpKSxJPU1hdGgubWF4KE1yLE1hdGgubWluKHFpLEkpKV07TXAoRCxWLGksdCxlLG4pPyh4fHwoaC5saW5lU3RhcnQoKSxoLnBvaW50KERbMF0sRFsxXSkpLGgucG9pbnQoVlswXSxWWzFdKSxrfHxoLmxpbmVFbmQoKSxBPSExKTprJiYoaC5saW5lU3RhcnQoKSxoLnBvaW50KEIsSSksQT0hMSl9Yj1CLHc9SSx4PWt9cmV0dXJuIF99fXZhciBJYSxrYSxBcixfcixpaT17c3BoZXJlOlN0LHBvaW50OlN0LGxpbmVTdGFydDpfcCxsaW5lRW5kOlN0LHBvbHlnb25TdGFydDpTdCxwb2x5Z29uRW5kOlN0fTtmdW5jdGlvbiBfcCgpe2lpLnBvaW50PXZwLGlpLmxpbmVFbmQ9U3B9ZnVuY3Rpb24gU3AoKXtpaS5wb2ludD1paS5saW5lRW5kPVN0fWZ1bmN0aW9uIHZwKGksdCl7aSo9SCx0Kj1ILGthPWksQXI9cSh0KSxfcj1XKHQpLGlpLnBvaW50PXpwfWZ1bmN0aW9uIHpwKGksdCl7aSo9SCx0Kj1IO3ZhciBlPXEodCksbj1XKHQpLHM9dHQoaS1rYSkscj1XKHMpLG89cShzKSxhPW4qbyxjPV9yKmUtQXIqbipyLGw9QXIqZStfcipuKnI7SWEuYWRkKHJlKExlKGEqYStjKmMpLGwpKSxrYT1pLEFyPWUsX3I9bn1mdW5jdGlvbiBUcChpKXtyZXR1cm4gSWE9bmV3IFJlLG9yKGksaWkpLCtJYX12YXIgTmE9W251bGwsbnVsbF0sRXA9e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOk5hfTtmdW5jdGlvbiBzaShpLHQpe3JldHVybiBOYVswXT1pLE5hWzFdPXQsVHAoRXApfXZhciBBaD17RmVhdHVyZTpmdW5jdGlvbihpLHQpe3JldHVybiBTcihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoU3IoZVtuXS5nZW9tZXRyeSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19LF9oPXtTcGhlcmU6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sUG9pbnQ6ZnVuY3Rpb24oaSx0KXtyZXR1cm4gU2goaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoU2goZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX0sTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe3JldHVybiB2aChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWlmKHZoKGVbbl0sdCkpcmV0dXJuITA7cmV0dXJuITF9LFBvbHlnb246ZnVuY3Rpb24oaSx0KXtyZXR1cm4gemgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2x5Z29uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZih6aChlW25dLHQpKXJldHVybiEwO3JldHVybiExfSxHZW9tZXRyeUNvbGxlY3Rpb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5nZW9tZXRyaWVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoU3IoZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19O2Z1bmN0aW9uIFNyKGksdCl7cmV0dXJuIGkmJl9oLmhhc093blByb3BlcnR5KGkudHlwZSk/X2hbaS50eXBlXShpLHQpOiExfWZ1bmN0aW9uIFNoKGksdCl7cmV0dXJuIHNpKGksdCk9PT0wfWZ1bmN0aW9uIHZoKGksdCl7Zm9yKHZhciBlLG4scyxyPTAsbz1pLmxlbmd0aDtyPG87cisrKXtpZihuPXNpKGlbcl0sdCksbj09PTB8fHI+MCYmKHM9c2koaVtyXSxpW3ItMV0pLHM+MCYmZTw9cyYmbjw9cyYmKGUrbi1zKSooMS1NYXRoLnBvdygoZS1uKS9zLDIpKTxpcipzKSlyZXR1cm4hMDtlPW59cmV0dXJuITF9ZnVuY3Rpb24gemgoaSx0KXtyZXR1cm4hIXdoKGkubWFwKFBwKSxUaCh0KSl9ZnVuY3Rpb24gUHAoaSl7cmV0dXJuIGk9aS5tYXAoVGgpLGkucG9wKCksaX1mdW5jdGlvbiBUaChpKXtyZXR1cm5baVswXSpILGlbMV0qSF19ZnVuY3Rpb24gQ3AoaSx0KXtyZXR1cm4oaSYmQWguaGFzT3duUHJvcGVydHkoaS50eXBlKT9BaFtpLnR5cGVdOlNyKShpLHQpfWZ1bmN0aW9uIEJwKGksdCl7dmFyIGU9aVswXSpILG49aVsxXSpILHM9dFswXSpILHI9dFsxXSpILG89VyhuKSxhPXEobiksYz1XKHIpLGw9cShyKSxoPW8qVyhlKSx1PW8qcShlKSxmPWMqVyhzKSxkPWMqcShzKSxwPTIqT2UoTGUoVmwoci1uKStvKmMqVmwocy1lKSkpLHk9cShwKSxtPXA/ZnVuY3Rpb24oZyl7dmFyIGI9cShnKj1wKS95LHc9cShwLWcpL3kseD13KmgrYipmLE09dyp1K2IqZCxBPXcqYStiKmw7cmV0dXJuW3JlKE0seCkqaHQscmUoQSxMZSh4KngrTSpNKSkqaHRdfTpmdW5jdGlvbigpe3JldHVybltlKmh0LG4qaHRdfTtyZXR1cm4gbS5kaXN0YW5jZT1wLG19dmFyIEVoPWk9Pmkscmk9MS8wLHZyPXJpLEhpPS1yaSx6cj1IaSxQaD17cG9pbnQ6RnAsbGluZVN0YXJ0OlN0LGxpbmVFbmQ6U3QscG9seWdvblN0YXJ0OlN0LHBvbHlnb25FbmQ6U3QscmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGk9W1tyaSx2cl0sW0hpLHpyXV07cmV0dXJuIEhpPXpyPS0odnI9cmk9MS8wKSxpfX07ZnVuY3Rpb24gRnAoaSx0KXtpPHJpJiYocmk9aSksaT5IaSYmKEhpPWkpLHQ8dnImJih2cj10KSx0PnpyJiYoenI9dCl9ZnVuY3Rpb24gUmEoaSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBMYTtmb3IodmFyIG4gaW4gaSllW25dPWlbbl07cmV0dXJuIGUuc3RyZWFtPXQsZX19ZnVuY3Rpb24gTGEoKXt9TGEucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpMYSxwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGksdCl9LHNwaGVyZTpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLnNwaGVyZSgpfSxsaW5lU3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5saW5lU3RhcnQoKX0sbGluZUVuZDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLmxpbmVFbmQoKX0scG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0ucG9seWdvblN0YXJ0KCl9LHBvbHlnb25FbmQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBPYShpLHQsZSl7dmFyIG49aS5jbGlwRXh0ZW50JiZpLmNsaXBFeHRlbnQoKTtyZXR1cm4gaS5zY2FsZSgxNTApLnRyYW5zbGF0ZShbMCwwXSksbiE9bnVsbCYmaS5jbGlwRXh0ZW50KG51bGwpLG9yKGUsaS5zdHJlYW0oUGgpKSx0KFBoLnJlc3VsdCgpKSxuIT1udWxsJiZpLmNsaXBFeHRlbnQobiksaX1mdW5jdGlvbiBDaChpLHQsZSl7cmV0dXJuIE9hKGksZnVuY3Rpb24obil7dmFyIHM9dFsxXVswXS10WzBdWzBdLHI9dFsxXVsxXS10WzBdWzFdLG89TWF0aC5taW4ocy8oblsxXVswXS1uWzBdWzBdKSxyLyhuWzFdWzFdLW5bMF1bMV0pKSxhPSt0WzBdWzBdKyhzLW8qKG5bMV1bMF0rblswXVswXSkpLzIsYz0rdFswXVsxXSsoci1vKihuWzFdWzFdK25bMF1bMV0pKS8yO2kuc2NhbGUoMTUwKm8pLnRyYW5zbGF0ZShbYSxjXSl9LGUpfWZ1bmN0aW9uIElwKGksdCxlKXtyZXR1cm4gQ2goaSxbWzAsMF0sdF0sZSl9ZnVuY3Rpb24ga3AoaSx0LGUpe3JldHVybiBPYShpLGZ1bmN0aW9uKG4pe3ZhciBzPSt0LHI9cy8oblsxXVswXS1uWzBdWzBdKSxvPShzLXIqKG5bMV1bMF0rblswXVswXSkpLzIsYT0tcipuWzBdWzFdO2kuc2NhbGUoMTUwKnIpLnRyYW5zbGF0ZShbbyxhXSl9LGUpfWZ1bmN0aW9uIE5wKGksdCxlKXtyZXR1cm4gT2EoaSxmdW5jdGlvbihuKXt2YXIgcz0rdCxyPXMvKG5bMV1bMV0tblswXVsxXSksbz0tcipuWzBdWzBdLGE9KHMtciooblsxXVsxXStuWzBdWzFdKSkvMjtpLnNjYWxlKDE1MCpyKS50cmFuc2xhdGUoW28sYV0pfSxlKX12YXIgQmg9MTYsUnA9VygzMCpIKTtmdW5jdGlvbiBGaChpLHQpe3JldHVybit0P09wKGksdCk6THAoaSl9ZnVuY3Rpb24gTHAoaSl7cmV0dXJuIFJhKHtwb2ludDpmdW5jdGlvbih0LGUpe3Q9aSh0LGUpLHRoaXMuc3RyZWFtLnBvaW50KHRbMF0sdFsxXSl9fSl9ZnVuY3Rpb24gT3AoaSx0KXtmdW5jdGlvbiBlKG4scyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbSl7dmFyIGc9bC1uLGI9aC1zLHc9ZypnK2IqYjtpZih3PjQqdCYmeS0tKXt2YXIgeD1vK2YsTT1hK2QsQT1jK3AsXz1MZSh4KngrTSpNK0EqQSksUz1PZShBLz1fKSxFPXR0KHR0KEEpLTEpPEt8fHR0KHItdSk8Sz8ocit1KS8yOnJlKE0seCksej1pKEUsUyksdj16WzBdLEM9elsxXSxQPXYtbixGPUMtcyxCPWIqUC1nKkY7KEIqQi93PnR8fHR0KChnKlArYipGKS93LS41KT4uM3x8bypmK2EqZCtjKnA8UnApJiYoZShuLHMscixvLGEsYyx2LEMsRSx4Lz1fLE0vPV8sQSx5LG0pLG0ucG9pbnQodixDKSxlKHYsQyxFLHgsTSxBLGwsaCx1LGYsZCxwLHksbSkpfX1yZXR1cm4gZnVuY3Rpb24obil7dmFyIHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG09e3BvaW50OmcsbGluZVN0YXJ0OmIsbGluZUVuZDp4LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe24ucG9seWdvblN0YXJ0KCksbS5saW5lU3RhcnQ9TX0scG9seWdvbkVuZDpmdW5jdGlvbigpe24ucG9seWdvbkVuZCgpLG0ubGluZVN0YXJ0PWJ9fTtmdW5jdGlvbiBnKFMsRSl7Uz1pKFMsRSksbi5wb2ludChTWzBdLFNbMV0pfWZ1bmN0aW9uIGIoKXt1PU5hTixtLnBvaW50PXcsbi5saW5lU3RhcnQoKX1mdW5jdGlvbiB3KFMsRSl7dmFyIHo9QW4oW1MsRV0pLHY9aShTLEUpO2UodSxmLGgsZCxwLHksdT12WzBdLGY9dlsxXSxoPVMsZD16WzBdLHA9elsxXSx5PXpbMl0sQmgsbiksbi5wb2ludCh1LGYpfWZ1bmN0aW9uIHgoKXttLnBvaW50PWcsbi5saW5lRW5kKCl9ZnVuY3Rpb24gTSgpe2IoKSxtLnBvaW50PUEsbS5saW5lRW5kPV99ZnVuY3Rpb24gQShTLEUpe3cocz1TLEUpLHI9dSxvPWYsYT1kLGM9cCxsPXksbS5wb2ludD13fWZ1bmN0aW9uIF8oKXtlKHUsZixoLGQscCx5LHIsbyxzLGEsYyxsLEJoLG4pLG0ubGluZUVuZD14LHgoKX1yZXR1cm4gbX19dmFyIERwPVJhKHtwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGkqSCx0KkgpfX0pO2Z1bmN0aW9uICRwKGkpe3JldHVybiBSYSh7cG9pbnQ6ZnVuY3Rpb24odCxlKXt2YXIgbj1pKHQsZSk7cmV0dXJuIHRoaXMuc3RyZWFtLnBvaW50KG5bMF0sblsxXSl9fSl9ZnVuY3Rpb24gVXAoaSx0LGUsbixzKXtmdW5jdGlvbiByKG8sYSl7cmV0dXJuIG8qPW4sYSo9cyxbdCtpKm8sZS1pKmFdfXJldHVybiByLmludmVydD1mdW5jdGlvbihvLGEpe3JldHVyblsoby10KS9pKm4sKGUtYSkvaSpzXX0scn1mdW5jdGlvbiBJaChpLHQsZSxuLHMscil7aWYoIXIpcmV0dXJuIFVwKGksdCxlLG4scyk7dmFyIG89VyhyKSxhPXEociksYz1vKmksbD1hKmksaD1vL2ksdT1hL2ksZj0oYSplLW8qdCkvaSxkPShhKnQrbyplKS9pO2Z1bmN0aW9uIHAoeSxtKXtyZXR1cm4geSo9bixtKj1zLFtjKnktbCptK3QsZS1sKnktYyptXX1yZXR1cm4gcC5pbnZlcnQ9ZnVuY3Rpb24oeSxtKXtyZXR1cm5bbiooaCp5LXUqbStmKSxzKihkLXUqeS1oKm0pXX0scH1mdW5jdGlvbiBUcihpKXtyZXR1cm4gVnAoZnVuY3Rpb24oKXtyZXR1cm4gaX0pKCl9ZnVuY3Rpb24gVnAoaSl7dmFyIHQsZT0xNTAsbj00ODAscz0yNTAscj0wLG89MCxhPTAsYz0wLGw9MCxoLHU9MCxmPTEsZD0xLHA9bnVsbCx5PU1oLG09bnVsbCxnLGIsdyx4PUVoLE09LjUsQSxfLFMsRSx6O2Z1bmN0aW9uIHYoQil7cmV0dXJuIFMoQlswXSpILEJbMV0qSCl9ZnVuY3Rpb24gQyhCKXtyZXR1cm4gQj1TLmludmVydChCWzBdLEJbMV0pLEImJltCWzBdKmh0LEJbMV0qaHRdfXYuc3RyZWFtPWZ1bmN0aW9uKEIpe3JldHVybiBFJiZ6PT09Qj9FOkU9RHAoJHAoaCkoeShBKHgoej1CKSkpKSl9LHYucHJlY2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeT1CLHA9dm9pZCAwLEYoKSk6eX0sdi5wb3N0Y2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CLG09Zz1iPXc9bnVsbCxGKCkpOnh9LHYuY2xpcEFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh5PStCP2JwKHA9QipIKToocD1udWxsLE1oKSxGKCkpOnAqaHR9LHYuY2xpcEV4dGVudD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CPT1udWxsPyhtPWc9Yj13PW51bGwsRWgpOkFwKG09K0JbMF1bMF0sZz0rQlswXVsxXSxiPStCWzFdWzBdLHc9K0JbMV1bMV0pLEYoKSk6bT09bnVsbD9udWxsOltbbSxnXSxbYix3XV19LHYuc2NhbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGU9K0IsUCgpKTplfSx2LnRyYW5zbGF0ZT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obj0rQlswXSxzPStCWzFdLFAoKSk6W24sc119LHYuY2VudGVyPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhyPUJbMF0lMzYwKkgsbz1CWzFdJTM2MCpILFAoKSk6W3IqaHQsbypodF19LHYucm90YXRlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhhPUJbMF0lMzYwKkgsYz1CWzFdJTM2MCpILGw9Qi5sZW5ndGg+Mj9CWzJdJTM2MCpIOjAsUCgpKTpbYSpodCxjKmh0LGwqaHRdfSx2LmFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh1PUIlMzYwKkgsUCgpKTp1Kmh0fSx2LnJlZmxlY3RYPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhmPUI/LTE6MSxQKCkpOmY8MH0sdi5yZWZsZWN0WT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZD1CPy0xOjEsUCgpKTpkPDB9LHYucHJlY2lzaW9uPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhBPUZoKF8sTT1CKkIpLEYoKSk6TGUoTSl9LHYuZml0RXh0ZW50PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIENoKHYsQixJKX0sdi5maXRTaXplPWZ1bmN0aW9uKEIsSSl7cmV0dXJuIElwKHYsQixJKX0sdi5maXRXaWR0aD1mdW5jdGlvbihCLEkpe3JldHVybiBrcCh2LEIsSSl9LHYuZml0SGVpZ2h0PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIE5wKHYsQixJKX07ZnVuY3Rpb24gUCgpe3ZhciBCPUloKGUsMCwwLGYsZCx1KS5hcHBseShudWxsLHQocixvKSksST1JaChlLG4tQlswXSxzLUJbMV0sZixkLHUpO3JldHVybiBoPWhoKGEsYyxsKSxfPUNhKHQsSSksUz1DYShoLF8pLEE9RmgoXyxNKSxGKCl9ZnVuY3Rpb24gRigpe3JldHVybiBFPXo9bnVsbCx2fXJldHVybiBmdW5jdGlvbigpe3JldHVybiB0PWkuYXBwbHkodGhpcyxhcmd1bWVudHMpLHYuaW52ZXJ0PXQuaW52ZXJ0JiZDLFAoKX19ZnVuY3Rpb24gcXAoaSl7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7dmFyIG49TGUodCp0K2UqZSkscz1pKG4pLHI9cShzKSxvPVcocyk7cmV0dXJuW3JlKHQqcixuKm8pLE9lKG4mJmUqci9uKV19fWZ1bmN0aW9uIERhKGksdCl7cmV0dXJuW2ksSzAoZXAoKE50K3QpLzIpKV19RGEuaW52ZXJ0PWZ1bmN0aW9uKGksdCl7cmV0dXJuW2ksMip4YShRMCh0KSktTnRdfTtmdW5jdGlvbiBIcCgpe3JldHVybiBXcChEYSkuc2NhbGUoOTYxL1J0KX1mdW5jdGlvbiBXcChpKXt2YXIgdD1UcihpKSxlPXQuY2VudGVyLG49dC5zY2FsZSxzPXQudHJhbnNsYXRlLHI9dC5jbGlwRXh0ZW50LG89bnVsbCxhLGMsbDt0LnNjYWxlPWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhuKHUpLGgoKSk6bigpfSx0LnRyYW5zbGF0ZT1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8ocyh1KSxoKCkpOnMoKX0sdC5jZW50ZXI9ZnVuY3Rpb24odSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGUodSksaCgpKTplKCl9LHQuY2xpcEV4dGVudD1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odT09bnVsbD9vPWE9Yz1sPW51bGw6KG89K3VbMF1bMF0sYT0rdVswXVsxXSxjPSt1WzFdWzBdLGw9K3VbMV1bMV0pLGgoKSk6bz09bnVsbD9udWxsOltbbyxhXSxbYyxsXV19O2Z1bmN0aW9uIGgoKXt2YXIgdT1YKm4oKSxmPXQocGgodC5yb3RhdGUoKSkuaW52ZXJ0KFswLDBdKSk7cmV0dXJuIHIobz09bnVsbD9bW2ZbMF0tdSxmWzFdLXVdLFtmWzBdK3UsZlsxXSt1XV06aT09PURhP1tbTWF0aC5tYXgoZlswXS11LG8pLGFdLFtNYXRoLm1pbihmWzBdK3UsYyksbF1dOltbbyxNYXRoLm1heChmWzFdLXUsYSldLFtjLE1hdGgubWluKGZbMV0rdSxsKV1dKX1yZXR1cm4gaCgpfWZ1bmN0aW9uICRhKGksdCl7cmV0dXJuW2ksdF19JGEuaW52ZXJ0PSRhO2Z1bmN0aW9uIEdwKCl7cmV0dXJuIFRyKCRhKS5zY2FsZSgxNTIuNjMpfWZ1bmN0aW9uIGtoKGksdCl7dmFyIGU9Vyh0KSxuPTErVyhpKSplO3JldHVybltlKnEoaSkvbixxKHQpL25dfWtoLmludmVydD1xcChmdW5jdGlvbihpKXtyZXR1cm4gMip4YShpKX0pO2Z1bmN0aW9uIFpwKCl7cmV0dXJuIFRyKGtoKS5zY2FsZSgyNTApLmNsaXBBbmdsZSgxNDIpfXZhciBYcD1NYXRoLmF0YW4sSnA9TWF0aC5jb3MsWXA9TWF0aC50YW4sanA9TWF0aC5QSSxRcD1qcC8xODA7ZnVuY3Rpb24gTmgoaSl7cmV0dXJuIGk+MD9NYXRoLnNxcnQoaSk6MH12YXIgRXI9SnAoMzUqUXApO2Z1bmN0aW9uIFJoKGksdCl7dmFyIGU9WXAodC8yKTtyZXR1cm5baSpFcipOaCgxLWUqZSksKDErRXIpKmVdfVJoLmludmVydD1mdW5jdGlvbihpLHQpe3ZhciBlPXQvKDErRXIpO3JldHVybltpJiZpLyhFcipOaCgxLWUqZSkpLDIqWHAoZSldfTtmdW5jdGlvbiBLcCgpe3JldHVybiBUcihSaCkuc2NhbGUoMTM3LjE1Mil9Y29uc3QgdHk9e21lcmNhdG9yOkhwLGVxdWlyZWN0YW5ndWxhcjpHcCxmYWhleTpLcH0sVWE9e30sV2k9aT0+e3ZhciBuLHMscjtjb25zdCB0PUpTT04uc3RyaW5naWZ5KGkpO2lmKFVhW3RdKXJldHVybiBVYVt0XTtjb25zdCBlPXR5WyhuPWkucHJvamVjdGlvblR5cGUpIT1udWxsP246Im1lcmNhdG9yIl0oKS5jZW50ZXIoaS5jZW50ZXIpLnNjYWxlKGkuc2NhbGUpLnRyYW5zbGF0ZSgocz1pLnRyYW5zbGF0ZSkhPW51bGw/czpbMCwwXSkucHJlY2lzaW9uKChyPWkucHJlY2lzaW9uKSE9bnVsbD9yOi4xKTtyZXR1cm4gaS5yb3RhdGUmJmUucm90YXRlKGkucm90YXRlKSxVYVt0XT1lLGV9LFByPShpLHQpPT5pLm1hcCgoW2Usbl0pPT57bGV0IHM7aWYodCl7Y29uc3RbcixvXT10KFtlLG5dKTtzPW5ldyBSKHIsLW8pfWVsc2Ugcz1uZXcgUihlLG4pO3JldHVybiBzfSk7dmFyIEdpPShpLHQpPT57Y29uc3QgZT0kbChpLHQhPW51bGw/dDowKSxuPXt9LHM9W10scj1PYmplY3Qua2V5cyhlLmF0dHJpYnV0ZXMpO3JldHVybiBlLmluZGV4JiZyLnB1c2goImluZGV4Iiksci5mb3JFYWNoKG89Pntjb25zdCBhPW89PT0iaW5kZXgiP2UuaW5kZXg6ZS5hdHRyaWJ1dGVzW29dO25bb109e2FycmF5OmEuYXJyYXksaXRlbVNpemU6YS5pdGVtU2l6ZX0scy5wdXNoKGEuYXJyYXkuYnVmZmVyKX0pLHQmJihuLmdyb3Vwcz1lLmdyb3VwcyksZS5kaXNwb3NlKCksaS5mb3JFYWNoKG89PntvLmRpc3Bvc2UoKX0pLHttZXNzYWdlOm4sdHJhbnNmZXI6c319LFZhPShpLHQ9MzAwKT0+e2NvbnN0IGU9W107cmV0dXJuIGkuZm9yRWFjaChuPT57bGV0IHM9ITE7Zm9yKGxldCByPTE7cjxuLmxlbmd0aDtyKyspaWYoTWF0aC5hYnMobltyXS54LW5bci0xXS54KT50KXtzPSEwO2JyZWFrfWlmKHMpe2NvbnN0IHI9W10sbz1bXTtuLmZvckVhY2goYT0+e2EueDwwP3IucHVzaChhKTpvLnB1c2goYSl9KSxlLnB1c2gocixvKX1lbHNlIGUucHVzaChuKX0pLGV9O2NvbnN0IGV5PSh7Y29vcmRpbmF0ZXNBcnI6aSxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxiYm94Om4sYmJveE9mZnNldDpzLGRlcHRoOnIscHJvamVjdGlvbjpvLHVzZUdyb3VwczphLGhhc1RvcDpjLGhhc0JvdHRvbTpsLGhhc1NpZGU6aCxzcGxpdFBvbHlnb25zOnUsdG9wU2VnbWVudHM6Zn0pPT57Y29uc3QgZD1vJiZXaShvKTtsZXQgcD1pLm1hcChnPT5QcihnLGQpKTt1JiYocD1WYShwLHUpKTtsZXQgeTtpZihuKXtjb25zdFtnLGJdPVByKFtbblswXSxuWzFdXSxbblsyXSxuWzNdXV0sbyE9bnVsbCYmby5yb3RhdGU/V2koR2UoRnQoe30sbykse3JvdGF0ZTp2b2lkIDB9KSk6ZCk7cyYmKGcueCs9c1swXSxnLnkrPXNbMV0sYi54Kz1zWzJdLGIueSs9c1szXSkseT1uZXcgZ3QobmV3IFQoZy54LGcueSwwKSxuZXcgVChiLngsYi55LDApKX1jb25zdCBtPXAubWFwKChnLGIpPT57dmFyIHc7cmV0dXJuIEQwKHtwb2ludHM6ZyxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxkZXB0aDoodz1yW2JdKSE9bnVsbD93OnJbMF0saGFzVG9wOmMsaGFzQm90dG9tOmwsaGFzU2lkZTpoLGJveDM6eSx0b3BTZWdtZW50czpmfSl9KTtyZXR1cm4gR2kobSxhKX07ZnVuY3Rpb24gcWEoaSx0LGUsbixzKXtsZXQgcjtpZihpPWkuc3ViYXJyYXl8fGkuc2xpY2U/aTppLmJ1ZmZlcixlPWUuc3ViYXJyYXl8fGUuc2xpY2U/ZTplLmJ1ZmZlcixpPXQ/aS5zdWJhcnJheT9pLnN1YmFycmF5KHQscyYmdCtzKTppLnNsaWNlKHQscyYmdCtzKTppLGUuc2V0KWUuc2V0KGksbik7ZWxzZSBmb3Iocj0wO3I8aS5sZW5ndGg7cisrKWVbcituXT1pW3JdO3JldHVybiBlfWZ1bmN0aW9uIG55KGkpe3JldHVybiBpIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5P2k6aSBpbnN0YW5jZW9mIHVlP2kuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLmFycmF5OmkubWFwKHQ9Pntjb25zdCBlPUFycmF5LmlzQXJyYXkodCk7cmV0dXJuIHQgaW5zdGFuY2VvZiBUP1t0LngsdC55LHQuel06dCBpbnN0YW5jZW9mIFI/W3QueCx0LnksMF06ZSYmdC5sZW5ndGg9PT0zP1t0WzBdLHRbMV0sdFsyXV06ZSYmdC5sZW5ndGg9PT0yP1t0WzBdLHRbMV0sMF06dH0pLmZsYXQoKX1jbGFzcyBpeSBleHRlbmRzIHVle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9Ik1lc2hMaW5lIix0aGlzLmlzTWVzaExpbmU9ITAsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdLHRoaXMuY291bnRlcnM9W10sdGhpcy53aWR0aENhbGxiYWNrPW51bGwsdGhpcy5fcG9pbnRzPVtdLHRoaXMubWF0cml4V29ybGQ9bmV3IHN0LE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMse3BvaW50czp7ZW51bWVyYWJsZTohMCxnZXQoKXtyZXR1cm4gdGhpcy5fcG9pbnRzfSxzZXQodCl7dGhpcy5zZXRQb2ludHModCx0aGlzLndpZHRoQ2FsbGJhY2spfX19KX1zZXRNYXRyaXhXb3JsZCh0KXt0aGlzLm1hdHJpeFdvcmxkPXR9c2V0UG9pbnRzKHQsZSl7aWYodD1ueSh0KSx0aGlzLl9wb2ludHM9dCx0aGlzLndpZHRoQ2FsbGJhY2s9ZSE9bnVsbD9lOm51bGwsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5jb3VudGVycz1bXSx0Lmxlbmd0aCYmdFswXWluc3RhbmNlb2YgVClmb3IobGV0IG49MDtuPHQubGVuZ3RoO24rKyl7Y29uc3Qgcz10W25dLHI9bi8odC5sZW5ndGgtMSk7dGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5jb3VudGVycy5wdXNoKHIpLHRoaXMuY291bnRlcnMucHVzaChyKX1lbHNlIGZvcihsZXQgbj0wO248dC5sZW5ndGg7bis9Myl7Y29uc3Qgcz1uLyh0Lmxlbmd0aC0xKTt0aGlzLnBvc2l0aW9ucy5wdXNoKHRbbl0sdFtuKzFdLHRbbisyXSksdGhpcy5wb3NpdGlvbnMucHVzaCh0W25dLHRbbisxXSx0W24rMl0pLHRoaXMuY291bnRlcnMucHVzaChzKSx0aGlzLmNvdW50ZXJzLnB1c2gocyl9dGhpcy5wcm9jZXNzKCl9Y29tcGFyZVYzKHQsZSl7Y29uc3Qgbj10KjYscz1lKjY7cmV0dXJuIHRoaXMucG9zaXRpb25zW25dPT09dGhpcy5wb3NpdGlvbnNbc10mJnRoaXMucG9zaXRpb25zW24rMV09PT10aGlzLnBvc2l0aW9uc1tzKzFdJiZ0aGlzLnBvc2l0aW9uc1tuKzJdPT09dGhpcy5wb3NpdGlvbnNbcysyXX1jb3B5VjModCl7Y29uc3QgZT10KjY7cmV0dXJuW3RoaXMucG9zaXRpb25zW2VdLHRoaXMucG9zaXRpb25zW2UrMV0sdGhpcy5wb3NpdGlvbnNbZSsyXV19cHJvY2Vzcygpe2NvbnN0IHQ9dGhpcy5wb3NpdGlvbnMubGVuZ3RoLzY7dGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdO2xldCBlLG47dGhpcy5jb21wYXJlVjMoMCx0LTEpP249dGhpcy5jb3B5VjModC0yKTpuPXRoaXMuY29weVYzKDApLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKTtmb3IobGV0IHM9MDtzPHQ7cysrKXtpZih0aGlzLnNpZGUucHVzaCgxKSx0aGlzLnNpZGUucHVzaCgtMSksdGhpcy53aWR0aENhbGxiYWNrP2U9dGhpcy53aWR0aENhbGxiYWNrKHMvKHQtMSkpOmU9MSx0aGlzLndpZHRoLnB1c2goZSksdGhpcy53aWR0aC5wdXNoKGUpLHRoaXMudXZzLnB1c2gocy8odC0xKSwwKSx0aGlzLnV2cy5wdXNoKHMvKHQtMSksMSksczx0LTEpe249dGhpcy5jb3B5VjMocyksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLnByZXZpb3VzLnB1c2goblswXSxuWzFdLG5bMl0pO2NvbnN0IHI9cyoyO3RoaXMuaW5kaWNlc19hcnJheS5wdXNoKHIscisxLHIrMiksdGhpcy5pbmRpY2VzX2FycmF5LnB1c2gocisyLHIrMSxyKzMpfXM+MCYmKG49dGhpcy5jb3B5VjMocyksdGhpcy5uZXh0LnB1c2goblswXSxuWzFdLG5bMl0pLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSl9dGhpcy5jb21wYXJlVjModC0xLDApP249dGhpcy5jb3B5VjMoMSk6bj10aGlzLmNvcHlWMyh0LTEpLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSksIXRoaXMuX2F0dHJpYnV0ZXN8fHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uY291bnQhPT10aGlzLmNvdW50ZXJzLmxlbmd0aD90aGlzLl9hdHRyaWJ1dGVzPXtwb3NpdGlvbjpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucyksMykscHJldmlvdXM6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wcmV2aW91cyksMyksbmV4dDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLm5leHQpLDMpLHNpZGU6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaWRlKSwxKSx3aWR0aDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSwxKSx1djpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnV2cyksMiksaW5kZXg6bmV3IHh0KG5ldyBVaW50MTZBcnJheSh0aGlzLmluZGljZXNfYXJyYXkpLDEpLGNvdW50ZXJzOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMuY291bnRlcnMpLDEpfToodGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucykpLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24ubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnByZXZpb3VzKSksdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLm5leHQuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5uZXh0KSksdGhpcy5fYXR0cmlidXRlcy5uZXh0Lm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMuc2lkZS5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnNpZGUpKSx0aGlzLl9hdHRyaWJ1dGVzLnNpZGUubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy53aWR0aC5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSksdGhpcy5fYXR0cmlidXRlcy53aWR0aC5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnV2LmNvcHlBcnJheShuZXcgRmxvYXQzMkFycmF5KHRoaXMudXZzKSksdGhpcy5fYXR0cmlidXRlcy51di5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLmluZGV4LmNvcHlBcnJheShuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzX2FycmF5KSksdGhpcy5fYXR0cmlidXRlcy5pbmRleC5uZWVkc1VwZGF0ZT0hMCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIix0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uKSx0aGlzLnNldEF0dHJpYnV0ZSgicHJldmlvdXMiLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMpLHRoaXMuc2V0QXR0cmlidXRlKCJuZXh0Iix0aGlzLl9hdHRyaWJ1dGVzLm5leHQpLHRoaXMuc2V0QXR0cmlidXRlKCJzaWRlIix0aGlzLl9hdHRyaWJ1dGVzLnNpZGUpLHRoaXMuc2V0QXR0cmlidXRlKCJ3aWR0aCIsdGhpcy5fYXR0cmlidXRlcy53aWR0aCksdGhpcy5zZXRBdHRyaWJ1dGUoInV2Iix0aGlzLl9hdHRyaWJ1dGVzLnV2KSx0aGlzLnNldEF0dHJpYnV0ZSgiY291bnRlcnMiLHRoaXMuX2F0dHJpYnV0ZXMuY291bnRlcnMpLHRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbiksdGhpcy5zZXRBdHRyaWJ1dGUoInByZXZpb3VzIix0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzKSx0aGlzLnNldEF0dHJpYnV0ZSgibmV4dCIsdGhpcy5fYXR0cmlidXRlcy5uZXh0KSx0aGlzLnNldEF0dHJpYnV0ZSgic2lkZSIsdGhpcy5fYXR0cmlidXRlcy5zaWRlKSx0aGlzLnNldEF0dHJpYnV0ZSgid2lkdGgiLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsdGhpcy5fYXR0cmlidXRlcy51diksdGhpcy5zZXRBdHRyaWJ1dGUoImNvdW50ZXJzIix0aGlzLl9hdHRyaWJ1dGVzLmNvdW50ZXJzKSx0aGlzLnNldEluZGV4KHRoaXMuX2F0dHJpYnV0ZXMuaW5kZXgpLHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCksdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKX1hZHZhbmNlKHt4OnQseTplLHo6bn0pe2NvbnN0IHM9dGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5hcnJheSxyPXRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMuYXJyYXksbz10aGlzLl9hdHRyaWJ1dGVzLm5leHQuYXJyYXksYT1zLmxlbmd0aDtxYShzLDAsciwwLGEpLHFhKHMsNixzLDAsYS02KSxzW2EtNl09dCxzW2EtNV09ZSxzW2EtNF09bixzW2EtM109dCxzW2EtMl09ZSxzW2EtMV09bixxYShzLDYsbywwLGEtNiksb1thLTZdPXQsb1thLTVdPWUsb1thLTRdPW4sb1thLTNdPXQsb1thLTJdPWUsb1thLTFdPW4sdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMubmV4dC5uZWVkc1VwZGF0ZT0hMH19dmFyIExoPWk9Pntjb25zdHtzZXRQb2ludFdpZHRoOnQsbm9kZXM6ZX09aSxuPW5ldyBpeTtyZXR1cm4gbi5zZXRQb2ludHMoZSx0KSxufTtjb25zdCBzeT0oe2Nvb3JkaW5hdGVzQXJyOmkscHJvamVjdGlvbjp0LGxpbmVXaWR0aDplLHVzZUdyb3VwczpuLHNwbGl0UG9seWdvbnM6c30pPT57Y29uc3Qgcj10JiZXaSh0KTtsZXQgbz1pLm1hcChjPT5QcihjLHIpKTtzJiYobz1WYShvLHMpKTtjb25zdCBhPW8ubWFwKChjLGwpPT57dmFyIHU7Y29uc3QgaD0odT1lW2xdKSE9bnVsbD91OmVbMF07cmV0dXJuIExoKHtub2RlczpjLHNldFBvaW50V2lkdGg6KCk9Pmh9KX0pO3JldHVybiBHaShhLG4pfTt2YXIgcnk9aT0+e2NvbnN0e3BvaW50czp0fT1pLGU9dC5yZWR1Y2UoKHMscixvKT0+KG88dC5sZW5ndGgtMSYmcy5wdXNoKHIsdFtvKzFdKSxzKSxbXSk7cmV0dXJuIG5ldyB1ZSgpLnNldEZyb21Qb2ludHMoZSl9O2NvbnN0IG95PSh7Y29vcmRpbmF0ZXNBcnI6aSxwcm9qZWN0aW9uOnQsbGluZVdpZHRoOmUsdXNlR3JvdXBzOm4sc3BsaXRQb2x5Z29uczpzfSk9Pntjb25zdCByPXQmJldpKHQpO2xldCBvPWkubWFwKGM9PlByKGMscikpO3MmJihvPVZhKG8scykpO2NvbnN0IGE9by5tYXAoKGMsbCk9PnJ5KHtwb2ludHM6Yy5tYXAoaD0+bmV3IFQoaC54LGgueSwwKSl9KSk7cmV0dXJuIEdpKGEsbil9O2Z1bmN0aW9uIGF5KGksdCxlPTIpe2NvbnN0IG49dCYmdC5sZW5ndGgscz1uP3RbMF0qZTppLmxlbmd0aDtsZXQgcj1PaChpLDAscyxlLCEwKTtjb25zdCBvPVtdO2lmKCFyfHxyLm5leHQ9PT1yLnByZXYpcmV0dXJuIG87bGV0IGEsYyxsO2lmKG4mJihyPWZ5KGksdCxyLGUpKSxpLmxlbmd0aD44MCplKXthPTEvMCxjPTEvMDtsZXQgaD0tMS8wLHU9LTEvMDtmb3IobGV0IGY9ZTtmPHM7Zis9ZSl7Y29uc3QgZD1pW2ZdLHA9aVtmKzFdO2Q8YSYmKGE9ZCkscDxjJiYoYz1wKSxkPmgmJihoPWQpLHA+dSYmKHU9cCl9bD1NYXRoLm1heChoLWEsdS1jKSxsPWwhPT0wPzMyNzY3L2w6MH1yZXR1cm4gWmkocixvLGUsYSxjLGwsMCksb31mdW5jdGlvbiBPaChpLHQsZSxuLHMpe2xldCByO2lmKHM9PT1feShpLHQsZSxuKT4wKWZvcihsZXQgbz10O288ZTtvKz1uKXI9VWgoby9ufDAsaVtvXSxpW28rMV0scik7ZWxzZSBmb3IobGV0IG89ZS1uO28+PXQ7by09bilyPVVoKG8vbnwwLGlbb10saVtvKzFdLHIpO3JldHVybiByJiZDcihyLHIubmV4dCkmJihKaShyKSxyPXIubmV4dCkscn1mdW5jdGlvbiBTbihpLHQpe2lmKCFpKXJldHVybiBpO3R8fCh0PWkpO2xldCBlPWksbjtkbyBpZihuPSExLCFlLnN0ZWluZXImJihDcihlLGUubmV4dCl8fGF0KGUucHJldixlLGUubmV4dCk9PT0wKSl7aWYoSmkoZSksZT10PWUucHJldixlPT09ZS5uZXh0KWJyZWFrO249ITB9ZWxzZSBlPWUubmV4dDt3aGlsZShufHxlIT09dCk7cmV0dXJuIHR9ZnVuY3Rpb24gWmkoaSx0LGUsbixzLHIsbyl7aWYoIWkpcmV0dXJuOyFvJiZyJiZneShpLG4scyxyKTtsZXQgYT1pO2Zvcig7aS5wcmV2IT09aS5uZXh0Oyl7Y29uc3QgYz1pLnByZXYsbD1pLm5leHQ7aWYocj9seShpLG4scyxyKTpjeShpKSl7dC5wdXNoKGMuaSxpLmksbC5pKSxKaShpKSxpPWwubmV4dCxhPWwubmV4dDtjb250aW51ZX1pZihpPWwsaT09PWEpe28/bz09PTE/KGk9aHkoU24oaSksdCksWmkoaSx0LGUsbixzLHIsMikpOm89PT0yJiZ1eShpLHQsZSxuLHMscik6WmkoU24oaSksdCxlLG4scyxyLDEpO2JyZWFrfX19ZnVuY3Rpb24gY3koaSl7Y29uc3QgdD1pLnByZXYsZT1pLG49aS5uZXh0O2lmKGF0KHQsZSxuKT49MClyZXR1cm4hMTtjb25zdCBzPXQueCxyPWUueCxvPW4ueCxhPXQueSxjPWUueSxsPW4ueSxoPXM8cj9zPG8/czpvOnI8bz9yOm8sdT1hPGM/YTxsP2E6bDpjPGw/YzpsLGY9cz5yP3M+bz9zOm86cj5vP3I6byxkPWE+Yz9hPmw/YTpsOmM+bD9jOmw7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJm9pKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZhdChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIGx5KGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihhdChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1hPGM/YTxsP2E6bDpjPGw/YzpsLHA9aDx1P2g8Zj9oOmY6dTxmP3U6Zix5PWE+Yz9hPmw/YTpsOmM+bD9jOmwsbT1oPnU/aD5mP2g6Zjp1PmY/dTpmLGc9SGEoZCxwLHQsZSxuKSxiPUhhKHksbSx0LGUsbik7bGV0IHc9aS5wcmV2Wix4PWkubmV4dFo7Zm9yKDt3JiZ3Lno+PWcmJngmJnguejw9Yjspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZvaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MHx8KHc9dy5wcmV2Wix4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmb2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApKXJldHVybiExO3g9eC5uZXh0Wn1mb3IoO3cmJncuej49Zzspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZvaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MClyZXR1cm4hMTt3PXcucHJldlp9Zm9yKDt4JiZ4Lno8PWI7KXtpZih4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmb2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApcmV0dXJuITE7eD14Lm5leHRafXJldHVybiEwfWZ1bmN0aW9uIGh5KGksdCl7bGV0IGU9aTtkb3tjb25zdCBuPWUucHJldixzPWUubmV4dC5uZXh0OyFDcihuLHMpJiZEaChuLGUsZS5uZXh0LHMpJiZYaShuLHMpJiZYaShzLG4pJiYodC5wdXNoKG4uaSxlLmkscy5pKSxKaShlKSxKaShlLm5leHQpLGU9aT1zKSxlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuIFNuKGUpfWZ1bmN0aW9uIHV5KGksdCxlLG4scyxyKXtsZXQgbz1pO2Rve2xldCBhPW8ubmV4dC5uZXh0O2Zvcig7YSE9PW8ucHJldjspe2lmKG8uaSE9PWEuaSYmYnkobyxhKSl7bGV0IGM9JGgobyxhKTtvPVNuKG8sby5uZXh0KSxjPVNuKGMsYy5uZXh0KSxaaShvLHQsZSxuLHMsciwwKSxaaShjLHQsZSxuLHMsciwwKTtyZXR1cm59YT1hLm5leHR9bz1vLm5leHR9d2hpbGUobyE9PWkpfWZ1bmN0aW9uIGZ5KGksdCxlLG4pe2NvbnN0IHM9W107Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXRbcl0qbixjPXI8by0xP3RbcisxXSpuOmkubGVuZ3RoLGw9T2goaSxhLGMsbiwhMSk7bD09PWwubmV4dCYmKGwuc3RlaW5lcj0hMCkscy5wdXNoKHd5KGwpKX1zLnNvcnQoZHkpO2ZvcihsZXQgcj0wO3I8cy5sZW5ndGg7cisrKWU9cHkoc1tyXSxlKTtyZXR1cm4gZX1mdW5jdGlvbiBkeShpLHQpe3JldHVybiBpLngtdC54fWZ1bmN0aW9uIHB5KGksdCl7Y29uc3QgZT15eShpLHQpO2lmKCFlKXJldHVybiB0O2NvbnN0IG49JGgoZSxpKTtyZXR1cm4gU24obixuLm5leHQpLFNuKGUsZS5uZXh0KX1mdW5jdGlvbiB5eShpLHQpe2xldCBlPXQ7Y29uc3Qgbj1pLngscz1pLnk7bGV0IHI9LTEvMCxvO2Rve2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZvaShzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTtYaShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmbXkobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIG15KGksdCl7cmV0dXJuIGF0KGkucHJldixpLHQucHJldik8MCYmYXQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIGd5KGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1IYShzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwseHkocyl9ZnVuY3Rpb24geHkoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBIYShpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24gd3koaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIG9pKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiBieShpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFNeShpLHQpJiYoWGkoaSx0KSYmWGkodCxpKSYmQXkoaSx0KSYmKGF0KGkucHJldixpLHQucHJldil8fGF0KGksdC5wcmV2LHQpKXx8Q3IoaSx0KSYmYXQoaS5wcmV2LGksaS5uZXh0KT4wJiZhdCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIGF0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24gQ3IoaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gRGgoaSx0LGUsbil7Y29uc3Qgcz1GcihhdChpLHQsZSkpLHI9RnIoYXQoaSx0LG4pKSxvPUZyKGF0KGUsbixpKSksYT1GcihhdChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJkJyKGksZSx0KXx8cj09PTAmJkJyKGksbix0KXx8bz09PTAmJkJyKGUsaSxuKXx8YT09PTAmJkJyKGUsdCxuKSl9ZnVuY3Rpb24gQnIoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIEZyKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBNeShpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmRGgoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gWGkoaSx0KXtyZXR1cm4gYXQoaS5wcmV2LGksaS5uZXh0KTwwP2F0KGksdCxpLm5leHQpPj0wJiZhdChpLGkucHJldix0KT49MDphdChpLHQsaS5wcmV2KTwwfHxhdChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIEF5KGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gJGgoaSx0KXtjb25zdCBlPVdhKGkuaSxpLngsaS55KSxuPVdhKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBVaChpLHQsZSxuKXtjb25zdCBzPVdhKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gSmkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBXYShpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gX3koaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWZ1bmN0aW9uIFZoKGkpe2NvbnN0IHQ9W10sZT1bXSxuPWlbMF1bMF0ubGVuZ3RoO2xldCBzPTAscj0wO2Zvcihjb25zdCBvIG9mIGkpe2Zvcihjb25zdCBhIG9mIG8pZm9yKGxldCBjPTA7YzxuO2MrKyl0LnB1c2goYVtjXSk7ciYmKHMrPXIsZS5wdXNoKHMpKSxyPW8ubGVuZ3RofXJldHVybnt2ZXJ0aWNlczp0LGhvbGVzOmUsZGltZW5zaW9uczpufX1mdW5jdGlvbiBTeShpKXtpZighaSl0aHJvdyBuZXcgRXJyb3IoImNvb3JkIGlzIHJlcXVpcmVkIik7aWYoIUFycmF5LmlzQXJyYXkoaSkpe2lmKGkudHlwZT09PSJGZWF0dXJlIiYmaS5nZW9tZXRyeSE9PW51bGwmJmkuZ2VvbWV0cnkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuZ2VvbWV0cnkuY29vcmRpbmF0ZXNdO2lmKGkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuY29vcmRpbmF0ZXNdfWlmKEFycmF5LmlzQXJyYXkoaSkmJmkubGVuZ3RoPj0yJiYhQXJyYXkuaXNBcnJheShpWzBdKSYmIUFycmF5LmlzQXJyYXkoaVsxXSkpcmV0dXJuWy4uLmldO3Rocm93IG5ldyBFcnJvcigiY29vcmQgbXVzdCBiZSBHZW9KU09OIFBvaW50IG9yIGFuIEFycmF5IG9mIG51bWJlcnMiKX1mdW5jdGlvbiB2eShpKXtpZihBcnJheS5pc0FycmF5KGkpKXJldHVybiBpO2lmKGkudHlwZT09PSJGZWF0dXJlIil7aWYoaS5nZW9tZXRyeSE9PW51bGwpcmV0dXJuIGkuZ2VvbWV0cnkuY29vcmRpbmF0ZXN9ZWxzZSBpZihpLmNvb3JkaW5hdGVzKXJldHVybiBpLmNvb3JkaW5hdGVzO3Rocm93IG5ldyBFcnJvcigiY29vcmRzIG11c3QgYmUgR2VvSlNPTiBGZWF0dXJlLCBHZW9tZXRyeSBPYmplY3Qgb3IgYW4gQXJyYXkiKX1mdW5jdGlvbiB6eShpKXtyZXR1cm4gaS50eXBlPT09IkZlYXR1cmUiP2kuZ2VvbWV0cnk6aX1mdW5jdGlvbiBUeShpKXtjb25zdCB0PXZ5KGkpO2xldCBlPTAsbj0xLHMscjtmb3IoO248dC5sZW5ndGg7KXM9cnx8dFswXSxyPXRbbl0sZSs9KHJbMF0tc1swXSkqKHJbMV0rc1sxXSksbisrO3JldHVybiBlPjB9dmFyIEV5PVR5O2NvbnN0IFZlPTExMTAyMjMwMjQ2MjUxNTY1ZS0zMix2dD0xMzQyMTc3MjksUHk9KDMrOCpWZSkqVmU7ZnVuY3Rpb24gR2EoaSx0LGUsbixzKXtsZXQgcixvLGEsYyxsPXRbMF0saD1uWzBdLHU9MCxmPTA7aD5sPT1oPi1sPyhyPWwsbD10WysrdV0pOihyPWgsaD1uWysrZl0pO2xldCBkPTA7aWYodTxpJiZmPGUpZm9yKGg+bD09aD4tbD8obz1sK3IsYT1yLShvLWwpLGw9dFsrK3VdKToobz1oK3IsYT1yLShvLWgpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7dTxpJiZmPGU7KWg+bD09aD4tbD8obz1yK2wsYz1vLXIsYT1yLShvLWMpKyhsLWMpLGw9dFsrK3VdKToobz1yK2gsYz1vLXIsYT1yLShvLWMpKyhoLWMpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDt1PGk7KW89citsLGM9by1yLGE9ci0oby1jKSsobC1jKSxsPXRbKyt1XSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDtmPGU7KW89citoLGM9by1yLGE9ci0oby1jKSsoaC1jKSxoPW5bKytmXSxyPW8sYSE9PTAmJihzW2QrK109YSk7cmV0dXJuKHIhPT0wfHxkPT09MCkmJihzW2QrK109ciksZH1mdW5jdGlvbiBDeShpLHQpe2xldCBlPXRbMF07Zm9yKGxldCBuPTE7bjxpO24rKyllKz10W25dO3JldHVybiBlfWZ1bmN0aW9uIFlpKGkpe3JldHVybiBuZXcgRmxvYXQ2NEFycmF5KGkpfWNvbnN0IEJ5PSgzKzE2KlZlKSpWZSxGeT0oMisxMipWZSkqVmUsSXk9KDkrNjQqVmUpKlZlKlZlLGFpPVlpKDQpLHFoPVlpKDgpLEhoPVlpKDEyKSxXaD1ZaSgxNiksQnQ9WWkoNCk7ZnVuY3Rpb24ga3koaSx0LGUsbixzLHIsbyl7bGV0IGEsYyxsLGgsdSxmLGQscCx5LG0sZyxiLHcseCxNLEEsXyxTO2NvbnN0IEU9aS1zLHo9ZS1zLHY9dC1yLEM9bi1yO3g9RSpDLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpDLHk9Zi0oZi1DKSxtPUMteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KnosZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KnoseT1mLShmLXopLG09ei15LF89cCptLShBLWQqeS1wKnktZCptKSxnPU0tXyx1PU0tZyxhaVswXT1NLShnK3UpKyh1LV8pLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxhaVsxXT13LShnK3UpKyh1LUEpLFM9YitnLHU9Uy1iLGFpWzJdPWItKFMtdSkrKGctdSksYWlbM109UztsZXQgUD1DeSg0LGFpKSxGPUZ5Km87aWYoUD49Rnx8LVA+PUZ8fCh1PWktRSxhPWktKEUrdSkrKHUtcyksdT1lLXosbD1lLSh6K3UpKyh1LXMpLHU9dC12LGM9dC0odit1KSsodS1yKSx1PW4tQyxoPW4tKEMrdSkrKHUtciksYT09PTAmJmM9PT0wJiZsPT09MCYmaD09PTApfHwoRj1JeSpvK1B5Kk1hdGguYWJzKFApLFArPUUqaCtDKmEtKHYqbCt6KmMpLFA+PUZ8fC1QPj1GKSlyZXR1cm4gUDt4PWEqQyxmPXZ0KmEsZD1mLShmLWEpLHA9YS1kLGY9dnQqQyx5PWYtKGYtQyksbT1DLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9Yyp6LGY9dnQqYyxkPWYtKGYtYykscD1jLWQsZj12dCp6LHk9Zi0oZi16KSxtPXoteSxfPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLV8sdT1NLWcsQnRbMF09TS0oZyt1KSsodS1fKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsQnRbMV09dy0oZyt1KSsodS1BKSxTPWIrZyx1PVMtYixCdFsyXT1iLShTLXUpKyhnLXUpLEJ0WzNdPVM7Y29uc3QgQj1HYSg0LGFpLDQsQnQscWgpO3g9RSpoLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpoLHk9Zi0oZi1oKSxtPWgteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KmwsZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KmwseT1mLShmLWwpLG09bC15LF89cCptLShBLWQqeS1wKnktZCptKSxnPU0tXyx1PU0tZyxCdFswXT1NLShnK3UpKyh1LV8pLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxCdFsxXT13LShnK3UpKyh1LUEpLFM9YitnLHU9Uy1iLEJ0WzJdPWItKFMtdSkrKGctdSksQnRbM109Uztjb25zdCBJPUdhKEIscWgsNCxCdCxIaCk7eD1hKmgsZj12dCphLGQ9Zi0oZi1hKSxwPWEtZCxmPXZ0KmgseT1mLShmLWgpLG09aC15LE09cCptLSh4LWQqeS1wKnktZCptKSxBPWMqbCxmPXZ0KmMsZD1mLShmLWMpLHA9Yy1kLGY9dnQqbCx5PWYtKGYtbCksbT1sLXksXz1wKm0tKEEtZCp5LXAqeS1kKm0pLGc9TS1fLHU9TS1nLEJ0WzBdPU0tKGcrdSkrKHUtXyksYj14K2csdT1iLXgsdz14LShiLXUpKyhnLXUpLGc9dy1BLHU9dy1nLEJ0WzFdPXctKGcrdSkrKHUtQSksUz1iK2csdT1TLWIsQnRbMl09Yi0oUy11KSsoZy11KSxCdFszXT1TO2NvbnN0IGs9R2EoSSxIaCw0LEJ0LFdoKTtyZXR1cm4gV2hbay0xXX1mdW5jdGlvbiBJcihpLHQsZSxuLHMscil7Y29uc3Qgbz0odC1yKSooZS1zKSxhPShpLXMpKihuLXIpLGM9by1hO2lmKG89PT0wfHxhPT09MHx8bz4wIT1hPjApcmV0dXJuIGM7Y29uc3QgbD1NYXRoLmFicyhvK2EpO3JldHVybiBNYXRoLmFicyhjKT49QnkqbD9jOi1reShpLHQsZSxuLHMscixsKX1jb25zdCBHaD1NYXRoLnBvdygyLC01Miksa3I9bmV3IFVpbnQzMkFycmF5KDUxMik7Y2xhc3Mgaml7c3RhdGljIGZyb20odCxlPUR5LG49JHkpe2NvbnN0IHM9dC5sZW5ndGgscj1uZXcgRmxvYXQ2NEFycmF5KHMqMik7Zm9yKGxldCBvPTA7bzxzO28rKyl7Y29uc3QgYT10W29dO3JbMipvXT1lKGEpLHJbMipvKzFdPW4oYSl9cmV0dXJuIG5ldyBqaShyKX1jb25zdHJ1Y3Rvcih0KXtjb25zdCBlPXQubGVuZ3RoPj4xO2lmKGU+MCYmdHlwZW9mIHRbMF0hPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcigiRXhwZWN0ZWQgY29vcmRzIHRvIGNvbnRhaW4gbnVtYmVycy4iKTt0aGlzLmNvb3Jkcz10O2NvbnN0IG49TWF0aC5tYXgoMiplLTUsMCk7dGhpcy5fdHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheShuKjMpLHRoaXMuX2hhbGZlZGdlcz1uZXcgSW50MzJBcnJheShuKjMpLHRoaXMuX2hhc2hTaXplPU1hdGguY2VpbChNYXRoLnNxcnQoZSkpLHRoaXMuX2h1bGxQcmV2PW5ldyBVaW50MzJBcnJheShlKSx0aGlzLl9odWxsTmV4dD1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbFRyaT1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbEhhc2g9bmV3IEludDMyQXJyYXkodGhpcy5faGFzaFNpemUpLmZpbGwoLTEpLHRoaXMuX2lkcz1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5fZGlzdHM9bmV3IEZsb2F0NjRBcnJheShlKSx0aGlzLnVwZGF0ZSgpfXVwZGF0ZSgpe2NvbnN0e2Nvb3Jkczp0LF9odWxsUHJldjplLF9odWxsTmV4dDpuLF9odWxsVHJpOnMsX2h1bGxIYXNoOnJ9PXRoaXMsbz10Lmxlbmd0aD4+MTtsZXQgYT0xLzAsYz0xLzAsbD0tMS8wLGg9LTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtjb25zdCB2PXRbMip6XSxDPXRbMip6KzFdO3Y8YSYmKGE9diksQzxjJiYoYz1DKSx2PmwmJihsPXYpLEM+aCYmKGg9QyksdGhpcy5faWRzW3pdPXp9Y29uc3QgdT0oYStsKS8yLGY9KGMraCkvMjtsZXQgZD0xLzAscCx5LG07Zm9yKGxldCB6PTA7ejxvO3orKyl7Y29uc3Qgdj1aYSh1LGYsdFsyKnpdLHRbMip6KzFdKTt2PGQmJihwPXosZD12KX1jb25zdCBnPXRbMipwXSxiPXRbMipwKzFdO2Q9MS8wO2ZvcihsZXQgej0wO3o8bzt6Kyspe2lmKHo9PT1wKWNvbnRpbnVlO2NvbnN0IHY9WmEoZyxiLHRbMip6XSx0WzIqeisxXSk7djxkJiZ2PjAmJih5PXosZD12KX1sZXQgdz10WzIqeV0seD10WzIqeSsxXSxNPTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtpZih6PT09cHx8ej09PXkpY29udGludWU7Y29uc3Qgdj1MeShnLGIsdyx4LHRbMip6XSx0WzIqeisxXSk7djxNJiYobT16LE09dil9bGV0IEE9dFsyKm1dLF89dFsyKm0rMV07aWYoTT09PTEvMCl7Zm9yKGxldCBDPTA7QzxvO0MrKyl0aGlzLl9kaXN0c1tDXT10WzIqQ10tdFswXXx8dFsyKkMrMV0tdFsxXTtjaSh0aGlzLl9pZHMsdGhpcy5fZGlzdHMsMCxvLTEpO2NvbnN0IHo9bmV3IFVpbnQzMkFycmF5KG8pO2xldCB2PTA7Zm9yKGxldCBDPTAsUD0tMS8wO0M8bztDKyspe2NvbnN0IEY9dGhpcy5faWRzW0NdO3RoaXMuX2Rpc3RzW0ZdPlAmJih6W3YrK109RixQPXRoaXMuX2Rpc3RzW0ZdKX10aGlzLmh1bGw9ei5zdWJhcnJheSgwLHYpLHRoaXMudHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheSgwKSx0aGlzLmhhbGZlZGdlcz1uZXcgVWludDMyQXJyYXkoMCk7cmV0dXJufWlmKElyKGcsYix3LHgsQSxfKTwwKXtjb25zdCB6PXksdj13LEM9eDt5PW0sdz1BLHg9XyxtPXosQT12LF89Q31jb25zdCBTPU95KGcsYix3LHgsQSxfKTt0aGlzLl9jeD1TLngsdGhpcy5fY3k9Uy55O2ZvcihsZXQgej0wO3o8bzt6KyspdGhpcy5fZGlzdHNbel09WmEodFsyKnpdLHRbMip6KzFdLFMueCxTLnkpO2NpKHRoaXMuX2lkcyx0aGlzLl9kaXN0cywwLG8tMSksdGhpcy5faHVsbFN0YXJ0PXA7bGV0IEU9MztuW3BdPWVbbV09eSxuW3ldPWVbcF09bSxuW21dPWVbeV09cCxzW3BdPTAsc1t5XT0xLHNbbV09MixyLmZpbGwoLTEpLHJbdGhpcy5faGFzaEtleShnLGIpXT1wLHJbdGhpcy5faGFzaEtleSh3LHgpXT15LHJbdGhpcy5faGFzaEtleShBLF8pXT1tLHRoaXMudHJpYW5nbGVzTGVuPTAsdGhpcy5fYWRkVHJpYW5nbGUocCx5LG0sLTEsLTEsLTEpO2ZvcihsZXQgej0wLHYsQzt6PHRoaXMuX2lkcy5sZW5ndGg7eisrKXtjb25zdCBQPXRoaXMuX2lkc1t6XSxGPXRbMipQXSxCPXRbMipQKzFdO2lmKHo+MCYmTWF0aC5hYnMoRi12KTw9R2gmJk1hdGguYWJzKEItQyk8PUdofHwodj1GLEM9QixQPT09cHx8UD09PXl8fFA9PT1tKSljb250aW51ZTtsZXQgST0wO2ZvcihsZXQgZHQ9MCxEdD10aGlzLl9oYXNoS2V5KEYsQik7ZHQ8dGhpcy5faGFzaFNpemUmJihJPXJbKER0K2R0KSV0aGlzLl9oYXNoU2l6ZV0sIShJIT09LTEmJkkhPT1uW0ldKSk7ZHQrKyk7ST1lW0ldO2xldCBrPUksRDtmb3IoO0Q9bltrXSxJcihGLEIsdFsyKmtdLHRbMiprKzFdLHRbMipEXSx0WzIqRCsxXSk+PTA7KWlmKGs9RCxrPT09SSl7az0tMTticmVha31pZihrPT09LTEpY29udGludWU7bGV0IFY9dGhpcy5fYWRkVHJpYW5nbGUoayxQLG5ba10sLTEsLTEsc1trXSk7c1tQXT10aGlzLl9sZWdhbGl6ZShWKzIpLHNba109VixFKys7bGV0IGo9bltrXTtmb3IoO0Q9bltqXSxJcihGLEIsdFsyKmpdLHRbMipqKzFdLHRbMipEXSx0WzIqRCsxXSk8MDspVj10aGlzLl9hZGRUcmlhbmdsZShqLFAsRCxzW1BdLC0xLHNbal0pLHNbUF09dGhpcy5fbGVnYWxpemUoVisyKSxuW2pdPWosRS0tLGo9RDtpZihrPT09SSlmb3IoO0Q9ZVtrXSxJcihGLEIsdFsyKkRdLHRbMipEKzFdLHRbMiprXSx0WzIqaysxXSk8MDspVj10aGlzLl9hZGRUcmlhbmdsZShELFAsaywtMSxzW2tdLHNbRF0pLHRoaXMuX2xlZ2FsaXplKFYrMiksc1tEXT1WLG5ba109ayxFLS0saz1EO3RoaXMuX2h1bGxTdGFydD1lW1BdPWssbltrXT1lW2pdPVAsbltQXT1qLHJbdGhpcy5faGFzaEtleShGLEIpXT1QLHJbdGhpcy5faGFzaEtleSh0WzIqa10sdFsyKmsrMV0pXT1rfXRoaXMuaHVsbD1uZXcgVWludDMyQXJyYXkoRSk7Zm9yKGxldCB6PTAsdj10aGlzLl9odWxsU3RhcnQ7ejxFO3orKyl0aGlzLmh1bGxbel09dix2PW5bdl07dGhpcy50cmlhbmdsZXM9dGhpcy5fdHJpYW5nbGVzLnN1YmFycmF5KDAsdGhpcy50cmlhbmdsZXNMZW4pLHRoaXMuaGFsZmVkZ2VzPXRoaXMuX2hhbGZlZGdlcy5zdWJhcnJheSgwLHRoaXMudHJpYW5nbGVzTGVuKX1faGFzaEtleSh0LGUpe3JldHVybiBNYXRoLmZsb29yKE55KHQtdGhpcy5fY3gsZS10aGlzLl9jeSkqdGhpcy5faGFzaFNpemUpJXRoaXMuX2hhc2hTaXplfV9sZWdhbGl6ZSh0KXtjb25zdHtfdHJpYW5nbGVzOmUsX2hhbGZlZGdlczpuLGNvb3JkczpzfT10aGlzO2xldCByPTAsbz0wO2Zvcig7Oyl7Y29uc3QgYT1uW3RdLGM9dC10JTM7aWYobz1jKyh0KzIpJTMsYT09PS0xKXtpZihyPT09MClicmVhazt0PWtyWy0tcl07Y29udGludWV9Y29uc3QgbD1hLWElMyxoPWMrKHQrMSklMyx1PWwrKGErMiklMyxmPWVbb10sZD1lW3RdLHA9ZVtoXSx5PWVbdV07aWYoUnkoc1syKmZdLHNbMipmKzFdLHNbMipkXSxzWzIqZCsxXSxzWzIqcF0sc1syKnArMV0sc1syKnldLHNbMip5KzFdKSl7ZVt0XT15LGVbYV09Zjtjb25zdCBnPW5bdV07aWYoZz09PS0xKXtsZXQgdz10aGlzLl9odWxsU3RhcnQ7ZG97aWYodGhpcy5faHVsbFRyaVt3XT09PXUpe3RoaXMuX2h1bGxUcmlbd109dDticmVha313PXRoaXMuX2h1bGxQcmV2W3ddfXdoaWxlKHchPT10aGlzLl9odWxsU3RhcnQpfXRoaXMuX2xpbmsodCxnKSx0aGlzLl9saW5rKGEsbltvXSksdGhpcy5fbGluayhvLHUpO2NvbnN0IGI9bCsoYSsxKSUzO3I8a3IubGVuZ3RoJiYoa3JbcisrXT1iKX1lbHNle2lmKHI9PT0wKWJyZWFrO3Q9a3JbLS1yXX19cmV0dXJuIG99X2xpbmsodCxlKXt0aGlzLl9oYWxmZWRnZXNbdF09ZSxlIT09LTEmJih0aGlzLl9oYWxmZWRnZXNbZV09dCl9X2FkZFRyaWFuZ2xlKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMudHJpYW5nbGVzTGVuO3JldHVybiB0aGlzLl90cmlhbmdsZXNbYV09dCx0aGlzLl90cmlhbmdsZXNbYSsxXT1lLHRoaXMuX3RyaWFuZ2xlc1thKzJdPW4sdGhpcy5fbGluayhhLHMpLHRoaXMuX2xpbmsoYSsxLHIpLHRoaXMuX2xpbmsoYSsyLG8pLHRoaXMudHJpYW5nbGVzTGVuKz0zLGF9fWZ1bmN0aW9uIE55KGksdCl7Y29uc3QgZT1pLyhNYXRoLmFicyhpKStNYXRoLmFicyh0KSk7cmV0dXJuKHQ+MD8zLWU6MStlKS80fWZ1bmN0aW9uIFphKGksdCxlLG4pe2NvbnN0IHM9aS1lLHI9dC1uO3JldHVybiBzKnMrcipyfWZ1bmN0aW9uIFJ5KGksdCxlLG4scyxyLG8sYSl7Y29uc3QgYz1pLW8sbD10LWEsaD1lLW8sdT1uLWEsZj1zLW8sZD1yLWEscD1jKmMrbCpsLHk9aCpoK3UqdSxtPWYqZitkKmQ7cmV0dXJuIGMqKHUqbS15KmQpLWwqKGgqbS15KmYpK3AqKGgqZC11KmYpPDB9ZnVuY3Rpb24gTHkoaSx0LGUsbixzLHIpe2NvbnN0IG89ZS1pLGE9bi10LGM9cy1pLGw9ci10LGg9bypvK2EqYSx1PWMqYytsKmwsZj0uNS8obypsLWEqYyksZD0obCpoLWEqdSkqZixwPShvKnUtYypoKSpmO3JldHVybiBkKmQrcCpwfWZ1bmN0aW9uIE95KGksdCxlLG4scyxyKXtjb25zdCBvPWUtaSxhPW4tdCxjPXMtaSxsPXItdCxoPW8qbythKmEsdT1jKmMrbCpsLGY9LjUvKG8qbC1hKmMpLGQ9aSsobCpoLWEqdSkqZixwPXQrKG8qdS1jKmgpKmY7cmV0dXJue3g6ZCx5OnB9fWZ1bmN0aW9uIGNpKGksdCxlLG4pe2lmKG4tZTw9MjApZm9yKGxldCBzPWUrMTtzPD1uO3MrKyl7Y29uc3Qgcj1pW3NdLG89dFtyXTtsZXQgYT1zLTE7Zm9yKDthPj1lJiZ0W2lbYV1dPm87KWlbYSsxXT1pW2EtLV07aVthKzFdPXJ9ZWxzZXtjb25zdCBzPWUrbj4+MTtsZXQgcj1lKzEsbz1uO1FpKGkscyxyKSx0W2lbZV1dPnRbaVtuXV0mJlFpKGksZSxuKSx0W2lbcl1dPnRbaVtuXV0mJlFpKGkscixuKSx0W2lbZV1dPnRbaVtyXV0mJlFpKGksZSxyKTtjb25zdCBhPWlbcl0sYz10W2FdO2Zvcig7Oyl7ZG8gcisrO3doaWxlKHRbaVtyXV08Yyk7ZG8gby0tO3doaWxlKHRbaVtvXV0+Yyk7aWYobzxyKWJyZWFrO1FpKGkscixvKX1pW2UrMV09aVtvXSxpW29dPWEsbi1yKzE+PW8tZT8oY2koaSx0LHIsbiksY2koaSx0LGUsby0xKSk6KGNpKGksdCxlLG8tMSksY2koaSx0LHIsbikpfX1mdW5jdGlvbiBRaShpLHQsZSl7Y29uc3Qgbj1pW3RdO2lbdF09aVtlXSxpW2VdPW59ZnVuY3Rpb24gRHkoaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gJHkoaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gVXkoaSx0KXt2YXIgZT0wLG49MCxzPTAscj0wLG89MCxhPTAsYz0wLGw9MCxoPW51bGwsdT1udWxsLGY9aVswXSxkPWlbMV0scD10Lmxlbmd0aDtmb3IoZTtlPHA7ZSsrKXtuPTA7dmFyIHk9dFtlXS5sZW5ndGgtMSxtPXRbZV07aWYoaD1tWzBdLGhbMF0hPT1tW3ldWzBdJiZoWzFdIT09bVt5XVsxXSl0aHJvdyBuZXcgRXJyb3IoIkZpcnN0IGFuZCBsYXN0IGNvb3JkaW5hdGVzIGluIGEgcmluZyBtdXN0IGJlIHRoZSBzYW1lIik7Zm9yKG89aFswXS1mLGE9aFsxXS1kLG47bjx5O24rKyl7aWYodT1tW24rMV0sbD11WzFdLWQsYTwwJiZsPDB8fGE+MCYmbD4wKXtoPXUsYT1sLG89aFswXS1mO2NvbnRpbnVlfWlmKGM9dVswXS1pWzBdLGw+MCYmYTw9MCl7aWYocj1vKmwtYyphLHI+MClzPXMrMTtlbHNlIGlmKHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT4wJiZsPD0wKXtpZihyPW8qbC1jKmEscjwwKXM9cysxO2Vsc2UgaWYocj09PTApcmV0dXJuIDB9ZWxzZSBpZihsPT09MCYmYTwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbDwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbD09PTApe2lmKGM8PTAmJm8+PTApcmV0dXJuIDA7aWYobzw9MCYmYz49MClyZXR1cm4gMH1oPXUsYT1sLG89Y319cmV0dXJuIHMlMiE9PTB9ZnVuY3Rpb24gVnkoaSx0LGU9e30pe2lmKCFpKXRocm93IG5ldyBFcnJvcigicG9pbnQgaXMgcmVxdWlyZWQiKTtpZighdCl0aHJvdyBuZXcgRXJyb3IoInBvbHlnb24gaXMgcmVxdWlyZWQiKTtjb25zdCBuPVN5KGkpLHM9enkodCkscj1zLnR5cGUsbz10LmJib3g7bGV0IGE9cy5jb29yZGluYXRlcztpZihvJiZxeShuLG8pPT09ITEpcmV0dXJuITE7cj09PSJQb2x5Z29uIiYmKGE9W2FdKTtsZXQgYz0hMTtmb3IodmFyIGw9MDtsPGEubGVuZ3RoOysrbCl7Y29uc3QgaD1VeShuLGFbbF0pO2lmKGg9PT0wKXJldHVybiFlLmlnbm9yZUJvdW5kYXJ5O2gmJihjPSEwKX1yZXR1cm4gY31mdW5jdGlvbiBxeShpLHQpe3JldHVybiB0WzBdPD1pWzBdJiZ0WzFdPD1pWzFdJiZ0WzJdPj1pWzBdJiZ0WzNdPj1pWzFdfXZhciBIeT1WeTtjb25zdCBaaD0xZS02O2NsYXNzIHZue2NvbnN0cnVjdG9yKCl7dGhpcy5feDA9dGhpcy5feTA9dGhpcy5feDE9dGhpcy5feTE9bnVsbCx0aGlzLl89IiJ9bW92ZVRvKHQsZSl7dGhpcy5fKz1gTSR7dGhpcy5feDA9dGhpcy5feDE9K3R9LCR7dGhpcy5feTA9dGhpcy5feTE9K2V9YH1jbG9zZVBhdGgoKXt0aGlzLl94MSE9PW51bGwmJih0aGlzLl94MT10aGlzLl94MCx0aGlzLl95MT10aGlzLl95MCx0aGlzLl8rPSJaIil9bGluZVRvKHQsZSl7dGhpcy5fKz1gTCR7dGhpcy5feDE9K3R9LCR7dGhpcy5feTE9K2V9YH1hcmModCxlLG4pe3Q9K3QsZT0rZSxuPStuO2NvbnN0IHM9dCtuLHI9ZTtpZihuPDApdGhyb3cgbmV3IEVycm9yKCJuZWdhdGl2ZSByYWRpdXMiKTt0aGlzLl94MT09PW51bGw/dGhpcy5fKz1gTSR7c30sJHtyfWA6KE1hdGguYWJzKHRoaXMuX3gxLXMpPlpofHxNYXRoLmFicyh0aGlzLl95MS1yKT5aaCkmJih0aGlzLl8rPSJMIitzKyIsIityKSxuJiYodGhpcy5fKz1gQSR7bn0sJHtufSwwLDEsMSwke3Qtbn0sJHtlfUEke259LCR7bn0sMCwxLDEsJHt0aGlzLl94MT1zfSwke3RoaXMuX3kxPXJ9YCl9cmVjdCh0LGUsbixzKXt0aGlzLl8rPWBNJHt0aGlzLl94MD10aGlzLl94MT0rdH0sJHt0aGlzLl95MD10aGlzLl95MT0rZX1oJHsrbn12JHsrc31oJHstbn1aYH12YWx1ZSgpe3JldHVybiB0aGlzLl98fG51bGx9fWNsYXNzIFhhe2NvbnN0cnVjdG9yKCl7dGhpcy5fPVtdfW1vdmVUbyh0LGUpe3RoaXMuXy5wdXNoKFt0LGVdKX1jbG9zZVBhdGgoKXt0aGlzLl8ucHVzaCh0aGlzLl9bMF0uc2xpY2UoKSl9bGluZVRvKHQsZSl7dGhpcy5fLnB1c2goW3QsZV0pfXZhbHVlKCl7cmV0dXJuIHRoaXMuXy5sZW5ndGg/dGhpcy5fOm51bGx9fWNsYXNzIFd5e2NvbnN0cnVjdG9yKHQsW2UsbixzLHJdPVswLDAsOTYwLDUwMF0pe2lmKCEoKHM9K3MpPj0oZT0rZSkpfHwhKChyPStyKT49KG49K24pKSl0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgYm91bmRzIik7dGhpcy5kZWxhdW5heT10LHRoaXMuX2NpcmN1bWNlbnRlcnM9bmV3IEZsb2F0NjRBcnJheSh0LnBvaW50cy5sZW5ndGgqMiksdGhpcy52ZWN0b3JzPW5ldyBGbG9hdDY0QXJyYXkodC5wb2ludHMubGVuZ3RoKjIpLHRoaXMueG1heD1zLHRoaXMueG1pbj1lLHRoaXMueW1heD1yLHRoaXMueW1pbj1uLHRoaXMuX2luaXQoKX11cGRhdGUoKXtyZXR1cm4gdGhpcy5kZWxhdW5heS51cGRhdGUoKSx0aGlzLl9pbml0KCksdGhpc31faW5pdCgpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dCxodWxsOmUsdHJpYW5nbGVzOm59LHZlY3RvcnM6c309dGhpcyxyPXRoaXMuY2lyY3VtY2VudGVycz10aGlzLl9jaXJjdW1jZW50ZXJzLnN1YmFycmF5KDAsbi5sZW5ndGgvMyoyKTtmb3IobGV0IGQ9MCxwPTAseT1uLmxlbmd0aCxtLGc7ZDx5O2QrPTMscCs9Mil7Y29uc3QgYj1uW2RdKjIsdz1uW2QrMV0qMix4PW5bZCsyXSoyLE09dFtiXSxBPXRbYisxXSxfPXRbd10sUz10W3crMV0sRT10W3hdLHo9dFt4KzFdLHY9Xy1NLEM9Uy1BLFA9RS1NLEY9ei1BLEI9KHYqRi1DKlApKjI7aWYoTWF0aC5hYnMoQik8MWUtOSl7bGV0IEk9MWU5O2NvbnN0IGs9blswXSoyO0kqPU1hdGguc2lnbigodFtrXS1NKSpGLSh0W2srMV0tQSkqUCksbT0oTStFKS8yLUkqRixnPShBK3opLzIrSSpQfWVsc2V7Y29uc3QgST0xL0Isaz12KnYrQypDLEQ9UCpQK0YqRjttPU0rKEYqay1DKkQpKkksZz1BKyh2KkQtUCprKSpJfXJbcF09bSxyW3ArMV09Z31sZXQgbz1lW2UubGVuZ3RoLTFdLGEsYz1vKjQsbCxoPXRbMipvXSx1LGY9dFsyKm8rMV07cy5maWxsKDApO2ZvcihsZXQgZD0wO2Q8ZS5sZW5ndGg7KytkKW89ZVtkXSxhPWMsbD1oLHU9ZixjPW8qNCxoPXRbMipvXSxmPXRbMipvKzFdLHNbYSsyXT1zW2NdPXUtZixzW2ErM109c1tjKzFdPWgtbH1yZW5kZXIodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHZuOnZvaWQgMCx7ZGVsYXVuYXk6e2hhbGZlZGdlczpuLGluZWRnZXM6cyxodWxsOnJ9LGNpcmN1bWNlbnRlcnM6byx2ZWN0b3JzOmF9PXRoaXM7aWYoci5sZW5ndGg8PTEpcmV0dXJuIG51bGw7Zm9yKGxldCBoPTAsdT1uLmxlbmd0aDtoPHU7KytoKXtjb25zdCBmPW5baF07aWYoZjxoKWNvbnRpbnVlO2NvbnN0IGQ9TWF0aC5mbG9vcihoLzMpKjIscD1NYXRoLmZsb29yKGYvMykqMix5PW9bZF0sbT1vW2QrMV0sZz1vW3BdLGI9b1twKzFdO3RoaXMuX3JlbmRlclNlZ21lbnQoeSxtLGcsYix0KX1sZXQgYyxsPXJbci5sZW5ndGgtMV07Zm9yKGxldCBoPTA7aDxyLmxlbmd0aDsrK2gpe2M9bCxsPXJbaF07Y29uc3QgdT1NYXRoLmZsb29yKHNbbF0vMykqMixmPW9bdV0sZD1vW3UrMV0scD1jKjQseT10aGlzLl9wcm9qZWN0KGYsZCxhW3ArMl0sYVtwKzNdKTt5JiZ0aGlzLl9yZW5kZXJTZWdtZW50KGYsZCx5WzBdLHlbMV0sdCl9cmV0dXJuIGUmJmUudmFsdWUoKX1yZW5kZXJCb3VuZHModCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHZuOnZvaWQgMDtyZXR1cm4gdC5yZWN0KHRoaXMueG1pbix0aGlzLnltaW4sdGhpcy54bWF4LXRoaXMueG1pbix0aGlzLnltYXgtdGhpcy55bWluKSxlJiZlLnZhbHVlKCl9cmVuZGVyQ2VsbCh0LGUpe2NvbnN0IG49ZT09bnVsbD9lPW5ldyB2bjp2b2lkIDAscz10aGlzLl9jbGlwKHQpO2lmKHM9PT1udWxsfHwhcy5sZW5ndGgpcmV0dXJuO2UubW92ZVRvKHNbMF0sc1sxXSk7bGV0IHI9cy5sZW5ndGg7Zm9yKDtzWzBdPT09c1tyLTJdJiZzWzFdPT09c1tyLTFdJiZyPjE7KXItPTI7Zm9yKGxldCBvPTI7bzxyO28rPTIpKHNbb10hPT1zW28tMl18fHNbbysxXSE9PXNbby0xXSkmJmUubGluZVRvKHNbb10sc1tvKzFdKTtyZXR1cm4gZS5jbG9zZVBhdGgoKSxuJiZuLnZhbHVlKCl9KmNlbGxQb2x5Z29ucygpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dH19PXRoaXM7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aC8yO2U8bjsrK2Upe2NvbnN0IHM9dGhpcy5jZWxsUG9seWdvbihlKTtzJiYocy5pbmRleD1lLHlpZWxkIHMpfX1jZWxsUG9seWdvbih0KXtjb25zdCBlPW5ldyBYYTtyZXR1cm4gdGhpcy5yZW5kZXJDZWxsKHQsZSksZS52YWx1ZSgpfV9yZW5kZXJTZWdtZW50KHQsZSxuLHMscil7bGV0IG87Y29uc3QgYT10aGlzLl9yZWdpb25jb2RlKHQsZSksYz10aGlzLl9yZWdpb25jb2RlKG4scyk7YT09PTAmJmM9PT0wPyhyLm1vdmVUbyh0LGUpLHIubGluZVRvKG4scykpOihvPXRoaXMuX2NsaXBTZWdtZW50KHQsZSxuLHMsYSxjKSkmJihyLm1vdmVUbyhvWzBdLG9bMV0pLHIubGluZVRvKG9bMl0sb1szXSkpfWNvbnRhaW5zKHQsZSxuKXtyZXR1cm4gZT0rZSxlIT09ZXx8KG49K24sbiE9PW4pPyExOnRoaXMuZGVsYXVuYXkuX3N0ZXAodCxlLG4pPT09dH0qbmVpZ2hib3JzKHQpe2NvbnN0IGU9dGhpcy5fY2xpcCh0KTtpZihlKWZvcihjb25zdCBuIG9mIHRoaXMuZGVsYXVuYXkubmVpZ2hib3JzKHQpKXtjb25zdCBzPXRoaXMuX2NsaXAobik7aWYocyl7dDpmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKz0yKWZvcihsZXQgYT0wLGM9cy5sZW5ndGg7YTxjO2ErPTIpaWYoZVtyXT09c1thXSYmZVtyKzFdPT1zW2ErMV0mJmVbKHIrMiklb109PXNbKGErYy0yKSVjXSYmZVsociszKSVvXT09c1soYStjLTEpJWNdKXt5aWVsZCBuO2JyZWFrIHR9fX19X2NlbGwodCl7Y29uc3R7Y2lyY3VtY2VudGVyczplLGRlbGF1bmF5OntpbmVkZ2VzOm4saGFsZmVkZ2VzOnMsdHJpYW5nbGVzOnJ9fT10aGlzLG89blt0XTtpZihvPT09LTEpcmV0dXJuIG51bGw7Y29uc3QgYT1bXTtsZXQgYz1vO2Rve2NvbnN0IGw9TWF0aC5mbG9vcihjLzMpO2lmKGEucHVzaChlW2wqMl0sZVtsKjIrMV0pLGM9YyUzPT09Mj9jLTI6YysxLHJbY10hPT10KWJyZWFrO2M9c1tjXX13aGlsZShjIT09byYmYyE9PS0xKTtyZXR1cm4gYX1fY2xpcCh0KXtpZih0PT09MCYmdGhpcy5kZWxhdW5heS5odWxsLmxlbmd0aD09PTEpcmV0dXJuW3RoaXMueG1heCx0aGlzLnltaW4sdGhpcy54bWF4LHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltaW5dO2NvbnN0IGU9dGhpcy5fY2VsbCh0KTtpZihlPT09bnVsbClyZXR1cm4gbnVsbDtjb25zdHt2ZWN0b3JzOm59PXRoaXMscz10KjQ7cmV0dXJuIG5bc118fG5bcysxXT90aGlzLl9jbGlwSW5maW5pdGUodCxlLG5bc10sbltzKzFdLG5bcysyXSxuW3MrM10pOnRoaXMuX2NsaXBGaW5pdGUodCxlKX1fY2xpcEZpbml0ZSh0LGUpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHM9bnVsbCxyLG8sYT1lW24tMl0sYz1lW24tMV0sbCxoPXRoaXMuX3JlZ2lvbmNvZGUoYSxjKSx1LGY9MDtmb3IobGV0IGQ9MDtkPG47ZCs9MilpZihyPWEsbz1jLGE9ZVtkXSxjPWVbZCsxXSxsPWgsaD10aGlzLl9yZWdpb25jb2RlKGEsYyksbD09PTAmJmg9PT0wKXU9ZixmPTAscz9zLnB1c2goYSxjKTpzPVthLGNdO2Vsc2V7bGV0IHAseSxtLGcsYjtpZihsPT09MCl7aWYoKHA9dGhpcy5fY2xpcFNlZ21lbnQocixvLGEsYyxsLGgpKT09PW51bGwpY29udGludWU7W3ksbSxnLGJdPXB9ZWxzZXtpZigocD10aGlzLl9jbGlwU2VnbWVudChhLGMscixvLGgsbCkpPT09bnVsbCljb250aW51ZTtbZyxiLHksbV09cCx1PWYsZj10aGlzLl9lZGdlY29kZSh5LG0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCkscz9zLnB1c2goeSxtKTpzPVt5LG1dfXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGcsYiksdSYmZiYmdGhpcy5fZWRnZSh0LHUsZixzLHMubGVuZ3RoKSxzP3MucHVzaChnLGIpOnM9W2csYl19aWYocyl1PWYsZj10aGlzLl9lZGdlY29kZShzWzBdLHNbMV0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCk7ZWxzZSBpZih0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpKXJldHVyblt0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWluXTtyZXR1cm4gc31fY2xpcFNlZ21lbnQodCxlLG4scyxyLG8pe2Zvcig7Oyl7aWYocj09PTAmJm89PT0wKXJldHVyblt0LGUsbixzXTtpZihyJm8pcmV0dXJuIG51bGw7bGV0IGEsYyxsPXJ8fG87bCY4PyhhPXQrKG4tdCkqKHRoaXMueW1heC1lKS8ocy1lKSxjPXRoaXMueW1heCk6bCY0PyhhPXQrKG4tdCkqKHRoaXMueW1pbi1lKS8ocy1lKSxjPXRoaXMueW1pbik6bCYyPyhjPWUrKHMtZSkqKHRoaXMueG1heC10KS8obi10KSxhPXRoaXMueG1heCk6KGM9ZSsocy1lKSoodGhpcy54bWluLXQpLyhuLXQpLGE9dGhpcy54bWluKSxyPyh0PWEsZT1jLHI9dGhpcy5fcmVnaW9uY29kZSh0LGUpKToobj1hLHM9YyxvPXRoaXMuX3JlZ2lvbmNvZGUobixzKSl9fV9jbGlwSW5maW5pdGUodCxlLG4scyxyLG8pe2xldCBhPUFycmF5LmZyb20oZSksYztpZigoYz10aGlzLl9wcm9qZWN0KGFbMF0sYVsxXSxuLHMpKSYmYS51bnNoaWZ0KGNbMF0sY1sxXSksKGM9dGhpcy5fcHJvamVjdChhW2EubGVuZ3RoLTJdLGFbYS5sZW5ndGgtMV0scixvKSkmJmEucHVzaChjWzBdLGNbMV0pLGE9dGhpcy5fY2xpcEZpbml0ZSh0LGEpKWZvcihsZXQgbD0wLGg9YS5sZW5ndGgsdSxmPXRoaXMuX2VkZ2Vjb2RlKGFbaC0yXSxhW2gtMV0pO2w8aDtsKz0yKXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGFbbF0sYVtsKzFdKSx1JiZmJiYobD10aGlzLl9lZGdlKHQsdSxmLGEsbCksaD1hLmxlbmd0aCk7ZWxzZSB0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpJiYoYT1bdGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heF0pO3JldHVybiBhfV9lZGdlKHQsZSxuLHMscil7Zm9yKDtlIT09bjspe2xldCBvLGE7c3dpdGNoKGUpe2Nhc2UgNTplPTQ7Y29udGludWU7Y2FzZSA0OmU9NixvPXRoaXMueG1heCxhPXRoaXMueW1pbjticmVhaztjYXNlIDY6ZT0yO2NvbnRpbnVlO2Nhc2UgMjplPTEwLG89dGhpcy54bWF4LGE9dGhpcy55bWF4O2JyZWFrO2Nhc2UgMTA6ZT04O2NvbnRpbnVlO2Nhc2UgODplPTksbz10aGlzLnhtaW4sYT10aGlzLnltYXg7YnJlYWs7Y2FzZSA5OmU9MTtjb250aW51ZTtjYXNlIDE6ZT01LG89dGhpcy54bWluLGE9dGhpcy55bWluO2JyZWFrfShzW3JdIT09b3x8c1tyKzFdIT09YSkmJnRoaXMuY29udGFpbnModCxvLGEpJiYocy5zcGxpY2UociwwLG8sYSkscis9Mil9aWYocy5sZW5ndGg+NClmb3IobGV0IG89MDtvPHMubGVuZ3RoO28rPTIpe2NvbnN0IGE9KG8rMiklcy5sZW5ndGgsYz0obys0KSVzLmxlbmd0aDsoc1tvXT09PXNbYV0mJnNbYV09PT1zW2NdfHxzW28rMV09PT1zW2ErMV0mJnNbYSsxXT09PXNbYysxXSkmJihzLnNwbGljZShhLDIpLG8tPTIpfXJldHVybiByfV9wcm9qZWN0KHQsZSxuLHMpe2xldCByPTEvMCxvLGEsYztpZihzPDApe2lmKGU8PXRoaXMueW1pbilyZXR1cm4gbnVsbDsobz0odGhpcy55bWluLWUpL3MpPHImJihjPXRoaXMueW1pbixhPXQrKHI9bykqbil9ZWxzZSBpZihzPjApe2lmKGU+PXRoaXMueW1heClyZXR1cm4gbnVsbDsobz0odGhpcy55bWF4LWUpL3MpPHImJihjPXRoaXMueW1heCxhPXQrKHI9bykqbil9aWYobj4wKXtpZih0Pj10aGlzLnhtYXgpcmV0dXJuIG51bGw7KG89KHRoaXMueG1heC10KS9uKTxyJiYoYT10aGlzLnhtYXgsYz1lKyhyPW8pKnMpfWVsc2UgaWYobjwwKXtpZih0PD10aGlzLnhtaW4pcmV0dXJuIG51bGw7KG89KHRoaXMueG1pbi10KS9uKTxyJiYoYT10aGlzLnhtaW4sYz1lKyhyPW8pKnMpfXJldHVyblthLGNdfV9lZGdlY29kZSh0LGUpe3JldHVybih0PT09dGhpcy54bWluPzE6dD09PXRoaXMueG1heD8yOjApfChlPT09dGhpcy55bWluPzQ6ZT09PXRoaXMueW1heD84OjApfV9yZWdpb25jb2RlKHQsZSl7cmV0dXJuKHQ8dGhpcy54bWluPzE6dD50aGlzLnhtYXg/MjowKXwoZTx0aGlzLnltaW4/NDplPnRoaXMueW1heD84OjApfX1jb25zdCBHeT0yKk1hdGguUEksbGk9TWF0aC5wb3c7ZnVuY3Rpb24gWnkoaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gWHkoaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gSnkoaSl7Y29uc3R7dHJpYW5nbGVzOnQsY29vcmRzOmV9PWk7Zm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKz0zKXtjb25zdCBzPTIqdFtuXSxyPTIqdFtuKzFdLG89Mip0W24rMl07aWYoKGVbb10tZVtzXSkqKGVbcisxXS1lW3MrMV0pLShlW3JdLWVbc10pKihlW28rMV0tZVtzKzFdKT4xZS0xMClyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBZeShpLHQsZSl7cmV0dXJuW2krTWF0aC5zaW4oaSt0KSplLHQrTWF0aC5jb3MoaS10KSplXX1jbGFzcyBKYXtzdGF0aWMgZnJvbSh0LGU9Wnksbj1YeSxzKXtyZXR1cm4gbmV3IEphKCJsZW5ndGgiaW4gdD9qeSh0LGUsbixzKTpGbG9hdDY0QXJyYXkuZnJvbShReSh0LGUsbixzKSkpfWNvbnN0cnVjdG9yKHQpe3RoaXMuX2RlbGF1bmF0b3I9bmV3IGppKHQpLHRoaXMuaW5lZGdlcz1uZXcgSW50MzJBcnJheSh0Lmxlbmd0aC8yKSx0aGlzLl9odWxsSW5kZXg9bmV3IEludDMyQXJyYXkodC5sZW5ndGgvMiksdGhpcy5wb2ludHM9dGhpcy5fZGVsYXVuYXRvci5jb29yZHMsdGhpcy5faW5pdCgpfXVwZGF0ZSgpe3JldHVybiB0aGlzLl9kZWxhdW5hdG9yLnVwZGF0ZSgpLHRoaXMuX2luaXQoKSx0aGlzfV9pbml0KCl7Y29uc3QgdD10aGlzLl9kZWxhdW5hdG9yLGU9dGhpcy5wb2ludHM7aWYodC5odWxsJiZ0Lmh1bGwubGVuZ3RoPjImJkp5KHQpKXt0aGlzLmNvbGxpbmVhcj1JbnQzMkFycmF5LmZyb20oe2xlbmd0aDplLmxlbmd0aC8yfSwoZixkKT0+ZCkuc29ydCgoZixkKT0+ZVsyKmZdLWVbMipkXXx8ZVsyKmYrMV0tZVsyKmQrMV0pO2NvbnN0IGM9dGhpcy5jb2xsaW5lYXJbMF0sbD10aGlzLmNvbGxpbmVhclt0aGlzLmNvbGxpbmVhci5sZW5ndGgtMV0saD1bZVsyKmNdLGVbMipjKzFdLGVbMipsXSxlWzIqbCsxXV0sdT0xZS04Kk1hdGguaHlwb3QoaFszXS1oWzFdLGhbMl0taFswXSk7Zm9yKGxldCBmPTAsZD1lLmxlbmd0aC8yO2Y8ZDsrK2Ype2NvbnN0IHA9WXkoZVsyKmZdLGVbMipmKzFdLHUpO2VbMipmXT1wWzBdLGVbMipmKzFdPXBbMV19dGhpcy5fZGVsYXVuYXRvcj1uZXcgamkoZSl9ZWxzZSBkZWxldGUgdGhpcy5jb2xsaW5lYXI7Y29uc3Qgbj10aGlzLmhhbGZlZGdlcz10aGlzLl9kZWxhdW5hdG9yLmhhbGZlZGdlcyxzPXRoaXMuaHVsbD10aGlzLl9kZWxhdW5hdG9yLmh1bGwscj10aGlzLnRyaWFuZ2xlcz10aGlzLl9kZWxhdW5hdG9yLnRyaWFuZ2xlcyxvPXRoaXMuaW5lZGdlcy5maWxsKC0xKSxhPXRoaXMuX2h1bGxJbmRleC5maWxsKC0xKTtmb3IobGV0IGM9MCxsPW4ubGVuZ3RoO2M8bDsrK2Mpe2NvbnN0IGg9cltjJTM9PT0yP2MtMjpjKzFdOyhuW2NdPT09LTF8fG9baF09PT0tMSkmJihvW2hdPWMpfWZvcihsZXQgYz0wLGw9cy5sZW5ndGg7YzxsOysrYylhW3NbY11dPWM7cy5sZW5ndGg8PTImJnMubGVuZ3RoPjAmJih0aGlzLnRyaWFuZ2xlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLmhhbGZlZGdlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLnRyaWFuZ2xlc1swXT1zWzBdLG9bc1swXV09MSxzLmxlbmd0aD09PTImJihvW3NbMV1dPTAsdGhpcy50cmlhbmdsZXNbMV09c1sxXSx0aGlzLnRyaWFuZ2xlc1syXT1zWzFdKSl9dm9yb25vaSh0KXtyZXR1cm4gbmV3IFd5KHRoaXMsdCl9Km5laWdoYm9ycyh0KXtjb25zdHtpbmVkZ2VzOmUsaHVsbDpuLF9odWxsSW5kZXg6cyxoYWxmZWRnZXM6cix0cmlhbmdsZXM6byxjb2xsaW5lYXI6YX09dGhpcztpZihhKXtjb25zdCB1PWEuaW5kZXhPZih0KTt1PjAmJih5aWVsZCBhW3UtMV0pLHU8YS5sZW5ndGgtMSYmKHlpZWxkIGFbdSsxXSk7cmV0dXJufWNvbnN0IGM9ZVt0XTtpZihjPT09LTEpcmV0dXJuO2xldCBsPWMsaD0tMTtkb3tpZih5aWVsZCBoPW9bbF0sbD1sJTM9PT0yP2wtMjpsKzEsb1tsXSE9PXQpcmV0dXJuO2lmKGw9cltsXSxsPT09LTEpe2NvbnN0IHU9blsoc1t0XSsxKSVuLmxlbmd0aF07dSE9PWgmJih5aWVsZCB1KTtyZXR1cm59fXdoaWxlKGwhPT1jKX1maW5kKHQsZSxuPTApe2lmKHQ9K3QsdCE9PXR8fChlPStlLGUhPT1lKSlyZXR1cm4tMTtjb25zdCBzPW47bGV0IHI7Zm9yKDsocj10aGlzLl9zdGVwKG4sdCxlKSk+PTAmJnIhPT1uJiZyIT09czspbj1yO3JldHVybiByfV9zdGVwKHQsZSxuKXtjb25zdHtpbmVkZ2VzOnMsaHVsbDpyLF9odWxsSW5kZXg6byxoYWxmZWRnZXM6YSx0cmlhbmdsZXM6Yyxwb2ludHM6bH09dGhpcztpZihzW3RdPT09LTF8fCFsLmxlbmd0aClyZXR1cm4odCsxKSUobC5sZW5ndGg+PjEpO2xldCBoPXQsdT1saShlLWxbdCoyXSwyKStsaShuLWxbdCoyKzFdLDIpO2NvbnN0IGY9c1t0XTtsZXQgZD1mO2Rve2xldCBwPWNbZF07Y29uc3QgeT1saShlLWxbcCoyXSwyKStsaShuLWxbcCoyKzFdLDIpO2lmKHk8dSYmKHU9eSxoPXApLGQ9ZCUzPT09Mj9kLTI6ZCsxLGNbZF0hPT10KWJyZWFrO2lmKGQ9YVtkXSxkPT09LTEpe2lmKGQ9clsob1t0XSsxKSVyLmxlbmd0aF0sZCE9PXAmJmxpKGUtbFtkKjJdLDIpK2xpKG4tbFtkKjIrMV0sMik8dSlyZXR1cm4gZDticmVha319d2hpbGUoZCE9PWYpO3JldHVybiBofXJlbmRlcih0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgdm46dm9pZCAwLHtwb2ludHM6bixoYWxmZWRnZXM6cyx0cmlhbmdsZXM6cn09dGhpcztmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTsrK28pe2NvbnN0IGM9c1tvXTtpZihjPG8pY29udGludWU7Y29uc3QgbD1yW29dKjIsaD1yW2NdKjI7dC5tb3ZlVG8obltsXSxuW2wrMV0pLHQubGluZVRvKG5baF0sbltoKzFdKX1yZXR1cm4gdGhpcy5yZW5kZXJIdWxsKHQpLGUmJmUudmFsdWUoKX1yZW5kZXJQb2ludHModCxlKXtlPT09dm9pZCAwJiYoIXR8fHR5cGVvZiB0Lm1vdmVUbyE9ImZ1bmN0aW9uIikmJihlPXQsdD1udWxsKSxlPWU9PW51bGw/MjorZTtjb25zdCBuPXQ9PW51bGw/dD1uZXcgdm46dm9pZCAwLHtwb2ludHM6c309dGhpcztmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKz0yKXtjb25zdCBhPXNbcl0sYz1zW3IrMV07dC5tb3ZlVG8oYStlLGMpLHQuYXJjKGEsYyxlLDAsR3kpfXJldHVybiBuJiZuLnZhbHVlKCl9cmVuZGVySHVsbCh0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgdm46dm9pZCAwLHtodWxsOm4scG9pbnRzOnN9PXRoaXMscj1uWzBdKjIsbz1uLmxlbmd0aDt0Lm1vdmVUbyhzW3JdLHNbcisxXSk7Zm9yKGxldCBhPTE7YTxvOysrYSl7Y29uc3QgYz0yKm5bYV07dC5saW5lVG8oc1tjXSxzW2MrMV0pfXJldHVybiB0LmNsb3NlUGF0aCgpLGUmJmUudmFsdWUoKX1odWxsUG9seWdvbigpe2NvbnN0IHQ9bmV3IFhhO3JldHVybiB0aGlzLnJlbmRlckh1bGwodCksdC52YWx1ZSgpfXJlbmRlclRyaWFuZ2xlKHQsZSl7Y29uc3Qgbj1lPT1udWxsP2U9bmV3IHZuOnZvaWQgMCx7cG9pbnRzOnMsdHJpYW5nbGVzOnJ9PXRoaXMsbz1yW3QqPTNdKjIsYT1yW3QrMV0qMixjPXJbdCsyXSoyO3JldHVybiBlLm1vdmVUbyhzW29dLHNbbysxXSksZS5saW5lVG8oc1thXSxzW2ErMV0pLGUubGluZVRvKHNbY10sc1tjKzFdKSxlLmNsb3NlUGF0aCgpLG4mJm4udmFsdWUoKX0qdHJpYW5nbGVQb2x5Z29ucygpe2NvbnN0e3RyaWFuZ2xlczp0fT10aGlzO2ZvcihsZXQgZT0wLG49dC5sZW5ndGgvMztlPG47KytlKXlpZWxkIHRoaXMudHJpYW5nbGVQb2x5Z29uKGUpfXRyaWFuZ2xlUG9seWdvbih0KXtjb25zdCBlPW5ldyBYYTtyZXR1cm4gdGhpcy5yZW5kZXJUcmlhbmdsZSh0LGUpLGUudmFsdWUoKX19ZnVuY3Rpb24gankoaSx0LGUsbil7Y29uc3Qgcz1pLmxlbmd0aCxyPW5ldyBGbG9hdDY0QXJyYXkocyoyKTtmb3IobGV0IG89MDtvPHM7KytvKXtjb25zdCBhPWlbb107cltvKjJdPXQuY2FsbChuLGEsbyxpKSxyW28qMisxXT1lLmNhbGwobixhLG8saSl9cmV0dXJuIHJ9ZnVuY3Rpb24qUXkoaSx0LGUsbil7bGV0IHM9MDtmb3IoY29uc3QgciBvZiBpKXlpZWxkIHQuY2FsbChuLHIscyxpKSx5aWVsZCBlLmNhbGwobixyLHMsaSksKytzfWNvbnN0IFlhPU1hdGguUEksWGg9WWEvMixKaD0xODAvWWEsWWg9WWEvMTgwLEt5PU1hdGguYXRhbjIsamg9TWF0aC5jb3MsdG09TWF0aC5tYXgsZW09TWF0aC5taW4sUWg9TWF0aC5zaW4sbm09TWF0aC5zaWdufHxmdW5jdGlvbihpKXtyZXR1cm4gaT4wPzE6aTwwPy0xOjB9LEtoPU1hdGguc3FydDtmdW5jdGlvbiBpbShpKXtyZXR1cm4gaT4xP1hoOmk8LTE/LVhoOk1hdGguYXNpbihpKX1mdW5jdGlvbiB0dShpLHQpe3JldHVybiBpWzBdKnRbMF0raVsxXSp0WzFdK2lbMl0qdFsyXX1mdW5jdGlvbiBXdChpLHQpe3JldHVybltpWzFdKnRbMl0taVsyXSp0WzFdLGlbMl0qdFswXS1pWzBdKnRbMl0saVswXSp0WzFdLWlbMV0qdFswXV19ZnVuY3Rpb24gTnIoaSx0KXtyZXR1cm5baVswXSt0WzBdLGlbMV0rdFsxXSxpWzJdK3RbMl1dfWZ1bmN0aW9uIFJyKGkpe3ZhciB0PUtoKGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtyZXR1cm5baVswXS90LGlbMV0vdCxpWzJdL3RdfWZ1bmN0aW9uIGphKGkpe3JldHVybltLeShpWzFdLGlbMF0pKkpoLGltKHRtKC0xLGVtKDEsaVsyXSkpKSpKaF19ZnVuY3Rpb24gYmUoaSl7Y29uc3QgdD1pWzBdKlloLGU9aVsxXSpZaCxuPWpoKGUpO3JldHVybltuKmpoKHQpLG4qUWgodCksUWgoZSldfWZ1bmN0aW9uIFFhKGkpe3JldHVybiBpPWkubWFwKHQ9PmJlKHQpKSx0dShpWzBdLFd0KGlbMl0saVsxXSkpfWZ1bmN0aW9uIHNtKGkpe2NvbnN0IHQ9b20oaSksZT1jbSh0KSxuPWFtKGUsaSkscz1obShlLGkubGVuZ3RoKSxyPXJtKHMsaSksbz1sbShlLGkpLHtwb2x5Z29uczphLGNlbnRlcnM6Y309dW0obyxlLGkpLGw9Zm0oYSksaD1wbShlLGkpLHU9ZG0obixlKTtyZXR1cm57ZGVsYXVuYXk6dCxlZGdlczpuLHRyaWFuZ2xlczplLGNlbnRlcnM6YyxuZWlnaGJvcnM6cyxwb2x5Z29uczphLG1lc2g6bCxodWxsOmgsdXJxdWhhcnQ6dSxmaW5kOnJ9fWZ1bmN0aW9uIHJtKGksdCl7ZnVuY3Rpb24gZShuLHMpe2xldCByPW5bMF0tc1swXSxvPW5bMV0tc1sxXSxhPW5bMl0tc1syXTtyZXR1cm4gcipyK28qbythKmF9cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtvPT09dm9pZCAwJiYobz0wKTtsZXQgYSxjLGw9bztjb25zdCBoPWJlKFtzLHJdKTtkbyBhPW8sbz1udWxsLGM9ZShoLGJlKHRbYV0pKSxpW2FdLmZvckVhY2godT0+e2xldCBmPWUoaCxiZSh0W3VdKSk7aWYoZjxjKXtjPWYsbz11LGw9dTtyZXR1cm59fSk7d2hpbGUobyE9PW51bGwpO3JldHVybiBsfX1mdW5jdGlvbiBvbShpKXtpZihpLmxlbmd0aDwyKXJldHVybnt9O2xldCB0PTA7Zm9yKDtpc05hTihpW3RdWzBdK2lbdF1bMV0pJiZ0Kys8aS5sZW5ndGg7KTtjb25zdCBlPXBoKGlbdF0pLG49WnAoKS50cmFuc2xhdGUoWzAsMF0pLnNjYWxlKDEpLnJvdGF0ZShlLmludmVydChbMTgwLDBdKSk7aT1pLm1hcChuKTtjb25zdCBzPVtdO2xldCByPTE7Zm9yKGxldCB1PTAsZj1pLmxlbmd0aDt1PGY7dSsrKXtsZXQgZD1kaShpW3VdWzBdLDIpK2RpKGlbdV1bMV0sMik7IWlzRmluaXRlKGQpfHxkPjFlMzI/cy5wdXNoKHUpOmQ+ciYmKHI9ZCl9Y29uc3Qgbz0xZTYqS2gocik7cy5mb3JFYWNoKHU9PmlbdV09W28sMF0pLGkucHVzaChbMCxvXSksaS5wdXNoKFstbywwXSksaS5wdXNoKFswLC1vXSk7Y29uc3QgYT1KYS5mcm9tKGkpO2EucHJvamVjdGlvbj1uO2NvbnN0e3RyaWFuZ2xlczpjLGhhbGZlZGdlczpsLGluZWRnZXM6aH09YTtmb3IobGV0IHU9MCxmPWwubGVuZ3RoO3U8Zjt1KyspaWYobFt1XTwwKXtjb25zdCBkPXUlMz09Mj91LTI6dSsxLHA9dSUzPT0wP3UrMjp1LTEseT1sW2RdLG09bFtwXTtsW3ldPW0sbFttXT15LGxbZF09bFtwXT0tMSxjW3VdPWNbZF09Y1twXT10LGhbY1t5XV09eSUzPT0wP3krMjp5LTEsaFtjW21dXT1tJTM9PTA/bSsyOm0tMSx1Kz0yLXUlM31lbHNlIGNbdV0+aS5sZW5ndGgtMy0xJiYoY1t1XT10KTtyZXR1cm4gYX1mdW5jdGlvbiBhbShpLHQpe2NvbnN0IGU9bmV3IFNldDtyZXR1cm4gdC5sZW5ndGg9PT0yP1tbMCwxXV06KGkuZm9yRWFjaChuPT57aWYoblswXSE9PW5bMV0mJiEoUWEobi5tYXAocz0+dFtzXSkpPDApKWZvcihsZXQgcz0wLHI7czwzO3MrKylyPShzKzEpJTMsZS5hZGQoZXIoW25bc10sbltyXV0pLmpvaW4oIi0iKSl9KSxBcnJheS5mcm9tKGUsbj0+bi5zcGxpdCgiLSIpLm1hcChOdW1iZXIpKSl9ZnVuY3Rpb24gY20oaSl7Y29uc3R7dHJpYW5nbGVzOnR9PWk7aWYoIXQpcmV0dXJuW107Y29uc3QgZT1bXTtmb3IobGV0IG49MCxzPXQubGVuZ3RoLzM7bjxzO24rKyl7Y29uc3Qgcj10WzMqbl0sbz10WzMqbisxXSxhPXRbMypuKzJdO3IhPT1vJiZvIT09YSYmZS5wdXNoKFtyLGEsb10pfXJldHVybiBlfWZ1bmN0aW9uIGxtKGksdCl7cmV0dXJuIGkubWFwKGU9Pntjb25zdCBuPWUubWFwKHI9PnRbcl0pLm1hcChiZSkscz1OcihOcihXdChuWzFdLG5bMF0pLFd0KG5bMl0sblsxXSkpLFd0KG5bMF0sblsyXSkpO3JldHVybiBqYShScihzKSl9KX1mdW5jdGlvbiBobShpLHQpe2NvbnN0IGU9W107cmV0dXJuIGkuZm9yRWFjaChuPT57Zm9yKGxldCBzPTA7czwzO3MrKyl7Y29uc3Qgcj1uW3NdLG89blsocysxKSUzXTtlW3JdPWVbcl18fFtdLGVbcl0ucHVzaChvKX19KSxpLmxlbmd0aD09PTAmJih0PT09Mj8oZVswXT1bMV0sZVsxXT1bMF0pOnQ9PT0xJiYoZVswXT1bXSkpLGV9ZnVuY3Rpb24gdW0oaSx0LGUpe2NvbnN0IG49W10scz1pLnNsaWNlKCk7aWYodC5sZW5ndGg9PT0wKXtpZihlLmxlbmd0aDwyKXJldHVybntwb2x5Z29uczpuLGNlbnRlcnM6c307aWYoZS5sZW5ndGg9PT0yKXtjb25zdCBhPWJlKGVbMF0pLGM9YmUoZVsxXSksbD1ScihOcihhLGMpKSxoPVJyKFd0KGEsYykpLHU9V3QobCxoKSxmPVtsLFd0KGwsdSksV3QoV3QobCx1KSx1KSxXdChXdChXdChsLHUpLHUpLHUpXS5tYXAoamEpLm1hcChvKTtyZXR1cm4gbi5wdXNoKGYpLG4ucHVzaChmLnNsaWNlKCkucmV2ZXJzZSgpKSx7cG9seWdvbnM6bixjZW50ZXJzOnN9fX10LmZvckVhY2goKGEsYyk9Pntmb3IobGV0IGw9MDtsPDM7bCsrKXtjb25zdCBoPWFbbF0sdT1hWyhsKzEpJTNdLGY9YVsobCsyKSUzXTtuW2hdPW5baF18fFtdLG5baF0ucHVzaChbdSxmLGMsW2gsdSxmXV0pfX0pO2NvbnN0IHI9bi5tYXAoYT0+e2NvbnN0IGM9W2FbMF1bMl1dO2xldCBsPWFbMF1bMV07Zm9yKGxldCBoPTE7aDxhLmxlbmd0aDtoKyspZm9yKGxldCB1PTA7dTxhLmxlbmd0aDt1KyspaWYoYVt1XVswXT09bCl7bD1hW3VdWzFdLGMucHVzaChhW3VdWzJdKTticmVha31pZihjLmxlbmd0aD4yKXJldHVybiBjO2lmKGMubGVuZ3RoPT0yKXtjb25zdCBoPWV1KGVbYVswXVszXVswXV0sZVthWzBdWzNdWzFdXSxzW2NbMF1dKSx1PWV1KGVbYVswXVszXVsyXV0sZVthWzBdWzNdWzBdXSxzW2NbMF1dKSxmPW8oaCksZD1vKHUpO3JldHVybltjWzBdLGQsY1sxXSxmXX19KTtmdW5jdGlvbiBvKGEpe2xldCBjPS0xO3JldHVybiBzLnNsaWNlKHQubGVuZ3RoLDEvMCkuZm9yRWFjaCgobCxoKT0+e2xbMF09PT1hWzBdJiZsWzFdPT09YVsxXSYmKGM9aCt0Lmxlbmd0aCl9KSxjPDAmJihjPXMubGVuZ3RoLHMucHVzaChhKSksY31yZXR1cm57cG9seWdvbnM6cixjZW50ZXJzOnN9fWZ1bmN0aW9uIGV1KGksdCxlKXtpPWJlKGkpLHQ9YmUodCksZT1iZShlKTtjb25zdCBuPW5tKHR1KFd0KHQsaSksZSkpO3JldHVybiBqYShScihOcihpLHQpKS5tYXAocz0+bipzKSl9ZnVuY3Rpb24gZm0oaSl7Y29uc3QgdD1bXTtyZXR1cm4gaS5mb3JFYWNoKGU9PntpZighZSlyZXR1cm47bGV0IG49ZVtlLmxlbmd0aC0xXTtmb3IobGV0IHMgb2YgZSlzPm4mJnQucHVzaChbbixzXSksbj1zfSksdH1mdW5jdGlvbiBkbShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtjb25zdCBuPW5ldyBNYXAscz1uZXcgTWFwO3JldHVybiBpLmZvckVhY2goKHIsbyk9Pntjb25zdCBhPXIuam9pbigiLSIpO24uc2V0KGEsZVtvXSkscy5zZXQoYSwhMCl9KSx0LmZvckVhY2gocj0+e2xldCBvPTAsYT0tMTtmb3IobGV0IGM9MDtjPDM7YysrKXtsZXQgbD1lcihbcltjXSxyWyhjKzEpJTNdXSkuam9pbigiLSIpO24uZ2V0KGwpPm8mJihvPW4uZ2V0KGwpLGE9bCl9cy5zZXQoYSwhMSl9KSxpLm1hcChyPT5zLmdldChyLmpvaW4oIi0iKSkpfX1mdW5jdGlvbiBwbShpLHQpe2NvbnN0IGU9bmV3IFNldCxuPVtdO2kubWFwKGE9PntpZighKFFhKGEubWFwKGM9PnRbYz50Lmxlbmd0aD8wOmNdKSk+MWUtMTIpKWZvcihsZXQgYz0wO2M8MztjKyspe2xldCBsPVthW2NdLGFbKGMrMSklM11dLGg9YCR7bFswXX0tJHtsWzFdfWA7ZS5oYXMoaCk/ZS5kZWxldGUoaCk6ZS5hZGQoYCR7bFsxXX0tJHtsWzBdfWApfX0pO2NvbnN0IHM9bmV3IE1hcDtsZXQgcjtpZihlLmZvckVhY2goYT0+e2E9YS5zcGxpdCgiLSIpLm1hcChOdW1iZXIpLHMuc2V0KGFbMF0sYVsxXSkscj1hWzBdfSkscj09PXZvaWQgMClyZXR1cm4gbjtsZXQgbz1yO2Rve24ucHVzaChvKTtsZXQgYT1zLmdldChvKTtzLnNldChvLC0xKSxvPWF9d2hpbGUobz4tMSYmbyE9PXIpO3JldHVybiBufWZ1bmN0aW9uIHltKGkpe2NvbnN0IHQ9ZnVuY3Rpb24oZSl7aWYodC5kZWxhdW5heT1udWxsLHQuX2RhdGE9ZSx0eXBlb2YgdC5fZGF0YT09Im9iamVjdCImJnQuX2RhdGEudHlwZT09PSJGZWF0dXJlQ29sbGVjdGlvbiImJih0Ll9kYXRhPXQuX2RhdGEuZmVhdHVyZXMpLHR5cGVvZiB0Ll9kYXRhPT0ib2JqZWN0Iil7Y29uc3Qgbj10Ll9kYXRhLm1hcChzPT5bdC5fdngocyksdC5fdnkocyksc10pLmZpbHRlcihzPT5pc0Zpbml0ZShzWzBdK3NbMV0pKTt0LnBvaW50cz1uLm1hcChzPT5bc1swXSxzWzFdXSksdC52YWxpZD1uLm1hcChzPT5zWzJdKSx0LmRlbGF1bmF5PXNtKHQucG9pbnRzKX1yZXR1cm4gdH07cmV0dXJuIHQuX3Z4PWZ1bmN0aW9uKGUpe2lmKHR5cGVvZiBlPT0ib2JqZWN0IiYmInR5cGUiaW4gZSlyZXR1cm4gbGgoZSlbMF07aWYoMCBpbiBlKXJldHVybiBlWzBdfSx0Ll92eT1mdW5jdGlvbihlKXtpZih0eXBlb2YgZT09Im9iamVjdCImJiJ0eXBlImluIGUpcmV0dXJuIGxoKGUpWzFdO2lmKDEgaW4gZSlyZXR1cm4gZVsxXX0sdC54PWZ1bmN0aW9uKGUpe3JldHVybiBlPyh0Ll92eD1lLHQpOnQuX3Z4fSx0Lnk9ZnVuY3Rpb24oZSl7cmV0dXJuIGU/KHQuX3Z5PWUsdCk6dC5fdnl9LHQucG9seWdvbnM9ZnVuY3Rpb24oZSl7aWYoZSE9PXZvaWQgMCYmdChlKSwhdC5kZWxhdW5heSlyZXR1cm4hMTtjb25zdCBuPXt0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6W119O3JldHVybiB0LnZhbGlkLmxlbmd0aD09PTB8fCh0LmRlbGF1bmF5LnBvbHlnb25zLmZvckVhY2goKHMscik9Pm4uZmVhdHVyZXMucHVzaCh7dHlwZToiRmVhdHVyZSIsZ2VvbWV0cnk6cz97dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5zLHNbMF1dLm1hcChvPT50LmRlbGF1bmF5LmNlbnRlcnNbb10pXX06bnVsbCxwcm9wZXJ0aWVzOntzaXRlOnQudmFsaWRbcl0sc2l0ZWNvb3JkaW5hdGVzOnQucG9pbnRzW3JdLG5laWdoYm91cnM6dC5kZWxhdW5heS5uZWlnaGJvcnNbcl19fSkpLHQudmFsaWQubGVuZ3RoPT09MSYmbi5mZWF0dXJlcy5wdXNoKHt0eXBlOiJGZWF0dXJlIixnZW9tZXRyeTp7dHlwZToiU3BoZXJlIn0scHJvcGVydGllczp7c2l0ZTp0LnZhbGlkWzBdLHNpdGVjb29yZGluYXRlczp0LnBvaW50c1swXSxuZWlnaGJvdXJzOltdfX0pKSxufSx0LnRyaWFuZ2xlcz1mdW5jdGlvbihlKXtyZXR1cm4gZSE9PXZvaWQgMCYmdChlKSx0LmRlbGF1bmF5P3t0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6dC5kZWxhdW5heS50cmlhbmdsZXMubWFwKChuLHMpPT4obj1uLm1hcChyPT50LnBvaW50c1tyXSksbi5jZW50ZXI9dC5kZWxhdW5heS5jZW50ZXJzW3NdLG4pKS5maWx0ZXIobj0+UWEobik+MCkubWFwKG49Pih7dHlwZToiRmVhdHVyZSIscHJvcGVydGllczp7Y2lyY3VtY2VudGVyOm4uY2VudGVyfSxnZW9tZXRyeTp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLG5bMF1dXX19KSl9OiExfSx0LmxpbmtzPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3Qgbj10LmRlbGF1bmF5LmVkZ2VzLm1hcChyPT5zaSh0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXSkpLHM9dC5kZWxhdW5heS51cnF1aGFydChuKTtyZXR1cm57dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOnQuZGVsYXVuYXkuZWRnZXMubWFwKChyLG8pPT4oe3R5cGU6IkZlYXR1cmUiLHByb3BlcnRpZXM6e3NvdXJjZTp0LnZhbGlkW3JbMF1dLHRhcmdldDp0LnZhbGlkW3JbMV1dLGxlbmd0aDpuW29dLHVycXVoYXJ0OiEhc1tvXX0sZ2VvbWV0cnk6e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOlt0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXV19fSkpfX0sdC5tZXNoPWZ1bmN0aW9uKGUpe3JldHVybiBlIT09dm9pZCAwJiZ0KGUpLHQuZGVsYXVuYXk/e3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6dC5kZWxhdW5heS5lZGdlcy5tYXAobj0+W3QucG9pbnRzW25bMF1dLHQucG9pbnRzW25bMV1dXSl9OiExfSx0LmNlbGxNZXNoPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3R7Y2VudGVyczpuLHBvbHlnb25zOnN9PXQuZGVsYXVuYXkscj1bXTtmb3IoY29uc3QgbyBvZiBzKWlmKG8pZm9yKGxldCBhPW8ubGVuZ3RoLGM9b1thLTFdLGw9b1swXSxoPTA7aDxhO2M9bCxsPW9bKytoXSlsPmMmJnIucHVzaChbbltjXSxuW2xdXSk7cmV0dXJue3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6cn19LHQuX2ZvdW5kPXZvaWQgMCx0LmZpbmQ9ZnVuY3Rpb24oZSxuLHMpe2lmKHQuX2ZvdW5kPXQuZGVsYXVuYXkuZmluZChlLG4sdC5fZm91bmQpLCFzfHxzaShbZSxuXSx0LnBvaW50c1t0Ll9mb3VuZF0pPHMpcmV0dXJuIHQuX2ZvdW5kfSx0Lmh1bGw9ZnVuY3Rpb24oZSl7ZSE9PXZvaWQgMCYmdChlKTtjb25zdCBuPXQuZGVsYXVuYXkuaHVsbCxzPXQucG9pbnRzO3JldHVybiBuLmxlbmd0aD09PTA/bnVsbDp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLm1hcChyPT5zW3JdKSxzW25bMF1dXV19fSxpP3QoaSk6dH1mdW5jdGlvbiBtbShpLHQpe3N3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtjYXNlIDA6YnJlYWs7Y2FzZSAxOnRoaXMucmFuZ2UoaSk7YnJlYWs7ZGVmYXVsdDp0aGlzLnJhbmdlKHQpLmRvbWFpbihpKTticmVha31yZXR1cm4gdGhpc31mdW5jdGlvbiBLYShpLHQsZSl7aS5wcm90b3R5cGU9dC5wcm90b3R5cGU9ZSxlLmNvbnN0cnVjdG9yPWl9ZnVuY3Rpb24gbnUoaSx0KXt2YXIgZT1PYmplY3QuY3JlYXRlKGkucHJvdG90eXBlKTtmb3IodmFyIG4gaW4gdCllW25dPXRbbl07cmV0dXJuIGV9ZnVuY3Rpb24gS2koKXt9dmFyIHRzPS43LExyPTEvdHMsaGk9IlxccyooWystXT9cXGQrKVxccyoiLGVzPSJcXHMqKFsrLV0/KD86XFxkKlxcLik/XFxkKyg/OltlRV1bKy1dP1xcZCspPylcXHMqIixNZT0iXFxzKihbKy1dPyg/OlxcZCpcXC4pP1xcZCsoPzpbZUVdWystXT9cXGQrKT8pJVxccyoiLGdtPS9eIyhbMC05YS1mXXszLDh9KSQvLHhtPW5ldyBSZWdFeHAoYF5yZ2JcXCgke2hpfSwke2hpfSwke2hpfVxcKSRgKSx3bT1uZXcgUmVnRXhwKGBecmdiXFwoJHtNZX0sJHtNZX0sJHtNZX1cXCkkYCksYm09bmV3IFJlZ0V4cChgXnJnYmFcXCgke2hpfSwke2hpfSwke2hpfSwke2VzfVxcKSRgKSxNbT1uZXcgUmVnRXhwKGBecmdiYVxcKCR7TWV9LCR7TWV9LCR7TWV9LCR7ZXN9XFwpJGApLEFtPW5ldyBSZWdFeHAoYF5oc2xcXCgke2VzfSwke01lfSwke01lfVxcKSRgKSxfbT1uZXcgUmVnRXhwKGBeaHNsYVxcKCR7ZXN9LCR7TWV9LCR7TWV9LCR7ZXN9XFwpJGApLGl1PXthbGljZWJsdWU6MTU3OTIzODMsYW50aXF1ZXdoaXRlOjE2NDQ0Mzc1LGFxdWE6NjU1MzUsYXF1YW1hcmluZTo4Mzg4NTY0LGF6dXJlOjE1Nzk0MTc1LGJlaWdlOjE2MTE5MjYwLGJpc3F1ZToxNjc3MDI0NCxibGFjazowLGJsYW5jaGVkYWxtb25kOjE2NzcyMDQ1LGJsdWU6MjU1LGJsdWV2aW9sZXQ6OTA1NTIwMixicm93bjoxMDgyNDIzNCxidXJseXdvb2Q6MTQ1OTYyMzEsY2FkZXRibHVlOjYyNjY1MjgsY2hhcnRyZXVzZTo4Mzg4MzUyLGNob2NvbGF0ZToxMzc4OTQ3MCxjb3JhbDoxNjc0NDI3Mixjb3JuZmxvd2VyYmx1ZTo2NTkxOTgxLGNvcm5zaWxrOjE2Nzc1Mzg4LGNyaW1zb246MTQ0MjMxMDAsY3lhbjo2NTUzNSxkYXJrYmx1ZToxMzksZGFya2N5YW46MzU3MjMsZGFya2dvbGRlbnJvZDoxMjA5MjkzOSxkYXJrZ3JheToxMTExOTAxNyxkYXJrZ3JlZW46MjU2MDAsZGFya2dyZXk6MTExMTkwMTcsZGFya2toYWtpOjEyNDMzMjU5LGRhcmttYWdlbnRhOjkxMDk2NDMsZGFya29saXZlZ3JlZW46NTU5Nzk5OSxkYXJrb3JhbmdlOjE2NzQ3NTIwLGRhcmtvcmNoaWQ6MTAwNDAwMTIsZGFya3JlZDo5MTA5NTA0LGRhcmtzYWxtb246MTUzMDg0MTAsZGFya3NlYWdyZWVuOjk0MTk5MTksZGFya3NsYXRlYmx1ZTo0NzM0MzQ3LGRhcmtzbGF0ZWdyYXk6MzEwMDQ5NSxkYXJrc2xhdGVncmV5OjMxMDA0OTUsZGFya3R1cnF1b2lzZTo1Mjk0NSxkYXJrdmlvbGV0Ojk2OTk1MzksZGVlcHBpbms6MTY3MTY5NDcsZGVlcHNreWJsdWU6NDkxNTEsZGltZ3JheTo2OTA4MjY1LGRpbWdyZXk6NjkwODI2NSxkb2RnZXJibHVlOjIwMDMxOTksZmlyZWJyaWNrOjExNjc0MTQ2LGZsb3JhbHdoaXRlOjE2Nzc1OTIwLGZvcmVzdGdyZWVuOjIyNjM4NDIsZnVjaHNpYToxNjcxMTkzNSxnYWluc2Jvcm86MTQ0NzQ0NjAsZ2hvc3R3aGl0ZToxNjMxNjY3MSxnb2xkOjE2NzY2NzIwLGdvbGRlbnJvZDoxNDMyOTEyMCxncmF5Ojg0MjE1MDQsZ3JlZW46MzI3NjgsZ3JlZW55ZWxsb3c6MTE0MDMwNTUsZ3JleTo4NDIxNTA0LGhvbmV5ZGV3OjE1Nzk0MTYwLGhvdHBpbms6MTY3Mzg3NDAsaW5kaWFucmVkOjEzNDU4NTI0LGluZGlnbzo0OTE1MzMwLGl2b3J5OjE2Nzc3MjAwLGtoYWtpOjE1Nzg3NjYwLGxhdmVuZGVyOjE1MTMyNDEwLGxhdmVuZGVyYmx1c2g6MTY3NzMzNjUsbGF3bmdyZWVuOjgxOTA5NzYsbGVtb25jaGlmZm9uOjE2Nzc1ODg1LGxpZ2h0Ymx1ZToxMTM5MzI1NCxsaWdodGNvcmFsOjE1NzYxNTM2LGxpZ2h0Y3lhbjoxNDc0NTU5OSxsaWdodGdvbGRlbnJvZHllbGxvdzoxNjQ0ODIxMCxsaWdodGdyYXk6MTM4ODIzMjMsbGlnaHRncmVlbjo5NDk4MjU2LGxpZ2h0Z3JleToxMzg4MjMyMyxsaWdodHBpbms6MTY3NTg0NjUsbGlnaHRzYWxtb246MTY3NTI3NjIsbGlnaHRzZWFncmVlbjoyMTQyODkwLGxpZ2h0c2t5Ymx1ZTo4OTAwMzQ2LGxpZ2h0c2xhdGVncmF5Ojc4MzM3NTMsbGlnaHRzbGF0ZWdyZXk6NzgzMzc1MyxsaWdodHN0ZWVsYmx1ZToxMTU4NDczNCxsaWdodHllbGxvdzoxNjc3NzE4NCxsaW1lOjY1MjgwLGxpbWVncmVlbjozMzI5MzMwLGxpbmVuOjE2NDQ1NjcwLG1hZ2VudGE6MTY3MTE5MzUsbWFyb29uOjgzODg2MDgsbWVkaXVtYXF1YW1hcmluZTo2NzM3MzIyLG1lZGl1bWJsdWU6MjA1LG1lZGl1bW9yY2hpZDoxMjIxMTY2NyxtZWRpdW1wdXJwbGU6OTY2MjY4MyxtZWRpdW1zZWFncmVlbjozOTc4MDk3LG1lZGl1bXNsYXRlYmx1ZTo4MDg3NzkwLG1lZGl1bXNwcmluZ2dyZWVuOjY0MTU0LG1lZGl1bXR1cnF1b2lzZTo0NzcyMzAwLG1lZGl1bXZpb2xldHJlZDoxMzA0NzE3MyxtaWRuaWdodGJsdWU6MTY0NDkxMixtaW50Y3JlYW06MTYxMjE4NTAsbWlzdHlyb3NlOjE2NzcwMjczLG1vY2Nhc2luOjE2NzcwMjI5LG5hdmFqb3doaXRlOjE2NzY4Njg1LG5hdnk6MTI4LG9sZGxhY2U6MTY2NDM1NTgsb2xpdmU6ODQyMTM3NixvbGl2ZWRyYWI6NzA0ODczOSxvcmFuZ2U6MTY3NTM5MjAsb3JhbmdlcmVkOjE2NzI5MzQ0LG9yY2hpZDoxNDMxNTczNCxwYWxlZ29sZGVucm9kOjE1NjU3MTMwLHBhbGVncmVlbjoxMDAyNTg4MCxwYWxldHVycXVvaXNlOjExNTI5OTY2LHBhbGV2aW9sZXRyZWQ6MTQzODEyMDMscGFwYXlhd2hpcDoxNjc3MzA3NyxwZWFjaHB1ZmY6MTY3Njc2NzMscGVydToxMzQ2ODk5MSxwaW5rOjE2NzYxMDM1LHBsdW06MTQ1MjQ2MzcscG93ZGVyYmx1ZToxMTU5MTkxMCxwdXJwbGU6ODM4ODczNixyZWJlY2NhcHVycGxlOjY2OTc4ODEscmVkOjE2NzExNjgwLHJvc3licm93bjoxMjM1NzUxOSxyb3lhbGJsdWU6NDI4Njk0NSxzYWRkbGVicm93bjo5MTI3MTg3LHNhbG1vbjoxNjQxNjg4MixzYW5keWJyb3duOjE2MDMyODY0LHNlYWdyZWVuOjMwNTAzMjcsc2Vhc2hlbGw6MTY3NzQ2Mzgsc2llbm5hOjEwNTA2Nzk3LHNpbHZlcjoxMjYzMjI1Nixza3libHVlOjg5MDAzMzEsc2xhdGVibHVlOjY5NzAwNjEsc2xhdGVncmF5OjczNzI5NDQsc2xhdGVncmV5OjczNzI5NDQsc25vdzoxNjc3NTkzMCxzcHJpbmdncmVlbjo2NTQwNyxzdGVlbGJsdWU6NDYyMDk4MCx0YW46MTM4MDg3ODAsdGVhbDozMjg5Nix0aGlzdGxlOjE0MjA0ODg4LHRvbWF0bzoxNjczNzA5NSx0dXJxdW9pc2U6NDI1MTg1Nix2aW9sZXQ6MTU2MzEwODYsd2hlYXQ6MTYxMTMzMzEsd2hpdGU6MTY3NzcyMTUsd2hpdGVzbW9rZToxNjExOTI4NSx5ZWxsb3c6MTY3NzY5NjAseWVsbG93Z3JlZW46MTAxNDUwNzR9O0thKEtpLG5zLHtjb3B5KGkpe3JldHVybiBPYmplY3QuYXNzaWduKG5ldyB0aGlzLmNvbnN0cnVjdG9yLHRoaXMsaSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuIHRoaXMucmdiKCkuZGlzcGxheWFibGUoKX0saGV4OnN1LGZvcm1hdEhleDpzdSxmb3JtYXRIZXg4OlNtLGZvcm1hdEhzbDp2bSxmb3JtYXRSZ2I6cnUsdG9TdHJpbmc6cnV9KTtmdW5jdGlvbiBzdSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleCgpfWZ1bmN0aW9uIFNtKCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0SGV4OCgpfWZ1bmN0aW9uIHZtKCl7cmV0dXJuIGh1KHRoaXMpLmZvcm1hdEhzbCgpfWZ1bmN0aW9uIHJ1KCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0UmdiKCl9ZnVuY3Rpb24gbnMoaSl7dmFyIHQsZTtyZXR1cm4gaT0oaSsiIikudHJpbSgpLnRvTG93ZXJDYXNlKCksKHQ9Z20uZXhlYyhpKSk/KGU9dFsxXS5sZW5ndGgsdD1wYXJzZUludCh0WzFdLDE2KSxlPT09Nj9vdSh0KTplPT09Mz9uZXcgT3QodD4+OCYxNXx0Pj40JjI0MCx0Pj40JjE1fHQmMjQwLCh0JjE1KTw8NHx0JjE1LDEpOmU9PT04P09yKHQ+PjI0JjI1NSx0Pj4xNiYyNTUsdD4+OCYyNTUsKHQmMjU1KS8yNTUpOmU9PT00P09yKHQ+PjEyJjE1fHQ+PjgmMjQwLHQ+PjgmMTV8dD4+NCYyNDAsdD4+NCYxNXx0JjI0MCwoKHQmMTUpPDw0fHQmMTUpLzI1NSk6bnVsbCk6KHQ9eG0uZXhlYyhpKSk/bmV3IE90KHRbMV0sdFsyXSx0WzNdLDEpOih0PXdtLmV4ZWMoaSkpP25ldyBPdCh0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCwxKToodD1ibS5leGVjKGkpKT9Pcih0WzFdLHRbMl0sdFszXSx0WzRdKToodD1NbS5leGVjKGkpKT9Pcih0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCx0WzRdKToodD1BbS5leGVjKGkpKT9sdSh0WzFdLHRbMl0vMTAwLHRbM10vMTAwLDEpOih0PV9tLmV4ZWMoaSkpP2x1KHRbMV0sdFsyXS8xMDAsdFszXS8xMDAsdFs0XSk6aXUuaGFzT3duUHJvcGVydHkoaSk/b3UoaXVbaV0pOmk9PT0idHJhbnNwYXJlbnQiP25ldyBPdChOYU4sTmFOLE5hTiwwKTpudWxsfWZ1bmN0aW9uIG91KGkpe3JldHVybiBuZXcgT3QoaT4+MTYmMjU1LGk+PjgmMjU1LGkmMjU1LDEpfWZ1bmN0aW9uIE9yKGksdCxlLG4pe3JldHVybiBuPD0wJiYoaT10PWU9TmFOKSxuZXcgT3QoaSx0LGUsbil9ZnVuY3Rpb24gem0oaSl7cmV0dXJuIGkgaW5zdGFuY2VvZiBLaXx8KGk9bnMoaSkpLGk/KGk9aS5yZ2IoKSxuZXcgT3QoaS5yLGkuZyxpLmIsaS5vcGFjaXR5KSk6bmV3IE90fWZ1bmN0aW9uIHRjKGksdCxlLG4pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT96bShpKTpuZXcgT3QoaSx0LGUsbj09bnVsbD8xOm4pfWZ1bmN0aW9uIE90KGksdCxlLG4pe3RoaXMucj0raSx0aGlzLmc9K3QsdGhpcy5iPStlLHRoaXMub3BhY2l0eT0rbn1LYShPdCx0YyxudShLaSx7YnJpZ2h0ZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9McjpNYXRoLnBvdyhMcixpKSxuZXcgT3QodGhpcy5yKmksdGhpcy5nKmksdGhpcy5iKmksdGhpcy5vcGFjaXR5KX0sZGFya2VyKGkpe3JldHVybiBpPWk9PW51bGw/dHM6TWF0aC5wb3codHMsaSksbmV3IE90KHRoaXMucippLHRoaXMuZyppLHRoaXMuYippLHRoaXMub3BhY2l0eSl9LHJnYigpe3JldHVybiB0aGlzfSxjbGFtcCgpe3JldHVybiBuZXcgT3Qoem4odGhpcy5yKSx6bih0aGlzLmcpLHpuKHRoaXMuYiksRHIodGhpcy5vcGFjaXR5KSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuLS41PD10aGlzLnImJnRoaXMucjwyNTUuNSYmLS41PD10aGlzLmcmJnRoaXMuZzwyNTUuNSYmLS41PD10aGlzLmImJnRoaXMuYjwyNTUuNSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGhleDphdSxmb3JtYXRIZXg6YXUsZm9ybWF0SGV4ODpUbSxmb3JtYXRSZ2I6Y3UsdG9TdHJpbmc6Y3V9KSk7ZnVuY3Rpb24gYXUoKXtyZXR1cm5gIyR7VG4odGhpcy5yKX0ke1RuKHRoaXMuZyl9JHtUbih0aGlzLmIpfWB9ZnVuY3Rpb24gVG0oKXtyZXR1cm5gIyR7VG4odGhpcy5yKX0ke1RuKHRoaXMuZyl9JHtUbih0aGlzLmIpfSR7VG4oKGlzTmFOKHRoaXMub3BhY2l0eSk/MTp0aGlzLm9wYWNpdHkpKjI1NSl9YH1mdW5jdGlvbiBjdSgpe2NvbnN0IGk9RHIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8icmdiKCI6InJnYmEoIn0ke3puKHRoaXMucil9LCAke3puKHRoaXMuZyl9LCAke3puKHRoaXMuYil9JHtpPT09MT8iKSI6YCwgJHtpfSlgfWB9ZnVuY3Rpb24gRHIoaSl7cmV0dXJuIGlzTmFOKGkpPzE6TWF0aC5tYXgoMCxNYXRoLm1pbigxLGkpKX1mdW5jdGlvbiB6bihpKXtyZXR1cm4gTWF0aC5tYXgoMCxNYXRoLm1pbigyNTUsTWF0aC5yb3VuZChpKXx8MCkpfWZ1bmN0aW9uIFRuKGkpe3JldHVybiBpPXpuKGkpLChpPDE2PyIwIjoiIikraS50b1N0cmluZygxNil9ZnVuY3Rpb24gbHUoaSx0LGUsbil7cmV0dXJuIG48PTA/aT10PWU9TmFOOmU8PTB8fGU+PTE/aT10PU5hTjp0PD0wJiYoaT1OYU4pLG5ldyB5ZShpLHQsZSxuKX1mdW5jdGlvbiBodShpKXtpZihpIGluc3RhbmNlb2YgeWUpcmV0dXJuIG5ldyB5ZShpLmgsaS5zLGkubCxpLm9wYWNpdHkpO2lmKGkgaW5zdGFuY2VvZiBLaXx8KGk9bnMoaSkpLCFpKXJldHVybiBuZXcgeWU7aWYoaSBpbnN0YW5jZW9mIHllKXJldHVybiBpO2k9aS5yZ2IoKTt2YXIgdD1pLnIvMjU1LGU9aS5nLzI1NSxuPWkuYi8yNTUscz1NYXRoLm1pbih0LGUsbikscj1NYXRoLm1heCh0LGUsbiksbz1OYU4sYT1yLXMsYz0ocitzKS8yO3JldHVybiBhPyh0PT09cj9vPShlLW4pL2ErKGU8bikqNjplPT09cj9vPShuLXQpL2ErMjpvPSh0LWUpL2ErNCxhLz1jPC41P3IrczoyLXItcyxvKj02MCk6YT1jPjAmJmM8MT8wOm8sbmV3IHllKG8sYSxjLGkub3BhY2l0eSl9ZnVuY3Rpb24gRW0oaSx0LGUsbil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg9PT0xP2h1KGkpOm5ldyB5ZShpLHQsZSxuPT1udWxsPzE6bil9ZnVuY3Rpb24geWUoaSx0LGUsbil7dGhpcy5oPStpLHRoaXMucz0rdCx0aGlzLmw9K2UsdGhpcy5vcGFjaXR5PStufUthKHllLEVtLG51KEtpLHticmlnaHRlcihpKXtyZXR1cm4gaT1pPT1udWxsP0xyOk1hdGgucG93KExyLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LGRhcmtlcihpKXtyZXR1cm4gaT1pPT1udWxsP3RzOk1hdGgucG93KHRzLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LHJnYigpe3ZhciBpPXRoaXMuaCUzNjArKHRoaXMuaDwwKSozNjAsdD1pc05hTihpKXx8aXNOYU4odGhpcy5zKT8wOnRoaXMucyxlPXRoaXMubCxuPWUrKGU8LjU/ZToxLWUpKnQscz0yKmUtbjtyZXR1cm4gbmV3IE90KGVjKGk+PTI0MD9pLTI0MDppKzEyMCxzLG4pLGVjKGkscyxuKSxlYyhpPDEyMD9pKzI0MDppLTEyMCxzLG4pLHRoaXMub3BhY2l0eSl9LGNsYW1wKCl7cmV0dXJuIG5ldyB5ZSh1dSh0aGlzLmgpLCRyKHRoaXMucyksJHIodGhpcy5sKSxEcih0aGlzLm9wYWNpdHkpKX0sZGlzcGxheWFibGUoKXtyZXR1cm4oMDw9dGhpcy5zJiZ0aGlzLnM8PTF8fGlzTmFOKHRoaXMucykpJiYwPD10aGlzLmwmJnRoaXMubDw9MSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGZvcm1hdEhzbCgpe2NvbnN0IGk9RHIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8iaHNsKCI6ImhzbGEoIn0ke3V1KHRoaXMuaCl9LCAkeyRyKHRoaXMucykqMTAwfSUsICR7JHIodGhpcy5sKSoxMDB9JSR7aT09PTE/IikiOmAsICR7aX0pYH1gfX0pKTtmdW5jdGlvbiB1dShpKXtyZXR1cm4gaT0oaXx8MCklMzYwLGk8MD9pKzM2MDppfWZ1bmN0aW9uICRyKGkpe3JldHVybiBNYXRoLm1heCgwLE1hdGgubWluKDEsaXx8MCkpfWZ1bmN0aW9uIGVjKGksdCxlKXtyZXR1cm4oaTw2MD90KyhlLXQpKmkvNjA6aTwxODA/ZTppPDI0MD90KyhlLXQpKigyNDAtaSkvNjA6dCkqMjU1fXZhciBuYz1pPT4oKT0+aTtmdW5jdGlvbiBQbShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gaStlKnR9fWZ1bmN0aW9uIENtKGksdCxlKXtyZXR1cm4gaT1NYXRoLnBvdyhpLGUpLHQ9TWF0aC5wb3codCxlKS1pLGU9MS9lLGZ1bmN0aW9uKG4pe3JldHVybiBNYXRoLnBvdyhpK24qdCxlKX19ZnVuY3Rpb24gQm0oaSl7cmV0dXJuKGk9K2kpPT0xP2Z1OmZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUtdD9DbSh0LGUsaSk6bmMoaXNOYU4odCk/ZTp0KX19ZnVuY3Rpb24gZnUoaSx0KXt2YXIgZT10LWk7cmV0dXJuIGU/UG0oaSxlKTpuYyhpc05hTihpKT90OmkpfXZhciBkdT1mdW5jdGlvbiBpKHQpe3ZhciBlPUJtKHQpO2Z1bmN0aW9uIG4ocyxyKXt2YXIgbz1lKChzPXRjKHMpKS5yLChyPXRjKHIpKS5yKSxhPWUocy5nLHIuZyksYz1lKHMuYixyLmIpLGw9ZnUocy5vcGFjaXR5LHIub3BhY2l0eSk7cmV0dXJuIGZ1bmN0aW9uKGgpe3JldHVybiBzLnI9byhoKSxzLmc9YShoKSxzLmI9YyhoKSxzLm9wYWNpdHk9bChoKSxzKyIifX1yZXR1cm4gbi5nYW1tYT1pLG59KDEpO2Z1bmN0aW9uIEZtKGksdCl7dHx8KHQ9W10pO3ZhciBlPWk/TWF0aC5taW4odC5sZW5ndGgsaS5sZW5ndGgpOjAsbj10LnNsaWNlKCkscztyZXR1cm4gZnVuY3Rpb24ocil7Zm9yKHM9MDtzPGU7KytzKW5bc109aVtzXSooMS1yKSt0W3NdKnI7cmV0dXJuIG59fWZ1bmN0aW9uIEltKGkpe3JldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoaSkmJiEoaSBpbnN0YW5jZW9mIERhdGFWaWV3KX1mdW5jdGlvbiBrbShpLHQpe3ZhciBlPXQ/dC5sZW5ndGg6MCxuPWk/TWF0aC5taW4oZSxpLmxlbmd0aCk6MCxzPW5ldyBBcnJheShuKSxyPW5ldyBBcnJheShlKSxvO2ZvcihvPTA7bzxuOysrbylzW29dPXJjKGlbb10sdFtvXSk7Zm9yKDtvPGU7KytvKXJbb109dFtvXTtyZXR1cm4gZnVuY3Rpb24oYSl7Zm9yKG89MDtvPG47KytvKXJbb109c1tvXShhKTtyZXR1cm4gcn19ZnVuY3Rpb24gTm0oaSx0KXt2YXIgZT1uZXcgRGF0ZTtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKG4pe3JldHVybiBlLnNldFRpbWUoaSooMS1uKSt0Km4pLGV9fWZ1bmN0aW9uIFVyKGksdCl7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihlKXtyZXR1cm4gaSooMS1lKSt0KmV9fWZ1bmN0aW9uIFJtKGksdCl7dmFyIGU9e30sbj17fSxzOyhpPT09bnVsbHx8dHlwZW9mIGkhPSJvYmplY3QiKSYmKGk9e30pLCh0PT09bnVsbHx8dHlwZW9mIHQhPSJvYmplY3QiKSYmKHQ9e30pO2ZvcihzIGluIHQpcyBpbiBpP2Vbc109cmMoaVtzXSx0W3NdKTpuW3NdPXRbc107cmV0dXJuIGZ1bmN0aW9uKHIpe2ZvcihzIGluIGUpbltzXT1lW3NdKHIpO3JldHVybiBufX12YXIgaWM9L1stK10/KD86XGQrXC4/XGQqfFwuP1xkKykoPzpbZUVdWy0rXT9cZCspPy9nLHNjPW5ldyBSZWdFeHAoaWMuc291cmNlLCJnIik7ZnVuY3Rpb24gTG0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIE9tKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gaSh0KSsiIn19ZnVuY3Rpb24gRG0oaSx0KXt2YXIgZT1pYy5sYXN0SW5kZXg9c2MubGFzdEluZGV4PTAsbixzLHIsbz0tMSxhPVtdLGM9W107Zm9yKGk9aSsiIix0PXQrIiI7KG49aWMuZXhlYyhpKSkmJihzPXNjLmV4ZWModCkpOykocj1zLmluZGV4KT5lJiYocj10LnNsaWNlKGUsciksYVtvXT9hW29dKz1yOmFbKytvXT1yKSwobj1uWzBdKT09PShzPXNbMF0pP2Fbb10/YVtvXSs9czphWysrb109czooYVsrK29dPW51bGwsYy5wdXNoKHtpOm8seDpVcihuLHMpfSkpLGU9c2MubGFzdEluZGV4O3JldHVybiBlPHQubGVuZ3RoJiYocj10LnNsaWNlKGUpLGFbb10/YVtvXSs9cjphWysrb109ciksYS5sZW5ndGg8Mj9jWzBdP09tKGNbMF0ueCk6TG0odCk6KHQ9Yy5sZW5ndGgsZnVuY3Rpb24obCl7Zm9yKHZhciBoPTAsdTtoPHQ7KytoKWFbKHU9Y1toXSkuaV09dS54KGwpO3JldHVybiBhLmpvaW4oIiIpfSl9ZnVuY3Rpb24gcmMoaSx0KXt2YXIgZT10eXBlb2YgdCxuO3JldHVybiB0PT1udWxsfHxlPT09ImJvb2xlYW4iP25jKHQpOihlPT09Im51bWJlciI/VXI6ZT09PSJzdHJpbmciPyhuPW5zKHQpKT8odD1uLGR1KTpEbTp0IGluc3RhbmNlb2YgbnM/ZHU6dCBpbnN0YW5jZW9mIERhdGU/Tm06SW0odCk/Rm06QXJyYXkuaXNBcnJheSh0KT9rbTp0eXBlb2YgdC52YWx1ZU9mIT0iZnVuY3Rpb24iJiZ0eXBlb2YgdC50b1N0cmluZyE9ImZ1bmN0aW9uInx8aXNOYU4odCk/Um06VXIpKGksdCl9ZnVuY3Rpb24gJG0oaSx0KXtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKGUpe3JldHVybiBNYXRoLnJvdW5kKGkqKDEtZSkrdCplKX19ZnVuY3Rpb24gVW0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIFZtKGkpe3JldHVybitpfXZhciBwdT1bMCwxXTtmdW5jdGlvbiB1aShpKXtyZXR1cm4gaX1mdW5jdGlvbiBvYyhpLHQpe3JldHVybih0LT1pPStpKT9mdW5jdGlvbihlKXtyZXR1cm4oZS1pKS90fTpVbShpc05hTih0KT9OYU46LjUpfWZ1bmN0aW9uIHFtKGksdCl7dmFyIGU7cmV0dXJuIGk+dCYmKGU9aSxpPXQsdD1lKSxmdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5tYXgoaSxNYXRoLm1pbih0LG4pKX19ZnVuY3Rpb24gSG0oaSx0LGUpe3ZhciBuPWlbMF0scz1pWzFdLHI9dFswXSxvPXRbMV07cmV0dXJuIHM8bj8obj1vYyhzLG4pLHI9ZShvLHIpKToobj1vYyhuLHMpLHI9ZShyLG8pKSxmdW5jdGlvbihhKXtyZXR1cm4gcihuKGEpKX19ZnVuY3Rpb24gV20oaSx0LGUpe3ZhciBuPU1hdGgubWluKGkubGVuZ3RoLHQubGVuZ3RoKS0xLHM9bmV3IEFycmF5KG4pLHI9bmV3IEFycmF5KG4pLG89LTE7Zm9yKGlbbl08aVswXSYmKGk9aS5zbGljZSgpLnJldmVyc2UoKSx0PXQuc2xpY2UoKS5yZXZlcnNlKCkpOysrbzxuOylzW29dPW9jKGlbb10saVtvKzFdKSxyW29dPWUodFtvXSx0W28rMV0pO3JldHVybiBmdW5jdGlvbihhKXt2YXIgYz1IMChpLGEsMSxuKS0xO3JldHVybiByW2NdKHNbY10oYSkpfX1mdW5jdGlvbiBHbShpLHQpe3JldHVybiB0LmRvbWFpbihpLmRvbWFpbigpKS5yYW5nZShpLnJhbmdlKCkpLmludGVycG9sYXRlKGkuaW50ZXJwb2xhdGUoKSkuY2xhbXAoaS5jbGFtcCgpKS51bmtub3duKGkudW5rbm93bigpKX1mdW5jdGlvbiBabSgpe3ZhciBpPXB1LHQ9cHUsZT1yYyxuLHMscixvPXVpLGEsYyxsO2Z1bmN0aW9uIGgoKXt2YXIgZj1NYXRoLm1pbihpLmxlbmd0aCx0Lmxlbmd0aCk7cmV0dXJuIG8hPT11aSYmKG89cW0oaVswXSxpW2YtMV0pKSxhPWY+Mj9XbTpIbSxjPWw9bnVsbCx1fWZ1bmN0aW9uIHUoZil7cmV0dXJuIGY9PW51bGx8fGlzTmFOKGY9K2YpP3I6KGN8fChjPWEoaS5tYXAobiksdCxlKSkpKG4obyhmKSkpfXJldHVybiB1LmludmVydD1mdW5jdGlvbihmKXtyZXR1cm4gbyhzKChsfHwobD1hKHQsaS5tYXAobiksVXIpKSkoZikpKX0sdS5kb21haW49ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGk9QXJyYXkuZnJvbShmLFZtKSxoKCkpOmkuc2xpY2UoKX0sdS5yYW5nZT1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odD1BcnJheS5mcm9tKGYpLGgoKSk6dC5zbGljZSgpfSx1LnJhbmdlUm91bmQ9ZnVuY3Rpb24oZil7cmV0dXJuIHQ9QXJyYXkuZnJvbShmKSxlPSRtLGgoKX0sdS5jbGFtcD1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obz1mPyEwOnVpLGgoKSk6byE9PXVpfSx1LmludGVycG9sYXRlPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhlPWYsaCgpKTplfSx1LnVua25vd249ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHI9Zix1KTpyfSxmdW5jdGlvbihmLGQpe3JldHVybiBuPWYscz1kLGgoKX19ZnVuY3Rpb24gWG0oKXtyZXR1cm4gWm0oKSh1aSx1aSl9ZnVuY3Rpb24gSm0oaSl7cmV0dXJuIE1hdGguYWJzKGk9TWF0aC5yb3VuZChpKSk+PTFlMjE/aS50b0xvY2FsZVN0cmluZygiZW4iKS5yZXBsYWNlKC8sL2csIiIpOmkudG9TdHJpbmcoMTApfWZ1bmN0aW9uIFZyKGksdCl7aWYoKGU9KGk9dD9pLnRvRXhwb25lbnRpYWwodC0xKTppLnRvRXhwb25lbnRpYWwoKSkuaW5kZXhPZigiZSIpKTwwKXJldHVybiBudWxsO3ZhciBlLG49aS5zbGljZSgwLGUpO3JldHVybltuLmxlbmd0aD4xP25bMF0rbi5zbGljZSgyKTpuLCtpLnNsaWNlKGUrMSldfWZ1bmN0aW9uIGZpKGkpe3JldHVybiBpPVZyKE1hdGguYWJzKGkpKSxpP2lbMV06TmFOfWZ1bmN0aW9uIFltKGksdCl7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Zm9yKHZhciBzPWUubGVuZ3RoLHI9W10sbz0wLGE9aVswXSxjPTA7cz4wJiZhPjAmJihjK2ErMT5uJiYoYT1NYXRoLm1heCgxLG4tYykpLHIucHVzaChlLnN1YnN0cmluZyhzLT1hLHMrYSkpLCEoKGMrPWErMSk+bikpOylhPWlbbz0obysxKSVpLmxlbmd0aF07cmV0dXJuIHIucmV2ZXJzZSgpLmpvaW4odCl9fWZ1bmN0aW9uIGptKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdC5yZXBsYWNlKC9bMC05XS9nLGZ1bmN0aW9uKGUpe3JldHVybiBpWytlXX0pfX12YXIgUW09L14oPzooLik/KFs8Pj1eXSkpPyhbK1wtKCBdKT8oWyQjXSk/KDApPyhcZCspPygsKT8oXC5cZCspPyh+KT8oW2EteiVdKT8kL2k7ZnVuY3Rpb24gcXIoaSl7aWYoISh0PVFtLmV4ZWMoaSkpKXRocm93IG5ldyBFcnJvcigiaW52YWxpZCBmb3JtYXQ6ICIraSk7dmFyIHQ7cmV0dXJuIG5ldyBhYyh7ZmlsbDp0WzFdLGFsaWduOnRbMl0sc2lnbjp0WzNdLHN5bWJvbDp0WzRdLHplcm86dFs1XSx3aWR0aDp0WzZdLGNvbW1hOnRbN10scHJlY2lzaW9uOnRbOF0mJnRbOF0uc2xpY2UoMSksdHJpbTp0WzldLHR5cGU6dFsxMF19KX1xci5wcm90b3R5cGU9YWMucHJvdG90eXBlO2Z1bmN0aW9uIGFjKGkpe3RoaXMuZmlsbD1pLmZpbGw9PT12b2lkIDA/IiAiOmkuZmlsbCsiIix0aGlzLmFsaWduPWkuYWxpZ249PT12b2lkIDA/Ij4iOmkuYWxpZ24rIiIsdGhpcy5zaWduPWkuc2lnbj09PXZvaWQgMD8iLSI6aS5zaWduKyIiLHRoaXMuc3ltYm9sPWkuc3ltYm9sPT09dm9pZCAwPyIiOmkuc3ltYm9sKyIiLHRoaXMuemVybz0hIWkuemVybyx0aGlzLndpZHRoPWkud2lkdGg9PT12b2lkIDA/dm9pZCAwOitpLndpZHRoLHRoaXMuY29tbWE9ISFpLmNvbW1hLHRoaXMucHJlY2lzaW9uPWkucHJlY2lzaW9uPT09dm9pZCAwP3ZvaWQgMDoraS5wcmVjaXNpb24sdGhpcy50cmltPSEhaS50cmltLHRoaXMudHlwZT1pLnR5cGU9PT12b2lkIDA/IiI6aS50eXBlKyIifWFjLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmZpbGwrdGhpcy5hbGlnbit0aGlzLnNpZ24rdGhpcy5zeW1ib2wrKHRoaXMuemVybz8iMCI6IiIpKyh0aGlzLndpZHRoPT09dm9pZCAwPyIiOk1hdGgubWF4KDEsdGhpcy53aWR0aHwwKSkrKHRoaXMuY29tbWE/IiwiOiIiKSsodGhpcy5wcmVjaXNpb249PT12b2lkIDA/IiI6Ii4iK01hdGgubWF4KDAsdGhpcy5wcmVjaXNpb258MCkpKyh0aGlzLnRyaW0/In4iOiIiKSt0aGlzLnR5cGV9O2Z1bmN0aW9uIEttKGkpe3Q6Zm9yKHZhciB0PWkubGVuZ3RoLGU9MSxuPS0xLHM7ZTx0OysrZSlzd2l0Y2goaVtlXSl7Y2FzZSIuIjpuPXM9ZTticmVhaztjYXNlIjAiOm49PT0wJiYobj1lKSxzPWU7YnJlYWs7ZGVmYXVsdDppZighK2lbZV0pYnJlYWsgdDtuPjAmJihuPTApO2JyZWFrfXJldHVybiBuPjA/aS5zbGljZSgwLG4pK2kuc2xpY2UocysxKTppfXZhciB5dTtmdW5jdGlvbiB0ZyhpLHQpe3ZhciBlPVZyKGksdCk7aWYoIWUpcmV0dXJuIGkrIiI7dmFyIG49ZVswXSxzPWVbMV0scj1zLSh5dT1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3Iocy8zKSkpKjMpKzEsbz1uLmxlbmd0aDtyZXR1cm4gcj09PW8/bjpyPm8/bituZXcgQXJyYXkoci1vKzEpLmpvaW4oIjAiKTpyPjA/bi5zbGljZSgwLHIpKyIuIituLnNsaWNlKHIpOiIwLiIrbmV3IEFycmF5KDEtcikuam9pbigiMCIpK1ZyKGksTWF0aC5tYXgoMCx0K3ItMSkpWzBdfWZ1bmN0aW9uIG11KGksdCl7dmFyIGU9VnIoaSx0KTtpZighZSlyZXR1cm4gaSsiIjt2YXIgbj1lWzBdLHM9ZVsxXTtyZXR1cm4gczwwPyIwLiIrbmV3IEFycmF5KC1zKS5qb2luKCIwIikrbjpuLmxlbmd0aD5zKzE/bi5zbGljZSgwLHMrMSkrIi4iK24uc2xpY2UocysxKTpuK25ldyBBcnJheShzLW4ubGVuZ3RoKzIpLmpvaW4oIjAiKX12YXIgZ3U9eyIlIjooaSx0KT0+KGkqMTAwKS50b0ZpeGVkKHQpLGI6aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZygyKSxjOmk9PmkrIiIsZDpKbSxlOihpLHQpPT5pLnRvRXhwb25lbnRpYWwodCksZjooaSx0KT0+aS50b0ZpeGVkKHQpLGc6KGksdCk9PmkudG9QcmVjaXNpb24odCksbzppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDgpLHA6KGksdCk9Pm11KGkqMTAwLHQpLHI6bXUsczp0ZyxYOmk9Pk1hdGgucm91bmQoaSkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkseDppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDE2KX07ZnVuY3Rpb24geHUoaSl7cmV0dXJuIGl9dmFyIHd1PUFycmF5LnByb3RvdHlwZS5tYXAsYnU9WyJ5IiwieiIsImEiLCJmIiwicCIsIm4iLCLCtSIsIm0iLCIiLCJrIiwiTSIsIkciLCJUIiwiUCIsIkUiLCJaIiwiWSJdO2Z1bmN0aW9uIGVnKGkpe3ZhciB0PWkuZ3JvdXBpbmc9PT12b2lkIDB8fGkudGhvdXNhbmRzPT09dm9pZCAwP3h1OlltKHd1LmNhbGwoaS5ncm91cGluZyxOdW1iZXIpLGkudGhvdXNhbmRzKyIiKSxlPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVswXSsiIixuPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVsxXSsiIixzPWkuZGVjaW1hbD09PXZvaWQgMD8iLiI6aS5kZWNpbWFsKyIiLHI9aS5udW1lcmFscz09PXZvaWQgMD94dTpqbSh3dS5jYWxsKGkubnVtZXJhbHMsU3RyaW5nKSksbz1pLnBlcmNlbnQ9PT12b2lkIDA/IiUiOmkucGVyY2VudCsiIixhPWkubWludXM9PT12b2lkIDA/IuKIkiI6aS5taW51cysiIixjPWkubmFuPT09dm9pZCAwPyJOYU4iOmkubmFuKyIiO2Z1bmN0aW9uIGwodSl7dT1xcih1KTt2YXIgZj11LmZpbGwsZD11LmFsaWduLHA9dS5zaWduLHk9dS5zeW1ib2wsbT11Lnplcm8sZz11LndpZHRoLGI9dS5jb21tYSx3PXUucHJlY2lzaW9uLHg9dS50cmltLE09dS50eXBlO009PT0ibiI/KGI9ITAsTT0iZyIpOmd1W01dfHwodz09PXZvaWQgMCYmKHc9MTIpLHg9ITAsTT0iZyIpLChtfHxmPT09IjAiJiZkPT09Ij0iKSYmKG09ITAsZj0iMCIsZD0iPSIpO3ZhciBBPXk9PT0iJCI/ZTp5PT09IiMiJiYvW2JveFhdLy50ZXN0KE0pPyIwIitNLnRvTG93ZXJDYXNlKCk6IiIsXz15PT09IiQiP246L1slcF0vLnRlc3QoTSk/bzoiIixTPWd1W01dLEU9L1tkZWZncHJzJV0vLnRlc3QoTSk7dz13PT09dm9pZCAwPzY6L1tncHJzXS8udGVzdChNKT9NYXRoLm1heCgxLE1hdGgubWluKDIxLHcpKTpNYXRoLm1heCgwLE1hdGgubWluKDIwLHcpKTtmdW5jdGlvbiB6KHYpe3ZhciBDPUEsUD1fLEYsQixJO2lmKE09PT0iYyIpUD1TKHYpK1Asdj0iIjtlbHNle3Y9K3Y7dmFyIGs9djwwfHwxL3Y8MDtpZih2PWlzTmFOKHYpP2M6UyhNYXRoLmFicyh2KSx3KSx4JiYodj1LbSh2KSksayYmK3Y9PTAmJnAhPT0iKyImJihrPSExKSxDPShrP3A9PT0iKCI/cDphOnA9PT0iLSJ8fHA9PT0iKCI/IiI6cCkrQyxQPShNPT09InMiP2J1WzgreXUvM106IiIpK1ArKGsmJnA9PT0iKCI/IikiOiIiKSxFKXtmb3IoRj0tMSxCPXYubGVuZ3RoOysrRjxCOylpZihJPXYuY2hhckNvZGVBdChGKSw0OD5JfHxJPjU3KXtQPShJPT09NDY/cyt2LnNsaWNlKEYrMSk6di5zbGljZShGKSkrUCx2PXYuc2xpY2UoMCxGKTticmVha319fWImJiFtJiYodj10KHYsMS8wKSk7dmFyIEQ9Qy5sZW5ndGgrdi5sZW5ndGgrUC5sZW5ndGgsVj1EPGc/bmV3IEFycmF5KGctRCsxKS5qb2luKGYpOiIiO3N3aXRjaChiJiZtJiYodj10KFYrdixWLmxlbmd0aD9nLVAubGVuZ3RoOjEvMCksVj0iIiksZCl7Y2FzZSI8Ijp2PUMrditQK1Y7YnJlYWs7Y2FzZSI9Ijp2PUMrVit2K1A7YnJlYWs7Y2FzZSJeIjp2PVYuc2xpY2UoMCxEPVYubGVuZ3RoPj4xKStDK3YrUCtWLnNsaWNlKEQpO2JyZWFrO2RlZmF1bHQ6dj1WK0MrditQO2JyZWFrfXJldHVybiByKHYpfXJldHVybiB6LnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHUrIiJ9LHp9ZnVuY3Rpb24gaCh1LGYpe3ZhciBkPWwoKHU9cXIodSksdS50eXBlPSJmIix1KSkscD1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3IoZmkoZikvMykpKSozLHk9TWF0aC5wb3coMTAsLXApLG09YnVbOCtwLzNdO3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZCh5KmcpK219fXJldHVybntmb3JtYXQ6bCxmb3JtYXRQcmVmaXg6aH19dmFyIEhyLE11LEF1O25nKHt0aG91c2FuZHM6IiwiLGdyb3VwaW5nOlszXSxjdXJyZW5jeTpbIiQiLCIiXX0pO2Z1bmN0aW9uIG5nKGkpe3JldHVybiBIcj1lZyhpKSxNdT1Ici5mb3JtYXQsQXU9SHIuZm9ybWF0UHJlZml4LEhyfWZ1bmN0aW9uIGlnKGkpe3JldHVybiBNYXRoLm1heCgwLC1maShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIHNnKGksdCl7cmV0dXJuIE1hdGgubWF4KDAsTWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKGZpKHQpLzMpKSkqMy1maShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIHJnKGksdCl7cmV0dXJuIGk9TWF0aC5hYnMoaSksdD1NYXRoLmFicyh0KS1pLE1hdGgubWF4KDAsZmkodCktZmkoaSkpKzF9ZnVuY3Rpb24gb2coaSx0LGUsbil7dmFyIHM9SjAoaSx0LGUpLHI7c3dpdGNoKG49cXIobj09bnVsbD8iLGYiOm4pLG4udHlwZSl7Y2FzZSJzIjp7dmFyIG89TWF0aC5tYXgoTWF0aC5hYnMoaSksTWF0aC5hYnModCkpO3JldHVybiBuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9c2cocyxvKSkmJihuLnByZWNpc2lvbj1yKSxBdShuLG8pfWNhc2UiIjpjYXNlImUiOmNhc2UiZyI6Y2FzZSJwIjpjYXNlInIiOntuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9cmcocyxNYXRoLm1heChNYXRoLmFicyhpKSxNYXRoLmFicyh0KSkpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSJlIikpO2JyZWFrfWNhc2UiZiI6Y2FzZSIlIjp7bi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPWlnKHMpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSIlIikqMik7YnJlYWt9fXJldHVybiBNdShuKX1mdW5jdGlvbiBhZyhpKXt2YXIgdD1pLmRvbWFpbjtyZXR1cm4gaS50aWNrcz1mdW5jdGlvbihlKXt2YXIgbj10KCk7cmV0dXJuIFgwKG5bMF0sbltuLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUpfSxpLnRpY2tGb3JtYXQ9ZnVuY3Rpb24oZSxuKXt2YXIgcz10KCk7cmV0dXJuIG9nKHNbMF0sc1tzLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUsbil9LGkubmljZT1mdW5jdGlvbihlKXtlPT1udWxsJiYoZT0xMCk7dmFyIG49dCgpLHM9MCxyPW4ubGVuZ3RoLTEsbz1uW3NdLGE9bltyXSxjLGwsaD0xMDtmb3IoYTxvJiYobD1vLG89YSxhPWwsbD1zLHM9cixyPWwpO2gtLSA+MDspe2lmKGw9Z2EobyxhLGUpLGw9PT1jKXJldHVybiBuW3NdPW8sbltyXT1hLHQobik7aWYobD4wKW89TWF0aC5mbG9vcihvL2wpKmwsYT1NYXRoLmNlaWwoYS9sKSpsO2Vsc2UgaWYobDwwKW89TWF0aC5jZWlsKG8qbCkvbCxhPU1hdGguZmxvb3IoYSpsKS9sO2Vsc2UgYnJlYWs7Yz1sfXJldHVybiBpfSxpfWZ1bmN0aW9uIGNjKCl7dmFyIGk9WG0oKTtyZXR1cm4gaS5jb3B5PWZ1bmN0aW9uKCl7cmV0dXJuIEdtKGksY2MoKSl9LG1tLmFwcGx5KGksYXJndW1lbnRzKSxhZyhpKX1mdW5jdGlvbiBjZyhpLHQpe3JldHVybiBpLm1hcChlPT57Y29uc3Qgbj1bXTtsZXQgcztyZXR1cm4gZS5mb3JFYWNoKHI9PntpZihzKXtjb25zdCBvPXNpKHIscykqMTgwL01hdGguUEk7aWYobz50KXtjb25zdCBhPUJwKHMsciksYz0xL01hdGguY2VpbChvL3QpO2xldCBsPWM7Zm9yKDtsPDE7KW4ucHVzaChhKGwpKSxsKz1jfX1uLnB1c2gocz1yKX0pLG59KX1mdW5jdGlvbiBsZyhpLHttaW5Mbmc6dCxtYXhMbmc6ZSxtaW5MYXQ6bixtYXhMYXQ6c309e30pe2NvbnN0IHI9TWF0aC5yb3VuZChkaSgzNjAvaSwyKS9NYXRoLlBJKSxvPSgxK01hdGguc3FydCg1KSkvMixhPWQ9PmQvbyozNjAlMzYwLTE4MCxjPWQ9Pk1hdGguYWNvcygyKmQvci0xKS9NYXRoLlBJKjE4MC05MCxsPWQ9PnIqKE1hdGguY29zKChkKzkwKSpNYXRoLlBJLzE4MCkrMSkvMixoPVtzIT09dm9pZCAwP01hdGguY2VpbChsKHMpKTowLG4hPT12b2lkIDA/TWF0aC5mbG9vcihsKG4pKTpyLTFdLHU9dD09PXZvaWQgMCYmZT09PXZvaWQgMD8oKT0+ITA6dD09PXZvaWQgMD9kPT5kPD1lOmU9PT12b2lkIDA/ZD0+ZD49dDplPj10P2Q9PmQ+PXQmJmQ8PWU6ZD0+ZD49dHx8ZDw9ZSxmPVtdO2ZvcihsZXQgZD1oWzBdO2Q8PWhbMV07ZCsrKXtjb25zdCBwPWEoZCk7dShwKSYmZi5wdXNoKFtwLGMoZCldKX1yZXR1cm4gZn1mdW5jdGlvbiBsYyhpLHQsZT0hMSl7cmV0dXJuIGU/Q3AodCxpKTpIeShpLHQpfWZ1bmN0aW9uIGhnKGksdCl7Y29uc3QgZT17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tuLHNdLFtyLG9dXT1paChlKTtpZihNYXRoLm1pbihNYXRoLmFicyhyLW4pLE1hdGguYWJzKG8tcykpPHQpcmV0dXJuW107Y29uc3QgYT1uPnJ8fG8+PTg5fHxzPD0tODk7cmV0dXJuIGxnKHQse21pbkxuZzpuLG1heExuZzpyLG1pbkxhdDpzLG1heExhdDpvfSkuZmlsdGVyKGM9PmxjKGMsZSxhKSl9ZnVuY3Rpb24gdWcoaSx7cmVzb2x1dGlvbjp0PTEvMCxiYm94OmUscHJvamVjdGlvbjpufT17fSl7Y29uc3Qgcz1jZyhpLHQpLHI9RGkocyksbz1oZyhpLHQpLGE9Wy4uLnIsLi4ub10sYz17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tsLGhdLFt1LGZdXT1paChjKSxkPWw+dXx8Zj49ODl8fGg8PS04OTtsZXQgcD1bXTtpZihkKXtjb25zdCBNPXltKGEpLnRyaWFuZ2xlcygpLEE9bmV3IE1hcChhLm1hcCgoW18sU10sRSk9PltgJHtffS0ke1N9YCxFXSkpO00uZmVhdHVyZXMuZm9yRWFjaChfPT57Y29uc3QgUz1fLmdlb21ldHJ5LmNvb3JkaW5hdGVzWzBdLnNsaWNlKDAsMykucmV2ZXJzZSgpLEU9W107aWYoUy5mb3JFYWNoKChbeix2XSk9Pntjb25zdCBDPWAke3p9LSR7dn1gO0EuaGFzKEMpJiZFLnB1c2goQS5nZXQoQykpfSksRS5sZW5ndGg9PT0zKXtpZihFLnNvbWUoej0+ejxyLmxlbmd0aCkpe2NvbnN0IHo9Xy5wcm9wZXJ0aWVzLmNpcmN1bWNlbnRlcjtpZighbGMoeixjLGQpKXJldHVybn1wLnB1c2goLi4uRSl9fSl9ZWxzZSBpZihvLmxlbmd0aCl7Y29uc3QgTT1qaS5mcm9tKGEpO2ZvcihsZXQgQT0wLF89TS50cmlhbmdsZXMubGVuZ3RoO0E8XztBKz0zKXtjb25zdCBTPVsyLDEsMF0ubWFwKHo9Pk0udHJpYW5nbGVzW0Erel0pLEU9Uy5tYXAoej0+YVt6XSk7aWYoUy5zb21lKHo9Pno8ci5sZW5ndGgpKXtjb25zdCB6PVswLDFdLm1hcCh2PT5ZMChFLEM9PkNbdl0pKTtpZighbGMoeixjLGQpKWNvbnRpbnVlfXAucHVzaCguLi5TKX19ZWxzZXtjb25zdHt2ZXJ0aWNlczpNLGhvbGVzOkE9W119PVZoKHMpO3A9YXkoTSxBLDIpfWxldCB5PWU/W2VbMF0sZVsyXV06ZXIoYSxNPT5NWzBdKSxtPWU/W2VbMV0sZVszXV06ZXIoYSxNPT5NWzFdKTtpZihuKXtjb25zdFtNLEFdPW4oW3lbMF0sbVswXV0pLFtfLFNdPW4oW3lbMV0sbVsxXV0pO3k9W00sX10sbT1bLUEsLVNdfWNvbnN0IGc9Y2MoeSxbMCwxXSksYj1jYyhtLFswLDFdKSx3PWEubWFwKChbTSxBXSk9PntpZihuKXtjb25zdFtfLFNdPW4oW00sQV0pO3JldHVybltnKF8pLGIoLVMpXX1lbHNlIHJldHVybltnKE0pLGIoQSldfSk7cmV0dXJue2NvbnRvdXI6cyx0cmlhbmdsZXM6e3BvaW50czphLGluZGljZXM6cCx1dnM6d319fWNvbnN0IF91PW5ldyB1ZSgpLnNldEF0dHJpYnV0ZT8ic2V0QXR0cmlidXRlIjoiYWRkQXR0cmlidXRlIjtmdW5jdGlvbiBXcihpLHQsZSxuKXtjb25zdCBzPWkubWFwKHI9PnIubWFwKChbbyxhXSk9PntpZihuKXtjb25zdFtjLGxdPW4oW28sYV0pO3JldHVybltjLC1sLHRdfXJldHVybiBlPyQwKG8sYSx0KTpbbyxhLHRdfSkpO3JldHVybiBWaChzKX1mdW5jdGlvbiBmZyhpLHQsZSxuLHMpe2NvbnN0e3ZlcnRpY2VzOnIsaG9sZXM6b309V3IoaSx0LG4scykse3ZlcnRpY2VzOmF9PVdyKGksZSxuLHMpLGM9RGkoW2Escl0pLGw9TWF0aC5yb3VuZChhLmxlbmd0aC8zKSxoPW5ldyBTZXQobyk7bGV0IHU9MDtjb25zdCBmPVtdO2ZvcihsZXQgcD0wO3A8bDtwKyspe2xldCB5PXArMTtpZih5PT09bCl5PXU7ZWxzZSBpZihoLmhhcyh5KSl7Y29uc3QgbT15O3k9dSx1PW19Zi5wdXNoKHAscCtsLHkrbCksZi5wdXNoKHkrbCx5LHApfWNvbnN0IGQ9W107Zm9yKGxldCBwPTE7cD49MDtwLS0pZm9yKGxldCB5PTA7eTxsO3krPTEpZC5wdXNoKHkvKGwtMSkscCk7cmV0dXJue2luZGljZXM6Zix2ZXJ0aWNlczpjLHV2czpkLHRvcFZlcnRzOmF9fWZ1bmN0aW9uIFN1KGksdCxlLG4scyxyKXtyZXR1cm57aW5kaWNlczpuP2kuaW5kaWNlczppLmluZGljZXMuc2xpY2UoKS5yZXZlcnNlKCksdmVydGljZXM6V3IoW2kucG9pbnRzXSx0LHMscikudmVydGljZXMsdXZzOmV9fWNvbnN0IHZ1PSh7cG9seWdvbkdlb0pzb246aSxzdGFydEhlaWdodDp0LGVuZEhlaWdodDplLGN1cnZhdHVyZVJlc29sdXRpb246bj0xLGNhcnRlc2lhbjpzPSEwLGhhc1NpZGU6cj0hMCxoYXNCb3R0b206bz0hMSxoYXNUb3A6YT0hMSxwcm9qZWN0aW9uOmMsYmJveDpsfSk9PntpLmZvckVhY2goZz0+e0V5KGcpfHxnLnJldmVyc2UoKX0pO2NvbnN0e2NvbnRvdXI6aCx0cmlhbmdsZXM6dX09dWcoaSx7cmVzb2x1dGlvbjpuLGJib3g6bCxwcm9qZWN0aW9uOmN9KTtsZXQgZj17fSxkO3ImJihmPWZnKGgsdCE9bnVsbD90OmUsZSE9bnVsbD9lOnQscyxjKSxkPWYudG9wVmVydHMpO2xldCBwPVtdOyhvfHxhKSYmKHA9RGkodS51dnMpKTtsZXQgeT17fTtvJiYoeT1TdSh1LHQscCwhMSxzLGMpKTtsZXQgbT17fTtyZXR1cm4gYSYmKG09U3UodSxlLHAsITAscyxjKSkse2NvbnRvdXI6aCx0cmlhbmdsZXM6dSxzaWRlVG9yc286Zixib3R0b21DYXA6eSx0b3BDYXA6bSx0b3BWZXJ0czpkfX07Y2xhc3MgZGcgZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0LGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJQb2x5Z29uQnVmZmVyR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz1GdCh7cG9seWdvbkdlb0pzb246dCxzdGFydEhlaWdodDowLGVuZEhlaWdodDoxLGhhc1RvcDohMCx0b3BGaXJzdDohMSxoYXNCb3R0b206ITAsaGFzU2lkZTohMCxjdXJ2YXR1cmVSZXNvbHV0aW9uOjEsY2FydGVzaWFuOiEwLHVzZXJEYXRhUnNvT2Zmc2V0OjB9LGUpO2NvbnN0e2VuZEhlaWdodDpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHVzZXJEYXRhUnNvT2Zmc2V0OmwscHJvamVjdGlvbjpofT10aGlzLnBhcmFtZXRlcnMse2NvbnRvdXI6dSxzaWRlVG9yc286Zix0b3BWZXJ0czpkLGJvdHRvbUNhcDpwLHRvcENhcDp5fT12dShGdCh7fSx0aGlzLnBhcmFtZXRlcnMpKTtsZXQgbT1bXSxnPVtdLGI9W10sdz0wO2NvbnN0IHg9TT0+e2NvbnN0IEE9TWF0aC5yb3VuZChtLmxlbmd0aC8zKSxfPWIubGVuZ3RoO209bS5jb25jYXQoTS52ZXJ0aWNlcyksZz1nLmNvbmNhdChNLnV2cyksYj1iLmNvbmNhdChBP00uaW5kaWNlcy5tYXAoUz0+UytBKTpNLmluZGljZXMpLHRoaXMuYWRkR3JvdXAoXyxiLmxlbmd0aC1fLHcrKyl9O3MmJnImJngoeSksYSYmKHgoZiksdGhpcy51c2VyRGF0YS50b3BWZXJ0cz1sP1dyKHUsbitsLGMsaCkudmVydGljZXM6ZCksbyYmeChwKSxzJiYhciYmeCh5KSx0aGlzLnNldEluZGV4KGIpLHRoaXNbX3VdKCJwb3NpdGlvbiIsbmV3IENlKG0sMykpLHRoaXNbX3VdKCJ1diIsbmV3IENlKGcsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKX19dmFyIHBnPWk9Pntjb25zdCBhPWkse2Nvb3JkaW5hdGU6dCxzdGFydEhlaWdodDplLGhlaWdodDpufT1hLHM9RHUoYSxbImNvb3JkaW5hdGUiLCJzdGFydEhlaWdodCIsImhlaWdodCJdKTtsZXQgcj1lfHwwO3JldHVybiB0eXBlb2YgZSE9InVuZGVmaW5lZCImJnR5cGVvZiBuIT0idW5kZWZpbmVkIiYmKHI9ZStuKSxuZXcgZGcoW3RdLEdlKEZ0KHt9LHMpLHtzdGFydEhlaWdodDplLGVuZEhlaWdodDpyfSkpfTtjb25zdCB5Zz0oe2Nvb3JkaW5hdGVzQXJyOmksc3RhcnQ6dCxkZXB0aDplLHVzZUdyb3VwczpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHByb2plY3Rpb246bCxjdXJ2YXR1cmVSZXNvbHV0aW9uOmgsYmJveDp1LGJib3hPZmZzZXQ6Zn0pPT57Y29uc3QgZD1sJiZXaShsKTtpZihkJiYoYz0hMSx1JiZmKSl7bGV0IHk9ZChbdVswXSx1WzFdXSksbT1kKFt1WzJdLHVbM11dKTt5WzFdPS15WzFdLG1bMV09LW1bMV0seVswXSs9ZlswXSx5WzFdKz1mWzFdLG1bMF0rPWZbMl0sbVsxXSs9ZlszXSx5PWQuaW52ZXJ0KFt5WzBdLC15WzFdXSl8fHksbT1kLmludmVydChbbVswXSwtbVsxXV0pfHxtLHU9W3lbMF0seVsxXSxtWzBdLG1bMV1dfXR8fCh0PVswXSk7Y29uc3QgcD1pLm1hcCgoeSxtKT0+e3ZhciBnLGI7cmV0dXJuIHBnKHtjb29yZGluYXRlOnkscHJvamVjdGlvbjpkLHN0YXJ0SGVpZ2h0OihnPXRbbV0pIT1udWxsP2c6dFswXSxoZWlnaHQ6KGI9ZVttXSkhPW51bGw/YjplWzBdLGhhc1RvcDpzIT1udWxsP3M6ITAsdG9wRmlyc3Q6ciE9bnVsbD9yOiExLGhhc0JvdHRvbTpvIT1udWxsP286ITAsaGFzU2lkZTphIT1udWxsP2E6ITAsY2FydGVzaWFuOmMhPW51bGw/YzohMCxjdXJ2YXR1cmVSZXNvbHV0aW9uOmghPW51bGw/aDoxLGJib3g6dX0pfSk7cmV0dXJuIEdpKHAsbil9LG1nPSh7Y29vcmRpbmF0ZXNBcnI6aSxsaW5lV2lkdGg6dCxzdGFydDplLHVzZUdyb3VwczpufSk9Pntjb25zdCByPWkubWFwKChvLGEpPT57dmFyIGM7cmV0dXJuIHZ1KHtwb2x5Z29uR2VvSnNvbjpbb10sc3RhcnRIZWlnaHQ6KGM9ZVthXSkhPW51bGw/YzplWzBdfSkudG9wVmVydHN9KS5tYXAoKG8sYSk9Pnt2YXIgbDtjb25zdCBjPShsPXRbYV0pIT1udWxsP2w6dFswXTtyZXR1cm4gTGgoe25vZGVzOm8sc2V0UG9pbnRXaWR0aDooKT0+Y30pfSk7cmV0dXJuIEdpKHIsbil9O3ZhciBnZz0oaSx0LGUpPT5uZXcgUHJvbWlzZSgobixzKT0+e3ZhciByPWM9Pnt0cnl7YShlLm5leHQoYykpfWNhdGNoKGwpe3MobCl9fSxvPWM9Pnt0cnl7YShlLnRocm93KGMpKX1jYXRjaChsKXtzKGwpfX0sYT1jPT5jLmRvbmU/bihjLnZhbHVlKTpQcm9taXNlLnJlc29sdmUoYy52YWx1ZSkudGhlbihyLG8pO2EoKGU9ZS5hcHBseShpLHQpKS5uZXh0KCkpfSk7ZnVuY3Rpb24geGcoaSl7cmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGkpLnJlZHVjZShmdW5jdGlvbih0LGUpe3JldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkodCxlLHt2YWx1ZTppW2VdLGVudW1lcmFibGU6ITB9KX0se30pfShpPT57Y29uc3QgdD17cnVuKGUsbil7Y29uc3Qgcz1uZXcgRnVuY3Rpb24oInJldHVybiAoIitlKyIpLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7Iik7cmV0dXJuIHMuYXBwbHkocyxuKX0sbWV0aG9kcygpe3JldHVybiBPYmplY3Qua2V5cyh0KX19O2FkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGU9PmdnKHZvaWQgMCxbZV0sZnVuY3Rpb24qKHtkYXRhOm59KXt0cnl7Y29uc3Qgcz10W24ubWV0aG9kXTtpZihzKXtjb25zdCByPXlpZWxkIHMuYXBwbHkocyxuLnBhcmFtcyk7ci50cmFuc2ZlciYmci5tZXNzYWdlP3Bvc3RNZXNzYWdlKHtpZDpuLmlkLHJlc3VsdDpyLm1lc3NhZ2UsZXJyb3I6bnVsbH0sci50cmFuc2Zlcik6cG9zdE1lc3NhZ2Uoe2lkOm4uaWQscmVzdWx0OnIsZXJyb3I6bnVsbH0pfWVsc2UgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG1ldGhvZCAiJytuLm1ldGhvZCsnIicpfWNhdGNoKHMpe3Bvc3RNZXNzYWdlKHtpZDpuLmlkLHJlc3VsdDpudWxsLGVycm9yOnhnKHMpfSl9fSkpLE9iamVjdC5rZXlzKGkpLmZvckVhY2goZT0+e3RbZV09aVtlXX0pLHBvc3RNZXNzYWdlKCJyZWFkeSIpfSkoe2V4dHJ1ZGVQb2x5Z29uOmV5LGxpbmU6c3ksbGluZTI6b3ksY29uaWNQb2x5Z29uOnlnLGNvbmljTGluZTptZ30pfSkoKTsK",N=g=>Uint8Array.from(atob(g),t=>t.charCodeAt(0)),z=typeof window!="undefined"&&window.Blob&&new Blob([N(o)],{type:"text/javascript;charset=utf-8"});function T(g){let t;try{if(t=z&&(window.URL||window.webkitURL).createObjectURL(z),!t)throw"";const r=new Worker(t,{name:g==null?void 0:g.name});return r.addEventListener("error",()=>{(window.URL||window.webkitURL).revokeObjectURL(t)}),r}catch(r){return new Worker("data:text/javascript;base64,"+o,{name:g==null?void 0:g.name})}finally{t&&(window.URL||window.webkitURL).revokeObjectURL(t)}}const R=g=>{const t=new BufferGeometry;return Object.keys(g).forEach(r=>{r==="groups"?g[r].forEach(d=>{t.addGroup(d.start,d.count,d.materialIndex)}):r==="index"?t.setIndex(new BufferAttribute(g[r].array,g[r].itemSize)):t.setAttribute(r,new BufferAttribute(g[r].array,g[r].itemSize))}),t};class Q{constructor(t){this.pluginName="worker",this.bufferGeometryLoader=new BufferGeometryLoader,this.cacheObj={},this._dispose=!1,this.options=W({dbName:"base",cacheVersion:"1"},t),this.store=createStore(this.options.dbName,"attributes")}install(t){this.pencil=t;const r=new esusLite.WorkerPool(T,{maxWorkers:this.options.maxWorkers});this.pool=r}geoGeometry(t,r){return V(this,null,function*(){const{mesaage:d,cacheKey:v,userData:C,cacheVersion:w,cb:E}=W(W({},this.options),r),ye=this.pool,{err:Le,res:Re}=yield ye.exec(t,[W({},d)],void 0,!0);if(Le)throw Le;const Ne=R(Re);if(Object.assign(Ne.userData,W({},C)),E&&(yield E(Ne)),v){const{cacheObj:Fe}=this;Fe[v]||(Fe[v]={[w]:[]}),Fe[v][w].push(W({attributes:Re},C))}return Ne})}getCachedGeometry(t){return V(this,null,function*(){const{cacheKey:r,cacheVersion:d}=t;if(r){const v=yield get(r,this.store),C=d||this.options.cacheVersion;return v!=null&&v[C]?v[C].map(w=>{const E=w,{attributes:ye}=E,Le=x(E,["attributes"]),Re=R(ye);return Object.assign(Re.userData,W({},Le)),Re}):[]}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}),d=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 w=new InstancedMesh(t,d,6),E=new Object3D;E.position.set(-10.906,2.009,1.846),E.rotation.set(0,-.195,0),E.scale.set(2.328,7.905,4.651),E.updateMatrix(),w.setMatrixAt(0,E.matrix),E.position.set(-5.607,-.754,-.758),E.rotation.set(0,.994,0),E.scale.set(1.97,1.534,3.955),E.updateMatrix(),w.setMatrixAt(1,E.matrix),E.position.set(6.167,.857,7.803),E.rotation.set(0,.561,0),E.scale.set(3.927,6.285,3.687),E.updateMatrix(),w.setMatrixAt(2,E.matrix),E.position.set(-2.017,.018,6.124),E.rotation.set(0,.333,0),E.scale.set(2.002,4.566,2.064),E.updateMatrix(),w.setMatrixAt(3,E.matrix),E.position.set(2.291,-.756,-2.621),E.rotation.set(0,-.286,0),E.scale.set(1.546,1.552,1.496),E.updateMatrix(),w.setMatrixAt(4,E.matrix),E.position.set(-2.193,-.369,-5.547),E.rotation.set(0,.516,0),E.scale.set(3.875,3.487,2.986),E.updateMatrix(),w.setMatrixAt(5,E.matrix),this.add(w);const ye=new Mesh(t,createAreaLightMaterial(50));ye.position.set(-16.116,14.37,8.208),ye.scale.set(.1,2.428,2.739),this.add(ye);const Le=new Mesh(t,createAreaLightMaterial(50));Le.position.set(-16.109,18.021,-8.207),Le.scale.set(.1,2.425,2.751),this.add(Le);const Re=new Mesh(t,createAreaLightMaterial(17));Re.position.set(14.904,12.198,-1.832),Re.scale.set(.15,4.265,6.331),this.add(Re);const Ne=new Mesh(t,createAreaLightMaterial(43));Ne.position.set(-.462,8.89,14.52),Ne.scale.set(4.38,5.441,.088),this.add(Ne);const Fe=new Mesh(t,createAreaLightMaterial(20));Fe.position.set(3.235,11.486,-12.541),Fe.scale.set(2.5,2,.1),this.add(Fe);const at=new Mesh(t,createAreaLightMaterial(100));at.position.set(0,20,0),at.scale.set(1,.1,1),this.add(at)}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(){_0(this,"event",new events.EventEmitter);_0(this,"eventHandlers",{});_0(this,"on",this.event.on.bind(this.event));_0(this,"emit",this.event.emit.bind(this.event))}addListener(t,r,d,v=!1){r in this.eventHandlers||(this.eventHandlers[r]=[]),this.eventHandlers[r].push({node:t,handler:d,capture:v}),t.addEventListener(r,d,v)}removeListener(t,r){this.eventHandlers[r].filter(({node:d})=>t?d===t:!0).forEach(({node:d,handler:v,capture:C})=>d.removeEventListener(r,v,C)),this.eventHandlers[r]=this.eventHandlers[r].filter(({node:d})=>t?d!==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);_0(this,"container");_0(this,"pencil");_0(this,"cameraState",{})}setSaveCamera(r){const d=this.pencil,v=d.cameraPositon,C=d.cameraTarget;this.cameraState[r]=[v.x,v.y,v.z,C.x,C.y,C.z]}useSaveCamera(r,d=!1){return D0(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],d),!0):!1})}lookAt(r,d,v,C,w,E,ye=!1,Le=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=Le/1e3,yield this.pencil.controls.setLookAt(r,d,v,C,w,E,ye),this.pencil.controls.smoothTime=250/1e3})}truck(r,d,v=!1,C=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=C/1e3,this.pencil.controls.restThreshold=0,yield this.pencil.controls.truck(r,d,v),this.pencil.controls.restThreshold=.0025,this.pencil.controls.smoothTime=250/1e3})}dollyTo(r,d=!1,v=250){return D0(this,null,function*(){let C=r;if(typeof C=="string"){const[w,E]=C.split("=");w==="+"?C=this.pencil.controls.distance+ +E:w==="-"?C=this.pencil.controls.distance-+E:w==="*"?C=this.pencil.controls.distance*+E:w==="/"?C=this.pencil.controls.distance/+E:console.error("dollyTo distance error")}this.pencil.controls.smoothTime=v/1e3,yield this.pencil.controls.dollyTo(C,d),this.pencil.controls.smoothTime=250/1e3})}absoluteAngle(r,d){const v=Math.PI*2,C=r-d;return MathUtils.euclideanModulo(C+Math.PI,v)-Math.PI}lookAtTarget(r,d=!1,v=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=v/1e3;const C=this.pencil.controls.azimuthAngle,w=this.pencil.controls.polarAngle,E=this.pencil.controls.distance,ye=this.pencil.cameraTarget.clone(),Le=r.azimuthAngle||C,Re=r.polarAngle||w,Ne=r.distance||E,Fe=r.target||ye;yield Promise.all([this.pencil.controls.moveTo(Fe.x,Fe.y,Fe.z,d),this.pencil.controls.dollyTo(Ne,d),this.pencil.controls.rotateTo(C+this.absoluteAngle(Le,C),w+this.absoluteAngle(Re,w),d)]),this.pencil.controls.smoothTime=250/1e3})}paddingInCssPixel(r,d,v,C,w,E){const{camera:ye,controls:Le}=this.pencil,Re=ye.fov*MathUtils.DEG2RAD,Ne=this.pencil.getSize().height,{size:Fe}=r.getSize(),at=Fe.x,ot=Fe.y,Gt=Fe.z;let ht=Le.getDistanceToFitBox(at,ot,Gt),ke=0,ct=0,xt=0,Rt=0;for(let Wt=0;Wt<10;Wt++){const Pt=ht-Gt*.5,Nt=2*Math.tan(Re*.5)*Math.abs(Pt)/Ne;ke=d*Nt,ct=C*Nt,xt=w*Nt,Rt=v*Nt,ht=Le.getDistanceToFitBox(at+xt+Rt,ot+ke+ct,Gt)}return Le.fitToBox(r.object3d,E,{paddingLeft:xt,paddingRight:Rt,paddingBottom:ct,paddingTop:ke})}resetCamera(r=!1,d=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=d/1e3,yield this.pencil.controls.reset(r),this.pencil.controls.smoothTime=250/1e3})}unproject(r,d=0){const v=new Vector3,C=new Vector3,{left:w,top:E,width:ye,height:Le}=this.container.getBoundingClientRect(),Re=(r.clientX-w)/ye*2-1,Ne=-((r.clientY-E)/Le)*2+1,Fe=this.pencil.cameraPositon.clone();v.set(Re,Ne,.5),v.unproject(this.pencil.camera),v.sub(Fe).normalize();const at=(d-Fe.z)/v.z;return C.copy(Fe).add(v.multiplyScalar(at)),C}dispose(){super.dispose(),this.cameraState={}}}class Command{constructor(t){_0(this,"id");_0(this,"updatable");_0(this,"type");_0(this,"name");_0(this,"editor");_0(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 d=this.editor.baseObjectByUuid(t.objectUuid);d&&(t.objectUuid=this.editor.uuidByBaseObject(d))}}fixJSON(){}}class SetColor extends Command{constructor(t,r,d,v){super(t),this.type="SetColor",this.name=`Set ${d}`,this.updatable=!0,this.object=r,this.attributeName=d,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,d,v,C){super(t),this.type="SetMaterialColor",this.name=`Set Material.${d}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[d].getHex():void 0,this.newValue=v,this.attributeName=d}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.uuidByObject(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.objectByUuid(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,d,v){var C;super(t),this.type="SetMaterial",this.name="New Material",this.object=r,this.materialSlot=v,this.oldMaterial=this.editor.getObjectMaterial(r,v),this.newMaterial=d,(C=this.oldMaterial)!=null&&C.name&&(this.newMaterial.name=this.oldMaterial.name)}execute(){var t;this.oldMaterial=this.editor.getObjectMaterial(this.object,this.materialSlot),(t=this.oldMaterial)!=null&&t.onBeforeCompile&&(this.newMaterial.onBeforeCompile=this.oldMaterial.onBeforeCompile),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.uuidByObject(this.object),t.materialSlot=this.materialSlot,t.oldMaterial=this.oldMaterial.toJSON(),t.newMaterial=this.newMaterial.toJSON(),t}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.oldMaterial=parseMaterial(t.oldMaterial),this.newMaterial=parseMaterial(t.newMaterial),((r=this.newMaterial.envMap)==null?void 0:r.name)==="PMREM.cubeUv"&&(this.newMaterial.envMap=this.editor.viewport.vis.getRoomEnvMap())}}function parseMaterial(g){if(!g)return null;const t=new ObjectLoader,r=t.parseImages(g.images),d=t.parseTextures(g.textures,r);return t.parseMaterials([g],d)[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,d,v,C){super(t),this.type="SetMaterialMap",this.name=`Set Material.${d}`,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldMap=r!==void 0?this.material[d]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=d}execute(){if(this.oldMap){if(this.editor.playing){const t=new O;t.track(this.oldMap),t.dispose()}else if(this.oldMap.dispose(),this.oldMap instanceof VideoTexture){const t=this.oldMap.source.data;t&&t.pause()}}this.newMap&&(this.newMap.anisotropy=this.editor.viewport.vis.tier0?1:this.editor.pencil.maxAnisotropy),this.material[this.mapName]=this.newMap,this.material instanceof Ie$2&&(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(){if(this.oldMap&&this.oldMap instanceof VideoTexture){const t=this.oldMap.source.data;t&&t.play()}this.material[this.mapName]=this.oldMap,this.material instanceof Ie$2&&(this.material.useMap=!!this.newMap),(!this.oldMap&&this.newMap||this.oldMap&&!this.newMap)&&(this.material.needsUpdate=!0),this.editor.emit("materialChanged",this.material)}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(this.object),t.materialSlot=this.materialSlot,t.mapName=this.mapName,t.newMap=serializeMap(this.newMap),t.oldMap=serializeMap(this.oldMap),t}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.mapName=t.mapName,this.oldMap=parseTexture(t.oldMap),this.newMap=parseTexture(t.newMap)}}function parseTexture(g){let t=null;if(g){const r=new ObjectLoader;if(g.isVideoTexture){const d=document.createElement("video");d.src=g.images[0].url,d.muted=!0,d.autoplay=!0,d.loop=!0,d.preload="auto",d.play();const v={[g.images[0].uuid]:new VideoTexture(d)};t=parseVideoTextures([g],v)[g.uuid]}else{const d=r.parseImages(g.images);t=r.parseTextures([g],d)[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 d={};if(g!==void 0)for(let v=0,C=g.length;v<C;v++){const w=g[v];let E=t[w.image];E.needsUpdate=!0,E.uuid=w.uuid,w.name!==void 0&&(E.name=w.name),w.mapping!==void 0&&(E.mapping=r(w.mapping,TEXTURE_MAPPING)),w.channel!==void 0&&(E.channel=w.channel),w.offset!==void 0&&E.offset.fromArray(w.offset),w.repeat!==void 0&&E.repeat.fromArray(w.repeat),w.center!==void 0&&E.center.fromArray(w.center),w.rotation!==void 0&&(E.rotation=w.rotation),w.wrap!==void 0&&(E.wrapS=r(w.wrap[0],TEXTURE_WRAPPING),E.wrapT=r(w.wrap[1],TEXTURE_WRAPPING)),w.format!==void 0&&(E.format=w.format),w.internalFormat!==void 0&&(E.internalFormat=w.internalFormat),w.type!==void 0&&(E.type=w.type),w.colorSpace!==void 0&&(E.colorSpace=w.colorSpace),w.encoding!==void 0&&(E.encoding=w.encoding),w.minFilter!==void 0&&(E.minFilter=r(w.minFilter,TEXTURE_FILTER)),w.magFilter!==void 0&&(E.magFilter=r(w.magFilter,TEXTURE_FILTER)),w.anisotropy!==void 0&&(E.anisotropy=w.anisotropy),w.flipY!==void 0&&(E.flipY=w.flipY),w.generateMipmaps!==void 0&&(E.generateMipmaps=w.generateMipmaps),w.premultiplyAlpha!==void 0&&(E.premultiplyAlpha=w.premultiplyAlpha),w.unpackAlignment!==void 0&&(E.unpackAlignment=w.unpackAlignment),w.compareFunction!==void 0&&(E.compareFunction=w.compareFunction),w.userData!==void 0&&(E.userData=w.userData),d[w.uuid]=E}return d};function serializeMap(g){if(g==null)return null;const t={geometries:{},materials:{},textures:{},images:{}},r=g.toJSON(t),d=extractFromCache(t.images);return g instanceof VideoTexture&&(d[0].url=g.source.data.src,r.isVideoTexture=!0),d.length>0&&(r.images=d),r.sourceFile=g.sourceFile,r}function extractFromCache(g){const t=[];for(const r in g){const d=g[r];delete d.metadata,t.push(d)}return t}const needsUpdateAttributeName=["transparent","alphaTest","fog","vertexColors","vertexShader","fragmentShader","sizeAttenuation"];class SetMaterialValue extends Command{constructor(t,r,d,v,C){super(t),this.type="SetMaterialValue",this.name=`Set Material.${d}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[d]:void 0,this.newValue=v,this.attributeName=d}execute(){this.material!==void 0&&(this.material[this.attributeName]=this.newValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("objectChanged",this.object),this.editor.emit("materialChanged",this.material),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("baseObjectListChange")}))}undo(){this.material[this.attributeName]=this.oldValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("objectChanged",this.object),this.editor.emit("materialChanged",this.material),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("baseObjectListChange")})}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(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.objectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot)}}class SetMaterialVector extends Command{constructor(t,r,d,v,C){super(t),this.type="SetMaterialVector",this.name=`Set Material.${d}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[d].toArray():void 0,this.newValue=v,this.attributeName=d}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.uuidByObject(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.objectByUuid(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,d,v,C,w="repeat"){var E,ye,Le,Re;super(t),this.type="SetMaterialMapVector",this.attributeName2=w,this.name=`Set Material.${d}.${w}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.material instanceof Ie$2&&d==="map"&&w==="repeat"?this.oldValue=this.material.repeat.toArray():((ye=(E=this.material)==null?void 0:E[d])==null?void 0:ye[w])instanceof Vector2?this.oldValue=this.material[d][w].toArray():typeof((Re=(Le=this.material)==null?void 0:Le[d])==null?void 0:Re[w])!="undefined"&&(this.oldValue=this.material[d][w]),this.newValue=v,this.attributeName=d}execute(){var t,r,d,v,C;if((t=this.material)!=null&&t[this.attributeName]){const w=this.attributeName;this.material[w].wrapS!==RepeatWrapping&&(this.material[w].wrapS=RepeatWrapping,this.material[w].wrapT=RepeatWrapping,this.material[w].needsUpdate=!0)}this.material instanceof Ie$2&&this.attributeName==="map"&&this.attributeName2==="repeat"?this.material[this.attributeName2].fromArray(this.newValue):((d=(r=this.material)==null?void 0:r[this.attributeName])==null?void 0:d[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,d,v;this.material instanceof Ie$2&&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=(d=this.material)==null?void 0:d[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.uuidByObject(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.objectByUuid(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,d,v,C){super(t),this.type="SetPosition",this.name="Set Position",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&d!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=d.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,d,v){super(t),this.type="SetRotation",this.name="Set Rotation",this.updatable=!0,this.object=r,r!==void 0&&d!==void 0&&(this.oldRotation=r.rotation.clone(),this.newRotation=d.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,d,v){super(t),this.type="SetScale",this.name="Set Scale",this.updatable=!0,this.object=r,r!==void 0&&d!==void 0&&(this.oldScale=r.scale.clone(),this.newScale=d.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,d,v,C){super(t),this.type="SetValue",this.name=`Set ${d}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=d;const w=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=w!==void 0?w[d]: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),setTimeout(()=>{(this.attributeName==="name"||this.attributeName==="prefab")&&this.editor.emit("baseObjectListChange")})))}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()}undo(){const t=this.properties?this.object[this.properties]:this.object;t[this.attributeName]=this.oldValue,this.fixObj(),this.editor.emit("objectChanged",this.object),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("baseObjectListChange")})}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,d,v,C){super(t),this.type="SetVector",this.name=`Set ${d}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=d;const w=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=w!==void 0?w[d].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,d,v){super(r);_0(this,"visType");_0(this,"visOptions");this.type="AddVis",this.visType=d,this.visOptions=v,d!==void 0&&(this.name=`Add Vis: ${d}`)}execute(){return D0(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,d,v){super(r);_0(this,"objectType");_0(this,"objectOptions");_0(this,"obj");_0(this,"addObjectUuid");this.type="AddObject",this.objectType=d,this.objectOptions=v,d!==void 0&&(this.name=`Add Object: ${d}`)}execute(){return D0(this,null,function*(){var d;const r=this.editor.viewport.vis;this.obj=yield r.lead.draw(this.objectType,Di(bi({},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),(d=this.editor.viewport.vis)==null||d.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,d){super(r);_0(this,"object");_0(this,"objectUuid");this.type="RemoveObject",this.name="Remove Object",this.object=d,this.objectUuid=this.editor.uuidByBaseObject(d)}execute(){this.object.hide(),this.object.userData.selectHide=!0,this.editor.emit("baseObjectListChange"),this.editor.select(null)}undo(){return D0(this,null,function*(){this.object.show(),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,d){super(r);_0(this,"object");_0(this,"copyObject",null);_0(this,"copyObjectUuid");this.type="CopyObject",this.name="Copy Object",this.object=d}execute(){return D0(this,null,function*(){var C;const r=this.editor.viewport.vis,d=this.object.key,v=yield this.object.instantiate(void 0,{key:`${this.id}`});this.copyObject=v,v.userData.updateKey!==!1&&r.lead.updateBaseObjectKey(v,`${d}_${this.id}`),this.copyObjectUuid=v.key,this.editor.select(this.copyObjectUuid),(C=this.editor.viewport.vis)==null||C.initBaseObjectUserData(v)})}undo(){return D0(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 SetSetting extends Command{constructor(r,d,v){super(r);_0(this,"attributeName");_0(this,"newValue");_0(this,"oldValue");this.type="SetSetting",this.updatable=!0,this.name=`Set Setting.${d}`,this.attributeName=d,this.newValue=v,r.viewport.vis&&(this.oldValue=r.viewport.vis.settings[d])}execute(){return D0(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 D0(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,d,v,C){super(t),this.type="SetTarget",this.name="Set Target",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&d!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=d.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,d,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[d]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=d}fromJSON(t){super.fromJSON(t),this.material=this.object[this.materialSlot]}}class SetGeometry extends Command{constructor(t,r=null,d){super(t),this.type="SetGeometry",this.name="Set Geometry",this.updatable=!0,this.object=r,this.oldGeometry=r!==null?r.geometry:null,this.newGeometry=d||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.oldGeometry=this.geometryToJSON(this.oldGeometry),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 Ve;return v.setPoints(t.points,t.variableWidth?C=>C:void 0),v}return new ObjectLoader().parseGeometries([t])[t.uuid]}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.oldGeometry=this.parseGeometry(t.oldGeometry),this.newGeometry=this.parseGeometry(t.newGeometry)}}const Commands=Object.freeze(Object.defineProperty({__proto__:null,AddObject,AddVis,CopyObject,RemoveObject,SetColor,SetGeometry,SetMaterial,SetMaterialColor,SetMaterialMap,SetMaterialMapVector,SetMaterialValue,SetMaterialVector,SetPosition,SetRotation,SetScale,SetSceenMap,SetSetting,SetTarget,SetValue,SetVector},Symbol.toStringTag,{value:"Module"}));class History{constructor(t){_0(this,"editor");_0(this,"undos");_0(this,"redos");_0(this,"lastCmdTime");_0(this,"idCounter");_0(this,"historyDisabled");this.editor=t,this.undos=[],this.redos=[],this.lastCmdTime=Date.now(),this.idCounter=0,this.historyDisabled=!1}execute(t,r){return D0(this,null,function*(){const d=this.undos[this.undos.length-1],v=Date.now()-this.lastCmdTime;d&&d.updatable&&t.updatable&&d.object===t.object&&d.type===t.type&&d.attributeName===t.attributeName&&d.attributeName2===t.attributeName2&&d.name===t.name&&d.objectUuid===t.objectUuid&&d.materialSlot===t.materialSlot&&v<500?(d.update(t),t=d):(this.undos.push(t),t.id=++this.idCounter),t.name=r!==void 0?r:t.name;try{yield t.execute()}catch(w){console.error(w,t)}this.editor.playing||(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;const t={u:[],i:[]};for(let d=0;d<this.undos.length;d++)if(this.undos[d].hasOwnProperty("json")){const v=this.undos[d].json;(r=v.newMap)!=null&&r.images?t.u.push(Di(bi({},v),{newMap:Di(bi({},v.newMap),{images:v.newMap.images.map(C=>{const w=t.i.findIndex(ye=>ye===C.url);let E=C.url;return w===-1?(t.i.push(C.url),E=`$rp-${t.i.length-1}`):E=`$rp-${w}`,Di(bi({},C),{url:E})})})})):t.u.push(bi({},v))}return t}fromJSON(t){var v;if(t===void 0)return;let r=-1;const d=t.i;for(let C=0;C<t.u.length;C++){const w=t.u[C];if(d!=null&&d.length&&((v=w.newMap)!=null&&v.images)&&w.newMap.images.forEach(ye=>{if(ye.url.startsWith("$rp-")){const Le=parseInt(ye.url.replace("$rp-",""));ye.url=d[Le]}}),w.id<=r){console.error("历史记录id错误");continue}if(w.type==="SetOption"||!w.type)continue;w.type.endsWith("Command")&&(w.type=w.type.replace("Command",""));const E=new Commands[w.type](this.editor);E.json=w,E.id=w.id,E.name=w.name,this.undos.push(E),this.idCounter=w.id>this.idCounter?w.id:this.idCounter,r=w.id}this.editor.emit("historyChanged",this.undos[this.undos.length-1])}processUndos(t=1e3/60){return new Promise((r,d)=>{const v=[...this.undos],C=v.length;let w=0;const E=()=>D0(this,null,function*(){const ye=performance.now();for(;v.length>0&&performance.now()-ye<t;){if(this.editor._dispose){d("dispose");return}const Le=v.shift(),Re=this.editor.hooks.events.beforeExecuteUndo.length?this.editor.hooks.dispatch("beforeExecuteUndo",Le):Le;Re&&(yield this.executeUndo(Re)),this.editor.hooks.events.afterExecuteUndo.length&&this.editor.hooks.dispatch("afterExecuteUndo",Le),w+=1}this.editor.emit("progress",{type:"还原场景",value:w/C*100|0}),v.length>0?requestAnimationFrame(E):r("")});requestAnimationFrame(E)})}executeUndo(t){return D0(this,null,function*(){t.fromJSON(t.json);try{t.json.type!=="AddObject"&&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){_0(this,"editor");_0(this,"vis");_0(this,"extendsOptions",{});_0(this,"cameraState",{});_0(this,"delLoadObj");_0(this,"options");this.options=r,this.editor=t}setSaveCamera(t){var r,d;this.vis.setSaveCamera(t),(r=this.vis.pencil.controls)==null||r.saveState(),this.cameraState=bi({},(d=this.vis)==null?void 0:d.cameraState),this.editor.emit("cameraStateChanged")}addVis(d){return D0(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(d){return D0(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=bi(bi({},r),this.extendsOptions);v=this.editor.hooks.events.beforeSetVisOptions.length?this.editor.hooks.dispatch("beforeSetVisOptions",v):v,this.vis.setOptions(v),this.vis.cameraState=bi({},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",(E,ye)=>{this.editor.emit("progress",{type:"下载资源",value:E/ye*100|0})}),this.vis.on("settingsChanged",()=>{this.editor.emit("settingsChanged")}),this.vis.on("show",()=>{this.editor.emit("visShow")}),yield this.vis.init();const{pencil:C}=this.vis;C.userData.EditorEnv=!this.editor.playing,this.editor.pencil=C,this.editor.changeSelectOption(),this.editor.playing||(this.initEvent(),this.editor.emit("visChanged",this.vis)),this.editor.on("baseObjectListChange",()=>{this.editor.changeSelectOption()}),C.event.on("baseObjectListChange",()=>{this.editor.emit("baseObjectListChange")});const w=()=>{this.editor.emit("baseObjectListChange")};C.event.on("updateKey",w),C.event.on("draw",w),C.event.on("erase",w)})}setResetCameraUp(){var w,E,ye;const r=((w=this.vis)==null?void 0:w.pencil.lead.group).getSize(),d=(r.max.x+r.min.x)/2,v=(r.max.y+r.min.y)/2,C=(E=this.vis)==null?void 0:E.pencil.cameraPositon.z;(ye=this.vis)==null||ye.pencil.controls.setLookAt(d,v,C,d,v,0,!0)}initEvent(){var r,d,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",w=>{this.editor.emit("refreshSidebarObject3D",w)}),(d=t.transformController)==null||d.event.on("translate",(w,E,ye)=>{this.editor.execute(new SetPosition(this.editor,w,E,ye))}),(v=t.transformController)==null||v.event.on("rotate",(w,E,ye)=>{this.editor.execute(new SetRotation(this.editor,w,E,ye))}),(C=t.transformController)==null||C.event.on("scale",(w,E,ye)=>{this.editor.execute(new SetScale(this.editor,w,E,ye))})}addObj(d){return D0(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 D0(this,null,function*(){const{vis:r}=this;if(!r)return;const d=this.editor.baseObjectByUuid(t);this.editor.execute(new RemoveObject(this.editor,d))})}copyObj(t){return D0(this,null,function*(){const{vis:r}=this;if(!r)return;const d=this.editor.baseObjectByUuid(t);this.editor.execute(new CopyObject(this.editor,d))})}setExtendsOptions(t,r){this.extendsOptions[t]=r,this.vis.extendsOptions[t]=r,this.editor.emit("optionsChanged"),setTimeout(()=>{const d=this.editor.toJSON();this.dispose(),this.editor.fromJSON(d)})}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 d;const{pencil:r}=this.vis;(d=r.transformController)==null||d.controls.setMode(t)}dispose(){var t;(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("."),d=t.split("."),v=Math.max(r.length,d.length);for(;r.length<v;)r.push("0");for(;d.length<v;)d.push("0");for(let C=0;C<v;C++){const w=parseInt(r[C]),E=parseInt(d[C]);if(w>E)return 1;if(w<E)return-1}return 0};function applyFixes(g,t){const r=[{version:"0.5.38",fix:()=>{var w;(w=t.v)!=null&&w.eo&&Object.keys(t.v.eo).forEach(E=>{["mouseLeft","mouseRight","mouseWheel","label","labelLite","shadowMap","autoRotate","equirectangular"].includes(E)&&(t.v.eo[E]=!!t.v.eo[E])}),t.h.u.forEach(E=>{E.type==="SetSetting"&&(E.attributeName==="阴影"&&(E.attributeName="shadowMap"),E.newValue=!!E.newValue,E.oldValue=!!E.oldValue)})}},{version:"0.7.14",fix:()=>{t.h.u.forEach(w=>{w.objectUuid&&(w.objectUuid=w.objectUuid.replace(w.objectUuid[0],w.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:w,adcode:E,geojsonLite:ye}=t.h.u[0].visOptions;t.h.u[0].visOptions=Di(bi({},t.h.u[0].visOptions),{geojsonMap:{[E]:w},extrudeLineGeojsonMap:{[E]:ye}}),delete t.h.u[0].visOptions.geojson,delete t.h.u[0].visOptions.geojsonLite}if(t.h.u[0].visOptions.bbox){const{bbox:w,bboxMap:E,adcode:ye}=t.h.u[0].visOptions;t.h.u[0].visOptions=Di(bi({},t.h.u[0].visOptions),{bboxMap:E||{[ye]:w}}),delete t.h.u[0].visOptions.bbox}if(t.h.u[0].visOptions.worldBg){const{worldBg:w}=t.h.u[0].visOptions;t.h.u[0].visOptions=Di(bi({},t.h.u[0].visOptions),{parentBg:w}),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(w=>{if(w.type==="SetSetting"&&w.attributeName.startsWith("测试")&&typeof w.newValue=="string"&&w.newValue.includes(":::")){const E=w.newValue.split(":::")[1];w.attributeName+=":::"+E,w.newValue=w.newValue.split(":::")[0],w.oldValue&&typeof w.oldValue=="string"&&(w.oldValue=w.oldValue.split(":::")[0])}})}},{version:"0.18.16",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u.forEach(w=>{if(w.type==="SetSetting"&&w.attributeName.startsWith("测试")&&w.attributeName.includes(":::")&&!w.attributeName.includes("caId")){const E=w.attributeName.split(":::")[1];w.attributeName=w.attributeName.replace(E,`caId.${E}`)}})}},{version:"0.21.24",fix:()=>{var w,E;t.h.u[0]&&t.h.u[0].visType==="map"&&((E=(w=t.v)==null?void 0:w.eo)!=null&&E.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,E;t.h.u[0]&&t.h.u[0].visType==="map"&&((E=(w=t.v)==null?void 0:w.eo)!=null&&E.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(w=>{w.objectUuid==="plane#topMatOne"?(w.objectUuid="area",w.materialSlot=0):w.objectUuid==="plane#sideMat"?(w.objectUuid="area",w.materialSlot=1):w.objectUuid==="plane#lineMat"?w.objectUuid="line":w.objectUuid==="plane#extrudeLineMat"?w.objectUuid="extrudeLine":w.objectUuid==="plane#bgTopMatOne"?w.objectUuid="bgPlane#topMat":w.objectUuid==="plane#bgSideMat"?w.objectUuid="bgPlane#sideMat":w.objectUuid==="plane#bgLineMat"?w.objectUuid="bgPlane#lineMat":w.objectUuid==="plane#bgExtrudeLineMat"?w.objectUuid="bgPlane#extrudeLineMat":w.objectUuid==="parentPlane#topMat"?(w.objectUuid="100000area",w.materialSlot=0):w.objectUuid==="parentPlane#sideMat"?(w.objectUuid="100000area",w.materialSlot=1):w.objectUuid==="parentPlane#lineMat"?w.objectUuid="100000line":w.objectUuid==="worldPlane#topMat"?(w.objectUuid="worldarea",w.materialSlot=0):w.objectUuid==="worldPlane#sideMat"?(w.objectUuid="worldarea",w.materialSlot=1):w.objectUuid==="worldPlane#lineMat"?w.objectUuid="worldline":w.objectUuid==="continents#topMat"?(w.objectUuid="continentsArea",w.materialSlot=0):w.objectUuid==="continents#sideMat"?(w.objectUuid="continentsArea",w.materialSlot=1):w.objectUuid==="continents#lineMat"?w.objectUuid="continentsLine":w.objectUuid==="area#river"?w.objectUuid="geography#river":w.objectUuid==="area#grassland"?w.objectUuid="geography#grassland":w.objectUuid==="area-grey#river"?w.objectUuid="geography-grey#river":w.objectUuid==="area-grey#grassland"&&(w.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 w={};t.h.u.forEach((E,ye)=>{var Le,Re,Ne;if(E.objectUuid==="area"&&E.materialSlot===0)E.objectUuid="plane#topMat",delete E.materialSlot;else if(E.objectUuid==="area"&&E.materialSlot===1)E.objectUuid="plane#sideMat",delete E.materialSlot;else if(E.objectUuid==="line")E.objectUuid="plane#lineMat";else if(E.objectUuid==="continentsArea"&&E.materialSlot===0)E.objectUuid="continents#topMat",delete E.materialSlot;else if(E.objectUuid==="continentsArea"&&E.materialSlot===1)E.objectUuid="continents#sideMat",delete E.materialSlot;else if(E.objectUuid==="continentsLine")E.objectUuid="continents#lineMat";else if(E.type==="SetSetting"&&((Le=E.attributeName)!=null&&Le.startsWith("测试"))&&E.attributeName.includes(":::caId.")){const Fe=E.attributeName.split(":::caId.")[1],at=t.h.u[0].visOptions.adcode;t.h.u[ye]=[{id:E.id,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`extrudePolygon#${at}-${Fe}`,copyObjectUuid:`ExtrudePolygon#${at}-${Fe}_${E.id}`},{id:E.id+.1,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`line#${at}-${Fe}`,copyObjectUuid:`line#${at}-${Fe}_${E.id+.1}`}],w[Fe]=E.id}else if((Re=E.objectUuid)!=null&&Re.startsWith("planeCopyExtrudePolygon")){const Fe=E.objectUuid.split("CopyExtrudePolygon")[1],at=t.h.u[0].visOptions.adcode;Object.assign(E,{objectUuid:`extrudePolygon#${at}-${Fe}_${w[Fe]}`})}else if((Ne=E.objectUuid)!=null&&Ne.startsWith("planeCopyLine")){const Fe=E.objectUuid.split("CopyLine")[1],at=t.h.u[0].visOptions.adcode;Object.assign(E,{objectUuid:`line#${at}-${Fe}_${w[Fe]+.1}`})}}),t.h.u=t.h.u.flat()}}},{version:"0.27.8",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&!t.h.u[0].visOptions.fixMap2CityOnMap&&(t.h.u[0].visOptions.mergeSide=!0,t.h.u.forEach(w=>{w.objectUuid==="extrudeLine"?w.objectUuid="plane#lineMat":w.objectUuid==="plane#lineMat"&&(w.objectUuid="extrudeLine")}),t.h.u[0].visOptions.fixMap2CityOnMap=!0)}},{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[0].visOptions.fixMap2CityOnMap2&&(t.h.u.forEach(w=>{w.objectUuid==="plane#extrudeLineMat"&&(w.objectUuid="plane#lineMat")}),t.h.u[0].visOptions.fixMap2CityOnMap2=!0)}}];let d=0,v=r.length-1,C=r.length;for(;d<=v;){const w=Math.floor((d+v)/2);compareVersion(r[w].version,g)>0?(C=w,v=w-1):d=w+1}for(let w=C;w<r.length;w++)r[w].fix()}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){_0(this,"editor");_0(this,"events",{beforeSetVisOptions:[],beforeExecuteUndo:[],afterExecuteUndo:[],beforeShow:[],afterShow:[],beforeFromJSON:[],afterFromJSON:[],errorFromJSON:[]});_0(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 d in t){const v=d;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 d;for(const v of this.events[t])if(t==="beforeSetVisOptions"?d=v(d!=null?d:r[0]):d=v(this.editor.viewport.vis,...r),d===!1)break;return d}}class Config{constructor(t){_0(this,"editor");_0(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",bi({},this.meta))}fromJSON(t){Object.keys(t).forEach(r=>{const d=r==="version"?"jsonVersion":r;d in this.meta&&this.setConfig(d,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 jsonFetch=(g,t,r=!1)=>{const d=esusLite.makePromiseCreator(!0),v=g.endsWith("gzip")||r;return window.fetch(g).then(C=>{let w=C;if(w.ok)return v?w.blob().then(E=>{const ye=new DecompressionStream("gzip"),Le=E.stream().pipeThrough(ye);return new Response(Le)}):w;throw new Error("Network response was not ok.")}).then(C=>C.json()).then(C=>{d.resolve(C)}).catch(C=>{d.reject(C)}),d.promise};class Editor{constructor(t){_0(this,"selected",null);_0(this,"playing",!0);_0(this,"currentMaterialSlot",0);_0(this,"events",new events.EventEmitter);_0(this,"history");_0(this,"viewport");_0(this,"hooks");_0(this,"config");_0(this,"pencil");_0(this,"on",this.events.on.bind(this.events));_0(this,"emit",this.events.emit.bind(this.events));_0(this,"options");_0(this,"selectOption",[]);_0(this,"_dispose",!1);this.options=bi({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;const d=this.pencil.lead.objMap.get(t);let v=t.material||(d==null?void 0:d.userData.material);return Array.isArray(v)&&r!==void 0&&(v=v[r]),v}getMListBaseObjectByObject(t,r){const d=this.getObjectMaterial(t,r);return d?this.viewport.vis.mList.getBaseObjectByMaterial(d):null}setObjectMaterial(t,r,d){const v=this.viewport.vis;let C=t.material;if(Array.isArray(t.material)&&r!==void 0?(C=t.material[r],t.material[r]=d):t.material=d,C){const w=new O;if(w.track(C),w.dispose(),t.userData.fixBufferGeometry){const E=v.pencil.lead,ye=Le=>{let Re=!1;if(Le.material)if(Array.isArray(Le.material)){const Ne=Le.material;Ne.forEach((Fe,at)=>{Fe===C&&(Re=!0,Ne[at]=d)})}else Le.material===C&&(Re=!0,Le.material=d);return Re?Le:null};this.pencil.scene.traverse(Le=>{const Re=Le;ye(Re);const Ne=E.objMap.get(Re);Ne!=null&&Ne.materialList&&Object.keys(Ne.materialList).forEach(Fe=>{if(Fe!==Ne.useMaterialType||!Array.isArray(Ne.materialList[Fe])){const at=Ne.materialList[Fe],ot=ye({material:at});ot&&Ne.setMaterialList(Fe,ot.material)}})})}}}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,d){for(let v=0;v<t.length;v++){const C=t[v];if(C[r]===d)return C;if(C.children){const w=this.findSelectItem(C.children,r,d);if(w)return w}}}changeSelectOption(){const t=this.viewport.vis,r=t.mList,d=v=>v.filter(C=>C.userData.selectHide!==!0).map(C=>{var ot;const w=[...C.children];if(C.key==="Scene"&&!w.find(Gt=>Gt.key==="camera"))this.pencil.camera.name="透视相机",w.unshift({key:"camera",object3d:this.pencil.camera,userData:{},children:[]});else if(C.object3d.target){const Gt=C.options.type;w.unshift({key:C.key.replace(Gt,Gt+"Target"),object3d:C.object3d.target,userData:{disabledCR:!0,disabledTC:!1},children:[]})}if(C.object3d.isDirectionalLight){const Gt=C.options.type;w.unshift({key:C.key.replace(Gt,Gt+"Shadow"),object3d:C.object3d.shadow.camera,userData:{disabledCR:!0},children:[]})}const ye=w.length>0?d(w):[],Le=C.object3d.userData.fixBufferGeometry,Re=C.object3d.isGroup&&C.userData.disabledTC!==!1,Ne=Le||Re||["Scene","camera"].includes(C.key)||C.userData.disabledCR;if(ye.length===0&&Re)return null;const Fe=C.key.replace(C.key[0],C.key[0].toLowerCase()),at=(ot=C.userData.disabledTC)!=null?ot:Ne;return{key:Fe,name:C.object3d.name,object:C.object3d,disabledCR:Ne,disabledTC:at,baseObject:C,children:ye}}).filter(C=>C!==null);this.selectOption=[...d([r.wrapObject]),...d([t.lead.scene])],this.emit("sceneGraphChanged")}execute(t,r){return D0(this,null,function*(){yield this.history.execute(t,r)})}fromJSON(t,r){return D0(this,null,function*(){var d,v,C,w;try{r&&!f(r)?console.warn("fromJSON 第二个参数已修改,{beforeSetVisOptions:(r)=>r} 替代"):r&&this.hooks.addEvents(r);let E;if(typeof t=="string"){const ye=this.options.assetsPrefix+t;console.time("vis-core:time.json-fetch");const{res:Le,err:Re}=yield jsonFetch(ye);if(console.timeEnd("vis-core:time.json-fetch"),Re)throw new Error("fromJSON error:"+Re);E=Le}else E=t;if(this.hooks.dispatch("beforeFromJSON"),E=fixJSON(E),E.at&&(accessToken.token=E.at),!this.storage){if(!accessToken.token)throw new Error("设置 token 或平台重新下载 JSON 文件");const ye=accessToken.getInfo();if(!ye||!ye.isValid)throw new Error("need accessToken")}if(this.config.fromJSON(E.c),this.history.fromJSON(E.h),this.viewport.fromJSON(E.v),this.hooks.fromJSON(E.s),this.config.compareVersion(),yield this.history.processUndos(this.options.processUndosMaxFrameTime),(d=E.v.bg)!=null&&d.texture&&this.viewport.vis){const ye=parseTexture(E.v.bg.texture);ye.colorSpace=SRGBColorSpace,this.viewport.vis.pencil.scene.background=ye}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),(w=this.viewport.vis)!=null&&w.workerOnce&&this.playing&&window.requestIdleCallback(()=>{var ye;(ye=this.viewport.vis)==null||ye.worker.dispose()}),this.hooks.dispatch("afterFromJSON"),E}catch(E){throw this.hooks.dispatch("errorFromJSON"),new Error("fromJSON error:"+E)}})}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){_0(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 d=tier0GPU[r],v=this.getGPUVersion();return d.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(/\([^)]+\)/,""),d=r.match(/\d+/)||r.match(/(\W|^)([A-Za-z]{1,3})(\W|$)/g);return(v=d==null?void 0:d.join("").replace(/\W|amd/g,""))!=null?v:""}queryFallback(){const t=this.renderer,r=BLOCKLISTED_GPUS.find(d=>t.includes(d));return r?{tier:0,gpu:r}:{tier:3,gpu:t}}}class WebGL{constructor(){_0(this,"rawRenderer");_0(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"),d=r==null?void 0:r.getExtension("WEBGL_debug_renderer_info");return r&&d?r.getParameter(d.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"),d=window.WebGL2RenderingContext&&r.getContext("webgl2");return d?(d.drawingBufferColorSpace=t,d.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 bi(bi({},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 d=new DOMMatrix(r);return Math.max(d.a,d.d)}};function observeScale(g,t){let r=g,d=1;for(;r;){const ye=getScale(r);if(ye!==void 0){d=ye;break}if(r=r.parentElement,r===document.body){r=null;break}}if(!r)return null;const v=ye=>{const Le=getScale(r)||1;d!==Le&&(d=Le,t(Le,ye))},C=ye=>{ye.propertyName==="transform"&&v("transitionEnd")},w=new MutationObserver(ye=>{for(const Le of ye)if(Le.type==="attributes"&&Le.attributeName==="style"){v("MutationObserver");return}});w.observe(r,{attributes:!0,attributeFilter:["style"]}),r.addEventListener("transitionend",C),t(d,"init");const E=w.disconnect;return w.disconnect=function(){E.call(w),r==null||r.removeEventListener("transitionend",C)},w}const IS_DEV=!1;class Base extends Camera{constructor(r){var d;super();_0(this,"playing",!0);_0(this,"leftTruck",!0);_0(this,"options");_0(this,"showState",!1);_0(this,"settings",{});_0(this,"delLoadArr");_0(this,"extendsOptions",{});_0(this,"leadObjs",objs$3);_0(this,"lead");_0(this,"mList",new MaterialList);_0(this,"workerOnce",!0);_0(this,"tier0",!1);_0(this,"pmremGenerator",null);_0(this,"re",null);_0(this,"roomEnvMap");_0(this,"visName");_0(this,"editor");_0(this,"publicDir",{});_0(this,"_baseObjectByUuid");_0(this,"_objectByUuid");_0(this,"observeScale",null);_0(this,"sceneActive",-1);_0(this,"initSettingsObj");_0(this,"mouseButtonsActiveStore",null);if(this.container=r.container,this.options=bi({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=(d=this.options.tier)!=null?d:v.tier;try{const w=window.location.search.match(/v_tier=(\d+)/);w&&(C=+w[1])}catch(w){console.error(w)}this.tier0=C!==3,this.editor=new Editor({assetsPrefix:this.options.assetsPrefix,visFactories:this}),console.info("vis-core:detect",version,JSON.stringify(Di(bi({},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=bi(bi({},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 D0(this,null,function*(){})}initVis(...r){return D0(this,null,function*(){})}init(...r){return D0(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 D0(this,null,function*(){var v,C,w,E,ye,Le,Re,Ne;if(this.pencil)return;const r=bi({},this.options.pencilConfig);if(this.options.css2DContainer&&(r.css2DRendererParams={container:this.options.css2DContainer}),this.options.pencil)this.pencil=this.options.pencil,this.sceneActive=this.pencil.addPage({cameraOptions:{fov:(C=(v=r.camera)==null?void 0:v.fov)!=null?C:45,near:(E=(w=r.camera)==null?void 0:w.near)!=null?E:.1,far:(Le=(ye=r.camera)==null?void 0:ye.far)!=null?Le:1e3,up:(Ne=(Re=r.camera)==null?void 0:Re.up)!=null?Ne:new Vector3(0,1,0)},sceneOptions:{background:new Color$1(0)}}),this.setSceneActive(),this.mList.install(this.pencil);else if(this.options.pencil2){this.pencil=this.options.pencil2,this.lead=this.pencil.lead.init(this.leadObjs),this.mList.dispose(),this.mList=this.pencil.installPlugins.get("materialList"),this.sceneActive=this.pencil.pageActiveIndex;return}else{const Fe=new rt(bi(Di(bi({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},bloom:!0,ssao:!0,ssaoParams:{minDistance:.001},scene:{background:new Color$1(0)},loader:bi({prefix:this.options.assetsPrefix,simpleTexture4deleted:!0},this.tier0?{anisotropy:1}:{})}),r));if(this.options.observeParentScale&&this.playing){const Gt=()=>{this.observeScale||(this.observeScale=observeScale(this.container,(ht,ke)=>{Fe.setDevicePixelRatio(window.devicePixelRatio*ht)}))};Gt(),Fe.event.on("resize",()=>{Gt()})}this.pencil=Fe,this.sceneActive=1;const at=Fe.composerController.ssaoPass;at&&(at.enabled=!1);const ot=new Q({dbName:this.visName,cacheVersion:version});Fe.use(ot),Fe.use(this.mList),this.playing||(window.vis=this,window.pencil=Fe)}const d=this.pencil;this.lead=d.lead.init(this.leadObjs),this.delLoadArr&&(d.loader.delLoadArr=this.delLoadArr),d.loader.on("progress",(...Fe)=>{this.showState!==!0&&this.emit("loaderProgress",...Fe)}),this.leftTruck&&(d.controls.mouseButtons.left=Ki.TRUCK,d.controls.mouseButtons.right=Ki.ROTATE),this.lead.group.hide(),this.lead.prefabGroup.hide(),this.initSceneUserData(),this.initCameraUserData(),this.initSettings()})}setSceneActive(){this.pencil.showPage(this.sceneActive),this.pencil.installPlugins.set("materialList",this.mList)}initCameraUserData(){const r=this.pencil;r.camera.userData=new Proxy({up:r.camera.up.toArray().join(",")},{set:(d,v,C)=>{if(v==="up"){const w=C.split(",").map(E=>+E);r.camera.up.set(w[0],w[1],w[2]),r.controls.updateCameraUp()}return Reflect.set(d,v,C)}})}initSceneUserData(){var E,ye,Le,Re,Ne,Fe;const r=this.pencil,d=r.scene.background,v=d instanceof Color$1?"Color":d instanceof Texture?"Texture":"None",C=v==="Texture"?d:null,w=v==="Color"?"#"+d.getHexString():"#000000";r.scene.userData=new Proxy({backgroundType:v,backgroundColor:w,backgroundTexture:C,shadowMapEnabled:this.pencil.renderer.shadowMap.enabled,shadowMapType:this.pencil.renderer.shadowMap.type,bloomThreshold:(ye=(E=this.pencil.composerController)==null?void 0:E.bloomPass)==null?void 0:ye.threshold,bloomRadius:(Re=(Le=this.pencil.composerController)==null?void 0:Le.bloomPass)==null?void 0:Re.radius,bloomStrength:(Fe=(Ne=this.pencil.composerController)==null?void 0:Ne.bloomPass)==null?void 0:Fe.strength},{set:(at,ot,Gt)=>(ot==="shadowMapEnabled"||ot==="shadowMapType"?(ot==="shadowMapEnabled"?this.pencil.renderer.shadowMap.enabled=Gt:ot==="shadowMapType"&&(this.pencil.renderer.shadowMap.type=Gt),this.pencil.scene.traverse(ht=>{const ke=ht;if(ke.receiveShadow&&ke.material){const ct=ke.material;Array.isArray(ct)?ct.forEach(xt=>{xt.needsUpdate=!0}):ct.needsUpdate=!0}})):ot==="backgroundType"?Gt==="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):ot==="backgroundColor"?r.scene.background=new Color$1(Gt):ot==="backgroundTexture"?r.scene.background=Gt:ot==="bloomThreshold"?r.composerController.bloomPass&&(r.composerController.bloomPass.threshold=Gt):ot==="bloomRadius"?r.composerController.bloomPass&&(r.composerController.bloomPass.radius=Gt):ot==="bloomStrength"&&r.composerController.bloomPass&&(r.composerController.bloomPass.strength=Gt),Reflect.set(at,ot,Gt))})}initBaseObjectUserData(r){const d=Di(bi({},r.object3d.userData),{bloom:!1});if(r.objectType==="BaseObject#Light")return;const v=r.objectType==="BaseObject#Arc",C=r.objectType==="BaseObject#Line",w=r.object3d instanceof Group$1;v?d.animationDuration=2e3:C&&(d.animationDuration=0),prefabType.includes(r.objectType.split("#")[1])&&(d.prefab=r.prefab),r.object3d.userData=new Proxy(d,{set:(E,ye,Le)=>(ye==="bloom"?Le?r.enableBloom():r.disableBloom():ye==="prefab"?(r.prefab=Le,Le?this.lead.prefabGroup.attach(r):this.lead.group.attach(r)):ye==="animationDuration"&&v?r.animateIn({duration:Le}):ye==="animationDuration"&&(C||w)&&(C?[r]:r.children).forEach(Ne=>{Ne.material.userData.tween&&(Ne.material.userData.tween.stop(),remove(Ne.material.userData.tween),Ne.material.userData.tween=null),Le&&(Ne.material.uniforms.offset.value.x=1,Ne.material.uniforms.offsetLoop.value=1,Ne.animate({duration:Le,repeat:1/0,lineLoop:!0,startShow:!0}))}),Reflect.set(E,ye,Le))})}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(Di(bi(bi({},this.initSettingsObj),r),{mouseNone:!1,viewportPadding:[0,0,0,0]}),{set:(d,v,C)=>{if(!(v in d)&&!(v.replace(/(:::.+)\..*$/,"$1")in d))return Reflect.set({},v,C);v==="mouseWheel"?typeof C=="boolean"&&(C=C?r.mouseWheel:Ki.NONE):v==="mouseLeft"?typeof C=="boolean"&&(C=C?r.mouseLeft:Ki.NONE):v==="mouseRight"&&typeof C=="boolean"&&(C=C?r.mouseRight:Ki.NONE);const w=v.includes(":::");return Reflect.set(d,w?v.replace(/(:::.+)\..*$/,"$1"):v,this.handleSetting(v,C))},get:(d,v)=>{const w=v.includes(":::")?v.replace(/(:::.+)\..*$/,"$1"):v,E=Reflect.get(d,w);return E instanceof Promise?E.then(ye=>(Reflect.set(d,w,ye),ye)):E}})}handleSetting(r,d){return D0(this,null,function*(){const{pencil:v}=this;if(r==="mouseWheel"||r==="mouseLeft"||r==="mouseRight"){const C=r.replace("mouse","").toLowerCase();(d||this.playing)&&(v.controls.mouseButtons[C]=d)}else if(r==="mouseNone")d?(this.mouseButtonsActiveStore={mouseLeft:v.controls.mouseButtons.left,mouseRight:v.controls.mouseButtons.right,mouseWheel:v.controls.mouseButtons.wheel},v.controls.mouseButtons.left=Ki.NONE,v.controls.mouseButtons.right=Ki.NONE,v.controls.mouseButtons.wheel=Ki.NONE):this.mouseButtonsActiveStore&&(v.controls.mouseButtons.left=this.mouseButtonsActiveStore.mouseLeft,v.controls.mouseButtons.right=this.mouseButtonsActiveStore.mouseRight,v.controls.mouseButtons.wheel=this.mouseButtonsActiveStore.mouseWheel);else if(r==="viewportPadding"){v.rendererController.setViewPadding(...d);const C=new Vector4;v.renderer.getViewport(C),v.cameraController.setAspect(C.z/C.w)}return d})}show(){this.showState||(this.useSaveCamera("visShow"),this.options.disableInitShow||this.showAction())}showAction(){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 D0(this,arguments,function*(r,d={}){typeof d=="string"&&(d={display:d}),d.display&&(r.style.display=d.display);let C=0;typeof d.onTop!="undefined"&&(C=d.onTop);const w=yield this.lead.draw("Node",{onTop:C});return w.setChildren(r),w})}addCSS3D(v){return D0(this,arguments,function*(r,d={}){d.display&&(r.style.display=d.display);let C=0;typeof d.onTop!="undefined"&&(C=d.onTop);let w="3d";typeof d.type!="undefined"&&(w=d.type);const E=yield this.lead.draw("Node",{onTop:C,type:w});return E.setChildren(r),E})}getRoomEnvMap(){if(this.roomEnvMap)return this.roomEnvMap;const r=new PMREMGenerator(this.pencil.renderer);r.compileEquirectangularShader();const d=new RoomEnvironment,v=r.fromScene(d,.04).texture;return this.pmremGenerator=r,this.re=d,this.roomEnvMap=v,v}handlePick(r,d,v){console.warn("handlePick is deprecated, use BaseObject.onPointerEvent"),this.lead.handlePick(r,d,v)}getScreenPosition(r,d,v){const C=new Vector3(r,d,v);C.project(this.pencil.camera);const{width:w,height:E}=this.pencil.getSize(),ye=(C.x*.5+.5)*w,Le=(C.y*-.5+.5)*E;return{x:ye,y:Le}}dispose(){var r,d,v,C,w;super.dispose(),this.editor&&(this.editor.viewport.vis=void 0,this.editor.dispose()),this.publicDir={},this.options.pencil?((r=this.mList)==null||r.dispose(),this.pencil.removePage(this.sceneActive)):this.options.pencil2||(d=this.pencil)==null||d.dispose(),(v=this.pmremGenerator)==null||v.dispose(),(C=this.re)==null||C.dispose(),(w=this.observeScale)==null||w.disconnect()}}_0(Base,"VisName","base");function clipGeojson(g,t){const r=turf.flatten(g).features,d=turf.flatten(t).features,v={type:"FeatureCollection",features:[]};for(let C=r.length-1;C>=0;C--){const w=r[C];for(let E=d.length-1;E>=0;E--){const ye=d[E];if(contains(w,ye))v.features.push(ye);else if(contains(ye,w))w.properties=ye.properties,v.features.push(w);else{const Le=turf.intersect(w,ye);Le&&(Le.properties=ye.properties,v.features.push(Le))}}}return v}function contains(g,t){let r=!0;const d=turf.explode(t).features;for(let v=d.length-1;v>=0;v--)if(!turf.inside(d[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,d)=>turf.polygon(t[d]))};class Building extends ie$1{constructor(r){super();_0(this,"options");_0(this,"building",{});_0(this,"outJson",new Map);_0(this,"worldPositionZ",{value:0});this.options=bi({},r)}create(){return D0(this,null,function*(){const{json:r,projection:d,cacheKey:v,meters:C,grey:w,clip:E}=this.options,ye=this.pencil.installPlugins.get("materialList"),Le=this.pencil.getPlugin("worker"),Re=this.pencil.lead,Ne=w?"-grey":"";this.createGroup();const Fe=ye.getMultiple("building"+Ne);let at=v?yield Le.getCachedGeometry({cacheKey:v}):[];if(at.length)E&&this.outJson.set(1,!0);else{let ot;E&&(ot=getBoxMultiPoly(E));const Gt={};(r.features||r).forEach(ke=>{const ct=typeof ke.properties.h=="string"?ke.properties.h.split(".")[1]:0,xt=Number(ke.properties.h)|0;Gt[ct]||(Gt[ct]={}),Gt[ct][xt]||(Gt[ct][xt]=[]),ot?ot.some(Wt=>{ke.geometry.coordinates[1]&&console.log(ke.geometry.coordinates[1]);const Pt=turf.polygon(ke.geometry.coordinates[0]);return turf.booleanContains(Wt,Pt)?(Gt[ct][xt].push(ke),!0):!1})||this.outJson.set(ke,!1):Gt[ct][xt].push(ke)});const ht=Object.keys(Gt).map(ke=>{const ct=Gt[ke];return Object.keys(ct).map(xt=>{const Rt=ct[xt];return{z:+ke,h:+xt,coordinatesArr:Rt.map(Wt=>Wt.geometry.type==="Polygon"?Wt.geometry.coordinates[0]:Wt.geometry.coordinates[0][0])}})}).flat().filter(ke=>ke.coordinatesArr.length);at=yield Promise.all(ht.map(ke=>{const{h:ct,z:xt,coordinatesArr:Rt}=ke,Wt=+ct<=20?+ct/18:+ct<=60?+ct/27:+ct/12;return Le.geoGeometry("extrudePolygon",{cacheKey:v,userData:{z:xt,h:ct},mesaage:{coordinatesArr:Rt,projection:d,useGroups:2,depth:[Number(ct)*(C||1)],hasBottom:!1,sideRepeat:Wt}})}))}yield Promise.all(at.map(ot=>D0(this,null,function*(){const{h:Gt,z:ht}=ot.userData,ke=Gt+ht,ct=ke<=20?"20":ke<=60?"60":"max";let xt=this.options.material;xt||(xt=[Fe[ct+"Top"],Fe[ct+"Side"]]);const Rt=yield Re.draw("ExtrudePolygon",{key:`$p:-${Gt}-${ht}`,geometry:ot,material:xt},this);this.options.grey||(Rt.object3d.castShadow=!0),this.building[Gt]||(this.building[Gt]=[]),this.building[Gt].push(Rt),Rt.position.z=Number(ht)*(C||1)}))),this.options.sideGradient&&this.sideGradient(),this.object3d.name="建筑",w||this.lead.updateBaseObjectKey(this,`building${Ne?"-grey":""}#group`)})}sideGradient(r="#052438",d=.05/100){this.traverse(v=>{if(v instanceof ss){const C=v.object3d.material;C[1].onBeforeCompile=w=>{w.uniforms.gradientColor={value:new Color$1(r)},w.uniforms.maxGradientHeight={value:d},w.uniforms.worldPositionZ=this.worldPositionZ,w.vertexShader=`
4856
+ `,defines:{}}),"baseTexture");return t.needsSwap=!0,t},Pe=1,me=!1,Xs=new MeshBasicMaterial({color:"black"}),qs=new PointsMaterial({color:"black",sizeAttenuation:!1}),$s=new PointsMaterial({color:"black",sizeAttenuation:!0}),Qs=new SpriteMaterial({color:"black",sizeAttenuation:!0}),Js=new SpriteMaterial({color:"black",sizeAttenuation:!1}),ei=new Ie$2({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.pipViewportState=null,this.options=t;const{rendererController:r,sceneController:d,cameraController:v,composerParams:C}=t,{renderer:w}=r;this.renderer=w;const{multisampling:E}=C,{maxSamples:ye}=w.capabilities,Le=w.getDrawingBufferSize(new Vector2),Re=new WebGLRenderTarget(Le.width,Le.height,{samples:Math.min(E,ye),type:HalfFloatType}),Ne=new EffectComposer(w,Re),Fe=this.getSize();Ne.setSize(Fe.width,Fe.height);const at=new RenderPass(d.scene,v.camera);Ne.addPass(at),this.scene=d.scene,this.camera=v.camera,this.finalComposer=Ne,this.renderPass=at,v.event.on("pageChange",ot=>{this.changeCamera(ot)}),d.event.on("pageChange",ot=>{this.changeScene(ot)})}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 Gs;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:d,renderer:v}=this,C=v.getSize(new Vector2),w=C.width,E=C.height,ye=new SSAOPass(r,d,w,E);ye.kernelRadius=t.kernelRadius,ye.minDistance=t.minDistance,ye.maxDistance=t.maxDistance,this.ssaoPass=ye,this.finalComposer.addPass(ye)}addBloomPass(t){const{renderer:r}=this,{threshold:d,strength:v,radius:C,bloomAlphaType:w}=t,E=new UnrealBloomPass(new Vector2(window.innerWidth,window.innerHeight),v,C,d);this.bloomPass=E;const ye=new EffectComposer(r);ye.renderToScreen=!1,ye.addPass(this.renderPass),ye.addPass(E),this.bloomComposer=ye;const Le=Ks(ye);Le.uniforms.bloomAlphaType.value=w,this.bloomComposer=ye,this.finalComposer.addPass(Le),this.mixPass=Le,this.bloomLayer.set(Pe)}setBloomSelection(t,r){if(!this.bloomComposer){console.warn("err:pencil.options.bloom");return}t.traverse(d=>{const{object3d:v}=d;v&&(r?(this.bloomSelection.add(d),v.layers.enable(Pe)):(this.bloomSelection.delete(d),v.layers.disable(Pe)))}),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 d;(d=this.bloomComposer)==null||d.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(d=>{d.isTransformControls||d.isTransformControlsRoot||d.type==="RectAreaLightHelper"?t.push(d):r.push(d)}),r.forEach(d=>{d.traverse(v=>{var C;const w=v,E=v,ye=v;(C=w.material)!=null&&C.isShadowMaterial?t.push(w):w.material&&this.bloomLayer.test(w.layers)===!1&&(this.bloomMaterials[w.uuid]=w.material,E.isSprite?E.material.sizeAttenuation?E.material=Qs:E.material=Js:w.material instanceof Ie$2?w.material=ei:ye.isPoints?ye.material.sizeAttenuation?ye.material=$s:ye.material=qs:w.material=Xs)})}),t.forEach(d=>{this.bloomVisible[d.uuid]=d.visible,d.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.mixPass.enabled=!0,this.darkenNonBloomed(),this.bloomComposer.render(),this.restoreNonBloomed()):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:d}=this.options;if(this.finalComposerRender(),this.pipViewportState){t.setPageActive(31),t.setAspect(this.pipViewportState.width/this.pipViewportState.height),r.setViewport(ee(U({},this.pipViewportState),{scissor:!0,scissorTest:!0})),this.finalComposerRender(),t.setPageActive(d.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 st extends Loader{constructor(t){super(t),this.options={type:"image"}}setOptions(t){return this.options=t,this}load(t,r,d,v){let C,w;this.options.type==="image"?(w=document.createElement("img"),C=new Texture(w)):this.options.type==="video"?(w=document.createElement("video"),w.preload="auto",w.autoplay=!1,w.loop=!1,w.muted=!0,w.setAttribute("webkit-playsinline","webkit-playsinline"),w.setAttribute("playsinline",""),C=new VideoTexture(w)):C=new Texture;const E=new FileLoader(this.manager);return E.setResponseType("blob"),E.setRequestHeader(this.requestHeader),E.setPath(this.path),E.setWithCredentials(this.withCredentials),E.load(t,ye=>{let Le=ye;const Re=t.split(".").pop(),Ne=this.options.type==="image"?`image/${Re||"png"}`:`video/${Re||"mp4"}`;Le=Le.slice(0,ye.size,Ne);const Fe=()=>{w.removeEventListener("load",at,!1),w.removeEventListener("error",ot,!1)},at=()=>{Fe(),C.needsUpdate=!0,r&&r(C)},ot=ht=>{Fe(),v&&v(ht),this.manager.itemError(t),this.manager.itemEnd(t)};w.addEventListener("load",at,!1),w.addEventListener("error",ot,!1);const Gt=window.URL.createObjectURL(Le);w.src=Gt},d,v),C}}class oi extends Loader{constructor(t){super(t)}load(t,r,d,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,w=>{const E=w,ye=new DecompressionStream("gzip"),Le=E.stream().pipeThrough(ye);new Response(Le).json().then(Re=>{r==null||r(Re)}).catch(Re=>{v==null||v(Re)})},d,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 ve.EventEmitter,this.options=U({simpleTexture4deleted:!1,prefix:""},t),this.loadingManager=new LoadingManager(()=>{},(r,d,v)=>{this.emit("progress",d,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 d=this.assets.get(t);if(!d){if((r==="images"||r==="media"||r==="exr")&&this.options.simpleTexture4deleted&&this.delLoadArr.includes(t))return new Texture;console.warn(`Asset ${t} not found`)}return d}getAssetType(t){var r;const d=(r=t.split(".").pop())==null?void 0:r.toLowerCase();if(d){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(d))return v}getLoader(t,r){if(t==="images")return this.textureLoader||(this.textureLoader=new st(this.loadingManager),this.options.prefix&&this.textureLoader.setPath(this.options.prefix)),this.textureLoader;if(t==="media")return this.videoTextureLoader||(this.videoTextureLoader=new st(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(d=>{const v=U({src:d},r);this.loadObj.push(v)})}getSrcByAsset(t,r=this.assets){let d;return r.forEach((v,C)=>{v===t&&(d=C)}),d}get textureAssets(){const t=new Map;return this.assets.forEach((r,d)=>{(r instanceof Texture||r instanceof DataTexture||r instanceof VideoTexture)&&t.set(d,r)}),t}loadAll(){return te(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 te(this,null,function*(){var d,v;const C=(d=r==null?void 0:r.type)!=null?d:this.getAssetType(t);if(!C)return;const w=(r==null?void 0:r.cache)!==!1,E=esusLite.makePromiseCreator();if(w){if(this.assets.has(t))return this.assets.get(t);this.assets.set(t,E.promise)}const ye=this.getLoader(C,r);try{const Le=yield ye.loadAsync(t);if(this.assets.set(t,Le),E.resolve(Le),C==="images"||C==="media"||C==="exr"||C==="lottie"){(r==null?void 0:r.colorCorrection)!==!1&&l$1({texture:Le});const Re=(v=r==null?void 0:r.anisotropy)!=null?v:this.options.anisotropy;Le.anisotropy=Re}return Le}catch(Le){E.reject(`Failed to load ${t}`);return}})}getUnusedAssets(){const{scene:t}=this.options;if(!t)return[...this.delLoadArr];const r=new Set,d=this.textureAssets;t.traverse(C=>{const w=C;w.material&&(Array.isArray(w.material)?w.material:[w.material]).forEach(E=>{[E.map,E.emissiveMap,E.normalMap,E.roughnessMap,E.metalnessMap,E.aoMap].forEach(ye=>{if(ye){const Le=this.getSrcByAsset(ye,d);Le&&r.add(Le)}})})});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 hi={prefix:""};class li extends ae{get loader(){return this.controller}constructor(t){super(),this.options=t}addLoader(t,r){const{loaderParams:d}=this.options,v=new ai(ee(U({},d),{scene:t}));return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}}class ci extends ie$1{constructor(t){super(),this.options=U({},t)}create(){var t;this.object3d=(t=this.options.scene)!=null?t:new Scene}}function it(g){let t=!1,r=[];return function(...d){r=d,t||(t=!0,requestAnimationFrame(()=>{t=!1,g(...r)}))}}class di{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.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"]),d=new Set(["down","downOutside","click"]),v=C=>{var w;if(!this.enabled)return;C.preventDefault();const E=t==="move"?r:d,ye=[];if(this.pickFunctionsMap.forEach(ot=>{E.has(ot.type)&&ye.push(ee(U({},ot),{objArr:ot.objArr instanceof Function?ot.objArr():ot.objArr}))}),ye.length===0)return;this.activeObjects.clear(),this.objCallbackMap.clear();const Le=this.objCallbackMap,Re=[];for(const ot of ye)for(const Gt of ot.objArr){if(!Gt.object3d||!Gt.visibleWithAncestors)continue;Le.has(Gt)||(Le.set(Gt,new Map),Re.push(Gt));const ht=Le.get(Gt);ht.has(ot.type)||ht.set(ot.type,[]),ht.get(ot.type).push(ot.cb)}if(Re.length===0)return;const Ne=Re.map(ot=>ot.object3d);Ne.forEach(ot=>{ot.isGroup&&ot.traverse(Gt=>{Gt instanceof Mesh&&Ne.push(Gt)})});const Fe=(w=this.pencil.pick(C,Ne,!1))==null?void 0:w.intersects;if(!Fe||Fe.length===0)t==="down"?this.handleDownOutside(C):t==="move"&&this.handleLeaveEvents(C);else{this.sortIntersections(Fe);const ot=Fe[0];this.processIntersection(ot,C,t)}const at=this.prevActiveObjects;this.prevActiveObjects=this.activeObjects,this.activeObjects=at,this.activeObjects.clear()};this.domElement.addEventListener(`pointer${t}`,it(v),{passive:!1})}sortIntersections(t){t.sort((r,d)=>r.distance===d.distance?r.object.getObjectById(d.object.id)?1:d.object.getObjectById(r.object.id)?-1:0:r.distance-d.distance)}processIntersection(t,r,d){const v=this.objCallbackMap,C=t.index||-1;let w=t.object;for(;w;){const E=this.pencil.lead.objMap.get(w);E&&v.has(E)&&this.activeObjects.add(E),w=w.parent}d==="move"?this.handleLeaveEvents(r):d==="down"&&this.handleDownOutside(r),this.processObjectHierarchy(r,d,C)}processObjectHierarchy(t,r,d){const v=this.objCallbackMap;let C=!1;const w=()=>{C=!0};for(const E of this.activeObjects){if(C)break;const ye=v.get(E);if(ye)if(r==="move"){const Le=ye.get("enter");if(Le&&!this.prevActiveObjects.has(E))for(const Ne of Le)Ne({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d});const Re=ye.get("move");if(Re)for(const Ne of Re)Ne({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d})}else{const Le=ye.get("down");if(Le)for(const Ne of Le)Ne({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d});const Re=ye.get("click");if(Re){const Ne=Fe=>{Fe.preventDefault();const at=5;if(!C&&Math.abs(Fe.clientX-t.clientX)<=at&&Math.abs(Fe.clientY-t.clientY)<=at)for(const ot of Re)ot({baseObject:E,mouseEvent:t,sp:w,intersectionIndex:d});this.domElement.removeEventListener("pointerup",Ne)};this.domElement.addEventListener("pointerup",Ne)}}}}handleLeaveEvents(t){this.objCallbackMap.forEach((r,d)=>{const v=r.get("leave");if(v&&this.prevActiveObjects.has(d)&&!this.activeObjects.has(d))for(const C of v)C({baseObject:d,mouseEvent:t})})}handleDownOutside(t){this.objCallbackMap.forEach((r,d)=>{const v=r.get("downOutside");if(v&&!this.activeObjects.has(d))for(const C of v)C({baseObject:d,mouseEvent:t})})}handlePick(t,r,d){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:d}),this.pickListener.move||Array.from(this.pickFunctionsMap.values()).some(w=>["move","enter","leave"].includes(w.type))&&(this.pickListener.move=!0,this.addPickListener("move")),this.pickListener.down||Array.from(this.pickFunctionsMap.values()).some(w=>["down","downOutside","click"].includes(w.type))&&(this.pickListener.down=!0,this.addPickListener("down")),C}removePick(t){this.pickFunctionsMap.delete(t)}handlePickNode(t,r,d){if(r==="downOutside")return console.warn("handlePickNode:err:不支持 downOutside"),-1;this.pickNodeFunctionsMapIndex+=1;const v=this.pickNodeFunctionsMapIndex,C=t instanceof Function?t():t,w=[];for(const E of C){const ye=E;ye.element.style.pointerEvents="auto";const Le=Ne=>{this.enabled&&(Ne.preventDefault(),d({baseObject:ye,mouseEvent:Ne}))},Re=`pointer${r}`;ye.element.addEventListener(Re,it(Le),!1),w.push({arr:ye,type:Re,listener:Le})}return this.pickNodeFunctionsMap.set(v,w),v}removePickNode(t){const r=this.pickNodeFunctionsMap.get(t);if(r){for(const d of r)d.arr.element.style.pointerEvents="none",d.arr.element.removeEventListener(d.type,d.listener,!1);this.pickNodeFunctionsMap.delete(t)}}dispose(){this.pickFunctionsMap.clear(),this.pickNodeFunctionsMap.clear(),this.activeObjects.clear(),this.prevActiveObjects.clear(),this.objCallbackMap.clear()}}class pi extends di{constructor(t,r){super(t),this.objMap=new Map,this.objects=new Map,this.objectsPm=new Map,this.objectNamesToFactories=new Map,this.scene=new ci({scene:r.scene}),this.scene.create(),this.scene.lead=this,this.scene.pencil=t,this.scene.key="Scene",this.scene.object3d.name="场景",this.group=new ze$1,this.group.create(),this.group.lead=this,this.group.pencil=t,this.group.key="@Group",this.group.object3d.name="物体组",this.prefabGroup=new ze$1,this.prefabGroup.create(),this.prefabGroup.lead=this,this.prefabGroup.pencil=t,this.prefabGroup.key="@PrefabGroup",this.prefabGroup.object3d.name="预制组",this.scene.add(this.group.object3d,this.prefabGroup.object3d),this.objects.set("@Scene",this.scene),this.objects.set("@Group",this.group),this.objects.set("@PrefabGroup",this.prefabGroup),this.objMap.set(this.scene.object3d,this.scene),this.objMap.set(this.group.object3d,this.group),this.objMap.set(this.prefabGroup.object3d,this.prefabGroup)}get objectsPromise(){return this.objectsPm.values()}init(t){return Object.keys(t).forEach(r=>{const d=class{create(v={}){return new t[r](v)}};this.objectNamesToFactories.set(r,d)}),this}getObject(t,r){t.includes("#")&&console.warn("getObject:err:不支持 #",t);const{key:d}=r||{},v=`${t}${d?`#${d}`:""}`;return this.objects.get(v)}getAllObject(t,r){t.includes("#")&&console.warn("getAllObject:err:不支持 #",t);const{key:d}=r||{},v=`${t}${d?`#${d}`:""}`,C=[];return this.objects.forEach((w,E)=>{(E.startsWith(d?v:`${v}#`)||E===v)&&C.push(w)}),C}draw(t,r,d){return te(this,null,function*(){var v,C,w,E;const ye=this.objectNamesToFactories.get(t);if(ye){r||(r={}),r.target===void 0&&(r.target=d);const Le=r.target,Re=(v=r.onTop)!=null?v:0,Ne=(C=r.prefab)!=null?C:!1,Fe=(w=r.create)!=null?w:!0,at=new ye().create(r);let ot;return Le===null?ot=null:typeof Le=="string"?ot=this.objects.get(Le):(E=Le==null?void 0:Le.objectType)!=null&&E.startsWith("BaseObject")||Le?ot=Le:Ne?ot=this.prefabGroup:ot=this.group,Fe===!1?at.create=()=>{}:Fe!==!0&&(at.create=()=>{Fe(at)}),at.pencil=this.pencil,at.lead=this,at.prefab=Ne,at.objectType=`BaseObject#${t}`,at.objectOptions=r,this.setBaseObjectKey(at,r.key?`$t:#${r.key}`:"$t:",ot==null?void 0:ot.key),this.objectsPm.set(at.key,this.addBaseObject(at,ot,Re)),yield this.objectsPm.get(at.key),this.objectsPm.delete(at.key),at}throw new Error(`Unrecognized:${t}`)})}setBaseObjectKey(t,r,d){const v=t.objectType,[,C]=v.split("#");let w=r.replace("$t:",C);if(d){const[,E]=d.split("#");w=w.replace("$p:",E)}return this.objects.has(w)&&(w.includes("#")?w+=`-${esusLite.generateUUID()}`:w+=`#${esusLite.generateUUID()}`),t.key=w,this.objects.set(w,t),w}updateBaseObjectKey(t,r){var d;let v;for(const[E,ye]of this.objects.entries())if(ye===t){v=E;break}const C=(d=t.parent)==null?void 0:d.key;if(!v)return this.setBaseObjectKey(t,r,C);this.objects.delete(v);const w=this.setBaseObjectKey(t,r,C);return this.pencil.event.emit("updateKey",t,w,v),w}addBaseObject(t,r,d){return te(this,null,function*(){yield t.create(),t.object3d&&(d&&t.setTop(d),r!==null&&(r.add(t.object3d),this.objMap.set(t.object3d,t))),t.render(),this.pencil.event.emit("draw",t)})}erase(...t){this.handleErase(!0,...t),this.pencil.event.emit("erase",...t)}eraseWithoutMaterial(...t){this.handleErase(!1,...t)}handleErase(t,...r){[...r].forEach(d=>{const v=[];if(typeof d=="string"){const[C,w]=d.split("#");v.push(...this.getAllObject(C,{key:w}))}else v.push(d);v.forEach(C=>{t?C.dispose():C.disposeWithOutMaterial()})})}update(t,r){this.objects.forEach(d=>{d.update(t,r)})}setSize(t,r){this.objects.forEach(d=>{d.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.objectNamesToFactories.clear()}}class mi extends ae{get lead(){return this.controller}constructor(t){super(),this.options=t}addLead(t,r){const{pencil:d}=this.options,v=new pi(d,{scene:t});return this.addController(v,r)}removePage(t){super.removePage(t,r=>{r.dispose()})}setPageActive(t){super.setPageActive(t,(r,d)=>{r.enabled=d})}setSize(t,r){this.controllerMap.forEach((d,v)=>{v.setSize(t,r)})}}const _e=class In{constructor(t){var r,d;this.raycaster=new Raycaster,this.maxBackufferArea=5760*5760,this.installPlugins=new Map,this._cameraPositon=new Vector3,this._cameraTarget=new Vector3,this.event=new ve.EventEmitter,this.timer=new Timer,this.userData={},this.pageActiveIndex=0,this.pageCountIndex=0,this.userSetDprCache=1,this.event.setMaxListeners(1/0),(d=(r=this.timer).connect)==null||d.call(r,document),this.options=is(In.options,t,{isMergeableObject:f}),this.userSetDprCache=this.options.renderer.devicePixelRatio;const{container:v,stats:C,transformControls:w}=this.options;if(this.init(),this.options.WebGPUTHREE||this.initComposer(),this.initCSSRenderer(),w&&this.initTransformControls(),C){const E=new Stats({horizontal:!1});E.dom.style.position="absolute",E.init(this.renderer),v.appendChild(E.dom),this.stats=E}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}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 d=this.pageCountIndex+1,v=this.cameraController.addPerspectiveCamera(r,d),C=this.sceneController.addScene(t,d);return C.add(v),this.controlsController.addCameraControls(v,d),this.loaderController.addLoader(C,d),this.leadController.addLead(C,d),this.pageCountIndex=d,d}removePage(t){this.cameraController.removePage(t),this.sceneController.removePage(t),this.controlsController.removePage(t),this.loaderController.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 d=this.scene;this.sceneController.setPageActive(t),d&&((r=this.cssRendererController)==null||r.render(d,this.camera)),this.cameraController.setPageActive(t),this.controlsController.setPageActive(t),this.loaderController.setPageActive(t),this.leadController.setPageActive(t),this.pageActiveIndex=t}init(){var t;const{container:r,WebGPUTHREE:d,helper:v,viewHelper:C,renderer:w,controls:E,loader:ye}=this.options,{width:Le,height:Re}=this.getSize(),Ne=d?new Rs({width:Le,height:Re,renderer:d.WebGPURenderer,rendererParams:Ds}):new Ms({width:Le,height:Re,rendererParams:ee(U({},w),{antialias:!1})}),Fe=new zs({width:Le,height:Re}),at=new Fs({}),ot=new Hs({controlsParams:{domElement:(t=E==null?void 0:E.domElement)!=null?t:Ne.renderer.domElement}}),Gt=new li({loaderParams:U({anisotropy:Ne.renderer.capabilities.getMaxAnisotropy()},ye)}),ht=new mi({pencil:this});this.sceneController=at,this.cameraController=Fe,this.controlsController=ot,this.rendererController=Ne,this.loaderController=Gt,this.leadController=ht;const ke=this.addPage({sceneOptions:this.options.scene,cameraOptions:this.options.camera});if(this.showPage(ke),v){const ct=new Ns({container:r,sceneController:at,cameraController:Fe});ct.add(at.scene),this.helperController=ct,C&&ct.addViewHelper()}r.appendChild(Ne.renderer.domElement)}initComposer(){const{bloom:t,bloomParams:r,ssao:d,ssaoParams:v,composer:C}=this.options,w=new ri({rendererController:this.rendererController,sceneController:this.sceneController,cameraController:this.cameraController,composerParams:C});this.composerController=w,t&&w.addBloomPass(U({},r)),d&&w.addSSAOPass(U({},v)),w.addOutputPass()}initCSSRenderer(){const{container:t,css2DRenderer:r,css3DRenderer:d,css2DRendererParams:v,css3DRendererParams:C}=this.options;if(r||d){const w=new Zs(t);r&&w.addRenderer("css2d",v),d&&w.addRenderer("css3d",C),this.cssRendererController=w}}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(d=>{for(const v of d){const C=v.contentRect;this.handeleResize(C.width,C.height),this.setDevicePixelRatio(this.userSetDprCache)}});r.observe(t),this.resizeObserver=r}handeleResize(t,r,d=!0){const{rendererController:v,cameraController:C,composerController:w,cssRendererController:E,leadController:ye}=this,Le=this.renderer.getSize(new Vector2);Le.x===t&&Le.y===r||(C.setSize(t,r),v.setSize(t,r),w==null||w.setSize(t,r),E==null||E.setSize(t,r),ye.setSize(t,r),this.installPlugins.forEach(Re=>{var Ne;(Ne=Re.setSize)==null||Ne.call(Re,t,r)}),this.render(),d&&this.event.emit("resize",{width:t,height:r}))}setDevicePixelRatio(t){var r;this.userSetDprCache=t;const{width:d,height:v}=this.getSize();let C=Math.sqrt(this.maxBackufferArea/(d*v));C=(C*100|0)/100;const w=Math.min(t,C);w!==t&&console.warn("maxBackufferArea:",this.maxBackufferArea," the pixel ratio is set to",w);const E=this.renderer.getPixelRatio();w!==E&&(this.rendererController.setPixelRatio(w),(r=this.composerController)==null||r.setPixelRatio(w))}pick(t,r,d=!0){const{raycaster:v,options:C}=this,{container:w}=C,E=new Vector2,ye=w.getBoundingClientRect();if(E.x=(t.clientX-ye.left)/(ye.right-ye.left)*2-1,E.y=-((t.clientY-ye.top)/(ye.bottom-ye.top))*2+1,this.camera&&this.scene){v.setFromCamera(E,this.camera);const Le=v.intersectObjects(r||this.scene.children,d);if(Le.length)return{object:Le[0].object,index:Le[0].index,intersects:Le}}}render(){var t,r,d,v,C,w;if(!this.camera||!this.scene)return;this.timer.update(),update();const E=this.timer.getDelta(),ye=this.timer.getElapsed();this.controlsController.update(E,ye),this.leadController.update(E,ye),this.installPlugins.forEach(Le=>{var Re;(Re=Le.update)==null||Re.call(Le,E,ye)}),(t=this.helperController)==null||t.update(E,this.controlsController,this.cameraTarget),(r=this.composerController)!=null&&r.active?this.composerController.render():(d=this.rendererController)==null||d.render(this.scene,this.camera),(v=this.helperController)==null||v.renderViewHelper(this.renderer),(C=this.cssRendererController)==null||C.render(this.scene,this.camera),(w=this.stats)==null||w.update(),this.event.emit("render",{delta:E,elapsed:ye})}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:d,height:v}=this.getSize(),C=new DOMRect(t.x/d,(v-t.y-t.height)/v,t.width/d,t.height/v);if(r)r.enabled=!0,r.camera.position.copy(this.camera.position);else{const w=this.cameraController.cloneCamera(31);w.aspect=t.width/t.height,w.updateProjectionMatrix(),r=this.controlsController.addCameraControls(w,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,d,v,C,w,E,ye,Le,Re,Ne,Fe,at;this.stop(),this.timer.dispose(),removeAll(),this.event.removeAllListeners(),(t=this.resizeObserver)==null||t.unobserve(this.options.container),this.installPlugins.forEach(ot=>{var Gt;(Gt=ot.dispose)==null||Gt.call(ot)}),(r=this.controlsController)==null||r.dispose(),(d=this.transformController)==null||d.dispose(),(v=this.cssRendererController)==null||v.dispose(),(C=this.sceneController)==null||C.dispose(),(w=this.cameraController)==null||w.dispose(),(E=this.helperController)==null||E.dispose(),(ye=this.composerController)==null||ye.dispose(),(Le=this.rendererController)==null||Le.dispose(),(Re=this.loaderController)==null||Re.dispose(),(Ne=this.leadController)==null||Ne.dispose(),this.cssRendererController=void 0,this.installPlugins.clear(),(Fe=this.stats)==null||Fe.dom.remove(),(at=this.renderer)==null||at.domElement.remove()}};_e.options={stats:me,helper:me,viewHelper:me,controls:!0,transformControls:me,renderer:As,composer:ii,scene:ks,camera:Tt,bloom:!1,bloomParams:si,ssao:!1,loader:hi,ssaoParams:ti,css2DRenderer:!1,css2DRendererParams:U({},tt),css3DRenderer:!1,css3DRendererParams:U({},tt)};let rt=_e;const Ki=J.ACTION,b$1=new Map,R$2=(g={})=>({generateTopUV(t,r,d,v,C){const w=r[d*3],E=r[d*3+1],ye=r[v*3],Le=r[v*3+1],Re=r[C*3],Ne=r[C*3+1];let Fe;if(b$1.has(t))Fe=b$1.get(t);else{let ht=g.box3;if(!ht){ht=new Box3;const ct=t.parameters.shapes.getPoints().map(xt=>[xt.x,xt.y,0]).flat();ht.setFromArray(ct)}const ke=ht.getSize(new Vector3);g.split&&(ke.y/=g.split),Fe={box:ht,size:ke},b$1.set(t,Fe)}const{box:at,size:ot}=Fe,Gt=g.split?1-g.split:0;return[new Vector2((w-at.min.x)/ot.x,(E-at.min.y)/ot.y+Gt),new Vector2((ye-at.min.x)/ot.x,(Le-at.min.y)/ot.y+Gt),new Vector2((Re-at.min.x)/ot.x,(Ne-at.min.y)/ot.y+Gt)]},generateSideWallUV(t,r,d,v,C,w){const E=r[d*3],ye=r[d*3+1],Le=r[d*3+2],Re=r[v*3],Ne=r[v*3+1],Fe=r[v*3+2],at=r[C*3],ot=r[C*3+1],Gt=r[C*3+2],ht=r[w*3],ke=r[w*3+1],ct=r[w*3+2];let xt;if(b$1.has(r))xt=b$1.get(r);else{const Pt=new Box3;Pt.setFromArray(r);const Nt=Pt.getSize(new Vector3);g.split&&(Nt.z/=1-g.split),g.sideRepeat&&(Nt.z/=g.sideRepeat),xt={box:Pt,size:Nt},b$1.set(r,xt)}const{box:Rt,size:Wt}=xt;return Math.abs(ye-Ne)<Math.abs(E-Re)?[new Vector2((E-Rt.min.x)/Wt.x,(Le-Rt.min.z)/Wt.z),new Vector2((Re-Rt.min.x)/Wt.x,(Fe-Rt.min.z)/Wt.z),new Vector2((at-Rt.min.x)/Wt.x,(Gt-Rt.min.z)/Wt.z),new Vector2((ht-Rt.min.x)/Wt.x,(ct-Rt.min.z)/Wt.z)]:[new Vector2((ye-Rt.min.y)/Wt.y,(Le-Rt.min.z)/Wt.z),new Vector2((Ne-Rt.min.y)/Wt.y,(Fe-Rt.min.z)/Wt.z),new Vector2((ot-Rt.min.y)/Wt.y,(Gt-Rt.min.z)/Wt.z),new Vector2((ke-Rt.min.y)/Wt.y,(ct-Rt.min.z)/Wt.z)]}}),P=()=>{b$1.clear()};var Jt=Object.defineProperty,Xt=Object.defineProperties,Qt=Object.getOwnPropertyDescriptors,lt=Object.getOwnPropertySymbols,Bt=Object.prototype.hasOwnProperty,Vt=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={}))Bt.call(t,r)&&It(g,r,t[r]);if(lt)for(var r of lt(t))Vt.call(t,r)&&It(g,r,t[r]);return g},ut=(g,t)=>Xt(g,Qt(t)),gt=(g,t)=>{var r={};for(var d in g)Bt.call(g,d)&&t.indexOf(d)<0&&(r[d]=g[d]);if(g!=null&&lt)for(var d of lt(g))t.indexOf(d)<0&&Vt.call(g,d)&&(r[d]=g[d]);return r},nt=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())});class Xe extends ie$1{constructor(t){super(),this.objectType="BaseObject#Node",this.onNodePointerIndex=[],this.options=G({type:"2d"},t)}create(){const{position:t,children:r}=this.options,d=document.createElement("div");this.element=d,r&&d.appendChild(r),this.options.type==="3d"?this.createCSS3DObject(d):this.options.type==="3dSprite"?this.createCSS3DSprite(d):this.createCSS2DObject(d),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(),d=window.innerWidth,v=window.innerHeight;let C=0,w=0;r.left<0?C=-r.left:r.right>d&&(C=d-r.right),r.top<0?w=-r.top:r.bottom>v&&(w=v-r.bottom),r.left+C<0&&(C=-r.left),r.top+w<0&&(w=-r.top),(C!==0||w!==0)&&(t.style.transform=`translate(${C}px, ${w}px)`)}ensureVisible(){const t=this.options.children;if(!t)return;t.style.transform&&(t.style.transform="");const r=new IntersectionObserver(d=>{d.forEach(v=>{v.isIntersecting&&(this.moveElementToViewport(),r.disconnect())})});r.observe(t)}onPointerEvent(t,r){const d=this.lead.handlePickNode([this],t,r);this.onNodePointerIndex.push(d)}dispose(){this.onNodePointerIndex.forEach(t=>{this.lead.removePickNode(t)}),super.dispose()}}const Ue={ArcCurve,CatmullRomCurve3,CubicBezierCurve,CubicBezierCurve3,EllipseCurve,LineCurve,LineCurve3,QuadraticBezierCurve,QuadraticBezierCurve3,SplineCurve};let Y$1=class zn 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 d=this,v=[],C=[];for(let E=0,ye=t.length;E<ye;E++){const Le=t[E];w(Le)}this.setAttribute("position",new Float32BufferAttribute(v,3)),this.setAttribute("uv",new Float32BufferAttribute(C,2)),this.computeVertexNormals();function w(E){var ye,Le,Re;const Ne=[],Fe=r.curveSegments!==void 0?r.curveSegments:12,at=r.steps!==void 0?r.steps:1,ot=r.depth!==void 0?r.depth:1;let Gt=r.bevelEnabled!==void 0?r.bevelEnabled:!0,ht=r.bevelThickness!==void 0?r.bevelThickness:.2,ke=r.bevelSize!==void 0?r.bevelSize:ht-.1,ct=r.bevelOffset!==void 0?r.bevelOffset:0,xt=r.bevelSegments!==void 0?r.bevelSegments:3;const Rt=r.extrudePath,Wt=r.UVGenerator!==void 0?r.UVGenerator:Ce,Pt=(ye=r.hasTop)!=null?ye:!0,Nt=(Le=r.hasBottom)!=null?Le:!0,Kt=(Re=r.hasSide)!=null?Re:!0;let Ft,kt=!1,Yt,s0,o0,h0;Rt&&(Ft=Rt.getSpacedPoints(at),kt=!0,Gt=!1,Yt=Rt.computeFrenetFrames(at,!1),s0=new Vector3,o0=new Vector3,h0=new Vector3),Gt||(xt=0,ht=0,ke=0,ct=0);const r0=E.extractPoints(Fe);let e0=r0.shape;const i0=r0.holes;if(!ShapeUtils.isClockWise(e0)){e0=e0.reverse();for(let F0=0,w0=i0.length;F0<w0;F0++){const c0=i0[F0];ShapeUtils.isClockWise(c0)&&(i0[F0]=c0.reverse())}}function Ut(F0){const w0=10000000000000001e-36;let c0=F0[0];for(let a0=1;a0<=F0.length;a0++){const M0=a0%F0.length,R0=F0[M0],N0=R0.x-c0.x,P0=R0.y-c0.y,Mi=N0*N0+P0*P0,yi=Math.max(Math.abs(R0.x),Math.abs(R0.y),Math.abs(c0.x),Math.abs(c0.y)),Xi=w0*yi*yi;if(Mi<=Xi){F0.splice(M0,1),a0--;continue}c0=R0}}Ut(e0),i0.forEach(Ut);const l0=i0.length,S0=e0;for(let F0=0;F0<l0;F0++){const w0=i0[F0];e0=e0.concat(w0)}function g0(F0,w0,c0){return w0||console.error("THREE.ExtrudeGeometry: vec does not exist"),F0.clone().addScaledVector(w0,c0)}const I0=e0.length;function fi(F0,w0,c0){let a0,M0,R0;const N0=F0.x-w0.x,P0=F0.y-w0.y,Mi=c0.x-F0.x,yi=c0.y-F0.y,Xi=N0*N0+P0*P0,Ii=N0*yi-P0*Mi;if(Math.abs(Ii)>Number.EPSILON){const $0=Math.sqrt(Xi),_i=Math.sqrt(Mi*Mi+yi*yi),Vi=w0.x-P0/$0,zi=w0.y+N0/$0,wi=c0.x-yi/_i,Bi=c0.y+Mi/_i,Ni=((wi-Vi)*yi-(Bi-zi)*Mi)/(N0*yi-P0*Mi);a0=Vi+N0*Ni-F0.x,M0=zi+P0*Ni-F0.y;const Hi=a0*a0+M0*M0;if(Hi<=2)return new Vector2(a0,M0);R0=Math.sqrt(Hi/2)}else{let $0=!1;N0>Number.EPSILON?Mi>Number.EPSILON&&($0=!0):N0<-Number.EPSILON?Mi<-Number.EPSILON&&($0=!0):Math.sign(P0)===Math.sign(yi)&&($0=!0),$0?(a0=-P0,M0=N0,R0=Math.sqrt(Xi)):(a0=N0,M0=P0,R0=Math.sqrt(Xi/2))}return new Vector2(a0/R0,M0/R0)}const L0=[];for(let F0=0,w0=S0.length,c0=w0-1,a0=F0+1;F0<w0;F0++,c0++,a0++)c0===w0&&(c0=0),a0===w0&&(a0=0),L0[F0]=fi(S0[F0],S0[c0],S0[a0]);const K0=[];let A0,J0=L0.concat();for(let F0=0,w0=l0;F0<w0;F0++){const c0=i0[F0];A0=[];for(let a0=0,M0=c0.length,R0=M0-1,N0=a0+1;a0<M0;a0++,R0++,N0++)R0===M0&&(R0=0),N0===M0&&(N0=0),A0[a0]=fi(c0[a0],c0[R0],c0[N0]);K0.push(A0),J0=J0.concat(A0)}let Gi;if(xt===0)Gi=ShapeUtils.triangulateShape(S0,i0);else{const F0=[],w0=[];for(let c0=0;c0<xt;c0++){const a0=c0/xt,M0=ht*Math.cos(a0*Math.PI/2),R0=ke*Math.sin(a0*Math.PI/2)+ct;for(let N0=0,P0=S0.length;N0<P0;N0++){const Mi=g0(S0[N0],L0[N0],R0);u0(Mi.x,Mi.y,-M0),a0===0&&F0.push(Mi)}for(let N0=0,P0=l0;N0<P0;N0++){const Mi=i0[N0];A0=K0[N0];const yi=[];for(let Xi=0,Ii=Mi.length;Xi<Ii;Xi++){const $0=g0(Mi[Xi],A0[Xi],R0);u0($0.x,$0.y,-M0),a0===0&&yi.push($0)}a0===0&&w0.push(yi)}}Gi=ShapeUtils.triangulateShape(F0,w0)}const Ci=Gi.length,Li=ke+ct;for(let F0=0;F0<I0;F0++){const w0=Gt?g0(e0[F0],J0[F0],Li):e0[F0];kt?(o0.copy(Yt.normals[0]).multiplyScalar(w0.x),s0.copy(Yt.binormals[0]).multiplyScalar(w0.y),h0.copy(Ft[0]).add(o0).add(s0),u0(h0.x,h0.y,h0.z)):u0(w0.x,w0.y,0)}for(let F0=1;F0<=at;F0++)for(let w0=0;w0<I0;w0++){const c0=Gt?g0(e0[w0],J0[w0],Li):e0[w0];kt?(o0.copy(Yt.normals[F0]).multiplyScalar(c0.x),s0.copy(Yt.binormals[F0]).multiplyScalar(c0.y),h0.copy(Ft[F0]).add(o0).add(s0),u0(h0.x,h0.y,h0.z)):u0(c0.x,c0.y,ot/at*F0)}for(let F0=xt-1;F0>=0;F0--){const w0=F0/xt,c0=ht*Math.cos(w0*Math.PI/2),a0=ke*Math.sin(w0*Math.PI/2)+ct;for(let M0=0,R0=S0.length;M0<R0;M0++){const N0=g0(S0[M0],L0[M0],a0);u0(N0.x,N0.y,ot+c0)}for(let M0=0,R0=i0.length;M0<R0;M0++){const N0=i0[M0];A0=K0[M0];for(let P0=0,Mi=N0.length;P0<Mi;P0++){const yi=g0(N0[P0],A0[P0],a0);kt?u0(yi.x,yi.y+Ft[at-1].y,Ft[at-1].x+c0):u0(yi.x,yi.y,ot+c0)}}}Ai(),Kt&&Fi();function Ai(){const F0=v.length/3;if(Gt){let w0=0,c0=I0*w0;if(Nt)for(let a0=0;a0<Ci;a0++){const M0=Gi[a0];vi(M0[2]+c0,M0[1]+c0,M0[0]+c0)}if(w0=at+xt*2,c0=I0*w0,Pt)for(let a0=0;a0<Ci;a0++){const M0=Gi[a0];vi(M0[0]+c0,M0[1]+c0,M0[2]+c0)}}else{if(Nt)for(let w0=0;w0<Ci;w0++){const c0=Gi[w0];vi(c0[2],c0[1],c0[0])}if(Pt)for(let w0=0;w0<Ci;w0++){const c0=Gi[w0];vi(c0[0]+I0*at,c0[1]+I0*at,c0[2]+I0*at)}}d.addGroup(F0,v.length/3-F0,0)}function Fi(){const F0=v.length/3;let w0=0;O0(S0,w0),w0+=S0.length;for(let c0=0,a0=i0.length;c0<a0;c0++){const M0=i0[c0];O0(M0,w0),w0+=M0.length}d.addGroup(F0,v.length/3-F0,1)}function O0(F0,w0){let c0=F0.length;for(;--c0>=0;){const a0=c0;let M0=c0-1;M0<0&&(M0=F0.length-1);for(let R0=0,N0=at+xt*2;R0<N0;R0++){const P0=I0*R0,Mi=I0*(R0+1),yi=w0+a0+P0,Xi=w0+M0+P0,Ii=w0+M0+Mi,$0=w0+a0+Mi;j0(yi,Xi,Ii,$0)}}}function u0(F0,w0,c0){Ne.push(F0),Ne.push(w0),Ne.push(c0)}function vi(F0,w0,c0){Q0(F0),Q0(w0),Q0(c0);const a0=v.length/3,M0=Wt.generateTopUV(d,v,a0-3,a0-2,a0-1);U0(M0[0]),U0(M0[1]),U0(M0[2])}function j0(F0,w0,c0,a0){Q0(F0),Q0(w0),Q0(a0),Q0(w0),Q0(c0),Q0(a0);const M0=v.length/3,R0=Wt.generateSideWallUV(d,v,M0-6,M0-3,M0-2,M0-1);U0(R0[0]),U0(R0[1]),U0(R0[3]),U0(R0[1]),U0(R0[2]),U0(R0[3])}function Q0(F0){v.push(Ne[F0*3+0]),v.push(Ne[F0*3+1]),v.push(Ne[F0*3+2])}function U0(F0){C.push(F0.x),C.push(F0.y)}}}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}toJSON(){const t=super.toJSON(),r=this.parameters.shapes,d=this.parameters.options;return Ie(r,d,t)}static fromJSON(t,r){const d=[];for(let C=0,w=t.shapes.length;C<w;C++){const E=r[t.shapes[C]];d.push(E)}const v=t.options.extrudePath;return v!==void 0&&(t.options.extrudePath=new Ue[`${v.type}`]().fromJSON(v)),new zn(d,t.options)}};const Ce={generateTopUV:function(g,t,r,d,v){const C=t[r*3],w=t[r*3+1],E=t[d*3],ye=t[d*3+1],Le=t[v*3],Re=t[v*3+1];return[new Vector2(C,w),new Vector2(E,ye),new Vector2(Le,Re)]},generateSideWallUV:function(g,t,r,d,v,C){const w=t[r*3],E=t[r*3+1],ye=t[r*3+2],Le=t[d*3],Re=t[d*3+1],Ne=t[d*3+2],Fe=t[v*3],at=t[v*3+1],ot=t[v*3+2],Gt=t[C*3],ht=t[C*3+1],ke=t[C*3+2];return Math.abs(E-Re)<Math.abs(w-Le)?[new Vector2(w,1-ye),new Vector2(Le,1-Ne),new Vector2(Fe,1-ot),new Vector2(Gt,1-ke)]:[new Vector2(E,1-ye),new Vector2(Re,1-Ne),new Vector2(at,1-ot),new Vector2(ht,1-ke)]}};function Ie(g,t,r){if(r.shapes=[],Array.isArray(g))for(let d=0,v=g.length;d<v;d++){const C=g[d];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 Ye extends ie$1{constructor(t){super(),this.rectAreaLightUniformsLibInit=!1,this.options=t}create(){var t,r,d,v,C,w,E,ye,Le,Re,Ne,Fe,at,ot,Gt,ht,ke;const ct=this.options;if(ct.type==="AmbientLight"){const xt=new AmbientLight(ct.color);xt.name="环境光",this.object3d=xt}else if(ct.type==="DirectionalLight"){const xt=new DirectionalLight(ct.color,ct.intensity);xt.name="平行光",xt.target.position.set(0,0,0),this.object3d=xt,xt.target.name="平行光目标",xt.shadow.camera.name="平行光阴影相机",xt.shadow.camera.userData.directionalLightShadow=!0,this.directionalLight=xt}else if(ct.type==="PointLight"){const xt=new PointLight((t=ct.color)!=null?t:16777215,(r=ct.intensity)!=null?r:1,(d=ct.distance)!=null?d:0,(v=ct.decay)!=null?v:2);xt.name="点光源",this.object3d=xt,this.pointLight=xt}else if(ct.type==="SpotLight"){const xt=new SpotLight((C=ct.color)!=null?C:16777215,(w=ct.intensity)!=null?w:1,(E=ct.distance)!=null?E:0,(ye=ct.angle)!=null?ye:Math.PI/3,(Le=ct.penumbra)!=null?Le:1,(Re=ct.decay)!=null?Re:2);xt.name="聚光灯",this.object3d=xt,this.spotLight=xt,xt.target.name="聚光灯目标"}else if(ct.type==="HemisphereLight"){const xt=new HemisphereLight((Ne=ct.color)!=null?Ne:16777215,(Fe=ct.groundColor)!=null?Fe:16777215,(at=ct.intensity)!=null?at:1);xt.name="半球光",this.object3d=xt,this.hemisphereLight=xt}else if(ct.type==="RectAreaLight"){this.rectAreaLightUniformsLibInit||(RectAreaLightUniformsLib.init(),this.rectAreaLightUniformsLibInit=!0);const xt=new RectAreaLight((ot=ct.color)!=null?ot:16777215,(Gt=ct.intensity)!=null?Gt:1,(ht=ct.width)!=null?ht:10,(ke=ct.height)!=null?ke:10);xt.name="矩形区域光",this.object3d=xt,this.rectAreaLight=xt}}render(){const t=this.object3d;t.target&&this.pencil.scene.add(t.target);const r=this.pencil.cameraTarget;if(this.spotLight||this.directionalLight){const d=this.spotLight||this.directionalLight;d.position.copy(r),d.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,d=new Set(Object.keys(g[0].attributes)),v=new Set(Object.keys(g[0].morphAttributes)),C={},w={},E=g[0].morphTargetsRelative,ye=new BufferGeometry;let Le=0;for(let Re=0;Re<g.length;++Re){const Ne=g[Re];let Fe=0;if(r!==(Ne.index!==null))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const at in Ne.attributes){if(!d.has(at))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+'. All geometries must have compatible attributes; make sure "'+at+'" attribute exists among all geometries, or in none of them.'),null;C[at]===void 0&&(C[at]=[]),C[at].push(Ne.attributes[at]),Fe++}if(Fe!==d.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". Make sure all geometries have the same number of attributes."),null;if(E!==Ne.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const at in Ne.morphAttributes){if(!v.has(at))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". .morphAttributes must be consistent throughout all geometries."),null;w[at]===void 0&&(w[at]=[]),w[at].push(Ne.morphAttributes[at])}if(t){let at;if(r)at=Ne.index.count;else if(Ne.attributes.position!==void 0)at=Ne.attributes.position.count;else return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+Re+". The geometry must have either an index or a position attribute"),null;if(t===1)ye.addGroup(Le,at,Re);else if(t===2&&Ne.groups.length>0)for(let ot of Ne.groups){let Gt=ot.materialIndex;ye.addGroup(Le+ot.start,Math.min(ot.count,at),Gt)}Le+=at}}if(r){let Re=0;const Ne=[];for(let Fe=0;Fe<g.length;++Fe){const at=g[Fe].index;for(let ot=0;ot<at.count;++ot)Ne.push(at.getX(ot)+Re);Re+=g[Fe].attributes.position.count}ye.setIndex(Ne)}for(const Re in C){const Ne=mergeAttributes(C[Re]);if(!Ne)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+Re+" attribute."),null;ye.setAttribute(Re,Ne)}for(const Re in w){const Ne=w[Re][0].length;if(Ne===0)break;ye.morphAttributes=ye.morphAttributes||{},ye.morphAttributes[Re]=[];for(let Fe=0;Fe<Ne;++Fe){const at=[];for(let Gt=0;Gt<w[Re].length;++Gt)at.push(w[Re][Gt][Fe]);const ot=mergeAttributes(at);if(!ot)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+Re+" morphAttribute."),null;ye.morphAttributes[Re].push(ot)}}return t===2?mergeGroups(ye):ye}const Dt=g=>{const{points:t}=g,r=t.reduce((d,v,C)=>(C<t.length-1&&d.push(v,t[C+1]),d),[]);return new BufferGeometry().setFromPoints(r)};let Ze=class extends ie$1{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:d,material:v,useGroups:C,setPointWidth:w,lineWidthArr:E,materialParameters:ye,instanceCount:Le}=this.options;let Re=v,Ne=r;!Re&&ye&&(Re=this.getMaterial(ye)),!Ne&&g?Ne=Dt({points:g}):!Ne&&t?Ne=R$1(t.map(at=>Dt({points:at})),C!=null?C:0):!Ne&&d&&d.length>1?Ne=R$1(d,C!=null?C:0):!Ne&&d&&d.length===1&&([Ne]=d);const Fe=new LineSegmentsGeometry().fromLineSegments(new LineSegments(Ne));if(this.pencil.options.WebGPUTHREE){Le&&(Fe.instanceCount=Le);const at=new De(Fe,Re);at.computeLineDistances(),this.object3d=at}else{const at=new LineSegments2(Fe,Re);at.computeLineDistances(),this.object3d=at}})}getMaterial(g){return new LineMaterial(G({color:new Color$1("#ffffff")},g))}};function yt(g,t,r,d,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,d);else for(C=0;C<g.length;C++)r[C+d]=g[C];return r}function Be(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 Ve 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=Be(t),this._points=t,this.widthCallback=r!=null?r:null,this.positions=[],this.counters=[],t.length&&t[0]instanceof Vector3)for(let d=0;d<t.length;d++){const v=t[d],C=d/(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 d=0;d<t.length;d+=3){const v=d/(t.length-1);this.positions.push(t[d],t[d+1],t[d+2]),this.positions.push(t[d],t[d+1],t[d+2]),this.counters.push(v),this.counters.push(v)}this.process()}compareV3(t,r){const d=t*6,v=r*6;return this.positions[d]===this.positions[v]&&this.positions[d+1]===this.positions[v+1]&&this.positions[d+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,d;this.compareV3(0,t-1)?d=this.copyV3(t-2):d=this.copyV3(0),this.previous.push(d[0],d[1],d[2]),this.previous.push(d[0],d[1],d[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){d=this.copyV3(v),this.previous.push(d[0],d[1],d[2]),this.previous.push(d[0],d[1],d[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&&(d=this.copyV3(v),this.next.push(d[0],d[1],d[2]),this.next.push(d[0],d[1],d[2]))}this.compareV3(t-1,0)?d=this.copyV3(1):d=this.copyV3(t-1),this.next.push(d[0],d[1],d[2]),this.next.push(d[0],d[1],d[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:d}){const v=this._attributes.position.array,C=this._attributes.previous.array,w=this._attributes.next.array,E=v.length;yt(v,0,C,0,E),yt(v,6,v,0,E-6),v[E-6]=t,v[E-5]=r,v[E-4]=d,v[E-3]=t,v[E-2]=r,v[E-1]=d,yt(v,6,w,0,E-6),w[E-6]=t,w[E-5]=r,w[E-4]=d,w[E-3]=t,w[E-2]=r,w[E-1]=d,this._attributes.position.needsUpdate=!0,this._attributes.previous.needsUpdate=!0,this._attributes.next.needsUpdate=!0}}const bt=g=>{const{setPointWidth:t,nodes:r}=g,d=new Ve;return d.setPoints(r,t),d};class ts extends ie$1{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:d,geometryArr:v,material:C,useGroups:w,setPointWidth:E,lineWidthArr:ye,materialParameters:Le}=this.options;let Re=C,Ne=d;!Re&&Le&&(Re=this.getMaterial(Le)),!Ne&&t?Ne=bt({nodes:t,setPointWidth:E}):!Ne&&r?Ne=R$1(r.map((Fe,at)=>{let ot=E;return!ot&&ye&&(ot=()=>{var Gt;return(Gt=ye[at])!=null?Gt:ye[0]}),bt({nodes:Fe,setPointWidth:ot})}),w!=null?w:0):!Ne&&v&&v.length>1?Ne=R$1(v,w!=null?w:0):!Ne&&v&&v.length===1&&([Ne]=v),this.createMesh(Ne,Re)})}setGeometry(t,r){const d=bt({nodes:t,setPointWidth:r}),v=this.object3d,C=v.geometry;v.geometry=d,C.dispose()}getMaterial(t){const{width:r,height:d}=this.pencil.getSize();return new Ie$2(G({color:new Color$1("#ffffff"),resolution:new Vector2(r,d)},t))}addGeometries(t){const r=this.object3d,d=R$1([r.geometry,...t]);r.geometry=d}resize(t,r){var d,v;(v=(d=this.material)==null?void 0:d.uniforms)==null||v.resolution.value.set(t,r)}useMaterial(t){super.useMaterial(t);const{width:r,height:d}=this.pencil.getSize();this.resize(r,d)}animate({duration:t=1e3,delay:r=0,repeat:d=0,lineLoop:v,onRepeat:C,onUpdate:w,onComplete:E,startShow:ye}={}){const{offset:Le,offsetLoop:Re}=this.material.uniforms;if(this.material.userData.tween)return;const Ne=v!=null?v:!0;Le.value.x=1,Re.value=Ne&&ye?1:0;let Fe=0;const at=new Tween(Le.value).to({x:-1},t).delay(r).repeat(d).onUpdate(({x:ot})=>{Ne&&ot<=0&&Re.value===0&&(Re.value=1),w&&w(ot)}).onRepeat(()=>{Fe+=1,C&&C(Fe)}).onComplete(()=>{E&&E()}).start();this.material.userData.tween=at}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:d,height:v}=t,C=gt(t,["coordinate","startHeight","height"]);let w=d||0;return typeof d!="undefined"&&typeof v!="undefined"&&(w=d+v),new Te$1([r],ut(G({},C),{startHeight:d,endHeight:w}))};class es extends ie$1{constructor(t){super(),this.options=G({},t)}create(){const t=this.options,{geometry:r,coordinateArr:d,coordinate:v,material:C,useGroups:w}=t,E=gt(t,["geometry","coordinateArr","coordinate","material","useGroups"]);let ye=r;if(!ye&&v)ye=Ot(G({coordinate:v},E));else if(!ye&&d){const Le=d.map(Re=>Ot(G({coordinate:Re},E)));ye=R$1(Le,w!=null?w:0)}this.createMesh(ye,C)}}class ze extends Y$1{constructor(t,r){super(t,r);const d=new Brush(new Y$1(t,ut(G({},r),{hasTop:!0,hasSide:!0,hasBottom:!1})));d.updateMatrixWorld();const v=new Box3().setFromObject(d),C=new Vector3;v.getSize(C);const w=new Vector3(v.min.x+C.x/2,v.min.y+C.y/2,0);let E=r.topSegments,ye=r.box3;if(ye){ye=ye.union(v);const ht=new Vector3;ye.getSize(ht);const ke=Math.max(C.x/ht.x,C.y/ht.y);E=Math.ceil(r.topSegments*ke)}if(E<4)return this;const Le=new PlaneGeometry(C.x,C.y,E,E),Re=new Brush(Le);Re.position.set(w.x,w.y,w.z),Re.updateMatrixWorld();const Ne=new Evaluator().evaluate(Re,d,INTERSECTION),Fe=Ne.geometry.getAttribute("position"),at=new Float32BufferAttribute(Fe.count*2,2);for(let ht=0;ht<Fe.count;ht++){const ke=Fe.getZ(ht);Fe.setZ(ht,r.depth+ke)}if(ye){const ht=ye.min,ke=ye.max,ct=new Vector3().subVectors(ke,ht);for(let xt=0;xt<Fe.count;xt++){const Rt=Fe.getX(xt),Wt=Fe.getY(xt),Pt=(Rt-ht.x)/ct.x,Nt=(Wt-ht.y)/ct.y;at.setXY(xt,Pt,Nt)}Ne.geometry.setAttribute("uv",at)}Fe.needsUpdate=!0;const ot=new Y$1(t,ut(G({},r),{hasTop:!1})),Gt=R$1([Ne.geometry,ot],2);this.copy(Gt.toNonIndexed())}}const Ht=g=>{const{split:t,depth:r,points:d,box3:v,hasTop:C,hasBottom:w,hasSide:E,sideRepeat:ye,topSegments:Le}=g,Re=Le?ze:Y$1,Ne=new Re(new Shape(d),{depth:r,bevelEnabled:!1,box3:v,UVGenerator:R$2({split:t,box3:v,sideRepeat:ye}),hasTop:C,hasBottom:w,hasSide:E,topSegments:Le});return P(),Ne};class ss extends ie$1{constructor(t){super(),this.options=G({depth:1},t)}create(){return nt(this,null,function*(){const{points:t,pointsArr:r,useGroups:d,depth:v,geometry:C,geometryArr:w,material:E,box3:ye,split:Le,hasTop:Re,hasBottom:Ne,hasSide:Fe}=this.options,at=Array.isArray(v)?v:[v],ot=Array.isArray(ye)?ye:[ye],Gt=E;let ht=C;Gt||console.log("material is null"),!ht&&t?ht=Ht({points:t,depth:at[0],box3:ot[0],split:Le,hasTop:Re,hasBottom:Ne,hasSide:Fe}):!ht&&r?ht=R$1(r.map((ke,ct)=>{var xt,Rt;return Ht({points:ke,depth:(xt=at[ct])!=null?xt:at[0],box3:(Rt=ot[ct])!=null?Rt:ot[0],split:Le,hasTop:Re,hasBottom:Ne,hasSide:Fe})}),d!=null?d:0):!ht&&w&&w.length>1?ht=R$1(w,d!=null?d:0):!ht&&w&&w.length===1&&([ht]=w),this.createMesh(ht,Gt)})}addGeometries(t){const r=this.object3d,d=R$1([r.geometry,...t]);r.geometry=d}setTextureAnisotropic(t,r){t.anisotropy=r||this.pencil.renderer.capabilities.getMaxAnisotropy()}}class Light extends Ye{update(t,r){var v;super.update(t,r);const d=this.object3d;(v=d.shadow)!=null&&v.camera&&(d.shadow.camera.near!==this.pencil.camera.near&&(d.shadow.camera.near=this.pencil.camera.near),d.shadow.camera.far!=this.pencil.camera.far&&(d.shadow.camera.far=this.pencil.camera.far))}render(){super.render();const t=this.object3d;t.userData=new Proxy({},{set:(E,ye,Le)=>(ye==="keepCamera"&&(Le?(this.pencil.render(),t.userData.parent=t.parent,this.pencil.camera.attach(t),t.target&&this.pencil.camera.attach(t.target)):!Le&&t.userData.parent&&(this.pencil.render(),t.userData.parent.attach(t),t.target&&t.userData.parent.attach(t.target))),Reflect.set(E,ye,Le))});const{type:r,key:d}=this.options;d?(this.lead.updateBaseObjectKey(this,`${r}_${d}`),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 w=this.object3d;w.isPointLight&&(w.shadow.mapSize.width=1024,w.shadow.mapSize.height=1024)}}class Point extends ie$1{constructor(r){super();_0(this,"options");_0(this,"scaleValue",1);this.options=bi({sprite:!0},r)}get material(){var r;return(r=this.object3d)==null?void 0:r.material}getMaterial(){const{sprite:r}=this.options,d=document.createElement("canvas");d.width=100,d.height=100;const v=d.getContext("2d");v.beginPath(),v.arc(50,50,50,0,2*Math.PI),v.fillStyle="#ffffff",v.fill(),v.closePath();const C=new CanvasTexture(d);return r?new SpriteMaterial({transparent:!0,map:C}):new MeshBasicMaterial({color:16777215,transparent:!0,map:C})}create(){return D0(this,null,function*(){const{sprite:r}=this.options,d=this.getMaterial();r?this.createSprite(d):this.createMesh(new PlaneGeometry(1,1),d),this.setScale(1),this.object3d.scale.multiplyScalar(.1)})}setScale(r){this.scaleValue=r;const d=this.material.map;d!=null&&d.image?this.object3d.scale.set(d.image.width*r,d.image.height*r,1):this.object3d.scale.set(r,r,1)}}const l={mercator:s$1,equirectangular:i$2,fahey:p},a$1={},m=g=>{var t,r,d;const v=JSON.stringify(g);if(a$1[v])return a$1[v];const C=l[(t=g.projectionType)!=null?t:"mercator"]().center(g.center).scale(g.scale).translate((r=g.translate)!=null?r:[0,0]).precision((d=g.precision)!=null?d:.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 d=document.createElement("canvas");d.width=256,d.height=1;const v=d.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 w=new CanvasTexture(d);return w.wrapS=RepeatWrapping,w.wrapT=RepeatWrapping,w.needsUpdate=!0,w},createFlyPath=(g,t,r=40)=>{const d=g.angleTo(t);let v=g.clone().add(t);v=v.normalize().multiplyScalar(r);let C;d<=1?C=r/5*d:d>1&&d<2?C=r/5*mn(d,2):C=r/5*mn(d,1.5);const w=g.clone().add(v).normalize().multiplyScalar(r+C),E=t.clone().add(v).normalize().multiplyScalar(r+C);return new CubicBezierCurve3(g,w,E,t)},createFlyPath2=(g,t,r=40)=>{const d=new Vector3().lerpVectors(g,t,.25),v=new Vector3().lerpVectors(g,t,.75);return d.z+=r,v.z+=r,new CubicBezierCurve3(g,d,v,t)},pixel2unit=(g,t)=>{const d=g.camera.fov*Math.PI/180,v=g.controls.getPosition(new Vector3,!1),C=2*Math.tan(d/2)*v.z,w=g.getSize(),E=w.width/w.width,ye=C*E;return t*g.renderer.getPixelRatio()/w.width/(1/ye)};let map;class Arc extends ie$1{constructor(r){super();_0(this,"options");_0(this,"line");_0(this,"helperMesh");_0(this,"helperMeshPosition");_0(this,"pickTube",null);this.options=bi({color:"#ffffff",lineWidth:6,globe:!1,offsetLoop:!0},r),this.options.repeat&&this.options.repeat[0]===.5&&(this.options.offsetLoop=!1)}static getInitOptions(r,d){const v=pixel2unit(r,200),C=d.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)),w=d.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:w.toArray()}}create(){return D0(this,null,function*(){map||(map=getLineTexture(.5));const{color:r,lineWidth:d,globe:v}=this.options;let{radius:C}=this.options;const w=h(this.options.from||[0,0,0]),E=h(this.options.to||[0,0,0]);C=C!=null?C:w.distanceTo(E);const ye=v?createFlyPath(w,E,C):createFlyPath2(w,E,C),Le=ye.getPoints(1500),Re=this.pencil.lead,Ne=yield Re.draw("Line",{nodes:Le,setPointWidth:ht=>ht*1,materialParameters:{color:r,map,useMap:1,transparent:!0,sizeAttenuation:0,lineWidth:d}},null);this.line=Ne,this.object3d=Ne.object3d;const[Fe,at,ot,Gt]=yield Promise.all([{key:"Arc_起点",position:ye.v0},{key:"Arc_第一控制点",position:ye.v1},{key:"Arc_第二控制点",position:ye.v2},{key:"Arc_终点",position:ye.v3}].map(ct=>D0(this,[ct],function*({key:ht,position:ke}){const xt=yield Re.draw("Group",{},this);return xt.position.copy(ke),xt.userData.disabledCR=!0,xt.userData.disabledTC=!1,Re.updateBaseObjectKey(xt,`${ht}_${this.options.key}`),xt})));this.helperMesh=[Fe,at,ot,Gt],this.helperMeshPosition=[Fe.position.clone(),at.position.clone(),ot.position.clone(),Gt.position.clone()]})}instantiate(){return D0(this,null,function*(){this.update();const r=yield this.line.instantiate(void 0,{recursive:!1}),d=yield yn(Arc.prototype,this,"instantiate").call(this,void 0,{create:v=>{v.line=r,v.object3d=r.object3d}});return d.position.set(0,0,0),d.rotation.set(0,0,0),d.scale.set(1,1,1),d})}setPath(r,d,v,C=w=>w*1){const{globe:w}=this.options;r=h(r),d=h(d);const ye=(w?createFlyPath(r,d,v):createFlyPath2(r,d,v)).getPoints(1500);this.line.options.nodes=ye,this.line.setGeometry(ye,C),this.pickTube&&this.addPickTarget(this.pickTube.options.radius)}addPickTarget(r=1,d=!1){return D0(this,null,function*(){const v=this.pickTube,C=this.pencil.lead,w=this.line.options.nodes,E=new CurvePath;for(let Re=0;Re<w.length-1;Re++)E.add(new LineCurve3(w[Re],w[Re+1]));const ye=yield C.draw("Tube",{path:E,radius:r,multiplyScalar:1},this),Le=ye.object3d;return Le.material=new MeshBasicMaterial({color:16711680,transparent:!0,opacity:d?1:0}),v&&(v.userData._pe_&&ye.onPointerEvent(...v.userData._pe_),v.erase()),this.pickTube=ye,ye})}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:d=0,repeat:v=1/0,onComplete:C,onRepeat:w}={}){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:d,lineLoop:this.options.offsetLoop,onRepeat:w,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,E)=>{this.helperMeshPosition[E].copy(w.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.track(this.line),setTimeout(()=>{!this.pencil.userData.EditorEnv&&this.prefab||this.line.material.userData.tween||this.animateIn()})}}class CrossPlane extends ie$1{constructor(r){super();_0(this,"options");this.options=bi({},r)}create(){return D0(this,null,function*(){const v=new PlaneGeometry(.5,5,2,2);this.createGroup();const C=this.options.material||new MeshBasicMaterial({color:"#ffffff",side:DoubleSide});C.depthWrite=!1;const w=new Mesh(v,C),E=w.clone();w.rotation.x=-Math.PI*.5,E.rotation.x=-Math.PI*.5,E.rotation.y=-Math.PI*.5,w.translateY(5/2),E.translateY(5/2),this.add(w,E),this.userData.material=C,this.userData.disabledTC=!1})}}class PlaneShadow extends ie$1{create(){return D0(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 ie$1{constructor(r){super();_0(this,"options");this.options=bi({},r)}create(){return D0(this,null,function*(){const r=this.pencil.loader,d=this.options.src;if(!d)throw new Error("src is required");let v=r.getAsset(d);v||(v=yield r.load(d)),this.object3d=v.scene,this.scale.multiplyScalar(20)})}}class Box extends ie$1{create(){const t=new BoxGeometry(1,1,1,1,1,1);this.createMesh(t),this.scale.multiplyScalar(20)}}class Capsule extends ie$1{create(){const t=new CapsuleGeometry(1,1,4,8);this.createMesh(t),this.scale.multiplyScalar(20)}}class Circle extends ie$1{create(){const t=new CircleGeometry(1,32,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Cylinder extends ie$1{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 ie$1{create(){const t=new DodecahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Icosahedron extends ie$1{create(){const t=new IcosahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Lathe extends ie$1{create(){const t=new LatheGeometry;this.createMesh(t,new MeshStandardMaterial({side:DoubleSide})),this.scale.multiplyScalar(20)}}class Octahedron extends ie$1{create(){const t=new OctahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Plane extends ie$1{create(){const t=new PlaneGeometry(1,1,2,2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Ring extends ie$1{create(){const t=new RingGeometry(.5,1,32,1,0,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class Sphere extends ie$1{constructor(){super(...arguments);_0(this,"radius",100);_0(this,"material");_0(this,"options")}create(){var d;(d=this.options)!=null&&d.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 ie$1{create(){this.createSprite(new SpriteMaterial),this.scale.multiplyScalar(20)}setDesiredPixelSize(t){var d;const r=this.object3d;if((d=r.material.map)!=null&&d.image){const v=this.pencil.camera,C=new Vector3;v.matrixWorld.decompose(C,new Quaternion,new Vector3);const w=MathUtils.degToRad(v.fov),ye=this.pencil.getSize().height*(1/(2*Math.tan(w/2))),Le=t/ye,{width:Re,height:Ne}=r.material.map.image;r.scale.set(Re/Ne*Le,Le,1)}}}class Tetrahedron extends ie$1{create(){const t=new TetrahedronGeometry(1,0);this.createMesh(t),this.scale.multiplyScalar(20)}}class Torus extends ie$1{create(){const t=new TorusGeometry(1,.4,12,48,Math.PI*2);this.createMesh(t),this.scale.multiplyScalar(20)}}class TorusKnot extends ie$1{create(){const t=new TorusKnotGeometry(1,.4,64,8,2,3);this.createMesh(t),this.scale.multiplyScalar(20)}}class Tube extends ie$1{constructor(r){super();_0(this,"options");this.options=r}create(){var w,E;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)]),d=(w=this.options.radius)!=null?w:1,v=(E=this.options.multiplyScalar)!=null?E:20,C=new TubeGeometry(r,64,d,8,!1);this.createMesh(C),this.scale.multiplyScalar(v)}}const baseObjs={Node:Xe,Line:ts,Line2:Ze,ExtrudePolygon:ss,ConicPolygon:es,Group:ze$1,Light,Point,Arc,Model},expObjs={Plane,CrossPlane,PlaneShadow,Ring,Sphere,Sprite,Tetrahedron,Torus,TorusKnot,Tube,Box,Capsule,Circle,Cylinder,Dodecahedron,Icosahedron,Lathe,Octahedron},prefabType=Object.keys(Di(bi({},expObjs),{Arc,Model})).map(g=>g),objs$3=bi(bi({},baseObjs),expObjs);class MaterialList{constructor(){_0(this,"pluginName","materialList");_0(this,"pencil");_0(this,"materials",new Map);_0(this,"baseObjects",new Map);_0(this,"fixBufferGeometry",new BufferGeometry);_0(this,"wrapObject")}install(t){this.pencil=t,this.wrapObject=this.makeBaseObject({key:"MaterialList",name:"材质列表",isGroup:!0,childrenGetter:()=>this.buildMaterialObjectHierarchy()})}buildMaterialObjectHierarchy(){const t=[],r={};return this.baseObjects.forEach((d,v)=>{if(v.includes("#")){const[C]=v.split("#");r[C]||(r[C]=this.makeBaseObject({key:C,name:C,isGroup:!0}),t.push(r[C])),r[C].children.push(d)}else t.push(d)}),t}makeBaseObject({key:t,name:r,isGroup:d=!1,childrenGetter:v,object3d:C}){const w={key:t,userData:{},children:v?[]:[]};return C?(w.object3d=C,r&&(w.object3d.name=r)):w.object3d={isGroup:d,name:r||t,userData:{fixBufferGeometry:!0}},v&&Object.defineProperty(w,"children",{get:v,enumerable:!0}),w}setUserData(t,r){const d=this.baseObjects.get(t);d&&(d.userData=bi(bi({},d.userData),r),this.emitObject3dChange())}add(t,r){this.materials.set(t,r);const d=new Proxy(new Mesh(this.fixBufferGeometry,r),{set:(C,w,E)=>w==="material"?(C.material=E,this.materials.set(t,E),!0):Reflect.set(C,w,E)});d.userData.fixBufferGeometry=!0;const v=this.makeBaseObject({name:r.name,key:t,object3d:d});this.baseObjects.set(t,v),this.emitObject3dChange()}addMultiple(t,r){for(const[d,v]of Object.entries(r)){const C=`${t}#${d}`;v&&this.add(C,v)}}get(t){const r=this.materials.get(t);return r||console.warn(`Material with key "${t}" not found.`),r}getBaseObjectByMaterial(t){for(const[r,d]of this.materials.entries())if(d===t)return this.baseObjects.get(r);return null}getMultiple(t){const r={},d=`${t}#`;let v=!1;for(const[C,w]of this.materials.entries())if(C.startsWith(d)){const E=C.substring(d.length);r[E]=w,v=!0}return v?r:null}copyMultiple(t,r){const d={},v=`${t}#`;for(const[C,w]of this.materials.entries())if(C.startsWith(v)){const E=C.substring(v.length),ye=w.clone();d[E]=ye;const Le=`${r}#${E}`;this.add(Le,ye)}return d}remove(t){this.materials.delete(t),this.baseObjects.delete(t),this.emitObject3dChange()}clear(){this.materials.clear(),this.baseObjects.clear(),this.emitObject3dChange()}getKeys(){return Array.from(this.materials.keys())}emitObject3dChange(){var t;(t=this.pencil)==null||t.event.emit("baseObjectListChange")}dispose(){const t=new O;t.track([...this.materials.values()]),t.dispose(),this.fixBufferGeometry.dispose(),this.materials.clear(),this.baseObjects.clear()}}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 d=promisifyRequest(r);return(v,C)=>d.then(w=>C(w.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(d=>r.put(d[1],d[0])),promisifyRequest(r.transaction)))}var H=Object.defineProperty,u=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable,s=(g,t,r)=>t in g?H(g,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[t]=r,W=(g,t)=>{for(var r in t||(t={}))a.call(t,r)&&s(g,r,t[r]);if(u)for(var r of u(t))Y.call(t,r)&&s(g,r,t[r]);return g},x=(g,t)=>{var r={};for(var d in g)a.call(g,d)&&t.indexOf(d)<0&&(r[d]=g[d]);if(g!=null&&u)for(var d of u(g))t.indexOf(d)<0&&Y.call(g,d)&&(r[d]=g[d]);return r},V=(g,t,r)=>new Promise((d,v)=>{var C=ye=>{try{E(r.next(ye))}catch(Le){v(Le)}},w=ye=>{try{E(r.throw(ye))}catch(Le){v(Le)}},E=ye=>ye.done?d(ye.value):Promise.resolve(ye.value).then(C,w);E((r=r.apply(g,t)).next())});const o="dmFyIFNnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSx2Zz1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgemc9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIFhyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIEx1PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksT3U9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgaGM9KEosUSk9PihRPVN5bWJvbFtKXSk/UTpTeW1ib2wuZm9yKCJTeW1ib2wuIitKKSxUZz1KPT57dGhyb3cgVHlwZUVycm9yKEopfSxkaT1NYXRoLnBvdyxSdT0oSixRLG10KT0+USBpbiBKP1NnKEosUSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6bXR9KTpKW1FdPW10LEZ0PShKLFEpPT57Zm9yKHZhciBtdCBpbiBRfHwoUT17fSkpTHUuY2FsbChRLG10KSYmUnUoSixtdCxRW210XSk7aWYoWHIpZm9yKHZhciBtdCBvZiBYcihRKSlPdS5jYWxsKFEsbXQpJiZSdShKLG10LFFbbXRdKTtyZXR1cm4gSn0sR2U9KEosUSk9PnZnKEosemcoUSkpO3ZhciBEdT0oSixRKT0+e3ZhciBtdD17fTtmb3IodmFyIE10IGluIEopTHUuY2FsbChKLE10KSYmUS5pbmRleE9mKE10KTwwJiYobXRbTXRdPUpbTXRdKTtpZihKIT1udWxsJiZYcilmb3IodmFyIE10IG9mIFhyKEopKVEuaW5kZXhPZihNdCk8MCYmT3UuY2FsbChKLE10KSYmKG10W010XT1KW010XSk7cmV0dXJuIG10fTt2YXIgRWc9ZnVuY3Rpb24oSixRKXt0aGlzWzBdPUosdGhpc1sxXT1RfTt2YXIgJHU9Sj0+e3ZhciBRPUpbaGMoImFzeW5jSXRlcmF0b3IiKV0sbXQ9ITEsTXQsYW49e307cmV0dXJuIFE9PW51bGw/KFE9SltoYygiaXRlcmF0b3IiKV0oKSxNdD1BZT0+YW5bQWVdPUNuPT5RW0FlXShDbikpOihRPVEuY2FsbChKKSxNdD1BZT0+YW5bQWVdPUNuPT57aWYobXQpe2lmKG10PSExLEFlPT09InRocm93Iil0aHJvdyBDbjtyZXR1cm4gQ259cmV0dXJuIG10PSEwLHtkb25lOiExLHZhbHVlOm5ldyBFZyhuZXcgUHJvbWlzZSh1Yz0+e3ZhciBKcj1RW0FlXShDbik7SnIgaW5zdGFuY2VvZiBPYmplY3R8fFRnKCJPYmplY3QgZXhwZWN0ZWQiKSx1YyhKcil9KSwxKX19KSxhbltoYygiaXRlcmF0b3IiKV09KCk9PmFuLE10KCJuZXh0IiksInRocm93ImluIFE/TXQoInRocm93Iik6YW4udGhyb3c9QWU9Pnt0aHJvdyBBZX0sInJldHVybiJpbiBRJiZNdCgicmV0dXJuIiksYW59OyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTAtMjAyNSBUaHJlZS5qcyBBdXRob3JzCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKICovY29uc3QgSj0iMTc2IixmYz0iIixvZT0ic3JnYiIsZGM9InNyZ2ItbGluZWFyIixwYz0ibGluZWFyIixZcj0ic3JnYiI7Y2xhc3MgaXN7YWRkRXZlbnRMaXN0ZW5lcih0LGUpe3RoaXMuX2xpc3RlbmVycz09PXZvaWQgMCYmKHRoaXMuX2xpc3RlbmVycz17fSk7Y29uc3Qgbj10aGlzLl9saXN0ZW5lcnM7blt0XT09PXZvaWQgMCYmKG5bdF09W10pLG5bdF0uaW5kZXhPZihlKT09PS0xJiZuW3RdLnB1c2goZSl9aGFzRXZlbnRMaXN0ZW5lcih0LGUpe2NvbnN0IG49dGhpcy5fbGlzdGVuZXJzO3JldHVybiBuPT09dm9pZCAwPyExOm5bdF0hPT12b2lkIDAmJm5bdF0uaW5kZXhPZihlKSE9PS0xfXJlbW92ZUV2ZW50TGlzdGVuZXIodCxlKXtjb25zdCBuPXRoaXMuX2xpc3RlbmVycztpZihuPT09dm9pZCAwKXJldHVybjtjb25zdCBzPW5bdF07aWYocyE9PXZvaWQgMCl7Y29uc3Qgcj1zLmluZGV4T2YoZSk7ciE9PS0xJiZzLnNwbGljZShyLDEpfX1kaXNwYXRjaEV2ZW50KHQpe2NvbnN0IGU9dGhpcy5fbGlzdGVuZXJzO2lmKGU9PT12b2lkIDApcmV0dXJuO2NvbnN0IG49ZVt0LnR5cGVdO2lmKG4hPT12b2lkIDApe3QudGFyZ2V0PXRoaXM7Y29uc3Qgcz1uLnNsaWNlKDApO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLmNhbGwodGhpcyx0KTt0LnRhcmdldD1udWxsfX19Y29uc3QgQXQ9WyIwMCIsIjAxIiwiMDIiLCIwMyIsIjA0IiwiMDUiLCIwNiIsIjA3IiwiMDgiLCIwOSIsIjBhIiwiMGIiLCIwYyIsIjBkIiwiMGUiLCIwZiIsIjEwIiwiMTEiLCIxMiIsIjEzIiwiMTQiLCIxNSIsIjE2IiwiMTciLCIxOCIsIjE5IiwiMWEiLCIxYiIsIjFjIiwiMWQiLCIxZSIsIjFmIiwiMjAiLCIyMSIsIjIyIiwiMjMiLCIyNCIsIjI1IiwiMjYiLCIyNyIsIjI4IiwiMjkiLCIyYSIsIjJiIiwiMmMiLCIyZCIsIjJlIiwiMmYiLCIzMCIsIjMxIiwiMzIiLCIzMyIsIjM0IiwiMzUiLCIzNiIsIjM3IiwiMzgiLCIzOSIsIjNhIiwiM2IiLCIzYyIsIjNkIiwiM2UiLCIzZiIsIjQwIiwiNDEiLCI0MiIsIjQzIiwiNDQiLCI0NSIsIjQ2IiwiNDciLCI0OCIsIjQ5IiwiNGEiLCI0YiIsIjRjIiwiNGQiLCI0ZSIsIjRmIiwiNTAiLCI1MSIsIjUyIiwiNTMiLCI1NCIsIjU1IiwiNTYiLCI1NyIsIjU4IiwiNTkiLCI1YSIsIjViIiwiNWMiLCI1ZCIsIjVlIiwiNWYiLCI2MCIsIjYxIiwiNjIiLCI2MyIsIjY0IiwiNjUiLCI2NiIsIjY3IiwiNjgiLCI2OSIsIjZhIiwiNmIiLCI2YyIsIjZkIiwiNmUiLCI2ZiIsIjcwIiwiNzEiLCI3MiIsIjczIiwiNzQiLCI3NSIsIjc2IiwiNzciLCI3OCIsIjc5IiwiN2EiLCI3YiIsIjdjIiwiN2QiLCI3ZSIsIjdmIiwiODAiLCI4MSIsIjgyIiwiODMiLCI4NCIsIjg1IiwiODYiLCI4NyIsIjg4IiwiODkiLCI4YSIsIjhiIiwiOGMiLCI4ZCIsIjhlIiwiOGYiLCI5MCIsIjkxIiwiOTIiLCI5MyIsIjk0IiwiOTUiLCI5NiIsIjk3IiwiOTgiLCI5OSIsIjlhIiwiOWIiLCI5YyIsIjlkIiwiOWUiLCI5ZiIsImEwIiwiYTEiLCJhMiIsImEzIiwiYTQiLCJhNSIsImE2IiwiYTciLCJhOCIsImE5IiwiYWEiLCJhYiIsImFjIiwiYWQiLCJhZSIsImFmIiwiYjAiLCJiMSIsImIyIiwiYjMiLCJiNCIsImI1IiwiYjYiLCJiNyIsImI4IiwiYjkiLCJiYSIsImJiIiwiYmMiLCJiZCIsImJlIiwiYmYiLCJjMCIsImMxIiwiYzIiLCJjMyIsImM0IiwiYzUiLCJjNiIsImM3IiwiYzgiLCJjOSIsImNhIiwiY2IiLCJjYyIsImNkIiwiY2UiLCJjZiIsImQwIiwiZDEiLCJkMiIsImQzIiwiZDQiLCJkNSIsImQ2IiwiZDciLCJkOCIsImQ5IiwiZGEiLCJkYiIsImRjIiwiZGQiLCJkZSIsImRmIiwiZTAiLCJlMSIsImUyIiwiZTMiLCJlNCIsImU1IiwiZTYiLCJlNyIsImU4IiwiZTkiLCJlYSIsImViIiwiZWMiLCJlZCIsImVlIiwiZWYiLCJmMCIsImYxIiwiZjIiLCJmMyIsImY0IiwiZjUiLCJmNiIsImY3IiwiZjgiLCJmOSIsImZhIiwiZmIiLCJmYyIsImZkIiwiZmUiLCJmZiJdO2Z1bmN0aW9uIEJuKCl7Y29uc3QgaT1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MCx0PU1hdGgucmFuZG9tKCkqNDI5NDk2NzI5NXwwLGU9TWF0aC5yYW5kb20oKSo0Mjk0OTY3Mjk1fDAsbj1NYXRoLnJhbmRvbSgpKjQyOTQ5NjcyOTV8MDtyZXR1cm4oQXRbaSYyNTVdK0F0W2k+PjgmMjU1XStBdFtpPj4xNiYyNTVdK0F0W2k+PjI0JjI1NV0rIi0iK0F0W3QmMjU1XStBdFt0Pj44JjI1NV0rIi0iK0F0W3Q+PjE2JjE1fDY0XStBdFt0Pj4yNCYyNTVdKyItIitBdFtlJjYzfDEyOF0rQXRbZT4+OCYyNTVdKyItIitBdFtlPj4xNiYyNTVdK0F0W2U+PjI0JjI1NV0rQXRbbiYyNTVdK0F0W24+PjgmMjU1XStBdFtuPj4xNiYyNTVdK0F0W24+PjI0JjI1NV0pLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gWihpLHQsZSl7cmV0dXJuIE1hdGgubWF4KHQsTWF0aC5taW4oZSxpKSl9ZnVuY3Rpb24gVXUoaSx0KXtyZXR1cm4oaSV0K3QpJXR9ZnVuY3Rpb24ganIoaSx0LGUpe3JldHVybigxLWUpKmkrZSp0fWZ1bmN0aW9uIHBpKGksdCl7c3dpdGNoKHQuY29uc3RydWN0b3Ipe2Nhc2UgRmxvYXQzMkFycmF5OnJldHVybiBpO2Nhc2UgVWludDMyQXJyYXk6cmV0dXJuIGkvNDI5NDk2NzI5NTtjYXNlIFVpbnQxNkFycmF5OnJldHVybiBpLzY1NTM1O2Nhc2UgVWludDhBcnJheTpyZXR1cm4gaS8yNTU7Y2FzZSBJbnQzMkFycmF5OnJldHVybiBNYXRoLm1heChpLzIxNDc0ODM2NDcsLTEpO2Nhc2UgSW50MTZBcnJheTpyZXR1cm4gTWF0aC5tYXgoaS8zMjc2NywtMSk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgubWF4KGkvMTI3LC0xKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiSW52YWxpZCBjb21wb25lbnQgdHlwZS4iKX19ZnVuY3Rpb24gSXQoaSx0KXtzd2l0Y2godC5jb25zdHJ1Y3Rvcil7Y2FzZSBGbG9hdDMyQXJyYXk6cmV0dXJuIGk7Y2FzZSBVaW50MzJBcnJheTpyZXR1cm4gTWF0aC5yb3VuZChpKjQyOTQ5NjcyOTUpO2Nhc2UgVWludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSo2NTUzNSk7Y2FzZSBVaW50OEFycmF5OnJldHVybiBNYXRoLnJvdW5kKGkqMjU1KTtjYXNlIEludDMyQXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoyMTQ3NDgzNjQ3KTtjYXNlIEludDE2QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSozMjc2Nyk7Y2FzZSBJbnQ4QXJyYXk6cmV0dXJuIE1hdGgucm91bmQoaSoxMjcpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGNvbXBvbmVudCB0eXBlLiIpfX1jbGFzcyBSe2NvbnN0cnVjdG9yKHQ9MCxlPTApe1IucHJvdG90eXBlLmlzVmVjdG9yMj0hMCx0aGlzLng9dCx0aGlzLnk9ZX1nZXQgd2lkdGgoKXtyZXR1cm4gdGhpcy54fXNldCB3aWR0aCh0KXt0aGlzLng9dH1nZXQgaGVpZ2h0KCl7cmV0dXJuIHRoaXMueX1zZXQgaGVpZ2h0KHQpe3RoaXMueT10fXNldCh0LGUpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Q29tcG9uZW50KHQsZSl7c3dpdGNoKHQpe2Nhc2UgMDp0aGlzLng9ZTticmVhaztjYXNlIDE6dGhpcy55PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnkpfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpc31kaXZpZGUodCl7cmV0dXJuIHRoaXMueC89dC54LHRoaXMueS89dC55LHRoaXN9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKDEvdCl9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PXNbMF0qZStzWzNdKm4rc1s2XSx0aGlzLnk9c1sxXSplK3NbNF0qbitzWzddLHRoaXN9bWluKHQpe3JldHVybiB0aGlzLng9TWF0aC5taW4odGhpcy54LHQueCksdGhpcy55PU1hdGgubWluKHRoaXMueSx0LnkpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXN9Y2xhbXAodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQueCxlLngpLHRoaXMueT1aKHRoaXMueSx0LnksZS55KSx0aGlzfWNsYW1wU2NhbGFyKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LGUpLHRoaXMueT1aKHRoaXMueSx0LGUpLHRoaXN9Y2xhbXBMZW5ndGgodCxlKXtjb25zdCBuPXRoaXMubGVuZ3RoKCk7cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKG58fDEpLm11bHRpcGx5U2NhbGFyKFoobix0LGUpKX1mbG9vcigpe3JldHVybiB0aGlzLng9TWF0aC5mbG9vcih0aGlzLngpLHRoaXMueT1NYXRoLmZsb29yKHRoaXMueSksdGhpc31jZWlsKCl7cmV0dXJuIHRoaXMueD1NYXRoLmNlaWwodGhpcy54KSx0aGlzLnk9TWF0aC5jZWlsKHRoaXMueSksdGhpc31yb3VuZCgpe3JldHVybiB0aGlzLng9TWF0aC5yb3VuZCh0aGlzLngpLHRoaXMueT1NYXRoLnJvdW5kKHRoaXMueSksdGhpc31yb3VuZFRvWmVybygpe3JldHVybiB0aGlzLng9TWF0aC50cnVuYyh0aGlzLngpLHRoaXMueT1NYXRoLnRydW5jKHRoaXMueSksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueX1sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSl9bWFuaGF0dGFuTGVuZ3RoKCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueCkrTWF0aC5hYnModGhpcy55KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9YW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMigtdGhpcy55LC10aGlzLngpK01hdGguUEl9YW5nbGVUbyh0KXtjb25zdCBlPU1hdGguc3FydCh0aGlzLmxlbmd0aFNxKCkqdC5sZW5ndGhTcSgpKTtpZihlPT09MClyZXR1cm4gTWF0aC5QSS8yO2NvbnN0IG49dGhpcy5kb3QodCkvZTtyZXR1cm4gTWF0aC5hY29zKFoobiwtMSwxKSl9ZGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VUb1NxdWFyZWQodCkpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe2NvbnN0IGU9dGhpcy54LXQueCxuPXRoaXMueS10Lnk7cmV0dXJuIGUqZStuKm59bWFuaGF0dGFuRGlzdGFuY2VUbyh0KXtyZXR1cm4gTWF0aC5hYnModGhpcy54LXQueCkrTWF0aC5hYnModGhpcy55LXQueSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55fWZyb21BcnJheSh0LGU9MCl7cmV0dXJuIHRoaXMueD10W2VdLHRoaXMueT10W2UrMV0sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXN9cm90YXRlQXJvdW5kKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9dGhpcy54LXQueCxvPXRoaXMueS10Lnk7cmV0dXJuIHRoaXMueD1yKm4tbypzK3QueCx0aGlzLnk9cipzK28qbit0LnksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55fX1jbGFzcyBnZXtjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyxhLGMsbCl7Z2UucHJvdG90eXBlLmlzTWF0cml4Mz0hMCx0aGlzLmVsZW1lbnRzPVsxLDAsMCwwLDEsMCwwLDAsMV0sdCE9PXZvaWQgMCYmdGhpcy5zZXQodCxlLG4scyxyLG8sYSxjLGwpfXNldCh0LGUsbixzLHIsbyxhLGMsbCl7Y29uc3QgaD10aGlzLmVsZW1lbnRzO3JldHVybiBoWzBdPXQsaFsxXT1zLGhbMl09YSxoWzNdPWUsaFs0XT1yLGhbNV09YyxoWzZdPW4saFs3XT1vLGhbOF09bCx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDEsMCwwLDAsMSwwLDAsMCwxKSx0aGlzfWNvcHkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVswXT1uWzBdLGVbMV09blsxXSxlWzJdPW5bMl0sZVszXT1uWzNdLGVbNF09bls0XSxlWzVdPW5bNV0sZVs2XT1uWzZdLGVbN109bls3XSxlWzhdPW5bOF0sdGhpc31leHRyYWN0QmFzaXModCxlLG4pe3JldHVybiB0LnNldEZyb21NYXRyaXgzQ29sdW1uKHRoaXMsMCksZS5zZXRGcm9tTWF0cml4M0NvbHVtbih0aGlzLDEpLG4uc2V0RnJvbU1hdHJpeDNDb2x1bW4odGhpcywyKSx0aGlzfXNldEZyb21NYXRyaXg0KHQpe2NvbnN0IGU9dC5lbGVtZW50cztyZXR1cm4gdGhpcy5zZXQoZVswXSxlWzRdLGVbOF0sZVsxXSxlWzVdLGVbOV0sZVsyXSxlWzZdLGVbMTBdKSx0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXModGhpcyx0KX1wcmVtdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHQsdGhpcyl9bXVsdGlwbHlNYXRyaWNlcyh0LGUpe2NvbnN0IG49dC5lbGVtZW50cyxzPWUuZWxlbWVudHMscj10aGlzLmVsZW1lbnRzLG89blswXSxhPW5bM10sYz1uWzZdLGw9blsxXSxoPW5bNF0sdT1uWzddLGY9blsyXSxkPW5bNV0scD1uWzhdLHk9c1swXSxtPXNbM10sZz1zWzZdLGI9c1sxXSx3PXNbNF0seD1zWzddLE09c1syXSxBPXNbNV0sXz1zWzhdO3JldHVybiByWzBdPW8qeSthKmIrYypNLHJbM109byptK2EqdytjKkEscls2XT1vKmcrYSp4K2MqXyxyWzFdPWwqeStoKmIrdSpNLHJbNF09bCptK2gqdyt1KkEscls3XT1sKmcraCp4K3UqXyxyWzJdPWYqeStkKmIrcCpNLHJbNV09ZiptK2QqdytwKkEscls4XT1mKmcrZCp4K3AqXyx0aGlzfW11bHRpcGx5U2NhbGFyKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cztyZXR1cm4gZVswXSo9dCxlWzNdKj10LGVbNl0qPXQsZVsxXSo9dCxlWzRdKj10LGVbN10qPXQsZVsyXSo9dCxlWzVdKj10LGVbOF0qPXQsdGhpc31kZXRlcm1pbmFudCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XTtyZXR1cm4gZSpvKmgtZSphKmwtbipyKmgrbiphKmMrcypyKmwtcypvKmN9aW52ZXJ0KCl7Y29uc3QgdD10aGlzLmVsZW1lbnRzLGU9dFswXSxuPXRbMV0scz10WzJdLHI9dFszXSxvPXRbNF0sYT10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdLHU9aCpvLWEqbCxmPWEqYy1oKnIsZD1sKnItbypjLHA9ZSp1K24qZitzKmQ7aWYocD09PTApcmV0dXJuIHRoaXMuc2V0KDAsMCwwLDAsMCwwLDAsMCwwKTtjb25zdCB5PTEvcDtyZXR1cm4gdFswXT11KnksdFsxXT0ocypsLWgqbikqeSx0WzJdPShhKm4tcypvKSp5LHRbM109Zip5LHRbNF09KGgqZS1zKmMpKnksdFs1XT0ocypyLWEqZSkqeSx0WzZdPWQqeSx0WzddPShuKmMtbCplKSp5LHRbOF09KG8qZS1uKnIpKnksdGhpc310cmFuc3Bvc2UoKXtsZXQgdDtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIHQ9ZVsxXSxlWzFdPWVbM10sZVszXT10LHQ9ZVsyXSxlWzJdPWVbNl0sZVs2XT10LHQ9ZVs1XSxlWzVdPWVbN10sZVs3XT10LHRoaXN9Z2V0Tm9ybWFsTWF0cml4KHQpe3JldHVybiB0aGlzLnNldEZyb21NYXRyaXg0KHQpLmludmVydCgpLnRyYW5zcG9zZSgpfXRyYW5zcG9zZUludG9BcnJheSh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbM10sdFsyXT1lWzZdLHRbM109ZVsxXSx0WzRdPWVbNF0sdFs1XT1lWzddLHRbNl09ZVsyXSx0WzddPWVbNV0sdFs4XT1lWzhdLHRoaXN9c2V0VXZUcmFuc2Zvcm0odCxlLG4scyxyLG8sYSl7Y29uc3QgYz1NYXRoLmNvcyhyKSxsPU1hdGguc2luKHIpO3JldHVybiB0aGlzLnNldChuKmMsbipsLC1uKihjKm8rbCphKStvK3QsLXMqbCxzKmMsLXMqKC1sKm8rYyphKSthK2UsMCwwLDEpLHRoaXN9c2NhbGUodCxlKXtyZXR1cm4gdGhpcy5wcmVtdWx0aXBseShRci5tYWtlU2NhbGUodCxlKSksdGhpc31yb3RhdGUodCl7cmV0dXJuIHRoaXMucHJlbXVsdGlwbHkoUXIubWFrZVJvdGF0aW9uKC10KSksdGhpc310cmFuc2xhdGUodCxlKXtyZXR1cm4gdGhpcy5wcmVtdWx0aXBseShRci5tYWtlVHJhbnNsYXRpb24odCxlKSksdGhpc31tYWtlVHJhbnNsYXRpb24odCxlKXtyZXR1cm4gdC5pc1ZlY3RvcjI/dGhpcy5zZXQoMSwwLHQueCwwLDEsdC55LDAsMCwxKTp0aGlzLnNldCgxLDAsdCwwLDEsZSwwLDAsMSksdGhpc31tYWtlUm90YXRpb24odCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldChlLC1uLDAsbixlLDAsMCwwLDEpLHRoaXN9bWFrZVNjYWxlKHQsZSl7cmV0dXJuIHRoaXMuc2V0KHQsMCwwLDAsZSwwLDAsMCwxKSx0aGlzfWVxdWFscyh0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10LmVsZW1lbnRzO2ZvcihsZXQgcz0wO3M8OTtzKyspaWYoZVtzXSE9PW5bc10pcmV0dXJuITE7cmV0dXJuITB9ZnJvbUFycmF5KHQsZT0wKXtmb3IobGV0IG49MDtuPDk7bisrKXRoaXMuZWxlbWVudHNbbl09dFtuK2VdO3JldHVybiB0aGlzfXRvQXJyYXkodD1bXSxlPTApe2NvbnN0IG49dGhpcy5lbGVtZW50cztyZXR1cm4gdFtlXT1uWzBdLHRbZSsxXT1uWzFdLHRbZSsyXT1uWzJdLHRbZSszXT1uWzNdLHRbZSs0XT1uWzRdLHRbZSs1XT1uWzVdLHRbZSs2XT1uWzZdLHRbZSs3XT1uWzddLHRbZSs4XT1uWzhdLHR9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5mcm9tQXJyYXkodGhpcy5lbGVtZW50cyl9fWNvbnN0IFFyPW5ldyBnZTtmdW5jdGlvbiBWdShpKXtmb3IobGV0IHQ9aS5sZW5ndGgtMTt0Pj0wOy0tdClpZihpW3RdPj02NTUzNSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiB5YyhpKXtyZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIixpKX1jb25zdCBtYz1uZXcgZ2UoKS5zZXQoLjQxMjM5MDgsLjM1NzU4NDMsLjE4MDQ4MDgsLjIxMjYzOSwuNzE1MTY4NywuMDcyMTkyMywuMDE5MzMwOCwuMTE5MTk0OCwuOTUwNTMyMiksZ2M9bmV3IGdlKCkuc2V0KDMuMjQwOTY5OSwtMS41MzczODMyLC0uNDk4NjEwOCwtLjk2OTI0MzYsMS44NzU5Njc1LC4wNDE1NTUxLC4wNTU2MzAxLC0uMjAzOTc3LDEuMDU2OTcxNSk7ZnVuY3Rpb24gcXUoKXtjb25zdCBpPXtlbmFibGVkOiEwLHdvcmtpbmdDb2xvclNwYWNlOmRjLHNwYWNlczp7fSxjb252ZXJ0OmZ1bmN0aW9uKHMscixvKXtyZXR1cm4gdGhpcy5lbmFibGVkPT09ITF8fHI9PT1vfHwhcnx8IW98fCh0aGlzLnNwYWNlc1tyXS50cmFuc2Zlcj09PVlyJiYocy5yPV9lKHMucikscy5nPV9lKHMuZykscy5iPV9lKHMuYikpLHRoaXMuc3BhY2VzW3JdLnByaW1hcmllcyE9PXRoaXMuc3BhY2VzW29dLnByaW1hcmllcyYmKHMuYXBwbHlNYXRyaXgzKHRoaXMuc3BhY2VzW3JdLnRvWFlaKSxzLmFwcGx5TWF0cml4Myh0aGlzLnNwYWNlc1tvXS5mcm9tWFlaKSksdGhpcy5zcGFjZXNbb10udHJhbnNmZXI9PT1ZciYmKHMucj1GbihzLnIpLHMuZz1GbihzLmcpLHMuYj1GbihzLmIpKSksc30sZnJvbVdvcmtpbmdDb2xvclNwYWNlOmZ1bmN0aW9uKHMscil7cmV0dXJuIHRoaXMuY29udmVydChzLHRoaXMud29ya2luZ0NvbG9yU3BhY2Uscil9LHRvV29ya2luZ0NvbG9yU3BhY2U6ZnVuY3Rpb24ocyxyKXtyZXR1cm4gdGhpcy5jb252ZXJ0KHMscix0aGlzLndvcmtpbmdDb2xvclNwYWNlKX0sZ2V0UHJpbWFyaWVzOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5wcmltYXJpZXN9LGdldFRyYW5zZmVyOmZ1bmN0aW9uKHMpe3JldHVybiBzPT09ZmM/cGM6dGhpcy5zcGFjZXNbc10udHJhbnNmZXJ9LGdldEx1bWluYW5jZUNvZWZmaWNpZW50czpmdW5jdGlvbihzLHI9dGhpcy53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHMuZnJvbUFycmF5KHRoaXMuc3BhY2VzW3JdLmx1bWluYW5jZUNvZWZmaWNpZW50cyl9LGRlZmluZTpmdW5jdGlvbihzKXtPYmplY3QuYXNzaWduKHRoaXMuc3BhY2VzLHMpfSxfZ2V0TWF0cml4OmZ1bmN0aW9uKHMscixvKXtyZXR1cm4gcy5jb3B5KHRoaXMuc3BhY2VzW3JdLnRvWFlaKS5tdWx0aXBseSh0aGlzLnNwYWNlc1tvXS5mcm9tWFlaKX0sX2dldERyYXdpbmdCdWZmZXJDb2xvclNwYWNlOmZ1bmN0aW9uKHMpe3JldHVybiB0aGlzLnNwYWNlc1tzXS5vdXRwdXRDb2xvclNwYWNlQ29uZmlnLmRyYXdpbmdCdWZmZXJDb2xvclNwYWNlfSxfZ2V0VW5wYWNrQ29sb3JTcGFjZTpmdW5jdGlvbihzPXRoaXMud29ya2luZ0NvbG9yU3BhY2Upe3JldHVybiB0aGlzLnNwYWNlc1tzXS53b3JraW5nQ29sb3JTcGFjZUNvbmZpZy51bnBhY2tDb2xvclNwYWNlfX0sdD1bLjY0LC4zMywuMywuNiwuMTUsLjA2XSxlPVsuMjEyNiwuNzE1MiwuMDcyMl0sbj1bLjMxMjcsLjMyOV07cmV0dXJuIGkuZGVmaW5lKHtbZGNdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6cGMsdG9YWVo6bWMsZnJvbVhZWjpnYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSx3b3JraW5nQ29sb3JTcGFjZUNvbmZpZzp7dW5wYWNrQ29sb3JTcGFjZTpvZX0sb3V0cHV0Q29sb3JTcGFjZUNvbmZpZzp7ZHJhd2luZ0J1ZmZlckNvbG9yU3BhY2U6b2V9fSxbb2VdOntwcmltYXJpZXM6dCx3aGl0ZVBvaW50Om4sdHJhbnNmZXI6WXIsdG9YWVo6bWMsZnJvbVhZWjpnYyxsdW1pbmFuY2VDb2VmZmljaWVudHM6ZSxvdXRwdXRDb2xvclNwYWNlQ29uZmlnOntkcmF3aW5nQnVmZmVyQ29sb3JTcGFjZTpvZX19fSksaX1jb25zdCBhZT1xdSgpO2Z1bmN0aW9uIF9lKGkpe3JldHVybiBpPC4wNDA0NT9pKi4wNzczOTkzODA4Ok1hdGgucG93KGkqLjk0Nzg2NzI5ODYrLjA1MjEzMjcwMTQsMi40KX1mdW5jdGlvbiBGbihpKXtyZXR1cm4gaTwuMDAzMTMwOD9pKjEyLjkyOjEuMDU1Kk1hdGgucG93KGksLjQxNjY2KS0uMDU1fWxldCBJbjtjbGFzcyBIdXtzdGF0aWMgZ2V0RGF0YVVSTCh0LGU9ImltYWdlL3BuZyIpe2lmKC9eZGF0YTovaS50ZXN0KHQuc3JjKXx8dHlwZW9mIEhUTUxDYW52YXNFbGVtZW50PT0idW5kZWZpbmVkIilyZXR1cm4gdC5zcmM7bGV0IG47aWYodCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KW49dDtlbHNle0luPT09dm9pZCAwJiYoSW49eWMoImNhbnZhcyIpKSxJbi53aWR0aD10LndpZHRoLEluLmhlaWdodD10LmhlaWdodDtjb25zdCBzPUluLmdldENvbnRleHQoIjJkIik7dCBpbnN0YW5jZW9mIEltYWdlRGF0YT9zLnB1dEltYWdlRGF0YSh0LDAsMCk6cy5kcmF3SW1hZ2UodCwwLDAsdC53aWR0aCx0LmhlaWdodCksbj1Jbn1yZXR1cm4gbi50b0RhdGFVUkwoZSl9c3RhdGljIHNSR0JUb0xpbmVhcih0KXtpZih0eXBlb2YgSFRNTEltYWdlRWxlbWVudCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50fHx0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQhPSJ1bmRlZmluZWQiJiZ0IGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnR8fHR5cGVvZiBJbWFnZUJpdG1hcCE9InVuZGVmaW5lZCImJnQgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcCl7Y29uc3QgZT15YygiY2FudmFzIik7ZS53aWR0aD10LndpZHRoLGUuaGVpZ2h0PXQuaGVpZ2h0O2NvbnN0IG49ZS5nZXRDb250ZXh0KCIyZCIpO24uZHJhd0ltYWdlKHQsMCwwLHQud2lkdGgsdC5oZWlnaHQpO2NvbnN0IHM9bi5nZXRJbWFnZURhdGEoMCwwLHQud2lkdGgsdC5oZWlnaHQpLHI9cy5kYXRhO2ZvcihsZXQgbz0wO288ci5sZW5ndGg7bysrKXJbb109X2UocltvXS8yNTUpKjI1NTtyZXR1cm4gbi5wdXRJbWFnZURhdGEocywwLDApLGV9ZWxzZSBpZih0LmRhdGEpe2NvbnN0IGU9dC5kYXRhLnNsaWNlKDApO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxlIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXk/ZVtuXT1NYXRoLmZsb29yKF9lKGVbbl0vMjU1KSoyNTUpOmVbbl09X2UoZVtuXSk7cmV0dXJue2RhdGE6ZSx3aWR0aDp0LndpZHRoLGhlaWdodDp0LmhlaWdodH19ZWxzZSByZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5JbWFnZVV0aWxzLnNSR0JUb0xpbmVhcigpOiBVbnN1cHBvcnRlZCBpbWFnZSB0eXBlLiBObyBjb2xvciBzcGFjZSBjb252ZXJzaW9uIGFwcGxpZWQuIiksdH19bGV0IFd1PTA7Y2xhc3MgR3V7Y29uc3RydWN0b3IodD1udWxsKXt0aGlzLmlzU291cmNlPSEwLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJpZCIse3ZhbHVlOld1Kyt9KSx0aGlzLnV1aWQ9Qm4oKSx0aGlzLmRhdGE9dCx0aGlzLmRhdGFSZWFkeT0hMCx0aGlzLnZlcnNpb249MH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK310b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQuaW1hZ2VzW3RoaXMudXVpZF0hPT12b2lkIDApcmV0dXJuIHQuaW1hZ2VzW3RoaXMudXVpZF07Y29uc3Qgbj17dXVpZDp0aGlzLnV1aWQsdXJsOiIifSxzPXRoaXMuZGF0YTtpZihzIT09bnVsbCl7bGV0IHI7aWYoQXJyYXkuaXNBcnJheShzKSl7cj1bXTtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTtvKyspc1tvXS5pc0RhdGFUZXh0dXJlP3IucHVzaChLcihzW29dLmltYWdlKSk6ci5wdXNoKEtyKHNbb10pKX1lbHNlIHI9S3Iocyk7bi51cmw9cn1yZXR1cm4gZXx8KHQuaW1hZ2VzW3RoaXMudXVpZF09biksbn19ZnVuY3Rpb24gS3IoaSl7cmV0dXJuIHR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50IT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnR8fHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudCE9InVuZGVmaW5lZCImJmkgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudHx8dHlwZW9mIEltYWdlQml0bWFwIT0idW5kZWZpbmVkIiYmaSBpbnN0YW5jZW9mIEltYWdlQml0bWFwP0h1LmdldERhdGFVUkwoaSk6aS5kYXRhP3tkYXRhOkFycmF5LmZyb20oaS5kYXRhKSx3aWR0aDppLndpZHRoLGhlaWdodDppLmhlaWdodCx0eXBlOmkuZGF0YS5jb25zdHJ1Y3Rvci5uYW1lfTooY29uc29sZS53YXJuKCJUSFJFRS5UZXh0dXJlOiBVbmFibGUgdG8gc2VyaWFsaXplIFRleHR1cmUuIikse30pfWxldCBadT0wO2NsYXNzIGNuIGV4dGVuZHMgaXN7Y29uc3RydWN0b3IodD1jbi5ERUZBVUxUX0lNQUdFLGU9Y24uREVGQVVMVF9NQVBQSU5HLG49MTAwMSxzPTEwMDEscj0xMDA2LG89MTAwOCxhPTEwMjMsYz0xMDA5LGw9Y24uREVGQVVMVF9BTklTT1RST1BZLGg9ZmMpe3N1cGVyKCksdGhpcy5pc1RleHR1cmU9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6WnUrK30pLHRoaXMudXVpZD1CbigpLHRoaXMubmFtZT0iIix0aGlzLnNvdXJjZT1uZXcgR3UodCksdGhpcy5taXBtYXBzPVtdLHRoaXMubWFwcGluZz1lLHRoaXMuY2hhbm5lbD0wLHRoaXMud3JhcFM9bix0aGlzLndyYXBUPXMsdGhpcy5tYWdGaWx0ZXI9cix0aGlzLm1pbkZpbHRlcj1vLHRoaXMuYW5pc290cm9weT1sLHRoaXMuZm9ybWF0PWEsdGhpcy5pbnRlcm5hbEZvcm1hdD1udWxsLHRoaXMudHlwZT1jLHRoaXMub2Zmc2V0PW5ldyBSKDAsMCksdGhpcy5yZXBlYXQ9bmV3IFIoMSwxKSx0aGlzLmNlbnRlcj1uZXcgUigwLDApLHRoaXMucm90YXRpb249MCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9ITAsdGhpcy5tYXRyaXg9bmV3IGdlLHRoaXMuZ2VuZXJhdGVNaXBtYXBzPSEwLHRoaXMucHJlbXVsdGlwbHlBbHBoYT0hMSx0aGlzLmZsaXBZPSEwLHRoaXMudW5wYWNrQWxpZ25tZW50PTQsdGhpcy5jb2xvclNwYWNlPWgsdGhpcy51c2VyRGF0YT17fSx0aGlzLnZlcnNpb249MCx0aGlzLm9uVXBkYXRlPW51bGwsdGhpcy5yZW5kZXJUYXJnZXQ9bnVsbCx0aGlzLmlzUmVuZGVyVGFyZ2V0VGV4dHVyZT0hMSx0aGlzLmlzVGV4dHVyZUFycmF5PSExLHRoaXMucG1yZW1WZXJzaW9uPTB9Z2V0IGltYWdlKCl7cmV0dXJuIHRoaXMuc291cmNlLmRhdGF9c2V0IGltYWdlKHQ9bnVsbCl7dGhpcy5zb3VyY2UuZGF0YT10fXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LnNldFV2VHJhbnNmb3JtKHRoaXMub2Zmc2V0LngsdGhpcy5vZmZzZXQueSx0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnksdGhpcy5yb3RhdGlvbix0aGlzLmNlbnRlci54LHRoaXMuY2VudGVyLnkpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLm5hbWU9dC5uYW1lLHRoaXMuc291cmNlPXQuc291cmNlLHRoaXMubWlwbWFwcz10Lm1pcG1hcHMuc2xpY2UoMCksdGhpcy5tYXBwaW5nPXQubWFwcGluZyx0aGlzLmNoYW5uZWw9dC5jaGFubmVsLHRoaXMud3JhcFM9dC53cmFwUyx0aGlzLndyYXBUPXQud3JhcFQsdGhpcy5tYWdGaWx0ZXI9dC5tYWdGaWx0ZXIsdGhpcy5taW5GaWx0ZXI9dC5taW5GaWx0ZXIsdGhpcy5hbmlzb3Ryb3B5PXQuYW5pc290cm9weSx0aGlzLmZvcm1hdD10LmZvcm1hdCx0aGlzLmludGVybmFsRm9ybWF0PXQuaW50ZXJuYWxGb3JtYXQsdGhpcy50eXBlPXQudHlwZSx0aGlzLm9mZnNldC5jb3B5KHQub2Zmc2V0KSx0aGlzLnJlcGVhdC5jb3B5KHQucmVwZWF0KSx0aGlzLmNlbnRlci5jb3B5KHQuY2VudGVyKSx0aGlzLnJvdGF0aW9uPXQucm90YXRpb24sdGhpcy5tYXRyaXhBdXRvVXBkYXRlPXQubWF0cml4QXV0b1VwZGF0ZSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLmdlbmVyYXRlTWlwbWFwcz10LmdlbmVyYXRlTWlwbWFwcyx0aGlzLnByZW11bHRpcGx5QWxwaGE9dC5wcmVtdWx0aXBseUFscGhhLHRoaXMuZmxpcFk9dC5mbGlwWSx0aGlzLnVucGFja0FsaWdubWVudD10LnVucGFja0FsaWdubWVudCx0aGlzLmNvbG9yU3BhY2U9dC5jb2xvclNwYWNlLHRoaXMucmVuZGVyVGFyZ2V0PXQucmVuZGVyVGFyZ2V0LHRoaXMuaXNSZW5kZXJUYXJnZXRUZXh0dXJlPXQuaXNSZW5kZXJUYXJnZXRUZXh0dXJlLHRoaXMuaXNUZXh0dXJlQXJyYXk9dC5pc1RleHR1cmVBcnJheSx0aGlzLnVzZXJEYXRhPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodC51c2VyRGF0YSkpLHRoaXMubmVlZHNVcGRhdGU9ITAsdGhpc310b0pTT04odCl7Y29uc3QgZT10PT09dm9pZCAwfHx0eXBlb2YgdD09InN0cmluZyI7aWYoIWUmJnQudGV4dHVyZXNbdGhpcy51dWlkXSE9PXZvaWQgMClyZXR1cm4gdC50ZXh0dXJlc1t0aGlzLnV1aWRdO2NvbnN0IG49e21ldGFkYXRhOnt2ZXJzaW9uOjQuNix0eXBlOiJUZXh0dXJlIixnZW5lcmF0b3I6IlRleHR1cmUudG9KU09OIn0sdXVpZDp0aGlzLnV1aWQsbmFtZTp0aGlzLm5hbWUsaW1hZ2U6dGhpcy5zb3VyY2UudG9KU09OKHQpLnV1aWQsbWFwcGluZzp0aGlzLm1hcHBpbmcsY2hhbm5lbDp0aGlzLmNoYW5uZWwscmVwZWF0Olt0aGlzLnJlcGVhdC54LHRoaXMucmVwZWF0LnldLG9mZnNldDpbdGhpcy5vZmZzZXQueCx0aGlzLm9mZnNldC55XSxjZW50ZXI6W3RoaXMuY2VudGVyLngsdGhpcy5jZW50ZXIueV0scm90YXRpb246dGhpcy5yb3RhdGlvbix3cmFwOlt0aGlzLndyYXBTLHRoaXMud3JhcFRdLGZvcm1hdDp0aGlzLmZvcm1hdCxpbnRlcm5hbEZvcm1hdDp0aGlzLmludGVybmFsRm9ybWF0LHR5cGU6dGhpcy50eXBlLGNvbG9yU3BhY2U6dGhpcy5jb2xvclNwYWNlLG1pbkZpbHRlcjp0aGlzLm1pbkZpbHRlcixtYWdGaWx0ZXI6dGhpcy5tYWdGaWx0ZXIsYW5pc290cm9weTp0aGlzLmFuaXNvdHJvcHksZmxpcFk6dGhpcy5mbGlwWSxnZW5lcmF0ZU1pcG1hcHM6dGhpcy5nZW5lcmF0ZU1pcG1hcHMscHJlbXVsdGlwbHlBbHBoYTp0aGlzLnByZW11bHRpcGx5QWxwaGEsdW5wYWNrQWxpZ25tZW50OnRoaXMudW5wYWNrQWxpZ25tZW50fTtyZXR1cm4gT2JqZWN0LmtleXModGhpcy51c2VyRGF0YSkubGVuZ3RoPjAmJihuLnVzZXJEYXRhPXRoaXMudXNlckRhdGEpLGV8fCh0LnRleHR1cmVzW3RoaXMudXVpZF09biksbn1kaXNwb3NlKCl7dGhpcy5kaXNwYXRjaEV2ZW50KHt0eXBlOiJkaXNwb3NlIn0pfXRyYW5zZm9ybVV2KHQpe2lmKHRoaXMubWFwcGluZyE9PTMwMClyZXR1cm4gdDtpZih0LmFwcGx5TWF0cml4Myh0aGlzLm1hdHJpeCksdC54PDB8fHQueD4xKXN3aXRjaCh0aGlzLndyYXBTKXtjYXNlIDFlMzp0Lng9dC54LU1hdGguZmxvb3IodC54KTticmVhaztjYXNlIDEwMDE6dC54PXQueDwwPzA6MTticmVhaztjYXNlIDEwMDI6TWF0aC5hYnMoTWF0aC5mbG9vcih0LngpJTIpPT09MT90Lng9TWF0aC5jZWlsKHQueCktdC54OnQueD10LngtTWF0aC5mbG9vcih0LngpO2JyZWFrfWlmKHQueTwwfHx0Lnk+MSlzd2l0Y2godGhpcy53cmFwVCl7Y2FzZSAxZTM6dC55PXQueS1NYXRoLmZsb29yKHQueSk7YnJlYWs7Y2FzZSAxMDAxOnQueT10Lnk8MD8wOjE7YnJlYWs7Y2FzZSAxMDAyOk1hdGguYWJzKE1hdGguZmxvb3IodC55KSUyKT09PTE/dC55PU1hdGguY2VpbCh0LnkpLXQueTp0Lnk9dC55LU1hdGguZmxvb3IodC55KTticmVha31yZXR1cm4gdGhpcy5mbGlwWSYmKHQueT0xLXQueSksdH1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiYodGhpcy52ZXJzaW9uKyssdGhpcy5zb3VyY2UubmVlZHNVcGRhdGU9ITApfXNldCBuZWVkc1BNUkVNVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy5wbXJlbVZlcnNpb24rK319Y24uREVGQVVMVF9JTUFHRT1udWxsLGNuLkRFRkFVTFRfTUFQUElORz0zMDAsY24uREVGQVVMVF9BTklTT1RST1BZPTE7Y2xhc3MgWXR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTAscz0xKXtZdC5wcm90b3R5cGUuaXNWZWN0b3I0PSEwLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXMudz1zfWdldCB3aWR0aCgpe3JldHVybiB0aGlzLnp9c2V0IHdpZHRoKHQpe3RoaXMuej10fWdldCBoZWlnaHQoKXtyZXR1cm4gdGhpcy53fXNldCBoZWlnaHQodCl7dGhpcy53PXR9c2V0KHQsZSxuLHMpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bix0aGlzLnc9cyx0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy54PXQsdGhpcy55PXQsdGhpcy56PXQsdGhpcy53PXQsdGhpc31zZXRYKHQpe3JldHVybiB0aGlzLng9dCx0aGlzfXNldFkodCl7cmV0dXJuIHRoaXMueT10LHRoaXN9c2V0Wih0KXtyZXR1cm4gdGhpcy56PXQsdGhpc31zZXRXKHQpe3JldHVybiB0aGlzLnc9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztjYXNlIDM6dGhpcy53PWU7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX1yZXR1cm4gdGhpc31nZXRDb21wb25lbnQodCl7c3dpdGNoKHQpe2Nhc2UgMDpyZXR1cm4gdGhpcy54O2Nhc2UgMTpyZXR1cm4gdGhpcy55O2Nhc2UgMjpyZXR1cm4gdGhpcy56O2Nhc2UgMzpyZXR1cm4gdGhpcy53O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICIrdCl9fWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMueCx0aGlzLnksdGhpcy56LHRoaXMudyl9Y29weSh0KXtyZXR1cm4gdGhpcy54PXQueCx0aGlzLnk9dC55LHRoaXMuej10LnosdGhpcy53PXQudyE9PXZvaWQgMD90Lnc6MSx0aGlzfWFkZCh0KXtyZXR1cm4gdGhpcy54Kz10LngsdGhpcy55Kz10LnksdGhpcy56Kz10LnosdGhpcy53Kz10LncsdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMueCs9dCx0aGlzLnkrPXQsdGhpcy56Kz10LHRoaXMudys9dCx0aGlzfWFkZFZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueCtlLngsdGhpcy55PXQueStlLnksdGhpcy56PXQueitlLnosdGhpcy53PXQudytlLncsdGhpc31hZGRTY2FsZWRWZWN0b3IodCxlKXtyZXR1cm4gdGhpcy54Kz10LngqZSx0aGlzLnkrPXQueSplLHRoaXMueis9dC56KmUsdGhpcy53Kz10LncqZSx0aGlzfXN1Yih0KXtyZXR1cm4gdGhpcy54LT10LngsdGhpcy55LT10LnksdGhpcy56LT10LnosdGhpcy53LT10LncsdGhpc31zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMueC09dCx0aGlzLnktPXQsdGhpcy56LT10LHRoaXMudy09dCx0aGlzfXN1YlZlY3RvcnModCxlKXtyZXR1cm4gdGhpcy54PXQueC1lLngsdGhpcy55PXQueS1lLnksdGhpcy56PXQuei1lLnosdGhpcy53PXQudy1lLncsdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy54Kj10LngsdGhpcy55Kj10LnksdGhpcy56Kj10LnosdGhpcy53Kj10LncsdGhpc31tdWx0aXBseVNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kj10LHRoaXMueSo9dCx0aGlzLnoqPXQsdGhpcy53Kj10LHRoaXN9YXBwbHlNYXRyaXg0KHQpe2NvbnN0IGU9dGhpcy54LG49dGhpcy55LHM9dGhpcy56LHI9dGhpcy53LG89dC5lbGVtZW50cztyZXR1cm4gdGhpcy54PW9bMF0qZStvWzRdKm4rb1s4XSpzK29bMTJdKnIsdGhpcy55PW9bMV0qZStvWzVdKm4rb1s5XSpzK29bMTNdKnIsdGhpcy56PW9bMl0qZStvWzZdKm4rb1sxMF0qcytvWzE0XSpyLHRoaXMudz1vWzNdKmUrb1s3XSpuK29bMTFdKnMrb1sxNV0qcix0aGlzfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpcy53Lz10LncsdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1zZXRBeGlzQW5nbGVGcm9tUXVhdGVybmlvbih0KXt0aGlzLnc9MipNYXRoLmFjb3ModC53KTtjb25zdCBlPU1hdGguc3FydCgxLXQudyp0LncpO3JldHVybiBlPDFlLTQ/KHRoaXMueD0xLHRoaXMueT0wLHRoaXMuej0wKToodGhpcy54PXQueC9lLHRoaXMueT10LnkvZSx0aGlzLno9dC56L2UpLHRoaXN9c2V0QXhpc0FuZ2xlRnJvbVJvdGF0aW9uTWF0cml4KHQpe2xldCBlLG4scyxyO2NvbnN0IGM9dC5lbGVtZW50cyxsPWNbMF0saD1jWzRdLHU9Y1s4XSxmPWNbMV0sZD1jWzVdLHA9Y1s5XSx5PWNbMl0sbT1jWzZdLGc9Y1sxMF07aWYoTWF0aC5hYnMoaC1mKTwuMDEmJk1hdGguYWJzKHUteSk8LjAxJiZNYXRoLmFicyhwLW0pPC4wMSl7aWYoTWF0aC5hYnMoaCtmKTwuMSYmTWF0aC5hYnModSt5KTwuMSYmTWF0aC5hYnMocCttKTwuMSYmTWF0aC5hYnMobCtkK2ctMyk8LjEpcmV0dXJuIHRoaXMuc2V0KDEsMCwwLDApLHRoaXM7ZT1NYXRoLlBJO2NvbnN0IHc9KGwrMSkvMix4PShkKzEpLzIsTT0oZysxKS8yLEE9KGgrZikvNCxfPSh1K3kpLzQsUz0ocCttKS80O3JldHVybiB3PngmJnc+TT93PC4wMT8obj0wLHM9LjcwNzEwNjc4MSxyPS43MDcxMDY3ODEpOihuPU1hdGguc3FydCh3KSxzPUEvbixyPV8vbik6eD5NP3g8LjAxPyhuPS43MDcxMDY3ODEscz0wLHI9LjcwNzEwNjc4MSk6KHM9TWF0aC5zcXJ0KHgpLG49QS9zLHI9Uy9zKTpNPC4wMT8obj0uNzA3MTA2NzgxLHM9LjcwNzEwNjc4MSxyPTApOihyPU1hdGguc3FydChNKSxuPV8vcixzPVMvciksdGhpcy5zZXQobixzLHIsZSksdGhpc31sZXQgYj1NYXRoLnNxcnQoKG0tcCkqKG0tcCkrKHUteSkqKHUteSkrKGYtaCkqKGYtaCkpO3JldHVybiBNYXRoLmFicyhiKTwuMDAxJiYoYj0xKSx0aGlzLng9KG0tcCkvYix0aGlzLnk9KHUteSkvYix0aGlzLno9KGYtaCkvYix0aGlzLnc9TWF0aC5hY29zKChsK2QrZy0xKS8yKSx0aGlzfXNldEZyb21NYXRyaXhQb3NpdGlvbih0KXtjb25zdCBlPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1lWzEyXSx0aGlzLnk9ZVsxM10sdGhpcy56PWVbMTRdLHRoaXMudz1lWzE1XSx0aGlzfW1pbih0KXtyZXR1cm4gdGhpcy54PU1hdGgubWluKHRoaXMueCx0LngpLHRoaXMueT1NYXRoLm1pbih0aGlzLnksdC55KSx0aGlzLno9TWF0aC5taW4odGhpcy56LHQueiksdGhpcy53PU1hdGgubWluKHRoaXMudyx0LncpLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzLnc9TWF0aC5tYXgodGhpcy53LHQudyksdGhpc31jbGFtcCh0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdC54LGUueCksdGhpcy55PVoodGhpcy55LHQueSxlLnkpLHRoaXMuej1aKHRoaXMueix0LnosZS56KSx0aGlzLnc9Wih0aGlzLncsdC53LGUudyksdGhpc31jbGFtcFNjYWxhcih0LGUpe3JldHVybiB0aGlzLng9Wih0aGlzLngsdCxlKSx0aGlzLnk9Wih0aGlzLnksdCxlKSx0aGlzLno9Wih0aGlzLnosdCxlKSx0aGlzLnc9Wih0aGlzLncsdCxlKSx0aGlzfWNsYW1wTGVuZ3RoKHQsZSl7Y29uc3Qgbj10aGlzLmxlbmd0aCgpO3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcihufHwxKS5tdWx0aXBseVNjYWxhcihaKG4sdCxlKSl9Zmxvb3IoKXtyZXR1cm4gdGhpcy54PU1hdGguZmxvb3IodGhpcy54KSx0aGlzLnk9TWF0aC5mbG9vcih0aGlzLnkpLHRoaXMuej1NYXRoLmZsb29yKHRoaXMueiksdGhpcy53PU1hdGguZmxvb3IodGhpcy53KSx0aGlzfWNlaWwoKXtyZXR1cm4gdGhpcy54PU1hdGguY2VpbCh0aGlzLngpLHRoaXMueT1NYXRoLmNlaWwodGhpcy55KSx0aGlzLno9TWF0aC5jZWlsKHRoaXMueiksdGhpcy53PU1hdGguY2VpbCh0aGlzLncpLHRoaXN9cm91bmQoKXtyZXR1cm4gdGhpcy54PU1hdGgucm91bmQodGhpcy54KSx0aGlzLnk9TWF0aC5yb3VuZCh0aGlzLnkpLHRoaXMuej1NYXRoLnJvdW5kKHRoaXMueiksdGhpcy53PU1hdGgucm91bmQodGhpcy53KSx0aGlzfXJvdW5kVG9aZXJvKCl7cmV0dXJuIHRoaXMueD1NYXRoLnRydW5jKHRoaXMueCksdGhpcy55PU1hdGgudHJ1bmModGhpcy55KSx0aGlzLno9TWF0aC50cnVuYyh0aGlzLnopLHRoaXMudz1NYXRoLnRydW5jKHRoaXMudyksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpcy53PS10aGlzLncsdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56K3RoaXMudyp0Lnd9bGVuZ3RoU3EoKXtyZXR1cm4gdGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnordGhpcy53KnRoaXMud31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56K3RoaXMudyp0aGlzLncpfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KStNYXRoLmFicyh0aGlzLncpfW5vcm1hbGl6ZSgpe3JldHVybiB0aGlzLmRpdmlkZVNjYWxhcih0aGlzLmxlbmd0aCgpfHwxKX1zZXRMZW5ndGgodCl7cmV0dXJuIHRoaXMubm9ybWFsaXplKCkubXVsdGlwbHlTY2FsYXIodCl9bGVycCh0LGUpe3JldHVybiB0aGlzLngrPSh0LngtdGhpcy54KSplLHRoaXMueSs9KHQueS10aGlzLnkpKmUsdGhpcy56Kz0odC56LXRoaXMueikqZSx0aGlzLncrPSh0LnctdGhpcy53KSplLHRoaXN9bGVycFZlY3RvcnModCxlLG4pe3JldHVybiB0aGlzLng9dC54KyhlLngtdC54KSpuLHRoaXMueT10LnkrKGUueS10LnkpKm4sdGhpcy56PXQueisoZS56LXQueikqbix0aGlzLnc9dC53KyhlLnctdC53KSpuLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lng9PT10aGlzLngmJnQueT09PXRoaXMueSYmdC56PT09dGhpcy56JiZ0Lnc9PT10aGlzLnd9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXMudz10W2UrM10sdGhpc310b0FycmF5KHQ9W10sZT0wKXtyZXR1cm4gdFtlXT10aGlzLngsdFtlKzFdPXRoaXMueSx0W2UrMl09dGhpcy56LHRbZSszXT10aGlzLncsdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMueD10LmdldFgoZSksdGhpcy55PXQuZ2V0WShlKSx0aGlzLno9dC5nZXRaKGUpLHRoaXMudz10LmdldFcoZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpcy53PU1hdGgucmFuZG9tKCksdGhpc30qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLngseWllbGQgdGhpcy55LHlpZWxkIHRoaXMueix5aWVsZCB0aGlzLnd9fWNsYXNzIHlpe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9MSl7dGhpcy5pc1F1YXRlcm5pb249ITAsdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fdz1zfXN0YXRpYyBzbGVycEZsYXQodCxlLG4scyxyLG8sYSl7bGV0IGM9bltzKzBdLGw9bltzKzFdLGg9bltzKzJdLHU9bltzKzNdO2NvbnN0IGY9cltvKzBdLGQ9cltvKzFdLHA9cltvKzJdLHk9cltvKzNdO2lmKGE9PT0wKXt0W2UrMF09Yyx0W2UrMV09bCx0W2UrMl09aCx0W2UrM109dTtyZXR1cm59aWYoYT09PTEpe3RbZSswXT1mLHRbZSsxXT1kLHRbZSsyXT1wLHRbZSszXT15O3JldHVybn1pZih1IT09eXx8YyE9PWZ8fGwhPT1kfHxoIT09cCl7bGV0IG09MS1hO2NvbnN0IGc9YypmK2wqZCtoKnArdSp5LGI9Zz49MD8xOi0xLHc9MS1nKmc7aWYodz5OdW1iZXIuRVBTSUxPTil7Y29uc3QgTT1NYXRoLnNxcnQodyksQT1NYXRoLmF0YW4yKE0sZypiKTttPU1hdGguc2luKG0qQSkvTSxhPU1hdGguc2luKGEqQSkvTX1jb25zdCB4PWEqYjtpZihjPWMqbStmKngsbD1sKm0rZCp4LGg9aCptK3AqeCx1PXUqbSt5KngsbT09PTEtYSl7Y29uc3QgTT0xL01hdGguc3FydChjKmMrbCpsK2gqaCt1KnUpO2MqPU0sbCo9TSxoKj1NLHUqPU19fXRbZV09Yyx0W2UrMV09bCx0W2UrMl09aCx0W2UrM109dX1zdGF0aWMgbXVsdGlwbHlRdWF0ZXJuaW9uc0ZsYXQodCxlLG4scyxyLG8pe2NvbnN0IGE9bltzXSxjPW5bcysxXSxsPW5bcysyXSxoPW5bcyszXSx1PXJbb10sZj1yW28rMV0sZD1yW28rMl0scD1yW28rM107cmV0dXJuIHRbZV09YSpwK2gqdStjKmQtbCpmLHRbZSsxXT1jKnAraCpmK2wqdS1hKmQsdFtlKzJdPWwqcCtoKmQrYSpmLWMqdSx0W2UrM109aCpwLWEqdS1jKmYtbCpkLHR9Z2V0IHgoKXtyZXR1cm4gdGhpcy5feH1zZXQgeCh0KXt0aGlzLl94PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB5KCl7cmV0dXJuIHRoaXMuX3l9c2V0IHkodCl7dGhpcy5feT10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeigpe3JldHVybiB0aGlzLl96fXNldCB6KHQpe3RoaXMuX3o9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IHcoKXtyZXR1cm4gdGhpcy5fd31zZXQgdyh0KXt0aGlzLl93PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfXNldCh0LGUsbixzKXtyZXR1cm4gdGhpcy5feD10LHRoaXMuX3k9ZSx0aGlzLl96PW4sdGhpcy5fdz1zLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuX3gsdGhpcy5feSx0aGlzLl96LHRoaXMuX3cpfWNvcHkodCl7cmV0dXJuIHRoaXMuX3g9dC54LHRoaXMuX3k9dC55LHRoaXMuX3o9dC56LHRoaXMuX3c9dC53LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21FdWxlcih0LGU9ITApe2NvbnN0IG49dC5feCxzPXQuX3kscj10Ll96LG89dC5fb3JkZXIsYT1NYXRoLmNvcyxjPU1hdGguc2luLGw9YShuLzIpLGg9YShzLzIpLHU9YShyLzIpLGY9YyhuLzIpLGQ9YyhzLzIpLHA9YyhyLzIpO3N3aXRjaChvKXtjYXNlIlhZWiI6dGhpcy5feD1mKmgqdStsKmQqcCx0aGlzLl95PWwqZCp1LWYqaCpwLHRoaXMuX3o9bCpoKnArZipkKnUsdGhpcy5fdz1sKmgqdS1mKmQqcDticmVhaztjYXNlIllYWiI6dGhpcy5feD1mKmgqdStsKmQqcCx0aGlzLl95PWwqZCp1LWYqaCpwLHRoaXMuX3o9bCpoKnAtZipkKnUsdGhpcy5fdz1sKmgqdStmKmQqcDticmVhaztjYXNlIlpYWSI6dGhpcy5feD1mKmgqdS1sKmQqcCx0aGlzLl95PWwqZCp1K2YqaCpwLHRoaXMuX3o9bCpoKnArZipkKnUsdGhpcy5fdz1sKmgqdS1mKmQqcDticmVhaztjYXNlIlpZWCI6dGhpcy5feD1mKmgqdS1sKmQqcCx0aGlzLl95PWwqZCp1K2YqaCpwLHRoaXMuX3o9bCpoKnAtZipkKnUsdGhpcy5fdz1sKmgqdStmKmQqcDticmVhaztjYXNlIllaWCI6dGhpcy5feD1mKmgqdStsKmQqcCx0aGlzLl95PWwqZCp1K2YqaCpwLHRoaXMuX3o9bCpoKnAtZipkKnUsdGhpcy5fdz1sKmgqdS1mKmQqcDticmVhaztjYXNlIlhaWSI6dGhpcy5feD1mKmgqdS1sKmQqcCx0aGlzLl95PWwqZCp1LWYqaCpwLHRoaXMuX3o9bCpoKnArZipkKnUsdGhpcy5fdz1sKmgqdStmKmQqcDticmVhaztkZWZhdWx0OmNvbnNvbGUud2FybigiVEhSRUUuUXVhdGVybmlvbjogLnNldEZyb21FdWxlcigpIGVuY291bnRlcmVkIGFuIHVua25vd24gb3JkZXI6ICIrbyl9cmV0dXJuIGU9PT0hMCYmdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbUF4aXNBbmdsZSh0LGUpe2NvbnN0IG49ZS8yLHM9TWF0aC5zaW4obik7cmV0dXJuIHRoaXMuX3g9dC54KnMsdGhpcy5feT10Lnkqcyx0aGlzLl96PXQueipzLHRoaXMuX3c9TWF0aC5jb3MobiksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVJvdGF0aW9uTWF0cml4KHQpe2NvbnN0IGU9dC5lbGVtZW50cyxuPWVbMF0scz1lWzRdLHI9ZVs4XSxvPWVbMV0sYT1lWzVdLGM9ZVs5XSxsPWVbMl0saD1lWzZdLHU9ZVsxMF0sZj1uK2ErdTtpZihmPjApe2NvbnN0IGQ9LjUvTWF0aC5zcXJ0KGYrMSk7dGhpcy5fdz0uMjUvZCx0aGlzLl94PShoLWMpKmQsdGhpcy5feT0oci1sKSpkLHRoaXMuX3o9KG8tcykqZH1lbHNlIGlmKG4+YSYmbj51KXtjb25zdCBkPTIqTWF0aC5zcXJ0KDErbi1hLXUpO3RoaXMuX3c9KGgtYykvZCx0aGlzLl94PS4yNSpkLHRoaXMuX3k9KHMrbykvZCx0aGlzLl96PShyK2wpL2R9ZWxzZSBpZihhPnUpe2NvbnN0IGQ9MipNYXRoLnNxcnQoMSthLW4tdSk7dGhpcy5fdz0oci1sKS9kLHRoaXMuX3g9KHMrbykvZCx0aGlzLl95PS4yNSpkLHRoaXMuX3o9KGMraCkvZH1lbHNle2NvbnN0IGQ9MipNYXRoLnNxcnQoMSt1LW4tYSk7dGhpcy5fdz0oby1zKS9kLHRoaXMuX3g9KHIrbCkvZCx0aGlzLl95PShjK2gpL2QsdGhpcy5fej0uMjUqZH1yZXR1cm4gdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9c2V0RnJvbVVuaXRWZWN0b3JzKHQsZSl7bGV0IG49dC5kb3QoZSkrMTtyZXR1cm4gbjxOdW1iZXIuRVBTSUxPTj8obj0wLE1hdGguYWJzKHQueCk+TWF0aC5hYnModC56KT8odGhpcy5feD0tdC55LHRoaXMuX3k9dC54LHRoaXMuX3o9MCx0aGlzLl93PW4pOih0aGlzLl94PTAsdGhpcy5feT0tdC56LHRoaXMuX3o9dC55LHRoaXMuX3c9bikpOih0aGlzLl94PXQueSplLnotdC56KmUueSx0aGlzLl95PXQueiplLngtdC54KmUueix0aGlzLl96PXQueCplLnktdC55KmUueCx0aGlzLl93PW4pLHRoaXMubm9ybWFsaXplKCl9YW5nbGVUbyh0KXtyZXR1cm4gMipNYXRoLmFjb3MoTWF0aC5hYnMoWih0aGlzLmRvdCh0KSwtMSwxKSkpfXJvdGF0ZVRvd2FyZHModCxlKXtjb25zdCBuPXRoaXMuYW5nbGVUbyh0KTtpZihuPT09MClyZXR1cm4gdGhpcztjb25zdCBzPU1hdGgubWluKDEsZS9uKTtyZXR1cm4gdGhpcy5zbGVycCh0LHMpLHRoaXN9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMSl9aW52ZXJ0KCl7cmV0dXJuIHRoaXMuY29uanVnYXRlKCl9Y29uanVnYXRlKCl7cmV0dXJuIHRoaXMuX3gqPS0xLHRoaXMuX3kqPS0xLHRoaXMuX3oqPS0xLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfWRvdCh0KXtyZXR1cm4gdGhpcy5feCp0Ll94K3RoaXMuX3kqdC5feSt0aGlzLl96KnQuX3ordGhpcy5fdyp0Ll93fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fd31sZW5ndGgoKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMuX3gqdGhpcy5feCt0aGlzLl95KnRoaXMuX3krdGhpcy5feip0aGlzLl96K3RoaXMuX3cqdGhpcy5fdyl9bm9ybWFsaXplKCl7bGV0IHQ9dGhpcy5sZW5ndGgoKTtyZXR1cm4gdD09PTA/KHRoaXMuX3g9MCx0aGlzLl95PTAsdGhpcy5fej0wLHRoaXMuX3c9MSk6KHQ9MS90LHRoaXMuX3g9dGhpcy5feCp0LHRoaXMuX3k9dGhpcy5feSp0LHRoaXMuX3o9dGhpcy5feip0LHRoaXMuX3c9dGhpcy5fdyp0KSx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseVF1YXRlcm5pb25zKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlRdWF0ZXJuaW9ucyh0LHRoaXMpfW11bHRpcGx5UXVhdGVybmlvbnModCxlKXtjb25zdCBuPXQuX3gscz10Ll95LHI9dC5feixvPXQuX3csYT1lLl94LGM9ZS5feSxsPWUuX3osaD1lLl93O3JldHVybiB0aGlzLl94PW4qaCtvKmErcypsLXIqYyx0aGlzLl95PXMqaCtvKmMrciphLW4qbCx0aGlzLl96PXIqaCtvKmwrbipjLXMqYSx0aGlzLl93PW8qaC1uKmEtcypjLXIqbCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCksdGhpc31zbGVycCh0LGUpe2lmKGU9PT0wKXJldHVybiB0aGlzO2lmKGU9PT0xKXJldHVybiB0aGlzLmNvcHkodCk7Y29uc3Qgbj10aGlzLl94LHM9dGhpcy5feSxyPXRoaXMuX3osbz10aGlzLl93O2xldCBhPW8qdC5fdytuKnQuX3grcyp0Ll95K3IqdC5fejtpZihhPDA/KHRoaXMuX3c9LXQuX3csdGhpcy5feD0tdC5feCx0aGlzLl95PS10Ll95LHRoaXMuX3o9LXQuX3osYT0tYSk6dGhpcy5jb3B5KHQpLGE+PTEpcmV0dXJuIHRoaXMuX3c9byx0aGlzLl94PW4sdGhpcy5feT1zLHRoaXMuX3o9cix0aGlzO2NvbnN0IGM9MS1hKmE7aWYoYzw9TnVtYmVyLkVQU0lMT04pe2NvbnN0IGQ9MS1lO3JldHVybiB0aGlzLl93PWQqbytlKnRoaXMuX3csdGhpcy5feD1kKm4rZSp0aGlzLl94LHRoaXMuX3k9ZCpzK2UqdGhpcy5feSx0aGlzLl96PWQqcitlKnRoaXMuX3osdGhpcy5ub3JtYWxpemUoKSx0aGlzfWNvbnN0IGw9TWF0aC5zcXJ0KGMpLGg9TWF0aC5hdGFuMihsLGEpLHU9TWF0aC5zaW4oKDEtZSkqaCkvbCxmPU1hdGguc2luKGUqaCkvbDtyZXR1cm4gdGhpcy5fdz1vKnUrdGhpcy5fdypmLHRoaXMuX3g9bip1K3RoaXMuX3gqZix0aGlzLl95PXMqdSt0aGlzLl95KmYsdGhpcy5fej1yKnUrdGhpcy5feipmLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNsZXJwUXVhdGVybmlvbnModCxlLG4pe3JldHVybiB0aGlzLmNvcHkodCkuc2xlcnAoZSxuKX1yYW5kb20oKXtjb25zdCB0PTIqTWF0aC5QSSpNYXRoLnJhbmRvbSgpLGU9MipNYXRoLlBJKk1hdGgucmFuZG9tKCksbj1NYXRoLnJhbmRvbSgpLHM9TWF0aC5zcXJ0KDEtbikscj1NYXRoLnNxcnQobik7cmV0dXJuIHRoaXMuc2V0KHMqTWF0aC5zaW4odCkscypNYXRoLmNvcyh0KSxyKk1hdGguc2luKGUpLHIqTWF0aC5jb3MoZSkpfWVxdWFscyh0KXtyZXR1cm4gdC5feD09PXRoaXMuX3gmJnQuX3k9PT10aGlzLl95JiZ0Ll96PT09dGhpcy5feiYmdC5fdz09PXRoaXMuX3d9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy5feD10W2VdLHRoaXMuX3k9dFtlKzFdLHRoaXMuX3o9dFtlKzJdLHRoaXMuX3c9dFtlKzNdLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvQXJyYXkodD1bXSxlPTApe3JldHVybiB0W2VdPXRoaXMuX3gsdFtlKzFdPXRoaXMuX3ksdFtlKzJdPXRoaXMuX3osdFtlKzNdPXRoaXMuX3csdH1mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMuX3g9dC5nZXRYKGUpLHRoaXMuX3k9dC5nZXRZKGUpLHRoaXMuX3o9dC5nZXRaKGUpLHRoaXMuX3c9dC5nZXRXKGUpLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXRvSlNPTigpe3JldHVybiB0aGlzLnRvQXJyYXkoKX1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX3d9fWNsYXNzIFR7Y29uc3RydWN0b3IodD0wLGU9MCxuPTApe1QucHJvdG90eXBlLmlzVmVjdG9yMz0hMCx0aGlzLng9dCx0aGlzLnk9ZSx0aGlzLno9bn1zZXQodCxlLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj10aGlzLnopLHRoaXMueD10LHRoaXMueT1lLHRoaXMuej1uLHRoaXN9c2V0U2NhbGFyKHQpe3JldHVybiB0aGlzLng9dCx0aGlzLnk9dCx0aGlzLno9dCx0aGlzfXNldFgodCl7cmV0dXJuIHRoaXMueD10LHRoaXN9c2V0WSh0KXtyZXR1cm4gdGhpcy55PXQsdGhpc31zZXRaKHQpe3JldHVybiB0aGlzLno9dCx0aGlzfXNldENvbXBvbmVudCh0LGUpe3N3aXRjaCh0KXtjYXNlIDA6dGhpcy54PWU7YnJlYWs7Y2FzZSAxOnRoaXMueT1lO2JyZWFrO2Nhc2UgMjp0aGlzLno9ZTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAiK3QpfXJldHVybiB0aGlzfWdldENvbXBvbmVudCh0KXtzd2l0Y2godCl7Y2FzZSAwOnJldHVybiB0aGlzLng7Y2FzZSAxOnJldHVybiB0aGlzLnk7Y2FzZSAyOnJldHVybiB0aGlzLno7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoImluZGV4IGlzIG91dCBvZiByYW5nZTogIit0KX19Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy54LHRoaXMueSx0aGlzLnopfWNvcHkodCl7cmV0dXJuIHRoaXMueD10LngsdGhpcy55PXQueSx0aGlzLno9dC56LHRoaXN9YWRkKHQpe3JldHVybiB0aGlzLngrPXQueCx0aGlzLnkrPXQueSx0aGlzLnorPXQueix0aGlzfWFkZFNjYWxhcih0KXtyZXR1cm4gdGhpcy54Kz10LHRoaXMueSs9dCx0aGlzLnorPXQsdGhpc31hZGRWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngrZS54LHRoaXMueT10LnkrZS55LHRoaXMuej10LnorZS56LHRoaXN9YWRkU2NhbGVkVmVjdG9yKHQsZSl7cmV0dXJuIHRoaXMueCs9dC54KmUsdGhpcy55Kz10LnkqZSx0aGlzLnorPXQueiplLHRoaXN9c3ViKHQpe3JldHVybiB0aGlzLngtPXQueCx0aGlzLnktPXQueSx0aGlzLnotPXQueix0aGlzfXN1YlNjYWxhcih0KXtyZXR1cm4gdGhpcy54LT10LHRoaXMueS09dCx0aGlzLnotPXQsdGhpc31zdWJWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngtZS54LHRoaXMueT10LnktZS55LHRoaXMuej10LnotZS56LHRoaXN9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMueCo9dC54LHRoaXMueSo9dC55LHRoaXMueio9dC56LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7cmV0dXJuIHRoaXMueCo9dCx0aGlzLnkqPXQsdGhpcy56Kj10LHRoaXN9bXVsdGlwbHlWZWN0b3JzKHQsZSl7cmV0dXJuIHRoaXMueD10LngqZS54LHRoaXMueT10LnkqZS55LHRoaXMuej10LnoqZS56LHRoaXN9YXBwbHlFdWxlcih0KXtyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oeGMuc2V0RnJvbUV1bGVyKHQpKX1hcHBseUF4aXNBbmdsZSh0LGUpe3JldHVybiB0aGlzLmFwcGx5UXVhdGVybmlvbih4Yy5zZXRGcm9tQXhpc0FuZ2xlKHQsZSkpfWFwcGx5TWF0cml4Myh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrclszXSpuK3JbNl0qcyx0aGlzLnk9clsxXSplK3JbNF0qbityWzddKnMsdGhpcy56PXJbMl0qZStyWzVdKm4rcls4XSpzLHRoaXN9YXBwbHlOb3JtYWxNYXRyaXgodCl7cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXgzKHQpLm5vcm1hbGl6ZSgpfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHMsbz0xLyhyWzNdKmUrcls3XSpuK3JbMTFdKnMrclsxNV0pO3JldHVybiB0aGlzLng9KHJbMF0qZStyWzRdKm4rcls4XSpzK3JbMTJdKSpvLHRoaXMueT0oclsxXSplK3JbNV0qbityWzldKnMrclsxM10pKm8sdGhpcy56PShyWzJdKmUrcls2XSpuK3JbMTBdKnMrclsxNF0pKm8sdGhpc31hcHBseVF1YXRlcm5pb24odCl7Y29uc3QgZT10aGlzLngsbj10aGlzLnkscz10aGlzLnoscj10Lngsbz10LnksYT10LnosYz10LncsbD0yKihvKnMtYSpuKSxoPTIqKGEqZS1yKnMpLHU9MioocipuLW8qZSk7cmV0dXJuIHRoaXMueD1lK2MqbCtvKnUtYSpoLHRoaXMueT1uK2MqaCthKmwtcip1LHRoaXMuej1zK2MqdStyKmgtbypsLHRoaXN9cHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZEludmVyc2UpLmFwcGx5TWF0cml4NCh0LnByb2plY3Rpb25NYXRyaXgpfXVucHJvamVjdCh0KXtyZXR1cm4gdGhpcy5hcHBseU1hdHJpeDQodC5wcm9qZWN0aW9uTWF0cml4SW52ZXJzZSkuYXBwbHlNYXRyaXg0KHQubWF0cml4V29ybGQpfXRyYW5zZm9ybURpcmVjdGlvbih0KXtjb25zdCBlPXRoaXMueCxuPXRoaXMueSxzPXRoaXMueixyPXQuZWxlbWVudHM7cmV0dXJuIHRoaXMueD1yWzBdKmUrcls0XSpuK3JbOF0qcyx0aGlzLnk9clsxXSplK3JbNV0qbityWzldKnMsdGhpcy56PXJbMl0qZStyWzZdKm4rclsxMF0qcyx0aGlzLm5vcm1hbGl6ZSgpfWRpdmlkZSh0KXtyZXR1cm4gdGhpcy54Lz10LngsdGhpcy55Lz10LnksdGhpcy56Lz10LnosdGhpc31kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoMS90KX1taW4odCl7cmV0dXJuIHRoaXMueD1NYXRoLm1pbih0aGlzLngsdC54KSx0aGlzLnk9TWF0aC5taW4odGhpcy55LHQueSksdGhpcy56PU1hdGgubWluKHRoaXMueix0LnopLHRoaXN9bWF4KHQpe3JldHVybiB0aGlzLng9TWF0aC5tYXgodGhpcy54LHQueCksdGhpcy55PU1hdGgubWF4KHRoaXMueSx0LnkpLHRoaXMuej1NYXRoLm1heCh0aGlzLnosdC56KSx0aGlzfWNsYW1wKHQsZSl7cmV0dXJuIHRoaXMueD1aKHRoaXMueCx0LngsZS54KSx0aGlzLnk9Wih0aGlzLnksdC55LGUueSksdGhpcy56PVoodGhpcy56LHQueixlLnopLHRoaXN9Y2xhbXBTY2FsYXIodCxlKXtyZXR1cm4gdGhpcy54PVoodGhpcy54LHQsZSksdGhpcy55PVoodGhpcy55LHQsZSksdGhpcy56PVoodGhpcy56LHQsZSksdGhpc31jbGFtcExlbmd0aCh0LGUpe2NvbnN0IG49dGhpcy5sZW5ndGgoKTtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIobnx8MSkubXVsdGlwbHlTY2FsYXIoWihuLHQsZSkpfWZsb29yKCl7cmV0dXJuIHRoaXMueD1NYXRoLmZsb29yKHRoaXMueCksdGhpcy55PU1hdGguZmxvb3IodGhpcy55KSx0aGlzLno9TWF0aC5mbG9vcih0aGlzLnopLHRoaXN9Y2VpbCgpe3JldHVybiB0aGlzLng9TWF0aC5jZWlsKHRoaXMueCksdGhpcy55PU1hdGguY2VpbCh0aGlzLnkpLHRoaXMuej1NYXRoLmNlaWwodGhpcy56KSx0aGlzfXJvdW5kKCl7cmV0dXJuIHRoaXMueD1NYXRoLnJvdW5kKHRoaXMueCksdGhpcy55PU1hdGgucm91bmQodGhpcy55KSx0aGlzLno9TWF0aC5yb3VuZCh0aGlzLnopLHRoaXN9cm91bmRUb1plcm8oKXtyZXR1cm4gdGhpcy54PU1hdGgudHJ1bmModGhpcy54KSx0aGlzLnk9TWF0aC50cnVuYyh0aGlzLnkpLHRoaXMuej1NYXRoLnRydW5jKHRoaXMueiksdGhpc31uZWdhdGUoKXtyZXR1cm4gdGhpcy54PS10aGlzLngsdGhpcy55PS10aGlzLnksdGhpcy56PS10aGlzLnosdGhpc31kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueSt0aGlzLnoqdC56fWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMueCp0aGlzLngrdGhpcy55KnRoaXMueSt0aGlzLnoqdGhpcy56fWxlbmd0aCgpe3JldHVybiBNYXRoLnNxcnQodGhpcy54KnRoaXMueCt0aGlzLnkqdGhpcy55K3RoaXMueip0aGlzLnopfW1hbmhhdHRhbkxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLngpK01hdGguYWJzKHRoaXMueSkrTWF0aC5hYnModGhpcy56KX1ub3JtYWxpemUoKXtyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIodGhpcy5sZW5ndGgoKXx8MSl9c2V0TGVuZ3RoKHQpe3JldHVybiB0aGlzLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKHQpfWxlcnAodCxlKXtyZXR1cm4gdGhpcy54Kz0odC54LXRoaXMueCkqZSx0aGlzLnkrPSh0LnktdGhpcy55KSplLHRoaXMueis9KHQuei10aGlzLnopKmUsdGhpc31sZXJwVmVjdG9ycyh0LGUsbil7cmV0dXJuIHRoaXMueD10LngrKGUueC10LngpKm4sdGhpcy55PXQueSsoZS55LXQueSkqbix0aGlzLno9dC56KyhlLnotdC56KSpuLHRoaXN9Y3Jvc3ModCl7cmV0dXJuIHRoaXMuY3Jvc3NWZWN0b3JzKHRoaXMsdCl9Y3Jvc3NWZWN0b3JzKHQsZSl7Y29uc3Qgbj10Lngscz10Lnkscj10Lnosbz1lLngsYT1lLnksYz1lLno7cmV0dXJuIHRoaXMueD1zKmMtciphLHRoaXMueT1yKm8tbipjLHRoaXMuej1uKmEtcypvLHRoaXN9cHJvamVjdE9uVmVjdG9yKHQpe2NvbnN0IGU9dC5sZW5ndGhTcSgpO2lmKGU9PT0wKXJldHVybiB0aGlzLnNldCgwLDAsMCk7Y29uc3Qgbj10LmRvdCh0aGlzKS9lO3JldHVybiB0aGlzLmNvcHkodCkubXVsdGlwbHlTY2FsYXIobil9cHJvamVjdE9uUGxhbmUodCl7cmV0dXJuIHRvLmNvcHkodGhpcykucHJvamVjdE9uVmVjdG9yKHQpLHRoaXMuc3ViKHRvKX1yZWZsZWN0KHQpe3JldHVybiB0aGlzLnN1Yih0by5jb3B5KHQpLm11bHRpcGx5U2NhbGFyKDIqdGhpcy5kb3QodCkpKX1hbmdsZVRvKHQpe2NvbnN0IGU9TWF0aC5zcXJ0KHRoaXMubGVuZ3RoU3EoKSp0Lmxlbmd0aFNxKCkpO2lmKGU9PT0wKXJldHVybiBNYXRoLlBJLzI7Y29uc3Qgbj10aGlzLmRvdCh0KS9lO3JldHVybiBNYXRoLmFjb3MoWihuLC0xLDEpKX1kaXN0YW5jZVRvKHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVRvU3F1YXJlZCh0KSl9ZGlzdGFuY2VUb1NxdWFyZWQodCl7Y29uc3QgZT10aGlzLngtdC54LG49dGhpcy55LXQueSxzPXRoaXMuei10Lno7cmV0dXJuIGUqZStuKm4rcypzfW1hbmhhdHRhbkRpc3RhbmNlVG8odCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueC10LngpK01hdGguYWJzKHRoaXMueS10LnkpK01hdGguYWJzKHRoaXMuei10LnopfXNldEZyb21TcGhlcmljYWwodCl7cmV0dXJuIHRoaXMuc2V0RnJvbVNwaGVyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnBoaSx0LnRoZXRhKX1zZXRGcm9tU3BoZXJpY2FsQ29vcmRzKHQsZSxuKXtjb25zdCBzPU1hdGguc2luKGUpKnQ7cmV0dXJuIHRoaXMueD1zKk1hdGguc2luKG4pLHRoaXMueT1NYXRoLmNvcyhlKSp0LHRoaXMuej1zKk1hdGguY29zKG4pLHRoaXN9c2V0RnJvbUN5bGluZHJpY2FsKHQpe3JldHVybiB0aGlzLnNldEZyb21DeWxpbmRyaWNhbENvb3Jkcyh0LnJhZGl1cyx0LnRoZXRhLHQueSl9c2V0RnJvbUN5bGluZHJpY2FsQ29vcmRzKHQsZSxuKXtyZXR1cm4gdGhpcy54PXQqTWF0aC5zaW4oZSksdGhpcy55PW4sdGhpcy56PXQqTWF0aC5jb3MoZSksdGhpc31zZXRGcm9tTWF0cml4UG9zaXRpb24odCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLng9ZVsxMl0sdGhpcy55PWVbMTNdLHRoaXMuej1lWzE0XSx0aGlzfXNldEZyb21NYXRyaXhTY2FsZSh0KXtjb25zdCBlPXRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLG49dGhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCkscz10aGlzLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gdGhpcy54PWUsdGhpcy55PW4sdGhpcy56PXMsdGhpc31zZXRGcm9tTWF0cml4Q29sdW1uKHQsZSl7cmV0dXJuIHRoaXMuZnJvbUFycmF5KHQuZWxlbWVudHMsZSo0KX1zZXRGcm9tTWF0cml4M0NvbHVtbih0LGUpe3JldHVybiB0aGlzLmZyb21BcnJheSh0LmVsZW1lbnRzLGUqMyl9c2V0RnJvbUV1bGVyKHQpe3JldHVybiB0aGlzLng9dC5feCx0aGlzLnk9dC5feSx0aGlzLno9dC5feix0aGlzfXNldEZyb21Db2xvcih0KXtyZXR1cm4gdGhpcy54PXQucix0aGlzLnk9dC5nLHRoaXMuej10LmIsdGhpc31lcXVhbHModCl7cmV0dXJuIHQueD09PXRoaXMueCYmdC55PT09dGhpcy55JiZ0Lno9PT10aGlzLnp9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy54PXRbZV0sdGhpcy55PXRbZSsxXSx0aGlzLno9dFtlKzJdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy54LHRbZSsxXT10aGlzLnksdFtlKzJdPXRoaXMueix0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy54PXQuZ2V0WChlKSx0aGlzLnk9dC5nZXRZKGUpLHRoaXMuej10LmdldFooZSksdGhpc31yYW5kb20oKXtyZXR1cm4gdGhpcy54PU1hdGgucmFuZG9tKCksdGhpcy55PU1hdGgucmFuZG9tKCksdGhpcy56PU1hdGgucmFuZG9tKCksdGhpc31yYW5kb21EaXJlY3Rpb24oKXtjb25zdCB0PU1hdGgucmFuZG9tKCkqTWF0aC5QSSoyLGU9TWF0aC5yYW5kb20oKSoyLTEsbj1NYXRoLnNxcnQoMS1lKmUpO3JldHVybiB0aGlzLng9bipNYXRoLmNvcyh0KSx0aGlzLnk9ZSx0aGlzLno9bipNYXRoLnNpbih0KSx0aGlzfSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMueCx5aWVsZCB0aGlzLnkseWllbGQgdGhpcy56fX1jb25zdCB0bz1uZXcgVCx4Yz1uZXcgeWk7Y2xhc3MgZ3R7Y29uc3RydWN0b3IodD1uZXcgVCgxLzAsMS8wLDEvMCksZT1uZXcgVCgtMS8wLC0xLzAsLTEvMCkpe3RoaXMuaXNCb3gzPSEwLHRoaXMubWluPXQsdGhpcy5tYXg9ZX1zZXQodCxlKXtyZXR1cm4gdGhpcy5taW4uY29weSh0KSx0aGlzLm1heC5jb3B5KGUpLHRoaXN9c2V0RnJvbUFycmF5KHQpe3RoaXMubWFrZUVtcHR5KCk7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aDtlPG47ZSs9Myl0aGlzLmV4cGFuZEJ5UG9pbnQoY2UuZnJvbUFycmF5KHQsZSkpO3JldHVybiB0aGlzfXNldEZyb21CdWZmZXJBdHRyaWJ1dGUodCl7dGhpcy5tYWtlRW1wdHkoKTtmb3IobGV0IGU9MCxuPXQuY291bnQ7ZTxuO2UrKyl0aGlzLmV4cGFuZEJ5UG9pbnQoY2UuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpKTtyZXR1cm4gdGhpc31zZXRGcm9tUG9pbnRzKHQpe3RoaXMubWFrZUVtcHR5KCk7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aDtlPG47ZSsrKXRoaXMuZXhwYW5kQnlQb2ludCh0W2VdKTtyZXR1cm4gdGhpc31zZXRGcm9tQ2VudGVyQW5kU2l6ZSh0LGUpe2NvbnN0IG49Y2UuY29weShlKS5tdWx0aXBseVNjYWxhciguNSk7cmV0dXJuIHRoaXMubWluLmNvcHkodCkuc3ViKG4pLHRoaXMubWF4LmNvcHkodCkuYWRkKG4pLHRoaXN9c2V0RnJvbU9iamVjdCh0LGU9ITEpe3JldHVybiB0aGlzLm1ha2VFbXB0eSgpLHRoaXMuZXhwYW5kQnlPYmplY3QodCxlKX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5taW4uY29weSh0Lm1pbiksdGhpcy5tYXguY29weSh0Lm1heCksdGhpc31tYWtlRW1wdHkoKXtyZXR1cm4gdGhpcy5taW4ueD10aGlzLm1pbi55PXRoaXMubWluLno9MS8wLHRoaXMubWF4Lng9dGhpcy5tYXgueT10aGlzLm1heC56PS0xLzAsdGhpc31pc0VtcHR5KCl7cmV0dXJuIHRoaXMubWF4Lng8dGhpcy5taW4ueHx8dGhpcy5tYXgueTx0aGlzLm1pbi55fHx0aGlzLm1heC56PHRoaXMubWluLnp9Z2V0Q2VudGVyKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90LnNldCgwLDAsMCk6dC5hZGRWZWN0b3JzKHRoaXMubWluLHRoaXMubWF4KS5tdWx0aXBseVNjYWxhciguNSl9Z2V0U2l6ZSh0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dC5zZXQoMCwwLDApOnQuc3ViVmVjdG9ycyh0aGlzLm1heCx0aGlzLm1pbil9ZXhwYW5kQnlQb2ludCh0KXtyZXR1cm4gdGhpcy5taW4ubWluKHQpLHRoaXMubWF4Lm1heCh0KSx0aGlzfWV4cGFuZEJ5VmVjdG9yKHQpe3JldHVybiB0aGlzLm1pbi5zdWIodCksdGhpcy5tYXguYWRkKHQpLHRoaXN9ZXhwYW5kQnlTY2FsYXIodCl7cmV0dXJuIHRoaXMubWluLmFkZFNjYWxhcigtdCksdGhpcy5tYXguYWRkU2NhbGFyKHQpLHRoaXN9ZXhwYW5kQnlPYmplY3QodCxlPSExKXt0LnVwZGF0ZVdvcmxkTWF0cml4KCExLCExKTtjb25zdCBuPXQuZ2VvbWV0cnk7aWYobiE9PXZvaWQgMCl7Y29uc3Qgcj1uLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKTtpZihlPT09ITAmJnIhPT12b2lkIDAmJnQuaXNJbnN0YW5jZWRNZXNoIT09ITApZm9yKGxldCBvPTAsYT1yLmNvdW50O288YTtvKyspdC5pc01lc2g9PT0hMD90LmdldFZlcnRleFBvc2l0aW9uKG8sY2UpOmNlLmZyb21CdWZmZXJBdHRyaWJ1dGUocixvKSxjZS5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZCksdGhpcy5leHBhbmRCeVBvaW50KGNlKTtlbHNlIHQuYm91bmRpbmdCb3ghPT12b2lkIDA/KHQuYm91bmRpbmdCb3g9PT1udWxsJiZ0LmNvbXB1dGVCb3VuZGluZ0JveCgpLHNzLmNvcHkodC5ib3VuZGluZ0JveCkpOihuLmJvdW5kaW5nQm94PT09bnVsbCYmbi5jb21wdXRlQm91bmRpbmdCb3goKSxzcy5jb3B5KG4uYm91bmRpbmdCb3gpKSxzcy5hcHBseU1hdHJpeDQodC5tYXRyaXhXb3JsZCksdGhpcy51bmlvbihzcyl9Y29uc3Qgcz10LmNoaWxkcmVuO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKyl0aGlzLmV4cGFuZEJ5T2JqZWN0KHNbcl0sZSk7cmV0dXJuIHRoaXN9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gdC54Pj10aGlzLm1pbi54JiZ0Lng8PXRoaXMubWF4LngmJnQueT49dGhpcy5taW4ueSYmdC55PD10aGlzLm1heC55JiZ0Lno+PXRoaXMubWluLnomJnQuejw9dGhpcy5tYXguen1jb250YWluc0JveCh0KXtyZXR1cm4gdGhpcy5taW4ueDw9dC5taW4ueCYmdC5tYXgueDw9dGhpcy5tYXgueCYmdGhpcy5taW4ueTw9dC5taW4ueSYmdC5tYXgueTw9dGhpcy5tYXgueSYmdGhpcy5taW4uejw9dC5taW4ueiYmdC5tYXguejw9dGhpcy5tYXguen1nZXRQYXJhbWV0ZXIodCxlKXtyZXR1cm4gZS5zZXQoKHQueC10aGlzLm1pbi54KS8odGhpcy5tYXgueC10aGlzLm1pbi54KSwodC55LXRoaXMubWluLnkpLyh0aGlzLm1heC55LXRoaXMubWluLnkpLCh0LnotdGhpcy5taW4ueikvKHRoaXMubWF4LnotdGhpcy5taW4ueikpfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQubWF4Lng+PXRoaXMubWluLngmJnQubWluLng8PXRoaXMubWF4LngmJnQubWF4Lnk+PXRoaXMubWluLnkmJnQubWluLnk8PXRoaXMubWF4LnkmJnQubWF4Lno+PXRoaXMubWluLnomJnQubWluLno8PXRoaXMubWF4Lnp9aW50ZXJzZWN0c1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5jbGFtcFBvaW50KHQuY2VudGVyLGNlKSxjZS5kaXN0YW5jZVRvU3F1YXJlZCh0LmNlbnRlcik8PXQucmFkaXVzKnQucmFkaXVzfWludGVyc2VjdHNQbGFuZSh0KXtsZXQgZSxuO3JldHVybiB0Lm5vcm1hbC54PjA/KGU9dC5ub3JtYWwueCp0aGlzLm1pbi54LG49dC5ub3JtYWwueCp0aGlzLm1heC54KTooZT10Lm5vcm1hbC54KnRoaXMubWF4Lngsbj10Lm5vcm1hbC54KnRoaXMubWluLngpLHQubm9ybWFsLnk+MD8oZSs9dC5ub3JtYWwueSp0aGlzLm1pbi55LG4rPXQubm9ybWFsLnkqdGhpcy5tYXgueSk6KGUrPXQubm9ybWFsLnkqdGhpcy5tYXgueSxuKz10Lm5vcm1hbC55KnRoaXMubWluLnkpLHQubm9ybWFsLno+MD8oZSs9dC5ub3JtYWwueip0aGlzLm1pbi56LG4rPXQubm9ybWFsLnoqdGhpcy5tYXgueik6KGUrPXQubm9ybWFsLnoqdGhpcy5tYXgueixuKz10Lm5vcm1hbC56KnRoaXMubWluLnopLGU8PS10LmNvbnN0YW50JiZuPj0tdC5jb25zdGFudH1pbnRlcnNlY3RzVHJpYW5nbGUodCl7aWYodGhpcy5pc0VtcHR5KCkpcmV0dXJuITE7dGhpcy5nZXRDZW50ZXIobWkpLHJzLnN1YlZlY3RvcnModGhpcy5tYXgsbWkpLGtuLnN1YlZlY3RvcnModC5hLG1pKSxObi5zdWJWZWN0b3JzKHQuYixtaSksUm4uc3ViVmVjdG9ycyh0LmMsbWkpLFplLnN1YlZlY3RvcnMoTm4sa24pLFhlLnN1YlZlY3RvcnMoUm4sTm4pLGxuLnN1YlZlY3RvcnMoa24sUm4pO2xldCBlPVswLC1aZS56LFplLnksMCwtWGUueixYZS55LDAsLWxuLnosbG4ueSxaZS56LDAsLVplLngsWGUueiwwLC1YZS54LGxuLnosMCwtbG4ueCwtWmUueSxaZS54LDAsLVhlLnksWGUueCwwLC1sbi55LGxuLngsMF07cmV0dXJuIWVvKGUsa24sTm4sUm4scnMpfHwoZT1bMSwwLDAsMCwxLDAsMCwwLDFdLCFlbyhlLGtuLE5uLFJuLHJzKSk/ITE6KG9zLmNyb3NzVmVjdG9ycyhaZSxYZSksZT1bb3MueCxvcy55LG9zLnpdLGVvKGUsa24sTm4sUm4scnMpKX1jbGFtcFBvaW50KHQsZSl7cmV0dXJuIGUuY29weSh0KS5jbGFtcCh0aGlzLm1pbix0aGlzLm1heCl9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiB0aGlzLmNsYW1wUG9pbnQodCxjZSkuZGlzdGFuY2VUbyh0KX1nZXRCb3VuZGluZ1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/dC5tYWtlRW1wdHkoKToodGhpcy5nZXRDZW50ZXIodC5jZW50ZXIpLHQucmFkaXVzPXRoaXMuZ2V0U2l6ZShjZSkubGVuZ3RoKCkqLjUpLHR9aW50ZXJzZWN0KHQpe3JldHVybiB0aGlzLm1pbi5tYXgodC5taW4pLHRoaXMubWF4Lm1pbih0Lm1heCksdGhpcy5pc0VtcHR5KCkmJnRoaXMubWFrZUVtcHR5KCksdGhpc311bmlvbih0KXtyZXR1cm4gdGhpcy5taW4ubWluKHQubWluKSx0aGlzLm1heC5tYXgodC5tYXgpLHRoaXN9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90aGlzOihTZVswXS5zZXQodGhpcy5taW4ueCx0aGlzLm1pbi55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVsxXS5zZXQodGhpcy5taW4ueCx0aGlzLm1pbi55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSxTZVsyXS5zZXQodGhpcy5taW4ueCx0aGlzLm1heC55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVszXS5zZXQodGhpcy5taW4ueCx0aGlzLm1heC55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSxTZVs0XS5zZXQodGhpcy5tYXgueCx0aGlzLm1pbi55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVs1XS5zZXQodGhpcy5tYXgueCx0aGlzLm1pbi55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSxTZVs2XS5zZXQodGhpcy5tYXgueCx0aGlzLm1heC55LHRoaXMubWluLnopLmFwcGx5TWF0cml4NCh0KSxTZVs3XS5zZXQodGhpcy5tYXgueCx0aGlzLm1heC55LHRoaXMubWF4LnopLmFwcGx5TWF0cml4NCh0KSx0aGlzLnNldEZyb21Qb2ludHMoU2UpLHRoaXMpfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5taW4uYWRkKHQpLHRoaXMubWF4LmFkZCh0KSx0aGlzfWVxdWFscyh0KXtyZXR1cm4gdC5taW4uZXF1YWxzKHRoaXMubWluKSYmdC5tYXguZXF1YWxzKHRoaXMubWF4KX19Y29uc3QgU2U9W25ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBULG5ldyBUXSxjZT1uZXcgVCxzcz1uZXcgZ3Qsa249bmV3IFQsTm49bmV3IFQsUm49bmV3IFQsWmU9bmV3IFQsWGU9bmV3IFQsbG49bmV3IFQsbWk9bmV3IFQscnM9bmV3IFQsb3M9bmV3IFQsaG49bmV3IFQ7ZnVuY3Rpb24gZW8oaSx0LGUsbixzKXtmb3IobGV0IHI9MCxvPWkubGVuZ3RoLTM7cjw9bztyKz0zKXtobi5mcm9tQXJyYXkoaSxyKTtjb25zdCBhPXMueCpNYXRoLmFicyhobi54KStzLnkqTWF0aC5hYnMoaG4ueSkrcy56Kk1hdGguYWJzKGhuLnopLGM9dC5kb3QoaG4pLGw9ZS5kb3QoaG4pLGg9bi5kb3QoaG4pO2lmKE1hdGgubWF4KC1NYXRoLm1heChjLGwsaCksTWF0aC5taW4oYyxsLGgpKT5hKXJldHVybiExfXJldHVybiEwfWNvbnN0IFh1PW5ldyBndCxnaT1uZXcgVCxubz1uZXcgVDtjbGFzcyBpb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9LTEpe3RoaXMuaXNTcGhlcmU9ITAsdGhpcy5jZW50ZXI9dCx0aGlzLnJhZGl1cz1lfXNldCh0LGUpe3JldHVybiB0aGlzLmNlbnRlci5jb3B5KHQpLHRoaXMucmFkaXVzPWUsdGhpc31zZXRGcm9tUG9pbnRzKHQsZSl7Y29uc3Qgbj10aGlzLmNlbnRlcjtlIT09dm9pZCAwP24uY29weShlKTpYdS5zZXRGcm9tUG9pbnRzKHQpLmdldENlbnRlcihuKTtsZXQgcz0wO2ZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKylzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZCh0W3JdKSk7cmV0dXJuIHRoaXMucmFkaXVzPU1hdGguc3FydChzKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuY2VudGVyLmNvcHkodC5jZW50ZXIpLHRoaXMucmFkaXVzPXQucmFkaXVzLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLnJhZGl1czwwfW1ha2VFbXB0eSgpe3JldHVybiB0aGlzLmNlbnRlci5zZXQoMCwwLDApLHRoaXMucmFkaXVzPS0xLHRoaXN9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmNlbnRlcik8PXRoaXMucmFkaXVzKnRoaXMucmFkaXVzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKS10aGlzLnJhZGl1c31pbnRlcnNlY3RzU3BoZXJlKHQpe2NvbnN0IGU9dGhpcy5yYWRpdXMrdC5yYWRpdXM7cmV0dXJuIHQuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHRoaXMuY2VudGVyKTw9ZSplfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1NwaGVyZSh0aGlzKX1pbnRlcnNlY3RzUGxhbmUodCl7cmV0dXJuIE1hdGguYWJzKHQuZGlzdGFuY2VUb1BvaW50KHRoaXMuY2VudGVyKSk8PXRoaXMucmFkaXVzfWNsYW1wUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKHQpO3JldHVybiBlLmNvcHkodCksbj50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyYmKGUuc3ViKHRoaXMuY2VudGVyKS5ub3JtYWxpemUoKSxlLm11bHRpcGx5U2NhbGFyKHRoaXMucmFkaXVzKS5hZGQodGhpcy5jZW50ZXIpKSxlfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT8odC5tYWtlRW1wdHkoKSx0KToodC5zZXQodGhpcy5jZW50ZXIsdGhpcy5jZW50ZXIpLHQuZXhwYW5kQnlTY2FsYXIodGhpcy5yYWRpdXMpLHQpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYXBwbHlNYXRyaXg0KHQpLHRoaXMucmFkaXVzPXRoaXMucmFkaXVzKnQuZ2V0TWF4U2NhbGVPbkF4aXMoKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jZW50ZXIuYWRkKHQpLHRoaXN9ZXhwYW5kQnlQb2ludCh0KXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4gdGhpcy5jZW50ZXIuY29weSh0KSx0aGlzLnJhZGl1cz0wLHRoaXM7Z2kuc3ViVmVjdG9ycyh0LHRoaXMuY2VudGVyKTtjb25zdCBlPWdpLmxlbmd0aFNxKCk7aWYoZT50aGlzLnJhZGl1cyp0aGlzLnJhZGl1cyl7Y29uc3Qgbj1NYXRoLnNxcnQoZSkscz0obi10aGlzLnJhZGl1cykqLjU7dGhpcy5jZW50ZXIuYWRkU2NhbGVkVmVjdG9yKGdpLHMvbiksdGhpcy5yYWRpdXMrPXN9cmV0dXJuIHRoaXN9dW5pb24odCl7cmV0dXJuIHQuaXNFbXB0eSgpP3RoaXM6dGhpcy5pc0VtcHR5KCk/KHRoaXMuY29weSh0KSx0aGlzKToodGhpcy5jZW50ZXIuZXF1YWxzKHQuY2VudGVyKT09PSEwP3RoaXMucmFkaXVzPU1hdGgubWF4KHRoaXMucmFkaXVzLHQucmFkaXVzKToobm8uc3ViVmVjdG9ycyh0LmNlbnRlcix0aGlzLmNlbnRlcikuc2V0TGVuZ3RoKHQucmFkaXVzKSx0aGlzLmV4cGFuZEJ5UG9pbnQoZ2kuY29weSh0LmNlbnRlcikuYWRkKG5vKSksdGhpcy5leHBhbmRCeVBvaW50KGdpLmNvcHkodC5jZW50ZXIpLnN1YihubykpKSx0aGlzKX1lcXVhbHModCl7cmV0dXJuIHQuY2VudGVyLmVxdWFscyh0aGlzLmNlbnRlcikmJnQucmFkaXVzPT09dGhpcy5yYWRpdXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX1jb25zdCB2ZT1uZXcgVCxzbz1uZXcgVCxhcz1uZXcgVCxKZT1uZXcgVCxybz1uZXcgVCxjcz1uZXcgVCxvbz1uZXcgVDtjbGFzcyBhb3tjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQoMCwwLC0xKSl7dGhpcy5vcmlnaW49dCx0aGlzLmRpcmVjdGlvbj1lfXNldCh0LGUpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQpLHRoaXMuZGlyZWN0aW9uLmNvcHkoZSksdGhpc31jb3B5KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHQub3JpZ2luKSx0aGlzLmRpcmVjdGlvbi5jb3B5KHQuZGlyZWN0aW9uKSx0aGlzfWF0KHQsZSl7cmV0dXJuIGUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLHQpfWxvb2tBdCh0KXtyZXR1cm4gdGhpcy5kaXJlY3Rpb24uY29weSh0KS5zdWIodGhpcy5vcmlnaW4pLm5vcm1hbGl6ZSgpLHRoaXN9cmVjYXN0KHQpe3JldHVybiB0aGlzLm9yaWdpbi5jb3B5KHRoaXMuYXQodCx2ZSkpLHRoaXN9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUpe2Uuc3ViVmVjdG9ycyh0LHRoaXMub3JpZ2luKTtjb25zdCBuPWUuZG90KHRoaXMuZGlyZWN0aW9uKTtyZXR1cm4gbjwwP2UuY29weSh0aGlzLm9yaWdpbik6ZS5jb3B5KHRoaXMub3JpZ2luKS5hZGRTY2FsZWRWZWN0b3IodGhpcy5kaXJlY3Rpb24sbil9ZGlzdGFuY2VUb1BvaW50KHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVNxVG9Qb2ludCh0KSl9ZGlzdGFuY2VTcVRvUG9pbnQodCl7Y29uc3QgZT12ZS5zdWJWZWN0b3JzKHQsdGhpcy5vcmlnaW4pLmRvdCh0aGlzLmRpcmVjdGlvbik7cmV0dXJuIGU8MD90aGlzLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZCh0KToodmUuY29weSh0aGlzLm9yaWdpbikuYWRkU2NhbGVkVmVjdG9yKHRoaXMuZGlyZWN0aW9uLGUpLHZlLmRpc3RhbmNlVG9TcXVhcmVkKHQpKX1kaXN0YW5jZVNxVG9TZWdtZW50KHQsZSxuLHMpe3NvLmNvcHkodCkuYWRkKGUpLm11bHRpcGx5U2NhbGFyKC41KSxhcy5jb3B5KGUpLnN1Yih0KS5ub3JtYWxpemUoKSxKZS5jb3B5KHRoaXMub3JpZ2luKS5zdWIoc28pO2NvbnN0IHI9dC5kaXN0YW5jZVRvKGUpKi41LG89LXRoaXMuZGlyZWN0aW9uLmRvdChhcyksYT1KZS5kb3QodGhpcy5kaXJlY3Rpb24pLGM9LUplLmRvdChhcyksbD1KZS5sZW5ndGhTcSgpLGg9TWF0aC5hYnMoMS1vKm8pO2xldCB1LGYsZCxwO2lmKGg+MClpZih1PW8qYy1hLGY9byphLWMscD1yKmgsdT49MClpZihmPj0tcClpZihmPD1wKXtjb25zdCB5PTEvaDt1Kj15LGYqPXksZD11Kih1K28qZisyKmEpK2YqKG8qdStmKzIqYykrbH1lbHNlIGY9cix1PU1hdGgubWF4KDAsLShvKmYrYSkpLGQ9LXUqdStmKihmKzIqYykrbDtlbHNlIGY9LXIsdT1NYXRoLm1heCgwLC0obypmK2EpKSxkPS11KnUrZiooZisyKmMpK2w7ZWxzZSBmPD0tcD8odT1NYXRoLm1heCgwLC0oLW8qcithKSksZj11PjA/LXI6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk6Zjw9cD8odT0wLGY9TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9ZiooZisyKmMpK2wpOih1PU1hdGgubWF4KDAsLShvKnIrYSkpLGY9dT4wP3I6TWF0aC5taW4oTWF0aC5tYXgoLXIsLWMpLHIpLGQ9LXUqdStmKihmKzIqYykrbCk7ZWxzZSBmPW8+MD8tcjpyLHU9TWF0aC5tYXgoMCwtKG8qZithKSksZD0tdSp1K2YqKGYrMipjKStsO3JldHVybiBuJiZuLmNvcHkodGhpcy5vcmlnaW4pLmFkZFNjYWxlZFZlY3Rvcih0aGlzLmRpcmVjdGlvbix1KSxzJiZzLmNvcHkoc28pLmFkZFNjYWxlZFZlY3RvcihhcyxmKSxkfWludGVyc2VjdFNwaGVyZSh0LGUpe3ZlLnN1YlZlY3RvcnModC5jZW50ZXIsdGhpcy5vcmlnaW4pO2NvbnN0IG49dmUuZG90KHRoaXMuZGlyZWN0aW9uKSxzPXZlLmRvdCh2ZSktbipuLHI9dC5yYWRpdXMqdC5yYWRpdXM7aWYocz5yKXJldHVybiBudWxsO2NvbnN0IG89TWF0aC5zcXJ0KHItcyksYT1uLW8sYz1uK287cmV0dXJuIGM8MD9udWxsOmE8MD90aGlzLmF0KGMsZSk6dGhpcy5hdChhLGUpfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIHRoaXMuZGlzdGFuY2VTcVRvUG9pbnQodC5jZW50ZXIpPD10LnJhZGl1cyp0LnJhZGl1c31kaXN0YW5jZVRvUGxhbmUodCl7Y29uc3QgZT10Lm5vcm1hbC5kb3QodGhpcy5kaXJlY3Rpb24pO2lmKGU9PT0wKXJldHVybiB0LmRpc3RhbmNlVG9Qb2ludCh0aGlzLm9yaWdpbik9PT0wPzA6bnVsbDtjb25zdCBuPS0odGhpcy5vcmlnaW4uZG90KHQubm9ybWFsKSt0LmNvbnN0YW50KS9lO3JldHVybiBuPj0wP246bnVsbH1pbnRlcnNlY3RQbGFuZSh0LGUpe2NvbnN0IG49dGhpcy5kaXN0YW5jZVRvUGxhbmUodCk7cmV0dXJuIG49PT1udWxsP251bGw6dGhpcy5hdChuLGUpfWludGVyc2VjdHNQbGFuZSh0KXtjb25zdCBlPXQuZGlzdGFuY2VUb1BvaW50KHRoaXMub3JpZ2luKTtyZXR1cm4gZT09PTB8fHQubm9ybWFsLmRvdCh0aGlzLmRpcmVjdGlvbikqZTwwfWludGVyc2VjdEJveCh0LGUpe2xldCBuLHMscixvLGEsYztjb25zdCBsPTEvdGhpcy5kaXJlY3Rpb24ueCxoPTEvdGhpcy5kaXJlY3Rpb24ueSx1PTEvdGhpcy5kaXJlY3Rpb24ueixmPXRoaXMub3JpZ2luO3JldHVybiBsPj0wPyhuPSh0Lm1pbi54LWYueCkqbCxzPSh0Lm1heC54LWYueCkqbCk6KG49KHQubWF4LngtZi54KSpsLHM9KHQubWluLngtZi54KSpsKSxoPj0wPyhyPSh0Lm1pbi55LWYueSkqaCxvPSh0Lm1heC55LWYueSkqaCk6KHI9KHQubWF4LnktZi55KSpoLG89KHQubWluLnktZi55KSpoKSxuPm98fHI+c3x8KChyPm58fGlzTmFOKG4pKSYmKG49ciksKG88c3x8aXNOYU4ocykpJiYocz1vKSx1Pj0wPyhhPSh0Lm1pbi56LWYueikqdSxjPSh0Lm1heC56LWYueikqdSk6KGE9KHQubWF4LnotZi56KSp1LGM9KHQubWluLnotZi56KSp1KSxuPmN8fGE+cyl8fCgoYT5ufHxuIT09bikmJihuPWEpLChjPHN8fHMhPT1zKSYmKHM9YyksczwwKT9udWxsOnRoaXMuYXQobj49MD9uOnMsZSl9aW50ZXJzZWN0c0JveCh0KXtyZXR1cm4gdGhpcy5pbnRlcnNlY3RCb3godCx2ZSkhPT1udWxsfWludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHMscil7cm8uc3ViVmVjdG9ycyhlLHQpLGNzLnN1YlZlY3RvcnMobix0KSxvby5jcm9zc1ZlY3RvcnMocm8sY3MpO2xldCBvPXRoaXMuZGlyZWN0aW9uLmRvdChvbyksYTtpZihvPjApe2lmKHMpcmV0dXJuIG51bGw7YT0xfWVsc2UgaWYobzwwKWE9LTEsbz0tbztlbHNlIHJldHVybiBudWxsO0plLnN1YlZlY3RvcnModGhpcy5vcmlnaW4sdCk7Y29uc3QgYz1hKnRoaXMuZGlyZWN0aW9uLmRvdChjcy5jcm9zc1ZlY3RvcnMoSmUsY3MpKTtpZihjPDApcmV0dXJuIG51bGw7Y29uc3QgbD1hKnRoaXMuZGlyZWN0aW9uLmRvdChyby5jcm9zcyhKZSkpO2lmKGw8MHx8YytsPm8pcmV0dXJuIG51bGw7Y29uc3QgaD0tYSpKZS5kb3Qob28pO3JldHVybiBoPDA/bnVsbDp0aGlzLmF0KGgvbyxyKX1hcHBseU1hdHJpeDQodCl7cmV0dXJuIHRoaXMub3JpZ2luLmFwcGx5TWF0cml4NCh0KSx0aGlzLmRpcmVjdGlvbi50cmFuc2Zvcm1EaXJlY3Rpb24odCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQub3JpZ2luLmVxdWFscyh0aGlzLm9yaWdpbikmJnQuZGlyZWN0aW9uLmVxdWFscyh0aGlzLmRpcmVjdGlvbil9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfX1jbGFzcyBzdHtjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtzdC5wcm90b3R5cGUuaXNNYXRyaXg0PSEwLHRoaXMuZWxlbWVudHM9WzEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDFdLHQhPT12b2lkIDAmJnRoaXMuc2V0KHQsZSxuLHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG0pfXNldCh0LGUsbixzLHIsbyxhLGMsbCxoLHUsZixkLHAseSxtKXtjb25zdCBnPXRoaXMuZWxlbWVudHM7cmV0dXJuIGdbMF09dCxnWzRdPWUsZ1s4XT1uLGdbMTJdPXMsZ1sxXT1yLGdbNV09byxnWzldPWEsZ1sxM109YyxnWzJdPWwsZ1s2XT1oLGdbMTBdPXUsZ1sxNF09ZixnWzNdPWQsZ1s3XT1wLGdbMTFdPXksZ1sxNV09bSx0aGlzfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuc2V0KDEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDEpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHN0KCkuZnJvbUFycmF5KHRoaXMuZWxlbWVudHMpfWNvcHkodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cztyZXR1cm4gZVswXT1uWzBdLGVbMV09blsxXSxlWzJdPW5bMl0sZVszXT1uWzNdLGVbNF09bls0XSxlWzVdPW5bNV0sZVs2XT1uWzZdLGVbN109bls3XSxlWzhdPW5bOF0sZVs5XT1uWzldLGVbMTBdPW5bMTBdLGVbMTFdPW5bMTFdLGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLGVbMTVdPW5bMTVdLHRoaXN9Y29weVBvc2l0aW9uKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7cmV0dXJuIGVbMTJdPW5bMTJdLGVbMTNdPW5bMTNdLGVbMTRdPW5bMTRdLHRoaXN9c2V0RnJvbU1hdHJpeDModCl7Y29uc3QgZT10LmVsZW1lbnRzO3JldHVybiB0aGlzLnNldChlWzBdLGVbM10sZVs2XSwwLGVbMV0sZVs0XSxlWzddLDAsZVsyXSxlWzVdLGVbOF0sMCwwLDAsMCwxKSx0aGlzfWV4dHJhY3RCYXNpcyh0LGUsbil7cmV0dXJuIHQuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDApLGUuc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDEpLG4uc2V0RnJvbU1hdHJpeENvbHVtbih0aGlzLDIpLHRoaXN9bWFrZUJhc2lzKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodC54LGUueCxuLngsMCx0LnksZS55LG4ueSwwLHQueixlLnosbi56LDAsMCwwLDAsMSksdGhpc31leHRyYWN0Um90YXRpb24odCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC5lbGVtZW50cyxzPTEvTG4uc2V0RnJvbU1hdHJpeENvbHVtbih0LDApLmxlbmd0aCgpLHI9MS9Mbi5zZXRGcm9tTWF0cml4Q29sdW1uKHQsMSkubGVuZ3RoKCksbz0xL0xuLnNldEZyb21NYXRyaXhDb2x1bW4odCwyKS5sZW5ndGgoKTtyZXR1cm4gZVswXT1uWzBdKnMsZVsxXT1uWzFdKnMsZVsyXT1uWzJdKnMsZVszXT0wLGVbNF09bls0XSpyLGVbNV09bls1XSpyLGVbNl09bls2XSpyLGVbN109MCxlWzhdPW5bOF0qbyxlWzldPW5bOV0qbyxlWzEwXT1uWzEwXSpvLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21FdWxlcih0KXtjb25zdCBlPXRoaXMuZWxlbWVudHMsbj10Lngscz10Lnkscj10Lnosbz1NYXRoLmNvcyhuKSxhPU1hdGguc2luKG4pLGM9TWF0aC5jb3MocyksbD1NYXRoLnNpbihzKSxoPU1hdGguY29zKHIpLHU9TWF0aC5zaW4ocik7aWYodC5vcmRlcj09PSJYWVoiKXtjb25zdCBmPW8qaCxkPW8qdSxwPWEqaCx5PWEqdTtlWzBdPWMqaCxlWzRdPS1jKnUsZVs4XT1sLGVbMV09ZCtwKmwsZVs1XT1mLXkqbCxlWzldPS1hKmMsZVsyXT15LWYqbCxlWzZdPXArZCpsLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWVhaIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mK3kqYSxlWzRdPXAqYS1kLGVbOF09bypsLGVbMV09byp1LGVbNV09bypoLGVbOV09LWEsZVsyXT1kKmEtcCxlWzZdPXkrZiphLGVbMTBdPW8qY31lbHNlIGlmKHQub3JkZXI9PT0iWlhZIil7Y29uc3QgZj1jKmgsZD1jKnUscD1sKmgseT1sKnU7ZVswXT1mLXkqYSxlWzRdPS1vKnUsZVs4XT1wK2QqYSxlWzFdPWQrcCphLGVbNV09bypoLGVbOV09eS1mKmEsZVsyXT0tbypsLGVbNl09YSxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IlpZWCIpe2NvbnN0IGY9bypoLGQ9byp1LHA9YSpoLHk9YSp1O2VbMF09YypoLGVbNF09cCpsLWQsZVs4XT1mKmwreSxlWzFdPWMqdSxlWzVdPXkqbCtmLGVbOV09ZCpsLXAsZVsyXT0tbCxlWzZdPWEqYyxlWzEwXT1vKmN9ZWxzZSBpZih0Lm9yZGVyPT09IllaWCIpe2NvbnN0IGY9bypjLGQ9bypsLHA9YSpjLHk9YSpsO2VbMF09YypoLGVbNF09eS1mKnUsZVs4XT1wKnUrZCxlWzFdPXUsZVs1XT1vKmgsZVs5XT0tYSpoLGVbMl09LWwqaCxlWzZdPWQqdStwLGVbMTBdPWYteSp1fWVsc2UgaWYodC5vcmRlcj09PSJYWlkiKXtjb25zdCBmPW8qYyxkPW8qbCxwPWEqYyx5PWEqbDtlWzBdPWMqaCxlWzRdPS11LGVbOF09bCpoLGVbMV09Zip1K3ksZVs1XT1vKmgsZVs5XT1kKnUtcCxlWzJdPXAqdS1kLGVbNl09YSpoLGVbMTBdPXkqdStmfXJldHVybiBlWzNdPTAsZVs3XT0wLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSx0aGlzfW1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLmNvbXBvc2UoSnUsdCxZdSl9bG9va0F0KHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuICR0LnN1YlZlY3RvcnModCxlKSwkdC5sZW5ndGhTcSgpPT09MCYmKCR0Lno9MSksJHQubm9ybWFsaXplKCksWWUuY3Jvc3NWZWN0b3JzKG4sJHQpLFllLmxlbmd0aFNxKCk9PT0wJiYoTWF0aC5hYnMobi56KT09PTE/JHQueCs9MWUtNDokdC56Kz0xZS00LCR0Lm5vcm1hbGl6ZSgpLFllLmNyb3NzVmVjdG9ycyhuLCR0KSksWWUubm9ybWFsaXplKCksbHMuY3Jvc3NWZWN0b3JzKCR0LFllKSxzWzBdPVllLngsc1s0XT1scy54LHNbOF09JHQueCxzWzFdPVllLnksc1s1XT1scy55LHNbOV09JHQueSxzWzJdPVllLnosc1s2XT1scy56LHNbMTBdPSR0LnosdGhpc31tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKHRoaXMsdCl9cHJlbXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyh0LHRoaXMpfW11bHRpcGx5TWF0cmljZXModCxlKXtjb25zdCBuPXQuZWxlbWVudHMscz1lLmVsZW1lbnRzLHI9dGhpcy5lbGVtZW50cyxvPW5bMF0sYT1uWzRdLGM9bls4XSxsPW5bMTJdLGg9blsxXSx1PW5bNV0sZj1uWzldLGQ9blsxM10scD1uWzJdLHk9bls2XSxtPW5bMTBdLGc9blsxNF0sYj1uWzNdLHc9bls3XSx4PW5bMTFdLE09blsxNV0sQT1zWzBdLF89c1s0XSxTPXNbOF0sRT1zWzEyXSx6PXNbMV0sdj1zWzVdLEM9c1s5XSxQPXNbMTNdLEY9c1syXSxCPXNbNl0sST1zWzEwXSxrPXNbMTRdLEQ9c1szXSxWPXNbN10saj1zWzExXSxkdD1zWzE1XTtyZXR1cm4gclswXT1vKkErYSp6K2MqRitsKkQscls0XT1vKl8rYSp2K2MqQitsKlYscls4XT1vKlMrYSpDK2MqSStsKmosclsxMl09bypFK2EqUCtjKmsrbCpkdCxyWzFdPWgqQSt1KnorZipGK2QqRCxyWzVdPWgqXyt1KnYrZipCK2QqVixyWzldPWgqUyt1KkMrZipJK2QqaixyWzEzXT1oKkUrdSpQK2YqaytkKmR0LHJbMl09cCpBK3kqeittKkYrZypELHJbNl09cCpfK3kqdittKkIrZypWLHJbMTBdPXAqUyt5KkMrbSpJK2cqaixyWzE0XT1wKkUreSpQK20qaytnKmR0LHJbM109YipBK3cqeit4KkYrTSpELHJbN109YipfK3cqdit4KkIrTSpWLHJbMTFdPWIqUyt3KkMreCpJK00qaixyWzE1XT1iKkUrdypQK3gqaytNKmR0LHRoaXN9bXVsdGlwbHlTY2FsYXIodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzO3JldHVybiBlWzBdKj10LGVbNF0qPXQsZVs4XSo9dCxlWzEyXSo9dCxlWzFdKj10LGVbNV0qPXQsZVs5XSo9dCxlWzEzXSo9dCxlWzJdKj10LGVbNl0qPXQsZVsxMF0qPXQsZVsxNF0qPXQsZVszXSo9dCxlWzddKj10LGVbMTFdKj10LGVbMTVdKj10LHRoaXN9ZGV0ZXJtaW5hbnQoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdLG49dFs0XSxzPXRbOF0scj10WzEyXSxvPXRbMV0sYT10WzVdLGM9dFs5XSxsPXRbMTNdLGg9dFsyXSx1PXRbNl0sZj10WzEwXSxkPXRbMTRdLHA9dFszXSx5PXRbN10sbT10WzExXSxnPXRbMTVdO3JldHVybiBwKigrcipjKnUtcypsKnUtciphKmYrbipsKmYrcyphKmQtbipjKmQpK3kqKCtlKmMqZC1lKmwqZityKm8qZi1zKm8qZCtzKmwqaC1yKmMqaCkrbSooK2UqbCp1LWUqYSpkLXIqbyp1K24qbypkK3IqYSpoLW4qbCpoKStnKigtcyphKmgtZSpjKnUrZSphKmYrcypvKnUtbipvKmYrbipjKmgpfXRyYW5zcG9zZSgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cztsZXQgZTtyZXR1cm4gZT10WzFdLHRbMV09dFs0XSx0WzRdPWUsZT10WzJdLHRbMl09dFs4XSx0WzhdPWUsZT10WzZdLHRbNl09dFs5XSx0WzldPWUsZT10WzNdLHRbM109dFsxMl0sdFsxMl09ZSxlPXRbN10sdFs3XT10WzEzXSx0WzEzXT1lLGU9dFsxMV0sdFsxMV09dFsxNF0sdFsxNF09ZSx0aGlzfXNldFBvc2l0aW9uKHQsZSxuKXtjb25zdCBzPXRoaXMuZWxlbWVudHM7cmV0dXJuIHQuaXNWZWN0b3IzPyhzWzEyXT10Lngsc1sxM109dC55LHNbMTRdPXQueik6KHNbMTJdPXQsc1sxM109ZSxzWzE0XT1uKSx0aGlzfWludmVydCgpe2NvbnN0IHQ9dGhpcy5lbGVtZW50cyxlPXRbMF0sbj10WzFdLHM9dFsyXSxyPXRbM10sbz10WzRdLGE9dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSx1PXRbOV0sZj10WzEwXSxkPXRbMTFdLHA9dFsxMl0seT10WzEzXSxtPXRbMTRdLGc9dFsxNV0sYj11Km0qbC15KmYqbCt5KmMqZC1hKm0qZC11KmMqZythKmYqZyx3PXAqZipsLWgqbSpsLXAqYypkK28qbSpkK2gqYypnLW8qZipnLHg9aCp5KmwtcCp1KmwrcCphKmQtbyp5KmQtaCphKmcrbyp1KmcsTT1wKnUqYy1oKnkqYy1wKmEqZitvKnkqZitoKmEqbS1vKnUqbSxBPWUqYituKncrcyp4K3IqTTtpZihBPT09MClyZXR1cm4gdGhpcy5zZXQoMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCk7Y29uc3QgXz0xL0E7cmV0dXJuIHRbMF09YipfLHRbMV09KHkqZipyLXUqbSpyLXkqcypkK24qbSpkK3UqcypnLW4qZipnKSpfLHRbMl09KGEqbSpyLXkqYypyK3kqcypsLW4qbSpsLWEqcypnK24qYypnKSpfLHRbM109KHUqYypyLWEqZipyLXUqcypsK24qZipsK2EqcypkLW4qYypkKSpfLHRbNF09dypfLHRbNV09KGgqbSpyLXAqZipyK3AqcypkLWUqbSpkLWgqcypnK2UqZipnKSpfLHRbNl09KHAqYypyLW8qbSpyLXAqcypsK2UqbSpsK28qcypnLWUqYypnKSpfLHRbN109KG8qZipyLWgqYypyK2gqcypsLWUqZipsLW8qcypkK2UqYypkKSpfLHRbOF09eCpfLHRbOV09KHAqdSpyLWgqeSpyLXAqbipkK2UqeSpkK2gqbipnLWUqdSpnKSpfLHRbMTBdPShvKnkqci1wKmEqcitwKm4qbC1lKnkqbC1vKm4qZytlKmEqZykqXyx0WzExXT0oaCphKnItbyp1KnItaCpuKmwrZSp1KmwrbypuKmQtZSphKmQpKl8sdFsxMl09TSpfLHRbMTNdPShoKnkqcy1wKnUqcytwKm4qZi1lKnkqZi1oKm4qbStlKnUqbSkqXyx0WzE0XT0ocCphKnMtbyp5KnMtcCpuKmMrZSp5KmMrbypuKm0tZSphKm0pKl8sdFsxNV09KG8qdSpzLWgqYSpzK2gqbipjLWUqdSpjLW8qbipmK2UqYSpmKSpfLHRoaXN9c2NhbGUodCl7Y29uc3QgZT10aGlzLmVsZW1lbnRzLG49dC54LHM9dC55LHI9dC56O3JldHVybiBlWzBdKj1uLGVbNF0qPXMsZVs4XSo9cixlWzFdKj1uLGVbNV0qPXMsZVs5XSo9cixlWzJdKj1uLGVbNl0qPXMsZVsxMF0qPXIsZVszXSo9bixlWzddKj1zLGVbMTFdKj1yLHRoaXN9Z2V0TWF4U2NhbGVPbkF4aXMoKXtjb25zdCB0PXRoaXMuZWxlbWVudHMsZT10WzBdKnRbMF0rdFsxXSp0WzFdK3RbMl0qdFsyXSxuPXRbNF0qdFs0XSt0WzVdKnRbNV0rdFs2XSp0WzZdLHM9dFs4XSp0WzhdK3RbOV0qdFs5XSt0WzEwXSp0WzEwXTtyZXR1cm4gTWF0aC5zcXJ0KE1hdGgubWF4KGUsbixzKSl9bWFrZVRyYW5zbGF0aW9uKHQsZSxuKXtyZXR1cm4gdC5pc1ZlY3RvcjM/dGhpcy5zZXQoMSwwLDAsdC54LDAsMSwwLHQueSwwLDAsMSx0LnosMCwwLDAsMSk6dGhpcy5zZXQoMSwwLDAsdCwwLDEsMCxlLDAsMCwxLG4sMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25YKHQpe2NvbnN0IGU9TWF0aC5jb3ModCksbj1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy5zZXQoMSwwLDAsMCwwLGUsLW4sMCwwLG4sZSwwLDAsMCwwLDEpLHRoaXN9bWFrZVJvdGF0aW9uWSh0KXtjb25zdCBlPU1hdGguY29zKHQpLG49TWF0aC5zaW4odCk7cmV0dXJuIHRoaXMuc2V0KGUsMCxuLDAsMCwxLDAsMCwtbiwwLGUsMCwwLDAsMCwxKSx0aGlzfW1ha2VSb3RhdGlvbloodCl7Y29uc3QgZT1NYXRoLmNvcyh0KSxuPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnNldChlLC1uLDAsMCxuLGUsMCwwLDAsMCwxLDAsMCwwLDAsMSksdGhpc31tYWtlUm90YXRpb25BeGlzKHQsZSl7Y29uc3Qgbj1NYXRoLmNvcyhlKSxzPU1hdGguc2luKGUpLHI9MS1uLG89dC54LGE9dC55LGM9dC56LGw9cipvLGg9ciphO3JldHVybiB0aGlzLnNldChsKm8rbixsKmEtcypjLGwqYytzKmEsMCxsKmErcypjLGgqYStuLGgqYy1zKm8sMCxsKmMtcyphLGgqYytzKm8scipjKmMrbiwwLDAsMCwwLDEpLHRoaXN9bWFrZVNjYWxlKHQsZSxuKXtyZXR1cm4gdGhpcy5zZXQodCwwLDAsMCwwLGUsMCwwLDAsMCxuLDAsMCwwLDAsMSksdGhpc31tYWtlU2hlYXIodCxlLG4scyxyLG8pe3JldHVybiB0aGlzLnNldCgxLG4sciwwLHQsMSxvLDAsZSxzLDEsMCwwLDAsMCwxKSx0aGlzfWNvbXBvc2UodCxlLG4pe2NvbnN0IHM9dGhpcy5lbGVtZW50cyxyPWUuX3gsbz1lLl95LGE9ZS5feixjPWUuX3csbD1yK3IsaD1vK28sdT1hK2EsZj1yKmwsZD1yKmgscD1yKnUseT1vKmgsbT1vKnUsZz1hKnUsYj1jKmwsdz1jKmgseD1jKnUsTT1uLngsQT1uLnksXz1uLno7cmV0dXJuIHNbMF09KDEtKHkrZykpKk0sc1sxXT0oZCt4KSpNLHNbMl09KHAtdykqTSxzWzNdPTAsc1s0XT0oZC14KSpBLHNbNV09KDEtKGYrZykpKkEsc1s2XT0obStiKSpBLHNbN109MCxzWzhdPShwK3cpKl8sc1s5XT0obS1iKSpfLHNbMTBdPSgxLShmK3kpKSpfLHNbMTFdPTAsc1sxMl09dC54LHNbMTNdPXQueSxzWzE0XT10Lnosc1sxNV09MSx0aGlzfWRlY29tcG9zZSh0LGUsbil7Y29uc3Qgcz10aGlzLmVsZW1lbnRzO2xldCByPUxuLnNldChzWzBdLHNbMV0sc1syXSkubGVuZ3RoKCk7Y29uc3Qgbz1Mbi5zZXQoc1s0XSxzWzVdLHNbNl0pLmxlbmd0aCgpLGE9TG4uc2V0KHNbOF0sc1s5XSxzWzEwXSkubGVuZ3RoKCk7dGhpcy5kZXRlcm1pbmFudCgpPDAmJihyPS1yKSx0Lng9c1sxMl0sdC55PXNbMTNdLHQuej1zWzE0XSxsZS5jb3B5KHRoaXMpO2NvbnN0IGw9MS9yLGg9MS9vLHU9MS9hO3JldHVybiBsZS5lbGVtZW50c1swXSo9bCxsZS5lbGVtZW50c1sxXSo9bCxsZS5lbGVtZW50c1syXSo9bCxsZS5lbGVtZW50c1s0XSo9aCxsZS5lbGVtZW50c1s1XSo9aCxsZS5lbGVtZW50c1s2XSo9aCxsZS5lbGVtZW50c1s4XSo9dSxsZS5lbGVtZW50c1s5XSo9dSxsZS5lbGVtZW50c1sxMF0qPXUsZS5zZXRGcm9tUm90YXRpb25NYXRyaXgobGUpLG4ueD1yLG4ueT1vLG4uej1hLHRoaXN9bWFrZVBlcnNwZWN0aXZlKHQsZSxuLHMscixvLGE9MmUzKXtjb25zdCBjPXRoaXMuZWxlbWVudHMsbD0yKnIvKGUtdCksaD0yKnIvKG4tcyksdT0oZSt0KS8oZS10KSxmPShuK3MpLyhuLXMpO2xldCBkLHA7aWYoYT09PTJlMylkPS0obytyKS8oby1yKSxwPS0yKm8qci8oby1yKTtlbHNlIGlmKGE9PT0yMDAxKWQ9LW8vKG8tcikscD0tbypyLyhvLXIpO2Vsc2UgdGhyb3cgbmV3IEVycm9yKCJUSFJFRS5NYXRyaXg0Lm1ha2VQZXJzcGVjdGl2ZSgpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPWwsY1s0XT0wLGNbOF09dSxjWzEyXT0wLGNbMV09MCxjWzVdPWgsY1s5XT1mLGNbMTNdPTAsY1syXT0wLGNbNl09MCxjWzEwXT1kLGNbMTRdPXAsY1szXT0wLGNbN109MCxjWzExXT0tMSxjWzE1XT0wLHRoaXN9bWFrZU9ydGhvZ3JhcGhpYyh0LGUsbixzLHIsbyxhPTJlMyl7Y29uc3QgYz10aGlzLmVsZW1lbnRzLGw9MS8oZS10KSxoPTEvKG4tcyksdT0xLyhvLXIpLGY9KGUrdCkqbCxkPShuK3MpKmg7bGV0IHAseTtpZihhPT09MmUzKXA9KG8rcikqdSx5PS0yKnU7ZWxzZSBpZihhPT09MjAwMSlwPXIqdSx5PS0xKnU7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIlRIUkVFLk1hdHJpeDQubWFrZU9ydGhvZ3JhcGhpYygpOiBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtOiAiK2EpO3JldHVybiBjWzBdPTIqbCxjWzRdPTAsY1s4XT0wLGNbMTJdPS1mLGNbMV09MCxjWzVdPTIqaCxjWzldPTAsY1sxM109LWQsY1syXT0wLGNbNl09MCxjWzEwXT15LGNbMTRdPS1wLGNbM109MCxjWzddPTAsY1sxMV09MCxjWzE1XT0xLHRoaXN9ZXF1YWxzKHQpe2NvbnN0IGU9dGhpcy5lbGVtZW50cyxuPXQuZWxlbWVudHM7Zm9yKGxldCBzPTA7czwxNjtzKyspaWYoZVtzXSE9PW5bc10pcmV0dXJuITE7cmV0dXJuITB9ZnJvbUFycmF5KHQsZT0wKXtmb3IobGV0IG49MDtuPDE2O24rKyl0aGlzLmVsZW1lbnRzW25dPXRbbitlXTtyZXR1cm4gdGhpc310b0FycmF5KHQ9W10sZT0wKXtjb25zdCBuPXRoaXMuZWxlbWVudHM7cmV0dXJuIHRbZV09blswXSx0W2UrMV09blsxXSx0W2UrMl09blsyXSx0W2UrM109blszXSx0W2UrNF09bls0XSx0W2UrNV09bls1XSx0W2UrNl09bls2XSx0W2UrN109bls3XSx0W2UrOF09bls4XSx0W2UrOV09bls5XSx0W2UrMTBdPW5bMTBdLHRbZSsxMV09blsxMV0sdFtlKzEyXT1uWzEyXSx0W2UrMTNdPW5bMTNdLHRbZSsxNF09blsxNF0sdFtlKzE1XT1uWzE1XSx0fX1jb25zdCBMbj1uZXcgVCxsZT1uZXcgc3QsSnU9bmV3IFQoMCwwLDApLFl1PW5ldyBUKDEsMSwxKSxZZT1uZXcgVCxscz1uZXcgVCwkdD1uZXcgVCx3Yz1uZXcgc3QsYmM9bmV3IHlpO2NsYXNzIHhpe2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0wLHM9eGkuREVGQVVMVF9PUkRFUil7dGhpcy5pc0V1bGVyPSEwLHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXN9Z2V0IHgoKXtyZXR1cm4gdGhpcy5feH1zZXQgeCh0KXt0aGlzLl94PXQsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpfWdldCB5KCl7cmV0dXJuIHRoaXMuX3l9c2V0IHkodCl7dGhpcy5feT10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1nZXQgeigpe3JldHVybiB0aGlzLl96fXNldCB6KHQpe3RoaXMuX3o9dCx0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKCl9Z2V0IG9yZGVyKCl7cmV0dXJuIHRoaXMuX29yZGVyfXNldCBvcmRlcih0KXt0aGlzLl9vcmRlcj10LHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKX1zZXQodCxlLG4scz10aGlzLl9vcmRlcil7cmV0dXJuIHRoaXMuX3g9dCx0aGlzLl95PWUsdGhpcy5fej1uLHRoaXMuX29yZGVyPXMsdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5feCx0aGlzLl95LHRoaXMuX3osdGhpcy5fb3JkZXIpfWNvcHkodCl7cmV0dXJuIHRoaXMuX3g9dC5feCx0aGlzLl95PXQuX3ksdGhpcy5fej10Ll96LHRoaXMuX29yZGVyPXQuX29yZGVyLHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21Sb3RhdGlvbk1hdHJpeCh0LGU9dGhpcy5fb3JkZXIsbj0hMCl7Y29uc3Qgcz10LmVsZW1lbnRzLHI9c1swXSxvPXNbNF0sYT1zWzhdLGM9c1sxXSxsPXNbNV0saD1zWzldLHU9c1syXSxmPXNbNl0sZD1zWzEwXTtzd2l0Y2goZSl7Y2FzZSJYWVoiOnRoaXMuX3k9TWF0aC5hc2luKFooYSwtMSwxKSksTWF0aC5hYnMoYSk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMigtaCxkKSx0aGlzLl96PU1hdGguYXRhbjIoLW8scikpOih0aGlzLl94PU1hdGguYXRhbjIoZixsKSx0aGlzLl96PTApO2JyZWFrO2Nhc2UiWVhaIjp0aGlzLl94PU1hdGguYXNpbigtWihoLC0xLDEpKSxNYXRoLmFicyhoKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKGEsZCksdGhpcy5fej1NYXRoLmF0YW4yKGMsbCkpOih0aGlzLl95PU1hdGguYXRhbjIoLXUsciksdGhpcy5fej0wKTticmVhaztjYXNlIlpYWSI6dGhpcy5feD1NYXRoLmFzaW4oWihmLC0xLDEpKSxNYXRoLmFicyhmKTwuOTk5OTk5OT8odGhpcy5feT1NYXRoLmF0YW4yKC11LGQpLHRoaXMuX3o9TWF0aC5hdGFuMigtbyxsKSk6KHRoaXMuX3k9MCx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk7YnJlYWs7Y2FzZSJaWVgiOnRoaXMuX3k9TWF0aC5hc2luKC1aKHUsLTEsMSkpLE1hdGguYWJzKHUpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoZixkKSx0aGlzLl96PU1hdGguYXRhbjIoYyxyKSk6KHRoaXMuX3g9MCx0aGlzLl96PU1hdGguYXRhbjIoLW8sbCkpO2JyZWFrO2Nhc2UiWVpYIjp0aGlzLl96PU1hdGguYXNpbihaKGMsLTEsMSkpLE1hdGguYWJzKGMpPC45OTk5OTk5Pyh0aGlzLl94PU1hdGguYXRhbjIoLWgsbCksdGhpcy5feT1NYXRoLmF0YW4yKC11LHIpKToodGhpcy5feD0wLHRoaXMuX3k9TWF0aC5hdGFuMihhLGQpKTticmVhaztjYXNlIlhaWSI6dGhpcy5fej1NYXRoLmFzaW4oLVoobywtMSwxKSksTWF0aC5hYnMobyk8Ljk5OTk5OTk/KHRoaXMuX3g9TWF0aC5hdGFuMihmLGwpLHRoaXMuX3k9TWF0aC5hdGFuMihhLHIpKToodGhpcy5feD1NYXRoLmF0YW4yKC1oLGQpLHRoaXMuX3k9MCk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkV1bGVyOiAuc2V0RnJvbVJvdGF0aW9uTWF0cml4KCkgZW5jb3VudGVyZWQgYW4gdW5rbm93biBvcmRlcjogIitlKX1yZXR1cm4gdGhpcy5fb3JkZXI9ZSxuPT09ITAmJnRoaXMuX29uQ2hhbmdlQ2FsbGJhY2soKSx0aGlzfXNldEZyb21RdWF0ZXJuaW9uKHQsZSxuKXtyZXR1cm4gd2MubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24odCksdGhpcy5zZXRGcm9tUm90YXRpb25NYXRyaXgod2MsZSxuKX1zZXRGcm9tVmVjdG9yMyh0LGU9dGhpcy5fb3JkZXIpe3JldHVybiB0aGlzLnNldCh0LngsdC55LHQueixlKX1yZW9yZGVyKHQpe3JldHVybiBiYy5zZXRGcm9tRXVsZXIodGhpcyksdGhpcy5zZXRGcm9tUXVhdGVybmlvbihiYyx0KX1lcXVhbHModCl7cmV0dXJuIHQuX3g9PT10aGlzLl94JiZ0Ll95PT09dGhpcy5feSYmdC5fej09PXRoaXMuX3omJnQuX29yZGVyPT09dGhpcy5fb3JkZXJ9ZnJvbUFycmF5KHQpe3JldHVybiB0aGlzLl94PXRbMF0sdGhpcy5feT10WzFdLHRoaXMuX3o9dFsyXSx0WzNdIT09dm9pZCAwJiYodGhpcy5fb3JkZXI9dFszXSksdGhpcy5fb25DaGFuZ2VDYWxsYmFjaygpLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy5feCx0W2UrMV09dGhpcy5feSx0W2UrMl09dGhpcy5feix0W2UrM109dGhpcy5fb3JkZXIsdH1fb25DaGFuZ2UodCl7cmV0dXJuIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2s9dCx0aGlzfV9vbkNoYW5nZUNhbGxiYWNrKCl7fSpbU3ltYm9sLml0ZXJhdG9yXSgpe3lpZWxkIHRoaXMuX3gseWllbGQgdGhpcy5feSx5aWVsZCB0aGlzLl96LHlpZWxkIHRoaXMuX29yZGVyfX14aS5ERUZBVUxUX09SREVSPSJYWVoiO2NsYXNzIGp1e2NvbnN0cnVjdG9yKCl7dGhpcy5tYXNrPTF9c2V0KHQpe3RoaXMubWFzaz0oMTw8dHwwKT4+PjB9ZW5hYmxlKHQpe3RoaXMubWFza3w9MTw8dHwwfWVuYWJsZUFsbCgpe3RoaXMubWFzaz0tMX10b2dnbGUodCl7dGhpcy5tYXNrXj0xPDx0fDB9ZGlzYWJsZSh0KXt0aGlzLm1hc2smPX4oMTw8dHwwKX1kaXNhYmxlQWxsKCl7dGhpcy5tYXNrPTB9dGVzdCh0KXtyZXR1cm4odGhpcy5tYXNrJnQubWFzaykhPT0wfWlzRW5hYmxlZCh0KXtyZXR1cm4odGhpcy5tYXNrJigxPDx0fDApKSE9PTB9fWxldCBRdT0wO2NvbnN0IE1jPW5ldyBULE9uPW5ldyB5aSx6ZT1uZXcgc3QsaHM9bmV3IFQsd2k9bmV3IFQsS3U9bmV3IFQsdGY9bmV3IHlpLEFjPW5ldyBUKDEsMCwwKSxfYz1uZXcgVCgwLDEsMCksU2M9bmV3IFQoMCwwLDEpLHZjPXt0eXBlOiJhZGRlZCJ9LGVmPXt0eXBlOiJyZW1vdmVkIn0sRG49e3R5cGU6ImNoaWxkYWRkZWQiLGNoaWxkOm51bGx9LGNvPXt0eXBlOiJjaGlsZHJlbW92ZWQiLGNoaWxkOm51bGx9O2NsYXNzIFRlIGV4dGVuZHMgaXN7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNPYmplY3QzRD0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpRdSsrfSksdGhpcy51dWlkPUJuKCksdGhpcy5uYW1lPSIiLHRoaXMudHlwZT0iT2JqZWN0M0QiLHRoaXMucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbj1bXSx0aGlzLnVwPVRlLkRFRkFVTFRfVVAuY2xvbmUoKTtjb25zdCB0PW5ldyBULGU9bmV3IHhpLG49bmV3IHlpLHM9bmV3IFQoMSwxLDEpO2Z1bmN0aW9uIHIoKXtuLnNldEZyb21FdWxlcihlLCExKX1mdW5jdGlvbiBvKCl7ZS5zZXRGcm9tUXVhdGVybmlvbihuLHZvaWQgMCwhMSl9ZS5fb25DaGFuZ2Uociksbi5fb25DaGFuZ2UobyksT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcyx7cG9zaXRpb246e2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiEwLHZhbHVlOnR9LHJvdGF0aW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTplfSxxdWF0ZXJuaW9uOntjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx2YWx1ZTpufSxzY2FsZTp7Y29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITAsdmFsdWU6c30sbW9kZWxWaWV3TWF0cml4Ont2YWx1ZTpuZXcgc3R9LG5vcm1hbE1hdHJpeDp7dmFsdWU6bmV3IGdlfX0pLHRoaXMubWF0cml4PW5ldyBzdCx0aGlzLm1hdHJpeFdvcmxkPW5ldyBzdCx0aGlzLm1hdHJpeEF1dG9VcGRhdGU9VGUuREVGQVVMVF9NQVRSSVhfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9VGUuREVGQVVMVF9NQVRSSVhfV09STERfQVVUT19VUERBVEUsdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSExLHRoaXMubGF5ZXJzPW5ldyBqdSx0aGlzLnZpc2libGU9ITAsdGhpcy5jYXN0U2hhZG93PSExLHRoaXMucmVjZWl2ZVNoYWRvdz0hMSx0aGlzLmZydXN0dW1DdWxsZWQ9ITAsdGhpcy5yZW5kZXJPcmRlcj0wLHRoaXMuYW5pbWF0aW9ucz1bXSx0aGlzLmN1c3RvbURlcHRoTWF0ZXJpYWw9dm9pZCAwLHRoaXMuY3VzdG9tRGlzdGFuY2VNYXRlcmlhbD12b2lkIDAsdGhpcy51c2VyRGF0YT17fX1vbkJlZm9yZVNoYWRvdygpe31vbkFmdGVyU2hhZG93KCl7fW9uQmVmb3JlUmVuZGVyKCl7fW9uQWZ0ZXJSZW5kZXIoKXt9YXBwbHlNYXRyaXg0KHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSx0aGlzLm1hdHJpeC5wcmVtdWx0aXBseSh0KSx0aGlzLm1hdHJpeC5kZWNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSl9YXBwbHlRdWF0ZXJuaW9uKHQpe3JldHVybiB0aGlzLnF1YXRlcm5pb24ucHJlbXVsdGlwbHkodCksdGhpc31zZXRSb3RhdGlvbkZyb21BeGlzQW5nbGUodCxlKXt0aGlzLnF1YXRlcm5pb24uc2V0RnJvbUF4aXNBbmdsZSh0LGUpfXNldFJvdGF0aW9uRnJvbUV1bGVyKHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tRXVsZXIodCwhMCl9c2V0Um90YXRpb25Gcm9tTWF0cml4KHQpe3RoaXMucXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgodCl9c2V0Um90YXRpb25Gcm9tUXVhdGVybmlvbih0KXt0aGlzLnF1YXRlcm5pb24uY29weSh0KX1yb3RhdGVPbkF4aXModCxlKXtyZXR1cm4gT24uc2V0RnJvbUF4aXNBbmdsZSh0LGUpLHRoaXMucXVhdGVybmlvbi5tdWx0aXBseShPbiksdGhpc31yb3RhdGVPbldvcmxkQXhpcyh0LGUpe3JldHVybiBPbi5zZXRGcm9tQXhpc0FuZ2xlKHQsZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KE9uKSx0aGlzfXJvdGF0ZVgodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKEFjLHQpfXJvdGF0ZVkodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKF9jLHQpfXJvdGF0ZVoodCl7cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKFNjLHQpfXRyYW5zbGF0ZU9uQXhpcyh0LGUpe3JldHVybiBNYy5jb3B5KHQpLmFwcGx5UXVhdGVybmlvbih0aGlzLnF1YXRlcm5pb24pLHRoaXMucG9zaXRpb24uYWRkKE1jLm11bHRpcGx5U2NhbGFyKGUpKSx0aGlzfXRyYW5zbGF0ZVgodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKEFjLHQpfXRyYW5zbGF0ZVkodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKF9jLHQpfXRyYW5zbGF0ZVoodCl7cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKFNjLHQpfWxvY2FsVG9Xb3JsZCh0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdC5hcHBseU1hdHJpeDQodGhpcy5tYXRyaXhXb3JsZCl9d29ybGRUb0xvY2FsKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0LmFwcGx5TWF0cml4NCh6ZS5jb3B5KHRoaXMubWF0cml4V29ybGQpLmludmVydCgpKX1sb29rQXQodCxlLG4pe3QuaXNWZWN0b3IzP2hzLmNvcHkodCk6aHMuc2V0KHQsZSxuKTtjb25zdCBzPXRoaXMucGFyZW50O3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHdpLnNldEZyb21NYXRyaXhQb3NpdGlvbih0aGlzLm1hdHJpeFdvcmxkKSx0aGlzLmlzQ2FtZXJhfHx0aGlzLmlzTGlnaHQ/emUubG9va0F0KHdpLGhzLHRoaXMudXApOnplLmxvb2tBdChocyx3aSx0aGlzLnVwKSx0aGlzLnF1YXRlcm5pb24uc2V0RnJvbVJvdGF0aW9uTWF0cml4KHplKSxzJiYoemUuZXh0cmFjdFJvdGF0aW9uKHMubWF0cml4V29ybGQpLE9uLnNldEZyb21Sb3RhdGlvbk1hdHJpeCh6ZSksdGhpcy5xdWF0ZXJuaW9uLnByZW11bHRpcGx5KE9uLmludmVydCgpKSl9YWRkKHQpe2lmKGFyZ3VtZW50cy5sZW5ndGg+MSl7Zm9yKGxldCBlPTA7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl0aGlzLmFkZChhcmd1bWVudHNbZV0pO3JldHVybiB0aGlzfXJldHVybiB0PT09dGhpcz8oY29uc29sZS5lcnJvcigiVEhSRUUuT2JqZWN0M0QuYWRkOiBvYmplY3QgY2FuJ3QgYmUgYWRkZWQgYXMgYSBjaGlsZCBvZiBpdHNlbGYuIix0KSx0aGlzKToodCYmdC5pc09iamVjdDNEPyh0LnJlbW92ZUZyb21QYXJlbnQoKSx0LnBhcmVudD10aGlzLHRoaXMuY2hpbGRyZW4ucHVzaCh0KSx0LmRpc3BhdGNoRXZlbnQodmMpLERuLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KERuKSxEbi5jaGlsZD1udWxsKTpjb25zb2xlLmVycm9yKCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBub3QgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuT2JqZWN0M0QuIix0KSx0aGlzKX1yZW1vdmUodCl7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IobGV0IG49MDtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXRoaXMucmVtb3ZlKGFyZ3VtZW50c1tuXSk7cmV0dXJuIHRoaXN9Y29uc3QgZT10aGlzLmNoaWxkcmVuLmluZGV4T2YodCk7cmV0dXJuIGUhPT0tMSYmKHQucGFyZW50PW51bGwsdGhpcy5jaGlsZHJlbi5zcGxpY2UoZSwxKSx0LmRpc3BhdGNoRXZlbnQoZWYpLGNvLmNoaWxkPXQsdGhpcy5kaXNwYXRjaEV2ZW50KGNvKSxjby5jaGlsZD1udWxsKSx0aGlzfXJlbW92ZUZyb21QYXJlbnQoKXtjb25zdCB0PXRoaXMucGFyZW50O3JldHVybiB0IT09bnVsbCYmdC5yZW1vdmUodGhpcyksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLnJlbW92ZSguLi50aGlzLmNoaWxkcmVuKX1hdHRhY2godCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHplLmNvcHkodGhpcy5tYXRyaXhXb3JsZCkuaW52ZXJ0KCksdC5wYXJlbnQhPT1udWxsJiYodC5wYXJlbnQudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHplLm11bHRpcGx5KHQucGFyZW50Lm1hdHJpeFdvcmxkKSksdC5hcHBseU1hdHJpeDQoemUpLHQucmVtb3ZlRnJvbVBhcmVudCgpLHQucGFyZW50PXRoaXMsdGhpcy5jaGlsZHJlbi5wdXNoKHQpLHQudXBkYXRlV29ybGRNYXRyaXgoITEsITApLHQuZGlzcGF0Y2hFdmVudCh2YyksRG4uY2hpbGQ9dCx0aGlzLmRpc3BhdGNoRXZlbnQoRG4pLERuLmNoaWxkPW51bGwsdGhpc31nZXRPYmplY3RCeUlkKHQpe3JldHVybiB0aGlzLmdldE9iamVjdEJ5UHJvcGVydHkoImlkIix0KX1nZXRPYmplY3RCeU5hbWUodCl7cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlQcm9wZXJ0eSgibmFtZSIsdCl9Z2V0T2JqZWN0QnlQcm9wZXJ0eSh0LGUpe2lmKHRoaXNbdF09PT1lKXJldHVybiB0aGlzO2ZvcihsZXQgbj0wLHM9dGhpcy5jaGlsZHJlbi5sZW5ndGg7bjxzO24rKyl7Y29uc3Qgbz10aGlzLmNoaWxkcmVuW25dLmdldE9iamVjdEJ5UHJvcGVydHkodCxlKTtpZihvIT09dm9pZCAwKXJldHVybiBvfX1nZXRPYmplY3RzQnlQcm9wZXJ0eSh0LGUsbj1bXSl7dGhpc1t0XT09PWUmJm4ucHVzaCh0aGlzKTtjb25zdCBzPXRoaXMuY2hpbGRyZW47Zm9yKGxldCByPTAsbz1zLmxlbmd0aDtyPG87cisrKXNbcl0uZ2V0T2JqZWN0c0J5UHJvcGVydHkodCxlLG4pO3JldHVybiBufWdldFdvcmxkUG9zaXRpb24odCl7cmV0dXJuIHRoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpLHQuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKHRoaXMubWF0cml4V29ybGQpfWdldFdvcmxkUXVhdGVybmlvbih0KXtyZXR1cm4gdGhpcy51cGRhdGVXb3JsZE1hdHJpeCghMCwhMSksdGhpcy5tYXRyaXhXb3JsZC5kZWNvbXBvc2Uod2ksdCxLdSksdH1nZXRXb3JsZFNjYWxlKHQpe3JldHVybiB0aGlzLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZSh3aSx0Zix0KSx0fWdldFdvcmxkRGlyZWN0aW9uKHQpe3RoaXMudXBkYXRlV29ybGRNYXRyaXgoITAsITEpO2NvbnN0IGU9dGhpcy5tYXRyaXhXb3JsZC5lbGVtZW50cztyZXR1cm4gdC5zZXQoZVs4XSxlWzldLGVbMTBdKS5ub3JtYWxpemUoKX1yYXljYXN0KCl7fXRyYXZlcnNlKHQpe3QodGhpcyk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnRyYXZlcnNlKHQpfXRyYXZlcnNlVmlzaWJsZSh0KXtpZih0aGlzLnZpc2libGU9PT0hMSlyZXR1cm47dCh0aGlzKTtjb25zdCBlPXRoaXMuY2hpbGRyZW47Zm9yKGxldCBuPTAscz1lLmxlbmd0aDtuPHM7bisrKWVbbl0udHJhdmVyc2VWaXNpYmxlKHQpfXRyYXZlcnNlQW5jZXN0b3JzKHQpe2NvbnN0IGU9dGhpcy5wYXJlbnQ7ZSE9PW51bGwmJih0KGUpLGUudHJhdmVyc2VBbmNlc3RvcnModCkpfXVwZGF0ZU1hdHJpeCgpe3RoaXMubWF0cml4LmNvbXBvc2UodGhpcy5wb3NpdGlvbix0aGlzLnF1YXRlcm5pb24sdGhpcy5zY2FsZSksdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlPSEwfXVwZGF0ZU1hdHJpeFdvcmxkKHQpe3RoaXMubWF0cml4QXV0b1VwZGF0ZSYmdGhpcy51cGRhdGVNYXRyaXgoKSwodGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlfHx0KSYmKHRoaXMubWF0cml4V29ybGRBdXRvVXBkYXRlPT09ITAmJih0aGlzLnBhcmVudD09PW51bGw/dGhpcy5tYXRyaXhXb3JsZC5jb3B5KHRoaXMubWF0cml4KTp0aGlzLm1hdHJpeFdvcmxkLm11bHRpcGx5TWF0cmljZXModGhpcy5wYXJlbnQubWF0cml4V29ybGQsdGhpcy5tYXRyaXgpKSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9ITEsdD0hMCk7Y29uc3QgZT10aGlzLmNoaWxkcmVuO2ZvcihsZXQgbj0wLHM9ZS5sZW5ndGg7bjxzO24rKyllW25dLnVwZGF0ZU1hdHJpeFdvcmxkKHQpfXVwZGF0ZVdvcmxkTWF0cml4KHQsZSl7Y29uc3Qgbj10aGlzLnBhcmVudDtpZih0PT09ITAmJm4hPT1udWxsJiZuLnVwZGF0ZVdvcmxkTWF0cml4KCEwLCExKSx0aGlzLm1hdHJpeEF1dG9VcGRhdGUmJnRoaXMudXBkYXRlTWF0cml4KCksdGhpcy5tYXRyaXhXb3JsZEF1dG9VcGRhdGU9PT0hMCYmKHRoaXMucGFyZW50PT09bnVsbD90aGlzLm1hdHJpeFdvcmxkLmNvcHkodGhpcy5tYXRyaXgpOnRoaXMubWF0cml4V29ybGQubXVsdGlwbHlNYXRyaWNlcyh0aGlzLnBhcmVudC5tYXRyaXhXb3JsZCx0aGlzLm1hdHJpeCkpLGU9PT0hMCl7Y29uc3Qgcz10aGlzLmNoaWxkcmVuO2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKylzW3JdLnVwZGF0ZVdvcmxkTWF0cml4KCExLCEwKX19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciLG49e307ZSYmKHQ9e2dlb21ldHJpZXM6e30sbWF0ZXJpYWxzOnt9LHRleHR1cmVzOnt9LGltYWdlczp7fSxzaGFwZXM6e30sc2tlbGV0b25zOnt9LGFuaW1hdGlvbnM6e30sbm9kZXM6e319LG4ubWV0YWRhdGE9e3ZlcnNpb246NC42LHR5cGU6Ik9iamVjdCIsZ2VuZXJhdG9yOiJPYmplY3QzRC50b0pTT04ifSk7Y29uc3Qgcz17fTtzLnV1aWQ9dGhpcy51dWlkLHMudHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJihzLm5hbWU9dGhpcy5uYW1lKSx0aGlzLmNhc3RTaGFkb3c9PT0hMCYmKHMuY2FzdFNoYWRvdz0hMCksdGhpcy5yZWNlaXZlU2hhZG93PT09ITAmJihzLnJlY2VpdmVTaGFkb3c9ITApLHRoaXMudmlzaWJsZT09PSExJiYocy52aXNpYmxlPSExKSx0aGlzLmZydXN0dW1DdWxsZWQ9PT0hMSYmKHMuZnJ1c3R1bUN1bGxlZD0hMSksdGhpcy5yZW5kZXJPcmRlciE9PTAmJihzLnJlbmRlck9yZGVyPXRoaXMucmVuZGVyT3JkZXIpLE9iamVjdC5rZXlzKHRoaXMudXNlckRhdGEpLmxlbmd0aD4wJiYocy51c2VyRGF0YT10aGlzLnVzZXJEYXRhKSxzLmxheWVycz10aGlzLmxheWVycy5tYXNrLHMubWF0cml4PXRoaXMubWF0cml4LnRvQXJyYXkoKSxzLnVwPXRoaXMudXAudG9BcnJheSgpLHRoaXMubWF0cml4QXV0b1VwZGF0ZT09PSExJiYocy5tYXRyaXhBdXRvVXBkYXRlPSExKSx0aGlzLmlzSW5zdGFuY2VkTWVzaCYmKHMudHlwZT0iSW5zdGFuY2VkTWVzaCIscy5jb3VudD10aGlzLmNvdW50LHMuaW5zdGFuY2VNYXRyaXg9dGhpcy5pbnN0YW5jZU1hdHJpeC50b0pTT04oKSx0aGlzLmluc3RhbmNlQ29sb3IhPT1udWxsJiYocy5pbnN0YW5jZUNvbG9yPXRoaXMuaW5zdGFuY2VDb2xvci50b0pTT04oKSkpLHRoaXMuaXNCYXRjaGVkTWVzaCYmKHMudHlwZT0iQmF0Y2hlZE1lc2giLHMucGVyT2JqZWN0RnJ1c3R1bUN1bGxlZD10aGlzLnBlck9iamVjdEZydXN0dW1DdWxsZWQscy5zb3J0T2JqZWN0cz10aGlzLnNvcnRPYmplY3RzLHMuZHJhd1Jhbmdlcz10aGlzLl9kcmF3UmFuZ2VzLHMucmVzZXJ2ZWRSYW5nZXM9dGhpcy5fcmVzZXJ2ZWRSYW5nZXMscy5nZW9tZXRyeUluZm89dGhpcy5fZ2VvbWV0cnlJbmZvLm1hcChhPT5HZShGdCh7fSxhKSx7Ym91bmRpbmdCb3g6YS5ib3VuZGluZ0JveD97bWluOmEuYm91bmRpbmdCb3gubWluLnRvQXJyYXkoKSxtYXg6YS5ib3VuZGluZ0JveC5tYXgudG9BcnJheSgpfTp2b2lkIDAsYm91bmRpbmdTcGhlcmU6YS5ib3VuZGluZ1NwaGVyZT97cmFkaXVzOmEuYm91bmRpbmdTcGhlcmUucmFkaXVzLGNlbnRlcjphLmJvdW5kaW5nU3BoZXJlLmNlbnRlci50b0FycmF5KCl9OnZvaWQgMH0pKSxzLmluc3RhbmNlSW5mbz10aGlzLl9pbnN0YW5jZUluZm8ubWFwKGE9PkZ0KHt9LGEpKSxzLmF2YWlsYWJsZUluc3RhbmNlSWRzPXRoaXMuX2F2YWlsYWJsZUluc3RhbmNlSWRzLnNsaWNlKCkscy5hdmFpbGFibGVHZW9tZXRyeUlkcz10aGlzLl9hdmFpbGFibGVHZW9tZXRyeUlkcy5zbGljZSgpLHMubmV4dEluZGV4U3RhcnQ9dGhpcy5fbmV4dEluZGV4U3RhcnQscy5uZXh0VmVydGV4U3RhcnQ9dGhpcy5fbmV4dFZlcnRleFN0YXJ0LHMuZ2VvbWV0cnlDb3VudD10aGlzLl9nZW9tZXRyeUNvdW50LHMubWF4SW5zdGFuY2VDb3VudD10aGlzLl9tYXhJbnN0YW5jZUNvdW50LHMubWF4VmVydGV4Q291bnQ9dGhpcy5fbWF4VmVydGV4Q291bnQscy5tYXhJbmRleENvdW50PXRoaXMuX21heEluZGV4Q291bnQscy5nZW9tZXRyeUluaXRpYWxpemVkPXRoaXMuX2dlb21ldHJ5SW5pdGlhbGl6ZWQscy5tYXRyaWNlc1RleHR1cmU9dGhpcy5fbWF0cmljZXNUZXh0dXJlLnRvSlNPTih0KSxzLmluZGlyZWN0VGV4dHVyZT10aGlzLl9pbmRpcmVjdFRleHR1cmUudG9KU09OKHQpLHRoaXMuX2NvbG9yc1RleHR1cmUhPT1udWxsJiYocy5jb2xvcnNUZXh0dXJlPXRoaXMuX2NvbG9yc1RleHR1cmUudG9KU09OKHQpKSx0aGlzLmJvdW5kaW5nU3BoZXJlIT09bnVsbCYmKHMuYm91bmRpbmdTcGhlcmU9e2NlbnRlcjp0aGlzLmJvdW5kaW5nU3BoZXJlLmNlbnRlci50b0FycmF5KCkscmFkaXVzOnRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzfSksdGhpcy5ib3VuZGluZ0JveCE9PW51bGwmJihzLmJvdW5kaW5nQm94PXttaW46dGhpcy5ib3VuZGluZ0JveC5taW4udG9BcnJheSgpLG1heDp0aGlzLmJvdW5kaW5nQm94Lm1heC50b0FycmF5KCl9KSk7ZnVuY3Rpb24gcihhLGMpe3JldHVybiBhW2MudXVpZF09PT12b2lkIDAmJihhW2MudXVpZF09Yy50b0pTT04odCkpLGMudXVpZH1pZih0aGlzLmlzU2NlbmUpdGhpcy5iYWNrZ3JvdW5kJiYodGhpcy5iYWNrZ3JvdW5kLmlzQ29sb3I/cy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04oKTp0aGlzLmJhY2tncm91bmQuaXNUZXh0dXJlJiYocy5iYWNrZ3JvdW5kPXRoaXMuYmFja2dyb3VuZC50b0pTT04odCkudXVpZCkpLHRoaXMuZW52aXJvbm1lbnQmJnRoaXMuZW52aXJvbm1lbnQuaXNUZXh0dXJlJiZ0aGlzLmVudmlyb25tZW50LmlzUmVuZGVyVGFyZ2V0VGV4dHVyZSE9PSEwJiYocy5lbnZpcm9ubWVudD10aGlzLmVudmlyb25tZW50LnRvSlNPTih0KS51dWlkKTtlbHNlIGlmKHRoaXMuaXNNZXNofHx0aGlzLmlzTGluZXx8dGhpcy5pc1BvaW50cyl7cy5nZW9tZXRyeT1yKHQuZ2VvbWV0cmllcyx0aGlzLmdlb21ldHJ5KTtjb25zdCBhPXRoaXMuZ2VvbWV0cnkucGFyYW1ldGVycztpZihhIT09dm9pZCAwJiZhLnNoYXBlcyE9PXZvaWQgMCl7Y29uc3QgYz1hLnNoYXBlcztpZihBcnJheS5pc0FycmF5KGMpKWZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyl7Y29uc3QgdT1jW2xdO3IodC5zaGFwZXMsdSl9ZWxzZSByKHQuc2hhcGVzLGMpfX1pZih0aGlzLmlzU2tpbm5lZE1lc2gmJihzLmJpbmRNb2RlPXRoaXMuYmluZE1vZGUscy5iaW5kTWF0cml4PXRoaXMuYmluZE1hdHJpeC50b0FycmF5KCksdGhpcy5za2VsZXRvbiE9PXZvaWQgMCYmKHIodC5za2VsZXRvbnMsdGhpcy5za2VsZXRvbikscy5za2VsZXRvbj10aGlzLnNrZWxldG9uLnV1aWQpKSx0aGlzLm1hdGVyaWFsIT09dm9pZCAwKWlmKEFycmF5LmlzQXJyYXkodGhpcy5tYXRlcmlhbCkpe2NvbnN0IGE9W107Zm9yKGxldCBjPTAsbD10aGlzLm1hdGVyaWFsLmxlbmd0aDtjPGw7YysrKWEucHVzaChyKHQubWF0ZXJpYWxzLHRoaXMubWF0ZXJpYWxbY10pKTtzLm1hdGVyaWFsPWF9ZWxzZSBzLm1hdGVyaWFsPXIodC5tYXRlcmlhbHMsdGhpcy5tYXRlcmlhbCk7aWYodGhpcy5jaGlsZHJlbi5sZW5ndGg+MCl7cy5jaGlsZHJlbj1bXTtmb3IobGV0IGE9MDthPHRoaXMuY2hpbGRyZW4ubGVuZ3RoO2ErKylzLmNoaWxkcmVuLnB1c2godGhpcy5jaGlsZHJlblthXS50b0pTT04odCkub2JqZWN0KX1pZih0aGlzLmFuaW1hdGlvbnMubGVuZ3RoPjApe3MuYW5pbWF0aW9ucz1bXTtmb3IobGV0IGE9MDthPHRoaXMuYW5pbWF0aW9ucy5sZW5ndGg7YSsrKXtjb25zdCBjPXRoaXMuYW5pbWF0aW9uc1thXTtzLmFuaW1hdGlvbnMucHVzaChyKHQuYW5pbWF0aW9ucyxjKSl9fWlmKGUpe2NvbnN0IGE9byh0Lmdlb21ldHJpZXMpLGM9byh0Lm1hdGVyaWFscyksbD1vKHQudGV4dHVyZXMpLGg9byh0LmltYWdlcyksdT1vKHQuc2hhcGVzKSxmPW8odC5za2VsZXRvbnMpLGQ9byh0LmFuaW1hdGlvbnMpLHA9byh0Lm5vZGVzKTthLmxlbmd0aD4wJiYobi5nZW9tZXRyaWVzPWEpLGMubGVuZ3RoPjAmJihuLm1hdGVyaWFscz1jKSxsLmxlbmd0aD4wJiYobi50ZXh0dXJlcz1sKSxoLmxlbmd0aD4wJiYobi5pbWFnZXM9aCksdS5sZW5ndGg+MCYmKG4uc2hhcGVzPXUpLGYubGVuZ3RoPjAmJihuLnNrZWxldG9ucz1mKSxkLmxlbmd0aD4wJiYobi5hbmltYXRpb25zPWQpLHAubGVuZ3RoPjAmJihuLm5vZGVzPXApfXJldHVybiBuLm9iamVjdD1zLG47ZnVuY3Rpb24gbyhhKXtjb25zdCBjPVtdO2Zvcihjb25zdCBsIGluIGEpe2NvbnN0IGg9YVtsXTtkZWxldGUgaC5tZXRhZGF0YSxjLnB1c2goaCl9cmV0dXJuIGN9fWNsb25lKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyx0KX1jb3B5KHQsZT0hMCl7aWYodGhpcy5uYW1lPXQubmFtZSx0aGlzLnVwLmNvcHkodC51cCksdGhpcy5wb3NpdGlvbi5jb3B5KHQucG9zaXRpb24pLHRoaXMucm90YXRpb24ub3JkZXI9dC5yb3RhdGlvbi5vcmRlcix0aGlzLnF1YXRlcm5pb24uY29weSh0LnF1YXRlcm5pb24pLHRoaXMuc2NhbGUuY29weSh0LnNjYWxlKSx0aGlzLm1hdHJpeC5jb3B5KHQubWF0cml4KSx0aGlzLm1hdHJpeFdvcmxkLmNvcHkodC5tYXRyaXhXb3JsZCksdGhpcy5tYXRyaXhBdXRvVXBkYXRlPXQubWF0cml4QXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkQXV0b1VwZGF0ZT10Lm1hdHJpeFdvcmxkQXV0b1VwZGF0ZSx0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU9dC5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlLHRoaXMubGF5ZXJzLm1hc2s9dC5sYXllcnMubWFzayx0aGlzLnZpc2libGU9dC52aXNpYmxlLHRoaXMuY2FzdFNoYWRvdz10LmNhc3RTaGFkb3csdGhpcy5yZWNlaXZlU2hhZG93PXQucmVjZWl2ZVNoYWRvdyx0aGlzLmZydXN0dW1DdWxsZWQ9dC5mcnVzdHVtQ3VsbGVkLHRoaXMucmVuZGVyT3JkZXI9dC5yZW5kZXJPcmRlcix0aGlzLmFuaW1hdGlvbnM9dC5hbmltYXRpb25zLnNsaWNlKCksdGhpcy51c2VyRGF0YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQudXNlckRhdGEpKSxlPT09ITApZm9yKGxldCBuPTA7bjx0LmNoaWxkcmVuLmxlbmd0aDtuKyspe2NvbnN0IHM9dC5jaGlsZHJlbltuXTt0aGlzLmFkZChzLmNsb25lKCkpfXJldHVybiB0aGlzfX1UZS5ERUZBVUxUX1VQPW5ldyBUKDAsMSwwKSxUZS5ERUZBVUxUX01BVFJJWF9BVVRPX1VQREFURT0hMCxUZS5ERUZBVUxUX01BVFJJWF9XT1JMRF9BVVRPX1VQREFURT0hMDtjb25zdCBoZT1uZXcgVCxFZT1uZXcgVCxsbz1uZXcgVCxQZT1uZXcgVCwkbj1uZXcgVCxVbj1uZXcgVCx6Yz1uZXcgVCxobz1uZXcgVCx1bz1uZXcgVCxmbz1uZXcgVCxwbz1uZXcgWXQseW89bmV3IFl0LG1vPW5ldyBZdDtjbGFzcyBldHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCl7dGhpcy5hPXQsdGhpcy5iPWUsdGhpcy5jPW59c3RhdGljIGdldE5vcm1hbCh0LGUsbixzKXtzLnN1YlZlY3RvcnMobixlKSxoZS5zdWJWZWN0b3JzKHQsZSkscy5jcm9zcyhoZSk7Y29uc3Qgcj1zLmxlbmd0aFNxKCk7cmV0dXJuIHI+MD9zLm11bHRpcGx5U2NhbGFyKDEvTWF0aC5zcXJ0KHIpKTpzLnNldCgwLDAsMCl9c3RhdGljIGdldEJhcnljb29yZCh0LGUsbixzLHIpe2hlLnN1YlZlY3RvcnMocyxlKSxFZS5zdWJWZWN0b3JzKG4sZSksbG8uc3ViVmVjdG9ycyh0LGUpO2NvbnN0IG89aGUuZG90KGhlKSxhPWhlLmRvdChFZSksYz1oZS5kb3QobG8pLGw9RWUuZG90KEVlKSxoPUVlLmRvdChsbyksdT1vKmwtYSphO2lmKHU9PT0wKXJldHVybiByLnNldCgwLDAsMCksbnVsbDtjb25zdCBmPTEvdSxkPShsKmMtYSpoKSpmLHA9KG8qaC1hKmMpKmY7cmV0dXJuIHIuc2V0KDEtZC1wLHAsZCl9c3RhdGljIGNvbnRhaW5zUG9pbnQodCxlLG4scyl7cmV0dXJuIHRoaXMuZ2V0QmFyeWNvb3JkKHQsZSxuLHMsUGUpPT09bnVsbD8hMTpQZS54Pj0wJiZQZS55Pj0wJiZQZS54K1BlLnk8PTF9c3RhdGljIGdldEludGVycG9sYXRpb24odCxlLG4scyxyLG8sYSxjKXtyZXR1cm4gdGhpcy5nZXRCYXJ5Y29vcmQodCxlLG4scyxQZSk9PT1udWxsPyhjLng9MCxjLnk9MCwieiJpbiBjJiYoYy56PTApLCJ3ImluIGMmJihjLnc9MCksbnVsbCk6KGMuc2V0U2NhbGFyKDApLGMuYWRkU2NhbGVkVmVjdG9yKHIsUGUueCksYy5hZGRTY2FsZWRWZWN0b3IobyxQZS55KSxjLmFkZFNjYWxlZFZlY3RvcihhLFBlLnopLGMpfXN0YXRpYyBnZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUodCxlLG4scyxyLG8pe3JldHVybiBwby5zZXRTY2FsYXIoMCkseW8uc2V0U2NhbGFyKDApLG1vLnNldFNjYWxhcigwKSxwby5mcm9tQnVmZmVyQXR0cmlidXRlKHQsZSkseW8uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LG4pLG1vLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSxvLnNldFNjYWxhcigwKSxvLmFkZFNjYWxlZFZlY3RvcihwbyxyLngpLG8uYWRkU2NhbGVkVmVjdG9yKHlvLHIueSksby5hZGRTY2FsZWRWZWN0b3IobW8sci56KSxvfXN0YXRpYyBpc0Zyb250RmFjaW5nKHQsZSxuLHMpe3JldHVybiBoZS5zdWJWZWN0b3JzKG4sZSksRWUuc3ViVmVjdG9ycyh0LGUpLGhlLmNyb3NzKEVlKS5kb3Qocyk8MH1zZXQodCxlLG4pe3JldHVybiB0aGlzLmEuY29weSh0KSx0aGlzLmIuY29weShlKSx0aGlzLmMuY29weShuKSx0aGlzfXNldEZyb21Qb2ludHNBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuY29weSh0W2VdKSx0aGlzLmIuY29weSh0W25dKSx0aGlzLmMuY29weSh0W3NdKSx0aGlzfXNldEZyb21BdHRyaWJ1dGVBbmRJbmRpY2VzKHQsZSxuLHMpe3JldHVybiB0aGlzLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGUpLHRoaXMuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsbiksdGhpcy5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxzKSx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3JldHVybiB0aGlzLmEuY29weSh0LmEpLHRoaXMuYi5jb3B5KHQuYiksdGhpcy5jLmNvcHkodC5jKSx0aGlzfWdldEFyZWEoKXtyZXR1cm4gaGUuc3ViVmVjdG9ycyh0aGlzLmMsdGhpcy5iKSxFZS5zdWJWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLGhlLmNyb3NzKEVlKS5sZW5ndGgoKSouNX1nZXRNaWRwb2ludCh0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuYSx0aGlzLmIpLmFkZCh0aGlzLmMpLm11bHRpcGx5U2NhbGFyKDEvMyl9Z2V0Tm9ybWFsKHQpe3JldHVybiBldC5nZXROb3JtYWwodGhpcy5hLHRoaXMuYix0aGlzLmMsdCl9Z2V0UGxhbmUodCl7cmV0dXJuIHQuc2V0RnJvbUNvcGxhbmFyUG9pbnRzKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1nZXRCYXJ5Y29vcmQodCxlKXtyZXR1cm4gZXQuZ2V0QmFyeWNvb3JkKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSl9Z2V0SW50ZXJwb2xhdGlvbih0LGUsbixzLHIpe3JldHVybiBldC5nZXRJbnRlcnBvbGF0aW9uKHQsdGhpcy5hLHRoaXMuYix0aGlzLmMsZSxuLHMscil9Y29udGFpbnNQb2ludCh0KXtyZXR1cm4gZXQuY29udGFpbnNQb2ludCh0LHRoaXMuYSx0aGlzLmIsdGhpcy5jKX1pc0Zyb250RmFjaW5nKHQpe3JldHVybiBldC5pc0Zyb250RmFjaW5nKHRoaXMuYSx0aGlzLmIsdGhpcy5jLHQpfWludGVyc2VjdHNCb3godCl7cmV0dXJuIHQuaW50ZXJzZWN0c1RyaWFuZ2xlKHRoaXMpfWNsb3Nlc3RQb2ludFRvUG9pbnQodCxlKXtjb25zdCBuPXRoaXMuYSxzPXRoaXMuYixyPXRoaXMuYztsZXQgbyxhOyRuLnN1YlZlY3RvcnMocyxuKSxVbi5zdWJWZWN0b3JzKHIsbiksaG8uc3ViVmVjdG9ycyh0LG4pO2NvbnN0IGM9JG4uZG90KGhvKSxsPVVuLmRvdChobyk7aWYoYzw9MCYmbDw9MClyZXR1cm4gZS5jb3B5KG4pO3VvLnN1YlZlY3RvcnModCxzKTtjb25zdCBoPSRuLmRvdCh1byksdT1Vbi5kb3QodW8pO2lmKGg+PTAmJnU8PWgpcmV0dXJuIGUuY29weShzKTtjb25zdCBmPWMqdS1oKmw7aWYoZjw9MCYmYz49MCYmaDw9MClyZXR1cm4gbz1jLyhjLWgpLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoJG4sbyk7Zm8uc3ViVmVjdG9ycyh0LHIpO2NvbnN0IGQ9JG4uZG90KGZvKSxwPVVuLmRvdChmbyk7aWYocD49MCYmZDw9cClyZXR1cm4gZS5jb3B5KHIpO2NvbnN0IHk9ZCpsLWMqcDtpZih5PD0wJiZsPj0wJiZwPD0wKXJldHVybiBhPWwvKGwtcCksZS5jb3B5KG4pLmFkZFNjYWxlZFZlY3RvcihVbixhKTtjb25zdCBtPWgqcC1kKnU7aWYobTw9MCYmdS1oPj0wJiZkLXA+PTApcmV0dXJuIHpjLnN1YlZlY3RvcnMocixzKSxhPSh1LWgpLyh1LWgrKGQtcCkpLGUuY29weShzKS5hZGRTY2FsZWRWZWN0b3IoemMsYSk7Y29uc3QgZz0xLyhtK3krZik7cmV0dXJuIG89eSpnLGE9ZipnLGUuY29weShuKS5hZGRTY2FsZWRWZWN0b3IoJG4sbykuYWRkU2NhbGVkVmVjdG9yKFVuLGEpfWVxdWFscyh0KXtyZXR1cm4gdC5hLmVxdWFscyh0aGlzLmEpJiZ0LmIuZXF1YWxzKHRoaXMuYikmJnQuYy5lcXVhbHModGhpcy5jKX19Y29uc3QgVGM9e2FsaWNlYmx1ZToxNTc5MjM4MyxhbnRpcXVld2hpdGU6MTY0NDQzNzUsYXF1YTo2NTUzNSxhcXVhbWFyaW5lOjgzODg1NjQsYXp1cmU6MTU3OTQxNzUsYmVpZ2U6MTYxMTkyNjAsYmlzcXVlOjE2NzcwMjQ0LGJsYWNrOjAsYmxhbmNoZWRhbG1vbmQ6MTY3NzIwNDUsYmx1ZToyNTUsYmx1ZXZpb2xldDo5MDU1MjAyLGJyb3duOjEwODI0MjM0LGJ1cmx5d29vZDoxNDU5NjIzMSxjYWRldGJsdWU6NjI2NjUyOCxjaGFydHJldXNlOjgzODgzNTIsY2hvY29sYXRlOjEzNzg5NDcwLGNvcmFsOjE2NzQ0MjcyLGNvcm5mbG93ZXJibHVlOjY1OTE5ODEsY29ybnNpbGs6MTY3NzUzODgsY3JpbXNvbjoxNDQyMzEwMCxjeWFuOjY1NTM1LGRhcmtibHVlOjEzOSxkYXJrY3lhbjozNTcyMyxkYXJrZ29sZGVucm9kOjEyMDkyOTM5LGRhcmtncmF5OjExMTE5MDE3LGRhcmtncmVlbjoyNTYwMCxkYXJrZ3JleToxMTExOTAxNyxkYXJra2hha2k6MTI0MzMyNTksZGFya21hZ2VudGE6OTEwOTY0MyxkYXJrb2xpdmVncmVlbjo1NTk3OTk5LGRhcmtvcmFuZ2U6MTY3NDc1MjAsZGFya29yY2hpZDoxMDA0MDAxMixkYXJrcmVkOjkxMDk1MDQsZGFya3NhbG1vbjoxNTMwODQxMCxkYXJrc2VhZ3JlZW46OTQxOTkxOSxkYXJrc2xhdGVibHVlOjQ3MzQzNDcsZGFya3NsYXRlZ3JheTozMTAwNDk1LGRhcmtzbGF0ZWdyZXk6MzEwMDQ5NSxkYXJrdHVycXVvaXNlOjUyOTQ1LGRhcmt2aW9sZXQ6OTY5OTUzOSxkZWVwcGluazoxNjcxNjk0NyxkZWVwc2t5Ymx1ZTo0OTE1MSxkaW1ncmF5OjY5MDgyNjUsZGltZ3JleTo2OTA4MjY1LGRvZGdlcmJsdWU6MjAwMzE5OSxmaXJlYnJpY2s6MTE2NzQxNDYsZmxvcmFsd2hpdGU6MTY3NzU5MjAsZm9yZXN0Z3JlZW46MjI2Mzg0MixmdWNoc2lhOjE2NzExOTM1LGdhaW5zYm9ybzoxNDQ3NDQ2MCxnaG9zdHdoaXRlOjE2MzE2NjcxLGdvbGQ6MTY3NjY3MjAsZ29sZGVucm9kOjE0MzI5MTIwLGdyYXk6ODQyMTUwNCxncmVlbjozMjc2OCxncmVlbnllbGxvdzoxMTQwMzA1NSxncmV5Ojg0MjE1MDQsaG9uZXlkZXc6MTU3OTQxNjAsaG90cGluazoxNjczODc0MCxpbmRpYW5yZWQ6MTM0NTg1MjQsaW5kaWdvOjQ5MTUzMzAsaXZvcnk6MTY3NzcyMDAsa2hha2k6MTU3ODc2NjAsbGF2ZW5kZXI6MTUxMzI0MTAsbGF2ZW5kZXJibHVzaDoxNjc3MzM2NSxsYXduZ3JlZW46ODE5MDk3NixsZW1vbmNoaWZmb246MTY3NzU4ODUsbGlnaHRibHVlOjExMzkzMjU0LGxpZ2h0Y29yYWw6MTU3NjE1MzYsbGlnaHRjeWFuOjE0NzQ1NTk5LGxpZ2h0Z29sZGVucm9keWVsbG93OjE2NDQ4MjEwLGxpZ2h0Z3JheToxMzg4MjMyMyxsaWdodGdyZWVuOjk0OTgyNTYsbGlnaHRncmV5OjEzODgyMzIzLGxpZ2h0cGluazoxNjc1ODQ2NSxsaWdodHNhbG1vbjoxNjc1Mjc2MixsaWdodHNlYWdyZWVuOjIxNDI4OTAsbGlnaHRza3libHVlOjg5MDAzNDYsbGlnaHRzbGF0ZWdyYXk6NzgzMzc1MyxsaWdodHNsYXRlZ3JleTo3ODMzNzUzLGxpZ2h0c3RlZWxibHVlOjExNTg0NzM0LGxpZ2h0eWVsbG93OjE2Nzc3MTg0LGxpbWU6NjUyODAsbGltZWdyZWVuOjMzMjkzMzAsbGluZW46MTY0NDU2NzAsbWFnZW50YToxNjcxMTkzNSxtYXJvb246ODM4ODYwOCxtZWRpdW1hcXVhbWFyaW5lOjY3MzczMjIsbWVkaXVtYmx1ZToyMDUsbWVkaXVtb3JjaGlkOjEyMjExNjY3LG1lZGl1bXB1cnBsZTo5NjYyNjgzLG1lZGl1bXNlYWdyZWVuOjM5NzgwOTcsbWVkaXVtc2xhdGVibHVlOjgwODc3OTAsbWVkaXVtc3ByaW5nZ3JlZW46NjQxNTQsbWVkaXVtdHVycXVvaXNlOjQ3NzIzMDAsbWVkaXVtdmlvbGV0cmVkOjEzMDQ3MTczLG1pZG5pZ2h0Ymx1ZToxNjQ0OTEyLG1pbnRjcmVhbToxNjEyMTg1MCxtaXN0eXJvc2U6MTY3NzAyNzMsbW9jY2FzaW46MTY3NzAyMjksbmF2YWpvd2hpdGU6MTY3Njg2ODUsbmF2eToxMjgsb2xkbGFjZToxNjY0MzU1OCxvbGl2ZTo4NDIxMzc2LG9saXZlZHJhYjo3MDQ4NzM5LG9yYW5nZToxNjc1MzkyMCxvcmFuZ2VyZWQ6MTY3MjkzNDQsb3JjaGlkOjE0MzE1NzM0LHBhbGVnb2xkZW5yb2Q6MTU2NTcxMzAscGFsZWdyZWVuOjEwMDI1ODgwLHBhbGV0dXJxdW9pc2U6MTE1Mjk5NjYscGFsZXZpb2xldHJlZDoxNDM4MTIwMyxwYXBheWF3aGlwOjE2NzczMDc3LHBlYWNocHVmZjoxNjc2NzY3MyxwZXJ1OjEzNDY4OTkxLHBpbms6MTY3NjEwMzUscGx1bToxNDUyNDYzNyxwb3dkZXJibHVlOjExNTkxOTEwLHB1cnBsZTo4Mzg4NzM2LHJlYmVjY2FwdXJwbGU6NjY5Nzg4MSxyZWQ6MTY3MTE2ODAscm9zeWJyb3duOjEyMzU3NTE5LHJveWFsYmx1ZTo0Mjg2OTQ1LHNhZGRsZWJyb3duOjkxMjcxODcsc2FsbW9uOjE2NDE2ODgyLHNhbmR5YnJvd246MTYwMzI4NjQsc2VhZ3JlZW46MzA1MDMyNyxzZWFzaGVsbDoxNjc3NDYzOCxzaWVubmE6MTA1MDY3OTcsc2lsdmVyOjEyNjMyMjU2LHNreWJsdWU6ODkwMDMzMSxzbGF0ZWJsdWU6Njk3MDA2MSxzbGF0ZWdyYXk6NzM3Mjk0NCxzbGF0ZWdyZXk6NzM3Mjk0NCxzbm93OjE2Nzc1OTMwLHNwcmluZ2dyZWVuOjY1NDA3LHN0ZWVsYmx1ZTo0NjIwOTgwLHRhbjoxMzgwODc4MCx0ZWFsOjMyODk2LHRoaXN0bGU6MTQyMDQ4ODgsdG9tYXRvOjE2NzM3MDk1LHR1cnF1b2lzZTo0MjUxODU2LHZpb2xldDoxNTYzMTA4Nix3aGVhdDoxNjExMzMzMSx3aGl0ZToxNjc3NzIxNSx3aGl0ZXNtb2tlOjE2MTE5Mjg1LHllbGxvdzoxNjc3Njk2MCx5ZWxsb3dncmVlbjoxMDE0NTA3NH0samU9e2g6MCxzOjAsbDowfSx1cz17aDowLHM6MCxsOjB9O2Z1bmN0aW9uIGdvKGksdCxlKXtyZXR1cm4gZTwwJiYoZSs9MSksZT4xJiYoZS09MSksZTwxLzY/aSsodC1pKSo2KmU6ZTwxLzI/dDplPDIvMz9pKyh0LWkpKjYqKDIvMy1lKTppfWxldCBmcz1jbGFzc3tjb25zdHJ1Y3Rvcih0LGUsbil7cmV0dXJuIHRoaXMuaXNDb2xvcj0hMCx0aGlzLnI9MSx0aGlzLmc9MSx0aGlzLmI9MSx0aGlzLnNldCh0LGUsbil9c2V0KHQsZSxuKXtpZihlPT09dm9pZCAwJiZuPT09dm9pZCAwKXtjb25zdCBzPXQ7cyYmcy5pc0NvbG9yP3RoaXMuY29weShzKTp0eXBlb2Ygcz09Im51bWJlciI/dGhpcy5zZXRIZXgocyk6dHlwZW9mIHM9PSJzdHJpbmciJiZ0aGlzLnNldFN0eWxlKHMpfWVsc2UgdGhpcy5zZXRSR0IodCxlLG4pO3JldHVybiB0aGlzfXNldFNjYWxhcih0KXtyZXR1cm4gdGhpcy5yPXQsdGhpcy5nPXQsdGhpcy5iPXQsdGhpc31zZXRIZXgodCxlPW9lKXtyZXR1cm4gdD1NYXRoLmZsb29yKHQpLHRoaXMucj0odD4+MTYmMjU1KS8yNTUsdGhpcy5nPSh0Pj44JjI1NSkvMjU1LHRoaXMuYj0odCYyNTUpLzI1NSxhZS50b1dvcmtpbmdDb2xvclNwYWNlKHRoaXMsZSksdGhpc31zZXRSR0IodCxlLG4scz1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIHRoaXMucj10LHRoaXMuZz1lLHRoaXMuYj1uLGFlLnRvV29ya2luZ0NvbG9yU3BhY2UodGhpcyxzKSx0aGlzfXNldEhTTCh0LGUsbixzPWFlLndvcmtpbmdDb2xvclNwYWNlKXtpZih0PVV1KHQsMSksZT1aKGUsMCwxKSxuPVoobiwwLDEpLGU9PT0wKXRoaXMucj10aGlzLmc9dGhpcy5iPW47ZWxzZXtjb25zdCByPW48PS41P24qKDErZSk6bitlLW4qZSxvPTIqbi1yO3RoaXMucj1nbyhvLHIsdCsxLzMpLHRoaXMuZz1nbyhvLHIsdCksdGhpcy5iPWdvKG8scix0LTEvMyl9cmV0dXJuIGFlLnRvV29ya2luZ0NvbG9yU3BhY2UodGhpcyxzKSx0aGlzfXNldFN0eWxlKHQsZT1vZSl7ZnVuY3Rpb24gbihyKXtyIT09dm9pZCAwJiZwYXJzZUZsb2F0KHIpPDEmJmNvbnNvbGUud2FybigiVEhSRUUuQ29sb3I6IEFscGhhIGNvbXBvbmVudCBvZiAiK3QrIiB3aWxsIGJlIGlnbm9yZWQuIil9bGV0IHM7aWYocz0vXihcdyspXCgoW15cKV0qKVwpLy5leGVjKHQpKXtsZXQgcjtjb25zdCBvPXNbMV0sYT1zWzJdO3N3aXRjaChvKXtjYXNlInJnYiI6Y2FzZSJyZ2JhIjppZihyPS9eXHMqKFxkKylccyosXHMqKFxkKylccyosXHMqKFxkKylccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRSR0IoTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMV0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbMl0sMTApKS8yNTUsTWF0aC5taW4oMjU1LHBhcnNlSW50KHJbM10sMTApKS8yNTUsZSk7aWYocj0vXlxzKihcZCspXCVccyosXHMqKFxkKylcJVxzKixccyooXGQrKVwlXHMqKD86LFxzKihcZCpcLj9cZCspXHMqKT8kLy5leGVjKGEpKXJldHVybiBuKHJbNF0pLHRoaXMuc2V0UkdCKE1hdGgubWluKDEwMCxwYXJzZUludChyWzFdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzJdLDEwKSkvMTAwLE1hdGgubWluKDEwMCxwYXJzZUludChyWzNdLDEwKSkvMTAwLGUpO2JyZWFrO2Nhc2UiaHNsIjpjYXNlImhzbGEiOmlmKHI9L15ccyooXGQqXC4/XGQrKVxzKixccyooXGQqXC4/XGQrKVwlXHMqLFxzKihcZCpcLj9cZCspXCVccyooPzosXHMqKFxkKlwuP1xkKylccyopPyQvLmV4ZWMoYSkpcmV0dXJuIG4ocls0XSksdGhpcy5zZXRIU0wocGFyc2VGbG9hdChyWzFdKS8zNjAscGFyc2VGbG9hdChyWzJdKS8xMDAscGFyc2VGbG9hdChyWzNdKS8xMDAsZSk7YnJlYWs7ZGVmYXVsdDpjb25zb2xlLndhcm4oIlRIUkVFLkNvbG9yOiBVbmtub3duIGNvbG9yIG1vZGVsICIrdCl9fWVsc2UgaWYocz0vXlwjKFtBLUZhLWZcZF0rKSQvLmV4ZWModCkpe2NvbnN0IHI9c1sxXSxvPXIubGVuZ3RoO2lmKG89PT0zKXJldHVybiB0aGlzLnNldFJHQihwYXJzZUludChyLmNoYXJBdCgwKSwxNikvMTUscGFyc2VJbnQoci5jaGFyQXQoMSksMTYpLzE1LHBhcnNlSW50KHIuY2hhckF0KDIpLDE2KS8xNSxlKTtpZihvPT09NilyZXR1cm4gdGhpcy5zZXRIZXgocGFyc2VJbnQociwxNiksZSk7Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogSW52YWxpZCBoZXggY29sb3IgIit0KX1lbHNlIGlmKHQmJnQubGVuZ3RoPjApcmV0dXJuIHRoaXMuc2V0Q29sb3JOYW1lKHQsZSk7cmV0dXJuIHRoaXN9c2V0Q29sb3JOYW1lKHQsZT1vZSl7Y29uc3Qgbj1UY1t0LnRvTG93ZXJDYXNlKCldO3JldHVybiBuIT09dm9pZCAwP3RoaXMuc2V0SGV4KG4sZSk6Y29uc29sZS53YXJuKCJUSFJFRS5Db2xvcjogVW5rbm93biBjb2xvciAiK3QpLHRoaXN9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5yLHRoaXMuZyx0aGlzLmIpfWNvcHkodCl7cmV0dXJuIHRoaXMucj10LnIsdGhpcy5nPXQuZyx0aGlzLmI9dC5iLHRoaXN9Y29weVNSR0JUb0xpbmVhcih0KXtyZXR1cm4gdGhpcy5yPV9lKHQuciksdGhpcy5nPV9lKHQuZyksdGhpcy5iPV9lKHQuYiksdGhpc31jb3B5TGluZWFyVG9TUkdCKHQpe3JldHVybiB0aGlzLnI9Rm4odC5yKSx0aGlzLmc9Rm4odC5nKSx0aGlzLmI9Rm4odC5iKSx0aGlzfWNvbnZlcnRTUkdCVG9MaW5lYXIoKXtyZXR1cm4gdGhpcy5jb3B5U1JHQlRvTGluZWFyKHRoaXMpLHRoaXN9Y29udmVydExpbmVhclRvU1JHQigpe3JldHVybiB0aGlzLmNvcHlMaW5lYXJUb1NSR0IodGhpcyksdGhpc31nZXRIZXgodD1vZSl7cmV0dXJuIGFlLmZyb21Xb3JraW5nQ29sb3JTcGFjZShfdC5jb3B5KHRoaXMpLHQpLE1hdGgucm91bmQoWihfdC5yKjI1NSwwLDI1NSkpKjY1NTM2K01hdGgucm91bmQoWihfdC5nKjI1NSwwLDI1NSkpKjI1NitNYXRoLnJvdW5kKFooX3QuYioyNTUsMCwyNTUpKX1nZXRIZXhTdHJpbmcodD1vZSl7cmV0dXJuKCIwMDAwMDAiK3RoaXMuZ2V0SGV4KHQpLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTYpfWdldEhTTCh0LGU9YWUud29ya2luZ0NvbG9yU3BhY2Upe2FlLmZyb21Xb3JraW5nQ29sb3JTcGFjZShfdC5jb3B5KHRoaXMpLGUpO2NvbnN0IG49X3QucixzPV90Lmcscj1fdC5iLG89TWF0aC5tYXgobixzLHIpLGE9TWF0aC5taW4obixzLHIpO2xldCBjLGw7Y29uc3QgaD0oYStvKS8yO2lmKGE9PT1vKWM9MCxsPTA7ZWxzZXtjb25zdCB1PW8tYTtzd2l0Y2gobD1oPD0uNT91LyhvK2EpOnUvKDItby1hKSxvKXtjYXNlIG46Yz0ocy1yKS91KyhzPHI/NjowKTticmVhaztjYXNlIHM6Yz0oci1uKS91KzI7YnJlYWs7Y2FzZSByOmM9KG4tcykvdSs0O2JyZWFrfWMvPTZ9cmV0dXJuIHQuaD1jLHQucz1sLHQubD1oLHR9Z2V0UkdCKHQsZT1hZS53b3JraW5nQ29sb3JTcGFjZSl7cmV0dXJuIGFlLmZyb21Xb3JraW5nQ29sb3JTcGFjZShfdC5jb3B5KHRoaXMpLGUpLHQucj1fdC5yLHQuZz1fdC5nLHQuYj1fdC5iLHR9Z2V0U3R5bGUodD1vZSl7YWUuZnJvbVdvcmtpbmdDb2xvclNwYWNlKF90LmNvcHkodGhpcyksdCk7Y29uc3QgZT1fdC5yLG49X3QuZyxzPV90LmI7cmV0dXJuIHQhPT1vZT9gY29sb3IoJHt0fSAke2UudG9GaXhlZCgzKX0gJHtuLnRvRml4ZWQoMyl9ICR7cy50b0ZpeGVkKDMpfSlgOmByZ2IoJHtNYXRoLnJvdW5kKGUqMjU1KX0sJHtNYXRoLnJvdW5kKG4qMjU1KX0sJHtNYXRoLnJvdW5kKHMqMjU1KX0pYH1vZmZzZXRIU0wodCxlLG4pe3JldHVybiB0aGlzLmdldEhTTChqZSksdGhpcy5zZXRIU0woamUuaCt0LGplLnMrZSxqZS5sK24pfWFkZCh0KXtyZXR1cm4gdGhpcy5yKz10LnIsdGhpcy5nKz10LmcsdGhpcy5iKz10LmIsdGhpc31hZGRDb2xvcnModCxlKXtyZXR1cm4gdGhpcy5yPXQucitlLnIsdGhpcy5nPXQuZytlLmcsdGhpcy5iPXQuYitlLmIsdGhpc31hZGRTY2FsYXIodCl7cmV0dXJuIHRoaXMucis9dCx0aGlzLmcrPXQsdGhpcy5iKz10LHRoaXN9c3ViKHQpe3JldHVybiB0aGlzLnI9TWF0aC5tYXgoMCx0aGlzLnItdC5yKSx0aGlzLmc9TWF0aC5tYXgoMCx0aGlzLmctdC5nKSx0aGlzLmI9TWF0aC5tYXgoMCx0aGlzLmItdC5iKSx0aGlzfW11bHRpcGx5KHQpe3JldHVybiB0aGlzLnIqPXQucix0aGlzLmcqPXQuZyx0aGlzLmIqPXQuYix0aGlzfW11bHRpcGx5U2NhbGFyKHQpe3JldHVybiB0aGlzLnIqPXQsdGhpcy5nKj10LHRoaXMuYio9dCx0aGlzfWxlcnAodCxlKXtyZXR1cm4gdGhpcy5yKz0odC5yLXRoaXMucikqZSx0aGlzLmcrPSh0LmctdGhpcy5nKSplLHRoaXMuYis9KHQuYi10aGlzLmIpKmUsdGhpc31sZXJwQ29sb3JzKHQsZSxuKXtyZXR1cm4gdGhpcy5yPXQucisoZS5yLXQucikqbix0aGlzLmc9dC5nKyhlLmctdC5nKSpuLHRoaXMuYj10LmIrKGUuYi10LmIpKm4sdGhpc31sZXJwSFNMKHQsZSl7dGhpcy5nZXRIU0woamUpLHQuZ2V0SFNMKHVzKTtjb25zdCBuPWpyKGplLmgsdXMuaCxlKSxzPWpyKGplLnMsdXMucyxlKSxyPWpyKGplLmwsdXMubCxlKTtyZXR1cm4gdGhpcy5zZXRIU0wobixzLHIpLHRoaXN9c2V0RnJvbVZlY3RvcjModCl7cmV0dXJuIHRoaXMucj10LngsdGhpcy5nPXQueSx0aGlzLmI9dC56LHRoaXN9YXBwbHlNYXRyaXgzKHQpe2NvbnN0IGU9dGhpcy5yLG49dGhpcy5nLHM9dGhpcy5iLHI9dC5lbGVtZW50cztyZXR1cm4gdGhpcy5yPXJbMF0qZStyWzNdKm4rcls2XSpzLHRoaXMuZz1yWzFdKmUrcls0XSpuK3JbN10qcyx0aGlzLmI9clsyXSplK3JbNV0qbityWzhdKnMsdGhpc31lcXVhbHModCl7cmV0dXJuIHQucj09PXRoaXMuciYmdC5nPT09dGhpcy5nJiZ0LmI9PT10aGlzLmJ9ZnJvbUFycmF5KHQsZT0wKXtyZXR1cm4gdGhpcy5yPXRbZV0sdGhpcy5nPXRbZSsxXSx0aGlzLmI9dFtlKzJdLHRoaXN9dG9BcnJheSh0PVtdLGU9MCl7cmV0dXJuIHRbZV09dGhpcy5yLHRbZSsxXT10aGlzLmcsdFtlKzJdPXRoaXMuYix0fWZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKXtyZXR1cm4gdGhpcy5yPXQuZ2V0WChlKSx0aGlzLmc9dC5nZXRZKGUpLHRoaXMuYj10LmdldFooZSksdGhpc310b0pTT04oKXtyZXR1cm4gdGhpcy5nZXRIZXgoKX0qW1N5bWJvbC5pdGVyYXRvcl0oKXt5aWVsZCB0aGlzLnIseWllbGQgdGhpcy5nLHlpZWxkIHRoaXMuYn19O2NvbnN0IF90PW5ldyBmcztmcy5OQU1FUz1UYztsZXQgbmY9MDtjbGFzcyBzZiBleHRlbmRzIGlze2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLmlzTWF0ZXJpYWw9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6bmYrK30pLHRoaXMudXVpZD1CbigpLHRoaXMubmFtZT0iIix0aGlzLnR5cGU9Ik1hdGVyaWFsIix0aGlzLmJsZW5kaW5nPTEsdGhpcy5zaWRlPTAsdGhpcy52ZXJ0ZXhDb2xvcnM9ITEsdGhpcy5vcGFjaXR5PTEsdGhpcy50cmFuc3BhcmVudD0hMSx0aGlzLmFscGhhSGFzaD0hMSx0aGlzLmJsZW5kU3JjPTIwNCx0aGlzLmJsZW5kRHN0PTIwNSx0aGlzLmJsZW5kRXF1YXRpb249MTAwLHRoaXMuYmxlbmRTcmNBbHBoYT1udWxsLHRoaXMuYmxlbmREc3RBbHBoYT1udWxsLHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhPW51bGwsdGhpcy5ibGVuZENvbG9yPW5ldyBmcygwLDAsMCksdGhpcy5ibGVuZEFscGhhPTAsdGhpcy5kZXB0aEZ1bmM9Myx0aGlzLmRlcHRoVGVzdD0hMCx0aGlzLmRlcHRoV3JpdGU9ITAsdGhpcy5zdGVuY2lsV3JpdGVNYXNrPTI1NSx0aGlzLnN0ZW5jaWxGdW5jPTUxOSx0aGlzLnN0ZW5jaWxSZWY9MCx0aGlzLnN0ZW5jaWxGdW5jTWFzaz0yNTUsdGhpcy5zdGVuY2lsRmFpbD03NjgwLHRoaXMuc3RlbmNpbFpGYWlsPTc2ODAsdGhpcy5zdGVuY2lsWlBhc3M9NzY4MCx0aGlzLnN0ZW5jaWxXcml0ZT0hMSx0aGlzLmNsaXBwaW5nUGxhbmVzPW51bGwsdGhpcy5jbGlwSW50ZXJzZWN0aW9uPSExLHRoaXMuY2xpcFNoYWRvd3M9ITEsdGhpcy5zaGFkb3dTaWRlPW51bGwsdGhpcy5jb2xvcldyaXRlPSEwLHRoaXMucHJlY2lzaW9uPW51bGwsdGhpcy5wb2x5Z29uT2Zmc2V0PSExLHRoaXMucG9seWdvbk9mZnNldEZhY3Rvcj0wLHRoaXMucG9seWdvbk9mZnNldFVuaXRzPTAsdGhpcy5kaXRoZXJpbmc9ITEsdGhpcy5hbHBoYVRvQ292ZXJhZ2U9ITEsdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE9ITEsdGhpcy5mb3JjZVNpbmdsZVBhc3M9ITEsdGhpcy5hbGxvd092ZXJyaWRlPSEwLHRoaXMudmlzaWJsZT0hMCx0aGlzLnRvbmVNYXBwZWQ9ITAsdGhpcy51c2VyRGF0YT17fSx0aGlzLnZlcnNpb249MCx0aGlzLl9hbHBoYVRlc3Q9MH1nZXQgYWxwaGFUZXN0KCl7cmV0dXJuIHRoaXMuX2FscGhhVGVzdH1zZXQgYWxwaGFUZXN0KHQpe3RoaXMuX2FscGhhVGVzdD4wIT10PjAmJnRoaXMudmVyc2lvbisrLHRoaXMuX2FscGhhVGVzdD10fW9uQmVmb3JlUmVuZGVyKCl7fW9uQmVmb3JlQ29tcGlsZSgpe31jdXN0b21Qcm9ncmFtQ2FjaGVLZXkoKXtyZXR1cm4gdGhpcy5vbkJlZm9yZUNvbXBpbGUudG9TdHJpbmcoKX1zZXRWYWx1ZXModCl7aWYodCE9PXZvaWQgMClmb3IoY29uc3QgZSBpbiB0KXtjb25zdCBuPXRbZV07aWYobj09PXZvaWQgMCl7Y29uc29sZS53YXJuKGBUSFJFRS5NYXRlcmlhbDogcGFyYW1ldGVyICcke2V9JyBoYXMgdmFsdWUgb2YgdW5kZWZpbmVkLmApO2NvbnRpbnVlfWNvbnN0IHM9dGhpc1tlXTtpZihzPT09dm9pZCAwKXtjb25zb2xlLndhcm4oYFRIUkVFLk1hdGVyaWFsOiAnJHtlfScgaXMgbm90IGEgcHJvcGVydHkgb2YgVEhSRUUuJHt0aGlzLnR5cGV9LmApO2NvbnRpbnVlfXMmJnMuaXNDb2xvcj9zLnNldChuKTpzJiZzLmlzVmVjdG9yMyYmbiYmbi5pc1ZlY3RvcjM/cy5jb3B5KG4pOnRoaXNbZV09bn19dG9KU09OKHQpe2NvbnN0IGU9dD09PXZvaWQgMHx8dHlwZW9mIHQ9PSJzdHJpbmciO2UmJih0PXt0ZXh0dXJlczp7fSxpbWFnZXM6e319KTtjb25zdCBuPXttZXRhZGF0YTp7dmVyc2lvbjo0LjYsdHlwZToiTWF0ZXJpYWwiLGdlbmVyYXRvcjoiTWF0ZXJpYWwudG9KU09OIn19O24udXVpZD10aGlzLnV1aWQsbi50eXBlPXRoaXMudHlwZSx0aGlzLm5hbWUhPT0iIiYmKG4ubmFtZT10aGlzLm5hbWUpLHRoaXMuY29sb3ImJnRoaXMuY29sb3IuaXNDb2xvciYmKG4uY29sb3I9dGhpcy5jb2xvci5nZXRIZXgoKSksdGhpcy5yb3VnaG5lc3MhPT12b2lkIDAmJihuLnJvdWdobmVzcz10aGlzLnJvdWdobmVzcyksdGhpcy5tZXRhbG5lc3MhPT12b2lkIDAmJihuLm1ldGFsbmVzcz10aGlzLm1ldGFsbmVzcyksdGhpcy5zaGVlbiE9PXZvaWQgMCYmKG4uc2hlZW49dGhpcy5zaGVlbiksdGhpcy5zaGVlbkNvbG9yJiZ0aGlzLnNoZWVuQ29sb3IuaXNDb2xvciYmKG4uc2hlZW5Db2xvcj10aGlzLnNoZWVuQ29sb3IuZ2V0SGV4KCkpLHRoaXMuc2hlZW5Sb3VnaG5lc3MhPT12b2lkIDAmJihuLnNoZWVuUm91Z2huZXNzPXRoaXMuc2hlZW5Sb3VnaG5lc3MpLHRoaXMuZW1pc3NpdmUmJnRoaXMuZW1pc3NpdmUuaXNDb2xvciYmKG4uZW1pc3NpdmU9dGhpcy5lbWlzc2l2ZS5nZXRIZXgoKSksdGhpcy5lbWlzc2l2ZUludGVuc2l0eSE9PXZvaWQgMCYmdGhpcy5lbWlzc2l2ZUludGVuc2l0eSE9PTEmJihuLmVtaXNzaXZlSW50ZW5zaXR5PXRoaXMuZW1pc3NpdmVJbnRlbnNpdHkpLHRoaXMuc3BlY3VsYXImJnRoaXMuc3BlY3VsYXIuaXNDb2xvciYmKG4uc3BlY3VsYXI9dGhpcy5zcGVjdWxhci5nZXRIZXgoKSksdGhpcy5zcGVjdWxhckludGVuc2l0eSE9PXZvaWQgMCYmKG4uc3BlY3VsYXJJbnRlbnNpdHk9dGhpcy5zcGVjdWxhckludGVuc2l0eSksdGhpcy5zcGVjdWxhckNvbG9yJiZ0aGlzLnNwZWN1bGFyQ29sb3IuaXNDb2xvciYmKG4uc3BlY3VsYXJDb2xvcj10aGlzLnNwZWN1bGFyQ29sb3IuZ2V0SGV4KCkpLHRoaXMuc2hpbmluZXNzIT09dm9pZCAwJiYobi5zaGluaW5lc3M9dGhpcy5zaGluaW5lc3MpLHRoaXMuY2xlYXJjb2F0IT09dm9pZCAwJiYobi5jbGVhcmNvYXQ9dGhpcy5jbGVhcmNvYXQpLHRoaXMuY2xlYXJjb2F0Um91Z2huZXNzIT09dm9pZCAwJiYobi5jbGVhcmNvYXRSb3VnaG5lc3M9dGhpcy5jbGVhcmNvYXRSb3VnaG5lc3MpLHRoaXMuY2xlYXJjb2F0TWFwJiZ0aGlzLmNsZWFyY29hdE1hcC5pc1RleHR1cmUmJihuLmNsZWFyY29hdE1hcD10aGlzLmNsZWFyY29hdE1hcC50b0pTT04odCkudXVpZCksdGhpcy5jbGVhcmNvYXRSb3VnaG5lc3NNYXAmJnRoaXMuY2xlYXJjb2F0Um91Z2huZXNzTWFwLmlzVGV4dHVyZSYmKG4uY2xlYXJjb2F0Um91Z2huZXNzTWFwPXRoaXMuY2xlYXJjb2F0Um91Z2huZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmNsZWFyY29hdE5vcm1hbE1hcCYmdGhpcy5jbGVhcmNvYXROb3JtYWxNYXAuaXNUZXh0dXJlJiYobi5jbGVhcmNvYXROb3JtYWxNYXA9dGhpcy5jbGVhcmNvYXROb3JtYWxNYXAudG9KU09OKHQpLnV1aWQsbi5jbGVhcmNvYXROb3JtYWxTY2FsZT10aGlzLmNsZWFyY29hdE5vcm1hbFNjYWxlLnRvQXJyYXkoKSksdGhpcy5kaXNwZXJzaW9uIT09dm9pZCAwJiYobi5kaXNwZXJzaW9uPXRoaXMuZGlzcGVyc2lvbiksdGhpcy5pcmlkZXNjZW5jZSE9PXZvaWQgMCYmKG4uaXJpZGVzY2VuY2U9dGhpcy5pcmlkZXNjZW5jZSksdGhpcy5pcmlkZXNjZW5jZUlPUiE9PXZvaWQgMCYmKG4uaXJpZGVzY2VuY2VJT1I9dGhpcy5pcmlkZXNjZW5jZUlPUiksdGhpcy5pcmlkZXNjZW5jZVRoaWNrbmVzc1JhbmdlIT09dm9pZCAwJiYobi5pcmlkZXNjZW5jZVRoaWNrbmVzc1JhbmdlPXRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NSYW5nZSksdGhpcy5pcmlkZXNjZW5jZU1hcCYmdGhpcy5pcmlkZXNjZW5jZU1hcC5pc1RleHR1cmUmJihuLmlyaWRlc2NlbmNlTWFwPXRoaXMuaXJpZGVzY2VuY2VNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXAmJnRoaXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXAuaXNUZXh0dXJlJiYobi5pcmlkZXNjZW5jZVRoaWNrbmVzc01hcD10aGlzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmFuaXNvdHJvcHkhPT12b2lkIDAmJihuLmFuaXNvdHJvcHk9dGhpcy5hbmlzb3Ryb3B5KSx0aGlzLmFuaXNvdHJvcHlSb3RhdGlvbiE9PXZvaWQgMCYmKG4uYW5pc290cm9weVJvdGF0aW9uPXRoaXMuYW5pc290cm9weVJvdGF0aW9uKSx0aGlzLmFuaXNvdHJvcHlNYXAmJnRoaXMuYW5pc290cm9weU1hcC5pc1RleHR1cmUmJihuLmFuaXNvdHJvcHlNYXA9dGhpcy5hbmlzb3Ryb3B5TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLm1hcCYmdGhpcy5tYXAuaXNUZXh0dXJlJiYobi5tYXA9dGhpcy5tYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubWF0Y2FwJiZ0aGlzLm1hdGNhcC5pc1RleHR1cmUmJihuLm1hdGNhcD10aGlzLm1hdGNhcC50b0pTT04odCkudXVpZCksdGhpcy5hbHBoYU1hcCYmdGhpcy5hbHBoYU1hcC5pc1RleHR1cmUmJihuLmFscGhhTWFwPXRoaXMuYWxwaGFNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMubGlnaHRNYXAmJnRoaXMubGlnaHRNYXAuaXNUZXh0dXJlJiYobi5saWdodE1hcD10aGlzLmxpZ2h0TWFwLnRvSlNPTih0KS51dWlkLG4ubGlnaHRNYXBJbnRlbnNpdHk9dGhpcy5saWdodE1hcEludGVuc2l0eSksdGhpcy5hb01hcCYmdGhpcy5hb01hcC5pc1RleHR1cmUmJihuLmFvTWFwPXRoaXMuYW9NYXAudG9KU09OKHQpLnV1aWQsbi5hb01hcEludGVuc2l0eT10aGlzLmFvTWFwSW50ZW5zaXR5KSx0aGlzLmJ1bXBNYXAmJnRoaXMuYnVtcE1hcC5pc1RleHR1cmUmJihuLmJ1bXBNYXA9dGhpcy5idW1wTWFwLnRvSlNPTih0KS51dWlkLG4uYnVtcFNjYWxlPXRoaXMuYnVtcFNjYWxlKSx0aGlzLm5vcm1hbE1hcCYmdGhpcy5ub3JtYWxNYXAuaXNUZXh0dXJlJiYobi5ub3JtYWxNYXA9dGhpcy5ub3JtYWxNYXAudG9KU09OKHQpLnV1aWQsbi5ub3JtYWxNYXBUeXBlPXRoaXMubm9ybWFsTWFwVHlwZSxuLm5vcm1hbFNjYWxlPXRoaXMubm9ybWFsU2NhbGUudG9BcnJheSgpKSx0aGlzLmRpc3BsYWNlbWVudE1hcCYmdGhpcy5kaXNwbGFjZW1lbnRNYXAuaXNUZXh0dXJlJiYobi5kaXNwbGFjZW1lbnRNYXA9dGhpcy5kaXNwbGFjZW1lbnRNYXAudG9KU09OKHQpLnV1aWQsbi5kaXNwbGFjZW1lbnRTY2FsZT10aGlzLmRpc3BsYWNlbWVudFNjYWxlLG4uZGlzcGxhY2VtZW50Qmlhcz10aGlzLmRpc3BsYWNlbWVudEJpYXMpLHRoaXMucm91Z2huZXNzTWFwJiZ0aGlzLnJvdWdobmVzc01hcC5pc1RleHR1cmUmJihuLnJvdWdobmVzc01hcD10aGlzLnJvdWdobmVzc01hcC50b0pTT04odCkudXVpZCksdGhpcy5tZXRhbG5lc3NNYXAmJnRoaXMubWV0YWxuZXNzTWFwLmlzVGV4dHVyZSYmKG4ubWV0YWxuZXNzTWFwPXRoaXMubWV0YWxuZXNzTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmVtaXNzaXZlTWFwJiZ0aGlzLmVtaXNzaXZlTWFwLmlzVGV4dHVyZSYmKG4uZW1pc3NpdmVNYXA9dGhpcy5lbWlzc2l2ZU1hcC50b0pTT04odCkudXVpZCksdGhpcy5zcGVjdWxhck1hcCYmdGhpcy5zcGVjdWxhck1hcC5pc1RleHR1cmUmJihuLnNwZWN1bGFyTWFwPXRoaXMuc3BlY3VsYXJNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuc3BlY3VsYXJJbnRlbnNpdHlNYXAmJnRoaXMuc3BlY3VsYXJJbnRlbnNpdHlNYXAuaXNUZXh0dXJlJiYobi5zcGVjdWxhckludGVuc2l0eU1hcD10aGlzLnNwZWN1bGFySW50ZW5zaXR5TWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnNwZWN1bGFyQ29sb3JNYXAmJnRoaXMuc3BlY3VsYXJDb2xvck1hcC5pc1RleHR1cmUmJihuLnNwZWN1bGFyQ29sb3JNYXA9dGhpcy5zcGVjdWxhckNvbG9yTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLmVudk1hcCYmdGhpcy5lbnZNYXAuaXNUZXh0dXJlJiYobi5lbnZNYXA9dGhpcy5lbnZNYXAudG9KU09OKHQpLnV1aWQsdGhpcy5jb21iaW5lIT09dm9pZCAwJiYobi5jb21iaW5lPXRoaXMuY29tYmluZSkpLHRoaXMuZW52TWFwUm90YXRpb24hPT12b2lkIDAmJihuLmVudk1hcFJvdGF0aW9uPXRoaXMuZW52TWFwUm90YXRpb24udG9BcnJheSgpKSx0aGlzLmVudk1hcEludGVuc2l0eSE9PXZvaWQgMCYmKG4uZW52TWFwSW50ZW5zaXR5PXRoaXMuZW52TWFwSW50ZW5zaXR5KSx0aGlzLnJlZmxlY3Rpdml0eSE9PXZvaWQgMCYmKG4ucmVmbGVjdGl2aXR5PXRoaXMucmVmbGVjdGl2aXR5KSx0aGlzLnJlZnJhY3Rpb25SYXRpbyE9PXZvaWQgMCYmKG4ucmVmcmFjdGlvblJhdGlvPXRoaXMucmVmcmFjdGlvblJhdGlvKSx0aGlzLmdyYWRpZW50TWFwJiZ0aGlzLmdyYWRpZW50TWFwLmlzVGV4dHVyZSYmKG4uZ3JhZGllbnRNYXA9dGhpcy5ncmFkaWVudE1hcC50b0pTT04odCkudXVpZCksdGhpcy50cmFuc21pc3Npb24hPT12b2lkIDAmJihuLnRyYW5zbWlzc2lvbj10aGlzLnRyYW5zbWlzc2lvbiksdGhpcy50cmFuc21pc3Npb25NYXAmJnRoaXMudHJhbnNtaXNzaW9uTWFwLmlzVGV4dHVyZSYmKG4udHJhbnNtaXNzaW9uTWFwPXRoaXMudHJhbnNtaXNzaW9uTWFwLnRvSlNPTih0KS51dWlkKSx0aGlzLnRoaWNrbmVzcyE9PXZvaWQgMCYmKG4udGhpY2tuZXNzPXRoaXMudGhpY2tuZXNzKSx0aGlzLnRoaWNrbmVzc01hcCYmdGhpcy50aGlja25lc3NNYXAuaXNUZXh0dXJlJiYobi50aGlja25lc3NNYXA9dGhpcy50aGlja25lc3NNYXAudG9KU09OKHQpLnV1aWQpLHRoaXMuYXR0ZW51YXRpb25EaXN0YW5jZSE9PXZvaWQgMCYmdGhpcy5hdHRlbnVhdGlvbkRpc3RhbmNlIT09MS8wJiYobi5hdHRlbnVhdGlvbkRpc3RhbmNlPXRoaXMuYXR0ZW51YXRpb25EaXN0YW5jZSksdGhpcy5hdHRlbnVhdGlvbkNvbG9yIT09dm9pZCAwJiYobi5hdHRlbnVhdGlvbkNvbG9yPXRoaXMuYXR0ZW51YXRpb25Db2xvci5nZXRIZXgoKSksdGhpcy5zaXplIT09dm9pZCAwJiYobi5zaXplPXRoaXMuc2l6ZSksdGhpcy5zaGFkb3dTaWRlIT09bnVsbCYmKG4uc2hhZG93U2lkZT10aGlzLnNoYWRvd1NpZGUpLHRoaXMuc2l6ZUF0dGVudWF0aW9uIT09dm9pZCAwJiYobi5zaXplQXR0ZW51YXRpb249dGhpcy5zaXplQXR0ZW51YXRpb24pLHRoaXMuYmxlbmRpbmchPT0xJiYobi5ibGVuZGluZz10aGlzLmJsZW5kaW5nKSx0aGlzLnNpZGUhPT0wJiYobi5zaWRlPXRoaXMuc2lkZSksdGhpcy52ZXJ0ZXhDb2xvcnM9PT0hMCYmKG4udmVydGV4Q29sb3JzPSEwKSx0aGlzLm9wYWNpdHk8MSYmKG4ub3BhY2l0eT10aGlzLm9wYWNpdHkpLHRoaXMudHJhbnNwYXJlbnQ9PT0hMCYmKG4udHJhbnNwYXJlbnQ9ITApLHRoaXMuYmxlbmRTcmMhPT0yMDQmJihuLmJsZW5kU3JjPXRoaXMuYmxlbmRTcmMpLHRoaXMuYmxlbmREc3QhPT0yMDUmJihuLmJsZW5kRHN0PXRoaXMuYmxlbmREc3QpLHRoaXMuYmxlbmRFcXVhdGlvbiE9PTEwMCYmKG4uYmxlbmRFcXVhdGlvbj10aGlzLmJsZW5kRXF1YXRpb24pLHRoaXMuYmxlbmRTcmNBbHBoYSE9PW51bGwmJihuLmJsZW5kU3JjQWxwaGE9dGhpcy5ibGVuZFNyY0FscGhhKSx0aGlzLmJsZW5kRHN0QWxwaGEhPT1udWxsJiYobi5ibGVuZERzdEFscGhhPXRoaXMuYmxlbmREc3RBbHBoYSksdGhpcy5ibGVuZEVxdWF0aW9uQWxwaGEhPT1udWxsJiYobi5ibGVuZEVxdWF0aW9uQWxwaGE9dGhpcy5ibGVuZEVxdWF0aW9uQWxwaGEpLHRoaXMuYmxlbmRDb2xvciYmdGhpcy5ibGVuZENvbG9yLmlzQ29sb3ImJihuLmJsZW5kQ29sb3I9dGhpcy5ibGVuZENvbG9yLmdldEhleCgpKSx0aGlzLmJsZW5kQWxwaGEhPT0wJiYobi5ibGVuZEFscGhhPXRoaXMuYmxlbmRBbHBoYSksdGhpcy5kZXB0aEZ1bmMhPT0zJiYobi5kZXB0aEZ1bmM9dGhpcy5kZXB0aEZ1bmMpLHRoaXMuZGVwdGhUZXN0PT09ITEmJihuLmRlcHRoVGVzdD10aGlzLmRlcHRoVGVzdCksdGhpcy5kZXB0aFdyaXRlPT09ITEmJihuLmRlcHRoV3JpdGU9dGhpcy5kZXB0aFdyaXRlKSx0aGlzLmNvbG9yV3JpdGU9PT0hMSYmKG4uY29sb3JXcml0ZT10aGlzLmNvbG9yV3JpdGUpLHRoaXMuc3RlbmNpbFdyaXRlTWFzayE9PTI1NSYmKG4uc3RlbmNpbFdyaXRlTWFzaz10aGlzLnN0ZW5jaWxXcml0ZU1hc2spLHRoaXMuc3RlbmNpbEZ1bmMhPT01MTkmJihuLnN0ZW5jaWxGdW5jPXRoaXMuc3RlbmNpbEZ1bmMpLHRoaXMuc3RlbmNpbFJlZiE9PTAmJihuLnN0ZW5jaWxSZWY9dGhpcy5zdGVuY2lsUmVmKSx0aGlzLnN0ZW5jaWxGdW5jTWFzayE9PTI1NSYmKG4uc3RlbmNpbEZ1bmNNYXNrPXRoaXMuc3RlbmNpbEZ1bmNNYXNrKSx0aGlzLnN0ZW5jaWxGYWlsIT09NzY4MCYmKG4uc3RlbmNpbEZhaWw9dGhpcy5zdGVuY2lsRmFpbCksdGhpcy5zdGVuY2lsWkZhaWwhPT03NjgwJiYobi5zdGVuY2lsWkZhaWw9dGhpcy5zdGVuY2lsWkZhaWwpLHRoaXMuc3RlbmNpbFpQYXNzIT09NzY4MCYmKG4uc3RlbmNpbFpQYXNzPXRoaXMuc3RlbmNpbFpQYXNzKSx0aGlzLnN0ZW5jaWxXcml0ZT09PSEwJiYobi5zdGVuY2lsV3JpdGU9dGhpcy5zdGVuY2lsV3JpdGUpLHRoaXMucm90YXRpb24hPT12b2lkIDAmJnRoaXMucm90YXRpb24hPT0wJiYobi5yb3RhdGlvbj10aGlzLnJvdGF0aW9uKSx0aGlzLnBvbHlnb25PZmZzZXQ9PT0hMCYmKG4ucG9seWdvbk9mZnNldD0hMCksdGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yIT09MCYmKG4ucG9seWdvbk9mZnNldEZhY3Rvcj10aGlzLnBvbHlnb25PZmZzZXRGYWN0b3IpLHRoaXMucG9seWdvbk9mZnNldFVuaXRzIT09MCYmKG4ucG9seWdvbk9mZnNldFVuaXRzPXRoaXMucG9seWdvbk9mZnNldFVuaXRzKSx0aGlzLmxpbmV3aWR0aCE9PXZvaWQgMCYmdGhpcy5saW5ld2lkdGghPT0xJiYobi5saW5ld2lkdGg9dGhpcy5saW5ld2lkdGgpLHRoaXMuZGFzaFNpemUhPT12b2lkIDAmJihuLmRhc2hTaXplPXRoaXMuZGFzaFNpemUpLHRoaXMuZ2FwU2l6ZSE9PXZvaWQgMCYmKG4uZ2FwU2l6ZT10aGlzLmdhcFNpemUpLHRoaXMuc2NhbGUhPT12b2lkIDAmJihuLnNjYWxlPXRoaXMuc2NhbGUpLHRoaXMuZGl0aGVyaW5nPT09ITAmJihuLmRpdGhlcmluZz0hMCksdGhpcy5hbHBoYVRlc3Q+MCYmKG4uYWxwaGFUZXN0PXRoaXMuYWxwaGFUZXN0KSx0aGlzLmFscGhhSGFzaD09PSEwJiYobi5hbHBoYUhhc2g9ITApLHRoaXMuYWxwaGFUb0NvdmVyYWdlPT09ITAmJihuLmFscGhhVG9Db3ZlcmFnZT0hMCksdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE9PT0hMCYmKG4ucHJlbXVsdGlwbGllZEFscGhhPSEwKSx0aGlzLmZvcmNlU2luZ2xlUGFzcz09PSEwJiYobi5mb3JjZVNpbmdsZVBhc3M9ITApLHRoaXMud2lyZWZyYW1lPT09ITAmJihuLndpcmVmcmFtZT0hMCksdGhpcy53aXJlZnJhbWVMaW5ld2lkdGg+MSYmKG4ud2lyZWZyYW1lTGluZXdpZHRoPXRoaXMud2lyZWZyYW1lTGluZXdpZHRoKSx0aGlzLndpcmVmcmFtZUxpbmVjYXAhPT0icm91bmQiJiYobi53aXJlZnJhbWVMaW5lY2FwPXRoaXMud2lyZWZyYW1lTGluZWNhcCksdGhpcy53aXJlZnJhbWVMaW5lam9pbiE9PSJyb3VuZCImJihuLndpcmVmcmFtZUxpbmVqb2luPXRoaXMud2lyZWZyYW1lTGluZWpvaW4pLHRoaXMuZmxhdFNoYWRpbmc9PT0hMCYmKG4uZmxhdFNoYWRpbmc9ITApLHRoaXMudmlzaWJsZT09PSExJiYobi52aXNpYmxlPSExKSx0aGlzLnRvbmVNYXBwZWQ9PT0hMSYmKG4udG9uZU1hcHBlZD0hMSksdGhpcy5mb2c9PT0hMSYmKG4uZm9nPSExKSxPYmplY3Qua2V5cyh0aGlzLnVzZXJEYXRhKS5sZW5ndGg+MCYmKG4udXNlckRhdGE9dGhpcy51c2VyRGF0YSk7ZnVuY3Rpb24gcyhyKXtjb25zdCBvPVtdO2Zvcihjb25zdCBhIGluIHIpe2NvbnN0IGM9clthXTtkZWxldGUgYy5tZXRhZGF0YSxvLnB1c2goYyl9cmV0dXJuIG99aWYoZSl7Y29uc3Qgcj1zKHQudGV4dHVyZXMpLG89cyh0LmltYWdlcyk7ci5sZW5ndGg+MCYmKG4udGV4dHVyZXM9ciksby5sZW5ndGg+MCYmKG4uaW1hZ2VzPW8pfXJldHVybiBufWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1jb3B5KHQpe3RoaXMubmFtZT10Lm5hbWUsdGhpcy5ibGVuZGluZz10LmJsZW5kaW5nLHRoaXMuc2lkZT10LnNpZGUsdGhpcy52ZXJ0ZXhDb2xvcnM9dC52ZXJ0ZXhDb2xvcnMsdGhpcy5vcGFjaXR5PXQub3BhY2l0eSx0aGlzLnRyYW5zcGFyZW50PXQudHJhbnNwYXJlbnQsdGhpcy5ibGVuZFNyYz10LmJsZW5kU3JjLHRoaXMuYmxlbmREc3Q9dC5ibGVuZERzdCx0aGlzLmJsZW5kRXF1YXRpb249dC5ibGVuZEVxdWF0aW9uLHRoaXMuYmxlbmRTcmNBbHBoYT10LmJsZW5kU3JjQWxwaGEsdGhpcy5ibGVuZERzdEFscGhhPXQuYmxlbmREc3RBbHBoYSx0aGlzLmJsZW5kRXF1YXRpb25BbHBoYT10LmJsZW5kRXF1YXRpb25BbHBoYSx0aGlzLmJsZW5kQ29sb3IuY29weSh0LmJsZW5kQ29sb3IpLHRoaXMuYmxlbmRBbHBoYT10LmJsZW5kQWxwaGEsdGhpcy5kZXB0aEZ1bmM9dC5kZXB0aEZ1bmMsdGhpcy5kZXB0aFRlc3Q9dC5kZXB0aFRlc3QsdGhpcy5kZXB0aFdyaXRlPXQuZGVwdGhXcml0ZSx0aGlzLnN0ZW5jaWxXcml0ZU1hc2s9dC5zdGVuY2lsV3JpdGVNYXNrLHRoaXMuc3RlbmNpbEZ1bmM9dC5zdGVuY2lsRnVuYyx0aGlzLnN0ZW5jaWxSZWY9dC5zdGVuY2lsUmVmLHRoaXMuc3RlbmNpbEZ1bmNNYXNrPXQuc3RlbmNpbEZ1bmNNYXNrLHRoaXMuc3RlbmNpbEZhaWw9dC5zdGVuY2lsRmFpbCx0aGlzLnN0ZW5jaWxaRmFpbD10LnN0ZW5jaWxaRmFpbCx0aGlzLnN0ZW5jaWxaUGFzcz10LnN0ZW5jaWxaUGFzcyx0aGlzLnN0ZW5jaWxXcml0ZT10LnN0ZW5jaWxXcml0ZTtjb25zdCBlPXQuY2xpcHBpbmdQbGFuZXM7bGV0IG49bnVsbDtpZihlIT09bnVsbCl7Y29uc3Qgcz1lLmxlbmd0aDtuPW5ldyBBcnJheShzKTtmb3IobGV0IHI9MDtyIT09czsrK3IpbltyXT1lW3JdLmNsb25lKCl9cmV0dXJuIHRoaXMuY2xpcHBpbmdQbGFuZXM9bix0aGlzLmNsaXBJbnRlcnNlY3Rpb249dC5jbGlwSW50ZXJzZWN0aW9uLHRoaXMuY2xpcFNoYWRvd3M9dC5jbGlwU2hhZG93cyx0aGlzLnNoYWRvd1NpZGU9dC5zaGFkb3dTaWRlLHRoaXMuY29sb3JXcml0ZT10LmNvbG9yV3JpdGUsdGhpcy5wcmVjaXNpb249dC5wcmVjaXNpb24sdGhpcy5wb2x5Z29uT2Zmc2V0PXQucG9seWdvbk9mZnNldCx0aGlzLnBvbHlnb25PZmZzZXRGYWN0b3I9dC5wb2x5Z29uT2Zmc2V0RmFjdG9yLHRoaXMucG9seWdvbk9mZnNldFVuaXRzPXQucG9seWdvbk9mZnNldFVuaXRzLHRoaXMuZGl0aGVyaW5nPXQuZGl0aGVyaW5nLHRoaXMuYWxwaGFUZXN0PXQuYWxwaGFUZXN0LHRoaXMuYWxwaGFIYXNoPXQuYWxwaGFIYXNoLHRoaXMuYWxwaGFUb0NvdmVyYWdlPXQuYWxwaGFUb0NvdmVyYWdlLHRoaXMucHJlbXVsdGlwbGllZEFscGhhPXQucHJlbXVsdGlwbGllZEFscGhhLHRoaXMuZm9yY2VTaW5nbGVQYXNzPXQuZm9yY2VTaW5nbGVQYXNzLHRoaXMudmlzaWJsZT10LnZpc2libGUsdGhpcy50b25lTWFwcGVkPXQudG9uZU1hcHBlZCx0aGlzLnVzZXJEYXRhPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodC51c2VyRGF0YSkpLHRoaXN9ZGlzcG9zZSgpe3RoaXMuZGlzcGF0Y2hFdmVudCh7dHlwZToiZGlzcG9zZSJ9KX1zZXQgbmVlZHNVcGRhdGUodCl7dD09PSEwJiZ0aGlzLnZlcnNpb24rK319Y2xhc3MgcmYgZXh0ZW5kcyBzZntjb25zdHJ1Y3Rvcih0KXtzdXBlcigpLHRoaXMuaXNNZXNoQmFzaWNNYXRlcmlhbD0hMCx0aGlzLnR5cGU9Ik1lc2hCYXNpY01hdGVyaWFsIix0aGlzLmNvbG9yPW5ldyBmcygxNjc3NzIxNSksdGhpcy5tYXA9bnVsbCx0aGlzLmxpZ2h0TWFwPW51bGwsdGhpcy5saWdodE1hcEludGVuc2l0eT0xLHRoaXMuYW9NYXA9bnVsbCx0aGlzLmFvTWFwSW50ZW5zaXR5PTEsdGhpcy5zcGVjdWxhck1hcD1udWxsLHRoaXMuYWxwaGFNYXA9bnVsbCx0aGlzLmVudk1hcD1udWxsLHRoaXMuZW52TWFwUm90YXRpb249bmV3IHhpLHRoaXMuY29tYmluZT0wLHRoaXMucmVmbGVjdGl2aXR5PTEsdGhpcy5yZWZyYWN0aW9uUmF0aW89Ljk4LHRoaXMud2lyZWZyYW1lPSExLHRoaXMud2lyZWZyYW1lTGluZXdpZHRoPTEsdGhpcy53aXJlZnJhbWVMaW5lY2FwPSJyb3VuZCIsdGhpcy53aXJlZnJhbWVMaW5lam9pbj0icm91bmQiLHRoaXMuZm9nPSEwLHRoaXMuc2V0VmFsdWVzKHQpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5jb2xvci5jb3B5KHQuY29sb3IpLHRoaXMubWFwPXQubWFwLHRoaXMubGlnaHRNYXA9dC5saWdodE1hcCx0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5PXQubGlnaHRNYXBJbnRlbnNpdHksdGhpcy5hb01hcD10LmFvTWFwLHRoaXMuYW9NYXBJbnRlbnNpdHk9dC5hb01hcEludGVuc2l0eSx0aGlzLnNwZWN1bGFyTWFwPXQuc3BlY3VsYXJNYXAsdGhpcy5hbHBoYU1hcD10LmFscGhhTWFwLHRoaXMuZW52TWFwPXQuZW52TWFwLHRoaXMuZW52TWFwUm90YXRpb24uY29weSh0LmVudk1hcFJvdGF0aW9uKSx0aGlzLmNvbWJpbmU9dC5jb21iaW5lLHRoaXMucmVmbGVjdGl2aXR5PXQucmVmbGVjdGl2aXR5LHRoaXMucmVmcmFjdGlvblJhdGlvPXQucmVmcmFjdGlvblJhdGlvLHRoaXMud2lyZWZyYW1lPXQud2lyZWZyYW1lLHRoaXMud2lyZWZyYW1lTGluZXdpZHRoPXQud2lyZWZyYW1lTGluZXdpZHRoLHRoaXMud2lyZWZyYW1lTGluZWNhcD10LndpcmVmcmFtZUxpbmVjYXAsdGhpcy53aXJlZnJhbWVMaW5lam9pbj10LndpcmVmcmFtZUxpbmVqb2luLHRoaXMuZm9nPXQuZm9nLHRoaXN9fWNvbnN0IHB0PW5ldyBULGRzPW5ldyBSO2xldCBvZj0wO2NsYXNzIHh0e2NvbnN0cnVjdG9yKHQsZSxuPSExKXtpZihBcnJheS5pc0FycmF5KHQpKXRocm93IG5ldyBUeXBlRXJyb3IoIlRIUkVFLkJ1ZmZlckF0dHJpYnV0ZTogYXJyYXkgc2hvdWxkIGJlIGEgVHlwZWQgQXJyYXkuIik7dGhpcy5pc0J1ZmZlckF0dHJpYnV0ZT0hMCxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiaWQiLHt2YWx1ZTpvZisrfSksdGhpcy5uYW1lPSIiLHRoaXMuYXJyYXk9dCx0aGlzLml0ZW1TaXplPWUsdGhpcy5jb3VudD10IT09dm9pZCAwP3QubGVuZ3RoL2U6MCx0aGlzLm5vcm1hbGl6ZWQ9bix0aGlzLnVzYWdlPTM1MDQ0LHRoaXMudXBkYXRlUmFuZ2VzPVtdLHRoaXMuZ3B1VHlwZT0xMDE1LHRoaXMudmVyc2lvbj0wfW9uVXBsb2FkQ2FsbGJhY2soKXt9c2V0IG5lZWRzVXBkYXRlKHQpe3Q9PT0hMCYmdGhpcy52ZXJzaW9uKyt9c2V0VXNhZ2UodCl7cmV0dXJuIHRoaXMudXNhZ2U9dCx0aGlzfWFkZFVwZGF0ZVJhbmdlKHQsZSl7dGhpcy51cGRhdGVSYW5nZXMucHVzaCh7c3RhcnQ6dCxjb3VudDplfSl9Y2xlYXJVcGRhdGVSYW5nZXMoKXt0aGlzLnVwZGF0ZVJhbmdlcy5sZW5ndGg9MH1jb3B5KHQpe3JldHVybiB0aGlzLm5hbWU9dC5uYW1lLHRoaXMuYXJyYXk9bmV3IHQuYXJyYXkuY29uc3RydWN0b3IodC5hcnJheSksdGhpcy5pdGVtU2l6ZT10Lml0ZW1TaXplLHRoaXMuY291bnQ9dC5jb3VudCx0aGlzLm5vcm1hbGl6ZWQ9dC5ub3JtYWxpemVkLHRoaXMudXNhZ2U9dC51c2FnZSx0aGlzLmdwdVR5cGU9dC5ncHVUeXBlLHRoaXN9Y29weUF0KHQsZSxuKXt0Kj10aGlzLml0ZW1TaXplLG4qPWUuaXRlbVNpemU7Zm9yKGxldCBzPTAscj10aGlzLml0ZW1TaXplO3M8cjtzKyspdGhpcy5hcnJheVt0K3NdPWUuYXJyYXlbbitzXTtyZXR1cm4gdGhpc31jb3B5QXJyYXkodCl7cmV0dXJuIHRoaXMuYXJyYXkuc2V0KHQpLHRoaXN9YXBwbHlNYXRyaXgzKHQpe2lmKHRoaXMuaXRlbVNpemU9PT0yKWZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKWRzLmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxkcy5hcHBseU1hdHJpeDModCksdGhpcy5zZXRYWShlLGRzLngsZHMueSk7ZWxzZSBpZih0aGlzLml0ZW1TaXplPT09Mylmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQuYXBwbHlNYXRyaXgzKHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfWFwcGx5TWF0cml4NCh0KXtmb3IobGV0IGU9MCxuPXRoaXMuY291bnQ7ZTxuO2UrKylwdC5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsZSkscHQuYXBwbHlNYXRyaXg0KHQpLHRoaXMuc2V0WFlaKGUscHQueCxwdC55LHB0LnopO3JldHVybiB0aGlzfWFwcGx5Tm9ybWFsTWF0cml4KHQpe2ZvcihsZXQgZT0wLG49dGhpcy5jb3VudDtlPG47ZSsrKXB0LmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcyxlKSxwdC5hcHBseU5vcm1hbE1hdHJpeCh0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc310cmFuc2Zvcm1EaXJlY3Rpb24odCl7Zm9yKGxldCBlPTAsbj10aGlzLmNvdW50O2U8bjtlKyspcHQuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0aGlzLGUpLHB0LnRyYW5zZm9ybURpcmVjdGlvbih0KSx0aGlzLnNldFhZWihlLHB0LngscHQueSxwdC56KTtyZXR1cm4gdGhpc31zZXQodCxlPTApe3JldHVybiB0aGlzLmFycmF5LnNldCh0LGUpLHRoaXN9Z2V0Q29tcG9uZW50KHQsZSl7bGV0IG49dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrZV07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKG49cGkobix0aGlzLmFycmF5KSksbn1zZXRDb21wb25lbnQodCxlLG4pe3JldHVybiB0aGlzLm5vcm1hbGl6ZWQmJihuPUl0KG4sdGhpcy5hcnJheSkpLHRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplK2VdPW4sdGhpc31nZXRYKHQpe2xldCBlPXRoaXMuYXJyYXlbdCp0aGlzLml0ZW1TaXplXTtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1waShlLHRoaXMuYXJyYXkpKSxlfXNldFgodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QqdGhpcy5pdGVtU2l6ZV09ZSx0aGlzfWdldFkodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMV07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9cGkoZSx0aGlzLmFycmF5KSksZX1zZXRZKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMV09ZSx0aGlzfWdldFoodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMl07cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9cGkoZSx0aGlzLmFycmF5KSksZX1zZXRaKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrMl09ZSx0aGlzfWdldFcodCl7bGV0IGU9dGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrM107cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9cGkoZSx0aGlzLmFycmF5KSksZX1zZXRXKHQsZSl7cmV0dXJuIHRoaXMubm9ybWFsaXplZCYmKGU9SXQoZSx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KnRoaXMuaXRlbVNpemUrM109ZSx0aGlzfXNldFhZKHQsZSxuKXtyZXR1cm4gdCo9dGhpcy5pdGVtU2l6ZSx0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSksbj1JdChuLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QrMF09ZSx0aGlzLmFycmF5W3QrMV09bix0aGlzfXNldFhZWih0LGUsbixzKXtyZXR1cm4gdCo9dGhpcy5pdGVtU2l6ZSx0aGlzLm5vcm1hbGl6ZWQmJihlPUl0KGUsdGhpcy5hcnJheSksbj1JdChuLHRoaXMuYXJyYXkpLHM9SXQocyx0aGlzLmFycmF5KSksdGhpcy5hcnJheVt0KzBdPWUsdGhpcy5hcnJheVt0KzFdPW4sdGhpcy5hcnJheVt0KzJdPXMsdGhpc31zZXRYWVpXKHQsZSxuLHMscil7cmV0dXJuIHQqPXRoaXMuaXRlbVNpemUsdGhpcy5ub3JtYWxpemVkJiYoZT1JdChlLHRoaXMuYXJyYXkpLG49SXQobix0aGlzLmFycmF5KSxzPUl0KHMsdGhpcy5hcnJheSkscj1JdChyLHRoaXMuYXJyYXkpKSx0aGlzLmFycmF5W3QrMF09ZSx0aGlzLmFycmF5W3QrMV09bix0aGlzLmFycmF5W3QrMl09cyx0aGlzLmFycmF5W3QrM109cix0aGlzfW9uVXBsb2FkKHQpe3JldHVybiB0aGlzLm9uVXBsb2FkQ2FsbGJhY2s9dCx0aGlzfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuYXJyYXksdGhpcy5pdGVtU2l6ZSkuY29weSh0aGlzKX10b0pTT04oKXtjb25zdCB0PXtpdGVtU2l6ZTp0aGlzLml0ZW1TaXplLHR5cGU6dGhpcy5hcnJheS5jb25zdHJ1Y3Rvci5uYW1lLGFycmF5OkFycmF5LmZyb20odGhpcy5hcnJheSksbm9ybWFsaXplZDp0aGlzLm5vcm1hbGl6ZWR9O3JldHVybiB0aGlzLm5hbWUhPT0iIiYmKHQubmFtZT10aGlzLm5hbWUpLHRoaXMudXNhZ2UhPT0zNTA0NCYmKHQudXNhZ2U9dGhpcy51c2FnZSksdH19Y2xhc3MgYWYgZXh0ZW5kcyB4dHtjb25zdHJ1Y3Rvcih0LGUsbil7c3VwZXIobmV3IFVpbnQxNkFycmF5KHQpLGUsbil9fWNsYXNzIGNmIGV4dGVuZHMgeHR7Y29uc3RydWN0b3IodCxlLG4pe3N1cGVyKG5ldyBVaW50MzJBcnJheSh0KSxlLG4pfX1jbGFzcyBDZSBleHRlbmRzIHh0e2NvbnN0cnVjdG9yKHQsZSxuKXtzdXBlcihuZXcgRmxvYXQzMkFycmF5KHQpLGUsbil9fWxldCBsZj0wO2NvbnN0IGp0PW5ldyBzdCx4bz1uZXcgVGUsVm49bmV3IFQsVXQ9bmV3IGd0LGJpPW5ldyBndCxidD1uZXcgVDtjbGFzcyB1ZSBleHRlbmRzIGlze2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLmlzQnVmZmVyR2VvbWV0cnk9ITAsT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImlkIix7dmFsdWU6bGYrK30pLHRoaXMudXVpZD1CbigpLHRoaXMubmFtZT0iIix0aGlzLnR5cGU9IkJ1ZmZlckdlb21ldHJ5Iix0aGlzLmluZGV4PW51bGwsdGhpcy5pbmRpcmVjdD1udWxsLHRoaXMuYXR0cmlidXRlcz17fSx0aGlzLm1vcnBoQXR0cmlidXRlcz17fSx0aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPSExLHRoaXMuZ3JvdXBzPVtdLHRoaXMuYm91bmRpbmdCb3g9bnVsbCx0aGlzLmJvdW5kaW5nU3BoZXJlPW51bGwsdGhpcy5kcmF3UmFuZ2U9e3N0YXJ0OjAsY291bnQ6MS8wfSx0aGlzLnVzZXJEYXRhPXt9fWdldEluZGV4KCl7cmV0dXJuIHRoaXMuaW5kZXh9c2V0SW5kZXgodCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/dGhpcy5pbmRleD1uZXcoVnUodCk/Y2Y6YWYpKHQsMSk6dGhpcy5pbmRleD10LHRoaXN9c2V0SW5kaXJlY3QodCl7cmV0dXJuIHRoaXMuaW5kaXJlY3Q9dCx0aGlzfWdldEluZGlyZWN0KCl7cmV0dXJuIHRoaXMuaW5kaXJlY3R9Z2V0QXR0cmlidXRlKHQpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF19c2V0QXR0cmlidXRlKHQsZSl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XT1lLHRoaXN9ZGVsZXRlQXR0cmlidXRlKHQpe3JldHVybiBkZWxldGUgdGhpcy5hdHRyaWJ1dGVzW3RdLHRoaXN9aGFzQXR0cmlidXRlKHQpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF0hPT12b2lkIDB9YWRkR3JvdXAodCxlLG49MCl7dGhpcy5ncm91cHMucHVzaCh7c3RhcnQ6dCxjb3VudDplLG1hdGVyaWFsSW5kZXg6bn0pfWNsZWFyR3JvdXBzKCl7dGhpcy5ncm91cHM9W119c2V0RHJhd1JhbmdlKHQsZSl7dGhpcy5kcmF3UmFuZ2Uuc3RhcnQ9dCx0aGlzLmRyYXdSYW5nZS5jb3VudD1lfWFwcGx5TWF0cml4NCh0KXtjb25zdCBlPXRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbjtlIT09dm9pZCAwJiYoZS5hcHBseU1hdHJpeDQodCksZS5uZWVkc1VwZGF0ZT0hMCk7Y29uc3Qgbj10aGlzLmF0dHJpYnV0ZXMubm9ybWFsO2lmKG4hPT12b2lkIDApe2NvbnN0IHI9bmV3IGdlKCkuZ2V0Tm9ybWFsTWF0cml4KHQpO24uYXBwbHlOb3JtYWxNYXRyaXgociksbi5uZWVkc1VwZGF0ZT0hMH1jb25zdCBzPXRoaXMuYXR0cmlidXRlcy50YW5nZW50O3JldHVybiBzIT09dm9pZCAwJiYocy50cmFuc2Zvcm1EaXJlY3Rpb24odCkscy5uZWVkc1VwZGF0ZT0hMCksdGhpcy5ib3VuZGluZ0JveCE9PW51bGwmJnRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCksdGhpcy5ib3VuZGluZ1NwaGVyZSE9PW51bGwmJnRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCksdGhpc31hcHBseVF1YXRlcm5pb24odCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXJvdGF0ZVgodCl7cmV0dXJuIGp0Lm1ha2VSb3RhdGlvblgodCksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9cm90YXRlWSh0KXtyZXR1cm4ganQubWFrZVJvdGF0aW9uWSh0KSx0aGlzLmFwcGx5TWF0cml4NChqdCksdGhpc31yb3RhdGVaKHQpe3JldHVybiBqdC5tYWtlUm90YXRpb25aKHQpLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfXRyYW5zbGF0ZSh0LGUsbil7cmV0dXJuIGp0Lm1ha2VUcmFuc2xhdGlvbih0LGUsbiksdGhpcy5hcHBseU1hdHJpeDQoanQpLHRoaXN9c2NhbGUodCxlLG4pe3JldHVybiBqdC5tYWtlU2NhbGUodCxlLG4pLHRoaXMuYXBwbHlNYXRyaXg0KGp0KSx0aGlzfWxvb2tBdCh0KXtyZXR1cm4geG8ubG9va0F0KHQpLHhvLnVwZGF0ZU1hdHJpeCgpLHRoaXMuYXBwbHlNYXRyaXg0KHhvLm1hdHJpeCksdGhpc31jZW50ZXIoKXtyZXR1cm4gdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKSx0aGlzLmJvdW5kaW5nQm94LmdldENlbnRlcihWbikubmVnYXRlKCksdGhpcy50cmFuc2xhdGUoVm4ueCxWbi55LFZuLnopLHRoaXN9c2V0RnJvbVBvaW50cyh0KXtjb25zdCBlPXRoaXMuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpO2lmKGU9PT12b2lkIDApe2NvbnN0IG49W107Zm9yKGxldCBzPTAscj10Lmxlbmd0aDtzPHI7cysrKXtjb25zdCBvPXRbc107bi5wdXNoKG8ueCxvLnksby56fHwwKX10aGlzLnNldEF0dHJpYnV0ZSgicG9zaXRpb24iLG5ldyBDZShuLDMpKX1lbHNle2NvbnN0IG49TWF0aC5taW4odC5sZW5ndGgsZS5jb3VudCk7Zm9yKGxldCBzPTA7czxuO3MrKyl7Y29uc3Qgcj10W3NdO2Uuc2V0WFlaKHMsci54LHIueSxyLnp8fDApfXQubGVuZ3RoPmUuY291bnQmJmNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnk6IEJ1ZmZlciBzaXplIHRvbyBzbWFsbCBmb3IgcG9pbnRzIGRhdGEuIFVzZSAuZGlzcG9zZSgpIGFuZCBjcmVhdGUgYSBuZXcgZ2VvbWV0cnkuIiksZS5uZWVkc1VwZGF0ZT0hMH1yZXR1cm4gdGhpc31jb21wdXRlQm91bmRpbmdCb3goKXt0aGlzLmJvdW5kaW5nQm94PT09bnVsbCYmKHRoaXMuYm91bmRpbmdCb3g9bmV3IGd0KTtjb25zdCB0PXRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbixlPXRoaXMubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uO2lmKHQmJnQuaXNHTEJ1ZmZlckF0dHJpYnV0ZSl7Y29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94KCk6IEdMQnVmZmVyQXR0cmlidXRlIHJlcXVpcmVzIGEgbWFudWFsIGJvdW5kaW5nIGJveC4iLHRoaXMpLHRoaXMuYm91bmRpbmdCb3guc2V0KG5ldyBUKC0xLzAsLTEvMCwtMS8wKSxuZXcgVCgxLzAsMS8wLDEvMCkpO3JldHVybn1pZih0IT09dm9pZCAwKXtpZih0aGlzLmJvdW5kaW5nQm94LnNldEZyb21CdWZmZXJBdHRyaWJ1dGUodCksZSlmb3IobGV0IG49MCxzPWUubGVuZ3RoO248cztuKyspe2NvbnN0IHI9ZVtuXTtVdC5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKHIpLHRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU/KGJ0LmFkZFZlY3RvcnModGhpcy5ib3VuZGluZ0JveC5taW4sVXQubWluKSx0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoYnQpLGJ0LmFkZFZlY3RvcnModGhpcy5ib3VuZGluZ0JveC5tYXgsVXQubWF4KSx0aGlzLmJvdW5kaW5nQm94LmV4cGFuZEJ5UG9pbnQoYnQpKToodGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KFV0Lm1pbiksdGhpcy5ib3VuZGluZ0JveC5leHBhbmRCeVBvaW50KFV0Lm1heCkpfX1lbHNlIHRoaXMuYm91bmRpbmdCb3gubWFrZUVtcHR5KCk7KGlzTmFOKHRoaXMuYm91bmRpbmdCb3gubWluLngpfHxpc05hTih0aGlzLmJvdW5kaW5nQm94Lm1pbi55KXx8aXNOYU4odGhpcy5ib3VuZGluZ0JveC5taW4ueikpJiZjb25zb2xlLmVycm9yKCdUSFJFRS5CdWZmZXJHZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTogQ29tcHV0ZWQgbWluL21heCBoYXZlIE5hTiB2YWx1ZXMuIFRoZSAicG9zaXRpb24iIGF0dHJpYnV0ZSBpcyBsaWtlbHkgdG8gaGF2ZSBOYU4gdmFsdWVzLicsdGhpcyl9Y29tcHV0ZUJvdW5kaW5nU3BoZXJlKCl7dGhpcy5ib3VuZGluZ1NwaGVyZT09PW51bGwmJih0aGlzLmJvdW5kaW5nU3BoZXJlPW5ldyBpbyk7Y29uc3QgdD10aGlzLmF0dHJpYnV0ZXMucG9zaXRpb24sZT10aGlzLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbjtpZih0JiZ0LmlzR0xCdWZmZXJBdHRyaWJ1dGUpe2NvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpOiBHTEJ1ZmZlckF0dHJpYnV0ZSByZXF1aXJlcyBhIG1hbnVhbCBib3VuZGluZyBzcGhlcmUuIix0aGlzKSx0aGlzLmJvdW5kaW5nU3BoZXJlLnNldChuZXcgVCwxLzApO3JldHVybn1pZih0KXtjb25zdCBuPXRoaXMuYm91bmRpbmdTcGhlcmUuY2VudGVyO2lmKFV0LnNldEZyb21CdWZmZXJBdHRyaWJ1dGUodCksZSlmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVtyXTtiaS5zZXRGcm9tQnVmZmVyQXR0cmlidXRlKGEpLHRoaXMubW9ycGhUYXJnZXRzUmVsYXRpdmU/KGJ0LmFkZFZlY3RvcnMoVXQubWluLGJpLm1pbiksVXQuZXhwYW5kQnlQb2ludChidCksYnQuYWRkVmVjdG9ycyhVdC5tYXgsYmkubWF4KSxVdC5leHBhbmRCeVBvaW50KGJ0KSk6KFV0LmV4cGFuZEJ5UG9pbnQoYmkubWluKSxVdC5leHBhbmRCeVBvaW50KGJpLm1heCkpfVV0LmdldENlbnRlcihuKTtsZXQgcz0wO2ZvcihsZXQgcj0wLG89dC5jb3VudDtyPG87cisrKWJ0LmZyb21CdWZmZXJBdHRyaWJ1dGUodCxyKSxzPU1hdGgubWF4KHMsbi5kaXN0YW5jZVRvU3F1YXJlZChidCkpO2lmKGUpZm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl0sYz10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlO2ZvcihsZXQgbD0wLGg9YS5jb3VudDtsPGg7bCsrKWJ0LmZyb21CdWZmZXJBdHRyaWJ1dGUoYSxsKSxjJiYoVm4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LGwpLGJ0LmFkZChWbikpLHM9TWF0aC5tYXgocyxuLmRpc3RhbmNlVG9TcXVhcmVkKGJ0KSl9dGhpcy5ib3VuZGluZ1NwaGVyZS5yYWRpdXM9TWF0aC5zcXJ0KHMpLGlzTmFOKHRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzKSYmY29uc29sZS5lcnJvcignVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCk6IENvbXB1dGVkIHJhZGl1cyBpcyBOYU4uIFRoZSAicG9zaXRpb24iIGF0dHJpYnV0ZSBpcyBsaWtlbHkgdG8gaGF2ZSBOYU4gdmFsdWVzLicsdGhpcyl9fWNvbXB1dGVUYW5nZW50cygpe2NvbnN0IHQ9dGhpcy5pbmRleCxlPXRoaXMuYXR0cmlidXRlcztpZih0PT09bnVsbHx8ZS5wb3NpdGlvbj09PXZvaWQgMHx8ZS5ub3JtYWw9PT12b2lkIDB8fGUudXY9PT12b2lkIDApe2NvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5OiAuY29tcHV0ZVRhbmdlbnRzKCkgZmFpbGVkLiBNaXNzaW5nIHJlcXVpcmVkIGF0dHJpYnV0ZXMgKGluZGV4LCBwb3NpdGlvbiwgbm9ybWFsIG9yIHV2KSIpO3JldHVybn1jb25zdCBuPWUucG9zaXRpb24scz1lLm5vcm1hbCxyPWUudXY7dGhpcy5oYXNBdHRyaWJ1dGUoInRhbmdlbnQiKT09PSExJiZ0aGlzLnNldEF0dHJpYnV0ZSgidGFuZ2VudCIsbmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkoNCpuLmNvdW50KSw0KSk7Y29uc3Qgbz10aGlzLmdldEF0dHJpYnV0ZSgidGFuZ2VudCIpLGE9W10sYz1bXTtmb3IobGV0IFM9MDtTPG4uY291bnQ7UysrKWFbU109bmV3IFQsY1tTXT1uZXcgVDtjb25zdCBsPW5ldyBULGg9bmV3IFQsdT1uZXcgVCxmPW5ldyBSLGQ9bmV3IFIscD1uZXcgUix5PW5ldyBULG09bmV3IFQ7ZnVuY3Rpb24gZyhTLEUseil7bC5mcm9tQnVmZmVyQXR0cmlidXRlKG4sUyksaC5mcm9tQnVmZmVyQXR0cmlidXRlKG4sRSksdS5mcm9tQnVmZmVyQXR0cmlidXRlKG4seiksZi5mcm9tQnVmZmVyQXR0cmlidXRlKHIsUyksZC5mcm9tQnVmZmVyQXR0cmlidXRlKHIsRSkscC5mcm9tQnVmZmVyQXR0cmlidXRlKHIseiksaC5zdWIobCksdS5zdWIobCksZC5zdWIoZikscC5zdWIoZik7Y29uc3Qgdj0xLyhkLngqcC55LXAueCpkLnkpO2lzRmluaXRlKHYpJiYoeS5jb3B5KGgpLm11bHRpcGx5U2NhbGFyKHAueSkuYWRkU2NhbGVkVmVjdG9yKHUsLWQueSkubXVsdGlwbHlTY2FsYXIodiksbS5jb3B5KHUpLm11bHRpcGx5U2NhbGFyKGQueCkuYWRkU2NhbGVkVmVjdG9yKGgsLXAueCkubXVsdGlwbHlTY2FsYXIodiksYVtTXS5hZGQoeSksYVtFXS5hZGQoeSksYVt6XS5hZGQoeSksY1tTXS5hZGQobSksY1tFXS5hZGQobSksY1t6XS5hZGQobSkpfWxldCBiPXRoaXMuZ3JvdXBzO2IubGVuZ3RoPT09MCYmKGI9W3tzdGFydDowLGNvdW50OnQuY291bnR9XSk7Zm9yKGxldCBTPTAsRT1iLmxlbmd0aDtTPEU7KytTKXtjb25zdCB6PWJbU10sdj16LnN0YXJ0LEM9ei5jb3VudDtmb3IobGV0IFA9dixGPXYrQztQPEY7UCs9MylnKHQuZ2V0WChQKzApLHQuZ2V0WChQKzEpLHQuZ2V0WChQKzIpKX1jb25zdCB3PW5ldyBULHg9bmV3IFQsTT1uZXcgVCxBPW5ldyBUO2Z1bmN0aW9uIF8oUyl7TS5mcm9tQnVmZmVyQXR0cmlidXRlKHMsUyksQS5jb3B5KE0pO2NvbnN0IEU9YVtTXTt3LmNvcHkoRSksdy5zdWIoTS5tdWx0aXBseVNjYWxhcihNLmRvdChFKSkpLm5vcm1hbGl6ZSgpLHguY3Jvc3NWZWN0b3JzKEEsRSk7Y29uc3Qgdj14LmRvdChjW1NdKTwwPy0xOjE7by5zZXRYWVpXKFMsdy54LHcueSx3Lnosdil9Zm9yKGxldCBTPTAsRT1iLmxlbmd0aDtTPEU7KytTKXtjb25zdCB6PWJbU10sdj16LnN0YXJ0LEM9ei5jb3VudDtmb3IobGV0IFA9dixGPXYrQztQPEY7UCs9MylfKHQuZ2V0WChQKzApKSxfKHQuZ2V0WChQKzEpKSxfKHQuZ2V0WChQKzIpKX19Y29tcHV0ZVZlcnRleE5vcm1hbHMoKXtjb25zdCB0PXRoaXMuaW5kZXgsZT10aGlzLmdldEF0dHJpYnV0ZSgicG9zaXRpb24iKTtpZihlIT09dm9pZCAwKXtsZXQgbj10aGlzLmdldEF0dHJpYnV0ZSgibm9ybWFsIik7aWYobj09PXZvaWQgMCluPW5ldyB4dChuZXcgRmxvYXQzMkFycmF5KGUuY291bnQqMyksMyksdGhpcy5zZXRBdHRyaWJ1dGUoIm5vcm1hbCIsbik7ZWxzZSBmb3IobGV0IGY9MCxkPW4uY291bnQ7ZjxkO2YrKyluLnNldFhZWihmLDAsMCwwKTtjb25zdCBzPW5ldyBULHI9bmV3IFQsbz1uZXcgVCxhPW5ldyBULGM9bmV3IFQsbD1uZXcgVCxoPW5ldyBULHU9bmV3IFQ7aWYodClmb3IobGV0IGY9MCxkPXQuY291bnQ7ZjxkO2YrPTMpe2NvbnN0IHA9dC5nZXRYKGYrMCkseT10LmdldFgoZisxKSxtPXQuZ2V0WChmKzIpO3MuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHApLHIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHkpLG8uZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLG0pLGguc3ViVmVjdG9ycyhvLHIpLHUuc3ViVmVjdG9ycyhzLHIpLGguY3Jvc3ModSksYS5mcm9tQnVmZmVyQXR0cmlidXRlKG4scCksYy5mcm9tQnVmZmVyQXR0cmlidXRlKG4seSksbC5mcm9tQnVmZmVyQXR0cmlidXRlKG4sbSksYS5hZGQoaCksYy5hZGQoaCksbC5hZGQoaCksbi5zZXRYWVoocCxhLngsYS55LGEueiksbi5zZXRYWVooeSxjLngsYy55LGMueiksbi5zZXRYWVoobSxsLngsbC55LGwueil9ZWxzZSBmb3IobGV0IGY9MCxkPWUuY291bnQ7ZjxkO2YrPTMpcy5mcm9tQnVmZmVyQXR0cmlidXRlKGUsZiswKSxyLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxmKzEpLG8uZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLGYrMiksaC5zdWJWZWN0b3JzKG8sciksdS5zdWJWZWN0b3JzKHMsciksaC5jcm9zcyh1KSxuLnNldFhZWihmKzAsaC54LGgueSxoLnopLG4uc2V0WFlaKGYrMSxoLngsaC55LGgueiksbi5zZXRYWVooZisyLGgueCxoLnksaC56KTt0aGlzLm5vcm1hbGl6ZU5vcm1hbHMoKSxuLm5lZWRzVXBkYXRlPSEwfX1ub3JtYWxpemVOb3JtYWxzKCl7Y29uc3QgdD10aGlzLmF0dHJpYnV0ZXMubm9ybWFsO2ZvcihsZXQgZT0wLG49dC5jb3VudDtlPG47ZSsrKWJ0LmZyb21CdWZmZXJBdHRyaWJ1dGUodCxlKSxidC5ub3JtYWxpemUoKSx0LnNldFhZWihlLGJ0LngsYnQueSxidC56KX10b05vbkluZGV4ZWQoKXtmdW5jdGlvbiB0KGEsYyl7Y29uc3QgbD1hLmFycmF5LGg9YS5pdGVtU2l6ZSx1PWEubm9ybWFsaXplZCxmPW5ldyBsLmNvbnN0cnVjdG9yKGMubGVuZ3RoKmgpO2xldCBkPTAscD0wO2ZvcihsZXQgeT0wLG09Yy5sZW5ndGg7eTxtO3krKyl7YS5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlP2Q9Y1t5XSphLmRhdGEuc3RyaWRlK2Eub2Zmc2V0OmQ9Y1t5XSpoO2ZvcihsZXQgZz0wO2c8aDtnKyspZltwKytdPWxbZCsrXX1yZXR1cm4gbmV3IHh0KGYsaCx1KX1pZih0aGlzLmluZGV4PT09bnVsbClyZXR1cm4gY29uc29sZS53YXJuKCJUSFJFRS5CdWZmZXJHZW9tZXRyeS50b05vbkluZGV4ZWQoKTogQnVmZmVyR2VvbWV0cnkgaXMgYWxyZWFkeSBub24taW5kZXhlZC4iKSx0aGlzO2NvbnN0IGU9bmV3IHVlLG49dGhpcy5pbmRleC5hcnJheSxzPXRoaXMuYXR0cmlidXRlcztmb3IoY29uc3QgYSBpbiBzKXtjb25zdCBjPXNbYV0sbD10KGMsbik7ZS5zZXRBdHRyaWJ1dGUoYSxsKX1jb25zdCByPXRoaXMubW9ycGhBdHRyaWJ1dGVzO2Zvcihjb25zdCBhIGluIHIpe2NvbnN0IGM9W10sbD1yW2FdO2ZvcihsZXQgaD0wLHU9bC5sZW5ndGg7aDx1O2grKyl7Y29uc3QgZj1sW2hdLGQ9dChmLG4pO2MucHVzaChkKX1lLm1vcnBoQXR0cmlidXRlc1thXT1jfWUubW9ycGhUYXJnZXRzUmVsYXRpdmU9dGhpcy5tb3JwaFRhcmdldHNSZWxhdGl2ZTtjb25zdCBvPXRoaXMuZ3JvdXBzO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKyl7Y29uc3QgbD1vW2FdO2UuYWRkR3JvdXAobC5zdGFydCxsLmNvdW50LGwubWF0ZXJpYWxJbmRleCl9cmV0dXJuIGV9dG9KU09OKCl7Y29uc3QgdD17bWV0YWRhdGE6e3ZlcnNpb246NC42LHR5cGU6IkJ1ZmZlckdlb21ldHJ5IixnZW5lcmF0b3I6IkJ1ZmZlckdlb21ldHJ5LnRvSlNPTiJ9fTtpZih0LnV1aWQ9dGhpcy51dWlkLHQudHlwZT10aGlzLnR5cGUsdGhpcy5uYW1lIT09IiImJih0Lm5hbWU9dGhpcy5uYW1lKSxPYmplY3Qua2V5cyh0aGlzLnVzZXJEYXRhKS5sZW5ndGg+MCYmKHQudXNlckRhdGE9dGhpcy51c2VyRGF0YSksdGhpcy5wYXJhbWV0ZXJzIT09dm9pZCAwKXtjb25zdCBjPXRoaXMucGFyYW1ldGVycztmb3IoY29uc3QgbCBpbiBjKWNbbF0hPT12b2lkIDAmJih0W2xdPWNbbF0pO3JldHVybiB0fXQuZGF0YT17YXR0cmlidXRlczp7fX07Y29uc3QgZT10aGlzLmluZGV4O2UhPT1udWxsJiYodC5kYXRhLmluZGV4PXt0eXBlOmUuYXJyYXkuY29uc3RydWN0b3IubmFtZSxhcnJheTpBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChlLmFycmF5KX0pO2NvbnN0IG49dGhpcy5hdHRyaWJ1dGVzO2Zvcihjb25zdCBjIGluIG4pe2NvbnN0IGw9bltjXTt0LmRhdGEuYXR0cmlidXRlc1tjXT1sLnRvSlNPTih0LmRhdGEpfWNvbnN0IHM9e307bGV0IHI9ITE7Zm9yKGNvbnN0IGMgaW4gdGhpcy5tb3JwaEF0dHJpYnV0ZXMpe2NvbnN0IGw9dGhpcy5tb3JwaEF0dHJpYnV0ZXNbY10saD1bXTtmb3IobGV0IHU9MCxmPWwubGVuZ3RoO3U8Zjt1Kyspe2NvbnN0IGQ9bFt1XTtoLnB1c2goZC50b0pTT04odC5kYXRhKSl9aC5sZW5ndGg+MCYmKHNbY109aCxyPSEwKX1yJiYodC5kYXRhLm1vcnBoQXR0cmlidXRlcz1zLHQuZGF0YS5tb3JwaFRhcmdldHNSZWxhdGl2ZT10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlKTtjb25zdCBvPXRoaXMuZ3JvdXBzO28ubGVuZ3RoPjAmJih0LmRhdGEuZ3JvdXBzPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobykpKTtjb25zdCBhPXRoaXMuYm91bmRpbmdTcGhlcmU7cmV0dXJuIGEhPT1udWxsJiYodC5kYXRhLmJvdW5kaW5nU3BoZXJlPXtjZW50ZXI6YS5jZW50ZXIudG9BcnJheSgpLHJhZGl1czphLnJhZGl1c30pLHR9Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWNvcHkodCl7dGhpcy5pbmRleD1udWxsLHRoaXMuYXR0cmlidXRlcz17fSx0aGlzLm1vcnBoQXR0cmlidXRlcz17fSx0aGlzLmdyb3Vwcz1bXSx0aGlzLmJvdW5kaW5nQm94PW51bGwsdGhpcy5ib3VuZGluZ1NwaGVyZT1udWxsO2NvbnN0IGU9e307dGhpcy5uYW1lPXQubmFtZTtjb25zdCBuPXQuaW5kZXg7biE9PW51bGwmJnRoaXMuc2V0SW5kZXgobi5jbG9uZSgpKTtjb25zdCBzPXQuYXR0cmlidXRlcztmb3IoY29uc3QgbCBpbiBzKXtjb25zdCBoPXNbbF07dGhpcy5zZXRBdHRyaWJ1dGUobCxoLmNsb25lKGUpKX1jb25zdCByPXQubW9ycGhBdHRyaWJ1dGVzO2Zvcihjb25zdCBsIGluIHIpe2NvbnN0IGg9W10sdT1yW2xdO2ZvcihsZXQgZj0wLGQ9dS5sZW5ndGg7ZjxkO2YrKyloLnB1c2godVtmXS5jbG9uZShlKSk7dGhpcy5tb3JwaEF0dHJpYnV0ZXNbbF09aH10aGlzLm1vcnBoVGFyZ2V0c1JlbGF0aXZlPXQubW9ycGhUYXJnZXRzUmVsYXRpdmU7Y29uc3Qgbz10Lmdyb3Vwcztmb3IobGV0IGw9MCxoPW8ubGVuZ3RoO2w8aDtsKyspe2NvbnN0IHU9b1tsXTt0aGlzLmFkZEdyb3VwKHUuc3RhcnQsdS5jb3VudCx1Lm1hdGVyaWFsSW5kZXgpfWNvbnN0IGE9dC5ib3VuZGluZ0JveDthIT09bnVsbCYmKHRoaXMuYm91bmRpbmdCb3g9YS5jbG9uZSgpKTtjb25zdCBjPXQuYm91bmRpbmdTcGhlcmU7cmV0dXJuIGMhPT1udWxsJiYodGhpcy5ib3VuZGluZ1NwaGVyZT1jLmNsb25lKCkpLHRoaXMuZHJhd1JhbmdlLnN0YXJ0PXQuZHJhd1JhbmdlLnN0YXJ0LHRoaXMuZHJhd1JhbmdlLmNvdW50PXQuZHJhd1JhbmdlLmNvdW50LHRoaXMudXNlckRhdGE9dC51c2VyRGF0YSx0aGlzfWRpc3Bvc2UoKXt0aGlzLmRpc3BhdGNoRXZlbnQoe3R5cGU6ImRpc3Bvc2UifSl9fWNvbnN0IEVjPW5ldyBzdCx1bj1uZXcgYW8scHM9bmV3IGlvLFBjPW5ldyBULHlzPW5ldyBULG1zPW5ldyBULGdzPW5ldyBULHdvPW5ldyBULHhzPW5ldyBULENjPW5ldyBULHdzPW5ldyBUO2NsYXNzIGhmIGV4dGVuZHMgVGV7Y29uc3RydWN0b3IodD1uZXcgdWUsZT1uZXcgcmYpe3N1cGVyKCksdGhpcy5pc01lc2g9ITAsdGhpcy50eXBlPSJNZXNoIix0aGlzLmdlb21ldHJ5PXQsdGhpcy5tYXRlcmlhbD1lLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5PXZvaWQgMCx0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcz12b2lkIDAsdGhpcy51cGRhdGVNb3JwaFRhcmdldHMoKX1jb3B5KHQsZSl7cmV0dXJuIHN1cGVyLmNvcHkodCxlKSx0Lm1vcnBoVGFyZ2V0SW5mbHVlbmNlcyE9PXZvaWQgMCYmKHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPXQubW9ycGhUYXJnZXRJbmZsdWVuY2VzLnNsaWNlKCkpLHQubW9ycGhUYXJnZXREaWN0aW9uYXJ5IT09dm9pZCAwJiYodGhpcy5tb3JwaFRhcmdldERpY3Rpb25hcnk9T2JqZWN0LmFzc2lnbih7fSx0Lm1vcnBoVGFyZ2V0RGljdGlvbmFyeSkpLHRoaXMubWF0ZXJpYWw9QXJyYXkuaXNBcnJheSh0Lm1hdGVyaWFsKT90Lm1hdGVyaWFsLnNsaWNlKCk6dC5tYXRlcmlhbCx0aGlzLmdlb21ldHJ5PXQuZ2VvbWV0cnksdGhpc311cGRhdGVNb3JwaFRhcmdldHMoKXtjb25zdCBlPXRoaXMuZ2VvbWV0cnkubW9ycGhBdHRyaWJ1dGVzLG49T2JqZWN0LmtleXMoZSk7aWYobi5sZW5ndGg+MCl7Y29uc3Qgcz1lW25bMF1dO2lmKHMhPT12b2lkIDApe3RoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzPVtdLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5PXt9O2ZvcihsZXQgcj0wLG89cy5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT1zW3JdLm5hbWV8fFN0cmluZyhyKTt0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcy5wdXNoKDApLHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5W2FdPXJ9fX19Z2V0VmVydGV4UG9zaXRpb24odCxlKXtjb25zdCBuPXRoaXMuZ2VvbWV0cnkscz1uLmF0dHJpYnV0ZXMucG9zaXRpb24scj1uLm1vcnBoQXR0cmlidXRlcy5wb3NpdGlvbixvPW4ubW9ycGhUYXJnZXRzUmVsYXRpdmU7ZS5mcm9tQnVmZmVyQXR0cmlidXRlKHMsdCk7Y29uc3QgYT10aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcztpZihyJiZhKXt4cy5zZXQoMCwwLDApO2ZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1hW2NdLHU9cltjXTtoIT09MCYmKHdvLmZyb21CdWZmZXJBdHRyaWJ1dGUodSx0KSxvP3hzLmFkZFNjYWxlZFZlY3Rvcih3byxoKTp4cy5hZGRTY2FsZWRWZWN0b3Iod28uc3ViKGUpLGgpKX1lLmFkZCh4cyl9cmV0dXJuIGV9cmF5Y2FzdCh0LGUpe2NvbnN0IG49dGhpcy5nZW9tZXRyeSxzPXRoaXMubWF0ZXJpYWwscj10aGlzLm1hdHJpeFdvcmxkO3MhPT12b2lkIDAmJihuLmJvdW5kaW5nU3BoZXJlPT09bnVsbCYmbi5jb21wdXRlQm91bmRpbmdTcGhlcmUoKSxwcy5jb3B5KG4uYm91bmRpbmdTcGhlcmUpLHBzLmFwcGx5TWF0cml4NChyKSx1bi5jb3B5KHQucmF5KS5yZWNhc3QodC5uZWFyKSwhKHBzLmNvbnRhaW5zUG9pbnQodW4ub3JpZ2luKT09PSExJiYodW4uaW50ZXJzZWN0U3BoZXJlKHBzLFBjKT09PW51bGx8fHVuLm9yaWdpbi5kaXN0YW5jZVRvU3F1YXJlZChQYyk+ZGkodC5mYXItdC5uZWFyLDIpKSkmJihFYy5jb3B5KHIpLmludmVydCgpLHVuLmNvcHkodC5yYXkpLmFwcGx5TWF0cml4NChFYyksIShuLmJvdW5kaW5nQm94IT09bnVsbCYmdW4uaW50ZXJzZWN0c0JveChuLmJvdW5kaW5nQm94KT09PSExKSYmdGhpcy5fY29tcHV0ZUludGVyc2VjdGlvbnModCxlLHVuKSkpfV9jb21wdXRlSW50ZXJzZWN0aW9ucyh0LGUsbil7bGV0IHM7Y29uc3Qgcj10aGlzLmdlb21ldHJ5LG89dGhpcy5tYXRlcmlhbCxhPXIuaW5kZXgsYz1yLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1yLmF0dHJpYnV0ZXMudXYsaD1yLmF0dHJpYnV0ZXMudXYxLHU9ci5hdHRyaWJ1dGVzLm5vcm1hbCxmPXIuZ3JvdXBzLGQ9ci5kcmF3UmFuZ2U7aWYoYSE9PW51bGwpaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihhLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9YS5nZXRYKHgpLF89YS5nZXRYKHgrMSksUz1hLmdldFgoeCsyKTtzPWJzKHRoaXMsZyx0LG4sbCxoLHUsQSxfLFMpLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYS5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1hLmdldFgobSksdz1hLmdldFgobSsxKSx4PWEuZ2V0WChtKzIpO3M9YnModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX1lbHNlIGlmKGMhPT12b2lkIDApaWYoQXJyYXkuaXNBcnJheShvKSlmb3IobGV0IHA9MCx5PWYubGVuZ3RoO3A8eTtwKyspe2NvbnN0IG09ZltwXSxnPW9bbS5tYXRlcmlhbEluZGV4XSxiPU1hdGgubWF4KG0uc3RhcnQsZC5zdGFydCksdz1NYXRoLm1pbihjLmNvdW50LE1hdGgubWluKG0uc3RhcnQrbS5jb3VudCxkLnN0YXJ0K2QuY291bnQpKTtmb3IobGV0IHg9YixNPXc7eDxNO3grPTMpe2NvbnN0IEE9eCxfPXgrMSxTPXgrMjtzPWJzKHRoaXMsZyx0LG4sbCxoLHUsQSxfLFMpLHMmJihzLmZhY2VJbmRleD1NYXRoLmZsb29yKHgvMykscy5mYWNlLm1hdGVyaWFsSW5kZXg9bS5tYXRlcmlhbEluZGV4LGUucHVzaChzKSl9fWVsc2V7Y29uc3QgcD1NYXRoLm1heCgwLGQuc3RhcnQpLHk9TWF0aC5taW4oYy5jb3VudCxkLnN0YXJ0K2QuY291bnQpO2ZvcihsZXQgbT1wLGc9eTttPGc7bSs9Myl7Y29uc3QgYj1tLHc9bSsxLHg9bSsyO3M9YnModGhpcyxvLHQsbixsLGgsdSxiLHcseCkscyYmKHMuZmFjZUluZGV4PU1hdGguZmxvb3IobS8zKSxlLnB1c2gocykpfX19fWZ1bmN0aW9uIHVmKGksdCxlLG4scyxyLG8sYSl7bGV0IGM7aWYodC5zaWRlPT09MT9jPW4uaW50ZXJzZWN0VHJpYW5nbGUobyxyLHMsITAsYSk6Yz1uLmludGVyc2VjdFRyaWFuZ2xlKHMscixvLHQuc2lkZT09PTAsYSksYz09PW51bGwpcmV0dXJuIG51bGw7d3MuY29weShhKSx3cy5hcHBseU1hdHJpeDQoaS5tYXRyaXhXb3JsZCk7Y29uc3QgbD1lLnJheS5vcmlnaW4uZGlzdGFuY2VUbyh3cyk7cmV0dXJuIGw8ZS5uZWFyfHxsPmUuZmFyP251bGw6e2Rpc3RhbmNlOmwscG9pbnQ6d3MuY2xvbmUoKSxvYmplY3Q6aX19ZnVuY3Rpb24gYnMoaSx0LGUsbixzLHIsbyxhLGMsbCl7aS5nZXRWZXJ0ZXhQb3NpdGlvbihhLHlzKSxpLmdldFZlcnRleFBvc2l0aW9uKGMsbXMpLGkuZ2V0VmVydGV4UG9zaXRpb24obCxncyk7Y29uc3QgaD11ZihpLHQsZSxuLHlzLG1zLGdzLENjKTtpZihoKXtjb25zdCB1PW5ldyBUO2V0LmdldEJhcnljb29yZChDYyx5cyxtcyxncyx1KSxzJiYoaC51dj1ldC5nZXRJbnRlcnBvbGF0ZWRBdHRyaWJ1dGUocyxhLGMsbCx1LG5ldyBSKSksciYmKGgudXYxPWV0LmdldEludGVycG9sYXRlZEF0dHJpYnV0ZShyLGEsYyxsLHUsbmV3IFIpKSxvJiYoaC5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGVkQXR0cmlidXRlKG8sYSxjLGwsdSxuZXcgVCksaC5ub3JtYWwuZG90KG4uZGlyZWN0aW9uKT4wJiZoLm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGY9e2EsYjpjLGM6bCxub3JtYWw6bmV3IFQsbWF0ZXJpYWxJbmRleDowfTtldC5nZXROb3JtYWwoeXMsbXMsZ3MsZi5ub3JtYWwpLGguZmFjZT1mLGguYmFyeWNvb3JkPXV9cmV0dXJuIGh9Y29uc3QgYm89bmV3IFQsZmY9bmV3IFQsZGY9bmV3IGdlO2NsYXNzIE1ve2NvbnN0cnVjdG9yKHQ9bmV3IFQoMSwwLDApLGU9MCl7dGhpcy5pc1BsYW5lPSEwLHRoaXMubm9ybWFsPXQsdGhpcy5jb25zdGFudD1lfXNldCh0LGUpe3JldHVybiB0aGlzLm5vcm1hbC5jb3B5KHQpLHRoaXMuY29uc3RhbnQ9ZSx0aGlzfXNldENvbXBvbmVudHModCxlLG4scyl7cmV0dXJuIHRoaXMubm9ybWFsLnNldCh0LGUsbiksdGhpcy5jb25zdGFudD1zLHRoaXN9c2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQodCxlKXtyZXR1cm4gdGhpcy5ub3JtYWwuY29weSh0KSx0aGlzLmNvbnN0YW50PS1lLmRvdCh0aGlzLm5vcm1hbCksdGhpc31zZXRGcm9tQ29wbGFuYXJQb2ludHModCxlLG4pe2NvbnN0IHM9Ym8uc3ViVmVjdG9ycyhuLGUpLmNyb3NzKGZmLnN1YlZlY3RvcnModCxlKSkubm9ybWFsaXplKCk7cmV0dXJuIHRoaXMuc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQocyx0KSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMubm9ybWFsLmNvcHkodC5ub3JtYWwpLHRoaXMuY29uc3RhbnQ9dC5jb25zdGFudCx0aGlzfW5vcm1hbGl6ZSgpe2NvbnN0IHQ9MS90aGlzLm5vcm1hbC5sZW5ndGgoKTtyZXR1cm4gdGhpcy5ub3JtYWwubXVsdGlwbHlTY2FsYXIodCksdGhpcy5jb25zdGFudCo9dCx0aGlzfW5lZ2F0ZSgpe3JldHVybiB0aGlzLmNvbnN0YW50Kj0tMSx0aGlzLm5vcm1hbC5uZWdhdGUoKSx0aGlzfWRpc3RhbmNlVG9Qb2ludCh0KXtyZXR1cm4gdGhpcy5ub3JtYWwuZG90KHQpK3RoaXMuY29uc3RhbnR9ZGlzdGFuY2VUb1NwaGVyZSh0KXtyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQodC5jZW50ZXIpLXQucmFkaXVzfXByb2plY3RQb2ludCh0LGUpe3JldHVybiBlLmNvcHkodCkuYWRkU2NhbGVkVmVjdG9yKHRoaXMubm9ybWFsLC10aGlzLmRpc3RhbmNlVG9Qb2ludCh0KSl9aW50ZXJzZWN0TGluZSh0LGUpe2NvbnN0IG49dC5kZWx0YShibykscz10aGlzLm5vcm1hbC5kb3Qobik7aWYocz09PTApcmV0dXJuIHRoaXMuZGlzdGFuY2VUb1BvaW50KHQuc3RhcnQpPT09MD9lLmNvcHkodC5zdGFydCk6bnVsbDtjb25zdCByPS0odC5zdGFydC5kb3QodGhpcy5ub3JtYWwpK3RoaXMuY29uc3RhbnQpL3M7cmV0dXJuIHI8MHx8cj4xP251bGw6ZS5jb3B5KHQuc3RhcnQpLmFkZFNjYWxlZFZlY3RvcihuLHIpfWludGVyc2VjdHNMaW5lKHQpe2NvbnN0IGU9dGhpcy5kaXN0YW5jZVRvUG9pbnQodC5zdGFydCksbj10aGlzLmRpc3RhbmNlVG9Qb2ludCh0LmVuZCk7cmV0dXJuIGU8MCYmbj4wfHxuPDAmJmU+MH1pbnRlcnNlY3RzQm94KHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0LmludGVyc2VjdHNQbGFuZSh0aGlzKX1jb3BsYW5hclBvaW50KHQpe3JldHVybiB0LmNvcHkodGhpcy5ub3JtYWwpLm11bHRpcGx5U2NhbGFyKC10aGlzLmNvbnN0YW50KX1hcHBseU1hdHJpeDQodCxlKXtjb25zdCBuPWV8fGRmLmdldE5vcm1hbE1hdHJpeCh0KSxzPXRoaXMuY29wbGFuYXJQb2ludChibykuYXBwbHlNYXRyaXg0KHQpLHI9dGhpcy5ub3JtYWwuYXBwbHlNYXRyaXgzKG4pLm5vcm1hbGl6ZSgpO3JldHVybiB0aGlzLmNvbnN0YW50PS1zLmRvdChyKSx0aGlzfXRyYW5zbGF0ZSh0KXtyZXR1cm4gdGhpcy5jb25zdGFudC09dC5kb3QodGhpcy5ub3JtYWwpLHRoaXN9ZXF1YWxzKHQpe3JldHVybiB0Lm5vcm1hbC5lcXVhbHModGhpcy5ub3JtYWwpJiZ0LmNvbnN0YW50PT09dGhpcy5jb25zdGFudH1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9fWxldCB4ZT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMudHlwZT0iQ3VydmUiLHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPTIwMCx0aGlzLm5lZWRzVXBkYXRlPSExLHRoaXMuY2FjaGVBcmNMZW5ndGhzPW51bGx9Z2V0UG9pbnQoKXtjb25zb2xlLndhcm4oIlRIUkVFLkN1cnZlOiAuZ2V0UG9pbnQoKSBub3QgaW1wbGVtZW50ZWQuIil9Z2V0UG9pbnRBdCh0LGUpe2NvbnN0IG49dGhpcy5nZXRVdG9UbWFwcGluZyh0KTtyZXR1cm4gdGhpcy5nZXRQb2ludChuLGUpfWdldFBvaW50cyh0PTUpe2NvbnN0IGU9W107Zm9yKGxldCBuPTA7bjw9dDtuKyspZS5wdXNoKHRoaXMuZ2V0UG9pbnQobi90KSk7cmV0dXJuIGV9Z2V0U3BhY2VkUG9pbnRzKHQ9NSl7Y29uc3QgZT1bXTtmb3IobGV0IG49MDtuPD10O24rKyllLnB1c2godGhpcy5nZXRQb2ludEF0KG4vdCkpO3JldHVybiBlfWdldExlbmd0aCgpe2NvbnN0IHQ9dGhpcy5nZXRMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19Z2V0TGVuZ3Rocyh0PXRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zKXtpZih0aGlzLmNhY2hlQXJjTGVuZ3RocyYmdGhpcy5jYWNoZUFyY0xlbmd0aHMubGVuZ3RoPT09dCsxJiYhdGhpcy5uZWVkc1VwZGF0ZSlyZXR1cm4gdGhpcy5jYWNoZUFyY0xlbmd0aHM7dGhpcy5uZWVkc1VwZGF0ZT0hMTtjb25zdCBlPVtdO2xldCBuLHM9dGhpcy5nZXRQb2ludCgwKSxyPTA7ZS5wdXNoKDApO2ZvcihsZXQgbz0xO288PXQ7bysrKW49dGhpcy5nZXRQb2ludChvL3QpLHIrPW4uZGlzdGFuY2VUbyhzKSxlLnB1c2gocikscz1uO3JldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3Rocz1lLGV9dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5nZXRMZW5ndGhzKCl9Z2V0VXRvVG1hcHBpbmcodCxlPW51bGwpe2NvbnN0IG49dGhpcy5nZXRMZW5ndGhzKCk7bGV0IHM9MDtjb25zdCByPW4ubGVuZ3RoO2xldCBvO2U/bz1lOm89dCpuW3ItMV07bGV0IGE9MCxjPXItMSxsO2Zvcig7YTw9YzspaWYocz1NYXRoLmZsb29yKGErKGMtYSkvMiksbD1uW3NdLW8sbDwwKWE9cysxO2Vsc2UgaWYobD4wKWM9cy0xO2Vsc2V7Yz1zO2JyZWFrfWlmKHM9YyxuW3NdPT09bylyZXR1cm4gcy8oci0xKTtjb25zdCBoPW5bc10sZj1uW3MrMV0taCxkPShvLWgpL2Y7cmV0dXJuKHMrZCkvKHItMSl9Z2V0VGFuZ2VudCh0LGUpe2xldCBzPXQtMWUtNCxyPXQrMWUtNDtzPDAmJihzPTApLHI+MSYmKHI9MSk7Y29uc3Qgbz10aGlzLmdldFBvaW50KHMpLGE9dGhpcy5nZXRQb2ludChyKSxjPWV8fChvLmlzVmVjdG9yMj9uZXcgUjpuZXcgVCk7cmV0dXJuIGMuY29weShhKS5zdWIobykubm9ybWFsaXplKCksY31nZXRUYW5nZW50QXQodCxlKXtjb25zdCBuPXRoaXMuZ2V0VXRvVG1hcHBpbmcodCk7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudChuLGUpfWNvbXB1dGVGcmVuZXRGcmFtZXModCxlPSExKXtjb25zdCBuPW5ldyBULHM9W10scj1bXSxvPVtdLGE9bmV3IFQsYz1uZXcgc3Q7Zm9yKGxldCBkPTA7ZDw9dDtkKyspe2NvbnN0IHA9ZC90O3NbZF09dGhpcy5nZXRUYW5nZW50QXQocCxuZXcgVCl9clswXT1uZXcgVCxvWzBdPW5ldyBUO2xldCBsPU51bWJlci5NQVhfVkFMVUU7Y29uc3QgaD1NYXRoLmFicyhzWzBdLngpLHU9TWF0aC5hYnMoc1swXS55KSxmPU1hdGguYWJzKHNbMF0ueik7aDw9bCYmKGw9aCxuLnNldCgxLDAsMCkpLHU8PWwmJihsPXUsbi5zZXQoMCwxLDApKSxmPD1sJiZuLnNldCgwLDAsMSksYS5jcm9zc1ZlY3RvcnMoc1swXSxuKS5ub3JtYWxpemUoKSxyWzBdLmNyb3NzVmVjdG9ycyhzWzBdLGEpLG9bMF0uY3Jvc3NWZWN0b3JzKHNbMF0sclswXSk7Zm9yKGxldCBkPTE7ZDw9dDtkKyspe2lmKHJbZF09cltkLTFdLmNsb25lKCksb1tkXT1vW2QtMV0uY2xvbmUoKSxhLmNyb3NzVmVjdG9ycyhzW2QtMV0sc1tkXSksYS5sZW5ndGgoKT5OdW1iZXIuRVBTSUxPTil7YS5ub3JtYWxpemUoKTtjb25zdCBwPU1hdGguYWNvcyhaKHNbZC0xXS5kb3Qoc1tkXSksLTEsMSkpO3JbZF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhhLHApKX1vW2RdLmNyb3NzVmVjdG9ycyhzW2RdLHJbZF0pfWlmKGU9PT0hMCl7bGV0IGQ9TWF0aC5hY29zKFooclswXS5kb3Qoclt0XSksLTEsMSkpO2QvPXQsc1swXS5kb3QoYS5jcm9zc1ZlY3RvcnMoclswXSxyW3RdKSk+MCYmKGQ9LWQpO2ZvcihsZXQgcD0xO3A8PXQ7cCsrKXJbcF0uYXBwbHlNYXRyaXg0KGMubWFrZVJvdGF0aW9uQXhpcyhzW3BdLGQqcCkpLG9bcF0uY3Jvc3NWZWN0b3JzKHNbcF0scltwXSl9cmV0dXJue3RhbmdlbnRzOnMsbm9ybWFsczpyLGJpbm9ybWFsczpvfX1jbG9uZSgpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkodGhpcyl9Y29weSh0KXtyZXR1cm4gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM9dC5hcmNMZW5ndGhEaXZpc2lvbnMsdGhpc310b0pTT04oKXtjb25zdCB0PXttZXRhZGF0YTp7dmVyc2lvbjo0LjYsdHlwZToiQ3VydmUiLGdlbmVyYXRvcjoiQ3VydmUudG9KU09OIn19O3JldHVybiB0LmFyY0xlbmd0aERpdmlzaW9ucz10aGlzLmFyY0xlbmd0aERpdmlzaW9ucyx0LnR5cGU9dGhpcy50eXBlLHR9ZnJvbUpTT04odCl7cmV0dXJuIHRoaXMuYXJjTGVuZ3RoRGl2aXNpb25zPXQuYXJjTGVuZ3RoRGl2aXNpb25zLHRoaXN9fTtjbGFzcyBNcyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9MCxlPTAsbj0xLHM9MSxyPTAsbz1NYXRoLlBJKjIsYT0hMSxjPTApe3N1cGVyKCksdGhpcy5pc0VsbGlwc2VDdXJ2ZT0hMCx0aGlzLnR5cGU9IkVsbGlwc2VDdXJ2ZSIsdGhpcy5hWD10LHRoaXMuYVk9ZSx0aGlzLnhSYWRpdXM9bix0aGlzLnlSYWRpdXM9cyx0aGlzLmFTdGFydEFuZ2xlPXIsdGhpcy5hRW5kQW5nbGU9byx0aGlzLmFDbG9ja3dpc2U9YSx0aGlzLmFSb3RhdGlvbj1jfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9TWF0aC5QSSoyO2xldCByPXRoaXMuYUVuZEFuZ2xlLXRoaXMuYVN0YXJ0QW5nbGU7Y29uc3Qgbz1NYXRoLmFicyhyKTxOdW1iZXIuRVBTSUxPTjtmb3IoO3I8MDspcis9cztmb3IoO3I+czspci09cztyPE51bWJlci5FUFNJTE9OJiYobz9yPTA6cj1zKSx0aGlzLmFDbG9ja3dpc2U9PT0hMCYmIW8mJihyPT09cz9yPS1zOnI9ci1zKTtjb25zdCBhPXRoaXMuYVN0YXJ0QW5nbGUrdCpyO2xldCBjPXRoaXMuYVgrdGhpcy54UmFkaXVzKk1hdGguY29zKGEpLGw9dGhpcy5hWSt0aGlzLnlSYWRpdXMqTWF0aC5zaW4oYSk7aWYodGhpcy5hUm90YXRpb24hPT0wKXtjb25zdCBoPU1hdGguY29zKHRoaXMuYVJvdGF0aW9uKSx1PU1hdGguc2luKHRoaXMuYVJvdGF0aW9uKSxmPWMtdGhpcy5hWCxkPWwtdGhpcy5hWTtjPWYqaC1kKnUrdGhpcy5hWCxsPWYqdStkKmgrdGhpcy5hWX1yZXR1cm4gbi5zZXQoYyxsKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMuYVg9dC5hWCx0aGlzLmFZPXQuYVksdGhpcy54UmFkaXVzPXQueFJhZGl1cyx0aGlzLnlSYWRpdXM9dC55UmFkaXVzLHRoaXMuYVN0YXJ0QW5nbGU9dC5hU3RhcnRBbmdsZSx0aGlzLmFFbmRBbmdsZT10LmFFbmRBbmdsZSx0aGlzLmFDbG9ja3dpc2U9dC5hQ2xvY2t3aXNlLHRoaXMuYVJvdGF0aW9uPXQuYVJvdGF0aW9uLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC5hWD10aGlzLmFYLHQuYVk9dGhpcy5hWSx0LnhSYWRpdXM9dGhpcy54UmFkaXVzLHQueVJhZGl1cz10aGlzLnlSYWRpdXMsdC5hU3RhcnRBbmdsZT10aGlzLmFTdGFydEFuZ2xlLHQuYUVuZEFuZ2xlPXRoaXMuYUVuZEFuZ2xlLHQuYUNsb2Nrd2lzZT10aGlzLmFDbG9ja3dpc2UsdC5hUm90YXRpb249dGhpcy5hUm90YXRpb24sdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5hWD10LmFYLHRoaXMuYVk9dC5hWSx0aGlzLnhSYWRpdXM9dC54UmFkaXVzLHRoaXMueVJhZGl1cz10LnlSYWRpdXMsdGhpcy5hU3RhcnRBbmdsZT10LmFTdGFydEFuZ2xlLHRoaXMuYUVuZEFuZ2xlPXQuYUVuZEFuZ2xlLHRoaXMuYUNsb2Nrd2lzZT10LmFDbG9ja3dpc2UsdGhpcy5hUm90YXRpb249dC5hUm90YXRpb24sdGhpc319Y2xhc3MgQmMgZXh0ZW5kcyBNc3tjb25zdHJ1Y3Rvcih0LGUsbixzLHIsbyl7c3VwZXIodCxlLG4sbixzLHIsbyksdGhpcy5pc0FyY0N1cnZlPSEwLHRoaXMudHlwZT0iQXJjQ3VydmUifX1mdW5jdGlvbiBBbygpe2xldCBpPTAsdD0wLGU9MCxuPTA7ZnVuY3Rpb24gcyhyLG8sYSxjKXtpPXIsdD1hLGU9LTMqciszKm8tMiphLWMsbj0yKnItMipvK2ErY31yZXR1cm57aW5pdENhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsKXtzKG8sYSxsKihhLXIpLGwqKGMtbykpfSxpbml0Tm9udW5pZm9ybUNhdG11bGxSb206ZnVuY3Rpb24ocixvLGEsYyxsLGgsdSl7bGV0IGY9KG8tcikvbC0oYS1yKS8obCtoKSsoYS1vKS9oLGQ9KGEtbykvaC0oYy1vKS8oaCt1KSsoYy1hKS91O2YqPWgsZCo9aCxzKG8sYSxmLGQpfSxjYWxjOmZ1bmN0aW9uKHIpe2NvbnN0IG89cipyLGE9bypyO3JldHVybiBpK3QqcitlKm8rbiphfX19Y29uc3QgQXM9bmV3IFQsX289bmV3IEFvLFNvPW5ldyBBbyx2bz1uZXcgQW87Y2xhc3MgRmMgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdLGU9ITEsbj0iY2VudHJpcGV0YWwiLHM9LjUpe3N1cGVyKCksdGhpcy5pc0NhdG11bGxSb21DdXJ2ZTM9ITAsdGhpcy50eXBlPSJDYXRtdWxsUm9tQ3VydmUzIix0aGlzLnBvaW50cz10LHRoaXMuY2xvc2VkPWUsdGhpcy5jdXJ2ZVR5cGU9bix0aGlzLnRlbnNpb249c31nZXRQb2ludCh0LGU9bmV3IFQpe2NvbnN0IG49ZSxzPXRoaXMucG9pbnRzLHI9cy5sZW5ndGgsbz0oci0odGhpcy5jbG9zZWQ/MDoxKSkqdDtsZXQgYT1NYXRoLmZsb29yKG8pLGM9by1hO3RoaXMuY2xvc2VkP2ErPWE+MD8wOihNYXRoLmZsb29yKE1hdGguYWJzKGEpL3IpKzEpKnI6Yz09PTAmJmE9PT1yLTEmJihhPXItMixjPTEpO2xldCBsLGg7dGhpcy5jbG9zZWR8fGE+MD9sPXNbKGEtMSklcl06KEFzLnN1YlZlY3RvcnMoc1swXSxzWzFdKS5hZGQoc1swXSksbD1Bcyk7Y29uc3QgdT1zW2Elcl0sZj1zWyhhKzEpJXJdO2lmKHRoaXMuY2xvc2VkfHxhKzI8cj9oPXNbKGErMiklcl06KEFzLnN1YlZlY3RvcnMoc1tyLTFdLHNbci0yXSkuYWRkKHNbci0xXSksaD1BcyksdGhpcy5jdXJ2ZVR5cGU9PT0iY2VudHJpcGV0YWwifHx0aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIil7Y29uc3QgZD10aGlzLmN1cnZlVHlwZT09PSJjaG9yZGFsIj8uNTouMjU7bGV0IHA9TWF0aC5wb3cobC5kaXN0YW5jZVRvU3F1YXJlZCh1KSxkKSx5PU1hdGgucG93KHUuZGlzdGFuY2VUb1NxdWFyZWQoZiksZCksbT1NYXRoLnBvdyhmLmRpc3RhbmNlVG9TcXVhcmVkKGgpLGQpO3k8MWUtNCYmKHk9MSkscDwxZS00JiYocD15KSxtPDFlLTQmJihtPXkpLF9vLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLngsdS54LGYueCxoLngscCx5LG0pLFNvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnksdS55LGYueSxoLnkscCx5LG0pLHZvLmluaXROb251bmlmb3JtQ2F0bXVsbFJvbShsLnosdS56LGYueixoLnoscCx5LG0pfWVsc2UgdGhpcy5jdXJ2ZVR5cGU9PT0iY2F0bXVsbHJvbSImJihfby5pbml0Q2F0bXVsbFJvbShsLngsdS54LGYueCxoLngsdGhpcy50ZW5zaW9uKSxTby5pbml0Q2F0bXVsbFJvbShsLnksdS55LGYueSxoLnksdGhpcy50ZW5zaW9uKSx2by5pbml0Q2F0bXVsbFJvbShsLnosdS56LGYueixoLnosdGhpcy50ZW5zaW9uKSk7cmV0dXJuIG4uc2V0KF9vLmNhbGMoYyksU28uY2FsYyhjKSx2by5jYWxjKGMpKSxufWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5jbG9zZWQ9dC5jbG9zZWQsdGhpcy5jdXJ2ZVR5cGU9dC5jdXJ2ZVR5cGUsdGhpcy50ZW5zaW9uPXQudGVuc2lvbix0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdC5jbG9zZWQ9dGhpcy5jbG9zZWQsdC5jdXJ2ZVR5cGU9dGhpcy5jdXJ2ZVR5cGUsdC50ZW5zaW9uPXRoaXMudGVuc2lvbix0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChuZXcgVCgpLmZyb21BcnJheShzKSl9cmV0dXJuIHRoaXMuY2xvc2VkPXQuY2xvc2VkLHRoaXMuY3VydmVUeXBlPXQuY3VydmVUeXBlLHRoaXMudGVuc2lvbj10LnRlbnNpb24sdGhpc319ZnVuY3Rpb24gSWMoaSx0LGUsbixzKXtjb25zdCByPShuLXQpKi41LG89KHMtZSkqLjUsYT1pKmksYz1pKmE7cmV0dXJuKDIqZS0yKm4rcitvKSpjKygtMyplKzMqbi0yKnItbykqYStyKmkrZX1mdW5jdGlvbiBwZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiBlKmUqdH1mdW5jdGlvbiB5ZihpLHQpe3JldHVybiAyKigxLWkpKmkqdH1mdW5jdGlvbiBtZihpLHQpe3JldHVybiBpKmkqdH1mdW5jdGlvbiBNaShpLHQsZSxuKXtyZXR1cm4gcGYoaSx0KSt5ZihpLGUpK21mKGksbil9ZnVuY3Rpb24gZ2YoaSx0KXtjb25zdCBlPTEtaTtyZXR1cm4gZSplKmUqdH1mdW5jdGlvbiB4ZihpLHQpe2NvbnN0IGU9MS1pO3JldHVybiAzKmUqZSppKnR9ZnVuY3Rpb24gd2YoaSx0KXtyZXR1cm4gMyooMS1pKSppKmkqdH1mdW5jdGlvbiBiZihpLHQpe3JldHVybiBpKmkqaSp0fWZ1bmN0aW9uIEFpKGksdCxlLG4scyl7cmV0dXJuIGdmKGksdCkreGYoaSxlKSt3ZihpLG4pK2JmKGkscyl9Y2xhc3Mgem8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUixzPW5ldyBSKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlPSEwLHRoaXMudHlwZT0iQ3ViaWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW4sdGhpcy52Mz1zfWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyLGE9dGhpcy52MztyZXR1cm4gbi5zZXQoQWkodCxzLngsci54LG8ueCxhLngpLEFpKHQscy55LHIueSxvLnksYS55KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3Mga2MgZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQsbj1uZXcgVCxzPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNDdWJpY0JlemllckN1cnZlMz0hMCx0aGlzLnR5cGU9IkN1YmljQmV6aWVyQ3VydmUzIix0aGlzLnYwPXQsdGhpcy52MT1lLHRoaXMudjI9bix0aGlzLnYzPXN9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjIsYT10aGlzLnYzO3JldHVybiBuLnNldChBaSh0LHMueCxyLngsby54LGEueCksQWkodCxzLnksci55LG8ueSxhLnkpLEFpKHQscy56LHIueixvLnosYS56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXMudjMuY29weSh0LnYzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjA9dGhpcy52MC50b0FycmF5KCksdC52MT10aGlzLnYxLnRvQXJyYXkoKSx0LnYyPXRoaXMudjIudG9BcnJheSgpLHQudjM9dGhpcy52My50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpcy52My5mcm9tQXJyYXkodC52MyksdGhpc319Y2xhc3MgVG8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIpe3N1cGVyKCksdGhpcy5pc0xpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZSIsdGhpcy52MT10LHRoaXMudjI9ZX1nZXRQb2ludCh0LGU9bmV3IFIpe2NvbnN0IG49ZTtyZXR1cm4gdD09PTE/bi5jb3B5KHRoaXMudjIpOihuLmNvcHkodGhpcy52Mikuc3ViKHRoaXMudjEpLG4ubXVsdGlwbHlTY2FsYXIodCkuYWRkKHRoaXMudjEpKSxufWdldFBvaW50QXQodCxlKXtyZXR1cm4gdGhpcy5nZXRQb2ludCh0LGUpfWdldFRhbmdlbnQodCxlPW5ldyBSKXtyZXR1cm4gZS5zdWJWZWN0b3JzKHRoaXMudjIsdGhpcy52MSkubm9ybWFsaXplKCl9Z2V0VGFuZ2VudEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0VGFuZ2VudCh0LGUpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MS5jb3B5KHQudjEpLHRoaXMudjIuY29weSh0LnYyKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7cmV0dXJuIHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBOYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCl7c3VwZXIoKSx0aGlzLmlzTGluZUN1cnZlMz0hMCx0aGlzLnR5cGU9IkxpbmVDdXJ2ZTMiLHRoaXMudjE9dCx0aGlzLnYyPWV9Z2V0UG9pbnQodCxlPW5ldyBUKXtjb25zdCBuPWU7cmV0dXJuIHQ9PT0xP24uY29weSh0aGlzLnYyKToobi5jb3B5KHRoaXMudjIpLnN1Yih0aGlzLnYxKSxuLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnYxKSksbn1nZXRQb2ludEF0KHQsZSl7cmV0dXJuIHRoaXMuZ2V0UG9pbnQodCxlKX1nZXRUYW5nZW50KHQsZT1uZXcgVCl7cmV0dXJuIGUuc3ViVmVjdG9ycyh0aGlzLnYyLHRoaXMudjEpLm5vcm1hbGl6ZSgpfWdldFRhbmdlbnRBdCh0LGUpe3JldHVybiB0aGlzLmdldFRhbmdlbnQodCxlKX1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3MgRW8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PW5ldyBSLGU9bmV3IFIsbj1uZXcgUil7c3VwZXIoKSx0aGlzLmlzUXVhZHJhdGljQmV6aWVyQ3VydmU9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZSIsdGhpcy52MD10LHRoaXMudjE9ZSx0aGlzLnYyPW59Z2V0UG9pbnQodCxlPW5ldyBSKXtjb25zdCBuPWUscz10aGlzLnYwLHI9dGhpcy52MSxvPXRoaXMudjI7cmV0dXJuIG4uc2V0KE1pKHQscy54LHIueCxvLngpLE1pKHQscy55LHIueSxvLnkpKSxufWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy52MC5jb3B5KHQudjApLHRoaXMudjEuY29weSh0LnYxKSx0aGlzLnYyLmNvcHkodC52MiksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LnYwPXRoaXMudjAudG9BcnJheSgpLHQudjE9dGhpcy52MS50b0FycmF5KCksdC52Mj10aGlzLnYyLnRvQXJyYXkoKSx0fWZyb21KU09OKHQpe3JldHVybiBzdXBlci5mcm9tSlNPTih0KSx0aGlzLnYwLmZyb21BcnJheSh0LnYwKSx0aGlzLnYxLmZyb21BcnJheSh0LnYxKSx0aGlzLnYyLmZyb21BcnJheSh0LnYyKSx0aGlzfX1jbGFzcyBSYyBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQ9bmV3IFQsZT1uZXcgVCxuPW5ldyBUKXtzdXBlcigpLHRoaXMuaXNRdWFkcmF0aWNCZXppZXJDdXJ2ZTM9ITAsdGhpcy50eXBlPSJRdWFkcmF0aWNCZXppZXJDdXJ2ZTMiLHRoaXMudjA9dCx0aGlzLnYxPWUsdGhpcy52Mj1ufWdldFBvaW50KHQsZT1uZXcgVCl7Y29uc3Qgbj1lLHM9dGhpcy52MCxyPXRoaXMudjEsbz10aGlzLnYyO3JldHVybiBuLnNldChNaSh0LHMueCxyLngsby54KSxNaSh0LHMueSxyLnksby55KSxNaSh0LHMueixyLnosby56KSksbn1jb3B5KHQpe3JldHVybiBzdXBlci5jb3B5KHQpLHRoaXMudjAuY29weSh0LnYwKSx0aGlzLnYxLmNvcHkodC52MSksdGhpcy52Mi5jb3B5KHQudjIpLHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTtyZXR1cm4gdC52MD10aGlzLnYwLnRvQXJyYXkoKSx0LnYxPXRoaXMudjEudG9BcnJheSgpLHQudjI9dGhpcy52Mi50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy52MC5mcm9tQXJyYXkodC52MCksdGhpcy52MS5mcm9tQXJyYXkodC52MSksdGhpcy52Mi5mcm9tQXJyYXkodC52MiksdGhpc319Y2xhc3MgUG8gZXh0ZW5kcyB4ZXtjb25zdHJ1Y3Rvcih0PVtdKXtzdXBlcigpLHRoaXMuaXNTcGxpbmVDdXJ2ZT0hMCx0aGlzLnR5cGU9IlNwbGluZUN1cnZlIix0aGlzLnBvaW50cz10fWdldFBvaW50KHQsZT1uZXcgUil7Y29uc3Qgbj1lLHM9dGhpcy5wb2ludHMscj0ocy5sZW5ndGgtMSkqdCxvPU1hdGguZmxvb3IociksYT1yLW8sYz1zW289PT0wP286by0xXSxsPXNbb10saD1zW28+cy5sZW5ndGgtMj9zLmxlbmd0aC0xOm8rMV0sdT1zW28+cy5sZW5ndGgtMz9zLmxlbmd0aC0xOm8rMl07cmV0dXJuIG4uc2V0KEljKGEsYy54LGwueCxoLngsdS54KSxJYyhhLGMueSxsLnksaC55LHUueSkpLG59Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMucG9pbnRzPVtdO2ZvcihsZXQgZT0wLG49dC5wb2ludHMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5wb2ludHNbZV07dGhpcy5wb2ludHMucHVzaChzLmNsb25lKCkpfXJldHVybiB0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCk7dC5wb2ludHM9W107Zm9yKGxldCBlPTAsbj10aGlzLnBvaW50cy5sZW5ndGg7ZTxuO2UrKyl7Y29uc3Qgcz10aGlzLnBvaW50c1tlXTt0LnBvaW50cy5wdXNoKHMudG9BcnJheSgpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLnBvaW50cz1bXTtmb3IobGV0IGU9MCxuPXQucG9pbnRzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQucG9pbnRzW2VdO3RoaXMucG9pbnRzLnB1c2gobmV3IFIoKS5mcm9tQXJyYXkocykpfXJldHVybiB0aGlzfX12YXIgTGM9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQXJjQ3VydmU6QmMsQ2F0bXVsbFJvbUN1cnZlMzpGYyxDdWJpY0JlemllckN1cnZlOnpvLEN1YmljQmV6aWVyQ3VydmUzOmtjLEVsbGlwc2VDdXJ2ZTpNcyxMaW5lQ3VydmU6VG8sTGluZUN1cnZlMzpOYyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTpFbyxRdWFkcmF0aWNCZXppZXJDdXJ2ZTM6UmMsU3BsaW5lQ3VydmU6UG99KTtjbGFzcyBNZiBleHRlbmRzIHhle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9IkN1cnZlUGF0aCIsdGhpcy5jdXJ2ZXM9W10sdGhpcy5hdXRvQ2xvc2U9ITF9YWRkKHQpe3RoaXMuY3VydmVzLnB1c2godCl9Y2xvc2VQYXRoKCl7Y29uc3QgdD10aGlzLmN1cnZlc1swXS5nZXRQb2ludCgwKSxlPXRoaXMuY3VydmVzW3RoaXMuY3VydmVzLmxlbmd0aC0xXS5nZXRQb2ludCgxKTtpZighdC5lcXVhbHMoZSkpe2NvbnN0IG49dC5pc1ZlY3RvcjI9PT0hMD8iTGluZUN1cnZlIjoiTGluZUN1cnZlMyI7dGhpcy5jdXJ2ZXMucHVzaChuZXcgTGNbbl0oZSx0KSl9cmV0dXJuIHRoaXN9Z2V0UG9pbnQodCxlKXtjb25zdCBuPXQqdGhpcy5nZXRMZW5ndGgoKSxzPXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7bGV0IHI9MDtmb3IoO3I8cy5sZW5ndGg7KXtpZihzW3JdPj1uKXtjb25zdCBvPXNbcl0tbixhPXRoaXMuY3VydmVzW3JdLGM9YS5nZXRMZW5ndGgoKSxsPWM9PT0wPzA6MS1vL2M7cmV0dXJuIGEuZ2V0UG9pbnRBdChsLGUpfXIrK31yZXR1cm4gbnVsbH1nZXRMZW5ndGgoKXtjb25zdCB0PXRoaXMuZ2V0Q3VydmVMZW5ndGhzKCk7cmV0dXJuIHRbdC5sZW5ndGgtMV19dXBkYXRlQXJjTGVuZ3Rocygpe3RoaXMubmVlZHNVcGRhdGU9ITAsdGhpcy5jYWNoZUxlbmd0aHM9bnVsbCx0aGlzLmdldEN1cnZlTGVuZ3RocygpfWdldEN1cnZlTGVuZ3Rocygpe2lmKHRoaXMuY2FjaGVMZW5ndGhzJiZ0aGlzLmNhY2hlTGVuZ3Rocy5sZW5ndGg9PT10aGlzLmN1cnZlcy5sZW5ndGgpcmV0dXJuIHRoaXMuY2FjaGVMZW5ndGhzO2NvbnN0IHQ9W107bGV0IGU9MDtmb3IobGV0IG49MCxzPXRoaXMuY3VydmVzLmxlbmd0aDtuPHM7bisrKWUrPXRoaXMuY3VydmVzW25dLmdldExlbmd0aCgpLHQucHVzaChlKTtyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM9dCx0fWdldFNwYWNlZFBvaW50cyh0PTQwKXtjb25zdCBlPVtdO2ZvcihsZXQgbj0wO248PXQ7bisrKWUucHVzaCh0aGlzLmdldFBvaW50KG4vdCkpO3JldHVybiB0aGlzLmF1dG9DbG9zZSYmZS5wdXNoKGVbMF0pLGV9Z2V0UG9pbnRzKHQ9MTIpe2NvbnN0IGU9W107bGV0IG47Zm9yKGxldCBzPTAscj10aGlzLmN1cnZlcztzPHIubGVuZ3RoO3MrKyl7Y29uc3Qgbz1yW3NdLGE9by5pc0VsbGlwc2VDdXJ2ZT90KjI6by5pc0xpbmVDdXJ2ZXx8by5pc0xpbmVDdXJ2ZTM/MTpvLmlzU3BsaW5lQ3VydmU/dCpvLnBvaW50cy5sZW5ndGg6dCxjPW8uZ2V0UG9pbnRzKGEpO2ZvcihsZXQgbD0wO2w8Yy5sZW5ndGg7bCsrKXtjb25zdCBoPWNbbF07biYmbi5lcXVhbHMoaCl8fChlLnB1c2goaCksbj1oKX19cmV0dXJuIHRoaXMuYXV0b0Nsb3NlJiZlLmxlbmd0aD4xJiYhZVtlLmxlbmd0aC0xXS5lcXVhbHMoZVswXSkmJmUucHVzaChlWzBdKSxlfWNvcHkodCl7c3VwZXIuY29weSh0KSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gocy5jbG9uZSgpKX1yZXR1cm4gdGhpcy5hdXRvQ2xvc2U9dC5hdXRvQ2xvc2UsdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3QuYXV0b0Nsb3NlPXRoaXMuYXV0b0Nsb3NlLHQuY3VydmVzPVtdO2ZvcihsZXQgZT0wLG49dGhpcy5jdXJ2ZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dGhpcy5jdXJ2ZXNbZV07dC5jdXJ2ZXMucHVzaChzLnRvSlNPTigpKX1yZXR1cm4gdH1mcm9tSlNPTih0KXtzdXBlci5mcm9tSlNPTih0KSx0aGlzLmF1dG9DbG9zZT10LmF1dG9DbG9zZSx0aGlzLmN1cnZlcz1bXTtmb3IobGV0IGU9MCxuPXQuY3VydmVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuY3VydmVzW2VdO3RoaXMuY3VydmVzLnB1c2gobmV3IExjW3MudHlwZV0oKS5mcm9tSlNPTihzKSl9cmV0dXJuIHRoaXN9fWxldCBPYz1jbGFzcyBleHRlbmRzIE1me2NvbnN0cnVjdG9yKHQpe3N1cGVyKCksdGhpcy50eXBlPSJQYXRoIix0aGlzLmN1cnJlbnRQb2ludD1uZXcgUix0JiZ0aGlzLnNldEZyb21Qb2ludHModCl9c2V0RnJvbVBvaW50cyh0KXt0aGlzLm1vdmVUbyh0WzBdLngsdFswXS55KTtmb3IobGV0IGU9MSxuPXQubGVuZ3RoO2U8bjtlKyspdGhpcy5saW5lVG8odFtlXS54LHRbZV0ueSk7cmV0dXJuIHRoaXN9bW92ZVRvKHQsZSl7cmV0dXJuIHRoaXMuY3VycmVudFBvaW50LnNldCh0LGUpLHRoaXN9bGluZVRvKHQsZSl7Y29uc3Qgbj1uZXcgVG8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5zZXQodCxlKSx0aGlzfXF1YWRyYXRpY0N1cnZlVG8odCxlLG4scyl7Y29uc3Qgcj1uZXcgRW8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scykpO3JldHVybiB0aGlzLmN1cnZlcy5wdXNoKHIpLHRoaXMuY3VycmVudFBvaW50LnNldChuLHMpLHRoaXN9YmV6aWVyQ3VydmVUbyh0LGUsbixzLHIsbyl7Y29uc3QgYT1uZXcgem8odGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxuZXcgUih0LGUpLG5ldyBSKG4scyksbmV3IFIocixvKSk7cmV0dXJuIHRoaXMuY3VydmVzLnB1c2goYSksdGhpcy5jdXJyZW50UG9pbnQuc2V0KHIsbyksdGhpc31zcGxpbmVUaHJ1KHQpe2NvbnN0IGU9W3RoaXMuY3VycmVudFBvaW50LmNsb25lKCldLmNvbmNhdCh0KSxuPW5ldyBQbyhlKTtyZXR1cm4gdGhpcy5jdXJ2ZXMucHVzaChuKSx0aGlzLmN1cnJlbnRQb2ludC5jb3B5KHRbdC5sZW5ndGgtMV0pLHRoaXN9YXJjKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMuY3VycmVudFBvaW50LngsYz10aGlzLmN1cnJlbnRQb2ludC55O3JldHVybiB0aGlzLmFic2FyYyh0K2EsZStjLG4scyxyLG8pLHRoaXN9YWJzYXJjKHQsZSxuLHMscixvKXtyZXR1cm4gdGhpcy5hYnNlbGxpcHNlKHQsZSxuLG4scyxyLG8pLHRoaXN9ZWxsaXBzZSh0LGUsbixzLHIsbyxhLGMpe2NvbnN0IGw9dGhpcy5jdXJyZW50UG9pbnQueCxoPXRoaXMuY3VycmVudFBvaW50Lnk7cmV0dXJuIHRoaXMuYWJzZWxsaXBzZSh0K2wsZStoLG4scyxyLG8sYSxjKSx0aGlzfWFic2VsbGlwc2UodCxlLG4scyxyLG8sYSxjKXtjb25zdCBsPW5ldyBNcyh0LGUsbixzLHIsbyxhLGMpO2lmKHRoaXMuY3VydmVzLmxlbmd0aD4wKXtjb25zdCB1PWwuZ2V0UG9pbnQoMCk7dS5lcXVhbHModGhpcy5jdXJyZW50UG9pbnQpfHx0aGlzLmxpbmVUbyh1LngsdS55KX10aGlzLmN1cnZlcy5wdXNoKGwpO2NvbnN0IGg9bC5nZXRQb2ludCgxKTtyZXR1cm4gdGhpcy5jdXJyZW50UG9pbnQuY29weShoKSx0aGlzfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5jdXJyZW50UG9pbnQuY29weSh0LmN1cnJlbnRQb2ludCksdGhpc310b0pTT04oKXtjb25zdCB0PXN1cGVyLnRvSlNPTigpO3JldHVybiB0LmN1cnJlbnRQb2ludD10aGlzLmN1cnJlbnRQb2ludC50b0FycmF5KCksdH1mcm9tSlNPTih0KXtyZXR1cm4gc3VwZXIuZnJvbUpTT04odCksdGhpcy5jdXJyZW50UG9pbnQuZnJvbUFycmF5KHQuY3VycmVudFBvaW50KSx0aGlzfX07Y2xhc3MgRGMgZXh0ZW5kcyBPY3tjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLnV1aWQ9Qm4oKSx0aGlzLnR5cGU9IlNoYXBlIix0aGlzLmhvbGVzPVtdfWdldFBvaW50c0hvbGVzKHQpe2NvbnN0IGU9W107Zm9yKGxldCBuPTAscz10aGlzLmhvbGVzLmxlbmd0aDtuPHM7bisrKWVbbl09dGhpcy5ob2xlc1tuXS5nZXRQb2ludHModCk7cmV0dXJuIGV9ZXh0cmFjdFBvaW50cyh0KXtyZXR1cm57c2hhcGU6dGhpcy5nZXRQb2ludHModCksaG9sZXM6dGhpcy5nZXRQb2ludHNIb2xlcyh0KX19Y29weSh0KXtzdXBlci5jb3B5KHQpLHRoaXMuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10LmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXQuaG9sZXNbZV07dGhpcy5ob2xlcy5wdXNoKHMuY2xvbmUoKSl9cmV0dXJuIHRoaXN9dG9KU09OKCl7Y29uc3QgdD1zdXBlci50b0pTT04oKTt0LnV1aWQ9dGhpcy51dWlkLHQuaG9sZXM9W107Zm9yKGxldCBlPTAsbj10aGlzLmhvbGVzLmxlbmd0aDtlPG47ZSsrKXtjb25zdCBzPXRoaXMuaG9sZXNbZV07dC5ob2xlcy5wdXNoKHMudG9KU09OKCkpfXJldHVybiB0fWZyb21KU09OKHQpe3N1cGVyLmZyb21KU09OKHQpLHRoaXMudXVpZD10LnV1aWQsdGhpcy5ob2xlcz1bXTtmb3IobGV0IGU9MCxuPXQuaG9sZXMubGVuZ3RoO2U8bjtlKyspe2NvbnN0IHM9dC5ob2xlc1tlXTt0aGlzLmhvbGVzLnB1c2gobmV3IE9jKCkuZnJvbUpTT04ocykpfXJldHVybiB0aGlzfX1mdW5jdGlvbiBBZihpLHQsZT0yKXtjb25zdCBuPXQmJnQubGVuZ3RoLHM9bj90WzBdKmU6aS5sZW5ndGg7bGV0IHI9JGMoaSwwLHMsZSwhMCk7Y29uc3Qgbz1bXTtpZighcnx8ci5uZXh0PT09ci5wcmV2KXJldHVybiBvO2xldCBhLGMsbDtpZihuJiYocj1UZihpLHQscixlKSksaS5sZW5ndGg+ODAqZSl7YT0xLzAsYz0xLzA7bGV0IGg9LTEvMCx1PS0xLzA7Zm9yKGxldCBmPWU7ZjxzO2YrPWUpe2NvbnN0IGQ9aVtmXSxwPWlbZisxXTtkPGEmJihhPWQpLHA8YyYmKGM9cCksZD5oJiYoaD1kKSxwPnUmJih1PXApfWw9TWF0aC5tYXgoaC1hLHUtYyksbD1sIT09MD8zMjc2Ny9sOjB9cmV0dXJuIF9pKHIsbyxlLGEsYyxsLDApLG99ZnVuY3Rpb24gJGMoaSx0LGUsbixzKXtsZXQgcjtpZihzPT09T2YoaSx0LGUsbik+MClmb3IobGV0IG89dDtvPGU7bys9bilyPUhjKG8vbnwwLGlbb10saVtvKzFdLHIpO2Vsc2UgZm9yKGxldCBvPWUtbjtvPj10O28tPW4pcj1IYyhvL258MCxpW29dLGlbbysxXSxyKTtyZXR1cm4gciYmcW4ocixyLm5leHQpJiYoemkocikscj1yLm5leHQpLHJ9ZnVuY3Rpb24gZm4oaSx0KXtpZighaSlyZXR1cm4gaTt0fHwodD1pKTtsZXQgZT1pLG47ZG8gaWYobj0hMSwhZS5zdGVpbmVyJiYocW4oZSxlLm5leHQpfHxydChlLnByZXYsZSxlLm5leHQpPT09MCkpe2lmKHppKGUpLGU9dD1lLnByZXYsZT09PWUubmV4dClicmVhaztuPSEwfWVsc2UgZT1lLm5leHQ7d2hpbGUobnx8ZSE9PXQpO3JldHVybiB0fWZ1bmN0aW9uIF9pKGksdCxlLG4scyxyLG8pe2lmKCFpKXJldHVybjshbyYmciYmRmYoaSxuLHMscik7bGV0IGE9aTtmb3IoO2kucHJldiE9PWkubmV4dDspe2NvbnN0IGM9aS5wcmV2LGw9aS5uZXh0O2lmKHI/U2YoaSxuLHMscik6X2YoaSkpe3QucHVzaChjLmksaS5pLGwuaSksemkoaSksaT1sLm5leHQsYT1sLm5leHQ7Y29udGludWV9aWYoaT1sLGk9PT1hKXtvP289PT0xPyhpPXZmKGZuKGkpLHQpLF9pKGksdCxlLG4scyxyLDIpKTpvPT09MiYmemYoaSx0LGUsbixzLHIpOl9pKGZuKGkpLHQsZSxuLHMsciwxKTticmVha319fWZ1bmN0aW9uIF9mKGkpe2NvbnN0IHQ9aS5wcmV2LGU9aSxuPWkubmV4dDtpZihydCh0LGUsbik+PTApcmV0dXJuITE7Y29uc3Qgcz10Lngscj1lLngsbz1uLngsYT10LnksYz1lLnksbD1uLnksaD1NYXRoLm1pbihzLHIsbyksdT1NYXRoLm1pbihhLGMsbCksZj1NYXRoLm1heChzLHIsbyksZD1NYXRoLm1heChhLGMsbCk7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJlNpKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZydChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIFNmKGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihydChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1NYXRoLm1pbihhLGMsbCkscD1NYXRoLm1pbihoLHUsZikseT1NYXRoLm1heChhLGMsbCksbT1NYXRoLm1heChoLHUsZiksZz1DbyhkLHAsdCxlLG4pLGI9Q28oeSxtLHQsZSxuKTtsZXQgdz1pLnByZXZaLHg9aS5uZXh0Wjtmb3IoO3cmJncuej49ZyYmeCYmeC56PD1iOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJlNpKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wfHwodz13LnByZXZaLHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZTaShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MCkpcmV0dXJuITE7eD14Lm5leHRafWZvcig7dyYmdy56Pj1nOyl7aWYody54Pj1kJiZ3Lng8PXkmJncueT49cCYmdy55PD1tJiZ3IT09cyYmdyE9PW8mJlNpKGEsaCxjLHUsbCxmLHcueCx3LnkpJiZydCh3LnByZXYsdyx3Lm5leHQpPj0wKXJldHVybiExO3c9dy5wcmV2Wn1mb3IoO3gmJnguejw9Yjspe2lmKHgueD49ZCYmeC54PD15JiZ4Lnk+PXAmJngueTw9bSYmeCE9PXMmJnghPT1vJiZTaShhLGgsYyx1LGwsZix4LngseC55KSYmcnQoeC5wcmV2LHgseC5uZXh0KT49MClyZXR1cm4hMTt4PXgubmV4dFp9cmV0dXJuITB9ZnVuY3Rpb24gdmYoaSx0KXtsZXQgZT1pO2Rve2NvbnN0IG49ZS5wcmV2LHM9ZS5uZXh0Lm5leHQ7IXFuKG4scykmJlZjKG4sZSxlLm5leHQscykmJnZpKG4scykmJnZpKHMsbikmJih0LnB1c2gobi5pLGUuaSxzLmkpLHppKGUpLHppKGUubmV4dCksZT1pPXMpLGU9ZS5uZXh0fXdoaWxlKGUhPT1pKTtyZXR1cm4gZm4oZSl9ZnVuY3Rpb24gemYoaSx0LGUsbixzLHIpe2xldCBvPWk7ZG97bGV0IGE9by5uZXh0Lm5leHQ7Zm9yKDthIT09by5wcmV2Oyl7aWYoby5pIT09YS5pJiZOZihvLGEpKXtsZXQgYz1xYyhvLGEpO289Zm4obyxvLm5leHQpLGM9Zm4oYyxjLm5leHQpLF9pKG8sdCxlLG4scyxyLDApLF9pKGMsdCxlLG4scyxyLDApO3JldHVybn1hPWEubmV4dH1vPW8ubmV4dH13aGlsZShvIT09aSl9ZnVuY3Rpb24gVGYoaSx0LGUsbil7Y29uc3Qgcz1bXTtmb3IobGV0IHI9MCxvPXQubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9dFtyXSpuLGM9cjxvLTE/dFtyKzFdKm46aS5sZW5ndGgsbD0kYyhpLGEsYyxuLCExKTtsPT09bC5uZXh0JiYobC5zdGVpbmVyPSEwKSxzLnB1c2goa2YobCkpfXMuc29ydChFZik7Zm9yKGxldCByPTA7cjxzLmxlbmd0aDtyKyspZT1QZihzW3JdLGUpO3JldHVybiBlfWZ1bmN0aW9uIEVmKGksdCl7bGV0IGU9aS54LXQueDtpZihlPT09MCYmKGU9aS55LXQueSxlPT09MCkpe2NvbnN0IG49KGkubmV4dC55LWkueSkvKGkubmV4dC54LWkueCkscz0odC5uZXh0LnktdC55KS8odC5uZXh0LngtdC54KTtlPW4tc31yZXR1cm4gZX1mdW5jdGlvbiBQZihpLHQpe2NvbnN0IGU9Q2YoaSx0KTtpZighZSlyZXR1cm4gdDtjb25zdCBuPXFjKGUsaSk7cmV0dXJuIGZuKG4sbi5uZXh0KSxmbihlLGUubmV4dCl9ZnVuY3Rpb24gQ2YoaSx0KXtsZXQgZT10O2NvbnN0IG49aS54LHM9aS55O2xldCByPS0xLzAsbztpZihxbihpLGUpKXJldHVybiBlO2Rve2lmKHFuKGksZS5uZXh0KSlyZXR1cm4gZS5uZXh0O2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZVYyhzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTt2aShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmQmYobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIEJmKGksdCl7cmV0dXJuIHJ0KGkucHJldixpLHQucHJldik8MCYmcnQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIEZmKGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1DbyhzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwsSWYocyl9ZnVuY3Rpb24gSWYoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBDbyhpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24ga2YoaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIFVjKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiBTaShpLHQsZSxuLHMscixvLGEpe3JldHVybiEoaT09PW8mJnQ9PT1hKSYmVWMoaSx0LGUsbixzLHIsbyxhKX1mdW5jdGlvbiBOZihpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFSZihpLHQpJiYodmkoaSx0KSYmdmkodCxpKSYmTGYoaSx0KSYmKHJ0KGkucHJldixpLHQucHJldil8fHJ0KGksdC5wcmV2LHQpKXx8cW4oaSx0KSYmcnQoaS5wcmV2LGksaS5uZXh0KT4wJiZydCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIHJ0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24gcW4oaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gVmMoaSx0LGUsbil7Y29uc3Qgcz1TcyhydChpLHQsZSkpLHI9U3MocnQoaSx0LG4pKSxvPVNzKHJ0KGUsbixpKSksYT1TcyhydChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJl9zKGksZSx0KXx8cj09PTAmJl9zKGksbix0KXx8bz09PTAmJl9zKGUsaSxuKXx8YT09PTAmJl9zKGUsdCxuKSl9ZnVuY3Rpb24gX3MoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIFNzKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBSZihpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmVmMoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gdmkoaSx0KXtyZXR1cm4gcnQoaS5wcmV2LGksaS5uZXh0KTwwP3J0KGksdCxpLm5leHQpPj0wJiZydChpLGkucHJldix0KT49MDpydChpLHQsaS5wcmV2KTwwfHxydChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIExmKGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gcWMoaSx0KXtjb25zdCBlPUJvKGkuaSxpLngsaS55KSxuPUJvKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBIYyhpLHQsZSxuKXtjb25zdCBzPUJvKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gemkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBCbyhpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gT2YoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWNsYXNzIERme3N0YXRpYyB0cmlhbmd1bGF0ZSh0LGUsbj0yKXtyZXR1cm4gQWYodCxlLG4pfX1jbGFzcyBIbntzdGF0aWMgYXJlYSh0KXtjb25zdCBlPXQubGVuZ3RoO2xldCBuPTA7Zm9yKGxldCBzPWUtMSxyPTA7cjxlO3M9cisrKW4rPXRbc10ueCp0W3JdLnktdFtyXS54KnRbc10ueTtyZXR1cm4gbiouNX1zdGF0aWMgaXNDbG9ja1dpc2UodCl7cmV0dXJuIEhuLmFyZWEodCk8MH1zdGF0aWMgdHJpYW5ndWxhdGVTaGFwZSh0LGUpe2NvbnN0IG49W10scz1bXSxyPVtdO1djKHQpLEdjKG4sdCk7bGV0IG89dC5sZW5ndGg7ZS5mb3JFYWNoKFdjKTtmb3IobGV0IGM9MDtjPGUubGVuZ3RoO2MrKylzLnB1c2gobyksbys9ZVtjXS5sZW5ndGgsR2MobixlW2NdKTtjb25zdCBhPURmLnRyaWFuZ3VsYXRlKG4scyk7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKz0zKXIucHVzaChhLnNsaWNlKGMsYyszKSk7cmV0dXJuIHJ9fWZ1bmN0aW9uIFdjKGkpe2NvbnN0IHQ9aS5sZW5ndGg7dD4yJiZpW3QtMV0uZXF1YWxzKGlbMF0pJiZpLnBvcCgpfWZ1bmN0aW9uIEdjKGksdCl7Zm9yKGxldCBlPTA7ZTx0Lmxlbmd0aDtlKyspaS5wdXNoKHRbZV0ueCksaS5wdXNoKHRbZV0ueSl9Y2xhc3MgRm8gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PTEsZT0xLG49MSxzPTEpe3N1cGVyKCksdGhpcy50eXBlPSJQbGFuZUdlb21ldHJ5Iix0aGlzLnBhcmFtZXRlcnM9e3dpZHRoOnQsaGVpZ2h0OmUsd2lkdGhTZWdtZW50czpuLGhlaWdodFNlZ21lbnRzOnN9O2NvbnN0IHI9dC8yLG89ZS8yLGE9TWF0aC5mbG9vcihuKSxjPU1hdGguZmxvb3IocyksbD1hKzEsaD1jKzEsdT10L2EsZj1lL2MsZD1bXSxwPVtdLHk9W10sbT1bXTtmb3IobGV0IGc9MDtnPGg7ZysrKXtjb25zdCBiPWcqZi1vO2ZvcihsZXQgdz0wO3c8bDt3Kyspe2NvbnN0IHg9dyp1LXI7cC5wdXNoKHgsLWIsMCkseS5wdXNoKDAsMCwxKSxtLnB1c2gody9hKSxtLnB1c2goMS1nL2MpfX1mb3IobGV0IGc9MDtnPGM7ZysrKWZvcihsZXQgYj0wO2I8YTtiKyspe2NvbnN0IHc9YitsKmcseD1iK2wqKGcrMSksTT1iKzErbCooZysxKSxBPWIrMStsKmc7ZC5wdXNoKHcseCxBKSxkLnB1c2goeCxNLEEpfXRoaXMuc2V0SW5kZXgoZCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIixuZXcgQ2UocCwzKSksdGhpcy5zZXRBdHRyaWJ1dGUoIm5vcm1hbCIsbmV3IENlKHksMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IENlKG0sMikpfWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXN0YXRpYyBmcm9tSlNPTih0KXtyZXR1cm4gbmV3IEZvKHQud2lkdGgsdC5oZWlnaHQsdC53aWR0aFNlZ21lbnRzLHQuaGVpZ2h0U2VnbWVudHMpfX1jb25zdCBaYz1uZXcgVCx2cz1uZXcgVDtjbGFzcyBRdHtjb25zdHJ1Y3Rvcih0PW5ldyBULGU9bmV3IFQpe3RoaXMuc3RhcnQ9dCx0aGlzLmVuZD1lfXNldCh0LGUpe3JldHVybiB0aGlzLnN0YXJ0LmNvcHkodCksdGhpcy5lbmQuY29weShlKSx0aGlzfWNvcHkodCl7cmV0dXJuIHRoaXMuc3RhcnQuY29weSh0LnN0YXJ0KSx0aGlzLmVuZC5jb3B5KHQuZW5kKSx0aGlzfWdldENlbnRlcih0KXtyZXR1cm4gdC5hZGRWZWN0b3JzKHRoaXMuc3RhcnQsdGhpcy5lbmQpLm11bHRpcGx5U2NhbGFyKC41KX1kZWx0YSh0KXtyZXR1cm4gdC5zdWJWZWN0b3JzKHRoaXMuZW5kLHRoaXMuc3RhcnQpfWRpc3RhbmNlU3EoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvU3F1YXJlZCh0aGlzLmVuZCl9ZGlzdGFuY2UoKXtyZXR1cm4gdGhpcy5zdGFydC5kaXN0YW5jZVRvKHRoaXMuZW5kKX1hdCh0LGUpe3JldHVybiB0aGlzLmRlbHRhKGUpLm11bHRpcGx5U2NhbGFyKHQpLmFkZCh0aGlzLnN0YXJ0KX1jbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyKHQsZSl7WmMuc3ViVmVjdG9ycyh0LHRoaXMuc3RhcnQpLHZzLnN1YlZlY3RvcnModGhpcy5lbmQsdGhpcy5zdGFydCk7Y29uc3Qgbj12cy5kb3QodnMpO2xldCByPXZzLmRvdChaYykvbjtyZXR1cm4gZSYmKHI9WihyLDAsMSkpLHJ9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LGUsbil7Y29uc3Qgcz10aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxlKTtyZXR1cm4gdGhpcy5kZWx0YShuKS5tdWx0aXBseVNjYWxhcihzKS5hZGQodGhpcy5zdGFydCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0aGlzLnN0YXJ0LmFwcGx5TWF0cml4NCh0KSx0aGlzLmVuZC5hcHBseU1hdHJpeDQodCksdGhpc31lcXVhbHModCl7cmV0dXJuIHQuc3RhcnQuZXF1YWxzKHRoaXMuc3RhcnQpJiZ0LmVuZC5lcXVhbHModGhpcy5lbmQpfWNsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX19dHlwZW9mIF9fVEhSRUVfREVWVE9PTFNfXyE9InVuZGVmaW5lZCImJl9fVEhSRUVfREVWVE9PTFNfXy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudCgicmVnaXN0ZXIiLHtkZXRhaWw6e3JldmlzaW9uOkp9fSkpLHR5cGVvZiB3aW5kb3chPSJ1bmRlZmluZWQiJiYod2luZG93Ll9fVEhSRUVfXz9jb25zb2xlLndhcm4oIldBUk5JTkc6IE11bHRpcGxlIGluc3RhbmNlcyBvZiBUaHJlZS5qcyBiZWluZyBpbXBvcnRlZC4iKTp3aW5kb3cuX19USFJFRV9fPUopO2NvbnN0IGRuPW5ldyBNYXAsJGY9KGk9e30pPT4oe2dlbmVyYXRlVG9wVVYodCxlLG4scyxyKXtjb25zdCBvPWVbbiozXSxhPWVbbiozKzFdLGM9ZVtzKjNdLGw9ZVtzKjMrMV0saD1lW3IqM10sdT1lW3IqMysxXTtsZXQgZjtpZihkbi5oYXModCkpZj1kbi5nZXQodCk7ZWxzZXtsZXQgbT1pLmJveDM7aWYoIW0pe209bmV3IGd0O2NvbnN0IHc9dC5wYXJhbWV0ZXJzLnNoYXBlcy5nZXRQb2ludHMoKS5tYXAoeD0+W3gueCx4LnksMF0pLmZsYXQoKTttLnNldEZyb21BcnJheSh3KX1jb25zdCBnPW0uZ2V0U2l6ZShuZXcgVCk7aS5zcGxpdCYmKGcueS89aS5zcGxpdCksZj17Ym94Om0sc2l6ZTpnfSxkbi5zZXQodCxmKX1jb25zdHtib3g6ZCxzaXplOnB9PWYseT1pLnNwbGl0PzEtaS5zcGxpdDowO3JldHVybltuZXcgUigoby1kLm1pbi54KS9wLngsKGEtZC5taW4ueSkvcC55K3kpLG5ldyBSKChjLWQubWluLngpL3AueCwobC1kLm1pbi55KS9wLnkreSksbmV3IFIoKGgtZC5taW4ueCkvcC54LCh1LWQubWluLnkpL3AueSt5KV19LGdlbmVyYXRlU2lkZVdhbGxVVih0LGUsbixzLHIsbyl7Y29uc3QgYT1lW24qM10sYz1lW24qMysxXSxsPWVbbiozKzJdLGg9ZVtzKjNdLHU9ZVtzKjMrMV0sZj1lW3MqMysyXSxkPWVbciozXSxwPWVbciozKzFdLHk9ZVtyKjMrMl0sbT1lW28qM10sZz1lW28qMysxXSxiPWVbbyozKzJdO2xldCB3O2lmKGRuLmhhcyhlKSl3PWRuLmdldChlKTtlbHNle2NvbnN0IEE9bmV3IGd0O0Euc2V0RnJvbUFycmF5KGUpO2NvbnN0IF89QS5nZXRTaXplKG5ldyBUKTtpLnNwbGl0JiYoXy56Lz0xLWkuc3BsaXQpLGkuc2lkZVJlcGVhdCYmKF8uei89aS5zaWRlUmVwZWF0KSx3PXtib3g6QSxzaXplOl99LGRuLnNldChlLHcpfWNvbnN0e2JveDp4LHNpemU6TX09dztyZXR1cm4gTWF0aC5hYnMoYy11KTxNYXRoLmFicyhhLWgpP1tuZXcgUigoYS14Lm1pbi54KS9NLngsKGwteC5taW4ueikvTS56KSxuZXcgUigoaC14Lm1pbi54KS9NLngsKGYteC5taW4ueikvTS56KSxuZXcgUigoZC14Lm1pbi54KS9NLngsKHkteC5taW4ueikvTS56KSxuZXcgUigobS14Lm1pbi54KS9NLngsKGIteC5taW4ueikvTS56KV06W25ldyBSKChjLXgubWluLnkpL00ueSwobC14Lm1pbi56KS9NLnopLG5ldyBSKCh1LXgubWluLnkpL00ueSwoZi14Lm1pbi56KS9NLnopLG5ldyBSKChwLXgubWluLnkpL00ueSwoeS14Lm1pbi56KS9NLnopLG5ldyBSKChnLXgubWluLnkpL00ueSwoYi14Lm1pbi56KS9NLnopXX19KSxVZj0oKT0+e2RuLmNsZWFyKCl9LFZmPXtBcmNDdXJ2ZTpCYyxDYXRtdWxsUm9tQ3VydmUzOkZjLEN1YmljQmV6aWVyQ3VydmU6em8sQ3ViaWNCZXppZXJDdXJ2ZTM6a2MsRWxsaXBzZUN1cnZlOk1zLExpbmVDdXJ2ZTpUbyxMaW5lQ3VydmUzOk5jLFF1YWRyYXRpY0JlemllckN1cnZlOkVvLFF1YWRyYXRpY0JlemllckN1cnZlMzpSYyxTcGxpbmVDdXJ2ZTpQb307Y2xhc3MgV24gZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0PW5ldyBEYyhbbmV3IFIoLjUsLjUpLG5ldyBSKC0uNSwuNSksbmV3IFIoLS41LC0uNSksbmV3IFIoLjUsLS41KV0pLGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJFeHRydWRlR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz17c2hhcGVzOnQsb3B0aW9uczplfSx0PUFycmF5LmlzQXJyYXkodCk/dDpbdF07Y29uc3Qgbj10aGlzLHM9W10scj1bXTtmb3IobGV0IGE9MCxjPXQubGVuZ3RoO2E8YzthKyspe2NvbnN0IGw9dFthXTtvKGwpfXRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsbmV3IENlKHMsMykpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsbmV3IENlKHIsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtmdW5jdGlvbiBvKGEpe3ZhciBFdSxQdSxDdTtjb25zdCBjPVtdLGw9ZS5jdXJ2ZVNlZ21lbnRzIT09dm9pZCAwP2UuY3VydmVTZWdtZW50czoxMixoPWUuc3RlcHMhPT12b2lkIDA/ZS5zdGVwczoxLHU9ZS5kZXB0aCE9PXZvaWQgMD9lLmRlcHRoOjE7bGV0IGY9ZS5iZXZlbEVuYWJsZWQhPT12b2lkIDA/ZS5iZXZlbEVuYWJsZWQ6ITAsZD1lLmJldmVsVGhpY2tuZXNzIT09dm9pZCAwP2UuYmV2ZWxUaGlja25lc3M6LjIscD1lLmJldmVsU2l6ZSE9PXZvaWQgMD9lLmJldmVsU2l6ZTpkLS4xLHk9ZS5iZXZlbE9mZnNldCE9PXZvaWQgMD9lLmJldmVsT2Zmc2V0OjAsbT1lLmJldmVsU2VnbWVudHMhPT12b2lkIDA/ZS5iZXZlbFNlZ21lbnRzOjM7Y29uc3QgZz1lLmV4dHJ1ZGVQYXRoLGI9ZS5VVkdlbmVyYXRvciE9PXZvaWQgMD9lLlVWR2VuZXJhdG9yOnFmLHc9KEV1PWUuaGFzVG9wKSE9bnVsbD9FdTohMCx4PShQdT1lLmhhc0JvdHRvbSkhPW51bGw/UHU6ITAsTT0oQ3U9ZS5oYXNTaWRlKSE9bnVsbD9DdTohMDtsZXQgQSxfPSExLFMsRSx6LHY7ZyYmKEE9Zy5nZXRTcGFjZWRQb2ludHMoaCksXz0hMCxmPSExLFM9Zy5jb21wdXRlRnJlbmV0RnJhbWVzKGgsITEpLEU9bmV3IFQsej1uZXcgVCx2PW5ldyBUKSxmfHwobT0wLGQ9MCxwPTAseT0wKTtjb25zdCBDPWEuZXh0cmFjdFBvaW50cyhsKTtsZXQgUD1DLnNoYXBlO2NvbnN0IEY9Qy5ob2xlcztpZighSG4uaXNDbG9ja1dpc2UoUCkpe1A9UC5yZXZlcnNlKCk7Zm9yKGxldCBOPTAsTD1GLmxlbmd0aDtOPEw7TisrKXtjb25zdCBPPUZbTl07SG4uaXNDbG9ja1dpc2UoTykmJihGW05dPU8ucmV2ZXJzZSgpKX19ZnVuY3Rpb24gSShOKXtjb25zdCBPPTEwMDAwMDAwMDAwMDAwMDAxZS0zNjtsZXQgVT1OWzBdO2ZvcihsZXQgJD0xOyQ8PU4ubGVuZ3RoOyQrKyl7Y29uc3QgWT0kJU4ubGVuZ3RoLEc9TltZXSxpdD1HLngtVS54LGN0PUcueS1VLnksd3Q9aXQqaXQrY3QqY3QsWHQ9TWF0aC5tYXgoTWF0aC5hYnMoRy54KSxNYXRoLmFicyhHLnkpLE1hdGguYWJzKFUueCksTWF0aC5hYnMoVS55KSksUG49TypYdCpYdDtpZih3dDw9UG4pe04uc3BsaWNlKFksMSksJC0tO2NvbnRpbnVlfVU9R319SShQKSxGLmZvckVhY2goSSk7Y29uc3Qgaz1GLmxlbmd0aCxEPVA7Zm9yKGxldCBOPTA7TjxrO04rKyl7Y29uc3QgTD1GW05dO1A9UC5jb25jYXQoTCl9ZnVuY3Rpb24gVihOLEwsTyl7cmV0dXJuIEx8fGNvbnNvbGUuZXJyb3IoIlRIUkVFLkV4dHJ1ZGVHZW9tZXRyeTogdmVjIGRvZXMgbm90IGV4aXN0IiksTi5jbG9uZSgpLmFkZFNjYWxlZFZlY3RvcihMLE8pfWNvbnN0IGo9UC5sZW5ndGg7ZnVuY3Rpb24gZHQoTixMLE8pe2xldCBVLCQsWTtjb25zdCBHPU4ueC1MLngsaXQ9Ti55LUwueSxjdD1PLngtTi54LHd0PU8ueS1OLnksWHQ9RypHK2l0Kml0LFBuPUcqd3QtaXQqY3Q7aWYoTWF0aC5hYnMoUG4pPk51bWJlci5FUFNJTE9OKXtjb25zdCBKdD1NYXRoLnNxcnQoWHQpLEJ1PU1hdGguc3FydChjdCpjdCt3dCp3dCksRnU9TC54LWl0L0p0LEl1PUwueStHL0p0LEFnPU8ueC13dC9CdSxfZz1PLnkrY3QvQnUsa3U9KChBZy1GdSkqd3QtKF9nLUl1KSpjdCkvKEcqd3QtaXQqY3QpO1U9RnUrRyprdS1OLngsJD1JdStpdCprdS1OLnk7Y29uc3QgTnU9VSpVKyQqJDtpZihOdTw9MilyZXR1cm4gbmV3IFIoVSwkKTtZPU1hdGguc3FydChOdS8yKX1lbHNle2xldCBKdD0hMTtHPk51bWJlci5FUFNJTE9OP2N0Pk51bWJlci5FUFNJTE9OJiYoSnQ9ITApOkc8LU51bWJlci5FUFNJTE9OP2N0PC1OdW1iZXIuRVBTSUxPTiYmKEp0PSEwKTpNYXRoLnNpZ24oaXQpPT09TWF0aC5zaWduKHd0KSYmKEp0PSEwKSxKdD8oVT0taXQsJD1HLFk9TWF0aC5zcXJ0KFh0KSk6KFU9RywkPWl0LFk9TWF0aC5zcXJ0KFh0LzIpKX1yZXR1cm4gbmV3IFIoVS9ZLCQvWSl9Y29uc3QgRHQ9W107Zm9yKGxldCBOPTAsTD1ELmxlbmd0aCxPPUwtMSxVPU4rMTtOPEw7TisrLE8rKyxVKyspTz09PUwmJihPPTApLFU9PT1MJiYoVT0wKSxEdFtOXT1kdChEW05dLERbT10sRFtVXSk7Y29uc3QgR3Q9W107bGV0IFp0LG1lPUR0LmNvbmNhdCgpO2ZvcihsZXQgTj0wLEw9aztOPEw7TisrKXtjb25zdCBPPUZbTl07WnQ9W107Zm9yKGxldCBVPTAsJD1PLmxlbmd0aCxZPSQtMSxHPVUrMTtVPCQ7VSsrLFkrKyxHKyspWT09PSQmJihZPTApLEc9PT0kJiYoRz0wKSxadFtVXT1kdChPW1VdLE9bWV0sT1tHXSk7R3QucHVzaChadCksbWU9bWUuY29uY2F0KFp0KX1sZXQgRW47aWYobT09PTApRW49SG4udHJpYW5ndWxhdGVTaGFwZShELEYpO2Vsc2V7Y29uc3QgTj1bXSxMPVtdO2ZvcihsZXQgTz0wO088bTtPKyspe2NvbnN0IFU9Ty9tLCQ9ZCpNYXRoLmNvcyhVKk1hdGguUEkvMiksWT1wKk1hdGguc2luKFUqTWF0aC5QSS8yKSt5O2ZvcihsZXQgRz0wLGl0PUQubGVuZ3RoO0c8aXQ7RysrKXtjb25zdCBjdD1WKERbR10sRHRbR10sWSk7cWUoY3QueCxjdC55LC0kKSxVPT09MCYmTi5wdXNoKGN0KX1mb3IobGV0IEc9MCxpdD1rO0c8aXQ7RysrKXtjb25zdCBjdD1GW0ddO1p0PUd0W0ddO2NvbnN0IHd0PVtdO2ZvcihsZXQgWHQ9MCxQbj1jdC5sZW5ndGg7WHQ8UG47WHQrKyl7Y29uc3QgSnQ9VihjdFtYdF0sWnRbWHRdLFkpO3FlKEp0LngsSnQueSwtJCksVT09PTAmJnd0LnB1c2goSnQpfVU9PT0wJiZMLnB1c2god3QpfX1Fbj1Ibi50cmlhbmd1bGF0ZVNoYXBlKE4sTCl9Y29uc3QgR3I9RW4ubGVuZ3RoLHp1PXAreTtmb3IobGV0IE49MDtOPGo7TisrKXtjb25zdCBMPWY/VihQW05dLG1lW05dLHp1KTpQW05dO18/KHouY29weShTLm5vcm1hbHNbMF0pLm11bHRpcGx5U2NhbGFyKEwueCksRS5jb3B5KFMuYmlub3JtYWxzWzBdKS5tdWx0aXBseVNjYWxhcihMLnkpLHYuY29weShBWzBdKS5hZGQoeikuYWRkKEUpLHFlKHYueCx2Lnksdi56KSk6cWUoTC54LEwueSwwKX1mb3IobGV0IE49MTtOPD1oO04rKylmb3IobGV0IEw9MDtMPGo7TCsrKXtjb25zdCBPPWY/VihQW0xdLG1lW0xdLHp1KTpQW0xdO18/KHouY29weShTLm5vcm1hbHNbTl0pLm11bHRpcGx5U2NhbGFyKE8ueCksRS5jb3B5KFMuYmlub3JtYWxzW05dKS5tdWx0aXBseVNjYWxhcihPLnkpLHYuY29weShBW05dKS5hZGQoeikuYWRkKEUpLHFlKHYueCx2Lnksdi56KSk6cWUoTy54LE8ueSx1L2gqTil9Zm9yKGxldCBOPW0tMTtOPj0wO04tLSl7Y29uc3QgTD1OL20sTz1kKk1hdGguY29zKEwqTWF0aC5QSS8yKSxVPXAqTWF0aC5zaW4oTCpNYXRoLlBJLzIpK3k7Zm9yKGxldCAkPTAsWT1ELmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPVYoRFskXSxEdFskXSxVKTtxZShHLngsRy55LHUrTyl9Zm9yKGxldCAkPTAsWT1GLmxlbmd0aDskPFk7JCsrKXtjb25zdCBHPUZbJF07WnQ9R3RbJF07Zm9yKGxldCBpdD0wLGN0PUcubGVuZ3RoO2l0PGN0O2l0Kyspe2NvbnN0IHd0PVYoR1tpdF0sWnRbaXRdLFUpO18/cWUod3QueCx3dC55K0FbaC0xXS55LEFbaC0xXS54K08pOnFlKHd0Lngsd3QueSx1K08pfX19d2coKSxNJiZiZygpO2Z1bmN0aW9uIHdnKCl7Y29uc3QgTj1zLmxlbmd0aC8zO2lmKGYpe2xldCBMPTAsTz1qKkw7aWYoeClmb3IobGV0IFU9MDtVPEdyO1UrKyl7Y29uc3QgJD1FbltVXTtacigkWzJdK08sJFsxXStPLCRbMF0rTyl9aWYoTD1oK20qMixPPWoqTCx3KWZvcihsZXQgVT0wO1U8R3I7VSsrKXtjb25zdCAkPUVuW1VdO1pyKCRbMF0rTywkWzFdK08sJFsyXStPKX19ZWxzZXtpZih4KWZvcihsZXQgTD0wO0w8R3I7TCsrKXtjb25zdCBPPUVuW0xdO1pyKE9bMl0sT1sxXSxPWzBdKX1pZih3KWZvcihsZXQgTD0wO0w8R3I7TCsrKXtjb25zdCBPPUVuW0xdO1pyKE9bMF0raipoLE9bMV0raipoLE9bMl0raipoKX19bi5hZGRHcm91cChOLHMubGVuZ3RoLzMtTiwwKX1mdW5jdGlvbiBiZygpe2NvbnN0IE49cy5sZW5ndGgvMztsZXQgTD0wO1R1KEQsTCksTCs9RC5sZW5ndGg7Zm9yKGxldCBPPTAsVT1GLmxlbmd0aDtPPFU7TysrKXtjb25zdCAkPUZbT107VHUoJCxMKSxMKz0kLmxlbmd0aH1uLmFkZEdyb3VwKE4scy5sZW5ndGgvMy1OLDEpfWZ1bmN0aW9uIFR1KE4sTCl7bGV0IE89Ti5sZW5ndGg7Zm9yKDstLU8+PTA7KXtjb25zdCBVPU87bGV0ICQ9Ty0xOyQ8MCYmKCQ9Ti5sZW5ndGgtMSk7Zm9yKGxldCBZPTAsRz1oK20qMjtZPEc7WSsrKXtjb25zdCBpdD1qKlksY3Q9aiooWSsxKSx3dD1MK1UraXQsWHQ9TCskK2l0LFBuPUwrJCtjdCxKdD1MK1UrY3Q7TWcod3QsWHQsUG4sSnQpfX19ZnVuY3Rpb24gcWUoTixMLE8pe2MucHVzaChOKSxjLnB1c2goTCksYy5wdXNoKE8pfWZ1bmN0aW9uIFpyKE4sTCxPKXtIZShOKSxIZShMKSxIZShPKTtjb25zdCBVPXMubGVuZ3RoLzMsJD1iLmdlbmVyYXRlVG9wVVYobixzLFUtMyxVLTIsVS0xKTtXZSgkWzBdKSxXZSgkWzFdKSxXZSgkWzJdKX1mdW5jdGlvbiBNZyhOLEwsTyxVKXtIZShOKSxIZShMKSxIZShVKSxIZShMKSxIZShPKSxIZShVKTtjb25zdCAkPXMubGVuZ3RoLzMsWT1iLmdlbmVyYXRlU2lkZVdhbGxVVihuLHMsJC02LCQtMywkLTIsJC0xKTtXZShZWzBdKSxXZShZWzFdKSxXZShZWzNdKSxXZShZWzFdKSxXZShZWzJdKSxXZShZWzNdKX1mdW5jdGlvbiBIZShOKXtzLnB1c2goY1tOKjMrMF0pLHMucHVzaChjW04qMysxXSkscy5wdXNoKGNbTiozKzJdKX1mdW5jdGlvbiBXZShOKXtyLnB1c2goTi54KSxyLnB1c2goTi55KX19fWNvcHkodCl7cmV0dXJuIHN1cGVyLmNvcHkodCksdGhpcy5wYXJhbWV0ZXJzPU9iamVjdC5hc3NpZ24oe30sdC5wYXJhbWV0ZXJzKSx0aGlzfXRvSlNPTigpe2NvbnN0IHQ9c3VwZXIudG9KU09OKCksZT10aGlzLnBhcmFtZXRlcnMuc2hhcGVzLG49dGhpcy5wYXJhbWV0ZXJzLm9wdGlvbnM7cmV0dXJuIEhmKGUsbix0KX1zdGF0aWMgZnJvbUpTT04odCxlKXtjb25zdCBuPVtdO2ZvcihsZXQgcj0wLG89dC5zaGFwZXMubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9ZVt0LnNoYXBlc1tyXV07bi5wdXNoKGEpfWNvbnN0IHM9dC5vcHRpb25zLmV4dHJ1ZGVQYXRoO3JldHVybiBzIT09dm9pZCAwJiYodC5vcHRpb25zLmV4dHJ1ZGVQYXRoPW5ldyBWZltgJHtzLnR5cGV9YF0oKS5mcm9tSlNPTihzKSksbmV3IFduKG4sdC5vcHRpb25zKX19Y29uc3QgcWY9e2dlbmVyYXRlVG9wVVY6ZnVuY3Rpb24oaSx0LGUsbixzKXtjb25zdCByPXRbZSozXSxvPXRbZSozKzFdLGE9dFtuKjNdLGM9dFtuKjMrMV0sbD10W3MqM10saD10W3MqMysxXTtyZXR1cm5bbmV3IFIocixvKSxuZXcgUihhLGMpLG5ldyBSKGwsaCldfSxnZW5lcmF0ZVNpZGVXYWxsVVY6ZnVuY3Rpb24oaSx0LGUsbixzLHIpe2NvbnN0IG89dFtlKjNdLGE9dFtlKjMrMV0sYz10W2UqMysyXSxsPXRbbiozXSxoPXRbbiozKzFdLHU9dFtuKjMrMl0sZj10W3MqM10sZD10W3MqMysxXSxwPXRbcyozKzJdLHk9dFtyKjNdLG09dFtyKjMrMV0sZz10W3IqMysyXTtyZXR1cm4gTWF0aC5hYnMoYS1oKTxNYXRoLmFicyhvLWwpP1tuZXcgUihvLDEtYyksbmV3IFIobCwxLXUpLG5ldyBSKGYsMS1wKSxuZXcgUih5LDEtZyldOltuZXcgUihhLDEtYyksbmV3IFIoaCwxLXUpLG5ldyBSKGQsMS1wKSxuZXcgUihtLDEtZyldfX07ZnVuY3Rpb24gSGYoaSx0LGUpe2lmKGUuc2hhcGVzPVtdLEFycmF5LmlzQXJyYXkoaSkpZm9yKGxldCBuPTAscz1pLmxlbmd0aDtuPHM7bisrKXtjb25zdCByPWlbbl07ZS5zaGFwZXMucHVzaChyLnV1aWQpfWVsc2UgZS5zaGFwZXMucHVzaChpLnV1aWQpO3JldHVybiBlLm9wdGlvbnM9T2JqZWN0LmFzc2lnbih7fSx0KSx0LmV4dHJ1ZGVQYXRoIT09dm9pZCAwJiYoZS5vcHRpb25zLmV4dHJ1ZGVQYXRoPXQuZXh0cnVkZVBhdGgudG9KU09OKCkpLGV9Y29uc3QgWGM9MCxXZj0xLEdmPTIsSmM9MixJbz0xLjI1LFljPTEsVGk9Nio0KzQrNCx6cz02NTUzNSxaZj1NYXRoLnBvdygyLC0yNCksa289U3ltYm9sKCJTS0lQX0dFTkVSQVRJT04iKTtmdW5jdGlvbiBYZihpKXtyZXR1cm4gaS5pbmRleD9pLmluZGV4LmNvdW50OmkuYXR0cmlidXRlcy5wb3NpdGlvbi5jb3VudH1mdW5jdGlvbiBHbihpKXtyZXR1cm4gWGYoaSkvM31mdW5jdGlvbiBKZihpLHQ9QXJyYXlCdWZmZXIpe3JldHVybiBpPjY1NTM1P25ldyBVaW50MzJBcnJheShuZXcgdCg0KmkpKTpuZXcgVWludDE2QXJyYXkobmV3IHQoMippKSl9ZnVuY3Rpb24gWWYoaSx0KXtpZighaS5pbmRleCl7Y29uc3QgZT1pLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQsbj10LnVzZVNoYXJlZEFycmF5QnVmZmVyP1NoYXJlZEFycmF5QnVmZmVyOkFycmF5QnVmZmVyLHM9SmYoZSxuKTtpLnNldEluZGV4KG5ldyB4dChzLDEpKTtmb3IobGV0IHI9MDtyPGU7cisrKXNbcl09cn19ZnVuY3Rpb24gamMoaSx0KXtjb25zdCBlPUduKGkpLG49dHx8aS5kcmF3UmFuZ2Uscz1uLnN0YXJ0LzMscj0obi5zdGFydCtuLmNvdW50KS8zLG89TWF0aC5tYXgoMCxzKSxhPU1hdGgubWluKGUsciktbztyZXR1cm5be29mZnNldDpNYXRoLmZsb29yKG8pLGNvdW50Ok1hdGguZmxvb3IoYSl9XX1mdW5jdGlvbiBRYyhpLHQpe2lmKCFpLmdyb3Vwc3x8IWkuZ3JvdXBzLmxlbmd0aClyZXR1cm4gamMoaSx0KTtjb25zdCBlPVtdLG49bmV3IFNldCxzPXR8fGkuZHJhd1JhbmdlLHI9cy5zdGFydC8zLG89KHMuc3RhcnQrcy5jb3VudCkvMztmb3IoY29uc3QgYyBvZiBpLmdyb3Vwcyl7Y29uc3QgbD1jLnN0YXJ0LzMsaD0oYy5zdGFydCtjLmNvdW50KS8zO24uYWRkKE1hdGgubWF4KHIsbCkpLG4uYWRkKE1hdGgubWluKG8saCkpfWNvbnN0IGE9QXJyYXkuZnJvbShuLnZhbHVlcygpKS5zb3J0KChjLGwpPT5jLWwpO2ZvcihsZXQgYz0wO2M8YS5sZW5ndGgtMTtjKyspe2NvbnN0IGw9YVtjXSxoPWFbYysxXTtlLnB1c2goe29mZnNldDpNYXRoLmZsb29yKGwpLGNvdW50Ok1hdGguZmxvb3IoaC1sKX0pfXJldHVybiBlfWZ1bmN0aW9uIGpmKGksdCl7Y29uc3QgZT1HbihpKSxuPVFjKGksdCkuc29ydCgobyxhKT0+by5vZmZzZXQtYS5vZmZzZXQpLHM9bltuLmxlbmd0aC0xXTtzLmNvdW50PU1hdGgubWluKGUtcy5vZmZzZXQscy5jb3VudCk7bGV0IHI9MDtyZXR1cm4gbi5mb3JFYWNoKCh7Y291bnQ6b30pPT5yKz1vKSxlIT09cn1mdW5jdGlvbiBObyhpLHQsZSxuLHMpe2xldCByPTEvMCxvPTEvMCxhPTEvMCxjPS0xLzAsbD0tMS8wLGg9LTEvMCx1PTEvMCxmPTEvMCxkPTEvMCxwPS0xLzAseT0tMS8wLG09LTEvMDtmb3IobGV0IGc9dCo2LGI9KHQrZSkqNjtnPGI7Zys9Nil7Y29uc3Qgdz1pW2crMF0seD1pW2crMV0sTT13LXgsQT13K3g7TTxyJiYocj1NKSxBPmMmJihjPUEpLHc8dSYmKHU9dyksdz5wJiYocD13KTtjb25zdCBfPWlbZysyXSxTPWlbZyszXSxFPV8tUyx6PV8rUztFPG8mJihvPUUpLHo+bCYmKGw9eiksXzxmJiYoZj1fKSxfPnkmJih5PV8pO2NvbnN0IHY9aVtnKzRdLEM9aVtnKzVdLFA9di1DLEY9ditDO1A8YSYmKGE9UCksRj5oJiYoaD1GKSx2PGQmJihkPXYpLHY+bSYmKG09dil9blswXT1yLG5bMV09byxuWzJdPWEsblszXT1jLG5bNF09bCxuWzVdPWgsc1swXT11LHNbMV09ZixzWzJdPWQsc1szXT1wLHNbNF09eSxzWzVdPW19ZnVuY3Rpb24gUWYoaSx0PW51bGwsZT1udWxsLG49bnVsbCl7Y29uc3Qgcz1pLmF0dHJpYnV0ZXMucG9zaXRpb24scj1pLmluZGV4P2kuaW5kZXguYXJyYXk6bnVsbCxvPUduKGkpLGE9cy5ub3JtYWxpemVkO2xldCBjO3Q9PT1udWxsPyhjPW5ldyBGbG9hdDMyQXJyYXkobyo2KSxlPTAsbj1vKTooYz10LGU9ZXx8MCxuPW58fG8pO2NvbnN0IGw9cy5hcnJheSxoPXMub2Zmc2V0fHwwO2xldCB1PTM7cy5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlJiYodT1zLmRhdGEuc3RyaWRlKTtjb25zdCBmPVsiZ2V0WCIsImdldFkiLCJnZXRaIl07Zm9yKGxldCBkPWU7ZDxlK247ZCsrKXtjb25zdCBwPWQqMyx5PWQqNjtsZXQgbT1wKzAsZz1wKzEsYj1wKzI7ciYmKG09clttXSxnPXJbZ10sYj1yW2JdKSxhfHwobT1tKnUraCxnPWcqdStoLGI9Yip1K2gpO2ZvcihsZXQgdz0wO3c8Mzt3Kyspe2xldCB4LE0sQTthPyh4PXNbZlt3XV0obSksTT1zW2Zbd11dKGcpLEE9c1tmW3ddXShiKSk6KHg9bFttK3ddLE09bFtnK3ddLEE9bFtiK3ddKTtsZXQgXz14O008XyYmKF89TSksQTxfJiYoXz1BKTtsZXQgUz14O00+UyYmKFM9TSksQT5TJiYoUz1BKTtjb25zdCBFPShTLV8pLzIsej13KjI7Y1t5K3orMF09XytFLGNbeSt6KzFdPUUrKE1hdGguYWJzKF8pK0UpKlpmfX1yZXR1cm4gY31mdW5jdGlvbiBsdChpLHQsZSl7cmV0dXJuIGUubWluLng9dFtpXSxlLm1pbi55PXRbaSsxXSxlLm1pbi56PXRbaSsyXSxlLm1heC54PXRbaSszXSxlLm1heC55PXRbaSs0XSxlLm1heC56PXRbaSs1XSxlfWZ1bmN0aW9uIEtjKGkpe2xldCB0PS0xLGU9LTEvMDtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPWlbbiszXS1pW25dO3M+ZSYmKGU9cyx0PW4pfXJldHVybiB0fWZ1bmN0aW9uIHRsKGksdCl7dC5zZXQoaSl9ZnVuY3Rpb24gZWwoaSx0LGUpe2xldCBuLHM7Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz1yKzM7bj1pW3JdLHM9dFtyXSxlW3JdPW48cz9uOnMsbj1pW29dLHM9dFtvXSxlW29dPW4+cz9uOnN9fWZ1bmN0aW9uIFRzKGksdCxlKXtmb3IobGV0IG49MDtuPDM7bisrKXtjb25zdCBzPXRbaSsyKm5dLHI9dFtpKzIqbisxXSxvPXMtcixhPXMrcjtvPGVbbl0mJihlW25dPW8pLGE+ZVtuKzNdJiYoZVtuKzNdPWEpfX1mdW5jdGlvbiBFaShpKXtjb25zdCB0PWlbM10taVswXSxlPWlbNF0taVsxXSxuPWlbNV0taVsyXTtyZXR1cm4gMioodCplK2UqbituKnQpfWNvbnN0IEJlPTMyLEtmPShpLHQpPT5pLmNhbmRpZGF0ZS10LmNhbmRpZGF0ZSxRZT1uZXcgQXJyYXkoQmUpLmZpbGwoKS5tYXAoKCk9Pih7Y291bnQ6MCxib3VuZHM6bmV3IEZsb2F0MzJBcnJheSg2KSxyaWdodENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksbGVmdENhY2hlQm91bmRzOm5ldyBGbG9hdDMyQXJyYXkoNiksY2FuZGlkYXRlOjB9KSksRXM9bmV3IEZsb2F0MzJBcnJheSg2KTtmdW5jdGlvbiB0ZChpLHQsZSxuLHMscil7bGV0IG89LTEsYT0wO2lmKHI9PT1YYylvPUtjKHQpLG8hPT0tMSYmKGE9KHRbb10rdFtvKzNdKS8yKTtlbHNlIGlmKHI9PT1XZilvPUtjKGkpLG8hPT0tMSYmKGE9ZWQoZSxuLHMsbykpO2Vsc2UgaWYocj09PUdmKXtjb25zdCBjPUVpKGkpO2xldCBsPUlvKnM7Y29uc3QgaD1uKjYsdT0obitzKSo2O2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9dFtmXSxtPSh0W2YrM10tZCkvQmU7aWYoczxCZS80KXtjb25zdCBnPVsuLi5RZV07Zy5sZW5ndGg9cztsZXQgYj0wO2ZvcihsZXQgeD1oO3g8dTt4Kz02LGIrKyl7Y29uc3QgTT1nW2JdO00uY2FuZGlkYXRlPWVbeCsyKmZdLE0uY291bnQ9MDtjb25zdHtib3VuZHM6QSxsZWZ0Q2FjaGVCb3VuZHM6XyxyaWdodENhY2hlQm91bmRzOlN9PU07Zm9yKGxldCBFPTA7RTwzO0UrKylTW0VdPTEvMCxTW0UrM109LTEvMCxfW0VdPTEvMCxfW0UrM109LTEvMCxBW0VdPTEvMCxBW0UrM109LTEvMDtUcyh4LGUsQSl9Zy5zb3J0KEtmKTtsZXQgdz1zO2ZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XTtmb3IoO3grMTx3JiZnW3grMV0uY2FuZGlkYXRlPT09TS5jYW5kaWRhdGU7KWcuc3BsaWNlKHgrMSwxKSx3LS19Zm9yKGxldCB4PWg7eDx1O3grPTYpe2NvbnN0IE09ZVt4KzIqZl07Zm9yKGxldCBBPTA7QTx3O0ErKyl7Y29uc3QgXz1nW0FdO00+PV8uY2FuZGlkYXRlP1RzKHgsZSxfLnJpZ2h0Q2FjaGVCb3VuZHMpOihUcyh4LGUsXy5sZWZ0Q2FjaGVCb3VuZHMpLF8uY291bnQrKyl9fWZvcihsZXQgeD0wO3g8dzt4Kyspe2NvbnN0IE09Z1t4XSxBPU0uY291bnQsXz1zLU0uY291bnQsUz1NLmxlZnRDYWNoZUJvdW5kcyxFPU0ucmlnaHRDYWNoZUJvdW5kcztsZXQgej0wO0EhPT0wJiYoej1FaShTKS9jKTtsZXQgdj0wO18hPT0wJiYodj1FaShFKS9jKTtjb25zdCBDPVljK0lvKih6KkErdipfKTtDPGwmJihvPWYsbD1DLGE9TS5jYW5kaWRhdGUpfX1lbHNle2ZvcihsZXQgdz0wO3c8QmU7dysrKXtjb25zdCB4PVFlW3ddO3guY291bnQ9MCx4LmNhbmRpZGF0ZT1kK20rdyptO2NvbnN0IE09eC5ib3VuZHM7Zm9yKGxldCBBPTA7QTwzO0ErKylNW0FdPTEvMCxNW0ErM109LTEvMH1mb3IobGV0IHc9aDt3PHU7dys9Nil7bGV0IEE9fn4oKGVbdysyKmZdLWQpL20pO0E+PUJlJiYoQT1CZS0xKTtjb25zdCBfPVFlW0FdO18uY291bnQrKyxUcyh3LGUsXy5ib3VuZHMpfWNvbnN0IGc9UWVbQmUtMV07dGwoZy5ib3VuZHMsZy5yaWdodENhY2hlQm91bmRzKTtmb3IobGV0IHc9QmUtMjt3Pj0wO3ctLSl7Y29uc3QgeD1RZVt3XSxNPVFlW3crMV07ZWwoeC5ib3VuZHMsTS5yaWdodENhY2hlQm91bmRzLHgucmlnaHRDYWNoZUJvdW5kcyl9bGV0IGI9MDtmb3IobGV0IHc9MDt3PEJlLTE7dysrKXtjb25zdCB4PVFlW3ddLE09eC5jb3VudCxBPXguYm91bmRzLFM9UWVbdysxXS5yaWdodENhY2hlQm91bmRzO00hPT0wJiYoYj09PTA/dGwoQSxFcyk6ZWwoQSxFcyxFcykpLGIrPU07bGV0IEU9MCx6PTA7YiE9PTAmJihFPUVpKEVzKS9jKTtjb25zdCB2PXMtYjt2IT09MCYmKHo9RWkoUykvYyk7Y29uc3QgQz1ZYytJbyooRSpiK3oqdik7QzxsJiYobz1mLGw9QyxhPXguY2FuZGlkYXRlKX19fX1lbHNlIGNvbnNvbGUud2FybihgTWVzaEJWSDogSW52YWxpZCBidWlsZCBzdHJhdGVneSB2YWx1ZSAke3J9IHVzZWQuYCk7cmV0dXJue2F4aXM6byxwb3M6YX19ZnVuY3Rpb24gZWQoaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPXQrZTtyPG87cisrKXMrPWlbcio2K24qMl07cmV0dXJuIHMvZX1jbGFzcyBSb3tjb25zdHJ1Y3Rvcigpe3RoaXMuYm91bmRpbmdEYXRhPW5ldyBGbG9hdDMyQXJyYXkoNil9fWZ1bmN0aW9uIG5kKGksdCxlLG4scyxyKXtsZXQgbz1uLGE9bitzLTE7Y29uc3QgYz1yLnBvcyxsPXIuYXhpcyoyO2Zvcig7Oyl7Zm9yKDtvPD1hJiZlW28qNitsXTxjOylvKys7Zm9yKDtvPD1hJiZlW2EqNitsXT49YzspYS0tO2lmKG88YSl7Zm9yKGxldCBoPTA7aDwzO2grKyl7bGV0IHU9dFtvKjMraF07dFtvKjMraF09dFthKjMraF0sdFthKjMraF09dX1mb3IobGV0IGg9MDtoPDY7aCsrKXtsZXQgdT1lW28qNitoXTtlW28qNitoXT1lW2EqNitoXSxlW2EqNitoXT11fW8rKyxhLS19ZWxzZSByZXR1cm4gb319ZnVuY3Rpb24gaWQoaSx0LGUsbixzLHIpe2xldCBvPW4sYT1uK3MtMTtjb25zdCBjPXIucG9zLGw9ci5heGlzKjI7Zm9yKDs7KXtmb3IoO288PWEmJmVbbyo2K2xdPGM7KW8rKztmb3IoO288PWEmJmVbYSo2K2xdPj1jOylhLS07aWYobzxhKXtsZXQgaD1pW29dO2lbb109aVthXSxpW2FdPWg7Zm9yKGxldCB1PTA7dTw2O3UrKyl7bGV0IGY9ZVtvKjYrdV07ZVtvKjYrdV09ZVthKjYrdV0sZVthKjYrdV09Zn1vKyssYS0tfWVsc2UgcmV0dXJuIG99fWZ1bmN0aW9uIGt0KGksdCl7cmV0dXJuIHRbaSsxNV09PT02NTUzNX1mdW5jdGlvbiBWdChpLHQpe3JldHVybiB0W2krNl19ZnVuY3Rpb24gS3QoaSx0KXtyZXR1cm4gdFtpKzE0XX1mdW5jdGlvbiB0ZShpKXtyZXR1cm4gaSs4fWZ1bmN0aW9uIGVlKGksdCl7cmV0dXJuIHRbaSs2XX1mdW5jdGlvbiBubChpLHQpe3JldHVybiB0W2krN119ZnVuY3Rpb24gSGcoaSl7cmV0dXJuIGl9bGV0IGlsLFBpLFBzLHNsO2NvbnN0IHNkPU1hdGgucG93KDIsMzIpO2Z1bmN0aW9uIExvKGkpe3JldHVybiJjb3VudCJpbiBpPzE6MStMbyhpLmxlZnQpK0xvKGkucmlnaHQpfWZ1bmN0aW9uIHJkKGksdCxlKXtyZXR1cm4gaWw9bmV3IEZsb2F0MzJBcnJheShlKSxQaT1uZXcgVWludDMyQXJyYXkoZSksUHM9bmV3IFVpbnQxNkFycmF5KGUpLHNsPW5ldyBVaW50OEFycmF5KGUpLE9vKGksdCl9ZnVuY3Rpb24gT28oaSx0KXtjb25zdCBlPWkvNCxuPWkvMixzPSJjb3VudCJpbiB0LHI9dC5ib3VuZGluZ0RhdGE7Zm9yKGxldCBvPTA7bzw2O28rKylpbFtlK29dPXJbb107aWYocylpZih0LmJ1ZmZlcil7Y29uc3Qgbz10LmJ1ZmZlcjtzbC5zZXQobmV3IFVpbnQ4QXJyYXkobyksaSk7Zm9yKGxldCBhPWksYz1pK28uYnl0ZUxlbmd0aDthPGM7YSs9VGkpe2NvbnN0IGw9YS8yO2t0KGwsUHMpfHwoUGlbYS80KzZdKz1lKX1yZXR1cm4gaStvLmJ5dGVMZW5ndGh9ZWxzZXtjb25zdCBvPXQub2Zmc2V0LGE9dC5jb3VudDtyZXR1cm4gUGlbZSs2XT1vLFBzW24rMTRdPWEsUHNbbisxNV09enMsaStUaX1lbHNle2NvbnN0IG89dC5sZWZ0LGE9dC5yaWdodCxjPXQuc3BsaXRBeGlzO2xldCBsO2lmKGw9T28oaStUaSxvKSxsLzQ+c2QpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBDYW5ub3Qgc3RvcmUgY2hpbGQgcG9pbnRlciBncmVhdGVyIHRoYW4gMzIgYml0cy4iKTtyZXR1cm4gUGlbZSs2XT1sLzQsbD1PbyhsLGEpLFBpW2UrN109YyxsfX1mdW5jdGlvbiBvZChpLHQpe2NvbnN0IGU9KGkuaW5kZXg/aS5pbmRleC5jb3VudDppLmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQpLzMsbj1lPmRpKDIsMTYpLHM9bj80OjIscj10P25ldyBTaGFyZWRBcnJheUJ1ZmZlcihlKnMpOm5ldyBBcnJheUJ1ZmZlcihlKnMpLG89bj9uZXcgVWludDMyQXJyYXkocik6bmV3IFVpbnQxNkFycmF5KHIpO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKylvW2FdPWE7cmV0dXJuIG99ZnVuY3Rpb24gYWQoaSx0LGUsbixzKXtjb25zdHttYXhEZXB0aDpyLHZlcmJvc2U6byxtYXhMZWFmVHJpczphLHN0cmF0ZWd5OmMsb25Qcm9ncmVzczpsLGluZGlyZWN0Omh9PXMsdT1pLl9pbmRpcmVjdEJ1ZmZlcixmPWkuZ2VvbWV0cnksZD1mLmluZGV4P2YuaW5kZXguYXJyYXk6bnVsbCxwPWg/aWQ6bmQseT1HbihmKSxtPW5ldyBGbG9hdDMyQXJyYXkoNik7bGV0IGc9ITE7Y29uc3QgYj1uZXcgUm87cmV0dXJuIE5vKHQsZSxuLGIuYm91bmRpbmdEYXRhLG0pLHgoYixlLG4sbSksYjtmdW5jdGlvbiB3KE0pe2wmJmwoTS95KX1mdW5jdGlvbiB4KE0sQSxfLFM9bnVsbCxFPTApe2lmKCFnJiZFPj1yJiYoZz0hMCxvJiYoY29uc29sZS53YXJuKGBNZXNoQlZIOiBNYXggZGVwdGggb2YgJHtyfSByZWFjaGVkIHdoZW4gZ2VuZXJhdGluZyBCVkguIENvbnNpZGVyIGluY3JlYXNpbmcgbWF4RGVwdGguYCksY29uc29sZS53YXJuKGYpKSksXzw9YXx8RT49cilyZXR1cm4gdyhBK18pLE0ub2Zmc2V0PUEsTS5jb3VudD1fLE07Y29uc3Qgej10ZChNLmJvdW5kaW5nRGF0YSxTLHQsQSxfLGMpO2lmKHouYXhpcz09PS0xKXJldHVybiB3KEErXyksTS5vZmZzZXQ9QSxNLmNvdW50PV8sTTtjb25zdCB2PXAodSxkLHQsQSxfLHopO2lmKHY9PT1BfHx2PT09QStfKXcoQStfKSxNLm9mZnNldD1BLE0uY291bnQ9XztlbHNle00uc3BsaXRBeGlzPXouYXhpcztjb25zdCBDPW5ldyBSbyxQPUEsRj12LUE7TS5sZWZ0PUMsTm8odCxQLEYsQy5ib3VuZGluZ0RhdGEsbSkseChDLFAsRixtLEUrMSk7Y29uc3QgQj1uZXcgUm8sST12LGs9Xy1GO00ucmlnaHQ9QixObyh0LEksayxCLmJvdW5kaW5nRGF0YSxtKSx4KEIsSSxrLG0sRSsxKX1yZXR1cm4gTX19ZnVuY3Rpb24gY2QoaSx0KXtjb25zdCBlPWkuZ2VvbWV0cnk7dC5pbmRpcmVjdCYmKGkuX2luZGlyZWN0QnVmZmVyPW9kKGUsdC51c2VTaGFyZWRBcnJheUJ1ZmZlciksamYoZSx0LnJhbmdlKSYmIXQudmVyYm9zZSYmY29uc29sZS53YXJuKCdNZXNoQlZIOiBQcm92aWRlZCBnZW9tZXRyeSBjb250YWlucyBncm91cHMgb3IgYSByYW5nZSB0aGF0IGRvIG5vdCBmdWxseSBzcGFuIHRoZSB2ZXJ0ZXggY29udGVudHMgd2hpbGUgdXNpbmcgdGhlICJpbmRpcmVjdCIgb3B0aW9uLiBCVkggbWF5IGluY29ycmVjdGx5IHJlcG9ydCBpbnRlcnNlY3Rpb25zIG9uIHVucmVuZGVyZWQgcG9ydGlvbnMgb2YgdGhlIGdlb21ldHJ5LicpKSxpLl9pbmRpcmVjdEJ1ZmZlcnx8WWYoZSx0KTtjb25zdCBuPXQudXNlU2hhcmVkQXJyYXlCdWZmZXI/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1RZihlKSxyPXQuaW5kaXJlY3Q/amMoZSx0LnJhbmdlKTpRYyhlLHQucmFuZ2UpO2kuX3Jvb3RzPXIubWFwKG89Pntjb25zdCBhPWFkKGkscyxvLm9mZnNldCxvLmNvdW50LHQpLGM9TG8oYSksbD1uZXcgbihUaSpjKTtyZXR1cm4gcmQoMCxhLGwpLGx9KX1jbGFzcyBGZXtjb25zdHJ1Y3Rvcigpe3RoaXMubWluPTEvMCx0aGlzLm1heD0tMS8wfXNldEZyb21Qb2ludHNGaWVsZCh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBjPXRbcl1bZV07bj1jPG4/YzpuLHM9Yz5zP2M6c310aGlzLm1pbj1uLHRoaXMubWF4PXN9c2V0RnJvbVBvaW50cyh0LGUpe2xldCBuPTEvMCxzPS0xLzA7Zm9yKGxldCByPTAsbz1lLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPWVbcl0sYz10LmRvdChhKTtuPWM8bj9jOm4scz1jPnM/YzpzfXRoaXMubWluPW4sdGhpcy5tYXg9c31pc1NlcGFyYXRlZCh0KXtyZXR1cm4gdGhpcy5taW4+dC5tYXh8fHQubWluPnRoaXMubWF4fX1GZS5wcm90b3R5cGUuc2V0RnJvbUJveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Y29uc3Qgcz1uLm1pbixyPW4ubWF4O2xldCBvPTEvMCxhPS0xLzA7Zm9yKGxldCBjPTA7Yzw9MTtjKyspZm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspe2kueD1zLngqYytyLngqKDEtYyksaS55PXMueSpsK3IueSooMS1sKSxpLno9cy56Kmgrci56KigxLWgpO2NvbnN0IHU9ZS5kb3QoaSk7bz1NYXRoLm1pbih1LG8pLGE9TWF0aC5tYXgodSxhKX10aGlzLm1pbj1vLHRoaXMubWF4PWF9fSgpO2NvbnN0IGxkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtjb25zdCBhPXMuc3RhcnQsYz1pLGw9ci5zdGFydCxoPXQ7ZS5zdWJWZWN0b3JzKGEsbCksaS5zdWJWZWN0b3JzKHMuZW5kLHMuc3RhcnQpLHQuc3ViVmVjdG9ycyhyLmVuZCxyLnN0YXJ0KTtjb25zdCB1PWUuZG90KGgpLGY9aC5kb3QoYyksZD1oLmRvdChoKSxwPWUuZG90KGMpLG09Yy5kb3QoYykqZC1mKmY7bGV0IGcsYjttIT09MD9nPSh1KmYtcCpkKS9tOmc9MCxiPSh1K2cqZikvZCxvLng9ZyxvLnk9Yn19KCksRG89ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBSLHQ9bmV3IFQsZT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24ocyxyLG8sYSl7bGQocyxyLGkpO2xldCBjPWkueCxsPWkueTtpZihjPj0wJiZjPD0xJiZsPj0wJiZsPD0xKXtzLmF0KGMsbyksci5hdChsLGEpO3JldHVybn1lbHNlIGlmKGM+PTAmJmM8PTEpe2w8MD9yLmF0KDAsYSk6ci5hdCgxLGEpLHMuY2xvc2VzdFBvaW50VG9Qb2ludChhLCEwLG8pO3JldHVybn1lbHNlIGlmKGw+PTAmJmw8PTEpe2M8MD9zLmF0KDAsbyk6cy5hdCgxLG8pLHIuY2xvc2VzdFBvaW50VG9Qb2ludChvLCEwLGEpO3JldHVybn1lbHNle2xldCBoO2M8MD9oPXMuc3RhcnQ6aD1zLmVuZDtsZXQgdTtsPDA/dT1yLnN0YXJ0OnU9ci5lbmQ7Y29uc3QgZj10LGQ9ZTtpZihzLmNsb3Nlc3RQb2ludFRvUG9pbnQodSwhMCx0KSxyLmNsb3Nlc3RQb2ludFRvUG9pbnQoaCwhMCxlKSxmLmRpc3RhbmNlVG9TcXVhcmVkKHUpPD1kLmRpc3RhbmNlVG9TcXVhcmVkKGgpKXtvLmNvcHkoZiksYS5jb3B5KHUpO3JldHVybn1lbHNle28uY29weShoKSxhLmNvcHkoZCk7cmV0dXJufX19fSgpLGhkPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVCx0PW5ldyBULGU9bmV3IE1vLG49bmV3IFF0O3JldHVybiBmdW5jdGlvbihyLG8pe2NvbnN0e3JhZGl1czphLGNlbnRlcjpjfT1yLHthOmwsYjpoLGM6dX09bztpZihuLnN0YXJ0PWwsbi5lbmQ9aCxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hfHwobi5zdGFydD1sLG4uZW5kPXUsbi5jbG9zZXN0UG9pbnRUb1BvaW50KGMsITAsaSkuZGlzdGFuY2VUbyhjKTw9YSl8fChuLnN0YXJ0PWgsbi5lbmQ9dSxuLmNsb3Nlc3RQb2ludFRvUG9pbnQoYywhMCxpKS5kaXN0YW5jZVRvKGMpPD1hKSlyZXR1cm4hMDtjb25zdCB5PW8uZ2V0UGxhbmUoZSk7aWYoTWF0aC5hYnMoeS5kaXN0YW5jZVRvUG9pbnQoYykpPD1hKXtjb25zdCBnPXkucHJvamVjdFBvaW50KGMsdCk7aWYoby5jb250YWluc1BvaW50KGcpKXJldHVybiEwfXJldHVybiExfX0oKSx1ZD0xZS0xNTtmdW5jdGlvbiAkbyhpKXtyZXR1cm4gTWF0aC5hYnMoaSk8dWR9Y2xhc3MgbmUgZXh0ZW5kcyBldHtjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzRXh0ZW5kZWRUcmlhbmdsZT0hMCx0aGlzLnNhdEF4ZXM9bmV3IEFycmF5KDQpLmZpbGwoKS5tYXAoKCk9Pm5ldyBUKSx0aGlzLnNhdEJvdW5kcz1uZXcgQXJyYXkoNCkuZmlsbCgpLm1hcCgoKT0+bmV3IEZlKSx0aGlzLnBvaW50cz1bdGhpcy5hLHRoaXMuYix0aGlzLmNdLHRoaXMuc3BoZXJlPW5ldyBpbyx0aGlzLnBsYW5lPW5ldyBNbyx0aGlzLm5lZWRzVXBkYXRlPSEwfWludGVyc2VjdHNTcGhlcmUodCl7cmV0dXJuIGhkKHQsdGhpcyl9dXBkYXRlKCl7Y29uc3QgdD10aGlzLmEsZT10aGlzLmIsbj10aGlzLmMscz10aGlzLnBvaW50cyxyPXRoaXMuc2F0QXhlcyxvPXRoaXMuc2F0Qm91bmRzLGE9clswXSxjPW9bMF07dGhpcy5nZXROb3JtYWwoYSksYy5zZXRGcm9tUG9pbnRzKGEscyk7Y29uc3QgbD1yWzFdLGg9b1sxXTtsLnN1YlZlY3RvcnModCxlKSxoLnNldEZyb21Qb2ludHMobCxzKTtjb25zdCB1PXJbMl0sZj1vWzJdO3Uuc3ViVmVjdG9ycyhlLG4pLGYuc2V0RnJvbVBvaW50cyh1LHMpO2NvbnN0IGQ9clszXSxwPW9bM107ZC5zdWJWZWN0b3JzKG4sdCkscC5zZXRGcm9tUG9pbnRzKGQscyksdGhpcy5zcGhlcmUuc2V0RnJvbVBvaW50cyh0aGlzLnBvaW50cyksdGhpcy5wbGFuZS5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludChhLHQpLHRoaXMubmVlZHNVcGRhdGU9ITF9fW5lLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRUb1NlZ21lbnQ9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1uZXcgUXQ7cmV0dXJuIGZ1bmN0aW9uKHMscj1udWxsLG89bnVsbCl7Y29uc3R7c3RhcnQ6YSxlbmQ6Y309cyxsPXRoaXMucG9pbnRzO2xldCBoLHU9MS8wO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9KGYrMSklMztlLnN0YXJ0LmNvcHkobFtmXSksZS5lbmQuY29weShsW2RdKSxEbyhlLHMsaSx0KSxoPWkuZGlzdGFuY2VUb1NxdWFyZWQodCksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkodCkpfXJldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoYSxpKSxoPWEuZGlzdGFuY2VUb1NxdWFyZWQoaSksaDx1JiYodT1oLHImJnIuY29weShpKSxvJiZvLmNvcHkoYSkpLHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChjLGkpLGg9Yy5kaXN0YW5jZVRvU3F1YXJlZChpKSxoPHUmJih1PWgsciYmci5jb3B5KGkpLG8mJm8uY29weShjKSksTWF0aC5zcXJ0KHUpfX0oKSxuZS5wcm90b3R5cGUuaW50ZXJzZWN0c1RyaWFuZ2xlPWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgbmUsdD1uZXcgQXJyYXkoMyksZT1uZXcgQXJyYXkoMyksbj1uZXcgRmUscz1uZXcgRmUscj1uZXcgVCxvPW5ldyBULGE9bmV3IFQsYz1uZXcgVCxsPW5ldyBULGg9bmV3IFF0LHU9bmV3IFF0LGY9bmV3IFF0LGQ9bmV3IFQ7ZnVuY3Rpb24gcCh5LG0sZyl7Y29uc3QgYj15LnBvaW50cztsZXQgdz0wLHg9LTE7Zm9yKGxldCBNPTA7TTwzO00rKyl7Y29uc3R7c3RhcnQ6QSxlbmQ6X309aDtBLmNvcHkoYltNXSksXy5jb3B5KGJbKE0rMSklM10pLGguZGVsdGEobyk7Y29uc3QgUz0kbyhtLmRpc3RhbmNlVG9Qb2ludChBKSk7aWYoJG8obS5ub3JtYWwuZG90KG8pKSYmUyl7Zy5jb3B5KGgpLHc9MjticmVha31jb25zdCBFPW0uaW50ZXJzZWN0TGluZShoLGQpO2lmKCFFJiZTJiZkLmNvcHkoQSksKEV8fFMpJiYhJG8oZC5kaXN0YW5jZVRvKF8pKSl7aWYodzw9MSkodz09PTE/Zy5zdGFydDpnLmVuZCkuY29weShkKSxTJiYoeD13KTtlbHNlIGlmKHc+PTIpeyh4PT09MT9nLnN0YXJ0OmcuZW5kKS5jb3B5KGQpLHc9MjticmVha31pZih3Kyssdz09PTImJng9PT0tMSlicmVha319cmV0dXJuIHd9cmV0dXJuIGZ1bmN0aW9uKG0sZz1udWxsLGI9ITEpe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksbS5pc0V4dGVuZGVkVHJpYW5nbGU/bS5uZWVkc1VwZGF0ZSYmbS51cGRhdGUoKTooaS5jb3B5KG0pLGkudXBkYXRlKCksbT1pKTtjb25zdCB3PXRoaXMucGxhbmUseD1tLnBsYW5lO2lmKE1hdGguYWJzKHcubm9ybWFsLmRvdCh4Lm5vcm1hbCkpPjEtMWUtMTApe2NvbnN0IE09dGhpcy5zYXRCb3VuZHMsQT10aGlzLnNhdEF4ZXM7ZVswXT1tLmEsZVsxXT1tLmIsZVsyXT1tLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1NW0VdLHY9QVtFXTtpZihuLnNldEZyb21Qb2ludHModixlKSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWNvbnN0IF89bS5zYXRCb3VuZHMsUz1tLnNhdEF4ZXM7dFswXT10aGlzLmEsdFsxXT10aGlzLmIsdFsyXT10aGlzLmM7Zm9yKGxldCBFPTA7RTw0O0UrKyl7Y29uc3Qgej1fW0VdLHY9U1tFXTtpZihuLnNldEZyb21Qb2ludHModix0KSx6LmlzU2VwYXJhdGVkKG4pKXJldHVybiExfWZvcihsZXQgRT0wO0U8NDtFKyspe2NvbnN0IHo9QVtFXTtmb3IobGV0IHY9MDt2PDQ7disrKXtjb25zdCBDPVNbdl07aWYoci5jcm9zc1ZlY3RvcnMoeixDKSxuLnNldEZyb21Qb2ludHMocix0KSxzLnNldEZyb21Qb2ludHMocixlKSxuLmlzU2VwYXJhdGVkKHMpKXJldHVybiExfX1yZXR1cm4gZyYmKGJ8fGNvbnNvbGUud2FybigiRXh0ZW5kZWRUcmlhbmdsZS5pbnRlcnNlY3RzVHJpYW5nbGU6IFRyaWFuZ2xlcyBhcmUgY29wbGFuYXIgd2hpY2ggZG9lcyBub3Qgc3VwcG9ydCBhbiBvdXRwdXQgZWRnZS4gU2V0dGluZyBlZGdlIHRvIDAsIDAsIDAuIiksZy5zdGFydC5zZXQoMCwwLDApLGcuZW5kLnNldCgwLDAsMCkpLCEwfWVsc2V7Y29uc3QgTT1wKHRoaXMseCx1KTtpZihNPT09MSYmbS5jb250YWluc1BvaW50KHUuZW5kKSlyZXR1cm4gZyYmKGcuc3RhcnQuY29weSh1LmVuZCksZy5lbmQuY29weSh1LmVuZCkpLCEwO2lmKE0hPT0yKXJldHVybiExO2NvbnN0IEE9cChtLHcsZik7aWYoQT09PTEmJnRoaXMuY29udGFpbnNQb2ludChmLmVuZCkpcmV0dXJuIGcmJihnLnN0YXJ0LmNvcHkoZi5lbmQpLGcuZW5kLmNvcHkoZi5lbmQpKSwhMDtpZihBIT09MilyZXR1cm4hMTtpZih1LmRlbHRhKGEpLGYuZGVsdGEoYyksYS5kb3QoYyk8MCl7bGV0IFA9Zi5zdGFydDtmLnN0YXJ0PWYuZW5kLGYuZW5kPVB9Y29uc3QgXz11LnN0YXJ0LmRvdChhKSxTPXUuZW5kLmRvdChhKSxFPWYuc3RhcnQuZG90KGEpLHo9Zi5lbmQuZG90KGEpLHY9UzxFLEM9Xzx6O3JldHVybiBfIT09eiYmRSE9PVMmJnY9PT1DPyExOihnJiYobC5zdWJWZWN0b3JzKHUuc3RhcnQsZi5zdGFydCksbC5kb3QoYSk+MD9nLnN0YXJ0LmNvcHkodS5zdGFydCk6Zy5zdGFydC5jb3B5KGYuc3RhcnQpLGwuc3ViVmVjdG9ycyh1LmVuZCxmLmVuZCksbC5kb3QoYSk8MD9nLmVuZC5jb3B5KHUuZW5kKTpnLmVuZC5jb3B5KGYuZW5kKSksITApfX19KCksbmUucHJvdG90eXBlLmRpc3RhbmNlVG9Qb2ludD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQoZSxpKSxlLmRpc3RhbmNlVG8oaSl9fSgpLG5lLnByb3RvdHlwZS5kaXN0YW5jZVRvVHJpYW5nbGU9ZnVuY3Rpb24oKXtjb25zdCBpPW5ldyBULHQ9bmV3IFQsZT1bImEiLCJiIiwiYyJdLG49bmV3IFF0LHM9bmV3IFF0O3JldHVybiBmdW5jdGlvbihvLGE9bnVsbCxjPW51bGwpe2NvbnN0IGw9YXx8Yz9uOm51bGw7aWYodGhpcy5pbnRlcnNlY3RzVHJpYW5nbGUobyxsKSlyZXR1cm4oYXx8YykmJihhJiZsLmdldENlbnRlcihhKSxjJiZsLmdldENlbnRlcihjKSksMDtsZXQgaD0xLzA7Zm9yKGxldCB1PTA7dTwzO3UrKyl7bGV0IGY7Y29uc3QgZD1lW3VdLHA9b1tkXTt0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocCxpKSxmPXAuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weShpKSxjJiZjLmNvcHkocCkpO2NvbnN0IHk9dGhpc1tkXTtvLmNsb3Nlc3RQb2ludFRvUG9pbnQoeSxpKSxmPXkuZGlzdGFuY2VUb1NxdWFyZWQoaSksZjxoJiYoaD1mLGEmJmEuY29weSh5KSxjJiZjLmNvcHkoaSkpfWZvcihsZXQgdT0wO3U8Mzt1Kyspe2NvbnN0IGY9ZVt1XSxkPWVbKHUrMSklM107bi5zZXQodGhpc1tmXSx0aGlzW2RdKTtmb3IobGV0IHA9MDtwPDM7cCsrKXtjb25zdCB5PWVbcF0sbT1lWyhwKzEpJTNdO3Muc2V0KG9beV0sb1ttXSksRG8obixzLGksdCk7Y29uc3QgZz1pLmRpc3RhbmNlVG9TcXVhcmVkKHQpO2c8aCYmKGg9ZyxhJiZhLmNvcHkoaSksYyYmYy5jb3B5KHQpKX19cmV0dXJuIE1hdGguc3FydChoKX19KCk7Y2xhc3MgenR7Y29uc3RydWN0b3IodCxlLG4pe3RoaXMuaXNPcmllbnRlZEJveD0hMCx0aGlzLm1pbj1uZXcgVCx0aGlzLm1heD1uZXcgVCx0aGlzLm1hdHJpeD1uZXcgc3QsdGhpcy5pbnZNYXRyaXg9bmV3IHN0LHRoaXMucG9pbnRzPW5ldyBBcnJheSg4KS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRBeGVzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgVCksdGhpcy5zYXRCb3VuZHM9bmV3IEFycmF5KDMpLmZpbGwoKS5tYXAoKCk9Pm5ldyBGZSksdGhpcy5hbGlnbmVkU2F0Qm91bmRzPW5ldyBBcnJheSgzKS5maWxsKCkubWFwKCgpPT5uZXcgRmUpLHRoaXMubmVlZHNVcGRhdGU9ITEsdCYmdGhpcy5taW4uY29weSh0KSxlJiZ0aGlzLm1heC5jb3B5KGUpLG4mJnRoaXMubWF0cml4LmNvcHkobil9c2V0KHQsZSxuKXt0aGlzLm1pbi5jb3B5KHQpLHRoaXMubWF4LmNvcHkoZSksdGhpcy5tYXRyaXguY29weShuKSx0aGlzLm5lZWRzVXBkYXRlPSEwfWNvcHkodCl7dGhpcy5taW4uY29weSh0Lm1pbiksdGhpcy5tYXguY29weSh0Lm1heCksdGhpcy5tYXRyaXguY29weSh0Lm1hdHJpeCksdGhpcy5uZWVkc1VwZGF0ZT0hMH19enQucHJvdG90eXBlLnVwZGF0ZT1mdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbigpe2NvbnN0IHQ9dGhpcy5tYXRyaXgsZT10aGlzLm1pbixuPXRoaXMubWF4LHM9dGhpcy5wb2ludHM7Zm9yKGxldCBsPTA7bDw9MTtsKyspZm9yKGxldCBoPTA7aDw9MTtoKyspZm9yKGxldCB1PTA7dTw9MTt1Kyspe2NvbnN0IGY9MSpsfDIqaHw0KnUsZD1zW2ZdO2QueD1sP24ueDplLngsZC55PWg/bi55OmUueSxkLno9dT9uLno6ZS56LGQuYXBwbHlNYXRyaXg0KHQpfWNvbnN0IHI9dGhpcy5zYXRCb3VuZHMsbz10aGlzLnNhdEF4ZXMsYT1zWzBdO2ZvcihsZXQgbD0wO2w8MztsKyspe2NvbnN0IGg9b1tsXSx1PXJbbF0sZj0xPDxsLGQ9c1tmXTtoLnN1YlZlY3RvcnMoYSxkKSx1LnNldEZyb21Qb2ludHMoaCxzKX1jb25zdCBjPXRoaXMuYWxpZ25lZFNhdEJvdW5kcztjWzBdLnNldEZyb21Qb2ludHNGaWVsZChzLCJ4IiksY1sxXS5zZXRGcm9tUG9pbnRzRmllbGQocywieSIpLGNbMl0uc2V0RnJvbVBvaW50c0ZpZWxkKHMsInoiKSx0aGlzLmludk1hdHJpeC5jb3B5KHRoaXMubWF0cml4KS5pbnZlcnQoKSx0aGlzLm5lZWRzVXBkYXRlPSExfX0oKSx6dC5wcm90b3R5cGUuaW50ZXJzZWN0c0JveD1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IEZlO3JldHVybiBmdW5jdGlvbihlKXt0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpO2NvbnN0IG49ZS5taW4scz1lLm1heCxyPXRoaXMuc2F0Qm91bmRzLG89dGhpcy5zYXRBeGVzLGE9dGhpcy5hbGlnbmVkU2F0Qm91bmRzO2lmKGkubWluPW4ueCxpLm1heD1zLngsYVswXS5pc1NlcGFyYXRlZChpKXx8KGkubWluPW4ueSxpLm1heD1zLnksYVsxXS5pc1NlcGFyYXRlZChpKSl8fChpLm1pbj1uLnosaS5tYXg9cy56LGFbMl0uaXNTZXBhcmF0ZWQoaSkpKXJldHVybiExO2ZvcihsZXQgYz0wO2M8MztjKyspe2NvbnN0IGw9b1tjXSxoPXJbY107aWYoaS5zZXRGcm9tQm94KGwsZSksaC5pc1NlcGFyYXRlZChpKSlyZXR1cm4hMX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmludGVyc2VjdHNUcmlhbmdsZT1mdW5jdGlvbigpe2NvbnN0IGk9bmV3IG5lLHQ9bmV3IEFycmF5KDMpLGU9bmV3IEZlLG49bmV3IEZlLHM9bmV3IFQ7cmV0dXJuIGZ1bmN0aW9uKG8pe3RoaXMubmVlZHNVcGRhdGUmJnRoaXMudXBkYXRlKCksby5pc0V4dGVuZGVkVHJpYW5nbGU/by5uZWVkc1VwZGF0ZSYmby51cGRhdGUoKTooaS5jb3B5KG8pLGkudXBkYXRlKCksbz1pKTtjb25zdCBhPXRoaXMuc2F0Qm91bmRzLGM9dGhpcy5zYXRBeGVzO3RbMF09by5hLHRbMV09by5iLHRbMl09by5jO2ZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9YVtmXSxwPWNbZl07aWYoZS5zZXRGcm9tUG9pbnRzKHAsdCksZC5pc1NlcGFyYXRlZChlKSlyZXR1cm4hMX1jb25zdCBsPW8uc2F0Qm91bmRzLGg9by5zYXRBeGVzLHU9dGhpcy5wb2ludHM7Zm9yKGxldCBmPTA7ZjwzO2YrKyl7Y29uc3QgZD1sW2ZdLHA9aFtmXTtpZihlLnNldEZyb21Qb2ludHMocCx1KSxkLmlzU2VwYXJhdGVkKGUpKXJldHVybiExfWZvcihsZXQgZj0wO2Y8MztmKyspe2NvbnN0IGQ9Y1tmXTtmb3IobGV0IHA9MDtwPDQ7cCsrKXtjb25zdCB5PWhbcF07aWYocy5jcm9zc1ZlY3RvcnMoZCx5KSxlLnNldEZyb21Qb2ludHMocyx0KSxuLnNldEZyb21Qb2ludHMocyx1KSxlLmlzU2VwYXJhdGVkKG4pKXJldHVybiExfX1yZXR1cm4hMH19KCksenQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFRvUG9pbnQ9ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5uZWVkc1VwZGF0ZSYmdGhpcy51cGRhdGUoKSxlLmNvcHkodCkuYXBwbHlNYXRyaXg0KHRoaXMuaW52TWF0cml4KS5jbGFtcCh0aGlzLm1pbix0aGlzLm1heCkuYXBwbHlNYXRyaXg0KHRoaXMubWF0cml4KSxlfX0oKSx6dC5wcm90b3R5cGUuZGlzdGFuY2VUb1BvaW50PWZ1bmN0aW9uKCl7Y29uc3QgaT1uZXcgVDtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChlLGkpLGUuZGlzdGFuY2VUbyhpKX19KCksenQucHJvdG90eXBlLmRpc3RhbmNlVG9Cb3g9ZnVuY3Rpb24oKXtjb25zdCBpPVsieCIsInkiLCJ6Il0sdD1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksZT1uZXcgQXJyYXkoMTIpLmZpbGwoKS5tYXAoKCk9Pm5ldyBRdCksbj1uZXcgVCxzPW5ldyBUO3JldHVybiBmdW5jdGlvbihvLGE9MCxjPW51bGwsbD1udWxsKXtpZih0aGlzLm5lZWRzVXBkYXRlJiZ0aGlzLnVwZGF0ZSgpLHRoaXMuaW50ZXJzZWN0c0JveChvKSlyZXR1cm4oY3x8bCkmJihvLmdldENlbnRlcihzKSx0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnQocyxuKSxvLmNsb3Nlc3RQb2ludFRvUG9pbnQobixzKSxjJiZjLmNvcHkobiksbCYmbC5jb3B5KHMpKSwwO2NvbnN0IGg9YSphLHU9by5taW4sZj1vLm1heCxkPXRoaXMucG9pbnRzO2xldCBwPTEvMDtmb3IobGV0IG09MDttPDg7bSsrKXtjb25zdCBnPWRbbV07cy5jb3B5KGcpLmNsYW1wKHUsZik7Y29uc3QgYj1nLmRpc3RhbmNlVG9TcXVhcmVkKHMpO2lmKGI8cCYmKHA9YixjJiZjLmNvcHkoZyksbCYmbC5jb3B5KHMpLGI8aCkpcmV0dXJuIE1hdGguc3FydChiKX1sZXQgeT0wO2ZvcihsZXQgbT0wO208MzttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe2NvbnN0IHc9KG0rMSklMyx4PShtKzIpJTMsTT1nPDx3fGI8PHgsQT0xPDxtfGc8PHd8Yjw8eCxfPWRbTV0sUz1kW0FdO3RbeV0uc2V0KF8sUyk7Y29uc3Qgej1pW21dLHY9aVt3XSxDPWlbeF0sUD1lW3ldLEY9UC5zdGFydCxCPVAuZW5kO0Zbel09dVt6XSxGW3ZdPWc/dVt2XTpmW3ZdLEZbQ109Yj91W0NdOmZbdl0sQlt6XT1mW3pdLEJbdl09Zz91W3ZdOmZbdl0sQltDXT1iP3VbQ106Zlt2XSx5Kyt9Zm9yKGxldCBtPTA7bTw9MTttKyspZm9yKGxldCBnPTA7Zzw9MTtnKyspZm9yKGxldCBiPTA7Yjw9MTtiKyspe3MueD1tP2YueDp1Lngscy55PWc/Zi55OnUueSxzLno9Yj9mLno6dS56LHRoaXMuY2xvc2VzdFBvaW50VG9Qb2ludChzLG4pO2NvbnN0IHc9cy5kaXN0YW5jZVRvU3F1YXJlZChuKTtpZih3PHAmJihwPXcsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx3PGgpKXJldHVybiBNYXRoLnNxcnQodyl9Zm9yKGxldCBtPTA7bTwxMjttKyspe2NvbnN0IGc9dFttXTtmb3IobGV0IGI9MDtiPDEyO2IrKyl7Y29uc3Qgdz1lW2JdO0RvKGcsdyxuLHMpO2NvbnN0IHg9bi5kaXN0YW5jZVRvU3F1YXJlZChzKTtpZih4PHAmJihwPXgsYyYmYy5jb3B5KG4pLGwmJmwuY29weShzKSx4PGgpKXJldHVybiBNYXRoLnNxcnQoeCl9fXJldHVybiBNYXRoLnNxcnQocCl9fSgpO2NsYXNzIFVve2NvbnN0cnVjdG9yKHQpe3RoaXMuX2dldE5ld1ByaW1pdGl2ZT10LHRoaXMuX3ByaW1pdGl2ZXM9W119Z2V0UHJpbWl0aXZlKCl7Y29uc3QgdD10aGlzLl9wcmltaXRpdmVzO3JldHVybiB0Lmxlbmd0aD09PTA/dGhpcy5fZ2V0TmV3UHJpbWl0aXZlKCk6dC5wb3AoKX1yZWxlYXNlUHJpbWl0aXZlKHQpe3RoaXMuX3ByaW1pdGl2ZXMucHVzaCh0KX19Y2xhc3MgZmQgZXh0ZW5kcyBVb3tjb25zdHJ1Y3Rvcigpe3N1cGVyKCgpPT5uZXcgbmUpfX1jb25zdCBpZT1uZXcgZmQ7Y2xhc3MgZGR7Y29uc3RydWN0b3IoKXt0aGlzLmZsb2F0MzJBcnJheT1udWxsLHRoaXMudWludDE2QXJyYXk9bnVsbCx0aGlzLnVpbnQzMkFycmF5PW51bGw7Y29uc3QgdD1bXTtsZXQgZT1udWxsO3RoaXMuc2V0QnVmZmVyPW49PntlJiZ0LnB1c2goZSksZT1uLHRoaXMuZmxvYXQzMkFycmF5PW5ldyBGbG9hdDMyQXJyYXkobiksdGhpcy51aW50MTZBcnJheT1uZXcgVWludDE2QXJyYXkobiksdGhpcy51aW50MzJBcnJheT1uZXcgVWludDMyQXJyYXkobil9LHRoaXMuY2xlYXJCdWZmZXI9KCk9PntlPW51bGwsdGhpcy5mbG9hdDMyQXJyYXk9bnVsbCx0aGlzLnVpbnQxNkFycmF5PW51bGwsdGhpcy51aW50MzJBcnJheT1udWxsLHQubGVuZ3RoIT09MCYmdGhpcy5zZXRCdWZmZXIodC5wb3AoKSl9fX1jb25zdCBudD1uZXcgZGQ7bGV0IEtlLFpuO2NvbnN0IFhuPVtdLENzPW5ldyBVbygoKT0+bmV3IGd0KTtmdW5jdGlvbiBwZChpLHQsZSxuLHMscil7S2U9Q3MuZ2V0UHJpbWl0aXZlKCksWm49Q3MuZ2V0UHJpbWl0aXZlKCksWG4ucHVzaChLZSxabiksbnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPVZvKDAsaS5nZW9tZXRyeSxlLG4scyxyKTtudC5jbGVhckJ1ZmZlcigpLENzLnJlbGVhc2VQcmltaXRpdmUoS2UpLENzLnJlbGVhc2VQcmltaXRpdmUoWm4pLFhuLnBvcCgpLFhuLnBvcCgpO2NvbnN0IGE9WG4ubGVuZ3RoO3JldHVybiBhPjAmJihabj1YblthLTFdLEtlPVhuW2EtMl0pLG99ZnVuY3Rpb24gVm8oaSx0LGUsbixzPW51bGwscj0wLG89MCl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udDtsZXQgaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1WdChpLGwpLGQ9S3QoaCxjKTtyZXR1cm4gbHQoaSxhLEtlKSxuKGYsZCwhMSxvLHIraSxLZSl9ZWxzZXtsZXQgej1mdW5jdGlvbihDKXtjb25zdHt1aW50MTZBcnJheTpQLHVpbnQzMkFycmF5OkZ9PW50O2xldCBCPUMqMjtmb3IoOyFrdChCLFApOylDPXRlKEMpLEI9QyoyO3JldHVybiBWdChDLEYpfSx2PWZ1bmN0aW9uKEMpe2NvbnN0e3VpbnQxNkFycmF5OlAsdWludDMyQXJyYXk6Rn09bnQ7bGV0IEI9QyoyO2Zvcig7IWt0KEIsUCk7KUM9ZWUoQyxGKSxCPUMqMjtyZXR1cm4gVnQoQyxGKStLdChCLFApfTtjb25zdCBmPXRlKGkpLGQ9ZWUoaSxsKTtsZXQgcD1mLHk9ZCxtLGcsYix3O2lmKHMmJihiPUtlLHc9Wm4sbHQocCxhLGIpLGx0KHksYSx3KSxtPXMoYiksZz1zKHcpLGc8bSkpe3A9ZCx5PWY7Y29uc3QgQz1tO209ZyxnPUMsYj13fWJ8fChiPUtlLGx0KHAsYSxiKSk7Y29uc3QgeD1rdChwKjIsYyksTT1lKGIseCxtLG8rMSxyK3ApO2xldCBBO2lmKE09PT1KYyl7Y29uc3QgQz16KHApLEY9dihwKS1DO0E9bihDLEYsITAsbysxLHIrcCxiKX1lbHNlIEE9TSYmVm8ocCx0LGUsbixzLHIsbysxKTtpZihBKXJldHVybiEwO3c9Wm4sbHQoeSxhLHcpO2NvbnN0IF89a3QoeSoyLGMpLFM9ZSh3LF8sZyxvKzEscit5KTtsZXQgRTtpZihTPT09SmMpe2NvbnN0IEM9eih5KSxGPXYoeSktQztFPW4oQyxGLCEwLG8rMSxyK3ksdyl9ZWxzZSBFPVMmJlZvKHksdCxlLG4scyxyLG8rMSk7cmV0dXJuISFFfX1jb25zdCBDaT1uZXcgVCxxbz1uZXcgVDtmdW5jdGlvbiB5ZChpLHQsZT17fSxuPTAscz0xLzApe2NvbnN0IHI9bipuLG89cypzO2xldCBhPTEvMCxjPW51bGw7aWYoaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6aD0+KENpLmNvcHkodCkuY2xhbXAoaC5taW4saC5tYXgpLENpLmRpc3RhbmNlVG9TcXVhcmVkKHQpKSxpbnRlcnNlY3RzQm91bmRzOihoLHUsZik9PmY8YSYmZjxvLGludGVyc2VjdHNUcmlhbmdsZTooaCx1KT0+e2guY2xvc2VzdFBvaW50VG9Qb2ludCh0LENpKTtjb25zdCBmPXQuZGlzdGFuY2VUb1NxdWFyZWQoQ2kpO3JldHVybiBmPGEmJihxby5jb3B5KENpKSxhPWYsYz11KSxmPHJ9fSksYT09PTEvMClyZXR1cm4gbnVsbDtjb25zdCBsPU1hdGguc3FydChhKTtyZXR1cm4gZS5wb2ludD9lLnBvaW50LmNvcHkocW8pOmUucG9pbnQ9cW8uY2xvbmUoKSxlLmRpc3RhbmNlPWwsZS5mYWNlSW5kZXg9YyxlfWNvbnN0IG1kPXBhcnNlSW50KEopPj0xNjkscG49bmV3IFQseW49bmV3IFQsbW49bmV3IFQsQnM9bmV3IFIsRnM9bmV3IFIsSXM9bmV3IFIscmw9bmV3IFQsb2w9bmV3IFQsYWw9bmV3IFQsQmk9bmV3IFQ7ZnVuY3Rpb24gZ2QoaSx0LGUsbixzLHIsbyxhKXtsZXQgYztpZihyPT09MT9jPWkuaW50ZXJzZWN0VHJpYW5nbGUobixlLHQsITAscyk6Yz1pLmludGVyc2VjdFRyaWFuZ2xlKHQsZSxuLHIhPT0yLHMpLGM9PT1udWxsKXJldHVybiBudWxsO2NvbnN0IGw9aS5vcmlnaW4uZGlzdGFuY2VUbyhzKTtyZXR1cm4gbDxvfHxsPmE/bnVsbDp7ZGlzdGFuY2U6bCxwb2ludDpzLmNsb25lKCl9fWZ1bmN0aW9uIHhkKGksdCxlLG4scyxyLG8sYSxjLGwsaCl7cG4uZnJvbUJ1ZmZlckF0dHJpYnV0ZSh0LHIpLHluLmZyb21CdWZmZXJBdHRyaWJ1dGUodCxvKSxtbi5mcm9tQnVmZmVyQXR0cmlidXRlKHQsYSk7Y29uc3QgdT1nZChpLHBuLHluLG1uLEJpLGMsbCxoKTtpZih1KXtjb25zdCBmPW5ldyBUO2V0LmdldEJhcnljb29yZChCaSxwbix5bixtbixmKSxuJiYoQnMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShuLHIpLEZzLmZyb21CdWZmZXJBdHRyaWJ1dGUobixvKSxJcy5mcm9tQnVmZmVyQXR0cmlidXRlKG4sYSksdS51dj1ldC5nZXRJbnRlcnBvbGF0aW9uKEJpLHBuLHluLG1uLEJzLEZzLElzLG5ldyBSKSkscyYmKEJzLmZyb21CdWZmZXJBdHRyaWJ1dGUocyxyKSxGcy5mcm9tQnVmZmVyQXR0cmlidXRlKHMsbyksSXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShzLGEpLHUudXYxPWV0LmdldEludGVycG9sYXRpb24oQmkscG4seW4sbW4sQnMsRnMsSXMsbmV3IFIpKSxlJiYocmwuZnJvbUJ1ZmZlckF0dHJpYnV0ZShlLHIpLG9sLmZyb21CdWZmZXJBdHRyaWJ1dGUoZSxvKSxhbC5mcm9tQnVmZmVyQXR0cmlidXRlKGUsYSksdS5ub3JtYWw9ZXQuZ2V0SW50ZXJwb2xhdGlvbihCaSxwbix5bixtbixybCxvbCxhbCxuZXcgVCksdS5ub3JtYWwuZG90KGkuZGlyZWN0aW9uKT4wJiZ1Lm5vcm1hbC5tdWx0aXBseVNjYWxhcigtMSkpO2NvbnN0IGQ9e2E6cixiOm8sYzphLG5vcm1hbDpuZXcgVCxtYXRlcmlhbEluZGV4OjB9O2V0LmdldE5vcm1hbChwbix5bixtbixkLm5vcm1hbCksdS5mYWNlPWQsdS5mYWNlSW5kZXg9cixtZCYmKHUuYmFyeWNvb3JkPWYpfXJldHVybiB1fWZ1bmN0aW9uIGtzKGksdCxlLG4scyxyLG8pe2NvbnN0IGE9biozO2xldCBjPWErMCxsPWErMSxoPWErMjtjb25zdCB1PWkuaW5kZXg7aS5pbmRleCYmKGM9dS5nZXRYKGMpLGw9dS5nZXRYKGwpLGg9dS5nZXRYKGgpKTtjb25zdHtwb3NpdGlvbjpmLG5vcm1hbDpkLHV2OnAsdXYxOnl9PWkuYXR0cmlidXRlcyxtPXhkKGUsZixkLHAseSxjLGwsaCx0LHIsbyk7cmV0dXJuIG0/KG0uZmFjZUluZGV4PW4scyYmcy5wdXNoKG0pLG0pOm51bGx9ZnVuY3Rpb24geXQoaSx0LGUsbil7Y29uc3Qgcz1pLmEscj1pLmIsbz1pLmM7bGV0IGE9dCxjPXQrMSxsPXQrMjtlJiYoYT1lLmdldFgoYSksYz1lLmdldFgoYyksbD1lLmdldFgobCkpLHMueD1uLmdldFgoYSkscy55PW4uZ2V0WShhKSxzLno9bi5nZXRaKGEpLHIueD1uLmdldFgoYyksci55PW4uZ2V0WShjKSxyLno9bi5nZXRaKGMpLG8ueD1uLmdldFgobCksby55PW4uZ2V0WShsKSxvLno9bi5nZXRaKGwpfWZ1bmN0aW9uIHdkKGksdCxlLG4scyxyLG8sYSl7Y29uc3R7Z2VvbWV0cnk6YyxfaW5kaXJlY3RCdWZmZXI6bH09aTtmb3IobGV0IGg9bix1PW4rcztoPHU7aCsrKWtzKGMsdCxlLGgscixvLGEpfWZ1bmN0aW9uIGJkKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmEsX2luZGlyZWN0QnVmZmVyOmN9PWk7bGV0IGw9MS8wLGg9bnVsbDtmb3IobGV0IHU9bixmPW4rczt1PGY7dSsrKXtsZXQgZDtkPWtzKGEsdCxlLHUsbnVsbCxyLG8pLGQmJmQuZGlzdGFuY2U8bCYmKGg9ZCxsPWQuZGlzdGFuY2UpfXJldHVybiBofWZ1bmN0aW9uIE1kKGksdCxlLG4scyxyLG8pe2NvbnN0e2dlb21ldHJ5OmF9PWUse2luZGV4OmN9PWEsbD1hLmF0dHJpYnV0ZXMucG9zaXRpb247Zm9yKGxldCBoPWksdT10K2k7aDx1O2grKyl7bGV0IGY7aWYoZj1oLHl0KG8sZiozLGMsbCksby5uZWVkc1VwZGF0ZT0hMCxuKG8sZixzLHIpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIEFkKGksdD1udWxsKXt0JiZBcnJheS5pc0FycmF5KHQpJiYodD1uZXcgU2V0KHQpKTtjb25zdCBlPWkuZ2VvbWV0cnksbj1lLmluZGV4P2UuaW5kZXguYXJyYXk6bnVsbCxzPWUuYXR0cmlidXRlcy5wb3NpdGlvbjtsZXQgcixvLGEsYyxsPTA7Y29uc3QgaD1pLl9yb290cztmb3IobGV0IGY9MCxkPWgubGVuZ3RoO2Y8ZDtmKyspcj1oW2ZdLG89bmV3IFVpbnQzMkFycmF5KHIpLGE9bmV3IFVpbnQxNkFycmF5KHIpLGM9bmV3IEZsb2F0MzJBcnJheShyKSx1KDAsbCksbCs9ci5ieXRlTGVuZ3RoO2Z1bmN0aW9uIHUoZixkLHA9ITEpe2NvbnN0IHk9ZioyO2lmKGFbeSsxNV09PT16cyl7Y29uc3QgZz1vW2YrNl0sYj1hW3krMTRdO2xldCB3PTEvMCx4PTEvMCxNPTEvMCxBPS0xLzAsXz0tMS8wLFM9LTEvMDtmb3IobGV0IEU9MypnLHo9MyooZytiKTtFPHo7RSsrKXtsZXQgdj1uW0VdO2NvbnN0IEM9cy5nZXRYKHYpLFA9cy5nZXRZKHYpLEY9cy5nZXRaKHYpO0M8dyYmKHc9QyksQz5BJiYoQT1DKSxQPHgmJih4PVApLFA+XyYmKF89UCksRjxNJiYoTT1GKSxGPlMmJihTPUYpfXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1ffHxjW2YrNV0hPT1TPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09XyxjW2YrNV09UywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsXz0hMTt0P018fChBPXQuaGFzKHcpLF89dC5oYXMoeCksTT0hQSYmIV8pOihBPSEwLF89ITApO2NvbnN0IFM9TXx8QSxFPU18fF87bGV0IHo9ITE7UyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFY9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+Vj9rOlZ9cmV0dXJuIEN9fX1mdW5jdGlvbiB0bihpLHQsZSxuLHMpe2xldCByLG8sYSxjLGwsaDtjb25zdCB1PTEvZS5kaXJlY3Rpb24ueCxmPTEvZS5kaXJlY3Rpb24ueSxkPTEvZS5kaXJlY3Rpb24ueixwPWUub3JpZ2luLngseT1lLm9yaWdpbi55LG09ZS5vcmlnaW4uejtsZXQgZz10W2ldLGI9dFtpKzNdLHc9dFtpKzFdLHg9dFtpKzMrMV0sTT10W2krMl0sQT10W2krMysyXTtyZXR1cm4gdT49MD8ocj0oZy1wKSp1LG89KGItcCkqdSk6KHI9KGItcCkqdSxvPShnLXApKnUpLGY+PTA/KGE9KHcteSkqZixjPSh4LXkpKmYpOihhPSh4LXkpKmYsYz0ody15KSpmKSxyPmN8fGE+b3x8KChhPnJ8fGlzTmFOKHIpKSYmKHI9YSksKGM8b3x8aXNOYU4obykpJiYobz1jKSxkPj0wPyhsPShNLW0pKmQsaD0oQS1tKSpkKToobD0oQS1tKSpkLGg9KE0tbSkqZCkscj5ofHxsPm8pPyExOigobD5yfHxyIT09cikmJihyPWwpLChoPG98fG8hPT1vKSYmKG89aCkscjw9cyYmbz49bil9ZnVuY3Rpb24gX2QoaSx0LGUsbixzLHIsbyxhKXtjb25zdHtnZW9tZXRyeTpjLF9pbmRpcmVjdEJ1ZmZlcjpsfT1pO2ZvcihsZXQgaD1uLHU9bitzO2g8dTtoKyspe2xldCBmPWw/bFtoXTpoO2tzKGMsdCxlLGYscixvLGEpfX1mdW5jdGlvbiBTZChpLHQsZSxuLHMscixvKXtjb25zdHtnZW9tZXRyeTphLF9pbmRpcmVjdEJ1ZmZlcjpjfT1pO2xldCBsPTEvMCxoPW51bGw7Zm9yKGxldCB1PW4sZj1uK3M7dTxmO3UrKyl7bGV0IGQ7ZD1rcyhhLHQsZSxjP2NbdV06dSxudWxsLHIsbyksZCYmZC5kaXN0YW5jZTxsJiYoaD1kLGw9ZC5kaXN0YW5jZSl9cmV0dXJuIGh9ZnVuY3Rpb24gdmQoaSx0LGUsbixzLHIsbyl7Y29uc3R7Z2VvbWV0cnk6YX09ZSx7aW5kZXg6Y309YSxsPWEuYXR0cmlidXRlcy5wb3NpdGlvbjtmb3IobGV0IGg9aSx1PXQraTtoPHU7aCsrKXtsZXQgZjtpZihmPWUucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoaCkseXQobyxmKjMsYyxsKSxvLm5lZWRzVXBkYXRlPSEwLG4obyxmLHMscikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gemQoaSx0LGUsbixzLHIsbyl7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKSxIbygwLGksZSxuLHMscixvKSxudC5jbGVhckJ1ZmZlcigpfWZ1bmN0aW9uIEhvKGksdCxlLG4scyxyLG8pe2NvbnN0e2Zsb2F0MzJBcnJheTphLHVpbnQxNkFycmF5OmMsdWludDMyQXJyYXk6bH09bnQsaD1pKjI7aWYoa3QoaCxjKSl7Y29uc3QgZj1WdChpLGwpLGQ9S3QoaCxjKTt3ZCh0LGUsbixmLGQscyxyLG8pfWVsc2V7Y29uc3QgZj10ZShpKTt0bihmLGEsbixyLG8pJiZIbyhmLHQsZSxuLHMscixvKTtjb25zdCBkPWVlKGksbCk7dG4oZCxhLG4scixvKSYmSG8oZCx0LGUsbixzLHIsbyl9fWNvbnN0IFRkPVsieCIsInkiLCJ6Il07ZnVuY3Rpb24gRWQoaSx0LGUsbixzLHIpe250LnNldEJ1ZmZlcihpLl9yb290c1t0XSk7Y29uc3Qgbz1XbygwLGksZSxuLHMscik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksb31mdW5jdGlvbiBXbyhpLHQsZSxuLHMscil7Y29uc3R7ZmxvYXQzMkFycmF5Om8sdWludDE2QXJyYXk6YSx1aW50MzJBcnJheTpjfT1udDtsZXQgbD1pKjI7aWYoa3QobCxhKSl7Y29uc3QgdT1WdChpLGMpLGY9S3QobCxhKTtyZXR1cm4gYmQodCxlLG4sdSxmLHMscil9ZWxzZXtjb25zdCB1PW5sKGksYyksZj1UZFt1XSxwPW4uZGlyZWN0aW9uW2ZdPj0wO2xldCB5LG07cD8oeT10ZShpKSxtPWVlKGksYykpOih5PWVlKGksYyksbT10ZShpKSk7Y29uc3QgYj10bih5LG8sbixzLHIpP1dvKHksdCxlLG4scyxyKTpudWxsO2lmKGIpe2NvbnN0IE09Yi5wb2ludFtmXTtpZihwP008PW9bbSt1XTpNPj1vW20rdSszXSlyZXR1cm4gYn1jb25zdCB4PXRuKG0sbyxuLHMscik/V28obSx0LGUsbixzLHIpOm51bGw7cmV0dXJuIGImJng/Yi5kaXN0YW5jZTw9eC5kaXN0YW5jZT9iOng6Ynx8eHx8bnVsbH19Y29uc3QgTnM9bmV3IGd0LEpuPW5ldyBuZSxZbj1uZXcgbmUsRmk9bmV3IHN0LGNsPW5ldyB6dCxScz1uZXcgenQ7ZnVuY3Rpb24gUGQoaSx0LGUsbil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBzPUdvKDAsaSxlLG4pO3JldHVybiBudC5jbGVhckJ1ZmZlcigpLHN9ZnVuY3Rpb24gR28oaSx0LGUsbixzPW51bGwpe2NvbnN0e2Zsb2F0MzJBcnJheTpyLHVpbnQxNkFycmF5Om8sdWludDMyQXJyYXk6YX09bnQ7bGV0IGM9aSoyO2lmKHM9PT1udWxsJiYoZS5ib3VuZGluZ0JveHx8ZS5jb21wdXRlQm91bmRpbmdCb3goKSxjbC5zZXQoZS5ib3VuZGluZ0JveC5taW4sZS5ib3VuZGluZ0JveC5tYXgsbikscz1jbCksa3QoYyxvKSl7Y29uc3QgaD10Lmdlb21ldHJ5LHU9aC5pbmRleCxmPWguYXR0cmlidXRlcy5wb3NpdGlvbixkPWUuaW5kZXgscD1lLmF0dHJpYnV0ZXMucG9zaXRpb24seT1WdChpLGEpLG09S3QoYyxvKTtpZihGaS5jb3B5KG4pLmludmVydCgpLGUuYm91bmRzVHJlZSlyZXR1cm4gbHQoaSxyLFJzKSxScy5tYXRyaXguY29weShGaSksUnMubmVlZHNVcGRhdGU9ITAsZS5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpiPT5Scy5pbnRlcnNlY3RzQm94KGIpLGludGVyc2VjdHNUcmlhbmdsZTpiPT57Yi5hLmFwcGx5TWF0cml4NChuKSxiLmIuYXBwbHlNYXRyaXg0KG4pLGIuYy5hcHBseU1hdHJpeDQobiksYi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHc9eSozLHg9KG0reSkqMzt3PHg7dys9MylpZih5dChZbix3LHUsZiksWW4ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoWW4pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15KjMsYj0obSt5KSozO2c8YjtnKz0zKXt5dChKbixnLHUsZiksSm4uYS5hcHBseU1hdHJpeDQoRmkpLEpuLmIuYXBwbHlNYXRyaXg0KEZpKSxKbi5jLmFwcGx5TWF0cml4NChGaSksSm4ubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCB3PTAseD1kLmNvdW50O3c8eDt3Kz0zKWlmKHl0KFluLHcsZCxwKSxZbi5uZWVkc1VwZGF0ZT0hMCxKbi5pbnRlcnNlY3RzVHJpYW5nbGUoWW4pKXJldHVybiEwfX1lbHNle2NvbnN0IGg9aSs4LHU9YVtpKzZdO3JldHVybiBsdChoLHIsTnMpLCEhKHMuaW50ZXJzZWN0c0JveChOcykmJkdvKGgsdCxlLG4scyl8fChsdCh1LHIsTnMpLHMuaW50ZXJzZWN0c0JveChOcykmJkdvKHUsdCxlLG4scykpKX19Y29uc3QgTHM9bmV3IHN0LFpvPW5ldyB6dCxJaT1uZXcgenQsQ2Q9bmV3IFQsQmQ9bmV3IFQsRmQ9bmV3IFQsSWQ9bmV3IFQ7ZnVuY3Rpb24ga2QoaSx0LGUsbj17fSxzPXt9LHI9MCxvPTEvMCl7dC5ib3VuZGluZ0JveHx8dC5jb21wdXRlQm91bmRpbmdCb3goKSxaby5zZXQodC5ib3VuZGluZ0JveC5taW4sdC5ib3VuZGluZ0JveC5tYXgsZSksWm8ubmVlZHNVcGRhdGU9ITA7Y29uc3QgYT1pLmdlb21ldHJ5LGM9YS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9YS5pbmRleCxoPXQuYXR0cmlidXRlcy5wb3NpdGlvbix1PXQuaW5kZXgsZj1pZS5nZXRQcmltaXRpdmUoKSxkPWllLmdldFByaW1pdGl2ZSgpO2xldCBwPUNkLHk9QmQsbT1udWxsLGc9bnVsbDtzJiYobT1GZCxnPUlkKTtsZXQgYj0xLzAsdz1udWxsLHg9bnVsbDtyZXR1cm4gTHMuY29weShlKS5pbnZlcnQoKSxJaS5tYXRyaXguY29weShMcyksaS5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6TT0+Wm8uZGlzdGFuY2VUb0JveChNKSxpbnRlcnNlY3RzQm91bmRzOihNLEEsXyk9Pl88YiYmXzxvPyhBJiYoSWkubWluLmNvcHkoTS5taW4pLElpLm1heC5jb3B5KE0ubWF4KSxJaS5uZWVkc1VwZGF0ZT0hMCksITApOiExLGludGVyc2VjdHNSYW5nZTooTSxBKT0+e2lmKHQuYm91bmRzVHJlZSlyZXR1cm4gdC5ib3VuZHNUcmVlLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpTPT5JaS5kaXN0YW5jZVRvQm94KFMpLGludGVyc2VjdHNCb3VuZHM6KFMsRSx6KT0+ejxiJiZ6PG8saW50ZXJzZWN0c1JhbmdlOihTLEUpPT57Zm9yKGxldCB6PVMsdj1TK0U7ejx2O3orKyl7eXQoZCwzKnosdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgQz1NLFA9TStBO0M8UDtDKyspe3l0KGYsMypDLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBGPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihGPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Rix3PUMseD16KSxGPHIpcmV0dXJuITB9fX19KTt7Y29uc3QgXz1Hbih0KTtmb3IobGV0IFM9MCxFPV87UzxFO1MrKyl7eXQoZCwzKlMsdSxoKSxkLmEuYXBwbHlNYXRyaXg0KGUpLGQuYi5hcHBseU1hdHJpeDQoZSksZC5jLmFwcGx5TWF0cml4NChlKSxkLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgej1NLHY9TStBO3o8djt6Kyspe3l0KGYsMyp6LGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBDPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihDPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9Qyx3PXoseD1TKSxDPHIpcmV0dXJuITB9fX19fSksaWUucmVsZWFzZVByaW1pdGl2ZShmKSxpZS5yZWxlYXNlUHJpbWl0aXZlKGQpLGI9PT0xLzA/bnVsbDoobi5wb2ludD9uLnBvaW50LmNvcHkoeSk6bi5wb2ludD15LmNsb25lKCksbi5kaXN0YW5jZT1iLG4uZmFjZUluZGV4PXcscyYmKHMucG9pbnQ/cy5wb2ludC5jb3B5KGcpOnMucG9pbnQ9Zy5jbG9uZSgpLHMucG9pbnQuYXBwbHlNYXRyaXg0KExzKSx5LmFwcGx5TWF0cml4NChMcykscy5kaXN0YW5jZT15LnN1YihzLnBvaW50KS5sZW5ndGgoKSxzLmZhY2VJbmRleD14KSxuKX1mdW5jdGlvbiBOZChpLHQ9bnVsbCl7dCYmQXJyYXkuaXNBcnJheSh0KSYmKHQ9bmV3IFNldCh0KSk7Y29uc3QgZT1pLmdlb21ldHJ5LG49ZS5pbmRleD9lLmluZGV4LmFycmF5Om51bGwscz1lLmF0dHJpYnV0ZXMucG9zaXRpb247bGV0IHIsbyxhLGMsbD0wO2NvbnN0IGg9aS5fcm9vdHM7Zm9yKGxldCBmPTAsZD1oLmxlbmd0aDtmPGQ7ZisrKXI9aFtmXSxvPW5ldyBVaW50MzJBcnJheShyKSxhPW5ldyBVaW50MTZBcnJheShyKSxjPW5ldyBGbG9hdDMyQXJyYXkociksdSgwLGwpLGwrPXIuYnl0ZUxlbmd0aDtmdW5jdGlvbiB1KGYsZCxwPSExKXtjb25zdCB5PWYqMjtpZihhW3krMTVdPT09enMpe2NvbnN0IGc9b1tmKzZdLGI9YVt5KzE0XTtsZXQgdz0xLzAseD0xLzAsTT0xLzAsQT0tMS8wLF89LTEvMCxTPS0xLzA7Zm9yKGxldCBFPWcsej1nK2I7RTx6O0UrKyl7Y29uc3Qgdj0zKmkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoRSk7Zm9yKGxldCBDPTA7QzwzO0MrKyl7bGV0IFA9ditDO1A9bj9uW1BdOlA7Y29uc3QgRj1zLmdldFgoUCksQj1zLmdldFkoUCksST1zLmdldFooUCk7Rjx3JiYodz1GKSxGPkEmJihBPUYpLEI8eCYmKHg9QiksQj5fJiYoXz1CKSxJPE0mJihNPUkpLEk+UyYmKFM9SSl9fXJldHVybiBjW2YrMF0hPT13fHxjW2YrMV0hPT14fHxjW2YrMl0hPT1NfHxjW2YrM10hPT1BfHxjW2YrNF0hPT1ffHxjW2YrNV0hPT1TPyhjW2YrMF09dyxjW2YrMV09eCxjW2YrMl09TSxjW2YrM109QSxjW2YrNF09XyxjW2YrNV09UywhMCk6ITF9ZWxzZXtjb25zdCBnPWYrOCxiPW9bZis2XSx3PWcrZCx4PWIrZDtsZXQgTT1wLEE9ITEsXz0hMTt0P018fChBPXQuaGFzKHcpLF89dC5oYXMoeCksTT0hQSYmIV8pOihBPSEwLF89ITApO2NvbnN0IFM9TXx8QSxFPU18fF87bGV0IHo9ITE7UyYmKHo9dShnLGQsTSkpO2xldCB2PSExO0UmJih2PXUoYixkLE0pKTtjb25zdCBDPXp8fHY7aWYoQylmb3IobGV0IFA9MDtQPDM7UCsrKXtjb25zdCBGPWcrUCxCPWIrUCxJPWNbRl0saz1jW0YrM10sRD1jW0JdLFY9Y1tCKzNdO2NbZitQXT1JPEQ/STpELGNbZitQKzNdPWs+Vj9rOlZ9cmV0dXJuIEN9fX1mdW5jdGlvbiBSZChpLHQsZSxuLHMscixvKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pLFhvKDAsaSxlLG4scyxyLG8pLG50LmNsZWFyQnVmZmVyKCl9ZnVuY3Rpb24gWG8oaSx0LGUsbixzLHIsbyl7Y29uc3R7ZmxvYXQzMkFycmF5OmEsdWludDE2QXJyYXk6Yyx1aW50MzJBcnJheTpsfT1udCxoPWkqMjtpZihrdChoLGMpKXtjb25zdCBmPVZ0KGksbCksZD1LdChoLGMpO19kKHQsZSxuLGYsZCxzLHIsbyl9ZWxzZXtjb25zdCBmPXRlKGkpO3RuKGYsYSxuLHIsbykmJlhvKGYsdCxlLG4scyxyLG8pO2NvbnN0IGQ9ZWUoaSxsKTt0bihkLGEsbixyLG8pJiZYbyhkLHQsZSxuLHMscixvKX19Y29uc3QgTGQ9WyJ4IiwieSIsInoiXTtmdW5jdGlvbiBPZChpLHQsZSxuLHMscil7bnQuc2V0QnVmZmVyKGkuX3Jvb3RzW3RdKTtjb25zdCBvPUpvKDAsaSxlLG4scyxyKTtyZXR1cm4gbnQuY2xlYXJCdWZmZXIoKSxvfWZ1bmN0aW9uIEpvKGksdCxlLG4scyxyKXtjb25zdHtmbG9hdDMyQXJyYXk6byx1aW50MTZBcnJheTphLHVpbnQzMkFycmF5OmN9PW50O2xldCBsPWkqMjtpZihrdChsLGEpKXtjb25zdCB1PVZ0KGksYyksZj1LdChsLGEpO3JldHVybiBTZCh0LGUsbix1LGYscyxyKX1lbHNle2NvbnN0IHU9bmwoaSxjKSxmPUxkW3VdLHA9bi5kaXJlY3Rpb25bZl0+PTA7bGV0IHksbTtwPyh5PXRlKGkpLG09ZWUoaSxjKSk6KHk9ZWUoaSxjKSxtPXRlKGkpKTtjb25zdCBiPXRuKHksbyxuLHMscik/Sm8oeSx0LGUsbixzLHIpOm51bGw7aWYoYil7Y29uc3QgTT1iLnBvaW50W2ZdO2lmKHA/TTw9b1ttK3VdOk0+PW9bbSt1KzNdKXJldHVybiBifWNvbnN0IHg9dG4obSxvLG4scyxyKT9KbyhtLHQsZSxuLHMscik6bnVsbDtyZXR1cm4gYiYmeD9iLmRpc3RhbmNlPD14LmRpc3RhbmNlP2I6eDpifHx4fHxudWxsfX1jb25zdCBPcz1uZXcgZ3Qsam49bmV3IG5lLFFuPW5ldyBuZSxraT1uZXcgc3QsbGw9bmV3IHp0LERzPW5ldyB6dDtmdW5jdGlvbiBEZChpLHQsZSxuKXtudC5zZXRCdWZmZXIoaS5fcm9vdHNbdF0pO2NvbnN0IHM9WW8oMCxpLGUsbik7cmV0dXJuIG50LmNsZWFyQnVmZmVyKCksc31mdW5jdGlvbiBZbyhpLHQsZSxuLHM9bnVsbCl7Y29uc3R7ZmxvYXQzMkFycmF5OnIsdWludDE2QXJyYXk6byx1aW50MzJBcnJheTphfT1udDtsZXQgYz1pKjI7aWYocz09PW51bGwmJihlLmJvdW5kaW5nQm94fHxlLmNvbXB1dGVCb3VuZGluZ0JveCgpLGxsLnNldChlLmJvdW5kaW5nQm94Lm1pbixlLmJvdW5kaW5nQm94Lm1heCxuKSxzPWxsKSxrdChjLG8pKXtjb25zdCBoPXQuZ2VvbWV0cnksdT1oLmluZGV4LGY9aC5hdHRyaWJ1dGVzLnBvc2l0aW9uLGQ9ZS5pbmRleCxwPWUuYXR0cmlidXRlcy5wb3NpdGlvbix5PVZ0KGksYSksbT1LdChjLG8pO2lmKGtpLmNvcHkobikuaW52ZXJ0KCksZS5ib3VuZHNUcmVlKXJldHVybiBsdChpLHIsRHMpLERzLm1hdHJpeC5jb3B5KGtpKSxEcy5uZWVkc1VwZGF0ZT0hMCxlLmJvdW5kc1RyZWUuc2hhcGVjYXN0KHtpbnRlcnNlY3RzQm91bmRzOmI9PkRzLmludGVyc2VjdHNCb3goYiksaW50ZXJzZWN0c1RyaWFuZ2xlOmI9PntiLmEuYXBwbHlNYXRyaXg0KG4pLGIuYi5hcHBseU1hdHJpeDQobiksYi5jLmFwcGx5TWF0cml4NChuKSxiLm5lZWRzVXBkYXRlPSEwO2ZvcihsZXQgdz15LHg9bSt5O3c8eDt3KyspaWYoeXQoUW4sMyp0LnJlc29sdmVUcmlhbmdsZUluZGV4KHcpLHUsZiksUW4ubmVlZHNVcGRhdGU9ITAsYi5pbnRlcnNlY3RzVHJpYW5nbGUoUW4pKXJldHVybiEwO3JldHVybiExfX0pO2ZvcihsZXQgZz15LGI9bSt5O2c8YjtnKyspe2NvbnN0IHc9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChnKTt5dChqbiwzKncsdSxmKSxqbi5hLmFwcGx5TWF0cml4NChraSksam4uYi5hcHBseU1hdHJpeDQoa2kpLGpuLmMuYXBwbHlNYXRyaXg0KGtpKSxqbi5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHg9MCxNPWQuY291bnQ7eDxNO3grPTMpaWYoeXQoUW4seCxkLHApLFFuLm5lZWRzVXBkYXRlPSEwLGpuLmludGVyc2VjdHNUcmlhbmdsZShRbikpcmV0dXJuITB9fWVsc2V7Y29uc3QgaD1pKzgsdT1hW2krNl07cmV0dXJuIGx0KGgscixPcyksISEocy5pbnRlcnNlY3RzQm94KE9zKSYmWW8oaCx0LGUsbixzKXx8KGx0KHUscixPcykscy5pbnRlcnNlY3RzQm94KE9zKSYmWW8odSx0LGUsbixzKSkpfX1jb25zdCAkcz1uZXcgc3Qsam89bmV3IHp0LE5pPW5ldyB6dCwkZD1uZXcgVCxVZD1uZXcgVCxWZD1uZXcgVCxxZD1uZXcgVDtmdW5jdGlvbiBIZChpLHQsZSxuPXt9LHM9e30scj0wLG89MS8wKXt0LmJvdW5kaW5nQm94fHx0LmNvbXB1dGVCb3VuZGluZ0JveCgpLGpvLnNldCh0LmJvdW5kaW5nQm94Lm1pbix0LmJvdW5kaW5nQm94Lm1heCxlKSxqby5uZWVkc1VwZGF0ZT0hMDtjb25zdCBhPWkuZ2VvbWV0cnksYz1hLmF0dHJpYnV0ZXMucG9zaXRpb24sbD1hLmluZGV4LGg9dC5hdHRyaWJ1dGVzLnBvc2l0aW9uLHU9dC5pbmRleCxmPWllLmdldFByaW1pdGl2ZSgpLGQ9aWUuZ2V0UHJpbWl0aXZlKCk7bGV0IHA9JGQseT1VZCxtPW51bGwsZz1udWxsO3MmJihtPVZkLGc9cWQpO2xldCBiPTEvMCx3PW51bGwseD1udWxsO3JldHVybiAkcy5jb3B5KGUpLmludmVydCgpLE5pLm1hdHJpeC5jb3B5KCRzKSxpLnNoYXBlY2FzdCh7Ym91bmRzVHJhdmVyc2VPcmRlcjpNPT5qby5kaXN0YW5jZVRvQm94KE0pLGludGVyc2VjdHNCb3VuZHM6KE0sQSxfKT0+XzxiJiZfPG8/KEEmJihOaS5taW4uY29weShNLm1pbiksTmkubWF4LmNvcHkoTS5tYXgpLE5pLm5lZWRzVXBkYXRlPSEwKSwhMCk6ITEsaW50ZXJzZWN0c1JhbmdlOihNLEEpPT57aWYodC5ib3VuZHNUcmVlKXtjb25zdCBfPXQuYm91bmRzVHJlZTtyZXR1cm4gXy5zaGFwZWNhc3Qoe2JvdW5kc1RyYXZlcnNlT3JkZXI6Uz0+TmkuZGlzdGFuY2VUb0JveChTKSxpbnRlcnNlY3RzQm91bmRzOihTLEUseik9Pno8YiYmejxvLGludGVyc2VjdHNSYW5nZTooUyxFKT0+e2ZvcihsZXQgej1TLHY9UytFO3o8djt6Kyspe2NvbnN0IEM9Xy5yZXNvbHZlVHJpYW5nbGVJbmRleCh6KTt5dChkLDMqQyx1LGgpLGQuYS5hcHBseU1hdHJpeDQoZSksZC5iLmFwcGx5TWF0cml4NChlKSxkLmMuYXBwbHlNYXRyaXg0KGUpLGQubmVlZHNVcGRhdGU9ITA7Zm9yKGxldCBQPU0sRj1NK0E7UDxGO1ArKyl7Y29uc3QgQj1pLnJlc29sdmVUcmlhbmdsZUluZGV4KFApO3l0KGYsMypCLGwsYyksZi5uZWVkc1VwZGF0ZT0hMDtjb25zdCBJPWYuZGlzdGFuY2VUb1RyaWFuZ2xlKGQscCxtKTtpZihJPGImJih5LmNvcHkocCksZyYmZy5jb3B5KG0pLGI9SSx3PVAseD16KSxJPHIpcmV0dXJuITB9fX19KX1lbHNle2NvbnN0IF89R24odCk7Zm9yKGxldCBTPTAsRT1fO1M8RTtTKyspe3l0KGQsMypTLHUsaCksZC5hLmFwcGx5TWF0cml4NChlKSxkLmIuYXBwbHlNYXRyaXg0KGUpLGQuYy5hcHBseU1hdHJpeDQoZSksZC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHo9TSx2PU0rQTt6PHY7eisrKXtjb25zdCBDPWkucmVzb2x2ZVRyaWFuZ2xlSW5kZXgoeik7eXQoZiwzKkMsbCxjKSxmLm5lZWRzVXBkYXRlPSEwO2NvbnN0IFA9Zi5kaXN0YW5jZVRvVHJpYW5nbGUoZCxwLG0pO2lmKFA8YiYmKHkuY29weShwKSxnJiZnLmNvcHkobSksYj1QLHc9eix4PVMpLFA8cilyZXR1cm4hMH19fX19KSxpZS5yZWxlYXNlUHJpbWl0aXZlKGYpLGllLnJlbGVhc2VQcmltaXRpdmUoZCksYj09PTEvMD9udWxsOihuLnBvaW50P24ucG9pbnQuY29weSh5KTpuLnBvaW50PXkuY2xvbmUoKSxuLmRpc3RhbmNlPWIsbi5mYWNlSW5kZXg9dyxzJiYocy5wb2ludD9zLnBvaW50LmNvcHkoZyk6cy5wb2ludD1nLmNsb25lKCkscy5wb2ludC5hcHBseU1hdHJpeDQoJHMpLHkuYXBwbHlNYXRyaXg0KCRzKSxzLmRpc3RhbmNlPXkuc3ViKHMucG9pbnQpLmxlbmd0aCgpLHMuZmFjZUluZGV4PXgpLG4pfWZ1bmN0aW9uIFdkKCl7cmV0dXJuIHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciE9InVuZGVmaW5lZCJ9Y29uc3QgUmk9bmV3IG50LmNvbnN0cnVjdG9yLFVzPW5ldyBudC5jb25zdHJ1Y3Rvcixlbj1uZXcgVW8oKCk9Pm5ldyBndCksS249bmV3IGd0LHRpPW5ldyBndCxRbz1uZXcgZ3QsS289bmV3IGd0O2xldCB0YT0hMTtmdW5jdGlvbiBHZChpLHQsZSxuKXtpZih0YSl0aHJvdyBuZXcgRXJyb3IoIk1lc2hCVkg6IFJlY3Vyc2l2ZSBjYWxscyB0byBidmhjYXN0IG5vdCBzdXBwb3J0ZWQuIik7dGE9ITA7Y29uc3Qgcz1pLl9yb290cyxyPXQuX3Jvb3RzO2xldCBvLGE9MCxjPTA7Y29uc3QgbD1uZXcgc3QoKS5jb3B5KGUpLmludmVydCgpO2ZvcihsZXQgaD0wLHU9cy5sZW5ndGg7aDx1O2grKyl7Umkuc2V0QnVmZmVyKHNbaF0pLGM9MDtjb25zdCBmPWVuLmdldFByaW1pdGl2ZSgpO2x0KDAsUmkuZmxvYXQzMkFycmF5LGYpLGYuYXBwbHlNYXRyaXg0KGwpO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwJiYoVXMuc2V0QnVmZmVyKHJbZF0pLG89ZmUoMCwwLGUsbCxuLGEsYywwLDAsZiksVXMuY2xlYXJCdWZmZXIoKSxjKz1yW2RdLmxlbmd0aCwhbyk7ZCsrKTtpZihlbi5yZWxlYXNlUHJpbWl0aXZlKGYpLFJpLmNsZWFyQnVmZmVyKCksYSs9c1toXS5sZW5ndGgsbylicmVha31yZXR1cm4gdGE9ITEsb31mdW5jdGlvbiBmZShpLHQsZSxuLHMscj0wLG89MCxhPTAsYz0wLGw9bnVsbCxoPSExKXtsZXQgdSxmO2g/KHU9VXMsZj1SaSk6KHU9UmksZj1Vcyk7Y29uc3QgZD11LmZsb2F0MzJBcnJheSxwPXUudWludDMyQXJyYXkseT11LnVpbnQxNkFycmF5LG09Zi5mbG9hdDMyQXJyYXksZz1mLnVpbnQzMkFycmF5LGI9Zi51aW50MTZBcnJheSx3PWkqMix4PXQqMixNPWt0KHcseSksQT1rdCh4LGIpO2xldCBfPSExO2lmKEEmJk0paD9fPXMoVnQodCxnKSxLdCh0KjIsYiksVnQoaSxwKSxLdChpKjIseSksYyxvK3QsYSxyK2kpOl89cyhWdChpLHApLEt0KGkqMix5KSxWdCh0LGcpLEt0KHQqMixiKSxhLHIraSxjLG8rdCk7ZWxzZSBpZihBKXtjb25zdCBTPWVuLmdldFByaW1pdGl2ZSgpO2x0KHQsbSxTKSxTLmFwcGx5TWF0cml4NChlKTtjb25zdCBFPXRlKGkpLHo9ZWUoaSxwKTtsdChFLGQsS24pLGx0KHosZCx0aSk7Y29uc3Qgdj1TLmludGVyc2VjdHNCb3goS24pLEM9Uy5pbnRlcnNlY3RzQm94KHRpKTtfPXYmJmZlKHQsRSxuLGUscyxvLHIsYyxhKzEsUywhaCl8fEMmJmZlKHQseixuLGUscyxvLHIsYyxhKzEsUywhaCksZW4ucmVsZWFzZVByaW1pdGl2ZShTKX1lbHNle2NvbnN0IFM9dGUodCksRT1lZSh0LGcpO2x0KFMsbSxRbyksbHQoRSxtLEtvKTtjb25zdCB6PWwuaW50ZXJzZWN0c0JveChRbyksdj1sLmludGVyc2VjdHNCb3goS28pO2lmKHomJnYpXz1mZShpLFMsZSxuLHMscixvLGEsYysxLGwsaCl8fGZlKGksRSxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNlIGlmKHopaWYoTSlfPWZlKGksUyxlLG4scyxyLG8sYSxjKzEsbCxoKTtlbHNle2NvbnN0IEM9ZW4uZ2V0UHJpbWl0aXZlKCk7Qy5jb3B5KFFvKS5hcHBseU1hdHJpeDQoZSk7Y29uc3QgUD10ZShpKSxGPWVlKGkscCk7bHQoUCxkLEtuKSxsdChGLGQsdGkpO2NvbnN0IEI9Qy5pbnRlcnNlY3RzQm94KEtuKSxJPUMuaW50ZXJzZWN0c0JveCh0aSk7Xz1CJiZmZShTLFAsbixlLHMsbyxyLGMsYSsxLEMsIWgpfHxJJiZmZShTLEYsbixlLHMsbyxyLGMsYSsxLEMsIWgpLGVuLnJlbGVhc2VQcmltaXRpdmUoQyl9ZWxzZSBpZih2KWlmKE0pXz1mZShpLEUsZSxuLHMscixvLGEsYysxLGwsaCk7ZWxzZXtjb25zdCBDPWVuLmdldFByaW1pdGl2ZSgpO0MuY29weShLbykuYXBwbHlNYXRyaXg0KGUpO2NvbnN0IFA9dGUoaSksRj1lZShpLHApO2x0KFAsZCxLbiksbHQoRixkLHRpKTtjb25zdCBCPUMuaW50ZXJzZWN0c0JveChLbiksST1DLmludGVyc2VjdHNCb3godGkpO189QiYmZmUoRSxQLG4sZSxzLG8scixjLGErMSxDLCFoKXx8SSYmZmUoRSxGLG4sZSxzLG8scixjLGErMSxDLCFoKSxlbi5yZWxlYXNlUHJpbWl0aXZlKEMpfX1yZXR1cm4gX31jb25zdCBWcz1uZXcgenQsaGw9bmV3IGd0LFpkPXtzdHJhdGVneTpYYyxtYXhEZXB0aDo0MCxtYXhMZWFmVHJpczoxMCx1c2VTaGFyZWRBcnJheUJ1ZmZlcjohMSxzZXRCb3VuZGluZ0JveDohMCxvblByb2dyZXNzOm51bGwsaW5kaXJlY3Q6ITEsdmVyYm9zZTohMCxyYW5nZTpudWxsfTtjbGFzcyBlYXtzdGF0aWMgc2VyaWFsaXplKHQsZT17fSl7ZT1GdCh7Y2xvbmVCdWZmZXJzOiEwfSxlKTtjb25zdCBuPXQuZ2VvbWV0cnkscz10Ll9yb290cyxyPXQuX2luZGlyZWN0QnVmZmVyLG89bi5nZXRJbmRleCgpO2xldCBhO3JldHVybiBlLmNsb25lQnVmZmVycz9hPXtyb290czpzLm1hcChjPT5jLnNsaWNlKCkpLGluZGV4Om8/by5hcnJheS5zbGljZSgpOm51bGwsaW5kaXJlY3RCdWZmZXI6cj9yLnNsaWNlKCk6bnVsbH06YT17cm9vdHM6cyxpbmRleDpvP28uYXJyYXk6bnVsbCxpbmRpcmVjdEJ1ZmZlcjpyfSxhfXN0YXRpYyBkZXNlcmlhbGl6ZSh0LGUsbj17fSl7bj1GdCh7c2V0SW5kZXg6ITAsaW5kaXJlY3Q6ISF0LmluZGlyZWN0QnVmZmVyfSxuKTtjb25zdHtpbmRleDpzLHJvb3RzOnIsaW5kaXJlY3RCdWZmZXI6b309dCxhPW5ldyBlYShlLEdlKEZ0KHt9LG4pLHtba29dOiEwfSkpO2lmKGEuX3Jvb3RzPXIsYS5faW5kaXJlY3RCdWZmZXI9b3x8bnVsbCxuLnNldEluZGV4KXtjb25zdCBjPWUuZ2V0SW5kZXgoKTtpZihjPT09bnVsbCl7Y29uc3QgbD1uZXcgeHQodC5pbmRleCwxLCExKTtlLnNldEluZGV4KGwpfWVsc2UgYy5hcnJheSE9PXMmJihjLmFycmF5LnNldChzKSxjLm5lZWRzVXBkYXRlPSEwKX1yZXR1cm4gYX1nZXQgaW5kaXJlY3QoKXtyZXR1cm4hIXRoaXMuX2luZGlyZWN0QnVmZmVyfWNvbnN0cnVjdG9yKHQsZT17fSl7aWYodC5pc0J1ZmZlckdlb21ldHJ5KXtpZih0LmluZGV4JiZ0LmluZGV4LmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGUgaW5kZXggYXR0cmlidXRlLiIpfWVsc2UgdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBPbmx5IEJ1ZmZlckdlb21ldHJpZXMgYXJlIHN1cHBvcnRlZC4iKTtpZihlPU9iamVjdC5hc3NpZ24oR2UoRnQoe30sWmQpLHtba29dOiExfSksZSksZS51c2VTaGFyZWRBcnJheUJ1ZmZlciYmIVdkKCkpdGhyb3cgbmV3IEVycm9yKCJNZXNoQlZIOiBTaGFyZWRBcnJheUJ1ZmZlciBpcyBub3QgYXZhaWxhYmxlLiIpO3RoaXMuZ2VvbWV0cnk9dCx0aGlzLl9yb290cz1udWxsLHRoaXMuX2luZGlyZWN0QnVmZmVyPW51bGwsZVtrb118fChjZCh0aGlzLGUpLCF0LmJvdW5kaW5nQm94JiZlLnNldEJvdW5kaW5nQm94JiYodC5ib3VuZGluZ0JveD10aGlzLmdldEJvdW5kaW5nQm94KG5ldyBndCkpKSx0aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4PWUuaW5kaXJlY3Q/bj0+dGhpcy5faW5kaXJlY3RCdWZmZXJbbl06bj0+bn1yZWZpdCh0PW51bGwpe3JldHVybih0aGlzLmluZGlyZWN0P05kOkFkKSh0aGlzLHQpfXRyYXZlcnNlKHQsZT0wKXtjb25zdCBuPXRoaXMuX3Jvb3RzW2VdLHM9bmV3IFVpbnQzMkFycmF5KG4pLHI9bmV3IFVpbnQxNkFycmF5KG4pO28oMCk7ZnVuY3Rpb24gbyhhLGM9MCl7Y29uc3QgbD1hKjIsaD1yW2wrMTVdPT09enM7aWYoaCl7Y29uc3QgdT1zW2ErNl0sZj1yW2wrMTRdO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksdSxmKX1lbHNle2NvbnN0IHU9YStUaS80LGY9c1thKzZdLGQ9c1thKzddO3QoYyxoLG5ldyBGbG9hdDMyQXJyYXkobixhKjQsNiksZCl8fChvKHUsYysxKSxvKGYsYysxKSl9fX1yYXljYXN0KHQsZT0wLG49MCxzPTEvMCl7Y29uc3Qgcj10aGlzLl9yb290cyxvPXRoaXMuZ2VvbWV0cnksYT1bXSxjPWUuaXNNYXRlcmlhbCxsPUFycmF5LmlzQXJyYXkoZSksaD1vLmdyb3Vwcyx1PWM/ZS5zaWRlOmUsZj10aGlzLmluZGlyZWN0P1JkOnpkO2ZvcihsZXQgZD0wLHA9ci5sZW5ndGg7ZDxwO2QrKyl7Y29uc3QgeT1sP2VbaFtkXS5tYXRlcmlhbEluZGV4XS5zaWRlOnUsbT1hLmxlbmd0aDtpZihmKHRoaXMsZCx5LHQsYSxuLHMpLGwpe2NvbnN0IGc9aFtkXS5tYXRlcmlhbEluZGV4O2ZvcihsZXQgYj1tLHc9YS5sZW5ndGg7Yjx3O2IrKylhW2JdLmZhY2UubWF0ZXJpYWxJbmRleD1nfX1yZXR1cm4gYX1yYXljYXN0Rmlyc3QodCxlPTAsbj0wLHM9MS8wKXtjb25zdCByPXRoaXMuX3Jvb3RzLG89dGhpcy5nZW9tZXRyeSxhPWUuaXNNYXRlcmlhbCxjPUFycmF5LmlzQXJyYXkoZSk7bGV0IGw9bnVsbDtjb25zdCBoPW8uZ3JvdXBzLHU9YT9lLnNpZGU6ZSxmPXRoaXMuaW5kaXJlY3Q/T2Q6RWQ7Zm9yKGxldCBkPTAscD1yLmxlbmd0aDtkPHA7ZCsrKXtjb25zdCB5PWM/ZVtoW2RdLm1hdGVyaWFsSW5kZXhdLnNpZGU6dSxtPWYodGhpcyxkLHksdCxuLHMpO20hPW51bGwmJihsPT1udWxsfHxtLmRpc3RhbmNlPGwuZGlzdGFuY2UpJiYobD1tLGMmJihtLmZhY2UubWF0ZXJpYWxJbmRleD1oW2RdLm1hdGVyaWFsSW5kZXgpKX1yZXR1cm4gbH1pbnRlcnNlY3RzR2VvbWV0cnkodCxlKXtsZXQgbj0hMTtjb25zdCBzPXRoaXMuX3Jvb3RzLHI9dGhpcy5pbmRpcmVjdD9EZDpQZDtmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YSYmKG49cih0aGlzLG8sdCxlKSwhbik7bysrKTtyZXR1cm4gbn1zaGFwZWNhc3QodCl7Y29uc3QgZT1pZS5nZXRQcmltaXRpdmUoKSxuPXRoaXMuaW5kaXJlY3Q/dmQ6TWQ7bGV0e2JvdW5kc1RyYXZlcnNlT3JkZXI6cyxpbnRlcnNlY3RzQm91bmRzOnIsaW50ZXJzZWN0c1JhbmdlOm8saW50ZXJzZWN0c1RyaWFuZ2xlOmF9PXQ7aWYobyYmYSl7Y29uc3QgdT1vO289KGYsZCxwLHksbSk9PnUoZixkLHAseSxtKT8hMDpuKGYsZCx0aGlzLGEscCx5LGUpfWVsc2Ugb3x8KGE/bz0odSxmLGQscCk9Pm4odSxmLHRoaXMsYSxkLHAsZSk6bz0odSxmLGQpPT5kKTtsZXQgYz0hMSxsPTA7Y29uc3QgaD10aGlzLl9yb290cztmb3IobGV0IHU9MCxmPWgubGVuZ3RoO3U8Zjt1Kyspe2NvbnN0IGQ9aFt1XTtpZihjPXBkKHRoaXMsdSxyLG8scyxsKSxjKWJyZWFrO2wrPWQuYnl0ZUxlbmd0aH1yZXR1cm4gaWUucmVsZWFzZVByaW1pdGl2ZShlKSxjfWJ2aGNhc3QodCxlLG4pe2xldHtpbnRlcnNlY3RzUmFuZ2VzOnMsaW50ZXJzZWN0c1RyaWFuZ2xlczpyfT1uO2NvbnN0IG89aWUuZ2V0UHJpbWl0aXZlKCksYT10aGlzLmdlb21ldHJ5LmluZGV4LGM9dGhpcy5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uLGw9dGhpcy5pbmRpcmVjdD9wPT57Y29uc3QgeT10aGlzLnJlc29sdmVUcmlhbmdsZUluZGV4KHApO3l0KG8seSozLGEsYyl9OnA9Pnt5dChvLHAqMyxhLGMpfSxoPWllLmdldFByaW1pdGl2ZSgpLHU9dC5nZW9tZXRyeS5pbmRleCxmPXQuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixkPXQuaW5kaXJlY3Q/cD0+e2NvbnN0IHk9dC5yZXNvbHZlVHJpYW5nbGVJbmRleChwKTt5dChoLHkqMyx1LGYpfTpwPT57eXQoaCxwKjMsdSxmKX07aWYocil7Y29uc3QgcD0oeSxtLGcsYix3LHgsTSxBKT0+e2ZvcihsZXQgXz1nLFM9ZytiO188UztfKyspe2QoXyksaC5hLmFwcGx5TWF0cml4NChlKSxoLmIuYXBwbHlNYXRyaXg0KGUpLGguYy5hcHBseU1hdHJpeDQoZSksaC5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IEU9eSx6PXkrbTtFPHo7RSsrKWlmKGwoRSksby5uZWVkc1VwZGF0ZT0hMCxyKG8saCxFLF8sdyx4LE0sQSkpcmV0dXJuITB9cmV0dXJuITF9O2lmKHMpe2NvbnN0IHk9cztzPWZ1bmN0aW9uKG0sZyxiLHcseCxNLEEsXyl7cmV0dXJuIHkobSxnLGIsdyx4LE0sQSxfKT8hMDpwKG0sZyxiLHcseCxNLEEsXyl9fWVsc2Ugcz1wfXJldHVybiBHZCh0aGlzLHQsZSxzKX1pbnRlcnNlY3RzQm94KHQsZSl7cmV0dXJuIFZzLnNldCh0Lm1pbix0Lm1heCxlKSxWcy5uZWVkc1VwZGF0ZT0hMCx0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczpuPT5Wcy5pbnRlcnNlY3RzQm94KG4pLGludGVyc2VjdHNUcmlhbmdsZTpuPT5Wcy5pbnRlcnNlY3RzVHJpYW5nbGUobil9KX1pbnRlcnNlY3RzU3BoZXJlKHQpe3JldHVybiB0aGlzLnNoYXBlY2FzdCh7aW50ZXJzZWN0c0JvdW5kczplPT50LmludGVyc2VjdHNCb3goZSksaW50ZXJzZWN0c1RyaWFuZ2xlOmU9PmUuaW50ZXJzZWN0c1NwaGVyZSh0KX0pfWNsb3Nlc3RQb2ludFRvR2VvbWV0cnkodCxlLG49e30scz17fSxyPTAsbz0xLzApe3JldHVybih0aGlzLmluZGlyZWN0P0hkOmtkKSh0aGlzLHQsZSxuLHMscixvKX1jbG9zZXN0UG9pbnRUb1BvaW50KHQsZT17fSxuPTAscz0xLzApe3JldHVybiB5ZCh0aGlzLHQsZSxuLHMpfWdldEJvdW5kaW5nQm94KHQpe3JldHVybiB0Lm1ha2VFbXB0eSgpLHRoaXMuX3Jvb3RzLmZvckVhY2gobj0+e2x0KDAsbmV3IEZsb2F0MzJBcnJheShuKSxobCksdC51bmlvbihobCl9KSx0fX1jb25zdCB1bD0xZS02LFhkPXVsKi41LGZsPU1hdGgucG93KDEwLC1NYXRoLmxvZzEwKHVsKSksSmQ9WGQqZmw7ZnVuY3Rpb24gd2UoaSl7cmV0dXJufn4oaSpmbCtKZCl9ZnVuY3Rpb24gWWQoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfWB9ZnVuY3Rpb24gZGwoaSl7cmV0dXJuYCR7d2UoaS54KX0sJHt3ZShpLnkpfSwke3dlKGkueil9YH1mdW5jdGlvbiBqZChpKXtyZXR1cm5gJHt3ZShpLngpfSwke3dlKGkueSl9LCR7d2UoaS56KX0sJHt3ZShpLncpfWB9ZnVuY3Rpb24gUWQoaSx0LGUpe2UuZGlyZWN0aW9uLnN1YlZlY3RvcnModCxpKS5ub3JtYWxpemUoKTtjb25zdCBuPWkuZG90KGUuZGlyZWN0aW9uKTtyZXR1cm4gZS5vcmlnaW4uY29weShpKS5hZGRTY2FsZWRWZWN0b3IoZS5kaXJlY3Rpb24sLW4pLGV9ZnVuY3Rpb24gcGwoKXtyZXR1cm4gdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIn1mdW5jdGlvbiBLZChpKXtpZihpLmJ1ZmZlciBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKXJldHVybiBpO2NvbnN0IHQ9aS5jb25zdHJ1Y3RvcixlPWkuYnVmZmVyLG49bmV3IFNoYXJlZEFycmF5QnVmZmVyKGUuYnl0ZUxlbmd0aCkscz1uZXcgVWludDhBcnJheShlKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobikuc2V0KHMsMCksbmV3IHQobil9ZnVuY3Rpb24gdDAoaSx0PUFycmF5QnVmZmVyKXtyZXR1cm4gaT42NTUzNT9uZXcgVWludDMyQXJyYXkobmV3IHQoNCppKSk6bmV3IFVpbnQxNkFycmF5KG5ldyB0KDIqaSkpfWZ1bmN0aW9uIGUwKGksdCl7aWYoIWkuaW5kZXgpe2NvbnN0IGU9aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50LG49dC51c2VTaGFyZWRBcnJheUJ1ZmZlcj9TaGFyZWRBcnJheUJ1ZmZlcjpBcnJheUJ1ZmZlcixzPXQwKGUsbik7aS5zZXRJbmRleChuZXcgeHQocywxKSk7Zm9yKGxldCByPTA7cjxlO3IrKylzW3JdPXJ9fWZ1bmN0aW9uIG4wKGkpe3JldHVybiBpLmluZGV4P2kuaW5kZXguY291bnQ6aS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWZ1bmN0aW9uIG5hKGkpe3JldHVybiBuMChpKS8zfWNvbnN0IGkwPTFlLTgsczA9bmV3IFQ7ZnVuY3Rpb24gcjAoaSl7cmV0dXJufn4oaS8zKX1mdW5jdGlvbiBvMChpKXtyZXR1cm4gaSUzfWZ1bmN0aW9uIHlsKGksdCl7cmV0dXJuIGkuc3RhcnQtdC5zdGFydH1mdW5jdGlvbiBtbChpLHQpe3JldHVybiBzMC5zdWJWZWN0b3JzKHQsaS5vcmlnaW4pLmRvdChpLmRpcmVjdGlvbil9ZnVuY3Rpb24gYTAoaSx0LGUsbj1pMCl7aS5zb3J0KHlsKSx0LnNvcnQoeWwpO2ZvcihsZXQgYT0wO2E8aS5sZW5ndGg7YSsrKXtjb25zdCBjPWlbYV07Zm9yKGxldCBsPTA7bDx0Lmxlbmd0aDtsKyspe2NvbnN0IGg9dFtsXTtpZighKGguc3RhcnQ+Yy5lbmQpKXtpZihjLmVuZDxoLnN0YXJ0fHxoLmVuZDxjLnN0YXJ0KWNvbnRpbnVlO2lmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPj1oLmVuZClyKGguZW5kLGMuZW5kKXx8aS5zcGxpY2UoYSsxLDAse3N0YXJ0OmguZW5kLGVuZDpjLmVuZCxpbmRleDpjLmluZGV4fSksYy5lbmQ9aC5zdGFydCxoLnN0YXJ0PTAsaC5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPD1oLmVuZClyKGMuZW5kLGguZW5kKXx8dC5zcGxpY2UobCsxLDAse3N0YXJ0OmMuZW5kLGVuZDpoLmVuZCxpbmRleDpoLmluZGV4fSksaC5lbmQ9Yy5zdGFydCxjLnN0YXJ0PTAsYy5lbmQ9MDtlbHNlIGlmKGMuc3RhcnQ8PWguc3RhcnQmJmMuZW5kPD1oLmVuZCl7Y29uc3QgdT1jLmVuZDtjLmVuZD1oLnN0YXJ0LGguc3RhcnQ9dX1lbHNlIGlmKGMuc3RhcnQ+PWguc3RhcnQmJmMuZW5kPj1oLmVuZCl7Y29uc3QgdT1oLmVuZDtoLmVuZD1jLnN0YXJ0LGMuc3RhcnQ9dX1lbHNlIHRocm93IG5ldyBFcnJvcn1pZihlLmhhcyhjLmluZGV4KXx8ZS5zZXQoYy5pbmRleCxbXSksZS5oYXMoaC5pbmRleCl8fGUuc2V0KGguaW5kZXgsW10pLGUuZ2V0KGMuaW5kZXgpLnB1c2goaC5pbmRleCksZS5nZXQoaC5pbmRleCkucHVzaChjLmluZGV4KSxvKGgpJiYodC5zcGxpY2UobCwxKSxsLS0pLG8oYykpe2kuc3BsaWNlKGEsMSksYS0tO2JyZWFrfX19cyhpKSxzKHQpO2Z1bmN0aW9uIHMoYSl7Zm9yKGxldCBjPTA7YzxhLmxlbmd0aDtjKyspbyhhW2NdKSYmKGEuc3BsaWNlKGMsMSksYy0tKX1mdW5jdGlvbiByKGEsYyl7cmV0dXJuIE1hdGguYWJzKGMtYSk8bn1mdW5jdGlvbiBvKGEpe3JldHVybiBNYXRoLmFicyhhLmVuZC1hLnN0YXJ0KTxufX1jb25zdCBnbD0xZS01LHhsPTFlLTQ7Y2xhc3MgYzB7Y29uc3RydWN0b3IoKXt0aGlzLl9yYXlzPVtdfWFkZFJheSh0KXt0aGlzLl9yYXlzLnB1c2godCl9ZmluZENsb3Nlc3RSYXkodCl7Y29uc3QgZT10aGlzLl9yYXlzLG49dC5jbG9uZSgpO24uZGlyZWN0aW9uLm11bHRpcGx5U2NhbGFyKC0xKTtsZXQgcz0xLzAscj1udWxsO2ZvcihsZXQgYz0wLGw9ZS5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1lW2NdO2lmKG8oaCx0KSYmbyhoLG4pKWNvbnRpbnVlO2NvbnN0IHU9YShoLHQpLGY9YShoLG4pLGQ9TWF0aC5taW4odSxmKTtkPHMmJihzPWQscj1oKX1yZXR1cm4gcjtmdW5jdGlvbiBvKGMsbCl7Y29uc3QgaD1jLm9yaWdpbi5kaXN0YW5jZVRvKGwub3JpZ2luKT5nbDtyZXR1cm4gYy5kaXJlY3Rpb24uYW5nbGVUbyhsLmRpcmVjdGlvbik+eGx8fGh9ZnVuY3Rpb24gYShjLGwpe2NvbnN0IGg9Yy5vcmlnaW4uZGlzdGFuY2VUbyhsLm9yaWdpbiksdT1jLmRpcmVjdGlvbi5hbmdsZVRvKGwuZGlyZWN0aW9uKTtyZXR1cm4gaC9nbCt1L3hsfX19Y29uc3QgaWE9bmV3IFQsc2E9bmV3IFQscXM9bmV3IGFvO2Z1bmN0aW9uIGwwKGksdCxlKXtjb25zdCBuPWkuYXR0cmlidXRlcyxzPWkuaW5kZXgscj1uLnBvc2l0aW9uLG89bmV3IE1hcCxhPW5ldyBNYXAsYz1BcnJheS5mcm9tKHQpLGw9bmV3IGMwO2ZvcihsZXQgaD0wLHU9Yy5sZW5ndGg7aDx1O2grKyl7Y29uc3QgZj1jW2hdLGQ9cjAoZikscD1vMChmKTtsZXQgeT0zKmQrcCxtPTMqZCsocCsxKSUzO3MmJih5PXMuZ2V0WCh5KSxtPXMuZ2V0WChtKSksaWEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShyLHkpLHNhLmZyb21CdWZmZXJBdHRyaWJ1dGUocixtKSxRZChpYSxzYSxxcyk7bGV0IGcsYj1sLmZpbmRDbG9zZXN0UmF5KHFzKTtiPT09bnVsbCYmKGI9cXMuY2xvbmUoKSxsLmFkZFJheShiKSksYS5oYXMoYil8fGEuc2V0KGIse2ZvcndhcmQ6W10scmV2ZXJzZTpbXSxyYXk6Yn0pLGc9YS5nZXQoYik7bGV0IHc9bWwoYixpYSkseD1tbChiLHNhKTt3PngmJihbdyx4XT1beCx3XSkscXMuZGlyZWN0aW9uLmRvdChiLmRpcmVjdGlvbik8MD9nLnJldmVyc2UucHVzaCh7c3RhcnQ6dyxlbmQ6eCxpbmRleDpmfSk6Zy5mb3J3YXJkLnB1c2goe3N0YXJ0OncsZW5kOngsaW5kZXg6Zn0pfXJldHVybiBhLmZvckVhY2goKHtmb3J3YXJkOmgscmV2ZXJzZTp1fSxmKT0+e2EwKGgsdSxvLGUpLGgubGVuZ3RoPT09MCYmdS5sZW5ndGg9PT0wJiZhLmRlbGV0ZShmKX0pLHtkaXNqb2ludENvbm5lY3Rpdml0eU1hcDpvLGZyYWdtZW50TWFwOmF9fWNvbnN0IGgwPW5ldyBSLHJhPW5ldyBULHUwPW5ldyBZdCxvYT1bIiIsIiIsIiJdO2NsYXNzIGYwe2NvbnN0cnVjdG9yKHQ9bnVsbCl7dGhpcy5kYXRhPW51bGwsdGhpcy5kaXNqb2ludENvbm5lY3Rpb25zPW51bGwsdGhpcy51bm1hdGNoZWREaXNqb2ludEVkZ2VzPW51bGwsdGhpcy51bm1hdGNoZWRFZGdlcz0tMSx0aGlzLm1hdGNoZWRFZGdlcz0tMSx0aGlzLnVzZURyYXdSYW5nZT0hMCx0aGlzLnVzZUFsbEF0dHJpYnV0ZXM9ITEsdGhpcy5tYXRjaERpc2pvaW50RWRnZXM9ITEsdGhpcy5kZWdlbmVyYXRlRXBzaWxvbj0xZS04LHQmJnRoaXMudXBkYXRlRnJvbSh0KX1nZXRTaWJsaW5nVHJpYW5nbGVJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOn5+KG4vMyl9Z2V0U2libGluZ0VkZ2VJbmRleCh0LGUpe2NvbnN0IG49dGhpcy5kYXRhW3QqMytlXTtyZXR1cm4gbj09PS0xPy0xOm4lM31nZXREaXNqb2ludFNpYmxpbmdUcmlhbmdsZUluZGljZXModCxlKXtjb25zdCBuPXQqMytlLHM9dGhpcy5kaXNqb2ludENvbm5lY3Rpb25zLmdldChuKTtyZXR1cm4gcz9zLm1hcChyPT5+fihyLzMpKTpbXX1nZXREaXNqb2ludFNpYmxpbmdFZGdlSW5kaWNlcyh0LGUpe2NvbnN0IG49dCozK2Uscz10aGlzLmRpc2pvaW50Q29ubmVjdGlvbnMuZ2V0KG4pO3JldHVybiBzP3MubWFwKHI9PnIlMyk6W119aXNGdWxseUNvbm5lY3RlZCgpe3JldHVybiB0aGlzLnVubWF0Y2hlZEVkZ2VzPT09MH11cGRhdGVGcm9tKHQpe2NvbnN0e3VzZUFsbEF0dHJpYnV0ZXM6ZSx1c2VEcmF3UmFuZ2U6bixtYXRjaERpc2pvaW50RWRnZXM6cyxkZWdlbmVyYXRlRXBzaWxvbjpyfT10aGlzLG89ZT93OmIsYT1uZXcgTWFwLHthdHRyaWJ1dGVzOmN9PXQsbD1lP09iamVjdC5rZXlzKGMpOm51bGwsaD10LmluZGV4LHU9Yy5wb3NpdGlvbjtsZXQgZj1uYSh0KTtjb25zdCBkPWY7bGV0IHA9MDtuJiYocD10LmRyYXdSYW5nZS5zdGFydCx0LmRyYXdSYW5nZS5jb3VudCE9PTEvMCYmKGY9fn4odC5kcmF3UmFuZ2UuY291bnQvMykpKTtsZXQgeT10aGlzLmRhdGE7KCF5fHx5Lmxlbmd0aDwzKmQpJiYoeT1uZXcgSW50MzJBcnJheSgzKmQpKSx5LmZpbGwoLTEpO2xldCBtPTAsZz1uZXcgU2V0O2ZvcihsZXQgeD1wLE09ZiozK3A7eDxNO3grPTMpe2NvbnN0IEE9eDtmb3IobGV0IF89MDtfPDM7XysrKXtsZXQgUz1BK187aCYmKFM9aC5nZXRYKFMpKSxvYVtfXT1vKFMpfWZvcihsZXQgXz0wO188MztfKyspe2NvbnN0IFM9KF8rMSklMyxFPW9hW19dLHo9b2FbU10sdj1gJHt6fV8ke0V9YDtpZihhLmhhcyh2KSl7Y29uc3QgQz1BK18sUD1hLmdldCh2KTt5W0NdPVAseVtQXT1DLGEuZGVsZXRlKHYpLG0rPTIsZy5kZWxldGUoUCl9ZWxzZXtjb25zdCBDPWAke0V9XyR7en1gLFA9QStfO2Euc2V0KEMsUCksZy5hZGQoUCl9fX1pZihzKXtjb25zdHtmcmFnbWVudE1hcDp4LGRpc2pvaW50Q29ubmVjdGl2aXR5TWFwOk19PWwwKHQsZyxyKTtnLmNsZWFyKCkseC5mb3JFYWNoKCh7Zm9yd2FyZDpBLHJldmVyc2U6X30pPT57QS5mb3JFYWNoKCh7aW5kZXg6U30pPT5nLmFkZChTKSksXy5mb3JFYWNoKCh7aW5kZXg6U30pPT5nLmFkZChTKSl9KSx0aGlzLnVubWF0Y2hlZERpc2pvaW50RWRnZXM9eCx0aGlzLmRpc2pvaW50Q29ubmVjdGlvbnM9TSxtPWYqMy1nLnNpemV9dGhpcy5tYXRjaGVkRWRnZXM9bSx0aGlzLnVubWF0Y2hlZEVkZ2VzPWcuc2l6ZSx0aGlzLmRhdGE9eTtmdW5jdGlvbiBiKHgpe3JldHVybiByYS5mcm9tQnVmZmVyQXR0cmlidXRlKHUseCksZGwocmEpfWZ1bmN0aW9uIHcoeCl7bGV0IE09IiI7Zm9yKGxldCBBPTAsXz1sLmxlbmd0aDtBPF87QSsrKXtjb25zdCBTPWNbbFtBXV07bGV0IEU7c3dpdGNoKFMuaXRlbVNpemUpe2Nhc2UgMTpFPXdlKFMuZ2V0WCh4KSk7YnJlYWs7Y2FzZSAyOkU9WWQoaDAuZnJvbUJ1ZmZlckF0dHJpYnV0ZShTLHgpKTticmVhaztjYXNlIDM6RT1kbChyYS5mcm9tQnVmZmVyQXR0cmlidXRlKFMseCkpO2JyZWFrO2Nhc2UgNDpFPWpkKHUwLmZyb21CdWZmZXJBdHRyaWJ1dGUoUyx4KSk7YnJlYWt9TSE9PSIiJiYoTSs9InwiKSxNKz1FfXJldHVybiBNfX19Y2xhc3MgSHMgZXh0ZW5kcyBoZntjb25zdHJ1Y3RvciguLi50KXtzdXBlciguLi50KSx0aGlzLmlzQnJ1c2g9ITAsdGhpcy5fcHJldmlvdXNNYXRyaXg9bmV3IHN0LHRoaXMuX3ByZXZpb3VzTWF0cml4LmVsZW1lbnRzLmZpbGwoMCl9bWFya1VwZGF0ZWQoKXt0aGlzLl9wcmV2aW91c01hdHJpeC5jb3B5KHRoaXMubWF0cml4KX1pc0RpcnR5KCl7Y29uc3R7bWF0cml4OnQsX3ByZXZpb3VzTWF0cml4OmV9PXRoaXMsbj10LmVsZW1lbnRzLHM9ZS5lbGVtZW50cztmb3IobGV0IHI9MDtyPDE2O3IrKylpZihuW3JdIT09c1tyXSlyZXR1cm4hMDtyZXR1cm4hMX1wcmVwYXJlR2VvbWV0cnkoKXtjb25zdCB0PXRoaXMuZ2VvbWV0cnksZT10LmF0dHJpYnV0ZXMsbj1wbCgpO2lmKG4pZm9yKGNvbnN0IHMgaW4gZSl7Y29uc3Qgcj1lW3NdO2lmKHIuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSl0aHJvdyBuZXcgRXJyb3IoIkJydXNoOiBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIik7ci5hcnJheT1LZChyLmFycmF5KX1pZih0LmJvdW5kc1RyZWV8fChlMCh0LHt1c2VTaGFyZWRBcnJheUJ1ZmZlcjpufSksdC5ib3VuZHNUcmVlPW5ldyBlYSh0LHttYXhMZWFmVHJpczozLGluZGlyZWN0OiEwLHVzZVNoYXJlZEFycmF5QnVmZmVyOm59KSksdC5oYWxmRWRnZXN8fCh0LmhhbGZFZGdlcz1uZXcgZjAodCkpLCF0Lmdyb3VwSW5kaWNlcyl7Y29uc3Qgcz1uYSh0KSxyPW5ldyBVaW50MTZBcnJheShzKSxvPXQuZ3JvdXBzO2ZvcihsZXQgYT0wLGM9by5sZW5ndGg7YTxjO2ErKyl7Y29uc3R7c3RhcnQ6bCxjb3VudDpofT1vW2FdO2ZvcihsZXQgdT1sLzMsZj0obCtoKS8zO3U8Zjt1Kyspclt1XT1hfXQuZ3JvdXBJbmRpY2VzPXJ9fWRpc3Bvc2VDYWNoZURhdGEoKXtjb25zdHtnZW9tZXRyeTp0fT10aGlzO3QuaGFsZkVkZ2VzPW51bGwsdC5ib3VuZHNUcmVlPW51bGwsdC5ncm91cEluZGljZXM9bnVsbH19Y29uc3QgZDA9MWUtMTQsYWE9bmV3IFQsd2w9bmV3IFQsYmw9bmV3IFQ7ZnVuY3Rpb24gbm4oaSx0PWQwKXthYS5zdWJWZWN0b3JzKGkuYixpLmEpLHdsLnN1YlZlY3RvcnMoaS5jLGkuYSksYmwuc3ViVmVjdG9ycyhpLmIsaS5jKTtjb25zdCBlPWFhLmFuZ2xlVG8od2wpLG49YWEuYW5nbGVUbyhibCkscz1NYXRoLlBJLWUtbjtyZXR1cm4gTWF0aC5hYnMoZSk8dHx8TWF0aC5hYnMobik8dHx8TWF0aC5hYnMocyk8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYik8dHx8aS5hLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dHx8aS5iLmRpc3RhbmNlVG9TcXVhcmVkKGkuYyk8dH1jb25zdCBjYT0xZS0xMCxMaT0xZS0xMCxwMD0xZS0xMCxJZT1uZXcgUXQsZnQ9bmV3IFF0LGtlPW5ldyBULGxhPW5ldyBULE1sPW5ldyBULFdzPW5ldyBNbyxoYT1uZXcgbmU7Y2xhc3MgeTB7Y29uc3RydWN0b3IoKXt0aGlzLl9wb29sPVtdLHRoaXMuX2luZGV4PTB9Z2V0VHJpYW5nbGUoKXtyZXR1cm4gdGhpcy5faW5kZXg+PXRoaXMuX3Bvb2wubGVuZ3RoJiZ0aGlzLl9wb29sLnB1c2gobmV3IGV0KSx0aGlzLl9wb29sW3RoaXMuX2luZGV4KytdfWNsZWFyKCl7dGhpcy5faW5kZXg9MH1yZXNldCgpe3RoaXMuX3Bvb2wubGVuZ3RoPTAsdGhpcy5faW5kZXg9MH19Y2xhc3MgbTB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlUG9vbD1uZXcgeTAsdGhpcy50cmlhbmdsZXM9W10sdGhpcy5ub3JtYWw9bmV3IFQsdGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMX1pbml0aWFsaXplKHQpe3RoaXMucmVzZXQoKTtjb25zdHt0cmlhbmdsZXM6ZSx0cmlhbmdsZVBvb2w6bixub3JtYWw6c309dGhpcztpZihBcnJheS5pc0FycmF5KHQpKWZvcihsZXQgcj0wLG89dC5sZW5ndGg7cjxvO3IrKyl7Y29uc3QgYT10W3JdO2lmKHI9PT0wKWEuZ2V0Tm9ybWFsKHMpO2Vsc2UgaWYoTWF0aC5hYnMoMS1hLmdldE5vcm1hbChrZSkuZG90KHMpKT5jYSl0aHJvdyBuZXcgRXJyb3IoIlRyaWFuZ2xlIFNwbGl0dGVyOiBDYW5ub3QgaW5pdGlhbGl6ZSB3aXRoIHRyaWFuZ2xlcyB0aGF0IGhhdmUgZGlmZmVyZW50IG5vcm1hbHMuIik7Y29uc3QgYz1uLmdldFRyaWFuZ2xlKCk7Yy5jb3B5KGEpLGUucHVzaChjKX1lbHNle3QuZ2V0Tm9ybWFsKHMpO2NvbnN0IHI9bi5nZXRUcmlhbmdsZSgpO3IuY29weSh0KSxlLnB1c2gocil9fXNwbGl0QnlUcmlhbmdsZSh0KXtjb25zdHtub3JtYWw6ZSx0cmlhbmdsZXM6bn09dGhpcztpZih0LmdldE5vcm1hbChsYSkubm9ybWFsaXplKCksTWF0aC5hYnMoMS1NYXRoLmFicyhsYS5kb3QoZSkpKTxwMCl7dGhpcy5jb3BsYW5hclRyaWFuZ2xlVXNlZD0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTthLmNvcGxhbmFyQ291bnQ9MH1jb25zdCBzPVt0LmEsdC5iLHQuY107Zm9yKGxldCByPTA7cjwzO3IrKyl7Y29uc3Qgbz0ocisxKSUzLGE9c1tyXSxjPXNbb107a2Uuc3ViVmVjdG9ycyhjLGEpLm5vcm1hbGl6ZSgpLE1sLmNyb3NzVmVjdG9ycyhsYSxrZSksV3Muc2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQoTWwsYSksdGhpcy5zcGxpdEJ5UGxhbmUoV3MsdCl9fWVsc2UgdC5nZXRQbGFuZShXcyksdGhpcy5zcGxpdEJ5UGxhbmUoV3MsdCl9c3BsaXRCeVBsYW5lKHQsZSl7Y29uc3R7dHJpYW5nbGVzOm4sdHJpYW5nbGVQb29sOnN9PXRoaXM7aGEuY29weShlKSxoYS5uZWVkc1VwZGF0ZT0hMDtmb3IobGV0IHI9MCxvPW4ubGVuZ3RoO3I8bztyKyspe2NvbnN0IGE9bltyXTtpZighaGEuaW50ZXJzZWN0c1RyaWFuZ2xlKGEsSWUsITApKWNvbnRpbnVlO2NvbnN0e2E6YyxiOmwsYzpofT1hO2xldCB1PTAsZj0tMSxkPSExLHA9W10seT1bXTtjb25zdCBtPVtjLGwsaF07Zm9yKGxldCBnPTA7ZzwzO2crKyl7Y29uc3QgYj0oZysxKSUzO0llLnN0YXJ0LmNvcHkobVtnXSksSWUuZW5kLmNvcHkobVtiXSk7Y29uc3Qgdz10LmRpc3RhbmNlVG9Qb2ludChJZS5zdGFydCkseD10LmRpc3RhbmNlVG9Qb2ludChJZS5lbmQpO2lmKE1hdGguYWJzKHcpPExpJiZNYXRoLmFicyh4KTxMaSl7ZD0hMDticmVha31pZih3PjA/cC5wdXNoKGcpOnkucHVzaChnKSxNYXRoLmFicyh3KTxMaSljb250aW51ZTtsZXQgTT0hIXQuaW50ZXJzZWN0TGluZShJZSxrZSk7IU0mJk1hdGguYWJzKHgpPExpJiYoa2UuY29weShJZS5lbmQpLE09ITApLE0mJiEoa2UuZGlzdGFuY2VUbyhJZS5zdGFydCk8Y2EpJiYoa2UuZGlzdGFuY2VUbyhJZS5lbmQpPGNhJiYoZj1nKSx1PT09MD9mdC5zdGFydC5jb3B5KGtlKTpmdC5lbmQuY29weShrZSksdSsrKX1pZighZCYmdT09PTImJmZ0LmRpc3RhbmNlKCk+TGkpaWYoZiE9PS0xKXtmPShmKzEpJTM7bGV0IGc9MDtnPT09ZiYmKGc9KGcrMSklMyk7bGV0IGI9ZysxO2I9PT1mJiYoYj0oYisxKSUzKTtjb25zdCB3PXMuZ2V0VHJpYW5nbGUoKTt3LmEuY29weShtW2JdKSx3LmIuY29weShmdC5lbmQpLHcuYy5jb3B5KGZ0LnN0YXJ0KSxubih3KXx8bi5wdXNoKHcpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LnN0YXJ0KSxhLmMuY29weShmdC5lbmQpLG5uKGEpJiYobi5zcGxpY2UociwxKSxyLS0sby0tKX1lbHNle2NvbnN0IGc9cC5sZW5ndGg+PTI/eVswXTpwWzBdO2lmKGc9PT0wKXtsZXQgQT1mdC5zdGFydDtmdC5zdGFydD1mdC5lbmQsZnQuZW5kPUF9Y29uc3QgYj0oZysxKSUzLHc9KGcrMiklMyx4PXMuZ2V0VHJpYW5nbGUoKSxNPXMuZ2V0VHJpYW5nbGUoKTttW2JdLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LnN0YXJ0KTxtW3ddLmRpc3RhbmNlVG9TcXVhcmVkKGZ0LmVuZCk/KHguYS5jb3B5KG1bYl0pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LnN0YXJ0KSk6KHguYS5jb3B5KG1bd10pLHguYi5jb3B5KGZ0LnN0YXJ0KSx4LmMuY29weShmdC5lbmQpLE0uYS5jb3B5KG1bYl0pLE0uYi5jb3B5KG1bd10pLE0uYy5jb3B5KGZ0LmVuZCkpLGEuYS5jb3B5KG1bZ10pLGEuYi5jb3B5KGZ0LmVuZCksYS5jLmNvcHkoZnQuc3RhcnQpLG5uKHgpfHxuLnB1c2goeCksbm4oTSl8fG4ucHVzaChNKSxubihhKSYmKG4uc3BsaWNlKHIsMSksci0tLG8tLSl9ZWxzZSB1PT09MyYmY29uc29sZS53YXJuKCJUcmlhbmdsZUNsaXBwZXI6IENvcGxhbmFyIGNsaXAgbm90IGhhbmRsZWQiKX19cmVzZXQoKXt0aGlzLnRyaWFuZ2xlcy5sZW5ndGg9MCx0aGlzLnRyaWFuZ2xlUG9vbC5jbGVhcigpLHRoaXMuY29wbGFuYXJUcmlhbmdsZVVzZWQ9ITF9fWZ1bmN0aW9uIGcwKGkpe3JldHVybiBpPX5+aSxpKzQtaSU0fWNsYXNzIEFse2NvbnN0cnVjdG9yKHQsZT01MDApe3RoaXMuZXhwYW5zaW9uRmFjdG9yPTEuNSx0aGlzLnR5cGU9dCx0aGlzLmxlbmd0aD0wLHRoaXMuYXJyYXk9bnVsbCx0aGlzLnNldFNpemUoZSl9c2V0VHlwZSh0KXtpZih0aGlzLmxlbmd0aCE9PTApdGhyb3cgbmV3IEVycm9yKCJUeXBlQmFja2VkQXJyYXk6IENhbm5vdCBjaGFuZ2UgdGhlIHR5cGUgd2hpbGUgdGhlcmUgaXMgdXNlZCBkYXRhIGluIHRoZSBidWZmZXIuIik7Y29uc3QgZT10aGlzLmFycmF5LmJ1ZmZlcjt0aGlzLmFycmF5PW5ldyB0KGUpLHRoaXMudHlwZT10fXNldFNpemUodCl7aWYodGhpcy5hcnJheSYmdD09PXRoaXMuYXJyYXkubGVuZ3RoKXJldHVybjtjb25zdCBlPXRoaXMudHlwZSxuPXBsKCk/U2hhcmVkQXJyYXlCdWZmZXI6QXJyYXlCdWZmZXIscz1uZXcgZShuZXcgbihnMCh0KmUuQllURVNfUEVSX0VMRU1FTlQpKSk7dGhpcy5hcnJheSYmcy5zZXQodGhpcy5hcnJheSwwKSx0aGlzLmFycmF5PXN9ZXhwYW5kKCl7Y29uc3R7YXJyYXk6dCxleHBhbnNpb25GYWN0b3I6ZX09dGhpczt0aGlzLnNldFNpemUodC5sZW5ndGgqZSl9cHVzaCguLi50KXtsZXR7YXJyYXk6ZSxsZW5ndGg6bn09dGhpcztuK3QubGVuZ3RoPmUubGVuZ3RoJiYodGhpcy5leHBhbmQoKSxlPXRoaXMuYXJyYXkpO2ZvcihsZXQgcz0wLHI9dC5sZW5ndGg7czxyO3MrKyllW24rc109dFtzXTt0aGlzLmxlbmd0aCs9dC5sZW5ndGh9Y2xlYXIoKXt0aGlzLmxlbmd0aD0wfX1jbGFzcyB4MHtjb25zdHJ1Y3Rvcigpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVt7fV0sdGhpcy5ncm91cENvdW50PTB9Z2V0VHlwZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0udHlwZX1nZXRJdGVtU2l6ZSh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0uaXRlbVNpemV9Z2V0Tm9ybWFsaXplZCh0KXtyZXR1cm4gdGhpcy5ncm91cEF0dHJpYnV0ZXNbMF1bdF0ubm9ybWFsaXplZH1nZXRDb3VudCh0KXtpZih0aGlzLmdyb3VwQ291bnQ8PXQpcmV0dXJuIDA7Y29uc3QgZT10aGlzLmdldEdyb3VwQXR0ckFycmF5KCJwb3NpdGlvbiIsdCk7cmV0dXJuIGUubGVuZ3RoL2UuaXRlbVNpemV9Z2V0VG90YWxMZW5ndGgodCl7Y29uc3R7Z3JvdXBDb3VudDplLGdyb3VwQXR0cmlidXRlczpufT10aGlzO2xldCBzPTA7Zm9yKGxldCByPTA7cjxlO3IrKyl7Y29uc3Qgbz1uW3JdO3MrPW9bdF0ubGVuZ3RofXJldHVybiBzfWdldEdyb3VwQXR0clNldCh0PTApe2NvbnN0e2dyb3VwQXR0cmlidXRlczplfT10aGlzO2lmKGVbdF0pcmV0dXJuIHRoaXMuZ3JvdXBDb3VudD1NYXRoLm1heCh0aGlzLmdyb3VwQ291bnQsdCsxKSxlW3RdO2NvbnN0IG49ZVswXTtmb3IodGhpcy5ncm91cENvdW50PU1hdGgubWF4KHRoaXMuZ3JvdXBDb3VudCx0KzEpO3Q+PWUubGVuZ3RoOyl7Y29uc3Qgcz17fTtlLnB1c2gocyk7Zm9yKGNvbnN0IHIgaW4gbil7Y29uc3Qgbz1uW3JdLGE9bmV3IEFsKG8udHlwZSk7YS5pdGVtU2l6ZT1vLml0ZW1TaXplLGEubm9ybWFsaXplZD1vLm5vcm1hbGl6ZWQsc1tyXT1hfX1yZXR1cm4gZVt0XX1nZXRHcm91cEF0dHJBcnJheSh0LGU9MCl7Y29uc3R7Z3JvdXBBdHRyaWJ1dGVzOm59PXRoaXM7aWYoIW5bMF1bdF0pdGhyb3cgbmV3IEVycm9yKGBUeXBlZEF0dHJpYnV0ZURhdGE6IEF0dHJpYnV0ZSB3aXRoICIke3R9IiBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRgKTtyZXR1cm4gdGhpcy5nZXRHcm91cEF0dHJTZXQoZSlbdF19aW5pdGlhbGl6ZUFycmF5KHQsZSxuLHMpe2NvbnN0e2dyb3VwQXR0cmlidXRlczpyfT10aGlzLGE9clswXVt0XTtpZihhKXtpZihhLnR5cGUhPT1lKWZvcihsZXQgYz0wLGw9ci5sZW5ndGg7YzxsO2MrKyl7Y29uc3QgaD1yW2NdW3RdO2guc2V0VHlwZShlKSxoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXN9fWVsc2UgZm9yKGxldCBjPTAsbD1yLmxlbmd0aDtjPGw7YysrKXtjb25zdCBoPW5ldyBBbChlKTtoLml0ZW1TaXplPW4saC5ub3JtYWxpemVkPXMscltjXVt0XT1ofX1jbGVhcigpe3RoaXMuZ3JvdXBDb3VudD0wO2NvbnN0e2dyb3VwQXR0cmlidXRlczp0fT10aGlzO3QuZm9yRWFjaChlPT57Zm9yKGNvbnN0IG4gaW4gZSllW25dLmNsZWFyKCl9KX1kZWxldGUodCl7dGhpcy5ncm91cEF0dHJpYnV0ZXMuZm9yRWFjaChlPT57ZGVsZXRlIGVbdF19KX1yZXNldCgpe3RoaXMuZ3JvdXBBdHRyaWJ1dGVzPVtdLHRoaXMuZ3JvdXBDb3VudD0wfX1jbGFzcyBfbHtjb25zdHJ1Y3Rvcigpe3RoaXMuaW50ZXJzZWN0aW9uU2V0PXt9LHRoaXMuaWRzPVtdfWFkZCh0LGUpe2NvbnN0e2ludGVyc2VjdGlvblNldDpuLGlkczpzfT10aGlzO25bdF18fChuW3RdPVtdLHMucHVzaCh0KSksblt0XS5wdXNoKGUpfX1jb25zdCB3MD0wLGIwPTEsTTA9MixTbD0zLEEwPTQsdmw9NSx6bD02LHNlPW5ldyBhbyxUbD1uZXcgc3QsVHQ9bmV3IGV0LE5lPW5ldyBULEVsPW5ldyBZdCxQbD1uZXcgWXQsQ2w9bmV3IFl0LHVhPW5ldyBZdCxHcz1uZXcgWXQsWnM9bmV3IFl0LEJsPW5ldyBRdCxmYT1uZXcgVCxkYT0xZS04LF8wPTFlLTE1LGduPS0xLHhuPTEsWHM9LTIsSnM9MixPaT0wLHduPTEscGE9MixTMD0xZS0xNDtsZXQgWXM9bnVsbDtmdW5jdGlvbiBGbChpKXtZcz1pfWZ1bmN0aW9uIElsKGksdCl7aS5nZXRNaWRwb2ludChzZS5vcmlnaW4pLGkuZ2V0Tm9ybWFsKHNlLmRpcmVjdGlvbik7Y29uc3QgZT10LnJheWNhc3RGaXJzdChzZSwyKTtyZXR1cm4hIShlJiZzZS5kaXJlY3Rpb24uZG90KGUuZmFjZS5ub3JtYWwpPjApP2duOnhufWZ1bmN0aW9uIHYwKGksdCl7ZnVuY3Rpb24gZSgpe3JldHVybiBNYXRoLnJhbmRvbSgpLS41fWkuZ2V0Tm9ybWFsKGZhKSxzZS5kaXJlY3Rpb24uY29weShmYSksaS5nZXRNaWRwb2ludChzZS5vcmlnaW4pO2NvbnN0IG49MztsZXQgcz0wLHI9MS8wO2ZvcihsZXQgbz0wO288bjtvKyspe3NlLmRpcmVjdGlvbi54Kz1lKCkqZGEsc2UuZGlyZWN0aW9uLnkrPWUoKSpkYSxzZS5kaXJlY3Rpb24ueis9ZSgpKmRhLHNlLmRpcmVjdGlvbi5tdWx0aXBseVNjYWxhcigtMSk7Y29uc3QgYT10LnJheWNhc3RGaXJzdChzZSwyKTtpZighIShhJiZzZS5kaXJlY3Rpb24uZG90KGEuZmFjZS5ub3JtYWwpPjApJiZzKyssYSE9PW51bGwmJihyPU1hdGgubWluKHIsYS5kaXN0YW5jZSkpLHI8PV8wKXJldHVybiBhLmZhY2Uubm9ybWFsLmRvdChmYSk+MD9KczpYcztpZihzL24+LjV8fChvLXMrMSkvbj4uNSlicmVha31yZXR1cm4gcy9uPi41P2duOnhufWZ1bmN0aW9uIHowKGksdCl7Y29uc3QgZT1uZXcgX2wsbj1uZXcgX2w7cmV0dXJuIFRsLmNvcHkoaS5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkodC5tYXRyaXhXb3JsZCksaS5nZW9tZXRyeS5ib3VuZHNUcmVlLmJ2aGNhc3QodC5nZW9tZXRyeS5ib3VuZHNUcmVlLFRsLHtpbnRlcnNlY3RzVHJpYW5nbGVzKHMscixvLGEpe2lmKCFubihzKSYmIW5uKHIpKXtsZXQgYz1zLmludGVyc2VjdHNUcmlhbmdsZShyLEJsLCEwKTtpZighYyl7Y29uc3QgbD1zLnBsYW5lLGg9ci5wbGFuZSx1PWwubm9ybWFsLGY9aC5ub3JtYWw7dS5kb3QoZik9PT0xJiZNYXRoLmFicyhsLmNvbnN0YW50LWguY29uc3RhbnQpPFMwJiYoYz0hMCl9aWYoYyl7bGV0IGw9aS5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KG8pLGg9dC5nZW9tZXRyeS5ib3VuZHNUcmVlLnJlc29sdmVUcmlhbmdsZUluZGV4KGEpO2UuYWRkKGwsaCksbi5hZGQoaCxsKSxZcyYmKFlzLmFkZEVkZ2UoQmwpLFlzLmFkZEludGVyc2VjdGluZ1RyaWFuZ2xlcyhvLHMsYSxyKSl9fXJldHVybiExfX0pLHthSW50ZXJzZWN0aW9uczplLGJJbnRlcnNlY3Rpb25zOm59fWZ1bmN0aW9uIFQwKGksdCxlLG4scyxyLG89ITEpe2NvbnN0IGE9ZS5hdHRyaWJ1dGVzLGM9ZS5pbmRleCxsPWkqMyxoPWMuZ2V0WChsKzApLHU9Yy5nZXRYKGwrMSksZj1jLmdldFgobCsyKTtmb3IoY29uc3QgZCBpbiByKXtjb25zdCBwPWFbZF0seT1yW2RdO2lmKCEoZCBpbiBhKSl0aHJvdyBuZXcgRXJyb3IoYENTRyBPcGVyYXRpb25zOiBBdHRyaWJ1dGUgJHtkfSBub3QgYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IG09cC5pdGVtU2l6ZTtkPT09InBvc2l0aW9uIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlNYXRyaXg0KG4pLFR0LmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLHUpLmFwcGx5TWF0cml4NChuKSxUdC5jLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxmKS5hcHBseU1hdHJpeDQobikseWEoVHQuYSxUdC5iLFR0LmMsdCwzLHksbykpOmQ9PT0ibm9ybWFsIj8oVHQuYS5mcm9tQnVmZmVyQXR0cmlidXRlKHAsaCkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYi5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSkuYXBwbHlOb3JtYWxNYXRyaXgocyksVHQuYy5mcm9tQnVmZmVyQXR0cmlidXRlKHAsZikuYXBwbHlOb3JtYWxNYXRyaXgocyksbyYmKFR0LmEubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmIubXVsdGlwbHlTY2FsYXIoLTEpLFR0LmMubXVsdGlwbHlTY2FsYXIoLTEpKSx5YShUdC5hLFR0LmIsVHQuYyx0LDMseSxvLCEwKSk6KEVsLmZyb21CdWZmZXJBdHRyaWJ1dGUocCxoKSxQbC5mcm9tQnVmZmVyQXR0cmlidXRlKHAsdSksQ2wuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLGYpLHlhKEVsLFBsLENsLHQsbSx5LG8pKX19ZnVuY3Rpb24gRTAoaSx0LGUsbixzLHIsbyxhPSExKXttYShpLG4scyxyLG8sYSksbWEoYT9lOnQsbixzLHIsbyxhKSxtYShhP3Q6ZSxuLHMscixvLGEpfWZ1bmN0aW9uIGtsKGksdCxlPSExKXtzd2l0Y2goaSl7Y2FzZSB3MDppZih0PT09eG58fHQ9PT1KcyYmIWUpcmV0dXJuIHduO2JyZWFrO2Nhc2UgYjA6aWYoZSl7aWYodD09PWduKXJldHVybiBPaX1lbHNlIGlmKHQ9PT14bnx8dD09PVhzKXJldHVybiB3bjticmVhaztjYXNlIE0wOmlmKGUpe2lmKHQ9PT14bnx8dD09PVhzKXJldHVybiB3bn1lbHNlIGlmKHQ9PT1nbilyZXR1cm4gT2k7YnJlYWs7Y2FzZSBBMDppZih0PT09Z24pcmV0dXJuIE9pO2lmKHQ9PT14bilyZXR1cm4gd247YnJlYWs7Y2FzZSBTbDppZih0PT09Z258fHQ9PT1KcyYmIWUpcmV0dXJuIHduO2JyZWFrO2Nhc2Ugdmw6aWYoIWUmJih0PT09eG58fHQ9PT1YcykpcmV0dXJuIHduO2JyZWFrO2Nhc2Ugemw6aWYoIWUmJih0PT09Z258fHQ9PT1KcykpcmV0dXJuIHduO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgQ1NHIG9wZXJhdGlvbiBlbnVtICIke2l9Ii5gKX1yZXR1cm4gcGF9ZnVuY3Rpb24geWEoaSx0LGUsbixzLHIsbz0hMSxhPSExKXtjb25zdCBjPWw9PntyLnB1c2gobC54KSxzPjEmJnIucHVzaChsLnkpLHM+MiYmci5wdXNoKGwueikscz4zJiZyLnB1c2gobC53KX07dWEuc2V0KDAsMCwwLDApLmFkZFNjYWxlZFZlY3RvcihpLG4uYS54KS5hZGRTY2FsZWRWZWN0b3IodCxuLmEueSkuYWRkU2NhbGVkVmVjdG9yKGUsbi5hLnopLEdzLnNldCgwLDAsMCwwKS5hZGRTY2FsZWRWZWN0b3IoaSxuLmIueCkuYWRkU2NhbGVkVmVjdG9yKHQsbi5iLnkpLmFkZFNjYWxlZFZlY3RvcihlLG4uYi56KSxacy5zZXQoMCwwLDAsMCkuYWRkU2NhbGVkVmVjdG9yKGksbi5jLngpLmFkZFNjYWxlZFZlY3Rvcih0LG4uYy55KS5hZGRTY2FsZWRWZWN0b3IoZSxuLmMueiksYSYmKHVhLm5vcm1hbGl6ZSgpLEdzLm5vcm1hbGl6ZSgpLFpzLm5vcm1hbGl6ZSgpKSxjKHVhKSxvPyhjKFpzKSxjKEdzKSk6KGMoR3MpLGMoWnMpKX1mdW5jdGlvbiBtYShpLHQsZSxuLHMscj0hMSl7Zm9yKGNvbnN0IG8gaW4gcyl7Y29uc3QgYT10W29dLGM9c1tvXTtpZighKG8gaW4gdCkpdGhyb3cgbmV3IEVycm9yKGBDU0cgT3BlcmF0aW9uczogQXR0cmlidXRlICR7b30gbm8gYXZhaWxhYmxlIG9uIGdlb21ldHJ5LmApO2NvbnN0IGw9YS5pdGVtU2l6ZTtvPT09InBvc2l0aW9uIj8oTmUuZnJvbUJ1ZmZlckF0dHJpYnV0ZShhLGkpLmFwcGx5TWF0cml4NChlKSxjLnB1c2goTmUueCxOZS55LE5lLnopKTpvPT09Im5vcm1hbCI/KE5lLmZyb21CdWZmZXJBdHRyaWJ1dGUoYSxpKS5hcHBseU5vcm1hbE1hdHJpeChuKSxyJiZOZS5tdWx0aXBseVNjYWxhcigtMSksYy5wdXNoKE5lLngsTmUueSxOZS56KSk6KGMucHVzaChhLmdldFgoaSkpLGw+MSYmYy5wdXNoKGEuZ2V0WShpKSksbD4yJiZjLnB1c2goYS5nZXRaKGkpKSxsPjMmJmMucHVzaChhLmdldFcoaSkpKX19Y2xhc3MgUDB7Y29uc3RydWN0b3IodCl7dGhpcy50cmlhbmdsZT1uZXcgZXQoKS5jb3B5KHQpLHRoaXMuaW50ZXJzZWN0cz17fX1hZGRUcmlhbmdsZSh0LGUpe3RoaXMuaW50ZXJzZWN0c1t0XT1uZXcgZXQoKS5jb3B5KGUpfWdldEludGVyc2VjdEFycmF5KCl7Y29uc3QgdD1bXSx7aW50ZXJzZWN0czplfT10aGlzO2Zvcihjb25zdCBuIGluIGUpdC5wdXNoKGVbbl0pO3JldHVybiB0fX1jbGFzcyBObHtjb25zdHJ1Y3Rvcigpe3RoaXMuZGF0YT17fX1hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKXtjb25zdHtkYXRhOnJ9PXRoaXM7clt0XXx8KHJbdF09bmV3IFAwKGUpKSxyW3RdLmFkZFRyaWFuZ2xlKG4scyl9Z2V0VHJpYW5nbGVzQXNBcnJheSh0PW51bGwpe2NvbnN0e2RhdGE6ZX09dGhpcyxuPVtdO2lmKHQhPT1udWxsKXQgaW4gZSYmbi5wdXNoKGVbdF0udHJpYW5nbGUpO2Vsc2UgZm9yKGNvbnN0IHMgaW4gZSluLnB1c2goZVtzXS50cmlhbmdsZSk7cmV0dXJuIG59Z2V0VHJpYW5nbGVJbmRpY2VzKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubWFwKHQ9PnBhcnNlSW50KHQpKX1nZXRJbnRlcnNlY3Rpb25JbmRpY2VzKHQpe2NvbnN0e2RhdGE6ZX09dGhpcztyZXR1cm4gZVt0XT9PYmplY3Qua2V5cyhlW3RdLmludGVyc2VjdHMpLm1hcChuPT5wYXJzZUludChuKSk6W119Z2V0SW50ZXJzZWN0aW9uc0FzQXJyYXkodD1udWxsLGU9bnVsbCl7Y29uc3R7ZGF0YTpufT10aGlzLHM9bmV3IFNldCxyPVtdLG89YT0+e2lmKG5bYV0paWYoZSE9PW51bGwpblthXS5pbnRlcnNlY3RzW2VdJiZyLnB1c2goblthXS5pbnRlcnNlY3RzW2VdKTtlbHNle2NvbnN0IGM9blthXS5pbnRlcnNlY3RzO2Zvcihjb25zdCBsIGluIGMpcy5oYXMobCl8fChzLmFkZChsKSxyLnB1c2goY1tsXSkpfX07aWYodCE9PW51bGwpbyh0KTtlbHNlIGZvcihjb25zdCBhIGluIG4pbyhhKTtyZXR1cm4gcn1yZXNldCgpe3RoaXMuZGF0YT17fX19Y2xhc3MgQzB7Y29uc3RydWN0b3IoKXt0aGlzLmVuYWJsZWQ9ITEsdGhpcy50cmlhbmdsZUludGVyc2VjdHNBPW5ldyBObCx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0I9bmV3IE5sLHRoaXMuaW50ZXJzZWN0aW9uRWRnZXM9W119YWRkSW50ZXJzZWN0aW5nVHJpYW5nbGVzKHQsZSxuLHMpe2NvbnN0e3RyaWFuZ2xlSW50ZXJzZWN0c0E6cix0cmlhbmdsZUludGVyc2VjdHNCOm99PXRoaXM7ci5hZGRUcmlhbmdsZUludGVyc2VjdGlvbih0LGUsbixzKSxvLmFkZFRyaWFuZ2xlSW50ZXJzZWN0aW9uKG4scyx0LGUpfWFkZEVkZ2UodCl7dGhpcy5pbnRlcnNlY3Rpb25FZGdlcy5wdXNoKHQuY2xvbmUoKSl9cmVzZXQoKXt0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0EucmVzZXQoKSx0aGlzLnRyaWFuZ2xlSW50ZXJzZWN0c0IucmVzZXQoKSx0aGlzLmludGVyc2VjdGlvbkVkZ2VzPVtdfWluaXQoKXt0aGlzLmVuYWJsZWQmJih0aGlzLnJlc2V0KCksRmwodGhpcykpfWNvbXBsZXRlKCl7dGhpcy5lbmFibGVkJiZGbChudWxsKX19Y29uc3Qgc249bmV3IHN0LGpzPW5ldyBnZSxibj1uZXcgZXQsUXM9bmV3IGV0LHJuPW5ldyBldCxLcz1uZXcgZXQsZGU9W10sTW49W107ZnVuY3Rpb24gQjAoaSl7Zm9yKGNvbnN0IHQgb2YgaSlyZXR1cm4gdH1mdW5jdGlvbiBGMChpLHQsZSxuLHMscj17fSl7Y29uc3R7dXNlR3JvdXBzOm89ITB9PXIse2FJbnRlcnNlY3Rpb25zOmEsYkludGVyc2VjdGlvbnM6Y309ejAoaSx0KSxsPVtdO2xldCBoPW51bGwsdTtyZXR1cm4gdT1vPzA6LTEsUmwoaSx0LGEsZSwhMSxuLHMsdSksTGwoaSx0LGEsZSwhMSxzLHUpLGUuZmluZEluZGV4KGQ9PmQhPT16bCYmZCE9PXZsKSE9PS0xJiYodT1vP2kuZ2VvbWV0cnkuZ3JvdXBzLmxlbmd0aHx8MTotMSxSbCh0LGksYyxlLCEwLG4scyx1KSxMbCh0LGksYyxlLCEwLHMsdSkpLGRlLmxlbmd0aD0wLE1uLmxlbmd0aD0wLHtncm91cHM6bCxtYXRlcmlhbHM6aH19ZnVuY3Rpb24gUmwoaSx0LGUsbixzLHIsbyxhPTApe2NvbnN0IGM9aS5tYXRyaXhXb3JsZC5kZXRlcm1pbmFudCgpPDA7c24uY29weSh0Lm1hdHJpeFdvcmxkKS5pbnZlcnQoKS5tdWx0aXBseShpLm1hdHJpeFdvcmxkKSxqcy5nZXROb3JtYWxNYXRyaXgoaS5tYXRyaXhXb3JsZCkubXVsdGlwbHlTY2FsYXIoYz8tMToxKTtjb25zdCBsPWkuZ2VvbWV0cnkuZ3JvdXBJbmRpY2VzLGg9aS5nZW9tZXRyeS5pbmRleCx1PWkuZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbixmPXQuZ2VvbWV0cnkuYm91bmRzVHJlZSxkPXQuZ2VvbWV0cnkuaW5kZXgscD10Lmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb24seT1lLmlkcyxtPWUuaW50ZXJzZWN0aW9uU2V0O2ZvcihsZXQgZz0wLGI9eS5sZW5ndGg7ZzxiO2crKyl7Y29uc3Qgdz15W2ddLHg9YT09PS0xPzA6bFt3XSthLE09Myp3LEE9aC5nZXRYKE0rMCksXz1oLmdldFgoTSsxKSxTPWguZ2V0WChNKzIpO2JuLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSh1LEEpLmFwcGx5TWF0cml4NChzbiksYm4uYi5mcm9tQnVmZmVyQXR0cmlidXRlKHUsXykuYXBwbHlNYXRyaXg0KHNuKSxibi5jLmZyb21CdWZmZXJBdHRyaWJ1dGUodSxTKS5hcHBseU1hdHJpeDQoc24pLHIucmVzZXQoKSxyLmluaXRpYWxpemUoYm4pO2NvbnN0IEU9bVt3XTtmb3IobGV0IHY9MCxDPUUubGVuZ3RoO3Y8Qzt2Kyspe2NvbnN0IFA9MypFW3ZdLEY9ZC5nZXRYKFArMCksQj1kLmdldFgoUCsxKSxJPWQuZ2V0WChQKzIpO1FzLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEYpLFFzLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEIpLFFzLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShwLEkpLHIuc3BsaXRCeVRyaWFuZ2xlKFFzKX1jb25zdCB6PXIudHJpYW5nbGVzO2ZvcihsZXQgdj0wLEM9ei5sZW5ndGg7djxDO3YrKyl7Y29uc3QgUD16W3ZdLEY9ci5jb3BsYW5hclRyaWFuZ2xlVXNlZD92MChQLGYpOklsKFAsZik7ZGUubGVuZ3RoPTAsTW4ubGVuZ3RoPTA7Zm9yKGxldCBCPTAsST1uLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPWtsKG5bQl0sRixzKTtrIT09cGEmJihNbi5wdXNoKGspLGRlLnB1c2gob1tCXS5nZXRHcm91cEF0dHJTZXQoeCkpKX1pZihkZS5sZW5ndGghPT0wKXtibi5nZXRCYXJ5Y29vcmQoUC5hLEtzLmEpLGJuLmdldEJhcnljb29yZChQLmIsS3MuYiksYm4uZ2V0QmFyeWNvb3JkKFAuYyxLcy5jKTtmb3IobGV0IEI9MCxJPWRlLmxlbmd0aDtCPEk7QisrKXtjb25zdCBrPWRlW0JdLFY9TW5bQl09PT1PaTtUMCh3LEtzLGkuZ2VvbWV0cnksaS5tYXRyaXhXb3JsZCxqcyxrLGMhPT1WKX19fX1yZXR1cm4geS5sZW5ndGh9ZnVuY3Rpb24gTGwoaSx0LGUsbixzLHIsbz0wKXtjb25zdCBhPWkubWF0cml4V29ybGQuZGV0ZXJtaW5hbnQoKTwwO3NuLmNvcHkodC5tYXRyaXhXb3JsZCkuaW52ZXJ0KCkubXVsdGlwbHkoaS5tYXRyaXhXb3JsZCksanMuZ2V0Tm9ybWFsTWF0cml4KGkubWF0cml4V29ybGQpLm11bHRpcGx5U2NhbGFyKGE/LTE6MSk7Y29uc3QgYz10Lmdlb21ldHJ5LmJvdW5kc1RyZWUsbD1pLmdlb21ldHJ5Lmdyb3VwSW5kaWNlcyxoPWkuZ2VvbWV0cnkuaW5kZXgsdT1pLmdlb21ldHJ5LmF0dHJpYnV0ZXMsZj11LnBvc2l0aW9uLGQ9W10scD1pLmdlb21ldHJ5LmhhbGZFZGdlcyx5PW5ldyBTZXQsbT1uYShpLmdlb21ldHJ5KTtmb3IobGV0IGc9MCxiPW07ZzxiO2crKylnIGluIGUuaW50ZXJzZWN0aW9uU2V0fHx5LmFkZChnKTtmb3IoO3kuc2l6ZT4wOyl7Y29uc3QgZz1CMCh5KTt5LmRlbGV0ZShnKSxkLnB1c2goZyk7Y29uc3QgYj0zKmcsdz1oLmdldFgoYiswKSx4PWguZ2V0WChiKzEpLE09aC5nZXRYKGIrMik7cm4uYS5mcm9tQnVmZmVyQXR0cmlidXRlKGYsdykuYXBwbHlNYXRyaXg0KHNuKSxybi5iLmZyb21CdWZmZXJBdHRyaWJ1dGUoZix4KS5hcHBseU1hdHJpeDQoc24pLHJuLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLE0pLmFwcGx5TWF0cml4NChzbik7Y29uc3QgQT1JbChybixjKTtNbi5sZW5ndGg9MCxkZS5sZW5ndGg9MDtmb3IobGV0IF89MCxTPW4ubGVuZ3RoO188UztfKyspe2NvbnN0IEU9a2wobltfXSxBLHMpO0UhPT1wYSYmKE1uLnB1c2goRSksZGUucHVzaChyW19dKSl9Zm9yKDtkLmxlbmd0aD4wOyl7Y29uc3QgXz1kLnBvcCgpO2ZvcihsZXQgUz0wO1M8MztTKyspe2NvbnN0IEU9cC5nZXRTaWJsaW5nVHJpYW5nbGVJbmRleChfLFMpO0UhPT0tMSYmeS5oYXMoRSkmJihkLnB1c2goRSkseS5kZWxldGUoRSkpfWlmKGRlLmxlbmd0aCE9PTApe2NvbnN0IFM9MypfLEU9aC5nZXRYKFMrMCksej1oLmdldFgoUysxKSx2PWguZ2V0WChTKzIpLEM9bz09PS0xPzA6bFtfXStvO2lmKHJuLmEuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLEUpLHJuLmIuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHopLHJuLmMuZnJvbUJ1ZmZlckF0dHJpYnV0ZShmLHYpLCFubihybikpZm9yKGxldCBQPTAsRj1kZS5sZW5ndGg7UDxGO1ArKyl7Y29uc3QgQj1NbltQXSxJPWRlW1BdLmdldEdyb3VwQXR0clNldChDKSxrPUI9PT1PaTtFMChFLHosdix1LGkubWF0cml4V29ybGQsanMsSSxrIT09YSl9fX19fWZ1bmN0aW9uIEkwKGkpe2ZvcihsZXQgdD0wO3Q8aS5sZW5ndGgtMTt0Kyspe2NvbnN0IGU9aVt0XSxuPWlbdCsxXTtpZihlLm1hdGVyaWFsSW5kZXg9PT1uLm1hdGVyaWFsSW5kZXgpe2NvbnN0IHM9ZS5zdGFydCxyPW4uc3RhcnQrbi5jb3VudDtuLnN0YXJ0PXMsbi5jb3VudD1yLXMsaS5zcGxpY2UodCwxKSx0LS19fX1mdW5jdGlvbiBrMChpLHQsZSxuKXtlLmNsZWFyKCk7Y29uc3Qgcz1pLmF0dHJpYnV0ZXM7Zm9yKGxldCByPTAsbz1uLmxlbmd0aDtyPG87cisrKXtjb25zdCBhPW5bcl0sYz1zW2FdO2UuaW5pdGlhbGl6ZUFycmF5KGEsYy5hcnJheS5jb25zdHJ1Y3RvcixjLml0ZW1TaXplLGMubm9ybWFsaXplZCl9Zm9yKGNvbnN0IHIgaW4gZS5hdHRyaWJ1dGVzKW4uaW5jbHVkZXMocil8fGUuZGVsZXRlKHIpO2Zvcihjb25zdCByIGluIHQuYXR0cmlidXRlcyluLmluY2x1ZGVzKHIpfHwodC5kZWxldGVBdHRyaWJ1dGUociksdC5kaXNwb3NlKCkpfWZ1bmN0aW9uIE4wKGksdCxlKXtsZXQgbj0hMSxzPS0xO2NvbnN0IHI9aS5hdHRyaWJ1dGVzLG89dC5ncm91cEF0dHJpYnV0ZXNbMF07Zm9yKGNvbnN0IGMgaW4gbyl7Y29uc3QgbD10LmdldFRvdGFsTGVuZ3RoKGMpLGg9dC5nZXRUeXBlKGMpLHU9dC5nZXRJdGVtU2l6ZShjKSxmPXQuZ2V0Tm9ybWFsaXplZChjKTtsZXQgZD1yW2NdOyghZHx8ZC5hcnJheS5sZW5ndGg8bCkmJihkPW5ldyB4dChuZXcgaChsKSx1LGYpLGkuc2V0QXR0cmlidXRlKGMsZCksbj0hMCk7bGV0IHA9MDtmb3IobGV0IHk9MCxtPU1hdGgubWluKGUubGVuZ3RoLHQuZ3JvdXBDb3VudCk7eTxtO3krKyl7Y29uc3QgZz1lW3ldLmluZGV4LHthcnJheTpiLHR5cGU6dyxsZW5ndGg6eH09dC5ncm91cEF0dHJpYnV0ZXNbZ11bY10sTT1uZXcgdyhiLmJ1ZmZlciwwLHgpO2QuYXJyYXkuc2V0KE0scCkscCs9TS5sZW5ndGh9ZC5uZWVkc1VwZGF0ZT0hMCxzPWwvZC5pdGVtU2l6ZX1pZihpLmluZGV4KXtjb25zdCBjPWkuaW5kZXguYXJyYXk7aWYoYy5sZW5ndGg8cylpLmluZGV4PW51bGwsbj0hMDtlbHNlIGZvcihsZXQgbD0wLGg9Yy5sZW5ndGg7bDxoO2wrKyljW2xdPWx9bGV0IGE9MDtpLmNsZWFyR3JvdXBzKCk7Zm9yKGxldCBjPTAsbD1NYXRoLm1pbihlLmxlbmd0aCx0Lmdyb3VwQ291bnQpO2M8bDtjKyspe2NvbnN0e2luZGV4OmgsbWF0ZXJpYWxJbmRleDp1fT1lW2NdLGY9dC5nZXRDb3VudChoKTtmIT09MCYmKGkuYWRkR3JvdXAoYSxmLHUpLGErPWYpfWkuc2V0RHJhd1JhbmdlKDAscyksaS5ib3VuZHNUcmVlPW51bGwsbiYmaS5kaXNwb3NlKCl9ZnVuY3Rpb24gT2woaSx0KXtsZXQgZT10O3JldHVybiBBcnJheS5pc0FycmF5KHQpfHwoZT1bXSxpLmZvckVhY2gobj0+e2Vbbi5tYXRlcmlhbEluZGV4XT10fSkpLGV9Y2xhc3MgUjB7Y29uc3RydWN0b3IoKXt0aGlzLnRyaWFuZ2xlU3BsaXR0ZXI9bmV3IG0wLHRoaXMuYXR0cmlidXRlRGF0YT1bXSx0aGlzLmF0dHJpYnV0ZXM9WyJwb3NpdGlvbiIsInV2Iiwibm9ybWFsIl0sdGhpcy51c2VHcm91cHM9ITAsdGhpcy5jb25zb2xpZGF0ZUdyb3Vwcz0hMCx0aGlzLmRlYnVnPW5ldyBDMH1nZXRHcm91cFJhbmdlcyh0KXtyZXR1cm4hdGhpcy51c2VHcm91cHN8fHQuZ3JvdXBzLmxlbmd0aD09PTA/W3tzdGFydDowLGNvdW50OjEvMCxtYXRlcmlhbEluZGV4OjB9XTp0Lmdyb3Vwcy5tYXAoZT0+RnQoe30sZSkpfWV2YWx1YXRlKHQsZSxuLHM9bmV3IEhzKXtsZXQgcj0hMDtpZihBcnJheS5pc0FycmF5KG4pfHwobj1bbl0pLEFycmF5LmlzQXJyYXkocyl8fChzPVtzXSxyPSExKSxzLmxlbmd0aCE9PW4ubGVuZ3RoKXRocm93IG5ldyBFcnJvcigiRXZhbHVhdG9yOiBvcGVyYXRpb25zIGFuZCB0YXJnZXQgYXJyYXkgcGFzc2VkIGFzIGRpZmZlcmVudCBzaXplcy4iKTt0LnByZXBhcmVHZW9tZXRyeSgpLGUucHJlcGFyZUdlb21ldHJ5KCk7Y29uc3R7dHJpYW5nbGVTcGxpdHRlcjpvLGF0dHJpYnV0ZURhdGE6YSxhdHRyaWJ1dGVzOmMsdXNlR3JvdXBzOmwsY29uc29saWRhdGVHcm91cHM6aCxkZWJ1Zzp1fT10aGlzO2Zvcig7YS5sZW5ndGg8cy5sZW5ndGg7KWEucHVzaChuZXcgeDApO3MuZm9yRWFjaCgoZyxiKT0+e2swKHQuZ2VvbWV0cnksZy5nZW9tZXRyeSxhW2JdLGMpfSksdS5pbml0KCksRjAodCxlLG4sbyxhLHt1c2VHcm91cHM6bH0pLHUuY29tcGxldGUoKTtjb25zdCBmPXRoaXMuZ2V0R3JvdXBSYW5nZXModC5nZW9tZXRyeSksZD1PbChmLHQubWF0ZXJpYWwpLHA9dGhpcy5nZXRHcm91cFJhbmdlcyhlLmdlb21ldHJ5KSx5PU9sKHAsZS5tYXRlcmlhbCk7cC5mb3JFYWNoKGc9PmcubWF0ZXJpYWxJbmRleCs9ZC5sZW5ndGgpO2xldCBtPVsuLi5mLC4uLnBdLm1hcCgoZyxiKT0+R2UoRnQoe30sZykse2luZGV4OmJ9KSk7aWYobCl7Y29uc3QgZz1bLi4uZCwuLi55XTtoJiYobT1tLm1hcCh3PT57Y29uc3QgeD1nW3cubWF0ZXJpYWxJbmRleF07cmV0dXJuIHcubWF0ZXJpYWxJbmRleD1nLmluZGV4T2YoeCksd30pLnNvcnQoKHcseCk9PncubWF0ZXJpYWxJbmRleC14Lm1hdGVyaWFsSW5kZXgpKTtjb25zdCBiPVtdO2ZvcihsZXQgdz0wLHg9Zy5sZW5ndGg7dzx4O3crKyl7bGV0IE09ITE7Zm9yKGxldCBBPTAsXz1tLmxlbmd0aDtBPF87QSsrKXtjb25zdCBTPW1bQV07Uy5tYXRlcmlhbEluZGV4PT09dyYmKE09ITAsUy5tYXRlcmlhbEluZGV4PWIubGVuZ3RoKX1NJiZiLnB1c2goZ1t3XSl9cy5mb3JFYWNoKHc9Pnt3Lm1hdGVyaWFsPWJ9KX1lbHNlIG09W3tzdGFydDowLGNvdW50OjEvMCxpbmRleDowLG1hdGVyaWFsSW5kZXg6MH1dLHMuZm9yRWFjaChnPT57Zy5tYXRlcmlhbD1kWzBdfSk7cmV0dXJuIHMuZm9yRWFjaCgoZyxiKT0+e2NvbnN0IHc9Zy5nZW9tZXRyeTtOMCh3LGFbYl0sbSksaCYmSTAody5ncm91cHMpfSkscj9zOnNbMF19ZXZhbHVhdGVIaWVyYXJjaHkodCxlPW5ldyBIcyl7dC51cGRhdGVNYXRyaXhXb3JsZCghMCk7Y29uc3Qgbj0ocixvKT0+e2NvbnN0IGE9ci5jaGlsZHJlbjtmb3IobGV0IGM9MCxsPWEubGVuZ3RoO2M8bDtjKyspe2NvbnN0IGg9YVtjXTtoLmlzT3BlcmF0aW9uR3JvdXA/bihoLG8pOm8oaCl9fSxzPXI9Pntjb25zdCBvPXIuY2hpbGRyZW47bGV0IGE9ITE7Zm9yKGxldCBsPTAsaD1vLmxlbmd0aDtsPGg7bCsrKXtjb25zdCB1PW9bbF07YT1zKHUpfHxhfWNvbnN0IGM9ci5pc0RpcnR5KCk7aWYoYyYmci5tYXJrVXBkYXRlZCgpLGEmJiFyLmlzT3BlcmF0aW9uR3JvdXApe2xldCBsO3JldHVybiBuKHIsaD0+e2w/bD10aGlzLmV2YWx1YXRlKGwsaCxoLm9wZXJhdGlvbik6bD10aGlzLmV2YWx1YXRlKHIsaCxoLm9wZXJhdGlvbil9KSxyLl9jYWNoZWRHZW9tZXRyeT1sLmdlb21ldHJ5LHIuX2NhY2hlZE1hdGVyaWFscz1sLm1hdGVyaWFsLCEwfWVsc2UgcmV0dXJuIGF8fGN9O3JldHVybiBzKHQpLGUuZ2VvbWV0cnk9dC5fY2FjaGVkR2VvbWV0cnksZS5tYXRlcmlhbD10Ll9jYWNoZWRNYXRlcmlhbHMsZX1yZXNldCgpe3RoaXMudHJpYW5nbGVTcGxpdHRlci5yZXNldCgpfX1mdW5jdGlvbiBEbChpKXtsZXQgdCxlLG4scz0tMSxyPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZih0PT09dm9pZCAwJiYodD1oLmFycmF5LmNvbnN0cnVjdG9yKSx0IT09aC5hcnJheS5jb25zdHJ1Y3RvcilyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmFycmF5IG11c3QgYmUgb2YgY29uc2lzdGVudCBhcnJheSB0eXBlcyBhY3Jvc3MgbWF0Y2hpbmcgYXR0cmlidXRlcy4iKSxudWxsO2lmKGU9PT12b2lkIDAmJihlPWguaXRlbVNpemUpLGUhPT1oLml0ZW1TaXplKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUuaXRlbVNpemUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7aWYobj09PXZvaWQgMCYmKG49aC5ub3JtYWxpemVkKSxuIT09aC5ub3JtYWxpemVkKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VBdHRyaWJ1dGVzKCkgZmFpbGVkLiBCdWZmZXJBdHRyaWJ1dGUubm9ybWFsaXplZCBtdXN0IGJlIGNvbnNpc3RlbnQgYWNyb3NzIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihzPT09LTEmJihzPWguZ3B1VHlwZSkscyE9PWguZ3B1VHlwZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlQXR0cmlidXRlcygpIGZhaWxlZC4gQnVmZmVyQXR0cmlidXRlLmdwdVR5cGUgbXVzdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBtYXRjaGluZyBhdHRyaWJ1dGVzLiIpLG51bGw7cis9aC5jb3VudCplfWNvbnN0IG89bmV3IHQociksYT1uZXcgeHQobyxlLG4pO2xldCBjPTA7Zm9yKGxldCBsPTA7bDxpLmxlbmd0aDsrK2wpe2NvbnN0IGg9aVtsXTtpZihoLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUpe2NvbnN0IHU9Yy9lO2ZvcihsZXQgZj0wLGQ9aC5jb3VudDtmPGQ7ZisrKWZvcihsZXQgcD0wO3A8ZTtwKyspe2NvbnN0IHk9aC5nZXRDb21wb25lbnQoZixwKTthLnNldENvbXBvbmVudChmK3UscCx5KX19ZWxzZSBvLnNldChoLmFycmF5LGMpO2MrPWguY291bnQqZX1yZXR1cm4gcyE9PXZvaWQgMCYmKGEuZ3B1VHlwZT1zKSxhfWZ1bmN0aW9uIEwwKGkpe2lmKGkuZ3JvdXBzLmxlbmd0aD09PTApcmV0dXJuIGNvbnNvbGUud2FybigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlscy5tZXJnZUdyb3VwcygpOiBObyBncm91cHMgYXJlIGRlZmluZWQuIE5vdGhpbmcgdG8gbWVyZ2UuIiksaTtsZXQgdD1pLmdyb3VwcztpZih0PXQuc29ydCgobyxhKT0+by5tYXRlcmlhbEluZGV4IT09YS5tYXRlcmlhbEluZGV4P28ubWF0ZXJpYWxJbmRleC1hLm1hdGVyaWFsSW5kZXg6by5zdGFydC1hLnN0YXJ0KSxpLmdldEluZGV4KCk9PT1udWxsKXtjb25zdCBvPWkuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLGE9W107Zm9yKGxldCBjPTA7YzxvLmNvdW50O2MrPTMpYS5wdXNoKGMsYysxLGMrMik7aS5zZXRJbmRleChhKX1jb25zdCBlPWkuZ2V0SW5kZXgoKSxuPVtdO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb10sYz1hLnN0YXJ0LGw9YythLmNvdW50O2ZvcihsZXQgaD1jO2g8bDtoKyspbi5wdXNoKGUuZ2V0WChoKSl9aS5kaXNwb3NlKCksaS5zZXRJbmRleChuKTtsZXQgcz0wO2ZvcihsZXQgbz0wO288dC5sZW5ndGg7bysrKXtjb25zdCBhPXRbb107YS5zdGFydD1zLHMrPWEuY291bnR9bGV0IHI9dFswXTtpLmdyb3Vwcz1bcl07Zm9yKGxldCBvPTE7bzx0Lmxlbmd0aDtvKyspe2NvbnN0IGE9dFtvXTtyLm1hdGVyaWFsSW5kZXg9PT1hLm1hdGVyaWFsSW5kZXg/ci5jb3VudCs9YS5jb3VudDoocj1hLGkuZ3JvdXBzLnB1c2gocikpfXJldHVybiBpfWZ1bmN0aW9uICRsKGksdD0wKXtjb25zdCBlPWlbMF0uaW5kZXghPT1udWxsLG49bmV3IFNldChPYmplY3Qua2V5cyhpWzBdLmF0dHJpYnV0ZXMpKSxzPW5ldyBTZXQoT2JqZWN0LmtleXMoaVswXS5tb3JwaEF0dHJpYnV0ZXMpKSxyPXt9LG89e30sYT1pWzBdLm1vcnBoVGFyZ2V0c1JlbGF0aXZlLGM9bmV3IHVlO2xldCBsPTA7Zm9yKGxldCBoPTA7aDxpLmxlbmd0aDsrK2gpe2NvbnN0IHU9aVtoXTtsZXQgZj0wO2lmKGUhPT0odS5pbmRleCE9PW51bGwpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuIEFsbCBnZW9tZXRyaWVzIG11c3QgaGF2ZSBjb21wYXRpYmxlIGF0dHJpYnV0ZXM7IG1ha2Ugc3VyZSBpbmRleCBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1LmF0dHJpYnV0ZXMpe2lmKCFuLmhhcyhkKSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsnLiBBbGwgZ2VvbWV0cmllcyBtdXN0IGhhdmUgY29tcGF0aWJsZSBhdHRyaWJ1dGVzOyBtYWtlIHN1cmUgIicrZCsnIiBhdHRyaWJ1dGUgZXhpc3RzIGFtb25nIGFsbCBnZW9tZXRyaWVzLCBvciBpbiBub25lIG9mIHRoZW0uJyksbnVsbDtyW2RdPT09dm9pZCAwJiYocltkXT1bXSkscltkXS5wdXNoKHUuYXR0cmlidXRlc1tkXSksZisrfWlmKGYhPT1uLnNpemUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoIlRIUkVFLkJ1ZmZlckdlb21ldHJ5VXRpbHM6IC5tZXJnZUdlb21ldHJpZXMoKSBmYWlsZWQgd2l0aCBnZW9tZXRyeSBhdCBpbmRleCAiK2grIi4gTWFrZSBzdXJlIGFsbCBnZW9tZXRyaWVzIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuIiksbnVsbDtpZihhIT09dS5tb3JwaFRhcmdldHNSZWxhdGl2ZSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiAubW9ycGhUYXJnZXRzUmVsYXRpdmUgbXVzdCBiZSBjb25zaXN0ZW50IHRocm91Z2hvdXQgYWxsIGdlb21ldHJpZXMuIiksbnVsbDtmb3IoY29uc3QgZCBpbiB1Lm1vcnBoQXR0cmlidXRlcyl7aWYoIXMuaGFzKGQpKXJldHVybiBjb25zb2xlLmVycm9yKCJUSFJFRS5CdWZmZXJHZW9tZXRyeVV0aWxzOiAubWVyZ2VHZW9tZXRyaWVzKCkgZmFpbGVkIHdpdGggZ2VvbWV0cnkgYXQgaW5kZXggIitoKyIuICAubW9ycGhBdHRyaWJ1dGVzIG11c3QgYmUgY29uc2lzdGVudCB0aHJvdWdob3V0IGFsbCBnZW9tZXRyaWVzLiIpLG51bGw7b1tkXT09PXZvaWQgMCYmKG9bZF09W10pLG9bZF0ucHVzaCh1Lm1vcnBoQXR0cmlidXRlc1tkXSl9aWYodCl7bGV0IGQ7aWYoZSlkPXUuaW5kZXguY291bnQ7ZWxzZSBpZih1LmF0dHJpYnV0ZXMucG9zaXRpb24hPT12b2lkIDApZD11LmF0dHJpYnV0ZXMucG9zaXRpb24uY291bnQ7ZWxzZSByZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aXRoIGdlb21ldHJ5IGF0IGluZGV4ICIraCsiLiBUaGUgZ2VvbWV0cnkgbXVzdCBoYXZlIGVpdGhlciBhbiBpbmRleCBvciBhIHBvc2l0aW9uIGF0dHJpYnV0ZSIpLG51bGw7aWYodD09PTEpYy5hZGRHcm91cChsLGQsaCk7ZWxzZSBpZih0PT09MiYmdS5ncm91cHMubGVuZ3RoPjApZm9yKGxldCBwIG9mIHUuZ3JvdXBzKXtsZXQgeT1wLm1hdGVyaWFsSW5kZXg7Yy5hZGRHcm91cChsK3Auc3RhcnQsTWF0aC5taW4ocC5jb3VudCxkKSx5KX1sKz1kfX1pZihlKXtsZXQgaD0wO2NvbnN0IHU9W107Zm9yKGxldCBmPTA7ZjxpLmxlbmd0aDsrK2Ype2NvbnN0IGQ9aVtmXS5pbmRleDtmb3IobGV0IHA9MDtwPGQuY291bnQ7KytwKXUucHVzaChkLmdldFgocCkraCk7aCs9aVtmXS5hdHRyaWJ1dGVzLnBvc2l0aW9uLmNvdW50fWMuc2V0SW5kZXgodSl9Zm9yKGNvbnN0IGggaW4gcil7Y29uc3QgdT1EbChyW2hdKTtpZighdSlyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIGF0dHJpYnV0ZS4iKSxudWxsO2Muc2V0QXR0cmlidXRlKGgsdSl9Zm9yKGNvbnN0IGggaW4gbyl7Y29uc3QgdT1vW2hdWzBdLmxlbmd0aDtpZih1PT09MClicmVhaztjLm1vcnBoQXR0cmlidXRlcz1jLm1vcnBoQXR0cmlidXRlc3x8e30sYy5tb3JwaEF0dHJpYnV0ZXNbaF09W107Zm9yKGxldCBmPTA7Zjx1OysrZil7Y29uc3QgZD1bXTtmb3IobGV0IHk9MDt5PG9baF0ubGVuZ3RoOysreSlkLnB1c2gob1toXVt5XVtmXSk7Y29uc3QgcD1EbChkKTtpZighcClyZXR1cm4gY29uc29sZS5lcnJvcigiVEhSRUUuQnVmZmVyR2VvbWV0cnlVdGlsczogLm1lcmdlR2VvbWV0cmllcygpIGZhaWxlZCB3aGlsZSB0cnlpbmcgdG8gbWVyZ2UgdGhlICIraCsiIG1vcnBoQXR0cmlidXRlLiIpLG51bGw7Yy5tb3JwaEF0dHJpYnV0ZXNbaF0ucHVzaChwKX19cmV0dXJuIHQ9PT0yP0wwKGMpOmN9Y2xhc3MgTzAgZXh0ZW5kcyBXbntjb25zdHJ1Y3Rvcih0LGUpe3N1cGVyKHQsZSk7Y29uc3Qgbj1uZXcgSHMobmV3IFduKHQsR2UoRnQoe30sZSkse2hhc1RvcDohMCxoYXNTaWRlOiEwLGhhc0JvdHRvbTohMX0pKSk7bi51cGRhdGVNYXRyaXhXb3JsZCgpO2NvbnN0IHM9bmV3IGd0KCkuc2V0RnJvbU9iamVjdChuKSxyPW5ldyBUO3MuZ2V0U2l6ZShyKTtjb25zdCBvPW5ldyBUKHMubWluLngrci54LzIscy5taW4ueStyLnkvMiwwKTtsZXQgYT1lLnRvcFNlZ21lbnRzLGM9ZS5ib3gzO2lmKGMpe2M9Yy51bmlvbihzKTtjb25zdCBnPW5ldyBUO2MuZ2V0U2l6ZShnKTtjb25zdCBiPU1hdGgubWF4KHIueC9nLngsci55L2cueSk7YT1NYXRoLmNlaWwoZS50b3BTZWdtZW50cypiKX1pZihhPDQpcmV0dXJuIHRoaXM7Y29uc3QgbD1uZXcgRm8oci54LHIueSxhLGEpLGg9bmV3IEhzKGwpO2gucG9zaXRpb24uc2V0KG8ueCxvLnksby56KSxoLnVwZGF0ZU1hdHJpeFdvcmxkKCk7Y29uc3QgZj1uZXcgUjAoKS5ldmFsdWF0ZShoLG4sU2wpLGQ9Zi5nZW9tZXRyeS5nZXRBdHRyaWJ1dGUoInBvc2l0aW9uIikscD1uZXcgQ2UoZC5jb3VudCoyLDIpO2ZvcihsZXQgZz0wO2c8ZC5jb3VudDtnKyspe2NvbnN0IGI9ZC5nZXRaKGcpO2Quc2V0WihnLGUuZGVwdGgrYil9aWYoYyl7Y29uc3QgZz1jLm1pbixiPWMubWF4LHc9bmV3IFQoKS5zdWJWZWN0b3JzKGIsZyk7Zm9yKGxldCB4PTA7eDxkLmNvdW50O3grKyl7Y29uc3QgTT1kLmdldFgoeCksQT1kLmdldFkoeCksXz0oTS1nLngpL3cueCxTPShBLWcueSkvdy55O3Auc2V0WFkoeCxfLFMpfWYuZ2VvbWV0cnkuc2V0QXR0cmlidXRlKCJ1diIscCl9ZC5uZWVkc1VwZGF0ZT0hMDtjb25zdCB5PW5ldyBXbih0LEdlKEZ0KHt9LGUpLHtoYXNUb3A6ITF9KSksbT0kbChbZi5nZW9tZXRyeSx5XSwyKTt0aGlzLmNvcHkobS50b05vbkluZGV4ZWQoKSl9fXZhciBEMD1pPT57Y29uc3R7c3BsaXQ6dCxkZXB0aDplLHBvaW50czpuLGJveDM6cyxoYXNUb3A6cixoYXNCb3R0b206byxoYXNTaWRlOmEsc2lkZVJlcGVhdDpjLHRvcFNlZ21lbnRzOmx9PWksaD1sP08wOlduLHU9bmV3IGgobmV3IERjKG4pLHtkZXB0aDplLGJldmVsRW5hYmxlZDohMSxib3gzOnMsVVZHZW5lcmF0b3I6JGYoe3NwbGl0OnQsYm94MzpzLHNpZGVSZXBlYXQ6Y30pLGhhc1RvcDpyLGhhc0JvdHRvbTpvLGhhc1NpZGU6YSx0b3BTZWdtZW50czpsfSk7cmV0dXJuIFVmKCksdX07ZnVuY3Rpb24gJDAoaSx0LGU9MCl7Y29uc3Qgbj0oOTAtdCkqTWF0aC5QSS8xODAscz0oOTAtaSkqTWF0aC5QSS8xODA7cmV0dXJuW2UqTWF0aC5zaW4obikqTWF0aC5jb3MocyksZSpNYXRoLmNvcyhuKSxlKk1hdGguc2luKG4pKk1hdGguc2luKHMpXX1mdW5jdGlvbiB0cihpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjppPHQ/LTE6aT50PzE6aT49dD8wOk5hTn1mdW5jdGlvbiBVMChpLHQpe3JldHVybiBpPT1udWxsfHx0PT1udWxsP05hTjp0PGk/LTE6dD5pPzE6dD49aT8wOk5hTn1mdW5jdGlvbiBVbChpKXtsZXQgdCxlLG47aS5sZW5ndGghPT0yPyh0PXRyLGU9KGEsYyk9PnRyKGkoYSksYyksbj0oYSxjKT0+aShhKS1jKToodD1pPT09dHJ8fGk9PT1VMD9pOlYwLGU9aSxuPWkpO2Z1bmN0aW9uIHMoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTwwP2w9dSsxOmg9dX13aGlsZShsPGgpfXJldHVybiBsfWZ1bmN0aW9uIHIoYSxjLGw9MCxoPWEubGVuZ3RoKXtpZihsPGgpe2lmKHQoYyxjKSE9PTApcmV0dXJuIGg7ZG97Y29uc3QgdT1sK2g+Pj4xO2UoYVt1XSxjKTw9MD9sPXUrMTpoPXV9d2hpbGUobDxoKX1yZXR1cm4gbH1mdW5jdGlvbiBvKGEsYyxsPTAsaD1hLmxlbmd0aCl7Y29uc3QgdT1zKGEsYyxsLGgtMSk7cmV0dXJuIHU+bCYmbihhW3UtMV0sYyk+LW4oYVt1XSxjKT91LTE6dX1yZXR1cm57bGVmdDpzLGNlbnRlcjpvLHJpZ2h0OnJ9fWZ1bmN0aW9uIFYwKCl7cmV0dXJuIDB9ZnVuY3Rpb24gcTAoaSl7cmV0dXJuIGk9PT1udWxsP05hTjoraX1jb25zdCBIMD1VbCh0cikucmlnaHQ7VWwocTApLmNlbnRlcjtmdW5jdGlvbiBlcihpLHQpe2xldCBlLG47aWYodD09PXZvaWQgMClmb3IoY29uc3QgcyBvZiBpKXMhPW51bGwmJihlPT09dm9pZCAwP3M+PXMmJihlPW49cyk6KGU+cyYmKGU9cyksbjxzJiYobj1zKSkpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihlPT09dm9pZCAwP3I+PXImJihlPW49cik6KGU+ciYmKGU9ciksbjxyJiYobj1yKSkpfXJldHVybltlLG5dfWNsYXNzIFJle2NvbnN0cnVjdG9yKCl7dGhpcy5fcGFydGlhbHM9bmV3IEZsb2F0NjRBcnJheSgzMiksdGhpcy5fbj0wfWFkZCh0KXtjb25zdCBlPXRoaXMuX3BhcnRpYWxzO2xldCBuPTA7Zm9yKGxldCBzPTA7czx0aGlzLl9uJiZzPDMyO3MrKyl7Y29uc3Qgcj1lW3NdLG89dCtyLGE9TWF0aC5hYnModCk8TWF0aC5hYnMocik/dC0oby1yKTpyLShvLXQpO2EmJihlW24rK109YSksdD1vfXJldHVybiBlW25dPXQsdGhpcy5fbj1uKzEsdGhpc312YWx1ZU9mKCl7Y29uc3QgdD10aGlzLl9wYXJ0aWFscztsZXQgZT10aGlzLl9uLG4scyxyLG89MDtpZihlPjApe2ZvcihvPXRbLS1lXTtlPjAmJihuPW8scz10Wy0tZV0sbz1uK3Mscj1zLShvLW4pLCFyKTspO2U+MCYmKHI8MCYmdFtlLTFdPDB8fHI+MCYmdFtlLTFdPjApJiYocz1yKjIsbj1vK3Mscz09bi1vJiYobz1uKSl9cmV0dXJuIG99fWNvbnN0IFcwPU1hdGguc3FydCg1MCksRzA9TWF0aC5zcXJ0KDEwKSxaMD1NYXRoLnNxcnQoMik7ZnVuY3Rpb24gbnIoaSx0LGUpe2NvbnN0IG49KHQtaSkvTWF0aC5tYXgoMCxlKSxzPU1hdGguZmxvb3IoTWF0aC5sb2cxMChuKSkscj1uL01hdGgucG93KDEwLHMpLG89cj49VzA/MTA6cj49RzA/NTpyPj1aMD8yOjE7bGV0IGEsYyxsO3JldHVybiBzPDA/KGw9TWF0aC5wb3coMTAsLXMpL28sYT1NYXRoLnJvdW5kKGkqbCksYz1NYXRoLnJvdW5kKHQqbCksYS9sPGkmJisrYSxjL2w+dCYmLS1jLGw9LWwpOihsPU1hdGgucG93KDEwLHMpKm8sYT1NYXRoLnJvdW5kKGkvbCksYz1NYXRoLnJvdW5kKHQvbCksYSpsPGkmJisrYSxjKmw+dCYmLS1jKSxjPGEmJi41PD1lJiZlPDI/bnIoaSx0LGUqMik6W2EsYyxsXX1mdW5jdGlvbiBYMChpLHQsZSl7aWYodD0rdCxpPStpLGU9K2UsIShlPjApKXJldHVybltdO2lmKGk9PT10KXJldHVybltpXTtjb25zdCBuPXQ8aSxbcyxyLG9dPW4/bnIodCxpLGUpOm5yKGksdCxlKTtpZighKHI+PXMpKXJldHVybltdO2NvbnN0IGE9ci1zKzEsYz1uZXcgQXJyYXkoYSk7aWYobilpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShyLWwpKm87ZWxzZSBpZihvPDApZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpLy1vO2Vsc2UgZm9yKGxldCBsPTA7bDxhOysrbCljW2xdPShzK2wpKm87cmV0dXJuIGN9ZnVuY3Rpb24gZ2EoaSx0LGUpe3JldHVybiB0PSt0LGk9K2ksZT0rZSxucihpLHQsZSlbMl19ZnVuY3Rpb24gSjAoaSx0LGUpe3Q9K3QsaT0raSxlPStlO2NvbnN0IG49dDxpLHM9bj9nYSh0LGksZSk6Z2EoaSx0LGUpO3JldHVybihuPy0xOjEpKihzPDA/MS8tczpzKX1mdW5jdGlvbiBZMChpLHQpe2xldCBlPTAsbj0wO2lmKHQ9PT12b2lkIDApZm9yKGxldCBzIG9mIGkpcyE9bnVsbCYmKHM9K3MpPj1zJiYoKytlLG4rPXMpO2Vsc2V7bGV0IHM9LTE7Zm9yKGxldCByIG9mIGkpKHI9dChyLCsrcyxpKSkhPW51bGwmJihyPStyKT49ciYmKCsrZSxuKz1yKX1pZihlKXJldHVybiBuL2V9ZnVuY3Rpb24qajAoaSl7Zm9yKGNvbnN0IHQgb2YgaSl5aWVsZCokdSh0KX1mdW5jdGlvbiBEaShpKXtyZXR1cm4gQXJyYXkuZnJvbShqMChpKSl9dmFyIEs9MWUtNixpcj0xZS0xMixYPU1hdGguUEksTnQ9WC8yLHNyPVgvNCxSdD1YKjIsaHQ9MTgwL1gsSD1YLzE4MCx0dD1NYXRoLmFicyx4YT1NYXRoLmF0YW4scmU9TWF0aC5hdGFuMixXPU1hdGguY29zLFEwPU1hdGguZXhwLHdhPU1hdGguaHlwb3QsSzA9TWF0aC5sb2cscT1NYXRoLnNpbix0cD1NYXRoLnNpZ258fGZ1bmN0aW9uKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH0sTGU9TWF0aC5zcXJ0LGVwPU1hdGgudGFuO2Z1bmN0aW9uIG5wKGkpe3JldHVybiBpPjE/MDppPC0xP1g6TWF0aC5hY29zKGkpfWZ1bmN0aW9uIE9lKGkpe3JldHVybiBpPjE/TnQ6aTwtMT8tTnQ6TWF0aC5hc2luKGkpfWZ1bmN0aW9uIFZsKGkpe3JldHVybihpPXEoaS8yKSkqaX1mdW5jdGlvbiBTdCgpe31mdW5jdGlvbiBycihpLHQpe2kmJkhsLmhhc093blByb3BlcnR5KGkudHlwZSkmJkhsW2kudHlwZV0oaSx0KX12YXIgcWw9e0ZlYXR1cmU6ZnVuY3Rpb24oaSx0KXtycihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspcnIoZVtuXS5nZW9tZXRyeSx0KX19LEhsPXtTcGhlcmU6ZnVuY3Rpb24oaSx0KXt0LnNwaGVyZSgpfSxQb2ludDpmdW5jdGlvbihpLHQpe2k9aS5jb29yZGluYXRlcyx0LnBvaW50KGlbMF0saVsxXSxpWzJdKX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaT1lW25dLHQucG9pbnQoaVswXSxpWzFdLGlbMl0pfSxMaW5lU3RyaW5nOmZ1bmN0aW9uKGksdCl7YmEoaS5jb29yZGluYXRlcyx0LDApfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWJhKGVbbl0sdCwwKX0sUG9seWdvbjpmdW5jdGlvbihpLHQpe1dsKGkuY29vcmRpbmF0ZXMsdCl9LE11bHRpUG9seWdvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspV2woZVtuXSx0KX0sR2VvbWV0cnlDb2xsZWN0aW9uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuZ2VvbWV0cmllcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KXJyKGVbbl0sdCl9fTtmdW5jdGlvbiBiYShpLHQsZSl7dmFyIG49LTEscz1pLmxlbmd0aC1lLHI7Zm9yKHQubGluZVN0YXJ0KCk7KytuPHM7KXI9aVtuXSx0LnBvaW50KHJbMF0sclsxXSxyWzJdKTt0LmxpbmVFbmQoKX1mdW5jdGlvbiBXbChpLHQpe3ZhciBlPS0xLG49aS5sZW5ndGg7Zm9yKHQucG9seWdvblN0YXJ0KCk7KytlPG47KWJhKGlbZV0sdCwxKTt0LnBvbHlnb25FbmQoKX1mdW5jdGlvbiBvcihpLHQpe2kmJnFsLmhhc093blByb3BlcnR5KGkudHlwZSk/cWxbaS50eXBlXShpLHQpOnJyKGksdCl9dmFyIGFyPW5ldyBSZSxHbD1uZXcgUmUsWmwsWGwsTWEsQWEsX2EsRGU9e3BvaW50OlN0LGxpbmVTdGFydDpTdCxsaW5lRW5kOlN0LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2FyPW5ldyBSZSxEZS5saW5lU3RhcnQ9aXAsRGUubGluZUVuZD1zcH0scG9seWdvbkVuZDpmdW5jdGlvbigpe3ZhciBpPSthcjtHbC5hZGQoaTwwP1J0K2k6aSksdGhpcy5saW5lU3RhcnQ9dGhpcy5saW5lRW5kPXRoaXMucG9pbnQ9U3R9LHNwaGVyZTpmdW5jdGlvbigpe0dsLmFkZChSdCl9fTtmdW5jdGlvbiBpcCgpe0RlLnBvaW50PXJwfWZ1bmN0aW9uIHNwKCl7SmwoWmwsWGwpfWZ1bmN0aW9uIHJwKGksdCl7RGUucG9pbnQ9SmwsWmw9aSxYbD10LGkqPUgsdCo9SCxNYT1pLEFhPVcodD10LzIrc3IpLF9hPXEodCl9ZnVuY3Rpb24gSmwoaSx0KXtpKj1ILHQqPUgsdD10LzIrc3I7dmFyIGU9aS1NYSxuPWU+PTA/MTotMSxzPW4qZSxyPVcodCksbz1xKHQpLGE9X2EqbyxjPUFhKnIrYSpXKHMpLGw9YSpuKnEocyk7YXIuYWRkKHJlKGwsYykpLE1hPWksQWE9cixfYT1vfWZ1bmN0aW9uIGNyKGkpe3JldHVybltyZShpWzFdLGlbMF0pLE9lKGlbMl0pXX1mdW5jdGlvbiBBbihpKXt2YXIgdD1pWzBdLGU9aVsxXSxuPVcoZSk7cmV0dXJuW24qVyh0KSxuKnEodCkscShlKV19ZnVuY3Rpb24gbHIoaSx0KXtyZXR1cm4gaVswXSp0WzBdK2lbMV0qdFsxXStpWzJdKnRbMl19ZnVuY3Rpb24gZWkoaSx0KXtyZXR1cm5baVsxXSp0WzJdLWlbMl0qdFsxXSxpWzJdKnRbMF0taVswXSp0WzJdLGlbMF0qdFsxXS1pWzFdKnRbMF1dfWZ1bmN0aW9uIFNhKGksdCl7aVswXSs9dFswXSxpWzFdKz10WzFdLGlbMl0rPXRbMl19ZnVuY3Rpb24gaHIoaSx0KXtyZXR1cm5baVswXSp0LGlbMV0qdCxpWzJdKnRdfWZ1bmN0aW9uIHVyKGkpe3ZhciB0PUxlKGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtpWzBdLz10LGlbMV0vPXQsaVsyXS89dH12YXIgb3QsTHQsdXQscXQsX24sWWwsamwsbmksJGksb24sJGUsVWU9e3BvaW50OnZhLGxpbmVTdGFydDpLbCxsaW5lRW5kOnRoLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe1VlLnBvaW50PWVoLFVlLmxpbmVTdGFydD1vcCxVZS5saW5lRW5kPWFwLCRpPW5ldyBSZSxEZS5wb2x5Z29uU3RhcnQoKX0scG9seWdvbkVuZDpmdW5jdGlvbigpe0RlLnBvbHlnb25FbmQoKSxVZS5wb2ludD12YSxVZS5saW5lU3RhcnQ9S2wsVWUubGluZUVuZD10aCxhcjwwPyhvdD0tKHV0PTE4MCksTHQ9LShxdD05MCkpOiRpPks/cXQ9OTA6JGk8LUsmJihMdD0tOTApLCRlWzBdPW90LCRlWzFdPXV0fSxzcGhlcmU6ZnVuY3Rpb24oKXtvdD0tKHV0PTE4MCksTHQ9LShxdD05MCl9fTtmdW5jdGlvbiB2YShpLHQpe29uLnB1c2goJGU9W290PWksdXQ9aV0pLHQ8THQmJihMdD10KSx0PnF0JiYocXQ9dCl9ZnVuY3Rpb24gUWwoaSx0KXt2YXIgZT1BbihbaSpILHQqSF0pO2lmKG5pKXt2YXIgbj1laShuaSxlKSxzPVtuWzFdLC1uWzBdLDBdLHI9ZWkocyxuKTt1cihyKSxyPWNyKHIpO3ZhciBvPWktX24sYT1vPjA/MTotMSxjPXJbMF0qaHQqYSxsLGg9dHQobyk+MTgwO2heKGEqX248YyYmYzxhKmkpPyhsPXJbMV0qaHQsbD5xdCYmKHF0PWwpKTooYz0oYyszNjApJTM2MC0xODAsaF4oYSpfbjxjJiZjPGEqaSk/KGw9LXJbMV0qaHQsbDxMdCYmKEx0PWwpKToodDxMdCYmKEx0PXQpLHQ+cXQmJihxdD10KSkpLGg/aTxfbj9IdChvdCxpKT5IdChvdCx1dCkmJih1dD1pKTpIdChpLHV0KT5IdChvdCx1dCkmJihvdD1pKTp1dD49b3Q/KGk8b3QmJihvdD1pKSxpPnV0JiYodXQ9aSkpOmk+X24/SHQob3QsaSk+SHQob3QsdXQpJiYodXQ9aSk6SHQoaSx1dCk+SHQob3QsdXQpJiYob3Q9aSl9ZWxzZSBvbi5wdXNoKCRlPVtvdD1pLHV0PWldKTt0PEx0JiYoTHQ9dCksdD5xdCYmKHF0PXQpLG5pPWUsX249aX1mdW5jdGlvbiBLbCgpe1VlLnBvaW50PVFsfWZ1bmN0aW9uIHRoKCl7JGVbMF09b3QsJGVbMV09dXQsVWUucG9pbnQ9dmEsbmk9bnVsbH1mdW5jdGlvbiBlaChpLHQpe2lmKG5pKXt2YXIgZT1pLV9uOyRpLmFkZCh0dChlKT4xODA/ZSsoZT4wPzM2MDotMzYwKTplKX1lbHNlIFlsPWksamw9dDtEZS5wb2ludChpLHQpLFFsKGksdCl9ZnVuY3Rpb24gb3AoKXtEZS5saW5lU3RhcnQoKX1mdW5jdGlvbiBhcCgpe2VoKFlsLGpsKSxEZS5saW5lRW5kKCksdHQoJGkpPksmJihvdD0tKHV0PTE4MCkpLCRlWzBdPW90LCRlWzFdPXV0LG5pPW51bGx9ZnVuY3Rpb24gSHQoaSx0KXtyZXR1cm4odC09aSk8MD90KzM2MDp0fWZ1bmN0aW9uIGNwKGksdCl7cmV0dXJuIGlbMF0tdFswXX1mdW5jdGlvbiBuaChpLHQpe3JldHVybiBpWzBdPD1pWzFdP2lbMF08PXQmJnQ8PWlbMV06dDxpWzBdfHxpWzFdPHR9ZnVuY3Rpb24gaWgoaSl7dmFyIHQsZSxuLHMscixvLGE7aWYocXQ9dXQ9LShvdD1MdD0xLzApLG9uPVtdLG9yKGksVWUpLGU9b24ubGVuZ3RoKXtmb3Iob24uc29ydChjcCksdD0xLG49b25bMF0scj1bbl07dDxlOysrdClzPW9uW3RdLG5oKG4sc1swXSl8fG5oKG4sc1sxXSk/KEh0KG5bMF0sc1sxXSk+SHQoblswXSxuWzFdKSYmKG5bMV09c1sxXSksSHQoc1swXSxuWzFdKT5IdChuWzBdLG5bMV0pJiYoblswXT1zWzBdKSk6ci5wdXNoKG49cyk7Zm9yKG89LTEvMCxlPXIubGVuZ3RoLTEsdD0wLG49cltlXTt0PD1lO249cywrK3Qpcz1yW3RdLChhPUh0KG5bMV0sc1swXSkpPm8mJihvPWEsb3Q9c1swXSx1dD1uWzFdKX1yZXR1cm4gb249JGU9bnVsbCxvdD09PTEvMHx8THQ9PT0xLzA/W1tOYU4sTmFOXSxbTmFOLE5hTl1dOltbb3QsTHRdLFt1dCxxdF1dfXZhciBVaSxmcixkcixwcix5cixtcixncix4cix6YSxUYSxFYSxzaCxyaCxFdCxQdCxDdCxwZT17c3BoZXJlOlN0LHBvaW50OlBhLGxpbmVTdGFydDpvaCxsaW5lRW5kOmFoLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe3BlLmxpbmVTdGFydD11cCxwZS5saW5lRW5kPWZwfSxwb2x5Z29uRW5kOmZ1bmN0aW9uKCl7cGUubGluZVN0YXJ0PW9oLHBlLmxpbmVFbmQ9YWh9fTtmdW5jdGlvbiBQYShpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO1ZpKGUqVyhpKSxlKnEoaSkscSh0KSl9ZnVuY3Rpb24gVmkoaSx0LGUpeysrVWksZHIrPShpLWRyKS9VaSxwcis9KHQtcHIpL1VpLHlyKz0oZS15cikvVWl9ZnVuY3Rpb24gb2goKXtwZS5wb2ludD1scH1mdW5jdGlvbiBscChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpO0V0PWUqVyhpKSxQdD1lKnEoaSksQ3Q9cSh0KSxwZS5wb2ludD1ocCxWaShFdCxQdCxDdCl9ZnVuY3Rpb24gaHAoaSx0KXtpKj1ILHQqPUg7dmFyIGU9Vyh0KSxuPWUqVyhpKSxzPWUqcShpKSxyPXEodCksbz1yZShMZSgobz1QdCpyLUN0KnMpKm8rKG89Q3Qqbi1FdCpyKSpvKyhvPUV0KnMtUHQqbikqbyksRXQqbitQdCpzK0N0KnIpO2ZyKz1vLG1yKz1vKihFdCsoRXQ9bikpLGdyKz1vKihQdCsoUHQ9cykpLHhyKz1vKihDdCsoQ3Q9cikpLFZpKEV0LFB0LEN0KX1mdW5jdGlvbiBhaCgpe3BlLnBvaW50PVBhfWZ1bmN0aW9uIHVwKCl7cGUucG9pbnQ9ZHB9ZnVuY3Rpb24gZnAoKXtjaChzaCxyaCkscGUucG9pbnQ9UGF9ZnVuY3Rpb24gZHAoaSx0KXtzaD1pLHJoPXQsaSo9SCx0Kj1ILHBlLnBvaW50PWNoO3ZhciBlPVcodCk7RXQ9ZSpXKGkpLFB0PWUqcShpKSxDdD1xKHQpLFZpKEV0LFB0LEN0KX1mdW5jdGlvbiBjaChpLHQpe2kqPUgsdCo9SDt2YXIgZT1XKHQpLG49ZSpXKGkpLHM9ZSpxKGkpLHI9cSh0KSxvPVB0KnItQ3QqcyxhPUN0Km4tRXQqcixjPUV0KnMtUHQqbixsPXdhKG8sYSxjKSxoPU9lKGwpLHU9bCYmLWgvbDt6YS5hZGQodSpvKSxUYS5hZGQodSphKSxFYS5hZGQodSpjKSxmcis9aCxtcis9aCooRXQrKEV0PW4pKSxncis9aCooUHQrKFB0PXMpKSx4cis9aCooQ3QrKEN0PXIpKSxWaShFdCxQdCxDdCl9ZnVuY3Rpb24gbGgoaSl7VWk9ZnI9ZHI9cHI9eXI9bXI9Z3I9eHI9MCx6YT1uZXcgUmUsVGE9bmV3IFJlLEVhPW5ldyBSZSxvcihpLHBlKTt2YXIgdD0remEsZT0rVGEsbj0rRWEscz13YSh0LGUsbik7cmV0dXJuIHM8aXImJih0PW1yLGU9Z3Isbj14cixmcjxLJiYodD1kcixlPXByLG49eXIpLHM9d2EodCxlLG4pLHM8aXIpP1tOYU4sTmFOXTpbcmUoZSx0KSpodCxPZShuL3MpKmh0XX1mdW5jdGlvbiBDYShpLHQpe2Z1bmN0aW9uIGUobixzKXtyZXR1cm4gbj1pKG4scyksdChuWzBdLG5bMV0pfXJldHVybiBpLmludmVydCYmdC5pbnZlcnQmJihlLmludmVydD1mdW5jdGlvbihuLHMpe3JldHVybiBuPXQuaW52ZXJ0KG4scyksbiYmaS5pbnZlcnQoblswXSxuWzFdKX0pLGV9ZnVuY3Rpb24gQmEoaSx0KXtyZXR1cm4gdHQoaSk+WCYmKGktPU1hdGgucm91bmQoaS9SdCkqUnQpLFtpLHRdfUJhLmludmVydD1CYTtmdW5jdGlvbiBoaChpLHQsZSl7cmV0dXJuKGklPVJ0KT90fHxlP0NhKGZoKGkpLGRoKHQsZSkpOmZoKGkpOnR8fGU/ZGgodCxlKTpCYX1mdW5jdGlvbiB1aChpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdCs9aSx0dCh0KT5YJiYodC09TWF0aC5yb3VuZCh0L1J0KSpSdCksW3QsZV19fWZ1bmN0aW9uIGZoKGkpe3ZhciB0PXVoKGkpO3JldHVybiB0LmludmVydD11aCgtaSksdH1mdW5jdGlvbiBkaChpLHQpe3ZhciBlPVcoaSksbj1xKGkpLHM9Vyh0KSxyPXEodCk7ZnVuY3Rpb24gbyhhLGMpe3ZhciBsPVcoYyksaD1XKGEpKmwsdT1xKGEpKmwsZj1xKGMpLGQ9ZiplK2gqbjtyZXR1cm5bcmUodSpzLWQqcixoKmUtZipuKSxPZShkKnMrdSpyKV19cmV0dXJuIG8uaW52ZXJ0PWZ1bmN0aW9uKGEsYyl7dmFyIGw9VyhjKSxoPVcoYSkqbCx1PXEoYSkqbCxmPXEoYyksZD1mKnMtdSpyO3JldHVybltyZSh1KnMrZipyLGgqZStkKm4pLE9lKGQqZS1oKm4pXX0sb31mdW5jdGlvbiBwaChpKXtpPWhoKGlbMF0qSCxpWzFdKkgsaS5sZW5ndGg+Mj9pWzJdKkg6MCk7ZnVuY3Rpb24gdChlKXtyZXR1cm4gZT1pKGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9cmV0dXJuIHQuaW52ZXJ0PWZ1bmN0aW9uKGUpe3JldHVybiBlPWkuaW52ZXJ0KGVbMF0qSCxlWzFdKkgpLGVbMF0qPWh0LGVbMV0qPWh0LGV9LHR9ZnVuY3Rpb24gcHAoaSx0LGUsbixzLHIpe2lmKGUpe3ZhciBvPVcodCksYT1xKHQpLGM9biplO3M9PW51bGw/KHM9dCtuKlJ0LHI9dC1jLzIpOihzPXloKG8scykscj15aChvLHIpLChuPjA/czxyOnM+cikmJihzKz1uKlJ0KSk7Zm9yKHZhciBsLGg9cztuPjA/aD5yOmg8cjtoLT1jKWw9Y3IoW28sLWEqVyhoKSwtYSpxKGgpXSksaS5wb2ludChsWzBdLGxbMV0pfX1mdW5jdGlvbiB5aChpLHQpe3Q9QW4odCksdFswXS09aSx1cih0KTt2YXIgZT1ucCgtdFsxXSk7cmV0dXJuKCgtdFsyXTwwPy1lOmUpK1J0LUspJVJ0fWZ1bmN0aW9uIG1oKCl7dmFyIGk9W10sdDtyZXR1cm57cG9pbnQ6ZnVuY3Rpb24oZSxuLHMpe3QucHVzaChbZSxuLHNdKX0sbGluZVN0YXJ0OmZ1bmN0aW9uKCl7aS5wdXNoKHQ9W10pfSxsaW5lRW5kOlN0LHJlam9pbjpmdW5jdGlvbigpe2kubGVuZ3RoPjEmJmkucHVzaChpLnBvcCgpLmNvbmNhdChpLnNoaWZ0KCkpKX0scmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGU9aTtyZXR1cm4gaT1bXSx0PW51bGwsZX19fWZ1bmN0aW9uIHdyKGksdCl7cmV0dXJuIHR0KGlbMF0tdFswXSk8SyYmdHQoaVsxXS10WzFdKTxLfWZ1bmN0aW9uIGJyKGksdCxlLG4pe3RoaXMueD1pLHRoaXMuej10LHRoaXMubz1lLHRoaXMuZT1uLHRoaXMudj0hMSx0aGlzLm49dGhpcy5wPW51bGx9ZnVuY3Rpb24gZ2goaSx0LGUsbixzKXt2YXIgcj1bXSxvPVtdLGEsYztpZihpLmZvckVhY2goZnVuY3Rpb24ocCl7aWYoISgoeT1wLmxlbmd0aC0xKTw9MCkpe3ZhciB5LG09cFswXSxnPXBbeV0sYjtpZih3cihtLGcpKXtpZighbVsyXSYmIWdbMl0pe2ZvcihzLmxpbmVTdGFydCgpLGE9MDthPHk7KythKXMucG9pbnQoKG09cFthXSlbMF0sbVsxXSk7cy5saW5lRW5kKCk7cmV0dXJufWdbMF0rPTIqS31yLnB1c2goYj1uZXcgYnIobSxwLG51bGwsITApKSxvLnB1c2goYi5vPW5ldyBicihtLG51bGwsYiwhMSkpLHIucHVzaChiPW5ldyBicihnLHAsbnVsbCwhMSkpLG8ucHVzaChiLm89bmV3IGJyKGcsbnVsbCxiLCEwKSl9fSksISFyLmxlbmd0aCl7Zm9yKG8uc29ydCh0KSx4aChyKSx4aChvKSxhPTAsYz1vLmxlbmd0aDthPGM7KythKW9bYV0uZT1lPSFlO2Zvcih2YXIgbD1yWzBdLGgsdTs7KXtmb3IodmFyIGY9bCxkPSEwO2YudjspaWYoKGY9Zi5uKT09PWwpcmV0dXJuO2g9Zi56LHMubGluZVN0YXJ0KCk7ZG97aWYoZi52PWYuby52PSEwLGYuZSl7aWYoZClmb3IoYT0wLGM9aC5sZW5ndGg7YTxjOysrYSlzLnBvaW50KCh1PWhbYV0pWzBdLHVbMV0pO2Vsc2UgbihmLngsZi5uLngsMSxzKTtmPWYubn1lbHNle2lmKGQpZm9yKGg9Zi5wLnosYT1oLmxlbmd0aC0xO2E+PTA7LS1hKXMucG9pbnQoKHU9aFthXSlbMF0sdVsxXSk7ZWxzZSBuKGYueCxmLnAueCwtMSxzKTtmPWYucH1mPWYubyxoPWYueixkPSFkfXdoaWxlKCFmLnYpO3MubGluZUVuZCgpfX19ZnVuY3Rpb24geGgoaSl7aWYodD1pLmxlbmd0aCl7Zm9yKHZhciB0LGU9MCxuPWlbMF0sczsrK2U8dDspbi5uPXM9aVtlXSxzLnA9bixuPXM7bi5uPXM9aVswXSxzLnA9bn19ZnVuY3Rpb24gRmEoaSl7cmV0dXJuIHR0KGlbMF0pPD1YP2lbMF06dHAoaVswXSkqKCh0dChpWzBdKStYKSVSdC1YKX1mdW5jdGlvbiB3aChpLHQpe3ZhciBlPUZhKHQpLG49dFsxXSxzPXEobikscj1bcShlKSwtVyhlKSwwXSxvPTAsYT0wLGM9bmV3IFJlO3M9PT0xP249TnQrSzpzPT09LTEmJihuPS1OdC1LKTtmb3IodmFyIGw9MCxoPWkubGVuZ3RoO2w8aDsrK2wpaWYoZj0odT1pW2xdKS5sZW5ndGgpZm9yKHZhciB1LGYsZD11W2YtMV0scD1GYShkKSx5PWRbMV0vMitzcixtPXEoeSksZz1XKHkpLGI9MDtiPGY7KytiLHA9eCxtPUEsZz1fLGQ9dyl7dmFyIHc9dVtiXSx4PUZhKHcpLE09d1sxXS8yK3NyLEE9cShNKSxfPVcoTSksUz14LXAsRT1TPj0wPzE6LTEsej1FKlMsdj16PlgsQz1tKkE7aWYoYy5hZGQocmUoQypFKnEoeiksZypfK0MqVyh6KSkpLG8rPXY/UytFKlJ0OlMsdl5wPj1lXng+PWUpe3ZhciBQPWVpKEFuKGQpLEFuKHcpKTt1cihQKTt2YXIgRj1laShyLFApO3VyKEYpO3ZhciBCPSh2XlM+PTA/LTE6MSkqT2UoRlsyXSk7KG4+Qnx8bj09PUImJihQWzBdfHxQWzFdKSkmJihhKz12XlM+PTA/MTotMSl9fXJldHVybihvPC1LfHxvPEsmJmM8LWlyKV5hJjF9ZnVuY3Rpb24gYmgoaSx0LGUsbil7cmV0dXJuIGZ1bmN0aW9uKHMpe3ZhciByPXQocyksbz1taCgpLGE9dChvKSxjPSExLGwsaCx1LGY9e3BvaW50OmQsbGluZVN0YXJ0OnksbGluZUVuZDptLHBvbHlnb25TdGFydDpmdW5jdGlvbigpe2YucG9pbnQ9ZyxmLmxpbmVTdGFydD1iLGYubGluZUVuZD13LGg9W10sbD1bXX0scG9seWdvbkVuZDpmdW5jdGlvbigpe2YucG9pbnQ9ZCxmLmxpbmVTdGFydD15LGYubGluZUVuZD1tLGg9RGkoaCk7dmFyIHg9d2gobCxuKTtoLmxlbmd0aD8oY3x8KHMucG9seWdvblN0YXJ0KCksYz0hMCksZ2goaCxtcCx4LGUscykpOngmJihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkpLGMmJihzLnBvbHlnb25FbmQoKSxjPSExKSxoPWw9bnVsbH0sc3BoZXJlOmZ1bmN0aW9uKCl7cy5wb2x5Z29uU3RhcnQoKSxzLmxpbmVTdGFydCgpLGUobnVsbCxudWxsLDEscykscy5saW5lRW5kKCkscy5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBkKHgsTSl7aSh4LE0pJiZzLnBvaW50KHgsTSl9ZnVuY3Rpb24gcCh4LE0pe3IucG9pbnQoeCxNKX1mdW5jdGlvbiB5KCl7Zi5wb2ludD1wLHIubGluZVN0YXJ0KCl9ZnVuY3Rpb24gbSgpe2YucG9pbnQ9ZCxyLmxpbmVFbmQoKX1mdW5jdGlvbiBnKHgsTSl7dS5wdXNoKFt4LE1dKSxhLnBvaW50KHgsTSl9ZnVuY3Rpb24gYigpe2EubGluZVN0YXJ0KCksdT1bXX1mdW5jdGlvbiB3KCl7Zyh1WzBdWzBdLHVbMF1bMV0pLGEubGluZUVuZCgpO3ZhciB4PWEuY2xlYW4oKSxNPW8ucmVzdWx0KCksQSxfPU0ubGVuZ3RoLFMsRSx6O2lmKHUucG9wKCksbC5wdXNoKHUpLHU9bnVsbCwhIV8pe2lmKHgmMSl7aWYoRT1NWzBdLChTPUUubGVuZ3RoLTEpPjApe2ZvcihjfHwocy5wb2x5Z29uU3RhcnQoKSxjPSEwKSxzLmxpbmVTdGFydCgpLEE9MDtBPFM7KytBKXMucG9pbnQoKHo9RVtBXSlbMF0selsxXSk7cy5saW5lRW5kKCl9cmV0dXJufV8+MSYmeCYyJiZNLnB1c2goTS5wb3AoKS5jb25jYXQoTS5zaGlmdCgpKSksaC5wdXNoKE0uZmlsdGVyKHlwKSl9fXJldHVybiBmfX1mdW5jdGlvbiB5cChpKXtyZXR1cm4gaS5sZW5ndGg+MX1mdW5jdGlvbiBtcChpLHQpe3JldHVybigoaT1pLngpWzBdPDA/aVsxXS1OdC1LOk50LWlbMV0pLSgodD10LngpWzBdPDA/dFsxXS1OdC1LOk50LXRbMV0pfXZhciBNaD1iaChmdW5jdGlvbigpe3JldHVybiEwfSxncCx3cCxbLVgsLU50XSk7ZnVuY3Rpb24gZ3AoaSl7dmFyIHQ9TmFOLGU9TmFOLG49TmFOLHM7cmV0dXJue2xpbmVTdGFydDpmdW5jdGlvbigpe2kubGluZVN0YXJ0KCkscz0xfSxwb2ludDpmdW5jdGlvbihyLG8pe3ZhciBhPXI+MD9YOi1YLGM9dHQoci10KTt0dChjLVgpPEs/KGkucG9pbnQodCxlPShlK28pLzI+MD9OdDotTnQpLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxpLnBvaW50KHIsZSkscz0wKTpuIT09YSYmYz49WCYmKHR0KHQtbik8SyYmKHQtPW4qSyksdHQoci1hKTxLJiYoci09YSpLKSxlPXhwKHQsZSxyLG8pLGkucG9pbnQobixlKSxpLmxpbmVFbmQoKSxpLmxpbmVTdGFydCgpLGkucG9pbnQoYSxlKSxzPTApLGkucG9pbnQodD1yLGU9byksbj1hfSxsaW5lRW5kOmZ1bmN0aW9uKCl7aS5saW5lRW5kKCksdD1lPU5hTn0sY2xlYW46ZnVuY3Rpb24oKXtyZXR1cm4gMi1zfX19ZnVuY3Rpb24geHAoaSx0LGUsbil7dmFyIHMscixvPXEoaS1lKTtyZXR1cm4gdHQobyk+Sz94YSgocSh0KSoocj1XKG4pKSpxKGUpLXEobikqKHM9Vyh0KSkqcShpKSkvKHMqcipvKSk6KHQrbikvMn1mdW5jdGlvbiB3cChpLHQsZSxuKXt2YXIgcztpZihpPT1udWxsKXM9ZSpOdCxuLnBvaW50KC1YLHMpLG4ucG9pbnQoMCxzKSxuLnBvaW50KFgscyksbi5wb2ludChYLDApLG4ucG9pbnQoWCwtcyksbi5wb2ludCgwLC1zKSxuLnBvaW50KC1YLC1zKSxuLnBvaW50KC1YLDApLG4ucG9pbnQoLVgscyk7ZWxzZSBpZih0dChpWzBdLXRbMF0pPkspe3ZhciByPWlbMF08dFswXT9YOi1YO3M9ZSpyLzIsbi5wb2ludCgtcixzKSxuLnBvaW50KDAscyksbi5wb2ludChyLHMpfWVsc2Ugbi5wb2ludCh0WzBdLHRbMV0pfWZ1bmN0aW9uIGJwKGkpe3ZhciB0PVcoaSksZT0yKkgsbj10PjAscz10dCh0KT5LO2Z1bmN0aW9uIHIoaCx1LGYsZCl7cHAoZCxpLGUsZixoLHUpfWZ1bmN0aW9uIG8oaCx1KXtyZXR1cm4gVyhoKSpXKHUpPnR9ZnVuY3Rpb24gYShoKXt2YXIgdSxmLGQscCx5O3JldHVybntsaW5lU3RhcnQ6ZnVuY3Rpb24oKXtwPWQ9ITEseT0xfSxwb2ludDpmdW5jdGlvbihtLGcpe3ZhciBiPVttLGddLHcseD1vKG0sZyksTT1uP3g/MDpsKG0sZyk6eD9sKG0rKG08MD9YOi1YKSxnKTowO2lmKCF1JiYocD1kPXgpJiZoLmxpbmVTdGFydCgpLHghPT1kJiYodz1jKHUsYiksKCF3fHx3cih1LHcpfHx3cihiLHcpKSYmKGJbMl09MSkpLHghPT1kKXk9MCx4PyhoLmxpbmVTdGFydCgpLHc9YyhiLHUpLGgucG9pbnQod1swXSx3WzFdKSk6KHc9Yyh1LGIpLGgucG9pbnQod1swXSx3WzFdLDIpLGgubGluZUVuZCgpKSx1PXc7ZWxzZSBpZihzJiZ1JiZuXngpe3ZhciBBOyEoTSZmKSYmKEE9YyhiLHUsITApKSYmKHk9MCxuPyhoLmxpbmVTdGFydCgpLGgucG9pbnQoQVswXVswXSxBWzBdWzFdKSxoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCkpOihoLnBvaW50KEFbMV1bMF0sQVsxXVsxXSksaC5saW5lRW5kKCksaC5saW5lU3RhcnQoKSxoLnBvaW50KEFbMF1bMF0sQVswXVsxXSwzKSkpfXgmJighdXx8IXdyKHUsYikpJiZoLnBvaW50KGJbMF0sYlsxXSksdT1iLGQ9eCxmPU19LGxpbmVFbmQ6ZnVuY3Rpb24oKXtkJiZoLmxpbmVFbmQoKSx1PW51bGx9LGNsZWFuOmZ1bmN0aW9uKCl7cmV0dXJuIHl8KHAmJmQpPDwxfX19ZnVuY3Rpb24gYyhoLHUsZil7dmFyIGQ9QW4oaCkscD1Bbih1KSx5PVsxLDAsMF0sbT1laShkLHApLGc9bHIobSxtKSxiPW1bMF0sdz1nLWIqYjtpZighdylyZXR1cm4hZiYmaDt2YXIgeD10KmcvdyxNPS10KmIvdyxBPWVpKHksbSksXz1ocih5LHgpLFM9aHIobSxNKTtTYShfLFMpO3ZhciBFPUEsej1scihfLEUpLHY9bHIoRSxFKSxDPXoqei12KihscihfLF8pLTEpO2lmKCEoQzwwKSl7dmFyIFA9TGUoQyksRj1ocihFLCgtei1QKS92KTtpZihTYShGLF8pLEY9Y3IoRiksIWYpcmV0dXJuIEY7dmFyIEI9aFswXSxJPXVbMF0saz1oWzFdLEQ9dVsxXSxWO0k8QiYmKFY9QixCPUksST1WKTt2YXIgaj1JLUIsZHQ9dHQoai1YKTxLLER0PWR0fHxqPEs7aWYoIWR0JiZEPGsmJihWPWssaz1ELEQ9ViksRHQ/ZHQ/aytEPjBeRlsxXTwodHQoRlswXS1CKTxLP2s6RCk6azw9RlsxXSYmRlsxXTw9RDpqPlheKEI8PUZbMF0mJkZbMF08PUkpKXt2YXIgR3Q9aHIoRSwoLXorUCkvdik7cmV0dXJuIFNhKEd0LF8pLFtGLGNyKEd0KV19fX1mdW5jdGlvbiBsKGgsdSl7dmFyIGY9bj9pOlgtaSxkPTA7cmV0dXJuIGg8LWY/ZHw9MTpoPmYmJihkfD0yKSx1PC1mP2R8PTQ6dT5mJiYoZHw9OCksZH1yZXR1cm4gYmgobyxhLHIsbj9bMCwtaV06Wy1YLGktWF0pfWZ1bmN0aW9uIE1wKGksdCxlLG4scyxyKXt2YXIgbz1pWzBdLGE9aVsxXSxjPXRbMF0sbD10WzFdLGg9MCx1PTEsZj1jLW8sZD1sLWEscDtpZihwPWUtbywhKCFmJiZwPjApKXtpZihwLz1mLGY8MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWVsc2UgaWYoZj4wKXtpZihwPnUpcmV0dXJuO3A+aCYmKGg9cCl9aWYocD1zLW8sISghZiYmcDwwKSl7aWYocC89ZixmPDApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1lbHNlIGlmKGY+MCl7aWYocDxoKXJldHVybjtwPHUmJih1PXApfWlmKHA9bi1hLCEoIWQmJnA+MCkpe2lmKHAvPWQsZDwwKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9ZWxzZSBpZihkPjApe2lmKHA+dSlyZXR1cm47cD5oJiYoaD1wKX1pZihwPXItYSwhKCFkJiZwPDApKXtpZihwLz1kLGQ8MCl7aWYocD51KXJldHVybjtwPmgmJihoPXApfWVsc2UgaWYoZD4wKXtpZihwPGgpcmV0dXJuO3A8dSYmKHU9cCl9cmV0dXJuIGg+MCYmKGlbMF09bytoKmYsaVsxXT1hK2gqZCksdTwxJiYodFswXT1vK3UqZix0WzFdPWErdSpkKSwhMH19fX19dmFyIHFpPTFlOSxNcj0tcWk7ZnVuY3Rpb24gQXAoaSx0LGUsbil7ZnVuY3Rpb24gcyhsLGgpe3JldHVybiBpPD1sJiZsPD1lJiZ0PD1oJiZoPD1ufWZ1bmN0aW9uIHIobCxoLHUsZil7dmFyIGQ9MCxwPTA7aWYobD09bnVsbHx8KGQ9byhsLHUpKSE9PShwPW8oaCx1KSl8fGMobCxoKTwwXnU+MClkbyBmLnBvaW50KGQ9PT0wfHxkPT09Mz9pOmUsZD4xP246dCk7d2hpbGUoKGQ9KGQrdSs0KSU0KSE9PXApO2Vsc2UgZi5wb2ludChoWzBdLGhbMV0pfWZ1bmN0aW9uIG8obCxoKXtyZXR1cm4gdHQobFswXS1pKTxLP2g+MD8wOjM6dHQobFswXS1lKTxLP2g+MD8yOjE6dHQobFsxXS10KTxLP2g+MD8xOjA6aD4wPzM6Mn1mdW5jdGlvbiBhKGwsaCl7cmV0dXJuIGMobC54LGgueCl9ZnVuY3Rpb24gYyhsLGgpe3ZhciB1PW8obCwxKSxmPW8oaCwxKTtyZXR1cm4gdSE9PWY/dS1mOnU9PT0wP2hbMV0tbFsxXTp1PT09MT9sWzBdLWhbMF06dT09PTI/bFsxXS1oWzFdOmhbMF0tbFswXX1yZXR1cm4gZnVuY3Rpb24obCl7dmFyIGg9bCx1PW1oKCksZixkLHAseSxtLGcsYix3LHgsTSxBLF89e3BvaW50OlMsbGluZVN0YXJ0OkMsbGluZUVuZDpQLHBvbHlnb25TdGFydDp6LHBvbHlnb25FbmQ6dn07ZnVuY3Rpb24gUyhCLEkpe3MoQixJKSYmaC5wb2ludChCLEkpfWZ1bmN0aW9uIEUoKXtmb3IodmFyIEI9MCxJPTAsaz1kLmxlbmd0aDtJPGs7KytJKWZvcih2YXIgRD1kW0ldLFY9MSxqPUQubGVuZ3RoLGR0PURbMF0sRHQsR3QsWnQ9ZHRbMF0sbWU9ZHRbMV07VjxqOysrVilEdD1adCxHdD1tZSxkdD1EW1ZdLFp0PWR0WzBdLG1lPWR0WzFdLEd0PD1uP21lPm4mJihadC1EdCkqKG4tR3QpPihtZS1HdCkqKGktRHQpJiYrK0I6bWU8PW4mJihadC1EdCkqKG4tR3QpPChtZS1HdCkqKGktRHQpJiYtLUI7cmV0dXJuIEJ9ZnVuY3Rpb24geigpe2g9dSxmPVtdLGQ9W10sQT0hMH1mdW5jdGlvbiB2KCl7dmFyIEI9RSgpLEk9QSYmQixrPShmPURpKGYpKS5sZW5ndGg7KEl8fGspJiYobC5wb2x5Z29uU3RhcnQoKSxJJiYobC5saW5lU3RhcnQoKSxyKG51bGwsbnVsbCwxLGwpLGwubGluZUVuZCgpKSxrJiZnaChmLGEsQixyLGwpLGwucG9seWdvbkVuZCgpKSxoPWwsZj1kPXA9bnVsbH1mdW5jdGlvbiBDKCl7Xy5wb2ludD1GLGQmJmQucHVzaChwPVtdKSxNPSEwLHg9ITEsYj13PU5hTn1mdW5jdGlvbiBQKCl7ZiYmKEYoeSxtKSxnJiZ4JiZ1LnJlam9pbigpLGYucHVzaCh1LnJlc3VsdCgpKSksXy5wb2ludD1TLHgmJmgubGluZUVuZCgpfWZ1bmN0aW9uIEYoQixJKXt2YXIgaz1zKEIsSSk7aWYoZCYmcC5wdXNoKFtCLEldKSxNKXk9QixtPUksZz1rLE09ITEsayYmKGgubGluZVN0YXJ0KCksaC5wb2ludChCLEkpKTtlbHNlIGlmKGsmJngpaC5wb2ludChCLEkpO2Vsc2V7dmFyIEQ9W2I9TWF0aC5tYXgoTXIsTWF0aC5taW4ocWksYikpLHc9TWF0aC5tYXgoTXIsTWF0aC5taW4ocWksdykpXSxWPVtCPU1hdGgubWF4KE1yLE1hdGgubWluKHFpLEIpKSxJPU1hdGgubWF4KE1yLE1hdGgubWluKHFpLEkpKV07TXAoRCxWLGksdCxlLG4pPyh4fHwoaC5saW5lU3RhcnQoKSxoLnBvaW50KERbMF0sRFsxXSkpLGgucG9pbnQoVlswXSxWWzFdKSxrfHxoLmxpbmVFbmQoKSxBPSExKTprJiYoaC5saW5lU3RhcnQoKSxoLnBvaW50KEIsSSksQT0hMSl9Yj1CLHc9SSx4PWt9cmV0dXJuIF99fXZhciBJYSxrYSxBcixfcixpaT17c3BoZXJlOlN0LHBvaW50OlN0LGxpbmVTdGFydDpfcCxsaW5lRW5kOlN0LHBvbHlnb25TdGFydDpTdCxwb2x5Z29uRW5kOlN0fTtmdW5jdGlvbiBfcCgpe2lpLnBvaW50PXZwLGlpLmxpbmVFbmQ9U3B9ZnVuY3Rpb24gU3AoKXtpaS5wb2ludD1paS5saW5lRW5kPVN0fWZ1bmN0aW9uIHZwKGksdCl7aSo9SCx0Kj1ILGthPWksQXI9cSh0KSxfcj1XKHQpLGlpLnBvaW50PXpwfWZ1bmN0aW9uIHpwKGksdCl7aSo9SCx0Kj1IO3ZhciBlPXEodCksbj1XKHQpLHM9dHQoaS1rYSkscj1XKHMpLG89cShzKSxhPW4qbyxjPV9yKmUtQXIqbipyLGw9QXIqZStfcipuKnI7SWEuYWRkKHJlKExlKGEqYStjKmMpLGwpKSxrYT1pLEFyPWUsX3I9bn1mdW5jdGlvbiBUcChpKXtyZXR1cm4gSWE9bmV3IFJlLG9yKGksaWkpLCtJYX12YXIgTmE9W251bGwsbnVsbF0sRXA9e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOk5hfTtmdW5jdGlvbiBzaShpLHQpe3JldHVybiBOYVswXT1pLE5hWzFdPXQsVHAoRXApfXZhciBBaD17RmVhdHVyZTpmdW5jdGlvbihpLHQpe3JldHVybiBTcihpLmdlb21ldHJ5LHQpfSxGZWF0dXJlQ29sbGVjdGlvbjpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmZlYXR1cmVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoU3IoZVtuXS5nZW9tZXRyeSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19LF9oPXtTcGhlcmU6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sUG9pbnQ6ZnVuY3Rpb24oaSx0KXtyZXR1cm4gU2goaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2ludDpmdW5jdGlvbihpLHQpe2Zvcih2YXIgZT1pLmNvb3JkaW5hdGVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoU2goZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX0sTGluZVN0cmluZzpmdW5jdGlvbihpLHQpe3JldHVybiB2aChpLmNvb3JkaW5hdGVzLHQpfSxNdWx0aUxpbmVTdHJpbmc6ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5jb29yZGluYXRlcyxuPS0xLHM9ZS5sZW5ndGg7KytuPHM7KWlmKHZoKGVbbl0sdCkpcmV0dXJuITA7cmV0dXJuITF9LFBvbHlnb246ZnVuY3Rpb24oaSx0KXtyZXR1cm4gemgoaS5jb29yZGluYXRlcyx0KX0sTXVsdGlQb2x5Z29uOmZ1bmN0aW9uKGksdCl7Zm9yKHZhciBlPWkuY29vcmRpbmF0ZXMsbj0tMSxzPWUubGVuZ3RoOysrbjxzOylpZih6aChlW25dLHQpKXJldHVybiEwO3JldHVybiExfSxHZW9tZXRyeUNvbGxlY3Rpb246ZnVuY3Rpb24oaSx0KXtmb3IodmFyIGU9aS5nZW9tZXRyaWVzLG49LTEscz1lLmxlbmd0aDsrK248czspaWYoU3IoZVtuXSx0KSlyZXR1cm4hMDtyZXR1cm4hMX19O2Z1bmN0aW9uIFNyKGksdCl7cmV0dXJuIGkmJl9oLmhhc093blByb3BlcnR5KGkudHlwZSk/X2hbaS50eXBlXShpLHQpOiExfWZ1bmN0aW9uIFNoKGksdCl7cmV0dXJuIHNpKGksdCk9PT0wfWZ1bmN0aW9uIHZoKGksdCl7Zm9yKHZhciBlLG4scyxyPTAsbz1pLmxlbmd0aDtyPG87cisrKXtpZihuPXNpKGlbcl0sdCksbj09PTB8fHI+MCYmKHM9c2koaVtyXSxpW3ItMV0pLHM+MCYmZTw9cyYmbjw9cyYmKGUrbi1zKSooMS1NYXRoLnBvdygoZS1uKS9zLDIpKTxpcipzKSlyZXR1cm4hMDtlPW59cmV0dXJuITF9ZnVuY3Rpb24gemgoaSx0KXtyZXR1cm4hIXdoKGkubWFwKFBwKSxUaCh0KSl9ZnVuY3Rpb24gUHAoaSl7cmV0dXJuIGk9aS5tYXAoVGgpLGkucG9wKCksaX1mdW5jdGlvbiBUaChpKXtyZXR1cm5baVswXSpILGlbMV0qSF19ZnVuY3Rpb24gQ3AoaSx0KXtyZXR1cm4oaSYmQWguaGFzT3duUHJvcGVydHkoaS50eXBlKT9BaFtpLnR5cGVdOlNyKShpLHQpfWZ1bmN0aW9uIEJwKGksdCl7dmFyIGU9aVswXSpILG49aVsxXSpILHM9dFswXSpILHI9dFsxXSpILG89VyhuKSxhPXEobiksYz1XKHIpLGw9cShyKSxoPW8qVyhlKSx1PW8qcShlKSxmPWMqVyhzKSxkPWMqcShzKSxwPTIqT2UoTGUoVmwoci1uKStvKmMqVmwocy1lKSkpLHk9cShwKSxtPXA/ZnVuY3Rpb24oZyl7dmFyIGI9cShnKj1wKS95LHc9cShwLWcpL3kseD13KmgrYipmLE09dyp1K2IqZCxBPXcqYStiKmw7cmV0dXJuW3JlKE0seCkqaHQscmUoQSxMZSh4KngrTSpNKSkqaHRdfTpmdW5jdGlvbigpe3JldHVybltlKmh0LG4qaHRdfTtyZXR1cm4gbS5kaXN0YW5jZT1wLG19dmFyIEVoPWk9Pmkscmk9MS8wLHZyPXJpLEhpPS1yaSx6cj1IaSxQaD17cG9pbnQ6RnAsbGluZVN0YXJ0OlN0LGxpbmVFbmQ6U3QscG9seWdvblN0YXJ0OlN0LHBvbHlnb25FbmQ6U3QscmVzdWx0OmZ1bmN0aW9uKCl7dmFyIGk9W1tyaSx2cl0sW0hpLHpyXV07cmV0dXJuIEhpPXpyPS0odnI9cmk9MS8wKSxpfX07ZnVuY3Rpb24gRnAoaSx0KXtpPHJpJiYocmk9aSksaT5IaSYmKEhpPWkpLHQ8dnImJih2cj10KSx0PnpyJiYoenI9dCl9ZnVuY3Rpb24gUmEoaSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBMYTtmb3IodmFyIG4gaW4gaSllW25dPWlbbl07cmV0dXJuIGUuc3RyZWFtPXQsZX19ZnVuY3Rpb24gTGEoKXt9TGEucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpMYSxwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGksdCl9LHNwaGVyZTpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLnNwaGVyZSgpfSxsaW5lU3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5saW5lU3RhcnQoKX0sbGluZUVuZDpmdW5jdGlvbigpe3RoaXMuc3RyZWFtLmxpbmVFbmQoKX0scG9seWdvblN0YXJ0OmZ1bmN0aW9uKCl7dGhpcy5zdHJlYW0ucG9seWdvblN0YXJ0KCl9LHBvbHlnb25FbmQ6ZnVuY3Rpb24oKXt0aGlzLnN0cmVhbS5wb2x5Z29uRW5kKCl9fTtmdW5jdGlvbiBPYShpLHQsZSl7dmFyIG49aS5jbGlwRXh0ZW50JiZpLmNsaXBFeHRlbnQoKTtyZXR1cm4gaS5zY2FsZSgxNTApLnRyYW5zbGF0ZShbMCwwXSksbiE9bnVsbCYmaS5jbGlwRXh0ZW50KG51bGwpLG9yKGUsaS5zdHJlYW0oUGgpKSx0KFBoLnJlc3VsdCgpKSxuIT1udWxsJiZpLmNsaXBFeHRlbnQobiksaX1mdW5jdGlvbiBDaChpLHQsZSl7cmV0dXJuIE9hKGksZnVuY3Rpb24obil7dmFyIHM9dFsxXVswXS10WzBdWzBdLHI9dFsxXVsxXS10WzBdWzFdLG89TWF0aC5taW4ocy8oblsxXVswXS1uWzBdWzBdKSxyLyhuWzFdWzFdLW5bMF1bMV0pKSxhPSt0WzBdWzBdKyhzLW8qKG5bMV1bMF0rblswXVswXSkpLzIsYz0rdFswXVsxXSsoci1vKihuWzFdWzFdK25bMF1bMV0pKS8yO2kuc2NhbGUoMTUwKm8pLnRyYW5zbGF0ZShbYSxjXSl9LGUpfWZ1bmN0aW9uIElwKGksdCxlKXtyZXR1cm4gQ2goaSxbWzAsMF0sdF0sZSl9ZnVuY3Rpb24ga3AoaSx0LGUpe3JldHVybiBPYShpLGZ1bmN0aW9uKG4pe3ZhciBzPSt0LHI9cy8oblsxXVswXS1uWzBdWzBdKSxvPShzLXIqKG5bMV1bMF0rblswXVswXSkpLzIsYT0tcipuWzBdWzFdO2kuc2NhbGUoMTUwKnIpLnRyYW5zbGF0ZShbbyxhXSl9LGUpfWZ1bmN0aW9uIE5wKGksdCxlKXtyZXR1cm4gT2EoaSxmdW5jdGlvbihuKXt2YXIgcz0rdCxyPXMvKG5bMV1bMV0tblswXVsxXSksbz0tcipuWzBdWzBdLGE9KHMtciooblsxXVsxXStuWzBdWzFdKSkvMjtpLnNjYWxlKDE1MCpyKS50cmFuc2xhdGUoW28sYV0pfSxlKX12YXIgQmg9MTYsUnA9VygzMCpIKTtmdW5jdGlvbiBGaChpLHQpe3JldHVybit0P09wKGksdCk6THAoaSl9ZnVuY3Rpb24gTHAoaSl7cmV0dXJuIFJhKHtwb2ludDpmdW5jdGlvbih0LGUpe3Q9aSh0LGUpLHRoaXMuc3RyZWFtLnBvaW50KHRbMF0sdFsxXSl9fSl9ZnVuY3Rpb24gT3AoaSx0KXtmdW5jdGlvbiBlKG4scyxyLG8sYSxjLGwsaCx1LGYsZCxwLHksbSl7dmFyIGc9bC1uLGI9aC1zLHc9ZypnK2IqYjtpZih3PjQqdCYmeS0tKXt2YXIgeD1vK2YsTT1hK2QsQT1jK3AsXz1MZSh4KngrTSpNK0EqQSksUz1PZShBLz1fKSxFPXR0KHR0KEEpLTEpPEt8fHR0KHItdSk8Sz8ocit1KS8yOnJlKE0seCksej1pKEUsUyksdj16WzBdLEM9elsxXSxQPXYtbixGPUMtcyxCPWIqUC1nKkY7KEIqQi93PnR8fHR0KChnKlArYipGKS93LS41KT4uM3x8bypmK2EqZCtjKnA8UnApJiYoZShuLHMscixvLGEsYyx2LEMsRSx4Lz1fLE0vPV8sQSx5LG0pLG0ucG9pbnQodixDKSxlKHYsQyxFLHgsTSxBLGwsaCx1LGYsZCxwLHksbSkpfX1yZXR1cm4gZnVuY3Rpb24obil7dmFyIHMscixvLGEsYyxsLGgsdSxmLGQscCx5LG09e3BvaW50OmcsbGluZVN0YXJ0OmIsbGluZUVuZDp4LHBvbHlnb25TdGFydDpmdW5jdGlvbigpe24ucG9seWdvblN0YXJ0KCksbS5saW5lU3RhcnQ9TX0scG9seWdvbkVuZDpmdW5jdGlvbigpe24ucG9seWdvbkVuZCgpLG0ubGluZVN0YXJ0PWJ9fTtmdW5jdGlvbiBnKFMsRSl7Uz1pKFMsRSksbi5wb2ludChTWzBdLFNbMV0pfWZ1bmN0aW9uIGIoKXt1PU5hTixtLnBvaW50PXcsbi5saW5lU3RhcnQoKX1mdW5jdGlvbiB3KFMsRSl7dmFyIHo9QW4oW1MsRV0pLHY9aShTLEUpO2UodSxmLGgsZCxwLHksdT12WzBdLGY9dlsxXSxoPVMsZD16WzBdLHA9elsxXSx5PXpbMl0sQmgsbiksbi5wb2ludCh1LGYpfWZ1bmN0aW9uIHgoKXttLnBvaW50PWcsbi5saW5lRW5kKCl9ZnVuY3Rpb24gTSgpe2IoKSxtLnBvaW50PUEsbS5saW5lRW5kPV99ZnVuY3Rpb24gQShTLEUpe3cocz1TLEUpLHI9dSxvPWYsYT1kLGM9cCxsPXksbS5wb2ludD13fWZ1bmN0aW9uIF8oKXtlKHUsZixoLGQscCx5LHIsbyxzLGEsYyxsLEJoLG4pLG0ubGluZUVuZD14LHgoKX1yZXR1cm4gbX19dmFyIERwPVJhKHtwb2ludDpmdW5jdGlvbihpLHQpe3RoaXMuc3RyZWFtLnBvaW50KGkqSCx0KkgpfX0pO2Z1bmN0aW9uICRwKGkpe3JldHVybiBSYSh7cG9pbnQ6ZnVuY3Rpb24odCxlKXt2YXIgbj1pKHQsZSk7cmV0dXJuIHRoaXMuc3RyZWFtLnBvaW50KG5bMF0sblsxXSl9fSl9ZnVuY3Rpb24gVXAoaSx0LGUsbixzKXtmdW5jdGlvbiByKG8sYSl7cmV0dXJuIG8qPW4sYSo9cyxbdCtpKm8sZS1pKmFdfXJldHVybiByLmludmVydD1mdW5jdGlvbihvLGEpe3JldHVyblsoby10KS9pKm4sKGUtYSkvaSpzXX0scn1mdW5jdGlvbiBJaChpLHQsZSxuLHMscil7aWYoIXIpcmV0dXJuIFVwKGksdCxlLG4scyk7dmFyIG89VyhyKSxhPXEociksYz1vKmksbD1hKmksaD1vL2ksdT1hL2ksZj0oYSplLW8qdCkvaSxkPShhKnQrbyplKS9pO2Z1bmN0aW9uIHAoeSxtKXtyZXR1cm4geSo9bixtKj1zLFtjKnktbCptK3QsZS1sKnktYyptXX1yZXR1cm4gcC5pbnZlcnQ9ZnVuY3Rpb24oeSxtKXtyZXR1cm5bbiooaCp5LXUqbStmKSxzKihkLXUqeS1oKm0pXX0scH1mdW5jdGlvbiBUcihpKXtyZXR1cm4gVnAoZnVuY3Rpb24oKXtyZXR1cm4gaX0pKCl9ZnVuY3Rpb24gVnAoaSl7dmFyIHQsZT0xNTAsbj00ODAscz0yNTAscj0wLG89MCxhPTAsYz0wLGw9MCxoLHU9MCxmPTEsZD0xLHA9bnVsbCx5PU1oLG09bnVsbCxnLGIsdyx4PUVoLE09LjUsQSxfLFMsRSx6O2Z1bmN0aW9uIHYoQil7cmV0dXJuIFMoQlswXSpILEJbMV0qSCl9ZnVuY3Rpb24gQyhCKXtyZXR1cm4gQj1TLmludmVydChCWzBdLEJbMV0pLEImJltCWzBdKmh0LEJbMV0qaHRdfXYuc3RyZWFtPWZ1bmN0aW9uKEIpe3JldHVybiBFJiZ6PT09Qj9FOkU9RHAoJHAoaCkoeShBKHgoej1CKSkpKSl9LHYucHJlY2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeT1CLHA9dm9pZCAwLEYoKSk6eX0sdi5wb3N0Y2xpcD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CLG09Zz1iPXc9bnVsbCxGKCkpOnh9LHYuY2xpcEFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh5PStCP2JwKHA9QipIKToocD1udWxsLE1oKSxGKCkpOnAqaHR9LHYuY2xpcEV4dGVudD1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oeD1CPT1udWxsPyhtPWc9Yj13PW51bGwsRWgpOkFwKG09K0JbMF1bMF0sZz0rQlswXVsxXSxiPStCWzFdWzBdLHc9K0JbMV1bMV0pLEYoKSk6bT09bnVsbD9udWxsOltbbSxnXSxbYix3XV19LHYuc2NhbGU9ZnVuY3Rpb24oQil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGU9K0IsUCgpKTplfSx2LnRyYW5zbGF0ZT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obj0rQlswXSxzPStCWzFdLFAoKSk6W24sc119LHYuY2VudGVyPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhyPUJbMF0lMzYwKkgsbz1CWzFdJTM2MCpILFAoKSk6W3IqaHQsbypodF19LHYucm90YXRlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhhPUJbMF0lMzYwKkgsYz1CWzFdJTM2MCpILGw9Qi5sZW5ndGg+Mj9CWzJdJTM2MCpIOjAsUCgpKTpbYSpodCxjKmh0LGwqaHRdfSx2LmFuZ2xlPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyh1PUIlMzYwKkgsUCgpKTp1Kmh0fSx2LnJlZmxlY3RYPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhmPUI/LTE6MSxQKCkpOmY8MH0sdi5yZWZsZWN0WT1mdW5jdGlvbihCKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oZD1CPy0xOjEsUCgpKTpkPDB9LHYucHJlY2lzaW9uPWZ1bmN0aW9uKEIpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhBPUZoKF8sTT1CKkIpLEYoKSk6TGUoTSl9LHYuZml0RXh0ZW50PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIENoKHYsQixJKX0sdi5maXRTaXplPWZ1bmN0aW9uKEIsSSl7cmV0dXJuIElwKHYsQixJKX0sdi5maXRXaWR0aD1mdW5jdGlvbihCLEkpe3JldHVybiBrcCh2LEIsSSl9LHYuZml0SGVpZ2h0PWZ1bmN0aW9uKEIsSSl7cmV0dXJuIE5wKHYsQixJKX07ZnVuY3Rpb24gUCgpe3ZhciBCPUloKGUsMCwwLGYsZCx1KS5hcHBseShudWxsLHQocixvKSksST1JaChlLG4tQlswXSxzLUJbMV0sZixkLHUpO3JldHVybiBoPWhoKGEsYyxsKSxfPUNhKHQsSSksUz1DYShoLF8pLEE9RmgoXyxNKSxGKCl9ZnVuY3Rpb24gRigpe3JldHVybiBFPXo9bnVsbCx2fXJldHVybiBmdW5jdGlvbigpe3JldHVybiB0PWkuYXBwbHkodGhpcyxhcmd1bWVudHMpLHYuaW52ZXJ0PXQuaW52ZXJ0JiZDLFAoKX19ZnVuY3Rpb24gcXAoaSl7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7dmFyIG49TGUodCp0K2UqZSkscz1pKG4pLHI9cShzKSxvPVcocyk7cmV0dXJuW3JlKHQqcixuKm8pLE9lKG4mJmUqci9uKV19fWZ1bmN0aW9uIERhKGksdCl7cmV0dXJuW2ksSzAoZXAoKE50K3QpLzIpKV19RGEuaW52ZXJ0PWZ1bmN0aW9uKGksdCl7cmV0dXJuW2ksMip4YShRMCh0KSktTnRdfTtmdW5jdGlvbiBIcCgpe3JldHVybiBXcChEYSkuc2NhbGUoOTYxL1J0KX1mdW5jdGlvbiBXcChpKXt2YXIgdD1UcihpKSxlPXQuY2VudGVyLG49dC5zY2FsZSxzPXQudHJhbnNsYXRlLHI9dC5jbGlwRXh0ZW50LG89bnVsbCxhLGMsbDt0LnNjYWxlPWZ1bmN0aW9uKHUpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhuKHUpLGgoKSk6bigpfSx0LnRyYW5zbGF0ZT1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8ocyh1KSxoKCkpOnMoKX0sdC5jZW50ZXI9ZnVuY3Rpb24odSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGUodSksaCgpKTplKCl9LHQuY2xpcEV4dGVudD1mdW5jdGlvbih1KXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odT09bnVsbD9vPWE9Yz1sPW51bGw6KG89K3VbMF1bMF0sYT0rdVswXVsxXSxjPSt1WzFdWzBdLGw9K3VbMV1bMV0pLGgoKSk6bz09bnVsbD9udWxsOltbbyxhXSxbYyxsXV19O2Z1bmN0aW9uIGgoKXt2YXIgdT1YKm4oKSxmPXQocGgodC5yb3RhdGUoKSkuaW52ZXJ0KFswLDBdKSk7cmV0dXJuIHIobz09bnVsbD9bW2ZbMF0tdSxmWzFdLXVdLFtmWzBdK3UsZlsxXSt1XV06aT09PURhP1tbTWF0aC5tYXgoZlswXS11LG8pLGFdLFtNYXRoLm1pbihmWzBdK3UsYyksbF1dOltbbyxNYXRoLm1heChmWzFdLXUsYSldLFtjLE1hdGgubWluKGZbMV0rdSxsKV1dKX1yZXR1cm4gaCgpfWZ1bmN0aW9uICRhKGksdCl7cmV0dXJuW2ksdF19JGEuaW52ZXJ0PSRhO2Z1bmN0aW9uIEdwKCl7cmV0dXJuIFRyKCRhKS5zY2FsZSgxNTIuNjMpfWZ1bmN0aW9uIGtoKGksdCl7dmFyIGU9Vyh0KSxuPTErVyhpKSplO3JldHVybltlKnEoaSkvbixxKHQpL25dfWtoLmludmVydD1xcChmdW5jdGlvbihpKXtyZXR1cm4gMip4YShpKX0pO2Z1bmN0aW9uIFpwKCl7cmV0dXJuIFRyKGtoKS5zY2FsZSgyNTApLmNsaXBBbmdsZSgxNDIpfXZhciBYcD1NYXRoLmF0YW4sSnA9TWF0aC5jb3MsWXA9TWF0aC50YW4sanA9TWF0aC5QSSxRcD1qcC8xODA7ZnVuY3Rpb24gTmgoaSl7cmV0dXJuIGk+MD9NYXRoLnNxcnQoaSk6MH12YXIgRXI9SnAoMzUqUXApO2Z1bmN0aW9uIFJoKGksdCl7dmFyIGU9WXAodC8yKTtyZXR1cm5baSpFcipOaCgxLWUqZSksKDErRXIpKmVdfVJoLmludmVydD1mdW5jdGlvbihpLHQpe3ZhciBlPXQvKDErRXIpO3JldHVybltpJiZpLyhFcipOaCgxLWUqZSkpLDIqWHAoZSldfTtmdW5jdGlvbiBLcCgpe3JldHVybiBUcihSaCkuc2NhbGUoMTM3LjE1Mil9Y29uc3QgdHk9e21lcmNhdG9yOkhwLGVxdWlyZWN0YW5ndWxhcjpHcCxmYWhleTpLcH0sVWE9e30sV2k9aT0+e3ZhciBuLHMscjtjb25zdCB0PUpTT04uc3RyaW5naWZ5KGkpO2lmKFVhW3RdKXJldHVybiBVYVt0XTtjb25zdCBlPXR5WyhuPWkucHJvamVjdGlvblR5cGUpIT1udWxsP246Im1lcmNhdG9yIl0oKS5jZW50ZXIoaS5jZW50ZXIpLnNjYWxlKGkuc2NhbGUpLnRyYW5zbGF0ZSgocz1pLnRyYW5zbGF0ZSkhPW51bGw/czpbMCwwXSkucHJlY2lzaW9uKChyPWkucHJlY2lzaW9uKSE9bnVsbD9yOi4xKTtyZXR1cm4gaS5yb3RhdGUmJmUucm90YXRlKGkucm90YXRlKSxVYVt0XT1lLGV9LFByPShpLHQpPT5pLm1hcCgoW2Usbl0pPT57bGV0IHM7aWYodCl7Y29uc3RbcixvXT10KFtlLG5dKTtzPW5ldyBSKHIsLW8pfWVsc2Ugcz1uZXcgUihlLG4pO3JldHVybiBzfSk7dmFyIEdpPShpLHQpPT57Y29uc3QgZT0kbChpLHQhPW51bGw/dDowKSxuPXt9LHM9W10scj1PYmplY3Qua2V5cyhlLmF0dHJpYnV0ZXMpO3JldHVybiBlLmluZGV4JiZyLnB1c2goImluZGV4Iiksci5mb3JFYWNoKG89Pntjb25zdCBhPW89PT0iaW5kZXgiP2UuaW5kZXg6ZS5hdHRyaWJ1dGVzW29dO25bb109e2FycmF5OmEuYXJyYXksaXRlbVNpemU6YS5pdGVtU2l6ZX0scy5wdXNoKGEuYXJyYXkuYnVmZmVyKX0pLHQmJihuLmdyb3Vwcz1lLmdyb3VwcyksZS5kaXNwb3NlKCksaS5mb3JFYWNoKG89PntvLmRpc3Bvc2UoKX0pLHttZXNzYWdlOm4sdHJhbnNmZXI6c319LFZhPShpLHQ9MzAwKT0+e2NvbnN0IGU9W107cmV0dXJuIGkuZm9yRWFjaChuPT57bGV0IHM9ITE7Zm9yKGxldCByPTE7cjxuLmxlbmd0aDtyKyspaWYoTWF0aC5hYnMobltyXS54LW5bci0xXS54KT50KXtzPSEwO2JyZWFrfWlmKHMpe2NvbnN0IHI9W10sbz1bXTtuLmZvckVhY2goYT0+e2EueDwwP3IucHVzaChhKTpvLnB1c2goYSl9KSxlLnB1c2gocixvKX1lbHNlIGUucHVzaChuKX0pLGV9O2NvbnN0IGV5PSh7Y29vcmRpbmF0ZXNBcnI6aSxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxiYm94Om4sYmJveE9mZnNldDpzLGRlcHRoOnIscHJvamVjdGlvbjpvLHVzZUdyb3VwczphLGhhc1RvcDpjLGhhc0JvdHRvbTpsLGhhc1NpZGU6aCxzcGxpdFBvbHlnb25zOnUsdG9wU2VnbWVudHM6Zn0pPT57Y29uc3QgZD1vJiZXaShvKTtsZXQgcD1pLm1hcChnPT5QcihnLGQpKTt1JiYocD1WYShwLHUpKTtsZXQgeTtpZihuKXtjb25zdFtnLGJdPVByKFtbblswXSxuWzFdXSxbblsyXSxuWzNdXV0sbyE9bnVsbCYmby5yb3RhdGU/V2koR2UoRnQoe30sbykse3JvdGF0ZTp2b2lkIDB9KSk6ZCk7cyYmKGcueCs9c1swXSxnLnkrPXNbMV0sYi54Kz1zWzJdLGIueSs9c1szXSkseT1uZXcgZ3QobmV3IFQoZy54LGcueSwwKSxuZXcgVChiLngsYi55LDApKX1jb25zdCBtPXAubWFwKChnLGIpPT57dmFyIHc7cmV0dXJuIEQwKHtwb2ludHM6ZyxzcGxpdDp0LHNpZGVSZXBlYXQ6ZSxkZXB0aDoodz1yW2JdKSE9bnVsbD93OnJbMF0saGFzVG9wOmMsaGFzQm90dG9tOmwsaGFzU2lkZTpoLGJveDM6eSx0b3BTZWdtZW50czpmfSl9KTtyZXR1cm4gR2kobSxhKX07ZnVuY3Rpb24gcWEoaSx0LGUsbixzKXtsZXQgcjtpZihpPWkuc3ViYXJyYXl8fGkuc2xpY2U/aTppLmJ1ZmZlcixlPWUuc3ViYXJyYXl8fGUuc2xpY2U/ZTplLmJ1ZmZlcixpPXQ/aS5zdWJhcnJheT9pLnN1YmFycmF5KHQscyYmdCtzKTppLnNsaWNlKHQscyYmdCtzKTppLGUuc2V0KWUuc2V0KGksbik7ZWxzZSBmb3Iocj0wO3I8aS5sZW5ndGg7cisrKWVbcituXT1pW3JdO3JldHVybiBlfWZ1bmN0aW9uIG55KGkpe3JldHVybiBpIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5P2k6aSBpbnN0YW5jZW9mIHVlP2kuZ2V0QXR0cmlidXRlKCJwb3NpdGlvbiIpLmFycmF5OmkubWFwKHQ9Pntjb25zdCBlPUFycmF5LmlzQXJyYXkodCk7cmV0dXJuIHQgaW5zdGFuY2VvZiBUP1t0LngsdC55LHQuel06dCBpbnN0YW5jZW9mIFI/W3QueCx0LnksMF06ZSYmdC5sZW5ndGg9PT0zP1t0WzBdLHRbMV0sdFsyXV06ZSYmdC5sZW5ndGg9PT0yP1t0WzBdLHRbMV0sMF06dH0pLmZsYXQoKX1jbGFzcyBpeSBleHRlbmRzIHVle2NvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLnR5cGU9Ik1lc2hMaW5lIix0aGlzLmlzTWVzaExpbmU9ITAsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdLHRoaXMuY291bnRlcnM9W10sdGhpcy53aWR0aENhbGxiYWNrPW51bGwsdGhpcy5fcG9pbnRzPVtdLHRoaXMubWF0cml4V29ybGQ9bmV3IHN0LE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMse3BvaW50czp7ZW51bWVyYWJsZTohMCxnZXQoKXtyZXR1cm4gdGhpcy5fcG9pbnRzfSxzZXQodCl7dGhpcy5zZXRQb2ludHModCx0aGlzLndpZHRoQ2FsbGJhY2spfX19KX1zZXRNYXRyaXhXb3JsZCh0KXt0aGlzLm1hdHJpeFdvcmxkPXR9c2V0UG9pbnRzKHQsZSl7aWYodD1ueSh0KSx0aGlzLl9wb2ludHM9dCx0aGlzLndpZHRoQ2FsbGJhY2s9ZSE9bnVsbD9lOm51bGwsdGhpcy5wb3NpdGlvbnM9W10sdGhpcy5jb3VudGVycz1bXSx0Lmxlbmd0aCYmdFswXWluc3RhbmNlb2YgVClmb3IobGV0IG49MDtuPHQubGVuZ3RoO24rKyl7Y29uc3Qgcz10W25dLHI9bi8odC5sZW5ndGgtMSk7dGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5wb3NpdGlvbnMucHVzaChzLngscy55LHMueiksdGhpcy5jb3VudGVycy5wdXNoKHIpLHRoaXMuY291bnRlcnMucHVzaChyKX1lbHNlIGZvcihsZXQgbj0wO248dC5sZW5ndGg7bis9Myl7Y29uc3Qgcz1uLyh0Lmxlbmd0aC0xKTt0aGlzLnBvc2l0aW9ucy5wdXNoKHRbbl0sdFtuKzFdLHRbbisyXSksdGhpcy5wb3NpdGlvbnMucHVzaCh0W25dLHRbbisxXSx0W24rMl0pLHRoaXMuY291bnRlcnMucHVzaChzKSx0aGlzLmNvdW50ZXJzLnB1c2gocyl9dGhpcy5wcm9jZXNzKCl9Y29tcGFyZVYzKHQsZSl7Y29uc3Qgbj10KjYscz1lKjY7cmV0dXJuIHRoaXMucG9zaXRpb25zW25dPT09dGhpcy5wb3NpdGlvbnNbc10mJnRoaXMucG9zaXRpb25zW24rMV09PT10aGlzLnBvc2l0aW9uc1tzKzFdJiZ0aGlzLnBvc2l0aW9uc1tuKzJdPT09dGhpcy5wb3NpdGlvbnNbcysyXX1jb3B5VjModCl7Y29uc3QgZT10KjY7cmV0dXJuW3RoaXMucG9zaXRpb25zW2VdLHRoaXMucG9zaXRpb25zW2UrMV0sdGhpcy5wb3NpdGlvbnNbZSsyXV19cHJvY2Vzcygpe2NvbnN0IHQ9dGhpcy5wb3NpdGlvbnMubGVuZ3RoLzY7dGhpcy5wcmV2aW91cz1bXSx0aGlzLm5leHQ9W10sdGhpcy5zaWRlPVtdLHRoaXMud2lkdGg9W10sdGhpcy5pbmRpY2VzX2FycmF5PVtdLHRoaXMudXZzPVtdO2xldCBlLG47dGhpcy5jb21wYXJlVjMoMCx0LTEpP249dGhpcy5jb3B5VjModC0yKTpuPXRoaXMuY29weVYzKDApLHRoaXMucHJldmlvdXMucHVzaChuWzBdLG5bMV0sblsyXSksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKTtmb3IobGV0IHM9MDtzPHQ7cysrKXtpZih0aGlzLnNpZGUucHVzaCgxKSx0aGlzLnNpZGUucHVzaCgtMSksdGhpcy53aWR0aENhbGxiYWNrP2U9dGhpcy53aWR0aENhbGxiYWNrKHMvKHQtMSkpOmU9MSx0aGlzLndpZHRoLnB1c2goZSksdGhpcy53aWR0aC5wdXNoKGUpLHRoaXMudXZzLnB1c2gocy8odC0xKSwwKSx0aGlzLnV2cy5wdXNoKHMvKHQtMSksMSksczx0LTEpe249dGhpcy5jb3B5VjMocyksdGhpcy5wcmV2aW91cy5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLnByZXZpb3VzLnB1c2goblswXSxuWzFdLG5bMl0pO2NvbnN0IHI9cyoyO3RoaXMuaW5kaWNlc19hcnJheS5wdXNoKHIscisxLHIrMiksdGhpcy5pbmRpY2VzX2FycmF5LnB1c2gocisyLHIrMSxyKzMpfXM+MCYmKG49dGhpcy5jb3B5VjMocyksdGhpcy5uZXh0LnB1c2goblswXSxuWzFdLG5bMl0pLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSl9dGhpcy5jb21wYXJlVjModC0xLDApP249dGhpcy5jb3B5VjMoMSk6bj10aGlzLmNvcHlWMyh0LTEpLHRoaXMubmV4dC5wdXNoKG5bMF0sblsxXSxuWzJdKSx0aGlzLm5leHQucHVzaChuWzBdLG5bMV0sblsyXSksIXRoaXMuX2F0dHJpYnV0ZXN8fHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24uY291bnQhPT10aGlzLmNvdW50ZXJzLmxlbmd0aD90aGlzLl9hdHRyaWJ1dGVzPXtwb3NpdGlvbjpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucyksMykscHJldmlvdXM6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wcmV2aW91cyksMyksbmV4dDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLm5leHQpLDMpLHNpZGU6bmV3IHh0KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaWRlKSwxKSx3aWR0aDpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSwxKSx1djpuZXcgeHQobmV3IEZsb2F0MzJBcnJheSh0aGlzLnV2cyksMiksaW5kZXg6bmV3IHh0KG5ldyBVaW50MTZBcnJheSh0aGlzLmluZGljZXNfYXJyYXkpLDEpLGNvdW50ZXJzOm5ldyB4dChuZXcgRmxvYXQzMkFycmF5KHRoaXMuY291bnRlcnMpLDEpfToodGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnBvc2l0aW9ucykpLHRoaXMuX2F0dHJpYnV0ZXMucG9zaXRpb24ubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnByZXZpb3VzKSksdGhpcy5fYXR0cmlidXRlcy5wcmV2aW91cy5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLm5leHQuY29weUFycmF5KG5ldyBGbG9hdDMyQXJyYXkodGhpcy5uZXh0KSksdGhpcy5fYXR0cmlidXRlcy5uZXh0Lm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMuc2lkZS5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLnNpZGUpKSx0aGlzLl9hdHRyaWJ1dGVzLnNpZGUubmVlZHNVcGRhdGU9ITAsdGhpcy5fYXR0cmlidXRlcy53aWR0aC5jb3B5QXJyYXkobmV3IEZsb2F0MzJBcnJheSh0aGlzLndpZHRoKSksdGhpcy5fYXR0cmlidXRlcy53aWR0aC5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnV2LmNvcHlBcnJheShuZXcgRmxvYXQzMkFycmF5KHRoaXMudXZzKSksdGhpcy5fYXR0cmlidXRlcy51di5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLmluZGV4LmNvcHlBcnJheShuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzX2FycmF5KSksdGhpcy5fYXR0cmlidXRlcy5pbmRleC5uZWVkc1VwZGF0ZT0hMCksdGhpcy5zZXRBdHRyaWJ1dGUoInBvc2l0aW9uIix0aGlzLl9hdHRyaWJ1dGVzLnBvc2l0aW9uKSx0aGlzLnNldEF0dHJpYnV0ZSgicHJldmlvdXMiLHRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMpLHRoaXMuc2V0QXR0cmlidXRlKCJuZXh0Iix0aGlzLl9hdHRyaWJ1dGVzLm5leHQpLHRoaXMuc2V0QXR0cmlidXRlKCJzaWRlIix0aGlzLl9hdHRyaWJ1dGVzLnNpZGUpLHRoaXMuc2V0QXR0cmlidXRlKCJ3aWR0aCIsdGhpcy5fYXR0cmlidXRlcy53aWR0aCksdGhpcy5zZXRBdHRyaWJ1dGUoInV2Iix0aGlzLl9hdHRyaWJ1dGVzLnV2KSx0aGlzLnNldEF0dHJpYnV0ZSgiY291bnRlcnMiLHRoaXMuX2F0dHJpYnV0ZXMuY291bnRlcnMpLHRoaXMuc2V0QXR0cmlidXRlKCJwb3NpdGlvbiIsdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbiksdGhpcy5zZXRBdHRyaWJ1dGUoInByZXZpb3VzIix0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzKSx0aGlzLnNldEF0dHJpYnV0ZSgibmV4dCIsdGhpcy5fYXR0cmlidXRlcy5uZXh0KSx0aGlzLnNldEF0dHJpYnV0ZSgic2lkZSIsdGhpcy5fYXR0cmlidXRlcy5zaWRlKSx0aGlzLnNldEF0dHJpYnV0ZSgid2lkdGgiLHRoaXMuX2F0dHJpYnV0ZXMud2lkdGgpLHRoaXMuc2V0QXR0cmlidXRlKCJ1diIsdGhpcy5fYXR0cmlidXRlcy51diksdGhpcy5zZXRBdHRyaWJ1dGUoImNvdW50ZXJzIix0aGlzLl9hdHRyaWJ1dGVzLmNvdW50ZXJzKSx0aGlzLnNldEluZGV4KHRoaXMuX2F0dHJpYnV0ZXMuaW5kZXgpLHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCksdGhpcy5jb21wdXRlQm91bmRpbmdCb3goKX1hZHZhbmNlKHt4OnQseTplLHo6bn0pe2NvbnN0IHM9dGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5hcnJheSxyPXRoaXMuX2F0dHJpYnV0ZXMucHJldmlvdXMuYXJyYXksbz10aGlzLl9hdHRyaWJ1dGVzLm5leHQuYXJyYXksYT1zLmxlbmd0aDtxYShzLDAsciwwLGEpLHFhKHMsNixzLDAsYS02KSxzW2EtNl09dCxzW2EtNV09ZSxzW2EtNF09bixzW2EtM109dCxzW2EtMl09ZSxzW2EtMV09bixxYShzLDYsbywwLGEtNiksb1thLTZdPXQsb1thLTVdPWUsb1thLTRdPW4sb1thLTNdPXQsb1thLTJdPWUsb1thLTFdPW4sdGhpcy5fYXR0cmlidXRlcy5wb3NpdGlvbi5uZWVkc1VwZGF0ZT0hMCx0aGlzLl9hdHRyaWJ1dGVzLnByZXZpb3VzLm5lZWRzVXBkYXRlPSEwLHRoaXMuX2F0dHJpYnV0ZXMubmV4dC5uZWVkc1VwZGF0ZT0hMH19dmFyIExoPWk9Pntjb25zdHtzZXRQb2ludFdpZHRoOnQsbm9kZXM6ZX09aSxuPW5ldyBpeTtyZXR1cm4gbi5zZXRQb2ludHMoZSx0KSxufTtjb25zdCBzeT0oe2Nvb3JkaW5hdGVzQXJyOmkscHJvamVjdGlvbjp0LGxpbmVXaWR0aDplLHVzZUdyb3VwczpuLHNwbGl0UG9seWdvbnM6c30pPT57Y29uc3Qgcj10JiZXaSh0KTtsZXQgbz1pLm1hcChjPT5QcihjLHIpKTtzJiYobz1WYShvLHMpKTtjb25zdCBhPW8ubWFwKChjLGwpPT57dmFyIHU7Y29uc3QgaD0odT1lW2xdKSE9bnVsbD91OmVbMF07cmV0dXJuIExoKHtub2RlczpjLHNldFBvaW50V2lkdGg6KCk9Pmh9KX0pO3JldHVybiBHaShhLG4pfTt2YXIgcnk9aT0+e2NvbnN0e3BvaW50czp0fT1pLGU9dC5yZWR1Y2UoKHMscixvKT0+KG88dC5sZW5ndGgtMSYmcy5wdXNoKHIsdFtvKzFdKSxzKSxbXSk7cmV0dXJuIG5ldyB1ZSgpLnNldEZyb21Qb2ludHMoZSl9O2NvbnN0IG95PSh7Y29vcmRpbmF0ZXNBcnI6aSxwcm9qZWN0aW9uOnQsbGluZVdpZHRoOmUsdXNlR3JvdXBzOm4sc3BsaXRQb2x5Z29uczpzfSk9Pntjb25zdCByPXQmJldpKHQpO2xldCBvPWkubWFwKGM9PlByKGMscikpO3MmJihvPVZhKG8scykpO2NvbnN0IGE9by5tYXAoKGMsbCk9PnJ5KHtwb2ludHM6Yy5tYXAoaD0+bmV3IFQoaC54LGgueSwwKSl9KSk7cmV0dXJuIEdpKGEsbil9O2Z1bmN0aW9uIGF5KGksdCxlPTIpe2NvbnN0IG49dCYmdC5sZW5ndGgscz1uP3RbMF0qZTppLmxlbmd0aDtsZXQgcj1PaChpLDAscyxlLCEwKTtjb25zdCBvPVtdO2lmKCFyfHxyLm5leHQ9PT1yLnByZXYpcmV0dXJuIG87bGV0IGEsYyxsO2lmKG4mJihyPWZ5KGksdCxyLGUpKSxpLmxlbmd0aD44MCplKXthPTEvMCxjPTEvMDtsZXQgaD0tMS8wLHU9LTEvMDtmb3IobGV0IGY9ZTtmPHM7Zis9ZSl7Y29uc3QgZD1pW2ZdLHA9aVtmKzFdO2Q8YSYmKGE9ZCkscDxjJiYoYz1wKSxkPmgmJihoPWQpLHA+dSYmKHU9cCl9bD1NYXRoLm1heChoLWEsdS1jKSxsPWwhPT0wPzMyNzY3L2w6MH1yZXR1cm4gWmkocixvLGUsYSxjLGwsMCksb31mdW5jdGlvbiBPaChpLHQsZSxuLHMpe2xldCByO2lmKHM9PT1feShpLHQsZSxuKT4wKWZvcihsZXQgbz10O288ZTtvKz1uKXI9VWgoby9ufDAsaVtvXSxpW28rMV0scik7ZWxzZSBmb3IobGV0IG89ZS1uO28+PXQ7by09bilyPVVoKG8vbnwwLGlbb10saVtvKzFdLHIpO3JldHVybiByJiZDcihyLHIubmV4dCkmJihKaShyKSxyPXIubmV4dCkscn1mdW5jdGlvbiBTbihpLHQpe2lmKCFpKXJldHVybiBpO3R8fCh0PWkpO2xldCBlPWksbjtkbyBpZihuPSExLCFlLnN0ZWluZXImJihDcihlLGUubmV4dCl8fGF0KGUucHJldixlLGUubmV4dCk9PT0wKSl7aWYoSmkoZSksZT10PWUucHJldixlPT09ZS5uZXh0KWJyZWFrO249ITB9ZWxzZSBlPWUubmV4dDt3aGlsZShufHxlIT09dCk7cmV0dXJuIHR9ZnVuY3Rpb24gWmkoaSx0LGUsbixzLHIsbyl7aWYoIWkpcmV0dXJuOyFvJiZyJiZneShpLG4scyxyKTtsZXQgYT1pO2Zvcig7aS5wcmV2IT09aS5uZXh0Oyl7Y29uc3QgYz1pLnByZXYsbD1pLm5leHQ7aWYocj9seShpLG4scyxyKTpjeShpKSl7dC5wdXNoKGMuaSxpLmksbC5pKSxKaShpKSxpPWwubmV4dCxhPWwubmV4dDtjb250aW51ZX1pZihpPWwsaT09PWEpe28/bz09PTE/KGk9aHkoU24oaSksdCksWmkoaSx0LGUsbixzLHIsMikpOm89PT0yJiZ1eShpLHQsZSxuLHMscik6WmkoU24oaSksdCxlLG4scyxyLDEpO2JyZWFrfX19ZnVuY3Rpb24gY3koaSl7Y29uc3QgdD1pLnByZXYsZT1pLG49aS5uZXh0O2lmKGF0KHQsZSxuKT49MClyZXR1cm4hMTtjb25zdCBzPXQueCxyPWUueCxvPW4ueCxhPXQueSxjPWUueSxsPW4ueSxoPXM8cj9zPG8/czpvOnI8bz9yOm8sdT1hPGM/YTxsP2E6bDpjPGw/YzpsLGY9cz5yP3M+bz9zOm86cj5vP3I6byxkPWE+Yz9hPmw/YTpsOmM+bD9jOmw7bGV0IHA9bi5uZXh0O2Zvcig7cCE9PXQ7KXtpZihwLng+PWgmJnAueDw9ZiYmcC55Pj11JiZwLnk8PWQmJm9pKHMsYSxyLGMsbyxsLHAueCxwLnkpJiZhdChwLnByZXYscCxwLm5leHQpPj0wKXJldHVybiExO3A9cC5uZXh0fXJldHVybiEwfWZ1bmN0aW9uIGx5KGksdCxlLG4pe2NvbnN0IHM9aS5wcmV2LHI9aSxvPWkubmV4dDtpZihhdChzLHIsbyk+PTApcmV0dXJuITE7Y29uc3QgYT1zLngsYz1yLngsbD1vLngsaD1zLnksdT1yLnksZj1vLnksZD1hPGM/YTxsP2E6bDpjPGw/YzpsLHA9aDx1P2g8Zj9oOmY6dTxmP3U6Zix5PWE+Yz9hPmw/YTpsOmM+bD9jOmwsbT1oPnU/aD5mP2g6Zjp1PmY/dTpmLGc9SGEoZCxwLHQsZSxuKSxiPUhhKHksbSx0LGUsbik7bGV0IHc9aS5wcmV2Wix4PWkubmV4dFo7Zm9yKDt3JiZ3Lno+PWcmJngmJnguejw9Yjspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZvaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MHx8KHc9dy5wcmV2Wix4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmb2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApKXJldHVybiExO3g9eC5uZXh0Wn1mb3IoO3cmJncuej49Zzspe2lmKHcueD49ZCYmdy54PD15JiZ3Lnk+PXAmJncueTw9bSYmdyE9PXMmJnchPT1vJiZvaShhLGgsYyx1LGwsZix3Lngsdy55KSYmYXQody5wcmV2LHcsdy5uZXh0KT49MClyZXR1cm4hMTt3PXcucHJldlp9Zm9yKDt4JiZ4Lno8PWI7KXtpZih4Lng+PWQmJngueDw9eSYmeC55Pj1wJiZ4Lnk8PW0mJnghPT1zJiZ4IT09byYmb2koYSxoLGMsdSxsLGYseC54LHgueSkmJmF0KHgucHJldix4LHgubmV4dCk+PTApcmV0dXJuITE7eD14Lm5leHRafXJldHVybiEwfWZ1bmN0aW9uIGh5KGksdCl7bGV0IGU9aTtkb3tjb25zdCBuPWUucHJldixzPWUubmV4dC5uZXh0OyFDcihuLHMpJiZEaChuLGUsZS5uZXh0LHMpJiZYaShuLHMpJiZYaShzLG4pJiYodC5wdXNoKG4uaSxlLmkscy5pKSxKaShlKSxKaShlLm5leHQpLGU9aT1zKSxlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuIFNuKGUpfWZ1bmN0aW9uIHV5KGksdCxlLG4scyxyKXtsZXQgbz1pO2Rve2xldCBhPW8ubmV4dC5uZXh0O2Zvcig7YSE9PW8ucHJldjspe2lmKG8uaSE9PWEuaSYmYnkobyxhKSl7bGV0IGM9JGgobyxhKTtvPVNuKG8sby5uZXh0KSxjPVNuKGMsYy5uZXh0KSxaaShvLHQsZSxuLHMsciwwKSxaaShjLHQsZSxuLHMsciwwKTtyZXR1cm59YT1hLm5leHR9bz1vLm5leHR9d2hpbGUobyE9PWkpfWZ1bmN0aW9uIGZ5KGksdCxlLG4pe2NvbnN0IHM9W107Zm9yKGxldCByPTAsbz10Lmxlbmd0aDtyPG87cisrKXtjb25zdCBhPXRbcl0qbixjPXI8by0xP3RbcisxXSpuOmkubGVuZ3RoLGw9T2goaSxhLGMsbiwhMSk7bD09PWwubmV4dCYmKGwuc3RlaW5lcj0hMCkscy5wdXNoKHd5KGwpKX1zLnNvcnQoZHkpO2ZvcihsZXQgcj0wO3I8cy5sZW5ndGg7cisrKWU9cHkoc1tyXSxlKTtyZXR1cm4gZX1mdW5jdGlvbiBkeShpLHQpe3JldHVybiBpLngtdC54fWZ1bmN0aW9uIHB5KGksdCl7Y29uc3QgZT15eShpLHQpO2lmKCFlKXJldHVybiB0O2NvbnN0IG49JGgoZSxpKTtyZXR1cm4gU24obixuLm5leHQpLFNuKGUsZS5uZXh0KX1mdW5jdGlvbiB5eShpLHQpe2xldCBlPXQ7Y29uc3Qgbj1pLngscz1pLnk7bGV0IHI9LTEvMCxvO2Rve2lmKHM8PWUueSYmcz49ZS5uZXh0LnkmJmUubmV4dC55IT09ZS55KXtjb25zdCB1PWUueCsocy1lLnkpKihlLm5leHQueC1lLngpLyhlLm5leHQueS1lLnkpO2lmKHU8PW4mJnU+ciYmKHI9dSxvPWUueDxlLm5leHQueD9lOmUubmV4dCx1PT09bikpcmV0dXJuIG99ZT1lLm5leHR9d2hpbGUoZSE9PXQpO2lmKCFvKXJldHVybiBudWxsO2NvbnN0IGE9byxjPW8ueCxsPW8ueTtsZXQgaD0xLzA7ZT1vO2Rve2lmKG4+PWUueCYmZS54Pj1jJiZuIT09ZS54JiZvaShzPGw/bjpyLHMsYyxsLHM8bD9yOm4scyxlLngsZS55KSl7Y29uc3QgdT1NYXRoLmFicyhzLWUueSkvKG4tZS54KTtYaShlLGkpJiYodTxofHx1PT09aCYmKGUueD5vLnh8fGUueD09PW8ueCYmbXkobyxlKSkpJiYobz1lLGg9dSl9ZT1lLm5leHR9d2hpbGUoZSE9PWEpO3JldHVybiBvfWZ1bmN0aW9uIG15KGksdCl7cmV0dXJuIGF0KGkucHJldixpLHQucHJldik8MCYmYXQodC5uZXh0LGksaS5uZXh0KTwwfWZ1bmN0aW9uIGd5KGksdCxlLG4pe2xldCBzPWk7ZG8gcy56PT09MCYmKHMuej1IYShzLngscy55LHQsZSxuKSkscy5wcmV2Wj1zLnByZXYscy5uZXh0Wj1zLm5leHQscz1zLm5leHQ7d2hpbGUocyE9PWkpO3MucHJldloubmV4dFo9bnVsbCxzLnByZXZaPW51bGwseHkocyl9ZnVuY3Rpb24geHkoaSl7bGV0IHQsZT0xO2Rve2xldCBuPWkscztpPW51bGw7bGV0IHI9bnVsbDtmb3IodD0wO247KXt0Kys7bGV0IG89bixhPTA7Zm9yKGxldCBsPTA7bDxlJiYoYSsrLG89by5uZXh0WiwhIW8pO2wrKyk7bGV0IGM9ZTtmb3IoO2E+MHx8Yz4wJiZvOylhIT09MCYmKGM9PT0wfHwhb3x8bi56PD1vLnopPyhzPW4sbj1uLm5leHRaLGEtLSk6KHM9byxvPW8ubmV4dFosYy0tKSxyP3IubmV4dFo9czppPXMscy5wcmV2Wj1yLHI9cztuPW99ci5uZXh0Wj1udWxsLGUqPTJ9d2hpbGUodD4xKTtyZXR1cm4gaX1mdW5jdGlvbiBIYShpLHQsZSxuLHMpe3JldHVybiBpPShpLWUpKnN8MCx0PSh0LW4pKnN8MCxpPShpfGk8PDgpJjE2NzExOTM1LGk9KGl8aTw8NCkmMjUyNjQ1MTM1LGk9KGl8aTw8MikmODU4OTkzNDU5LGk9KGl8aTw8MSkmMTQzMTY1NTc2NSx0PSh0fHQ8PDgpJjE2NzExOTM1LHQ9KHR8dDw8NCkmMjUyNjQ1MTM1LHQ9KHR8dDw8MikmODU4OTkzNDU5LHQ9KHR8dDw8MSkmMTQzMTY1NTc2NSxpfHQ8PDF9ZnVuY3Rpb24gd3koaSl7bGV0IHQ9aSxlPWk7ZG8odC54PGUueHx8dC54PT09ZS54JiZ0Lnk8ZS55KSYmKGU9dCksdD10Lm5leHQ7d2hpbGUodCE9PWkpO3JldHVybiBlfWZ1bmN0aW9uIG9pKGksdCxlLG4scyxyLG8sYSl7cmV0dXJuKHMtbykqKHQtYSk+PShpLW8pKihyLWEpJiYoaS1vKSoobi1hKT49KGUtbykqKHQtYSkmJihlLW8pKihyLWEpPj0ocy1vKSoobi1hKX1mdW5jdGlvbiBieShpLHQpe3JldHVybiBpLm5leHQuaSE9PXQuaSYmaS5wcmV2LmkhPT10LmkmJiFNeShpLHQpJiYoWGkoaSx0KSYmWGkodCxpKSYmQXkoaSx0KSYmKGF0KGkucHJldixpLHQucHJldil8fGF0KGksdC5wcmV2LHQpKXx8Q3IoaSx0KSYmYXQoaS5wcmV2LGksaS5uZXh0KT4wJiZhdCh0LnByZXYsdCx0Lm5leHQpPjApfWZ1bmN0aW9uIGF0KGksdCxlKXtyZXR1cm4odC55LWkueSkqKGUueC10LngpLSh0LngtaS54KSooZS55LXQueSl9ZnVuY3Rpb24gQ3IoaSx0KXtyZXR1cm4gaS54PT09dC54JiZpLnk9PT10Lnl9ZnVuY3Rpb24gRGgoaSx0LGUsbil7Y29uc3Qgcz1GcihhdChpLHQsZSkpLHI9RnIoYXQoaSx0LG4pKSxvPUZyKGF0KGUsbixpKSksYT1GcihhdChlLG4sdCkpO3JldHVybiEhKHMhPT1yJiZvIT09YXx8cz09PTAmJkJyKGksZSx0KXx8cj09PTAmJkJyKGksbix0KXx8bz09PTAmJkJyKGUsaSxuKXx8YT09PTAmJkJyKGUsdCxuKSl9ZnVuY3Rpb24gQnIoaSx0LGUpe3JldHVybiB0Lng8PU1hdGgubWF4KGkueCxlLngpJiZ0Lng+PU1hdGgubWluKGkueCxlLngpJiZ0Lnk8PU1hdGgubWF4KGkueSxlLnkpJiZ0Lnk+PU1hdGgubWluKGkueSxlLnkpfWZ1bmN0aW9uIEZyKGkpe3JldHVybiBpPjA/MTppPDA/LTE6MH1mdW5jdGlvbiBNeShpLHQpe2xldCBlPWk7ZG97aWYoZS5pIT09aS5pJiZlLm5leHQuaSE9PWkuaSYmZS5pIT09dC5pJiZlLm5leHQuaSE9PXQuaSYmRGgoZSxlLm5leHQsaSx0KSlyZXR1cm4hMDtlPWUubmV4dH13aGlsZShlIT09aSk7cmV0dXJuITF9ZnVuY3Rpb24gWGkoaSx0KXtyZXR1cm4gYXQoaS5wcmV2LGksaS5uZXh0KTwwP2F0KGksdCxpLm5leHQpPj0wJiZhdChpLGkucHJldix0KT49MDphdChpLHQsaS5wcmV2KTwwfHxhdChpLGkubmV4dCx0KTwwfWZ1bmN0aW9uIEF5KGksdCl7bGV0IGU9aSxuPSExO2NvbnN0IHM9KGkueCt0LngpLzIscj0oaS55K3QueSkvMjtkbyBlLnk+ciE9ZS5uZXh0Lnk+ciYmZS5uZXh0LnkhPT1lLnkmJnM8KGUubmV4dC54LWUueCkqKHItZS55KS8oZS5uZXh0LnktZS55KStlLngmJihuPSFuKSxlPWUubmV4dDt3aGlsZShlIT09aSk7cmV0dXJuIG59ZnVuY3Rpb24gJGgoaSx0KXtjb25zdCBlPVdhKGkuaSxpLngsaS55KSxuPVdhKHQuaSx0LngsdC55KSxzPWkubmV4dCxyPXQucHJldjtyZXR1cm4gaS5uZXh0PXQsdC5wcmV2PWksZS5uZXh0PXMscy5wcmV2PWUsbi5uZXh0PWUsZS5wcmV2PW4sci5uZXh0PW4sbi5wcmV2PXIsbn1mdW5jdGlvbiBVaChpLHQsZSxuKXtjb25zdCBzPVdhKGksdCxlKTtyZXR1cm4gbj8ocy5uZXh0PW4ubmV4dCxzLnByZXY9bixuLm5leHQucHJldj1zLG4ubmV4dD1zKToocy5wcmV2PXMscy5uZXh0PXMpLHN9ZnVuY3Rpb24gSmkoaSl7aS5uZXh0LnByZXY9aS5wcmV2LGkucHJldi5uZXh0PWkubmV4dCxpLnByZXZaJiYoaS5wcmV2Wi5uZXh0Wj1pLm5leHRaKSxpLm5leHRaJiYoaS5uZXh0Wi5wcmV2Wj1pLnByZXZaKX1mdW5jdGlvbiBXYShpLHQsZSl7cmV0dXJue2kseDp0LHk6ZSxwcmV2Om51bGwsbmV4dDpudWxsLHo6MCxwcmV2WjpudWxsLG5leHRaOm51bGwsc3RlaW5lcjohMX19ZnVuY3Rpb24gX3koaSx0LGUsbil7bGV0IHM9MDtmb3IobGV0IHI9dCxvPWUtbjtyPGU7cis9bilzKz0oaVtvXS1pW3JdKSooaVtyKzFdK2lbbysxXSksbz1yO3JldHVybiBzfWZ1bmN0aW9uIFZoKGkpe2NvbnN0IHQ9W10sZT1bXSxuPWlbMF1bMF0ubGVuZ3RoO2xldCBzPTAscj0wO2Zvcihjb25zdCBvIG9mIGkpe2Zvcihjb25zdCBhIG9mIG8pZm9yKGxldCBjPTA7YzxuO2MrKyl0LnB1c2goYVtjXSk7ciYmKHMrPXIsZS5wdXNoKHMpKSxyPW8ubGVuZ3RofXJldHVybnt2ZXJ0aWNlczp0LGhvbGVzOmUsZGltZW5zaW9uczpufX1mdW5jdGlvbiBTeShpKXtpZighaSl0aHJvdyBuZXcgRXJyb3IoImNvb3JkIGlzIHJlcXVpcmVkIik7aWYoIUFycmF5LmlzQXJyYXkoaSkpe2lmKGkudHlwZT09PSJGZWF0dXJlIiYmaS5nZW9tZXRyeSE9PW51bGwmJmkuZ2VvbWV0cnkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuZ2VvbWV0cnkuY29vcmRpbmF0ZXNdO2lmKGkudHlwZT09PSJQb2ludCIpcmV0dXJuWy4uLmkuY29vcmRpbmF0ZXNdfWlmKEFycmF5LmlzQXJyYXkoaSkmJmkubGVuZ3RoPj0yJiYhQXJyYXkuaXNBcnJheShpWzBdKSYmIUFycmF5LmlzQXJyYXkoaVsxXSkpcmV0dXJuWy4uLmldO3Rocm93IG5ldyBFcnJvcigiY29vcmQgbXVzdCBiZSBHZW9KU09OIFBvaW50IG9yIGFuIEFycmF5IG9mIG51bWJlcnMiKX1mdW5jdGlvbiB2eShpKXtpZihBcnJheS5pc0FycmF5KGkpKXJldHVybiBpO2lmKGkudHlwZT09PSJGZWF0dXJlIil7aWYoaS5nZW9tZXRyeSE9PW51bGwpcmV0dXJuIGkuZ2VvbWV0cnkuY29vcmRpbmF0ZXN9ZWxzZSBpZihpLmNvb3JkaW5hdGVzKXJldHVybiBpLmNvb3JkaW5hdGVzO3Rocm93IG5ldyBFcnJvcigiY29vcmRzIG11c3QgYmUgR2VvSlNPTiBGZWF0dXJlLCBHZW9tZXRyeSBPYmplY3Qgb3IgYW4gQXJyYXkiKX1mdW5jdGlvbiB6eShpKXtyZXR1cm4gaS50eXBlPT09IkZlYXR1cmUiP2kuZ2VvbWV0cnk6aX1mdW5jdGlvbiBUeShpKXtjb25zdCB0PXZ5KGkpO2xldCBlPTAsbj0xLHMscjtmb3IoO248dC5sZW5ndGg7KXM9cnx8dFswXSxyPXRbbl0sZSs9KHJbMF0tc1swXSkqKHJbMV0rc1sxXSksbisrO3JldHVybiBlPjB9dmFyIEV5PVR5O2NvbnN0IFZlPTExMTAyMjMwMjQ2MjUxNTY1ZS0zMix2dD0xMzQyMTc3MjksUHk9KDMrOCpWZSkqVmU7ZnVuY3Rpb24gR2EoaSx0LGUsbixzKXtsZXQgcixvLGEsYyxsPXRbMF0saD1uWzBdLHU9MCxmPTA7aD5sPT1oPi1sPyhyPWwsbD10WysrdV0pOihyPWgsaD1uWysrZl0pO2xldCBkPTA7aWYodTxpJiZmPGUpZm9yKGg+bD09aD4tbD8obz1sK3IsYT1yLShvLWwpLGw9dFsrK3VdKToobz1oK3IsYT1yLShvLWgpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7dTxpJiZmPGU7KWg+bD09aD4tbD8obz1yK2wsYz1vLXIsYT1yLShvLWMpKyhsLWMpLGw9dFsrK3VdKToobz1yK2gsYz1vLXIsYT1yLShvLWMpKyhoLWMpLGg9blsrK2ZdKSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDt1PGk7KW89citsLGM9by1yLGE9ci0oby1jKSsobC1jKSxsPXRbKyt1XSxyPW8sYSE9PTAmJihzW2QrK109YSk7Zm9yKDtmPGU7KW89citoLGM9by1yLGE9ci0oby1jKSsoaC1jKSxoPW5bKytmXSxyPW8sYSE9PTAmJihzW2QrK109YSk7cmV0dXJuKHIhPT0wfHxkPT09MCkmJihzW2QrK109ciksZH1mdW5jdGlvbiBDeShpLHQpe2xldCBlPXRbMF07Zm9yKGxldCBuPTE7bjxpO24rKyllKz10W25dO3JldHVybiBlfWZ1bmN0aW9uIFlpKGkpe3JldHVybiBuZXcgRmxvYXQ2NEFycmF5KGkpfWNvbnN0IEJ5PSgzKzE2KlZlKSpWZSxGeT0oMisxMipWZSkqVmUsSXk9KDkrNjQqVmUpKlZlKlZlLGFpPVlpKDQpLHFoPVlpKDgpLEhoPVlpKDEyKSxXaD1ZaSgxNiksQnQ9WWkoNCk7ZnVuY3Rpb24ga3koaSx0LGUsbixzLHIsbyl7bGV0IGEsYyxsLGgsdSxmLGQscCx5LG0sZyxiLHcseCxNLEEsXyxTO2NvbnN0IEU9aS1zLHo9ZS1zLHY9dC1yLEM9bi1yO3g9RSpDLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpDLHk9Zi0oZi1DKSxtPUMteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KnosZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KnoseT1mLShmLXopLG09ei15LF89cCptLShBLWQqeS1wKnktZCptKSxnPU0tXyx1PU0tZyxhaVswXT1NLShnK3UpKyh1LV8pLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxhaVsxXT13LShnK3UpKyh1LUEpLFM9YitnLHU9Uy1iLGFpWzJdPWItKFMtdSkrKGctdSksYWlbM109UztsZXQgUD1DeSg0LGFpKSxGPUZ5Km87aWYoUD49Rnx8LVA+PUZ8fCh1PWktRSxhPWktKEUrdSkrKHUtcyksdT1lLXosbD1lLSh6K3UpKyh1LXMpLHU9dC12LGM9dC0odit1KSsodS1yKSx1PW4tQyxoPW4tKEMrdSkrKHUtciksYT09PTAmJmM9PT0wJiZsPT09MCYmaD09PTApfHwoRj1JeSpvK1B5Kk1hdGguYWJzKFApLFArPUUqaCtDKmEtKHYqbCt6KmMpLFA+PUZ8fC1QPj1GKSlyZXR1cm4gUDt4PWEqQyxmPXZ0KmEsZD1mLShmLWEpLHA9YS1kLGY9dnQqQyx5PWYtKGYtQyksbT1DLXksTT1wKm0tKHgtZCp5LXAqeS1kKm0pLEE9Yyp6LGY9dnQqYyxkPWYtKGYtYykscD1jLWQsZj12dCp6LHk9Zi0oZi16KSxtPXoteSxfPXAqbS0oQS1kKnktcCp5LWQqbSksZz1NLV8sdT1NLWcsQnRbMF09TS0oZyt1KSsodS1fKSxiPXgrZyx1PWIteCx3PXgtKGItdSkrKGctdSksZz13LUEsdT13LWcsQnRbMV09dy0oZyt1KSsodS1BKSxTPWIrZyx1PVMtYixCdFsyXT1iLShTLXUpKyhnLXUpLEJ0WzNdPVM7Y29uc3QgQj1HYSg0LGFpLDQsQnQscWgpO3g9RSpoLGY9dnQqRSxkPWYtKGYtRSkscD1FLWQsZj12dCpoLHk9Zi0oZi1oKSxtPWgteSxNPXAqbS0oeC1kKnktcCp5LWQqbSksQT12KmwsZj12dCp2LGQ9Zi0oZi12KSxwPXYtZCxmPXZ0KmwseT1mLShmLWwpLG09bC15LF89cCptLShBLWQqeS1wKnktZCptKSxnPU0tXyx1PU0tZyxCdFswXT1NLShnK3UpKyh1LV8pLGI9eCtnLHU9Yi14LHc9eC0oYi11KSsoZy11KSxnPXctQSx1PXctZyxCdFsxXT13LShnK3UpKyh1LUEpLFM9YitnLHU9Uy1iLEJ0WzJdPWItKFMtdSkrKGctdSksQnRbM109Uztjb25zdCBJPUdhKEIscWgsNCxCdCxIaCk7eD1hKmgsZj12dCphLGQ9Zi0oZi1hKSxwPWEtZCxmPXZ0KmgseT1mLShmLWgpLG09aC15LE09cCptLSh4LWQqeS1wKnktZCptKSxBPWMqbCxmPXZ0KmMsZD1mLShmLWMpLHA9Yy1kLGY9dnQqbCx5PWYtKGYtbCksbT1sLXksXz1wKm0tKEEtZCp5LXAqeS1kKm0pLGc9TS1fLHU9TS1nLEJ0WzBdPU0tKGcrdSkrKHUtXyksYj14K2csdT1iLXgsdz14LShiLXUpKyhnLXUpLGc9dy1BLHU9dy1nLEJ0WzFdPXctKGcrdSkrKHUtQSksUz1iK2csdT1TLWIsQnRbMl09Yi0oUy11KSsoZy11KSxCdFszXT1TO2NvbnN0IGs9R2EoSSxIaCw0LEJ0LFdoKTtyZXR1cm4gV2hbay0xXX1mdW5jdGlvbiBJcihpLHQsZSxuLHMscil7Y29uc3Qgbz0odC1yKSooZS1zKSxhPShpLXMpKihuLXIpLGM9by1hO2lmKG89PT0wfHxhPT09MHx8bz4wIT1hPjApcmV0dXJuIGM7Y29uc3QgbD1NYXRoLmFicyhvK2EpO3JldHVybiBNYXRoLmFicyhjKT49QnkqbD9jOi1reShpLHQsZSxuLHMscixsKX1jb25zdCBHaD1NYXRoLnBvdygyLC01Miksa3I9bmV3IFVpbnQzMkFycmF5KDUxMik7Y2xhc3Mgaml7c3RhdGljIGZyb20odCxlPUR5LG49JHkpe2NvbnN0IHM9dC5sZW5ndGgscj1uZXcgRmxvYXQ2NEFycmF5KHMqMik7Zm9yKGxldCBvPTA7bzxzO28rKyl7Y29uc3QgYT10W29dO3JbMipvXT1lKGEpLHJbMipvKzFdPW4oYSl9cmV0dXJuIG5ldyBqaShyKX1jb25zdHJ1Y3Rvcih0KXtjb25zdCBlPXQubGVuZ3RoPj4xO2lmKGU+MCYmdHlwZW9mIHRbMF0hPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcigiRXhwZWN0ZWQgY29vcmRzIHRvIGNvbnRhaW4gbnVtYmVycy4iKTt0aGlzLmNvb3Jkcz10O2NvbnN0IG49TWF0aC5tYXgoMiplLTUsMCk7dGhpcy5fdHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheShuKjMpLHRoaXMuX2hhbGZlZGdlcz1uZXcgSW50MzJBcnJheShuKjMpLHRoaXMuX2hhc2hTaXplPU1hdGguY2VpbChNYXRoLnNxcnQoZSkpLHRoaXMuX2h1bGxQcmV2PW5ldyBVaW50MzJBcnJheShlKSx0aGlzLl9odWxsTmV4dD1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbFRyaT1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5faHVsbEhhc2g9bmV3IEludDMyQXJyYXkodGhpcy5faGFzaFNpemUpLmZpbGwoLTEpLHRoaXMuX2lkcz1uZXcgVWludDMyQXJyYXkoZSksdGhpcy5fZGlzdHM9bmV3IEZsb2F0NjRBcnJheShlKSx0aGlzLnVwZGF0ZSgpfXVwZGF0ZSgpe2NvbnN0e2Nvb3Jkczp0LF9odWxsUHJldjplLF9odWxsTmV4dDpuLF9odWxsVHJpOnMsX2h1bGxIYXNoOnJ9PXRoaXMsbz10Lmxlbmd0aD4+MTtsZXQgYT0xLzAsYz0xLzAsbD0tMS8wLGg9LTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtjb25zdCB2PXRbMip6XSxDPXRbMip6KzFdO3Y8YSYmKGE9diksQzxjJiYoYz1DKSx2PmwmJihsPXYpLEM+aCYmKGg9QyksdGhpcy5faWRzW3pdPXp9Y29uc3QgdT0oYStsKS8yLGY9KGMraCkvMjtsZXQgZD0xLzAscCx5LG07Zm9yKGxldCB6PTA7ejxvO3orKyl7Y29uc3Qgdj1aYSh1LGYsdFsyKnpdLHRbMip6KzFdKTt2PGQmJihwPXosZD12KX1jb25zdCBnPXRbMipwXSxiPXRbMipwKzFdO2Q9MS8wO2ZvcihsZXQgej0wO3o8bzt6Kyspe2lmKHo9PT1wKWNvbnRpbnVlO2NvbnN0IHY9WmEoZyxiLHRbMip6XSx0WzIqeisxXSk7djxkJiZ2PjAmJih5PXosZD12KX1sZXQgdz10WzIqeV0seD10WzIqeSsxXSxNPTEvMDtmb3IobGV0IHo9MDt6PG87eisrKXtpZih6PT09cHx8ej09PXkpY29udGludWU7Y29uc3Qgdj1MeShnLGIsdyx4LHRbMip6XSx0WzIqeisxXSk7djxNJiYobT16LE09dil9bGV0IEE9dFsyKm1dLF89dFsyKm0rMV07aWYoTT09PTEvMCl7Zm9yKGxldCBDPTA7QzxvO0MrKyl0aGlzLl9kaXN0c1tDXT10WzIqQ10tdFswXXx8dFsyKkMrMV0tdFsxXTtjaSh0aGlzLl9pZHMsdGhpcy5fZGlzdHMsMCxvLTEpO2NvbnN0IHo9bmV3IFVpbnQzMkFycmF5KG8pO2xldCB2PTA7Zm9yKGxldCBDPTAsUD0tMS8wO0M8bztDKyspe2NvbnN0IEY9dGhpcy5faWRzW0NdO3RoaXMuX2Rpc3RzW0ZdPlAmJih6W3YrK109RixQPXRoaXMuX2Rpc3RzW0ZdKX10aGlzLmh1bGw9ei5zdWJhcnJheSgwLHYpLHRoaXMudHJpYW5nbGVzPW5ldyBVaW50MzJBcnJheSgwKSx0aGlzLmhhbGZlZGdlcz1uZXcgVWludDMyQXJyYXkoMCk7cmV0dXJufWlmKElyKGcsYix3LHgsQSxfKTwwKXtjb25zdCB6PXksdj13LEM9eDt5PW0sdz1BLHg9XyxtPXosQT12LF89Q31jb25zdCBTPU95KGcsYix3LHgsQSxfKTt0aGlzLl9jeD1TLngsdGhpcy5fY3k9Uy55O2ZvcihsZXQgej0wO3o8bzt6KyspdGhpcy5fZGlzdHNbel09WmEodFsyKnpdLHRbMip6KzFdLFMueCxTLnkpO2NpKHRoaXMuX2lkcyx0aGlzLl9kaXN0cywwLG8tMSksdGhpcy5faHVsbFN0YXJ0PXA7bGV0IEU9MztuW3BdPWVbbV09eSxuW3ldPWVbcF09bSxuW21dPWVbeV09cCxzW3BdPTAsc1t5XT0xLHNbbV09MixyLmZpbGwoLTEpLHJbdGhpcy5faGFzaEtleShnLGIpXT1wLHJbdGhpcy5faGFzaEtleSh3LHgpXT15LHJbdGhpcy5faGFzaEtleShBLF8pXT1tLHRoaXMudHJpYW5nbGVzTGVuPTAsdGhpcy5fYWRkVHJpYW5nbGUocCx5LG0sLTEsLTEsLTEpO2ZvcihsZXQgej0wLHYsQzt6PHRoaXMuX2lkcy5sZW5ndGg7eisrKXtjb25zdCBQPXRoaXMuX2lkc1t6XSxGPXRbMipQXSxCPXRbMipQKzFdO2lmKHo+MCYmTWF0aC5hYnMoRi12KTw9R2gmJk1hdGguYWJzKEItQyk8PUdofHwodj1GLEM9QixQPT09cHx8UD09PXl8fFA9PT1tKSljb250aW51ZTtsZXQgST0wO2ZvcihsZXQgZHQ9MCxEdD10aGlzLl9oYXNoS2V5KEYsQik7ZHQ8dGhpcy5faGFzaFNpemUmJihJPXJbKER0K2R0KSV0aGlzLl9oYXNoU2l6ZV0sIShJIT09LTEmJkkhPT1uW0ldKSk7ZHQrKyk7ST1lW0ldO2xldCBrPUksRDtmb3IoO0Q9bltrXSxJcihGLEIsdFsyKmtdLHRbMiprKzFdLHRbMipEXSx0WzIqRCsxXSk+PTA7KWlmKGs9RCxrPT09SSl7az0tMTticmVha31pZihrPT09LTEpY29udGludWU7bGV0IFY9dGhpcy5fYWRkVHJpYW5nbGUoayxQLG5ba10sLTEsLTEsc1trXSk7c1tQXT10aGlzLl9sZWdhbGl6ZShWKzIpLHNba109VixFKys7bGV0IGo9bltrXTtmb3IoO0Q9bltqXSxJcihGLEIsdFsyKmpdLHRbMipqKzFdLHRbMipEXSx0WzIqRCsxXSk8MDspVj10aGlzLl9hZGRUcmlhbmdsZShqLFAsRCxzW1BdLC0xLHNbal0pLHNbUF09dGhpcy5fbGVnYWxpemUoVisyKSxuW2pdPWosRS0tLGo9RDtpZihrPT09SSlmb3IoO0Q9ZVtrXSxJcihGLEIsdFsyKkRdLHRbMipEKzFdLHRbMiprXSx0WzIqaysxXSk8MDspVj10aGlzLl9hZGRUcmlhbmdsZShELFAsaywtMSxzW2tdLHNbRF0pLHRoaXMuX2xlZ2FsaXplKFYrMiksc1tEXT1WLG5ba109ayxFLS0saz1EO3RoaXMuX2h1bGxTdGFydD1lW1BdPWssbltrXT1lW2pdPVAsbltQXT1qLHJbdGhpcy5faGFzaEtleShGLEIpXT1QLHJbdGhpcy5faGFzaEtleSh0WzIqa10sdFsyKmsrMV0pXT1rfXRoaXMuaHVsbD1uZXcgVWludDMyQXJyYXkoRSk7Zm9yKGxldCB6PTAsdj10aGlzLl9odWxsU3RhcnQ7ejxFO3orKyl0aGlzLmh1bGxbel09dix2PW5bdl07dGhpcy50cmlhbmdsZXM9dGhpcy5fdHJpYW5nbGVzLnN1YmFycmF5KDAsdGhpcy50cmlhbmdsZXNMZW4pLHRoaXMuaGFsZmVkZ2VzPXRoaXMuX2hhbGZlZGdlcy5zdWJhcnJheSgwLHRoaXMudHJpYW5nbGVzTGVuKX1faGFzaEtleSh0LGUpe3JldHVybiBNYXRoLmZsb29yKE55KHQtdGhpcy5fY3gsZS10aGlzLl9jeSkqdGhpcy5faGFzaFNpemUpJXRoaXMuX2hhc2hTaXplfV9sZWdhbGl6ZSh0KXtjb25zdHtfdHJpYW5nbGVzOmUsX2hhbGZlZGdlczpuLGNvb3JkczpzfT10aGlzO2xldCByPTAsbz0wO2Zvcig7Oyl7Y29uc3QgYT1uW3RdLGM9dC10JTM7aWYobz1jKyh0KzIpJTMsYT09PS0xKXtpZihyPT09MClicmVhazt0PWtyWy0tcl07Y29udGludWV9Y29uc3QgbD1hLWElMyxoPWMrKHQrMSklMyx1PWwrKGErMiklMyxmPWVbb10sZD1lW3RdLHA9ZVtoXSx5PWVbdV07aWYoUnkoc1syKmZdLHNbMipmKzFdLHNbMipkXSxzWzIqZCsxXSxzWzIqcF0sc1syKnArMV0sc1syKnldLHNbMip5KzFdKSl7ZVt0XT15LGVbYV09Zjtjb25zdCBnPW5bdV07aWYoZz09PS0xKXtsZXQgdz10aGlzLl9odWxsU3RhcnQ7ZG97aWYodGhpcy5faHVsbFRyaVt3XT09PXUpe3RoaXMuX2h1bGxUcmlbd109dDticmVha313PXRoaXMuX2h1bGxQcmV2W3ddfXdoaWxlKHchPT10aGlzLl9odWxsU3RhcnQpfXRoaXMuX2xpbmsodCxnKSx0aGlzLl9saW5rKGEsbltvXSksdGhpcy5fbGluayhvLHUpO2NvbnN0IGI9bCsoYSsxKSUzO3I8a3IubGVuZ3RoJiYoa3JbcisrXT1iKX1lbHNle2lmKHI9PT0wKWJyZWFrO3Q9a3JbLS1yXX19cmV0dXJuIG99X2xpbmsodCxlKXt0aGlzLl9oYWxmZWRnZXNbdF09ZSxlIT09LTEmJih0aGlzLl9oYWxmZWRnZXNbZV09dCl9X2FkZFRyaWFuZ2xlKHQsZSxuLHMscixvKXtjb25zdCBhPXRoaXMudHJpYW5nbGVzTGVuO3JldHVybiB0aGlzLl90cmlhbmdsZXNbYV09dCx0aGlzLl90cmlhbmdsZXNbYSsxXT1lLHRoaXMuX3RyaWFuZ2xlc1thKzJdPW4sdGhpcy5fbGluayhhLHMpLHRoaXMuX2xpbmsoYSsxLHIpLHRoaXMuX2xpbmsoYSsyLG8pLHRoaXMudHJpYW5nbGVzTGVuKz0zLGF9fWZ1bmN0aW9uIE55KGksdCl7Y29uc3QgZT1pLyhNYXRoLmFicyhpKStNYXRoLmFicyh0KSk7cmV0dXJuKHQ+MD8zLWU6MStlKS80fWZ1bmN0aW9uIFphKGksdCxlLG4pe2NvbnN0IHM9aS1lLHI9dC1uO3JldHVybiBzKnMrcipyfWZ1bmN0aW9uIFJ5KGksdCxlLG4scyxyLG8sYSl7Y29uc3QgYz1pLW8sbD10LWEsaD1lLW8sdT1uLWEsZj1zLW8sZD1yLWEscD1jKmMrbCpsLHk9aCpoK3UqdSxtPWYqZitkKmQ7cmV0dXJuIGMqKHUqbS15KmQpLWwqKGgqbS15KmYpK3AqKGgqZC11KmYpPDB9ZnVuY3Rpb24gTHkoaSx0LGUsbixzLHIpe2NvbnN0IG89ZS1pLGE9bi10LGM9cy1pLGw9ci10LGg9bypvK2EqYSx1PWMqYytsKmwsZj0uNS8obypsLWEqYyksZD0obCpoLWEqdSkqZixwPShvKnUtYypoKSpmO3JldHVybiBkKmQrcCpwfWZ1bmN0aW9uIE95KGksdCxlLG4scyxyKXtjb25zdCBvPWUtaSxhPW4tdCxjPXMtaSxsPXItdCxoPW8qbythKmEsdT1jKmMrbCpsLGY9LjUvKG8qbC1hKmMpLGQ9aSsobCpoLWEqdSkqZixwPXQrKG8qdS1jKmgpKmY7cmV0dXJue3g6ZCx5OnB9fWZ1bmN0aW9uIGNpKGksdCxlLG4pe2lmKG4tZTw9MjApZm9yKGxldCBzPWUrMTtzPD1uO3MrKyl7Y29uc3Qgcj1pW3NdLG89dFtyXTtsZXQgYT1zLTE7Zm9yKDthPj1lJiZ0W2lbYV1dPm87KWlbYSsxXT1pW2EtLV07aVthKzFdPXJ9ZWxzZXtjb25zdCBzPWUrbj4+MTtsZXQgcj1lKzEsbz1uO1FpKGkscyxyKSx0W2lbZV1dPnRbaVtuXV0mJlFpKGksZSxuKSx0W2lbcl1dPnRbaVtuXV0mJlFpKGkscixuKSx0W2lbZV1dPnRbaVtyXV0mJlFpKGksZSxyKTtjb25zdCBhPWlbcl0sYz10W2FdO2Zvcig7Oyl7ZG8gcisrO3doaWxlKHRbaVtyXV08Yyk7ZG8gby0tO3doaWxlKHRbaVtvXV0+Yyk7aWYobzxyKWJyZWFrO1FpKGkscixvKX1pW2UrMV09aVtvXSxpW29dPWEsbi1yKzE+PW8tZT8oY2koaSx0LHIsbiksY2koaSx0LGUsby0xKSk6KGNpKGksdCxlLG8tMSksY2koaSx0LHIsbikpfX1mdW5jdGlvbiBRaShpLHQsZSl7Y29uc3Qgbj1pW3RdO2lbdF09aVtlXSxpW2VdPW59ZnVuY3Rpb24gRHkoaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gJHkoaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gVXkoaSx0KXt2YXIgZT0wLG49MCxzPTAscj0wLG89MCxhPTAsYz0wLGw9MCxoPW51bGwsdT1udWxsLGY9aVswXSxkPWlbMV0scD10Lmxlbmd0aDtmb3IoZTtlPHA7ZSsrKXtuPTA7dmFyIHk9dFtlXS5sZW5ndGgtMSxtPXRbZV07aWYoaD1tWzBdLGhbMF0hPT1tW3ldWzBdJiZoWzFdIT09bVt5XVsxXSl0aHJvdyBuZXcgRXJyb3IoIkZpcnN0IGFuZCBsYXN0IGNvb3JkaW5hdGVzIGluIGEgcmluZyBtdXN0IGJlIHRoZSBzYW1lIik7Zm9yKG89aFswXS1mLGE9aFsxXS1kLG47bjx5O24rKyl7aWYodT1tW24rMV0sbD11WzFdLWQsYTwwJiZsPDB8fGE+MCYmbD4wKXtoPXUsYT1sLG89aFswXS1mO2NvbnRpbnVlfWlmKGM9dVswXS1pWzBdLGw+MCYmYTw9MCl7aWYocj1vKmwtYyphLHI+MClzPXMrMTtlbHNlIGlmKHI9PT0wKXJldHVybiAwfWVsc2UgaWYoYT4wJiZsPD0wKXtpZihyPW8qbC1jKmEscjwwKXM9cysxO2Vsc2UgaWYocj09PTApcmV0dXJuIDB9ZWxzZSBpZihsPT09MCYmYTwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbDwwKXtpZihyPW8qbC1jKmEscj09PTApcmV0dXJuIDB9ZWxzZSBpZihhPT09MCYmbD09PTApe2lmKGM8PTAmJm8+PTApcmV0dXJuIDA7aWYobzw9MCYmYz49MClyZXR1cm4gMH1oPXUsYT1sLG89Y319cmV0dXJuIHMlMiE9PTB9ZnVuY3Rpb24gVnkoaSx0LGU9e30pe2lmKCFpKXRocm93IG5ldyBFcnJvcigicG9pbnQgaXMgcmVxdWlyZWQiKTtpZighdCl0aHJvdyBuZXcgRXJyb3IoInBvbHlnb24gaXMgcmVxdWlyZWQiKTtjb25zdCBuPVN5KGkpLHM9enkodCkscj1zLnR5cGUsbz10LmJib3g7bGV0IGE9cy5jb29yZGluYXRlcztpZihvJiZxeShuLG8pPT09ITEpcmV0dXJuITE7cj09PSJQb2x5Z29uIiYmKGE9W2FdKTtsZXQgYz0hMTtmb3IodmFyIGw9MDtsPGEubGVuZ3RoOysrbCl7Y29uc3QgaD1VeShuLGFbbF0pO2lmKGg9PT0wKXJldHVybiFlLmlnbm9yZUJvdW5kYXJ5O2gmJihjPSEwKX1yZXR1cm4gY31mdW5jdGlvbiBxeShpLHQpe3JldHVybiB0WzBdPD1pWzBdJiZ0WzFdPD1pWzFdJiZ0WzJdPj1pWzBdJiZ0WzNdPj1pWzFdfXZhciBIeT1WeTtjb25zdCBaaD0xZS02O2NsYXNzIHZue2NvbnN0cnVjdG9yKCl7dGhpcy5feDA9dGhpcy5feTA9dGhpcy5feDE9dGhpcy5feTE9bnVsbCx0aGlzLl89IiJ9bW92ZVRvKHQsZSl7dGhpcy5fKz1gTSR7dGhpcy5feDA9dGhpcy5feDE9K3R9LCR7dGhpcy5feTA9dGhpcy5feTE9K2V9YH1jbG9zZVBhdGgoKXt0aGlzLl94MSE9PW51bGwmJih0aGlzLl94MT10aGlzLl94MCx0aGlzLl95MT10aGlzLl95MCx0aGlzLl8rPSJaIil9bGluZVRvKHQsZSl7dGhpcy5fKz1gTCR7dGhpcy5feDE9K3R9LCR7dGhpcy5feTE9K2V9YH1hcmModCxlLG4pe3Q9K3QsZT0rZSxuPStuO2NvbnN0IHM9dCtuLHI9ZTtpZihuPDApdGhyb3cgbmV3IEVycm9yKCJuZWdhdGl2ZSByYWRpdXMiKTt0aGlzLl94MT09PW51bGw/dGhpcy5fKz1gTSR7c30sJHtyfWA6KE1hdGguYWJzKHRoaXMuX3gxLXMpPlpofHxNYXRoLmFicyh0aGlzLl95MS1yKT5aaCkmJih0aGlzLl8rPSJMIitzKyIsIityKSxuJiYodGhpcy5fKz1gQSR7bn0sJHtufSwwLDEsMSwke3Qtbn0sJHtlfUEke259LCR7bn0sMCwxLDEsJHt0aGlzLl94MT1zfSwke3RoaXMuX3kxPXJ9YCl9cmVjdCh0LGUsbixzKXt0aGlzLl8rPWBNJHt0aGlzLl94MD10aGlzLl94MT0rdH0sJHt0aGlzLl95MD10aGlzLl95MT0rZX1oJHsrbn12JHsrc31oJHstbn1aYH12YWx1ZSgpe3JldHVybiB0aGlzLl98fG51bGx9fWNsYXNzIFhhe2NvbnN0cnVjdG9yKCl7dGhpcy5fPVtdfW1vdmVUbyh0LGUpe3RoaXMuXy5wdXNoKFt0LGVdKX1jbG9zZVBhdGgoKXt0aGlzLl8ucHVzaCh0aGlzLl9bMF0uc2xpY2UoKSl9bGluZVRvKHQsZSl7dGhpcy5fLnB1c2goW3QsZV0pfXZhbHVlKCl7cmV0dXJuIHRoaXMuXy5sZW5ndGg/dGhpcy5fOm51bGx9fWNsYXNzIFd5e2NvbnN0cnVjdG9yKHQsW2UsbixzLHJdPVswLDAsOTYwLDUwMF0pe2lmKCEoKHM9K3MpPj0oZT0rZSkpfHwhKChyPStyKT49KG49K24pKSl0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgYm91bmRzIik7dGhpcy5kZWxhdW5heT10LHRoaXMuX2NpcmN1bWNlbnRlcnM9bmV3IEZsb2F0NjRBcnJheSh0LnBvaW50cy5sZW5ndGgqMiksdGhpcy52ZWN0b3JzPW5ldyBGbG9hdDY0QXJyYXkodC5wb2ludHMubGVuZ3RoKjIpLHRoaXMueG1heD1zLHRoaXMueG1pbj1lLHRoaXMueW1heD1yLHRoaXMueW1pbj1uLHRoaXMuX2luaXQoKX11cGRhdGUoKXtyZXR1cm4gdGhpcy5kZWxhdW5heS51cGRhdGUoKSx0aGlzLl9pbml0KCksdGhpc31faW5pdCgpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dCxodWxsOmUsdHJpYW5nbGVzOm59LHZlY3RvcnM6c309dGhpcyxyPXRoaXMuY2lyY3VtY2VudGVycz10aGlzLl9jaXJjdW1jZW50ZXJzLnN1YmFycmF5KDAsbi5sZW5ndGgvMyoyKTtmb3IobGV0IGQ9MCxwPTAseT1uLmxlbmd0aCxtLGc7ZDx5O2QrPTMscCs9Mil7Y29uc3QgYj1uW2RdKjIsdz1uW2QrMV0qMix4PW5bZCsyXSoyLE09dFtiXSxBPXRbYisxXSxfPXRbd10sUz10W3crMV0sRT10W3hdLHo9dFt4KzFdLHY9Xy1NLEM9Uy1BLFA9RS1NLEY9ei1BLEI9KHYqRi1DKlApKjI7aWYoTWF0aC5hYnMoQik8MWUtOSl7bGV0IEk9MWU5O2NvbnN0IGs9blswXSoyO0kqPU1hdGguc2lnbigodFtrXS1NKSpGLSh0W2srMV0tQSkqUCksbT0oTStFKS8yLUkqRixnPShBK3opLzIrSSpQfWVsc2V7Y29uc3QgST0xL0Isaz12KnYrQypDLEQ9UCpQK0YqRjttPU0rKEYqay1DKkQpKkksZz1BKyh2KkQtUCprKSpJfXJbcF09bSxyW3ArMV09Z31sZXQgbz1lW2UubGVuZ3RoLTFdLGEsYz1vKjQsbCxoPXRbMipvXSx1LGY9dFsyKm8rMV07cy5maWxsKDApO2ZvcihsZXQgZD0wO2Q8ZS5sZW5ndGg7KytkKW89ZVtkXSxhPWMsbD1oLHU9ZixjPW8qNCxoPXRbMipvXSxmPXRbMipvKzFdLHNbYSsyXT1zW2NdPXUtZixzW2ErM109c1tjKzFdPWgtbH1yZW5kZXIodCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHZuOnZvaWQgMCx7ZGVsYXVuYXk6e2hhbGZlZGdlczpuLGluZWRnZXM6cyxodWxsOnJ9LGNpcmN1bWNlbnRlcnM6byx2ZWN0b3JzOmF9PXRoaXM7aWYoci5sZW5ndGg8PTEpcmV0dXJuIG51bGw7Zm9yKGxldCBoPTAsdT1uLmxlbmd0aDtoPHU7KytoKXtjb25zdCBmPW5baF07aWYoZjxoKWNvbnRpbnVlO2NvbnN0IGQ9TWF0aC5mbG9vcihoLzMpKjIscD1NYXRoLmZsb29yKGYvMykqMix5PW9bZF0sbT1vW2QrMV0sZz1vW3BdLGI9b1twKzFdO3RoaXMuX3JlbmRlclNlZ21lbnQoeSxtLGcsYix0KX1sZXQgYyxsPXJbci5sZW5ndGgtMV07Zm9yKGxldCBoPTA7aDxyLmxlbmd0aDsrK2gpe2M9bCxsPXJbaF07Y29uc3QgdT1NYXRoLmZsb29yKHNbbF0vMykqMixmPW9bdV0sZD1vW3UrMV0scD1jKjQseT10aGlzLl9wcm9qZWN0KGYsZCxhW3ArMl0sYVtwKzNdKTt5JiZ0aGlzLl9yZW5kZXJTZWdtZW50KGYsZCx5WzBdLHlbMV0sdCl9cmV0dXJuIGUmJmUudmFsdWUoKX1yZW5kZXJCb3VuZHModCl7Y29uc3QgZT10PT1udWxsP3Q9bmV3IHZuOnZvaWQgMDtyZXR1cm4gdC5yZWN0KHRoaXMueG1pbix0aGlzLnltaW4sdGhpcy54bWF4LXRoaXMueG1pbix0aGlzLnltYXgtdGhpcy55bWluKSxlJiZlLnZhbHVlKCl9cmVuZGVyQ2VsbCh0LGUpe2NvbnN0IG49ZT09bnVsbD9lPW5ldyB2bjp2b2lkIDAscz10aGlzLl9jbGlwKHQpO2lmKHM9PT1udWxsfHwhcy5sZW5ndGgpcmV0dXJuO2UubW92ZVRvKHNbMF0sc1sxXSk7bGV0IHI9cy5sZW5ndGg7Zm9yKDtzWzBdPT09c1tyLTJdJiZzWzFdPT09c1tyLTFdJiZyPjE7KXItPTI7Zm9yKGxldCBvPTI7bzxyO28rPTIpKHNbb10hPT1zW28tMl18fHNbbysxXSE9PXNbby0xXSkmJmUubGluZVRvKHNbb10sc1tvKzFdKTtyZXR1cm4gZS5jbG9zZVBhdGgoKSxuJiZuLnZhbHVlKCl9KmNlbGxQb2x5Z29ucygpe2NvbnN0e2RlbGF1bmF5Ontwb2ludHM6dH19PXRoaXM7Zm9yKGxldCBlPTAsbj10Lmxlbmd0aC8yO2U8bjsrK2Upe2NvbnN0IHM9dGhpcy5jZWxsUG9seWdvbihlKTtzJiYocy5pbmRleD1lLHlpZWxkIHMpfX1jZWxsUG9seWdvbih0KXtjb25zdCBlPW5ldyBYYTtyZXR1cm4gdGhpcy5yZW5kZXJDZWxsKHQsZSksZS52YWx1ZSgpfV9yZW5kZXJTZWdtZW50KHQsZSxuLHMscil7bGV0IG87Y29uc3QgYT10aGlzLl9yZWdpb25jb2RlKHQsZSksYz10aGlzLl9yZWdpb25jb2RlKG4scyk7YT09PTAmJmM9PT0wPyhyLm1vdmVUbyh0LGUpLHIubGluZVRvKG4scykpOihvPXRoaXMuX2NsaXBTZWdtZW50KHQsZSxuLHMsYSxjKSkmJihyLm1vdmVUbyhvWzBdLG9bMV0pLHIubGluZVRvKG9bMl0sb1szXSkpfWNvbnRhaW5zKHQsZSxuKXtyZXR1cm4gZT0rZSxlIT09ZXx8KG49K24sbiE9PW4pPyExOnRoaXMuZGVsYXVuYXkuX3N0ZXAodCxlLG4pPT09dH0qbmVpZ2hib3JzKHQpe2NvbnN0IGU9dGhpcy5fY2xpcCh0KTtpZihlKWZvcihjb25zdCBuIG9mIHRoaXMuZGVsYXVuYXkubmVpZ2hib3JzKHQpKXtjb25zdCBzPXRoaXMuX2NsaXAobik7aWYocyl7dDpmb3IobGV0IHI9MCxvPWUubGVuZ3RoO3I8bztyKz0yKWZvcihsZXQgYT0wLGM9cy5sZW5ndGg7YTxjO2ErPTIpaWYoZVtyXT09c1thXSYmZVtyKzFdPT1zW2ErMV0mJmVbKHIrMiklb109PXNbKGErYy0yKSVjXSYmZVsociszKSVvXT09c1soYStjLTEpJWNdKXt5aWVsZCBuO2JyZWFrIHR9fX19X2NlbGwodCl7Y29uc3R7Y2lyY3VtY2VudGVyczplLGRlbGF1bmF5OntpbmVkZ2VzOm4saGFsZmVkZ2VzOnMsdHJpYW5nbGVzOnJ9fT10aGlzLG89blt0XTtpZihvPT09LTEpcmV0dXJuIG51bGw7Y29uc3QgYT1bXTtsZXQgYz1vO2Rve2NvbnN0IGw9TWF0aC5mbG9vcihjLzMpO2lmKGEucHVzaChlW2wqMl0sZVtsKjIrMV0pLGM9YyUzPT09Mj9jLTI6YysxLHJbY10hPT10KWJyZWFrO2M9c1tjXX13aGlsZShjIT09byYmYyE9PS0xKTtyZXR1cm4gYX1fY2xpcCh0KXtpZih0PT09MCYmdGhpcy5kZWxhdW5heS5odWxsLmxlbmd0aD09PTEpcmV0dXJuW3RoaXMueG1heCx0aGlzLnltaW4sdGhpcy54bWF4LHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWF4LHRoaXMueG1pbix0aGlzLnltaW5dO2NvbnN0IGU9dGhpcy5fY2VsbCh0KTtpZihlPT09bnVsbClyZXR1cm4gbnVsbDtjb25zdHt2ZWN0b3JzOm59PXRoaXMscz10KjQ7cmV0dXJuIG5bc118fG5bcysxXT90aGlzLl9jbGlwSW5maW5pdGUodCxlLG5bc10sbltzKzFdLG5bcysyXSxuW3MrM10pOnRoaXMuX2NsaXBGaW5pdGUodCxlKX1fY2xpcEZpbml0ZSh0LGUpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHM9bnVsbCxyLG8sYT1lW24tMl0sYz1lW24tMV0sbCxoPXRoaXMuX3JlZ2lvbmNvZGUoYSxjKSx1LGY9MDtmb3IobGV0IGQ9MDtkPG47ZCs9MilpZihyPWEsbz1jLGE9ZVtkXSxjPWVbZCsxXSxsPWgsaD10aGlzLl9yZWdpb25jb2RlKGEsYyksbD09PTAmJmg9PT0wKXU9ZixmPTAscz9zLnB1c2goYSxjKTpzPVthLGNdO2Vsc2V7bGV0IHAseSxtLGcsYjtpZihsPT09MCl7aWYoKHA9dGhpcy5fY2xpcFNlZ21lbnQocixvLGEsYyxsLGgpKT09PW51bGwpY29udGludWU7W3ksbSxnLGJdPXB9ZWxzZXtpZigocD10aGlzLl9jbGlwU2VnbWVudChhLGMscixvLGgsbCkpPT09bnVsbCljb250aW51ZTtbZyxiLHksbV09cCx1PWYsZj10aGlzLl9lZGdlY29kZSh5LG0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCkscz9zLnB1c2goeSxtKTpzPVt5LG1dfXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGcsYiksdSYmZiYmdGhpcy5fZWRnZSh0LHUsZixzLHMubGVuZ3RoKSxzP3MucHVzaChnLGIpOnM9W2csYl19aWYocyl1PWYsZj10aGlzLl9lZGdlY29kZShzWzBdLHNbMV0pLHUmJmYmJnRoaXMuX2VkZ2UodCx1LGYscyxzLmxlbmd0aCk7ZWxzZSBpZih0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpKXJldHVyblt0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heCx0aGlzLnhtaW4sdGhpcy55bWluXTtyZXR1cm4gc31fY2xpcFNlZ21lbnQodCxlLG4scyxyLG8pe2Zvcig7Oyl7aWYocj09PTAmJm89PT0wKXJldHVyblt0LGUsbixzXTtpZihyJm8pcmV0dXJuIG51bGw7bGV0IGEsYyxsPXJ8fG87bCY4PyhhPXQrKG4tdCkqKHRoaXMueW1heC1lKS8ocy1lKSxjPXRoaXMueW1heCk6bCY0PyhhPXQrKG4tdCkqKHRoaXMueW1pbi1lKS8ocy1lKSxjPXRoaXMueW1pbik6bCYyPyhjPWUrKHMtZSkqKHRoaXMueG1heC10KS8obi10KSxhPXRoaXMueG1heCk6KGM9ZSsocy1lKSoodGhpcy54bWluLXQpLyhuLXQpLGE9dGhpcy54bWluKSxyPyh0PWEsZT1jLHI9dGhpcy5fcmVnaW9uY29kZSh0LGUpKToobj1hLHM9YyxvPXRoaXMuX3JlZ2lvbmNvZGUobixzKSl9fV9jbGlwSW5maW5pdGUodCxlLG4scyxyLG8pe2xldCBhPUFycmF5LmZyb20oZSksYztpZigoYz10aGlzLl9wcm9qZWN0KGFbMF0sYVsxXSxuLHMpKSYmYS51bnNoaWZ0KGNbMF0sY1sxXSksKGM9dGhpcy5fcHJvamVjdChhW2EubGVuZ3RoLTJdLGFbYS5sZW5ndGgtMV0scixvKSkmJmEucHVzaChjWzBdLGNbMV0pLGE9dGhpcy5fY2xpcEZpbml0ZSh0LGEpKWZvcihsZXQgbD0wLGg9YS5sZW5ndGgsdSxmPXRoaXMuX2VkZ2Vjb2RlKGFbaC0yXSxhW2gtMV0pO2w8aDtsKz0yKXU9ZixmPXRoaXMuX2VkZ2Vjb2RlKGFbbF0sYVtsKzFdKSx1JiZmJiYobD10aGlzLl9lZGdlKHQsdSxmLGEsbCksaD1hLmxlbmd0aCk7ZWxzZSB0aGlzLmNvbnRhaW5zKHQsKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpJiYoYT1bdGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWluLHRoaXMueG1heCx0aGlzLnltYXgsdGhpcy54bWluLHRoaXMueW1heF0pO3JldHVybiBhfV9lZGdlKHQsZSxuLHMscil7Zm9yKDtlIT09bjspe2xldCBvLGE7c3dpdGNoKGUpe2Nhc2UgNTplPTQ7Y29udGludWU7Y2FzZSA0OmU9NixvPXRoaXMueG1heCxhPXRoaXMueW1pbjticmVhaztjYXNlIDY6ZT0yO2NvbnRpbnVlO2Nhc2UgMjplPTEwLG89dGhpcy54bWF4LGE9dGhpcy55bWF4O2JyZWFrO2Nhc2UgMTA6ZT04O2NvbnRpbnVlO2Nhc2UgODplPTksbz10aGlzLnhtaW4sYT10aGlzLnltYXg7YnJlYWs7Y2FzZSA5OmU9MTtjb250aW51ZTtjYXNlIDE6ZT01LG89dGhpcy54bWluLGE9dGhpcy55bWluO2JyZWFrfShzW3JdIT09b3x8c1tyKzFdIT09YSkmJnRoaXMuY29udGFpbnModCxvLGEpJiYocy5zcGxpY2UociwwLG8sYSkscis9Mil9aWYocy5sZW5ndGg+NClmb3IobGV0IG89MDtvPHMubGVuZ3RoO28rPTIpe2NvbnN0IGE9KG8rMiklcy5sZW5ndGgsYz0obys0KSVzLmxlbmd0aDsoc1tvXT09PXNbYV0mJnNbYV09PT1zW2NdfHxzW28rMV09PT1zW2ErMV0mJnNbYSsxXT09PXNbYysxXSkmJihzLnNwbGljZShhLDIpLG8tPTIpfXJldHVybiByfV9wcm9qZWN0KHQsZSxuLHMpe2xldCByPTEvMCxvLGEsYztpZihzPDApe2lmKGU8PXRoaXMueW1pbilyZXR1cm4gbnVsbDsobz0odGhpcy55bWluLWUpL3MpPHImJihjPXRoaXMueW1pbixhPXQrKHI9bykqbil9ZWxzZSBpZihzPjApe2lmKGU+PXRoaXMueW1heClyZXR1cm4gbnVsbDsobz0odGhpcy55bWF4LWUpL3MpPHImJihjPXRoaXMueW1heCxhPXQrKHI9bykqbil9aWYobj4wKXtpZih0Pj10aGlzLnhtYXgpcmV0dXJuIG51bGw7KG89KHRoaXMueG1heC10KS9uKTxyJiYoYT10aGlzLnhtYXgsYz1lKyhyPW8pKnMpfWVsc2UgaWYobjwwKXtpZih0PD10aGlzLnhtaW4pcmV0dXJuIG51bGw7KG89KHRoaXMueG1pbi10KS9uKTxyJiYoYT10aGlzLnhtaW4sYz1lKyhyPW8pKnMpfXJldHVyblthLGNdfV9lZGdlY29kZSh0LGUpe3JldHVybih0PT09dGhpcy54bWluPzE6dD09PXRoaXMueG1heD8yOjApfChlPT09dGhpcy55bWluPzQ6ZT09PXRoaXMueW1heD84OjApfV9yZWdpb25jb2RlKHQsZSl7cmV0dXJuKHQ8dGhpcy54bWluPzE6dD50aGlzLnhtYXg/MjowKXwoZTx0aGlzLnltaW4/NDplPnRoaXMueW1heD84OjApfX1jb25zdCBHeT0yKk1hdGguUEksbGk9TWF0aC5wb3c7ZnVuY3Rpb24gWnkoaSl7cmV0dXJuIGlbMF19ZnVuY3Rpb24gWHkoaSl7cmV0dXJuIGlbMV19ZnVuY3Rpb24gSnkoaSl7Y29uc3R7dHJpYW5nbGVzOnQsY29vcmRzOmV9PWk7Zm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKz0zKXtjb25zdCBzPTIqdFtuXSxyPTIqdFtuKzFdLG89Mip0W24rMl07aWYoKGVbb10tZVtzXSkqKGVbcisxXS1lW3MrMV0pLShlW3JdLWVbc10pKihlW28rMV0tZVtzKzFdKT4xZS0xMClyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBZeShpLHQsZSl7cmV0dXJuW2krTWF0aC5zaW4oaSt0KSplLHQrTWF0aC5jb3MoaS10KSplXX1jbGFzcyBKYXtzdGF0aWMgZnJvbSh0LGU9Wnksbj1YeSxzKXtyZXR1cm4gbmV3IEphKCJsZW5ndGgiaW4gdD9qeSh0LGUsbixzKTpGbG9hdDY0QXJyYXkuZnJvbShReSh0LGUsbixzKSkpfWNvbnN0cnVjdG9yKHQpe3RoaXMuX2RlbGF1bmF0b3I9bmV3IGppKHQpLHRoaXMuaW5lZGdlcz1uZXcgSW50MzJBcnJheSh0Lmxlbmd0aC8yKSx0aGlzLl9odWxsSW5kZXg9bmV3IEludDMyQXJyYXkodC5sZW5ndGgvMiksdGhpcy5wb2ludHM9dGhpcy5fZGVsYXVuYXRvci5jb29yZHMsdGhpcy5faW5pdCgpfXVwZGF0ZSgpe3JldHVybiB0aGlzLl9kZWxhdW5hdG9yLnVwZGF0ZSgpLHRoaXMuX2luaXQoKSx0aGlzfV9pbml0KCl7Y29uc3QgdD10aGlzLl9kZWxhdW5hdG9yLGU9dGhpcy5wb2ludHM7aWYodC5odWxsJiZ0Lmh1bGwubGVuZ3RoPjImJkp5KHQpKXt0aGlzLmNvbGxpbmVhcj1JbnQzMkFycmF5LmZyb20oe2xlbmd0aDplLmxlbmd0aC8yfSwoZixkKT0+ZCkuc29ydCgoZixkKT0+ZVsyKmZdLWVbMipkXXx8ZVsyKmYrMV0tZVsyKmQrMV0pO2NvbnN0IGM9dGhpcy5jb2xsaW5lYXJbMF0sbD10aGlzLmNvbGxpbmVhclt0aGlzLmNvbGxpbmVhci5sZW5ndGgtMV0saD1bZVsyKmNdLGVbMipjKzFdLGVbMipsXSxlWzIqbCsxXV0sdT0xZS04Kk1hdGguaHlwb3QoaFszXS1oWzFdLGhbMl0taFswXSk7Zm9yKGxldCBmPTAsZD1lLmxlbmd0aC8yO2Y8ZDsrK2Ype2NvbnN0IHA9WXkoZVsyKmZdLGVbMipmKzFdLHUpO2VbMipmXT1wWzBdLGVbMipmKzFdPXBbMV19dGhpcy5fZGVsYXVuYXRvcj1uZXcgamkoZSl9ZWxzZSBkZWxldGUgdGhpcy5jb2xsaW5lYXI7Y29uc3Qgbj10aGlzLmhhbGZlZGdlcz10aGlzLl9kZWxhdW5hdG9yLmhhbGZlZGdlcyxzPXRoaXMuaHVsbD10aGlzLl9kZWxhdW5hdG9yLmh1bGwscj10aGlzLnRyaWFuZ2xlcz10aGlzLl9kZWxhdW5hdG9yLnRyaWFuZ2xlcyxvPXRoaXMuaW5lZGdlcy5maWxsKC0xKSxhPXRoaXMuX2h1bGxJbmRleC5maWxsKC0xKTtmb3IobGV0IGM9MCxsPW4ubGVuZ3RoO2M8bDsrK2Mpe2NvbnN0IGg9cltjJTM9PT0yP2MtMjpjKzFdOyhuW2NdPT09LTF8fG9baF09PT0tMSkmJihvW2hdPWMpfWZvcihsZXQgYz0wLGw9cy5sZW5ndGg7YzxsOysrYylhW3NbY11dPWM7cy5sZW5ndGg8PTImJnMubGVuZ3RoPjAmJih0aGlzLnRyaWFuZ2xlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLmhhbGZlZGdlcz1uZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKSx0aGlzLnRyaWFuZ2xlc1swXT1zWzBdLG9bc1swXV09MSxzLmxlbmd0aD09PTImJihvW3NbMV1dPTAsdGhpcy50cmlhbmdsZXNbMV09c1sxXSx0aGlzLnRyaWFuZ2xlc1syXT1zWzFdKSl9dm9yb25vaSh0KXtyZXR1cm4gbmV3IFd5KHRoaXMsdCl9Km5laWdoYm9ycyh0KXtjb25zdHtpbmVkZ2VzOmUsaHVsbDpuLF9odWxsSW5kZXg6cyxoYWxmZWRnZXM6cix0cmlhbmdsZXM6byxjb2xsaW5lYXI6YX09dGhpcztpZihhKXtjb25zdCB1PWEuaW5kZXhPZih0KTt1PjAmJih5aWVsZCBhW3UtMV0pLHU8YS5sZW5ndGgtMSYmKHlpZWxkIGFbdSsxXSk7cmV0dXJufWNvbnN0IGM9ZVt0XTtpZihjPT09LTEpcmV0dXJuO2xldCBsPWMsaD0tMTtkb3tpZih5aWVsZCBoPW9bbF0sbD1sJTM9PT0yP2wtMjpsKzEsb1tsXSE9PXQpcmV0dXJuO2lmKGw9cltsXSxsPT09LTEpe2NvbnN0IHU9blsoc1t0XSsxKSVuLmxlbmd0aF07dSE9PWgmJih5aWVsZCB1KTtyZXR1cm59fXdoaWxlKGwhPT1jKX1maW5kKHQsZSxuPTApe2lmKHQ9K3QsdCE9PXR8fChlPStlLGUhPT1lKSlyZXR1cm4tMTtjb25zdCBzPW47bGV0IHI7Zm9yKDsocj10aGlzLl9zdGVwKG4sdCxlKSk+PTAmJnIhPT1uJiZyIT09czspbj1yO3JldHVybiByfV9zdGVwKHQsZSxuKXtjb25zdHtpbmVkZ2VzOnMsaHVsbDpyLF9odWxsSW5kZXg6byxoYWxmZWRnZXM6YSx0cmlhbmdsZXM6Yyxwb2ludHM6bH09dGhpcztpZihzW3RdPT09LTF8fCFsLmxlbmd0aClyZXR1cm4odCsxKSUobC5sZW5ndGg+PjEpO2xldCBoPXQsdT1saShlLWxbdCoyXSwyKStsaShuLWxbdCoyKzFdLDIpO2NvbnN0IGY9c1t0XTtsZXQgZD1mO2Rve2xldCBwPWNbZF07Y29uc3QgeT1saShlLWxbcCoyXSwyKStsaShuLWxbcCoyKzFdLDIpO2lmKHk8dSYmKHU9eSxoPXApLGQ9ZCUzPT09Mj9kLTI6ZCsxLGNbZF0hPT10KWJyZWFrO2lmKGQ9YVtkXSxkPT09LTEpe2lmKGQ9clsob1t0XSsxKSVyLmxlbmd0aF0sZCE9PXAmJmxpKGUtbFtkKjJdLDIpK2xpKG4tbFtkKjIrMV0sMik8dSlyZXR1cm4gZDticmVha319d2hpbGUoZCE9PWYpO3JldHVybiBofXJlbmRlcih0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgdm46dm9pZCAwLHtwb2ludHM6bixoYWxmZWRnZXM6cyx0cmlhbmdsZXM6cn09dGhpcztmb3IobGV0IG89MCxhPXMubGVuZ3RoO288YTsrK28pe2NvbnN0IGM9c1tvXTtpZihjPG8pY29udGludWU7Y29uc3QgbD1yW29dKjIsaD1yW2NdKjI7dC5tb3ZlVG8obltsXSxuW2wrMV0pLHQubGluZVRvKG5baF0sbltoKzFdKX1yZXR1cm4gdGhpcy5yZW5kZXJIdWxsKHQpLGUmJmUudmFsdWUoKX1yZW5kZXJQb2ludHModCxlKXtlPT09dm9pZCAwJiYoIXR8fHR5cGVvZiB0Lm1vdmVUbyE9ImZ1bmN0aW9uIikmJihlPXQsdD1udWxsKSxlPWU9PW51bGw/MjorZTtjb25zdCBuPXQ9PW51bGw/dD1uZXcgdm46dm9pZCAwLHtwb2ludHM6c309dGhpcztmb3IobGV0IHI9MCxvPXMubGVuZ3RoO3I8bztyKz0yKXtjb25zdCBhPXNbcl0sYz1zW3IrMV07dC5tb3ZlVG8oYStlLGMpLHQuYXJjKGEsYyxlLDAsR3kpfXJldHVybiBuJiZuLnZhbHVlKCl9cmVuZGVySHVsbCh0KXtjb25zdCBlPXQ9PW51bGw/dD1uZXcgdm46dm9pZCAwLHtodWxsOm4scG9pbnRzOnN9PXRoaXMscj1uWzBdKjIsbz1uLmxlbmd0aDt0Lm1vdmVUbyhzW3JdLHNbcisxXSk7Zm9yKGxldCBhPTE7YTxvOysrYSl7Y29uc3QgYz0yKm5bYV07dC5saW5lVG8oc1tjXSxzW2MrMV0pfXJldHVybiB0LmNsb3NlUGF0aCgpLGUmJmUudmFsdWUoKX1odWxsUG9seWdvbigpe2NvbnN0IHQ9bmV3IFhhO3JldHVybiB0aGlzLnJlbmRlckh1bGwodCksdC52YWx1ZSgpfXJlbmRlclRyaWFuZ2xlKHQsZSl7Y29uc3Qgbj1lPT1udWxsP2U9bmV3IHZuOnZvaWQgMCx7cG9pbnRzOnMsdHJpYW5nbGVzOnJ9PXRoaXMsbz1yW3QqPTNdKjIsYT1yW3QrMV0qMixjPXJbdCsyXSoyO3JldHVybiBlLm1vdmVUbyhzW29dLHNbbysxXSksZS5saW5lVG8oc1thXSxzW2ErMV0pLGUubGluZVRvKHNbY10sc1tjKzFdKSxlLmNsb3NlUGF0aCgpLG4mJm4udmFsdWUoKX0qdHJpYW5nbGVQb2x5Z29ucygpe2NvbnN0e3RyaWFuZ2xlczp0fT10aGlzO2ZvcihsZXQgZT0wLG49dC5sZW5ndGgvMztlPG47KytlKXlpZWxkIHRoaXMudHJpYW5nbGVQb2x5Z29uKGUpfXRyaWFuZ2xlUG9seWdvbih0KXtjb25zdCBlPW5ldyBYYTtyZXR1cm4gdGhpcy5yZW5kZXJUcmlhbmdsZSh0LGUpLGUudmFsdWUoKX19ZnVuY3Rpb24gankoaSx0LGUsbil7Y29uc3Qgcz1pLmxlbmd0aCxyPW5ldyBGbG9hdDY0QXJyYXkocyoyKTtmb3IobGV0IG89MDtvPHM7KytvKXtjb25zdCBhPWlbb107cltvKjJdPXQuY2FsbChuLGEsbyxpKSxyW28qMisxXT1lLmNhbGwobixhLG8saSl9cmV0dXJuIHJ9ZnVuY3Rpb24qUXkoaSx0LGUsbil7bGV0IHM9MDtmb3IoY29uc3QgciBvZiBpKXlpZWxkIHQuY2FsbChuLHIscyxpKSx5aWVsZCBlLmNhbGwobixyLHMsaSksKytzfWNvbnN0IFlhPU1hdGguUEksWGg9WWEvMixKaD0xODAvWWEsWWg9WWEvMTgwLEt5PU1hdGguYXRhbjIsamg9TWF0aC5jb3MsdG09TWF0aC5tYXgsZW09TWF0aC5taW4sUWg9TWF0aC5zaW4sbm09TWF0aC5zaWdufHxmdW5jdGlvbihpKXtyZXR1cm4gaT4wPzE6aTwwPy0xOjB9LEtoPU1hdGguc3FydDtmdW5jdGlvbiBpbShpKXtyZXR1cm4gaT4xP1hoOmk8LTE/LVhoOk1hdGguYXNpbihpKX1mdW5jdGlvbiB0dShpLHQpe3JldHVybiBpWzBdKnRbMF0raVsxXSp0WzFdK2lbMl0qdFsyXX1mdW5jdGlvbiBXdChpLHQpe3JldHVybltpWzFdKnRbMl0taVsyXSp0WzFdLGlbMl0qdFswXS1pWzBdKnRbMl0saVswXSp0WzFdLWlbMV0qdFswXV19ZnVuY3Rpb24gTnIoaSx0KXtyZXR1cm5baVswXSt0WzBdLGlbMV0rdFsxXSxpWzJdK3RbMl1dfWZ1bmN0aW9uIFJyKGkpe3ZhciB0PUtoKGlbMF0qaVswXStpWzFdKmlbMV0raVsyXSppWzJdKTtyZXR1cm5baVswXS90LGlbMV0vdCxpWzJdL3RdfWZ1bmN0aW9uIGphKGkpe3JldHVybltLeShpWzFdLGlbMF0pKkpoLGltKHRtKC0xLGVtKDEsaVsyXSkpKSpKaF19ZnVuY3Rpb24gYmUoaSl7Y29uc3QgdD1pWzBdKlloLGU9aVsxXSpZaCxuPWpoKGUpO3JldHVybltuKmpoKHQpLG4qUWgodCksUWgoZSldfWZ1bmN0aW9uIFFhKGkpe3JldHVybiBpPWkubWFwKHQ9PmJlKHQpKSx0dShpWzBdLFd0KGlbMl0saVsxXSkpfWZ1bmN0aW9uIHNtKGkpe2NvbnN0IHQ9b20oaSksZT1jbSh0KSxuPWFtKGUsaSkscz1obShlLGkubGVuZ3RoKSxyPXJtKHMsaSksbz1sbShlLGkpLHtwb2x5Z29uczphLGNlbnRlcnM6Y309dW0obyxlLGkpLGw9Zm0oYSksaD1wbShlLGkpLHU9ZG0obixlKTtyZXR1cm57ZGVsYXVuYXk6dCxlZGdlczpuLHRyaWFuZ2xlczplLGNlbnRlcnM6YyxuZWlnaGJvcnM6cyxwb2x5Z29uczphLG1lc2g6bCxodWxsOmgsdXJxdWhhcnQ6dSxmaW5kOnJ9fWZ1bmN0aW9uIHJtKGksdCl7ZnVuY3Rpb24gZShuLHMpe2xldCByPW5bMF0tc1swXSxvPW5bMV0tc1sxXSxhPW5bMl0tc1syXTtyZXR1cm4gcipyK28qbythKmF9cmV0dXJuIGZ1bmN0aW9uKHMscixvKXtvPT09dm9pZCAwJiYobz0wKTtsZXQgYSxjLGw9bztjb25zdCBoPWJlKFtzLHJdKTtkbyBhPW8sbz1udWxsLGM9ZShoLGJlKHRbYV0pKSxpW2FdLmZvckVhY2godT0+e2xldCBmPWUoaCxiZSh0W3VdKSk7aWYoZjxjKXtjPWYsbz11LGw9dTtyZXR1cm59fSk7d2hpbGUobyE9PW51bGwpO3JldHVybiBsfX1mdW5jdGlvbiBvbShpKXtpZihpLmxlbmd0aDwyKXJldHVybnt9O2xldCB0PTA7Zm9yKDtpc05hTihpW3RdWzBdK2lbdF1bMV0pJiZ0Kys8aS5sZW5ndGg7KTtjb25zdCBlPXBoKGlbdF0pLG49WnAoKS50cmFuc2xhdGUoWzAsMF0pLnNjYWxlKDEpLnJvdGF0ZShlLmludmVydChbMTgwLDBdKSk7aT1pLm1hcChuKTtjb25zdCBzPVtdO2xldCByPTE7Zm9yKGxldCB1PTAsZj1pLmxlbmd0aDt1PGY7dSsrKXtsZXQgZD1kaShpW3VdWzBdLDIpK2RpKGlbdV1bMV0sMik7IWlzRmluaXRlKGQpfHxkPjFlMzI/cy5wdXNoKHUpOmQ+ciYmKHI9ZCl9Y29uc3Qgbz0xZTYqS2gocik7cy5mb3JFYWNoKHU9PmlbdV09W28sMF0pLGkucHVzaChbMCxvXSksaS5wdXNoKFstbywwXSksaS5wdXNoKFswLC1vXSk7Y29uc3QgYT1KYS5mcm9tKGkpO2EucHJvamVjdGlvbj1uO2NvbnN0e3RyaWFuZ2xlczpjLGhhbGZlZGdlczpsLGluZWRnZXM6aH09YTtmb3IobGV0IHU9MCxmPWwubGVuZ3RoO3U8Zjt1KyspaWYobFt1XTwwKXtjb25zdCBkPXUlMz09Mj91LTI6dSsxLHA9dSUzPT0wP3UrMjp1LTEseT1sW2RdLG09bFtwXTtsW3ldPW0sbFttXT15LGxbZF09bFtwXT0tMSxjW3VdPWNbZF09Y1twXT10LGhbY1t5XV09eSUzPT0wP3krMjp5LTEsaFtjW21dXT1tJTM9PTA/bSsyOm0tMSx1Kz0yLXUlM31lbHNlIGNbdV0+aS5sZW5ndGgtMy0xJiYoY1t1XT10KTtyZXR1cm4gYX1mdW5jdGlvbiBhbShpLHQpe2NvbnN0IGU9bmV3IFNldDtyZXR1cm4gdC5sZW5ndGg9PT0yP1tbMCwxXV06KGkuZm9yRWFjaChuPT57aWYoblswXSE9PW5bMV0mJiEoUWEobi5tYXAocz0+dFtzXSkpPDApKWZvcihsZXQgcz0wLHI7czwzO3MrKylyPShzKzEpJTMsZS5hZGQoZXIoW25bc10sbltyXV0pLmpvaW4oIi0iKSl9KSxBcnJheS5mcm9tKGUsbj0+bi5zcGxpdCgiLSIpLm1hcChOdW1iZXIpKSl9ZnVuY3Rpb24gY20oaSl7Y29uc3R7dHJpYW5nbGVzOnR9PWk7aWYoIXQpcmV0dXJuW107Y29uc3QgZT1bXTtmb3IobGV0IG49MCxzPXQubGVuZ3RoLzM7bjxzO24rKyl7Y29uc3Qgcj10WzMqbl0sbz10WzMqbisxXSxhPXRbMypuKzJdO3IhPT1vJiZvIT09YSYmZS5wdXNoKFtyLGEsb10pfXJldHVybiBlfWZ1bmN0aW9uIGxtKGksdCl7cmV0dXJuIGkubWFwKGU9Pntjb25zdCBuPWUubWFwKHI9PnRbcl0pLm1hcChiZSkscz1OcihOcihXdChuWzFdLG5bMF0pLFd0KG5bMl0sblsxXSkpLFd0KG5bMF0sblsyXSkpO3JldHVybiBqYShScihzKSl9KX1mdW5jdGlvbiBobShpLHQpe2NvbnN0IGU9W107cmV0dXJuIGkuZm9yRWFjaChuPT57Zm9yKGxldCBzPTA7czwzO3MrKyl7Y29uc3Qgcj1uW3NdLG89blsocysxKSUzXTtlW3JdPWVbcl18fFtdLGVbcl0ucHVzaChvKX19KSxpLmxlbmd0aD09PTAmJih0PT09Mj8oZVswXT1bMV0sZVsxXT1bMF0pOnQ9PT0xJiYoZVswXT1bXSkpLGV9ZnVuY3Rpb24gdW0oaSx0LGUpe2NvbnN0IG49W10scz1pLnNsaWNlKCk7aWYodC5sZW5ndGg9PT0wKXtpZihlLmxlbmd0aDwyKXJldHVybntwb2x5Z29uczpuLGNlbnRlcnM6c307aWYoZS5sZW5ndGg9PT0yKXtjb25zdCBhPWJlKGVbMF0pLGM9YmUoZVsxXSksbD1ScihOcihhLGMpKSxoPVJyKFd0KGEsYykpLHU9V3QobCxoKSxmPVtsLFd0KGwsdSksV3QoV3QobCx1KSx1KSxXdChXdChXdChsLHUpLHUpLHUpXS5tYXAoamEpLm1hcChvKTtyZXR1cm4gbi5wdXNoKGYpLG4ucHVzaChmLnNsaWNlKCkucmV2ZXJzZSgpKSx7cG9seWdvbnM6bixjZW50ZXJzOnN9fX10LmZvckVhY2goKGEsYyk9Pntmb3IobGV0IGw9MDtsPDM7bCsrKXtjb25zdCBoPWFbbF0sdT1hWyhsKzEpJTNdLGY9YVsobCsyKSUzXTtuW2hdPW5baF18fFtdLG5baF0ucHVzaChbdSxmLGMsW2gsdSxmXV0pfX0pO2NvbnN0IHI9bi5tYXAoYT0+e2NvbnN0IGM9W2FbMF1bMl1dO2xldCBsPWFbMF1bMV07Zm9yKGxldCBoPTE7aDxhLmxlbmd0aDtoKyspZm9yKGxldCB1PTA7dTxhLmxlbmd0aDt1KyspaWYoYVt1XVswXT09bCl7bD1hW3VdWzFdLGMucHVzaChhW3VdWzJdKTticmVha31pZihjLmxlbmd0aD4yKXJldHVybiBjO2lmKGMubGVuZ3RoPT0yKXtjb25zdCBoPWV1KGVbYVswXVszXVswXV0sZVthWzBdWzNdWzFdXSxzW2NbMF1dKSx1PWV1KGVbYVswXVszXVsyXV0sZVthWzBdWzNdWzBdXSxzW2NbMF1dKSxmPW8oaCksZD1vKHUpO3JldHVybltjWzBdLGQsY1sxXSxmXX19KTtmdW5jdGlvbiBvKGEpe2xldCBjPS0xO3JldHVybiBzLnNsaWNlKHQubGVuZ3RoLDEvMCkuZm9yRWFjaCgobCxoKT0+e2xbMF09PT1hWzBdJiZsWzFdPT09YVsxXSYmKGM9aCt0Lmxlbmd0aCl9KSxjPDAmJihjPXMubGVuZ3RoLHMucHVzaChhKSksY31yZXR1cm57cG9seWdvbnM6cixjZW50ZXJzOnN9fWZ1bmN0aW9uIGV1KGksdCxlKXtpPWJlKGkpLHQ9YmUodCksZT1iZShlKTtjb25zdCBuPW5tKHR1KFd0KHQsaSksZSkpO3JldHVybiBqYShScihOcihpLHQpKS5tYXAocz0+bipzKSl9ZnVuY3Rpb24gZm0oaSl7Y29uc3QgdD1bXTtyZXR1cm4gaS5mb3JFYWNoKGU9PntpZighZSlyZXR1cm47bGV0IG49ZVtlLmxlbmd0aC0xXTtmb3IobGV0IHMgb2YgZSlzPm4mJnQucHVzaChbbixzXSksbj1zfSksdH1mdW5jdGlvbiBkbShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtjb25zdCBuPW5ldyBNYXAscz1uZXcgTWFwO3JldHVybiBpLmZvckVhY2goKHIsbyk9Pntjb25zdCBhPXIuam9pbigiLSIpO24uc2V0KGEsZVtvXSkscy5zZXQoYSwhMCl9KSx0LmZvckVhY2gocj0+e2xldCBvPTAsYT0tMTtmb3IobGV0IGM9MDtjPDM7YysrKXtsZXQgbD1lcihbcltjXSxyWyhjKzEpJTNdXSkuam9pbigiLSIpO24uZ2V0KGwpPm8mJihvPW4uZ2V0KGwpLGE9bCl9cy5zZXQoYSwhMSl9KSxpLm1hcChyPT5zLmdldChyLmpvaW4oIi0iKSkpfX1mdW5jdGlvbiBwbShpLHQpe2NvbnN0IGU9bmV3IFNldCxuPVtdO2kubWFwKGE9PntpZighKFFhKGEubWFwKGM9PnRbYz50Lmxlbmd0aD8wOmNdKSk+MWUtMTIpKWZvcihsZXQgYz0wO2M8MztjKyspe2xldCBsPVthW2NdLGFbKGMrMSklM11dLGg9YCR7bFswXX0tJHtsWzFdfWA7ZS5oYXMoaCk/ZS5kZWxldGUoaCk6ZS5hZGQoYCR7bFsxXX0tJHtsWzBdfWApfX0pO2NvbnN0IHM9bmV3IE1hcDtsZXQgcjtpZihlLmZvckVhY2goYT0+e2E9YS5zcGxpdCgiLSIpLm1hcChOdW1iZXIpLHMuc2V0KGFbMF0sYVsxXSkscj1hWzBdfSkscj09PXZvaWQgMClyZXR1cm4gbjtsZXQgbz1yO2Rve24ucHVzaChvKTtsZXQgYT1zLmdldChvKTtzLnNldChvLC0xKSxvPWF9d2hpbGUobz4tMSYmbyE9PXIpO3JldHVybiBufWZ1bmN0aW9uIHltKGkpe2NvbnN0IHQ9ZnVuY3Rpb24oZSl7aWYodC5kZWxhdW5heT1udWxsLHQuX2RhdGE9ZSx0eXBlb2YgdC5fZGF0YT09Im9iamVjdCImJnQuX2RhdGEudHlwZT09PSJGZWF0dXJlQ29sbGVjdGlvbiImJih0Ll9kYXRhPXQuX2RhdGEuZmVhdHVyZXMpLHR5cGVvZiB0Ll9kYXRhPT0ib2JqZWN0Iil7Y29uc3Qgbj10Ll9kYXRhLm1hcChzPT5bdC5fdngocyksdC5fdnkocyksc10pLmZpbHRlcihzPT5pc0Zpbml0ZShzWzBdK3NbMV0pKTt0LnBvaW50cz1uLm1hcChzPT5bc1swXSxzWzFdXSksdC52YWxpZD1uLm1hcChzPT5zWzJdKSx0LmRlbGF1bmF5PXNtKHQucG9pbnRzKX1yZXR1cm4gdH07cmV0dXJuIHQuX3Z4PWZ1bmN0aW9uKGUpe2lmKHR5cGVvZiBlPT0ib2JqZWN0IiYmInR5cGUiaW4gZSlyZXR1cm4gbGgoZSlbMF07aWYoMCBpbiBlKXJldHVybiBlWzBdfSx0Ll92eT1mdW5jdGlvbihlKXtpZih0eXBlb2YgZT09Im9iamVjdCImJiJ0eXBlImluIGUpcmV0dXJuIGxoKGUpWzFdO2lmKDEgaW4gZSlyZXR1cm4gZVsxXX0sdC54PWZ1bmN0aW9uKGUpe3JldHVybiBlPyh0Ll92eD1lLHQpOnQuX3Z4fSx0Lnk9ZnVuY3Rpb24oZSl7cmV0dXJuIGU/KHQuX3Z5PWUsdCk6dC5fdnl9LHQucG9seWdvbnM9ZnVuY3Rpb24oZSl7aWYoZSE9PXZvaWQgMCYmdChlKSwhdC5kZWxhdW5heSlyZXR1cm4hMTtjb25zdCBuPXt0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6W119O3JldHVybiB0LnZhbGlkLmxlbmd0aD09PTB8fCh0LmRlbGF1bmF5LnBvbHlnb25zLmZvckVhY2goKHMscik9Pm4uZmVhdHVyZXMucHVzaCh7dHlwZToiRmVhdHVyZSIsZ2VvbWV0cnk6cz97dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5zLHNbMF1dLm1hcChvPT50LmRlbGF1bmF5LmNlbnRlcnNbb10pXX06bnVsbCxwcm9wZXJ0aWVzOntzaXRlOnQudmFsaWRbcl0sc2l0ZWNvb3JkaW5hdGVzOnQucG9pbnRzW3JdLG5laWdoYm91cnM6dC5kZWxhdW5heS5uZWlnaGJvcnNbcl19fSkpLHQudmFsaWQubGVuZ3RoPT09MSYmbi5mZWF0dXJlcy5wdXNoKHt0eXBlOiJGZWF0dXJlIixnZW9tZXRyeTp7dHlwZToiU3BoZXJlIn0scHJvcGVydGllczp7c2l0ZTp0LnZhbGlkWzBdLHNpdGVjb29yZGluYXRlczp0LnBvaW50c1swXSxuZWlnaGJvdXJzOltdfX0pKSxufSx0LnRyaWFuZ2xlcz1mdW5jdGlvbihlKXtyZXR1cm4gZSE9PXZvaWQgMCYmdChlKSx0LmRlbGF1bmF5P3t0eXBlOiJGZWF0dXJlQ29sbGVjdGlvbiIsZmVhdHVyZXM6dC5kZWxhdW5heS50cmlhbmdsZXMubWFwKChuLHMpPT4obj1uLm1hcChyPT50LnBvaW50c1tyXSksbi5jZW50ZXI9dC5kZWxhdW5heS5jZW50ZXJzW3NdLG4pKS5maWx0ZXIobj0+UWEobik+MCkubWFwKG49Pih7dHlwZToiRmVhdHVyZSIscHJvcGVydGllczp7Y2lyY3VtY2VudGVyOm4uY2VudGVyfSxnZW9tZXRyeTp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLG5bMF1dXX19KSl9OiExfSx0LmxpbmtzPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3Qgbj10LmRlbGF1bmF5LmVkZ2VzLm1hcChyPT5zaSh0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXSkpLHM9dC5kZWxhdW5heS51cnF1aGFydChuKTtyZXR1cm57dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOnQuZGVsYXVuYXkuZWRnZXMubWFwKChyLG8pPT4oe3R5cGU6IkZlYXR1cmUiLHByb3BlcnRpZXM6e3NvdXJjZTp0LnZhbGlkW3JbMF1dLHRhcmdldDp0LnZhbGlkW3JbMV1dLGxlbmd0aDpuW29dLHVycXVoYXJ0OiEhc1tvXX0sZ2VvbWV0cnk6e3R5cGU6IkxpbmVTdHJpbmciLGNvb3JkaW5hdGVzOlt0LnBvaW50c1tyWzBdXSx0LnBvaW50c1tyWzFdXV19fSkpfX0sdC5tZXNoPWZ1bmN0aW9uKGUpe3JldHVybiBlIT09dm9pZCAwJiZ0KGUpLHQuZGVsYXVuYXk/e3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6dC5kZWxhdW5heS5lZGdlcy5tYXAobj0+W3QucG9pbnRzW25bMF1dLHQucG9pbnRzW25bMV1dXSl9OiExfSx0LmNlbGxNZXNoPWZ1bmN0aW9uKGUpe2lmKGUhPT12b2lkIDAmJnQoZSksIXQuZGVsYXVuYXkpcmV0dXJuITE7Y29uc3R7Y2VudGVyczpuLHBvbHlnb25zOnN9PXQuZGVsYXVuYXkscj1bXTtmb3IoY29uc3QgbyBvZiBzKWlmKG8pZm9yKGxldCBhPW8ubGVuZ3RoLGM9b1thLTFdLGw9b1swXSxoPTA7aDxhO2M9bCxsPW9bKytoXSlsPmMmJnIucHVzaChbbltjXSxuW2xdXSk7cmV0dXJue3R5cGU6Ik11bHRpTGluZVN0cmluZyIsY29vcmRpbmF0ZXM6cn19LHQuX2ZvdW5kPXZvaWQgMCx0LmZpbmQ9ZnVuY3Rpb24oZSxuLHMpe2lmKHQuX2ZvdW5kPXQuZGVsYXVuYXkuZmluZChlLG4sdC5fZm91bmQpLCFzfHxzaShbZSxuXSx0LnBvaW50c1t0Ll9mb3VuZF0pPHMpcmV0dXJuIHQuX2ZvdW5kfSx0Lmh1bGw9ZnVuY3Rpb24oZSl7ZSE9PXZvaWQgMCYmdChlKTtjb25zdCBuPXQuZGVsYXVuYXkuaHVsbCxzPXQucG9pbnRzO3JldHVybiBuLmxlbmd0aD09PTA/bnVsbDp7dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6W1suLi5uLm1hcChyPT5zW3JdKSxzW25bMF1dXV19fSxpP3QoaSk6dH1mdW5jdGlvbiBtbShpLHQpe3N3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtjYXNlIDA6YnJlYWs7Y2FzZSAxOnRoaXMucmFuZ2UoaSk7YnJlYWs7ZGVmYXVsdDp0aGlzLnJhbmdlKHQpLmRvbWFpbihpKTticmVha31yZXR1cm4gdGhpc31mdW5jdGlvbiBLYShpLHQsZSl7aS5wcm90b3R5cGU9dC5wcm90b3R5cGU9ZSxlLmNvbnN0cnVjdG9yPWl9ZnVuY3Rpb24gbnUoaSx0KXt2YXIgZT1PYmplY3QuY3JlYXRlKGkucHJvdG90eXBlKTtmb3IodmFyIG4gaW4gdCllW25dPXRbbl07cmV0dXJuIGV9ZnVuY3Rpb24gS2koKXt9dmFyIHRzPS43LExyPTEvdHMsaGk9IlxccyooWystXT9cXGQrKVxccyoiLGVzPSJcXHMqKFsrLV0/KD86XFxkKlxcLik/XFxkKyg/OltlRV1bKy1dP1xcZCspPylcXHMqIixNZT0iXFxzKihbKy1dPyg/OlxcZCpcXC4pP1xcZCsoPzpbZUVdWystXT9cXGQrKT8pJVxccyoiLGdtPS9eIyhbMC05YS1mXXszLDh9KSQvLHhtPW5ldyBSZWdFeHAoYF5yZ2JcXCgke2hpfSwke2hpfSwke2hpfVxcKSRgKSx3bT1uZXcgUmVnRXhwKGBecmdiXFwoJHtNZX0sJHtNZX0sJHtNZX1cXCkkYCksYm09bmV3IFJlZ0V4cChgXnJnYmFcXCgke2hpfSwke2hpfSwke2hpfSwke2VzfVxcKSRgKSxNbT1uZXcgUmVnRXhwKGBecmdiYVxcKCR7TWV9LCR7TWV9LCR7TWV9LCR7ZXN9XFwpJGApLEFtPW5ldyBSZWdFeHAoYF5oc2xcXCgke2VzfSwke01lfSwke01lfVxcKSRgKSxfbT1uZXcgUmVnRXhwKGBeaHNsYVxcKCR7ZXN9LCR7TWV9LCR7TWV9LCR7ZXN9XFwpJGApLGl1PXthbGljZWJsdWU6MTU3OTIzODMsYW50aXF1ZXdoaXRlOjE2NDQ0Mzc1LGFxdWE6NjU1MzUsYXF1YW1hcmluZTo4Mzg4NTY0LGF6dXJlOjE1Nzk0MTc1LGJlaWdlOjE2MTE5MjYwLGJpc3F1ZToxNjc3MDI0NCxibGFjazowLGJsYW5jaGVkYWxtb25kOjE2NzcyMDQ1LGJsdWU6MjU1LGJsdWV2aW9sZXQ6OTA1NTIwMixicm93bjoxMDgyNDIzNCxidXJseXdvb2Q6MTQ1OTYyMzEsY2FkZXRibHVlOjYyNjY1MjgsY2hhcnRyZXVzZTo4Mzg4MzUyLGNob2NvbGF0ZToxMzc4OTQ3MCxjb3JhbDoxNjc0NDI3Mixjb3JuZmxvd2VyYmx1ZTo2NTkxOTgxLGNvcm5zaWxrOjE2Nzc1Mzg4LGNyaW1zb246MTQ0MjMxMDAsY3lhbjo2NTUzNSxkYXJrYmx1ZToxMzksZGFya2N5YW46MzU3MjMsZGFya2dvbGRlbnJvZDoxMjA5MjkzOSxkYXJrZ3JheToxMTExOTAxNyxkYXJrZ3JlZW46MjU2MDAsZGFya2dyZXk6MTExMTkwMTcsZGFya2toYWtpOjEyNDMzMjU5LGRhcmttYWdlbnRhOjkxMDk2NDMsZGFya29saXZlZ3JlZW46NTU5Nzk5OSxkYXJrb3JhbmdlOjE2NzQ3NTIwLGRhcmtvcmNoaWQ6MTAwNDAwMTIsZGFya3JlZDo5MTA5NTA0LGRhcmtzYWxtb246MTUzMDg0MTAsZGFya3NlYWdyZWVuOjk0MTk5MTksZGFya3NsYXRlYmx1ZTo0NzM0MzQ3LGRhcmtzbGF0ZWdyYXk6MzEwMDQ5NSxkYXJrc2xhdGVncmV5OjMxMDA0OTUsZGFya3R1cnF1b2lzZTo1Mjk0NSxkYXJrdmlvbGV0Ojk2OTk1MzksZGVlcHBpbms6MTY3MTY5NDcsZGVlcHNreWJsdWU6NDkxNTEsZGltZ3JheTo2OTA4MjY1LGRpbWdyZXk6NjkwODI2NSxkb2RnZXJibHVlOjIwMDMxOTksZmlyZWJyaWNrOjExNjc0MTQ2LGZsb3JhbHdoaXRlOjE2Nzc1OTIwLGZvcmVzdGdyZWVuOjIyNjM4NDIsZnVjaHNpYToxNjcxMTkzNSxnYWluc2Jvcm86MTQ0NzQ0NjAsZ2hvc3R3aGl0ZToxNjMxNjY3MSxnb2xkOjE2NzY2NzIwLGdvbGRlbnJvZDoxNDMyOTEyMCxncmF5Ojg0MjE1MDQsZ3JlZW46MzI3NjgsZ3JlZW55ZWxsb3c6MTE0MDMwNTUsZ3JleTo4NDIxNTA0LGhvbmV5ZGV3OjE1Nzk0MTYwLGhvdHBpbms6MTY3Mzg3NDAsaW5kaWFucmVkOjEzNDU4NTI0LGluZGlnbzo0OTE1MzMwLGl2b3J5OjE2Nzc3MjAwLGtoYWtpOjE1Nzg3NjYwLGxhdmVuZGVyOjE1MTMyNDEwLGxhdmVuZGVyYmx1c2g6MTY3NzMzNjUsbGF3bmdyZWVuOjgxOTA5NzYsbGVtb25jaGlmZm9uOjE2Nzc1ODg1LGxpZ2h0Ymx1ZToxMTM5MzI1NCxsaWdodGNvcmFsOjE1NzYxNTM2LGxpZ2h0Y3lhbjoxNDc0NTU5OSxsaWdodGdvbGRlbnJvZHllbGxvdzoxNjQ0ODIxMCxsaWdodGdyYXk6MTM4ODIzMjMsbGlnaHRncmVlbjo5NDk4MjU2LGxpZ2h0Z3JleToxMzg4MjMyMyxsaWdodHBpbms6MTY3NTg0NjUsbGlnaHRzYWxtb246MTY3NTI3NjIsbGlnaHRzZWFncmVlbjoyMTQyODkwLGxpZ2h0c2t5Ymx1ZTo4OTAwMzQ2LGxpZ2h0c2xhdGVncmF5Ojc4MzM3NTMsbGlnaHRzbGF0ZWdyZXk6NzgzMzc1MyxsaWdodHN0ZWVsYmx1ZToxMTU4NDczNCxsaWdodHllbGxvdzoxNjc3NzE4NCxsaW1lOjY1MjgwLGxpbWVncmVlbjozMzI5MzMwLGxpbmVuOjE2NDQ1NjcwLG1hZ2VudGE6MTY3MTE5MzUsbWFyb29uOjgzODg2MDgsbWVkaXVtYXF1YW1hcmluZTo2NzM3MzIyLG1lZGl1bWJsdWU6MjA1LG1lZGl1bW9yY2hpZDoxMjIxMTY2NyxtZWRpdW1wdXJwbGU6OTY2MjY4MyxtZWRpdW1zZWFncmVlbjozOTc4MDk3LG1lZGl1bXNsYXRlYmx1ZTo4MDg3NzkwLG1lZGl1bXNwcmluZ2dyZWVuOjY0MTU0LG1lZGl1bXR1cnF1b2lzZTo0NzcyMzAwLG1lZGl1bXZpb2xldHJlZDoxMzA0NzE3MyxtaWRuaWdodGJsdWU6MTY0NDkxMixtaW50Y3JlYW06MTYxMjE4NTAsbWlzdHlyb3NlOjE2NzcwMjczLG1vY2Nhc2luOjE2NzcwMjI5LG5hdmFqb3doaXRlOjE2NzY4Njg1LG5hdnk6MTI4LG9sZGxhY2U6MTY2NDM1NTgsb2xpdmU6ODQyMTM3NixvbGl2ZWRyYWI6NzA0ODczOSxvcmFuZ2U6MTY3NTM5MjAsb3JhbmdlcmVkOjE2NzI5MzQ0LG9yY2hpZDoxNDMxNTczNCxwYWxlZ29sZGVucm9kOjE1NjU3MTMwLHBhbGVncmVlbjoxMDAyNTg4MCxwYWxldHVycXVvaXNlOjExNTI5OTY2LHBhbGV2aW9sZXRyZWQ6MTQzODEyMDMscGFwYXlhd2hpcDoxNjc3MzA3NyxwZWFjaHB1ZmY6MTY3Njc2NzMscGVydToxMzQ2ODk5MSxwaW5rOjE2NzYxMDM1LHBsdW06MTQ1MjQ2MzcscG93ZGVyYmx1ZToxMTU5MTkxMCxwdXJwbGU6ODM4ODczNixyZWJlY2NhcHVycGxlOjY2OTc4ODEscmVkOjE2NzExNjgwLHJvc3licm93bjoxMjM1NzUxOSxyb3lhbGJsdWU6NDI4Njk0NSxzYWRkbGVicm93bjo5MTI3MTg3LHNhbG1vbjoxNjQxNjg4MixzYW5keWJyb3duOjE2MDMyODY0LHNlYWdyZWVuOjMwNTAzMjcsc2Vhc2hlbGw6MTY3NzQ2Mzgsc2llbm5hOjEwNTA2Nzk3LHNpbHZlcjoxMjYzMjI1Nixza3libHVlOjg5MDAzMzEsc2xhdGVibHVlOjY5NzAwNjEsc2xhdGVncmF5OjczNzI5NDQsc2xhdGVncmV5OjczNzI5NDQsc25vdzoxNjc3NTkzMCxzcHJpbmdncmVlbjo2NTQwNyxzdGVlbGJsdWU6NDYyMDk4MCx0YW46MTM4MDg3ODAsdGVhbDozMjg5Nix0aGlzdGxlOjE0MjA0ODg4LHRvbWF0bzoxNjczNzA5NSx0dXJxdW9pc2U6NDI1MTg1Nix2aW9sZXQ6MTU2MzEwODYsd2hlYXQ6MTYxMTMzMzEsd2hpdGU6MTY3NzcyMTUsd2hpdGVzbW9rZToxNjExOTI4NSx5ZWxsb3c6MTY3NzY5NjAseWVsbG93Z3JlZW46MTAxNDUwNzR9O0thKEtpLG5zLHtjb3B5KGkpe3JldHVybiBPYmplY3QuYXNzaWduKG5ldyB0aGlzLmNvbnN0cnVjdG9yLHRoaXMsaSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuIHRoaXMucmdiKCkuZGlzcGxheWFibGUoKX0saGV4OnN1LGZvcm1hdEhleDpzdSxmb3JtYXRIZXg4OlNtLGZvcm1hdEhzbDp2bSxmb3JtYXRSZ2I6cnUsdG9TdHJpbmc6cnV9KTtmdW5jdGlvbiBzdSgpe3JldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleCgpfWZ1bmN0aW9uIFNtKCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0SGV4OCgpfWZ1bmN0aW9uIHZtKCl7cmV0dXJuIGh1KHRoaXMpLmZvcm1hdEhzbCgpfWZ1bmN0aW9uIHJ1KCl7cmV0dXJuIHRoaXMucmdiKCkuZm9ybWF0UmdiKCl9ZnVuY3Rpb24gbnMoaSl7dmFyIHQsZTtyZXR1cm4gaT0oaSsiIikudHJpbSgpLnRvTG93ZXJDYXNlKCksKHQ9Z20uZXhlYyhpKSk/KGU9dFsxXS5sZW5ndGgsdD1wYXJzZUludCh0WzFdLDE2KSxlPT09Nj9vdSh0KTplPT09Mz9uZXcgT3QodD4+OCYxNXx0Pj40JjI0MCx0Pj40JjE1fHQmMjQwLCh0JjE1KTw8NHx0JjE1LDEpOmU9PT04P09yKHQ+PjI0JjI1NSx0Pj4xNiYyNTUsdD4+OCYyNTUsKHQmMjU1KS8yNTUpOmU9PT00P09yKHQ+PjEyJjE1fHQ+PjgmMjQwLHQ+PjgmMTV8dD4+NCYyNDAsdD4+NCYxNXx0JjI0MCwoKHQmMTUpPDw0fHQmMTUpLzI1NSk6bnVsbCk6KHQ9eG0uZXhlYyhpKSk/bmV3IE90KHRbMV0sdFsyXSx0WzNdLDEpOih0PXdtLmV4ZWMoaSkpP25ldyBPdCh0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCwxKToodD1ibS5leGVjKGkpKT9Pcih0WzFdLHRbMl0sdFszXSx0WzRdKToodD1NbS5leGVjKGkpKT9Pcih0WzFdKjI1NS8xMDAsdFsyXSoyNTUvMTAwLHRbM10qMjU1LzEwMCx0WzRdKToodD1BbS5leGVjKGkpKT9sdSh0WzFdLHRbMl0vMTAwLHRbM10vMTAwLDEpOih0PV9tLmV4ZWMoaSkpP2x1KHRbMV0sdFsyXS8xMDAsdFszXS8xMDAsdFs0XSk6aXUuaGFzT3duUHJvcGVydHkoaSk/b3UoaXVbaV0pOmk9PT0idHJhbnNwYXJlbnQiP25ldyBPdChOYU4sTmFOLE5hTiwwKTpudWxsfWZ1bmN0aW9uIG91KGkpe3JldHVybiBuZXcgT3QoaT4+MTYmMjU1LGk+PjgmMjU1LGkmMjU1LDEpfWZ1bmN0aW9uIE9yKGksdCxlLG4pe3JldHVybiBuPD0wJiYoaT10PWU9TmFOKSxuZXcgT3QoaSx0LGUsbil9ZnVuY3Rpb24gem0oaSl7cmV0dXJuIGkgaW5zdGFuY2VvZiBLaXx8KGk9bnMoaSkpLGk/KGk9aS5yZ2IoKSxuZXcgT3QoaS5yLGkuZyxpLmIsaS5vcGFjaXR5KSk6bmV3IE90fWZ1bmN0aW9uIHRjKGksdCxlLG4pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT96bShpKTpuZXcgT3QoaSx0LGUsbj09bnVsbD8xOm4pfWZ1bmN0aW9uIE90KGksdCxlLG4pe3RoaXMucj0raSx0aGlzLmc9K3QsdGhpcy5iPStlLHRoaXMub3BhY2l0eT0rbn1LYShPdCx0YyxudShLaSx7YnJpZ2h0ZXIoaSl7cmV0dXJuIGk9aT09bnVsbD9McjpNYXRoLnBvdyhMcixpKSxuZXcgT3QodGhpcy5yKmksdGhpcy5nKmksdGhpcy5iKmksdGhpcy5vcGFjaXR5KX0sZGFya2VyKGkpe3JldHVybiBpPWk9PW51bGw/dHM6TWF0aC5wb3codHMsaSksbmV3IE90KHRoaXMucippLHRoaXMuZyppLHRoaXMuYippLHRoaXMub3BhY2l0eSl9LHJnYigpe3JldHVybiB0aGlzfSxjbGFtcCgpe3JldHVybiBuZXcgT3Qoem4odGhpcy5yKSx6bih0aGlzLmcpLHpuKHRoaXMuYiksRHIodGhpcy5vcGFjaXR5KSl9LGRpc3BsYXlhYmxlKCl7cmV0dXJuLS41PD10aGlzLnImJnRoaXMucjwyNTUuNSYmLS41PD10aGlzLmcmJnRoaXMuZzwyNTUuNSYmLS41PD10aGlzLmImJnRoaXMuYjwyNTUuNSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGhleDphdSxmb3JtYXRIZXg6YXUsZm9ybWF0SGV4ODpUbSxmb3JtYXRSZ2I6Y3UsdG9TdHJpbmc6Y3V9KSk7ZnVuY3Rpb24gYXUoKXtyZXR1cm5gIyR7VG4odGhpcy5yKX0ke1RuKHRoaXMuZyl9JHtUbih0aGlzLmIpfWB9ZnVuY3Rpb24gVG0oKXtyZXR1cm5gIyR7VG4odGhpcy5yKX0ke1RuKHRoaXMuZyl9JHtUbih0aGlzLmIpfSR7VG4oKGlzTmFOKHRoaXMub3BhY2l0eSk/MTp0aGlzLm9wYWNpdHkpKjI1NSl9YH1mdW5jdGlvbiBjdSgpe2NvbnN0IGk9RHIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8icmdiKCI6InJnYmEoIn0ke3puKHRoaXMucil9LCAke3puKHRoaXMuZyl9LCAke3puKHRoaXMuYil9JHtpPT09MT8iKSI6YCwgJHtpfSlgfWB9ZnVuY3Rpb24gRHIoaSl7cmV0dXJuIGlzTmFOKGkpPzE6TWF0aC5tYXgoMCxNYXRoLm1pbigxLGkpKX1mdW5jdGlvbiB6bihpKXtyZXR1cm4gTWF0aC5tYXgoMCxNYXRoLm1pbigyNTUsTWF0aC5yb3VuZChpKXx8MCkpfWZ1bmN0aW9uIFRuKGkpe3JldHVybiBpPXpuKGkpLChpPDE2PyIwIjoiIikraS50b1N0cmluZygxNil9ZnVuY3Rpb24gbHUoaSx0LGUsbil7cmV0dXJuIG48PTA/aT10PWU9TmFOOmU8PTB8fGU+PTE/aT10PU5hTjp0PD0wJiYoaT1OYU4pLG5ldyB5ZShpLHQsZSxuKX1mdW5jdGlvbiBodShpKXtpZihpIGluc3RhbmNlb2YgeWUpcmV0dXJuIG5ldyB5ZShpLmgsaS5zLGkubCxpLm9wYWNpdHkpO2lmKGkgaW5zdGFuY2VvZiBLaXx8KGk9bnMoaSkpLCFpKXJldHVybiBuZXcgeWU7aWYoaSBpbnN0YW5jZW9mIHllKXJldHVybiBpO2k9aS5yZ2IoKTt2YXIgdD1pLnIvMjU1LGU9aS5nLzI1NSxuPWkuYi8yNTUscz1NYXRoLm1pbih0LGUsbikscj1NYXRoLm1heCh0LGUsbiksbz1OYU4sYT1yLXMsYz0ocitzKS8yO3JldHVybiBhPyh0PT09cj9vPShlLW4pL2ErKGU8bikqNjplPT09cj9vPShuLXQpL2ErMjpvPSh0LWUpL2ErNCxhLz1jPC41P3IrczoyLXItcyxvKj02MCk6YT1jPjAmJmM8MT8wOm8sbmV3IHllKG8sYSxjLGkub3BhY2l0eSl9ZnVuY3Rpb24gRW0oaSx0LGUsbil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg9PT0xP2h1KGkpOm5ldyB5ZShpLHQsZSxuPT1udWxsPzE6bil9ZnVuY3Rpb24geWUoaSx0LGUsbil7dGhpcy5oPStpLHRoaXMucz0rdCx0aGlzLmw9K2UsdGhpcy5vcGFjaXR5PStufUthKHllLEVtLG51KEtpLHticmlnaHRlcihpKXtyZXR1cm4gaT1pPT1udWxsP0xyOk1hdGgucG93KExyLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LGRhcmtlcihpKXtyZXR1cm4gaT1pPT1udWxsP3RzOk1hdGgucG93KHRzLGkpLG5ldyB5ZSh0aGlzLmgsdGhpcy5zLHRoaXMubCppLHRoaXMub3BhY2l0eSl9LHJnYigpe3ZhciBpPXRoaXMuaCUzNjArKHRoaXMuaDwwKSozNjAsdD1pc05hTihpKXx8aXNOYU4odGhpcy5zKT8wOnRoaXMucyxlPXRoaXMubCxuPWUrKGU8LjU/ZToxLWUpKnQscz0yKmUtbjtyZXR1cm4gbmV3IE90KGVjKGk+PTI0MD9pLTI0MDppKzEyMCxzLG4pLGVjKGkscyxuKSxlYyhpPDEyMD9pKzI0MDppLTEyMCxzLG4pLHRoaXMub3BhY2l0eSl9LGNsYW1wKCl7cmV0dXJuIG5ldyB5ZSh1dSh0aGlzLmgpLCRyKHRoaXMucyksJHIodGhpcy5sKSxEcih0aGlzLm9wYWNpdHkpKX0sZGlzcGxheWFibGUoKXtyZXR1cm4oMDw9dGhpcy5zJiZ0aGlzLnM8PTF8fGlzTmFOKHRoaXMucykpJiYwPD10aGlzLmwmJnRoaXMubDw9MSYmMDw9dGhpcy5vcGFjaXR5JiZ0aGlzLm9wYWNpdHk8PTF9LGZvcm1hdEhzbCgpe2NvbnN0IGk9RHIodGhpcy5vcGFjaXR5KTtyZXR1cm5gJHtpPT09MT8iaHNsKCI6ImhzbGEoIn0ke3V1KHRoaXMuaCl9LCAkeyRyKHRoaXMucykqMTAwfSUsICR7JHIodGhpcy5sKSoxMDB9JSR7aT09PTE/IikiOmAsICR7aX0pYH1gfX0pKTtmdW5jdGlvbiB1dShpKXtyZXR1cm4gaT0oaXx8MCklMzYwLGk8MD9pKzM2MDppfWZ1bmN0aW9uICRyKGkpe3JldHVybiBNYXRoLm1heCgwLE1hdGgubWluKDEsaXx8MCkpfWZ1bmN0aW9uIGVjKGksdCxlKXtyZXR1cm4oaTw2MD90KyhlLXQpKmkvNjA6aTwxODA/ZTppPDI0MD90KyhlLXQpKigyNDAtaSkvNjA6dCkqMjU1fXZhciBuYz1pPT4oKT0+aTtmdW5jdGlvbiBQbShpLHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gaStlKnR9fWZ1bmN0aW9uIENtKGksdCxlKXtyZXR1cm4gaT1NYXRoLnBvdyhpLGUpLHQ9TWF0aC5wb3codCxlKS1pLGU9MS9lLGZ1bmN0aW9uKG4pe3JldHVybiBNYXRoLnBvdyhpK24qdCxlKX19ZnVuY3Rpb24gQm0oaSl7cmV0dXJuKGk9K2kpPT0xP2Z1OmZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUtdD9DbSh0LGUsaSk6bmMoaXNOYU4odCk/ZTp0KX19ZnVuY3Rpb24gZnUoaSx0KXt2YXIgZT10LWk7cmV0dXJuIGU/UG0oaSxlKTpuYyhpc05hTihpKT90OmkpfXZhciBkdT1mdW5jdGlvbiBpKHQpe3ZhciBlPUJtKHQpO2Z1bmN0aW9uIG4ocyxyKXt2YXIgbz1lKChzPXRjKHMpKS5yLChyPXRjKHIpKS5yKSxhPWUocy5nLHIuZyksYz1lKHMuYixyLmIpLGw9ZnUocy5vcGFjaXR5LHIub3BhY2l0eSk7cmV0dXJuIGZ1bmN0aW9uKGgpe3JldHVybiBzLnI9byhoKSxzLmc9YShoKSxzLmI9YyhoKSxzLm9wYWNpdHk9bChoKSxzKyIifX1yZXR1cm4gbi5nYW1tYT1pLG59KDEpO2Z1bmN0aW9uIEZtKGksdCl7dHx8KHQ9W10pO3ZhciBlPWk/TWF0aC5taW4odC5sZW5ndGgsaS5sZW5ndGgpOjAsbj10LnNsaWNlKCkscztyZXR1cm4gZnVuY3Rpb24ocil7Zm9yKHM9MDtzPGU7KytzKW5bc109aVtzXSooMS1yKSt0W3NdKnI7cmV0dXJuIG59fWZ1bmN0aW9uIEltKGkpe3JldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoaSkmJiEoaSBpbnN0YW5jZW9mIERhdGFWaWV3KX1mdW5jdGlvbiBrbShpLHQpe3ZhciBlPXQ/dC5sZW5ndGg6MCxuPWk/TWF0aC5taW4oZSxpLmxlbmd0aCk6MCxzPW5ldyBBcnJheShuKSxyPW5ldyBBcnJheShlKSxvO2ZvcihvPTA7bzxuOysrbylzW29dPXJjKGlbb10sdFtvXSk7Zm9yKDtvPGU7KytvKXJbb109dFtvXTtyZXR1cm4gZnVuY3Rpb24oYSl7Zm9yKG89MDtvPG47KytvKXJbb109c1tvXShhKTtyZXR1cm4gcn19ZnVuY3Rpb24gTm0oaSx0KXt2YXIgZT1uZXcgRGF0ZTtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKG4pe3JldHVybiBlLnNldFRpbWUoaSooMS1uKSt0Km4pLGV9fWZ1bmN0aW9uIFVyKGksdCl7cmV0dXJuIGk9K2ksdD0rdCxmdW5jdGlvbihlKXtyZXR1cm4gaSooMS1lKSt0KmV9fWZ1bmN0aW9uIFJtKGksdCl7dmFyIGU9e30sbj17fSxzOyhpPT09bnVsbHx8dHlwZW9mIGkhPSJvYmplY3QiKSYmKGk9e30pLCh0PT09bnVsbHx8dHlwZW9mIHQhPSJvYmplY3QiKSYmKHQ9e30pO2ZvcihzIGluIHQpcyBpbiBpP2Vbc109cmMoaVtzXSx0W3NdKTpuW3NdPXRbc107cmV0dXJuIGZ1bmN0aW9uKHIpe2ZvcihzIGluIGUpbltzXT1lW3NdKHIpO3JldHVybiBufX12YXIgaWM9L1stK10/KD86XGQrXC4/XGQqfFwuP1xkKykoPzpbZUVdWy0rXT9cZCspPy9nLHNjPW5ldyBSZWdFeHAoaWMuc291cmNlLCJnIik7ZnVuY3Rpb24gTG0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIE9tKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gaSh0KSsiIn19ZnVuY3Rpb24gRG0oaSx0KXt2YXIgZT1pYy5sYXN0SW5kZXg9c2MubGFzdEluZGV4PTAsbixzLHIsbz0tMSxhPVtdLGM9W107Zm9yKGk9aSsiIix0PXQrIiI7KG49aWMuZXhlYyhpKSkmJihzPXNjLmV4ZWModCkpOykocj1zLmluZGV4KT5lJiYocj10LnNsaWNlKGUsciksYVtvXT9hW29dKz1yOmFbKytvXT1yKSwobj1uWzBdKT09PShzPXNbMF0pP2Fbb10/YVtvXSs9czphWysrb109czooYVsrK29dPW51bGwsYy5wdXNoKHtpOm8seDpVcihuLHMpfSkpLGU9c2MubGFzdEluZGV4O3JldHVybiBlPHQubGVuZ3RoJiYocj10LnNsaWNlKGUpLGFbb10/YVtvXSs9cjphWysrb109ciksYS5sZW5ndGg8Mj9jWzBdP09tKGNbMF0ueCk6TG0odCk6KHQ9Yy5sZW5ndGgsZnVuY3Rpb24obCl7Zm9yKHZhciBoPTAsdTtoPHQ7KytoKWFbKHU9Y1toXSkuaV09dS54KGwpO3JldHVybiBhLmpvaW4oIiIpfSl9ZnVuY3Rpb24gcmMoaSx0KXt2YXIgZT10eXBlb2YgdCxuO3JldHVybiB0PT1udWxsfHxlPT09ImJvb2xlYW4iP25jKHQpOihlPT09Im51bWJlciI/VXI6ZT09PSJzdHJpbmciPyhuPW5zKHQpKT8odD1uLGR1KTpEbTp0IGluc3RhbmNlb2YgbnM/ZHU6dCBpbnN0YW5jZW9mIERhdGU/Tm06SW0odCk/Rm06QXJyYXkuaXNBcnJheSh0KT9rbTp0eXBlb2YgdC52YWx1ZU9mIT0iZnVuY3Rpb24iJiZ0eXBlb2YgdC50b1N0cmluZyE9ImZ1bmN0aW9uInx8aXNOYU4odCk/Um06VXIpKGksdCl9ZnVuY3Rpb24gJG0oaSx0KXtyZXR1cm4gaT0raSx0PSt0LGZ1bmN0aW9uKGUpe3JldHVybiBNYXRoLnJvdW5kKGkqKDEtZSkrdCplKX19ZnVuY3Rpb24gVW0oaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGl9fWZ1bmN0aW9uIFZtKGkpe3JldHVybitpfXZhciBwdT1bMCwxXTtmdW5jdGlvbiB1aShpKXtyZXR1cm4gaX1mdW5jdGlvbiBvYyhpLHQpe3JldHVybih0LT1pPStpKT9mdW5jdGlvbihlKXtyZXR1cm4oZS1pKS90fTpVbShpc05hTih0KT9OYU46LjUpfWZ1bmN0aW9uIHFtKGksdCl7dmFyIGU7cmV0dXJuIGk+dCYmKGU9aSxpPXQsdD1lKSxmdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5tYXgoaSxNYXRoLm1pbih0LG4pKX19ZnVuY3Rpb24gSG0oaSx0LGUpe3ZhciBuPWlbMF0scz1pWzFdLHI9dFswXSxvPXRbMV07cmV0dXJuIHM8bj8obj1vYyhzLG4pLHI9ZShvLHIpKToobj1vYyhuLHMpLHI9ZShyLG8pKSxmdW5jdGlvbihhKXtyZXR1cm4gcihuKGEpKX19ZnVuY3Rpb24gV20oaSx0LGUpe3ZhciBuPU1hdGgubWluKGkubGVuZ3RoLHQubGVuZ3RoKS0xLHM9bmV3IEFycmF5KG4pLHI9bmV3IEFycmF5KG4pLG89LTE7Zm9yKGlbbl08aVswXSYmKGk9aS5zbGljZSgpLnJldmVyc2UoKSx0PXQuc2xpY2UoKS5yZXZlcnNlKCkpOysrbzxuOylzW29dPW9jKGlbb10saVtvKzFdKSxyW29dPWUodFtvXSx0W28rMV0pO3JldHVybiBmdW5jdGlvbihhKXt2YXIgYz1IMChpLGEsMSxuKS0xO3JldHVybiByW2NdKHNbY10oYSkpfX1mdW5jdGlvbiBHbShpLHQpe3JldHVybiB0LmRvbWFpbihpLmRvbWFpbigpKS5yYW5nZShpLnJhbmdlKCkpLmludGVycG9sYXRlKGkuaW50ZXJwb2xhdGUoKSkuY2xhbXAoaS5jbGFtcCgpKS51bmtub3duKGkudW5rbm93bigpKX1mdW5jdGlvbiBabSgpe3ZhciBpPXB1LHQ9cHUsZT1yYyxuLHMscixvPXVpLGEsYyxsO2Z1bmN0aW9uIGgoKXt2YXIgZj1NYXRoLm1pbihpLmxlbmd0aCx0Lmxlbmd0aCk7cmV0dXJuIG8hPT11aSYmKG89cW0oaVswXSxpW2YtMV0pKSxhPWY+Mj9XbTpIbSxjPWw9bnVsbCx1fWZ1bmN0aW9uIHUoZil7cmV0dXJuIGY9PW51bGx8fGlzTmFOKGY9K2YpP3I6KGN8fChjPWEoaS5tYXAobiksdCxlKSkpKG4obyhmKSkpfXJldHVybiB1LmludmVydD1mdW5jdGlvbihmKXtyZXR1cm4gbyhzKChsfHwobD1hKHQsaS5tYXAobiksVXIpKSkoZikpKX0sdS5kb21haW49ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGk9QXJyYXkuZnJvbShmLFZtKSxoKCkpOmkuc2xpY2UoKX0sdS5yYW5nZT1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odD1BcnJheS5mcm9tKGYpLGgoKSk6dC5zbGljZSgpfSx1LnJhbmdlUm91bmQ9ZnVuY3Rpb24oZil7cmV0dXJuIHQ9QXJyYXkuZnJvbShmKSxlPSRtLGgoKX0sdS5jbGFtcD1mdW5jdGlvbihmKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8obz1mPyEwOnVpLGgoKSk6byE9PXVpfSx1LmludGVycG9sYXRlPWZ1bmN0aW9uKGYpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhlPWYsaCgpKTplfSx1LnVua25vd249ZnVuY3Rpb24oZil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHI9Zix1KTpyfSxmdW5jdGlvbihmLGQpe3JldHVybiBuPWYscz1kLGgoKX19ZnVuY3Rpb24gWG0oKXtyZXR1cm4gWm0oKSh1aSx1aSl9ZnVuY3Rpb24gSm0oaSl7cmV0dXJuIE1hdGguYWJzKGk9TWF0aC5yb3VuZChpKSk+PTFlMjE/aS50b0xvY2FsZVN0cmluZygiZW4iKS5yZXBsYWNlKC8sL2csIiIpOmkudG9TdHJpbmcoMTApfWZ1bmN0aW9uIFZyKGksdCl7aWYoKGU9KGk9dD9pLnRvRXhwb25lbnRpYWwodC0xKTppLnRvRXhwb25lbnRpYWwoKSkuaW5kZXhPZigiZSIpKTwwKXJldHVybiBudWxsO3ZhciBlLG49aS5zbGljZSgwLGUpO3JldHVybltuLmxlbmd0aD4xP25bMF0rbi5zbGljZSgyKTpuLCtpLnNsaWNlKGUrMSldfWZ1bmN0aW9uIGZpKGkpe3JldHVybiBpPVZyKE1hdGguYWJzKGkpKSxpP2lbMV06TmFOfWZ1bmN0aW9uIFltKGksdCl7cmV0dXJuIGZ1bmN0aW9uKGUsbil7Zm9yKHZhciBzPWUubGVuZ3RoLHI9W10sbz0wLGE9aVswXSxjPTA7cz4wJiZhPjAmJihjK2ErMT5uJiYoYT1NYXRoLm1heCgxLG4tYykpLHIucHVzaChlLnN1YnN0cmluZyhzLT1hLHMrYSkpLCEoKGMrPWErMSk+bikpOylhPWlbbz0obysxKSVpLmxlbmd0aF07cmV0dXJuIHIucmV2ZXJzZSgpLmpvaW4odCl9fWZ1bmN0aW9uIGptKGkpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdC5yZXBsYWNlKC9bMC05XS9nLGZ1bmN0aW9uKGUpe3JldHVybiBpWytlXX0pfX12YXIgUW09L14oPzooLik/KFs8Pj1eXSkpPyhbK1wtKCBdKT8oWyQjXSk/KDApPyhcZCspPygsKT8oXC5cZCspPyh+KT8oW2EteiVdKT8kL2k7ZnVuY3Rpb24gcXIoaSl7aWYoISh0PVFtLmV4ZWMoaSkpKXRocm93IG5ldyBFcnJvcigiaW52YWxpZCBmb3JtYXQ6ICIraSk7dmFyIHQ7cmV0dXJuIG5ldyBhYyh7ZmlsbDp0WzFdLGFsaWduOnRbMl0sc2lnbjp0WzNdLHN5bWJvbDp0WzRdLHplcm86dFs1XSx3aWR0aDp0WzZdLGNvbW1hOnRbN10scHJlY2lzaW9uOnRbOF0mJnRbOF0uc2xpY2UoMSksdHJpbTp0WzldLHR5cGU6dFsxMF19KX1xci5wcm90b3R5cGU9YWMucHJvdG90eXBlO2Z1bmN0aW9uIGFjKGkpe3RoaXMuZmlsbD1pLmZpbGw9PT12b2lkIDA/IiAiOmkuZmlsbCsiIix0aGlzLmFsaWduPWkuYWxpZ249PT12b2lkIDA/Ij4iOmkuYWxpZ24rIiIsdGhpcy5zaWduPWkuc2lnbj09PXZvaWQgMD8iLSI6aS5zaWduKyIiLHRoaXMuc3ltYm9sPWkuc3ltYm9sPT09dm9pZCAwPyIiOmkuc3ltYm9sKyIiLHRoaXMuemVybz0hIWkuemVybyx0aGlzLndpZHRoPWkud2lkdGg9PT12b2lkIDA/dm9pZCAwOitpLndpZHRoLHRoaXMuY29tbWE9ISFpLmNvbW1hLHRoaXMucHJlY2lzaW9uPWkucHJlY2lzaW9uPT09dm9pZCAwP3ZvaWQgMDoraS5wcmVjaXNpb24sdGhpcy50cmltPSEhaS50cmltLHRoaXMudHlwZT1pLnR5cGU9PT12b2lkIDA/IiI6aS50eXBlKyIifWFjLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmZpbGwrdGhpcy5hbGlnbit0aGlzLnNpZ24rdGhpcy5zeW1ib2wrKHRoaXMuemVybz8iMCI6IiIpKyh0aGlzLndpZHRoPT09dm9pZCAwPyIiOk1hdGgubWF4KDEsdGhpcy53aWR0aHwwKSkrKHRoaXMuY29tbWE/IiwiOiIiKSsodGhpcy5wcmVjaXNpb249PT12b2lkIDA/IiI6Ii4iK01hdGgubWF4KDAsdGhpcy5wcmVjaXNpb258MCkpKyh0aGlzLnRyaW0/In4iOiIiKSt0aGlzLnR5cGV9O2Z1bmN0aW9uIEttKGkpe3Q6Zm9yKHZhciB0PWkubGVuZ3RoLGU9MSxuPS0xLHM7ZTx0OysrZSlzd2l0Y2goaVtlXSl7Y2FzZSIuIjpuPXM9ZTticmVhaztjYXNlIjAiOm49PT0wJiYobj1lKSxzPWU7YnJlYWs7ZGVmYXVsdDppZighK2lbZV0pYnJlYWsgdDtuPjAmJihuPTApO2JyZWFrfXJldHVybiBuPjA/aS5zbGljZSgwLG4pK2kuc2xpY2UocysxKTppfXZhciB5dTtmdW5jdGlvbiB0ZyhpLHQpe3ZhciBlPVZyKGksdCk7aWYoIWUpcmV0dXJuIGkrIiI7dmFyIG49ZVswXSxzPWVbMV0scj1zLSh5dT1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3Iocy8zKSkpKjMpKzEsbz1uLmxlbmd0aDtyZXR1cm4gcj09PW8/bjpyPm8/bituZXcgQXJyYXkoci1vKzEpLmpvaW4oIjAiKTpyPjA/bi5zbGljZSgwLHIpKyIuIituLnNsaWNlKHIpOiIwLiIrbmV3IEFycmF5KDEtcikuam9pbigiMCIpK1ZyKGksTWF0aC5tYXgoMCx0K3ItMSkpWzBdfWZ1bmN0aW9uIG11KGksdCl7dmFyIGU9VnIoaSx0KTtpZighZSlyZXR1cm4gaSsiIjt2YXIgbj1lWzBdLHM9ZVsxXTtyZXR1cm4gczwwPyIwLiIrbmV3IEFycmF5KC1zKS5qb2luKCIwIikrbjpuLmxlbmd0aD5zKzE/bi5zbGljZSgwLHMrMSkrIi4iK24uc2xpY2UocysxKTpuK25ldyBBcnJheShzLW4ubGVuZ3RoKzIpLmpvaW4oIjAiKX12YXIgZ3U9eyIlIjooaSx0KT0+KGkqMTAwKS50b0ZpeGVkKHQpLGI6aT0+TWF0aC5yb3VuZChpKS50b1N0cmluZygyKSxjOmk9PmkrIiIsZDpKbSxlOihpLHQpPT5pLnRvRXhwb25lbnRpYWwodCksZjooaSx0KT0+aS50b0ZpeGVkKHQpLGc6KGksdCk9PmkudG9QcmVjaXNpb24odCksbzppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDgpLHA6KGksdCk9Pm11KGkqMTAwLHQpLHI6bXUsczp0ZyxYOmk9Pk1hdGgucm91bmQoaSkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkseDppPT5NYXRoLnJvdW5kKGkpLnRvU3RyaW5nKDE2KX07ZnVuY3Rpb24geHUoaSl7cmV0dXJuIGl9dmFyIHd1PUFycmF5LnByb3RvdHlwZS5tYXAsYnU9WyJ5IiwieiIsImEiLCJmIiwicCIsIm4iLCLCtSIsIm0iLCIiLCJrIiwiTSIsIkciLCJUIiwiUCIsIkUiLCJaIiwiWSJdO2Z1bmN0aW9uIGVnKGkpe3ZhciB0PWkuZ3JvdXBpbmc9PT12b2lkIDB8fGkudGhvdXNhbmRzPT09dm9pZCAwP3h1OlltKHd1LmNhbGwoaS5ncm91cGluZyxOdW1iZXIpLGkudGhvdXNhbmRzKyIiKSxlPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVswXSsiIixuPWkuY3VycmVuY3k9PT12b2lkIDA/IiI6aS5jdXJyZW5jeVsxXSsiIixzPWkuZGVjaW1hbD09PXZvaWQgMD8iLiI6aS5kZWNpbWFsKyIiLHI9aS5udW1lcmFscz09PXZvaWQgMD94dTpqbSh3dS5jYWxsKGkubnVtZXJhbHMsU3RyaW5nKSksbz1pLnBlcmNlbnQ9PT12b2lkIDA/IiUiOmkucGVyY2VudCsiIixhPWkubWludXM9PT12b2lkIDA/IuKIkiI6aS5taW51cysiIixjPWkubmFuPT09dm9pZCAwPyJOYU4iOmkubmFuKyIiO2Z1bmN0aW9uIGwodSl7dT1xcih1KTt2YXIgZj11LmZpbGwsZD11LmFsaWduLHA9dS5zaWduLHk9dS5zeW1ib2wsbT11Lnplcm8sZz11LndpZHRoLGI9dS5jb21tYSx3PXUucHJlY2lzaW9uLHg9dS50cmltLE09dS50eXBlO009PT0ibiI/KGI9ITAsTT0iZyIpOmd1W01dfHwodz09PXZvaWQgMCYmKHc9MTIpLHg9ITAsTT0iZyIpLChtfHxmPT09IjAiJiZkPT09Ij0iKSYmKG09ITAsZj0iMCIsZD0iPSIpO3ZhciBBPXk9PT0iJCI/ZTp5PT09IiMiJiYvW2JveFhdLy50ZXN0KE0pPyIwIitNLnRvTG93ZXJDYXNlKCk6IiIsXz15PT09IiQiP246L1slcF0vLnRlc3QoTSk/bzoiIixTPWd1W01dLEU9L1tkZWZncHJzJV0vLnRlc3QoTSk7dz13PT09dm9pZCAwPzY6L1tncHJzXS8udGVzdChNKT9NYXRoLm1heCgxLE1hdGgubWluKDIxLHcpKTpNYXRoLm1heCgwLE1hdGgubWluKDIwLHcpKTtmdW5jdGlvbiB6KHYpe3ZhciBDPUEsUD1fLEYsQixJO2lmKE09PT0iYyIpUD1TKHYpK1Asdj0iIjtlbHNle3Y9K3Y7dmFyIGs9djwwfHwxL3Y8MDtpZih2PWlzTmFOKHYpP2M6UyhNYXRoLmFicyh2KSx3KSx4JiYodj1LbSh2KSksayYmK3Y9PTAmJnAhPT0iKyImJihrPSExKSxDPShrP3A9PT0iKCI/cDphOnA9PT0iLSJ8fHA9PT0iKCI/IiI6cCkrQyxQPShNPT09InMiP2J1WzgreXUvM106IiIpK1ArKGsmJnA9PT0iKCI/IikiOiIiKSxFKXtmb3IoRj0tMSxCPXYubGVuZ3RoOysrRjxCOylpZihJPXYuY2hhckNvZGVBdChGKSw0OD5JfHxJPjU3KXtQPShJPT09NDY/cyt2LnNsaWNlKEYrMSk6di5zbGljZShGKSkrUCx2PXYuc2xpY2UoMCxGKTticmVha319fWImJiFtJiYodj10KHYsMS8wKSk7dmFyIEQ9Qy5sZW5ndGgrdi5sZW5ndGgrUC5sZW5ndGgsVj1EPGc/bmV3IEFycmF5KGctRCsxKS5qb2luKGYpOiIiO3N3aXRjaChiJiZtJiYodj10KFYrdixWLmxlbmd0aD9nLVAubGVuZ3RoOjEvMCksVj0iIiksZCl7Y2FzZSI8Ijp2PUMrditQK1Y7YnJlYWs7Y2FzZSI9Ijp2PUMrVit2K1A7YnJlYWs7Y2FzZSJeIjp2PVYuc2xpY2UoMCxEPVYubGVuZ3RoPj4xKStDK3YrUCtWLnNsaWNlKEQpO2JyZWFrO2RlZmF1bHQ6dj1WK0MrditQO2JyZWFrfXJldHVybiByKHYpfXJldHVybiB6LnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHUrIiJ9LHp9ZnVuY3Rpb24gaCh1LGYpe3ZhciBkPWwoKHU9cXIodSksdS50eXBlPSJmIix1KSkscD1NYXRoLm1heCgtOCxNYXRoLm1pbig4LE1hdGguZmxvb3IoZmkoZikvMykpKSozLHk9TWF0aC5wb3coMTAsLXApLG09YnVbOCtwLzNdO3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZCh5KmcpK219fXJldHVybntmb3JtYXQ6bCxmb3JtYXRQcmVmaXg6aH19dmFyIEhyLE11LEF1O25nKHt0aG91c2FuZHM6IiwiLGdyb3VwaW5nOlszXSxjdXJyZW5jeTpbIiQiLCIiXX0pO2Z1bmN0aW9uIG5nKGkpe3JldHVybiBIcj1lZyhpKSxNdT1Ici5mb3JtYXQsQXU9SHIuZm9ybWF0UHJlZml4LEhyfWZ1bmN0aW9uIGlnKGkpe3JldHVybiBNYXRoLm1heCgwLC1maShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIHNnKGksdCl7cmV0dXJuIE1hdGgubWF4KDAsTWF0aC5tYXgoLTgsTWF0aC5taW4oOCxNYXRoLmZsb29yKGZpKHQpLzMpKSkqMy1maShNYXRoLmFicyhpKSkpfWZ1bmN0aW9uIHJnKGksdCl7cmV0dXJuIGk9TWF0aC5hYnMoaSksdD1NYXRoLmFicyh0KS1pLE1hdGgubWF4KDAsZmkodCktZmkoaSkpKzF9ZnVuY3Rpb24gb2coaSx0LGUsbil7dmFyIHM9SjAoaSx0LGUpLHI7c3dpdGNoKG49cXIobj09bnVsbD8iLGYiOm4pLG4udHlwZSl7Y2FzZSJzIjp7dmFyIG89TWF0aC5tYXgoTWF0aC5hYnMoaSksTWF0aC5hYnModCkpO3JldHVybiBuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9c2cocyxvKSkmJihuLnByZWNpc2lvbj1yKSxBdShuLG8pfWNhc2UiIjpjYXNlImUiOmNhc2UiZyI6Y2FzZSJwIjpjYXNlInIiOntuLnByZWNpc2lvbj09bnVsbCYmIWlzTmFOKHI9cmcocyxNYXRoLm1heChNYXRoLmFicyhpKSxNYXRoLmFicyh0KSkpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSJlIikpO2JyZWFrfWNhc2UiZiI6Y2FzZSIlIjp7bi5wcmVjaXNpb249PW51bGwmJiFpc05hTihyPWlnKHMpKSYmKG4ucHJlY2lzaW9uPXItKG4udHlwZT09PSIlIikqMik7YnJlYWt9fXJldHVybiBNdShuKX1mdW5jdGlvbiBhZyhpKXt2YXIgdD1pLmRvbWFpbjtyZXR1cm4gaS50aWNrcz1mdW5jdGlvbihlKXt2YXIgbj10KCk7cmV0dXJuIFgwKG5bMF0sbltuLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUpfSxpLnRpY2tGb3JtYXQ9ZnVuY3Rpb24oZSxuKXt2YXIgcz10KCk7cmV0dXJuIG9nKHNbMF0sc1tzLmxlbmd0aC0xXSxlPT1udWxsPzEwOmUsbil9LGkubmljZT1mdW5jdGlvbihlKXtlPT1udWxsJiYoZT0xMCk7dmFyIG49dCgpLHM9MCxyPW4ubGVuZ3RoLTEsbz1uW3NdLGE9bltyXSxjLGwsaD0xMDtmb3IoYTxvJiYobD1vLG89YSxhPWwsbD1zLHM9cixyPWwpO2gtLSA+MDspe2lmKGw9Z2EobyxhLGUpLGw9PT1jKXJldHVybiBuW3NdPW8sbltyXT1hLHQobik7aWYobD4wKW89TWF0aC5mbG9vcihvL2wpKmwsYT1NYXRoLmNlaWwoYS9sKSpsO2Vsc2UgaWYobDwwKW89TWF0aC5jZWlsKG8qbCkvbCxhPU1hdGguZmxvb3IoYSpsKS9sO2Vsc2UgYnJlYWs7Yz1sfXJldHVybiBpfSxpfWZ1bmN0aW9uIGNjKCl7dmFyIGk9WG0oKTtyZXR1cm4gaS5jb3B5PWZ1bmN0aW9uKCl7cmV0dXJuIEdtKGksY2MoKSl9LG1tLmFwcGx5KGksYXJndW1lbnRzKSxhZyhpKX1mdW5jdGlvbiBjZyhpLHQpe3JldHVybiBpLm1hcChlPT57Y29uc3Qgbj1bXTtsZXQgcztyZXR1cm4gZS5mb3JFYWNoKHI9PntpZihzKXtjb25zdCBvPXNpKHIscykqMTgwL01hdGguUEk7aWYobz50KXtjb25zdCBhPUJwKHMsciksYz0xL01hdGguY2VpbChvL3QpO2xldCBsPWM7Zm9yKDtsPDE7KW4ucHVzaChhKGwpKSxsKz1jfX1uLnB1c2gocz1yKX0pLG59KX1mdW5jdGlvbiBsZyhpLHttaW5Mbmc6dCxtYXhMbmc6ZSxtaW5MYXQ6bixtYXhMYXQ6c309e30pe2NvbnN0IHI9TWF0aC5yb3VuZChkaSgzNjAvaSwyKS9NYXRoLlBJKSxvPSgxK01hdGguc3FydCg1KSkvMixhPWQ9PmQvbyozNjAlMzYwLTE4MCxjPWQ9Pk1hdGguYWNvcygyKmQvci0xKS9NYXRoLlBJKjE4MC05MCxsPWQ9PnIqKE1hdGguY29zKChkKzkwKSpNYXRoLlBJLzE4MCkrMSkvMixoPVtzIT09dm9pZCAwP01hdGguY2VpbChsKHMpKTowLG4hPT12b2lkIDA/TWF0aC5mbG9vcihsKG4pKTpyLTFdLHU9dD09PXZvaWQgMCYmZT09PXZvaWQgMD8oKT0+ITA6dD09PXZvaWQgMD9kPT5kPD1lOmU9PT12b2lkIDA/ZD0+ZD49dDplPj10P2Q9PmQ+PXQmJmQ8PWU6ZD0+ZD49dHx8ZDw9ZSxmPVtdO2ZvcihsZXQgZD1oWzBdO2Q8PWhbMV07ZCsrKXtjb25zdCBwPWEoZCk7dShwKSYmZi5wdXNoKFtwLGMoZCldKX1yZXR1cm4gZn1mdW5jdGlvbiBsYyhpLHQsZT0hMSl7cmV0dXJuIGU/Q3AodCxpKTpIeShpLHQpfWZ1bmN0aW9uIGhnKGksdCl7Y29uc3QgZT17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tuLHNdLFtyLG9dXT1paChlKTtpZihNYXRoLm1pbihNYXRoLmFicyhyLW4pLE1hdGguYWJzKG8tcykpPHQpcmV0dXJuW107Y29uc3QgYT1uPnJ8fG8+PTg5fHxzPD0tODk7cmV0dXJuIGxnKHQse21pbkxuZzpuLG1heExuZzpyLG1pbkxhdDpzLG1heExhdDpvfSkuZmlsdGVyKGM9PmxjKGMsZSxhKSl9ZnVuY3Rpb24gdWcoaSx7cmVzb2x1dGlvbjp0PTEvMCxiYm94OmUscHJvamVjdGlvbjpufT17fSl7Y29uc3Qgcz1jZyhpLHQpLHI9RGkocyksbz1oZyhpLHQpLGE9Wy4uLnIsLi4ub10sYz17dHlwZToiUG9seWdvbiIsY29vcmRpbmF0ZXM6aX0sW1tsLGhdLFt1LGZdXT1paChjKSxkPWw+dXx8Zj49ODl8fGg8PS04OTtsZXQgcD1bXTtpZihkKXtjb25zdCBNPXltKGEpLnRyaWFuZ2xlcygpLEE9bmV3IE1hcChhLm1hcCgoW18sU10sRSk9PltgJHtffS0ke1N9YCxFXSkpO00uZmVhdHVyZXMuZm9yRWFjaChfPT57Y29uc3QgUz1fLmdlb21ldHJ5LmNvb3JkaW5hdGVzWzBdLnNsaWNlKDAsMykucmV2ZXJzZSgpLEU9W107aWYoUy5mb3JFYWNoKChbeix2XSk9Pntjb25zdCBDPWAke3p9LSR7dn1gO0EuaGFzKEMpJiZFLnB1c2goQS5nZXQoQykpfSksRS5sZW5ndGg9PT0zKXtpZihFLnNvbWUoej0+ejxyLmxlbmd0aCkpe2NvbnN0IHo9Xy5wcm9wZXJ0aWVzLmNpcmN1bWNlbnRlcjtpZighbGMoeixjLGQpKXJldHVybn1wLnB1c2goLi4uRSl9fSl9ZWxzZSBpZihvLmxlbmd0aCl7Y29uc3QgTT1qaS5mcm9tKGEpO2ZvcihsZXQgQT0wLF89TS50cmlhbmdsZXMubGVuZ3RoO0E8XztBKz0zKXtjb25zdCBTPVsyLDEsMF0ubWFwKHo9Pk0udHJpYW5nbGVzW0Erel0pLEU9Uy5tYXAoej0+YVt6XSk7aWYoUy5zb21lKHo9Pno8ci5sZW5ndGgpKXtjb25zdCB6PVswLDFdLm1hcCh2PT5ZMChFLEM9PkNbdl0pKTtpZighbGMoeixjLGQpKWNvbnRpbnVlfXAucHVzaCguLi5TKX19ZWxzZXtjb25zdHt2ZXJ0aWNlczpNLGhvbGVzOkE9W119PVZoKHMpO3A9YXkoTSxBLDIpfWxldCB5PWU/W2VbMF0sZVsyXV06ZXIoYSxNPT5NWzBdKSxtPWU/W2VbMV0sZVszXV06ZXIoYSxNPT5NWzFdKTtpZihuKXtjb25zdFtNLEFdPW4oW3lbMF0sbVswXV0pLFtfLFNdPW4oW3lbMV0sbVsxXV0pO3k9W00sX10sbT1bLUEsLVNdfWNvbnN0IGc9Y2MoeSxbMCwxXSksYj1jYyhtLFswLDFdKSx3PWEubWFwKChbTSxBXSk9PntpZihuKXtjb25zdFtfLFNdPW4oW00sQV0pO3JldHVybltnKF8pLGIoLVMpXX1lbHNlIHJldHVybltnKE0pLGIoQSldfSk7cmV0dXJue2NvbnRvdXI6cyx0cmlhbmdsZXM6e3BvaW50czphLGluZGljZXM6cCx1dnM6d319fWNvbnN0IF91PW5ldyB1ZSgpLnNldEF0dHJpYnV0ZT8ic2V0QXR0cmlidXRlIjoiYWRkQXR0cmlidXRlIjtmdW5jdGlvbiBXcihpLHQsZSxuKXtjb25zdCBzPWkubWFwKHI9PnIubWFwKChbbyxhXSk9PntpZihuKXtjb25zdFtjLGxdPW4oW28sYV0pO3JldHVybltjLC1sLHRdfXJldHVybiBlPyQwKG8sYSx0KTpbbyxhLHRdfSkpO3JldHVybiBWaChzKX1mdW5jdGlvbiBmZyhpLHQsZSxuLHMpe2NvbnN0e3ZlcnRpY2VzOnIsaG9sZXM6b309V3IoaSx0LG4scykse3ZlcnRpY2VzOmF9PVdyKGksZSxuLHMpLGM9RGkoW2Escl0pLGw9TWF0aC5yb3VuZChhLmxlbmd0aC8zKSxoPW5ldyBTZXQobyk7bGV0IHU9MDtjb25zdCBmPVtdO2ZvcihsZXQgcD0wO3A8bDtwKyspe2xldCB5PXArMTtpZih5PT09bCl5PXU7ZWxzZSBpZihoLmhhcyh5KSl7Y29uc3QgbT15O3k9dSx1PW19Zi5wdXNoKHAscCtsLHkrbCksZi5wdXNoKHkrbCx5LHApfWNvbnN0IGQ9W107Zm9yKGxldCBwPTE7cD49MDtwLS0pZm9yKGxldCB5PTA7eTxsO3krPTEpZC5wdXNoKHkvKGwtMSkscCk7cmV0dXJue2luZGljZXM6Zix2ZXJ0aWNlczpjLHV2czpkLHRvcFZlcnRzOmF9fWZ1bmN0aW9uIFN1KGksdCxlLG4scyxyKXtyZXR1cm57aW5kaWNlczpuP2kuaW5kaWNlczppLmluZGljZXMuc2xpY2UoKS5yZXZlcnNlKCksdmVydGljZXM6V3IoW2kucG9pbnRzXSx0LHMscikudmVydGljZXMsdXZzOmV9fWNvbnN0IHZ1PSh7cG9seWdvbkdlb0pzb246aSxzdGFydEhlaWdodDp0LGVuZEhlaWdodDplLGN1cnZhdHVyZVJlc29sdXRpb246bj0xLGNhcnRlc2lhbjpzPSEwLGhhc1NpZGU6cj0hMCxoYXNCb3R0b206bz0hMSxoYXNUb3A6YT0hMSxwcm9qZWN0aW9uOmMsYmJveDpsfSk9PntpLmZvckVhY2goZz0+e0V5KGcpfHxnLnJldmVyc2UoKX0pO2NvbnN0e2NvbnRvdXI6aCx0cmlhbmdsZXM6dX09dWcoaSx7cmVzb2x1dGlvbjpuLGJib3g6bCxwcm9qZWN0aW9uOmN9KTtsZXQgZj17fSxkO3ImJihmPWZnKGgsdCE9bnVsbD90OmUsZSE9bnVsbD9lOnQscyxjKSxkPWYudG9wVmVydHMpO2xldCBwPVtdOyhvfHxhKSYmKHA9RGkodS51dnMpKTtsZXQgeT17fTtvJiYoeT1TdSh1LHQscCwhMSxzLGMpKTtsZXQgbT17fTtyZXR1cm4gYSYmKG09U3UodSxlLHAsITAscyxjKSkse2NvbnRvdXI6aCx0cmlhbmdsZXM6dSxzaWRlVG9yc286Zixib3R0b21DYXA6eSx0b3BDYXA6bSx0b3BWZXJ0czpkfX07Y2xhc3MgZGcgZXh0ZW5kcyB1ZXtjb25zdHJ1Y3Rvcih0LGU9e30pe3N1cGVyKCksdGhpcy50eXBlPSJQb2x5Z29uQnVmZmVyR2VvbWV0cnkiLHRoaXMucGFyYW1ldGVycz1GdCh7cG9seWdvbkdlb0pzb246dCxzdGFydEhlaWdodDowLGVuZEhlaWdodDoxLGhhc1RvcDohMCx0b3BGaXJzdDohMSxoYXNCb3R0b206ITAsaGFzU2lkZTohMCxjdXJ2YXR1cmVSZXNvbHV0aW9uOjEsY2FydGVzaWFuOiEwLHVzZXJEYXRhUnNvT2Zmc2V0OjB9LGUpO2NvbnN0e2VuZEhlaWdodDpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHVzZXJEYXRhUnNvT2Zmc2V0OmwscHJvamVjdGlvbjpofT10aGlzLnBhcmFtZXRlcnMse2NvbnRvdXI6dSxzaWRlVG9yc286Zix0b3BWZXJ0czpkLGJvdHRvbUNhcDpwLHRvcENhcDp5fT12dShGdCh7fSx0aGlzLnBhcmFtZXRlcnMpKTtsZXQgbT1bXSxnPVtdLGI9W10sdz0wO2NvbnN0IHg9TT0+e2NvbnN0IEE9TWF0aC5yb3VuZChtLmxlbmd0aC8zKSxfPWIubGVuZ3RoO209bS5jb25jYXQoTS52ZXJ0aWNlcyksZz1nLmNvbmNhdChNLnV2cyksYj1iLmNvbmNhdChBP00uaW5kaWNlcy5tYXAoUz0+UytBKTpNLmluZGljZXMpLHRoaXMuYWRkR3JvdXAoXyxiLmxlbmd0aC1fLHcrKyl9O3MmJnImJngoeSksYSYmKHgoZiksdGhpcy51c2VyRGF0YS50b3BWZXJ0cz1sP1dyKHUsbitsLGMsaCkudmVydGljZXM6ZCksbyYmeChwKSxzJiYhciYmeCh5KSx0aGlzLnNldEluZGV4KGIpLHRoaXNbX3VdKCJwb3NpdGlvbiIsbmV3IENlKG0sMykpLHRoaXNbX3VdKCJ1diIsbmV3IENlKGcsMikpLHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKX19dmFyIHBnPWk9Pntjb25zdCBhPWkse2Nvb3JkaW5hdGU6dCxzdGFydEhlaWdodDplLGhlaWdodDpufT1hLHM9RHUoYSxbImNvb3JkaW5hdGUiLCJzdGFydEhlaWdodCIsImhlaWdodCJdKTtsZXQgcj1lfHwwO3JldHVybiB0eXBlb2YgZSE9InVuZGVmaW5lZCImJnR5cGVvZiBuIT0idW5kZWZpbmVkIiYmKHI9ZStuKSxuZXcgZGcoW3RdLEdlKEZ0KHt9LHMpLHtzdGFydEhlaWdodDplLGVuZEhlaWdodDpyfSkpfTtjb25zdCB5Zz0oe2Nvb3JkaW5hdGVzQXJyOmksc3RhcnQ6dCxkZXB0aDplLHVzZUdyb3VwczpuLGhhc1RvcDpzLHRvcEZpcnN0OnIsaGFzQm90dG9tOm8saGFzU2lkZTphLGNhcnRlc2lhbjpjLHByb2plY3Rpb246bCxjdXJ2YXR1cmVSZXNvbHV0aW9uOmgsYmJveDp1LGJib3hPZmZzZXQ6Zn0pPT57Y29uc3QgZD1sJiZXaShsKTtpZihkJiYoYz0hMSx1JiZmKSl7bGV0IHk9ZChbdVswXSx1WzFdXSksbT1kKFt1WzJdLHVbM11dKTt5WzFdPS15WzFdLG1bMV09LW1bMV0seVswXSs9ZlswXSx5WzFdKz1mWzFdLG1bMF0rPWZbMl0sbVsxXSs9ZlszXSx5PWQuaW52ZXJ0KFt5WzBdLC15WzFdXSl8fHksbT1kLmludmVydChbbVswXSwtbVsxXV0pfHxtLHU9W3lbMF0seVsxXSxtWzBdLG1bMV1dfXR8fCh0PVswXSk7Y29uc3QgcD1pLm1hcCgoeSxtKT0+e3ZhciBnLGI7cmV0dXJuIHBnKHtjb29yZGluYXRlOnkscHJvamVjdGlvbjpkLHN0YXJ0SGVpZ2h0OihnPXRbbV0pIT1udWxsP2c6dFswXSxoZWlnaHQ6KGI9ZVttXSkhPW51bGw/YjplWzBdLGhhc1RvcDpzIT1udWxsP3M6ITAsdG9wRmlyc3Q6ciE9bnVsbD9yOiExLGhhc0JvdHRvbTpvIT1udWxsP286ITAsaGFzU2lkZTphIT1udWxsP2E6ITAsY2FydGVzaWFuOmMhPW51bGw/YzohMCxjdXJ2YXR1cmVSZXNvbHV0aW9uOmghPW51bGw/aDoxLGJib3g6dX0pfSk7cmV0dXJuIEdpKHAsbil9LG1nPSh7Y29vcmRpbmF0ZXNBcnI6aSxsaW5lV2lkdGg6dCxzdGFydDplLHVzZUdyb3VwczpufSk9Pntjb25zdCByPWkubWFwKChvLGEpPT57dmFyIGM7cmV0dXJuIHZ1KHtwb2x5Z29uR2VvSnNvbjpbb10sc3RhcnRIZWlnaHQ6KGM9ZVthXSkhPW51bGw/YzplWzBdfSkudG9wVmVydHN9KS5tYXAoKG8sYSk9Pnt2YXIgbDtjb25zdCBjPShsPXRbYV0pIT1udWxsP2w6dFswXTtyZXR1cm4gTGgoe25vZGVzOm8sc2V0UG9pbnRXaWR0aDooKT0+Y30pfSk7cmV0dXJuIEdpKHIsbil9O3ZhciBnZz0oaSx0LGUpPT5uZXcgUHJvbWlzZSgobixzKT0+e3ZhciByPWM9Pnt0cnl7YShlLm5leHQoYykpfWNhdGNoKGwpe3MobCl9fSxvPWM9Pnt0cnl7YShlLnRocm93KGMpKX1jYXRjaChsKXtzKGwpfX0sYT1jPT5jLmRvbmU/bihjLnZhbHVlKTpQcm9taXNlLnJlc29sdmUoYy52YWx1ZSkudGhlbihyLG8pO2EoKGU9ZS5hcHBseShpLHQpKS5uZXh0KCkpfSk7ZnVuY3Rpb24geGcoaSl7cmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGkpLnJlZHVjZShmdW5jdGlvbih0LGUpe3JldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkodCxlLHt2YWx1ZTppW2VdLGVudW1lcmFibGU6ITB9KX0se30pfShpPT57Y29uc3QgdD17cnVuKGUsbil7Y29uc3Qgcz1uZXcgRnVuY3Rpb24oInJldHVybiAoIitlKyIpLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7Iik7cmV0dXJuIHMuYXBwbHkocyxuKX0sbWV0aG9kcygpe3JldHVybiBPYmplY3Qua2V5cyh0KX19O2FkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGU9PmdnKHZvaWQgMCxbZV0sZnVuY3Rpb24qKHtkYXRhOm59KXt0cnl7Y29uc3Qgcz10W24ubWV0aG9kXTtpZihzKXtjb25zdCByPXlpZWxkIHMuYXBwbHkocyxuLnBhcmFtcyk7ci50cmFuc2ZlciYmci5tZXNzYWdlP3Bvc3RNZXNzYWdlKHtpZDpuLmlkLHJlc3VsdDpyLm1lc3NhZ2UsZXJyb3I6bnVsbH0sci50cmFuc2Zlcik6cG9zdE1lc3NhZ2Uoe2lkOm4uaWQscmVzdWx0OnIsZXJyb3I6bnVsbH0pfWVsc2UgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG1ldGhvZCAiJytuLm1ldGhvZCsnIicpfWNhdGNoKHMpe3Bvc3RNZXNzYWdlKHtpZDpuLmlkLHJlc3VsdDpudWxsLGVycm9yOnhnKHMpfSl9fSkpLE9iamVjdC5rZXlzKGkpLmZvckVhY2goZT0+e3RbZV09aVtlXX0pLHBvc3RNZXNzYWdlKCJyZWFkeSIpfSkoe2V4dHJ1ZGVQb2x5Z29uOmV5LGxpbmU6c3ksbGluZTI6b3ksY29uaWNQb2x5Z29uOnlnLGNvbmljTGluZTptZ30pfSkoKTsK",N=g=>Uint8Array.from(atob(g),t=>t.charCodeAt(0)),z=typeof window!="undefined"&&window.Blob&&new Blob([N(o)],{type:"text/javascript;charset=utf-8"});function T(g){let t;try{if(t=z&&(window.URL||window.webkitURL).createObjectURL(z),!t)throw"";const r=new Worker(t,{name:g==null?void 0:g.name});return r.addEventListener("error",()=>{(window.URL||window.webkitURL).revokeObjectURL(t)}),r}catch(r){return new Worker("data:text/javascript;base64,"+o,{name:g==null?void 0:g.name})}finally{t&&(window.URL||window.webkitURL).revokeObjectURL(t)}}const R=g=>{const t=new BufferGeometry;return Object.keys(g).forEach(r=>{r==="groups"?g[r].forEach(d=>{t.addGroup(d.start,d.count,d.materialIndex)}):r==="index"?t.setIndex(new BufferAttribute(g[r].array,g[r].itemSize)):t.setAttribute(r,new BufferAttribute(g[r].array,g[r].itemSize))}),t};class Q{constructor(t){this.pluginName="worker",this.bufferGeometryLoader=new BufferGeometryLoader,this.cacheObj={},this._dispose=!1,this.options=W({dbName:"base",cacheVersion:"1"},t),this.store=createStore(this.options.dbName,"attributes")}install(t){this.pencil=t;const r=new esusLite.WorkerPool(T,{maxWorkers:this.options.maxWorkers});this.pool=r}geoGeometry(t,r){return V(this,null,function*(){const{mesaage:d,cacheKey:v,userData:C,cacheVersion:w,cb:E}=W(W({},this.options),r),ye=this.pool,{err:Le,res:Re}=yield ye.exec(t,[W({},d)],void 0,!0);if(Le)throw Le;const Ne=R(Re);if(Object.assign(Ne.userData,W({},C)),E&&(yield E(Ne)),v){const{cacheObj:Fe}=this;Fe[v]||(Fe[v]={[w]:[]}),Fe[v][w].push(W({attributes:Re},C))}return Ne})}getCachedGeometry(t){return V(this,null,function*(){const{cacheKey:r,cacheVersion:d}=t;if(r){const v=yield get(r,this.store),C=d||this.options.cacheVersion;return v!=null&&v[C]?v[C].map(w=>{const E=w,{attributes:ye}=E,Le=x(E,["attributes"]),Re=R(ye);return Object.assign(Re.userData,W({},Le)),Re}):[]}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}),d=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 w=new InstancedMesh(t,d,6),E=new Object3D;E.position.set(-10.906,2.009,1.846),E.rotation.set(0,-.195,0),E.scale.set(2.328,7.905,4.651),E.updateMatrix(),w.setMatrixAt(0,E.matrix),E.position.set(-5.607,-.754,-.758),E.rotation.set(0,.994,0),E.scale.set(1.97,1.534,3.955),E.updateMatrix(),w.setMatrixAt(1,E.matrix),E.position.set(6.167,.857,7.803),E.rotation.set(0,.561,0),E.scale.set(3.927,6.285,3.687),E.updateMatrix(),w.setMatrixAt(2,E.matrix),E.position.set(-2.017,.018,6.124),E.rotation.set(0,.333,0),E.scale.set(2.002,4.566,2.064),E.updateMatrix(),w.setMatrixAt(3,E.matrix),E.position.set(2.291,-.756,-2.621),E.rotation.set(0,-.286,0),E.scale.set(1.546,1.552,1.496),E.updateMatrix(),w.setMatrixAt(4,E.matrix),E.position.set(-2.193,-.369,-5.547),E.rotation.set(0,.516,0),E.scale.set(3.875,3.487,2.986),E.updateMatrix(),w.setMatrixAt(5,E.matrix),this.add(w);const ye=new Mesh(t,createAreaLightMaterial(50));ye.position.set(-16.116,14.37,8.208),ye.scale.set(.1,2.428,2.739),this.add(ye);const Le=new Mesh(t,createAreaLightMaterial(50));Le.position.set(-16.109,18.021,-8.207),Le.scale.set(.1,2.425,2.751),this.add(Le);const Re=new Mesh(t,createAreaLightMaterial(17));Re.position.set(14.904,12.198,-1.832),Re.scale.set(.15,4.265,6.331),this.add(Re);const Ne=new Mesh(t,createAreaLightMaterial(43));Ne.position.set(-.462,8.89,14.52),Ne.scale.set(4.38,5.441,.088),this.add(Ne);const Fe=new Mesh(t,createAreaLightMaterial(20));Fe.position.set(3.235,11.486,-12.541),Fe.scale.set(2.5,2,.1),this.add(Fe);const at=new Mesh(t,createAreaLightMaterial(100));at.position.set(0,20,0),at.scale.set(1,.1,1),this.add(at)}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(){_0(this,"event",new events.EventEmitter);_0(this,"eventHandlers",{});_0(this,"on",this.event.on.bind(this.event));_0(this,"emit",this.event.emit.bind(this.event))}addListener(t,r,d,v=!1){r in this.eventHandlers||(this.eventHandlers[r]=[]),this.eventHandlers[r].push({node:t,handler:d,capture:v}),t.addEventListener(r,d,v)}removeListener(t,r){this.eventHandlers[r].filter(({node:d})=>t?d===t:!0).forEach(({node:d,handler:v,capture:C})=>d.removeEventListener(r,v,C)),this.eventHandlers[r]=this.eventHandlers[r].filter(({node:d})=>t?d!==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);_0(this,"container");_0(this,"pencil");_0(this,"cameraState",{})}setSaveCamera(r){const d=this.pencil,v=d.cameraPositon,C=d.cameraTarget;this.cameraState[r]=[v.x,v.y,v.z,C.x,C.y,C.z]}useSaveCamera(r,d=!1){return D0(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],d),!0):!1})}lookAt(r,d,v,C,w,E,ye=!1,Le=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=Le/1e3,yield this.pencil.controls.setLookAt(r,d,v,C,w,E,ye),this.pencil.controls.smoothTime=250/1e3})}truck(r,d,v=!1,C=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=C/1e3,this.pencil.controls.restThreshold=0,yield this.pencil.controls.truck(r,d,v),this.pencil.controls.restThreshold=.0025,this.pencil.controls.smoothTime=250/1e3})}dollyTo(r,d=!1,v=250){return D0(this,null,function*(){let C=r;if(typeof C=="string"){const[w,E]=C.split("=");w==="+"?C=this.pencil.controls.distance+ +E:w==="-"?C=this.pencil.controls.distance-+E:w==="*"?C=this.pencil.controls.distance*+E:w==="/"?C=this.pencil.controls.distance/+E:console.error("dollyTo distance error")}this.pencil.controls.smoothTime=v/1e3,yield this.pencil.controls.dollyTo(C,d),this.pencil.controls.smoothTime=250/1e3})}absoluteAngle(r,d){const v=Math.PI*2,C=r-d;return MathUtils.euclideanModulo(C+Math.PI,v)-Math.PI}lookAtTarget(r,d=!1,v=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=v/1e3;const C=this.pencil.controls.azimuthAngle,w=this.pencil.controls.polarAngle,E=this.pencil.controls.distance,ye=this.pencil.cameraTarget.clone(),Le=r.azimuthAngle||C,Re=r.polarAngle||w,Ne=r.distance||E,Fe=r.target||ye;yield Promise.all([this.pencil.controls.moveTo(Fe.x,Fe.y,Fe.z,d),this.pencil.controls.dollyTo(Ne,d),this.pencil.controls.rotateTo(C+this.absoluteAngle(Le,C),w+this.absoluteAngle(Re,w),d)]),this.pencil.controls.smoothTime=250/1e3})}paddingInCssPixel(r,d,v,C,w,E){const{camera:ye,controls:Le}=this.pencil,Re=ye.fov*MathUtils.DEG2RAD,Ne=this.pencil.getSize().height,{size:Fe}=r.getSize(),at=Fe.x,ot=Fe.y,Gt=Fe.z;let ht=Le.getDistanceToFitBox(at,ot,Gt),ke=0,ct=0,xt=0,Rt=0;for(let Wt=0;Wt<10;Wt++){const Pt=ht-Gt*.5,Nt=2*Math.tan(Re*.5)*Math.abs(Pt)/Ne;ke=d*Nt,ct=C*Nt,xt=w*Nt,Rt=v*Nt,ht=Le.getDistanceToFitBox(at+xt+Rt,ot+ke+ct,Gt)}return Le.fitToBox(r.object3d,E,{paddingLeft:xt,paddingRight:Rt,paddingBottom:ct,paddingTop:ke})}resetCamera(r=!1,d=250){return D0(this,null,function*(){this.pencil.controls.smoothTime=d/1e3,yield this.pencil.controls.reset(r),this.pencil.controls.smoothTime=250/1e3})}unproject(r,d=0){const v=new Vector3,C=new Vector3,{left:w,top:E,width:ye,height:Le}=this.container.getBoundingClientRect(),Re=(r.clientX-w)/ye*2-1,Ne=-((r.clientY-E)/Le)*2+1,Fe=this.pencil.cameraPositon.clone();v.set(Re,Ne,.5),v.unproject(this.pencil.camera),v.sub(Fe).normalize();const at=(d-Fe.z)/v.z;return C.copy(Fe).add(v.multiplyScalar(at)),C}dispose(){super.dispose(),this.cameraState={}}}class Command{constructor(t){_0(this,"id");_0(this,"updatable");_0(this,"type");_0(this,"name");_0(this,"editor");_0(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 d=this.editor.baseObjectByUuid(t.objectUuid);d&&(t.objectUuid=this.editor.uuidByBaseObject(d))}}fixJSON(){}}class SetColor extends Command{constructor(t,r,d,v){super(t),this.type="SetColor",this.name=`Set ${d}`,this.updatable=!0,this.object=r,this.attributeName=d,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,d,v,C){super(t),this.type="SetMaterialColor",this.name=`Set Material.${d}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[d].getHex():void 0,this.newValue=v,this.attributeName=d}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.uuidByObject(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.objectByUuid(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,d,v){var C;super(t),this.type="SetMaterial",this.name="New Material",this.object=r,this.materialSlot=v,this.oldMaterial=this.editor.getObjectMaterial(r,v),this.newMaterial=d,(C=this.oldMaterial)!=null&&C.name&&(this.newMaterial.name=this.oldMaterial.name)}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.uuidByObject(this.object),t.materialSlot=this.materialSlot,t.newMaterial=this.newMaterial.toJSON(),t}fromJSON(t){var r;super.fromJSON(t),this.object=this.editor.objectByUuid(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;t&&t.oldMaterial&&delete t.oldMaterial}}function parseMaterial(g){if(!g)return null;const t=new ObjectLoader,r=t.parseImages(g.images),d=t.parseTextures(g.textures,r);return t.parseMaterials([g],d)[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,d,v,C){super(t),this.type="SetMaterialMap",this.name=`Set Material.${d}`,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldMap=r!==void 0?this.material[d]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=d}execute(){if(this.oldMap){const t=new O;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 Ie$2&&(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 Ie$2&&(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.uuidByObject(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.objectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot),this.mapName=t.mapName,this.oldMap=this.object!==void 0?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 d=document.createElement("video");d.src=g.images[0].url,d.muted=!0,d.loop=!0,d.preload="auto";const v={[g.images[0].uuid]:new VideoTexture(d)};t=parseVideoTextures([g],v)[g.uuid]}else{const d=r.parseImages(g.images);t=r.parseTextures([g],d)[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 d={};if(g!==void 0)for(let v=0,C=g.length;v<C;v++){const w=g[v];let E=t[w.image];E.needsUpdate=!0,E.uuid=w.uuid,w.name!==void 0&&(E.name=w.name),w.mapping!==void 0&&(E.mapping=r(w.mapping,TEXTURE_MAPPING)),w.channel!==void 0&&(E.channel=w.channel),w.offset!==void 0&&E.offset.fromArray(w.offset),w.repeat!==void 0&&E.repeat.fromArray(w.repeat),w.center!==void 0&&E.center.fromArray(w.center),w.rotation!==void 0&&(E.rotation=w.rotation),w.wrap!==void 0&&(E.wrapS=r(w.wrap[0],TEXTURE_WRAPPING),E.wrapT=r(w.wrap[1],TEXTURE_WRAPPING)),w.format!==void 0&&(E.format=w.format),w.internalFormat!==void 0&&(E.internalFormat=w.internalFormat),w.type!==void 0&&(E.type=w.type),w.colorSpace!==void 0&&(E.colorSpace=w.colorSpace),w.encoding!==void 0&&(E.encoding=w.encoding),w.minFilter!==void 0&&(E.minFilter=r(w.minFilter,TEXTURE_FILTER)),w.magFilter!==void 0&&(E.magFilter=r(w.magFilter,TEXTURE_FILTER)),w.anisotropy!==void 0&&(E.anisotropy=w.anisotropy),w.flipY!==void 0&&(E.flipY=w.flipY),w.generateMipmaps!==void 0&&(E.generateMipmaps=w.generateMipmaps),w.premultiplyAlpha!==void 0&&(E.premultiplyAlpha=w.premultiplyAlpha),w.unpackAlignment!==void 0&&(E.unpackAlignment=w.unpackAlignment),w.compareFunction!==void 0&&(E.compareFunction=w.compareFunction),w.userData!==void 0&&(E.userData=w.userData),d[w.uuid]=E}return d};function serializeMap(g){if(g==null)return null;const t={geometries:{},materials:{},textures:{},images:{}},r=g.toJSON(t),d=extractFromCache(t.images);return g instanceof VideoTexture&&(d[0].url=g.source.data.src,r.isVideoTexture=!0),d.length>0&&(r.images=d),r.sourceFile=g.sourceFile,r}function extractFromCache(g){const t=[];for(const r in g){const d=g[r];delete d.metadata,t.push(d)}return t}const needsUpdateAttributeName=["transparent","alphaTest","fog","vertexColors","vertexShader","fragmentShader","sizeAttenuation"];class SetMaterialValue extends Command{constructor(t,r,d,v,C){super(t),this.type="SetMaterialValue",this.name=`Set Material.${d}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[d]:void 0,this.newValue=v,this.attributeName=d}execute(){this.material!==void 0&&(this.material[this.attributeName]=this.newValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("objectChanged",this.object),this.editor.emit("materialChanged",this.material),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("baseObjectListChange")}))}undo(){this.material[this.attributeName]=this.oldValue,needsUpdateAttributeName.includes(this.attributeName)&&(this.material.needsUpdate=!0),this.editor.emit("objectChanged",this.object),this.editor.emit("materialChanged",this.material),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("baseObjectListChange")})}update(t){this.newValue=t.newValue}toJSON(){const t=super.toJSON(this);return t.objectUuid=this.editor.uuidByObject(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.objectByUuid(t.objectUuid),this.materialSlot=t.materialSlot,this.material=this.editor.getObjectMaterial(this.object,this.materialSlot)}}class SetMaterialVector extends Command{constructor(t,r,d,v,C){super(t),this.type="SetMaterialVector",this.name=`Set Material.${d}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.oldValue=this.material!==void 0?this.material[d].toArray():void 0,this.newValue=v,this.attributeName=d}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.uuidByObject(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.objectByUuid(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,d,v,C,w="repeat"){var E,ye,Le,Re;super(t),this.type="SetMaterialMapVector",this.attributeName2=w,this.name=`Set Material.${d}.${w}`,this.updatable=!0,this.object=r,this.materialSlot=C,this.material=this.editor.getObjectMaterial(r,C),this.material instanceof Ie$2&&d==="map"&&w==="repeat"?this.oldValue=this.material.repeat.toArray():((ye=(E=this.material)==null?void 0:E[d])==null?void 0:ye[w])instanceof Vector2?this.oldValue=this.material[d][w].toArray():typeof((Re=(Le=this.material)==null?void 0:Le[d])==null?void 0:Re[w])!="undefined"&&(this.oldValue=this.material[d][w]),this.newValue=v,this.attributeName=d}execute(){var t,r,d,v,C;if((t=this.material)!=null&&t[this.attributeName]){const w=this.attributeName;this.material[w].wrapS!==RepeatWrapping&&(this.material[w].wrapS=RepeatWrapping,this.material[w].wrapT=RepeatWrapping,this.material[w].needsUpdate=!0)}this.material instanceof Ie$2&&this.attributeName==="map"&&this.attributeName2==="repeat"?this.material[this.attributeName2].fromArray(this.newValue):((d=(r=this.material)==null?void 0:r[this.attributeName])==null?void 0:d[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,d,v;this.material instanceof Ie$2&&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=(d=this.material)==null?void 0:d[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.uuidByObject(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.objectByUuid(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,d,v,C){super(t),this.type="SetPosition",this.name="Set Position",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&d!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=d.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,d,v){super(t),this.type="SetRotation",this.name="Set Rotation",this.updatable=!0,this.object=r,r!==void 0&&d!==void 0&&(this.oldRotation=r.rotation.clone(),this.newRotation=d.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,d,v){super(t),this.type="SetScale",this.name="Set Scale",this.updatable=!0,this.object=r,r!==void 0&&d!==void 0&&(this.oldScale=r.scale.clone(),this.newScale=d.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,d,v,C){super(t),this.type="SetValue",this.name=`Set ${d}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=d;const w=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=w!==void 0?w[d]: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),setTimeout(()=>{(this.attributeName==="name"||this.attributeName==="prefab")&&this.editor.emit("baseObjectListChange")})))}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()}undo(){const t=this.properties?this.object[this.properties]:this.object;t[this.attributeName]=this.oldValue,this.fixObj(),this.editor.emit("objectChanged",this.object),setTimeout(()=>{this.attributeName==="name"&&this.editor.emit("baseObjectListChange")})}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,d,v,C){super(t),this.type="SetVector",this.name=`Set ${d}`,this.updatable=!0,this.object=r,this.properties=C,this.attributeName=d;const w=r===void 0?void 0:this.properties?this.object[this.properties]:this.object;this.oldValue=w!==void 0?w[d].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,d,v){super(r);_0(this,"visType");_0(this,"visOptions");this.type="AddVis",this.visType=d,this.visOptions=v,d!==void 0&&(this.name=`Add Vis: ${d}`)}execute(){return D0(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,d,v){super(r);_0(this,"objectType");_0(this,"objectOptions");_0(this,"obj");_0(this,"addObjectUuid");this.type="AddObject",this.objectType=d,this.objectOptions=v,d!==void 0&&(this.name=`Add Object: ${d}`)}execute(){return D0(this,null,function*(){var d;const r=this.editor.viewport.vis;this.obj=yield r.lead.draw(this.objectType,Di(bi({},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),(d=this.editor.viewport.vis)==null||d.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,d){super(r);_0(this,"object");_0(this,"objectUuid");this.type="RemoveObject",this.name="Remove Object",this.object=d,this.objectUuid=this.editor.uuidByBaseObject(d)}execute(){this.object.hide(),this.object.userData.selectHide=!0,this.editor.emit("baseObjectListChange"),this.editor.select(null)}undo(){return D0(this,null,function*(){this.object.show(),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,d){super(r);_0(this,"object");_0(this,"copyObject",null);_0(this,"copyObjectUuid");this.type="CopyObject",this.name="Copy Object",this.object=d}execute(){return D0(this,null,function*(){var C;const r=this.editor.viewport.vis,d=this.object.key,v=yield this.object.instantiate(void 0,{key:`${this.id}`});this.copyObject=v,v.userData.updateKey!==!1&&r.lead.updateBaseObjectKey(v,`${d}_${this.id}`),this.copyObjectUuid=v.key,this.editor.select(this.copyObjectUuid),(C=this.editor.viewport.vis)==null||C.initBaseObjectUserData(v)})}undo(){return D0(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 SetSetting extends Command{constructor(r,d,v){super(r);_0(this,"attributeName");_0(this,"newValue");_0(this,"oldValue");this.type="SetSetting",this.updatable=!0,this.name=`Set Setting.${d}`,this.attributeName=d,this.newValue=v,r.viewport.vis&&(this.oldValue=r.viewport.vis.settings[d])}execute(){return D0(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 D0(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,d,v,C){super(t),this.type="SetTarget",this.name="Set Target",this.updatable=!0,this.cameraControls=C,this.object=r,r!==void 0&&d!==void 0&&(this.oldPosition=r.position.clone(),this.newPosition=d.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,d,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[d]:void 0,this.newMap=v,this.oldMap&&this.newMap&&(this.newMap.wrapS=this.oldMap.wrapS,this.newMap.wrapT=this.oldMap.wrapT),this.mapName=d}fromJSON(t){super.fromJSON(t),this.material=this.object[this.materialSlot]}}class SetGeometry extends Command{constructor(t,r=null,d){super(t),this.type="SetGeometry",this.name="Set Geometry",this.updatable=!0,this.object=r,this.oldGeometry=r!==null?r.geometry:null,this.newGeometry=d||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.oldGeometry=this.geometryToJSON(this.oldGeometry),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 Ve;return v.setPoints(t.points,t.variableWidth?C=>C:void 0),v}return new ObjectLoader().parseGeometries([t])[t.uuid]}fromJSON(t){super.fromJSON(t),this.object=this.editor.objectByUuid(t.objectUuid),this.oldGeometry=this.parseGeometry(t.oldGeometry),this.newGeometry=this.parseGeometry(t.newGeometry)}}const Commands=Object.freeze(Object.defineProperty({__proto__:null,AddObject,AddVis,CopyObject,RemoveObject,SetColor,SetGeometry,SetMaterial,SetMaterialColor,SetMaterialMap,SetMaterialMapVector,SetMaterialValue,SetMaterialVector,SetPosition,SetRotation,SetScale,SetSceenMap,SetSetting,SetTarget,SetValue,SetVector},Symbol.toStringTag,{value:"Module"}));class History{constructor(t){_0(this,"editor");_0(this,"undos");_0(this,"redos");_0(this,"lastCmdTime");_0(this,"idCounter");_0(this,"historyDisabled");this.editor=t,this.undos=[],this.redos=[],this.lastCmdTime=Date.now(),this.idCounter=0,this.historyDisabled=!1}execute(t,r){return D0(this,null,function*(){const d=this.undos[this.undos.length-1],v=Date.now()-this.lastCmdTime;d&&d.updatable&&t.updatable&&d.object===t.object&&d.type===t.type&&d.attributeName===t.attributeName&&d.attributeName2===t.attributeName2&&d.name===t.name&&d.objectUuid===t.objectUuid&&d.materialSlot===t.materialSlot&&v<500?(d.update(t),t=d):(this.undos.push(t),t.id=++this.idCounter),t.name=r!==void 0?r:t.name;try{yield t.execute()}catch(w){console.error(w,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;const t={u:[],i:[]};for(let d=0;d<this.undos.length;d++)if(this.undos[d].hasOwnProperty("json")){const v=this.undos[d].json;(r=v.newMap)!=null&&r.images?t.u.push(Di(bi({},v),{newMap:Di(bi({},v.newMap),{images:v.newMap.images.map(C=>{const w=t.i.findIndex(ye=>ye===C.url);let E=C.url;return w===-1?(t.i.push(C.url),E=`$rp-${t.i.length-1}`):E=`$rp-${w}`,Di(bi({},C),{url:E})})})})):t.u.push(bi({},v))}return t}fromJSON(t){var v;if(t===void 0)return;let r=-1;const d=t.i;for(let C=0;C<t.u.length;C++){const w=t.u[C];if(d!=null&&d.length&&((v=w.newMap)!=null&&v.images)&&w.newMap.images.forEach(ye=>{if(ye.url.startsWith("$rp-")){const Le=parseInt(ye.url.replace("$rp-",""));ye.url=d[Le]}}),w.id<=r){console.error("历史记录id错误");continue}if(w.type==="SetOption"||!w.type)continue;w.type.endsWith("Command")&&(w.type=w.type.replace("Command",""));const E=new Commands[w.type](this.editor);E.json=w,E.id=w.id,E.name=w.name,this.undos.push(E),this.idCounter=w.id>this.idCounter?w.id:this.idCounter,r=w.id}this.editor.emit("historyChanged",this.undos[this.undos.length-1])}processUndos(t=1e3/60){return new Promise((r,d)=>{const v=[...this.undos],C=v.length;let w=0;const E=()=>D0(this,null,function*(){const ye=performance.now();for(;v.length>0&&performance.now()-ye<t;){if(this.editor._dispose){d("dispose");return}const Le=v.shift(),Re=this.editor.hooks.events.beforeExecuteUndo.length?this.editor.hooks.dispatch("beforeExecuteUndo",Le):Le;Re&&(yield this.executeUndo(Re)),this.editor.hooks.events.afterExecuteUndo.length&&this.editor.hooks.dispatch("afterExecuteUndo",Le),w+=1}this.editor.emit("progress",{type:"还原场景",value:w/C*100|0}),v.length>0?requestAnimationFrame(E):r("")});requestAnimationFrame(E)})}executeUndo(t){return D0(this,null,function*(){t.fromJSON(t.json);try{t.json.type!=="AddObject"&&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){_0(this,"editor");_0(this,"vis");_0(this,"extendsOptions",{});_0(this,"cameraState",{});_0(this,"delLoadObj");_0(this,"options");this.options=r,this.editor=t}setSaveCamera(t){var r,d;this.vis.setSaveCamera(t),(r=this.vis.pencil.controls)==null||r.saveState(),this.cameraState=bi({},(d=this.vis)==null?void 0:d.cameraState),this.editor.emit("cameraStateChanged")}addVis(d){return D0(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(d){return D0(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=bi(bi({},r),this.extendsOptions);v=this.editor.hooks.events.beforeSetVisOptions.length?this.editor.hooks.dispatch("beforeSetVisOptions",v):v,this.vis.setOptions(v),this.vis.cameraState=bi({},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",(E,ye)=>{this.editor.emit("progress",{type:"下载资源",value:E/ye*100|0})}),this.vis.on("settingsChanged",()=>{this.editor.emit("settingsChanged")}),this.vis.on("show",()=>{this.editor.emit("visShow")}),yield this.vis.init();const{pencil:C}=this.vis;C.userData.EditorEnv=!this.editor.playing,this.editor.pencil=C,this.editor.changeSelectOption(),this.editor.playing||(this.initEvent(),this.editor.emit("visChanged",this.vis)),this.editor.on("baseObjectListChange",()=>{this.editor.changeSelectOption()}),C.event.on("baseObjectListChange",()=>{this.editor.emit("baseObjectListChange")});const w=()=>{this.editor.emit("baseObjectListChange")};C.event.on("updateKey",w),C.event.on("draw",w),C.event.on("erase",w)})}setResetCameraUp(){var w,E,ye;const r=((w=this.vis)==null?void 0:w.pencil.lead.group).getSize(),d=(r.max.x+r.min.x)/2,v=(r.max.y+r.min.y)/2,C=(E=this.vis)==null?void 0:E.pencil.cameraPositon.z;(ye=this.vis)==null||ye.pencil.controls.setLookAt(d,v,C,d,v,0,!0)}initEvent(){var r,d,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",w=>{this.editor.emit("refreshSidebarObject3D",w)}),(d=t.transformController)==null||d.event.on("translate",(w,E,ye)=>{this.editor.execute(new SetPosition(this.editor,w,E,ye))}),(v=t.transformController)==null||v.event.on("rotate",(w,E,ye)=>{this.editor.execute(new SetRotation(this.editor,w,E,ye))}),(C=t.transformController)==null||C.event.on("scale",(w,E,ye)=>{this.editor.execute(new SetScale(this.editor,w,E,ye))})}addObj(d){return D0(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 D0(this,null,function*(){const{vis:r}=this;if(!r)return;const d=this.editor.baseObjectByUuid(t);this.editor.execute(new RemoveObject(this.editor,d))})}copyObj(t){return D0(this,null,function*(){const{vis:r}=this;if(!r)return;const d=this.editor.baseObjectByUuid(t);this.editor.execute(new CopyObject(this.editor,d))})}setExtendsOptions(t,r){this.extendsOptions[t]=r,this.vis.extendsOptions[t]=r,this.editor.emit("optionsChanged"),setTimeout(()=>{const d=this.editor.toJSON();this.dispose(),this.editor.fromJSON(d)})}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 d;const{pencil:r}=this.vis;(d=r.transformController)==null||d.controls.setMode(t)}dispose(){var t;(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("."),d=t.split("."),v=Math.max(r.length,d.length);for(;r.length<v;)r.push("0");for(;d.length<v;)d.push("0");for(let C=0;C<v;C++){const w=parseInt(r[C]),E=parseInt(d[C]);if(w>E)return 1;if(w<E)return-1}return 0};function applyFixes(g,t){const r=[{version:"0.5.38",fix:()=>{var w;(w=t.v)!=null&&w.eo&&Object.keys(t.v.eo).forEach(E=>{["mouseLeft","mouseRight","mouseWheel","label","labelLite","shadowMap","autoRotate","equirectangular"].includes(E)&&(t.v.eo[E]=!!t.v.eo[E])}),t.h.u.forEach(E=>{E.type==="SetSetting"&&(E.attributeName==="阴影"&&(E.attributeName="shadowMap"),E.newValue=!!E.newValue,E.oldValue=!!E.oldValue)})}},{version:"0.7.14",fix:()=>{t.h.u.forEach(w=>{w.objectUuid&&(w.objectUuid=w.objectUuid.replace(w.objectUuid[0],w.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:w,adcode:E,geojsonLite:ye}=t.h.u[0].visOptions;t.h.u[0].visOptions=Di(bi({},t.h.u[0].visOptions),{geojsonMap:{[E]:w},extrudeLineGeojsonMap:{[E]:ye}}),delete t.h.u[0].visOptions.geojson,delete t.h.u[0].visOptions.geojsonLite}if(t.h.u[0].visOptions.bbox){const{bbox:w,bboxMap:E,adcode:ye}=t.h.u[0].visOptions;t.h.u[0].visOptions=Di(bi({},t.h.u[0].visOptions),{bboxMap:E||{[ye]:w}}),delete t.h.u[0].visOptions.bbox}if(t.h.u[0].visOptions.worldBg){const{worldBg:w}=t.h.u[0].visOptions;t.h.u[0].visOptions=Di(bi({},t.h.u[0].visOptions),{parentBg:w}),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(w=>{if(w.type==="SetSetting"&&w.attributeName.startsWith("测试")&&typeof w.newValue=="string"&&w.newValue.includes(":::")){const E=w.newValue.split(":::")[1];w.attributeName+=":::"+E,w.newValue=w.newValue.split(":::")[0],w.oldValue&&typeof w.oldValue=="string"&&(w.oldValue=w.oldValue.split(":::")[0])}})}},{version:"0.18.16",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u.forEach(w=>{if(w.type==="SetSetting"&&w.attributeName.startsWith("测试")&&w.attributeName.includes(":::")&&!w.attributeName.includes("caId")){const E=w.attributeName.split(":::")[1];w.attributeName=w.attributeName.replace(E,`caId.${E}`)}})}},{version:"0.21.24",fix:()=>{var w,E;t.h.u[0]&&t.h.u[0].visType==="map"&&((E=(w=t.v)==null?void 0:w.eo)!=null&&E.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,E;t.h.u[0]&&t.h.u[0].visType==="map"&&((E=(w=t.v)==null?void 0:w.eo)!=null&&E.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(w=>{w.objectUuid==="plane#topMatOne"?(w.objectUuid="area",w.materialSlot=0):w.objectUuid==="plane#sideMat"?(w.objectUuid="area",w.materialSlot=1):w.objectUuid==="plane#lineMat"?w.objectUuid="line":w.objectUuid==="plane#extrudeLineMat"?w.objectUuid="extrudeLine":w.objectUuid==="plane#bgTopMatOne"?w.objectUuid="bgPlane#topMat":w.objectUuid==="plane#bgSideMat"?w.objectUuid="bgPlane#sideMat":w.objectUuid==="plane#bgLineMat"?w.objectUuid="bgPlane#lineMat":w.objectUuid==="plane#bgExtrudeLineMat"?w.objectUuid="bgPlane#extrudeLineMat":w.objectUuid==="parentPlane#topMat"?(w.objectUuid="100000area",w.materialSlot=0):w.objectUuid==="parentPlane#sideMat"?(w.objectUuid="100000area",w.materialSlot=1):w.objectUuid==="parentPlane#lineMat"?w.objectUuid="100000line":w.objectUuid==="worldPlane#topMat"?(w.objectUuid="worldarea",w.materialSlot=0):w.objectUuid==="worldPlane#sideMat"?(w.objectUuid="worldarea",w.materialSlot=1):w.objectUuid==="worldPlane#lineMat"?w.objectUuid="worldline":w.objectUuid==="continents#topMat"?(w.objectUuid="continentsArea",w.materialSlot=0):w.objectUuid==="continents#sideMat"?(w.objectUuid="continentsArea",w.materialSlot=1):w.objectUuid==="continents#lineMat"?w.objectUuid="continentsLine":w.objectUuid==="area#river"?w.objectUuid="geography#river":w.objectUuid==="area#grassland"?w.objectUuid="geography#grassland":w.objectUuid==="area-grey#river"?w.objectUuid="geography-grey#river":w.objectUuid==="area-grey#grassland"&&(w.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 w={};t.h.u.forEach((E,ye)=>{var Le,Re,Ne;if(E.objectUuid==="area"&&E.materialSlot===0)E.objectUuid="plane#topMat",delete E.materialSlot;else if(E.objectUuid==="area"&&E.materialSlot===1)E.objectUuid="plane#sideMat",delete E.materialSlot;else if(E.objectUuid==="line")E.objectUuid="plane#lineMat";else if(E.objectUuid==="continentsArea"&&E.materialSlot===0)E.objectUuid="continents#topMat",delete E.materialSlot;else if(E.objectUuid==="continentsArea"&&E.materialSlot===1)E.objectUuid="continents#sideMat",delete E.materialSlot;else if(E.objectUuid==="continentsLine")E.objectUuid="continents#lineMat";else if(E.type==="SetSetting"&&((Le=E.attributeName)!=null&&Le.startsWith("测试"))&&E.attributeName.includes(":::caId.")){const Fe=E.attributeName.split(":::caId.")[1],at=t.h.u[0].visOptions.adcode;t.h.u[ye]=[{id:E.id,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`extrudePolygon#${at}-${Fe}`,copyObjectUuid:`ExtrudePolygon#${at}-${Fe}_${E.id}`},{id:E.id+.1,type:"CopyObject",name:"Copy Object",updatable:!1,objectUuid:`line#${at}-${Fe}`,copyObjectUuid:`line#${at}-${Fe}_${E.id+.1}`}],w[Fe]=E.id}else if((Re=E.objectUuid)!=null&&Re.startsWith("planeCopyExtrudePolygon")){const Fe=E.objectUuid.split("CopyExtrudePolygon")[1],at=t.h.u[0].visOptions.adcode;Object.assign(E,{objectUuid:`extrudePolygon#${at}-${Fe}_${w[Fe]}`})}else if((Ne=E.objectUuid)!=null&&Ne.startsWith("planeCopyLine")){const Fe=E.objectUuid.split("CopyLine")[1],at=t.h.u[0].visOptions.adcode;Object.assign(E,{objectUuid:`line#${at}-${Fe}_${w[Fe]+.1}`})}}),t.h.u=t.h.u.flat()}}},{version:"0.27.8",fix:()=>{t.h.u[0]&&t.h.u[0].visType==="map"&&t.h.u[0].visOptions.style==="map2CityOnMap"&&!t.h.u[0].visOptions.fixMap2CityOnMap&&(t.h.u[0].visOptions.mergeSide=!0,t.h.u.forEach(w=>{w.objectUuid==="extrudeLine"?w.objectUuid="plane#lineMat":w.objectUuid==="plane#lineMat"&&(w.objectUuid="extrudeLine")}),t.h.u[0].visOptions.fixMap2CityOnMap=!0)}},{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[0].visOptions.fixMap2CityOnMap2&&(t.h.u.forEach(w=>{w.objectUuid==="plane#extrudeLineMat"&&(w.objectUuid="plane#lineMat")}),t.h.u[0].visOptions.fixMap2CityOnMap2=!0)}}];let d=0,v=r.length-1,C=r.length;for(;d<=v;){const w=Math.floor((d+v)/2);compareVersion(r[w].version,g)>0?(C=w,v=w-1):d=w+1}for(let w=C;w<r.length;w++)r[w].fix()}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){_0(this,"editor");_0(this,"events",{beforeSetVisOptions:[],beforeExecuteUndo:[],afterExecuteUndo:[],beforeShow:[],afterShow:[],beforeFromJSON:[],afterFromJSON:[],errorFromJSON:[]});_0(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 d in t){const v=d;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 d;for(const v of this.events[t])if(t==="beforeSetVisOptions"?d=v(d!=null?d:r[0]):d=v(this.editor.viewport.vis,...r),d===!1)break;return d}}class Config{constructor(t){_0(this,"editor");_0(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",bi({},this.meta))}fromJSON(t){Object.keys(t).forEach(r=>{const d=r==="version"?"jsonVersion":r;d in this.meta&&this.setConfig(d,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 jsonFetch=(g,t,r=!1)=>{const d=esusLite.makePromiseCreator(!0),v=g.endsWith("gzip")||r;return window.fetch(g).then(C=>{let w=C;if(w.ok)return v?w.blob().then(E=>{const ye=new DecompressionStream("gzip"),Le=E.stream().pipeThrough(ye);return new Response(Le)}):w;throw new Error("Network response was not ok.")}).then(C=>C.json()).then(C=>{d.resolve(C)}).catch(C=>{d.reject(C)}),d.promise};class Editor{constructor(t){_0(this,"selected",null);_0(this,"playing",!0);_0(this,"currentMaterialSlot",0);_0(this,"events",new events.EventEmitter);_0(this,"history");_0(this,"viewport");_0(this,"hooks");_0(this,"config");_0(this,"pencil");_0(this,"on",this.events.on.bind(this.events));_0(this,"emit",this.events.emit.bind(this.events));_0(this,"options");_0(this,"selectOption",[]);_0(this,"_dispose",!1);this.options=bi({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;const d=this.pencil.lead.objMap.get(t);let v=t.material||(d==null?void 0:d.userData.material);return Array.isArray(v)&&r!==void 0&&(v=v[r]),v}getMListBaseObjectByObject(t,r){const d=this.getObjectMaterial(t,r);return d?this.viewport.vis.mList.getBaseObjectByMaterial(d):null}setObjectMaterial(t,r,d){const v=this.viewport.vis;let C=t.material;if(Array.isArray(t.material)&&r!==void 0?(C=t.material[r],t.material[r]=d):t.material=d,C){C.onBeforeCompile&&(d.onBeforeCompile=C.onBeforeCompile);const w=new O;if(w.track(C),w.dispose(),t.userData.fixBufferGeometry){const E=v.pencil.lead,ye=Le=>{let Re=!1;if(Le.material)if(Array.isArray(Le.material)){const Ne=Le.material;Ne.forEach((Fe,at)=>{Fe===C&&(Re=!0,Ne[at]=d)})}else Le.material===C&&(Re=!0,Le.material=d);return Re?Le:null};this.pencil.scene.traverse(Le=>{const Re=Le;ye(Re);const Ne=E.objMap.get(Re);Ne!=null&&Ne.materialList&&Object.keys(Ne.materialList).forEach(Fe=>{if(Fe!==Ne.useMaterialType||!Array.isArray(Ne.materialList[Fe])){const at=Ne.materialList[Fe],ot=ye({material:at});ot&&Ne.setMaterialList(Fe,ot.material)}})})}}}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,d){for(let v=0;v<t.length;v++){const C=t[v];if(C[r]===d)return C;if(C.children){const w=this.findSelectItem(C.children,r,d);if(w)return w}}}changeSelectOption(){const t=this.viewport.vis,r=t.mList,d=v=>v.filter(C=>C.userData.selectHide!==!0).map(C=>{var ot;const w=[...C.children];if(C.key==="Scene"&&!w.find(Gt=>Gt.key==="camera"))this.pencil.camera.name="透视相机",w.unshift({key:"camera",object3d:this.pencil.camera,userData:{},children:[]});else if(C.object3d.target){const Gt=C.options.type;w.unshift({key:C.key.replace(Gt,Gt+"Target"),object3d:C.object3d.target,userData:{disabledCR:!0,disabledTC:!1},children:[]})}if(C.object3d.isDirectionalLight){const Gt=C.options.type;w.unshift({key:C.key.replace(Gt,Gt+"Shadow"),object3d:C.object3d.shadow.camera,userData:{disabledCR:!0},children:[]})}const ye=w.length>0?d(w):[],Le=C.object3d.userData.fixBufferGeometry,Re=C.object3d.isGroup&&C.userData.disabledTC!==!1,Ne=Le||Re||["Scene","camera"].includes(C.key)||C.userData.disabledCR;if(ye.length===0&&Re)return null;const Fe=C.key.replace(C.key[0],C.key[0].toLowerCase()),at=(ot=C.userData.disabledTC)!=null?ot:Ne;return{key:Fe,name:C.object3d.name,object:C.object3d,disabledCR:Ne,disabledTC:at,baseObject:C,children:ye}}).filter(C=>C!==null);this.selectOption=[...d([r.wrapObject]),...d([t.lead.scene])],this.emit("sceneGraphChanged")}execute(t,r){return D0(this,null,function*(){yield this.history.execute(t,r)})}fromJSON(t,r){return D0(this,null,function*(){var d,v,C,w;try{r&&!f(r)?console.warn("fromJSON 第二个参数已修改,{beforeSetVisOptions:(r)=>r} 替代"):r&&this.hooks.addEvents(r);let E;if(typeof t=="string"){const ye=this.options.assetsPrefix+t;console.time("vis-core:time.json-fetch");const{res:Le,err:Re}=yield jsonFetch(ye);if(console.timeEnd("vis-core:time.json-fetch"),Re)throw new Error("fromJSON error:"+Re);E=Le}else E=t;if(this.hooks.dispatch("beforeFromJSON"),E=fixJSON(E),E.at&&(accessToken.token=E.at),!this.storage){if(!accessToken.token)throw new Error("设置 token 或平台重新下载 JSON 文件");const ye=accessToken.getInfo();if(!ye||!ye.isValid)throw new Error("need accessToken")}if(this.config.fromJSON(E.c),this.history.fromJSON(E.h),this.viewport.fromJSON(E.v),this.hooks.fromJSON(E.s),this.config.compareVersion(),yield this.history.processUndos(this.options.processUndosMaxFrameTime),(d=E.v.bg)!=null&&d.texture&&this.viewport.vis){const ye=parseTexture(E.v.bg.texture);ye.colorSpace=SRGBColorSpace,this.viewport.vis.pencil.scene.background=ye}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),(w=this.viewport.vis)!=null&&w.workerOnce&&this.playing&&window.requestIdleCallback(()=>{var ye;(ye=this.viewport.vis)==null||ye.worker.dispose()}),this.hooks.dispatch("afterFromJSON"),E}catch(E){throw this.hooks.dispatch("errorFromJSON"),new Error("fromJSON error:"+E)}})}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){_0(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 d=tier0GPU[r],v=this.getGPUVersion();return d.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(/\([^)]+\)/,""),d=r.match(/\d+/)||r.match(/(\W|^)([A-Za-z]{1,3})(\W|$)/g);return(v=d==null?void 0:d.join("").replace(/\W|amd/g,""))!=null?v:""}queryFallback(){const t=this.renderer,r=BLOCKLISTED_GPUS.find(d=>t.includes(d));return r?{tier:0,gpu:r}:{tier:3,gpu:t}}}class WebGL{constructor(){_0(this,"rawRenderer");_0(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"),d=r==null?void 0:r.getExtension("WEBGL_debug_renderer_info");return r&&d?r.getParameter(d.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"),d=window.WebGL2RenderingContext&&r.getContext("webgl2");return d?(d.drawingBufferColorSpace=t,d.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 bi(bi({},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 d=new DOMMatrix(r);return Math.max(d.a,d.d)}};function observeScale(g,t){let r=g,d=1;for(;r;){const ye=getScale(r);if(ye!==void 0){d=ye;break}if(r=r.parentElement,r===document.body){r=null;break}}if(!r)return null;const v=ye=>{const Le=getScale(r)||1;d!==Le&&(d=Le,t(Le,ye))},C=ye=>{ye.propertyName==="transform"&&v("transitionEnd")},w=new MutationObserver(ye=>{for(const Le of ye)if(Le.type==="attributes"&&Le.attributeName==="style"){v("MutationObserver");return}});w.observe(r,{attributes:!0,attributeFilter:["style"]}),r.addEventListener("transitionend",C),t(d,"init");const E=w.disconnect;return w.disconnect=function(){E.call(w),r==null||r.removeEventListener("transitionend",C)},w}const IS_DEV=!1;class Base extends Camera{constructor(r){var d;super();_0(this,"playing",!0);_0(this,"leftTruck",!0);_0(this,"options");_0(this,"showState",!1);_0(this,"settings",{});_0(this,"delLoadArr");_0(this,"extendsOptions",{});_0(this,"leadObjs",objs$3);_0(this,"lead");_0(this,"mList",new MaterialList);_0(this,"workerOnce",!0);_0(this,"tier0",!1);_0(this,"pmremGenerator",null);_0(this,"re",null);_0(this,"roomEnvMap");_0(this,"visName");_0(this,"editor");_0(this,"publicDir",{});_0(this,"_baseObjectByUuid");_0(this,"_objectByUuid");_0(this,"observeScale",null);_0(this,"sceneActive",-1);_0(this,"initSettingsObj");_0(this,"mouseButtonsActiveStore",null);if(this.container=r.container,this.options=bi({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=(d=this.options.tier)!=null?d:v.tier;try{const w=window.location.search.match(/v_tier=(\d+)/);w&&(C=+w[1])}catch(w){console.error(w)}this.tier0=C!==3,this.editor=new Editor({assetsPrefix:this.options.assetsPrefix,visFactories:this}),console.info("vis-core:detect",version,JSON.stringify(Di(bi({},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=bi(bi({},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 D0(this,null,function*(){})}initVis(...r){return D0(this,null,function*(){})}init(...r){return D0(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 D0(this,null,function*(){var v,C,w,E,ye,Le,Re,Ne;if(this.pencil)return;const r=bi({},this.options.pencilConfig);if(this.options.css2DContainer&&(r.css2DRendererParams={container:this.options.css2DContainer}),this.options.pencil)this.pencil=this.options.pencil,this.sceneActive=this.pencil.addPage({cameraOptions:{fov:(C=(v=r.camera)==null?void 0:v.fov)!=null?C:45,near:(E=(w=r.camera)==null?void 0:w.near)!=null?E:.1,far:(Le=(ye=r.camera)==null?void 0:ye.far)!=null?Le:1e3,up:(Ne=(Re=r.camera)==null?void 0:Re.up)!=null?Ne:new Vector3(0,1,0)},sceneOptions:{background:new Color$1(0)}}),this.setSceneActive(),this.mList.install(this.pencil);else if(this.options.pencil2){this.pencil=this.options.pencil2,this.lead=this.pencil.lead.init(this.leadObjs),this.mList.dispose(),this.mList=this.pencil.installPlugins.get("materialList"),this.sceneActive=this.pencil.pageActiveIndex;return}else{const Fe=new rt(bi(Di(bi({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},bloom:!0,ssao:!0,ssaoParams:{minDistance:.001},scene:{background:new Color$1(0)},loader:bi({prefix:this.options.assetsPrefix,simpleTexture4deleted:!0},this.tier0?{anisotropy:1}:{})}),r));if(this.options.observeParentScale&&this.playing){const Gt=()=>{this.observeScale||(this.observeScale=observeScale(this.container,(ht,ke)=>{Fe.setDevicePixelRatio(window.devicePixelRatio*ht)}))};Gt(),Fe.event.on("resize",()=>{Gt()})}this.pencil=Fe,this.sceneActive=1;const at=Fe.composerController.ssaoPass;at&&(at.enabled=!1);const ot=new Q({dbName:this.visName,cacheVersion:version});Fe.use(ot),Fe.use(this.mList),this.playing||(window.vis=this,window.pencil=Fe)}const d=this.pencil;this.lead=d.lead.init(this.leadObjs),this.delLoadArr&&(d.loader.delLoadArr=this.delLoadArr),d.loader.on("progress",(...Fe)=>{this.showState!==!0&&this.emit("loaderProgress",...Fe)}),this.leftTruck&&(d.controls.mouseButtons.left=Ki.TRUCK,d.controls.mouseButtons.right=Ki.ROTATE),this.lead.group.hide(),this.lead.prefabGroup.hide(),this.initSceneUserData(),this.initCameraUserData(),this.initSettings()})}setSceneActive(){this.pencil.showPage(this.sceneActive),this.pencil.installPlugins.set("materialList",this.mList)}initCameraUserData(){const r=this.pencil;r.camera.userData=new Proxy({up:r.camera.up.toArray().join(",")},{set:(d,v,C)=>{if(v==="up"){const w=C.split(",").map(E=>+E);r.camera.up.set(w[0],w[1],w[2]),r.controls.updateCameraUp()}return Reflect.set(d,v,C)}})}initSceneUserData(){var E,ye,Le,Re,Ne,Fe;const r=this.pencil,d=r.scene.background,v=d instanceof Color$1?"Color":d instanceof Texture?"Texture":"None",C=v==="Texture"?d:null,w=v==="Color"?"#"+d.getHexString():"#000000";r.scene.userData=new Proxy({backgroundType:v,backgroundColor:w,backgroundTexture:C,shadowMapEnabled:this.pencil.renderer.shadowMap.enabled,shadowMapType:this.pencil.renderer.shadowMap.type,bloomThreshold:(ye=(E=this.pencil.composerController)==null?void 0:E.bloomPass)==null?void 0:ye.threshold,bloomRadius:(Re=(Le=this.pencil.composerController)==null?void 0:Le.bloomPass)==null?void 0:Re.radius,bloomStrength:(Fe=(Ne=this.pencil.composerController)==null?void 0:Ne.bloomPass)==null?void 0:Fe.strength},{set:(at,ot,Gt)=>(ot==="shadowMapEnabled"||ot==="shadowMapType"?(ot==="shadowMapEnabled"?this.pencil.renderer.shadowMap.enabled=Gt:ot==="shadowMapType"&&(this.pencil.renderer.shadowMap.type=Gt),this.pencil.scene.traverse(ht=>{const ke=ht;if(ke.receiveShadow&&ke.material){const ct=ke.material;Array.isArray(ct)?ct.forEach(xt=>{xt.needsUpdate=!0}):ct.needsUpdate=!0}})):ot==="backgroundType"?Gt==="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):ot==="backgroundColor"?r.scene.background=new Color$1(Gt):ot==="backgroundTexture"?r.scene.background=Gt:ot==="bloomThreshold"?r.composerController.bloomPass&&(r.composerController.bloomPass.threshold=Gt):ot==="bloomRadius"?r.composerController.bloomPass&&(r.composerController.bloomPass.radius=Gt):ot==="bloomStrength"&&r.composerController.bloomPass&&(r.composerController.bloomPass.strength=Gt),Reflect.set(at,ot,Gt))})}initBaseObjectUserData(r){const d=Di(bi({},r.object3d.userData),{bloom:!1});if(r.objectType==="BaseObject#Light")return;const v=r.objectType==="BaseObject#Arc",C=r.objectType==="BaseObject#Line",w=r.object3d instanceof Group$1;v?d.animationDuration=2e3:C&&(d.animationDuration=0),prefabType.includes(r.objectType.split("#")[1])&&(d.prefab=r.prefab),r.object3d.userData=new Proxy(d,{set:(E,ye,Le)=>(ye==="bloom"?Le?r.enableBloom():r.disableBloom():ye==="prefab"?(r.prefab=Le,Le?this.lead.prefabGroup.attach(r):this.lead.group.attach(r)):ye==="animationDuration"&&v?r.animateIn({duration:Le}):ye==="animationDuration"&&(C||w)&&(C?[r]:r.children).forEach(Ne=>{Ne.material.userData.tween&&(Ne.material.userData.tween.stop(),remove(Ne.material.userData.tween),Ne.material.userData.tween=null),Le&&(Ne.material.uniforms.offset.value.x=1,Ne.material.uniforms.offsetLoop.value=1,Ne.animate({duration:Le,repeat:1/0,lineLoop:!0,startShow:!0}))}),Reflect.set(E,ye,Le))})}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(Di(bi(bi({},this.initSettingsObj),r),{mouseNone:!1,viewportPadding:[0,0,0,0]}),{set:(d,v,C)=>{if(!(v in d)&&!(v.replace(/(:::.+)\..*$/,"$1")in d))return Reflect.set({},v,C);v==="mouseWheel"?typeof C=="boolean"&&(C=C?r.mouseWheel:Ki.NONE):v==="mouseLeft"?typeof C=="boolean"&&(C=C?r.mouseLeft:Ki.NONE):v==="mouseRight"&&typeof C=="boolean"&&(C=C?r.mouseRight:Ki.NONE);const w=v.includes(":::");return Reflect.set(d,w?v.replace(/(:::.+)\..*$/,"$1"):v,this.handleSetting(v,C))},get:(d,v)=>{const w=v.includes(":::")?v.replace(/(:::.+)\..*$/,"$1"):v,E=Reflect.get(d,w);return E instanceof Promise?E.then(ye=>(Reflect.set(d,w,ye),ye)):E}})}handleSetting(r,d){return D0(this,null,function*(){const{pencil:v}=this;if(r==="mouseWheel"||r==="mouseLeft"||r==="mouseRight"){const C=r.replace("mouse","").toLowerCase();(d||this.playing)&&(v.controls.mouseButtons[C]=d)}else if(r==="mouseNone")d?(this.mouseButtonsActiveStore={mouseLeft:v.controls.mouseButtons.left,mouseRight:v.controls.mouseButtons.right,mouseWheel:v.controls.mouseButtons.wheel},v.controls.mouseButtons.left=Ki.NONE,v.controls.mouseButtons.right=Ki.NONE,v.controls.mouseButtons.wheel=Ki.NONE):this.mouseButtonsActiveStore&&(v.controls.mouseButtons.left=this.mouseButtonsActiveStore.mouseLeft,v.controls.mouseButtons.right=this.mouseButtonsActiveStore.mouseRight,v.controls.mouseButtons.wheel=this.mouseButtonsActiveStore.mouseWheel);else if(r==="viewportPadding"){v.rendererController.setViewPadding(...d);const C=new Vector4;v.renderer.getViewport(C),v.cameraController.setAspect(C.z/C.w)}return d})}show(){this.showState||(this.useSaveCamera("visShow"),this.options.disableInitShow||this.showAction())}showAction(){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 D0(this,arguments,function*(r,d={}){typeof d=="string"&&(d={display:d}),d.display&&(r.style.display=d.display);let C=0;typeof d.onTop!="undefined"&&(C=d.onTop);const w=yield this.lead.draw("Node",{onTop:C});return w.setChildren(r),w})}addCSS3D(v){return D0(this,arguments,function*(r,d={}){d.display&&(r.style.display=d.display);let C=0;typeof d.onTop!="undefined"&&(C=d.onTop);let w="3d";typeof d.type!="undefined"&&(w=d.type);const E=yield this.lead.draw("Node",{onTop:C,type:w});return E.setChildren(r),E})}getRoomEnvMap(){if(this.roomEnvMap)return this.roomEnvMap;const r=new PMREMGenerator(this.pencil.renderer);r.compileEquirectangularShader();const d=new RoomEnvironment,v=r.fromScene(d,.04).texture;return this.pmremGenerator=r,this.re=d,this.roomEnvMap=v,v}handlePick(r,d,v){console.warn("handlePick is deprecated, use BaseObject.onPointerEvent"),this.lead.handlePick(r,d,v)}getScreenPosition(r,d,v){const C=new Vector3(r,d,v);C.project(this.pencil.camera);const{width:w,height:E}=this.pencil.getSize(),ye=(C.x*.5+.5)*w,Le=(C.y*-.5+.5)*E;return{x:ye,y:Le}}dispose(){var r,d,v,C,w;super.dispose(),this.editor&&(this.editor.viewport.vis=void 0,this.editor.dispose()),this.publicDir={},this.options.pencil?((r=this.mList)==null||r.dispose(),this.pencil.removePage(this.sceneActive)):this.options.pencil2||(d=this.pencil)==null||d.dispose(),(v=this.pmremGenerator)==null||v.dispose(),(C=this.re)==null||C.dispose(),(w=this.observeScale)==null||w.disconnect()}}_0(Base,"VisName","base");function clipGeojson(g,t){const r=turf.flatten(g).features,d=turf.flatten(t).features,v={type:"FeatureCollection",features:[]};for(let C=r.length-1;C>=0;C--){const w=r[C];for(let E=d.length-1;E>=0;E--){const ye=d[E];if(contains(w,ye))v.features.push(ye);else if(contains(ye,w))w.properties=ye.properties,v.features.push(w);else{const Le=turf.intersect(w,ye);Le&&(Le.properties=ye.properties,v.features.push(Le))}}}return v}function contains(g,t){let r=!0;const d=turf.explode(t).features;for(let v=d.length-1;v>=0;v--)if(!turf.inside(d[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,d)=>turf.polygon(t[d]))};class Building extends ie$1{constructor(r){super();_0(this,"options");_0(this,"building",{});_0(this,"outJson",new Map);_0(this,"worldPositionZ",{value:0});this.options=bi({},r)}create(){return D0(this,null,function*(){const{json:r,projection:d,cacheKey:v,meters:C,grey:w,clip:E}=this.options,ye=this.pencil.installPlugins.get("materialList"),Le=this.pencil.getPlugin("worker"),Re=this.pencil.lead,Ne=w?"-grey":"";this.createGroup();const Fe=ye.getMultiple("building"+Ne);let at=v?yield Le.getCachedGeometry({cacheKey:v}):[];if(at.length)E&&this.outJson.set(1,!0);else{let ot;E&&(ot=getBoxMultiPoly(E));const Gt={};(r.features||r).forEach(ke=>{const ct=typeof ke.properties.h=="string"?ke.properties.h.split(".")[1]:0,xt=Number(ke.properties.h)|0;Gt[ct]||(Gt[ct]={}),Gt[ct][xt]||(Gt[ct][xt]=[]),ot?ot.some(Wt=>{ke.geometry.coordinates[1]&&console.log(ke.geometry.coordinates[1]);const Pt=turf.polygon(ke.geometry.coordinates[0]);return turf.booleanContains(Wt,Pt)?(Gt[ct][xt].push(ke),!0):!1})||this.outJson.set(ke,!1):Gt[ct][xt].push(ke)});const ht=Object.keys(Gt).map(ke=>{const ct=Gt[ke];return Object.keys(ct).map(xt=>{const Rt=ct[xt];return{z:+ke,h:+xt,coordinatesArr:Rt.map(Wt=>Wt.geometry.type==="Polygon"?Wt.geometry.coordinates[0]:Wt.geometry.coordinates[0][0])}})}).flat().filter(ke=>ke.coordinatesArr.length);at=yield Promise.all(ht.map(ke=>{const{h:ct,z:xt,coordinatesArr:Rt}=ke,Wt=+ct<=20?+ct/18:+ct<=60?+ct/27:+ct/12;return Le.geoGeometry("extrudePolygon",{cacheKey:v,userData:{z:xt,h:ct},mesaage:{coordinatesArr:Rt,projection:d,useGroups:2,depth:[Number(ct)*(C||1)],hasBottom:!1,sideRepeat:Wt}})}))}yield Promise.all(at.map(ot=>D0(this,null,function*(){const{h:Gt,z:ht}=ot.userData,ke=Gt+ht,ct=ke<=20?"20":ke<=60?"60":"max";let xt=this.options.material;xt||(xt=[Fe[ct+"Top"],Fe[ct+"Side"]]);const Rt=yield Re.draw("ExtrudePolygon",{key:`$p:-${Gt}-${ht}`,geometry:ot,material:xt},this);this.options.grey||(Rt.object3d.castShadow=!0),this.building[Gt]||(this.building[Gt]=[]),this.building[Gt].push(Rt),Rt.position.z=Number(ht)*(C||1)}))),this.options.sideGradient&&this.sideGradient(),this.object3d.name="建筑",w||this.lead.updateBaseObjectKey(this,`building${Ne?"-grey":""}#group`)})}sideGradient(r="#052438",d=.05/100){this.traverse(v=>{if(v instanceof ss){const C=v.object3d.material;C[1].onBeforeCompile=w=>{w.uniforms.gradientColor={value:new Color$1(r)},w.uniforms.maxGradientHeight={value:d},w.uniforms.worldPositionZ=this.worldPositionZ,w.vertexShader=`
4857
4857
  varying vec3 vPosition;
4858
4858
  varying vec3 vWorldPosition;
4859
4859
  ${w.vertexShader}